Enforce no-null-args to FFTs; avoid corresponding potential crash in formant preservation code
This commit is contained in:
@@ -930,7 +930,8 @@ RubberBandStretcher::Impl::formantShiftChunk(size_t channel)
|
||||
|
||||
v_scale(dblbuf, factor, cutoff);
|
||||
|
||||
cd.fft->forward(dblbuf, envelope, 0);
|
||||
double *spare = (double *)alloca((hs + 1) * sizeof(double));
|
||||
cd.fft->forward(dblbuf, envelope, spare);
|
||||
|
||||
v_exp(envelope, hs + 1);
|
||||
v_divide(mag, envelope, hs + 1);
|
||||
|
||||
@@ -3187,99 +3187,154 @@ FFT::~FFT()
|
||||
delete d;
|
||||
}
|
||||
|
||||
#ifndef NO_EXCEPTIONS
|
||||
#define CHECK_NOT_NULL(x) \
|
||||
if (!(x)) { \
|
||||
std::cerr << "FFT: ERROR: Null argument " #x << std::endl; \
|
||||
throw NullArgument; \
|
||||
}
|
||||
#else
|
||||
#define CHECK_NOT_NULL(x) \
|
||||
if (!(x)) { \
|
||||
std::cerr << "FFT: ERROR: Null argument " #x << std::endl; \
|
||||
std::cerr << "FFT: Would be throwing NullArgument here, if exceptions were not disabled" << std::endl; \
|
||||
return; \
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
FFT::forward(const double *R__ realIn, double *R__ realOut, double *R__ imagOut)
|
||||
{
|
||||
CHECK_NOT_NULL(realIn);
|
||||
CHECK_NOT_NULL(realOut);
|
||||
CHECK_NOT_NULL(imagOut);
|
||||
d->forward(realIn, realOut, imagOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::forwardInterleaved(const double *R__ realIn, double *R__ complexOut)
|
||||
{
|
||||
CHECK_NOT_NULL(realIn);
|
||||
CHECK_NOT_NULL(complexOut);
|
||||
d->forwardInterleaved(realIn, complexOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut)
|
||||
{
|
||||
CHECK_NOT_NULL(realIn);
|
||||
CHECK_NOT_NULL(magOut);
|
||||
CHECK_NOT_NULL(phaseOut);
|
||||
d->forwardPolar(realIn, magOut, phaseOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::forwardMagnitude(const double *R__ realIn, double *R__ magOut)
|
||||
{
|
||||
CHECK_NOT_NULL(realIn);
|
||||
CHECK_NOT_NULL(magOut);
|
||||
d->forwardMagnitude(realIn, magOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::forward(const float *R__ realIn, float *R__ realOut, float *R__ imagOut)
|
||||
{
|
||||
CHECK_NOT_NULL(realIn);
|
||||
CHECK_NOT_NULL(realOut);
|
||||
CHECK_NOT_NULL(imagOut);
|
||||
d->forward(realIn, realOut, imagOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::forwardInterleaved(const float *R__ realIn, float *R__ complexOut)
|
||||
{
|
||||
CHECK_NOT_NULL(realIn);
|
||||
CHECK_NOT_NULL(complexOut);
|
||||
d->forwardInterleaved(realIn, complexOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut)
|
||||
{
|
||||
CHECK_NOT_NULL(realIn);
|
||||
CHECK_NOT_NULL(magOut);
|
||||
CHECK_NOT_NULL(phaseOut);
|
||||
d->forwardPolar(realIn, magOut, phaseOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::forwardMagnitude(const float *R__ realIn, float *R__ magOut)
|
||||
{
|
||||
CHECK_NOT_NULL(realIn);
|
||||
CHECK_NOT_NULL(magOut);
|
||||
d->forwardMagnitude(realIn, magOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::inverse(const double *R__ realIn, const double *R__ imagIn, double *R__ realOut)
|
||||
{
|
||||
CHECK_NOT_NULL(realIn);
|
||||
CHECK_NOT_NULL(imagIn);
|
||||
CHECK_NOT_NULL(realOut);
|
||||
d->inverse(realIn, imagIn, realOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::inverseInterleaved(const double *R__ complexIn, double *R__ realOut)
|
||||
{
|
||||
CHECK_NOT_NULL(complexIn);
|
||||
CHECK_NOT_NULL(realOut);
|
||||
d->inverseInterleaved(complexIn, realOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut)
|
||||
{
|
||||
CHECK_NOT_NULL(magIn);
|
||||
CHECK_NOT_NULL(phaseIn);
|
||||
CHECK_NOT_NULL(realOut);
|
||||
d->inversePolar(magIn, phaseIn, realOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::inverseCepstral(const double *R__ magIn, double *R__ cepOut)
|
||||
{
|
||||
CHECK_NOT_NULL(magIn);
|
||||
CHECK_NOT_NULL(cepOut);
|
||||
d->inverseCepstral(magIn, cepOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::inverse(const float *R__ realIn, const float *R__ imagIn, float *R__ realOut)
|
||||
{
|
||||
CHECK_NOT_NULL(realIn);
|
||||
CHECK_NOT_NULL(imagIn);
|
||||
CHECK_NOT_NULL(realOut);
|
||||
d->inverse(realIn, imagIn, realOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::inverseInterleaved(const float *R__ complexIn, float *R__ realOut)
|
||||
{
|
||||
CHECK_NOT_NULL(complexIn);
|
||||
CHECK_NOT_NULL(realOut);
|
||||
d->inverseInterleaved(complexIn, realOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut)
|
||||
{
|
||||
CHECK_NOT_NULL(magIn);
|
||||
CHECK_NOT_NULL(phaseIn);
|
||||
CHECK_NOT_NULL(realOut);
|
||||
d->inversePolar(magIn, phaseIn, realOut);
|
||||
}
|
||||
|
||||
void
|
||||
FFT::inverseCepstral(const float *R__ magIn, float *R__ cepOut)
|
||||
{
|
||||
CHECK_NOT_NULL(magIn);
|
||||
CHECK_NOT_NULL(cepOut);
|
||||
d->inverseCepstral(magIn, cepOut);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,17 +45,21 @@ class FFTImpl;
|
||||
* The "interleaved" functions use the format sometimes called CCS --
|
||||
* size/2+1 real+imaginary pairs. So, the array elements at indices 1
|
||||
* and size+1 will always be zero (since the signal is real).
|
||||
*
|
||||
* All pointer arguments must point to valid data. A NullArgument
|
||||
* exception is thrown if any argument is NULL.
|
||||
*
|
||||
* Neither forward nor inverse transform is scaled.
|
||||
*
|
||||
* This class is reentrant but not thread safe: use a separate
|
||||
* instance per thread, or use a mutex.
|
||||
*/
|
||||
|
||||
class FFT
|
||||
{
|
||||
public:
|
||||
enum Exception { InvalidSize, InvalidImplementation, InternalError };
|
||||
enum Exception {
|
||||
NullArgument, InvalidSize, InvalidImplementation, InternalError
|
||||
};
|
||||
|
||||
FFT(int size, int debugLevel = 0); // may throw InvalidSize
|
||||
~FFT();
|
||||
|
||||
Reference in New Issue
Block a user