Browse Source

Send noteoffs on midifile/seq if needed; LinkedList out-of-mem fix

Closes #207
tags/1.9.6
falkTX 10 years ago
parent
commit
32af9ac879
3 changed files with 37 additions and 20 deletions
  1. +15
    -8
      source/native-plugins/midi-file.cpp
  2. +19
    -11
      source/native-plugins/midi-sequencer.cpp
  3. +3
    -1
      source/utils/LinkedList.hpp

+ 15
- 8
source/native-plugins/midi-file.cpp View File

@@ -29,6 +29,7 @@ public:
MidiFilePlugin(const NativeHostDescriptor* const host) MidiFilePlugin(const NativeHostDescriptor* const host)
: NativePluginClass(host), : NativePluginClass(host),
fMidiOut(this), fMidiOut(this),
fNeedsAllNotesOff(false),
fWasPlayingBefore(false), fWasPlayingBefore(false),
leakDetector_MidiFilePlugin() {} leakDetector_MidiFilePlugin() {}


@@ -54,32 +55,35 @@ protected:
{ {
const NativeTimeInfo* const timePos(getTimeInfo()); 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; NativeMidiEvent midiEvent;


midiEvent.port = 0; midiEvent.port = 0;
midiEvent.time = 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[1] = MIDI_CONTROL_ALL_NOTES_OFF;
midiEvent.data[2] = 0; midiEvent.data[2] = 0;
midiEvent.data[3] = 0; midiEvent.data[3] = 0;
midiEvent.size = 3; 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); 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: private:
MidiPattern fMidiOut; MidiPattern fMidiOut;
bool fNeedsAllNotesOff;
bool fWasPlayingBefore; bool fWasPlayingBefore;


void _loadMidiFile(const char* const filename) 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)); fMidiOut.addRaw(static_cast<uint64_t>(time), midiMessage.getRawData(), static_cast<uint8_t>(dataSize));
} }
} }

fNeedsAllNotesOff = true;
} }


PluginClassEND(MidiFilePlugin) PluginClassEND(MidiFilePlugin)


+ 19
- 11
source/native-plugins/midi-sequencer.cpp View File

@@ -32,6 +32,7 @@ public:


MidiSequencerPlugin(const NativeHostDescriptor* const host) MidiSequencerPlugin(const NativeHostDescriptor* const host)
: NativePluginAndUiClass(host, CARLA_OS_SEP_STR "midiseq-ui"), : NativePluginAndUiClass(host, CARLA_OS_SEP_STR "midiseq-ui"),
fNeedsAllNotesOff(false),
fWantInEvents(false), fWantInEvents(false),
fWasPlayingBefore(false), fWasPlayingBefore(false),
fTicksPerFrame(0.0), fTicksPerFrame(0.0),
@@ -76,17 +77,13 @@ protected:
fInEvents.trySplice(); 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; NativeMidiEvent midiEvent;


@@ -104,10 +101,19 @@ protected:
NativePluginAndUiClass::writeMidiEvent(&midiEvent); 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) if (std::strcmp(msg, "midi-clear-all") == 0)
{ {
fMidiOut.clear(); fMidiOut.clear();
fNeedsAllNotesOff = true;
return true; return true;
} }


@@ -259,6 +266,7 @@ protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------


private: private:
bool fNeedsAllNotesOff;
bool fWantInEvents; bool fWantInEvents;
bool fWasPlayingBefore; bool fWasPlayingBefore;




+ 3
- 1
source/utils/LinkedList.hpp View File

@@ -366,7 +366,9 @@ private:


bool _add(const T& value, const bool inTail, ListHead* const queue) noexcept 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 bool _add_internal(Data* const data, const T& value, const bool inTail, ListHead* const queue) noexcept


Loading…
Cancel
Save