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>(
|
impl.oscSendQueueTimer_ = makeOwned<CVSTGUITimer>(
|
||||||
[this](CVSTGUITimer* timer) { impl_->tickOSCQueue(timer); },
|
[this](CVSTGUITimer* timer) { impl_->tickOSCQueue(timer); },
|
||||||
oscSendInterval, false);
|
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()
|
void Editor::close()
|
||||||
|
|
@ -312,12 +306,6 @@ void Editor::Impl::uiReceiveValue(EditId id, const EditValue& v)
|
||||||
const std::string& value = v.to_string();
|
const std::string& value = v.to_string();
|
||||||
currentSfzFile_ = value;
|
currentSfzFile_ = value;
|
||||||
updateSfzFileLabel(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;
|
break;
|
||||||
case EditId::Volume:
|
case EditId::Volume:
|
||||||
|
|
@ -476,6 +464,10 @@ void Editor::Impl::uiReceiveValue(EditId id, const EditValue& v)
|
||||||
}
|
}
|
||||||
else if (editIdIsCCUsed(id)) {
|
else if (editIdIsCCUsed(id)) {
|
||||||
updateCCUsed(ccUsedForEditId(id), v.to_float() != 0);
|
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)) {
|
else if (editIdIsCCDefault(id)) {
|
||||||
updateCCDefaultValue(ccDefaultForEditId(id), v.to_float());
|
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];
|
unsigned indices[8];
|
||||||
|
|
||||||
if (Messages::matchOSC("/key/slots", 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 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")) {
|
|
||||||
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 cc = 0; cc < numBits; ++cc) {
|
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")) {
|
else if (Messages::matchOSC("/cc&/value", path, indices) && !strcmp(sig, "f")) {
|
||||||
updateCCValue(indices[0], args[0].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")) {
|
else if (Messages::matchOSC("/sw/last/current", path, indices) && !strcmp(sig, "i")) {
|
||||||
updateSWLastCurrent(args[0].i);
|
updateSWLastCurrent(args[0].i);
|
||||||
}
|
}
|
||||||
else if (Messages::matchOSC("/sw/last/current", path, indices) && !strcmp(sig, "N")) {
|
else if (Messages::matchOSC("/sw/last/current", path, indices) && !strcmp(sig, "N")) {
|
||||||
updateSWLastCurrent(-1);
|
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")) {
|
else if (Messages::matchOSC("/mem/buffers", path, indices) && !strcmp(sig, "h")) {
|
||||||
updateMemoryUsed(args[0].h);
|
updateMemoryUsed(args[0].h);
|
||||||
}
|
}
|
||||||
|
|
@ -1176,12 +1117,6 @@ void Editor::Impl::changeSfzFile(const std::string& filePath)
|
||||||
ctrl_->uiSendValue(EditId::SfzFile, filePath);
|
ctrl_->uiSendValue(EditId::SfzFile, filePath);
|
||||||
currentSfzFile_ = filePath;
|
currentSfzFile_ = filePath;
|
||||||
updateSfzFileLabel(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)
|
void Editor::Impl::changeToNextSfzFile(long offset)
|
||||||
|
|
|
||||||
|
|
@ -942,6 +942,10 @@ run(LV2_Handle instance, uint32_t sample_count)
|
||||||
// Render the block
|
// Render the block
|
||||||
sfizz_render_block(self->synth, self->output_buffers, 2, (int)sample_count);
|
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);
|
spin_mutex_unlock(self->synth_mutex);
|
||||||
|
|
||||||
if (self->midnam && self->must_update_midnam.exchange(0))
|
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);
|
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;
|
_playStateChangeCounter += numFrames;
|
||||||
if (_playStateChangeCounter > _playStateChangePeriod) {
|
if (_playStateChangeCounter > _playStateChangePeriod) {
|
||||||
_playStateChangeCounter %= _playStateChangePeriod;
|
_playStateChangeCounter %= _playStateChangePeriod;
|
||||||
|
|
|
||||||
|
|
@ -249,7 +249,6 @@ void Synth::Impl::clear()
|
||||||
numGroups_ = 0;
|
numGroups_ = 0;
|
||||||
numMasters_ = 0;
|
numMasters_ = 0;
|
||||||
currentSwitch_ = absl::nullopt;
|
currentSwitch_ = absl::nullopt;
|
||||||
currentSwitchChanged_ = true;
|
|
||||||
defaultPath_ = "";
|
defaultPath_ = "";
|
||||||
image_ = "";
|
image_ = "";
|
||||||
resources_.midiState.reset();
|
resources_.midiState.reset();
|
||||||
|
|
@ -791,8 +790,6 @@ void Synth::Impl::finalizeSfzLoad()
|
||||||
swLastSlots_.set(key);
|
swLastSlots_.set(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// resend current keyswitch
|
|
||||||
currentSwitchChanged_ = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Synth::loadScalaFile(const fs::path& path)
|
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
|
// Advance the clock to the end of cycle
|
||||||
bc.endCycle();
|
bc.endCycle();
|
||||||
|
|
||||||
// Send the set of changed CCs
|
// Update sets 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);
|
|
||||||
}
|
|
||||||
impl.changedCCsLastCycle_ = impl.changedCCsThisCycle_;
|
impl.changedCCsLastCycle_ = impl.changedCCsThisCycle_;
|
||||||
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'>(finalFrameNumber, "/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 };
|
||||||
|
|
@ -1137,7 +1117,6 @@ void Synth::Impl::noteOnDispatch(int delay, int noteNumber, float velocity) noex
|
||||||
layer->keySwitched_ = false;
|
layer->keySwitched_ = false;
|
||||||
}
|
}
|
||||||
currentSwitch_ = noteNumber;
|
currentSwitch_ = noteNumber;
|
||||||
currentSwitchChanged_ = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Layer* layer : lastKeyswitchLists_[noteNumber])
|
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
|
// 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 LayerViewVector = std::vector<Layer*>;
|
using LayerViewVector = std::vector<Layer*>;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue