Skip to content

Commit

Permalink
Added switch, to select if findPrevNextBeats should compare with or w…
Browse files Browse the repository at this point in the history
…ithout tolerance epsilon
  • Loading branch information
JoergAtGithub committed Feb 21, 2021
1 parent 4719d5e commit 143f255
Show file tree
Hide file tree
Showing 12 changed files with 54 additions and 36 deletions.
2 changes: 1 addition & 1 deletion src/engine/controls/bpmcontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ bool BpmControl::getBeatContext(const mixxx::BeatsPointer& pBeats,

double dPrevBeat;
double dNextBeat;
if (!pBeats->findPrevNextBeats(dPosition, &dPrevBeat, &dNextBeat)) {
if (!pBeats->findPrevNextBeats(dPosition, &dPrevBeat, &dNextBeat, false)) {
return false;
}

Expand Down
6 changes: 4 additions & 2 deletions src/engine/controls/clockcontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@ void ClockControl::updateIndicators(const double dRate,
(currentSample <= m_PrevBeatSamples)) {
//qDebug() << "### findPrevNextBeats ### " << " currentSample: " << currentSample << " m_lastEvaluatedSample: " << m_lastEvaluatedSample << " m_PrevBeatSamples: " << m_PrevBeatSamples << " m_NextBeatSamples: " << m_NextBeatSamples;

pBeats->findPrevNextBeats(
currentSample, &m_PrevBeatSamples, &m_NextBeatSamples);
pBeats->findPrevNextBeats(currentSample,
&m_PrevBeatSamples,
&m_NextBeatSamples,
true); // Precise compare without tolerance needed

m_blinkIntervalSamples = (m_NextBeatSamples - m_PrevBeatSamples) * kBlinkInterval;
}
Expand Down
2 changes: 1 addition & 1 deletion src/engine/controls/loopingcontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1194,7 +1194,7 @@ void LoopingControl::slotBeatLoop(double beats, bool keepStartPoint, bool enable
// The closest beat might be ahead of play position and will cause a catching loop.
double prevBeat;
double nextBeat;
pBeats->findPrevNextBeats(currentSample, &prevBeat, &nextBeat);
pBeats->findPrevNextBeats(currentSample, &prevBeat, &nextBeat, false);

if (m_pQuantizeEnabled->toBool() && prevBeat != -1) {
double beatLength = nextBeat - prevBeat;
Expand Down
2 changes: 1 addition & 1 deletion src/engine/controls/quantizecontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ void QuantizeControl::lookupBeatPositions(double dCurrentSample) {
mixxx::BeatsPointer pBeats = m_pBeats;
if (pBeats) {
double prevBeat, nextBeat;
pBeats->findPrevNextBeats(dCurrentSample, &prevBeat, &nextBeat);
pBeats->findPrevNextBeats(dCurrentSample, &prevBeat, &nextBeat, false);
m_pCOPrevBeat->set(prevBeat);
m_pCONextBeat->set(nextBeat);
}
Expand Down
8 changes: 4 additions & 4 deletions src/test/beatgridtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ TEST(BeatGridTest, TestNthBeatWhenOnBeat) {

// Also test prev/next beat calculation.
double prevBeat, nextBeat;
pGrid->findPrevNextBeats(position, &prevBeat, &nextBeat);
pGrid->findPrevNextBeats(position, &prevBeat, &nextBeat, false);
EXPECT_NEAR(position, prevBeat, kMaxBeatError);
EXPECT_NEAR(position + beatLength, nextBeat, kMaxBeatError);

Expand Down Expand Up @@ -115,7 +115,7 @@ TEST(BeatGridTest, TestNthBeatWhenOnBeat_BeforeEpsilon) {

// Also test prev/next beat calculation.
double prevBeat, nextBeat;
pGrid->findPrevNextBeats(position, &prevBeat, &nextBeat);
pGrid->findPrevNextBeats(position, &prevBeat, &nextBeat, false);
EXPECT_NEAR(kClosestBeat, prevBeat, kMaxBeatError);
EXPECT_NEAR(kClosestBeat + beatLength, nextBeat, kMaxBeatError);

Expand Down Expand Up @@ -152,7 +152,7 @@ TEST(BeatGridTest, TestNthBeatWhenOnBeat_AfterEpsilon) {

// Also test prev/next beat calculation.
double prevBeat, nextBeat;
pGrid->findPrevNextBeats(position, &prevBeat, &nextBeat);
pGrid->findPrevNextBeats(position, &prevBeat, &nextBeat, false);
EXPECT_NEAR(kClosestBeat, prevBeat, kMaxBeatError);
EXPECT_NEAR(kClosestBeat + beatLength, nextBeat, kMaxBeatError);

Expand Down Expand Up @@ -190,7 +190,7 @@ TEST(BeatGridTest, TestNthBeatWhenNotOnBeat) {

// Also test prev/next beat calculation
double foundPrevBeat, foundNextBeat;
pGrid->findPrevNextBeats(position, &foundPrevBeat, &foundNextBeat);
pGrid->findPrevNextBeats(position, &foundPrevBeat, &foundNextBeat, false);
EXPECT_NEAR(previousBeat, foundPrevBeat, kMaxBeatError);
EXPECT_NEAR(nextBeat, foundNextBeat, kMaxBeatError);
}
Expand Down
12 changes: 6 additions & 6 deletions src/test/beatmaptest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,11 @@ TEST_F(BeatMapTest, TestNthBeat) {
EXPECT_EQ(-1, pMap->findNthBeat(firstBeat, -2));

double prevBeat, nextBeat;
pMap->findPrevNextBeats(lastBeat, &prevBeat, &nextBeat);
pMap->findPrevNextBeats(lastBeat, &prevBeat, &nextBeat, false);
EXPECT_EQ(lastBeat, prevBeat);
EXPECT_EQ(-1, nextBeat);

pMap->findPrevNextBeats(firstBeat, &prevBeat, &nextBeat);
pMap->findPrevNextBeats(firstBeat, &prevBeat, &nextBeat, false);
EXPECT_EQ(firstBeat, prevBeat);
EXPECT_EQ(firstBeat + beatLengthSamples, nextBeat);
}
Expand Down Expand Up @@ -137,7 +137,7 @@ TEST_F(BeatMapTest, TestNthBeatWhenOnBeat) {

// Also test prev/next beat calculation.
double prevBeat, nextBeat;
pMap->findPrevNextBeats(position, &prevBeat, &nextBeat);
pMap->findPrevNextBeats(position, &prevBeat, &nextBeat, false);
EXPECT_EQ(position, prevBeat);
EXPECT_EQ(position + beatLengthSamples, nextBeat);

Expand Down Expand Up @@ -175,7 +175,7 @@ TEST_F(BeatMapTest, TestNthBeatWhenOnBeat_BeforeEpsilon) {

// Also test prev/next beat calculation
double prevBeat, nextBeat;
pMap->findPrevNextBeats(position, &prevBeat, &nextBeat);
pMap->findPrevNextBeats(position, &prevBeat, &nextBeat, false);
EXPECT_EQ(kClosestBeat, prevBeat);
EXPECT_EQ(kClosestBeat + beatLengthSamples, nextBeat);

Expand Down Expand Up @@ -216,7 +216,7 @@ TEST_F(BeatMapTest, TestNthBeatWhenOnBeat_AfterEpsilon) {

// Also test prev/next beat calculation.
double prevBeat, nextBeat;
pMap->findPrevNextBeats(position, &prevBeat, &nextBeat);
pMap->findPrevNextBeats(position, &prevBeat, &nextBeat, false);
EXPECT_EQ(kClosestBeat, prevBeat);
EXPECT_EQ(kClosestBeat + beatLengthSamples, nextBeat);

Expand Down Expand Up @@ -256,7 +256,7 @@ TEST_F(BeatMapTest, TestNthBeatWhenNotOnBeat) {

// Also test prev/next beat calculation
double foundPrevBeat, foundNextBeat;
pMap->findPrevNextBeats(position, &foundPrevBeat, &foundNextBeat);
pMap->findPrevNextBeats(position, &foundPrevBeat, &foundNextBeat, false);
EXPECT_EQ(previousBeat, foundPrevBeat);
EXPECT_EQ(nextBeat, foundNextBeat);
}
Expand Down
21 changes: 13 additions & 8 deletions src/track/beatgrid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ double BeatGrid::findClosestBeat(double dSamples) const {
}
double prevBeat;
double nextBeat;
findPrevNextBeats(dSamples, &prevBeat, &nextBeat);
findPrevNextBeats(dSamples, &prevBeat, &nextBeat, false);
if (prevBeat == -1) {
// If both values are -1, we correctly return -1.
return nextBeat;
Expand Down Expand Up @@ -214,8 +214,10 @@ double BeatGrid::findNthBeat(double dSamples, int n) const {
}

bool BeatGrid::findPrevNextBeats(double dSamples,
double* dpPrevBeatSamples,
double* dpNextBeatSamples) const {

double* dpPrevBeatSamples,
double* dpNextBeatSamples,
bool NoTolerance) const {
double dFirstBeatSample;
double dBeatLength;
{
Expand All @@ -232,11 +234,15 @@ bool BeatGrid::findPrevNextBeats(double dSamples,
double beatFraction = (dSamples - dFirstBeatSample) / dBeatLength;
double prevBeat = floor(beatFraction);
double nextBeat = ceil(beatFraction);
double kEpsilon;

// If the position is within 1/1000,000,000th of the next or previous beat, treat it
// as if it is that beat. This value ensures safe float comparisation and that the
// accuracy is always better one sample.
const double kEpsilon = 1e-09;
if (NoTolerance) {
kEpsilon = 0.0f;
} else {
// If the position is within 1/100th of the next or previous beat, treat it
// as if it is that beat.
kEpsilon = .01;
}

if (fabs(nextBeat - beatFraction) < kEpsilon) {
beatFraction = nextBeat;
Expand All @@ -252,7 +258,6 @@ bool BeatGrid::findPrevNextBeats(double dSamples,
return true;
}


std::unique_ptr<BeatIterator> BeatGrid::findBeats(double startSample, double stopSample) const {
QMutexLocker locker(&m_mutex);
if (!isValid() || startSample > stopSample) {
Expand Down
6 changes: 4 additions & 2 deletions src/track/beatgrid.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@ class BeatGrid final : public Beats {
double findNextBeat(double dSamples) const override;
double findPrevBeat(double dSamples) const override;
bool findPrevNextBeats(double dSamples,
double* dpPrevBeatSamples,
double* dpNextBeatSamples) const override;

double* dpPrevBeatSamples,
double* dpNextBeatSamples,
bool NoTolerance) const override;
double findClosestBeat(double dSamples) const override;
double findNthBeat(double dSamples, int n) const override;
std::unique_ptr<BeatIterator> findBeats(double startSample, double stopSample) const override;
Expand Down
19 changes: 13 additions & 6 deletions src/track/beatmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ double BeatMap::findClosestBeat(double dSamples) const {
}
double prevBeat;
double nextBeat;
findPrevNextBeats(dSamples, &prevBeat, &nextBeat);
findPrevNextBeats(dSamples, &prevBeat, &nextBeat, false);
if (prevBeat == -1) {
// If both values are -1, we correctly return -1.
return nextBeat;
Expand Down Expand Up @@ -286,8 +286,9 @@ double BeatMap::findNthBeat(double dSamples, int n) const {
}

bool BeatMap::findPrevNextBeats(double dSamples,
double* dpPrevBeatSamples,
double* dpNextBeatSamples) const {
double* dpPrevBeatSamples,
double* dpNextBeatSamples,
bool NoTolerance) const {
QMutexLocker locker(&m_mutex);

if (!isValid()) {
Expand All @@ -304,9 +305,15 @@ bool BeatMap::findPrevNextBeats(double dSamples,
BeatList::const_iterator it =
std::lower_bound(m_beats.constBegin(), m_beats.constEnd(), beat, BeatLessThan);

// If the position is within 1/10th of a second of the next or previous
// beat, pretend we are on that beat.
const double kFrameEpsilon = 0.1 * m_iSampleRate;
double kFrameEpsilon;

if (NoTolerance) {
kFrameEpsilon = 0.0f;
} else {
// If the position is within 1/10th of a second of the next or previous
// beat, pretend we are on that beat.
kFrameEpsilon = 0.1 * m_iSampleRate;
}

// Back-up by one.
if (it != m_beats.begin()) {
Expand Down
5 changes: 3 additions & 2 deletions src/track/beatmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ class BeatMap final : public Beats {
double findNextBeat(double dSamples) const override;
double findPrevBeat(double dSamples) const override;
bool findPrevNextBeats(double dSamples,
double* dpPrevBeatSamples,
double* dpNextBeatSamples) const override;
double* dpPrevBeatSamples,
double* dpNextBeatSamples,
bool NoTolerance) const override;
double findClosestBeat(double dSamples) const override;
double findNthBeat(double dSamples, int n) const override;
std::unique_ptr<BeatIterator> findBeats(double startSample, double stopSample) const override;
Expand Down
2 changes: 1 addition & 1 deletion src/track/beats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ double Beats::findNBeatsFromSample(double fromSample, double beats) const {
double prevBeat;
double nextBeat;

if (!findPrevNextBeats(fromSample, &prevBeat, &nextBeat)) {
if (!findPrevNextBeats(fromSample, &prevBeat, &nextBeat, false)) {
return fromSample;
}
double fromFractionBeats = (fromSample - prevBeat) / (nextBeat - prevBeat);
Expand Down
5 changes: 3 additions & 2 deletions src/track/beats.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,9 @@ class Beats : public QObject {
// even. Returns false if *at least one* sample is -1. (Can return false
// with one beat successfully filled)
virtual bool findPrevNextBeats(double dSamples,
double* dpPrevBeatSamples,
double* dpNextBeatSamples) const = 0;
double* dpPrevBeatSamples,
double* dpNextBeatSamples,
bool NoTolerance) const = 0;

// Starting from sample dSamples, return the sample of the closest beat in
// the track, or -1 if none exists. Non- -1 values are guaranteed to be
Expand Down

0 comments on commit 143f255

Please sign in to comment.