From c81f74100b4e1e7251d81ee58f3227200dd3dcc1 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Mon, 14 Dec 2020 19:35:21 +0100 Subject: [PATCH] Add CC message processing for OSC --- src/sfizz/Synth.cpp | 34 +++++++++++++++++++++++++----- src/sfizz/SynthMessaging.cpp | 41 ++++++++++++++++++++++++++++++++++++ src/sfizz/SynthPrivate.h | 5 +++++ 3 files changed, 75 insertions(+), 5 deletions(-) diff --git a/src/sfizz/Synth.cpp b/src/sfizz/Synth.cpp index 93617268..e50df231 100644 --- a/src/sfizz/Synth.cpp +++ b/src/sfizz/Synth.cpp @@ -244,7 +244,7 @@ void Synth::Impl::clear() resources_.midiState.reset(); resources_.filePool.clear(); resources_.filePool.setRamLoading(config::loadInRam); - ccLabels_.clear(); + clearCCLabels(); keyLabels_.clear(); keyswitchLabels_.clear(); globalOpcodes_.clear(); @@ -261,9 +261,9 @@ void Synth::Impl::clear() setDefaultHdcc(11, 1.0f); // set default controller labels - insertPairUniquely(ccLabels_, 7, "Volume"); - insertPairUniquely(ccLabels_, 10, "Pan"); - insertPairUniquely(ccLabels_, 11, "Expression"); + setCCLabel(7, "Volume"); + setCCLabel(10, "Pan"); + setCCLabel(11, "Expression"); } void Synth::Impl::handleMasterOpcodes(const std::vector& members) @@ -365,7 +365,7 @@ void Synth::Impl::handleControlOpcodes(const std::vector& members) break; case hash("label_cc&"): if (Default::ccNumberRange.containsWithEnd(member.parameters.back())) - insertPairUniquely(ccLabels_, member.parameters.back(), std::string(member.value)); + setCCLabel(member.parameters.back(), std::string(member.value)); break; case hash("label_key&"): if (member.parameters.back() <= Default::keyRange.getEnd()) { @@ -1794,6 +1794,30 @@ std::bitset Synth::Impl::collectAllUsedCCs() return used; } +const std::string* Synth::Impl::getCCLabel(int ccNumber) +{ + auto it = ccLabelsMap_.find(ccNumber); + return (it == ccLabelsMap_.end()) ? nullptr : &ccLabels_[it->second].second; +} + +void Synth::Impl::setCCLabel(int ccNumber, std::string name) +{ + auto it = ccLabelsMap_.find(ccNumber); + if (it != ccLabelsMap_.end()) + ccLabels_[it->second].second = std::move(name); + else { + size_t index = ccLabels_.size(); + ccLabels_.emplace_back(ccNumber, std::move(name)); + ccLabelsMap_[ccNumber] = index; + } +} + +void Synth::Impl::clearCCLabels() +{ + ccLabels_.clear(); + ccLabelsMap_.clear(); +} + Parser& Synth::getParser() noexcept { Impl& impl = *impl_; diff --git a/src/sfizz/SynthMessaging.cpp b/src/sfizz/SynthMessaging.cpp index cabb85ec..68dbf362 100644 --- a/src/sfizz/SynthMessaging.cpp +++ b/src/sfizz/SynthMessaging.cpp @@ -36,6 +36,47 @@ void sfz::Synth::dispatchMessage(Client& client, int delay, const char* path, co client.receive(delay, "/hello", "", nullptr); } break; + //---------------------------------------------------------------------- + + MATCH("/cc/slots", "") { + uint8_t data[(config::numCCs + 7) / 8] = {}; + + const std::bitset& ccs = impl.currentUsedCCs_; + for (unsigned i = 0; i < config::numCCs; ++i) + data[i / 8] |= ccs.test(i) << (i % 8); + + sfizz_blob_t blob { data, sizeof(data) }; + client.receive<'b'>(delay, path, &blob); + } break; + + MATCH("/cc&/default", "") { + if (indices[0] >= config::numCCs) + break; + client.receive<'f'>(delay, path, impl.defaultCCValues_[indices[0]]); + } break; + + MATCH("/cc&/value", "") { + if (indices[0] >= config::numCCs) + break; + // Note: result value is not frame-exact + client.receive<'f'>(delay, path, impl.resources_.midiState.getCCValue(indices[0])); + } break; + + MATCH("/cc&/value", "f") { + if (indices[0] >= config::numCCs) + break; + impl.resources_.midiState.ccEvent(delay, indices[0], args[0].f); + } break; + + MATCH("/cc&/label", "") { + if (indices[0] >= config::numCCs) + break; + const std::string* label = impl.getCCLabel(indices[0]); + client.receive<'s'>(delay, path, label ? label->c_str() : ""); + } break; + + //---------------------------------------------------------------------- + MATCH("/region&/delay", "") { GET_REGION_OR_BREAK(indices[0]) client.receive<'f'>(delay, path, region.delay); diff --git a/src/sfizz/SynthPrivate.h b/src/sfizz/SynthPrivate.h index 42063ed0..43c5b5a8 100644 --- a/src/sfizz/SynthPrivate.h +++ b/src/sfizz/SynthPrivate.h @@ -179,6 +179,10 @@ struct Synth::Impl final: public Parser::Listener { std::bitset collectAllUsedCCs(); + const std::string* getCCLabel(int ccNumber); + void setCCLabel(int ccNumber, std::string name); + void clearCCLabels(); + /** * @brief Perform a CC event * @@ -208,6 +212,7 @@ struct Synth::Impl final: public Parser::Listener { // Names for the CC and notes as set by label_cc and label_key std::vector ccLabels_; + std::map ccLabelsMap_; std::vector keyLabels_; std::vector keyswitchLabels_;