commit 6f903c4164f4360019907de9db5f0e07b22fc863
parent 11c66c24a10c52f60cd58258fcf97e5ced439b48
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date: Thu, 30 Dec 2021 22:16:52 +0100
rework bank numbers to use strong typed enum to prevent -1/+1 problem at compile time
Diffstat:
10 files changed, 154 insertions(+), 80 deletions(-)
diff --git a/source/jucePlugin/PluginEditor.cpp b/source/jucePlugin/PluginEditor.cpp
@@ -48,19 +48,20 @@ AudioPluginAudioProcessorEditor::AudioPluginAudioProcessorEditor(AudioPluginAudi
loadFile();
};
- for (auto pt = 0; pt < 16; pt++)
+ for (uint8_t pt = 0; pt < 16; pt++)
{
m_partSelectors[pt].onClick = [this, pt]() {
juce::PopupMenu selector;
- for(auto b=0; b<processorRef.getController().getBankCount(); ++b)
+ for(uint8_t b=0; b<processorRef.getController().getBankCount(); ++b)
{
- auto bank = processorRef.getController().getSinglePresetNames(b);
+ const auto bank = virusLib::fromArrayIndex(b);
+ auto presetNames = processorRef.getController().getSinglePresetNames(bank);
juce::PopupMenu p;
- for (auto i = 0; i < 128; i++)
+ for (uint8_t i = 0; i < 128; i++)
{
- p.addItem(bank[i], [this, b, i, pt] { processorRef.getController().setCurrentPartPreset(pt, b, i); });
+ p.addItem(presetNames[i], [this, bank, i, pt] { processorRef.getController().setCurrentPartPreset(pt, bank, i); });
}
std::stringstream bankName;
bankName << "Bank " << static_cast<char>('A' + b);
diff --git a/source/jucePlugin/VirusController.cpp b/source/jucePlugin/VirusController.cpp
@@ -180,8 +180,16 @@ namespace Virus
*/
}
- juce::StringArray Controller::getSinglePresetNames(int bank) const
+ juce::StringArray Controller::getSinglePresetNames(virusLib::BankNumber _bank) const
{
+ if (_bank == virusLib::BankNumber::EditBuffer)
+ {
+ jassertfalse;
+ return {};
+ }
+
+ const auto bank = virusLib::toArrayIndex(_bank);
+
if (bank >= m_singles.size() || bank < 0)
{
jassertfalse;
@@ -212,9 +220,17 @@ namespace Virus
return juce::String(text);
}
- void Controller::setCurrentPartPreset(uint8_t part, uint8_t bank, uint8_t prg)
+ void Controller::setCurrentPartPreset(uint8_t part, virusLib::BankNumber _bank, uint8_t prg)
{
- if (bank < 0 || bank >= m_singles.size() || prg < 0 || prg > 127)
+ if(_bank == virusLib::BankNumber::EditBuffer || prg < 0 || prg > 127)
+ {
+ jassertfalse;
+ return;
+ }
+
+ const auto bank = virusLib::toArrayIndex(_bank);
+
+ if (bank >= m_singles.size())
{
jassertfalse;
return;
@@ -227,11 +243,11 @@ namespace Virus
patch.push_back(preset.data[i]);
sendSysEx(constructMessage(patch));
sendSysEx(constructMessage({MessageType::REQUEST_ARRANGEMENT}));
- m_currentBank[part] = bank;
+ m_currentBank[part] = _bank;
m_currentProgram[part] = prg;
}
- uint8_t Controller::getCurrentPartBank(uint8_t part) { return m_currentBank[part]; }
+ virusLib::BankNumber Controller::getCurrentPartBank(uint8_t part) { return m_currentBank[part]; }
uint8_t Controller::getCurrentPartProgram(uint8_t part) { return m_currentProgram[part]; }
void Controller::parseSingle(const SysEx &msg)
{
@@ -243,7 +259,7 @@ namespace Virus
assert(hasChecksum || dataSize == expectedDataSize);
SinglePatch patch;
- patch.bankNumber = msg[kHeaderWithMsgCodeLen];
+ patch.bankNumber = virusLib::fromMidiByte(msg[kHeaderWithMsgCodeLen]);
patch.progNumber = msg[kHeaderWithMsgCodeLen + 1];
[[maybe_unused]] const auto dataSum = copyData(msg, kHeaderWithMsgCodeLen + 2, patch.data);
@@ -251,16 +267,15 @@ namespace Virus
{
const auto checksum = msg[msg.size() - 2];
const auto deviceId = msg[5];
- [[maybe_unused]] const auto expectedSum =
- (deviceId + 0x10 + patch.bankNumber + patch.progNumber + dataSum) & 0x7f;
+ [[maybe_unused]] const auto expectedSum = (deviceId + 0x10 + virusLib::toMidiByte(patch.bankNumber) + patch.progNumber + dataSum) & 0x7f;
assert(expectedSum == checksum);
}
- if (patch.bankNumber == 0)
+ if (patch.bankNumber == virusLib::BankNumber::EditBuffer)
{
// virus sends also the single buffer not matter what's the mode.
// instead of keeping both, we 'encapsulate' this into first channel.
// the logic to maintain this is done by listening the global single/multi param.
- if (isMultiMode() && patch.progNumber == 0x40)
+ if (isMultiMode() && patch.progNumber == virusLib::SINGLE)
return;
else if (!isMultiMode() && patch.progNumber == 0x0)
return;
@@ -274,7 +289,7 @@ namespace Virus
}
}
else
- m_singles[patch.bankNumber - 1][patch.progNumber] = patch;
+ m_singles[virusLib::toArrayIndex(patch.bankNumber)][patch.progNumber] = patch;
const auto namePos = kHeaderWithMsgCodeLen + 2 + 128 + 112;
assert(namePos < msg.size());
diff --git a/source/jucePlugin/VirusController.h b/source/jucePlugin/VirusController.h
@@ -4,6 +4,11 @@
#include "../synthLib/plugin.h"
#include "VirusParameter.h"
+namespace virusLib
+{
+ enum class BankNumber : uint8_t;
+}
+
class AudioPluginAudioProcessor;
namespace Virus
@@ -29,12 +34,12 @@ namespace Virus
juce::Value *getParam(uint8_t ch, uint8_t bank, uint8_t paramIndex);
// bank - 0-1 (AB)
- juce::StringArray getSinglePresetNames(int bank) const;
+ juce::StringArray getSinglePresetNames(virusLib::BankNumber bank) const;
juce::StringArray getMultiPresetsName() const;
bool isMultiMode() { return getParam(0, 2, 0x7a)->getValue(); }
// part 0 - 15 (ignored when single! 0x40...)
- void setCurrentPartPreset(uint8_t part, uint8_t bank, uint8_t prg);
- uint8_t getCurrentPartBank(uint8_t part);
+ void setCurrentPartPreset(uint8_t part, virusLib::BankNumber bank, uint8_t prg);
+ virusLib::BankNumber getCurrentPartBank(uint8_t part);
uint8_t getCurrentPartProgram(uint8_t part);
juce::String getCurrentPartPresetName(uint8_t part);
uint32_t getBankCount() const { return static_cast<uint32_t>(m_singles.size()); }
@@ -53,7 +58,7 @@ namespace Virus
struct SinglePatch
{
- uint8_t bankNumber;
+ virusLib::BankNumber bankNumber;
uint8_t progNumber;
uint8_t data[kDataSizeInBytes];
};
@@ -103,7 +108,7 @@ namespace Virus
juce::CriticalSection m_eventQueueLock;
std::vector<synthLib::SMidiEvent> m_virusOut;
unsigned char m_deviceId;
- uint8_t m_currentBank[16];
+ virusLib::BankNumber m_currentBank[16];
uint8_t m_currentProgram[16];
};
}; // namespace Virus
diff --git a/source/jucePlugin/VirusParameter.h b/source/jucePlugin/VirusParameter.h
@@ -69,8 +69,8 @@ namespace Virus
{
// brute force but this should be O(1) of 128...
for (auto i = 0; i < 128; i++)
- if (m_desc.valueToTextFunction(i, m_desc) == text)
- return convertTo0to1(i);
+ if (m_desc.valueToTextFunction(static_cast<float>(i), m_desc) == text)
+ return convertTo0to1(static_cast<float>(i));
}
return convertTo0to1(text.getFloatValue());
}
diff --git a/source/virusLib/CMakeLists.txt b/source/virusLib/CMakeLists.txt
@@ -8,7 +8,7 @@ set(SOURCES
midiOutParser.cpp midiOutParser.h
romfile.cpp romfile.h
microcontroller.cpp microcontroller.h
- microcontrollerTypes.h
+ microcontrollerTypes.cpp microcontrollerTypes.h
)
target_sources(virusLib PRIVATE ${SOURCES})
diff --git a/source/virusLib/microcontroller.cpp b/source/virusLib/microcontroller.cpp
@@ -96,7 +96,7 @@ void Microcontroller::createDefaultState()
sendControlCommand(PLAY_MODE, g_defaultPlayMode);
if constexpr (g_defaultPlayMode == PlayModeSingle)
- writeSingle(0, SINGLE, m_singleEditBuffer);
+ writeSingle(BankNumber::EditBuffer, SINGLE, m_singleEditBuffer);
else
loadMulti(0, m_multiEditBuffer);
}
@@ -199,7 +199,7 @@ bool Microcontroller::sendMIDI(const SMidiEvent& _ev, bool cancelIfFull/* = fals
if(getSingle(m_currentBank, _ev.b, single))
{
m_currentSingle = _ev.b;
- return writeSingle(0, SINGLE, single);
+ return writeSingle(BankNumber::EditBuffer, SINGLE, single);
}
}
else
@@ -262,7 +262,7 @@ bool Microcontroller::sendSysex(const std::vector<uint8_t>& _data, bool _cancelI
response.push_back(deviceId);
};
- auto buildPresetResponse = [&](const uint8_t _type, const uint8_t _bank, const uint8_t _program, const TPreset& _dump)
+ auto buildPresetResponse = [&](const uint8_t _type, const BankNumber _bank, const uint8_t _program, const TPreset& _dump)
{
SMidiEvent ev;
ev.source = _source;
@@ -272,7 +272,7 @@ bool Microcontroller::sendSysex(const std::vector<uint8_t>& _data, bool _cancelI
buildResponseHeader(ev);
response.push_back(_type);
- response.push_back(_bank);
+ response.push_back(toMidiByte(_bank));
response.push_back(_program);
for(const auto value : _dump)
@@ -293,7 +293,7 @@ bool Microcontroller::sendSysex(const std::vector<uint8_t>& _data, bool _cancelI
_responses.emplace_back(std::move(ev));
};
- auto buildSingleResponse = [&](const uint8_t _bank, const uint8_t _program)
+ auto buildSingleResponse = [&](const BankNumber _bank, const uint8_t _program)
{
TPreset dump;
const auto res = requestSingle(_bank, _program, dump);
@@ -301,7 +301,7 @@ bool Microcontroller::sendSysex(const std::vector<uint8_t>& _data, bool _cancelI
buildPresetResponse(DUMP_SINGLE, _bank, _program, dump);
};
- auto buildMultiResponse = [&](const uint8_t _bank, const uint8_t _program)
+ auto buildMultiResponse = [&](const BankNumber _bank, const uint8_t _program)
{
TPreset dump;
const auto res = requestMulti(_bank, _program, dump);
@@ -309,12 +309,17 @@ bool Microcontroller::sendSysex(const std::vector<uint8_t>& _data, bool _cancelI
buildPresetResponse(DUMP_MULTI, _bank, _program, dump);
};
- auto buildSingleBankResponse = [&](const uint8_t _bank)
+ auto buildSingleBankResponse = [&](const BankNumber _bank)
{
- if(_bank > 0 && _bank <= m_singles.size())
+ if (_bank == BankNumber::EditBuffer)
+ return;
+
+ const auto bankIndex = toArrayIndex(_bank);
+
+ if(bankIndex < m_singles.size())
{
// eat this, host, whoever you are. 128 single packets
- for(uint8_t i=0; i<m_singles[_bank-1].size(); ++i)
+ for(uint8_t i=0; i<m_singles[bankIndex].size(); ++i)
{
TPreset data;
const auto res = requestSingle(_bank, i, data);
@@ -323,9 +328,9 @@ bool Microcontroller::sendSysex(const std::vector<uint8_t>& _data, bool _cancelI
}
};
- auto buildMultiBankResponse = [&](const uint8_t _bank)
+ auto buildMultiBankResponse = [&](const BankNumber _bank)
{
- if(_bank == 1)
+ if(_bank == BankNumber::A)
{
// eat this, host, whoever you are. 128 multi packets
for(uint8_t i=0; i<g_presetsPerBank; ++i)
@@ -363,9 +368,9 @@ bool Microcontroller::sendSysex(const std::vector<uint8_t>& _data, bool _cancelI
auto buildTotalResponse = [&]()
{
buildGlobalResponses();
- buildSingleBankResponse(1);
- buildSingleBankResponse(2);
- buildMultiBankResponse(1);
+ buildSingleBankResponse(BankNumber::A);
+ buildSingleBankResponse(BankNumber::B);
+ buildMultiBankResponse(BankNumber::A);
};
auto buildArrangementResponse = [&]()
@@ -375,22 +380,22 @@ bool Microcontroller::sendSysex(const std::vector<uint8_t>& _data, bool _cancelI
const bool isMultiMode = m_globalSettings[PLAY_MODE] == PlayModeMulti;
if(isMultiMode)
- buildSingleResponse(0, SINGLE);
+ buildSingleResponse(BankNumber::EditBuffer, SINGLE);
- buildMultiResponse(0, 0);
+ buildMultiResponse(BankNumber::EditBuffer, 0);
for(uint8_t p=0; p<16; ++p)
- buildPresetResponse(DUMP_SINGLE, 0, p, m_singleEditBuffers[p]);
+ buildPresetResponse(DUMP_SINGLE, BankNumber::EditBuffer, p, m_singleEditBuffers[p]);
if(!isMultiMode)
- buildSingleResponse(0, SINGLE);
+ buildSingleResponse(BankNumber::EditBuffer, SINGLE);
};
auto buildControllerDumpResponse = [&](uint8_t _part)
{
TPreset _dump, _multi;
- const auto res = requestSingle(0, _part, _dump);
- const auto resm = requestMulti(0, 0, _multi);
+ const auto res = requestSingle(BankNumber::EditBuffer, _part, _dump);
+ const auto resm = requestMulti(BankNumber::EditBuffer, 0, _multi);
const uint8_t channel = _part == SINGLE ? m_globalSettings[GLOBAL_CHANNEL] : _multi[static_cast<size_t>(MD_PART_MIDI_CHANNEL) + _part];
for (const auto cc : g_pageA)
{
@@ -417,33 +422,33 @@ bool Microcontroller::sendSysex(const std::vector<uint8_t>& _data, bool _cancelI
{
case DUMP_SINGLE:
{
- const uint8_t bank = _data[7];
+ const auto bank = fromMidiByte(_data[7]);
const uint8_t program = _data[8];
- LOG("Received Single dump, Bank " << (int)bank << ", program " << (int)program);
+ LOG("Received Single dump, Bank " << (int)toMidiByte(bank) << ", program " << (int)program);
TPreset dump;
std::copy_n(_data.data() + g_sysexPresetHeaderSize, dump.size(), dump.begin());
return writeSingle(bank, program, dump);
}
case DUMP_MULTI:
{
- const uint8_t bank = _data[7];
+ const auto bank = fromMidiByte(_data[7]);
const uint8_t program = _data[8];
- LOG("Received Multi dump, Bank " << (int)bank << ", program " << (int)program);
+ LOG("Received Multi dump, Bank " << (int)toMidiByte(bank) << ", program " << (int)program);
TPreset dump;
std::copy_n(_data.data() + g_sysexPresetHeaderSize, dump.size(), dump.begin());
return writeMulti(bank, program, dump);
}
case REQUEST_SINGLE:
{
- const uint8_t bank = _data[7];
+ const auto bank = fromMidiByte(_data[7]);
const uint8_t program = _data[8];
- LOG("Request Single, Bank " << (int)bank << ", program " << (int)program);
+ LOG("Request Single, Bank " << (int)toMidiByte(bank) << ", program " << (int)program);
buildSingleResponse(bank, program);
break;
}
case REQUEST_MULTI:
{
- const uint8_t bank = _data[7];
+ const auto bank = fromMidiByte(_data[7]);
const uint8_t program = _data[8];
LOG("Request Multi, Bank " << (int)bank << ", program " << (int)program);
buildMultiResponse(bank, program);
@@ -451,19 +456,19 @@ bool Microcontroller::sendSysex(const std::vector<uint8_t>& _data, bool _cancelI
}
case REQUEST_BANK_SINGLE:
{
- const uint8_t bank = _data[7];
+ const auto bank = fromMidiByte(_data[7]);
buildSingleBankResponse(bank);
break;
}
case REQUEST_BANK_MULTI:
{
- const uint8_t bank = _data[7];
+ const auto bank = fromMidiByte(_data[7]);
buildMultiBankResponse(bank);
break;
}
case REQUEST_CONTROLLER_DUMP:
{
- const uint8_t part = _data[8];
+ const auto part = _data[8];
if (part < 16 || part == SINGLE)
buildControllerDumpResponse(part);
break;
@@ -506,15 +511,15 @@ bool Microcontroller::sendSysex(const std::vector<uint8_t>& _data, bool _cancelI
m_globalSettings[PLAY_MODE] = playMode;
LOG("Switch to Single mode");
- return writeSingle(0, SINGLE, m_singleEditBuffer);
+ return writeSingle(BankNumber::EditBuffer, SINGLE, m_singleEditBuffer);
}
case PlayModeMultiSingle:
case PlayModeMulti:
{
m_globalSettings[PLAY_MODE] = PlayModeMulti;
- writeMulti(0, 0, m_multiEditBuffer);
+ writeMulti(BankNumber::EditBuffer, 0, m_multiEditBuffer);
for(uint8_t i=0; i<16; ++i)
- writeSingle(0, i, m_singleEditBuffers[i]);
+ writeSingle(BankNumber::EditBuffer, i, m_singleEditBuffers[i]);
return true;
}
default:
@@ -610,25 +615,25 @@ void Microcontroller::waitUntilReady() const
}
}
-bool Microcontroller::requestMulti(uint8_t _bank, uint8_t _program, TPreset& _data) const
+bool Microcontroller::requestMulti(BankNumber _bank, uint8_t _program, TPreset& _data) const
{
- if (_bank == 0)
+ if (_bank == BankNumber::EditBuffer)
{
// Use multi-edit buffer
_data = m_multiEditBuffer;
return true;
}
- if (_bank != 1)
+ if (_bank != BankNumber::A)
return false;
// Load from flash
return m_rom.getMulti(_program, _data);
}
-bool Microcontroller::requestSingle(uint8_t _bank, uint8_t _program, TPreset& _data) const
+bool Microcontroller::requestSingle(BankNumber _bank, uint8_t _program, TPreset& _data) const
{
- if (_bank == 0)
+ if (_bank == BankNumber::EditBuffer)
{
// Use single-edit buffer
if(_program == SINGLE)
@@ -640,20 +645,22 @@ bool Microcontroller::requestSingle(uint8_t _bank, uint8_t _program, TPreset& _d
}
// Load from flash
- return getSingle(_bank - 1, _program, _data);
+ return getSingle(toArrayIndex(_bank), _program, _data);
}
-bool Microcontroller::writeSingle(uint8_t _bank, uint8_t _program, const TPreset& _data)
+bool Microcontroller::writeSingle(BankNumber _bank, uint8_t _program, const TPreset& _data)
{
- if (_bank > 0)
+ if (_bank != BankNumber::EditBuffer)
{
- if(_bank >= m_singles.size() || _bank >= g_singleRamBankCount)
+ const auto bank = toArrayIndex(_bank);
+
+ if(bank >= m_singles.size() || bank >= g_singleRamBankCount)
return true; // out of range
- if(_program >= m_singles[_bank].size())
+ if(_program >= m_singles[bank].size())
return true; // out of range
- m_singles[_bank][_program] = _data;
+ m_singles[bank][_program] = _data;
return true;
}
@@ -669,11 +676,11 @@ bool Microcontroller::writeSingle(uint8_t _bank, uint8_t _program, const TPreset
return sendPreset(_program, presetToDSPWords(_data), false);
}
-bool Microcontroller::writeMulti(uint8_t _bank, uint8_t _program, const TPreset& _data)
+bool Microcontroller::writeMulti(BankNumber _bank, uint8_t _program, const TPreset& _data)
{
- if (_bank != 0)
+ if (_bank != BankNumber::EditBuffer)
{
- LOG("We do not support writing to flash, attempt to write multi to bank " << _bank << ", program " << _program);
+ LOG("We do not support writing to RAM or ROM, attempt to write multi to bank " << static_cast<int>(toMidiByte(_bank)) << ", program " << static_cast<int>(_program));
return true;
}
@@ -704,7 +711,7 @@ bool Microcontroller::partProgramChange(const uint8_t _part, const uint8_t _valu
if(getSingle(bank, _value, single))
{
m_multiEditBuffer[MD_PART_PROGRAM_NUMBER + _part] = _value;
- return writeSingle(0, _part, single);
+ return writeSingle(BankNumber::EditBuffer, _part, single);
}
return true;
@@ -722,7 +729,7 @@ bool Microcontroller::multiProgramChange(uint8_t _value)
bool Microcontroller::loadMulti(uint8_t _program, const TPreset& _multi)
{
- if(!writeMulti(0, _program, _multi))
+ if(!writeMulti(BankNumber::EditBuffer, _program, _multi))
return false;
for (uint8_t p = 0; p < 16; ++p)
diff --git a/source/virusLib/microcontroller.h b/source/virusLib/microcontroller.h
@@ -25,10 +25,10 @@ public:
bool sendMIDI(const synthLib::SMidiEvent& _ev, bool cancelIfFull = false);
bool sendSysex(const std::vector<uint8_t>& _data, bool _cancelIfFull, std::vector<synthLib::SMidiEvent>& _responses, synthLib::MidiEventSource _source);
- bool writeSingle(uint8_t _bank, uint8_t _program, const TPreset& _data);
- bool writeMulti(uint8_t _bank, uint8_t _program, const TPreset& _data);
- bool requestMulti(uint8_t _bank, uint8_t _program, TPreset& _data) const;
- bool requestSingle(uint8_t _bank, uint8_t _program, TPreset& _data) const;
+ bool writeSingle(BankNumber _bank, uint8_t _program, const TPreset& _data);
+ bool writeMulti(BankNumber _bank, uint8_t _program, const TPreset& _data);
+ bool requestMulti(BankNumber _bank, uint8_t _program, TPreset& _data) const;
+ bool requestSingle(BankNumber _bank, uint8_t _program, TPreset& _data) const;
void sendInitControlCommands();
diff --git a/source/virusLib/microcontrollerTypes.cpp b/source/virusLib/microcontrollerTypes.cpp
@@ -0,0 +1,26 @@
+#include "microcontrollerTypes.h"
+
+#include <cassert>
+
+namespace virusLib
+{
+ uint8_t toMidiByte(BankNumber _bank)
+ {
+ return static_cast<uint8_t>(_bank);
+ }
+ BankNumber fromMidiByte(uint8_t _byte)
+ {
+ return static_cast<BankNumber>(_byte);
+ }
+ uint32_t toArrayIndex(BankNumber _bank)
+ {
+ const auto bank = static_cast<uint8_t>(_bank);
+ assert(bank > 0);
+ return bank - 1;
+ }
+
+ BankNumber fromArrayIndex(uint8_t _bank)
+ {
+ return static_cast<BankNumber>(_bank + 1);
+ }
+}
diff --git a/source/virusLib/microcontrollerTypes.h b/source/virusLib/microcontrollerTypes.h
@@ -1,5 +1,7 @@
#pragma once
+#include <cstdint>
+
namespace virusLib
{
enum SysexMessageType : uint8_t
@@ -158,4 +160,23 @@ namespace virusLib
};
static constexpr uint8_t OMNI_DEVICE_ID = 0x10;
-}
-\ No newline at end of file
+
+ enum class BankNumber : uint8_t
+ {
+ EditBuffer,
+ A,
+ B,
+ C,
+ D,
+ E,
+ F,
+ G,
+ H,
+ Count
+ };
+
+ uint8_t toMidiByte(BankNumber _bank);
+ BankNumber fromMidiByte(uint8_t _byte);
+ uint32_t toArrayIndex(BankNumber _bank);
+ BankNumber fromArrayIndex(uint8_t _bank);
+}
diff --git a/source/virusTestConsole/virusTestConsole.cpp b/source/virusTestConsole/virusTestConsole.cpp
@@ -51,7 +51,7 @@ void audioCallback(dsp56k::Audio* audio)
break;
case 64:
LOG("Sending Preset");
- microcontroller->writeSingle(0, SINGLE, preset);
+ microcontroller->writeSingle(BankNumber::EditBuffer, SINGLE, preset);
break;
case 128:
LOG("Sending Note On");