zynaddsubfx

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

commit f03fd83c8ef2ed86d8cc63938a2023e64d81c86e
parent 763bb2cc091d4a8383639803ff69ea7b16b9fe4d
Author: paulnasca <paulnasca>
Date:   Sat, 19 Jun 2004 11:51:47 +0000

*** empty log message ***

Diffstat:
MChangeLog | 2+-
Msrc/Synth/OscilGen.C | 109++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Msrc/Synth/OscilGen.h | 11++++++++++-
Msrc/UI/OscilGenUI.fl | 112++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
4 files changed, 202 insertions(+), 32 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -585,6 +585,6 @@ - Separat OscilGenUI din ADnoteUI - Inceput sa scriu modulul de sinteza PADnote 19 Iun 2004 - Adaugat modul liniar de controller bandwidth si modificat modul liniar la controllerul modulation wheel - + - Adaugata modulatia in frecventa la OsciGen diff --git a/src/Synth/OscilGen.C b/src/Synth/OscilGen.C @@ -50,6 +50,7 @@ OscilGen::~OscilGen(){ void OscilGen::defaults(){ oldbasefunc=0;oldbasepar=64;oldhmagtype=0;oldwaveshapingfunction=0;oldwaveshaping=64,oldnormalizemethod=0; oldbasefuncmodulation=0;oldharmonicshift=0;oldbasefuncmodulationpar1=0;oldbasefuncmodulationpar2=0;oldbasefuncmodulationpar3=0; + oldmodulation=0;oldmodulationpar1=0;oldmodulationpar2=0;oldmodulationpar3=0; for (int i=0;i<MAX_AD_HARMONICS;i++){ hmag[i]=0.0; hphase[i]=0.0; @@ -68,6 +69,11 @@ void OscilGen::defaults(){ Pbasefuncmodulationpar2=64; Pbasefuncmodulationpar3=32; + Pmodulation=0; + Pmodulationpar1=64; + Pmodulationpar2=64; + Pmodulationpar3=32; + Pwaveshapingfunction=0; Pwaveshaping=64; Pnormalizemethod=2; @@ -289,7 +295,7 @@ void OscilGen::oscilfilter(){ for (int i=1;i<OSCIL_SIZE/2;i++){ REALTYPE gain=1.0; switch(Pfiltertype){ - case 1: gain=pow(1.0-par*par*par,i);//lp + case 1: gain=pow(1.0-par*par*par*0.99,i);//lp break; case 2: gain=1.0-pow(1.0-par*par,i+1);//hp1 break; @@ -396,6 +402,86 @@ void OscilGen::waveshape(){ fft->smps2freqs(oscilFFTfreqs,NULL);//perform FFT }; + +/* + * Do the Frequency Modulation of the Oscil + */ +void OscilGen::modulation(){ + int i; + + oldmodulation=Pmodulation; + oldmodulationpar1=Pmodulationpar1; + oldmodulationpar2=Pmodulationpar2; + oldmodulationpar3=Pmodulationpar3; + if (Pmodulation==0) return; + + + REALTYPE modulationpar1=Pmodulationpar1/127.0, + modulationpar2=Pmodulationpar2/127.0, + modulationpar3=Pmodulationpar3/127.0; + + switch(Pmodulation){ + case 1:modulationpar1=(pow(2,modulationpar1*5.0)-1.0)/10.0; + modulationpar3=floor((pow(2,modulationpar3*5.0)-1.0)); + if (modulationpar3<0.9999) modulationpar3=-1.0; + break; + case 2:modulationpar1=(pow(2,modulationpar1*5.0)-1.0)/10.0; + modulationpar3=1.0+floor((pow(2,modulationpar3*5.0)-1.0)); + break; + case 3:modulationpar1=(pow(2,modulationpar1*7.0)-1.0)/10.0; + modulationpar3=0.01+(pow(2,modulationpar3*16.0)-1.0)/10.0; + break; + }; + + oscilFFTfreqs[0]=0.0;//remove the DC + //reduce the amplitude of the freqs near the nyquist + for (i=1;i<OSCIL_SIZE/8;i++) { + REALTYPE tmp=i/(OSCIL_SIZE/8.0); + oscilFFTfreqs[OSCIL_SIZE/2+i-1]*=tmp; + oscilFFTfreqs[OSCIL_SIZE/2-i+1]*=tmp; + }; + fft->freqs2smps(oscilFFTfreqs,NULL); + //now the oscilFFTfreqs contains *time-domain data* of samples + //I don't want to allocate another array for this + + int extra_points=2; + REALTYPE *in=new REALTYPE[OSCIL_SIZE+extra_points]; + + //Normalize + REALTYPE max=0.0; + for (i=0;i<OSCIL_SIZE;i++) + if (max<fabs(oscilFFTfreqs[i])) max=fabs(oscilFFTfreqs[i]); + if (max<0.00001) max=1.0; + max=1.0/max;for (i=0;i<OSCIL_SIZE;i++) in[i]=oscilFFTfreqs[i]*max; + for (i=0;i<extra_points;i++) in[i+OSCIL_SIZE]=oscilFFTfreqs[i]*max; + + //Do the modulation + for (i=0;i<OSCIL_SIZE;i++) { + REALTYPE t=i*1.0/OSCIL_SIZE; + + switch(Pmodulation){ + case 1:t=t*modulationpar3+sin((t+modulationpar2)*2.0*PI)*modulationpar1;//rev + break; + case 2:t=t+sin((t*modulationpar3+modulationpar2)*2.0*PI)*modulationpar1;//sine + break; + case 3:t=t+pow((1.0-cos((t+modulationpar2)*2.0*PI))*0.5,modulationpar3)*modulationpar1;//power + break; + }; + + t=(t-floor(t))*OSCIL_SIZE; + + int poshi=(int) t; + REALTYPE poslo=t-floor(t); + + oscilFFTfreqs[i]=in[poshi]*(1.0-poslo)+in[poshi+1]*poslo; + }; + + delete(in); + fft->smps2freqs(oscilFFTfreqs,NULL);//perform FFT +}; + + + /* * Adjust the spectrum */ @@ -485,8 +571,7 @@ void OscilGen::shiftharmonics(){ void OscilGen::prepare(){ int i,j,k; REALTYPE a,b,c,d,hmagnew; - - + if ((oldbasepar!=Pbasefuncpar)||(oldbasefunc!=Pcurrentbasefunc)|| (oldbasefuncmodulation!=Pbasefuncmodulation)|| (oldbasefuncmodulationpar1!=Pbasefuncmodulationpar1)|| @@ -538,6 +623,8 @@ void OscilGen::prepare(){ if (Pharmonicshiftfirst!=0) shiftharmonics(); + + if (Pfilterbeforews==0){ waveshape(); oscilfilter(); @@ -546,6 +633,7 @@ void OscilGen::prepare(){ waveshape(); }; + modulation(); spectrumadjust(); if (Pharmonicshiftfirst==0) shiftharmonics(); @@ -671,6 +759,12 @@ short int OscilGen::get(REALTYPE *smps,REALTYPE freqHz,int resonance){ (oldbasefuncmodulationpar3!=Pbasefuncmodulationpar3)) oscilprepared=0; + if ((oldmodulation!=Pmodulation)|| + (oldmodulationpar1!=Pmodulationpar1)|| + (oldmodulationpar2!=Pmodulationpar2)|| + (oldmodulationpar3!=Pmodulationpar3)) + oscilprepared=0; + if (oldharmonicshift!=Pharmonicshift+Pharmonicshiftfirst*256) oscilprepared=0; if (oscilprepared!=1) prepare(); @@ -1047,6 +1141,11 @@ void OscilGen::add2XML(XMLwrapper *xml){ xml->addpar("base_function_modulation_par2",Pbasefuncmodulationpar2); xml->addpar("base_function_modulation_par3",Pbasefuncmodulationpar3); + xml->addpar("modulation",Pmodulation); + xml->addpar("modulation_par1",Pmodulationpar1); + xml->addpar("modulation_par2",Pmodulationpar2); + xml->addpar("modulation_par3",Pmodulationpar3); + xml->addpar("wave_shaping",Pwaveshaping); xml->addpar("wave_shaping_function",Pwaveshapingfunction); @@ -1113,6 +1212,10 @@ void OscilGen::getfromXML(XMLwrapper *xml){ 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); diff --git a/src/Synth/OscilGen.h b/src/Synth/OscilGen.h @@ -76,7 +76,7 @@ class OscilGen{ unsigned char Pbasefuncpar;//the parameter of the base function unsigned char Pbasefuncmodulation;//what modulation is applied to the basefunc - unsigned char Pbasefuncmodulationpar1,Pbasefuncmodulationpar2,Pbasefuncmodulationpar3;//the parameter of the base functions + unsigned char Pbasefuncmodulationpar1,Pbasefuncmodulationpar2,Pbasefuncmodulationpar3;//the parameter of the base function modulation /*the Randomness: 64=no randomness @@ -96,6 +96,10 @@ class OscilGen{ unsigned char Padaptiveharmonics;//the adaptive harmonics status (off=0,on=1) unsigned char Padaptiveharmonicsbasefreq;//the base frequency of the adaptive harmonic (30..3000Hz) unsigned char Padaptiveharmonicspower;//the strength of the effect (0=off,100=full) + + unsigned char Pmodulation;//what modulation is applied to the oscil + unsigned char Pmodulationpar1,Pmodulationpar2,Pmodulationpar3;//the parameter of the parameters + private: @@ -116,9 +120,13 @@ class OscilGen{ //Shift the harmonics void shiftharmonics(); + //Do the oscil modulation stuff + void modulation(); + //Do the adaptive harmonic stuff void adaptiveharmonic(REALTYPE *freqs,REALTYPE freq); + //Base function saveto/loadfrom quantised data void savebasefuncQ(); void loadbasefuncQ(); @@ -141,6 +149,7 @@ class OscilGen{ //Internal Data unsigned char oldbasefunc,oldbasepar,oldhmagtype,oldwaveshapingfunction,oldwaveshaping,oldnormalizemethod; int oldfilterpars,oldsapars,oldbasefuncmodulation,oldbasefuncmodulationpar1,oldbasefuncmodulationpar2,oldbasefuncmodulationpar3,oldharmonicshift; + int oldmodulation,oldmodulationpar1,oldmodulationpar2,oldmodulationpar3; /* The frequencies of wavefroms are stored like this: c[0],c[1],....,c[OSCIL_SIZE/2],s[OSCIL_SIZE/2-1],...,s[2],s[1] diff --git a/src/UI/OscilGenUI.fl b/src/UI/OscilGenUI.fl @@ -287,7 +287,7 @@ class OscilEditor {} { Function {make_window()} {} { Fl_Window osceditUI { label {ADsynth Oscillator Editor} - xywh {66 94 750 590} type Double hide + xywh {66 94 745 590} type Double hide } { Fl_Group oscildisplaygroup { xywh {15 5 360 300} box ENGRAVED_FRAME @@ -451,11 +451,11 @@ if ((oscil->Pcurrentbasefunc==0)||(oscil->Pcurrentbasefunc==127)) basefuncmodula code0 {o->value(oscil->Pbasefuncpar-64);} } Fl_Group basefuncmodulation { - xywh {579 276 150 25} box ENGRAVED_BOX + xywh {560 276 169 25} box ENGRAVED_BOX code0 {if ((oscil->Pcurrentbasefunc==0)||(oscil->Pcurrentbasefunc==127)) basefuncmodulation->deactivate();} } { Fl_Choice {} { - label {Mod.} + label {B.F.Mod.} callback {oscil->Pbasefuncmodulation=(int) o->value(); basefuncdisplaygroup->redraw(); oscildisplaygroup->redraw(); @@ -579,7 +579,7 @@ oldosc->redraw();} Fl_Button {} { label Close callback {osceditUI->hide();} - xywh {678 557 69 28} box THIN_UP_BOX + xywh {678 557 62 28} box THIN_UP_BOX } Fl_Button {} { label Clear @@ -605,10 +605,10 @@ pthread_mutex_unlock(&master->mutex); oscildisplaygroup->redraw(); oldosc->redraw();} - xywh {685 310 50 20} box THIN_UP_BOX labelfont 1 labelsize 12 + xywh {680 530 60 20} box THIN_UP_BOX labelfont 1 labelsize 12 } Fl_Group {} { - xywh {145 305 185 30} box ENGRAVED_BOX + xywh {145 305 150 30} box ENGRAVED_BOX } { Fl_Choice wshbutton { label {Wsh.} @@ -680,12 +680,17 @@ oldosc->redraw();} open xywh {90 90 100 20} labelfont 1 labelsize 10 } } - Fl_Value_Slider {} { + Fl_Dial {} { callback {oscil->Pwaveshaping=(int)o->value()+64; -//basefuncdisplaygroup->redraw(); oscildisplaygroup->redraw(); -oldosc->redraw();} - tooltip {Waveshaping Parameter} xywh {230 315 95 10} type {Horz Knob} box FLAT_BOX labelsize 10 align 5 minimum -64 maximum 63 step 1 +oldosc->redraw(); +wsparval->value(oscil->Pbasefuncpar-64);} + tooltip {Waveshaping Parameter} xywh {270 310 20 20} minimum -64 maximum 63 step 1 + code0 {o->value(oscil->Pwaveshaping-64);} + class WidgetPDial + } + Fl_Value_Output wsparval { + xywh {238 313 25 15} labelsize 13 minimum -63 maximum 63 step 1 code0 {o->value(oscil->Pwaveshaping-64);} } } @@ -694,14 +699,14 @@ oldosc->redraw();} tooltip {Auto clear when using the oscillator as base function} xywh {105 310 35 20} box THIN_UP_BOX value 1 labelfont 1 labelsize 10 } Fl_Group {} { - xywh {330 305 160 30} box ENGRAVED_BOX + xywh {295 305 155 30} box ENGRAVED_BOX } { Fl_Choice fltbutton { label Filter callback {oscil->Pfiltertype=(int) o->value(); oscildisplaygroup->redraw(); oldosc->redraw();} - tooltip {Oscillator's filter type} xywh {360 310 50 20} down_box BORDER_BOX labelsize 10 textsize 10 + tooltip {Oscillator's filter type} xywh {325 310 50 20} down_box BORDER_BOX labelsize 10 textsize 10 code0 {o->value(oscil->Pfiltertype);} } { menuitem {} { @@ -757,7 +762,7 @@ oldosc->redraw();} callback {oscil->Pfilterpar=(int)o->value(); oscildisplaygroup->redraw(); oldosc->redraw();} - tooltip {Oscillator's filter parameter} xywh {415 310 20 20} maximum 127 step 1 + tooltip {Oscillator's filter parameter} xywh {380 310 20 20} maximum 127 step 1 code0 {o->value(oscil->Pfilterpar);} class WidgetPDial } @@ -766,7 +771,7 @@ oldosc->redraw();} callback {oscil->Pfilterbeforews=(int)o->value(); oscildisplaygroup->redraw(); oldosc->redraw();} - tooltip {Apply the filter before the waveshaping} xywh {445 310 35 20} down_box DOWN_BOX labelsize 10 align 24 + tooltip {Apply the filter before the waveshaping} xywh {410 310 35 20} down_box DOWN_BOX labelsize 10 align 24 code0 {o->value(oscil->Pfilterbeforews);} } } @@ -781,7 +786,7 @@ oldosc->redraw();} Fl_Choice {} { label Normalize callback {oscil->Pnormalizemethod=(int) o->value();} - tooltip {Normalize type (harmonic's sum/RMS) of the oscillator} xywh {680 420 60 20} down_box BORDER_BOX labelsize 10 align 5 textsize 10 + tooltip {Normalize type (harmonic's sum/RMS) of the oscillator} xywh {680 415 60 20} down_box BORDER_BOX labelsize 10 align 5 textsize 10 code0 {o->value(oscil->Pnormalizemethod);} } { menuitem {} { @@ -798,14 +803,14 @@ oldosc->redraw();} } } Fl_Group {} { - xywh {490 305 130 30} box ENGRAVED_BOX + xywh {600 305 130 30} box ENGRAVED_BOX } { Fl_Choice sabutton { label {Sp.adj.} callback {oscil->Psatype=(int) o->value(); oscildisplaygroup->redraw(); oldosc->redraw();} - tooltip {Oscillator's spectrum adjust} xywh {530 310 60 20} down_box BORDER_BOX labelsize 10 textsize 10 + tooltip {Oscillator's spectrum adjust} xywh {640 310 60 20} down_box BORDER_BOX labelsize 10 textsize 10 code0 {o->value(oscil->Psatype);} } { menuitem {} { @@ -829,20 +834,20 @@ oldosc->redraw();} callback {oscil->Psapar=(int)o->value(); oscildisplaygroup->redraw(); oldosc->redraw();} - tooltip {Oscillator's spectrum adjust parameter} xywh {595 310 20 20} maximum 127 step 1 + tooltip {Oscillator's spectrum adjust parameter} xywh {705 310 20 20} maximum 127 step 1 code0 {o->value(oscil->Psapar);} class WidgetPDial } } Fl_Group {} { - xywh {675 335 70 65} box ENGRAVED_BOX + xywh {675 335 65 65} box ENGRAVED_BOX } { Fl_Counter harmonicshiftcounter { label {Harmonic Shift} callback {oscil->Pharmonicshift=(int)o->value(); oscildisplaygroup->redraw(); oldosc->redraw();} - xywh {680 360 60 15} type Simple labelsize 10 align 129 minimum -64 maximum 64 step 1 textfont 1 textsize 10 + xywh {680 360 55 15} type Simple labelsize 10 align 129 minimum -64 maximum 64 step 1 textfont 1 textsize 10 code0 {o->value(oscil->Pharmonicshift);} } Fl_Check_Button {} { @@ -850,7 +855,7 @@ oldosc->redraw();} callback {oscil->Pharmonicshiftfirst=(int)o->value(); oscildisplaygroup->redraw(); oldosc->redraw();} - tooltip {Apply the harmonic shift before the waveshaping and filtering} xywh {706 380 35 15} down_box DOWN_BOX labelsize 10 align 24 + tooltip {Apply the harmonic shift before the waveshaping and filtering} xywh {700 380 34 15} down_box DOWN_BOX labelsize 10 align 24 code0 {o->value(oscil->Pharmonicshiftfirst);} } Fl_Button {} { @@ -859,19 +864,19 @@ oldosc->redraw();} harmonicshiftcounter->value(0); oscildisplaygroup->redraw(); oldosc->redraw();} - xywh {680 380 25 15} box THIN_UP_BOX labelfont 1 labelsize 10 + xywh {680 380 20 15} box THIN_UP_BOX labelfont 1 labelsize 10 } } Fl_Group {} { - xywh {675 445 65 90} box ENGRAVED_FRAME + xywh {675 440 65 85} box ENGRAVED_FRAME } { Fl_Box {} { label {Adaptive Harmonics} - xywh {680 445 55 25} labelsize 10 align 144 + xywh {680 440 60 25} labelsize 10 align 144 } Fl_Choice {} { callback {oscil->Padaptiveharmonics=(int) o->value();} open - tooltip {The type of the addaptive harmonics} xywh {680 470 55 15} down_box BORDER_BOX labelsize 10 textsize 10 + tooltip {The type of the addaptive harmonics} xywh {680 465 55 15} down_box BORDER_BOX labelsize 10 textsize 10 code0 {o->value(oscil->Padaptiveharmonics);} } { menuitem {} { @@ -886,18 +891,71 @@ oldosc->redraw();} Fl_Dial {} { label pow callback {oscil->Padaptiveharmonicspower=(int)o->value();} - tooltip {Adaptive harmonics power} xywh {710 495 25 25} labelsize 6 maximum 100 step 1 + tooltip {Adaptive harmonics power} xywh {710 490 25 25} labelsize 6 maximum 100 step 1 code0 {o->value(oscil->Padaptiveharmonicspower);} class WidgetPDial } Fl_Dial {} { label baseF callback {oscil->Padaptiveharmonicsbasefreq=(int)o->value();} - tooltip {Adaptive harmonics base frequency} xywh {680 495 25 25} labelsize 9 maximum 255 step 1 + tooltip {Adaptive harmonics base frequency} xywh {680 490 25 25} labelsize 9 maximum 255 step 1 code0 {o->value(oscil->Padaptiveharmonicsbasefreq);} class WidgetPDial } } + Fl_Group {} { + xywh {450 305 150 30} box ENGRAVED_BOX + } { + Fl_Choice {} { + label {Mod.} + callback {oscil->Pmodulation=(int) o->value(); +oscildisplaygroup->redraw(); +oldosc->redraw();} + tooltip modulation xywh {480 312 50 15} down_box BORDER_BOX labelsize 10 textsize 10 + code0 {o->value(oscil->Pmodulation);} + } { + menuitem {} { + label None + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Rev + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Sine + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Pow + xywh {90 90 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial {} { + callback {oscil->Pmodulationpar1=(int)o->value(); +oscildisplaygroup->redraw(); +oldosc->redraw();} + tooltip {Oscillator's modulation parameter 1} xywh {540 312 15 15} maximum 127 step 1 + code0 {o->value(oscil->Pmodulationpar1);} + class WidgetPDial + } + Fl_Dial {} { + callback {oscil->Pmodulationpar2=(int)o->value(); +oscildisplaygroup->redraw(); +oldosc->redraw();} + tooltip {Oscillator's modulation parameter 2} xywh {560 312 15 15} maximum 127 step 1 + code0 {o->value(oscil->Pmodulationpar2);} + class WidgetPDial + } + Fl_Dial {} { + callback {oscil->Pmodulationpar3=(int)o->value(); +oscildisplaygroup->redraw(); +oldosc->redraw();} + tooltip {Oscillator's modulation parameter 3} xywh {580 312 15 15} maximum 127 step 1 + code0 {o->value(oscil->Pmodulationpar3);} + class WidgetPDial + } + } } } Function {OscilEditor(OscilGen *oscil_,Fl_Widget *oldosc_,Master *master_)} {} {