Merge from branch midside3

This commit is contained in:
Chris Cannam
2023-03-20 10:08:20 +00:00
3 changed files with 56 additions and 3 deletions

View File

@@ -94,6 +94,7 @@ public:
const process_t *const *prevMag, const process_t *const *prevMag,
const Guide::Configuration &configuration, const Guide::Configuration &configuration,
const Guide::Guidance *const *guidance, const Guide::Guidance *const *guidance,
bool usingMidSide,
int inhop, int inhop,
int outhop) { int outhop) {
@@ -197,6 +198,9 @@ public:
process_t ph = 0.0; process_t ph = 0.0;
if (inRange(f, g->phaseReset) || inRange(f, g->kick)) { if (inRange(f, g->phaseReset) || inRange(f, g->kick)) {
ph = phase[c][i]; ph = phase[c][i];
} else if (usingMidSide && channels == 2 &&
c == 0 && inRange(f, guidance[1]->phaseReset)) {
ph = phase[c][i];
} else if (inhop == outhop) { } else if (inhop == outhop) {
ph = m_unlocked[c][i]; ph = m_unlocked[c][i];
} else if (inRange (f, g->highUnlocked)) { } else if (inRange (f, g->highUnlocked)) {

View File

@@ -757,11 +757,13 @@ R3Stretcher::process(const float *const *input, size_t samples, bool final)
int maxResampleInput = int(floor(maxResampleOutput * m_pitchScale)); int maxResampleInput = int(floor(maxResampleOutput * m_pitchScale));
int resampleInput = std::min(remaining, maxResampleInput); int resampleInput = std::min(remaining, maxResampleInput);
if (resampleInput == 0) resampleInput = 1; if (resampleInput == 0) resampleInput = 1;
prepareInput(input, inputIx, resampleInput);
int resampleOutput = m_resampler->resample int resampleOutput = m_resampler->resample
(m_channelAssembly.resampled.data(), (m_channelAssembly.resampled.data(),
maxResampleOutput, maxResampleOutput,
input, m_channelAssembly.input.data(),
resampleInput, resampleInput,
1.0 / m_pitchScale, 1.0 / m_pitchScale,
final); final);
@@ -781,8 +783,11 @@ R3Stretcher::process(const float *const *input, size_t samples, bool final)
m_log.log(2, "process: resamplingBefore is false, writing to inbuf from supplied data, former read space and samples being added", m_channelData[0]->inbuf->getReadSpace(), toWrite); m_log.log(2, "process: resamplingBefore is false, writing to inbuf from supplied data, former read space and samples being added", m_channelData[0]->inbuf->getReadSpace(), toWrite);
prepareInput(input, inputIx, toWrite);
for (int c = 0; c < m_parameters.channels; ++c) { for (int c = 0; c < m_parameters.channels; ++c) {
m_channelData[c]->inbuf->write(input[c] + inputIx, toWrite); m_channelData[c]->inbuf->write
(m_channelAssembly.input[c], toWrite);
} }
inputIx += toWrite; inputIx += toWrite;
} }
@@ -819,9 +824,43 @@ R3Stretcher::retrieve(float *const *output, size_t samples) const
} }
} }
if (useMidSide()) {
for (int i = 0; i < got; ++i) {
float m = output[0][i];
float s = output[1][i];
float l = m + s;
float r = m - s;
output[0][i] = l;
output[1][i] = r;
}
}
return got; return got;
} }
void
R3Stretcher::prepareInput(const float *const *input, int ix, int n)
{
if (useMidSide()) {
auto &c0 = m_channelData.at(0)->mixdown;
auto &c1 = m_channelData.at(1)->mixdown;
for (int i = 0; i < n; ++i) {
float l = input[0][i + ix];
float r = input[1][i + ix];
float m = (l + r) / 2.f;
float s = (l - r) / 2.f;
c0[i] = m;
c1[i] = s;
}
m_channelAssembly.input[0] = m_channelData.at(0)->mixdown.data();
m_channelAssembly.input[1] = m_channelData.at(1)->mixdown.data();
} else {
for (int c = 0; c < m_parameters.channels; ++c) {
m_channelAssembly.input[c] = input[c] + ix;
}
}
}
void void
R3Stretcher::consume() R3Stretcher::consume()
{ {
@@ -933,6 +972,7 @@ R3Stretcher::consume()
m_channelAssembly.prevMag.data(), m_channelAssembly.prevMag.data(),
m_guideConfiguration, m_guideConfiguration,
m_channelAssembly.guidance.data(), m_channelAssembly.guidance.data(),
useMidSide(),
m_prevInhop, m_prevInhop,
m_prevOuthop); m_prevOuthop);
} }

View File

@@ -241,7 +241,7 @@ protected:
BinClassifier::Classification::Residual), BinClassifier::Classification::Residual),
segmenter(new BinSegmenter(segmenterParameters)), segmenter(new BinSegmenter(segmenterParameters)),
segmentation(), prevSegmentation(), nextSegmentation(), segmentation(), prevSegmentation(), nextSegmentation(),
mixdown(longestFftSize, 0.f), mixdown(inRingBufferSize, 0.f),
resampled(outRingBufferSize, 0.f), resampled(outRingBufferSize, 0.f),
inbuf(new RingBuffer<float>(inRingBufferSize)), inbuf(new RingBuffer<float>(inRingBufferSize)),
outbuf(new RingBuffer<float>(outRingBufferSize)), outbuf(new RingBuffer<float>(outRingBufferSize)),
@@ -263,6 +263,7 @@ protected:
struct ChannelAssembly { struct ChannelAssembly {
// Vectors of bare pointers, used to package container data // Vectors of bare pointers, used to package container data
// from different channels into arguments for PhaseAdvance // from different channels into arguments for PhaseAdvance
FixedVector<const float *> input;
FixedVector<process_t *> mag; FixedVector<process_t *> mag;
FixedVector<process_t *> phase; FixedVector<process_t *> phase;
FixedVector<process_t *> prevMag; FixedVector<process_t *> prevMag;
@@ -271,6 +272,7 @@ protected:
FixedVector<float *> mixdown; FixedVector<float *> mixdown;
FixedVector<float *> resampled; FixedVector<float *> resampled;
ChannelAssembly(int channels) : ChannelAssembly(int channels) :
input(channels, nullptr),
mag(channels, nullptr), phase(channels, nullptr), mag(channels, nullptr), phase(channels, nullptr),
prevMag(channels, nullptr), guidance(channels, nullptr), prevMag(channels, nullptr), guidance(channels, nullptr),
outPhase(channels, nullptr), mixdown(channels, nullptr), outPhase(channels, nullptr), mixdown(channels, nullptr),
@@ -350,6 +352,7 @@ protected:
}; };
ProcessMode m_mode; ProcessMode m_mode;
void prepareInput(const float *const *input, int ix, int n);
void consume(); void consume();
void createResampler(); void createResampler();
void calculateHop(); void calculateHop();
@@ -469,6 +472,12 @@ protected:
} }
} }
bool useMidSide() const {
return m_parameters.channels == 2 &&
(m_parameters.options &
RubberBandStretcher::OptionChannelsTogether);
}
bool isSingleWindowed() const { bool isSingleWindowed() const {
return m_parameters.options & return m_parameters.options &
RubberBandStretcher::OptionWindowShort; RubberBandStretcher::OptionWindowShort;