Notify editor of CC changed by MIDI
This commit is contained in:
parent
4c833b1749
commit
27ec95566a
4 changed files with 40 additions and 1 deletions
|
|
@ -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")) {
|
else if (matchMessage("/cc&/value", path, indices) && !strcmp(sig, "f")) {
|
||||||
updateCCValue(indices[0], args[0].f);
|
updateCCValue(indices[0], args[0].f);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -245,6 +245,8 @@ void Synth::Impl::clear()
|
||||||
resources_.filePool.clear();
|
resources_.filePool.clear();
|
||||||
resources_.filePool.setRamLoading(config::loadInRam);
|
resources_.filePool.setRamLoading(config::loadInRam);
|
||||||
clearCCLabels();
|
clearCCLabels();
|
||||||
|
currentUsedCCs_.clear();
|
||||||
|
changedCCsThisCycle_.clear();
|
||||||
keyLabels_.clear();
|
keyLabels_.clear();
|
||||||
keyswitchLabels_.clear();
|
keyswitchLabels_.clear();
|
||||||
globalOpcodes_.clear();
|
globalOpcodes_.clear();
|
||||||
|
|
@ -855,6 +857,12 @@ void Synth::renderBlock(AudioSpan<float> buffer) noexcept
|
||||||
buffer.fill(0.0f);
|
buffer.fill(0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const size_t numFrames = buffer.getNumFrames();
|
||||||
|
if (numFrames < 1) {
|
||||||
|
CHECKFALSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (impl.resources_.synthConfig.freeWheeling)
|
if (impl.resources_.synthConfig.freeWheeling)
|
||||||
impl.resources_.filePool.waitForBackgroundLoading();
|
impl.resources_.filePool.waitForBackgroundLoading();
|
||||||
|
|
||||||
|
|
@ -867,7 +875,6 @@ void Synth::renderBlock(AudioSpan<float> buffer) noexcept
|
||||||
impl.resources_.filePool.triggerGarbageCollection();
|
impl.resources_.filePool.triggerGarbageCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t numFrames = buffer.getNumFrames();
|
|
||||||
auto tempSpan = impl.resources_.bufferPool.getStereoBuffer(numFrames);
|
auto tempSpan = impl.resources_.bufferPool.getStereoBuffer(numFrames);
|
||||||
auto tempMixSpan = impl.resources_.bufferPool.getStereoBuffer(numFrames);
|
auto tempMixSpan = impl.resources_.bufferPool.getStereoBuffer(numFrames);
|
||||||
auto rampSpan = impl.resources_.bufferPool.getBuffer(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
|
// Advance the clock to the end of cycle
|
||||||
bc.endCycle();
|
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
|
{ // Clear events and advance midi time
|
||||||
ScopedTiming logger { impl.dispatchDuration_, ScopedTiming::Operation::addToDuration };
|
ScopedTiming logger { impl.dispatchDuration_, ScopedTiming::Operation::addToDuration };
|
||||||
impl.resources_.midiState.advanceTime(buffer.getNumFrames());
|
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 };
|
ScopedTiming logger { dispatchDuration_, ScopedTiming::Operation::addToDuration };
|
||||||
resources_.midiState.ccEvent(delay, ccNumber, normValue);
|
resources_.midiState.ccEvent(delay, ccNumber, normValue);
|
||||||
|
|
||||||
|
changedCCsThisCycle_.set(ccNumber);
|
||||||
|
|
||||||
if (asMidi) {
|
if (asMidi) {
|
||||||
if (ccNumber == config::resetCC) {
|
if (ccNumber == config::resetCC) {
|
||||||
resetAllControllers(delay);
|
resetAllControllers(delay);
|
||||||
|
|
|
||||||
|
|
@ -285,10 +285,18 @@ struct Synth::Impl final: public Parser::Listener {
|
||||||
|
|
||||||
std::array<float, config::numCCs> defaultCCValues_;
|
std::array<float, config::numCCs> defaultCCValues_;
|
||||||
BitArray<config::numCCs> currentUsedCCs_;
|
BitArray<config::numCCs> currentUsedCCs_;
|
||||||
|
BitArray<config::numCCs> changedCCsThisCycle_;
|
||||||
|
|
||||||
// Messaging
|
// Messaging
|
||||||
sfizz_receive_t* broadcastReceiver = nullptr;
|
sfizz_receive_t* broadcastReceiver = nullptr;
|
||||||
void* broadcastData = nullptr;
|
void* broadcastData = nullptr;
|
||||||
|
|
||||||
|
Client getBroadcaster() const
|
||||||
|
{
|
||||||
|
Client client(broadcastData);
|
||||||
|
client.setReceiveCallback(broadcastReceiver);
|
||||||
|
return client;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sfz
|
} // namespace sfz
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ public:
|
||||||
static constexpr size_t byte_size() noexcept { return (N + 7) / 8; }
|
static constexpr size_t byte_size() noexcept { return (N + 7) / 8; }
|
||||||
BitSpan span() noexcept { return BitSpan(data_, N); };
|
BitSpan span() noexcept { return BitSpan(data_, N); };
|
||||||
ConstBitSpan span() const noexcept { return ConstBitSpan(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); }
|
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) noexcept { span().set(i); }
|
||||||
void set(size_t i, bool b) noexcept { span().set(i, b); }
|
void set(size_t i, bool b) noexcept { span().set(i, b); }
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue