diff options
author | Uwe Klotz <uklotz@mixxx.org> | 2021-09-08 10:47:05 +0200 |
---|---|---|
committer | Uwe Klotz <uklotz@mixxx.org> | 2021-09-08 10:49:29 +0200 |
commit | 9c42ccc419b1b968c79b29224f3185f846ec1a07 (patch) | |
tree | 29caf233ff1e52f8814af83032f728d89b742bb9 /src/track | |
parent | c468680572c673f60a85ea93553df88d13889078 (diff) |
Beat detection: Check preconditions and handle edge cases
Diffstat (limited to 'src/track')
-rw-r--r-- | src/track/beatfactory.cpp | 11 | ||||
-rw-r--r-- | src/track/beatutils.cpp | 15 |
2 files changed, 16 insertions, 10 deletions
diff --git a/src/track/beatfactory.cpp b/src/track/beatfactory.cpp index 749680dfc5..110dc2c4d2 100644 --- a/src/track/beatfactory.cpp +++ b/src/track/beatfactory.cpp @@ -55,9 +55,7 @@ mixxx::BeatsPointer BeatFactory::makePreferredBeats( const QHash<QString, QString>& extraVersionInfo, bool fixedTempo, mixxx::audio::SampleRate sampleRate) { - const QString version = getPreferredVersion(fixedTempo); - const QString subVersion = getPreferredSubVersion(extraVersionInfo); - + DEBUG_ASSERT(sampleRate.isValid()); #ifdef DEBUG_PRINT_BEATS for (mixxx::audio::FramePos beat : beats) { qDebug().noquote() << QString::number(beat.value(), 'g', 8); @@ -66,13 +64,18 @@ mixxx::BeatsPointer BeatFactory::makePreferredBeats( QVector<BeatUtils::ConstRegion> constantRegions = BeatUtils::retrieveConstRegions(beats, sampleRate); - #ifdef DEBUG_PRINT_BEATS for (auto& region : constantRegions) { qDebug().noquote() << QString::number(region.firstBeat.value(), 'g', 8) << QString::number(region.beatLength, 'g', 8); } #endif + if (constantRegions.isEmpty()) { + return nullptr; + } + + const QString version = getPreferredVersion(fixedTempo); + const QString subVersion = getPreferredSubVersion(extraVersionInfo); if (version == BEAT_GRID_2_VERSION) { mixxx::audio::FramePos firstBeat = mixxx::audio::kStartFramePos; diff --git a/src/track/beatutils.cpp b/src/track/beatutils.cpp index b98cfa67fa..118a2aaffa 100644 --- a/src/track/beatutils.cpp +++ b/src/track/beatutils.cpp @@ -55,6 +55,11 @@ mixxx::Bpm BeatUtils::calculateBpm( QVector<BeatUtils::ConstRegion> BeatUtils::retrieveConstRegions( const QVector<mixxx::audio::FramePos>& coarseBeats, mixxx::audio::SampleRate sampleRate) { + DEBUG_ASSERT(sampleRate.isValid()); + if (coarseBeats.size() < 2) { + // Cannot infer a tempo for less than 2 beats + return {}; + } // The QM Beat detector has a step size of 512 frames @ 44100 Hz. This means that // Single beats have has a jitter of +- 12 ms around the actual position. // Expressed in BPM it means we have for instance steps of these BPM value around 120 BPM @@ -71,17 +76,12 @@ QVector<BeatUtils::ConstRegion> BeatUtils::retrieveConstRegions( // current average to adjust them by up to +-12 ms. // Than we start with the region from the found beat to the end. - QVector<ConstRegion> constantRegions; - if (!coarseBeats.size()) { - // no beats - return constantRegions; - } - const mixxx::audio::FrameDiff_t maxPhaseError = kMaxSecsPhaseError * sampleRate; const mixxx::audio::FrameDiff_t maxPhaseErrorSum = kMaxSecsPhaseErrorSum * sampleRate; int leftIndex = 0; int rightIndex = coarseBeats.size() - 1; + QVector<ConstRegion> constantRegions; while (leftIndex < coarseBeats.size() - 1) { DEBUG_ASSERT(rightIndex > leftIndex); mixxx::audio::FrameDiff_t meanBeatLength = @@ -144,6 +144,9 @@ mixxx::Bpm BeatUtils::makeConstBpm( const QVector<BeatUtils::ConstRegion>& constantRegions, mixxx::audio::SampleRate sampleRate, mixxx::audio::FramePos* pFirstBeat) { + DEBUG_ASSERT(!constantRegions.isEmpty()); + DEBUG_ASSERT(sampleRate.isValid()); + DEBUG_ASSERT(!pFirstBeat || pFirstBeat->isValid()); // We assume here the track was recorded with an unhear-able static metronome. // This metronome is likely at a full BPM. // The track may has intros, outros and bridges without detectable beats. |