Merge pull request #665 from jpcima/show-keyswitch
Display the active keyswitch in the editor
This commit is contained in:
commit
9123f206fc
6 changed files with 139 additions and 18 deletions
|
|
@ -60,9 +60,9 @@ widget_class mainView {open
|
||||||
xywh {195 11 250 31} labelsize 20 align 20
|
xywh {195 11 250 31} labelsize 20 align 20
|
||||||
class ClickableLabel
|
class ClickableLabel
|
||||||
}
|
}
|
||||||
Fl_Box {} {
|
Fl_Box keyswitchLabel_ {
|
||||||
label {Key switch:}
|
label {Key switch:} selected
|
||||||
xywh {195 44 250 30} labelsize 20 align 20
|
xywh {195 44 360 30} labelsize 20 align 20
|
||||||
class Label
|
class Label
|
||||||
}
|
}
|
||||||
Fl_Box {} {
|
Fl_Box {} {
|
||||||
|
|
@ -221,7 +221,7 @@ widget_class mainView {open
|
||||||
class LogicalGroup
|
class LogicalGroup
|
||||||
} {
|
} {
|
||||||
Fl_Group {} {
|
Fl_Group {} {
|
||||||
label Engine open selected
|
label Engine open
|
||||||
xywh {305 135 195 100} box ROUNDED_BOX labelsize 12 align 17
|
xywh {305 135 195 100} box ROUNDED_BOX labelsize 12 align 17
|
||||||
class TitleGroup
|
class TitleGroup
|
||||||
} {
|
} {
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
#include <ghc/fs_std.hpp>
|
#include <ghc/fs_std.hpp>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <unordered_map>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
@ -49,6 +50,10 @@ struct Editor::Impl : EditorController::Receiver, IControlListener {
|
||||||
std::string userFilesDir_;
|
std::string userFilesDir_;
|
||||||
std::string fallbackFilesDir_;
|
std::string fallbackFilesDir_;
|
||||||
|
|
||||||
|
int currentKeyswitch_ = -1;
|
||||||
|
std::unordered_map<unsigned, std::string> keyswitchNames_;
|
||||||
|
std::string keyswitchLabelPrefix_;
|
||||||
|
|
||||||
SharedPointer<CVSTGUITimer> memQueryTimer_;
|
SharedPointer<CVSTGUITimer> memQueryTimer_;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
@ -102,6 +107,7 @@ struct Editor::Impl : EditorController::Receiver, IControlListener {
|
||||||
CTextLabel* tuningFrequencyLabel_ = nullptr;
|
CTextLabel* tuningFrequencyLabel_ = nullptr;
|
||||||
CControl *stretchedTuningSlider_ = nullptr;
|
CControl *stretchedTuningSlider_ = nullptr;
|
||||||
CTextLabel* stretchedTuningLabel_ = nullptr;
|
CTextLabel* stretchedTuningLabel_ = nullptr;
|
||||||
|
CTextLabel* keyswitchLabel_ = nullptr;
|
||||||
|
|
||||||
STitleContainer* userFilesGroup_ = nullptr;
|
STitleContainer* userFilesGroup_ = nullptr;
|
||||||
STextButton* userFilesDirButton_ = nullptr;
|
STextButton* userFilesDirButton_ = nullptr;
|
||||||
|
|
@ -170,12 +176,17 @@ struct Editor::Impl : EditorController::Receiver, IControlListener {
|
||||||
void updateTuningFrequencyLabel(float tuningFrequency);
|
void updateTuningFrequencyLabel(float tuningFrequency);
|
||||||
void updateStretchedTuningLabel(float stretchedTuning);
|
void updateStretchedTuningLabel(float stretchedTuning);
|
||||||
|
|
||||||
|
absl::string_view getCurrentKeyswitchName() const;
|
||||||
|
void updateKeyswitchNameLabel();
|
||||||
|
|
||||||
void updateKeyUsed(unsigned key, bool used);
|
void updateKeyUsed(unsigned key, bool used);
|
||||||
void updateKeyswitchUsed(unsigned key, bool used);
|
void updateKeyswitchUsed(unsigned key, bool used);
|
||||||
void updateCCUsed(unsigned cc, bool used);
|
void updateCCUsed(unsigned cc, bool used);
|
||||||
void updateCCValue(unsigned cc, float value);
|
void updateCCValue(unsigned cc, float value);
|
||||||
void updateCCDefaultValue(unsigned cc, float value);
|
void updateCCDefaultValue(unsigned cc, float value);
|
||||||
void updateCCLabel(unsigned cc, const char* label);
|
void updateCCLabel(unsigned cc, const char* label);
|
||||||
|
void updateSWLastCurrent(int sw);
|
||||||
|
void updateSWLastLabel(unsigned sw, const char* label);
|
||||||
void updateMemoryUsed(uint64_t mem);
|
void updateMemoryUsed(uint64_t mem);
|
||||||
|
|
||||||
// edition of CC by UI
|
// edition of CC by UI
|
||||||
|
|
@ -237,7 +248,7 @@ void Editor::open(CFrame& frame)
|
||||||
|
|
||||||
// request the whole Key and CC information
|
// request the whole Key and CC information
|
||||||
impl.sendQueuedOSC("/key/slots", "", nullptr);
|
impl.sendQueuedOSC("/key/slots", "", nullptr);
|
||||||
impl.sendQueuedOSC("/sw/slots", "", nullptr);
|
impl.sendQueuedOSC("/sw/last/slots", "", nullptr);
|
||||||
impl.sendQueuedOSC("/cc/slots", "", nullptr);
|
impl.sendQueuedOSC("/cc/slots", "", nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -268,7 +279,7 @@ void Editor::Impl::uiReceiveValue(EditId id, const EditValue& v)
|
||||||
|
|
||||||
// request the whole Key and CC information
|
// request the whole Key and CC information
|
||||||
sendQueuedOSC("/key/slots", "", nullptr);
|
sendQueuedOSC("/key/slots", "", nullptr);
|
||||||
sendQueuedOSC("/sw/slots", "", nullptr);
|
sendQueuedOSC("/sw/last/slots", "", nullptr);
|
||||||
sendQueuedOSC("/cc/slots", "", nullptr);
|
sendQueuedOSC("/cc/slots", "", nullptr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -430,13 +441,19 @@ void Editor::Impl::uiReceiveMessage(const char* path, const char* sig, const sfi
|
||||||
updateKeyUsed(key, used);
|
updateKeyUsed(key, used);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Messages::matchOSC("/sw/slots", path, indices) && !strcmp(sig, "b")) {
|
else if (Messages::matchOSC("/sw/last/slots", path, indices) && !strcmp(sig, "b")) {
|
||||||
size_t numBits = 8 * args[0].b->size;
|
size_t numBits = 8 * args[0].b->size;
|
||||||
ConstBitSpan bits { args[0].b->data, numBits };
|
ConstBitSpan bits { args[0].b->data, numBits };
|
||||||
for (unsigned key = 0; key < 128; ++key) {
|
for (unsigned key = 0; key < 128; ++key) {
|
||||||
bool used = key < numBits && bits.test(key);
|
bool used = key < numBits && bits.test(key);
|
||||||
updateKeyswitchUsed(key, used);
|
updateKeyswitchUsed(key, used);
|
||||||
|
if (used) {
|
||||||
|
char pathBuf[256];
|
||||||
|
sprintf(pathBuf, "/sw/last/%u/label", key);
|
||||||
|
sendQueuedOSC(pathBuf, "", nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
sendQueuedOSC("/sw/last/current", "", nullptr);
|
||||||
}
|
}
|
||||||
else if (Messages::matchOSC("/cc/slots", path, indices) && !strcmp(sig, "b")) {
|
else if (Messages::matchOSC("/cc/slots", path, indices) && !strcmp(sig, "b")) {
|
||||||
size_t numBits = 8 * args[0].b->size;
|
size_t numBits = 8 * args[0].b->size;
|
||||||
|
|
@ -476,6 +493,12 @@ void Editor::Impl::uiReceiveMessage(const char* path, const char* sig, const sfi
|
||||||
else if (Messages::matchOSC("/cc&/label", path, indices) && !strcmp(sig, "s")) {
|
else if (Messages::matchOSC("/cc&/label", path, indices) && !strcmp(sig, "s")) {
|
||||||
updateCCLabel(indices[0], args[0].s);
|
updateCCLabel(indices[0], args[0].s);
|
||||||
}
|
}
|
||||||
|
else if (Messages::matchOSC("/sw/last/current", path, indices) && !strcmp(sig, "i")) {
|
||||||
|
updateSWLastCurrent(args[0].i);
|
||||||
|
}
|
||||||
|
else if (Messages::matchOSC("/sw/last/&/label", path, indices) && !strcmp(sig, "s")) {
|
||||||
|
updateSWLastLabel(indices[0], args[0].s);
|
||||||
|
}
|
||||||
else if (Messages::matchOSC("/mem/buffers", path, indices) && !strcmp(sig, "h")) {
|
else if (Messages::matchOSC("/mem/buffers", path, indices) && !strcmp(sig, "h")) {
|
||||||
updateMemoryUsed(args[0].h);
|
updateMemoryUsed(args[0].h);
|
||||||
}
|
}
|
||||||
|
|
@ -808,6 +831,10 @@ void Editor::Impl::createFrameContents()
|
||||||
mainView_ = owned(mainView);
|
mainView_ = owned(mainView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
if (keyswitchLabel_)
|
||||||
|
keyswitchLabelPrefix_ = std::string(keyswitchLabel_->getText()) + ' ';
|
||||||
|
|
||||||
///
|
///
|
||||||
SharedPointer<SFileDropTarget> fileDropTarget = owned(new SFileDropTarget);
|
SharedPointer<SFileDropTarget> fileDropTarget = owned(new SFileDropTarget);
|
||||||
|
|
||||||
|
|
@ -1033,7 +1060,7 @@ void Editor::Impl::changeSfzFile(const std::string& filePath)
|
||||||
|
|
||||||
// request the whole Key and CC information
|
// request the whole Key and CC information
|
||||||
sendQueuedOSC("/key/slots", "", nullptr);
|
sendQueuedOSC("/key/slots", "", nullptr);
|
||||||
sendQueuedOSC("/sw/slots", "", nullptr);
|
sendQueuedOSC("/sw/last/slots", "", nullptr);
|
||||||
sendQueuedOSC("/cc/slots", "", nullptr);
|
sendQueuedOSC("/cc/slots", "", nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1347,6 +1374,27 @@ void Editor::Impl::updateStretchedTuningLabel(float stretchedTuning)
|
||||||
label->setText(text);
|
label->setText(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
absl::string_view Editor::Impl::getCurrentKeyswitchName() const
|
||||||
|
{
|
||||||
|
int sw = currentKeyswitch_;
|
||||||
|
if (sw == -1)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
auto it = keyswitchNames_.find(static_cast<unsigned>(sw));
|
||||||
|
if (it == keyswitchNames_.end())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Editor::Impl::updateKeyswitchNameLabel()
|
||||||
|
{
|
||||||
|
if (CTextLabel* label = keyswitchLabel_) {
|
||||||
|
std::string name { getCurrentKeyswitchName() };
|
||||||
|
label->setText((keyswitchLabelPrefix_ + name).c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Editor::Impl::updateKeyUsed(unsigned key, bool used)
|
void Editor::Impl::updateKeyUsed(unsigned key, bool used)
|
||||||
{
|
{
|
||||||
if (SPiano* piano = piano_)
|
if (SPiano* piano = piano_)
|
||||||
|
|
@ -1383,6 +1431,21 @@ void Editor::Impl::updateCCLabel(unsigned cc, const char* label)
|
||||||
panel->setControlLabelText(cc, label);
|
panel->setControlLabelText(cc, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Editor::Impl::updateSWLastCurrent(int sw)
|
||||||
|
{
|
||||||
|
if (currentKeyswitch_ == sw)
|
||||||
|
return;
|
||||||
|
currentKeyswitch_ = sw;
|
||||||
|
updateKeyswitchNameLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Editor::Impl::updateSWLastLabel(unsigned sw, const char* label)
|
||||||
|
{
|
||||||
|
keyswitchNames_[sw].assign(label);
|
||||||
|
if ((unsigned)currentKeyswitch_ == sw)
|
||||||
|
updateKeyswitchNameLabel();
|
||||||
|
}
|
||||||
|
|
||||||
void Editor::Impl::updateMemoryUsed(uint64_t mem)
|
void Editor::Impl::updateMemoryUsed(uint64_t mem)
|
||||||
{
|
{
|
||||||
if (CTextLabel* label = memoryLabel_) {
|
if (CTextLabel* label = memoryLabel_) {
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,8 @@ view__8->addView(view__10);
|
||||||
auto* const view__11 = createClickableLabel(CRect(10, 6, 260, 37), kTagLoadSfzFile, "DefaultInstrument.sfz", kLeftText, 20);
|
auto* const view__11 = createClickableLabel(CRect(10, 6, 260, 37), kTagLoadSfzFile, "DefaultInstrument.sfz", kLeftText, 20);
|
||||||
sfzFileLabel_ = view__11;
|
sfzFileLabel_ = view__11;
|
||||||
view__8->addView(view__11);
|
view__8->addView(view__11);
|
||||||
auto* const view__12 = createLabel(CRect(10, 39, 260, 69), -1, "Key switch:", kLeftText, 20);
|
auto* const view__12 = createLabel(CRect(10, 39, 370, 69), -1, "Key switch:", kLeftText, 20);
|
||||||
|
keyswitchLabel_ = view__12;
|
||||||
view__8->addView(view__12);
|
view__8->addView(view__12);
|
||||||
auto* const view__13 = createLabel(CRect(10, 71, 70, 96), -1, "Voices:", kRightText, 12);
|
auto* const view__13 = createLabel(CRect(10, 71, 70, 96), -1, "Voices:", kRightText, 12);
|
||||||
view__8->addView(view__13);
|
view__8->addView(view__13);
|
||||||
|
|
|
||||||
|
|
@ -241,6 +241,7 @@ void Synth::Impl::clear()
|
||||||
numGroups_ = 0;
|
numGroups_ = 0;
|
||||||
numMasters_ = 0;
|
numMasters_ = 0;
|
||||||
currentSwitch_ = absl::nullopt;
|
currentSwitch_ = absl::nullopt;
|
||||||
|
currentSwitchChanged_ = true;
|
||||||
defaultPath_ = "";
|
defaultPath_ = "";
|
||||||
resources_.midiState.reset();
|
resources_.midiState.reset();
|
||||||
resources_.filePool.clear();
|
resources_.filePool.clear();
|
||||||
|
|
@ -250,8 +251,8 @@ void Synth::Impl::clear()
|
||||||
changedCCsThisCycle_.clear();
|
changedCCsThisCycle_.clear();
|
||||||
keyLabels_.clear();
|
keyLabels_.clear();
|
||||||
keySlots_.clear();
|
keySlots_.clear();
|
||||||
swSlots_.clear();
|
swLastSlots_.clear();
|
||||||
keyswitchLabels_.clear();
|
clearKeyswitchLabels();
|
||||||
globalOpcodes_.clear();
|
globalOpcodes_.clear();
|
||||||
masterOpcodes_.clear();
|
masterOpcodes_.clear();
|
||||||
groupOpcodes_.clear();
|
groupOpcodes_.clear();
|
||||||
|
|
@ -623,7 +624,7 @@ void Synth::Impl::finalizeSfzLoad()
|
||||||
region->keySwitched = (*currentSwitch_ == *region->lastKeyswitch);
|
region->keySwitched = (*currentSwitch_ == *region->lastKeyswitch);
|
||||||
|
|
||||||
if (region->keyswitchLabel)
|
if (region->keyswitchLabel)
|
||||||
insertPairUniquely(keyswitchLabels_, *region->lastKeyswitch, *region->keyswitchLabel);
|
setKeyswitchLabel(*region->lastKeyswitch, *region->keyswitchLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (region->lastKeyswitchRange) {
|
if (region->lastKeyswitchRange) {
|
||||||
|
|
@ -633,7 +634,7 @@ void Synth::Impl::finalizeSfzLoad()
|
||||||
|
|
||||||
if (region->keyswitchLabel) {
|
if (region->keyswitchLabel) {
|
||||||
for (uint8_t note = range.getStart(), end = range.getEnd(); note <= end; note++)
|
for (uint8_t note = range.getStart(), end = range.getEnd(); note <= end; note++)
|
||||||
insertPairUniquely(keyswitchLabels_, note, *region->keyswitchLabel);
|
setKeyswitchLabel(note, *region->keyswitchLabel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -749,15 +750,17 @@ void Synth::Impl::finalizeSfzLoad()
|
||||||
// cache the set of keyswitches assigned
|
// cache the set of keyswitches assigned
|
||||||
for (const RegionPtr& regionPtr : regions_) {
|
for (const RegionPtr& regionPtr : regions_) {
|
||||||
if (absl::optional<uint8_t> sw = regionPtr->lastKeyswitch) {
|
if (absl::optional<uint8_t> sw = regionPtr->lastKeyswitch) {
|
||||||
swSlots_.set(*sw);
|
swLastSlots_.set(*sw);
|
||||||
}
|
}
|
||||||
else if (absl::optional<Range<uint8_t>> swRange = regionPtr->lastKeyswitchRange) {
|
else if (absl::optional<Range<uint8_t>> swRange = regionPtr->lastKeyswitchRange) {
|
||||||
unsigned loKey = swRange->getStart();
|
unsigned loKey = swRange->getStart();
|
||||||
unsigned hiKey = swRange->getEnd();
|
unsigned hiKey = swRange->getEnd();
|
||||||
for (unsigned key = loKey; key <= hiKey; ++key)
|
for (unsigned key = loKey; key <= hiKey; ++key)
|
||||||
swSlots_.set(key);
|
swLastSlots_.set(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// resend current keyswitch
|
||||||
|
currentSwitchChanged_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Synth::loadScalaFile(const fs::path& path)
|
bool Synth::loadScalaFile(const fs::path& path)
|
||||||
|
|
@ -985,6 +988,16 @@ void Synth::renderBlock(AudioSpan<float> buffer) noexcept
|
||||||
broadcaster.receive<'b'>(numFrames - 1, "/cc/changed", &blob);
|
broadcaster.receive<'b'>(numFrames - 1, "/cc/changed", &blob);
|
||||||
}
|
}
|
||||||
impl.changedCCsThisCycle_.clear();
|
impl.changedCCsThisCycle_.clear();
|
||||||
|
// Send the changed keyswitch
|
||||||
|
if (impl.currentSwitchChanged_) {
|
||||||
|
if (broadcaster.canReceive()) {
|
||||||
|
int32_t value = -1;
|
||||||
|
if (impl.currentSwitch_)
|
||||||
|
value = *impl.currentSwitch_;
|
||||||
|
broadcaster.receive<'i'>(numFrames - 1, "/sw/last/current", value);
|
||||||
|
}
|
||||||
|
impl.currentSwitchChanged_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
{ // Clear events and advance midi time
|
{ // Clear events and advance midi time
|
||||||
ScopedTiming logger { impl.dispatchDuration_, ScopedTiming::Operation::addToDuration };
|
ScopedTiming logger { impl.dispatchDuration_, ScopedTiming::Operation::addToDuration };
|
||||||
|
|
@ -1081,6 +1094,7 @@ void Synth::Impl::noteOnDispatch(int delay, int noteNumber, float velocity) noex
|
||||||
region->keySwitched = false;
|
region->keySwitched = false;
|
||||||
}
|
}
|
||||||
currentSwitch_ = noteNumber;
|
currentSwitch_ = noteNumber;
|
||||||
|
currentSwitchChanged_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& region : lastKeyswitchLists_[noteNumber])
|
for (auto& region : lastKeyswitchLists_[noteNumber])
|
||||||
|
|
@ -1869,12 +1883,36 @@ void Synth::Impl::setCCLabel(int ccNumber, std::string name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string* Synth::Impl::getKeyswitchLabel(int swNumber)
|
||||||
|
{
|
||||||
|
auto it = keyswitchLabelsMap_.find(swNumber);
|
||||||
|
return (it == keyswitchLabelsMap_.end()) ? nullptr : &keyswitchLabels_[it->second].second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Synth::Impl::setKeyswitchLabel(int swNumber, std::string name)
|
||||||
|
{
|
||||||
|
auto it = keyswitchLabelsMap_.find(swNumber);
|
||||||
|
if (it != keyswitchLabelsMap_.end())
|
||||||
|
keyswitchLabels_[it->second].second = std::move(name);
|
||||||
|
else {
|
||||||
|
size_t index = keyswitchLabels_.size();
|
||||||
|
keyswitchLabels_.emplace_back(swNumber, std::move(name));
|
||||||
|
keyswitchLabelsMap_[swNumber] = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Synth::Impl::clearCCLabels()
|
void Synth::Impl::clearCCLabels()
|
||||||
{
|
{
|
||||||
ccLabels_.clear();
|
ccLabels_.clear();
|
||||||
ccLabelsMap_.clear();
|
ccLabelsMap_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Synth::Impl::clearKeyswitchLabels()
|
||||||
|
{
|
||||||
|
keyswitchLabels_.clear();
|
||||||
|
keyswitchLabelsMap_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
Parser& Synth::getParser() noexcept
|
Parser& Synth::getParser() noexcept
|
||||||
{
|
{
|
||||||
Impl& impl = *impl_;
|
Impl& impl = *impl_;
|
||||||
|
|
|
||||||
|
|
@ -46,12 +46,26 @@ void sfz::Synth::dispatchMessage(Client& client, int delay, const char* path, co
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
MATCH("/sw/slots", "") {
|
MATCH("/sw/last/slots", "") {
|
||||||
const BitArray<128>& switches = impl.swSlots_;
|
const BitArray<128>& switches = impl.swLastSlots_;
|
||||||
sfizz_blob_t blob { switches.data(), static_cast<uint32_t>(switches.byte_size()) };
|
sfizz_blob_t blob { switches.data(), static_cast<uint32_t>(switches.byte_size()) };
|
||||||
client.receive<'b'>(delay, path, &blob);
|
client.receive<'b'>(delay, path, &blob);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
MATCH("/sw/last/current", "") {
|
||||||
|
int32_t value = -1;
|
||||||
|
if (impl.currentSwitch_)
|
||||||
|
value = *impl.currentSwitch_;
|
||||||
|
client.receive<'i'>(delay, path, value);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
MATCH("/sw/last/&/label", "") {
|
||||||
|
if (indices[0] >= 128)
|
||||||
|
break;
|
||||||
|
const std::string* label = impl.getKeyswitchLabel(indices[0]);
|
||||||
|
client.receive<'s'>(delay, path, label ? label->c_str() : "");
|
||||||
|
} break;
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
MATCH("/cc/slots", "") {
|
MATCH("/cc/slots", "") {
|
||||||
|
|
|
||||||
|
|
@ -184,6 +184,9 @@ struct Synth::Impl final: public Parser::Listener {
|
||||||
const std::string* getCCLabel(int ccNumber);
|
const std::string* getCCLabel(int ccNumber);
|
||||||
void setCCLabel(int ccNumber, std::string name);
|
void setCCLabel(int ccNumber, std::string name);
|
||||||
void clearCCLabels();
|
void clearCCLabels();
|
||||||
|
const std::string* getKeyswitchLabel(int swNumber);
|
||||||
|
void setKeyswitchLabel(int swNumber, std::string name);
|
||||||
|
void clearKeyswitchLabels();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Perform a CC event
|
* @brief Perform a CC event
|
||||||
|
|
@ -217,11 +220,13 @@ struct Synth::Impl final: public Parser::Listener {
|
||||||
std::map<int, size_t> ccLabelsMap_;
|
std::map<int, size_t> ccLabelsMap_;
|
||||||
std::vector<NoteNamePair> keyLabels_;
|
std::vector<NoteNamePair> keyLabels_;
|
||||||
BitArray<128> keySlots_;
|
BitArray<128> keySlots_;
|
||||||
BitArray<128> swSlots_;
|
BitArray<128> swLastSlots_;
|
||||||
std::vector<NoteNamePair> keyswitchLabels_;
|
std::vector<NoteNamePair> keyswitchLabels_;
|
||||||
|
std::map<int, size_t> keyswitchLabelsMap_;
|
||||||
|
|
||||||
// Set as sw_default if present in the file
|
// Set as sw_default if present in the file
|
||||||
absl::optional<uint8_t> currentSwitch_;
|
absl::optional<uint8_t> currentSwitch_;
|
||||||
|
bool currentSwitchChanged_ = true;
|
||||||
std::vector<std::string> unknownOpcodes_;
|
std::vector<std::string> unknownOpcodes_;
|
||||||
using RegionViewVector = std::vector<Region*>;
|
using RegionViewVector = std::vector<Region*>;
|
||||||
using VoiceViewVector = std::vector<Voice*>;
|
using VoiceViewVector = std::vector<Voice*>;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue