Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Analysis: Add support for overriding variable/constant BPM on a per-track basis #10931

Merged
merged 11 commits into from
Oct 5, 2022
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