Merge pull request #963 from paulfd/sustain-sostenuto-psa
Add a check for sustain and sostenuto in the LV2
This commit is contained in:
commit
fbac436cc0
9 changed files with 46 additions and 9 deletions
|
|
@ -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;
|
||||
|
|
@ -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"))
|
||||
|
|
|
|||
|
|
@ -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 {};
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -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:
|
||||
|
|
@ -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,
|
||||
|
|
@ -1218,7 +1233,7 @@ 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;
|
||||
|
|
@ -1226,6 +1241,9 @@ sfizz_lv2_update_sfz_info(sfizz_plugin_t *self)
|
|||
self->cc_current[cc] = desc.ccDefault[cc];
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(self->sustain_or_sostenuto, desc.sustainOrSostenuto.data(),
|
||||
sizeof(self->sustain_or_sostenuto));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -1457,7 +1475,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,
|
||||
|
|
|
|||
|
|
@ -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 {};
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
|
|||
|
|
@ -271,6 +271,7 @@ void Synth::Impl::clear()
|
|||
filePool.setRamLoading(config::loadInRam);
|
||||
clearCCLabels();
|
||||
currentUsedCCs_.clear();
|
||||
sustainOrSostenuto_.clear();
|
||||
changedCCsThisCycle_.clear();
|
||||
changedCCsLastCycle_.clear();
|
||||
clearKeyLabels();
|
||||
|
|
@ -2111,8 +2112,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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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", "") {
|
||||
|
|
|
|||
|
|
@ -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_;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue