Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a check for sustain and sostenuto in the LV2 #963

Merged
merged 1 commit into from
Sep 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions plugins/common/plugin/InstrumentDescription.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ std::string getDescriptionBlob(sfizz_synth_t* handle)
synth.sendMessage(*client, 0, "/key/slots", "", nullptr);
synth.sendMessage(*client, 0, "/sw/last/slots", "", nullptr);
synth.sendMessage(*client, 0, "/cc/slots", "", nullptr);
synth.sendMessage(*client, 0, "/sustain_or_sostenuto/slots", "", nullptr);

blob.shrink_to_fit();
return blob;
Expand Down Expand Up @@ -152,6 +153,8 @@ InstrumentDescription parseDescriptionBlob(absl::string_view blob)
copyArgToBitSpan(args[0], desc.keyswitchUsed.span());
else if (Messages::matchOSC("/cc/slots", path, indices) && !strcmp(sig, "b"))
copyArgToBitSpan(args[0], desc.ccUsed.span());
else if (Messages::matchOSC("/sustain_or_sostenuto/slots", path, indices) && !strcmp(sig, "b"))
copyArgToBitSpan(args[0], desc.sustainOrSostenuto.span());
else if (Messages::matchOSC("/key&/label", path, indices) && !strcmp(sig, "s"))
desc.keyLabel[indices[0]] = args[0].s;
else if (Messages::matchOSC("/sw/last/&/label", path, indices) && !strcmp(sig, "s"))
Expand Down
1 change: 1 addition & 0 deletions plugins/common/plugin/InstrumentDescription.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ struct InstrumentDescription {
std::string image;
BitArray<128> keyUsed {};
BitArray<128> keyswitchUsed {};
BitArray<128> sustainOrSostenuto {};
BitArray<sfz::config::numCCs> ccUsed {};
std::array<std::string, 128> keyLabel {};
std::array<std::string, 128> keyswitchLabel {};
Expand Down
30 changes: 24 additions & 6 deletions plugins/lv2/sfizz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,12 @@ sfizz_lv2_handle_atom_object(sfizz_plugin_t *self, int delay, const LV2_Atom_Obj
}
}

static bool
sfizz_is_sustain_or_sostenuto(sfizz_plugin_t* self, unsigned cc)
{
return (self->sustain_or_sostenuto[cc / 8] & (1 << (cc % 8)));
}

