Skip to content

Commit

Permalink
Merge pull request #10931 from fwcd/var-bpm-analysis-override
Browse files Browse the repository at this point in the history
Analysis: Add support for overriding variable/constant BPM on a per-track basis
  • Loading branch information
daschuer authored Oct 5, 2022
2 parents 97d0bef + a1848e1 commit 505c47a
Show file tree
Hide file tree
Showing 33 changed files with 277 additions and 91 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -491,8 +491,10 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/analyzer/analyzerebur128.cpp
src/analyzer/analyzergain.cpp
src/analyzer/analyzerkey.cpp
src/analyzer/analyzerscheduledtrack.cpp
src/analyzer/analyzersilence.cpp
src/analyzer/analyzerthread.cpp
src/analyzer/analyzertrack.cpp
src/analyzer/analyzerwaveform.cpp
src/analyzer/plugins/analyzerqueenmarybeats.cpp
src/analyzer/plugins/analyzerqueenmarykey.cpp
Expand Down
11 changes: 7 additions & 4 deletions src/analyzer/analyzer.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include "analyzer/analyzertrack.h"
#include "audio/types.h"
#include "util/assert.h"
#include "util/types.h"
Expand All @@ -22,7 +23,7 @@ class Analyzer {
// 1. Check if the track needs to be analyzed, otherwise return false.
// 2. Perform the initialization and return true on success.
// 3. If the initialization failed log the internal error and return false.
virtual bool initialize(TrackPointer tio,
virtual bool initialize(const AnalyzerTrack& tio,
mixxx::audio::SampleRate sampleRate,
int totalSamples) = 0;

Expand Down Expand Up @@ -69,7 +70,9 @@ class AnalyzerWithState final {
return m_active;
}

bool initialize(TrackPointer tio, mixxx::audio::SampleRate sampleRate, int totalSamples) {
bool initialize(const AnalyzerTrack& tio,
mixxx::audio::SampleRate sampleRate,
int totalSamples) {
DEBUG_ASSERT(!m_active);
return m_active = m_analyzer->initialize(tio, sampleRate, totalSamples);
}
Expand All @@ -85,9 +88,9 @@ class AnalyzerWithState final {
}
}

void finish(TrackPointer tio) {
void finish(const AnalyzerTrack& tio) {
if (m_active) {
m_analyzer->storeResults(tio);
m_analyzer->storeResults(tio.getTrack());
m_analyzer->cleanup();
m_active = false;
}
Expand Down
10 changes: 6 additions & 4 deletions src/analyzer/analyzerbeats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <QVector>
#include <QtDebug>

#include "analyzer/analyzertrack.h"
#include "analyzer/constants.h"
#include "analyzer/plugins/analyzerqueenmarybeats.h"
#include "analyzer/plugins/analyzersoundtouchbeats.h"
Expand Down Expand Up @@ -41,7 +42,7 @@ AnalyzerBeats::AnalyzerBeats(UserSettingsPointer pConfig, bool enforceBpmDetecti
m_iCurrentSample(0) {
}

bool AnalyzerBeats::initialize(TrackPointer pTrack,
bool AnalyzerBeats::initialize(const AnalyzerTrack& track,
mixxx::audio::SampleRate sampleRate,
int totalSamples) {
if (totalSamples == 0) {
Expand All @@ -55,13 +56,14 @@ bool AnalyzerBeats::initialize(TrackPointer pTrack,
return false;
}

bool bpmLock = pTrack->isBpmLocked();
bool bpmLock = track.getTrack()->isBpmLocked();
if (bpmLock) {
qDebug() << "Track is BpmLocked: Beat calculation will not start";
return false;
}

m_bPreferencesFixedTempo = m_bpmSettings.getFixedTempoAssumption();
m_bPreferencesFixedTempo = track.getOptions().useFixedTempo.value_or(
m_bpmSettings.getFixedTempoAssumption());
m_bPreferencesReanalyzeOldBpm = m_bpmSettings.getReanalyzeWhenSettingsChange();
m_bPreferencesReanalyzeImported = m_bpmSettings.getReanalyzeImported();
m_bPreferencesFastAnalysis = m_bpmSettings.getFastAnalysis();
Expand Down Expand Up @@ -98,7 +100,7 @@ bool AnalyzerBeats::initialize(TrackPointer pTrack,
m_iCurrentSample = 0;

// if we can load a stored track don't reanalyze it
bool bShouldAnalyze = shouldAnalyze(pTrack);
bool bShouldAnalyze = shouldAnalyze(track.getTrack());

DEBUG_ASSERT(!m_pPlugin);
if (bShouldAnalyze) {
Expand Down
3 changes: 2 additions & 1 deletion src/analyzer/analyzerbeats.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <QList>

#include "analyzer/analyzer.h"
#include "analyzer/analyzertrack.h"
#include "analyzer/plugins/analyzerplugin.h"
#include "preferences/beatdetectionsettings.h"
#include "preferences/usersettings.h"
Expand All @@ -26,7 +27,7 @@ class AnalyzerBeats : public Analyzer {
static QList<mixxx::AnalyzerPluginInfo> availablePlugins();
static mixxx::AnalyzerPluginInfo defaultPlugin();

bool initialize(TrackPointer pTrack,
bool initialize(const AnalyzerTrack& track,
mixxx::audio::SampleRate sampleRate,
int totalSamples) override;
bool processSamples(const CSAMPLE *pIn, const int iLen) override;
Expand Down
5 changes: 3 additions & 2 deletions src/analyzer/analyzerebur128.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <QtDebug>

#include "analyzer/analyzertrack.h"
#include "track/track.h"
#include "util/math.h"
#include "util/sample.h"
Expand All @@ -20,10 +21,10 @@ AnalyzerEbur128::~AnalyzerEbur128() {
cleanup(); // ...to prevent memory leaks
}

bool AnalyzerEbur128::initialize(TrackPointer tio,
bool AnalyzerEbur128::initialize(const AnalyzerTrack& tio,
mixxx::audio::SampleRate sampleRate,
int totalSamples) {
if (m_rgSettings.isAnalyzerDisabled(2, tio) || totalSamples == 0) {
if (m_rgSettings.isAnalyzerDisabled(2, tio.getTrack()) || totalSamples == 0) {
qDebug() << "Skipping AnalyzerEbur128";
return false;
}
Expand Down
3 changes: 2 additions & 1 deletion src/analyzer/analyzerebur128.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <ebur128.h>

#include "analyzer/analyzer.h"
#include "analyzer/analyzertrack.h"
#include "preferences/replaygainsettings.h"

class AnalyzerEbur128 : public Analyzer {
Expand All @@ -14,7 +15,7 @@ class AnalyzerEbur128 : public Analyzer {
return rgSettings.isAnalyzerEnabled(2);
}

bool initialize(TrackPointer tio,
bool initialize(const AnalyzerTrack& track,
mixxx::audio::SampleRate sampleRate,
int totalSamples) override;
bool processSamples(const CSAMPLE* pIn, const int iLen) override;
Expand Down
9 changes: 6 additions & 3 deletions src/analyzer/analyzergain.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#include "analyzer/analyzergain.h"

#include <replaygain.h>

#include <QtDebug>

#include "analyzer/analyzergain.h"
#include "analyzer/analyzertrack.h"
#include "track/track.h"
#include "util/math.h"
#include "util/sample.h"
Expand All @@ -17,10 +20,10 @@ AnalyzerGain::~AnalyzerGain() {
delete m_pReplayGain;
}

bool AnalyzerGain::initialize(TrackPointer tio,
bool AnalyzerGain::initialize(const AnalyzerTrack& tio,
mixxx::audio::SampleRate sampleRate,
int totalSamples) {
if (m_rgSettings.isAnalyzerDisabled(1, tio) || totalSamples == 0) {
if (m_rgSettings.isAnalyzerDisabled(1, tio.getTrack()) || totalSamples == 0) {
qDebug() << "Skipping AnalyzerGain";
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/analyzer/analyzergain.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class AnalyzerGain : public Analyzer {
return rgSettings.isAnalyzerEnabled(1);
}

bool initialize(TrackPointer tio,
bool initialize(const AnalyzerTrack& track,
mixxx::audio::SampleRate sampleRate,
int totalSamples) override;
bool processSamples(const CSAMPLE* pIn, const int iLen) override;
Expand Down
5 changes: 3 additions & 2 deletions src/analyzer/analyzerkey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <QVector>
#include <QtDebug>

#include "analyzer/analyzertrack.h"
#include "analyzer/constants.h"
#if defined __KEYFINDER__
#include "analyzer/plugins/analyzerkeyfinder.h"
Expand Down Expand Up @@ -41,7 +42,7 @@ AnalyzerKey::AnalyzerKey(const KeyDetectionSettings& keySettings)
m_bPreferencesReanalyzeEnabled(false) {
}

bool AnalyzerKey::initialize(TrackPointer tio,
bool AnalyzerKey::initialize(const AnalyzerTrack& tio,
mixxx::audio::SampleRate sampleRate,
int totalSamples) {
if (totalSamples == 0) {
Expand Down Expand Up @@ -86,7 +87,7 @@ bool AnalyzerKey::initialize(TrackPointer tio,
m_iCurrentSample = 0;

// if we can't load a stored track reanalyze it
bool bShouldAnalyze = shouldAnalyze(tio);
bool bShouldAnalyze = shouldAnalyze(tio.getTrack());

DEBUG_ASSERT(!m_pPlugin);
if (bShouldAnalyze) {
Expand Down
3 changes: 2 additions & 1 deletion src/analyzer/analyzerkey.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <QString>

#include "analyzer/analyzer.h"
#include "analyzer/analyzertrack.h"
#include "analyzer/plugins/analyzerplugin.h"
#include "preferences/keydetectionsettings.h"
#include "preferences/usersettings.h"
Expand All @@ -19,7 +20,7 @@ class AnalyzerKey : public Analyzer {
static QList<mixxx::AnalyzerPluginInfo> availablePlugins();
static mixxx::AnalyzerPluginInfo defaultPlugin();

bool initialize(TrackPointer tio,
bool initialize(const AnalyzerTrack& tio,
mixxx::audio::SampleRate sampleRate,
int totalSamples) override;
bool processSamples(const CSAMPLE *pIn, const int iLen) override;
Expand Down
16 changes: 16 additions & 0 deletions src/analyzer/analyzerscheduledtrack.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include "analyzer/analyzerscheduledtrack.h"

#include "analyzer/analyzertrack.h"
#include "track/trackid.h"

AnalyzerScheduledTrack::AnalyzerScheduledTrack(TrackId trackId, AnalyzerTrack::Options options)
: m_trackId(trackId), m_options(options) {
}

const TrackId& AnalyzerScheduledTrack::getTrackId() const {
return m_trackId;
}

const AnalyzerTrack::Options& AnalyzerScheduledTrack::getOptions() const {
return m_options;
}
26 changes: 26 additions & 0 deletions src/analyzer/analyzerscheduledtrack.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

#include <optional>

#include "analyzer/analyzertrack.h"
#include "track/track_decl.h"
#include "track/trackid.h"

/// A track to be scheduled for analysis with additional options.
class AnalyzerScheduledTrack {
public:
AnalyzerScheduledTrack(TrackId trackId,
AnalyzerTrack::Options options = AnalyzerTrack::Options());

/// Fetches the id of the track to be analyzed.
const TrackId& getTrackId() const;

/// Fetches the additional options.
const AnalyzerTrack::Options& getOptions() const;

private:
/// The id of the track to be analyzed.
TrackId m_trackId;
/// The additional options.
AnalyzerTrack::Options m_options;
};
5 changes: 3 additions & 2 deletions src/analyzer/analyzersilence.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "analyzer/analyzersilence.h"

#include "analyzer/analyzertrack.h"
#include "analyzer/constants.h"
#include "engine/engine.h"
#include "track/track.h"
Expand Down Expand Up @@ -32,13 +33,13 @@ AnalyzerSilence::AnalyzerSilence(UserSettingsPointer pConfig)
m_iSignalEnd(-1) {
}

bool AnalyzerSilence::initialize(TrackPointer pTrack,
bool AnalyzerSilence::initialize(const AnalyzerTrack& track,
mixxx::audio::SampleRate sampleRate,
int totalSamples) {
Q_UNUSED(sampleRate);
Q_UNUSED(totalSamples);

if (!shouldAnalyze(pTrack)) {
if (!shouldAnalyze(track.getTrack())) {
return false;
}

Expand Down
3 changes: 2 additions & 1 deletion src/analyzer/analyzersilence.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "analyzer/analyzer.h"
#include "analyzer/analyzertrack.h"
#include "preferences/usersettings.h"

class CuePointer;
Expand All @@ -10,7 +11,7 @@ class AnalyzerSilence : public Analyzer {
explicit AnalyzerSilence(UserSettingsPointer pConfig);
~AnalyzerSilence() override = default;

bool initialize(TrackPointer pTrack,
bool initialize(const AnalyzerTrack& track,
mixxx::audio::SampleRate sampleRate,
int totalSamples) override;
bool processSamples(const CSAMPLE* pIn, const int iLen) override;
Expand Down
Loading

0 comments on commit 505c47a

Please sign in to comment.