mirror of
https://github.com/cookiengineer/audacity
synced 2025-05-04 17:49:45 +02:00
Workaround for GarageBand as synth not respecting notes-off message
This commit is contained in:
parent
c2229b131f
commit
07ea0ae03f
@ -3869,7 +3869,21 @@ void AudioIO::OutputEvent()
|
||||
data2 = (data2 < 1 ? 1 : (data2 > 127 ? 127 : data2));
|
||||
// since we are going to play this note, we need to get a note_off
|
||||
mIterator->request_note_off();
|
||||
} else data2 = 0; // 0 velocity means "note off"
|
||||
|
||||
#ifdef AUDIO_IO_GB_MIDI_WORKAROUND
|
||||
mPendingNotesOff.push_back(std::make_pair(channel, data1));
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
data2 = 0; // 0 velocity means "note off"
|
||||
#ifdef AUDIO_IO_GB_MIDI_WORKAROUND
|
||||
auto end = mPendingNotesOff.end();
|
||||
auto iter = std::find(
|
||||
mPendingNotesOff.begin(), end, std::make_pair(channel, data1) );
|
||||
if (iter != end)
|
||||
mPendingNotesOff.erase(iter);
|
||||
#endif
|
||||
}
|
||||
command = 0x90; // MIDI NOTE ON (or OFF when velocity == 0)
|
||||
// Update event
|
||||
} else if (mNextEvent->is_update()) {
|
||||
@ -4007,6 +4021,17 @@ PmTimestamp AudioIO::MidiTime()
|
||||
|
||||
void AudioIO::AllNotesOff()
|
||||
{
|
||||
#ifdef AUDIO_IO_GB_MIDI_WORKAROUND
|
||||
// Send individual note-off messages for each note-on not yet paired.
|
||||
for (const auto &pair : mPendingNotesOff) {
|
||||
Pm_WriteShort(mMidiStream, 0, Pm_Message(
|
||||
0x90 + pair.first, pair.second, 0));
|
||||
}
|
||||
mPendingNotesOff.clear();
|
||||
|
||||
// Proceed to do the usual messages too.
|
||||
#endif
|
||||
|
||||
for (int chan = 0; chan < 16; chan++) {
|
||||
Pm_WriteShort(mMidiStream, 0, Pm_Message(0xB0 + chan, 0x7B, 0));
|
||||
}
|
||||
|
@ -125,6 +125,10 @@ struct AudioIOStartStreamOptions
|
||||
#endif
|
||||
};
|
||||
|
||||
// This workaround makes pause and stop work when output is to GarageBand,
|
||||
// which seems not to implement the notes-off message correctly.
|
||||
#define AUDIO_IO_GB_MIDI_WORKAROUND
|
||||
|
||||
class AUDACITY_DLL_API AudioIO final {
|
||||
|
||||
public:
|
||||
@ -543,6 +547,11 @@ private:
|
||||
std::unique_ptr<Alg_iterator> mIterator;
|
||||
/// The next event to play (or null)
|
||||
Alg_event_ptr mNextEvent;
|
||||
|
||||
#ifdef AUDIO_IO_GB_MIDI_WORKAROUND
|
||||
std::vector< std::pair< int, int > > mPendingNotesOff;
|
||||
#endif
|
||||
|
||||
/// Time at which the next event should be output, measured in seconds.
|
||||
/// Note that this could be a note's time+duration for note offs.
|
||||
double mNextEventTime;
|
||||
|
Loading…
x
Reference in New Issue
Block a user