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

Engine: Add feature for building with/without Rubberband #12661

Merged
merged 1 commit into from
Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -779,7 +779,6 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/effects/backends/builtin/distortioneffect.cpp
src/effects/backends/builtin/parametriceqeffect.cpp
src/effects/backends/builtin/phasereffect.cpp
src/effects/backends/builtin/pitchshifteffect.cpp
src/effects/backends/builtin/reverbeffect.cpp
src/effects/backends/builtin/threebandbiquadeqeffect.cpp
src/effects/backends/builtin/tremoloeffect.cpp
Expand Down Expand Up @@ -808,7 +807,6 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/encoder/encoderwavesettings.cpp
src/engine/bufferscalers/enginebufferscale.cpp
src/engine/bufferscalers/enginebufferscalelinear.cpp
src/engine/bufferscalers/enginebufferscalerubberband.cpp
src/engine/bufferscalers/enginebufferscalest.cpp
src/engine/cachingreader/cachingreader.cpp
src/engine/cachingreader/cachingreaderchunk.cpp
Expand Down Expand Up @@ -2909,8 +2907,16 @@ target_include_directories(mixxx-lib SYSTEM PRIVATE lib/reverb)
target_link_libraries(mixxx-lib PRIVATE Reverb)

# Rubberband
find_package(rubberband REQUIRED)
target_link_libraries(mixxx-lib PRIVATE rubberband::rubberband)
option(RUBBERBAND "Enable the rubberband engine for pitch-bending" ON)
if(RUBBERBAND)
find_package(rubberband REQUIRED)
target_link_libraries(mixxx-lib PRIVATE rubberband::rubberband)
target_compile_definitions(mixxx-lib PUBLIC __RUBBERBAND__)
target_sources(mixxx-lib PRIVATE
src/effects/backends/builtin/pitchshifteffect.cpp
src/engine/bufferscalers/enginebufferscalerubberband.cpp
)
endif()

# SndFile
find_package(SndFile REQUIRED)
Expand Down
4 changes: 4 additions & 0 deletions src/effects/backends/builtin/builtinbackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
#include "effects/backends/builtin/loudnesscontoureffect.h"
#include "effects/backends/builtin/metronomeeffect.h"
#include "effects/backends/builtin/phasereffect.h"
#ifdef __RUBBERBAND__
#include "effects/backends/builtin/pitchshifteffect.h"
#endif
#include "effects/backends/builtin/tremoloeffect.h"
#include "effects/backends/builtin/whitenoiseeffect.h"

Expand Down Expand Up @@ -54,7 +56,9 @@ BuiltInBackend::BuiltInBackend() {
registerEffect<PhaserEffect>();
registerEffect<MetronomeEffect>();
registerEffect<TremoloEffect>();
#ifdef __RUBBERBAND__
registerEffect<PitchShiftEffect>();
#endif
registerEffect<DistortionEffect>();
}

Expand Down
13 changes: 12 additions & 1 deletion src/engine/enginebuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include "control/controlproxy.h"
#include "control/controlpushbutton.h"
#include "engine/bufferscalers/enginebufferscalelinear.h"
#include "engine/bufferscalers/enginebufferscalerubberband.h"
#include "engine/bufferscalers/enginebufferscalest.h"
#include "engine/cachingreader/cachingreader.h"
#include "engine/channels/enginechannel.h"
Expand All @@ -34,6 +33,10 @@
#include "util/timer.h"
#include "waveform/visualplayposition.h"

#ifdef __RUBBERBAND__
#include "engine/bufferscalers/enginebufferscalerubberband.h"
#endif

