Pull out per-channel analysis and resynthesis functions

This commit is contained in:
Chris Cannam
2022-05-25 11:26:16 +01:00
parent 47476b9088
commit f5b381e086
2 changed files with 279 additions and 265 deletions

View File

@@ -179,9 +179,7 @@ void
R3StretcherImpl::consume()
{
double ratio = getEffectiveRatio();
int longest = m_guideConfiguration.longestFftSize;
int classify = m_guideConfiguration.classificationFftSize;
m_calculator->setDebugLevel(3);
@@ -194,11 +192,14 @@ R3StretcherImpl::consume()
std::cout << "outhop = " << outhop << std::endl;
double instantaneousRatio = double(m_prevOuthop) / double(m_inhop);
m_prevOuthop = outhop;
while (m_channelData.at(0)->outbuf->getWriteSpace() >= outhop) {
// NB our ChannelData, ScaleData, and ChannelScaleData maps
// contain shared_ptrs; whenever we retain one of them in a
// variable, we do so by reference to avoid copying the
// shared_ptr (as that is not realtime safe). Same goes for
// the map iterators
int readSpace = m_channelData.at(0)->inbuf->getReadSpace();
if (readSpace < longest) {
if (m_draining) {
@@ -210,20 +211,54 @@ R3StretcherImpl::consume()
}
}
// Analysis. This is per channel
// Analysis
for (int c = 0; c < m_parameters.channels; ++c) {
analyseChannel(c, m_prevOuthop);
}
// Our ChannelData, ScaleData, and ChannelScaleData maps
// contain shared_ptrs; whenever we retain one of them in
// a variable here, we do so by reference to avoid copying
// the shared_ptr (as that is not realtime safe). Same
// goes for the map iterators
// Phase update. This is synchronised across all channels
for (auto &it : m_channelData[0]->scales) {
int fftSize = it.first;
for (int c = 0; c < m_parameters.channels; ++c) {
auto &cd = m_channelData.at(c);
auto &scale = cd->scales.at(fftSize);
m_channelAssembly.mag[c] = scale->mag.data();
m_channelAssembly.phase[c] = scale->phase.data();
m_channelAssembly.guidance[c] = &cd->guidance;
m_channelAssembly.outPhase[c] = scale->advancedPhase.data();
}
m_scaleData.at(fftSize)->guided.advance
(m_channelAssembly.outPhase.data(),
m_channelAssembly.mag.data(),
m_channelAssembly.phase.data(),
m_guideConfiguration,
m_channelAssembly.guidance.data(),
m_inhop,
outhop);
}
// Resynthesis
for (int c = 0; c < m_parameters.channels; ++c) {
synthesiseChannel(c, outhop);
}
}
m_prevOuthop = outhop;
}
void
R3StretcherImpl::analyseChannel(int c, int prevOuthop)
{
int longest = m_guideConfiguration.longestFftSize;
int classify = m_guideConfiguration.classificationFftSize;
auto &cd = m_channelData.at(c);
auto &longestScale = cd->scales.at(longest);
double *buf = longestScale->timeDomain.data();
double *buf = cd->scales.at(longest)->timeDomain.data();
int readSpace = cd->inbuf->getReadSpace();
if (readSpace < longest) {
cd->inbuf->peek(buf, readSpace);
v_zero(buf + readSpace, longest - readSpace);
@@ -354,6 +389,7 @@ R3StretcherImpl::consume()
(classifyScale->mag.data(), 3, nullptr,
classifyScale->troughs.data());
double instantaneousRatio = double(prevOuthop) / double(m_inhop);
m_guide.calculate(instantaneousRatio,
classifyScale->mag.data(),
classifyScale->troughs.data(),
@@ -364,31 +400,10 @@ R3StretcherImpl::consume()
cd->guidance);
}
// Phase update. This is synchronised across all channels
for (auto &it : m_channelData[0]->scales) {
int fftSize = it.first;
for (int c = 0; c < m_parameters.channels; ++c) {
auto &cd = m_channelData.at(c);
auto &classifyScale = cd->scales.at(fftSize);
m_channelAssembly.mag[c] = classifyScale->mag.data();
m_channelAssembly.phase[c] = classifyScale->phase.data();
m_channelAssembly.guidance[c] = &cd->guidance;
m_channelAssembly.outPhase[c] = classifyScale->advancedPhase.data();
}
m_scaleData.at(fftSize)->guided.advance
(m_channelAssembly.outPhase.data(),
m_channelAssembly.mag.data(),
m_channelAssembly.phase.data(),
m_guideConfiguration,
m_channelAssembly.guidance.data(),
m_inhop,
outhop);
}
// Resynthesis. This is per channel
for (int c = 0; c < m_parameters.channels; ++c) {
void
R3StretcherImpl::synthesiseChannel(int c, int outhop)
{
int longest = m_guideConfiguration.longestFftSize;
auto &cd = m_channelData.at(c);
@@ -474,8 +489,7 @@ R3StretcherImpl::consume()
int synthesisWindowSize = scaleData->synthesisWindow.getSize();
int fromOffset = (fftSize - synthesisWindowSize) / 2;
int toOffset = (m_guideConfiguration.longestFftSize -
synthesisWindowSize) / 2;
int toOffset = (longest - synthesisWindowSize) / 2;
scaleData->synthesisWindow.cutAndAdd
(scale->timeDomain.data() + fromOffset,
@@ -504,6 +518,7 @@ R3StretcherImpl::consume()
v_zero(accptr + n, outhop);
}
int readSpace = cd->inbuf->getReadSpace();
if (readSpace < m_inhop) {
// This should happen only when draining
cd->inbuf->skip(readSpace);
@@ -511,9 +526,6 @@ R3StretcherImpl::consume()
cd->inbuf->skip(m_inhop);
}
}
}
}
}

View File

@@ -248,6 +248,8 @@ protected:
void consume();
void calculateHop();
void analyseChannel(int channel, int prevOuthop);
void synthesiseChannel(int channel, int outhop);
double getEffectiveRatio() const {
return m_timeRatio * m_pitchScale;