summaryrefslogtreecommitdiffstats
path: root/src/track
diff options
context:
space:
mode:
authorUwe Klotz <uklotz@mixxx.org>2021-09-08 10:47:05 +0200
committerUwe Klotz <uklotz@mixxx.org>2021-09-08 10:49:29 +0200
commit9c42ccc419b1b968c79b29224f3185f846ec1a07 (patch)
tree29caf233ff1e52f8814af83032f728d89b742bb9 /src/track
parentc468680572c673f60a85ea93553df88d13889078 (diff)
Beat detection: Check preconditions and handle edge cases
Diffstat (limited to 'src/track')
-rw-r--r--src/track/beatfactory.cpp11
-rw-r--r--src/track/beatutils.cpp15
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.