diff --git a/plugins/editor/src/editor/Editor.cpp b/plugins/editor/src/editor/Editor.cpp index 2866d04c..6c2af261 100644 --- a/plugins/editor/src/editor/Editor.cpp +++ b/plugins/editor/src/editor/Editor.cpp @@ -279,12 +279,6 @@ void Editor::open(CFrame& frame) impl.oscSendQueueTimer_ = makeOwned( [this](CVSTGUITimer* timer) { impl_->tickOSCQueue(timer); }, oscSendInterval, false); - - // request the whole Key and CC information - impl.sendQueuedOSC("/key/slots", "", nullptr); - impl.sendQueuedOSC("/sw/last/slots", "", nullptr); - impl.sendQueuedOSC("/cc/slots", "", nullptr); - impl.sendQueuedOSC("/image", "", nullptr); } void Editor::close() @@ -312,12 +306,6 @@ void Editor::Impl::uiReceiveValue(EditId id, const EditValue& v) const std::string& value = v.to_string(); currentSfzFile_ = value; updateSfzFileLabel(value); - - // request the whole Key and CC information - sendQueuedOSC("/key/slots", "", nullptr); - sendQueuedOSC("/sw/last/slots", "", nullptr); - sendQueuedOSC("/cc/slots", "", nullptr); - sendQueuedOSC("/image", "", nullptr); } break; case EditId::Volume: @@ -476,6 +464,10 @@ void Editor::Impl::uiReceiveValue(EditId id, const EditValue& v) } else if (editIdIsCCUsed(id)) { updateCCUsed(ccUsedForEditId(id), v.to_float() != 0); + // TODO(jpc) remove value requests, when implementing CC automation + char pathBuf[256]; + sprintf(pathBuf, "/cc%u/value", ccUsedForEditId(id)); + sendQueuedOSC(pathBuf, "", nullptr); } else if (editIdIsCCDefault(id)) { updateCCDefaultValue(ccDefaultForEditId(id), v.to_float()); @@ -491,46 +483,7 @@ void Editor::Impl::uiReceiveMessage(const char* path, const char* sig, const sfi { unsigned indices[8]; - if (Messages::matchOSC("/key/slots", path, indices) && !strcmp(sig, "b")) { - size_t numBits = 8 * args[0].b->size; - ConstBitSpan bits { args[0].b->data, numBits }; - for (unsigned key = 0; key < 128; ++key) { - bool used = key < numBits && bits.test(key); - updateKeyUsed(key, used); - } - } - else if (Messages::matchOSC("/sw/last/slots", path, indices) && !strcmp(sig, "b")) { - size_t numBits = 8 * args[0].b->size; - ConstBitSpan bits { args[0].b->data, numBits }; - for (unsigned key = 0; key < 128; ++key) { - bool used = key < numBits && bits.test(key); - 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")) { - size_t numBits = 8 * args[0].b->size; - ConstBitSpan bits { args[0].b->data, numBits }; - for (unsigned cc = 0; cc < numBits; ++cc) { - bool used = bits.test(cc); - updateCCUsed(cc, used); - if (used) { - char pathBuf[256]; - sprintf(pathBuf, "/cc%u/value", cc); - sendQueuedOSC(pathBuf, "", nullptr); - sprintf(pathBuf, "/cc%u/default", cc); - sendQueuedOSC(pathBuf, "", nullptr); - sprintf(pathBuf, "/cc%u/label", cc); - sendQueuedOSC(pathBuf, "", nullptr); - } - } - } - else if (Messages::matchOSC("/cc/changed", path, indices) && !strcmp(sig, "b")) { + if (Messages::matchOSC("/cc/changed~", path, indices) && !strcmp(sig, "b")) { size_t numBits = 8 * args[0].b->size; ConstBitSpan bits { args[0].b->data, numBits }; for (unsigned cc = 0; cc < numBits; ++cc) { @@ -545,24 +498,12 @@ void Editor::Impl::uiReceiveMessage(const char* path, const char* sig, const sfi else if (Messages::matchOSC("/cc&/value", path, indices) && !strcmp(sig, "f")) { updateCCValue(indices[0], args[0].f); } - else if (Messages::matchOSC("/cc&/default", path, indices) && !strcmp(sig, "f")) { - updateCCDefaultValue(indices[0], args[0].f); - } - else if (Messages::matchOSC("/cc&/label", path, indices) && !strcmp(sig, "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/current", path, indices) && !strcmp(sig, "N")) { updateSWLastCurrent(-1); } - else if (Messages::matchOSC("/sw/last/&/label", path, indices) && !strcmp(sig, "s")) { - updateSWLastLabel(indices[0], args[0].s); - } - else if (Messages::matchOSC("/image", path, indices) && !strcmp(sig, "s")) { - updateBackgroundImage(args[0].s); - } else if (Messages::matchOSC("/mem/buffers", path, indices) && !strcmp(sig, "h")) { updateMemoryUsed(args[0].h); } @@ -1176,12 +1117,6 @@ void Editor::Impl::changeSfzFile(const std::string& filePath) ctrl_->uiSendValue(EditId::SfzFile, filePath); currentSfzFile_ = filePath; updateSfzFileLabel(filePath); - - // request the whole Key and CC information - sendQueuedOSC("/key/slots", "", nullptr); - sendQueuedOSC("/sw/last/slots", "", nullptr); - sendQueuedOSC("/cc/slots", "", nullptr); - sendQueuedOSC("/image", "", nullptr); } void Editor::Impl::changeToNextSfzFile(long offset) diff --git a/plugins/lv2/sfizz.cpp b/plugins/lv2/sfizz.cpp index edf486bf..f597d2e9 100644 --- a/plugins/lv2/sfizz.cpp +++ b/plugins/lv2/sfizz.cpp @@ -942,6 +942,10 @@ run(LV2_Handle instance, uint32_t sample_count) // Render the block sfizz_render_block(self->synth, self->output_buffers, 2, (int)sample_count); + // Request OSC updates + sfizz_send_message(self->synth, self->client, 0, "/cc/changed~", "", nullptr); + sfizz_send_message(self->synth, self->client, 0, "/sw/last/current", "", nullptr); + spin_mutex_unlock(self->synth_mutex); if (self->midnam && self->must_update_midnam.exchange(0)) diff --git a/plugins/vst/SfizzVstProcessor.cpp b/plugins/vst/SfizzVstProcessor.cpp index 31e673c7..1bc97468 100644 --- a/plugins/vst/SfizzVstProcessor.cpp +++ b/plugins/vst/SfizzVstProcessor.cpp @@ -286,6 +286,11 @@ tresult PLUGIN_API SfizzVstProcessor::process(Vst::ProcessData& data) synth.renderBlock(outputs, numFrames, numChannels); + // Request OSC updates + sfz::Client& client = *_client; + synth.sendMessage(client, 0, "/cc/changed~", "", nullptr); + synth.sendMessage(client, 0, "/sw/last/current", "", nullptr); + _playStateChangeCounter += numFrames; if (_playStateChangeCounter > _playStateChangePeriod) { _playStateChangeCounter %= _playStateChangePeriod; diff --git a/src/sfizz/Synth.cpp b/src/sfizz/Synth.cpp index 2b713909..ea7914ac 100644 --- a/src/sfizz/Synth.cpp +++ b/src/sfizz/Synth.cpp @@ -249,7 +249,6 @@ void Synth::Impl::clear() numGroups_ = 0; numMasters_ = 0; currentSwitch_ = absl::nullopt; - currentSwitchChanged_ = true; defaultPath_ = ""; image_ = ""; resources_.midiState.reset(); @@ -791,8 +790,6 @@ void Synth::Impl::finalizeSfzLoad() swLastSlots_.set(key); } } - // resend current keyswitch - currentSwitchChanged_ = true; } bool Synth::loadScalaFile(const fs::path& path) @@ -1018,26 +1015,9 @@ void Synth::renderBlock(AudioSpan buffer) noexcept // Advance the clock to the end of cycle bc.endCycle(); - // Send the set of changed CCs - Client broadcaster = impl.getBroadcaster(); - const BitArray& changedCCs = impl.changedCCsThisCycle_; - const int finalFrameNumber = int(numFrames - 1); - if (broadcaster.canReceive()) { - sfizz_blob_t blob { changedCCs.data(), static_cast(changedCCs.byte_size()) }; - broadcaster.receive<'b'>(finalFrameNumber, "/cc/changed", &blob); - } + // Update sets of changed CCs impl.changedCCsLastCycle_ = impl.changedCCsThisCycle_; 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'>(finalFrameNumber, "/sw/last/current", value); - } - impl.currentSwitchChanged_ = false; - } { // Clear events and advance midi time ScopedTiming logger { impl.dispatchDuration_, ScopedTiming::Operation::addToDuration }; @@ -1137,7 +1117,6 @@ void Synth::Impl::noteOnDispatch(int delay, int noteNumber, float velocity) noex layer->keySwitched_ = false; } currentSwitch_ = noteNumber; - currentSwitchChanged_ = true; } for (Layer* layer : lastKeyswitchLists_[noteNumber]) diff --git a/src/sfizz/SynthPrivate.h b/src/sfizz/SynthPrivate.h index 960fe9f2..74fa5e34 100644 --- a/src/sfizz/SynthPrivate.h +++ b/src/sfizz/SynthPrivate.h @@ -240,7 +240,6 @@ struct Synth::Impl final: public Parser::Listener { // Set as sw_default if present in the file absl::optional currentSwitch_; - bool currentSwitchChanged_ = true; std::vector unknownOpcodes_; using RegionViewVector = std::vector; using LayerViewVector = std::vector;