Closes #207tags/1.9.6
| @@ -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<uint64_t>(time), midiMessage.getRawData(), static_cast<uint8_t>(dataSize)); | |||
| } | |||
| } | |||
| fNeedsAllNotesOff = true; | |||
| } | |||
| PluginClassEND(MidiFilePlugin) | |||
| @@ -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<long double>(fTimeInfo.frame), | |||
| fTicksPerFrame*static_cast<double>(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<long double>(fTimeInfo.frame), | |||
| fTicksPerFrame*static_cast<double>(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; | |||
| @@ -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 | |||