Pull model for current CC and switch

This commit is contained in:
Jean Pierre Cimalando 2021-04-03 03:59:43 +02:00
parent d729ba66e6
commit 53a5e989e5
5 changed files with 15 additions and 93 deletions

View file

@ -279,12 +279,6 @@ void Editor::open(CFrame& frame)
impl.oscSendQueueTimer_ = makeOwned<CVSTGUITimer>(
[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)

View file

@ -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))

View file

@ -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;

View file

@ -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<float> buffer) noexcept
// Advance the clock to the end of cycle
bc.endCycle();
// Send the set of changed CCs
Client broadcaster = impl.getBroadcaster();
const BitArray<config::numCCs>& changedCCs = impl.changedCCsThisCycle_;
const int finalFrameNumber = int(numFrames - 1);
if (broadcaster.canReceive()) {
sfizz_blob_t blob { changedCCs.data(), static_cast<uint32_t>(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])

View file

@ -240,7 +240,6 @@ struct Synth::Impl final: public Parser::Listener {
// Set as sw_default if present in the file
absl::optional<uint8_t> currentSwitch_;
bool currentSwitchChanged_ = true;
std::vector<std::string> unknownOpcodes_;
using RegionViewVector = std::vector<Region*>;
using LayerViewVector = std::vector<Layer*>;