pixel column counts and sample window sizes use unsigned types
This commit is contained in:
parent
b910bf63da
commit
ed21545c80
108
src/FFT.cpp
108
src/FFT.cpp
|
@ -50,15 +50,12 @@
|
|||
#include "Experimental.h"
|
||||
|
||||
static int **gFFTBitTable = NULL;
|
||||
static const int MaxFastBits = 16;
|
||||
static const size_t MaxFastBits = 16;
|
||||
|
||||
/* Declare Static functions */
|
||||
static int IsPowerOfTwo(int x);
|
||||
static int NumberOfBitsNeeded(int PowerOfTwo);
|
||||
static int ReverseBits(int index, int NumBits);
|
||||
static void InitFFT();
|
||||
|
||||
int IsPowerOfTwo(int x)
|
||||
static bool IsPowerOfTwo(size_t x)
|
||||
{
|
||||
if (x < 2)
|
||||
return false;
|
||||
|
@ -69,23 +66,23 @@ int IsPowerOfTwo(int x)
|
|||
return true;
|
||||
}
|
||||
|
||||
int NumberOfBitsNeeded(int PowerOfTwo)
|
||||
static size_t NumberOfBitsNeeded(size_t PowerOfTwo)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (PowerOfTwo < 2) {
|
||||
fprintf(stderr, "Error: FFT called with size %d\n", PowerOfTwo);
|
||||
fprintf(stderr, "Error: FFT called with size %ld\n", PowerOfTwo);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i = 0;; i++)
|
||||
if (PowerOfTwo & (1 << i))
|
||||
return i;
|
||||
size_t i = 0;
|
||||
while (PowerOfTwo > 1)
|
||||
PowerOfTwo >>= 1, ++i;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int ReverseBits(int index, int NumBits)
|
||||
int ReverseBits(size_t index, size_t NumBits)
|
||||
{
|
||||
int i, rev;
|
||||
size_t i, rev;
|
||||
|
||||
for (i = rev = 0; i < NumBits; i++) {
|
||||
rev = (rev << 1) | (index & 1);
|
||||
|
@ -99,12 +96,12 @@ void InitFFT()
|
|||
{
|
||||
gFFTBitTable = new int *[MaxFastBits];
|
||||
|
||||
int len = 2;
|
||||
for (int b = 1; b <= MaxFastBits; b++) {
|
||||
size_t len = 2;
|
||||
for (size_t b = 1; b <= MaxFastBits; b++) {
|
||||
|
||||
gFFTBitTable[b - 1] = new int[len];
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
for (size_t i = 0; i < len; i++)
|
||||
gFFTBitTable[b - 1][i] = ReverseBits(i, b);
|
||||
|
||||
len <<= 1;
|
||||
|
@ -114,7 +111,7 @@ void InitFFT()
|
|||
void DeinitFFT()
|
||||
{
|
||||
if (gFFTBitTable) {
|
||||
for (int b = 1; b <= MaxFastBits; b++) {
|
||||
for (size_t b = 1; b <= MaxFastBits; b++) {
|
||||
delete[] gFFTBitTable[b-1];
|
||||
}
|
||||
delete[] gFFTBitTable;
|
||||
|
@ -123,7 +120,7 @@ void DeinitFFT()
|
|||
CleanupFFT();
|
||||
}
|
||||
|
||||
inline int FastReverseBits(int i, int NumBits)
|
||||
static inline size_t FastReverseBits(size_t i, size_t NumBits)
|
||||
{
|
||||
if (NumBits <= MaxFastBits)
|
||||
return gFFTBitTable[NumBits - 1][i];
|
||||
|
@ -135,20 +132,16 @@ inline int FastReverseBits(int i, int NumBits)
|
|||
* Complex Fast Fourier Transform
|
||||
*/
|
||||
|
||||
void FFT(int NumSamples,
|
||||
void FFT(size_t NumSamples,
|
||||
bool InverseTransform,
|
||||
const float *RealIn, const float *ImagIn,
|
||||
float *RealOut, float *ImagOut)
|
||||
{
|
||||
int NumBits; /* Number of bits needed to store indices */
|
||||
int i, j, k, n;
|
||||
int BlockSize, BlockEnd;
|
||||
|
||||
double angle_numerator = 2.0 * M_PI;
|
||||
double tr, ti; /* temp real, temp imaginary */
|
||||
|
||||
if (!IsPowerOfTwo(NumSamples)) {
|
||||
fprintf(stderr, "%d is not a power of two\n", NumSamples);
|
||||
fprintf(stderr, "%ld is not a power of two\n", NumSamples);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -158,14 +151,15 @@ void FFT(int NumSamples,
|
|||
if (!InverseTransform)
|
||||
angle_numerator = -angle_numerator;
|
||||
|
||||
NumBits = NumberOfBitsNeeded(NumSamples);
|
||||
/* Number of bits needed to store indices */
|
||||
auto NumBits = NumberOfBitsNeeded(NumSamples);
|
||||
|
||||
/*
|
||||
** Do simultaneous data copy and bit-reversal ordering into outputs...
|
||||
*/
|
||||
|
||||
for (i = 0; i < NumSamples; i++) {
|
||||
j = FastReverseBits(i, NumBits);
|
||||
for (size_t i = 0; i < NumSamples; i++) {
|
||||
auto j = FastReverseBits(i, NumBits);
|
||||
RealOut[j] = RealIn[i];
|
||||
ImagOut[j] = (ImagIn == NULL) ? 0.0 : ImagIn[i];
|
||||
}
|
||||
|
@ -174,8 +168,8 @@ void FFT(int NumSamples,
|
|||
** Do the FFT itself...
|
||||
*/
|
||||
|
||||
BlockEnd = 1;
|
||||
for (BlockSize = 2; BlockSize <= NumSamples; BlockSize <<= 1) {
|
||||
size_t BlockEnd = 1;
|
||||
for (size_t BlockSize = 2; BlockSize <= NumSamples; BlockSize <<= 1) {
|
||||
|
||||
double delta_angle = angle_numerator / (double) BlockSize;
|
||||
|
||||
|
@ -186,14 +180,14 @@ void FFT(int NumSamples,
|
|||
double w = 2 * cm1;
|
||||
double ar0, ar1, ar2, ai0, ai1, ai2;
|
||||
|
||||
for (i = 0; i < NumSamples; i += BlockSize) {
|
||||
for (size_t i = 0; i < NumSamples; i += BlockSize) {
|
||||
ar2 = cm2;
|
||||
ar1 = cm1;
|
||||
|
||||
ai2 = sm2;
|
||||
ai1 = sm1;
|
||||
|
||||
for (j = i, n = 0; n < BlockEnd; j++, n++) {
|
||||
for (size_t j = i, n = 0; n < BlockEnd; j++, n++) {
|
||||
ar0 = w * ar1 - ar2;
|
||||
ar2 = ar1;
|
||||
ar1 = ar0;
|
||||
|
@ -202,7 +196,7 @@ void FFT(int NumSamples,
|
|||
ai2 = ai1;
|
||||
ai1 = ai0;
|
||||
|
||||
k = j + BlockEnd;
|
||||
size_t k = j + BlockEnd;
|
||||
tr = ar0 * RealOut[k] - ai0 * ImagOut[k];
|
||||
ti = ar0 * ImagOut[k] + ai0 * RealOut[k];
|
||||
|
||||
|
@ -224,7 +218,7 @@ void FFT(int NumSamples,
|
|||
if (InverseTransform) {
|
||||
float denom = (float) NumSamples;
|
||||
|
||||
for (i = 0; i < NumSamples; i++) {
|
||||
for (size_t i = 0; i < NumSamples; i++) {
|
||||
RealOut[i] /= denom;
|
||||
ImagOut[i] /= denom;
|
||||
}
|
||||
|
@ -237,20 +231,20 @@ void FFT(int NumSamples,
|
|||
* This is merely a wrapper of RealFFTf() from RealFFTf.h.
|
||||
*/
|
||||
|
||||
void RealFFT(int NumSamples, const float *RealIn, float *RealOut, float *ImagOut)
|
||||
void RealFFT(size_t NumSamples, const float *RealIn, float *RealOut, float *ImagOut)
|
||||
{
|
||||
int i;
|
||||
size_t i;
|
||||
HFFT hFFT = GetFFT(NumSamples);
|
||||
float *pFFT = new float[NumSamples];
|
||||
// Copy the data into the processing buffer
|
||||
for(i=0; i<NumSamples; i++)
|
||||
for(i = 0; i < NumSamples; i++)
|
||||
pFFT[i] = RealIn[i];
|
||||
|
||||
// Perform the FFT
|
||||
RealFFTf(pFFT, hFFT);
|
||||
|
||||
// Copy the data into the real and imaginary outputs
|
||||
for(i=1;i<(NumSamples/2);i++) {
|
||||
for(i = 1; i < (NumSamples / 2); i++) {
|
||||
RealOut[i]=pFFT[hFFT->BitReversed[i] ];
|
||||
ImagOut[i]=pFFT[hFFT->BitReversed[i]+1];
|
||||
}
|
||||
|
@ -259,7 +253,7 @@ void RealFFT(int NumSamples, const float *RealIn, float *RealOut, float *ImagOut
|
|||
RealOut[i] = pFFT[1];
|
||||
ImagOut[0] = ImagOut[i] = 0;
|
||||
// Fill in the upper half using symmetry properties
|
||||
for(i++ ; i<NumSamples; i++) {
|
||||
for(i++ ; i < NumSamples; i++) {
|
||||
RealOut[i] = RealOut[NumSamples-i];
|
||||
ImagOut[i] = -ImagOut[NumSamples-i];
|
||||
}
|
||||
|
@ -278,20 +272,20 @@ void RealFFT(int NumSamples, const float *RealIn, float *RealOut, float *ImagOut
|
|||
*
|
||||
* This is merely a wrapper of InverseRealFFTf() from RealFFTf.h.
|
||||
*/
|
||||
void InverseRealFFT(int NumSamples, const float *RealIn, const float *ImagIn,
|
||||
void InverseRealFFT(size_t NumSamples, const float *RealIn, const float *ImagIn,
|
||||
float *RealOut)
|
||||
{
|
||||
int i;
|
||||
size_t i;
|
||||
HFFT hFFT = GetFFT(NumSamples);
|
||||
float *pFFT = new float[NumSamples];
|
||||
// Copy the data into the processing buffer
|
||||
for(i=0; i<(NumSamples/2); i++)
|
||||
for(i = 0; i < (NumSamples / 2); i++)
|
||||
pFFT[2*i ] = RealIn[i];
|
||||
if(ImagIn == NULL) {
|
||||
for(i=0; i<(NumSamples/2); i++)
|
||||
for(i = 0; i < (NumSamples/2); i++)
|
||||
pFFT[2*i+1] = 0;
|
||||
} else {
|
||||
for(i=0; i<(NumSamples/2); i++)
|
||||
for(i = 0; i < (NumSamples/2); i++)
|
||||
pFFT[2*i+1] = ImagIn[i];
|
||||
}
|
||||
// Put the fs/2 component in the imaginary part of the DC bin
|
||||
|
@ -318,20 +312,20 @@ void InverseRealFFT(int NumSamples, const float *RealIn, const float *ImagIn,
|
|||
* of its code.
|
||||
*/
|
||||
|
||||
void PowerSpectrum(int NumSamples, const float *In, float *Out)
|
||||
void PowerSpectrum(size_t NumSamples, const float *In, float *Out)
|
||||
{
|
||||
int i;
|
||||
size_t i;
|
||||
HFFT hFFT = GetFFT(NumSamples);
|
||||
float *pFFT = new float[NumSamples];
|
||||
// Copy the data into the processing buffer
|
||||
for(i=0; i<NumSamples; i++)
|
||||
for(i = 0; i < NumSamples; i++)
|
||||
pFFT[i] = In[i];
|
||||
|
||||
// Perform the FFT
|
||||
RealFFTf(pFFT, hFFT);
|
||||
|
||||
// Copy the data into the real and imaginary outputs
|
||||
for(i=1;i<NumSamples/2;i++) {
|
||||
for(i = 1; i < NumSamples / 2; i++) {
|
||||
Out[i]= (pFFT[hFFT->BitReversed[i] ]*pFFT[hFFT->BitReversed[i] ])
|
||||
+ (pFFT[hFFT->BitReversed[i]+1]*pFFT[hFFT->BitReversed[i]+1]);
|
||||
}
|
||||
|
@ -378,10 +372,13 @@ const wxChar *WindowFuncName(int whichFunction)
|
|||
}
|
||||
}
|
||||
|
||||
void NewWindowFunc(int whichFunction, int NumSamples, bool extraSample, float *in)
|
||||
void NewWindowFunc(int whichFunction, size_t NumSamples, bool extraSample, float *in)
|
||||
{
|
||||
if (extraSample)
|
||||
if (extraSample) {
|
||||
wxASSERT(NumSamples > 0);
|
||||
--NumSamples;
|
||||
}
|
||||
wxASSERT(NumSamples > 0);
|
||||
|
||||
switch (whichFunction) {
|
||||
default:
|
||||
|
@ -519,7 +516,7 @@ void NewWindowFunc(int whichFunction, int NumSamples, bool extraSample, float *i
|
|||
}
|
||||
|
||||
// See cautions in FFT.h !
|
||||
void WindowFunc(int whichFunction, int NumSamples, float *in)
|
||||
void WindowFunc(int whichFunction, size_t NumSamples, float *in)
|
||||
{
|
||||
bool extraSample = false;
|
||||
switch (whichFunction)
|
||||
|
@ -542,12 +539,13 @@ void WindowFunc(int whichFunction, int NumSamples, float *in)
|
|||
NewWindowFunc(whichFunction, NumSamples, extraSample, in);
|
||||
}
|
||||
|
||||
void DerivativeOfWindowFunc(int whichFunction, int NumSamples, bool extraSample, float *in)
|
||||
void DerivativeOfWindowFunc(int whichFunction, size_t NumSamples, bool extraSample, float *in)
|
||||
{
|
||||
if (eWinFuncRectangular == whichFunction)
|
||||
{
|
||||
// Rectangular
|
||||
// There are deltas at the ends
|
||||
wxASSERT(NumSamples > 0);
|
||||
--NumSamples;
|
||||
// in[0] *= 1.0f;
|
||||
for (int ii = 1; ii < NumSamples; ++ii)
|
||||
|
@ -556,8 +554,12 @@ void DerivativeOfWindowFunc(int whichFunction, int NumSamples, bool extraSample,
|
|||
return;
|
||||
}
|
||||
|
||||
if (extraSample)
|
||||
if (extraSample) {
|
||||
wxASSERT(NumSamples > 0);
|
||||
--NumSamples;
|
||||
}
|
||||
|
||||
wxASSERT(NumSamples > 0);
|
||||
|
||||
double A;
|
||||
switch (whichFunction) {
|
||||
|
|
14
src/FFT.h
14
src/FFT.h
|
@ -61,7 +61,7 @@
|
|||
* input array, and that NumSamples must be a power of two.
|
||||
*/
|
||||
|
||||
void PowerSpectrum(int NumSamples, const float *In, float *Out);
|
||||
void PowerSpectrum(size_t NumSamples, const float *In, float *Out);
|
||||
|
||||
/*
|
||||
* Computes an FFT when the input data is real but you still
|
||||
|
@ -70,7 +70,7 @@ void PowerSpectrum(int NumSamples, const float *In, float *Out);
|
|||
* NumSamples must be a power of two.
|
||||
*/
|
||||
|
||||
void RealFFT(int NumSamples,
|
||||
void RealFFT(size_t NumSamples,
|
||||
const float *RealIn, float *RealOut, float *ImagOut);
|
||||
|
||||
/*
|
||||
|
@ -78,7 +78,7 @@ void RealFFT(int NumSamples,
|
|||
* so the output is purely real. NumSamples must be a power of
|
||||
* two.
|
||||
*/
|
||||
void InverseRealFFT(int NumSamples,
|
||||
void InverseRealFFT(size_t NumSamples,
|
||||
const float *RealIn, const float *ImagIn, float *RealOut);
|
||||
|
||||
/*
|
||||
|
@ -87,7 +87,7 @@ void InverseRealFFT(int NumSamples,
|
|||
* inverse transform as well.
|
||||
*/
|
||||
|
||||
void FFT(int NumSamples,
|
||||
void FFT(size_t NumSamples,
|
||||
bool InverseTransform,
|
||||
const float *RealIn, const float *ImagIn, float *RealOut, float *ImagOut);
|
||||
|
||||
|
@ -115,7 +115,7 @@ enum eWindowFunctions
|
|||
eWinFuncCount
|
||||
};
|
||||
|
||||
void WindowFunc(int whichFunction, int NumSamples, float *data);
|
||||
void WindowFunc(int whichFunction, size_t NumSamples, float *data);
|
||||
|
||||
/*
|
||||
* Multiply values in data by values of the chosen function
|
||||
|
@ -123,7 +123,7 @@ void WindowFunc(int whichFunction, int NumSamples, float *data);
|
|||
* otherwise about (NumSamples - 1) / 2
|
||||
* All functions have 0 in data[0] except Rectangular, Hamming and Gaussians
|
||||
*/
|
||||
void NewWindowFunc(int whichFunction, int NumSamples, bool extraSample, float *data);
|
||||
void NewWindowFunc(int whichFunction, size_t NumSamples, bool extraSample, float *data);
|
||||
|
||||
/*
|
||||
* Multiply values in data by derivative of the chosen function, assuming
|
||||
|
@ -132,7 +132,7 @@ void NewWindowFunc(int whichFunction, int NumSamples, bool extraSample, float *d
|
|||
* otherwise about (NumSamples - 1) / 2
|
||||
* All functions have 0 in data[0] except Rectangular, Hamming and Gaussians
|
||||
*/
|
||||
void DerivativeOfWindowFunc(int whichFunction, int NumSamples, bool extraSample, float *data);
|
||||
void DerivativeOfWindowFunc(int whichFunction, size_t NumSamples, bool extraSample, float *data);
|
||||
|
||||
/*
|
||||
* Returns the name of the windowing function (for UI display)
|
||||
|
|
|
@ -584,7 +584,7 @@ void FreqWindow::GetAudio()
|
|||
auto start = track->TimeToLongSamples(p->mViewInfo.selectedRegion.t0());
|
||||
float *buffer2 = new float[mDataLen];
|
||||
track->Get((samplePtr)buffer2, floatSample, start, mDataLen);
|
||||
for (int i = 0; i < mDataLen; i++)
|
||||
for (size_t i = 0; i < mDataLen; i++)
|
||||
mData[i] += buffer2[i];
|
||||
delete[] buffer2;
|
||||
}
|
||||
|
@ -1169,8 +1169,8 @@ void FreqGauge::Reset()
|
|||
}
|
||||
|
||||
bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc,
|
||||
int windowSize, double rate,
|
||||
const float *data, int dataLen,
|
||||
size_t windowSize, double rate,
|
||||
const float *data, size_t dataLen,
|
||||
float *pYMin, float *pYMax,
|
||||
FreqGauge *progress)
|
||||
{
|
||||
|
@ -1198,7 +1198,7 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc,
|
|||
mWindowSize = windowSize;
|
||||
mAlg = alg;
|
||||
|
||||
int half = mWindowSize / 2;
|
||||
auto half = mWindowSize / 2;
|
||||
mProcessed.resize(mWindowSize);
|
||||
|
||||
float *in = new float[mWindowSize];
|
||||
|
@ -1206,7 +1206,7 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc,
|
|||
float *out2 = new float[mWindowSize];
|
||||
float *win = new float[mWindowSize];
|
||||
|
||||
for (int i = 0; i < mWindowSize; i++) {
|
||||
for (size_t i = 0; i < mWindowSize; i++) {
|
||||
mProcessed[i] = 0.0f;
|
||||
win[i] = 1.0f;
|
||||
}
|
||||
|
@ -1216,7 +1216,7 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc,
|
|||
// Scale window such that an amplitude of 1.0 in the time domain
|
||||
// shows an amplitude of 0dB in the frequency domain
|
||||
double wss = 0;
|
||||
for(int i=0; i<mWindowSize; i++)
|
||||
for(size_t i = 0; i < mWindowSize; i++)
|
||||
wss += win[i];
|
||||
if(wss > 0)
|
||||
wss = 4.0 / (wss*wss);
|
||||
|
@ -1227,17 +1227,17 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc,
|
|||
progress->SetRange(dataLen);
|
||||
}
|
||||
|
||||
int start = 0;
|
||||
size_t start = 0;
|
||||
int windows = 0;
|
||||
while (start + mWindowSize <= dataLen) {
|
||||
for (int i = 0; i < mWindowSize; i++)
|
||||
for (size_t i = 0; i < mWindowSize; i++)
|
||||
in[i] = win[i] * data[start + i];
|
||||
|
||||
switch (alg) {
|
||||
case Spectrum:
|
||||
PowerSpectrum(mWindowSize, in, out);
|
||||
|
||||
for (int i = 0; i < half; i++)
|
||||
for (size_t i = 0; i < half; i++)
|
||||
mProcessed[i] += out[i];
|
||||
break;
|
||||
|
||||
|
@ -1248,11 +1248,11 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc,
|
|||
// Take FFT
|
||||
RealFFT(mWindowSize, in, out, out2);
|
||||
// Compute power
|
||||
for (int i = 0; i < mWindowSize; i++)
|
||||
for (size_t i = 0; i < mWindowSize; i++)
|
||||
in[i] = (out[i] * out[i]) + (out2[i] * out2[i]);
|
||||
|
||||
if (alg == Autocorrelation) {
|
||||
for (int i = 0; i < mWindowSize; i++)
|
||||
for (size_t i = 0; i < mWindowSize; i++)
|
||||
in[i] = sqrt(in[i]);
|
||||
}
|
||||
if (alg == CubeRootAutocorrelation ||
|
||||
|
@ -1260,14 +1260,14 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc,
|
|||
// Tolonen and Karjalainen recommend taking the cube root
|
||||
// of the power, instead of the square root
|
||||
|
||||
for (int i = 0; i < mWindowSize; i++)
|
||||
for (size_t i = 0; i < mWindowSize; i++)
|
||||
in[i] = pow(in[i], 1.0f / 3.0f);
|
||||
}
|
||||
// Take FFT
|
||||
RealFFT(mWindowSize, in, out, out2);
|
||||
|
||||
// Take real part of result
|
||||
for (int i = 0; i < half; i++)
|
||||
for (size_t i = 0; i < half; i++)
|
||||
mProcessed[i] += out[i];
|
||||
break;
|
||||
|
||||
|
@ -1278,7 +1278,7 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc,
|
|||
{
|
||||
float power;
|
||||
float minpower = 1e-20*mWindowSize*mWindowSize;
|
||||
for (int i = 0; i < mWindowSize; i++)
|
||||
for (size_t i = 0; i < mWindowSize; i++)
|
||||
{
|
||||
power = (out[i] * out[i]) + (out2[i] * out2[i]);
|
||||
if(power < minpower)
|
||||
|
@ -1290,7 +1290,7 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc,
|
|||
InverseRealFFT(mWindowSize, in, NULL, out);
|
||||
|
||||
// Take real part of result
|
||||
for (int i = 0; i < half; i++)
|
||||
for (size_t i = 0; i < half; i++)
|
||||
mProcessed[i] += out[i];
|
||||
}
|
||||
|
||||
|
@ -1323,7 +1323,7 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc,
|
|||
mYMin = 1000000.;
|
||||
mYMax = -1000000.;
|
||||
scale = wss / (double)windows;
|
||||
for (int i = 0; i < half; i++)
|
||||
for (size_t i = 0; i < half; i++)
|
||||
{
|
||||
mProcessed[i] = 10 * log10(mProcessed[i] * scale);
|
||||
if(mProcessed[i] > mYMax)
|
||||
|
@ -1335,13 +1335,13 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc,
|
|||
|
||||
case Autocorrelation:
|
||||
case CubeRootAutocorrelation:
|
||||
for (int i = 0; i < half; i++)
|
||||
for (size_t i = 0; i < half; i++)
|
||||
mProcessed[i] = mProcessed[i] / windows;
|
||||
|
||||
// Find min/max
|
||||
mYMin = mProcessed[0];
|
||||
mYMax = mProcessed[0];
|
||||
for (int i = 1; i < half; i++)
|
||||
for (size_t i = 1; i < half; i++)
|
||||
if (mProcessed[i] > mYMax)
|
||||
mYMax = mProcessed[i];
|
||||
else if (mProcessed[i] < mYMin)
|
||||
|
@ -1349,13 +1349,13 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc,
|
|||
break;
|
||||
|
||||
case EnhancedAutocorrelation:
|
||||
for (int i = 0; i < half; i++)
|
||||
for (size_t i = 0; i < half; i++)
|
||||
mProcessed[i] = mProcessed[i] / windows;
|
||||
|
||||
// Peak Pruning as described by Tolonen and Karjalainen, 2000
|
||||
|
||||
// Clip at zero, copy to temp array
|
||||
for (int i = 0; i < half; i++) {
|
||||
for (size_t i = 0; i < half; i++) {
|
||||
if (mProcessed[i] < 0.0)
|
||||
mProcessed[i] = float(0.0);
|
||||
out[i] = mProcessed[i];
|
||||
|
@ -1363,21 +1363,21 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc,
|
|||
|
||||
// Subtract a time-doubled signal (linearly interp.) from the original
|
||||
// (clipped) signal
|
||||
for (int i = 0; i < half; i++)
|
||||
for (size_t i = 0; i < half; i++)
|
||||
if ((i % 2) == 0)
|
||||
mProcessed[i] -= out[i / 2];
|
||||
else
|
||||
mProcessed[i] -= ((out[i / 2] + out[i / 2 + 1]) / 2);
|
||||
|
||||
// Clip at zero again
|
||||
for (int i = 0; i < half; i++)
|
||||
for (size_t i = 0; i < half; i++)
|
||||
if (mProcessed[i] < 0.0)
|
||||
mProcessed[i] = float(0.0);
|
||||
|
||||
// Find NEW min/max
|
||||
mYMin = mProcessed[0];
|
||||
mYMax = mProcessed[0];
|
||||
for (int i = 1; i < half; i++)
|
||||
for (size_t i = 1; i < half; i++)
|
||||
if (mProcessed[i] > mYMax)
|
||||
mYMax = mProcessed[i];
|
||||
else if (mProcessed[i] < mYMin)
|
||||
|
@ -1385,15 +1385,15 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc,
|
|||
break;
|
||||
|
||||
case Cepstrum:
|
||||
for (int i = 0; i < half; i++)
|
||||
for (size_t i = 0; i < half; i++)
|
||||
mProcessed[i] = mProcessed[i] / windows;
|
||||
|
||||
// Find min/max, ignoring first and last few values
|
||||
{
|
||||
int ignore = 4;
|
||||
size_t ignore = 4;
|
||||
mYMin = mProcessed[ignore];
|
||||
mYMax = mProcessed[ignore];
|
||||
for (int i = ignore + 1; i < half - ignore; i++)
|
||||
for (size_t i = ignore + 1; i + ignore < half; i++)
|
||||
if (mProcessed[i] > mYMax)
|
||||
mYMax = mProcessed[i];
|
||||
else if (mProcessed[i] < mYMin)
|
||||
|
|
|
@ -62,8 +62,8 @@ public:
|
|||
// Return true iff successful
|
||||
bool Calculate(Algorithm alg,
|
||||
int windowFunc, // see FFT.h for values
|
||||
int windowSize, double rate,
|
||||
const float *data, int dataLen,
|
||||
size_t windowSize, double rate,
|
||||
const float *data, size_t dataLen,
|
||||
float *pYMin = NULL, float *pYMax = NULL, // outputs
|
||||
FreqGauge *progress = NULL);
|
||||
|
||||
|
@ -80,7 +80,7 @@ private:
|
|||
private:
|
||||
Algorithm mAlg;
|
||||
double mRate;
|
||||
int mWindowSize;
|
||||
size_t mWindowSize;
|
||||
std::vector<float> mProcessed;
|
||||
};
|
||||
|
||||
|
@ -199,9 +199,9 @@ private:
|
|||
|
||||
|
||||
double mRate;
|
||||
int mDataLen;
|
||||
size_t mDataLen;
|
||||
float *mData;
|
||||
int mWindowSize;
|
||||
size_t mWindowSize;
|
||||
|
||||
bool mLogAxis;
|
||||
float mYMin;
|
||||
|
|
140
src/RealFFTf.cpp
140
src/RealFFTf.cpp
|
@ -54,11 +54,9 @@
|
|||
* Initialize the Sine table and Twiddle pointers (bit-reversed pointers)
|
||||
* for the FFT routine.
|
||||
*/
|
||||
HFFT InitializeFFT(int fftlen)
|
||||
HFFT InitializeFFT(size_t fftlen)
|
||||
{
|
||||
int i;
|
||||
int temp;
|
||||
int mask;
|
||||
HFFT h;
|
||||
|
||||
if((h=(HFFT)malloc(sizeof(FFTParam)))==NULL)
|
||||
|
@ -71,7 +69,7 @@ HFFT InitializeFFT(int fftlen)
|
|||
* The full FFT output can be reconstructed from this FFT's output.
|
||||
* (This optimization can be made since the data is real.)
|
||||
*/
|
||||
h->Points = fftlen/2;
|
||||
h->Points = fftlen / 2;
|
||||
|
||||
if((h->SinTable=(fft_type *)malloc(2*h->Points*sizeof(fft_type)))==NULL)
|
||||
{
|
||||
|
@ -85,16 +83,16 @@ HFFT InitializeFFT(int fftlen)
|
|||
exit(8);
|
||||
}
|
||||
|
||||
for(i=0;i<h->Points;i++)
|
||||
for(size_t i = 0; i < h->Points; i++)
|
||||
{
|
||||
temp=0;
|
||||
for(mask=h->Points/2;mask>0;mask >>= 1)
|
||||
temp=(temp >> 1) + (i&mask ? h->Points : 0);
|
||||
temp = 0;
|
||||
for(size_t mask = h->Points / 2; mask > 0; mask >>= 1)
|
||||
temp = (temp >> 1) + (i & mask ? h->Points : 0);
|
||||
|
||||
h->BitReversed[i]=temp;
|
||||
h->BitReversed[i] = temp;
|
||||
}
|
||||
|
||||
for(i=0;i<h->Points;i++)
|
||||
for(size_t i = 0; i < h->Points; i++)
|
||||
{
|
||||
h->SinTable[h->BitReversed[i] ]=(fft_type)-sin(2*M_PI*i/(2*h->Points));
|
||||
h->SinTable[h->BitReversed[i]+1]=(fft_type)-cos(2*M_PI*i/(2*h->Points));
|
||||
|
@ -102,9 +100,9 @@ HFFT InitializeFFT(int fftlen)
|
|||
|
||||
#ifdef EXPERIMENTAL_EQ_SSE_THREADED
|
||||
// NEW SSE FFT routines work on live data
|
||||
for(i=0;i<32;i++)
|
||||
if((1<<i)&fftlen)
|
||||
h->pow2Bits=i;
|
||||
for(size_t i = 0; i < 32; i++)
|
||||
if((1 << i) & fftlen)
|
||||
h->pow2Bits = i;
|
||||
#endif
|
||||
|
||||
return h;
|
||||
|
@ -115,25 +113,29 @@ HFFT InitializeFFT(int fftlen)
|
|||
*/
|
||||
void EndFFT(HFFT h)
|
||||
{
|
||||
if(h->Points>0) {
|
||||
if(h->Points > 0) {
|
||||
free(h->BitReversed);
|
||||
free(h->SinTable);
|
||||
}
|
||||
h->Points=0;
|
||||
h->Points = 0;
|
||||
free(h);
|
||||
}
|
||||
|
||||
#define MAX_HFFT 10
|
||||
enum : size_t { MAX_HFFT = 10 };
|
||||
static HFFT hFFTArray[MAX_HFFT] = { NULL };
|
||||
static int nFFTLockCount[MAX_HFFT] = { 0 };
|
||||
|
||||
/* Get a handle to the FFT tables of the desired length */
|
||||
/* This version keeps common tables rather than allocating a NEW table every time */
|
||||
HFFT GetFFT(int fftlen)
|
||||
HFFT GetFFT(size_t fftlen)
|
||||
{
|
||||
int h,n = fftlen/2;
|
||||
for(h=0; (h<MAX_HFFT) && (hFFTArray[h] != NULL) && (n != hFFTArray[h]->Points); h++);
|
||||
if(h<MAX_HFFT) {
|
||||
size_t h = 0;
|
||||
auto n = fftlen/2;
|
||||
for(;
|
||||
(h < MAX_HFFT) && (hFFTArray[h] != NULL) && (n != hFFTArray[h]->Points);
|
||||
h++)
|
||||
;
|
||||
if(h < MAX_HFFT) {
|
||||
if(hFFTArray[h] == NULL) {
|
||||
hFFTArray[h] = InitializeFFT(fftlen);
|
||||
nFFTLockCount[h] = 0;
|
||||
|
@ -142,7 +144,7 @@ HFFT GetFFT(int fftlen)
|
|||
return hFFTArray[h];
|
||||
} else {
|
||||
// All buffers used, so fall back to allocating a NEW set of tables
|
||||
return InitializeFFT(fftlen);;
|
||||
return InitializeFFT(fftlen);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,7 +199,7 @@ void RealFFTf(fft_type *buffer,HFFT h)
|
|||
fft_type HRplus,HRminus,HIplus,HIminus;
|
||||
fft_type v1,v2,sin,cos;
|
||||
|
||||
int ButterfliesPerGroup=h->Points/2;
|
||||
auto ButterfliesPerGroup = h->Points/2;
|
||||
|
||||
/*
|
||||
* Butterfly:
|
||||
|
@ -207,37 +209,37 @@ void RealFFTf(fft_type *buffer,HFFT h)
|
|||
* Bin-----Bout
|
||||
*/
|
||||
|
||||
endptr1=buffer+h->Points*2;
|
||||
endptr1 = buffer + h->Points * 2;
|
||||
|
||||
while(ButterfliesPerGroup>0)
|
||||
while(ButterfliesPerGroup > 0)
|
||||
{
|
||||
A=buffer;
|
||||
B=buffer+ButterfliesPerGroup*2;
|
||||
sptr=h->SinTable;
|
||||
A = buffer;
|
||||
B = buffer + ButterfliesPerGroup * 2;
|
||||
sptr = h->SinTable;
|
||||
|
||||
while(A<endptr1)
|
||||
while(A < endptr1)
|
||||
{
|
||||
sin=*sptr;
|
||||
cos=*(sptr+1);
|
||||
endptr2=B;
|
||||
while(A<endptr2)
|
||||
sin = *sptr;
|
||||
cos = *(sptr+1);
|
||||
endptr2 = B;
|
||||
while(A < endptr2)
|
||||
{
|
||||
v1=*B*cos + *(B+1)*sin;
|
||||
v2=*B*sin - *(B+1)*cos;
|
||||
*B=(*A+v1);
|
||||
*(A++)=*(B++)-2*v1;
|
||||
*B=(*A-v2);
|
||||
*(A++)=*(B++)+2*v2;
|
||||
v1 = *B * cos + *(B + 1) * sin;
|
||||
v2 = *B * sin - *(B + 1) * cos;
|
||||
*B = (*A + v1);
|
||||
*(A++) = *(B++) - 2 * v1;
|
||||
*B = (*A - v2);
|
||||
*(A++) = *(B++) + 2 * v2;
|
||||
}
|
||||
A=B;
|
||||
B+=ButterfliesPerGroup*2;
|
||||
sptr+=2;
|
||||
A = B;
|
||||
B += ButterfliesPerGroup * 2;
|
||||
sptr += 2;
|
||||
}
|
||||
ButterfliesPerGroup >>= 1;
|
||||
}
|
||||
/* Massage output to get the output for a real input sequence. */
|
||||
br1=h->BitReversed+1;
|
||||
br2=h->BitReversed+h->Points-1;
|
||||
br1 = h->BitReversed + 1;
|
||||
br2 = h->BitReversed + h->Points - 1;
|
||||
|
||||
while(br1<br2)
|
||||
{
|
||||
|
@ -299,12 +301,12 @@ void InverseRealFFTf(fft_type *buffer,HFFT h)
|
|||
fft_type HRplus,HRminus,HIplus,HIminus;
|
||||
fft_type v1,v2,sin,cos;
|
||||
|
||||
int ButterfliesPerGroup=h->Points/2;
|
||||
auto ButterfliesPerGroup = h->Points / 2;
|
||||
|
||||
/* Massage input to get the input for a real output sequence. */
|
||||
A=buffer+2;
|
||||
B=buffer+h->Points*2-2;
|
||||
br1=h->BitReversed+1;
|
||||
A = buffer + 2;
|
||||
B = buffer + h->Points * 2 - 2;
|
||||
br1 = h->BitReversed + 1;
|
||||
while(A<B)
|
||||
{
|
||||
sin=h->SinTable[*br1];
|
||||
|
@ -344,30 +346,30 @@ void InverseRealFFTf(fft_type *buffer,HFFT h)
|
|||
* Bin-----Bout
|
||||
*/
|
||||
|
||||
endptr1=buffer+h->Points*2;
|
||||
endptr1 = buffer + h->Points * 2;
|
||||
|
||||
while(ButterfliesPerGroup>0)
|
||||
while(ButterfliesPerGroup > 0)
|
||||
{
|
||||
A=buffer;
|
||||
B=buffer+ButterfliesPerGroup*2;
|
||||
sptr=h->SinTable;
|
||||
A = buffer;
|
||||
B = buffer + ButterfliesPerGroup * 2;
|
||||
sptr = h->SinTable;
|
||||
|
||||
while(A<endptr1)
|
||||
while(A < endptr1)
|
||||
{
|
||||
sin=*(sptr++);
|
||||
cos=*(sptr++);
|
||||
endptr2=B;
|
||||
while(A<endptr2)
|
||||
sin = *(sptr++);
|
||||
cos = *(sptr++);
|
||||
endptr2 = B;
|
||||
while(A < endptr2)
|
||||
{
|
||||
v1=*B*cos - *(B+1)*sin;
|
||||
v2=*B*sin + *(B+1)*cos;
|
||||
*B=(*A+v1)*(fft_type)0.5;
|
||||
*(A++)=*(B++)-v1;
|
||||
*B=(*A+v2)*(fft_type)0.5;
|
||||
*(A++)=*(B++)-v2;
|
||||
v1 = *B * cos - *(B + 1) * sin;
|
||||
v2 = *B * sin + *(B + 1) * cos;
|
||||
*B = (*A + v1) * (fft_type)0.5;
|
||||
*(A++) = *(B++) - v1;
|
||||
*B = (*A + v2) * (fft_type)0.5;
|
||||
*(A++) = *(B++) - v2;
|
||||
}
|
||||
A=B;
|
||||
B+=ButterfliesPerGroup*2;
|
||||
A = B;
|
||||
B += ButterfliesPerGroup * 2;
|
||||
}
|
||||
ButterfliesPerGroup >>= 1;
|
||||
}
|
||||
|
@ -377,9 +379,9 @@ void ReorderToFreq(HFFT hFFT, const fft_type *buffer,
|
|||
fft_type *RealOut, fft_type *ImagOut)
|
||||
{
|
||||
// Copy the data into the real and imaginary outputs
|
||||
for(int i=1;i<hFFT->Points;i++) {
|
||||
RealOut[i]=buffer[hFFT->BitReversed[i] ];
|
||||
ImagOut[i]=buffer[hFFT->BitReversed[i]+1];
|
||||
for(size_t i = 1; i < hFFT->Points; i++) {
|
||||
RealOut[i] = buffer[hFFT->BitReversed[i] ];
|
||||
ImagOut[i] = buffer[hFFT->BitReversed[i]+1];
|
||||
}
|
||||
RealOut[0] = buffer[0]; // DC component
|
||||
ImagOut[0] = 0;
|
||||
|
@ -390,7 +392,7 @@ void ReorderToFreq(HFFT hFFT, const fft_type *buffer,
|
|||
void ReorderToTime(HFFT hFFT, const fft_type *buffer, fft_type *TimeOut)
|
||||
{
|
||||
// Copy the data into the real outputs
|
||||
for(int i=0;i<hFFT->Points;i++) {
|
||||
for(size_t i = 0; i < hFFT->Points; i++) {
|
||||
TimeOut[i*2 ]=buffer[hFFT->BitReversed[i] ];
|
||||
TimeOut[i*2+1]=buffer[hFFT->BitReversed[i]+1];
|
||||
}
|
||||
|
|
|
@ -7,16 +7,16 @@
|
|||
struct FFTParam {
|
||||
int *BitReversed;
|
||||
fft_type *SinTable;
|
||||
int Points;
|
||||
size_t Points;
|
||||
#ifdef EXPERIMENTAL_EQ_SSE_THREADED
|
||||
int pow2Bits;
|
||||
#endif
|
||||
};
|
||||
typedef FFTParam * HFFT;
|
||||
|
||||
HFFT InitializeFFT(int);
|
||||
HFFT InitializeFFT(size_t);
|
||||
void EndFFT(HFFT);
|
||||
HFFT GetFFT(int);
|
||||
HFFT GetFFT(size_t);
|
||||
void ReleaseFFT(HFFT);
|
||||
void CleanupFFT();
|
||||
void RealFFTf(fft_type *,HFFT);
|
||||
|
|
1086
src/RealFFTf48x.cpp
1086
src/RealFFTf48x.cpp
File diff suppressed because it is too large
Load Diff
|
@ -1262,8 +1262,9 @@ struct MinMaxSumsq
|
|||
}
|
||||
|
||||
bool Sequence::GetWaveDisplay(float *min, float *max, float *rms, int* bl,
|
||||
int len, const sampleCount *where)
|
||||
size_t len, const sampleCount *where)
|
||||
{
|
||||
wxASSERT(len > 0);
|
||||
const auto s0 = std::max(sampleCount(0), where[0]);
|
||||
if (s0 >= mNumSamples)
|
||||
// None of the samples asked for are in range. Abandon.
|
||||
|
@ -1276,7 +1277,7 @@ bool Sequence::GetWaveDisplay(float *min, float *max, float *rms, int* bl,
|
|||
std::min(mNumSamples, std::max(1 + where[len - 1], where[len]));
|
||||
float *temp = new float[mMaxSamples];
|
||||
|
||||
int pixel = 0;
|
||||
decltype(len) pixel = 0;
|
||||
|
||||
auto srcX = s0;
|
||||
decltype(srcX) nextSrcX = 0;
|
||||
|
@ -1305,7 +1306,7 @@ bool Sequence::GetWaveDisplay(float *min, float *max, float *rms, int* bl,
|
|||
|
||||
// Find the range of pixels covered by the current block file
|
||||
// (Their starting samples covered by it, to be exact)
|
||||
int nextPixel;
|
||||
decltype(len) nextPixel;
|
||||
if (nextSrcX >= s1)
|
||||
// last pass
|
||||
nextPixel = len;
|
||||
|
@ -1416,7 +1417,7 @@ bool Sequence::GetWaveDisplay(float *min, float *max, float *rms, int* bl,
|
|||
// (normally just one, but maybe more when zoomed very close)
|
||||
// and the range of positions for those columns
|
||||
// (normally one or more, for that one column)
|
||||
int pixelX = pixel + 1;
|
||||
auto pixelX = pixel + 1;
|
||||
decltype(filePosition) positionX = 0;
|
||||
while (pixelX < nextPixel &&
|
||||
filePosition ==
|
||||
|
|
|
@ -100,7 +100,7 @@ class PROFILE_DLL_API Sequence final : public XMLTagHandler{
|
|||
// bl is negative wherever data are not yet available.
|
||||
// Return true if successful.
|
||||
bool GetWaveDisplay(float *min, float *max, float *rms, int* bl,
|
||||
int len, const sampleCount *where);
|
||||
size_t len, const sampleCount *where);
|
||||
|
||||
bool Copy(sampleCount s0, sampleCount s1, std::unique_ptr<Sequence> &dest) const;
|
||||
bool Paste(sampleCount s0, const Sequence *src);
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
|
||||
#include "Experimental.h"
|
||||
|
||||
bool ComputeSpectrum(const float * data, int width,
|
||||
int windowSize,
|
||||
bool ComputeSpectrum(const float * data, size_t width,
|
||||
size_t windowSize,
|
||||
double WXUNUSED(rate), float *output,
|
||||
bool autocorrelation, int windowFunc)
|
||||
{
|
||||
|
@ -33,19 +33,18 @@ bool ComputeSpectrum(const float * data, int width,
|
|||
|
||||
float *processed = new float[windowSize];
|
||||
|
||||
int i;
|
||||
for (i = 0; i < windowSize; i++)
|
||||
for (size_t i = 0; i < windowSize; i++)
|
||||
processed[i] = float(0.0);
|
||||
int half = windowSize / 2;
|
||||
auto half = windowSize / 2;
|
||||
|
||||
float *in = new float[windowSize];
|
||||
float *out = new float[windowSize];
|
||||
float *out2 = new float[windowSize];
|
||||
|
||||
int start = 0;
|
||||
int windows = 0;
|
||||
size_t start = 0;
|
||||
unsigned windows = 0;
|
||||
while (start + windowSize <= width) {
|
||||
for (i = 0; i < windowSize; i++)
|
||||
for (size_t i = 0; i < windowSize; i++)
|
||||
in[i] = data[start + i];
|
||||
|
||||
WindowFunc(windowFunc, windowSize, in);
|
||||
|
@ -54,13 +53,13 @@ bool ComputeSpectrum(const float * data, int width,
|
|||
// Take FFT
|
||||
RealFFT(windowSize, in, out, out2);
|
||||
// Compute power
|
||||
for (i = 0; i < windowSize; i++)
|
||||
for (size_t i = 0; i < windowSize; i++)
|
||||
in[i] = (out[i] * out[i]) + (out2[i] * out2[i]);
|
||||
|
||||
// Tolonen and Karjalainen recommend taking the cube root
|
||||
// of the power, instead of the square root
|
||||
|
||||
for (i = 0; i < windowSize; i++)
|
||||
for (size_t i = 0; i < windowSize; i++)
|
||||
in[i] = powf(in[i], 1.0f / 3.0f);
|
||||
|
||||
// Take FFT
|
||||
|
@ -70,7 +69,7 @@ bool ComputeSpectrum(const float * data, int width,
|
|||
PowerSpectrum(windowSize, in, out);
|
||||
|
||||
// Take real part of result
|
||||
for (i = 0; i < half; i++)
|
||||
for (size_t i = 0; i < half; i++)
|
||||
processed[i] += out[i];
|
||||
|
||||
start += half;
|
||||
|
@ -85,7 +84,7 @@ bool ComputeSpectrum(const float * data, int width,
|
|||
It should be safe, as indexes refer only to current and previous elements,
|
||||
that have already been clipped, etc...
|
||||
*/
|
||||
for (i = 0; i < half; i++) {
|
||||
for (size_t i = 0; i < half; i++) {
|
||||
// Clip at zero, copy to temp array
|
||||
if (processed[i] < 0.0)
|
||||
processed[i] = float(0.0);
|
||||
|
@ -103,23 +102,23 @@ bool ComputeSpectrum(const float * data, int width,
|
|||
}
|
||||
|
||||
// Reverse and scale
|
||||
for (i = 0; i < half; i++)
|
||||
for (size_t i = 0; i < half; i++)
|
||||
in[i] = processed[i] / (windowSize / 4);
|
||||
for (i = 0; i < half; i++)
|
||||
for (size_t i = 0; i < half; i++)
|
||||
processed[half - 1 - i] = in[i];
|
||||
} else {
|
||||
// Convert to decibels
|
||||
// But do it safely; -Inf is nobody's friend
|
||||
for (i = 0; i < half; i++){
|
||||
for (size_t i = 0; i < half; i++){
|
||||
float temp=(processed[i] / windowSize / windows);
|
||||
if (temp > 0.0)
|
||||
processed[i] = 10*log10(temp);
|
||||
processed[i] = 10 * log10(temp);
|
||||
else
|
||||
processed[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0;i<half;i++)
|
||||
for(size_t i = 0; i < half; i++)
|
||||
output[i] = processed[i];
|
||||
delete[]in;
|
||||
delete[]out;
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
calculates windowSize/2 frequency samples
|
||||
*/
|
||||
|
||||
bool ComputeSpectrum(const float * data, int width, int windowSize,
|
||||
bool ComputeSpectrum(const float * data, size_t width, size_t windowSize,
|
||||
double rate, float *out, bool autocorrelation,
|
||||
int windowFunc = eWinFuncHanning);
|
||||
|
||||
|
|
|
@ -2015,7 +2015,7 @@ void TrackArtist::DrawSpectrum(const WaveTrack *track,
|
|||
}
|
||||
|
||||
static inline float findValue
|
||||
(const float *spectrum, float bin0, float bin1, int half,
|
||||
(const float *spectrum, float bin0, float bin1, unsigned half,
|
||||
bool autocorrelation, int gain, int range)
|
||||
{
|
||||
float value;
|
||||
|
@ -2035,7 +2035,7 @@ static inline float findValue
|
|||
bin0 += 1.0;
|
||||
}
|
||||
// Do not reference past end of freq array.
|
||||
if (int(bin1) >= half) {
|
||||
if (int(bin1) >= (int)half) {
|
||||
bin1 -= 1.0;
|
||||
}
|
||||
|
||||
|
@ -2043,7 +2043,6 @@ static inline float findValue
|
|||
value /= binwidth;
|
||||
}
|
||||
#else
|
||||
wxUnusedVar(half);
|
||||
// Maximum method, and no apportionment of any single bins over multiple pixel rows
|
||||
// See Bug971
|
||||
int index, limitIndex;
|
||||
|
@ -2058,8 +2057,8 @@ static inline float findValue
|
|||
));
|
||||
}
|
||||
else {
|
||||
index = std::min(half - 1, int(floor(0.5 + bin0)));
|
||||
limitIndex = std::min(half, int(floor(0.5 + bin1)));
|
||||
index = std::min<int>(half - 1, int(floor(0.5 + bin0)));
|
||||
limitIndex = std::min<int>(half, int(floor(0.5 + bin1)));
|
||||
}
|
||||
value = spectrum[index];
|
||||
while (++index < limitIndex)
|
||||
|
@ -2166,14 +2165,15 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
|
|||
return;
|
||||
unsigned char *data = image.GetData();
|
||||
|
||||
const int half = settings.GetFFTLength() / 2;
|
||||
const auto half = settings.GetFFTLength() / 2;
|
||||
const double binUnit = rate / (2 * half);
|
||||
const float *freq = 0;
|
||||
const sampleCount *where = 0;
|
||||
bool updated;
|
||||
{
|
||||
const double pps = averagePixelsPerSample * rate;
|
||||
updated = clip->GetSpectrogram(waveTrackCache, freq, where, hiddenMid.width,
|
||||
updated = clip->GetSpectrogram(waveTrackCache, freq, where,
|
||||
(size_t)hiddenMid.width,
|
||||
t0, pps);
|
||||
}
|
||||
|
||||
|
@ -2399,12 +2399,12 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
|
|||
const int end = hidden
|
||||
? 0
|
||||
: std::min(mid.width, int(zoomInfo.GetFisheyeRightBoundary(-leftOffset)));
|
||||
const int numPixels = std::max(0, end - begin);
|
||||
const int zeroPaddingFactor = autocorrelation ? 1 : settings.zeroPaddingFactor;
|
||||
const size_t numPixels = std::max(0, end - begin);
|
||||
const size_t zeroPaddingFactor = autocorrelation ? 1 : settings.ZeroPaddingFactor();
|
||||
SpecCache specCache
|
||||
(numPixels, settings.algorithm, -1,
|
||||
t0, settings.windowType,
|
||||
settings.windowSize, zeroPaddingFactor, settings.frequencyGain);
|
||||
settings.WindowSize(), zeroPaddingFactor, settings.frequencyGain);
|
||||
if (numPixels > 0) {
|
||||
for (int ii = begin; ii < end; ++ii) {
|
||||
const double time = zoomInfo.PositionToTime(ii, -leftOffset) - tOffset;
|
||||
|
|
|
@ -2346,7 +2346,7 @@ inline double findMaxRatio(double center, double rate)
|
|||
void TrackPanel::SnapCenterOnce(const WaveTrack *pTrack, bool up)
|
||||
{
|
||||
const SpectrogramSettings &settings = pTrack->GetSpectrogramSettings();
|
||||
const int windowSize = settings.GetFFTLength();
|
||||
const auto windowSize = settings.GetFFTLength();
|
||||
const double rate = pTrack->GetRate();
|
||||
const double nyq = rate / 2.0;
|
||||
const double binFrequency = rate / windowSize;
|
||||
|
@ -2409,7 +2409,7 @@ void TrackPanel::StartSnappingFreqSelection (const WaveTrack *pTrack)
|
|||
// except, shrink the window as needed so we get some answers
|
||||
|
||||
const SpectrogramSettings &settings = pTrack->GetSpectrogramSettings();
|
||||
int windowSize = settings.GetFFTLength();
|
||||
auto windowSize = settings.GetFFTLength();
|
||||
|
||||
while(windowSize > effectiveLength)
|
||||
windowSize >>= 1;
|
||||
|
@ -4102,7 +4102,7 @@ void TrackPanel::HandleWaveTrackVZoom
|
|||
if (spectral) {
|
||||
track->GetSpectrumBounds(&min, &max);
|
||||
scale = (settings.GetScale(min, max, rate, false));
|
||||
const int fftLength = settings.GetFFTLength();
|
||||
const auto fftLength = settings.GetFFTLength();
|
||||
const float binSize = rate / fftLength;
|
||||
|
||||
// JKC: Following discussions of Bug 1208 I'm allowing zooming in
|
||||
|
|
|
@ -177,7 +177,7 @@ sampleCount VoiceKey::OnForward (WaveTrack & t, sampleCount start, sampleCount l
|
|||
//Now, go through the sound again, sample by sample.
|
||||
wxASSERT(WindowSizeInt < SignalWindowSizeInt);
|
||||
size_t i;
|
||||
for(i = 0; i < SignalWindowSizeInt - WindowSizeInt; i++) {
|
||||
for(i = 0; i + WindowSizeInt < SignalWindowSizeInt; i++) {
|
||||
|
||||
int tests = 0;
|
||||
int testThreshold = 0;
|
||||
|
|
148
src/WaveClip.cpp
148
src/WaveClip.cpp
|
@ -57,7 +57,6 @@ class WaveCache {
|
|||
public:
|
||||
WaveCache()
|
||||
: dirty(-1)
|
||||
, len(-1)
|
||||
, start(-1)
|
||||
, pps(0)
|
||||
, rate(-1)
|
||||
|
@ -70,7 +69,7 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
WaveCache(int len_, double pixelsPerSecond, double rate_, double t0, int dirty_)
|
||||
WaveCache(size_t len_, double pixelsPerSecond, double rate_, double t0, int dirty_)
|
||||
: dirty(dirty_)
|
||||
, len(len_)
|
||||
, start(t0)
|
||||
|
@ -94,7 +93,7 @@ public:
|
|||
}
|
||||
|
||||
int dirty;
|
||||
const int len; // counts pixels, not samples
|
||||
const size_t len { 0 }; // counts pixels, not samples
|
||||
const double start;
|
||||
const double pps;
|
||||
const int rate;
|
||||
|
@ -108,10 +107,12 @@ public:
|
|||
class InvalidRegion
|
||||
{
|
||||
public:
|
||||
InvalidRegion(int s, int e):start(s),end(e){}
|
||||
InvalidRegion(size_t s, size_t e)
|
||||
: start(s), end(e)
|
||||
{}
|
||||
//start and end pixel count. (not samples)
|
||||
int start;
|
||||
int end;
|
||||
size_t start;
|
||||
size_t end;
|
||||
};
|
||||
|
||||
|
||||
|
@ -157,7 +158,7 @@ public:
|
|||
//if the regions intersect OR are pixel adjacent
|
||||
InvalidRegion ®ion = mRegions[i];
|
||||
if(region.start <= invalEnd+1
|
||||
&& region.end >= invalStart-1)
|
||||
&& region.end + 1 >= invalStart)
|
||||
{
|
||||
//take the union region
|
||||
if(region.start > invalStart)
|
||||
|
@ -183,8 +184,8 @@ public:
|
|||
|
||||
if(!added)
|
||||
{
|
||||
InvalidRegion newRegion(invalStart,invalEnd);
|
||||
mRegions.insert(mRegions.begin(),newRegion);
|
||||
InvalidRegion newRegion(invalStart, invalEnd);
|
||||
mRegions.insert(mRegions.begin(), newRegion);
|
||||
}
|
||||
|
||||
|
||||
|
@ -195,7 +196,7 @@ public:
|
|||
InvalidRegion ®ion = mRegions[i];
|
||||
InvalidRegion &prevRegion = mRegions[i - 1];
|
||||
if(region.start <= prevRegion.end+1
|
||||
&& region.end >= prevRegion.start-1)
|
||||
&& region.end + 1 >= prevRegion.start)
|
||||
{
|
||||
//take the union region
|
||||
if(region.start > prevRegion.start)
|
||||
|
@ -218,8 +219,8 @@ public:
|
|||
|
||||
//lock before calling these in a section. unlock after finished.
|
||||
int GetNumInvalidRegions() const {return mRegions.size();}
|
||||
int GetInvalidRegionStart(int i) const {return mRegions[i].start;}
|
||||
int GetInvalidRegionEnd(int i) const {return mRegions[i].end;}
|
||||
size_t GetInvalidRegionStart(int i) const {return mRegions[i].start;}
|
||||
size_t GetInvalidRegionEnd(int i) const {return mRegions[i].end;}
|
||||
|
||||
void ClearInvalidRegions()
|
||||
{
|
||||
|
@ -228,8 +229,8 @@ public:
|
|||
|
||||
void LoadInvalidRegion(int ii, Sequence *sequence, bool updateODCount)
|
||||
{
|
||||
const int invStart = GetInvalidRegionStart(ii);
|
||||
const int invEnd = GetInvalidRegionEnd(ii);
|
||||
const auto invStart = GetInvalidRegionStart(ii);
|
||||
const auto invEnd = GetInvalidRegionEnd(ii);
|
||||
|
||||
//before check number of ODPixels
|
||||
int regionODPixels = 0;
|
||||
|
@ -258,7 +259,7 @@ public:
|
|||
LoadInvalidRegion(i, sequence, updateODCount);
|
||||
}
|
||||
|
||||
int CountODPixels(int start, int end)
|
||||
int CountODPixels(size_t start, size_t end)
|
||||
{
|
||||
using namespace std;
|
||||
const int *begin = &bl[0];
|
||||
|
@ -272,23 +273,23 @@ protected:
|
|||
};
|
||||
|
||||
static void ComputeSpectrumUsingRealFFTf
|
||||
(float * __restrict buffer, HFFT hFFT, const float * __restrict window, int len, float * __restrict out)
|
||||
(float * __restrict buffer, HFFT hFFT, const float * __restrict window, size_t len, float * __restrict out)
|
||||
{
|
||||
int i;
|
||||
if(len > hFFT->Points*2)
|
||||
len = hFFT->Points*2;
|
||||
for(i=0; i<len; i++)
|
||||
size_t i;
|
||||
if(len > hFFT->Points * 2)
|
||||
len = hFFT->Points * 2;
|
||||
for(i = 0; i < len; i++)
|
||||
buffer[i] *= window[i];
|
||||
for( ; i<(hFFT->Points*2); i++)
|
||||
buffer[i]=0; // zero pad as needed
|
||||
for( ; i < (hFFT->Points * 2); i++)
|
||||
buffer[i] = 0; // zero pad as needed
|
||||
RealFFTf(buffer, hFFT);
|
||||
// Handle the (real-only) DC
|
||||
float power = buffer[0]*buffer[0];
|
||||
float power = buffer[0] * buffer[0];
|
||||
if(power <= 0)
|
||||
out[0] = -160.0;
|
||||
else
|
||||
out[0] = 10.0*log10f(power);
|
||||
for(i=1;i<hFFT->Points;i++) {
|
||||
out[0] = 10.0 * log10f(power);
|
||||
for(i = 1; i < hFFT->Points; i++) {
|
||||
const int index = hFFT->BitReversed[i];
|
||||
const float re = buffer[index], im = buffer[index + 1];
|
||||
power = re * re + im * im;
|
||||
|
@ -435,7 +436,8 @@ void WaveClip::AddInvalidRegion(sampleCount startSample, sampleCount endSample)
|
|||
namespace {
|
||||
|
||||
inline
|
||||
void findCorrection(const std::vector<sampleCount> &oldWhere, int oldLen, int newLen,
|
||||
void findCorrection(const std::vector<sampleCount> &oldWhere, size_t oldLen,
|
||||
size_t newLen,
|
||||
double t0, double rate, double samplesPerPixel,
|
||||
int &oldX0, double &correction)
|
||||
{
|
||||
|
@ -478,7 +480,7 @@ void findCorrection(const std::vector<sampleCount> &oldWhere, int oldLen, int ne
|
|||
}
|
||||
|
||||
inline void
|
||||
fillWhere(std::vector<sampleCount> &where, int len, double bias, double correction,
|
||||
fillWhere(std::vector<sampleCount> &where, size_t len, double bias, double correction,
|
||||
double t0, double rate, double samplesPerPixel)
|
||||
{
|
||||
// Be careful to make the first value non-negative
|
||||
|
@ -500,10 +502,10 @@ bool WaveClip::GetWaveDisplay(WaveDisplay &display, double t0,
|
|||
{
|
||||
const bool allocated = (display.where != 0);
|
||||
|
||||
const int numPixels = display.width;
|
||||
const size_t numPixels = (int)display.width;
|
||||
|
||||
int p0 = 0; // least column requiring computation
|
||||
int p1 = numPixels; // greatest column requiring computation, plus one
|
||||
size_t p0 = 0; // least column requiring computation
|
||||
size_t p1 = numPixels; // greatest column requiring computation, plus one
|
||||
|
||||
float *min;
|
||||
float *max;
|
||||
|
@ -558,7 +560,7 @@ bool WaveClip::GetWaveDisplay(WaveDisplay &display, double t0,
|
|||
|
||||
int oldX0 = 0;
|
||||
double correction = 0.0;
|
||||
int copyBegin = 0, copyEnd = 0;
|
||||
size_t copyBegin = 0, copyEnd = 0;
|
||||
if (match) {
|
||||
findCorrection(oldCache->where, oldCache->len, numPixels,
|
||||
t0, mRate, samplesPerPixel,
|
||||
|
@ -566,9 +568,10 @@ bool WaveClip::GetWaveDisplay(WaveDisplay &display, double t0,
|
|||
// Remember our first pixel maps to oldX0 in the old cache,
|
||||
// possibly out of bounds.
|
||||
// For what range of pixels can data be copied?
|
||||
copyBegin = std::min(numPixels, std::max(0, -oldX0));
|
||||
copyEnd = std::min(numPixels,
|
||||
copyBegin + oldCache->len - std::max(0, oldX0)
|
||||
copyBegin = std::min<size_t>(numPixels, std::max(0, -oldX0));
|
||||
copyEnd = std::min<size_t>(numPixels,
|
||||
std::max(0,
|
||||
(int)copyBegin + (int)oldCache->len - std::max(0, oldX0))
|
||||
);
|
||||
}
|
||||
if (!(copyEnd > copyBegin))
|
||||
|
@ -603,7 +606,7 @@ bool WaveClip::GetWaveDisplay(WaveDisplay &display, double t0,
|
|||
// Copy what we can from the old cache.
|
||||
const int length = copyEnd - copyBegin;
|
||||
const size_t sizeFloats = length * sizeof(float);
|
||||
const int srcIdx = copyBegin + oldX0;
|
||||
const int srcIdx = (int)copyBegin + oldX0;
|
||||
memcpy(&min[copyBegin], &oldCache->min[srcIdx], sizeFloats);
|
||||
memcpy(&max[copyBegin], &oldCache->max[srcIdx], sizeFloats);
|
||||
memcpy(&rms[copyBegin], &oldCache->rms[srcIdx], sizeFloats);
|
||||
|
@ -618,11 +621,11 @@ bool WaveClip::GetWaveDisplay(WaveDisplay &display, double t0,
|
|||
/* handle values in the append buffer */
|
||||
|
||||
auto numSamples = mSequence->GetNumSamples();
|
||||
int a;
|
||||
auto a = p0;
|
||||
|
||||
// Not all of the required columns might be in the sequence.
|
||||
// Some might be in the append buffer.
|
||||
for (a = p0; a < p1; ++a) {
|
||||
for (; a < p1; ++a) {
|
||||
if (where[a + 1] > numSamples)
|
||||
break;
|
||||
}
|
||||
|
@ -630,11 +633,9 @@ bool WaveClip::GetWaveDisplay(WaveDisplay &display, double t0,
|
|||
// Handle the columns that land in the append buffer.
|
||||
//compute the values that are outside the overlap from scratch.
|
||||
if (a < p1) {
|
||||
int i;
|
||||
|
||||
sampleFormat seqFormat = mSequence->GetSampleFormat();
|
||||
bool didUpdate = false;
|
||||
for(i=a; i<p1; i++) {
|
||||
for(auto i = a; i < p1; i++) {
|
||||
auto left = std::max(sampleCount{ 0 },
|
||||
where[i] - numSamples);
|
||||
auto right = std::min(sampleCount{ mAppendBufferLen },
|
||||
|
@ -724,7 +725,7 @@ bool WaveClip::GetWaveDisplay(WaveDisplay &display, double t0,
|
|||
namespace {
|
||||
|
||||
void ComputeSpectrogramGainFactors
|
||||
(int fftLen, double rate, int frequencyGain, std::vector<float> &gainFactors)
|
||||
(size_t fftLen, double rate, int frequencyGain, std::vector<float> &gainFactors)
|
||||
{
|
||||
if (frequencyGain > 0) {
|
||||
// Compute a frequency-dependent gain factor
|
||||
|
@ -733,7 +734,7 @@ void ComputeSpectrogramGainFactors
|
|||
// This is the reciprocal of the bin number of 1000 Hz:
|
||||
const double factor = ((double)rate / (double)fftLen) / 1000.0;
|
||||
|
||||
int half = fftLen / 2;
|
||||
auto half = fftLen / 2;
|
||||
gainFactors.reserve(half);
|
||||
// Don't take logarithm of zero! Let bin 0 replicate the gain factor for bin 1.
|
||||
gainFactors.push_back(frequencyGain*log10(factor));
|
||||
|
@ -760,8 +761,8 @@ bool SpecCache::Matches
|
|||
ppsMatch &&
|
||||
dirty == dirty_ &&
|
||||
windowType == settings.windowType &&
|
||||
windowSize == settings.windowSize &&
|
||||
zeroPaddingFactor == settings.zeroPaddingFactor &&
|
||||
windowSize == settings.WindowSize() &&
|
||||
zeroPaddingFactor == settings.ZeroPaddingFactor() &&
|
||||
frequencyGain == settings.frequencyGain &&
|
||||
algorithm == settings.algorithm;
|
||||
}
|
||||
|
@ -778,7 +779,7 @@ bool SpecCache::CalculateOneSpectrum
|
|||
bool result = false;
|
||||
const bool reassignment =
|
||||
(settings.algorithm == SpectrogramSettings::algReassignment);
|
||||
const int windowSize = settings.windowSize;
|
||||
const size_t windowSize = settings.WindowSize();
|
||||
|
||||
sampleCount start;
|
||||
if (xx < 0)
|
||||
|
@ -790,10 +791,10 @@ bool SpecCache::CalculateOneSpectrum
|
|||
|
||||
const bool autocorrelation =
|
||||
settings.algorithm == SpectrogramSettings::algPitchEAC;
|
||||
const int zeroPaddingFactor = (autocorrelation ? 1 : settings.zeroPaddingFactor);
|
||||
const int padding = (windowSize * (zeroPaddingFactor - 1)) / 2;
|
||||
const int fftLen = windowSize * zeroPaddingFactor;
|
||||
const int half = fftLen / 2;
|
||||
const size_t zeroPaddingFactor = (autocorrelation ? 1 : settings.ZeroPaddingFactor());
|
||||
const size_t padding = (windowSize * (zeroPaddingFactor - 1)) / 2;
|
||||
const size_t fftLen = windowSize * zeroPaddingFactor;
|
||||
const auto half = fftLen / 2;
|
||||
|
||||
if (start <= 0 || start >= numSamples) {
|
||||
if (xx >= 0 && xx < len) {
|
||||
|
@ -864,26 +865,26 @@ bool SpecCache::CalculateOneSpectrum
|
|||
|
||||
{
|
||||
const float *const window = settings.window;
|
||||
for (int ii = 0; ii < fftLen; ++ii)
|
||||
for (size_t ii = 0; ii < fftLen; ++ii)
|
||||
scratch[ii] *= window[ii];
|
||||
RealFFTf(scratch, hFFT);
|
||||
}
|
||||
|
||||
{
|
||||
const float *const dWindow = settings.dWindow;
|
||||
for (int ii = 0; ii < fftLen; ++ii)
|
||||
for (size_t ii = 0; ii < fftLen; ++ii)
|
||||
scratch2[ii] *= dWindow[ii];
|
||||
RealFFTf(scratch2, hFFT);
|
||||
}
|
||||
|
||||
{
|
||||
const float *const tWindow = settings.tWindow;
|
||||
for (int ii = 0; ii < fftLen; ++ii)
|
||||
for (size_t ii = 0; ii < fftLen; ++ii)
|
||||
scratch3[ii] *= tWindow[ii];
|
||||
RealFFTf(scratch3, hFFT);
|
||||
}
|
||||
|
||||
for (int ii = 0; ii < hFFT->Points; ++ii) {
|
||||
for (size_t ii = 0; ii < hFFT->Points; ++ii) {
|
||||
const int index = hFFT->BitReversed[ii];
|
||||
const float
|
||||
denomRe = scratch[index],
|
||||
|
@ -895,7 +896,7 @@ bool SpecCache::CalculateOneSpectrum
|
|||
|
||||
double freqCorrection;
|
||||
{
|
||||
const double multiplier = -fftLen / (2.0f * M_PI);
|
||||
const double multiplier = -(fftLen / (2.0f * M_PI));
|
||||
const float
|
||||
numRe = scratch2[index],
|
||||
numIm = ii == 0 ? 0 : scratch2[index + 1];
|
||||
|
@ -929,7 +930,8 @@ bool SpecCache::CalculateOneSpectrum
|
|||
{
|
||||
result = true;
|
||||
|
||||
int index = half * correctedX + bin;
|
||||
// Can this be negative?
|
||||
int index = (int)half * correctedX + bin;
|
||||
#ifdef _OPENMP
|
||||
// This assignment can race if index reaches into another thread's bins.
|
||||
// The probability of a race very low, so this carries little overhead,
|
||||
|
@ -954,7 +956,7 @@ bool SpecCache::CalculateOneSpectrum
|
|||
(useBuffer, settings.hFFT, settings.window, fftLen, results);
|
||||
if (!gainFactors.empty()) {
|
||||
// Apply a frequency-dependant gain factor
|
||||
for (int ii = 0; ii < half; ++ii)
|
||||
for (size_t ii = 0; ii < half; ++ii)
|
||||
results[ii] += gainFactors[ii];
|
||||
}
|
||||
}
|
||||
|
@ -965,28 +967,28 @@ bool SpecCache::CalculateOneSpectrum
|
|||
|
||||
void SpecCache::Populate
|
||||
(const SpectrogramSettings &settings, WaveTrackCache &waveTrackCache,
|
||||
int copyBegin, int copyEnd, int numPixels,
|
||||
int copyBegin, int copyEnd, size_t numPixels,
|
||||
sampleCount numSamples,
|
||||
double offset, double rate, double pixelsPerSecond)
|
||||
{
|
||||
settings.CacheWindows();
|
||||
|
||||
const int &frequencyGain = settings.frequencyGain;
|
||||
const int &windowSize = settings.windowSize;
|
||||
const size_t windowSize = settings.WindowSize();
|
||||
const bool autocorrelation =
|
||||
settings.algorithm == SpectrogramSettings::algPitchEAC;
|
||||
const bool reassignment =
|
||||
settings.algorithm == SpectrogramSettings::algReassignment;
|
||||
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
|
||||
const int &zeroPaddingFactor = autocorrelation ? 1 : settings.zeroPaddingFactor;
|
||||
const size_t zeroPaddingFactor = autocorrelation ? 1 : settings.ZeroPaddingFactor();
|
||||
#else
|
||||
const int zeroPaddingFactor = 1;
|
||||
const size_t zeroPaddingFactor = 1;
|
||||
#endif
|
||||
|
||||
// FFT length may be longer than the window of samples that affect results
|
||||
// because of zero padding done for increased frequency resolution
|
||||
const int fftLen = windowSize * zeroPaddingFactor;
|
||||
const int half = fftLen / 2;
|
||||
const size_t fftLen = windowSize * zeroPaddingFactor;
|
||||
const auto half = fftLen / 2;
|
||||
|
||||
const size_t bufferSize = fftLen;
|
||||
const size_t scratchSize = reassignment ? 3 * bufferSize : bufferSize;
|
||||
|
@ -1078,7 +1080,7 @@ void SpecCache::Populate
|
|||
for (auto xx = lowerBoundX; xx < upperBoundX; ++xx) {
|
||||
float *const results = &freq[half * xx];
|
||||
const HFFT hFFT = settings.hFFT;
|
||||
for (int ii = 0; ii < hFFT->Points; ++ii) {
|
||||
for (size_t ii = 0; ii < hFFT->Points; ++ii) {
|
||||
float &power = results[ii];
|
||||
if (power <= 0)
|
||||
power = -160.0;
|
||||
|
@ -1087,7 +1089,7 @@ void SpecCache::Populate
|
|||
}
|
||||
if (!gainFactors.empty()) {
|
||||
// Apply a frequency-dependant gain factor
|
||||
for (int ii = 0; ii < half; ++ii)
|
||||
for (size_t ii = 0; ii < half; ++ii)
|
||||
results[ii] += gainFactors[ii];
|
||||
}
|
||||
}
|
||||
|
@ -1097,7 +1099,7 @@ void SpecCache::Populate
|
|||
|
||||
bool WaveClip::GetSpectrogram(WaveTrackCache &waveTrackCache,
|
||||
const float *& spectrogram, const sampleCount *& where,
|
||||
int numPixels,
|
||||
size_t numPixels,
|
||||
double t0, double pixelsPerSecond) const
|
||||
{
|
||||
BEGIN_TASK_PROFILING("GetSpectrogram");
|
||||
|
@ -1107,18 +1109,18 @@ bool WaveClip::GetSpectrogram(WaveTrackCache &waveTrackCache,
|
|||
const bool autocorrelation =
|
||||
settings.algorithm == SpectrogramSettings::algPitchEAC;
|
||||
const int &frequencyGain = settings.frequencyGain;
|
||||
const int &windowSize = settings.windowSize;
|
||||
const size_t windowSize = settings.WindowSize();
|
||||
const int &windowType = settings.windowType;
|
||||
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
|
||||
const int &zeroPaddingFactor = autocorrelation ? 1 : settings.zeroPaddingFactor;
|
||||
const size_t zeroPaddingFactor = autocorrelation ? 1 : settings.ZeroPaddingFactor();
|
||||
#else
|
||||
const int zeroPaddingFactor = 1;
|
||||
const size_t zeroPaddingFactor = 1;
|
||||
#endif
|
||||
|
||||
// FFT length may be longer than the window of samples that affect results
|
||||
// because of zero padding done for increased frequency resolution
|
||||
const int fftLen = windowSize * zeroPaddingFactor;
|
||||
const int half = fftLen / 2;
|
||||
const size_t fftLen = windowSize * zeroPaddingFactor;
|
||||
const auto half = fftLen / 2;
|
||||
|
||||
bool match =
|
||||
mSpecCache &&
|
||||
|
@ -1158,9 +1160,9 @@ bool WaveClip::GetSpectrogram(WaveTrackCache &waveTrackCache,
|
|||
// Remember our first pixel maps to oldX0 in the old cache,
|
||||
// possibly out of bounds.
|
||||
// For what range of pixels can data be copied?
|
||||
copyBegin = std::min(numPixels, std::max(0, -oldX0));
|
||||
copyEnd = std::min(numPixels,
|
||||
copyBegin + oldCache->len - std::max(0, oldX0)
|
||||
copyBegin = std::min((int)numPixels, std::max(0, -oldX0));
|
||||
copyEnd = std::min((int)numPixels,
|
||||
copyBegin + (int)oldCache->len - std::max(0, oldX0)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,13 +41,10 @@ public:
|
|||
|
||||
// Make invalid cache
|
||||
SpecCache()
|
||||
: len(-1)
|
||||
, algorithm(-1)
|
||||
: algorithm(-1)
|
||||
, pps(-1.0)
|
||||
, start(-1.0)
|
||||
, windowType(-1)
|
||||
, windowSize(-1)
|
||||
, zeroPaddingFactor(-1)
|
||||
, frequencyGain(-1)
|
||||
#if 0
|
||||
, freq(NULL)
|
||||
|
@ -58,9 +55,9 @@ public:
|
|||
}
|
||||
|
||||
// Make valid cache, to be filled in
|
||||
SpecCache(int cacheLen, int algorithm_,
|
||||
double pps_, double start_, int windowType_, int windowSize_,
|
||||
int zeroPaddingFactor_, int frequencyGain_)
|
||||
SpecCache(size_t cacheLen, int algorithm_,
|
||||
double pps_, double start_, int windowType_, size_t windowSize_,
|
||||
unsigned zeroPaddingFactor_, int frequencyGain_)
|
||||
: len(cacheLen)
|
||||
, algorithm(algorithm_)
|
||||
, pps(pps_)
|
||||
|
@ -102,17 +99,17 @@ public:
|
|||
|
||||
void Populate
|
||||
(const SpectrogramSettings &settings, WaveTrackCache &waveTrackCache,
|
||||
int copyBegin, int copyEnd, int numPixels,
|
||||
int copyBegin, int copyEnd, size_t numPixels,
|
||||
sampleCount numSamples,
|
||||
double offset, double rate, double pixelsPerSecond);
|
||||
|
||||
const int len; // counts pixels, not samples
|
||||
const size_t len { 0 }; // counts pixels, not samples
|
||||
const int algorithm;
|
||||
const double pps;
|
||||
const double start;
|
||||
const int windowType;
|
||||
const int windowSize;
|
||||
const int zeroPaddingFactor;
|
||||
const size_t windowSize { 0 };
|
||||
const unsigned zeroPaddingFactor { 0 };
|
||||
const int frequencyGain;
|
||||
std::vector<float> freq;
|
||||
std::vector<sampleCount> where;
|
||||
|
@ -280,7 +277,7 @@ public:
|
|||
double t0, double pixelsPerSecond, bool &isLoadingOD) const;
|
||||
bool GetSpectrogram(WaveTrackCache &cache,
|
||||
const float *& spectrogram, const sampleCount *& where,
|
||||
int numPixels,
|
||||
size_t numPixels,
|
||||
double t0, double pixelsPerSecond) const;
|
||||
bool GetMinMax(float *min, float *max, double t0, double t1) const;
|
||||
bool GetRMS(float *rms, double t0, double t1);
|
||||
|
|
|
@ -314,7 +314,7 @@ void WaveTrack::GetSpectrumBounds(float *min, float *max) const
|
|||
bottom = 0.0f;
|
||||
else if (type == SpectrogramSettings::stPeriod) {
|
||||
// special case
|
||||
const int half = settings.GetFFTLength() / 2;
|
||||
const auto half = settings.GetFFTLength() / 2;
|
||||
// EAC returns no data for below this frequency:
|
||||
const float bin2 = rate / half;
|
||||
bottom = bin2;
|
||||
|
|
|
@ -50,8 +50,8 @@ Param( MaximumPause, double, XO("MaximumPause"), 1.0, 0.0, DB
|
|||
* Common constants
|
||||
*/
|
||||
|
||||
static const int kBufSize = 131072; // number of samples to process at once
|
||||
static const int kRMSWindowSize = 100; // samples in circular RMS window buffer
|
||||
enum : size_t { kBufSize = 131072 }; // number of samples to process at once
|
||||
enum : size_t { kRMSWindowSize = 100 }; // samples in circular RMS window buffer
|
||||
|
||||
/*
|
||||
* A auto duck region and an array of auto duck regions
|
||||
|
|
|
@ -406,44 +406,41 @@ void EffectChangePitch::DeduceFrequencies()
|
|||
// Aim for around 2048 samples at 44.1 kHz (good down to about 100 Hz).
|
||||
// To detect single notes, analysis period should be about 0.2 seconds.
|
||||
// windowSize must be a power of 2.
|
||||
int windowSize = wxRound(pow(2.0, floor((log(rate / 20.0)/log(2.0)) + 0.5)));
|
||||
// windowSize < 256 too inaccurate
|
||||
windowSize = (windowSize > 256)? windowSize : 256;
|
||||
const size_t windowSize =
|
||||
// windowSize < 256 too inaccurate
|
||||
std::max(256, wxRound(pow(2.0, floor((log(rate / 20.0)/log(2.0)) + 0.5))));
|
||||
|
||||
// we want about 0.2 seconds to catch the first note.
|
||||
// number of windows rounded to nearest integer >= 1.
|
||||
int numWindows = wxRound((double)(rate / (5.0f * windowSize)));
|
||||
numWindows = (numWindows > 0)? numWindows : 1;
|
||||
const unsigned numWindows =
|
||||
std::max(1, wxRound((double)(rate / (5.0f * windowSize))));
|
||||
|
||||
double trackStart = track->GetStartTime();
|
||||
double t0 = mT0 < trackStart? trackStart: mT0;
|
||||
auto start = track->TimeToLongSamples(t0);
|
||||
|
||||
int analyzeSize = windowSize * numWindows;
|
||||
auto analyzeSize = windowSize * numWindows;
|
||||
float * buffer;
|
||||
buffer = new float[analyzeSize];
|
||||
|
||||
float * freq;
|
||||
freq = new float[windowSize/2];
|
||||
freq = new float[windowSize / 2];
|
||||
|
||||
float * freqa;
|
||||
freqa = new float[windowSize/2];
|
||||
freqa = new float[windowSize / 2];
|
||||
|
||||
int i, j, argmax;
|
||||
int lag;
|
||||
|
||||
for(j=0; j<windowSize/2; j++)
|
||||
for(size_t j = 0; j < windowSize / 2; j++)
|
||||
freqa[j] = 0;
|
||||
|
||||
track->Get((samplePtr) buffer, floatSample, start, analyzeSize);
|
||||
for(i=0; i<numWindows; i++) {
|
||||
ComputeSpectrum(buffer+i*windowSize, windowSize,
|
||||
for(unsigned i = 0; i < numWindows; i++) {
|
||||
ComputeSpectrum(buffer + i * windowSize, windowSize,
|
||||
windowSize, rate, freq, true);
|
||||
for(j=0; j<windowSize/2; j++)
|
||||
for(size_t j = 0; j < windowSize / 2; j++)
|
||||
freqa[j] += freq[j];
|
||||
}
|
||||
argmax=0;
|
||||
for(j=1; j<windowSize/2; j++)
|
||||
size_t argmax = 0;
|
||||
for(size_t j = 1; j < windowSize / 2; j++)
|
||||
if (freqa[j] > freqa[argmax])
|
||||
argmax = j;
|
||||
|
||||
|
@ -451,7 +448,7 @@ void EffectChangePitch::DeduceFrequencies()
|
|||
delete [] freqa;
|
||||
delete [] buffer;
|
||||
|
||||
lag = (windowSize/2 - 1) - argmax;
|
||||
auto lag = (windowSize / 2 - 1) - argmax;
|
||||
m_dStartFrequency = rate / lag;
|
||||
}
|
||||
|
||||
|
|
|
@ -198,10 +198,11 @@ bool EffectClickRemoval::Process()
|
|||
|
||||
bool EffectClickRemoval::ProcessOne(int count, WaveTrack * track, sampleCount start, sampleCount len)
|
||||
{
|
||||
if (len <= windowSize/2)
|
||||
if (len <= windowSize / 2)
|
||||
{
|
||||
wxMessageBox(
|
||||
wxString::Format(_("Selection must be larger than %d samples."), windowSize/2),
|
||||
wxString::Format(_("Selection must be larger than %d samples."),
|
||||
windowSize / 2),
|
||||
GetName(),
|
||||
wxOK | wxICON_ERROR);
|
||||
return false;
|
||||
|
@ -215,27 +216,24 @@ bool EffectClickRemoval::ProcessOne(int count, WaveTrack * track, sampleCount st
|
|||
decltype(len) s = 0;
|
||||
float *buffer = new float[idealBlockLen];
|
||||
float *datawindow = new float[windowSize];
|
||||
while ((s < len) && ((len - s) > windowSize/2))
|
||||
while ((len - s) > windowSize / 2)
|
||||
{
|
||||
auto block = limitSampleBufferSize( idealBlockLen, len - s );
|
||||
|
||||
track->Get((samplePtr) buffer, floatSample, start + s, block);
|
||||
|
||||
for (int i=0; i < (block-windowSize/2); i += windowSize/2)
|
||||
for (decltype(block) i = 0; i + windowSize / 2 < block; i += windowSize / 2)
|
||||
{
|
||||
int wcopy = windowSize;
|
||||
if (i + wcopy > block)
|
||||
wcopy = block - i;
|
||||
auto wcopy = std::min( windowSize, block - i );
|
||||
|
||||
int j;
|
||||
for(j=0; j<wcopy; j++)
|
||||
for(decltype(wcopy) j = 0; j < wcopy; j++)
|
||||
datawindow[j] = buffer[i+j];
|
||||
for(j=wcopy; j<windowSize; j++)
|
||||
for(auto j = wcopy; j < windowSize; j++)
|
||||
datawindow[j] = 0;
|
||||
|
||||
mbDidSomething |= RemoveClicks(windowSize, datawindow);
|
||||
|
||||
for(j=0; j<wcopy; j++)
|
||||
for(decltype(wcopy) j = 0; j < wcopy; j++)
|
||||
buffer[i+j] = datawindow[j];
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ private:
|
|||
Envelope *mEnvelope;
|
||||
|
||||
bool mbDidSomething; // This effect usually does nothing on real-world data.
|
||||
int windowSize;
|
||||
size_t windowSize;
|
||||
int mThresholdLevel;
|
||||
int mClickWidth;
|
||||
int sep;
|
||||
|
|
|
@ -434,7 +434,9 @@ bool EffectEqualization::Startup()
|
|||
if (gPrefs->Exists(base))
|
||||
{
|
||||
// These get saved to the current preset
|
||||
gPrefs->Read(base + wxT("FilterLength"), &mM, 4001);
|
||||
int filterLength;
|
||||
gPrefs->Read(base + wxT("FilterLength"), &filterLength, 4001);
|
||||
mM = std::max(0, filterLength);
|
||||
if ((mM < 21) || (mM > 8191)) { // corrupted Prefs?
|
||||
mM = 4001; //default
|
||||
}
|
||||
|
@ -808,7 +810,7 @@ void EffectEqualization::PopulateOrExchange(ShuttleGui & S)
|
|||
S.StartHorizontalLay(wxEXPAND, 1);
|
||||
{
|
||||
S.SetStyle(wxSL_HORIZONTAL);
|
||||
mMSlider = S.Id(ID_Length).AddSlider(wxT(""), (mM -1) / 2, 4095, 10);
|
||||
mMSlider = S.Id(ID_Length).AddSlider(wxT(""), (mM - 1) / 2, 4095, 10);
|
||||
mMSlider->SetName(_("Length of Filter"));
|
||||
}
|
||||
S.EndHorizontalLay();
|
||||
|
@ -816,7 +818,7 @@ void EffectEqualization::PopulateOrExchange(ShuttleGui & S)
|
|||
S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0);
|
||||
{
|
||||
wxString label;
|
||||
label.Printf(wxT("%d"), mM);
|
||||
label.Printf(wxT("%ld"), mM);
|
||||
mMText = S.AddVariableText(label);
|
||||
mMText->SetName(label); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
|
||||
}
|
||||
|
@ -963,7 +965,7 @@ bool EffectEqualization::TransferDataToWindow()
|
|||
|
||||
mGridOnOff->SetValue( mDrawGrid ); // checks/unchecks the box on the interface
|
||||
|
||||
mMSlider->SetValue((mM-1)/2);
|
||||
mMSlider->SetValue((mM - 1) / 2);
|
||||
mM = 0; // force refresh in TransferDataFromWindow()
|
||||
|
||||
mdBMinSlider->SetValue((int)mdBMin);
|
||||
|
@ -1060,7 +1062,8 @@ bool EffectEqualization::ProcessOne(int count, WaveTrack * t,
|
|||
AudacityProject *p = GetActiveProject();
|
||||
auto output = p->GetTrackFactory()->NewWaveTrack(floatSample, t->GetRate());
|
||||
|
||||
int L = windowSize - (mM - 1); //Process L samples at a go
|
||||
wxASSERT(mM - 1 < windowSize);
|
||||
size_t L = windowSize - (mM - 1); //Process L samples at a go
|
||||
auto s = start;
|
||||
auto idealBlockLen = t->GetMaxBlockSize() * 4;
|
||||
if (idealBlockLen % L != 0)
|
||||
|
@ -1075,14 +1078,13 @@ bool EffectEqualization::ProcessOne(int count, WaveTrack * t,
|
|||
|
||||
auto originalLen = len;
|
||||
|
||||
int i,j;
|
||||
for(i=0; i<windowSize; i++)
|
||||
for(size_t i = 0; i < windowSize; i++)
|
||||
lastWindow[i] = 0;
|
||||
|
||||
TrackProgress(count, 0.);
|
||||
bool bLoopSuccess = true;
|
||||
int wcopy = 0;
|
||||
int offset = (mM - 1)/2;
|
||||
size_t wcopy = 0;
|
||||
int offset = (mM - 1) / 2;
|
||||
|
||||
while (len != 0)
|
||||
{
|
||||
|
@ -1090,20 +1092,20 @@ bool EffectEqualization::ProcessOne(int count, WaveTrack * t,
|
|||
|
||||
t->Get((samplePtr)buffer, floatSample, s, block);
|
||||
|
||||
for(i=0; i<block; i+=L) //go through block in lumps of length L
|
||||
for(size_t i = 0; i < block; i += L) //go through block in lumps of length L
|
||||
{
|
||||
wcopy = std::min <int> (L, block - i);
|
||||
for(j=0; j<wcopy; j++)
|
||||
wcopy = std::min <size_t> (L, block - i);
|
||||
for(size_t j = 0; j < wcopy; j++)
|
||||
thisWindow[j] = buffer[i+j]; //copy the L (or remaining) samples
|
||||
for(j=wcopy; j<windowSize; j++)
|
||||
for(auto j = wcopy; j < windowSize; j++)
|
||||
thisWindow[j] = 0; //this includes the padding
|
||||
|
||||
Filter(windowSize, thisWindow);
|
||||
|
||||
// Overlap - Add
|
||||
for(j=0; (j<mM-1) && (j<wcopy); j++)
|
||||
for(size_t j = 0; (j < mM - 1) && (j < wcopy); j++)
|
||||
buffer[i+j] = thisWindow[j] + lastWindow[L + j];
|
||||
for(j=mM-1; j<wcopy; j++)
|
||||
for(size_t j = mM - 1; j < wcopy; j++)
|
||||
buffer[i+j] = thisWindow[j];
|
||||
|
||||
float *tempP = thisWindow;
|
||||
|
@ -1125,20 +1127,21 @@ bool EffectEqualization::ProcessOne(int count, WaveTrack * t,
|
|||
if(bLoopSuccess)
|
||||
{
|
||||
// mM-1 samples of 'tail' left in lastWindow, get them now
|
||||
if(wcopy < (mM-1)) {
|
||||
if(wcopy < (mM - 1)) {
|
||||
// Still have some overlap left to process
|
||||
// (note that lastWindow and thisWindow have been exchanged at this point
|
||||
// so that 'thisWindow' is really the window prior to 'lastWindow')
|
||||
for(j=0; j<mM-1-wcopy; j++)
|
||||
size_t j = 0;
|
||||
for(; j < mM - 1 - wcopy; j++)
|
||||
buffer[j] = lastWindow[wcopy + j] + thisWindow[L + wcopy + j];
|
||||
// And fill in the remainder after the overlap
|
||||
for( ; j<mM-1; j++)
|
||||
for( ; j < mM - 1; j++)
|
||||
buffer[j] = lastWindow[wcopy + j];
|
||||
} else {
|
||||
for(j=0; j<mM-1; j++)
|
||||
for(size_t j = 0; j < mM - 1; j++)
|
||||
buffer[j] = lastWindow[wcopy + j];
|
||||
}
|
||||
output->Append((samplePtr)buffer, floatSample, mM-1);
|
||||
output->Append((samplePtr)buffer, floatSample, mM - 1);
|
||||
output->Flush();
|
||||
|
||||
// now move the appropriate bit of the output back to the track
|
||||
|
@ -1182,7 +1185,7 @@ bool EffectEqualization::ProcessOne(int count, WaveTrack * t,
|
|||
clipStartEndTimes.push_back(std::pair<double,double>(clipStartT,clipEndT));
|
||||
}
|
||||
//now go thru and replace the old clips with NEW
|
||||
for(unsigned int i=0;i<clipStartEndTimes.size();i++)
|
||||
for(unsigned int i = 0; i < clipStartEndTimes.size(); i++)
|
||||
{
|
||||
//remove the old audio and get the NEW
|
||||
t->Clear(clipStartEndTimes[i].first,clipStartEndTimes[i].second);
|
||||
|
@ -1217,7 +1220,7 @@ bool EffectEqualization::CalcFilter()
|
|||
double hiLog = log10(mHiFreq);
|
||||
double denom = hiLog - loLog;
|
||||
|
||||
double delta = mHiFreq / ((double)(mWindowSize/2.));
|
||||
double delta = mHiFreq / ((double)(mWindowSize / 2.));
|
||||
double val0;
|
||||
double val1;
|
||||
|
||||
|
@ -1234,8 +1237,7 @@ bool EffectEqualization::CalcFilter()
|
|||
mFilterFuncR[0] = val0;
|
||||
double freq = delta;
|
||||
|
||||
int i;
|
||||
for(i=1; i<=mWindowSize/2; i++)
|
||||
for(size_t i = 1; i <= mWindowSize / 2; i++)
|
||||
{
|
||||
double when;
|
||||
if( IsLinear() )
|
||||
|
@ -1259,55 +1261,68 @@ bool EffectEqualization::CalcFilter()
|
|||
}
|
||||
freq += delta;
|
||||
}
|
||||
mFilterFuncR[mWindowSize/2] = val1;
|
||||
mFilterFuncR[mWindowSize / 2] = val1;
|
||||
|
||||
mFilterFuncR[0] = DB_TO_LINEAR(mFilterFuncR[0]);
|
||||
for(i=1;i<mWindowSize/2;i++)
|
||||
|
||||
{
|
||||
mFilterFuncR[i] = DB_TO_LINEAR(mFilterFuncR[i]);
|
||||
mFilterFuncR[mWindowSize-i]=mFilterFuncR[i]; //Fill entire array
|
||||
size_t i = 1;
|
||||
for(; i < mWindowSize / 2; i++)
|
||||
{
|
||||
mFilterFuncR[i] = DB_TO_LINEAR(mFilterFuncR[i]);
|
||||
mFilterFuncR[mWindowSize - i] = mFilterFuncR[i]; //Fill entire array
|
||||
}
|
||||
mFilterFuncR[i] = DB_TO_LINEAR(mFilterFuncR[i]); //do last one
|
||||
}
|
||||
mFilterFuncR[i] = DB_TO_LINEAR(mFilterFuncR[i]); //do last one
|
||||
|
||||
//transfer to time domain to do the padding and windowing
|
||||
float *outr = new float[mWindowSize];
|
||||
float *outi = new float[mWindowSize];
|
||||
InverseRealFFT(mWindowSize, mFilterFuncR, NULL, outr); // To time domain
|
||||
|
||||
for(i=0;i<=(mM-1)/2;i++)
|
||||
{ //Windowing - could give a choice, fixed for now - MJS
|
||||
// double mult=0.54-0.46*cos(2*M_PI*(i+(mM-1)/2.0)/(mM-1)); //Hamming
|
||||
//Blackman
|
||||
double mult=0.42-0.5*cos(2*M_PI*(i+(mM-1)/2.0)/(mM-1))+.08*cos(4*M_PI*(i+(mM-1)/2.0)/(mM-1));
|
||||
outr[i]*=mult;
|
||||
if(i!=0){
|
||||
outr[mWindowSize-i]*=mult;
|
||||
{
|
||||
size_t i = 0;
|
||||
for(; i <= (mM - 1) / 2; i++)
|
||||
{ //Windowing - could give a choice, fixed for now - MJS
|
||||
// double mult=0.54-0.46*cos(2*M_PI*(i+(mM-1)/2.0)/(mM-1)); //Hamming
|
||||
//Blackman
|
||||
double mult =
|
||||
0.42 -
|
||||
0.5 * cos(2 * M_PI * (i + (mM - 1) / 2.0) / (mM - 1)) +
|
||||
.08 * cos(4 * M_PI * (i + (mM - 1) / 2.0) / (mM - 1));
|
||||
outr[i] *= mult;
|
||||
if(i != 0){
|
||||
outr[mWindowSize - i] *= mult;
|
||||
}
|
||||
}
|
||||
for(; i <= mWindowSize / 2; i++)
|
||||
{ //Padding
|
||||
outr[i] = 0;
|
||||
outr[mWindowSize - i] = 0;
|
||||
}
|
||||
}
|
||||
for(;i<=mWindowSize/2;i++)
|
||||
{ //Padding
|
||||
outr[i]=0;
|
||||
outr[mWindowSize-i]=0;
|
||||
}
|
||||
float *tempr = new float[mM];
|
||||
for(i=0;i<(mM-1)/2;i++)
|
||||
{ //shift so that padding on right
|
||||
tempr[(mM-1)/2+i]=outr[i];
|
||||
tempr[i]=outr[mWindowSize-(mM-1)/2+i];
|
||||
{
|
||||
size_t i = 0;
|
||||
for(; i < (mM - 1) / 2; i++)
|
||||
{ //shift so that padding on right
|
||||
tempr[(mM - 1) / 2 + i] = outr[i];
|
||||
tempr[i] = outr[mWindowSize - (mM - 1) / 2 + i];
|
||||
}
|
||||
tempr[(mM - 1) / 2 + i] = outr[i];
|
||||
}
|
||||
tempr[(mM-1)/2+i]=outr[i];
|
||||
|
||||
for(i=0;i<mM;i++)
|
||||
for(size_t i = 0; i < mM; i++)
|
||||
{ //and copy useful values back
|
||||
outr[i]=tempr[i];
|
||||
outr[i] = tempr[i];
|
||||
}
|
||||
for(i=mM;i<mWindowSize;i++)
|
||||
for(size_t i = mM; i < mWindowSize; i++)
|
||||
{ //rest is padding
|
||||
outr[i]=0.;
|
||||
}
|
||||
|
||||
//Back to the frequency domain so we can use it
|
||||
RealFFT(mWindowSize,outr,mFilterFuncR,mFilterFuncI);
|
||||
RealFFT(mWindowSize, outr, mFilterFuncR, mFilterFuncI);
|
||||
|
||||
delete[] outr;
|
||||
delete[] outi;
|
||||
|
@ -1316,9 +1331,8 @@ bool EffectEqualization::CalcFilter()
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void EffectEqualization::Filter(sampleCount len, float *buffer)
|
||||
void EffectEqualization::Filter(size_t len, float *buffer)
|
||||
{
|
||||
int i;
|
||||
float re,im;
|
||||
// Apply FFT
|
||||
RealFFTf(buffer, hFFT);
|
||||
|
@ -1327,7 +1341,7 @@ void EffectEqualization::Filter(sampleCount len, float *buffer)
|
|||
// Apply filter
|
||||
// DC component is purely real
|
||||
mFFTBuffer[0] = buffer[0] * mFilterFuncR[0];
|
||||
for(i=1; i<(len/2); i++)
|
||||
for(size_t i = 1; i < (len / 2); i++)
|
||||
{
|
||||
re=buffer[hFFT->BitReversed[i] ];
|
||||
im=buffer[hFFT->BitReversed[i]+1];
|
||||
|
@ -3021,7 +3035,7 @@ void EqualizationPanel::OnPaint(wxPaintEvent & WXUNUSED(event))
|
|||
memDC.SetPen(wxPen(theTheme.Colour( clrResponseLines ), 1, wxSOLID));
|
||||
double scale = (double)mEnvRect.height/(mEffect->mdBMax-mEffect->mdBMin); //pixels per dB
|
||||
double yF; //gain at this freq
|
||||
double delta = mEffect->mHiFreq/(((double)mEffect->mWindowSize/2.)); //size of each freq bin
|
||||
double delta = mEffect->mHiFreq / (((double)mEffect->mWindowSize / 2.)); //size of each freq bin
|
||||
|
||||
bool lin = mEffect->IsLinear(); // log or lin scale?
|
||||
|
||||
|
@ -3029,7 +3043,7 @@ void EqualizationPanel::OnPaint(wxPaintEvent & WXUNUSED(event))
|
|||
double step = lin ? mEffect->mHiFreq : (log10(mEffect->mHiFreq) - loLog);
|
||||
step /= ((double)mEnvRect.width-1.);
|
||||
double freq; //actual freq corresponding to x position
|
||||
int halfM = (mEffect->mM-1)/2;
|
||||
int halfM = (mEffect->mM - 1) / 2;
|
||||
int n; //index to mFreqFunc
|
||||
for(int i=0; i<mEnvRect.width; i++)
|
||||
{
|
||||
|
|
|
@ -124,7 +124,7 @@ private:
|
|||
// EffectEqualization implementation
|
||||
|
||||
// Number of samples in an FFT window
|
||||
enum {windowSize=16384}; //MJS - work out the optimum for this at run time? Have a dialog box for it?
|
||||
enum : size_t {windowSize=16384}; //MJS - work out the optimum for this at run time? Have a dialog box for it?
|
||||
|
||||
// Low frequency of the FFT. 20Hz is the
|
||||
// low range of human hearing
|
||||
|
@ -133,7 +133,7 @@ private:
|
|||
bool ProcessOne(int count, WaveTrack * t,
|
||||
sampleCount start, sampleCount len);
|
||||
bool CalcFilter();
|
||||
void Filter(sampleCount len, float *buffer);
|
||||
void Filter(size_t len, float *buffer);
|
||||
|
||||
void Flatten();
|
||||
void ForceRecalc();
|
||||
|
@ -193,7 +193,7 @@ private:
|
|||
float *mFFTBuffer;
|
||||
float *mFilterFuncR;
|
||||
float *mFilterFuncI;
|
||||
int mM;
|
||||
size_t mM;
|
||||
wxString mCurveName;
|
||||
bool mLin;
|
||||
float mdBMax;
|
||||
|
@ -212,7 +212,7 @@ private:
|
|||
bool mDisallowCustom;
|
||||
double mLoFreq;
|
||||
double mHiFreq;
|
||||
long mWindowSize;
|
||||
size_t mWindowSize;
|
||||
bool mDirty;
|
||||
int mSlidersOld[NUMBER_OF_BANDS];
|
||||
double mEQVals[NUMBER_OF_BANDS+1];
|
||||
|
@ -315,7 +315,7 @@ private:
|
|||
wxRect mEnvRect;
|
||||
int mWidth;
|
||||
int mHeight;
|
||||
// long mWindowSize;
|
||||
// size_t mWindowSize;
|
||||
// float *mFilterFuncR;
|
||||
// float *mFilterFuncI;
|
||||
float *mOutr;
|
||||
|
|
|
@ -180,6 +180,7 @@ bool EffectEqualization48x::AllocateBuffersWorkers(int nThreads)
|
|||
FreeBuffersWorkers();
|
||||
mFilterSize=(mEffectEqualization->mM-1)&(~15); // 4000 !!! Filter MUST BE QUAD WORD ALIGNED !!!!
|
||||
mWindowSize=mEffectEqualization->windowSize;
|
||||
wxASSERT(mFilterSize < mWindowSize);
|
||||
mBlockSize=mWindowSize-mFilterSize; // 12,384
|
||||
mThreaded = (nThreads > 0 );
|
||||
if(mThreaded)
|
||||
|
@ -680,7 +681,7 @@ bool EffectEqualization48x::ProcessOne1x(int count, WaveTrack * t,
|
|||
return bBreakLoop;
|
||||
}
|
||||
|
||||
void EffectEqualization48x::Filter1x(sampleCount len,
|
||||
void EffectEqualization48x::Filter1x(size_t len,
|
||||
float *buffer, float *scratchBuffer)
|
||||
{
|
||||
int i;
|
||||
|
@ -692,13 +693,13 @@ void EffectEqualization48x::Filter1x(sampleCount len,
|
|||
// DC component is purely real
|
||||
|
||||
float filterFuncR, filterFuncI;
|
||||
filterFuncR=mEffectEqualization->mFilterFuncR[0];
|
||||
scratchBuffer[0]=buffer[0]*filterFuncR;
|
||||
int halfLength=(len/2);
|
||||
filterFuncR = mEffectEqualization->mFilterFuncR[0];
|
||||
scratchBuffer[0] = buffer[0] * filterFuncR;
|
||||
auto halfLength = (len / 2);
|
||||
|
||||
bool useBitReverseTable=sMathPath&1;
|
||||
|
||||
for(i=1; i<halfLength; i++)
|
||||
for(i = 1; i < halfLength; i++)
|
||||
{
|
||||
if(useBitReverseTable) {
|
||||
real=buffer[mEffectEqualization->hFFT->BitReversed[i] ];
|
||||
|
@ -973,7 +974,7 @@ bool EffectEqualization48x::ProcessOne1x4xThreaded(int count, WaveTrack * t,
|
|||
return bBreakLoop;
|
||||
}
|
||||
|
||||
void EffectEqualization48x::Filter4x(sampleCount len,
|
||||
void EffectEqualization48x::Filter4x(size_t len,
|
||||
float *buffer, float *scratchBuffer)
|
||||
{
|
||||
int i;
|
||||
|
@ -987,13 +988,13 @@ void EffectEqualization48x::Filter4x(sampleCount len,
|
|||
__m128 *localBuffer=(__m128 *)buffer;
|
||||
|
||||
__m128 filterFuncR, filterFuncI;
|
||||
filterFuncR=_mm_set1_ps(mEffectEqualization->mFilterFuncR[0]);
|
||||
localFFTBuffer[0]=_mm_mul_ps(localBuffer[0], filterFuncR);
|
||||
int halfLength=(len/2);
|
||||
filterFuncR = _mm_set1_ps(mEffectEqualization->mFilterFuncR[0]);
|
||||
localFFTBuffer[0] = _mm_mul_ps(localBuffer[0], filterFuncR);
|
||||
auto halfLength = (len / 2);
|
||||
|
||||
bool useBitReverseTable=sMathPath&1;
|
||||
bool useBitReverseTable = sMathPath & 1;
|
||||
|
||||
for(i=1; i<halfLength; i++)
|
||||
for(i = 1; i < halfLength; i++)
|
||||
{
|
||||
if(useBitReverseTable) {
|
||||
real128=localBuffer[mEffectEqualization->hFFT->BitReversed[i] ];
|
||||
|
@ -1273,7 +1274,7 @@ bool EffectEqualization48x::ProcessOne8xThreaded(int count, WaveTrack * t,
|
|||
|
||||
|
||||
|
||||
void EffectEqualization48x::Filter8x(sampleCount len,
|
||||
void EffectEqualization48x::Filter8x(size_t len,
|
||||
float *buffer, float *scratchBuffer)
|
||||
{
|
||||
int i;
|
||||
|
@ -1287,13 +1288,13 @@ void EffectEqualization48x::Filter8x(sampleCount len,
|
|||
__m256 *localBuffer=(__m256 *)buffer;
|
||||
|
||||
__m256 filterFuncR, filterFuncI;
|
||||
filterFuncR=_mm256_set1_ps(mEffectEqualization->mFilterFuncR[0]);
|
||||
localFFTBuffer[0]=_mm256_mul_ps(localBuffer[0], filterFuncR);
|
||||
int halfLength=(len/2);
|
||||
filterFuncR = _mm256_set1_ps(mEffectEqualization->mFilterFuncR[0]);
|
||||
localFFTBuffer[0] = _mm256_mul_ps(localBuffer[0], filterFuncR);
|
||||
auto halfLength = (len / 2);
|
||||
|
||||
bool useBitReverseTable=sMathPath&1;
|
||||
bool useBitReverseTable = sMathPath & 1;
|
||||
|
||||
for(i=1; i<halfLength; i++)
|
||||
for(i = 1; i < halfLength; i++)
|
||||
{
|
||||
if(useBitReverseTable) {
|
||||
real256=localBuffer[mEffectEqualization->hFFT->BitReversed[i] ];
|
||||
|
|
|
@ -130,25 +130,25 @@ private:
|
|||
bool ProcessBuffer(fft_type *sourceBuffer, fft_type *destBuffer, sampleCount bufferLength);
|
||||
bool ProcessBuffer1x(BufferInfo *bufferInfo);
|
||||
bool ProcessOne1x(int count, WaveTrack * t, sampleCount start, sampleCount len);
|
||||
void Filter1x(sampleCount len, float *buffer, float *scratchBuffer);
|
||||
void Filter1x(size_t len, float *buffer, float *scratchBuffer);
|
||||
|
||||
bool ProcessBuffer4x(BufferInfo *bufferInfo);
|
||||
bool ProcessOne4x(int count, WaveTrack * t, sampleCount start, sampleCount len);
|
||||
bool ProcessOne1x4xThreaded(int count, WaveTrack * t, sampleCount start, sampleCount len, int processingType=4);
|
||||
void Filter4x(sampleCount len, float *buffer, float *scratchBuffer);
|
||||
void Filter4x(size_t len, float *buffer, float *scratchBuffer);
|
||||
|
||||
#ifdef __AVX_ENABLED
|
||||
bool ProcessBuffer8x(BufferInfo *bufferInfo);
|
||||
bool ProcessOne8x(int count, WaveTrack * t, sampleCount start, sampleCount len);
|
||||
bool ProcessOne8xThreaded(int count, WaveTrack * t, sampleCount start, sampleCount len);
|
||||
void Filter8x(sampleCount len, float *buffer, float *scratchBuffer);
|
||||
void Filter8x(size_t len, float *buffer, float *scratchBuffer);
|
||||
#endif
|
||||
|
||||
EffectEqualization* mEffectEqualization;
|
||||
int mThreadCount;
|
||||
sampleCount mFilterSize;
|
||||
sampleCount mBlockSize;
|
||||
sampleCount mWindowSize;
|
||||
size_t mFilterSize;
|
||||
size_t mBlockSize;
|
||||
size_t mWindowSize;
|
||||
int mBufferCount;
|
||||
int mWorkerDataCount;
|
||||
int mBlocksPerBuffer;
|
||||
|
|
|
@ -121,7 +121,7 @@ enum WindowTypes {
|
|||
|
||||
const struct WindowTypesInfo {
|
||||
const wxChar *name;
|
||||
int minSteps;
|
||||
unsigned minSteps;
|
||||
double inCoefficients[3];
|
||||
double outCoefficients[3];
|
||||
double productConstantTerm;
|
||||
|
@ -159,7 +159,7 @@ enum NoiseReductionChoice {
|
|||
class EffectNoiseReduction::Statistics
|
||||
{
|
||||
public:
|
||||
Statistics(int spectrumSize, double rate, int windowTypes)
|
||||
Statistics(size_t spectrumSize, double rate, int windowTypes)
|
||||
: mRate(rate)
|
||||
, mWindowSize((spectrumSize - 1) * 2)
|
||||
, mWindowTypes(windowTypes)
|
||||
|
@ -175,7 +175,7 @@ public:
|
|||
// Noise profile statistics follow
|
||||
|
||||
double mRate; // Rate of profile track(s) -- processed tracks must match
|
||||
int mWindowSize;
|
||||
size_t mWindowSize;
|
||||
int mWindowTypes;
|
||||
|
||||
int mTotalWindows;
|
||||
|
@ -206,8 +206,8 @@ public:
|
|||
bool PrefsIO(bool read);
|
||||
bool Validate() const;
|
||||
|
||||
int WindowSize() const { return 1 << (3 + mWindowSizeChoice); }
|
||||
int StepsPerWindow() const { return 1 << (1 + mStepsPerWindowChoice); }
|
||||
size_t WindowSize() const { return 1u << (3 + mWindowSizeChoice); }
|
||||
unsigned StepsPerWindow() const { return 1u << (1 + mStepsPerWindowChoice); }
|
||||
|
||||
bool mDoProfile;
|
||||
|
||||
|
@ -286,7 +286,7 @@ private:
|
|||
|
||||
const double mSampleRate;
|
||||
|
||||
const int mWindowSize;
|
||||
const size_t mWindowSize;
|
||||
// These have that size:
|
||||
HFFT hFFT;
|
||||
FloatVector mFFTBuffer;
|
||||
|
@ -296,16 +296,16 @@ private:
|
|||
FloatVector mInWindow;
|
||||
FloatVector mOutWindow;
|
||||
|
||||
const int mSpectrumSize;
|
||||
const size_t mSpectrumSize;
|
||||
FloatVector mFreqSmoothingScratch;
|
||||
const int mFreqSmoothingBins;
|
||||
const size_t mFreqSmoothingBins;
|
||||
// When spectral selection limits the affected band:
|
||||
int mBinLow; // inclusive lower bound
|
||||
int mBinHigh; // exclusive upper bound
|
||||
|
||||
const int mNoiseReductionChoice;
|
||||
const int mStepsPerWindow;
|
||||
const int mStepSize;
|
||||
const unsigned mStepsPerWindow;
|
||||
const size_t mStepSize;
|
||||
const int mMethod;
|
||||
const double mNewSensitivity;
|
||||
|
||||
|
@ -319,13 +319,13 @@ private:
|
|||
float mNoiseAttenFactor;
|
||||
float mOldSensitivityFactor;
|
||||
|
||||
int mNWindowsToExamine;
|
||||
int mCenter;
|
||||
int mHistoryLen;
|
||||
unsigned mNWindowsToExamine;
|
||||
unsigned mCenter;
|
||||
unsigned mHistoryLen;
|
||||
|
||||
struct Record
|
||||
{
|
||||
Record(int spectrumSize)
|
||||
Record(size_t spectrumSize)
|
||||
: mSpectrums(spectrumSize)
|
||||
, mGains(spectrumSize)
|
||||
, mRealFFTs(spectrumSize - 1)
|
||||
|
@ -608,7 +608,7 @@ bool EffectNoiseReduction::Process()
|
|||
// Initialize statistics if gathering them, or check for mismatched (advanced)
|
||||
// settings if reducing noise.
|
||||
if (mSettings->mDoProfile) {
|
||||
int spectrumSize = 1 + mSettings->WindowSize() / 2;
|
||||
size_t spectrumSize = 1 + mSettings->WindowSize() / 2;
|
||||
mStatistics = std::make_unique<Statistics>
|
||||
(spectrumSize, track->GetRate(), mSettings->mWindowTypes);
|
||||
}
|
||||
|
@ -704,7 +704,7 @@ void EffectNoiseReduction::Worker::ApplyFreqSmoothing(FloatVector &gains)
|
|||
gains[ii] = log(gains[ii]);
|
||||
|
||||
for (int ii = 0; ii < mSpectrumSize; ++ii) {
|
||||
const int j0 = std::max(0, ii - mFreqSmoothingBins);
|
||||
const int j0 = std::max(0, ii - (int)mFreqSmoothingBins);
|
||||
const int j1 = std::min(mSpectrumSize - 1, ii + mFreqSmoothingBins);
|
||||
for(int jj = j0; jj <= j1; ++jj) {
|
||||
mFreqSmoothingScratch[ii] += gains[jj];
|
||||
|
@ -763,8 +763,8 @@ EffectNoiseReduction::Worker::Worker
|
|||
#endif
|
||||
|
||||
const double noiseGain = -settings.mNoiseGain;
|
||||
const int nAttackBlocks = 1 + (int)(settings.mAttackTime * sampleRate / mStepSize);
|
||||
const int nReleaseBlocks = 1 + (int)(settings.mReleaseTime * sampleRate / mStepSize);
|
||||
const unsigned nAttackBlocks = 1 + (int)(settings.mAttackTime * sampleRate / mStepSize);
|
||||
const unsigned nReleaseBlocks = 1 + (int)(settings.mReleaseTime * sampleRate / mStepSize);
|
||||
// Applies to amplitudes, divide by 20:
|
||||
mNoiseAttenFactor = DB_TO_LINEAR(noiseGain);
|
||||
// Apply to gain factors which apply to amplitudes, divide by 20:
|
||||
|
@ -794,7 +794,7 @@ EffectNoiseReduction::Worker::Worker
|
|||
}
|
||||
|
||||
mQueue.resize(mHistoryLen);
|
||||
for (int ii = 0; ii < mHistoryLen; ++ii)
|
||||
for (unsigned ii = 0; ii < mHistoryLen; ++ii)
|
||||
mQueue[ii] = make_movable<Record>(mSpectrumSize);
|
||||
|
||||
// Create windows
|
||||
|
@ -823,7 +823,7 @@ EffectNoiseReduction::Worker::Worker
|
|||
const double c1 = coefficients[1];
|
||||
const double c2 = coefficients[2];
|
||||
mInWindow.resize(mWindowSize);
|
||||
for (int ii = 0; ii < mWindowSize; ++ii)
|
||||
for (size_t ii = 0; ii < mWindowSize; ++ii)
|
||||
mInWindow[ii] = m *
|
||||
(c0 + c1 * cos((2.0*M_PI*ii) / mWindowSize)
|
||||
+ c2 * cos((4.0*M_PI*ii) / mWindowSize));
|
||||
|
@ -840,7 +840,7 @@ EffectNoiseReduction::Worker::Worker
|
|||
case WT_HAMMING_INV_HAMMING:
|
||||
{
|
||||
mOutWindow.resize(mWindowSize);
|
||||
for (int ii = 0; ii < mWindowSize; ++ii)
|
||||
for (size_t ii = 0; ii < mWindowSize; ++ii)
|
||||
mOutWindow[ii] = multiplier / mInWindow[ii];
|
||||
}
|
||||
break;
|
||||
|
@ -852,10 +852,10 @@ EffectNoiseReduction::Worker::Worker
|
|||
const double c1 = coefficients[1];
|
||||
const double c2 = coefficients[2];
|
||||
mOutWindow.resize(mWindowSize);
|
||||
for (int ii = 0; ii < mWindowSize; ++ii)
|
||||
for (size_t ii = 0; ii < mWindowSize; ++ii)
|
||||
mOutWindow[ii] = multiplier *
|
||||
(c0 + c1 * cos((2.0*M_PI*ii) / mWindowSize)
|
||||
+ c2 * cos((4.0*M_PI*ii) / mWindowSize));
|
||||
(c0 + c1 * cos((2.0 * M_PI * ii) / mWindowSize)
|
||||
+ c2 * cos((4.0 * M_PI * ii) / mWindowSize));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -865,7 +865,7 @@ EffectNoiseReduction::Worker::Worker
|
|||
void EffectNoiseReduction::Worker::StartNewTrack()
|
||||
{
|
||||
float *pFill;
|
||||
for(int ii = 0; ii < mHistoryLen; ++ii) {
|
||||
for(unsigned ii = 0; ii < mHistoryLen; ++ii) {
|
||||
Record &record = *mQueue[ii];
|
||||
|
||||
pFill = &record.mSpectrums[0];
|
||||
|
@ -891,7 +891,7 @@ void EffectNoiseReduction::Worker::StartNewTrack()
|
|||
{
|
||||
// We do not want leading zero padded windows
|
||||
mInWavePos = 0;
|
||||
mOutStepCount = -(mHistoryLen - 1);
|
||||
mOutStepCount = -(int)(mHistoryLen - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -900,7 +900,7 @@ void EffectNoiseReduction::Worker::StartNewTrack()
|
|||
// samples of wave data:
|
||||
mInWavePos = mWindowSize - mStepSize;
|
||||
// This starts negative, to count up until the queue fills:
|
||||
mOutStepCount = -(mHistoryLen - 1)
|
||||
mOutStepCount = -(int)(mHistoryLen - 1)
|
||||
// ... and then must pass over the padded windows,
|
||||
// before the first full window:
|
||||
- (mStepsPerWindow - 1);
|
||||
|
@ -914,7 +914,7 @@ void EffectNoiseReduction::Worker::ProcessSamples
|
|||
sampleCount len, float *buffer)
|
||||
{
|
||||
while (len && mOutStepCount * mStepSize < mInSampleCount) {
|
||||
int avail = std::min(int(len), mWindowSize - mInWavePos);
|
||||
auto avail = std::min(len, sampleCount(mWindowSize - mInWavePos));
|
||||
memmove(&mInWaveBuffer[mInWavePos], buffer, avail * sizeof(float));
|
||||
buffer += avail;
|
||||
len -= avail;
|
||||
|
@ -941,7 +941,7 @@ void EffectNoiseReduction::Worker::FillFirstHistoryWindow()
|
|||
{
|
||||
// Transform samples to frequency domain, windowed as needed
|
||||
if (mInWindow.size() > 0)
|
||||
for (int ii = 0; ii < mWindowSize; ++ii)
|
||||
for (size_t ii = 0; ii < mWindowSize; ++ii)
|
||||
mFFTBuffer[ii] = mInWaveBuffer[ii] * mInWindow[ii];
|
||||
else
|
||||
memmove(&mFFTBuffer[0], &mInWaveBuffer[0], mWindowSize * sizeof(float));
|
||||
|
@ -956,7 +956,7 @@ void EffectNoiseReduction::Worker::FillFirstHistoryWindow()
|
|||
float *pImag = &record.mImagFFTs[1];
|
||||
float *pPower = &record.mSpectrums[1];
|
||||
int *pBitReversed = &hFFT->BitReversed[1];
|
||||
const int last = mSpectrumSize - 1;
|
||||
const auto last = mSpectrumSize - 1;
|
||||
for (int ii = 1; ii < last; ++ii) {
|
||||
const int kk = *pBitReversed++;
|
||||
const float realPart = *pReal++ = mFFTBuffer[kk];
|
||||
|
@ -1043,7 +1043,7 @@ void EffectNoiseReduction::Worker::GatherStatistics(Statistics &statistics)
|
|||
// level achieved at that frequency for a minimum of
|
||||
// mMinSignalBlocks blocks in a row - the max of a min.
|
||||
|
||||
int finish = mHistoryLen;
|
||||
auto finish = mHistoryLen;
|
||||
|
||||
{
|
||||
// old statistics
|
||||
|
@ -1051,7 +1051,7 @@ void EffectNoiseReduction::Worker::GatherStatistics(Statistics &statistics)
|
|||
float *pThreshold = &statistics.mNoiseThreshold[0];
|
||||
for (int jj = 0; jj < mSpectrumSize; ++jj) {
|
||||
float min = *pPower++;
|
||||
for (int ii = 1; ii < finish; ++ii)
|
||||
for (unsigned ii = 1; ii < finish; ++ii)
|
||||
min = std::min(min, mQueue[ii]->mSpectrums[jj]);
|
||||
*pThreshold = std::max(*pThreshold, min);
|
||||
++pThreshold;
|
||||
|
@ -1070,7 +1070,7 @@ bool EffectNoiseReduction::Worker::Classify(const Statistics &statistics, int ba
|
|||
case DM_OLD_METHOD:
|
||||
{
|
||||
float min = mQueue[0]->mSpectrums[band];
|
||||
for (int ii = 1; ii < mNWindowsToExamine; ++ii)
|
||||
for (unsigned ii = 1; ii < mNWindowsToExamine; ++ii)
|
||||
min = std::min(min, mQueue[ii]->mSpectrums[band]);
|
||||
return min <= mOldSensitivityFactor * statistics.mNoiseThreshold[band];
|
||||
}
|
||||
|
@ -1094,7 +1094,7 @@ bool EffectNoiseReduction::Worker::Classify(const Statistics &statistics, int ba
|
|||
else if (mNWindowsToExamine == 5)
|
||||
{
|
||||
float greatest = 0.0, second = 0.0, third = 0.0;
|
||||
for (int ii = 0; ii < mNWindowsToExamine; ++ii) {
|
||||
for (unsigned ii = 0; ii < mNWindowsToExamine; ++ii) {
|
||||
const float power = mQueue[ii]->mSpectrums[band];
|
||||
if (power >= greatest)
|
||||
third = second, second = greatest, greatest = power;
|
||||
|
@ -1116,7 +1116,7 @@ bool EffectNoiseReduction::Worker::Classify(const Statistics &statistics, int ba
|
|||
// should be less prone to distortions and more prone to
|
||||
// chimes.
|
||||
float greatest = 0.0, second = 0.0;
|
||||
for (int ii = 0; ii < mNWindowsToExamine; ++ii) {
|
||||
for (unsigned ii = 0; ii < mNWindowsToExamine; ++ii) {
|
||||
const float power = mQueue[ii]->mSpectrums[band];
|
||||
if (power >= greatest)
|
||||
second = greatest, greatest = power;
|
||||
|
@ -1171,7 +1171,7 @@ void EffectNoiseReduction::Worker::ReduceNoise
|
|||
// First, the attack, which goes backward in time, which is,
|
||||
// toward higher indices in the queue.
|
||||
for (int jj = 0; jj < mSpectrumSize; ++jj) {
|
||||
for (int ii = mCenter + 1; ii < mHistoryLen; ++ii) {
|
||||
for (unsigned ii = mCenter + 1; ii < mHistoryLen; ++ii) {
|
||||
const float minimum =
|
||||
std::max(mNoiseAttenFactor,
|
||||
mQueue[ii - 1]->mGains[jj] * mOneBlockAttack);
|
||||
|
@ -1204,7 +1204,7 @@ void EffectNoiseReduction::Worker::ReduceNoise
|
|||
|
||||
if (mOutStepCount >= -(mStepsPerWindow - 1)) {
|
||||
Record &record = *mQueue[mHistoryLen - 1]; // end of the queue
|
||||
const int last = mSpectrumSize - 1;
|
||||
const auto last = mSpectrumSize - 1;
|
||||
|
||||
if (mNoiseReductionChoice != NRC_ISOLATE_NOISE)
|
||||
// Apply frequency smoothing to output gain
|
||||
|
@ -1217,7 +1217,7 @@ void EffectNoiseReduction::Worker::ReduceNoise
|
|||
const float *pReal = &record.mRealFFTs[1];
|
||||
const float *pImag = &record.mImagFFTs[1];
|
||||
float *pBuffer = &mFFTBuffer[2];
|
||||
int nn = mSpectrumSize - 2;
|
||||
auto nn = mSpectrumSize - 2;
|
||||
if (mNoiseReductionChoice == NRC_LEAVE_RESIDUE) {
|
||||
for (; nn--;) {
|
||||
// Subtract the gain we would otherwise apply from 1, and
|
||||
|
@ -1273,7 +1273,7 @@ void EffectNoiseReduction::Worker::ReduceNoise
|
|||
}
|
||||
|
||||
// Shift the remainder over.
|
||||
memmove(buffer, buffer + mStepSize, sizeof(float)*(mWindowSize - mStepSize));
|
||||
memmove(buffer, buffer + mStepSize, sizeof(float) * (mWindowSize - mStepSize));
|
||||
std::fill(buffer + mWindowSize - mStepSize, buffer + mWindowSize, 0.0f);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -363,7 +363,7 @@ void EffectNoiseRemoval::StartNewTrack()
|
|||
|
||||
mInputPos = 0;
|
||||
mInSampleCount = 0;
|
||||
mOutSampleCount = -(mWindowSize / 2) * (mHistoryLen - 1);
|
||||
mOutSampleCount = -(int)((mWindowSize / 2) * (mHistoryLen - 1));
|
||||
}
|
||||
|
||||
void EffectNoiseRemoval::ProcessSamples(sampleCount len, float *buffer)
|
||||
|
|
|
@ -69,7 +69,7 @@ private:
|
|||
|
||||
// Parameters chosen before the first phase
|
||||
double mSampleRate;
|
||||
int mWindowSize;
|
||||
size_t mWindowSize;
|
||||
int mSpectrumSize;
|
||||
float mMinSignalTime; // in secs
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ for classification of the sample format and the used endianness.
|
|||
#include <wx/defs.h>
|
||||
|
||||
#include "MultiFormatReader.h"
|
||||
#include "SpecPowerMeter.h"
|
||||
#include "sndfile.h"
|
||||
|
||||
FormatClassifier::FormatClassifier(const char* filename) :
|
||||
|
|
|
@ -52,7 +52,6 @@ and sample size to help you importing data of an unknown format.
|
|||
|
||||
// #include "RawAudioGuess.h"
|
||||
#include "MultiFormatReader.h"
|
||||
#include "SpecPowerMeter.h"
|
||||
#include "FormatClassifier.h"
|
||||
|
||||
#include "sndfile.h"
|
||||
|
|
|
@ -24,10 +24,10 @@ measurements in subbands or in the entire signal band.
|
|||
|
||||
#include "../FFT.h"
|
||||
|
||||
SpecPowerMeter::SpecPowerMeter(int sigLen)
|
||||
SpecPowerMeter::SpecPowerMeter(size_t sigLen)
|
||||
: mSigLen(sigLen)
|
||||
{
|
||||
mSigLen = sigLen;
|
||||
|
||||
|
||||
// Init buffers
|
||||
mSigI = new float[sigLen];
|
||||
mSigFR = new float[sigLen];
|
||||
|
@ -85,7 +85,7 @@ int SpecPowerMeter::Freq2Bin(float fc)
|
|||
|
||||
// There is no round() in (older) MSVSs ...
|
||||
bin = floor((double)fc * mSigLen);
|
||||
bin %= mSigLen;
|
||||
bin %= (int)mSigLen;
|
||||
|
||||
return bin;
|
||||
}
|
||||
|
|
|
@ -11,9 +11,11 @@
|
|||
#ifndef __AUDACITY_SPECPOWERMETER_H_
|
||||
#define __AUDACITY_SPECPOWERMETER_H_
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
class SpecPowerMeter
|
||||
{
|
||||
int mSigLen;
|
||||
const size_t mSigLen;
|
||||
|
||||
float* mSigI;
|
||||
float* mSigFR;
|
||||
|
@ -22,7 +24,7 @@ class SpecPowerMeter
|
|||
float CalcBinPower(float* sig_f_r, float* sig_f_i, int loBin, int hiBin);
|
||||
int Freq2Bin(float fc);
|
||||
public:
|
||||
SpecPowerMeter(int sigLen);
|
||||
SpecPowerMeter(size_t sigLen);
|
||||
~SpecPowerMeter();
|
||||
|
||||
float CalcPower(float* sig, float fc, float bw);
|
||||
|
|
|
@ -371,8 +371,8 @@ namespace
|
|||
{
|
||||
enum { WINDOW, TWINDOW, DWINDOW };
|
||||
void RecreateWindow(
|
||||
float *&window, int which, int fftLen,
|
||||
int padding, int windowType, int windowSize, double &scale)
|
||||
float *&window, int which, size_t fftLen,
|
||||
size_t padding, int windowType, size_t windowSize, double &scale)
|
||||
{
|
||||
if (window != NULL)
|
||||
delete[] window;
|
||||
|
@ -402,7 +402,7 @@ namespace
|
|||
// Future, reassignment
|
||||
case TWINDOW:
|
||||
NewWindowFunc(windowType, windowSize, extra, window + padding);
|
||||
for (int ii = padding, multiplier = -windowSize / 2; ii < endOfWindow; ++ii, ++multiplier)
|
||||
for (int ii = padding, multiplier = -(int)windowSize / 2; ii < endOfWindow; ++ii, ++multiplier)
|
||||
window[ii] *= multiplier;
|
||||
break;
|
||||
case DWINDOW:
|
||||
|
@ -429,8 +429,8 @@ void SpectrogramSettings::CacheWindows() const
|
|||
if (hFFT == NULL || window == NULL) {
|
||||
|
||||
double scale;
|
||||
const int fftLen = windowSize * zeroPaddingFactor;
|
||||
const int padding = (windowSize * (zeroPaddingFactor - 1)) / 2;
|
||||
const auto fftLen = WindowSize() * ZeroPaddingFactor();
|
||||
const auto padding = (windowSize * (zeroPaddingFactor - 1)) / 2;
|
||||
|
||||
if (hFFT != NULL)
|
||||
EndFFT(hFFT);
|
||||
|
@ -475,7 +475,7 @@ void SpectrogramSettings::ConvertToActualWindowSizes()
|
|||
#endif
|
||||
}
|
||||
|
||||
int SpectrogramSettings::GetFFTLength() const
|
||||
size_t SpectrogramSettings::GetFFTLength() const
|
||||
{
|
||||
return windowSize
|
||||
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
|
||||
|
@ -488,7 +488,7 @@ NumberScale SpectrogramSettings::GetScale
|
|||
(float minFreq, float maxFreq, double rate, bool bins) const
|
||||
{
|
||||
NumberScaleType type = nstLinear;
|
||||
const int half = GetFFTLength() / 2;
|
||||
const auto half = GetFFTLength() / 2;
|
||||
|
||||
// Don't assume the correspondence of the enums will remain direct in the future.
|
||||
// Do this switch.
|
||||
|
|
|
@ -100,12 +100,20 @@ public:
|
|||
int frequencyGain;
|
||||
|
||||
int windowType;
|
||||
|
||||
private:
|
||||
int windowSize;
|
||||
public:
|
||||
size_t WindowSize() const { return windowSize; }
|
||||
|
||||
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
|
||||
private:
|
||||
int zeroPaddingFactor;
|
||||
public:
|
||||
size_t ZeroPaddingFactor() const { return zeroPaddingFactor; }
|
||||
#endif
|
||||
|
||||
int GetFFTLength() const; // window size (times zero padding, if STFT)
|
||||
size_t GetFFTLength() const; // window size (times zero padding, if STFT)
|
||||
|
||||
bool isGrayscale;
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ SpectrumPrefs::SpectrumPrefs(wxWindow * parent, WaveTrack *wt)
|
|||
mDefaulted = false;
|
||||
}
|
||||
|
||||
const int windowSize = mTempSettings.windowSize;
|
||||
const auto windowSize = mTempSettings.WindowSize();
|
||||
mTempSettings.ConvertToEnumeratedWindowSizes();
|
||||
Populate(windowSize);
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ enum {
|
|||
ID_DEFAULTS,
|
||||
};
|
||||
|
||||
void SpectrumPrefs::Populate(int windowSize)
|
||||
void SpectrumPrefs::Populate(size_t windowSize)
|
||||
{
|
||||
mSizeChoices.Add(_("8 - most wideband"));
|
||||
mSizeChoices.Add(wxT("16"));
|
||||
|
@ -112,7 +112,7 @@ void SpectrumPrefs::Populate(int windowSize)
|
|||
// ----------------------- End of main section --------------
|
||||
}
|
||||
|
||||
void SpectrumPrefs::PopulatePaddingChoices(int windowSize)
|
||||
void SpectrumPrefs::PopulatePaddingChoices(size_t windowSize)
|
||||
{
|
||||
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
|
||||
mZeroPaddingChoice = 1;
|
||||
|
@ -132,9 +132,9 @@ void SpectrumPrefs::PopulatePaddingChoices(int windowSize)
|
|||
pPaddingSizeControl->Clear();
|
||||
}
|
||||
|
||||
int padding = 1;
|
||||
unsigned padding = 1;
|
||||
int numChoices = 0;
|
||||
const int maxWindowSize = 1 << (SpectrogramSettings::LogMaxWindowSize);
|
||||
const size_t maxWindowSize = 1 << (SpectrogramSettings::LogMaxWindowSize);
|
||||
while (windowSize <= maxWindowSize) {
|
||||
const wxString numeral = wxString::Format(wxT("%d"), padding);
|
||||
mZeroPaddingChoices.Add(numeral);
|
||||
|
@ -449,7 +449,7 @@ void SpectrumPrefs::OnWindowSize(wxCommandEvent &evt)
|
|||
// size and padding may not exceed the largest window size.
|
||||
wxChoice *const pWindowSizeControl =
|
||||
static_cast<wxChoice*>(wxWindow::FindWindowById(ID_WINDOW_SIZE, this));
|
||||
int windowSize = 1 <<
|
||||
size_t windowSize = 1 <<
|
||||
(pWindowSizeControl->GetSelection() + SpectrogramSettings::LogMinWindowSize);
|
||||
PopulatePaddingChoices(windowSize);
|
||||
|
||||
|
|
|
@ -48,8 +48,8 @@ class SpectrumPrefs final : public PrefsPanel
|
|||
bool Validate() override;
|
||||
|
||||
private:
|
||||
void Populate(int windowSize);
|
||||
void PopulatePaddingChoices(int windowSize);
|
||||
void Populate(size_t windowSize);
|
||||
void PopulatePaddingChoices(size_t windowSize);
|
||||
void PopulateOrExchange(ShuttleGui & S);
|
||||
|
||||
void OnControl(wxCommandEvent &event);
|
||||
|
|
Loading…
Reference in New Issue