diff --git a/source/native-plugins/midi-file.cpp b/source/native-plugins/midi-file.cpp index 40ab28d1e..d05b621ad 100644 --- a/source/native-plugins/midi-file.cpp +++ b/source/native-plugins/midi-file.cpp @@ -29,6 +29,7 @@ public: MidiFilePlugin(const NativeHostDescriptor* const host) : NativePluginClass(host), fMidiOut(this), + fNeedsAllNotesOff(false), fWasPlayingBefore(false), leakDetector_MidiFilePlugin() {} @@ -54,32 +55,35 @@ protected: { const NativeTimeInfo* const timePos(getTimeInfo()); - if (timePos->playing) + if (fWasPlayingBefore != timePos->playing) { - fMidiOut.play(timePos->frame, frames); + fNeedsAllNotesOff = true; + fWasPlayingBefore = timePos->playing; } - else if (fWasPlayingBefore) + + if (fNeedsAllNotesOff) { NativeMidiEvent midiEvent; midiEvent.port = 0; midiEvent.time = 0; - midiEvent.data[0] = MIDI_STATUS_CONTROL_CHANGE; + midiEvent.data[0] = 0; midiEvent.data[1] = MIDI_CONTROL_ALL_NOTES_OFF; midiEvent.data[2] = 0; midiEvent.data[3] = 0; midiEvent.size = 3; - for (int i=0; i < MAX_MIDI_CHANNELS; ++i) + for (int channel=MAX_MIDI_CHANNELS; --channel >= 0;) { - midiEvent.data[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE+i); + midiEvent.data[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT)); NativePluginClass::writeMidiEvent(&midiEvent); } - carla_stdout("WAS PLAYING BEFORE, NOW STOPPED"); + fNeedsAllNotesOff = false; } - fWasPlayingBefore = timePos->playing; + if (fWasPlayingBefore) + fMidiOut.play(timePos->frame, frames); } // ------------------------------------------------------------------- @@ -131,6 +135,7 @@ protected: private: MidiPattern fMidiOut; + bool fNeedsAllNotesOff; bool fWasPlayingBefore; void _loadMidiFile(const char* const filename) @@ -200,6 +205,8 @@ private: fMidiOut.addRaw(static_cast(time), midiMessage.getRawData(), static_cast(dataSize)); } } + + fNeedsAllNotesOff = true; } PluginClassEND(MidiFilePlugin) diff --git a/source/native-plugins/midi-sequencer.cpp b/source/native-plugins/midi-sequencer.cpp index 97914d4ef..0baf03371 100644 --- a/source/native-plugins/midi-sequencer.cpp +++ b/source/native-plugins/midi-sequencer.cpp @@ -32,6 +32,7 @@ public: MidiSequencerPlugin(const NativeHostDescriptor* const host) : NativePluginAndUiClass(host, CARLA_OS_SEP_STR "midiseq-ui"), + fNeedsAllNotesOff(false), fWantInEvents(false), fWasPlayingBefore(false), fTicksPerFrame(0.0), @@ -76,17 +77,13 @@ protected: fInEvents.trySplice(); } - if (fTimeInfo.playing) + if (fWasPlayingBefore != fTimeInfo.playing) { - if (! fTimeInfo.bbt.valid) - fTimeInfo.bbt.beatsPerMinute = 120.0; - - fTicksPerFrame = 48.0 / (60.0 / fTimeInfo.bbt.beatsPerMinute * getSampleRate()); - - fMidiOut.play(fTicksPerFrame*static_cast(fTimeInfo.frame), - fTicksPerFrame*static_cast(frames)); + fNeedsAllNotesOff = true; + fWasPlayingBefore = fTimeInfo.playing; } - else if (fWasPlayingBefore) + + if (fNeedsAllNotesOff) { NativeMidiEvent midiEvent; @@ -104,10 +101,19 @@ protected: NativePluginAndUiClass::writeMidiEvent(&midiEvent); } - carla_stdout("WAS PLAYING BEFORE, NOW STOPPED"); + fNeedsAllNotesOff = false; } - fWasPlayingBefore = fTimeInfo.playing; + if (fTimeInfo.playing) + { + if (! fTimeInfo.bbt.valid) + fTimeInfo.bbt.beatsPerMinute = 120.0; + + fTicksPerFrame = 48.0 / (60.0 / fTimeInfo.bbt.beatsPerMinute * getSampleRate()); + + fMidiOut.play(fTicksPerFrame*static_cast(fTimeInfo.frame), + fTicksPerFrame*static_cast(frames)); + } } // ------------------------------------------------------------------- @@ -208,6 +214,7 @@ protected: if (std::strcmp(msg, "midi-clear-all") == 0) { fMidiOut.clear(); + fNeedsAllNotesOff = true; return true; } @@ -259,6 +266,7 @@ protected: // ------------------------------------------------------------------- private: + bool fNeedsAllNotesOff; bool fWantInEvents; bool fWasPlayingBefore; diff --git a/source/utils/LinkedList.hpp b/source/utils/LinkedList.hpp index 4b6f2bc21..cf2aa88e6 100644 --- a/source/utils/LinkedList.hpp +++ b/source/utils/LinkedList.hpp @@ -366,7 +366,9 @@ private: bool _add(const T& value, const bool inTail, ListHead* const queue) noexcept { - return _add_internal(_allocate(), value, inTail, queue); + if (Data* const data = _allocate()) + return _add_internal(data, value, inTail, queue); + return false; } bool _add_internal(Data* const data, const T& value, const bool inTail, ListHead* const queue) noexcept