From 4c878340dfa15d27f9bc6f07af9fb2d05c04f085 Mon Sep 17 00:00:00 2001 From: Chris Cannam Date: Wed, 25 May 2022 16:24:51 +0100 Subject: [PATCH 1/2] This is a little faster, and I can't tell the difference at first listen, nor think of a good reason why it should be worse. To be tested. --- src/finer/PhaseAdvance.h | 36 +++++++----------------------------- 1 file changed, 7 insertions(+), 29 deletions(-) diff --git a/src/finer/PhaseAdvance.h b/src/finer/PhaseAdvance.h index 69e2df8..fc3a479 100644 --- a/src/finer/PhaseAdvance.h +++ b/src/finer/PhaseAdvance.h @@ -127,27 +127,10 @@ public: nullptr); } - m_peakPicker.findNearestAndNextPeaks(m_prevInMag[c], - lowest, highest - lowest + 1, - 2, m_prevPeaks[c], - nullptr); - -/* - static int counter = 0; - if (c == 0) { - if (++counter > 140 && counter < 150) { - std::cout << "Magnitudes and peaks (fftSize = " << m_parameters.fftSize << "):" << std::endl; - for (int i = 0; i < bs; ++i) { - if (m_currentPeaks[c][i] == i) { - std::cout << "*"; - } - std::cout << mag[c][i] << ", "; - } - std::cout << std::endl; - } - } -*/ - +// m_peakPicker.findNearestAndNextPeaks(m_prevInMag[c], +// lowest, highest - lowest + 1, +// 2, m_prevPeaks[c], +// nullptr); } if (channels > 1) { @@ -230,15 +213,10 @@ public: m_prevOutPhase[c][i] = outPhase[c][i]; } } - - //!!! NB in the original we use a different value of p for - //!!! peak-picking the prior magnitudes - this isn't carried - //!!! over here - it is now but I don't think this was the - //!!! full cause of our burbling -// int **tmp = m_prevPeaks; -// m_prevPeaks = m_currentPeaks; -// m_currentPeaks = tmp; + int **tmp = m_prevPeaks; + m_prevPeaks = m_currentPeaks; + m_currentPeaks = tmp; } protected: From fa004562f718179ba2ce49e64b89ec439c0865a9 Mon Sep 17 00:00:00 2001 From: Chris Cannam Date: Wed, 25 May 2022 16:25:03 +0100 Subject: [PATCH 2/2] Tidy, and format comments --- src/finer/PhaseAdvance.h | 27 +++++++++++-------- src/finer/R3StretcherImpl.cpp | 51 +++++++++++++++++------------------ 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/src/finer/PhaseAdvance.h b/src/finer/PhaseAdvance.h index fc3a479..624cfa0 100644 --- a/src/finer/PhaseAdvance.h +++ b/src/finer/PhaseAdvance.h @@ -48,18 +48,23 @@ public: GuidedPhaseAdvance(Parameters parameters) : m_parameters(parameters), - m_blockSize(parameters.fftSize / 2 + 1), - m_peakPicker(m_blockSize), + m_binCount(parameters.fftSize / 2 + 1), + m_peakPicker(m_binCount), m_reported(false) { size_t ch = m_parameters.channels; - m_currentPeaks = allocate_and_zero_channels(ch, m_blockSize); - m_prevPeaks = allocate_and_zero_channels(ch, m_blockSize); - m_greatestChannel = allocate_and_zero(m_blockSize); - //!!! there is also a prevMag in R3StretcherImpl which could be passed in to here instead - m_prevInMag = allocate_and_zero_channels(ch, m_blockSize); - m_prevInPhase = allocate_and_zero_channels(ch, m_blockSize); - m_prevOutPhase = allocate_and_zero_channels(ch, m_blockSize); - m_unlocked = allocate_and_zero_channels(ch, m_blockSize); + m_currentPeaks = allocate_and_zero_channels(ch, m_binCount); + m_prevPeaks = allocate_and_zero_channels(ch, m_binCount); + m_greatestChannel = allocate_and_zero(m_binCount); + m_prevInMag = allocate_and_zero_channels(ch, m_binCount); + m_prevInPhase = allocate_and_zero_channels(ch, m_binCount); + m_prevOutPhase = allocate_and_zero_channels(ch, m_binCount); + m_unlocked = allocate_and_zero_channels(ch, m_binCount); + + for (int c = 0; c < ch; ++c) { + for (int i = 0; i < m_binCount; ++i) { + m_prevPeaks[c][i] = i; + } + } } ~GuidedPhaseAdvance() { @@ -221,7 +226,7 @@ public: protected: Parameters m_parameters; - int m_blockSize; + int m_binCount; Peak m_peakPicker; int **m_currentPeaks; int **m_prevPeaks; diff --git a/src/finer/R3StretcherImpl.cpp b/src/finer/R3StretcherImpl.cpp index d637064..9a1e66e 100644 --- a/src/finer/R3StretcherImpl.cpp +++ b/src/finer/R3StretcherImpl.cpp @@ -371,12 +371,12 @@ R3StretcherImpl::analyseChannel(int c, int inhop, int prevOuthop) cd->inbuf->peek(buf, longest); } - // We have a single unwindowed frame at the longest FFT - // size ("scale"). Populate the shorter FFT sizes from the - // centre of it, windowing as we copy. The classification - // scale is handled separately because it has readahead, - // so skip it here as well as the longest. (In practice - // this means we are probably only populating one scale) + // We have a single unwindowed frame at the longest FFT size + // ("scale"). Populate the shorter FFT sizes from the centre of + // it, windowing as we copy. The classification scale is handled + // separately because it has readahead, so skip it here as well as + // the longest. (In practice this means we are probably only + // populating one scale) for (auto &it: cd->scales) { int fftSize = it.first; @@ -406,10 +406,9 @@ R3StretcherImpl::analyseChannel(int c, int inhop, int prevOuthop) // FFT shift, forward FFT, and carry out cartesian-polar // conversion for each FFT size. - // For the classification scale we need magnitudes for the - // full range (polar only in a subset) and we operate in - // the readahead, pulling current values from the existing - // readahead + // For the classification scale we need magnitudes for the full + // range (polar only in a subset) and we operate in the readahead, + // pulling current values from the existing readahead v_fftshift(readahead.timeDomain.data(), classify); @@ -455,8 +454,8 @@ R3StretcherImpl::analyseChannel(int c, int inhop, int prevOuthop) } } - // For the others we operate directly in the scale data - // and restrict the range for cartesian-polar conversion + // For the others we operate directly in the scale data and + // restrict the range for cartesian-polar conversion for (auto &it: cd->scales) { int fftSize = it.first; @@ -485,9 +484,8 @@ R3StretcherImpl::analyseChannel(int c, int inhop, int prevOuthop) } } - // Use the classification scale to get a bin segmentation - // and calculate the adaptive frequency guide for this - // channel + // Use the classification scale to get a bin segmentation and + // calculate the adaptive frequency guide for this channel cd->prevSegmentation = cd->segmentation; cd->segmentation = cd->nextSegmentation; cd->nextSegmentation = cd->segmenter->segment(readahead.mag.data()); @@ -541,9 +539,9 @@ R3StretcherImpl::synthesiseChannel(int c, int outhop) } winscale = double(outhop) / winscale; - // The frequency filter is applied naively in the - // frequency domain. Aliasing is reduced by the - // shorter resynthesis window + // The frequency filter is applied naively in the frequency + // domain. Aliasing is reduced by the shorter resynthesis + // window double factor = m_parameters.sampleRate / double(fftSize); for (int i = 0; i < fftSize/2 + 1; ++i) { @@ -557,9 +555,9 @@ R3StretcherImpl::synthesiseChannel(int c, int outhop) } } - // Resynthesise each FFT size (scale) individually, then - // sum. This is easier to manage scaling for in situations - // with a varying resynthesis hop + // Resynthesise each FFT size (scale) individually, then sum. This + // is easier to manage scaling for in situations with a varying + // resynthesis hop for (auto &it : cd->scales) { int fftSize = it.first; @@ -587,12 +585,11 @@ R3StretcherImpl::synthesiseChannel(int c, int outhop) v_fftshift(scale->timeDomain.data(), fftSize); - // Synthesis window is shorter than analysis window, - // so copy and cut only from the middle of the - // time-domain frame; and the accumulator length - // always matches the longest FFT size, so as to make - // mixing straightforward, so there is an additional - // offset needed for the target + // Synthesis window may be shorter than analysis window, so + // copy and cut only from the middle of the time-domain frame; + // and the accumulator length always matches the longest FFT + // size, so as to make mixing straightforward, so there is an + // additional offset needed for the target int synthesisWindowSize = scaleData->synthesisWindow.getSize(); int fromOffset = (fftSize - synthesisWindowSize) / 2;