summaryrefslogtreecommitdiff
path: root/attic/muse_qt4_evolution/synti/zynaddsubfx/Synth/Resonance.C
diff options
context:
space:
mode:
Diffstat (limited to 'attic/muse_qt4_evolution/synti/zynaddsubfx/Synth/Resonance.C')
-rw-r--r--attic/muse_qt4_evolution/synti/zynaddsubfx/Synth/Resonance.C231
1 files changed, 231 insertions, 0 deletions
diff --git a/attic/muse_qt4_evolution/synti/zynaddsubfx/Synth/Resonance.C b/attic/muse_qt4_evolution/synti/zynaddsubfx/Synth/Resonance.C
new file mode 100644
index 00000000..fb741055
--- /dev/null
+++ b/attic/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();
+ };
+};
+
+