zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

commit 3b5974577aba517de87d665220d73f9eafe081be
parent 04d4bb13e4eecca5a3b648a0b796922be9121daa
Author: fundamental <mark.d.mccurry@gmail.com>
Date:   Fri, 12 Aug 2011 13:35:37 -0400

OscilGen: more complex ops and RMS normals

Diffstat:
Msrc/Synth/OscilGen.cpp | 82+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
1 file changed, 49 insertions(+), 33 deletions(-)

diff --git a/src/Synth/OscilGen.cpp b/src/Synth/OscilGen.cpp @@ -41,23 +41,41 @@ inline void clearDC(FFTFREQS &freqs) freqs.s[0] = freqs.c[0] = 0.0f; } +//return magnitude squared +inline float normal(const FFTFREQS &freqs, off_t x) +{ + return freqs.c[x] * freqs.c[x] + + freqs.s[x] * freqs.s[x]; +} + +//return magnitude +inline float abs(const FFTFREQS &freqs, off_t x) +{ + return sqrt(normal(freqs, x)); +} + +//return angle aka phase +inline float arg(const FFTFREQS &freqs, off_t x) +{ + return atan2(freqs.c[x], freqs.s[x]); +} + /** * Take frequency spectrum and ensure values are normalized based upon * magnitude to 0<=x<=1 */ -inline void normalize(FFTFREQS &freqs) +void normalize(FFTFREQS &freqs) { float normMax = 0.0; for(int i = 0; i < OSCIL_SIZE / 2; ++i) { //magnitude squared - float norm = freqs.c[i] * freqs.c[i] - + freqs.s[i] * freqs.s[i]; + const float norm = normal(freqs, i); if(normMax < norm) normMax = norm; } const float max = sqrt(normMax); - if(max < 1e-8) //data is all zero, do not amplify noise + if(max < 1e-8) //data is all ~zero, do not amplify noise return; for(int i=0; i < OSCIL_SIZE / 2; ++i) { @@ -66,6 +84,25 @@ inline void normalize(FFTFREQS &freqs) } } +//Full RMS normalize +void rmsNormalize(FFTFREQS &freqs) +{ + float sum = 0.0f; + for(int i = 1; i < OSCIL_SIZE / 2; ++i) + sum += normal(freqs, i); + + if(sum < 0.000001) + return; //data is all ~zero, do not amplify noise + + const float gain = 1.0 / sqrt(sum); + + for(int i = 1; i < OSCIL_SIZE / 2; i++) { + freqs.c[i] *= gain; + freqs.s[i] *= gain; + } +} + + OscilGen::OscilGen(FFTwrapper *fft_, Resonance *res_):Presets() { setpresettype("Poscilgen"); @@ -182,9 +219,8 @@ void OscilGen::convert2sine() mag[0] = 0; phase[0] = 0; for(int i = 0; i < MAX_AD_HARMONICS; i++) { - mag[i] = sqrt(freqs.s[i + 1] * freqs.s[i + 1] - + freqs.c[i + 1] * freqs.c[i + 1]); - phase[i] = atan2(freqs.c[i + 1], freqs.s[i + 1]); + mag[i] = abs(freqs, i + 1); + phase[i] = arg(freqs, i + 1); } defaults(); @@ -482,10 +518,8 @@ void OscilGen::spectrumadjust() normalize(oscilFFTfreqs); for(int i = 0; i < OSCIL_SIZE / 2; i++) { - float mag = - sqrt(oscilFFTfreqs.s[i] * oscilFFTfreqs.s[i] - + oscilFFTfreqs.c[i] * oscilFFTfreqs.c[i]); - float phase = atan2(oscilFFTfreqs.s[i], oscilFFTfreqs.c[i]); + float mag = abs(oscilFFTfreqs, i); + float phase = arg(oscilFFTfreqs, i); switch(Psatype) { case 1: @@ -891,26 +925,11 @@ short int OscilGen::get(float *smps, float freqHz, int resonance) if((freqHz > 0.1) && (resonance != 0)) res->applyres(nyquist - 1, outoscilFFTfreqs, freqHz); - //Full RMS normalize - float sum = 0; - for(int j = 1; j < OSCIL_SIZE / 2; j++) { - float term = outoscilFFTfreqs.c[j] * outoscilFFTfreqs.c[j] - + outoscilFFTfreqs.s[j] * outoscilFFTfreqs.s[j]; - sum += term; - } - if(sum < 0.000001) - sum = 1.0; - sum = 1.0 / sqrt(sum); - for(int j = 1; j < OSCIL_SIZE / 2; j++) { - outoscilFFTfreqs.c[j] *= sum; - outoscilFFTfreqs.s[j] *= sum; - } - + rmsNormalize(outoscilFFTfreqs); if((ADvsPAD) && (freqHz > 0.1)) //in this case the smps will contain the freqs for(i = 1; i < OSCIL_SIZE / 2; i++) - smps[i - 1] = sqrt(outoscilFFTfreqs.c[i] * outoscilFFTfreqs.c[i] - + outoscilFFTfreqs.s[i] * outoscilFFTfreqs.s[i]); + smps[i - 1] = abs(outoscilFFTfreqs, i); else { fft->freqs2smps(outoscilFFTfreqs, smps); for(i = 0; i < OSCIL_SIZE; i++) @@ -934,15 +953,12 @@ void OscilGen::getspectrum(int n, float *spc, int what) for(int i = 1; i < n; i++) { if(what == 0) - spc[i - 1] = sqrt(oscilFFTfreqs.c[i] * oscilFFTfreqs.c[i] - + oscilFFTfreqs.s[i] * oscilFFTfreqs.s[i]); + spc[i - 1] = abs(oscilFFTfreqs, i); else { if(Pcurrentbasefunc == 0) spc[i - 1] = ((i == 1) ? (1.0) : (0.0)); else - spc[i - 1] = sqrt(basefuncFFTfreqs.c[i] * basefuncFFTfreqs.c[i] - + basefuncFFTfreqs.s[i] - * basefuncFFTfreqs.s[i]); + spc[i - 1] = abs(basefuncFFTfreqs, i); } }