| @@ -1046,6 +1046,9 @@ public: | |||
| if (h2) descriptor->activate(h2); | |||
| } | |||
| postponeEvent(PluginPostEventParameterChange, PARAMETER_ACTIVE, 0, 0.0); | |||
| postponeEvent(PluginPostEventParameterChange, PARAMETER_ACTIVE, 0, 1.0); | |||
| allNotesOffSent = true; | |||
| } | |||
| break; | |||
| @@ -1201,19 +1204,22 @@ public: | |||
| { | |||
| if (! m_activeBefore) | |||
| { | |||
| if (mIn.count > 0 && m_ctrlInChannel >= 0 && m_ctrlInChannel < 16) | |||
| if (mIn.count > 0) | |||
| { | |||
| memset(&midiEvents[0], 0, sizeof(::MidiEvent)); | |||
| midiEvents[0].data[0] = MIDI_STATUS_CONTROL_CHANGE + m_ctrlInChannel; | |||
| midiEvents[0].data[1] = MIDI_CONTROL_ALL_SOUND_OFF; | |||
| midiEvents[0].size = 2; | |||
| memset(&midiEvents[1], 0, sizeof(::MidiEvent)); | |||
| midiEvents[1].data[0] = MIDI_STATUS_CONTROL_CHANGE + m_ctrlInChannel; | |||
| midiEvents[1].data[1] = MIDI_CONTROL_ALL_NOTES_OFF; | |||
| midiEvents[1].size = 2; | |||
| for (k=0; k < MAX_MIDI_CHANNELS; k++) | |||
| { | |||
| memset(&midiEvents[k], 0, sizeof(::MidiEvent)); | |||
| midiEvents[k].data[0] = MIDI_STATUS_CONTROL_CHANGE + k; | |||
| midiEvents[k].data[1] = MIDI_CONTROL_ALL_SOUND_OFF; | |||
| midiEvents[k].size = 2; | |||
| memset(&midiEvents[k*2], 0, sizeof(::MidiEvent)); | |||
| midiEvents[k*2].data[0] = MIDI_STATUS_CONTROL_CHANGE + k; | |||
| midiEvents[k*2].data[1] = MIDI_CONTROL_ALL_NOTES_OFF; | |||
| midiEvents[k*2].size = 2; | |||
| } | |||
| midiEventCount = 2; | |||
| midiEventCount = MAX_MIDI_CHANNELS*2; | |||
| } | |||
| if (descriptor->activate) | |||
| @@ -1715,9 +1715,9 @@ public: | |||
| extMidiNotes[i].note = i; | |||
| extMidiNotes[i].velo = 0; | |||
| postEvents.data[i + postPad].type = PluginPostEventNoteOff; | |||
| postEvents.data[i + postPad].value1 = i; | |||
| postEvents.data[i + postPad].value2 = 0; | |||
| postEvents.data[i + postPad].type = PluginPostEventNoteOff; | |||
| postEvents.data[i + postPad].value1 = m_ctrlInChannel; | |||
| postEvents.data[i + postPad].value2 = i; | |||
| postEvents.data[i + postPad].value3 = 0.0; | |||
| } | |||
| @@ -996,6 +996,9 @@ public: | |||
| if (h2) ldescriptor->activate(h2); | |||
| } | |||
| postponeEvent(PluginPostEventParameterChange, PARAMETER_ACTIVE, 0, 0.0); | |||
| postponeEvent(PluginPostEventParameterChange, PARAMETER_ACTIVE, 0, 1.0); | |||
| allNotesOffSent = true; | |||
| } | |||
| break; | |||
| @@ -1162,19 +1165,22 @@ public: | |||
| { | |||
| if (! m_activeBefore) | |||
| { | |||
| if (midi.portMin && m_ctrlInChannel >= 0 && m_ctrlInChannel < 16) | |||
| if (midi.portMin) | |||
| { | |||
| memset(&midiEvents[0], 0, sizeof(snd_seq_event_t)); | |||
| midiEvents[0].type = SND_SEQ_EVENT_CONTROLLER; | |||
| midiEvents[0].data.control.channel = m_ctrlInChannel; | |||
| midiEvents[0].data.control.param = MIDI_CONTROL_ALL_SOUND_OFF; | |||
| memset(&midiEvents[1], 0, sizeof(snd_seq_event_t)); | |||
| midiEvents[1].type = SND_SEQ_EVENT_CONTROLLER; | |||
| midiEvents[1].data.control.channel = m_ctrlInChannel; | |||
| midiEvents[1].data.control.param = MIDI_CONTROL_ALL_NOTES_OFF; | |||
| for (k=0; k < MAX_MIDI_CHANNELS; k++) | |||
| { | |||
| memset(&midiEvents[k], 0, sizeof(snd_seq_event_t)); | |||
| midiEvents[k].type = SND_SEQ_EVENT_CONTROLLER; | |||
| midiEvents[k].data.control.channel = k; | |||
| midiEvents[k].data.control.param = MIDI_CONTROL_ALL_SOUND_OFF; | |||
| memset(&midiEvents[k*2], 0, sizeof(snd_seq_event_t)); | |||
| midiEvents[k*2].type = SND_SEQ_EVENT_CONTROLLER; | |||
| midiEvents[k*2].data.control.channel = k; | |||
| midiEvents[k*2].data.control.param = MIDI_CONTROL_ALL_NOTES_OFF; | |||
| } | |||
| midiEventCount = 2; | |||
| midiEventCount = MAX_MIDI_CHANNELS; | |||
| } | |||
| if (ldescriptor->activate) | |||
| @@ -992,17 +992,10 @@ public: | |||
| if (! allNotesOffSent) | |||
| sendMidiAllNotesOff(); | |||
| allNotesOffSent = true; | |||
| postponeEvent(PluginPostEventParameterChange, PARAMETER_ACTIVE, 0, 0.0); | |||
| postponeEvent(PluginPostEventParameterChange, PARAMETER_ACTIVE, 0, 1.0); | |||
| #ifdef FLUIDSYNTH_VERSION_NEW_API | |||
| fluid_synth_all_notes_off(f_synth, m_ctrlInChannel); | |||
| fluid_synth_all_sounds_off(f_synth, m_ctrlInChannel); | |||
| } | |||
| else if (cinEvent->channel < 16) | |||
| { | |||
| fluid_synth_all_notes_off(f_synth, cinEvent->channel); | |||
| fluid_synth_all_sounds_off(f_synth, cinEvent->channel); | |||
| #endif | |||
| allNotesOffSent = true; | |||
| } | |||
| break; | |||
| @@ -1013,14 +1006,6 @@ public: | |||
| sendMidiAllNotesOff(); | |||
| allNotesOffSent = true; | |||
| #ifdef FLUIDSYNTH_VERSION_NEW_API | |||
| fluid_synth_all_notes_off(f_synth, m_ctrlInChannel); | |||
| } | |||
| else if (cinEvent->channel < 16) | |||
| { | |||
| fluid_synth_all_notes_off(f_synth, cinEvent->channel); | |||
| #endif | |||
| } | |||
| break; | |||
| } | |||
| @@ -1138,19 +1123,16 @@ public: | |||
| { | |||
| if (! m_activeBefore) | |||
| { | |||
| if (m_ctrlInChannel >= 0 && m_ctrlInChannel < 16) | |||
| for (int c=0; c < MAX_MIDI_CHANNELS; c++) | |||
| { | |||
| fluid_synth_cc(f_synth, m_ctrlInChannel, MIDI_CONTROL_ALL_SOUND_OFF, 0); | |||
| fluid_synth_cc(f_synth, m_ctrlInChannel, MIDI_CONTROL_ALL_NOTES_OFF, 0); | |||
| } | |||
| #ifdef FLUIDSYNTH_VERSION_NEW_API | |||
| for (i=0; i < 16; i++) | |||
| { | |||
| fluid_synth_all_notes_off(f_synth, i); | |||
| fluid_synth_all_sounds_off(f_synth, i); | |||
| } | |||
| fluid_synth_all_notes_off(f_synth, c); | |||
| fluid_synth_all_sounds_off(f_synth, c); | |||
| #else | |||
| fluid_synth_cc(f_synth, c, MIDI_CONTROL_ALL_SOUND_OFF, 0); | |||
| fluid_synth_cc(f_synth, c, MIDI_CONTROL_ALL_NOTES_OFF, 0); | |||
| #endif | |||
| } | |||
| } | |||
| fluid_synth_process(f_synth, frames, 0, nullptr, 2, outBuffer); | |||
| @@ -838,6 +838,9 @@ public: | |||
| descriptor->activate(handle); | |||
| if (h2) descriptor->activate(h2); | |||
| } | |||
| postponeEvent(PluginPostEventParameterChange, PARAMETER_ACTIVE, 0, 0.0); | |||
| postponeEvent(PluginPostEventParameterChange, PARAMETER_ACTIVE, 0, 1.0); | |||
| } | |||
| break; | |||
| @@ -443,6 +443,9 @@ public: | |||
| audioOutputDevice->Stop(); | |||
| audioOutputDevice->Play(); | |||
| postponeEvent(PluginPostEventParameterChange, PARAMETER_ACTIVE, 0, 0.0); | |||
| postponeEvent(PluginPostEventParameterChange, PARAMETER_ACTIVE, 0, 1.0); | |||
| allNotesOffSent = true; | |||
| } | |||
| break; | |||
| @@ -574,10 +577,10 @@ public: | |||
| { | |||
| if (! m_activeBefore) | |||
| { | |||
| if (m_ctrlInChannel >= 0 && m_ctrlInChannel < 16) | |||
| for (int c=0; c < MAX_MIDI_CHANNELS; c++) | |||
| { | |||
| midiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_SOUND_OFF, 0, m_ctrlInChannel); | |||
| midiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_NOTES_OFF, 0, m_ctrlInChannel); | |||
| midiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_SOUND_OFF, 0, c); | |||
| midiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_NOTES_OFF, 0, c); | |||
| } | |||
| audioOutputDevice->Play(); | |||
| @@ -2081,6 +2081,9 @@ public: | |||
| if (h2) descriptor->activate(h2); | |||
| } | |||
| postponeEvent(PluginPostEventParameterChange, PARAMETER_ACTIVE, 0, 0.0); | |||
| postponeEvent(PluginPostEventParameterChange, PARAMETER_ACTIVE, 0, 1.0); | |||
| allNotesOffSent = true; | |||
| } | |||
| break; | |||
| @@ -2403,58 +2406,62 @@ public: | |||
| { | |||
| if (! m_activeBefore) | |||
| { | |||
| if (evIn.count > 0 && m_ctrlInChannel >= 0 && m_ctrlInChannel < 16) | |||
| if (evIn.count > 0) | |||
| { | |||
| uint8_t midiEvent1[2] = { 0 }; | |||
| midiEvent1[0] = MIDI_STATUS_CONTROL_CHANGE + m_ctrlInChannel; | |||
| midiEvent1[1] = MIDI_CONTROL_ALL_SOUND_OFF; | |||
| for (i=0; i < MAX_MIDI_CHANNELS; i++) | |||
| { | |||
| uint8_t midiEvent1[2] = { 0 }; | |||
| midiEvent1[0] = MIDI_STATUS_CONTROL_CHANGE + i; | |||
| midiEvent1[1] = MIDI_CONTROL_ALL_SOUND_OFF; | |||
| uint8_t midiEvent2[2] = { 0 }; | |||
| midiEvent2[0] = MIDI_STATUS_CONTROL_CHANGE + m_ctrlInChannel; | |||
| midiEvent2[1] = MIDI_CONTROL_ALL_SOUND_OFF; | |||
| uint8_t midiEvent2[2] = { 0 }; | |||
| midiEvent2[0] = MIDI_STATUS_CONTROL_CHANGE + i; | |||
| midiEvent2[1] = MIDI_CONTROL_ALL_SOUND_OFF; | |||
| // send to all midi inputs | |||
| for (k=0; k < evIn.count; k++) | |||
| { | |||
| if (evIn.data[k].type & CARLA_EVENT_TYPE_MIDI) | |||
| // send to all midi inputs | |||
| for (k=0; k < evIn.count; k++) | |||
| { | |||
| if (evIn.data[k].type & CARLA_EVENT_DATA_ATOM) | |||
| { | |||
| // all sound off | |||
| LV2_Atom_Event* const aev1 = getLv2AtomEvent(evIn.data[k].atom, evInAtomOffsets[k]); | |||
| aev1->time.frames = 0; | |||
| aev1->body.type = CARLA_URI_MAP_ID_MIDI_EVENT; | |||
| aev1->body.size = 2; | |||
| memcpy(LV2_ATOM_BODY(&aev1->body), midiEvent1, 2); | |||
| const uint32_t padSize = lv2_atom_pad_size(sizeof(LV2_Atom_Event) + 2); | |||
| evInAtomOffsets[k] += padSize; | |||
| evIn.data[k].atom->atom.size += padSize; | |||
| // all notes off | |||
| LV2_Atom_Event* const aev2 = getLv2AtomEvent(evIn.data[k].atom, evInAtomOffsets[k]); | |||
| aev2->time.frames = 0; | |||
| aev2->body.type = CARLA_URI_MAP_ID_MIDI_EVENT; | |||
| aev2->body.size = 2; | |||
| memcpy(LV2_ATOM_BODY(&aev2->body), midiEvent2, 2); | |||
| evInAtomOffsets[k] += padSize; | |||
| evIn.data[k].atom->atom.size += padSize; | |||
| } | |||
| else if (evIn.data[k].type & CARLA_EVENT_DATA_EVENT) | |||
| { | |||
| lv2_event_write(&evInEventIters[k], 0, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 2, midiEvent1); | |||
| lv2_event_write(&evInEventIters[k], 0, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 2, midiEvent2); | |||
| } | |||
| else if (evIn.data[k].type & CARLA_EVENT_DATA_MIDI_LL) | |||
| if (evIn.data[k].type & CARLA_EVENT_TYPE_MIDI) | |||
| { | |||
| lv2midi_put_event(&evInMidiStates[k], 0, 2, midiEvent1); | |||
| lv2midi_put_event(&evInMidiStates[k], 0, 2, midiEvent2); | |||
| if (evIn.data[k].type & CARLA_EVENT_DATA_ATOM) | |||
| { | |||
| const uint32_t padSize = lv2_atom_pad_size(sizeof(LV2_Atom_Event) + 2); | |||
| // all sound off | |||
| LV2_Atom_Event* const aev1 = getLv2AtomEvent(evIn.data[k].atom, evInAtomOffsets[k]); | |||
| aev1->time.frames = 0; | |||
| aev1->body.type = CARLA_URI_MAP_ID_MIDI_EVENT; | |||
| aev1->body.size = 2; | |||
| memcpy(LV2_ATOM_BODY(&aev1->body), midiEvent1, 2); | |||
| evInAtomOffsets[k] += padSize; | |||
| evIn.data[k].atom->atom.size += padSize; | |||
| // all notes off | |||
| LV2_Atom_Event* const aev2 = getLv2AtomEvent(evIn.data[k].atom, evInAtomOffsets[k]); | |||
| aev2->time.frames = 0; | |||
| aev2->body.type = CARLA_URI_MAP_ID_MIDI_EVENT; | |||
| aev2->body.size = 2; | |||
| memcpy(LV2_ATOM_BODY(&aev2->body), midiEvent2, 2); | |||
| evInAtomOffsets[k] += padSize; | |||
| evIn.data[k].atom->atom.size += padSize; | |||
| } | |||
| else if (evIn.data[k].type & CARLA_EVENT_DATA_EVENT) | |||
| { | |||
| lv2_event_write(&evInEventIters[k], 0, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 2, midiEvent1); | |||
| lv2_event_write(&evInEventIters[k], 0, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 2, midiEvent2); | |||
| } | |||
| else if (evIn.data[k].type & CARLA_EVENT_DATA_MIDI_LL) | |||
| { | |||
| lv2midi_put_event(&evInMidiStates[k], 0, 2, midiEvent1); | |||
| lv2midi_put_event(&evInMidiStates[k], 0, 2, midiEvent2); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| midiEventCount = 2; | |||
| midiEventCount = MAX_MIDI_CHANNELS*2; | |||
| } | |||
| if (descriptor->activate) | |||
| @@ -1001,6 +1001,9 @@ public: | |||
| effect->dispatcher(effect, effMainsChanged, 0, 1, nullptr, 0.0f); | |||
| effect->dispatcher(effect, effStartProcess, 0, 0, nullptr, 0.0f); | |||
| postponeEvent(PluginPostEventParameterChange, PARAMETER_ACTIVE, 0, 0.0); | |||
| postponeEvent(PluginPostEventParameterChange, PARAMETER_ACTIVE, 0, 1.0); | |||
| allNotesOffSent = true; | |||
| } | |||
| break; | |||
| @@ -1151,21 +1154,24 @@ public: | |||
| { | |||
| if (! m_activeBefore) | |||
| { | |||
| if (midi.portMin && m_ctrlInChannel >= 0 && m_ctrlInChannel < 16) | |||
| if (midi.portMin) | |||
| { | |||
| memset(&midiEvents[0], 0, sizeof(VstMidiEvent)); | |||
| midiEvents[0].type = kVstMidiType; | |||
| midiEvents[0].byteSize = sizeof(VstMidiEvent); | |||
| midiEvents[0].midiData[0] = MIDI_STATUS_CONTROL_CHANGE + m_ctrlInChannel; | |||
| midiEvents[0].midiData[1] = MIDI_CONTROL_ALL_SOUND_OFF; | |||
| memset(&midiEvents[1], 0, sizeof(VstMidiEvent)); | |||
| midiEvents[1].type = kVstMidiType; | |||
| midiEvents[1].byteSize = sizeof(VstMidiEvent); | |||
| midiEvents[1].midiData[0] = MIDI_STATUS_CONTROL_CHANGE + m_ctrlInChannel; | |||
| midiEvents[1].midiData[1] = MIDI_CONTROL_ALL_NOTES_OFF; | |||
| midiEventCount = 2; | |||
| for (k=0; k < MAX_MIDI_CHANNELS; k++) | |||
| { | |||
| memset(&midiEvents[k], 0, sizeof(VstMidiEvent)); | |||
| midiEvents[k].type = kVstMidiType; | |||
| midiEvents[k].byteSize = sizeof(VstMidiEvent); | |||
| midiEvents[k].midiData[0] = MIDI_STATUS_CONTROL_CHANGE + k; | |||
| midiEvents[k].midiData[1] = MIDI_CONTROL_ALL_SOUND_OFF; | |||
| memset(&midiEvents[k*2], 0, sizeof(VstMidiEvent)); | |||
| midiEvents[k*2].type = kVstMidiType; | |||
| midiEvents[k*2].byteSize = sizeof(VstMidiEvent); | |||
| midiEvents[k*2].midiData[0] = MIDI_STATUS_CONTROL_CHANGE + k; | |||
| midiEvents[k*2].midiData[1] = MIDI_CONTROL_ALL_NOTES_OFF; | |||
| } | |||
| midiEventCount = MAX_MIDI_CHANNELS*2; | |||
| } | |||
| effect->dispatcher(effect, effMainsChanged, 0, 1, nullptr, 0.0f); | |||