Mercurial > hg > svapp
diff audio/AudioGenerator.cpp @ 596:c99892f0c5c3
Proper handling for notes that end at the same frame as a subsequent note of the same pitch begins. The note-off needs to be associated with the prior note, not a spurious zero-duration version of the subsequent note.
author | Chris Cannam |
---|---|
date | Wed, 18 Apr 2018 15:19:09 +0100 |
parents | b23bebfdfaba |
children | 7da68349a0c5 |
line wrap: on
line diff
--- a/audio/AudioGenerator.cpp Thu Mar 01 18:02:22 2018 +0000 +++ b/audio/AudioGenerator.cpp Wed Apr 18 15:19:09 2018 +0100 @@ -65,7 +65,7 @@ AudioGenerator::~AudioGenerator() { #ifdef DEBUG_AUDIO_GENERATOR - SVDEBUG << "AudioGenerator::~AudioGenerator" << endl; + cerr << "AudioGenerator::~AudioGenerator" << endl; #endif for (int i = 0; i < m_channelBufCount; ++i) { @@ -570,9 +570,27 @@ ni != notes.end(); ++ni) { sv_frame_t noteFrame = ni->start; + sv_frame_t noteDuration = ni->duration; if (noteFrame < reqStart || - noteFrame >= reqStart + m_processingBlockSize) continue; + noteFrame >= reqStart + m_processingBlockSize) { + continue; + } + + if (noteDuration == 0) { + // If we have a note-off and a note-on with the same + // time, then the note-off will be assumed (in the + // logic below that deals with two-point note-on/off + // events) to be switching off an earlier note before + // this one begins -- that's necessary in order to + // support adjoining notes of equal pitch. But it does + // mean we have to explicitly ignore zero-duration + // notes, otherwise they'll be played without end +#ifdef DEBUG_AUDIO_GENERATOR + cerr << "mixModel [clip]: zero-duration note found at frame " << noteFrame << ", skipping it" << endl; +#endif + continue; + } while (noteOffs.begin() != noteOffs.end() && noteOffs.begin()->frame <= noteFrame) { @@ -602,7 +620,7 @@ starts.push_back(on); noteOffs.insert - (NoteOff(on.frequency, noteFrame + ni->duration)); + (NoteOff(on.frequency, noteFrame + noteDuration)); } while (noteOffs.begin() != noteOffs.end() &&