commit b78fede312db7cb248c9562855976c02cd54d1b3
parent 43e33d1405cd5ab204f067a98887c282e06844f7
Author: fundamental <mark.d.mccurry@gmail.com>
Date: Fri, 12 Aug 2011 10:59:57 -0400
OscilGen: Separating out normalization code
Diffstat:
1 file changed, 117 insertions(+), 75 deletions(-)
diff --git a/src/Synth/OscilGen.cpp b/src/Synth/OscilGen.cpp
@@ -41,6 +41,31 @@ inline void clearDC(FFTFREQS &freqs)
freqs.s[0] = freqs.c[0] = 0.0f;
}
+/**
+ * Take frequency spectrum and ensure values are normalized based upon
+ * magnitude to 0<=x<=1
+ */
+inline 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];
+ if(normMax < norm)
+ normMax = norm;
+ }
+
+ float max = sqrt(normMax);
+ if(max < 1e-8)
+ max = 1.0;
+
+ for(int i=0; i < OSCIL_SIZE / 2; ++i) {
+ freqs.s[i] /= max;
+ freqs.c[i] /= max;
+ }
+}
+
OscilGen::OscilGen(FFTwrapper *fft_, Resonance *res_):Presets()
{
setpresettype("Poscilgen");
@@ -255,6 +280,30 @@ void OscilGen::getbasefunction(float *smps)
}
}
+inline void rootMaxSquaredNormal(FFTFREQS &freqs)
+{
+ float max = 0.0f;
+ for(int i = 1; i < OSCIL_SIZE / 2; i++) {
+ const float magnitude = freqs.s[i] * freqs.s[i]
+ + freqs.c[i] * freqs.c[i];
+ if(max < magnitude)
+ max = magnitude;
+ }
+
+ //Root MAX Squared best describes this, but based upon previous
+ //documentation, it should be root mean squared, current state is for
+ //compatiability
+ max = sqrt(max);
+ if(max < 1e-10)
+ max = 1.0;
+
+ //Normalize signal
+ for(int i = 1; i < OSCIL_SIZE / 2; i++) {
+ freqs.s[i] /= max;
+ freqs.c[i] /= max;
+ }
+}
+
/*
* Filter the oscillator
*/
@@ -265,31 +314,15 @@ void OscilGen::oscilfilter()
const float par = 1.0 - Pfilterpar1 / 128.0;
const float par2 = Pfilterpar2 / 127.0;
- float max = 0.0;
filter_func filter = getFilter(Pfiltertype);
for(int i = 1; i < OSCIL_SIZE / 2; i++) {
- float gain = filter(i,par,par2);
-
+ const float gain = filter(i,par,par2);
oscilFFTfreqs.s[i] *= gain;
oscilFFTfreqs.c[i] *= gain;
- float magnitude = oscilFFTfreqs.s[i] * oscilFFTfreqs.s[i]
- + oscilFFTfreqs.c[i] * oscilFFTfreqs.c[i];
- if(max < magnitude)
- max = magnitude;
}
- //Finish RMS calculation
- max = sqrt(max);
- if(max < 1e-10)
- max = 1.0;
- float imax = 1.0 / max;
-
- //Normalize signal
- for(int i = 1; i < OSCIL_SIZE / 2; i++) {
- oscilFFTfreqs.s[i] *= imax;
- oscilFFTfreqs.c[i] *= imax;
- }
+ rootMaxSquaredNormal(oscilFFTfreqs);
}
@@ -314,13 +347,26 @@ void OscilGen::changebasefunction()
oldbasefuncmodulationpar3 = Pbasefuncmodulationpar3;
}
+inline void normalize(float *smps, size_t N)
+{
+ //Find max
+ float max = 0.0;
+ for(size_t i = 0; i < N; i++)
+ if(max < fabs(smps[i]))
+ max = fabs(smps[i]);
+ if(max < 0.00001)
+ max = 1.0;
+
+ //Normalize to +-1
+ for(size_t i = 0; i < N; i++)
+ smps[i] /= max;
+}
+
/*
* Waveshape
*/
void OscilGen::waveshape()
{
- int i;
-
oldwaveshapingfunction = Pwaveshapingfunction;
oldwaveshaping = Pwaveshaping;
if(Pwaveshapingfunction == 0)
@@ -328,23 +374,15 @@ void OscilGen::waveshape()
clearDC(oscilFFTfreqs);
//reduce the amplitude of the freqs near the nyquist
- for(i = 1; i < OSCIL_SIZE / 8; i++) {
- float tmp = i / (OSCIL_SIZE / 8.0);
- oscilFFTfreqs.s[OSCIL_SIZE / 2 - i] *= tmp;
- oscilFFTfreqs.c[OSCIL_SIZE / 2 - i] *= tmp;
+ for(int i = 1; i < OSCIL_SIZE / 8; i++) {
+ float gain = i / (OSCIL_SIZE / 8.0);
+ oscilFFTfreqs.s[OSCIL_SIZE / 2 - i] *= gain;
+ oscilFFTfreqs.c[OSCIL_SIZE / 2 - i] *= gain;
}
fft->freqs2smps(oscilFFTfreqs, tmpsmps);
//Normalize
- float max = 0.0;
- for(i = 0; i < OSCIL_SIZE; i++)
- if(max < fabs(tmpsmps[i]))
- max = fabs(tmpsmps[i]);
- if(max < 0.00001)
- max = 1.0;
- max = 1.0 / max;
- for(i = 0; i < OSCIL_SIZE; i++)
- tmpsmps[i] *= max;
+ normalize(tmpsmps, OSCIL_SIZE);
//Do the waveshaping
waveShapeSmps(OSCIL_SIZE, tmpsmps, Pwaveshapingfunction, Pwaveshaping);
@@ -401,17 +439,12 @@ void OscilGen::modulation()
float *in = new float[OSCIL_SIZE + extra_points];
//Normalize
- float max = 0.0;
- for(i = 0; i < OSCIL_SIZE; i++)
- if(max < fabs(tmpsmps[i]))
- max = fabs(tmpsmps[i]);
- if(max < 0.00001)
- max = 1.0;
- max = 1.0 / max;
+ normalize(tmpsmps, OSCIL_SIZE);
+
for(i = 0; i < OSCIL_SIZE; i++)
- in[i] = tmpsmps[i] * max;
+ in[i] = tmpsmps[i];
for(i = 0; i < extra_points; i++)
- in[i + OSCIL_SIZE] = tmpsmps[i] * max;
+ in[i + OSCIL_SIZE] = tmpsmps[i];
//Do the modulation
for(i = 0; i < OSCIL_SIZE; i++) {
@@ -446,6 +479,24 @@ void OscilGen::modulation()
fft->smps2freqs(tmpsmps, oscilFFTfreqs); //perform FFT
}
+inline void quasiRmsNorm(FFTFREQS &freqs)
+{
+ float max = 0.0;
+ for(int i = 0; i < OSCIL_SIZE / 2; ++i) {
+ float tmp = freqs.c[i] * freqs.c[i]
+ + freqs.s[i] * freqs.s[i];
+ if(max < tmp)
+ max = tmp;
+ }
+ max = sqrt(max) / OSCIL_SIZE * 2.0;
+ if(max < 1e-8)
+ max = 1.0;
+
+ for(int i=0; i < OSCIL_SIZE / 2; ++i) {
+ freqs.s[i] /= max;
+ freqs.c[i] /= max;
+ }
+}
/*
@@ -473,21 +524,12 @@ void OscilGen::spectrumadjust()
}
- float max = 0.0;
- for(int i = 0; i < OSCIL_SIZE / 2; i++) {
- float tmp = pow(oscilFFTfreqs.c[i], 2) + pow(oscilFFTfreqs.s[i], 2.0);
- if(max < tmp)
- max = tmp;
- }
- max = sqrt(max) / OSCIL_SIZE * 2.0;
- if(max < 1e-8)
- max = 1.0;
-
+ quasiRmsNorm(oscilFFTfreqs);
for(int i = 0; i < OSCIL_SIZE / 2; i++) {
float mag =
- sqrt(pow(oscilFFTfreqs.s[i],
- 2) + pow(oscilFFTfreqs.c[i], 2.0)) / max;
+ sqrt(oscilFFTfreqs.s[i] * oscilFFTfreqs.s[i]
+ + oscilFFTfreqs.c[i] * oscilFFTfreqs.c[i]);
float phase = atan2(oscilFFTfreqs.s[i], oscilFFTfreqs.c[i]);
switch(Psatype) {
@@ -967,9 +1009,7 @@ void OscilGen::getspectrum(int n, float *spc, int what)
*/
void OscilGen::useasbase()
{
- int i;
-
- for(i = 0; i < OSCIL_SIZE / 2; i++) {
+ for(int i = 0; i < OSCIL_SIZE / 2; i++) {
basefuncFFTfreqs.c[i] = oscilFFTfreqs.c[i];
basefuncFFTfreqs.s[i] = oscilFFTfreqs.s[i];
}
@@ -991,6 +1031,24 @@ void OscilGen::getcurrentbasefunction(float *smps)
getbasefunction(smps); //the sine case
}
+inline void peiceNormal(FFTFREQS &freqs)
+{
+ float max = 0.0;
+
+ for(int i = 0; i < OSCIL_SIZE / 2; i++) {
+ if(max < fabs(freqs.c[i]))
+ max = fabs(freqs.c[i]);
+ if(max < fabs(freqs.s[i]))
+ max = fabs(freqs.s[i]);
+ }
+ if(max < 0.00000001)
+ max = 1.0;
+
+ for(int i = 0; i < OSCIL_SIZE / 2; i++) {
+ freqs.c[i] /= max;
+ freqs.s[i] /= max;
+ }
+}
void OscilGen::add2XML(XMLwrapper *xml)
{
@@ -1068,7 +1126,6 @@ void OscilGen::add2XML(XMLwrapper *xml)
}
}
-
void OscilGen::getfromXML(XMLwrapper *xml)
{
Phmagtype = xml->getpar127("harmonic_mag_type", Phmagtype);
@@ -1159,27 +1216,12 @@ void OscilGen::getfromXML(XMLwrapper *xml)
}
xml->exitbranch();
- float max = 0.0;
-
clearDC(basefuncFFTfreqs);
- for(int i = 0; i < OSCIL_SIZE / 2; i++) {
- if(max < fabs(basefuncFFTfreqs.c[i]))
- max = fabs(basefuncFFTfreqs.c[i]);
- if(max < fabs(basefuncFFTfreqs.s[i]))
- max = fabs(basefuncFFTfreqs.s[i]);
- }
- if(max < 0.00000001)
- max = 1.0;
-
- for(int i = 0; i < OSCIL_SIZE / 2; i++) {
- if(basefuncFFTfreqs.c[i])
- basefuncFFTfreqs.c[i] /= max;
- if(basefuncFFTfreqs.s[i])
- basefuncFFTfreqs.s[i] /= max;
- }
+ peiceNormal(basefuncFFTfreqs);
}
}
+
//Define basic functions
#define FUNC(b) float basefunc_##b(float x, float a)