Skip to content

Commit

Permalink
add rubberband engine 3 support when available at compile-time
Browse files Browse the repository at this point in the history
  • Loading branch information
Swiftb0y committed Jul 23, 2022
1 parent ea21fa5 commit a2b7152
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 19 deletions.
57 changes: 38 additions & 19 deletions src/engine/bufferscalers/enginebufferscalerubberband.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ namespace {
// This is the default increment from RubberBand 1.8.1.
size_t kRubberBandBlockSize = 256;

#define RUBBERBANDV3 (RUBBERBAND_API_MAJOR_VERSION >= 2 && RUBBERBAND_API_MINOR_VERSION >= 7)

} // namespace

EngineBufferScaleRubberBand::EngineBufferScaleRubberBand(
Expand Down Expand Up @@ -56,13 +58,15 @@ void EngineBufferScaleRubberBand::setScaleParameters(double base_rate,
// References:
// https://bugs.launchpad.net/ubuntu/+bug/1263233
// https://todo.sr.ht/~breakfastquay/rubberband/5
constexpr double kMinSeekSpeed = 1.0 / 128.0;

double speed_abs = fabs(*pTempoRatio);
if (speed_abs < kMinSeekSpeed) {
// Let the caller know we ignored their speed.
speed_abs = *pTempoRatio = 0;
if (runningEngineVersion() == 2) {
constexpr double kMinSeekSpeed = 1.0 / 128.0;
if (speed_abs < kMinSeekSpeed) {
// Let the caller know we ignored their speed.
speed_abs = *pTempoRatio = 0;
}
}

// RubberBand handles checking for whether the change in pitchScale is a
// no-op.
double pitchScale = fabs(base_rate * *pPitchRatio);
Expand All @@ -82,21 +86,22 @@ void EngineBufferScaleRubberBand::setScaleParameters(double base_rate,
m_pRubberBand->setTimeRatio(1.0 / timeRatioInverse);
}

if (m_pRubberBand->getInputIncrement() == 0) {
qWarning() << "EngineBufferScaleRubberBand inputIncrement is 0."
<< "On RubberBand <=1.8.1 a SIGFPE is imminent despite"
<< "our workaround. Taking evasive action."
<< "Please file an issue on https://github.com/mixxxdj/mixxx/issues";

// This is much slower than the minimum seek speed workaround above.
while (m_pRubberBand->getInputIncrement() == 0) {
timeRatioInverse += 0.001;
m_pRubberBand->setTimeRatio(1.0 / timeRatioInverse);
if (runningEngineVersion() == 2) {
if (m_pRubberBand->getInputIncrement() == 0) {
qWarning() << "EngineBufferScaleRubberBand inputIncrement is 0."
<< "On RubberBand <=1.8.1 a SIGFPE is imminent despite"
<< "our workaround. Taking evasive action."
<< "Please file an issue on https://github.com/mixxxdj/mixxx/issues";

// This is much slower than the minimum seek speed workaround above.
while (m_pRubberBand->getInputIncrement() == 0) {
timeRatioInverse += 0.001;
m_pRubberBand->setTimeRatio(1.0 / timeRatioInverse);
}
speed_abs = timeRatioInverse / base_rate;
*pTempoRatio = m_bBackwards ? -speed_abs : speed_abs;
}
speed_abs = timeRatioInverse / base_rate;
*pTempoRatio = m_bBackwards ? -speed_abs : speed_abs;
}

// Used by other methods so we need to keep them up to date.
m_dBaseRate = base_rate;
m_dTempoRatio = speed_abs;
Expand All @@ -111,10 +116,16 @@ void EngineBufferScaleRubberBand::onSampleRateChanged() {
m_pRubberBand.reset();
return;
}
RubberBandStretcher::Options rubberbandOptions = RubberBandStretcher::OptionProcessRealTime;
#if RUBBERBANDV3
// TODO make this a runtime option
rubberbandOptions |= RubberBandStretcher::OptionEngineFiner;
#endif

m_pRubberBand = std::make_unique<RubberBandStretcher>(
getOutputSignal().getSampleRate(),
getOutputSignal().getChannelCount(),
RubberBandStretcher::OptionProcessRealTime);
rubberbandOptions);
// TODO (XXX): we should always be able to provide rubberband as
// many samples as it wants. So remove this.
m_pRubberBand->setMaxProcessSize(kRubberBandBlockSize);
Expand Down Expand Up @@ -252,3 +263,11 @@ double EngineBufferScaleRubberBand::scaleBuffer(

return framesRead;
}

int EngineBufferScaleRubberBand::runningEngineVersion() {
#if RUBBERBANDV3
return m_pRubberBand->getEngineVersion();
#else
return 2;
#endif
}
2 changes: 2 additions & 0 deletions src/engine/bufferscalers/enginebufferscalerubberband.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class EngineBufferScaleRubberBand : public EngineBufferScale {
// Reset RubberBand library with new audio signal
void onSampleRateChanged() override;

int runningEngineVersion();

void deinterleaveAndProcess(const CSAMPLE* pBuffer, SINT frames, bool flush);
SINT retrieveAndDeinterleave(CSAMPLE* pBuffer, SINT frames);

Expand Down

0 comments on commit a2b7152

Please sign in to comment.