void OscilGen::paste(OscilGen &o) { //XXX Figure out a better implementation of this sensitive to RT issues... //Preserve Pointer Elements PRESERVE(oscilFFTfreqs); PRESERVE(pendingfreqs); PRESERVE(tmpsmps); PRESERVE(outoscilFFTfreqs); PRESERVE(fft); PRESERVE(basefuncFFTfreqs); PRESERVE(res); memcpy((char*)this, (char*)&o, sizeof(*this)); RESTORE(oscilFFTfreqs); RESTORE(pendingfreqs); RESTORE(tmpsmps); RESTORE(outoscilFFTfreqs); RESTORE(fft); RESTORE(basefuncFFTfreqs); RESTORE(res); if(this->Pcurrentbasefunc) changebasefunction(); this->prepare(); }
/* * Prepare the Oscillator */ void OscilGen::prepare() { int i, j, k; REALTYPE a, b, c, d, hmagnew; if((oldbasepar != Pbasefuncpar) || (oldbasefunc != Pcurrentbasefunc) || (oldbasefuncmodulation != Pbasefuncmodulation) || (oldbasefuncmodulationpar1 != Pbasefuncmodulationpar1) || (oldbasefuncmodulationpar2 != Pbasefuncmodulationpar2) || (oldbasefuncmodulationpar3 != Pbasefuncmodulationpar3)) changebasefunction(); for(i = 0; i < MAX_AD_HARMONICS; i++) hphase[i] = (Phphase[i] - 64.0) / 64.0 * PI / (i + 1); for(i = 0; i < MAX_AD_HARMONICS; i++) { hmagnew = 1.0 - fabs(Phmag[i] / 64.0 - 1.0); switch(Phmagtype) { case 1: hmag[i] = exp(hmagnew * log(0.01)); break; case 2: hmag[i] = exp(hmagnew * log(0.001)); break; case 3: hmag[i] = exp(hmagnew * log(0.0001)); break; case 4: hmag[i] = exp(hmagnew * log(0.00001)); break; default: hmag[i] = 1.0 - hmagnew; break; } if(Phmag[i] < 64) hmag[i] = -hmag[i]; } //remove the harmonics where Phmag[i]==64 for(i = 0; i < MAX_AD_HARMONICS; i++) if(Phmag[i] == 64) hmag[i] = 0.0; for(i = 0; i < OSCIL_SIZE / 2; i++) { oscilFFTfreqs.c[i] = 0.0; oscilFFTfreqs.s[i] = 0.0; } if(Pcurrentbasefunc == 0) { //the sine case for(i = 0; i < MAX_AD_HARMONICS; i++) { oscilFFTfreqs.c[i + 1] = -hmag[i] * sin(hphase[i] * (i + 1)) / 2.0; oscilFFTfreqs.s[i + 1] = hmag[i] * cos(hphase[i] * (i + 1)) / 2.0; } } else { for(j = 0; j < MAX_AD_HARMONICS; j++) { if(Phmag[j] == 64) continue; for(i = 1; i < OSCIL_SIZE / 2; i++) { k = i * (j + 1); if(k >= OSCIL_SIZE / 2) break; a = basefuncFFTfreqs.c[i]; b = basefuncFFTfreqs.s[i]; c = hmag[j] * cos(hphase[j] * k); d = hmag[j] * sin(hphase[j] * k); oscilFFTfreqs.c[k] += a * c - b * d; oscilFFTfreqs.s[k] += a * d + b * c; } } } if(Pharmonicshiftfirst != 0) shiftharmonics(); if(Pfilterbeforews == 0) { waveshape(); oscilfilter(); } else { oscilfilter(); waveshape(); } modulation(); spectrumadjust(); if(Pharmonicshiftfirst == 0) shiftharmonics(); oscilFFTfreqs.c[0] = 0.0; oldhmagtype = Phmagtype; oldharmonicshift = Pharmonicshift + Pharmonicshiftfirst * 256; oscilprepared = 1; }
void OscilGen::getfromXML(XMLwrapper *xml) { Phmagtype = xml->getpar127("harmonic_mag_type", Phmagtype); Pcurrentbasefunc = xml->getpar127("base_function", Pcurrentbasefunc); Pbasefuncpar = xml->getpar127("base_function_par", Pbasefuncpar); Pbasefuncmodulation = xml->getpar127("base_function_modulation", Pbasefuncmodulation); Pbasefuncmodulationpar1 = xml->getpar127("base_function_modulation_par1", Pbasefuncmodulationpar1); Pbasefuncmodulationpar2 = xml->getpar127("base_function_modulation_par2", Pbasefuncmodulationpar2); Pbasefuncmodulationpar3 = xml->getpar127("base_function_modulation_par3", Pbasefuncmodulationpar3); Pmodulation = xml->getpar127("modulation", Pmodulation); Pmodulationpar1 = xml->getpar127("modulation_par1", Pmodulationpar1); Pmodulationpar2 = xml->getpar127("modulation_par2", Pmodulationpar2); Pmodulationpar3 = xml->getpar127("modulation_par3", Pmodulationpar3); Pwaveshaping = xml->getpar127("wave_shaping", Pwaveshaping); Pwaveshapingfunction = xml->getpar127("wave_shaping_function", Pwaveshapingfunction); Pfiltertype = xml->getpar127("filter_type", Pfiltertype); Pfilterpar1 = xml->getpar127("filter_par1", Pfilterpar1); Pfilterpar2 = xml->getpar127("filter_par2", Pfilterpar2); Pfilterbeforews = xml->getpar127("filter_before_wave_shaping", Pfilterbeforews); Psatype = xml->getpar127("spectrum_adjust_type", Psatype); Psapar = xml->getpar127("spectrum_adjust_par", Psapar); Prand = xml->getpar127("rand", Prand); Pamprandtype = xml->getpar127("amp_rand_type", Pamprandtype); Pamprandpower = xml->getpar127("amp_rand_power", Pamprandpower); Pharmonicshift = xml->getpar("harmonic_shift", Pharmonicshift, -64, 64); Pharmonicshiftfirst = xml->getparbool("harmonic_shift_first", Pharmonicshiftfirst); Padaptiveharmonics = xml->getpar("adaptive_harmonics", Padaptiveharmonics, 0, 127); Padaptiveharmonicsbasefreq = xml->getpar( "adaptive_harmonics_base_frequency", Padaptiveharmonicsbasefreq, 0, 255); Padaptiveharmonicspower = xml->getpar("adaptive_harmonics_power", Padaptiveharmonicspower, 0, 200); if(xml->enterbranch("HARMONICS")) { Phmag[0] = 64; Phphase[0] = 64; for(int n = 0; n < MAX_AD_HARMONICS; n++) { if(xml->enterbranch("HARMONIC", n + 1) == 0) continue; Phmag[n] = xml->getpar127("mag", 64); Phphase[n] = xml->getpar127("phase", 64); xml->exitbranch(); } xml->exitbranch(); } if(Pcurrentbasefunc != 0) changebasefunction(); if(xml->enterbranch("BASE_FUNCTION")) { for(int i = 1; i < OSCIL_SIZE / 2; i++) { if(xml->enterbranch("BF_HARMONIC", i)) { basefuncFFTfreqs.c[i] = xml->getparreal("cos", 0.0); basefuncFFTfreqs.s[i] = xml->getparreal("sin", 0.0); xml->exitbranch(); } } xml->exitbranch(); REALTYPE max = 0.0; basefuncFFTfreqs.c[0] = 0.0; 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; } } }
void OscilGen::prepare(fft_t *freqs) { if((oldbasepar != Pbasefuncpar) || (oldbasefunc != Pcurrentbasefunc) || DIFF(basefuncmodulation) || DIFF(basefuncmodulationpar1) || DIFF(basefuncmodulationpar2) || DIFF(basefuncmodulationpar3)) changebasefunction(); for(int i = 0; i < MAX_AD_HARMONICS; ++i) hphase[i] = (Phphase[i] - 64.0f) / 64.0f * PI / (i + 1); for(int i = 0; i < MAX_AD_HARMONICS; ++i) { const float hmagnew = 1.0f - fabs(Phmag[i] / 64.0f - 1.0f); switch(Phmagtype) { case 1: hmag[i] = expf(hmagnew * logf(0.01f)); break; case 2: hmag[i] = expf(hmagnew * logf(0.001f)); break; case 3: hmag[i] = expf(hmagnew * logf(0.0001f)); break; case 4: hmag[i] = expf(hmagnew * logf(0.00001f)); break; default: hmag[i] = 1.0f - hmagnew; break; } if(Phmag[i] < 64) hmag[i] = -hmag[i]; } //remove the harmonics where Phmag[i]==64 for(int i = 0; i < MAX_AD_HARMONICS; ++i) if(Phmag[i] == 64) hmag[i] = 0.0f; clearAll(freqs, synth.oscilsize); if(Pcurrentbasefunc == 0) //the sine case for(int i = 0; i < MAX_AD_HARMONICS - 1; ++i) { freqs[i + 1] = std::complex<float>(-hmag[i] * sinf(hphase[i] * (i + 1)) / 2.0f, hmag[i] * cosf(hphase[i] * (i + 1)) / 2.0f); } else for(int j = 0; j < MAX_AD_HARMONICS; ++j) { if(Phmag[j] == 64) continue; for(int i = 1; i < synth.oscilsize / 2; ++i) { int k = i * (j + 1); if(k >= synth.oscilsize / 2) break; freqs[k] += basefuncFFTfreqs[i] * FFTpolar<fftw_real>( hmag[j], hphase[j] * k); } } if(Pharmonicshiftfirst != 0) shiftharmonics(freqs); if(Pfilterbeforews) { oscilfilter(freqs); waveshape(freqs); } else { waveshape(freqs); oscilfilter(freqs); } modulation(freqs); spectrumadjust(freqs); if(Pharmonicshiftfirst == 0) shiftharmonics(freqs); clearDC(freqs); oldhmagtype = Phmagtype; oldharmonicshift = Pharmonicshift + Pharmonicshiftfirst * 256; oscilprepared = 1; }
void OscilGen::getfromXML(XMLwrapper *xml) { Phmagtype = xml->getpar127("harmonic_mag_type", Phmagtype); Pcurrentbasefunc = xml->getpar127("base_function", Pcurrentbasefunc); Pbasefuncpar = xml->getpar127("base_function_par", Pbasefuncpar); Pbasefuncmodulation = xml->getpar127("base_function_modulation", Pbasefuncmodulation); Pbasefuncmodulationpar1 = xml->getpar127("base_function_modulation_par1", Pbasefuncmodulationpar1); Pbasefuncmodulationpar2 = xml->getpar127("base_function_modulation_par2", Pbasefuncmodulationpar2); Pbasefuncmodulationpar3 = xml->getpar127("base_function_modulation_par3", Pbasefuncmodulationpar3); Pmodulation = xml->getpar127("modulation", Pmodulation); Pmodulationpar1 = xml->getpar127("modulation_par1", Pmodulationpar1); Pmodulationpar2 = xml->getpar127("modulation_par2", Pmodulationpar2); Pmodulationpar3 = xml->getpar127("modulation_par3", Pmodulationpar3); Pwaveshaping = xml->getpar127("wave_shaping", Pwaveshaping); Pwaveshapingfunction = xml->getpar127("wave_shaping_function", Pwaveshapingfunction); Pfiltertype = xml->getpar127("filter_type", Pfiltertype); Pfilterpar1 = xml->getpar127("filter_par1", Pfilterpar1); Pfilterpar2 = xml->getpar127("filter_par2", Pfilterpar2); Pfilterbeforews = xml->getpar127("filter_before_wave_shaping", Pfilterbeforews); Psatype = xml->getpar127("spectrum_adjust_type", Psatype); Psapar = xml->getpar127("spectrum_adjust_par", Psapar); Prand = xml->getpar127("rand", Prand); Pamprandtype = xml->getpar127("amp_rand_type", Pamprandtype); Pamprandpower = xml->getpar127("amp_rand_power", Pamprandpower); Pharmonicshift = xml->getpar("harmonic_shift", Pharmonicshift, -64, 64); Pharmonicshiftfirst = xml->getparbool("harmonic_shift_first", Pharmonicshiftfirst); Padaptiveharmonics = xml->getpar("adaptive_harmonics", Padaptiveharmonics, 0, 127); Padaptiveharmonicsbasefreq = xml->getpar( "adaptive_harmonics_base_frequency", Padaptiveharmonicsbasefreq, 0, 255); Padaptiveharmonicspower = xml->getpar("adaptive_harmonics_power", Padaptiveharmonicspower, 0, 200); if(xml->enterbranch("HARMONICS")) { Phmag[0] = 64; Phphase[0] = 64; for(int n = 0; n < MAX_AD_HARMONICS; ++n) { if(xml->enterbranch("HARMONIC", n + 1) == 0) continue; Phmag[n] = xml->getpar127("mag", 64); Phphase[n] = xml->getpar127("phase", 64); xml->exitbranch(); } xml->exitbranch(); } if(xml->enterbranch("BASE_FUNCTION")) { for(int i = 1; i < synth.oscilsize / 2; ++i) if(xml->enterbranch("BF_HARMONIC", i)) { basefuncFFTfreqs[i] = std::complex<float>(xml->getparreal("cos", 0.0f), xml->getparreal("sin", 0.0f)); xml->exitbranch(); } xml->exitbranch(); if(Pcurrentbasefunc != 0) changebasefunction(); clearDC(basefuncFFTfreqs); normalize(basefuncFFTfreqs, synth.oscilsize); } else if(Pcurrentbasefunc != 0) changebasefunction(); }