Mercurial > hg > svapp
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 |