Notify editor of CC changed by MIDI

This commit is contained in:
Jean Pierre Cimalando 2021-02-03 14:30:16 +01:00
parent 4c833b1749
commit 27ec95566a
4 changed files with 40 additions and 1 deletions

View file

@ -420,6 +420,18 @@ void Editor::Impl::uiReceiveMessage(const char* path, const char* sig, const sfi
}
}
}
else if (!strcmp(path, "/cc/changed") && !strcmp(sig, "b")) {
const uint8_t* bitChunks = args[0].b->data;
uint32_t byteSize = args[0].b->size;
for (unsigned cc = 0; cc < 8 * byteSize; ++cc) {
bool changed = bitChunks[cc / 8] & (1u << (cc % 8));
if (changed) {
char pathBuf[256];
sprintf(pathBuf, "/cc%u/value", cc);
sendQueuedOSC(pathBuf, "", nullptr);
}
}
}
else if (matchMessage("/cc&/value", path, indices) && !strcmp(sig, "f")) {
updateCCValue(indices[0], args[0].f);
}

View file

@ -245,6 +245,8 @@ void Synth::Impl::clear()
resources_.filePool.clear();
resources_.filePool.setRamLoading(config::loadInRam);
clearCCLabels();
currentUsedCCs_.clear();
changedCCsThisCycle_.clear();
keyLabels_.clear();
keyswitchLabels_.clear();
globalOpcodes_.clear();
@ -855,6 +857,12 @@ void Synth::renderBlock(AudioSpan<float> buffer) noexcept
buffer.fill(0.0f);
}
const size_t numFrames = buffer.getNumFrames();
if (numFrames < 1) {
CHECKFALSE;
return;
}
if (impl.resources_.synthConfig.freeWheeling)
impl.resources_.filePool.waitForBackgroundLoading();
@ -867,7 +875,6 @@ void Synth::renderBlock(AudioSpan<float> buffer) noexcept
impl.resources_.filePool.triggerGarbageCollection();
}
size_t numFrames = buffer.getNumFrames();
auto tempSpan = impl.resources_.bufferPool.getStereoBuffer(numFrames);
auto tempMixSpan = impl.resources_.bufferPool.getStereoBuffer(numFrames);
auto rampSpan = impl.resources_.bufferPool.getBuffer(numFrames);
@ -958,6 +965,15 @@ 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_;
if (broadcaster.canReceive()) {
sfizz_blob_t blob { changedCCs.data(), static_cast<uint32_t>(changedCCs.byte_size()) };
broadcaster.receive<'b'>(numFrames - 1, "/cc/changed", &blob);
}
impl.changedCCsThisCycle_.clear();
{ // Clear events and advance midi time
ScopedTiming logger { impl.dispatchDuration_, ScopedTiming::Operation::addToDuration };
impl.resources_.midiState.advanceTime(buffer.getNumFrames());
@ -1137,6 +1153,8 @@ void Synth::Impl::performHdcc(int delay, int ccNumber, float normValue, bool asM
ScopedTiming logger { dispatchDuration_, ScopedTiming::Operation::addToDuration };
resources_.midiState.ccEvent(delay, ccNumber, normValue);
changedCCsThisCycle_.set(ccNumber);
if (asMidi) {
if (ccNumber == config::resetCC) {
resetAllControllers(delay);

View file

@ -285,10 +285,18 @@ struct Synth::Impl final: public Parser::Listener {
std::array<float, config::numCCs> defaultCCValues_;
BitArray<config::numCCs> currentUsedCCs_;
BitArray<config::numCCs> changedCCsThisCycle_;
// Messaging
sfizz_receive_t* broadcastReceiver = nullptr;
void* broadcastData = nullptr;
Client getBroadcaster() const
{
Client client(broadcastData);
client.setReceiveCallback(broadcastReceiver);
return client;
}
};
} // namespace sfz

View file

@ -67,6 +67,7 @@ public:
static constexpr size_t byte_size() noexcept { return (N + 7) / 8; }
BitSpan span() noexcept { return BitSpan(data_, N); };
ConstBitSpan span() const noexcept { return ConstBitSpan(data_, N); };
void clear() { span().clear(); }
bool test(size_t i) const noexcept { return span().test(i); }
void set(size_t i) noexcept { span().set(i); }
void set(size_t i, bool b) noexcept { span().set(i, b); }