Put binForFrequency/frequencyForBin in a common place
This commit is contained in:
56
src/common/mathmisc.h
Normal file
56
src/common/mathmisc.h
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Rubber Band Library
|
||||||
|
An audio time-stretching and pitch-shifting library.
|
||||||
|
Copyright 2007-2022 Particular Programs Ltd.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of the
|
||||||
|
License, or (at your option) any later version. See the file
|
||||||
|
COPYING included with this distribution for more information.
|
||||||
|
|
||||||
|
Alternatively, if you have a valid commercial licence for the
|
||||||
|
Rubber Band Library obtained by agreement with the copyright
|
||||||
|
holders, you may redistribute and/or modify it under the terms
|
||||||
|
described in that licence.
|
||||||
|
|
||||||
|
If you wish to distribute code using the Rubber Band Library
|
||||||
|
under terms other than those of the GNU General Public License,
|
||||||
|
you must obtain a valid commercial licence before doing so.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RUBBERBAND_MATHMISC_H
|
||||||
|
#define RUBBERBAND_MATHMISC_H
|
||||||
|
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265358979323846
|
||||||
|
#endif // M_PI
|
||||||
|
|
||||||
|
namespace RubberBand {
|
||||||
|
|
||||||
|
inline double mod(double x, double y) {
|
||||||
|
return x - (y * floor(x / y));
|
||||||
|
}
|
||||||
|
inline float modf(float x, float y) {
|
||||||
|
return x - (y * float(floor(x / y)));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double princarg(double a) {
|
||||||
|
return mod(a + M_PI, -2.0 * M_PI) + M_PI;
|
||||||
|
}
|
||||||
|
inline float princargf(float a) {
|
||||||
|
return modf(a + (float)M_PI, -2.f * (float)M_PI) + (float)M_PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int binForFrequency(double f, int fftSize, double sampleRate) {
|
||||||
|
return int(round(f * double(fftSize) / sampleRate));
|
||||||
|
}
|
||||||
|
inline double frequencyForBin(int b, int fftSize, double sampleRate) {
|
||||||
|
return (double(b) * sampleRate) / double(fftSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -92,16 +92,6 @@ struct timeval { long tv_sec; long tv_usec; };
|
|||||||
void gettimeofday(struct timeval *p, void *tz);
|
void gettimeofday(struct timeval *p, void *tz);
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
inline double mod(double x, double y) { return x - (y * floor(x / y)); }
|
|
||||||
inline float modf(float x, float y) { return x - (y * float(floor(x / y))); }
|
|
||||||
|
|
||||||
#ifndef M_PI
|
|
||||||
#define M_PI 3.14159265358979323846
|
|
||||||
#endif // M_PI
|
|
||||||
|
|
||||||
inline double princarg(double a) { return mod(a + M_PI, -2.0 * M_PI) + M_PI; }
|
|
||||||
inline float princargf(float a) { return modf(a + (float)M_PI, -2.f * (float)M_PI) + (float)M_PI; }
|
|
||||||
|
|
||||||
} // end namespace
|
} // end namespace
|
||||||
|
|
||||||
// The following should be functions in the RubberBand namespace, really
|
// The following should be functions in the RubberBand namespace, really
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "../common/Profiler.h"
|
#include "../common/Profiler.h"
|
||||||
#include "../common/VectorOps.h"
|
#include "../common/VectorOps.h"
|
||||||
#include "../common/sysutils.h"
|
#include "../common/sysutils.h"
|
||||||
|
#include "../common/mathmisc.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|||||||
@@ -25,7 +25,9 @@
|
|||||||
#define RUBBERBAND_BIN_SEGMENTER_H
|
#define RUBBERBAND_BIN_SEGMENTER_H
|
||||||
|
|
||||||
#include "BinClassifier.h"
|
#include "BinClassifier.h"
|
||||||
|
|
||||||
#include "../common/HistogramFilter.h"
|
#include "../common/HistogramFilter.h"
|
||||||
|
#include "../common/mathmisc.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -83,11 +85,12 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
*/
|
*/
|
||||||
double f0 = 0.0;
|
double f0 = 0.0;
|
||||||
for (int i = 1; i < n; ++i) {
|
for (int i = 1; i < n; ++i) {
|
||||||
if (m_numeric[i] != 1) {
|
if (m_numeric[i] != 1) {
|
||||||
f0 = frequencyForBin(i);
|
f0 = frequencyForBin
|
||||||
|
(i, m_parameters.fftSize, m_parameters.sampleRate);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,14 +105,17 @@ public:
|
|||||||
continue;
|
continue;
|
||||||
} else if (c == 1) { // percussive
|
} else if (c == 1) { // percussive
|
||||||
inPercussive = true;
|
inPercussive = true;
|
||||||
f2 = frequencyForBin(i);
|
f2 = frequencyForBin
|
||||||
|
(i, m_parameters.fftSize, m_parameters.sampleRate);
|
||||||
} else { // harmonic
|
} else { // harmonic
|
||||||
f1 = f2 = frequencyForBin(i);
|
f1 = f2 = frequencyForBin
|
||||||
|
(i, m_parameters.fftSize, m_parameters.sampleRate);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else { // inPercussive
|
} else { // inPercussive
|
||||||
if (c != 1) { // non-percussive
|
if (c != 1) { // non-percussive
|
||||||
f1 = frequencyForBin(i);
|
f1 = frequencyForBin
|
||||||
|
(i, m_parameters.fftSize, m_parameters.sampleRate);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -128,16 +134,6 @@ protected:
|
|||||||
std::vector<int> m_numeric;
|
std::vector<int> m_numeric;
|
||||||
HistogramFilter m_classFilter;
|
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(const BinSegmenter &) =delete;
|
||||||
BinSegmenter &operator=(const BinSegmenter &) =delete;
|
BinSegmenter &operator=(const BinSegmenter &) =delete;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -312,15 +312,6 @@ protected:
|
|||||||
double m_maxLower;
|
double m_maxLower;
|
||||||
double m_maxHigher;
|
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
|
// near-dupe with R2 RubberBandStretcher::Impl
|
||||||
int roundUp(int value) const {
|
int roundUp(int value) const {
|
||||||
if (value < 1) return 1;
|
if (value < 1) return 1;
|
||||||
@@ -333,7 +324,8 @@ protected:
|
|||||||
|
|
||||||
bool checkPotentialKick(const double *const magnitudes,
|
bool checkPotentialKick(const double *const magnitudes,
|
||||||
const double *const prevMagnitudes) const {
|
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;
|
double here = 0.0, there = 0.0;
|
||||||
for (int i = 1; i <= b; ++i) {
|
for (int i = 1; i <= b; ++i) {
|
||||||
here += magnitudes[i];
|
here += magnitudes[i];
|
||||||
@@ -345,7 +337,8 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
double descendToValley(double f, const double *const magnitudes) const {
|
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) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
if (magnitudes[b+1] < magnitudes[b]) {
|
if (magnitudes[b+1] < magnitudes[b]) {
|
||||||
++b;
|
++b;
|
||||||
@@ -355,7 +348,8 @@ protected:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
double sf = frequencyForBin(b);
|
double sf = frequencyForBin(b, m_configuration.classificationFftSize,
|
||||||
|
m_parameters.sampleRate);
|
||||||
return sf;
|
return sf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
|
|
||||||
#include "Guide.h"
|
#include "Guide.h"
|
||||||
|
|
||||||
|
#include "../common/mathmisc.h"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
@@ -129,8 +131,10 @@ public:
|
|||||||
m_currentPeaks[c][i] = i;
|
m_currentPeaks[c][i] = i;
|
||||||
}
|
}
|
||||||
for (const auto &band : guidance[c]->phaseLockBands) {
|
for (const auto &band : guidance[c]->phaseLockBands) {
|
||||||
int startBin = binForFrequency(band.f0);
|
int startBin = binForFrequency
|
||||||
int endBin = binForFrequency(band.f1);
|
(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;
|
if (startBin > highest || endBin < lowest) continue;
|
||||||
int count = endBin - startBin + 1;
|
int count = endBin - startBin + 1;
|
||||||
m_peakPicker.findNearestAndNextPeaks(mag[c],
|
m_peakPicker.findNearestAndNextPeaks(mag[c],
|
||||||
@@ -176,7 +180,8 @@ public:
|
|||||||
const Guide::Guidance *g = guidance[c];
|
const Guide::Guidance *g = guidance[c];
|
||||||
int phaseLockBand = 0;
|
int phaseLockBand = 0;
|
||||||
for (int i = lowest; i <= highest; ++i) {
|
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) {
|
while (f > g->phaseLockBands[phaseLockBand].f1) {
|
||||||
++phaseLockBand;
|
++phaseLockBand;
|
||||||
}
|
}
|
||||||
@@ -237,14 +242,6 @@ protected:
|
|||||||
double **m_unlocked;
|
double **m_unlocked;
|
||||||
bool m_reported;
|
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) {
|
bool inRange(double f, const Guide::Range &r) {
|
||||||
return r.present && f >= r.f0 && f < r.f1;
|
return r.present && f >= r.f0 && f < r.f1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -688,9 +688,9 @@ R3StretcherImpl::analyseChannel(int c, int inhop, int prevInhop, int prevOuthop)
|
|||||||
double pb = cd->nextSegmentation.percussiveBelow;
|
double pb = cd->nextSegmentation.percussiveBelow;
|
||||||
double pa = cd->nextSegmentation.percussiveAbove;
|
double pa = cd->nextSegmentation.percussiveAbove;
|
||||||
double ra = cd->nextSegmentation.residualAbove;
|
double ra = cd->nextSegmentation.residualAbove;
|
||||||
int pbb = binForFrequency(pb, classify);
|
int pbb = binForFrequency(pb, classify, m_parameters.sampleRate);
|
||||||
int pab = binForFrequency(pa, classify);
|
int pab = binForFrequency(pa, classify, m_parameters.sampleRate);
|
||||||
int rab = binForFrequency(ra, classify);
|
int rab = binForFrequency(ra, classify, m_parameters.sampleRate);
|
||||||
std::cout << "pb = " << pb << ", pbb = " << pbb << std::endl;
|
std::cout << "pb = " << pb << ", pbb = " << pbb << std::endl;
|
||||||
std::cout << "pa = " << pa << ", pab = " << pab << std::endl;
|
std::cout << "pa = " << pa << ", pab = " << pab << std::endl;
|
||||||
std::cout << "ra = " << ra << ", rab = " << rab << 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;
|
auto fftSize = cd->guidance.fftBands[0].fftSize;
|
||||||
if (cd->guidance.preKick.present) {
|
if (cd->guidance.preKick.present) {
|
||||||
auto &scale = cd->scales.at(fftSize);
|
auto &scale = cd->scales.at(fftSize);
|
||||||
int from = binForFrequency(cd->guidance.preKick.f0, fftSize);
|
int from = binForFrequency(cd->guidance.preKick.f0,
|
||||||
int to = binForFrequency(cd->guidance.preKick.f1, fftSize);
|
fftSize, m_parameters.sampleRate);
|
||||||
|
int to = binForFrequency(cd->guidance.preKick.f1,
|
||||||
|
fftSize, m_parameters.sampleRate);
|
||||||
for (int i = from; i <= to; ++i) {
|
for (int i = from; i <= to; ++i) {
|
||||||
double diff = scale->mag[i] - scale->prevMag[i];
|
double diff = scale->mag[i] - scale->prevMag[i];
|
||||||
if (diff > 0.0) {
|
if (diff > 0.0) {
|
||||||
@@ -815,8 +817,10 @@ R3StretcherImpl::adjustPreKick(int c)
|
|||||||
}
|
}
|
||||||
} else if (cd->guidance.kick.present) {
|
} else if (cd->guidance.kick.present) {
|
||||||
auto &scale = cd->scales.at(fftSize);
|
auto &scale = cd->scales.at(fftSize);
|
||||||
int from = binForFrequency(cd->guidance.preKick.f0, fftSize);
|
int from = binForFrequency(cd->guidance.preKick.f0,
|
||||||
int to = binForFrequency(cd->guidance.preKick.f1, fftSize);
|
fftSize, m_parameters.sampleRate);
|
||||||
|
int to = binForFrequency(cd->guidance.preKick.f1,
|
||||||
|
fftSize, m_parameters.sampleRate);
|
||||||
for (int i = from; i <= to; ++i) {
|
for (int i = from; i <= to; ++i) {
|
||||||
scale->mag[i] += scale->pendingKick[i];
|
scale->mag[i] += scale->pendingKick[i];
|
||||||
scale->pendingKick[i] = 0.0;
|
scale->pendingKick[i] = 0.0;
|
||||||
@@ -852,12 +856,9 @@ R3StretcherImpl::synthesiseChannel(int c, int outhop)
|
|||||||
// The frequency filter is applied naively in the frequency
|
// The frequency filter is applied naively in the frequency
|
||||||
// domain. Aliasing is reduced by the shorter resynthesis
|
// domain. Aliasing is reduced by the shorter resynthesis
|
||||||
// window
|
// 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 lowBin = binForFrequency(band.f0, fftSize, m_parameters.sampleRate);
|
||||||
int highBin = int(floor(fftSize * band.f1 / m_parameters.sampleRate));
|
int highBin = binForFrequency(band.f1, fftSize, m_parameters.sampleRate);
|
||||||
if (highBin % 2 == 0 && highBin > 0) --highBin;
|
if (highBin % 2 == 0 && highBin > 0) --highBin;
|
||||||
|
|
||||||
for (int i = 0; i < lowBin; ++i) {
|
for (int i = 0; i < lowBin; ++i) {
|
||||||
|
|||||||
@@ -294,16 +294,6 @@ protected:
|
|||||||
static void logCout(const std::string &message) {
|
static void logCout(const std::string &message) {
|
||||||
std::cout << "RubberBandStretcher: " << message << std::endl;
|
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);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user