commit 224c0d8d72c970e500d8d7d04fdb8950b232c6f5
parent dded541aeee9cb759d5b2d1ca69fb9aa52dbf5e4
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date: Mon, 5 Aug 2024 21:34:35 +0200
master volume knob works, state not preserved yet
Diffstat:
9 files changed, 94 insertions(+), 0 deletions(-)
diff --git a/source/nord/n2x/n2xJucePlugin/CMakeLists.txt b/source/nord/n2x/n2xJucePlugin/CMakeLists.txt
@@ -6,6 +6,7 @@ set(SOURCES
n2xArp.cpp n2xArp.h
n2xController.cpp n2xController.h
n2xEditor.cpp n2xEditor.h
+ n2xMasterVolume.cpp n2xMasterVolume.h
n2xLcd.cpp n2xLcd.h
n2xPart.cpp n2xPart.h
n2xParts.cpp n2xParts.h
diff --git a/source/nord/n2x/n2xJucePlugin/n2xController.h b/source/nord/n2x/n2xJucePlugin/n2xController.h
@@ -61,6 +61,8 @@ namespace n2xJucePlugin
std::string getSingleName(uint8_t _part) const;
std::string getPatchName(uint8_t _part) const;
+ using pluginLib::Controller::sendSysEx;
+
private:
n2x::State m_state;
pluginLib::EventListener<uint8_t> m_currentPartChanged;
diff --git a/source/nord/n2x/n2xJucePlugin/n2xEditor.cpp b/source/nord/n2x/n2xJucePlugin/n2xEditor.cpp
@@ -5,6 +5,7 @@
#include "n2xArp.h"
#include "n2xController.h"
#include "n2xLcd.h"
+#include "n2xMasterVolume.h"
#include "n2xPart.h"
#include "n2xParts.h"
#include "n2xPatchManager.h"
@@ -69,6 +70,7 @@ namespace n2xJucePlugin
m_arp.reset(new Arp(*this));
m_lcd.reset(new Lcd(*this));
+ m_masterVolume.reset(new MasterVolume(*this));
m_parts.reset(new Parts(*this));
onPartChanged.set(m_controller.onCurrentPartChanged, [this](const uint8_t& _part)
@@ -111,6 +113,7 @@ namespace n2xJucePlugin
{
m_arp.reset();
m_lcd.reset();
+ m_masterVolume.reset();
m_parts.reset();
}
diff --git a/source/nord/n2x/n2xJucePlugin/n2xEditor.h b/source/nord/n2x/n2xJucePlugin/n2xEditor.h
@@ -21,6 +21,7 @@ namespace n2xJucePlugin
class Lcd;
class Arp;
class Parts;
+ class MasterVolume;
class Editor final : public jucePluginEditorLib::Editor
{
@@ -57,6 +58,7 @@ namespace n2xJucePlugin
std::unique_ptr<Arp> m_arp;
std::unique_ptr<Lcd> m_lcd;
+ std::unique_ptr<MasterVolume> m_masterVolume;
std::unique_ptr<Parts> m_parts;
pluginLib::EventListener<uint8_t> onPartChanged;
diff --git a/source/nord/n2x/n2xJucePlugin/n2xMasterVolume.cpp b/source/nord/n2x/n2xJucePlugin/n2xMasterVolume.cpp
@@ -0,0 +1,20 @@
+#include "n2xMasterVolume.h"
+
+#include "n2xController.h"
+#include "n2xEditor.h"
+
+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);
+
+ m_volume->onValueChange = [this]
+ {
+ const auto sysex = n2x::State::createKnobSysex(n2x::KnobType::MasterVol, static_cast<uint8_t>(m_volume->getValue()));
+
+ m_editor.getN2xController().sendSysEx(sysex);
+ };
+ }
+}
diff --git a/source/nord/n2x/n2xJucePlugin/n2xMasterVolume.h b/source/nord/n2x/n2xJucePlugin/n2xMasterVolume.h
@@ -0,0 +1,22 @@
+#pragma once
+
+namespace juce
+{
+ class Slider;
+}
+
+namespace n2xJucePlugin
+{
+ class Editor;
+
+ class MasterVolume
+ {
+ public:
+ explicit MasterVolume(const Editor& _editor);
+
+ private:
+ const Editor& m_editor;
+
+ juce::Slider* m_volume;
+ };
+}
diff --git a/source/nord/n2x/n2xLib/n2xmiditypes.h b/source/nord/n2x/n2xLib/n2xmiditypes.h
@@ -13,6 +13,8 @@ namespace n2x
MultiDumpBankEditBuffer = 30, MultiDumpBankA,
MultiRequestBankEditBuffer = 40,
+
+ EmuSetPotPosition = 90, // total dump is: f0, IdClavia, IdDevice, IdN2x, EmuSetPotPosition, KnobType / nibble high, nibble low / f7
};
enum SysexIndex
@@ -22,6 +24,8 @@ namespace n2x
IdxN2x,
IdxMsgType,
IdxMsgSpec,
+ IdxPotPosH,
+ IdxPotPosL
};
enum SingleParam
diff --git a/source/nord/n2x/n2xLib/n2xstate.cpp b/source/nord/n2x/n2xLib/n2xstate.cpp
@@ -249,6 +249,18 @@ namespace n2x
if(sysex.size() == g_patchRequestSize)
return false;
+ if(bank == n2x::SysexByte::EmuSetPotPosition)
+ {
+ KnobType knobType;
+ uint8_t knobValue;
+
+ if(parseKnobSysex(knobType, knobValue, sysex))
+ {
+ m_hardware->setKnobPosition(knobType, knobValue);
+ return true;
+ }
+ }
+
return false;
}
@@ -414,6 +426,30 @@ namespace n2x
return res;
}
+ std::vector<uint8_t> State::createKnobSysex(KnobType _type, uint8_t _value)
+ {
+ return {0xf0, IdClavia, DefaultDeviceId, IdN2X,
+ EmuSetPotPosition,
+ static_cast<uint8_t>(_type),
+ static_cast<uint8_t>(_value >> 4),
+ static_cast<uint8_t>(_value & 0x0f),
+ 0xf7
+ };
+ }
+
+ bool State::parseKnobSysex(KnobType& _type, uint8_t& _value, const std::vector<uint8_t>& _sysex)
+ {
+ if(_sysex.size() <= SysexIndex::IdxPotPosL)
+ 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]);
+
+ 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
@@ -5,6 +5,7 @@
#include <cstddef>
#include "n2xmiditypes.h"
+#include "n2xtypes.h"
#include "synthLib/midiTypes.h"
@@ -106,6 +107,9 @@ namespace n2x
_dump[_off+1] = _value >> 4;
}
+ 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);
+
private:
template<size_t Size> bool receive(const std::array<uint8_t, Size>& _data)
{