commit 1b2018955518f1d6e98a224578641e4fa32b49b3
parent 224c0d8d72c970e500d8d7d04fdb8950b232c6f5
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date: Mon, 5 Aug 2024 22:04:14 +0200
master volume now saved in plugin state
Diffstat:
8 files changed, 101 insertions(+), 18 deletions(-)
diff --git a/source/nord/n2x/n2xJucePlugin/n2xController.cpp b/source/nord/n2x/n2xJucePlugin/n2xController.cpp
@@ -43,6 +43,8 @@ namespace n2xJucePlugin
requestDump(n2x::SysexByte::MultiRequestBankEditBuffer, 0); // performance edit buffer
+ requestDump(n2x::SysexByte::EmuGetPotsPosition, 0);
+
m_currentPartChanged.set(onCurrentPartChanged, [this](const uint8_t& _part)
{
setMultiParameter(n2x::SelectedChannel, _part);
@@ -86,12 +88,33 @@ namespace n2xJucePlugin
return {};
}
- bool Controller::parseSysexMessage(const pluginLib::SysEx& _msg, synthLib::MidiEventSource)
+ void Controller::onStateLoaded()
+ {
+ requestDump(n2x::SysexByte::EmuGetPotsPosition, 0);
+ }
+
+ bool Controller::parseSysexMessage(const pluginLib::SysEx& _msg, synthLib::MidiEventSource _source)
{
if(_msg.size() == n2x::g_singleDumpSize)
+ {
return parseSingleDump(_msg);
+ }
if(_msg.size() == n2x::g_multiDumpSize)
+ {
return parseMultiDump(_msg);
+ }
+
+ n2x::KnobType knobType;
+ uint8_t knobValue;
+
+ if(n2x::State::parseKnobSysex(knobType, knobValue, _msg))
+ {
+ if(m_state.receive(_msg, _source))
+ {
+ onKnobChanged(knobType, knobValue);
+ return true;
+ }
+ }
return false;
}
@@ -389,4 +412,9 @@ namespace n2xJucePlugin
return PatchManager::getPatchName({multi.begin(), multi.end()});
return getSingleName(_part);
}
+
+ bool Controller::getKnobState(uint8_t& _result, const n2x::KnobType _type) const
+ {
+ return m_state.getKnobState(_result, _type);
+ }
}
diff --git a/source/nord/n2x/n2xJucePlugin/n2xController.h b/source/nord/n2x/n2xJucePlugin/n2xController.h
@@ -20,15 +20,14 @@ namespace n2xJucePlugin
};
pluginLib::Event<> onProgramChanged;
+ pluginLib::Event<n2x::KnobType, uint8_t> onKnobChanged;
Controller(AudioPluginAudioProcessor&);
~Controller() override;
static std::string loadParameterDescriptions();
- void onStateLoaded() override
- {
- }
+ void onStateLoaded() override;
uint8_t getPartCount() const override
{
@@ -63,6 +62,8 @@ namespace n2xJucePlugin
using pluginLib::Controller::sendSysEx;
+ bool getKnobState(uint8_t& _result, n2x::KnobType _type) const;
+
private:
n2x::State m_state;
pluginLib::EventListener<uint8_t> m_currentPartChanged;
diff --git a/source/nord/n2x/n2xJucePlugin/n2xMasterVolume.cpp b/source/nord/n2x/n2xJucePlugin/n2xMasterVolume.cpp
@@ -8,7 +8,13 @@ namespace n2xJucePlugin
MasterVolume::MasterVolume(const Editor& _editor) : m_editor(_editor), m_volume(_editor.findComponentT<juce::Slider>("MasterVolume"))
{
m_volume->setRange(0.0f, 255.0f);
- m_volume->setValue(255.0f);
+
+ uint8_t currentValue;
+
+ if(_editor.getN2xController().getKnobState(currentValue, n2x::KnobType::MasterVol))
+ m_volume->setValue(currentValue, juce::dontSendNotification);
+ else
+ m_volume->setValue(255.0f, juce::dontSendNotification);
m_volume->onValueChange = [this]
{
@@ -16,5 +22,12 @@ namespace n2xJucePlugin
m_editor.getN2xController().sendSysEx(sysex);
};
+
+ m_onKnobChanged.set(_editor.getN2xController().onKnobChanged, [this](const n2x::KnobType& _type, const unsigned char& _value)
+ {
+ if(_type != n2x::KnobType::MasterVol)
+ return;
+ m_volume->setValue(_value, juce::dontSendNotification);
+ });
}
}
diff --git a/source/nord/n2x/n2xJucePlugin/n2xMasterVolume.h b/source/nord/n2x/n2xJucePlugin/n2xMasterVolume.h
@@ -1,5 +1,12 @@
#pragma once
+#include "jucePluginLib/event.h"
+
+namespace n2x
+{
+ enum class KnobType;
+}
+
namespace juce
{
class Slider;
@@ -18,5 +25,7 @@ namespace n2xJucePlugin
const Editor& m_editor;
juce::Slider* m_volume;
+
+ pluginLib::EventListener<n2x::KnobType, uint8_t> m_onKnobChanged;
};
}
diff --git a/source/nord/n2x/n2xLib/n2xdevice.cpp b/source/nord/n2x/n2xLib/n2xdevice.cpp
@@ -90,14 +90,14 @@ namespace n2x
{
if(_ev.sysex.empty())
{
- m_state.receive(_ev);
+ m_state.receive(_response, _ev);
auto e = _ev;
e.offset += m_numSamplesProcessed + getExtraLatencySamples();
m_hardware.sendMidi(e);
}
else
{
- if(m_state.receive(_ev))
+ if(m_state.receive(_response, _ev))
return true;
m_hardware.sendMidi(_ev);
diff --git a/source/nord/n2x/n2xLib/n2xmiditypes.h b/source/nord/n2x/n2xLib/n2xmiditypes.h
@@ -14,7 +14,8 @@ namespace n2x
MultiDumpBankEditBuffer = 30, MultiDumpBankA,
MultiRequestBankEditBuffer = 40,
- EmuSetPotPosition = 90, // total dump is: f0, IdClavia, IdDevice, IdN2x, EmuSetPotPosition, KnobType / nibble high, nibble low / f7
+ EmuSetPotPosition = 90, // total dump is: f0, IdClavia, IdDevice, IdN2x, EmuSetPotPosition, KnobType / nibble high, nibble low / f7
+ EmuGetPotsPosition = 91,
};
enum SysexIndex
@@ -24,8 +25,8 @@ namespace n2x
IdxN2x,
IdxMsgType,
IdxMsgSpec,
- IdxPotPosH,
- IdxPotPosL
+ IdxKnobPosH,
+ IdxKnobPosL
};
enum SingleParam
diff --git a/source/nord/n2x/n2xLib/n2xstate.cpp b/source/nord/n2x/n2xLib/n2xstate.cpp
@@ -195,6 +195,11 @@ namespace n2x
{
updateMultiFromSingles();
_state.insert(_state.end(), m_multi.begin(), m_multi.end());
+ for (const auto it : m_knobStates)
+ {
+ auto knobSysex = createKnobSysex(it.first, it.second);
+ _state.insert(_state.end(), knobSysex.begin(), knobSysex.end());
+ }
return true;
}
@@ -209,7 +214,7 @@ namespace n2x
return false;
}
- bool State::receive(const synthLib::SMidiEvent& _ev)
+ bool State::receive(std::vector<synthLib::SMidiEvent>& _responses, const synthLib::SMidiEvent& _ev)
{
if(_ev.sysex.empty())
{
@@ -246,9 +251,6 @@ namespace n2x
return true;
}
- if(sysex.size() == g_patchRequestSize)
- return false;
-
if(bank == n2x::SysexByte::EmuSetPotPosition)
{
KnobType knobType;
@@ -256,10 +258,21 @@ namespace n2x
if(parseKnobSysex(knobType, knobValue, sysex))
{
- m_hardware->setKnobPosition(knobType, knobValue);
+ if(m_hardware)
+ m_hardware->setKnobPosition(knobType, knobValue);
+ m_knobStates[knobType] = knobValue;
return true;
}
}
+ else if(bank == SysexByte::EmuGetPotsPosition)
+ {
+ for (const auto it : m_knobStates)
+ {
+ _responses.emplace_back(synthLib::MidiEventSource::Internal);
+ _responses.back().sysex = createKnobSysex(it.first, it.second);
+ }
+ return true;
+ }
return false;
}
@@ -439,17 +452,26 @@ namespace n2x
bool State::parseKnobSysex(KnobType& _type, uint8_t& _value, const std::vector<uint8_t>& _sysex)
{
- if(_sysex.size() <= SysexIndex::IdxPotPosL)
+ if(_sysex.size() <= SysexIndex::IdxKnobPosL)
return false;
if(_sysex[SysexIndex::IdxMsgType] != SysexByte::EmuSetPotPosition)
return false;
_type = static_cast<KnobType>(_sysex[SysexIndex::IdxMsgSpec]);
- _value = static_cast<uint8_t>((_sysex[SysexIndex::IdxPotPosH] << 4) | _sysex[SysexIndex::IdxPotPosL]);
+ _value = static_cast<uint8_t>((_sysex[SysexIndex::IdxKnobPosH] << 4) | _sysex[SysexIndex::IdxKnobPosL]);
return true;
}
+ bool State::getKnobState(uint8_t& _result, const KnobType _type) const
+ {
+ const auto it = m_knobStates.find(_type);
+ if(it == m_knobStates.end())
+ return false;
+ _result = it->second;
+ return true;
+ }
+
void State::send(const synthLib::SMidiEvent& _e) const
{
if(_e.source == synthLib::MidiEventSource::Plugin)
diff --git a/source/nord/n2x/n2xLib/n2xstate.h b/source/nord/n2x/n2xLib/n2xstate.h
@@ -3,6 +3,7 @@
#include <array>
#include <vector>
#include <cstddef>
+#include <unordered_map>
#include "n2xmiditypes.h"
#include "n2xtypes.h"
@@ -24,7 +25,12 @@ namespace n2x
bool getState(std::vector<uint8_t>& _state);
bool setState(const std::vector<uint8_t>& _state);
- bool receive(const synthLib::SMidiEvent& _ev);
+ bool receive(const synthLib::SMidiEvent& _ev)
+ {
+ std::vector<synthLib::SMidiEvent> responses;
+ return receive(responses, _ev);
+ }
+ bool receive(std::vector<synthLib::SMidiEvent>& _responses, const synthLib::SMidiEvent& _ev);
bool receive(const std::vector<uint8_t>& _data, synthLib::MidiEventSource _source);
bool receiveNonSysex(const synthLib::SMidiEvent& _ev);
@@ -110,6 +116,8 @@ namespace n2x
static std::vector<uint8_t> createKnobSysex(KnobType _type, uint8_t _value);
static bool parseKnobSysex(KnobType& _type, uint8_t& _value, const std::vector<uint8_t>& _sysex);
+ bool getKnobState(uint8_t& _result, KnobType _type) const;
+
private:
template<size_t Size> bool receive(const std::array<uint8_t, Size>& _data)
{
@@ -124,5 +132,6 @@ namespace n2x
Hardware* m_hardware;
std::array<SingleDump, 4> m_singles;
MultiDump m_multi;
+ std::unordered_map<KnobType, uint8_t> m_knobStates;
};
}