From 7c8fd53a0eade2507b5818af9d350a6d7c3859e6 Mon Sep 17 00:00:00 2001 From: "Andrey M. Tokarev" Date: Fri, 5 Jul 2013 15:31:36 +0400 Subject: [PATCH] Fix quantization of non-tuplet chords --- mscore/importmidi_quant.cpp | 42 ++++++++++++++++-------------------- mscore/importmidi_tuplet.cpp | 17 +++++++++++++++ mscore/importmidi_tuplet.h | 11 +++++----- 3 files changed, 40 insertions(+), 30 deletions(-) diff --git a/mscore/importmidi_quant.cpp b/mscore/importmidi_quant.cpp index 0ce6d66271..9282016a54 100644 --- a/mscore/importmidi_quant.cpp +++ b/mscore/importmidi_quant.cpp @@ -117,20 +117,19 @@ int findQuantRaster(const std::multimap::iterator &startBarChord return raster; } -// chords onTime values here don't repeat -// chords that were quantisized in tuplets aren't quantisized here - void doGridQuantizationOfBar(std::multimap &quantizedChords, const std::multimap::iterator &startChordIt, const std::multimap::iterator &endChordIt, int raster, - int endBarTick) + int endBarTick, + const std::vector::iterator> &chordsNotQuant) { int raster2 = raster >> 1; for (auto it = startChordIt; it != endChordIt; ++it) { if (it->first >= endBarTick) break; - if (quantizedChords.find(it->first) != quantizedChords.end()) + auto found = std::find(chordsNotQuant.begin(), chordsNotQuant.end(), it); + if (found != chordsNotQuant.end()) continue; auto chord = it->second; chord.onTime = ((chord.onTime + raster2) / raster) * raster; @@ -145,7 +144,9 @@ void doGridQuantizationOfBar(std::multimap &quantizedChords, void applyGridQuant(std::multimap &chords, std::multimap &quantizedChords, int lastTick, - const TimeSigMap* sigmap) + const TimeSigMap* sigmap, + const std::vector::iterator> &chordsNotQuant + = std::vector::iterator>()) { int startBarTick = 0; auto startBarChordIt = chords.begin(); @@ -153,10 +154,10 @@ void applyGridQuant(std::multimap &chords, int endBarTick = sigmap->bar2tick(i, 0); startBarChordIt = findFirstChordInRange(startBarTick, endBarTick, startBarChordIt, chords.end()); - if (startBarChordIt != chords.end()) { // if chords are found in this bar + if (startBarChordIt != chords.end()) { // if chords are found in this bar int raster = findQuantRaster(startBarChordIt, chords.end(), endBarTick); doGridQuantizationOfBar(quantizedChords, startBarChordIt, chords.end(), - raster, endBarTick); + raster, endBarTick, chordsNotQuant); } else startBarChordIt = chords.begin(); @@ -175,32 +176,24 @@ void applyGridQuant(std::multimap &chords, std::swap(chords, quantizedChords); } -// input chords - sorted by onTime value, -// onTime values don't repeat even in multimap below +// input chords - sorted by onTime value, onTime values don't repeat void quantizeChordsAndTuplets(std::multimap &tupletEvents, std::multimap &chords, const TimeSigMap* sigmap, int lastTick) { - std::multimap quantizedChords; // chords with already quantized onTime values - // quantize chords in tuplets + std::multimap quantizedChords; + std::vector::iterator> tupletChords; + // quantize tuplet chords, if any int startBarTick = 0; for (int i = 1;; ++i) { // iterate over all measures by indexes int endBarTick = sigmap->bar2tick(i, 0); Fraction barFraction = sigmap->timesig(startBarTick).timesig(); - std::vector preparedTuplets; - { - auto tuplets = MidiTuplet::findTupletCandidatesOfBar(startBarTick, endBarTick, - barFraction, chords); - MidiTuplet::filterTuplets(tuplets); + auto tuplets = MidiTuplet::findTuplets(startBarTick, endBarTick, barFraction, chords); + MidiTuplet::separateTupletVoices(tuplets, chords); - for (const auto &t: tuplets) - preparedTuplets.push_back(t.second); - } - MidiTuplet::separateTupletVoices(preparedTuplets, chords); - - for (auto &tupletInfo: preparedTuplets) { + for (auto &tupletInfo: tuplets) { auto &infoChords = tupletInfo.chords; for (auto &tupletChord: infoChords) { int tupletNoteNum = tupletChord.first; @@ -211,6 +204,7 @@ void quantizeChordsAndTuplets(std::multimap &tuplet MidiChord midiChord = midiChordEventIt->second; MidiTuplet::quantizeTupletChord(midiChord, onTime, tupletInfo); quantizedChords.insert({onTime, midiChord}); + tupletChords.push_back(midiChordEventIt); } MidiTuplet::TupletData tupletData = {tupletInfo.chords.begin()->second->second.voice, tupletInfo.onTime, @@ -223,7 +217,7 @@ void quantizeChordsAndTuplets(std::multimap &tuplet startBarTick = endBarTick; } // quantize non-tuplet (remaining) chords with ordinary grid - applyGridQuant(chords, quantizedChords, lastTick, sigmap); + applyGridQuant(chords, quantizedChords, lastTick, sigmap, tupletChords); std::swap(chords, quantizedChords); } diff --git a/mscore/importmidi_tuplet.cpp b/mscore/importmidi_tuplet.cpp index e3c46db1ce..5cf85ecffa 100644 --- a/mscore/importmidi_tuplet.cpp +++ b/mscore/importmidi_tuplet.cpp @@ -434,6 +434,23 @@ void quantizeTupletChord(MidiChord &midiChord, int onTime, const TupletInfo &tup note.onTime = onTime; note.len = offTime - onTime; } + // notes in chord here may have different durations + // so we don't set the whole chord duration + } + +std::vector findTuplets(int startBarTick, + int endBarTick, + const Fraction &barFraction, + std::multimap &chords) + { + std::vector preparedTuplets; + auto tuplets = findTupletCandidatesOfBar(startBarTick, endBarTick, + barFraction, chords); + filterTuplets(tuplets); + for (const auto &t: tuplets) + preparedTuplets.push_back(t.second); + + return preparedTuplets; } } // namespace MidiTuplet diff --git a/mscore/importmidi_tuplet.h b/mscore/importmidi_tuplet.h index f66f65249f..9a6b2a5403 100644 --- a/mscore/importmidi_tuplet.h +++ b/mscore/importmidi_tuplet.h @@ -42,14 +42,13 @@ void filterTuplets(std::multimap &tuplets); void separateTupletVoices(std::vector &tuplets, std::multimap &chords); -std::multimap -findTupletCandidatesOfBar(int startBarTick, - int endBarTick, - const Fraction &barFraction, - std::multimap &chords); - void quantizeTupletChord(MidiChord &midiChord, int onTime, const TupletInfo &tupletInfo); +std::vector findTuplets(int startBarTick, + int endBarTick, + const Fraction &barFraction, + std::multimap &chords); + } // namespace MidiTuplet } // namespace Ms