Mercurial > hg > svapp
changeset 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 | f03bc1d38cac |
files | audio/AudioGenerator.cpp audio/ClipMixer.cpp |
diffstat | 2 files changed, 28 insertions(+), 5 deletions(-) [+] |
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() &&
--- a/audio/ClipMixer.cpp Thu Mar 01 18:02:22 2018 +0000 +++ b/audio/ClipMixer.cpp Wed Apr 18 15:19:09 2018 +0100 @@ -159,8 +159,13 @@ bool ending = false; foreach (NoteEnd end, endingNotes) { - if (end.frequency == note.frequency && - end.frameOffset >= start && + if (end.frequency == note.frequency && + // This is > rather than >= because if we have a + // note-off and a note-on at the same time, the + // note-off must be switching off an earlier note-on, + // not the current one (zero-duration notes are + // forbidden earlier in the pipeline) + end.frameOffset > start && end.frameOffset <= m_blockSize) { ending = true; durationHere = end.frameOffset;