comparison 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
comparison
equal deleted inserted replaced
595:b23bebfdfaba 596:c99892f0c5c3
63 } 63 }
64 64
65 AudioGenerator::~AudioGenerator() 65 AudioGenerator::~AudioGenerator()
66 { 66 {
67 #ifdef DEBUG_AUDIO_GENERATOR 67 #ifdef DEBUG_AUDIO_GENERATOR
68 SVDEBUG << "AudioGenerator::~AudioGenerator" << endl; 68 cerr << "AudioGenerator::~AudioGenerator" << endl;
69 #endif 69 #endif
70 70
71 for (int i = 0; i < m_channelBufCount; ++i) { 71 for (int i = 0; i < m_channelBufCount; ++i) {
72 delete[] m_channelBuffer[i]; 72 delete[] m_channelBuffer[i];
73 } 73 }
568 568
569 for (NoteList::const_iterator ni = notes.begin(); 569 for (NoteList::const_iterator ni = notes.begin();
570 ni != notes.end(); ++ni) { 570 ni != notes.end(); ++ni) {
571 571
572 sv_frame_t noteFrame = ni->start; 572 sv_frame_t noteFrame = ni->start;
573 sv_frame_t noteDuration = ni->duration;
573 574
574 if (noteFrame < reqStart || 575 if (noteFrame < reqStart ||
575 noteFrame >= reqStart + m_processingBlockSize) continue; 576 noteFrame >= reqStart + m_processingBlockSize) {
577 continue;
578 }
579
580 if (noteDuration == 0) {
581 // If we have a note-off and a note-on with the same
582 // time, then the note-off will be assumed (in the
583 // logic below that deals with two-point note-on/off
584 // events) to be switching off an earlier note before
585 // this one begins -- that's necessary in order to
586 // support adjoining notes of equal pitch. But it does
587 // mean we have to explicitly ignore zero-duration
588 // notes, otherwise they'll be played without end
589 #ifdef DEBUG_AUDIO_GENERATOR
590 cerr << "mixModel [clip]: zero-duration note found at frame " << noteFrame << ", skipping it" << endl;
591 #endif
592 continue;
593 }
576 594
577 while (noteOffs.begin() != noteOffs.end() && 595 while (noteOffs.begin() != noteOffs.end() &&
578 noteOffs.begin()->frame <= noteFrame) { 596 noteOffs.begin()->frame <= noteFrame) {
579 597
580 sv_frame_t eventFrame = noteOffs.begin()->frame; 598 sv_frame_t eventFrame = noteOffs.begin()->frame;
600 cout << "mixModel [clip]: adding note at frame " << noteFrame << ", frame offset " << on.frameOffset << " frequency " << on.frequency << ", level " << on.level << endl; 618 cout << "mixModel [clip]: adding note at frame " << noteFrame << ", frame offset " << on.frameOffset << " frequency " << on.frequency << ", level " << on.level << endl;
601 #endif 619 #endif
602 620
603 starts.push_back(on); 621 starts.push_back(on);
604 noteOffs.insert 622 noteOffs.insert
605 (NoteOff(on.frequency, noteFrame + ni->duration)); 623 (NoteOff(on.frequency, noteFrame + noteDuration));
606 } 624 }
607 625
608 while (noteOffs.begin() != noteOffs.end() && 626 while (noteOffs.begin() != noteOffs.end() &&
609 noteOffs.begin()->frame <= reqStart + m_processingBlockSize) { 627 noteOffs.begin()->frame <= reqStart + m_processingBlockSize) {
610 628