Pull model for current CC and switch
This commit is contained in:
parent
d729ba66e6
commit
53a5e989e5
5 changed files with 15 additions and 93 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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])
|
||||
|
|
|
|||
|
|
@ -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*>;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue