Browse Source

Carla: Properly handle all sound/note off events

tags/v0.9.0
falkTX 13 years ago
parent
commit
d2e0704e7f
8 changed files with 126 additions and 113 deletions
  1. +17
    -11
      c++/carla-backend/carla_native.cpp
  2. +3
    -3
      c++/carla-backend/carla_plugin.h
  3. +17
    -11
      c++/carla-backend/dssi.cpp
  4. +10
    -28
      c++/carla-backend/fluidsynth.cpp
  5. +3
    -0
      c++/carla-backend/ladspa.cpp
  6. +6
    -3
      c++/carla-backend/linuxsampler.cpp
  7. +50
    -43
      c++/carla-backend/lv2.cpp
  8. +20
    -14
      c++/carla-backend/vst.cpp

+ 17
- 11
c++/carla-backend/carla_native.cpp View File

@@ -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)


+ 3
- 3
c++/carla-backend/carla_plugin.h View File

@@ -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;
}



+ 17
- 11
c++/carla-backend/dssi.cpp View File

@@ -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)


+ 10
- 28
c++/carla-backend/fluidsynth.cpp View File

@@ -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);


+ 3
- 0
c++/carla-backend/ladspa.cpp View File

@@ -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;



+ 6
- 3
c++/carla-backend/linuxsampler.cpp View File

@@ -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();


+ 50
- 43
c++/carla-backend/lv2.cpp View File

@@ -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)


+ 20
- 14
c++/carla-backend/vst.cpp View File

@@ -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);


Loading…
Cancel
Save