diff options
author | Robert Jonsson <spamatica@gmail.com> | 2009-12-27 11:30:35 +0000 |
---|---|---|
committer | Robert Jonsson <spamatica@gmail.com> | 2009-12-27 11:30:35 +0000 |
commit | b703eab295330e6f81564fbb39a10a1a2fdd2f54 (patch) | |
tree | e46b5c9a6bc22fd661c15d1d2123f5bf631cef80 /muse_qt4_evolution/synti/zynaddsubfx/Synth/Resonance.C | |
parent | 5d5fa0fdf913907edbc3d2d29a7548f0cb658c94 (diff) |
moved old qt4 branch
Diffstat (limited to 'muse_qt4_evolution/synti/zynaddsubfx/Synth/Resonance.C')
-rw-r--r-- | muse_qt4_evolution/synti/zynaddsubfx/Synth/Resonance.C | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/muse_qt4_evolution/synti/zynaddsubfx/Synth/Resonance.C b/muse_qt4_evolution/synti/zynaddsubfx/Synth/Resonance.C new file mode 100644 index 00000000..fb741055 --- /dev/null +++ b/muse_qt4_evolution/synti/zynaddsubfx/Synth/Resonance.C @@ -0,0 +1,231 @@ +/* + ZynAddSubFX - a software synthesizer + + Resonance.C - Resonance + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include <math.h> +#include <stdlib.h> +#include "Resonance.h" + + +#include <stdio.h> + +Resonance::Resonance():Presets(){ + setpresettype("Presonance"); + defaults(); +}; + +Resonance::~Resonance(){ +}; + + +void Resonance::defaults(){ + Penabled=0; + PmaxdB=20; + Pcenterfreq=64;//1 kHz + Poctavesfreq=64; + Pprotectthefundamental=0; + ctlcenter=1.0; + ctlbw=1.0; + for (int i=0;i<N_RES_POINTS;i++) Prespoints[i]=64; +}; + +/* + * Set a point of resonance function with a value + */ +void Resonance::setpoint(int n,unsigned char p){ + if ((n<0)||(n>=N_RES_POINTS)) return; + Prespoints[n]=p; +}; + +/* + * Apply the resonance to FFT data + */ +void Resonance::applyres(int n,FFTFREQS fftdata,REALTYPE freq){ + if (Penabled==0) return;//if the resonance is disabled + REALTYPE sum=0.0, + l1=log(getfreqx(0.0)*ctlcenter), + l2=log(2.0)*getoctavesfreq()*ctlbw; + + for (int i=0;i<N_RES_POINTS;i++) if (sum<Prespoints[i]) sum=Prespoints[i]; + if (sum<1.0) sum=1.0; + + for (int i=1;i<n;i++){ + REALTYPE x=(log(freq*i)-l1)/l2;//compute where the n-th hamonics fits to the graph + if (x<0.0) x=0.0; + + x*=N_RES_POINTS; + REALTYPE dx=x-floor(x);x=floor(x); + int kx1=(int)x; if (kx1>=N_RES_POINTS) kx1=N_RES_POINTS-1; + int kx2=kx1+1;if (kx2>=N_RES_POINTS) kx2=N_RES_POINTS-1; + REALTYPE y=(Prespoints[kx1]*(1.0-dx)+Prespoints[kx2]*dx)/127.0-sum/127.0; + + y=pow(10.0,y*PmaxdB/20.0); + + if ((Pprotectthefundamental!=0)&&(i==1)) y=1.0; + + fftdata.c[i]*=y; + fftdata.s[i]*=y; + }; +}; + +/* + * Gets the response at the frequency "freq" + */ + +REALTYPE Resonance::getfreqresponse(REALTYPE freq){ + REALTYPE l1=log(getfreqx(0.0)*ctlcenter), + l2=log(2.0)*getoctavesfreq()*ctlbw,sum=0.0; + + for (int i=0;i<N_RES_POINTS;i++) if (sum<Prespoints[i]) sum=Prespoints[i]; + if (sum<1.0) sum=1.0; + + REALTYPE x=(log(freq)-l1)/l2;//compute where the n-th hamonics fits to the graph + if (x<0.0) x=0.0; + x*=N_RES_POINTS; + REALTYPE dx=x-floor(x);x=floor(x); + int kx1=(int)x; if (kx1>=N_RES_POINTS) kx1=N_RES_POINTS-1; + int kx2=kx1+1;if (kx2>=N_RES_POINTS) kx2=N_RES_POINTS-1; + REALTYPE result=(Prespoints[kx1]*(1.0-dx)+Prespoints[kx2]*dx)/127.0-sum/127.0; + result=pow(10.0,result*PmaxdB/20.0); + return(result); +}; + + +/* + * Smooth the resonance function + */ +void Resonance::smooth(){ + REALTYPE old=Prespoints[0]; + for (int i=0;i<N_RES_POINTS;i++){ + old=old*0.4+Prespoints[i]*0.6; + Prespoints[i]=(int) old; + }; + old=Prespoints[N_RES_POINTS-1]; + for (int i=N_RES_POINTS-1;i>0;i--){ + old=old*0.4+Prespoints[i]*0.6; + Prespoints[i]=(int) old+1; + if (Prespoints[i]>127) Prespoints[i]=127; + }; +}; + +/* + * Randomize the resonance function + */ +void Resonance::randomize(int type){ + int r=(int)(RND*127.0); + for (int i=0;i<N_RES_POINTS;i++){ + Prespoints[i]=r; + if ((RND<0.1)&&(type==0)) r=(int)(RND*127.0); + if ((RND<0.3)&&(type==1)) r=(int)(RND*127.0); + if (type==2) r=(int)(RND*127.0); + }; + smooth(); +}; + +/* + * Interpolate the peaks + */ +void Resonance::interpolatepeaks(int type){ + int x1=0,y1=Prespoints[0]; + for (int i=1;i<N_RES_POINTS;i++){ + if ((Prespoints[i]!=64)||(i+1==N_RES_POINTS)){ + int y2=Prespoints[i]; + for (int k=0;k<i-x1;k++){ + float x=(float) k/(i-x1); + if (type==0) x=(1-cos(x*PI))*0.5; + Prespoints[x1+k]=(int)(y1*(1.0-x)+y2*x); + }; + x1=i; + y1=y2; + }; + }; +}; + +/* + * Get the frequency from x, where x is [0..1]; x is the x coordinate + */ +REALTYPE Resonance::getfreqx(REALTYPE x){ + if (x>1.0) x=1.0; + REALTYPE octf=pow(2.0,getoctavesfreq()); + return(getcenterfreq()/sqrt(octf)*pow(octf,x)); +}; + +/* + * Get the x coordinate from frequency (used by the UI) + */ +REALTYPE Resonance::getfreqpos(REALTYPE freq){ + return((log(freq)-log(getfreqx(0.0)))/log(2.0)/getoctavesfreq()); +}; + +/* + * Get the center frequency of the resonance graph + */ +REALTYPE Resonance::getcenterfreq(){ + return(10000.0*pow(10,-(1.0-Pcenterfreq/127.0)*2.0)); +}; + +/* + * Get the number of octave that the resonance functions applies to + */ +REALTYPE Resonance::getoctavesfreq(){ + return(0.25+10.0*Poctavesfreq/127.0); +}; + +void Resonance::sendcontroller(MidiControllers ctl,REALTYPE par){ + if (ctl==C_resonance_center) ctlcenter=par; + else ctlbw=par; +}; + + + + +void Resonance::add2XML(XMLwrapper *xml){ + xml->addparbool("enabled",Penabled); + + if ((Penabled==0)&&(xml->minimal)) return; + + xml->addpar("max_db",PmaxdB); + xml->addpar("center_freq",Pcenterfreq); + xml->addpar("octaves_freq",Poctavesfreq); + xml->addparbool("protect_fundamental_frequency",Pprotectthefundamental); + xml->addpar("resonance_points",N_RES_POINTS); + for (int i=0;i<N_RES_POINTS;i++){ + xml->beginbranch("RESPOINT",i); + xml->addpar("val",Prespoints[i]); + xml->endbranch(); + }; +}; + + +void Resonance::getfromXML(XMLwrapper *xml){ + Penabled=xml->getparbool("enabled",Penabled); + + PmaxdB=xml->getpar127("max_db",PmaxdB); + Pcenterfreq=xml->getpar127("center_freq",Pcenterfreq); + Poctavesfreq=xml->getpar127("octaves_freq",Poctavesfreq); + Pprotectthefundamental=xml->getparbool("protect_fundamental_frequency",Pprotectthefundamental); + for (int i=0;i<N_RES_POINTS;i++){ + if (xml->enterbranch("RESPOINT",i)==0) continue; + Prespoints[i]=xml->getpar127("val",Prespoints[i]); + xml->exitbranch(); + }; +}; + + |