Put binForFrequency/frequencyForBin in a common place

This commit is contained in:
Chris Cannam
2022-06-13 10:08:05 +01:00
parent 05fb611544
commit 182e2b0e3b
8 changed files with 95 additions and 70 deletions

View File

@@ -25,7 +25,9 @@
#define RUBBERBAND_BIN_SEGMENTER_H
#include "BinClassifier.h"
#include "../common/HistogramFilter.h"
#include "../common/mathmisc.h"
#include <vector>
@@ -83,11 +85,12 @@ public:
}
}
std::cout << std::endl;
*/
*/
double f0 = 0.0;
for (int i = 1; i < n; ++i) {
if (m_numeric[i] != 1) {
f0 = frequencyForBin(i);
f0 = frequencyForBin
(i, m_parameters.fftSize, m_parameters.sampleRate);
break;
}
}
@@ -102,14 +105,17 @@ public:
continue;
} else if (c == 1) { // percussive
inPercussive = true;
f2 = frequencyForBin(i);
f2 = frequencyForBin
(i, m_parameters.fftSize, m_parameters.sampleRate);
} else { // harmonic
f1 = f2 = frequencyForBin(i);
f1 = f2 = frequencyForBin
(i, m_parameters.fftSize, m_parameters.sampleRate);
break;
}
} else { // inPercussive
if (c != 1) { // non-percussive
f1 = frequencyForBin(i);
f1 = frequencyForBin
(i, m_parameters.fftSize, m_parameters.sampleRate);
break;
}
}
@@ -128,16 +134,6 @@ protected:
std::vector<int> m_numeric;
HistogramFilter m_classFilter;
//!!! dupes
int binForFrequency(double f) const {
return int(round(f * double(m_parameters.fftSize) /
m_parameters.sampleRate));
}
double frequencyForBin(int b) const {
return (double(b) * m_parameters.sampleRate)
/ double(m_parameters.fftSize);
}
BinSegmenter(const BinSegmenter &) =delete;
BinSegmenter &operator=(const BinSegmenter &) =delete;
};

View File

