From 6cd5317e0980497b66a72f25c808be787b2c9f02 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Sun, 18 Mar 2018 13:36:05 -0400 Subject: [PATCH] Fix C++ standards library portability issue. (#4261) Fix C++ standards library portability issue. Cherry-pick of upstream 2.5 patches: zynaddsubfx/zynaddsubfx@417d49b, zynaddsubfx/zynaddsubfx@edca8ab Closes #4152 --- .../zynaddsubfx/src/DSP/FFTwrapper.h | 19 +++++++++++++++++++ .../src/Params/PADnoteParameters.cpp | 2 +- .../zynaddsubfx/src/Synth/OscilGen.cpp | 6 +++--- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/plugins/zynaddsubfx/zynaddsubfx/src/DSP/FFTwrapper.h b/plugins/zynaddsubfx/zynaddsubfx/src/DSP/FFTwrapper.h index 1d61e2e53..c79bd211b 100644 --- a/plugins/zynaddsubfx/zynaddsubfx/src/DSP/FFTwrapper.h +++ b/plugins/zynaddsubfx/zynaddsubfx/src/DSP/FFTwrapper.h @@ -49,5 +49,24 @@ class FFTwrapper fftwf_plan planfftw, planfftw_inv; }; +/* + * The "std::polar" template has no clear definition for the range of + * the input parameters, and some C++ standard library implementations + * don't accept negative amplitude among others. Define our own + * FFTpolar template, which works like we expect it to. + */ +template +std::complex<_Tp> +FFTpolar(const _Tp& __rho, const _Tp& __theta = _Tp(0)) +{ + _Tp __x = __rho * cos(__theta); + if (std::isnan(__x)) + __x = 0; + _Tp __y = __rho * sin(__theta); + if (std::isnan(__y)) + __y = 0; + return std::complex<_Tp>(__x, __y); +} + void FFT_cleanup(); #endif diff --git a/plugins/zynaddsubfx/zynaddsubfx/src/Params/PADnoteParameters.cpp b/plugins/zynaddsubfx/zynaddsubfx/src/Params/PADnoteParameters.cpp index d0572cac3..136ee50e6 100644 --- a/plugins/zynaddsubfx/zynaddsubfx/src/Params/PADnoteParameters.cpp +++ b/plugins/zynaddsubfx/zynaddsubfx/src/Params/PADnoteParameters.cpp @@ -615,7 +615,7 @@ void PADnoteParameters::applyparameters(bool lockmutex) newsample.smp[0] = 0.0f; for(int i = 1; i < spectrumsize; ++i) //randomize the phases - fftfreqs[i] = std::polar(spectrum[i], (float)RND * 6.29f); + fftfreqs[i] = FFTpolar(spectrum[i], (float)RND * 6.29f); fft->freqs2smps(fftfreqs, newsample.smp); //that's all; here is the only ifft for the whole sample; no windows are used ;-) diff --git a/plugins/zynaddsubfx/zynaddsubfx/src/Synth/OscilGen.cpp b/plugins/zynaddsubfx/zynaddsubfx/src/Synth/OscilGen.cpp index 6cd89dcc6..7e24a5a6b 100644 --- a/plugins/zynaddsubfx/zynaddsubfx/src/Synth/OscilGen.cpp +++ b/plugins/zynaddsubfx/zynaddsubfx/src/Synth/OscilGen.cpp @@ -533,7 +533,7 @@ void OscilGen::spectrumadjust() mag = 1.0f; break; } - oscilFFTfreqs[i] = std::polar(mag, phase); + oscilFFTfreqs[i] = FFTpolar(mag, phase); } } @@ -629,7 +629,7 @@ void OscilGen::prepare() int k = i * (j + 1); if(k >= synth->oscilsize / 2) break; - oscilFFTfreqs[k] += basefuncFFTfreqs[i] * std::polar( + oscilFFTfreqs[k] += basefuncFFTfreqs[i] * FFTpolar( hmag[j], hphase[j] * k); } @@ -857,7 +857,7 @@ short int OscilGen::get(float *smps, float freqHz, int resonance) const float rnd = PI * powf((Prand - 64.0f) / 64.0f, 2.0f); for(int i = 1; i < nyquist - 1; ++i) //to Nyquist only for AntiAliasing outoscilFFTfreqs[i] *= - std::polar(1.0f, (float)(rnd * i * RND)); + FFTpolar(1.0f, (float)(rnd * i * RND)); } //Harmonic Amplitude Randomness