Skip to content

Commit

Permalink
Merge pull request #26188 from alexpavlov96/guitar_bend_import_5
Browse files Browse the repository at this point in the history
Guitar bend import 5
  • Loading branch information
alexpavlov96 authored Jan 21, 2025
2 parents 20390c2 + 6c09339 commit 225ea69
Show file tree
Hide file tree
Showing 7 changed files with 1,755 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ constexpr int MAX_DENOMINATOR = 64;
constexpr Fraction ONE_DOT_DURATION_MULTIPLIER(3, 2);
constexpr Fraction TWO_DOTS_DURATION_MULTIPLIER(7, 4);

static int findClosestNumerator(const Fraction& fraction, int requestedDenominator, bool skipFirstBest);
static Fraction findClosestDisplayableDuration(const Fraction& totalDuration, const Fraction& targetDuration, int maxDenominator,
bool skipFirstBest);
static std::vector<Fraction> fillDurationsByProportions(const Fraction& totalDuration, const std::vector<Fraction>& proportions,
Expand Down Expand Up @@ -153,24 +152,14 @@ static std::vector<Fraction> generateDurations(int maxDenominator)
return durations;
}

static Fraction findClosestDisplayableDuration(const Fraction& totalDuration, const Fraction& targetDuration, int maxDenominator,
static Fraction findClosestDisplayableDuration(const Fraction& totalDuration, const Fraction& targetDuration, int requestedDenominator,
bool skipFirstBest)
{
int numerator = findClosestNumerator(targetDuration, maxDenominator, skipFirstBest);
Fraction currentChordTicks = Fraction(numerator, maxDenominator);
currentChordTicks = std::max(currentChordTicks, Fraction(1, maxDenominator));
currentChordTicks = std::min(currentChordTicks, totalDuration - Fraction(1, maxDenominator));
currentChordTicks.reduce();

return currentChordTicks;
}

static int findClosestNumerator(const Fraction& fraction, int requestedDenominator, bool skipFirstBest)
{
int closestNumerator = 0;
Fraction closestFraction = Fraction(0, 1);
double minDifference = std::numeric_limits<double>::max();
int numerator = fraction.numerator();
int denominator = fraction.denominator();
int numerator = targetDuration.numerator();
int denominator = targetDuration.denominator();
const Fraction smallestFraction(1, requestedDenominator);

bool firstBestSkipped = false;

Expand All @@ -180,18 +169,23 @@ static int findClosestNumerator(const Fraction& fraction, int requestedDenominat

double difference = std::fabs(originalFraction - candidateFraction);

if (difference < minDifference
&& canBeRepresentedAsDottedNote(Fraction(candidateNumerator, requestedDenominator), requestedDenominator)) {
if (skipFirstBest && !firstBestSkipped) {
firstBestSkipped = true;
} else {
minDifference = difference;
closestNumerator = candidateNumerator;
if (difference < minDifference) {
Fraction resultCandidateFraction(candidateNumerator, requestedDenominator);
resultCandidateFraction = std::max(resultCandidateFraction, smallestFraction);
resultCandidateFraction = std::min(resultCandidateFraction, totalDuration - smallestFraction);

if (canBeRepresentedAsDottedNote(resultCandidateFraction, requestedDenominator)) {
if (skipFirstBest && !firstBestSkipped) {
firstBestSkipped = true;
} else {
minDifference = difference;
closestFraction = resultCandidateFraction;
}
}
}
}

return closestNumerator;
return closestFraction.reduced();
}

static bool canBeRepresentedAsDottedNote(const Fraction& duration, int maxDenominator)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,27 @@ BendDataContext BendDataCollector::collectBendDataContext()
}
}

auto isPowerOfTwo = [](int n) {
return n > 0 && (n & (n - 1)) == 0;
};

for (const auto& [track, trackInfo] : tiedNotesAfterBend) {
const auto& importedInfoForTrack = m_bendInfoForNote.at(track);
for (const auto& [mainTick, chords] : trackInfo) {
const auto& importedInfoForTick = importedInfoForTrack.at(mainTick);
const Chord* lastChord = chords.back();
Fraction totalDuration = lastChord->tick() - Fraction::fromTicks(mainTick) + lastChord->ticks();
Fraction totalDuration = lastChord->tick() - Fraction::fromTicks(mainTick) + lastChord->actualTicks();
if (Tuplet* tuplet = lastChord->tuplet()) {
totalDuration *= tuplet->ratio();
}

totalDuration.reduce();
IF_ASSERT_FAILED(!totalDuration.negative() && isPowerOfTwo(totalDuration.denominator())) {
LOGE() << "bend import error: duration is wrong for track " << track << ", tick " << mainTick << "(" <<
totalDuration.numerator() << " / " << totalDuration.denominator() << ")";
continue;
}

if (!importedInfoForTick.empty()) {
fillChordDurationsFromBendDiagram(bendDataCtx, totalDuration, importedInfoForTick.begin()->second);
}
Expand Down Expand Up @@ -324,8 +339,13 @@ static void fillNormalBendData(BendDataContext& bendDataCtx, const BendDataColle

const auto& tickDurations = trackDurations.at(chordStartTick.ticks());

Fraction currentTick = chordStartTick;
if (tickDurations.empty()) {
LOGE() << "bend import error : chord durations are empty for track " << chord->track() << " tick " <<
chordStartTick.ticks();
return;
}

Fraction currentTick = chordStartTick;
for (size_t i = 0; i < tickDurations.size() - 1; i++) {
if (currentIndex >= importedInfo.segments.size()) {
break;
Expand Down
Loading

0 comments on commit 225ea69

Please sign in to comment.