@@ -312,15 +312,6 @@ protected:
double m_maxLower;
double m_maxHigher;
int binForFrequency(double f) const {
return int(round(f * double(m_configuration.classificationFftSize) /
m_parameters.sampleRate));
}
double frequencyForBin(int b) const {
return (double(b) * m_parameters.sampleRate)
/ double(m_configuration.classificationFftSize);
}
// near-dupe with R2 RubberBandStretcher::Impl
int roundUp(int value) const {
if (value < 1) return 1;
@@ -333,7 +324,8 @@ protected:
bool checkPotentialKick(const double *const magnitudes,
const double *const prevMagnitudes) const {
int b = binForFrequency(200.0);
int b = binForFrequency(200.0, m_configuration.classificationFftSize,
m_parameters.sampleRate);
double here = 0.0, there = 0.0;
for (int i = 1; i <= b; ++i) {
here += magnitudes[i];
@@ -345,7 +337,8 @@ protected:
}
double descendToValley(double f, const double *const magnitudes) const {
int b = binForFrequency(f);
int b = binForFrequency(f, m_configuration.classificationFftSize,
m_parameters.sampleRate);
for (int i = 0; i < 3; ++i) {
if (magnitudes[b+1] < magnitudes[b]) {
++b;
@@ -355,7 +348,8 @@ protected:
break;
}
}
double sf = frequencyForBin(b);
double sf = frequencyForBin(b, m_configuration.classificationFftSize,
m_parameters.sampleRate);
return sf;
}

View File

@@ -26,6 +26,8 @@
#include "Guide.h"
#include "../common/mathmisc.h"
#include <sstream>
#include <functional>
@@ -129,8 +131,10 @@ public:
m_currentPeaks[c][i] = i;
}
for (const auto &band : guidance[c]->phaseLockBands) {
int startBin = binForFrequency(band.f0);
int endBin = binForFrequency(band.f1);
int startBin = binForFrequency
(band.f0, m_parameters.fftSize, m_parameters.sampleRate);
int endBin = binForFrequency
(band.f1, m_parameters.fftSize, m_parameters.sampleRate);
if (startBin > highest || endBin < lowest) continue;
int count = endBin - startBin + 1;
m_peakPicker.findNearestAndNextPeaks(mag[c],
@@ -176,7 +180,8 @@ public:
const Guide::Guidance *g = guidance[c];
int phaseLockBand = 0;
for (int i = lowest; i <= highest; ++i) {
double f = frequencyForBin(i);
double f = frequencyForBin
(i, m_parameters.fftSize, m_parameters.sampleRate);
while (f > g->phaseLockBands[phaseLockBand].f1) {
++phaseLockBand;
}
@@ -237,14 +242,6 @@ protected:
double **m_unlocked;
bool m_reported;
int binForFrequency(double f) const {
return int(round(f * double(m_parameters.fftSize) /
m_parameters.sampleRate));
}
double frequencyForBin(int b) const {
return (double(b) * m_parameters.sampleRate)
/ double(m_parameters.fftSize);
}
bool inRange(double f, const Guide::Range &r) {
return r.present && f >= r.f0 && f < r.f1;
}

View File

@@ -688,9 +688,9 @@ R3StretcherImpl::analyseChannel(int c, int inhop, int prevInhop, int prevOuthop)
double pb = cd->nextSegmentation.percussiveBelow;
double pa = cd->nextSegmentation.percussiveAbove;
double ra = cd->nextSegmentation.residualAbove;
int pbb = binForFrequency(pb, classify);
int pab = binForFrequency(pa, classify);
int rab = binForFrequency(ra, classify);
int pbb = binForFrequency(pb, classify, m_parameters.sampleRate);
int pab = binForFrequency(pa, classify, m_parameters.sampleRate);
int rab = binForFrequency(ra, classify, m_parameters.sampleRate);
std::cout << "pb = " << pb << ", pbb = " << pbb << std::endl;
std::cout << "pa = " << pa << ", pab = " << pab << std::endl;
std::cout << "ra = " << ra << ", rab = " << rab << std::endl;
@@ -804,8 +804,10 @@ R3StretcherImpl::adjustPreKick(int c)
auto fftSize = cd->guidance.fftBands[0].fftSize;
if (cd->guidance.preKick.present) {
auto &scale = cd->scales.at(fftSize);
int from = binForFrequency(cd->guidance.preKick.f0, fftSize);
int to = binForFrequency(cd->guidance.preKick.f1, fftSize);
int from = binForFrequency(cd->guidance.preKick.f0,
fftSize, m_parameters.sampleRate);
int to = binForFrequency(cd->guidance.preKick.f1,
fftSize, m_parameters.sampleRate);
for (int i = from; i <= to; ++i) {
double diff = scale->mag[i] - scale->prevMag[i];
if (diff > 0.0) {
@@ -815,8 +817,10 @@ R3StretcherImpl::adjustPreKick(int c)
}
} else if (cd->guidance.kick.present) {
auto &scale = cd->scales.at(fftSize);
int from = binForFrequency(cd->guidance.preKick.f0, fftSize);
int to = binForFrequency(cd->guidance.preKick.f1, fftSize);
int from = binForFrequency(cd->guidance.preKick.f0,
fftSize, m_parameters.sampleRate);
int to = binForFrequency(cd->guidance.preKick.f1,
fftSize, m_parameters.sampleRate);
for (int i = from; i <= to; ++i) {
scale->mag[i] += scale->pendingKick[i];
scale->pendingKick[i] = 0.0;
@@ -852,12 +856,9 @@ R3StretcherImpl::synthesiseChannel(int c, int outhop)
// The frequency filter is applied naively in the frequency
// domain. Aliasing is reduced by the shorter resynthesis
// window
//!!! I don't think we have binForFrequency etc available in
//!!! this class - really that's ridiculous
int lowBin = int(floor(fftSize * band.f0 / m_parameters.sampleRate));
int highBin = int(floor(fftSize * band.f1 / m_parameters.sampleRate));
int lowBin = binForFrequency(band.f0, fftSize, m_parameters.sampleRate);
int highBin = binForFrequency(band.f1, fftSize, m_parameters.sampleRate);
if (highBin % 2 == 0 && highBin > 0) --highBin;
for (int i = 0; i < lowBin; ++i) {

View File

@@ -294,16 +294,6 @@ protected:
static void logCout(const std::string &message) {
std::cout << "RubberBandStretcher: " << message << std::endl;
}
//!!! dupes
int binForFrequency(double f, int fftSize) const {
return int(round(f * double(fftSize) /
m_parameters.sampleRate));
}
double frequencyForBin(int b, int fftSize) const {
return (double(b) * m_parameters.sampleRate)
/ double(fftSize);
}
};
}