Skip to content

Commit

Permalink
Refactor linear scaler to use SampleUtil
Browse files Browse the repository at this point in the history
Signed-off-by: Antoine C <[email protected]>
  • Loading branch information
acolombier committed Jun 9, 2024
1 parent ccd8a22 commit f340b1b
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 32 deletions.
51 changes: 20 additions & 31 deletions src/engine/bufferscalers/enginebufferscalelinear.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ EngineBufferScaleLinear::~EngineBufferScaleLinear() {
}

void EngineBufferScaleLinear::onSignalChanged() {
m_floorSampleOld.resize(getOutputSignal().getChannelCount());
std::fill(m_floorSampleOld.begin(), m_floorSampleOld.end(), 0.0);
m_floorSampleOld = mixxx::SampleBuffer(getOutputSignal().getChannelCount());
m_floorSample = mixxx::SampleBuffer(getOutputSignal().getChannelCount());
m_ceilSample = mixxx::SampleBuffer(getOutputSignal().getChannelCount());
}

void EngineBufferScaleLinear::setScaleParameters(double base_rate,
Expand Down Expand Up @@ -90,9 +91,7 @@ double EngineBufferScaleLinear::scaleBuffer(
SINT iNextSample = getOutputSignal().frames2samples(static_cast<SINT>(ceil(m_dNextFrame)));
int chCount = getOutputSignal().getChannelCount();
if (iNextSample + chCount <= m_bufferIntSize) {
for (int chIdx = 0; chIdx < chCount; chIdx++) {
m_floorSampleOld[chIdx] = m_bufferInt[iNextSample + chIdx];
}
SampleUtil::copy(m_floorSampleOld.data(), &m_bufferInt[iNextSample], chCount);
}

// if the buffer has extra samples, do a read so RAMAN ends up back where
Expand Down Expand Up @@ -229,11 +228,8 @@ double EngineBufferScaleLinear::do_scale(CSAMPLE* buf, SINT buf_size) {
m_dNextFrame - floor(m_dNextFrame));

int chCount = getOutputSignal().getChannelCount();
std::vector<CSAMPLE> floorSample(chCount);
std::vector<CSAMPLE> ceilSample(chCount);

std::fill(floorSample.begin(), floorSample.end(), 0.0);
std::fill(ceilSample.begin(), ceilSample.end(), 0.0);
m_floorSample.clear();
m_ceilSample.clear();

double startFrame = m_dNextFrame;
SINT i = 0;
Expand Down Expand Up @@ -261,24 +257,18 @@ double EngineBufferScaleLinear::do_scale(CSAMPLE* buf, SINT buf_size) {
// we have advanced to a new buffer in the previous run,
// but the floor still points to the old buffer
// so take the cached sample, this happens on slow rates
for (int chIdx = 0; chIdx < chCount; chIdx++) {
floorSample[chIdx] = m_floorSampleOld[chIdx];
ceilSample[chIdx] = m_bufferInt[chIdx];
}
SampleUtil::copy(m_floorSample.data(), m_floorSampleOld.data(), chCount);
SampleUtil::copy(m_ceilSample.data(), m_bufferInt, chCount);
} else if (sampleCount + 2 * chCount - 1 < m_bufferIntSize) {
// take floorSample form the buffer of the previous run
for (int chIdx = 0; chIdx < chCount; chIdx++) {
floorSample[chIdx] = m_bufferInt[sampleCount + chIdx];
ceilSample[chIdx] = m_bufferInt[sampleCount + chCount + chIdx];
}
SampleUtil::copy(m_floorSample.data(), &m_bufferInt[sampleCount], chCount);
SampleUtil::copy(m_ceilSample.data(), &m_bufferInt[sampleCount + chCount], chCount);
} else {
// if we don't have the ceilSample in buffer, load some more

if (sampleCount + chCount - 1 < m_bufferIntSize) {
// take floorSample form the buffer of the previous run
for (int chIdx = 0; chIdx < chCount; chIdx++) {
floorSample[chIdx] = m_bufferInt[sampleCount + chIdx];
}
SampleUtil::copy(m_floorSample.data(), &m_bufferInt[sampleCount], chCount);
}

do {
Expand Down Expand Up @@ -312,15 +302,13 @@ double EngineBufferScaleLinear::do_scale(CSAMPLE* buf, SINT buf_size) {
sampleCount = getOutputSignal().frames2samples(currentFrameFloor);
} while (sampleCount + 2 * chCount - 1 >= m_bufferIntSize);

for (int chIdx = 0; chIdx < chCount; chIdx++) {
// Now that the buffer is up to date, we can get the value of the sample
// at the floor of our position.
if (currentFrameFloor >= 0) {
// the previous position is in the new buffer
floorSample[chIdx] = m_bufferInt[sampleCount + chIdx];
}
ceilSample[chIdx] = m_bufferInt[sampleCount + chCount + chIdx];
// Now that the buffer is up to date, we can get the value of the sample
// at the floor of our position.
if (currentFrameFloor >= 0) {
// the previous position is in the new buffer
SampleUtil::copy(m_floorSample.data(), &m_bufferInt[sampleCount], chCount);
}
SampleUtil::copy(m_ceilSample.data(), &m_bufferInt[sampleCount + chCount], chCount);
}

// For the current index, what percentage is it
Expand All @@ -329,10 +317,11 @@ double EngineBufferScaleLinear::do_scale(CSAMPLE* buf, SINT buf_size) {

// Perform linear interpolation
for (int chIdx = 0; chIdx < chCount; chIdx++) {
buf[i + chIdx] = floorSample[chIdx] + frac * (ceilSample[chIdx] - floorSample[chIdx]);
buf[i + chIdx] = m_floorSample[chIdx] +
frac * (m_ceilSample[chIdx] - m_floorSample[chIdx]);
}

m_floorSampleOld = floorSample;
m_floorSampleOld.swap(m_floorSample);

// increment the index for the next loop
m_dNextFrame = m_dCurrentFrame + rate_add;
Expand Down
5 changes: 4 additions & 1 deletion src/engine/bufferscalers/enginebufferscalelinear.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "engine/bufferscalers/enginebufferscale.h"
#include "util/samplebuffer.h"

class ReadAheadManager;

Expand Down Expand Up @@ -36,7 +37,9 @@ class EngineBufferScaleLinear : public EngineBufferScale {
CSAMPLE* m_bufferInt;
SINT m_bufferIntSize;

std::vector<CSAMPLE> m_floorSampleOld;
mixxx::SampleBuffer m_floorSampleOld;
mixxx::SampleBuffer m_floorSample;
mixxx::SampleBuffer m_ceilSample;

bool m_bClear;
double m_dRate;
Expand Down

0 comments on commit f340b1b

Please sign in to comment.