#ifdef __VINYLCONTROL__
#include "engine/controls/vinylcontrolcontrol.h"
#endif
Expand Down Expand Up @@ -254,7 +257,9 @@ EngineBuffer::EngineBuffer(const QString& group,
// Construct scaling objects
m_pScaleLinear = new EngineBufferScaleLinear(m_pReadAheadManager);
m_pScaleST = new EngineBufferScaleST(m_pReadAheadManager);
#ifdef __RUBBERBAND__
m_pScaleRB = new EngineBufferScaleRubberBand(m_pReadAheadManager);
#endif
slotKeylockEngineChanged(m_pKeylockEngine->get());
m_pScaleVinyl = m_pScaleLinear;
m_pScale = m_pScaleVinyl;
Expand Down Expand Up @@ -305,7 +310,9 @@ EngineBuffer::~EngineBuffer() {

delete m_pScaleLinear;
delete m_pScaleST;
#ifdef __RUBBERBAND__
delete m_pScaleRB;
#endif

delete m_pKeylock;

Expand Down Expand Up @@ -805,6 +812,7 @@ void EngineBuffer::slotKeylockEngineChanged(double dIndex) {
case KeylockEngine::SoundTouch:
m_pScaleKeylock = m_pScaleST;
break;
#ifdef __RUBBERBAND__
case KeylockEngine::RubberBandFaster:
m_pScaleRB->useEngineFiner(false);
m_pScaleKeylock = m_pScaleRB;
Expand All @@ -814,6 +822,7 @@ void EngineBuffer::slotKeylockEngineChanged(double dIndex) {
true); // in case of Rubberband V2 it falls back to RUBBERBAND_FASTER
m_pScaleKeylock = m_pScaleRB;
break;
#endif
default:
slotKeylockEngineChanged(static_cast<double>(defaultKeylockEngine()));
break;
Expand Down Expand Up @@ -1147,7 +1156,9 @@ void EngineBuffer::process(CSAMPLE* pOutput, const int iBufferSize) {
// We do this even if rubberband is not active.
m_pScaleLinear->setSampleRate(m_sampleRate);
m_pScaleST->setSampleRate(m_sampleRate);
#ifdef __RUBBERBAND__
m_pScaleRB->setSampleRate(m_sampleRate);
#endif

bool hasStableTrack = m_pTrackLoaded->toBool() && m_iTrackLoading.loadAcquire() == 0;
if (hasStableTrack && m_pause.tryLock()) {
Expand Down
26 changes: 24 additions & 2 deletions src/engine/enginebuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

#include "audio/frame.h"
#include "control/controlvalue.h"
#include "engine/bufferscalers/enginebufferscalerubberband.h"
#include "engine/cachingreader/cachingreader.h"
#include "engine/engineobject.h"
#include "engine/slipmodestate.h"
Expand All @@ -18,6 +17,10 @@
#include "track/track_decl.h"
#include "util/types.h"

#ifdef __RUBBERBAND__
#include "engine/bufferscalers/enginebufferscalerubberband.h"
#endif

//for the writer
#ifdef __SCALER_DEBUG__
#include <QFile>
Expand Down Expand Up @@ -80,15 +83,20 @@ class EngineBuffer : public EngineObject {
// Don't remove or swap values to keep backward compatibility
enum class KeylockEngine {
SoundTouch = 0,
#ifdef __RUBBERBAND__
RubberBandFaster = 1,
RubberBandFiner = 2,
#endif
};

// intended for iteration over the KeylockEngine enum
constexpr static std::initializer_list<KeylockEngine> kKeylockEngines = {
KeylockEngine::SoundTouch,
#ifdef __RUBBERBAND__
KeylockEngine::RubberBandFaster,
KeylockEngine::RubberBandFiner};
KeylockEngine::RubberBandFiner
#endif
};

EngineBuffer(const QString& group,
UserSettingsPointer pConfig,
Expand Down Expand Up @@ -158,33 +166,45 @@ class EngineBuffer : public EngineObject {
switch (engine) {
case KeylockEngine::SoundTouch:
return tr("Soundtouch (faster)");
#ifdef __RUBBERBAND__
case KeylockEngine::RubberBandFaster:
return tr("Rubberband (better)");
case KeylockEngine::RubberBandFiner:
if (EngineBufferScaleRubberBand::isEngineFinerAvailable()) {
return tr("Rubberband R3 (near-hi-fi quality)");
}
[[fallthrough]];
#endif
default:
#ifdef __RUBBERBAND__
return tr("Unknown, using Rubberband (better)");
#else
return tr("Unknown, using Soundtouch");
#endif
}
}

static bool isKeylockEngineAvailable(KeylockEngine engine) {
switch (engine) {
case KeylockEngine::SoundTouch:
return true;
#ifdef __RUBBERBAND__
case KeylockEngine::RubberBandFaster:
return true;
case KeylockEngine::RubberBandFiner:
return EngineBufferScaleRubberBand::isEngineFinerAvailable();
#endif
default:
return false;
}
}

constexpr static KeylockEngine defaultKeylockEngine() {
#ifdef __RUBBERBAND__
return KeylockEngine::RubberBandFaster;
#else
return KeylockEngine::SoundTouch;
#endif
}

// Request that the EngineBuffer load a track. Since the process is
Expand Down Expand Up @@ -407,7 +427,9 @@ class EngineBuffer : public EngineObject {
EngineBufferScaleLinear* m_pScaleLinear;
// Objects used for pitch-indep time stretch (key lock) scaling of the audio
EngineBufferScaleST* m_pScaleST;
#ifdef __RUBBERBAND__
EngineBufferScaleRubberBand* m_pScaleRB;
#endif

// Indicates whether the scaler has changed since the last process()
bool m_bScalerChanged;
Expand Down
6 changes: 6 additions & 0 deletions src/test/enginebuffertest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ TEST_F(EngineBufferTest, PitchRoundtrip) {
ASSERT_NEAR(0.0, ControlObject::get(ConfigKey(m_sGroup1, "pitch")), 1e-10);
}

#ifdef __RUBBERBAND__
TEST_F(EngineBufferTest, SlowRubberBand) {
// At very slow speeds, RubberBand needs to reallocate buffers and since
// this
Expand Down Expand Up @@ -152,6 +153,7 @@ TEST_F(EngineBufferTest, SlowRubberBand) {
ProcessBuffer();
EXPECT_EQ(m_pMockScaleVinyl1, m_pChannel1->getEngineBuffer()->m_pScale);
}
#endif

TEST_F(EngineBufferTest, ScalerNoTransport) {
// normally use the Vinyl scaler
Expand Down Expand Up @@ -338,6 +340,7 @@ TEST_F(EngineBufferE2ETest, DISABLED_SoundTouchToggleTest) {
"SoundTouchTestRegular");
}

#ifdef __RUBBERBAND__
// DISABLED: This test is too dependent on the rubber band library version.
TEST_F(EngineBufferE2ETest, DISABLED_RubberbandToggleTest) {
// Test various cases where Rubberband toggles on and off.
Expand Down Expand Up @@ -366,6 +369,7 @@ TEST_F(EngineBufferE2ETest, DISABLED_RubberbandToggleTest) {
kProcessBufferSize,
"RubberbandTestRegular");
}
#endif

// DISABLED: This test is too dependent on the sound touch library version.
// NOTE(uklotzde, 2018-01-10): We have also seen spurious failures on the
Expand Down Expand Up @@ -417,6 +421,7 @@ TEST_F(EngineBufferE2ETest, SoundTouchReverseTest) {
// on the uses library version
}

#ifdef __RUBBERBAND__
TEST_F(EngineBufferE2ETest, RubberbandReverseTest) {
// This test must not crash when changing to reverse while pitch is tweaked
// Testing issue #8061
Expand All @@ -430,6 +435,7 @@ TEST_F(EngineBufferE2ETest, RubberbandReverseTest) {
// Note: we cannot compare a golden buffer here, because the result depends
// on the uses library version
}
#endif

TEST_F(EngineBufferE2ETest, CueGotoAndStopTest) {
// Be sure, that the Crossfade buffer is processed only once
Expand Down
7 changes: 6 additions & 1 deletion src/util/versionstore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@
#undef WIN32
#endif

#ifdef __RUBBERBAND__
#include <rubberband/RubberBandStretcher.h>
#endif

#include <FLAC/format.h>
#include <chromaprint.h>
#include <lame/lame.h>
#include <portaudio.h>
#include <rubberband/RubberBandStretcher.h>
#include <sndfile.h>
#include <soundtouch/SoundTouch.h>
#include <taglib/taglib.h>
Expand Down Expand Up @@ -160,8 +163,10 @@ QStringList VersionStore::dependencyVersions() {
<< QString("PortAudio: %1 %2")
.arg(Pa_GetVersion())
.arg(Pa_GetVersionText())
#ifdef __RUBBERBAND__
// The version of the RubberBand headers Mixxx was compiled with.
<< QString("RubberBand: %1").arg(RUBBERBAND_VERSION)
#endif
// The version of the SoundTouch headers Mixxx was compiled with.
<< QString("SoundTouch: %1").arg(SOUNDTOUCH_VERSION)
// The version of the TagLib headers Mixxx was compiled with.
Expand Down
Loading