static void
sfizz_lv2_process_midi_event(sfizz_plugin_t *self, const LV2_Atom_Event *ev)
{
Expand All @@ -704,14 +710,23 @@ sfizz_lv2_process_midi_event(sfizz_plugin_t *self, const LV2_Atom_Event *ev)
(int)msg[1],
msg[2]);
break;
// Note(jpc) CC must be mapped by host, not handled here.
// See LV2 midi:binding.
#if defined(SFIZZ_LV2_PSA)
case LV2_MIDI_MSG_CONTROLLER:
{
unsigned cc = msg[1];
float value = float(msg[2]) * (1.0f / 127.0f);

// Send
if (sfizz_is_sustain_or_sostenuto(self, cc)) {
sfizz_automate_hdcc(self->synth,
(int)ev->time.frames,
(int)cc,
value);
break;
}

// Note(jpc) CC must be mapped by host, not handled here.
// See LV2 midi:binding.
#if defined(SFIZZ_LV2_PSA)
switch (cc)
{
default:
Expand All @@ -733,9 +748,9 @@ sfizz_lv2_process_midi_event(sfizz_plugin_t *self, const LV2_Atom_Event *ev)
sfizz_all_sound_off(self->synth);
break;
}
#endif
}
break;
#endif
case LV2_MIDI_MSG_CHANNEL_PRESSURE:
sfizz_send_channel_aftertouch(self->synth,
(int)ev->time.frames,
Expand Down Expand Up @@ -1218,14 +1233,17 @@ sfizz_lv2_update_sfz_info(sfizz_plugin_t *self)
//
const InstrumentDescription desc = parseDescriptionBlob(blob);
for (unsigned cc = 0; cc < sfz::config::numCCs; ++cc) {
if (desc.ccUsed.test(cc)) {
if (desc.ccUsed.test(cc) && !desc.sustainOrSostenuto.test(cc)) {
// Mark all the used CCs for automation with default values
self->ccauto[cc] = desc.ccDefault[cc];
self->have_ccauto = true;
// Update the current CCs
self->cc_current[cc] = desc.ccDefault[cc];
}
}

memcpy(self->sustain_or_sostenuto, desc.sustainOrSostenuto.data(),
sizeof(self->sustain_or_sostenuto));
}

static bool
Expand Down Expand Up @@ -1515,7 +1533,7 @@ save(LV2_Handle instance,
self->sfz_blob_mutex->unlock();

for (unsigned cc = 0; cc < sfz::config::numCCs; ++cc) {
if (desc.ccUsed.test(cc)) {
if (desc.ccUsed.test(cc) && !desc.sustainOrSostenuto.test(cc)) {
LV2_URID urid = sfizz_lv2_ccmap_map(self->ccmap, int(cc));
store(handle,
urid,
Expand Down
3 changes: 3 additions & 0 deletions plugins/lv2/sfizz_lv2_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ struct sfizz_plugin_t
const uint8_t *volatile sfz_blob_data {};
volatile uint32_t sfz_blob_size {};

// Sostenuto or sustain
char sustain_or_sostenuto[16] {};

// Current CC values in the synth (synchronized by `synth_mutex`)
// updated by hdcc or file load
float *cc_current {};
Expand Down
2 changes: 1 addition & 1 deletion plugins/lv2/sfizz_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ sfizz_ui_update_description(sfizz_ui_t *self, const InstrumentDescription& desc)
}

for (unsigned cc = 0; cc < sfz::config::numCCs; ++cc) {
bool ccUsed = desc.ccUsed.test(cc);
bool ccUsed = desc.ccUsed.test(cc) && !desc.sustainOrSostenuto.test(cc);
self->uiReceiveValue(editIdForCCUsed(cc), float(ccUsed));
if (ccUsed) {
self->uiReceiveValue(editIdForCCDefault(cc), desc.ccDefault[cc]);
Expand Down
2 changes: 1 addition & 1 deletion plugins/vst/SfizzVstEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ bool SfizzVstEditor::processUpdate(FUnknown* changedUnknown, int32 message)
}

for (unsigned cc = 0; cc < sfz::config::numCCs; ++cc) {
bool ccUsed = desc.ccUsed.test(cc);
bool ccUsed = desc.ccUsed.test(cc) && !desc.sustainOrSostenuto.test(cc);
uiReceiveValue(editIdForCCUsed(int(cc)), float(ccUsed));
if (ccUsed) {
uiReceiveValue(editIdForCCDefault(int(cc)), desc.ccDefault[cc]);
Expand Down
6 changes: 5 additions & 1 deletion src/sfizz/Synth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ void Synth::Impl::clear()
filePool.setRamLoading(config::loadInRam);
clearCCLabels();
currentUsedCCs_.clear();
sustainOrSostenuto_.clear();
changedCCsThisCycle_.clear();
changedCCsLastCycle_.clear();
clearKeyLabels();
Expand Down Expand Up @@ -2113,8 +2114,11 @@ void Synth::Impl::collectUsedCCsFromModulations(BitArray<config::numCCs>& usedCC
BitArray<config::numCCs> Synth::Impl::collectAllUsedCCs()
{
BitArray<config::numCCs> used;
for (const LayerPtr& layerPtr : layers_)
for (const LayerPtr& layerPtr : layers_) {
collectUsedCCsFromRegion(used, layerPtr->getRegion());
sustainOrSostenuto_.set(layerPtr->region_.sustainCC);
sustainOrSostenuto_.set(layerPtr->region_.sostenutoCC);
}
collectUsedCCsFromModulations(used, resources_.getModMatrix());
return used;
}
Expand Down
7 changes: 7 additions & 0 deletions src/sfizz/SynthMessaging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,13 @@ void sfz::Synth::dispatchMessage(Client& client, int delay, const char* path, co
client.receive<'b'>(delay, path, &blob);
} break;

MATCH("/sustain_or_sostenuto/slots", "") {
const BitArray<128>& sustainOrSostenuto = impl.sustainOrSostenuto_;
sfizz_blob_t blob { sustainOrSostenuto.data(),
static_cast<uint32_t>(sustainOrSostenuto.byte_size()) };
client.receive<'b'>(delay, path, &blob);
} break;

//----------------------------------------------------------------------

MATCH("/mem/buffers", "") {
Expand Down
1 change: 1 addition & 0 deletions src/sfizz/SynthPrivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ struct Synth::Impl final: public Parser::Listener {
std::map<int, size_t> keyLabelsMap_;
BitArray<128> keySlots_;
BitArray<128> swLastSlots_;
BitArray<128> sustainOrSostenuto_;
std::vector<NoteNamePair> keyswitchLabels_;
std::map<int, size_t> keyswitchLabelsMap_;

Expand Down