@@ -683,7 +683,7 @@ void AudioPluginAudioProcessor::processBlock(juce::AudioBuffer<float> &buffer,
683683 }
684684
685685 {
686- // TODO: if it will cause audio glitches,
686+ // TODO: if it will cause audio glitches,
687687 // change the approach to an intermediate buffer for notes
688688 std::scoped_lock lock (notesMutex);
689689 // Stop playing unexisting notes (from piano roll)
@@ -854,39 +854,28 @@ void AudioPluginAudioProcessor::processBlock(juce::AudioBuffer<float> &buffer,
854854 }
855855 }
856856 }
857- // ===================== Note bend =====================
858- for (int i = 0 ; i < notes.size (); ++i) {
859- const Note ¬e = notes[i];
860- if ((note.bend != 0 ) && (note.time < playHeadTime) &&
861- (playHeadTime <= note.time + note.duration )) {
862- int totalCents = note.octave * 1200 + note.cents ;
863- const auto &itNote = noteToChAndMidiNoteMPE.find ({i, totalCents});
864- if (itNote != noteToChAndMidiNoteMPE.end ()) {
865- const auto &chAndMidiNote = itNote->second ;
866- int bendMPE = calcBendMPE (note, playHeadTime);
867- juce::MidiMessage pitchBend =
868- juce::MidiMessage::pitchWheel (chAndMidiNote.first , bendMPE);
869- midiMessages.addEvent (pitchBend, 0 );
870- }
871- }
872- }
873857 // ===================== Note on =====================
858+ const bool chaseMIDINotes =
859+ GlobalSettings::getInstance ().getChaseMIDINotes ();
874860 for (int i = 0 ; i < notes.size (); ++i) {
875861 const Note ¬e = notes[i];
876862 int totalCents = note.octave * 1200 + note.cents ;
877- if ((note. time >= playHeadTime) &&
878- (note. time < playHeadTime + barsInBlock) &&
879- // need to check it so there will be no bug when you turn on/off
880- // playback so fast that you can't catch the moment isPlaying=false
881- // to make noteOff (so just don't make unnecassry noteOn)
863+ bool rightBorderCond =
864+ chaseMIDINotes
865+ ? playHeadTime <= note. time + note. duration - barsInBlock
866+ : playHeadTime <= note. time ;
867+ if ((note. time - barsInBlock < playHeadTime) && rightBorderCond &&
882868 (!noteToChAndMidiNoteMPE.contains ({i, totalCents}))) {
883869 std::tie (midiNote, bendMPE) = calcMidiNoteAndBendMPE (totalCents);
884870 int ch =
885871 channelsManagerMPE->allocateChannelMPE (bendMPE, note.bend != 0 );
886872 if (ch != -1 ) {
887873 pitchesOverflow = false ;
888- int noteOnSample = static_cast <int >(ceil (
889- numSamples * (note.time - playHeadTime) / barsInBlock));
874+ int noteOnSample = 0 ;
875+ if (playHeadTime < note.time ) {
876+ noteOnSample = static_cast <int >(ceil (
877+ numSamples * (note.time - playHeadTime) / barsInBlock));
878+ }
890879 juce::MidiMessage pitchBend =
891880 juce::MidiMessage::pitchWheel (ch, bendMPE);
892881 midiMessages.addEvent (pitchBend, noteOnSample);
@@ -901,6 +890,22 @@ void AudioPluginAudioProcessor::processBlock(juce::AudioBuffer<float> &buffer,
901890 }
902891 }
903892 }
893+ // ===================== Note bend =====================
894+ for (int i = 0 ; i < notes.size (); ++i) {
895+ const Note ¬e = notes[i];
896+ if ((note.bend != 0 ) && (note.time < playHeadTime) &&
897+ (playHeadTime <= note.time + note.duration )) {
898+ int totalCents = note.octave * 1200 + note.cents ;
899+ const auto &itNote = noteToChAndMidiNoteMPE.find ({i, totalCents});
900+ if (itNote != noteToChAndMidiNoteMPE.end ()) {
901+ const auto &chAndMidiNote = itNote->second ;
902+ int bendMPE = calcBendMPE (note, playHeadTime);
903+ juce::MidiMessage pitchBend =
904+ juce::MidiMessage::pitchWheel (chAndMidiNote.first , bendMPE);
905+ midiMessages.addEvent (pitchBend, 0 );
906+ }
907+ }
908+ }
904909 }
905910 }
906911
@@ -936,9 +941,9 @@ void AudioPluginAudioProcessor::processBlock(juce::AudioBuffer<float> &buffer,
936941 // = USING MTS-ESP =
937942 // ================================================================================
938943
939- // TODO: if it causes glitches,
940- // change the approach to an intermediate buffers for things that are
941- // changed in prepareToPlay(). Also then use buffers for notes and
944+ // TODO: if it causes glitches,
945+ // change the approach to an intermediate buffers for things that are
946+ // changed in prepareToPlay(). Also then use buffers for notes and
942947 // manPlNotes, so all data will be consistent
943948 std::scoped_lock lock (prepareNotesMutex);
944949
@@ -1073,16 +1078,6 @@ void AudioPluginAudioProcessor::processBlock(juce::AudioBuffer<float> &buffer,
10731078 }
10741079 bool needUpdateFreqs = false ;
10751080 // =======================================
1076- for (int i = 0 ; i < notes.size (); ++i) {
1077- const Note ¬e = notes[i];
1078- // Note bend
1079- if ((note.bend != 0 ) && (note.time < playHeadTime) &&
1080- (playHeadTime <= note.time + note.duration )) {
1081- freqs[notesIndexes[i]] = getNoteFreq (note);
1082- needUpdateFreqs = true ;
1083- }
1084- }
1085- // =======================================
10861081 for (int i = 0 ; i < notes.size (); ++i) {
10871082 const Note ¬e = notes[i];
10881083 // PRE Note on
@@ -1099,23 +1094,27 @@ void AudioPluginAudioProcessor::processBlock(juce::AudioBuffer<float> &buffer,
10991094 }
11001095 }
11011096 // =======================================
1097+ const bool chaseMIDINotes =
1098+ GlobalSettings::getInstance ().getChaseMIDINotes ();
11021099 for (int i = 0 ; i < notes.size (); ++i) {
11031100 const Note ¬e = notes[i];
11041101 // Note on
1105- if ((note. time >= playHeadTime) &&
1106- (note. time < playHeadTime + barsInBlock) &&
1107- // need to check it so there will be no bug when you turn on/off
1108- // playback so fast that you can't catch the moment isPlaying=false
1109- // to make noteOff (so just don't make unnecassry noteOn)
1102+ bool rightBorderCond =
1103+ chaseMIDINotes
1104+ ? playHeadTime <= note. time + note. duration - barsInBlock
1105+ : playHeadTime <= note. time ;
1106+ if ((note. time - barsInBlock < playHeadTime) && rightBorderCond &&
11101107 !currPlayedNotesTotalCents.contains (note.octave * 1200 +
11111108 note.cents )) {
11121109 const int noteInd = notesIndexes[i];
11131110 juce::MidiMessage noteOn = juce::MidiMessage::noteOn (
11141111 params.channelIndex + 1 , noteInd, note.velocity );
1115- midiMessages.addEvent (
1116- noteOn,
1117- static_cast <int >(ceil (numSamples * (note.time - playHeadTime) /
1118- barsInBlock)));
1112+ int noteOnSample = 0 ;
1113+ if (playHeadTime < note.time ) {
1114+ noteOnSample = static_cast <int >(ceil (
1115+ numSamples * (note.time - playHeadTime) / barsInBlock));
1116+ }
1117+ midiMessages.addEvent (noteOn, noteOnSample);
11191118 currPlayedNotesTotalCents.insert (note.octave * 1200 + note.cents );
11201119 currPlayedNotesIndexes.insert (noteInd);
11211120 if (note.bend != 0 ) {
@@ -1125,6 +1124,16 @@ void AudioPluginAudioProcessor::processBlock(juce::AudioBuffer<float> &buffer,
11251124 }
11261125 }
11271126 }
1127+ // =======================================
1128+ for (int i = 0 ; i < notes.size (); ++i) {
1129+ const Note ¬e = notes[i];
1130+ // Note bend
1131+ if ((note.bend != 0 ) && (note.time < playHeadTime) &&
1132+ (playHeadTime <= note.time + note.duration )) {
1133+ freqs[notesIndexes[i]] = getNoteFreq (note);
1134+ needUpdateFreqs = true ;
1135+ }
1136+ }
11281137 if (needUpdateFreqs) {
11291138 pluginInstanceManager->updateFreqs (freqs);
11301139 }
0 commit comments