zynaddsubfx

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

commit 09ae8d044ad3352bec24f9bc3da5d35c3a3ba773
parent 64eefd45a3f315aee7af86a8e9cc8510b028015e
Author: fundamental <mark.d.mccurry@gmail.com>
Date:   Fri,  9 Oct 2009 17:31:18 -0400

Style: Restylized entire codebase

Restylized entire codebase to deal with inconsistencies.
This was done with an automated run of uncrustify, so there may be some odd
formatting for now.
The guidelines for formatting are in place at the sourceforge website and all
known changes appear to fully match them.

Diffstat:
MChangeLog | 3+++
MExternalPrograms/Controller/Controller.C | 105++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
MExternalPrograms/Controller/Controller.h | 40+++++++++++++++++++++-------------------
MExternalPrograms/Controller/main.C | 9+++++----
MExternalPrograms/Spliter/Spliter.C | 117+++++++++++++++++++++++++++++++++++++++++++------------------------------------
MExternalPrograms/Spliter/Spliter.h | 24+++++++++++++-----------
MExternalPrograms/Spliter/main.C | 46++++++++++++++++++++++++----------------------
Msrc/Controls/Control.cpp | 10+++++-----
Msrc/Controls/Control.h | 52++++++++++++++++++++++++++--------------------------
Msrc/Controls/DelayCtl.cpp | 13+++++++------
Msrc/Controls/DelayCtl.h | 18+++++++++---------
Msrc/DSP/AnalogFilter.cpp | 667++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Msrc/DSP/AnalogFilter.h | 85+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/DSP/FFTwrapper.cpp | 98+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Msrc/DSP/FFTwrapper.h | 30+++++++++++++++---------------
Msrc/DSP/Filter.cpp | 51++++++++++++++++++++++++++++-----------------------
Msrc/DSP/Filter.h | 24++++++++++++------------
Msrc/DSP/Filter_.h | 18+++++++++---------
Msrc/DSP/FormantFilter.cpp | 275+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Msrc/DSP/FormantFilter.h | 60++++++++++++++++++++++++++++++------------------------------
Msrc/DSP/SVFilter.cpp | 190++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Msrc/DSP/SVFilter.h | 71+++++++++++++++++++++++++++++++++++++----------------------------------
Msrc/DSP/Unison.cpp | 300+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/DSP/Unison.h | 65+++++++++++++++++++++++++++++++++--------------------------------
Msrc/Effects/Alienwah.cpp | 236++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Msrc/Effects/Alienwah.h | 88++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/Effects/Chorus.cpp | 284++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Msrc/Effects/Chorus.h | 146++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/Effects/Distorsion.cpp | 500++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Msrc/Effects/Distorsion.h | 66++++++++++++++++++++++++++++++++++--------------------------------
Msrc/Effects/DynamicFilter.cpp | 354++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/Effects/DynamicFilter.h | 54+++++++++++++++++++++++++++---------------------------
Msrc/Effects/EQ.cpp | 196+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/Effects/EQ.h | 44+++++++++++++++++++++-----------------------
Msrc/Effects/Echo.cpp | 211++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Msrc/Effects/Echo.h | 200++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/Effects/Effect.cpp | 11++++++-----
Msrc/Effects/Effect.h | 116++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/Effects/EffectLFO.cpp | 116+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/Effects/EffectLFO.h | 36++++++++++++++++++------------------
Msrc/Effects/EffectMgr.cpp | 297+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/Effects/EffectMgr.h | 112++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/Effects/Phaser.cpp | 577++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/Effects/Phaser.h | 152++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/Effects/Reverb.cpp | 1063+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/Effects/Reverb.h | 270++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/Input/ALSAMidiIn.cpp | 88+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/Input/ALSAMidiIn.h | 28+++++++++++++++-------------
Msrc/Input/MidiIn.cpp | 53+++++++++++++++++++++++++++--------------------------
Msrc/Input/MidiIn.h | 28++++++++++++++++------------
Msrc/Input/NULLMidiIn.cpp | 14+++++++-------
Msrc/Input/NULLMidiIn.h | 28+++++++++++++++-------------
Msrc/Input/OSSMidiIn.cpp | 107+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/Input/OSSMidiIn.h | 31++++++++++++++++---------------
Msrc/Input/WINMidiIn.cpp | 71+++++++++++++++++++++++++++++++++++++++--------------------------------
Msrc/Misc/Bank.cpp | 694+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/Misc/Bank.h | 96++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/Misc/Config.cpp | 422+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Msrc/Misc/Config.h | 68++++++++++++++++++++++++++++++++++----------------------------------
Msrc/Misc/Control.h | 122++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/Misc/Dump.cpp | 117+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Msrc/Misc/Dump.h | 59++++++++++++++++++++++++++++++-----------------------------
Msrc/Misc/LASHClient.cpp | 52++++++++++++++++++++++++++--------------------------
Msrc/Misc/LASHClient.h | 44++++++++++++++++++++++----------------------
Msrc/Misc/Master.cpp | 916++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Msrc/Misc/Master.h | 183+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/Misc/Microtonal.cpp | 816++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Msrc/Misc/Microtonal.h | 190+++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/Misc/Part.cpp | 1578+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Msrc/Misc/Part.h | 280++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/Misc/Stereo.cpp | 17+++++++++--------
Msrc/Misc/Stereo.h | 71+++++++++++++++++++++++++++++++++++------------------------------------
Msrc/Misc/Util.cpp | 83++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Msrc/Misc/Util.h | 16+++++++++-------
Msrc/Misc/XMLwrapper.cpp | 567+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Msrc/Misc/XMLwrapper.h | 458++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/Output/DSSIaudiooutput.cpp | 141+++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/Output/DSSIaudiooutput.h | 28++++++++++++++--------------
Msrc/Output/JACK_RTaudiooutput.cpp | 255+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/Output/JACKaudiooutput.cpp | 158+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Msrc/Output/JACKaudiooutput.h | 13+++++++------
Msrc/Output/OSSaudiooutput.cpp | 102++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Msrc/Output/OSSaudiooutput.h | 32++++++++++++++++----------------
Msrc/Output/PAaudiooutput.cpp | 61++++++++++++++++++++++++++++++++++---------------------------
Msrc/Output/Recorder.cpp | 99+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/Output/Recorder.h | 45+++++++++++++++++++++++----------------------
Msrc/Output/VSTaudiooutput.cpp | 43+++++++++++++++++++++++--------------------
Msrc/Output/VSTaudiooutput.h | 42++++++++++++++++++++++--------------------
Msrc/Output/WAVaudiooutput.cpp | 106++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/Output/WAVaudiooutput.h | 25+++++++++++++------------
Msrc/Params/ADnoteParameters.cpp | 899+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Msrc/Params/ADnoteParameters.h | 140++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/Params/Controller.cpp | 491++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Msrc/Params/Controller.h | 368++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/Params/EnvelopeParams.cpp | 371++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/Params/EnvelopeParams.h | 100+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/Params/FilterParams.cpp | 457++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Msrc/Params/FilterParams.h | 116++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/Params/LFOParams.cpp | 96++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Msrc/Params/LFOParams.h | 65++++++++++++++++++++++++++++++++++++-----------------------------
Msrc/Params/PADnoteParameters.cpp | 1027+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/Params/PADnoteParameters.h | 214++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Msrc/Params/Presets.cpp | 133+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/Params/Presets.h | 48++++++++++++++++++++++++------------------------
Msrc/Params/PresetsStore.cpp | 244+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Msrc/Params/PresetsStore.h | 59+++++++++++++++++++++++++++++------------------------------
Msrc/Params/SUBnoteParameters.cpp | 252+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/Params/SUBnoteParameters.h | 100+++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/Samples/AuSample.cpp | 8++++----
Msrc/Samples/AuSample.h | 11+++++------
Msrc/Samples/FqSample.cpp | 8++++----
Msrc/Samples/FqSample.h | 14+++++++-------
Msrc/Samples/Sample.cpp | 102++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/Samples/Sample.h | 76+++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/Seq/MIDIEvents.cpp | 73+++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/Seq/MIDIEvents.h | 57++++++++++++++++++++++++++++-----------------------------
Msrc/Seq/MIDIFile.cpp | 433+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/Seq/MIDIFile.h | 84+++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/Seq/Sequencer.cpp | 153+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/Seq/Sequencer.h | 83+++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/Synth/ADnote.cpp | 2662+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Msrc/Synth/ADnote.h | 505+++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/Synth/Envelope.cpp | 226+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/Synth/Envelope.h | 54+++++++++++++++++++++++++++---------------------------
Msrc/Synth/LFO.cpp | 177+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Msrc/Synth/LFO.h | 49++++++++++++++++++++++++-------------------------
Msrc/Synth/OscilGen.cpp | 1958+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/Synth/OscilGen.h | 243++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/Synth/PADnote.cpp | 765++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Msrc/Synth/PADnote.h | 163++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Msrc/Synth/Resonance.cpp | 307+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/Synth/Resonance.h | 67++++++++++++++++++++++++++++++++++---------------------------------
Msrc/Synth/SUBnote.cpp | 961++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Msrc/Synth/SUBnote.h | 173+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/Tests/AdNoteTest.h | 219++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/Tests/ControllerTest.h | 77++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/Tests/EchoTest.h | 136++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/Tests/MicrotonalTest.h | 218++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/Tests/SampleTest.h | 92++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/Tests/SubNoteTest.h | 210++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/Tests/XMLwrapperTest.h | 32++++++++++++++++----------------
Msrc/globals.h | 64++++++++++++++++++++++++++++++++++++++++++----------------------
Msrc/main.cpp | 663++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
143 files changed, 17413 insertions(+), 14837 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -954,3 +954,6 @@ - Started to see if memset/memcpy offer performance benifits when widely used - Added basic SUBnote test + +09 Oct 2009 (Mark McCurry) + - Restylized codebase with uncrustify diff --git a/ExternalPrograms/Controller/Controller.C b/ExternalPrograms/Controller/Controller.C @@ -6,69 +6,80 @@ pthread_mutex_t mutex; int Pexitprogram; -Controller::Controller(){ +Controller::Controller() { //init - for (int i=0;i<6;i++){ - pars[i].mode=1; - pars[i].val1=0; - pars[i].val2=127; - pars[i].nrpn.cpar=8; - pars[i].nrpn.fpar=0; - pars[i].nrpn.cval=0; - }; - pars[0].ctl.par=71; - pars[1].ctl.par=74; - pars[2].ctl.par=10; - pars[3].ctl.par=11; - pars[4].ctl.par=1; - pars[5].ctl.par=75; - + for(int i = 0; i < 6; i++) { + pars[i].mode = 1; + pars[i].val1 = 0; + pars[i].val2 = 127; + pars[i].nrpn.cpar = 8; + pars[i].nrpn.fpar = 0; + pars[i].nrpn.cval = 0; + } + pars[0].ctl.par = 71; + pars[1].ctl.par = 74; + pars[2].ctl.par = 10; + pars[3].ctl.par = 11; + pars[4].ctl.par = 1; + pars[5].ctl.par = 75; + //ALSA init - snd_seq_open(&midi_out,"default",SND_SEQ_OPEN_OUTPUT,0); + snd_seq_open(&midi_out, "default", SND_SEQ_OPEN_OUTPUT, 0); - char portname[50];sprintf(portname,"Controller"); - int alsaport = snd_seq_create_simple_port(midi_out,portname - ,SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ - ,SND_SEQ_PORT_TYPE_SYNTH); -}; + char portname[50]; sprintf(portname, "Controller"); + int alsaport = snd_seq_create_simple_port( + midi_out, + portname, + SND_SEQ_PORT_CAP_READ + | SND_SEQ_PORT_CAP_SUBS_READ, + SND_SEQ_PORT_TYPE_SYNTH); +} -Controller::~Controller(){ +Controller::~Controller() { snd_seq_close(midi_out); -}; +} -void Controller::sendcontroller(int par,unsigned char val){ +void Controller::sendcontroller(int par, unsigned char val) { snd_seq_event_t midievent; snd_seq_ev_clear(&midievent); - snd_seq_ev_set_controller(&midievent,Pchout,par,val); + snd_seq_ev_set_controller(&midievent, Pchout, par, val); - snd_seq_ev_set_subs(&midievent); + snd_seq_ev_set_subs(&midievent); snd_seq_ev_set_direct(&midievent); - snd_seq_event_output_direct(midi_out,&midievent); - + snd_seq_event_output_direct(midi_out, &midievent); + // fprintf(stderr,"Controller: %d %d\n",par,val); -}; +} -void Controller::sendnrpn(int npar,unsigned char val){ +void Controller::sendnrpn(int npar, unsigned char val) { // fprintf(stderr,"NRPN: %d %d %d %d\n",pars[npar].nrpn.cpar,pars[npar].nrpn.fpar,pars[npar].nrpn.cval,val); - sendcontroller(0x99,pars[npar].nrpn.cpar); - sendcontroller(0x98,pars[npar].nrpn.fpar); - sendcontroller(0x06,pars[npar].nrpn.cval); - sendcontroller(0x26,val); + sendcontroller(0x99, pars[npar].nrpn.cpar); + sendcontroller(0x98, pars[npar].nrpn.fpar); + sendcontroller(0x06, pars[npar].nrpn.cval); + sendcontroller(0x26, val); // fprintf(stderr,"------------\n\n"); -}; +} -void Controller::send(int npar,float xval){ - if (pars[npar].mode==0) return; +void Controller::send(int npar, float xval) { + if(pars[npar].mode == 0) + return; int val; - if (pars[npar].val1<=pars[npar].val2) - val=(int) (xval*(pars[npar].val2-pars[npar].val1+1.0)*0.9999+pars[npar].val1); - else val=(int) (xval*(pars[npar].val2-pars[npar].val1-1.0)*0.9999+pars[npar].val1+1.0); - switch (pars[npar].mode){ - case 1:sendcontroller(pars[npar].ctl.par,val);break; - //case 2:break; - case 3:sendnrpn(npar,val);break; - }; -}; + if(pars[npar].val1 <= pars[npar].val2) + val = + (int) (xval + * (pars[npar].val2 - pars[npar].val1 + + 1.0) * 0.9999 + pars[npar].val1); + else + val = + (int) (xval + * (pars[npar].val2 - pars[npar].val1 + - 1.0) * 0.9999 + pars[npar].val1 + 1.0); + switch(pars[npar].mode) { + case 1: sendcontroller(pars[npar].ctl.par, val); break; + //case 2:break; + case 3: sendnrpn(npar, val); break; + } +} diff --git a/ExternalPrograms/Controller/Controller.h b/ExternalPrograms/Controller/Controller.h @@ -5,28 +5,30 @@ extern pthread_mutex_t mutex; extern int Pexitprogram; -class Controller{ +class Controller +{ public: - Controller(); - ~Controller(); - void send(int npar,float xval); - //parameters - unsigned char Pchout; - struct{ - unsigned char mode;//0=off,1=ctl,2=RPN,3=NRPN - unsigned char val1,val2; - struct { - unsigned char par; - } ctl; - struct { - unsigned char cpar,fpar,cval; - } nrpn; - }pars[6]; + Controller(); + ~Controller(); + void send(int npar, float xval); + //parameters + unsigned char Pchout; + struct { + unsigned char mode; //0=off,1=ctl,2=RPN,3=NRPN + unsigned char val1, val2; + struct { + unsigned char par; + } ctl; + struct { + unsigned char cpar, fpar, cval; + } nrpn; + } pars[6]; private: - void sendcontroller(int par,unsigned char val); - void sendnrpn(int npar,unsigned char val); + void sendcontroller(int par, unsigned char val); + void sendnrpn(int npar, unsigned char val); - snd_seq_t *midi_out; + snd_seq_t *midi_out; }; #endif + diff --git a/ExternalPrograms/Controller/main.C b/ExternalPrograms/Controller/main.C @@ -1,16 +1,17 @@ #include "Controller.h" #include "ControllerUI.h" -pthread_t thr1,thr2; +pthread_t thr1, thr2; Controller controller; -main(){ - ControllerUI *controllerUI=new ControllerUI(&controller); +main() +{ + ControllerUI *controllerUI = new ControllerUI(&controller); Fl::run(); - + delete controllerUI; }; diff --git a/ExternalPrograms/Spliter/Spliter.C b/ExternalPrograms/Spliter/Spliter.C @@ -1,4 +1,4 @@ -//Copyright (c) 2002-2003 Nasca Octavian Paul +//Copyright (c) 2002-2003 Nasca Octavian Paul //License: GNU GPL 2 #include "Spliter.h" @@ -7,66 +7,77 @@ pthread_mutex_t mutex; int Pexitprogram; -Spliter::Spliter(){ +Spliter::Spliter() { //init - Psplitpoint=60; - Pchin=0; - Pchout1=0; - Pchout2=1; - Poct1=0; - Poct2=0; + Psplitpoint = 60; + Pchin = 0; + Pchout1 = 0; + Pchout2 = 1; + Poct1 = 0; + Poct2 = 0; //ALSA init - snd_seq_open(&midi_in,"default",SND_SEQ_OPEN_INPUT,0); - snd_seq_open(&midi_out,"default",SND_SEQ_OPEN_OUTPUT,0); + snd_seq_open(&midi_in, "default", SND_SEQ_OPEN_INPUT, 0); + snd_seq_open(&midi_out, "default", SND_SEQ_OPEN_OUTPUT, 0); - char portname[50];sprintf(portname,"Spliter IN"); - int alsaport = snd_seq_create_simple_port(midi_in,portname - ,SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE - ,SND_SEQ_PORT_TYPE_SYNTH); - sprintf(portname,"Spliter OUT"); - alsaport = snd_seq_create_simple_port(midi_out,portname - ,SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ - ,SND_SEQ_PORT_TYPE_SYNTH); + char portname[50]; sprintf(portname, "Spliter IN"); + int alsaport = snd_seq_create_simple_port( + midi_in, + portname, + SND_SEQ_PORT_CAP_WRITE + | SND_SEQ_PORT_CAP_SUBS_WRITE, + SND_SEQ_PORT_TYPE_SYNTH); + sprintf(portname, "Spliter OUT"); + alsaport = snd_seq_create_simple_port( + midi_out, + portname, + SND_SEQ_PORT_CAP_READ + | SND_SEQ_PORT_CAP_SUBS_READ, + SND_SEQ_PORT_TYPE_SYNTH); +} - -}; - -Spliter::~Spliter(){ +Spliter::~Spliter() { snd_seq_close(midi_in); snd_seq_close(midi_out); -}; +} // This splits the Midi events from one channel to another two channels -void Spliter::midievents(){ +void Spliter::midievents() { snd_seq_event_t *midievent; - midievent=NULL; - snd_seq_event_input(midi_in,&midievent); - - if (midievent==NULL) return; - if ((midievent->type==SND_SEQ_EVENT_NOTEON)||(midievent->type==SND_SEQ_EVENT_NOTEOFF)){ - int cmdchan=midievent->data.note.channel; - if (cmdchan==Pchin){ - snd_seq_ev_set_subs(midievent); - snd_seq_ev_set_direct(midievent); - if (midievent->data.note.note<Psplitpoint) { - midievent->data.note.channel=Pchout1; - int tmp=midievent->data.note.note; - tmp+=Poct1*12;if (tmp>127) tmp=127;if (tmp<0) tmp=0; - midievent->data.note.note=tmp; - } else { - midievent->data.note.channel=Pchout2; - int tmp=midievent->data.note.note; - tmp+=Poct2*12;if (tmp>127) tmp=127;if (tmp<0) tmp=0; - midievent->data.note.note=tmp; - }; - snd_seq_event_output_direct(midi_out,midievent); - } else { - snd_seq_ev_set_subs(midievent); - snd_seq_ev_set_direct(midievent); - snd_seq_event_output_direct(midi_out,midievent); - }; - - }; + midievent = NULL; + snd_seq_event_input(midi_in, &midievent); + + if(midievent == NULL) + return; + if((midievent->type == SND_SEQ_EVENT_NOTEON) + || (midievent->type == SND_SEQ_EVENT_NOTEOFF)) { + int cmdchan = midievent->data.note.channel; + if(cmdchan == Pchin) { + snd_seq_ev_set_subs(midievent); + snd_seq_ev_set_direct(midievent); + if(midievent->data.note.note < Psplitpoint) { + midievent->data.note.channel = Pchout1; + int tmp = midievent->data.note.note; + tmp += Poct1 * 12; if(tmp > 127) + tmp = 127;if(tmp < 0) + tmp = 0; + midievent->data.note.note = tmp; + } + else { + midievent->data.note.channel = Pchout2; + int tmp = midievent->data.note.note; + tmp += Poct2 * 12; if(tmp > 127) + tmp = 127;if(tmp < 0) + tmp = 0; + midievent->data.note.note = tmp; + } + snd_seq_event_output_direct(midi_out, midievent); + } + else { + snd_seq_ev_set_subs(midievent); + snd_seq_ev_set_direct(midievent); + snd_seq_event_output_direct(midi_out, midievent); + } + } snd_seq_free_event(midievent); -}; +} diff --git a/ExternalPrograms/Spliter/Spliter.h b/ExternalPrograms/Spliter/Spliter.h @@ -1,4 +1,4 @@ -//Copyright (c) 2002-2003 Nasca Octavian Paul +//Copyright (c) 2002-2003 Nasca Octavian Paul //License: GNU GPL 2 #ifndef SPLITER_H @@ -9,18 +9,20 @@ extern pthread_mutex_t mutex; extern int Pexitprogram; -class Spliter{ +class Spliter +{ public: - Spliter(); - ~Spliter(); - void midievents(); - - //parameters - unsigned char Psplitpoint; - unsigned char Pchin,Pchout1,Pchout2; - signed char Poct1,Poct2; + Spliter(); + ~Spliter(); + void midievents(); + + //parameters + unsigned char Psplitpoint; + unsigned char Pchin, Pchout1, Pchout2; + signed char Poct1, Poct2; private: - snd_seq_t *midi_in,*midi_out; + snd_seq_t *midi_in, *midi_out; }; #endif + diff --git a/ExternalPrograms/Spliter/main.C b/ExternalPrograms/Spliter/main.C @@ -1,35 +1,37 @@ -//Copyright (c) 2002-2003 Nasca Octavian Paul +//Copyright (c) 2002-2003 Nasca Octavian Paul //License: GNU GPL 2 #include <pthread.h> #include "Spliter.h" #include "SpliterUI.h" -pthread_t thr1,thr2; -Spliter spliter; +pthread_t thr1, thr2; +Spliter spliter; -void *thread1(void *arg){ +void *thread1(void *arg) { Fl::run(); - return(0); -}; -void *thread2(void *arg){ - while (Pexitprogram==0) spliter.midievents(); - return(0); -}; + return 0; +} +void *thread2(void *arg) { + while(Pexitprogram == 0) + spliter.midievents(); + return 0; +} + + +main() +{ + Pexitprogram = 0; + SpliterUI *spliterUI = new SpliterUI(&spliter); + + pthread_mutex_init(&mutex, NULL); + pthread_create(&thr1, NULL, thread1, NULL); + pthread_create(&thr2, NULL, thread2, NULL); + while(Pexitprogram == 0) { + usleep(100000); + } -main(){ - Pexitprogram=0; - SpliterUI *spliterUI=new SpliterUI(&spliter); - - pthread_mutex_init(&mutex,NULL); - pthread_create(&thr1,NULL,thread1,NULL); - pthread_create(&thr2,NULL,thread2,NULL); - - while (Pexitprogram==0){ - usleep(100000); - }; - pthread_mutex_destroy(&mutex); delete spliterUI; }; diff --git a/src/Controls/Control.cpp b/src/Controls/Control.cpp @@ -22,19 +22,19 @@ #include "Control.h" Control::Control(char ndefaultval) - :defaultval(ndefaultval),lockqueue(-1),locked(false) + :defaultval(ndefaultval), lockqueue(-1), locked(false) {} void Control::lock() { - locked=true; - lockqueue=-1; + locked = true; + lockqueue = -1; } void Control::ulock() { - if (locked&&lockqueue>=0) + if(locked && (lockqueue >= 0)) setmVal(lockqueue); - locked=false; + locked = false; } diff --git a/src/Controls/Control.h b/src/Controls/Control.h @@ -25,33 +25,33 @@ /**A control for a parameter within the program*/ class Control { -public: - Control(char ndefaultval);/**\todo create proper initialization list*/ - ~Control() {}; - /**Return the string, which represents the internal value - * @return a string representation of the current value*/ - virtual std::string getString()const=0; - /**Set the Control to the given value - * @param nval A number 0-127*/ - virtual void setmVal(char nval)=0; - /**Return the midi value (aka the char) - * @return the current value*/ - virtual char getmVal()const=0; - /** Will lock the Control until it is ulocked - * - * Locking a Control will Stop it from having - * its internal data altered*/ - void lock(); - /** Will unlock the Control - * - * This will also update the Control - * if something attempted to update it while it was locked*/ - void ulock(); -private: - char defaultval;/**<Default value of the Control*/ - char lockqueue; /**<The value is that is stored, while the Control is locked + public: + Control(char ndefaultval); /**\todo create proper initialization list*/ + ~Control() {} + /**Return the string, which represents the internal value + * @return a string representation of the current value*/ + virtual std::string getString() const = 0; + /**Set the Control to the given value + * @param nval A number 0-127*/ + virtual void setmVal(char nval) = 0; + /**Return the midi value (aka the char) + * @return the current value*/ + virtual char getmVal() const = 0; + /** Will lock the Control until it is ulocked + * + * Locking a Control will Stop it from having + * its internal data altered*/ + void lock(); + /** Will unlock the Control + * + * This will also update the Control + * if something attempted to update it while it was locked*/ + void ulock(); + private: + char defaultval; /**<Default value of the Control*/ + char lockqueue; /**<The value is that is stored, while the Control is locked * and something attempts to update it*/ - bool locked;//upgrade this to a integer lock level if problems occur + bool locked; //upgrade this to a integer lock level if problems occur }; #endif diff --git a/src/Controls/DelayCtl.cpp b/src/Controls/DelayCtl.cpp @@ -23,28 +23,29 @@ #include <sstream> DelayCtl::DelayCtl() - :Control(64),value(64/127.0*1.5) {} /**\todo finishme*/ + :Control(64), value(64 / 127.0 * 1.5) {} /**\todo finishme*/ std::string DelayCtl::getString() const { std::ostringstream buf; - buf<<value; - return (buf.str() + " Seconds"); + buf << value; + return buf.str() + " Seconds"; } void DelayCtl::setmVal(char nval) { /**\todo add locking code*/ //value=1+(int)(nval/127.0*SAMPLE_RATE*1.5);//0 .. 1.5 sec - value=(nval/127.0*1.5);//0 .. 1.5 sec + value = (nval / 127.0 * 1.5); //0 .. 1.5 sec } char DelayCtl::getmVal() const { - return((char)(value/1.5*127.0)); + return (char)(value / 1.5 * 127.0); } float DelayCtl::getiVal() const { - return(value); + return value; } + diff --git a/src/Controls/DelayCtl.h b/src/Controls/DelayCtl.h @@ -28,15 +28,15 @@ * Will vary from 0 seconds to 1.5 seconds*/ class DelayCtl:public Control { -public: - DelayCtl(); - ~DelayCtl() {}; - std::string getString() const; - void setmVal(char nval); - char getmVal() const; - float getiVal() const; -private: - float value; + public: + DelayCtl(); + ~DelayCtl() {} + std::string getString() const; + void setmVal(char nval); + char getmVal() const; + float getiVal() const; + private: + float value; }; #endif diff --git a/src/DSP/AnalogFilter.cpp b/src/DSP/AnalogFilter.cpp @@ -24,384 +24,427 @@ #include <stdio.h> #include "AnalogFilter.h" -AnalogFilter::AnalogFilter(unsigned char Ftype,REALTYPE Ffreq, REALTYPE Fq,unsigned char Fstages) +AnalogFilter::AnalogFilter(unsigned char Ftype, + REALTYPE Ffreq, + REALTYPE Fq, + unsigned char Fstages) { - stages=Fstages; - for (int i=0;i<3;i++) { - oldc[i]=0.0; - oldd[i]=0.0; - c[i]=0.0; - d[i]=0.0; - }; - type=Ftype; - freq=Ffreq; - q=Fq; - gain=1.0; - if (stages>=MAX_FILTER_STAGES) stages=MAX_FILTER_STAGES; + stages = Fstages; + for(int i = 0; i < 3; i++) { + oldc[i] = 0.0; + oldd[i] = 0.0; + c[i] = 0.0; + d[i] = 0.0; + } + type = Ftype; + freq = Ffreq; + q = Fq; + gain = 1.0; + if(stages >= MAX_FILTER_STAGES) + stages = MAX_FILTER_STAGES; cleanup(); - firsttime=0; - abovenq=0; - oldabovenq=0; - setfreq_and_q(Ffreq,Fq); - firsttime=1; - d[0]=0;//this is not used - outgain=1.0; -}; + firsttime = 0; + abovenq = 0; + oldabovenq = 0; + setfreq_and_q(Ffreq, Fq); + firsttime = 1; + d[0] = 0; //this is not used + outgain = 1.0; +} AnalogFilter::~AnalogFilter() -{ -}; +{} void AnalogFilter::cleanup() { - for (int i=0;i<MAX_FILTER_STAGES+1;i++) { - x[i].c1=0.0; - x[i].c2=0.0; - y[i].c1=0.0; - y[i].c2=0.0; - oldx[i]=x[i]; - oldy[i]=y[i]; - }; - needsinterpolation=0; -}; + for(int i = 0; i < MAX_FILTER_STAGES + 1; i++) { + x[i].c1 = 0.0; + x[i].c2 = 0.0; + y[i].c1 = 0.0; + y[i].c2 = 0.0; + oldx[i] = x[i]; + oldy[i] = y[i]; + } + needsinterpolation = 0; +} void AnalogFilter::computefiltercoefs() { REALTYPE tmp; - REALTYPE omega,sn,cs,alpha,beta; - int zerocoefs=0;//this is used if the freq is too high + REALTYPE omega, sn, cs, alpha, beta; + int zerocoefs = 0; //this is used if the freq is too high //do not allow frequencies bigger than samplerate/2 - REALTYPE freq=this->freq; - if (freq>(SAMPLE_RATE/2-500.0)) { - freq=SAMPLE_RATE/2-500.0; - zerocoefs=1; - }; - if (freq<0.1) freq=0.1; + REALTYPE freq = this->freq; + if(freq > (SAMPLE_RATE / 2 - 500.0)) { + freq = SAMPLE_RATE / 2 - 500.0; + zerocoefs = 1; + } + if(freq < 0.1) + freq = 0.1; //do not allow bogus Q - if (q<0.0) q=0.0; - REALTYPE tmpq,tmpgain; - if (stages==0) { - tmpq=q; - tmpgain=gain; - } else { - tmpq=(q>1.0 ? pow(q,1.0/(stages+1)) : q); - tmpgain=pow(gain,1.0/(stages+1)); - }; + if(q < 0.0) + q = 0.0; + REALTYPE tmpq, tmpgain; + if(stages == 0) { + tmpq = q; + tmpgain = gain; + } + else { + tmpq = (q > 1.0 ? pow(q, 1.0 / (stages + 1)) : q); + tmpgain = pow(gain, 1.0 / (stages + 1)); + } //most of theese are implementations of //the "Cookbook formulae for audio EQ" by Robert Bristow-Johnson //The original location of the Cookbook is: //http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt - switch (type) { - case 0://LPF 1 pole - if (zerocoefs==0) tmp=exp(-2.0*PI*freq/SAMPLE_RATE); - else tmp=0.0; - c[0]=1.0-tmp; - c[1]=0.0; - c[2]=0.0; - d[1]=tmp; - d[2]=0.0; - order=1; + switch(type) { + case 0: //LPF 1 pole + if(zerocoefs == 0) + tmp = exp(-2.0 * PI * freq / SAMPLE_RATE); + else + tmp = 0.0; + c[0] = 1.0 - tmp; + c[1] = 0.0; + c[2] = 0.0; + d[1] = tmp; + d[2] = 0.0; + order = 1; break; - case 1://HPF 1 pole - if (zerocoefs==0) tmp=exp(-2.0*PI*freq/SAMPLE_RATE); - else tmp=0.0; - c[0]=(1.0+tmp)/2.0; - c[1]=-(1.0+tmp)/2.0; - c[2]=0.0; - d[1]=tmp; - d[2]=0.0; - order=1; + case 1: //HPF 1 pole + if(zerocoefs == 0) + tmp = exp(-2.0 * PI * freq / SAMPLE_RATE); + else + tmp = 0.0; + c[0] = (1.0 + tmp) / 2.0; + c[1] = -(1.0 + tmp) / 2.0; + c[2] = 0.0; + d[1] = tmp; + d[2] = 0.0; + order = 1; break; - case 2://LPF 2 poles - if (zerocoefs==0) { - omega=2*PI*freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - alpha=sn/(2*tmpq); - tmp=1+alpha; - c[0]=(1.0-cs)/2.0/tmp; - c[1]=(1.0-cs)/tmp; - c[2]=(1.0-cs)/2.0/tmp; - d[1]=-2*cs/tmp*(-1); - d[2]=(1-alpha)/tmp*(-1); - } else { - c[0]=1.0; - c[1]=0.0; - c[2]=0.0; - d[1]=0.0; - d[2]=0.0; - }; - order=2; + case 2: //LPF 2 poles + if(zerocoefs == 0) { + omega = 2 * PI * freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + alpha = sn / (2 * tmpq); + tmp = 1 + alpha; + c[0] = (1.0 - cs) / 2.0 / tmp; + c[1] = (1.0 - cs) / tmp; + c[2] = (1.0 - cs) / 2.0 / tmp; + d[1] = -2 * cs / tmp * (-1); + d[2] = (1 - alpha) / tmp * (-1); + } + else { + c[0] = 1.0; + c[1] = 0.0; + c[2] = 0.0; + d[1] = 0.0; + d[2] = 0.0; + } + order = 2; break; - case 3://HPF 2 poles - if (zerocoefs==0) { - omega=2*PI*freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - alpha=sn/(2*tmpq); - tmp=1+alpha; - c[0]=(1.0+cs)/2.0/tmp; - c[1]=-(1.0+cs)/tmp; - c[2]=(1.0+cs)/2.0/tmp; - d[1]=-2*cs/tmp*(-1); - d[2]=(1-alpha)/tmp*(-1); - } else { - c[0]=0.0; - c[1]=0.0; - c[2]=0.0; - d[1]=0.0; - d[2]=0.0; - }; - order=2; + case 3: //HPF 2 poles + if(zerocoefs == 0) { + omega = 2 * PI * freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + alpha = sn / (2 * tmpq); + tmp = 1 + alpha; + c[0] = (1.0 + cs) / 2.0 / tmp; + c[1] = -(1.0 + cs) / tmp; + c[2] = (1.0 + cs) / 2.0 / tmp; + d[1] = -2 * cs / tmp * (-1); + d[2] = (1 - alpha) / tmp * (-1); + } + else { + c[0] = 0.0; + c[1] = 0.0; + c[2] = 0.0; + d[1] = 0.0; + d[2] = 0.0; + } + order = 2; break; - case 4://BPF 2 poles - if (zerocoefs==0) { - omega=2*PI*freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - alpha=sn/(2*tmpq); - tmp=1+alpha; - c[0]=alpha/tmp*sqrt(tmpq+1); - c[1]=0; - c[2]=-alpha/tmp*sqrt(tmpq+1); - d[1]=-2*cs/tmp*(-1); - d[2]=(1-alpha)/tmp*(-1); - } else { - c[0]=0.0; - c[1]=0.0; - c[2]=0.0; - d[1]=0.0; - d[2]=0.0; - }; - order=2; + case 4: //BPF 2 poles + if(zerocoefs == 0) { + omega = 2 * PI * freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + alpha = sn / (2 * tmpq); + tmp = 1 + alpha; + c[0] = alpha / tmp *sqrt(tmpq + 1); + c[1] = 0; + c[2] = -alpha / tmp *sqrt(tmpq + 1); + d[1] = -2 * cs / tmp * (-1); + d[2] = (1 - alpha) / tmp * (-1); + } + else { + c[0] = 0.0; + c[1] = 0.0; + c[2] = 0.0; + d[1] = 0.0; + d[2] = 0.0; + } + order = 2; break; - case 5://NOTCH 2 poles - if (zerocoefs==0) { - omega=2*PI*freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - alpha=sn/(2*sqrt(tmpq)); - tmp=1+alpha; - c[0]=1/tmp; - c[1]=-2*cs/tmp; - c[2]=1/tmp; - d[1]=-2*cs/tmp*(-1); - d[2]=(1-alpha)/tmp*(-1); - } else { - c[0]=1.0; - c[1]=0.0; - c[2]=0.0; - d[1]=0.0; - d[2]=0.0; - }; - order=2; + case 5: //NOTCH 2 poles + if(zerocoefs == 0) { + omega = 2 * PI * freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + alpha = sn / (2 * sqrt(tmpq)); + tmp = 1 + alpha; + c[0] = 1 / tmp; + c[1] = -2 * cs / tmp; + c[2] = 1 / tmp; + d[1] = -2 * cs / tmp * (-1); + d[2] = (1 - alpha) / tmp * (-1); + } + else { + c[0] = 1.0; + c[1] = 0.0; + c[2] = 0.0; + d[1] = 0.0; + d[2] = 0.0; + } + order = 2; break; - case 6://PEAK (2 poles) - if (zerocoefs==0) { - omega=2*PI*freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - tmpq*=3.0; - alpha=sn/(2*tmpq); - tmp=1+alpha/tmpgain; - c[0]=(1.0+alpha*tmpgain)/tmp; - c[1]=(-2.0*cs)/tmp; - c[2]=(1.0-alpha*tmpgain)/tmp; - d[1]=-2*cs/tmp*(-1); - d[2]=(1-alpha/tmpgain)/tmp*(-1); - } else { - c[0]=1.0; - c[1]=0.0; - c[2]=0.0; - d[1]=0.0; - d[2]=0.0; - }; - order=2; + case 6: //PEAK (2 poles) + if(zerocoefs == 0) { + omega = 2 * PI * freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + tmpq *= 3.0; + alpha = sn / (2 * tmpq); + tmp = 1 + alpha / tmpgain; + c[0] = (1.0 + alpha * tmpgain) / tmp; + c[1] = (-2.0 * cs) / tmp; + c[2] = (1.0 - alpha * tmpgain) / tmp; + d[1] = -2 * cs / tmp * (-1); + d[2] = (1 - alpha / tmpgain) / tmp * (-1); + } + else { + c[0] = 1.0; + c[1] = 0.0; + c[2] = 0.0; + d[1] = 0.0; + d[2] = 0.0; + } + order = 2; break; - case 7://Low Shelf - 2 poles - if (zerocoefs==0) { - omega=2*PI*freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - tmpq=sqrt(tmpq); - alpha=sn/(2*tmpq); - beta=sqrt(tmpgain)/tmpq; - tmp=(tmpgain+1.0)+(tmpgain-1.0)*cs+beta*sn; - - c[0]=tmpgain*((tmpgain+1.0)-(tmpgain-1.0)*cs+beta*sn)/tmp; - c[1]=2.0*tmpgain*((tmpgain-1.0)-(tmpgain+1.0)*cs)/tmp; - c[2]=tmpgain*((tmpgain+1.0)-(tmpgain-1.0)*cs-beta*sn)/tmp; - d[1]=-2.0*((tmpgain-1.0)+(tmpgain+1.0)*cs)/tmp*(-1); - d[2]=((tmpgain+1.0)+(tmpgain-1.0)*cs-beta*sn)/tmp*(-1); - } else { - c[0]=tmpgain; - c[1]=0.0; - c[2]=0.0; - d[1]=0.0; - d[2]=0.0; - }; - order=2; + case 7: //Low Shelf - 2 poles + if(zerocoefs == 0) { + omega = 2 * PI * freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + tmpq = sqrt(tmpq); + alpha = sn / (2 * tmpq); + beta = sqrt(tmpgain) / tmpq; + tmp = (tmpgain + 1.0) + (tmpgain - 1.0) * cs + beta * sn; + + c[0] = tmpgain + * ((tmpgain + + 1.0) - (tmpgain - 1.0) * cs + beta * sn) / tmp; + c[1] = 2.0 * tmpgain + * ((tmpgain - 1.0) - (tmpgain + 1.0) * cs) / tmp; + c[2] = tmpgain + * ((tmpgain + + 1.0) - (tmpgain - 1.0) * cs - beta * sn) / tmp; + d[1] = -2.0 * ((tmpgain - 1.0) + (tmpgain + 1.0) * cs) / tmp * (-1); + d[2] = + ((tmpgain + + 1.0) + (tmpgain - 1.0) * cs - beta * sn) / tmp * (-1); + } + else { + c[0] = tmpgain; + c[1] = 0.0; + c[2] = 0.0; + d[1] = 0.0; + d[2] = 0.0; + } + order = 2; break; - case 8://High Shelf - 2 poles - if (zerocoefs==0) { - omega=2*PI*freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - tmpq=sqrt(tmpq); - alpha=sn/(2*tmpq); - beta=sqrt(tmpgain)/tmpq; - tmp=(tmpgain+1.0)-(tmpgain-1.0)*cs+beta*sn; - - c[0]=tmpgain*((tmpgain+1.0)+(tmpgain-1.0)*cs+beta*sn)/tmp; - c[1]=-2.0*tmpgain*((tmpgain-1.0)+(tmpgain+1.0)*cs)/tmp; - c[2]=tmpgain*((tmpgain+1.0)+(tmpgain-1.0)*cs-beta*sn)/tmp; - d[1]=2.0*((tmpgain-1.0)-(tmpgain+1.0)*cs)/tmp*(-1); - d[2]=((tmpgain+1.0)-(tmpgain-1.0)*cs-beta*sn)/tmp*(-1); - } else { - c[0]=1.0; - c[1]=0.0; - c[2]=0.0; - d[1]=0.0; - d[2]=0.0; - }; - order=2; + case 8: //High Shelf - 2 poles + if(zerocoefs == 0) { + omega = 2 * PI * freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + tmpq = sqrt(tmpq); + alpha = sn / (2 * tmpq); + beta = sqrt(tmpgain) / tmpq; + tmp = (tmpgain + 1.0) - (tmpgain - 1.0) * cs + beta * sn; + + c[0] = tmpgain + * ((tmpgain + + 1.0) + (tmpgain - 1.0) * cs + beta * sn) / tmp; + c[1] = -2.0 * tmpgain + * ((tmpgain - 1.0) + (tmpgain + 1.0) * cs) / tmp; + c[2] = tmpgain + * ((tmpgain + + 1.0) + (tmpgain - 1.0) * cs - beta * sn) / tmp; + d[1] = 2.0 * ((tmpgain - 1.0) - (tmpgain + 1.0) * cs) / tmp * (-1); + d[2] = + ((tmpgain + + 1.0) - (tmpgain - 1.0) * cs - beta * sn) / tmp * (-1); + } + else { + c[0] = 1.0; + c[1] = 0.0; + c[2] = 0.0; + d[1] = 0.0; + d[2] = 0.0; + } + order = 2; break; - default://wrong type - type=0; + default: //wrong type + type = 0; computefiltercoefs(); break; - }; -}; + } +} void AnalogFilter::setfreq(REALTYPE frequency) { - if (frequency<0.1) frequency=0.1; - REALTYPE rap=freq/frequency; - if (rap<1.0) rap=1.0/rap; - - oldabovenq=abovenq; - abovenq=frequency>(SAMPLE_RATE/2-500.0); - - int nyquistthresh=(abovenq^oldabovenq); - - - if ((rap>3.0)||(nyquistthresh!=0)) {//if the frequency is changed fast, it needs interpolation (now, filter and coeficients backup) - for (int i=0;i<3;i++) { - oldc[i]=c[i]; - oldd[i]=d[i]; - }; - for (int i=0;i<MAX_FILTER_STAGES+1;i++) { - oldx[i]=x[i]; - oldy[i]=y[i]; - }; - if (firsttime==0) needsinterpolation=1; - }; - freq=frequency; + if(frequency < 0.1) + frequency = 0.1; + REALTYPE rap = freq / frequency; + if(rap < 1.0) + rap = 1.0 / rap; + + oldabovenq = abovenq; + abovenq = frequency > (SAMPLE_RATE / 2 - 500.0); + + int nyquistthresh = (abovenq ^ oldabovenq); + + + if((rap > 3.0) || (nyquistthresh != 0)) { //if the frequency is changed fast, it needs interpolation (now, filter and coeficients backup) + for(int i = 0; i < 3; i++) { + oldc[i] = c[i]; + oldd[i] = d[i]; + } + for(int i = 0; i < MAX_FILTER_STAGES + 1; i++) { + oldx[i] = x[i]; + oldy[i] = y[i]; + } + if(firsttime == 0) + needsinterpolation = 1; + } + freq = frequency; computefiltercoefs(); - firsttime=0; - -}; + firsttime = 0; +} -void AnalogFilter::setfreq_and_q(REALTYPE frequency,REALTYPE q_) +void AnalogFilter::setfreq_and_q(REALTYPE frequency, REALTYPE q_) { - q=q_; + q = q_; setfreq(frequency); -}; +} void AnalogFilter::setq(REALTYPE q_) { - q=q_; + q = q_; computefiltercoefs(); -}; +} void AnalogFilter::settype(int type_) { - type=type_; + type = type_; computefiltercoefs(); -}; +} void AnalogFilter::setgain(REALTYPE dBgain) { - gain=dB2rap(dBgain); + gain = dB2rap(dBgain); computefiltercoefs(); -}; +} void AnalogFilter::setstages(int stages_) { - if (stages_>=MAX_FILTER_STAGES) stages_=MAX_FILTER_STAGES-1; - stages=stages_; + if(stages_ >= MAX_FILTER_STAGES) + stages_ = MAX_FILTER_STAGES - 1; + stages = stages_; cleanup(); computefiltercoefs(); -}; +} -void AnalogFilter::singlefilterout(REALTYPE *smp,fstage &x,fstage &y,REALTYPE *c,REALTYPE *d) +void AnalogFilter::singlefilterout(REALTYPE *smp, + fstage &x, + fstage &y, + REALTYPE *c, + REALTYPE *d) { - int i; + int i; REALTYPE y0; - if (order==1) {//First order filter - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - y0=smp[i]*c[0]+x.c1*c[1]+y.c1*d[1]; - y.c1=y0; - x.c1=smp[i]; + if(order == 1) { //First order filter + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + y0 = smp[i] * c[0] + x.c1 * c[1] + y.c1 * d[1]; + y.c1 = y0; + x.c1 = smp[i]; //output - smp[i]=y0; - }; - }; - if (order==2) {//Second order filter - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - y0=smp[i]*c[0]+x.c1*c[1]+x.c2*c[2]+y.c1*d[1]+y.c2*d[2]; - y.c2=y.c1; - y.c1=y0; - x.c2=x.c1; - x.c1=smp[i]; + smp[i] = y0; + } + } + if(order == 2) { //Second order filter + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + y0 = smp[i] * c[0] + x.c1 * c[1] + x.c2 * c[2] + y.c1 * d[1] + + y.c2 * d[2]; + y.c2 = y.c1; + y.c1 = y0; + x.c2 = x.c1; + x.c1 = smp[i]; //output - smp[i]=y0; - }; - }; -}; + smp[i] = y0; + } + } +} void AnalogFilter::filterout(REALTYPE *smp) { - REALTYPE *ismp=NULL;//used if it needs interpolation + REALTYPE *ismp = NULL; //used if it needs interpolation int i; - if (needsinterpolation!=0) { - ismp=new REALTYPE[SOUND_BUFFER_SIZE]; - for (i=0;i<SOUND_BUFFER_SIZE;i++) ismp[i]=smp[i]; - for (i=0;i<stages+1;i++) singlefilterout(ismp,oldx[i],oldy[i],oldc,oldd); - }; - - for (i=0;i<stages+1;i++) singlefilterout(smp,x[i],y[i],c,d); - - if (needsinterpolation!=0) { - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - REALTYPE x=i/(REALTYPE) SOUND_BUFFER_SIZE; - smp[i]=ismp[i]*(1.0-x)+smp[i]*x; - }; + if(needsinterpolation != 0) { + ismp = new REALTYPE[SOUND_BUFFER_SIZE]; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + ismp[i] = smp[i]; + for(i = 0; i < stages + 1; i++) + singlefilterout(ismp, oldx[i], oldy[i], oldc, oldd); + } + + for(i = 0; i < stages + 1; i++) + singlefilterout(smp, x[i], y[i], c, d); + + if(needsinterpolation != 0) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + REALTYPE x = i / (REALTYPE) SOUND_BUFFER_SIZE; + smp[i] = ismp[i] * (1.0 - x) + smp[i] * x; + } delete [] ismp; - needsinterpolation=0; - }; + needsinterpolation = 0; + } - for (i=0;i<SOUND_BUFFER_SIZE;i++) smp[i]*=outgain; -}; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + smp[i] *= outgain; +} REALTYPE AnalogFilter::H(REALTYPE freq) { - REALTYPE fr=freq/SAMPLE_RATE*PI*2.0; - REALTYPE x=c[0],y=0.0; - for (int n=1;n<3;n++) { - x+=cos(n*fr)*c[n]; - y-=sin(n*fr)*c[n]; - }; - REALTYPE h=x*x+y*y; - x=1.0; - y=0.0; - for (int n=1;n<3;n++) { - x-=cos(n*fr)*d[n]; - y+=sin(n*fr)*d[n]; - }; - h=h/(x*x+y*y); - return(pow(h,(stages+1.0)/2.0)); -}; + REALTYPE fr = freq / SAMPLE_RATE * PI * 2.0; + REALTYPE x = c[0], y = 0.0; + for(int n = 1; n < 3; n++) { + x += cos(n * fr) * c[n]; + y -= sin(n * fr) * c[n]; + } + REALTYPE h = x * x + y * y; + x = 1.0; + y = 0.0; + for(int n = 1; n < 3; n++) { + x -= cos(n * fr) * d[n]; + y += sin(n * fr) * d[n]; + } + h = h / (x * x + y * y); + return pow(h, (stages + 1.0) / 2.0); +} diff --git a/src/DSP/AnalogFilter.h b/src/DSP/AnalogFilter.h @@ -29,45 +29,52 @@ /**Implementation of Several analog filters (lowpass, highpass...)*/ class AnalogFilter:public Filter_ { -public: - AnalogFilter(unsigned char Ftype,REALTYPE Ffreq, REALTYPE Fq,unsigned char Fstages); - ~AnalogFilter(); - void filterout(REALTYPE *smp); - void setfreq(REALTYPE frequency); - void setfreq_and_q(REALTYPE frequency,REALTYPE q_); - void setq(REALTYPE q_); - - void settype(int type_); - void setgain(REALTYPE dBgain); - void setstages(int stages_); - void cleanup(); - - REALTYPE H(REALTYPE freq);//Obtains the response for a given frequency - -private: - struct fstage { - REALTYPE c1,c2; - } x[MAX_FILTER_STAGES+1],y[MAX_FILTER_STAGES+1], - oldx[MAX_FILTER_STAGES+1],oldy[MAX_FILTER_STAGES+1]; - - void singlefilterout(REALTYPE *smp,fstage &x,fstage &y,REALTYPE *c,REALTYPE *d); - void computefiltercoefs(); - int type;//The type of the filter (LPF1,HPF1,LPF2,HPF2...) - int stages;//how many times the filter is applied (0->1,1->2,etc.) - REALTYPE freq;//Frequency given in Hz - REALTYPE q; //Q factor (resonance or Q factor) - REALTYPE gain;//the gain of the filter (if are shelf/peak) filters - - int order;//the order of the filter (number of poles) - - REALTYPE c[3],d[3];//coefficients - - REALTYPE oldc[3],oldd[3];//old coefficients(used only if some filter paremeters changes very fast, and it needs interpolation) - - REALTYPE xd[3],yd[3];//used if the filter is applied more times - int needsinterpolation,firsttime;/**\todo see if bool works for these*/ - int abovenq;//this is 1 if the frequency is above the nyquist - int oldabovenq;//if the last time was above nyquist (used to see if it needs interpolation) + public: + AnalogFilter(unsigned char Ftype, + REALTYPE Ffreq, + REALTYPE Fq, + unsigned char Fstages); + ~AnalogFilter(); + void filterout(REALTYPE *smp); + void setfreq(REALTYPE frequency); + void setfreq_and_q(REALTYPE frequency, REALTYPE q_); + void setq(REALTYPE q_); + + void settype(int type_); + void setgain(REALTYPE dBgain); + void setstages(int stages_); + void cleanup(); + + REALTYPE H(REALTYPE freq); //Obtains the response for a given frequency + + private: + struct fstage { + REALTYPE c1, c2; + } x[MAX_FILTER_STAGES + 1], y[MAX_FILTER_STAGES + 1], + oldx[MAX_FILTER_STAGES + 1], oldy[MAX_FILTER_STAGES + 1]; + + void singlefilterout(REALTYPE *smp, + fstage &x, + fstage &y, + REALTYPE *c, + REALTYPE *d); + void computefiltercoefs(); + int type; //The type of the filter (LPF1,HPF1,LPF2,HPF2...) + int stages; //how many times the filter is applied (0->1,1->2,etc.) + REALTYPE freq; //Frequency given in Hz + REALTYPE q; //Q factor (resonance or Q factor) + REALTYPE gain; //the gain of the filter (if are shelf/peak) filters + + int order; //the order of the filter (number of poles) + + REALTYPE c[3], d[3]; //coefficients + + REALTYPE oldc[3], oldd[3]; //old coefficients(used only if some filter paremeters changes very fast, and it needs interpolation) + + REALTYPE xd[3], yd[3]; //used if the filter is applied more times + int needsinterpolation, firsttime; /**\todo see if bool works for these*/ + int abovenq; //this is 1 if the frequency is above the nyquist + int oldabovenq; //if the last time was above nyquist (used to see if it needs interpolation) }; diff --git a/src/DSP/FFTwrapper.cpp b/src/DSP/FFTwrapper.cpp @@ -25,17 +25,29 @@ FFTwrapper::FFTwrapper(int fftsize_) { - fftsize=fftsize_; - tmpfftdata1=new fftw_real[fftsize]; - tmpfftdata2=new fftw_real[fftsize]; + fftsize = fftsize_; + tmpfftdata1 = new fftw_real[fftsize]; + tmpfftdata2 = new fftw_real[fftsize]; #ifdef FFTW_VERSION_2 - planfftw=rfftw_create_plan(fftsize,FFTW_REAL_TO_COMPLEX,FFTW_ESTIMATE|FFTW_IN_PLACE); - planfftw_inv=rfftw_create_plan(fftsize,FFTW_COMPLEX_TO_REAL,FFTW_ESTIMATE|FFTW_IN_PLACE); + planfftw = rfftw_create_plan(fftsize, + FFTW_REAL_TO_COMPLEX, + FFTW_ESTIMATE | FFTW_IN_PLACE); + planfftw_inv = rfftw_create_plan(fftsize, + FFTW_COMPLEX_TO_REAL, + FFTW_ESTIMATE | FFTW_IN_PLACE); #else - planfftw=fftw_plan_r2r_1d(fftsize,tmpfftdata1,tmpfftdata1,FFTW_R2HC,FFTW_ESTIMATE); - planfftw_inv=fftw_plan_r2r_1d(fftsize,tmpfftdata2,tmpfftdata2,FFTW_HC2R,FFTW_ESTIMATE); + planfftw = fftw_plan_r2r_1d(fftsize, + tmpfftdata1, + tmpfftdata1, + FFTW_R2HC, + FFTW_ESTIMATE); + planfftw_inv = fftw_plan_r2r_1d(fftsize, + tmpfftdata2, + tmpfftdata2, + FFTW_HC2R, + FFTW_ESTIMATE); #endif -}; +} FFTwrapper::~FFTwrapper() { @@ -49,60 +61,67 @@ FFTwrapper::~FFTwrapper() delete [] tmpfftdata1; delete [] tmpfftdata2; -}; +} /* * do the Fast Fourier Transform */ -void FFTwrapper::smps2freqs(REALTYPE *smps,FFTFREQS freqs) +void FFTwrapper::smps2freqs(REALTYPE *smps, FFTFREQS freqs) { #ifdef FFTW_VERSION_2 - for (int i=0;i<fftsize;i++) tmpfftdata1[i]=smps[i]; - rfftw_one(planfftw,tmpfftdata1,tmpfftdata2); - for (int i=0;i<fftsize/2;i++) { - freqs.c[i]=tmpfftdata2[i]; - if (i!=0) freqs.s[i]=tmpfftdata2[fftsize-i]; - }; + for(int i = 0; i < fftsize; i++) + tmpfftdata1[i] = smps[i]; + rfftw_one(planfftw, tmpfftdata1, tmpfftdata2); + for(int i = 0; i < fftsize / 2; i++) { + freqs.c[i] = tmpfftdata2[i]; + if(i != 0) + freqs.s[i] = tmpfftdata2[fftsize - i]; + } #else - for (int i=0;i<fftsize;i++) tmpfftdata1[i]=smps[i]; + for(int i = 0; i < fftsize; i++) + tmpfftdata1[i] = smps[i]; fftw_execute(planfftw); - for (int i=0;i<fftsize/2;i++) { - freqs.c[i]=tmpfftdata1[i]; - if (i!=0) freqs.s[i]=tmpfftdata1[fftsize-i]; - }; + for(int i = 0; i < fftsize / 2; i++) { + freqs.c[i] = tmpfftdata1[i]; + if(i != 0) + freqs.s[i] = tmpfftdata1[fftsize - i]; + } #endif - tmpfftdata2[fftsize/2]=0.0; -}; + tmpfftdata2[fftsize / 2] = 0.0; +} /* * do the Inverse Fast Fourier Transform */ -void FFTwrapper::freqs2smps(FFTFREQS freqs,REALTYPE *smps) +void FFTwrapper::freqs2smps(FFTFREQS freqs, REALTYPE *smps) { - tmpfftdata2[fftsize/2]=0.0; + tmpfftdata2[fftsize / 2] = 0.0; #ifdef FFTW_VERSION_2 - for (int i=0;i<fftsize/2;i++) { - tmpfftdata1[i]=freqs.c[i]; - if (i!=0) tmpfftdata1[fftsize-i]=freqs.s[i]; - }; - rfftw_one(planfftw_inv,tmpfftdata1,tmpfftdata2); - for (int i=0;i<fftsize;i++) smps[i]=tmpfftdata2[i]; + for(int i = 0; i < fftsize / 2; i++) { + tmpfftdata1[i] = freqs.c[i]; + if(i != 0) + tmpfftdata1[fftsize - i] = freqs.s[i]; + } + rfftw_one(planfftw_inv, tmpfftdata1, tmpfftdata2); + for(int i = 0; i < fftsize; i++) + smps[i] = tmpfftdata2[i]; #else - for (int i=0;i<fftsize/2;i++) { - tmpfftdata2[i]=freqs.c[i]; - if (i!=0) tmpfftdata2[fftsize-i]=freqs.s[i]; - }; + for(int i = 0; i < fftsize / 2; i++) { + tmpfftdata2[i] = freqs.c[i]; + if(i != 0) + tmpfftdata2[fftsize - i] = freqs.s[i]; + } fftw_execute(planfftw_inv); - for (int i=0;i<fftsize;i++) smps[i]=tmpfftdata2[i]; + for(int i = 0; i < fftsize; i++) + smps[i] = tmpfftdata2[i]; #endif - -}; +} void newFFTFREQS(FFTFREQS *f, int size) { f->c = new REALTYPE[size]; f->s = new REALTYPE[size]; - for (int i=0; i<size; i++) { + for(int i = 0; i < size; i++) { f->c[i] = 0.0; f->s[i] = 0.0; } @@ -114,3 +133,4 @@ void deleteFFTFREQS(FFTFREQS *f) delete[] f->s; f->c = f->s = NULL; } + diff --git a/src/DSP/FFTwrapper.h b/src/DSP/FFTwrapper.h @@ -47,21 +47,21 @@ Hope all goes right." */ /**A wrapper for the FFTW library (Fast Fourier Transforms)*/ class FFTwrapper { -public: - /**Constructor - * @param fftsize The size of samples to be fed to fftw*/ - FFTwrapper(int fftsize_); - /**Destructor*/ - ~FFTwrapper(); - /**Convert Samples to Frequencies using Fourier Transform - * @param smps Pointer to Samples to be converted; has length fftsize_ - * @param freqs Structure FFTFREQS which stores the frequencies*/ - void smps2freqs(REALTYPE *smps,FFTFREQS freqs); - void freqs2smps(FFTFREQS freqs,REALTYPE *smps); -private: - int fftsize; - fftw_real *tmpfftdata1,*tmpfftdata2; - rfftw_plan planfftw,planfftw_inv; + public: + /**Constructor + * @param fftsize The size of samples to be fed to fftw*/ + FFTwrapper(int fftsize_); + /**Destructor*/ + ~FFTwrapper(); + /**Convert Samples to Frequencies using Fourier Transform + * @param smps Pointer to Samples to be converted; has length fftsize_ + * @param freqs Structure FFTFREQS which stores the frequencies*/ + void smps2freqs(REALTYPE *smps, FFTFREQS freqs); + void freqs2smps(FFTFREQS freqs, REALTYPE *smps); + private: + int fftsize; + fftw_real *tmpfftdata1, *tmpfftdata2; + rfftw_plan planfftw, planfftw_inv; }; void newFFTFREQS(FFTFREQS *f, int size); diff --git a/src/DSP/Filter.cpp b/src/DSP/Filter.cpp @@ -27,56 +27,61 @@ Filter::Filter(FilterParams *pars) { - unsigned char Ftype=pars->Ptype; - unsigned char Fstages=pars->Pstages; + unsigned char Ftype = pars->Ptype; + unsigned char Fstages = pars->Pstages; - category=pars->Pcategory; + category = pars->Pcategory; - switch (category) { + switch(category) { case 1: - filter=new FormantFilter(pars); + filter = new FormantFilter(pars); break; case 2: - filter=new SVFilter(Ftype,1000.0,pars->getq(),Fstages); - filter->outgain=dB2rap(pars->getgain()); - if (filter->outgain>1.0) filter->outgain=sqrt(filter->outgain); + filter = new SVFilter(Ftype, 1000.0, pars->getq(), Fstages); + filter->outgain = dB2rap(pars->getgain()); + if(filter->outgain > 1.0) + filter->outgain = sqrt(filter->outgain); break; default: - filter=new AnalogFilter(Ftype,1000.0,pars->getq(),Fstages); - if ((Ftype>=6)&&(Ftype<=8)) filter->setgain(pars->getgain()); - else filter->outgain=dB2rap(pars->getgain()); + filter = new AnalogFilter(Ftype, 1000.0, pars->getq(), Fstages); + if((Ftype >= 6) && (Ftype <= 8)) + filter->setgain(pars->getgain()); + else + filter->outgain = dB2rap(pars->getgain()); break; - }; -}; + } +} Filter::~Filter() { delete (filter); -}; +} void Filter::filterout(REALTYPE *smp) { filter->filterout(smp); -}; +} void Filter::setfreq(REALTYPE frequency) { filter->setfreq(frequency); -}; +} -void Filter::setfreq_and_q(REALTYPE frequency,REALTYPE q_) +void Filter::setfreq_and_q(REALTYPE frequency, REALTYPE q_) { - filter->setfreq_and_q(frequency,q_); -}; + filter->setfreq_and_q(frequency, q_); +} void Filter::setq(REALTYPE q_) { filter->setq(q_); -}; +} REALTYPE Filter::getrealfreq(REALTYPE freqpitch) { - if ((category==0)||(category==2)) return(pow(2.0,freqpitch+9.96578428));//log2(1000)=9.95748 - else return(freqpitch); -}; + if((category == 0) || (category == 2)) + return pow(2.0, freqpitch + 9.96578428); //log2(1000)=9.95748 + else + return freqpitch; +} diff --git a/src/DSP/Filter.h b/src/DSP/Filter.h @@ -33,18 +33,18 @@ class Filter { -public: - Filter(FilterParams *pars); - ~Filter(); - void filterout(REALTYPE *smp); - void setfreq(REALTYPE frequency); - void setfreq_and_q(REALTYPE frequency,REALTYPE q_); - void setq(REALTYPE q_); - - REALTYPE getrealfreq(REALTYPE freqpitch); -private: - Filter_ *filter; - unsigned char category; + public: + Filter(FilterParams *pars); + ~Filter(); + void filterout(REALTYPE *smp); + void setfreq(REALTYPE frequency); + void setfreq_and_q(REALTYPE frequency, REALTYPE q_); + void setq(REALTYPE q_); + + REALTYPE getrealfreq(REALTYPE freqpitch); + private: + Filter_ *filter; + unsigned char category; }; diff --git a/src/DSP/Filter_.h b/src/DSP/Filter_.h @@ -27,15 +27,15 @@ class Filter_ { -public: - virtual ~Filter_() {}; - virtual void filterout(REALTYPE *smp)=0; - virtual void setfreq(REALTYPE frequency)=0; - virtual void setfreq_and_q(REALTYPE frequency,REALTYPE q_)=0; - virtual void setq(REALTYPE q_)=0; - virtual void setgain(REALTYPE dBgain) {}; - REALTYPE outgain; -private: + public: + virtual ~Filter_() {} + virtual void filterout(REALTYPE *smp) = 0; + virtual void setfreq(REALTYPE frequency) = 0; + virtual void setfreq_and_q(REALTYPE frequency, REALTYPE q_) = 0; + virtual void setq(REALTYPE q_) = 0; + virtual void setgain(REALTYPE dBgain) {} + REALTYPE outgain; + private: }; diff --git a/src/DSP/FormantFilter.cpp b/src/DSP/FormantFilter.cpp @@ -26,151 +26,202 @@ FormantFilter::FormantFilter(FilterParams *pars) { - numformants=pars->Pnumformants; - for (int i=0;i<numformants;i++) formant[i]=new AnalogFilter(4/*BPF*/,1000.0,10.0,pars->Pstages); + numformants = pars->Pnumformants; + for(int i = 0; i < numformants; i++) + formant[i] = new AnalogFilter(4 /*BPF*/, 1000.0, 10.0, pars->Pstages); cleanup(); - inbuffer=new REALTYPE [SOUND_BUFFER_SIZE]; - tmpbuf=new REALTYPE [SOUND_BUFFER_SIZE]; - - for (int j=0;j<FF_MAX_VOWELS;j++) - for (int i=0;i<numformants;i++) { - formantpar[j][i].freq=pars->getformantfreq(pars->Pvowels[j].formants[i].freq); - formantpar[j][i].amp=pars->getformantamp(pars->Pvowels[j].formants[i].amp); - formantpar[j][i].q=pars->getformantq(pars->Pvowels[j].formants[i].q); - }; - for (int i=0;i<FF_MAX_FORMANTS;i++) oldformantamp[i]=1.0; - for (int i=0;i<numformants;i++) { - currentformants[i].freq=1000.0; - currentformants[i].amp=1.0; - currentformants[i].q=2.0; - }; - - formantslowness=pow(1.0-(pars->Pformantslowness/128.0),3.0); - - sequencesize=pars->Psequencesize; - if (sequencesize==0) sequencesize=1; - for (int k=0;k<sequencesize;k++) sequence[k].nvowel=pars->Psequence[k].nvowel; - - vowelclearness=pow(10.0,(pars->Pvowelclearness-32.0)/48.0); - - sequencestretch=pow(0.1,(pars->Psequencestretch-32.0)/48.0); - if (pars->Psequencereversed) sequencestretch*= -1.0; - - outgain=dB2rap(pars->getgain()); - - oldinput=-1.0; - Qfactor=1.0; - oldQfactor=Qfactor; - firsttime=1; -}; + inbuffer = new REALTYPE [SOUND_BUFFER_SIZE]; + tmpbuf = new REALTYPE [SOUND_BUFFER_SIZE]; + + for(int j = 0; j < FF_MAX_VOWELS; j++) + for(int i = 0; i < numformants; i++) { + formantpar[j][i].freq = pars->getformantfreq( + pars->Pvowels[j].formants[i].freq); + formantpar[j][i].amp = pars->getformantamp( + pars->Pvowels[j].formants[i].amp); + formantpar[j][i].q = pars->getformantq( + pars->Pvowels[j].formants[i].q); + } + ; + for(int i = 0; i < FF_MAX_FORMANTS; i++) + oldformantamp[i] = 1.0; + for(int i = 0; i < numformants; i++) { + currentformants[i].freq = 1000.0; + currentformants[i].amp = 1.0; + currentformants[i].q = 2.0; + } + + formantslowness = pow(1.0 - (pars->Pformantslowness / 128.0), 3.0); + + sequencesize = pars->Psequencesize; + if(sequencesize == 0) + sequencesize = 1; + for(int k = 0; k < sequencesize; k++) + sequence[k].nvowel = pars->Psequence[k].nvowel; + + vowelclearness = pow(10.0, (pars->Pvowelclearness - 32.0) / 48.0); + + sequencestretch = pow(0.1, (pars->Psequencestretch - 32.0) / 48.0); + if(pars->Psequencereversed) + sequencestretch *= -1.0; + + outgain = dB2rap(pars->getgain()); + + oldinput = -1.0; + Qfactor = 1.0; + oldQfactor = Qfactor; + firsttime = 1; +} FormantFilter::~FormantFilter() { - for (int i=0;i<numformants;i++) delete(formant[i]); + for(int i = 0; i < numformants; i++) + delete (formant[i]); delete[] inbuffer; delete[] tmpbuf; -}; +} void FormantFilter::cleanup() { - for (int i=0;i<numformants;i++) formant[i]->cleanup(); -}; + for(int i = 0; i < numformants; i++) + formant[i]->cleanup(); +} void FormantFilter::setpos(REALTYPE input) { - int p1,p2; + int p1, p2; - if (firsttime!=0) slowinput=input; - else slowinput=slowinput*(1.0-formantslowness)+input*formantslowness; + if(firsttime != 0) + slowinput = input; + else + slowinput = slowinput + * (1.0 - formantslowness) + input * formantslowness; - if ((fabs(oldinput-input)<0.001)&&(fabs(slowinput-input)<0.001)&& - (fabs(Qfactor-oldQfactor)<0.001)) { + if((fabs(oldinput - input) < 0.001) && (fabs(slowinput - input) < 0.001) + && (fabs(Qfactor - oldQfactor) < 0.001)) { // oldinput=input; daca setez asta, o sa faca probleme la schimbari foarte lente - firsttime=0; + firsttime = 0; return; - } else oldinput=input; - - - REALTYPE pos=fmod(input*sequencestretch,1.0); - if (pos<0.0) pos+=1.0; - - F2I(pos*sequencesize,p2); - p1=p2-1; - if (p1<0) p1+=sequencesize; - - pos=fmod(pos*sequencesize,1.0); - if (pos<0.0) pos=0.0; - else if (pos>1.0) pos=1.0; - pos=(atan((pos*2.0-1.0)*vowelclearness)/atan(vowelclearness)+1.0)*0.5; - - p1=sequence[p1].nvowel; - p2=sequence[p2].nvowel; - - if (firsttime!=0) { - for (int i=0;i<numformants;i++) { - currentformants[i].freq=formantpar[p1][i].freq*(1.0-pos)+formantpar[p2][i].freq*pos; - currentformants[i].amp=formantpar[p1][i].amp*(1.0-pos)+formantpar[p2][i].amp*pos; - currentformants[i].q=formantpar[p1][i].q*(1.0-pos)+formantpar[p2][i].q*pos; - formant[i]->setfreq_and_q(currentformants[i].freq,currentformants[i].q*Qfactor); - oldformantamp[i]=currentformants[i].amp; - }; - firsttime=0; - } else { - for (int i=0;i<numformants;i++) { - currentformants[i].freq=currentformants[i].freq*(1.0-formantslowness) - +(formantpar[p1][i].freq*(1.0-pos)+formantpar[p2][i].freq*pos)*formantslowness; - - currentformants[i].amp=currentformants[i].amp*(1.0-formantslowness) - +(formantpar[p1][i].amp*(1.0-pos)+formantpar[p2][i].amp*pos)*formantslowness; - - currentformants[i].q=currentformants[i].q*(1.0-formantslowness) - +(formantpar[p1][i].q*(1.0-pos)+formantpar[p2][i].q*pos)*formantslowness; - - formant[i]->setfreq_and_q(currentformants[i].freq,currentformants[i].q*Qfactor); - }; - }; - - oldQfactor=Qfactor; -}; + } + else + oldinput = input; + + + REALTYPE pos = fmod(input * sequencestretch, 1.0); + if(pos < 0.0) + pos += 1.0; + + F2I(pos * sequencesize, p2); + p1 = p2 - 1; + if(p1 < 0) + p1 += sequencesize; + + pos = fmod(pos * sequencesize, 1.0); + if(pos < 0.0) + pos = 0.0; + else + if(pos > 1.0) + pos = 1.0; + pos = + (atan((pos * 2.0 + - 1.0) * vowelclearness) / atan(vowelclearness) + 1.0) * 0.5; + + p1 = sequence[p1].nvowel; + p2 = sequence[p2].nvowel; + + if(firsttime != 0) { + for(int i = 0; i < numformants; i++) { + currentformants[i].freq = formantpar[p1][i].freq + * (1.0 + - pos) + formantpar[p2][i].freq * pos; + currentformants[i].amp = formantpar[p1][i].amp + * (1.0 + - pos) + formantpar[p2][i].amp * pos; + currentformants[i].q = formantpar[p1][i].q + * (1.0 - pos) + formantpar[p2][i].q * pos; + formant[i]->setfreq_and_q(currentformants[i].freq, + currentformants[i].q * Qfactor); + oldformantamp[i] = currentformants[i].amp; + } + firsttime = 0; + } + else { + for(int i = 0; i < numformants; i++) { + currentformants[i].freq = currentformants[i].freq + * (1.0 - formantslowness) + + (formantpar[p1][i].freq + * (1.0 + - pos) + formantpar[p2][i].freq + * pos) * formantslowness; + + currentformants[i].amp = currentformants[i].amp + * (1.0 - formantslowness) + + (formantpar[p1][i].amp + * (1.0 + - pos) + formantpar[p2][i].amp + * pos) * formantslowness; + + currentformants[i].q = currentformants[i].q + * (1.0 - formantslowness) + + (formantpar[p1][i].q + * (1.0 + - pos) + formantpar[p2][i].q + * pos) * formantslowness; + + formant[i]->setfreq_and_q(currentformants[i].freq, + currentformants[i].q * Qfactor); + } + } + + oldQfactor = Qfactor; +} void FormantFilter::setfreq(REALTYPE frequency) { setpos(frequency); -}; +} void FormantFilter::setq(REALTYPE q_) { - Qfactor=q_; - for (int i=0;i<numformants;i++) formant[i]->setq(Qfactor*currentformants[i].q); -}; + Qfactor = q_; + for(int i = 0; i < numformants; i++) + formant[i]->setq(Qfactor * currentformants[i].q); +} -void FormantFilter::setfreq_and_q(REALTYPE frequency,REALTYPE q_) +void FormantFilter::setfreq_and_q(REALTYPE frequency, REALTYPE q_) { - Qfactor=q_; + Qfactor = q_; setpos(frequency); -}; +} void FormantFilter::filterout(REALTYPE *smp) { - int i,j; - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - inbuffer[i]=smp[i]; - smp[i]=0.0; - }; - - for (j=0;j<numformants;j++) { - for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpbuf[i]=inbuffer[i]*outgain; + int i, j; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + inbuffer[i] = smp[i]; + smp[i] = 0.0; + } + + for(j = 0; j < numformants; j++) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpbuf[i] = inbuffer[i] * outgain; formant[j]->filterout(tmpbuf); - if (ABOVE_AMPLITUDE_THRESHOLD(oldformantamp[j],currentformants[j].amp)) - for (i=0;i<SOUND_BUFFER_SIZE;i++) smp[i]+=tmpbuf[i]* - INTERPOLATE_AMPLITUDE(oldformantamp[j],currentformants[j].amp,i,SOUND_BUFFER_SIZE); - else for (i=0;i<SOUND_BUFFER_SIZE;i++) smp[i]+=tmpbuf[i]*currentformants[j].amp; - oldformantamp[j]=currentformants[j].amp; - }; -}; + if(ABOVE_AMPLITUDE_THRESHOLD(oldformantamp[j], currentformants[j].amp)) + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + smp[i] += tmpbuf[i] + * INTERPOLATE_AMPLITUDE(oldformantamp[j], + currentformants[j].amp, + i, + SOUND_BUFFER_SIZE); + else + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + smp[i] += tmpbuf[i] * currentformants[j].amp; + oldformantamp[j] = currentformants[j].amp; + } +} diff --git a/src/DSP/FormantFilter.h b/src/DSP/FormantFilter.h @@ -31,36 +31,36 @@ class FormantFilter:public Filter_ { -public: - FormantFilter(FilterParams *pars); - ~FormantFilter(); - void filterout(REALTYPE *smp); - void setfreq(REALTYPE frequency); - void setfreq_and_q(REALTYPE frequency,REALTYPE q_); - void setq(REALTYPE q_); - - void cleanup(); -private: - AnalogFilter *formant[FF_MAX_FORMANTS]; - REALTYPE *inbuffer,*tmpbuf; - - struct { - REALTYPE freq,amp,q;//frequency,amplitude,Q - } formantpar[FF_MAX_VOWELS][FF_MAX_FORMANTS],currentformants[FF_MAX_FORMANTS]; - - struct { - unsigned char nvowel; - } sequence [FF_MAX_SEQUENCE]; - - REALTYPE oldformantamp[FF_MAX_FORMANTS]; - - int sequencesize,numformants,firsttime; - REALTYPE oldinput,slowinput; - REALTYPE Qfactor,formantslowness,oldQfactor; - REALTYPE vowelclearness,sequencestretch; - - void setpos(REALTYPE input); - + public: + FormantFilter(FilterParams *pars); + ~FormantFilter(); + void filterout(REALTYPE *smp); + void setfreq(REALTYPE frequency); + void setfreq_and_q(REALTYPE frequency, REALTYPE q_); + void setq(REALTYPE q_); + + void cleanup(); + private: + AnalogFilter *formant[FF_MAX_FORMANTS]; + REALTYPE *inbuffer, *tmpbuf; + + struct { + REALTYPE freq, amp, q; //frequency,amplitude,Q + } formantpar[FF_MAX_VOWELS][FF_MAX_FORMANTS], + currentformants[FF_MAX_FORMANTS]; + + struct { + unsigned char nvowel; + } sequence [FF_MAX_SEQUENCE]; + + REALTYPE oldformantamp[FF_MAX_FORMANTS]; + + int sequencesize, numformants, firsttime; + REALTYPE oldinput, slowinput; + REALTYPE Qfactor, formantslowness, oldQfactor; + REALTYPE vowelclearness, sequencestretch; + + void setpos(REALTYPE input); }; diff --git a/src/DSP/SVFilter.cpp b/src/DSP/SVFilter.cpp @@ -24,153 +24,163 @@ #include <stdio.h> #include "SVFilter.h" -SVFilter::SVFilter(unsigned char Ftype,REALTYPE Ffreq, REALTYPE Fq,unsigned char Fstages) +SVFilter::SVFilter(unsigned char Ftype, + REALTYPE Ffreq, + REALTYPE Fq, + unsigned char Fstages) { - stages=Fstages; - type=Ftype; - freq=Ffreq; - q=Fq; - gain=1.0; - outgain=1.0; - needsinterpolation=0; - firsttime=1; - if (stages>=MAX_FILTER_STAGES) stages=MAX_FILTER_STAGES; + stages = Fstages; + type = Ftype; + freq = Ffreq; + q = Fq; + gain = 1.0; + outgain = 1.0; + needsinterpolation = 0; + firsttime = 1; + if(stages >= MAX_FILTER_STAGES) + stages = MAX_FILTER_STAGES; cleanup(); - setfreq_and_q(Ffreq,Fq); -}; + setfreq_and_q(Ffreq, Fq); +} SVFilter::~SVFilter() -{ -}; +{} void SVFilter::cleanup() { - for (int i=0;i<MAX_FILTER_STAGES+1;i++) { - st[i].low=0.0; - st[i].high=0.0; - st[i].band=0.0; - st[i].notch=0.0; - }; - oldabovenq=0; - abovenq=0; -}; + for(int i = 0; i < MAX_FILTER_STAGES + 1; i++) { + st[i].low = 0.0; + st[i].high = 0.0; + st[i].band = 0.0; + st[i].notch = 0.0; + } + oldabovenq = 0; + abovenq = 0; +} void SVFilter::computefiltercoefs() { - par.f=freq / SAMPLE_RATE*4.0; - if (par.f>0.99999) par.f=0.99999; - par.q=1.0-atan(sqrt(q))*2.0/PI; - par.q=pow(par.q,1.0/(stages+1)); - par.q_sqrt=sqrt(par.q); -}; + par.f = freq / SAMPLE_RATE * 4.0; + if(par.f > 0.99999) + par.f = 0.99999; + par.q = 1.0 - atan(sqrt(q)) * 2.0 / PI; + par.q = pow(par.q, 1.0 / (stages + 1)); + par.q_sqrt = sqrt(par.q); +} void SVFilter::setfreq(REALTYPE frequency) { - if (frequency<0.1) frequency=0.1; - REALTYPE rap=freq/frequency; - if (rap<1.0) rap=1.0/rap; + if(frequency < 0.1) + frequency = 0.1; + REALTYPE rap = freq / frequency; + if(rap < 1.0) + rap = 1.0 / rap; - oldabovenq=abovenq; - abovenq=frequency>(SAMPLE_RATE/2-500.0); + oldabovenq = abovenq; + abovenq = frequency > (SAMPLE_RATE / 2 - 500.0); - int nyquistthresh=(abovenq^oldabovenq); + int nyquistthresh = (abovenq ^ oldabovenq); - if ((rap>3.0)||(nyquistthresh!=0)) {//if the frequency is changed fast, it needs interpolation (now, filter and coeficients backup) - if (firsttime==0) needsinterpolation=1; - ipar=par; - }; - freq=frequency; + if((rap > 3.0) || (nyquistthresh != 0)) { //if the frequency is changed fast, it needs interpolation (now, filter and coeficients backup) + if(firsttime == 0) + needsinterpolation = 1; + ipar = par; + } + freq = frequency; computefiltercoefs(); - firsttime=0; - -}; + firsttime = 0; +} -void SVFilter::setfreq_and_q(REALTYPE frequency,REALTYPE q_) +void SVFilter::setfreq_and_q(REALTYPE frequency, REALTYPE q_) { - q=q_; + q = q_; setfreq(frequency); -}; +} void SVFilter::setq(REALTYPE q_) { - q=q_; + q = q_; computefiltercoefs(); -}; +} void SVFilter::settype(int type_) { - type=type_; + type = type_; computefiltercoefs(); -}; +} void SVFilter::setgain(REALTYPE dBgain) { - gain=dB2rap(dBgain); + gain = dB2rap(dBgain); computefiltercoefs(); -}; +} void SVFilter::setstages(int stages_) { - if (stages_>=MAX_FILTER_STAGES) stages_=MAX_FILTER_STAGES-1; - stages=stages_; + if(stages_ >= MAX_FILTER_STAGES) + stages_ = MAX_FILTER_STAGES - 1; + stages = stages_; cleanup(); computefiltercoefs(); -}; +} -void SVFilter::singlefilterout(REALTYPE *smp,fstage &x,parameters &par) +void SVFilter::singlefilterout(REALTYPE *smp, fstage &x, parameters &par) { int i; - REALTYPE *out=NULL; - switch (type) { + REALTYPE *out = NULL; + switch(type) { case 0: - out=&x.low; + out = &x.low; break; case 1: - out=&x.high; + out = &x.high; break; case 2: - out=&x.band; + out = &x.band; break; case 3: - out=&x.notch; + out = &x.notch; break; - }; + } - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - x.low = x.low + par.f * x.band; - x.high = par.q_sqrt * smp[i] - x.low - par.q*x.band; - x.band = par.f * x.high + x.band; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + x.low = x.low + par.f * x.band; + x.high = par.q_sqrt * smp[i] - x.low - par.q * x.band; + x.band = par.f * x.high + x.band; x.notch = x.high + x.low; - smp[i]= *out; - }; -}; + smp[i] = *out; + } +} void SVFilter::filterout(REALTYPE *smp) { int i; - REALTYPE *ismp=NULL; - - if (needsinterpolation!=0) { - ismp=new REALTYPE[SOUND_BUFFER_SIZE]; - for (i=0;i<SOUND_BUFFER_SIZE;i++) ismp[i]=smp[i]; - for (i=0;i<stages+1;i++) singlefilterout(ismp,st[i],ipar); - }; - - for (i=0;i<stages+1;i++) singlefilterout(smp,st[i],par); - - if (needsinterpolation!=0) { - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - REALTYPE x=i/(REALTYPE) SOUND_BUFFER_SIZE; - smp[i]=ismp[i]*(1.0-x)+smp[i]*x; - }; + REALTYPE *ismp = NULL; + + if(needsinterpolation != 0) { + ismp = new REALTYPE[SOUND_BUFFER_SIZE]; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + ismp[i] = smp[i]; + for(i = 0; i < stages + 1; i++) + singlefilterout(ismp, st[i], ipar); + } + + for(i = 0; i < stages + 1; i++) + singlefilterout(smp, st[i], par); + + if(needsinterpolation != 0) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + REALTYPE x = i / (REALTYPE) SOUND_BUFFER_SIZE; + smp[i] = ismp[i] * (1.0 - x) + smp[i] * x; + } delete [] ismp; - needsinterpolation=0; - }; - - for (i=0;i<SOUND_BUFFER_SIZE;i++) smp[i]*=outgain; + needsinterpolation = 0; + } -}; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + smp[i] *= outgain; +} diff --git a/src/DSP/SVFilter.h b/src/DSP/SVFilter.h @@ -27,40 +27,43 @@ #include "Filter_.h" class SVFilter:public Filter_ { -public: - SVFilter(unsigned char Ftype,REALTYPE Ffreq, REALTYPE Fq,unsigned char Fstages); - ~SVFilter(); - void filterout(REALTYPE *smp); - void setfreq(REALTYPE frequency); - void setfreq_and_q(REALTYPE frequency,REALTYPE q_); - void setq(REALTYPE q_); - - void settype(int type_); - void setgain(REALTYPE dBgain); - void setstages(int stages_); - void cleanup(); - -private: - struct fstage { - REALTYPE low,high,band,notch; - } st[MAX_FILTER_STAGES+1]; - - struct parameters { - REALTYPE f,q,q_sqrt; - }par,ipar; - - - void singlefilterout(REALTYPE *smp,fstage &x,parameters &par); - void computefiltercoefs(); - int type;//The type of the filter (LPF1,HPF1,LPF2,HPF2...) - int stages;//how many times the filter is applied (0->1,1->2,etc.) - REALTYPE freq;//Frequency given in Hz - REALTYPE q; //Q factor (resonance or Q factor) - REALTYPE gain;//the gain of the filter (if are shelf/peak) filters - - int abovenq;//this is 1 if the frequency is above the nyquist - int oldabovenq; - int needsinterpolation,firsttime; + public: + SVFilter(unsigned char Ftype, + REALTYPE Ffreq, + REALTYPE Fq, + unsigned char Fstages); + ~SVFilter(); + void filterout(REALTYPE *smp); + void setfreq(REALTYPE frequency); + void setfreq_and_q(REALTYPE frequency, REALTYPE q_); + void setq(REALTYPE q_); + + void settype(int type_); + void setgain(REALTYPE dBgain); + void setstages(int stages_); + void cleanup(); + + private: + struct fstage { + REALTYPE low, high, band, notch; + } st[MAX_FILTER_STAGES + 1]; + + struct parameters { + REALTYPE f, q, q_sqrt; + } par, ipar; + + + void singlefilterout(REALTYPE *smp, fstage &x, parameters &par); + void computefiltercoefs(); + int type; //The type of the filter (LPF1,HPF1,LPF2,HPF2...) + int stages; //how many times the filter is applied (0->1,1->2,etc.) + REALTYPE freq; //Frequency given in Hz + REALTYPE q; //Q factor (resonance or Q factor) + REALTYPE gain; //the gain of the filter (if are shelf/peak) filters + + int abovenq; //this is 1 if the frequency is above the nyquist + int oldabovenq; + int needsinterpolation, firsttime; }; diff --git a/src/DSP/Unison.cpp b/src/DSP/Unison.cpp @@ -23,144 +23,170 @@ #include <stdio.h> #include "Unison.h" -Unison::Unison(int update_period_samples_,REALTYPE max_delay_sec_){ - update_period_samples=update_period_samples_; - max_delay=(int)(max_delay_sec_*(REALTYPE)SAMPLE_RATE+1); - if (max_delay<10) max_delay=10; - delay_buffer=new REALTYPE[max_delay]; - delay_k=0; - base_freq=1.0; - unison_bandwidth_cents=10.0; - - ZERO_REALTYPE(delay_buffer,max_delay); - - uv=NULL; - update_period_sample_k=0; - first_time=0; - - set_size(1); - -}; - -Unison::~Unison(){ - delete []delay_buffer; - if (uv) delete []uv; -}; - -void Unison::set_size(int new_size){ - if (new_size<1) new_size=1; - unison_size=new_size; - if (uv) delete []uv; - uv=new UnisonVoice[unison_size]; - first_time=true; - update_parameters(); -}; - -void Unison::set_base_frequency(REALTYPE freq){ - base_freq=freq; - update_parameters(); -}; - -void Unison::set_bandwidth(REALTYPE bandwidth){ - if (bandwidth<0) bandwidth=0.0; - if (bandwidth>1200.0) bandwidth=1200.0; - - printf("bandwidth %g\n",bandwidth); -#warning: todo: if bandwidth is too small the audio will be self canceled (because of the sign change of the outputs) - unison_bandwidth_cents=bandwidth; - update_parameters(); -}; - -void Unison::update_parameters(){ - if (!uv) return; - REALTYPE increments_per_second=SAMPLE_RATE/(REALTYPE) update_period_samples; +Unison::Unison(int update_period_samples_, REALTYPE max_delay_sec_) { + update_period_samples = update_period_samples_; + max_delay = (int)(max_delay_sec_ * (REALTYPE)SAMPLE_RATE + 1); + if(max_delay < 10) + max_delay = 10; + delay_buffer = new REALTYPE[max_delay]; + delay_k = 0; + base_freq = 1.0; + unison_bandwidth_cents = 10.0; + + ZERO_REALTYPE(delay_buffer, max_delay); + + uv = NULL; + update_period_sample_k = 0; + first_time = 0; + + set_size(1); +} + +Unison::~Unison() { + delete [] delay_buffer; + if(uv) + delete [] uv; +} + +void Unison::set_size(int new_size) { + if(new_size < 1) + new_size = 1; + unison_size = new_size; + if(uv) + delete [] uv; + uv = new UnisonVoice[unison_size]; + first_time = true; + update_parameters(); +} + +void Unison::set_base_frequency(REALTYPE freq) { + base_freq = freq; + update_parameters(); +} + +void Unison::set_bandwidth(REALTYPE bandwidth) { + if(bandwidth < 0) + bandwidth = 0.0; + if(bandwidth > 1200.0) + bandwidth = 1200.0; + + printf("bandwidth %g\n", bandwidth); +#warning \ + : todo: if bandwidth is too small the audio will be self canceled (because of the sign change of the outputs) + unison_bandwidth_cents = bandwidth; + update_parameters(); +} + +void Unison::update_parameters() { + if(!uv) + return; + REALTYPE increments_per_second = SAMPLE_RATE + / (REALTYPE) update_period_samples; // printf("#%g, %g\n",increments_per_second,base_freq); - for (int i=0;i<unison_size;i++){ - REALTYPE base=pow(UNISON_FREQ_SPAN,RND*2.0-1.0); - uv[i].relative_amplitude=base; - REALTYPE period=base/base_freq; - REALTYPE m=4.0/(period*increments_per_second); - if (RND<0.5) m=-m; - uv[i].step=m; + for(int i = 0; i < unison_size; i++) { + REALTYPE base = pow(UNISON_FREQ_SPAN, RND * 2.0 - 1.0); + uv[i].relative_amplitude = base; + REALTYPE period = base / base_freq; + REALTYPE m = 4.0 / (period * increments_per_second); + if(RND < 0.5) + m = -m; + uv[i].step = m; // printf("%g %g\n",uv[i].relative_amplitude,period); - }; - - REALTYPE max_speed=pow(2.0,unison_bandwidth_cents/1200.0); - unison_amplitude_samples=0.125*(max_speed-1.0)*SAMPLE_RATE/base_freq; -printf("unison_amplitude_samples %g\n",unison_amplitude_samples); - -#warning todo: test if unison_amplitude_samples is to big and reallocate bigger memory - if (unison_amplitude_samples>=max_delay-1) unison_amplitude_samples=max_delay-2; - - update_unison_data(); -}; - -void Unison::process(int bufsize,REALTYPE *inbuf,REALTYPE *outbuf){ - if (!uv) return; - if (!outbuf) outbuf=inbuf; - - REALTYPE volume=1.0/sqrt(unison_size); - REALTYPE xpos_step=1.0/(REALTYPE) update_period_samples; - REALTYPE xpos=(REALTYPE) update_period_sample_k*xpos_step; - for (int i=0;i<bufsize;i++){ - if ((update_period_sample_k++)>=update_period_samples) { - update_unison_data(); - update_period_sample_k=0; - xpos=0.0; - }; - xpos+=xpos_step; - REALTYPE in=inbuf[i],out=0.0; - - REALTYPE sign=1.0; - for (int k=0;k<unison_size;k++){ - REALTYPE vpos=uv[k].realpos1*(1.0-xpos)+uv[k].realpos2*xpos;//optimize - REALTYPE pos=delay_k+max_delay-vpos-1.0;//optimize - int posi; - REALTYPE posf; - F2I(pos,posi);//optimize! - if (posi>=max_delay) posi-=max_delay; - posf=pos-floor(pos); - out+=((1.0-posf)*delay_buffer[posi]+posf*delay_buffer[posi+1])*sign; - sign=-sign; - }; - outbuf[i]=out*volume; + } + + REALTYPE max_speed = pow(2.0, unison_bandwidth_cents / 1200.0); + unison_amplitude_samples = 0.125 + * (max_speed - 1.0) * SAMPLE_RATE / base_freq; + printf("unison_amplitude_samples %g\n", unison_amplitude_samples); + +#warning \ + todo: test if unison_amplitude_samples is to big and reallocate bigger memory + if(unison_amplitude_samples >= max_delay - 1) + unison_amplitude_samples = max_delay - 2; + + update_unison_data(); +} + +void Unison::process(int bufsize, REALTYPE *inbuf, REALTYPE *outbuf) { + if(!uv) + return; + if(!outbuf) + outbuf = inbuf; + + REALTYPE volume = 1.0 / sqrt(unison_size); + REALTYPE xpos_step = 1.0 / (REALTYPE) update_period_samples; + REALTYPE xpos = (REALTYPE) update_period_sample_k * xpos_step; + for(int i = 0; i < bufsize; i++) { + if((update_period_sample_k++) >= update_period_samples) { + update_unison_data(); + update_period_sample_k = 0; + xpos = 0.0; + } + xpos += xpos_step; + REALTYPE in = inbuf[i], out = 0.0; + + REALTYPE sign = 1.0; + for(int k = 0; k < unison_size; k++) { + REALTYPE vpos = uv[k].realpos1 + * (1.0 - xpos) + uv[k].realpos2 * xpos; //optimize + REALTYPE pos = delay_k + max_delay - vpos - 1.0; //optimize + int posi; + REALTYPE posf; + F2I(pos, posi); //optimize! + if(posi >= max_delay) + posi -= max_delay; + posf = pos - floor(pos); + out += + ((1.0 + - posf) * delay_buffer[posi] + posf + * delay_buffer[posi + 1]) * sign; + sign = -sign; + } + outbuf[i] = out * volume; // printf("%d %g\n",i,outbuf[i]); - delay_buffer[delay_k]=in; - if ((++delay_k)>=max_delay) delay_k=0; - }; -}; - -void Unison::update_unison_data(){ - if (!uv) return; - - for (int k=0;k<unison_size;k++){ - REALTYPE pos=uv[k].position; - REALTYPE step=uv[k].step; - pos+=step; - if (pos<=-1.0) { - pos=-1.0; - step=-step; - }; - if (pos>=1.0){ - pos=1.0; - step=-step; - }; - REALTYPE vibratto_val=(pos-0.333333333*pos*pos*pos)*1.5;//make the vibratto lfo smoother -#warning I will use relative amplitude, so the delay might be bigger than the whole buffer -#warning I have to enlarge (reallocate) the buffer to make place for the whole delay - REALTYPE newval=1.0+0.5*(vibratto_val+1.0)*unison_amplitude_samples*uv[k].relative_amplitude; - - if (first_time){ - uv[k].realpos1=uv[k].realpos2=newval; - }else{ - uv[k].realpos1=uv[k].realpos2; - uv[k].realpos2=newval; - }; - - uv[k].position=pos; - uv[k].step=step; - }; - if (first_time) first_time=false; - -}; + delay_buffer[delay_k] = in; + if((++delay_k) >= max_delay) + delay_k = 0; + } +} + +void Unison::update_unison_data() { + if(!uv) + return; + + for(int k = 0; k < unison_size; k++) { + REALTYPE pos = uv[k].position; + REALTYPE step = uv[k].step; + pos += step; + if(pos <= -1.0) { + pos = -1.0; + step = -step; + } + if(pos >= 1.0) { + pos = 1.0; + step = -step; + } + REALTYPE vibratto_val = (pos - 0.333333333 * pos * pos * pos) * 1.5; //make the vibratto lfo smoother +#warning \ + I will use relative amplitude, so the delay might be bigger than the whole buffer +#warning \ + I have to enlarge (reallocate) the buffer to make place for the whole delay + REALTYPE newval = 1.0 + 0.5 + * (vibratto_val + + 1.0) * unison_amplitude_samples + * uv[k].relative_amplitude; + + if(first_time) + uv[k].realpos1 = uv[k].realpos2 = newval; + else{ + uv[k].realpos1 = uv[k].realpos2; + uv[k].realpos2 = newval; + } + + uv[k].position = pos; + uv[k].step = step; + } + if(first_time) + first_time = false; +} diff --git a/src/DSP/Unison.h b/src/DSP/Unison.h @@ -27,42 +27,43 @@ #define UNISON_FREQ_SPAN 2.0 //how much the unison frequencies varies (always >= 1.0) -class Unison{ - public: - Unison(int update_period_samples_,REALTYPE max_delay_sec_); - ~Unison(); +class Unison +{ + public: + Unison(int update_period_samples_, REALTYPE max_delay_sec_); + ~Unison(); - void set_size(int new_size); - void set_base_frequency(REALTYPE freq); - void set_bandwidth(REALTYPE bandwidth_cents); + void set_size(int new_size); + void set_base_frequency(REALTYPE freq); + void set_bandwidth(REALTYPE bandwidth_cents); - void process(int bufsize,REALTYPE *inbuf,REALTYPE *outbuf=NULL); + void process(int bufsize, REALTYPE *inbuf, REALTYPE *outbuf = NULL); - private: - void update_parameters(); - void update_unison_data(); + private: + void update_parameters(); + void update_unison_data(); - int unison_size; - REALTYPE base_freq; - struct UnisonVoice{ - REALTYPE step,position;//base LFO - REALTYPE realpos1,realpos2; //the position regarding samples - REALTYPE relative_amplitude; - REALTYPE lin_fpos,lin_ffreq; - UnisonVoice(){ - position=RND*1.8-0.9; - realpos1=0.0; - realpos2=0.0; - step=0.0; - relative_amplitude=1.0; - }; - }*uv; - int update_period_samples,update_period_sample_k; - int max_delay,delay_k; - bool first_time; - REALTYPE *delay_buffer; - REALTYPE unison_amplitude_samples; - REALTYPE unison_bandwidth_cents; + int unison_size; + REALTYPE base_freq; + struct UnisonVoice { + REALTYPE step, position; //base LFO + REALTYPE realpos1, realpos2; //the position regarding samples + REALTYPE relative_amplitude; + REALTYPE lin_fpos, lin_ffreq; + UnisonVoice() { + position = RND * 1.8 - 0.9; + realpos1 = 0.0; + realpos2 = 0.0; + step = 0.0; + relative_amplitude = 1.0; + } + } *uv; + int update_period_samples, update_period_sample_k; + int max_delay, delay_k; + bool first_time; + REALTYPE *delay_buffer; + REALTYPE unison_amplitude_samples; + REALTYPE unison_bandwidth_cents; }; #endif diff --git a/src/Effects/Alienwah.cpp b/src/Effects/Alienwah.cpp @@ -23,83 +23,87 @@ #include <cmath> #include "Alienwah.h" -Alienwah::Alienwah(const int &insertion_,REALTYPE *const efxoutl_,REALTYPE *const efxoutr_) - :Effect(insertion_,efxoutl_,efxoutr_,NULL,0),oldl(NULL),oldr(NULL) +Alienwah::Alienwah(const int &insertion_, + REALTYPE *const efxoutl_, + REALTYPE *const efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0), oldl(NULL), oldr(NULL) { setpreset(Ppreset); cleanup(); - oldclfol=complex<REALTYPE>(fb,0.0); - oldclfor=complex<REALTYPE>(fb,0.0); -}; + oldclfol = complex<REALTYPE>(fb, 0.0); + oldclfor = complex<REALTYPE>(fb, 0.0); +} Alienwah::~Alienwah() { - if (oldl!=NULL) delete [] oldl; - if (oldr!=NULL) delete [] oldr ; -}; + if(oldl != NULL) + delete [] oldl; + if(oldr != NULL) + delete [] oldr; +} /* * Apply the effect */ -void Alienwah::out(REALTYPE *smpsl,REALTYPE *smpsr) +void Alienwah::out(REALTYPE *smpsl, REALTYPE *smpsr) { - REALTYPE lfol,lfor; //Left/Right LFOs - complex<REALTYPE> clfol,clfor,out,tmp; + REALTYPE lfol, lfor; //Left/Right LFOs + complex<REALTYPE> clfol, clfor, out, tmp; /**\todo Rework, as optimization can be used when the new complex type is * utilized. * Before all calculations needed to be done with individual REALTYPE, * but now they can be done together*/ - lfo.effectlfoout(&lfol,&lfor); - lfol*=depth*PI*2.0; - lfor*=depth*PI*2.0; - clfol=complex<REALTYPE>(cos(lfol+phase)*fb,sin(lfol+phase)*fb); //rework - clfor=complex<REALTYPE>(cos(lfor+phase)*fb,sin(lfor+phase)*fb); //rework - - for (int i=0;i<SOUND_BUFFER_SIZE;i++) { - REALTYPE x=((REALTYPE) i)/SOUND_BUFFER_SIZE; - REALTYPE x1=1.0-x; + lfo.effectlfoout(&lfol, &lfor); + lfol *= depth * PI * 2.0; + lfor *= depth * PI * 2.0; + clfol = complex<REALTYPE>(cos(lfol + phase) * fb, sin(lfol + phase) * fb); //rework + clfor = complex<REALTYPE>(cos(lfor + phase) * fb, sin(lfor + phase) * fb); //rework + + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + REALTYPE x = ((REALTYPE) i) / SOUND_BUFFER_SIZE; + REALTYPE x1 = 1.0 - x; //left - tmp=clfol*x+oldclfol*x1; + tmp = clfol * x + oldclfol * x1; - out=tmp*oldl[oldk]; - out.real()+=(1-fabs(fb))*smpsr[i]*(1.0-panning); + out = tmp * oldl[oldk]; + out.real() += (1 - fabs(fb)) * smpsr[i] * (1.0 - panning); - oldl[oldk]=out; - REALTYPE l=out.real()*10.0*(fb+0.1); + oldl[oldk] = out; + REALTYPE l = out.real() * 10.0 * (fb + 0.1); //right - tmp=clfor*x+oldclfor*x1; + tmp = clfor * x + oldclfor * x1; - out=tmp*oldr[oldk]; - out.real()+=(1-fabs(fb))*smpsr[i]*(1.0-panning); + out = tmp * oldr[oldk]; + out.real() += (1 - fabs(fb)) * smpsr[i] * (1.0 - panning); - oldr[oldk]=out; - REALTYPE r=out.real()*10.0*(fb+0.1); + oldr[oldk] = out; + REALTYPE r = out.real() * 10.0 * (fb + 0.1); - if (++oldk>=Pdelay) oldk=0; + if(++oldk >= Pdelay) + oldk = 0; //LRcross - efxoutl[i]=l*(1.0-lrcross)+r*lrcross; - efxoutr[i]=r*(1.0-lrcross)+l*lrcross; - }; - - oldclfol=clfol; - oldclfor=clfor; + efxoutl[i] = l * (1.0 - lrcross) + r * lrcross; + efxoutr[i] = r * (1.0 - lrcross) + l * lrcross; + } -}; + oldclfol = clfol; + oldclfor = clfor; +} /* * Cleanup the effect */ void Alienwah::cleanup() { - for (int i=0;i<Pdelay;i++) { - oldl[i]=complex<REALTYPE>(0.0,0.0); - oldr[i]=complex<REALTYPE>(0.0,0.0); - }; - oldk=0; -}; + for(int i = 0; i < Pdelay; i++) { + oldl[i] = complex<REALTYPE>(0.0, 0.0); + oldr[i] = complex<REALTYPE>(0.0, 0.0); + } + oldk = 0; +} /* @@ -108,81 +112,92 @@ void Alienwah::cleanup() void Alienwah::setdepth(const unsigned char &Pdepth) { - this->Pdepth=Pdepth; - depth=(Pdepth/127.0); -}; + this->Pdepth = Pdepth; + depth = (Pdepth / 127.0); +} void Alienwah::setfb(const unsigned char &Pfb) { - this->Pfb=Pfb; - fb=fabs((Pfb-64.0)/64.1); - fb=sqrt(fb); - if (fb<0.4) fb=0.4; - if (Pfb<64) fb=-fb; -}; + this->Pfb = Pfb; + fb = fabs((Pfb - 64.0) / 64.1); + fb = sqrt(fb); + if(fb < 0.4) + fb = 0.4; + if(Pfb < 64) + fb = -fb; +} void Alienwah::setvolume(const unsigned char &Pvolume) { - this->Pvolume=Pvolume; - outvolume=Pvolume/127.0; - if (insertion==0) volume=1.0; - else volume=outvolume; -}; + this->Pvolume = Pvolume; + outvolume = Pvolume / 127.0; + if(insertion == 0) + volume = 1.0; + else + volume = outvolume; +} void Alienwah::setpanning(const unsigned char &Ppanning) { - this->Ppanning=Ppanning; - panning=Ppanning/127.0; -}; + this->Ppanning = Ppanning; + panning = Ppanning / 127.0; +} void Alienwah::setlrcross(const unsigned char &Plrcross) { - this->Plrcross=Plrcross; - lrcross=Plrcross/127.0; -}; + this->Plrcross = Plrcross; + lrcross = Plrcross / 127.0; +} void Alienwah::setphase(const unsigned char &Pphase) { - this->Pphase=Pphase; - phase=(Pphase-64.0)/64.0*PI; -}; + this->Pphase = Pphase; + phase = (Pphase - 64.0) / 64.0 * PI; +} void Alienwah::setdelay(const unsigned char &Pdelay) { - if (oldl!=NULL) delete [] oldl; - if (oldr!=NULL) delete [] oldr; - if (Pdelay>=MAX_ALIENWAH_DELAY) this->Pdelay=MAX_ALIENWAH_DELAY; - else this->Pdelay=Pdelay; - oldl=new complex<REALTYPE>[Pdelay]; - oldr=new complex<REALTYPE>[Pdelay]; + if(oldl != NULL) + delete [] oldl; + if(oldr != NULL) + delete [] oldr; + if(Pdelay >= MAX_ALIENWAH_DELAY) + this->Pdelay = MAX_ALIENWAH_DELAY; + else + this->Pdelay = Pdelay; + oldl = new complex<REALTYPE>[Pdelay]; + oldr = new complex<REALTYPE>[Pdelay]; cleanup(); -}; +} void Alienwah::setpreset(unsigned char npreset) { - const int PRESET_SIZE=11; - const int NUM_PRESETS=4; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + const int PRESET_SIZE = 11; + const int NUM_PRESETS = 4; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { //AlienWah1 - {127,64,70,0,0,62,60,105,25,0,64}, + {127, 64, 70, 0, 0, 62, 60, 105, 25, 0, 64}, //AlienWah2 - {127,64,73,106,0,101,60,105,17,0,64}, + {127, 64, 73, 106, 0, 101, 60, 105, 17, 0, 64}, //AlienWah3 - {127,64,63,0,1,100,112,105,31,0,42}, + {127, 64, 63, 0, 1, 100, 112, 105, 31, 0, 42}, //AlienWah4 - {93,64,25,0,1,66,101,11,47,0,86} + {93, 64, 25, 0, 1, 66, 101, 11, 47, 0, 86} }; - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n<PRESET_SIZE;n++) changepar(n,presets[npreset][n]); - if (insertion==0) changepar(0,presets[npreset][0]/2);//lower the volume if this is system effect - Ppreset=npreset; -}; + if(npreset >= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); + if(insertion == 0) + changepar(0, presets[npreset][0] / 2); //lower the volume if this is system effect + Ppreset = npreset; +} -void Alienwah::changepar(const int &npar,const unsigned char &value) +void Alienwah::changepar(const int &npar, const unsigned char &value) { - switch (npar) { + switch(npar) { case 0: setvolume(value); break; @@ -190,19 +205,19 @@ void Alienwah::changepar(const int &npar,const unsigned char &value) setpanning(value); break; case 2: - lfo.Pfreq=value; + lfo.Pfreq = value; lfo.updateparams(); break; case 3: - lfo.Prandomness=value; + lfo.Prandomness = value; lfo.updateparams(); break; case 4: - lfo.PLFOtype=value; + lfo.PLFOtype = value; lfo.updateparams(); break; case 5: - lfo.Pstereo=value; + lfo.Pstereo = value; lfo.updateparams(); break; case 6: @@ -220,48 +235,47 @@ void Alienwah::changepar(const int &npar,const unsigned char &value) case 10: setphase(value); break; - }; -}; + } +} -unsigned char Alienwah::getpar(const int &npar)const +unsigned char Alienwah::getpar(const int &npar) const { - switch (npar) { + switch(npar) { case 0: - return(Pvolume); + return Pvolume; break; case 1: - return(Ppanning); + return Ppanning; break; case 2: - return(lfo.Pfreq); + return lfo.Pfreq; break; case 3: - return(lfo.Prandomness); + return lfo.Prandomness; break; case 4: - return(lfo.PLFOtype); + return lfo.PLFOtype; break; case 5: - return(lfo.Pstereo); + return lfo.Pstereo; break; case 6: - return(Pdepth); + return Pdepth; break; case 7: - return(Pfb); + return Pfb; break; case 8: - return(Pdelay); + return Pdelay; break; case 9: - return(Plrcross); + return Plrcross; break; case 10: - return(Pphase); + return Pphase; break; default: - return (0); - }; - -}; + return 0; + } +} diff --git a/src/Effects/Alienwah.h b/src/Effects/Alienwah.h @@ -34,49 +34,51 @@ using namespace std; /**"AlienWah" Effect*/ class Alienwah:public Effect { -public: - /** - * Constructor - * @param insetion_ 1 for insertion Effect, 0 for others - * @param efxoutl_ Pointer to Alienwah's left channel output buffer - * @param efxoutr_ Pointer to Alienwah's left channel output buffer - * @return Initialized Alienwah - */ - Alienwah(const int &insetion_,REALTYPE *const efxoutl_,REALTYPE *const efxoutr_); - ~Alienwah(); - void out(REALTYPE *const smpsl,REALTYPE *const smpsr); - - void setpreset(unsigned char npreset); - void changepar(const int &npar,const unsigned char &value); - unsigned char getpar(const int &npar)const; - void cleanup(); - -private: - //Alienwah Parameters - EffectLFO lfo;//lfo-ul Alienwah - unsigned char Pvolume; - unsigned char Ppanning; - unsigned char Pdepth;//the depth of the Alienwah - unsigned char Pfb;//feedback - unsigned char Plrcross;//feedback - unsigned char Pdelay; - unsigned char Pphase; - - - //Control Parameters - void setvolume(const unsigned char &Pvolume); - void setpanning(const unsigned char &Ppanning); - void setdepth(const unsigned char &Pdepth); - void setfb(const unsigned char &Pfb); - void setlrcross(const unsigned char &Plrcross); - void setdelay(const unsigned char &Pdelay); - void setphase(const unsigned char &Pphase); - - //Internal Values - REALTYPE panning,fb,depth,lrcross,phase; - complex<REALTYPE> *oldl,*oldr; - complex<REALTYPE> oldclfol,oldclfor; - int oldk; + public: + /** + * Constructor + * @param insetion_ 1 for insertion Effect, 0 for others + * @param efxoutl_ Pointer to Alienwah's left channel output buffer + * @param efxoutr_ Pointer to Alienwah's left channel output buffer + * @return Initialized Alienwah + */ + Alienwah(const int &insetion_, + REALTYPE *const efxoutl_, + REALTYPE *const efxoutr_); + ~Alienwah(); + void out(REALTYPE *const smpsl, REALTYPE *const smpsr); + + void setpreset(unsigned char npreset); + void changepar(const int &npar, const unsigned char &value); + unsigned char getpar(const int &npar) const; + void cleanup(); + + private: + //Alienwah Parameters + EffectLFO lfo; //lfo-ul Alienwah + unsigned char Pvolume; + unsigned char Ppanning; + unsigned char Pdepth; //the depth of the Alienwah + unsigned char Pfb; //feedback + unsigned char Plrcross; //feedback + unsigned char Pdelay; + unsigned char Pphase; + + + //Control Parameters + void setvolume(const unsigned char &Pvolume); + void setpanning(const unsigned char &Ppanning); + void setdepth(const unsigned char &Pdepth); + void setfb(const unsigned char &Pfb); + void setlrcross(const unsigned char &Plrcross); + void setdelay(const unsigned char &Pdelay); + void setphase(const unsigned char &Pphase); + + //Internal Values + REALTYPE panning, fb, depth, lrcross, phase; + complex<REALTYPE> *oldl, *oldr; + complex<REALTYPE> oldclfol, oldclfor; + int oldk; }; #endif diff --git a/src/Effects/Chorus.cpp b/src/Effects/Chorus.cpp @@ -26,26 +26,28 @@ using namespace std; -Chorus::Chorus(const int &insertion_,REALTYPE *const efxoutl_,REALTYPE *const efxoutr_) - :Effect(insertion_,efxoutl_,efxoutr_,NULL,0), - maxdelay((int)(MAX_CHORUS_DELAY/1000.0*SAMPLE_RATE)), - delaySample(maxdelay) +Chorus::Chorus(const int &insertion_, + REALTYPE *const efxoutl_, + REALTYPE *const efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0), + maxdelay((int)(MAX_CHORUS_DELAY / 1000.0 * SAMPLE_RATE)), + delaySample(maxdelay) { - dlk=0; - drk=0; + dlk = 0; + drk = 0; //maxdelay=(int)(MAX_CHORUS_DELAY/1000.0*SAMPLE_RATE); //delayl=new REALTYPE[maxdelay]; //delayr=new REALTYPE[maxdelay]; setpreset(Ppreset); - lfo.effectlfoout(&lfol,&lfor); - dl2=getdelay(lfol); - dr2=getdelay(lfor); + lfo.effectlfoout(&lfol, &lfor); + dl2 = getdelay(lfol); + dr2 = getdelay(lfor); cleanup(); -}; +} -Chorus::~Chorus() {}; +Chorus::~Chorus() {} /* * get the delay value in samples; xlfo is the current lfo value @@ -53,91 +55,100 @@ Chorus::~Chorus() {}; REALTYPE Chorus::getdelay(REALTYPE xlfo) { REALTYPE result; - if (Pflangemode==0) { - result=(delay+xlfo*depth)*SAMPLE_RATE; - } else result=0; + if(Pflangemode == 0) + result = (delay + xlfo * depth) * SAMPLE_RATE; + else + result = 0; //check if it is too big delay(caused bu errornous setdelay() and setdepth() /**\todo fix setdelay() and setdepth(), so this error cannot occur*/ - if ((result+0.5)>=maxdelay) { - cerr << "WARNING: Chorus.C::getdelay(..) too big delay (see setdelay and setdepth funcs.)\n"; - result=maxdelay-1.0; - }; - return(result); -}; + if((result + 0.5) >= maxdelay) { + cerr + << + "WARNING: Chorus.C::getdelay(..) too big delay (see setdelay and setdepth funcs.)\n"; + result = maxdelay - 1.0; + } + return result; +} /* * Apply the effect */ -void Chorus::out(REALTYPE *smpsl,REALTYPE *smpsr) +void Chorus::out(REALTYPE *smpsl, REALTYPE *smpsr) { - const Stereo<AuSample> input(AuSample(SOUND_BUFFER_SIZE,smpsl),AuSample(SOUND_BUFFER_SIZE,smpsr)); + const Stereo<AuSample> input(AuSample(SOUND_BUFFER_SIZE, smpsl), AuSample( + SOUND_BUFFER_SIZE, + smpsr)); out(input); } void Chorus::out(const Stereo<AuSample> &input) { - const REALTYPE one=1.0; - dl1=dl2; - dr1=dr2; - lfo.effectlfoout(&lfol,&lfor); + const REALTYPE one = 1.0; + dl1 = dl2; + dr1 = dr2; + lfo.effectlfoout(&lfol, &lfor); - dl2=getdelay(lfol); - dr2=getdelay(lfor); + dl2 = getdelay(lfol); + dr2 = getdelay(lfor); - for (int i=0;i<input.l().size();i++) { - REALTYPE inl=input.l()[i]; - REALTYPE inr=input.r()[i]; + for(int i = 0; i < input.l().size(); i++) { + REALTYPE inl = input.l()[i]; + REALTYPE inr = input.r()[i]; //LRcross - Stereo<REALTYPE> tmpc(inl,inr); + Stereo<REALTYPE> tmpc(inl, inr); //REALTYPE r=inr; - inl=tmpc.l()*(1.0-lrcross)+tmpc.r()*lrcross; - inr=tmpc.r()*(1.0-lrcross)+tmpc.l()*lrcross; + inl = tmpc.l() * (1.0 - lrcross) + tmpc.r() * lrcross; + inr = tmpc.r() * (1.0 - lrcross) + tmpc.l() * lrcross; //Left channel //compute the delay in samples using linear interpolation between the lfo delays - mdel=(dl1*(SOUND_BUFFER_SIZE-i)+dl2*i)/SOUND_BUFFER_SIZE; - if (++dlk>=maxdelay) dlk=0; - REALTYPE tmp=dlk-mdel+maxdelay*2.0;//where should I get the sample from + mdel = (dl1 * (SOUND_BUFFER_SIZE - i) + dl2 * i) / SOUND_BUFFER_SIZE; + if(++dlk >= maxdelay) + dlk = 0; + REALTYPE tmp = dlk - mdel + maxdelay * 2.0; //where should I get the sample from - F2I(tmp,dlhi); - dlhi%=maxdelay; + F2I(tmp, dlhi); + dlhi %= maxdelay; - dlhi2=(dlhi-1+maxdelay)%maxdelay; - dllo=1.0-fmod(tmp,one); - efxoutl[i]=delaySample.l()[dlhi2]*dllo+delaySample.l()[dlhi]*(1.0-dllo); - delaySample.l()[dlk]=inl+efxoutl[i]*fb; + dlhi2 = (dlhi - 1 + maxdelay) % maxdelay; + dllo = 1.0 - fmod(tmp, one); + efxoutl[i] = delaySample.l()[dlhi2] * dllo + delaySample.l()[dlhi] + * (1.0 - dllo); + delaySample.l()[dlk] = inl + efxoutl[i] * fb; //Right channel //compute the delay in samples using linear interpolation between the lfo delays - mdel=(dr1*(SOUND_BUFFER_SIZE-i)+dr2*i)/SOUND_BUFFER_SIZE; - if (++drk>=maxdelay) drk=0; - tmp=drk*1.0-mdel+maxdelay*2.0;//where should I get the sample from - - F2I(tmp,dlhi); - dlhi%=maxdelay; - - dlhi2=(dlhi-1+maxdelay)%maxdelay; - dllo=1.0-fmod(tmp,one); - efxoutr[i]=delaySample.r()[dlhi2]*dllo+delaySample.r()[dlhi]*(1.0-dllo); - delaySample.r()[dlk]=inr+efxoutr[i]*fb; - - }; - - if (Poutsub!=0) - for (int i=0;i<input.l().size();i++) { + mdel = (dr1 * (SOUND_BUFFER_SIZE - i) + dr2 * i) / SOUND_BUFFER_SIZE; + if(++drk >= maxdelay) + drk = 0; + tmp = drk * 1.0 - mdel + maxdelay * 2.0; //where should I get the sample from + + F2I(tmp, dlhi); + dlhi %= maxdelay; + + dlhi2 = (dlhi - 1 + maxdelay) % maxdelay; + dllo = 1.0 - fmod(tmp, one); + efxoutr[i] = delaySample.r()[dlhi2] * dllo + delaySample.r()[dlhi] + * (1.0 - dllo); + delaySample.r()[dlk] = inr + efxoutr[i] * fb; + } + + if(Poutsub != 0) + for(int i = 0; i < input.l().size(); i++) { efxoutl[i] *= -1.0; efxoutr[i] *= -1.0; - }; + } + ; - for (int i=0;i<input.l().size();i++) { - efxoutl[i]*=panning; - efxoutr[i]*=(1.0-panning); - }; -}; + for(int i = 0; i < input.l().size(); i++) { + efxoutl[i] *= panning; + efxoutr[i] *= (1.0 - panning); + } +} /* * Cleanup the effect @@ -146,84 +157,88 @@ void Chorus::cleanup() { delaySample.l().clear(); delaySample.r().clear(); -}; +} /* * Parameter control */ void Chorus::setdepth(const unsigned char &Pdepth) { - this->Pdepth=Pdepth; - depth=(pow(8.0,(Pdepth/127.0)*2.0)-1.0)/1000.0;//seconds -}; + this->Pdepth = Pdepth; + depth = (pow(8.0, (Pdepth / 127.0) * 2.0) - 1.0) / 1000.0; //seconds +} void Chorus::setdelay(const unsigned char &Pdelay) { - this->Pdelay=Pdelay; - delay=(pow(10.0,(Pdelay/127.0)*2.0)-1.0)/1000.0;//seconds -}; + this->Pdelay = Pdelay; + delay = (pow(10.0, (Pdelay / 127.0) * 2.0) - 1.0) / 1000.0; //seconds +} void Chorus::setfb(const unsigned char &Pfb) { - this->Pfb=Pfb; - fb=(Pfb-64.0)/64.1; -}; + this->Pfb = Pfb; + fb = (Pfb - 64.0) / 64.1; +} void Chorus::setvolume(const unsigned char &Pvolume) { - this->Pvolume=Pvolume; - outvolume=Pvolume/127.0; - if (insertion==0) volume=1.0; - else volume=outvolume; -}; + this->Pvolume = Pvolume; + outvolume = Pvolume / 127.0; + if(insertion == 0) + volume = 1.0; + else + volume = outvolume; +} void Chorus::setpanning(const unsigned char &Ppanning) { - this->Ppanning=Ppanning; - panning=Ppanning/127.0; -}; + this->Ppanning = Ppanning; + panning = Ppanning / 127.0; +} void Chorus::setlrcross(const unsigned char &Plrcross) { - this->Plrcross=Plrcross; - lrcross=Plrcross/127.0; -}; + this->Plrcross = Plrcross; + lrcross = Plrcross / 127.0; +} void Chorus::setpreset(unsigned char npreset) { - const int PRESET_SIZE=12; - const int NUM_PRESETS=10; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + const int PRESET_SIZE = 12; + const int NUM_PRESETS = 10; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { //Chorus1 - {64,64,50,0,0,90,40,85,64,119,0,0}, + {64, 64, 50, 0, 0, 90, 40, 85, 64, 119, 0, 0 }, //Chorus2 - {64,64,45,0,0,98,56,90,64,19,0,0}, + {64, 64, 45, 0, 0, 98, 56, 90, 64, 19, 0, 0 }, //Chorus3 - {64,64,29,0,1,42,97,95,90,127,0,0}, + {64, 64, 29, 0, 1, 42, 97, 95, 90, 127, 0, 0 }, //Celeste1 - {64,64,26,0,0,42,115,18,90,127,0,0}, + {64, 64, 26, 0, 0, 42, 115, 18, 90, 127, 0, 0 }, //Celeste2 - {64,64,29,117,0,50,115,9,31,127,0,1}, + {64, 64, 29, 117, 0, 50, 115, 9, 31, 127, 0, 1 }, //Flange1 - {64,64,57,0,0,60,23,3,62,0,0,0}, + {64, 64, 57, 0, 0, 60, 23, 3, 62, 0, 0, 0 }, //Flange2 - {64,64,33,34,1,40,35,3,109,0,0,0}, + {64, 64, 33, 34, 1, 40, 35, 3, 109, 0, 0, 0 }, //Flange3 - {64,64,53,34,1,94,35,3,54,0,0,1}, + {64, 64, 53, 34, 1, 94, 35, 3, 54, 0, 0, 1 }, //Flange4 - {64,64,40,0,1,62,12,19,97,0,0,0}, + {64, 64, 40, 0, 1, 62, 12, 19, 97, 0, 0, 0 }, //Flange5 - {64,64,55,105,0,24,39,19,17,0,0,1} + {64, 64, 55, 105, 0, 24, 39, 19, 17, 0, 0, 1 } }; - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n<PRESET_SIZE;n++) changepar(n,presets[npreset][n]); - Ppreset=npreset; -}; + if(npreset >= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); + Ppreset = npreset; +} -void Chorus::changepar(const int &npar,const unsigned char &value) +void Chorus::changepar(const int &npar, const unsigned char &value) { - switch (npar) { + switch(npar) { case 0: setvolume(value); break; @@ -231,19 +246,19 @@ void Chorus::changepar(const int &npar,const unsigned char &value) setpanning(value); break; case 2: - lfo.Pfreq=value; + lfo.Pfreq = value; lfo.updateparams(); break; case 3: - lfo.Prandomness=value; + lfo.Prandomness = value; lfo.updateparams(); break; case 4: - lfo.PLFOtype=value; + lfo.PLFOtype = value; lfo.updateparams(); break; case 5: - lfo.Pstereo=value; + lfo.Pstereo = value; lfo.updateparams(); break; case 6: @@ -259,58 +274,61 @@ void Chorus::changepar(const int &npar,const unsigned char &value) setlrcross(value); break; case 10: - if (value>1) Pflangemode=1; - else Pflangemode=value; + if(value > 1) + Pflangemode = 1; + else + Pflangemode = value; break; case 11: - if (value>1) Poutsub=1; - else Poutsub=value; + if(value > 1) + Poutsub = 1; + else + Poutsub = value; break; - }; -}; + } +} -unsigned char Chorus::getpar(const int &npar)const +unsigned char Chorus::getpar(const int &npar) const { - switch (npar) { + switch(npar) { case 0: - return(Pvolume); + return Pvolume; break; case 1: - return(Ppanning); + return Ppanning; break; case 2: - return(lfo.Pfreq); + return lfo.Pfreq; break; case 3: - return(lfo.Prandomness); + return lfo.Prandomness; break; case 4: - return(lfo.PLFOtype); + return lfo.PLFOtype; break; case 5: - return(lfo.Pstereo); + return lfo.Pstereo; break; case 6: - return(Pdepth); + return Pdepth; break; case 7: - return(Pdelay); + return Pdelay; break; case 8: - return(Pfb); + return Pfb; break; case 9: - return(Plrcross); + return Plrcross; break; case 10: - return(Pflangemode); + return Pflangemode; break; case 11: - return(Poutsub); + return Poutsub; break; default: - return (0); - }; - -}; + return 0; + } +} diff --git a/src/Effects/Chorus.h b/src/Effects/Chorus.h @@ -33,83 +33,83 @@ /**Chorus and Flange effects*/ class Chorus:public Effect { -public: - Chorus(const int &insetion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); - /**Destructor*/ - ~Chorus(); - void out(REALTYPE *smpsl,REALTYPE *smpsr); - void out(const Stereo<AuSample> &input); - void setpreset(unsigned char npreset); - /** - * Sets the value of the chosen variable - * - * The possible parameters are: - * -# Volume - * -# Panning - * -# LFO Frequency - * -# LFO Randomness - * -# LFO Type - * -# LFO stereo - * -# Depth - * -# Delay - * -# Feedback - * -# Flange Mode - * -# Subtractive - * @param npar number of chosen parameter - * @param value the new value - */ - void changepar(const int &npar,const unsigned char &value); - /** - * Gets the value of the chosen variable - * - * The possible parameters are: - * -# Volume - * -# Panning - * -# LFO Frequency - * -# LFO Randomness - * -# LFO Type - * -# LFO stereo - * -# Depth - * -# Delay - * -# Feedback - * -# Flange Mode - * -# Subtractive - * @param npar number of chosen parameter - * @return the value of the parameter - */ - unsigned char getpar(const int &npar)const; - void cleanup(); + public: + Chorus(const int &insetion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_); + /**Destructor*/ + ~Chorus(); + void out(REALTYPE *smpsl, REALTYPE *smpsr); + void out(const Stereo<AuSample> &input); + void setpreset(unsigned char npreset); + /** + * Sets the value of the chosen variable + * + * The possible parameters are: + * -# Volume + * -# Panning + * -# LFO Frequency + * -# LFO Randomness + * -# LFO Type + * -# LFO stereo + * -# Depth + * -# Delay + * -# Feedback + * -# Flange Mode + * -# Subtractive + * @param npar number of chosen parameter + * @param value the new value + */ + void changepar(const int &npar, const unsigned char &value); + /** + * Gets the value of the chosen variable + * + * The possible parameters are: + * -# Volume + * -# Panning + * -# LFO Frequency + * -# LFO Randomness + * -# LFO Type + * -# LFO stereo + * -# Depth + * -# Delay + * -# Feedback + * -# Flange Mode + * -# Subtractive + * @param npar number of chosen parameter + * @return the value of the parameter + */ + unsigned char getpar(const int &npar) const; + void cleanup(); -private: - //Chorus Parameters - EffectLFO lfo;//lfo-ul chorus - unsigned char Pvolume; - unsigned char Ppanning; - unsigned char Pdepth;//the depth of the Chorus(ms) - unsigned char Pdelay;//the delay (ms) - unsigned char Pfb;//feedback - unsigned char Plrcross;//feedback - unsigned char Pflangemode;//how the LFO is scaled, to result chorus or flange - unsigned char Poutsub;//if I wish to substract the output instead of the adding it + private: + //Chorus Parameters + EffectLFO lfo; //lfo-ul chorus + unsigned char Pvolume; + unsigned char Ppanning; + unsigned char Pdepth; //the depth of the Chorus(ms) + unsigned char Pdelay; //the delay (ms) + unsigned char Pfb; //feedback + unsigned char Plrcross; //feedback + unsigned char Pflangemode; //how the LFO is scaled, to result chorus or flange + unsigned char Poutsub; //if I wish to substract the output instead of the adding it - //Parameter Controls - void setvolume(const unsigned char &Pvolume); - void setpanning(const unsigned char &Ppanning); - void setdepth(const unsigned char &Pdepth); - void setdelay(const unsigned char &Pdelay); - void setfb(const unsigned char &Pfb); - void setlrcross(const unsigned char &Plrcross); + //Parameter Controls + void setvolume(const unsigned char &Pvolume); + void setpanning(const unsigned char &Ppanning); + void setdepth(const unsigned char &Pdepth); + void setdelay(const unsigned char &Pdelay); + void setfb(const unsigned char &Pfb); + void setlrcross(const unsigned char &Plrcross); - //Internal Values - REALTYPE depth,delay,fb,lrcross,panning; - REALTYPE dl1,dl2,dr1,dr2,lfol,lfor; - int maxdelay; - Stereo<AuSample> delaySample; - //REALTYPE *delayl,*delayr; - int dlk,drk,dlhi,dlhi2; - REALTYPE getdelay(REALTYPE xlfo); - REALTYPE dllo,mdel; + //Internal Values + REALTYPE depth, delay, fb, lrcross, panning; + REALTYPE dl1, dl2, dr1, dr2, lfol, lfor; + int maxdelay; + Stereo<AuSample> delaySample; + //REALTYPE *delayl,*delayr; + int dlk, drk, dlhi, dlhi2; + REALTYPE getdelay(REALTYPE xlfo); + REALTYPE dllo, mdel; }; #endif diff --git a/src/Effects/Distorsion.cpp b/src/Effects/Distorsion.cpp @@ -28,159 +28,199 @@ * Waveshape (this is called by OscilGen::waveshape and Distorsion::process) */ -void waveshapesmps(int n,REALTYPE *smps,unsigned char type,unsigned char drive) +void waveshapesmps(int n, + REALTYPE *smps, + unsigned char type, + unsigned char drive) { - int i; - REALTYPE ws=drive/127.0; + int i; + REALTYPE ws = drive / 127.0; REALTYPE tmpv; - switch (type) { + switch(type) { case 1: - ws=pow(10,ws*ws*3.0)-1.0+0.001;//Arctangent - for (i=0;i<n;i++) - smps[i]=atan(smps[i]*ws)/atan(ws); + ws = pow(10, ws * ws * 3.0) - 1.0 + 0.001; //Arctangent + for(i = 0; i < n; i++) + smps[i] = atan(smps[i] * ws) / atan(ws); break; case 2: - ws=ws*ws*32.0+0.0001;//Asymmetric - if (ws<1.0) tmpv=sin(ws)+0.1; - else tmpv=1.1; - for (i=0;i<n;i++) { - smps[i]=sin(smps[i]*(0.1+ws-ws*smps[i]))/tmpv; - }; + ws = ws * ws * 32.0 + 0.0001; //Asymmetric + if(ws < 1.0) + tmpv = sin(ws) + 0.1; + else + tmpv = 1.1; + for(i = 0; i < n; i++) + smps[i] = sin(smps[i] * (0.1 + ws - ws * smps[i])) / tmpv; + ; break; case 3: - ws=ws*ws*ws*20.0+0.0001;//Pow - for (i=0;i<n;i++) { - smps[i]*=ws; - if (fabs(smps[i])<1.0) { - smps[i]=(smps[i]-pow(smps[i],3.0))*3.0; - if (ws<1.0) smps[i]/=ws; - } else smps[i]=0.0; - }; + ws = ws * ws * ws * 20.0 + 0.0001; //Pow + for(i = 0; i < n; i++) { + smps[i] *= ws; + if(fabs(smps[i]) < 1.0) { + smps[i] = (smps[i] - pow(smps[i], 3.0)) * 3.0; + if(ws < 1.0) + smps[i] /= ws; + } + else + smps[i] = 0.0; + } break; case 4: - ws=ws*ws*ws*32.0+0.0001;//Sine - if (ws<1.57) tmpv=sin(ws); - else tmpv=1.0; - for (i=0;i<n;i++) smps[i]=sin(smps[i]*ws)/tmpv; + ws = ws * ws * ws * 32.0 + 0.0001; //Sine + if(ws < 1.57) + tmpv = sin(ws); + else + tmpv = 1.0; + for(i = 0; i < n; i++) + smps[i] = sin(smps[i] * ws) / tmpv; break; case 5: - ws=ws*ws+0.000001;//Quantisize - for (i=0;i<n;i++) - smps[i]=floor(smps[i]/ws+0.5)*ws; + ws = ws * ws + 0.000001; //Quantisize + for(i = 0; i < n; i++) + smps[i] = floor(smps[i] / ws + 0.5) * ws; break; case 6: - ws=ws*ws*ws*32+0.0001;//Zigzag - if (ws<1.0) tmpv=sin(ws); - else tmpv=1.0; - for (i=0;i<n;i++) - smps[i]=asin(sin(smps[i]*ws))/tmpv; + ws = ws * ws * ws * 32 + 0.0001; //Zigzag + if(ws < 1.0) + tmpv = sin(ws); + else + tmpv = 1.0; + for(i = 0; i < n; i++) + smps[i] = asin(sin(smps[i] * ws)) / tmpv; break; case 7: - ws=pow(2.0,-ws*ws*8.0); //Limiter - for (i=0;i<n;i++) { - REALTYPE tmp=smps[i]; - if (fabs(tmp)>ws) { - if (tmp>=0.0) smps[i]=1.0; - else smps[i]=-1.0; - } else smps[i]/=ws; - }; + ws = pow(2.0, -ws * ws * 8.0); //Limiter + for(i = 0; i < n; i++) { + REALTYPE tmp = smps[i]; + if(fabs(tmp) > ws) { + if(tmp >= 0.0) + smps[i] = 1.0; + else + smps[i] = -1.0; + } + else + smps[i] /= ws; + } break; case 8: - ws=pow(2.0,-ws*ws*8.0); //Upper Limiter - for (i=0;i<n;i++) { - REALTYPE tmp=smps[i]; - if (tmp>ws) smps[i]=ws; - smps[i]*=2.0; - }; + ws = pow(2.0, -ws * ws * 8.0); //Upper Limiter + for(i = 0; i < n; i++) { + REALTYPE tmp = smps[i]; + if(tmp > ws) + smps[i] = ws; + smps[i] *= 2.0; + } break; case 9: - ws=pow(2.0,-ws*ws*8.0); //Lower Limiter - for (i=0;i<n;i++) { - REALTYPE tmp=smps[i]; - if (tmp<-ws) smps[i]=-ws; - smps[i]*=2.0; - }; + ws = pow(2.0, -ws * ws * 8.0); //Lower Limiter + for(i = 0; i < n; i++) { + REALTYPE tmp = smps[i]; + if(tmp < -ws) + smps[i] = -ws; + smps[i] *= 2.0; + } break; case 10: - ws=(pow(2.0,ws*6.0)-1.0)/pow(2.0,6.0); //Inverse Limiter - for (i=0;i<n;i++) { - REALTYPE tmp=smps[i]; - if (fabs(tmp)>ws) { - if (tmp>=0.0) smps[i]=tmp-ws; - else smps[i]=tmp+ws; - } else smps[i]=0; - }; + ws = (pow(2.0, ws * 6.0) - 1.0) / pow(2.0, 6.0); //Inverse Limiter + for(i = 0; i < n; i++) { + REALTYPE tmp = smps[i]; + if(fabs(tmp) > ws) { + if(tmp >= 0.0) + smps[i] = tmp - ws; + else + smps[i] = tmp + ws; + } + else + smps[i] = 0; + } break; case 11: - ws=pow(5,ws*ws*1.0)-1.0;//Clip - for (i=0;i<n;i++) - smps[i]=smps[i]*(ws+0.5)*0.9999-floor(0.5+smps[i]*(ws+0.5)*0.9999); + ws = pow(5, ws * ws * 1.0) - 1.0; //Clip + for(i = 0; i < n; i++) + smps[i] = smps[i] + * (ws + 0.5) * 0.9999 - floor( + 0.5 + smps[i] * (ws + 0.5) * 0.9999); break; case 12: - ws=ws*ws*ws*30+0.001;//Asym2 - if (ws<0.3) tmpv=ws; - else tmpv=1.0; - for (i=0;i<n;i++) { - REALTYPE tmp=smps[i]*ws; - if ((tmp>-2.0) && (tmp<1.0)) smps[i]=tmp*(1.0-tmp)*(tmp+2.0)/tmpv; - else smps[i]=0.0; - }; + ws = ws * ws * ws * 30 + 0.001; //Asym2 + if(ws < 0.3) + tmpv = ws; + else + tmpv = 1.0; + for(i = 0; i < n; i++) { + REALTYPE tmp = smps[i] * ws; + if((tmp > -2.0) && (tmp < 1.0)) + smps[i] = tmp * (1.0 - tmp) * (tmp + 2.0) / tmpv; + else + smps[i] = 0.0; + } break; case 13: - ws=ws*ws*ws*32.0+0.0001;//Pow2 - if (ws<1.0) tmpv=ws*(1+ws)/2.0; - else tmpv=1.0; - for (i=0;i<n;i++) { - REALTYPE tmp=smps[i]*ws; - if ((tmp>-1.0)&&(tmp<1.618034)) smps[i]=tmp*(1.0-tmp)/tmpv; - else if (tmp>0.0) smps[i]=-1.0; - else smps[i]=-2.0; - }; + ws = ws * ws * ws * 32.0 + 0.0001; //Pow2 + if(ws < 1.0) + tmpv = ws * (1 + ws) / 2.0; + else + tmpv = 1.0; + for(i = 0; i < n; i++) { + REALTYPE tmp = smps[i] * ws; + if((tmp > -1.0) && (tmp < 1.618034)) + smps[i] = tmp * (1.0 - tmp) / tmpv; + else + if(tmp > 0.0) + smps[i] = -1.0; + else + smps[i] = -2.0; + } break; case 14: - ws=pow(ws,5.0)*80.0+0.0001;//sigmoid - if (ws>10.0) tmpv=0.5; - else tmpv=0.5-1.0/(exp(ws)+1.0); - for (i=0;i<n;i++) { - REALTYPE tmp=smps[i]*ws; - if (tmp<-10.0) tmp=-10.0; - else if (tmp>10.0) tmp=10.0; - tmp=0.5-1.0/(exp(tmp)+1.0); - smps[i]=tmp/tmpv; - }; + ws = pow(ws, 5.0) * 80.0 + 0.0001; //sigmoid + if(ws > 10.0) + tmpv = 0.5; + else + tmpv = 0.5 - 1.0 / (exp(ws) + 1.0); + for(i = 0; i < n; i++) { + REALTYPE tmp = smps[i] * ws; + if(tmp < -10.0) + tmp = -10.0; + else + if(tmp > 10.0) + tmp = 10.0; + tmp = 0.5 - 1.0 / (exp(tmp) + 1.0); + smps[i] = tmp / tmpv; + } break; /**\todo update to Distorsion::changepar (Ptype max) if there is added more waveshapings functions*/ - }; - -}; + } +} -Distorsion::Distorsion(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_) - :Effect(insertion_,efxoutl_,efxoutr_,NULL,0) +Distorsion::Distorsion(const int &insertion_, + REALTYPE *efxoutl_, + REALTYPE *efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0) { - - lpfl=new AnalogFilter(2,22000,1,0); - lpfr=new AnalogFilter(2,22000,1,0); - hpfl=new AnalogFilter(3,20,1,0); - hpfr=new AnalogFilter(3,20,1,0); + lpfl = new AnalogFilter(2, 22000, 1, 0); + lpfr = new AnalogFilter(2, 22000, 1, 0); + hpfl = new AnalogFilter(3, 20, 1, 0); + hpfr = new AnalogFilter(3, 20, 1, 0); //default values - Pvolume=50; - Plrcross=40; - Pdrive=90; - Plevel=64; - Ptype=0; - Pnegate=0; - Plpf=127; - Phpf=0; - Pstereo=0; - Pprefiltering=0; + Pvolume = 50; + Plrcross = 40; + Pdrive = 90; + Plevel = 64; + Ptype = 0; + Pnegate = 0; + Plpf = 127; + Phpf = 0; + Pstereo = 0; + Pprefiltering = 0; setpreset(Ppreset); cleanup(); -}; +} Distorsion::~Distorsion() { @@ -188,8 +228,7 @@ Distorsion::~Distorsion() delete lpfr; delete hpfl; delete hpfr; - -}; +} /* * Cleanup the effect @@ -200,72 +239,77 @@ void Distorsion::cleanup() hpfl->cleanup(); lpfr->cleanup(); hpfr->cleanup(); -}; +} /* * Apply the filters */ -void Distorsion::applyfilters(REALTYPE *efxoutl,REALTYPE *efxoutr) +void Distorsion::applyfilters(REALTYPE *efxoutl, REALTYPE *efxoutr) { lpfl->filterout(efxoutl); hpfl->filterout(efxoutl); - if (Pstereo!=0) {//stereo + if(Pstereo != 0) { //stereo lpfr->filterout(efxoutr); hpfr->filterout(efxoutr); - }; - -}; + } +} /* * Effect output */ -void Distorsion::out(REALTYPE *smpsl,REALTYPE *smpsr) +void Distorsion::out(REALTYPE *smpsl, REALTYPE *smpsr) { - int i; - REALTYPE l,r,lout,rout; - - REALTYPE inputvol=pow(5.0,(Pdrive-32.0)/127.0); - if (Pnegate!=0) inputvol*=-1.0; - - if (Pstereo!=0) {//Stereo - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - efxoutl[i]=smpsl[i]*inputvol*panning; - efxoutr[i]=smpsr[i]*inputvol*(1.0-panning); - }; - } else { - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - efxoutl[i]=( smpsl[i]*panning + smpsr[i]*(1.0-panning) ) * inputvol; - }; - }; - - if (Pprefiltering!=0) applyfilters(efxoutl,efxoutr); + int i; + REALTYPE l, r, lout, rout; + + REALTYPE inputvol = pow(5.0, (Pdrive - 32.0) / 127.0); + if(Pnegate != 0) + inputvol *= -1.0; + + if(Pstereo != 0) { //Stereo + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + efxoutl[i] = smpsl[i] * inputvol * panning; + efxoutr[i] = smpsr[i] * inputvol * (1.0 - panning); + } + } + else { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + efxoutl[i] = + (smpsl[i] * panning + smpsr[i] * (1.0 - panning)) * inputvol; + ; + } + + if(Pprefiltering != 0) + applyfilters(efxoutl, efxoutr); //no optimised, yet (no look table) - waveshapesmps(SOUND_BUFFER_SIZE,efxoutl,Ptype+1,Pdrive); - if (Pstereo!=0) waveshapesmps(SOUND_BUFFER_SIZE,efxoutr,Ptype+1,Pdrive); + waveshapesmps(SOUND_BUFFER_SIZE, efxoutl, Ptype + 1, Pdrive); + if(Pstereo != 0) + waveshapesmps(SOUND_BUFFER_SIZE, efxoutr, Ptype + 1, Pdrive); - if (Pprefiltering==0) applyfilters(efxoutl,efxoutr); + if(Pprefiltering == 0) + applyfilters(efxoutl, efxoutr); - if (Pstereo==0) for (i=0;i<SOUND_BUFFER_SIZE;i++) efxoutr[i]=efxoutl[i]; + if(Pstereo == 0) + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + efxoutr[i] = efxoutl[i]; - REALTYPE level=dB2rap(60.0*Plevel/127.0-40.0); - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - lout=efxoutl[i]; - rout=efxoutr[i]; - l=lout*(1.0-lrcross)+rout*lrcross; - r=rout*(1.0-lrcross)+lout*lrcross; - lout=l; - rout=r; + REALTYPE level = dB2rap(60.0 * Plevel / 127.0 - 40.0); + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + lout = efxoutl[i]; + rout = efxoutr[i]; + l = lout * (1.0 - lrcross) + rout * lrcross; + r = rout * (1.0 - lrcross) + lout * lrcross; + lout = l; + rout = r; - efxoutl[i]=lout*2.0*level; - efxoutr[i]=rout*2.0*level; - - }; - -}; + efxoutl[i] = lout * 2.0 * level; + efxoutr[i] = rout * 2.0 * level; + } +} /* @@ -273,79 +317,83 @@ void Distorsion::out(REALTYPE *smpsl,REALTYPE *smpsr) */ void Distorsion::setvolume(const unsigned char &Pvolume) { - this->Pvolume=Pvolume; - - if (insertion==0) { - outvolume=pow(0.01,(1.0-Pvolume/127.0))*4.0; - volume=1.0; - } else { - volume=outvolume=Pvolume/127.0; - }; - if (Pvolume==0) cleanup(); - -}; + this->Pvolume = Pvolume; + + if(insertion == 0) { + outvolume = pow(0.01, (1.0 - Pvolume / 127.0)) * 4.0; + volume = 1.0; + } + else + volume = outvolume = Pvolume / 127.0; + ; + if(Pvolume == 0) + cleanup(); +} void Distorsion::setpanning(const unsigned char &Ppanning) { - this->Ppanning=Ppanning; - panning=(Ppanning+0.5)/127.0; -}; + this->Ppanning = Ppanning; + panning = (Ppanning + 0.5) / 127.0; +} void Distorsion::setlrcross(const unsigned char &Plrcross) { - this->Plrcross=Plrcross; - lrcross=Plrcross/127.0*1.0; -}; + this->Plrcross = Plrcross; + lrcross = Plrcross / 127.0 * 1.0; +} void Distorsion::setlpf(const unsigned char &Plpf) { - this->Plpf=Plpf; - REALTYPE fr=exp(pow(Plpf/127.0,0.5)*log(25000.0))+40; + this->Plpf = Plpf; + REALTYPE fr = exp(pow(Plpf / 127.0, 0.5) * log(25000.0)) + 40; lpfl->setfreq(fr); lpfr->setfreq(fr); -}; +} void Distorsion::sethpf(const unsigned char &Phpf) { - this->Phpf=Phpf; - REALTYPE fr=exp(pow(Phpf/127.0,0.5)*log(25000.0))+20.0; + this->Phpf = Phpf; + REALTYPE fr = exp(pow(Phpf / 127.0, 0.5) * log(25000.0)) + 20.0; hpfl->setfreq(fr); hpfr->setfreq(fr); -}; +} void Distorsion::setpreset(unsigned char npreset) { - const int PRESET_SIZE=11; - const int NUM_PRESETS=6; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + const int PRESET_SIZE = 11; + const int NUM_PRESETS = 6; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { //Overdrive 1 - {127,64,35,56,70,0,0,96,0,0,0}, + {127, 64, 35, 56, 70, 0, 0, 96, 0, 0, 0 }, //Overdrive 2 - {127,64,35,29,75,1,0,127,0,0,0}, + {127, 64, 35, 29, 75, 1, 0, 127, 0, 0, 0 }, //A. Exciter 1 - {64,64,35,75,80,5,0,127,105,1,0}, + {64, 64, 35, 75, 80, 5, 0, 127, 105, 1, 0 }, //A. Exciter 2 - {64,64,35,85,62,1,0,127,118,1,0}, + {64, 64, 35, 85, 62, 1, 0, 127, 118, 1, 0 }, //Guitar Amp - {127,64,35,63,75,2,0,55,0,0,0}, + {127, 64, 35, 63, 75, 2, 0, 55, 0, 0, 0 }, //Quantisize - {127,64,35,88,75,4,0,127,0,1,0} + {127, 64, 35, 88, 75, 4, 0, 127, 0, 1, 0 } }; - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n<PRESET_SIZE;n++) changepar(n,presets[npreset][n]); - if (insertion==0) changepar(0,(int) (presets[npreset][0]/1.5));//lower the volume if this is system effect - Ppreset=npreset; + if(npreset >= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); + if(insertion == 0) + changepar(0, (int) (presets[npreset][0] / 1.5)); //lower the volume if this is system effect + Ppreset = npreset; cleanup(); -}; +} -void Distorsion::changepar(const int &npar,const unsigned char &value) +void Distorsion::changepar(const int &npar, const unsigned char &value) { - switch (npar) { + switch(npar) { case 0: setvolume(value); break; @@ -356,18 +404,22 @@ void Distorsion::changepar(const int &npar,const unsigned char &value) setlrcross(value); break; case 3: - Pdrive=value; + Pdrive = value; break; case 4: - Plevel=value; + Plevel = value; break; case 5: - if (value>13) Ptype=13;//this must be increased if more distorsion types are added - else Ptype=value; + if(value > 13) + Ptype = 13; //this must be increased if more distorsion types are added + else + Ptype = value; break; case 6: - if (value>1) Pnegate=1; - else Pnegate=value; + if(value > 1) + Pnegate = 1; + else + Pnegate = value; break; case 7: setlpf(value); @@ -376,52 +428,54 @@ void Distorsion::changepar(const int &npar,const unsigned char &value) sethpf(value); break; case 9: - if (value>1) Pstereo=1; - else Pstereo=value; + if(value > 1) + Pstereo = 1; + else + Pstereo = value; break; case 10: - Pprefiltering=value; + Pprefiltering = value; break; - }; -}; + } +} -unsigned char Distorsion::getpar(const int &npar)const +unsigned char Distorsion::getpar(const int &npar) const { - switch (npar) { + switch(npar) { case 0: - return(Pvolume); + return Pvolume; break; case 1: - return(Ppanning); + return Ppanning; break; case 2: - return(Plrcross); + return Plrcross; break; case 3: - return(Pdrive); + return Pdrive; break; case 4: - return(Plevel); + return Plevel; break; case 5: - return(Ptype); + return Ptype; break; case 6: - return(Pnegate); + return Pnegate; break; case 7: - return(Plpf); + return Plpf; break; case 8: - return(Phpf); + return Phpf; break; case 9: - return(Pstereo); + return Pstereo; break; case 10: - return(Pprefiltering); + return Pprefiltering; break; - }; - return(0);//in case of bogus parameter number -}; + } + return 0; //in case of bogus parameter number +} diff --git a/src/Effects/Distorsion.h b/src/Effects/Distorsion.h @@ -28,44 +28,46 @@ #include "Effect.h" //Waveshaping(called by Distorsion effect and waveshape from OscilGen) -void waveshapesmps(int n,REALTYPE *smps,unsigned char type,unsigned char drive); +void waveshapesmps(int n, + REALTYPE *smps, + unsigned char type, + unsigned char drive); /**Distortion Effect*/ class Distorsion:public Effect { -public: - Distorsion(const int &insertion,REALTYPE *efxoutl_,REALTYPE *efxoutr_); - ~Distorsion(); - void out(REALTYPE *smpsl,REALTYPE *smpr); - void setpreset(unsigned char npreset); - void changepar(const int &npar,const unsigned char &value); - unsigned char getpar(const int &npar)const; - void cleanup(); - void applyfilters(REALTYPE *efxoutl,REALTYPE *efxoutr); + public: + Distorsion(const int &insertion, REALTYPE *efxoutl_, REALTYPE *efxoutr_); + ~Distorsion(); + void out(REALTYPE *smpsl, REALTYPE *smpr); + void setpreset(unsigned char npreset); + void changepar(const int &npar, const unsigned char &value); + unsigned char getpar(const int &npar) const; + void cleanup(); + void applyfilters(REALTYPE *efxoutl, REALTYPE *efxoutr); -private: - //Parametrii - unsigned char Pvolume; //Volumul or E/R - unsigned char Ppanning;//Panning - unsigned char Plrcross;// L/R Mixing - unsigned char Pdrive; //the input amplification - unsigned char Plevel; //the output amplification - unsigned char Ptype; //Distorsion type - unsigned char Pnegate; //if the input is negated - unsigned char Plpf; //lowpass filter - unsigned char Phpf; //highpass filter - unsigned char Pstereo; //0=mono,1=stereo - unsigned char Pprefiltering;//if you want to do the filtering before the distorsion + private: + //Parametrii + unsigned char Pvolume; //Volumul or E/R + unsigned char Ppanning; //Panning + unsigned char Plrcross; // L/R Mixing + unsigned char Pdrive; //the input amplification + unsigned char Plevel; //the output amplification + unsigned char Ptype; //Distorsion type + unsigned char Pnegate; //if the input is negated + unsigned char Plpf; //lowpass filter + unsigned char Phpf; //highpass filter + unsigned char Pstereo; //0=mono,1=stereo + unsigned char Pprefiltering; //if you want to do the filtering before the distorsion - void setvolume(const unsigned char &Pvolume); - void setpanning(const unsigned char &Ppanning); - void setlrcross(const unsigned char &Plrcross); - void setlpf(const unsigned char &Plpf); - void sethpf(const unsigned char &Phpf); - - //Real Parameters - REALTYPE panning,lrcross; - AnalogFilter *lpfl,*lpfr,*hpfl,*hpfr; + void setvolume(const unsigned char &Pvolume); + void setpanning(const unsigned char &Ppanning); + void setlrcross(const unsigned char &Plrcross); + void setlpf(const unsigned char &Plpf); + void sethpf(const unsigned char &Phpf); + //Real Parameters + REALTYPE panning, lrcross; + AnalogFilter *lpfl, *lpfr, *hpfl, *hpfr; }; diff --git a/src/Effects/DynamicFilter.cpp b/src/Effects/DynamicFilter.cpp @@ -23,74 +23,75 @@ #include <cmath> #include "DynamicFilter.h" -DynamicFilter::DynamicFilter(int insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_) - :Effect(insertion_,efxoutl_,efxoutr_,new FilterParams(0,64,64),0), - Pvolume(110),Ppanning(64),Pdepth(0),Pampsns(90), - Pampsnsinv(0),Pampsmooth(60), - filterl(NULL),filterr(NULL) +DynamicFilter::DynamicFilter(int insertion_, + REALTYPE *efxoutl_, + REALTYPE *efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, new FilterParams(0, 64, 64), 0), + Pvolume(110), Ppanning(64), Pdepth(0), Pampsns(90), + Pampsnsinv(0), Pampsmooth(60), + filterl(NULL), filterr(NULL) { setpreset(Ppreset); cleanup(); -}; +} DynamicFilter::~DynamicFilter() { delete filterpars; delete filterl; delete filterr; -}; +} /* * Apply the effect */ -void DynamicFilter::out(REALTYPE *smpsl,REALTYPE *smpsr) +void DynamicFilter::out(REALTYPE *smpsl, REALTYPE *smpsr) { int i; - if (filterpars->changed) { - filterpars->changed=false; + if(filterpars->changed) { + filterpars->changed = false; cleanup(); - }; + } - REALTYPE lfol,lfor; - lfo.effectlfoout(&lfol,&lfor); - lfol*=depth*5.0; - lfor*=depth*5.0; - REALTYPE freq=filterpars->getfreq(); - REALTYPE q=filterpars->getq(); + REALTYPE lfol, lfor; + lfo.effectlfoout(&lfol, &lfor); + lfol *= depth * 5.0; + lfor *= depth * 5.0; + REALTYPE freq = filterpars->getfreq(); + REALTYPE q = filterpars->getq(); - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - efxoutl[i]=smpsl[i]; - efxoutr[i]=smpsr[i]; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + efxoutl[i] = smpsl[i]; + efxoutr[i] = smpsr[i]; - REALTYPE x=(fabs(smpsl[i])+fabs(smpsr[i]))*0.5; - ms1=ms1*(1.0-ampsmooth)+x*ampsmooth+1e-10; - }; + REALTYPE x = (fabs(smpsl[i]) + fabs(smpsr[i])) * 0.5; + ms1 = ms1 * (1.0 - ampsmooth) + x * ampsmooth + 1e-10; + } - REALTYPE ampsmooth2=pow(ampsmooth,0.2)*0.3; - ms2=ms2*(1.0-ampsmooth2)+ms1*ampsmooth2; - ms3=ms3*(1.0-ampsmooth2)+ms2*ampsmooth2; - ms4=ms4*(1.0-ampsmooth2)+ms3*ampsmooth2; - REALTYPE rms=(sqrt(ms4))*ampsns; + REALTYPE ampsmooth2 = pow(ampsmooth, 0.2) * 0.3; + ms2 = ms2 * (1.0 - ampsmooth2) + ms1 * ampsmooth2; + ms3 = ms3 * (1.0 - ampsmooth2) + ms2 * ampsmooth2; + ms4 = ms4 * (1.0 - ampsmooth2) + ms3 * ampsmooth2; + REALTYPE rms = (sqrt(ms4)) * ampsns; - REALTYPE frl=filterl->getrealfreq(freq+lfol+rms); - REALTYPE frr=filterr->getrealfreq(freq+lfor+rms); + REALTYPE frl = filterl->getrealfreq(freq + lfol + rms); + REALTYPE frr = filterr->getrealfreq(freq + lfor + rms); - filterl->setfreq_and_q(frl,q); - filterr->setfreq_and_q(frr,q); + filterl->setfreq_and_q(frl, q); + filterr->setfreq_and_q(frr, q); filterl->filterout(efxoutl); filterr->filterout(efxoutr); //panning - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - efxoutl[i]*=panning; - efxoutr[i]*=(1.0-panning); - }; - -}; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + efxoutl[i] *= panning; + efxoutr[i] *= (1.0 - panning); + } +} /* * Cleanup the effect @@ -98,11 +99,11 @@ void DynamicFilter::out(REALTYPE *smpsl,REALTYPE *smpsr) void DynamicFilter::cleanup() { reinitfilter(); - ms1=0.0; - ms2=0.0; - ms3=0.0; - ms4=0.0; -}; + ms1 = 0.0; + ms2 = 0.0; + ms3 = 0.0; + ms4 = 0.0; +} /* @@ -111,159 +112,167 @@ void DynamicFilter::cleanup() void DynamicFilter::setdepth(const unsigned char &Pdepth) { - this->Pdepth=Pdepth; - depth=pow((Pdepth/127.0),2.0); -}; + this->Pdepth = Pdepth; + depth = pow((Pdepth / 127.0), 2.0); +} void DynamicFilter::setvolume(const unsigned char &Pvolume) { - this->Pvolume=Pvolume; - outvolume=Pvolume/127.0; - if (insertion==0) volume=1.0; - else volume=outvolume; -}; + this->Pvolume = Pvolume; + outvolume = Pvolume / 127.0; + if(insertion == 0) + volume = 1.0; + else + volume = outvolume; +} void DynamicFilter::setpanning(const unsigned char &Ppanning) { - this->Ppanning=Ppanning; - panning=Ppanning/127.0; -}; + this->Ppanning = Ppanning; + panning = Ppanning / 127.0; +} void DynamicFilter::setampsns(const unsigned char &Pampsns) { - ampsns=pow(Pampsns/127.0,2.5)*10.0; - if (Pampsnsinv!=0) ampsns=-ampsns; - ampsmooth=exp(-Pampsmooth/127.0*10.0)*0.99; - this->Pampsns=Pampsns; -}; + ampsns = pow(Pampsns / 127.0, 2.5) * 10.0; + if(Pampsnsinv != 0) + ampsns = -ampsns; + ampsmooth = exp(-Pampsmooth / 127.0 * 10.0) * 0.99; + this->Pampsns = Pampsns; +} void DynamicFilter::reinitfilter() { - if (filterl!=NULL) delete(filterl); - if (filterr!=NULL) delete(filterr); - filterl=new Filter(filterpars); - filterr=new Filter(filterpars); -}; + if(filterl != NULL) + delete (filterl); + if(filterr != NULL) + delete (filterr); + filterl = new Filter(filterpars); + filterr = new Filter(filterpars); +} void DynamicFilter::setpreset(unsigned char npreset) { - const int PRESET_SIZE=10; - const int NUM_PRESETS=5; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + const int PRESET_SIZE = 10; + const int NUM_PRESETS = 5; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { //WahWah - {110,64,80,0,0,64,0,90,0,60}, + {110, 64, 80, 0, 0, 64, 0, 90, 0, 60}, //AutoWah - {110,64,70,0,0,80,70,0,0,60}, + {110, 64, 70, 0, 0, 80, 70, 0, 0, 60}, //Sweep - {100,64,30,0,0,50,80,0,0,60}, + {100, 64, 30, 0, 0, 50, 80, 0, 0, 60}, //VocalMorph1 - {110,64,80,0,0,64,0,64,0,60}, + {110, 64, 80, 0, 0, 64, 0, 64, 0, 60}, //VocalMorph1 - {127,64,50,0,0,96,64,0,0,60} + {127, 64, 50, 0, 0, 96, 64, 0, 0, 60} }; - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n<PRESET_SIZE;n++) changepar(n,presets[npreset][n]); + if(npreset >= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); filterpars->defaults(); - switch (npreset) { + switch(npreset) { case 0: - filterpars->Pcategory=0; - filterpars->Ptype=2; - filterpars->Pfreq=45; - filterpars->Pq=64; - filterpars->Pstages=1; - filterpars->Pgain=64; + filterpars->Pcategory = 0; + filterpars->Ptype = 2; + filterpars->Pfreq = 45; + filterpars->Pq = 64; + filterpars->Pstages = 1; + filterpars->Pgain = 64; break; case 1: - filterpars->Pcategory=2; - filterpars->Ptype=0; - filterpars->Pfreq=72; - filterpars->Pq=64; - filterpars->Pstages=0; - filterpars->Pgain=64; + filterpars->Pcategory = 2; + filterpars->Ptype = 0; + filterpars->Pfreq = 72; + filterpars->Pq = 64; + filterpars->Pstages = 0; + filterpars->Pgain = 64; break; case 2: - filterpars->Pcategory=0; - filterpars->Ptype=4; - filterpars->Pfreq=64; - filterpars->Pq=64; - filterpars->Pstages=2; - filterpars->Pgain=64; + filterpars->Pcategory = 0; + filterpars->Ptype = 4; + filterpars->Pfreq = 64; + filterpars->Pq = 64; + filterpars->Pstages = 2; + filterpars->Pgain = 64; break; case 3: - filterpars->Pcategory=1; - filterpars->Ptype=0; - filterpars->Pfreq=50; - filterpars->Pq=70; - filterpars->Pstages=1; - filterpars->Pgain=64; - - filterpars->Psequencesize=2; + filterpars->Pcategory = 1; + filterpars->Ptype = 0; + filterpars->Pfreq = 50; + filterpars->Pq = 70; + filterpars->Pstages = 1; + filterpars->Pgain = 64; + + filterpars->Psequencesize = 2; // "I" - filterpars->Pvowels[0].formants[0].freq=34; - filterpars->Pvowels[0].formants[0].amp=127; - filterpars->Pvowels[0].formants[0].q=64; - filterpars->Pvowels[0].formants[1].freq=99; - filterpars->Pvowels[0].formants[1].amp=122; - filterpars->Pvowels[0].formants[1].q=64; - filterpars->Pvowels[0].formants[2].freq=108; - filterpars->Pvowels[0].formants[2].amp=112; - filterpars->Pvowels[0].formants[2].q=64; + filterpars->Pvowels[0].formants[0].freq = 34; + filterpars->Pvowels[0].formants[0].amp = 127; + filterpars->Pvowels[0].formants[0].q = 64; + filterpars->Pvowels[0].formants[1].freq = 99; + filterpars->Pvowels[0].formants[1].amp = 122; + filterpars->Pvowels[0].formants[1].q = 64; + filterpars->Pvowels[0].formants[2].freq = 108; + filterpars->Pvowels[0].formants[2].amp = 112; + filterpars->Pvowels[0].formants[2].q = 64; // "A" - filterpars->Pvowels[1].formants[0].freq=61; - filterpars->Pvowels[1].formants[0].amp=127; - filterpars->Pvowels[1].formants[0].q=64; - filterpars->Pvowels[1].formants[1].freq=71; - filterpars->Pvowels[1].formants[1].amp=121; - filterpars->Pvowels[1].formants[1].q=64; - filterpars->Pvowels[1].formants[2].freq=99; - filterpars->Pvowels[1].formants[2].amp=117; - filterpars->Pvowels[1].formants[2].q=64; + filterpars->Pvowels[1].formants[0].freq = 61; + filterpars->Pvowels[1].formants[0].amp = 127; + filterpars->Pvowels[1].formants[0].q = 64; + filterpars->Pvowels[1].formants[1].freq = 71; + filterpars->Pvowels[1].formants[1].amp = 121; + filterpars->Pvowels[1].formants[1].q = 64; + filterpars->Pvowels[1].formants[2].freq = 99; + filterpars->Pvowels[1].formants[2].amp = 117; + filterpars->Pvowels[1].formants[2].q = 64; break; case 4: - filterpars->Pcategory=1; - filterpars->Ptype=0; - filterpars->Pfreq=64; - filterpars->Pq=70; - filterpars->Pstages=1; - filterpars->Pgain=64; - - filterpars->Psequencesize=2; - filterpars->Pnumformants=2; - filterpars->Pvowelclearness=0; - - filterpars->Pvowels[0].formants[0].freq=70; - filterpars->Pvowels[0].formants[0].amp=127; - filterpars->Pvowels[0].formants[0].q=64; - filterpars->Pvowels[0].formants[1].freq=80; - filterpars->Pvowels[0].formants[1].amp=122; - filterpars->Pvowels[0].formants[1].q=64; - - filterpars->Pvowels[1].formants[0].freq=20; - filterpars->Pvowels[1].formants[0].amp=127; - filterpars->Pvowels[1].formants[0].q=64; - filterpars->Pvowels[1].formants[1].freq=100; - filterpars->Pvowels[1].formants[1].amp=121; - filterpars->Pvowels[1].formants[1].q=64; + filterpars->Pcategory = 1; + filterpars->Ptype = 0; + filterpars->Pfreq = 64; + filterpars->Pq = 70; + filterpars->Pstages = 1; + filterpars->Pgain = 64; + + filterpars->Psequencesize = 2; + filterpars->Pnumformants = 2; + filterpars->Pvowelclearness = 0; + + filterpars->Pvowels[0].formants[0].freq = 70; + filterpars->Pvowels[0].formants[0].amp = 127; + filterpars->Pvowels[0].formants[0].q = 64; + filterpars->Pvowels[0].formants[1].freq = 80; + filterpars->Pvowels[0].formants[1].amp = 122; + filterpars->Pvowels[0].formants[1].q = 64; + + filterpars->Pvowels[1].formants[0].freq = 20; + filterpars->Pvowels[1].formants[0].amp = 127; + filterpars->Pvowels[1].formants[0].q = 64; + filterpars->Pvowels[1].formants[1].freq = 100; + filterpars->Pvowels[1].formants[1].amp = 121; + filterpars->Pvowels[1].formants[1].q = 64; break; - }; + } // for (int i=0;i<5;i++){ // printf("freq=%d amp=%d q=%d\n",filterpars->Pvowels[0].formants[i].freq,filterpars->Pvowels[0].formants[i].amp,filterpars->Pvowels[0].formants[i].q); // }; - if (insertion==0) changepar(0,presets[npreset][0]/2);//lower the volume if this is system effect - Ppreset=npreset; + if(insertion == 0) + changepar(0, presets[npreset][0] / 2); //lower the volume if this is system effect + Ppreset = npreset; reinitfilter(); -}; +} -void DynamicFilter::changepar(const int &npar,const unsigned char &value) +void DynamicFilter::changepar(const int &npar, const unsigned char &value) { - switch (npar) { + switch(npar) { case 0: setvolume(value); break; @@ -271,19 +280,19 @@ void DynamicFilter::changepar(const int &npar,const unsigned char &value) setpanning(value); break; case 2: - lfo.Pfreq=value; + lfo.Pfreq = value; lfo.updateparams(); break; case 3: - lfo.Prandomness=value; + lfo.Prandomness = value; lfo.updateparams(); break; case 4: - lfo.PLFOtype=value; + lfo.PLFOtype = value; lfo.updateparams(); break; case 5: - lfo.Pstereo=value; + lfo.Pstereo = value; lfo.updateparams(); break; case 6: @@ -293,52 +302,51 @@ void DynamicFilter::changepar(const int &npar,const unsigned char &value) setampsns(value); break; case 8: - Pampsnsinv=value; + Pampsnsinv = value; setampsns(Pampsns); break; case 9: - Pampsmooth=value; + Pampsmooth = value; setampsns(Pampsns); break; - }; -}; + } +} -unsigned char DynamicFilter::getpar(const int &npar)const +unsigned char DynamicFilter::getpar(const int &npar) const { - switch (npar) { + switch(npar) { case 0: - return(Pvolume); + return Pvolume; break; case 1: - return(Ppanning); + return Ppanning; break; case 2: - return(lfo.Pfreq); + return lfo.Pfreq; break; case 3: - return(lfo.Prandomness); + return lfo.Prandomness; break; case 4: - return(lfo.PLFOtype); + return lfo.PLFOtype; break; case 5: - return(lfo.Pstereo); + return lfo.Pstereo; break; case 6: - return(Pdepth); + return Pdepth; break; case 7: - return(Pampsns); + return Pampsns; break; case 8: - return(Pampsnsinv); + return Pampsnsinv; break; case 9: - return(Pampsmooth); + return Pampsmooth; break; default: - return (0); - }; - -}; + return 0; + } +} diff --git a/src/Effects/DynamicFilter.h b/src/Effects/DynamicFilter.h @@ -30,42 +30,42 @@ /**DynamicFilter Effect*/ class DynamicFilter:public Effect { -public: - DynamicFilter(int insetion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); - ~DynamicFilter(); - void out(REALTYPE *smpsl,REALTYPE *smpsr); + public: + DynamicFilter(int insetion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_); + ~DynamicFilter(); + void out(REALTYPE *smpsl, REALTYPE *smpsr); - void setpreset(unsigned char npreset); - void changepar(const int &npar,const unsigned char &value); - unsigned char getpar(const int &npar)const; - void cleanup(); + void setpreset(unsigned char npreset); + void changepar(const int &npar, const unsigned char &value); + unsigned char getpar(const int &npar) const; + void cleanup(); // void setdryonly(); -private: - //Parametrii DynamicFilter - EffectLFO lfo;//lfo-ul DynamicFilter - unsigned char Pvolume; - unsigned char Ppanning; - unsigned char Pdepth;/**<the depth of the lfo of the DynamicFilter*/ - unsigned char Pampsns;/**<how the filter varies according to the input amplitude*/ - unsigned char Pampsnsinv;//if the filter freq is lowered if the input amplitude rises - unsigned char Pampsmooth;//how smooth the input amplitude changes the filter + private: + //Parametrii DynamicFilter + EffectLFO lfo; //lfo-ul DynamicFilter + unsigned char Pvolume; + unsigned char Ppanning; + unsigned char Pdepth; /**<the depth of the lfo of the DynamicFilter*/ + unsigned char Pampsns; /**<how the filter varies according to the input amplitude*/ + unsigned char Pampsnsinv; //if the filter freq is lowered if the input amplitude rises + unsigned char Pampsmooth; //how smooth the input amplitude changes the filter - //Parameter Control - void setvolume(const unsigned char &Pvolume); - void setpanning(const unsigned char &Ppanning); - void setdepth(const unsigned char &Pdepth); - void setampsns(const unsigned char &Pampsns); + //Parameter Control + void setvolume(const unsigned char &Pvolume); + void setpanning(const unsigned char &Ppanning); + void setdepth(const unsigned char &Pdepth); + void setampsns(const unsigned char &Pampsns); - void reinitfilter(); + void reinitfilter(); - //Internal Values - REALTYPE panning,depth,ampsns,ampsmooth; + //Internal Values + REALTYPE panning, depth, ampsns, ampsmooth; - Filter *filterl,*filterr; + Filter *filterl, *filterr; - REALTYPE ms1,ms2,ms3,ms4;//mean squares + REALTYPE ms1, ms2, ms3, ms4; //mean squares }; #endif diff --git a/src/Effects/EQ.cpp b/src/Effects/EQ.cpp @@ -23,60 +23,59 @@ #include <cmath> #include "EQ.h" -EQ::EQ(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_) - :Effect(insertion_,efxoutl_,efxoutr_,NULL,0) +EQ::EQ(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0) { - - for (int i=0;i<MAX_EQ_BANDS;i++) { - filter[i].Ptype=0; - filter[i].Pfreq=64; - filter[i].Pgain=64; - filter[i].Pq=64; - filter[i].Pstages=0; - filter[i].l=new AnalogFilter(6,1000.0,1.0,0); - filter[i].r=new AnalogFilter(6,1000.0,1.0,0); - }; + for(int i = 0; i < MAX_EQ_BANDS; i++) { + filter[i].Ptype = 0; + filter[i].Pfreq = 64; + filter[i].Pgain = 64; + filter[i].Pq = 64; + filter[i].Pstages = 0; + filter[i].l = new AnalogFilter(6, 1000.0, 1.0, 0); + filter[i].r = new AnalogFilter(6, 1000.0, 1.0, 0); + } //default values - Pvolume=50; + Pvolume = 50; setpreset(Ppreset); cleanup(); -}; +} EQ::~EQ() -{ -}; +{} /* * Cleanup the effect */ void EQ::cleanup() { - for (int i=0;i<MAX_EQ_BANDS;i++) { + for(int i = 0; i < MAX_EQ_BANDS; i++) { filter[i].l->cleanup(); filter[i].r->cleanup(); - }; -}; + } +} /* * Effect output */ -void EQ::out(REALTYPE *smpsl,REALTYPE *smpsr) +void EQ::out(REALTYPE *smpsl, REALTYPE *smpsr) { int i; - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - efxoutl[i]=smpsl[i]*volume; - efxoutr[i]=smpsr[i]*volume; - }; - - for (i=0;i<MAX_EQ_BANDS;i++) { - if (filter[i].Ptype==0) continue; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + efxoutl[i] = smpsl[i] * volume; + efxoutr[i] = smpsr[i] * volume; + } + + for(i = 0; i < MAX_EQ_BANDS; i++) { + if(filter[i].Ptype == 0) + continue; filter[i].l->filterout(efxoutl); filter[i].r->filterout(efxoutr); - }; -}; + } +} /* @@ -84,131 +83,138 @@ void EQ::out(REALTYPE *smpsl,REALTYPE *smpsr) */ void EQ::setvolume(const unsigned char &Pvolume) { - this->Pvolume=Pvolume; - - outvolume=pow(0.005,(1.0-Pvolume/127.0))*10.0; - if (insertion==0) { - volume=1.0; - } else { - volume=outvolume; - }; + this->Pvolume = Pvolume; -}; + outvolume = pow(0.005, (1.0 - Pvolume / 127.0)) * 10.0; + if(insertion == 0) + volume = 1.0; + else + volume = outvolume; + ; +} void EQ::setpreset(unsigned char npreset) { - const int PRESET_SIZE=1; - const int NUM_PRESETS=2; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + const int PRESET_SIZE = 1; + const int NUM_PRESETS = 2; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { //EQ 1 {67}, //EQ 2 {67} }; - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n<PRESET_SIZE;n++) changepar(n,presets[npreset][n]); - Ppreset=npreset; -}; + if(npreset >= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); + Ppreset = npreset; +} -void EQ::changepar(const int &npar,const unsigned char &value) +void EQ::changepar(const int &npar, const unsigned char &value) { - switch (npar) { + switch(npar) { case 0: setvolume(value); break; - }; - if (npar<10) return; + } + if(npar < 10) + return; - int nb=(npar-10)/5;//number of the band (filter) - if (nb>=MAX_EQ_BANDS) return; - int bp=npar%5;//band paramenter + int nb = (npar - 10) / 5; //number of the band (filter) + if(nb >= MAX_EQ_BANDS) + return; + int bp = npar % 5; //band paramenter REALTYPE tmp; - switch (bp) { + switch(bp) { case 0: - filter[nb].Ptype=value; - if (value>9) filter[nb].Ptype=0;//has to be changed if more filters will be added - if (filter[nb].Ptype!=0) { - filter[nb].l->settype(value-1); - filter[nb].r->settype(value-1); - }; + filter[nb].Ptype = value; + if(value > 9) + filter[nb].Ptype = 0; //has to be changed if more filters will be added + if(filter[nb].Ptype != 0) { + filter[nb].l->settype(value - 1); + filter[nb].r->settype(value - 1); + } break; case 1: - filter[nb].Pfreq=value; - tmp=600.0*pow(30.0,(value-64.0)/64.0); + filter[nb].Pfreq = value; + tmp = 600.0 * pow(30.0, (value - 64.0) / 64.0); filter[nb].l->setfreq(tmp); filter[nb].r->setfreq(tmp); break; case 2: - filter[nb].Pgain=value; - tmp=30.0*(value-64.0)/64.0; + filter[nb].Pgain = value; + tmp = 30.0 * (value - 64.0) / 64.0; filter[nb].l->setgain(tmp); filter[nb].r->setgain(tmp); break; case 3: - filter[nb].Pq=value; - tmp=pow(30.0,(value-64.0)/64.0); + filter[nb].Pq = value; + tmp = pow(30.0, (value - 64.0) / 64.0); filter[nb].l->setq(tmp); filter[nb].r->setq(tmp); break; case 4: - filter[nb].Pstages=value; - if (value>=MAX_FILTER_STAGES) filter[nb].Pstages=MAX_FILTER_STAGES-1; + filter[nb].Pstages = value; + if(value >= MAX_FILTER_STAGES) + filter[nb].Pstages = MAX_FILTER_STAGES - 1; filter[nb].l->setstages(value); filter[nb].r->setstages(value); break; - }; -}; + } +} -unsigned char EQ::getpar(const int &npar)const +unsigned char EQ::getpar(const int &npar) const { - switch (npar) { + switch(npar) { case 0: - return(Pvolume); + return Pvolume; break; - }; + } - if (npar<10) return(0); + if(npar < 10) + return 0; - int nb=(npar-10)/5;//number of the band (filter) - if (nb>=MAX_EQ_BANDS) return(0); - int bp=npar%5;//band paramenter - switch (bp) { + int nb = (npar - 10) / 5; //number of the band (filter) + if(nb >= MAX_EQ_BANDS) + return 0; + int bp = npar % 5; //band paramenter + switch(bp) { case 0: - return(filter[nb].Ptype); + return filter[nb].Ptype; break; case 1: - return(filter[nb].Pfreq); + return filter[nb].Pfreq; break; case 2: - return(filter[nb].Pgain); + return filter[nb].Pgain; break; case 3: - return(filter[nb].Pq); + return filter[nb].Pq; break; case 4: - return(filter[nb].Pstages); + return filter[nb].Pstages; break; - }; + } - return(0);//in case of bogus parameter number -}; + return 0; //in case of bogus parameter number +} REALTYPE EQ::getfreqresponse(REALTYPE freq) { - REALTYPE resp=1.0; - - for (int i=0;i<MAX_EQ_BANDS;i++) { - if (filter[i].Ptype==0) continue; - resp*=filter[i].l->H(freq); - }; - return(rap2dB(resp*outvolume)); -}; - + REALTYPE resp = 1.0; + + for(int i = 0; i < MAX_EQ_BANDS; i++) { + if(filter[i].Ptype == 0) + continue; + resp *= filter[i].l->H(freq); + } + return rap2dB(resp * outvolume); +} diff --git a/src/Effects/EQ.h b/src/Effects/EQ.h @@ -30,31 +30,29 @@ /**EQ Effect*/ class EQ:public Effect { -public: - EQ(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); - ~EQ(); - void out(REALTYPE *smpsl,REALTYPE *smpr); - void setpreset(unsigned char npreset); - void changepar(const int &npar,const unsigned char &value); - unsigned char getpar(const int &npar)const; - void cleanup(); - REALTYPE getfreqresponse(REALTYPE freq); -private: - //Parameters - unsigned char Pvolume;/**<Volume*/ - - void setvolume(const unsigned char &Pvolume); - - struct { - //parameters - unsigned char Ptype,Pfreq,Pgain,Pq,Pstages; - //internal values - AnalogFilter *l,*r; - }filter[MAX_EQ_BANDS]; - + public: + EQ(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_); + ~EQ(); + void out(REALTYPE *smpsl, REALTYPE *smpr); + void setpreset(unsigned char npreset); + void changepar(const int &npar, const unsigned char &value); + unsigned char getpar(const int &npar) const; + void cleanup(); + REALTYPE getfreqresponse(REALTYPE freq); + private: + //Parameters + unsigned char Pvolume; /**<Volume*/ + + void setvolume(const unsigned char &Pvolume); + + struct { + //parameters + unsigned char Ptype, Pfreq, Pgain, Pq, Pstages; + //internal values + AnalogFilter *l, *r; + } filter[MAX_EQ_BANDS]; }; #endif - diff --git a/src/Effects/Echo.cpp b/src/Effects/Echo.cpp @@ -24,11 +24,13 @@ #include <iostream> #include "Echo.h" -Echo::Echo(const int & insertion_,REALTYPE *const efxoutl_,REALTYPE *const efxoutr_) - : Effect(insertion_,efxoutl_,efxoutr_,NULL,0), - Pvolume(50),Ppanning(64),//Pdelay(60), - Plrdelay(100),Plrcross(100),Pfb(40),Phidamp(60), - lrdelay(0),delaySample(1),old(0.0) +Echo::Echo(const int &insertion_, + REALTYPE *const efxoutl_, + REALTYPE *const efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0), + Pvolume(50), Ppanning(64), //Pdelay(60), + Plrdelay(100), Plrcross(100), Pfb(40), Phidamp(60), + lrdelay(0), delaySample(1), old(0.0) { setpreset(Ppreset); } @@ -42,7 +44,7 @@ void Echo::cleanup() { delaySample.l().clear(); delaySample.r().clear(); - old=Stereo<REALTYPE>(0.0); + old = Stereo<REALTYPE>(0.0); } @@ -52,85 +54,91 @@ void Echo::cleanup() void Echo::initdelays() { /**\todo make this adjust insted of destroy old delays*/ - kl=0; - kr=0; - dl=(int)(1+delay.getiVal()*SAMPLE_RATE-lrdelay); - if (dl<1) dl=1; - dr=(int)(1+delay.getiVal()*SAMPLE_RATE+lrdelay); - if (dr<1) dr=1; - - delaySample.l()=AuSample(dl); - delaySample.r()=AuSample(dr); - - old=Stereo<REALTYPE>(0.0); + kl = 0; + kr = 0; + dl = (int)(1 + delay.getiVal() * SAMPLE_RATE - lrdelay); + if(dl < 1) + dl = 1; + dr = (int)(1 + delay.getiVal() * SAMPLE_RATE + lrdelay); + if(dr < 1) + dr = 1; + + delaySample.l() = AuSample(dl); + delaySample.r() = AuSample(dr); + + old = Stereo<REALTYPE>(0.0); } /* * Effect output */ -void Echo::out(REALTYPE *const smpsl,REALTYPE *const smpsr) +void Echo::out(REALTYPE *const smpsl, REALTYPE *const smpsr) { - Stereo<AuSample> input(AuSample(SOUND_BUFFER_SIZE,smpsl),AuSample(SOUND_BUFFER_SIZE,smpsr)); + Stereo<AuSample> input(AuSample(SOUND_BUFFER_SIZE, smpsl), AuSample( + SOUND_BUFFER_SIZE, + smpsr)); out(input); } void Echo::out(const Stereo<AuSample> &input) { //void Echo::out(const Stereo<AuSample> & input){ //ideal - REALTYPE l,r,ldl,rdl;/**\todo move l+r->? ldl+rdl->?*/ + REALTYPE l, r, ldl, rdl; /**\todo move l+r->? ldl+rdl->?*/ - for (int i=0;i<input.l().size();i++) { - ldl=delaySample.l()[kl]; - rdl=delaySample.r()[kr]; - l=ldl*(1.0-lrcross)+rdl*lrcross; - r=rdl*(1.0-lrcross)+ldl*lrcross; - ldl=l; - rdl=r; + for(int i = 0; i < input.l().size(); i++) { + ldl = delaySample.l()[kl]; + rdl = delaySample.r()[kr]; + l = ldl * (1.0 - lrcross) + rdl * lrcross; + r = rdl * (1.0 - lrcross) + ldl * lrcross; + ldl = l; + rdl = r; - efxoutl[i]=ldl*2.0; - efxoutr[i]=rdl*2.0; + efxoutl[i] = ldl * 2.0; + efxoutr[i] = rdl * 2.0; - ldl=input.l()[i]*panning-ldl*fb; - rdl=input.r()[i]*(1.0-panning)-rdl*fb; + ldl = input.l()[i] * panning - ldl * fb; + rdl = input.r()[i] * (1.0 - panning) - rdl * fb; //LowPass Filter - delaySample.l()[kl]=ldl=ldl*hidamp+old.l()*(1.0-hidamp); - delaySample.r()[kr]=rdl=rdl*hidamp+old.r()*(1.0-hidamp); - old.l()=ldl; - old.r()=rdl; - - if (++kl>=dl) kl=0; - if (++kr>=dr) kr=0; - }; - + delaySample.l()[kl] = ldl = ldl * hidamp + old.l() * (1.0 - hidamp); + delaySample.r()[kr] = rdl = rdl * hidamp + old.r() * (1.0 - hidamp); + old.l() = ldl; + old.r() = rdl; + + if(++kl >= dl) + kl = 0; + if(++kr >= dr) + kr = 0; + } } /* * Parameter control */ -void Echo::setvolume(const unsigned char & Pvolume) +void Echo::setvolume(const unsigned char &Pvolume) { - this->Pvolume=Pvolume; - - if (insertion==0) { - outvolume=pow(0.01,(1.0-Pvolume/127.0))*4.0; - volume=1.0; - } else { - volume=outvolume=Pvolume/127.0; - }; - if (Pvolume==0) cleanup(); - + this->Pvolume = Pvolume; + + if(insertion == 0) { + outvolume = pow(0.01, (1.0 - Pvolume / 127.0)) * 4.0; + volume = 1.0; + } + else + volume = outvolume = Pvolume / 127.0; + ; + if(Pvolume == 0) + cleanup(); } -void Echo::setpanning(const unsigned char & Ppanning) +void Echo::setpanning(const unsigned char &Ppanning) { - this->Ppanning=Ppanning; - panning=(Ppanning+0.5)/127.0; + this->Ppanning = Ppanning; + panning = (Ppanning + 0.5) / 127.0; } -void Echo::setdelay(const unsigned char & Pdelay) +void Echo::setdelay(const unsigned char &Pdelay) { delay.setmVal(Pdelay); //this->Pdelay=Pdelay; @@ -138,71 +146,76 @@ void Echo::setdelay(const unsigned char & Pdelay) initdelays(); } -void Echo::setlrdelay(const unsigned char & Plrdelay) +void Echo::setlrdelay(const unsigned char &Plrdelay) { REALTYPE tmp; - this->Plrdelay=Plrdelay; - tmp=(pow(2,fabs(Plrdelay-64.0)/64.0*9)-1.0)/1000.0*SAMPLE_RATE; - if (Plrdelay<64.0) tmp=-tmp; - lrdelay=(int) tmp; + this->Plrdelay = Plrdelay; + tmp = + (pow(2, fabs(Plrdelay - 64.0) / 64.0 * 9) - 1.0) / 1000.0 * SAMPLE_RATE; + if(Plrdelay < 64.0) + tmp = -tmp; + lrdelay = (int) tmp; initdelays(); } -void Echo::setlrcross(const unsigned char & Plrcross) +void Echo::setlrcross(const unsigned char &Plrcross) { - this->Plrcross=Plrcross; - lrcross=Plrcross/127.0*1.0; + this->Plrcross = Plrcross; + lrcross = Plrcross / 127.0 * 1.0; } -void Echo::setfb(const unsigned char & Pfb) +void Echo::setfb(const unsigned char &Pfb) { - this->Pfb=Pfb; - fb=Pfb/128.0; + this->Pfb = Pfb; + fb = Pfb / 128.0; } -void Echo::sethidamp(const unsigned char & Phidamp) +void Echo::sethidamp(const unsigned char &Phidamp) { - this->Phidamp=Phidamp; - hidamp=1.0-Phidamp/127.0; + this->Phidamp = Phidamp; + hidamp = 1.0 - Phidamp / 127.0; } void Echo::setpreset(unsigned char npreset) { /**\todo see if the preset array can be replaced with a struct or a class*/ - const int PRESET_SIZE=7; - const int NUM_PRESETS=9; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + const int PRESET_SIZE = 7; + const int NUM_PRESETS = 9; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { //Echo 1 - {67,64,35,64,30,59,0}, + {67, 64, 35, 64, 30, 59, 0 }, //Echo 2 - {67,64,21,64,30,59,0}, + {67, 64, 21, 64, 30, 59, 0 }, //Echo 3 - {67,75,60,64,30,59,10}, + {67, 75, 60, 64, 30, 59, 10 }, //Simple Echo - {67,60,44,64,30,0,0}, + {67, 60, 44, 64, 30, 0, 0 }, //Canyon - {67,60,102,50,30,82,48}, + {67, 60, 102, 50, 30, 82, 48 }, //Panning Echo 1 - {67,64,44,17,0,82,24}, + {67, 64, 44, 17, 0, 82, 24 }, //Panning Echo 2 - {81,60,46,118,100,68,18}, + {81, 60, 46, 118, 100, 68, 18 }, //Panning Echo 3 - {81,60,26,100,127,67,36}, + {81, 60, 26, 100, 127, 67, 36 }, //Feedback Echo - {62,64,28,64,100,90,55} + {62, 64, 28, 64, 100, 90, 55 } }; - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n<PRESET_SIZE;n++) changepar(n,presets[npreset][n]); - if (insertion) setvolume(presets[npreset][0]/2);//lower the volume if this is insertion effect - Ppreset=npreset; + if(npreset >= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); + if(insertion) + setvolume(presets[npreset][0] / 2); //lower the volume if this is insertion effect + Ppreset = npreset; } -void Echo::changepar(const int & npar,const unsigned char & value) +void Echo::changepar(const int &npar, const unsigned char &value) { - switch (npar) { + switch(npar) { case 0: setvolume(value); break; @@ -224,34 +237,34 @@ void Echo::changepar(const int & npar,const unsigned char & value) case 6: sethidamp(value); break; - }; + } } -unsigned char Echo::getpar(const int & npar)const +unsigned char Echo::getpar(const int &npar) const { - switch (npar) { + switch(npar) { case 0: - return(Pvolume); + return Pvolume; break; case 1: - return(Ppanning); + return Ppanning; break; case 2: - return(delay.getmVal()); + return delay.getmVal(); break; case 3: - return(Plrdelay); + return Plrdelay; break; case 4: - return(Plrcross); + return Plrcross; break; case 5: - return(Pfb); + return Pfb; break; case 6: - return(Phidamp); + return Phidamp; break; - }; - return(0);// in case of bogus parameter number + } + return 0; // in case of bogus parameter number } diff --git a/src/Effects/Echo.h b/src/Effects/Echo.h @@ -32,105 +32,107 @@ /**Echo Effect*/ class Echo:public Effect { -public: - - /** - * The Constructor For Echo - * @param insertion_ integer to determine if Echo is an insertion effect - * or not - * @param efxoutl_ Effect out Left Channel - * @param efxoutr_ Effect out Right Channel - * @return An initialized Echo Object - */ - Echo(const int & insertion_,REALTYPE *const efxoutl_,REALTYPE *const efxoutr_); - - /** - * The destructor - */ - ~Echo(); - - /** - * Outputs the echo to efxoutl and efxoutr - * @param smpsl Sample from Left channel - * @param smpsr Sample from Right channel - * \todo try to figure out if smpsl should be const *const - * or not (It should be) - */ - void out(REALTYPE *const smpsl,REALTYPE *const smpr); - void out(const Stereo<AuSample> &input); - - /** - * Sets the state of Echo to the specified preset - * @param npreset number of chosen preset - */ - void setpreset(unsigned char npreset); - - /** - * Sets the value of the chosen variable - * - * The possible parameters are: - * -# Volume - * -# Panning - * -# Delay - * -# L/R Delay - * -# L/R Crossover - * -# Feedback - * -# Dampening - * @param npar number of chosen parameter - * @param value the new value - */ - void changepar(const int & npar,const unsigned char & value); - - /** - * Gets the specified parameter - * - * The possible parameters are - * -# Volume - * -# Panning - * -# Delay - * -# L/R Delay - * -# L/R Crossover - * -# Feedback - * -# Dampening - * @param npar number of chosen parameter - * @return value of parameter - */ - unsigned char getpar(const int & npar)const; - - int getnumparams(); - - /**Zeros out the state of the Echo*/ - void cleanup(); - - /**\todo This function needs to be implemented or the prototype should be removed*/ - void setdryonly(); -private: - //Parameters - char Pvolume;/**<#1 Volume or Dry/Wetness*/ - char Ppanning;/**<#2 Panning*/ - DelayCtl delay;/**<#3 Delay of the Echo*/ - char Plrdelay;/**<#4 L/R delay difference*/ - char Plrcross;/**<#5 L/R Mixing*/ - char Pfb;/**<#6Feedback*/ - char Phidamp;/**<#7Dampening of the Echo*/ - - void setvolume(const unsigned char & Pvolume); - void setpanning(const unsigned char & Ppanning); - void setdelay(const unsigned char & Pdelay); - void setlrdelay(const unsigned char & Plrdelay); - void setlrcross(const unsigned char & Plrcross); - void setfb(const unsigned char & Pfb); - void sethidamp(const unsigned char & Phidamp); - - //Real Parameters - REALTYPE panning,lrcross,fb,hidamp; //needs better names - int dl,dr,lrdelay; //needs better names - - void initdelays(); - Stereo<AuSample> delaySample; - Stereo<REALTYPE> old; - - int kl,kr; + public: + + /** + * The Constructor For Echo + * @param insertion_ integer to determine if Echo is an insertion effect + * or not + * @param efxoutl_ Effect out Left Channel + * @param efxoutr_ Effect out Right Channel + * @return An initialized Echo Object + */ + Echo(const int &insertion_, + REALTYPE *const efxoutl_, + REALTYPE *const efxoutr_); + + /** + * The destructor + */ + ~Echo(); + + /** + * Outputs the echo to efxoutl and efxoutr + * @param smpsl Sample from Left channel + * @param smpsr Sample from Right channel + * \todo try to figure out if smpsl should be const *const + * or not (It should be) + */ + void out(REALTYPE *const smpsl, REALTYPE *const smpr); + void out(const Stereo<AuSample> &input); + + /** + * Sets the state of Echo to the specified preset + * @param npreset number of chosen preset + */ + void setpreset(unsigned char npreset); + + /** + * Sets the value of the chosen variable + * + * The possible parameters are: + * -# Volume + * -# Panning + * -# Delay + * -# L/R Delay + * -# L/R Crossover + * -# Feedback + * -# Dampening + * @param npar number of chosen parameter + * @param value the new value + */ + void changepar(const int &npar, const unsigned char &value); + + /** + * Gets the specified parameter + * + * The possible parameters are + * -# Volume + * -# Panning + * -# Delay + * -# L/R Delay + * -# L/R Crossover + * -# Feedback + * -# Dampening + * @param npar number of chosen parameter + * @return value of parameter + */ + unsigned char getpar(const int &npar) const; + + int getnumparams(); + + /**Zeros out the state of the Echo*/ + void cleanup(); + + /**\todo This function needs to be implemented or the prototype should be removed*/ + void setdryonly(); + private: + //Parameters + char Pvolume; /**<#1 Volume or Dry/Wetness*/ + char Ppanning; /**<#2 Panning*/ + DelayCtl delay; /**<#3 Delay of the Echo*/ + char Plrdelay; /**<#4 L/R delay difference*/ + char Plrcross; /**<#5 L/R Mixing*/ + char Pfb; /**<#6Feedback*/ + char Phidamp; /**<#7Dampening of the Echo*/ + + void setvolume(const unsigned char &Pvolume); + void setpanning(const unsigned char &Ppanning); + void setdelay(const unsigned char &Pdelay); + void setlrdelay(const unsigned char &Plrdelay); + void setlrcross(const unsigned char &Plrcross); + void setfb(const unsigned char &Pfb); + void sethidamp(const unsigned char &Phidamp); + + //Real Parameters + REALTYPE panning, lrcross, fb, hidamp; //needs better names + int dl, dr, lrdelay; //needs better names + + void initdelays(); + Stereo<AuSample> delaySample; + Stereo<REALTYPE> old; + + int kl, kr; }; #endif diff --git a/src/Effects/Effect.cpp b/src/Effects/Effect.cpp @@ -23,8 +23,9 @@ #include "Effect.h" -Effect::Effect(bool insertion_,REALTYPE *const efxoutl_, - REALTYPE *const efxoutr_,FilterParams *filterpars_, - const unsigned char & Ppreset_) - :Ppreset(Ppreset_),efxoutl(efxoutl_),efxoutr(efxoutr_), - filterpars(filterpars_),insertion(insertion_) {} +Effect::Effect(bool insertion_, REALTYPE *const efxoutl_, + REALTYPE *const efxoutr_, FilterParams *filterpars_, + const unsigned char &Ppreset_) + :Ppreset(Ppreset_), efxoutl(efxoutl_), efxoutr(efxoutr_), + filterpars(filterpars_), insertion(insertion_) {} + diff --git a/src/Effects/Effect.h b/src/Effects/Effect.h @@ -31,71 +31,71 @@ /**this class is inherited by the all effects(Reverb, Echo, ..)*/ class Effect { -public: - /** - * Effect Constructor - * @param insertion_ 1 when it is an insertion Effect and 0 when it - * is not an insertion Effect - * @param efxoutl_ Effect output buffer Left channel - * @param efxoutr_ Effect output buffer Right channel - * @param filterpars_ pointer to FilterParams array - * @param Ppreset_ chosen preset - * @return Initialized Effect object*/ - Effect(bool insertion_,REALTYPE *const efxoutl_, - REALTYPE *const efxoutr_,FilterParams *filterpars_, - const unsigned char & Ppreset_); - /**Deconstructor - * - * Deconstructs the Effect and releases any resouces that it has - * allocated for itself*/ - virtual ~Effect() {}; - /** - * Choose a preset - * @param npreset number of chosen preset*/ - virtual void setpreset(unsigned char npreset)=0; - /**Change parameter npar to value - * @param npar chosen parameter - * @param value chosen new value*/ - virtual void changepar(const int &npar,const unsigned char &value)=0; - /**Get the value of parameter npar - * @param npar chosen parameter - * @return the value of the parameter in an unsigned char or 0 if it - * does not exist*/ - virtual unsigned char getpar(const int &npar)const=0; - /**Output result of effect based on the given buffers - * - * This method should result in the effect generating its results - * and placing them into the efxoutl and efxoutr buffers. - * Every Effect should overide this method. - * - * @param smpsl Input buffer for the Left channel - * @param smpsr Input buffer for the Right channel - */ - virtual void out(REALTYPE *const smpsl,REALTYPE *const smpsr)=0; - /**Reset the state of the effect*/ - virtual void cleanup() {}; - /**This is only used for EQ (for user interface)*/ - virtual REALTYPE getfreqresponse(REALTYPE freq) { - return (0); - }; - - unsigned char Ppreset;/**<Currently used preset*/ - REALTYPE *const efxoutl;/**<Effect out Left Channel*/ - REALTYPE *const efxoutr;/**<Effect out Right Channel*/ - /**\todo make efxoutl and efxoutr private and replace them with a StereoSample*/ - - REALTYPE outvolume;/**<This is the volume of effect and is public because + public: + /** + * Effect Constructor + * @param insertion_ 1 when it is an insertion Effect and 0 when it + * is not an insertion Effect + * @param efxoutl_ Effect output buffer Left channel + * @param efxoutr_ Effect output buffer Right channel + * @param filterpars_ pointer to FilterParams array + * @param Ppreset_ chosen preset + * @return Initialized Effect object*/ + Effect(bool insertion_, REALTYPE *const efxoutl_, + REALTYPE *const efxoutr_, FilterParams *filterpars_, + const unsigned char &Ppreset_); + /**Deconstructor + * + * Deconstructs the Effect and releases any resouces that it has + * allocated for itself*/ + virtual ~Effect() {} + /** + * Choose a preset + * @param npreset number of chosen preset*/ + virtual void setpreset(unsigned char npreset) = 0; + /**Change parameter npar to value + * @param npar chosen parameter + * @param value chosen new value*/ + virtual void changepar(const int &npar, const unsigned char &value) = 0; + /**Get the value of parameter npar + * @param npar chosen parameter + * @return the value of the parameter in an unsigned char or 0 if it + * does not exist*/ + virtual unsigned char getpar(const int &npar) const = 0; + /**Output result of effect based on the given buffers + * + * This method should result in the effect generating its results + * and placing them into the efxoutl and efxoutr buffers. + * Every Effect should overide this method. + * + * @param smpsl Input buffer for the Left channel + * @param smpsr Input buffer for the Right channel + */ + virtual void out(REALTYPE *const smpsl, REALTYPE *const smpsr) = 0; + /**Reset the state of the effect*/ + virtual void cleanup() {} + /**This is only used for EQ (for user interface)*/ + virtual REALTYPE getfreqresponse(REALTYPE freq) { + return 0; + } + + unsigned char Ppreset; /**<Currently used preset*/ + REALTYPE *const efxoutl; /**<Effect out Left Channel*/ + REALTYPE *const efxoutr; /**<Effect out Right Channel*/ + /**\todo make efxoutl and efxoutr private and replace them with a StereoSample*/ + + REALTYPE outvolume;/**<This is the volume of effect and is public because * it is needed in system effects. * The out volume of such effects are always 1.0, so * this setting tells me how is the volume to the * Master Output only.*/ - REALTYPE volume; + REALTYPE volume; - FilterParams *filterpars;/**<Parameters for filters used by Effect*/ -protected: + FilterParams *filterpars; /**<Parameters for filters used by Effect*/ + protected: - const bool insertion;/**<If Effect is an insertion effect, insertion=1 + const bool insertion;/**<If Effect is an insertion effect, insertion=1 *otherwise, it should be insertion=0*/ }; diff --git a/src/Effects/EffectLFO.cpp b/src/Effects/EffectLFO.cpp @@ -28,24 +28,23 @@ EffectLFO::EffectLFO() { - xl=0.0; - xr=0.0; - Pfreq=40; - Prandomness=0; - PLFOtype=0; - Pstereo=96; + xl = 0.0; + xr = 0.0; + Pfreq = 40; + Prandomness = 0; + PLFOtype = 0; + Pstereo = 96; updateparams(); - ampl1=(1-lfornd)+lfornd*RND; - ampl2=(1-lfornd)+lfornd*RND; - ampr1=(1-lfornd)+lfornd*RND; - ampr2=(1-lfornd)+lfornd*RND; -}; + ampl1 = (1 - lfornd) + lfornd * RND; + ampl2 = (1 - lfornd) + lfornd * RND; + ampr1 = (1 - lfornd) + lfornd * RND; + ampr2 = (1 - lfornd) + lfornd * RND; +} EffectLFO::~EffectLFO() -{ -}; +{} /* @@ -53,19 +52,24 @@ EffectLFO::~EffectLFO() */ void EffectLFO::updateparams() { - REALTYPE lfofreq=(pow(2,Pfreq/127.0*10.0)-1.0)*0.03; - incx=fabs(lfofreq)*(REALTYPE)SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE; - if (incx>0.49999999) incx=0.499999999; //Limit the Frequency + REALTYPE lfofreq = (pow(2, Pfreq / 127.0 * 10.0) - 1.0) * 0.03; + incx = fabs(lfofreq) * (REALTYPE)SOUND_BUFFER_SIZE / (REALTYPE)SAMPLE_RATE; + if(incx > 0.49999999) + incx = 0.499999999; //Limit the Frequency - lfornd=Prandomness/127.0; - if (lfornd<0.0) lfornd=0.0; - else if (lfornd>1.0) lfornd=1.0; + lfornd = Prandomness / 127.0; + if(lfornd < 0.0) + lfornd = 0.0; + else + if(lfornd > 1.0) + lfornd = 1.0; - if (PLFOtype>1) PLFOtype=1;//this has to be updated if more lfo's are added - lfotype=PLFOtype; + if(PLFOtype > 1) + PLFOtype = 1; //this has to be updated if more lfo's are added + lfotype = PLFOtype; - xr=fmod(xl+(Pstereo-64.0)/127.0+1.0,1.0); -}; + xr = fmod(xl + (Pstereo - 64.0) / 127.0 + 1.0, 1.0); +} /* @@ -74,44 +78,50 @@ void EffectLFO::updateparams() REALTYPE EffectLFO::getlfoshape(REALTYPE x) { REALTYPE out; - switch (lfotype) { + switch(lfotype) { case 1: //EffectLFO_TRIANGLE - if ((x>0.0)&&(x<0.25)) out=4.0*x; - else if ((x>0.25)&&(x<0.75)) out=2-4*x; - else out=4.0*x-4.0; + if((x > 0.0) && (x < 0.25)) + out = 4.0 * x; + else + if((x > 0.25) && (x < 0.75)) + out = 2 - 4 * x; + else + out = 4.0 * x - 4.0; break; - /**\todo more to be added here; also ::updateparams() need to be updated (to allow more lfotypes)*/ + /**\todo more to be added here; also ::updateparams() need to be updated (to allow more lfotypes)*/ default: - out=cos(x*2*PI);//EffectLFO_SINE - }; - return(out); -}; + out = cos(x * 2 * PI); //EffectLFO_SINE + } + return out; +} /* * LFO output */ -void EffectLFO::effectlfoout(REALTYPE *outl,REALTYPE *outr) +void EffectLFO::effectlfoout(REALTYPE *outl, REALTYPE *outr) { REALTYPE out; - out=getlfoshape(xl); - if ((lfotype==0)||(lfotype==1)) out*=(ampl1+xl*(ampl2-ampl1)); - xl+=incx; - if (xl>1.0) { - xl-=1.0; - ampl1=ampl2; - ampl2=(1.0-lfornd)+lfornd*RND; - }; - *outl=(out+1.0)*0.5; - - out=getlfoshape(xr); - if ((lfotype==0)||(lfotype==1)) out*=(ampr1+xr*(ampr2-ampr1)); - xr+=incx; - if (xr>1.0) { - xr-=1.0; - ampr1=ampr2; - ampr2=(1.0-lfornd)+lfornd*RND; - }; - *outr=(out+1.0)*0.5; -}; + out = getlfoshape(xl); + if((lfotype == 0) || (lfotype == 1)) + out *= (ampl1 + xl * (ampl2 - ampl1)); + xl += incx; + if(xl > 1.0) { + xl -= 1.0; + ampl1 = ampl2; + ampl2 = (1.0 - lfornd) + lfornd * RND; + } + *outl = (out + 1.0) * 0.5; + + out = getlfoshape(xr); + if((lfotype == 0) || (lfotype == 1)) + out *= (ampr1 + xr * (ampr2 - ampr1)); + xr += incx; + if(xr > 1.0) { + xr -= 1.0; + ampr1 = ampr2; + ampr2 = (1.0 - lfornd) + lfornd * RND; + } + *outr = (out + 1.0) * 0.5; +} diff --git a/src/Effects/EffectLFO.h b/src/Effects/EffectLFO.h @@ -28,24 +28,24 @@ * \todo see if this should inherit LFO*/ class EffectLFO { -public: - EffectLFO(); - ~EffectLFO(); - void effectlfoout(REALTYPE *outl,REALTYPE *outr); - void updateparams(); - unsigned char Pfreq; - unsigned char Prandomness; - unsigned char PLFOtype; - unsigned char Pstereo;//"64"=0 -private: - REALTYPE getlfoshape(REALTYPE x); - - REALTYPE xl,xr; - REALTYPE incx; - REALTYPE ampl1,ampl2,ampr1,ampr2;//necessary for "randomness" - REALTYPE lfointensity; - REALTYPE lfornd; - char lfotype; /**\todo GET RID OF CHAR (replace with short or enum)*/ + public: + EffectLFO(); + ~EffectLFO(); + void effectlfoout(REALTYPE *outl, REALTYPE *outr); + void updateparams(); + unsigned char Pfreq; + unsigned char Prandomness; + unsigned char PLFOtype; + unsigned char Pstereo; //"64"=0 + private: + REALTYPE getlfoshape(REALTYPE x); + + REALTYPE xl, xr; + REALTYPE incx; + REALTYPE ampl1, ampl2, ampr1, ampr2; //necessary for "randomness" + REALTYPE lfointensity; + REALTYPE lfornd; + char lfotype; /**\todo GET RID OF CHAR (replace with short or enum)*/ }; diff --git a/src/Effects/EffectMgr.cpp b/src/Effects/EffectMgr.cpp @@ -22,11 +22,11 @@ #include "EffectMgr.h" -EffectMgr::EffectMgr(int insertion_,pthread_mutex_t *mutex_) - :insertion(insertion_), - efxoutl(new REALTYPE[SOUND_BUFFER_SIZE]), - efxoutr(new REALTYPE[SOUND_BUFFER_SIZE]), - filterpars(NULL),nefx(0),efx(NULL),mutex(mutex_),dryonly(false) +EffectMgr::EffectMgr(int insertion_, pthread_mutex_t *mutex_) + :insertion(insertion_), + efxoutl(new REALTYPE[SOUND_BUFFER_SIZE]), + efxoutr(new REALTYPE[SOUND_BUFFER_SIZE]), + filterpars(NULL), nefx(0), efx(NULL), mutex(mutex_), dryonly(false) { setpresettype("Peffect"); /**\todo Figure out what this is doing * , as it might be another leaky abstraction.*/ @@ -36,10 +36,10 @@ EffectMgr::EffectMgr(int insertion_,pthread_mutex_t *mutex_) // mutex=mutex_; // efxoutl=new REALTYPE[SOUND_BUFFER_SIZE]; // efxoutr=new REALTYPE[SOUND_BUFFER_SIZE]; - for (int i=0;i<SOUND_BUFFER_SIZE;i++) { - efxoutl[i]=0.0; - efxoutr[i]=0.0; - }; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + efxoutl[i] = 0.0; + efxoutr[i] = 0.0; + } // filterpars=NULL; // dryonly=false; defaults(); @@ -48,9 +48,10 @@ EffectMgr::EffectMgr(int insertion_,pthread_mutex_t *mutex_) EffectMgr::~EffectMgr() { - if (efx!=NULL) delete efx; - delete []efxoutl; - delete []efxoutr; + if(efx != NULL) + delete efx; + delete [] efxoutl; + delete [] efxoutr; } void EffectMgr::defaults() @@ -65,46 +66,49 @@ void EffectMgr::defaults() void EffectMgr::changeeffect(int nefx_) { cleanup(); - if (nefx==nefx_) return; - nefx=nefx_; - for (int i=0;i<SOUND_BUFFER_SIZE;i++) { - efxoutl[i]=0.0; - efxoutr[i]=0.0; - }; - - if (efx!=NULL) delete efx; - switch (nefx) { /**\todo replace leaky abstraction*/ + if(nefx == nefx_) + return; + nefx = nefx_; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + efxoutl[i] = 0.0; + efxoutr[i] = 0.0; + } + + if(efx != NULL) + delete efx; + switch(nefx) { /**\todo replace leaky abstraction*/ case 1: - efx=new Reverb(insertion,efxoutl,efxoutr); + efx = new Reverb(insertion, efxoutl, efxoutr); break; case 2: - efx=new Echo(insertion,efxoutl,efxoutr); + efx = new Echo(insertion, efxoutl, efxoutr); break; case 3: - efx=new Chorus(insertion,efxoutl,efxoutr); + efx = new Chorus(insertion, efxoutl, efxoutr); break; case 4: - efx=new Phaser(insertion,efxoutl,efxoutr); + efx = new Phaser(insertion, efxoutl, efxoutr); break; case 5: - efx=new Alienwah(insertion,efxoutl,efxoutr); + efx = new Alienwah(insertion, efxoutl, efxoutr); break; case 6: - efx=new Distorsion(insertion,efxoutl,efxoutr); + efx = new Distorsion(insertion, efxoutl, efxoutr); break; case 7: - efx=new EQ(insertion,efxoutl,efxoutr); + efx = new EQ(insertion, efxoutl, efxoutr); break; case 8: - efx=new DynamicFilter(insertion,efxoutl,efxoutr); + efx = new DynamicFilter(insertion, efxoutl, efxoutr); break; - //put more effect here + //put more effect here default: - efx=NULL; - break;//no effect (thru) - }; + efx = NULL; + break; //no effect (thru) + } - if (efx!=NULL) filterpars=efx->filterpars; + if(efx != NULL) + filterpars = efx->filterpars; } /* @@ -112,7 +116,7 @@ void EffectMgr::changeeffect(int nefx_) */ int EffectMgr::geteffect() { - return (nefx); + return nefx; } /* @@ -120,7 +124,8 @@ int EffectMgr::geteffect() */ void EffectMgr::cleanup() { - if (efx!=NULL) efx->cleanup(); + if(efx != NULL) + efx->cleanup(); } @@ -130,8 +135,10 @@ void EffectMgr::cleanup() unsigned char EffectMgr::getpreset() { - if (efx!=NULL) return(efx->Ppreset); - else return(0); + if(efx != NULL) + return efx->Ppreset; + else + return 0; } /* @@ -139,7 +146,8 @@ unsigned char EffectMgr::getpreset() */ void EffectMgr::changepreset_nolock(unsigned char npreset) { - if (efx!=NULL) efx->setpreset(npreset); + if(efx != NULL) + efx->setpreset(npreset); } /* @@ -156,19 +164,20 @@ void EffectMgr::changepreset(unsigned char npreset) /* * Change a parameter of the current effect */ -void EffectMgr::seteffectpar_nolock(int npar,unsigned char value) +void EffectMgr::seteffectpar_nolock(int npar, unsigned char value) { - if (efx==NULL) return; - efx->changepar(npar,value); + if(efx == NULL) + return; + efx->changepar(npar, value); } /* * Change a parameter of the current effect (with thread locking) */ -void EffectMgr::seteffectpar(int npar,unsigned char value) +void EffectMgr::seteffectpar(int npar, unsigned char value) { pthread_mutex_lock(mutex); - seteffectpar_nolock(npar,value); + seteffectpar_nolock(npar, value); pthread_mutex_unlock(mutex); } @@ -177,80 +186,85 @@ void EffectMgr::seteffectpar(int npar,unsigned char value) */ unsigned char EffectMgr::geteffectpar(int npar) { - if (efx==NULL) return(0); - return(efx->getpar(npar)); + if(efx == NULL) + return 0; + return efx->getpar(npar); } /* * Apply the effect */ -void EffectMgr::out(REALTYPE *smpsl,REALTYPE *smpsr) +void EffectMgr::out(REALTYPE *smpsl, REALTYPE *smpsr) { int i; - if (efx==NULL) { - if (insertion==0) - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - smpsl[i]=0.0; - smpsr[i]=0.0; - efxoutl[i]=0.0; - efxoutr[i]=0.0; - }; + if(efx == NULL) { + if(insertion == 0) + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + smpsl[i] = 0.0; + smpsr[i] = 0.0; + efxoutl[i] = 0.0; + efxoutr[i] = 0.0; + } + ; return; - }; - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - smpsl[i]+=denormalkillbuf[i]; - smpsr[i]+=denormalkillbuf[i]; - efxoutl[i]=0.0; - efxoutr[i]=0.0; - }; - efx->out(smpsl,smpsr); - - REALTYPE volume=efx->volume; - - if (nefx==7) {//this is need only for the EQ effect + } + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + smpsl[i] += denormalkillbuf[i]; + smpsr[i] += denormalkillbuf[i]; + efxoutl[i] = 0.0; + efxoutr[i] = 0.0; + } + efx->out(smpsl, smpsr); + + REALTYPE volume = efx->volume; + + if(nefx == 7) { //this is need only for the EQ effect /**\todo figure out why*/ - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - smpsl[i]=efxoutl[i]; - smpsr[i]=efxoutr[i]; - }; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + smpsl[i] = efxoutl[i]; + smpsr[i] = efxoutr[i]; + } return; - }; + } //Insertion effect - if (insertion!=0) { - REALTYPE v1,v2; - if (volume<0.5) { - v1=1.0; - v2=volume*2.0; - } else { - v1=(1.0-volume)*2.0; - v2=1.0; - }; - if ((nefx==1)||(nefx==2)) v2*=v2;//for Reverb and Echo, the wet function is not liniar - - if (dryonly) {//this is used for instrument effect only - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - smpsl[i]*=v1; - smpsr[i]*=v1; - efxoutl[i]*=v2; - efxoutr[i]*=v2; - }; - } else {//normal instrument/insertion effect - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - smpsl[i]=smpsl[i]*v1+efxoutl[i]*v2; - smpsr[i]=smpsr[i]*v1+efxoutr[i]*v2; - }; - }; - } else {//System effect - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - efxoutl[i]*=2.0*volume; - efxoutr[i]*=2.0*volume; - smpsl[i]=efxoutl[i]; - smpsr[i]=efxoutr[i]; - }; - }; - + if(insertion != 0) { + REALTYPE v1, v2; + if(volume < 0.5) { + v1 = 1.0; + v2 = volume * 2.0; + } + else { + v1 = (1.0 - volume) * 2.0; + v2 = 1.0; + } + if((nefx == 1) || (nefx == 2)) + v2 *= v2; //for Reverb and Echo, the wet function is not liniar + + if(dryonly) { //this is used for instrument effect only + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + smpsl[i] *= v1; + smpsr[i] *= v1; + efxoutl[i] *= v2; + efxoutr[i] *= v2; + } + } + else { //normal instrument/insertion effect + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + smpsl[i] = smpsl[i] * v1 + efxoutl[i] * v2; + smpsr[i] = smpsr[i] * v1 + efxoutr[i] * v2; + } + } + } + else { //System effect + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + efxoutl[i] *= 2.0 * volume; + efxoutr[i] *= 2.0 * volume; + smpsl[i] = efxoutl[i]; + smpsr[i] = efxoutr[i]; + } + } } /* @@ -258,8 +272,10 @@ void EffectMgr::out(REALTYPE *smpsl,REALTYPE *smpsr) */ REALTYPE EffectMgr::sysefxgetvolume() { - if (efx==NULL) return (1.0); - else return(efx->outvolume); + if(efx == NULL) + return 1.0; + else + return efx->outvolume; } @@ -268,65 +284,72 @@ REALTYPE EffectMgr::sysefxgetvolume() */ REALTYPE EffectMgr::getEQfreqresponse(REALTYPE freq) { - if (nefx==7) return(efx->getfreqresponse(freq)); - else return(0.0); + if(nefx == 7) + return efx->getfreqresponse(freq); + else + return 0.0; } void EffectMgr::setdryonly(bool value) { - dryonly=value; + dryonly = value; } void EffectMgr::add2XML(XMLwrapper *xml) { - xml->addpar("type",geteffect()); + xml->addpar("type", geteffect()); - if ((efx==NULL)||(geteffect()==0)) return; - xml->addpar("preset",efx->Ppreset); + if((efx == NULL) || (geteffect() == 0)) + return; + xml->addpar("preset", efx->Ppreset); xml->beginbranch("EFFECT_PARAMETERS"); - for (int n=0;n<128;n++) { /**\todo evaluate who should oversee saving - * and loading of parameters*/ - int par=geteffectpar(n); - if (par==0) continue; - xml->beginbranch("par_no",n); - xml->addpar("par",par); + for(int n = 0; n < 128; n++) { + /**\todo evaluate who should oversee saving + * and loading of parameters*/ + int par = geteffectpar(n); + if(par == 0) + continue; + xml->beginbranch("par_no", n); + xml->addpar("par", par); xml->endbranch(); - }; - if (filterpars!=NULL) { + } + if(filterpars != NULL) { xml->beginbranch("FILTER"); filterpars->add2XML(xml); xml->endbranch(); - }; + } xml->endbranch(); } void EffectMgr::getfromXML(XMLwrapper *xml) { - changeeffect(xml->getpar127("type",geteffect())); + changeeffect(xml->getpar127("type", geteffect())); - if ((efx==NULL)||(geteffect()==0)) return; + if((efx == NULL) || (geteffect() == 0)) + return; - efx->Ppreset=xml->getpar127("preset",efx->Ppreset); + efx->Ppreset = xml->getpar127("preset", efx->Ppreset); - if (xml->enterbranch("EFFECT_PARAMETERS")) { - for (int n=0;n<128;n++) { - seteffectpar_nolock(n,0);//erase effect parameter - if (xml->enterbranch("par_no",n)==0) continue; + if(xml->enterbranch("EFFECT_PARAMETERS")) { + for(int n = 0; n < 128; n++) { + seteffectpar_nolock(n, 0); //erase effect parameter + if(xml->enterbranch("par_no", n) == 0) + continue; - int par=geteffectpar(n); - seteffectpar_nolock(n,xml->getpar127("par",par)); + int par = geteffectpar(n); + seteffectpar_nolock(n, xml->getpar127("par", par)); xml->exitbranch(); - }; - if (filterpars!=NULL) { - if (xml->enterbranch("FILTER")) { + } + if(filterpars != NULL) { + if(xml->enterbranch("FILTER")) { filterpars->getfromXML(xml); xml->exitbranch(); - }; - }; + } + } xml->exitbranch(); - }; + } cleanup(); } diff --git a/src/Effects/EffectMgr.h b/src/Effects/EffectMgr.h @@ -41,62 +41,62 @@ /**Effect manager, an interface betwen the program and effects*/ class EffectMgr:public Presets { -public: - EffectMgr(int insertion_,pthread_mutex_t *mutex_); - ~EffectMgr(); - - void add2XML(XMLwrapper *xml); - void defaults(); - void getfromXML(XMLwrapper *xml); - - void out(REALTYPE *smpsl,REALTYPE *smpsr); - - void setdryonly(bool value); - - /**get the output(to speakers) volume of the systemeffect*/ - REALTYPE sysefxgetvolume(); - - void cleanup();/**<cleanup the effect*/ - - /**change effect to the given int - * @param nefx_ the number of the effect*/ - void changeeffect(int nefx_); - /**Get the number of the effect - * @return the number*/ - int geteffect(); - /** - * Change the preset to the given one - * @param npreset number of the chosen preset - */ - void changepreset(unsigned char npreset); - /** - * Change the preset to the given one without locking the thread - * @param npreset number of the chosen preset - */ - void changepreset_nolock(unsigned char npreset); - /** - * Get the current preset - * @return the current preset*/ - unsigned char getpreset(); - /**sets the effect par*/ - void seteffectpar(int npar,unsigned char value); - /**<sets the effect par without thread lock*/ - void seteffectpar_nolock(int npar,unsigned char value); - unsigned char geteffectpar(int npar); - const bool insertion;/**<1 if the effect is connected as insertion effect*/ - REALTYPE *efxoutl,*efxoutr; - - /**used by UI - * \todo needs to be decoupled*/ - REALTYPE getEQfreqresponse(REALTYPE freq); - - FilterParams *filterpars; - -private: - int nefx; - Effect *efx; - pthread_mutex_t *mutex; - bool dryonly; + public: + EffectMgr(int insertion_, pthread_mutex_t *mutex_); + ~EffectMgr(); + + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); + + void out(REALTYPE *smpsl, REALTYPE *smpsr); + + void setdryonly(bool value); + + /**get the output(to speakers) volume of the systemeffect*/ + REALTYPE sysefxgetvolume(); + + void cleanup(); /**<cleanup the effect*/ + + /**change effect to the given int + * @param nefx_ the number of the effect*/ + void changeeffect(int nefx_); + /**Get the number of the effect + * @return the number*/ + int geteffect(); + /** + * Change the preset to the given one + * @param npreset number of the chosen preset + */ + void changepreset(unsigned char npreset); + /** + * Change the preset to the given one without locking the thread + * @param npreset number of the chosen preset + */ + void changepreset_nolock(unsigned char npreset); + /** + * Get the current preset + * @return the current preset*/ + unsigned char getpreset(); + /**sets the effect par*/ + void seteffectpar(int npar, unsigned char value); + /**<sets the effect par without thread lock*/ + void seteffectpar_nolock(int npar, unsigned char value); + unsigned char geteffectpar(int npar); + const bool insertion; /**<1 if the effect is connected as insertion effect*/ + REALTYPE *efxoutl, *efxoutr; + + /**used by UI + * \todo needs to be decoupled*/ + REALTYPE getEQfreqresponse(REALTYPE freq); + + FilterParams *filterpars; + + private: + int nefx; + Effect *efx; + pthread_mutex_t *mutex; + bool dryonly; }; #endif diff --git a/src/Effects/Phaser.cpp b/src/Effects/Phaser.cpp @@ -1,283 +1,294 @@ -/* - ZynAddSubFX - a software synthesizer - - Phaser.C - Phaser effect - 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 or later) 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 <cmath> -#include "Phaser.h" -#define PHASER_LFO_SHAPE 2 - -Phaser::Phaser(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_) - :Effect(insertion_,efxoutl_,efxoutr_,NULL,0),old(1),oldgain(0.0) -{ - setpreset(Ppreset); - cleanup(); -}; - -Phaser::~Phaser() -{ -}; - - -/* - * Effect output - */ -void Phaser::out(REALTYPE *smpsl,REALTYPE *smpsr) -{ - int i,j; - REALTYPE lfol,lfor,lgain,rgain,tmp; - - lfo.effectlfoout(&lfol,&lfor); - lgain=lfol; - rgain=lfor; - lgain=(exp(lgain*PHASER_LFO_SHAPE)-1)/(exp(PHASER_LFO_SHAPE)-1.0); - rgain=(exp(rgain*PHASER_LFO_SHAPE)-1)/(exp(PHASER_LFO_SHAPE)-1.0); - - - lgain=1.0-phase*(1.0-depth)-(1.0-phase)*lgain*depth; - rgain=1.0-phase*(1.0-depth)-(1.0-phase)*rgain*depth; - - if (lgain>1.0) lgain=1.0; - else if (lgain<0.0) lgain=0.0; - if (rgain>1.0) rgain=1.0; - else if (rgain<0.0) rgain=0.0; - - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - REALTYPE x=(REALTYPE) i /SOUND_BUFFER_SIZE; - REALTYPE x1=1.0-x; - REALTYPE gl=lgain*x+oldgain.left()*x1; - REALTYPE gr=rgain*x+oldgain.right()*x1; - REALTYPE inl=smpsl[i]*panning+fbl; - REALTYPE inr=smpsr[i]*(1.0-panning)+fbr; - - //Left channel - for (j=0;j<Pstages*2;j++) {//Phasing routine - tmp=old.left()[j]; - old.left()[j]=gl*tmp+inl; - inl=tmp-gl*old.left()[j]; - }; - //Right channel - for (j=0;j<Pstages*2;j++) {//Phasing routine - tmp=old.right()[j]; - old.right()[j]=gr*tmp+inr; - inr=tmp-gr*old.right()[j]; - }; - //Left/Right crossing - REALTYPE l=inl; - REALTYPE r=inr; - inl=l*(1.0-lrcross)+r*lrcross; - inr=r*(1.0-lrcross)+l*lrcross; - - fbl=inl*fb; - fbr=inr*fb; - efxoutl[i]=inl; - efxoutr[i]=inr; - - }; - - oldgain=Stereo<REALTYPE>(lgain,rgain); - - if (Poutsub!=0) - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - efxoutl[i]*= -1.0; - efxoutr[i]*= -1.0; - }; - -}; - -/* - * Cleanup the effect - */ -void Phaser::cleanup() -{ - fbl=0.0; - fbr=0.0; - oldgain=Stereo<REALTYPE>(0.0); - old.l().clear(); - old.r().clear(); -}; - -/* - * Parameter control - */ -void Phaser::setdepth(const unsigned char &Pdepth) -{ - this->Pdepth=Pdepth; - depth=(Pdepth/127.0); -}; - - -void Phaser::setfb(const unsigned char &Pfb) -{ - this->Pfb=Pfb; - fb=(Pfb-64.0)/64.1; -}; - -void Phaser::setvolume(const unsigned char &Pvolume) -{ - this->Pvolume=Pvolume; - outvolume=Pvolume/127.0; - if (insertion==0) volume=1.0; - else volume=outvolume; -}; - -void Phaser::setpanning(const unsigned char &Ppanning) -{ - this->Ppanning=Ppanning; - panning=Ppanning/127.0; -}; - -void Phaser::setlrcross(const unsigned char &Plrcross) -{ - this->Plrcross=Plrcross; - lrcross=Plrcross/127.0; -}; - -void Phaser::setstages(const unsigned char &Pstages) -{ - if (Pstages>=MAX_PHASER_STAGES) this->Pstages=MAX_PHASER_STAGES-1; - else this->Pstages=Pstages; - old=Stereo<AuSample>(Pstages*2); - cleanup(); -}; - -void Phaser::setphase(const unsigned char &Pphase) -{ - this->Pphase=Pphase; - phase=(Pphase/127.0); -}; - - -void Phaser::setpreset(unsigned char npreset) -{ - const int PRESET_SIZE=12; - const int NUM_PRESETS=6; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ - //Phaser1 - {64,64,36,0,0,64,110,64,1,0,0,20}, - //Phaser2 - {64,64,35,0,0,88,40,64,3,0,0,20}, - //Phaser3 - {64,64,31,0,0,66,68,107,2,0,0,20}, - //Phaser4 - {39,64,22,0,0,66,67,10,5,0,1,20}, - //Phaser5 - {64,64,20,0,1,110,67,78,10,0,0,20}, - //Phaser6 - {64,64,53,100,0,58,37,78,3,0,0,20} - }; - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n<PRESET_SIZE;n++) changepar(n,presets[npreset][n]); - Ppreset=npreset; -}; - - -void Phaser::changepar(const int &npar,const unsigned char &value) -{ - switch (npar) { - case 0: - setvolume(value); - break; - case 1: - setpanning(value); - break; - case 2: - lfo.Pfreq=value; - lfo.updateparams(); - break; - case 3: - lfo.Prandomness=value; - lfo.updateparams(); - break; - case 4: - lfo.PLFOtype=value; - lfo.updateparams(); - break; - case 5: - lfo.Pstereo=value; - lfo.updateparams(); - break; - case 6: - setdepth(value); - break; - case 7: - setfb(value); - break; - case 8: - setstages(value); - break; - case 9: - setlrcross(value); - break; - case 10: - if (value>1) Poutsub=1; - else Poutsub=value; - break; - case 11: - setphase(value); - break; - }; -}; - -unsigned char Phaser::getpar(const int &npar)const -{ - switch (npar) { - case 0: - return(Pvolume); - break; - case 1: - return(Ppanning); - break; - case 2: - return(lfo.Pfreq); - break; - case 3: - return(lfo.Prandomness); - break; - case 4: - return(lfo.PLFOtype); - break; - case 5: - return(lfo.Pstereo); - break; - case 6: - return(Pdepth); - break; - case 7: - return(Pfb); - break; - case 8: - return(Pstages); - break; - case 9: - return(Plrcross); - break; - case 10: - return(Poutsub); - break; - case 11: - return(Pphase); - break; - default: - return (0); - }; - -}; - +/* + ZynAddSubFX - a software synthesizer + + Phaser.C - Phaser effect + 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 or later) 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 <cmath> +#include "Phaser.h" +#define PHASER_LFO_SHAPE 2 + +Phaser::Phaser(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0), old(1), oldgain(0.0) +{ + setpreset(Ppreset); + cleanup(); +} + +Phaser::~Phaser() +{} + + +/* + * Effect output + */ +void Phaser::out(REALTYPE *smpsl, REALTYPE *smpsr) +{ + int i, j; + REALTYPE lfol, lfor, lgain, rgain, tmp; + + lfo.effectlfoout(&lfol, &lfor); + lgain = lfol; + rgain = lfor; + lgain = (exp(lgain * PHASER_LFO_SHAPE) - 1) / (exp(PHASER_LFO_SHAPE) - 1.0); + rgain = (exp(rgain * PHASER_LFO_SHAPE) - 1) / (exp(PHASER_LFO_SHAPE) - 1.0); + + + lgain = 1.0 - phase * (1.0 - depth) - (1.0 - phase) * lgain * depth; + rgain = 1.0 - phase * (1.0 - depth) - (1.0 - phase) * rgain * depth; + + if(lgain > 1.0) + lgain = 1.0; + else + if(lgain < 0.0) + lgain = 0.0; + if(rgain > 1.0) + rgain = 1.0; + else + if(rgain < 0.0) + rgain = 0.0; + + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + REALTYPE x = (REALTYPE) i / SOUND_BUFFER_SIZE; + REALTYPE x1 = 1.0 - x; + REALTYPE gl = lgain * x + oldgain.left() * x1; + REALTYPE gr = rgain * x + oldgain.right() * x1; + REALTYPE inl = smpsl[i] * panning + fbl; + REALTYPE inr = smpsr[i] * (1.0 - panning) + fbr; + + //Left channel + for(j = 0; j < Pstages * 2; j++) { //Phasing routine + tmp = old.left()[j]; + old.left()[j] = gl * tmp + inl; + inl = tmp - gl *old.left()[j]; + } + //Right channel + for(j = 0; j < Pstages * 2; j++) { //Phasing routine + tmp = old.right()[j]; + old.right()[j] = gr * tmp + inr; + inr = tmp - gr *old.right()[j]; + } + //Left/Right crossing + REALTYPE l = inl; + REALTYPE r = inr; + inl = l * (1.0 - lrcross) + r * lrcross; + inr = r * (1.0 - lrcross) + l * lrcross; + + fbl = inl * fb; + fbr = inr * fb; + efxoutl[i] = inl; + efxoutr[i] = inr; + } + + oldgain = Stereo<REALTYPE>(lgain, rgain); + + if(Poutsub != 0) + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + efxoutl[i] *= -1.0; + efxoutr[i] *= -1.0; + } + ; +} + +/* + * Cleanup the effect + */ +void Phaser::cleanup() +{ + fbl = 0.0; + fbr = 0.0; + oldgain = Stereo<REALTYPE>(0.0); + old.l().clear(); + old.r().clear(); +} + +/* + * Parameter control + */ +void Phaser::setdepth(const unsigned char &Pdepth) +{ + this->Pdepth = Pdepth; + depth = (Pdepth / 127.0); +} + + +void Phaser::setfb(const unsigned char &Pfb) +{ + this->Pfb = Pfb; + fb = (Pfb - 64.0) / 64.1; +} + +void Phaser::setvolume(const unsigned char &Pvolume) +{ + this->Pvolume = Pvolume; + outvolume = Pvolume / 127.0; + if(insertion == 0) + volume = 1.0; + else + volume = outvolume; +} + +void Phaser::setpanning(const unsigned char &Ppanning) +{ + this->Ppanning = Ppanning; + panning = Ppanning / 127.0; +} + +void Phaser::setlrcross(const unsigned char &Plrcross) +{ + this->Plrcross = Plrcross; + lrcross = Plrcross / 127.0; +} + +void Phaser::setstages(const unsigned char &Pstages) +{ + if(Pstages >= MAX_PHASER_STAGES) + this->Pstages = MAX_PHASER_STAGES - 1; + else + this->Pstages = Pstages; + old = Stereo<AuSample>(Pstages * 2); + cleanup(); +} + +void Phaser::setphase(const unsigned char &Pphase) +{ + this->Pphase = Pphase; + phase = (Pphase / 127.0); +} + + +void Phaser::setpreset(unsigned char npreset) +{ + const int PRESET_SIZE = 12; + const int NUM_PRESETS = 6; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { + //Phaser1 + {64, 64, 36, 0, 0, 64, 110, 64, 1, 0, 0, 20}, + //Phaser2 + {64, 64, 35, 0, 0, 88, 40, 64, 3, 0, 0, 20}, + //Phaser3 + {64, 64, 31, 0, 0, 66, 68, 107, 2, 0, 0, 20}, + //Phaser4 + {39, 64, 22, 0, 0, 66, 67, 10, 5, 0, 1, 20}, + //Phaser5 + {64, 64, 20, 0, 1, 110, 67, 78, 10, 0, 0, 20}, + //Phaser6 + {64, 64, 53, 100, 0, 58, 37, 78, 3, 0, 0, 20} + }; + if(npreset >= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); + Ppreset = npreset; +} + + +void Phaser::changepar(const int &npar, const unsigned char &value) +{ + switch(npar) { + case 0: + setvolume(value); + break; + case 1: + setpanning(value); + break; + case 2: + lfo.Pfreq = value; + lfo.updateparams(); + break; + case 3: + lfo.Prandomness = value; + lfo.updateparams(); + break; + case 4: + lfo.PLFOtype = value; + lfo.updateparams(); + break; + case 5: + lfo.Pstereo = value; + lfo.updateparams(); + break; + case 6: + setdepth(value); + break; + case 7: + setfb(value); + break; + case 8: + setstages(value); + break; + case 9: + setlrcross(value); + break; + case 10: + if(value > 1) + Poutsub = 1; + else + Poutsub = value; + break; + case 11: + setphase(value); + break; + } +} + +unsigned char Phaser::getpar(const int &npar) const +{ + switch(npar) { + case 0: + return Pvolume; + break; + case 1: + return Ppanning; + break; + case 2: + return lfo.Pfreq; + break; + case 3: + return lfo.Prandomness; + break; + case 4: + return lfo.PLFOtype; + break; + case 5: + return lfo.Pstereo; + break; + case 6: + return Pdepth; + break; + case 7: + return Pfb; + break; + case 8: + return Pstages; + break; + case 9: + return Plrcross; + break; + case 10: + return Poutsub; + break; + case 11: + return Pphase; + break; + default: + return 0; + } +} + diff --git a/src/Effects/Phaser.h b/src/Effects/Phaser.h @@ -1,76 +1,76 @@ -/* - ZynAddSubFX - a software synthesizer - - Phaser.h - Phaser effect - 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 or later) 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 - -*/ - -#ifndef PHASER_H -#define PHASER_H -#include "../globals.h" -#include "../Misc/Stereo.h" -#include "../Samples/AuSample.h" -#include "Effect.h" -#include "EffectLFO.h" - -#define MAX_PHASER_STAGES 12 -/**Phaser Effect*/ -class Phaser:public Effect -{ -public: - Phaser(const int &insetion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); - ~Phaser(); - void out(REALTYPE *smpsl,REALTYPE *smpsr); - void setpreset(unsigned char npreset); - void changepar(const int &npar,const unsigned char &value); - unsigned char getpar(const int &npar)const; - void cleanup(); - void setdryonly(); - -private: - //Parametrii Phaser - EffectLFO lfo;/**<lfo-ul Phaser*/ - unsigned char Pvolume; - unsigned char Ppanning; - unsigned char Pdepth;/**<the depth of the Phaser*/ - unsigned char Pfb;/**<feedback*/ - unsigned char Plrcross;/**<feedback*/ - unsigned char Pstages; - unsigned char Poutsub;/**<if I wish to substract the output instead of the adding it*/ - unsigned char Pphase; - - //Control Parametrii - void setvolume(const unsigned char &Pvolume); - void setpanning(const unsigned char &Ppanning); - void setdepth(const unsigned char &Pdepth); - void setfb(const unsigned char &Pfb); - void setlrcross(const unsigned char &Plrcross); - void setstages(const unsigned char &Pstages); - void setphase(const unsigned char &Pphase); - - //Internal Values - //int insertion; //inherited from Effect - REALTYPE panning,fb,depth,lrcross,fbl,fbr,phase; - //REALTYPE *oldl,*oldr; - Stereo<AuSample> old; - //REALTYPE oldlgain,oldrgain; - Stereo<REALTYPE> oldgain; -}; - -#endif - +/* + ZynAddSubFX - a software synthesizer + + Phaser.h - Phaser effect + 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 or later) 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 + +*/ + +#ifndef PHASER_H +#define PHASER_H +#include "../globals.h" +#include "../Misc/Stereo.h" +#include "../Samples/AuSample.h" +#include "Effect.h" +#include "EffectLFO.h" + +#define MAX_PHASER_STAGES 12 +/**Phaser Effect*/ +class Phaser:public Effect +{ + public: + Phaser(const int &insetion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_); + ~Phaser(); + void out(REALTYPE *smpsl, REALTYPE *smpsr); + void setpreset(unsigned char npreset); + void changepar(const int &npar, const unsigned char &value); + unsigned char getpar(const int &npar) const; + void cleanup(); + void setdryonly(); + + private: + //Parametrii Phaser + EffectLFO lfo; /**<lfo-ul Phaser*/ + unsigned char Pvolume; + unsigned char Ppanning; + unsigned char Pdepth; /**<the depth of the Phaser*/ + unsigned char Pfb; /**<feedback*/ + unsigned char Plrcross; /**<feedback*/ + unsigned char Pstages; + unsigned char Poutsub; /**<if I wish to substract the output instead of the adding it*/ + unsigned char Pphase; + + //Control Parametrii + void setvolume(const unsigned char &Pvolume); + void setpanning(const unsigned char &Ppanning); + void setdepth(const unsigned char &Pdepth); + void setfb(const unsigned char &Pfb); + void setlrcross(const unsigned char &Plrcross); + void setstages(const unsigned char &Pstages); + void setphase(const unsigned char &Pphase); + + //Internal Values + //int insertion; //inherited from Effect + REALTYPE panning, fb, depth, lrcross, fbl, fbr, phase; + //REALTYPE *oldl,*oldr; + Stereo<AuSample> old; + //REALTYPE oldlgain,oldrgain; + Stereo<REALTYPE> oldgain; +}; + +#endif + diff --git a/src/Effects/Reverb.cpp b/src/Effects/Reverb.cpp @@ -1,506 +1,557 @@ -/* - ZynAddSubFX - a software synthesizer - - Reverb.C - Reverberation effect - 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 or later) 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 <cmath> -#include "Reverb.h" - -/**\todo: EarlyReflections,Prdelay,Perbalance */ - -Reverb::Reverb(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_) - :Effect(insertion_,efxoutl_,efxoutr_,NULL,0) -{ - inputbuf=new REALTYPE[SOUND_BUFFER_SIZE]; - - bandwidth=NULL; - - //defaults - Pvolume=48; - Ppan=64; - Ptime=64; - Pidelay=40; - Pidelayfb=0; - Prdelay=0; - Plpf=127; - Phpf=0; - Perbalance=64; - Plohidamp=80; - Ptype=1; - Proomsize=64; - Pbandwidth=30; - roomsize=1.0; - rs=1.0; - - for (int i=0;i<REV_COMBS*2;i++) { - comblen[i]=800+(int)(RND*1400); - combk[i]=0; - lpcomb[i]=0; - combfb[i]=-0.97; - comb[i]=NULL; - }; - - for (int i=0;i<REV_APS*2;i++) { - aplen[i]=500+(int)(RND*500); - apk[i]=0; - ap[i]=NULL; - }; - - lpf=NULL; - hpf=NULL;//no filter - idelay=NULL; - - setpreset(Ppreset); - cleanup();//do not call this before the comb initialisation -}; - - -Reverb::~Reverb() -{ - int i; - if (idelay!=NULL) delete []idelay; - if (hpf!=NULL) delete hpf; - if (lpf!=NULL) delete lpf; - - for (i=0;i<REV_APS*2;i++) delete [] ap[i]; - for (i=0;i<REV_COMBS*2;i++) delete [] comb[i]; - - delete [] inputbuf; - if (bandwidth) delete bandwidth; -}; - -/* - * Cleanup the effect - */ -void Reverb::cleanup() -{ - int i,j; - for (i=0;i<REV_COMBS*2;i++) { - lpcomb[i]=0.0; - for (j=0;j<comblen[i];j++) comb[i][j]=0.0; - }; - - for (i=0;i<REV_APS*2;i++) - for (j=0;j<aplen[i];j++) ap[i][j]=0.0; - - if (idelay!=NULL) for (i=0;i<idelaylen;i++) idelay[i]=0.0; - - if (hpf!=NULL) hpf->cleanup(); - if (lpf!=NULL) lpf->cleanup(); - -}; - -/* - * Process one channel; 0=left,1=right - */ -void Reverb::processmono(int ch,REALTYPE *output) -{ - int i,j; - REALTYPE fbout,tmp; - /**\todo: implement the high part from lohidamp*/ - - for (j=REV_COMBS*ch;j<REV_COMBS*(ch+1);j++) { - - int ck=combk[j]; - int comblength=comblen[j]; - REALTYPE lpcombj=lpcomb[j]; - - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - fbout=comb[j][ck]*combfb[j]; - fbout=fbout*(1.0-lohifb)+lpcombj*lohifb; - lpcombj=fbout; - - comb[j][ck]=inputbuf[i]+fbout; - output[i]+=fbout; - - if ((++ck)>=comblength) ck=0; - }; - - combk[j]=ck; - lpcomb[j]=lpcombj; - }; - - for (j=REV_APS*ch;j<REV_APS*(1+ch);j++) { - int ak=apk[j]; - int aplength=aplen[j]; - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - tmp=ap[j][ak]; - ap[j][ak]=0.7*tmp+output[i]; - output[i]=tmp-0.7*ap[j][ak]; - if ((++ak)>=aplength) ak=0; - }; - apk[j]=ak; - }; -}; - -/* - * Effect output - */ -void Reverb::out(REALTYPE *smps_l, REALTYPE *smps_r) -{ - int i; - if ((Pvolume==0)&&(insertion!=0)) return; - - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - inputbuf[i]=(smps_l[i]+smps_r[i])/2.0; - }; - - if (idelay!=NULL) { - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - //Initial delay r - REALTYPE tmp=inputbuf[i]+idelay[idelayk]*idelayfb; - inputbuf[i]=idelay[idelayk]; - idelay[idelayk]=tmp; - idelayk++; - if (idelayk>=idelaylen) { - idelayk=0; - }; - }; - }; - - if (bandwidth) bandwidth->process(SOUND_BUFFER_SIZE,inputbuf); - - if (lpf!=NULL) lpf->filterout(inputbuf); - if (hpf!=NULL) hpf->filterout(inputbuf); - - processmono(0,efxoutl);//left - processmono(1,efxoutr);//right - - REALTYPE lvol=rs/REV_COMBS*pan; - REALTYPE rvol=rs/REV_COMBS*(1.0-pan); - if (insertion!=0) { - lvol*=2; - rvol*=2; - }; - for (int i=0;i<SOUND_BUFFER_SIZE;i++) { - efxoutl[i]*=lvol; - efxoutr[i]*=rvol; - }; -}; - - -/* - * Parameter control - */ -void Reverb::setvolume(const unsigned char &Pvolume) -{ - this->Pvolume=Pvolume; - if (insertion==0) { - outvolume=pow(0.01,(1.0-Pvolume/127.0))*4.0; - volume=1.0; - } else { - volume=outvolume=Pvolume/127.0; - if (Pvolume==0) cleanup(); - }; -}; - -void Reverb::setpan(const unsigned char &Ppan) -{ - this->Ppan=Ppan; - pan=(REALTYPE)Ppan/127.0; -}; - -void Reverb::settime(const unsigned char &Ptime) -{ - int i; - REALTYPE t; - this->Ptime=Ptime; - t=pow(60.0,(REALTYPE)Ptime/127.0)-0.97; - - for (i=0;i<REV_COMBS*2;i++) { - combfb[i]=-exp((REALTYPE)comblen[i]/(REALTYPE)SAMPLE_RATE*log(0.001)/t); - //the feedback is negative because it removes the DC - }; -}; - -void Reverb::setlohidamp(unsigned char Plohidamp) -{ - REALTYPE x; - - if (Plohidamp<64) Plohidamp=64;//remove this when the high part from lohidamp will be added - - this->Plohidamp=Plohidamp; - if (Plohidamp==64) { - lohidamptype=0; - lohifb=0.0; - } else { - if (Plohidamp<64) lohidamptype=1; - if (Plohidamp>64) lohidamptype=2; - x=fabs((REALTYPE)(Plohidamp-64)/64.1); - lohifb=x*x; - }; -}; - -void Reverb::setidelay(const unsigned char &Pidelay) -{ - REALTYPE delay; - this->Pidelay=Pidelay; - delay=pow(50*Pidelay/127.0,2)-1.0; - - if (idelay!=NULL) delete []idelay; - idelay=NULL; - - idelaylen=(int) (SAMPLE_RATE*delay/1000); - if (idelaylen>1) { - idelayk=0; - idelay=new REALTYPE[idelaylen]; - for (int i=0;i<idelaylen;i++) idelay[i]=0.0; - }; -}; - -void Reverb::setidelayfb(const unsigned char &Pidelayfb) -{ - this->Pidelayfb=Pidelayfb; - idelayfb=Pidelayfb/128.0; -}; - -void Reverb::sethpf(const unsigned char &Phpf) -{ - this->Phpf=Phpf; - if (Phpf==0) {//No HighPass - if (hpf!=NULL) delete hpf; - hpf=NULL; - } else { - REALTYPE fr=exp(pow(Phpf/127.0,0.5)*log(10000.0))+20.0; - if (hpf==NULL) hpf=new AnalogFilter(3,fr,1,0); - else hpf->setfreq(fr); - }; -}; - -void Reverb::setlpf(const unsigned char &Plpf) -{ - this->Plpf=Plpf; - if (Plpf==127) {//No LowPass - if (lpf!=NULL) delete lpf; - lpf=NULL; - } else { - REALTYPE fr=exp(pow(Plpf/127.0,0.5)*log(25000.0))+40; - if (lpf==NULL) lpf=new AnalogFilter(2,fr,1,0); - else lpf->setfreq(fr); - }; -}; - -void Reverb::settype(unsigned char Ptype) -{ - const int NUM_TYPES=3; - int combtunings[NUM_TYPES][REV_COMBS]={ - //this is unused (for random) - {0,0,0,0,0,0,0,0}, - //Freeverb by Jezar at Dreampoint - {1116,1188,1277,1356,1422,1491,1557,1617}, - //Freeverb by Jezar at Dreampoint //duplicate - {1116,1188,1277,1356,1422,1491,1557,1617} - }; - int aptunings[NUM_TYPES][REV_APS]={ - //this is unused (for random) - {0,0,0,0}, - //Freeverb by Jezar at Dreampoint - {225,341,441,556}, - //Freeverb by Jezar at Dreampoint (duplicate) - {225,341,441,556} - }; - - if (Ptype>=NUM_TYPES) Ptype=NUM_TYPES-1; - this->Ptype=Ptype; - - REALTYPE tmp; - for (int i=0;i<REV_COMBS*2;i++) { - if (Ptype==0) tmp=800.0+(int)(RND*1400.0); - else tmp=combtunings[Ptype][i%REV_COMBS]; - tmp*=roomsize; - if (i>REV_COMBS) tmp+=23.0; - tmp*=SAMPLE_RATE/44100.0;//adjust the combs according to the samplerate - if (tmp<10) tmp=10; - - comblen[i]=(int) tmp; - combk[i]=0; - lpcomb[i]=0; - if (comb[i]!=NULL) delete []comb[i]; - comb[i]=new REALTYPE[comblen[i]]; - }; - - for (int i=0;i<REV_APS*2;i++) { - if (Ptype==0) tmp=500+(int)(RND*500); - else tmp=aptunings[Ptype][i%REV_APS]; - tmp*=roomsize; - if (i>REV_APS) tmp+=23.0; - tmp*=SAMPLE_RATE/44100.0;//adjust the combs according to the samplerate - if (tmp<10) tmp=10; - aplen[i]=(int) tmp; - apk[i]=0; - if (ap[i]!=NULL) delete []ap[i]; - ap[i]=new REALTYPE[aplen[i]]; - }; - settime(Ptime); - cleanup(); - if (bandwidth) delete bandwidth; - bandwidth=NULL; - if (Ptype==2){//bandwidth - bandwidth=new Unison(SOUND_BUFFER_SIZE/4+1,2.0); - bandwidth->set_size(50); - bandwidth->set_base_frequency(1.0); -#warning sa schimb size-ul - }; -}; - -void Reverb::setroomsize(const unsigned char &Proomsize) -{ - this->Proomsize=Proomsize; - if (Proomsize==0) this->Proomsize=64;//this is because the older versions consider roomsize=0 - roomsize=(this->Proomsize-64.0)/64.0; - if (roomsize>0.0) roomsize*=2.0; - roomsize=pow(10.0,roomsize); - rs=sqrt(roomsize); - settype(Ptype); -}; - -void Reverb::setbandwidth(const unsigned char &Pbandwidth){ - this->Pbandwidth=Pbandwidth; - REALTYPE v=Pbandwidth/127.0; - if (bandwidth) bandwidth->set_bandwidth(pow(v,2.0)*200.0); -}; - -void Reverb::setpreset(unsigned char npreset) -{ - const int PRESET_SIZE=13; - const int NUM_PRESETS=13; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ - //Cathedral1 - {80,64,63,24,0,0,0,85,5,83,1,64,20}, - //Cathedral2 - {80,64,69,35,0,0,0,127,0,71,0,64,20}, - //Cathedral3 - {80,64,69,24,0,0,0,127,75,78,1,85,20}, - //Hall1 - {90,64,51,10,0,0,0,127,21,78,1,64,20}, - //Hall2 - {90,64,53,20,0,0,0,127,75,71,1,64,20}, - //Room1 - {100,64,33,0,0,0,0,127,0,106,0,30,20}, - //Room2 - {100,64,21,26,0,0,0,62,0,77,1,45,20}, - //Basement - {110,64,14,0,0,0,0,127,5,71,0,25,20}, - //Tunnel - {85,80,84,20,42,0,0,51,0,78,1,105,20}, - //Echoed1 - {95,64,26,60,71,0,0,114,0,64,1,64,20}, - //Echoed2 - {90,64,40,88,71,0,0,114,0,88,1,64,20}, - //VeryLong1 - {90,64,93,15,0,0,0,114,0,77,0,95,20}, - //VeryLong2 - {90,64,111,30,0,0,0,114,90,74,1,80,20} - }; - - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n<PRESET_SIZE;n++) changepar(n,presets[npreset][n]); - if (insertion!=0) changepar(0,presets[npreset][0]/2);//lower the volume if reverb is insertion effect - Ppreset=npreset; -}; - - -void Reverb::changepar(const int &npar,const unsigned char &value) -{ - switch (npar) { - case 0: - setvolume(value); - break; - case 1: - setpan(value); - break; - case 2: - settime(value); - break; - case 3: - setidelay(value); - break; - case 4: - setidelayfb(value); - break; -// case 5: setrdelay(value); -// break; -// case 6: seterbalance(value); -// break; - case 7: - setlpf(value); - break; - case 8: - sethpf(value); - break; - case 9: - setlohidamp(value); - break; - case 10: - settype(value); - break; - case 11: - setroomsize(value); - break; - case 12: - setbandwidth(value); - break; - }; -}; - -unsigned char Reverb::getpar(const int &npar)const -{ - switch (npar) { - case 0: - return(Pvolume); - break; - case 1: - return(Ppan); - break; - case 2: - return(Ptime); - break; - case 3: - return(Pidelay); - break; - case 4: - return(Pidelayfb); - break; -// case 5: return(Prdelay); -// break; -// case 6: return(Perbalance); -// break; - case 7: - return(Plpf); - break; - case 8: - return(Phpf); - break; - case 9: - return(Plohidamp); - break; - case 10: - return(Ptype); - break; - case 11: - return(Proomsize); - break; - case 12: - return(Pbandwidth); - break; - }; - return(0);//in case of bogus "parameter" -}; - +/* + ZynAddSubFX - a software synthesizer + + Reverb.C - Reverberation effect + 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 or later) 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 <cmath> +#include "Reverb.h" + +/**\todo: EarlyReflections,Prdelay,Perbalance */ + +Reverb::Reverb(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0) +{ + inputbuf = new REALTYPE[SOUND_BUFFER_SIZE]; + + bandwidth = NULL; + + //defaults + Pvolume = 48; + Ppan = 64; + Ptime = 64; + Pidelay = 40; + Pidelayfb = 0; + Prdelay = 0; + Plpf = 127; + Phpf = 0; + Perbalance = 64; + Plohidamp = 80; + Ptype = 1; + Proomsize = 64; + Pbandwidth = 30; + roomsize = 1.0; + rs = 1.0; + + for(int i = 0; i < REV_COMBS * 2; i++) { + comblen[i] = 800 + (int)(RND * 1400); + combk[i] = 0; + lpcomb[i] = 0; + combfb[i] = -0.97; + comb[i] = NULL; + } + + for(int i = 0; i < REV_APS * 2; i++) { + aplen[i] = 500 + (int)(RND * 500); + apk[i] = 0; + ap[i] = NULL; + } + + lpf = NULL; + hpf = NULL; //no filter + idelay = NULL; + + setpreset(Ppreset); + cleanup(); //do not call this before the comb initialisation +} + + +Reverb::~Reverb() +{ + int i; + if(idelay != NULL) + delete [] idelay; + if(hpf != NULL) + delete hpf; + if(lpf != NULL) + delete lpf; + + for(i = 0; i < REV_APS * 2; i++) + delete [] ap[i]; + for(i = 0; i < REV_COMBS * 2; i++) + delete [] comb[i]; + + delete [] inputbuf; + if(bandwidth) + delete bandwidth; +} + +/* + * Cleanup the effect + */ +void Reverb::cleanup() +{ + int i, j; + for(i = 0; i < REV_COMBS * 2; i++) { + lpcomb[i] = 0.0; + for(j = 0; j < comblen[i]; j++) + comb[i][j] = 0.0; + } + + for(i = 0; i < REV_APS * 2; i++) + for(j = 0; j < aplen[i]; j++) + ap[i][j] = 0.0; + + if(idelay != NULL) + for(i = 0; i < idelaylen; i++) + idelay[i] = 0.0; + + if(hpf != NULL) + hpf->cleanup(); + if(lpf != NULL) + lpf->cleanup(); +} + +/* + * Process one channel; 0=left,1=right + */ +void Reverb::processmono(int ch, REALTYPE *output) +{ + int i, j; + REALTYPE fbout, tmp; + /**\todo: implement the high part from lohidamp*/ + + for(j = REV_COMBS * ch; j < REV_COMBS * (ch + 1); j++) { + int ck = combk[j]; + int comblength = comblen[j]; + REALTYPE lpcombj = lpcomb[j]; + + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + fbout = comb[j][ck] * combfb[j]; + fbout = fbout * (1.0 - lohifb) + lpcombj * lohifb; + lpcombj = fbout; + + comb[j][ck] = inputbuf[i] + fbout; + output[i] += fbout; + + if((++ck) >= comblength) + ck = 0; + } + + combk[j] = ck; + lpcomb[j] = lpcombj; + } + + for(j = REV_APS * ch; j < REV_APS * (1 + ch); j++) { + int ak = apk[j]; + int aplength = aplen[j]; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tmp = ap[j][ak]; + ap[j][ak] = 0.7 * tmp + output[i]; + output[i] = tmp - 0.7 * ap[j][ak]; + if((++ak) >= aplength) + ak = 0; + } + apk[j] = ak; + } +} + +/* + * Effect output + */ +void Reverb::out(REALTYPE *smps_l, REALTYPE *smps_r) +{ + int i; + if((Pvolume == 0) && (insertion != 0)) + return; + + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + inputbuf[i] = (smps_l[i] + smps_r[i]) / 2.0; + ; + + if(idelay != NULL) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + //Initial delay r + REALTYPE tmp = inputbuf[i] + idelay[idelayk] * idelayfb; + inputbuf[i] = idelay[idelayk]; + idelay[idelayk] = tmp; + idelayk++; + if(idelayk >= idelaylen) + idelayk = 0; + ; + } + } + + if(bandwidth) + bandwidth->process(SOUND_BUFFER_SIZE, inputbuf); + + if(lpf != NULL) + lpf->filterout(inputbuf); + if(hpf != NULL) + hpf->filterout(inputbuf); + + processmono(0, efxoutl); //left + processmono(1, efxoutr); //right + + REALTYPE lvol = rs / REV_COMBS * pan; + REALTYPE rvol = rs / REV_COMBS * (1.0 - pan); + if(insertion != 0) { + lvol *= 2; + rvol *= 2; + } + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + efxoutl[i] *= lvol; + efxoutr[i] *= rvol; + } +} + + +/* + * Parameter control + */ +void Reverb::setvolume(const unsigned char &Pvolume) +{ + this->Pvolume = Pvolume; + if(insertion == 0) { + outvolume = pow(0.01, (1.0 - Pvolume / 127.0)) * 4.0; + volume = 1.0; + } + else { + volume = outvolume = Pvolume / 127.0; + if(Pvolume == 0) + cleanup(); + } +} + +void Reverb::setpan(const unsigned char &Ppan) +{ + this->Ppan = Ppan; + pan = (REALTYPE)Ppan / 127.0; +} + +void Reverb::settime(const unsigned char &Ptime) +{ + int i; + REALTYPE t; + this->Ptime = Ptime; + t = pow(60.0, (REALTYPE)Ptime / 127.0) - 0.97; + + for(i = 0; i < REV_COMBS * 2; i++) + combfb[i] = + -exp((REALTYPE)comblen[i] / (REALTYPE)SAMPLE_RATE * log(0.001) / t); + //the feedback is negative because it removes the DC + ; +} + +void Reverb::setlohidamp(unsigned char Plohidamp) +{ + REALTYPE x; + + if(Plohidamp < 64) + Plohidamp = 64; //remove this when the high part from lohidamp will be added + + this->Plohidamp = Plohidamp; + if(Plohidamp == 64) { + lohidamptype = 0; + lohifb = 0.0; + } + else { + if(Plohidamp < 64) + lohidamptype = 1; + if(Plohidamp > 64) + lohidamptype = 2; + x = fabs((REALTYPE)(Plohidamp - 64) / 64.1); + lohifb = x * x; + } +} + +void Reverb::setidelay(const unsigned char &Pidelay) +{ + REALTYPE delay; + this->Pidelay = Pidelay; + delay = pow(50 * Pidelay / 127.0, 2) - 1.0; + + if(idelay != NULL) + delete [] idelay; + idelay = NULL; + + idelaylen = (int) (SAMPLE_RATE * delay / 1000); + if(idelaylen > 1) { + idelayk = 0; + idelay = new REALTYPE[idelaylen]; + for(int i = 0; i < idelaylen; i++) + idelay[i] = 0.0; + } +} + +void Reverb::setidelayfb(const unsigned char &Pidelayfb) +{ + this->Pidelayfb = Pidelayfb; + idelayfb = Pidelayfb / 128.0; +} + +void Reverb::sethpf(const unsigned char &Phpf) +{ + this->Phpf = Phpf; + if(Phpf == 0) { //No HighPass + if(hpf != NULL) + delete hpf; + hpf = NULL; + } + else { + REALTYPE fr = exp(pow(Phpf / 127.0, 0.5) * log(10000.0)) + 20.0; + if(hpf == NULL) + hpf = new AnalogFilter(3, fr, 1, 0); + else + hpf->setfreq(fr); + } +} + +void Reverb::setlpf(const unsigned char &Plpf) +{ + this->Plpf = Plpf; + if(Plpf == 127) { //No LowPass + if(lpf != NULL) + delete lpf; + lpf = NULL; + } + else { + REALTYPE fr = exp(pow(Plpf / 127.0, 0.5) * log(25000.0)) + 40; + if(lpf == NULL) + lpf = new AnalogFilter(2, fr, 1, 0); + else + lpf->setfreq(fr); + } +} + +void Reverb::settype(unsigned char Ptype) +{ + const int NUM_TYPES = 3; + int combtunings[NUM_TYPES][REV_COMBS] = { + //this is unused (for random) + {0, 0, 0, 0, 0, 0, 0, 0 }, + //Freeverb by Jezar at Dreampoint + {1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617 }, + //Freeverb by Jezar at Dreampoint //duplicate + {1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617 } + }; + int aptunings[NUM_TYPES][REV_APS] = { + //this is unused (for random) + {0, 0, 0, 0 }, + //Freeverb by Jezar at Dreampoint + {225, 341, 441, 556 }, + //Freeverb by Jezar at Dreampoint (duplicate) + {225, 341, 441, 556 } + }; + + if(Ptype >= NUM_TYPES) + Ptype = NUM_TYPES - 1; + this->Ptype = Ptype; + + REALTYPE tmp; + for(int i = 0; i < REV_COMBS * 2; i++) { + if(Ptype == 0) + tmp = 800.0 + (int)(RND * 1400.0); + else + tmp = combtunings[Ptype][i % REV_COMBS]; + tmp *= roomsize; + if(i > REV_COMBS) + tmp += 23.0; + tmp *= SAMPLE_RATE / 44100.0; //adjust the combs according to the samplerate + if(tmp < 10) + tmp = 10; + + comblen[i] = (int) tmp; + combk[i] = 0; + lpcomb[i] = 0; + if(comb[i] != NULL) + delete [] comb[i]; + comb[i] = new REALTYPE[comblen[i]]; + } + + for(int i = 0; i < REV_APS * 2; i++) { + if(Ptype == 0) + tmp = 500 + (int)(RND * 500); + else + tmp = aptunings[Ptype][i % REV_APS]; + tmp *= roomsize; + if(i > REV_APS) + tmp += 23.0; + tmp *= SAMPLE_RATE / 44100.0; //adjust the combs according to the samplerate + if(tmp < 10) + tmp = 10; + aplen[i] = (int) tmp; + apk[i] = 0; + if(ap[i] != NULL) + delete [] ap[i]; + ap[i] = new REALTYPE[aplen[i]]; + } + settime(Ptime); + cleanup(); + if(bandwidth) + delete bandwidth; + bandwidth = NULL; + if(Ptype == 2) { //bandwidth + bandwidth = new Unison(SOUND_BUFFER_SIZE / 4 + 1, 2.0); + bandwidth->set_size(50); + bandwidth->set_base_frequency(1.0); +#warning sa schimb size-ul + } +} + +void Reverb::setroomsize(const unsigned char &Proomsize) +{ + this->Proomsize = Proomsize; + if(Proomsize == 0) + this->Proomsize = 64; //this is because the older versions consider roomsize=0 + roomsize = (this->Proomsize - 64.0) / 64.0; + if(roomsize > 0.0) + roomsize *= 2.0; + roomsize = pow(10.0, roomsize); + rs = sqrt(roomsize); + settype(Ptype); +} + +void Reverb::setbandwidth(const unsigned char &Pbandwidth) { + this->Pbandwidth = Pbandwidth; + REALTYPE v = Pbandwidth / 127.0; + if(bandwidth) + bandwidth->set_bandwidth(pow(v, 2.0) * 200.0); +} + +void Reverb::setpreset(unsigned char npreset) +{ + const int PRESET_SIZE = 13; + const int NUM_PRESETS = 13; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { + //Cathedral1 + {80, 64, 63, 24, 0, 0, 0, 85, 5, 83, 1, 64, 20 }, + //Cathedral2 + {80, 64, 69, 35, 0, 0, 0, 127, 0, 71, 0, 64, 20 }, + //Cathedral3 + {80, 64, 69, 24, 0, 0, 0, 127, 75, 78, 1, 85, 20 }, + //Hall1 + {90, 64, 51, 10, 0, 0, 0, 127, 21, 78, 1, 64, 20 }, + //Hall2 + {90, 64, 53, 20, 0, 0, 0, 127, 75, 71, 1, 64, 20 }, + //Room1 + {100, 64, 33, 0, 0, 0, 0, 127, 0, 106, 0, 30, 20 }, + //Room2 + {100, 64, 21, 26, 0, 0, 0, 62, 0, 77, 1, 45, 20 }, + //Basement + {110, 64, 14, 0, 0, 0, 0, 127, 5, 71, 0, 25, 20 }, + //Tunnel + {85, 80, 84, 20, 42, 0, 0, 51, 0, 78, 1, 105, 20 }, + //Echoed1 + {95, 64, 26, 60, 71, 0, 0, 114, 0, 64, 1, 64, 20 }, + //Echoed2 + {90, 64, 40, 88, 71, 0, 0, 114, 0, 88, 1, 64, 20 }, + //VeryLong1 + {90, 64, 93, 15, 0, 0, 0, 114, 0, 77, 0, 95, 20 }, + //VeryLong2 + {90, 64, 111, 30, 0, 0, 0, 114, 90, 74, 1, 80, 20 } + }; + + if(npreset >= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); + if(insertion != 0) + changepar(0, presets[npreset][0] / 2); //lower the volume if reverb is insertion effect + Ppreset = npreset; +} + + +void Reverb::changepar(const int &npar, const unsigned char &value) +{ + switch(npar) { + case 0: + setvolume(value); + break; + case 1: + setpan(value); + break; + case 2: + settime(value); + break; + case 3: + setidelay(value); + break; + case 4: + setidelayfb(value); + break; +// case 5: setrdelay(value); +// break; +// case 6: seterbalance(value); +// break; + case 7: + setlpf(value); + break; + case 8: + sethpf(value); + break; + case 9: + setlohidamp(value); + break; + case 10: + settype(value); + break; + case 11: + setroomsize(value); + break; + case 12: + setbandwidth(value); + break; + } +} + +unsigned char Reverb::getpar(const int &npar) const +{ + switch(npar) { + case 0: + return Pvolume; + break; + case 1: + return Ppan; + break; + case 2: + return Ptime; + break; + case 3: + return Pidelay; + break; + case 4: + return Pidelayfb; + break; +// case 5: return(Prdelay); +// break; +// case 6: return(Perbalance); +// break; + case 7: + return Plpf; + break; + case 8: + return Phpf; + break; + case 9: + return Plohidamp; + break; + case 10: + return Ptype; + break; + case 11: + return Proomsize; + break; + case 12: + return Pbandwidth; + break; + } + return 0; //in case of bogus "parameter" +} + diff --git a/src/Effects/Reverb.h b/src/Effects/Reverb.h @@ -1,135 +1,135 @@ -/* - ZynAddSubFX - a software synthesizer - - Reverb.h - Reverberation effect - Copyright (C) 2002-2009 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 or later) 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 - -*/ - -#ifndef REVERB_H -#define REVERB_H - -#include <math.h> -#include "../globals.h" -#include "../DSP/AnalogFilter.h" -#include "../DSP/FFTwrapper.h" -#include "../DSP/Unison.h" -#include "Effect.h" - -#define REV_COMBS 8 -#define REV_APS 4 - -/**Creates Reverberation Effects*/ - -class Reverb:public Effect -{ -public: - Reverb(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); - ~Reverb(); - void out(REALTYPE *smps_l,REALTYPE *smps_r); - void cleanup(); - - void setpreset(unsigned char npreset); - void changepar(const int &npar,const unsigned char &value); - unsigned char getpar(const int &npar)const; - -private: - //Parametrii - /**Amount of the reverb*/ - unsigned char Pvolume; - - /**Left/Right Panning*/ - unsigned char Ppan; - - /**duration of reverb*/ - unsigned char Ptime; - - /**Initial delay*/ - unsigned char Pidelay; - - /**Initial delay feedback*/ - unsigned char Pidelayfb; - - /**delay between ER/Reverbs*/ - unsigned char Prdelay; - - /**EarlyReflections/Reverb Balance*/ - unsigned char Perbalance; - - /**HighPassFilter*/ - unsigned char Plpf; - - /**LowPassFilter*/ - unsigned char Phpf; - - /**Low/HighFrequency Damping - * \todo 0..63 lpf,64=off,65..127=hpf(TODO)*/ - unsigned char Plohidamp; - - /**Reverb type*/ - unsigned char Ptype; - - /**Room Size*/ - unsigned char Proomsize; - - /**Bandwidth */ - unsigned char Pbandwidth; - - //parameter control - void setvolume(const unsigned char &Pvolume); - void setpan(const unsigned char &Ppan); - void settime(const unsigned char &Ptime); - void setlohidamp(unsigned char Plohidamp); - void setidelay(const unsigned char &Pidelay); - void setidelayfb(const unsigned char &Pidelayfb); - void sethpf(const unsigned char &Phpf); - void setlpf(const unsigned char &Plpf); - void settype( unsigned char Ptype); - void setroomsize(const unsigned char &Proomsize); - void setbandwidth(const unsigned char &Pbandwidth); - - REALTYPE pan,erbalance; - //Parameters - int lohidamptype;/**<0=disable,1=highdamp(lowpass),2=lowdamp(highpass)*/ - int idelaylen,rdelaylen; - int idelayk; - REALTYPE lohifb,idelayfb,roomsize,rs;//rs is used to "normalise" the volume according to the roomsize - int comblen[REV_COMBS*2]; - int aplen[REV_APS*2]; - Unison *bandwidth; - - //Internal Variables - - REALTYPE *comb[REV_COMBS*2]; - - int combk[REV_COMBS*2]; - REALTYPE combfb[REV_COMBS*2];/**<feedback-ul fiecarui filtru "comb"*/ - REALTYPE lpcomb[REV_COMBS*2];/**<pentru Filtrul LowPass*/ - - REALTYPE *ap[REV_APS*2]; - - int apk[REV_APS*2]; - - REALTYPE *idelay; - AnalogFilter *lpf,*hpf;//filters - REALTYPE *inputbuf; - - void processmono(int ch,REALTYPE *output); -}; - -#endif - +/* + ZynAddSubFX - a software synthesizer + + Reverb.h - Reverberation effect + Copyright (C) 2002-2009 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 or later) 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 + +*/ + +#ifndef REVERB_H +#define REVERB_H + +#include <math.h> +#include "../globals.h" +#include "../DSP/AnalogFilter.h" +#include "../DSP/FFTwrapper.h" +#include "../DSP/Unison.h" +#include "Effect.h" + +#define REV_COMBS 8 +#define REV_APS 4 + +/**Creates Reverberation Effects*/ + +class Reverb:public Effect +{ + public: + Reverb(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_); + ~Reverb(); + void out(REALTYPE *smps_l, REALTYPE *smps_r); + void cleanup(); + + void setpreset(unsigned char npreset); + void changepar(const int &npar, const unsigned char &value); + unsigned char getpar(const int &npar) const; + + private: + //Parametrii + /**Amount of the reverb*/ + unsigned char Pvolume; + + /**Left/Right Panning*/ + unsigned char Ppan; + + /**duration of reverb*/ + unsigned char Ptime; + + /**Initial delay*/ + unsigned char Pidelay; + + /**Initial delay feedback*/ + unsigned char Pidelayfb; + + /**delay between ER/Reverbs*/ + unsigned char Prdelay; + + /**EarlyReflections/Reverb Balance*/ + unsigned char Perbalance; + + /**HighPassFilter*/ + unsigned char Plpf; + + /**LowPassFilter*/ + unsigned char Phpf; + + /**Low/HighFrequency Damping + * \todo 0..63 lpf,64=off,65..127=hpf(TODO)*/ + unsigned char Plohidamp; + + /**Reverb type*/ + unsigned char Ptype; + + /**Room Size*/ + unsigned char Proomsize; + + /**Bandwidth */ + unsigned char Pbandwidth; + + //parameter control + void setvolume(const unsigned char &Pvolume); + void setpan(const unsigned char &Ppan); + void settime(const unsigned char &Ptime); + void setlohidamp(unsigned char Plohidamp); + void setidelay(const unsigned char &Pidelay); + void setidelayfb(const unsigned char &Pidelayfb); + void sethpf(const unsigned char &Phpf); + void setlpf(const unsigned char &Plpf); + void settype(unsigned char Ptype); + void setroomsize(const unsigned char &Proomsize); + void setbandwidth(const unsigned char &Pbandwidth); + + REALTYPE pan, erbalance; + //Parameters + int lohidamptype; /**<0=disable,1=highdamp(lowpass),2=lowdamp(highpass)*/ + int idelaylen, rdelaylen; + int idelayk; + REALTYPE lohifb, idelayfb, roomsize, rs; //rs is used to "normalise" the volume according to the roomsize + int comblen[REV_COMBS * 2]; + int aplen[REV_APS * 2]; + Unison *bandwidth; + + //Internal Variables + + REALTYPE *comb[REV_COMBS * 2]; + + int combk[REV_COMBS * 2]; + REALTYPE combfb[REV_COMBS * 2]; /**<feedback-ul fiecarui filtru "comb"*/ + REALTYPE lpcomb[REV_COMBS * 2]; /**<pentru Filtrul LowPass*/ + + REALTYPE *ap[REV_APS * 2]; + + int apk[REV_APS * 2]; + + REALTYPE *idelay; + AnalogFilter *lpf, *hpf; //filters + REALTYPE *inputbuf; + + void processmono(int ch, REALTYPE *output); +}; + +#endif + diff --git a/src/Input/ALSAMidiIn.cpp b/src/Input/ALSAMidiIn.cpp @@ -25,80 +25,88 @@ ALSAMidiIn::ALSAMidiIn() { int alsaport; - inputok=false; + inputok = false; - midi_handle=NULL; + midi_handle = NULL; - if (snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_INPUT,0)!=0) return; + if(snd_seq_open(&midi_handle, "default", SND_SEQ_OPEN_INPUT, 0) != 0) + return; - snd_seq_set_client_name(midi_handle,"ZynAddSubFX");//thanks to Frank Neumann + snd_seq_set_client_name(midi_handle, "ZynAddSubFX"); //thanks to Frank Neumann - alsaport = snd_seq_create_simple_port(midi_handle,"ZynAddSubFX" - ,SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE - ,SND_SEQ_PORT_TYPE_SYNTH); - if (alsaport<0) return; + alsaport = snd_seq_create_simple_port( + midi_handle, + "ZynAddSubFX", + SND_SEQ_PORT_CAP_WRITE + | SND_SEQ_PORT_CAP_SUBS_WRITE, + SND_SEQ_PORT_TYPE_SYNTH); + if(alsaport < 0) + return; - inputok=true; -}; + inputok = true; +} ALSAMidiIn::~ALSAMidiIn() { - if (midi_handle) snd_seq_close(midi_handle); -}; + if(midi_handle) + snd_seq_close(midi_handle); +} /* * Get the midi command,channel and parameters */ -void ALSAMidiIn::getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams) +void ALSAMidiIn::getmidicmd(MidiCmdType &cmdtype, + unsigned char &cmdchan, + int *cmdparams) { - snd_seq_event_t *midievent=NULL; - cmdtype=MidiNull; + snd_seq_event_t *midievent = NULL; + cmdtype = MidiNull; - if (inputok==false) { + if(inputok == false) { /* The input is broken. We need to block for a while anyway so other non-RT threads get a chance to run. */ sleep(1); return; - }; + } - snd_seq_event_input(midi_handle,&midievent); + snd_seq_event_input(midi_handle, &midievent); - if (midievent==NULL) return; - switch (midievent->type) { + if(midievent == NULL) + return; + switch(midievent->type) { case SND_SEQ_EVENT_NOTEON: - cmdtype=MidiNoteON; - cmdchan=midievent->data.note.channel; - cmdparams[0]=midievent->data.note.note; - cmdparams[1]=midievent->data.note.velocity; + cmdtype = MidiNoteON; + cmdchan = midievent->data.note.channel; + cmdparams[0] = midievent->data.note.note; + cmdparams[1] = midievent->data.note.velocity; break; case SND_SEQ_EVENT_NOTEOFF: - cmdtype=MidiNoteOFF; - cmdchan=midievent->data.note.channel; - cmdparams[0]=midievent->data.note.note; + cmdtype = MidiNoteOFF; + cmdchan = midievent->data.note.channel; + cmdparams[0] = midievent->data.note.note; break; case SND_SEQ_EVENT_PITCHBEND: - cmdtype=MidiController; - cmdchan=midievent->data.control.channel; - cmdparams[0]=C_pitchwheel;//Pitch Bend - cmdparams[1]=midievent->data.control.value; + cmdtype = MidiController; + cmdchan = midievent->data.control.channel; + cmdparams[0] = C_pitchwheel; //Pitch Bend + cmdparams[1] = midievent->data.control.value; break; case SND_SEQ_EVENT_CONTROLLER: - cmdtype=MidiController; - cmdchan=midievent->data.control.channel; - cmdparams[0]=getcontroller(midievent->data.control.param); - cmdparams[1]=midievent->data.control.value; + cmdtype = MidiController; + cmdchan = midievent->data.control.channel; + cmdparams[0] = getcontroller(midievent->data.control.param); + cmdparams[1] = midievent->data.control.value; //fprintf(stderr,"t=%d val=%d\n",midievent->data.control.param,midievent->data.control.value); break; - - }; -}; + } +} int ALSAMidiIn::getalsaid() { - if (midi_handle) { - snd_seq_client_info_t* seq_info; + if(midi_handle) { + snd_seq_client_info_t *seq_info; snd_seq_client_info_malloc(&seq_info); snd_seq_get_client_info(midi_handle, seq_info); int id = snd_seq_client_info_get_client(seq_info); diff --git a/src/Input/ALSAMidiIn.h b/src/Input/ALSAMidiIn.h @@ -30,19 +30,21 @@ /**Midi input for ALSA (this creates an ALSA virtual port)*/ class ALSAMidiIn:public MidiIn { -public: - /**Constructor*/ - ALSAMidiIn(); - /**Destructor*/ - ~ALSAMidiIn(); - - void getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams); - /**Get the ALSA id - * @return ALSA id*/ - int getalsaid(); - -private: - snd_seq_t *midi_handle; + public: + /**Constructor*/ + ALSAMidiIn(); + /**Destructor*/ + ~ALSAMidiIn(); + + void getmidicmd(MidiCmdType &cmdtype, + unsigned char &cmdchan, + int *cmdparams); + /**Get the ALSA id + * @return ALSA id*/ + int getalsaid(); + + private: + snd_seq_t *midi_handle; }; #endif diff --git a/src/Input/MidiIn.cpp b/src/Input/MidiIn.cpp @@ -26,70 +26,71 @@ int MidiIn::getcontroller(unsigned char b) { /**\todo there might be a better way to do this*/ - int ctl=C_NULL; - switch (b) { + int ctl = C_NULL; + switch(b) { case 1: - ctl=C_modwheel;//Modulation Wheel + ctl = C_modwheel; //Modulation Wheel break; case 7: - ctl=C_volume;//Volume + ctl = C_volume; //Volume break; case 10: - ctl=C_panning;//Panning + ctl = C_panning; //Panning break; case 11: - ctl=C_expression;//Expression + ctl = C_expression; //Expression break; case 64: - ctl=C_sustain;//Sustain pedal + ctl = C_sustain; //Sustain pedal break; case 65: - ctl=C_portamento;//Portamento + ctl = C_portamento; //Portamento break; case 71: - ctl=C_filterq;//Filter Q (Sound Timbre) + ctl = C_filterq; //Filter Q (Sound Timbre) break; case 74: - ctl=C_filtercutoff;//Filter Cutoff (Brightness) + ctl = C_filtercutoff; //Filter Cutoff (Brightness) break; case 75: - ctl=C_bandwidth;//BandWidth + ctl = C_bandwidth; //BandWidth break; case 76: - ctl=C_fmamp;//FM amplitude + ctl = C_fmamp; //FM amplitude break; case 77: - ctl=C_resonance_center;//Resonance Center Frequency + ctl = C_resonance_center; //Resonance Center Frequency break; case 78: - ctl=C_resonance_bandwidth;//Resonance Bandwith + ctl = C_resonance_bandwidth; //Resonance Bandwith break; case 120: - ctl=C_allsoundsoff;//All Sounds OFF + ctl = C_allsoundsoff; //All Sounds OFF break; case 121: - ctl=C_resetallcontrollers;//Reset All Controllers + ctl = C_resetallcontrollers; //Reset All Controllers break; case 123: - ctl=C_allnotesoff;//All Notes OFF + ctl = C_allnotesoff; //All Notes OFF break; - //RPN and NRPN + //RPN and NRPN case 0x06: - ctl=C_dataentryhi;//Data Entry (Coarse) + ctl = C_dataentryhi; //Data Entry (Coarse) break; case 0x26: - ctl=C_dataentrylo;//Data Entry (Fine) + ctl = C_dataentrylo; //Data Entry (Fine) break; case 99: - ctl=C_nrpnhi;//NRPN (Coarse) + ctl = C_nrpnhi; //NRPN (Coarse) break; case 98: - ctl=C_nrpnlo;//NRPN (Fine) + ctl = C_nrpnlo; //NRPN (Fine) break; default: - ctl=C_NULL;//unknown controller + ctl = C_NULL; //unknown controller //fprintf(stderr,"Controller=%d , par=%d\n",midievent->data.control.param,cmdparams[1]); break; - }; - return(ctl); -}; + } + return ctl; +} + diff --git a/src/Input/MidiIn.h b/src/Input/MidiIn.h @@ -25,23 +25,27 @@ #include "../globals.h" -enum MidiCmdType {MidiNull,MidiNoteOFF,MidiNoteON,MidiController}; +enum MidiCmdType { + MidiNull, MidiNoteOFF, MidiNoteON, MidiController +}; #define MP_MAX_BYTES 4000 //in case of loooong SYS_EXes /**This class is inherited by all the Midi input classes*/ class MidiIn { -public: - /**Get the command,channel and parameters of the MIDI - * - * \todo make pure virtual - * @param cmdtype the referece to the variable that will store the type - * @param cmdchan the channel for the event - * @param parameters for the event*/ - virtual void getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams)=0; - int getcontroller(unsigned char b); -protected: - bool inputok;/**<1 if I can read midi bytes from input ports*/ + public: + /**Get the command,channel and parameters of the MIDI + * + * \todo make pure virtual + * @param cmdtype the referece to the variable that will store the type + * @param cmdchan the channel for the event + * @param parameters for the event*/ + virtual void getmidicmd(MidiCmdType &cmdtype, + unsigned char &cmdchan, + int *cmdparams) = 0; + int getcontroller(unsigned char b); + protected: + bool inputok; /**<1 if I can read midi bytes from input ports*/ }; #endif diff --git a/src/Input/NULLMidiIn.cpp b/src/Input/NULLMidiIn.cpp @@ -23,19 +23,19 @@ #include "NULLMidiIn.h" NULLMidiIn::NULLMidiIn() -{ -}; +{} NULLMidiIn::~NULLMidiIn() -{ -}; +{} /* * Get the midi command,channel and parameters * It returns MidiNull because it is a dummy driver */ -void NULLMidiIn::getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams) +void NULLMidiIn::getmidicmd(MidiCmdType &cmdtype, + unsigned char &cmdchan, + int *cmdparams) { - cmdtype=MidiNull; -}; + cmdtype = MidiNull; +} diff --git a/src/Input/NULLMidiIn.h b/src/Input/NULLMidiIn.h @@ -29,19 +29,21 @@ /**a dummy Midi port*/ class NULLMidiIn:public MidiIn { -public: - /**Dummy Constructor - * \todo see if the default constructor would work here*/ - NULLMidiIn(); - /**Dummy Destructor - * \todo see if the default destructor would work here*/ - ~NULLMidiIn(); - /**Get the midi command,channel and parameters - * It returns MidiNull because it is a dummy driver - */ - void getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams); - -private: + public: + /**Dummy Constructor + * \todo see if the default constructor would work here*/ + NULLMidiIn(); + /**Dummy Destructor + * \todo see if the default destructor would work here*/ + ~NULLMidiIn(); + /**Get the midi command,channel and parameters + * It returns MidiNull because it is a dummy driver + */ + void getmidicmd(MidiCmdType &cmdtype, + unsigned char &cmdchan, + int *cmdparams); + + private: }; #endif diff --git a/src/Input/OSSMidiIn.cpp b/src/Input/OSSMidiIn.cpp @@ -33,88 +33,91 @@ OSSMidiIn::OSSMidiIn() { - inputok=false; - midi_handle=open(config.cfg.LinuxOSSSeqInDev,O_RDONLY,0); - if (midi_handle!=-1) inputok=true; + inputok = false; + midi_handle = open(config.cfg.LinuxOSSSeqInDev, O_RDONLY, 0); + if(midi_handle != -1) + inputok = true; - lastmidicmd=0; - cmdtype=0; - cmdchan=0; - -}; + lastmidicmd = 0; + cmdtype = 0; + cmdchan = 0; +} OSSMidiIn::~OSSMidiIn() { close(midi_handle); -}; +} unsigned char OSSMidiIn::readbyte() { unsigned char tmp[4]; - read(midi_handle,&tmp[0],1); - while (tmp[0]!=SEQ_MIDIPUTC) { - read(midi_handle,&tmp[0],4); + read(midi_handle, &tmp[0], 1); + while(tmp[0] != SEQ_MIDIPUTC) { + read(midi_handle, &tmp[0], 4); } - return(tmp[1]); -}; + return tmp[1]; +} unsigned char OSSMidiIn::getmidibyte() { unsigned char b; do { - b=readbyte(); - } while (b==0xfe);//drops the Active Sense Messages - return(b); -}; + b = readbyte(); + } while(b == 0xfe); //drops the Active Sense Messages + return b; +} /* * Get the midi command,channel and parameters */ -void OSSMidiIn::getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams) +void OSSMidiIn::getmidicmd(MidiCmdType &cmdtype, + unsigned char &cmdchan, + int *cmdparams) { - unsigned char tmp,i; - if (inputok==false) { - cmdtype=MidiNull; + unsigned char tmp, i; + if(inputok == false) { + cmdtype = MidiNull; return; } - i=0; - if (lastmidicmd==0) {//asteapta prima data pana cand vine prima comanda midi - while (tmp<0x80) tmp=getmidibyte(); - lastmidicmd=tmp; + i = 0; + if(lastmidicmd == 0) { //asteapta prima data pana cand vine prima comanda midi + while(tmp < 0x80) + tmp = getmidibyte(); + lastmidicmd = tmp; } - tmp=getmidibyte(); + tmp = getmidibyte(); - if (tmp>=0x80) { - lastmidicmd=tmp; - tmp=getmidibyte(); + if(tmp >= 0x80) { + lastmidicmd = tmp; + tmp = getmidibyte(); } - if ((lastmidicmd>=0x80)&&(lastmidicmd<=0x8f)) {//Note OFF - cmdtype=MidiNoteOFF; - cmdchan=lastmidicmd%16; - cmdparams[0]=tmp;//note number + if((lastmidicmd >= 0x80) && (lastmidicmd <= 0x8f)) { //Note OFF + cmdtype = MidiNoteOFF; + cmdchan = lastmidicmd % 16; + cmdparams[0] = tmp; //note number } - if ((lastmidicmd>=0x90)&&(lastmidicmd<=0x9f)) {//Note ON - cmdtype=MidiNoteON; - cmdchan=lastmidicmd%16; - cmdparams[0]=tmp;//note number - cmdparams[1]=getmidibyte();//velocity - if (cmdparams[1]==0) cmdtype=MidiNoteOFF;//if velocity==0 then is note off + if((lastmidicmd >= 0x90) && (lastmidicmd <= 0x9f)) { //Note ON + cmdtype = MidiNoteON; + cmdchan = lastmidicmd % 16; + cmdparams[0] = tmp; //note number + cmdparams[1] = getmidibyte(); //velocity + if(cmdparams[1] == 0) + cmdtype = MidiNoteOFF; //if velocity==0 then is note off } - if ((lastmidicmd>=0xB0)&&(lastmidicmd<=0xBF)) {//Controllers - cmdtype=MidiController; - cmdchan=lastmidicmd%16; - cmdparams[0]=getcontroller(tmp); - cmdparams[1]=getmidibyte(); + if((lastmidicmd >= 0xB0) && (lastmidicmd <= 0xBF)) { //Controllers + cmdtype = MidiController; + cmdchan = lastmidicmd % 16; + cmdparams[0] = getcontroller(tmp); + cmdparams[1] = getmidibyte(); } - if ((lastmidicmd>=0xE0)&&(lastmidicmd<=0xEF)) {//Pitch Wheel - cmdtype=MidiController; - cmdchan=lastmidicmd%16; - cmdparams[0]=C_pitchwheel; - cmdparams[1]=(tmp+getmidibyte()*(int) 128)-8192;//hope this is correct + if((lastmidicmd >= 0xE0) && (lastmidicmd <= 0xEF)) { //Pitch Wheel + cmdtype = MidiController; + cmdchan = lastmidicmd % 16; + cmdparams[0] = C_pitchwheel; + cmdparams[1] = (tmp + getmidibyte() * (int) 128) - 8192; //hope this is correct } -}; - +} diff --git a/src/Input/OSSMidiIn.h b/src/Input/OSSMidiIn.h @@ -27,21 +27,22 @@ class OSSMidiIn:public MidiIn { -public: - OSSMidiIn(); - ~OSSMidiIn(); - unsigned char getmidibyte(); - unsigned char readbyte(); - - //Midi parser - void getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams); - unsigned char cmdtype;//the Message Type (noteon,noteof,sysex..) - unsigned char cmdchan;//the channel number - -private: - int midi_handle; - unsigned char lastmidicmd;//last byte (>=80) received from the Midi - + public: + OSSMidiIn(); + ~OSSMidiIn(); + unsigned char getmidibyte(); + unsigned char readbyte(); + + //Midi parser + void getmidicmd(MidiCmdType &cmdtype, + unsigned char &cmdchan, + int *cmdparams); + unsigned char cmdtype; //the Message Type (noteon,noteof,sysex..) + unsigned char cmdchan; //the channel number + + private: + int midi_handle; + unsigned char lastmidicmd; //last byte (>=80) received from the Midi }; diff --git a/src/Input/WINMidiIn.cpp b/src/Input/WINMidiIn.cpp @@ -32,56 +32,63 @@ Master *winmaster; HMIDIIN winmidiinhandle; -MidiIn midictl;//used to convert the controllers to ZynAddSubFX controllers +MidiIn midictl; //used to convert the controllers to ZynAddSubFX controllers -void CALLBACK WinMidiInProc(HMIDIIN hMidiIn,UINT wMsg,DWORD dwInstance, - DWORD dwParam1,DWORD dwParam2) +void CALLBACK WinMidiInProc(HMIDIIN hMidiIn, UINT wMsg, DWORD dwInstance, + DWORD dwParam1, DWORD dwParam2) { - int midicommand=MidiNull; - if (wMsg==MIM_DATA) { - int cmd,par1,par2; - cmd=dwParam1&0xff; - if (cmd==0xfe) return; - par1=(dwParam1>>8)&0xff; - par2=dwParam1>>16; + int midicommand = MidiNull; + if(wMsg == MIM_DATA) { + int cmd, par1, par2; + cmd = dwParam1 & 0xff; + if(cmd == 0xfe) + return; + par1 = (dwParam1 >> 8) & 0xff; + par2 = dwParam1 >> 16; //printf("%x %x %x\n",cmd,par1,par2);fflush(stdout); - int cmdchan=cmd&0x0f; - int cmdtype=(cmd>>4)&0x0f; + int cmdchan = cmd & 0x0f; + int cmdtype = (cmd >> 4) & 0x0f; - int tmp=0; + int tmp = 0; pthread_mutex_lock(&winmaster->mutex); - switch (cmdtype) { - case(0x8)://noteon - winmaster->NoteOff(cmdchan,par1); + switch(cmdtype) { + case (0x8): //noteon + winmaster->NoteOff(cmdchan, par1); break; - case(0x9)://noteoff - winmaster->NoteOn(cmdchan,par1,par2&0xff); + case (0x9): //noteoff + winmaster->NoteOn(cmdchan, par1, par2 & 0xff); break; - case(0xb)://controller - winmaster->SetController(cmdchan,midictl.getcontroller(par1),par2&0xff); + case (0xb): //controller + winmaster->SetController(cmdchan, midictl.getcontroller( + par1), par2 & 0xff); break; - case(0xe)://pitch wheel - tmp=(par1+par2*(long int) 128)-8192; - winmaster->SetController(cmdchan,C_pitchwheel,tmp); + case (0xe): //pitch wheel + tmp = (par1 + par2 * (long int) 128) - 8192; + winmaster->SetController(cmdchan, C_pitchwheel, tmp); break; default: break; - }; + } pthread_mutex_unlock(&winmaster->mutex); - - }; -}; + } +} void InitWinMidi(Master *master_) { - winmaster=master_; + winmaster = master_; - long int result=midiInOpen(&winmidiinhandle,config.cfg.WindowsMidiInId,(DWORD)WinMidiInProc,0,CALLBACK_FUNCTION); - result=midiInStart(winmidiinhandle); -}; + long int result = + midiInOpen(&winmidiinhandle, + config.cfg.WindowsMidiInId, + (DWORD)WinMidiInProc, + 0, + CALLBACK_FUNCTION); + result = midiInStart(winmidiinhandle); +} void StopWinMidi() { midiInStop(winmidiinhandle); midiInClose(winmidiinhandle); -}; +} + diff --git a/src/Misc/Bank.cpp b/src/Misc/Bank.cpp @@ -41,183 +41,213 @@ Bank::Bank() { - - - ZERO(defaultinsname,PART_MAX_NAME_LEN); - snprintf(defaultinsname,PART_MAX_NAME_LEN,"%s"," "); - - for (int i=0;i<BANK_SIZE;i++) { - ins[i].used=false; - ins[i].filename=NULL; - ins[i].info.PADsynth_used=false; - }; - dirname=NULL; + ZERO(defaultinsname, PART_MAX_NAME_LEN); + snprintf(defaultinsname, PART_MAX_NAME_LEN, "%s", " "); + + for(int i = 0; i < BANK_SIZE; i++) { + ins[i].used = false; + ins[i].filename = NULL; + ins[i].info.PADsynth_used = false; + } + dirname = NULL; clearbank(); - for (int i=0;i<MAX_NUM_BANKS;i++) { - banks[i].dir=NULL; - banks[i].name=NULL; - }; + for(int i = 0; i < MAX_NUM_BANKS; i++) { + banks[i].dir = NULL; + banks[i].name = NULL; + } - bankfiletitle=dirname; + bankfiletitle = dirname; loadbank(config.cfg.currentBankDir); - -}; +} Bank::~Bank() { - for (int i=0;i<MAX_NUM_BANKS;i++) { - if (banks[i].dir!=NULL) delete []banks[i].dir; - if (banks[i].name!=NULL) delete []banks[i].name; - }; + for(int i = 0; i < MAX_NUM_BANKS; i++) { + if(banks[i].dir != NULL) + delete [] banks[i].dir; + if(banks[i].name != NULL) + delete [] banks[i].name; + } clearbank(); -}; +} /* * Get the name of an instrument from the bank */ -char *Bank::getname (unsigned int ninstrument) +char *Bank::getname(unsigned int ninstrument) { - if (emptyslot(ninstrument)) return (defaultinsname); - return (ins[ninstrument].name); -}; + if(emptyslot(ninstrument)) + return defaultinsname; + return ins[ninstrument].name; +} /* * Get the numbered name of an instrument from the bank */ -char *Bank::getnamenumbered (unsigned int ninstrument) +char *Bank::getnamenumbered(unsigned int ninstrument) { - if (emptyslot(ninstrument)) return (defaultinsname); - snprintf(tmpinsname[ninstrument],PART_MAX_NAME_LEN+15,"%d. %s",ninstrument+1,getname(ninstrument)); - return(tmpinsname[ninstrument]); -}; + if(emptyslot(ninstrument)) + return defaultinsname; + snprintf(tmpinsname[ninstrument], + PART_MAX_NAME_LEN + 15, + "%d. %s", + ninstrument + 1, + getname(ninstrument)); + return tmpinsname[ninstrument]; +} /* * Changes the name of an instrument (and the filename) */ -void Bank::setname(unsigned int ninstrument,const char *newname,int newslot) +void Bank::setname(unsigned int ninstrument, const char *newname, int newslot) { - if (emptyslot(ninstrument)) return; + if(emptyslot(ninstrument)) + return; - char newfilename[1000+1],tmpfilename[100+1]; + char newfilename[1000 + 1], tmpfilename[100 + 1]; - ZERO(newfilename,1001); - ZERO(tmpfilename,101); - if (newslot>=0) snprintf(tmpfilename,100,"%4d-%s",newslot+1,newname); - else snprintf(tmpfilename,100,"%4d-%s",ninstrument+1,newname); + ZERO(newfilename, 1001); + ZERO(tmpfilename, 101); + if(newslot >= 0) + snprintf(tmpfilename, 100, "%4d-%s", newslot + 1, newname); + else + snprintf(tmpfilename, 100, "%4d-%s", ninstrument + 1, newname); //add the zeroes at the start of filename - for (int i=0;i<4;i++) if (tmpfilename[i]==' ') tmpfilename[i]='0'; + for(int i = 0; i < 4; i++) + if(tmpfilename[i] == ' ') + tmpfilename[i] = '0'; //make the filenames legal - for (int i=0;i<(int) strlen(tmpfilename);i++) { - char c=tmpfilename[i]; - if ((c>='0')&&(c<='9')) continue; - if ((c>='A')&&(c<='Z')) continue; - if ((c>='a')&&(c<='z')) continue; - if ((c=='-')||(c==' ')) continue; - - tmpfilename[i]='_'; - }; - - snprintf(newfilename,1000,"%s/%s.xiz",dirname,tmpfilename); + for(int i = 0; i < (int) strlen(tmpfilename); i++) { + char c = tmpfilename[i]; + if((c >= '0') && (c <= '9')) + continue; + if((c >= 'A') && (c <= 'Z')) + continue; + if((c >= 'a') && (c <= 'z')) + continue; + if((c == '-') || (c == ' ')) + continue; + + tmpfilename[i] = '_'; + } + + snprintf(newfilename, 1000, "%s/%s.xiz", dirname, tmpfilename); // printf("rename %s -> %s\n",ins[ninstrument].filename,newfilename);////////////// - rename(ins[ninstrument].filename,newfilename); - if (ins[ninstrument].filename) delete []ins[ninstrument].filename; - ins[ninstrument].filename=new char[strlen(newfilename)+5]; - snprintf(ins[ninstrument].filename,strlen(newfilename)+1,"%s",newfilename); - snprintf(ins[ninstrument].name,PART_MAX_NAME_LEN,"%s",&tmpfilename[5]); - -}; + rename(ins[ninstrument].filename, newfilename); + if(ins[ninstrument].filename) + delete [] ins[ninstrument].filename; + ins[ninstrument].filename = new char[strlen(newfilename) + 5]; + snprintf(ins[ninstrument].filename, strlen( + newfilename) + 1, "%s", newfilename); + snprintf(ins[ninstrument].name, PART_MAX_NAME_LEN, "%s", &tmpfilename[5]); +} /* * Check if there is no instrument on a slot from the bank */ int Bank::emptyslot(unsigned int ninstrument) { - if (ninstrument>=BANK_SIZE) return (1); - if (ins[ninstrument].filename==NULL) return(1); + if(ninstrument >= BANK_SIZE) + return 1; + if(ins[ninstrument].filename == NULL) + return 1; - if (ins[ninstrument].used) return (0); - else return(1); -}; + if(ins[ninstrument].used) + return 0; + else + return 1; +} /* * Removes the instrument from the bank */ void Bank::clearslot(unsigned int ninstrument) { - if (emptyslot(ninstrument)) return; + if(emptyslot(ninstrument)) + return; // printf("remove %s \n",ins[ninstrument].filename);//////////////////////// remove(ins[ninstrument].filename); deletefrombank(ninstrument); -}; +} /* * Save the instrument to a slot */ -void Bank::savetoslot(unsigned int ninstrument,Part *part) +void Bank::savetoslot(unsigned int ninstrument, Part *part) { clearslot(ninstrument); - const int maxfilename=200; - char tmpfilename[maxfilename+20]; - ZERO(tmpfilename,maxfilename+20); + const int maxfilename = 200; + char tmpfilename[maxfilename + 20]; + ZERO(tmpfilename, maxfilename + 20); - snprintf(tmpfilename,maxfilename,"%4d-%s",ninstrument+1,(char *)part->Pname); + snprintf(tmpfilename, + maxfilename, + "%4d-%s", + ninstrument + 1, + (char *)part->Pname); //add the zeroes at the start of filename - for (int i=0;i<4;i++) if (tmpfilename[i]==' ') tmpfilename[i]='0'; + for(int i = 0; i < 4; i++) + if(tmpfilename[i] == ' ') + tmpfilename[i] = '0'; //make the filenames legal - for (int i=0;i<(int)strlen(tmpfilename);i++) { - char c=tmpfilename[i]; - if ((c>='0')&&(c<='9')) continue; - if ((c>='A')&&(c<='Z')) continue; - if ((c>='a')&&(c<='z')) continue; - if ((c=='-')||(c==' ')) continue; + for(int i = 0; i < (int)strlen(tmpfilename); i++) { + char c = tmpfilename[i]; + if((c >= '0') && (c <= '9')) + continue; + if((c >= 'A') && (c <= 'Z')) + continue; + if((c >= 'a') && (c <= 'z')) + continue; + if((c == '-') || (c == ' ')) + continue; - tmpfilename[i]='_'; - }; + tmpfilename[i] = '_'; + } - strncat(tmpfilename,".xiz",maxfilename+10); + strncat(tmpfilename, ".xiz", maxfilename + 10); - int fnsize=strlen(dirname)+strlen(tmpfilename)+10; - char *filename=new char[fnsize+4]; - ZERO(filename,fnsize+2); + int fnsize = strlen(dirname) + strlen(tmpfilename) + 10; + char *filename = new char[fnsize + 4]; + ZERO(filename, fnsize + 2); - snprintf(filename,fnsize,"%s/%s",dirname,tmpfilename); + snprintf(filename, fnsize, "%s/%s", dirname, tmpfilename); remove(filename); part->saveXML(filename); - addtobank(ninstrument,tmpfilename,(char *) part->Pname); + addtobank(ninstrument, tmpfilename, (char *) part->Pname); - delete[]filename; -}; + delete[] filename; +} /* * Loads the instrument from the bank */ -void Bank::loadfromslot(unsigned int ninstrument,Part *part) +void Bank::loadfromslot(unsigned int ninstrument, Part *part) { - if (emptyslot(ninstrument)) return; + if(emptyslot(ninstrument)) + return; part->defaultsinstrument(); // printf("load: %s\n",ins[ninstrument].filename); part->loadXMLinstrument(ins[ninstrument].filename); - -}; +} /* @@ -225,160 +255,173 @@ void Bank::loadfromslot(unsigned int ninstrument,Part *part) */ int Bank::loadbank(const char *bankdirname) { - DIR *dir=opendir(bankdirname); + DIR *dir = opendir(bankdirname); clearbank(); - if (dir==NULL) return(-1); + if(dir == NULL) + return -1; - if (dirname!=NULL) delete[]dirname; - dirname=new char[strlen(bankdirname)+1]; - snprintf(dirname,strlen(bankdirname)+1,"%s",bankdirname); + if(dirname != NULL) + delete[] dirname; + dirname = new char[strlen(bankdirname) + 1]; + snprintf(dirname, strlen(bankdirname) + 1, "%s", bankdirname); - bankfiletitle=dirname; + bankfiletitle = dirname; // printf("loadbank %s/\n",bankdirname); struct dirent *fn; - while ((fn=readdir(dir))) { - const char *filename= fn->d_name; + while((fn = readdir(dir))) { + const char *filename = fn->d_name; //sa verific daca e si extensia dorita - if (strstr(filename,INSTRUMENT_EXTENSION)==NULL) continue; + if(strstr(filename, INSTRUMENT_EXTENSION) == NULL) + continue; //verify if the name is like this NNNN-name (where N is a digit) - int no=0; - unsigned int startname=0; + int no = 0; + unsigned int startname = 0; - for (unsigned int i=0;i<4;i++) { - if (strlen(filename)<=i) break; + for(unsigned int i = 0; i < 4; i++) { + if(strlen(filename) <= i) + break; - if ((filename[i]>='0')&&(filename[i]<='9')) { - no=no*10+(filename[i]-'0'); + if((filename[i] >= '0') && (filename[i] <= '9')) { + no = no * 10 + (filename[i] - '0'); startname++; - }; - }; + } + } - if ((startname+1)<strlen(filename)) startname++;//to take out the "-" + if((startname + 1) < strlen(filename)) + startname++; //to take out the "-" - char name[PART_MAX_NAME_LEN+1]; - ZERO(name,PART_MAX_NAME_LEN+1); - snprintf(name,PART_MAX_NAME_LEN,"%s",filename); + char name[PART_MAX_NAME_LEN + 1]; + ZERO(name, PART_MAX_NAME_LEN + 1); + snprintf(name, PART_MAX_NAME_LEN, "%s", filename); //remove the file extension - for (int i=strlen(name)-1;i>=2;i--) { - if (name[i]=='.') { - name[i]='\0'; + for(int i = strlen(name) - 1; i >= 2; i--) { + if(name[i] == '.') { + name[i] = '\0'; break; - }; - }; - - if (no!=0) {//the instrument position in the bank is found - addtobank(no-1,filename,&name[startname]); - } else { - addtobank(-1,filename,name); - }; + } + } - }; + if(no != 0) //the instrument position in the bank is found + addtobank(no - 1, filename, &name[startname]); + else + addtobank(-1, filename, name); + ; + } closedir(dir); - if (dirname!=NULL) { - sprintf(config.cfg.currentBankDir,"%s",dirname); - }; + if(dirname != NULL) + sprintf(config.cfg.currentBankDir, "%s", dirname); + ; - return(0); -}; + return 0; +} /* * Makes a new bank, put it on a file and makes it current bank */ int Bank::newbank(const char *newbankdirname) { - int result; + int result; char tmpfilename[MAX_STRING_SIZE]; char bankdir[MAX_STRING_SIZE]; - snprintf(bankdir,MAX_STRING_SIZE,"%s",config.cfg.bankRootDirList[0]); + snprintf(bankdir, MAX_STRING_SIZE, "%s", config.cfg.bankRootDirList[0]); - if (((bankdir[strlen(bankdir)-1])!='/')&&((bankdir[strlen(bankdir)-1])!='\\')) { - strncat(bankdir,"/",MAX_STRING_SIZE); - }; - strncat(bankdir,newbankdirname,MAX_STRING_SIZE); + if(((bankdir[strlen(bankdir) - 1]) != '/') + && ((bankdir[strlen(bankdir) - 1]) != '\\')) + strncat(bankdir, "/", MAX_STRING_SIZE); + ; + strncat(bankdir, newbankdirname, MAX_STRING_SIZE); #ifdef OS_WINDOWS - result=mkdir(bankdir); + result = mkdir(bankdir); #else - result=mkdir(bankdir,S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + result = mkdir(bankdir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); #endif - if (result<0) return(-1); - - snprintf(tmpfilename,MAX_STRING_SIZE,"%s/%s",bankdir,FORCE_BANK_DIR_FILE); + if(result < 0) + return -1; + + snprintf(tmpfilename, + MAX_STRING_SIZE, + "%s/%s", + bankdir, + FORCE_BANK_DIR_FILE); // printf("%s\n",tmpfilename); - FILE *tmpfile=fopen(tmpfilename,"w+"); + FILE *tmpfile = fopen(tmpfilename, "w+"); fclose(tmpfile); - return(loadbank(bankdir)); -}; + return loadbank(bankdir); +} /* * Check if the bank is locked (i.e. the file opened was readonly) */ int Bank::locked() { - return(dirname==NULL); -}; + return dirname == NULL; +} /* * Swaps a slot with another */ void Bank::swapslot(unsigned int n1, unsigned int n2) { - if ((n1==n2)||(locked())) return; - if (emptyslot(n1)&&(emptyslot(n2))) return; - if (emptyslot(n1)) {//change n1 to n2 in order to make - int tmp=n2; - n2=n1; - n1=tmp; - }; - - if (emptyslot(n2)) {//this is just a movement from slot1 to slot2 - setname(n1,getname(n1),n2); - ins[n2]=ins[n1]; - ins[n1].used=false; - ins[n1].name[0]='\0'; - ins[n1].filename=NULL; - ins[n1].info.PADsynth_used=0; - } else {//if both slots are used - if (strcmp(ins[n1].name,ins[n2].name)==0) {//change the name of the second instrument if the name are equal - strncat(ins[n2].name,"2",PART_MAX_NAME_LEN); - }; - setname(n1,getname(n1),n2); - setname(n2,getname(n2),n1); + if((n1 == n2) || (locked())) + return; + if(emptyslot(n1) && (emptyslot(n2))) + return; + if(emptyslot(n1)) { //change n1 to n2 in order to make + int tmp = n2; + n2 = n1; + n1 = tmp; + } + + if(emptyslot(n2)) { //this is just a movement from slot1 to slot2 + setname(n1, getname(n1), n2); + ins[n2] = ins[n1]; + ins[n1].used = false; + ins[n1].name[0] = '\0'; + ins[n1].filename = NULL; + ins[n1].info.PADsynth_used = 0; + } + else { //if both slots are used + if(strcmp(ins[n1].name, ins[n2].name) == 0) //change the name of the second instrument if the name are equal + strncat(ins[n2].name, "2", PART_MAX_NAME_LEN); + ; + setname(n1, getname(n1), n2); + setname(n2, getname(n2), n1); ins_t tmp; - tmp.used=true; - strcpy(tmp.name,ins[n2].name); - char *tmpfilename=ins[n2].filename; - bool padsynth_used=ins[n2].info.PADsynth_used; - - ins[n2]=ins[n1]; - strcpy(ins[n1].name,tmp.name); - ins[n1].filename=tmpfilename; - ins[n1].info.PADsynth_used=padsynth_used; - }; + tmp.used = true; + strcpy(tmp.name, ins[n2].name); + char *tmpfilename = ins[n2].filename; + bool padsynth_used = ins[n2].info.PADsynth_used; -}; + ins[n2] = ins[n1]; + strcpy(ins[n1].name, tmp.name); + ins[n1].filename = tmpfilename; + ins[n1].info.PADsynth_used = padsynth_used; + } +} //a helper function that compares 2 banks[] arrays -int Bank_compar(const void *a,const void *b) +int Bank_compar(const void *a, const void *b) { - struct Bank::bankstruct *bank1= (Bank::bankstruct *)a; - struct Bank::bankstruct *bank2= (Bank::bankstruct *)b; - if (((bank1->name)==NULL)||((bank2->name)==NULL)) return(0); + struct Bank::bankstruct *bank1 = (Bank::bankstruct *)a; + struct Bank::bankstruct *bank2 = (Bank::bankstruct *)b; + if(((bank1->name) == NULL) || ((bank2->name) == NULL)) + return 0; - int result=strcasecmp(bank1->name,bank2->name); - return(result<0); -}; + int result = strcasecmp(bank1->name, bank2->name); + return result < 0; +} /* @@ -387,56 +430,61 @@ int Bank_compar(const void *a,const void *b) void Bank::rescanforbanks() { - for (int i=0;i<MAX_NUM_BANKS;i++) { - if (banks[i].dir!=NULL) delete []banks[i].dir; - if (banks[i].name!=NULL) delete []banks[i].name; - banks[i].dir=NULL; - banks[i].name=NULL; - }; - - for (int i=0;i<MAX_BANK_ROOT_DIRS;i++) if (config.cfg.bankRootDirList[i]!=NULL) scanrootdir(config.cfg.bankRootDirList[i]); + for(int i = 0; i < MAX_NUM_BANKS; i++) { + if(banks[i].dir != NULL) + delete [] banks[i].dir; + if(banks[i].name != NULL) + delete [] banks[i].name; + banks[i].dir = NULL; + banks[i].name = NULL; + } + + for(int i = 0; i < MAX_BANK_ROOT_DIRS; i++) + if(config.cfg.bankRootDirList[i] != NULL) + scanrootdir(config.cfg.bankRootDirList[i]); //sort the banks - for (int j=0;j<MAX_NUM_BANKS-1;j++) { - for (int i=j+1;i<MAX_NUM_BANKS;i++) { - if (Bank_compar(&banks[i],&banks[j])) { - char *tmpname=banks[i].name; - char *tmpdir=banks[i].dir; + for(int j = 0; j < MAX_NUM_BANKS - 1; j++) { + for(int i = j + 1; i < MAX_NUM_BANKS; i++) { + if(Bank_compar(&banks[i], &banks[j])) { + char *tmpname = banks[i].name; + char *tmpdir = banks[i].dir; - banks[i].name=banks[j].name; - banks[i].dir=banks[j].dir; + banks[i].name = banks[j].name; + banks[i].dir = banks[j].dir; - banks[j].name=tmpname; - banks[j].dir=tmpdir; - - }; - }; - }; + banks[j].name = tmpname; + banks[j].dir = tmpdir; + } + } + } //remove duplicate bank names - int dupl=0; - for (int j=0;j<MAX_NUM_BANKS-1;j++) { - for (int i=j+1;i<MAX_NUM_BANKS;i++) { - if ((banks[i].name==NULL)||(banks[j].name==NULL)) continue; - if (strcmp(banks[i].name,banks[j].name)==0) {//add a [1] to the first bankname and [n] to others - char *tmpname=banks[i].name; - banks[i].name=new char[strlen(tmpname)+100]; - sprintf(banks[i].name,"%s[%d]",tmpname,dupl+2); - delete[]tmpname; - - if (dupl==0) { - char *tmpname=banks[j].name; - banks[j].name=new char[strlen(tmpname)+100]; - sprintf(banks[j].name,"%s[1]",tmpname); - delete[]tmpname; - }; + int dupl = 0; + for(int j = 0; j < MAX_NUM_BANKS - 1; j++) { + for(int i = j + 1; i < MAX_NUM_BANKS; i++) { + if((banks[i].name == NULL) || (banks[j].name == NULL)) + continue; + if(strcmp(banks[i].name, banks[j].name) == 0) { //add a [1] to the first bankname and [n] to others + char *tmpname = banks[i].name; + banks[i].name = new char[strlen(tmpname) + 100]; + sprintf(banks[i].name, "%s[%d]", tmpname, dupl + 2); + delete[] tmpname; + + if(dupl == 0) { + char *tmpname = banks[j].name; + banks[j].name = new char[strlen(tmpname) + 100]; + sprintf(banks[j].name, "%s[1]", tmpname); + delete[] tmpname; + } dupl++; - } else dupl=0; - }; - }; - -}; + } + else + dupl = 0; + } + } +} @@ -445,140 +493,152 @@ void Bank::rescanforbanks() void Bank::scanrootdir(char *rootdir) { // printf("Scanning root dir:%s\n",rootdir); - DIR *dir=opendir(rootdir); - if (dir==NULL) return; + DIR *dir = opendir(rootdir); + if(dir == NULL) + return; - const int maxdirsize=1000; + const int maxdirsize = 1000; struct { char dir[maxdirsize]; char name[maxdirsize]; - }bank; + } bank; - const char *separator="/"; - if (strlen(rootdir)) { - char tmp=rootdir[strlen(rootdir)-1]; - if ((tmp=='/') || (tmp=='\\')) separator=""; - }; + const char *separator = "/"; + if(strlen(rootdir)) { + char tmp = rootdir[strlen(rootdir) - 1]; + if((tmp == '/') || (tmp == '\\')) + separator = ""; + } struct dirent *fn; - while ((fn=readdir(dir))) { - const char *dirname=fn->d_name; - if (dirname[0]=='.') continue; + while((fn = readdir(dir))) { + const char *dirname = fn->d_name; + if(dirname[0] == '.') + continue; - snprintf(bank.dir,maxdirsize,"%s%s%s/",rootdir,separator,dirname); - snprintf(bank.name,maxdirsize,"%s",dirname); + snprintf(bank.dir, maxdirsize, "%s%s%s/", rootdir, separator, dirname); + snprintf(bank.name, maxdirsize, "%s", dirname); //find out if the directory contains at least 1 instrument - bool isbank=false; + bool isbank = false; - DIR *d=opendir(bank.dir); - if (d==NULL) continue; + DIR *d = opendir(bank.dir); + if(d == NULL) + continue; struct dirent *fname; - while ((fname=readdir(d))) { - if ((strstr(fname->d_name,INSTRUMENT_EXTENSION)!=NULL)|| - (strstr(fname->d_name,FORCE_BANK_DIR_FILE)!=NULL)) { - isbank=true; - break;//aici as putea pune in loc de break un update la un counter care imi arata nr. de instrumente din bank - }; - }; + while((fname = readdir(d))) { + if((strstr(fname->d_name, INSTRUMENT_EXTENSION) != NULL) + || (strstr(fname->d_name, FORCE_BANK_DIR_FILE) != NULL)) { + isbank = true; + break; //aici as putea pune in loc de break un update la un counter care imi arata nr. de instrumente din bank + } + } closedir(d); - if (isbank) { - int pos=-1; - for (int i=1;i<MAX_NUM_BANKS;i++) { //banks[0] e liber intotdeauna - if (banks[i].name==NULL) { - pos=i; + if(isbank) { + int pos = -1; + for(int i = 1; i < MAX_NUM_BANKS; i++) { //banks[0] e liber intotdeauna + if(banks[i].name == NULL) { + pos = i; break; - }; - }; - - if (pos>=0) { - banks[pos].name=new char[maxdirsize]; - banks[pos].dir=new char[maxdirsize]; - snprintf(banks[pos].name,maxdirsize,"%s",bank.name); - snprintf(banks[pos].dir,maxdirsize,"%s",bank.dir); - }; - - }; - - }; + } + } + + if(pos >= 0) { + banks[pos].name = new char[maxdirsize]; + banks[pos].dir = new char[maxdirsize]; + snprintf(banks[pos].name, maxdirsize, "%s", bank.name); + snprintf(banks[pos].dir, maxdirsize, "%s", bank.dir); + } + } + } closedir(dir); - -}; +} void Bank::clearbank() { - for (int i=0;i<BANK_SIZE;i++) deletefrombank(i); - if (dirname!=NULL) delete[]dirname; - bankfiletitle=NULL; - dirname=NULL; -}; - -int Bank::addtobank(int pos, const char *filename, const char* name) + for(int i = 0; i < BANK_SIZE; i++) + deletefrombank(i); + if(dirname != NULL) + delete[] dirname; + bankfiletitle = NULL; + dirname = NULL; +} + +int Bank::addtobank(int pos, const char *filename, const char *name) { - if ((pos>=0)&&(pos<BANK_SIZE)) { - if (ins[pos].used) pos=-1;//force it to find a new free position - } else if (pos>=BANK_SIZE) pos=-1; - - - if (pos<0) {//find a free position - for (int i=BANK_SIZE-1;i>=0;i--) - if (!ins[i].used) { - pos=i; + if((pos >= 0) && (pos < BANK_SIZE)) { + if(ins[pos].used) + pos = -1; //force it to find a new free position + } + else + if(pos >= BANK_SIZE) + pos = -1; + + + if(pos < 0) { //find a free position + for(int i = BANK_SIZE - 1; i >= 0; i--) + if(!ins[i].used) { + pos = i; break; - }; + } + ; + } - }; - - if (pos<0) return (-1);//the bank is full + if(pos < 0) + return -1; //the bank is full // printf("%s %d\n",filename,pos); deletefrombank(pos); - ins[pos].used=true; - snprintf(ins[pos].name,PART_MAX_NAME_LEN,"%s",name); + ins[pos].used = true; + snprintf(ins[pos].name, PART_MAX_NAME_LEN, "%s", name); - snprintf(tmpinsname[pos],PART_MAX_NAME_LEN+10," "); + snprintf(tmpinsname[pos], PART_MAX_NAME_LEN + 10, " "); - int len=strlen(filename)+1+strlen(dirname); - ins[pos].filename=new char[len+2]; - ins[pos].filename[len+1]=0; - snprintf(ins[pos].filename,len+1,"%s/%s",dirname,filename); + int len = strlen(filename) + 1 + strlen(dirname); + ins[pos].filename = new char[len + 2]; + ins[pos].filename[len + 1] = 0; + snprintf(ins[pos].filename, len + 1, "%s/%s", dirname, filename); //see if PADsynth is used - if (config.cfg.CheckPADsynth) { - XMLwrapper *xml=new XMLwrapper(); + if(config.cfg.CheckPADsynth) { + XMLwrapper *xml = new XMLwrapper(); xml->loadXMLfile(ins[pos].filename); - ins[pos].info.PADsynth_used=xml->hasPadSynth(); + ins[pos].info.PADsynth_used = xml->hasPadSynth(); delete xml; - } else ins[pos].info.PADsynth_used=false; + } + else + ins[pos].info.PADsynth_used = false; - return(0); -}; + return 0; +} bool Bank::isPADsynth_used(unsigned int ninstrument) { - if (config.cfg.CheckPADsynth==0) return(0); - else return(ins[ninstrument].info.PADsynth_used); -}; + if(config.cfg.CheckPADsynth == 0) + return 0; + else + return ins[ninstrument].info.PADsynth_used; +} void Bank::deletefrombank(int pos) { - if ((pos<0)||(pos>=BANK_SIZE)) return; - ins[pos].used=false; - ZERO(ins[pos].name,PART_MAX_NAME_LEN+1); - if (ins[pos].filename!=NULL) { - delete []ins[pos].filename; - ins[pos].filename=NULL; - }; - - ZERO(tmpinsname[pos],PART_MAX_NAME_LEN+20); - -}; + if((pos < 0) || (pos >= BANK_SIZE)) + return; + ins[pos].used = false; + ZERO(ins[pos].name, PART_MAX_NAME_LEN + 1); + if(ins[pos].filename != NULL) { + delete [] ins[pos].filename; + ins[pos].filename = NULL; + } + + ZERO(tmpinsname[pos], PART_MAX_NAME_LEN + 20); +} diff --git a/src/Misc/Bank.h b/src/Misc/Bank.h @@ -38,70 +38,70 @@ * \todo add in strings to replace char* */ class Bank { -public: - /**Constructor*/ - Bank(); - ~Bank(); - char *getname(unsigned int ninstrument); - char *getnamenumbered(unsigned int ninstrument); - void setname(unsigned int ninstrument,const char *newname,int newslot);//if newslot==-1 then this is ignored, else it will be put on that slot - bool isPADsynth_used(unsigned int ninstrument); + public: + /**Constructor*/ + Bank(); + ~Bank(); + char *getname(unsigned int ninstrument); + char *getnamenumbered(unsigned int ninstrument); + void setname(unsigned int ninstrument, const char *newname, int newslot); //if newslot==-1 then this is ignored, else it will be put on that slot + bool isPADsynth_used(unsigned int ninstrument); - /**returns 0 if the slot is not empty or 1 if the slot is empty - * \todo start using bool before facepalm*/ - int emptyslot(unsigned int ninstrument); + /**returns 0 if the slot is not empty or 1 if the slot is empty + * \todo start using bool before facepalm*/ + int emptyslot(unsigned int ninstrument); - /**Empties out the selected slot*/ - void clearslot(unsigned int ninstrument); - /**Saves the given Part to slot*/ - void savetoslot(unsigned int ninstrument,Part *part); - /**Loads the given slot into a Part*/ - void loadfromslot(unsigned int ninstrument,Part *part); + /**Empties out the selected slot*/ + void clearslot(unsigned int ninstrument); + /**Saves the given Part to slot*/ + void savetoslot(unsigned int ninstrument, Part *part); + /**Loads the given slot into a Part*/ + void loadfromslot(unsigned int ninstrument, Part *part); - /**Swaps Slots*/ - void swapslot(unsigned int n1,unsigned int n2); + /**Swaps Slots*/ + void swapslot(unsigned int n1, unsigned int n2); - int loadbank(const char *bankdirname); - int newbank(const char *newbankdirname); + int loadbank(const char *bankdirname); + int newbank(const char *newbankdirname); - char *bankfiletitle; //this is shown on the UI of the bank (the title of the window) - int locked(); + char *bankfiletitle; //this is shown on the UI of the bank (the title of the window) + int locked(); - void rescanforbanks(); + void rescanforbanks(); - struct bankstruct { - char *dir; - char *name; - }; + struct bankstruct { + char *dir; + char *name; + }; - bankstruct banks[MAX_NUM_BANKS]; + bankstruct banks[MAX_NUM_BANKS]; -private: + private: - //it adds a filename to the bank - //if pos is -1 it try to find a position - //returns -1 if the bank is full, or 0 if the instrument was added - int addtobank(int pos,const char* filename,const char* name); + //it adds a filename to the bank + //if pos is -1 it try to find a position + //returns -1 if the bank is full, or 0 if the instrument was added + int addtobank(int pos, const char *filename, const char *name); - void deletefrombank(int pos); + void deletefrombank(int pos); - void clearbank(); + void clearbank(); - char defaultinsname[PART_MAX_NAME_LEN]; - char tmpinsname[BANK_SIZE][PART_MAX_NAME_LEN+20];//this keeps the numbered names + char defaultinsname[PART_MAX_NAME_LEN]; + char tmpinsname[BANK_SIZE][PART_MAX_NAME_LEN + 20]; //this keeps the numbered names - struct ins_t { - bool used; - char name[PART_MAX_NAME_LEN+1]; - char *filename; - struct { - bool PADsynth_used; - } info; - }ins[BANK_SIZE]; + struct ins_t { + bool used; + char name[PART_MAX_NAME_LEN + 1]; + char *filename; + struct { + bool PADsynth_used; + } info; + } ins[BANK_SIZE]; - char *dirname; + char *dirname; - void scanrootdir(char *rootdir);//scans a root dir for banks + void scanrootdir(char *rootdir); //scans a root dir for banks }; #endif diff --git a/src/Misc/Config.cpp b/src/Misc/Config.cpp @@ -33,309 +33,369 @@ #include "XMLwrapper.h" Config::Config() -{ -}; +{} void Config::init() { - maxstringsize=MAX_STRING_SIZE;//for ui + maxstringsize = MAX_STRING_SIZE; //for ui //defaults - cfg.SampleRate=44100; - cfg.SoundBufferSize=256; - cfg.OscilSize=1024; - cfg.SwapStereo=0; + cfg.SampleRate = 44100; + cfg.SoundBufferSize = 256; + cfg.OscilSize = 1024; + cfg.SwapStereo = 0; - cfg.LinuxOSSWaveOutDev=new char[MAX_STRING_SIZE]; - snprintf(cfg.LinuxOSSWaveOutDev,MAX_STRING_SIZE,"/dev/dsp"); - cfg.LinuxOSSSeqInDev=new char[MAX_STRING_SIZE]; - snprintf(cfg.LinuxOSSSeqInDev,MAX_STRING_SIZE,"/dev/sequencer"); + cfg.LinuxOSSWaveOutDev = new char[MAX_STRING_SIZE]; + snprintf(cfg.LinuxOSSWaveOutDev, MAX_STRING_SIZE, "/dev/dsp"); + cfg.LinuxOSSSeqInDev = new char[MAX_STRING_SIZE]; + snprintf(cfg.LinuxOSSSeqInDev, MAX_STRING_SIZE, "/dev/sequencer"); - cfg.DumpFile=new char[MAX_STRING_SIZE]; - snprintf(cfg.DumpFile,MAX_STRING_SIZE,"zynaddsubfx_dump.txt"); + cfg.DumpFile = new char[MAX_STRING_SIZE]; + snprintf(cfg.DumpFile, MAX_STRING_SIZE, "zynaddsubfx_dump.txt"); - cfg.WindowsWaveOutId=0; - cfg.WindowsMidiInId=0; + cfg.WindowsWaveOutId = 0; + cfg.WindowsMidiInId = 0; - cfg.BankUIAutoClose=0; - cfg.DumpNotesToFile=0; - cfg.DumpAppend=1; + cfg.BankUIAutoClose = 0; + cfg.DumpNotesToFile = 0; + cfg.DumpAppend = 1; - cfg.GzipCompression=3; + cfg.GzipCompression = 3; - cfg.Interpolation=0; - cfg.CheckPADsynth=1; + cfg.Interpolation = 0; + cfg.CheckPADsynth = 1; - cfg.UserInterfaceMode=0; - cfg.VirKeybLayout=1; - winwavemax=1; - winmidimax=1; + cfg.UserInterfaceMode = 0; + cfg.VirKeybLayout = 1; + winwavemax = 1; + winmidimax = 1; //try to find out how many input midi devices are there #ifdef WINMIDIIN - winmidimax=midiInGetNumDevs(); - if (winmidimax==0) winmidimax=1; + winmidimax = midiInGetNumDevs(); + if(winmidimax == 0) + winmidimax = 1; #endif - winmididevices=new winmidionedevice[winmidimax]; - for (int i=0;i<winmidimax;i++) { - winmididevices[i].name=new char[MAX_STRING_SIZE]; - for (int j=0;j<MAX_STRING_SIZE;j++) winmididevices[i].name[j]='\0'; - }; + winmididevices = new winmidionedevice[winmidimax]; + for(int i = 0; i < winmidimax; i++) { + winmididevices[i].name = new char[MAX_STRING_SIZE]; + for(int j = 0; j < MAX_STRING_SIZE; j++) + winmididevices[i].name[j] = '\0'; + } //get the midi input devices name #ifdef WINMIDIIN MIDIINCAPS midiincaps; - for (int i=0;i<winmidimax;i++) { - if (! midiInGetDevCaps(i,&midiincaps,sizeof(MIDIINCAPS))) - snprintf(winmididevices[i].name,MAX_STRING_SIZE,"%s",midiincaps.szPname); - }; + for(int i = 0; i < winmidimax; i++) + if(!midiInGetDevCaps(i, &midiincaps, sizeof(MIDIINCAPS))) + snprintf(winmididevices[i].name, + MAX_STRING_SIZE, + "%s", + midiincaps.szPname); + ; #endif - for (int i=0;i<MAX_BANK_ROOT_DIRS;i++) cfg.bankRootDirList[i]=NULL; - cfg.currentBankDir=new char[MAX_STRING_SIZE]; - sprintf(cfg.currentBankDir,"./testbnk"); + for(int i = 0; i < MAX_BANK_ROOT_DIRS; i++) + cfg.bankRootDirList[i] = NULL; + cfg.currentBankDir = new char[MAX_STRING_SIZE]; + sprintf(cfg.currentBankDir, "./testbnk"); - for (int i=0;i<MAX_BANK_ROOT_DIRS;i++) cfg.presetsDirList[i]=NULL; + for(int i = 0; i < MAX_BANK_ROOT_DIRS; i++) + cfg.presetsDirList[i] = NULL; char filename[MAX_STRING_SIZE]; - getConfigFileName(filename,MAX_STRING_SIZE); + getConfigFileName(filename, MAX_STRING_SIZE); readConfig(filename); - if (cfg.bankRootDirList[0]==NULL) { + if(cfg.bankRootDirList[0] == NULL) { #if defined(OS_LINUX) //banks - cfg.bankRootDirList[0]=new char[MAX_STRING_SIZE]; - sprintf(cfg.bankRootDirList[0],"~/banks"); + cfg.bankRootDirList[0] = new char[MAX_STRING_SIZE]; + sprintf(cfg.bankRootDirList[0], "~/banks"); - cfg.bankRootDirList[1]=new char[MAX_STRING_SIZE]; - sprintf(cfg.bankRootDirList[1],"./"); + cfg.bankRootDirList[1] = new char[MAX_STRING_SIZE]; + sprintf(cfg.bankRootDirList[1], "./"); - cfg.bankRootDirList[2]=new char[MAX_STRING_SIZE]; - sprintf(cfg.bankRootDirList[2],"/usr/share/zynaddsubfx/banks"); + cfg.bankRootDirList[2] = new char[MAX_STRING_SIZE]; + sprintf(cfg.bankRootDirList[2], "/usr/share/zynaddsubfx/banks"); - cfg.bankRootDirList[3]=new char[MAX_STRING_SIZE]; - sprintf(cfg.bankRootDirList[3],"/usr/local/share/zynaddsubfx/banks"); + cfg.bankRootDirList[3] = new char[MAX_STRING_SIZE]; + sprintf(cfg.bankRootDirList[3], "/usr/local/share/zynaddsubfx/banks"); - cfg.bankRootDirList[4]=new char[MAX_STRING_SIZE]; - sprintf(cfg.bankRootDirList[4],"../banks"); + cfg.bankRootDirList[4] = new char[MAX_STRING_SIZE]; + sprintf(cfg.bankRootDirList[4], "../banks"); - cfg.bankRootDirList[5]=new char[MAX_STRING_SIZE]; - sprintf(cfg.bankRootDirList[5],"banks"); + cfg.bankRootDirList[5] = new char[MAX_STRING_SIZE]; + sprintf(cfg.bankRootDirList[5], "banks"); #else //banks - cfg.bankRootDirList[0]=new char[MAX_STRING_SIZE]; - sprintf(cfg.bankRootDirList[0],"./"); + cfg.bankRootDirList[0] = new char[MAX_STRING_SIZE]; + sprintf(cfg.bankRootDirList[0], "./"); #ifdef VSTAUDIOOUT - cfg.bankRootDirList[1]=new char[MAX_STRING_SIZE]; - sprintf(cfg.bankRootDirList[1],"c:/Program Files/ZynAddSubFX/banks"); + cfg.bankRootDirList[1] = new char[MAX_STRING_SIZE]; + sprintf(cfg.bankRootDirList[1], "c:/Program Files/ZynAddSubFX/banks"); #else - cfg.bankRootDirList[1]=new char[MAX_STRING_SIZE]; - sprintf(cfg.bankRootDirList[1],"../banks"); + cfg.bankRootDirList[1] = new char[MAX_STRING_SIZE]; + sprintf(cfg.bankRootDirList[1], "../banks"); #endif - cfg.bankRootDirList[2]=new char[MAX_STRING_SIZE]; - sprintf(cfg.bankRootDirList[2],"banks"); + cfg.bankRootDirList[2] = new char[MAX_STRING_SIZE]; + sprintf(cfg.bankRootDirList[2], "banks"); #endif - }; + } - if (cfg.presetsDirList[0]==NULL) { + if(cfg.presetsDirList[0] == NULL) { #if defined(OS_LINUX) //presets - cfg.presetsDirList[0]=new char[MAX_STRING_SIZE]; - sprintf(cfg.presetsDirList[0],"./"); + cfg.presetsDirList[0] = new char[MAX_STRING_SIZE]; + sprintf(cfg.presetsDirList[0], "./"); - cfg.presetsDirList[1]=new char[MAX_STRING_SIZE]; - sprintf(cfg.presetsDirList[1],"../presets"); + cfg.presetsDirList[1] = new char[MAX_STRING_SIZE]; + sprintf(cfg.presetsDirList[1], "../presets"); - cfg.presetsDirList[2]=new char[MAX_STRING_SIZE]; - sprintf(cfg.presetsDirList[2],"presets"); + cfg.presetsDirList[2] = new char[MAX_STRING_SIZE]; + sprintf(cfg.presetsDirList[2], "presets"); - cfg.presetsDirList[3]=new char[MAX_STRING_SIZE]; - sprintf(cfg.presetsDirList[3],"/usr/share/zynaddsubfx/presets"); + cfg.presetsDirList[3] = new char[MAX_STRING_SIZE]; + sprintf(cfg.presetsDirList[3], "/usr/share/zynaddsubfx/presets"); - cfg.presetsDirList[4]=new char[MAX_STRING_SIZE]; - sprintf(cfg.presetsDirList[4],"/usr/local/share/zynaddsubfx/presets"); + cfg.presetsDirList[4] = new char[MAX_STRING_SIZE]; + sprintf(cfg.presetsDirList[4], "/usr/local/share/zynaddsubfx/presets"); #else //presets - cfg.presetsDirList[0]=new char[MAX_STRING_SIZE]; - sprintf(cfg.presetsDirList[0],"./"); + cfg.presetsDirList[0] = new char[MAX_STRING_SIZE]; + sprintf(cfg.presetsDirList[0], "./"); #ifdef VSTAUDIOOUT - cfg.presetsDirList[1]=new char[MAX_STRING_SIZE]; - sprintf(cfg.presetsDirList[1],"c:/Program Files/ZynAddSubFX/presets"); + cfg.presetsDirList[1] = new char[MAX_STRING_SIZE]; + sprintf(cfg.presetsDirList[1], "c:/Program Files/ZynAddSubFX/presets"); #else - cfg.presetsDirList[1]=new char[MAX_STRING_SIZE]; - sprintf(cfg.presetsDirList[1],"../presets"); + cfg.presetsDirList[1] = new char[MAX_STRING_SIZE]; + sprintf(cfg.presetsDirList[1], "../presets"); #endif - cfg.presetsDirList[2]=new char[MAX_STRING_SIZE]; - sprintf(cfg.presetsDirList[2],"presets"); + cfg.presetsDirList[2] = new char[MAX_STRING_SIZE]; + sprintf(cfg.presetsDirList[2], "presets"); #endif - }; - -}; + } +} Config::~Config() { - delete [] cfg.LinuxOSSWaveOutDev; delete [] cfg.LinuxOSSSeqInDev; delete [] cfg.DumpFile; - for (int i=0;i<winmidimax;i++) delete [] winmididevices[i].name; + for(int i = 0; i < winmidimax; i++) + delete [] winmididevices[i].name; delete [] winmididevices; -}; +} void Config::save() { char filename[MAX_STRING_SIZE]; - getConfigFileName(filename,MAX_STRING_SIZE); + getConfigFileName(filename, MAX_STRING_SIZE); saveConfig(filename); -}; +} void Config::clearbankrootdirlist() { - for (int i=0;i<MAX_BANK_ROOT_DIRS;i++) { - if (cfg.bankRootDirList[i]==NULL) delete(cfg.bankRootDirList[i]); - cfg.bankRootDirList[i]=NULL; - }; -}; + for(int i = 0; i < MAX_BANK_ROOT_DIRS; i++) { + if(cfg.bankRootDirList[i] == NULL) + delete (cfg.bankRootDirList[i]); + cfg.bankRootDirList[i] = NULL; + } +} void Config::clearpresetsdirlist() { - for (int i=0;i<MAX_BANK_ROOT_DIRS;i++) { - if (cfg.presetsDirList[i]==NULL) delete(cfg.presetsDirList[i]); - cfg.presetsDirList[i]=NULL; - }; -}; + for(int i = 0; i < MAX_BANK_ROOT_DIRS; i++) { + if(cfg.presetsDirList[i] == NULL) + delete (cfg.presetsDirList[i]); + cfg.presetsDirList[i] = NULL; + } +} void Config::readConfig(const char *filename) { - XMLwrapper *xmlcfg=new XMLwrapper(); - if (xmlcfg->loadXMLfile(filename)<0) return; - if (xmlcfg->enterbranch("CONFIGURATION")) { - cfg.SampleRate=xmlcfg->getpar("sample_rate",cfg.SampleRate,4000,1024000); - cfg.SoundBufferSize=xmlcfg->getpar("sound_buffer_size",cfg.SoundBufferSize,16,8192); - cfg.OscilSize=xmlcfg->getpar("oscil_size",cfg.OscilSize,MAX_AD_HARMONICS*2,131072); - cfg.SwapStereo=xmlcfg->getpar("swap_stereo",cfg.SwapStereo,0,1); - cfg.BankUIAutoClose=xmlcfg->getpar("bank_window_auto_close",cfg.BankUIAutoClose,0,1); - - cfg.DumpNotesToFile=xmlcfg->getpar("dump_notes_to_file",cfg.DumpNotesToFile,0,1); - cfg.DumpAppend=xmlcfg->getpar("dump_append",cfg.DumpAppend,0,1); - xmlcfg->getparstr("dump_file",cfg.DumpFile,MAX_STRING_SIZE); - - cfg.GzipCompression=xmlcfg->getpar("gzip_compression",cfg.GzipCompression,0,9); - - xmlcfg->getparstr("bank_current",cfg.currentBankDir,MAX_STRING_SIZE); - cfg.Interpolation=xmlcfg->getpar("interpolation",cfg.Interpolation,0,1); - - cfg.CheckPADsynth=xmlcfg->getpar("check_pad_synth",cfg.CheckPADsynth,0,1); - - - cfg.UserInterfaceMode=xmlcfg->getpar("user_interface_mode",cfg.UserInterfaceMode,0,2); - cfg.VirKeybLayout=xmlcfg->getpar("virtual_keyboard_layout",cfg.VirKeybLayout,0,10); + XMLwrapper *xmlcfg = new XMLwrapper(); + if(xmlcfg->loadXMLfile(filename) < 0) + return; + if(xmlcfg->enterbranch("CONFIGURATION")) { + cfg.SampleRate = xmlcfg->getpar("sample_rate", + cfg.SampleRate, + 4000, + 1024000); + cfg.SoundBufferSize = xmlcfg->getpar("sound_buffer_size", + cfg.SoundBufferSize, + 16, + 8192); + cfg.OscilSize = xmlcfg->getpar("oscil_size", + cfg.OscilSize, + MAX_AD_HARMONICS * 2, + 131072); + cfg.SwapStereo = xmlcfg->getpar("swap_stereo", + cfg.SwapStereo, + 0, + 1); + cfg.BankUIAutoClose = xmlcfg->getpar("bank_window_auto_close", + cfg.BankUIAutoClose, + 0, + 1); + + cfg.DumpNotesToFile = xmlcfg->getpar("dump_notes_to_file", + cfg.DumpNotesToFile, + 0, + 1); + cfg.DumpAppend = xmlcfg->getpar("dump_append", + cfg.DumpAppend, + 0, + 1); + xmlcfg->getparstr("dump_file", cfg.DumpFile, MAX_STRING_SIZE); + + cfg.GzipCompression = xmlcfg->getpar("gzip_compression", + cfg.GzipCompression, + 0, + 9); + + xmlcfg->getparstr("bank_current", cfg.currentBankDir, MAX_STRING_SIZE); + cfg.Interpolation = xmlcfg->getpar("interpolation", + cfg.Interpolation, + 0, + 1); + + cfg.CheckPADsynth = xmlcfg->getpar("check_pad_synth", + cfg.CheckPADsynth, + 0, + 1); + + + cfg.UserInterfaceMode = xmlcfg->getpar("user_interface_mode", + cfg.UserInterfaceMode, + 0, + 2); + cfg.VirKeybLayout = xmlcfg->getpar("virtual_keyboard_layout", + cfg.VirKeybLayout, + 0, + 10); //get bankroot dirs - for (int i=0;i<MAX_BANK_ROOT_DIRS;i++) { - if (xmlcfg->enterbranch("BANKROOT",i)) { - cfg.bankRootDirList[i]=new char[MAX_STRING_SIZE]; - xmlcfg->getparstr("bank_root",cfg.bankRootDirList[i],MAX_STRING_SIZE); + for(int i = 0; i < MAX_BANK_ROOT_DIRS; i++) { + if(xmlcfg->enterbranch("BANKROOT", i)) { + cfg.bankRootDirList[i] = new char[MAX_STRING_SIZE]; + xmlcfg->getparstr("bank_root", + cfg.bankRootDirList[i], + MAX_STRING_SIZE); xmlcfg->exitbranch(); - }; - }; + } + } //get preset root dirs - for (int i=0;i<MAX_BANK_ROOT_DIRS;i++) { - if (xmlcfg->enterbranch("PRESETSROOT",i)) { - cfg.presetsDirList[i]=new char[MAX_STRING_SIZE]; - xmlcfg->getparstr("presets_root",cfg.presetsDirList[i],MAX_STRING_SIZE); + for(int i = 0; i < MAX_BANK_ROOT_DIRS; i++) { + if(xmlcfg->enterbranch("PRESETSROOT", i)) { + cfg.presetsDirList[i] = new char[MAX_STRING_SIZE]; + xmlcfg->getparstr("presets_root", + cfg.presetsDirList[i], + MAX_STRING_SIZE); xmlcfg->exitbranch(); - }; - }; + } + } //linux stuff - xmlcfg->getparstr("linux_oss_wave_out_dev",cfg.LinuxOSSWaveOutDev,MAX_STRING_SIZE); - xmlcfg->getparstr("linux_oss_seq_in_dev",cfg.LinuxOSSSeqInDev,MAX_STRING_SIZE); + xmlcfg->getparstr("linux_oss_wave_out_dev", + cfg.LinuxOSSWaveOutDev, + MAX_STRING_SIZE); + xmlcfg->getparstr("linux_oss_seq_in_dev", + cfg.LinuxOSSSeqInDev, + MAX_STRING_SIZE); //windows stuff - cfg.WindowsWaveOutId=xmlcfg->getpar("windows_wave_out_id",cfg.WindowsWaveOutId,0,winwavemax); - cfg.WindowsMidiInId=xmlcfg->getpar("windows_midi_in_id",cfg.WindowsMidiInId,0,winmidimax); + cfg.WindowsWaveOutId = xmlcfg->getpar("windows_wave_out_id", + cfg.WindowsWaveOutId, + 0, + winwavemax); + cfg.WindowsMidiInId = xmlcfg->getpar("windows_midi_in_id", + cfg.WindowsMidiInId, + 0, + winmidimax); xmlcfg->exitbranch(); - }; - delete(xmlcfg); + } + delete (xmlcfg); - cfg.OscilSize=(int) pow(2,ceil(log (cfg.OscilSize-1.0)/log(2.0))); - -}; + cfg.OscilSize = (int) pow(2, ceil(log(cfg.OscilSize - 1.0) / log(2.0))); +} void Config::saveConfig(const char *filename) { - XMLwrapper *xmlcfg=new XMLwrapper(); + XMLwrapper *xmlcfg = new XMLwrapper(); xmlcfg->beginbranch("CONFIGURATION"); - xmlcfg->addpar("sample_rate",cfg.SampleRate); - xmlcfg->addpar("sound_buffer_size",cfg.SoundBufferSize); - xmlcfg->addpar("oscil_size",cfg.OscilSize); - xmlcfg->addpar("swap_stereo",cfg.SwapStereo); - xmlcfg->addpar("bank_window_auto_close",cfg.BankUIAutoClose); + xmlcfg->addpar("sample_rate", cfg.SampleRate); + xmlcfg->addpar("sound_buffer_size", cfg.SoundBufferSize); + xmlcfg->addpar("oscil_size", cfg.OscilSize); + xmlcfg->addpar("swap_stereo", cfg.SwapStereo); + xmlcfg->addpar("bank_window_auto_close", cfg.BankUIAutoClose); - xmlcfg->addpar("dump_notes_to_file",cfg.DumpNotesToFile); - xmlcfg->addpar("dump_append",cfg.DumpAppend); - xmlcfg->addparstr("dump_file",cfg.DumpFile); + xmlcfg->addpar("dump_notes_to_file", cfg.DumpNotesToFile); + xmlcfg->addpar("dump_append", cfg.DumpAppend); + xmlcfg->addparstr("dump_file", cfg.DumpFile); - xmlcfg->addpar("gzip_compression",cfg.GzipCompression); + xmlcfg->addpar("gzip_compression", cfg.GzipCompression); - xmlcfg->addpar("check_pad_synth",cfg.CheckPADsynth); + xmlcfg->addpar("check_pad_synth", cfg.CheckPADsynth); - xmlcfg->addparstr("bank_current",cfg.currentBankDir); + xmlcfg->addparstr("bank_current", cfg.currentBankDir); - xmlcfg->addpar("user_interface_mode",cfg.UserInterfaceMode); - xmlcfg->addpar("virtual_keyboard_layout",cfg.VirKeybLayout); + xmlcfg->addpar("user_interface_mode", cfg.UserInterfaceMode); + xmlcfg->addpar("virtual_keyboard_layout", cfg.VirKeybLayout); - for (int i=0;i<MAX_BANK_ROOT_DIRS;i++) if (cfg.bankRootDirList[i]!=NULL) { - xmlcfg->beginbranch("BANKROOT",i); - xmlcfg->addparstr("bank_root",cfg.bankRootDirList[i]); + for(int i = 0; i < MAX_BANK_ROOT_DIRS; i++) + if(cfg.bankRootDirList[i] != NULL) { + xmlcfg->beginbranch("BANKROOT", i); + xmlcfg->addparstr("bank_root", cfg.bankRootDirList[i]); xmlcfg->endbranch(); - }; + } + ; - for (int i=0;i<MAX_BANK_ROOT_DIRS;i++) if (cfg.presetsDirList[i]!=NULL) { - xmlcfg->beginbranch("PRESETSROOT",i); - xmlcfg->addparstr("presets_root",cfg.presetsDirList[i]); + for(int i = 0; i < MAX_BANK_ROOT_DIRS; i++) + if(cfg.presetsDirList[i] != NULL) { + xmlcfg->beginbranch("PRESETSROOT", i); + xmlcfg->addparstr("presets_root", cfg.presetsDirList[i]); xmlcfg->endbranch(); - }; + } + ; - xmlcfg->addpar("interpolation",cfg.Interpolation); + xmlcfg->addpar("interpolation", cfg.Interpolation); //linux stuff - xmlcfg->addparstr("linux_oss_wave_out_dev",cfg.LinuxOSSWaveOutDev); - xmlcfg->addparstr("linux_oss_seq_in_dev",cfg.LinuxOSSSeqInDev); + xmlcfg->addparstr("linux_oss_wave_out_dev", cfg.LinuxOSSWaveOutDev); + xmlcfg->addparstr("linux_oss_seq_in_dev", cfg.LinuxOSSSeqInDev); //windows stuff - xmlcfg->addpar("windows_wave_out_id",cfg.WindowsWaveOutId); - xmlcfg->addpar("windows_midi_in_id",cfg.WindowsMidiInId); + xmlcfg->addpar("windows_wave_out_id", cfg.WindowsWaveOutId); + xmlcfg->addpar("windows_midi_in_id", cfg.WindowsMidiInId); xmlcfg->endbranch(); - int tmp=cfg.GzipCompression; - cfg.GzipCompression=0; + int tmp = cfg.GzipCompression; + cfg.GzipCompression = 0; xmlcfg->saveXMLfile(filename); - cfg.GzipCompression=tmp; + cfg.GzipCompression = tmp; - delete(xmlcfg); -}; + delete (xmlcfg); +} void Config::getConfigFileName(char *name, int namesize) { - name[0]=0; + name[0] = 0; #ifdef OS_LINUX - snprintf(name,namesize,"%s%s",getenv("HOME"),"/.zynaddsubfxXML.cfg"); + snprintf(name, namesize, "%s%s", getenv("HOME"), "/.zynaddsubfxXML.cfg"); #else - snprintf(name,namesize,"%s","zynaddsubfxXML.cfg"); + snprintf(name, namesize, "%s", "zynaddsubfxXML.cfg"); #endif - -}; +} diff --git a/src/Misc/Config.h b/src/Misc/Config.h @@ -29,43 +29,43 @@ /**Configuration file functions*/ class Config { -public: - /** Constructor*/ - Config(); - /** Destructor*/ - ~Config(); - struct { - char *LinuxOSSWaveOutDev,*LinuxOSSSeqInDev; - int SampleRate,SoundBufferSize,OscilSize,SwapStereo; - int WindowsWaveOutId,WindowsMidiInId; - int BankUIAutoClose; - int DumpNotesToFile,DumpAppend; - int GzipCompression; - int Interpolation; - char *DumpFile; - char *bankRootDirList[MAX_BANK_ROOT_DIRS],*currentBankDir; - char *presetsDirList[MAX_BANK_ROOT_DIRS]; - int CheckPADsynth; - int UserInterfaceMode; - int VirKeybLayout; - } cfg; - int winwavemax,winmidimax;//number of wave/midi devices on Windows - int maxstringsize; + public: + /** Constructor*/ + Config(); + /** Destructor*/ + ~Config(); + struct { + char *LinuxOSSWaveOutDev, *LinuxOSSSeqInDev; + int SampleRate, SoundBufferSize, OscilSize, SwapStereo; + int WindowsWaveOutId, WindowsMidiInId; + int BankUIAutoClose; + int DumpNotesToFile, DumpAppend; + int GzipCompression; + int Interpolation; + char *DumpFile; + char *bankRootDirList[MAX_BANK_ROOT_DIRS], *currentBankDir; + char *presetsDirList[MAX_BANK_ROOT_DIRS]; + int CheckPADsynth; + int UserInterfaceMode; + int VirKeybLayout; + } cfg; + int winwavemax, winmidimax; //number of wave/midi devices on Windows + int maxstringsize; - struct winmidionedevice { - char *name; - }; - winmidionedevice *winmididevices; + struct winmidionedevice { + char *name; + }; + winmidionedevice *winmididevices; - void clearbankrootdirlist(); - void clearpresetsdirlist(); - void init(); - void save(); + void clearbankrootdirlist(); + void clearpresetsdirlist(); + void init(); + void save(); -private: - void readConfig(const char *filename); - void saveConfig(const char *filename); - void getConfigFileName(char *name,int namesize); + private: + void readConfig(const char *filename); + void saveConfig(const char *filename); + void getConfigFileName(char *name, int namesize); }; #endif diff --git a/src/Misc/Control.h b/src/Misc/Control.h @@ -27,74 +27,74 @@ class Control { -public: - /** - * The parent is the logical owner of this control. Parent should only - * be null for the root node. - * The id is a string uniquely identifying this control within the - * context of the parent control. No spaces or dots are allowed in this - * id. - * Children id's are denoted by <parent-id>.<children-id>, so that one - * can refer to any control in the hierarchy by separating them with - * dots. Example: Main.AddSynth.FrequencyLFO.Amplitude - */ - Control(Control *parent, string id); - - /** - * Will recursively get the XML representation for all the subcontrols. - * Used for saving to file and copy-pasting settings - */ - string getXMLRepresentation(); - - /** - * Set the value of this (and possibly subcomponents as well) based on - * a xml description. - */ - void restoreFromXML(string xml); - - /** - * Register a controluser. This will cause this user to be notified - * whenever the contents of the control changes. - */ - void registerControlUser(ControlUser *user); - - /** - * This should return a string representation of the controls internal - * value - */ - virtual string getStringRepresentation() = 0; - + public: + /** + * The parent is the logical owner of this control. Parent should only + * be null for the root node. + * The id is a string uniquely identifying this control within the + * context of the parent control. No spaces or dots are allowed in this + * id. + * Children id's are denoted by <parent-id>.<children-id>, so that one + * can refer to any control in the hierarchy by separating them with + * dots. Example: Main.AddSynth.FrequencyLFO.Amplitude + */ + Control(Control *parent, string id); + + /** + * Will recursively get the XML representation for all the subcontrols. + * Used for saving to file and copy-pasting settings + */ + string getXMLRepresentation(); + + /** + * Set the value of this (and possibly subcomponents as well) based on + * a xml description. + */ + void restoreFromXML(string xml); + + /** + * Register a controluser. This will cause this user to be notified + * whenever the contents of the control changes. + */ + void registerControlUser(ControlUser *user); + + /** + * This should return a string representation of the controls internal + * value + */ + virtual string getStringRepresentation() = 0; }; -class FloatControl : public Control +class FloatControl:public Control { -public: - /** - * Set the value of this control. If the ControlUser variable is set, - * then this user will not be updated with the new value. This is to - * avoid setting a value being set back to the source that set it - * (which would be redundant, or possibly causing infinite setValue - * loops). - * NOTE: this function is thread-safe (using a mutex internally) - */ - void setValue(float value, ControlUser *user = NULL); - - /** - * Reimplemented from Control - */ - virtual string getStringRepresentation(); - - float value(); + public: + /** + * Set the value of this control. If the ControlUser variable is set, + * then this user will not be updated with the new value. This is to + * avoid setting a value being set back to the source that set it + * (which would be redundant, or possibly causing infinite setValue + * loops). + * NOTE: this function is thread-safe (using a mutex internally) + */ + void setValue(float value, ControlUser *user = NULL); + + /** + * Reimplemented from Control + */ + virtual string getStringRepresentation(); + + float value(); }; class ControlUser { -public: - /** - * Pure virtual method, to notify the controluser that the value has - * been changed internally, and needs to be read again. - */ - virtual void controlUpdated(Control *control) = 0; + public: + /** + * Pure virtual method, to notify the controluser that the value has + * been changed internally, and needs to be read again. + */ + virtual void controlUpdated(Control *control) = 0; }; #endif /* _CONTROL_H_ */ + diff --git a/src/Misc/Dump.cpp b/src/Misc/Dump.cpp @@ -28,80 +28,97 @@ Dump dump; Dump::Dump() { - file=NULL; - tick=0; - k=0; - keyspressed=0; -}; + file = NULL; + tick = 0; + k = 0; + keyspressed = 0; +} Dump::~Dump() { - if (file!=NULL) { - double duration=(double)tick*(double) SOUND_BUFFER_SIZE/(double) SAMPLE_RATE; - fprintf(file,"\n# statistics: duration = %d seconds; keyspressed = %d\n\n\n\n",(int) duration,keyspressed); + if(file != NULL) { + double duration = (double)tick * (double) SOUND_BUFFER_SIZE + / (double) SAMPLE_RATE; + fprintf( + file, + "\n# statistics: duration = %d seconds; keyspressed = %d\n\n\n\n", + (int) duration, + keyspressed); fclose(file); - }; -}; + } +} void Dump::startnow() { - if (file!=NULL) return;//the file is already open - - if (config.cfg.DumpNotesToFile!=0) { - if (config.cfg.DumpAppend!=0) file=fopen(config.cfg.DumpFile,"a"); - else file=fopen(config.cfg.DumpFile,"w"); - if (file==NULL) return; - if (config.cfg.DumpAppend!=0) fprintf(file,"%s","#************************************\n"); - - time_t tm=time(NULL); - - fprintf(file,"#date/time = %s\n",ctime(&tm)); - fprintf(file,"#1 tick = %g milliseconds\n",SOUND_BUFFER_SIZE*1000.0/SAMPLE_RATE); - fprintf(file,"SAMPLERATE = %d\n",SAMPLE_RATE); - fprintf(file,"TICKSIZE = %d #samples\n",SOUND_BUFFER_SIZE); - fprintf(file,"\n\nSTART\n"); - }; -}; + if(file != NULL) + return; //the file is already open + + if(config.cfg.DumpNotesToFile != 0) { + if(config.cfg.DumpAppend != 0) + file = fopen(config.cfg.DumpFile, "a"); + else + file = fopen(config.cfg.DumpFile, "w"); + if(file == NULL) + return; + if(config.cfg.DumpAppend != 0) + fprintf(file, "%s", "#************************************\n"); + + time_t tm = time(NULL); + + fprintf(file, "#date/time = %s\n", ctime(&tm)); + fprintf(file, + "#1 tick = %g milliseconds\n", + SOUND_BUFFER_SIZE * 1000.0 / SAMPLE_RATE); + fprintf(file, "SAMPLERATE = %d\n", SAMPLE_RATE); + fprintf(file, "TICKSIZE = %d #samples\n", SOUND_BUFFER_SIZE); + fprintf(file, "\n\nSTART\n"); + } +} void Dump::inctick() { tick++; -}; +} -void Dump::dumpnote(char chan,char note, char vel) +void Dump::dumpnote(char chan, char note, char vel) { - if (file==NULL) return; - if (note==0) return; - if (vel==0) fprintf(file,"n %d -> %d %d \n",tick,chan,note);//note off - else fprintf(file,"N %d -> %d %d %d \n",tick,chan,note,vel);//note on - - if (vel!=0) keyspressed++; + if(file == NULL) + return; + if(note == 0) + return; + if(vel == 0) + fprintf(file, "n %d -> %d %d \n", tick, chan, note); //note off + else + fprintf(file, "N %d -> %d %d %d \n", tick, chan, note, vel); //note on + + if(vel != 0) + keyspressed++; #ifndef JACKAUDIOOUT - if (k++>25) { + if(k++ > 25) { fflush(file); - k=0; - }; + k = 0; + } #endif -}; +} -void Dump::dumpcontroller(char chan,unsigned int type,int par) +void Dump::dumpcontroller(char chan, unsigned int type, int par) { - if (file==NULL) return; - switch (type) { + if(file == NULL) + return; + switch(type) { case C_pitchwheel: - fprintf(file,"P %d -> %d %d\n",tick,chan,par); + fprintf(file, "P %d -> %d %d\n", tick, chan, par); break; default: - fprintf(file,"C %d -> %d %d %d\n",tick,chan,type,par); + fprintf(file, "C %d -> %d %d %d\n", tick, chan, type, par); break; - }; + } #ifndef JACKAUDIOOUT - if (k++>25) { + if(k++ > 25) { fflush(file); - k=0; - }; + k = 0; + } #endif -}; - +} diff --git a/src/Misc/Dump.h b/src/Misc/Dump.h @@ -30,34 +30,35 @@ * \todo upgrade from stdio to iostream*/ class Dump { -public: - /**Constructor*/ - Dump(); - /**Destructor - * Closes the dumpfile*/ - ~Dump(); - /**Open dumpfile and prepare it for dumps - * \todo see if this fits better in the constructor*/ - void startnow(); - /**Tick the timestamp*/ - void inctick(); - /**Dump Note to dumpfile - * @param chan The channel of the note - * @param note The note - * @param vel The velocity of the note*/ - void dumpnote(char chan,char note, char vel); - /** Dump the Controller - * @param chan The channel of the Controller - * @param type The type - * @param par The value of the controller - * \todo figure out what type is exactly meaning*/ - void dumpcontroller(char chan,unsigned int type,int par); - -private: - FILE *file; - int tick; - int k;//This appears to be a constant used to flush the file - //periodically when JACK is used - int keyspressed; + public: + /**Constructor*/ + Dump(); + /**Destructor + * Closes the dumpfile*/ + ~Dump(); + /**Open dumpfile and prepare it for dumps + * \todo see if this fits better in the constructor*/ + void startnow(); + /**Tick the timestamp*/ + void inctick(); + /**Dump Note to dumpfile + * @param chan The channel of the note + * @param note The note + * @param vel The velocity of the note*/ + void dumpnote(char chan, char note, char vel); + /** Dump the Controller + * @param chan The channel of the Controller + * @param type The type + * @param par The value of the controller + * \todo figure out what type is exactly meaning*/ + void dumpcontroller(char chan, unsigned int type, int par); + + private: + FILE *file; + int tick; + int k; //This appears to be a constant used to flush the file + //periodically when JACK is used + int keyspressed; }; #endif + diff --git a/src/Misc/LASHClient.cpp b/src/Misc/LASHClient.cpp @@ -26,7 +26,7 @@ #include "LASHClient.h" -LASHClient::LASHClient(int* argc, char*** argv) +LASHClient::LASHClient(int *argc, char ***argv) { client = lash_init(lash_extract_args(argc, argv), "ZynAddSubFX", LASH_Config_File, LASH_PROTOCOL(2, 0)); @@ -35,56 +35,54 @@ LASHClient::LASHClient(int* argc, char*** argv) void LASHClient::setalsaid(int id) { - if (lash_enabled(client)) { - if (id != -1) + if(lash_enabled(client)) + if(id != -1) lash_alsa_client_id(client, id); - } } -void LASHClient::setjackname(const char* name) +void LASHClient::setjackname(const char *name) { - if (lash_enabled(client)) { - if (name != NULL) { + if(lash_enabled(client)) + if(name != NULL) { lash_jack_client_name(client, name); lash_event_t *event = lash_event_new_with_type(LASH_Client_Name); lash_event_set_string(event, name); lash_send_event(client, event); } - } } -LASHClient::Event LASHClient::checkevents(std::string& filename) +LASHClient::Event LASHClient::checkevents(std::string &filename) { - - if (!lash_enabled(client)) + if(!lash_enabled(client)) return NoEvent; Event received = NoEvent; - lash_event_t* event; - while (event = lash_get_event(client)) { - + lash_event_t *event; + while(event = lash_get_event(client)) { // save - if (lash_event_get_type(event) == LASH_Save_File) { - std::cerr<<"LASH event: LASH_Save_File"<<std::endl; - filename = std::string(lash_event_get_string(event)) + "/master.xmz"; + if(lash_event_get_type(event) == LASH_Save_File) { + std::cerr << "LASH event: LASH_Save_File" << std::endl; + filename = std::string(lash_event_get_string(event)) + + "/master.xmz"; received = Save; break; } - // restore - else if (lash_event_get_type(event) == LASH_Restore_File) { - std::cerr<<"LASH event: LASH_Restore_File"<<std::endl; - filename = std::string(lash_event_get_string(event)) + "/master.xmz"; + else + if(lash_event_get_type(event) == LASH_Restore_File) { + std::cerr << "LASH event: LASH_Restore_File" << std::endl; + filename = std::string(lash_event_get_string(event)) + + "/master.xmz"; received = Restore; break; } - // quit - else if (lash_event_get_type(event) == LASH_Quit) { - std::cerr<<"LASH event: LASH_Quit"<<std::endl; + else + if(lash_event_get_type(event) == LASH_Quit) { + std::cerr << "LASH event: LASH_Quit" << std::endl; received = Quit; break; } @@ -97,8 +95,10 @@ LASHClient::Event LASHClient::checkevents(std::string& filename) void LASHClient::confirmevent(Event event) { - if (event == Save) + if(event == Save) lash_send_event(client, lash_event_new_with_type(LASH_Save_File)); - else if (event == Restore) + else + if(event == Restore) lash_send_event(client, lash_event_new_with_type(LASH_Restore_File)); } + diff --git a/src/Misc/LASHClient.h b/src/Misc/LASHClient.h @@ -33,32 +33,32 @@ * \todo see why there is no destructor*/ class LASHClient { -public: - /**Enum to represent the LASH events that are currently handled*/ - enum Event { - Save, - Restore, - Quit, - NoEvent - }; + public: + /**Enum to represent the LASH events that are currently handled*/ + enum Event { + Save, + Restore, + Quit, + NoEvent + }; - /** Constructor - * @param argc number of arguments - * @param argv the text arguments*/ - LASHClient(int* argc, char*** argv); + /** Constructor + * @param argc number of arguments + * @param argv the text arguments*/ + LASHClient(int *argc, char ***argv); - /**set the ALSA id - * @param id new ALSA id*/ - void setalsaid(int id); - /**Set the JACK name - * @param name the new name*/ - void setjackname(const char* name); - Event checkevents(std::string& filename); - void confirmevent(Event event); + /**set the ALSA id + * @param id new ALSA id*/ + void setalsaid(int id); + /**Set the JACK name + * @param name the new name*/ + void setjackname(const char *name); + Event checkevents(std::string &filename); + void confirmevent(Event event); -private: + private: - lash_client_t* client; + lash_client_t *client; }; diff --git a/src/Misc/Master.cpp b/src/Misc/Master.cpp @@ -31,231 +31,237 @@ Master::Master() { - swaplr=0; + swaplr = 0; - pthread_mutex_init(&mutex,NULL); - fft=new FFTwrapper(OSCIL_SIZE); + pthread_mutex_init(&mutex, NULL); + fft = new FFTwrapper(OSCIL_SIZE); - tmpmixl=new REALTYPE[SOUND_BUFFER_SIZE]; - tmpmixr=new REALTYPE[SOUND_BUFFER_SIZE]; - audiooutl=new REALTYPE[SOUND_BUFFER_SIZE]; - audiooutr=new REALTYPE[SOUND_BUFFER_SIZE]; + tmpmixl = new REALTYPE[SOUND_BUFFER_SIZE]; + tmpmixr = new REALTYPE[SOUND_BUFFER_SIZE]; + audiooutl = new REALTYPE[SOUND_BUFFER_SIZE]; + audiooutr = new REALTYPE[SOUND_BUFFER_SIZE]; - ksoundbuffersample=-1;//this is only time when this is -1; this means that the GetAudioOutSamples was never called - ksoundbuffersamplelow=0.0; - oldsamplel=0.0; - oldsampler=0.0; - shutup=0; - for (int npart=0;npart<NUM_MIDI_PARTS;npart++) { - vuoutpeakpart[npart]=1e-9; - fakepeakpart[npart]=0; - }; + ksoundbuffersample = -1; //this is only time when this is -1; this means that the GetAudioOutSamples was never called + ksoundbuffersamplelow = 0.0; + oldsamplel = 0.0; + oldsampler = 0.0; + shutup = 0; + for(int npart = 0; npart < NUM_MIDI_PARTS; npart++) { + vuoutpeakpart[npart] = 1e-9; + fakepeakpart[npart] = 0; + } - for (int i=0;i<SOUND_BUFFER_SIZE;i++) { - audiooutl[i]=0.0; - audiooutr[i]=0.0; - }; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + audiooutl[i] = 0.0; + audiooutr[i] = 0.0; + } - for (int npart=0;npart<NUM_MIDI_PARTS;npart++) - part[npart]=new Part(&microtonal,fft,&mutex); + for(int npart = 0; npart < NUM_MIDI_PARTS; npart++) + part[npart] = new Part(&microtonal, fft, &mutex); //Insertion Effects init - for (int nefx=0;nefx<NUM_INS_EFX;nefx++) - insefx[nefx]=new EffectMgr(1,&mutex); + for(int nefx = 0; nefx < NUM_INS_EFX; nefx++) + insefx[nefx] = new EffectMgr(1, &mutex); //System Effects init - for (int nefx=0;nefx<NUM_SYS_EFX;nefx++) { - sysefx[nefx]=new EffectMgr(0,&mutex); - }; + for(int nefx = 0; nefx < NUM_SYS_EFX; nefx++) + sysefx[nefx] = new EffectMgr(0, &mutex); + ; defaults(); -}; +} void Master::defaults() { - volume=1.0; + volume = 1.0; setPvolume(80); setPkeyshift(64); - for (int npart=0;npart<NUM_MIDI_PARTS;npart++) { + for(int npart = 0; npart < NUM_MIDI_PARTS; npart++) { part[npart]->defaults(); - part[npart]->Prcvchn=npart%NUM_MIDI_CHANNELS; - }; + part[npart]->Prcvchn = npart % NUM_MIDI_CHANNELS; + } - partonoff(0,1);//enable the first part + partonoff(0, 1); //enable the first part - for (int nefx=0;nefx<NUM_INS_EFX;nefx++) { + for(int nefx = 0; nefx < NUM_INS_EFX; nefx++) { insefx[nefx]->defaults(); - Pinsparts[nefx]=-1; - }; + Pinsparts[nefx] = -1; + } //System Effects init - for (int nefx=0;nefx<NUM_SYS_EFX;nefx++) { + for(int nefx = 0; nefx < NUM_SYS_EFX; nefx++) { sysefx[nefx]->defaults(); - for (int npart=0;npart<NUM_MIDI_PARTS;npart++) { + for(int npart = 0; npart < NUM_MIDI_PARTS; npart++) //if (nefx==0) setPsysefxvol(npart,nefx,64); //else - setPsysefxvol(npart,nefx,0); - }; - for (int nefxto=0;nefxto<NUM_SYS_EFX;nefxto++) - setPsysefxsend(nefx,nefxto,0); - }; + setPsysefxvol(npart, nefx, 0); + ; + for(int nefxto = 0; nefxto < NUM_SYS_EFX; nefxto++) + setPsysefxsend(nefx, nefxto, 0); + } // sysefx[0]->changeeffect(1); microtonal.defaults(); ShutUp(); -}; +} /* * Note On Messages (velocity=0 for NoteOff) */ -void Master::NoteOn(unsigned char chan,unsigned char note,unsigned char velocity) +void Master::NoteOn(unsigned char chan, + unsigned char note, + unsigned char velocity) { - dump.dumpnote(chan,note,velocity); + dump.dumpnote(chan, note, velocity); - noteon(chan,note,velocity); -}; + noteon(chan, note, velocity); +} /* * Internal Note On (velocity=0 for NoteOff) */ -void Master::noteon(unsigned char chan,unsigned char note,unsigned char velocity) +void Master::noteon(unsigned char chan, + unsigned char note, + unsigned char velocity) { int npart; - if (velocity!=0) { - for (npart=0;npart<NUM_MIDI_PARTS;npart++) { - if (chan==part[npart]->Prcvchn) { - fakepeakpart[npart]=velocity*2; - if (part[npart]->Penabled!=0) part[npart]->NoteOn(note,velocity,keyshift); - }; - }; - } else { - this->NoteOff(chan,note); - }; + if(velocity != 0) { + for(npart = 0; npart < NUM_MIDI_PARTS; npart++) { + if(chan == part[npart]->Prcvchn) { + fakepeakpart[npart] = velocity * 2; + if(part[npart]->Penabled != 0) + part[npart]->NoteOn(note, velocity, keyshift); + } + } + } + else + this->NoteOff(chan, note); + ; HDDRecorder.triggernow(); -}; +} /* * Note Off Messages */ -void Master::NoteOff(unsigned char chan,unsigned char note) +void Master::NoteOff(unsigned char chan, unsigned char note) { - dump.dumpnote(chan,note,0); + dump.dumpnote(chan, note, 0); - noteoff(chan,note); -}; + noteoff(chan, note); +} /* * Internal Note Off */ -void Master::noteoff(unsigned char chan,unsigned char note) +void Master::noteoff(unsigned char chan, unsigned char note) { int npart; - for (npart=0;npart<NUM_MIDI_PARTS;npart++) { - if ((chan==part[npart]->Prcvchn) && (part[npart]->Penabled!=0)) + for(npart = 0; npart < NUM_MIDI_PARTS; npart++) + if((chan == part[npart]->Prcvchn) && (part[npart]->Penabled != 0)) part[npart]->NoteOff(note); - }; -}; + ; +} /* * Controllers */ -void Master::SetController(unsigned char chan,unsigned int type,int par) +void Master::SetController(unsigned char chan, unsigned int type, int par) { - dump.dumpcontroller(chan,type,par); + dump.dumpcontroller(chan, type, par); - setcontroller(chan,type,par); -}; + setcontroller(chan, type, par); +} /* * Internal Controllers */ -void Master::setcontroller(unsigned char chan,unsigned int type,int par) +void Master::setcontroller(unsigned char chan, unsigned int type, int par) { - if ((type==C_dataentryhi)||(type==C_dataentrylo)|| - (type==C_nrpnhi)||(type==C_nrpnlo)) {//Process RPN and NRPN by the Master (ignore the chan) - ctl.setparameternumber(type,par); + if((type == C_dataentryhi) || (type == C_dataentrylo) + || (type == C_nrpnhi) || (type == C_nrpnlo)) { //Process RPN and NRPN by the Master (ignore the chan) + ctl.setparameternumber(type, par); - int parhi=-1,parlo=-1,valhi=-1,vallo=-1; - if (ctl.getnrpn(&parhi,&parlo,&valhi,&vallo)==0) {//this is NRPN + int parhi = -1, parlo = -1, valhi = -1, vallo = -1; + if(ctl.getnrpn(&parhi, &parlo, &valhi, &vallo) == 0) //this is NRPN //fprintf(stderr,"rcv. NRPN: %d %d %d %d\n",parhi,parlo,valhi,vallo); - switch (parhi) { - case 0x04://System Effects - if (parlo<NUM_SYS_EFX) { - sysefx[parlo]->seteffectpar_nolock(valhi,vallo); - }; + switch(parhi) { + case 0x04: //System Effects + if(parlo < NUM_SYS_EFX) + sysefx[parlo]->seteffectpar_nolock(valhi, vallo); + ; break; - case 0x08://Insertion Effects - if (parlo<NUM_INS_EFX) { - insefx[parlo]->seteffectpar_nolock(valhi,vallo); - }; + case 0x08: //Insertion Effects + if(parlo < NUM_INS_EFX) + insefx[parlo]->seteffectpar_nolock(valhi, vallo); + ; break; - - }; - }; - } else {//other controllers - for (int npart=0;npart<NUM_MIDI_PARTS;npart++) {//Send the controller to all part assigned to the channel - if ((chan==part[npart]->Prcvchn) && (part[npart]->Penabled!=0)) - part[npart]->SetController(type,par); - }; - - if (type==C_allsoundsoff) { //cleanup insertion/system FX - for (int nefx=0;nefx<NUM_SYS_EFX;++nefx) { - sysefx[nefx]->cleanup(); } - for (int nefx=0;nefx<NUM_INS_EFX;++nefx) { + ; + } + else { //other controllers + for(int npart = 0; npart < NUM_MIDI_PARTS; npart++) //Send the controller to all part assigned to the channel + if((chan == part[npart]->Prcvchn) && (part[npart]->Penabled != 0)) + part[npart]->SetController(type, par); + ; + + if(type == C_allsoundsoff) { //cleanup insertion/system FX + for(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx) + sysefx[nefx]->cleanup(); + for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx) insefx[nefx]->cleanup(); - } } - }; -}; + } +} /* * Enable/Disable a part */ -void Master::partonoff(int npart,int what) +void Master::partonoff(int npart, int what) { - if (npart>=NUM_MIDI_PARTS) return; - if (what==0) {//disable part - fakepeakpart[npart]=0; - part[npart]->Penabled=0; + if(npart >= NUM_MIDI_PARTS) + return; + if(what == 0) { //disable part + fakepeakpart[npart] = 0; + part[npart]->Penabled = 0; part[npart]->cleanup(); - for (int nefx=0;nefx<NUM_INS_EFX;nefx++) { - if (Pinsparts[nefx]==npart) { + for(int nefx = 0; nefx < NUM_INS_EFX; nefx++) { + if(Pinsparts[nefx] == npart) insefx[nefx]->cleanup(); - }; - }; - } else {//enabled - part[npart]->Penabled=1; - fakepeakpart[npart]=0; - }; -}; + ; + } + } + else { //enabled + part[npart]->Penabled = 1; + fakepeakpart[npart] = 0; + } +} /* * Master audio out (the final sound) */ -void Master::AudioOut(REALTYPE *outl,REALTYPE *outr) +void Master::AudioOut(REALTYPE *outl, REALTYPE *outr) { - int i,npart,nefx; + int i, npart, nefx; /* //test!!!!!!!!!!!!! se poate bloca aici (mutex) if (seq.play){ - int type,par1,par2,again,midichan; - int ntrack=1; + int type,par1,par2,again,midichan; + int ntrack=1; // do{ - again=seq.getevent(ntrack,&midichan,&type,&par1,&par2); - if (type>0) { + again=seq.getevent(ntrack,&midichan,&type,&par1,&par2); + if (type>0) { // printf("aaa\n"); - if (type==1){//note_on or note_off - if (par2!=0) NoteOn(midichan,par1,par2); - else NoteOff(midichan,par1); - }; - }; + if (type==1){//note_on or note_off + if (par2!=0) NoteOn(midichan,par1,par2); + else NoteOff(midichan,par1); + }; + }; // } while (again); }; */ @@ -265,250 +271,287 @@ void Master::AudioOut(REALTYPE *outl,REALTYPE *outr) //Swaps the Left channel with Right Channel (if it is asked for) - if (swaplr!=0) { - REALTYPE *tmp=outl; - outl=outr; - outr=tmp; - }; + if(swaplr != 0) { + REALTYPE *tmp = outl; + outl = outr; + outr = tmp; + } //clean up the output samples - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - outl[i]=0.0; - outr[i]=0.0; - }; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + outl[i] = 0.0; + outr[i] = 0.0; + } //Compute part samples and store them part[npart]->partoutl,partoutr - for (npart=0;npart<NUM_MIDI_PARTS;npart++) - if (part[npart]->Penabled!=0) part[npart]->ComputePartSmps(); + for(npart = 0; npart < NUM_MIDI_PARTS; npart++) + if(part[npart]->Penabled != 0) + part[npart]->ComputePartSmps(); //Insertion effects - for (nefx=0;nefx<NUM_INS_EFX;nefx++) { - if (Pinsparts[nefx]>=0) { - int efxpart=Pinsparts[nefx]; - if (part[efxpart]->Penabled!=0) - insefx[nefx]->out(part[efxpart]->partoutl,part[efxpart]->partoutr); - }; - }; + for(nefx = 0; nefx < NUM_INS_EFX; nefx++) { + if(Pinsparts[nefx] >= 0) { + int efxpart = Pinsparts[nefx]; + if(part[efxpart]->Penabled != 0) + insefx[nefx]->out(part[efxpart]->partoutl, + part[efxpart]->partoutr); + } + } //Apply the part volumes and pannings (after insertion effects) - for (npart=0;npart<NUM_MIDI_PARTS;npart++) { - if (part[npart]->Penabled==0) continue; - - REALTYPE newvol_l=part[npart]->volume; - REALTYPE newvol_r=part[npart]->volume; - REALTYPE oldvol_l=part[npart]->oldvolumel; - REALTYPE oldvol_r=part[npart]->oldvolumer; - REALTYPE pan=part[npart]->panning; - if (pan<0.5) newvol_l*=pan*2.0; - else newvol_r*=(1.0-pan)*2.0; - - if (ABOVE_AMPLITUDE_THRESHOLD(oldvol_l,newvol_l)|| - ABOVE_AMPLITUDE_THRESHOLD(oldvol_r,newvol_r)) {//the volume or the panning has changed and needs interpolation - - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - REALTYPE vol_l=INTERPOLATE_AMPLITUDE(oldvol_l,newvol_l,i,SOUND_BUFFER_SIZE); - REALTYPE vol_r=INTERPOLATE_AMPLITUDE(oldvol_r,newvol_r,i,SOUND_BUFFER_SIZE); - part[npart]->partoutl[i]*=vol_l; - part[npart]->partoutr[i]*=vol_r; - }; - part[npart]->oldvolumel=newvol_l; - part[npart]->oldvolumer=newvol_r; - - } else { - for (i=0;i<SOUND_BUFFER_SIZE;i++) {//the volume did not changed - part[npart]->partoutl[i]*=newvol_l; - part[npart]->partoutr[i]*=newvol_r; - }; - }; - }; + for(npart = 0; npart < NUM_MIDI_PARTS; npart++) { + if(part[npart]->Penabled == 0) + continue; + + REALTYPE newvol_l = part[npart]->volume; + REALTYPE newvol_r = part[npart]->volume; + REALTYPE oldvol_l = part[npart]->oldvolumel; + REALTYPE oldvol_r = part[npart]->oldvolumer; + REALTYPE pan = part[npart]->panning; + if(pan < 0.5) + newvol_l *= pan * 2.0; + else + newvol_r *= (1.0 - pan) * 2.0; + + if(ABOVE_AMPLITUDE_THRESHOLD(oldvol_l, newvol_l) + || ABOVE_AMPLITUDE_THRESHOLD(oldvol_r, newvol_r)) { //the volume or the panning has changed and needs interpolation + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + REALTYPE vol_l = INTERPOLATE_AMPLITUDE(oldvol_l, + newvol_l, + i, + SOUND_BUFFER_SIZE); + REALTYPE vol_r = INTERPOLATE_AMPLITUDE(oldvol_r, + newvol_r, + i, + SOUND_BUFFER_SIZE); + part[npart]->partoutl[i] *= vol_l; + part[npart]->partoutr[i] *= vol_r; + } + part[npart]->oldvolumel = newvol_l; + part[npart]->oldvolumer = newvol_r; + } + else { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //the volume did not changed + part[npart]->partoutl[i] *= newvol_l; + part[npart]->partoutr[i] *= newvol_r; + } + } + } //System effects - for (nefx=0;nefx<NUM_SYS_EFX;nefx++) { - if (sysefx[nefx]->geteffect()==0) continue;//the effect is disabled + for(nefx = 0; nefx < NUM_SYS_EFX; nefx++) { + if(sysefx[nefx]->geteffect() == 0) + continue; //the effect is disabled //Clean up the samples used by the system effects - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - tmpmixl[i]=0.0; - tmpmixr[i]=0.0; - }; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tmpmixl[i] = 0.0; + tmpmixr[i] = 0.0; + } //Mix the channels according to the part settings about System Effect - for (npart=0;npart<NUM_MIDI_PARTS;npart++) { + for(npart = 0; npart < NUM_MIDI_PARTS; npart++) { //skip if the part has no output to effect - if (Psysefxvol[nefx][npart]==0) continue; + if(Psysefxvol[nefx][npart] == 0) + continue; //skip if the part is disabled - if (part[npart]->Penabled==0) continue; + if(part[npart]->Penabled == 0) + continue; //the output volume of each part to system effect - REALTYPE vol=sysefxvol[nefx][npart]; - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - tmpmixl[i]+=part[npart]->partoutl[i]*vol; - tmpmixr[i]+=part[npart]->partoutr[i]*vol; - }; - }; + REALTYPE vol = sysefxvol[nefx][npart]; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tmpmixl[i] += part[npart]->partoutl[i] * vol; + tmpmixr[i] += part[npart]->partoutr[i] * vol; + } + } // system effect send to next ones - for (int nefxfrom=0;nefxfrom<nefx;nefxfrom++) { - if (Psysefxsend[nefxfrom][nefx]!=0) { - REALTYPE v=sysefxsend[nefxfrom][nefx]; - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - tmpmixl[i]+=sysefx[nefxfrom]->efxoutl[i]*v; - tmpmixr[i]+=sysefx[nefxfrom]->efxoutr[i]*v; - }; - }; - }; + for(int nefxfrom = 0; nefxfrom < nefx; nefxfrom++) { + if(Psysefxsend[nefxfrom][nefx] != 0) { + REALTYPE v = sysefxsend[nefxfrom][nefx]; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tmpmixl[i] += sysefx[nefxfrom]->efxoutl[i] * v; + tmpmixr[i] += sysefx[nefxfrom]->efxoutr[i] * v; + } + } + } - sysefx[nefx]->out(tmpmixl,tmpmixr); + sysefx[nefx]->out(tmpmixl, tmpmixr); //Add the System Effect to sound output - REALTYPE outvol=sysefx[nefx]->sysefxgetvolume(); - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - outl[i]+=tmpmixl[i]*outvol; - outr[i]+=tmpmixr[i]*outvol; - }; - - }; + REALTYPE outvol = sysefx[nefx]->sysefxgetvolume(); + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + outl[i] += tmpmixl[i] * outvol; + outr[i] += tmpmixr[i] * outvol; + } + } //Mix all parts - for (npart=0;npart<NUM_MIDI_PARTS;npart++) { - for (i=0;i<SOUND_BUFFER_SIZE;i++) {//the volume did not changed - outl[i]+=part[npart]->partoutl[i]; - outr[i]+=part[npart]->partoutr[i]; - }; - }; + for(npart = 0; npart < NUM_MIDI_PARTS; npart++) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //the volume did not changed + outl[i] += part[npart]->partoutl[i]; + outr[i] += part[npart]->partoutr[i]; + } + } //Insertion effects for Master Out - for (nefx=0;nefx<NUM_INS_EFX;nefx++) { - if (Pinsparts[nefx] == -2) - insefx[nefx]->out(outl,outr); - }; + for(nefx = 0; nefx < NUM_INS_EFX; nefx++) + if(Pinsparts[nefx] == -2) + insefx[nefx]->out(outl, outr); + ; //Master Volume - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - outl[i]*=volume; - outr[i]*=volume; - }; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + outl[i] *= volume; + outr[i] *= volume; + } //Peak computation (for vumeters) - vuoutpeakl=1e-12; - vuoutpeakr=1e-12; - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - if (fabs(outl[i])>vuoutpeakl) vuoutpeakl=fabs(outl[i]); - if (fabs(outr[i])>vuoutpeakr) vuoutpeakr=fabs(outr[i]); - }; - if ((vuoutpeakl>1.0)||(vuoutpeakr>1.0)) vuclipped=1; - if (vumaxoutpeakl<vuoutpeakl) vumaxoutpeakl=vuoutpeakl; - if (vumaxoutpeakr<vuoutpeakr) vumaxoutpeakr=vuoutpeakr; + vuoutpeakl = 1e-12; + vuoutpeakr = 1e-12; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + if(fabs(outl[i]) > vuoutpeakl) + vuoutpeakl = fabs(outl[i]); + if(fabs(outr[i]) > vuoutpeakr) + vuoutpeakr = fabs(outr[i]); + } + if((vuoutpeakl > 1.0) || (vuoutpeakr > 1.0)) + vuclipped = 1; + if(vumaxoutpeakl < vuoutpeakl) + vumaxoutpeakl = vuoutpeakl; + if(vumaxoutpeakr < vuoutpeakr) + vumaxoutpeakr = vuoutpeakr; //RMS Peak computation (for vumeters) - vurmspeakl=1e-12; - vurmspeakr=1e-12; - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - vurmspeakl+=outl[i]*outl[i]; - vurmspeakr+=outr[i]*outr[i]; - }; - vurmspeakl=sqrt(vurmspeakl/SOUND_BUFFER_SIZE); - vurmspeakr=sqrt(vurmspeakr/SOUND_BUFFER_SIZE); + vurmspeakl = 1e-12; + vurmspeakr = 1e-12; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + vurmspeakl += outl[i] * outl[i]; + vurmspeakr += outr[i] * outr[i]; + } + vurmspeakl = sqrt(vurmspeakl / SOUND_BUFFER_SIZE); + vurmspeakr = sqrt(vurmspeakr / SOUND_BUFFER_SIZE); //Part Peak computation (for Part vumeters or fake part vumeters) - for (npart=0;npart<NUM_MIDI_PARTS;npart++) { - vuoutpeakpart[npart]=1.0e-12; - if (part[npart]->Penabled!=0) { - REALTYPE *outl=part[npart]->partoutl, - *outr=part[npart]->partoutr; - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - REALTYPE tmp=fabs(outl[i]+outr[i]); - if (tmp>vuoutpeakpart[npart]) vuoutpeakpart[npart]=tmp; - }; - vuoutpeakpart[npart]*=volume; - } else { - if (fakepeakpart[npart]>1) fakepeakpart[npart]--; - }; - }; + for(npart = 0; npart < NUM_MIDI_PARTS; npart++) { + vuoutpeakpart[npart] = 1.0e-12; + if(part[npart]->Penabled != 0) { + REALTYPE *outl = part[npart]->partoutl, + *outr = part[npart]->partoutr; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + REALTYPE tmp = fabs(outl[i] + outr[i]); + if(tmp > vuoutpeakpart[npart]) + vuoutpeakpart[npart] = tmp; + } + vuoutpeakpart[npart] *= volume; + } + else + if(fakepeakpart[npart] > 1) + fakepeakpart[npart]--; + ; + } //Shutup if it is asked (with fade-out) - if (shutup!=0) { - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - REALTYPE tmp=(SOUND_BUFFER_SIZE-i)/(REALTYPE) SOUND_BUFFER_SIZE; - outl[i]*=tmp; - outr[i]*=tmp; - }; + if(shutup != 0) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + REALTYPE tmp = + (SOUND_BUFFER_SIZE - i) / (REALTYPE) SOUND_BUFFER_SIZE; + outl[i] *= tmp; + outr[i] *= tmp; + } ShutUp(); - }; + } //update the LFO's time LFOParams::time++; - if (HDDRecorder.recording()) HDDRecorder.recordbuffer(outl,outr); + if(HDDRecorder.recording()) + HDDRecorder.recordbuffer(outl, outr); dump.inctick(); -}; +} -void Master::GetAudioOutSamples(int nsamples,int samplerate,REALTYPE *outl,REALTYPE *outr) +void Master::GetAudioOutSamples(int nsamples, + int samplerate, + REALTYPE *outl, + REALTYPE *outr) { - if (ksoundbuffersample==-1) {//first time - AudioOut(&audiooutl[0],&audiooutr[0]); - ksoundbuffersample=0; - }; + if(ksoundbuffersample == -1) { //first time + AudioOut(&audiooutl[0], &audiooutr[0]); + ksoundbuffersample = 0; + } - if (samplerate==SAMPLE_RATE) {//no resample - int ksample=0; - while (ksample<nsamples) { - outl[ksample]=audiooutl[ksoundbuffersample]; - outr[ksample]=audiooutr[ksoundbuffersample]; + if(samplerate == SAMPLE_RATE) { //no resample + int ksample = 0; + while(ksample < nsamples) { + outl[ksample] = audiooutl[ksoundbuffersample]; + outr[ksample] = audiooutr[ksoundbuffersample]; ksample++; ksoundbuffersample++; - if (ksoundbuffersample>=SOUND_BUFFER_SIZE) { - AudioOut(&audiooutl[0],&audiooutr[0]); - ksoundbuffersample=0; - }; - }; - } else {//Resample - int ksample=0; - REALTYPE srinc=SAMPLE_RATE/(REALTYPE)samplerate; - - while (ksample<nsamples) { - if (ksoundbuffersample!=0) { - outl[ksample]=audiooutl[ksoundbuffersample]*ksoundbuffersamplelow - +audiooutl[ksoundbuffersample-1]*(1.0-ksoundbuffersamplelow); - outr[ksample]=audiooutr[ksoundbuffersample]*ksoundbuffersamplelow - +audiooutr[ksoundbuffersample-1]*(1.0-ksoundbuffersamplelow); - } else { - outl[ksample]=audiooutl[ksoundbuffersample]*ksoundbuffersamplelow - +oldsamplel*(1.0-ksoundbuffersamplelow); - outr[ksample]=audiooutr[ksoundbuffersample]*ksoundbuffersamplelow - +oldsampler*(1.0-ksoundbuffersamplelow); - }; + if(ksoundbuffersample >= SOUND_BUFFER_SIZE) { + AudioOut(&audiooutl[0], &audiooutr[0]); + ksoundbuffersample = 0; + } + } + } + else { //Resample + int ksample = 0; + REALTYPE srinc = SAMPLE_RATE / (REALTYPE)samplerate; + + while(ksample < nsamples) { + if(ksoundbuffersample != 0) { + outl[ksample] = audiooutl[ksoundbuffersample] + * ksoundbuffersamplelow + + audiooutl[ksoundbuffersample + - 1] * (1.0 - ksoundbuffersamplelow); + outr[ksample] = audiooutr[ksoundbuffersample] + * ksoundbuffersamplelow + + audiooutr[ksoundbuffersample + - 1] * (1.0 - ksoundbuffersamplelow); + } + else { + outl[ksample] = audiooutl[ksoundbuffersample] + * ksoundbuffersamplelow + + oldsamplel * (1.0 - ksoundbuffersamplelow); + outr[ksample] = audiooutr[ksoundbuffersample] + * ksoundbuffersamplelow + + oldsampler * (1.0 - ksoundbuffersamplelow); + } ksample++; - ksoundbuffersamplelow+=srinc; - if (ksoundbuffersamplelow>=1.0) { - ksoundbuffersample+=(int) floor(ksoundbuffersamplelow); - ksoundbuffersamplelow=ksoundbuffersamplelow-floor(ksoundbuffersamplelow); - }; + ksoundbuffersamplelow += srinc; + if(ksoundbuffersamplelow >= 1.0) { + ksoundbuffersample += (int) floor(ksoundbuffersamplelow); + ksoundbuffersamplelow = ksoundbuffersamplelow - floor( + ksoundbuffersamplelow); + } - if (ksoundbuffersample>=SOUND_BUFFER_SIZE) { - oldsamplel=audiooutl[SOUND_BUFFER_SIZE-1]; - oldsampler=audiooutr[SOUND_BUFFER_SIZE-1]; - AudioOut(&audiooutl[0],&audiooutr[0]); - ksoundbuffersample=0; - }; - }; - }; -}; + if(ksoundbuffersample >= SOUND_BUFFER_SIZE) { + oldsamplel = audiooutl[SOUND_BUFFER_SIZE - 1]; + oldsampler = audiooutr[SOUND_BUFFER_SIZE - 1]; + AudioOut(&audiooutl[0], &audiooutr[0]); + ksoundbuffersample = 0; + } + } + } +} Master::~Master() { - for (int npart=0;npart<NUM_MIDI_PARTS;npart++) delete part[npart]; - for (int nefx=0;nefx<NUM_INS_EFX;nefx++) delete insefx[nefx]; - for (int nefx=0;nefx<NUM_SYS_EFX;nefx++) delete sysefx[nefx]; + for(int npart = 0; npart < NUM_MIDI_PARTS; npart++) + delete part[npart]; + for(int nefx = 0; nefx < NUM_INS_EFX; nefx++) + delete insefx[nefx]; + for(int nefx = 0; nefx < NUM_SYS_EFX; nefx++) + delete sysefx[nefx]; delete [] audiooutl; delete [] audiooutr; @@ -517,7 +560,7 @@ Master::~Master() delete (fft); pthread_mutex_destroy(&mutex); -}; +} /* @@ -525,28 +568,28 @@ Master::~Master() */ void Master::setPvolume(char Pvolume_) { - Pvolume=Pvolume_; - volume=dB2rap((Pvolume-96.0)/96.0*40.0); -}; + Pvolume = Pvolume_; + volume = dB2rap((Pvolume - 96.0) / 96.0 * 40.0); +} void Master::setPkeyshift(char Pkeyshift_) { - Pkeyshift=Pkeyshift_; - keyshift=(int)Pkeyshift-64; -}; + Pkeyshift = Pkeyshift_; + keyshift = (int)Pkeyshift - 64; +} -void Master::setPsysefxvol(int Ppart,int Pefx,char Pvol) +void Master::setPsysefxvol(int Ppart, int Pefx, char Pvol) { - Psysefxvol[Pefx][Ppart]=Pvol; - sysefxvol[Pefx][Ppart]=pow(0.1,(1.0-Pvol/96.0)*2.0); -}; + Psysefxvol[Pefx][Ppart] = Pvol; + sysefxvol[Pefx][Ppart] = pow(0.1, (1.0 - Pvol / 96.0) * 2.0); +} -void Master::setPsysefxsend(int Pefxfrom,int Pefxto,char Pvol) +void Master::setPsysefxsend(int Pefxfrom, int Pefxto, char Pvol) { - Psysefxsend[Pefxfrom][Pefxto]=Pvol; - sysefxsend[Pefxfrom][Pefxto]=pow(0.1,(1.0-Pvol/96.0)*2.0); -}; + Psysefxsend[Pefxfrom][Pefxto] = Pvol; + sysefxsend[Pefxfrom][Pefxto] = pow(0.1, (1.0 - Pvol / 96.0) * 2.0); +} /* @@ -554,15 +597,17 @@ void Master::setPsysefxsend(int Pefxfrom,int Pefxto,char Pvol) */ void Master::ShutUp() { - for (int npart=0;npart<NUM_MIDI_PARTS;npart++) { + for(int npart = 0; npart < NUM_MIDI_PARTS; npart++) { part[npart]->cleanup(); - fakepeakpart[npart]=0; - }; - for (int nefx=0;nefx<NUM_INS_EFX;nefx++) insefx[nefx]->cleanup(); - for (int nefx=0;nefx<NUM_SYS_EFX;nefx++) sysefx[nefx]->cleanup(); + fakepeakpart[npart] = 0; + } + for(int nefx = 0; nefx < NUM_INS_EFX; nefx++) + insefx[nefx]->cleanup(); + for(int nefx = 0; nefx < NUM_SYS_EFX; nefx++) + sysefx[nefx]->cleanup(); vuresetpeaks(); - shutup=0; -}; + shutup = 0; +} /* @@ -570,81 +615,80 @@ void Master::ShutUp() */ void Master::vuresetpeaks() { - vuoutpeakl=1e-9; - vuoutpeakr=1e-9; - vumaxoutpeakl=1e-9; - vumaxoutpeakr=1e-9; - vuclipped=0; -}; + vuoutpeakl = 1e-9; + vuoutpeakr = 1e-9; + vumaxoutpeakl = 1e-9; + vumaxoutpeakr = 1e-9; + vuclipped = 0; +} void Master::applyparameters() { - for (int npart=0;npart<NUM_MIDI_PARTS;npart++) { + for(int npart = 0; npart < NUM_MIDI_PARTS; npart++) part[npart]->applyparameters(); - }; -}; + ; +} void Master::add2XML(XMLwrapper *xml) { - xml->addpar("volume",Pvolume); - xml->addpar("key_shift",Pkeyshift); - xml->addparbool("nrpn_receive",ctl.NRPN.receive); + xml->addpar("volume", Pvolume); + xml->addpar("key_shift", Pkeyshift); + xml->addparbool("nrpn_receive", ctl.NRPN.receive); xml->beginbranch("MICROTONAL"); microtonal.add2XML(xml); xml->endbranch(); - for (int npart=0;npart<NUM_MIDI_PARTS;npart++) { - xml->beginbranch("PART",npart); + for(int npart = 0; npart < NUM_MIDI_PARTS; npart++) { + xml->beginbranch("PART", npart); part[npart]->add2XML(xml); xml->endbranch(); - }; + } xml->beginbranch("SYSTEM_EFFECTS"); - for (int nefx=0;nefx<NUM_SYS_EFX;nefx++) { - xml->beginbranch("SYSTEM_EFFECT",nefx); + for(int nefx = 0; nefx < NUM_SYS_EFX; nefx++) { + xml->beginbranch("SYSTEM_EFFECT", nefx); xml->beginbranch("EFFECT"); sysefx[nefx]->add2XML(xml); xml->endbranch(); - for (int pefx=0;pefx<NUM_MIDI_PARTS;pefx++) { - xml->beginbranch("VOLUME",pefx); - xml->addpar("vol",Psysefxvol[nefx][pefx]); + for(int pefx = 0; pefx < NUM_MIDI_PARTS; pefx++) { + xml->beginbranch("VOLUME", pefx); + xml->addpar("vol", Psysefxvol[nefx][pefx]); xml->endbranch(); - }; + } - for (int tonefx=nefx+1;tonefx<NUM_SYS_EFX;tonefx++) { - xml->beginbranch("SENDTO",tonefx); - xml->addpar("send_vol",Psysefxsend[nefx][tonefx]); + for(int tonefx = nefx + 1; tonefx < NUM_SYS_EFX; tonefx++) { + xml->beginbranch("SENDTO", tonefx); + xml->addpar("send_vol", Psysefxsend[nefx][tonefx]); xml->endbranch(); - }; + } xml->endbranch(); - }; + } xml->endbranch(); xml->beginbranch("INSERTION_EFFECTS"); - for (int nefx=0;nefx<NUM_INS_EFX;nefx++) { - xml->beginbranch("INSERTION_EFFECT",nefx); - xml->addpar("part",Pinsparts[nefx]); + for(int nefx = 0; nefx < NUM_INS_EFX; nefx++) { + xml->beginbranch("INSERTION_EFFECT", nefx); + xml->addpar("part", Pinsparts[nefx]); xml->beginbranch("EFFECT"); insefx[nefx]->add2XML(xml); xml->endbranch(); xml->endbranch(); - }; + } xml->endbranch(); - -}; +} int Master::getalldata(char **data) { - XMLwrapper *xml=new XMLwrapper(); + XMLwrapper *xml = new XMLwrapper(); xml->beginbranch("MASTER"); @@ -654,20 +698,21 @@ int Master::getalldata(char **data) xml->endbranch(); - *data=xml->getXMLdata(); + *data = xml->getXMLdata(); delete (xml); - return(strlen(*data)+1); -}; + return strlen(*data) + 1; +} -void Master::putalldata(char *data,int size) +void Master::putalldata(char *data, int size) { - XMLwrapper *xml=new XMLwrapper(); - if (!xml->putXMLdata(data)) { - delete(xml); + XMLwrapper *xml = new XMLwrapper(); + if(!xml->putXMLdata(data)) { + delete (xml); return; - }; + } - if (xml->enterbranch("MASTER")==0) return; + if(xml->enterbranch("MASTER") == 0) + return; pthread_mutex_lock(&mutex); getfromXML(xml); @@ -675,104 +720,109 @@ void Master::putalldata(char *data,int size) xml->exitbranch(); - delete(xml); -}; + delete (xml); +} int Master::saveXML(const char *filename) { - XMLwrapper *xml=new XMLwrapper(); + XMLwrapper *xml = new XMLwrapper(); xml->beginbranch("MASTER"); add2XML(xml); xml->endbranch(); - int result=xml->saveXMLfile(filename); + int result = xml->saveXMLfile(filename); delete (xml); - return(result); -}; + return result; +} int Master::loadXML(const char *filename) { - XMLwrapper *xml=new XMLwrapper(); - if (xml->loadXMLfile(filename)<0) { - delete(xml); - return(-1); - }; - - if (xml->enterbranch("MASTER")==0) return(-10); + XMLwrapper *xml = new XMLwrapper(); + if(xml->loadXMLfile(filename) < 0) { + delete (xml); + return -1; + } + + if(xml->enterbranch("MASTER") == 0) + return -10; getfromXML(xml); xml->exitbranch(); - delete(xml); - return(0); -}; + delete (xml); + return 0; +} void Master::getfromXML(XMLwrapper *xml) { - setPvolume(xml->getpar127("volume",Pvolume)); - setPkeyshift(xml->getpar127("key_shift",Pkeyshift)); - ctl.NRPN.receive=xml->getparbool("nrpn_receive",ctl.NRPN.receive); + setPvolume(xml->getpar127("volume", Pvolume)); + setPkeyshift(xml->getpar127("key_shift", Pkeyshift)); + ctl.NRPN.receive = xml->getparbool("nrpn_receive", ctl.NRPN.receive); - part[0]->Penabled=0; - for (int npart=0;npart<NUM_MIDI_PARTS;npart++) { - if (xml->enterbranch("PART",npart)==0) continue; + part[0]->Penabled = 0; + for(int npart = 0; npart < NUM_MIDI_PARTS; npart++) { + if(xml->enterbranch("PART", npart) == 0) + continue; part[npart]->getfromXML(xml); xml->exitbranch(); - }; + } - if (xml->enterbranch("MICROTONAL")) { + if(xml->enterbranch("MICROTONAL")) { microtonal.getfromXML(xml); xml->exitbranch(); - }; + } sysefx[0]->changeeffect(0); - if (xml->enterbranch("SYSTEM_EFFECTS")) { - for (int nefx=0;nefx<NUM_SYS_EFX;nefx++) { - if (xml->enterbranch("SYSTEM_EFFECT",nefx)==0) continue; - if (xml->enterbranch("EFFECT")) { + if(xml->enterbranch("SYSTEM_EFFECTS")) { + for(int nefx = 0; nefx < NUM_SYS_EFX; nefx++) { + if(xml->enterbranch("SYSTEM_EFFECT", nefx) == 0) + continue; + if(xml->enterbranch("EFFECT")) { sysefx[nefx]->getfromXML(xml); xml->exitbranch(); - }; + } - for (int partefx=0;partefx<NUM_MIDI_PARTS;partefx++) { - if (xml->enterbranch("VOLUME",partefx)==0) continue; - setPsysefxvol(partefx,nefx,xml->getpar127("vol",Psysefxvol[partefx][nefx])); + for(int partefx = 0; partefx < NUM_MIDI_PARTS; partefx++) { + if(xml->enterbranch("VOLUME", partefx) == 0) + continue; + setPsysefxvol(partefx, nefx, + xml->getpar127("vol", Psysefxvol[partefx][nefx])); xml->exitbranch(); - }; + } - for (int tonefx=nefx+1;tonefx<NUM_SYS_EFX;tonefx++) { - if (xml->enterbranch("SENDTO",tonefx)==0) continue; - setPsysefxsend(nefx,tonefx,xml->getpar127("send_vol",Psysefxsend[nefx][tonefx])); + for(int tonefx = nefx + 1; tonefx < NUM_SYS_EFX; tonefx++) { + if(xml->enterbranch("SENDTO", tonefx) == 0) + continue; + setPsysefxsend(nefx, tonefx, + xml->getpar127("send_vol", + Psysefxsend[nefx][tonefx])); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } xml->exitbranch(); - }; - - - if (xml->enterbranch("INSERTION_EFFECTS")) { - for (int nefx=0;nefx<NUM_INS_EFX;nefx++) { - - if (xml->enterbranch("INSERTION_EFFECT",nefx)==0) continue; - Pinsparts[nefx]=xml->getpar("part",Pinsparts[nefx],-2,NUM_MIDI_PARTS); - if (xml->enterbranch("EFFECT")) { + } + + + if(xml->enterbranch("INSERTION_EFFECTS")) { + for(int nefx = 0; nefx < NUM_INS_EFX; nefx++) { + if(xml->enterbranch("INSERTION_EFFECT", nefx) == 0) + continue; + Pinsparts[nefx] = xml->getpar("part", + Pinsparts[nefx], + -2, + NUM_MIDI_PARTS); + if(xml->enterbranch("EFFECT")) { insefx[nefx]->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - - }; + } xml->exitbranch(); - }; - - -}; - - - + } +} diff --git a/src/Misc/Master.h b/src/Misc/Master.h @@ -40,129 +40,136 @@ extern Dump dump; * process them with system/insertion effects and mix them */ class Master { -public: - /** Constructor*/ - Master(); - /** Destructor*/ - ~Master(); + public: + /** Constructor*/ + Master(); + /** Destructor*/ + ~Master(); - /**Saves all settings to a XML file - * @return 0 for ok or <0 if there is an error*/ - int saveXML(const char *filename); + /**Saves all settings to a XML file + * @return 0 for ok or <0 if there is an error*/ + int saveXML(const char *filename); - /**This adds the parameters to the XML data*/ - void add2XML(XMLwrapper *xml); + /**This adds the parameters to the XML data*/ + void add2XML(XMLwrapper *xml); - void defaults(); + void defaults(); - /**loads all settings from a XML file - * @return 0 for ok or -1 if there is an error*/ - int loadXML(const char *filename); - void applyparameters(); + /**loads all settings from a XML file + * @return 0 for ok or -1 if there is an error*/ + int loadXML(const char *filename); + void applyparameters(); - void getfromXML(XMLwrapper *xml); + void getfromXML(XMLwrapper *xml); - /**get all data to a newly allocated array (used for VST) - * @return the datasize*/ - int getalldata(char **data); - /**put all data from the *data array to zynaddsubfx parameters (used for VST)*/ - void putalldata(char *data,int size); + /**get all data to a newly allocated array (used for VST) + * @return the datasize*/ + int getalldata(char **data); + /**put all data from the *data array to zynaddsubfx parameters (used for VST)*/ + void putalldata(char *data, int size); - //Midi IN - void NoteOn(unsigned char chan,unsigned char note,unsigned char velocity); - void NoteOff(unsigned char chan,unsigned char note); - void SetController(unsigned char chan,unsigned int type,int par); - //void NRPN... + //Midi IN + void NoteOn(unsigned char chan, + unsigned char note, + unsigned char velocity); + void NoteOff(unsigned char chan, unsigned char note); + void SetController(unsigned char chan, unsigned int type, int par); + //void NRPN... - void ShutUp(); - int shutup; + void ShutUp(); + int shutup; - /**Audio Output*/ - void AudioOut(REALTYPE *outl,REALTYPE *outr); - /**Audio Output (for callback mode). This allows the program to be controled by an external program*/ - void GetAudioOutSamples(int nsamples,int samplerate,REALTYPE *outl,REALTYPE *outr); + /**Audio Output*/ + void AudioOut(REALTYPE *outl, REALTYPE *outr); + /**Audio Output (for callback mode). This allows the program to be controled by an external program*/ + void GetAudioOutSamples(int nsamples, + int samplerate, + REALTYPE *outl, + REALTYPE *outr); - void partonoff(int npart,int what); + void partonoff(int npart, int what); - /**parts \todo see if this can be made to be dynamic*/ - Part *part[NUM_MIDI_PARTS]; + /**parts \todo see if this can be made to be dynamic*/ + Part *part[NUM_MIDI_PARTS]; - //parameters - unsigned char Pvolume; - unsigned char Pkeyshift; - unsigned char Psysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS]; - unsigned char Psysefxsend[NUM_SYS_EFX][NUM_SYS_EFX]; + //parameters + unsigned char Pvolume; + unsigned char Pkeyshift; + unsigned char Psysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS]; + unsigned char Psysefxsend[NUM_SYS_EFX][NUM_SYS_EFX]; - //parameters control - void setPvolume(char Pvolume_); - void setPkeyshift(char Pkeyshift_); - void setPsysefxvol(int Ppart,int Pefx,char Pvol); - void setPsysefxsend(int Pefxfrom,int Pefxto,char Pvol); + //parameters control + void setPvolume(char Pvolume_); + void setPkeyshift(char Pkeyshift_); + void setPsysefxvol(int Ppart, int Pefx, char Pvol); + void setPsysefxsend(int Pefxfrom, int Pefxto, char Pvol); - //effects - EffectMgr *sysefx[NUM_SYS_EFX];//system - EffectMgr *insefx[NUM_INS_EFX];//insertion + //effects + EffectMgr *sysefx[NUM_SYS_EFX]; //system + EffectMgr *insefx[NUM_INS_EFX]; //insertion // void swapcopyeffects(int what,int type,int neff1,int neff2); - //HDD recorder - Recorder HDDRecorder; + //HDD recorder + Recorder HDDRecorder; - //part that's apply the insertion effect; -1 to disable - short int Pinsparts[NUM_INS_EFX]; + //part that's apply the insertion effect; -1 to disable + short int Pinsparts[NUM_INS_EFX]; - //peaks for VU-meter - void vuresetpeaks(); - REALTYPE vuoutpeakl,vuoutpeakr,vumaxoutpeakl,vumaxoutpeakr,vurmspeakl,vurmspeakr; - int vuclipped; + //peaks for VU-meter + void vuresetpeaks(); + REALTYPE vuoutpeakl, vuoutpeakr, vumaxoutpeakl, vumaxoutpeakr, + vurmspeakl, vurmspeakr; + int vuclipped; - //peaks for part VU-meters - REALTYPE vuoutpeakpart[NUM_MIDI_PARTS]; - unsigned char fakepeakpart[NUM_MIDI_PARTS];//this is used to compute the "peak" when the part is disabled + //peaks for part VU-meters + REALTYPE vuoutpeakpart[NUM_MIDI_PARTS]; + unsigned char fakepeakpart[NUM_MIDI_PARTS]; //this is used to compute the "peak" when the part is disabled - Controller ctl; - int swaplr;//1 if L and R are swapped + Controller ctl; + int swaplr; //1 if L and R are swapped - //Sequencer - Sequencer seq; + //Sequencer + Sequencer seq; - //other objects - Microtonal microtonal; - Bank bank; + //other objects + Microtonal microtonal; + Bank bank; - FFTwrapper *fft; - pthread_mutex_t mutex; + FFTwrapper *fft; + pthread_mutex_t mutex; -private: - REALTYPE volume; - REALTYPE sysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS]; - REALTYPE sysefxsend[NUM_SYS_EFX][NUM_SYS_EFX]; + private: + REALTYPE volume; + REALTYPE sysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS]; + REALTYPE sysefxsend[NUM_SYS_EFX][NUM_SYS_EFX]; - //Temporary mixing samples for part samples which is sent to system effect - REALTYPE *tmpmixl; - REALTYPE *tmpmixr; + //Temporary mixing samples for part samples which is sent to system effect + REALTYPE *tmpmixl; + REALTYPE *tmpmixr; - int keyshift; + int keyshift; - //Audio Output samples (if it used GetAudioOutSamples - eg. for Jack output; elsewhere is unused) - REALTYPE *audiooutl; - REALTYPE *audiooutr; + //Audio Output samples (if it used GetAudioOutSamples - eg. for Jack output; elsewhere is unused) + REALTYPE *audiooutl; + REALTYPE *audiooutr; - int ksoundbuffersample;//this is used to know if there is need to call AudioOut by GetAudioOutSamples method - REALTYPE ksoundbuffersamplelow;//this is used for resampling (eg. if Jack samplerate!= SAMPLE_RATE) - REALTYPE oldsamplel,oldsampler;//this is used for resampling - - //These are called by the NoteOn, NoteOff,SetController (which are from external sources like MIDI, Virtual Keyboard) - //and are called by internal parts of the program (like sequencer) - void noteon(unsigned char chan,unsigned char note,unsigned char velocity); - void noteoff(unsigned char chan,unsigned char note); - void setcontroller(unsigned char chan,unsigned int type,int par); + int ksoundbuffersample; //this is used to know if there is need to call AudioOut by GetAudioOutSamples method + REALTYPE ksoundbuffersamplelow; //this is used for resampling (eg. if Jack samplerate!= SAMPLE_RATE) + REALTYPE oldsamplel, oldsampler; //this is used for resampling + //These are called by the NoteOn, NoteOff,SetController (which are from external sources like MIDI, Virtual Keyboard) + //and are called by internal parts of the program (like sequencer) + void noteon(unsigned char chan, + unsigned char note, + unsigned char velocity); + void noteoff(unsigned char chan, unsigned char note); + void setcontroller(unsigned char chan, unsigned int type, int par); }; diff --git a/src/Misc/Microtonal.cpp b/src/Misc/Microtonal.cpp @@ -28,158 +28,190 @@ Microtonal::Microtonal() { - Pname=new unsigned char[MICROTONAL_MAX_NAME_LEN]; - Pcomment=new unsigned char[MICROTONAL_MAX_NAME_LEN]; + Pname = new unsigned char[MICROTONAL_MAX_NAME_LEN]; + Pcomment = new unsigned char[MICROTONAL_MAX_NAME_LEN]; defaults(); -}; +} void Microtonal::defaults() { - Pinvertupdown=0; - Pinvertupdowncenter=60; - octavesize=12; - Penabled=0; - PAnote=69; - PAfreq=440.0; - Pscaleshift=64; - - Pfirstkey=0; - Plastkey=127; - Pmiddlenote=60; - Pmapsize=12; - Pmappingenabled=0; - - for (int i=0;i<128;i++) Pmapping[i]=i; - - for (int i=0;i<MAX_OCTAVE_SIZE;i++) { - octave[i].tuning=tmpoctave[i].tuning=pow(2,(i%octavesize+1)/12.0); - octave[i].type=tmpoctave[i].type=1; - octave[i].x1=tmpoctave[i].x1=(i%octavesize+1)*100; - octave[i].x2=tmpoctave[i].x2=0; - }; - octave[11].type=2; - octave[11].x1=2; - octave[11].x2=1; - for (int i=0;i<MICROTONAL_MAX_NAME_LEN;i++) { - Pname[i]='\0'; - Pcomment[i]='\0'; - }; - snprintf((char *) Pname,MICROTONAL_MAX_NAME_LEN,"12tET"); - snprintf((char *) Pcomment,MICROTONAL_MAX_NAME_LEN,"Equal Temperament 12 notes per octave"); - Pglobalfinedetune=64; -}; + Pinvertupdown = 0; + Pinvertupdowncenter = 60; + octavesize = 12; + Penabled = 0; + PAnote = 69; + PAfreq = 440.0; + Pscaleshift = 64; + + Pfirstkey = 0; + Plastkey = 127; + Pmiddlenote = 60; + Pmapsize = 12; + Pmappingenabled = 0; + + for(int i = 0; i < 128; i++) + Pmapping[i] = i; + + for(int i = 0; i < MAX_OCTAVE_SIZE; i++) { + octave[i].tuning = tmpoctave[i].tuning = pow( + 2, + (i % octavesize + + 1) / 12.0); + octave[i].type = tmpoctave[i].type = 1; + octave[i].x1 = tmpoctave[i].x1 = (i % octavesize + 1) * 100; + octave[i].x2 = tmpoctave[i].x2 = 0; + } + octave[11].type = 2; + octave[11].x1 = 2; + octave[11].x2 = 1; + for(int i = 0; i < MICROTONAL_MAX_NAME_LEN; i++) { + Pname[i] = '\0'; + Pcomment[i] = '\0'; + } + snprintf((char *) Pname, MICROTONAL_MAX_NAME_LEN, "12tET"); + snprintf((char *) Pcomment, + MICROTONAL_MAX_NAME_LEN, + "Equal Temperament 12 notes per octave"); + Pglobalfinedetune = 64; +} Microtonal::~Microtonal() { delete [] Pname; delete [] Pcomment; -}; +} /* * Get the size of the octave */ unsigned char Microtonal::getoctavesize() const { - if (Penabled!=0) return(octavesize); - else return(12); -}; + if(Penabled != 0) + return octavesize; + else + return 12; +} /* * Get the frequency according the note number */ -REALTYPE Microtonal::getnotefreq(int note,int keyshift) const +REALTYPE Microtonal::getnotefreq(int note, int keyshift) const { // in this function will appears many times things like this: // var=(a+b*100)%b // I had written this way because if I use var=a%b gives unwanted results when a<0 // This is the same with divisions. - if ((Pinvertupdown!=0)&&((Pmappingenabled==0)||(Penabled==0))) note=(int) Pinvertupdowncenter*2-note; + if((Pinvertupdown != 0) && ((Pmappingenabled == 0) || (Penabled == 0))) + note = (int) Pinvertupdowncenter * 2 - note; //compute global fine detune - REALTYPE globalfinedetunerap=pow(2.0,(Pglobalfinedetune-64.0)/1200.0);//-64.0 .. 63.0 cents + REALTYPE globalfinedetunerap = pow(2.0, (Pglobalfinedetune - 64.0) / 1200.0); //-64.0 .. 63.0 cents - if (Penabled==0) return(pow(2.0,(note-PAnote+keyshift)/12.0)*PAfreq*globalfinedetunerap);//12tET + if(Penabled == 0) + return pow(2.0, + (note - PAnote + + keyshift) / 12.0) * PAfreq * globalfinedetunerap; //12tET - int scaleshift=((int)Pscaleshift-64+(int) octavesize*100)%octavesize; + int scaleshift = + ((int)Pscaleshift - 64 + (int) octavesize * 100) % octavesize; //compute the keyshift - REALTYPE rap_keyshift=1.0; - if (keyshift!=0) { - int kskey=(keyshift+(int)octavesize*100)%octavesize; - int ksoct=(keyshift+(int)octavesize*100)/octavesize-100; - rap_keyshift=(kskey==0) ? (1.0):(octave[kskey-1].tuning); - rap_keyshift*=pow(octave[octavesize-1].tuning,ksoct); - }; + REALTYPE rap_keyshift = 1.0; + if(keyshift != 0) { + int kskey = (keyshift + (int)octavesize * 100) % octavesize; + int ksoct = (keyshift + (int)octavesize * 100) / octavesize - 100; + rap_keyshift = (kskey == 0) ? (1.0) : (octave[kskey - 1].tuning); + rap_keyshift *= pow(octave[octavesize - 1].tuning, ksoct); + } //if the mapping is enabled - if (Pmappingenabled!=0) { - if ((note<Pfirstkey)||(note>Plastkey)) return (-1.0); + if(Pmappingenabled != 0) { + if((note < Pfirstkey) || (note > Plastkey)) + return -1.0; //Compute how many mapped keys are from middle note to reference note //and find out the proportion between the freq. of middle note and "A" note - int tmp=PAnote-Pmiddlenote,minus=0; - if (tmp<0) { - tmp=-tmp; - minus=1; - }; - int deltanote=0; - for (int i=0;i<tmp;i++) if (Pmapping[i%Pmapsize]>=0) deltanote++; - REALTYPE rap_anote_middlenote=(deltanote==0) ? (1.0) : (octave[(deltanote-1)%octavesize].tuning); - if (deltanote!=0) rap_anote_middlenote*=pow(octave[octavesize-1].tuning,(deltanote-1)/octavesize); - if (minus!=0) rap_anote_middlenote=1.0/rap_anote_middlenote; + int tmp = PAnote - Pmiddlenote, minus = 0; + if(tmp < 0) { + tmp = -tmp; + minus = 1; + } + int deltanote = 0; + for(int i = 0; i < tmp; i++) + if(Pmapping[i % Pmapsize] >= 0) + deltanote++; + REALTYPE rap_anote_middlenote = + (deltanote == + 0) ? (1.0) : (octave[(deltanote - 1) % octavesize].tuning); + if(deltanote != 0) + rap_anote_middlenote *= + pow(octave[octavesize - 1].tuning, (deltanote - 1) / octavesize); + if(minus != 0) + rap_anote_middlenote = 1.0 / rap_anote_middlenote; //Convert from note (midi) to degree (note from the tunning) - int degoct=(note-(int)Pmiddlenote+(int) Pmapsize*200)/(int)Pmapsize-200; - int degkey=(note-Pmiddlenote+(int)Pmapsize*100)%Pmapsize; - degkey=Pmapping[degkey]; - if (degkey<0) return(-1.0);//this key is not mapped + int degoct = + (note - (int)Pmiddlenote + (int) Pmapsize + * 200) / (int)Pmapsize - 200; + int degkey = (note - Pmiddlenote + (int)Pmapsize * 100) % Pmapsize; + degkey = Pmapping[degkey]; + if(degkey < 0) + return -1.0; //this key is not mapped //invert the keyboard upside-down if it is asked for //TODO: do the right way by using Pinvertupdowncenter - if (Pinvertupdown!=0) { - degkey=octavesize-degkey-1; - degoct=-degoct; - }; + if(Pinvertupdown != 0) { + degkey = octavesize - degkey - 1; + degoct = -degoct; + } //compute the frequency of the note - degkey=degkey+scaleshift; - degoct+=degkey/octavesize; - degkey%=octavesize; - - REALTYPE freq=(degkey==0) ? (1.0):octave[degkey-1].tuning; - freq*=pow(octave[octavesize-1].tuning,degoct); - freq*=PAfreq/rap_anote_middlenote; - freq*=globalfinedetunerap; - if (scaleshift!=0) freq/=octave[scaleshift-1].tuning; - return(freq*rap_keyshift); - } else {//if the mapping is disabled - int nt=note-PAnote+scaleshift; - int ntkey=(nt+(int)octavesize*100)%octavesize; - int ntoct=(nt-ntkey)/octavesize; - - REALTYPE oct=octave[octavesize-1].tuning; - REALTYPE freq=octave[(ntkey+octavesize-1)%octavesize].tuning*pow(oct,ntoct)*PAfreq; - if (ntkey==0) freq/=oct; - if (scaleshift!=0) freq/=octave[scaleshift-1].tuning; + degkey = degkey + scaleshift; + degoct += degkey / octavesize; + degkey %= octavesize; + + REALTYPE freq = (degkey == 0) ? (1.0) : octave[degkey - 1].tuning; + freq *= pow(octave[octavesize - 1].tuning, degoct); + freq *= PAfreq / rap_anote_middlenote; + freq *= globalfinedetunerap; + if(scaleshift != 0) + freq /= octave[scaleshift - 1].tuning; + return freq * rap_keyshift; + } + else { //if the mapping is disabled + int nt = note - PAnote + scaleshift; + int ntkey = (nt + (int)octavesize * 100) % octavesize; + int ntoct = (nt - ntkey) / octavesize; + + REALTYPE oct = octave[octavesize - 1].tuning; + REALTYPE freq = + octave[(ntkey + octavesize - 1) % octavesize].tuning *pow(oct, + ntoct) + * PAfreq; + if(ntkey == 0) + freq /= oct; + if(scaleshift != 0) + freq /= octave[scaleshift - 1].tuning; // fprintf(stderr,"note=%d freq=%.3f cents=%d\n",note,freq,(int)floor(log(freq/PAfreq)/log(2.0)*1200.0+0.5)); - freq*=globalfinedetunerap; - return(freq*rap_keyshift); - }; -}; + freq *= globalfinedetunerap; + return freq * rap_keyshift; + } +} bool Microtonal::operator==(const Microtonal &micro) const { - return(!(*this!=micro)); + return !(*this != micro); } bool Microtonal::operator!=(const Microtonal &micro) const { - //A simple macro to test equality MiCRotonal EQuals (not the perfect //approach, but good enough) -#define MCREQ( x ) if(x!=micro.x)return true; +#define MCREQ(x) if(x != micro.x) \ + return true; //for floats -#define FMCREQ( x ) if(!((x<micro.x+0.0001)&&(x>micro.x-0.0001)))return true; +#define FMCREQ(x) if(!((x < micro.x + 0.0001) && (x > micro.x - 0.0001))) \ + return true; MCREQ(Pinvertupdown); MCREQ(Pinvertupdowncenter); @@ -195,18 +227,18 @@ bool Microtonal::operator!=(const Microtonal &micro) const MCREQ(Pmapsize); MCREQ(Pmappingenabled); - for (int i=0;i<128;i++) + for(int i = 0; i < 128; i++) MCREQ(Pmapping[i]); - for (int i=0;i<octavesize;i++) { + for(int i = 0; i < octavesize; i++) { FMCREQ(octave[i].tuning); MCREQ(octave[i].type); MCREQ(octave[i].x1); MCREQ(octave[i].x2); } - if(strcmp((const char *)this->Pname,(const char *)micro.Pname)) + if(strcmp((const char *)this->Pname, (const char *)micro.Pname)) return true; - if(strcmp((const char *)this->Pcomment,(const char *)micro.Pcomment)) + if(strcmp((const char *)this->Pcomment, (const char *)micro.Pcomment)) return true; MCREQ(Pglobalfinedetune); return false; @@ -214,384 +246,442 @@ bool Microtonal::operator!=(const Microtonal &micro) const //undefine macros, as they are no longer needed #undef MCREQ #undef FMCREQ - } /* * Convert a line to tunings; returns -1 if it ok */ -int Microtonal::linetotunings(unsigned int nline,const char *line) +int Microtonal::linetotunings(unsigned int nline, const char *line) { - int x1=-1,x2=-1,type=-1; - REALTYPE x=-1.0,tmp,tuning=1.0; - if (strstr(line,"/")==NULL) { - if (strstr(line,".")==NULL) {// M case (M=M/1) - sscanf(line,"%d",&x1); - x2=1; - type=2;//division - } else {// float number case - sscanf(line,"%f",&x); - if (x<0.000001) return(1); - type=1;//float type(cents) - }; - } else {// M/N case - sscanf(line,"%d/%d",&x1,&x2); - if ((x1<0)||(x2<0)) return(1); - if (x2==0) x2=1; - type=2;//division - }; - - if (x1<=0) x1=1;//not allow zero frequency sounds (consider 0 as 1) + int x1 = -1, x2 = -1, type = -1; + REALTYPE x = -1.0, tmp, tuning = 1.0; + if(strstr(line, "/") == NULL) { + if(strstr(line, ".") == NULL) { // M case (M=M/1) + sscanf(line, "%d", &x1); + x2 = 1; + type = 2; //division + } + else { // float number case + sscanf(line, "%f", &x); + if(x < 0.000001) + return 1; + type = 1; //float type(cents) + } + } + else { // M/N case + sscanf(line, "%d/%d", &x1, &x2); + if((x1 < 0) || (x2 < 0)) + return 1; + if(x2 == 0) + x2 = 1; + type = 2; //division + } + + if(x1 <= 0) + x1 = 1; //not allow zero frequency sounds (consider 0 as 1) //convert to float if the number are too big - if ((type==2)&&((x1>(128*128*128-1))||(x2>(128*128*128-1)))) { - type=1; - x=((REALTYPE) x1)/x2; - }; - switch (type) { + if((type == 2) + && ((x1 > (128 * 128 * 128 - 1)) || (x2 > (128 * 128 * 128 - 1)))) { + type = 1; + x = ((REALTYPE) x1) / x2; + } + switch(type) { case 1: - x1=(int) floor(x); - tmp=fmod(x,1.0); - x2=(int) (floor (tmp*1e6)); - tuning=pow(2.0,x/1200.0); + x1 = (int) floor(x); + tmp = fmod(x, 1.0); + x2 = (int) (floor(tmp * 1e6)); + tuning = pow(2.0, x / 1200.0); break; case 2: - x=((REALTYPE)x1)/x2; - tuning=x; + x = ((REALTYPE)x1) / x2; + tuning = x; break; - }; + } - tmpoctave[nline].tuning=tuning; - tmpoctave[nline].type=type; - tmpoctave[nline].x1=x1; - tmpoctave[nline].x2=x2; + tmpoctave[nline].tuning = tuning; + tmpoctave[nline].type = type; + tmpoctave[nline].x1 = x1; + tmpoctave[nline].x2 = x2; - return(-1);//ok -}; + return -1; //ok +} /* * Convert the text to tunnings */ int Microtonal::texttotunings(const char *text) { - unsigned int i,k=0,nl=0; + unsigned int i, k = 0, nl = 0; char *lin; - lin=new char[MAX_LINE_SIZE+1]; - while (k<strlen(text)) { - for (i=0;i<MAX_LINE_SIZE;i++) { - lin[i]=text[k++]; - if (lin[i]<0x20) break; - }; - lin[i]='\0'; - if (strlen(lin)==0) continue; - int err=linetotunings(nl,lin); - if (err!=-1) { + lin = new char[MAX_LINE_SIZE + 1]; + while(k < strlen(text)) { + for(i = 0; i < MAX_LINE_SIZE; i++) { + lin[i] = text[k++]; + if(lin[i] < 0x20) + break; + } + lin[i] = '\0'; + if(strlen(lin) == 0) + continue; + int err = linetotunings(nl, lin); + if(err != -1) { delete [] lin; - return(nl);//Parse error - }; + return nl; //Parse error + } nl++; - }; + } delete [] lin; - if (nl>MAX_OCTAVE_SIZE) nl=MAX_OCTAVE_SIZE; - if (nl==0) return(-2);//the input is empty - octavesize=nl; - for (i=0;i<octavesize;i++) { - octave[i].tuning=tmpoctave[i].tuning; - octave[i].type=tmpoctave[i].type; - octave[i].x1=tmpoctave[i].x1; - octave[i].x2=tmpoctave[i].x2; - }; - return(-1);//ok -}; + if(nl > MAX_OCTAVE_SIZE) + nl = MAX_OCTAVE_SIZE; + if(nl == 0) + return -2; //the input is empty + octavesize = nl; + for(i = 0; i < octavesize; i++) { + octave[i].tuning = tmpoctave[i].tuning; + octave[i].type = tmpoctave[i].type; + octave[i].x1 = tmpoctave[i].x1; + octave[i].x2 = tmpoctave[i].x2; + } + return -1; //ok +} /* * Convert the text to mapping */ void Microtonal::texttomapping(const char *text) { - unsigned int i,k=0; + unsigned int i, k = 0; char *lin; - lin=new char[MAX_LINE_SIZE+1]; - for (i=0;i<128;i++) Pmapping[i]=-1; - int tx=0; - while (k<strlen(text)) { - for (i=0;i<MAX_LINE_SIZE;i++) { - lin[i]=text[k++]; - if (lin[i]<0x20) break; - }; - lin[i]='\0'; - if (strlen(lin)==0) continue; - - int tmp=0; - if (sscanf(lin,"%d",&tmp)==0) tmp=-1; - if (tmp<-1) tmp=-1; - Pmapping[tx]=tmp; - - if ((tx++)>127) break; - }; + lin = new char[MAX_LINE_SIZE + 1]; + for(i = 0; i < 128; i++) + Pmapping[i] = -1; + int tx = 0; + while(k < strlen(text)) { + for(i = 0; i < MAX_LINE_SIZE; i++) { + lin[i] = text[k++]; + if(lin[i] < 0x20) + break; + } + lin[i] = '\0'; + if(strlen(lin) == 0) + continue; + + int tmp = 0; + if(sscanf(lin, "%d", &tmp) == 0) + tmp = -1; + if(tmp < -1) + tmp = -1; + Pmapping[tx] = tmp; + + if((tx++) > 127) + break; + } delete [] lin; - if (tx==0) tx=1; - Pmapsize=tx; -}; + if(tx == 0) + tx = 1; + Pmapsize = tx; +} /* * Convert tunning to text line */ -void Microtonal::tuningtoline(int n,char *line,int maxn) +void Microtonal::tuningtoline(int n, char *line, int maxn) { - if ((n>octavesize) || (n>MAX_OCTAVE_SIZE)) { - line[0]='\0'; + if((n > octavesize) || (n > MAX_OCTAVE_SIZE)) { + line[0] = '\0'; return; - }; - if (octave[n].type==1) snprintf(line,maxn,"%d.%d",octave[n].x1,octave[n].x2); - if (octave[n].type==2) snprintf(line,maxn,"%d/%d",octave[n].x1,octave[n].x2); -}; + } + if(octave[n].type == 1) + snprintf(line, maxn, "%d.%d", octave[n].x1, octave[n].x2); + if(octave[n].type == 2) + snprintf(line, maxn, "%d/%d", octave[n].x1, octave[n].x2); +} -int Microtonal::loadline(FILE *file,char *line) +int Microtonal::loadline(FILE *file, char *line) { do { - if (fgets(line,500,file)==0) return(1); - } while (line[0]=='!'); - return(0); -}; + if(fgets(line, 500, file) == 0) + return 1; + } while(line[0] == '!'); + return 0; +} /* * Loads the tunnings from a scl file */ int Microtonal::loadscl(const char *filename) { - FILE *file=fopen(filename, "r"); - char tmp[500]; - fseek(file,0,SEEK_SET); + FILE *file = fopen(filename, "r"); + char tmp[500]; + fseek(file, 0, SEEK_SET); //loads the short description - if (loadline(file,&tmp[0])!=0) return(2); - for (int i=0;i<500;i++) if (tmp[i]<32) tmp[i]=0; - snprintf((char *) Pname,MICROTONAL_MAX_NAME_LEN,"%s",tmp); - snprintf((char *) Pcomment,MICROTONAL_MAX_NAME_LEN,"%s",tmp); + if(loadline(file, &tmp[0]) != 0) + return 2; + for(int i = 0; i < 500; i++) + if(tmp[i] < 32) + tmp[i] = 0; + snprintf((char *) Pname, MICROTONAL_MAX_NAME_LEN, "%s", tmp); + snprintf((char *) Pcomment, MICROTONAL_MAX_NAME_LEN, "%s", tmp); //loads the number of the notes - if (loadline(file,&tmp[0])!=0) return(2); - int nnotes=MAX_OCTAVE_SIZE; - sscanf(&tmp[0],"%d",&nnotes); - if (nnotes>MAX_OCTAVE_SIZE) return (2); + if(loadline(file, &tmp[0]) != 0) + return 2; + int nnotes = MAX_OCTAVE_SIZE; + sscanf(&tmp[0], "%d", &nnotes); + if(nnotes > MAX_OCTAVE_SIZE) + return 2; //load the tunnings - for (int nline=0;nline<nnotes;nline++) { - if (loadline(file,&tmp[0])!=0) return(2); - linetotunings(nline,&tmp[0]); - }; + for(int nline = 0; nline < nnotes; nline++) { + if(loadline(file, &tmp[0]) != 0) + return 2; + linetotunings(nline, &tmp[0]); + } fclose(file); - octavesize=nnotes; - for (int i=0;i<octavesize;i++) { - octave[i].tuning=tmpoctave[i].tuning; - octave[i].type=tmpoctave[i].type; - octave[i].x1=tmpoctave[i].x1; - octave[i].x2=tmpoctave[i].x2; - }; + octavesize = nnotes; + for(int i = 0; i < octavesize; i++) { + octave[i].tuning = tmpoctave[i].tuning; + octave[i].type = tmpoctave[i].type; + octave[i].x1 = tmpoctave[i].x1; + octave[i].x2 = tmpoctave[i].x2; + } - return(0); -}; + return 0; +} /* * Loads the mapping from a kbm file */ int Microtonal::loadkbm(const char *filename) { - FILE *file=fopen(filename, "r"); - int x; - char tmp[500]; + FILE *file = fopen(filename, "r"); + int x; + char tmp[500]; - fseek(file,0,SEEK_SET); + fseek(file, 0, SEEK_SET); //loads the mapsize - if (loadline(file,&tmp[0])!=0) return(2); - if (sscanf(&tmp[0],"%d",&x)==0) return(2); - if (x<1) x=0; - if (x>127) x=127;//just in case... - Pmapsize=x; + if(loadline(file, &tmp[0]) != 0) + return 2; + if(sscanf(&tmp[0], "%d", &x) == 0) + return 2; + if(x < 1) + x = 0; + if(x > 127) + x = 127; //just in case... + Pmapsize = x; //loads first MIDI note to retune - if (loadline(file,&tmp[0])!=0) return(2); - if (sscanf(&tmp[0],"%d",&x)==0) return(2); - if (x<1) x=0; - if (x>127) x=127;//just in case... - Pfirstkey=x; + if(loadline(file, &tmp[0]) != 0) + return 2; + if(sscanf(&tmp[0], "%d", &x) == 0) + return 2; + if(x < 1) + x = 0; + if(x > 127) + x = 127; //just in case... + Pfirstkey = x; //loads last MIDI note to retune - if (loadline(file,&tmp[0])!=0) return(2); - if (sscanf(&tmp[0],"%d",&x)==0) return(2); - if (x<1) x=0; - if (x>127) x=127;//just in case... - Plastkey=x; + if(loadline(file, &tmp[0]) != 0) + return 2; + if(sscanf(&tmp[0], "%d", &x) == 0) + return 2; + if(x < 1) + x = 0; + if(x > 127) + x = 127; //just in case... + Plastkey = x; //loads last the middle note where scale fro scale degree=0 - if (loadline(file,&tmp[0])!=0) return(2); - if (sscanf(&tmp[0],"%d",&x)==0) return(2); - if (x<1) x=0; - if (x>127) x=127;//just in case... - Pmiddlenote=x; + if(loadline(file, &tmp[0]) != 0) + return 2; + if(sscanf(&tmp[0], "%d", &x) == 0) + return 2; + if(x < 1) + x = 0; + if(x > 127) + x = 127; //just in case... + Pmiddlenote = x; //loads the reference note - if (loadline(file,&tmp[0])!=0) return(2); - if (sscanf(&tmp[0],"%d",&x)==0) return(2); - if (x<1) x=0; - if (x>127) x=127;//just in case... - PAnote=x; + if(loadline(file, &tmp[0]) != 0) + return 2; + if(sscanf(&tmp[0], "%d", &x) == 0) + return 2; + if(x < 1) + x = 0; + if(x > 127) + x = 127; //just in case... + PAnote = x; //loads the reference freq. - if (loadline(file,&tmp[0])!=0) return(2); - REALTYPE tmpPAfreq=440.0; - if (sscanf(&tmp[0],"%f",&tmpPAfreq)==0) return(2); - PAfreq=tmpPAfreq; + if(loadline(file, &tmp[0]) != 0) + return 2; + REALTYPE tmpPAfreq = 440.0; + if(sscanf(&tmp[0], "%f", &tmpPAfreq) == 0) + return 2; + PAfreq = tmpPAfreq; //the scale degree(which is the octave) is not loaded, it is obtained by the tunnings with getoctavesize() method - if (loadline(file,&tmp[0])!=0) return(2); + if(loadline(file, &tmp[0]) != 0) + return 2; //load the mappings - if (Pmapsize!=0) { - for (int nline=0;nline<Pmapsize;nline++) { - if (loadline(file,&tmp[0])!=0) return(2); - if (sscanf(&tmp[0],"%d",&x)==0) x=-1; - Pmapping[nline]=x; - }; - Pmappingenabled=1; - } else { - Pmappingenabled=0; - Pmapping[0]=0; - Pmapsize=1; - }; + if(Pmapsize != 0) { + for(int nline = 0; nline < Pmapsize; nline++) { + if(loadline(file, &tmp[0]) != 0) + return 2; + if(sscanf(&tmp[0], "%d", &x) == 0) + x = -1; + Pmapping[nline] = x; + } + Pmappingenabled = 1; + } + else { + Pmappingenabled = 0; + Pmapping[0] = 0; + Pmapsize = 1; + } fclose(file); - return(0); -}; + return 0; +} -void Microtonal::add2XML(XMLwrapper *xml)const +void Microtonal::add2XML(XMLwrapper *xml) const { - xml->addparstr("name",(char *) Pname); - xml->addparstr("comment",(char *) Pcomment); + xml->addparstr("name", (char *) Pname); + xml->addparstr("comment", (char *) Pcomment); - xml->addparbool("invert_up_down",Pinvertupdown); - xml->addpar("invert_up_down_center",Pinvertupdowncenter); + xml->addparbool("invert_up_down", Pinvertupdown); + xml->addpar("invert_up_down_center", Pinvertupdowncenter); - xml->addparbool("enabled",Penabled); - xml->addpar("global_fine_detune",Pglobalfinedetune); + xml->addparbool("enabled", Penabled); + xml->addpar("global_fine_detune", Pglobalfinedetune); - xml->addpar("a_note",PAnote); - xml->addparreal("a_freq",PAfreq); + xml->addpar("a_note", PAnote); + xml->addparreal("a_freq", PAfreq); - if ((Penabled==0)&&(xml->minimal)) return; + if((Penabled == 0) && (xml->minimal)) + return; xml->beginbranch("SCALE"); - xml->addpar("scale_shift",Pscaleshift); - xml->addpar("first_key",Pfirstkey); - xml->addpar("last_key",Plastkey); - xml->addpar("middle_note",Pmiddlenote); + xml->addpar("scale_shift", Pscaleshift); + xml->addpar("first_key", Pfirstkey); + xml->addpar("last_key", Plastkey); + xml->addpar("middle_note", Pmiddlenote); xml->beginbranch("OCTAVE"); - xml->addpar("octave_size",octavesize); - for (int i=0;i<octavesize;i++) { - xml->beginbranch("DEGREE",i); - if (octave[i].type==1) { - xml->addparreal("cents",octave[i].tuning); - }; - if (octave[i].type==2) { - xml->addpar("numerator",octave[i].x1); - xml->addpar("denominator",octave[i].x2); - }; + xml->addpar("octave_size", octavesize); + for(int i = 0; i < octavesize; i++) { + xml->beginbranch("DEGREE", i); + if(octave[i].type == 1) + xml->addparreal("cents", octave[i].tuning); + ; + if(octave[i].type == 2) { + xml->addpar("numerator", octave[i].x1); + xml->addpar("denominator", octave[i].x2); + } xml->endbranch(); - }; + } xml->endbranch(); xml->beginbranch("KEYBOARD_MAPPING"); - xml->addpar("map_size",Pmapsize); - xml->addpar("mapping_enabled",Pmappingenabled); - for (int i=0;i<Pmapsize;i++) { - xml->beginbranch("KEYMAP",i); - xml->addpar("degree",Pmapping[i]); + xml->addpar("map_size", Pmapsize); + xml->addpar("mapping_enabled", Pmappingenabled); + for(int i = 0; i < Pmapsize; i++) { + xml->beginbranch("KEYMAP", i); + xml->addpar("degree", Pmapping[i]); xml->endbranch(); - }; + } xml->endbranch(); xml->endbranch(); -}; +} void Microtonal::getfromXML(XMLwrapper *xml) { - xml->getparstr("name",(char *) Pname,MICROTONAL_MAX_NAME_LEN); - xml->getparstr("comment",(char *) Pcomment,MICROTONAL_MAX_NAME_LEN); - - Pinvertupdown=xml->getparbool("invert_up_down",Pinvertupdown); - Pinvertupdowncenter=xml->getpar127("invert_up_down_center",Pinvertupdowncenter); - - Penabled=xml->getparbool("enabled",Penabled); - Pglobalfinedetune=xml->getpar127("global_fine_detune",Pglobalfinedetune); - - PAnote=xml->getpar127("a_note",PAnote); - PAfreq=xml->getparreal("a_freq",PAfreq,1.0,10000.0); - - if (xml->enterbranch("SCALE")) { - Pscaleshift=xml->getpar127("scale_shift",Pscaleshift); - Pfirstkey=xml->getpar127("first_key",Pfirstkey); - Plastkey=xml->getpar127("last_key",Plastkey); - Pmiddlenote=xml->getpar127("middle_note",Pmiddlenote); - - if (xml->enterbranch("OCTAVE")) { - octavesize=xml->getpar127("octave_size",octavesize); - for (int i=0;i<octavesize;i++) { - if (xml->enterbranch("DEGREE",i)==0) continue; - octave[i].x2=0; - octave[i].tuning=xml->getparreal("cents",octave[i].tuning); - octave[i].x1=xml->getpar127("numerator",octave[i].x1); - octave[i].x2=xml->getpar127("denominator",octave[i].x2); - - if (octave[i].x2!=0) octave[i].type=2; - else octave[i].type=1; + xml->getparstr("name", (char *) Pname, MICROTONAL_MAX_NAME_LEN); + xml->getparstr("comment", (char *) Pcomment, MICROTONAL_MAX_NAME_LEN); + + Pinvertupdown = xml->getparbool("invert_up_down", Pinvertupdown); + Pinvertupdowncenter = xml->getpar127("invert_up_down_center", + Pinvertupdowncenter); + + Penabled = xml->getparbool("enabled", Penabled); + Pglobalfinedetune = xml->getpar127("global_fine_detune", Pglobalfinedetune); + + PAnote = xml->getpar127("a_note", PAnote); + PAfreq = xml->getparreal("a_freq", PAfreq, 1.0, 10000.0); + + if(xml->enterbranch("SCALE")) { + Pscaleshift = xml->getpar127("scale_shift", Pscaleshift); + Pfirstkey = xml->getpar127("first_key", Pfirstkey); + Plastkey = xml->getpar127("last_key", Plastkey); + Pmiddlenote = xml->getpar127("middle_note", Pmiddlenote); + + if(xml->enterbranch("OCTAVE")) { + octavesize = xml->getpar127("octave_size", octavesize); + for(int i = 0; i < octavesize; i++) { + if(xml->enterbranch("DEGREE", i) == 0) + continue; + octave[i].x2 = 0; + octave[i].tuning = xml->getparreal("cents", octave[i].tuning); + octave[i].x1 = xml->getpar127("numerator", octave[i].x1); + octave[i].x2 = xml->getpar127("denominator", octave[i].x2); + + if(octave[i].x2 != 0) + octave[i].type = 2; + else + octave[i].type = 1; xml->exitbranch(); - }; + } xml->exitbranch(); - }; - - if (xml->enterbranch("KEYBOARD_MAPPING")) { - Pmapsize=xml->getpar127("map_size",Pmapsize); - Pmappingenabled=xml->getpar127("mapping_enabled",Pmappingenabled); - for (int i=0;i<Pmapsize;i++) { - if (xml->enterbranch("KEYMAP",i)==0) continue; - Pmapping[i]=xml->getpar127("degree",Pmapping[i]); + } + + if(xml->enterbranch("KEYBOARD_MAPPING")) { + Pmapsize = xml->getpar127("map_size", Pmapsize); + Pmappingenabled = xml->getpar127("mapping_enabled", Pmappingenabled); + for(int i = 0; i < Pmapsize; i++) { + if(xml->enterbranch("KEYMAP", i) == 0) + continue; + Pmapping[i] = xml->getpar127("degree", Pmapping[i]); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } xml->exitbranch(); - }; -}; + } +} -int Microtonal::saveXML(const char *filename)const +int Microtonal::saveXML(const char *filename) const { - XMLwrapper *xml=new XMLwrapper(); + XMLwrapper *xml = new XMLwrapper(); xml->beginbranch("MICROTONAL"); add2XML(xml); xml->endbranch(); - int result=xml->saveXMLfile(filename); + int result = xml->saveXMLfile(filename); delete (xml); - return(result); -}; + return result; +} int Microtonal::loadXML(const char *filename) { - XMLwrapper *xml=new XMLwrapper(); - if (xml->loadXMLfile(filename)<0) { - delete(xml); - return(-1); - }; + XMLwrapper *xml = new XMLwrapper(); + if(xml->loadXMLfile(filename) < 0) { + delete (xml); + return -1; + } - if (xml->enterbranch("MICROTONAL")==0) return(-10); + if(xml->enterbranch("MICROTONAL") == 0) + return -10; getfromXML(xml); xml->exitbranch(); - delete(xml); - return(0); -}; - + delete (xml); + return 0; +} diff --git a/src/Misc/Microtonal.h b/src/Misc/Microtonal.h @@ -35,102 +35,100 @@ /**Tuning settings and microtonal capabilities*/ class Microtonal { -public: - /**Constructor*/ - Microtonal(); - /**Destructor*/ - ~Microtonal(); - void defaults(); - /**Calculates the frequency for a given note - */ - REALTYPE getnotefreq(int note,int keyshift) const; - - - //Parameters - /**if the keys are inversed (the pitch is lower to keys from the right direction)*/ - unsigned char Pinvertupdown; - - /**the central key of the inversion*/ - unsigned char Pinvertupdowncenter; - - /**0 for 12 key temperate scale, 1 for microtonal*/ - unsigned char Penabled; - - /**the note of "A" key*/ - unsigned char PAnote; - - /**the frequency of the "A" note*/ - REALTYPE PAfreq; - - /**if the scale is "tuned" to a note, you can tune to other note*/ - unsigned char Pscaleshift; - - //first and last key (to retune) - unsigned char Pfirstkey; - unsigned char Plastkey; - - /**The middle note where scale degree 0 is mapped to*/ - unsigned char Pmiddlenote; - - /**Map size*/ - unsigned char Pmapsize; - - /**Mapping ON/OFF*/ - unsigned char Pmappingenabled; - /**Mapping (keys)*/ - short int Pmapping[128]; - - /**Fine detune to be applied to all notes*/ - unsigned char Pglobalfinedetune; - - // Functions - /** Return the current octave size*/ - unsigned char getoctavesize() const; - /**Convert tunning to string*/ - void tuningtoline(int n,char *line,int maxn); - /**load the tunnings from a .scl file*/ - int loadscl(const char *filename); - /**load the mapping from .kbm file*/ - int loadkbm(const char *filename); - /**Load text into the internal tunings - * - *\todo better description*/ - int texttotunings(const char *text); - /**Load text into the internal mappings - * - *\todo better description*/ - void texttomapping(const char *text); - - /**Name of Microtonal tuning*/ - unsigned char *Pname; - /**Comment about the tuning*/ - unsigned char *Pcomment; - - void add2XML(XMLwrapper *xml)const; - void getfromXML(XMLwrapper *xml); - int saveXML(const char *filename)const; - int loadXML(const char *filename); - - //simple operators primarily for debug - bool operator==(const Microtonal &micro) const; - bool operator!=(const Microtonal &micro) const; - -private: - int linetotunings(unsigned int nline,const char *line); - int loadline(FILE *file,char *line);//loads a line from the text file, while ignoring the lines beggining with "!" - unsigned char octavesize; - struct { - unsigned char type;//1 for cents or 2 for division - - // the real tuning (eg. +1.05946 for one halftone) - // or 2.0 for one octave - REALTYPE tuning; - - //the real tunning is x1/x2 - unsigned int x1,x2; - - } octave[MAX_OCTAVE_SIZE],tmpoctave[MAX_OCTAVE_SIZE]; - + public: + /**Constructor*/ + Microtonal(); + /**Destructor*/ + ~Microtonal(); + void defaults(); + /**Calculates the frequency for a given note + */ + REALTYPE getnotefreq(int note, int keyshift) const; + + + //Parameters + /**if the keys are inversed (the pitch is lower to keys from the right direction)*/ + unsigned char Pinvertupdown; + + /**the central key of the inversion*/ + unsigned char Pinvertupdowncenter; + + /**0 for 12 key temperate scale, 1 for microtonal*/ + unsigned char Penabled; + + /**the note of "A" key*/ + unsigned char PAnote; + + /**the frequency of the "A" note*/ + REALTYPE PAfreq; + + /**if the scale is "tuned" to a note, you can tune to other note*/ + unsigned char Pscaleshift; + + //first and last key (to retune) + unsigned char Pfirstkey; + unsigned char Plastkey; + + /**The middle note where scale degree 0 is mapped to*/ + unsigned char Pmiddlenote; + + /**Map size*/ + unsigned char Pmapsize; + + /**Mapping ON/OFF*/ + unsigned char Pmappingenabled; + /**Mapping (keys)*/ + short int Pmapping[128]; + + /**Fine detune to be applied to all notes*/ + unsigned char Pglobalfinedetune; + + // Functions + /** Return the current octave size*/ + unsigned char getoctavesize() const; + /**Convert tunning to string*/ + void tuningtoline(int n, char *line, int maxn); + /**load the tunnings from a .scl file*/ + int loadscl(const char *filename); + /**load the mapping from .kbm file*/ + int loadkbm(const char *filename); + /**Load text into the internal tunings + * + *\todo better description*/ + int texttotunings(const char *text); + /**Load text into the internal mappings + * + *\todo better description*/ + void texttomapping(const char *text); + + /**Name of Microtonal tuning*/ + unsigned char *Pname; + /**Comment about the tuning*/ + unsigned char *Pcomment; + + void add2XML(XMLwrapper *xml) const; + void getfromXML(XMLwrapper *xml); + int saveXML(const char *filename) const; + int loadXML(const char *filename); + + //simple operators primarily for debug + bool operator==(const Microtonal &micro) const; + bool operator!=(const Microtonal &micro) const; + + private: + int linetotunings(unsigned int nline, const char *line); + int loadline(FILE *file, char *line); //loads a line from the text file, while ignoring the lines beggining with "!" + unsigned char octavesize; + struct { + unsigned char type; //1 for cents or 2 for division + + // the real tuning (eg. +1.05946 for one halftone) + // or 2.0 for one octave + REALTYPE tuning; + + //the real tunning is x1/x2 + unsigned int x1, x2; + } octave[MAX_OCTAVE_SIZE], tmpoctave[MAX_OCTAVE_SIZE]; }; #endif diff --git a/src/Misc/Part.cpp b/src/Misc/Part.cpp @@ -26,122 +26,122 @@ #include <stdio.h> #include <string.h> -Part::Part(Microtonal *microtonal_,FFTwrapper *fft_, pthread_mutex_t *mutex_) +Part::Part(Microtonal *microtonal_, FFTwrapper *fft_, pthread_mutex_t *mutex_) { - microtonal=microtonal_; - fft=fft_; - mutex=mutex_; - partoutl=new REALTYPE [SOUND_BUFFER_SIZE]; - partoutr=new REALTYPE [SOUND_BUFFER_SIZE]; - tmpoutl=new REALTYPE [SOUND_BUFFER_SIZE]; - tmpoutr=new REALTYPE [SOUND_BUFFER_SIZE]; - - for (int n=0;n<NUM_KIT_ITEMS;n++) { - kit[n].Pname=new unsigned char [PART_MAX_NAME_LEN]; - kit[n].adpars=NULL; - kit[n].subpars=NULL; - kit[n].padpars=NULL; - }; - - kit[0].adpars=new ADnoteParameters(fft); - kit[0].subpars=new SUBnoteParameters(); - kit[0].padpars=new PADnoteParameters(fft,mutex); + microtonal = microtonal_; + fft = fft_; + mutex = mutex_; + partoutl = new REALTYPE [SOUND_BUFFER_SIZE]; + partoutr = new REALTYPE [SOUND_BUFFER_SIZE]; + tmpoutl = new REALTYPE [SOUND_BUFFER_SIZE]; + tmpoutr = new REALTYPE [SOUND_BUFFER_SIZE]; + + for(int n = 0; n < NUM_KIT_ITEMS; n++) { + kit[n].Pname = new unsigned char [PART_MAX_NAME_LEN]; + kit[n].adpars = NULL; + kit[n].subpars = NULL; + kit[n].padpars = NULL; + } + + kit[0].adpars = new ADnoteParameters(fft); + kit[0].subpars = new SUBnoteParameters(); + kit[0].padpars = new PADnoteParameters(fft, mutex); // ADPartParameters=kit[0].adpars; // SUBPartParameters=kit[0].subpars; //Part's Insertion Effects init - for (int nefx=0;nefx<NUM_PART_EFX;nefx++) { - partefx[nefx]=new EffectMgr(1,mutex); - Pefxbypass[nefx]=false; + for(int nefx = 0; nefx < NUM_PART_EFX; nefx++) { + partefx[nefx] = new EffectMgr(1, mutex); + Pefxbypass[nefx] = false; } - for (int n=0;n<NUM_PART_EFX+1;n++) { - partfxinputl[n]=new REALTYPE [SOUND_BUFFER_SIZE]; - partfxinputr[n]=new REALTYPE [SOUND_BUFFER_SIZE]; - }; - - killallnotes=0; - oldfreq=-1.0; - - int i,j; - for (i=0;i<POLIPHONY;i++) { - partnote[i].status=KEY_OFF; - partnote[i].note=-1; - partnote[i].itemsplaying=0; - for (j=0;j<NUM_KIT_ITEMS;j++) { - partnote[i].kititem[j].adnote=NULL; - partnote[i].kititem[j].subnote=NULL; - partnote[i].kititem[j].padnote=NULL; - }; - partnote[i].time=0; - }; + for(int n = 0; n < NUM_PART_EFX + 1; n++) { + partfxinputl[n] = new REALTYPE [SOUND_BUFFER_SIZE]; + partfxinputr[n] = new REALTYPE [SOUND_BUFFER_SIZE]; + } + + killallnotes = 0; + oldfreq = -1.0; + + int i, j; + for(i = 0; i < POLIPHONY; i++) { + partnote[i].status = KEY_OFF; + partnote[i].note = -1; + partnote[i].itemsplaying = 0; + for(j = 0; j < NUM_KIT_ITEMS; j++) { + partnote[i].kititem[j].adnote = NULL; + partnote[i].kititem[j].subnote = NULL; + partnote[i].kititem[j].padnote = NULL; + } + partnote[i].time = 0; + } cleanup(); - Pname=new unsigned char [PART_MAX_NAME_LEN]; + Pname = new unsigned char [PART_MAX_NAME_LEN]; - oldvolumel=oldvolumer=0.5; - lastnote=-1; - lastpos=0; // lastpos will store previously used NoteOn(...)'s pos. - lastlegatomodevalid=false; // To store previous legatomodevalid value. + oldvolumel = oldvolumer = 0.5; + lastnote = -1; + lastpos = 0; // lastpos will store previously used NoteOn(...)'s pos. + lastlegatomodevalid = false; // To store previous legatomodevalid value. defaults(); -}; +} void Part::defaults() { - Penabled=0; - Pminkey=0; - Pmaxkey=127; - Pnoteon=1; - Ppolymode=1; - Plegatomode=0; + Penabled = 0; + Pminkey = 0; + Pmaxkey = 127; + Pnoteon = 1; + Ppolymode = 1; + Plegatomode = 0; setPvolume(96); - Pkeyshift=64; - Prcvchn=0; + Pkeyshift = 64; + Prcvchn = 0; setPpanning(64); - Pvelsns=64; - Pveloffs=64; - Pkeylimit=15; + Pvelsns = 64; + Pveloffs = 64; + Pkeylimit = 15; defaultsinstrument(); ctl.defaults(); -}; +} void Part::defaultsinstrument() { - ZERO(Pname,PART_MAX_NAME_LEN); - - info.Ptype=0; - ZERO(info.Pauthor,MAX_INFO_TEXT_SIZE+1); - ZERO(info.Pcomments,MAX_INFO_TEXT_SIZE+1); - - Pkitmode=0; - Pdrummode=0; - - for (int n=0;n<NUM_KIT_ITEMS;n++) { - kit[n].Penabled=0; - kit[n].Pmuted=0; - kit[n].Pminkey=0; - kit[n].Pmaxkey=127; - kit[n].Padenabled=0; - kit[n].Psubenabled=0; - kit[n].Ppadenabled=0; - ZERO(kit[n].Pname,PART_MAX_NAME_LEN); - kit[n].Psendtoparteffect=0; - if (n!=0) setkititemstatus(n,0); - }; - kit[0].Penabled=1; - kit[0].Padenabled=1; + ZERO(Pname, PART_MAX_NAME_LEN); + + info.Ptype = 0; + ZERO(info.Pauthor, MAX_INFO_TEXT_SIZE + 1); + ZERO(info.Pcomments, MAX_INFO_TEXT_SIZE + 1); + + Pkitmode = 0; + Pdrummode = 0; + + for(int n = 0; n < NUM_KIT_ITEMS; n++) { + kit[n].Penabled = 0; + kit[n].Pmuted = 0; + kit[n].Pminkey = 0; + kit[n].Pmaxkey = 127; + kit[n].Padenabled = 0; + kit[n].Psubenabled = 0; + kit[n].Ppadenabled = 0; + ZERO(kit[n].Pname, PART_MAX_NAME_LEN); + kit[n].Psendtoparteffect = 0; + if(n != 0) + setkititemstatus(n, 0); + } + kit[0].Penabled = 1; + kit[0].Padenabled = 1; kit[0].adpars->defaults(); kit[0].subpars->defaults(); kit[0].padpars->defaults(); - for (int nefx=0;nefx<NUM_PART_EFX;nefx++) { + for(int nefx = 0; nefx < NUM_PART_EFX; nefx++) { partefx[nefx]->defaults(); - Pefxroute[nefx]=0;//route to next effect - }; - -}; + Pefxroute[nefx] = 0; //route to next effect + } +} @@ -150,321 +150,515 @@ void Part::defaultsinstrument() */ void Part::cleanup() { - for (int k=0;k<POLIPHONY;k++) KillNotePos(k); - for (int i=0;i<SOUND_BUFFER_SIZE;i++) { - partoutl[i]=denormalkillbuf[i]; - partoutr[i]=denormalkillbuf[i]; - tmpoutl[i]=0.0; - tmpoutr[i]=0.0; - }; + for(int k = 0; k < POLIPHONY; k++) + KillNotePos(k); + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + partoutl[i] = denormalkillbuf[i]; + partoutr[i] = denormalkillbuf[i]; + tmpoutl[i] = 0.0; + tmpoutr[i] = 0.0; + } ctl.resetall(); - for (int nefx=0;nefx<NUM_PART_EFX;nefx++) partefx[nefx]->cleanup(); - for (int n=0;n<NUM_PART_EFX+1;n++) { - for (int i=0;i<SOUND_BUFFER_SIZE;i++) { - partfxinputl[n][i]=denormalkillbuf[i]; - partfxinputr[n][i]=denormalkillbuf[i]; - }; - }; -}; + for(int nefx = 0; nefx < NUM_PART_EFX; nefx++) + partefx[nefx]->cleanup(); + for(int n = 0; n < NUM_PART_EFX + 1; n++) { + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + partfxinputl[n][i] = denormalkillbuf[i]; + partfxinputr[n][i] = denormalkillbuf[i]; + } + } +} Part::~Part() { cleanup(); - for (int n=0;n<NUM_KIT_ITEMS;n++) { - if (kit[n].adpars!=NULL) delete (kit[n].adpars); - if (kit[n].subpars!=NULL) delete (kit[n].subpars); - if (kit[n].padpars!=NULL) delete (kit[n].padpars); - kit[n].adpars=NULL; - kit[n].subpars=NULL; - kit[n].padpars=NULL; + for(int n = 0; n < NUM_KIT_ITEMS; n++) { + if(kit[n].adpars != NULL) + delete (kit[n].adpars); + if(kit[n].subpars != NULL) + delete (kit[n].subpars); + if(kit[n].padpars != NULL) + delete (kit[n].padpars); + kit[n].adpars = NULL; + kit[n].subpars = NULL; + kit[n].padpars = NULL; delete [] kit[n].Pname; - }; + } delete [] Pname; delete [] partoutl; delete [] partoutr; delete [] tmpoutl; delete [] tmpoutr; - for (int nefx=0;nefx<NUM_PART_EFX;nefx++) + for(int nefx = 0; nefx < NUM_PART_EFX; nefx++) delete (partefx[nefx]); - for (int n=0;n<NUM_PART_EFX+1;n++) { + for(int n = 0; n < NUM_PART_EFX + 1; n++) { delete [] partfxinputl[n]; delete [] partfxinputr[n]; } -}; +} /* * Note On Messages */ -void Part::NoteOn(unsigned char note,unsigned char velocity,int masterkeyshift) +void Part::NoteOn(unsigned char note, + unsigned char velocity, + int masterkeyshift) { - int i,pos; + int i, pos; // Legato and MonoMem used vars: - int posb=POLIPHONY-1; // Just a dummy initial value. - bool legatomodevalid=false;//true when legato mode is determined applicable. - bool doinglegato=false; // true when we determined we do a legato note. - bool ismonofirstnote=false; /*(In Mono/Legato) true when we determined - no other notes are held down or sustained.*/ - int lastnotecopy=lastnote;//Useful after lastnote has been changed. - - if (Pnoteon==0) return; - if ((note<Pminkey)||(note>Pmaxkey)) return; + int posb = POLIPHONY - 1; // Just a dummy initial value. + bool legatomodevalid = false; //true when legato mode is determined applicable. + bool doinglegato = false; // true when we determined we do a legato note. + bool ismonofirstnote = false; /*(In Mono/Legato) true when we determined + no other notes are held down or sustained.*/ + int lastnotecopy = lastnote; //Useful after lastnote has been changed. + + if(Pnoteon == 0) + return; + if((note < Pminkey) || (note > Pmaxkey)) + return; // MonoMem stuff: - if (Ppolymode==0) { // If Poly is off + if(Ppolymode == 0) { // If Poly is off monomemnotes.push_back(note); // Add note to the list. - monomem[note].velocity=velocity; // Store this note's velocity. - monomem[note].mkeyshift=masterkeyshift; /* Store masterkeyshift too, - I'm not sure why though... */ - if ((partnote[lastpos].status!=KEY_PLAYING) - && (partnote[lastpos].status!=KEY_RELASED_AND_SUSTAINED)) { - ismonofirstnote=true; // No other keys are held or sustained. - } - } else { - // Poly mode is On so just make sure the list is empty. - if (not monomemnotes.empty()) monomemnotes.clear(); + monomem[note].velocity = velocity; // Store this note's velocity. + monomem[note].mkeyshift = masterkeyshift; /* Store masterkeyshift too, + I'm not sure why though... */ + if((partnote[lastpos].status != KEY_PLAYING) + && (partnote[lastpos].status != KEY_RELASED_AND_SUSTAINED)) + ismonofirstnote = true; // No other keys are held or sustained. } + else + // Poly mode is On so just make sure the list is empty. + if(not monomemnotes.empty()) + monomemnotes.clear(); - lastnote=note; + lastnote = note; - pos=-1; - for (i=0;i<POLIPHONY;i++) { - if (partnote[i].status==KEY_OFF) { - pos=i; + pos = -1; + for(i = 0; i < POLIPHONY; i++) { + if(partnote[i].status == KEY_OFF) { + pos = i; break; - }; - }; - - if ((Plegatomode!=0) && (Pdrummode==0)) { - if (Ppolymode!=0) { - fprintf(stderr, "ZynAddSubFX WARNING: Poly and Legato modes are both On, that should not happen ! ... Disabling Legato mode ! - (Part.C::NoteOn(..))\n"); - Plegatomode=0; - } else { + } + } + + if((Plegatomode != 0) && (Pdrummode == 0)) { + if(Ppolymode != 0) { + fprintf( + stderr, + "ZynAddSubFX WARNING: Poly and Legato modes are both On, that should not happen ! ... Disabling Legato mode ! - (Part.C::NoteOn(..))\n"); + Plegatomode = 0; + } + else { // Legato mode is on and applicable. - legatomodevalid=true; - if ((not ismonofirstnote)&&(lastlegatomodevalid)) { + legatomodevalid = true; + if((not ismonofirstnote) && (lastlegatomodevalid)) { // At least one other key is held or sustained, and the // previous note was played while in valid legato mode. - doinglegato=true; // So we'll do a legato note. - pos=lastpos; // A legato note uses same pos as previous.. - posb=lastposb; // .. same goes for posb. - } else { + doinglegato = true; // So we'll do a legato note. + pos = lastpos; // A legato note uses same pos as previous.. + posb = lastposb; // .. same goes for posb. + } + else { // Legato mode is valid, but this is only a first note. - for (i=0;i<POLIPHONY;i++) - if ((partnote[i].status==KEY_PLAYING) || - (partnote[i].status==KEY_RELASED_AND_SUSTAINED)) + for(i = 0; i < POLIPHONY; i++) + if((partnote[i].status == KEY_PLAYING) + || (partnote[i].status == KEY_RELASED_AND_SUSTAINED)) RelaseNotePos(i); // Set posb - posb=(pos+1)%POLIPHONY;//We really want it (if the following fails) - for (i=0;i<POLIPHONY;i++) { - if ((partnote[i].status==KEY_OFF) && (pos!=i)) { - posb=i; + posb = (pos + 1) % POLIPHONY; //We really want it (if the following fails) + for(i = 0; i < POLIPHONY; i++) + if((partnote[i].status == KEY_OFF) && (pos != i)) { + posb = i; break; } - } } - lastposb=posb;// Keep a trace of used posb - } - } else { // Legato mode is either off or non-applicable. - if (Ppolymode==0) {//if the mode is 'mono' turn off all other notes - for (i=0;i<POLIPHONY;i++) - if (partnote[i].status==KEY_PLAYING) RelaseNotePos(i); - RelaseSustainedKeys(); + lastposb = posb; // Keep a trace of used posb } } - lastlegatomodevalid=legatomodevalid; + else // Legato mode is either off or non-applicable. + if(Ppolymode == 0) { //if the mode is 'mono' turn off all other notes + for(i = 0; i < POLIPHONY; i++) + if(partnote[i].status == KEY_PLAYING) + RelaseNotePos(i); + RelaseSustainedKeys(); + } + lastlegatomodevalid = legatomodevalid; - if (pos==-1) { + if(pos == -1) //test - fprintf(stderr,"%s","NOTES TOO MANY (> POLIPHONY) - (Part.C::NoteOn(..))\n"); - } else { - + fprintf(stderr, + "%s", + "NOTES TOO MANY (> POLIPHONY) - (Part.C::NoteOn(..))\n"); + else { //start the note - partnote[pos].status=KEY_PLAYING; - partnote[pos].note=note; - if (legatomodevalid) { - partnote[posb].status=KEY_PLAYING; - partnote[posb].note=note; + partnote[pos].status = KEY_PLAYING; + partnote[pos].note = note; + if(legatomodevalid) { + partnote[posb].status = KEY_PLAYING; + partnote[posb].note = note; } //this computes the velocity sensing of the part - REALTYPE vel=VelF(velocity/127.0,Pvelsns); + REALTYPE vel = VelF(velocity / 127.0, Pvelsns); //compute the velocity offset - vel+=(Pveloffs-64.0)/64.0; - if (vel<0.0) vel=0.0; - else if (vel>1.0) vel=1.0; + vel += (Pveloffs - 64.0) / 64.0; + if(vel < 0.0) + vel = 0.0; + else + if(vel > 1.0) + vel = 1.0; //compute the keyshift - int partkeyshift=(int)Pkeyshift-64; - int keyshift=masterkeyshift+partkeyshift; + int partkeyshift = (int)Pkeyshift - 64; + int keyshift = masterkeyshift + partkeyshift; //initialise note frequency REALTYPE notebasefreq; - if (Pdrummode==0) { - notebasefreq=microtonal->getnotefreq(note,keyshift); - if (notebasefreq<0.0) return;//the key is no mapped - } else { - notebasefreq=440.0*pow(2.0,(note-69.0)/12.0); - }; + if(Pdrummode == 0) { + notebasefreq = microtonal->getnotefreq(note, keyshift); + if(notebasefreq < 0.0) + return; //the key is no mapped + } + else + notebasefreq = 440.0 * pow(2.0, (note - 69.0) / 12.0); + ; //Portamento - if (oldfreq<1.0) oldfreq=notebasefreq;//this is only the first note is played + if(oldfreq < 1.0) + oldfreq = notebasefreq; //this is only the first note is played // For Mono/Legato: Force Portamento Off on first // notes. That means it is required that the previous note is // still held down or sustained for the Portamento to activate // (that's like Legato). - int portamento=0; - if ((Ppolymode!=0) || (not ismonofirstnote)) { + int portamento = 0; + if((Ppolymode != 0) || (not ismonofirstnote)) // I added a third argument to the // ctl.initportamento(...) function to be able // to tell it if we're doing a legato note. - portamento=ctl.initportamento(oldfreq,notebasefreq,doinglegato); - } + portamento = ctl.initportamento(oldfreq, notebasefreq, doinglegato); - if (portamento!=0) ctl.portamento.noteusing=pos; - oldfreq=notebasefreq; + if(portamento != 0) + ctl.portamento.noteusing = pos; + oldfreq = notebasefreq; - lastpos=pos; // Keep a trace of used pos. + lastpos = pos; // Keep a trace of used pos. - if (doinglegato) { + if(doinglegato) { // Do Legato note - if (Pkitmode==0) { // "normal mode" legato note - if ((kit[0].Padenabled!=0) - && (partnote[pos].kititem[0].adnote!=NULL) - && (partnote[posb].kititem[0].adnote!=NULL)) { - partnote[pos].kititem[0].adnote->ADlegatonote(notebasefreq, vel, portamento, note, true);//'true' is to tell it it's being called from here. - partnote[posb].kititem[0].adnote->ADlegatonote(notebasefreq, vel, portamento, note, true); + if(Pkitmode == 0) { // "normal mode" legato note + if((kit[0].Padenabled != 0) + && (partnote[pos].kititem[0].adnote != NULL) + && (partnote[posb].kititem[0].adnote != NULL)) { + partnote[pos].kititem[0].adnote->ADlegatonote(notebasefreq, + vel, + portamento, + note, + true); //'true' is to tell it it's being called from here. + partnote[posb].kititem[0].adnote->ADlegatonote(notebasefreq, + vel, + portamento, + note, + true); } - if ((kit[0].Psubenabled!=0) - && (partnote[pos].kititem[0].subnote!=NULL) - && (partnote[posb].kititem[0].subnote!=NULL)) { - partnote[pos].kititem[0].subnote->SUBlegatonote(notebasefreq, vel, portamento, note, true); - partnote[posb].kititem[0].subnote->SUBlegatonote(notebasefreq, vel, portamento, note, true); + if((kit[0].Psubenabled != 0) + && (partnote[pos].kititem[0].subnote != NULL) + && (partnote[posb].kititem[0].subnote != NULL)) { + partnote[pos].kititem[0].subnote->SUBlegatonote( + notebasefreq, + vel, + portamento, + note, + true); + partnote[posb].kititem[0].subnote->SUBlegatonote( + notebasefreq, + vel, + portamento, + note, + true); } - if ((kit[0].Ppadenabled!=0) - && (partnote[pos].kititem[0].padnote!=NULL) - && (partnote[posb].kititem[0].padnote!=NULL)) { - partnote[pos].kititem[0].padnote->PADlegatonote(notebasefreq, vel, portamento, note, true); - partnote[posb].kititem[0].padnote->PADlegatonote(notebasefreq, vel, portamento, note, true); + if((kit[0].Ppadenabled != 0) + && (partnote[pos].kititem[0].padnote != NULL) + && (partnote[posb].kititem[0].padnote != NULL)) { + partnote[pos].kititem[0].padnote->PADlegatonote( + notebasefreq, + vel, + portamento, + note, + true); + partnote[posb].kititem[0].padnote->PADlegatonote( + notebasefreq, + vel, + portamento, + note, + true); } - - } else { // "kit mode" legato note - int ci=0; - for (int item=0;item<NUM_KIT_ITEMS;item++) { - if (kit[item].Pmuted!=0) continue; - if ((note<kit[item].Pminkey)||(note>kit[item].Pmaxkey)) continue; - - if ((lastnotecopy<kit[item].Pminkey) - ||(lastnotecopy>kit[item].Pmaxkey)) + } + else { // "kit mode" legato note + int ci = 0; + for(int item = 0; item < NUM_KIT_ITEMS; item++) { + if(kit[item].Pmuted != 0) + continue; + if((note < kit[item].Pminkey) || (note > kit[item].Pmaxkey)) + continue; + + if((lastnotecopy < kit[item].Pminkey) + || (lastnotecopy > kit[item].Pmaxkey)) continue; // We will not perform legato across 2 key regions. - partnote[pos].kititem[ci].sendtoparteffect=( kit[item].Psendtoparteffect<NUM_PART_EFX ? kit[item].Psendtoparteffect: NUM_PART_EFX);//if this parameter is 127 for "unprocessed" - partnote[posb].kititem[ci].sendtoparteffect=( kit[item].Psendtoparteffect<NUM_PART_EFX ? kit[item].Psendtoparteffect: NUM_PART_EFX); - - if ((kit[item].Padenabled!=0) && (kit[item].adpars!=NULL) - && (partnote[pos].kititem[ci].adnote!=NULL) - && (partnote[posb].kititem[ci].adnote!=NULL)) { - partnote[pos].kititem[ci].adnote->ADlegatonote(notebasefreq,vel,portamento,note,true); - partnote[posb].kititem[ci].adnote->ADlegatonote(notebasefreq,vel,portamento,note,true); + partnote[pos].kititem[ci].sendtoparteffect = + (kit[item].Psendtoparteffect < + NUM_PART_EFX ? kit[item].Psendtoparteffect : NUM_PART_EFX); //if this parameter is 127 for "unprocessed" + partnote[posb].kititem[ci].sendtoparteffect = + (kit[item].Psendtoparteffect < + NUM_PART_EFX ? kit[item].Psendtoparteffect : NUM_PART_EFX); + + if((kit[item].Padenabled != 0) && (kit[item].adpars != NULL) + && (partnote[pos].kititem[ci].adnote != NULL) + && (partnote[posb].kititem[ci].adnote != NULL)) { + partnote[pos].kititem[ci].adnote->ADlegatonote( + notebasefreq, + vel, + portamento, + note, + true); + partnote[posb].kititem[ci].adnote->ADlegatonote( + notebasefreq, + vel, + portamento, + note, + true); } - if ((kit[item].Psubenabled!=0) && (kit[item].subpars!=NULL) - && (partnote[pos].kititem[ci].subnote!=NULL) - && (partnote[posb].kititem[ci].subnote!=NULL)) { - partnote[pos].kititem[ci].subnote->SUBlegatonote(notebasefreq,vel,portamento,note,true); - partnote[posb].kititem[ci].subnote->SUBlegatonote(notebasefreq,vel,portamento,note,true); + if((kit[item].Psubenabled != 0) + && (kit[item].subpars != NULL) + && (partnote[pos].kititem[ci].subnote != NULL) + && (partnote[posb].kititem[ci].subnote != NULL)) { + partnote[pos].kititem[ci].subnote->SUBlegatonote( + notebasefreq, + vel, + portamento, + note, + true); + partnote[posb].kititem[ci].subnote->SUBlegatonote( + notebasefreq, + vel, + portamento, + note, + true); } - if ((kit[item].Ppadenabled!=0) && (kit[item].padpars!=NULL) - && (partnote[pos].kititem[ci].padnote!=NULL) - && (partnote[posb].kititem[ci].padnote!=NULL)) { - partnote[pos].kititem[ci].padnote->PADlegatonote(notebasefreq,vel,portamento,note,true); - partnote[posb].kititem[ci].padnote->PADlegatonote(notebasefreq,vel,portamento,note,true); + if((kit[item].Ppadenabled != 0) + && (kit[item].padpars != NULL) + && (partnote[pos].kititem[ci].padnote != NULL) + && (partnote[posb].kititem[ci].padnote != NULL)) { + partnote[pos].kititem[ci].padnote->PADlegatonote( + notebasefreq, + vel, + portamento, + note, + true); + partnote[posb].kititem[ci].padnote->PADlegatonote( + notebasefreq, + vel, + portamento, + note, + true); } - if ((kit[item].adpars!=NULL)||(kit[item].subpars!=NULL)||(kit[item].padpars!=NULL)) { + if((kit[item].adpars != NULL) + || (kit[item].subpars != NULL) + || (kit[item].padpars != NULL)) { ci++; - if ( ((kit[item].Padenabled!=0)||(kit[item].Psubenabled!=0)||(kit[item].Ppadenabled!=0)) && (Pkitmode==2) ) break; + if(((kit[item].Padenabled != 0) + || (kit[item].Psubenabled != 0) + || (kit[item].Ppadenabled != 0)) && (Pkitmode == 2)) + break; } } - if (ci==0) { + if(ci == 0) { // No legato were performed at all, so pretend nothing happened: monomemnotes.pop_back(); // Remove last note from the list. - lastnote=lastnotecopy; // Set lastnote back to previous value. + lastnote = lastnotecopy; // Set lastnote back to previous value. } } return; // Ok, Legato note done, return. } - partnote[pos].itemsplaying=0; - if (legatomodevalid) partnote[posb].itemsplaying=0; - - if (Pkitmode==0) {//init the notes for the "normal mode" - partnote[pos].kititem[0].sendtoparteffect=0; - if (kit[0].Padenabled!=0) partnote[pos].kititem[0].adnote=new ADnote(kit[0].adpars,&ctl,notebasefreq,vel,portamento,note,false); - if (kit[0].Psubenabled!=0) partnote[pos].kititem[0].subnote=new SUBnote(kit[0].subpars,&ctl,notebasefreq,vel,portamento,note,false); - if (kit[0].Ppadenabled!=0) partnote[pos].kititem[0].padnote=new PADnote(kit[0].padpars,&ctl,notebasefreq,vel,portamento,note,false); - if ((kit[0].Padenabled!=0)||(kit[0].Psubenabled!=0)||(kit[0].Ppadenabled!=0)) partnote[pos].itemsplaying++; + partnote[pos].itemsplaying = 0; + if(legatomodevalid) + partnote[posb].itemsplaying = 0; + + if(Pkitmode == 0) { //init the notes for the "normal mode" + partnote[pos].kititem[0].sendtoparteffect = 0; + if(kit[0].Padenabled != 0) + partnote[pos].kititem[0].adnote = new ADnote(kit[0].adpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + false); + if(kit[0].Psubenabled != 0) + partnote[pos].kititem[0].subnote = new SUBnote(kit[0].subpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + false); + if(kit[0].Ppadenabled != 0) + partnote[pos].kititem[0].padnote = new PADnote(kit[0].padpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + false); + if((kit[0].Padenabled != 0) || (kit[0].Psubenabled != 0) + || (kit[0].Ppadenabled != 0)) + partnote[pos].itemsplaying++; // Spawn another note (but silent) if legatomodevalid==true - if (legatomodevalid) { - partnote[posb].kititem[0].sendtoparteffect=0; - if (kit[0].Padenabled!=0) partnote[posb].kititem[0].adnote=new ADnote(kit[0].adpars,&ctl,notebasefreq,vel,portamento,note,true);//true for silent. - if (kit[0].Psubenabled!=0) partnote[posb].kititem[0].subnote=new SUBnote(kit[0].subpars,&ctl,notebasefreq,vel,portamento,note,true); - if (kit[0].Ppadenabled!=0) partnote[posb].kititem[0].padnote=new PADnote(kit[0].padpars,&ctl,notebasefreq,vel,portamento,note,true); - if ((kit[0].Padenabled!=0)||(kit[0].Psubenabled!=0)||(kit[0].Ppadenabled!=0)) partnote[posb].itemsplaying++; + if(legatomodevalid) { + partnote[posb].kititem[0].sendtoparteffect = 0; + if(kit[0].Padenabled != 0) + partnote[posb].kititem[0].adnote = new ADnote(kit[0].adpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + true); //true for silent. + if(kit[0].Psubenabled != 0) + partnote[posb].kititem[0].subnote = new SUBnote( + kit[0].subpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + true); + if(kit[0].Ppadenabled != 0) + partnote[posb].kititem[0].padnote = new PADnote( + kit[0].padpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + true); + if((kit[0].Padenabled != 0) || (kit[0].Psubenabled != 0) + || (kit[0].Ppadenabled != 0)) + partnote[posb].itemsplaying++; } - - } else {//init the notes for the "kit mode" - for (int item=0;item<NUM_KIT_ITEMS;item++) { - if (kit[item].Pmuted!=0) continue; - if ((note<kit[item].Pminkey)||(note>kit[item].Pmaxkey)) continue; - - int ci=partnote[pos].itemsplaying;//ci=current item - - partnote[pos].kititem[ci].sendtoparteffect=( kit[item].Psendtoparteffect<NUM_PART_EFX ? - kit[item].Psendtoparteffect: NUM_PART_EFX);//if this parameter is 127 for "unprocessed" - - if ((kit[item].adpars!=NULL)&&(kit[item].Padenabled)!=0) - partnote[pos].kititem[ci].adnote=new ADnote(kit[item].adpars,&ctl,notebasefreq,vel,portamento,note,false); - - if ((kit[item].subpars!=NULL)&&(kit[item].Psubenabled)!=0) - partnote[pos].kititem[ci].subnote=new SUBnote(kit[item].subpars,&ctl,notebasefreq,vel,portamento,note,false); - - if ((kit[item].padpars!=NULL)&&(kit[item].Ppadenabled)!=0) - partnote[pos].kititem[ci].padnote=new PADnote(kit[item].padpars,&ctl,notebasefreq,vel,portamento,note,false); + } + else { //init the notes for the "kit mode" + for(int item = 0; item < NUM_KIT_ITEMS; item++) { + if(kit[item].Pmuted != 0) + continue; + if((note < kit[item].Pminkey) || (note > kit[item].Pmaxkey)) + continue; + + int ci = partnote[pos].itemsplaying; //ci=current item + + partnote[pos].kititem[ci].sendtoparteffect = + (kit[item].Psendtoparteffect < NUM_PART_EFX ? + kit[item]. + Psendtoparteffect : NUM_PART_EFX); //if this parameter is 127 for "unprocessed" + + if((kit[item].adpars != NULL) && ((kit[item].Padenabled) != 0)) + partnote[pos].kititem[ci].adnote = new ADnote( + kit[item].adpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + false); + + if((kit[item].subpars != NULL) && ((kit[item].Psubenabled) != 0)) + partnote[pos].kititem[ci].subnote = new SUBnote( + kit[item].subpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + false); + + if((kit[item].padpars != NULL) && ((kit[item].Ppadenabled) != 0)) + partnote[pos].kititem[ci].padnote = new PADnote( + kit[item].padpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + false); // Spawn another note (but silent) if legatomodevalid==true - if (legatomodevalid) { - partnote[posb].kititem[ci].sendtoparteffect=( kit[item].Psendtoparteffect<NUM_PART_EFX ? kit[item].Psendtoparteffect: NUM_PART_EFX);//if this parameter is 127 for "unprocessed" - - if ((kit[item].adpars!=NULL)&&(kit[item].Padenabled)!=0) - partnote[posb].kititem[ci].adnote=new ADnote(kit[item].adpars,&ctl,notebasefreq,vel,portamento,note,true);//true for silent. - if ((kit[item].subpars!=NULL)&&(kit[item].Psubenabled)!=0) - partnote[posb].kititem[ci].subnote=new SUBnote(kit[item].subpars,&ctl,notebasefreq,vel,portamento,note,true); - if ((kit[item].padpars!=NULL)&&(kit[item].Ppadenabled)!=0) - partnote[posb].kititem[ci].padnote=new PADnote(kit[item].padpars,&ctl,notebasefreq,vel,portamento,note,true); - - if ((kit[item].adpars!=NULL)|| (kit[item].subpars!=NULL)) + if(legatomodevalid) { + partnote[posb].kititem[ci].sendtoparteffect = + (kit[item].Psendtoparteffect < + NUM_PART_EFX ? kit[item].Psendtoparteffect : NUM_PART_EFX); //if this parameter is 127 for "unprocessed" + + if((kit[item].adpars != NULL) + && ((kit[item].Padenabled) != 0)) + partnote[posb].kititem[ci].adnote = new ADnote( + kit[item].adpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + true); //true for silent. + if((kit[item].subpars != NULL) + && ((kit[item].Psubenabled) != 0)) + partnote[posb].kititem[ci].subnote = + new SUBnote(kit[item].subpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + true); + if((kit[item].padpars != NULL) + && ((kit[item].Ppadenabled) != 0)) + partnote[posb].kititem[ci].padnote = + new PADnote(kit[item].padpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + true); + + if((kit[item].adpars != NULL) || (kit[item].subpars != NULL)) partnote[posb].itemsplaying++; } - if ((kit[item].adpars!=NULL)|| (kit[item].subpars!=NULL)) { + if((kit[item].adpars != NULL) || (kit[item].subpars != NULL)) { partnote[pos].itemsplaying++; - if ( ((kit[item].Padenabled!=0)||(kit[item].Psubenabled!=0)||(kit[item].Ppadenabled!=0)) - && (Pkitmode==2) ) break; - }; - }; - }; - }; + if(((kit[item].Padenabled != 0) + || (kit[item].Psubenabled != 0) + || (kit[item].Ppadenabled != 0)) + && (Pkitmode == 2)) + break; + } + } + } + } //this only relase the keys if there is maximum number of keys allowed setkeylimit(Pkeylimit); -}; +} /* * Note Off Messages @@ -474,43 +668,42 @@ void Part::NoteOff(unsigned char note) //relase the key int i; // This note is released, so we remove it from the list. - if (not monomemnotes.empty()) monomemnotes.remove(note); + if(not monomemnotes.empty()) + monomemnotes.remove(note); - for (i=POLIPHONY-1;i>=0;i--) { //first note in, is first out if there are same note multiple times - if ((partnote[i].status==KEY_PLAYING)&&(partnote[i].note==note)) { - if (ctl.sustain.sustain==0) { //the sustain pedal is not pushed - if ((Ppolymode==0) && (not monomemnotes.empty())) { + for(i = POLIPHONY - 1; i >= 0; i--) //first note in, is first out if there are same note multiple times + if((partnote[i].status == KEY_PLAYING) && (partnote[i].note == note)) { + if(ctl.sustain.sustain == 0) { //the sustain pedal is not pushed + if((Ppolymode == 0) && (not monomemnotes.empty())) MonoMemRenote(); // To play most recent still held note. - } else { + else RelaseNotePos(i); /// break; - } - } else {//the sustain pedal is pushed - partnote[i].status=KEY_RELASED_AND_SUSTAINED; } + else //the sustain pedal is pushed + partnote[i].status = KEY_RELASED_AND_SUSTAINED; } - } -}; +} /* * Controllers */ -void Part::SetController(unsigned int type,int par) +void Part::SetController(unsigned int type, int par) { - switch (type) { + switch(type) { case C_pitchwheel: ctl.setpitchwheel(par); break; case C_expression: ctl.setexpression(par); - setPvolume(Pvolume);//update the volume + setPvolume(Pvolume); //update the volume break; case C_portamento: ctl.setportamento(par); break; case C_panning: ctl.setpanning(par); - setPpanning(Ppanning);//update the panning + setPpanning(Ppanning); //update the panning break; case C_filtercutoff: ctl.setfiltercutoff(par); @@ -529,32 +722,38 @@ void Part::SetController(unsigned int type,int par) break; case C_volume: ctl.setvolume(par); - if (ctl.volume.receive!=0) volume=ctl.volume.volume; - else setPvolume(Pvolume); + if(ctl.volume.receive != 0) + volume = ctl.volume.volume; + else + setPvolume(Pvolume); break; case C_sustain: ctl.setsustain(par); - if (ctl.sustain.sustain==0) RelaseSustainedKeys(); + if(ctl.sustain.sustain == 0) + RelaseSustainedKeys(); break; case C_allsoundsoff: - AllNotesOff();//Panic + AllNotesOff(); //Panic break; case C_resetallcontrollers: ctl.resetall(); RelaseSustainedKeys(); - if (ctl.volume.receive!=0) volume=ctl.volume.volume; - else setPvolume(Pvolume); - setPvolume(Pvolume);//update the volume - setPpanning(Ppanning);//update the panning - - for (int item=0;item<NUM_KIT_ITEMS;item++) { - if (kit[item].adpars==NULL) continue; + if(ctl.volume.receive != 0) + volume = ctl.volume.volume; + else + setPvolume(Pvolume); + setPvolume(Pvolume); //update the volume + setPpanning(Ppanning); //update the panning + + for(int item = 0; item < NUM_KIT_ITEMS; item++) { + if(kit[item].adpars == NULL) + continue; kit[item].adpars->GlobalPar.Reson-> - sendcontroller(C_resonance_center,1.0); + sendcontroller(C_resonance_center, 1.0); kit[item].adpars->GlobalPar.Reson-> - sendcontroller(C_resonance_bandwidth,1.0); - }; + sendcontroller(C_resonance_bandwidth, 1.0); + } //more update to add here if I add controllers break; case C_allnotesoff: @@ -562,19 +761,20 @@ void Part::SetController(unsigned int type,int par) break; case C_resonance_center: ctl.setresonancecenter(par); - for (int item=0;item<NUM_KIT_ITEMS;item++) { - if (kit[item].adpars==NULL) continue; + for(int item = 0; item < NUM_KIT_ITEMS; item++) { + if(kit[item].adpars == NULL) + continue; kit[item].adpars->GlobalPar.Reson-> - sendcontroller(C_resonance_center,ctl.resonancecenter.relcenter); - }; + sendcontroller(C_resonance_center, ctl.resonancecenter.relcenter); + } break; case C_resonance_bandwidth: ctl.setresonancebw(par); kit[0].adpars->GlobalPar.Reson-> - sendcontroller(C_resonance_bandwidth,ctl.resonancebandwidth.relbw); + sendcontroller(C_resonance_bandwidth, ctl.resonancebandwidth.relbw); break; - }; -}; + } +} /* * Relase the sustained keys */ @@ -582,13 +782,14 @@ void Part::SetController(unsigned int type,int par) void Part::RelaseSustainedKeys() { // Let's call MonoMemRenote() on some conditions: - if ((Ppolymode==0) && (not monomemnotes.empty())) - if (monomemnotes.back()!=lastnote) // Sustain controller manipulation would cause repeated same note respawn without this check. + if((Ppolymode == 0) && (not monomemnotes.empty())) + if(monomemnotes.back() != lastnote) // Sustain controller manipulation would cause repeated same note respawn without this check. MonoMemRenote(); // To play most recent still held note. - for (int i=0;i<POLIPHONY;i++) - if (partnote[i].status==KEY_RELASED_AND_SUSTAINED) RelaseNotePos(i); -}; + for(int i = 0; i < POLIPHONY; i++) + if(partnote[i].status == KEY_RELASED_AND_SUSTAINED) + RelaseNotePos(i); +} /* * Relase all keys @@ -596,25 +797,24 @@ void Part::RelaseSustainedKeys() void Part::RelaseAllKeys() { - for (int i=0;i<POLIPHONY;i++) { - if ((partnote[i].status!=KEY_RELASED)&& - (partnote[i].status!=KEY_OFF)) //thanks to Frank Neumann + for(int i = 0; i < POLIPHONY; i++) + if((partnote[i].status != KEY_RELASED) + && (partnote[i].status != KEY_OFF)) //thanks to Frank Neumann RelaseNotePos(i); - }; -}; + ; +} // Call NoteOn(...) with the most recent still held key as new note // (Made for Mono/Legato). void Part::MonoMemRenote() { - unsigned char mmrtempnote=monomemnotes.back(); // Last list element. - monomemnotes.pop_back();// We remove it, will be added again in NoteOn(...). - if (Pnoteon==0) { + unsigned char mmrtempnote = monomemnotes.back(); // Last list element. + monomemnotes.pop_back(); // We remove it, will be added again in NoteOn(...). + if(Pnoteon == 0) RelaseNotePos(lastpos); - } else { + else NoteOn(mmrtempnote, monomem[mmrtempnote].velocity, monomem[mmrtempnote].mkeyshift); - } } /* @@ -622,23 +822,21 @@ void Part::MonoMemRenote() */ void Part::RelaseNotePos(int pos) { - - for (int j=0;j<NUM_KIT_ITEMS;j++) { - - if (partnote[pos].kititem[j].adnote!=NULL) - if (partnote[pos].kititem[j].adnote) + for(int j = 0; j < NUM_KIT_ITEMS; j++) { + if(partnote[pos].kititem[j].adnote != NULL) + if(partnote[pos].kititem[j].adnote) partnote[pos].kititem[j].adnote->relasekey(); - if (partnote[pos].kititem[j].subnote!=NULL) - if (partnote[pos].kititem[j].subnote!=NULL) + if(partnote[pos].kititem[j].subnote != NULL) + if(partnote[pos].kititem[j].subnote != NULL) partnote[pos].kititem[j].subnote->relasekey(); - if (partnote[pos].kititem[j].padnote!=NULL) - if (partnote[pos].kititem[j].padnote) + if(partnote[pos].kititem[j].padnote != NULL) + if(partnote[pos].kititem[j].padnote) partnote[pos].kititem[j].padnote->relasekey(); - }; - partnote[pos].status=KEY_RELASED; -}; + } + partnote[pos].status = KEY_RELASED; +} /* @@ -646,30 +844,30 @@ void Part::RelaseNotePos(int pos) */ void Part::KillNotePos(int pos) { - partnote[pos].status=KEY_OFF; - partnote[pos].note=-1; - partnote[pos].time=0; - partnote[pos].itemsplaying=0; - - for (int j=0;j<NUM_KIT_ITEMS;j++) { - if (partnote[pos].kititem[j].adnote!=NULL) { - delete(partnote[pos].kititem[j].adnote); - partnote[pos].kititem[j].adnote=NULL; - }; - if (partnote[pos].kititem[j].subnote!=NULL) { - delete(partnote[pos].kititem[j].subnote); - partnote[pos].kititem[j].subnote=NULL; - }; - if (partnote[pos].kititem[j].padnote!=NULL) { - delete(partnote[pos].kititem[j].padnote); - partnote[pos].kititem[j].padnote=NULL; - }; - }; - if (pos==ctl.portamento.noteusing) { - ctl.portamento.noteusing=-1; - ctl.portamento.used=0; - }; -}; + partnote[pos].status = KEY_OFF; + partnote[pos].note = -1; + partnote[pos].time = 0; + partnote[pos].itemsplaying = 0; + + for(int j = 0; j < NUM_KIT_ITEMS; j++) { + if(partnote[pos].kititem[j].adnote != NULL) { + delete (partnote[pos].kititem[j].adnote); + partnote[pos].kititem[j].adnote = NULL; + } + if(partnote[pos].kititem[j].subnote != NULL) { + delete (partnote[pos].kititem[j].subnote); + partnote[pos].kititem[j].subnote = NULL; + } + if(partnote[pos].kititem[j].padnote != NULL) { + delete (partnote[pos].kititem[j].padnote); + partnote[pos].kititem[j].padnote = NULL; + } + } + if(pos == ctl.portamento.noteusing) { + ctl.portamento.noteusing = -1; + ctl.portamento.used = 0; + } +} /* @@ -677,30 +875,34 @@ void Part::KillNotePos(int pos) */ void Part::setkeylimit(unsigned char Pkeylimit) { - this->Pkeylimit=Pkeylimit; - int keylimit=Pkeylimit; - if (keylimit==0) keylimit=POLIPHONY-5; + this->Pkeylimit = Pkeylimit; + int keylimit = Pkeylimit; + if(keylimit == 0) + keylimit = POLIPHONY - 5; //release old keys if the number of notes>keylimit - if (Ppolymode!=0) { - int notecount=0; - for (int i=0;i<POLIPHONY;i++) { - if ((partnote[i].status==KEY_PLAYING)||(partnote[i].status==KEY_RELASED_AND_SUSTAINED)) + if(Ppolymode != 0) { + int notecount = 0; + for(int i = 0; i < POLIPHONY; i++) + if((partnote[i].status == KEY_PLAYING) + || (partnote[i].status == KEY_RELASED_AND_SUSTAINED)) notecount++; - }; - int oldestnotepos=-1,maxtime=0; - if (notecount>keylimit) {//find out the oldest note - for (int i=0;i<POLIPHONY;i++) { - if ( ((partnote[i].status==KEY_PLAYING)||(partnote[i].status==KEY_RELASED_AND_SUSTAINED)) - && (partnote[i].time>maxtime)) { - maxtime=partnote[i].time; - oldestnotepos=i; - }; - }; - }; - if (oldestnotepos!=-1) RelaseNotePos(oldestnotepos); - }; -}; + ; + int oldestnotepos = -1, maxtime = 0; + if(notecount > keylimit) { //find out the oldest note + for(int i = 0; i < POLIPHONY; i++) { + if(((partnote[i].status == KEY_PLAYING) + || (partnote[i].status == KEY_RELASED_AND_SUSTAINED)) + && (partnote[i].time > maxtime)) { + maxtime = partnote[i].time; + oldestnotepos = i; + } + } + } + if(oldestnotepos != -1) + RelaseNotePos(oldestnotepos); + } +} /* @@ -708,8 +910,8 @@ void Part::setkeylimit(unsigned char Pkeylimit) */ void Part::AllNotesOff() { - killallnotes=1; -}; + killallnotes = 1; +} /* @@ -717,266 +919,287 @@ void Part::AllNotesOff() */ void Part::ComputePartSmps() { - int i,k; - int noteplay;//0 if there is nothing activated - for (int nefx=0;nefx<NUM_PART_EFX+1;nefx++) { - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - partfxinputl[nefx][i]=0.0; - partfxinputr[nefx][i]=0.0; - }; - }; - - for (k=0;k<POLIPHONY;k++) { - if (partnote[k].status==KEY_OFF) continue; - noteplay=0; + int i, k; + int noteplay; //0 if there is nothing activated + for(int nefx = 0; nefx < NUM_PART_EFX + 1; nefx++) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + partfxinputl[nefx][i] = 0.0; + partfxinputr[nefx][i] = 0.0; + } + } + + for(k = 0; k < POLIPHONY; k++) { + if(partnote[k].status == KEY_OFF) + continue; + noteplay = 0; partnote[k].time++; //get the sampledata of the note and kill it if it's finished - for (int item=0;item<partnote[k].itemsplaying;item++) { + for(int item = 0; item < partnote[k].itemsplaying; item++) { + int sendcurrenttofx = partnote[k].kititem[item].sendtoparteffect; - int sendcurrenttofx=partnote[k].kititem[item].sendtoparteffect; - - ADnote *adnote=partnote[k].kititem[item].adnote; - SUBnote *subnote=partnote[k].kititem[item].subnote; - PADnote *padnote=partnote[k].kititem[item].padnote; + ADnote *adnote = partnote[k].kititem[item].adnote; + SUBnote *subnote = partnote[k].kititem[item].subnote; + PADnote *padnote = partnote[k].kititem[item].padnote; //get from the ADnote - if (adnote!=NULL) { + if(adnote != NULL) { noteplay++; - if (adnote->ready!=0) adnote->noteout(&tmpoutl[0],&tmpoutr[0]); - else for (i=0;i<SOUND_BUFFER_SIZE;i++) { - tmpoutl[i]=0.0; - tmpoutr[i]=0.0; - }; - if (adnote->finished()!=0) { + if(adnote->ready != 0) + adnote->noteout(&tmpoutl[0], &tmpoutr[0]); + else + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tmpoutl[i] = 0.0; + tmpoutr[i] = 0.0; + } + ; + if(adnote->finished() != 0) { delete (adnote); - partnote[k].kititem[item].adnote=NULL; - }; - for (i=0;i<SOUND_BUFFER_SIZE;i++) {//add the ADnote to part(mix) - partfxinputl[sendcurrenttofx][i]+=tmpoutl[i]; - partfxinputr[sendcurrenttofx][i]+=tmpoutr[i]; - }; - }; + partnote[k].kititem[item].adnote = NULL; + } + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //add the ADnote to part(mix) + partfxinputl[sendcurrenttofx][i] += tmpoutl[i]; + partfxinputr[sendcurrenttofx][i] += tmpoutr[i]; + } + } //get from the SUBnote - if (subnote!=NULL) { + if(subnote != NULL) { noteplay++; - if (subnote->ready!=0) subnote->noteout(&tmpoutl[0],&tmpoutr[0]); - else for (i=0;i<SOUND_BUFFER_SIZE;i++) { - tmpoutl[i]=0.0; - tmpoutr[i]=0.0; - }; - - for (i=0;i<SOUND_BUFFER_SIZE;i++) {//add the SUBnote to part(mix) - partfxinputl[sendcurrenttofx][i]+=tmpoutl[i]; - partfxinputr[sendcurrenttofx][i]+=tmpoutr[i]; - }; - if (subnote->finished()!=0) { + if(subnote->ready != 0) + subnote->noteout(&tmpoutl[0], &tmpoutr[0]); + else + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tmpoutl[i] = 0.0; + tmpoutr[i] = 0.0; + } + ; + + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //add the SUBnote to part(mix) + partfxinputl[sendcurrenttofx][i] += tmpoutl[i]; + partfxinputr[sendcurrenttofx][i] += tmpoutr[i]; + } + if(subnote->finished() != 0) { delete (subnote); - partnote[k].kititem[item].subnote=NULL; - }; - }; + partnote[k].kititem[item].subnote = NULL; + } + } //get from the PADnote - if (padnote!=NULL) { + if(padnote != NULL) { noteplay++; - if (padnote->ready!=0) padnote->noteout(&tmpoutl[0],&tmpoutr[0]); - else for (i=0;i<SOUND_BUFFER_SIZE;i++) { - tmpoutl[i]=0.0; - tmpoutr[i]=0.0; - }; - if (padnote->finished()!=0) { + if(padnote->ready != 0) + padnote->noteout(&tmpoutl[0], &tmpoutr[0]); + else + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tmpoutl[i] = 0.0; + tmpoutr[i] = 0.0; + } + ; + if(padnote->finished() != 0) { delete (padnote); - partnote[k].kititem[item].padnote=NULL; - }; - for (i=0;i<SOUND_BUFFER_SIZE;i++) {//add the PADnote to part(mix) - partfxinputl[sendcurrenttofx][i]+=tmpoutl[i]; - partfxinputr[sendcurrenttofx][i]+=tmpoutr[i]; - }; - }; - - }; + partnote[k].kititem[item].padnote = NULL; + } + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //add the PADnote to part(mix) + partfxinputl[sendcurrenttofx][i] += tmpoutl[i]; + partfxinputr[sendcurrenttofx][i] += tmpoutr[i]; + } + } + } //Kill note if there is no synth on that note - if (noteplay==0) KillNotePos(k); - }; + if(noteplay == 0) + KillNotePos(k); + } //Apply part's effects and mix them - for (int nefx=0;nefx<NUM_PART_EFX;nefx++) { - if (!Pefxbypass[nefx]) { - partefx[nefx]->out(partfxinputl[nefx],partfxinputr[nefx]); - if (Pefxroute[nefx]==2) { - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - partfxinputl[nefx+1][i]+=partefx[nefx]->efxoutl[i]; - partfxinputr[nefx+1][i]+=partefx[nefx]->efxoutr[i]; - }; - }; - }; - int routeto=((Pefxroute[nefx]==0) ? nefx+1 : NUM_PART_EFX); - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - partfxinputl[routeto][i]+=partfxinputl[nefx][i]; - partfxinputr[routeto][i]+=partfxinputr[nefx][i]; - }; - - }; - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - partoutl[i]=partfxinputl[NUM_PART_EFX][i]; - partoutr[i]=partfxinputr[NUM_PART_EFX][i]; - }; + for(int nefx = 0; nefx < NUM_PART_EFX; nefx++) { + if(!Pefxbypass[nefx]) { + partefx[nefx]->out(partfxinputl[nefx], partfxinputr[nefx]); + if(Pefxroute[nefx] == 2) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + partfxinputl[nefx + 1][i] += partefx[nefx]->efxoutl[i]; + partfxinputr[nefx + 1][i] += partefx[nefx]->efxoutr[i]; + } + } + } + int routeto = ((Pefxroute[nefx] == 0) ? nefx + 1 : NUM_PART_EFX); + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + partfxinputl[routeto][i] += partfxinputl[nefx][i]; + partfxinputr[routeto][i] += partfxinputr[nefx][i]; + } + } + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + partoutl[i] = partfxinputl[NUM_PART_EFX][i]; + partoutr[i] = partfxinputr[NUM_PART_EFX][i]; + } //Kill All Notes if killallnotes!=0 - if (killallnotes!=0) { - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - REALTYPE tmp=(SOUND_BUFFER_SIZE-i)/(REALTYPE) SOUND_BUFFER_SIZE; - partoutl[i]*=tmp; - partoutr[i]*=tmp; - tmpoutl[i]=0.0; - tmpoutr[i]=0.0; - }; - for (int k=0;k<POLIPHONY;k++) KillNotePos(k); - killallnotes=0; - for (int nefx=0;nefx<NUM_PART_EFX;nefx++) { + if(killallnotes != 0) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + REALTYPE tmp = + (SOUND_BUFFER_SIZE - i) / (REALTYPE) SOUND_BUFFER_SIZE; + partoutl[i] *= tmp; + partoutr[i] *= tmp; + tmpoutl[i] = 0.0; + tmpoutr[i] = 0.0; + } + for(int k = 0; k < POLIPHONY; k++) + KillNotePos(k); + killallnotes = 0; + for(int nefx = 0; nefx < NUM_PART_EFX; nefx++) partefx[nefx]->cleanup(); - }; - }; + ; + } ctl.updateportamento(); -}; +} /* * Parameter control */ void Part::setPvolume(char Pvolume_) { - Pvolume=Pvolume_; - volume=dB2rap((Pvolume-96.0)/96.0*40.0)*ctl.expression.relvolume; -}; + Pvolume = Pvolume_; + volume = dB2rap((Pvolume - 96.0) / 96.0 * 40.0) * ctl.expression.relvolume; +} void Part::setPpanning(char Ppanning_) { - Ppanning=Ppanning_; - panning=Ppanning/127.0+ctl.panning.pan; - if (panning<0.0) panning=0.0; - else if (panning>1.0) panning=1.0; - -}; + Ppanning = Ppanning_; + panning = Ppanning / 127.0 + ctl.panning.pan; + if(panning < 0.0) + panning = 0.0; + else + if(panning > 1.0) + panning = 1.0; +} /* * Enable or disable a kit item */ -void Part::setkititemstatus(int kititem,int Penabled_) +void Part::setkititemstatus(int kititem, int Penabled_) { - if ((kititem==0)&&(kititem>=NUM_KIT_ITEMS)) return;//nonexistent kit item and the first kit item is always enabled - kit[kititem].Penabled=Penabled_; - - bool resetallnotes=false; - if (Penabled_==0) { - if (kit[kititem].adpars!=NULL) delete (kit[kititem].adpars); - if (kit[kititem].subpars!=NULL) delete (kit[kititem].subpars); - if (kit[kititem].padpars!=NULL) { + if((kititem == 0) && (kititem >= NUM_KIT_ITEMS)) + return; //nonexistent kit item and the first kit item is always enabled + kit[kititem].Penabled = Penabled_; + + bool resetallnotes = false; + if(Penabled_ == 0) { + if(kit[kititem].adpars != NULL) + delete (kit[kititem].adpars); + if(kit[kititem].subpars != NULL) + delete (kit[kititem].subpars); + if(kit[kititem].padpars != NULL) { delete (kit[kititem].padpars); - resetallnotes=true; - }; - kit[kititem].adpars=NULL; - kit[kititem].subpars=NULL; - kit[kititem].padpars=NULL; - kit[kititem].Pname[0]='\0'; - } else { - if (kit[kititem].adpars==NULL) kit[kititem].adpars=new ADnoteParameters(fft); - if (kit[kititem].subpars==NULL) kit[kititem].subpars=new SUBnoteParameters(); - if (kit[kititem].padpars==NULL) kit[kititem].padpars=new PADnoteParameters(fft,mutex); - }; + resetallnotes = true; + } + kit[kititem].adpars = NULL; + kit[kititem].subpars = NULL; + kit[kititem].padpars = NULL; + kit[kititem].Pname[0] = '\0'; + } + else { + if(kit[kititem].adpars == NULL) + kit[kititem].adpars = new ADnoteParameters(fft); + if(kit[kititem].subpars == NULL) + kit[kititem].subpars = new SUBnoteParameters(); + if(kit[kititem].padpars == NULL) + kit[kititem].padpars = new PADnoteParameters(fft, mutex); + } - if (resetallnotes) for (int k=0;k<POLIPHONY;k++) KillNotePos(k); -}; + if(resetallnotes) + for(int k = 0; k < POLIPHONY; k++) + KillNotePos(k); +} void Part::add2XMLinstrument(XMLwrapper *xml) { xml->beginbranch("INFO"); - xml->addparstr("name",(char *)Pname); - xml->addparstr("author",(char *)info.Pauthor); - xml->addparstr("comments",(char *)info.Pcomments); - xml->addpar("type",info.Ptype); + xml->addparstr("name", (char *)Pname); + xml->addparstr("author", (char *)info.Pauthor); + xml->addparstr("comments", (char *)info.Pcomments); + xml->addpar("type", info.Ptype); xml->endbranch(); xml->beginbranch("INSTRUMENT_KIT"); - xml->addpar("kit_mode",Pkitmode); - xml->addparbool("drum_mode",Pdrummode); + xml->addpar("kit_mode", Pkitmode); + xml->addparbool("drum_mode", Pdrummode); - for (int i=0;i<NUM_KIT_ITEMS;i++) { - xml->beginbranch("INSTRUMENT_KIT_ITEM",i); - xml->addparbool("enabled",kit[i].Penabled); - if (kit[i].Penabled!=0) { - xml->addparstr("name",(char *)kit[i].Pname); + for(int i = 0; i < NUM_KIT_ITEMS; i++) { + xml->beginbranch("INSTRUMENT_KIT_ITEM", i); + xml->addparbool("enabled", kit[i].Penabled); + if(kit[i].Penabled != 0) { + xml->addparstr("name", (char *)kit[i].Pname); - xml->addparbool("muted",kit[i].Pmuted); - xml->addpar("min_key",kit[i].Pminkey); - xml->addpar("max_key",kit[i].Pmaxkey); + xml->addparbool("muted", kit[i].Pmuted); + xml->addpar("min_key", kit[i].Pminkey); + xml->addpar("max_key", kit[i].Pmaxkey); - xml->addpar("send_to_instrument_effect",kit[i].Psendtoparteffect); + xml->addpar("send_to_instrument_effect", kit[i].Psendtoparteffect); - xml->addparbool("add_enabled",kit[i].Padenabled); - if ((kit[i].Padenabled!=0)&&(kit[i].adpars!=NULL)) { + xml->addparbool("add_enabled", kit[i].Padenabled); + if((kit[i].Padenabled != 0) && (kit[i].adpars != NULL)) { xml->beginbranch("ADD_SYNTH_PARAMETERS"); kit[i].adpars->add2XML(xml); xml->endbranch(); - }; + } - xml->addparbool("sub_enabled",kit[i].Psubenabled); - if ((kit[i].Psubenabled!=0)&&(kit[i].subpars!=NULL)) { + xml->addparbool("sub_enabled", kit[i].Psubenabled); + if((kit[i].Psubenabled != 0) && (kit[i].subpars != NULL)) { xml->beginbranch("SUB_SYNTH_PARAMETERS"); kit[i].subpars->add2XML(xml); xml->endbranch(); - }; + } - xml->addparbool("pad_enabled",kit[i].Ppadenabled); - if ((kit[i].Ppadenabled!=0)&&(kit[i].padpars!=NULL)) { + xml->addparbool("pad_enabled", kit[i].Ppadenabled); + if((kit[i].Ppadenabled != 0) && (kit[i].padpars != NULL)) { xml->beginbranch("PAD_SYNTH_PARAMETERS"); kit[i].padpars->add2XML(xml); xml->endbranch(); - }; - - }; + } + } xml->endbranch(); - }; + } xml->endbranch(); xml->beginbranch("INSTRUMENT_EFFECTS"); - for (int nefx=0;nefx<NUM_PART_EFX;nefx++) { - xml->beginbranch("INSTRUMENT_EFFECT",nefx); + for(int nefx = 0; nefx < NUM_PART_EFX; nefx++) { + xml->beginbranch("INSTRUMENT_EFFECT", nefx); xml->beginbranch("EFFECT"); partefx[nefx]->add2XML(xml); xml->endbranch(); - xml->addpar("route",Pefxroute[nefx]); - partefx[nefx]->setdryonly(Pefxroute[nefx]==2); - xml->addparbool("bypass",Pefxbypass[nefx]); + xml->addpar("route", Pefxroute[nefx]); + partefx[nefx]->setdryonly(Pefxroute[nefx] == 2); + xml->addparbool("bypass", Pefxbypass[nefx]); xml->endbranch(); - }; + } xml->endbranch(); -}; +} void Part::add2XML(XMLwrapper *xml) { //parameters - xml->addparbool("enabled",Penabled); - if ((Penabled==0)&&(xml->minimal)) return; + xml->addparbool("enabled", Penabled); + if((Penabled == 0) && (xml->minimal)) + return; - xml->addpar("volume",Pvolume); - xml->addpar("panning",Ppanning); + xml->addpar("volume", Pvolume); + xml->addpar("panning", Ppanning); - xml->addpar("min_key",Pminkey); - xml->addpar("max_key",Pmaxkey); - xml->addpar("key_shift",Pkeyshift); - xml->addpar("rcv_chn",Prcvchn); + xml->addpar("min_key", Pminkey); + xml->addpar("max_key", Pmaxkey); + xml->addpar("key_shift", Pkeyshift); + xml->addpar("rcv_chn", Prcvchn); - xml->addpar("velocity_sensing",Pvelsns); - xml->addpar("velocity_offset",Pveloffs); + xml->addpar("velocity_sensing", Pvelsns); + xml->addpar("velocity_offset", Pveloffs); - xml->addparbool("note_on",Pnoteon); - xml->addparbool("poly_mode",Ppolymode); - xml->addpar("legato_mode",Plegatomode); - xml->addpar("key_limit",Pkeylimit); + xml->addparbool("note_on", Pnoteon); + xml->addparbool("poly_mode", Ppolymode); + xml->addpar("legato_mode", Plegatomode); + xml->addpar("key_limit", Pkeylimit); xml->beginbranch("INSTRUMENT"); add2XMLinstrument(xml); @@ -985,154 +1208,163 @@ void Part::add2XML(XMLwrapper *xml) xml->beginbranch("CONTROLLER"); ctl.add2XML(xml); xml->endbranch(); -}; +} int Part::saveXML(char *filename) { XMLwrapper *xml; - xml=new XMLwrapper(); + xml = new XMLwrapper(); xml->beginbranch("INSTRUMENT"); add2XMLinstrument(xml); xml->endbranch(); - int result=xml->saveXMLfile(filename); + int result = xml->saveXMLfile(filename); delete (xml); - return(result); -}; + return result; +} int Part::loadXMLinstrument(const char *filename) { - XMLwrapper *xml=new XMLwrapper(); - if (xml->loadXMLfile(filename)<0) { - delete(xml); - return(-1); - }; + XMLwrapper *xml = new XMLwrapper(); + if(xml->loadXMLfile(filename) < 0) { + delete (xml); + return -1; + } - if (xml->enterbranch("INSTRUMENT")==0) return(-10); + if(xml->enterbranch("INSTRUMENT") == 0) + return -10; getfromXMLinstrument(xml); xml->exitbranch(); - delete(xml); - return(0); -}; + delete (xml); + return 0; +} void Part::applyparameters() { - for (int n=0;n<NUM_KIT_ITEMS;n++) { - if ((kit[n].padpars!=NULL)&&(kit[n].Ppadenabled!=0)) kit[n].padpars->applyparameters(true); - }; -}; + for(int n = 0; n < NUM_KIT_ITEMS; n++) + if((kit[n].padpars != NULL) && (kit[n].Ppadenabled != 0)) + kit[n].padpars->applyparameters(true); + ; +} void Part::getfromXMLinstrument(XMLwrapper *xml) { - if (xml->enterbranch("INFO")) { - xml->getparstr("name",(char *)Pname,PART_MAX_NAME_LEN); - xml->getparstr("author",(char *)info.Pauthor,MAX_INFO_TEXT_SIZE); - xml->getparstr("comments",(char *)info.Pcomments,MAX_INFO_TEXT_SIZE); - info.Ptype=xml->getpar("type",info.Ptype,0,16); + if(xml->enterbranch("INFO")) { + xml->getparstr("name", (char *)Pname, PART_MAX_NAME_LEN); + xml->getparstr("author", (char *)info.Pauthor, MAX_INFO_TEXT_SIZE); + xml->getparstr("comments", (char *)info.Pcomments, MAX_INFO_TEXT_SIZE); + info.Ptype = xml->getpar("type", info.Ptype, 0, 16); xml->exitbranch(); - }; + } - if (xml->enterbranch("INSTRUMENT_KIT")) { - Pkitmode=xml->getpar127("kit_mode",Pkitmode); - Pdrummode=xml->getparbool("drum_mode",Pdrummode); + if(xml->enterbranch("INSTRUMENT_KIT")) { + Pkitmode = xml->getpar127("kit_mode", Pkitmode); + Pdrummode = xml->getparbool("drum_mode", Pdrummode); - setkititemstatus(0,0); - for (int i=0;i<NUM_KIT_ITEMS;i++) { - if (xml->enterbranch("INSTRUMENT_KIT_ITEM",i)==0) continue; - setkititemstatus(i,xml->getparbool("enabled",kit[i].Penabled)); - if (kit[i].Penabled==0) { + setkititemstatus(0, 0); + for(int i = 0; i < NUM_KIT_ITEMS; i++) { + if(xml->enterbranch("INSTRUMENT_KIT_ITEM", i) == 0) + continue; + setkititemstatus(i, xml->getparbool("enabled", kit[i].Penabled)); + if(kit[i].Penabled == 0) { xml->exitbranch(); continue; - }; + } - xml->getparstr("name",(char *)kit[i].Pname,PART_MAX_NAME_LEN); + xml->getparstr("name", (char *)kit[i].Pname, PART_MAX_NAME_LEN); - kit[i].Pmuted=xml->getparbool("muted",kit[i].Pmuted); - kit[i].Pminkey=xml->getpar127("min_key",kit[i].Pminkey); - kit[i].Pmaxkey=xml->getpar127("max_key",kit[i].Pmaxkey); + kit[i].Pmuted = xml->getparbool("muted", kit[i].Pmuted); + kit[i].Pminkey = xml->getpar127("min_key", kit[i].Pminkey); + kit[i].Pmaxkey = xml->getpar127("max_key", kit[i].Pmaxkey); - kit[i].Psendtoparteffect=xml->getpar127("send_to_instrument_effect",kit[i].Psendtoparteffect); + kit[i].Psendtoparteffect = xml->getpar127( + "send_to_instrument_effect", + kit[i].Psendtoparteffect); - kit[i].Padenabled=xml->getparbool("add_enabled",kit[i].Padenabled); - if (xml->enterbranch("ADD_SYNTH_PARAMETERS")) { + kit[i].Padenabled = xml->getparbool("add_enabled", + kit[i].Padenabled); + if(xml->enterbranch("ADD_SYNTH_PARAMETERS")) { kit[i].adpars->getfromXML(xml); xml->exitbranch(); - }; + } - kit[i].Psubenabled=xml->getparbool("sub_enabled",kit[i].Psubenabled); - if (xml->enterbranch("SUB_SYNTH_PARAMETERS")) { + kit[i].Psubenabled = xml->getparbool("sub_enabled", + kit[i].Psubenabled); + if(xml->enterbranch("SUB_SYNTH_PARAMETERS")) { kit[i].subpars->getfromXML(xml); xml->exitbranch(); - }; + } - kit[i].Ppadenabled=xml->getparbool("pad_enabled",kit[i].Ppadenabled); - if (xml->enterbranch("PAD_SYNTH_PARAMETERS")) { + kit[i].Ppadenabled = xml->getparbool("pad_enabled", + kit[i].Ppadenabled); + if(xml->enterbranch("PAD_SYNTH_PARAMETERS")) { kit[i].padpars->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("INSTRUMENT_EFFECTS")) { - for (int nefx=0;nefx<NUM_PART_EFX;nefx++) { - if (xml->enterbranch("INSTRUMENT_EFFECT",nefx)==0) continue; - if (xml->enterbranch("EFFECT")) { + if(xml->enterbranch("INSTRUMENT_EFFECTS")) { + for(int nefx = 0; nefx < NUM_PART_EFX; nefx++) { + if(xml->enterbranch("INSTRUMENT_EFFECT", nefx) == 0) + continue; + if(xml->enterbranch("EFFECT")) { partefx[nefx]->getfromXML(xml); xml->exitbranch(); - }; + } - Pefxroute[nefx]=xml->getpar("route",Pefxroute[nefx],0,NUM_PART_EFX); - partefx[nefx]->setdryonly(Pefxroute[nefx]==2); - Pefxbypass[nefx]=xml->getparbool("bypass",Pefxbypass[nefx]); + Pefxroute[nefx] = xml->getpar("route", + Pefxroute[nefx], + 0, + NUM_PART_EFX); + partefx[nefx]->setdryonly(Pefxroute[nefx] == 2); + Pefxbypass[nefx] = xml->getparbool("bypass", Pefxbypass[nefx]); xml->exitbranch(); - }; + } xml->exitbranch(); - }; - -}; + } +} void Part::getfromXML(XMLwrapper *xml) { - Penabled=xml->getparbool("enabled",Penabled); + Penabled = xml->getparbool("enabled", Penabled); - setPvolume(xml->getpar127("volume",Pvolume)); - setPpanning(xml->getpar127("panning",Ppanning)); + setPvolume(xml->getpar127("volume", Pvolume)); + setPpanning(xml->getpar127("panning", Ppanning)); - Pminkey=xml->getpar127("min_key",Pminkey); - Pmaxkey=xml->getpar127("max_key",Pmaxkey); - Pkeyshift=xml->getpar127("key_shift",Pkeyshift); - Prcvchn=xml->getpar127("rcv_chn",Prcvchn); + Pminkey = xml->getpar127("min_key", Pminkey); + Pmaxkey = xml->getpar127("max_key", Pmaxkey); + Pkeyshift = xml->getpar127("key_shift", Pkeyshift); + Prcvchn = xml->getpar127("rcv_chn", Prcvchn); - Pvelsns=xml->getpar127("velocity_sensing",Pvelsns); - Pveloffs=xml->getpar127("velocity_offset",Pveloffs); + Pvelsns = xml->getpar127("velocity_sensing", Pvelsns); + Pveloffs = xml->getpar127("velocity_offset", Pveloffs); - Pnoteon=xml->getparbool("note_on",Pnoteon); - Ppolymode=xml->getparbool("poly_mode",Ppolymode); - Plegatomode=xml->getparbool("legato_mode",Plegatomode);//older versions - if (!Plegatomode) Plegatomode=xml->getpar127("legato_mode",Plegatomode); - Pkeylimit=xml->getpar127("key_limit",Pkeylimit); + Pnoteon = xml->getparbool("note_on", Pnoteon); + Ppolymode = xml->getparbool("poly_mode", Ppolymode); + Plegatomode = xml->getparbool("legato_mode", Plegatomode); //older versions + if(!Plegatomode) + Plegatomode = xml->getpar127("legato_mode", Plegatomode); + Pkeylimit = xml->getpar127("key_limit", Pkeylimit); - if (xml->enterbranch("INSTRUMENT")) { + if(xml->enterbranch("INSTRUMENT")) { getfromXMLinstrument(xml); xml->exitbranch(); - }; + } - if (xml->enterbranch("CONTROLLER")) { + if(xml->enterbranch("CONTROLLER")) { ctl.getfromXML(xml); xml->exitbranch(); - }; - -}; - - + } +} diff --git a/src/Misc/Part.h b/src/Misc/Part.h @@ -43,159 +43,163 @@ /** Part implementation*/ class Part { + public: + /**Constructor + * @param microtonal_ Pointer to the microtonal object + * @param fft_ Pointer to the FFTwrapper + * @param mutex_ Pointer to the master pthread_mutex_t*/ + Part(Microtonal *microtonal_, FFTwrapper *fft_, pthread_mutex_t *mutex_); + /**Destructor*/ + ~Part(); -public: - /**Constructor - * @param microtonal_ Pointer to the microtonal object - * @param fft_ Pointer to the FFTwrapper - * @param mutex_ Pointer to the master pthread_mutex_t*/ - Part(Microtonal *microtonal_,FFTwrapper *fft_,pthread_mutex_t *mutex_); - /**Destructor*/ - ~Part(); + // Midi commands implemented + void NoteOn(unsigned char note, + unsigned char velocity, + int masterkeyshift); + void NoteOff(unsigned char note); + void AllNotesOff(); //panic + void SetController(unsigned int type, int par); + void RelaseSustainedKeys(); //this is called when the sustain pedal is relased + void RelaseAllKeys(); //this is called on AllNotesOff controller - // Midi commands implemented - void NoteOn(unsigned char note,unsigned char velocity,int masterkeyshift); - void NoteOff(unsigned char note); - void AllNotesOff();//panic - void SetController(unsigned int type,int par); - void RelaseSustainedKeys();//this is called when the sustain pedal is relased - void RelaseAllKeys();//this is called on AllNotesOff controller + /* The synthesizer part output */ + void ComputePartSmps(); //Part output - /* The synthesizer part output */ - void ComputePartSmps();//Part output + //instrumentonly: 0 - save all, 1 - save only instrumnet, 2 - save only instrument without the name(used in bank) - //instrumentonly: 0 - save all, 1 - save only instrumnet, 2 - save only instrument without the name(used in bank) + //saves the instrument settings to a XML file + //returns 0 for ok or <0 if there is an error + int saveXML(char *filename); + int loadXMLinstrument(const char *filename); - //saves the instrument settings to a XML file - //returns 0 for ok or <0 if there is an error - int saveXML(char *filename); - int loadXMLinstrument(const char *filename); + void add2XML(XMLwrapper *xml); + void add2XMLinstrument(XMLwrapper *xml); - void add2XML(XMLwrapper *xml); - void add2XMLinstrument(XMLwrapper *xml); + void defaults(); + void defaultsinstrument(); - void defaults(); - void defaultsinstrument(); + void applyparameters(); - void applyparameters(); + void getfromXML(XMLwrapper *xml); + void getfromXMLinstrument(XMLwrapper *xml); - void getfromXML(XMLwrapper *xml); - void getfromXMLinstrument(XMLwrapper *xml); - - void cleanup(); + void cleanup(); // ADnoteParameters *ADPartParameters; // SUBnoteParameters *SUBPartParameters; - //the part's kit - struct { - unsigned char Penabled,Pmuted,Pminkey,Pmaxkey; - unsigned char *Pname; - unsigned char Padenabled,Psubenabled,Ppadenabled; - unsigned char Psendtoparteffect; - ADnoteParameters *adpars; - SUBnoteParameters *subpars; - PADnoteParameters *padpars; - } kit[NUM_KIT_ITEMS]; - - - //Part parameters - void setkeylimit(unsigned char Pkeylimit); - void setkititemstatus(int kititem,int Penabled_); - - unsigned char Penabled;/**<if the part is enabled*/ - unsigned char Pvolume;/**<part volume*/ - unsigned char Pminkey;/**<the minimum key that the part receives noteon messages*/ - unsigned char Pmaxkey;//the maximum key that the part receives noteon messages - void setPvolume(char Pvolume); - unsigned char Pkeyshift;//Part keyshift - unsigned char Prcvchn;//from what midi channel it receive commnads - unsigned char Ppanning;//part panning - void setPpanning(char Ppanning); - unsigned char Pvelsns;//velocity sensing (amplitude velocity scale) - unsigned char Pveloffs;//velocity offset - unsigned char Pnoteon;//if the part receives NoteOn messages - unsigned char Pkitmode;//if the kitmode is enabled - unsigned char Pdrummode;//if all keys are mapped and the system is 12tET (used for drums) - - unsigned char Ppolymode;//Part mode - 0=monophonic , 1=polyphonic - unsigned char Plegatomode;// 0=normal, 1=legato - unsigned char Pkeylimit;//how many keys are alowed to be played same time (0=off), the older will be relased - - unsigned char *Pname; //name of the instrument - struct {//instrument additional information - unsigned char Ptype; - unsigned char Pauthor[MAX_INFO_TEXT_SIZE+1]; - unsigned char Pcomments[MAX_INFO_TEXT_SIZE+1]; - } info; - - - REALTYPE *partoutl;//Left channel output of the part - REALTYPE *partoutr;//Right channel output of the part - - REALTYPE *partfxinputl[NUM_PART_EFX+1],*partfxinputr[NUM_PART_EFX+1];//Left and right signal that pass thru part effects; partfxinput l/r [NUM_PART_EFX] is for "no effect" buffer - - enum NoteStatus {KEY_OFF,KEY_PLAYING,KEY_RELASED_AND_SUSTAINED,KEY_RELASED}; - - REALTYPE volume,oldvolumel,oldvolumer;//this is applied by Master - REALTYPE panning;//this is applied by Master, too - - Controller ctl;//Part controllers - - EffectMgr *partefx[NUM_PART_EFX];//insertion part effects (they are part of the instrument) - unsigned char Pefxroute[NUM_PART_EFX];//how the effect's output is routed(to next effect/to out) - bool Pefxbypass[NUM_PART_EFX];//if the effects are bypassed - - - pthread_mutex_t *mutex; - - int lastnote; - -private: - void KillNotePos(int pos); - void RelaseNotePos(int pos); - void MonoMemRenote(); // MonoMem stuff. - - int killallnotes;//is set to 1 if I want to kill all notes - - struct PartNotes { - NoteStatus status; - int note;//if there is no note playing, the "note"=-1 - int itemsplaying; + //the part's kit + struct { + unsigned char Penabled, Pmuted, Pminkey, Pmaxkey; + unsigned char *Pname; + unsigned char Padenabled, Psubenabled, Ppadenabled; + unsigned char Psendtoparteffect; + ADnoteParameters *adpars; + SUBnoteParameters *subpars; + PADnoteParameters *padpars; + } kit[NUM_KIT_ITEMS]; + + + //Part parameters + void setkeylimit(unsigned char Pkeylimit); + void setkititemstatus(int kititem, int Penabled_); + + unsigned char Penabled; /**<if the part is enabled*/ + unsigned char Pvolume; /**<part volume*/ + unsigned char Pminkey; /**<the minimum key that the part receives noteon messages*/ + unsigned char Pmaxkey; //the maximum key that the part receives noteon messages + void setPvolume(char Pvolume); + unsigned char Pkeyshift; //Part keyshift + unsigned char Prcvchn; //from what midi channel it receive commnads + unsigned char Ppanning; //part panning + void setPpanning(char Ppanning); + unsigned char Pvelsns; //velocity sensing (amplitude velocity scale) + unsigned char Pveloffs; //velocity offset + unsigned char Pnoteon; //if the part receives NoteOn messages + unsigned char Pkitmode; //if the kitmode is enabled + unsigned char Pdrummode; //if all keys are mapped and the system is 12tET (used for drums) + + unsigned char Ppolymode; //Part mode - 0=monophonic , 1=polyphonic + unsigned char Plegatomode; // 0=normal, 1=legato + unsigned char Pkeylimit; //how many keys are alowed to be played same time (0=off), the older will be relased + + unsigned char *Pname; //name of the instrument + struct { //instrument additional information + unsigned char Ptype; + unsigned char Pauthor[MAX_INFO_TEXT_SIZE + 1]; + unsigned char Pcomments[MAX_INFO_TEXT_SIZE + 1]; + } info; + + + REALTYPE *partoutl; //Left channel output of the part + REALTYPE *partoutr; //Right channel output of the part + + REALTYPE *partfxinputl[NUM_PART_EFX + 1], + *partfxinputr[NUM_PART_EFX + 1]; //Left and right signal that pass thru part effects; partfxinput l/r [NUM_PART_EFX] is for "no effect" buffer + + enum NoteStatus { + KEY_OFF, KEY_PLAYING, KEY_RELASED_AND_SUSTAINED, KEY_RELASED + }; + + REALTYPE volume, oldvolumel, oldvolumer; //this is applied by Master + REALTYPE panning; //this is applied by Master, too + + Controller ctl; //Part controllers + + EffectMgr *partefx[NUM_PART_EFX]; //insertion part effects (they are part of the instrument) + unsigned char Pefxroute[NUM_PART_EFX]; //how the effect's output is routed(to next effect/to out) + bool Pefxbypass[NUM_PART_EFX]; //if the effects are bypassed + + + pthread_mutex_t *mutex; + + int lastnote; + + private: + void KillNotePos(int pos); + void RelaseNotePos(int pos); + void MonoMemRenote(); // MonoMem stuff. + + int killallnotes; //is set to 1 if I want to kill all notes + + struct PartNotes { + NoteStatus status; + int note; //if there is no note playing, the "note"=-1 + int itemsplaying; + struct { + ADnote *adnote; + SUBnote *subnote; + PADnote *padnote; + int sendtoparteffect; + } kititem[NUM_KIT_ITEMS]; + int time; + }; + + int lastpos, lastposb; // To keep track of previously used pos and posb. + bool lastlegatomodevalid; // To keep track of previous legatomodevalid. + + // MonoMem stuff + std::list<unsigned char> monomemnotes; // A list to remember held notes. struct { - ADnote *adnote; - SUBnote *subnote; - PADnote *padnote; - int sendtoparteffect; - } kititem[NUM_KIT_ITEMS]; - int time; - }; - - int lastpos, lastposb; // To keep track of previously used pos and posb. - bool lastlegatomodevalid; // To keep track of previous legatomodevalid. - - // MonoMem stuff - std::list<unsigned char> monomemnotes; // A list to remember held notes. - struct { - unsigned char velocity; - int mkeyshift;// I'm not sure masterkeyshift should be remembered. - } monomem[256]; /* 256 is to cover all possible note values. - monomem[] is used in conjunction with the list to - store the velocity and masterkeyshift values of a - given note (the list only store note values). - For example 'monomem[note].velocity' would be the - velocity value of the note 'note'. - */ - - PartNotes partnote[POLIPHONY]; - - REALTYPE *tmpoutl;//used to get the note - REALTYPE *tmpoutr; - - REALTYPE oldfreq;//this is used for portamento - Microtonal *microtonal; - FFTwrapper *fft; + unsigned char velocity; + int mkeyshift; // I'm not sure masterkeyshift should be remembered. + } monomem[256]; /* 256 is to cover all possible note values. + monomem[] is used in conjunction with the list to + store the velocity and masterkeyshift values of a + given note (the list only store note values). + For example 'monomem[note].velocity' would be the + velocity value of the note 'note'. + */ + + PartNotes partnote[POLIPHONY]; + + REALTYPE *tmpoutl; //used to get the note + REALTYPE *tmpoutr; + + REALTYPE oldfreq; //this is used for portamento + Microtonal *microtonal; + FFTwrapper *fft; }; #endif diff --git a/src/Misc/Stereo.cpp b/src/Misc/Stereo.cpp @@ -19,19 +19,20 @@ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -template <class T> +template<class T> Stereo<T>::Stereo(const T &left, const T &right) - :leftChannel(left),rightChannel(right) + :leftChannel(left), rightChannel(right) {} -template <class T> +template<class T> Stereo<T>::Stereo(const T &val) - :leftChannel(val),rightChannel(val) + :leftChannel(val), rightChannel(val) {} -template <class T> -void Stereo<T>::operator=(const Stereo<T> & nstr) +template<class T> +void Stereo<T>::operator=(const Stereo<T> &nstr) { - leftChannel=nstr.leftChannel; - rightChannel=nstr.rightChannel; + leftChannel = nstr.leftChannel; + rightChannel = nstr.rightChannel; } + diff --git a/src/Misc/Stereo.h b/src/Misc/Stereo.h @@ -21,46 +21,45 @@ #ifndef STEREO_H #define STEREO_H -template <class T> +template<class T> class Stereo { -public: - Stereo(const T &left,const T &right); + public: + Stereo(const T &left, const T &right); - /**Initializes Stereo with left and right set to val - * @param val the value for both channels*/ - Stereo(const T &val); - ~Stereo() {}; - - void operator=(const Stereo<T> &smp); - T &left() { - return leftChannel; - }; - T &right() { - return rightChannel; - }; - T &l() { - return leftChannel; - }; - T &r() { - return rightChannel; - }; - const T &left()const { - return leftChannel; - }; - const T &right()const { - return rightChannel; - }; - const T &l()const { - return leftChannel; - }; - const T &r()const { - return rightChannel; - }; -private: - T leftChannel; - T rightChannel; + /**Initializes Stereo with left and right set to val + * @param val the value for both channels*/ + Stereo(const T &val); + ~Stereo() {} + void operator=(const Stereo<T> &smp); + T &left() { + return leftChannel; + } + T &right() { + return rightChannel; + } + T &l() { + return leftChannel; + } + T &r() { + return rightChannel; + } + const T &left() const { + return leftChannel; + } + const T &right() const { + return rightChannel; + } + const T &l() const { + return leftChannel; + } + const T &r() const { + return rightChannel; + } + private: + T leftChannel; + T rightChannel; }; #include "Stereo.cpp" #endif diff --git a/src/Misc/Util.cpp b/src/Misc/Util.cpp @@ -31,76 +31,85 @@ #include <errno.h> #include <string.h> -int SAMPLE_RATE=44100; -int SOUND_BUFFER_SIZE=256; -int OSCIL_SIZE=1024; +int SAMPLE_RATE = 44100; +int SOUND_BUFFER_SIZE = 256; +int OSCIL_SIZE = 1024; -Config config; +Config config; REALTYPE *denormalkillbuf; /* * Transform the velocity according the scaling parameter (velocity sensing) */ -REALTYPE VelF(REALTYPE velocity,unsigned char scaling) +REALTYPE VelF(REALTYPE velocity, unsigned char scaling) { REALTYPE x; - x=pow(VELOCITY_MAX_SCALE,(64.0-scaling)/64.0); - if ((scaling==127)||(velocity>0.99)) return(1.0); - else return(pow(velocity,x)); -}; + x = pow(VELOCITY_MAX_SCALE, (64.0 - scaling) / 64.0); + if((scaling == 127) || (velocity > 0.99)) + return 1.0; + else + return pow(velocity, x); +} /* * Get the detune in cents */ -REALTYPE getdetune(unsigned char type,unsigned short int coarsedetune,unsigned short int finedetune) +REALTYPE getdetune(unsigned char type, + unsigned short int coarsedetune, + unsigned short int finedetune) { - REALTYPE det=0.0,octdet=0.0,cdet=0.0,findet=0.0; + REALTYPE det = 0.0, octdet = 0.0, cdet = 0.0, findet = 0.0; //Get Octave - int octave=coarsedetune/1024; - if (octave>=8) octave-=16; - octdet=octave*1200.0; + int octave = coarsedetune / 1024; + if(octave >= 8) + octave -= 16; + octdet = octave * 1200.0; //Coarse and fine detune - int cdetune=coarsedetune%1024; - if (cdetune>512) cdetune-=1024; + int cdetune = coarsedetune % 1024; + if(cdetune > 512) + cdetune -= 1024; - int fdetune=finedetune-8192; + int fdetune = finedetune - 8192; - switch (type) { + switch(type) { // case 1: is used for the default (see below) case 2: - cdet=fabs(cdetune*10.0); - findet=fabs(fdetune/8192.0)*10.0; + cdet = fabs(cdetune * 10.0); + findet = fabs(fdetune / 8192.0) * 10.0; break; case 3: - cdet=fabs(cdetune*100); - findet=pow(10,fabs(fdetune/8192.0)*3.0)/10.0-0.1; + cdet = fabs(cdetune * 100); + findet = pow(10, fabs(fdetune / 8192.0) * 3.0) / 10.0 - 0.1; break; case 4: - cdet=fabs(cdetune*701.95500087);//perfect fifth - findet=(pow(2,fabs(fdetune/8192.0)*12.0)-1.0)/4095*1200; + cdet = fabs(cdetune * 701.95500087); //perfect fifth + findet = (pow(2, fabs(fdetune / 8192.0) * 12.0) - 1.0) / 4095 * 1200; break; - //case ...: need to update N_DETUNE_TYPES, if you'll add more + //case ...: need to update N_DETUNE_TYPES, if you'll add more default: - cdet=fabs(cdetune*50.0); - findet=fabs(fdetune/8192.0)*35.0;//almost like "Paul's Sound Designer 2" + cdet = fabs(cdetune * 50.0); + findet = fabs(fdetune / 8192.0) * 35.0; //almost like "Paul's Sound Designer 2" break; - }; - if (finedetune<8192) findet=-findet; - if (cdetune<0) cdet=-cdet; + } + if(finedetune < 8192) + findet = -findet; + if(cdetune < 0) + cdet = -cdet; - det=octdet+cdet+findet; - return(det); -}; + det = octdet + cdet + findet; + return det; +} bool fileexists(const char *filename) { struct stat tmp; - int result=stat(filename,&tmp); - if (result>=0) return(true); + int result = stat(filename, &tmp); + if(result >= 0) + return true; - return(false); -}; + return false; +} diff --git a/src/Misc/Util.h b/src/Misc/Util.h @@ -29,18 +29,20 @@ #include "Config.h" //Velocity Sensing function -extern REALTYPE VelF(REALTYPE velocity,unsigned char scaling); +extern REALTYPE VelF(REALTYPE velocity, unsigned char scaling); bool fileexists(const char *filename); #define N_DETUNE_TYPES 4 //the number of detune types -extern REALTYPE getdetune(unsigned char type,unsigned short int coarsedetune,unsigned short int finedetune); +extern REALTYPE getdetune(unsigned char type, + unsigned short int coarsedetune, + unsigned short int finedetune); -extern REALTYPE *denormalkillbuf;/**<the buffer to add noise in order to avoid denormalisation*/ +extern REALTYPE *denormalkillbuf; /**<the buffer to add noise in order to avoid denormalisation*/ extern Config config; -template <class T> +template<class T> std::string stringFrom(T x) { std::stringstream ss; @@ -48,10 +50,10 @@ std::string stringFrom(T x) return ss.str(); } -template <class T> -T stringTo(const char * x) +template<class T> +T stringTo(const char *x) { - std::string str = x!=NULL ? x : "0"; //should work for the basic float/int + std::string str = x != NULL ? x : "0"; //should work for the basic float/int std::stringstream ss(str); T ans; ss >> ans; diff --git a/src/Misc/XMLwrapper.cpp b/src/Misc/XMLwrapper.cpp @@ -36,57 +36,62 @@ using namespace std; -int xml_k = 0; +int xml_k = 0; bool verbose = false; -const char *XMLwrapper_whitespace_callback(mxml_node_t *node,int where) +const char *XMLwrapper_whitespace_callback(mxml_node_t *node, int where) { - const char *name=node->value.element.name; + const char *name = node->value.element.name; - if ((where==MXML_WS_BEFORE_OPEN)&&(!strcmp(name,"?xml"))) return(NULL); - if ((where==MXML_WS_BEFORE_CLOSE)&&(!strcmp(name,"string"))) return(NULL); + if((where == MXML_WS_BEFORE_OPEN) && (!strcmp(name, "?xml"))) + return NULL; + if((where == MXML_WS_BEFORE_CLOSE) && (!strcmp(name, "string"))) + return NULL; - if ((where==MXML_WS_BEFORE_OPEN)||(where==MXML_WS_BEFORE_CLOSE)) { + if((where == MXML_WS_BEFORE_OPEN) || (where == MXML_WS_BEFORE_CLOSE)) /* const char *tmp=node->value.element.name; - if (tmp!=NULL) { - if ((strstr(tmp,"par")!=tmp)&&(strstr(tmp,"string")!=tmp)) { - printf("%s ",tmp); - if (where==MXML_WS_BEFORE_OPEN) xml_k++; - if (where==MXML_WS_BEFORE_CLOSE) xml_k--; - if (xml_k>=STACKSIZE) xml_k=STACKSIZE-1; - if (xml_k<0) xml_k=0; - printf("%d\n",xml_k); - printf("\n"); - }; - - }; - int i=0; - for (i=1;i<xml_k;i++) tabs[i]='\t'; - tabs[0]='\n';tabs[i+1]='\0'; - if (where==MXML_WS_BEFORE_OPEN) return(tabs); - else return("\n"); + if (tmp!=NULL) { + if ((strstr(tmp,"par")!=tmp)&&(strstr(tmp,"string")!=tmp)) { + printf("%s ",tmp); + if (where==MXML_WS_BEFORE_OPEN) xml_k++; + if (where==MXML_WS_BEFORE_CLOSE) xml_k--; + if (xml_k>=STACKSIZE) xml_k=STACKSIZE-1; + if (xml_k<0) xml_k=0; + printf("%d\n",xml_k); + printf("\n"); + }; + + }; + int i=0; + for (i=1;i<xml_k;i++) tabs[i]='\t'; + tabs[0]='\n';tabs[i+1]='\0'; + if (where==MXML_WS_BEFORE_OPEN) return(tabs); + else return("\n"); */ - return("\n"); - }; + return "\n"; + ; - return(0); -}; + return 0; +} //temporary const overload of mxmlFindElement const mxml_node_t *mxmlFindElement(const mxml_node_t *node, - const mxml_node_t *top, const char *name, const char *attr, - const char *value, int descend) -{ - return(const_cast<const mxml_node_t *> (mxmlFindElement( - const_cast<mxml_node_t *>(node), - const_cast<mxml_node_t *>(top), - name, attr, value, descend))); + const mxml_node_t *top, + const char *name, + const char *attr, + const char *value, + int descend) +{ + return const_cast<const mxml_node_t *>(mxmlFindElement( + const_cast<mxml_node_t *>(node), + const_cast<mxml_node_t *>(top), + name, attr, value, descend)); } //temporary const overload of mxmlElementGetAttr const char *mxmlElementGetAttr(const mxml_node_t *node, const char *name) { - return mxmlElementGetAttr(const_cast<mxml_node_t *>(node),name); + return mxmlElementGetAttr(const_cast<mxml_node_t *>(node), name); } XMLwrapper::XMLwrapper() @@ -95,75 +100,88 @@ XMLwrapper::XMLwrapper() version.Minor = 4; version.Revision = 1; - minimal=true; + minimal = true; - node=tree=mxmlNewElement(MXML_NO_PARENT,"?xml version=\"1.0\" encoding=\"UTF-8\"?"); + node = tree = mxmlNewElement(MXML_NO_PARENT, + "?xml version=\"1.0\" encoding=\"UTF-8\"?"); /* for mxml 2.1 (and older) tree=mxmlNewElement(MXML_NO_PARENT,"?xml"); mxmlElementSetAttr(tree,"version","1.0"); mxmlElementSetAttr(tree,"encoding","UTF-8"); */ - mxml_node_t *doctype=mxmlNewElement(tree,"!DOCTYPE"); - mxmlElementSetAttr(doctype,"ZynAddSubFX-data",NULL); + mxml_node_t *doctype = mxmlNewElement(tree, "!DOCTYPE"); + mxmlElementSetAttr(doctype, "ZynAddSubFX-data", NULL); - node=root=addparams("ZynAddSubFX-data",4, - "version-major", stringFrom<int>(version.Major).c_str(), - "version-minor", stringFrom<int>(version.Minor).c_str(), - "version-revision", stringFrom<int>(version.Revision).c_str(), - "ZynAddSubFX-author", "Nasca Octavian Paul"); + node = root = addparams("ZynAddSubFX-data", 4, + "version-major", stringFrom<int>( + version.Major).c_str(), + "version-minor", stringFrom<int>( + version.Minor).c_str(), + "version-revision", + stringFrom<int>(version.Revision).c_str(), + "ZynAddSubFX-author", "Nasca Octavian Paul"); //make the empty branch that will contain the information parameters - info=addparams("INFORMATION",0); + info = addparams("INFORMATION", 0); //save zynaddsubfx specifications beginbranch("BASE_PARAMETERS"); - addpar("max_midi_parts",NUM_MIDI_PARTS); - addpar("max_kit_items_per_instrument",NUM_KIT_ITEMS); + addpar("max_midi_parts", NUM_MIDI_PARTS); + addpar("max_kit_items_per_instrument", NUM_KIT_ITEMS); - addpar("max_system_effects",NUM_SYS_EFX); - addpar("max_insertion_effects",NUM_INS_EFX); - addpar("max_instrument_effects",NUM_PART_EFX); + addpar("max_system_effects", NUM_SYS_EFX); + addpar("max_insertion_effects", NUM_INS_EFX); + addpar("max_instrument_effects", NUM_PART_EFX); - addpar("max_addsynth_voices",NUM_VOICES); + addpar("max_addsynth_voices", NUM_VOICES); endbranch(); - -}; +} XMLwrapper::~XMLwrapper() { - if (tree!=NULL) mxmlDelete(tree); -}; + if(tree != NULL) + mxmlDelete(tree); +} void XMLwrapper::setPadSynth(bool enabled) { /**@bug this might create multiple nodes when only one is needed*/ - mxml_node_t *oldnode=node; - node=info; + mxml_node_t *oldnode = node; + node = info; //Info storing - addparbool("PADsynth_used",enabled); - node=oldnode; + addparbool("PADsynth_used", enabled); + node = oldnode; } bool XMLwrapper::hasPadSynth() const { /**Right now this has a copied implementation of setparbool, so this should * be reworked as XMLwrapper evolves*/ - mxml_node_t * tmp = mxmlFindElement(tree,tree,"INFORMATION",NULL,NULL,MXML_DESCEND); - - mxml_node_t * parameter = mxmlFindElement(tmp, tmp, "par_bool", "name", - "PADsynth_used", MXML_DESCEND_FIRST); - if (parameter==NULL)//no information availiable - return(false); - - const char *strval = mxmlElementGetAttr(parameter,"value"); - if (strval==NULL)//no information available - return(false); - - if ((strval[0]=='Y')||(strval[0]=='y')) - return(true); + mxml_node_t *tmp = mxmlFindElement(tree, + tree, + "INFORMATION", + NULL, + NULL, + MXML_DESCEND); + + mxml_node_t *parameter = mxmlFindElement(tmp, + tmp, + "par_bool", + "name", + "PADsynth_used", + MXML_DESCEND_FIRST); + if(parameter == NULL) //no information availiable + return false; + + const char *strval = mxmlElementGetAttr(parameter, "value"); + if(strval == NULL) //no information available + return false; + + if((strval[0] == 'Y') || (strval[0] == 'y')) + return true; else - return(false); + return false; } @@ -171,97 +189,110 @@ bool XMLwrapper::hasPadSynth() const int XMLwrapper::saveXMLfile(const string &filename) const { - char *xmldata=getXMLdata(); - if (xmldata==NULL) return(-2); + char *xmldata = getXMLdata(); + if(xmldata == NULL) + return -2; - int compression=config.cfg.GzipCompression; - int result=dosavefile(filename.c_str(),compression,xmldata); + int compression = config.cfg.GzipCompression; + int result = dosavefile(filename.c_str(), compression, xmldata); free(xmldata); - return(result); -}; + return result; +} char *XMLwrapper::getXMLdata() const { - xml_k=0; + xml_k = 0; - char *xmldata=mxmlSaveAllocString(tree,XMLwrapper_whitespace_callback); + char *xmldata = mxmlSaveAllocString(tree, XMLwrapper_whitespace_callback); - return(xmldata); -}; + return xmldata; +} -int XMLwrapper::dosavefile(const char *filename,int compression,const char *xmldata) const +int XMLwrapper::dosavefile(const char *filename, + int compression, + const char *xmldata) const { - if (compression==0) { + if(compression == 0) { FILE *file; - file=fopen(filename,"w"); - if (file==NULL) return(-1); - fputs(xmldata,file); + file = fopen(filename, "w"); + if(file == NULL) + return -1; + fputs(xmldata, file); fclose(file); - } else { - if (compression>9) compression=9; - if (compression<1) compression=1; + } + else { + if(compression > 9) + compression = 9; + if(compression < 1) + compression = 1; char options[10]; - snprintf(options,10,"wb%d",compression); + snprintf(options, 10, "wb%d", compression); gzFile gzfile; - gzfile=gzopen(filename,options); - if (gzfile==NULL) return(-1); - gzputs(gzfile,xmldata); + gzfile = gzopen(filename, options); + if(gzfile == NULL) + return -1; + gzputs(gzfile, xmldata); gzclose(gzfile); - }; + } - return(0); -}; + return 0; +} -void XMLwrapper::addpar(const string &name,int val) +void XMLwrapper::addpar(const string &name, int val) { - addparams("par",2,"name",name.c_str(),"value",stringFrom<int>(val).c_str()); -}; + addparams("par", 2, "name", name.c_str(), "value", stringFrom<int>( + val).c_str()); +} -void XMLwrapper::addparreal(const string &name,REALTYPE val) +void XMLwrapper::addparreal(const string &name, REALTYPE val) { - addparams("par_real",2,"name",name.c_str(),"value",stringFrom<REALTYPE>(val).c_str()); -}; + addparams("par_real", 2, "name", name.c_str(), "value", + stringFrom<REALTYPE>(val).c_str()); +} -void XMLwrapper::addparbool(const string &name,int val) +void XMLwrapper::addparbool(const string &name, int val) { - if (val!=0) addparams("par_bool",2,"name",name.c_str(),"value","yes"); - else addparams("par_bool",2,"name",name.c_str(),"value","no"); -}; + if(val != 0) + addparams("par_bool", 2, "name", name.c_str(), "value", "yes"); + else + addparams("par_bool", 2, "name", name.c_str(), "value", "no"); +} -void XMLwrapper::addparstr(const string &name,const string &val) +void XMLwrapper::addparstr(const string &name, const string &val) { - mxml_node_t *element=mxmlNewElement(node,"string"); - mxmlElementSetAttr(element,"name",name.c_str()); - mxmlNewText(element,0,val.c_str()); -}; + mxml_node_t *element = mxmlNewElement(node, "string"); + mxmlElementSetAttr(element, "name", name.c_str()); + mxmlNewText(element, 0, val.c_str()); +} void XMLwrapper::beginbranch(const string &name) { if(verbose) cout << "beginbranch()" << name << endl; - node = addparams(name.c_str(),0); -}; + node = addparams(name.c_str(), 0); +} -void XMLwrapper::beginbranch(const string &name,int id) +void XMLwrapper::beginbranch(const string &name, int id) { if(verbose) cout << "beginbranch(" << id << ")" << name << endl; - node = addparams(name.c_str(),1,"id",stringFrom<int>(id).c_str()); -}; + node = addparams(name.c_str(), 1, "id", stringFrom<int>(id).c_str()); +} void XMLwrapper::endbranch() { if(verbose) - cout << "endbranch()" << node << "-" << node->value.element.name << " To " + cout << "endbranch()" << node << "-" << node->value.element.name + << " To " << node->parent << "-" << node->parent->value.element.name << endl; node = node->parent; -}; +} @@ -269,61 +300,71 @@ void XMLwrapper::endbranch() int XMLwrapper::loadXMLfile(const string &filename) { - if (tree!=NULL) mxmlDelete(tree); - tree=NULL; + if(tree != NULL) + mxmlDelete(tree); + tree = NULL; - const char *xmldata=doloadfile(filename.c_str()); - if (xmldata==NULL) return(-1);//the file could not be loaded or uncompressed + const char *xmldata = doloadfile(filename.c_str()); + if(xmldata == NULL) + return -1; //the file could not be loaded or uncompressed - root=tree=mxmlLoadString(NULL,xmldata,MXML_OPAQUE_CALLBACK); + root = tree = mxmlLoadString(NULL, xmldata, MXML_OPAQUE_CALLBACK); - delete []xmldata; + delete [] xmldata; - if (tree==NULL) return(-2);//this is not XML + if(tree == NULL) + return -2; //this is not XML - node = root = mxmlFindElement(tree,tree,"ZynAddSubFX-data",NULL,NULL,MXML_DESCEND); - if (root==NULL) return(-3);//the XML doesnt embbed zynaddsubfx data + node = root = mxmlFindElement(tree, + tree, + "ZynAddSubFX-data", + NULL, + NULL, + MXML_DESCEND); + if(root == NULL) + return -3; //the XML doesnt embbed zynaddsubfx data //fetch version information - version.Major = stringTo<int>(mxmlElementGetAttr(root,"version-major")); - version.Minor = stringTo<int>(mxmlElementGetAttr(root,"version-minor")); - version.Revision = stringTo<int>(mxmlElementGetAttr(root,"version-revision")); + version.Major = stringTo<int>(mxmlElementGetAttr(root, "version-major")); + version.Minor = stringTo<int>(mxmlElementGetAttr(root, "version-minor")); + version.Revision = + stringTo<int>(mxmlElementGetAttr(root, "version-revision")); if(verbose) - cout << "loadXMLfile() version: " << version.Major << '.' << version.Minor << '.' << version.Revision << endl; + cout << "loadXMLfile() version: " << version.Major << '.' + << version.Minor << '.' << version.Revision << endl; - return(0); -}; + return 0; +} char *XMLwrapper::doloadfile(const string &filename) const { - char * xmldata = NULL; - gzFile gzfile = gzopen(filename.c_str(),"rb"); - - if (gzfile != NULL) {//The possibly compressed file opened + char *xmldata = NULL; + gzFile gzfile = gzopen(filename.c_str(), "rb"); + if(gzfile != NULL) { //The possibly compressed file opened stringstream strBuf; //reading stream const int bufSize = 500; //fetch size - char fetchBuf[bufSize+1];//fetch buffer - int read = 0; //chars read in last fetch + char fetchBuf[bufSize + 1]; //fetch buffer + int read = 0; //chars read in last fetch - fetchBuf[bufSize] = 0;//force null termination + fetchBuf[bufSize] = 0; //force null termination while(bufSize == (read = gzread(gzfile, fetchBuf, bufSize))) strBuf << fetchBuf; - fetchBuf[read] = 0;//Truncate last partial read + fetchBuf[read] = 0; //Truncate last partial read strBuf << fetchBuf; gzclose(gzfile); //Place data in output format string tmp = strBuf.str(); - xmldata = new char[tmp.size()+1]; - strncpy(xmldata, tmp.c_str(), tmp.size()+1); + xmldata = new char[tmp.size() + 1]; + strncpy(xmldata, tmp.c_str(), tmp.size() + 1); } return xmldata; @@ -331,23 +372,28 @@ char *XMLwrapper::doloadfile(const string &filename) const bool XMLwrapper::putXMLdata(const char *xmldata) { - if (tree!=NULL) + if(tree != NULL) mxmlDelete(tree); - tree=NULL; - if (xmldata==NULL) - return (false); + tree = NULL; + if(xmldata == NULL) + return false; - root = tree = mxmlLoadString(NULL,xmldata,MXML_OPAQUE_CALLBACK); - if (tree==NULL) - return(false); + root = tree = mxmlLoadString(NULL, xmldata, MXML_OPAQUE_CALLBACK); + if(tree == NULL) + return false; - node = root = mxmlFindElement(tree,tree,"ZynAddSubFX-data",NULL,NULL,MXML_DESCEND); - if (root==NULL) - return (false); + node = root = mxmlFindElement(tree, + tree, + "ZynAddSubFX-data", + NULL, + NULL, + MXML_DESCEND); + if(root == NULL) + return false; - return(true); -}; + return true; +} @@ -355,155 +401,214 @@ int XMLwrapper::enterbranch(const string &name) { if(verbose) cout << "enterbranch() " << name << endl; - mxml_node_t *tmp = mxmlFindElement(node,node,name.c_str(),NULL,NULL,MXML_DESCEND_FIRST); - if (tmp==NULL) - return(0); + mxml_node_t *tmp = mxmlFindElement(node, node, + name.c_str(), NULL, NULL, + MXML_DESCEND_FIRST); + if(tmp == NULL) + return 0; node = tmp; - return(1); -}; + return 1; +} -int XMLwrapper::enterbranch(const string &name,int id) +int XMLwrapper::enterbranch(const string &name, int id) { if(verbose) - cout << "enterbranch("<<id<<") " << name << endl; - mxml_node_t *tmp = mxmlFindElement(node,node,name.c_str(),"id",stringFrom<int>(id).c_str(),MXML_DESCEND_FIRST); - if (tmp==NULL) - return(0); + cout << "enterbranch(" << id << ") " << name << endl; + mxml_node_t *tmp = mxmlFindElement(node, node, + name.c_str(), "id", stringFrom<int>( + id).c_str(), MXML_DESCEND_FIRST); + if(tmp == NULL) + return 0; node = tmp; - return(1); -}; + return 1; +} void XMLwrapper::exitbranch() { if(verbose) - cout << "exitbranch()" << node << "-" << node->value.element.name << " To " + cout << "exitbranch()" << node << "-" << node->value.element.name + << " To " << node->parent << "-" << node->parent->value.element.name << endl; node = node->parent; -}; +} int XMLwrapper::getbranchid(int min, int max) const { - int id=stringTo<int>(mxmlElementGetAttr(node,"id")); - if ((min==0)&&(max==0)) return(id); + int id = stringTo<int>(mxmlElementGetAttr(node, "id")); + if((min == 0) && (max == 0)) + return id; - if (id<min) id=min; - else if (id>max) id=max; + if(id < min) + id = min; + else + if(id > max) + id = max; - return(id); -}; + return id; +} -int XMLwrapper::getpar(const string &name,int defaultpar,int min,int max) const +int XMLwrapper::getpar(const string &name, int defaultpar, int min, + int max) const { - const mxml_node_t * tmp = mxmlFindElement(node,node,"par","name",name.c_str(),MXML_DESCEND_FIRST); + const mxml_node_t *tmp = mxmlFindElement(node, + node, + "par", + "name", + name.c_str(), + MXML_DESCEND_FIRST); - if (tmp==NULL) return(defaultpar); + if(tmp == NULL) + return defaultpar; - const char *strval=mxmlElementGetAttr(tmp,"value"); - if (strval==NULL) return(defaultpar); + const char *strval = mxmlElementGetAttr(tmp, "value"); + if(strval == NULL) + return defaultpar; - int val=stringTo<int>(strval); - if (val<min) val=min; - else if (val>max) val=max; + int val = stringTo<int>(strval); + if(val < min) + val = min; + else + if(val > max) + val = max; - return(val); -}; + return val; +} -int XMLwrapper::getpar127(const string &name,int defaultpar) const +int XMLwrapper::getpar127(const string &name, int defaultpar) const { - return(getpar(name,defaultpar,0,127)); -}; + return getpar(name, defaultpar, 0, 127); +} -int XMLwrapper::getparbool(const string &name,int defaultpar) const +int XMLwrapper::getparbool(const string &name, int defaultpar) const { - const mxml_node_t * tmp = mxmlFindElement(node,node,"par_bool","name",name.c_str(),MXML_DESCEND_FIRST); + const mxml_node_t *tmp = mxmlFindElement(node, + node, + "par_bool", + "name", + name.c_str(), + MXML_DESCEND_FIRST); - if (tmp==NULL) return(defaultpar); + if(tmp == NULL) + return defaultpar; - const char *strval=mxmlElementGetAttr(tmp,"value"); - if (strval==NULL) return(defaultpar); + const char *strval = mxmlElementGetAttr(tmp, "value"); + if(strval == NULL) + return defaultpar; - if ((strval[0]=='Y')||(strval[0]=='y')) return(1); - else return(0); -}; + if((strval[0] == 'Y') || (strval[0] == 'y')) + return 1; + else + return 0; +} -void XMLwrapper::getparstr(const string &name,char *par,int maxstrlen) const +void XMLwrapper::getparstr(const string &name, char *par, int maxstrlen) const { - ZERO(par,maxstrlen); - const mxml_node_t * tmp = mxmlFindElement(node,node,"string","name",name.c_str(),MXML_DESCEND_FIRST); + ZERO(par, maxstrlen); + const mxml_node_t *tmp = mxmlFindElement(node, + node, + "string", + "name", + name.c_str(), + MXML_DESCEND_FIRST); - if (tmp==NULL) return; - if (tmp->child==NULL) return; - if (tmp->child->type==MXML_OPAQUE){ - snprintf(par,maxstrlen,"%s",tmp->child->value.element.name); + if(tmp == NULL) + return; + if(tmp->child == NULL) + return; + if(tmp->child->type == MXML_OPAQUE) { + snprintf(par, maxstrlen, "%s", tmp->child->value.element.name); return; } - if (tmp->child->type==MXML_TEXT && tmp->child->value.text.string!=NULL){ - snprintf(par,maxstrlen,"%s",tmp->child->value.text.string); + if((tmp->child->type == MXML_TEXT) + && (tmp->child->value.text.string != NULL)) { + snprintf(par, maxstrlen, "%s", tmp->child->value.text.string); return; } +} -}; - -string XMLwrapper::getparstr(const string &name,const std::string &defaultpar) const +string XMLwrapper::getparstr(const string &name, + const std::string &defaultpar) const { - const mxml_node_t * tmp = mxmlFindElement(node, node, "string", "name", name.c_str(), MXML_DESCEND_FIRST); + const mxml_node_t *tmp = mxmlFindElement(node, + node, + "string", + "name", + name.c_str(), + MXML_DESCEND_FIRST); - if (tmp==NULL||tmp->child==NULL) + if((tmp == NULL) || (tmp->child == NULL)) return defaultpar; - if (tmp->child->type==MXML_OPAQUE && tmp->child->value.element.name!=NULL) + if((tmp->child->type == MXML_OPAQUE) + && (tmp->child->value.element.name != NULL)) return tmp->child->value.element.name; - if (tmp->child->type==MXML_TEXT && tmp->child->value.text.string!=NULL) + if((tmp->child->type == MXML_TEXT) + && (tmp->child->value.text.string != NULL)) return tmp->child->value.text.string; return defaultpar; } -REALTYPE XMLwrapper::getparreal(const char *name,REALTYPE defaultpar) const +REALTYPE XMLwrapper::getparreal(const char *name, REALTYPE defaultpar) const { - const mxml_node_t * tmp = mxmlFindElement(node,node,"par_real","name",name,MXML_DESCEND_FIRST); - if (tmp==NULL) return(defaultpar); + const mxml_node_t *tmp = mxmlFindElement(node, + node, + "par_real", + "name", + name, + MXML_DESCEND_FIRST); + if(tmp == NULL) + return defaultpar; - const char *strval=mxmlElementGetAttr(tmp,"value"); - if (strval==NULL) return(defaultpar); + const char *strval = mxmlElementGetAttr(tmp, "value"); + if(strval == NULL) + return defaultpar; - return(stringTo<REALTYPE>(strval)); -}; + return stringTo<REALTYPE>(strval); +} -REALTYPE XMLwrapper::getparreal(const char *name,REALTYPE defaultpar,REALTYPE min,REALTYPE max) const +REALTYPE XMLwrapper::getparreal(const char *name, + REALTYPE defaultpar, + REALTYPE min, + REALTYPE max) const { - REALTYPE result=getparreal(name,defaultpar); + REALTYPE result = getparreal(name, defaultpar); - if (result<min) result=min; - else if (result>max) result=max; - return(result); -}; + if(result < min) + result = min; + else + if(result > max) + result = max; + return result; +} /** Private members **/ -mxml_node_t *XMLwrapper::addparams(const char *name, unsigned int params, ...) const +mxml_node_t *XMLwrapper::addparams(const char *name, unsigned int params, + ...) const { /**@todo make this function send out a good error message if something goes * wrong**/ mxml_node_t *element = mxmlNewElement(node, name); - if(params){ + if(params) { va_list variableList; va_start(variableList, params); const char *ParamName; const char *ParamValue; - while(params--){ + while(params--) { ParamName = va_arg(variableList, const char *); ParamValue = va_arg(variableList, const char *); if(verbose) - cout << "addparams()[" << params << "]=" << name << " " << ParamName <<"=\"" << ParamValue << "\"" << endl; + cout << "addparams()[" << params << "]=" << name << " " + << ParamName << "=\"" << ParamValue << "\"" << endl; mxmlElementSetAttr(element, ParamName, ParamValue); } } diff --git a/src/Misc/XMLwrapper.h b/src/Misc/XMLwrapper.h @@ -34,231 +34,239 @@ /**Mxml wrapper*/ class XMLwrapper { -public: - /** - * Constructor. - * Will Construct the object and fill in top level branch - * */ - XMLwrapper(); - - /**Destructor*/ - ~XMLwrapper(); - - /** - * Saves the XML to a file. - * @param filename the name of the destination file. - * @returns 0 if ok or -1 if the file cannot be saved. - */ - int saveXMLfile(const std::string &filename) const; - - /** - * Return XML tree as a string. - * Note: The string must be freed with free() to deallocate - * @returns a newly allocated NULL terminated string of the XML data. - */ - char *getXMLdata() const; - - /** - * Add simple parameter. - * @param name The name of the mXML node. - * @param val The string value of the mXml node - */ - void addpar(const std::string &name,int val); - - /** - * Adds a realtype parameter. - * @param name The name of the mXML node. - * @param val The REALTYPE value of the node. - */ - void addparreal(const std::string &name,REALTYPE val); - - /** - * Add boolean parameter. - * \todo Fix this reverse boolean logic. - * @param name The name of the mXML node. - * @param val The boolean value of the node (0->"yes";else->"no"). - */ - void addparbool(const std::string &name,int val); - - /** - * Add string parameter. - * @param name The name of the mXML node. - * @param val The string value of the node. - */ - void addparstr(const std::string &name,const std::string &val); - - /** - * Create a new branch. - * @param name Name of new branch - * @see void endbranch() - */ - void beginbranch(const std::string &name); - /** - * Create a new branch. - * @param name Name of new branch - * @param id "id" value of branch - * @see void endbranch() - */ - void beginbranch(const std::string &name, int id); - - /**Closes new branches. - * This must be called to exit each branch created by beginbranch( ). - * @see void beginbranch(const std::string &name) - * @see void beginbranch(const std::string &name, int id) - */ - void endbranch(); - - /** - * Loads file into XMLwrapper. - * @param filename file to be loaded - * @returns 0 if ok or -1 if the file cannot be loaded - */ - int loadXMLfile(const std::string &filename); - - /** - * Loads string into XMLwrapper. - * @param xmldata NULL terminated string of XML data. - * @returns true if successful. - */ - bool putXMLdata(const char *xmldata); - - /** - * Enters the branch. - * @param name Name of branch. - * @returns 1 if is ok, or 0 otherwise. - */ - int enterbranch(const std::string &name); - - /** - * Enter into the branch \c name with id \c id. - * @param name Name of branch. - * @param id Value of branch's "id". - * @returns 1 if is ok, or 0 otherwise. - */ - int enterbranch(const std::string &name, int id); - - /**Exits from a branch*/ - void exitbranch(); - - /**Get the the branch_id and limits it between the min and max. - * if min==max==0, it will not limit it - * if there isn't any id, will return min - * this must be called only imediately after enterbranch() - */ - int getbranchid(int min, int max) const; - - /** - * Returns the integer value stored in node name. - * It returns the integer value between the limits min and max. - * If min==max==0, then the value will not be limited. - * If there is no location named name, then defaultpar will be returned. - * @param name The parameter name. - * @param defaultpar The default value if the real value is not found. - * @param min The minimum return value. - * @param max The maximum return value. - */ - int getpar(const std::string &name,int defaultpar,int min,int max) const; - - /** - * Returns the integer value stored in the node with range [0,127]. - * @param name The parameter name. - * @param defaultpar The default value if the real value is not found. - */ - int getpar127(const std::string &name,int defaultpar) const; - - /** - * Returns the boolean value stored in the node. - * @param name The parameter name. - * @param defaultpar The default value if the real value is not found. - */ - int getparbool(const std::string &name,int defaultpar) const; - - /** - * Get the string value stored in the node. - * @param name The parameter name. - * @param par Pointer to destination string - * @param maxstrlen Max string length for destination - */ - void getparstr(const std::string &name,char *par,int maxstrlen) const; - - /** - * Get the string value stored in the node. - * @param name The parameter name. - * @param defaultpar The default value if the real value is not found. - */ - std::string getparstr(const std::string &name,const std::string &defaultpar) const; - - /** - * Returns the real value stored in the node. - * @param name The parameter name. - * @param defaultpar The default value if the real value is not found. - */ - REALTYPE getparreal(const char *name,REALTYPE defaultpar) const; - - /** - * Returns the real value stored in the node. - * @param name The parameter name. - * @param defaultpar The default value if the real value is not found. - * @param min The minimum value - * @param max The maximum value - */ - REALTYPE getparreal(const char *name,REALTYPE defaultpar,REALTYPE min,REALTYPE max) const; - - bool minimal;/**<false if all parameters will be stored (used only for clipboard)*/ - - /** - * Sets the current tree's PAD Synth usage - */ - void setPadSynth(bool enabled); - /** - * Checks the current tree for PADsynth usage - */ - bool hasPadSynth() const; - -private: - - /** - * Save the file. - * @param filename File to save to - * @param compression Level of gzip compression - * @param xmldata String to be saved - */ - int dosavefile(const char *filename,int compression,const char *xmldata) const; - - /** - * Loads specified file and returns data. - * - * Will load a gziped file or an uncompressed file. - * @param filename the file - * @return The decompressed data - */ - char *doloadfile(const std::string &filename) const; - - mxml_node_t *tree;/**<all xml data*/ - mxml_node_t *root;/**<xml data used by zynaddsubfx*/ - mxml_node_t *node;/**<current subtree in parsing or writing */ - mxml_node_t *info;/**<Node used to store the information about the data*/ - - /** - * Create mxml_node_t with specified name and parameters - * - * Results should look like: - * <name optionalParam1="value1" optionalParam2="value2" ...> - * - * @param name The name of the xml node - * @param params The number of the attributes - * @param ... const char * pairs that are in the format attribute_name, - * attribute_value - */ - mxml_node_t *addparams(const char *name, unsigned int params, ...) const; - - /**@todo keep these numbers up to date*/ - struct{ - int Major;/**<major version number.*/ - int Minor;/**<minor version number.*/ - int Revision;/**<version revision number.*/ - }version; - + public: + /** + * Constructor. + * Will Construct the object and fill in top level branch + * */ + XMLwrapper(); + + /**Destructor*/ + ~XMLwrapper(); + + /** + * Saves the XML to a file. + * @param filename the name of the destination file. + * @returns 0 if ok or -1 if the file cannot be saved. + */ + int saveXMLfile(const std::string &filename) const; + + /** + * Return XML tree as a string. + * Note: The string must be freed with free() to deallocate + * @returns a newly allocated NULL terminated string of the XML data. + */ + char *getXMLdata() const; + + /** + * Add simple parameter. + * @param name The name of the mXML node. + * @param val The string value of the mXml node + */ + void addpar(const std::string &name, int val); + + /** + * Adds a realtype parameter. + * @param name The name of the mXML node. + * @param val The REALTYPE value of the node. + */ + void addparreal(const std::string &name, REALTYPE val); + + /** + * Add boolean parameter. + * \todo Fix this reverse boolean logic. + * @param name The name of the mXML node. + * @param val The boolean value of the node (0->"yes";else->"no"). + */ + void addparbool(const std::string &name, int val); + + /** + * Add string parameter. + * @param name The name of the mXML node. + * @param val The string value of the node. + */ + void addparstr(const std::string &name, const std::string &val); + + /** + * Create a new branch. + * @param name Name of new branch + * @see void endbranch() + */ + void beginbranch(const std::string &name); + /** + * Create a new branch. + * @param name Name of new branch + * @param id "id" value of branch + * @see void endbranch() + */ + void beginbranch(const std::string &name, int id); + + /**Closes new branches. + * This must be called to exit each branch created by beginbranch( ). + * @see void beginbranch(const std::string &name) + * @see void beginbranch(const std::string &name, int id) + */ + void endbranch(); + + /** + * Loads file into XMLwrapper. + * @param filename file to be loaded + * @returns 0 if ok or -1 if the file cannot be loaded + */ + int loadXMLfile(const std::string &filename); + + /** + * Loads string into XMLwrapper. + * @param xmldata NULL terminated string of XML data. + * @returns true if successful. + */ + bool putXMLdata(const char *xmldata); + + /** + * Enters the branch. + * @param name Name of branch. + * @returns 1 if is ok, or 0 otherwise. + */ + int enterbranch(const std::string &name); + + /** + * Enter into the branch \c name with id \c id. + * @param name Name of branch. + * @param id Value of branch's "id". + * @returns 1 if is ok, or 0 otherwise. + */ + int enterbranch(const std::string &name, int id); + + /**Exits from a branch*/ + void exitbranch(); + + /**Get the the branch_id and limits it between the min and max. + * if min==max==0, it will not limit it + * if there isn't any id, will return min + * this must be called only imediately after enterbranch() + */ + int getbranchid(int min, int max) const; + + /** + * Returns the integer value stored in node name. + * It returns the integer value between the limits min and max. + * If min==max==0, then the value will not be limited. + * If there is no location named name, then defaultpar will be returned. + * @param name The parameter name. + * @param defaultpar The default value if the real value is not found. + * @param min The minimum return value. + * @param max The maximum return value. + */ + int getpar(const std::string &name, int defaultpar, int min, + int max) const; + + /** + * Returns the integer value stored in the node with range [0,127]. + * @param name The parameter name. + * @param defaultpar The default value if the real value is not found. + */ + int getpar127(const std::string &name, int defaultpar) const; + + /** + * Returns the boolean value stored in the node. + * @param name The parameter name. + * @param defaultpar The default value if the real value is not found. + */ + int getparbool(const std::string &name, int defaultpar) const; + + /** + * Get the string value stored in the node. + * @param name The parameter name. + * @param par Pointer to destination string + * @param maxstrlen Max string length for destination + */ + void getparstr(const std::string &name, char *par, int maxstrlen) const; + + /** + * Get the string value stored in the node. + * @param name The parameter name. + * @param defaultpar The default value if the real value is not found. + */ + std::string getparstr(const std::string &name, + const std::string &defaultpar) const; + + /** + * Returns the real value stored in the node. + * @param name The parameter name. + * @param defaultpar The default value if the real value is not found. + */ + REALTYPE getparreal(const char *name, REALTYPE defaultpar) const; + + /** + * Returns the real value stored in the node. + * @param name The parameter name. + * @param defaultpar The default value if the real value is not found. + * @param min The minimum value + * @param max The maximum value + */ + REALTYPE getparreal(const char *name, + REALTYPE defaultpar, + REALTYPE min, + REALTYPE max) const; + + bool minimal; /**<false if all parameters will be stored (used only for clipboard)*/ + + /** + * Sets the current tree's PAD Synth usage + */ + void setPadSynth(bool enabled); + /** + * Checks the current tree for PADsynth usage + */ + bool hasPadSynth() const; + + private: + + /** + * Save the file. + * @param filename File to save to + * @param compression Level of gzip compression + * @param xmldata String to be saved + */ + int dosavefile(const char *filename, + int compression, + const char *xmldata) const; + + /** + * Loads specified file and returns data. + * + * Will load a gziped file or an uncompressed file. + * @param filename the file + * @return The decompressed data + */ + char *doloadfile(const std::string &filename) const; + + mxml_node_t *tree; /**<all xml data*/ + mxml_node_t *root; /**<xml data used by zynaddsubfx*/ + mxml_node_t *node; /**<current subtree in parsing or writing */ + mxml_node_t *info; /**<Node used to store the information about the data*/ + + /** + * Create mxml_node_t with specified name and parameters + * + * Results should look like: + * <name optionalParam1="value1" optionalParam2="value2" ...> + * + * @param name The name of the xml node + * @param params The number of the attributes + * @param ... const char * pairs that are in the format attribute_name, + * attribute_value + */ + mxml_node_t *addparams(const char *name, unsigned int params, + ...) const; + + /**@todo keep these numbers up to date*/ + struct { + int Major; /**<major version number.*/ + int Minor; /**<minor version number.*/ + int Revision; /**<version revision number.*/ + } version; }; #endif + diff --git a/src/Output/DSSIaudiooutput.cpp b/src/Output/DSSIaudiooutput.cpp @@ -27,7 +27,7 @@ #include "DSSIaudiooutput.h" static LADSPA_Descriptor *tsLDescriptor = NULL; -static DSSI_Descriptor *tsDDescriptor = NULL; +static DSSI_Descriptor *tsDDescriptor = NULL; typedef struct { LADSPA_Data *outl; @@ -42,11 +42,11 @@ static void cleanupTS(LADSPA_Handle instance) free(instance); } static void connectPortTS(LADSPA_Handle instance, unsigned long port, - LADSPA_Data * data) + LADSPA_Data *data) { TS *plugin; plugin = (TS *) instance; - switch (port) { + switch(port) { case 0: plugin->outl = data; break; @@ -58,7 +58,7 @@ static void connectPortTS(LADSPA_Handle instance, unsigned long port, const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) { - switch (index) { + switch(index) { case 0: return tsLDescriptor; default: @@ -71,7 +71,7 @@ const DSSI_Descriptor *dssi_descriptor(unsigned long index) // FILE *a=fopen("/tmp/zzzzz11z","w"); // fprintf(a,"aaaaaaaaaaa TEST\n"); // fclose(a); - switch (index) { + switch(index) { case 0: return tsDDescriptor; default: @@ -79,14 +79,13 @@ const DSSI_Descriptor *dssi_descriptor(unsigned long index) } } -static LADSPA_Handle instantiateTS(const LADSPA_Descriptor * descriptor, +static LADSPA_Handle instantiateTS(const LADSPA_Descriptor *descriptor, unsigned long s_rate) { - TS *plugin_data = (TS *) malloc(sizeof(TS)); /* for (i=0; i<MIDI_NOTES; i++) { - plugin_data->omega[i] = M_PI * 2.0 / (double)s_rate * - pow(2.0, (i-69.0) / 12.0); + plugin_data->omega[i] = M_PI * 2.0 / (double)s_rate * + pow(2.0, (i-69.0) / 12.0); } */ return (LADSPA_Handle) plugin_data; @@ -115,47 +114,47 @@ static void runTS(LADSPA_Handle instance, unsigned long sample_count, unsigned long note; /* if (freq < 1.0) { - freq = 440.0f; + freq = 440.0f; } if (vol < 0.000001) { - vol = 1.0f; + vol = 1.0f; } if (event_count > 0) { - printf("trivial_synth: have %ld events\n", event_count); + printf("trivial_synth: have %ld events\n", event_count); } for (pos = 0, event_pos = 0; pos < sample_count; pos++) { - while (event_pos < event_count - && pos == events[event_pos].time.tick) { - - printf("trivial_synth: event type %d\n", events[event_pos].type); - - if (events[event_pos].type == SND_SEQ_EVENT_NOTEON) { - data[events[event_pos].data.note.note].amp = - events[event_pos].data.note.velocity / 512.0f; - data[events[event_pos].data.note.note]. - active = events[event_pos].data.note.velocity > 0; - data[events[event_pos].data.note.note]. - phase = 0.0; - } else if (events[event_pos].type == SND_SEQ_EVENT_NOTEOFF) { - data[events[event_pos].data.note.note]. - active = 0; - } - event_pos++; - } - - output[pos] = 0.0f; - for (note = 0; note < MIDI_NOTES; note++) { - if (data[note].active) { - output[pos] += sin(data[note].phase) * data[note].amp * vol; - data[note].phase += plugin_data->omega[note] * freq; - if (data[note].phase > M_PI * 2.0) { - data[note].phase -= M_PI * 2.0; - } - } - } + while (event_pos < event_count + && pos == events[event_pos].time.tick) { + + printf("trivial_synth: event type %d\n", events[event_pos].type); + + if (events[event_pos].type == SND_SEQ_EVENT_NOTEON) { + data[events[event_pos].data.note.note].amp = + events[event_pos].data.note.velocity / 512.0f; + data[events[event_pos].data.note.note]. + active = events[event_pos].data.note.velocity > 0; + data[events[event_pos].data.note.note]. + phase = 0.0; + } else if (events[event_pos].type == SND_SEQ_EVENT_NOTEOFF) { + data[events[event_pos].data.note.note]. + active = 0; + } + event_pos++; + } + + output[pos] = 0.0f; + for (note = 0; note < MIDI_NOTES; note++) { + if (data[note].active) { + output[pos] += sin(data[note].phase) * data[note].amp * vol; + data[note].phase += plugin_data->omega[note] * freq; + if (data[note].phase > M_PI * 2.0) { + data[note].phase -= M_PI * 2.0; + } + } + } } */ } @@ -176,22 +175,23 @@ void _init() { char **port_names; LADSPA_PortDescriptor *port_descriptors; - LADSPA_PortRangeHint *port_range_hints; + LADSPA_PortRangeHint *port_range_hints; - FILE *a=fopen("/tmp/zzzzzz","w"); - fprintf(a,"aaaaaaaaaaa TEST\n"); + FILE *a = fopen("/tmp/zzzzzz", "w"); + fprintf(a, "aaaaaaaaaaa TEST\n"); fclose(a); tsLDescriptor = (LADSPA_Descriptor *) malloc(sizeof(LADSPA_Descriptor)); - if (tsLDescriptor) { - tsLDescriptor->UniqueID = 100; - tsLDescriptor->Label = "ZASF"; + if(tsLDescriptor) { + tsLDescriptor->UniqueID = 100; + tsLDescriptor->Label = "ZASF"; tsLDescriptor->Properties = 0; tsLDescriptor->Name = "ZynAddSubFX"; - tsLDescriptor->Maker = "Nasca Octavian Paul <zynaddsubfx@yahoo.com>"; - tsLDescriptor->Copyright = "GNU General Public License v.2"; - tsLDescriptor->PortCount = 2; + tsLDescriptor->Maker = + "Nasca Octavian Paul <zynaddsubfx@yahoo.com>"; + tsLDescriptor->Copyright = "GNU General Public License v.2"; + tsLDescriptor->PortCount = 2; port_descriptors = (LADSPA_PortDescriptor *) calloc(tsLDescriptor->PortCount, sizeof @@ -208,42 +208,40 @@ void _init() port_names = (char **) calloc(tsLDescriptor->PortCount, sizeof(char *)); tsLDescriptor->PortNames = (const char **) port_names; - port_descriptors[0] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + port_descriptors[0] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; port_names[0] = "Output L"; port_range_hints[0].HintDescriptor = 0; port_descriptors[1] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; port_names[1] = "Output R"; port_range_hints[1].HintDescriptor = 0; - tsLDescriptor->activate = activateTS; - tsLDescriptor->cleanup = cleanupTS; + tsLDescriptor->activate = activateTS; + tsLDescriptor->cleanup = cleanupTS; tsLDescriptor->connect_port = connectPortTS; - tsLDescriptor->deactivate = NULL; - tsLDescriptor->instantiate = instantiateTS; + tsLDescriptor->deactivate = NULL; + tsLDescriptor->instantiate = instantiateTS; tsLDescriptor->run = runTSWrapper; - tsLDescriptor->run_adding = NULL; + tsLDescriptor->run_adding = NULL; tsLDescriptor->set_run_adding_gain = NULL; } tsDDescriptor = (DSSI_Descriptor *) malloc(sizeof(DSSI_Descriptor)); - if (tsDDescriptor) { - tsDDescriptor->DSSI_API_Version = 1; - tsDDescriptor->LADSPA_Plugin = tsLDescriptor; + if(tsDDescriptor) { + tsDDescriptor->DSSI_API_Version = 1; + tsDDescriptor->LADSPA_Plugin = tsLDescriptor; tsDDescriptor->configure = NULL; - tsDDescriptor->get_program = NULL; + tsDDescriptor->get_program = NULL; tsDDescriptor->get_midi_controller_for_port = getControllerTS; - tsDDescriptor->select_program = NULL; + tsDDescriptor->select_program = NULL; tsDDescriptor->run_synth = runTS; - tsDDescriptor->run_synth_adding = NULL; + tsDDescriptor->run_synth_adding = NULL; tsDDescriptor->run_multiple_synths = NULL; tsDDescriptor->run_multiple_synths_adding = NULL; } - -}; +} void _fini() -{ -}; +{} @@ -272,17 +270,18 @@ long int VSTSynth::canDo(char *txt){ }; bool VSTSynth::getVendorString(char *txt){ - strcpy(txt,"Nasca O. Paul"); - return(true); + strcpy(txt,"Nasca O. Paul"); + return(true); }; bool VSTSynth::getProductString(char *txt){ - strcpy(txt,"ZynAddSubFX"); - return(true); + strcpy(txt,"ZynAddSubFX"); + return(true); }; void VSTSynth::resume(){ - wantEvents(); + wantEvents(); }; */ + diff --git a/src/Output/DSSIaudiooutput.h b/src/Output/DSSIaudiooutput.h @@ -34,25 +34,25 @@ /* class VSTSynth:public AudioEffectX{ public: - VSTSynth (audioMasterCallback audioMaster); - ~VSTSynth(); + VSTSynth (audioMasterCallback audioMaster); + ~VSTSynth(); - virtual void process (float **inputs, float **outputs, long sampleframes); - virtual void processReplacing (float **inputs, float **outputs, long sampleframes); - virtual long processEvents(VstEvents *events);//this is used for Midi input - virtual long int canDo(char *txt); - virtual bool getVendorString(char *txt); - virtual bool getProductString(char *txt); - virtual void resume(); + virtual void process (float **inputs, float **outputs, long sampleframes); + virtual void processReplacing (float **inputs, float **outputs, long sampleframes); + virtual long processEvents(VstEvents *events);//this is used for Midi input + virtual long int canDo(char *txt); + virtual bool getVendorString(char *txt); + virtual bool getProductString(char *txt); + virtual void resume(); - virtual long getChunk(void** data,bool isPreset=false); - virtual void setChunk(void *data,long size,bool isPreset=false); + virtual long getChunk(void** data,bool isPreset=false); + virtual void setChunk(void *data,long size,bool isPreset=false); - MasterUI *ui; - int Pexitprogram; + MasterUI *ui; + int Pexitprogram; Master *vmaster; - pthread_t thr; + pthread_t thr; }; */ #endif diff --git a/src/Output/JACK_RTaudiooutput.cpp b/src/Output/JACK_RTaudiooutput.cpp @@ -33,174 +33,197 @@ extern "C" #include "JACKaudiooutput.h" Master *jackmaster; -jack_client_t *jackclient; -jack_port_t *outport_left,*outport_right; -jack_ringbuffer_t *rb=NULL; +jack_client_t *jackclient; +jack_port_t *outport_left, *outport_right; +jack_ringbuffer_t *rb = NULL; -REALTYPE *jackoutl,*jackoutr; -int jackfinish=0; +REALTYPE *jackoutl, *jackoutr; +int jackfinish = 0; void *thread_blocked(void *arg); -int jackprocess(jack_nframes_t nframes,void *arg); -int jacksrate(jack_nframes_t nframes,void *arg); +int jackprocess(jack_nframes_t nframes, void *arg); +int jacksrate(jack_nframes_t nframes, void *arg); void jackshutdown(void *arg); -pthread_cond_t more_data=PTHREAD_COND_INITIALIZER; -pthread_mutex_t zyn_thread_lock=PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t more_data = PTHREAD_COND_INITIALIZER; +pthread_mutex_t zyn_thread_lock = PTHREAD_MUTEX_INITIALIZER; pthread_t bthr; bool JACKaudiooutputinit(Master *master_) { - jackmaster=master_; - jackclient=0; + jackmaster = master_; + jackclient = 0; char tmpstr[100]; - jackoutl=new REALTYPE [SOUND_BUFFER_SIZE]; - jackoutr=new REALTYPE [SOUND_BUFFER_SIZE]; - - int rbbufsize=SOUND_BUFFER_SIZE*sizeof (REALTYPE)*2*2; - printf("%d\n",rbbufsize); - rb=jack_ringbuffer_create(rbbufsize); - for (int i=0;i<rbbufsize;i++) rb->buf[i]=0.0; - - - for (int i=0;i<15;i++) { - if (i!=0) snprintf(tmpstr,100,"ZynAddSubFX_%d",i); - else snprintf(tmpstr,100,"ZynAddSubFX"); - jackclient=jack_client_new(tmpstr); - if (jackclient!=0) break; - }; - - if (jackclient==0) { - fprintf(stderr,"\nERROR: Cannot make a jack client (possible reasons: JACK server is not running or jackd is launched by root and zynaddsubfx by another user.).\n\n\n"); - return(false); - }; - - fprintf(stderr,"Internal SampleRate = %d\nJack Output SampleRate= %d\n",SAMPLE_RATE,jack_get_sample_rate(jackclient)); - if ((unsigned int)jack_get_sample_rate(jackclient)!=(unsigned int) SAMPLE_RATE) - fprintf(stderr,"It is recomanded that the both samplerates to be equal.\n"); - - jack_set_process_callback(jackclient,jackprocess,0); - jack_set_sample_rate_callback(jackclient,jacksrate,0); - jack_on_shutdown(jackclient,jackshutdown,0); - - outport_left=jack_port_register(jackclient,"out_1", - JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput|JackPortIsTerminal,0); - outport_right=jack_port_register(jackclient,"out_2", - JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput|JackPortIsTerminal,0); - - if (jack_activate(jackclient)) { - fprintf(stderr,"Cannot activate jack client\n"); - return(false); - }; - - pthread_create(&bthr,NULL,thread_blocked,NULL); + jackoutl = new REALTYPE [SOUND_BUFFER_SIZE]; + jackoutr = new REALTYPE [SOUND_BUFFER_SIZE]; + + int rbbufsize = SOUND_BUFFER_SIZE * sizeof(REALTYPE) * 2 * 2; + printf("%d\n", rbbufsize); + rb = jack_ringbuffer_create(rbbufsize); + for(int i = 0; i < rbbufsize; i++) + rb->buf[i] = 0.0; + + + for(int i = 0; i < 15; i++) { + if(i != 0) + snprintf(tmpstr, 100, "ZynAddSubFX_%d", i); + else + snprintf(tmpstr, 100, "ZynAddSubFX"); + jackclient = jack_client_new(tmpstr); + if(jackclient != 0) + break; + } + + if(jackclient == 0) { + fprintf( + stderr, + "\nERROR: Cannot make a jack client (possible reasons: JACK server is not running or jackd is launched by root and zynaddsubfx by another user.).\n\n\n"); + return false; + } + + fprintf(stderr, + "Internal SampleRate = %d\nJack Output SampleRate= %d\n", + SAMPLE_RATE, + jack_get_sample_rate(jackclient)); + if((unsigned int)jack_get_sample_rate(jackclient) != + (unsigned int) SAMPLE_RATE) + fprintf(stderr, + "It is recomanded that the both samplerates to be equal.\n"); + + jack_set_process_callback(jackclient, jackprocess, 0); + jack_set_sample_rate_callback(jackclient, jacksrate, 0); + jack_on_shutdown(jackclient, jackshutdown, 0); + + outport_left = jack_port_register(jackclient, + "out_1", + JACK_DEFAULT_AUDIO_TYPE, + JackPortIsOutput | JackPortIsTerminal, + 0); + outport_right = jack_port_register(jackclient, + "out_2", + JACK_DEFAULT_AUDIO_TYPE, + JackPortIsOutput | JackPortIsTerminal, + 0); + + if(jack_activate(jackclient)) { + fprintf(stderr, "Cannot activate jack client\n"); + return false; + } + + pthread_create(&bthr, NULL, thread_blocked, NULL); /* jack_connect(jackclient,jack_port_name(outport_left),"alsa_pcm:out_1"); jack_connect(jackclient,jack_port_name(outport_right),"alsa_pcm:out_2"); */ - return(true); -}; + return true; +} void *thread_blocked(void *arg) { - int datasize=SOUND_BUFFER_SIZE*sizeof (REALTYPE); + int datasize = SOUND_BUFFER_SIZE * sizeof(REALTYPE); //try to get realtime sched_param sc; - sc.sched_priority=50; - int err=sched_setscheduler(0,SCHED_FIFO,&sc); + sc.sched_priority = 50; + int err = sched_setscheduler(0, SCHED_FIFO, &sc); - pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); pthread_mutex_lock(&zyn_thread_lock); - while (jackfinish==0) { - while (jack_ringbuffer_write_space(rb)>=datasize) { + while(jackfinish == 0) { + while(jack_ringbuffer_write_space(rb) >= datasize) { pthread_mutex_lock(&jackmaster->mutex); - jackmaster->GetAudioOutSamples(SOUND_BUFFER_SIZE,jack_get_sample_rate(jackclient),jackoutl,jackoutr); + jackmaster->GetAudioOutSamples(SOUND_BUFFER_SIZE, + jack_get_sample_rate(jackclient), + jackoutl, + jackoutr); pthread_mutex_unlock(&jackmaster->mutex); - jack_ringbuffer_write(rb, (char *) jackoutl,datasize); - jack_ringbuffer_write(rb, (char *) jackoutr,datasize); - }; - pthread_cond_wait(&more_data,&zyn_thread_lock); - }; + jack_ringbuffer_write(rb, (char *) jackoutl, datasize); + jack_ringbuffer_write(rb, (char *) jackoutr, datasize); + } + pthread_cond_wait(&more_data, &zyn_thread_lock); + } pthread_mutex_unlock(&zyn_thread_lock); - return(0); -}; + return 0; +} -int jackprocess(jack_nframes_t nframes,void *arg) +int jackprocess(jack_nframes_t nframes, void *arg) { - jack_default_audio_sample_t *outl=(jack_default_audio_sample_t *) jack_port_get_buffer (outport_left, nframes); - jack_default_audio_sample_t *outr=(jack_default_audio_sample_t *) jack_port_get_buffer (outport_right, nframes); - - int datasize=nframes*sizeof (REALTYPE); - int incoming_datasize=SOUND_BUFFER_SIZE*sizeof (REALTYPE); - int data_read=0; - - - if (jack_ringbuffer_read_space(rb)>=(2*incoming_datasize)) { - if (datasize>incoming_datasize) { - data_read=0; - while (data_read < datasize) { - jack_ringbuffer_read(rb, (char *) outl+data_read,datasize); - jack_ringbuffer_read(rb, (char *) outr+data_read,datasize); - data_read+=incoming_datasize; - }; - } else if (datasize==incoming_datasize) { - jack_ringbuffer_read(rb, (char *) outl,datasize); - jack_ringbuffer_read(rb, (char *) outr,datasize); - } else { - }; - } else {//the ringbuffer is empty or there are too small amount of samples in it - for (int i=0;i<nframes;i++) { - outl[i]=0.0; - outr[i]=0.0; - }; - }; + jack_default_audio_sample_t *outl = + (jack_default_audio_sample_t *) jack_port_get_buffer(outport_left, + nframes); + jack_default_audio_sample_t *outr = + (jack_default_audio_sample_t *) jack_port_get_buffer(outport_right, + nframes); + + int datasize = nframes * sizeof(REALTYPE); + int incoming_datasize = SOUND_BUFFER_SIZE * sizeof(REALTYPE); + int data_read = 0; + + + if(jack_ringbuffer_read_space(rb) >= (2 * incoming_datasize)) { + if(datasize > incoming_datasize) { + data_read = 0; + while(data_read < datasize) { + jack_ringbuffer_read(rb, (char *) outl + data_read, datasize); + jack_ringbuffer_read(rb, (char *) outr + data_read, datasize); + data_read += incoming_datasize; + } + } + else + if(datasize == incoming_datasize) { + jack_ringbuffer_read(rb, (char *) outl, datasize); + jack_ringbuffer_read(rb, (char *) outr, datasize); + } + else {} + } + else { //the ringbuffer is empty or there are too small amount of samples in it + for(int i = 0; i < nframes; i++) { + outl[i] = 0.0; + outr[i] = 0.0; + } + } /* if (jack_ringbuffer_read_space(rb)>=datasize){ - jack_ringbuffer_read(rb, (char *) outl,datasize); - jack_ringbuffer_read(rb, (char *) outr,datasize); + jack_ringbuffer_read(rb, (char *) outl,datasize); + jack_ringbuffer_read(rb, (char *) outr,datasize); } else {//the ringbuffer is empty or there are too small amount of samples in it - for (int i=0;i<nframes;i++){ - outl[i]=0.0;outr[i]=0.0; - }; + for (int i=0;i<nframes;i++){ + outl[i]=0.0;outr[i]=0.0; + }; }; */ - if (pthread_mutex_trylock(&zyn_thread_lock)==0) { + if(pthread_mutex_trylock(&zyn_thread_lock) == 0) { pthread_cond_signal(&more_data); pthread_mutex_unlock(&zyn_thread_lock); - }; + } - return(0); -}; + return 0; +} void JACKfinish() { - jackfinish=1; + jackfinish = 1; jack_ringbuffer_free(rb); jack_client_close(jackclient); usleep(100000); - delete(jackoutl); - delete(jackoutr); -}; + delete (jackoutl); + delete (jackoutr); +} -int jacksrate(jack_nframes_t nframes,void *arg) +int jacksrate(jack_nframes_t nframes, void *arg) { - - return(0); -}; + return 0; +} void jackshutdown(void *arg) -{ -}; - - +{} diff --git a/src/Output/JACKaudiooutput.cpp b/src/Output/JACKaudiooutput.cpp @@ -27,110 +27,132 @@ Master *jackmaster; jack_client_t *jackclient; char jackname[100]; -jack_port_t *outport_left,*outport_right,*midi_inport; +jack_port_t *outport_left, *outport_right, *midi_inport; -int jackprocess(jack_nframes_t nframes,void *arg); -int jacksrate(jack_nframes_t nframes,void *arg); +int jackprocess(jack_nframes_t nframes, void *arg); +int jacksrate(jack_nframes_t nframes, void *arg); void jackshutdown(void *arg); bool JACKaudiooutputinit(Master *master_) { - jackmaster=master_; - jackclient=0; - - for (int i=0;i<15;i++) { - if (i!=0) snprintf(jackname,100,"ZynAddSubFX_%d",i); - else snprintf(jackname,100,"ZynAddSubFX"); - jackclient=jack_client_new(jackname); - if (jackclient!=0) break; - }; - - if (jackclient==0) { - fprintf(stderr,"\nERROR: Cannot make a jack client (possible reasons: JACK server is not running or jackd is launched by root and zynaddsubfx by another user.).\n"); - return(false); - }; - - fprintf(stderr,"Internal SampleRate = %d\nJack Output SampleRate= %d\n",SAMPLE_RATE,jack_get_sample_rate(jackclient)); - if ((unsigned int)jack_get_sample_rate(jackclient)!=(unsigned int) SAMPLE_RATE) - fprintf(stderr,"It is recomanded that the both samplerates to be equal.\n"); - - jack_set_process_callback(jackclient,jackprocess,0); - jack_set_sample_rate_callback(jackclient,jacksrate,0); - jack_on_shutdown(jackclient,jackshutdown,0); - - outport_left=jack_port_register(jackclient,"out_1", - JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput|JackPortIsTerminal,0); - outport_right=jack_port_register(jackclient,"out_2", - JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput|JackPortIsTerminal,0); - midi_inport=jack_port_register(jackclient,"midi_input", - JACK_DEFAULT_MIDI_TYPE,JackPortIsInput|JackPortIsTerminal,0); - - if (jack_activate(jackclient)) { - fprintf(stderr,"Cannot activate jack client\n"); - return(false); - }; + jackmaster = master_; + jackclient = 0; + + for(int i = 0; i < 15; i++) { + if(i != 0) + snprintf(jackname, 100, "ZynAddSubFX_%d", i); + else + snprintf(jackname, 100, "ZynAddSubFX"); + jackclient = jack_client_new(jackname); + if(jackclient != 0) + break; + } + + if(jackclient == 0) { + fprintf( + stderr, + "\nERROR: Cannot make a jack client (possible reasons: JACK server is not running or jackd is launched by root and zynaddsubfx by another user.).\n"); + return false; + } + + fprintf(stderr, + "Internal SampleRate = %d\nJack Output SampleRate= %d\n", + SAMPLE_RATE, + jack_get_sample_rate(jackclient)); + if((unsigned int)jack_get_sample_rate(jackclient) != + (unsigned int) SAMPLE_RATE) + fprintf(stderr, + "It is recomanded that the both samplerates to be equal.\n"); + + jack_set_process_callback(jackclient, jackprocess, 0); + jack_set_sample_rate_callback(jackclient, jacksrate, 0); + jack_on_shutdown(jackclient, jackshutdown, 0); + + outport_left = jack_port_register(jackclient, + "out_1", + JACK_DEFAULT_AUDIO_TYPE, + JackPortIsOutput | JackPortIsTerminal, + 0); + outport_right = jack_port_register(jackclient, + "out_2", + JACK_DEFAULT_AUDIO_TYPE, + JackPortIsOutput | JackPortIsTerminal, + 0); + midi_inport = jack_port_register(jackclient, + "midi_input", + JACK_DEFAULT_MIDI_TYPE, + JackPortIsInput | JackPortIsTerminal, + 0); + + if(jack_activate(jackclient)) { + fprintf(stderr, "Cannot activate jack client\n"); + return false; + } /* jack_connect(jackclient,jack_port_name(outport_left),"alsa_pcm:out_1"); jack_connect(jackclient,jack_port_name(outport_right),"alsa_pcm:out_2"); */ - return(true); -}; + return true; +} -int jackprocess(jack_nframes_t nframes,void *arg) +int jackprocess(jack_nframes_t nframes, void *arg) { - jack_default_audio_sample_t *outl=(jack_default_audio_sample_t *) jack_port_get_buffer (outport_left, nframes); - jack_default_audio_sample_t *outr=(jack_default_audio_sample_t *) jack_port_get_buffer (outport_right, nframes); - - if (!pthread_mutex_trylock(&jackmaster->mutex)) { + jack_default_audio_sample_t *outl = + (jack_default_audio_sample_t *) jack_port_get_buffer(outport_left, + nframes); + jack_default_audio_sample_t *outr = + (jack_default_audio_sample_t *) jack_port_get_buffer(outport_right, + nframes); + + if(!pthread_mutex_trylock(&jackmaster->mutex)) { JACKhandlemidi(nframes); - jackmaster->GetAudioOutSamples(nframes,jack_get_sample_rate(jackclient),outl,outr); + jackmaster->GetAudioOutSamples(nframes, jack_get_sample_rate( + jackclient), outl, outr); pthread_mutex_unlock(&jackmaster->mutex); - } else { + } + else { memset(outl, 0, sizeof(jack_default_audio_sample_t) * nframes); memset(outr, 0, sizeof(jack_default_audio_sample_t) * nframes); } - return(0); -}; + return 0; +} void JACKfinish() { jack_client_close(jackclient); -}; +} -int jacksrate(jack_nframes_t nframes,void *arg) +int jacksrate(jack_nframes_t nframes, void *arg) { - - return(0); -}; + return 0; +} void jackshutdown(void *arg) -{ -}; +{} void JACKhandlemidi(unsigned long frames) { - // We must have the master mutex before we run this function // XXX This is really nasty, not only do we lose the sample accuracy of // JACK MIDI, but any accuracy at all below the buffer size - void* midi_buf = jack_port_get_buffer(midi_inport, frames); + void *midi_buf = jack_port_get_buffer(midi_inport, frames); jack_midi_event_t jack_midi_event; - jack_nframes_t event_index = 0; - unsigned char* midi_data; - unsigned char type, chan; + jack_nframes_t event_index = 0; + unsigned char *midi_data; + unsigned char type, chan; - while (jack_midi_event_get(&jack_midi_event,midi_buf, event_index++) == 0) { + while(jack_midi_event_get(&jack_midi_event, midi_buf, + event_index++) == 0) { midi_data = jack_midi_event.buffer; - type = midi_data[0] & 0xF0; - chan = midi_data[0] & 0x0F; - - switch (type) { + type = midi_data[0] & 0xF0; + chan = midi_data[0] & 0x0F; + switch(type) { case 0x80: /* note-off */ jackmaster->NoteOff(chan, midi_data[1]); break; @@ -151,13 +173,13 @@ void JACKhandlemidi(unsigned long frames) /* XXX TODO: handle MSB/LSB controllers and RPNs and NRPNs */ } } - } -const char* JACKgetname() +const char *JACKgetname() { - if (jackclient != NULL) + if(jackclient != NULL) return jackname; return NULL; } + diff --git a/src/Output/JACKaudiooutput.h b/src/Output/JACKaudiooutput.h @@ -28,11 +28,12 @@ #include "../Misc/Master.h" -#if (REALTYPE!=jack_default_audio_sample_t) -#error "The internal sample datatype of ZynAddSubFX and the datatype of jack differs.\ - In order to compile ZynAddSubFX the 'REALTYPE' and 'jack_default_audio_sample_t' must be equal.\ - Set the 'REALTYPE' data type (which is defined in 'globals.h') to what is defined \ - in the file types.h from jack include directory as 'jack_default_audio_sample_t' (as float or double)." +#if (REALTYPE != jack_default_audio_sample_t) +#error \ + "The internal sample datatype of ZynAddSubFX and the datatype of jack differs. \ + In order to compile ZynAddSubFX the 'REALTYPE' and 'jack_default_audio_sample_t' must be equal. \ + Set the 'REALTYPE' data type (which is defined in 'globals.h') to what is defined \ + in the file types.h from jack include directory as 'jack_default_audio_sample_t' (as float or double)." #endif @@ -41,7 +42,7 @@ bool JACKaudiooutputinit(Master *master_); void JACKfinish(); void JACKhandlemidi(unsigned long frames); -const char* JACKgetname(); +const char *JACKgetname(); #endif diff --git a/src/Output/OSSaudiooutput.cpp b/src/Output/OSSaudiooutput.cpp @@ -37,86 +37,92 @@ using namespace std; OSSaudiooutput::OSSaudiooutput() { int i; - int snd_bitsize=16; - snd_fragment=0x00080009;//fragment size (?) - snd_stereo=1;//stereo - snd_format=AFMT_S16_LE; - snd_samplerate=SAMPLE_RATE; - playing_until.tv_sec=0; - playing_until.tv_usec=0; - - smps=new short int[SOUND_BUFFER_SIZE*2]; - for (i=0;i<SOUND_BUFFER_SIZE*2;i++) smps[i]=0; - - snd_handle=open(config.cfg.LinuxOSSWaveOutDev,O_WRONLY,0); - if (snd_handle == -1) { + int snd_bitsize = 16; + snd_fragment = 0x00080009; //fragment size (?) + snd_stereo = 1; //stereo + snd_format = AFMT_S16_LE; + snd_samplerate = SAMPLE_RATE; + playing_until.tv_sec = 0; + playing_until.tv_usec = 0; + + smps = new short int[SOUND_BUFFER_SIZE * 2]; + for(i = 0; i < SOUND_BUFFER_SIZE * 2; i++) + smps[i] = 0; + + snd_handle = open(config.cfg.LinuxOSSWaveOutDev, O_WRONLY, 0); + if(snd_handle == -1) { cerr << "ERROR - I can't open the "; - cerr << config.cfg.LinuxOSSWaveOutDev << '.'<< endl; + cerr << config.cfg.LinuxOSSWaveOutDev << '.' << endl; return; - }; - ioctl(snd_handle,SNDCTL_DSP_RESET,NULL); - - ioctl(snd_handle,SNDCTL_DSP_SETFMT,&snd_format); - ioctl(snd_handle,SNDCTL_DSP_STEREO,&snd_stereo); - ioctl(snd_handle,SNDCTL_DSP_SPEED,&snd_samplerate); - ioctl(snd_handle,SNDCTL_DSP_SAMPLESIZE,&snd_bitsize); - ioctl(snd_handle,SNDCTL_DSP_SETFRAGMENT,&snd_fragment); + } + ioctl(snd_handle, SNDCTL_DSP_RESET, NULL); -}; + ioctl(snd_handle, SNDCTL_DSP_SETFMT, &snd_format); + ioctl(snd_handle, SNDCTL_DSP_STEREO, &snd_stereo); + ioctl(snd_handle, SNDCTL_DSP_SPEED, &snd_samplerate); + ioctl(snd_handle, SNDCTL_DSP_SAMPLESIZE, &snd_bitsize); + ioctl(snd_handle, SNDCTL_DSP_SETFRAGMENT, &snd_fragment); +} /* * Output the samples to the soundcard * The samples are bigger than -1.0 and smaller 1.0 */ -void OSSaudiooutput::OSSout(REALTYPE *smp_left,REALTYPE *smp_right) +void OSSaudiooutput::OSSout(REALTYPE *smp_left, REALTYPE *smp_right) { - int i; - REALTYPE l,r; - if (snd_handle < 0) { //output could not be opened + int i; + REALTYPE l, r; + if(snd_handle < 0) { //output could not be opened struct timeval now; int remaining; gettimeofday(&now, NULL); - if((playing_until.tv_usec==0)&&(playing_until.tv_sec==0)) { + if((playing_until.tv_usec == 0) && (playing_until.tv_sec == 0)) { playing_until.tv_usec = now.tv_usec; playing_until.tv_sec = now.tv_sec; } - else { + else { remaining = (playing_until.tv_usec - now.tv_usec) - + (playing_until.tv_sec - now.tv_sec)*1000000; + + (playing_until.tv_sec - now.tv_sec) * 1000000; if(remaining > 10000) //Don't sleep() less than 10ms. //This will add latency... - usleep(remaining-10000); + usleep(remaining - 10000); if(remaining < 0) cerr << "WARNING - too late" << endl; } - playing_until.tv_usec += SOUND_BUFFER_SIZE*1000000/SAMPLE_RATE; + playing_until.tv_usec += SOUND_BUFFER_SIZE * 1000000 / SAMPLE_RATE; if(remaining < 0) playing_until.tv_usec -= remaining; - playing_until.tv_sec += playing_until.tv_usec/1000000; + playing_until.tv_sec += playing_until.tv_usec / 1000000; playing_until.tv_usec %= 1000000; return; } - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - l=smp_left[i]; - r=smp_right[i]; - - if (l<-1.0) l=-1.0; - else if (l>1.0) l=1.0; - if (r<-1.0) r=-1.0; - else if (r>1.0) r=1.0; - - smps[i*2]=(short int) (l*32767.0); - smps[i*2+1]=(short int) (r*32767.0); - }; - write(snd_handle,smps,SOUND_BUFFER_SIZE*4);// *2 because is 16 bit, again * 2 because is stereo -}; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + l = smp_left[i]; + r = smp_right[i]; + + if(l < -1.0) + l = -1.0; + else + if(l > 1.0) + l = 1.0; + if(r < -1.0) + r = -1.0; + else + if(r > 1.0) + r = 1.0; + + smps[i * 2] = (short int) (l * 32767.0); + smps[i * 2 + 1] = (short int) (r * 32767.0); + } + write(snd_handle, smps, SOUND_BUFFER_SIZE * 4); // *2 because is 16 bit, again * 2 because is stereo +} OSSaudiooutput::~OSSaudiooutput() { close(snd_handle); delete [] smps; -}; +} diff --git a/src/Output/OSSaudiooutput.h b/src/Output/OSSaudiooutput.h @@ -28,22 +28,22 @@ class OSSaudiooutput { -public: - OSSaudiooutput(); - ~OSSaudiooutput(); - - //the out is [-1.0 .. 1.0] - /* smp_left[] and smp_right[] has the size of SOUND_BUFFER_SIZE */ - void OSSout(REALTYPE *smp_left,REALTYPE *smp_right); -private: - int snd_handle; - int snd_fragment; - int snd_stereo; - int snd_format; - int snd_samplerate; - struct timeval playing_until; - - short int *smps;//Samples to be sent to soundcard + public: + OSSaudiooutput(); + ~OSSaudiooutput(); + + //the out is [-1.0 .. 1.0] + /* smp_left[] and smp_right[] has the size of SOUND_BUFFER_SIZE */ + void OSSout(REALTYPE *smp_left, REALTYPE *smp_right); + private: + int snd_handle; + int snd_fragment; + int snd_stereo; + int snd_format; + int snd_samplerate; + struct timeval playing_until; + + short int *smps; //Samples to be sent to soundcard }; #endif diff --git a/src/Output/PAaudiooutput.cpp b/src/Output/PAaudiooutput.cpp @@ -22,52 +22,59 @@ #include "PAaudiooutput.h" -Master *PAmaster; +Master *PAmaster; PaStream *stream; -REALTYPE *outl,*outr; +REALTYPE *outl, *outr; -int PAprocess(void *inputBuffer,void *outputBuffer, +int PAprocess(void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, - PaTimestamp outTime,void *userData) + PaTimestamp outTime, void *userData) { - - if (framesPerBuffer!=SOUND_BUFFER_SIZE) { - fprintf(stderr,"Bug: PAudioOutput::PAprocess SOUND_BUFFER_SIZE!=framesPerBuffer"); - fprintf(stderr,"%d %d\n",framesPerBuffer,SOUND_BUFFER_SIZE); - }; + if(framesPerBuffer != SOUND_BUFFER_SIZE) { + fprintf( + stderr, + "Bug: PAudioOutput::PAprocess SOUND_BUFFER_SIZE!=framesPerBuffer"); + fprintf(stderr, "%d %d\n", framesPerBuffer, SOUND_BUFFER_SIZE); + } pthread_mutex_lock(&PAmaster->mutex); - PAmaster->GetAudioOutSamples(SOUND_BUFFER_SIZE,SAMPLE_RATE,outl,outr); + PAmaster->GetAudioOutSamples(SOUND_BUFFER_SIZE, SAMPLE_RATE, outl, outr); pthread_mutex_unlock(&PAmaster->mutex); - float *out=(float *)outputBuffer; + float *out = (float *)outputBuffer; - for (int i=0;i<framesPerBuffer;i++) { - if (i>=SOUND_BUFFER_SIZE) break;//this should never happens, except only when framesPerBuffer!>SOUND_BUFFER_SIZE - out[i*2]=outl[i]; - out[i*2+1]=outr[i]; - }; + for(int i = 0; i < framesPerBuffer; i++) { + if(i >= SOUND_BUFFER_SIZE) + break; //this should never happens, except only when framesPerBuffer!>SOUND_BUFFER_SIZE + out[i * 2] = outl[i]; + out[i * 2 + 1] = outr[i]; + } - return(0); -}; + return 0; +} void PAaudiooutputinit(Master *master_) { - PAmaster=master_; - outl=new REALTYPE [SOUND_BUFFER_SIZE]; - outr=new REALTYPE [SOUND_BUFFER_SIZE]; + PAmaster = master_; + outl = new REALTYPE [SOUND_BUFFER_SIZE]; + outr = new REALTYPE [SOUND_BUFFER_SIZE]; Pa_Initialize(); - Pa_OpenDefaultStream(&stream,0,2,paFloat32,SAMPLE_RATE,SOUND_BUFFER_SIZE,0,PAprocess,NULL); + Pa_OpenDefaultStream(&stream, + 0, + 2, + paFloat32, + SAMPLE_RATE, + SOUND_BUFFER_SIZE, + 0, + PAprocess, + NULL); Pa_StartStream(stream); -}; +} void PAfinish() { Pa_StopStream(stream); delete (outl); delete (outr); -}; - - - +} diff --git a/src/Output/Recorder.cpp b/src/Output/Recorder.cpp @@ -25,80 +25,89 @@ Recorder::Recorder() { - recordbuf_16bit=new short int [SOUND_BUFFER_SIZE*2]; - status=0; - notetrigger=0; - for (int i=0;i<SOUND_BUFFER_SIZE*2;i++) { - recordbuf_16bit[i]=0; - } -}; + recordbuf_16bit = new short int [SOUND_BUFFER_SIZE * 2]; + status = 0; + notetrigger = 0; + for(int i = 0; i < SOUND_BUFFER_SIZE * 2; i++) + recordbuf_16bit[i] = 0; +} Recorder::~Recorder() { - if (recording()==1) stop(); + if(recording() == 1) + stop(); delete [] recordbuf_16bit; -}; +} -int Recorder::preparefile(std::string filename_,int overwrite) +int Recorder::preparefile(std::string filename_, int overwrite) { - if (!overwrite) { + if(!overwrite) { struct stat fileinfo; int statr; - statr = stat(filename_.c_str(),&fileinfo); - if (statr == 0) {//file exists + statr = stat(filename_.c_str(), &fileinfo); + if(statr == 0) //file exists return 1; - } } - if (!wav.newfile(filename_, SAMPLE_RATE,2)) return 2; + if(!wav.newfile(filename_, SAMPLE_RATE, 2)) + return 2; - status=1;//ready + status = 1; //ready - return(0); -}; + return 0; +} void Recorder::start() { - notetrigger=0; - status=2;//recording -}; + notetrigger = 0; + status = 2; //recording +} void Recorder::stop() { wav.close(); - status=0; -}; + status = 0; +} void Recorder::pause() { - status=0; -}; + status = 0; +} int Recorder::recording() { - if ((status==2)&&(notetrigger!=0)) return(1); - else return(0); -}; + if((status == 2) && (notetrigger != 0)) + return 1; + else + return 0; +} -void Recorder::recordbuffer(REALTYPE *outl,REALTYPE *outr) +void Recorder::recordbuffer(REALTYPE *outl, REALTYPE *outr) { int tmp; - if (status!=2) return; - for (int i=0;i<SOUND_BUFFER_SIZE;i++) { - tmp=(int)(outl[i]*32767.0); - if (tmp<-32768) tmp=-32768; - if (tmp>32767) tmp=32767; - recordbuf_16bit[i*2]=tmp; - - tmp=(int)(outr[i]*32767.0); - if (tmp<-32768) tmp=-32768; - if (tmp>32767) tmp=32767; - recordbuf_16bit[i*2+1]=tmp; - }; - wav.write_stereo_samples(SOUND_BUFFER_SIZE,recordbuf_16bit); -}; + if(status != 2) + return; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + tmp = (int)(outl[i] * 32767.0); + if(tmp < -32768) + tmp = -32768; + if(tmp > 32767) + tmp = 32767; + recordbuf_16bit[i * 2] = tmp; + + tmp = (int)(outr[i] * 32767.0); + if(tmp < -32768) + tmp = -32768; + if(tmp > 32767) + tmp = 32767; + recordbuf_16bit[i * 2 + 1] = tmp; + } + wav.write_stereo_samples(SOUND_BUFFER_SIZE, recordbuf_16bit); +} void Recorder::triggernow() { - if (status==2) notetrigger=1; -}; + if(status == 2) + notetrigger = 1; +} + diff --git a/src/Output/Recorder.h b/src/Output/Recorder.h @@ -29,28 +29,29 @@ /**Records sound to a file*/ class Recorder { -public: - - Recorder(); - ~Recorder(); - int preparefile(std::string filename_,int overwrite);//returns 1 if the file exists - void start(); - void stop(); - void pause(); - int recording(); - void triggernow(); - void recordbuffer(REALTYPE *outl,REALTYPE *outr); - - /** Status: - * 0 - not ready(no file selected), - * 1 - ready - * 2 - recording */ - int status; - -private: - WAVaudiooutput wav; - short int *recordbuf_16bit; - int notetrigger; + public: + + Recorder(); + ~Recorder(); + int preparefile(std::string filename_, int overwrite); //returns 1 if the file exists + void start(); + void stop(); + void pause(); + int recording(); + void triggernow(); + void recordbuffer(REALTYPE *outl, REALTYPE *outr); + + /** Status: + * 0 - not ready(no file selected), + * 1 - ready + * 2 - recording */ + int status; + + private: + WAVaudiooutput wav; + short int *recordbuf_16bit; + int notetrigger; }; #endif + diff --git a/src/Output/VSTaudiooutput.cpp b/src/Output/VSTaudiooutput.cpp @@ -24,42 +24,45 @@ //the constructor and the destructor are defined in main.C -void VSTSynth::process (float **inputs, float **outputs, long sampleframes) +void VSTSynth::process(float **inputs, float **outputs, long sampleframes) { - float *outl=outputs[0]; - float *outr=outputs[1]; + float *outl = outputs[0]; + float *outr = outputs[1]; pthread_mutex_lock(&vmaster->mutex); - vmaster->GetAudioOutSamples(sampleframes,(int) getSampleRate(),outl,outr); + vmaster->GetAudioOutSamples(sampleframes, (int) getSampleRate(), outl, outr); pthread_mutex_unlock(&vmaster->mutex); -}; +} -void VSTSynth::processReplacing (float **inputs, float **outputs, long sampleframes) +void VSTSynth::processReplacing(float **inputs, + float **outputs, + long sampleframes) { - process(inputs,outputs,sampleframes); -}; + process(inputs, outputs, sampleframes); +} long int VSTSynth::canDo(char *txt) { - if (strcmp(txt,"receiveVstEvents")==0) return (1); - if (strcmp(txt,"receiveVstMidiEvent")==0) return (1); - return(-1); -}; + if(strcmp(txt, "receiveVstEvents") == 0) + return 1; + if(strcmp(txt, "receiveVstMidiEvent") == 0) + return 1; + return -1; +} bool VSTSynth::getVendorString(char *txt) { - strcpy(txt,"Nasca O. Paul"); - return(true); -}; + strcpy(txt, "Nasca O. Paul"); + return true; +} bool VSTSynth::getProductString(char *txt) { - strcpy(txt,"ZynAddSubFX"); - return(true); -}; + strcpy(txt, "ZynAddSubFX"); + return true; +} void VSTSynth::resume() { wantEvents(); -}; - +} diff --git a/src/Output/VSTaudiooutput.h b/src/Output/VSTaudiooutput.h @@ -32,26 +32,28 @@ class VSTSynth:public AudioEffectX { -public: - VSTSynth (audioMasterCallback audioMaster); - ~VSTSynth(); - - virtual void process (float **inputs, float **outputs, long sampleframes); - virtual void processReplacing (float **inputs, float **outputs, long sampleframes); - virtual long processEvents(VstEvents *events);//this is used for Midi input - virtual long int canDo(char *txt); - virtual bool getVendorString(char *txt); - virtual bool getProductString(char *txt); - virtual void resume(); - - virtual long getChunk(void** data,bool isPreset=false); - virtual long setChunk(void *data,long size,bool isPreset=false); - - MasterUI *ui; - int Pexitprogram; - - Master *vmaster; - pthread_t thr; + public: + VSTSynth(audioMasterCallback audioMaster); + ~VSTSynth(); + + virtual void process(float **inputs, float **outputs, long sampleframes); + virtual void processReplacing(float **inputs, + float **outputs, + long sampleframes); + virtual long processEvents(VstEvents *events); //this is used for Midi input + virtual long int canDo(char *txt); + virtual bool getVendorString(char *txt); + virtual bool getProductString(char *txt); + virtual void resume(); + + virtual long getChunk(void **data, bool isPreset = false); + virtual long setChunk(void *data, long size, bool isPreset = false); + + MasterUI *ui; + int Pexitprogram; + + Master *vmaster; + pthread_t thr; }; #endif diff --git a/src/Output/WAVaudiooutput.cpp b/src/Output/WAVaudiooutput.cpp @@ -23,77 +23,79 @@ using namespace std; WAVaudiooutput::WAVaudiooutput() { - file=NULL; - sampleswritten=0; - samplerate=44100; -}; + file = NULL; + sampleswritten = 0; + samplerate = 44100; +} WAVaudiooutput::~WAVaudiooutput() { close(); -}; +} -bool WAVaudiooutput::newfile(string filename,int samplerate,int channels) +bool WAVaudiooutput::newfile(string filename, int samplerate, int channels) { /**\todo Move this into the Constructor*/ - close();//inchide un posibil fisier existent - file=fopen(filename.c_str(),"w"); - if (!file) return false; - this->samplerate=samplerate; - this->channels=channels; - sampleswritten=0; + close(); //inchide un posibil fisier existent + file = fopen(filename.c_str(), "w"); + if(!file) + return false; + this->samplerate = samplerate; + this->channels = channels; + sampleswritten = 0; char tmp[44]; - fwrite(tmp,1,44,file); - return(true); -}; + fwrite(tmp, 1, 44, file); + return true; +} void WAVaudiooutput::close() { - if (file) { + if(file) { unsigned int chunksize; rewind(file); - fwrite("RIFF",4,1,file); - chunksize=sampleswritten*4+36; - fwrite(&chunksize,4,1,file); - - fwrite("WAVEfmt ",8,1,file); - chunksize=16; - fwrite(&chunksize,4,1,file); - unsigned short int formattag=1;//uncompresed wave - fwrite(&formattag,2,1,file); - unsigned short int nchannels=channels;//stereo - fwrite(&nchannels,2,1,file); - unsigned int samplerate_=samplerate;//samplerate - fwrite(&samplerate_,4,1,file); - unsigned int bytespersec=samplerate*2*channels;//bytes/sec - fwrite(&bytespersec,4,1,file); - unsigned short int blockalign=2*channels;//2 channels * 16 bits/8 - fwrite(&blockalign,2,1,file); - unsigned short int bitspersample=16; - fwrite(&bitspersample,2,1,file); - - fwrite("data",4,1,file); - chunksize=sampleswritten*blockalign; - fwrite(&chunksize,4,1,file); + fwrite("RIFF", 4, 1, file); + chunksize = sampleswritten * 4 + 36; + fwrite(&chunksize, 4, 1, file); + + fwrite("WAVEfmt ", 8, 1, file); + chunksize = 16; + fwrite(&chunksize, 4, 1, file); + unsigned short int formattag = 1; //uncompresed wave + fwrite(&formattag, 2, 1, file); + unsigned short int nchannels = channels; //stereo + fwrite(&nchannels, 2, 1, file); + unsigned int samplerate_ = samplerate; //samplerate + fwrite(&samplerate_, 4, 1, file); + unsigned int bytespersec = samplerate * 2 * channels; //bytes/sec + fwrite(&bytespersec, 4, 1, file); + unsigned short int blockalign = 2 * channels; //2 channels * 16 bits/8 + fwrite(&blockalign, 2, 1, file); + unsigned short int bitspersample = 16; + fwrite(&bitspersample, 2, 1, file); + + fwrite("data", 4, 1, file); + chunksize = sampleswritten * blockalign; + fwrite(&chunksize, 4, 1, file); fclose(file); - file=NULL; + file = NULL; } -}; +} -void WAVaudiooutput::write_stereo_samples(int nsmps,short int *smps) +void WAVaudiooutput::write_stereo_samples(int nsmps, short int *smps) { - if (!file) return; - fwrite(smps,nsmps,4,file); - sampleswritten+=nsmps; -}; + if(!file) + return; + fwrite(smps, nsmps, 4, file); + sampleswritten += nsmps; +} -void WAVaudiooutput::write_mono_samples(int nsmps,short int *smps) +void WAVaudiooutput::write_mono_samples(int nsmps, short int *smps) { - if (!file) return; - fwrite(smps,nsmps,2,file); - sampleswritten+=nsmps; -}; - + if(!file) + return; + fwrite(smps, nsmps, 2, file); + sampleswritten += nsmps; +} diff --git a/src/Output/WAVaudiooutput.h b/src/Output/WAVaudiooutput.h @@ -23,20 +23,21 @@ class WAVaudiooutput { -public: - WAVaudiooutput(); - ~WAVaudiooutput(); + public: + WAVaudiooutput(); + ~WAVaudiooutput(); - bool newfile(std::string filename,int samplerate,int channels); - void close(); + bool newfile(std::string filename, int samplerate, int channels); + void close(); - void write_mono_samples(int nsmps, short int *smps); - void write_stereo_samples(int nsmps, short int *smps); + void write_mono_samples(int nsmps, short int *smps); + void write_stereo_samples(int nsmps, short int *smps); -private: - int sampleswritten; - int samplerate; - int channels; - FILE *file; + private: + int sampleswritten; + int samplerate; + int channels; + FILE *file; }; #endif + diff --git a/src/Params/ADnoteParameters.cpp b/src/Params/ADnoteParameters.cpp @@ -25,123 +25,125 @@ #include <math.h> #include "ADnoteParameters.h" -int ADnote_unison_sizes[]={1,2,3,4,5,6,8,10,12,15,20,25,30,40,50,0}; +int ADnote_unison_sizes[] = +{1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 25, 30, 40, 50, 0}; ADnoteParameters::ADnoteParameters(FFTwrapper *fft_):Presets() { setpresettype("Padsyth"); - fft=fft_; + fft = fft_; - GlobalPar.FreqEnvelope=new EnvelopeParams(0,0); - GlobalPar.FreqEnvelope->ASRinit(64,50,64,60); - GlobalPar.FreqLfo=new LFOParams(70,0,64,0,0,0,0,0); + GlobalPar.FreqEnvelope = new EnvelopeParams(0, 0); + GlobalPar.FreqEnvelope->ASRinit(64, 50, 64, 60); + GlobalPar.FreqLfo = new LFOParams(70, 0, 64, 0, 0, 0, 0, 0); - GlobalPar.AmpEnvelope=new EnvelopeParams(64,1); - GlobalPar.AmpEnvelope->ADSRinit_dB(0,40,127,25); - GlobalPar.AmpLfo=new LFOParams(80,0,64,0,0,0,0,1); + GlobalPar.AmpEnvelope = new EnvelopeParams(64, 1); + GlobalPar.AmpEnvelope->ADSRinit_dB(0, 40, 127, 25); + GlobalPar.AmpLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 1); - GlobalPar.GlobalFilter=new FilterParams(2,94,40); - GlobalPar.FilterEnvelope=new EnvelopeParams(0,1); - GlobalPar.FilterEnvelope->ADSRinit_filter(64,40,64,70,60,64); - GlobalPar.FilterLfo=new LFOParams(80,0,64,0,0,0,0,2); - GlobalPar.Reson=new Resonance(); + GlobalPar.GlobalFilter = new FilterParams(2, 94, 40); + GlobalPar.FilterEnvelope = new EnvelopeParams(0, 1); + GlobalPar.FilterEnvelope->ADSRinit_filter(64, 40, 64, 70, 60, 64); + GlobalPar.FilterLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 2); + GlobalPar.Reson = new Resonance(); - for (int nvoice=0;nvoice<NUM_VOICES;nvoice++) EnableVoice(nvoice); + for(int nvoice = 0; nvoice < NUM_VOICES; nvoice++) + EnableVoice(nvoice); defaults(); -}; +} void ADnoteParameters::defaults() { //Default Parameters /* Frequency Global Parameters */ - GlobalPar.PStereo=1;//stereo - GlobalPar.PDetune=8192;//zero - GlobalPar.PCoarseDetune=0; - GlobalPar.PDetuneType=1; + GlobalPar.PStereo = 1; //stereo + GlobalPar.PDetune = 8192; //zero + GlobalPar.PCoarseDetune = 0; + GlobalPar.PDetuneType = 1; GlobalPar.FreqEnvelope->defaults(); GlobalPar.FreqLfo->defaults(); - GlobalPar.PBandwidth=64; + GlobalPar.PBandwidth = 64; /* Amplitude Global Parameters */ - GlobalPar.PVolume=90; - GlobalPar.PPanning=64;//center - GlobalPar.PAmpVelocityScaleFunction=64; + GlobalPar.PVolume = 90; + GlobalPar.PPanning = 64; //center + GlobalPar.PAmpVelocityScaleFunction = 64; GlobalPar.AmpEnvelope->defaults(); GlobalPar.AmpLfo->defaults(); - GlobalPar.PPunchStrength=0; - GlobalPar.PPunchTime=60; - GlobalPar.PPunchStretch=64; - GlobalPar.PPunchVelocitySensing=72; - GlobalPar.Hrandgrouping=0; + GlobalPar.PPunchStrength = 0; + GlobalPar.PPunchTime = 60; + GlobalPar.PPunchStretch = 64; + GlobalPar.PPunchVelocitySensing = 72; + GlobalPar.Hrandgrouping = 0; /* Filter Global Parameters*/ - GlobalPar.PFilterVelocityScale=64; - GlobalPar.PFilterVelocityScaleFunction=64; + GlobalPar.PFilterVelocityScale = 64; + GlobalPar.PFilterVelocityScaleFunction = 64; GlobalPar.GlobalFilter->defaults(); GlobalPar.FilterEnvelope->defaults(); GlobalPar.FilterLfo->defaults(); GlobalPar.Reson->defaults(); - for (int nvoice=0;nvoice<NUM_VOICES;nvoice++) { + for(int nvoice = 0; nvoice < NUM_VOICES; nvoice++) defaults(nvoice); - }; - VoicePar[0].Enabled=1; -}; + ; + VoicePar[0].Enabled = 1; +} /* * Defaults a voice */ void ADnoteParameters::defaults(int n) { - int nvoice=n; - VoicePar[nvoice].Enabled=0; - - VoicePar[nvoice].Unison_size=1; - VoicePar[nvoice].Unison_frequency_spread=60; - VoicePar[nvoice].Unison_stereo_spread=64; - VoicePar[nvoice].Unison_vibratto=64; - VoicePar[nvoice].Unison_vibratto_speed=64; - VoicePar[nvoice].Unison_invert_phase=0; - - VoicePar[nvoice].Type=0; - VoicePar[nvoice].Pfixedfreq=0; - VoicePar[nvoice].PfixedfreqET=0; - VoicePar[nvoice].Presonance=1; - VoicePar[nvoice].Pfilterbypass=0; - VoicePar[nvoice].Pextoscil=-1; - VoicePar[nvoice].PextFMoscil=-1; - VoicePar[nvoice].Poscilphase=64; - VoicePar[nvoice].PFMoscilphase=64; - VoicePar[nvoice].PDelay=0; - VoicePar[nvoice].PVolume=100; - VoicePar[nvoice].PVolumeminus=0; - VoicePar[nvoice].PPanning=64;//center - VoicePar[nvoice].PDetune=8192;//8192=0 - VoicePar[nvoice].PCoarseDetune=0; - VoicePar[nvoice].PDetuneType=0; - VoicePar[nvoice].PFreqLfoEnabled=0; - VoicePar[nvoice].PFreqEnvelopeEnabled=0; - VoicePar[nvoice].PAmpEnvelopeEnabled=0; - VoicePar[nvoice].PAmpLfoEnabled=0; - VoicePar[nvoice].PAmpVelocityScaleFunction=127; - VoicePar[nvoice].PFilterEnabled=0; - VoicePar[nvoice].PFilterEnvelopeEnabled=0; - VoicePar[nvoice].PFilterLfoEnabled=0; - VoicePar[nvoice].PFMEnabled=0; + int nvoice = n; + VoicePar[nvoice].Enabled = 0; + + VoicePar[nvoice].Unison_size = 1; + VoicePar[nvoice].Unison_frequency_spread = 60; + VoicePar[nvoice].Unison_stereo_spread = 64; + VoicePar[nvoice].Unison_vibratto = 64; + VoicePar[nvoice].Unison_vibratto_speed = 64; + VoicePar[nvoice].Unison_invert_phase = 0; + + VoicePar[nvoice].Type = 0; + VoicePar[nvoice].Pfixedfreq = 0; + VoicePar[nvoice].PfixedfreqET = 0; + VoicePar[nvoice].Presonance = 1; + VoicePar[nvoice].Pfilterbypass = 0; + VoicePar[nvoice].Pextoscil = -1; + VoicePar[nvoice].PextFMoscil = -1; + VoicePar[nvoice].Poscilphase = 64; + VoicePar[nvoice].PFMoscilphase = 64; + VoicePar[nvoice].PDelay = 0; + VoicePar[nvoice].PVolume = 100; + VoicePar[nvoice].PVolumeminus = 0; + VoicePar[nvoice].PPanning = 64; //center + VoicePar[nvoice].PDetune = 8192; //8192=0 + VoicePar[nvoice].PCoarseDetune = 0; + VoicePar[nvoice].PDetuneType = 0; + VoicePar[nvoice].PFreqLfoEnabled = 0; + VoicePar[nvoice].PFreqEnvelopeEnabled = 0; + VoicePar[nvoice].PAmpEnvelopeEnabled = 0; + VoicePar[nvoice].PAmpLfoEnabled = 0; + VoicePar[nvoice].PAmpVelocityScaleFunction = 127; + VoicePar[nvoice].PFilterEnabled = 0; + VoicePar[nvoice].PFilterEnvelopeEnabled = 0; + VoicePar[nvoice].PFilterLfoEnabled = 0; + VoicePar[nvoice].PFMEnabled = 0; //I use the internal oscillator (-1) - VoicePar[nvoice].PFMVoice=-1; + VoicePar[nvoice].PFMVoice = -1; - VoicePar[nvoice].PFMVolume=90; - VoicePar[nvoice].PFMVolumeDamp=64; - VoicePar[nvoice].PFMDetune=8192; - VoicePar[nvoice].PFMCoarseDetune=0; - VoicePar[nvoice].PFMDetuneType=0; - VoicePar[nvoice].PFMFreqEnvelopeEnabled=0; - VoicePar[nvoice].PFMAmpEnvelopeEnabled=0; - VoicePar[nvoice].PFMVelocityScaleFunction=64; + VoicePar[nvoice].PFMVolume = 90; + VoicePar[nvoice].PFMVolumeDamp = 64; + VoicePar[nvoice].PFMDetune = 8192; + VoicePar[nvoice].PFMCoarseDetune = 0; + VoicePar[nvoice].PFMDetuneType = 0; + VoicePar[nvoice].PFMFreqEnvelopeEnabled = 0; + VoicePar[nvoice].PFMAmpEnvelopeEnabled = 0; + VoicePar[nvoice].PFMVelocityScaleFunction = 64; VoicePar[nvoice].OscilSmp->defaults(); VoicePar[nvoice].FMSmp->defaults(); @@ -158,7 +160,7 @@ void ADnoteParameters::defaults(int n) VoicePar[nvoice].FMFreqEnvelope->defaults(); VoicePar[nvoice].FMAmpEnvelope->defaults(); -}; +} @@ -167,49 +169,48 @@ void ADnoteParameters::defaults(int n) */ void ADnoteParameters::EnableVoice(int nvoice) { - VoicePar[nvoice].OscilSmp=new OscilGen(fft,GlobalPar.Reson); - VoicePar[nvoice].FMSmp=new OscilGen(fft,NULL); + VoicePar[nvoice].OscilSmp = new OscilGen(fft, GlobalPar.Reson); + VoicePar[nvoice].FMSmp = new OscilGen(fft, NULL); - VoicePar[nvoice].AmpEnvelope=new EnvelopeParams(64,1); - VoicePar[nvoice].AmpEnvelope->ADSRinit_dB(0,100,127,100); - VoicePar[nvoice].AmpLfo=new LFOParams(90,32,64,0,0,30,0,1); + VoicePar[nvoice].AmpEnvelope = new EnvelopeParams(64, 1); + VoicePar[nvoice].AmpEnvelope->ADSRinit_dB(0, 100, 127, 100); + VoicePar[nvoice].AmpLfo = new LFOParams(90, 32, 64, 0, 0, 30, 0, 1); - VoicePar[nvoice].FreqEnvelope=new EnvelopeParams(0,0); - VoicePar[nvoice].FreqEnvelope->ASRinit(30,40,64,60); - VoicePar[nvoice].FreqLfo=new LFOParams(50,40,0,0,0,0,0,0); + VoicePar[nvoice].FreqEnvelope = new EnvelopeParams(0, 0); + VoicePar[nvoice].FreqEnvelope->ASRinit(30, 40, 64, 60); + VoicePar[nvoice].FreqLfo = new LFOParams(50, 40, 0, 0, 0, 0, 0, 0); - VoicePar[nvoice].VoiceFilter=new FilterParams(2,50,60); - VoicePar[nvoice].FilterEnvelope=new EnvelopeParams(0,0); - VoicePar[nvoice].FilterEnvelope->ADSRinit_filter(90,70,40,70,10,40); - VoicePar[nvoice].FilterLfo=new LFOParams(50,20,64,0,0,0,0,2); + VoicePar[nvoice].VoiceFilter = new FilterParams(2, 50, 60); + VoicePar[nvoice].FilterEnvelope = new EnvelopeParams(0, 0); + VoicePar[nvoice].FilterEnvelope->ADSRinit_filter(90, 70, 40, 70, 10, 40); + VoicePar[nvoice].FilterLfo = new LFOParams(50, 20, 64, 0, 0, 0, 0, 2); - VoicePar[nvoice].FMFreqEnvelope=new EnvelopeParams(0,0); - VoicePar[nvoice].FMFreqEnvelope->ASRinit(20,90,40,80); - VoicePar[nvoice].FMAmpEnvelope=new EnvelopeParams(64,1); - VoicePar[nvoice].FMAmpEnvelope->ADSRinit(80,90,127,100); -}; + VoicePar[nvoice].FMFreqEnvelope = new EnvelopeParams(0, 0); + VoicePar[nvoice].FMFreqEnvelope->ASRinit(20, 90, 40, 80); + VoicePar[nvoice].FMAmpEnvelope = new EnvelopeParams(64, 1); + VoicePar[nvoice].FMAmpEnvelope->ADSRinit(80, 90, 127, 100); +} /* * Get the Multiplier of the fine detunes of the voices */ REALTYPE ADnoteParameters::getBandwidthDetuneMultiplier() { - REALTYPE bw=(GlobalPar.PBandwidth-64.0)/64.0; - bw=pow(2.0,bw*pow(fabs(bw),0.2)*5.0); + REALTYPE bw = (GlobalPar.PBandwidth - 64.0) / 64.0; + bw = pow(2.0, bw * pow(fabs(bw), 0.2) * 5.0); - return(bw); -}; + return bw; +} /* * Get the unison spread in cents for a voice */ -REALTYPE ADnoteParameters::getUnisonFrequencySpreadCents(int nvoice){ - REALTYPE unison_spread=VoicePar[nvoice].Unison_frequency_spread/127.0; - unison_spread=pow(unison_spread*2.0,2.0)*50.0;//cents - return unison_spread; - -}; +REALTYPE ADnoteParameters::getUnisonFrequencySpreadCents(int nvoice) { + REALTYPE unison_spread = VoicePar[nvoice].Unison_frequency_spread / 127.0; + unison_spread = pow(unison_spread * 2.0, 2.0) * 50.0; //cents + return unison_spread; +} /* * Kill the voice @@ -231,94 +232,101 @@ void ADnoteParameters::KillVoice(int nvoice) delete (VoicePar[nvoice].FMFreqEnvelope); delete (VoicePar[nvoice].FMAmpEnvelope); -}; +} ADnoteParameters::~ADnoteParameters() { - delete(GlobalPar.FreqEnvelope); - delete(GlobalPar.FreqLfo); - delete(GlobalPar.AmpEnvelope); - delete(GlobalPar.AmpLfo); - delete(GlobalPar.GlobalFilter); - delete(GlobalPar.FilterEnvelope); - delete(GlobalPar.FilterLfo); - delete(GlobalPar.Reson); - - for (int nvoice=0;nvoice<NUM_VOICES;nvoice++) { + delete (GlobalPar.FreqEnvelope); + delete (GlobalPar.FreqLfo); + delete (GlobalPar.AmpEnvelope); + delete (GlobalPar.AmpLfo); + delete (GlobalPar.GlobalFilter); + delete (GlobalPar.FilterEnvelope); + delete (GlobalPar.FilterLfo); + delete (GlobalPar.Reson); + + for(int nvoice = 0; nvoice < NUM_VOICES; nvoice++) KillVoice(nvoice); - }; -}; - -int ADnoteParameters::get_unison_size_index(int nvoice){ - int index=0; - if (nvoice>=NUM_VOICES) return 0; - int unison=VoicePar[nvoice].Unison_size; - - while(1){ - if (ADnote_unison_sizes[index]>=unison) { - return index; - }; - if (ADnote_unison_sizes[index]==0) { - return index-1; - }; - index++; - }; - return 0; -}; - -void ADnoteParameters::set_unison_size_index(int nvoice,int index){ - int unison=1; - for (int i=0;i<=index;i++){ - unison=ADnote_unison_sizes[i]; - if (unison==0) { - unison=ADnote_unison_sizes[i-1]; - break; - }; - }; - - VoicePar[nvoice].Unison_size=unison; -}; - - - -void ADnoteParameters::add2XMLsection(XMLwrapper *xml,int n) + ; +} + +int ADnoteParameters::get_unison_size_index(int nvoice) { + int index = 0; + if(nvoice >= NUM_VOICES) + return 0; + int unison = VoicePar[nvoice].Unison_size; + + while(1) { + if(ADnote_unison_sizes[index] >= unison) + return index; + ; + if(ADnote_unison_sizes[index] == 0) + return index - 1; + ; + index++; + } + return 0; +} + +void ADnoteParameters::set_unison_size_index(int nvoice, int index) { + int unison = 1; + for(int i = 0; i <= index; i++) { + unison = ADnote_unison_sizes[i]; + if(unison == 0) { + unison = ADnote_unison_sizes[i - 1]; + break; + } + } + + VoicePar[nvoice].Unison_size = unison; +} + + + +void ADnoteParameters::add2XMLsection(XMLwrapper *xml, int n) { - int nvoice=n; - if (nvoice>=NUM_VOICES) return; + int nvoice = n; + if(nvoice >= NUM_VOICES) + return; + + int oscilused = 0, fmoscilused = 0; //if the oscil or fmoscil are used by another voice - int oscilused=0,fmoscilused=0;//if the oscil or fmoscil are used by another voice + for(int i = 0; i < NUM_VOICES; i++) { + if(VoicePar[i].Pextoscil == nvoice) + oscilused = 1; + if(VoicePar[i].PextFMoscil == nvoice) + fmoscilused = 1; + } - for (int i=0;i<NUM_VOICES;i++) { - if (VoicePar[i].Pextoscil==nvoice) oscilused=1; - if (VoicePar[i].PextFMoscil==nvoice) fmoscilused=1; - }; + xml->addparbool("enabled", VoicePar[nvoice].Enabled); + if(((VoicePar[nvoice].Enabled == 0) && (oscilused == 0) + && (fmoscilused == 0)) && (xml->minimal)) + return; - xml->addparbool("enabled",VoicePar[nvoice].Enabled); - if (((VoicePar[nvoice].Enabled==0)&&(oscilused==0)&&(fmoscilused==0))&&(xml->minimal)) return; + xml->addpar("type", VoicePar[nvoice].Type); - xml->addpar("type",VoicePar[nvoice].Type); - - xml->addpar("unison_size",VoicePar[nvoice].Unison_size); - xml->addpar("unison_frequency_spread",VoicePar[nvoice].Unison_frequency_spread); - xml->addpar("unison_stereo_spread",VoicePar[nvoice].Unison_stereo_spread); - xml->addpar("unison_vibratto",VoicePar[nvoice].Unison_vibratto); - xml->addpar("unison_vibratto_speed",VoicePar[nvoice].Unison_vibratto_speed); - xml->addpar("unison_invert_phase",VoicePar[nvoice].Unison_invert_phase); - - xml->addpar("delay",VoicePar[nvoice].PDelay); - xml->addparbool("resonance",VoicePar[nvoice].Presonance); + xml->addpar("unison_size", VoicePar[nvoice].Unison_size); + xml->addpar("unison_frequency_spread", + VoicePar[nvoice].Unison_frequency_spread); + xml->addpar("unison_stereo_spread", VoicePar[nvoice].Unison_stereo_spread); + xml->addpar("unison_vibratto", VoicePar[nvoice].Unison_vibratto); + xml->addpar("unison_vibratto_speed", VoicePar[nvoice].Unison_vibratto_speed); + xml->addpar("unison_invert_phase", VoicePar[nvoice].Unison_invert_phase); - xml->addpar("ext_oscil",VoicePar[nvoice].Pextoscil); - xml->addpar("ext_fm_oscil",VoicePar[nvoice].PextFMoscil); + xml->addpar("delay", VoicePar[nvoice].PDelay); + xml->addparbool("resonance", VoicePar[nvoice].Presonance); - xml->addpar("oscil_phase",VoicePar[nvoice].Poscilphase); - xml->addpar("oscil_fm_phase",VoicePar[nvoice].PFMoscilphase); + xml->addpar("ext_oscil", VoicePar[nvoice].Pextoscil); + xml->addpar("ext_fm_oscil", VoicePar[nvoice].PextFMoscil); - xml->addparbool("filter_enabled",VoicePar[nvoice].PFilterEnabled); - xml->addparbool("filter_bypass",VoicePar[nvoice].Pfilterbypass); + xml->addpar("oscil_phase", VoicePar[nvoice].Poscilphase); + xml->addpar("oscil_fm_phase", VoicePar[nvoice].PFMoscilphase); - xml->addpar("fm_enabled",VoicePar[nvoice].PFMEnabled); + xml->addparbool("filter_enabled", VoicePar[nvoice].PFilterEnabled); + xml->addparbool("filter_bypass", VoicePar[nvoice].Pfilterbypass); + + xml->addpar("fm_enabled", VoicePar[nvoice].PFMEnabled); xml->beginbranch("OSCIL"); VoicePar[nvoice].OscilSmp->add2XML(xml); @@ -326,94 +334,102 @@ void ADnoteParameters::add2XMLsection(XMLwrapper *xml,int n) xml->beginbranch("AMPLITUDE_PARAMETERS"); - xml->addpar("panning",VoicePar[nvoice].PPanning); - xml->addpar("volume",VoicePar[nvoice].PVolume); - xml->addparbool("volume_minus",VoicePar[nvoice].PVolumeminus); - xml->addpar("velocity_sensing",VoicePar[nvoice].PAmpVelocityScaleFunction); - - xml->addparbool("amp_envelope_enabled",VoicePar[nvoice].PAmpEnvelopeEnabled); - if ((VoicePar[nvoice].PAmpEnvelopeEnabled!=0)||(!xml->minimal)) { + xml->addpar("panning", VoicePar[nvoice].PPanning); + xml->addpar("volume", VoicePar[nvoice].PVolume); + xml->addparbool("volume_minus", VoicePar[nvoice].PVolumeminus); + xml->addpar("velocity_sensing", VoicePar[nvoice].PAmpVelocityScaleFunction); + + xml->addparbool("amp_envelope_enabled", + VoicePar[nvoice].PAmpEnvelopeEnabled); + if((VoicePar[nvoice].PAmpEnvelopeEnabled != 0) || (!xml->minimal)) { xml->beginbranch("AMPLITUDE_ENVELOPE"); VoicePar[nvoice].AmpEnvelope->add2XML(xml); xml->endbranch(); - }; - xml->addparbool("amp_lfo_enabled",VoicePar[nvoice].PAmpLfoEnabled); - if ((VoicePar[nvoice].PAmpLfoEnabled!=0)||(!xml->minimal)) { + } + xml->addparbool("amp_lfo_enabled", VoicePar[nvoice].PAmpLfoEnabled); + if((VoicePar[nvoice].PAmpLfoEnabled != 0) || (!xml->minimal)) { xml->beginbranch("AMPLITUDE_LFO"); VoicePar[nvoice].AmpLfo->add2XML(xml); xml->endbranch(); - }; + } xml->endbranch(); xml->beginbranch("FREQUENCY_PARAMETERS"); - xml->addparbool("fixed_freq",VoicePar[nvoice].Pfixedfreq); - xml->addpar("fixed_freq_et",VoicePar[nvoice].PfixedfreqET); - xml->addpar("detune",VoicePar[nvoice].PDetune); - xml->addpar("coarse_detune",VoicePar[nvoice].PCoarseDetune); - xml->addpar("detune_type",VoicePar[nvoice].PDetuneType); - - xml->addparbool("freq_envelope_enabled",VoicePar[nvoice].PFreqEnvelopeEnabled); - if ((VoicePar[nvoice].PFreqEnvelopeEnabled!=0)||(!xml->minimal)) { + xml->addparbool("fixed_freq", VoicePar[nvoice].Pfixedfreq); + xml->addpar("fixed_freq_et", VoicePar[nvoice].PfixedfreqET); + xml->addpar("detune", VoicePar[nvoice].PDetune); + xml->addpar("coarse_detune", VoicePar[nvoice].PCoarseDetune); + xml->addpar("detune_type", VoicePar[nvoice].PDetuneType); + + xml->addparbool("freq_envelope_enabled", + VoicePar[nvoice].PFreqEnvelopeEnabled); + if((VoicePar[nvoice].PFreqEnvelopeEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FREQUENCY_ENVELOPE"); VoicePar[nvoice].FreqEnvelope->add2XML(xml); xml->endbranch(); - }; - xml->addparbool("freq_lfo_enabled",VoicePar[nvoice].PFreqLfoEnabled); - if ((VoicePar[nvoice].PFreqLfoEnabled!=0)||(!xml->minimal)) { + } + xml->addparbool("freq_lfo_enabled", VoicePar[nvoice].PFreqLfoEnabled); + if((VoicePar[nvoice].PFreqLfoEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FREQUENCY_LFO"); VoicePar[nvoice].FreqLfo->add2XML(xml); xml->endbranch(); - }; + } xml->endbranch(); - if ((VoicePar[nvoice].PFilterEnabled!=0)||(!xml->minimal)) { + if((VoicePar[nvoice].PFilterEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FILTER_PARAMETERS"); xml->beginbranch("FILTER"); VoicePar[nvoice].VoiceFilter->add2XML(xml); xml->endbranch(); - xml->addparbool("filter_envelope_enabled",VoicePar[nvoice].PFilterEnvelopeEnabled); - if ((VoicePar[nvoice].PFilterEnvelopeEnabled!=0)||(!xml->minimal)) { + xml->addparbool("filter_envelope_enabled", + VoicePar[nvoice].PFilterEnvelopeEnabled); + if((VoicePar[nvoice].PFilterEnvelopeEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FILTER_ENVELOPE"); VoicePar[nvoice].FilterEnvelope->add2XML(xml); xml->endbranch(); - }; + } - xml->addparbool("filter_lfo_enabled",VoicePar[nvoice].PFilterLfoEnabled); - if ((VoicePar[nvoice].PFilterLfoEnabled!=0)||(!xml->minimal)) { + xml->addparbool("filter_lfo_enabled", + VoicePar[nvoice].PFilterLfoEnabled); + if((VoicePar[nvoice].PFilterLfoEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FILTER_LFO"); VoicePar[nvoice].FilterLfo->add2XML(xml); xml->endbranch(); - }; + } xml->endbranch(); - }; + } - if ((VoicePar[nvoice].PFMEnabled!=0)||(fmoscilused!=0)||(!xml->minimal)) { + if((VoicePar[nvoice].PFMEnabled != 0) || (fmoscilused != 0) + || (!xml->minimal)) { xml->beginbranch("FM_PARAMETERS"); - xml->addpar("input_voice",VoicePar[nvoice].PFMVoice); + xml->addpar("input_voice", VoicePar[nvoice].PFMVoice); - xml->addpar("volume",VoicePar[nvoice].PFMVolume); - xml->addpar("volume_damp",VoicePar[nvoice].PFMVolumeDamp); - xml->addpar("velocity_sensing",VoicePar[nvoice].PFMVelocityScaleFunction); + xml->addpar("volume", VoicePar[nvoice].PFMVolume); + xml->addpar("volume_damp", VoicePar[nvoice].PFMVolumeDamp); + xml->addpar("velocity_sensing", + VoicePar[nvoice].PFMVelocityScaleFunction); - xml->addparbool("amp_envelope_enabled",VoicePar[nvoice].PFMAmpEnvelopeEnabled); - if ((VoicePar[nvoice].PFMAmpEnvelopeEnabled!=0)||(!xml->minimal)) { + xml->addparbool("amp_envelope_enabled", + VoicePar[nvoice].PFMAmpEnvelopeEnabled); + if((VoicePar[nvoice].PFMAmpEnvelopeEnabled != 0) || (!xml->minimal)) { xml->beginbranch("AMPLITUDE_ENVELOPE"); VoicePar[nvoice].FMAmpEnvelope->add2XML(xml); xml->endbranch(); - }; + } xml->beginbranch("MODULATOR"); - xml->addpar("detune",VoicePar[nvoice].PFMDetune); - xml->addpar("coarse_detune",VoicePar[nvoice].PFMCoarseDetune); - xml->addpar("detune_type",VoicePar[nvoice].PFMDetuneType); + xml->addpar("detune", VoicePar[nvoice].PFMDetune); + xml->addpar("coarse_detune", VoicePar[nvoice].PFMCoarseDetune); + xml->addpar("detune_type", VoicePar[nvoice].PFMDetuneType); - xml->addparbool("freq_envelope_enabled",VoicePar[nvoice].PFMFreqEnvelopeEnabled); - if ((VoicePar[nvoice].PFMFreqEnvelopeEnabled!=0)||(!xml->minimal)) { + xml->addparbool("freq_envelope_enabled", + VoicePar[nvoice].PFMFreqEnvelopeEnabled); + if((VoicePar[nvoice].PFMFreqEnvelopeEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FREQUENCY_ENVELOPE"); VoicePar[nvoice].FMFreqEnvelope->add2XML(xml); xml->endbranch(); - }; + } xml->beginbranch("OSCIL"); VoicePar[nvoice].FMSmp->add2XML(xml); @@ -421,23 +437,23 @@ void ADnoteParameters::add2XMLsection(XMLwrapper *xml,int n) xml->endbranch(); xml->endbranch(); - }; -}; + } +} void ADnoteParameters::add2XML(XMLwrapper *xml) { - xml->addparbool("stereo",GlobalPar.PStereo); + xml->addparbool("stereo", GlobalPar.PStereo); xml->beginbranch("AMPLITUDE_PARAMETERS"); - xml->addpar("volume",GlobalPar.PVolume); - xml->addpar("panning",GlobalPar.PPanning); - xml->addpar("velocity_sensing",GlobalPar.PAmpVelocityScaleFunction); - xml->addpar("punch_strength",GlobalPar.PPunchStrength); - xml->addpar("punch_time",GlobalPar.PPunchTime); - xml->addpar("punch_stretch",GlobalPar.PPunchStretch); - xml->addpar("punch_velocity_sensing",GlobalPar.PPunchVelocitySensing); - xml->addpar("harmonic_randomness_grouping",GlobalPar.Hrandgrouping); + xml->addpar("volume", GlobalPar.PVolume); + xml->addpar("panning", GlobalPar.PPanning); + xml->addpar("velocity_sensing", GlobalPar.PAmpVelocityScaleFunction); + xml->addpar("punch_strength", GlobalPar.PPunchStrength); + xml->addpar("punch_time", GlobalPar.PPunchTime); + xml->addpar("punch_stretch", GlobalPar.PPunchStretch); + xml->addpar("punch_velocity_sensing", GlobalPar.PPunchVelocitySensing); + xml->addpar("harmonic_randomness_grouping", GlobalPar.Hrandgrouping); xml->beginbranch("AMPLITUDE_ENVELOPE"); GlobalPar.AmpEnvelope->add2XML(xml); @@ -449,12 +465,12 @@ void ADnoteParameters::add2XML(XMLwrapper *xml) xml->endbranch(); xml->beginbranch("FREQUENCY_PARAMETERS"); - xml->addpar("detune",GlobalPar.PDetune); + xml->addpar("detune", GlobalPar.PDetune); - xml->addpar("coarse_detune",GlobalPar.PCoarseDetune); - xml->addpar("detune_type",GlobalPar.PDetuneType); + xml->addpar("coarse_detune", GlobalPar.PCoarseDetune); + xml->addpar("detune_type", GlobalPar.PDetuneType); - xml->addpar("bandwidth",GlobalPar.PBandwidth); + xml->addpar("bandwidth", GlobalPar.PBandwidth); xml->beginbranch("FREQUENCY_ENVELOPE"); GlobalPar.FreqEnvelope->add2XML(xml); @@ -467,8 +483,8 @@ void ADnoteParameters::add2XML(XMLwrapper *xml) xml->beginbranch("FILTER_PARAMETERS"); - xml->addpar("velocity_sensing_amplitude",GlobalPar.PFilterVelocityScale); - xml->addpar("velocity_sensing",GlobalPar.PFilterVelocityScaleFunction); + xml->addpar("velocity_sensing_amplitude", GlobalPar.PFilterVelocityScale); + xml->addpar("velocity_sensing", GlobalPar.PFilterVelocityScaleFunction); xml->beginbranch("FILTER"); GlobalPar.GlobalFilter->add2XML(xml); @@ -487,48 +503,66 @@ void ADnoteParameters::add2XML(XMLwrapper *xml) GlobalPar.Reson->add2XML(xml); xml->endbranch(); - for (int nvoice=0;nvoice<NUM_VOICES;nvoice++) { - xml->beginbranch("VOICE",nvoice); - add2XMLsection(xml,nvoice); + for(int nvoice = 0; nvoice < NUM_VOICES; nvoice++) { + xml->beginbranch("VOICE", nvoice); + add2XMLsection(xml, nvoice); xml->endbranch(); - }; -}; + } +} void ADnoteParameters::getfromXML(XMLwrapper *xml) { - GlobalPar.PStereo=xml->getparbool("stereo",GlobalPar.PStereo); - - if (xml->enterbranch("AMPLITUDE_PARAMETERS")) { - GlobalPar.PVolume=xml->getpar127("volume",GlobalPar.PVolume); - GlobalPar.PPanning=xml->getpar127("panning",GlobalPar.PPanning); - GlobalPar.PAmpVelocityScaleFunction=xml->getpar127("velocity_sensing",GlobalPar.PAmpVelocityScaleFunction); - - GlobalPar.PPunchStrength=xml->getpar127("punch_strength",GlobalPar.PPunchStrength); - GlobalPar.PPunchTime=xml->getpar127("punch_time",GlobalPar.PPunchTime); - GlobalPar.PPunchStretch=xml->getpar127("punch_stretch",GlobalPar.PPunchStretch); - GlobalPar.PPunchVelocitySensing=xml->getpar127("punch_velocity_sensing",GlobalPar.PPunchVelocitySensing); - GlobalPar.Hrandgrouping=xml->getpar127("harmonic_randomness_grouping",GlobalPar.Hrandgrouping); - - if (xml->enterbranch("AMPLITUDE_ENVELOPE")) { + GlobalPar.PStereo = xml->getparbool("stereo", GlobalPar.PStereo); + + if(xml->enterbranch("AMPLITUDE_PARAMETERS")) { + GlobalPar.PVolume = xml->getpar127("volume", GlobalPar.PVolume); + GlobalPar.PPanning = xml->getpar127("panning", GlobalPar.PPanning); + GlobalPar.PAmpVelocityScaleFunction = xml->getpar127( + "velocity_sensing", + GlobalPar. + PAmpVelocityScaleFunction); + + GlobalPar.PPunchStrength = xml->getpar127("punch_strength", + GlobalPar.PPunchStrength); + GlobalPar.PPunchTime = xml->getpar127("punch_time", + GlobalPar.PPunchTime); + GlobalPar.PPunchStretch = xml->getpar127("punch_stretch", + GlobalPar.PPunchStretch); + GlobalPar.PPunchVelocitySensing = xml->getpar127( + "punch_velocity_sensing", + GlobalPar.PPunchVelocitySensing); + GlobalPar.Hrandgrouping = xml->getpar127( + "harmonic_randomness_grouping", + GlobalPar.Hrandgrouping); + + if(xml->enterbranch("AMPLITUDE_ENVELOPE")) { GlobalPar.AmpEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } - if (xml->enterbranch("AMPLITUDE_LFO")) { + if(xml->enterbranch("AMPLITUDE_LFO")) { GlobalPar.AmpLfo->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; - - if (xml->enterbranch("FREQUENCY_PARAMETERS")) { - GlobalPar.PDetune=xml->getpar("detune",GlobalPar.PDetune,0,16383); - GlobalPar.PCoarseDetune=xml->getpar("coarse_detune",GlobalPar.PCoarseDetune,0,16383); - GlobalPar.PDetuneType=xml->getpar127("detune_type",GlobalPar.PDetuneType); - - GlobalPar.PBandwidth=xml->getpar127("bandwidth",GlobalPar.PBandwidth); + } + + if(xml->enterbranch("FREQUENCY_PARAMETERS")) { + GlobalPar.PDetune = xml->getpar("detune", + GlobalPar.PDetune, + 0, + 16383); + GlobalPar.PCoarseDetune = xml->getpar("coarse_detune", + GlobalPar.PCoarseDetune, + 0, + 16383); + GlobalPar.PDetuneType = xml->getpar127("detune_type", + GlobalPar.PDetuneType); + + GlobalPar.PBandwidth = xml->getpar127("bandwidth", + GlobalPar.PBandwidth); xml->enterbranch("FREQUENCY_ENVELOPE"); GlobalPar.FreqEnvelope->getfromXML(xml); @@ -539,12 +573,16 @@ void ADnoteParameters::getfromXML(XMLwrapper *xml) xml->exitbranch(); xml->exitbranch(); - }; + } - if (xml->enterbranch("FILTER_PARAMETERS")) { - GlobalPar.PFilterVelocityScale=xml->getpar127("velocity_sensing_amplitude",GlobalPar.PFilterVelocityScale); - GlobalPar.PFilterVelocityScaleFunction=xml->getpar127("velocity_sensing",GlobalPar.PFilterVelocityScaleFunction); + if(xml->enterbranch("FILTER_PARAMETERS")) { + GlobalPar.PFilterVelocityScale = xml->getpar127( + "velocity_sensing_amplitude", + GlobalPar.PFilterVelocityScale); + GlobalPar.PFilterVelocityScaleFunction = xml->getpar127( + "velocity_sensing", + GlobalPar.PFilterVelocityScaleFunction); xml->enterbranch("FILTER"); GlobalPar.GlobalFilter->getfromXML(xml); @@ -558,155 +596,244 @@ void ADnoteParameters::getfromXML(XMLwrapper *xml) GlobalPar.FilterLfo->getfromXML(xml); xml->exitbranch(); xml->exitbranch(); - }; + } - if (xml->enterbranch("RESONANCE")) { + if(xml->enterbranch("RESONANCE")) { GlobalPar.Reson->getfromXML(xml); xml->exitbranch(); - }; + } - for (int nvoice=0;nvoice<NUM_VOICES;nvoice++) { - VoicePar[nvoice].Enabled=0; - if (xml->enterbranch("VOICE",nvoice)==0) continue; - getfromXMLsection(xml,nvoice); + for(int nvoice = 0; nvoice < NUM_VOICES; nvoice++) { + VoicePar[nvoice].Enabled = 0; + if(xml->enterbranch("VOICE", nvoice) == 0) + continue; + getfromXMLsection(xml, nvoice); xml->exitbranch(); - }; - + } +} -}; - -void ADnoteParameters::getfromXMLsection(XMLwrapper *xml,int n) +void ADnoteParameters::getfromXMLsection(XMLwrapper *xml, int n) { - int nvoice=n; - if (nvoice>=NUM_VOICES) return; - - VoicePar[nvoice].Enabled=xml->getparbool("enabled",0); - - VoicePar[nvoice].Unison_size=xml->getpar127("unison_size",VoicePar[nvoice].Unison_size); - VoicePar[nvoice].Unison_frequency_spread=xml->getpar127("unison_frequency_spread",VoicePar[nvoice].Unison_frequency_spread); - VoicePar[nvoice].Unison_stereo_spread=xml->getpar127("unison_stereo_spread",VoicePar[nvoice].Unison_stereo_spread); - VoicePar[nvoice].Unison_vibratto=xml->getpar127("unison_vibratto",VoicePar[nvoice].Unison_vibratto); - VoicePar[nvoice].Unison_vibratto_speed=xml->getpar127("unison_vibratto_speed",VoicePar[nvoice].Unison_vibratto_speed); - VoicePar[nvoice].Unison_invert_phase=xml->getpar127("unison_invert_phase",VoicePar[nvoice].Unison_invert_phase); - - VoicePar[nvoice].Type=xml->getpar127("type",VoicePar[nvoice].Type); - VoicePar[nvoice].PDelay=xml->getpar127("delay",VoicePar[nvoice].PDelay); - VoicePar[nvoice].Presonance=xml->getparbool("resonance",VoicePar[nvoice].Presonance); - - VoicePar[nvoice].Pextoscil=xml->getpar("ext_oscil",-1,-1,nvoice-1); - VoicePar[nvoice].PextFMoscil=xml->getpar("ext_fm_oscil",-1,-1,nvoice-1); - - VoicePar[nvoice].Poscilphase=xml->getpar127("oscil_phase",VoicePar[nvoice].Poscilphase); - VoicePar[nvoice].PFMoscilphase=xml->getpar127("oscil_fm_phase",VoicePar[nvoice].PFMoscilphase); - - VoicePar[nvoice].PFilterEnabled=xml->getparbool("filter_enabled",VoicePar[nvoice].PFilterEnabled); - VoicePar[nvoice].Pfilterbypass=xml->getparbool("filter_bypass",VoicePar[nvoice].Pfilterbypass); - - VoicePar[nvoice].PFMEnabled=xml->getpar127("fm_enabled",VoicePar[nvoice].PFMEnabled); - - if (xml->enterbranch("OSCIL")) { + int nvoice = n; + if(nvoice >= NUM_VOICES) + return; + + VoicePar[nvoice].Enabled = xml->getparbool("enabled", 0); + + VoicePar[nvoice].Unison_size = + xml->getpar127("unison_size", VoicePar[nvoice].Unison_size); + VoicePar[nvoice].Unison_frequency_spread = xml->getpar127( + "unison_frequency_spread", + VoicePar[nvoice].Unison_frequency_spread); + VoicePar[nvoice].Unison_stereo_spread = xml->getpar127( + "unison_stereo_spread", + VoicePar[nvoice].Unison_stereo_spread); + VoicePar[nvoice].Unison_vibratto = xml->getpar127( + "unison_vibratto", + VoicePar[nvoice]. + Unison_vibratto); + VoicePar[nvoice].Unison_vibratto_speed = xml->getpar127( + "unison_vibratto_speed", + VoicePar[nvoice].Unison_vibratto_speed); + VoicePar[nvoice].Unison_invert_phase = xml->getpar127( + "unison_invert_phase", + VoicePar[nvoice].Unison_invert_phase); + + VoicePar[nvoice].Type = xml->getpar127("type", + VoicePar[nvoice].Type); + VoicePar[nvoice].PDelay = xml->getpar127("delay", + VoicePar[nvoice].PDelay); + VoicePar[nvoice].Presonance = + xml->getparbool("resonance", VoicePar[nvoice].Presonance); + + VoicePar[nvoice].Pextoscil = xml->getpar("ext_oscil", + -1, + -1, + nvoice - 1); + VoicePar[nvoice].PextFMoscil = xml->getpar("ext_fm_oscil", + -1, + -1, + nvoice - 1); + + VoicePar[nvoice].Poscilphase = + xml->getpar127("oscil_phase", VoicePar[nvoice].Poscilphase); + VoicePar[nvoice].PFMoscilphase = xml->getpar127( + "oscil_fm_phase", + VoicePar[nvoice]. + PFMoscilphase); + + VoicePar[nvoice].PFilterEnabled = xml->getparbool( + "filter_enabled", + VoicePar[nvoice]. + PFilterEnabled); + VoicePar[nvoice].Pfilterbypass = xml->getparbool( + "filter_bypass", + VoicePar[nvoice]. + Pfilterbypass); + + VoicePar[nvoice].PFMEnabled = + xml->getpar127("fm_enabled", VoicePar[nvoice].PFMEnabled); + + if(xml->enterbranch("OSCIL")) { VoicePar[nvoice].OscilSmp->getfromXML(xml); xml->exitbranch(); - }; - - - if (xml->enterbranch("AMPLITUDE_PARAMETERS")) { - VoicePar[nvoice].PPanning=xml->getpar127("panning",VoicePar[nvoice].PPanning); - VoicePar[nvoice].PVolume=xml->getpar127("volume",VoicePar[nvoice].PVolume); - VoicePar[nvoice].PVolumeminus=xml->getparbool("volume_minus",VoicePar[nvoice].PVolumeminus); - VoicePar[nvoice].PAmpVelocityScaleFunction=xml->getpar127("velocity_sensing",VoicePar[nvoice].PAmpVelocityScaleFunction); - - VoicePar[nvoice].PAmpEnvelopeEnabled=xml->getparbool("amp_envelope_enabled",VoicePar[nvoice].PAmpEnvelopeEnabled); - if (xml->enterbranch("AMPLITUDE_ENVELOPE")) { + } + + + if(xml->enterbranch("AMPLITUDE_PARAMETERS")) { + VoicePar[nvoice].PPanning = + xml->getpar127("panning", VoicePar[nvoice].PPanning); + VoicePar[nvoice].PVolume = + xml->getpar127("volume", VoicePar[nvoice].PVolume); + VoicePar[nvoice].PVolumeminus = xml->getparbool( + "volume_minus", + VoicePar[nvoice]. + PVolumeminus); + VoicePar[nvoice].PAmpVelocityScaleFunction = xml->getpar127( + "velocity_sensing", + VoicePar[nvoice].PAmpVelocityScaleFunction); + + VoicePar[nvoice].PAmpEnvelopeEnabled = xml->getparbool( + "amp_envelope_enabled", + VoicePar[nvoice].PAmpEnvelopeEnabled); + if(xml->enterbranch("AMPLITUDE_ENVELOPE")) { VoicePar[nvoice].AmpEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } - VoicePar[nvoice].PAmpLfoEnabled=xml->getparbool("amp_lfo_enabled",VoicePar[nvoice].PAmpLfoEnabled); - if (xml->enterbranch("AMPLITUDE_LFO")) { + VoicePar[nvoice].PAmpLfoEnabled = xml->getparbool( + "amp_lfo_enabled", + VoicePar[nvoice]. + PAmpLfoEnabled); + if(xml->enterbranch("AMPLITUDE_LFO")) { VoicePar[nvoice].AmpLfo->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; - - if (xml->enterbranch("FREQUENCY_PARAMETERS")) { - VoicePar[nvoice].Pfixedfreq=xml->getparbool("fixed_freq",VoicePar[nvoice].Pfixedfreq); - VoicePar[nvoice].PfixedfreqET=xml->getpar127("fixed_freq_et",VoicePar[nvoice].PfixedfreqET); - - - VoicePar[nvoice].PDetune=xml->getpar("detune",VoicePar[nvoice].PDetune,0,16383); - - VoicePar[nvoice].PCoarseDetune=xml->getpar("coarse_detune",VoicePar[nvoice].PCoarseDetune,0,16383); - VoicePar[nvoice].PDetuneType=xml->getpar127("detune_type",VoicePar[nvoice].PDetuneType); - - VoicePar[nvoice].PFreqEnvelopeEnabled=xml->getparbool("freq_envelope_enabled",VoicePar[nvoice].PFreqEnvelopeEnabled); - if (xml->enterbranch("FREQUENCY_ENVELOPE")) { + } + + if(xml->enterbranch("FREQUENCY_PARAMETERS")) { + VoicePar[nvoice].Pfixedfreq = + xml->getparbool("fixed_freq", VoicePar[nvoice].Pfixedfreq); + VoicePar[nvoice].PfixedfreqET = xml->getpar127( + "fixed_freq_et", + VoicePar[nvoice]. + PfixedfreqET); + + + VoicePar[nvoice].PDetune = xml->getpar("detune", + VoicePar[nvoice].PDetune, + 0, + 16383); + + VoicePar[nvoice].PCoarseDetune = + xml->getpar("coarse_detune", + VoicePar[nvoice].PCoarseDetune, + 0, + 16383); + VoicePar[nvoice].PDetuneType = xml->getpar127( + "detune_type", + VoicePar[nvoice]. + PDetuneType); + + VoicePar[nvoice].PFreqEnvelopeEnabled = xml->getparbool( + "freq_envelope_enabled", + VoicePar[nvoice].PFreqEnvelopeEnabled); + if(xml->enterbranch("FREQUENCY_ENVELOPE")) { VoicePar[nvoice].FreqEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } - VoicePar[nvoice].PFreqLfoEnabled=xml->getparbool("freq_lfo_enabled",VoicePar[nvoice].PFreqLfoEnabled); - if (xml->enterbranch("FREQUENCY_LFO")) { + VoicePar[nvoice].PFreqLfoEnabled = xml->getparbool( + "freq_lfo_enabled", + VoicePar[nvoice]. + PFreqLfoEnabled); + if(xml->enterbranch("FREQUENCY_LFO")) { VoicePar[nvoice].FreqLfo->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("FILTER_PARAMETERS")) { - if (xml->enterbranch("FILTER")) { + if(xml->enterbranch("FILTER_PARAMETERS")) { + if(xml->enterbranch("FILTER")) { VoicePar[nvoice].VoiceFilter->getfromXML(xml); xml->exitbranch(); - }; + } - VoicePar[nvoice].PFilterEnvelopeEnabled=xml->getparbool("filter_envelope_enabled",VoicePar[nvoice].PFilterEnvelopeEnabled); - if (xml->enterbranch("FILTER_ENVELOPE")) { + VoicePar[nvoice].PFilterEnvelopeEnabled = xml->getparbool( + "filter_envelope_enabled", + VoicePar[nvoice].PFilterEnvelopeEnabled); + if(xml->enterbranch("FILTER_ENVELOPE")) { VoicePar[nvoice].FilterEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } - VoicePar[nvoice].PFilterLfoEnabled=xml->getparbool("filter_lfo_enabled",VoicePar[nvoice].PFilterLfoEnabled); - if (xml->enterbranch("FILTER_LFO")) { + VoicePar[nvoice].PFilterLfoEnabled = xml->getparbool( + "filter_lfo_enabled", + VoicePar[nvoice].PFilterLfoEnabled); + if(xml->enterbranch("FILTER_LFO")) { VoicePar[nvoice].FilterLfo->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; - - if (xml->enterbranch("FM_PARAMETERS")) { - VoicePar[nvoice].PFMVoice=xml->getpar("input_voice",VoicePar[nvoice].PFMVoice,-1,nvoice-1); - - VoicePar[nvoice].PFMVolume=xml->getpar127("volume",VoicePar[nvoice].PFMVolume); - VoicePar[nvoice].PFMVolumeDamp=xml->getpar127("volume_damp",VoicePar[nvoice].PFMVolumeDamp); - VoicePar[nvoice].PFMVelocityScaleFunction=xml->getpar127("velocity_sensing",VoicePar[nvoice].PFMVelocityScaleFunction); - - VoicePar[nvoice].PFMAmpEnvelopeEnabled=xml->getparbool("amp_envelope_enabled",VoicePar[nvoice].PFMAmpEnvelopeEnabled); - if (xml->enterbranch("AMPLITUDE_ENVELOPE")) { + } + + if(xml->enterbranch("FM_PARAMETERS")) { + VoicePar[nvoice].PFMVoice = + xml->getpar("input_voice", + VoicePar[nvoice].PFMVoice, + -1, + nvoice - 1); + + VoicePar[nvoice].PFMVolume = + xml->getpar127("volume", VoicePar[nvoice].PFMVolume); + VoicePar[nvoice].PFMVolumeDamp = xml->getpar127( + "volume_damp", + VoicePar[nvoice]. + PFMVolumeDamp); + VoicePar[nvoice].PFMVelocityScaleFunction = xml->getpar127( + "velocity_sensing", + VoicePar[nvoice].PFMVelocityScaleFunction); + + VoicePar[nvoice].PFMAmpEnvelopeEnabled = xml->getparbool( + "amp_envelope_enabled", + VoicePar[nvoice].PFMAmpEnvelopeEnabled); + if(xml->enterbranch("AMPLITUDE_ENVELOPE")) { VoicePar[nvoice].FMAmpEnvelope->getfromXML(xml); xml->exitbranch(); - }; - - if (xml->enterbranch("MODULATOR")) { - VoicePar[nvoice].PFMDetune=xml->getpar("detune",VoicePar[nvoice].PFMDetune,0,16383); - VoicePar[nvoice].PFMCoarseDetune=xml->getpar("coarse_detune",VoicePar[nvoice].PFMCoarseDetune,0,16383); - VoicePar[nvoice].PFMDetuneType=xml->getpar127("detune_type",VoicePar[nvoice].PFMDetuneType); - - VoicePar[nvoice].PFMFreqEnvelopeEnabled=xml->getparbool("freq_envelope_enabled",VoicePar[nvoice].PFMFreqEnvelopeEnabled); - if (xml->enterbranch("FREQUENCY_ENVELOPE")) { + } + + if(xml->enterbranch("MODULATOR")) { + VoicePar[nvoice].PFMDetune = + xml->getpar("detune", VoicePar[nvoice].PFMDetune, 0, 16383); + VoicePar[nvoice].PFMCoarseDetune = xml->getpar( + "coarse_detune", + VoicePar[nvoice]. + PFMCoarseDetune, + 0, + 16383); + VoicePar[nvoice].PFMDetuneType = xml->getpar127( + "detune_type", + VoicePar[nvoice]. + PFMDetuneType); + + VoicePar[nvoice].PFMFreqEnvelopeEnabled = xml->getparbool( + "freq_envelope_enabled", + VoicePar[nvoice].PFMFreqEnvelopeEnabled); + if(xml->enterbranch("FREQUENCY_ENVELOPE")) { VoicePar[nvoice].FMFreqEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } - if (xml->enterbranch("OSCIL")) { + if(xml->enterbranch("OSCIL")) { VoicePar[nvoice].FMSmp->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } xml->exitbranch(); - }; -}; - + } +} diff --git a/src/Params/ADnoteParameters.h b/src/Params/ADnoteParameters.h @@ -35,7 +35,9 @@ #include "../DSP/FFTwrapper.h" #include "Presets.h" -enum FMTYPE {NONE,MORPH,RING_MOD,PHASE_MOD,FREQ_MOD,PITCH_MOD}; +enum FMTYPE { + NONE, MORPH, RING_MOD, PHASE_MOD, FREQ_MOD, PITCH_MOD +}; extern int ADnote_unison_sizes[]; /*****************************************************************/ @@ -43,7 +45,6 @@ extern int ADnote_unison_sizes[]; /*****************************************************************/ struct ADnoteGlobalParam { - /* The instrument type - MONO/STEREO If the mode is MONO, the panning of voices are not used Stereo=1, Mono=0. */ @@ -54,35 +55,36 @@ struct ADnoteGlobalParam { /****************************************** * FREQUENCY GLOBAL PARAMETERS * ******************************************/ - unsigned short int PDetune;//fine detune - unsigned short int PCoarseDetune;//coarse detune+octave - unsigned char PDetuneType;//detune type + unsigned short int PDetune; //fine detune + unsigned short int PCoarseDetune; //coarse detune+octave + unsigned char PDetuneType; //detune type - unsigned char PBandwidth;//how much the relative fine detunes of the voices are changed + unsigned char PBandwidth; //how much the relative fine detunes of the voices are changed - EnvelopeParams *FreqEnvelope; //Frequency Envelope + EnvelopeParams *FreqEnvelope; //Frequency Envelope - LFOParams *FreqLfo;//Frequency LFO + LFOParams *FreqLfo; //Frequency LFO /******************************************** * AMPLITUDE GLOBAL PARAMETERS * ********************************************/ /* Panning - 0 - random - 1 - left - 64 - center - 127 - right */ - unsigned char PPanning; + 1 - left + 64 - center + 127 - right */ + unsigned char PPanning; - unsigned char PVolume; + unsigned char PVolume; - unsigned char PAmpVelocityScaleFunction; + unsigned char PAmpVelocityScaleFunction; EnvelopeParams *AmpEnvelope; - LFOParams *AmpLfo; + LFOParams *AmpLfo; - unsigned char PPunchStrength,PPunchTime,PPunchStretch,PPunchVelocitySensing; + unsigned char PPunchStrength, PPunchTime, PPunchStretch, + PPunchVelocitySensing; /****************************************** * FILTER GLOBAL PARAMETERS * @@ -93,11 +95,11 @@ struct ADnoteGlobalParam { unsigned char PFilterVelocityScale; // filter velocity sensing - unsigned char PFilterVelocityScaleFunction; + unsigned char PFilterVelocityScaleFunction; EnvelopeParams *FilterEnvelope; - LFOParams *FilterLfo; + LFOParams *FilterLfo; // RESONANCE Resonance *Reson; @@ -112,27 +114,26 @@ struct ADnoteGlobalParam { /* VOICE PARAMETERS */ /***********************************************************/ struct ADnoteVoiceParam { - /** If the voice is enabled */ unsigned char Enabled; - /** How many subvoices are used in this voice */ - unsigned char Unison_size; + /** How many subvoices are used in this voice */ + unsigned char Unison_size; - /** How subvoices are spread */ - unsigned char Unison_frequency_spread; + /** How subvoices are spread */ + unsigned char Unison_frequency_spread; - /** Stereo spread of the subvoices*/ - unsigned char Unison_stereo_spread; - - /** Vibratto of the subvoices (which makes the unison more "natural")*/ - unsigned char Unison_vibratto; + /** Stereo spread of the subvoices*/ + unsigned char Unison_stereo_spread; - /** Medium speed of the vibratto of the subvoices*/ - unsigned char Unison_vibratto_speed; + /** Vibratto of the subvoices (which makes the unison more "natural")*/ + unsigned char Unison_vibratto; - /** Unison invert phase */ - unsigned char Unison_invert_phase;//0=none,1=random,2=50%,3=33%,4=25% + /** Medium speed of the vibratto of the subvoices*/ + unsigned char Unison_vibratto_speed; + + /** Unison invert phase */ + unsigned char Unison_invert_phase; //0=none,1=random,2=50%,3=33%,4=25% /** Type of the voice (0=Sound,1=Noise)*/ unsigned char Type; @@ -144,11 +145,11 @@ struct ADnoteVoiceParam { unsigned char Presonance; // What external oscil should I use, -1 for internal OscilSmp&FMSmp - short int Pextoscil,PextFMoscil; + short int Pextoscil, PextFMoscil; // it is not allowed that the externoscil,externFMoscil => current voice // oscillator phases - unsigned char Poscilphase,PFMoscilphase; + unsigned char Poscilphase, PFMoscilphase; // filter bypass unsigned char Pfilterbypass; @@ -178,12 +179,12 @@ struct ADnoteVoiceParam { unsigned char PDetuneType; /* Frequency Envelope */ - unsigned char PFreqEnvelopeEnabled; + unsigned char PFreqEnvelopeEnabled; EnvelopeParams *FreqEnvelope; /* Frequency LFO */ unsigned char PFreqLfoEnabled; - LFOParams *FreqLfo; + LFOParams *FreqLfo; /*************************** @@ -191,9 +192,9 @@ struct ADnoteVoiceParam { ***************************/ /* Panning 0 - random - 1 - left - 64 - center - 127 - right + 1 - left + 64 - center + 127 - right The Panning is ignored if the instrument is mono */ unsigned char PPanning; @@ -207,12 +208,12 @@ struct ADnoteVoiceParam { unsigned char PAmpVelocityScaleFunction; /* Amplitude Envelope */ - unsigned char PAmpEnvelopeEnabled; + unsigned char PAmpEnvelopeEnabled; EnvelopeParams *AmpEnvelope; /* Amplitude LFO */ unsigned char PAmpLfoEnabled; - LFOParams *AmpLfo; + LFOParams *AmpLfo; @@ -225,12 +226,12 @@ struct ADnoteVoiceParam { FilterParams *VoiceFilter; /* Filter Envelope */ - unsigned char PFilterEnvelopeEnabled; + unsigned char PFilterEnvelopeEnabled; EnvelopeParams *FilterEnvelope; /* LFO Envelope */ unsigned char PFilterLfoEnabled; - LFOParams *FilterLfo; + LFOParams *FilterLfo; /**************************** * MODULLATOR PARAMETERS * @@ -266,40 +267,41 @@ struct ADnoteVoiceParam { unsigned char PFMDetuneType; /* Frequency Envelope of the Modullator */ - unsigned char PFMFreqEnvelopeEnabled; + unsigned char PFMFreqEnvelopeEnabled; EnvelopeParams *FMFreqEnvelope; /* Frequency Envelope of the Modullator */ - unsigned char PFMAmpEnvelopeEnabled; + unsigned char PFMAmpEnvelopeEnabled; EnvelopeParams *FMAmpEnvelope; }; class ADnoteParameters:public Presets { -public: - ADnoteParameters(FFTwrapper *fft_); - ~ADnoteParameters(); - - ADnoteGlobalParam GlobalPar; - ADnoteVoiceParam VoicePar[NUM_VOICES]; - - void defaults(); - void add2XML(XMLwrapper *xml); - void getfromXML(XMLwrapper *xml); - - REALTYPE getBandwidthDetuneMultiplier(); - REALTYPE getUnisonFrequencySpreadCents(int nvoice); - int get_unison_size_index(int nvoice); - void set_unison_size_index(int nvoice,int index); -private: - void defaults(int n);//n is the nvoice - - void EnableVoice(int nvoice); - void KillVoice(int nvoice); - FFTwrapper *fft; - - void add2XMLsection(XMLwrapper *xml,int n); - void getfromXMLsection(XMLwrapper *xml,int n); + public: + ADnoteParameters(FFTwrapper *fft_); + ~ADnoteParameters(); + + ADnoteGlobalParam GlobalPar; + ADnoteVoiceParam VoicePar[NUM_VOICES]; + + void defaults(); + void add2XML(XMLwrapper *xml); + void getfromXML(XMLwrapper *xml); + + REALTYPE getBandwidthDetuneMultiplier(); + REALTYPE getUnisonFrequencySpreadCents(int nvoice); + int get_unison_size_index(int nvoice); + void set_unison_size_index(int nvoice, int index); + private: + void defaults(int n); //n is the nvoice + + void EnableVoice(int nvoice); + void KillVoice(int nvoice); + FFTwrapper *fft; + + void add2XMLsection(XMLwrapper *xml, int n); + void getfromXMLsection(XMLwrapper *xml, int n); }; #endif + diff --git a/src/Params/Controller.cpp b/src/Params/Controller.cpp @@ -28,50 +28,48 @@ Controller::Controller() { defaults(); resetall(); -}; +} Controller::~Controller() -{ -}; +{} void Controller::defaults() { - setpitchwheelbendrange(200);//2 halftones - expression.receive=1; - panning.depth=64; - filtercutoff.depth=64; - filterq.depth=64; - bandwidth.depth=64; - bandwidth.exponential=0; - modwheel.depth=80; - modwheel.exponential=0; - fmamp.receive=1; - volume.receive=1; - sustain.receive=1; - NRPN.receive=1; - - portamento.portamento=0; - portamento.used=0; - portamento.proportional=0; - portamento.propRate=80; - portamento.propDepth=90; - portamento.receive=1; - portamento.time=64; - portamento.updowntimestretch=64; - portamento.pitchthresh=3; - portamento.pitchthreshtype=1; - portamento.noteusing=-1; - resonancecenter.depth=64; - resonancebandwidth.depth=64; - - initportamento(440.0,440.0,false); // Now has a third argument + setpitchwheelbendrange(200); //2 halftones + expression.receive = 1; + panning.depth = 64; + filtercutoff.depth = 64; + filterq.depth = 64; + bandwidth.depth = 64; + bandwidth.exponential = 0; + modwheel.depth = 80; + modwheel.exponential = 0; + fmamp.receive = 1; + volume.receive = 1; + sustain.receive = 1; + NRPN.receive = 1; + + portamento.portamento = 0; + portamento.used = 0; + portamento.proportional = 0; + portamento.propRate = 80; + portamento.propDepth = 90; + portamento.receive = 1; + portamento.time = 64; + portamento.updowntimestretch = 64; + portamento.pitchthresh = 3; + portamento.pitchthreshtype = 1; + portamento.noteusing = -1; + resonancecenter.depth = 64; + resonancebandwidth.depth = 64; + + initportamento(440.0, 440.0, false); // Now has a third argument setportamento(0); - -}; +} void Controller::resetall() { - setpitchwheel(0);//center + setpitchwheel(0); //center setexpression(127); setpanning(64); setfiltercutoff(64); @@ -85,276 +83,333 @@ void Controller::resetall() setresonancebw(64); //reset the NRPN - NRPN.parhi=-1; - NRPN.parlo=-1; - NRPN.valhi=-1; - NRPN.vallo=-1; -}; + NRPN.parhi = -1; + NRPN.parlo = -1; + NRPN.valhi = -1; + NRPN.vallo = -1; +} void Controller::setpitchwheel(int value) { - pitchwheel.data=value; - REALTYPE cents=value/8192.0; - cents*=pitchwheel.bendrange; - pitchwheel.relfreq=pow(2,cents/1200.0); + pitchwheel.data = value; + REALTYPE cents = value / 8192.0; + cents *= pitchwheel.bendrange; + pitchwheel.relfreq = pow(2, cents / 1200.0); //fprintf(stderr,"%ld %ld -> %.3f\n",pitchwheel.bendrange,pitchwheel.data,pitchwheel.relfreq);fflush(stderr); -}; +} void Controller::setpitchwheelbendrange(unsigned short int value) { - pitchwheel.bendrange=value; -}; + pitchwheel.bendrange = value; +} void Controller::setexpression(int value) { - expression.data=value; - if (expression.receive!=0) expression.relvolume=value/127.0; - else expression.relvolume=1.0; -}; + expression.data = value; + if(expression.receive != 0) + expression.relvolume = value / 127.0; + else + expression.relvolume = 1.0; +} void Controller::setpanning(int value) { - panning.data=value; - panning.pan=(value/128.0-0.5)*(panning.depth/64.0); -}; + panning.data = value; + panning.pan = (value / 128.0 - 0.5) * (panning.depth / 64.0); +} void Controller::setfiltercutoff(int value) { - filtercutoff.data=value; - filtercutoff.relfreq=(value-64.0)*filtercutoff.depth/4096.0*3.321928;//3.3219..=ln2(10) -}; + filtercutoff.data = value; + filtercutoff.relfreq = + (value - 64.0) * filtercutoff.depth / 4096.0 * 3.321928; //3.3219..=ln2(10) +} void Controller::setfilterq(int value) { - filterq.data=value; - filterq.relq=pow(30.0,(value-64.0)/64.0*(filterq.depth/64.0)); -}; + filterq.data = value; + filterq.relq = pow(30.0, (value - 64.0) / 64.0 * (filterq.depth / 64.0)); +} void Controller::setbandwidth(int value) { - bandwidth.data=value; - if (bandwidth.exponential==0) { - REALTYPE tmp=pow(25.0,pow(bandwidth.depth/127.0,1.5))-1.0; - if ((value<64)&&(bandwidth.depth>=64)) tmp=1.0; - bandwidth.relbw=(value/64.0-1.0)*tmp+1.0; - if (bandwidth.relbw<0.01) bandwidth.relbw=0.01; - } else { - bandwidth.relbw=pow(25.0,(value-64.0)/64.0*(bandwidth.depth/64.0)); - }; -}; + bandwidth.data = value; + if(bandwidth.exponential == 0) { + REALTYPE tmp = pow(25.0, pow(bandwidth.depth / 127.0, 1.5)) - 1.0; + if((value < 64) && (bandwidth.depth >= 64)) + tmp = 1.0; + bandwidth.relbw = (value / 64.0 - 1.0) * tmp + 1.0; + if(bandwidth.relbw < 0.01) + bandwidth.relbw = 0.01; + } + else + bandwidth.relbw = + pow(25.0, (value - 64.0) / 64.0 * (bandwidth.depth / 64.0)); + ; +} void Controller::setmodwheel(int value) { - modwheel.data=value; - if (modwheel.exponential==0) { - REALTYPE tmp=pow(25.0,pow(modwheel.depth/127.0,1.5)*2.0)/25.0; - if ((value<64)&&(modwheel.depth>=64)) tmp=1.0; - modwheel.relmod=(value/64.0-1.0)*tmp+1.0; - if (modwheel.relmod<0.0) modwheel.relmod=0.0; - } else modwheel.relmod=pow(25.0,(value-64.0)/64.0*(modwheel.depth/80.0)); -}; + modwheel.data = value; + if(modwheel.exponential == 0) { + REALTYPE tmp = pow(25.0, pow(modwheel.depth / 127.0, 1.5) * 2.0) / 25.0; + if((value < 64) && (modwheel.depth >= 64)) + tmp = 1.0; + modwheel.relmod = (value / 64.0 - 1.0) * tmp + 1.0; + if(modwheel.relmod < 0.0) + modwheel.relmod = 0.0; + } + else + modwheel.relmod = + pow(25.0, (value - 64.0) / 64.0 * (modwheel.depth / 80.0)); +} void Controller::setfmamp(int value) { - fmamp.data=value; - fmamp.relamp=value/127.0; - if (fmamp.receive!=0) fmamp.relamp=value/127.0; - else fmamp.relamp=1.0; -}; + fmamp.data = value; + fmamp.relamp = value / 127.0; + if(fmamp.receive != 0) + fmamp.relamp = value / 127.0; + else + fmamp.relamp = 1.0; +} void Controller::setvolume(int value) { - volume.data=value; - if (volume.receive!=0) volume.volume=pow(0.1,(127-value)/127.0*2.0); - else volume.volume=1.0; -}; + volume.data = value; + if(volume.receive != 0) + volume.volume = pow(0.1, (127 - value) / 127.0 * 2.0); + else + volume.volume = 1.0; +} void Controller::setsustain(int value) { - sustain.data=value; - if (sustain.receive!=0) sustain.sustain=((value<64) ? 0 : 1 ); - else sustain.sustain=0; -}; + sustain.data = value; + if(sustain.receive != 0) + sustain.sustain = ((value < 64) ? 0 : 1); + else + sustain.sustain = 0; +} void Controller::setportamento(int value) { - portamento.data=value; - if (portamento.receive!=0) portamento.portamento=((value<64) ? 0 : 1 ); -}; - -int Controller::initportamento(REALTYPE oldfreq,REALTYPE newfreq,bool legatoflag) + portamento.data = value; + if(portamento.receive != 0) + portamento.portamento = ((value < 64) ? 0 : 1); +} + +int Controller::initportamento(REALTYPE oldfreq, + REALTYPE newfreq, + bool legatoflag) { - portamento.x=0.0; + portamento.x = 0.0; + + if(legatoflag) { // Legato in progress + if(portamento.portamento == 0) + return 0; + } + else // No legato, do the original if...return + if((portamento.used != 0) || (portamento.portamento == 0)) + return 0; + ; - if (legatoflag) { // Legato in progress - if (portamento.portamento==0) return(0); - } else { // No legato, do the original if...return - if ((portamento.used!=0) || (portamento.portamento==0)) return(0); - }; + REALTYPE portamentotime = pow(100.0, portamento.time / 127.0) / 50.0; //portamento time in seconds - REALTYPE portamentotime=pow(100.0,portamento.time/127.0)/50.0;//portamento time in seconds - - if (portamento.proportional) { + if(portamento.proportional) { //If there is a min(float,float) and a max(float,float) then they //could be used here //Linear functors could also make this nicer if(oldfreq > newfreq) //2 is the center of propRate - portamentotime *= pow(oldfreq/newfreq/(portamento.propRate/127.0*3+.05), - (portamento.propDepth/127.0*1.6+.2)); + portamentotime *= + pow(oldfreq / newfreq / (portamento.propRate / 127.0 * 3 + .05), + (portamento.propDepth / 127.0 * 1.6 + .2)); else //1 is the center of propDepth - portamentotime *= pow(newfreq/oldfreq/(portamento.propRate/127.0*3+.05), - (portamento.propDepth/127.0*1.6+.2)); + portamentotime *= + pow(newfreq / oldfreq / (portamento.propRate / 127.0 * 3 + .05), + (portamento.propDepth / 127.0 * 1.6 + .2)); } - if ((portamento.updowntimestretch>=64)&&(newfreq<oldfreq)) { - if (portamento.updowntimestretch==127) return(0); - portamentotime*=pow(0.1,(portamento.updowntimestretch-64)/63.0); + if((portamento.updowntimestretch >= 64) && (newfreq < oldfreq)) { + if(portamento.updowntimestretch == 127) + return 0; + portamentotime *= pow(0.1, (portamento.updowntimestretch - 64) / 63.0); + } + if((portamento.updowntimestretch < 64) && (newfreq > oldfreq)) { + if(portamento.updowntimestretch == 0) + return 0; + portamentotime *= pow(0.1, (64.0 - portamento.updowntimestretch) / 64.0); } - if ((portamento.updowntimestretch<64)&&(newfreq>oldfreq)) { - if (portamento.updowntimestretch==0) return(0); - portamentotime*=pow(0.1,(64.0-portamento.updowntimestretch)/64.0); - }; //printf("%f->%f : Time %f\n",oldfreq,newfreq,portamentotime); - portamento.dx=SOUND_BUFFER_SIZE/(portamentotime*SAMPLE_RATE); - portamento.origfreqrap=oldfreq/newfreq; + portamento.dx = SOUND_BUFFER_SIZE / (portamentotime * SAMPLE_RATE); + portamento.origfreqrap = oldfreq / newfreq; - REALTYPE tmprap=( (portamento.origfreqrap>1.0) ? - (portamento.origfreqrap) : - (1.0/portamento.origfreqrap) ); + REALTYPE tmprap = ((portamento.origfreqrap > 1.0) ? + (portamento.origfreqrap) : + (1.0 / portamento.origfreqrap)); - REALTYPE thresholdrap=pow(2.0,portamento.pitchthresh/12.0); - if ((portamento.pitchthreshtype==0) && (tmprap-0.00001>thresholdrap) ) return(0); - if ((portamento.pitchthreshtype==1) && (tmprap+0.00001<thresholdrap) ) return(0); + REALTYPE thresholdrap = pow(2.0, portamento.pitchthresh / 12.0); + if((portamento.pitchthreshtype == 0) && (tmprap - 0.00001 > thresholdrap)) + return 0; + if((portamento.pitchthreshtype == 1) && (tmprap + 0.00001 < thresholdrap)) + return 0; - portamento.used=1; - portamento.freqrap=portamento.origfreqrap; - return (1); -}; + portamento.used = 1; + portamento.freqrap = portamento.origfreqrap; + return 1; +} void Controller::updateportamento() { - if (portamento.used==0) return; + if(portamento.used == 0) + return; - portamento.x+=portamento.dx; - if (portamento.x>1.0) { - portamento.x=1.0; - portamento.used=0; - }; - portamento.freqrap=(1.0-portamento.x)*portamento.origfreqrap+portamento.x; -}; + portamento.x += portamento.dx; + if(portamento.x > 1.0) { + portamento.x = 1.0; + portamento.used = 0; + } + portamento.freqrap = + (1.0 - portamento.x) * portamento.origfreqrap + portamento.x; +} void Controller::setresonancecenter(int value) { - resonancecenter.data=value; - resonancecenter.relcenter=pow(3.0,(value-64.0)/64.0*(resonancecenter.depth/64.0)); -}; + resonancecenter.data = value; + resonancecenter.relcenter = + pow(3.0, (value - 64.0) / 64.0 * (resonancecenter.depth / 64.0)); +} void Controller::setresonancebw(int value) { - resonancebandwidth.data=value; - resonancebandwidth.relbw=pow(1.5,(value-64.0)/64.0*(resonancebandwidth.depth/127.0)); -}; + resonancebandwidth.data = value; + resonancebandwidth.relbw = + pow(1.5, (value - 64.0) / 64.0 * (resonancebandwidth.depth / 127.0)); +} //Returns 0 if there is NRPN or 1 if there is not int Controller::getnrpn(int *parhi, int *parlo, int *valhi, int *vallo) { - if (NRPN.receive==0) return(1); - if ((NRPN.parhi<0)||(NRPN.parlo<0)||(NRPN.valhi<0)||(NRPN.vallo<0)) - return(1); + if(NRPN.receive == 0) + return 1; + if((NRPN.parhi < 0) || (NRPN.parlo < 0) || (NRPN.valhi < 0) + || (NRPN.vallo < 0)) + return 1; - *parhi=NRPN.parhi; - *parlo=NRPN.parlo; - *valhi=NRPN.valhi; - *vallo=NRPN.vallo; - return(0); -}; + *parhi = NRPN.parhi; + *parlo = NRPN.parlo; + *valhi = NRPN.valhi; + *vallo = NRPN.vallo; + return 0; +} -void Controller::setparameternumber(unsigned int type,int value) +void Controller::setparameternumber(unsigned int type, int value) { - switch (type) { + switch(type) { case C_nrpnhi: - NRPN.parhi=value; - NRPN.valhi=-1; - NRPN.vallo=-1;//clear the values + NRPN.parhi = value; + NRPN.valhi = -1; + NRPN.vallo = -1; //clear the values break; case C_nrpnlo: - NRPN.parlo=value; - NRPN.valhi=-1; - NRPN.vallo=-1;//clear the values + NRPN.parlo = value; + NRPN.valhi = -1; + NRPN.vallo = -1; //clear the values break; case C_dataentryhi: - if ((NRPN.parhi>=0)&&(NRPN.parlo>=0)) NRPN.valhi=value; + if((NRPN.parhi >= 0) && (NRPN.parlo >= 0)) + NRPN.valhi = value; break; case C_dataentrylo: - if ((NRPN.parhi>=0)&&(NRPN.parlo>=0)) NRPN.vallo=value; + if((NRPN.parhi >= 0) && (NRPN.parlo >= 0)) + NRPN.vallo = value; break; - }; -}; + } +} void Controller::add2XML(XMLwrapper *xml) { - xml->addpar("pitchwheel_bendrange",pitchwheel.bendrange); - - xml->addparbool("expression_receive",expression.receive); - xml->addpar("panning_depth",panning.depth); - xml->addpar("filter_cutoff_depth",filtercutoff.depth); - xml->addpar("filter_q_depth",filterq.depth); - xml->addpar("bandwidth_depth",bandwidth.depth); - xml->addpar("mod_wheel_depth",modwheel.depth); - xml->addparbool("mod_wheel_exponential",modwheel.exponential); - xml->addparbool("fm_amp_receive",fmamp.receive); - xml->addparbool("volume_receive",volume.receive); - xml->addparbool("sustain_receive",sustain.receive); - - xml->addparbool("portamento_receive",portamento.receive); - xml->addpar("portamento_time",portamento.time); - xml->addpar("portamento_pitchthresh",portamento.pitchthresh); - xml->addpar("portamento_pitchthreshtype",portamento.pitchthreshtype); - xml->addpar("portamento_portamento",portamento.portamento); - xml->addpar("portamento_updowntimestretch",portamento.updowntimestretch); - xml->addpar("portamento_proportional",portamento.proportional); - xml->addpar("portamento_proprate",portamento.propRate); - xml->addpar("portamento_propdepth",portamento.propDepth); - - xml->addpar("resonance_center_depth",resonancecenter.depth); - xml->addpar("resonance_bandwidth_depth",resonancebandwidth.depth); -}; + xml->addpar("pitchwheel_bendrange", pitchwheel.bendrange); + + xml->addparbool("expression_receive", expression.receive); + xml->addpar("panning_depth", panning.depth); + xml->addpar("filter_cutoff_depth", filtercutoff.depth); + xml->addpar("filter_q_depth", filterq.depth); + xml->addpar("bandwidth_depth", bandwidth.depth); + xml->addpar("mod_wheel_depth", modwheel.depth); + xml->addparbool("mod_wheel_exponential", modwheel.exponential); + xml->addparbool("fm_amp_receive", fmamp.receive); + xml->addparbool("volume_receive", volume.receive); + xml->addparbool("sustain_receive", sustain.receive); + + xml->addparbool("portamento_receive", portamento.receive); + xml->addpar("portamento_time", portamento.time); + xml->addpar("portamento_pitchthresh", portamento.pitchthresh); + xml->addpar("portamento_pitchthreshtype", portamento.pitchthreshtype); + xml->addpar("portamento_portamento", portamento.portamento); + xml->addpar("portamento_updowntimestretch", portamento.updowntimestretch); + xml->addpar("portamento_proportional", portamento.proportional); + xml->addpar("portamento_proprate", portamento.propRate); + xml->addpar("portamento_propdepth", portamento.propDepth); + + xml->addpar("resonance_center_depth", resonancecenter.depth); + xml->addpar("resonance_bandwidth_depth", resonancebandwidth.depth); +} void Controller::getfromXML(XMLwrapper *xml) { - pitchwheel.bendrange=xml->getpar("pitchwheel_bendrange",pitchwheel.bendrange,-6400,6400); - - expression.receive=xml->getparbool("expression_receive",expression.receive); - panning.depth=xml->getpar127("panning_depth",panning.depth); - filtercutoff.depth=xml->getpar127("filter_cutoff_depth",filtercutoff.depth); - filterq.depth=xml->getpar127("filter_q_depth",filterq.depth); - bandwidth.depth=xml->getpar127("bandwidth_depth",bandwidth.depth); - modwheel.depth=xml->getpar127("mod_wheel_depth",modwheel.depth); - modwheel.exponential=xml->getparbool("mod_wheel_exponential",modwheel.exponential); - fmamp.receive=xml->getparbool("fm_amp_receive",fmamp.receive); - volume.receive=xml->getparbool("volume_receive",volume.receive); - sustain.receive=xml->getparbool("sustain_receive",sustain.receive); - - portamento.receive=xml->getparbool("portamento_receive",portamento.receive); - portamento.time=xml->getpar127("portamento_time",portamento.time); - portamento.pitchthresh=xml->getpar127("portamento_pitchthresh",portamento.pitchthresh); - portamento.pitchthreshtype=xml->getpar127("portamento_pitchthreshtype",portamento.pitchthreshtype); - portamento.portamento=xml->getpar127("portamento_portamento",portamento.portamento); - portamento.updowntimestretch=xml->getpar127("portamento_updowntimestretch",portamento.updowntimestretch); - portamento.proportional=xml->getpar127("portamento_proportional",portamento.proportional); - portamento.propRate=xml->getpar127("portamento_proprate",portamento.propRate); - portamento.propDepth=xml->getpar127("portamento_propdepth",portamento.propDepth); - - - resonancecenter.depth=xml->getpar127("resonance_center_depth",resonancecenter.depth); - resonancebandwidth.depth=xml->getpar127("resonance_bandwidth_depth",resonancebandwidth.depth); -}; - - + pitchwheel.bendrange = xml->getpar("pitchwheel_bendrange", + pitchwheel.bendrange, + -6400, + 6400); + + expression.receive = xml->getparbool("expression_receive", + expression.receive); + panning.depth = xml->getpar127("panning_depth", panning.depth); + filtercutoff.depth = xml->getpar127("filter_cutoff_depth", + filtercutoff.depth); + filterq.depth = xml->getpar127("filter_q_depth", filterq.depth); + bandwidth.depth = xml->getpar127("bandwidth_depth", bandwidth.depth); + modwheel.depth = xml->getpar127("mod_wheel_depth", modwheel.depth); + modwheel.exponential = xml->getparbool("mod_wheel_exponential", + modwheel.exponential); + fmamp.receive = xml->getparbool("fm_amp_receive", + fmamp.receive); + volume.receive = xml->getparbool("volume_receive", + volume.receive); + sustain.receive = xml->getparbool("sustain_receive", + sustain.receive); + + portamento.receive = xml->getparbool("portamento_receive", + portamento.receive); + portamento.time = xml->getpar127("portamento_time", + portamento.time); + portamento.pitchthresh = xml->getpar127("portamento_pitchthresh", + portamento.pitchthresh); + portamento.pitchthreshtype = xml->getpar127("portamento_pitchthreshtype", + portamento.pitchthreshtype); + portamento.portamento = xml->getpar127("portamento_portamento", + portamento.portamento); + portamento.updowntimestretch = xml->getpar127( + "portamento_updowntimestretch", + portamento.updowntimestretch); + portamento.proportional = xml->getpar127("portamento_proportional", + portamento.proportional); + portamento.propRate = xml->getpar127("portamento_proprate", + portamento.propRate); + portamento.propDepth = xml->getpar127("portamento_propdepth", + portamento.propDepth); + + + resonancecenter.depth = xml->getpar127("resonance_center_depth", + resonancecenter.depth); + resonancebandwidth.depth = xml->getpar127("resonance_bandwidth_depth", + resonancebandwidth.depth); +} diff --git a/src/Params/Controller.h b/src/Params/Controller.h @@ -30,191 +30,191 @@ /**(Midi) Controllers implementation*/ class Controller { -public: - Controller(); - ~Controller(); - void resetall(); - - void add2XML(XMLwrapper *xml); - void defaults(); - void getfromXML(XMLwrapper *xml); - - //Controllers functions - void setpitchwheel(int value); - void setpitchwheelbendrange(unsigned short int value); - void setexpression(int value); - void setpanning(int value); - void setfiltercutoff(int value); - void setfilterq(int value); - void setbandwidth(int value); - void setmodwheel(int value); - void setfmamp(int value); - void setvolume(int value); - void setsustain(int value); - /**Enable or disable portamento - * @param value 0-127 MIDI value (greater than 64 enables)*/ - void setportamento(int value); - void setresonancecenter(int value); - void setresonancebw(int value); - - - void setparameternumber(unsigned int type,int value);//used for RPN and NRPN's - int getnrpn(int *parhi, int *parlo, int *valhi, int *vallo); - - /** - * Initialize a portamento - * - * @param oldfreq Starting frequency of the portamento (Hz) - * @param newfreq Ending frequency of the portamento (Hz) - * @param legatoflag true when legato is in progress, false otherwise - * @returns 1 if properly initialized, 0 otherwise*/ - int initportamento(REALTYPE oldfreq,REALTYPE newfreq,bool legatoflag); - /**Update portamento's freqrap to next value based upon dx*/ - void updateportamento(); - - // Controllers values - struct {//Pitch Wheel - int data; - short int bendrange;//bendrange is in cents - REALTYPE relfreq;//the relative frequency (default is 1.0) - } pitchwheel; - - struct {//Expression - int data; - REALTYPE relvolume; - unsigned char receive; - } expression; - - struct {//Panning - int data; - REALTYPE pan; - unsigned char depth; - } panning; - - - struct {//Filter cutoff - int data; - REALTYPE relfreq; - unsigned char depth; - } filtercutoff; - - struct {//Filter Q - int data; - REALTYPE relq; - unsigned char depth; - } filterq; - - struct {//Bandwidth - int data; - REALTYPE relbw; - unsigned char depth; - unsigned char exponential; - } bandwidth; - - struct {//Modulation Wheel - int data; - REALTYPE relmod; - unsigned char depth; - unsigned char exponential; - } modwheel; - - struct {//FM amplitude - int data; - REALTYPE relamp; - unsigned char receive; - } fmamp; - - struct {//Volume - int data; - REALTYPE volume; - unsigned char receive; - } volume; - - struct {//Sustain - int data,sustain; - unsigned char receive; - } sustain; - - struct {/**<Portamento*/ - //parameters - int data; - unsigned char portamento; - /**Whether the portamento midi events are received or not*/ - unsigned char receive; - /** The time that it takes for the portamento to complete + public: + Controller(); + ~Controller(); + void resetall(); + + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); + + //Controllers functions + void setpitchwheel(int value); + void setpitchwheelbendrange(unsigned short int value); + void setexpression(int value); + void setpanning(int value); + void setfiltercutoff(int value); + void setfilterq(int value); + void setbandwidth(int value); + void setmodwheel(int value); + void setfmamp(int value); + void setvolume(int value); + void setsustain(int value); + /**Enable or disable portamento + * @param value 0-127 MIDI value (greater than 64 enables)*/ + void setportamento(int value); + void setresonancecenter(int value); + void setresonancebw(int value); + + + void setparameternumber(unsigned int type, int value); //used for RPN and NRPN's + int getnrpn(int *parhi, int *parlo, int *valhi, int *vallo); + + /** + * Initialize a portamento * - * Translates in an expontal fashion to 0 Seconds to 1.93 Seconds - * of completion time*/ - unsigned char time; - /**If the portamento is proportinal to the distance spanned - * - * 0 - constant time(default) - * 1 - proportional*/ - unsigned char proportional; - /**Rate of proportinal portamento*/ - unsigned char propRate; - /**Depth of proportinal portamento*/ - unsigned char propDepth; - /**pitchthresh is the threshold of enabling protamento*/ - unsigned char pitchthresh; - /**enable the portamento only below(0)/above(1) the threshold*/ - unsigned char pitchthreshtype; - - /**this value represent how the portamento time is reduced - * 0 - for down portamento - * 1-63 - the up portamento's time is smaller than the down portamento - * 64 - the portamento time is always the same - * 64-126 - the down portamento's time is smaller than the up portamento - * 127 - for upper portamento - * 'up portamento' means when the frequency is rising - * (eg: the portamento is from 200Hz to 300 Hz) - * 'down portamento' means when the frequency is lowering - * (eg: the portamento is from 300Hz to 200 Hz) - */ - unsigned char updowntimestretch; - /**this value is used to compute the actual portamento - * - * This is a multiplyer to change the frequency of the newer - * frequency to fit the profile of the portamento. - * This will be linear with respect to x.*/ - REALTYPE freqrap; - /**this is used by the Part for knowing which note uses the portamento*/ - int noteusing; - /**if a the portamento is used by a note - * \todo see if this can be a bool*/ - int used; - - //Internal data - - /**x is from 0.0 (start portamento) to 1.0 (finished portamento)*/ - REALTYPE x; - /**dx is the increment to x when updateportamento is called*/ - REALTYPE dx; - /** this is used for computing oldfreq value from x*/ - REALTYPE origfreqrap; - } portamento; - - struct {//Resonance Center Frequency - int data; - REALTYPE relcenter; - unsigned char depth; - } resonancecenter; - - struct {//Resonance Bandwidth - int data; - REALTYPE relbw; - unsigned char depth; - } resonancebandwidth; - - - /** RPN and NPRPN */ - struct {//nrpn - int parhi,parlo; - int valhi,vallo; - unsigned char receive;//this is saved to disk by Master - } NRPN; - -private: + * @param oldfreq Starting frequency of the portamento (Hz) + * @param newfreq Ending frequency of the portamento (Hz) + * @param legatoflag true when legato is in progress, false otherwise + * @returns 1 if properly initialized, 0 otherwise*/ + int initportamento(REALTYPE oldfreq, REALTYPE newfreq, bool legatoflag); + /**Update portamento's freqrap to next value based upon dx*/ + void updateportamento(); + + // Controllers values + struct { //Pitch Wheel + int data; + short int bendrange; //bendrange is in cents + REALTYPE relfreq; //the relative frequency (default is 1.0) + } pitchwheel; + + struct { //Expression + int data; + REALTYPE relvolume; + unsigned char receive; + } expression; + + struct { //Panning + int data; + REALTYPE pan; + unsigned char depth; + } panning; + + + struct { //Filter cutoff + int data; + REALTYPE relfreq; + unsigned char depth; + } filtercutoff; + + struct { //Filter Q + int data; + REALTYPE relq; + unsigned char depth; + } filterq; + + struct { //Bandwidth + int data; + REALTYPE relbw; + unsigned char depth; + unsigned char exponential; + } bandwidth; + + struct { //Modulation Wheel + int data; + REALTYPE relmod; + unsigned char depth; + unsigned char exponential; + } modwheel; + + struct { //FM amplitude + int data; + REALTYPE relamp; + unsigned char receive; + } fmamp; + + struct { //Volume + int data; + REALTYPE volume; + unsigned char receive; + } volume; + + struct { //Sustain + int data, sustain; + unsigned char receive; + } sustain; + + struct { /**<Portamento*/ + //parameters + int data; + unsigned char portamento; + /**Whether the portamento midi events are received or not*/ + unsigned char receive; + /** The time that it takes for the portamento to complete + * + * Translates in an expontal fashion to 0 Seconds to 1.93 Seconds + * of completion time*/ + unsigned char time; + /**If the portamento is proportinal to the distance spanned + * + * 0 - constant time(default) + * 1 - proportional*/ + unsigned char proportional; + /**Rate of proportinal portamento*/ + unsigned char propRate; + /**Depth of proportinal portamento*/ + unsigned char propDepth; + /**pitchthresh is the threshold of enabling protamento*/ + unsigned char pitchthresh; + /**enable the portamento only below(0)/above(1) the threshold*/ + unsigned char pitchthreshtype; + + /**this value represent how the portamento time is reduced + * 0 - for down portamento + * 1-63 - the up portamento's time is smaller than the down portamento + * 64 - the portamento time is always the same + * 64-126 - the down portamento's time is smaller than the up portamento + * 127 - for upper portamento + * 'up portamento' means when the frequency is rising + * (eg: the portamento is from 200Hz to 300 Hz) + * 'down portamento' means when the frequency is lowering + * (eg: the portamento is from 300Hz to 200 Hz) + */ + unsigned char updowntimestretch; + /**this value is used to compute the actual portamento + * + * This is a multiplyer to change the frequency of the newer + * frequency to fit the profile of the portamento. + * This will be linear with respect to x.*/ + REALTYPE freqrap; + /**this is used by the Part for knowing which note uses the portamento*/ + int noteusing; + /**if a the portamento is used by a note + * \todo see if this can be a bool*/ + int used; + + //Internal data + + /**x is from 0.0 (start portamento) to 1.0 (finished portamento)*/ + REALTYPE x; + /**dx is the increment to x when updateportamento is called*/ + REALTYPE dx; + /** this is used for computing oldfreq value from x*/ + REALTYPE origfreqrap; + } portamento; + + struct { //Resonance Center Frequency + int data; + REALTYPE relcenter; + unsigned char depth; + } resonancecenter; + + struct { //Resonance Bandwidth + int data; + REALTYPE relbw; + unsigned char depth; + } resonancebandwidth; + + + /** RPN and NPRPN */ + struct { //nrpn + int parhi, parlo; + int valhi, vallo; + unsigned char receive; //this is saved to disk by Master + } NRPN; + + private: }; #endif diff --git a/src/Params/EnvelopeParams.cpp b/src/Params/EnvelopeParams.cpp @@ -26,264 +26,273 @@ #include <stdlib.h> #include "EnvelopeParams.h" -EnvelopeParams::EnvelopeParams(unsigned char Penvstretch_,unsigned char Pforcedrelease_):Presets() +EnvelopeParams::EnvelopeParams(unsigned char Penvstretch_, + unsigned char Pforcedrelease_):Presets() { int i; - PA_dt=10; - PD_dt=10; - PR_dt=10; - PA_val=64; - PD_val=64; - PS_val=64; - PR_val=64; - - for (i=0;i<MAX_ENVELOPE_POINTS;i++) { - Penvdt[i]=32; - Penvval[i]=64; - }; - Penvdt[0]=0;//no used - Penvsustain=1; - Penvpoints=1; - Envmode=1; - Penvstretch=Penvstretch_; - Pforcedrelease=Pforcedrelease_; - Pfreemode=1; - Plinearenvelope=0; + PA_dt = 10; + PD_dt = 10; + PR_dt = 10; + PA_val = 64; + PD_val = 64; + PS_val = 64; + PR_val = 64; + + for(i = 0; i < MAX_ENVELOPE_POINTS; i++) { + Penvdt[i] = 32; + Penvval[i] = 64; + } + Penvdt[0] = 0; //no used + Penvsustain = 1; + Penvpoints = 1; + Envmode = 1; + Penvstretch = Penvstretch_; + Pforcedrelease = Pforcedrelease_; + Pfreemode = 1; + Plinearenvelope = 0; store2defaults(); -}; +} EnvelopeParams::~EnvelopeParams() -{ -}; +{} REALTYPE EnvelopeParams::getdt(char i) { - REALTYPE result=(pow(2.0,Penvdt[(int)i]/127.0*12.0)-1.0)*10.0;//miliseconds - return(result); -}; + REALTYPE result = (pow(2.0, Penvdt[(int)i] / 127.0 * 12.0) - 1.0) * 10.0; //miliseconds + return result; +} /* * ADSR/ASR... initialisations */ -void EnvelopeParams::ADSRinit(char A_dt,char D_dt,char S_val,char R_dt) +void EnvelopeParams::ADSRinit(char A_dt, char D_dt, char S_val, char R_dt) { setpresettype("Penvamplitude"); - Envmode=1; - PA_dt=A_dt; - PD_dt=D_dt; - PS_val=S_val; - PR_dt=R_dt; - Pfreemode=0; + Envmode = 1; + PA_dt = A_dt; + PD_dt = D_dt; + PS_val = S_val; + PR_dt = R_dt; + Pfreemode = 0; converttofree(); store2defaults(); -}; +} -void EnvelopeParams::ADSRinit_dB(char A_dt,char D_dt,char S_val,char R_dt) +void EnvelopeParams::ADSRinit_dB(char A_dt, char D_dt, char S_val, char R_dt) { setpresettype("Penvamplitude"); - Envmode=2; - PA_dt=A_dt; - PD_dt=D_dt; - PS_val=S_val; - PR_dt=R_dt; - Pfreemode=0; + Envmode = 2; + PA_dt = A_dt; + PD_dt = D_dt; + PS_val = S_val; + PR_dt = R_dt; + Pfreemode = 0; converttofree(); store2defaults(); -}; +} -void EnvelopeParams::ASRinit(char A_val,char A_dt,char R_val,char R_dt) +void EnvelopeParams::ASRinit(char A_val, char A_dt, char R_val, char R_dt) { setpresettype("Penvfrequency"); - Envmode=3; - PA_val=A_val; - PA_dt=A_dt; - PR_val=R_val; - PR_dt=R_dt; - Pfreemode=0; + Envmode = 3; + PA_val = A_val; + PA_dt = A_dt; + PR_val = R_val; + PR_dt = R_dt; + Pfreemode = 0; converttofree(); store2defaults(); -}; - -void EnvelopeParams::ADSRinit_filter(char A_val,char A_dt,char D_val,char D_dt,char R_dt,char R_val) +} + +void EnvelopeParams::ADSRinit_filter(char A_val, + char A_dt, + char D_val, + char D_dt, + char R_dt, + char R_val) { setpresettype("Penvfilter"); - Envmode=4; - PA_val=A_val; - PA_dt=A_dt; - PD_val=D_val; - PD_dt=D_dt; - PR_dt=R_dt; - PR_val=R_val; - Pfreemode=0; + Envmode = 4; + PA_val = A_val; + PA_dt = A_dt; + PD_val = D_val; + PD_dt = D_dt; + PR_dt = R_dt; + PR_val = R_val; + Pfreemode = 0; converttofree(); store2defaults(); -}; +} -void EnvelopeParams::ASRinit_bw(char A_val,char A_dt,char R_val,char R_dt) +void EnvelopeParams::ASRinit_bw(char A_val, char A_dt, char R_val, char R_dt) { setpresettype("Penvbandwidth"); - Envmode=5; - PA_val=A_val; - PA_dt=A_dt; - PR_val=R_val; - PR_dt=R_dt; - Pfreemode=0; + Envmode = 5; + PA_val = A_val; + PA_dt = A_dt; + PR_val = R_val; + PR_dt = R_dt; + Pfreemode = 0; converttofree(); store2defaults(); -}; +} /* * Convert the Envelope to freemode */ void EnvelopeParams::converttofree() { - switch (Envmode) { + switch(Envmode) { case 1: - Penvpoints=4; - Penvsustain=2; - Penvval[0]=0; - Penvdt[1]=PA_dt; - Penvval[1]=127; - Penvdt[2]=PD_dt; - Penvval[2]=PS_val; - Penvdt[3]=PR_dt; - Penvval[3]=0; + Penvpoints = 4; + Penvsustain = 2; + Penvval[0] = 0; + Penvdt[1] = PA_dt; + Penvval[1] = 127; + Penvdt[2] = PD_dt; + Penvval[2] = PS_val; + Penvdt[3] = PR_dt; + Penvval[3] = 0; break; case 2: - Penvpoints=4; - Penvsustain=2; - Penvval[0]=0; - Penvdt[1]=PA_dt; - Penvval[1]=127; - Penvdt[2]=PD_dt; - Penvval[2]=PS_val; - Penvdt[3]=PR_dt; - Penvval[3]=0; + Penvpoints = 4; + Penvsustain = 2; + Penvval[0] = 0; + Penvdt[1] = PA_dt; + Penvval[1] = 127; + Penvdt[2] = PD_dt; + Penvval[2] = PS_val; + Penvdt[3] = PR_dt; + Penvval[3] = 0; break; case 3: - Penvpoints=3; - Penvsustain=1; - Penvval[0]=PA_val; - Penvdt[1]=PA_dt; - Penvval[1]=64; - Penvdt[2]=PR_dt; - Penvval[2]=PR_val; + Penvpoints = 3; + Penvsustain = 1; + Penvval[0] = PA_val; + Penvdt[1] = PA_dt; + Penvval[1] = 64; + Penvdt[2] = PR_dt; + Penvval[2] = PR_val; break; case 4: - Penvpoints=4; - Penvsustain=2; - Penvval[0]=PA_val; - Penvdt[1]=PA_dt; - Penvval[1]=PD_val; - Penvdt[2]=PD_dt; - Penvval[2]=64; - Penvdt[3]=PR_dt; - Penvval[3]=PR_val; + Penvpoints = 4; + Penvsustain = 2; + Penvval[0] = PA_val; + Penvdt[1] = PA_dt; + Penvval[1] = PD_val; + Penvdt[2] = PD_dt; + Penvval[2] = 64; + Penvdt[3] = PR_dt; + Penvval[3] = PR_val; break; case 5: - Penvpoints=3; - Penvsustain=1; - Penvval[0]=PA_val; - Penvdt[1]=PA_dt; - Penvval[1]=64; - Penvdt[2]=PR_dt; - Penvval[2]=PR_val; + Penvpoints = 3; + Penvsustain = 1; + Penvval[0] = PA_val; + Penvdt[1] = PA_dt; + Penvval[1] = 64; + Penvdt[2] = PR_dt; + Penvval[2] = PR_val; break; - }; -}; + } +} void EnvelopeParams::add2XML(XMLwrapper *xml) { - xml->addparbool("free_mode",Pfreemode); - xml->addpar("env_points",Penvpoints); - xml->addpar("env_sustain",Penvsustain); - xml->addpar("env_stretch",Penvstretch); - xml->addparbool("forced_release",Pforcedrelease); - xml->addparbool("linear_envelope",Plinearenvelope); - xml->addpar("A_dt",PA_dt); - xml->addpar("D_dt",PD_dt); - xml->addpar("R_dt",PR_dt); - xml->addpar("A_val",PA_val); - xml->addpar("D_val",PD_val); - xml->addpar("S_val",PS_val); - xml->addpar("R_val",PR_val); - - if ((Pfreemode!=0)||(!xml->minimal)) { - for (int i=0;i<Penvpoints;i++) { - xml->beginbranch("POINT",i); - if (i!=0) xml->addpar("dt",Penvdt[i]); - xml->addpar("val",Penvval[i]); + xml->addparbool("free_mode", Pfreemode); + xml->addpar("env_points", Penvpoints); + xml->addpar("env_sustain", Penvsustain); + xml->addpar("env_stretch", Penvstretch); + xml->addparbool("forced_release", Pforcedrelease); + xml->addparbool("linear_envelope", Plinearenvelope); + xml->addpar("A_dt", PA_dt); + xml->addpar("D_dt", PD_dt); + xml->addpar("R_dt", PR_dt); + xml->addpar("A_val", PA_val); + xml->addpar("D_val", PD_val); + xml->addpar("S_val", PS_val); + xml->addpar("R_val", PR_val); + + if((Pfreemode != 0) || (!xml->minimal)) { + for(int i = 0; i < Penvpoints; i++) { + xml->beginbranch("POINT", i); + if(i != 0) + xml->addpar("dt", Penvdt[i]); + xml->addpar("val", Penvval[i]); xml->endbranch(); - }; - }; -}; + } + } +} void EnvelopeParams::getfromXML(XMLwrapper *xml) { - Pfreemode=xml->getparbool("free_mode",Pfreemode); - Penvpoints=xml->getpar127("env_points",Penvpoints); - Penvsustain=xml->getpar127("env_sustain",Penvsustain); - Penvstretch=xml->getpar127("env_stretch",Penvstretch); - Pforcedrelease=xml->getparbool("forced_release",Pforcedrelease); - Plinearenvelope=xml->getparbool("linear_envelope",Plinearenvelope); - - PA_dt=xml->getpar127("A_dt",PA_dt); - PD_dt=xml->getpar127("D_dt",PD_dt); - PR_dt=xml->getpar127("R_dt",PR_dt); - PA_val=xml->getpar127("A_val",PA_val); - PD_val=xml->getpar127("D_val",PD_val); - PS_val=xml->getpar127("S_val",PS_val); - PR_val=xml->getpar127("R_val",PR_val); - - for (int i=0;i<Penvpoints;i++) { - if (xml->enterbranch("POINT",i)==0) continue; - if (i!=0) Penvdt[i]=xml->getpar127("dt",Penvdt[i]); - Penvval[i]=xml->getpar127("val",Penvval[i]); + Pfreemode = xml->getparbool("free_mode", Pfreemode); + Penvpoints = xml->getpar127("env_points", Penvpoints); + Penvsustain = xml->getpar127("env_sustain", Penvsustain); + Penvstretch = xml->getpar127("env_stretch", Penvstretch); + Pforcedrelease = xml->getparbool("forced_release", Pforcedrelease); + Plinearenvelope = xml->getparbool("linear_envelope", Plinearenvelope); + + PA_dt = xml->getpar127("A_dt", PA_dt); + PD_dt = xml->getpar127("D_dt", PD_dt); + PR_dt = xml->getpar127("R_dt", PR_dt); + PA_val = xml->getpar127("A_val", PA_val); + PD_val = xml->getpar127("D_val", PD_val); + PS_val = xml->getpar127("S_val", PS_val); + PR_val = xml->getpar127("R_val", PR_val); + + for(int i = 0; i < Penvpoints; i++) { + if(xml->enterbranch("POINT", i) == 0) + continue; + if(i != 0) + Penvdt[i] = xml->getpar127("dt", Penvdt[i]); + Penvval[i] = xml->getpar127("val", Penvval[i]); xml->exitbranch(); - }; + } - if (!Pfreemode) converttofree(); -}; + if(!Pfreemode) + converttofree(); +} void EnvelopeParams::defaults() { - Penvstretch=Denvstretch; - Pforcedrelease=Dforcedrelease; - Plinearenvelope=Dlinearenvelope; - PA_dt=DA_dt; - PD_dt=DD_dt; - PR_dt=DR_dt; - PA_val=DA_val; - PD_val=DD_val; - PS_val=DS_val; - PR_val=DR_val; - Pfreemode=0; + Penvstretch = Denvstretch; + Pforcedrelease = Dforcedrelease; + Plinearenvelope = Dlinearenvelope; + PA_dt = DA_dt; + PD_dt = DD_dt; + PR_dt = DR_dt; + PA_val = DA_val; + PD_val = DD_val; + PS_val = DS_val; + PR_val = DR_val; + Pfreemode = 0; converttofree(); -}; +} void EnvelopeParams::store2defaults() { - Denvstretch=Penvstretch; - Dforcedrelease=Pforcedrelease; - Dlinearenvelope=Plinearenvelope; - DA_dt=PA_dt; - DD_dt=PD_dt; - DR_dt=PR_dt; - DA_val=PA_val; - DD_val=PD_val; - DS_val=PS_val; - DR_val=PR_val; -}; + Denvstretch = Penvstretch; + Dforcedrelease = Pforcedrelease; + Dlinearenvelope = Plinearenvelope; + DA_dt = PA_dt; + DD_dt = PD_dt; + DR_dt = PR_dt; + DA_val = PA_val; + DD_val = PD_val; + DS_val = PS_val; + DR_val = PR_val; +} diff --git a/src/Params/EnvelopeParams.h b/src/Params/EnvelopeParams.h @@ -32,54 +32,58 @@ class EnvelopeParams:public Presets { -public: - EnvelopeParams(unsigned char Penvstretch_,unsigned char Pforcedrelease_); - ~EnvelopeParams(); - void ADSRinit(char A_dt,char D_dt,char S_val,char R_dt); - void ADSRinit_dB(char A_dt,char D_dt,char S_val,char R_dt); - void ASRinit(char A_val,char A_dt,char R_val,char R_dt); - void ADSRinit_filter(char A_val,char A_dt,char D_val,char D_dt,char R_dt,char R_val); - void ASRinit_bw(char A_val,char A_dt,char R_val,char R_dt); - void converttofree(); - - void add2XML(XMLwrapper *xml); - void defaults(); - void getfromXML(XMLwrapper *xml); - - REALTYPE getdt(char i); - - /* MIDI Parameters */ - unsigned char Pfreemode;//1 daca este in modul free sau 0 daca este in mod ADSR,ASR,... - unsigned char Penvpoints; - unsigned char Penvsustain;//127 pentru dezactivat - unsigned char Penvdt[MAX_ENVELOPE_POINTS]; - unsigned char Penvval[MAX_ENVELOPE_POINTS]; - unsigned char Penvstretch;//64=normal stretch (piano-like), 0=no stretch - unsigned char Pforcedrelease;//0 - OFF, 1 - ON - unsigned char Plinearenvelope;//if the amplitude envelope is linear - - unsigned char PA_dt,PD_dt,PR_dt, - PA_val,PD_val,PS_val,PR_val; - - - - int Envmode;// 1 for ADSR parameters (linear amplitude) - // 2 for ADSR_dB parameters (dB amplitude) - // 3 for ASR parameters (frequency LFO) - // 4 for ADSR_filter parameters (filter parameters) - // 5 for ASR_bw parameters (bandwidth parameters) - -private: - void store2defaults(); - - /* Default parameters */ - unsigned char Denvstretch; - unsigned char Dforcedrelease; - unsigned char Dlinearenvelope; - unsigned char DA_dt,DD_dt,DR_dt, - DA_val,DD_val,DS_val,DR_val; - - + public: + EnvelopeParams(unsigned char Penvstretch_, + unsigned char Pforcedrelease_); + ~EnvelopeParams(); + void ADSRinit(char A_dt, char D_dt, char S_val, char R_dt); + void ADSRinit_dB(char A_dt, char D_dt, char S_val, char R_dt); + void ASRinit(char A_val, char A_dt, char R_val, char R_dt); + void ADSRinit_filter(char A_val, + char A_dt, + char D_val, + char D_dt, + char R_dt, + char R_val); + void ASRinit_bw(char A_val, char A_dt, char R_val, char R_dt); + void converttofree(); + + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); + + REALTYPE getdt(char i); + + /* MIDI Parameters */ + unsigned char Pfreemode; //1 daca este in modul free sau 0 daca este in mod ADSR,ASR,... + unsigned char Penvpoints; + unsigned char Penvsustain; //127 pentru dezactivat + unsigned char Penvdt[MAX_ENVELOPE_POINTS]; + unsigned char Penvval[MAX_ENVELOPE_POINTS]; + unsigned char Penvstretch; //64=normal stretch (piano-like), 0=no stretch + unsigned char Pforcedrelease; //0 - OFF, 1 - ON + unsigned char Plinearenvelope; //if the amplitude envelope is linear + + unsigned char PA_dt, PD_dt, PR_dt, + PA_val, PD_val, PS_val, PR_val; + + + + int Envmode; // 1 for ADSR parameters (linear amplitude) + // 2 for ADSR_dB parameters (dB amplitude) + // 3 for ASR parameters (frequency LFO) + // 4 for ADSR_filter parameters (filter parameters) + // 5 for ASR_bw parameters (bandwidth parameters) + + private: + void store2defaults(); + + /* Default parameters */ + unsigned char Denvstretch; + unsigned char Dforcedrelease; + unsigned char Dlinearenvelope; + unsigned char DA_dt, DD_dt, DR_dt, + DA_val, DD_val, DS_val, DR_val; }; #endif diff --git a/src/Params/FilterParams.cpp b/src/Params/FilterParams.cpp @@ -25,58 +25,60 @@ #include <stdlib.h> #include "FilterParams.h" -FilterParams::FilterParams(unsigned char Ptype_,unsigned char Pfreq_,unsigned char Pq_):Presets() +FilterParams::FilterParams(unsigned char Ptype_, + unsigned char Pfreq_, + unsigned char Pq_):Presets() { setpresettype("Pfilter"); - Dtype=Ptype_; - Dfreq=Pfreq_; - Dq=Pq_; + Dtype = Ptype_; + Dfreq = Pfreq_; + Dq = Pq_; - changed=false; + changed = false; defaults(); -}; +} FilterParams::~FilterParams() -{ -}; +{} void FilterParams::defaults() { - Ptype=Dtype; - Pfreq=Dfreq; - Pq=Dq; - - Pstages=0; - Pfreqtrack=64; - Pgain=64; - Pcategory=0; - - Pnumformants=3; - Pformantslowness=64; - for (int j=0;j<FF_MAX_VOWELS;j++) { + Ptype = Dtype; + Pfreq = Dfreq; + Pq = Dq; + + Pstages = 0; + Pfreqtrack = 64; + Pgain = 64; + Pcategory = 0; + + Pnumformants = 3; + Pformantslowness = 64; + for(int j = 0; j < FF_MAX_VOWELS; j++) defaults(j); - }; + ; - Psequencesize=3; - for (int i=0;i<FF_MAX_SEQUENCE;i++) Psequence[i].nvowel=i%FF_MAX_VOWELS; + Psequencesize = 3; + for(int i = 0; i < FF_MAX_SEQUENCE; i++) + Psequence[i].nvowel = i % FF_MAX_VOWELS; - Psequencestretch=40; - Psequencereversed=0; - Pcenterfreq=64;//1 kHz - Poctavesfreq=64; - Pvowelclearness=64; -}; + Psequencestretch = 40; + Psequencereversed = 0; + Pcenterfreq = 64; //1 kHz + Poctavesfreq = 64; + Pvowelclearness = 64; +} void FilterParams::defaults(int n) { - int j=n; - for (int i=0;i<FF_MAX_FORMANTS;i++) { - Pvowels[j].formants[i].freq=(int)(RND*127.0);//some random freqs - Pvowels[j].formants[i].q=64; - Pvowels[j].formants[i].amp=127; - }; -}; + int j = n; + for(int i = 0; i < FF_MAX_FORMANTS; i++) { + Pvowels[j].formants[i].freq = (int)(RND * 127.0); //some random freqs + Pvowels[j].formants[i].q = 64; + Pvowels[j].formants[i].amp = 127; + } +} /* @@ -87,36 +89,38 @@ void FilterParams::getfromFilterParams(FilterParams *pars) { defaults(); - if (pars==NULL) return; + if(pars == NULL) + return; - Ptype=pars->Ptype; - Pfreq=pars->Pfreq; - Pq=pars->Pq; + Ptype = pars->Ptype; + Pfreq = pars->Pfreq; + Pq = pars->Pq; - Pstages=pars->Pstages; - Pfreqtrack=pars->Pfreqtrack; - Pgain=pars->Pgain; - Pcategory=pars->Pcategory; + Pstages = pars->Pstages; + Pfreqtrack = pars->Pfreqtrack; + Pgain = pars->Pgain; + Pcategory = pars->Pcategory; - Pnumformants=pars->Pnumformants; - Pformantslowness=pars->Pformantslowness; - for (int j=0;j<FF_MAX_VOWELS;j++) { - for (int i=0;i<FF_MAX_FORMANTS;i++) { - Pvowels[j].formants[i].freq=pars->Pvowels[j].formants[i].freq; - Pvowels[j].formants[i].q=pars->Pvowels[j].formants[i].q; - Pvowels[j].formants[i].amp=pars->Pvowels[j].formants[i].amp; - }; - }; + Pnumformants = pars->Pnumformants; + Pformantslowness = pars->Pformantslowness; + for(int j = 0; j < FF_MAX_VOWELS; j++) { + for(int i = 0; i < FF_MAX_FORMANTS; i++) { + Pvowels[j].formants[i].freq = pars->Pvowels[j].formants[i].freq; + Pvowels[j].formants[i].q = pars->Pvowels[j].formants[i].q; + Pvowels[j].formants[i].amp = pars->Pvowels[j].formants[i].amp; + } + } - Psequencesize=pars->Psequencesize; - for (int i=0;i<FF_MAX_SEQUENCE;i++) Psequence[i].nvowel=pars->Psequence[i].nvowel; + Psequencesize = pars->Psequencesize; + for(int i = 0; i < FF_MAX_SEQUENCE; i++) + Psequence[i].nvowel = pars->Psequence[i].nvowel; - Psequencestretch=pars->Psequencestretch; - Psequencereversed=pars->Psequencereversed; - Pcenterfreq=pars->Pcenterfreq; - Poctavesfreq=pars->Poctavesfreq; - Pvowelclearness=pars->Pvowelclearness; -}; + Psequencestretch = pars->Psequencestretch; + Psequencereversed = pars->Psequencereversed; + Pcenterfreq = pars->Pcenterfreq; + Poctavesfreq = pars->Poctavesfreq; + Pvowelclearness = pars->Pvowelclearness; +} /* @@ -124,243 +128,264 @@ void FilterParams::getfromFilterParams(FilterParams *pars) */ REALTYPE FilterParams::getfreq() { - return((Pfreq/64.0-1.0)*5.0); -}; + return (Pfreq / 64.0 - 1.0) * 5.0; +} REALTYPE FilterParams::getq() { - return(exp(pow((REALTYPE) Pq/127.0,2)*log(1000.0))-0.9); -}; + return exp(pow((REALTYPE) Pq / 127.0, 2) * log(1000.0)) - 0.9; +} REALTYPE FilterParams::getfreqtracking(REALTYPE notefreq) { - return(log(notefreq/440.0)*(Pfreqtrack-64.0)/(64.0*LOG_2)); -}; + return log(notefreq / 440.0) * (Pfreqtrack - 64.0) / (64.0 * LOG_2); +} REALTYPE FilterParams::getgain() { - return((Pgain/64.0-1.0)*30.0);//-30..30dB -}; + return (Pgain / 64.0 - 1.0) * 30.0; //-30..30dB +} /* * Get the center frequency of the formant's graph */ REALTYPE FilterParams::getcenterfreq() { - return(10000.0*pow(10,-(1.0-Pcenterfreq/127.0)*2.0)); -}; + return 10000.0 * pow(10, -(1.0 - Pcenterfreq / 127.0) * 2.0); +} /* * Get the number of octave that the formant functions applies to */ REALTYPE FilterParams::getoctavesfreq() { - return(0.25+10.0*Poctavesfreq/127.0); -}; + return 0.25 + 10.0 * Poctavesfreq / 127.0; +} /* * Get the frequency from x, where x is [0..1] */ REALTYPE FilterParams::getfreqx(REALTYPE x) { - if (x>1.0) x=1.0; - REALTYPE octf=pow(2.0,getoctavesfreq()); - return(getcenterfreq()/sqrt(octf)*pow(octf,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 FilterParams::getfreqpos(REALTYPE freq) { - return((log(freq)-log(getfreqx(0.0)))/log(2.0)/getoctavesfreq()); -}; + return (log(freq) - log(getfreqx(0.0))) / log(2.0) / getoctavesfreq(); +} /* * Get the freq. response of the formant filter */ -void FilterParams::formantfilterH(int nvowel,int nfreqs,REALTYPE *freqs) +void FilterParams::formantfilterH(int nvowel, int nfreqs, REALTYPE *freqs) { - REALTYPE c[3],d[3]; - REALTYPE filter_freq,filter_q,filter_amp; - REALTYPE omega,sn,cs,alpha; + REALTYPE c[3], d[3]; + REALTYPE filter_freq, filter_q, filter_amp; + REALTYPE omega, sn, cs, alpha; - for (int i=0;i<nfreqs;i++) freqs[i]=0.0; + for(int i = 0; i < nfreqs; i++) + freqs[i] = 0.0; //for each formant... - for (int nformant=0;nformant<Pnumformants;nformant++) { + for(int nformant = 0; nformant < Pnumformants; nformant++) { //compute formant parameters(frequency,amplitude,etc.) - filter_freq=getformantfreq(Pvowels[nvowel].formants[nformant].freq); - filter_q=getformantq(Pvowels[nvowel].formants[nformant].q)*getq(); - if (Pstages>0) filter_q=(filter_q>1.0 ? pow(filter_q,1.0/(Pstages+1)) : filter_q); - - filter_amp=getformantamp(Pvowels[nvowel].formants[nformant].amp); - - - if (filter_freq<=(SAMPLE_RATE/2-100.0)) { - omega=2*PI*filter_freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - alpha=sn/(2*filter_q); - REALTYPE tmp=1+alpha; - c[0]=alpha/tmp*sqrt(filter_q+1); - c[1]=0; - c[2]=-alpha/tmp*sqrt(filter_q+1); - d[1]=-2*cs/tmp*(-1); - d[2]=(1-alpha)/tmp*(-1); - } else continue; - - - for (int i=0;i<nfreqs;i++) { - REALTYPE freq=getfreqx(i/(REALTYPE) nfreqs); - if (freq>SAMPLE_RATE/2) { - for (int tmp=i;tmp<nfreqs;tmp++) freqs[tmp]=0.0; + filter_freq = getformantfreq(Pvowels[nvowel].formants[nformant].freq); + filter_q = getformantq(Pvowels[nvowel].formants[nformant].q) * getq(); + if(Pstages > 0) + filter_q = + (filter_q > 1.0 ? pow(filter_q, 1.0 / (Pstages + 1)) : filter_q); + + filter_amp = getformantamp(Pvowels[nvowel].formants[nformant].amp); + + + if(filter_freq <= (SAMPLE_RATE / 2 - 100.0)) { + omega = 2 * PI * filter_freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + alpha = sn / (2 * filter_q); + REALTYPE tmp = 1 + alpha; + c[0] = alpha / tmp *sqrt(filter_q + 1); + c[1] = 0; + c[2] = -alpha / tmp *sqrt(filter_q + 1); + d[1] = -2 * cs / tmp * (-1); + d[2] = (1 - alpha) / tmp * (-1); + } + else + continue; + + + for(int i = 0; i < nfreqs; i++) { + REALTYPE freq = getfreqx(i / (REALTYPE) nfreqs); + if(freq > SAMPLE_RATE / 2) { + for(int tmp = i; tmp < nfreqs; tmp++) + freqs[tmp] = 0.0; break; - }; - REALTYPE fr=freq/SAMPLE_RATE*PI*2.0; - REALTYPE x=c[0],y=0.0; - for (int n=1;n<3;n++) { - x+=cos(n*fr)*c[n]; - y-=sin(n*fr)*c[n]; - }; - REALTYPE h=x*x+y*y; - x=1.0; - y=0.0; - for (int n=1;n<3;n++) { - x-=cos(n*fr)*d[n]; - y+=sin(n*fr)*d[n]; - }; - h=h/(x*x+y*y); - - freqs[i]+=pow(h,(Pstages+1.0)/2.0)*filter_amp; - }; - }; - for (int i=0;i<nfreqs;i++) { - if (freqs[i]>0.000000001) freqs[i]=rap2dB(freqs[i])+getgain(); - else freqs[i]=-90.0; - }; - -}; + } + REALTYPE fr = freq / SAMPLE_RATE * PI * 2.0; + REALTYPE x = c[0], y = 0.0; + for(int n = 1; n < 3; n++) { + x += cos(n * fr) * c[n]; + y -= sin(n * fr) * c[n]; + } + REALTYPE h = x * x + y * y; + x = 1.0; + y = 0.0; + for(int n = 1; n < 3; n++) { + x -= cos(n * fr) * d[n]; + y += sin(n * fr) * d[n]; + } + h = h / (x * x + y * y); + + freqs[i] += pow(h, (Pstages + 1.0) / 2.0) * filter_amp; + } + } + for(int i = 0; i < nfreqs; i++) { + if(freqs[i] > 0.000000001) + freqs[i] = rap2dB(freqs[i]) + getgain(); + else + freqs[i] = -90.0; + } +} /* * Transforms a parameter to the real value */ REALTYPE FilterParams::getformantfreq(unsigned char freq) { - REALTYPE result=getfreqx(freq/127.0); - return(result); -}; + REALTYPE result = getfreqx(freq / 127.0); + return result; +} REALTYPE FilterParams::getformantamp(unsigned char amp) { - REALTYPE result=pow(0.1,(1.0-amp/127.0)*4.0); - return(result); -}; + REALTYPE result = pow(0.1, (1.0 - amp / 127.0) * 4.0); + return result; +} REALTYPE FilterParams::getformantq(unsigned char q) { //temp - REALTYPE result=pow(25.0,(q-32.0)/64.0); - return(result); -}; + REALTYPE result = pow(25.0, (q - 32.0) / 64.0); + return result; +} -void FilterParams::add2XMLsection(XMLwrapper *xml,int n) +void FilterParams::add2XMLsection(XMLwrapper *xml, int n) { - int nvowel=n; - for (int nformant=0;nformant<FF_MAX_FORMANTS;nformant++) { - xml->beginbranch("FORMANT",nformant); - xml->addpar("freq",Pvowels[nvowel].formants[nformant].freq); - xml->addpar("amp",Pvowels[nvowel].formants[nformant].amp); - xml->addpar("q",Pvowels[nvowel].formants[nformant].q); + int nvowel = n; + for(int nformant = 0; nformant < FF_MAX_FORMANTS; nformant++) { + xml->beginbranch("FORMANT", nformant); + xml->addpar("freq", Pvowels[nvowel].formants[nformant].freq); + xml->addpar("amp", Pvowels[nvowel].formants[nformant].amp); + xml->addpar("q", Pvowels[nvowel].formants[nformant].q); xml->endbranch(); - }; -}; + } +} void FilterParams::add2XML(XMLwrapper *xml) { //filter parameters - xml->addpar("category",Pcategory); - xml->addpar("type",Ptype); - xml->addpar("freq",Pfreq); - xml->addpar("q",Pq); - xml->addpar("stages",Pstages); - xml->addpar("freq_track",Pfreqtrack); - xml->addpar("gain",Pgain); + xml->addpar("category", Pcategory); + xml->addpar("type", Ptype); + xml->addpar("freq", Pfreq); + xml->addpar("q", Pq); + xml->addpar("stages", Pstages); + xml->addpar("freq_track", Pfreqtrack); + xml->addpar("gain", Pgain); //formant filter parameters - if ((Pcategory==1)||(!xml->minimal)) { + if((Pcategory == 1) || (!xml->minimal)) { xml->beginbranch("FORMANT_FILTER"); - xml->addpar("num_formants",Pnumformants); - xml->addpar("formant_slowness",Pformantslowness); - xml->addpar("vowel_clearness",Pvowelclearness); - xml->addpar("center_freq",Pcenterfreq); - xml->addpar("octaves_freq",Poctavesfreq); - for (int nvowel=0;nvowel<FF_MAX_VOWELS;nvowel++) { - xml->beginbranch("VOWEL",nvowel); - add2XMLsection(xml,nvowel); + xml->addpar("num_formants", Pnumformants); + xml->addpar("formant_slowness", Pformantslowness); + xml->addpar("vowel_clearness", Pvowelclearness); + xml->addpar("center_freq", Pcenterfreq); + xml->addpar("octaves_freq", Poctavesfreq); + for(int nvowel = 0; nvowel < FF_MAX_VOWELS; nvowel++) { + xml->beginbranch("VOWEL", nvowel); + add2XMLsection(xml, nvowel); xml->endbranch(); - }; - xml->addpar("sequence_size",Psequencesize); - xml->addpar("sequence_stretch",Psequencestretch); - xml->addparbool("sequence_reversed",Psequencereversed); - for (int nseq=0;nseq<FF_MAX_SEQUENCE;nseq++) { - xml->beginbranch("SEQUENCE_POS",nseq); - xml->addpar("vowel_id",Psequence[nseq].nvowel); + } + xml->addpar("sequence_size", Psequencesize); + xml->addpar("sequence_stretch", Psequencestretch); + xml->addparbool("sequence_reversed", Psequencereversed); + for(int nseq = 0; nseq < FF_MAX_SEQUENCE; nseq++) { + xml->beginbranch("SEQUENCE_POS", nseq); + xml->addpar("vowel_id", Psequence[nseq].nvowel); xml->endbranch(); - }; + } xml->endbranch(); - }; -}; + } +} -void FilterParams::getfromXMLsection(XMLwrapper *xml,int n) +void FilterParams::getfromXMLsection(XMLwrapper *xml, int n) { - int nvowel=n; - for (int nformant=0;nformant<FF_MAX_FORMANTS;nformant++) { - if (xml->enterbranch("FORMANT",nformant)==0) continue; - Pvowels[nvowel].formants[nformant].freq=xml->getpar127("freq",Pvowels[nvowel].formants[nformant].freq); - Pvowels[nvowel].formants[nformant].amp=xml->getpar127("amp",Pvowels[nvowel].formants[nformant].amp); - Pvowels[nvowel].formants[nformant].q=xml->getpar127("q",Pvowels[nvowel].formants[nformant].q); + int nvowel = n; + for(int nformant = 0; nformant < FF_MAX_FORMANTS; nformant++) { + if(xml->enterbranch("FORMANT", nformant) == 0) + continue; + Pvowels[nvowel].formants[nformant].freq = xml->getpar127( + "freq", + Pvowels[nvowel + ].formants[nformant].freq); + Pvowels[nvowel].formants[nformant].amp = xml->getpar127( + "amp", + Pvowels[nvowel + ].formants[nformant].amp); + Pvowels[nvowel].formants[nformant].q = + xml->getpar127("q", Pvowels[nvowel].formants[nformant].q); xml->exitbranch(); - }; -}; + } +} void FilterParams::getfromXML(XMLwrapper *xml) { //filter parameters - Pcategory=xml->getpar127("category",Pcategory); - Ptype=xml->getpar127("type",Ptype); - Pfreq=xml->getpar127("freq",Pfreq); - Pq=xml->getpar127("q",Pq); - Pstages=xml->getpar127("stages",Pstages); - Pfreqtrack=xml->getpar127("freq_track",Pfreqtrack); - Pgain=xml->getpar127("gain",Pgain); + Pcategory = xml->getpar127("category", Pcategory); + Ptype = xml->getpar127("type", Ptype); + Pfreq = xml->getpar127("freq", Pfreq); + Pq = xml->getpar127("q", Pq); + Pstages = xml->getpar127("stages", Pstages); + Pfreqtrack = xml->getpar127("freq_track", Pfreqtrack); + Pgain = xml->getpar127("gain", Pgain); //formant filter parameters - if (xml->enterbranch("FORMANT_FILTER")) { - Pnumformants=xml->getpar127("num_formants",Pnumformants); - Pformantslowness=xml->getpar127("formant_slowness",Pformantslowness); - Pvowelclearness=xml->getpar127("vowel_clearness",Pvowelclearness); - Pcenterfreq=xml->getpar127("center_freq",Pcenterfreq); - Poctavesfreq=xml->getpar127("octaves_freq",Poctavesfreq); - - for (int nvowel=0;nvowel<FF_MAX_VOWELS;nvowel++) { - if (xml->enterbranch("VOWEL",nvowel)==0) continue; - getfromXMLsection(xml,nvowel); + if(xml->enterbranch("FORMANT_FILTER")) { + Pnumformants = xml->getpar127("num_formants", Pnumformants); + Pformantslowness = xml->getpar127("formant_slowness", Pformantslowness); + Pvowelclearness = xml->getpar127("vowel_clearness", Pvowelclearness); + Pcenterfreq = xml->getpar127("center_freq", Pcenterfreq); + Poctavesfreq = xml->getpar127("octaves_freq", Poctavesfreq); + + for(int nvowel = 0; nvowel < FF_MAX_VOWELS; nvowel++) { + if(xml->enterbranch("VOWEL", nvowel) == 0) + continue; + getfromXMLsection(xml, nvowel); xml->exitbranch(); - }; - Psequencesize=xml->getpar127("sequence_size",Psequencesize); - Psequencestretch=xml->getpar127("sequence_stretch",Psequencestretch); - Psequencereversed=xml->getparbool("sequence_reversed",Psequencereversed); - for (int nseq=0;nseq<FF_MAX_SEQUENCE;nseq++) { - if (xml->enterbranch("SEQUENCE_POS",nseq)==0) continue; - Psequence[nseq].nvowel=xml->getpar("vowel_id",Psequence[nseq].nvowel,0,FF_MAX_VOWELS-1); + } + Psequencesize = xml->getpar127("sequence_size", Psequencesize); + Psequencestretch = xml->getpar127("sequence_stretch", Psequencestretch); + Psequencereversed = xml->getparbool("sequence_reversed", + Psequencereversed); + for(int nseq = 0; nseq < FF_MAX_SEQUENCE; nseq++) { + if(xml->enterbranch("SEQUENCE_POS", nseq) == 0) + continue; + Psequence[nseq].nvowel = xml->getpar("vowel_id", + Psequence[nseq].nvowel, + 0, + FF_MAX_VOWELS - 1); xml->exitbranch(); - }; + } xml->exitbranch(); - }; - -}; + } +} diff --git a/src/Params/FilterParams.h b/src/Params/FilterParams.h @@ -29,72 +29,74 @@ class FilterParams:public Presets { -public: - FilterParams(unsigned char Ptype_,unsigned char Pfreq,unsigned char Pq_); - ~FilterParams(); - - void add2XML(XMLwrapper *xml); - void add2XMLsection(XMLwrapper *xml,int n); - void defaults(); - void getfromXML(XMLwrapper *xml); - void getfromXMLsection(XMLwrapper *xml,int n); - - - void getfromFilterParams(FilterParams *pars); - - REALTYPE getfreq(); - REALTYPE getq(); - REALTYPE getfreqtracking(REALTYPE notefreq); - REALTYPE getgain(); - - unsigned char Pcategory;//Filter category (Analog/Formant/StVar) - unsigned char Ptype;// Filter type (for analog lpf,hpf,bpf..) - unsigned char Pfreq;// Frequency (64-central frequency) - unsigned char Pq; // Q parameters (resonance or bandwidth) - unsigned char Pstages; //filter stages+1 - unsigned char Pfreqtrack;//how the filter frequency is changing according the note frequency - unsigned char Pgain;//filter's output gain - - //Formant filter parameters - unsigned char Pnumformants;//how many formants are used - unsigned char Pformantslowness;//how slow varies the formants - unsigned char Pvowelclearness;//how vowels are kept clean (how much try to avoid "mixed" vowels) - unsigned char Pcenterfreq,Poctavesfreq;//the center frequency of the res. func., and the number of octaves - - struct { + public: + FilterParams(unsigned char Ptype_, + unsigned char Pfreq, + unsigned char Pq_); + ~FilterParams(); + + void add2XML(XMLwrapper *xml); + void add2XMLsection(XMLwrapper *xml, int n); + void defaults(); + void getfromXML(XMLwrapper *xml); + void getfromXMLsection(XMLwrapper *xml, int n); + + + void getfromFilterParams(FilterParams *pars); + + REALTYPE getfreq(); + REALTYPE getq(); + REALTYPE getfreqtracking(REALTYPE notefreq); + REALTYPE getgain(); + + unsigned char Pcategory; //Filter category (Analog/Formant/StVar) + unsigned char Ptype; // Filter type (for analog lpf,hpf,bpf..) + unsigned char Pfreq; // Frequency (64-central frequency) + unsigned char Pq; // Q parameters (resonance or bandwidth) + unsigned char Pstages; //filter stages+1 + unsigned char Pfreqtrack; //how the filter frequency is changing according the note frequency + unsigned char Pgain; //filter's output gain + + //Formant filter parameters + unsigned char Pnumformants; //how many formants are used + unsigned char Pformantslowness; //how slow varies the formants + unsigned char Pvowelclearness; //how vowels are kept clean (how much try to avoid "mixed" vowels) + unsigned char Pcenterfreq, Poctavesfreq; //the center frequency of the res. func., and the number of octaves + struct { - unsigned char freq,amp,q;//frequency,amplitude,Q - }formants[FF_MAX_FORMANTS]; - }Pvowels[FF_MAX_VOWELS]; + struct { + unsigned char freq, amp, q; //frequency,amplitude,Q + } formants[FF_MAX_FORMANTS]; + } Pvowels[FF_MAX_VOWELS]; - unsigned char Psequencesize;//how many vowels are in the sequence - unsigned char Psequencestretch;//how the sequence is stretched (how the input from filter envelopes/LFOs/etc. is "stretched") - unsigned char Psequencereversed;//if the input from filter envelopes/LFOs/etc. is reversed(negated) - struct { - unsigned char nvowel;//the vowel from the position - } Psequence[FF_MAX_SEQUENCE]; + unsigned char Psequencesize; //how many vowels are in the sequence + unsigned char Psequencestretch; //how the sequence is stretched (how the input from filter envelopes/LFOs/etc. is "stretched") + unsigned char Psequencereversed; //if the input from filter envelopes/LFOs/etc. is reversed(negated) + struct { + unsigned char nvowel; //the vowel from the position + } Psequence[FF_MAX_SEQUENCE]; - REALTYPE getcenterfreq(); - REALTYPE getoctavesfreq(); - REALTYPE getfreqpos(REALTYPE freq); - REALTYPE getfreqx(REALTYPE x); + REALTYPE getcenterfreq(); + REALTYPE getoctavesfreq(); + REALTYPE getfreqpos(REALTYPE freq); + REALTYPE getfreqx(REALTYPE x); - void formantfilterH(int nvowel,int nfreqs,REALTYPE *freqs);//used by UI + void formantfilterH(int nvowel, int nfreqs, REALTYPE *freqs); //used by UI - REALTYPE getformantfreq(unsigned char freq); - REALTYPE getformantamp(unsigned char amp); - REALTYPE getformantq(unsigned char q); + REALTYPE getformantfreq(unsigned char freq); + REALTYPE getformantamp(unsigned char amp); + REALTYPE getformantq(unsigned char q); - bool changed; + bool changed; -private: - void defaults(int n); + private: + void defaults(int n); - //stored default parameters - unsigned char Dtype; - unsigned char Dfreq; - unsigned char Dq; + //stored default parameters + unsigned char Dtype; + unsigned char Dfreq; + unsigned char Dq; }; #endif diff --git a/src/Params/LFOParams.cpp b/src/Params/LFOParams.cpp @@ -27,9 +27,16 @@ int LFOParams::time; -LFOParams::LFOParams(char Pfreq_,char Pintensity_,char Pstartphase_, char PLFOtype_,char Prandomness_, char Pdelay_,char Pcontinous_,char fel_):Presets() +LFOParams::LFOParams(char Pfreq_, + char Pintensity_, + char Pstartphase_, + char PLFOtype_, + char Prandomness_, + char Pdelay_, + char Pcontinous_, + char fel_):Presets() { - switch (fel_) { + switch(fel_) { case 0: setpresettype("Plfofrequency"); break; @@ -39,61 +46,60 @@ LFOParams::LFOParams(char Pfreq_,char Pintensity_,char Pstartphase_, char PLFOty case 2: setpresettype("Plfofilter"); break; - }; - Dfreq=Pfreq_; - Dintensity=Pintensity_; - Dstartphase=Pstartphase_; - DLFOtype=PLFOtype_; - Drandomness=Prandomness_; - Ddelay=Pdelay_; - Dcontinous=Pcontinous_; - fel=fel_; - time=0; + } + Dfreq = Pfreq_; + Dintensity = Pintensity_; + Dstartphase = Pstartphase_; + DLFOtype = PLFOtype_; + Drandomness = Prandomness_; + Ddelay = Pdelay_; + Dcontinous = Pcontinous_; + fel = fel_; + time = 0; defaults(); -}; +} LFOParams::~LFOParams() -{ -}; +{} void LFOParams::defaults() { - Pfreq=Dfreq/127.0; - Pintensity=Dintensity; - Pstartphase=Dstartphase; - PLFOtype=DLFOtype; - Prandomness=Drandomness; - Pdelay=Ddelay; - Pcontinous=Dcontinous; - Pfreqrand=0; - Pstretch=64; -}; + Pfreq = Dfreq / 127.0; + Pintensity = Dintensity; + Pstartphase = Dstartphase; + PLFOtype = DLFOtype; + Prandomness = Drandomness; + Pdelay = Ddelay; + Pcontinous = Dcontinous; + Pfreqrand = 0; + Pstretch = 64; +} void LFOParams::add2XML(XMLwrapper *xml) { - xml->addparreal("freq",Pfreq); - xml->addpar("intensity",Pintensity); - xml->addpar("start_phase",Pstartphase); - xml->addpar("lfo_type",PLFOtype); - xml->addpar("randomness_amplitude",Prandomness); - xml->addpar("randomness_frequency",Pfreqrand); - xml->addpar("delay",Pdelay); - xml->addpar("stretch",Pstretch); - xml->addparbool("continous",Pcontinous); -}; + xml->addparreal("freq", Pfreq); + xml->addpar("intensity", Pintensity); + xml->addpar("start_phase", Pstartphase); + xml->addpar("lfo_type", PLFOtype); + xml->addpar("randomness_amplitude", Prandomness); + xml->addpar("randomness_frequency", Pfreqrand); + xml->addpar("delay", Pdelay); + xml->addpar("stretch", Pstretch); + xml->addparbool("continous", Pcontinous); +} void LFOParams::getfromXML(XMLwrapper *xml) { - Pfreq=xml->getparreal("freq",Pfreq,0.0,1.0); - Pintensity=xml->getpar127("intensity",Pintensity); - Pstartphase=xml->getpar127("start_phase",Pstartphase); - PLFOtype=xml->getpar127("lfo_type",PLFOtype); - Prandomness=xml->getpar127("randomness_amplitude",Prandomness); - Pfreqrand=xml->getpar127("randomness_frequency",Pfreqrand); - Pdelay=xml->getpar127("delay",Pdelay); - Pstretch=xml->getpar127("stretch",Pstretch); - Pcontinous=xml->getparbool("continous",Pcontinous); -}; + Pfreq = xml->getparreal("freq", Pfreq, 0.0, 1.0); + Pintensity = xml->getpar127("intensity", Pintensity); + Pstartphase = xml->getpar127("start_phase", Pstartphase); + PLFOtype = xml->getpar127("lfo_type", PLFOtype); + Prandomness = xml->getpar127("randomness_amplitude", Prandomness); + Pfreqrand = xml->getpar127("randomness_frequency", Pfreqrand); + Pdelay = xml->getpar127("delay", Pdelay); + Pstretch = xml->getpar127("stretch", Pstretch); + Pcontinous = xml->getparbool("continous", Pcontinous); +} diff --git a/src/Params/LFOParams.h b/src/Params/LFOParams.h @@ -28,38 +28,45 @@ class LFOParams:public Presets { -public: - LFOParams(char Pfreq_,char Pintensity_,char Pstartphase_, char PLFOtype_,char Prandomness_, char Pdelay_,char Pcontinous,char fel_); - ~LFOParams(); + public: + LFOParams(char Pfreq_, + char Pintensity_, + char Pstartphase_, + char PLFOtype_, + char Prandomness_, + char Pdelay_, + char Pcontinous, + char fel_); + ~LFOParams(); - void add2XML(XMLwrapper *xml); - void defaults(); - /**Loads the LFO from the xml*/ - void getfromXML(XMLwrapper *xml); + void add2XML(XMLwrapper *xml); + void defaults(); + /**Loads the LFO from the xml*/ + void getfromXML(XMLwrapper *xml); - /* MIDI Parameters*/ - REALTYPE Pfreq; /**<frequency*/ - unsigned char Pintensity; /**<intensity*/ - unsigned char Pstartphase;/**<start phase (0=random)*/ - unsigned char PLFOtype; /**<LFO type (sin,triangle,square,ramp,...)*/ - unsigned char Prandomness;/**<randomness (0=off)*/ - unsigned char Pfreqrand; /**<frequency randomness (0=off)*/ - unsigned char Pdelay; /**<delay (0=off)*/ - unsigned char Pcontinous; /**<1 if LFO is continous*/ - unsigned char Pstretch; /**<how the LFO is "stretched" according the note frequency (64=no stretch)*/ - - int fel;//what kind is the LFO (0 - frequency, 1 - amplitude, 2 - filter) - static int time;//is used by Pcontinous parameter -private: - /* Default parameters */ - unsigned char Dfreq; - unsigned char Dintensity; - unsigned char Dstartphase; - unsigned char DLFOtype; - unsigned char Drandomness; - unsigned char Ddelay; - unsigned char Dcontinous; + /* MIDI Parameters*/ + REALTYPE Pfreq; /**<frequency*/ + unsigned char Pintensity; /**<intensity*/ + unsigned char Pstartphase; /**<start phase (0=random)*/ + unsigned char PLFOtype; /**<LFO type (sin,triangle,square,ramp,...)*/ + unsigned char Prandomness; /**<randomness (0=off)*/ + unsigned char Pfreqrand; /**<frequency randomness (0=off)*/ + unsigned char Pdelay; /**<delay (0=off)*/ + unsigned char Pcontinous; /**<1 if LFO is continous*/ + unsigned char Pstretch; /**<how the LFO is "stretched" according the note frequency (64=no stretch)*/ + int fel; //what kind is the LFO (0 - frequency, 1 - amplitude, 2 - filter) + static int time; //is used by Pcontinous parameter + private: + /* Default parameters */ + unsigned char Dfreq; + unsigned char Dintensity; + unsigned char Dstartphase; + unsigned char DLFOtype; + unsigned char Drandomness; + unsigned char Ddelay; + unsigned char Dcontinous; }; #endif + diff --git a/src/Params/PADnoteParameters.cpp b/src/Params/PADnoteParameters.cpp @@ -24,262 +24,281 @@ #include "../Output/WAVaudiooutput.h" using namespace std; -PADnoteParameters::PADnoteParameters(FFTwrapper *fft_,pthread_mutex_t *mutex_):Presets() +PADnoteParameters::PADnoteParameters(FFTwrapper *fft_, + pthread_mutex_t *mutex_):Presets() { setpresettype("Ppadsyth"); - fft=fft_; - mutex=mutex_; + fft = fft_; + mutex = mutex_; - resonance=new Resonance(); - oscilgen=new OscilGen(fft_,resonance); - oscilgen->ADvsPAD=true; + resonance = new Resonance(); + oscilgen = new OscilGen(fft_, resonance); + oscilgen->ADvsPAD = true; - FreqEnvelope=new EnvelopeParams(0,0); - FreqEnvelope->ASRinit(64,50,64,60); - FreqLfo=new LFOParams(70,0,64,0,0,0,0,0); + FreqEnvelope = new EnvelopeParams(0, 0); + FreqEnvelope->ASRinit(64, 50, 64, 60); + FreqLfo = new LFOParams(70, 0, 64, 0, 0, 0, 0, 0); - AmpEnvelope=new EnvelopeParams(64,1); - AmpEnvelope->ADSRinit_dB(0,40,127,25); - AmpLfo=new LFOParams(80,0,64,0,0,0,0,1); + AmpEnvelope = new EnvelopeParams(64, 1); + AmpEnvelope->ADSRinit_dB(0, 40, 127, 25); + AmpLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 1); - GlobalFilter=new FilterParams(2,94,40); - FilterEnvelope=new EnvelopeParams(0,1); - FilterEnvelope->ADSRinit_filter(64,40,64,70,60,64); - FilterLfo=new LFOParams(80,0,64,0,0,0,0,2); + GlobalFilter = new FilterParams(2, 94, 40); + FilterEnvelope = new EnvelopeParams(0, 1); + FilterEnvelope->ADSRinit_filter(64, 40, 64, 70, 60, 64); + FilterLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 2); - for (int i=0;i<PAD_MAX_SAMPLES;i++) sample[i].smp=NULL; - newsample.smp=NULL; + for(int i = 0; i < PAD_MAX_SAMPLES; i++) + sample[i].smp = NULL; + newsample.smp = NULL; defaults(); -}; +} PADnoteParameters::~PADnoteParameters() { deletesamples(); - delete(oscilgen); - delete(resonance); - - delete(FreqEnvelope); - delete(FreqLfo); - delete(AmpEnvelope); - delete(AmpLfo); - delete(GlobalFilter); - delete(FilterEnvelope); - delete(FilterLfo); - -}; + delete (oscilgen); + delete (resonance); + + delete (FreqEnvelope); + delete (FreqLfo); + delete (AmpEnvelope); + delete (AmpLfo); + delete (GlobalFilter); + delete (FilterEnvelope); + delete (FilterLfo); +} void PADnoteParameters::defaults() { - Pmode=0; - Php.base.type=0; - Php.base.par1=80; - Php.freqmult=0; - Php.modulator.par1=0; - Php.modulator.freq=30; - Php.width=127; - Php.amp.type=0; - Php.amp.mode=0; - Php.amp.par1=80; - Php.amp.par2=64; - Php.autoscale=true; - Php.onehalf=0; + Pmode = 0; + Php.base.type = 0; + Php.base.par1 = 80; + Php.freqmult = 0; + Php.modulator.par1 = 0; + Php.modulator.freq = 30; + Php.width = 127; + Php.amp.type = 0; + Php.amp.mode = 0; + Php.amp.par1 = 80; + Php.amp.par2 = 64; + Php.autoscale = true; + Php.onehalf = 0; setPbandwidth(500); - Pbwscale=0; + Pbwscale = 0; resonance->defaults(); oscilgen->defaults(); - Phrpos.type=0; - Phrpos.par1=64; - Phrpos.par2=64; - Phrpos.par3=0; + Phrpos.type = 0; + Phrpos.par1 = 64; + Phrpos.par2 = 64; + Phrpos.par3 = 0; - Pquality.samplesize=3; - Pquality.basenote=4; - Pquality.oct=3; - Pquality.smpoct=2; + Pquality.samplesize = 3; + Pquality.basenote = 4; + Pquality.oct = 3; + Pquality.smpoct = 2; - PStereo=1;//stereo + PStereo = 1; //stereo /* Frequency Global Parameters */ - Pfixedfreq=0; - PfixedfreqET=0; - PDetune=8192;//zero - PCoarseDetune=0; - PDetuneType=1; + Pfixedfreq = 0; + PfixedfreqET = 0; + PDetune = 8192; //zero + PCoarseDetune = 0; + PDetuneType = 1; FreqEnvelope->defaults(); FreqLfo->defaults(); /* Amplitude Global Parameters */ - PVolume=90; - PPanning=64;//center - PAmpVelocityScaleFunction=64; + PVolume = 90; + PPanning = 64; //center + PAmpVelocityScaleFunction = 64; AmpEnvelope->defaults(); AmpLfo->defaults(); - PPunchStrength=0; - PPunchTime=60; - PPunchStretch=64; - PPunchVelocitySensing=72; + PPunchStrength = 0; + PPunchTime = 60; + PPunchStretch = 64; + PPunchVelocitySensing = 72; /* Filter Global Parameters*/ - PFilterVelocityScale=64; - PFilterVelocityScaleFunction=64; + PFilterVelocityScale = 64; + PFilterVelocityScaleFunction = 64; GlobalFilter->defaults(); FilterEnvelope->defaults(); FilterLfo->defaults(); deletesamples(); -}; +} void PADnoteParameters::deletesample(int n) { - if ((n<0)||(n>=PAD_MAX_SAMPLES)) return; - if (sample[n].smp!=NULL) { - delete[]sample[n].smp; - sample[n].smp=NULL; - }; - sample[n].size=0; - sample[n].basefreq=440.0; -}; + if((n < 0) || (n >= PAD_MAX_SAMPLES)) + return; + if(sample[n].smp != NULL) { + delete[] sample[n].smp; + sample[n].smp = NULL; + } + sample[n].size = 0; + sample[n].basefreq = 440.0; +} void PADnoteParameters::deletesamples() { - for (int i=0;i<PAD_MAX_SAMPLES;i++) deletesample(i); -}; + for(int i = 0; i < PAD_MAX_SAMPLES; i++) + deletesample(i); +} /* * Get the harmonic profile (i.e. the frequency distributio of a single harmonic) */ -REALTYPE PADnoteParameters::getprofile(REALTYPE *smp,int size) +REALTYPE PADnoteParameters::getprofile(REALTYPE *smp, int size) { - for (int i=0;i<size;i++) smp[i]=0.0; - const int supersample=16; - REALTYPE basepar=pow(2.0,(1.0-Php.base.par1/127.0)*12.0); - REALTYPE freqmult=floor(pow(2.0,Php.freqmult/127.0*5.0)+0.000001); - - REALTYPE modfreq=floor(pow(2.0,Php.modulator.freq/127.0*5.0)+0.000001); - REALTYPE modpar1=pow(Php.modulator.par1/127.0,4.0)*5.0/sqrt(modfreq); - REALTYPE amppar1=pow(2.0,pow(Php.amp.par1/127.0,2.0)*10.0)-0.999; - REALTYPE amppar2=(1.0-Php.amp.par2/127.0)*0.998+0.001; - REALTYPE width=pow(150.0/(Php.width+22.0),2.0); - - for (int i=0;i<size*supersample;i++) { - bool makezero=false; - REALTYPE x=i*1.0/(size*(REALTYPE) supersample); - - REALTYPE origx=x; + for(int i = 0; i < size; i++) + smp[i] = 0.0; + const int supersample = 16; + REALTYPE basepar = pow(2.0, (1.0 - Php.base.par1 / 127.0) * 12.0); + REALTYPE freqmult = floor(pow(2.0, + Php.freqmult / 127.0 * 5.0) + 0.000001); + + REALTYPE modfreq = floor(pow(2.0, + Php.modulator.freq / 127.0 + * 5.0) + 0.000001); + REALTYPE modpar1 = pow(Php.modulator.par1 / 127.0, 4.0) * 5.0 / sqrt( + modfreq); + REALTYPE amppar1 = + pow(2.0, pow(Php.amp.par1 / 127.0, 2.0) * 10.0) - 0.999; + REALTYPE amppar2 = (1.0 - Php.amp.par2 / 127.0) * 0.998 + 0.001; + REALTYPE width = pow(150.0 / (Php.width + 22.0), 2.0); + + for(int i = 0; i < size * supersample; i++) { + bool makezero = false; + REALTYPE x = i * 1.0 / (size * (REALTYPE) supersample); + + REALTYPE origx = x; //do the sizing (width) - x=(x-0.5)*width+0.5; - if (x<0.0) { - x=0.0; - makezero=true; - } else { - if (x>1.0) { - x=1.0; - makezero=true; - }; - }; + x = (x - 0.5) * width + 0.5; + if(x < 0.0) { + x = 0.0; + makezero = true; + } + else { + if(x > 1.0) { + x = 1.0; + makezero = true; + } + } //compute the full profile or one half - switch (Php.onehalf) { + switch(Php.onehalf) { case 1: - x=x*0.5+0.5; + x = x * 0.5 + 0.5; break; case 2: - x=x*0.5; + x = x * 0.5; break; - }; + } - REALTYPE x_before_freq_mult=x; + REALTYPE x_before_freq_mult = x; //do the frequency multiplier - x*=freqmult; + x *= freqmult; //do the modulation of the profile - x+=sin(x_before_freq_mult*3.1415926*modfreq)*modpar1; - x=fmod(x+1000.0,1.0)*2.0-1.0; + x += sin(x_before_freq_mult * 3.1415926 * modfreq) * modpar1; + x = fmod(x + 1000.0, 1.0) * 2.0 - 1.0; //this is the base function of the profile REALTYPE f; - switch (Php.base.type) { + switch(Php.base.type) { case 1: - f=exp(-(x*x)*basepar); - if (f<0.4) f=0.0; - else f=1.0; + f = exp(-(x * x) * basepar); + if(f < 0.4) + f = 0.0; + else + f = 1.0; break; case 2: - f=exp(-(fabs(x))*sqrt(basepar)); + f = exp(-(fabs(x)) * sqrt(basepar)); break; default: - f=exp(-(x*x)*basepar); + f = exp(-(x * x) * basepar); break; - }; - if (makezero) f=0.0; + } + if(makezero) + f = 0.0; - REALTYPE amp=1.0; - origx=origx*2.0-1.0; + REALTYPE amp = 1.0; + origx = origx * 2.0 - 1.0; //compute the amplitude multiplier - switch (Php.amp.type) { + switch(Php.amp.type) { case 1: - amp=exp(-(origx*origx)*10.0*amppar1); + amp = exp(-(origx * origx) * 10.0 * amppar1); break; case 2: - amp=0.5*(1.0+cos(3.1415926*origx*sqrt(amppar1*4.0+1.0))); + amp = 0.5 * (1.0 + cos(3.1415926 * origx * sqrt(amppar1 * 4.0 + 1.0))); break; case 3: - amp=1.0/(pow(origx*(amppar1*2.0+0.8),14.0)+1.0); + amp = 1.0 / (pow(origx * (amppar1 * 2.0 + 0.8), 14.0) + 1.0); break; - }; + } //apply the amplitude multiplier - REALTYPE finalsmp=f; - if (Php.amp.type!=0) { - switch (Php.amp.mode) { + REALTYPE finalsmp = f; + if(Php.amp.type != 0) + switch(Php.amp.mode) { case 0: - finalsmp=amp*(1.0-amppar2)+finalsmp*amppar2; + finalsmp = amp * (1.0 - amppar2) + finalsmp * amppar2; break; case 1: - finalsmp*=amp*(1.0-amppar2)+amppar2; + finalsmp *= amp * (1.0 - amppar2) + amppar2; break; case 2: - finalsmp=finalsmp/(amp+pow(amppar2,4.0)*20.0+0.0001); + finalsmp = finalsmp / (amp + pow(amppar2, 4.0) * 20.0 + 0.0001); break; case 3: - finalsmp=amp/(finalsmp+pow(amppar2,4.0)*20.0+0.0001); + finalsmp = amp / (finalsmp + pow(amppar2, 4.0) * 20.0 + 0.0001); break; - }; - }; + } + ; - smp[i/supersample]+=finalsmp/supersample; - }; + smp[i / supersample] += finalsmp / supersample; + } //normalize the profile (make the max. to be equal to 1.0) - REALTYPE max=0.0; - for (int i=0;i<size;i++) { - if (smp[i]<0.0) smp[i]=0.0; - if (smp[i]>max) max=smp[i]; - }; - if (max<0.00001) max=1.0; - for (int i=0;i<size;i++) smp[i]/=max; - - if (!Php.autoscale) return(0.5); + REALTYPE max = 0.0; + for(int i = 0; i < size; i++) { + if(smp[i] < 0.0) + smp[i] = 0.0; + if(smp[i] > max) + max = smp[i]; + } + if(max < 0.00001) + max = 1.0; + for(int i = 0; i < size; i++) + smp[i] /= max; + + if(!Php.autoscale) + return 0.5; //compute the estimated perceived bandwidth - REALTYPE sum=0.0; - int i; - for (i=0;i<size/2-2;i++) { - sum+=smp[i]*smp[i]+smp[size-i-1]*smp[size-i-1]; - if (sum>=4.0) break; - }; + REALTYPE sum = 0.0; + int i; + for(i = 0; i < size / 2 - 2; i++) { + sum += smp[i] * smp[i] + smp[size - i - 1] * smp[size - i - 1]; + if(sum >= 4.0) + break; + } - REALTYPE result=1.0-2.0*i/(REALTYPE) size; - return(result); -}; + REALTYPE result = 1.0 - 2.0 * i / (REALTYPE) size; + return result; +} /* * Compute the real bandwidth in cents and returns it @@ -287,315 +306,387 @@ REALTYPE PADnoteParameters::getprofile(REALTYPE *smp,int size) */ REALTYPE PADnoteParameters::setPbandwidth(int Pbandwidth) { - this->Pbandwidth=Pbandwidth; - REALTYPE result=pow(Pbandwidth/1000.0,1.1); - result=pow(10.0,result*4.0)*0.25; - return(result); -}; + this->Pbandwidth = Pbandwidth; + REALTYPE result = pow(Pbandwidth / 1000.0, 1.1); + result = pow(10.0, result * 4.0) * 0.25; + return result; +} /* * Get the harmonic(overtone) position */ REALTYPE PADnoteParameters::getNhr(int n) { - REALTYPE result=1.0; - REALTYPE par1=pow(10.0,-(1.0-Phrpos.par1/255.0)*3.0); - REALTYPE par2=Phrpos.par2/255.0; - - REALTYPE n0=n-1.0; - REALTYPE tmp=0.0; - int thresh=0; - switch (Phrpos.type) { + REALTYPE result = 1.0; + REALTYPE par1 = pow(10.0, -(1.0 - Phrpos.par1 / 255.0) * 3.0); + REALTYPE par2 = Phrpos.par2 / 255.0; + + REALTYPE n0 = n - 1.0; + REALTYPE tmp = 0.0; + int thresh = 0; + switch(Phrpos.type) { case 1: - thresh=(int)(par2*par2*100.0)+1; - if (n<thresh) result=n; - else result=1.0+n0+(n0-thresh+1.0)*par1*8.0; + thresh = (int)(par2 * par2 * 100.0) + 1; + if(n < thresh) + result = n; + else + result = 1.0 + n0 + (n0 - thresh + 1.0) * par1 * 8.0; break; case 2: - thresh=(int)(par2*par2*100.0)+1; - if (n<thresh) result=n; - else result=1.0+n0-(n0-thresh+1.0)*par1*0.90; + thresh = (int)(par2 * par2 * 100.0) + 1; + if(n < thresh) + result = n; + else + result = 1.0 + n0 - (n0 - thresh + 1.0) * par1 * 0.90; break; case 3: - tmp=par1*100.0+1.0; - result=pow(n0/tmp,1.0-par2*0.8)*tmp+1.0; + tmp = par1 * 100.0 + 1.0; + result = pow(n0 / tmp, 1.0 - par2 * 0.8) * tmp + 1.0; break; case 4: - result=n0*(1.0-par1)+pow(n0*0.1,par2*3.0+1.0)*par1*10.0+1.0; + result = n0 + * (1.0 + - par1) + + pow(n0 * 0.1, par2 * 3.0 + 1.0) * par1 * 10.0 + 1.0; break; case 5: - result=n0+sin(n0*par2*par2*PI*0.999)*sqrt(par1)*2.0+1.0; + result = n0 + + sin(n0 * par2 * par2 * PI * 0.999) * sqrt(par1) * 2.0 + 1.0; break; case 6: - tmp=pow(par2*2.0,2.0)+0.1; - result=n0*pow(1.0+par1*pow(n0*0.8,tmp),tmp)+1.0; + tmp = pow(par2 * 2.0, 2.0) + 0.1; + result = n0 * pow(1.0 + par1 * pow(n0 * 0.8, tmp), tmp) + 1.0; break; default: - result=n; + result = n; break; - }; + } - REALTYPE par3=Phrpos.par3/255.0; + REALTYPE par3 = Phrpos.par3 / 255.0; - REALTYPE iresult=floor(result+0.5); - REALTYPE dresult=result-iresult; + REALTYPE iresult = floor(result + 0.5); + REALTYPE dresult = result - iresult; - result=iresult+(1.0-par3)*dresult; + result = iresult + (1.0 - par3) * dresult; - return(result); -}; + return result; +} /* * Generates the long spectrum for Bandwidth mode (only amplitudes are generated; phases will be random) */ -void PADnoteParameters::generatespectrum_bandwidthMode(REALTYPE *spectrum, int size,REALTYPE basefreq,REALTYPE *profile,int profilesize,REALTYPE bwadjust) +void PADnoteParameters::generatespectrum_bandwidthMode(REALTYPE *spectrum, + int size, + REALTYPE basefreq, + REALTYPE *profile, + int profilesize, + REALTYPE bwadjust) { - for (int i=0;i<size;i++) spectrum[i]=0.0; + for(int i = 0; i < size; i++) + spectrum[i] = 0.0; - REALTYPE harmonics[OSCIL_SIZE/2]; - for (int i=0;i<OSCIL_SIZE/2;i++) harmonics[i]=0.0; + REALTYPE harmonics[OSCIL_SIZE / 2]; + for(int i = 0; i < OSCIL_SIZE / 2; i++) + harmonics[i] = 0.0; //get the harmonic structure from the oscillator (I am using the frequency amplitudes, only) - oscilgen->get(harmonics,basefreq,false); + oscilgen->get(harmonics, basefreq, false); //normalize - REALTYPE max=0.0; - for (int i=0;i<OSCIL_SIZE/2;i++) if (harmonics[i]>max) max=harmonics[i]; - if (max<0.000001) max=1; - for (int i=0;i<OSCIL_SIZE/2;i++) harmonics[i]/=max; - - for (int nh=1;nh<OSCIL_SIZE/2;nh++) {//for each harmonic - REALTYPE realfreq=getNhr(nh)*basefreq; - if (realfreq>SAMPLE_RATE*0.49999) break; - if (realfreq<20.0) break; - if (harmonics[nh-1]<1e-4) continue; + REALTYPE max = 0.0; + for(int i = 0; i < OSCIL_SIZE / 2; i++) + if(harmonics[i] > max) + max = harmonics[i]; + if(max < 0.000001) + max = 1; + for(int i = 0; i < OSCIL_SIZE / 2; i++) + harmonics[i] /= max; + + for(int nh = 1; nh < OSCIL_SIZE / 2; nh++) { //for each harmonic + REALTYPE realfreq = getNhr(nh) * basefreq; + if(realfreq > SAMPLE_RATE * 0.49999) + break; + if(realfreq < 20.0) + break; + if(harmonics[nh - 1] < 1e-4) + continue; //compute the bandwidth of each harmonic - REALTYPE bandwidthcents=setPbandwidth(Pbandwidth); - REALTYPE bw=(pow(2.0,bandwidthcents/1200.0)-1.0)*basefreq/bwadjust; - REALTYPE power=1.0; - switch (Pbwscale) { + REALTYPE bandwidthcents = setPbandwidth(Pbandwidth); + REALTYPE bw = + (pow(2.0, bandwidthcents / 1200.0) - 1.0) * basefreq / bwadjust; + REALTYPE power = 1.0; + switch(Pbwscale) { case 0: - power=1.0; + power = 1.0; break; case 1: - power=0.0; + power = 0.0; break; case 2: - power=0.25; + power = 0.25; break; case 3: - power=0.5; + power = 0.5; break; case 4: - power=0.75; + power = 0.75; break; case 5: - power=1.5; + power = 1.5; break; case 6: - power=2.0; + power = 2.0; break; case 7: - power=-0.5; + power = -0.5; break; - }; - bw=bw*pow(realfreq/basefreq,power); - int ibw=(int)((bw/(SAMPLE_RATE*0.5)*size))+1; - - REALTYPE amp=harmonics[nh-1]; - if (resonance->Penabled) amp*=resonance->getfreqresponse(realfreq); - - if (ibw>profilesize) {//if the bandwidth is larger than the profilesize - REALTYPE rap=sqrt((REALTYPE)profilesize/(REALTYPE)ibw); - int cfreq=(int) (realfreq/(SAMPLE_RATE*0.5)*size)-ibw/2; - for (int i=0;i<ibw;i++) { - int src=(int)(i*rap*rap); - int spfreq=i+cfreq; - if (spfreq<0) continue; - if (spfreq>=size) break; - spectrum[spfreq]+=amp*profile[src]*rap; - }; - } else {//if the bandwidth is smaller than the profilesize - REALTYPE rap=sqrt((REALTYPE)ibw/(REALTYPE)profilesize); - REALTYPE ibasefreq=realfreq/(SAMPLE_RATE*0.5)*size; - for (int i=0;i<profilesize;i++) { - REALTYPE idfreq=i/(REALTYPE)profilesize-0.5; - idfreq*=ibw; - int spfreq=(int) (idfreq+ibasefreq); - REALTYPE fspfreq=fmod(idfreq+ibasefreq,1.0); - if (spfreq<=0) continue; - if (spfreq>=size-1) break; - spectrum[spfreq]+=amp*profile[i]*rap*(1.0-fspfreq); - spectrum[spfreq+1]+=amp*profile[i]*rap*fspfreq; - }; - }; - }; -}; + } + bw = bw * pow(realfreq / basefreq, power); + int ibw = (int)((bw / (SAMPLE_RATE * 0.5) * size)) + 1; + + REALTYPE amp = harmonics[nh - 1]; + if(resonance->Penabled) + amp *= resonance->getfreqresponse(realfreq); + + if(ibw > profilesize) { //if the bandwidth is larger than the profilesize + REALTYPE rap = sqrt((REALTYPE)profilesize / (REALTYPE)ibw); + int cfreq = + (int) (realfreq / (SAMPLE_RATE * 0.5) * size) - ibw / 2; + for(int i = 0; i < ibw; i++) { + int src = (int)(i * rap * rap); + int spfreq = i + cfreq; + if(spfreq < 0) + continue; + if(spfreq >= size) + break; + spectrum[spfreq] += amp * profile[src] * rap; + } + } + else { //if the bandwidth is smaller than the profilesize + REALTYPE rap = sqrt((REALTYPE)ibw / (REALTYPE)profilesize); + REALTYPE ibasefreq = realfreq / (SAMPLE_RATE * 0.5) * size; + for(int i = 0; i < profilesize; i++) { + REALTYPE idfreq = i / (REALTYPE)profilesize - 0.5; + idfreq *= ibw; + int spfreq = (int) (idfreq + ibasefreq); + REALTYPE fspfreq = fmod(idfreq + ibasefreq, 1.0); + if(spfreq <= 0) + continue; + if(spfreq >= size - 1) + break; + spectrum[spfreq] += amp * profile[i] * rap * (1.0 - fspfreq); + spectrum[spfreq + 1] += amp * profile[i] * rap * fspfreq; + } + } + } +} /* * Generates the long spectrum for non-Bandwidth modes (only amplitudes are generated; phases will be random) */ -void PADnoteParameters::generatespectrum_otherModes(REALTYPE *spectrum, int size,REALTYPE basefreq,REALTYPE *profile,int profilesize,REALTYPE bwadjust) +void PADnoteParameters::generatespectrum_otherModes(REALTYPE *spectrum, + int size, + REALTYPE basefreq, + REALTYPE *profile, + int profilesize, + REALTYPE bwadjust) { - for (int i=0;i<size;i++) spectrum[i]=0.0; + for(int i = 0; i < size; i++) + spectrum[i] = 0.0; - REALTYPE harmonics[OSCIL_SIZE/2]; - for (int i=0;i<OSCIL_SIZE/2;i++) harmonics[i]=0.0; + REALTYPE harmonics[OSCIL_SIZE / 2]; + for(int i = 0; i < OSCIL_SIZE / 2; i++) + harmonics[i] = 0.0; //get the harmonic structure from the oscillator (I am using the frequency amplitudes, only) - oscilgen->get(harmonics,basefreq,false); + oscilgen->get(harmonics, basefreq, false); //normalize - REALTYPE max=0.0; - for (int i=0;i<OSCIL_SIZE/2;i++) if (harmonics[i]>max) max=harmonics[i]; - if (max<0.000001) max=1; - for (int i=0;i<OSCIL_SIZE/2;i++) harmonics[i]/=max; - - for (int nh=1;nh<OSCIL_SIZE/2;nh++) {//for each harmonic - REALTYPE realfreq=getNhr(nh)*basefreq; + REALTYPE max = 0.0; + for(int i = 0; i < OSCIL_SIZE / 2; i++) + if(harmonics[i] > max) + max = harmonics[i]; + if(max < 0.000001) + max = 1; + for(int i = 0; i < OSCIL_SIZE / 2; i++) + harmonics[i] /= max; + + for(int nh = 1; nh < OSCIL_SIZE / 2; nh++) { //for each harmonic + REALTYPE realfreq = getNhr(nh) * basefreq; ///sa fac aici interpolarea si sa am grija daca frecv descresc - if (realfreq>SAMPLE_RATE*0.49999) break; - if (realfreq<20.0) break; + if(realfreq > SAMPLE_RATE * 0.49999) + break; + if(realfreq < 20.0) + break; // if (harmonics[nh-1]<1e-4) continue; - REALTYPE amp=harmonics[nh-1]; - if (resonance->Penabled) amp*=resonance->getfreqresponse(realfreq); - int cfreq=(int) (realfreq/(SAMPLE_RATE*0.5)*size); - - spectrum[cfreq]=amp+1e-9; - }; - - if (Pmode!=1) { - int old=0; - for (int k=1;k<size;k++) { - if ( (spectrum[k]>1e-10) || (k==(size-1)) ) { - int delta=k-old; - REALTYPE val1=spectrum[old]; - REALTYPE val2=spectrum[k]; - REALTYPE idelta=1.0/delta; - for (int i=0;i<delta;i++) { - REALTYPE x=idelta*i; - spectrum[old+i]=val1*(1.0-x)+val2*x; - }; - old=k; - }; - }; - }; - -}; + REALTYPE amp = harmonics[nh - 1]; + if(resonance->Penabled) + amp *= resonance->getfreqresponse(realfreq); + int cfreq = (int) (realfreq / (SAMPLE_RATE * 0.5) * size); + + spectrum[cfreq] = amp + 1e-9; + } + + if(Pmode != 1) { + int old = 0; + for(int k = 1; k < size; k++) { + if((spectrum[k] > 1e-10) || (k == (size - 1))) { + int delta = k - old; + REALTYPE val1 = spectrum[old]; + REALTYPE val2 = spectrum[k]; + REALTYPE idelta = 1.0 / delta; + for(int i = 0; i < delta; i++) { + REALTYPE x = idelta * i; + spectrum[old + i] = val1 * (1.0 - x) + val2 * x; + } + old = k; + } + } + } +} /* * Applies the parameters (i.e. computes all the samples, based on parameters); */ void PADnoteParameters::applyparameters(bool lockmutex) { - const int samplesize=(((int) 1)<<(Pquality.samplesize+14)); - int spectrumsize=samplesize/2; + const int samplesize = (((int) 1) << (Pquality.samplesize + 14)); + int spectrumsize = samplesize / 2; REALTYPE spectrum[spectrumsize]; - int profilesize=512; + int profilesize = 512; REALTYPE profile[profilesize]; - REALTYPE bwadjust=getprofile(profile,profilesize); + REALTYPE bwadjust = getprofile(profile, profilesize); // for (int i=0;i<profilesize;i++) profile[i]*=profile[i]; - REALTYPE basefreq=65.406*pow(2.0,Pquality.basenote/2); - if (Pquality.basenote%2==1) basefreq*=1.5; - - int samplemax=Pquality.oct+1; - int smpoct=Pquality.smpoct; - if (Pquality.smpoct==5) smpoct=6; - if (Pquality.smpoct==6) smpoct=12; - if (smpoct!=0) samplemax*=smpoct; - else samplemax=samplemax/2+1; - if (samplemax==0) samplemax=1; + REALTYPE basefreq = 65.406 * pow(2.0, Pquality.basenote / 2); + if(Pquality.basenote % 2 == 1) + basefreq *= 1.5; + + int samplemax = Pquality.oct + 1; + int smpoct = Pquality.smpoct; + if(Pquality.smpoct == 5) + smpoct = 6; + if(Pquality.smpoct == 6) + smpoct = 12; + if(smpoct != 0) + samplemax *= smpoct; + else + samplemax = samplemax / 2 + 1; + if(samplemax == 0) + samplemax = 1; //prepare a BIG FFT stuff - FFTwrapper *fft=new FFTwrapper(samplesize); - FFTFREQS fftfreqs; - newFFTFREQS(&fftfreqs,samplesize/2); - - REALTYPE adj[samplemax];//this is used to compute frequency relation to the base frequency - for (int nsample=0;nsample<samplemax;nsample++) adj[nsample]=(Pquality.oct+1.0)*(REALTYPE)nsample/samplemax; - for (int nsample=0;nsample<samplemax;nsample++) { - REALTYPE tmp=adj[nsample]-adj[samplemax-1]*0.5; - REALTYPE basefreqadjust=pow(2.0,tmp); - - if (Pmode==0) generatespectrum_bandwidthMode(spectrum,spectrumsize,basefreq*basefreqadjust,profile,profilesize,bwadjust); - else generatespectrum_otherModes(spectrum,spectrumsize,basefreq*basefreqadjust,profile,profilesize,bwadjust); - - const int extra_samples=5;//the last samples contains the first samples (used for linear/cubic interpolation) - newsample.smp=new REALTYPE[samplesize+extra_samples]; - - newsample.smp[0]=0.0; - for (int i=1;i<spectrumsize;i++) {//randomize the phases - REALTYPE phase=RND*6.29; - fftfreqs.c[i]=spectrum[i]*cos(phase); - fftfreqs.s[i]=spectrum[i]*sin(phase); - }; - fft->freqs2smps(fftfreqs,newsample.smp);//that's all; here is the only ifft for the whole sample; no windows are used ;-) + FFTwrapper *fft = new FFTwrapper(samplesize); + FFTFREQS fftfreqs; + newFFTFREQS(&fftfreqs, samplesize / 2); + + REALTYPE adj[samplemax]; //this is used to compute frequency relation to the base frequency + for(int nsample = 0; nsample < samplemax; nsample++) + adj[nsample] = (Pquality.oct + 1.0) * (REALTYPE)nsample / samplemax; + for(int nsample = 0; nsample < samplemax; nsample++) { + REALTYPE tmp = adj[nsample] - adj[samplemax - 1] * 0.5; + REALTYPE basefreqadjust = pow(2.0, tmp); + + if(Pmode == 0) + generatespectrum_bandwidthMode(spectrum, + spectrumsize, + basefreq * basefreqadjust, + profile, + profilesize, + bwadjust); + else + generatespectrum_otherModes(spectrum, + spectrumsize, + basefreq * basefreqadjust, + profile, + profilesize, + bwadjust); + + const int extra_samples = 5; //the last samples contains the first samples (used for linear/cubic interpolation) + newsample.smp = new REALTYPE[samplesize + extra_samples]; + + newsample.smp[0] = 0.0; + for(int i = 1; i < spectrumsize; i++) { //randomize the phases + REALTYPE phase = RND * 6.29; + fftfreqs.c[i] = spectrum[i] * cos(phase); + fftfreqs.s[i] = spectrum[i] * sin(phase); + } + fft->freqs2smps(fftfreqs, newsample.smp); //that's all; here is the only ifft for the whole sample; no windows are used ;-) //normalize(rms) - REALTYPE rms=0.0; - for (int i=0;i<samplesize;i++) rms+=newsample.smp[i]*newsample.smp[i]; - rms=sqrt(rms); - if (rms<0.000001) rms=1.0; - rms*=sqrt(262144.0/samplesize); - for (int i=0;i<samplesize;i++) newsample.smp[i]*=1.0/rms*50.0; + REALTYPE rms = 0.0; + for(int i = 0; i < samplesize; i++) + rms += newsample.smp[i] * newsample.smp[i]; + rms = sqrt(rms); + if(rms < 0.000001) + rms = 1.0; + rms *= sqrt(262144.0 / samplesize); + for(int i = 0; i < samplesize; i++) + newsample.smp[i] *= 1.0 / rms * 50.0; //prepare extra samples used by the linear or cubic interpolation - for (int i=0;i<extra_samples;i++) newsample.smp[i+samplesize]=newsample.smp[i]; + for(int i = 0; i < extra_samples; i++) + newsample.smp[i + samplesize] = newsample.smp[i]; //replace the current sample with the new computed sample - if (lockmutex) { + if(lockmutex) { pthread_mutex_lock(mutex); deletesample(nsample); - sample[nsample].smp=newsample.smp; - sample[nsample].size=samplesize; - sample[nsample].basefreq=basefreq*basefreqadjust; + sample[nsample].smp = newsample.smp; + sample[nsample].size = samplesize; + sample[nsample].basefreq = basefreq * basefreqadjust; pthread_mutex_unlock(mutex); - } else { + } + else { deletesample(nsample); - sample[nsample].smp=newsample.smp; - sample[nsample].size=samplesize; - sample[nsample].basefreq=basefreq*basefreqadjust; - }; - newsample.smp=NULL; - }; - delete(fft); + sample[nsample].smp = newsample.smp; + sample[nsample].size = samplesize; + sample[nsample].basefreq = basefreq * basefreqadjust; + } + newsample.smp = NULL; + } + delete (fft); deleteFFTFREQS(&fftfreqs); //delete the additional samples that might exists and are not useful - if (lockmutex) { + if(lockmutex) { pthread_mutex_lock(mutex); - for (int i=samplemax;i<PAD_MAX_SAMPLES;i++) deletesample(i); + for(int i = samplemax; i < PAD_MAX_SAMPLES; i++) + deletesample(i); pthread_mutex_unlock(mutex); - } else { - for (int i=samplemax;i<PAD_MAX_SAMPLES;i++) deletesample(i); - }; -}; + } + else + for(int i = samplemax; i < PAD_MAX_SAMPLES; i++) + deletesample(i); + ; +} void PADnoteParameters::export2wav(string basefilename) { applyparameters(true); - basefilename+="_PADsynth_"; - for (int k=0;k<PAD_MAX_SAMPLES;k++) { - if (sample[k].smp==NULL) continue; + basefilename += "_PADsynth_"; + for(int k = 0; k < PAD_MAX_SAMPLES; k++) { + if(sample[k].smp == NULL) + continue; char tmpstr[20]; - snprintf(tmpstr,20,"_%02d",k+1); - string filename=basefilename+string(tmpstr)+".wav"; + snprintf(tmpstr, 20, "_%02d", k + 1); + string filename = basefilename + string(tmpstr) + ".wav"; WAVaudiooutput wav; - if (wav.newfile(filename,SAMPLE_RATE,1)) { - int nsmps=sample[k].size; - short int *smps=new short int[nsmps]; - for (int i=0;i<nsmps;i++) smps[i]=(short int)(sample[k].smp[i]*32767.0); + if(wav.newfile(filename, SAMPLE_RATE, 1)) { + int nsmps = sample[k].size; + short int *smps = new short int[nsmps]; + for(int i = 0; i < nsmps; i++) + smps[i] = (short int)(sample[k].smp[i] * 32767.0); wav.write_mono_samples(nsmps, smps); wav.close(); - }; - }; -}; + } + } +} @@ -603,24 +694,24 @@ void PADnoteParameters::add2XML(XMLwrapper *xml) { xml->setPadSynth(true); - xml->addparbool("stereo",PStereo); - xml->addpar("mode",Pmode); - xml->addpar("bandwidth",Pbandwidth); - xml->addpar("bandwidth_scale",Pbwscale); + xml->addparbool("stereo", PStereo); + xml->addpar("mode", Pmode); + xml->addpar("bandwidth", Pbandwidth); + xml->addpar("bandwidth_scale", Pbwscale); xml->beginbranch("HARMONIC_PROFILE"); - xml->addpar("base_type",Php.base.type); - xml->addpar("base_par1",Php.base.par1); - xml->addpar("frequency_multiplier",Php.freqmult); - xml->addpar("modulator_par1",Php.modulator.par1); - xml->addpar("modulator_frequency",Php.modulator.freq); - xml->addpar("width",Php.width); - xml->addpar("amplitude_multiplier_type",Php.amp.type); - xml->addpar("amplitude_multiplier_mode",Php.amp.mode); - xml->addpar("amplitude_multiplier_par1",Php.amp.par1); - xml->addpar("amplitude_multiplier_par2",Php.amp.par2); - xml->addparbool("autoscale",Php.autoscale); - xml->addpar("one_half",Php.onehalf); + xml->addpar("base_type", Php.base.type); + xml->addpar("base_par1", Php.base.par1); + xml->addpar("frequency_multiplier", Php.freqmult); + xml->addpar("modulator_par1", Php.modulator.par1); + xml->addpar("modulator_frequency", Php.modulator.freq); + xml->addpar("width", Php.width); + xml->addpar("amplitude_multiplier_type", Php.amp.type); + xml->addpar("amplitude_multiplier_mode", Php.amp.mode); + xml->addpar("amplitude_multiplier_par1", Php.amp.par1); + xml->addpar("amplitude_multiplier_par2", Php.amp.par2); + xml->addparbool("autoscale", Php.autoscale); + xml->addpar("one_half", Php.onehalf); xml->endbranch(); xml->beginbranch("OSCIL"); @@ -632,27 +723,27 @@ void PADnoteParameters::add2XML(XMLwrapper *xml) xml->endbranch(); xml->beginbranch("HARMONIC_POSITION"); - xml->addpar("type",Phrpos.type); - xml->addpar("parameter1",Phrpos.par1); - xml->addpar("parameter2",Phrpos.par2); - xml->addpar("parameter3",Phrpos.par3); + xml->addpar("type", Phrpos.type); + xml->addpar("parameter1", Phrpos.par1); + xml->addpar("parameter2", Phrpos.par2); + xml->addpar("parameter3", Phrpos.par3); xml->endbranch(); xml->beginbranch("SAMPLE_QUALITY"); - xml->addpar("samplesize",Pquality.samplesize); - xml->addpar("basenote",Pquality.basenote); - xml->addpar("octaves",Pquality.oct); - xml->addpar("samples_per_octave",Pquality.smpoct); + xml->addpar("samplesize", Pquality.samplesize); + xml->addpar("basenote", Pquality.basenote); + xml->addpar("octaves", Pquality.oct); + xml->addpar("samples_per_octave", Pquality.smpoct); xml->endbranch(); xml->beginbranch("AMPLITUDE_PARAMETERS"); - xml->addpar("volume",PVolume); - xml->addpar("panning",PPanning); - xml->addpar("velocity_sensing",PAmpVelocityScaleFunction); - xml->addpar("punch_strength",PPunchStrength); - xml->addpar("punch_time",PPunchTime); - xml->addpar("punch_stretch",PPunchStretch); - xml->addpar("punch_velocity_sensing",PPunchVelocitySensing); + xml->addpar("volume", PVolume); + xml->addpar("panning", PPanning); + xml->addpar("velocity_sensing", PAmpVelocityScaleFunction); + xml->addpar("punch_strength", PPunchStrength); + xml->addpar("punch_time", PPunchTime); + xml->addpar("punch_stretch", PPunchStretch); + xml->addpar("punch_velocity_sensing", PPunchVelocitySensing); xml->beginbranch("AMPLITUDE_ENVELOPE"); AmpEnvelope->add2XML(xml); @@ -665,11 +756,11 @@ void PADnoteParameters::add2XML(XMLwrapper *xml) xml->endbranch(); xml->beginbranch("FREQUENCY_PARAMETERS"); - xml->addpar("fixed_freq",Pfixedfreq); - xml->addpar("fixed_freq_et",PfixedfreqET); - xml->addpar("detune",PDetune); - xml->addpar("coarse_detune",PCoarseDetune); - xml->addpar("detune_type",PDetuneType); + xml->addpar("fixed_freq", Pfixedfreq); + xml->addpar("fixed_freq_et", PfixedfreqET); + xml->addpar("detune", PDetune); + xml->addpar("coarse_detune", PCoarseDetune); + xml->addpar("detune_type", PDetuneType); xml->beginbranch("FREQUENCY_ENVELOPE"); FreqEnvelope->add2XML(xml); @@ -681,8 +772,8 @@ void PADnoteParameters::add2XML(XMLwrapper *xml) xml->endbranch(); xml->beginbranch("FILTER_PARAMETERS"); - xml->addpar("velocity_sensing_amplitude",PFilterVelocityScale); - xml->addpar("velocity_sensing",PFilterVelocityScaleFunction); + xml->addpar("velocity_sensing_amplitude", PFilterVelocityScale); + xml->addpar("velocity_sensing", PFilterVelocityScaleFunction); xml->beginbranch("FILTER"); GlobalFilter->add2XML(xml); @@ -696,65 +787,75 @@ void PADnoteParameters::add2XML(XMLwrapper *xml) FilterLfo->add2XML(xml); xml->endbranch(); xml->endbranch(); -}; +} void PADnoteParameters::getfromXML(XMLwrapper *xml) { - PStereo=xml->getparbool("stereo",PStereo); - Pmode=xml->getpar127("mode",0); - Pbandwidth=xml->getpar("bandwidth",Pbandwidth,0,1000); - Pbwscale=xml->getpar127("bandwidth_scale",Pbwscale); - - if (xml->enterbranch("HARMONIC_PROFILE")) { - Php.base.type=xml->getpar127("base_type",Php.base.type); - Php.base.par1=xml->getpar127("base_par1",Php.base.par1); - Php.freqmult=xml->getpar127("frequency_multiplier",Php.freqmult); - Php.modulator.par1=xml->getpar127("modulator_par1",Php.modulator.par1); - Php.modulator.freq=xml->getpar127("modulator_frequency",Php.modulator.freq); - Php.width=xml->getpar127("width",Php.width); - Php.amp.type=xml->getpar127("amplitude_multiplier_type",Php.amp.type); - Php.amp.mode=xml->getpar127("amplitude_multiplier_mode",Php.amp.mode); - Php.amp.par1=xml->getpar127("amplitude_multiplier_par1",Php.amp.par1); - Php.amp.par2=xml->getpar127("amplitude_multiplier_par2",Php.amp.par2); - Php.autoscale=xml->getparbool("autoscale",Php.autoscale); - Php.onehalf=xml->getpar127("one_half",Php.onehalf); + PStereo = xml->getparbool("stereo", PStereo); + Pmode = xml->getpar127("mode", 0); + Pbandwidth = xml->getpar("bandwidth", Pbandwidth, 0, 1000); + Pbwscale = xml->getpar127("bandwidth_scale", Pbwscale); + + if(xml->enterbranch("HARMONIC_PROFILE")) { + Php.base.type = xml->getpar127("base_type", Php.base.type); + Php.base.par1 = xml->getpar127("base_par1", Php.base.par1); + Php.freqmult = xml->getpar127("frequency_multiplier", + Php.freqmult); + Php.modulator.par1 = xml->getpar127("modulator_par1", + Php.modulator.par1); + Php.modulator.freq = xml->getpar127("modulator_frequency", + Php.modulator.freq); + Php.width = xml->getpar127("width", Php.width); + Php.amp.type = xml->getpar127("amplitude_multiplier_type", + Php.amp.type); + Php.amp.mode = xml->getpar127("amplitude_multiplier_mode", + Php.amp.mode); + Php.amp.par1 = xml->getpar127("amplitude_multiplier_par1", + Php.amp.par1); + Php.amp.par2 = xml->getpar127("amplitude_multiplier_par2", + Php.amp.par2); + Php.autoscale = xml->getparbool("autoscale", Php.autoscale); + Php.onehalf = xml->getpar127("one_half", Php.onehalf); xml->exitbranch(); - }; + } - if (xml->enterbranch("OSCIL")) { + if(xml->enterbranch("OSCIL")) { oscilgen->getfromXML(xml); xml->exitbranch(); - }; + } - if (xml->enterbranch("RESONANCE")) { + if(xml->enterbranch("RESONANCE")) { resonance->getfromXML(xml); xml->exitbranch(); - }; + } - if (xml->enterbranch("HARMONIC_POSITION")) { - Phrpos.type=xml->getpar127("type",Phrpos.type); - Phrpos.par1=xml->getpar("parameter1",Phrpos.par1,0,255); - Phrpos.par2=xml->getpar("parameter2",Phrpos.par2,0,255); - Phrpos.par3=xml->getpar("parameter3",Phrpos.par3,0,255); + if(xml->enterbranch("HARMONIC_POSITION")) { + Phrpos.type = xml->getpar127("type", Phrpos.type); + Phrpos.par1 = xml->getpar("parameter1", Phrpos.par1, 0, 255); + Phrpos.par2 = xml->getpar("parameter2", Phrpos.par2, 0, 255); + Phrpos.par3 = xml->getpar("parameter3", Phrpos.par3, 0, 255); xml->exitbranch(); - }; - - if (xml->enterbranch("SAMPLE_QUALITY")) { - Pquality.samplesize=xml->getpar127("samplesize",Pquality.samplesize); - Pquality.basenote=xml->getpar127("basenote",Pquality.basenote); - Pquality.oct=xml->getpar127("octaves",Pquality.oct); - Pquality.smpoct=xml->getpar127("samples_per_octave",Pquality.smpoct); + } + + if(xml->enterbranch("SAMPLE_QUALITY")) { + Pquality.samplesize = xml->getpar127("samplesize", Pquality.samplesize); + Pquality.basenote = xml->getpar127("basenote", Pquality.basenote); + Pquality.oct = xml->getpar127("octaves", Pquality.oct); + Pquality.smpoct = xml->getpar127("samples_per_octave", + Pquality.smpoct); xml->exitbranch(); - }; - - if (xml->enterbranch("AMPLITUDE_PARAMETERS")) { - PVolume=xml->getpar127("volume",PVolume); - PPanning=xml->getpar127("panning",PPanning); - PAmpVelocityScaleFunction=xml->getpar127("velocity_sensing",PAmpVelocityScaleFunction); - PPunchStrength=xml->getpar127("punch_strength",PPunchStrength); - PPunchTime=xml->getpar127("punch_time",PPunchTime); - PPunchStretch=xml->getpar127("punch_stretch",PPunchStretch); - PPunchVelocitySensing=xml->getpar127("punch_velocity_sensing",PPunchVelocitySensing); + } + + if(xml->enterbranch("AMPLITUDE_PARAMETERS")) { + PVolume = xml->getpar127("volume", PVolume); + PPanning = xml->getpar127("panning", PPanning); + PAmpVelocityScaleFunction = xml->getpar127("velocity_sensing", + PAmpVelocityScaleFunction); + PPunchStrength = xml->getpar127("punch_strength", PPunchStrength); + PPunchTime = xml->getpar127("punch_time", PPunchTime); + PPunchStretch = xml->getpar127("punch_stretch", PPunchStretch); + PPunchVelocitySensing = xml->getpar127("punch_velocity_sensing", + PPunchVelocitySensing); xml->enterbranch("AMPLITUDE_ENVELOPE"); AmpEnvelope->getfromXML(xml); @@ -765,14 +866,14 @@ void PADnoteParameters::getfromXML(XMLwrapper *xml) xml->exitbranch(); xml->exitbranch(); - }; + } - if (xml->enterbranch("FREQUENCY_PARAMETERS")) { - Pfixedfreq=xml->getpar127("fixed_freq",Pfixedfreq); - PfixedfreqET=xml->getpar127("fixed_freq_et",PfixedfreqET); - PDetune=xml->getpar("detune",PDetune,0,16383); - PCoarseDetune=xml->getpar("coarse_detune",PCoarseDetune,0,16383); - PDetuneType=xml->getpar127("detune_type",PDetuneType); + if(xml->enterbranch("FREQUENCY_PARAMETERS")) { + Pfixedfreq = xml->getpar127("fixed_freq", Pfixedfreq); + PfixedfreqET = xml->getpar127("fixed_freq_et", PfixedfreqET); + PDetune = xml->getpar("detune", PDetune, 0, 16383); + PCoarseDetune = xml->getpar("coarse_detune", PCoarseDetune, 0, 16383); + PDetuneType = xml->getpar127("detune_type", PDetuneType); xml->enterbranch("FREQUENCY_ENVELOPE"); FreqEnvelope->getfromXML(xml); @@ -782,11 +883,14 @@ void PADnoteParameters::getfromXML(XMLwrapper *xml) FreqLfo->getfromXML(xml); xml->exitbranch(); xml->exitbranch(); - }; + } - if (xml->enterbranch("FILTER_PARAMETERS")) { - PFilterVelocityScale=xml->getpar127("velocity_sensing_amplitude",PFilterVelocityScale); - PFilterVelocityScaleFunction=xml->getpar127("velocity_sensing",PFilterVelocityScaleFunction); + if(xml->enterbranch("FILTER_PARAMETERS")) { + PFilterVelocityScale = xml->getpar127("velocity_sensing_amplitude", + PFilterVelocityScale); + PFilterVelocityScaleFunction = xml->getpar127( + "velocity_sensing", + PFilterVelocityScaleFunction); xml->enterbranch("FILTER"); GlobalFilter->getfromXML(xml); @@ -800,7 +904,6 @@ void PADnoteParameters::getfromXML(XMLwrapper *xml) FilterLfo->getfromXML(xml); xml->exitbranch(); xml->exitbranch(); - }; -}; - + } +} diff --git a/src/Params/PADnoteParameters.h b/src/Params/PADnoteParameters.h @@ -38,133 +38,145 @@ class PADnoteParameters:public Presets { -public: - PADnoteParameters(FFTwrapper *fft_,pthread_mutex_t *mutex_); - ~PADnoteParameters(); - - void defaults(); - void add2XML(XMLwrapper *xml); - void getfromXML(XMLwrapper *xml); - - //returns a value between 0.0-1.0 that represents the estimation perceived bandwidth - REALTYPE getprofile(REALTYPE *smp,int size); - - //parameters - - //the mode: 0 - bandwidth, 1 - discrete (bandwidth=0), 2 - continous - //the harmonic profile is used only on mode 0 - unsigned char Pmode; - - //Harmonic profile (the frequency distribution of a single harmonic) - struct { - struct {//base function + public: + PADnoteParameters(FFTwrapper *fft_, pthread_mutex_t *mutex_); + ~PADnoteParameters(); + + void defaults(); + void add2XML(XMLwrapper *xml); + void getfromXML(XMLwrapper *xml); + + //returns a value between 0.0-1.0 that represents the estimation perceived bandwidth + REALTYPE getprofile(REALTYPE *smp, int size); + + //parameters + + //the mode: 0 - bandwidth, 1 - discrete (bandwidth=0), 2 - continous + //the harmonic profile is used only on mode 0 + unsigned char Pmode; + + //Harmonic profile (the frequency distribution of a single harmonic) + struct { + struct { //base function + unsigned char type; + unsigned char par1; + } base; + unsigned char freqmult; //frequency multiplier of the distribution + struct { //the modulator of the distribution + unsigned char par1; + unsigned char freq; + } modulator; + + unsigned char width; //the width of the resulting function after the modulation + struct { //the amplitude multiplier of the harmonic profile + unsigned char mode; + unsigned char type; + unsigned char par1; + unsigned char par2; + } amp; + bool autoscale; //if the scale of the harmonic profile is computed automaticaly + unsigned char onehalf; //what part of the base function is used to make the distribution + } Php; + + + unsigned int Pbandwidth; //the values are from 0 to 1000 + unsigned char Pbwscale; //how the bandwidth is increased according to the harmonic's frequency + + struct { //where are positioned the harmonics (on integer multimplier or different places) unsigned char type; - unsigned char par1; - }base; - unsigned char freqmult;//frequency multiplier of the distribution - struct {//the modulator of the distribution - unsigned char par1; - unsigned char freq; - }modulator; - - unsigned char width;//the width of the resulting function after the modulation - struct {//the amplitude multiplier of the harmonic profile - unsigned char mode; - unsigned char type; - unsigned char par1; - unsigned char par2; - }amp; - bool autoscale;//if the scale of the harmonic profile is computed automaticaly - unsigned char onehalf;//what part of the base function is used to make the distribution - }Php; - - - unsigned int Pbandwidth;//the values are from 0 to 1000 - unsigned char Pbwscale;//how the bandwidth is increased according to the harmonic's frequency + unsigned char par1, par2, par3; //0..255 + } Phrpos; - struct {//where are positioned the harmonics (on integer multimplier or different places) - unsigned char type; - unsigned char par1,par2,par3;//0..255 - }Phrpos; + struct { //quality of the samples (how many samples, the length of them,etc.) + unsigned char samplesize; + unsigned char basenote, oct, smpoct; + } Pquality; - struct {//quality of the samples (how many samples, the length of them,etc.) - unsigned char samplesize; - unsigned char basenote,oct,smpoct; - } Pquality; + //frequency parameters + //If the base frequency is fixed to 440 Hz + unsigned char Pfixedfreq; - //frequency parameters - //If the base frequency is fixed to 440 Hz - unsigned char Pfixedfreq; + /* Equal temperate (this is used only if the Pfixedfreq is enabled) + If this parameter is 0, the frequency is fixed (to 440 Hz); + if this parameter is 64, 1 MIDI halftone -> 1 frequency halftone */ + unsigned char PfixedfreqET; + unsigned short int PDetune; //fine detune + unsigned short int PCoarseDetune; //coarse detune+octave + unsigned char PDetuneType; //detune type - /* Equal temperate (this is used only if the Pfixedfreq is enabled) - If this parameter is 0, the frequency is fixed (to 440 Hz); - if this parameter is 64, 1 MIDI halftone -> 1 frequency halftone */ - unsigned char PfixedfreqET; - unsigned short int PDetune;//fine detune - unsigned short int PCoarseDetune;//coarse detune+octave - unsigned char PDetuneType;//detune type + EnvelopeParams *FreqEnvelope; //Frequency Envelope + LFOParams *FreqLfo; //Frequency LFO - EnvelopeParams *FreqEnvelope; //Frequency Envelope - LFOParams *FreqLfo;//Frequency LFO + //Amplitude parameters + unsigned char PStereo; + /* Panning - 0 - random + 1 - left + 64 - center + 127 - right */ + unsigned char PPanning; - //Amplitude parameters - unsigned char PStereo; - /* Panning - 0 - random - 1 - left - 64 - center - 127 - right */ - unsigned char PPanning; + unsigned char PVolume; - unsigned char PVolume; + unsigned char PAmpVelocityScaleFunction; - unsigned char PAmpVelocityScaleFunction; + EnvelopeParams *AmpEnvelope; - EnvelopeParams *AmpEnvelope; + LFOParams *AmpLfo; - LFOParams *AmpLfo; + unsigned char PPunchStrength, PPunchTime, PPunchStretch, + PPunchVelocitySensing; - unsigned char PPunchStrength,PPunchTime,PPunchStretch,PPunchVelocitySensing; + //Filter Parameters + FilterParams *GlobalFilter; - //Filter Parameters - FilterParams *GlobalFilter; + // filter velocity sensing + unsigned char PFilterVelocityScale; - // filter velocity sensing - unsigned char PFilterVelocityScale; + // filter velocity sensing + unsigned char PFilterVelocityScaleFunction; - // filter velocity sensing - unsigned char PFilterVelocityScaleFunction; + EnvelopeParams *FilterEnvelope; + LFOParams *FilterLfo; - EnvelopeParams *FilterEnvelope; - LFOParams *FilterLfo; + REALTYPE setPbandwidth(int Pbandwidth); //returns the BandWidth in cents + REALTYPE getNhr(int n); //gets the n-th overtone position relatively to N harmonic - REALTYPE setPbandwidth(int Pbandwidth);//returns the BandWidth in cents - REALTYPE getNhr(int n);//gets the n-th overtone position relatively to N harmonic + void applyparameters(bool lockmutex); + void export2wav(std::string basefilename); - void applyparameters(bool lockmutex); - void export2wav(std::string basefilename); + OscilGen *oscilgen; + Resonance *resonance; - OscilGen *oscilgen; - Resonance *resonance; + struct { + int size; + REALTYPE basefreq; + REALTYPE *smp; + } sample[PAD_MAX_SAMPLES], newsample; - struct { - int size; - REALTYPE basefreq; - REALTYPE *smp; - }sample[PAD_MAX_SAMPLES],newsample; + private: + void generatespectrum_bandwidthMode(REALTYPE *spectrum, + int size, + REALTYPE basefreq, + REALTYPE *profile, + int profilesize, + REALTYPE bwadjust); + void generatespectrum_otherModes(REALTYPE *spectrum, + int size, + REALTYPE basefreq, + REALTYPE *profile, + int profilesize, + REALTYPE bwadjust); + void deletesamples(); + void deletesample(int n); -private: - void generatespectrum_bandwidthMode(REALTYPE *spectrum, int size,REALTYPE basefreq,REALTYPE *profile,int profilesize,REALTYPE bwadjust); - void generatespectrum_otherModes(REALTYPE *spectrum, int size,REALTYPE basefreq,REALTYPE *profile,int profilesize,REALTYPE bwadjust); - void deletesamples(); - void deletesample(int n); - - FFTwrapper *fft; - pthread_mutex_t *mutex; + FFTwrapper *fft; + pthread_mutex_t *mutex; }; #endif + diff --git a/src/Params/Presets.cpp b/src/Params/Presets.cpp @@ -26,113 +26,124 @@ Presets::Presets() { - type[0]=0; - nelement=-1; -}; + type[0] = 0; + nelement = -1; +} Presets::~Presets() -{ -}; +{} void Presets::setpresettype(const char *type) { - strcpy(this->type,type); -}; + strcpy(this->type, type); +} void Presets::copy(const char *name) { - XMLwrapper *xml=new XMLwrapper(); + XMLwrapper *xml = new XMLwrapper(); //used only for the clipboard - if (name==NULL) xml->minimal=false; + if(name == NULL) + xml->minimal = false; char type[MAX_PRESETTYPE_SIZE]; - strcpy(type,this->type); - if (nelement!=-1) strcat(type,"n"); - if (name==NULL) { - if (strstr(type,"Plfo")!=NULL) strcpy(type,"Plfo"); - }; + strcpy(type, this->type); + if(nelement != -1) + strcat(type, "n"); + if(name == NULL) + if(strstr(type, "Plfo") != NULL) + strcpy(type, "Plfo"); + ; xml->beginbranch(type); - if (nelement==-1) add2XML(xml); - else add2XMLsection(xml,nelement); + if(nelement == -1) + add2XML(xml); + else + add2XMLsection(xml, nelement); xml->endbranch(); - if (name==NULL) presetsstore.copyclipboard(xml,type); - else presetsstore.copypreset(xml,type,name); + if(name == NULL) + presetsstore.copyclipboard(xml, type); + else + presetsstore.copypreset(xml, type, name); - delete(xml); - nelement=-1; -}; + delete (xml); + nelement = -1; +} void Presets::paste(int npreset) { char type[MAX_PRESETTYPE_SIZE]; - strcpy(type,this->type); - if (nelement!=-1) strcat(type,"n"); - if (npreset==0) { - if (strstr(type,"Plfo")!=NULL) strcpy(type,"Plfo"); - }; - - XMLwrapper *xml=new XMLwrapper(); - if (npreset==0) { - if (!checkclipboardtype()) { - nelement=-1; - delete(xml); + strcpy(type, this->type); + if(nelement != -1) + strcat(type, "n"); + if(npreset == 0) + if(strstr(type, "Plfo") != NULL) + strcpy(type, "Plfo"); + ; + + XMLwrapper *xml = new XMLwrapper(); + if(npreset == 0) { + if(!checkclipboardtype()) { + nelement = -1; + delete (xml); return; - }; - if (!presetsstore.pasteclipboard(xml)) { - delete(xml); - nelement=-1; + } + if(!presetsstore.pasteclipboard(xml)) { + delete (xml); + nelement = -1; return; - }; - } else { - if (!presetsstore.pastepreset(xml,npreset)) { - delete(xml); - nelement=-1; + } + } + else { + if(!presetsstore.pastepreset(xml, npreset)) { + delete (xml); + nelement = -1; return; - }; - }; + } + } - if (xml->enterbranch(type)==0) { - nelement=-1; + if(xml->enterbranch(type) == 0) { + nelement = -1; return; - }; - if (nelement==-1) { + } + if(nelement == -1) { defaults(); getfromXML(xml); - } else { + } + else { defaults(nelement); - getfromXMLsection(xml,nelement); - }; + getfromXMLsection(xml, nelement); + } xml->exitbranch(); - delete(xml); - nelement=-1; -}; + delete (xml); + nelement = -1; +} bool Presets::checkclipboardtype() { char type[MAX_PRESETTYPE_SIZE]; - strcpy(type,this->type); - if (nelement!=-1) strcat(type,"n"); + strcpy(type, this->type); + if(nelement != -1) + strcat(type, "n"); - return(presetsstore.checkclipboardtype(type)); -}; + return presetsstore.checkclipboardtype(type); +} void Presets::setelement(int n) { - nelement=n; -}; + nelement = n; +} void Presets::rescanforpresets() { presetsstore.rescanforpresets(type); -}; +} void Presets::deletepreset(int npreset) { presetsstore.deletepreset(npreset); -}; +} diff --git a/src/Params/Presets.h b/src/Params/Presets.h @@ -30,30 +30,30 @@ /**Presets and Clipboard management*/ class Presets { -public: - Presets(); - virtual ~Presets(); - - void copy(const char *name);/**<if name==NULL, the clipboard is used*/ - void paste(int npreset);//npreset==0 for clipboard - bool checkclipboardtype(); - void deletepreset(int npreset); - - char type[MAX_PRESETTYPE_SIZE]; - void setelement(int n); - - void rescanforpresets(); - -protected: - void setpresettype(const char *type); -private: - virtual void add2XML(XMLwrapper *xml)=0; - virtual void getfromXML(XMLwrapper *xml)=0; - virtual void defaults()=0; - virtual void add2XMLsection(XMLwrapper *xml,int n) {}; - virtual void getfromXMLsection(XMLwrapper *xml,int n) {}; - virtual void defaults(int n) {}; - int nelement; + public: + Presets(); + virtual ~Presets(); + + void copy(const char *name); /**<if name==NULL, the clipboard is used*/ + void paste(int npreset); //npreset==0 for clipboard + bool checkclipboardtype(); + void deletepreset(int npreset); + + char type[MAX_PRESETTYPE_SIZE]; + void setelement(int n); + + void rescanforpresets(); + + protected: + void setpresettype(const char *type); + private: + virtual void add2XML(XMLwrapper *xml) = 0; + virtual void getfromXML(XMLwrapper *xml) = 0; + virtual void defaults() = 0; + virtual void add2XMLsection(XMLwrapper *xml, int n) {} + virtual void getfromXMLsection(XMLwrapper *xml, int n) {} + virtual void defaults(int n) {} + int nelement; }; #endif diff --git a/src/Params/PresetsStore.cpp b/src/Params/PresetsStore.cpp @@ -31,165 +31,199 @@ PresetsStore presetsstore; PresetsStore::PresetsStore() { - clipboard.data=NULL; - clipboard.type[0]=0; + clipboard.data = NULL; + clipboard.type[0] = 0; - for (int i=0;i<MAX_PRESETS;i++) { - presets[i].file=NULL; - presets[i].name=NULL; - }; - -}; + for(int i = 0; i < MAX_PRESETS; i++) { + presets[i].file = NULL; + presets[i].name = NULL; + } +} PresetsStore::~PresetsStore() { - if (clipboard.data!=NULL) free (clipboard.data); + if(clipboard.data != NULL) + free(clipboard.data); clearpresets(); -}; +} //Clipboard management -void PresetsStore::copyclipboard(XMLwrapper *xml,char *type) +void PresetsStore::copyclipboard(XMLwrapper *xml, char *type) { - strcpy(clipboard.type,type); - if (clipboard.data!=NULL) free (clipboard.data); - clipboard.data=xml->getXMLdata(); -}; + strcpy(clipboard.type, type); + if(clipboard.data != NULL) + free(clipboard.data); + clipboard.data = xml->getXMLdata(); +} bool PresetsStore::pasteclipboard(XMLwrapper *xml) { - if (clipboard.data!=NULL) xml->putXMLdata(clipboard.data); - else return(false); - return(true); -}; + if(clipboard.data != NULL) + xml->putXMLdata(clipboard.data); + else + return false; + return true; +} bool PresetsStore::checkclipboardtype(char *type) { //makes LFO's compatible - if ((strstr(type,"Plfo")!=NULL)&&(strstr(clipboard.type,"Plfo")!=NULL)) return(true); - return(strcmp(type,clipboard.type)==0); -}; + if((strstr(type, + "Plfo") != NULL) && (strstr(clipboard.type, "Plfo") != NULL)) + return true; + return strcmp(type, clipboard.type) == 0; +} //Presets management void PresetsStore::clearpresets() { - for (int i=0;i<MAX_PRESETS;i++) { - if (presets[i].file!=NULL) { - delete(presets[i].file); - presets[i].file=NULL; - }; - if (presets[i].name!=NULL) { - delete(presets[i].name); - presets[i].name=NULL; - }; - }; - -}; + for(int i = 0; i < MAX_PRESETS; i++) { + if(presets[i].file != NULL) { + delete (presets[i].file); + presets[i].file = NULL; + } + if(presets[i].name != NULL) { + delete (presets[i].name); + presets[i].name = NULL; + } + } +} //a helper function that compares 2 presets[] -int Presets_compar(const void *a,const void *b) +int Presets_compar(const void *a, const void *b) { - struct PresetsStore::presetstruct *p1= (PresetsStore::presetstruct *)a; - struct PresetsStore::presetstruct *p2= (PresetsStore::presetstruct *)b; - if (((p1->name)==NULL)||((p2->name)==NULL)) return(0); + struct PresetsStore::presetstruct *p1 = (PresetsStore::presetstruct *)a; + struct PresetsStore::presetstruct *p2 = (PresetsStore::presetstruct *)b; + if(((p1->name) == NULL) || ((p2->name) == NULL)) + return 0; - return(strcasecmp(p1->name,p2->name)<0); -}; + return strcasecmp(p1->name, p2->name) < 0; +} void PresetsStore::rescanforpresets(char *type) { clearpresets(); - int presetk=0; + int presetk = 0; char ftype[MAX_STRING_SIZE]; - snprintf(ftype,MAX_STRING_SIZE,".%s.xpz",type); - - for (int i=0;i<MAX_BANK_ROOT_DIRS;i++) { - if (config.cfg.presetsDirList[i]==NULL) continue; - char *dirname=config.cfg.presetsDirList[i]; - DIR *dir=opendir(dirname); - if (dir==NULL) continue; + snprintf(ftype, MAX_STRING_SIZE, ".%s.xpz", type); + + for(int i = 0; i < MAX_BANK_ROOT_DIRS; i++) { + if(config.cfg.presetsDirList[i] == NULL) + continue; + char *dirname = config.cfg.presetsDirList[i]; + DIR *dir = opendir(dirname); + if(dir == NULL) + continue; struct dirent *fn; - while ((fn=readdir(dir))) { - const char *filename=fn->d_name; - if (strstr(filename,ftype)==NULL) continue; + while((fn = readdir(dir))) { + const char *filename = fn->d_name; + if(strstr(filename, ftype) == NULL) + continue; - presets[presetk].file=new char [MAX_STRING_SIZE]; - presets[presetk].name=new char [MAX_STRING_SIZE]; - char tmpc=dirname[strlen(dirname)-1]; + presets[presetk].file = new char [MAX_STRING_SIZE]; + presets[presetk].name = new char [MAX_STRING_SIZE]; + char tmpc = dirname[strlen(dirname) - 1]; const char *tmps; - if ((tmpc=='/')||(tmpc=='\\')) tmps=""; - else tmps="/"; - snprintf(presets[presetk].file,MAX_STRING_SIZE,"%s%s%s",dirname,tmps,filename); - snprintf(presets[presetk].name,MAX_STRING_SIZE,"%s",filename); - - char *tmp=strstr(presets[presetk].name,ftype); - if (tmp!=NULL) tmp[0]='\0'; + if((tmpc == '/') || (tmpc == '\\')) + tmps = ""; + else + tmps = "/"; + snprintf(presets[presetk].file, + MAX_STRING_SIZE, + "%s%s%s", + dirname, + tmps, + filename); + snprintf(presets[presetk].name, MAX_STRING_SIZE, "%s", filename); + + char *tmp = strstr(presets[presetk].name, ftype); + if(tmp != NULL) + tmp[0] = '\0'; presetk++; - if (presetk>=MAX_PRESETS) return; - }; + if(presetk >= MAX_PRESETS) + return; + } closedir(dir); - }; + } //sort the presets - for (int j=0;j<MAX_PRESETS-1;j++) { - for (int i=j+1;i<MAX_PRESETS;i++) { - if (Presets_compar(&presets[i],&presets[j])) { - presetstruct tmp=presets[i]; - presets[i]=presets[j]; - presets[j]=tmp; - }; - }; - }; -}; - -void PresetsStore::copypreset(XMLwrapper *xml,char *type, const char *name) + for(int j = 0; j < MAX_PRESETS - 1; j++) { + for(int i = j + 1; i < MAX_PRESETS; i++) { + if(Presets_compar(&presets[i], &presets[j])) { + presetstruct tmp = presets[i]; + presets[i] = presets[j]; + presets[j] = tmp; + } + } + } +} + +void PresetsStore::copypreset(XMLwrapper *xml, char *type, const char *name) { - char filename[MAX_STRING_SIZE],tmpfilename[MAX_STRING_SIZE]; + char filename[MAX_STRING_SIZE], tmpfilename[MAX_STRING_SIZE]; - if (config.cfg.presetsDirList[0]==NULL) return; + if(config.cfg.presetsDirList[0] == NULL) + return; - snprintf(tmpfilename,MAX_STRING_SIZE,"%s",name); + snprintf(tmpfilename, MAX_STRING_SIZE, "%s", name); //make the filenames legal - for (int i=0;i<(int) strlen(tmpfilename);i++) { - char c=tmpfilename[i]; - if ((c>='0')&&(c<='9')) continue; - if ((c>='A')&&(c<='Z')) continue; - if ((c>='a')&&(c<='z')) continue; - if ((c=='-')||(c==' ')) continue; - tmpfilename[i]='_'; - }; - - const char *dirname=config.cfg.presetsDirList[0]; - char tmpc=dirname[strlen(dirname)-1]; + for(int i = 0; i < (int) strlen(tmpfilename); i++) { + char c = tmpfilename[i]; + if((c >= '0') && (c <= '9')) + continue; + if((c >= 'A') && (c <= 'Z')) + continue; + if((c >= 'a') && (c <= 'z')) + continue; + if((c == '-') || (c == ' ')) + continue; + tmpfilename[i] = '_'; + } + + const char *dirname = config.cfg.presetsDirList[0]; + char tmpc = dirname[strlen(dirname) - 1]; const char *tmps; - if ((tmpc=='/')||(tmpc=='\\')) tmps=""; - else tmps="/"; - - snprintf(filename,MAX_STRING_SIZE,"%s%s%s.%s.xpz",dirname,tmps,name,type); + if((tmpc == '/') || (tmpc == '\\')) + tmps = ""; + else + tmps = "/"; + + snprintf(filename, + MAX_STRING_SIZE, + "%s%s%s.%s.xpz", + dirname, + tmps, + name, + type); xml->saveXMLfile(filename); -}; +} bool PresetsStore::pastepreset(XMLwrapper *xml, int npreset) { npreset--; - if (npreset>=MAX_PRESETS) return(false); - char *filename=presets[npreset].file; - if (filename==NULL) return(false); - bool result=(xml->loadXMLfile(filename)>=0); - return(result); -}; + if(npreset >= MAX_PRESETS) + return false; + char *filename = presets[npreset].file; + if(filename == NULL) + return false; + bool result = (xml->loadXMLfile(filename) >= 0); + return result; +} void PresetsStore::deletepreset(int npreset) { npreset--; - if (npreset>=MAX_PRESETS) return; - char *filename=presets[npreset].file; - if (filename==NULL) return; + if(npreset >= MAX_PRESETS) + return; + char *filename = presets[npreset].file; + if(filename == NULL) + return; remove(filename); -}; +} diff --git a/src/Params/PresetsStore.h b/src/Params/PresetsStore.h @@ -28,36 +28,35 @@ class PresetsStore { -public: - PresetsStore(); - ~PresetsStore(); - - //Clipboard stuff - void copyclipboard(XMLwrapper *xml,char *type); - bool pasteclipboard(XMLwrapper *xml); - bool checkclipboardtype(char *type); - - //presets stuff - void copypreset(XMLwrapper *xml,char *type, const char *name); - bool pastepreset(XMLwrapper *xml, int npreset); - void deletepreset(int npreset); - - struct presetstruct { - char *file; - char *name; - }; - presetstruct presets[MAX_PRESETS]; - - void rescanforpresets(char *type); - -private: - struct { - char *data; - char type[MAX_PRESETTYPE_SIZE]; - } clipboard; - - void clearpresets(); - + public: + PresetsStore(); + ~PresetsStore(); + + //Clipboard stuff + void copyclipboard(XMLwrapper *xml, char *type); + bool pasteclipboard(XMLwrapper *xml); + bool checkclipboardtype(char *type); + + //presets stuff + void copypreset(XMLwrapper *xml, char *type, const char *name); + bool pastepreset(XMLwrapper *xml, int npreset); + void deletepreset(int npreset); + + struct presetstruct { + char *file; + char *name; + }; + presetstruct presets[MAX_PRESETS]; + + void rescanforpresets(char *type); + + private: + struct { + char *data; + char type[MAX_PRESETTYPE_SIZE]; + } clipboard; + + void clearpresets(); }; extern PresetsStore presetsstore; diff --git a/src/Params/SUBnoteParameters.cpp b/src/Params/SUBnoteParameters.cpp @@ -27,59 +27,58 @@ SUBnoteParameters::SUBnoteParameters():Presets() { setpresettype("Psubsyth"); - AmpEnvelope=new EnvelopeParams(64,1); - AmpEnvelope->ADSRinit_dB(0,40,127,25); - FreqEnvelope=new EnvelopeParams(64,0); - FreqEnvelope->ASRinit(30,50,64,60); - BandWidthEnvelope=new EnvelopeParams(64,0); - BandWidthEnvelope->ASRinit_bw(100,70,64,60); + AmpEnvelope = new EnvelopeParams(64, 1); + AmpEnvelope->ADSRinit_dB(0, 40, 127, 25); + FreqEnvelope = new EnvelopeParams(64, 0); + FreqEnvelope->ASRinit(30, 50, 64, 60); + BandWidthEnvelope = new EnvelopeParams(64, 0); + BandWidthEnvelope->ASRinit_bw(100, 70, 64, 60); - GlobalFilter=new FilterParams(2,80,40); - GlobalFilterEnvelope=new EnvelopeParams(0,1); - GlobalFilterEnvelope->ADSRinit_filter(64,40,64,70,60,64); + GlobalFilter = new FilterParams(2, 80, 40); + GlobalFilterEnvelope = new EnvelopeParams(0, 1); + GlobalFilterEnvelope->ADSRinit_filter(64, 40, 64, 70, 60, 64); defaults(); -}; +} void SUBnoteParameters::defaults() { - PVolume=96; - PPanning=64; - PAmpVelocityScaleFunction=90; - - Pfixedfreq=0; - PfixedfreqET=0; - Pnumstages=2; - Pbandwidth=40; - Phmagtype=0; - Pbwscale=64; - Pstereo=1; - Pstart=1; - - PDetune=8192; - PCoarseDetune=0; - PDetuneType=1; - PFreqEnvelopeEnabled=0; - PBandWidthEnvelopeEnabled=0; - - for (int n=0;n<MAX_SUB_HARMONICS;n++) { - Phmag[n]=0; - Phrelbw[n]=64; - }; - Phmag[0]=127; - - PGlobalFilterEnabled=0; - PGlobalFilterVelocityScale=64; - PGlobalFilterVelocityScaleFunction=64; + PVolume = 96; + PPanning = 64; + PAmpVelocityScaleFunction = 90; + + Pfixedfreq = 0; + PfixedfreqET = 0; + Pnumstages = 2; + Pbandwidth = 40; + Phmagtype = 0; + Pbwscale = 64; + Pstereo = 1; + Pstart = 1; + + PDetune = 8192; + PCoarseDetune = 0; + PDetuneType = 1; + PFreqEnvelopeEnabled = 0; + PBandWidthEnvelopeEnabled = 0; + + for(int n = 0; n < MAX_SUB_HARMONICS; n++) { + Phmag[n] = 0; + Phrelbw[n] = 64; + } + Phmag[0] = 127; + + PGlobalFilterEnabled = 0; + PGlobalFilterVelocityScale = 64; + PGlobalFilterVelocityScaleFunction = 64; AmpEnvelope->defaults(); FreqEnvelope->defaults(); BandWidthEnvelope->defaults(); GlobalFilter->defaults(); GlobalFilterEnvelope->defaults(); - -}; +} @@ -90,154 +89,163 @@ SUBnoteParameters::~SUBnoteParameters() delete (BandWidthEnvelope); delete (GlobalFilter); delete (GlobalFilterEnvelope); -}; +} void SUBnoteParameters::add2XML(XMLwrapper *xml) { - xml->addpar("num_stages",Pnumstages); - xml->addpar("harmonic_mag_type",Phmagtype); - xml->addpar("start",Pstart); + xml->addpar("num_stages", Pnumstages); + xml->addpar("harmonic_mag_type", Phmagtype); + xml->addpar("start", Pstart); xml->beginbranch("HARMONICS"); - for (int i=0;i<MAX_SUB_HARMONICS;i++) { - if ((Phmag[i]==0)&&(xml->minimal)) continue; - xml->beginbranch("HARMONIC",i); - xml->addpar("mag",Phmag[i]); - xml->addpar("relbw",Phrelbw[i]); + for(int i = 0; i < MAX_SUB_HARMONICS; i++) { + if((Phmag[i] == 0) && (xml->minimal)) + continue; + xml->beginbranch("HARMONIC", i); + xml->addpar("mag", Phmag[i]); + xml->addpar("relbw", Phrelbw[i]); xml->endbranch(); - }; + } xml->endbranch(); xml->beginbranch("AMPLITUDE_PARAMETERS"); - xml->addparbool("stereo",Pstereo); - xml->addpar("volume",PVolume); - xml->addpar("panning",PPanning); - xml->addpar("velocity_sensing",PAmpVelocityScaleFunction); + xml->addparbool("stereo", Pstereo); + xml->addpar("volume", PVolume); + xml->addpar("panning", PPanning); + xml->addpar("velocity_sensing", PAmpVelocityScaleFunction); xml->beginbranch("AMPLITUDE_ENVELOPE"); AmpEnvelope->add2XML(xml); xml->endbranch(); xml->endbranch(); xml->beginbranch("FREQUENCY_PARAMETERS"); - xml->addparbool("fixed_freq",Pfixedfreq); - xml->addpar("fixed_freq_et",PfixedfreqET); + xml->addparbool("fixed_freq", Pfixedfreq); + xml->addpar("fixed_freq_et", PfixedfreqET); - xml->addpar("detune",PDetune); - xml->addpar("coarse_detune",PCoarseDetune); - xml->addpar("detune_type",PDetuneType); + xml->addpar("detune", PDetune); + xml->addpar("coarse_detune", PCoarseDetune); + xml->addpar("detune_type", PDetuneType); - xml->addpar("bandwidth",Pbandwidth); - xml->addpar("bandwidth_scale",Pbwscale); + xml->addpar("bandwidth", Pbandwidth); + xml->addpar("bandwidth_scale", Pbwscale); - xml->addparbool("freq_envelope_enabled",PFreqEnvelopeEnabled); - if ((PFreqEnvelopeEnabled!=0)||(!xml->minimal)) { + xml->addparbool("freq_envelope_enabled", PFreqEnvelopeEnabled); + if((PFreqEnvelopeEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FREQUENCY_ENVELOPE"); FreqEnvelope->add2XML(xml); xml->endbranch(); - }; + } - xml->addparbool("band_width_envelope_enabled",PBandWidthEnvelopeEnabled); - if ((PBandWidthEnvelopeEnabled!=0)||(!xml->minimal)) { + xml->addparbool("band_width_envelope_enabled", PBandWidthEnvelopeEnabled); + if((PBandWidthEnvelopeEnabled != 0) || (!xml->minimal)) { xml->beginbranch("BANDWIDTH_ENVELOPE"); BandWidthEnvelope->add2XML(xml); xml->endbranch(); - }; + } xml->endbranch(); xml->beginbranch("FILTER_PARAMETERS"); - xml->addparbool("enabled",PGlobalFilterEnabled); - if ((PGlobalFilterEnabled!=0)||(!xml->minimal)) { + xml->addparbool("enabled", PGlobalFilterEnabled); + if((PGlobalFilterEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FILTER"); GlobalFilter->add2XML(xml); xml->endbranch(); - xml->addpar("filter_velocity_sensing",PGlobalFilterVelocityScaleFunction); - xml->addpar("filter_velocity_sensing_amplitude",PGlobalFilterVelocityScale); + xml->addpar("filter_velocity_sensing", + PGlobalFilterVelocityScaleFunction); + xml->addpar("filter_velocity_sensing_amplitude", + PGlobalFilterVelocityScale); xml->beginbranch("FILTER_ENVELOPE"); GlobalFilterEnvelope->add2XML(xml); xml->endbranch(); - }; + } xml->endbranch(); -}; +} void SUBnoteParameters::getfromXML(XMLwrapper *xml) { - Pnumstages=xml->getpar127("num_stages",Pnumstages); - Phmagtype=xml->getpar127("harmonic_mag_type",Phmagtype); - Pstart=xml->getpar127("start",Pstart); - - if (xml->enterbranch("HARMONICS")) { - Phmag[0]=0; - for (int i=0;i<MAX_SUB_HARMONICS;i++) { - if (xml->enterbranch("HARMONIC",i)==0) continue; - Phmag[i]=xml->getpar127("mag",Phmag[i]); - Phrelbw[i]=xml->getpar127("relbw",Phrelbw[i]); + Pnumstages = xml->getpar127("num_stages", Pnumstages); + Phmagtype = xml->getpar127("harmonic_mag_type", Phmagtype); + Pstart = xml->getpar127("start", Pstart); + + if(xml->enterbranch("HARMONICS")) { + Phmag[0] = 0; + for(int i = 0; i < MAX_SUB_HARMONICS; i++) { + if(xml->enterbranch("HARMONIC", i) == 0) + continue; + Phmag[i] = xml->getpar127("mag", Phmag[i]); + Phrelbw[i] = xml->getpar127("relbw", Phrelbw[i]); xml->exitbranch(); - }; + } xml->exitbranch(); - }; - - if (xml->enterbranch("AMPLITUDE_PARAMETERS")) { - Pstereo=xml->getparbool("stereo",Pstereo); - PVolume=xml->getpar127("volume",PVolume); - PPanning=xml->getpar127("panning",PPanning); - PAmpVelocityScaleFunction=xml->getpar127("velocity_sensing",PAmpVelocityScaleFunction); - if (xml->enterbranch("AMPLITUDE_ENVELOPE")) { + } + + if(xml->enterbranch("AMPLITUDE_PARAMETERS")) { + Pstereo = xml->getparbool("stereo", Pstereo); + PVolume = xml->getpar127("volume", PVolume); + PPanning = xml->getpar127("panning", PPanning); + PAmpVelocityScaleFunction = xml->getpar127("velocity_sensing", + PAmpVelocityScaleFunction); + if(xml->enterbranch("AMPLITUDE_ENVELOPE")) { AmpEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("FREQUENCY_PARAMETERS")) { - Pfixedfreq=xml->getparbool("fixed_freq",Pfixedfreq); - PfixedfreqET=xml->getpar127("fixed_freq_et",PfixedfreqET); + if(xml->enterbranch("FREQUENCY_PARAMETERS")) { + Pfixedfreq = xml->getparbool("fixed_freq", Pfixedfreq); + PfixedfreqET = xml->getpar127("fixed_freq_et", PfixedfreqET); - PDetune=xml->getpar("detune",PDetune,0,16383); - PCoarseDetune=xml->getpar("coarse_detune",PCoarseDetune,0,16383); - PDetuneType=xml->getpar127("detune_type",PDetuneType); + PDetune = xml->getpar("detune", PDetune, 0, 16383); + PCoarseDetune = xml->getpar("coarse_detune", PCoarseDetune, 0, 16383); + PDetuneType = xml->getpar127("detune_type", PDetuneType); - Pbandwidth=xml->getpar127("bandwidth",Pbandwidth); - Pbwscale=xml->getpar127("bandwidth_scale",Pbwscale); + Pbandwidth = xml->getpar127("bandwidth", Pbandwidth); + Pbwscale = xml->getpar127("bandwidth_scale", Pbwscale); - PFreqEnvelopeEnabled=xml->getparbool("freq_envelope_enabled",PFreqEnvelopeEnabled); - if (xml->enterbranch("FREQUENCY_ENVELOPE")) { + PFreqEnvelopeEnabled = xml->getparbool("freq_envelope_enabled", + PFreqEnvelopeEnabled); + if(xml->enterbranch("FREQUENCY_ENVELOPE")) { FreqEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } - PBandWidthEnvelopeEnabled=xml->getparbool("band_width_envelope_enabled",PBandWidthEnvelopeEnabled); - if (xml->enterbranch("BANDWIDTH_ENVELOPE")) { + PBandWidthEnvelopeEnabled = xml->getparbool( + "band_width_envelope_enabled", + PBandWidthEnvelopeEnabled); + if(xml->enterbranch("BANDWIDTH_ENVELOPE")) { BandWidthEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("FILTER_PARAMETERS")) { - PGlobalFilterEnabled=xml->getparbool("enabled",PGlobalFilterEnabled); - if (xml->enterbranch("FILTER")) { + if(xml->enterbranch("FILTER_PARAMETERS")) { + PGlobalFilterEnabled = xml->getparbool("enabled", PGlobalFilterEnabled); + if(xml->enterbranch("FILTER")) { GlobalFilter->getfromXML(xml); xml->exitbranch(); - }; + } - PGlobalFilterVelocityScaleFunction=xml->getpar127("filter_velocity_sensing",PGlobalFilterVelocityScaleFunction); - PGlobalFilterVelocityScale=xml->getpar127("filter_velocity_sensing_amplitude",PGlobalFilterVelocityScale); + PGlobalFilterVelocityScaleFunction = xml->getpar127( + "filter_velocity_sensing", + PGlobalFilterVelocityScaleFunction); + PGlobalFilterVelocityScale = xml->getpar127( + "filter_velocity_sensing_amplitude", + PGlobalFilterVelocityScale); - if (xml->enterbranch("FILTER_ENVELOPE")) { + if(xml->enterbranch("FILTER_ENVELOPE")) { GlobalFilterEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; -}; - - - + } +} diff --git a/src/Params/SUBnoteParameters.h b/src/Params/SUBnoteParameters.h @@ -31,76 +31,74 @@ class SUBnoteParameters:public Presets { -public: - SUBnoteParameters(); - ~SUBnoteParameters(); + public: + SUBnoteParameters(); + ~SUBnoteParameters(); - void add2XML(XMLwrapper *xml); - void defaults(); - void getfromXML(XMLwrapper *xml); + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); - //Parameters - //AMPLITUDE PARAMETRERS - unsigned char Pstereo;//0 for mono,1 for stereo - unsigned char PVolume; - unsigned char PPanning; - unsigned char PAmpVelocityScaleFunction; - EnvelopeParams *AmpEnvelope; + //Parameters + //AMPLITUDE PARAMETRERS + unsigned char Pstereo; //0 for mono,1 for stereo + unsigned char PVolume; + unsigned char PPanning; + unsigned char PAmpVelocityScaleFunction; + EnvelopeParams *AmpEnvelope; - //Frequency Parameters - unsigned short int PDetune; - unsigned short int PCoarseDetune; - unsigned char PDetuneType; - unsigned char PFreqEnvelopeEnabled; - EnvelopeParams *FreqEnvelope; - unsigned char PBandWidthEnvelopeEnabled; - EnvelopeParams *BandWidthEnvelope; + //Frequency Parameters + unsigned short int PDetune; + unsigned short int PCoarseDetune; + unsigned char PDetuneType; + unsigned char PFreqEnvelopeEnabled; + EnvelopeParams *FreqEnvelope; + unsigned char PBandWidthEnvelopeEnabled; + EnvelopeParams *BandWidthEnvelope; - //Filter Parameters (Global) - unsigned char PGlobalFilterEnabled; - FilterParams *GlobalFilter; - unsigned char PGlobalFilterVelocityScale; - unsigned char PGlobalFilterVelocityScaleFunction; - EnvelopeParams *GlobalFilterEnvelope; + //Filter Parameters (Global) + unsigned char PGlobalFilterEnabled; + FilterParams *GlobalFilter; + unsigned char PGlobalFilterVelocityScale; + unsigned char PGlobalFilterVelocityScaleFunction; + EnvelopeParams *GlobalFilterEnvelope; - //Other Parameters + //Other Parameters - //If the base frequency is fixed to 440 Hz - unsigned char Pfixedfreq; + //If the base frequency is fixed to 440 Hz + unsigned char Pfixedfreq; - /* Equal temperate (this is used only if the Pfixedfreq is enabled) - If this parameter is 0, the frequency is fixed (to 440 Hz); - if this parameter is 64, 1 MIDI halftone -> 1 frequency halftone */ - unsigned char PfixedfreqET; + /* Equal temperate (this is used only if the Pfixedfreq is enabled) + If this parameter is 0, the frequency is fixed (to 440 Hz); + if this parameter is 64, 1 MIDI halftone -> 1 frequency halftone */ + unsigned char PfixedfreqET; - //how many times the filters are applied - unsigned char Pnumstages; + //how many times the filters are applied + unsigned char Pnumstages; - //bandwidth - unsigned char Pbandwidth; + //bandwidth + unsigned char Pbandwidth; - //How the magnitudes are computed (0=linear,1=-60dB,2=-60dB) - unsigned char Phmagtype; + //How the magnitudes are computed (0=linear,1=-60dB,2=-60dB) + unsigned char Phmagtype; - //Magnitudes - unsigned char Phmag[MAX_SUB_HARMONICS]; + //Magnitudes + unsigned char Phmag[MAX_SUB_HARMONICS]; - //Relative BandWidth ("64"=1.0) - unsigned char Phrelbw[MAX_SUB_HARMONICS]; + //Relative BandWidth ("64"=1.0) + unsigned char Phrelbw[MAX_SUB_HARMONICS]; - //how much the bandwidth is increased according to lower/higher frequency; 64-default - unsigned char Pbwscale; + //how much the bandwidth is increased according to lower/higher frequency; 64-default + unsigned char Pbwscale; - //how the harmonics start("0"=0,"1"=random,"2"=1) - unsigned char Pstart; + //how the harmonics start("0"=0,"1"=random,"2"=1) + unsigned char Pstart; -private: + private: }; #endif - - diff --git a/src/Samples/AuSample.cpp b/src/Samples/AuSample.cpp @@ -20,9 +20,9 @@ */ #include "AuSample.h" -AuSample::AuSample(int length,REALTYPE fill) - : Sample(length,fill) {} +AuSample::AuSample(int length, REALTYPE fill) + :Sample(length, fill) {} -AuSample::AuSample(int length,const REALTYPE *input) - : Sample(length,input) {} +AuSample::AuSample(int length, const REALTYPE *input) + :Sample(length, input) {} diff --git a/src/Samples/AuSample.h b/src/Samples/AuSample.h @@ -24,13 +24,12 @@ #include "Sample.h" #include "FqSample.h" -class AuSample : public Sample +class AuSample:public Sample { -public: - AuSample(int length,REALTYPE fill=0); - AuSample(int length,const REALTYPE *input); - FqSample getFqSample();/**\todo implement this*/ - + public: + AuSample(int length, REALTYPE fill = 0); + AuSample(int length, const REALTYPE *input); + FqSample getFqSample(); /**\todo implement this*/ }; #endif diff --git a/src/Samples/FqSample.cpp b/src/Samples/FqSample.cpp @@ -20,12 +20,12 @@ */ #include "FqSample.h" -FqSample::FqSample(int length,REALTYPE fill) - :Sample(length,fill) +FqSample::FqSample(int length, REALTYPE fill) + :Sample(length, fill) {} -FqSample::FqSample(int length,const REALTYPE *input) - : Sample(length,input) +FqSample::FqSample(int length, const REALTYPE *input) + :Sample(length, input) {} FqSample::~FqSample() diff --git a/src/Samples/FqSample.h b/src/Samples/FqSample.h @@ -24,14 +24,14 @@ #include "FqSample.h" #include "Sample.h" -class FqSample : public Sample +class FqSample:public Sample { -public: - FqSample(int length,REALTYPE fill=0); - FqSample(int length,const REALTYPE *input); - ~FqSample(); - //FqSample &operator=(const FqSample &smp); - //float *dontuse(){return buffer;}; + public: + FqSample(int length, REALTYPE fill = 0); + FqSample(int length, const REALTYPE *input); + ~FqSample(); + //FqSample &operator=(const FqSample &smp); + //float *dontuse(){return buffer;}; }; #endif diff --git a/src/Samples/Sample.cpp b/src/Samples/Sample.cpp @@ -24,34 +24,35 @@ /**\TODO start using pointer math here as these will be Frequency called * functions throughout the code*/ Sample::Sample(const Sample &smp) - : bufferSize(smp.bufferSize) + :bufferSize(smp.bufferSize) { - buffer=new REALTYPE[bufferSize]; - for (int i=0;i<bufferSize;++i) - *(i+buffer)=*(i+smp.buffer); + buffer = new REALTYPE[bufferSize]; + for(int i = 0; i < bufferSize; ++i) + *(i + buffer) = *(i + smp.buffer); } -Sample::Sample(int length,REALTYPE fill) - : bufferSize(length) +Sample::Sample(int length, REALTYPE fill) + :bufferSize(length) { - if (length<1) - bufferSize=1; - buffer=new REALTYPE[bufferSize]; - for(int i=0;i<bufferSize;++i) - buffer[i]=fill; + if(length < 1) + bufferSize = 1; + buffer = new REALTYPE[bufferSize]; + for(int i = 0; i < bufferSize; ++i) + buffer[i] = fill; } -Sample::Sample(int length,const REALTYPE *input) - : bufferSize(length) +Sample::Sample(int length, const REALTYPE *input) + :bufferSize(length) { - if (length>0) { - buffer=new REALTYPE[length]; - for (int i=0;i<length;++i) - *(buffer+i)=*(input+i); - } else { - buffer=new REALTYPE[1]; - bufferSize=1; - *buffer=0; + if(length > 0) { + buffer = new REALTYPE[length]; + for(int i = 0; i < length; ++i) + *(buffer + i) = *(input + i); + } + else { + buffer = new REALTYPE[1]; + bufferSize = 1; + *buffer = 0; } } @@ -62,58 +63,59 @@ Sample::~Sample() void Sample::clear() { - for (int i=0;i<bufferSize;++i) - *(i+buffer)=0; + for(int i = 0; i < bufferSize; ++i) + *(i + buffer) = 0; } void Sample::operator=(const Sample &smp) { /**\todo rewrite to be less repetitive*/ - if (bufferSize==smp.bufferSize) { - for (int i=0;i<bufferSize;++i) - *(i+buffer)=*(i+smp.buffer); - } else { + if(bufferSize == smp.bufferSize) + for(int i = 0; i < bufferSize; ++i) + *(i + buffer) = *(i + smp.buffer); + else { delete[] buffer; - buffer=new REALTYPE[smp.bufferSize]; - bufferSize=smp.bufferSize; - for (int i=0;i<bufferSize;++i) - *(i+buffer)=*(i+smp.buffer); + buffer = new REALTYPE[smp.bufferSize]; + bufferSize = smp.bufferSize; + for(int i = 0; i < bufferSize; ++i) + *(i + buffer) = *(i + smp.buffer); } } -bool Sample::operator==(const Sample &smp)const +bool Sample::operator==(const Sample &smp) const { - if(this->bufferSize!=smp.bufferSize) + if(this->bufferSize != smp.bufferSize) return false; - for(int i=0;i<bufferSize;++i) - if(this->buffer[i]!=smp.buffer[i]) + for(int i = 0; i < bufferSize; ++i) + if(this->buffer[i] != smp.buffer[i]) return false; return true; } -REALTYPE Sample::max()const +REALTYPE Sample::max() const { - REALTYPE max=-1500;//a good low considering that samples should store values -1.0 to 1.0 - for(int i=0;i<bufferSize;++i) - if(buffer[i]>max) - max=buffer[i]; + REALTYPE max = -1500; //a good low considering that samples should store values -1.0 to 1.0 + for(int i = 0; i < bufferSize; ++i) + if(buffer[i] > max) + max = buffer[i]; return max; } -REALTYPE Sample::min()const +REALTYPE Sample::min() const { - REALTYPE min=1500;//a good high considering that samples should store values -1.0 to 1.0 - for(int i=0;i<bufferSize;++i) - if(buffer[i]<min) - min=buffer[i]; + REALTYPE min = 1500; //a good high considering that samples should store values -1.0 to 1.0 + for(int i = 0; i < bufferSize; ++i) + if(buffer[i] < min) + min = buffer[i]; return min; } -REALTYPE Sample::absMax()const +REALTYPE Sample::absMax() const { - REALTYPE max=0; - for(int i=0;i<bufferSize;++i) - if(fabs(buffer[i])>max) - max=fabs(buffer[i]); + REALTYPE max = 0; + for(int i = 0; i < bufferSize; ++i) + if(fabs(buffer[i]) > max) + max = fabs(buffer[i]); return max; } + diff --git a/src/Samples/Sample.h b/src/Samples/Sample.h @@ -26,45 +26,43 @@ */ class Sample { -public: - Sample(const Sample &smp); - Sample(int length,REALTYPE fill=0); - Sample(int length,const REALTYPE *fill); - ~Sample(); - /**Fills the buffer with zeros*/ - void clear(); - /**States the size of the buffer - * @return the size of the buffer*/ - int size() const { - return bufferSize; - }; - /**Provides the indexing operator for non const Samples*/ - REALTYPE &operator[](int index) { - return *(buffer+index%bufferSize); - }; - /**Provides the indexing operator for const Samples*/ - const REALTYPE &operator[](int index)const { - return *(buffer+index%bufferSize); - }; - /**Provides the assignment operator*/ - void operator=(const Sample &smp); - /**Provides the == operator*/ - bool operator==(const Sample &smp)const; - /**Provides direct access to the buffer to allow for transition - * - * This method is like c_str() from the string class and should be used - * sparingly*/ - const REALTYPE *c_buf() { - return buffer; - }; - REALTYPE max()const; - REALTYPE min()const; - REALTYPE absMax()const; -private: - int bufferSize; - float *buffer; - - + public: + Sample(const Sample &smp); + Sample(int length, REALTYPE fill = 0); + Sample(int length, const REALTYPE *fill); + ~Sample(); + /**Fills the buffer with zeros*/ + void clear(); + /**States the size of the buffer + * @return the size of the buffer*/ + int size() const { + return bufferSize; + } + /**Provides the indexing operator for non const Samples*/ + REALTYPE &operator[](int index) { + return *(buffer + index % bufferSize); + } + /**Provides the indexing operator for const Samples*/ + const REALTYPE &operator[](int index) const { + return *(buffer + index % bufferSize); + } + /**Provides the assignment operator*/ + void operator=(const Sample &smp); + /**Provides the == operator*/ + bool operator==(const Sample &smp) const; + /**Provides direct access to the buffer to allow for transition + * + * This method is like c_str() from the string class and should be used + * sparingly*/ + const REALTYPE *c_buf() { + return buffer; + } + REALTYPE max() const; + REALTYPE min() const; + REALTYPE absMax() const; + private: + int bufferSize; + float *buffer; }; #endif diff --git a/src/Seq/MIDIEvents.cpp b/src/Seq/MIDIEvents.cpp @@ -25,68 +25,69 @@ #include <stdio.h> MIDIEvents::MIDIEvents() -{ -}; +{} MIDIEvents::~MIDIEvents() -{ -}; +{} /************** Track stuff ***************/ -void MIDIEvents::writeevent(list *l,event *ev) +void MIDIEvents::writeevent(list *l, event *ev) { - listpos *tmp=new listpos; - tmp->next=NULL; - tmp->ev=*ev; - if (l->current!=NULL) l->current->next=tmp; - else l->first=tmp; - l->current=tmp; + listpos *tmp = new listpos; + tmp->next = NULL; + tmp->ev = *ev; + if(l->current != NULL) + l->current->next = tmp; + else + l->first = tmp; + l->current = tmp; // printf("Wx%x ",(int) l->current); // printf("-> %d \n",l->current->ev.deltatime); l->size++; -}; +} -void MIDIEvents::readevent(list *l,event *ev) +void MIDIEvents::readevent(list *l, event *ev) { - if (l->current==NULL) { - ev->type=-1; + if(l->current == NULL) { + ev->type = -1; return; - }; - *ev=l->current->ev; - l->current=l->current->next; + } + *ev = l->current->ev; + l->current = l->current->next; //test - if (l->current!=NULL) { + if(l->current != NULL) { // ev->deltatime=10000; // printf("Rx%d\n",l->current->ev.deltatime); // printf("Rx%x ",(int) l->current); // printf("-> %d (next=%x) \n",(int)l->current->ev.deltatime,(int)l->current->next); - }; - -}; + } +} void MIDIEvents::rewindlist(list *l) { - l->current=l->first; -}; + l->current = l->first; +} void MIDIEvents::deletelist(list *l) { - l->current=l->first; - if (l->current==NULL) return; - while (l->current->next!=NULL) { - listpos *tmp=l->current; - l->current=l->current->next; - delete(tmp); - }; + l->current = l->first; + if(l->current == NULL) + return; + while(l->current->next != NULL) { + listpos *tmp = l->current; + l->current = l->current->next; + delete (tmp); + } deletelistreference(l); -}; +} void MIDIEvents::deletelistreference(list *l) { - l->current=l->first=NULL; - l->size=0; - l->length=0.0; -}; + l->current = l->first = NULL; + l->size = 0; + l->length = 0.0; +} + diff --git a/src/Seq/MIDIEvents.h b/src/Seq/MIDIEvents.h @@ -31,39 +31,38 @@ class MIDIEvents { friend class MIDIFile; -public: - MIDIEvents(); - ~MIDIEvents(); + public: + MIDIEvents(); + ~MIDIEvents(); -protected: + protected: - /* Events */ - struct event { - int deltatime; - int channel;//on what midi channel is - int type,par1,par2;//type=1 for note, type=2 for controller, type=255 for time messages - } tmpevent; - struct listpos { - event ev; - struct listpos *next; - }; - struct list { - listpos *first,*current; - int size;//how many events are - double length;//in seconds - }; - struct { - list track;//the stored track - list record;//the track being "recorded" from midi - } miditrack[NUM_MIDI_TRACKS]; + /* Events */ + struct event { + int deltatime; + int channel; //on what midi channel is + int type, par1, par2; //type=1 for note, type=2 for controller, type=255 for time messages + } tmpevent; + struct listpos { + event ev; + struct listpos *next; + }; + struct list { + listpos *first, *current; + int size; //how many events are + double length; //in seconds + }; + struct { + list track; //the stored track + list record; //the track being "recorded" from midi + } miditrack[NUM_MIDI_TRACKS]; - void writeevent(list *l,event *ev); - void readevent(list *l,event *ev); - - void rewindlist(list *l); - void deletelist(list *l); - void deletelistreference(list *l); + void writeevent(list *l, event *ev); + void readevent(list *l, event *ev); + void rewindlist(list *l); + void deletelist(list *l); + void deletelistreference(list *l); }; #endif diff --git a/src/Seq/MIDIFile.cpp b/src/Seq/MIDIFile.cpp @@ -27,382 +27,395 @@ MIDIFile::MIDIFile() { - midifile=NULL; - midifilesize=0; - midifilek=0; - midieof=false; - me=NULL; -}; + midifile = NULL; + midifilesize = 0; + midifilek = 0; + midieof = false; + me = NULL; +} MIDIFile::~MIDIFile() { clearmidifile(); -}; +} int MIDIFile::loadfile(const char *filename) { clearmidifile(); - FILE *file=fopen(filename,"r"); - if (file==NULL) return(-1); + FILE *file = fopen(filename, "r"); + if(file == NULL) + return -1; char header[4]; - ZERO(header,4); - fread(header,4,1,file); + ZERO(header, 4); + fread(header, 4, 1, file); //test to see if this a midi file - if ((header[0]!='M')||(header[1]!='T')||(header[2]!='h')||(header[3]!='d')) { + if((header[0] != 'M') || (header[1] != 'T') || (header[2] != 'h') + || (header[3] != 'd')) { fclose(file); - return(-1); - }; + return -1; + } //get the filesize - fseek(file,0,SEEK_END); - midifilesize=ftell(file); + fseek(file, 0, SEEK_END); + midifilesize = ftell(file); rewind(file); - midifile=new unsigned char[midifilesize]; - ZERO(midifile,midifilesize); - fread(midifile,midifilesize,1,file); + midifile = new unsigned char[midifilesize]; + ZERO(midifile, midifilesize); + fread(midifile, midifilesize, 1, file); fclose(file); // for (int i=0;i<midifilesize;i++) printf("%2x ",midifile[i]); // printf("\n"); - return(0); -}; + return 0; +} int MIDIFile::parsemidifile(MIDIEvents *me_) { - this->me=me_; + this->me = me_; //read the header - int chunk=getint32();//MThd - if (chunk!=0x4d546864) return(-1); - int size=getint32(); - if (size!=6) return(-1);//header is always 6 bytes long + int chunk = getint32(); //MThd + if(chunk != 0x4d546864) + return -1; + int size = getint32(); + if(size != 6) + return -1; //header is always 6 bytes long - int format=getint16(); - printf("format %d\n",format); + int format = getint16(); + printf("format %d\n", format); - int ntracks=getint16();//this is always 1 if the format is "0" - printf("ntracks %d\n",ntracks); + int ntracks = getint16(); //this is always 1 if the format is "0" + printf("ntracks %d\n", ntracks); - int division=getint16(); - printf("division %d\n",division); - if (division>=0) {//delta time units in each a quater note + int division = getint16(); + printf("division %d\n", division); + if(division >= 0) { //delta time units in each a quater note // tick=???; - } else {//SMPTE (frames/second and ticks/frame) - printf("ERROR:in MIDIFile.C::parsemidifile() - SMPTE not implemented yet."); - }; + } + else //SMPTE (frames/second and ticks/frame) + printf( + "ERROR:in MIDIFile.C::parsemidifile() - SMPTE not implemented yet."); + ; - if (ntracks>=NUM_MIDI_TRACKS) ntracks=NUM_MIDI_TRACKS-1; + if(ntracks >= NUM_MIDI_TRACKS) + ntracks = NUM_MIDI_TRACKS - 1; - for (int n=0;n<ntracks;n++) { - if (parsetrack(n)<0) { + for(int n = 0; n < ntracks; n++) { + if(parsetrack(n) < 0) { clearmidifile(); - return(-1); - }; - }; + return -1; + } + } - printf("\n\nCURRENT File position is = 0x%x\n",midifilek); + printf("\n\nCURRENT File position is = 0x%x\n", midifilek); printf("\nMIDI file succesfully parsed.\n"); // printf("\n0x%x\n",getbyte()); - this->me=NULL; - return(0); -}; + this->me = NULL; + return 0; +} //private members int MIDIFile::parsetrack(int ntrack) { - printf("\n--==*Reading track %d **==--\n",ntrack); + printf("\n--==*Reading track %d **==--\n", ntrack); - int chunk=getint32();//MTrk - if (chunk!=0x4d54726b) return(-1); + int chunk = getint32(); //MTrk + if(chunk != 0x4d54726b) + return -1; - int size=getint32(); - printf("size = %d\n",size); + int size = getint32(); + printf("size = %d\n", size); - int oldmidifilek=midifilek; + int oldmidifilek = midifilek; - unsigned char lastmsg=0; - unsigned int dt=0; + unsigned char lastmsg = 0; + unsigned int dt = 0; - while (!midieof) { - unsigned int msgdeltatime=getvarint32(); + while(!midieof) { + unsigned int msgdeltatime = getvarint32(); /// printf("MSGDELTATIME = %d\n",msgdeltatime); // dt+=msgdeltatime; - int msg=peekbyte(); + int msg = peekbyte(); /// printf("raw msg=0x%x ",msg); - if (msg<0x80) { - msg=lastmsg; - } else { - lastmsg=msg; + if(msg < 0x80) + msg = lastmsg; + else { + lastmsg = msg; getbyte(); - }; + } /// printf("msg=0x%x\n",msg); // dt+=msgdeltatime; add_dt(ntrack, msgdeltatime); - unsigned int mtype,mlength; + unsigned int mtype, mlength; - switch (msg) { - case 0x80 ... 0x8f://note on off - parsenoteoff(ntrack,msg & 0x0f,dt); - dt=0; + switch(msg) { + case 0x80 ... 0x8f: //note on off + parsenoteoff(ntrack, msg & 0x0f, dt); + dt = 0; break; - case 0x90 ... 0x9f://note on (or note off) - parsenoteon(ntrack,msg & 0x0f,dt); - dt=0; + case 0x90 ... 0x9f: //note on (or note off) + parsenoteon(ntrack, msg & 0x0f, dt); + dt = 0; break; - case 0xa0 ... 0xaf://aftertouch - ignored + case 0xa0 ... 0xaf: //aftertouch - ignored skipnbytes(2); break; - case 0xb0 ... 0xbf://control change - parsecontrolchange(ntrack,msg & 0x0f,dt); - dt=0; + case 0xb0 ... 0xbf: //control change + parsecontrolchange(ntrack, msg & 0x0f, dt); + dt = 0; break; - case 0xc0 ... 0xcf://program change - ignored + case 0xc0 ... 0xcf: //program change - ignored skipnbytes(1); break; - case 0xd0 ... 0xdf://channel pressure - ignored + case 0xd0 ... 0xdf: //channel pressure - ignored skipnbytes(1); break; - case 0xe0 ... 0xef://channel mode messages + case 0xe0 ... 0xef: //channel mode messages skipnbytes(2); break; - case 0xf0://sysex - ignored - while (getbyte()!=0xf7) { - if (midieof) break; - }; + case 0xf0: //sysex - ignored + while(getbyte() != 0xf7) { + if(midieof) + break; + } break; - case 0xf7://sysex (another type) - ignored + case 0xf7: //sysex (another type) - ignored skipnbytes(getvarint32()); break; - case 0xff://meta-event - mtype=getbyte(); - mlength=getbyte(); - parsemetaevent(mtype,mlength); + case 0xff: //meta-event + mtype = getbyte(); + mlength = getbyte(); + parsemetaevent(mtype, mlength); break; default: getbyte(); - printf("UNKNOWN message! 0x%x\n",msg); - return(-1); + printf("UNKNOWN message! 0x%x\n", msg); + return -1; break; - }; + } - if (midieof) return(-1); + if(midieof) + return -1; - if ((midifilek-oldmidifilek)==size) break; - else if ((midifilek-oldmidifilek)>size) return(-1); + if((midifilek - oldmidifilek) == size) + break; + else + if((midifilek - oldmidifilek) > size) + return -1; // if (size!=6) return(-1);//header is always 6 bytes long - }; + } printf("End Track\n\n"); - return(0); -}; + return 0; +} -void MIDIFile::parsenoteoff(char ntrack,char chan,unsigned int dt) +void MIDIFile::parsenoteoff(char ntrack, char chan, unsigned int dt) { unsigned char note; - note=getbyte(); + note = getbyte(); - unsigned char noteoff_velocity=getbyte();//unused by zynaddsubfx - noteoff_velocity=0; - if (chan>=NUM_MIDI_CHANNELS) return; + unsigned char noteoff_velocity = getbyte(); //unused by zynaddsubfx + noteoff_velocity = 0; + if(chan >= NUM_MIDI_CHANNELS) + return; - me->tmpevent.deltatime=convertdt(dt); - me->tmpevent.type=1; - me->tmpevent.par1=note; - me->tmpevent.par2=0; - me->tmpevent.channel=chan; + me->tmpevent.deltatime = convertdt(dt); + me->tmpevent.type = 1; + me->tmpevent.par1 = note; + me->tmpevent.par2 = 0; + me->tmpevent.channel = chan; - printf("Note off:%d \n",note); + printf("Note off:%d \n", note); ///test // ntrack=0; - me->writeevent(&me->miditrack[(int)ntrack].record,&me->tmpevent); + me->writeevent(&me->miditrack[(int)ntrack].record, &me->tmpevent); +} -}; - -void MIDIFile::parsenoteon(char ntrack,char chan,unsigned int dt) +void MIDIFile::parsenoteon(char ntrack, char chan, unsigned int dt) { - unsigned char note,vel; - note=getbyte(); - vel=getbyte(); + unsigned char note, vel; + note = getbyte(); + vel = getbyte(); // printf("ntrack=%d\n",ntrack); - printf("[dt %d ] Note on:%d %d\n",dt,note,vel); - - if (chan>=NUM_MIDI_CHANNELS) return; - - me->tmpevent.deltatime=convertdt(dt); - me->tmpevent.type=1; - me->tmpevent.par1=note; - me->tmpevent.par2=vel; - me->tmpevent.channel=chan; - me->writeevent(&me->miditrack[(int)ntrack].record,&me->tmpevent); - + printf("[dt %d ] Note on:%d %d\n", dt, note, vel); + if(chan >= NUM_MIDI_CHANNELS) + return; -}; + me->tmpevent.deltatime = convertdt(dt); + me->tmpevent.type = 1; + me->tmpevent.par1 = note; + me->tmpevent.par2 = vel; + me->tmpevent.channel = chan; + me->writeevent(&me->miditrack[(int)ntrack].record, &me->tmpevent); +} -void MIDIFile::parsecontrolchange(char ntrack,char chan,unsigned int dt) +void MIDIFile::parsecontrolchange(char ntrack, char chan, unsigned int dt) { - unsigned char control,value; - control=getbyte(); - value=getbyte(); + unsigned char control, value; + control = getbyte(); + value = getbyte(); - if (chan>=NUM_MIDI_CHANNELS) return; + if(chan >= NUM_MIDI_CHANNELS) + return; - printf("[dt %d] Control change:%d %d\n",dt,control,value); + printf("[dt %d] Control change:%d %d\n", dt, control, value); - me->tmpevent.deltatime=convertdt(dt); - me->tmpevent.type=2; - me->tmpevent.par1=control;//???????????? ma uit la Sequencer::recordnote() din varianele vechi de zyn - me->tmpevent.par2=value; - me->tmpevent.channel=chan; - me->writeevent(&me->miditrack[(int)ntrack].record,&me->tmpevent); + me->tmpevent.deltatime = convertdt(dt); + me->tmpevent.type = 2; + me->tmpevent.par1 = control; //???????????? ma uit la Sequencer::recordnote() din varianele vechi de zyn + me->tmpevent.par2 = value; + me->tmpevent.channel = chan; + me->writeevent(&me->miditrack[(int)ntrack].record, &me->tmpevent); +} -}; - -void MIDIFile::parsepitchwheel(char ntrack,char chan, unsigned int dt) +void MIDIFile::parsepitchwheel(char ntrack, char chan, unsigned int dt) { - unsigned char valhi,vallo; - vallo=getbyte(); - valhi=getbyte(); - - if (chan>=NUM_MIDI_CHANNELS) return; + unsigned char valhi, vallo; + vallo = getbyte(); + valhi = getbyte(); - int value=(int)valhi*128+vallo; + if(chan >= NUM_MIDI_CHANNELS) + return; - printf("[dt %d] Pitch wheel:%d\n",dt,value); + int value = (int)valhi * 128 + vallo; -}; + printf("[dt %d] Pitch wheel:%d\n", dt, value); +} -void MIDIFile::parsemetaevent(unsigned char mtype,unsigned char mlength) +void MIDIFile::parsemetaevent(unsigned char mtype, unsigned char mlength) { - int oldmidifilek=midifilek; - printf("meta-event type=0x%x length=%d\n",mtype,mlength); + int oldmidifilek = midifilek; + printf("meta-event type=0x%x length=%d\n", mtype, mlength); - midifilek=oldmidifilek+mlength; - -}; + midifilek = oldmidifilek + mlength; +} void MIDIFile::add_dt(char ntrack, unsigned int dt) { - me->tmpevent.deltatime=convertdt(dt); - me->tmpevent.type=255; - me->tmpevent.par1=0; - me->tmpevent.par2=0; - me->tmpevent.channel=0; - me->writeevent(&me->miditrack[(int)ntrack].record,&me->tmpevent); -}; + me->tmpevent.deltatime = convertdt(dt); + me->tmpevent.type = 255; + me->tmpevent.par1 = 0; + me->tmpevent.par2 = 0; + me->tmpevent.channel = 0; + me->writeevent(&me->miditrack[(int)ntrack].record, &me->tmpevent); +} unsigned int MIDIFile::convertdt(unsigned int dt) { - double result=dt; - printf("DT=%d\n",dt); + double result = dt; + printf("DT=%d\n", dt); - return((int) (result*15.0)); -}; + return (int) (result * 15.0); +} void MIDIFile::clearmidifile() { - if (midifile!=NULL) delete(midifile); - midifile=NULL; - midifilesize=0; - midifilek=0; - midieof=false; - data.tick=0.05; -}; + if(midifile != NULL) + delete (midifile); + midifile = NULL; + midifilesize = 0; + midifilek = 0; + midieof = false; + data.tick = 0.05; +} unsigned char MIDIFile::getbyte() { - if (midifilek>=midifilesize) { - midieof=true; - return(0); - }; + if(midifilek >= midifilesize) { + midieof = true; + return 0; + } /// printf("(%d) ",midifile[midifilek]); - return(midifile[midifilek++]); -}; + return midifile[midifilek++]; +} unsigned char MIDIFile::peekbyte() { - if (midifilek>=midifilesize) { - midieof=true; - return(0); - }; - return(midifile[midifilek]); -}; + if(midifilek >= midifilesize) { + midieof = true; + return 0; + } + return midifile[midifilek]; +} unsigned int MIDIFile::getint32() { - unsigned int result=0; - for (int i=0;i<4;i++) { - result=result*256+getbyte(); - }; - if (midieof) result=0; - return(result); -}; + unsigned int result = 0; + for(int i = 0; i < 4; i++) + result = result * 256 + getbyte(); + ; + if(midieof) + result = 0; + return result; +} unsigned short int MIDIFile::getint16() { - unsigned short int result=0; - for (int i=0;i<2;i++) { - result=result*256+getbyte(); - }; - if (midieof) result=0; - return(result); -}; + unsigned short int result = 0; + for(int i = 0; i < 2; i++) + result = result * 256 + getbyte(); + ; + if(midieof) + result = 0; + return result; +} unsigned int MIDIFile::getvarint32() { - unsigned long result=0; + unsigned long result = 0; unsigned char b; /// printf("\n[start]"); - if ((result = getbyte()) & 0x80) { + if((result = getbyte()) & 0x80) { result &= 0x7f; - do { - b=getbyte(); + do { + b = getbyte(); result = (result << 7) + (b & 0x7f); - } while (b & 0x80); + } while(b & 0x80); } /// printf("[end - result= %d]\n",result); return result; -}; +} void MIDIFile::skipnbytes(int n) { - midifilek+=n; - if (midifilek>=midifilesize) { - midifilek=midifilesize-1; - midieof=true; - }; -}; + midifilek += n; + if(midifilek >= midifilesize) { + midifilek = midifilesize - 1; + midieof = true; + } +} diff --git a/src/Seq/MIDIFile.h b/src/Seq/MIDIFile.h @@ -29,66 +29,64 @@ /**MIDI file loader*/ class MIDIFile { -public: - MIDIFile(); - ~MIDIFile(); + public: + MIDIFile(); + ~MIDIFile(); - /**Loads the given file - * @param filename The name of the file to load - * @return -1 if there is an error, otherwise 0*/ - int loadfile(const char *filename); + /**Loads the given file + * @param filename The name of the file to load + * @return -1 if there is an error, otherwise 0*/ + int loadfile(const char *filename); - //returns -1 if there is an error, otherwise 0 - int parsemidifile(MIDIEvents *me_); + //returns -1 if there is an error, otherwise 0 + int parsemidifile(MIDIEvents *me_); -private: - MIDIEvents *me; + private: + MIDIEvents *me; - unsigned char *midifile; - int midifilesize,midifilek; - bool midieof; + unsigned char *midifile; + int midifilesize, midifilek; + bool midieof; - //returns -1 if there is an error, otherwise 0 - int parsetrack(int ntrack); + //returns -1 if there is an error, otherwise 0 + int parsetrack(int ntrack); - void parsenoteoff(char ntrack,char chan,unsigned int dt); - void parsenoteon(char ntrack,char chan,unsigned int dt); - void parsecontrolchange(char ntrack,char chan,unsigned int dt); - void parsepitchwheel(char ntrack,char chan, unsigned int dt); - void parsemetaevent(unsigned char mtype,unsigned char mlength); + void parsenoteoff(char ntrack, char chan, unsigned int dt); + void parsenoteon(char ntrack, char chan, unsigned int dt); + void parsecontrolchange(char ntrack, char chan, unsigned int dt); + void parsepitchwheel(char ntrack, char chan, unsigned int dt); + void parsemetaevent(unsigned char mtype, unsigned char mlength); - void add_dt(char ntrack, unsigned int dt); + void add_dt(char ntrack, unsigned int dt); - void clearmidifile(); + void clearmidifile(); - //convert the delta-time to internal format - unsigned int convertdt(unsigned int dt); + //convert the delta-time to internal format + unsigned int convertdt(unsigned int dt); - /* Low Level MIDIfile functions */ + /* Low Level MIDIfile functions */ - //get a byte from the midifile - unsigned char getbyte(); + //get a byte from the midifile + unsigned char getbyte(); - //peek the current byte from the midifile - unsigned char peekbyte(); + //peek the current byte from the midifile + unsigned char peekbyte(); - //get a set of 4 bytes from the midifile - unsigned int getint32(); + //get a set of 4 bytes from the midifile + unsigned int getint32(); - //get a word of 2 bytes from the midifile - unsigned short int getint16(); + //get a word of 2 bytes from the midifile + unsigned short int getint16(); - //read a variable length quantity - unsigned int getvarint32(); + //read a variable length quantity + unsigned int getvarint32(); - //skip some bytes - void skipnbytes(int n); - - struct { - double tick;//how many seconds one tick has - - }data; + //skip some bytes + void skipnbytes(int n); + struct { + double tick; //how many seconds one tick has + } data; }; #endif diff --git a/src/Seq/Sequencer.cpp b/src/Seq/Sequencer.cpp @@ -33,76 +33,85 @@ Sequencer::Sequencer() { - play=0; - for (int i=0;i<NUM_MIDI_TRACKS;i++) { - miditrack[i].track.first=NULL; - miditrack[i].track.current=NULL; - miditrack[i].track.size=0; - miditrack[i].track.length=0.0; - miditrack[i].record.first=NULL; - miditrack[i].record.current=NULL; - miditrack[i].record.size=0; - miditrack[i].record.length=0.0; - - nextevent[i].time=0.0; + play = 0; + for(int i = 0; i < NUM_MIDI_TRACKS; i++) { + miditrack[i].track.first = NULL; + miditrack[i].track.current = NULL; + miditrack[i].track.size = 0; + miditrack[i].track.length = 0.0; + miditrack[i].record.first = NULL; + miditrack[i].record.current = NULL; + miditrack[i].record.size = 0; + miditrack[i].record.length = 0.0; + + nextevent[i].time = 0.0; resettime(&playtime[i]); - }; + } setplayspeed(0); -}; +} Sequencer::~Sequencer() { - for (int i=0;i<NUM_MIDI_TRACKS;i++) { + for(int i = 0; i < NUM_MIDI_TRACKS; i++) { deletelist(&miditrack[i].track); deletelist(&miditrack[i].record); - }; -}; + } +} int Sequencer::importmidifile(const char *filename) { - if (midifile.loadfile(filename)<0) return(-1); + if(midifile.loadfile(filename) < 0) + return -1; - for (int i=0;i<NUM_MIDI_TRACKS;i++) { + for(int i = 0; i < NUM_MIDI_TRACKS; i++) deletelist(&miditrack[i].record); - }; - if (midifile.parsemidifile(this)<0) return(-1); + ; + if(midifile.parsemidifile(this) < 0) + return -1; //copy the "record" track to the main track - for (int i=0;i<NUM_MIDI_TRACKS;i++) { + for(int i = 0; i < NUM_MIDI_TRACKS; i++) { deletelist(&miditrack[i].track); - miditrack[i].track=miditrack[i].record; + miditrack[i].track = miditrack[i].record; deletelistreference(&miditrack[i].record); - }; - return(0); -}; + } + return 0; +} void Sequencer::startplay() { - if (play!=0) return; - for (int i=0;i<NUM_MIDI_TRACKS;i++) resettime(&playtime[i]); + if(play != 0) + return; + for(int i = 0; i < NUM_MIDI_TRACKS; i++) + resettime(&playtime[i]); - for (int i=0;i<NUM_MIDI_TRACKS;i++) { + for(int i = 0; i < NUM_MIDI_TRACKS; i++) rewindlist(&miditrack[i].track); - }; - play=1; - -}; + ; + play = 1; +} void Sequencer::stopplay() { - if (play==0) return; - play=0; -}; + if(play == 0) + return; + play = 0; +} // ************ Player stuff *************** -int Sequencer::getevent(char ntrack,int *midich, int *type,int *par1, int *par2) +int Sequencer::getevent(char ntrack, + int *midich, + int *type, + int *par1, + int *par2) { - *type=0; - if (play==0) return(-1); + *type = 0; + if(play == 0) + return -1; //test // if (ntrack!=0) return(-1); @@ -111,65 +120,71 @@ int Sequencer::getevent(char ntrack,int *midich, int *type,int *par1, int *par2) // printf("%g %g\n",nextevent[ntrack].time,playtime[ntrack].abs); - if (nextevent[(int)ntrack].time<playtime[(int)ntrack].abs) readevent(&miditrack[(int)ntrack].track,&nextevent[(int)ntrack].ev); - else return(-1); - if (nextevent[(int)ntrack].ev.type==-1) return(-1); + if(nextevent[(int)ntrack].time < playtime[(int)ntrack].abs) + readevent(&miditrack[(int)ntrack].track, &nextevent[(int)ntrack].ev); + else + return -1; + if(nextevent[(int)ntrack].ev.type == -1) + return -1; // printf("********************************\n"); //sa pun aici o protectie. a.i. daca distanta dintre timpul curent si eveliment e prea mare (>1sec) sa elimin nota - if (ntrack==1) printf("_ %f %.2f (%d)\n",nextevent[(int)ntrack].time,playtime[(int)ntrack].abs,nextevent[(int)ntrack].ev.par2); + if(ntrack == 1) + printf("_ %f %.2f (%d)\n", nextevent[(int)ntrack].time, + playtime[(int)ntrack].abs, nextevent[(int)ntrack].ev.par2); - *type=nextevent[(int)ntrack].ev.type; - *par1=nextevent[(int)ntrack].ev.par1; - *par2=nextevent[(int)ntrack].ev.par2; - *midich=nextevent[(int)ntrack].ev.channel; + *type = nextevent[(int)ntrack].ev.type; + *par1 = nextevent[(int)ntrack].ev.par1; + *par2 = nextevent[(int)ntrack].ev.par2; + *midich = nextevent[(int)ntrack].ev.channel; - double dt=nextevent[(int)ntrack].ev.deltatime*0.0001*realplayspeed; - printf("zzzzzzzzzzzzzz[%d] %d\n",ntrack,nextevent[(int)ntrack].ev.deltatime); - nextevent[(int)ntrack].time+=dt; + double dt = nextevent[(int)ntrack].ev.deltatime * 0.0001 * realplayspeed; + printf("zzzzzzzzzzzzzz[%d] %d\n", + ntrack, + nextevent[(int)ntrack].ev.deltatime); + nextevent[(int)ntrack].time += dt; // printf("%f - %d %d \n",nextevent[ntrack].time,par1,par2); - return(0);//?? sau 1 -}; + return 0; //?? sau 1 +} /************** Timer stuff ***************/ void Sequencer::resettime(timestruct *t) { - t->abs=0.0; - t->rel=0.0; + t->abs = 0.0; + t->rel = 0.0; timeval tval; - t->last=0.0; + t->last = 0.0; #ifndef OS_WINDOWS - if (gettimeofday(&tval,NULL)==0) - t->last=tval.tv_sec+tval.tv_usec*0.000001; + if(gettimeofday(&tval, NULL) == 0) + t->last = tval.tv_sec + tval.tv_usec * 0.000001; #endif - -}; +} void Sequencer::updatecounter(timestruct *t) { timeval tval; - double current=0.0; + double current = 0.0; #ifndef OS_WINDOWS - if (gettimeofday(&tval,NULL)==0) - current=tval.tv_sec+tval.tv_usec*0.000001; + if(gettimeofday(&tval, NULL) == 0) + current = tval.tv_sec + tval.tv_usec * 0.000001; #endif - t->rel=current - t->last; - t->abs+=t->rel; - t->last=current; + t->rel = current - t->last; + t->abs += t->rel; + t->last = current; // printf("%f %f %f\n",t->last,t->abs,t->rel); -}; +} void Sequencer::setplayspeed(int speed) { - playspeed=speed; - realplayspeed=pow(10.0,speed/128.0); -}; + playspeed = speed; + realplayspeed = pow(10.0, speed / 128.0); +} diff --git a/src/Seq/Sequencer.h b/src/Seq/Sequencer.h @@ -30,61 +30,60 @@ * \todo restructure some of this code*/ class Sequencer:public MIDIEvents { -public: - /**Constructor*/ - Sequencer(); - /**Destructor*/ - ~Sequencer(); + public: + /**Constructor*/ + Sequencer(); + /**Destructor*/ + ~Sequencer(); - //these functions are called by the master and are ignored if the recorder/player are stopped - void recordnote(char chan, char note, char vel); - void recordcontroller(char chan,unsigned int type,int par); + //these functions are called by the master and are ignored if the recorder/player are stopped + void recordnote(char chan, char note, char vel); + void recordcontroller(char chan, unsigned int type, int par); - /**Gets an event \todo better description - * - * this is only for player - * @return 1 if this must be called at least once more - * 0 if there are no more notes for the current time - * -1 if there are no notes*/ - int getevent(char ntrack, int *midich,int *type,int *par1, int *par2); + /**Gets an event \todo better description + * + * this is only for player + * @return 1 if this must be called at least once more + * 0 if there are no more notes for the current time + * -1 if there are no notes*/ + int getevent(char ntrack, int *midich, int *type, int *par1, int *par2); - /**Imports a given midifile - * @return 0 if ok or -1 if there is a error loading file*/ - int importmidifile(const char *filename); + /**Imports a given midifile + * @return 0 if ok or -1 if there is a error loading file*/ + int importmidifile(const char *filename); - void startplay(); - void stopplay(); + void startplay(); + void stopplay(); - int play; - int playspeed;//viteza de rulare (0.1x-10x), 0=1.0x, 128=10x - void setplayspeed(int speed); + int play; + int playspeed; //viteza de rulare (0.1x-10x), 0=1.0x, 128=10x + void setplayspeed(int speed); -private: + private: - MIDIFile midifile; + MIDIFile midifile; - /* Timer */ - struct timestruct { - double abs;//the time from the begining of the track - double rel;//the time difference between the last and the current event - double last;//the time of the last event (absolute, since 1 Jan 1970) - //these must be double, because the float's precision is too low - //and all these represent the time in seconds - } playtime[NUM_MIDI_TRACKS]; + /* Timer */ + struct timestruct { + double abs; //the time from the begining of the track + double rel; //the time difference between the last and the current event + double last; //the time of the last event (absolute, since 1 Jan 1970) + //these must be double, because the float's precision is too low + //and all these represent the time in seconds + } playtime[NUM_MIDI_TRACKS]; - void resettime(timestruct *t); - void updatecounter(timestruct *t);//this updates the timer values + void resettime(timestruct *t); + void updatecounter(timestruct *t); //this updates the timer values - /* Player only*/ + /* Player only*/ - struct { - event ev; - double time; - } nextevent[NUM_MIDI_TRACKS]; - - double realplayspeed; + struct { + event ev; + double time; + } nextevent[NUM_MIDI_TRACKS]; + double realplayspeed; }; #endif diff --git a/src/Synth/ADnote.cpp b/src/Synth/ADnote.cpp @@ -29,509 +29,682 @@ #include "ADnote.h" -ADnote::ADnote(ADnoteParameters *pars,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote_,bool besilent) +ADnote::ADnote(ADnoteParameters *pars, + Controller *ctl_, + REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote_, + bool besilent) { - ready=0; + ready = 0; - tmpwavel=new REALTYPE [SOUND_BUFFER_SIZE]; - tmpwaver=new REALTYPE [SOUND_BUFFER_SIZE]; - bypassl=new REALTYPE [SOUND_BUFFER_SIZE]; - bypassr=new REALTYPE [SOUND_BUFFER_SIZE]; + tmpwavel = new REALTYPE [SOUND_BUFFER_SIZE]; + tmpwaver = new REALTYPE [SOUND_BUFFER_SIZE]; + bypassl = new REALTYPE [SOUND_BUFFER_SIZE]; + bypassr = new REALTYPE [SOUND_BUFFER_SIZE]; // Initialise some legato-specific vars - Legato.msg=LM_Norm; - Legato.fade.length=(int)(SAMPLE_RATE*0.005);// 0.005 seems ok. - if (Legato.fade.length<1) Legato.fade.length=1;// (if something's fishy) - Legato.fade.step=(1.0/Legato.fade.length); - Legato.decounter=-10; - Legato.param.freq=freq; - Legato.param.vel=velocity; - Legato.param.portamento=portamento_; - Legato.param.midinote=midinote_; - Legato.silent=besilent; - - partparams=pars; - ctl=ctl_; - portamento=portamento_; - midinote=midinote_; - NoteEnabled=ON; - basefreq=freq; - if (velocity>1.0) velocity=1.0; - this->velocity=velocity; - time=0.0; - stereo=pars->GlobalPar.PStereo; - - NoteGlobalPar.Detune=getdetune(pars->GlobalPar.PDetuneType - ,pars->GlobalPar.PCoarseDetune,pars->GlobalPar.PDetune); - bandwidthDetuneMultiplier=pars->getBandwidthDetuneMultiplier(); - - if (pars->GlobalPar.PPanning==0) NoteGlobalPar.Panning=RND; - else NoteGlobalPar.Panning=pars->GlobalPar.PPanning/128.0; - - - NoteGlobalPar.FilterCenterPitch=pars->GlobalPar.GlobalFilter->getfreq()+//center freq - pars->GlobalPar.PFilterVelocityScale/127.0*6.0* //velocity sensing - (VelF(velocity,pars->GlobalPar.PFilterVelocityScaleFunction)-1); - - if (pars->GlobalPar.PPunchStrength!=0) { - NoteGlobalPar.Punch.Enabled=1; - NoteGlobalPar.Punch.t=1.0;//start from 1.0 and to 0.0 - NoteGlobalPar.Punch.initialvalue=( (pow(10,1.5*pars->GlobalPar.PPunchStrength/127.0)-1.0) - *VelF(velocity,pars->GlobalPar.PPunchVelocitySensing) ); - REALTYPE time=pow(10,3.0*pars->GlobalPar.PPunchTime/127.0)/10000.0;//0.1 .. 100 ms - REALTYPE stretch=pow(440.0/freq,pars->GlobalPar.PPunchStretch/64.0); - NoteGlobalPar.Punch.dt=1.0/(time*SAMPLE_RATE*stretch); - } else NoteGlobalPar.Punch.Enabled=0; - - for (int nvoice=0;nvoice<NUM_VOICES;nvoice++) { - pars->VoicePar[nvoice].OscilSmp->newrandseed(rand()); - NoteVoicePar[nvoice].OscilSmp=NULL; - NoteVoicePar[nvoice].FMSmp=NULL; - NoteVoicePar[nvoice].VoiceOut=NULL; - - NoteVoicePar[nvoice].FMVoice=-1; - unison_size[nvoice]=1; - - if (pars->VoicePar[nvoice].Enabled==0) { - NoteVoicePar[nvoice].Enabled=OFF; + Legato.msg = LM_Norm; + Legato.fade.length = (int)(SAMPLE_RATE * 0.005); // 0.005 seems ok. + if(Legato.fade.length < 1) + Legato.fade.length = 1; // (if something's fishy) + Legato.fade.step = (1.0 / Legato.fade.length); + Legato.decounter = -10; + Legato.param.freq = freq; + Legato.param.vel = velocity; + Legato.param.portamento = portamento_; + Legato.param.midinote = midinote_; + Legato.silent = besilent; + + partparams = pars; + ctl = ctl_; + portamento = portamento_; + midinote = midinote_; + NoteEnabled = ON; + basefreq = freq; + if(velocity > 1.0) + velocity = 1.0; + this->velocity = velocity; + time = 0.0; + stereo = pars->GlobalPar.PStereo; + + NoteGlobalPar.Detune = getdetune(pars->GlobalPar.PDetuneType, + pars->GlobalPar.PCoarseDetune, + pars->GlobalPar.PDetune); + bandwidthDetuneMultiplier = pars->getBandwidthDetuneMultiplier(); + + if(pars->GlobalPar.PPanning == 0) + NoteGlobalPar.Panning = RND; + else + NoteGlobalPar.Panning = pars->GlobalPar.PPanning / 128.0; + + + NoteGlobalPar.FilterCenterPitch = pars->GlobalPar.GlobalFilter->getfreq() //center freq + + pars->GlobalPar.PFilterVelocityScale + / 127.0 * 6.0 //velocity sensing + * (VelF(velocity, + pars->GlobalPar. + PFilterVelocityScaleFunction) - 1); + + if(pars->GlobalPar.PPunchStrength != 0) { + NoteGlobalPar.Punch.Enabled = 1; + NoteGlobalPar.Punch.t = 1.0; //start from 1.0 and to 0.0 + NoteGlobalPar.Punch.initialvalue = + ((pow(10, 1.5 * pars->GlobalPar.PPunchStrength / 127.0) - 1.0) + * VelF(velocity, + pars->GlobalPar.PPunchVelocitySensing)); + REALTYPE time = + pow(10, 3.0 * pars->GlobalPar.PPunchTime / 127.0) / 10000.0; //0.1 .. 100 ms + REALTYPE stretch = pow(440.0 / freq, + pars->GlobalPar.PPunchStretch / 64.0); + NoteGlobalPar.Punch.dt = 1.0 / (time * SAMPLE_RATE * stretch); + } + else + NoteGlobalPar.Punch.Enabled = 0; + + for(int nvoice = 0; nvoice < NUM_VOICES; nvoice++) { + pars->VoicePar[nvoice].OscilSmp->newrandseed(rand()); + NoteVoicePar[nvoice].OscilSmp = NULL; + NoteVoicePar[nvoice].FMSmp = NULL; + NoteVoicePar[nvoice].VoiceOut = NULL; + + NoteVoicePar[nvoice].FMVoice = -1; + unison_size[nvoice] = 1; + + if(pars->VoicePar[nvoice].Enabled == 0) { + NoteVoicePar[nvoice].Enabled = OFF; continue; //the voice is disabled - }; + } - unison_stereo_spread[nvoice]=pars->VoicePar[nvoice].Unison_stereo_spread/127.0; - int unison=pars->VoicePar[nvoice].Unison_size; - if (unison<1) unison=1; - - //compute unison - unison_size[nvoice]=unison; - - unison_base_freq_rap[nvoice]=new REALTYPE[unison]; - unison_freq_rap[nvoice]=new REALTYPE[unison]; - unison_invert_phase[nvoice]=new bool[unison]; - REALTYPE unison_spread=pars->getUnisonFrequencySpreadCents(nvoice); - REALTYPE unison_real_spread=pow(2.0,(unison_spread*0.5)/1200.0); - REALTYPE unison_vibratto_a=pars->VoicePar[nvoice].Unison_vibratto/127.0;//0.0 .. 1.0 - - - switch (unison){ - case 1: - unison_base_freq_rap[nvoice][0]=1.0;//if the unison is not used, always make the only subvoice to have the default note - break; - case 2:{//unison for 2 subvoices - unison_base_freq_rap[nvoice][0]=1.0/unison_real_spread; - unison_base_freq_rap[nvoice][1]=unison_real_spread; - }; - break; - default:{//unison for more than 2 subvoices - REALTYPE unison_values[unison]; - REALTYPE min=-1e-6,max=1e-6; - for (int k=0;k<unison;k++){ - REALTYPE step=(k/(REALTYPE) (unison-1))*2.0-1.0;//this makes the unison spread more uniform - REALTYPE val=step+(RND*2.0-1.0)/(unison-1); - unison_values[k]=val; - if (val>max) max=val; - if (val<min) min=val; - }; - REALTYPE diff=max-min; - for (int k=0;k<unison;k++){ - unison_values[k]=(unison_values[k]-(max+min)*0.5)/diff;//the lowest value will be -1 and the highest will be 1 - unison_base_freq_rap[nvoice][k]=pow(2.0,(unison_spread*unison_values[k])/1200); - }; - }; - }; - - //unison vibrattos - if (unison>1){ - for (int k=0;k<unison;k++){//reduce the frequency difference for larger vibrattos - unison_base_freq_rap[nvoice][k]=1.0+(unison_base_freq_rap[nvoice][k]-1.0)*(1.0-unison_vibratto_a); - }; - }; - unison_vibratto[nvoice].step=new REALTYPE[unison]; - unison_vibratto[nvoice].position=new REALTYPE[unison]; - unison_vibratto[nvoice].amplitude=(unison_real_spread-1.0)*unison_vibratto_a; - - REALTYPE increments_per_second=SAMPLE_RATE/(REALTYPE)SOUND_BUFFER_SIZE; - REALTYPE vibratto_base_period=0.25*pow(2.0,(1.0-pars->VoicePar[nvoice].Unison_vibratto_speed/127.0)*4.0); - for (int k=0;k<unison;k++){ - unison_vibratto[nvoice].position[k]=RND*1.8-0.9; - REALTYPE vibratto_period=vibratto_base_period*pow(2.0,RND*2.0-1.0);//make period to vary randomly from 50% to 200% vibratto base period - - REALTYPE m=4.0/(vibratto_period*increments_per_second); - if (RND<0.5) m=-m; - unison_vibratto[nvoice].step[k]=m; - }; - - if (unison==1) {//no vibratto for a single voice - unison_vibratto[nvoice].step[0]=0.0; - unison_vibratto[nvoice].position[0]=0.0; - unison_vibratto[nvoice].amplitude=0.0; - }; - - //phase invert for unison - unison_invert_phase[nvoice][0]=false; - if (unison!=1){ - int inv=pars->VoicePar[nvoice].Unison_invert_phase; - switch(inv){ - case 0: for (int k=0;k<unison;k++) unison_invert_phase[nvoice][k]=false; - break; - case 1: for (int k=0;k<unison;k++) unison_invert_phase[nvoice][k]=(RND>0.5); - break; - default:for (int k=0;k<unison;k++) unison_invert_phase[nvoice][k]=(k%inv==0)?true:false; - break; - }; - }; - - - oscfreqhi[nvoice]=new int[unison]; - oscfreqlo[nvoice]=new REALTYPE[unison]; - oscfreqhiFM[nvoice]=new unsigned int[unison]; - oscfreqloFM[nvoice]=new REALTYPE[unison]; - oscposhi[nvoice]=new int[unison]; - oscposlo[nvoice]=new REALTYPE[unison]; - oscposhiFM[nvoice]=new unsigned int[unison]; - oscposloFM[nvoice]=new REALTYPE[unison]; - - NoteVoicePar[nvoice].Enabled=ON; - NoteVoicePar[nvoice].fixedfreq=pars->VoicePar[nvoice].Pfixedfreq; - NoteVoicePar[nvoice].fixedfreqET=pars->VoicePar[nvoice].PfixedfreqET; + unison_stereo_spread[nvoice] = + pars->VoicePar[nvoice].Unison_stereo_spread / 127.0; + int unison = pars->VoicePar[nvoice].Unison_size; + if(unison < 1) + unison = 1; - //use the Globalpars.detunetype if the detunetype is 0 - if (pars->VoicePar[nvoice].PDetuneType!=0) { - NoteVoicePar[nvoice].Detune=getdetune(pars->VoicePar[nvoice].PDetuneType - ,pars->VoicePar[nvoice].PCoarseDetune,8192);//coarse detune - NoteVoicePar[nvoice].FineDetune=getdetune(pars->VoicePar[nvoice].PDetuneType - ,0,pars->VoicePar[nvoice].PDetune);//fine detune - } else { - NoteVoicePar[nvoice].Detune=getdetune(pars->GlobalPar.PDetuneType - ,pars->VoicePar[nvoice].PCoarseDetune,8192);//coarse detune - NoteVoicePar[nvoice].FineDetune=getdetune(pars->GlobalPar.PDetuneType - ,0,pars->VoicePar[nvoice].PDetune);//fine detune + //compute unison + unison_size[nvoice] = unison; + + unison_base_freq_rap[nvoice] = new REALTYPE[unison]; + unison_freq_rap[nvoice] = new REALTYPE[unison]; + unison_invert_phase[nvoice] = new bool[unison]; + REALTYPE unison_spread = pars->getUnisonFrequencySpreadCents( + nvoice); + REALTYPE unison_real_spread = pow(2.0, (unison_spread * 0.5) / 1200.0); + REALTYPE unison_vibratto_a = pars->VoicePar[nvoice].Unison_vibratto + / 127.0; //0.0 .. 1.0 + + + switch(unison) { + case 1: + unison_base_freq_rap[nvoice][0] = 1.0; //if the unison is not used, always make the only subvoice to have the default note + break; + case 2: { //unison for 2 subvoices + unison_base_freq_rap[nvoice][0] = 1.0 / unison_real_spread; + unison_base_freq_rap[nvoice][1] = unison_real_spread; }; - if (pars->VoicePar[nvoice].PFMDetuneType!=0) { - NoteVoicePar[nvoice].FMDetune=getdetune(pars->VoicePar[nvoice].PFMDetuneType - ,pars->VoicePar[nvoice].PFMCoarseDetune,pars->VoicePar[nvoice].PFMDetune); - } else { - NoteVoicePar[nvoice].FMDetune=getdetune(pars->GlobalPar.PDetuneType - ,pars->VoicePar[nvoice].PFMCoarseDetune,pars->VoicePar[nvoice].PFMDetune); + break; + default: { //unison for more than 2 subvoices + REALTYPE unison_values[unison]; + REALTYPE min = -1e-6, max = 1e-6; + for(int k = 0; k < unison; k++) { + REALTYPE step = (k / (REALTYPE) (unison - 1)) * 2.0 - 1.0; //this makes the unison spread more uniform + REALTYPE val = step + (RND * 2.0 - 1.0) / (unison - 1); + unison_values[k] = val; + if(val > max) + max = val; + if(val < min) + min = val; + } + REALTYPE diff = max - min; + for(int k = 0; k < unison; k++) { + unison_values[k] = + (unison_values[k] - (max + min) * 0.5) / diff; //the lowest value will be -1 and the highest will be 1 + unison_base_freq_rap[nvoice][k] = + pow(2.0, (unison_spread * unison_values[k]) / 1200); + } }; + } + + //unison vibrattos + if(unison > 1) { + for(int k = 0; k < unison; k++) //reduce the frequency difference for larger vibrattos + unison_base_freq_rap[nvoice][k] = 1.0 + + (unison_base_freq_rap[ + nvoice][k] + - 1.0) + * (1.0 - unison_vibratto_a); + ; + } + unison_vibratto[nvoice].step = new REALTYPE[unison]; + unison_vibratto[nvoice].position = new REALTYPE[unison]; + unison_vibratto[nvoice].amplitude = + (unison_real_spread - 1.0) * unison_vibratto_a; + + REALTYPE increments_per_second = SAMPLE_RATE + / (REALTYPE)SOUND_BUFFER_SIZE; + REALTYPE vibratto_base_period = 0.25 + * pow(2.0, + (1.0 + - pars->VoicePar[nvoice]. + Unison_vibratto_speed / 127.0) * 4.0); + for(int k = 0; k < unison; k++) { + unison_vibratto[nvoice].position[k] = RND * 1.8 - 0.9; + REALTYPE vibratto_period = vibratto_base_period * pow( + 2.0, + RND * 2.0 + - 1.0); //make period to vary randomly from 50% to 200% vibratto base period + + REALTYPE m = 4.0 / (vibratto_period * increments_per_second); + if(RND < 0.5) + m = -m; + unison_vibratto[nvoice].step[k] = m; + } - - for (int k=0;k<unison;k++){ - oscposhi[nvoice][k]=0; - oscposlo[nvoice][k]=0.0; - oscposhiFM[nvoice][k]=0; - oscposloFM[nvoice][k]=0.0; - }; + if(unison == 1) { //no vibratto for a single voice + unison_vibratto[nvoice].step[0] = 0.0; + unison_vibratto[nvoice].position[0] = 0.0; + unison_vibratto[nvoice].amplitude = 0.0; + } - NoteVoicePar[nvoice].OscilSmp=new REALTYPE[OSCIL_SIZE+OSCIL_SMP_EXTRA_SAMPLES];//the extra points contains the first point + //phase invert for unison + unison_invert_phase[nvoice][0] = false; + if(unison != 1) { + int inv = pars->VoicePar[nvoice].Unison_invert_phase; + switch(inv) { + case 0: for(int k = 0; k < unison; k++) + unison_invert_phase[nvoice][k] = false; + break; + case 1: for(int k = 0; k < unison; k++) + unison_invert_phase[nvoice][k] = (RND > 0.5); + break; + default: for(int k = 0; k < unison; k++) + unison_invert_phase[nvoice][k] = + (k % inv == 0) ? true : false; + break; + } + } - //Get the voice's oscil or external's voice oscil - int vc=nvoice; - if (pars->VoicePar[nvoice].Pextoscil!=-1) vc=pars->VoicePar[nvoice].Pextoscil; - if (!pars->GlobalPar.Hrandgrouping) pars->VoicePar[vc].OscilSmp->newrandseed(rand()); - int oscposhi_start=pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp,getvoicebasefreq(nvoice), pars->VoicePar[nvoice].Presonance); - //I store the first elments to the last position for speedups - for (int i=0;i<OSCIL_SMP_EXTRA_SAMPLES;i++) NoteVoicePar[nvoice].OscilSmp[OSCIL_SIZE+i]=NoteVoicePar[nvoice].OscilSmp[i]; + oscfreqhi[nvoice] = new int[unison]; + oscfreqlo[nvoice] = new REALTYPE[unison]; + oscfreqhiFM[nvoice] = new unsigned int[unison]; + oscfreqloFM[nvoice] = new REALTYPE[unison]; + oscposhi[nvoice] = new int[unison]; + oscposlo[nvoice] = new REALTYPE[unison]; + oscposhiFM[nvoice] = new unsigned int[unison]; + oscposloFM[nvoice] = new REALTYPE[unison]; - oscposhi_start+=(int)((pars->VoicePar[nvoice].Poscilphase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE*4); - oscposhi_start%=OSCIL_SIZE; + NoteVoicePar[nvoice].Enabled = ON; + NoteVoicePar[nvoice].fixedfreq = pars->VoicePar[nvoice].Pfixedfreq; + NoteVoicePar[nvoice].fixedfreqET = pars->VoicePar[nvoice].PfixedfreqET; - for (int k=0;k<unison;k++){ - oscposhi[nvoice][k]=oscposhi_start; - oscposhi_start=(int)(RND*(OSCIL_SIZE-1));//put random starting point for other subvoices - }; + //use the Globalpars.detunetype if the detunetype is 0 + if(pars->VoicePar[nvoice].PDetuneType != 0) { + NoteVoicePar[nvoice].Detune = getdetune( + pars->VoicePar[nvoice].PDetuneType, + pars->VoicePar[nvoice]. + PCoarseDetune, + 8192); //coarse detune + NoteVoicePar[nvoice].FineDetune = getdetune( + pars->VoicePar[nvoice].PDetuneType, + 0, + pars->VoicePar[nvoice].PDetune); //fine detune + } + else { + NoteVoicePar[nvoice].Detune = getdetune( + pars->GlobalPar.PDetuneType, + pars->VoicePar[nvoice]. + PCoarseDetune, + 8192); //coarse detune + NoteVoicePar[nvoice].FineDetune = getdetune( + pars->GlobalPar.PDetuneType, + 0, + pars->VoicePar[nvoice].PDetune); //fine detune + } + if(pars->VoicePar[nvoice].PFMDetuneType != 0) + NoteVoicePar[nvoice].FMDetune = getdetune( + pars->VoicePar[nvoice].PFMDetuneType, + pars->VoicePar[nvoice]. + PFMCoarseDetune, + pars->VoicePar[nvoice].PFMDetune); + else + NoteVoicePar[nvoice].FMDetune = getdetune( + pars->GlobalPar.PDetuneType, + pars->VoicePar[nvoice]. + PFMCoarseDetune, + pars->VoicePar[nvoice].PFMDetune); + ; + + + for(int k = 0; k < unison; k++) { + oscposhi[nvoice][k] = 0; + oscposlo[nvoice][k] = 0.0; + oscposhiFM[nvoice][k] = 0; + oscposloFM[nvoice][k] = 0.0; + } - NoteVoicePar[nvoice].FreqLfo=NULL; - NoteVoicePar[nvoice].FreqEnvelope=NULL; + NoteVoicePar[nvoice].OscilSmp = + new REALTYPE[OSCIL_SIZE + OSCIL_SMP_EXTRA_SAMPLES]; //the extra points contains the first point - NoteVoicePar[nvoice].AmpLfo=NULL; - NoteVoicePar[nvoice].AmpEnvelope=NULL; + //Get the voice's oscil or external's voice oscil + int vc = nvoice; + if(pars->VoicePar[nvoice].Pextoscil != -1) + vc = pars->VoicePar[nvoice].Pextoscil; + if(!pars->GlobalPar.Hrandgrouping) + pars->VoicePar[vc].OscilSmp->newrandseed(rand()); + int oscposhi_start = + pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp, + getvoicebasefreq(nvoice), + pars->VoicePar[nvoice].Presonance); - NoteVoicePar[nvoice].VoiceFilterL=NULL; - NoteVoicePar[nvoice].VoiceFilterR=NULL; - NoteVoicePar[nvoice].FilterEnvelope=NULL; - NoteVoicePar[nvoice].FilterLfo=NULL; + //I store the first elments to the last position for speedups + for(int i = 0; i < OSCIL_SMP_EXTRA_SAMPLES; i++) + NoteVoicePar[nvoice].OscilSmp[OSCIL_SIZE + + i] = + NoteVoicePar[nvoice].OscilSmp[i]; + + oscposhi_start += + (int)((pars->VoicePar[nvoice].Poscilphase + - 64.0) / 128.0 * OSCIL_SIZE + OSCIL_SIZE * 4); + oscposhi_start %= OSCIL_SIZE; + + for(int k = 0; k < unison; k++) { + oscposhi[nvoice][k] = oscposhi_start; + oscposhi_start = (int)(RND * (OSCIL_SIZE - 1)); //put random starting point for other subvoices + } - NoteVoicePar[nvoice].FilterCenterPitch=pars->VoicePar[nvoice].VoiceFilter->getfreq(); - NoteVoicePar[nvoice].filterbypass=pars->VoicePar[nvoice].Pfilterbypass; + NoteVoicePar[nvoice].FreqLfo = NULL; + NoteVoicePar[nvoice].FreqEnvelope = NULL; - switch (pars->VoicePar[nvoice].PFMEnabled) { + NoteVoicePar[nvoice].AmpLfo = NULL; + NoteVoicePar[nvoice].AmpEnvelope = NULL; + + NoteVoicePar[nvoice].VoiceFilterL = NULL; + NoteVoicePar[nvoice].VoiceFilterR = NULL; + NoteVoicePar[nvoice].FilterEnvelope = NULL; + NoteVoicePar[nvoice].FilterLfo = NULL; + + NoteVoicePar[nvoice].FilterCenterPitch = + pars->VoicePar[nvoice].VoiceFilter->getfreq(); + NoteVoicePar[nvoice].filterbypass = + pars->VoicePar[nvoice].Pfilterbypass; + + switch(pars->VoicePar[nvoice].PFMEnabled) { case 1: - NoteVoicePar[nvoice].FMEnabled=MORPH; + NoteVoicePar[nvoice].FMEnabled = MORPH; break; case 2: - NoteVoicePar[nvoice].FMEnabled=RING_MOD; + NoteVoicePar[nvoice].FMEnabled = RING_MOD; break; case 3: - NoteVoicePar[nvoice].FMEnabled=PHASE_MOD; + NoteVoicePar[nvoice].FMEnabled = PHASE_MOD; break; case 4: - NoteVoicePar[nvoice].FMEnabled=FREQ_MOD; + NoteVoicePar[nvoice].FMEnabled = FREQ_MOD; break; case 5: - NoteVoicePar[nvoice].FMEnabled=PITCH_MOD; + NoteVoicePar[nvoice].FMEnabled = PITCH_MOD; break; default: - NoteVoicePar[nvoice].FMEnabled=NONE; - }; + NoteVoicePar[nvoice].FMEnabled = NONE; + } - NoteVoicePar[nvoice].FMVoice=pars->VoicePar[nvoice].PFMVoice; - NoteVoicePar[nvoice].FMFreqEnvelope=NULL; - NoteVoicePar[nvoice].FMAmpEnvelope=NULL; + NoteVoicePar[nvoice].FMVoice = pars->VoicePar[nvoice].PFMVoice; + NoteVoicePar[nvoice].FMFreqEnvelope = NULL; + NoteVoicePar[nvoice].FMAmpEnvelope = NULL; //Compute the Voice's modulator volume (incl. damping) - REALTYPE fmvoldamp=pow(440.0/getvoicebasefreq(nvoice),pars->VoicePar[nvoice].PFMVolumeDamp/64.0-1.0); - switch (NoteVoicePar[nvoice].FMEnabled) { + REALTYPE fmvoldamp = pow(440.0 / getvoicebasefreq( + nvoice), + pars->VoicePar[nvoice].PFMVolumeDamp / 64.0 + - 1.0); + switch(NoteVoicePar[nvoice].FMEnabled) { case PHASE_MOD: - fmvoldamp=pow(440.0/getvoicebasefreq(nvoice),pars->VoicePar[nvoice].PFMVolumeDamp/64.0); - NoteVoicePar[nvoice].FMVolume=(exp(pars->VoicePar[nvoice].PFMVolume/127.0*FM_AMP_MULTIPLIER)-1.0)*fmvoldamp*4.0; + fmvoldamp = + pow(440.0 / getvoicebasefreq( + nvoice), pars->VoicePar[nvoice].PFMVolumeDamp / 64.0); + NoteVoicePar[nvoice].FMVolume = + (exp(pars->VoicePar[nvoice].PFMVolume / 127.0 + * FM_AMP_MULTIPLIER) - 1.0) * fmvoldamp * 4.0; break; case FREQ_MOD: - NoteVoicePar[nvoice].FMVolume=(exp(pars->VoicePar[nvoice].PFMVolume/127.0*FM_AMP_MULTIPLIER)-1.0)*fmvoldamp*4.0; + NoteVoicePar[nvoice].FMVolume = + (exp(pars->VoicePar[nvoice].PFMVolume / 127.0 + * FM_AMP_MULTIPLIER) - 1.0) * fmvoldamp * 4.0; break; - // case PITCH_MOD:NoteVoicePar[nvoice].FMVolume=(pars->VoicePar[nvoice].PFMVolume/127.0*8.0)*fmvoldamp;//??????????? - // break; + // case PITCH_MOD:NoteVoicePar[nvoice].FMVolume=(pars->VoicePar[nvoice].PFMVolume/127.0*8.0)*fmvoldamp;//??????????? + // break; default: - if (fmvoldamp>1.0) fmvoldamp=1.0; - NoteVoicePar[nvoice].FMVolume=pars->VoicePar[nvoice].PFMVolume/127.0*fmvoldamp; - }; + if(fmvoldamp > 1.0) + fmvoldamp = 1.0; + NoteVoicePar[nvoice].FMVolume = pars->VoicePar[nvoice].PFMVolume + / 127.0 * fmvoldamp; + } //Voice's modulator velocity sensing - NoteVoicePar[nvoice].FMVolume*=VelF(velocity,partparams->VoicePar[nvoice].PFMVelocityScaleFunction); - - FMoldsmp[nvoice]=new REALTYPE [unison]; - for (int k=0;k<unison;k++) FMoldsmp[nvoice][k]=0.0;//this is for FM (integration) - - firsttick[nvoice]=1; - NoteVoicePar[nvoice].DelayTicks=(int)((exp(pars->VoicePar[nvoice].PDelay/127.0*log(50.0))-1.0)/SOUND_BUFFER_SIZE/10.0*SAMPLE_RATE); - - - }; - - max_unison=1; - for (int nvoice=0;nvoice<NUM_VOICES;nvoice++){ - if (unison_size[nvoice]>max_unison) max_unison=unison_size[nvoice]; - }; + NoteVoicePar[nvoice].FMVolume *= + VelF(velocity, + partparams->VoicePar[nvoice].PFMVelocityScaleFunction); + + FMoldsmp[nvoice] = new REALTYPE [unison]; + for(int k = 0; k < unison; k++) + FMoldsmp[nvoice][k] = 0.0; //this is for FM (integration) + + firsttick[nvoice] = 1; + NoteVoicePar[nvoice].DelayTicks = + (int)((exp(pars->VoicePar[nvoice].PDelay / 127.0 + * log(50.0)) + - 1.0) / SOUND_BUFFER_SIZE / 10.0 * SAMPLE_RATE); + } - tmpwave_unison=new REALTYPE*[max_unison]; - for (int k=0;k<max_unison;k++){ - tmpwave_unison[k]=new REALTYPE[SOUND_BUFFER_SIZE]; - for (int i=0;i<SOUND_BUFFER_SIZE;i++) tmpwave_unison[k][i]=0.0; - }; + max_unison = 1; + for(int nvoice = 0; nvoice < NUM_VOICES; nvoice++) + if(unison_size[nvoice] > max_unison) + max_unison = unison_size[nvoice]; + ; + + tmpwave_unison = new REALTYPE *[max_unison]; + for(int k = 0; k < max_unison; k++) { + tmpwave_unison[k] = new REALTYPE[SOUND_BUFFER_SIZE]; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwave_unison[k][i] = 0.0; + } initparameters(); - ready=1; -}; + ready = 1; +} // ADlegatonote: This function is (mostly) a copy of ADnote(...) and // initparameters() stuck together with some lines removed so that it // only alter the already playing note (to perform legato). It is // possible I left stuff that is not required for this. -void ADnote::ADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote_, bool externcall) +void ADnote::ADlegatonote(REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote_, + bool externcall) { - ADnoteParameters *pars=partparams; + ADnoteParameters *pars = partparams; //Controller *ctl_=ctl; // Manage legato stuff - if (externcall) Legato.msg=LM_Norm; - if (Legato.msg!=LM_CatchUp) { - Legato.lastfreq=Legato.param.freq; - Legato.param.freq=freq; - Legato.param.vel=velocity; - Legato.param.portamento=portamento_; - Legato.param.midinote=midinote_; - if (Legato.msg==LM_Norm) { - if (Legato.silent) { - Legato.fade.m=0.0; - Legato.msg=LM_FadeIn; - } else { - Legato.fade.m=1.0; - Legato.msg=LM_FadeOut; + if(externcall) + Legato.msg = LM_Norm; + if(Legato.msg != LM_CatchUp) { + Legato.lastfreq = Legato.param.freq; + Legato.param.freq = freq; + Legato.param.vel = velocity; + Legato.param.portamento = portamento_; + Legato.param.midinote = midinote_; + if(Legato.msg == LM_Norm) { + if(Legato.silent) { + Legato.fade.m = 0.0; + Legato.msg = LM_FadeIn; + } + else { + Legato.fade.m = 1.0; + Legato.msg = LM_FadeOut; return; } } - if (Legato.msg==LM_ToNorm) Legato.msg=LM_Norm; + if(Legato.msg == LM_ToNorm) + Legato.msg = LM_Norm; } - portamento=portamento_; - midinote=midinote_; - basefreq=freq; + portamento = portamento_; + midinote = midinote_; + basefreq = freq; - if (velocity>1.0) velocity=1.0; - this->velocity=velocity; + if(velocity > 1.0) + velocity = 1.0; + this->velocity = velocity; - NoteGlobalPar.Detune=getdetune(pars->GlobalPar.PDetuneType - ,pars->GlobalPar.PCoarseDetune,pars->GlobalPar.PDetune); - bandwidthDetuneMultiplier=pars->getBandwidthDetuneMultiplier(); + NoteGlobalPar.Detune = getdetune(pars->GlobalPar.PDetuneType, + pars->GlobalPar.PCoarseDetune, + pars->GlobalPar.PDetune); + bandwidthDetuneMultiplier = pars->getBandwidthDetuneMultiplier(); - if (pars->GlobalPar.PPanning==0) NoteGlobalPar.Panning=RND; - else NoteGlobalPar.Panning=pars->GlobalPar.PPanning/128.0; + if(pars->GlobalPar.PPanning == 0) + NoteGlobalPar.Panning = RND; + else + NoteGlobalPar.Panning = pars->GlobalPar.PPanning / 128.0; - NoteGlobalPar.FilterCenterPitch=pars->GlobalPar.GlobalFilter->getfreq()+//center freq - pars->GlobalPar.PFilterVelocityScale/127.0*6.0* //velocity sensing - (VelF(velocity,pars->GlobalPar.PFilterVelocityScaleFunction)-1); + NoteGlobalPar.FilterCenterPitch = pars->GlobalPar.GlobalFilter->getfreq() //center freq + + pars->GlobalPar.PFilterVelocityScale + / 127.0 * 6.0 //velocity sensing + * (VelF(velocity, + pars->GlobalPar. + PFilterVelocityScaleFunction) - 1); - for (int nvoice=0;nvoice<NUM_VOICES;nvoice++) { - if (NoteVoicePar[nvoice].Enabled==OFF) + for(int nvoice = 0; nvoice < NUM_VOICES; nvoice++) { + if(NoteVoicePar[nvoice].Enabled == OFF) continue; //(gf) Stay the same as first note in legato. - NoteVoicePar[nvoice].fixedfreq=pars->VoicePar[nvoice].Pfixedfreq; - NoteVoicePar[nvoice].fixedfreqET=pars->VoicePar[nvoice].PfixedfreqET; + NoteVoicePar[nvoice].fixedfreq = pars->VoicePar[nvoice].Pfixedfreq; + NoteVoicePar[nvoice].fixedfreqET = pars->VoicePar[nvoice].PfixedfreqET; //use the Globalpars.detunetype if the detunetype is 0 - if (pars->VoicePar[nvoice].PDetuneType!=0) { - NoteVoicePar[nvoice].Detune=getdetune(pars->VoicePar[nvoice].PDetuneType - ,pars->VoicePar[nvoice].PCoarseDetune,8192);//coarse detune - NoteVoicePar[nvoice].FineDetune=getdetune(pars->VoicePar[nvoice].PDetuneType - ,0,pars->VoicePar[nvoice].PDetune);//fine detune - } else { - NoteVoicePar[nvoice].Detune=getdetune(pars->GlobalPar.PDetuneType - ,pars->VoicePar[nvoice].PCoarseDetune,8192);//coarse detune - NoteVoicePar[nvoice].FineDetune=getdetune(pars->GlobalPar.PDetuneType - ,0,pars->VoicePar[nvoice].PDetune);//fine detune - }; - if (pars->VoicePar[nvoice].PFMDetuneType!=0) { - NoteVoicePar[nvoice].FMDetune=getdetune(pars->VoicePar[nvoice].PFMDetuneType - ,pars->VoicePar[nvoice].PFMCoarseDetune,pars->VoicePar[nvoice].PFMDetune); - } else { - NoteVoicePar[nvoice].FMDetune=getdetune(pars->GlobalPar.PDetuneType - ,pars->VoicePar[nvoice].PFMCoarseDetune,pars->VoicePar[nvoice].PFMDetune); - }; + if(pars->VoicePar[nvoice].PDetuneType != 0) { + NoteVoicePar[nvoice].Detune = getdetune( + pars->VoicePar[nvoice].PDetuneType, + pars->VoicePar[nvoice]. + PCoarseDetune, + 8192); //coarse detune + NoteVoicePar[nvoice].FineDetune = getdetune( + pars->VoicePar[nvoice].PDetuneType, + 0, + pars->VoicePar[nvoice].PDetune); //fine detune + } + else { + NoteVoicePar[nvoice].Detune = getdetune( + pars->GlobalPar.PDetuneType, + pars->VoicePar[nvoice]. + PCoarseDetune, + 8192); //coarse detune + NoteVoicePar[nvoice].FineDetune = getdetune( + pars->GlobalPar.PDetuneType, + 0, + pars->VoicePar[nvoice].PDetune); //fine detune + } + if(pars->VoicePar[nvoice].PFMDetuneType != 0) + NoteVoicePar[nvoice].FMDetune = getdetune( + pars->VoicePar[nvoice].PFMDetuneType, + pars->VoicePar[nvoice]. + PFMCoarseDetune, + pars->VoicePar[nvoice].PFMDetune); + else + NoteVoicePar[nvoice].FMDetune = getdetune( + pars->GlobalPar.PDetuneType, + pars->VoicePar[nvoice]. + PFMCoarseDetune, + pars->VoicePar[nvoice].PFMDetune); + ; //Get the voice's oscil or external's voice oscil - int vc=nvoice; - if (pars->VoicePar[nvoice].Pextoscil!=-1) vc=pars->VoicePar[nvoice].Pextoscil; - if (!pars->GlobalPar.Hrandgrouping) pars->VoicePar[vc].OscilSmp->newrandseed(rand()); + int vc = nvoice; + if(pars->VoicePar[nvoice].Pextoscil != -1) + vc = pars->VoicePar[nvoice].Pextoscil; + if(!pars->GlobalPar.Hrandgrouping) + pars->VoicePar[vc].OscilSmp->newrandseed(rand()); - pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp,getvoicebasefreq(nvoice),pars->VoicePar[nvoice].Presonance);//(gf)Modif of the above line. + pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp, + getvoicebasefreq(nvoice), + pars->VoicePar[nvoice].Presonance); //(gf)Modif of the above line. //I store the first elments to the last position for speedups - for (int i=0;i<OSCIL_SMP_EXTRA_SAMPLES;i++) NoteVoicePar[nvoice].OscilSmp[OSCIL_SIZE+i]=NoteVoicePar[nvoice].OscilSmp[i]; + for(int i = 0; i < OSCIL_SMP_EXTRA_SAMPLES; i++) + NoteVoicePar[nvoice].OscilSmp[OSCIL_SIZE + + i] = + NoteVoicePar[nvoice].OscilSmp[i]; - NoteVoicePar[nvoice].FilterCenterPitch=pars->VoicePar[nvoice].VoiceFilter->getfreq(); - NoteVoicePar[nvoice].filterbypass=pars->VoicePar[nvoice].Pfilterbypass; + NoteVoicePar[nvoice].FilterCenterPitch = + pars->VoicePar[nvoice].VoiceFilter->getfreq(); + NoteVoicePar[nvoice].filterbypass = + pars->VoicePar[nvoice].Pfilterbypass; - NoteVoicePar[nvoice].FMVoice=pars->VoicePar[nvoice].PFMVoice; + NoteVoicePar[nvoice].FMVoice = pars->VoicePar[nvoice].PFMVoice; //Compute the Voice's modulator volume (incl. damping) - REALTYPE fmvoldamp=pow(440.0/getvoicebasefreq(nvoice),pars->VoicePar[nvoice].PFMVolumeDamp/64.0-1.0); + REALTYPE fmvoldamp = pow(440.0 / getvoicebasefreq( + nvoice), + pars->VoicePar[nvoice].PFMVolumeDamp / 64.0 + - 1.0); - switch (NoteVoicePar[nvoice].FMEnabled) { + switch(NoteVoicePar[nvoice].FMEnabled) { case PHASE_MOD: - fmvoldamp=pow(440.0/getvoicebasefreq(nvoice),pars->VoicePar[nvoice].PFMVolumeDamp/64.0); - NoteVoicePar[nvoice].FMVolume=(exp(pars->VoicePar[nvoice].PFMVolume/127.0*FM_AMP_MULTIPLIER)-1.0)*fmvoldamp*4.0; + fmvoldamp = + pow(440.0 / getvoicebasefreq( + nvoice), pars->VoicePar[nvoice].PFMVolumeDamp / 64.0); + NoteVoicePar[nvoice].FMVolume = + (exp(pars->VoicePar[nvoice].PFMVolume / 127.0 + * FM_AMP_MULTIPLIER) - 1.0) * fmvoldamp * 4.0; break; case FREQ_MOD: - NoteVoicePar[nvoice].FMVolume=(exp(pars->VoicePar[nvoice].PFMVolume/127.0*FM_AMP_MULTIPLIER)-1.0)*fmvoldamp*4.0; + NoteVoicePar[nvoice].FMVolume = + (exp(pars->VoicePar[nvoice].PFMVolume / 127.0 + * FM_AMP_MULTIPLIER) - 1.0) * fmvoldamp * 4.0; break; - // case PITCH_MOD:NoteVoicePar[nvoice].FMVolume=(pars->VoicePar[nvoice].PFMVolume/127.0*8.0)*fmvoldamp;//??????????? - // break; + // case PITCH_MOD:NoteVoicePar[nvoice].FMVolume=(pars->VoicePar[nvoice].PFMVolume/127.0*8.0)*fmvoldamp;//??????????? + // break; default: - if (fmvoldamp>1.0) fmvoldamp=1.0; - NoteVoicePar[nvoice].FMVolume=pars->VoicePar[nvoice].PFMVolume/127.0*fmvoldamp; - }; + if(fmvoldamp > 1.0) + fmvoldamp = 1.0; + NoteVoicePar[nvoice].FMVolume = pars->VoicePar[nvoice].PFMVolume + / 127.0 * fmvoldamp; + } //Voice's modulator velocity sensing - NoteVoicePar[nvoice].FMVolume*=VelF(velocity,partparams->VoicePar[nvoice].PFMVelocityScaleFunction); - - NoteVoicePar[nvoice].DelayTicks=(int)((exp(pars->VoicePar[nvoice].PDelay/127.0*log(50.0))-1.0)/SOUND_BUFFER_SIZE/10.0*SAMPLE_RATE); - - }; + NoteVoicePar[nvoice].FMVolume *= + VelF(velocity, + partparams->VoicePar[nvoice].PFMVelocityScaleFunction); + + NoteVoicePar[nvoice].DelayTicks = + (int)((exp(pars->VoicePar[nvoice].PDelay / 127.0 + * log(50.0)) + - 1.0) / SOUND_BUFFER_SIZE / 10.0 * SAMPLE_RATE); + } /// initparameters(); /////////////// // Altered content of initparameters(): - int nvoice,i,tmp[NUM_VOICES]; + int nvoice, i, tmp[NUM_VOICES]; - NoteGlobalPar.Volume=4.0*pow(0.1,3.0*(1.0-partparams->GlobalPar.PVolume/96.0))//-60 dB .. 0 dB - *VelF(velocity,partparams->GlobalPar.PAmpVelocityScaleFunction);//velocity sensing + NoteGlobalPar.Volume = 4.0 + * pow(0.1, 3.0 + * (1.0 - partparams->GlobalPar.PVolume / 96.0)) //-60 dB .. 0 dB + * VelF( + velocity, + partparams->GlobalPar. + PAmpVelocityScaleFunction); //velocity sensing - globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); + globalnewamplitude = NoteGlobalPar.Volume + * NoteGlobalPar.AmpEnvelope->envout_dB() + * NoteGlobalPar.AmpLfo->amplfoout(); - NoteGlobalPar.FilterQ=partparams->GlobalPar.GlobalFilter->getq(); - NoteGlobalPar.FilterFreqTracking=partparams->GlobalPar.GlobalFilter->getfreqtracking(basefreq); + NoteGlobalPar.FilterQ = partparams->GlobalPar.GlobalFilter->getq(); + NoteGlobalPar.FilterFreqTracking = + partparams->GlobalPar.GlobalFilter->getfreqtracking(basefreq); // Forbids the Modulation Voice to be greater or equal than voice - for (i=0;i<NUM_VOICES;i++) if (NoteVoicePar[i].FMVoice>=i) NoteVoicePar[i].FMVoice=-1; + for(i = 0; i < NUM_VOICES; i++) + if(NoteVoicePar[i].FMVoice >= i) + NoteVoicePar[i].FMVoice = -1; // Voice Parameter init - for (nvoice=0;nvoice<NUM_VOICES;nvoice++) { - if (NoteVoicePar[nvoice].Enabled==0) continue; + for(nvoice = 0; nvoice < NUM_VOICES; nvoice++) { + if(NoteVoicePar[nvoice].Enabled == 0) + continue; - NoteVoicePar[nvoice].noisetype=partparams->VoicePar[nvoice].Type; + NoteVoicePar[nvoice].noisetype = partparams->VoicePar[nvoice].Type; /* Voice Amplitude Parameters Init */ - NoteVoicePar[nvoice].Volume=pow(0.1,3.0*(1.0-partparams->VoicePar[nvoice].PVolume/127.0)) // -60 dB .. 0 dB - *VelF(velocity,partparams->VoicePar[nvoice].PAmpVelocityScaleFunction);//velocity + NoteVoicePar[nvoice].Volume = + pow(0.1, 3.0 * (1.0 - partparams->VoicePar[nvoice].PVolume / 127.0)) // -60 dB .. 0 dB + * VelF(velocity, + partparams->VoicePar[nvoice].PAmpVelocityScaleFunction); //velocity - if (partparams->VoicePar[nvoice].PVolumeminus!=0) NoteVoicePar[nvoice].Volume=-NoteVoicePar[nvoice].Volume; + if(partparams->VoicePar[nvoice].PVolumeminus != 0) + NoteVoicePar[nvoice].Volume = -NoteVoicePar[nvoice].Volume; - if (partparams->VoicePar[nvoice].PPanning==0) - NoteVoicePar[nvoice].Panning=RND;// random panning - else NoteVoicePar[nvoice].Panning=partparams->VoicePar[nvoice].PPanning/128.0; + if(partparams->VoicePar[nvoice].PPanning == 0) + NoteVoicePar[nvoice].Panning = RND; // random panning + else + NoteVoicePar[nvoice].Panning = + partparams->VoicePar[nvoice].PPanning / 128.0; - newamplitude[nvoice]=1.0; - if ((partparams->VoicePar[nvoice].PAmpEnvelopeEnabled!=0) - && (NoteVoicePar[nvoice].AmpEnvelope!=NULL)) { - newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); - }; + newamplitude[nvoice] = 1.0; + if((partparams->VoicePar[nvoice].PAmpEnvelopeEnabled != 0) + && (NoteVoicePar[nvoice].AmpEnvelope != NULL)) + newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); + ; - if ((partparams->VoicePar[nvoice].PAmpLfoEnabled!=0) - && (NoteVoicePar[nvoice].AmpLfo!=NULL)) { - newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpLfo->amplfoout(); - }; + if((partparams->VoicePar[nvoice].PAmpLfoEnabled != 0) + && (NoteVoicePar[nvoice].AmpLfo != NULL)) + newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpLfo->amplfoout(); + ; - NoteVoicePar[nvoice].FilterFreqTracking=partparams->VoicePar[nvoice].VoiceFilter->getfreqtracking(basefreq); + NoteVoicePar[nvoice].FilterFreqTracking = + partparams->VoicePar[nvoice].VoiceFilter->getfreqtracking(basefreq); /* Voice Modulation Parameters Init */ - if ((NoteVoicePar[nvoice].FMEnabled!=NONE)&&(NoteVoicePar[nvoice].FMVoice<0)) { + if((NoteVoicePar[nvoice].FMEnabled != NONE) + && (NoteVoicePar[nvoice].FMVoice < 0)) { partparams->VoicePar[nvoice].FMSmp->newrandseed(rand()); //Perform Anti-aliasing only on MORPH or RING MODULATION - int vc=nvoice; - if (partparams->VoicePar[nvoice].PextFMoscil!=-1) vc=partparams->VoicePar[nvoice].PextFMoscil; + int vc = nvoice; + if(partparams->VoicePar[nvoice].PextFMoscil != -1) + vc = partparams->VoicePar[nvoice].PextFMoscil; - REALTYPE tmp=1.0; - if ((partparams->VoicePar[vc].FMSmp->Padaptiveharmonics!=0)|| - (NoteVoicePar[nvoice].FMEnabled==MORPH)|| - (NoteVoicePar[nvoice].FMEnabled==RING_MOD)) { - tmp=getFMvoicebasefreq(nvoice); - }; - if (!partparams->GlobalPar.Hrandgrouping) partparams->VoicePar[vc].FMSmp->newrandseed(rand()); + REALTYPE tmp = 1.0; + if((partparams->VoicePar[vc].FMSmp->Padaptiveharmonics != 0) + || (NoteVoicePar[nvoice].FMEnabled == MORPH) + || (NoteVoicePar[nvoice].FMEnabled == RING_MOD)) + tmp = getFMvoicebasefreq(nvoice); + ; + if(!partparams->GlobalPar.Hrandgrouping) + partparams->VoicePar[vc].FMSmp->newrandseed(rand()); ///oscposhiFM[nvoice]=(oscposhi[nvoice]+partparams->VoicePar[vc].FMSmp->get(NoteVoicePar[nvoice].FMSmp,tmp)) % OSCIL_SIZE; // / oscposhi[nvoice]+partparams->VoicePar[vc].FMSmp->get(NoteVoicePar[nvoice].FMSmp,tmp); //(gf) Modif of the above line. - for (int i=0;i<OSCIL_SMP_EXTRA_SAMPLES;i++) NoteVoicePar[nvoice].FMSmp[OSCIL_SIZE+i]=NoteVoicePar[nvoice].FMSmp[i]; + for(int i = 0; i < OSCIL_SMP_EXTRA_SAMPLES; i++) + NoteVoicePar[nvoice].FMSmp[OSCIL_SIZE + + i] = NoteVoicePar[nvoice].FMSmp[i]; ///oscposhiFM[nvoice]+=(int)((partparams->VoicePar[nvoice].PFMoscilphase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE*4); ///oscposhiFM[nvoice]%=OSCIL_SIZE; - }; + } - FMnewamplitude[nvoice]=NoteVoicePar[nvoice].FMVolume*ctl->fmamp.relamp; + FMnewamplitude[nvoice] = NoteVoicePar[nvoice].FMVolume + * ctl->fmamp.relamp; - if ((partparams->VoicePar[nvoice].PFMAmpEnvelopeEnabled!=0) - && (NoteVoicePar[nvoice].FMAmpEnvelope!=NULL)) { - FMnewamplitude[nvoice]*=NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB(); - }; - }; + if((partparams->VoicePar[nvoice].PFMAmpEnvelopeEnabled != 0) + && (NoteVoicePar[nvoice].FMAmpEnvelope != NULL)) + FMnewamplitude[nvoice] *= + NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB(); + ; + } - for (nvoice=0;nvoice<NUM_VOICES;nvoice++) { - for (i=nvoice+1;i<NUM_VOICES;i++) tmp[i]=0; - for (i=nvoice+1;i<NUM_VOICES;i++) - if ((NoteVoicePar[i].FMVoice==nvoice)&&(tmp[i]==0)) { - tmp[i]=1; - }; - }; + for(nvoice = 0; nvoice < NUM_VOICES; nvoice++) { + for(i = nvoice + 1; i < NUM_VOICES; i++) + tmp[i] = 0; + for(i = nvoice + 1; i < NUM_VOICES; i++) + if((NoteVoicePar[i].FMVoice == nvoice) && (tmp[i] == 0)) + tmp[i] = 1; + ; + } /////////////// // End of the ADlegatonote function. -}; +} /* @@ -539,61 +712,73 @@ void ADnote::ADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int */ void ADnote::KillVoice(int nvoice) { - - delete []oscfreqhi[nvoice]; - delete []oscfreqlo[nvoice]; - delete []oscfreqhiFM[nvoice]; - delete []oscfreqloFM[nvoice]; - delete []oscposhi[nvoice]; - delete []oscposlo[nvoice]; - delete []oscposhiFM[nvoice]; - delete []oscposloFM[nvoice]; - - delete []NoteVoicePar[nvoice].OscilSmp; - delete []unison_base_freq_rap[nvoice]; - delete []unison_freq_rap[nvoice]; - delete []unison_invert_phase[nvoice]; - delete []FMoldsmp[nvoice]; - delete []unison_vibratto[nvoice].step; - delete []unison_vibratto[nvoice].position; - - if (NoteVoicePar[nvoice].FreqEnvelope!=NULL) delete(NoteVoicePar[nvoice].FreqEnvelope); - NoteVoicePar[nvoice].FreqEnvelope=NULL; - - if (NoteVoicePar[nvoice].FreqLfo!=NULL) delete(NoteVoicePar[nvoice].FreqLfo); - NoteVoicePar[nvoice].FreqLfo=NULL; - - if (NoteVoicePar[nvoice].AmpEnvelope!=NULL) delete (NoteVoicePar[nvoice].AmpEnvelope); - NoteVoicePar[nvoice].AmpEnvelope=NULL; - - if (NoteVoicePar[nvoice].AmpLfo!=NULL) delete (NoteVoicePar[nvoice].AmpLfo); - NoteVoicePar[nvoice].AmpLfo=NULL; - - if (NoteVoicePar[nvoice].VoiceFilterL!=NULL) delete (NoteVoicePar[nvoice].VoiceFilterL); - NoteVoicePar[nvoice].VoiceFilterL=NULL; - - if (NoteVoicePar[nvoice].VoiceFilterR!=NULL) delete (NoteVoicePar[nvoice].VoiceFilterR); - NoteVoicePar[nvoice].VoiceFilterR=NULL; - - if (NoteVoicePar[nvoice].FilterEnvelope!=NULL) delete (NoteVoicePar[nvoice].FilterEnvelope); - NoteVoicePar[nvoice].FilterEnvelope=NULL; - - if (NoteVoicePar[nvoice].FilterLfo!=NULL) delete (NoteVoicePar[nvoice].FilterLfo); - NoteVoicePar[nvoice].FilterLfo=NULL; - - if (NoteVoicePar[nvoice].FMFreqEnvelope!=NULL) delete (NoteVoicePar[nvoice].FMFreqEnvelope); - NoteVoicePar[nvoice].FMFreqEnvelope=NULL; - - if (NoteVoicePar[nvoice].FMAmpEnvelope!=NULL) delete (NoteVoicePar[nvoice].FMAmpEnvelope); - NoteVoicePar[nvoice].FMAmpEnvelope=NULL; - - if ((NoteVoicePar[nvoice].FMEnabled!=NONE)&&(NoteVoicePar[nvoice].FMVoice<0)) delete []NoteVoicePar[nvoice].FMSmp; - - if (NoteVoicePar[nvoice].VoiceOut!=NULL) - memset(NoteVoicePar[nvoice].VoiceOut, 0, SOUND_BUFFER_SIZE * sizeof(REALTYPE));//do not delete, yet: perhaps is used by another voice - - NoteVoicePar[nvoice].Enabled=OFF; -}; + delete [] oscfreqhi[nvoice]; + delete [] oscfreqlo[nvoice]; + delete [] oscfreqhiFM[nvoice]; + delete [] oscfreqloFM[nvoice]; + delete [] oscposhi[nvoice]; + delete [] oscposlo[nvoice]; + delete [] oscposhiFM[nvoice]; + delete [] oscposloFM[nvoice]; + + delete [] NoteVoicePar[nvoice].OscilSmp; + delete [] unison_base_freq_rap[nvoice]; + delete [] unison_freq_rap[nvoice]; + delete [] unison_invert_phase[nvoice]; + delete [] FMoldsmp[nvoice]; + delete [] unison_vibratto[nvoice].step; + delete [] unison_vibratto[nvoice].position; + + if(NoteVoicePar[nvoice].FreqEnvelope != NULL) + delete (NoteVoicePar[nvoice].FreqEnvelope); + NoteVoicePar[nvoice].FreqEnvelope = NULL; + + if(NoteVoicePar[nvoice].FreqLfo != NULL) + delete (NoteVoicePar[nvoice].FreqLfo); + NoteVoicePar[nvoice].FreqLfo = NULL; + + if(NoteVoicePar[nvoice].AmpEnvelope != NULL) + delete (NoteVoicePar[nvoice].AmpEnvelope); + NoteVoicePar[nvoice].AmpEnvelope = NULL; + + if(NoteVoicePar[nvoice].AmpLfo != NULL) + delete (NoteVoicePar[nvoice].AmpLfo); + NoteVoicePar[nvoice].AmpLfo = NULL; + + if(NoteVoicePar[nvoice].VoiceFilterL != NULL) + delete (NoteVoicePar[nvoice].VoiceFilterL); + NoteVoicePar[nvoice].VoiceFilterL = NULL; + + if(NoteVoicePar[nvoice].VoiceFilterR != NULL) + delete (NoteVoicePar[nvoice].VoiceFilterR); + NoteVoicePar[nvoice].VoiceFilterR = NULL; + + if(NoteVoicePar[nvoice].FilterEnvelope != NULL) + delete (NoteVoicePar[nvoice].FilterEnvelope); + NoteVoicePar[nvoice].FilterEnvelope = NULL; + + if(NoteVoicePar[nvoice].FilterLfo != NULL) + delete (NoteVoicePar[nvoice].FilterLfo); + NoteVoicePar[nvoice].FilterLfo = NULL; + + if(NoteVoicePar[nvoice].FMFreqEnvelope != NULL) + delete (NoteVoicePar[nvoice].FMFreqEnvelope); + NoteVoicePar[nvoice].FMFreqEnvelope = NULL; + + if(NoteVoicePar[nvoice].FMAmpEnvelope != NULL) + delete (NoteVoicePar[nvoice].FMAmpEnvelope); + NoteVoicePar[nvoice].FMAmpEnvelope = NULL; + + if((NoteVoicePar[nvoice].FMEnabled != NONE) + && (NoteVoicePar[nvoice].FMVoice < 0)) + delete [] NoteVoicePar[nvoice].FMSmp; + + if(NoteVoicePar[nvoice].VoiceOut != NULL) + memset(NoteVoicePar[nvoice].VoiceOut, 0, SOUND_BUFFER_SIZE + * sizeof(REALTYPE)); //do not delete, yet: perhaps is used by another voice + + NoteVoicePar[nvoice].Enabled = OFF; +} /* * Kill the note @@ -601,38 +786,41 @@ void ADnote::KillVoice(int nvoice) void ADnote::KillNote() { int nvoice; - for (nvoice=0;nvoice<NUM_VOICES;nvoice++) { - if (NoteVoicePar[nvoice].Enabled==ON) KillVoice(nvoice); + for(nvoice = 0; nvoice < NUM_VOICES; nvoice++) { + if(NoteVoicePar[nvoice].Enabled == ON) + KillVoice(nvoice); //delete VoiceOut - if (NoteVoicePar[nvoice].VoiceOut!=NULL) delete(NoteVoicePar[nvoice].VoiceOut); - NoteVoicePar[nvoice].VoiceOut=NULL; - }; + if(NoteVoicePar[nvoice].VoiceOut != NULL) + delete (NoteVoicePar[nvoice].VoiceOut); + NoteVoicePar[nvoice].VoiceOut = NULL; + } delete (NoteGlobalPar.FreqEnvelope); delete (NoteGlobalPar.FreqLfo); delete (NoteGlobalPar.AmpEnvelope); delete (NoteGlobalPar.AmpLfo); delete (NoteGlobalPar.GlobalFilterL); - if (stereo!=0) delete (NoteGlobalPar.GlobalFilterR); + if(stereo != 0) + delete (NoteGlobalPar.GlobalFilterR); delete (NoteGlobalPar.FilterEnvelope); delete (NoteGlobalPar.FilterLfo); - NoteEnabled=OFF; -}; + NoteEnabled = OFF; +} ADnote::~ADnote() { - if (NoteEnabled==ON) KillNote(); + if(NoteEnabled == ON) + KillNote(); delete [] tmpwavel; delete [] tmpwaver; delete [] bypassl; delete [] bypassr; - for (int k=0;k<max_unison;k++) delete[]tmpwave_unison[k]; - delete[]tmpwave_unison; - - -}; + for(int k = 0; k < max_unison; k++) + delete[] tmpwave_unison[k]; + delete[] tmpwave_unison; +} /* @@ -640,330 +828,421 @@ ADnote::~ADnote() */ void ADnote::initparameters() { - int nvoice,i,tmp[NUM_VOICES]; + int nvoice, i, tmp[NUM_VOICES]; // Global Parameters - NoteGlobalPar.FreqEnvelope=new Envelope(partparams->GlobalPar.FreqEnvelope,basefreq); - NoteGlobalPar.FreqLfo=new LFO(partparams->GlobalPar.FreqLfo,basefreq); - - NoteGlobalPar.AmpEnvelope=new Envelope(partparams->GlobalPar.AmpEnvelope,basefreq); - NoteGlobalPar.AmpLfo=new LFO(partparams->GlobalPar.AmpLfo,basefreq); - - NoteGlobalPar.Volume=4.0*pow(0.1,3.0*(1.0-partparams->GlobalPar.PVolume/96.0))//-60 dB .. 0 dB - *VelF(velocity,partparams->GlobalPar.PAmpVelocityScaleFunction);//velocity sensing - - NoteGlobalPar.AmpEnvelope->envout_dB();//discard the first envelope output - globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); - - NoteGlobalPar.GlobalFilterL=new Filter(partparams->GlobalPar.GlobalFilter); - if (stereo!=0) NoteGlobalPar.GlobalFilterR=new Filter(partparams->GlobalPar.GlobalFilter); - - NoteGlobalPar.FilterEnvelope=new Envelope(partparams->GlobalPar.FilterEnvelope,basefreq); - NoteGlobalPar.FilterLfo=new LFO(partparams->GlobalPar.FilterLfo,basefreq); - NoteGlobalPar.FilterQ=partparams->GlobalPar.GlobalFilter->getq(); - NoteGlobalPar.FilterFreqTracking=partparams->GlobalPar.GlobalFilter->getfreqtracking(basefreq); + NoteGlobalPar.FreqEnvelope = new Envelope( + partparams->GlobalPar.FreqEnvelope, + basefreq); + NoteGlobalPar.FreqLfo = new LFO(partparams->GlobalPar.FreqLfo, + basefreq); + + NoteGlobalPar.AmpEnvelope = new Envelope(partparams->GlobalPar.AmpEnvelope, + basefreq); + NoteGlobalPar.AmpLfo = new LFO(partparams->GlobalPar.AmpLfo, basefreq); + + NoteGlobalPar.Volume = 4.0 + * pow(0.1, 3.0 + * (1.0 - partparams->GlobalPar.PVolume / 96.0)) //-60 dB .. 0 dB + * VelF( + velocity, + partparams->GlobalPar. + PAmpVelocityScaleFunction); //velocity sensing + + NoteGlobalPar.AmpEnvelope->envout_dB(); //discard the first envelope output + globalnewamplitude = NoteGlobalPar.Volume + * NoteGlobalPar.AmpEnvelope->envout_dB() + * NoteGlobalPar.AmpLfo->amplfoout(); + + NoteGlobalPar.GlobalFilterL = new Filter(partparams->GlobalPar.GlobalFilter); + if(stereo != 0) + NoteGlobalPar.GlobalFilterR = new Filter( + partparams->GlobalPar.GlobalFilter); + + NoteGlobalPar.FilterEnvelope = new Envelope( + partparams->GlobalPar.FilterEnvelope, + basefreq); + NoteGlobalPar.FilterLfo = new LFO(partparams->GlobalPar.FilterLfo, + basefreq); + NoteGlobalPar.FilterQ = partparams->GlobalPar.GlobalFilter->getq(); + NoteGlobalPar.FilterFreqTracking = + partparams->GlobalPar.GlobalFilter->getfreqtracking(basefreq); // Forbids the Modulation Voice to be greater or equal than voice - for (i=0;i<NUM_VOICES;i++) if (NoteVoicePar[i].FMVoice>=i) NoteVoicePar[i].FMVoice=-1; + for(i = 0; i < NUM_VOICES; i++) + if(NoteVoicePar[i].FMVoice >= i) + NoteVoicePar[i].FMVoice = -1; // Voice Parameter init - for (nvoice=0;nvoice<NUM_VOICES;nvoice++) { - if (NoteVoicePar[nvoice].Enabled==0) continue; + for(nvoice = 0; nvoice < NUM_VOICES; nvoice++) { + if(NoteVoicePar[nvoice].Enabled == 0) + continue; - NoteVoicePar[nvoice].noisetype=partparams->VoicePar[nvoice].Type; + NoteVoicePar[nvoice].noisetype = partparams->VoicePar[nvoice].Type; /* Voice Amplitude Parameters Init */ - NoteVoicePar[nvoice].Volume=pow(0.1,3.0*(1.0-partparams->VoicePar[nvoice].PVolume/127.0)) // -60 dB .. 0 dB - *VelF(velocity,partparams->VoicePar[nvoice].PAmpVelocityScaleFunction);//velocity - - if (partparams->VoicePar[nvoice].PVolumeminus!=0) NoteVoicePar[nvoice].Volume=-NoteVoicePar[nvoice].Volume; - - if (partparams->VoicePar[nvoice].PPanning==0) - NoteVoicePar[nvoice].Panning=RND;// random panning - else NoteVoicePar[nvoice].Panning=partparams->VoicePar[nvoice].PPanning/128.0; - - newamplitude[nvoice]=1.0; - if (partparams->VoicePar[nvoice].PAmpEnvelopeEnabled!=0) { - NoteVoicePar[nvoice].AmpEnvelope=new Envelope(partparams->VoicePar[nvoice].AmpEnvelope,basefreq); - NoteVoicePar[nvoice].AmpEnvelope->envout_dB();//discard the first envelope sample - newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); - }; + NoteVoicePar[nvoice].Volume = + pow(0.1, 3.0 * (1.0 - partparams->VoicePar[nvoice].PVolume / 127.0)) // -60 dB .. 0 dB + * VelF(velocity, + partparams->VoicePar[nvoice].PAmpVelocityScaleFunction); //velocity + + if(partparams->VoicePar[nvoice].PVolumeminus != 0) + NoteVoicePar[nvoice].Volume = -NoteVoicePar[nvoice].Volume; + + if(partparams->VoicePar[nvoice].PPanning == 0) + NoteVoicePar[nvoice].Panning = RND; // random panning + else + NoteVoicePar[nvoice].Panning = + partparams->VoicePar[nvoice].PPanning / 128.0; + + newamplitude[nvoice] = 1.0; + if(partparams->VoicePar[nvoice].PAmpEnvelopeEnabled != 0) { + NoteVoicePar[nvoice].AmpEnvelope = new Envelope( + partparams->VoicePar[nvoice].AmpEnvelope, + basefreq); + NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); //discard the first envelope sample + newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); + } - if (partparams->VoicePar[nvoice].PAmpLfoEnabled!=0) { - NoteVoicePar[nvoice].AmpLfo=new LFO(partparams->VoicePar[nvoice].AmpLfo,basefreq); - newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpLfo->amplfoout(); - }; + if(partparams->VoicePar[nvoice].PAmpLfoEnabled != 0) { + NoteVoicePar[nvoice].AmpLfo = new LFO( + partparams->VoicePar[nvoice].AmpLfo, + basefreq); + newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpLfo->amplfoout(); + } /* Voice Frequency Parameters Init */ - if (partparams->VoicePar[nvoice].PFreqEnvelopeEnabled!=0) - NoteVoicePar[nvoice].FreqEnvelope=new Envelope(partparams->VoicePar[nvoice].FreqEnvelope,basefreq); + if(partparams->VoicePar[nvoice].PFreqEnvelopeEnabled != 0) + NoteVoicePar[nvoice].FreqEnvelope = new Envelope( + partparams->VoicePar[nvoice].FreqEnvelope, + basefreq); - if (partparams->VoicePar[nvoice].PFreqLfoEnabled!=0) NoteVoicePar[nvoice].FreqLfo=new LFO(partparams->VoicePar[nvoice].FreqLfo,basefreq); + if(partparams->VoicePar[nvoice].PFreqLfoEnabled != 0) + NoteVoicePar[nvoice].FreqLfo = new LFO( + partparams->VoicePar[nvoice].FreqLfo, + basefreq); /* Voice Filter Parameters Init */ - if (partparams->VoicePar[nvoice].PFilterEnabled!=0) { - NoteVoicePar[nvoice].VoiceFilterL=new Filter(partparams->VoicePar[nvoice].VoiceFilter); - NoteVoicePar[nvoice].VoiceFilterR=new Filter(partparams->VoicePar[nvoice].VoiceFilter); - }; + if(partparams->VoicePar[nvoice].PFilterEnabled != 0) { + NoteVoicePar[nvoice].VoiceFilterL = new Filter( + partparams->VoicePar[nvoice].VoiceFilter); + NoteVoicePar[nvoice].VoiceFilterR = new Filter( + partparams->VoicePar[nvoice].VoiceFilter); + } - if (partparams->VoicePar[nvoice].PFilterEnvelopeEnabled!=0) - NoteVoicePar[nvoice].FilterEnvelope=new Envelope(partparams->VoicePar[nvoice].FilterEnvelope,basefreq); + if(partparams->VoicePar[nvoice].PFilterEnvelopeEnabled != 0) + NoteVoicePar[nvoice].FilterEnvelope = new Envelope( + partparams->VoicePar[nvoice].FilterEnvelope, + basefreq); - if (partparams->VoicePar[nvoice].PFilterLfoEnabled!=0) - NoteVoicePar[nvoice].FilterLfo=new LFO(partparams->VoicePar[nvoice].FilterLfo,basefreq); + if(partparams->VoicePar[nvoice].PFilterLfoEnabled != 0) + NoteVoicePar[nvoice].FilterLfo = + new LFO(partparams->VoicePar[nvoice].FilterLfo, basefreq); - NoteVoicePar[nvoice].FilterFreqTracking=partparams->VoicePar[nvoice].VoiceFilter->getfreqtracking(basefreq); + NoteVoicePar[nvoice].FilterFreqTracking = + partparams->VoicePar[nvoice].VoiceFilter->getfreqtracking(basefreq); /* Voice Modulation Parameters Init */ - if ((NoteVoicePar[nvoice].FMEnabled!=NONE)&&(NoteVoicePar[nvoice].FMVoice<0)) { + if((NoteVoicePar[nvoice].FMEnabled != NONE) + && (NoteVoicePar[nvoice].FMVoice < 0)) { partparams->VoicePar[nvoice].FMSmp->newrandseed(rand()); - NoteVoicePar[nvoice].FMSmp=new REALTYPE[OSCIL_SIZE+OSCIL_SMP_EXTRA_SAMPLES]; + NoteVoicePar[nvoice].FMSmp = + new REALTYPE[OSCIL_SIZE + OSCIL_SMP_EXTRA_SAMPLES]; //Perform Anti-aliasing only on MORPH or RING MODULATION - int vc=nvoice; - if (partparams->VoicePar[nvoice].PextFMoscil!=-1) vc=partparams->VoicePar[nvoice].PextFMoscil; - - REALTYPE tmp=1.0; - if ((partparams->VoicePar[vc].FMSmp->Padaptiveharmonics!=0)|| - (NoteVoicePar[nvoice].FMEnabled==MORPH)|| - (NoteVoicePar[nvoice].FMEnabled==RING_MOD)) { - tmp=getFMvoicebasefreq(nvoice); - }; - if (!partparams->GlobalPar.Hrandgrouping) partparams->VoicePar[vc].FMSmp->newrandseed(rand()); - - for (int k=0;k<unison_size[nvoice];k++){ - oscposhiFM[nvoice][k]=(oscposhi[nvoice][k]+partparams->VoicePar[vc].FMSmp->get(NoteVoicePar[nvoice].FMSmp,tmp)) % OSCIL_SIZE; - }; - for (int i=0;i<OSCIL_SMP_EXTRA_SAMPLES;i++) NoteVoicePar[nvoice].FMSmp[OSCIL_SIZE+i]=NoteVoicePar[nvoice].FMSmp[i]; - int oscposhiFM_add=(int)((partparams->VoicePar[nvoice].PFMoscilphase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE*4); - for (int k=0;k<unison_size[nvoice];k++){ - oscposhiFM[nvoice][k]+=oscposhiFM_add; - oscposhiFM[nvoice][k]%=OSCIL_SIZE; - }; - }; + int vc = nvoice; + if(partparams->VoicePar[nvoice].PextFMoscil != -1) + vc = partparams->VoicePar[nvoice].PextFMoscil; + + REALTYPE tmp = 1.0; + if((partparams->VoicePar[vc].FMSmp->Padaptiveharmonics != 0) + || (NoteVoicePar[nvoice].FMEnabled == MORPH) + || (NoteVoicePar[nvoice].FMEnabled == RING_MOD)) + tmp = getFMvoicebasefreq(nvoice); + ; + if(!partparams->GlobalPar.Hrandgrouping) + partparams->VoicePar[vc].FMSmp->newrandseed(rand()); + + for(int k = 0; k < unison_size[nvoice]; k++) + oscposhiFM[nvoice][k] = + (oscposhi[nvoice][k] + + partparams->VoicePar[vc].FMSmp->get(NoteVoicePar[nvoice] + . + FMSmp, + tmp)) % OSCIL_SIZE; + ; + for(int i = 0; i < OSCIL_SMP_EXTRA_SAMPLES; i++) + NoteVoicePar[nvoice].FMSmp[OSCIL_SIZE + + i] = NoteVoicePar[nvoice].FMSmp[i]; + int oscposhiFM_add = + (int)((partparams->VoicePar[nvoice].PFMoscilphase + - 64.0) / 128.0 * OSCIL_SIZE + OSCIL_SIZE * 4); + for(int k = 0; k < unison_size[nvoice]; k++) { + oscposhiFM[nvoice][k] += oscposhiFM_add; + oscposhiFM[nvoice][k] %= OSCIL_SIZE; + } + } - if (partparams->VoicePar[nvoice].PFMFreqEnvelopeEnabled!=0) - NoteVoicePar[nvoice].FMFreqEnvelope=new Envelope(partparams->VoicePar[nvoice].FMFreqEnvelope,basefreq); + if(partparams->VoicePar[nvoice].PFMFreqEnvelopeEnabled != 0) + NoteVoicePar[nvoice].FMFreqEnvelope = new Envelope( + partparams->VoicePar[nvoice].FMFreqEnvelope, + basefreq); - FMnewamplitude[nvoice]=NoteVoicePar[nvoice].FMVolume*ctl->fmamp.relamp; + FMnewamplitude[nvoice] = NoteVoicePar[nvoice].FMVolume + * ctl->fmamp.relamp; - if (partparams->VoicePar[nvoice].PFMAmpEnvelopeEnabled!=0) { - NoteVoicePar[nvoice].FMAmpEnvelope=new Envelope(partparams->VoicePar[nvoice].FMAmpEnvelope,basefreq); - FMnewamplitude[nvoice]*=NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB(); - }; - }; + if(partparams->VoicePar[nvoice].PFMAmpEnvelopeEnabled != 0) { + NoteVoicePar[nvoice].FMAmpEnvelope = new Envelope( + partparams->VoicePar[nvoice].FMAmpEnvelope, + basefreq); + FMnewamplitude[nvoice] *= + NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB(); + } + } + + for(nvoice = 0; nvoice < NUM_VOICES; nvoice++) { + for(i = nvoice + 1; i < NUM_VOICES; i++) + tmp[i] = 0; + for(i = nvoice + 1; i < NUM_VOICES; i++) + if((NoteVoicePar[i].FMVoice == nvoice) && (tmp[i] == 0)) { + NoteVoicePar[nvoice].VoiceOut = new REALTYPE[SOUND_BUFFER_SIZE]; + tmp[i] = 1; + } + ; + if(NoteVoicePar[nvoice].VoiceOut != NULL) + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + NoteVoicePar[nvoice].VoiceOut[i] = 0.0; + } +} - for (nvoice=0;nvoice<NUM_VOICES;nvoice++) { - for (i=nvoice+1;i<NUM_VOICES;i++) tmp[i]=0; - for (i=nvoice+1;i<NUM_VOICES;i++) - if ((NoteVoicePar[i].FMVoice==nvoice)&&(tmp[i]==0)) { - NoteVoicePar[nvoice].VoiceOut=new REALTYPE[SOUND_BUFFER_SIZE]; - tmp[i]=1; - }; - if (NoteVoicePar[nvoice].VoiceOut!=NULL) for (i=0;i<SOUND_BUFFER_SIZE;i++) NoteVoicePar[nvoice].VoiceOut[i]=0.0; - }; -}; - /* * Computes the relative frequency of each unison voice and it's vibratto * This must be called before setfreq* functions */ -void ADnote::compute_unison_freq_rap(int nvoice){ - if (unison_size[nvoice]==1){//no unison - unison_freq_rap[nvoice][0]=1.0; - return; - }; - REALTYPE relbw=ctl->bandwidth.relbw*bandwidthDetuneMultiplier; - for (int k=0;k<unison_size[nvoice];k++){ - REALTYPE pos=unison_vibratto[nvoice].position[k]; - REALTYPE step=unison_vibratto[nvoice].step[k]; - pos+=step; - if (pos<=-1.0) { - pos=-1.0; - step=-step; - }; - if (pos>=1.0){ - pos=1.0; - step=-step; - }; - REALTYPE vibratto_val=(pos-0.333333333*pos*pos*pos)*1.5;//make the vibratto lfo smoother - unison_freq_rap[nvoice][k]=1.0+((unison_base_freq_rap[nvoice][k]-1.0)+vibratto_val*unison_vibratto[nvoice].amplitude)*relbw; - - unison_vibratto[nvoice].position[k]=pos; - step=unison_vibratto[nvoice].step[k]=step; - }; - -}; +void ADnote::compute_unison_freq_rap(int nvoice) { + if(unison_size[nvoice] == 1) { //no unison + unison_freq_rap[nvoice][0] = 1.0; + return; + } + REALTYPE relbw = ctl->bandwidth.relbw * bandwidthDetuneMultiplier; + for(int k = 0; k < unison_size[nvoice]; k++) { + REALTYPE pos = unison_vibratto[nvoice].position[k]; + REALTYPE step = unison_vibratto[nvoice].step[k]; + pos += step; + if(pos <= -1.0) { + pos = -1.0; + step = -step; + } + if(pos >= 1.0) { + pos = 1.0; + step = -step; + } + REALTYPE vibratto_val = (pos - 0.333333333 * pos * pos * pos) * 1.5; //make the vibratto lfo smoother + unison_freq_rap[nvoice][k] = 1.0 + + ((unison_base_freq_rap[nvoice][k] + - 1.0) + vibratto_val + * unison_vibratto[nvoice].amplitude) + * relbw; + + unison_vibratto[nvoice].position[k] = pos; + step = unison_vibratto[nvoice].step[k] = step; + } +} /* * Computes the frequency of an oscillator */ -void ADnote::setfreq(int nvoice,REALTYPE in_freq) +void ADnote::setfreq(int nvoice, REALTYPE in_freq) { - for (int k=0;k<unison_size[nvoice];k++){ - REALTYPE freq=fabs(in_freq)*unison_freq_rap[nvoice][k]; - REALTYPE speed=freq*REALTYPE(OSCIL_SIZE)/(REALTYPE) SAMPLE_RATE; - if (speed>OSCIL_SIZE) speed=OSCIL_SIZE; - - F2I(speed,oscfreqhi[nvoice][k]); - oscfreqlo[nvoice][k]=speed-floor(speed); - }; -}; + for(int k = 0; k < unison_size[nvoice]; k++) { + REALTYPE freq = fabs(in_freq) * unison_freq_rap[nvoice][k]; + REALTYPE speed = freq * REALTYPE(OSCIL_SIZE) / (REALTYPE) SAMPLE_RATE; + if(speed > OSCIL_SIZE) + speed = OSCIL_SIZE; + + F2I(speed, oscfreqhi[nvoice][k]); + oscfreqlo[nvoice][k] = speed - floor(speed); + } +} /* * Computes the frequency of an modullator oscillator */ -void ADnote::setfreqFM(int nvoice,REALTYPE in_freq) +void ADnote::setfreqFM(int nvoice, REALTYPE in_freq) { - for (int k=0;k<unison_size[nvoice];k++){ - REALTYPE freq=fabs(in_freq)*unison_freq_rap[nvoice][k]; - REALTYPE speed=freq*REALTYPE(OSCIL_SIZE)/(REALTYPE) SAMPLE_RATE; - if (speed>OSCIL_SIZE) speed=OSCIL_SIZE; - - F2I(speed,oscfreqhiFM[nvoice][k]); - oscfreqloFM[nvoice][k]=speed-floor(speed); - }; -}; + for(int k = 0; k < unison_size[nvoice]; k++) { + REALTYPE freq = fabs(in_freq) * unison_freq_rap[nvoice][k]; + REALTYPE speed = freq * REALTYPE(OSCIL_SIZE) / (REALTYPE) SAMPLE_RATE; + if(speed > OSCIL_SIZE) + speed = OSCIL_SIZE; + + F2I(speed, oscfreqhiFM[nvoice][k]); + oscfreqloFM[nvoice][k] = speed - floor(speed); + } +} /* * Get Voice base frequency */ REALTYPE ADnote::getvoicebasefreq(int nvoice) const { - REALTYPE detune=NoteVoicePar[nvoice].Detune/100.0+ - NoteVoicePar[nvoice].FineDetune/100.0*ctl->bandwidth.relbw*bandwidthDetuneMultiplier+ - NoteGlobalPar.Detune/100.0; - - if (NoteVoicePar[nvoice].fixedfreq==0) return(this->basefreq*pow(2,detune/12.0)); - else {//the fixed freq is enabled - REALTYPE fixedfreq=440.0; - int fixedfreqET=NoteVoicePar[nvoice].fixedfreqET; - if (fixedfreqET!=0) {//if the frequency varies according the keyboard note - REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0); - if (fixedfreqET<=64) fixedfreq*=pow(2.0,tmp); - else fixedfreq*=pow(3.0,tmp); - }; - return(fixedfreq*pow(2.0,detune/12.0)); - }; -}; + REALTYPE detune = NoteVoicePar[nvoice].Detune / 100.0 + + NoteVoicePar[nvoice].FineDetune / 100.0 + * ctl->bandwidth.relbw * bandwidthDetuneMultiplier + + NoteGlobalPar.Detune / 100.0; + + if(NoteVoicePar[nvoice].fixedfreq == 0) + return this->basefreq * pow(2, detune / 12.0); + else { //the fixed freq is enabled + REALTYPE fixedfreq = 440.0; + int fixedfreqET = NoteVoicePar[nvoice].fixedfreqET; + if(fixedfreqET != 0) { //if the frequency varies according the keyboard note + REALTYPE tmp = + (midinote + - 69.0) / 12.0 * (pow(2.0, (fixedfreqET - 1) / 63.0) - 1.0); + if(fixedfreqET <= 64) + fixedfreq *= pow(2.0, tmp); + else + fixedfreq *= pow(3.0, tmp); + } + return fixedfreq * pow(2.0, detune / 12.0); + } +} /* * Get Voice's Modullator base frequency */ REALTYPE ADnote::getFMvoicebasefreq(int nvoice) const { - REALTYPE detune=NoteVoicePar[nvoice].FMDetune/100.0; - return(getvoicebasefreq(nvoice)*pow(2,detune/12.0)); -}; + REALTYPE detune = NoteVoicePar[nvoice].FMDetune / 100.0; + return getvoicebasefreq(nvoice) * pow(2, detune / 12.0); +} /* * Computes all the parameters for each tick */ void ADnote::computecurrentparameters() { - int nvoice; - REALTYPE voicefreq,voicepitch,filterpitch,filterfreq,FMfreq,FMrelativepitch,globalpitch,globalfilterpitch; - globalpitch=0.01*(NoteGlobalPar.FreqEnvelope->envout()+ - NoteGlobalPar.FreqLfo->lfoout()*ctl->modwheel.relmod); - globaloldamplitude=globalnewamplitude; - globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); - - globalfilterpitch=NoteGlobalPar.FilterEnvelope->envout()+NoteGlobalPar.FilterLfo->lfoout() - +NoteGlobalPar.FilterCenterPitch; - - REALTYPE tmpfilterfreq=globalfilterpitch+ctl->filtercutoff.relfreq - +NoteGlobalPar.FilterFreqTracking; - - tmpfilterfreq=NoteGlobalPar.GlobalFilterL->getrealfreq(tmpfilterfreq); - - REALTYPE globalfilterq=NoteGlobalPar.FilterQ*ctl->filterq.relq; - NoteGlobalPar.GlobalFilterL->setfreq_and_q(tmpfilterfreq,globalfilterq); - if (stereo!=0) NoteGlobalPar.GlobalFilterR->setfreq_and_q(tmpfilterfreq,globalfilterq); + int nvoice; + REALTYPE voicefreq, voicepitch, filterpitch, filterfreq, FMfreq, + FMrelativepitch, globalpitch, globalfilterpitch; + globalpitch = 0.01 * (NoteGlobalPar.FreqEnvelope->envout() + + NoteGlobalPar.FreqLfo->lfoout() + * ctl->modwheel.relmod); + globaloldamplitude = globalnewamplitude; + globalnewamplitude = NoteGlobalPar.Volume + * NoteGlobalPar.AmpEnvelope->envout_dB() + * NoteGlobalPar.AmpLfo->amplfoout(); + + globalfilterpitch = NoteGlobalPar.FilterEnvelope->envout() + + NoteGlobalPar.FilterLfo->lfoout() + + NoteGlobalPar.FilterCenterPitch; + + REALTYPE tmpfilterfreq = globalfilterpitch + ctl->filtercutoff.relfreq + + NoteGlobalPar.FilterFreqTracking; + + tmpfilterfreq = NoteGlobalPar.GlobalFilterL->getrealfreq(tmpfilterfreq); + + REALTYPE globalfilterq = NoteGlobalPar.FilterQ * ctl->filterq.relq; + NoteGlobalPar.GlobalFilterL->setfreq_and_q(tmpfilterfreq, globalfilterq); + if(stereo != 0) + NoteGlobalPar.GlobalFilterR->setfreq_and_q(tmpfilterfreq, globalfilterq); //compute the portamento, if it is used by this note - REALTYPE portamentofreqrap=1.0; - if (portamento!=0) {//this voice use portamento - portamentofreqrap=ctl->portamento.freqrap; - if (ctl->portamento.used==0) {//the portamento has finished - portamento=0;//this note is no longer "portamented" - }; - }; + REALTYPE portamentofreqrap = 1.0; + if(portamento != 0) { //this voice use portamento + portamentofreqrap = ctl->portamento.freqrap; + if(ctl->portamento.used == 0) //the portamento has finished + portamento = 0; //this note is no longer "portamented" + ; + } //compute parameters for all voices - for (nvoice=0;nvoice<NUM_VOICES;nvoice++) { - if (NoteVoicePar[nvoice].Enabled!=ON) continue; - NoteVoicePar[nvoice].DelayTicks-=1; - if (NoteVoicePar[nvoice].DelayTicks>0) continue; + for(nvoice = 0; nvoice < NUM_VOICES; nvoice++) { + if(NoteVoicePar[nvoice].Enabled != ON) + continue; + NoteVoicePar[nvoice].DelayTicks -= 1; + if(NoteVoicePar[nvoice].DelayTicks > 0) + continue; - compute_unison_freq_rap(nvoice); + compute_unison_freq_rap(nvoice); /*******************/ /* Voice Amplitude */ /*******************/ - oldamplitude[nvoice]=newamplitude[nvoice]; - newamplitude[nvoice]=1.0; + oldamplitude[nvoice] = newamplitude[nvoice]; + newamplitude[nvoice] = 1.0; - if (NoteVoicePar[nvoice].AmpEnvelope!=NULL) - newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); + if(NoteVoicePar[nvoice].AmpEnvelope != NULL) + newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); - if (NoteVoicePar[nvoice].AmpLfo!=NULL) - newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpLfo->amplfoout(); + if(NoteVoicePar[nvoice].AmpLfo != NULL) + newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpLfo->amplfoout(); /****************/ /* Voice Filter */ /****************/ - if (NoteVoicePar[nvoice].VoiceFilterL!=NULL) { - filterpitch=NoteVoicePar[nvoice].FilterCenterPitch; + if(NoteVoicePar[nvoice].VoiceFilterL != NULL) { + filterpitch = NoteVoicePar[nvoice].FilterCenterPitch; - if (NoteVoicePar[nvoice].FilterEnvelope!=NULL) - filterpitch+=NoteVoicePar[nvoice].FilterEnvelope->envout(); + if(NoteVoicePar[nvoice].FilterEnvelope != NULL) + filterpitch += NoteVoicePar[nvoice].FilterEnvelope->envout(); - if (NoteVoicePar[nvoice].FilterLfo!=NULL) - filterpitch+=NoteVoicePar[nvoice].FilterLfo->lfoout(); + if(NoteVoicePar[nvoice].FilterLfo != NULL) + filterpitch += NoteVoicePar[nvoice].FilterLfo->lfoout(); - filterfreq=filterpitch+NoteVoicePar[nvoice].FilterFreqTracking; - filterfreq=NoteVoicePar[nvoice].VoiceFilterL->getrealfreq(filterfreq); + filterfreq = filterpitch + NoteVoicePar[nvoice].FilterFreqTracking; + filterfreq = NoteVoicePar[nvoice].VoiceFilterL->getrealfreq( + filterfreq); NoteVoicePar[nvoice].VoiceFilterL->setfreq(filterfreq); - if (stereo&&NoteVoicePar[nvoice].VoiceFilterR) NoteVoicePar[nvoice].VoiceFilterR->setfreq(filterfreq); - }; - - if (NoteVoicePar[nvoice].noisetype==0) {//compute only if the voice isn't noise + if(stereo && NoteVoicePar[nvoice].VoiceFilterR) + NoteVoicePar[nvoice].VoiceFilterR->setfreq(filterfreq); + } + if(NoteVoicePar[nvoice].noisetype == 0) { //compute only if the voice isn't noise /*******************/ /* Voice Frequency */ /*******************/ - voicepitch=0.0; - if (NoteVoicePar[nvoice].FreqLfo!=NULL) - voicepitch+=NoteVoicePar[nvoice].FreqLfo->lfoout()/100.0 - *ctl->bandwidth.relbw; - - if (NoteVoicePar[nvoice].FreqEnvelope!=NULL) voicepitch+=NoteVoicePar[nvoice].FreqEnvelope->envout()/100.0; - voicefreq=getvoicebasefreq(nvoice)*pow(2,(voicepitch+globalpitch)/12.0);//Hz frequency - voicefreq*=ctl->pitchwheel.relfreq;//change the frequency by the controller - setfreq(nvoice,voicefreq*portamentofreqrap); + voicepitch = 0.0; + if(NoteVoicePar[nvoice].FreqLfo != NULL) + voicepitch += NoteVoicePar[nvoice].FreqLfo->lfoout() / 100.0 + * ctl->bandwidth.relbw; + + if(NoteVoicePar[nvoice].FreqEnvelope != NULL) + voicepitch += NoteVoicePar[nvoice].FreqEnvelope->envout() + / 100.0; + voicefreq = getvoicebasefreq(nvoice) + * pow(2, (voicepitch + globalpitch) / 12.0); //Hz frequency + voicefreq *= ctl->pitchwheel.relfreq; //change the frequency by the controller + setfreq(nvoice, voicefreq * portamentofreqrap); /***************/ /* Modulator */ /***************/ - if (NoteVoicePar[nvoice].FMEnabled!=NONE) { - FMrelativepitch=NoteVoicePar[nvoice].FMDetune/100.0; - if (NoteVoicePar[nvoice].FMFreqEnvelope!=NULL) FMrelativepitch+=NoteVoicePar[nvoice].FMFreqEnvelope->envout()/100; - FMfreq=pow(2.0,FMrelativepitch/12.0)*voicefreq*portamentofreqrap; - setfreqFM(nvoice,FMfreq); - - FMoldamplitude[nvoice]=FMnewamplitude[nvoice]; - FMnewamplitude[nvoice]=NoteVoicePar[nvoice].FMVolume*ctl->fmamp.relamp; - if (NoteVoicePar[nvoice].FMAmpEnvelope!=NULL) - FMnewamplitude[nvoice]*=NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB(); - }; - }; - - }; - time+=(REALTYPE)SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE; -}; + if(NoteVoicePar[nvoice].FMEnabled != NONE) { + FMrelativepitch = NoteVoicePar[nvoice].FMDetune / 100.0; + if(NoteVoicePar[nvoice].FMFreqEnvelope != NULL) + FMrelativepitch += + NoteVoicePar[nvoice].FMFreqEnvelope->envout() / 100; + FMfreq = + pow(2.0, FMrelativepitch + / 12.0) * voicefreq * portamentofreqrap; + setfreqFM(nvoice, FMfreq); + + FMoldamplitude[nvoice] = FMnewamplitude[nvoice]; + FMnewamplitude[nvoice] = NoteVoicePar[nvoice].FMVolume + * ctl->fmamp.relamp; + if(NoteVoicePar[nvoice].FMAmpEnvelope != NULL) + FMnewamplitude[nvoice] *= + NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB(); + } + } + } + time += (REALTYPE)SOUND_BUFFER_SIZE / (REALTYPE)SAMPLE_RATE; +} /* @@ -971,51 +1250,54 @@ void ADnote::computecurrentparameters() */ inline void ADnote::fadein(REALTYPE *smps) const { - int zerocrossings=0; - for (int i=1;i<SOUND_BUFFER_SIZE;i++) - if ((smps[i-1]<0.0) && (smps[i]>0.0)) zerocrossings++;//this is only the possitive crossings + int zerocrossings = 0; + for(int i = 1; i < SOUND_BUFFER_SIZE; i++) + if((smps[i - 1] < 0.0) && (smps[i] > 0.0)) + zerocrossings++; //this is only the possitive crossings - REALTYPE tmp=(SOUND_BUFFER_SIZE-1.0)/(zerocrossings+1)/3.0; - if (tmp<8.0) tmp=8.0; + REALTYPE tmp = (SOUND_BUFFER_SIZE - 1.0) / (zerocrossings + 1) / 3.0; + if(tmp < 8.0) + tmp = 8.0; int n; - F2I(tmp,n);//how many samples is the fade-in - if (n>SOUND_BUFFER_SIZE) n=SOUND_BUFFER_SIZE; - for (int i=0;i<n;i++) {//fade-in - REALTYPE tmp=0.5-cos((REALTYPE)i/(REALTYPE) n*PI)*0.5; - smps[i]*=tmp; - }; -}; + F2I(tmp, n); //how many samples is the fade-in + if(n > SOUND_BUFFER_SIZE) + n = SOUND_BUFFER_SIZE; + for(int i = 0; i < n; i++) { //fade-in + REALTYPE tmp = 0.5 - cos((REALTYPE)i / (REALTYPE) n * PI) * 0.5; + smps[i] *= tmp; + } +} /* * Computes the Oscillator (Without Modulation) - LinearInterpolation */ inline void ADnote::ComputeVoiceOscillator_LinearInterpolation(int nvoice) { - int i,poshi; + int i, poshi; REALTYPE poslo; - - for (int k=0;k<unison_size[nvoice];k++){ - poshi=oscposhi[nvoice][k]; - poslo=oscposlo[nvoice][k]; - int freqhi=oscfreqhi[nvoice][k]; - REALTYPE freqlo=oscfreqlo[nvoice][k]; - REALTYPE *smps=NoteVoicePar[nvoice].OscilSmp; - REALTYPE *tw=tmpwave_unison[k]; - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - tw[i]=smps[poshi]*(1.0-poslo)+smps[poshi+1]*poslo; - poslo+=freqlo; - if (poslo>=1.0) { - poslo-=1.0; - poshi++; - }; - poshi+=freqhi; - poshi&=OSCIL_SIZE-1; - }; - oscposhi[nvoice][k]=poshi; - oscposlo[nvoice][k]=poslo; - }; -}; + + for(int k = 0; k < unison_size[nvoice]; k++) { + poshi = oscposhi[nvoice][k]; + poslo = oscposlo[nvoice][k]; + int freqhi = oscfreqhi[nvoice][k]; + REALTYPE freqlo = oscfreqlo[nvoice][k]; + REALTYPE *smps = NoteVoicePar[nvoice].OscilSmp; + REALTYPE *tw = tmpwave_unison[k]; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tw[i] = smps[poshi] * (1.0 - poslo) + smps[poshi + 1] * poslo; + poslo += freqlo; + if(poslo >= 1.0) { + poslo -= 1.0; + poshi++; + } + poshi += freqhi; + poshi &= OSCIL_SIZE - 1; + } + oscposhi[nvoice][k] = poshi; + oscposlo[nvoice][k] = poslo; + } +} @@ -1032,22 +1314,22 @@ inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int nvoice){ REALTYPE *smps=NoteVoicePar[nvoice].OscilSmp; REALTYPE xm1,x0,x1,x2,a,b,c; for (i=0;i<SOUND_BUFFER_SIZE;i++){ - xm1=smps[poshi]; - x0=smps[poshi+1]; - x1=smps[poshi+2]; - x2=smps[poshi+3]; - a=(3.0 * (x0-x1) - xm1 + x2) / 2.0; - b = 2.0*x1 + xm1 - (5.0*x0 + x2) / 2.0; - c = (x1 - xm1) / 2.0; - tmpwave[i]=(((a * poslo) + b) * poslo + c) * poslo + x0; - printf("a\n"); - //tmpwave[i]=smps[poshi]*(1.0-poslo)+smps[poshi+1]*poslo; - poslo+=oscfreqlo[nvoice]; - if (poslo>=1.0) { - poslo-=1.0; - poshi++; - }; - poshi+=oscfreqhi[nvoice]; + xm1=smps[poshi]; + x0=smps[poshi+1]; + x1=smps[poshi+2]; + x2=smps[poshi+3]; + a=(3.0 * (x0-x1) - xm1 + x2) / 2.0; + b = 2.0*x1 + xm1 - (5.0*x0 + x2) / 2.0; + c = (x1 - xm1) / 2.0; + tmpwave[i]=(((a * poslo) + b) * poslo + c) * poslo + x0; + printf("a\n"); + //tmpwave[i]=smps[poshi]*(1.0-poslo)+smps[poshi+1]*poslo; + poslo+=oscfreqlo[nvoice]; + if (poslo>=1.0) { + poslo-=1.0; + poshi++; + }; + poshi+=oscfreqhi[nvoice]; poshi&=OSCIL_SIZE-1; }; oscposhi[nvoice]=poshi; @@ -1059,237 +1341,269 @@ inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int nvoice){ */ inline void ADnote::ComputeVoiceOscillatorMorph(int nvoice) { - int i; + int i; REALTYPE amp; ComputeVoiceOscillator_LinearInterpolation(nvoice); - if (FMnewamplitude[nvoice]>1.0) FMnewamplitude[nvoice]=1.0; - if (FMoldamplitude[nvoice]>1.0) FMoldamplitude[nvoice]=1.0; - - if (NoteVoicePar[nvoice].FMVoice>=0) { - //if I use VoiceOut[] as modullator - int FMVoice=NoteVoicePar[nvoice].FMVoice; - for (int k=0;k<unison_size[nvoice];k++){ - REALTYPE *tw=tmpwave_unison[k]; - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - amp=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice] - ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE); - tw[i]=tw[i]*(1.0-amp)+amp*NoteVoicePar[FMVoice].VoiceOut[i]; - }; - }; - } else { - for (int k=0;k<unison_size[nvoice];k++){ - int poshiFM=oscposhiFM[nvoice][k]; - REALTYPE posloFM=oscposloFM[nvoice][k]; - int freqhiFM=oscfreqhiFM[nvoice][k]; - REALTYPE freqloFM=oscfreqloFM[nvoice][k]; - REALTYPE *tw=tmpwave_unison[k]; - - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - amp=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice] - ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE); - tw[i]=tw[i]*(1.0-amp)+amp - *(NoteVoicePar[nvoice].FMSmp[poshiFM]*(1-posloFM) - +NoteVoicePar[nvoice].FMSmp[poshiFM+1]*posloFM); - posloFM+=freqloFM; - if (posloFM>=1.0) { - posloFM-=1.0; - poshiFM++; - }; - poshiFM+=freqhiFM; - poshiFM&=OSCIL_SIZE-1; - }; - oscposhiFM[nvoice][k]=poshiFM; - oscposloFM[nvoice][k]=posloFM; - }; - }; -}; + if(FMnewamplitude[nvoice] > 1.0) + FMnewamplitude[nvoice] = 1.0; + if(FMoldamplitude[nvoice] > 1.0) + FMoldamplitude[nvoice] = 1.0; + + if(NoteVoicePar[nvoice].FMVoice >= 0) { + //if I use VoiceOut[] as modullator + int FMVoice = NoteVoicePar[nvoice].FMVoice; + for(int k = 0; k < unison_size[nvoice]; k++) { + REALTYPE *tw = tmpwave_unison[k]; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + amp = INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice], + FMnewamplitude[nvoice], + i, + SOUND_BUFFER_SIZE); + tw[i] = tw[i] + * (1.0 - amp) + amp * NoteVoicePar[FMVoice].VoiceOut[i]; + } + } + } + else { + for(int k = 0; k < unison_size[nvoice]; k++) { + int poshiFM = oscposhiFM[nvoice][k]; + REALTYPE posloFM = oscposloFM[nvoice][k]; + int freqhiFM = oscfreqhiFM[nvoice][k]; + REALTYPE freqloFM = oscfreqloFM[nvoice][k]; + REALTYPE *tw = tmpwave_unison[k]; + + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + amp = INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice], + FMnewamplitude[nvoice], + i, + SOUND_BUFFER_SIZE); + tw[i] = tw[i] * (1.0 - amp) + amp + * (NoteVoicePar[nvoice].FMSmp[poshiFM] * (1 - posloFM) + + NoteVoicePar[nvoice].FMSmp[poshiFM + 1] * posloFM); + posloFM += freqloFM; + if(posloFM >= 1.0) { + posloFM -= 1.0; + poshiFM++; + } + poshiFM += freqhiFM; + poshiFM &= OSCIL_SIZE - 1; + } + oscposhiFM[nvoice][k] = poshiFM; + oscposloFM[nvoice][k] = posloFM; + } + } +} /* * Computes the Oscillator (Ring Modulation) */ inline void ADnote::ComputeVoiceOscillatorRingModulation(int nvoice) { - int i; + int i; REALTYPE amp; ComputeVoiceOscillator_LinearInterpolation(nvoice); - if (FMnewamplitude[nvoice]>1.0) FMnewamplitude[nvoice]=1.0; - if (FMoldamplitude[nvoice]>1.0) FMoldamplitude[nvoice]=1.0; - if (NoteVoicePar[nvoice].FMVoice>=0) { - // if I use VoiceOut[] as modullator - for (int k=0;k<unison_size[nvoice];k++){ - REALTYPE *tw=tmpwave_unison[k]; - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - amp=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice] - ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE); - int FMVoice=NoteVoicePar[nvoice].FMVoice; - for (i=0;i<SOUND_BUFFER_SIZE;i++) - tw[i]*=(1.0-amp)+amp*NoteVoicePar[FMVoice].VoiceOut[i]; - }; - }; - } else { - for (int k=0;k<unison_size[nvoice];k++){ - int poshiFM=oscposhiFM[nvoice][k]; - REALTYPE posloFM=oscposloFM[nvoice][k]; - int freqhiFM=oscfreqhiFM[nvoice][k]; - REALTYPE freqloFM=oscfreqloFM[nvoice][k]; - REALTYPE *tw=tmpwave_unison[k]; - - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - amp=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice] - ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE); - tw[i]*=( NoteVoicePar[nvoice].FMSmp[poshiFM]*(1.0-posloFM) - +NoteVoicePar[nvoice].FMSmp[poshiFM+1]*posloFM)*amp - +(1.0-amp); - posloFM+=freqloFM; - if (posloFM>=1.0) { - posloFM-=1.0; - poshiFM++; - }; - poshiFM+=freqhiFM; - poshiFM&=OSCIL_SIZE-1; - }; - oscposhiFM[nvoice][k]=poshiFM; - oscposloFM[nvoice][k]=posloFM; - }; - }; -}; + if(FMnewamplitude[nvoice] > 1.0) + FMnewamplitude[nvoice] = 1.0; + if(FMoldamplitude[nvoice] > 1.0) + FMoldamplitude[nvoice] = 1.0; + if(NoteVoicePar[nvoice].FMVoice >= 0) { + // if I use VoiceOut[] as modullator + for(int k = 0; k < unison_size[nvoice]; k++) { + REALTYPE *tw = tmpwave_unison[k]; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + amp = INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice], + FMnewamplitude[nvoice], + i, + SOUND_BUFFER_SIZE); + int FMVoice = NoteVoicePar[nvoice].FMVoice; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tw[i] *= + (1.0 - amp) + amp * NoteVoicePar[FMVoice].VoiceOut[i]; + } + } + } + else { + for(int k = 0; k < unison_size[nvoice]; k++) { + int poshiFM = oscposhiFM[nvoice][k]; + REALTYPE posloFM = oscposloFM[nvoice][k]; + int freqhiFM = oscfreqhiFM[nvoice][k]; + REALTYPE freqloFM = oscfreqloFM[nvoice][k]; + REALTYPE *tw = tmpwave_unison[k]; + + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + amp = INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice], + FMnewamplitude[nvoice], + i, + SOUND_BUFFER_SIZE); + tw[i] *= (NoteVoicePar[nvoice].FMSmp[poshiFM] * (1.0 - posloFM) + + NoteVoicePar[nvoice].FMSmp[poshiFM + + 1] * posloFM) * amp + + (1.0 - amp); + posloFM += freqloFM; + if(posloFM >= 1.0) { + posloFM -= 1.0; + poshiFM++; + } + poshiFM += freqhiFM; + poshiFM &= OSCIL_SIZE - 1; + } + oscposhiFM[nvoice][k] = poshiFM; + oscposloFM[nvoice][k] = posloFM; + } + } +} /* * Computes the Oscillator (Phase Modulation or Frequency Modulation) */ -inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int nvoice,int FMmode) +inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int nvoice, + int FMmode) { - int carposhi=0; - int i,FMmodfreqhi=0; - REALTYPE FMmodfreqlo=0,carposlo=0; + int carposhi = 0; + int i, FMmodfreqhi = 0; + REALTYPE FMmodfreqlo = 0, carposlo = 0; - if (NoteVoicePar[nvoice].FMVoice>=0) { + if(NoteVoicePar[nvoice].FMVoice >= 0) { //if I use VoiceOut[] as modulator - for (int k=0;k<unison_size[nvoice];k++){ - REALTYPE *tw=tmpwave_unison[k]; - for (i=0;i<SOUND_BUFFER_SIZE;i++) tw[i]=NoteVoicePar[NoteVoicePar[nvoice].FMVoice].VoiceOut[i]; - }; - } else { - //Compute the modulator and store it in tmpwave_unison[][] - for (int k=0;k<unison_size[nvoice];k++){ - int poshiFM=oscposhiFM[nvoice][k]; - REALTYPE posloFM=oscposloFM[nvoice][k]; - int freqhiFM=oscfreqhiFM[nvoice][k]; - REALTYPE freqloFM=oscfreqloFM[nvoice][k]; - REALTYPE *tw=tmpwave_unison[k]; - - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - tw[i]=(NoteVoicePar[nvoice].FMSmp[poshiFM]*(1.0-posloFM) - +NoteVoicePar[nvoice].FMSmp[poshiFM+1]*posloFM); - posloFM+=freqloFM; - if (posloFM>=1.0) { - posloFM=fmod(posloFM,1.0); - poshiFM++; - }; - poshiFM+=freqhiFM; - poshiFM&=OSCIL_SIZE-1; - }; - oscposhiFM[nvoice][k]=poshiFM; - oscposloFM[nvoice][k]=posloFM; - }; - }; + for(int k = 0; k < unison_size[nvoice]; k++) { + REALTYPE *tw = tmpwave_unison[k]; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tw[i] = NoteVoicePar[NoteVoicePar[nvoice].FMVoice].VoiceOut[i]; + } + } + else { + //Compute the modulator and store it in tmpwave_unison[][] + for(int k = 0; k < unison_size[nvoice]; k++) { + int poshiFM = oscposhiFM[nvoice][k]; + REALTYPE posloFM = oscposloFM[nvoice][k]; + int freqhiFM = oscfreqhiFM[nvoice][k]; + REALTYPE freqloFM = oscfreqloFM[nvoice][k]; + REALTYPE *tw = tmpwave_unison[k]; + + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tw[i] = + (NoteVoicePar[nvoice].FMSmp[poshiFM] * (1.0 - posloFM) + + NoteVoicePar[nvoice].FMSmp[poshiFM + 1] * posloFM); + posloFM += freqloFM; + if(posloFM >= 1.0) { + posloFM = fmod(posloFM, 1.0); + poshiFM++; + } + poshiFM += freqhiFM; + poshiFM &= OSCIL_SIZE - 1; + } + oscposhiFM[nvoice][k] = poshiFM; + oscposloFM[nvoice][k] = posloFM; + } + } // Amplitude interpolation - if (ABOVE_AMPLITUDE_THRESHOLD(FMoldamplitude[nvoice],FMnewamplitude[nvoice])) { - for (int k=0;k<unison_size[nvoice];k++){ - REALTYPE *tw=tmpwave_unison[k]; - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - tw[i]*=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice] - ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE); - }; - }; - } else { - for (int k=0;k<unison_size[nvoice];k++){ - REALTYPE *tw=tmpwave_unison[k]; - for (i=0;i<SOUND_BUFFER_SIZE;i++) tw[i]*=FMnewamplitude[nvoice]; - }; - }; + if(ABOVE_AMPLITUDE_THRESHOLD(FMoldamplitude[nvoice], + FMnewamplitude[nvoice])) { + for(int k = 0; k < unison_size[nvoice]; k++) { + REALTYPE *tw = tmpwave_unison[k]; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tw[i] *= INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice], + FMnewamplitude[nvoice], + i, + SOUND_BUFFER_SIZE); + ; + } + } + else { + for(int k = 0; k < unison_size[nvoice]; k++) { + REALTYPE *tw = tmpwave_unison[k]; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tw[i] *= FMnewamplitude[nvoice]; + } + } //normalize: makes all sample-rates, oscil_sizes to produce same sound - if (FMmode!=0) {//Frequency modulation - REALTYPE normalize=OSCIL_SIZE/262144.0*44100.0/(REALTYPE)SAMPLE_RATE; - for (int k=0;k<unison_size[nvoice];k++){ - REALTYPE *tw=tmpwave_unison[k]; - REALTYPE fmold=FMoldsmp[nvoice][k]; - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - fmold=fmod(fmold+tw[i]*normalize,OSCIL_SIZE); - tw[i]=fmold; - }; - FMoldsmp[nvoice][k]=fmold; - }; - } else {//Phase modulation - REALTYPE normalize=OSCIL_SIZE/262144.0; - for (int k=0;k<unison_size[nvoice];k++){ - REALTYPE *tw=tmpwave_unison[k]; - for (i=0;i<SOUND_BUFFER_SIZE;i++) tw[i]*=normalize; - }; - }; + if(FMmode != 0) { //Frequency modulation + REALTYPE normalize = OSCIL_SIZE / 262144.0 * 44100.0 + / (REALTYPE)SAMPLE_RATE; + for(int k = 0; k < unison_size[nvoice]; k++) { + REALTYPE *tw = tmpwave_unison[k]; + REALTYPE fmold = FMoldsmp[nvoice][k]; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + fmold = fmod(fmold + tw[i] * normalize, OSCIL_SIZE); + tw[i] = fmold; + } + FMoldsmp[nvoice][k] = fmold; + } + } + else { //Phase modulation + REALTYPE normalize = OSCIL_SIZE / 262144.0; + for(int k = 0; k < unison_size[nvoice]; k++) { + REALTYPE *tw = tmpwave_unison[k]; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tw[i] *= normalize; + } + } - //do the modulation - for (int k=0;k<unison_size[nvoice];k++){ - REALTYPE *tw=tmpwave_unison[k]; - int poshi=oscposhi[nvoice][k]; - REALTYPE poslo=oscposlo[nvoice][k]; - int freqhi=oscfreqhi[nvoice][k]; - REALTYPE freqlo=oscfreqlo[nvoice][k]; - - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - F2I(tw[i],FMmodfreqhi); - FMmodfreqlo=fmod(tw[i]+0.0000000001,1.0); - if (FMmodfreqhi<0) FMmodfreqlo++; - - //carrier - carposhi=poshi+FMmodfreqhi; - carposlo=poslo+FMmodfreqlo; - - if (carposlo>=1.0) { - carposhi++; - carposlo=fmod(carposlo,1.0); - }; - carposhi&=(OSCIL_SIZE-1); - - tw[i]=NoteVoicePar[nvoice].OscilSmp[carposhi]*(1.0-carposlo) - +NoteVoicePar[nvoice].OscilSmp[carposhi+1]*carposlo; - - poslo+=freqlo; - if (poslo>=1.0) { - poslo=fmod(poslo,1.0); - poshi++; - }; - - poshi+=freqhi; - poshi&=OSCIL_SIZE-1; - }; - oscposhi[nvoice][k]=poshi; - oscposlo[nvoice][k]=poslo; - - }; -}; + //do the modulation + for(int k = 0; k < unison_size[nvoice]; k++) { + REALTYPE *tw = tmpwave_unison[k]; + int poshi = oscposhi[nvoice][k]; + REALTYPE poslo = oscposlo[nvoice][k]; + int freqhi = oscfreqhi[nvoice][k]; + REALTYPE freqlo = oscfreqlo[nvoice][k]; + + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + F2I(tw[i], FMmodfreqhi); + FMmodfreqlo = fmod(tw[i] + 0.0000000001, 1.0); + if(FMmodfreqhi < 0) + FMmodfreqlo++; + + //carrier + carposhi = poshi + FMmodfreqhi; + carposlo = poslo + FMmodfreqlo; + + if(carposlo >= 1.0) { + carposhi++; + carposlo = fmod(carposlo, 1.0); + } + carposhi &= (OSCIL_SIZE - 1); + + tw[i] = NoteVoicePar[nvoice].OscilSmp[carposhi] + * (1.0 - carposlo) + + NoteVoicePar[nvoice].OscilSmp[carposhi + + 1] * carposlo; + + poslo += freqlo; + if(poslo >= 1.0) { + poslo = fmod(poslo, 1.0); + poshi++; + } + + poshi += freqhi; + poshi &= OSCIL_SIZE - 1; + } + oscposhi[nvoice][k] = poshi; + oscposlo[nvoice][k] = poslo; + } +} /*Calculeaza Oscilatorul cu PITCH MODULATION*/ inline void ADnote::ComputeVoiceOscillatorPitchModulation(int nvoice) { //TODO -}; +} /* * Computes the Noise */ inline void ADnote::ComputeVoiceNoise(int nvoice) { - for (int k=0;k<unison_size[nvoice];k++){ - REALTYPE *tw=tmpwave_unison[k]; - for (int i=0;i<SOUND_BUFFER_SIZE;i++) tw[i]=RND*2.0-1.0; - }; -}; + for(int k = 0; k < unison_size[nvoice]; k++) { + REALTYPE *tw = tmpwave_unison[k]; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) + tw[i] = RND * 2.0 - 1.0; + } +} @@ -1297,23 +1611,26 @@ inline void ADnote::ComputeVoiceNoise(int nvoice) * Compute the ADnote samples * Returns 0 if the note is finished */ -int ADnote::noteout(REALTYPE *outl,REALTYPE *outr) +int ADnote::noteout(REALTYPE *outl, REALTYPE *outr) { - int i,nvoice; + int i, nvoice; - memcpy(outl, denormalkillbuf, SOUND_BUFFER_SIZE*sizeof(REALTYPE)); - memcpy(outr, denormalkillbuf, SOUND_BUFFER_SIZE*sizeof(REALTYPE)); + memcpy(outl, denormalkillbuf, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); + memcpy(outr, denormalkillbuf, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); - if (NoteEnabled==OFF) return(0); + if(NoteEnabled == OFF) + return 0; - memset(bypassl, 0, SOUND_BUFFER_SIZE*sizeof(REALTYPE)); - memset(bypassr, 0, SOUND_BUFFER_SIZE*sizeof(REALTYPE)); + memset(bypassl, 0, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); + memset(bypassr, 0, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); computecurrentparameters(); - for (nvoice=0;nvoice<NUM_VOICES;nvoice++) { - if ((NoteVoicePar[nvoice].Enabled!=ON) || (NoteVoicePar[nvoice].DelayTicks>0)) continue; - if (NoteVoicePar[nvoice].noisetype==0) {//voice mode=sound - switch (NoteVoicePar[nvoice].FMEnabled) { + for(nvoice = 0; nvoice < NUM_VOICES; nvoice++) { + if((NoteVoicePar[nvoice].Enabled != ON) + || (NoteVoicePar[nvoice].DelayTicks > 0)) + continue; + if(NoteVoicePar[nvoice].noisetype == 0) //voice mode=sound + switch(NoteVoicePar[nvoice].FMEnabled) { case MORPH: ComputeVoiceOscillatorMorph(nvoice); break; @@ -1321,266 +1638,328 @@ int ADnote::noteout(REALTYPE *outl,REALTYPE *outr) ComputeVoiceOscillatorRingModulation(nvoice); break; case PHASE_MOD: - ComputeVoiceOscillatorFrequencyModulation(nvoice,0); + ComputeVoiceOscillatorFrequencyModulation(nvoice, 0); break; case FREQ_MOD: - ComputeVoiceOscillatorFrequencyModulation(nvoice,1); + ComputeVoiceOscillatorFrequencyModulation(nvoice, 1); break; - //case PITCH_MOD:ComputeVoiceOscillatorPitchModulation(nvoice);break; + //case PITCH_MOD:ComputeVoiceOscillatorPitchModulation(nvoice);break; default: ComputeVoiceOscillator_LinearInterpolation(nvoice); //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(nvoice); - - }; - } else ComputeVoiceNoise(nvoice); + } + else + ComputeVoiceNoise(nvoice); // Voice Processing - //mix subvoices into voice - for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwavel[i]=0.0; - if (stereo) for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwaver[i]=0.0; - for (int k=0;k<unison_size[nvoice];k++){ - REALTYPE *tw=tmpwave_unison[k]; - if (stereo){ - REALTYPE stereo_pos=0; - if (unison_size[nvoice]>1) stereo_pos=k/(REALTYPE)(unison_size[nvoice]-1)*2.0-1.0; - REALTYPE stereo_spread=unison_stereo_spread[nvoice]*2.0;//between 0 and 2.0 - if (stereo_spread>1.0){ - REALTYPE stereo_pos_1=(stereo_pos>=0.0)?1.0:-1.0; - stereo_pos=(2.0-stereo_spread)*stereo_pos+(stereo_spread-1.0)*stereo_pos_1; - }else{ - stereo_pos*=stereo_spread; - }; - if (unison_size[nvoice]==1) stereo_pos=0.0; - REALTYPE panning=(stereo_pos+1.0)*0.5; - - - REALTYPE lvol=(1.0-panning)*2.0; - if (lvol>1.0) lvol=1.0; - - REALTYPE rvol=panning*2.0; - if (rvol>1.0) rvol=1.0; - - if (unison_invert_phase[nvoice][k]) { - lvol=-lvol; - rvol=-rvol; - }; - - for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwavel[i]+=tw[i]*lvol; - for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwaver[i]+=tw[i]*rvol; - }else{ - for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwavel[i]+=tw[i]; - }; - - }; - - - REALTYPE unison_amplitude=1.0/sqrt(unison_size[nvoice]);//reduce the amplitude for large unison sizes + //mix subvoices into voice + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwavel[i] = 0.0; + if(stereo) + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwaver[i] = 0.0; + for(int k = 0; k < unison_size[nvoice]; k++) { + REALTYPE *tw = tmpwave_unison[k]; + if(stereo) { + REALTYPE stereo_pos = 0; + if(unison_size[nvoice] > 1) + stereo_pos = k + / (REALTYPE)(unison_size[nvoice] + - 1) * 2.0 - 1.0; + REALTYPE stereo_spread = unison_stereo_spread[nvoice] * 2.0; //between 0 and 2.0 + if(stereo_spread > 1.0) { + REALTYPE stereo_pos_1 = (stereo_pos >= 0.0) ? 1.0 : -1.0; + stereo_pos = + (2.0 + - stereo_spread) * stereo_pos + + (stereo_spread - 1.0) * stereo_pos_1; + } + else + stereo_pos *= stereo_spread; + ; + if(unison_size[nvoice] == 1) + stereo_pos = 0.0; + REALTYPE panning = (stereo_pos + 1.0) * 0.5; + + + REALTYPE lvol = (1.0 - panning) * 2.0; + if(lvol > 1.0) + lvol = 1.0; + + REALTYPE rvol = panning * 2.0; + if(rvol > 1.0) + rvol = 1.0; + + if(unison_invert_phase[nvoice][k]) { + lvol = -lvol; + rvol = -rvol; + } + + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwavel[i] += tw[i] * lvol; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwaver[i] += tw[i] * rvol; + } + else + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwavel[i] += tw[i]; + ; + } + + + REALTYPE unison_amplitude = 1.0 / sqrt(unison_size[nvoice]); //reduce the amplitude for large unison sizes // Amplitude - REALTYPE oldam=oldamplitude[nvoice]*unison_amplitude; - REALTYPE newam=newamplitude[nvoice]*unison_amplitude; + REALTYPE oldam = oldamplitude[nvoice] * unison_amplitude; + REALTYPE newam = newamplitude[nvoice] * unison_amplitude; - if (ABOVE_AMPLITUDE_THRESHOLD(oldam,newam)) { - int rest=SOUND_BUFFER_SIZE; + if(ABOVE_AMPLITUDE_THRESHOLD(oldam, newam)) { + int rest = SOUND_BUFFER_SIZE; //test if the amplitude if raising and the difference is high - if ((newam>oldam)&&((newam-oldam)>0.25)) { - rest=10; - if (rest>SOUND_BUFFER_SIZE) rest=SOUND_BUFFER_SIZE; - for (int i=0;i<SOUND_BUFFER_SIZE-rest;i++) tmpwavel[i]*=oldam; - if (stereo) for (int i=0;i<SOUND_BUFFER_SIZE-rest;i++) tmpwaver[i]*=oldam; - }; + if((newam > oldam) && ((newam - oldam) > 0.25)) { + rest = 10; + if(rest > SOUND_BUFFER_SIZE) + rest = SOUND_BUFFER_SIZE; + for(int i = 0; i < SOUND_BUFFER_SIZE - rest; i++) + tmpwavel[i] *= oldam; + if(stereo) + for(int i = 0; i < SOUND_BUFFER_SIZE - rest; i++) + tmpwaver[i] *= oldam; + } // Amplitude interpolation - for (i=0;i<rest;i++) { - REALTYPE amp=INTERPOLATE_AMPLITUDE(oldam,newam,i,rest); - tmpwavel[i+(SOUND_BUFFER_SIZE-rest)]*=amp; - if (stereo) tmpwaver[i+(SOUND_BUFFER_SIZE-rest)]*=amp; - }; - } else { - for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwavel[i]*=newam; - if (stereo) for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwaver[i]*=newam; - }; + for(i = 0; i < rest; i++) { + REALTYPE amp = INTERPOLATE_AMPLITUDE(oldam, newam, i, rest); + tmpwavel[i + (SOUND_BUFFER_SIZE - rest)] *= amp; + if(stereo) + tmpwaver[i + (SOUND_BUFFER_SIZE - rest)] *= amp; + } + } + else { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwavel[i] *= newam; + if(stereo) + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwaver[i] *= newam; + } // Fade in - if (firsttick[nvoice]!=0) { + if(firsttick[nvoice] != 0) { fadein(&tmpwavel[0]); - if (stereo) fadein(&tmpwaver[0]); - firsttick[nvoice]=0; - }; + if(stereo) + fadein(&tmpwaver[0]); + firsttick[nvoice] = 0; + } // Filter - if (NoteVoicePar[nvoice].VoiceFilterL!=NULL) NoteVoicePar[nvoice].VoiceFilterL->filterout(&tmpwavel[0]); - if ((stereo)&&(NoteVoicePar[nvoice].VoiceFilterR!=NULL)) NoteVoicePar[nvoice].VoiceFilterR->filterout(&tmpwaver[0]); + if(NoteVoicePar[nvoice].VoiceFilterL != NULL) + NoteVoicePar[nvoice].VoiceFilterL->filterout(&tmpwavel[0]); + if((stereo) && (NoteVoicePar[nvoice].VoiceFilterR != NULL)) + NoteVoicePar[nvoice].VoiceFilterR->filterout(&tmpwaver[0]); //check if the amplitude envelope is finished, if yes, the voice will be fadeout - if (NoteVoicePar[nvoice].AmpEnvelope!=NULL) { - if (NoteVoicePar[nvoice].AmpEnvelope->finished()!=0){ - for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwavel[i]*=1.0-(REALTYPE)i/(REALTYPE)SOUND_BUFFER_SIZE; - if (stereo) for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwaver[i]*=1.0-(REALTYPE)i/(REALTYPE)SOUND_BUFFER_SIZE; - }; + if(NoteVoicePar[nvoice].AmpEnvelope != NULL) { + if(NoteVoicePar[nvoice].AmpEnvelope->finished() != 0) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwavel[i] *= 1.0 - (REALTYPE)i + / (REALTYPE)SOUND_BUFFER_SIZE; + if(stereo) + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwaver[i] *= 1.0 - (REALTYPE)i + / (REALTYPE)SOUND_BUFFER_SIZE; + } //the voice is killed later - }; + } // Put the ADnote samples in VoiceOut (without appling Global volume, because I wish to use this voice as a modullator) - if (NoteVoicePar[nvoice].VoiceOut!=NULL){ - if (stereo) { - for (i=0;i<SOUND_BUFFER_SIZE;i++) NoteVoicePar[nvoice].VoiceOut[i]=tmpwavel[i]+tmpwaver[i]; - }else {//mono - for (i=0;i<SOUND_BUFFER_SIZE;i++) NoteVoicePar[nvoice].VoiceOut[i]=tmpwavel[i]; - }; - }; + if(NoteVoicePar[nvoice].VoiceOut != NULL) { + if(stereo) + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + NoteVoicePar[nvoice].VoiceOut[i] = tmpwavel[i] + + tmpwaver[i]; + else //mono + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + NoteVoicePar[nvoice].VoiceOut[i] = tmpwavel[i]; + ; + } // Add the voice that do not bypass the filter to out - if (NoteVoicePar[nvoice].filterbypass==0) {//no bypass - if (stereo) { - for (i=0;i<SOUND_BUFFER_SIZE;i++) {//stereo - outl[i]+=tmpwavel[i]*NoteVoicePar[nvoice].Volume*NoteVoicePar[nvoice].Panning*2.0; - outr[i]+=tmpwaver[i]*NoteVoicePar[nvoice].Volume*(1.0-NoteVoicePar[nvoice].Panning)*2.0; - }; - }else{ - for (i=0;i<SOUND_BUFFER_SIZE;i++) outl[i]+=tmpwavel[i]*NoteVoicePar[nvoice].Volume;//mono - }; - } else {//bypass the filter - if (stereo) { - for (i=0;i<SOUND_BUFFER_SIZE;i++) {//stereo - bypassl[i]+=tmpwavel[i]*NoteVoicePar[nvoice].Volume*NoteVoicePar[nvoice].Panning*2.0; - bypassr[i]+=tmpwaver[i]*NoteVoicePar[nvoice].Volume*(1.0-NoteVoicePar[nvoice].Panning)*2.0; - }; - }else{ - for (i=0;i<SOUND_BUFFER_SIZE;i++) bypassl[i]+=tmpwavel[i]*NoteVoicePar[nvoice].Volume;//mono - }; - }; + if(NoteVoicePar[nvoice].filterbypass == 0) { //no bypass + if(stereo) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //stereo + outl[i] += tmpwavel[i] * NoteVoicePar[nvoice].Volume + * NoteVoicePar[nvoice].Panning * 2.0; + outr[i] += tmpwaver[i] * NoteVoicePar[nvoice].Volume + * (1.0 - NoteVoicePar[nvoice].Panning) * 2.0; + } + } + else + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + outl[i] += tmpwavel[i] * NoteVoicePar[nvoice].Volume; //mono + ; + } + else { //bypass the filter + if(stereo) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //stereo + bypassl[i] += tmpwavel[i] * NoteVoicePar[nvoice].Volume + * NoteVoicePar[nvoice].Panning * 2.0; + bypassr[i] += tmpwaver[i] * NoteVoicePar[nvoice].Volume + * (1.0 - NoteVoicePar[nvoice].Panning) * 2.0; + } + } + else + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + bypassl[i] += tmpwavel[i] * NoteVoicePar[nvoice].Volume; //mono + ; + } // chech if there is necesary to proces the voice longer (if the Amplitude envelope isn't finished) - if (NoteVoicePar[nvoice].AmpEnvelope!=NULL) { - if (NoteVoicePar[nvoice].AmpEnvelope->finished()!=0) KillVoice(nvoice); - }; - }; + if(NoteVoicePar[nvoice].AmpEnvelope != NULL) + if(NoteVoicePar[nvoice].AmpEnvelope->finished() != 0) + KillVoice(nvoice); + ; + } //Processing Global parameters NoteGlobalPar.GlobalFilterL->filterout(&outl[0]); - if (stereo==0) { - for (i=0;i<SOUND_BUFFER_SIZE;i++) {//set the right channel=left channel - outr[i]=outl[i]; - bypassr[i]=bypassl[i]; + if(stereo == 0) + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //set the right channel=left channel + outr[i] = outl[i]; + bypassr[i] = bypassl[i]; } - } else NoteGlobalPar.GlobalFilterR->filterout(&outr[0]); + else + NoteGlobalPar.GlobalFilterR->filterout(&outr[0]); - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - outl[i]+=bypassl[i]; - outr[i]+=bypassr[i]; - }; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + outl[i] += bypassl[i]; + outr[i] += bypassr[i]; + } - if (ABOVE_AMPLITUDE_THRESHOLD(globaloldamplitude,globalnewamplitude)) { + if(ABOVE_AMPLITUDE_THRESHOLD(globaloldamplitude, globalnewamplitude)) { // Amplitude Interpolation - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - REALTYPE tmpvol=INTERPOLATE_AMPLITUDE(globaloldamplitude - ,globalnewamplitude,i,SOUND_BUFFER_SIZE); - outl[i]*=tmpvol*NoteGlobalPar.Panning; - outr[i]*=tmpvol*(1.0-NoteGlobalPar.Panning); - }; - } else { - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - outl[i]*=globalnewamplitude*NoteGlobalPar.Panning; - outr[i]*=globalnewamplitude*(1.0-NoteGlobalPar.Panning); - }; - }; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + REALTYPE tmpvol = INTERPOLATE_AMPLITUDE(globaloldamplitude, + globalnewamplitude, + i, + SOUND_BUFFER_SIZE); + outl[i] *= tmpvol * NoteGlobalPar.Panning; + outr[i] *= tmpvol * (1.0 - NoteGlobalPar.Panning); + } + } + else { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + outl[i] *= globalnewamplitude * NoteGlobalPar.Panning; + outr[i] *= globalnewamplitude * (1.0 - NoteGlobalPar.Panning); + } + } //Apply the punch - if (NoteGlobalPar.Punch.Enabled!=0) { - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - REALTYPE punchamp=NoteGlobalPar.Punch.initialvalue*NoteGlobalPar.Punch.t+1.0; - outl[i]*=punchamp; - outr[i]*=punchamp; - NoteGlobalPar.Punch.t-=NoteGlobalPar.Punch.dt; - if (NoteGlobalPar.Punch.t<0.0) { - NoteGlobalPar.Punch.Enabled=0; + if(NoteGlobalPar.Punch.Enabled != 0) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + REALTYPE punchamp = NoteGlobalPar.Punch.initialvalue + * NoteGlobalPar.Punch.t + 1.0; + outl[i] *= punchamp; + outr[i] *= punchamp; + NoteGlobalPar.Punch.t -= NoteGlobalPar.Punch.dt; + if(NoteGlobalPar.Punch.t < 0.0) { + NoteGlobalPar.Punch.Enabled = 0; break; - }; - }; - }; + } + } + } // Apply legato-specific sound signal modifications - if (Legato.silent) { // Silencer - if (Legato.msg!=LM_FadeIn) { + if(Legato.silent) // Silencer + if(Legato.msg != LM_FadeIn) { memset(outl, 0, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); memset(outl, 0, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); } - } - switch (Legato.msg) { - case LM_CatchUp : // Continue the catch-up... - if (Legato.decounter==-10) Legato.decounter=Legato.fade.length; - for (i=0;i<SOUND_BUFFER_SIZE;i++) {//Yea, could be done without the loop... + switch(Legato.msg) { + case LM_CatchUp: // Continue the catch-up... + if(Legato.decounter == -10) + Legato.decounter = Legato.fade.length; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //Yea, could be done without the loop... Legato.decounter--; - if (Legato.decounter<1) { + if(Legato.decounter < 1) { // Catching-up done, we can finally set // the note to the actual parameters. - Legato.decounter=-10; - Legato.msg=LM_ToNorm; - ADlegatonote(Legato.param.freq, Legato.param.vel, Legato.param.portamento, Legato.param.midinote, false); + Legato.decounter = -10; + Legato.msg = LM_ToNorm; + ADlegatonote(Legato.param.freq, + Legato.param.vel, + Legato.param.portamento, + Legato.param.midinote, + false); break; } } break; - case LM_FadeIn : // Fade-in - if (Legato.decounter==-10) Legato.decounter=Legato.fade.length; - Legato.silent=false; - for (i=0;i<SOUND_BUFFER_SIZE;i++) { + case LM_FadeIn: // Fade-in + if(Legato.decounter == -10) + Legato.decounter = Legato.fade.length; + Legato.silent = false; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { Legato.decounter--; - if (Legato.decounter<1) { - Legato.decounter=-10; - Legato.msg=LM_Norm; + if(Legato.decounter < 1) { + Legato.decounter = -10; + Legato.msg = LM_Norm; break; } - Legato.fade.m+=Legato.fade.step; - outl[i]*=Legato.fade.m; - outr[i]*=Legato.fade.m; + Legato.fade.m += Legato.fade.step; + outl[i] *= Legato.fade.m; + outr[i] *= Legato.fade.m; } break; - case LM_FadeOut : // Fade-out, then set the catch-up - if (Legato.decounter==-10) Legato.decounter=Legato.fade.length; - for (i=0;i<SOUND_BUFFER_SIZE;i++) { + case LM_FadeOut: // Fade-out, then set the catch-up + if(Legato.decounter == -10) + Legato.decounter = Legato.fade.length; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { Legato.decounter--; - if (Legato.decounter<1) { - for (int j=i;j<SOUND_BUFFER_SIZE;j++) { - outl[j]=0.0; - outr[j]=0.0; + if(Legato.decounter < 1) { + for(int j = i; j < SOUND_BUFFER_SIZE; j++) { + outl[j] = 0.0; + outr[j] = 0.0; } - Legato.decounter=-10; - Legato.silent=true; + Legato.decounter = -10; + Legato.silent = true; // Fading-out done, now set the catch-up : - Legato.decounter=Legato.fade.length; - Legato.msg=LM_CatchUp; - REALTYPE catchupfreq=Legato.param.freq*(Legato.param.freq/Legato.lastfreq);//This freq should make this now silent note to catch-up (or should I say resync ?) with the heard note for the same length it stayed at the previous freq during the fadeout. - ADlegatonote(catchupfreq, Legato.param.vel, Legato.param.portamento, Legato.param.midinote, false); + Legato.decounter = Legato.fade.length; + Legato.msg = LM_CatchUp; + REALTYPE catchupfreq = Legato.param.freq + * (Legato.param.freq / Legato.lastfreq); //This freq should make this now silent note to catch-up (or should I say resync ?) with the heard note for the same length it stayed at the previous freq during the fadeout. + ADlegatonote(catchupfreq, + Legato.param.vel, + Legato.param.portamento, + Legato.param.midinote, + false); break; } - Legato.fade.m-=Legato.fade.step; - outl[i]*=Legato.fade.m; - outr[i]*=Legato.fade.m; + Legato.fade.m -= Legato.fade.step; + outl[i] *= Legato.fade.m; + outr[i] *= Legato.fade.m; } break; - default : + default: break; } // Check if the global amplitude is finished. // If it does, disable the note - if (NoteGlobalPar.AmpEnvelope->finished()!=0) { - for (i=0;i<SOUND_BUFFER_SIZE;i++) {//fade-out - REALTYPE tmp=1.0-(REALTYPE)i/(REALTYPE)SOUND_BUFFER_SIZE; - outl[i]*=tmp; - outr[i]*=tmp; - }; + if(NoteGlobalPar.AmpEnvelope->finished() != 0) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //fade-out + REALTYPE tmp = 1.0 - (REALTYPE)i / (REALTYPE)SOUND_BUFFER_SIZE; + outl[i] *= tmp; + outr[i] *= tmp; + } KillNote(); - }; - return(1); -}; + } + return 1; +} /* @@ -1589,28 +1968,33 @@ int ADnote::noteout(REALTYPE *outl,REALTYPE *outr) void ADnote::relasekey() { int nvoice; - for (nvoice=0;nvoice<NUM_VOICES;nvoice++) { - if (NoteVoicePar[nvoice].Enabled==0) continue; - if (NoteVoicePar[nvoice].AmpEnvelope!=NULL) NoteVoicePar[nvoice].AmpEnvelope->relasekey(); - if (NoteVoicePar[nvoice].FreqEnvelope!=NULL) NoteVoicePar[nvoice].FreqEnvelope->relasekey(); - if (NoteVoicePar[nvoice].FilterEnvelope!=NULL) NoteVoicePar[nvoice].FilterEnvelope->relasekey(); - if (NoteVoicePar[nvoice].FMFreqEnvelope!=NULL) NoteVoicePar[nvoice].FMFreqEnvelope->relasekey(); - if (NoteVoicePar[nvoice].FMAmpEnvelope!=NULL) NoteVoicePar[nvoice].FMAmpEnvelope->relasekey(); - }; + for(nvoice = 0; nvoice < NUM_VOICES; nvoice++) { + if(NoteVoicePar[nvoice].Enabled == 0) + continue; + if(NoteVoicePar[nvoice].AmpEnvelope != NULL) + NoteVoicePar[nvoice].AmpEnvelope->relasekey(); + if(NoteVoicePar[nvoice].FreqEnvelope != NULL) + NoteVoicePar[nvoice].FreqEnvelope->relasekey(); + if(NoteVoicePar[nvoice].FilterEnvelope != NULL) + NoteVoicePar[nvoice].FilterEnvelope->relasekey(); + if(NoteVoicePar[nvoice].FMFreqEnvelope != NULL) + NoteVoicePar[nvoice].FMFreqEnvelope->relasekey(); + if(NoteVoicePar[nvoice].FMAmpEnvelope != NULL) + NoteVoicePar[nvoice].FMAmpEnvelope->relasekey(); + } NoteGlobalPar.FreqEnvelope->relasekey(); NoteGlobalPar.FilterEnvelope->relasekey(); NoteGlobalPar.AmpEnvelope->relasekey(); - -}; +} /* * Check if the note is finished */ int ADnote::finished() const { - if (NoteEnabled==ON) return(0); - else return(1); -}; - - + if(NoteEnabled == ON) + return 0; + else + return 1; +} diff --git a/src/Synth/ADnote.h b/src/Synth/ADnote.h @@ -40,313 +40,310 @@ /**The "additive" synthesizer*/ class ADnote //ADDitive note { -public: - /**Constructor. - * @param pars Note Parameters - * @param ctl_ Pointer to system Controller - * @param freq Base frequency for note - * @param velocity Velocity of note - * @param portamento_ 1 if the note has portamento - * @param midinote_ The midi number of the note - * @param besilent Start silent note if true*/ - ADnote(ADnoteParameters *pars, Controller *ctl_, REALTYPE freq, - REALTYPE velocity, int portamento_, int midinote_, - bool besilent); - /**Destructor*/ - ~ADnote(); - - /**Alters the playing note for legato effect*/ - void ADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, - int midinote_, bool externcall); - - /**Compute ADnote Samples. - * @return 0 if note is finished*/ - int noteout(REALTYPE *outl,REALTYPE *outr); - - /**Release the key for the note and start release portion of envelopes.*/ - void relasekey(); - /**Return if note is finished. - * @return finished=1 unfinished=0*/ - int finished() const; - - - /**Nonzero when ready for output(the parameters has been computed) - * zero when parameters need to be computed.*/ - char ready; - -private: - - /**Changes the frequency of an oscillator. - * @param nvoice voice to run computations on - * @param in_freq new frequency*/ - void setfreq(int nvoice,REALTYPE in_freq); - /**Set the frequency of the modulator oscillator*/ - void setfreqFM(int nvoice,REALTYPE in_freq); - /**Computes relative frequency for unison and unison's vibratto. - * Note: Must be called before setfreq* functions.*/ - void compute_unison_freq_rap(int nvoice); - /**Compute parameters for next tick*/ - void computecurrentparameters(); - /**Initializes All Parameters*/ - void initparameters(); - /**Deallocate/Cleanup given voice*/ - void KillVoice(int nvoice); - /**Deallocate Note resources and voice resources*/ - void KillNote(); - /**Get the Voice's base frequency*/ - inline REALTYPE getvoicebasefreq(int nvoice) const; - /**Get modulator's base frequency*/ - inline REALTYPE getFMvoicebasefreq(int nvoice) const; - /**Compute the Oscillator's samples. - * Affects tmpwave_unison and updates oscposhi/oscposlo*/ - inline void ComputeVoiceOscillator_LinearInterpolation(int nvoice); - /**Compute the Oscillator's samples. - * Affects tmpwave_unison and updates oscposhi/oscposlo - * @todo remove this declaration if it is commented out*/ - inline void ComputeVoiceOscillator_CubicInterpolation(int nvoice); - /**Computes the Oscillator samples with morphing. - * updates tmpwave_unison*/ - inline void ComputeVoiceOscillatorMorph(int nvoice); - /**Computes the Ring Modulated Oscillator.*/ - inline void ComputeVoiceOscillatorRingModulation(int nvoice); - /**Computes the Frequency Modulated Oscillator. - * @param FMmode modulation type 0=Phase 1=Frequency*/ - inline void ComputeVoiceOscillatorFrequencyModulation(int nvoice,int FMmode);//FMmode=0 for phase modulation, 1 for Frequency modulation - // inline void ComputeVoiceOscillatorFrequencyModulation(int nvoice); - /**TODO*/ - inline void ComputeVoiceOscillatorPitchModulation(int nvoice); - - /**Generate Noise Samples for Voice*/ - inline void ComputeVoiceNoise(int nvoice); - - /**Fadein in a way that removes clicks but keep sound "punchy"*/ - inline void fadein(REALTYPE *smps) const; - - - //GLOBALS - ADnoteParameters *partparams; - unsigned char stereo;//if the note is stereo (allows note Panning) - int midinote; - REALTYPE velocity,basefreq; - - ONOFFTYPE NoteEnabled; - Controller *ctl; - - /*****************************************************************/ - /* GLOBAL PARAMETERS */ - /*****************************************************************/ - - struct ADnoteGlobal { - /****************************************** - * FREQUENCY GLOBAL PARAMETERS * - ******************************************/ - REALTYPE Detune;//cents - - Envelope *FreqEnvelope; - LFO *FreqLfo; - - /******************************************** - * AMPLITUDE GLOBAL PARAMETERS * - ********************************************/ - REALTYPE Volume;// [ 0 .. 1 ] - - REALTYPE Panning;// [ 0 .. 1 ] - - Envelope *AmpEnvelope; - LFO *AmpLfo; + public: + /**Constructor. + * @param pars Note Parameters + * @param ctl_ Pointer to system Controller + * @param freq Base frequency for note + * @param velocity Velocity of note + * @param portamento_ 1 if the note has portamento + * @param midinote_ The midi number of the note + * @param besilent Start silent note if true*/ + ADnote(ADnoteParameters *pars, Controller *ctl_, REALTYPE freq, + REALTYPE velocity, int portamento_, int midinote_, + bool besilent); + /**Destructor*/ + ~ADnote(); + + /**Alters the playing note for legato effect*/ + void ADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, + int midinote_, bool externcall); + + /**Compute ADnote Samples. + * @return 0 if note is finished*/ + int noteout(REALTYPE *outl, REALTYPE *outr); + + /**Release the key for the note and start release portion of envelopes.*/ + void relasekey(); + /**Return if note is finished. + * @return finished=1 unfinished=0*/ + int finished() const; + + + /**Nonzero when ready for output(the parameters has been computed) + * zero when parameters need to be computed.*/ + char ready; + + private: + + /**Changes the frequency of an oscillator. + * @param nvoice voice to run computations on + * @param in_freq new frequency*/ + void setfreq(int nvoice, REALTYPE in_freq); + /**Set the frequency of the modulator oscillator*/ + void setfreqFM(int nvoice, REALTYPE in_freq); + /**Computes relative frequency for unison and unison's vibratto. + * Note: Must be called before setfreq* functions.*/ + void compute_unison_freq_rap(int nvoice); + /**Compute parameters for next tick*/ + void computecurrentparameters(); + /**Initializes All Parameters*/ + void initparameters(); + /**Deallocate/Cleanup given voice*/ + void KillVoice(int nvoice); + /**Deallocate Note resources and voice resources*/ + void KillNote(); + /**Get the Voice's base frequency*/ + inline REALTYPE getvoicebasefreq(int nvoice) const; + /**Get modulator's base frequency*/ + inline REALTYPE getFMvoicebasefreq(int nvoice) const; + /**Compute the Oscillator's samples. + * Affects tmpwave_unison and updates oscposhi/oscposlo*/ + inline void ComputeVoiceOscillator_LinearInterpolation(int nvoice); + /**Compute the Oscillator's samples. + * Affects tmpwave_unison and updates oscposhi/oscposlo + * @todo remove this declaration if it is commented out*/ + inline void ComputeVoiceOscillator_CubicInterpolation(int nvoice); + /**Computes the Oscillator samples with morphing. + * updates tmpwave_unison*/ + inline void ComputeVoiceOscillatorMorph(int nvoice); + /**Computes the Ring Modulated Oscillator.*/ + inline void ComputeVoiceOscillatorRingModulation(int nvoice); + /**Computes the Frequency Modulated Oscillator. + * @param FMmode modulation type 0=Phase 1=Frequency*/ + inline void ComputeVoiceOscillatorFrequencyModulation(int nvoice, + int FMmode); //FMmode=0 for phase modulation, 1 for Frequency modulation + // inline void ComputeVoiceOscillatorFrequencyModulation(int nvoice); + /**TODO*/ + inline void ComputeVoiceOscillatorPitchModulation(int nvoice); + + /**Generate Noise Samples for Voice*/ + inline void ComputeVoiceNoise(int nvoice); + + /**Fadein in a way that removes clicks but keep sound "punchy"*/ + inline void fadein(REALTYPE *smps) const; + + + //GLOBALS + ADnoteParameters *partparams; + unsigned char stereo; //if the note is stereo (allows note Panning) + int midinote; + REALTYPE velocity, basefreq; + + ONOFFTYPE NoteEnabled; + Controller *ctl; + + /*****************************************************************/ + /* GLOBAL PARAMETERS */ + /*****************************************************************/ + + struct ADnoteGlobal { + /****************************************** + * FREQUENCY GLOBAL PARAMETERS * + ******************************************/ + REALTYPE Detune; //cents + + Envelope *FreqEnvelope; + LFO *FreqLfo; + + /******************************************** + * AMPLITUDE GLOBAL PARAMETERS * + ********************************************/ + REALTYPE Volume; // [ 0 .. 1 ] + + REALTYPE Panning; // [ 0 .. 1 ] + + Envelope *AmpEnvelope; + LFO *AmpLfo; - struct { - int Enabled; - REALTYPE initialvalue,dt,t; - } Punch; - - /****************************************** - * FILTER GLOBAL PARAMETERS * - ******************************************/ - Filter *GlobalFilterL,*GlobalFilterR; + struct { + int Enabled; + REALTYPE initialvalue, dt, t; + } Punch; - REALTYPE FilterCenterPitch;//octaves - REALTYPE FilterQ; - REALTYPE FilterFreqTracking; + /****************************************** + * FILTER GLOBAL PARAMETERS * + ******************************************/ + Filter *GlobalFilterL, *GlobalFilterR; - Envelope *FilterEnvelope; + REALTYPE FilterCenterPitch; //octaves + REALTYPE FilterQ; + REALTYPE FilterFreqTracking; - LFO *FilterLfo; - } NoteGlobalPar; + Envelope *FilterEnvelope; + LFO *FilterLfo; + } NoteGlobalPar; - /***********************************************************/ - /* VOICE PARAMETERS */ - /***********************************************************/ - struct ADnoteVoice { - /* If the voice is enabled */ - ONOFFTYPE Enabled; - /* Voice Type (sound/noise)*/ - int noisetype; + /***********************************************************/ + /* VOICE PARAMETERS */ + /***********************************************************/ + struct ADnoteVoice { + /* If the voice is enabled */ + ONOFFTYPE Enabled; - /* Filter Bypass */ - int filterbypass; + /* Voice Type (sound/noise)*/ + int noisetype; - /* Delay (ticks) */ - int DelayTicks; + /* Filter Bypass */ + int filterbypass; - /* Waveform of the Voice */ - REALTYPE *OscilSmp; + /* Delay (ticks) */ + int DelayTicks; - /************************************ - * FREQUENCY PARAMETERS * - ************************************/ - int fixedfreq;//if the frequency is fixed to 440 Hz - int fixedfreqET;//if the "fixed" frequency varies according to the note (ET) + /* Waveform of the Voice */ + REALTYPE *OscilSmp; - // cents = basefreq*VoiceDetune - REALTYPE Detune,FineDetune; + /************************************ + * FREQUENCY PARAMETERS * + ************************************/ + int fixedfreq; //if the frequency is fixed to 440 Hz + int fixedfreqET; //if the "fixed" frequency varies according to the note (ET) - Envelope *FreqEnvelope; - LFO *FreqLfo; + // cents = basefreq*VoiceDetune + REALTYPE Detune, FineDetune; + Envelope *FreqEnvelope; + LFO *FreqLfo; - /*************************** - * AMPLITUDE PARAMETERS * - ***************************/ - /* Panning 0.0=left, 0.5 - center, 1.0 = right */ - REALTYPE Panning; - REALTYPE Volume;// [-1.0 .. 1.0] + /*************************** + * AMPLITUDE PARAMETERS * + ***************************/ - Envelope *AmpEnvelope; - LFO *AmpLfo; + /* Panning 0.0=left, 0.5 - center, 1.0 = right */ + REALTYPE Panning; + REALTYPE Volume; // [-1.0 .. 1.0] - /************************* - * FILTER PARAMETERS * - *************************/ + Envelope *AmpEnvelope; + LFO *AmpLfo; - Filter *VoiceFilterL; - Filter *VoiceFilterR; + /************************* + * FILTER PARAMETERS * + *************************/ - REALTYPE FilterCenterPitch;/* Filter center Pitch*/ - REALTYPE FilterFreqTracking; + Filter *VoiceFilterL; + Filter *VoiceFilterR; - Envelope *FilterEnvelope; - LFO *FilterLfo; + REALTYPE FilterCenterPitch; /* Filter center Pitch*/ + REALTYPE FilterFreqTracking; + Envelope *FilterEnvelope; + LFO *FilterLfo; - /**************************** - * MODULLATOR PARAMETERS * - ****************************/ - FMTYPE FMEnabled; + /**************************** + * MODULLATOR PARAMETERS * + ****************************/ - int FMVoice; + FMTYPE FMEnabled; - // Voice Output used by other voices if use this as modullator - REALTYPE *VoiceOut; + int FMVoice; - /* Wave of the Voice */ - REALTYPE *FMSmp; + // Voice Output used by other voices if use this as modullator + REALTYPE *VoiceOut; - REALTYPE FMVolume; - REALTYPE FMDetune; //in cents + /* Wave of the Voice */ + REALTYPE *FMSmp; - Envelope *FMFreqEnvelope; - Envelope *FMAmpEnvelope; - - } NoteVoicePar[NUM_VOICES]; + REALTYPE FMVolume; + REALTYPE FMDetune; //in cents + Envelope *FMFreqEnvelope; + Envelope *FMAmpEnvelope; + } NoteVoicePar[NUM_VOICES]; - /********************************************************/ - /* INTERNAL VALUES OF THE NOTE AND OF THE VOICES */ - /********************************************************/ - //time from the start of the note - REALTYPE time; + /********************************************************/ + /* INTERNAL VALUES OF THE NOTE AND OF THE VOICES */ + /********************************************************/ - //the size of unison for a single voice - int unison_size[NUM_VOICES]; + //time from the start of the note + REALTYPE time; - //the stereo spread of the unison subvoices (0.0=mono,1.0=max) - REALTYPE unison_stereo_spread[NUM_VOICES]; + //the size of unison for a single voice + int unison_size[NUM_VOICES]; - //fractional part (skip) - REALTYPE *oscposlo[NUM_VOICES],*oscfreqlo[NUM_VOICES]; + //the stereo spread of the unison subvoices (0.0=mono,1.0=max) + REALTYPE unison_stereo_spread[NUM_VOICES]; - //integer part (skip) - int *oscposhi[NUM_VOICES],*oscfreqhi[NUM_VOICES]; + //fractional part (skip) + REALTYPE *oscposlo[NUM_VOICES], *oscfreqlo[NUM_VOICES]; - //fractional part (skip) of the Modullator - REALTYPE *oscposloFM[NUM_VOICES],*oscfreqloFM[NUM_VOICES]; + //integer part (skip) + int *oscposhi[NUM_VOICES], *oscfreqhi[NUM_VOICES]; - //the unison base_value - REALTYPE *unison_base_freq_rap[NUM_VOICES]; - - //how the unison subvoice's frequency is changed (1.0 for no change) - REALTYPE *unison_freq_rap[NUM_VOICES]; - - //which subvoice has phase inverted - bool *unison_invert_phase[NUM_VOICES]; + //fractional part (skip) of the Modullator + REALTYPE *oscposloFM[NUM_VOICES], *oscfreqloFM[NUM_VOICES]; - //unison vibratto - struct { - REALTYPE amplitude; //amplitude which be added to unison_freq_rap - REALTYPE *step; //value which increments the position - REALTYPE *position;//between -1.0 and 1.0 - }unison_vibratto[NUM_VOICES]; + //the unison base_value + REALTYPE *unison_base_freq_rap[NUM_VOICES]; + //how the unison subvoice's frequency is changed (1.0 for no change) + REALTYPE *unison_freq_rap[NUM_VOICES]; - //integer part (skip) of the Modullator - unsigned int *oscposhiFM[NUM_VOICES],*oscfreqhiFM[NUM_VOICES]; + //which subvoice has phase inverted + bool *unison_invert_phase[NUM_VOICES]; - //used to compute and interpolate the amplitudes of voices and modullators - REALTYPE oldamplitude[NUM_VOICES], - newamplitude[NUM_VOICES], - FMoldamplitude[NUM_VOICES], - FMnewamplitude[NUM_VOICES]; + //unison vibratto + struct { + REALTYPE amplitude; //amplitude which be added to unison_freq_rap + REALTYPE *step; //value which increments the position + REALTYPE *position; //between -1.0 and 1.0 + } unison_vibratto[NUM_VOICES]; - //used by Frequency Modulation (for integration) - REALTYPE *FMoldsmp[NUM_VOICES]; - //temporary buffer - REALTYPE *tmpwavel; - REALTYPE *tmpwaver; - int max_unison; - REALTYPE **tmpwave_unison; + //integer part (skip) of the Modullator + unsigned int *oscposhiFM[NUM_VOICES], *oscfreqhiFM[NUM_VOICES]; - //Filter bypass samples - REALTYPE *bypassl,*bypassr; + //used to compute and interpolate the amplitudes of voices and modullators + REALTYPE oldamplitude[NUM_VOICES], + newamplitude[NUM_VOICES], + FMoldamplitude[NUM_VOICES], + FMnewamplitude[NUM_VOICES]; - //interpolate the amplitudes - REALTYPE globaloldamplitude,globalnewamplitude; + //used by Frequency Modulation (for integration) + REALTYPE *FMoldsmp[NUM_VOICES]; - //1 - if it is the fitst tick (used to fade in the sound) - char firsttick[NUM_VOICES]; + //temporary buffer + REALTYPE *tmpwavel; + REALTYPE *tmpwaver; + int max_unison; + REALTYPE **tmpwave_unison; - //1 if the note has portamento - int portamento; + //Filter bypass samples + REALTYPE *bypassl, *bypassr; - //how the fine detunes are made bigger or smaller - REALTYPE bandwidthDetuneMultiplier; + //interpolate the amplitudes + REALTYPE globaloldamplitude, globalnewamplitude; - // Legato vars - struct { - bool silent; - REALTYPE lastfreq; - LegatoMsg msg; - int decounter; - struct { // Fade In/Out vars - int length; - REALTYPE m, step; - } fade; - struct { // Note parameters - REALTYPE freq, vel; - int portamento, midinote; - } param; - } Legato; -}; + //1 - if it is the fitst tick (used to fade in the sound) + char firsttick[NUM_VOICES]; -#endif + //1 if the note has portamento + int portamento; + //how the fine detunes are made bigger or smaller + REALTYPE bandwidthDetuneMultiplier; + // Legato vars + struct { + bool silent; + REALTYPE lastfreq; + LegatoMsg msg; + int decounter; + struct { // Fade In/Out vars + int length; + REALTYPE m, step; + } fade; + struct { // Note parameters + REALTYPE freq, vel; + int portamento, midinote; + } param; + } Legato; +}; +#endif diff --git a/src/Synth/Envelope.cpp b/src/Synth/Envelope.cpp @@ -23,64 +23,71 @@ #include <stdio.h> #include "Envelope.h" -Envelope::Envelope(EnvelopeParams *envpars,REALTYPE basefreq) +Envelope::Envelope(EnvelopeParams *envpars, REALTYPE basefreq) { int i; - envpoints=envpars->Penvpoints; - if (envpoints>MAX_ENVELOPE_POINTS) envpoints=MAX_ENVELOPE_POINTS; - envsustain=(envpars->Penvsustain==0)?-1:envpars->Penvsustain; - forcedrelase=envpars->Pforcedrelease; - envstretch=pow(440.0/basefreq,envpars->Penvstretch/64.0); - linearenvelope=envpars->Plinearenvelope; + envpoints = envpars->Penvpoints; + if(envpoints > MAX_ENVELOPE_POINTS) + envpoints = MAX_ENVELOPE_POINTS; + envsustain = (envpars->Penvsustain == 0) ? -1 : envpars->Penvsustain; + forcedrelase = envpars->Pforcedrelease; + envstretch = pow(440.0 / basefreq, envpars->Penvstretch / 64.0); + linearenvelope = envpars->Plinearenvelope; - if (envpars->Pfreemode==0) envpars->converttofree(); + if(envpars->Pfreemode == 0) + envpars->converttofree(); - REALTYPE bufferdt=SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE; + REALTYPE bufferdt = SOUND_BUFFER_SIZE / (REALTYPE)SAMPLE_RATE; - int mode=envpars->Envmode; + int mode = envpars->Envmode; //for amplitude envelopes - if ((mode==1)&&(linearenvelope==0)) mode=2;//change to log envelope - if ((mode==2)&&(linearenvelope!=0)) mode=1;//change to linear - - for (i=0;i<MAX_ENVELOPE_POINTS;i++) { - REALTYPE tmp=envpars->getdt(i)/1000.0*envstretch; - if (tmp>bufferdt) envdt[i]=bufferdt/tmp; - else envdt[i]=2.0;//any value larger than 1 - - switch (mode) { + if((mode == 1) && (linearenvelope == 0)) + mode = 2; //change to log envelope + if((mode == 2) && (linearenvelope != 0)) + mode = 1; //change to linear + + for(i = 0; i < MAX_ENVELOPE_POINTS; i++) { + REALTYPE tmp = envpars->getdt(i) / 1000.0 * envstretch; + if(tmp > bufferdt) + envdt[i] = bufferdt / tmp; + else + envdt[i] = 2.0; //any value larger than 1 + + switch(mode) { case 2: - envval[i]=(1.0-envpars->Penvval[i]/127.0)*MIN_ENVELOPE_DB; + envval[i] = (1.0 - envpars->Penvval[i] / 127.0) * MIN_ENVELOPE_DB; break; case 3: - envval[i]=(pow(2,6.0*fabs(envpars->Penvval[i]-64.0)/64.0)-1.0)*100.0; - if (envpars->Penvval[i]<64) envval[i]=-envval[i]; + envval[i] = + (pow(2, 6.0 + * fabs(envpars->Penvval[i] - 64.0) / 64.0) - 1.0) * 100.0; + if(envpars->Penvval[i] < 64) + envval[i] = -envval[i]; break; case 4: - envval[i]=(envpars->Penvval[i]-64.0)/64.0*6.0;//6 octaves (filtru) + envval[i] = (envpars->Penvval[i] - 64.0) / 64.0 * 6.0; //6 octaves (filtru) break; case 5: - envval[i]=(envpars->Penvval[i]-64.0)/64.0*10; + envval[i] = (envpars->Penvval[i] - 64.0) / 64.0 * 10; break; default: - envval[i]=envpars->Penvval[i]/127.0; - }; + envval[i] = envpars->Penvval[i] / 127.0; + } + } - }; + envdt[0] = 1.0; - envdt[0]=1.0; - - currentpoint=1;//the envelope starts from 1 - keyreleased=0; - t=0.0; - envfinish=0; - inct=envdt[1]; - envoutval=0.0; -}; + currentpoint = 1; //the envelope starts from 1 + keyreleased = 0; + t = 0.0; + envfinish = 0; + inct = envdt[1]; + envoutval = 0.0; +} Envelope::~Envelope() -{ -}; +{} /* @@ -88,10 +95,12 @@ Envelope::~Envelope() */ void Envelope::relasekey() { - if (keyreleased==1) return; - keyreleased=1; - if (forcedrelase!=0) t=0.0; -}; + if(keyreleased == 1) + return; + keyreleased = 1; + if(forcedrelase != 0) + t = 0.0; +} /* * Envelope Output @@ -100,46 +109,54 @@ REALTYPE Envelope::envout() { REALTYPE out; - if (envfinish!=0) {//if the envelope is finished - envoutval=envval[envpoints-1]; - return(envoutval); - }; - if ((currentpoint==envsustain+1)&&(keyreleased==0)) {//if it is sustaining now - envoutval=envval[envsustain]; - return(envoutval); - }; - - if ((keyreleased!=0) && (forcedrelase!=0)) {//do the forced release - - int tmp=(envsustain<0) ? (envpoints-1):(envsustain+1);//if there is no sustain point, use the last point for release - - if (envdt[tmp]<0.00000001) out=envval[tmp]; - else out=envoutval+(envval[tmp]-envoutval)*t; - t+=envdt[tmp]*envstretch; - - if (t>=1.0) { - currentpoint=envsustain+2; - forcedrelase=0; - t=0.0; - inct=envdt[currentpoint]; - if ((currentpoint>=envpoints)||(envsustain<0)) envfinish=1; - }; - return(out); - }; - if (inct>=1.0) out=envval[currentpoint]; - else out=envval[currentpoint-1]+(envval[currentpoint]-envval[currentpoint-1])*t; - - t+=inct; - if (t>=1.0) { - if (currentpoint>=envpoints-1) envfinish=1; - else currentpoint++; - t=0.0; - inct=envdt[currentpoint]; - }; - - envoutval=out; - return (out); -}; + if(envfinish != 0) { //if the envelope is finished + envoutval = envval[envpoints - 1]; + return envoutval; + } + if((currentpoint == envsustain + 1) && (keyreleased == 0)) { //if it is sustaining now + envoutval = envval[envsustain]; + return envoutval; + } + + if((keyreleased != 0) && (forcedrelase != 0)) { //do the forced release + int tmp = (envsustain < 0) ? (envpoints - 1) : (envsustain + 1); //if there is no sustain point, use the last point for release + + if(envdt[tmp] < 0.00000001) + out = envval[tmp]; + else + out = envoutval + (envval[tmp] - envoutval) * t; + t += envdt[tmp] * envstretch; + + if(t >= 1.0) { + currentpoint = envsustain + 2; + forcedrelase = 0; + t = 0.0; + inct = envdt[currentpoint]; + if((currentpoint >= envpoints) || (envsustain < 0)) + envfinish = 1; + } + return out; + } + if(inct >= 1.0) + out = envval[currentpoint]; + else + out = + envval[currentpoint + - 1] + (envval[currentpoint] - envval[currentpoint - 1]) * t; + + t += inct; + if(t >= 1.0) { + if(currentpoint >= envpoints - 1) + envfinish = 1; + else + currentpoint++; + t = 0.0; + inct = envdt[currentpoint]; + } + + envoutval = out; + return out; +} /* * Envelope Output (dB) @@ -147,30 +164,35 @@ REALTYPE Envelope::envout() REALTYPE Envelope::envout_dB() { REALTYPE out; - if (linearenvelope!=0) return (envout()); - - if ((currentpoint==1)&&((keyreleased==0)||(forcedrelase==0))) {//first point is always lineary interpolated - REALTYPE v1=dB2rap(envval[0]); - REALTYPE v2=dB2rap(envval[1]); - out=v1+(v2-v1)*t; - - t+=inct; - if (t>=1.0) { - t=0.0; - inct=envdt[2]; + if(linearenvelope != 0) + return envout(); + + if((currentpoint == 1) && ((keyreleased == 0) || (forcedrelase == 0))) { //first point is always lineary interpolated + REALTYPE v1 = dB2rap(envval[0]); + REALTYPE v2 = dB2rap(envval[1]); + out = v1 + (v2 - v1) * t; + + t += inct; + if(t >= 1.0) { + t = 0.0; + inct = envdt[2]; currentpoint++; - out=v2; - }; + out = v2; + } - if (out>0.001) envoutval=rap2dB(out); - else envoutval=-40.0; - } else out=dB2rap(envout()); + if(out > 0.001) + envoutval = rap2dB(out); + else + envoutval = -40.0; + } + else + out = dB2rap(envout()); - return(out); -}; + return out; +} int Envelope::finished() { - return(envfinish); -}; + return envfinish; +} diff --git a/src/Synth/Envelope.h b/src/Synth/Envelope.h @@ -30,35 +30,35 @@ /**Implementation of a general Envelope*/ class Envelope { -public: + public: - /**Constructor*/ - Envelope(EnvelopeParams *envpars,REALTYPE basefreq); - /**Destructor*/ - ~Envelope(); - void relasekey(); - REALTYPE envout(); - REALTYPE envout_dB(); - /**Determines the status of the Envelope - * - *\todo see if this can be changed to use a boolean - * @return returns 1 if the envelope is finished*/ - int finished(); -private: - int envpoints; - int envsustain;//"-1" means disabled - REALTYPE envdt[MAX_ENVELOPE_POINTS];//millisecons - REALTYPE envval[MAX_ENVELOPE_POINTS];// [0.0 .. 1.0] - REALTYPE envstretch; - int linearenvelope; + /**Constructor*/ + Envelope(EnvelopeParams *envpars, REALTYPE basefreq); + /**Destructor*/ + ~Envelope(); + void relasekey(); + REALTYPE envout(); + REALTYPE envout_dB(); + /**Determines the status of the Envelope + * + *\todo see if this can be changed to use a boolean + * @return returns 1 if the envelope is finished*/ + int finished(); + private: + int envpoints; + int envsustain; //"-1" means disabled + REALTYPE envdt[MAX_ENVELOPE_POINTS]; //millisecons + REALTYPE envval[MAX_ENVELOPE_POINTS]; // [0.0 .. 1.0] + REALTYPE envstretch; + int linearenvelope; - int currentpoint; //current envelope point (starts from 1) - int forcedrelase; - char keyreleased; //if the key was released /** \todo figure out WHY IS THIS A CHAR*/ - char envfinish; /** \todo figure out WHY IS THIS A CHAR*/ - REALTYPE t; // the time from the last point - REALTYPE inct;// the time increment - REALTYPE envoutval;//used to do the forced release + int currentpoint; //current envelope point (starts from 1) + int forcedrelase; + char keyreleased; //if the key was released /** \todo figure out WHY IS THIS A CHAR*/ + char envfinish; /** \todo figure out WHY IS THIS A CHAR*/ + REALTYPE t; // the time from the last point + REALTYPE inct; // the time increment + REALTYPE envoutval; //used to do the forced release }; diff --git a/src/Synth/LFO.cpp b/src/Synth/LFO.cpp @@ -27,59 +27,68 @@ #include "LFO.h" -LFO::LFO(LFOParams *lfopars,REALTYPE basefreq) +LFO::LFO(LFOParams *lfopars, REALTYPE basefreq) { - if (lfopars->Pstretch==0) lfopars->Pstretch=1; - REALTYPE lfostretch=pow(basefreq/440.0,(lfopars->Pstretch-64.0)/63.0);//max 2x/octave - - REALTYPE lfofreq=(pow(2,lfopars->Pfreq*10.0)-1.0)/12.0*lfostretch; - incx=fabs(lfofreq)*(REALTYPE)SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE; - - if (lfopars->Pcontinous==0) { - if (lfopars->Pstartphase==0) x=RND; - else x=fmod((lfopars->Pstartphase-64.0)/127.0+1.0,1.0); - } else { - REALTYPE tmp=fmod(lfopars->time*incx,1.0); - x=fmod((lfopars->Pstartphase-64.0)/127.0+1.0+tmp,1.0); - }; + if(lfopars->Pstretch == 0) + lfopars->Pstretch = 1; + REALTYPE lfostretch = pow(basefreq / 440.0, + (lfopars->Pstretch - 64.0) / 63.0); //max 2x/octave + + REALTYPE lfofreq = + (pow(2, lfopars->Pfreq * 10.0) - 1.0) / 12.0 * lfostretch; + incx = fabs(lfofreq) * (REALTYPE)SOUND_BUFFER_SIZE / (REALTYPE)SAMPLE_RATE; + + if(lfopars->Pcontinous == 0) { + if(lfopars->Pstartphase == 0) + x = RND; + else + x = fmod((lfopars->Pstartphase - 64.0) / 127.0 + 1.0, 1.0); + } + else { + REALTYPE tmp = fmod(lfopars->time * incx, 1.0); + x = fmod((lfopars->Pstartphase - 64.0) / 127.0 + 1.0 + tmp, 1.0); + } //Limit the Frequency(or else...) - if (incx>0.49999999) incx=0.499999999; + if(incx > 0.49999999) + incx = 0.499999999; - lfornd=lfopars->Prandomness/127.0; - if (lfornd<0.0) lfornd=0.0; - else if (lfornd>1.0) lfornd=1.0; + lfornd = lfopars->Prandomness / 127.0; + if(lfornd < 0.0) + lfornd = 0.0; + else + if(lfornd > 1.0) + lfornd = 1.0; // lfofreqrnd=pow(lfopars->Pfreqrand/127.0,2.0)*2.0*4.0; - lfofreqrnd=pow(lfopars->Pfreqrand/127.0,2.0)*4.0; + lfofreqrnd = pow(lfopars->Pfreqrand / 127.0, 2.0) * 4.0; - switch (lfopars->fel) { + switch(lfopars->fel) { case 1: - lfointensity=lfopars->Pintensity/127.0; + lfointensity = lfopars->Pintensity / 127.0; break; case 2: - lfointensity=lfopars->Pintensity/127.0*4.0; - break;//in octave + lfointensity = lfopars->Pintensity / 127.0 * 4.0; + break; //in octave default: - lfointensity=pow(2,lfopars->Pintensity/127.0*11.0)-1.0;//in centi - x-=0.25;//chance the starting phase + lfointensity = pow(2, lfopars->Pintensity / 127.0 * 11.0) - 1.0; //in centi + x -= 0.25; //chance the starting phase break; - }; - - amp1=(1-lfornd)+lfornd*RND; - amp2=(1-lfornd)+lfornd*RND; - lfotype=lfopars->PLFOtype; - lfodelay=lfopars->Pdelay/127.0*4.0;//0..4 sec - incrnd=nextincrnd=1.0; - freqrndenabled=(lfopars->Pfreqrand!=0); + } + + amp1 = (1 - lfornd) + lfornd * RND; + amp2 = (1 - lfornd) + lfornd * RND; + lfotype = lfopars->PLFOtype; + lfodelay = lfopars->Pdelay / 127.0 * 4.0; //0..4 sec + incrnd = nextincrnd = 1.0; + freqrndenabled = (lfopars->Pfreqrand != 0); computenextincrnd(); - computenextincrnd();//twice because I want incrnd & nextincrnd to be random -}; + computenextincrnd(); //twice because I want incrnd & nextincrnd to be random +} LFO::~LFO() -{ -}; +{} /* * LFO out @@ -87,53 +96,67 @@ LFO::~LFO() REALTYPE LFO::lfoout() { REALTYPE out; - switch (lfotype) { + switch(lfotype) { case 1: //LFO_TRIANGLE - if ((x>=0.0)&&(x<0.25)) out=4.0*x; - else if ((x>0.25)&&(x<0.75)) out=2-4*x; - else out=4.0*x-4.0; + if((x >= 0.0) && (x < 0.25)) + out = 4.0 * x; + else + if((x > 0.25) && (x < 0.75)) + out = 2 - 4 * x; + else + out = 4.0 * x - 4.0; break; case 2: //LFO_SQUARE - if (x<0.5) out=-1; - else out=1; + if(x < 0.5) + out = -1; + else + out = 1; break; case 3: //LFO_RAMPUP - out=(x-0.5)*2.0; + out = (x - 0.5) * 2.0; break; case 4: //LFO_RAMPDOWN - out=(0.5-x)*2.0; + out = (0.5 - x) * 2.0; break; case 5: //LFO_EXP_DOWN 1 - out=pow(0.05,x)*2.0-1.0; + out = pow(0.05, x) * 2.0 - 1.0; break; case 6: //LFO_EXP_DOWN 2 - out=pow(0.001,x)*2.0-1.0; + out = pow(0.001, x) * 2.0 - 1.0; break; default: - out=cos(x*2.0*PI);//LFO_SINE - }; + out = cos(x * 2.0 * PI); //LFO_SINE + } - if ((lfotype==0)||(lfotype==1)) out*=lfointensity*(amp1+x*(amp2-amp1)); - else out*=lfointensity*amp2; - if (lfodelay<0.00001) { - if (freqrndenabled==0) x+=incx; + if((lfotype == 0) || (lfotype == 1)) + out *= lfointensity * (amp1 + x * (amp2 - amp1)); + else + out *= lfointensity * amp2; + if(lfodelay < 0.00001) { + if(freqrndenabled == 0) + x += incx; else { - float tmp=(incrnd*(1.0-x)+nextincrnd*x); - if (tmp>1.0) tmp=1.0; - else if (tmp<0.0) tmp=0.0; - x+=incx*tmp; - }; - if (x>=1) { - x=fmod(x,1.0); - amp1=amp2; - amp2=(1-lfornd)+lfornd*RND; + float tmp = (incrnd * (1.0 - x) + nextincrnd * x); + if(tmp > 1.0) + tmp = 1.0; + else + if(tmp < 0.0) + tmp = 0.0; + x += incx * tmp; + } + if(x >= 1) { + x = fmod(x, 1.0); + amp1 = amp2; + amp2 = (1 - lfornd) + lfornd * RND; computenextincrnd(); - }; - } else lfodelay-=(REALTYPE)SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE; - return(out); -}; + } + } + else + lfodelay -= (REALTYPE)SOUND_BUFFER_SIZE / (REALTYPE)SAMPLE_RATE; + return out; +} /* * LFO out (for amplitude) @@ -141,17 +164,21 @@ REALTYPE LFO::lfoout() REALTYPE LFO::amplfoout() { REALTYPE out; - out=1.0-lfointensity+lfoout(); - if (out<-1.0) out=-1.0; - else if (out>1.0) out=1.0; - return(out); -}; + out = 1.0 - lfointensity + lfoout(); + if(out < -1.0) + out = -1.0; + else + if(out > 1.0) + out = 1.0; + return out; +} void LFO::computenextincrnd() { - if (freqrndenabled==0) return; - incrnd=nextincrnd; - nextincrnd=pow(0.5,lfofreqrnd)+RND*(pow(2.0,lfofreqrnd)-1.0); -}; + if(freqrndenabled == 0) + return; + incrnd = nextincrnd; + nextincrnd = pow(0.5, lfofreqrnd) + RND * (pow(2.0, lfofreqrnd) - 1.0); +} diff --git a/src/Synth/LFO.h b/src/Synth/LFO.h @@ -29,31 +29,30 @@ /**Class for creating Low Frequency Ocillators*/ class LFO { -public: - /**Constructor - * - * @param lfopars pointer to a LFOParams object - * @param basefreq base frequency of LFO - */ - LFO(LFOParams *lfopars, REALTYPE basefreq); - /**Deconstructor*/ - ~LFO(); - REALTYPE lfoout(); - REALTYPE amplfoout(); -private: - REALTYPE x; - REALTYPE incx,incrnd,nextincrnd; - REALTYPE amp1,amp2;// used for randomness - REALTYPE lfointensity; - REALTYPE lfornd,lfofreqrnd; - REALTYPE lfodelay; - /**\todo see if an enum would be better here*/ - char lfotype; - int freqrndenabled; - - - void computenextincrnd(); - + public: + /**Constructor + * + * @param lfopars pointer to a LFOParams object + * @param basefreq base frequency of LFO + */ + LFO(LFOParams *lfopars, REALTYPE basefreq); + /**Deconstructor*/ + ~LFO(); + REALTYPE lfoout(); + REALTYPE amplfoout(); + private: + REALTYPE x; + REALTYPE incx, incrnd, nextincrnd; + REALTYPE amp1, amp2; // used for randomness + REALTYPE lfointensity; + REALTYPE lfornd, lfofreqrnd; + REALTYPE lfodelay; + /**\todo see if an enum would be better here*/ + char lfotype; + int freqrndenabled; + + + void computenextincrnd(); }; #endif diff --git a/src/Synth/OscilGen.cpp b/src/Synth/OscilGen.cpp @@ -27,22 +27,22 @@ #include "OscilGen.h" #include "../Effects/Distorsion.h" -OscilGen::OscilGen(FFTwrapper *fft_,Resonance *res_):Presets() +OscilGen::OscilGen(FFTwrapper *fft_, Resonance *res_):Presets() { setpresettype("Poscilgen"); - fft=fft_; - res=res_; + fft = fft_; + res = res_; tmpsmps = new REALTYPE[OSCIL_SIZE]; - newFFTFREQS(&outoscilFFTfreqs, OSCIL_SIZE/2); - newFFTFREQS(&oscilFFTfreqs,OSCIL_SIZE/2); - newFFTFREQS(&basefuncFFTfreqs,OSCIL_SIZE/2); + newFFTFREQS(&outoscilFFTfreqs, OSCIL_SIZE / 2); + newFFTFREQS(&oscilFFTfreqs, OSCIL_SIZE / 2); + newFFTFREQS(&basefuncFFTfreqs, OSCIL_SIZE / 2); - randseed=1; - ADvsPAD=false; + randseed = 1; + ADvsPAD = false; defaults(); -}; +} OscilGen::~OscilGen() { @@ -50,237 +50,271 @@ OscilGen::~OscilGen() deleteFFTFREQS(&outoscilFFTfreqs); deleteFFTFREQS(&basefuncFFTfreqs); deleteFFTFREQS(&oscilFFTfreqs); -}; +} void OscilGen::defaults() { - - oldbasefunc=0; - oldbasepar=64; - oldhmagtype=0; - oldwaveshapingfunction=0; - oldwaveshaping=64; - 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; - Phmag[i]=64; - Phphase[i]=64; - }; - Phmag[0]=127; - Phmagtype=0; - if (ADvsPAD) Prand=127;//max phase randomness (usefull if the oscil will be imported to a ADsynth from a PADsynth - else Prand=64;//no randomness - - Pcurrentbasefunc=0; - Pbasefuncpar=64; - - Pbasefuncmodulation=0; - Pbasefuncmodulationpar1=64; - Pbasefuncmodulationpar2=64; - Pbasefuncmodulationpar3=32; - - Pmodulation=0; - Pmodulationpar1=64; - Pmodulationpar2=64; - Pmodulationpar3=32; - - Pwaveshapingfunction=0; - Pwaveshaping=64; - Pfiltertype=0; - Pfilterpar1=64; - Pfilterpar2=64; - Pfilterbeforews=0; - Psatype=0; - Psapar=64; - - Pamprandpower=64; - Pamprandtype=0; - - Pharmonicshift=0; - Pharmonicshiftfirst=0; - - Padaptiveharmonics=0; - Padaptiveharmonicspower=100; - Padaptiveharmonicsbasefreq=128; - Padaptiveharmonicspar=50; - - for (int i=0;i<OSCIL_SIZE/2;i++) { - oscilFFTfreqs.s[i]=0.0; - oscilFFTfreqs.c[i]=0.0; - basefuncFFTfreqs.s[i]=0.0; - basefuncFFTfreqs.c[i]=0.0; - }; - oscilprepared=0; - oldfilterpars=0; - oldsapars=0; + oldbasefunc = 0; + oldbasepar = 64; + oldhmagtype = 0; + oldwaveshapingfunction = 0; + oldwaveshaping = 64; + 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; + Phmag[i] = 64; + Phphase[i] = 64; + } + Phmag[0] = 127; + Phmagtype = 0; + if(ADvsPAD) + Prand = 127; //max phase randomness (usefull if the oscil will be imported to a ADsynth from a PADsynth + else + Prand = 64; //no randomness + + Pcurrentbasefunc = 0; + Pbasefuncpar = 64; + + Pbasefuncmodulation = 0; + Pbasefuncmodulationpar1 = 64; + Pbasefuncmodulationpar2 = 64; + Pbasefuncmodulationpar3 = 32; + + Pmodulation = 0; + Pmodulationpar1 = 64; + Pmodulationpar2 = 64; + Pmodulationpar3 = 32; + + Pwaveshapingfunction = 0; + Pwaveshaping = 64; + Pfiltertype = 0; + Pfilterpar1 = 64; + Pfilterpar2 = 64; + Pfilterbeforews = 0; + Psatype = 0; + Psapar = 64; + + Pamprandpower = 64; + Pamprandtype = 0; + + Pharmonicshift = 0; + Pharmonicshiftfirst = 0; + + Padaptiveharmonics = 0; + Padaptiveharmonicspower = 100; + Padaptiveharmonicsbasefreq = 128; + Padaptiveharmonicspar = 50; + + for(int i = 0; i < OSCIL_SIZE / 2; i++) { + oscilFFTfreqs.s[i] = 0.0; + oscilFFTfreqs.c[i] = 0.0; + basefuncFFTfreqs.s[i] = 0.0; + basefuncFFTfreqs.c[i] = 0.0; + } + oscilprepared = 0; + oldfilterpars = 0; + oldsapars = 0; prepare(); -}; +} void OscilGen::convert2sine(int magtype) { - REALTYPE mag[MAX_AD_HARMONICS],phase[MAX_AD_HARMONICS]; + REALTYPE mag[MAX_AD_HARMONICS], phase[MAX_AD_HARMONICS]; REALTYPE oscil[OSCIL_SIZE]; FFTFREQS freqs; - newFFTFREQS(&freqs,OSCIL_SIZE/2); - - get(oscil,-1.0); - FFTwrapper *fft=new FFTwrapper(OSCIL_SIZE); - fft->smps2freqs(oscil,freqs); - delete(fft); - - REALTYPE max=0.0; - - mag[0]=0; - phase[0]=0; - for (int i=0;i<MAX_AD_HARMONICS;i++) { - mag[i]=sqrt(pow(freqs.s[i+1],2)+pow(freqs.c[i+1],2.0)); - phase[i]=atan2(freqs.c[i+1],freqs.s[i+1]); - if (max<mag[i]) max=mag[i]; - }; - if (max<0.00001) max=1.0; + newFFTFREQS(&freqs, OSCIL_SIZE / 2); + + get(oscil, -1.0); + FFTwrapper *fft = new FFTwrapper(OSCIL_SIZE); + fft->smps2freqs(oscil, freqs); + delete (fft); + + REALTYPE max = 0.0; + + mag[0] = 0; + phase[0] = 0; + for(int i = 0; i < MAX_AD_HARMONICS; i++) { + mag[i] = sqrt(pow(freqs.s[i + 1], 2) + pow(freqs.c[i + 1], 2.0)); + phase[i] = atan2(freqs.c[i + 1], freqs.s[i + 1]); + if(max < mag[i]) + max = mag[i]; + } + if(max < 0.00001) + max = 1.0; defaults(); - for (int i=0;i<MAX_AD_HARMONICS-1;i++) { - REALTYPE newmag=mag[i]/max; - REALTYPE newphase=phase[i]; + for(int i = 0; i < MAX_AD_HARMONICS - 1; i++) { + REALTYPE newmag = mag[i] / max; + REALTYPE newphase = phase[i]; - Phmag[i]=(int) ((newmag)*64.0)+64; + Phmag[i] = (int) ((newmag) * 64.0) + 64; - Phphase[i]=64-(int) (64.0*newphase/PI); - if (Phphase[i]>127) Phphase[i]=127; + Phphase[i] = 64 - (int) (64.0 * newphase / PI); + if(Phphase[i] > 127) + Phphase[i] = 127; - if (Phmag[i]==64) Phphase[i]=64; - }; + if(Phmag[i] == 64) + Phphase[i] = 64; + } deleteFFTFREQS(&freqs); prepare(); -}; +} /* * Base Functions - START */ -REALTYPE OscilGen::basefunc_pulse(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_pulse(REALTYPE x, REALTYPE a) { - return((fmod(x,1.0)<a)?-1.0:1.0); -}; + return (fmod(x, 1.0) < a) ? -1.0 : 1.0; +} -REALTYPE OscilGen::basefunc_saw(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_saw(REALTYPE x, REALTYPE a) { - if (a<0.00001) a=0.00001; - else if (a>0.99999) a=0.99999; - x=fmod(x,1); - if (x<a) return(x/a*2.0-1.0); - else return((1.0-x)/(1.0-a)*2.0-1.0); -}; - -REALTYPE OscilGen::basefunc_triangle(REALTYPE x,REALTYPE a) + if(a < 0.00001) + a = 0.00001; + else + if(a > 0.99999) + a = 0.99999; + x = fmod(x, 1); + if(x < a) + return x / a * 2.0 - 1.0; + else + return (1.0 - x) / (1.0 - a) * 2.0 - 1.0; +} + +REALTYPE OscilGen::basefunc_triangle(REALTYPE x, REALTYPE a) { - x=fmod(x+0.25,1); - a=1-a; - if (a<0.00001) a=0.00001; - if (x<0.5) x=x*4-1.0; - else x=(1.0-x)*4-1.0; - x/=-a; - if (x<-1.0) x=-1.0; - if (x>1.0) x=1.0; - return(x); -}; - -REALTYPE OscilGen::basefunc_power(REALTYPE x,REALTYPE a) + x = fmod(x + 0.25, 1); + a = 1 - a; + if(a < 0.00001) + a = 0.00001; + if(x < 0.5) + x = x * 4 - 1.0; + else + x = (1.0 - x) * 4 - 1.0; + x /= -a; + if(x < -1.0) + x = -1.0; + if(x > 1.0) + x = 1.0; + return x; +} + +REALTYPE OscilGen::basefunc_power(REALTYPE x, REALTYPE a) { - x=fmod(x,1); - if (a<0.00001) a=0.00001; - else if (a>0.99999) a=0.99999; - return(pow(x,exp((a-0.5)*10.0))*2.0-1.0); -}; - -REALTYPE OscilGen::basefunc_gauss(REALTYPE x,REALTYPE a) + x = fmod(x, 1); + if(a < 0.00001) + a = 0.00001; + else + if(a > 0.99999) + a = 0.99999; + return pow(x, exp((a - 0.5) * 10.0)) * 2.0 - 1.0; +} + +REALTYPE OscilGen::basefunc_gauss(REALTYPE x, REALTYPE a) { - x=fmod(x,1)*2.0-1.0; - if (a<0.00001) a=0.00001; - return(exp(-x*x*(exp(a*8)+5.0))*2.0-1.0); -}; + x = fmod(x, 1) * 2.0 - 1.0; + if(a < 0.00001) + a = 0.00001; + return exp(-x * x * (exp(a * 8) + 5.0)) * 2.0 - 1.0; +} -REALTYPE OscilGen::basefunc_diode(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_diode(REALTYPE x, REALTYPE a) { - if (a<0.00001) a=0.00001; - else if (a>0.99999) a=0.99999; - a=a*2.0-1.0; - x=cos((x+0.5)*2.0*PI)-a; - if (x<0.0) x=0.0; - return(x/(1.0-a)*2-1.0); -}; - -REALTYPE OscilGen::basefunc_abssine(REALTYPE x,REALTYPE a) + if(a < 0.00001) + a = 0.00001; + else + if(a > 0.99999) + a = 0.99999; + a = a * 2.0 - 1.0; + x = cos((x + 0.5) * 2.0 * PI) - a; + if(x < 0.0) + x = 0.0; + return x / (1.0 - a) * 2 - 1.0; +} + +REALTYPE OscilGen::basefunc_abssine(REALTYPE x, REALTYPE a) { - x=fmod(x,1); - if (a<0.00001) a=0.00001; - else if (a>0.99999) a=0.99999; - return(sin(pow(x,exp((a-0.5)*5.0))*PI)*2.0-1.0); -}; - -REALTYPE OscilGen::basefunc_pulsesine(REALTYPE x,REALTYPE a) + x = fmod(x, 1); + if(a < 0.00001) + a = 0.00001; + else + if(a > 0.99999) + a = 0.99999; + return sin(pow(x, exp((a - 0.5) * 5.0)) * PI) * 2.0 - 1.0; +} + +REALTYPE OscilGen::basefunc_pulsesine(REALTYPE x, REALTYPE a) { - if (a<0.00001) a=0.00001; - x=(fmod(x,1)-0.5)*exp((a-0.5)*log(128)); - if (x<-0.5) x=-0.5; - else if (x>0.5) x=0.5; - x=sin(x*PI*2.0); - return(x); -}; - -REALTYPE OscilGen::basefunc_stretchsine(REALTYPE x,REALTYPE a) + if(a < 0.00001) + a = 0.00001; + x = (fmod(x, 1) - 0.5) * exp((a - 0.5) * log(128)); + if(x < -0.5) + x = -0.5; + else + if(x > 0.5) + x = 0.5; + x = sin(x * PI * 2.0); + return x; +} + +REALTYPE OscilGen::basefunc_stretchsine(REALTYPE x, REALTYPE a) { - x=fmod(x+0.5,1)*2.0-1.0; - a=(a-0.5)*4; - if (a>0.0) a*=2; - a=pow(3.0,a); - REALTYPE b=pow(fabs(x),a); - if (x<0) b=-b; - return(-sin(b*PI)); -}; - -REALTYPE OscilGen::basefunc_chirp(REALTYPE x,REALTYPE a) + x = fmod(x + 0.5, 1) * 2.0 - 1.0; + a = (a - 0.5) * 4; + if(a > 0.0) + a *= 2; + a = pow(3.0, a); + REALTYPE b = pow(fabs(x), a); + if(x < 0) + b = -b; + return -sin(b * PI); +} + +REALTYPE OscilGen::basefunc_chirp(REALTYPE x, REALTYPE a) { - x=fmod(x,1.0)*2.0*PI; - a=(a-0.5)*4; - if (a<0.0) a*=2.0; - a=pow(3.0,a); - return(sin(x/2.0)*sin(a*x*x)); -}; - -REALTYPE OscilGen::basefunc_absstretchsine(REALTYPE x,REALTYPE a) + x = fmod(x, 1.0) * 2.0 * PI; + a = (a - 0.5) * 4; + if(a < 0.0) + a *= 2.0; + a = pow(3.0, a); + return sin(x / 2.0) * sin(a * x * x); +} + +REALTYPE OscilGen::basefunc_absstretchsine(REALTYPE x, REALTYPE a) { - x=fmod(x+0.5,1)*2.0-1.0; - a=(a-0.5)*9; - a=pow(3.0,a); - REALTYPE b=pow(fabs(x),a); - if (x<0) b=-b; - return(-pow(sin(b*PI),2)); -}; - -REALTYPE OscilGen::basefunc_chebyshev(REALTYPE x,REALTYPE a) + x = fmod(x + 0.5, 1) * 2.0 - 1.0; + a = (a - 0.5) * 9; + a = pow(3.0, a); + REALTYPE b = pow(fabs(x), a); + if(x < 0) + b = -b; + return -pow(sin(b * PI), 2); +} + +REALTYPE OscilGen::basefunc_chebyshev(REALTYPE x, REALTYPE a) { - a=a*a*a*30.0+1.0; - return(cos(acos(x*2.0-1.0)*a)); -}; + a = a * a * a * 30.0 + 1.0; + return cos(acos(x * 2.0 - 1.0) * a); +} -REALTYPE OscilGen::basefunc_sqr(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_sqr(REALTYPE x, REALTYPE a) { - a=a*a*a*a*160.0+0.001; - return(-atan(sin(x*2.0*PI)*a)); -}; + a = a * a * a * a * 160.0 + 0.001; + return -atan(sin(x * 2.0 * PI) * a); +} /* * Base Functions - END */ @@ -291,223 +325,266 @@ REALTYPE OscilGen::basefunc_sqr(REALTYPE x,REALTYPE a) */ void OscilGen::getbasefunction(REALTYPE *smps) { - int i; - REALTYPE par=(Pbasefuncpar+0.5)/128.0; - if (Pbasefuncpar==64) par=0.5; + int i; + REALTYPE par = (Pbasefuncpar + 0.5) / 128.0; + if(Pbasefuncpar == 64) + par = 0.5; - REALTYPE basefuncmodulationpar1=Pbasefuncmodulationpar1/127.0, - basefuncmodulationpar2=Pbasefuncmodulationpar2/127.0, - basefuncmodulationpar3=Pbasefuncmodulationpar3/127.0; + REALTYPE basefuncmodulationpar1 = Pbasefuncmodulationpar1 / 127.0, + basefuncmodulationpar2 = Pbasefuncmodulationpar2 / 127.0, + basefuncmodulationpar3 = Pbasefuncmodulationpar3 / 127.0; - switch (Pbasefuncmodulation) { + switch(Pbasefuncmodulation) { case 1: - basefuncmodulationpar1=(pow(2,basefuncmodulationpar1*5.0)-1.0)/10.0; - basefuncmodulationpar3=floor((pow(2,basefuncmodulationpar3*5.0)-1.0)); - if (basefuncmodulationpar3<0.9999) basefuncmodulationpar3=-1.0; + basefuncmodulationpar1 = + (pow(2, basefuncmodulationpar1 * 5.0) - 1.0) / 10.0; + basefuncmodulationpar3 = + floor((pow(2, basefuncmodulationpar3 * 5.0) - 1.0)); + if(basefuncmodulationpar3 < 0.9999) + basefuncmodulationpar3 = -1.0; break; case 2: - basefuncmodulationpar1=(pow(2,basefuncmodulationpar1*5.0)-1.0)/10.0; - basefuncmodulationpar3=1.0+floor((pow(2,basefuncmodulationpar3*5.0)-1.0)); + basefuncmodulationpar1 = + (pow(2, basefuncmodulationpar1 * 5.0) - 1.0) / 10.0; + basefuncmodulationpar3 = 1.0 + + floor((pow(2, basefuncmodulationpar3 + * 5.0) - 1.0)); break; case 3: - basefuncmodulationpar1=(pow(2,basefuncmodulationpar1*7.0)-1.0)/10.0; - basefuncmodulationpar3=0.01+(pow(2,basefuncmodulationpar3*16.0)-1.0)/10.0; + basefuncmodulationpar1 = + (pow(2, basefuncmodulationpar1 * 7.0) - 1.0) / 10.0; + basefuncmodulationpar3 = 0.01 + + (pow(2, basefuncmodulationpar3 + * 16.0) - 1.0) / 10.0; break; - }; + } // printf("%.5f %.5f\n",basefuncmodulationpar1,basefuncmodulationpar3); - for (i=0;i<OSCIL_SIZE;i++) { - REALTYPE t=i*1.0/OSCIL_SIZE; + for(i = 0; i < OSCIL_SIZE; i++) { + REALTYPE t = i * 1.0 / OSCIL_SIZE; - switch (Pbasefuncmodulation) { + switch(Pbasefuncmodulation) { case 1: - t=t*basefuncmodulationpar3+sin((t+basefuncmodulationpar2)*2.0*PI)*basefuncmodulationpar1;//rev + t = t * basefuncmodulationpar3 + sin( + (t + + basefuncmodulationpar2) * 2.0 * PI) * basefuncmodulationpar1; //rev break; case 2: - t=t+sin((t*basefuncmodulationpar3+basefuncmodulationpar2)*2.0*PI)*basefuncmodulationpar1;//sine + t = t + sin( + (t * basefuncmodulationpar3 + + basefuncmodulationpar2) * 2.0 * PI) * basefuncmodulationpar1; //sine break; case 3: - t=t+pow((1.0-cos((t+basefuncmodulationpar2)*2.0*PI))*0.5,basefuncmodulationpar3)*basefuncmodulationpar1;//power + t = t + pow((1.0 - cos( + (t + basefuncmodulationpar2) * 2.0 * PI)) * 0.5, + basefuncmodulationpar3) * basefuncmodulationpar1; //power break; - }; + } - t=t-floor(t); + t = t - floor(t); - switch (Pcurrentbasefunc) { + switch(Pcurrentbasefunc) { case 1: - smps[i]=basefunc_triangle(t,par); + smps[i] = basefunc_triangle(t, par); break; case 2: - smps[i]=basefunc_pulse(t,par); + smps[i] = basefunc_pulse(t, par); break; case 3: - smps[i]=basefunc_saw(t,par); + smps[i] = basefunc_saw(t, par); break; case 4: - smps[i]=basefunc_power(t,par); + smps[i] = basefunc_power(t, par); break; case 5: - smps[i]=basefunc_gauss(t,par); + smps[i] = basefunc_gauss(t, par); break; case 6: - smps[i]=basefunc_diode(t,par); + smps[i] = basefunc_diode(t, par); break; case 7: - smps[i]=basefunc_abssine(t,par); + smps[i] = basefunc_abssine(t, par); break; case 8: - smps[i]=basefunc_pulsesine(t,par); + smps[i] = basefunc_pulsesine(t, par); break; case 9: - smps[i]=basefunc_stretchsine(t,par); + smps[i] = basefunc_stretchsine(t, par); break; case 10: - smps[i]=basefunc_chirp(t,par); + smps[i] = basefunc_chirp(t, par); break; case 11: - smps[i]=basefunc_absstretchsine(t,par); + smps[i] = basefunc_absstretchsine(t, par); break; case 12: - smps[i]=basefunc_chebyshev(t,par); + smps[i] = basefunc_chebyshev(t, par); break; case 13: - smps[i]=basefunc_sqr(t,par); + smps[i] = basefunc_sqr(t, par); break; default: - smps[i]=-sin(2.0*PI*i/OSCIL_SIZE); - }; - }; -}; + smps[i] = -sin(2.0 * PI * i / OSCIL_SIZE); + } + } +} /* * Filter the oscillator */ void OscilGen::oscilfilter() { - if (Pfiltertype==0) return; - REALTYPE par=1.0-Pfilterpar1/128.0; - REALTYPE par2=Pfilterpar2/127.0; - REALTYPE max=0.0,tmp=0.0,p2,x; - for (int i=1;i<OSCIL_SIZE/2;i++) { - REALTYPE gain=1.0; - switch (Pfiltertype) { + if(Pfiltertype == 0) + return; + REALTYPE par = 1.0 - Pfilterpar1 / 128.0; + REALTYPE par2 = Pfilterpar2 / 127.0; + REALTYPE max = 0.0, tmp = 0.0, p2, x; + for(int i = 1; i < OSCIL_SIZE / 2; i++) { + REALTYPE gain = 1.0; + switch(Pfiltertype) { case 1: - gain=pow(1.0-par*par*par*0.99,i);//lp - tmp=par2*par2*par2*par2*0.5+0.0001; - if (gain<tmp) gain=pow(gain,10.0)/pow(tmp,9.0); + gain = pow(1.0 - par * par * par * 0.99, i); //lp + tmp = par2 * par2 * par2 * par2 * 0.5 + 0.0001; + if(gain < tmp) + gain = pow(gain, 10.0) / pow(tmp, 9.0); break; case 2: - gain=1.0-pow(1.0-par*par,i+1);//hp1 - gain=pow(gain,par2*2.0+0.1); + gain = 1.0 - pow(1.0 - par * par, i + 1); //hp1 + gain = pow(gain, par2 * 2.0 + 0.1); break; case 3: - if (par<0.2) par=par*0.25+0.15; - gain=1.0-pow(1.0-par*par*0.999+0.001,i*0.05*i+1.0);//hp1b - tmp=pow(5.0,par2*2.0); - gain=pow(gain,tmp); + if(par < 0.2) + par = par * 0.25 + 0.15; + gain = 1.0 - pow(1.0 - par * par * 0.999 + 0.001, + i * 0.05 * i + 1.0); //hp1b + tmp = pow(5.0, par2 * 2.0); + gain = pow(gain, tmp); break; case 4: - gain=i+1-pow(2,(1.0-par)*7.5);//bp1 - gain=1.0/(1.0+gain*gain/(i+1.0)); - tmp=pow(5.0,par2*2.0); - gain=pow(gain,tmp); - if (gain<1e-5) gain=1e-5; + gain = i + 1 - pow(2, (1.0 - par) * 7.5); //bp1 + gain = 1.0 / (1.0 + gain * gain / (i + 1.0)); + tmp = pow(5.0, par2 * 2.0); + gain = pow(gain, tmp); + if(gain < 1e-5) + gain = 1e-5; break; case 5: - gain=i+1-pow(2,(1.0-par)*7.5);//bs1 - gain=pow(atan(gain/(i/10.0+1))/1.57,6); - gain=pow(gain,par2*par2*3.9+0.1); + gain = i + 1 - pow(2, (1.0 - par) * 7.5); //bs1 + gain = pow(atan(gain / (i / 10.0 + 1)) / 1.57, 6); + gain = pow(gain, par2 * par2 * 3.9 + 0.1); break; case 6: - tmp=pow(par2,0.33); - gain=(i+1>pow(2,(1.0-par)*10)?0.0:1.0)*par2+(1.0-par2);//lp2 + tmp = pow(par2, 0.33); + gain = + (i + 1 > + pow(2, (1.0 - par) * 10) ? 0.0 : 1.0) * par2 + (1.0 - par2); //lp2 break; case 7: - tmp=pow(par2,0.33); + tmp = pow(par2, 0.33); //tmp=1.0-(1.0-par2)*(1.0-par2); - gain=(i+1>pow(2,(1.0-par)*7)?1.0:0.0)*par2+(1.0-par2);//hp2 - if (Pfilterpar1==0) gain=1.0; + gain = + (i + 1 > + pow(2, (1.0 - par) * 7) ? 1.0 : 0.0) * par2 + (1.0 - par2); //hp2 + if(Pfilterpar1 == 0) + gain = 1.0; break; case 8: - tmp=pow(par2,0.33); + tmp = pow(par2, 0.33); //tmp=1.0-(1.0-par2)*(1.0-par2); - gain=(fabs(pow(2,(1.0-par)*7)-i)>i/2+1?0.0:1.0)*par2+(1.0-par2);//bp2 + gain = + (fabs(pow(2, + (1.0 + - par) + * 7) - i) > i / 2 + 1 ? 0.0 : 1.0) * par2 + (1.0 - par2); //bp2 break; case 9: - tmp=pow(par2,0.33); - gain=(fabs(pow(2,(1.0-par)*7)-i)<i/2+1?0.0:1.0)*par2+(1.0-par2);//bs2 + tmp = pow(par2, 0.33); + gain = + (fabs(pow(2, + (1.0 + - par) + * 7) - i) < i / 2 + 1 ? 0.0 : 1.0) * par2 + (1.0 - par2); //bs2 break; case 10: - tmp=pow(5.0,par2*2.0-1.0); - tmp=pow(i/32.0,tmp)*32.0; - if (Pfilterpar2==64) tmp=i; - gain=cos(par*par*PI/2.0*tmp);//cos - gain*=gain; + tmp = pow(5.0, par2 * 2.0 - 1.0); + tmp = pow(i / 32.0, tmp) * 32.0; + if(Pfilterpar2 == 64) + tmp = i; + gain = cos(par * par * PI / 2.0 * tmp); //cos + gain *= gain; break; case 11: - tmp=pow(5.0,par2*2.0-1.0); - tmp=pow(i/32.0,tmp)*32.0; - if (Pfilterpar2==64) tmp=i; - gain=sin(par*par*PI/2.0*tmp);//sin - gain*=gain; + tmp = pow(5.0, par2 * 2.0 - 1.0); + tmp = pow(i / 32.0, tmp) * 32.0; + if(Pfilterpar2 == 64) + tmp = i; + gain = sin(par * par * PI / 2.0 * tmp); //sin + gain *= gain; break; case 12: - p2=1.0-par+0.2; - x=i/(64.0*p2*p2); - if (x<0.0) x=0.0; - else if (x>1.0) x=1.0; - tmp=pow(1.0-par2,2.0); - gain=cos(x*PI)*(1.0-tmp)+1.01+tmp;//low shelf + p2 = 1.0 - par + 0.2; + x = i / (64.0 * p2 * p2); + if(x < 0.0) + x = 0.0; + else + if(x > 1.0) + x = 1.0; + tmp = pow(1.0 - par2, 2.0); + gain = cos(x * PI) * (1.0 - tmp) + 1.01 + tmp; //low shelf break; case 13: - tmp=(int) (pow(2.0,(1.0-par)*7.2)); - gain=1.0; - if (i==(int) (tmp)) gain=pow(2.0,par2*par2*8.0); + tmp = (int) (pow(2.0, (1.0 - par) * 7.2)); + gain = 1.0; + if(i == (int) (tmp)) + gain = pow(2.0, par2 * par2 * 8.0); break; - }; + } - oscilFFTfreqs.s[i]*=gain; - oscilFFTfreqs.c[i]*=gain; - REALTYPE tmp=oscilFFTfreqs.s[i]*oscilFFTfreqs.s[i]+ - oscilFFTfreqs.c[i]*oscilFFTfreqs.c[i]; - if (max<tmp) max=tmp; - }; + oscilFFTfreqs.s[i] *= gain; + oscilFFTfreqs.c[i] *= gain; + REALTYPE tmp = oscilFFTfreqs.s[i] * oscilFFTfreqs.s[i] + + oscilFFTfreqs.c[i] * oscilFFTfreqs.c[i]; + if(max < tmp) + max = tmp; + } - max=sqrt(max); - if (max<1e-10) max=1.0; - REALTYPE imax=1.0/max; - for (int i=1;i<OSCIL_SIZE/2;i++) { - oscilFFTfreqs.s[i]*=imax; - oscilFFTfreqs.c[i]*=imax; - }; -}; + max = sqrt(max); + if(max < 1e-10) + max = 1.0; + REALTYPE imax = 1.0 / max; + for(int i = 1; i < OSCIL_SIZE / 2; i++) { + oscilFFTfreqs.s[i] *= imax; + oscilFFTfreqs.c[i] *= imax; + } +} /* * Change the base function */ void OscilGen::changebasefunction() { - if (Pcurrentbasefunc!=0) { + if(Pcurrentbasefunc != 0) { getbasefunction(tmpsmps); - fft->smps2freqs(tmpsmps,basefuncFFTfreqs); - basefuncFFTfreqs.c[0]=0.0; - } else { - for (int i=0;i<OSCIL_SIZE/2;i++) { - basefuncFFTfreqs.s[i]=0.0; - basefuncFFTfreqs.c[i]=0.0; - }; + fft->smps2freqs(tmpsmps, basefuncFFTfreqs); + basefuncFFTfreqs.c[0] = 0.0; + } + else { + for(int i = 0; i < OSCIL_SIZE / 2; i++) { + basefuncFFTfreqs.s[i] = 0.0; + basefuncFFTfreqs.c[i] = 0.0; + } //in this case basefuncFFTfreqs_ are not used } - oscilprepared=0; - oldbasefunc=Pcurrentbasefunc; - oldbasepar=Pbasefuncpar; - oldbasefuncmodulation=Pbasefuncmodulation; - oldbasefuncmodulationpar1=Pbasefuncmodulationpar1; - oldbasefuncmodulationpar2=Pbasefuncmodulationpar2; - oldbasefuncmodulationpar3=Pbasefuncmodulationpar3; -}; + oscilprepared = 0; + oldbasefunc = Pcurrentbasefunc; + oldbasepar = Pbasefuncpar; + oldbasefuncmodulation = Pbasefuncmodulation; + oldbasefuncmodulationpar1 = Pbasefuncmodulationpar1; + oldbasefuncmodulationpar2 = Pbasefuncmodulationpar2; + oldbasefuncmodulationpar3 = Pbasefuncmodulationpar3; +} /* * Waveshape @@ -516,32 +593,36 @@ void OscilGen::waveshape() { int i; - oldwaveshapingfunction=Pwaveshapingfunction; - oldwaveshaping=Pwaveshaping; - if (Pwaveshapingfunction==0) return; + oldwaveshapingfunction = Pwaveshapingfunction; + oldwaveshaping = Pwaveshaping; + if(Pwaveshapingfunction == 0) + return; - oscilFFTfreqs.c[0]=0.0;//remove the DC + oscilFFTfreqs.c[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.s[OSCIL_SIZE/2-i]*=tmp; - oscilFFTfreqs.c[OSCIL_SIZE/2-i]*=tmp; - }; - fft->freqs2smps(oscilFFTfreqs,tmpsmps); + for(i = 1; i < OSCIL_SIZE / 8; i++) { + REALTYPE tmp = i / (OSCIL_SIZE / 8.0); + oscilFFTfreqs.s[OSCIL_SIZE / 2 - i] *= tmp; + oscilFFTfreqs.c[OSCIL_SIZE / 2 - i] *= tmp; + } + fft->freqs2smps(oscilFFTfreqs, tmpsmps); //Normalize - REALTYPE 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; + REALTYPE 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; //Do the waveshaping - waveshapesmps(OSCIL_SIZE,tmpsmps,Pwaveshapingfunction,Pwaveshaping); + waveshapesmps(OSCIL_SIZE, tmpsmps, Pwaveshapingfunction, Pwaveshaping); - fft->smps2freqs(tmpsmps,oscilFFTfreqs);//perform FFT -}; + fft->smps2freqs(tmpsmps, oscilFFTfreqs); //perform FFT +} /* @@ -551,79 +632,91 @@ void OscilGen::modulation() { int i; - oldmodulation=Pmodulation; - oldmodulationpar1=Pmodulationpar1; - oldmodulationpar2=Pmodulationpar2; - oldmodulationpar3=Pmodulationpar3; - if (Pmodulation==0) return; + oldmodulation = Pmodulation; + oldmodulationpar1 = Pmodulationpar1; + oldmodulationpar2 = Pmodulationpar2; + oldmodulationpar3 = Pmodulationpar3; + if(Pmodulation == 0) + return; - REALTYPE modulationpar1=Pmodulationpar1/127.0, - modulationpar2=0.5-Pmodulationpar2/127.0, - modulationpar3=Pmodulationpar3/127.0; + REALTYPE modulationpar1 = Pmodulationpar1 / 127.0, + modulationpar2 = 0.5 - Pmodulationpar2 / 127.0, + modulationpar3 = Pmodulationpar3 / 127.0; - switch (Pmodulation) { + switch(Pmodulation) { case 1: - modulationpar1=(pow(2,modulationpar1*7.0)-1.0)/100.0; - modulationpar3=floor((pow(2,modulationpar3*5.0)-1.0)); - if (modulationpar3<0.9999) modulationpar3=-1.0; + modulationpar1 = (pow(2, modulationpar1 * 7.0) - 1.0) / 100.0; + modulationpar3 = floor((pow(2, modulationpar3 * 5.0) - 1.0)); + if(modulationpar3 < 0.9999) + modulationpar3 = -1.0; break; case 2: - modulationpar1=(pow(2,modulationpar1*7.0)-1.0)/100.0; - modulationpar3=1.0+floor((pow(2,modulationpar3*5.0)-1.0)); + modulationpar1 = (pow(2, modulationpar1 * 7.0) - 1.0) / 100.0; + modulationpar3 = 1.0 + floor((pow(2, modulationpar3 * 5.0) - 1.0)); break; case 3: - modulationpar1=(pow(2,modulationpar1*9.0)-1.0)/100.0; - modulationpar3=0.01+(pow(2,modulationpar3*16.0)-1.0)/10.0; + modulationpar1 = (pow(2, modulationpar1 * 9.0) - 1.0) / 100.0; + modulationpar3 = 0.01 + (pow(2, modulationpar3 * 16.0) - 1.0) / 10.0; break; - }; + } - oscilFFTfreqs.c[0]=0.0;//remove the DC + oscilFFTfreqs.c[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.s[OSCIL_SIZE/2-i]*=tmp; - oscilFFTfreqs.c[OSCIL_SIZE/2-i]*=tmp; - }; - fft->freqs2smps(oscilFFTfreqs,tmpsmps); - int extra_points=2; - REALTYPE *in=new REALTYPE[OSCIL_SIZE+extra_points]; + for(i = 1; i < OSCIL_SIZE / 8; i++) { + REALTYPE tmp = i / (OSCIL_SIZE / 8.0); + oscilFFTfreqs.s[OSCIL_SIZE / 2 - i] *= tmp; + oscilFFTfreqs.c[OSCIL_SIZE / 2 - i] *= tmp; + } + fft->freqs2smps(oscilFFTfreqs, tmpsmps); + 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(tmpsmps[i])) max=fabs(tmpsmps[i]); - if (max<0.00001) max=1.0; - max=1.0/max; - for (i=0;i<OSCIL_SIZE;i++) in[i]=tmpsmps[i]*max; - for (i=0;i<extra_points;i++) in[i+OSCIL_SIZE]=tmpsmps[i]*max; + REALTYPE 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++) + in[i] = tmpsmps[i] * max; + for(i = 0; i < extra_points; i++) + in[i + OSCIL_SIZE] = tmpsmps[i] * max; //Do the modulation - for (i=0;i<OSCIL_SIZE;i++) { - REALTYPE t=i*1.0/OSCIL_SIZE; + for(i = 0; i < OSCIL_SIZE; i++) { + REALTYPE t = i * 1.0 / OSCIL_SIZE; - switch (Pmodulation) { + switch(Pmodulation) { case 1: - t=t*modulationpar3+sin((t+modulationpar2)*2.0*PI)*modulationpar1;//rev + 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 + 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 + t = t + pow((1.0 - cos( + (t + modulationpar2) * 2.0 * PI)) * 0.5, + modulationpar3) * modulationpar1; //power break; - }; + } - t=(t-floor(t))*OSCIL_SIZE; + t = (t - floor(t)) * OSCIL_SIZE; - int poshi=(int) t; - REALTYPE poslo=t-floor(t); + int poshi = (int) t; + REALTYPE poslo = t - floor(t); - tmpsmps[i]=in[poshi]*(1.0-poslo)+in[poshi+1]*poslo; - }; + tmpsmps[i] = in[poshi] * (1.0 - poslo) + in[poshi + 1] * poslo; + } delete [] in; - fft->smps2freqs(tmpsmps,oscilFFTfreqs);//perform FFT -}; + fft->smps2freqs(tmpsmps, oscilFFTfreqs); //perform FFT +} @@ -632,477 +725,534 @@ void OscilGen::modulation() */ void OscilGen::spectrumadjust() { - if (Psatype==0) return; - REALTYPE par=Psapar/127.0; - switch (Psatype) { + if(Psatype == 0) + return; + REALTYPE par = Psapar / 127.0; + switch(Psatype) { case 1: - par=1.0-par*2.0; - if (par>=0.0) par=pow(5.0,par); - else par=pow(8.0,par); + par = 1.0 - par * 2.0; + if(par >= 0.0) + par = pow(5.0, par); + else + par = pow(8.0, par); break; case 2: - par=pow(10.0,(1.0-par)*3.0)*0.25; + par = pow(10.0, (1.0 - par) * 3.0) * 0.25; break; case 3: - par=pow(10.0,(1.0-par)*3.0)*0.25; + par = pow(10.0, (1.0 - par) * 3.0) * 0.25; break; - }; + } - REALTYPE max=0.0; - for (int i=0;i<OSCIL_SIZE/2;i++) { - REALTYPE 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; + REALTYPE max = 0.0; + for(int i = 0; i < OSCIL_SIZE / 2; i++) { + REALTYPE 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; - for (int i=0;i<OSCIL_SIZE/2;i++) { - REALTYPE mag=sqrt(pow(oscilFFTfreqs.s[i],2)+pow(oscilFFTfreqs.c[i],2.0))/max; - REALTYPE phase=atan2(oscilFFTfreqs.s[i],oscilFFTfreqs.c[i]); + for(int i = 0; i < OSCIL_SIZE / 2; i++) { + REALTYPE mag = + sqrt(pow(oscilFFTfreqs.s[i], + 2) + pow(oscilFFTfreqs.c[i], 2.0)) / max; + REALTYPE phase = atan2(oscilFFTfreqs.s[i], oscilFFTfreqs.c[i]); - switch (Psatype) { + switch(Psatype) { case 1: - mag=pow(mag,par); + mag = pow(mag, par); break; case 2: - if (mag<par) mag=0.0; + if(mag < par) + mag = 0.0; break; case 3: - mag/=par; - if (mag>1.0) mag=1.0; + mag /= par; + if(mag > 1.0) + mag = 1.0; break; - }; - oscilFFTfreqs.c[i]=mag*cos(phase); - oscilFFTfreqs.s[i]=mag*sin(phase); - }; - -}; + } + oscilFFTfreqs.c[i] = mag * cos(phase); + oscilFFTfreqs.s[i] = mag * sin(phase); + } +} void OscilGen::shiftharmonics() { - if (Pharmonicshift==0) return; - - REALTYPE hc,hs; - int harmonicshift=-Pharmonicshift; - - if (harmonicshift>0) { - for (int i=OSCIL_SIZE/2-2;i>=0;i--) { - int oldh=i-harmonicshift; - if (oldh<0) { - hc=0.0; - hs=0.0; - } else { - hc=oscilFFTfreqs.c[oldh+1]; - hs=oscilFFTfreqs.s[oldh+1]; - }; - oscilFFTfreqs.c[i+1]=hc; - oscilFFTfreqs.s[i+1]=hs; - }; - } else { - for (int i=0;i<OSCIL_SIZE/2-1;i++) { - int oldh=i+abs(harmonicshift); - if (oldh>=(OSCIL_SIZE/2-1)) { - hc=0.0; - hs=0.0; - } else { - hc=oscilFFTfreqs.c[oldh+1]; - hs=oscilFFTfreqs.s[oldh+1]; - if (fabs(hc)<0.000001) hc=0.0; - if (fabs(hs)<0.000001) hs=0.0; - }; - - oscilFFTfreqs.c[i+1]=hc; - oscilFFTfreqs.s[i+1]=hs; - }; - }; - - oscilFFTfreqs.c[0]=0.0; -}; + if(Pharmonicshift == 0) + return; + + REALTYPE hc, hs; + int harmonicshift = -Pharmonicshift; + + if(harmonicshift > 0) { + for(int i = OSCIL_SIZE / 2 - 2; i >= 0; i--) { + int oldh = i - harmonicshift; + if(oldh < 0) { + hc = 0.0; + hs = 0.0; + } + else { + hc = oscilFFTfreqs.c[oldh + 1]; + hs = oscilFFTfreqs.s[oldh + 1]; + } + oscilFFTfreqs.c[i + 1] = hc; + oscilFFTfreqs.s[i + 1] = hs; + } + } + else { + for(int i = 0; i < OSCIL_SIZE / 2 - 1; i++) { + int oldh = i + abs(harmonicshift); + if(oldh >= (OSCIL_SIZE / 2 - 1)) { + hc = 0.0; + hs = 0.0; + } + else { + hc = oscilFFTfreqs.c[oldh + 1]; + hs = oscilFFTfreqs.s[oldh + 1]; + if(fabs(hc) < 0.000001) + hc = 0.0; + if(fabs(hs) < 0.000001) + hs = 0.0; + } + + oscilFFTfreqs.c[i + 1] = hc; + oscilFFTfreqs.s[i + 1] = hs; + } + } + + oscilFFTfreqs.c[0] = 0.0; +} /* * 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)) + 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++) + 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) { + 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)); + hmag[i] = exp(hmagnew * log(0.01)); break; case 2: - hmag[i]=exp(hmagnew*log(0.001)); + hmag[i] = exp(hmagnew * log(0.001)); break; case 3: - hmag[i]=exp(hmagnew*log(0.0001)); + hmag[i] = exp(hmagnew * log(0.0001)); break; case 4: - hmag[i]=exp(hmagnew*log(0.00001)); + hmag[i] = exp(hmagnew * log(0.00001)); break; default: - hmag[i]=1.0-hmagnew; + hmag[i] = 1.0 - hmagnew; break; - }; + } - if (Phmag[i]<64) hmag[i]=-hmag[i]; - }; + 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) { + 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 { + } + else { oscilfilter(); waveshape(); - }; + } modulation(); spectrumadjust(); - if (Pharmonicshiftfirst==0) shiftharmonics(); + if(Pharmonicshiftfirst == 0) + shiftharmonics(); - oscilFFTfreqs.c[0]=0.0; + oscilFFTfreqs.c[0] = 0.0; - oldhmagtype=Phmagtype; - oldharmonicshift=Pharmonicshift+Pharmonicshiftfirst*256; + oldhmagtype = Phmagtype; + oldharmonicshift = Pharmonicshift + Pharmonicshiftfirst * 256; - oscilprepared=1; -}; + oscilprepared = 1; +} -void OscilGen::adaptiveharmonic(FFTFREQS f,REALTYPE freq) +void OscilGen::adaptiveharmonic(FFTFREQS f, REALTYPE freq) { - if ((Padaptiveharmonics==0)/*||(freq<1.0)*/) return; - if (freq<1.0) freq=440.0; + if((Padaptiveharmonics == 0) /*||(freq<1.0)*/) + return; + if(freq < 1.0) + freq = 440.0; FFTFREQS inf; - newFFTFREQS(&inf,OSCIL_SIZE/2); - for (int i=0;i<OSCIL_SIZE/2;i++) { - inf.s[i]=f.s[i]; - inf.c[i]=f.c[i]; - f.s[i]=0.0; - f.c[i]=0.0; - }; - inf.c[0]=0.0; - inf.s[0]=0.0; - - REALTYPE hc=0.0,hs=0.0; - REALTYPE basefreq=30.0*pow(10.0,Padaptiveharmonicsbasefreq/128.0); - REALTYPE power=(Padaptiveharmonicspower+1.0)/101.0; - - REALTYPE rap=freq/basefreq; - - rap=pow(rap,power); - - bool down=false; - if (rap>1.0) { - rap=1.0/rap; - down=true; - }; - - for (int i=0;i<OSCIL_SIZE/2-2;i++) { - REALTYPE h=i*rap; - int high=(int)(i*rap); - REALTYPE low=fmod(h,1.0); - - if (high>=(OSCIL_SIZE/2-2)) { + newFFTFREQS(&inf, OSCIL_SIZE / 2); + for(int i = 0; i < OSCIL_SIZE / 2; i++) { + inf.s[i] = f.s[i]; + inf.c[i] = f.c[i]; + f.s[i] = 0.0; + f.c[i] = 0.0; + } + inf.c[0] = 0.0; + inf.s[0] = 0.0; + + REALTYPE hc = 0.0, hs = 0.0; + REALTYPE basefreq = 30.0 * pow(10.0, Padaptiveharmonicsbasefreq / 128.0); + REALTYPE power = (Padaptiveharmonicspower + 1.0) / 101.0; + + REALTYPE rap = freq / basefreq; + + rap = pow(rap, power); + + bool down = false; + if(rap > 1.0) { + rap = 1.0 / rap; + down = true; + } + + for(int i = 0; i < OSCIL_SIZE / 2 - 2; i++) { + REALTYPE h = i * rap; + int high = (int)(i * rap); + REALTYPE low = fmod(h, 1.0); + + if(high >= (OSCIL_SIZE / 2 - 2)) break; - } else { - if (down) { - f.c[high]+=inf.c[i]*(1.0-low); - f.s[high]+=inf.s[i]*(1.0-low); - f.c[high+1]+=inf.c[i]*low; - f.s[high+1]+=inf.s[i]*low; - } else { - hc=inf.c[high]*(1.0-low)+inf.c[high+1]*low; - hs=inf.s[high]*(1.0-low)+inf.s[high+1]*low; - }; - if (fabs(hc)<0.000001) hc=0.0; - if (fabs(hs)<0.000001) hs=0.0; - }; - - if (!down) { - if (i==0) {//corect the aplitude of the first harmonic - hc*=rap; - hs*=rap; - }; - f.c[i]=hc; - f.s[i]=hs; - }; - }; - - f.c[1]+=f.c[0]; - f.s[1]+=f.s[0]; - f.c[0]=0.0; - f.s[0]=0.0; + else { + if(down) { + f.c[high] += inf.c[i] * (1.0 - low); + f.s[high] += inf.s[i] * (1.0 - low); + f.c[high + 1] += inf.c[i] * low; + f.s[high + 1] += inf.s[i] * low; + } + else { + hc = inf.c[high] * (1.0 - low) + inf.c[high + 1] * low; + hs = inf.s[high] * (1.0 - low) + inf.s[high + 1] * low; + } + if(fabs(hc) < 0.000001) + hc = 0.0; + if(fabs(hs) < 0.000001) + hs = 0.0; + } + + if(!down) { + if(i == 0) { //corect the aplitude of the first harmonic + hc *= rap; + hs *= rap; + } + f.c[i] = hc; + f.s[i] = hs; + } + } + + f.c[1] += f.c[0]; + f.s[1] += f.s[0]; + f.c[0] = 0.0; + f.s[0] = 0.0; deleteFFTFREQS(&inf); -}; +} -void OscilGen::adaptiveharmonicpostprocess(REALTYPE *f,int size) +void OscilGen::adaptiveharmonicpostprocess(REALTYPE *f, int size) { - if (Padaptiveharmonics<=1) return; - REALTYPE *inf=new REALTYPE[size]; - REALTYPE par=Padaptiveharmonicspar*0.01; - par=1.0-pow((1.0-par),1.5); - - for (int i=0;i<size;i++) { - inf[i]=f[i]*par; - f[i]=f[i]*(1.0-par); - }; - - - if (Padaptiveharmonics==2) {//2n+1 - for (int i=0;i<size;i++) if ((i%2)==0) f[i]+=inf[i];//i=0 pt prima armonica,etc. - } else {//celelalte moduri - int nh=(Padaptiveharmonics-3)/2+2; - int sub_vs_add=(Padaptiveharmonics-3)%2; - if (sub_vs_add==0) { - for (int i=0;i<size;i++) { - if (((i+1)%nh)==0) { - f[i]+=inf[i]; - }; - }; - } else { - for (int i=0;i<size/nh-1;i++) { - f[(i+1)*nh-1]+=inf[i]; - }; - }; - }; - - delete(inf); -}; + if(Padaptiveharmonics <= 1) + return; + REALTYPE *inf = new REALTYPE[size]; + REALTYPE par = Padaptiveharmonicspar * 0.01; + par = 1.0 - pow((1.0 - par), 1.5); + + for(int i = 0; i < size; i++) { + inf[i] = f[i] * par; + f[i] = f[i] * (1.0 - par); + } + + + if(Padaptiveharmonics == 2) { //2n+1 + for(int i = 0; i < size; i++) + if((i % 2) == 0) + f[i] += inf[i]; //i=0 pt prima armonica,etc. + } + else { //celelalte moduri + int nh = (Padaptiveharmonics - 3) / 2 + 2; + int sub_vs_add = (Padaptiveharmonics - 3) % 2; + if(sub_vs_add == 0) { + for(int i = 0; i < size; i++) { + if(((i + 1) % nh) == 0) + f[i] += inf[i]; + ; + } + } + else { + for(int i = 0; i < size / nh - 1; i++) + f[(i + 1) * nh - 1] += inf[i]; + ; + } + } + + delete (inf); +} /* * Get the oscillator function */ -short int OscilGen::get(REALTYPE *smps,REALTYPE freqHz) +short int OscilGen::get(REALTYPE *smps, REALTYPE freqHz) { - return(this->get(smps,freqHz,0)); -}; + return this->get(smps, freqHz, 0); +} void OscilGen::newrandseed(unsigned int randseed) { - this->randseed=randseed; -}; + this->randseed = randseed; +} /* * Get the oscillator function */ -short int OscilGen::get(REALTYPE *smps,REALTYPE freqHz,int resonance) +short int OscilGen::get(REALTYPE *smps, REALTYPE freqHz, int resonance) { int i; - int nyquist,outpos; - - if ((oldbasepar!=Pbasefuncpar)||(oldbasefunc!=Pcurrentbasefunc)||(oldhmagtype!=Phmagtype) - ||(oldwaveshaping!=Pwaveshaping)||(oldwaveshapingfunction!=Pwaveshapingfunction)) oscilprepared=0; - if (oldfilterpars!=Pfiltertype*256+Pfilterpar1+Pfilterpar2*65536+Pfilterbeforews*16777216) { - oscilprepared=0; - oldfilterpars=Pfiltertype*256+Pfilterpar1+Pfilterpar2*65536+Pfilterbeforews*16777216; - }; - if (oldsapars!=Psatype*256+Psapar) { - oscilprepared=0; - oldsapars=Psatype*256+Psapar; - }; + int nyquist, outpos; + + if((oldbasepar != Pbasefuncpar) || (oldbasefunc != Pcurrentbasefunc) + || (oldhmagtype != Phmagtype) + || (oldwaveshaping != Pwaveshaping) + || (oldwaveshapingfunction != Pwaveshapingfunction)) + oscilprepared = 0; + if(oldfilterpars != Pfiltertype * 256 + Pfilterpar1 + Pfilterpar2 * 65536 + + Pfilterbeforews * 16777216) { + oscilprepared = 0; + oldfilterpars = Pfiltertype * 256 + Pfilterpar1 + Pfilterpar2 * 65536 + + Pfilterbeforews * 16777216; + } + if(oldsapars != Psatype * 256 + Psapar) { + oscilprepared = 0; + oldsapars = Psatype * 256 + Psapar; + } - if ((oldbasefuncmodulation!=Pbasefuncmodulation)|| - (oldbasefuncmodulationpar1!=Pbasefuncmodulationpar1)|| - (oldbasefuncmodulationpar2!=Pbasefuncmodulationpar2)|| - (oldbasefuncmodulationpar3!=Pbasefuncmodulationpar3)) - oscilprepared=0; + if((oldbasefuncmodulation != Pbasefuncmodulation) + || (oldbasefuncmodulationpar1 != Pbasefuncmodulationpar1) + || (oldbasefuncmodulationpar2 != Pbasefuncmodulationpar2) + || (oldbasefuncmodulationpar3 != Pbasefuncmodulationpar3)) + oscilprepared = 0; - if ((oldmodulation!=Pmodulation)|| - (oldmodulationpar1!=Pmodulationpar1)|| - (oldmodulationpar2!=Pmodulationpar2)|| - (oldmodulationpar3!=Pmodulationpar3)) - oscilprepared=0; + if((oldmodulation != Pmodulation) + || (oldmodulationpar1 != Pmodulationpar1) + || (oldmodulationpar2 != Pmodulationpar2) + || (oldmodulationpar3 != Pmodulationpar3)) + oscilprepared = 0; - if (oldharmonicshift!=Pharmonicshift+Pharmonicshiftfirst*256) oscilprepared=0; + if(oldharmonicshift != Pharmonicshift + Pharmonicshiftfirst * 256) + oscilprepared = 0; - if (oscilprepared!=1) prepare(); + if(oscilprepared != 1) + prepare(); - outpos=(int)((RND*2.0-1.0)*(REALTYPE) OSCIL_SIZE*(Prand-64.0)/64.0); - outpos=(outpos+2*OSCIL_SIZE) % OSCIL_SIZE; + outpos = + (int)((RND * 2.0 - 1.0) * (REALTYPE) OSCIL_SIZE * (Prand - 64.0) / 64.0); + outpos = (outpos + 2 * OSCIL_SIZE) % OSCIL_SIZE; - for (i=0;i<OSCIL_SIZE/2;i++) { - outoscilFFTfreqs.c[i]=0.0; - outoscilFFTfreqs.s[i]=0.0; - }; + for(i = 0; i < OSCIL_SIZE / 2; i++) { + outoscilFFTfreqs.c[i] = 0.0; + outoscilFFTfreqs.s[i] = 0.0; + } - nyquist=(int)(0.5*SAMPLE_RATE/fabs(freqHz))+2; - if (ADvsPAD) nyquist=(int)(OSCIL_SIZE/2); - if (nyquist>OSCIL_SIZE/2) nyquist=OSCIL_SIZE/2; + nyquist = (int)(0.5 * SAMPLE_RATE / fabs(freqHz)) + 2; + if(ADvsPAD) + nyquist = (int)(OSCIL_SIZE / 2); + if(nyquist > OSCIL_SIZE / 2) + nyquist = OSCIL_SIZE / 2; - int realnyquist=nyquist; + int realnyquist = nyquist; - if (Padaptiveharmonics!=0) nyquist=OSCIL_SIZE/2; - for (i=1;i<nyquist-1;i++) { - outoscilFFTfreqs.c[i]=oscilFFTfreqs.c[i]; - outoscilFFTfreqs.s[i]=oscilFFTfreqs.s[i]; - }; + if(Padaptiveharmonics != 0) + nyquist = OSCIL_SIZE / 2; + for(i = 1; i < nyquist - 1; i++) { + outoscilFFTfreqs.c[i] = oscilFFTfreqs.c[i]; + outoscilFFTfreqs.s[i] = oscilFFTfreqs.s[i]; + } - adaptiveharmonic(outoscilFFTfreqs,freqHz); - adaptiveharmonicpostprocess(&outoscilFFTfreqs.c[1],OSCIL_SIZE/2-1); - adaptiveharmonicpostprocess(&outoscilFFTfreqs.s[1],OSCIL_SIZE/2-1); + adaptiveharmonic(outoscilFFTfreqs, freqHz); + adaptiveharmonicpostprocess(&outoscilFFTfreqs.c[1], OSCIL_SIZE / 2 - 1); + adaptiveharmonicpostprocess(&outoscilFFTfreqs.s[1], OSCIL_SIZE / 2 - 1); - nyquist=realnyquist; - if (Padaptiveharmonics) {//do the antialiasing in the case of adaptive harmonics - for (i=nyquist;i<OSCIL_SIZE/2;i++) { - outoscilFFTfreqs.s[i]=0; - outoscilFFTfreqs.c[i]=0; - }; - }; + nyquist = realnyquist; + if(Padaptiveharmonics) { //do the antialiasing in the case of adaptive harmonics + for(i = nyquist; i < OSCIL_SIZE / 2; i++) { + outoscilFFTfreqs.s[i] = 0; + outoscilFFTfreqs.c[i] = 0; + } + } // Randomness (each harmonic), the block type is computed // in ADnote by setting start position according to this setting - if ((Prand>64)&&(freqHz>=0.0)&&(!ADvsPAD)) { - REALTYPE rnd,angle,a,b,c,d; - rnd=PI*pow((Prand-64.0)/64.0,2.0); - for (i=1;i<nyquist-1;i++) {//to Nyquist only for AntiAliasing - angle=rnd*i*RND; - a=outoscilFFTfreqs.c[i]; - b=outoscilFFTfreqs.s[i]; - c=cos(angle); - d=sin(angle); - outoscilFFTfreqs.c[i]=a*c-b*d; - outoscilFFTfreqs.s[i]=a*d+b*c; - }; - }; + if((Prand > 64) && (freqHz >= 0.0) && (!ADvsPAD)) { + REALTYPE rnd, angle, a, b, c, d; + rnd = PI * pow((Prand - 64.0) / 64.0, 2.0); + for(i = 1; i < nyquist - 1; i++) { //to Nyquist only for AntiAliasing + angle = rnd * i * RND; + a = outoscilFFTfreqs.c[i]; + b = outoscilFFTfreqs.s[i]; + c = cos(angle); + d = sin(angle); + outoscilFFTfreqs.c[i] = a * c - b * d; + outoscilFFTfreqs.s[i] = a * d + b * c; + } + } //Harmonic Amplitude Randomness - if ((freqHz>0.1)&&(!ADvsPAD)) { - unsigned int realrnd=rand(); + if((freqHz > 0.1) && (!ADvsPAD)) { + unsigned int realrnd = rand(); srand(randseed); - REALTYPE power=Pamprandpower/127.0; - REALTYPE normalize=1.0/(1.2-power); - switch (Pamprandtype) { + REALTYPE power = Pamprandpower / 127.0; + REALTYPE normalize = 1.0 / (1.2 - power); + switch(Pamprandtype) { case 1: - power=power*2.0-0.5; - power=pow(15.0,power); - for (i=1;i<nyquist-1;i++) { - REALTYPE amp=pow(RND,power)*normalize; - outoscilFFTfreqs.c[i]*=amp; - outoscilFFTfreqs.s[i]*=amp; - }; + power = power * 2.0 - 0.5; + power = pow(15.0, power); + for(i = 1; i < nyquist - 1; i++) { + REALTYPE amp = pow(RND, power) * normalize; + outoscilFFTfreqs.c[i] *= amp; + outoscilFFTfreqs.s[i] *= amp; + } break; case 2: - power=power*2.0-0.5; - power=pow(15.0,power)*2.0; - REALTYPE rndfreq=2*PI*RND; - for (i=1;i<nyquist-1;i++) { - REALTYPE amp=pow(fabs(sin(i*rndfreq)),power)*normalize; - outoscilFFTfreqs.c[i]*=amp; - outoscilFFTfreqs.s[i]*=amp; - }; + power = power * 2.0 - 0.5; + power = pow(15.0, power) * 2.0; + REALTYPE rndfreq = 2 * PI * RND; + for(i = 1; i < nyquist - 1; i++) { + REALTYPE amp = pow(fabs(sin(i * rndfreq)), power) * normalize; + outoscilFFTfreqs.c[i] *= amp; + outoscilFFTfreqs.s[i] *= amp; + } break; - }; - srand(realrnd+1); - }; + } + srand(realrnd + 1); + } - if ((freqHz>0.1)&&(resonance!=0)) res->applyres(nyquist-1,outoscilFFTfreqs,freqHz); + if((freqHz > 0.1) && (resonance != 0)) + res->applyres(nyquist - 1, outoscilFFTfreqs, freqHz); //Full RMS normalize - REALTYPE sum=0; - for (int j=1;j<OSCIL_SIZE/2;j++) { - REALTYPE term=outoscilFFTfreqs.c[j]*outoscilFFTfreqs.c[j] - +outoscilFFTfreqs.s[j]*outoscilFFTfreqs.s[j]; - sum+=term; - }; - if (sum<0.000001) sum=1.0; - sum=1.0/sqrt(sum); - for (int j=1;j<OSCIL_SIZE/2;j++) { - outoscilFFTfreqs.c[j]*=sum; - outoscilFFTfreqs.s[j]*=sum; - }; - - - if ((ADvsPAD)&&(freqHz>0.1)) {//in this case the smps will contain the freqs - for (i=1;i<OSCIL_SIZE/2;i++) smps[i-1]=sqrt(outoscilFFTfreqs.c[i]*outoscilFFTfreqs.c[i] - +outoscilFFTfreqs.s[i]*outoscilFFTfreqs.s[i]); - } else { - fft->freqs2smps(outoscilFFTfreqs,smps); - for (i=0;i<OSCIL_SIZE;i++) smps[i]*=0.25;//correct the amplitude - }; - - if (Prand<64) return(outpos); - else return(0); -}; + REALTYPE sum = 0; + for(int j = 1; j < OSCIL_SIZE / 2; j++) { + REALTYPE term = outoscilFFTfreqs.c[j] * outoscilFFTfreqs.c[j] + + outoscilFFTfreqs.s[j] * outoscilFFTfreqs.s[j]; + sum += term; + } + if(sum < 0.000001) + sum = 1.0; + sum = 1.0 / sqrt(sum); + for(int j = 1; j < OSCIL_SIZE / 2; j++) { + outoscilFFTfreqs.c[j] *= sum; + outoscilFFTfreqs.s[j] *= sum; + } + + + if((ADvsPAD) && (freqHz > 0.1)) //in this case the smps will contain the freqs + for(i = 1; i < OSCIL_SIZE / 2; i++) + smps[i - 1] = sqrt(outoscilFFTfreqs.c[i] * outoscilFFTfreqs.c[i] + + outoscilFFTfreqs.s[i] * outoscilFFTfreqs.s[i]); + else { + fft->freqs2smps(outoscilFFTfreqs, smps); + for(i = 0; i < OSCIL_SIZE; i++) + smps[i] *= 0.25; //correct the amplitude + } + + if(Prand < 64) + return outpos; + else + return 0; +} /* * Get the spectrum of the oscillator for the UI */ -void OscilGen::getspectrum(int n, REALTYPE *spc,int what) +void OscilGen::getspectrum(int n, REALTYPE *spc, int what) { - if (n>OSCIL_SIZE/2) n=OSCIL_SIZE/2; - - for (int i=1;i<n;i++) { - if (what==0) { - spc[i-1]=sqrt(oscilFFTfreqs.c[i]*oscilFFTfreqs.c[i] - +oscilFFTfreqs.s[i]*oscilFFTfreqs.s[i]); - } else { - if (Pcurrentbasefunc==0) spc[i-1]=((i==1)?(1.0):(0.0)); - else spc[i-1]=sqrt(basefuncFFTfreqs.c[i]*basefuncFFTfreqs.c[i]+ - basefuncFFTfreqs.s[i]*basefuncFFTfreqs.s[i]); - }; - }; - - if (what==0) { - for (int i=0;i<n;i++) outoscilFFTfreqs.s[i]=outoscilFFTfreqs.c[i]=spc[i]; - for (int i=n;i<OSCIL_SIZE/2;i++) outoscilFFTfreqs.s[i]=outoscilFFTfreqs.c[i]=0.0; - adaptiveharmonic(outoscilFFTfreqs,0.0); - for (int i=0;i<n;i++) spc[i]=outoscilFFTfreqs.s[i]; - adaptiveharmonicpostprocess(spc,n-1); - }; -}; + if(n > OSCIL_SIZE / 2) + n = OSCIL_SIZE / 2; + + for(int i = 1; i < n; i++) { + if(what == 0) + spc[i - 1] = sqrt(oscilFFTfreqs.c[i] * oscilFFTfreqs.c[i] + + oscilFFTfreqs.s[i] * oscilFFTfreqs.s[i]); + else { + if(Pcurrentbasefunc == 0) + spc[i - 1] = ((i == 1) ? (1.0) : (0.0)); + else + spc[i - 1] = sqrt(basefuncFFTfreqs.c[i] * basefuncFFTfreqs.c[i] + + basefuncFFTfreqs.s[i] + * basefuncFFTfreqs.s[i]); + } + } + + if(what == 0) { + for(int i = 0; i < n; i++) + outoscilFFTfreqs.s[i] = outoscilFFTfreqs.c[i] = spc[i]; + for(int i = n; i < OSCIL_SIZE / 2; i++) + outoscilFFTfreqs.s[i] = outoscilFFTfreqs.c[i] = 0.0; + adaptiveharmonic(outoscilFFTfreqs, 0.0); + for(int i = 0; i < n; i++) + spc[i] = outoscilFFTfreqs.s[i]; + adaptiveharmonicpostprocess(spc, n - 1); + } +} /* @@ -1112,15 +1262,15 @@ void OscilGen::useasbase() { int i; - for (i=0;i<OSCIL_SIZE/2;i++) { - basefuncFFTfreqs.c[i]=oscilFFTfreqs.c[i]; - basefuncFFTfreqs.s[i]=oscilFFTfreqs.s[i]; - }; + for(i = 0; i < OSCIL_SIZE / 2; i++) { + basefuncFFTfreqs.c[i] = oscilFFTfreqs.c[i]; + basefuncFFTfreqs.s[i] = oscilFFTfreqs.s[i]; + } - oldbasefunc=Pcurrentbasefunc=127; + oldbasefunc = Pcurrentbasefunc = 127; prepare(); -}; +} /* @@ -1128,166 +1278,198 @@ void OscilGen::useasbase() */ void OscilGen::getcurrentbasefunction(REALTYPE *smps) { - if (Pcurrentbasefunc!=0) { - fft->freqs2smps(basefuncFFTfreqs,smps); - } else getbasefunction(smps);//the sine case -}; + if(Pcurrentbasefunc != 0) + fft->freqs2smps(basefuncFFTfreqs, smps); + else + getbasefunction(smps); //the sine case +} void OscilGen::add2XML(XMLwrapper *xml) { - xml->addpar("harmonic_mag_type",Phmagtype); + xml->addpar("harmonic_mag_type", Phmagtype); - xml->addpar("base_function",Pcurrentbasefunc); - xml->addpar("base_function_par",Pbasefuncpar); - xml->addpar("base_function_modulation",Pbasefuncmodulation); - xml->addpar("base_function_modulation_par1",Pbasefuncmodulationpar1); - xml->addpar("base_function_modulation_par2",Pbasefuncmodulationpar2); - xml->addpar("base_function_modulation_par3",Pbasefuncmodulationpar3); + xml->addpar("base_function", Pcurrentbasefunc); + xml->addpar("base_function_par", Pbasefuncpar); + xml->addpar("base_function_modulation", Pbasefuncmodulation); + xml->addpar("base_function_modulation_par1", Pbasefuncmodulationpar1); + 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("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); + xml->addpar("wave_shaping", Pwaveshaping); + xml->addpar("wave_shaping_function", Pwaveshapingfunction); - xml->addpar("filter_type",Pfiltertype); - xml->addpar("filter_par1",Pfilterpar1); - xml->addpar("filter_par2",Pfilterpar2); - xml->addpar("filter_before_wave_shaping",Pfilterbeforews); + xml->addpar("filter_type", Pfiltertype); + xml->addpar("filter_par1", Pfilterpar1); + xml->addpar("filter_par2", Pfilterpar2); + xml->addpar("filter_before_wave_shaping", Pfilterbeforews); - xml->addpar("spectrum_adjust_type",Psatype); - xml->addpar("spectrum_adjust_par",Psapar); + xml->addpar("spectrum_adjust_type", Psatype); + xml->addpar("spectrum_adjust_par", Psapar); - xml->addpar("rand",Prand); - xml->addpar("amp_rand_type",Pamprandtype); - xml->addpar("amp_rand_power",Pamprandpower); + xml->addpar("rand", Prand); + xml->addpar("amp_rand_type", Pamprandtype); + xml->addpar("amp_rand_power", Pamprandpower); - xml->addpar("harmonic_shift",Pharmonicshift); - xml->addparbool("harmonic_shift_first",Pharmonicshiftfirst); + xml->addpar("harmonic_shift", Pharmonicshift); + xml->addparbool("harmonic_shift_first", Pharmonicshiftfirst); - xml->addpar("adaptive_harmonics",Padaptiveharmonics); - xml->addpar("adaptive_harmonics_base_frequency",Padaptiveharmonicsbasefreq); - xml->addpar("adaptive_harmonics_power",Padaptiveharmonicspower); + xml->addpar("adaptive_harmonics", Padaptiveharmonics); + xml->addpar("adaptive_harmonics_base_frequency", Padaptiveharmonicsbasefreq); + xml->addpar("adaptive_harmonics_power", Padaptiveharmonicspower); xml->beginbranch("HARMONICS"); - for (int n=0;n<MAX_AD_HARMONICS;n++) { - if ((Phmag[n]==64)&&(Phphase[n]==64)) continue; - xml->beginbranch("HARMONIC",n+1); - xml->addpar("mag",Phmag[n]); - xml->addpar("phase",Phphase[n]); + for(int n = 0; n < MAX_AD_HARMONICS; n++) { + if((Phmag[n] == 64) && (Phphase[n] == 64)) + continue; + xml->beginbranch("HARMONIC", n + 1); + xml->addpar("mag", Phmag[n]); + xml->addpar("phase", Phphase[n]); xml->endbranch(); - }; + } xml->endbranch(); - if (Pcurrentbasefunc==127) { - REALTYPE max=0.0; + if(Pcurrentbasefunc == 127) { + REALTYPE max = 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(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; xml->beginbranch("BASE_FUNCTION"); - for (int i=1;i<OSCIL_SIZE/2;i++) { - REALTYPE xc=basefuncFFTfreqs.c[i]/max; - REALTYPE xs=basefuncFFTfreqs.s[i]/max; - if ((fabs(xs)>0.00001)&&(fabs(xs)>0.00001)) { - xml->beginbranch("BF_HARMONIC",i); - xml->addparreal("cos",xc); - xml->addparreal("sin",xs); + for(int i = 1; i < OSCIL_SIZE / 2; i++) { + REALTYPE xc = basefuncFFTfreqs.c[i] / max; + REALTYPE xs = basefuncFFTfreqs.s[i] / max; + if((fabs(xs) > 0.00001) && (fabs(xs) > 0.00001)) { + xml->beginbranch("BF_HARMONIC", i); + xml->addparreal("cos", xc); + xml->addparreal("sin", xs); xml->endbranch(); - }; - }; + } + } xml->endbranch(); - }; -}; + } +} 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); + 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(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); + 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; - }; - }; -}; + 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; + } + } +} diff --git a/src/Synth/OscilGen.h b/src/Synth/OscilGen.h @@ -31,148 +31,153 @@ class OscilGen:public Presets { -public: - OscilGen(FFTwrapper *fft_,Resonance *res_); - ~OscilGen(); + public: + OscilGen(FFTwrapper *fft_, Resonance *res_); + ~OscilGen(); - /**computes the full spectrum of oscil from harmonics,phases and basefunc*/ - void prepare(); + /**computes the full spectrum of oscil from harmonics,phases and basefunc*/ + void prepare(); - /**do the antialiasing(cut off higher freqs.),apply randomness and do a IFFT*/ - short get(REALTYPE *smps,REALTYPE freqHz);//returns where should I start getting samples, used in block type randomness - short get(REALTYPE *smps,REALTYPE freqHz,int resonance); - //if freqHz is smaller than 0, return the "un-randomized" sample for UI + /**do the antialiasing(cut off higher freqs.),apply randomness and do a IFFT*/ + short get(REALTYPE *smps, REALTYPE freqHz); //returns where should I start getting samples, used in block type randomness + short get(REALTYPE *smps, REALTYPE freqHz, int resonance); + //if freqHz is smaller than 0, return the "un-randomized" sample for UI - void getbasefunction(REALTYPE *smps); + void getbasefunction(REALTYPE *smps); - //called by UI - void getspectrum(int n,REALTYPE *spc,int what);//what=0 pt. oscil,1 pt. basefunc - void getcurrentbasefunction(REALTYPE *smps); - /**convert oscil to base function*/ - void useasbase(); + //called by UI + void getspectrum(int n, REALTYPE *spc, int what); //what=0 pt. oscil,1 pt. basefunc + void getcurrentbasefunction(REALTYPE *smps); + /**convert oscil to base function*/ + void useasbase(); - void add2XML(XMLwrapper *xml); - void defaults(); - void getfromXML(XMLwrapper *xml); + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); - void convert2sine(int magtype); + void convert2sine(int magtype); - //Parameters + //Parameters - /** - * The hmag and hphase starts counting from 0, so the first harmonic(1) has the index 0, - * 2-nd harmonic has index 1, ..the 128 harminic has index 127 - */ - unsigned char Phmag[MAX_AD_HARMONICS],Phphase[MAX_AD_HARMONICS];//the MIDI parameters for mag. and phases + /** + * The hmag and hphase starts counting from 0, so the first harmonic(1) has the index 0, + * 2-nd harmonic has index 1, ..the 128 harminic has index 127 + */ + unsigned char Phmag[MAX_AD_HARMONICS], Phphase[MAX_AD_HARMONICS]; //the MIDI parameters for mag. and phases - /**The Type of magnitude: - * 0 - Linear - * 1 - dB scale (-40) - * 2 - dB scale (-60) - * 3 - dB scale (-80) - * 4 - dB scale (-100)*/ - unsigned char Phmagtype; + /**The Type of magnitude: + * 0 - Linear + * 1 - dB scale (-40) + * 2 - dB scale (-60) + * 3 - dB scale (-80) + * 4 - dB scale (-100)*/ + unsigned char Phmagtype; - unsigned char Pcurrentbasefunc;//The base function used - 0=sin, 1=... - unsigned char Pbasefuncpar;//the parameter of the base function + unsigned char Pcurrentbasefunc; //The base function used - 0=sin, 1=... + 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 function modulation + unsigned char Pbasefuncmodulation; //what modulation is applied to the basefunc + unsigned char Pbasefuncmodulationpar1, Pbasefuncmodulationpar2, + Pbasefuncmodulationpar3; //the parameter of the base function modulation - /*the Randomness: - 64=no randomness - 63..0 - block type randomness - 0 is maximum - 65..127 - each harmonic randomness - 127 is maximum*/ - unsigned char Prand; - unsigned char Pwaveshaping,Pwaveshapingfunction; - unsigned char Pfiltertype,Pfilterpar1,Pfilterpar2; - unsigned char Pfilterbeforews; - unsigned char Psatype,Psapar;//spectrum adjust + /*the Randomness: + 64=no randomness + 63..0 - block type randomness - 0 is maximum + 65..127 - each harmonic randomness - 127 is maximum*/ + unsigned char Prand; + unsigned char Pwaveshaping, Pwaveshapingfunction; + unsigned char Pfiltertype, Pfilterpar1, Pfilterpar2; + unsigned char Pfilterbeforews; + unsigned char Psatype, Psapar; //spectrum adjust - unsigned char Pamprandpower, Pamprandtype;//amplitude randomness - int Pharmonicshift;//how the harmonics are shifted - int Pharmonicshiftfirst;//if the harmonic shift is done before waveshaping and filter + unsigned char Pamprandpower, Pamprandtype; //amplitude randomness + int Pharmonicshift; //how the harmonics are shifted + int Pharmonicshiftfirst; //if the harmonic shift is done before waveshaping and filter - unsigned char Padaptiveharmonics;//the adaptive harmonics status (off=0,on=1,etc..) - 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 Padaptiveharmonicspar;//the parameters in 2,3,4.. modes of adaptive harmonics + unsigned char Padaptiveharmonics; //the adaptive harmonics status (off=0,on=1,etc..) + 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 Padaptiveharmonicspar; //the parameters in 2,3,4.. modes of adaptive harmonics - unsigned char Pmodulation;//what modulation is applied to the oscil - unsigned char Pmodulationpar1,Pmodulationpar2,Pmodulationpar3;//the parameter of the parameters + unsigned char Pmodulation; //what modulation is applied to the oscil + unsigned char Pmodulationpar1, Pmodulationpar2, Pmodulationpar3; //the parameter of the parameters - //makes a new random seed for Amplitude Randomness - //this should be called every note on event - void newrandseed(unsigned int randseed); + //makes a new random seed for Amplitude Randomness + //this should be called every note on event + void newrandseed(unsigned int randseed); - bool ADvsPAD;//if it is used by ADsynth or by PADsynth + bool ADvsPAD; //if it is used by ADsynth or by PADsynth -private: - //This array stores some termporary data and it has OSCIL_SIZE elements - REALTYPE *tmpsmps; - FFTFREQS outoscilFFTfreqs; + private: + //This array stores some termporary data and it has OSCIL_SIZE elements + REALTYPE *tmpsmps; + FFTFREQS outoscilFFTfreqs; - REALTYPE hmag[MAX_AD_HARMONICS],hphase[MAX_AD_HARMONICS];//the magnituides and the phases of the sine/nonsine harmonics + REALTYPE hmag[MAX_AD_HARMONICS], hphase[MAX_AD_HARMONICS]; //the magnituides and the phases of the sine/nonsine harmonics // private: - FFTwrapper *fft; - //computes the basefunction and make the FFT; newbasefunc<0 = same basefunc - void changebasefunction(); - //Waveshaping - void waveshape(); - - //Filter the oscillator accotding to Pfiltertype and Pfilterpar - void oscilfilter(); - - //Adjust the spectrum - void spectrumadjust(); - - //Shift the harmonics - void shiftharmonics(); - - //Do the oscil modulation stuff - void modulation(); - - //Do the adaptive harmonic stuff - void adaptiveharmonic(FFTFREQS f,REALTYPE freq); - - //Do the adaptive harmonic postprocessing (2n+1,2xS,2xA,etc..) - //this function is called even for the user interface - //this can be called for the sine and components, and for the spectrum - //(that's why the sine and cosine components should be processed with a separate call) - void adaptiveharmonicpostprocess(REALTYPE *f, int size); - - //Basic/base functions (Functiile De Baza) - REALTYPE basefunc_pulse(REALTYPE x,REALTYPE a); - REALTYPE basefunc_saw(REALTYPE x,REALTYPE a); - REALTYPE basefunc_triangle(REALTYPE x,REALTYPE a); - REALTYPE basefunc_power(REALTYPE x,REALTYPE a); - REALTYPE basefunc_gauss(REALTYPE x,REALTYPE a); - REALTYPE basefunc_diode(REALTYPE x,REALTYPE a); - REALTYPE basefunc_abssine(REALTYPE x,REALTYPE a); - REALTYPE basefunc_pulsesine(REALTYPE x,REALTYPE a); - REALTYPE basefunc_stretchsine(REALTYPE x,REALTYPE a); - REALTYPE basefunc_chirp(REALTYPE x,REALTYPE a); - REALTYPE basefunc_absstretchsine(REALTYPE x,REALTYPE a); - REALTYPE basefunc_chebyshev(REALTYPE x,REALTYPE a); - REALTYPE basefunc_sqr(REALTYPE x,REALTYPE a); - - //Internal Data - unsigned char oldbasefunc,oldbasepar,oldhmagtype,oldwaveshapingfunction,oldwaveshaping; - int oldfilterpars,oldsapars,oldbasefuncmodulation,oldbasefuncmodulationpar1,oldbasefuncmodulationpar2,oldbasefuncmodulationpar3,oldharmonicshift; - int oldmodulation,oldmodulationpar1,oldmodulationpar2,oldmodulationpar3; - - - FFTFREQS basefuncFFTfreqs;//Base Function Frequencies - FFTFREQS oscilFFTfreqs;//Oscillator Frequencies - this is different than the hamonics set-up by the user, it may contains time-domain data if the antialiasing is turned off - int oscilprepared;//1 if the oscil is prepared, 0 if it is not prepared and is need to call ::prepare() before ::get() - - Resonance *res; - - unsigned int randseed; - + FFTwrapper *fft; + //computes the basefunction and make the FFT; newbasefunc<0 = same basefunc + void changebasefunction(); + //Waveshaping + void waveshape(); + + //Filter the oscillator accotding to Pfiltertype and Pfilterpar + void oscilfilter(); + + //Adjust the spectrum + void spectrumadjust(); + + //Shift the harmonics + void shiftharmonics(); + + //Do the oscil modulation stuff + void modulation(); + + //Do the adaptive harmonic stuff + void adaptiveharmonic(FFTFREQS f, REALTYPE freq); + + //Do the adaptive harmonic postprocessing (2n+1,2xS,2xA,etc..) + //this function is called even for the user interface + //this can be called for the sine and components, and for the spectrum + //(that's why the sine and cosine components should be processed with a separate call) + void adaptiveharmonicpostprocess(REALTYPE *f, int size); + + //Basic/base functions (Functiile De Baza) + REALTYPE basefunc_pulse(REALTYPE x, REALTYPE a); + REALTYPE basefunc_saw(REALTYPE x, REALTYPE a); + REALTYPE basefunc_triangle(REALTYPE x, REALTYPE a); + REALTYPE basefunc_power(REALTYPE x, REALTYPE a); + REALTYPE basefunc_gauss(REALTYPE x, REALTYPE a); + REALTYPE basefunc_diode(REALTYPE x, REALTYPE a); + REALTYPE basefunc_abssine(REALTYPE x, REALTYPE a); + REALTYPE basefunc_pulsesine(REALTYPE x, REALTYPE a); + REALTYPE basefunc_stretchsine(REALTYPE x, REALTYPE a); + REALTYPE basefunc_chirp(REALTYPE x, REALTYPE a); + REALTYPE basefunc_absstretchsine(REALTYPE x, REALTYPE a); + REALTYPE basefunc_chebyshev(REALTYPE x, REALTYPE a); + REALTYPE basefunc_sqr(REALTYPE x, REALTYPE a); + + //Internal Data + unsigned char oldbasefunc, oldbasepar, oldhmagtype, + oldwaveshapingfunction, oldwaveshaping; + int oldfilterpars, oldsapars, oldbasefuncmodulation, + oldbasefuncmodulationpar1, oldbasefuncmodulationpar2, + oldbasefuncmodulationpar3, oldharmonicshift; + int oldmodulation, oldmodulationpar1, oldmodulationpar2, + oldmodulationpar3; + + + FFTFREQS basefuncFFTfreqs; //Base Function Frequencies + FFTFREQS oscilFFTfreqs; //Oscillator Frequencies - this is different than the hamonics set-up by the user, it may contains time-domain data if the antialiasing is turned off + int oscilprepared; //1 if the oscil is prepared, 0 if it is not prepared and is need to call ::prepare() before ::get() + + Resonance *res; + + unsigned int randseed; }; #endif + diff --git a/src/Synth/PADnote.cpp b/src/Synth/PADnote.cpp @@ -22,217 +22,269 @@ #include "PADnote.h" #include "../Misc/Config.h" -PADnote::PADnote(PADnoteParameters *parameters, Controller *ctl_,REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool besilent) +PADnote::PADnote(PADnoteParameters *parameters, + Controller *ctl_, + REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote, + bool besilent) { - ready=0; + ready = 0; // Initialise some legato-specific vars - Legato.msg=LM_Norm; - Legato.fade.length=(int)(SAMPLE_RATE*0.005);// 0.005 seems ok. - if (Legato.fade.length<1) Legato.fade.length=1;// (if something's fishy) - Legato.fade.step=(1.0/Legato.fade.length); - Legato.decounter=-10; - Legato.param.freq=freq; - Legato.param.vel=velocity; - Legato.param.portamento=portamento_; - Legato.param.midinote=midinote; - Legato.silent=besilent; - - pars=parameters; - portamento=portamento_; - ctl=ctl_; - this->velocity=velocity; - finished_=false; - - - if (pars->Pfixedfreq==0) basefreq=freq; + Legato.msg = LM_Norm; + Legato.fade.length = (int)(SAMPLE_RATE * 0.005); // 0.005 seems ok. + if(Legato.fade.length < 1) + Legato.fade.length = 1; // (if something's fishy) + Legato.fade.step = (1.0 / Legato.fade.length); + Legato.decounter = -10; + Legato.param.freq = freq; + Legato.param.vel = velocity; + Legato.param.portamento = portamento_; + Legato.param.midinote = midinote; + Legato.silent = besilent; + + pars = parameters; + portamento = portamento_; + ctl = ctl_; + this->velocity = velocity; + finished_ = false; + + + if(pars->Pfixedfreq == 0) + basefreq = freq; else { - basefreq=440.0; - int fixedfreqET=pars->PfixedfreqET; - if (fixedfreqET!=0) {//if the frequency varies according the keyboard note - REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0); - if (fixedfreqET<=64) basefreq*=pow(2.0,tmp); - else basefreq*=pow(3.0,tmp); - }; - - }; + basefreq = 440.0; + int fixedfreqET = pars->PfixedfreqET; + if(fixedfreqET != 0) { //if the frequency varies according the keyboard note + REALTYPE tmp = + (midinote + - 69.0) / 12.0 * (pow(2.0, (fixedfreqET - 1) / 63.0) - 1.0); + if(fixedfreqET <= 64) + basefreq *= pow(2.0, tmp); + else + basefreq *= pow(3.0, tmp); + } + } - firsttime=true; - released=false; - realfreq=basefreq; - NoteGlobalPar.Detune=getdetune(pars->PDetuneType - ,pars->PCoarseDetune,pars->PDetune); + firsttime = true; + released = false; + realfreq = basefreq; + NoteGlobalPar.Detune = getdetune(pars->PDetuneType, + pars->PCoarseDetune, pars->PDetune); //find out the closest note - REALTYPE logfreq=log(basefreq*pow(2.0,NoteGlobalPar.Detune/1200.0)); - REALTYPE mindist=fabs(logfreq-log(pars->sample[0].basefreq+0.0001)); - nsample=0; - for (int i=1;i<PAD_MAX_SAMPLES;i++) { - if (pars->sample[i].smp==NULL) break; - REALTYPE dist=fabs(logfreq-log(pars->sample[i].basefreq+0.0001)); + REALTYPE logfreq = log(basefreq * pow(2.0, NoteGlobalPar.Detune / 1200.0)); + REALTYPE mindist = fabs(logfreq - log(pars->sample[0].basefreq + 0.0001)); + nsample = 0; + for(int i = 1; i < PAD_MAX_SAMPLES; i++) { + if(pars->sample[i].smp == NULL) + break; + REALTYPE dist = fabs(logfreq - log(pars->sample[i].basefreq + 0.0001)); // printf("(mindist=%g) %i %g %g\n",mindist,i,dist,pars->sample[i].basefreq); - if (dist<mindist) { - nsample=i; - mindist=dist; - }; - }; + if(dist < mindist) { + nsample = i; + mindist = dist; + } + } - int size=pars->sample[nsample].size; - if (size==0) size=1; + int size = pars->sample[nsample].size; + if(size == 0) + size = 1; - poshi_l=(int)(RND*(size-1)); - if (pars->PStereo!=0) poshi_r=(poshi_l+size/2)%size; - else poshi_r=poshi_l; - poslo=0.0; + poshi_l = (int)(RND * (size - 1)); + if(pars->PStereo != 0) + poshi_r = (poshi_l + size / 2) % size; + else + poshi_r = poshi_l; + poslo = 0.0; - tmpwave=new REALTYPE [SOUND_BUFFER_SIZE]; + tmpwave = new REALTYPE [SOUND_BUFFER_SIZE]; - if (pars->PPanning==0) NoteGlobalPar.Panning=RND; - else NoteGlobalPar.Panning=pars->PPanning/128.0; + if(pars->PPanning == 0) + NoteGlobalPar.Panning = RND; + else + NoteGlobalPar.Panning = pars->PPanning / 128.0; - NoteGlobalPar.FilterCenterPitch=pars->GlobalFilter->getfreq()+//center freq - pars->PFilterVelocityScale/127.0*6.0* //velocity sensing - (VelF(velocity,pars->PFilterVelocityScaleFunction)-1); + NoteGlobalPar.FilterCenterPitch = pars->GlobalFilter->getfreq() //center freq + + pars->PFilterVelocityScale / 127.0 + * 6.0 //velocity sensing + * (VelF(velocity, + pars-> + PFilterVelocityScaleFunction) - 1); - if (pars->PPunchStrength!=0) { - NoteGlobalPar.Punch.Enabled=1; - NoteGlobalPar.Punch.t=1.0;//start from 1.0 and to 0.0 - NoteGlobalPar.Punch.initialvalue=( (pow(10,1.5*pars->PPunchStrength/127.0)-1.0) - *VelF(velocity,pars->PPunchVelocitySensing) ); - REALTYPE time=pow(10,3.0*pars->PPunchTime/127.0)/10000.0;//0.1 .. 100 ms - REALTYPE stretch=pow(440.0/freq,pars->PPunchStretch/64.0); - NoteGlobalPar.Punch.dt=1.0/(time*SAMPLE_RATE*stretch); - } else NoteGlobalPar.Punch.Enabled=0; + if(pars->PPunchStrength != 0) { + NoteGlobalPar.Punch.Enabled = 1; + NoteGlobalPar.Punch.t = 1.0; //start from 1.0 and to 0.0 + NoteGlobalPar.Punch.initialvalue = + ((pow(10, 1.5 * pars->PPunchStrength / 127.0) - 1.0) + * VelF(velocity, + pars->PPunchVelocitySensing)); + REALTYPE time = pow(10, 3.0 * pars->PPunchTime / 127.0) / 10000.0; //0.1 .. 100 ms + REALTYPE stretch = pow(440.0 / freq, pars->PPunchStretch / 64.0); + NoteGlobalPar.Punch.dt = 1.0 / (time * SAMPLE_RATE * stretch); + } + else + NoteGlobalPar.Punch.Enabled = 0; - NoteGlobalPar.FreqEnvelope=new Envelope(pars->FreqEnvelope,basefreq); - NoteGlobalPar.FreqLfo=new LFO(pars->FreqLfo,basefreq); + NoteGlobalPar.FreqEnvelope = new Envelope(pars->FreqEnvelope, basefreq); + NoteGlobalPar.FreqLfo = new LFO(pars->FreqLfo, basefreq); - NoteGlobalPar.AmpEnvelope=new Envelope(pars->AmpEnvelope,basefreq); - NoteGlobalPar.AmpLfo=new LFO(pars->AmpLfo,basefreq); + NoteGlobalPar.AmpEnvelope = new Envelope(pars->AmpEnvelope, basefreq); + NoteGlobalPar.AmpLfo = new LFO(pars->AmpLfo, basefreq); - NoteGlobalPar.Volume=4.0*pow(0.1,3.0*(1.0-pars->PVolume/96.0))//-60 dB .. 0 dB - *VelF(velocity,pars->PAmpVelocityScaleFunction);//velocity sensing + NoteGlobalPar.Volume = 4.0 * pow(0.1, 3.0 * (1.0 - pars->PVolume / 96.0)) //-60 dB .. 0 dB + * VelF(velocity, pars->PAmpVelocityScaleFunction); //velocity sensing - NoteGlobalPar.AmpEnvelope->envout_dB();//discard the first envelope output - globaloldamplitude=globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); + NoteGlobalPar.AmpEnvelope->envout_dB(); //discard the first envelope output + globaloldamplitude = globalnewamplitude = NoteGlobalPar.Volume + * NoteGlobalPar.AmpEnvelope-> + envout_dB() + * NoteGlobalPar.AmpLfo->amplfoout(); - NoteGlobalPar.GlobalFilterL=new Filter(pars->GlobalFilter); - NoteGlobalPar.GlobalFilterR=new Filter(pars->GlobalFilter); + NoteGlobalPar.GlobalFilterL = new Filter(pars->GlobalFilter); + NoteGlobalPar.GlobalFilterR = new Filter(pars->GlobalFilter); - NoteGlobalPar.FilterEnvelope=new Envelope(pars->FilterEnvelope,basefreq); - NoteGlobalPar.FilterLfo=new LFO(pars->FilterLfo,basefreq); - NoteGlobalPar.FilterQ=pars->GlobalFilter->getq(); - NoteGlobalPar.FilterFreqTracking=pars->GlobalFilter->getfreqtracking(basefreq); + NoteGlobalPar.FilterEnvelope = new Envelope(pars->FilterEnvelope, + basefreq); + NoteGlobalPar.FilterLfo = new LFO(pars->FilterLfo, basefreq); + NoteGlobalPar.FilterQ = pars->GlobalFilter->getq(); + NoteGlobalPar.FilterFreqTracking = pars->GlobalFilter->getfreqtracking( + basefreq); - ready=1;///sa il pun pe asta doar cand e chiar gata + ready = 1; ///sa il pun pe asta doar cand e chiar gata - if (parameters->sample[nsample].smp==NULL) { - finished_=true; + if(parameters->sample[nsample].smp == NULL) { + finished_ = true; return; - }; -}; + } +} // PADlegatonote: This function is (mostly) a copy of PADnote(...) // with some lines removed so that it only alter the already playing // note (to perform legato). It is possible I left stuff that is not // required for this. -void PADnote::PADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool externcall) +void PADnote::PADlegatonote(REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote, + bool externcall) { - PADnoteParameters *parameters=pars; + PADnoteParameters *parameters = pars; //Controller *ctl_=ctl; // Manage legato stuff - if (externcall) Legato.msg=LM_Norm; - if (Legato.msg!=LM_CatchUp) { - Legato.lastfreq=Legato.param.freq; - Legato.param.freq=freq; - Legato.param.vel=velocity; - Legato.param.portamento=portamento_; - Legato.param.midinote=midinote; - if (Legato.msg==LM_Norm) { - if (Legato.silent) { - Legato.fade.m=0.0; - Legato.msg=LM_FadeIn; - } else { - Legato.fade.m=1.0; - Legato.msg=LM_FadeOut; + if(externcall) + Legato.msg = LM_Norm; + if(Legato.msg != LM_CatchUp) { + Legato.lastfreq = Legato.param.freq; + Legato.param.freq = freq; + Legato.param.vel = velocity; + Legato.param.portamento = portamento_; + Legato.param.midinote = midinote; + if(Legato.msg == LM_Norm) { + if(Legato.silent) { + Legato.fade.m = 0.0; + Legato.msg = LM_FadeIn; + } + else { + Legato.fade.m = 1.0; + Legato.msg = LM_FadeOut; return; } } - if (Legato.msg==LM_ToNorm) Legato.msg=LM_Norm; + if(Legato.msg == LM_ToNorm) + Legato.msg = LM_Norm; } - portamento=portamento_; - this->velocity=velocity; - finished_=false; + portamento = portamento_; + this->velocity = velocity; + finished_ = false; - if (pars->Pfixedfreq==0) basefreq=freq; + if(pars->Pfixedfreq == 0) + basefreq = freq; else { - basefreq=440.0; - int fixedfreqET=pars->PfixedfreqET; - if (fixedfreqET!=0) {//if the frequency varies according the keyboard note - REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0); - if (fixedfreqET<=64) basefreq*=pow(2.0,tmp); - else basefreq*=pow(3.0,tmp); - }; - }; + basefreq = 440.0; + int fixedfreqET = pars->PfixedfreqET; + if(fixedfreqET != 0) { //if the frequency varies according the keyboard note + REALTYPE tmp = + (midinote + - 69.0) / 12.0 * (pow(2.0, (fixedfreqET - 1) / 63.0) - 1.0); + if(fixedfreqET <= 64) + basefreq *= pow(2.0, tmp); + else + basefreq *= pow(3.0, tmp); + } + } - released=false; - realfreq=basefreq; + released = false; + realfreq = basefreq; - getdetune(pars->PDetuneType,pars->PCoarseDetune,pars->PDetune); + getdetune(pars->PDetuneType, pars->PCoarseDetune, pars->PDetune); //find out the closest note - REALTYPE logfreq=log(basefreq*pow(2.0,NoteGlobalPar.Detune/1200.0)); - REALTYPE mindist=fabs(logfreq-log(pars->sample[0].basefreq+0.0001)); - nsample=0; - for (int i=1;i<PAD_MAX_SAMPLES;i++) { - if (pars->sample[i].smp==NULL) break; - REALTYPE dist=fabs(logfreq-log(pars->sample[i].basefreq+0.0001)); - - if (dist<mindist) { - nsample=i; - mindist=dist; - }; - }; + REALTYPE logfreq = log(basefreq * pow(2.0, NoteGlobalPar.Detune / 1200.0)); + REALTYPE mindist = fabs(logfreq - log(pars->sample[0].basefreq + 0.0001)); + nsample = 0; + for(int i = 1; i < PAD_MAX_SAMPLES; i++) { + if(pars->sample[i].smp == NULL) + break; + REALTYPE dist = fabs(logfreq - log(pars->sample[i].basefreq + 0.0001)); + + if(dist < mindist) { + nsample = i; + mindist = dist; + } + } - int size=pars->sample[nsample].size; - if (size==0) size=1; + int size = pars->sample[nsample].size; + if(size == 0) + size = 1; - if (pars->PPanning==0) NoteGlobalPar.Panning=RND; - else NoteGlobalPar.Panning=pars->PPanning/128.0; + if(pars->PPanning == 0) + NoteGlobalPar.Panning = RND; + else + NoteGlobalPar.Panning = pars->PPanning / 128.0; - NoteGlobalPar.FilterCenterPitch=pars->GlobalFilter->getfreq()+//center freq - pars->PFilterVelocityScale/127.0*6.0* //velocity sensing - (VelF(velocity,pars->PFilterVelocityScaleFunction)-1); + NoteGlobalPar.FilterCenterPitch = pars->GlobalFilter->getfreq() //center freq + + pars->PFilterVelocityScale / 127.0 + * 6.0 //velocity sensing + * (VelF(velocity, + pars-> + PFilterVelocityScaleFunction) - 1); - NoteGlobalPar.Volume=4.0*pow(0.1,3.0*(1.0-pars->PVolume/96.0))//-60 dB .. 0 dB - *VelF(velocity,pars->PAmpVelocityScaleFunction);//velocity sensing + NoteGlobalPar.Volume = 4.0 * pow(0.1, 3.0 * (1.0 - pars->PVolume / 96.0)) //-60 dB .. 0 dB + * VelF(velocity, pars->PAmpVelocityScaleFunction); //velocity sensing - NoteGlobalPar.AmpEnvelope->envout_dB();//discard the first envelope output - globaloldamplitude=globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); + NoteGlobalPar.AmpEnvelope->envout_dB(); //discard the first envelope output + globaloldamplitude = globalnewamplitude = NoteGlobalPar.Volume + * NoteGlobalPar.AmpEnvelope-> + envout_dB() + * NoteGlobalPar.AmpLfo->amplfoout(); - NoteGlobalPar.FilterQ=pars->GlobalFilter->getq(); - NoteGlobalPar.FilterFreqTracking=pars->GlobalFilter->getfreqtracking(basefreq); + NoteGlobalPar.FilterQ = pars->GlobalFilter->getq(); + NoteGlobalPar.FilterFreqTracking = pars->GlobalFilter->getfreqtracking( + basefreq); - if (parameters->sample[nsample].smp==NULL) { - finished_=true; + if(parameters->sample[nsample].smp == NULL) { + finished_ = true; return; - }; + } // End of the PADlegatonote function. -}; +} PADnote::~PADnote() @@ -246,282 +298,317 @@ PADnote::~PADnote() delete (NoteGlobalPar.FilterEnvelope); delete (NoteGlobalPar.FilterLfo); delete [] tmpwave; -}; +} inline void PADnote::fadein(REALTYPE *smps) { - int zerocrossings=0; - for (int i=1;i<SOUND_BUFFER_SIZE;i++) - if ((smps[i-1]<0.0) && (smps[i]>0.0)) zerocrossings++;//this is only the possitive crossings + int zerocrossings = 0; + for(int i = 1; i < SOUND_BUFFER_SIZE; i++) + if((smps[i - 1] < 0.0) && (smps[i] > 0.0)) + zerocrossings++; //this is only the possitive crossings - REALTYPE tmp=(SOUND_BUFFER_SIZE-1.0)/(zerocrossings+1)/3.0; - if (tmp<8.0) tmp=8.0; + REALTYPE tmp = (SOUND_BUFFER_SIZE - 1.0) / (zerocrossings + 1) / 3.0; + if(tmp < 8.0) + tmp = 8.0; int n; - F2I(tmp,n);//how many samples is the fade-in - if (n>SOUND_BUFFER_SIZE) n=SOUND_BUFFER_SIZE; - for (int i=0;i<n;i++) {//fade-in - REALTYPE tmp=0.5-cos((REALTYPE)i/(REALTYPE) n*PI)*0.5; - smps[i]*=tmp; - }; -}; + F2I(tmp, n); //how many samples is the fade-in + if(n > SOUND_BUFFER_SIZE) + n = SOUND_BUFFER_SIZE; + for(int i = 0; i < n; i++) { //fade-in + REALTYPE tmp = 0.5 - cos((REALTYPE)i / (REALTYPE) n * PI) * 0.5; + smps[i] *= tmp; + } +} void PADnote::computecurrentparameters() { - REALTYPE globalpitch,globalfilterpitch; - globalpitch=0.01*(NoteGlobalPar.FreqEnvelope->envout()+ - NoteGlobalPar.FreqLfo->lfoout()*ctl->modwheel.relmod+NoteGlobalPar.Detune); - globaloldamplitude=globalnewamplitude; - globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); + REALTYPE globalpitch, globalfilterpitch; + globalpitch = 0.01 * (NoteGlobalPar.FreqEnvelope->envout() + + NoteGlobalPar.FreqLfo->lfoout() + * ctl->modwheel.relmod + NoteGlobalPar.Detune); + globaloldamplitude = globalnewamplitude; + globalnewamplitude = NoteGlobalPar.Volume + * NoteGlobalPar.AmpEnvelope->envout_dB() + * NoteGlobalPar.AmpLfo->amplfoout(); - globalfilterpitch=NoteGlobalPar.FilterEnvelope->envout()+NoteGlobalPar.FilterLfo->lfoout() - +NoteGlobalPar.FilterCenterPitch; + globalfilterpitch = NoteGlobalPar.FilterEnvelope->envout() + + NoteGlobalPar.FilterLfo->lfoout() + + NoteGlobalPar.FilterCenterPitch; - REALTYPE tmpfilterfreq=globalfilterpitch+ctl->filtercutoff.relfreq - +NoteGlobalPar.FilterFreqTracking; + REALTYPE tmpfilterfreq = globalfilterpitch + ctl->filtercutoff.relfreq + + NoteGlobalPar.FilterFreqTracking; - tmpfilterfreq=NoteGlobalPar.GlobalFilterL->getrealfreq(tmpfilterfreq); + tmpfilterfreq = NoteGlobalPar.GlobalFilterL->getrealfreq(tmpfilterfreq); - REALTYPE globalfilterq=NoteGlobalPar.FilterQ*ctl->filterq.relq; - NoteGlobalPar.GlobalFilterL->setfreq_and_q(tmpfilterfreq,globalfilterq); - NoteGlobalPar.GlobalFilterR->setfreq_and_q(tmpfilterfreq,globalfilterq); + REALTYPE globalfilterq = NoteGlobalPar.FilterQ * ctl->filterq.relq; + NoteGlobalPar.GlobalFilterL->setfreq_and_q(tmpfilterfreq, globalfilterq); + NoteGlobalPar.GlobalFilterR->setfreq_and_q(tmpfilterfreq, globalfilterq); //compute the portamento, if it is used by this note - REALTYPE portamentofreqrap=1.0; - if (portamento!=0) {//this voice use portamento - portamentofreqrap=ctl->portamento.freqrap; - if (ctl->portamento.used==0) {//the portamento has finished - portamento=0;//this note is no longer "portamented" - }; - }; + REALTYPE portamentofreqrap = 1.0; + if(portamento != 0) { //this voice use portamento + portamentofreqrap = ctl->portamento.freqrap; + if(ctl->portamento.used == 0) //the portamento has finished + portamento = 0; //this note is no longer "portamented" + ; + } - realfreq=basefreq*portamentofreqrap*pow(2.0,globalpitch/12.0)*ctl->pitchwheel.relfreq; -}; + realfreq = basefreq * portamentofreqrap + * pow(2.0, globalpitch / 12.0) * ctl->pitchwheel.relfreq; +} -int PADnote::Compute_Linear(REALTYPE *outl,REALTYPE *outr,int freqhi,REALTYPE freqlo) +int PADnote::Compute_Linear(REALTYPE *outl, + REALTYPE *outr, + int freqhi, + REALTYPE freqlo) { - REALTYPE *smps=pars->sample[nsample].smp; - if (smps==NULL) { - finished_=true; - return(1); - }; - int size=pars->sample[nsample].size; - for (int i=0;i<SOUND_BUFFER_SIZE;i++) { - poshi_l+=freqhi; - poshi_r+=freqhi; - poslo+=freqlo; - if (poslo>=1.0) { - poshi_l+=1; - poshi_r+=1; - poslo-=1.0; - }; - if (poshi_l>=size) poshi_l%=size; - if (poshi_r>=size) poshi_r%=size; - - outl[i]=smps[poshi_l]*(1.0-poslo)+smps[poshi_l+1]*poslo; - outr[i]=smps[poshi_r]*(1.0-poslo)+smps[poshi_r+1]*poslo; - }; - return(1); -}; -int PADnote::Compute_Cubic(REALTYPE *outl,REALTYPE *outr,int freqhi,REALTYPE freqlo) + REALTYPE *smps = pars->sample[nsample].smp; + if(smps == NULL) { + finished_ = true; + return 1; + } + int size = pars->sample[nsample].size; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + poshi_l += freqhi; + poshi_r += freqhi; + poslo += freqlo; + if(poslo >= 1.0) { + poshi_l += 1; + poshi_r += 1; + poslo -= 1.0; + } + if(poshi_l >= size) + poshi_l %= size; + if(poshi_r >= size) + poshi_r %= size; + + outl[i] = smps[poshi_l] * (1.0 - poslo) + smps[poshi_l + 1] * poslo; + outr[i] = smps[poshi_r] * (1.0 - poslo) + smps[poshi_r + 1] * poslo; + } + return 1; +} +int PADnote::Compute_Cubic(REALTYPE *outl, + REALTYPE *outr, + int freqhi, + REALTYPE freqlo) { - REALTYPE *smps=pars->sample[nsample].smp; - if (smps==NULL) { - finished_=true; - return(1); - }; - int size=pars->sample[nsample].size; - REALTYPE xm1,x0,x1,x2,a,b,c; - for (int i=0;i<SOUND_BUFFER_SIZE;i++) { - poshi_l+=freqhi; - poshi_r+=freqhi; - poslo+=freqlo; - if (poslo>=1.0) { - poshi_l+=1; - poshi_r+=1; - poslo-=1.0; - }; - if (poshi_l>=size) poshi_l%=size; - if (poshi_r>=size) poshi_r%=size; + REALTYPE *smps = pars->sample[nsample].smp; + if(smps == NULL) { + finished_ = true; + return 1; + } + int size = pars->sample[nsample].size; + REALTYPE xm1, x0, x1, x2, a, b, c; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + poshi_l += freqhi; + poshi_r += freqhi; + poslo += freqlo; + if(poslo >= 1.0) { + poshi_l += 1; + poshi_r += 1; + poslo -= 1.0; + } + if(poshi_l >= size) + poshi_l %= size; + if(poshi_r >= size) + poshi_r %= size; //left - xm1=smps[poshi_l]; - x0=smps[poshi_l + 1]; - x1=smps[poshi_l + 2]; - x2=smps[poshi_l + 3]; - a = (3.0 * (x0-x1) - xm1 + x2)*0.5; - b = 2.0*x1 + xm1 - (5.0*x0 + x2)*0.5; - c = (x1 - xm1)*0.5; + xm1 = smps[poshi_l]; + x0 = smps[poshi_l + 1]; + x1 = smps[poshi_l + 2]; + x2 = smps[poshi_l + 3]; + a = (3.0 * (x0 - x1) - xm1 + x2) * 0.5; + b = 2.0 * x1 + xm1 - (5.0 * x0 + x2) * 0.5; + c = (x1 - xm1) * 0.5; outl[i] = (((a * poslo) + b) * poslo + c) * poslo + x0; //right - xm1=smps[poshi_r]; - x0=smps[poshi_r + 1]; - x1=smps[poshi_r + 2]; - x2=smps[poshi_r + 3]; - a = (3.0 * (x0-x1) - xm1 + x2)*0.5; - b = 2.0*x1 + xm1 - (5.0*x0 + x2)*0.5; - c = (x1 - xm1)*0.5; + xm1 = smps[poshi_r]; + x0 = smps[poshi_r + 1]; + x1 = smps[poshi_r + 2]; + x2 = smps[poshi_r + 3]; + a = (3.0 * (x0 - x1) - xm1 + x2) * 0.5; + b = 2.0 * x1 + xm1 - (5.0 * x0 + x2) * 0.5; + c = (x1 - xm1) * 0.5; outr[i] = (((a * poslo) + b) * poslo + c) * poslo + x0; - }; - return(1); -}; + } + return 1; +} -int PADnote::noteout(REALTYPE *outl,REALTYPE *outr) +int PADnote::noteout(REALTYPE *outl, REALTYPE *outr) { computecurrentparameters(); - REALTYPE *smps=pars->sample[nsample].smp; - if (smps==NULL) { - for (int i=0;i<SOUND_BUFFER_SIZE;i++) { - outl[i]=0.0; - outr[i]=0.0; - }; - return(1); - }; - REALTYPE smpfreq=pars->sample[nsample].basefreq; + REALTYPE *smps = pars->sample[nsample].smp; + if(smps == NULL) { + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + outl[i] = 0.0; + outr[i] = 0.0; + } + return 1; + } + REALTYPE smpfreq = pars->sample[nsample].basefreq; - REALTYPE freqrap=realfreq/smpfreq; - int freqhi=(int) (floor(freqrap)); - REALTYPE freqlo=freqrap-floor(freqrap); + REALTYPE freqrap = realfreq / smpfreq; + int freqhi = (int) (floor(freqrap)); + REALTYPE freqlo = freqrap - floor(freqrap); - if (config.cfg.Interpolation) Compute_Cubic(outl,outr,freqhi,freqlo); - else Compute_Linear(outl,outr,freqhi,freqlo); + if(config.cfg.Interpolation) + Compute_Cubic(outl, outr, freqhi, freqlo); + else + Compute_Linear(outl, outr, freqhi, freqlo); - if (firsttime) { + if(firsttime) { fadein(outl); fadein(outr); - firsttime=false; - }; + firsttime = false; + } NoteGlobalPar.GlobalFilterL->filterout(outl); NoteGlobalPar.GlobalFilterR->filterout(outr); //Apply the punch - if (NoteGlobalPar.Punch.Enabled!=0) { - for (int i=0;i<SOUND_BUFFER_SIZE;i++) { - REALTYPE punchamp=NoteGlobalPar.Punch.initialvalue*NoteGlobalPar.Punch.t+1.0; - outl[i]*=punchamp; - outr[i]*=punchamp; - NoteGlobalPar.Punch.t-=NoteGlobalPar.Punch.dt; - if (NoteGlobalPar.Punch.t<0.0) { - NoteGlobalPar.Punch.Enabled=0; + if(NoteGlobalPar.Punch.Enabled != 0) { + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + REALTYPE punchamp = NoteGlobalPar.Punch.initialvalue + * NoteGlobalPar.Punch.t + 1.0; + outl[i] *= punchamp; + outr[i] *= punchamp; + NoteGlobalPar.Punch.t -= NoteGlobalPar.Punch.dt; + if(NoteGlobalPar.Punch.t < 0.0) { + NoteGlobalPar.Punch.Enabled = 0; break; - }; - }; - }; + } + } + } - if (ABOVE_AMPLITUDE_THRESHOLD(globaloldamplitude,globalnewamplitude)) { + if(ABOVE_AMPLITUDE_THRESHOLD(globaloldamplitude, globalnewamplitude)) { // Amplitude Interpolation - for (int i=0;i<SOUND_BUFFER_SIZE;i++) { - REALTYPE tmpvol=INTERPOLATE_AMPLITUDE(globaloldamplitude,globalnewamplitude,i,SOUND_BUFFER_SIZE); - outl[i]*=tmpvol*NoteGlobalPar.Panning; - outr[i]*=tmpvol*(1.0-NoteGlobalPar.Panning); - }; - } else { - for (int i=0;i<SOUND_BUFFER_SIZE;i++) { - outl[i]*=globalnewamplitude*NoteGlobalPar.Panning; - outr[i]*=globalnewamplitude*(1.0-NoteGlobalPar.Panning); - }; - }; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + REALTYPE tmpvol = INTERPOLATE_AMPLITUDE(globaloldamplitude, + globalnewamplitude, + i, + SOUND_BUFFER_SIZE); + outl[i] *= tmpvol * NoteGlobalPar.Panning; + outr[i] *= tmpvol * (1.0 - NoteGlobalPar.Panning); + } + } + else { + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + outl[i] *= globalnewamplitude * NoteGlobalPar.Panning; + outr[i] *= globalnewamplitude * (1.0 - NoteGlobalPar.Panning); + } + } // Apply legato-specific sound signal modifications - if (Legato.silent) { // Silencer - if (Legato.msg!=LM_FadeIn) { - for (int i=0;i<SOUND_BUFFER_SIZE;i++) { - outl[i]=0.0; - outr[i]=0.0; + if(Legato.silent) // Silencer + if(Legato.msg != LM_FadeIn) + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + outl[i] = 0.0; + outr[i] = 0.0; } - } - } - switch (Legato.msg) { - case LM_CatchUp : // Continue the catch-up... - if (Legato.decounter==-10) Legato.decounter=Legato.fade.length; - for (int i=0;i<SOUND_BUFFER_SIZE;i++) {//Yea, could be done without the loop... + switch(Legato.msg) { + case LM_CatchUp: // Continue the catch-up... + if(Legato.decounter == -10) + Legato.decounter = Legato.fade.length; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { //Yea, could be done without the loop... Legato.decounter--; - if (Legato.decounter<1) { + if(Legato.decounter < 1) { // Catching-up done, we can finally set // the note to the actual parameters. - Legato.decounter=-10; - Legato.msg=LM_ToNorm; - PADlegatonote(Legato.param.freq, Legato.param.vel, Legato.param.portamento, Legato.param.midinote, false); + Legato.decounter = -10; + Legato.msg = LM_ToNorm; + PADlegatonote(Legato.param.freq, + Legato.param.vel, + Legato.param.portamento, + Legato.param.midinote, + false); break; } } break; - case LM_FadeIn : // Fade-in - if (Legato.decounter==-10) Legato.decounter=Legato.fade.length; - Legato.silent=false; - for (int i=0;i<SOUND_BUFFER_SIZE;i++) { + case LM_FadeIn: // Fade-in + if(Legato.decounter == -10) + Legato.decounter = Legato.fade.length; + Legato.silent = false; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { Legato.decounter--; - if (Legato.decounter<1) { - Legato.decounter=-10; - Legato.msg=LM_Norm; + if(Legato.decounter < 1) { + Legato.decounter = -10; + Legato.msg = LM_Norm; break; } - Legato.fade.m+=Legato.fade.step; - outl[i]*=Legato.fade.m; - outr[i]*=Legato.fade.m; + Legato.fade.m += Legato.fade.step; + outl[i] *= Legato.fade.m; + outr[i] *= Legato.fade.m; } break; - case LM_FadeOut : // Fade-out, then set the catch-up - if (Legato.decounter==-10) Legato.decounter=Legato.fade.length; - for (int i=0;i<SOUND_BUFFER_SIZE;i++) { + case LM_FadeOut: // Fade-out, then set the catch-up + if(Legato.decounter == -10) + Legato.decounter = Legato.fade.length; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { Legato.decounter--; - if (Legato.decounter<1) { - for (int j=i;j<SOUND_BUFFER_SIZE;j++) { - outl[j]=0.0; - outr[j]=0.0; + if(Legato.decounter < 1) { + for(int j = i; j < SOUND_BUFFER_SIZE; j++) { + outl[j] = 0.0; + outr[j] = 0.0; } - Legato.decounter=-10; - Legato.silent=true; + Legato.decounter = -10; + Legato.silent = true; // Fading-out done, now set the catch-up : - Legato.decounter=Legato.fade.length; - Legato.msg=LM_CatchUp; - REALTYPE catchupfreq=Legato.param.freq*(Legato.param.freq/Legato.lastfreq);//This freq should make this now silent note to catch-up (or should I say resync ?) with the heard note for the same length it stayed at the previous freq during the fadeout. - PADlegatonote(catchupfreq, Legato.param.vel, Legato.param.portamento, Legato.param.midinote, false); + Legato.decounter = Legato.fade.length; + Legato.msg = LM_CatchUp; + REALTYPE catchupfreq = Legato.param.freq + * (Legato.param.freq / Legato.lastfreq); //This freq should make this now silent note to catch-up (or should I say resync ?) with the heard note for the same length it stayed at the previous freq during the fadeout. + PADlegatonote(catchupfreq, + Legato.param.vel, + Legato.param.portamento, + Legato.param.midinote, + false); break; } - Legato.fade.m-=Legato.fade.step; - outl[i]*=Legato.fade.m; - outr[i]*=Legato.fade.m; + Legato.fade.m -= Legato.fade.step; + outl[i] *= Legato.fade.m; + outr[i] *= Legato.fade.m; } break; - default : + default: break; } // Check if the global amplitude is finished. // If it does, disable the note - if (NoteGlobalPar.AmpEnvelope->finished()!=0) { - for (int i=0;i<SOUND_BUFFER_SIZE;i++) {//fade-out - REALTYPE tmp=1.0-(REALTYPE)i/(REALTYPE)SOUND_BUFFER_SIZE; - outl[i]*=tmp; - outr[i]*=tmp; - }; - finished_=1; - }; - - return(1); -}; + if(NoteGlobalPar.AmpEnvelope->finished() != 0) { + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { //fade-out + REALTYPE tmp = 1.0 - (REALTYPE)i / (REALTYPE)SOUND_BUFFER_SIZE; + outl[i] *= tmp; + outr[i] *= tmp; + } + finished_ = 1; + } + + return 1; +} int PADnote::finished() { - return(finished_); -}; + return finished_; +} void PADnote::relasekey() { NoteGlobalPar.FreqEnvelope->relasekey(); NoteGlobalPar.FilterEnvelope->relasekey(); NoteGlobalPar.AmpEnvelope->relasekey(); -}; +} diff --git a/src/Synth/PADnote.h b/src/Synth/PADnote.h @@ -32,95 +32,112 @@ /**The "pad" synthesizer*/ class PADnote { -public: - PADnote(PADnoteParameters *parameters, Controller *ctl_,REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool besilent); - ~PADnote(); + public: + PADnote(PADnoteParameters *parameters, + Controller *ctl_, + REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote, + bool besilent); + ~PADnote(); + + void PADlegatonote(REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote, + bool externcall); + + int noteout(REALTYPE *outl, REALTYPE *outr); + int finished(); + void relasekey(); + + int ready; + + private: + void fadein(REALTYPE *smps); + void computecurrentparameters(); + bool finished_; + PADnoteParameters *pars; + + int poshi_l, poshi_r; + REALTYPE poslo; + + REALTYPE basefreq; + bool firsttime, released; + + int nsample, portamento; + + int Compute_Linear(REALTYPE *outl, + REALTYPE *outr, + int freqhi, + REALTYPE freqlo); + int Compute_Cubic(REALTYPE *outl, + REALTYPE *outr, + int freqhi, + REALTYPE freqlo); - void PADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool externcall); - int noteout(REALTYPE *outl,REALTYPE *outr); - int finished(); - void relasekey(); - - int ready; + struct { + /****************************************** + * FREQUENCY GLOBAL PARAMETERS * + ******************************************/ + REALTYPE Detune; //cents -private: - void fadein(REALTYPE *smps); - void computecurrentparameters(); - bool finished_; - PADnoteParameters *pars; + Envelope *FreqEnvelope; + LFO *FreqLfo; - int poshi_l,poshi_r; - REALTYPE poslo; + /******************************************** + * AMPLITUDE GLOBAL PARAMETERS * + ********************************************/ + REALTYPE Volume; // [ 0 .. 1 ] - REALTYPE basefreq; - bool firsttime,released; + REALTYPE Panning; // [ 0 .. 1 ] - int nsample,portamento; + Envelope *AmpEnvelope; + LFO *AmpLfo; - int Compute_Linear(REALTYPE *outl,REALTYPE *outr,int freqhi,REALTYPE freqlo); - int Compute_Cubic(REALTYPE *outl,REALTYPE *outr,int freqhi,REALTYPE freqlo); + struct { + int Enabled; + REALTYPE initialvalue, dt, t; + } Punch; + /****************************************** + * FILTER GLOBAL PARAMETERS * + ******************************************/ + Filter *GlobalFilterL, *GlobalFilterR; - struct { - /****************************************** - * FREQUENCY GLOBAL PARAMETERS * - ******************************************/ - REALTYPE Detune;//cents + REALTYPE FilterCenterPitch; //octaves + REALTYPE FilterQ; + REALTYPE FilterFreqTracking; - Envelope *FreqEnvelope; - LFO *FreqLfo; + Envelope *FilterEnvelope; - /******************************************** - * AMPLITUDE GLOBAL PARAMETERS * - ********************************************/ - REALTYPE Volume;// [ 0 .. 1 ] + LFO *FilterLfo; + } NoteGlobalPar; - REALTYPE Panning;// [ 0 .. 1 ] - Envelope *AmpEnvelope; - LFO *AmpLfo; + REALTYPE globaloldamplitude, globalnewamplitude, velocity, realfreq; + REALTYPE *tmpwave; + Controller *ctl; + // Legato vars struct { - int Enabled; - REALTYPE initialvalue,dt,t; - } Punch; - - /****************************************** - * FILTER GLOBAL PARAMETERS * - ******************************************/ - Filter *GlobalFilterL,*GlobalFilterR; - - REALTYPE FilterCenterPitch;//octaves - REALTYPE FilterQ; - REALTYPE FilterFreqTracking; - - Envelope *FilterEnvelope; - - LFO *FilterLfo; - } NoteGlobalPar; - - - REALTYPE globaloldamplitude,globalnewamplitude,velocity,realfreq; - REALTYPE *tmpwave; - Controller *ctl; - - // Legato vars - struct { - bool silent; - REALTYPE lastfreq; - LegatoMsg msg; - int decounter; - struct { // Fade In/Out vars - int length; - REALTYPE m, step; - } fade; - struct { // Note parameters - REALTYPE freq, vel; - int portamento, midinote; - } param; - } Legato; + bool silent; + REALTYPE lastfreq; + LegatoMsg msg; + int decounter; + struct { // Fade In/Out vars + int length; + REALTYPE m, step; + } fade; + struct { // Note parameters + REALTYPE freq, vel; + int portamento, midinote; + } param; + } Legato; }; #endif + diff --git a/src/Synth/Resonance.cpp b/src/Synth/Resonance.cpp @@ -30,68 +30,79 @@ 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; -}; + 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) +void Resonance::setpoint(int n, unsigned char p) { - if ((n<0)||(n>=N_RES_POINTS)) return; - Prespoints[n]=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) +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; - }; -}; + 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" @@ -99,25 +110,33 @@ void Resonance::applyres(int n,FFTFREQS fftdata,REALTYPE 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); -}; + 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; +} /* @@ -125,129 +144,139 @@ REALTYPE Resonance::getfreqresponse(REALTYPE freq) */ 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; - }; -}; + 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); - }; + 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; - }; - }; -}; + 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)); -}; + 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()); -}; + 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)); -}; + 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); -}; + return 0.25 + 10.0 * Poctavesfreq / 127.0; +} -void Resonance::sendcontroller(MidiControllers ctl,REALTYPE par) +void Resonance::sendcontroller(MidiControllers ctl, REALTYPE par) { - if (ctl==C_resonance_center) ctlcenter=par; - else ctlbw=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->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]); + 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(); - }; -}; - + } +} diff --git a/src/Synth/Resonance.h b/src/Synth/Resonance.h @@ -31,39 +31,40 @@ class Resonance:public Presets { -public: - Resonance(); - ~Resonance(); - void setpoint(int n,unsigned char p); - void applyres(int n,FFTFREQS fftdata,REALTYPE freq); - void smooth(); - void interpolatepeaks(int type); - void randomize(int type); - - void add2XML(XMLwrapper *xml); - void defaults(); - void getfromXML(XMLwrapper *xml); - - - REALTYPE getfreqpos(REALTYPE freq); - REALTYPE getfreqx(REALTYPE x); - REALTYPE getfreqresponse(REALTYPE freq); - REALTYPE getcenterfreq(); - REALTYPE getoctavesfreq(); - void sendcontroller(MidiControllers ctl,REALTYPE par); - - //parameters - unsigned char Penabled; //if the ressonance is enabled - unsigned char Prespoints[N_RES_POINTS]; //how many points define the resonance function - unsigned char PmaxdB; //how many dB the signal may be amplified - unsigned char Pcenterfreq,Poctavesfreq; //the center frequency of the res. func., and the number of octaves - unsigned char Pprotectthefundamental; //the fundamental (1-st harmonic) is not damped, even it resonance function is low - - //controllers - REALTYPE ctlcenter;//center frequency(relative) - REALTYPE ctlbw;//bandwidth(relative) - -private: + public: + Resonance(); + ~Resonance(); + void setpoint(int n, unsigned char p); + void applyres(int n, FFTFREQS fftdata, REALTYPE freq); + void smooth(); + void interpolatepeaks(int type); + void randomize(int type); + + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); + + + REALTYPE getfreqpos(REALTYPE freq); + REALTYPE getfreqx(REALTYPE x); + REALTYPE getfreqresponse(REALTYPE freq); + REALTYPE getcenterfreq(); + REALTYPE getoctavesfreq(); + void sendcontroller(MidiControllers ctl, REALTYPE par); + + //parameters + unsigned char Penabled; //if the ressonance is enabled + unsigned char Prespoints[N_RES_POINTS]; //how many points define the resonance function + unsigned char PmaxdB; //how many dB the signal may be amplified + unsigned char Pcenterfreq, Poctavesfreq; //the center frequency of the res. func., and the number of octaves + unsigned char Pprotectthefundamental; //the fundamental (1-st harmonic) is not damped, even it resonance function is low + + //controllers + REALTYPE ctlcenter; //center frequency(relative) + REALTYPE ctlbw; //bandwidth(relative) + + private: }; #endif + diff --git a/src/Synth/SUBnote.cpp b/src/Synth/SUBnote.cpp @@ -27,419 +27,491 @@ #include "SUBnote.h" #include "../Misc/Util.h" -SUBnote::SUBnote(SUBnoteParameters *parameters,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote,bool besilent) +SUBnote::SUBnote(SUBnoteParameters *parameters, + Controller *ctl_, + REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote, + bool besilent) { - ready=0; + ready = 0; - tmpsmp=new REALTYPE[SOUND_BUFFER_SIZE]; - tmprnd=new REALTYPE[SOUND_BUFFER_SIZE]; + tmpsmp = new REALTYPE[SOUND_BUFFER_SIZE]; + tmprnd = new REALTYPE[SOUND_BUFFER_SIZE]; // Initialise some legato-specific vars - Legato.msg=LM_Norm; - Legato.fade.length=(int)(SAMPLE_RATE*0.005);// 0.005 seems ok. - if (Legato.fade.length<1) Legato.fade.length=1;// (if something's fishy) - Legato.fade.step=(1.0/Legato.fade.length); - Legato.decounter=-10; - Legato.param.freq=freq; - Legato.param.vel=velocity; - Legato.param.portamento=portamento_; - Legato.param.midinote=midinote; - Legato.silent=besilent; - - pars=parameters; - ctl=ctl_; - portamento=portamento_; - NoteEnabled=ON; - volume=pow(0.1,3.0*(1.0-pars->PVolume/96.0));//-60 dB .. 0 dB - volume*=VelF(velocity,pars->PAmpVelocityScaleFunction); - if (pars->PPanning!=0) panning=pars->PPanning/127.0; - else panning=RND; - numstages=pars->Pnumstages; - stereo=pars->Pstereo; - start=pars->Pstart; - firsttick=1; + Legato.msg = LM_Norm; + Legato.fade.length = (int)(SAMPLE_RATE * 0.005); // 0.005 seems ok. + if(Legato.fade.length < 1) + Legato.fade.length = 1; // (if something's fishy) + Legato.fade.step = (1.0 / Legato.fade.length); + Legato.decounter = -10; + Legato.param.freq = freq; + Legato.param.vel = velocity; + Legato.param.portamento = portamento_; + Legato.param.midinote = midinote; + Legato.silent = besilent; + + pars = parameters; + ctl = ctl_; + portamento = portamento_; + NoteEnabled = ON; + volume = pow(0.1, 3.0 * (1.0 - pars->PVolume / 96.0)); //-60 dB .. 0 dB + volume *= VelF(velocity, pars->PAmpVelocityScaleFunction); + if(pars->PPanning != 0) + panning = pars->PPanning / 127.0; + else + panning = RND; + numstages = pars->Pnumstages; + stereo = pars->Pstereo; + start = pars->Pstart; + firsttick = 1; int pos[MAX_SUB_HARMONICS]; - if (pars->Pfixedfreq==0) basefreq=freq; + if(pars->Pfixedfreq == 0) + basefreq = freq; else { - basefreq=440.0; - int fixedfreqET=pars->PfixedfreqET; - if (fixedfreqET!=0) {//if the frequency varies according the keyboard note - REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0); - if (fixedfreqET<=64) basefreq*=pow(2.0,tmp); - else basefreq*=pow(3.0,tmp); - }; - - }; - REALTYPE detune=getdetune(pars->PDetuneType,pars->PCoarseDetune,pars->PDetune); - basefreq*=pow(2.0,detune/1200.0);//detune + basefreq = 440.0; + int fixedfreqET = pars->PfixedfreqET; + if(fixedfreqET != 0) { //if the frequency varies according the keyboard note + REALTYPE tmp = + (midinote + - 69.0) / 12.0 * (pow(2.0, (fixedfreqET - 1) / 63.0) - 1.0); + if(fixedfreqET <= 64) + basefreq *= pow(2.0, tmp); + else + basefreq *= pow(3.0, tmp); + } + } + REALTYPE detune = getdetune(pars->PDetuneType, + pars->PCoarseDetune, + pars->PDetune); + basefreq *= pow(2.0, detune / 1200.0); //detune // basefreq*=ctl->pitchwheel.relfreq;//pitch wheel //global filter - GlobalFilterCenterPitch=pars->GlobalFilter->getfreq()+//center freq - (pars->PGlobalFilterVelocityScale/127.0*6.0)* //velocity sensing - (VelF(velocity,pars->PGlobalFilterVelocityScaleFunction)-1); + GlobalFilterCenterPitch = pars->GlobalFilter->getfreq() //center freq + + (pars->PGlobalFilterVelocityScale / 127.0 * 6.0) //velocity sensing + * (VelF(velocity, + pars->PGlobalFilterVelocityScaleFunction) + - 1); - GlobalFilterL=NULL; - GlobalFilterR=NULL; - GlobalFilterEnvelope=NULL; + GlobalFilterL = NULL; + GlobalFilterR = NULL; + GlobalFilterEnvelope = NULL; //select only harmonics that desire to compute - numharmonics=0; - for (int n=0;n<MAX_SUB_HARMONICS;n++) { - if (pars->Phmag[n]==0)continue; - if (n*basefreq>SAMPLE_RATE/2.0) break;//remove the freqs above the Nyquist freq - pos[numharmonics++]=n; - }; - firstnumharmonics=numharmonics;//(gf)Useful in legato mode. - - if (numharmonics==0) { - NoteEnabled=OFF; + numharmonics = 0; + for(int n = 0; n < MAX_SUB_HARMONICS; n++) { + if(pars->Phmag[n] == 0) + continue; + if(n * basefreq > SAMPLE_RATE / 2.0) + break; //remove the freqs above the Nyquist freq + pos[numharmonics++] = n; + } + firstnumharmonics = numharmonics; //(gf)Useful in legato mode. + + if(numharmonics == 0) { + NoteEnabled = OFF; return; - }; + } - lfilter=new bpfilter[numstages*numharmonics]; - if (stereo!=0) rfilter=new bpfilter[numstages*numharmonics]; + lfilter = new bpfilter[numstages * numharmonics]; + if(stereo != 0) + rfilter = new bpfilter[numstages * numharmonics]; //how much the amplitude is normalised (because the harmonics) - REALTYPE reduceamp=0.0; - - for (int n=0;n<numharmonics;n++) { + REALTYPE reduceamp = 0.0; - REALTYPE freq=basefreq*(pos[n]+1); + for(int n = 0; n < numharmonics; n++) { + REALTYPE freq = basefreq * (pos[n] + 1); //the bandwidth is not absolute(Hz); it is relative to frequency - REALTYPE bw=pow(10,(pars->Pbandwidth-127.0)/127.0*4)*numstages; + REALTYPE bw = + pow(10, (pars->Pbandwidth - 127.0) / 127.0 * 4) * numstages; //Bandwidth Scale - bw*=pow(1000/freq,(pars->Pbwscale-64.0)/64.0*3.0); + bw *= pow(1000 / freq, (pars->Pbwscale - 64.0) / 64.0 * 3.0); //Relative BandWidth - bw*=pow(100,(pars->Phrelbw[pos[n]]-64.0)/64.0); + bw *= pow(100, (pars->Phrelbw[pos[n]] - 64.0) / 64.0); - if (bw>25.0) bw=25.0; + if(bw > 25.0) + bw = 25.0; //try to keep same amplitude on all freqs and bw. (empirically) - REALTYPE gain=sqrt(1500.0/(bw*freq)); + REALTYPE gain = sqrt(1500.0 / (bw * freq)); - REALTYPE hmagnew=1.0-pars->Phmag[pos[n]]/127.0; + REALTYPE hmagnew = 1.0 - pars->Phmag[pos[n]] / 127.0; REALTYPE hgain; - switch (pars->Phmagtype) { + switch(pars->Phmagtype) { case 1: - hgain=exp(hmagnew*log(0.01)); + hgain = exp(hmagnew * log(0.01)); break; case 2: - hgain=exp(hmagnew*log(0.001)); + hgain = exp(hmagnew * log(0.001)); break; case 3: - hgain=exp(hmagnew*log(0.0001)); + hgain = exp(hmagnew * log(0.0001)); break; case 4: - hgain=exp(hmagnew*log(0.00001)); + hgain = exp(hmagnew * log(0.00001)); break; default: - hgain=1.0-hmagnew; - }; - gain*=hgain; - reduceamp+=hgain; - - for (int nph=0;nph<numstages;nph++) { - REALTYPE amp=1.0; - if (nph==0) amp=gain; - initfilter(lfilter[nph+n*numstages],freq,bw,amp,hgain); - if (stereo!=0) initfilter(rfilter[nph+n*numstages],freq,bw,amp,hgain); - }; - }; + hgain = 1.0 - hmagnew; + } + gain *= hgain; + reduceamp += hgain; + + for(int nph = 0; nph < numstages; nph++) { + REALTYPE amp = 1.0; + if(nph == 0) + amp = gain; + initfilter(lfilter[nph + n * numstages], freq, bw, amp, hgain); + if(stereo != 0) + initfilter(rfilter[nph + n * numstages], freq, bw, amp, hgain); + } + } - if (reduceamp<0.001) reduceamp=1.0; - volume/=reduceamp; + if(reduceamp < 0.001) + reduceamp = 1.0; + volume /= reduceamp; - oldpitchwheel=0; - oldbandwidth=64; - if (pars->Pfixedfreq==0) initparameters(basefreq); - else initparameters(basefreq/440.0*freq); + oldpitchwheel = 0; + oldbandwidth = 64; + if(pars->Pfixedfreq == 0) + initparameters(basefreq); + else + initparameters(basefreq / 440.0 * freq); - oldamplitude=newamplitude; - ready=1; -}; + oldamplitude = newamplitude; + ready = 1; +} // SUBlegatonote: This function is (mostly) a copy of SUBnote(...) and // initparameters(...) stuck together with some lines removed so that // it only alter the already playing note (to perform legato). It is // possible I left stuff that is not required for this. -void SUBnote::SUBlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool externcall) +void SUBnote::SUBlegatonote(REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote, + bool externcall) { //SUBnoteParameters *parameters=pars; //Controller *ctl_=ctl; // Manage legato stuff - if (externcall) Legato.msg=LM_Norm; - if (Legato.msg!=LM_CatchUp) { - Legato.lastfreq=Legato.param.freq; - Legato.param.freq=freq; - Legato.param.vel=velocity; - Legato.param.portamento=portamento_; - Legato.param.midinote=midinote; - if (Legato.msg==LM_Norm) { - if (Legato.silent) { - Legato.fade.m=0.0; - Legato.msg=LM_FadeIn; - } else { - Legato.fade.m=1.0; - Legato.msg=LM_FadeOut; + if(externcall) + Legato.msg = LM_Norm; + if(Legato.msg != LM_CatchUp) { + Legato.lastfreq = Legato.param.freq; + Legato.param.freq = freq; + Legato.param.vel = velocity; + Legato.param.portamento = portamento_; + Legato.param.midinote = midinote; + if(Legato.msg == LM_Norm) { + if(Legato.silent) { + Legato.fade.m = 0.0; + Legato.msg = LM_FadeIn; + } + else { + Legato.fade.m = 1.0; + Legato.msg = LM_FadeOut; return; } } - if (Legato.msg==LM_ToNorm) Legato.msg=LM_Norm; + if(Legato.msg == LM_ToNorm) + Legato.msg = LM_Norm; } - portamento=portamento_; + portamento = portamento_; - volume=pow(0.1,3.0*(1.0-pars->PVolume/96.0));//-60 dB .. 0 dB - volume*=VelF(velocity,pars->PAmpVelocityScaleFunction); - if (pars->PPanning!=0) panning=pars->PPanning/127.0; - else panning=RND; + volume = pow(0.1, 3.0 * (1.0 - pars->PVolume / 96.0)); //-60 dB .. 0 dB + volume *= VelF(velocity, pars->PAmpVelocityScaleFunction); + if(pars->PPanning != 0) + panning = pars->PPanning / 127.0; + else + panning = RND; ///start=pars->Pstart; int pos[MAX_SUB_HARMONICS]; - if (pars->Pfixedfreq==0) basefreq=freq; + if(pars->Pfixedfreq == 0) + basefreq = freq; else { - basefreq=440.0; - int fixedfreqET=pars->PfixedfreqET; - if (fixedfreqET!=0) {//if the frequency varies according the keyboard note - REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0); - if (fixedfreqET<=64) basefreq*=pow(2.0,tmp); - else basefreq*=pow(3.0,tmp); - }; - }; - REALTYPE detune=getdetune(pars->PDetuneType,pars->PCoarseDetune,pars->PDetune); - basefreq*=pow(2.0,detune/1200.0);//detune + basefreq = 440.0; + int fixedfreqET = pars->PfixedfreqET; + if(fixedfreqET != 0) { //if the frequency varies according the keyboard note + REALTYPE tmp = + (midinote + - 69.0) / 12.0 * (pow(2.0, (fixedfreqET - 1) / 63.0) - 1.0); + if(fixedfreqET <= 64) + basefreq *= pow(2.0, tmp); + else + basefreq *= pow(3.0, tmp); + } + } + REALTYPE detune = getdetune(pars->PDetuneType, + pars->PCoarseDetune, + pars->PDetune); + basefreq *= pow(2.0, detune / 1200.0); //detune //global filter - GlobalFilterCenterPitch=pars->GlobalFilter->getfreq()+//center freq - (pars->PGlobalFilterVelocityScale/127.0*6.0)* //velocity sensing - (VelF(velocity,pars->PGlobalFilterVelocityScaleFunction)-1); - - - int legatonumharmonics=0; - for (int n=0;n<MAX_SUB_HARMONICS;n++) { - if (pars->Phmag[n]==0)continue; - if (n*basefreq>SAMPLE_RATE/2.0) break;//remove the freqs above the Nyquist freq - pos[legatonumharmonics++]=n; - }; - if (legatonumharmonics>firstnumharmonics) numharmonics=firstnumharmonics; - else numharmonics=legatonumharmonics; - - if (numharmonics==0) { - NoteEnabled=OFF; + GlobalFilterCenterPitch = pars->GlobalFilter->getfreq() //center freq + + (pars->PGlobalFilterVelocityScale / 127.0 * 6.0) //velocity sensing + * (VelF(velocity, + pars->PGlobalFilterVelocityScaleFunction) + - 1); + + + int legatonumharmonics = 0; + for(int n = 0; n < MAX_SUB_HARMONICS; n++) { + if(pars->Phmag[n] == 0) + continue; + if(n * basefreq > SAMPLE_RATE / 2.0) + break; //remove the freqs above the Nyquist freq + pos[legatonumharmonics++] = n; + } + if(legatonumharmonics > firstnumharmonics) + numharmonics = firstnumharmonics; + else + numharmonics = legatonumharmonics; + + if(numharmonics == 0) { + NoteEnabled = OFF; return; - }; + } //how much the amplitude is normalised (because the harmonics) - REALTYPE reduceamp=0.0; + REALTYPE reduceamp = 0.0; - for (int n=0;n<numharmonics;n++) { - - REALTYPE freq=basefreq*(pos[n]+1); + for(int n = 0; n < numharmonics; n++) { + REALTYPE freq = basefreq * (pos[n] + 1); //the bandwidth is not absolute(Hz); it is relative to frequency - REALTYPE bw=pow(10,(pars->Pbandwidth-127.0)/127.0*4)*numstages; + REALTYPE bw = + pow(10, (pars->Pbandwidth - 127.0) / 127.0 * 4) * numstages; //Bandwidth Scale - bw*=pow(1000/freq,(pars->Pbwscale-64.0)/64.0*3.0); + bw *= pow(1000 / freq, (pars->Pbwscale - 64.0) / 64.0 * 3.0); //Relative BandWidth - bw*=pow(100,(pars->Phrelbw[pos[n]]-64.0)/64.0); + bw *= pow(100, (pars->Phrelbw[pos[n]] - 64.0) / 64.0); - if (bw>25.0) bw=25.0; + if(bw > 25.0) + bw = 25.0; //try to keep same amplitude on all freqs and bw. (empirically) - REALTYPE gain=sqrt(1500.0/(bw*freq)); + REALTYPE gain = sqrt(1500.0 / (bw * freq)); - REALTYPE hmagnew=1.0-pars->Phmag[pos[n]]/127.0; + REALTYPE hmagnew = 1.0 - pars->Phmag[pos[n]] / 127.0; REALTYPE hgain; - switch (pars->Phmagtype) { + switch(pars->Phmagtype) { case 1: - hgain=exp(hmagnew*log(0.01)); + hgain = exp(hmagnew * log(0.01)); break; case 2: - hgain=exp(hmagnew*log(0.001)); + hgain = exp(hmagnew * log(0.001)); break; case 3: - hgain=exp(hmagnew*log(0.0001)); + hgain = exp(hmagnew * log(0.0001)); break; case 4: - hgain=exp(hmagnew*log(0.00001)); + hgain = exp(hmagnew * log(0.00001)); break; default: - hgain=1.0-hmagnew; - }; - gain*=hgain; - reduceamp+=hgain; - - for (int nph=0;nph<numstages;nph++) { - REALTYPE amp=1.0; - if (nph==0) amp=gain; - initfilter(lfilter[nph+n*numstages],freq,bw,amp,hgain); - if (stereo!=0) initfilter(rfilter[nph+n*numstages],freq,bw,amp,hgain); - }; - }; + hgain = 1.0 - hmagnew; + } + gain *= hgain; + reduceamp += hgain; + + for(int nph = 0; nph < numstages; nph++) { + REALTYPE amp = 1.0; + if(nph == 0) + amp = gain; + initfilter(lfilter[nph + n * numstages], freq, bw, amp, hgain); + if(stereo != 0) + initfilter(rfilter[nph + n * numstages], freq, bw, amp, hgain); + } + } - if (reduceamp<0.001) reduceamp=1.0; - volume/=reduceamp; + if(reduceamp < 0.001) + reduceamp = 1.0; + volume /= reduceamp; - oldpitchwheel=0; - oldbandwidth=64; + oldpitchwheel = 0; + oldbandwidth = 64; - if (pars->Pfixedfreq==0) freq=basefreq; - else freq*=basefreq/440.0; + if(pars->Pfixedfreq == 0) + freq = basefreq; + else + freq *= basefreq / 440.0; /////////////// // Altered initparameters(...) content: - if (pars->PGlobalFilterEnabled!=0) { - globalfiltercenterq=pars->GlobalFilter->getq(); - GlobalFilterFreqTracking=pars->GlobalFilter->getfreqtracking(basefreq); - }; + if(pars->PGlobalFilterEnabled != 0) { + globalfiltercenterq = pars->GlobalFilter->getq(); + GlobalFilterFreqTracking = pars->GlobalFilter->getfreqtracking(basefreq); + } // end of the altered initparameters function content. /////////////// - oldamplitude=newamplitude; + oldamplitude = newamplitude; // End of the SUBlegatonote function. -}; +} SUBnote::~SUBnote() { - if (NoteEnabled!=OFF) KillNote(); + if(NoteEnabled != OFF) + KillNote(); delete [] tmpsmp; delete [] tmprnd; -}; +} /* * Kill the note */ void SUBnote::KillNote() { - if (NoteEnabled!=OFF) { + if(NoteEnabled != OFF) { delete [] lfilter; - lfilter=NULL; - if (stereo!=0) delete [] rfilter; - rfilter=NULL; - delete(AmpEnvelope); - if (FreqEnvelope!=NULL) delete(FreqEnvelope); - if (BandWidthEnvelope!=NULL) delete(BandWidthEnvelope); - NoteEnabled=OFF; - }; - -}; + lfilter = NULL; + if(stereo != 0) + delete [] rfilter; + rfilter = NULL; + delete (AmpEnvelope); + if(FreqEnvelope != NULL) + delete (FreqEnvelope); + if(BandWidthEnvelope != NULL) + delete (BandWidthEnvelope); + NoteEnabled = OFF; + } +} /* * Compute the filters coefficients */ -void SUBnote::computefiltercoefs(bpfilter &filter,REALTYPE freq,REALTYPE bw,REALTYPE gain) +void SUBnote::computefiltercoefs(bpfilter &filter, + REALTYPE freq, + REALTYPE bw, + REALTYPE gain) { - if (freq>SAMPLE_RATE/2.0-200.0) { - freq=SAMPLE_RATE/2.0-200.0; - }; - - REALTYPE omega=2.0*PI*freq/SAMPLE_RATE; - REALTYPE sn=sin(omega); - REALTYPE cs=cos(omega); - REALTYPE alpha=sn*sinh(LOG_2/2.0*bw*omega/sn); + if(freq > SAMPLE_RATE / 2.0 - 200.0) + freq = SAMPLE_RATE / 2.0 - 200.0; + ; - if (alpha>1) alpha=1; - if (alpha>bw) alpha=bw; + REALTYPE omega = 2.0 * PI * freq / SAMPLE_RATE; + REALTYPE sn = sin(omega); + REALTYPE cs = cos(omega); + REALTYPE alpha = sn * sinh(LOG_2 / 2.0 * bw * omega / sn); - filter.b0=alpha/(1.0+alpha)*filter.amp*gain; - filter.b2=-alpha/(1.0+alpha)*filter.amp*gain; - filter.a1=-2.0*cs/(1.0+alpha); - filter.a2=(1.0-alpha)/(1.0+alpha); + if(alpha > 1) + alpha = 1; + if(alpha > bw) + alpha = bw; -}; + filter.b0 = alpha / (1.0 + alpha) * filter.amp * gain; + filter.b2 = -alpha / (1.0 + alpha) * filter.amp * gain; + filter.a1 = -2.0 * cs / (1.0 + alpha); + filter.a2 = (1.0 - alpha) / (1.0 + alpha); +} /* * Initialise the filters */ -void SUBnote::initfilter(bpfilter &filter,REALTYPE freq,REALTYPE bw,REALTYPE amp,REALTYPE mag) +void SUBnote::initfilter(bpfilter &filter, + REALTYPE freq, + REALTYPE bw, + REALTYPE amp, + REALTYPE mag) { - filter.xn1=0.0; - filter.xn2=0.0; - - if (start==0) { - filter.yn1=0.0; - filter.yn2=0.0; - } else { - REALTYPE a=0.1*mag;//empirically - REALTYPE p=RND*2.0*PI; - if (start==1) a*=RND; - filter.yn1=a*cos(p); - filter.yn2=a*cos(p+freq*2.0*PI/SAMPLE_RATE); + filter.xn1 = 0.0; + filter.xn2 = 0.0; + + if(start == 0) { + filter.yn1 = 0.0; + filter.yn2 = 0.0; + } + else { + REALTYPE a = 0.1 * mag; //empirically + REALTYPE p = RND * 2.0 * PI; + if(start == 1) + a *= RND; + filter.yn1 = a * cos(p); + filter.yn2 = a * cos(p + freq * 2.0 * PI / SAMPLE_RATE); //correct the error of computation the start amplitude //at very high frequencies - if (freq>SAMPLE_RATE*0.96) { - filter.yn1=0.0; - filter.yn2=0.0; - - }; - }; + if(freq > SAMPLE_RATE * 0.96) { + filter.yn1 = 0.0; + filter.yn2 = 0.0; + } + } - filter.amp=amp; - filter.freq=freq; - filter.bw=bw; - computefiltercoefs(filter,freq,bw,1.0); -}; + filter.amp = amp; + filter.freq = freq; + filter.bw = bw; + computefiltercoefs(filter, freq, bw, 1.0); +} /* * Do the filtering */ -void SUBnote::filter(bpfilter &filter,REALTYPE *smps) +void SUBnote::filter(bpfilter &filter, REALTYPE *smps) { - int i; + int i; REALTYPE out; - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - out=smps[i] * filter.b0 + filter.b2 * filter.xn2 - -filter.a1 * filter.yn1 - filter.a2 * filter.yn2; - filter.xn2=filter.xn1; - filter.xn1=smps[i]; - filter.yn2=filter.yn1; - filter.yn1=out; - smps[i]=out; - }; -}; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + out = smps[i] * filter.b0 + filter.b2 * filter.xn2 + - filter.a1 * filter.yn1 - filter.a2 * filter.yn2; + filter.xn2 = filter.xn1; + filter.xn1 = smps[i]; + filter.yn2 = filter.yn1; + filter.yn1 = out; + smps[i] = out; + } +} /* * Init Parameters */ void SUBnote::initparameters(REALTYPE freq) { - AmpEnvelope=new Envelope(pars->AmpEnvelope,freq); - if (pars->PFreqEnvelopeEnabled!=0) FreqEnvelope=new Envelope(pars->FreqEnvelope,freq); - else FreqEnvelope=NULL; - if (pars->PBandWidthEnvelopeEnabled!=0) BandWidthEnvelope=new Envelope(pars->BandWidthEnvelope,freq); - else BandWidthEnvelope=NULL; - if (pars->PGlobalFilterEnabled!=0) { - globalfiltercenterq=pars->GlobalFilter->getq(); - GlobalFilterL=new Filter(pars->GlobalFilter); - if (stereo!=0) GlobalFilterR=new Filter(pars->GlobalFilter); - GlobalFilterEnvelope=new Envelope(pars->GlobalFilterEnvelope,freq); - GlobalFilterFreqTracking=pars->GlobalFilter->getfreqtracking(basefreq); - }; + AmpEnvelope = new Envelope(pars->AmpEnvelope, freq); + if(pars->PFreqEnvelopeEnabled != 0) + FreqEnvelope = new Envelope(pars->FreqEnvelope, freq); + else + FreqEnvelope = NULL; + if(pars->PBandWidthEnvelopeEnabled != 0) + BandWidthEnvelope = new Envelope(pars->BandWidthEnvelope, freq); + else + BandWidthEnvelope = NULL; + if(pars->PGlobalFilterEnabled != 0) { + globalfiltercenterq = pars->GlobalFilter->getq(); + GlobalFilterL = new Filter(pars->GlobalFilter); + if(stereo != 0) + GlobalFilterR = new Filter(pars->GlobalFilter); + GlobalFilterEnvelope = new Envelope(pars->GlobalFilterEnvelope, + freq); + GlobalFilterFreqTracking = pars->GlobalFilter->getfreqtracking(basefreq); + } computecurrentparameters(); -}; +} /* @@ -447,209 +519,249 @@ void SUBnote::initparameters(REALTYPE freq) */ void SUBnote::computecurrentparameters() { - if ((FreqEnvelope!=NULL)||(BandWidthEnvelope!=NULL)|| - (oldpitchwheel!=ctl->pitchwheel.data)|| - (oldbandwidth!=ctl->bandwidth.data)|| - (portamento!=0)) { - REALTYPE envfreq=1.0; - REALTYPE envbw=1.0; - REALTYPE gain=1.0; - - if (FreqEnvelope!=NULL) { - envfreq=FreqEnvelope->envout()/1200; - envfreq=pow(2.0,envfreq); - }; - envfreq*=ctl->pitchwheel.relfreq;//pitch wheel - if (portamento!=0) {//portamento is used - envfreq*=ctl->portamento.freqrap; - if (ctl->portamento.used==0) {//the portamento has finished - portamento=0;//this note is no longer "portamented" - }; - }; - - if (BandWidthEnvelope!=NULL) { - envbw=BandWidthEnvelope->envout(); - envbw=pow(2,envbw); - }; - envbw*=ctl->bandwidth.relbw;//bandwidth controller - - REALTYPE tmpgain=1.0/sqrt(envbw*envfreq); - - for (int n=0;n<numharmonics;n++) { - for (int nph=0;nph<numstages;nph++) { - if (nph==0) gain=tmpgain; - else gain=1.0; - computefiltercoefs( lfilter[nph+n*numstages], - lfilter[nph+n*numstages].freq*envfreq, - lfilter[nph+n*numstages].bw*envbw,gain); - }; - }; - if (stereo!=0) - for (int n=0;n<numharmonics;n++) { - for (int nph=0;nph<numstages;nph++) { - if (nph==0) gain=tmpgain; - else gain=1.0; - computefiltercoefs( rfilter[nph+n*numstages], - rfilter[nph+n*numstages].freq*envfreq, - rfilter[nph+n*numstages].bw*envbw,gain); - }; - }; - oldbandwidth=ctl->bandwidth.data; - oldpitchwheel=ctl->pitchwheel.data; - }; - newamplitude=volume*AmpEnvelope->envout_dB()*2.0; - - //Filter - if (GlobalFilterL!=NULL) { - REALTYPE globalfilterpitch=GlobalFilterCenterPitch+GlobalFilterEnvelope->envout(); - REALTYPE filterfreq=globalfilterpitch+ctl->filtercutoff.relfreq+GlobalFilterFreqTracking; - filterfreq=GlobalFilterL->getrealfreq(filterfreq); + if((FreqEnvelope != NULL) || (BandWidthEnvelope != NULL) + || (oldpitchwheel != ctl->pitchwheel.data) + || (oldbandwidth != ctl->bandwidth.data) + || (portamento != 0)) { + REALTYPE envfreq = 1.0; + REALTYPE envbw = 1.0; + REALTYPE gain = 1.0; + + if(FreqEnvelope != NULL) { + envfreq = FreqEnvelope->envout() / 1200; + envfreq = pow(2.0, envfreq); + } + envfreq *= ctl->pitchwheel.relfreq; //pitch wheel + if(portamento != 0) { //portamento is used + envfreq *= ctl->portamento.freqrap; + if(ctl->portamento.used == 0) //the portamento has finished + portamento = 0; //this note is no longer "portamented" + ; + } - GlobalFilterL->setfreq_and_q(filterfreq,globalfiltercenterq*ctl->filterq.relq); - if (GlobalFilterR!=NULL) GlobalFilterR->setfreq_and_q(filterfreq,globalfiltercenterq*ctl->filterq.relq); - }; + if(BandWidthEnvelope != NULL) { + envbw = BandWidthEnvelope->envout(); + envbw = pow(2, envbw); + } + envbw *= ctl->bandwidth.relbw; //bandwidth controller + + REALTYPE tmpgain = 1.0 / sqrt(envbw * envfreq); + + for(int n = 0; n < numharmonics; n++) { + for(int nph = 0; nph < numstages; nph++) { + if(nph == 0) + gain = tmpgain; + else + gain = 1.0; + computefiltercoefs(lfilter[nph + n * numstages], + lfilter[nph + n * numstages].freq * envfreq, + lfilter[nph + n * numstages].bw * envbw, + gain); + } + } + if(stereo != 0) + for(int n = 0; n < numharmonics; n++) { + for(int nph = 0; nph < numstages; nph++) { + if(nph == 0) + gain = tmpgain; + else + gain = 1.0; + computefiltercoefs( + rfilter[nph + n * numstages], + rfilter[nph + n + * numstages].freq * envfreq, + rfilter[nph + n * numstages].bw * envbw, + gain); + } + } + ; + oldbandwidth = ctl->bandwidth.data; + oldpitchwheel = ctl->pitchwheel.data; + } + newamplitude = volume * AmpEnvelope->envout_dB() * 2.0; -}; + //Filter + if(GlobalFilterL != NULL) { + REALTYPE globalfilterpitch = GlobalFilterCenterPitch + + GlobalFilterEnvelope->envout(); + REALTYPE filterfreq = globalfilterpitch + ctl->filtercutoff.relfreq + + GlobalFilterFreqTracking; + filterfreq = GlobalFilterL->getrealfreq(filterfreq); + + GlobalFilterL->setfreq_and_q(filterfreq, + globalfiltercenterq * ctl->filterq.relq); + if(GlobalFilterR != NULL) + GlobalFilterR->setfreq_and_q( + filterfreq, + globalfiltercenterq + * ctl->filterq.relq); + } +} /* * Note Output */ -int SUBnote::noteout(REALTYPE *outl,REALTYPE *outr) +int SUBnote::noteout(REALTYPE *outl, REALTYPE *outr) { int i; memcpy(outl, denormalkillbuf, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); memcpy(outr, denormalkillbuf, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); - if (NoteEnabled==OFF) return(0); + if(NoteEnabled == OFF) + return 0; //left channel - for (i=0;i<SOUND_BUFFER_SIZE;i++) tmprnd[i]=RND*2.0-1.0; - for (int n=0;n<numharmonics;n++) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmprnd[i] = RND * 2.0 - 1.0; + for(int n = 0; n < numharmonics; n++) { memcpy(tmpsmp, tmprnd, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); - for (int nph=0;nph<numstages;nph++) - filter(lfilter[nph+n*numstages],tmpsmp); - for (i=0;i<SOUND_BUFFER_SIZE;i++) outl[i]+=tmpsmp[i]; - }; + for(int nph = 0; nph < numstages; nph++) + filter(lfilter[nph + n * numstages], tmpsmp); + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + outl[i] += tmpsmp[i]; + } - if (GlobalFilterL!=NULL) GlobalFilterL->filterout(&outl[0]); + if(GlobalFilterL != NULL) + GlobalFilterL->filterout(&outl[0]); //right channel - if (stereo!=0) { - for (i=0;i<SOUND_BUFFER_SIZE;i++) tmprnd[i]=RND*2.0-1.0; - for (int n=0;n<numharmonics;n++) { + if(stereo != 0) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmprnd[i] = RND * 2.0 - 1.0; + for(int n = 0; n < numharmonics; n++) { memcpy(tmpsmp, tmprnd, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); - for (int nph=0;nph<numstages;nph++) - filter(rfilter[nph+n*numstages],tmpsmp); - for (i=0;i<SOUND_BUFFER_SIZE;i++) outr[i]+=tmpsmp[i]; - }; - if (GlobalFilterR!=NULL) GlobalFilterR->filterout(&outr[0]); - } else memcpy(outr, outl, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); - - if (firsttick!=0) { - int n=10; - if (n>SOUND_BUFFER_SIZE) n=SOUND_BUFFER_SIZE; - for (i=0;i<n;i++) { - REALTYPE ampfadein=0.5-0.5*cos((REALTYPE) i/(REALTYPE) n*PI); - outl[i]*=ampfadein; - outr[i]*=ampfadein; - }; - firsttick=0; - }; - - if (ABOVE_AMPLITUDE_THRESHOLD(oldamplitude,newamplitude)) { + for(int nph = 0; nph < numstages; nph++) + filter(rfilter[nph + n * numstages], tmpsmp); + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + outr[i] += tmpsmp[i]; + } + if(GlobalFilterR != NULL) + GlobalFilterR->filterout(&outr[0]); + } + else + memcpy(outr, outl, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); + + if(firsttick != 0) { + int n = 10; + if(n > SOUND_BUFFER_SIZE) + n = SOUND_BUFFER_SIZE; + for(i = 0; i < n; i++) { + REALTYPE ampfadein = 0.5 - 0.5 * cos( + (REALTYPE) i / (REALTYPE) n * PI); + outl[i] *= ampfadein; + outr[i] *= ampfadein; + } + firsttick = 0; + } + + if(ABOVE_AMPLITUDE_THRESHOLD(oldamplitude, newamplitude)) { // Amplitude interpolation - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - REALTYPE tmpvol=INTERPOLATE_AMPLITUDE(oldamplitude - ,newamplitude,i,SOUND_BUFFER_SIZE); - outl[i]*=tmpvol*panning; - outr[i]*=tmpvol*(1.0-panning); - }; - } else { - for (i=0;i<SOUND_BUFFER_SIZE;i++) { - outl[i]*=newamplitude*panning; - outr[i]*=newamplitude*(1.0-panning); - }; - }; - - oldamplitude=newamplitude; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + REALTYPE tmpvol = INTERPOLATE_AMPLITUDE(oldamplitude, + newamplitude, + i, + SOUND_BUFFER_SIZE); + outl[i] *= tmpvol * panning; + outr[i] *= tmpvol * (1.0 - panning); + } + } + else { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + outl[i] *= newamplitude * panning; + outr[i] *= newamplitude * (1.0 - panning); + } + } + + oldamplitude = newamplitude; computecurrentparameters(); // Apply legato-specific sound signal modifications - if (Legato.silent) { // Silencer - if (Legato.msg!=LM_FadeIn) { - memset(outl, 0, SOUND_BUFFER_SIZE* sizeof(REALTYPE)); - memset(outr, 0, SOUND_BUFFER_SIZE* sizeof(REALTYPE)); + if(Legato.silent) // Silencer + if(Legato.msg != LM_FadeIn) { + memset(outl, 0, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); + memset(outr, 0, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); } - } - switch (Legato.msg) { - case LM_CatchUp : // Continue the catch-up... - if (Legato.decounter==-10) Legato.decounter=Legato.fade.length; - for (i=0;i<SOUND_BUFFER_SIZE;i++) {//Yea, could be done without the loop... + switch(Legato.msg) { + case LM_CatchUp: // Continue the catch-up... + if(Legato.decounter == -10) + Legato.decounter = Legato.fade.length; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //Yea, could be done without the loop... Legato.decounter--; - if (Legato.decounter<1) { + if(Legato.decounter < 1) { // Catching-up done, we can finally set // the note to the actual parameters. - Legato.decounter=-10; - Legato.msg=LM_ToNorm; - SUBlegatonote(Legato.param.freq, Legato.param.vel, Legato.param.portamento, Legato.param.midinote, false); + Legato.decounter = -10; + Legato.msg = LM_ToNorm; + SUBlegatonote(Legato.param.freq, + Legato.param.vel, + Legato.param.portamento, + Legato.param.midinote, + false); break; } } break; - case LM_FadeIn : // Fade-in - if (Legato.decounter==-10) Legato.decounter=Legato.fade.length; - Legato.silent=false; - for (i=0;i<SOUND_BUFFER_SIZE;i++) { + case LM_FadeIn: // Fade-in + if(Legato.decounter == -10) + Legato.decounter = Legato.fade.length; + Legato.silent = false; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { Legato.decounter--; - if (Legato.decounter<1) { - Legato.decounter=-10; - Legato.msg=LM_Norm; + if(Legato.decounter < 1) { + Legato.decounter = -10; + Legato.msg = LM_Norm; break; } - Legato.fade.m+=Legato.fade.step; - outl[i]*=Legato.fade.m; - outr[i]*=Legato.fade.m; + Legato.fade.m += Legato.fade.step; + outl[i] *= Legato.fade.m; + outr[i] *= Legato.fade.m; } break; - case LM_FadeOut : // Fade-out, then set the catch-up - if (Legato.decounter==-10) Legato.decounter=Legato.fade.length; - for (i=0;i<SOUND_BUFFER_SIZE;i++) { + case LM_FadeOut: // Fade-out, then set the catch-up + if(Legato.decounter == -10) + Legato.decounter = Legato.fade.length; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { Legato.decounter--; - if (Legato.decounter<1) { - for (int j=i;j<SOUND_BUFFER_SIZE;j++) { - outl[j]=0.0; - outr[j]=0.0; + if(Legato.decounter < 1) { + for(int j = i; j < SOUND_BUFFER_SIZE; j++) { + outl[j] = 0.0; + outr[j] = 0.0; } - Legato.decounter=-10; - Legato.silent=true; + Legato.decounter = -10; + Legato.silent = true; // Fading-out done, now set the catch-up : - Legato.decounter=Legato.fade.length; - Legato.msg=LM_CatchUp; - REALTYPE catchupfreq=Legato.param.freq*(Legato.param.freq/Legato.lastfreq);//This freq should make this now silent note to catch-up (or should I say resync ?) with the heard note for the same length it stayed at the previous freq during the fadeout. - SUBlegatonote(catchupfreq, Legato.param.vel, Legato.param.portamento, Legato.param.midinote, false); + Legato.decounter = Legato.fade.length; + Legato.msg = LM_CatchUp; + REALTYPE catchupfreq = Legato.param.freq + * (Legato.param.freq / Legato.lastfreq); //This freq should make this now silent note to catch-up (or should I say resync ?) with the heard note for the same length it stayed at the previous freq during the fadeout. + SUBlegatonote(catchupfreq, + Legato.param.vel, + Legato.param.portamento, + Legato.param.midinote, + false); break; } - Legato.fade.m-=Legato.fade.step; - outl[i]*=Legato.fade.m; - outr[i]*=Legato.fade.m; + Legato.fade.m -= Legato.fade.step; + outl[i] *= Legato.fade.m; + outr[i] *= Legato.fade.m; } break; - default : + default: break; } // Check if the note needs to be computed more - if (AmpEnvelope->finished()!=0) { - for (i=0;i<SOUND_BUFFER_SIZE;i++) {//fade-out - REALTYPE tmp=1.0-(REALTYPE)i/(REALTYPE)SOUND_BUFFER_SIZE; - outl[i]*=tmp; - outr[i]*=tmp; - }; + if(AmpEnvelope->finished() != 0) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //fade-out + REALTYPE tmp = 1.0 - (REALTYPE)i / (REALTYPE)SOUND_BUFFER_SIZE; + outl[i] *= tmp; + outr[i] *= tmp; + } KillNote(); - }; - return(1); -}; + } + return 1; +} /* * Relase Key (Note Off) @@ -657,17 +769,22 @@ int SUBnote::noteout(REALTYPE *outl,REALTYPE *outr) void SUBnote::relasekey() { AmpEnvelope->relasekey(); - if (FreqEnvelope!=NULL) FreqEnvelope->relasekey(); - if (BandWidthEnvelope!=NULL) BandWidthEnvelope->relasekey(); - if (GlobalFilterEnvelope!=NULL) GlobalFilterEnvelope->relasekey(); -}; + if(FreqEnvelope != NULL) + FreqEnvelope->relasekey(); + if(BandWidthEnvelope != NULL) + BandWidthEnvelope->relasekey(); + if(GlobalFilterEnvelope != NULL) + GlobalFilterEnvelope->relasekey(); +} /* * Check if the note is finished */ int SUBnote::finished() { - if (NoteEnabled==OFF) return(1); - else return(0); -}; + if(NoteEnabled == OFF) + return 1; + else + return 0; +} diff --git a/src/Synth/SUBnote.h b/src/Synth/SUBnote.h @@ -31,84 +31,101 @@ class SUBnote { -public: - SUBnote(SUBnoteParameters *parameters,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote,bool besilent); - ~SUBnote(); - - void SUBlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool externcall); - - int noteout(REALTYPE *outl,REALTYPE *outr);//note output,return 0 if the note is finished - void relasekey(); - int finished(); - - int ready; //if I can get the sampledata - -private: - - void computecurrentparameters(); - void initparameters(REALTYPE freq); - void KillNote(); - - SUBnoteParameters *pars; - - //parameters - int stereo; - int numstages;//number of stages of filters - int numharmonics;//number of harmonics (after the too higher hamonics are removed) - int firstnumharmonics;//To keep track of the first note's numharmonics value, useful in legato mode. - int start;//how the harmonics start - REALTYPE basefreq; - REALTYPE panning; - Envelope *AmpEnvelope; - Envelope *FreqEnvelope; - Envelope *BandWidthEnvelope; - - Filter *GlobalFilterL,*GlobalFilterR; - - Envelope *GlobalFilterEnvelope; - - //internal values - ONOFFTYPE NoteEnabled; - int firsttick,portamento; - REALTYPE volume,oldamplitude,newamplitude; - - REALTYPE GlobalFilterCenterPitch;//octaves - REALTYPE GlobalFilterFreqTracking; - - struct bpfilter { - REALTYPE freq,bw,amp; //filter parameters - REALTYPE a1,a2,b0,b2;//filter coefs. b1=0 - REALTYPE xn1,xn2,yn1,yn2; //filter internal values - }; - - void initfilter(bpfilter &filter,REALTYPE freq,REALTYPE bw,REALTYPE amp,REALTYPE mag); - void computefiltercoefs(bpfilter &filter,REALTYPE freq,REALTYPE bw,REALTYPE gain); - inline void filter(bpfilter &filter,REALTYPE *smps); - - bpfilter *lfilter,*rfilter; - - REALTYPE *tmpsmp; - REALTYPE *tmprnd;//this is filled with random numbers - - Controller *ctl; - int oldpitchwheel,oldbandwidth; - REALTYPE globalfiltercenterq; - - // Legato vars - struct { - bool silent; - REALTYPE lastfreq; - LegatoMsg msg; - int decounter; - struct { // Fade In/Out vars - int length; - REALTYPE m, step; - } fade; - struct { // Note parameters - REALTYPE freq, vel; - int portamento, midinote; - } param; - } Legato; + public: + SUBnote(SUBnoteParameters *parameters, + Controller *ctl_, + REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote, + bool besilent); + ~SUBnote(); + + void SUBlegatonote(REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote, + bool externcall); + + int noteout(REALTYPE *outl, REALTYPE *outr); //note output,return 0 if the note is finished + void relasekey(); + int finished(); + + int ready; //if I can get the sampledata + + private: + + void computecurrentparameters(); + void initparameters(REALTYPE freq); + void KillNote(); + + SUBnoteParameters *pars; + + //parameters + int stereo; + int numstages; //number of stages of filters + int numharmonics; //number of harmonics (after the too higher hamonics are removed) + int firstnumharmonics; //To keep track of the first note's numharmonics value, useful in legato mode. + int start; //how the harmonics start + REALTYPE basefreq; + REALTYPE panning; + Envelope *AmpEnvelope; + Envelope *FreqEnvelope; + Envelope *BandWidthEnvelope; + + Filter *GlobalFilterL, *GlobalFilterR; + + Envelope *GlobalFilterEnvelope; + + //internal values + ONOFFTYPE NoteEnabled; + int firsttick, portamento; + REALTYPE volume, oldamplitude, newamplitude; + + REALTYPE GlobalFilterCenterPitch; //octaves + REALTYPE GlobalFilterFreqTracking; + + struct bpfilter { + REALTYPE freq, bw, amp; //filter parameters + REALTYPE a1, a2, b0, b2; //filter coefs. b1=0 + REALTYPE xn1, xn2, yn1, yn2; //filter internal values + }; + + void initfilter(bpfilter &filter, + REALTYPE freq, + REALTYPE bw, + REALTYPE amp, + REALTYPE mag); + void computefiltercoefs(bpfilter &filter, + REALTYPE freq, + REALTYPE bw, + REALTYPE gain); + inline void filter(bpfilter &filter, REALTYPE *smps); + + bpfilter *lfilter, *rfilter; + + REALTYPE *tmpsmp; + REALTYPE *tmprnd; //this is filled with random numbers + + Controller *ctl; + int oldpitchwheel, oldbandwidth; + REALTYPE globalfiltercenterq; + + // Legato vars + struct { + bool silent; + REALTYPE lastfreq; + LegatoMsg msg; + int decounter; + struct { // Fade In/Out vars + int length; + REALTYPE m, step; + } fade; + struct { // Note parameters + REALTYPE freq, vel; + int portamento, midinote; + } param; + } Legato; }; diff --git a/src/Tests/AdNoteTest.h b/src/Tests/AdNoteTest.h @@ -11,142 +11,147 @@ using namespace std; -class AdNoteTest : public CxxTest::TestSuite +class AdNoteTest:public CxxTest::TestSuite { -public: - - ADnote *note; - Master *master; - Controller *controller; - unsigned char testnote; - - - float *outR,*outL; - - void setUp() { - - //First the sensible settings and variables that have to be set: - SOUND_BUFFER_SIZE = 256; - - outL=new float[SOUND_BUFFER_SIZE]; - for (int i=0;i<SOUND_BUFFER_SIZE;++i) - *(outL+i)=0; - outR=new float[SOUND_BUFFER_SIZE]; - for (int i=0;i<SOUND_BUFFER_SIZE;++i) - *(outR+i)=0; - - //next the bad global variables that for some reason have not been properly placed in some - //initialization routine, but rather exist as cryptic oneliners in main.cpp: - denormalkillbuf= new REALTYPE[SOUND_BUFFER_SIZE]; - for (int i=0;i<SOUND_BUFFER_SIZE;i++) denormalkillbuf[i]=0; - - //phew, glad to get thouse out of my way. took me a lot of sweat and gdb to get this far... - - //prepare the default settings - ADnoteParameters *defaultPreset = new ADnoteParameters(new FFTwrapper(OSCIL_SIZE)); - XMLwrapper *wrap = new XMLwrapper(); - cout << string(SOURCE_DIR) + string("/Tests/guitar-adnote.xmz") << endl; - wrap->loadXMLfile(string(SOURCE_DIR) + string("/Tests/guitar-adnote.xmz")); - TS_ASSERT(wrap->enterbranch("MASTER")); - TS_ASSERT(wrap->enterbranch("PART", 0)); - TS_ASSERT(wrap->enterbranch("INSTRUMENT")); - TS_ASSERT(wrap->enterbranch("INSTRUMENT_KIT")); - TS_ASSERT(wrap->enterbranch("INSTRUMENT_KIT_ITEM", 0)); - TS_ASSERT(wrap->enterbranch("ADD_SYNTH_PARAMETERS")); - defaultPreset->getfromXML(wrap); - //defaultPreset->defaults(); - - - - controller = new Controller(); - - //lets go with.... 50! as a nice note - testnote = 50; - REALTYPE freq = 440.0*pow(2.0,(testnote-69.0)/12.0); - - note = new ADnote(defaultPreset, controller, freq, 120, 0, testnote, false); - - } - - void willNoteBeRunButIsHereForLinkingReasonsHowsThisForCamelCaseEh() - { - master = new Master(); - } + public: + + ADnote *note; + Master *master; + Controller *controller; + unsigned char testnote; + + + float *outR, *outL; + + void setUp() { + //First the sensible settings and variables that have to be set: + SOUND_BUFFER_SIZE = 256; + + outL = new float[SOUND_BUFFER_SIZE]; + for(int i = 0; i < SOUND_BUFFER_SIZE; ++i) + *(outL + i) = 0; + outR = new float[SOUND_BUFFER_SIZE]; + for(int i = 0; i < SOUND_BUFFER_SIZE; ++i) + *(outR + i) = 0; + + //next the bad global variables that for some reason have not been properly placed in some + //initialization routine, but rather exist as cryptic oneliners in main.cpp: + denormalkillbuf = new REALTYPE[SOUND_BUFFER_SIZE]; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) + denormalkillbuf[i] = 0; + + //phew, glad to get thouse out of my way. took me a lot of sweat and gdb to get this far... + + //prepare the default settings + ADnoteParameters *defaultPreset = new ADnoteParameters( + new FFTwrapper(OSCIL_SIZE)); + XMLwrapper *wrap = new XMLwrapper(); + cout << string(SOURCE_DIR) + string("/Tests/guitar-adnote.xmz") + << endl; + wrap->loadXMLfile(string(SOURCE_DIR) + + string("/Tests/guitar-adnote.xmz")); + TS_ASSERT(wrap->enterbranch("MASTER")); + TS_ASSERT(wrap->enterbranch("PART", 0)); + TS_ASSERT(wrap->enterbranch("INSTRUMENT")); + TS_ASSERT(wrap->enterbranch("INSTRUMENT_KIT")); + TS_ASSERT(wrap->enterbranch("INSTRUMENT_KIT_ITEM", 0)); + TS_ASSERT(wrap->enterbranch("ADD_SYNTH_PARAMETERS")); + defaultPreset->getfromXML(wrap); + //defaultPreset->defaults(); + + + + controller = new Controller(); + + //lets go with.... 50! as a nice note + testnote = 50; + REALTYPE freq = 440.0 * pow(2.0, (testnote - 69.0) / 12.0); + + note = new ADnote(defaultPreset, + controller, + freq, + 120, + 0, + testnote, + false); + } - void tearDown() { - delete note; - } + void willNoteBeRunButIsHereForLinkingReasonsHowsThisForCamelCaseEh() + { + master = new Master(); + } - void testDefaults() { + void tearDown() { + delete note; + } - TS_ASSERT(note->ready); - int sampleCount = 0; + void testDefaults() { + TS_ASSERT(note->ready); + int sampleCount = 0; //#define WRITE_OUTPUT #ifdef WRITE_OUTPUT - ofstream file("adnoteout", ios::out); + ofstream file("adnoteout", ios::out); #endif - note->noteout(outL, outR); + note->noteout(outL, outR); #ifdef WRITE_OUTPUT - for (int i = 0; i < SOUND_BUFFER_SIZE; ++i) { - file << outL[i] << std::endl; - } -#endif - sampleCount += SOUND_BUFFER_SIZE; + for(int i = 0; i < SOUND_BUFFER_SIZE; ++i) + file << outL[i] << std::endl; - TS_ASSERT_DELTA(outL[255], 0.3019, 0.0001); +#endif + sampleCount += SOUND_BUFFER_SIZE; - note->relasekey(); + TS_ASSERT_DELTA(outL[255], 0.3019, 0.0001); + note->relasekey(); - note->noteout(outL, outR); - sampleCount += SOUND_BUFFER_SIZE; - TS_ASSERT_DELTA(outL[255], -0.1382, 0.0001); - note->noteout(outL, outR); - sampleCount += SOUND_BUFFER_SIZE; - TS_ASSERT_DELTA(outL[255], -0.0334, 0.0001); + note->noteout(outL, outR); + sampleCount += SOUND_BUFFER_SIZE; + TS_ASSERT_DELTA(outL[255], -0.1382, 0.0001); - note->noteout(outL, outR); - sampleCount += SOUND_BUFFER_SIZE; - TS_ASSERT_DELTA(outL[255], -0.1329, 0.0001); + note->noteout(outL, outR); + sampleCount += SOUND_BUFFER_SIZE; + TS_ASSERT_DELTA(outL[255], -0.0334, 0.0001); - note->noteout(outL, outR); - sampleCount += SOUND_BUFFER_SIZE; - TS_ASSERT_DELTA(outL[255], 0.2690, 0.0001); + note->noteout(outL, outR); + sampleCount += SOUND_BUFFER_SIZE; + TS_ASSERT_DELTA(outL[255], -0.1329, 0.0001); - while (!note->finished()) { note->noteout(outL, outR); + sampleCount += SOUND_BUFFER_SIZE; + TS_ASSERT_DELTA(outL[255], 0.2690, 0.0001); + + while(!note->finished()) { + note->noteout(outL, outR); #ifdef WRITE_OUTPUT - for (int i = 0; i < SOUND_BUFFER_SIZE; ++i) { - file << outL[i] << std::endl; - } + for(int i = 0; i < SOUND_BUFFER_SIZE; ++i) + file << outL[i] << std::endl; + #endif - sampleCount += SOUND_BUFFER_SIZE; - } + sampleCount += SOUND_BUFFER_SIZE; + } #ifdef WRITE_OUTPUT - file.close(); + file.close(); #endif - TS_ASSERT_EQUALS(sampleCount, 9472); - - } + TS_ASSERT_EQUALS(sampleCount, 9472); + } #define OUTPUT_PROFILE #ifdef OUTPUT_PROFILE - void testSpeed() { + void testSpeed() { + const int samps = 15000; - const int samps = 15000; + int t_on = clock(); // timer before calling func + for(int i = 0; i < samps; ++i) + note->noteout(outL, outR); + int t_off = clock(); // timer when func returns - int t_on = clock(); // timer before calling func - for(int i=0; i<samps; ++i) - note->noteout(outL, outR); - int t_off = clock(); // timer when func returns - - printf ("AdNoteTest: %f seconds for %d Samples to be generated.\n", - (static_cast<float>(t_off - t_on))/CLOCKS_PER_SEC, samps); - } + printf("AdNoteTest: %f seconds for %d Samples to be generated.\n", + (static_cast<float>(t_off - t_on)) / CLOCKS_PER_SEC, samps); + } #endif }; diff --git a/src/Tests/ControllerTest.h b/src/Tests/ControllerTest.h @@ -23,51 +23,50 @@ #include <iostream> #include "../Params/Controller.h" -class ControllerTest : public CxxTest::TestSuite +class ControllerTest:public CxxTest::TestSuite { -public: - void setUp() { - testCtl=new Controller(); - } + public: + void setUp() { + testCtl = new Controller(); + } - void tearDown() { - delete testCtl; - } + void tearDown() { + delete testCtl; + } - void testPortamentoRange() { - //Initialize portamento - testCtl->setportamento(127); - testCtl->portamento.time=127; - testCtl->initportamento(40.0,400.0,false); - //Bounds Check - while(testCtl->portamento.used){ - TS_ASSERT((0.0<=testCtl->portamento.x)&& - (testCtl->portamento.x<=1.0)); - TS_ASSERT((0.1<=testCtl->portamento.freqrap)&& - (testCtl->portamento.freqrap<=1.0)); - testCtl->updateportamento(); + void testPortamentoRange() { + //Initialize portamento + testCtl->setportamento(127); + testCtl->portamento.time = 127; + testCtl->initportamento(40.0, 400.0, false); + //Bounds Check + while(testCtl->portamento.used) { + TS_ASSERT((0.0 <= testCtl->portamento.x) + && (testCtl->portamento.x <= 1.0)); + TS_ASSERT((0.1 <= testCtl->portamento.freqrap) + && (testCtl->portamento.freqrap <= 1.0)); + testCtl->updateportamento(); + } + TS_ASSERT((0.0 <= testCtl->portamento.x) + && (testCtl->portamento.x <= 1.0)); + TS_ASSERT((0.1 <= testCtl->portamento.freqrap) + && (testCtl->portamento.freqrap <= 1.0)); } - TS_ASSERT((0.0<=testCtl->portamento.x)&& - (testCtl->portamento.x<=1.0)); - TS_ASSERT((0.1<=testCtl->portamento.freqrap)&& - (testCtl->portamento.freqrap<=1.0)); - } - void testPortamentoValue() { - testCtl->setportamento(127); - testCtl->portamento.time=127; - testCtl->initportamento(40.0,400.0,false); - int i; - for(i=0;i<10;++i){ - testCtl->updateportamento(); + void testPortamentoValue() { + testCtl->setportamento(127); + testCtl->portamento.time = 127; + testCtl->initportamento(40.0, 400.0, false); + int i; + for(i = 0; i < 10; ++i) + testCtl->updateportamento(); + //Assert that the numbers are the same as they were at release + TS_ASSERT_DELTA(testCtl->portamento.x, 0.0290249, 0.000001) + TS_ASSERT_DELTA(testCtl->portamento.freqrap, 0.126122, 0.000001) } - //Assert that the numbers are the same as they were at release - TS_ASSERT_DELTA(testCtl->portamento.x,0.0290249,0.000001) - TS_ASSERT_DELTA(testCtl->portamento.freqrap,0.126122,0.000001) - } - -private: - Controller *testCtl; + private: + Controller *testCtl; }; + diff --git a/src/Tests/EchoTest.h b/src/Tests/EchoTest.h @@ -24,86 +24,86 @@ #include "../Effects/Echo.h" #include "../globals.h" //int SOUND_BUFFER_SIZE=256; -class EchoTest : public CxxTest::TestSuite +class EchoTest:public CxxTest::TestSuite { -public: - void setUp() { - outL=new float[SOUND_BUFFER_SIZE]; - for (int i=0;i<SOUND_BUFFER_SIZE;++i) - *(outL+i)=0; - outR=new float[SOUND_BUFFER_SIZE]; - for (int i=0;i<SOUND_BUFFER_SIZE;++i) - *(outR+i)=0; - input=new Stereo<AuSample>(SOUND_BUFFER_SIZE); - testFX=new Echo(true,outL,outR); - } + public: + void setUp() { + outL = new float[SOUND_BUFFER_SIZE]; + for(int i = 0; i < SOUND_BUFFER_SIZE; ++i) + *(outL + i) = 0; + outR = new float[SOUND_BUFFER_SIZE]; + for(int i = 0; i < SOUND_BUFFER_SIZE; ++i) + *(outR + i) = 0; + input = new Stereo<AuSample>(SOUND_BUFFER_SIZE); + testFX = new Echo(true, outL, outR); + } - void tearDown() { - delete input; - delete[] outL; - delete[] outR; - delete testFX; - } + void tearDown() { + delete input; + delete[] outL; + delete[] outR; + delete testFX; + } - void testInit() { - //Make sure that the output will be zero at start - //(given a zero input) - testFX->out(*input); - for (int i=0;i<SOUND_BUFFER_SIZE;++i){ - TS_ASSERT_DELTA(outL[i],0.0,0.0001); - TS_ASSERT_DELTA(outR[i],0.0,0.0001); + void testInit() { + //Make sure that the output will be zero at start + //(given a zero input) + testFX->out(*input); + for(int i = 0; i < SOUND_BUFFER_SIZE; ++i) { + TS_ASSERT_DELTA(outL[i], 0.0, 0.0001); + TS_ASSERT_DELTA(outR[i], 0.0, 0.0001); + } } - } - void testClear() { - char DELAY=2; - testFX->changepar(DELAY,127); - *input=Stereo<AuSample>(AuSample(SOUND_BUFFER_SIZE,1.0)); - for (int i=0;i<500;++i) + void testClear() { + char DELAY = 2; + testFX->changepar(DELAY, 127); + *input = Stereo<AuSample>(AuSample(SOUND_BUFFER_SIZE, 1.0)); + for(int i = 0; i < 500; ++i) + testFX->out(*input); + for(int i = 0; i < SOUND_BUFFER_SIZE; ++i) { + TS_ASSERT_DIFFERS(outL[i], 0.0); + TS_ASSERT_DIFFERS(outR[i], 0.0) + } + //After making sure the internal buffer has a nonzero value + //cleanup + //Then get the next output, which should be zereoed out if DELAY + //is large enough + testFX->cleanup(); testFX->out(*input); - for (int i=0;i<SOUND_BUFFER_SIZE;++i) { - TS_ASSERT_DIFFERS(outL[i],0.0); - TS_ASSERT_DIFFERS(outR[i],0.0) - } - //After making sure the internal buffer has a nonzero value - //cleanup - //Then get the next output, which should be zereoed out if DELAY - //is large enough - testFX->cleanup(); - testFX->out(*input); - for (int i=0;i<SOUND_BUFFER_SIZE;++i) { - TS_ASSERT_DELTA(outL[i],0.0,0.0001); - TS_ASSERT_DELTA(outR[i],0.0,0.0001); + for(int i = 0; i < SOUND_BUFFER_SIZE; ++i) { + TS_ASSERT_DELTA(outL[i], 0.0, 0.0001); + TS_ASSERT_DELTA(outR[i], 0.0, 0.0001); + } } - } - //Insures that the proper decay occurs with high feedback - void testDecaywFb() { - *input=Stereo<AuSample>(AuSample(SOUND_BUFFER_SIZE,1.0)); - char FEEDBACK=5; - testFX->changepar(FEEDBACK,127); - for (int i=0;i<100;++i) - testFX->out(*input); - for (int i=0;i<SOUND_BUFFER_SIZE;++i) { - TS_ASSERT_DIFFERS(outL[i],0.0); - TS_ASSERT_DIFFERS(outR[i],0.0) + //Insures that the proper decay occurs with high feedback + void testDecaywFb() { + *input = Stereo<AuSample>(AuSample(SOUND_BUFFER_SIZE, 1.0)); + char FEEDBACK = 5; + testFX->changepar(FEEDBACK, 127); + for(int i = 0; i < 100; ++i) + testFX->out(*input); + for(int i = 0; i < SOUND_BUFFER_SIZE; ++i) { + TS_ASSERT_DIFFERS(outL[i], 0.0); + TS_ASSERT_DIFFERS(outR[i], 0.0) + } + float amp = abs(outL[0] + outR[0]) / 2; + //reset input to zero + *input = Stereo<AuSample>(SOUND_BUFFER_SIZE); + //give the echo time to fade based upon zero input and high feedback + for(int i = 0; i < 50; ++i) + testFX->out(*input); + TS_ASSERT_LESS_THAN(abs(outL[0] + outR[0]) / 2, amp); } - float amp=abs(outL[0]+outR[0])/2; - //reset input to zero - *input=Stereo<AuSample>(SOUND_BUFFER_SIZE); - //give the echo time to fade based upon zero input and high feedback - for (int i=0;i<50;++i) - testFX->out(*input); - TS_ASSERT_LESS_THAN(abs(outL[0]+outR[0])/2, amp); - } -private: - Stereo<AuSample> *input; - float *outR,*outL; - Echo *testFX; - + private: + Stereo<AuSample> *input; + float *outR, *outL; + Echo *testFX; }; + diff --git a/src/Tests/MicrotonalTest.h b/src/Tests/MicrotonalTest.h @@ -28,113 +28,115 @@ using namespace std; -class MicrotonalTest : public CxxTest::TestSuite +class MicrotonalTest:public CxxTest::TestSuite { -public: - void setUp() { - testMicro=new Microtonal(); - } - - void tearDown() { - delete testMicro; - } - - //Verifies that the object is initialized correctly - void testinit() { - TS_ASSERT_EQUALS(testMicro->Pinvertupdown, 0 ); - TS_ASSERT_EQUALS(testMicro->Pinvertupdowncenter, 60 ); - TS_ASSERT_EQUALS(testMicro->getoctavesize(), 12 ); - TS_ASSERT_EQUALS(testMicro->Penabled, 0 ); - TS_ASSERT_EQUALS(testMicro->PAnote, 69 ); - TS_ASSERT_EQUALS(testMicro->PAfreq, 440.0); - TS_ASSERT_EQUALS(testMicro->Pscaleshift, 64 ); - TS_ASSERT_EQUALS(testMicro->Pfirstkey, 0 ); - TS_ASSERT_EQUALS(testMicro->Plastkey, 127 ); - TS_ASSERT_EQUALS(testMicro->Pmiddlenote, 60 ); - TS_ASSERT_EQUALS(testMicro->Pmapsize, 12 ); - TS_ASSERT_EQUALS(testMicro->Pmappingenabled, 0 ); - TS_ASSERT_EQUALS(testMicro->Pglobalfinedetune, 64 ); - - TS_ASSERT_EQUALS(string((const char *)testMicro->Pname),"12tET"); - TS_ASSERT_EQUALS(string((const char *)testMicro->Pcomment),"Equal Temperament 12 notes per octave"); - - for (int i=0;i<128;i++) - TS_ASSERT_EQUALS(testMicro->Pmapping[i], i); - - TS_ASSERT_DELTA(testMicro->getnotefreq(19,0),24.4997,0.0001); - } - - //performs basic sanity check with the == and != operators - void testeqeq(){ - Microtonal other; - TS_ASSERT(*testMicro==other);//both are constructed the same, so they should be equal - other.PAfreq=220.0; - TS_ASSERT(*testMicro!=other);//other is now different - } - - //Tests saving/loading to XML - void testXML() { - //Gah, the XMLwrapper is a twisted maze - testMicro->Penabled=1; - XMLwrapper xml; - xml.beginbranch("Dummy"); //this should not be needed, but odd behavior - //seems to exist from MICROTONAL being on the - //top of the stack - xml.beginbranch("MICROTONAL"); - testMicro->add2XML(&xml); - xml.endbranch(); - xml.endbranch(); - - char *tmp = xml.getXMLdata(); - Microtonal other; - - other.Penabled=1; - strcpy((char *)other.Pname,"Myname");//will be nicer with strings - - TS_ASSERT(*testMicro!=other);//sanity check - - TS_ASSERT(xml.enterbranch("Dummy")); - TS_ASSERT(xml.enterbranch("MICROTONAL")); - - other.getfromXML(&xml); - xml.exitbranch(); - xml.exitbranch(); - char *tmpo=xml.getXMLdata(); - - TS_ASSERT(!strcmp(tmp,tmpo)); - free(tmp); - free(tmpo); - - TS_ASSERT(*testMicro==other); //cxxTest sees error here - } - - /**\todo Test Saving/loading from file*/ - //void testSaveLoad() {} - - //Test texttomapping TODO finish - void testTextToMapping() { - //the mapping is from old documentation for "Intense Diatonic" scale - const char *mapping[12]= - {"0","x","1","x","2","3","x","4","x","5","x","6"}; - //for(int i=0;i<20;++i) - // cout << i << ':' << testMicro->getnotefreq(i,0) << endl; - // - // octave size == 7 - // find dead notes - } - //Test texttotunings TODO finish - void testTextToTunings() { - //the tuning is from old documentation for "Intense Diatonic" scale - const char *tuning[7]={"9/8","5/4","4/3","3/2","5/3","15/8","2/1"}; - const int numTunings=7; - //for(int i=0;i<20;++i) - // cout << i << ':' << testMicro->getnotefreq(i,0) << endl; - // go to middle key and verify the proportions - - } - /**\TODO test loading from scl and kbm files*/ - -private: - Microtonal *testMicro; - + public: + void setUp() { + testMicro = new Microtonal(); + } + + void tearDown() { + delete testMicro; + } + + //Verifies that the object is initialized correctly + void testinit() { + TS_ASSERT_EQUALS(testMicro->Pinvertupdown, 0); + TS_ASSERT_EQUALS(testMicro->Pinvertupdowncenter, 60); + TS_ASSERT_EQUALS(testMicro->getoctavesize(), 12); + TS_ASSERT_EQUALS(testMicro->Penabled, 0); + TS_ASSERT_EQUALS(testMicro->PAnote, 69); + TS_ASSERT_EQUALS(testMicro->PAfreq, 440.0); + TS_ASSERT_EQUALS(testMicro->Pscaleshift, 64); + TS_ASSERT_EQUALS(testMicro->Pfirstkey, 0); + TS_ASSERT_EQUALS(testMicro->Plastkey, 127); + TS_ASSERT_EQUALS(testMicro->Pmiddlenote, 60); + TS_ASSERT_EQUALS(testMicro->Pmapsize, 12); + TS_ASSERT_EQUALS(testMicro->Pmappingenabled, 0); + TS_ASSERT_EQUALS(testMicro->Pglobalfinedetune, 64); + + TS_ASSERT_EQUALS(string((const char *)testMicro->Pname), "12tET"); + TS_ASSERT_EQUALS(string( + (const char *)testMicro->Pcomment), + "Equal Temperament 12 notes per octave"); + + for(int i = 0; i < 128; i++) + TS_ASSERT_EQUALS(testMicro->Pmapping[i], i); + + TS_ASSERT_DELTA(testMicro->getnotefreq(19, 0), 24.4997, 0.0001); + } + + //performs basic sanity check with the == and != operators + void testeqeq() { + Microtonal other; + TS_ASSERT(*testMicro == other); //both are constructed the same, so they should be equal + other.PAfreq = 220.0; + TS_ASSERT(*testMicro != other); //other is now different + } + + //Tests saving/loading to XML + void testXML() { + //Gah, the XMLwrapper is a twisted maze + testMicro->Penabled = 1; + XMLwrapper xml; + xml.beginbranch("Dummy"); //this should not be needed, but odd behavior + //seems to exist from MICROTONAL being on the + //top of the stack + xml.beginbranch("MICROTONAL"); + testMicro->add2XML(&xml); + xml.endbranch(); + xml.endbranch(); + + char *tmp = xml.getXMLdata(); + Microtonal other; + + other.Penabled = 1; + strcpy((char *)other.Pname, "Myname"); //will be nicer with strings + + TS_ASSERT(*testMicro != other); //sanity check + + TS_ASSERT(xml.enterbranch("Dummy")); + TS_ASSERT(xml.enterbranch("MICROTONAL")); + + other.getfromXML(&xml); + xml.exitbranch(); + xml.exitbranch(); + char *tmpo = xml.getXMLdata(); + + TS_ASSERT(!strcmp(tmp, tmpo)); + free(tmp); + free(tmpo); + + TS_ASSERT(*testMicro == other); //cxxTest sees error here + } + + /**\todo Test Saving/loading from file*/ + //void testSaveLoad() {} + + //Test texttomapping TODO finish + void testTextToMapping() { + //the mapping is from old documentation for "Intense Diatonic" scale + const char *mapping[12] = + {"0", "x", "1", "x", "2", "3", "x", "4", "x", "5", "x", "6"}; + //for(int i=0;i<20;++i) + // cout << i << ':' << testMicro->getnotefreq(i,0) << endl; + // + // octave size == 7 + // find dead notes + } + //Test texttotunings TODO finish + void testTextToTunings() { + //the tuning is from old documentation for "Intense Diatonic" scale + const char *tuning[7] = + {"9/8", "5/4", "4/3", "3/2", "5/3", "15/8", "2/1"}; + const int numTunings = 7; + //for(int i=0;i<20;++i) + // cout << i << ':' << testMicro->getnotefreq(i,0) << endl; + // go to middle key and verify the proportions + } + /**\TODO test loading from scl and kbm files*/ + + private: + Microtonal *testMicro; }; + diff --git a/src/Tests/SampleTest.h b/src/Tests/SampleTest.h @@ -22,54 +22,54 @@ #include <cxxtest/TestSuite.h> #include "../Samples/AuSample.h" -class SampleTest : public CxxTest::TestSuite +class SampleTest:public CxxTest::TestSuite { -public: - void testInit() { - AuSample smp(10); - TS_ASSERT_EQUALS(smp.size(),10); - for (int i=0;i<20;++i) - TS_ASSERT_EQUALS(smp[i],0.0); - AuSample nsmp(5,15.0); - TS_ASSERT_EQUALS(nsmp.size(),5); - TS_ASSERT_EQUALS(nsmp[4],15.0); - } + public: + void testInit() { + AuSample smp(10); + TS_ASSERT_EQUALS(smp.size(), 10); + for(int i = 0; i < 20; ++i) + TS_ASSERT_EQUALS(smp[i], 0.0); + AuSample nsmp(5, 15.0); + TS_ASSERT_EQUALS(nsmp.size(), 5); + TS_ASSERT_EQUALS(nsmp[4], 15.0); + } - void testAssign() { - AuSample smp(3); - smp[0]=0; - smp[1]=1; - smp[2]=2; - AuSample nsmp(40); - nsmp=smp; - TS_ASSERT_EQUALS(smp.size(),nsmp.size()); - for (int i=0;i<29;++i) - TS_ASSERT_EQUALS(smp[i],nsmp[i]); - } - void testBounds() { - AuSample smp(0); - TS_ASSERT(smp.size()!=0); - } + void testAssign() { + AuSample smp(3); + smp[0] = 0; + smp[1] = 1; + smp[2] = 2; + AuSample nsmp(40); + nsmp = smp; + TS_ASSERT_EQUALS(smp.size(), nsmp.size()); + for(int i = 0; i < 29; ++i) + TS_ASSERT_EQUALS(smp[i], nsmp[i]); + } + void testBounds() { + AuSample smp(0); + TS_ASSERT(smp.size() != 0); + } - void testAllocDealloc() { - float * fl=new float[50]; - for (int i=0;i<50;++i) - *(fl+i)=i; - AuSample smp(2); - smp = AuSample(50,fl); - delete [] fl; - for (int i=0;i<50;++i) - TS_ASSERT_DELTA(smp[i],i,0.001); - smp = AuSample(3); - } - - void testClear() { - AuSample smp(50); - for (int i=0;i<50;++i) - smp[i]=10; - smp.clear(); - for (int i=0;i<50;++i) - TS_ASSERT_EQUALS(smp[i],0); - } + void testAllocDealloc() { + float *fl = new float[50]; + for(int i = 0; i < 50; ++i) + *(fl + i) = i; + AuSample smp(2); + smp = AuSample(50, fl); + delete [] fl; + for(int i = 0; i < 50; ++i) + TS_ASSERT_DELTA(smp[i], i, 0.001); + smp = AuSample(3); + } + void testClear() { + AuSample smp(50); + for(int i = 0; i < 50; ++i) + smp[i] = 10; + smp.clear(); + for(int i = 0; i < 50; ++i) + TS_ASSERT_EQUALS(smp[i], 0); + } }; + diff --git a/src/Tests/SubNoteTest.h b/src/Tests/SubNoteTest.h @@ -12,139 +12,143 @@ using namespace std; -class SubNoteTest : public CxxTest::TestSuite +class SubNoteTest:public CxxTest::TestSuite { -public: - - SUBnote *note; - Master *master; - Controller *controller; - unsigned char testnote; - - - float *outR,*outL; - - void setUp() { - - //First the sensible settings and variables that have to be set: - SOUND_BUFFER_SIZE = 256; - - outL=new float[SOUND_BUFFER_SIZE]; - for (int i=0;i<SOUND_BUFFER_SIZE;++i) - *(outL+i)=0; - outR=new float[SOUND_BUFFER_SIZE]; - for (int i=0;i<SOUND_BUFFER_SIZE;++i) - *(outR+i)=0; - - //next the bad global variables that for some reason have not been properly placed in some - //initialization routine, but rather exist as cryptic oneliners in main.cpp: - denormalkillbuf= new REALTYPE[SOUND_BUFFER_SIZE]; - for (int i=0;i<SOUND_BUFFER_SIZE;i++) denormalkillbuf[i]=0; - - //prepare the default settings - SUBnoteParameters *defaultPreset = new SUBnoteParameters(); - XMLwrapper *wrap = new XMLwrapper(); - wrap->loadXMLfile(string(SOURCE_DIR) + string("/Tests/guitar-adnote.xmz")); - TS_ASSERT(wrap->enterbranch("MASTER")); - TS_ASSERT(wrap->enterbranch("PART", 1)); - TS_ASSERT(wrap->enterbranch("INSTRUMENT")); - TS_ASSERT(wrap->enterbranch("INSTRUMENT_KIT")); - TS_ASSERT(wrap->enterbranch("INSTRUMENT_KIT_ITEM", 0)); - TS_ASSERT(wrap->enterbranch("SUB_SYNTH_PARAMETERS")); - defaultPreset->getfromXML(wrap); - //defaultPreset->defaults(); - - controller = new Controller(); - - //lets go with.... 50! as a nice note - testnote = 50; - REALTYPE freq = 440.0*pow(2.0,(testnote-69.0)/12.0); - - note = new SUBnote(defaultPreset, controller, freq, 120, 0, testnote, false); - - } + public: + + SUBnote *note; + Master *master; + Controller *controller; + unsigned char testnote; + + + float *outR, *outL; + + void setUp() { + //First the sensible settings and variables that have to be set: + SOUND_BUFFER_SIZE = 256; + + outL = new float[SOUND_BUFFER_SIZE]; + for(int i = 0; i < SOUND_BUFFER_SIZE; ++i) + *(outL + i) = 0; + outR = new float[SOUND_BUFFER_SIZE]; + for(int i = 0; i < SOUND_BUFFER_SIZE; ++i) + *(outR + i) = 0; + + //next the bad global variables that for some reason have not been properly placed in some + //initialization routine, but rather exist as cryptic oneliners in main.cpp: + denormalkillbuf = new REALTYPE[SOUND_BUFFER_SIZE]; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) + denormalkillbuf[i] = 0; + + //prepare the default settings + SUBnoteParameters *defaultPreset = new SUBnoteParameters(); + XMLwrapper *wrap = new XMLwrapper(); + wrap->loadXMLfile(string(SOURCE_DIR) + + string("/Tests/guitar-adnote.xmz")); + TS_ASSERT(wrap->enterbranch("MASTER")); + TS_ASSERT(wrap->enterbranch("PART", 1)); + TS_ASSERT(wrap->enterbranch("INSTRUMENT")); + TS_ASSERT(wrap->enterbranch("INSTRUMENT_KIT")); + TS_ASSERT(wrap->enterbranch("INSTRUMENT_KIT_ITEM", 0)); + TS_ASSERT(wrap->enterbranch("SUB_SYNTH_PARAMETERS")); + defaultPreset->getfromXML(wrap); + //defaultPreset->defaults(); + + controller = new Controller(); + + //lets go with.... 50! as a nice note + testnote = 50; + REALTYPE freq = 440.0 * pow(2.0, (testnote - 69.0) / 12.0); + + note = new SUBnote(defaultPreset, + controller, + freq, + 120, + 0, + testnote, + false); + } - void willNoteBeRunButIsHereForLinkingReasonsHowsThisForCamelCaseEh() - { - master = new Master(); - } + void willNoteBeRunButIsHereForLinkingReasonsHowsThisForCamelCaseEh() + { + master = new Master(); + } - void tearDown() { - delete note; - } + void tearDown() { + delete note; + } - void testDefaults() { - //Note: if these tests fail it is due to the relationship between - //global.h::RND and SUBnote.cpp + void testDefaults() { + //Note: if these tests fail it is due to the relationship between + //global.h::RND and SUBnote.cpp - TS_ASSERT(note->ready); - int sampleCount = 0; + TS_ASSERT(note->ready); + int sampleCount = 0; //#define WRITE_OUTPUT #ifdef WRITE_OUTPUT - ofstream file("subnoteout", ios::out); + ofstream file("subnoteout", ios::out); #endif - note->noteout(outL, outR); + note->noteout(outL, outR); #ifdef WRITE_OUTPUT - for (int i = 0; i < SOUND_BUFFER_SIZE; ++i) { - file << outL[i] << std::endl; - } -#endif - sampleCount += SOUND_BUFFER_SIZE; + for(int i = 0; i < SOUND_BUFFER_SIZE; ++i) + file << outL[i] << std::endl; - TS_ASSERT_DELTA(outL[255], 0.0000, 0.0001); +#endif + sampleCount += SOUND_BUFFER_SIZE; - note->relasekey(); + TS_ASSERT_DELTA(outL[255], 0.0000, 0.0001); + note->relasekey(); - note->noteout(outL, outR); - sampleCount += SOUND_BUFFER_SIZE; - TS_ASSERT_DELTA(outL[255], 0.0022, 0.0001); - note->noteout(outL, outR); - sampleCount += SOUND_BUFFER_SIZE; - TS_ASSERT_DELTA(outL[255], -0.0020, 0.0001); + note->noteout(outL, outR); + sampleCount += SOUND_BUFFER_SIZE; + TS_ASSERT_DELTA(outL[255], 0.0022, 0.0001); - note->noteout(outL, outR); - sampleCount += SOUND_BUFFER_SIZE; - TS_ASSERT_DELTA(outL[255], 0.0010, 0.0001); + note->noteout(outL, outR); + sampleCount += SOUND_BUFFER_SIZE; + TS_ASSERT_DELTA(outL[255], -0.0020, 0.0001); - note->noteout(outL, outR); - sampleCount += SOUND_BUFFER_SIZE; - TS_ASSERT_DELTA(outL[255], 0.0005, 0.0001); + note->noteout(outL, outR); + sampleCount += SOUND_BUFFER_SIZE; + TS_ASSERT_DELTA(outL[255], 0.0010, 0.0001); - while (!note->finished()) { note->noteout(outL, outR); + sampleCount += SOUND_BUFFER_SIZE; + TS_ASSERT_DELTA(outL[255], 0.0005, 0.0001); + + while(!note->finished()) { + note->noteout(outL, outR); #ifdef WRITE_OUTPUT - for (int i = 0; i < SOUND_BUFFER_SIZE; ++i) { - file << outL[i] << std::endl; - } + for(int i = 0; i < SOUND_BUFFER_SIZE; ++i) + file << outL[i] << std::endl; + #endif - sampleCount += SOUND_BUFFER_SIZE; - } + sampleCount += SOUND_BUFFER_SIZE; + } #ifdef WRITE_OUTPUT - file.close(); + file.close(); #endif - TS_ASSERT_EQUALS(sampleCount, 2304); - - } + TS_ASSERT_EQUALS(sampleCount, 2304); + } #define OUTPUT_PROFILE #ifdef OUTPUT_PROFILE - void testSpeed() { + void testSpeed() { + const int samps = 15000; - const int samps = 15000; + int t_on = clock(); // timer before calling func + for(int i = 0; i < samps; ++i) + note->noteout(outL, outR); + int t_off = clock(); // timer when func returns - int t_on = clock(); // timer before calling func - for(int i=0; i<samps; ++i) - note->noteout(outL, outR); - int t_off = clock(); // timer when func returns - - printf ("SubNoteTest: %f seconds for %d Samples to be generated.\n", - (static_cast<float>(t_off - t_on))/CLOCKS_PER_SEC, samps); - } + printf("SubNoteTest: %f seconds for %d Samples to be generated.\n", + (static_cast<float>(t_off - t_on)) / CLOCKS_PER_SEC, samps); + } #endif }; diff --git a/src/Tests/XMLwrapperTest.h b/src/Tests/XMLwrapperTest.h @@ -22,27 +22,27 @@ #include <cxxtest/TestSuite.h> #include "../Misc/XMLwrapper.h" -class XMLwrapperTest : public CxxTest::TestSuite +class XMLwrapperTest:public CxxTest::TestSuite { -public: - void setUp() { - xmla = new XMLwrapper; - xmlb = new XMLwrapper; - } + public: + void setUp() { + xmla = new XMLwrapper; + xmlb = new XMLwrapper; + } - void testAddPar() { - xmla->addpar("my Pa*_ramet@er",75); - TS_ASSERT_EQUALS(xmla->getpar("my Pa*_ramet@er",0,-200,200),75); - } - - void tearDown() { - delete xmla; - delete xmlb; - } + void testAddPar() { + xmla->addpar("my Pa*_ramet@er", 75); + TS_ASSERT_EQUALS(xmla->getpar("my Pa*_ramet@er", 0, -200, 200), 75); + } + void tearDown() { + delete xmla; + delete xmlb; + } -private: + + private: XMLwrapper *xmla; XMLwrapper *xmlb; }; diff --git a/src/globals.h b/src/globals.h @@ -29,10 +29,10 @@ #define REALTYPE float struct FFTFREQS { - REALTYPE *s,*c;//sine and cosine components + REALTYPE *s, *c; //sine and cosine components }; -extern void newFFTFREQS(FFTFREQS *f,int size); +extern void newFFTFREQS(FFTFREQS *f, int size); extern void deleteFFTFREQS(FFTFREQS *f); /**Sampling rate*/ @@ -131,7 +131,7 @@ extern int OSCIL_SIZE; * The maximum number of bands of the equaliser */ #define MAX_EQ_BANDS 8 -#if (MAX_EQ_BANDS>=20) +#if (MAX_EQ_BANDS >= 20) #error "Too many EQ bands in globals.h" #endif @@ -162,47 +162,67 @@ extern int OSCIL_SIZE; /* * How the amplitude threshold is computed */ -#define ABOVE_AMPLITUDE_THRESHOLD(a,b) ( ( 2.0*fabs( (b) - (a) ) / \ - ( fabs( (b) + (a) + 0.0000000001) ) ) > AMPLITUDE_INTERPOLATION_THRESHOLD ) +#define ABOVE_AMPLITUDE_THRESHOLD(a, b) ((2.0 * fabs((b) - (a)) \ + / (fabs((b) + (a) + 0.0000000001))) > \ + AMPLITUDE_INTERPOLATION_THRESHOLD) /* * Interpolate Amplitude */ -#define INTERPOLATE_AMPLITUDE(a,b,x,size) ( (a) + \ - ( (b) - (a) ) * (REALTYPE)(x) / (REALTYPE) (size) ) +#define INTERPOLATE_AMPLITUDE(a, b, x, size) ((a) \ + + ((b) \ + - (a)) * (REALTYPE)(x) \ + / (REALTYPE) (size)) /* * dB */ -#define dB2rap(dB) ((exp((dB)*LOG_10/20.0))) -#define rap2dB(rap) ((20*log(rap)/LOG_10)) +#define dB2rap(dB) ((exp((dB) * LOG_10 / 20.0))) +#define rap2dB(rap) ((20 * log(rap) / LOG_10)) /* * The random generator (0.0..1.0) */ -#define RND (rand()/(RAND_MAX+1.0)) +#define RND (rand() / (RAND_MAX + 1.0)) -#define ZERO(data,size) {char *data_=(char *) data;for (int i=0;i<size;i++) data_[i]=0;}; -#define ZERO_REALTYPE(data,size) {REALTYPE *data_=(REALTYPE *) data;for (int i=0;i<size;i++) data_[i]=0.0;}; +#define ZERO(data, size) {char *data_ = (char *) data; for(int i = 0; \ + i < size; \ + i++) \ + data_[i] = 0;} +#define ZERO_REALTYPE(data, size) {REALTYPE *data_ = (REALTYPE *) data; \ + for(int i = 0; \ + i < size; \ + i++) \ + data_[i] = 0.0;} -enum ONOFFTYPE {OFF=0,ON=1}; +enum ONOFFTYPE { + OFF = 0, ON = 1 +}; -enum MidiControllers {C_NULL=0,C_pitchwheel=1000,C_expression=11,C_panning=10, - C_filtercutoff=74,C_filterq=71,C_bandwidth=75,C_modwheel=1,C_fmamp=76, - C_volume=7,C_sustain=64,C_allnotesoff=123,C_allsoundsoff=120,C_resetallcontrollers=121, - C_portamento=65,C_resonance_center=77,C_resonance_bandwidth=78, +enum MidiControllers { + C_NULL = 0, C_pitchwheel = 1000, C_expression = 11, C_panning = 10, + C_filtercutoff = 74, C_filterq = 71, C_bandwidth = 75, C_modwheel = 1, + C_fmamp = 76, + C_volume = 7, C_sustain = 64, C_allnotesoff = 123, C_allsoundsoff = 120, + C_resetallcontrollers = 121, + C_portamento = 65, C_resonance_center = 77, C_resonance_bandwidth = 78, - C_dataentryhi=0x06,C_dataentrylo=0x26,C_nrpnhi=99,C_nrpnlo=98 - }; + C_dataentryhi = 0x06, C_dataentrylo = 0x26, C_nrpnhi = 99, C_nrpnlo = 98 +}; -enum LegatoMsg {LM_Norm, LM_FadeIn, LM_FadeOut, LM_CatchUp, LM_ToNorm}; +enum LegatoMsg { + LM_Norm, LM_FadeIn, LM_FadeOut, LM_CatchUp, LM_ToNorm +}; //is like i=(int)(floor(f)) #ifdef ASM_F2I_YES -#define F2I(f,i) __asm__ __volatile__ ("fistpl %0" : "=m" (i) : "t" (f-0.49999999) : "st") ; +#define F2I(f, \ + i) __asm__ __volatile__ ("fistpl %0" : "=m" (i) : "t" (f \ + - 0.49999999) \ + : "st"); #else -#define F2I(f,i) (i)=((f>0) ? ( (int)(f) ) :( (int)(f-1.0) )); +#define F2I(f, i) (i) = ((f > 0) ? ((int)(f)) : ((int)(f - 1.0))); #endif diff --git a/src/main.cpp b/src/main.cpp @@ -20,7 +20,7 @@ */ -#include <stdio.h>//remove once iostream is used +#include <stdio.h> //remove once iostream is used #include <iostream> #include <unistd.h> @@ -46,7 +46,7 @@ extern Dump dump; #include "Input/OSSMidiIn.h" #endif -#if (defined(NONEMIDIIN)||defined(VSTMIDIIN)) +#if (defined(NONEMIDIIN) || defined(VSTMIDIIN)) #include "Input/NULLMidiIn.h" #endif @@ -72,10 +72,10 @@ MasterUI *ui; using namespace std; -pthread_t thr1,thr2,thr3,thr4; -Master *master; -int swaplr=0;//1 for left-right swapping -bool usejackit=false; +pthread_t thr1, thr2, thr3, thr4; +Master *master; +int swaplr = 0; //1 for left-right swapping +bool usejackit = false; #ifdef JACKAUDIOOUT #include "Output/JACKaudiooutput.h" @@ -100,7 +100,7 @@ LASHClient *lash; #endif MidiIn *Midi; -int Pexitprogram=0;//if the UI set this to 1, the program will exit +int Pexitprogram = 0; //if the UI set this to 1, the program will exit /* * Try to get the realtime priority @@ -110,43 +110,46 @@ void set_realtime() #ifdef OS_LINUX sched_param sc; - sc.sched_priority=50; + sc.sched_priority = 50; //if you want get "sched_setscheduler undeclared" from compilation, you can safely remove the folowing line - sched_setscheduler(0,SCHED_FIFO,&sc); + sched_setscheduler(0, SCHED_FIFO, &sc); // if (err==0) printf("Real-time"); #endif -}; +} /* * Midi input thread */ -#if !(defined(WINMIDIIN)||defined(VSTMIDIIN)) +#if !(defined(WINMIDIIN) || defined(VSTMIDIIN)) void *thread1(void *arg) { - MidiCmdType cmdtype=MidiNoteOFF; - unsigned char cmdchan=0,note=0,vel=0; + MidiCmdType cmdtype = MidiNoteOFF; + unsigned char cmdchan = 0, note = 0, vel = 0; int cmdparams[MP_MAX_BYTES]; - for (int i=0;i<MP_MAX_BYTES;++i) - cmdparams[i]=0; + for(int i = 0; i < MP_MAX_BYTES; ++i) + cmdparams[i] = 0; set_realtime(); - while (Pexitprogram==0) { - Midi->getmidicmd(cmdtype,cmdchan,cmdparams); - note=cmdparams[0]; - vel=cmdparams[1]; + while(Pexitprogram == 0) { + Midi->getmidicmd(cmdtype, cmdchan, cmdparams); + note = cmdparams[0]; + vel = cmdparams[1]; pthread_mutex_lock(&master->mutex); - if ((cmdtype==MidiNoteON)&&(note!=0)) master->NoteOn(cmdchan,note,vel); - if ((cmdtype==MidiNoteOFF)&&(note!=0)) master->NoteOff(cmdchan,note); - if (cmdtype==MidiController) master->SetController(cmdchan,cmdparams[0],cmdparams[1]); + if((cmdtype == MidiNoteON) && (note != 0)) + master->NoteOn(cmdchan, note, vel); + if((cmdtype == MidiNoteOFF) && (note != 0)) + master->NoteOff(cmdchan, note); + if(cmdtype == MidiController) + master->SetController(cmdchan, cmdparams[0], cmdparams[1]); pthread_mutex_unlock(&master->mutex); - }; + } - return(0); -}; + return 0; +} #endif /* @@ -161,36 +164,36 @@ void *thread2(void *arg) REALTYPE outputr[SOUND_BUFFER_SIZE]; set_realtime(); - while (Pexitprogram==0) { + while(Pexitprogram == 0) { pthread_mutex_lock(&master->mutex); - master->AudioOut(outputl,outputr); + master->AudioOut(outputl, outputr); pthread_mutex_unlock(&master->mutex); #ifndef NONEAUDIOOUT - audioout->OSSout(outputl,outputr); -#endif - - /** / int i,x,x2; - REALTYPE xx,xx2; - - short int xsmps[SOUND_BUFFER_SIZE*2]; - for (i=0;i<SOUND_BUFFER_SIZE;i++){//output to stdout - xx=-outputl[i]*32767; - xx2=-outputr[i]*32767; - if (xx<-32768) xx=-32768; - if (xx>32767) xx=32767; - if (xx2<-32768) xx2=-32768; - if (xx2>32767) xx2=32767; - x=(short int) xx; - x2=(short int) xx2; - xsmps[i*2]=x;xsmps[i*2+1]=x2; - }; - write(1,&xsmps,SOUND_BUFFER_SIZE*2*2); - - / * */ - }; - return(0); -}; + audioout->OSSout(outputl, outputr); +#endif + + /** / int i,x,x2; + REALTYPE xx,xx2; + + short int xsmps[SOUND_BUFFER_SIZE*2]; + for (i=0;i<SOUND_BUFFER_SIZE;i++){//output to stdout + xx=-outputl[i]*32767; + xx2=-outputr[i]*32767; + if (xx<-32768) xx=-32768; + if (xx>32767) xx=32767; + if (xx2<-32768) xx2=-32768; + if (xx2>32767) xx2=32767; + x=(short int) xx; + x2=(short int) xx2; + xsmps[i*2]=x;xsmps[i*2+1]=x2; + }; + write(1,&xsmps,SOUND_BUFFER_SIZE*2*2); + + / * */ + } + return 0; +} #endif /* @@ -205,10 +208,10 @@ void *thread3(void *arg) #ifdef FLTK_GUI ui->showUI(); - while (Pexitprogram==0) { + while(Pexitprogram == 0) { #ifdef USE_LASH string filename; - switch (lash->checkevents(filename)) { + switch(lash->checkevents(filename)) { case LASHClient::Save: ui->do_save_master(filename.c_str()); lash->confirmevent(LASHClient::Save); @@ -228,28 +231,33 @@ void *thread3(void *arg) #elif defined QT_GUI app = new QApplication(0, 0); - ui=new MasterUI(master, 0); + ui = new MasterUI(master, 0); ui->show(); app->exec(); #endif //defined QT_GUI #endif //DISABLE_GUI - return(0); -}; + return 0; +} /* * Sequencer thread (test) */ void *thread4(void *arg) { - while (Pexitprogram==0) { - int type,par1,par2,again,midichan; - for (int ntrack=0;ntrack<NUM_MIDI_TRACKS;ntrack++) { - if (master->seq.play==0) break; + while(Pexitprogram == 0) { + int type, par1, par2, again, midichan; + for(int ntrack = 0; ntrack < NUM_MIDI_TRACKS; ntrack++) { + if(master->seq.play == 0) + break; do { - again=master->seq.getevent(ntrack,&midichan,&type,&par1,&par2); + again = master->seq.getevent(ntrack, + &midichan, + &type, + &par1, + &par2); // printf("ntrack=%d again=%d\n",ntrack,again); - if (type>0) { + if(type > 0) { // printf("%d %d %d %d %d\n",type,midichan,chan,par1,par2); // if (cmdtype==MidiController) master->SetController(cmdchan,cmdparams[0],cmdparams[1]); @@ -257,15 +265,16 @@ void *thread4(void *arg) pthread_mutex_lock(&master->mutex); - if (type==1) {//note_on or note_off - if (par2!=0) master->NoteOn(midichan,par1,par2); - else master->NoteOff(midichan,par1); - }; + if(type == 1) { //note_on or note_off + if(par2 != 0) + master->NoteOn(midichan, par1, par2); + else + master->NoteOff(midichan, par1); + } pthread_mutex_unlock(&master->mutex); - }; - } while (again>0); - - }; + } + } while(again > 0); + } //if (!realtime player) atunci fac asta //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #ifdef OS_LINUX @@ -273,10 +282,10 @@ void *thread4(void *arg) #elif OS_WINDOWS Sleep(1); #endif - }; + } - return(0); -}; + return 0; +} /* * Program initialisation @@ -293,31 +302,37 @@ void initprogram() #endif #endif cerr << "Sound Buffer Size = \t" << SOUND_BUFFER_SIZE << " samples" << endl; - cerr << "Internal latency = \t" << SOUND_BUFFER_SIZE*1000.0/SAMPLE_RATE << " ms" << endl; + cerr << "Internal latency = \t" << SOUND_BUFFER_SIZE * 1000.0 + / SAMPLE_RATE << " ms" << endl; cerr << "ADsynth Oscil.Size = \t" << OSCIL_SIZE << " samples" << endl; //fflush(stderr); srand(time(NULL)); - denormalkillbuf=new REALTYPE [SOUND_BUFFER_SIZE]; - for (int i=0;i<SOUND_BUFFER_SIZE;i++) denormalkillbuf[i]=(RND-0.5)*1e-16; + denormalkillbuf = new REALTYPE [SOUND_BUFFER_SIZE]; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) + denormalkillbuf[i] = (RND - 0.5) * 1e-16; - master=new Master(); - master->swaplr=swaplr; + master = new Master(); + master->swaplr = swaplr; #if defined(JACKAUDIOOUT) - if (usejackit) { - bool tmp=JACKaudiooutputinit(master); + if(usejackit) { + bool tmp = JACKaudiooutputinit(master); #if defined(OSSAUDIOOUT) - if (!tmp) cout << "\nUsing OSS instead." << endl; + if(!tmp) + cout << "\nUsing OSS instead." << endl; #else - if (!tmp) exit(1); + if(!tmp) + exit(1); #endif - usejackit=tmp; - }; + usejackit = tmp; + } #endif #if defined(OSSAUDIOOUT) - if (!usejackit) audioout=new OSSaudiooutput(); - else audioout=NULL; + if(!usejackit) + audioout = new OSSaudiooutput(); + else + audioout = NULL; #endif #ifdef JACK_RTAUDIOOUT @@ -328,18 +343,18 @@ void initprogram() #endif #ifdef ALSAMIDIIN - Midi=new ALSAMidiIn(); + Midi = new ALSAMidiIn(); #endif #ifdef OSSMIDIIN - Midi=new OSSMidiIn(); + Midi = new OSSMidiIn(); #endif -#if (defined(NONEMIDIIN)||(defined(VSTMIDIIN))) - Midi=new NULLMidiIn(); +#if (defined(NONEMIDIIN) || (defined(VSTMIDIIN))) + Midi = new NULLMidiIn(); #endif #ifndef DISABLE_GUI - ui=new MasterUI(master,&Pexitprogram); + ui = new MasterUI(master, &Pexitprogram); #endif -}; +} /* * Program exit @@ -348,10 +363,11 @@ void exitprogram() { pthread_mutex_lock(&master->mutex); #ifdef OSSAUDIOOUT - delete(audioout); + delete (audioout); #endif #ifdef JACKAUDIOOUT - if (usejackit) JACKfinish(); + if(usejackit) + JACKfinish(); #endif #ifdef JACK_RTAUDIOOUT JACKfinish(); @@ -361,13 +377,13 @@ void exitprogram() #endif #ifndef DISABLE_GUI - delete(ui); + delete (ui); #endif - delete(Midi); - delete(master); + delete (Midi); + delete (master); #ifdef USE_LASH - delete(lash); + delete (lash); #endif // pthread_mutex_unlock(&master->mutex); @@ -379,22 +395,24 @@ void exitprogram() char winoptarguments[ARGSIZE]; char getopt(int argc, char *argv[], const char *shortopts, int *index) { - winoptarguments[0]=0; - char result=0; - - if (*index>=argc) return(-1); - - if (strlen(argv[*index])==2) - if (argv[*index][0]=='-') { - result=argv[*index][1]; - if (*index+1<argc) { - snprintf(winoptarguments,ARGSIZE,"%s",argv[*index+1]); - }; - }; + winoptarguments[0] = 0; + char result = 0; + + if(*index >= argc) + return -1; + + if(strlen(argv[*index]) == 2) + if(argv[*index][0] == '-') { + result = argv[*index][1]; + if(*index + 1 < argc) + snprintf(winoptarguments, ARGSIZE, "%s", argv[*index + 1]); + ; + } + ; (*index)++; - return(result); -}; -int opterr=0; + return result; +} +int opterr = 0; #undef ARGSIZE #endif @@ -402,170 +420,215 @@ int opterr=0; #ifndef VSTAUDIOOUT int main(int argc, char *argv[]) { - #ifdef USE_LASH lash = new LASHClient(&argc, &argv); #endif config.init(); dump.startnow(); - int noui=0; + int noui = 0; #ifdef JACKAUDIOOUT - usejackit=true;//use jack by default + usejackit = true; //use jack by default #endif - cerr<<"\nZynAddSubFX - Copyright (c) 2002-2009 Nasca Octavian Paul and others"<<endl; + cerr + << "\nZynAddSubFX - Copyright (c) 2002-2009 Nasca Octavian Paul and others" + << endl; cerr << "Compiled: " << __DATE__ << " " << __TIME__ << endl; cerr << "This program is free software (GNU GPL v.2 or later) and \n"; cerr << "it comes with ABSOLUTELY NO WARRANTY.\n" << endl; #ifdef OS_LINUX - if (argc==1) cerr << "Try 'zynaddsubfx --help' for command-line options." << endl; + if(argc == 1) + cerr << "Try 'zynaddsubfx --help' for command-line options." << endl; #else - if (argc==1) cerr << "Try 'zynaddsubfx -h' for command-line options.\n" << endl; + if(argc == 1) + cerr << "Try 'zynaddsubfx -h' for command-line options.\n" << endl; #endif /* Get the settings from the Config*/ - SAMPLE_RATE=config.cfg.SampleRate; - SOUND_BUFFER_SIZE=config.cfg.SoundBufferSize; - OSCIL_SIZE=config.cfg.OscilSize; - swaplr=config.cfg.SwapStereo; + SAMPLE_RATE = config.cfg.SampleRate; + SOUND_BUFFER_SIZE = config.cfg.SoundBufferSize; + OSCIL_SIZE = config.cfg.OscilSize; + swaplr = config.cfg.SwapStereo; /* Parse command-line options */ #ifdef OS_LINUX - struct option opts[]={ - {"load",2,NULL,'l'}, - {"load-instrument",2,NULL,'L'}, - {"sample-rate",2,NULL,'r'}, - {"buffer-size",2,NULL,'b'}, - {"oscil-size",2,NULL,'o'}, - {"dump",2,NULL,'D'}, - {"swap",2,NULL,'S'}, - {"no-gui",2,NULL,'U'}, - {"not-use-jack",2,NULL,'A'}, - {"dummy",2,NULL,'Y'}, - {"help",2,NULL,'h'}, - {0,0,0,0} + struct option opts[] = { + { + "load", 2, NULL, 'l' + }, + { + "load-instrument", 2, NULL, 'L' + }, + { + "sample-rate", 2, NULL, 'r' + }, + { + "buffer-size", 2, NULL, 'b' + }, + { + "oscil-size", 2, NULL, 'o' + }, + { + "dump", 2, NULL, 'D' + }, + { + "swap", 2, NULL, 'S' + }, + { + "no-gui", 2, NULL, 'U' + }, + { + "not-use-jack", 2, NULL, 'A' + }, + { + "dummy", 2, NULL, 'Y' + }, + { + "help", 2, NULL, 'h' + }, + { + 0, 0, 0, 0 + } }; #endif - opterr=0; - int option_index=0,opt,exitwithhelp=0; + opterr = 0; + int option_index = 0, opt, exitwithhelp = 0; char loadfile[1001]; - ZERO(loadfile,1001); + ZERO(loadfile, 1001); char loadinstrument[1001]; - ZERO(loadinstrument,1001); + ZERO(loadinstrument, 1001); - while (1) { + while(1) { /**\todo check this process for a small memory leak*/ #ifdef OS_LINUX - opt=getopt_long(argc,argv,"l:L:r:b:o:hSDUAY",opts,&option_index); - char *optarguments=optarg; + opt = getopt_long(argc, argv, "l:L:r:b:o:hSDUAY", opts, &option_index); + char *optarguments = optarg; #else - opt=getopt(argc,argv,"l:L:r:b:o:hSDUAY",&option_index); - char *optarguments=&winoptarguments[0]; + opt = getopt(argc, argv, "l:L:r:b:o:hSDUAY", &option_index); + char *optarguments = &winoptarguments[0]; #endif - if (opt==-1) break; + if(opt == -1) + break; int tmp; - switch (opt) { + switch(opt) { case 'h': - exitwithhelp=1; + exitwithhelp = 1; break; case 'Y':/* this command a dummy command (has NO effect) - and is used because I need for NSIS installer - (NSIS sometimes forces a command line for a - program, even if I don't need that; eg. when - I want to add a icon to a shortcut. - */ + and is used because I need for NSIS installer + (NSIS sometimes forces a command line for a + program, even if I don't need that; eg. when + I want to add a icon to a shortcut. + */ break; case 'U': - noui=1; + noui = 1; break; case 'A': #ifdef JACKAUDIOOUT #ifdef OSSAUDIOOUT - usejackit=false; + usejackit = false; #endif #endif break; case 'l': - tmp=0; - if (optarguments!=NULL) { - snprintf(loadfile,1000,"%s",optarguments); - }; + tmp = 0; + if(optarguments != NULL) + snprintf(loadfile, 1000, "%s", optarguments); + ; break; case 'L': - tmp=0; - if (optarguments!=NULL) { - snprintf(loadinstrument,1000,"%s",optarguments); - }; + tmp = 0; + if(optarguments != NULL) + snprintf(loadinstrument, 1000, "%s", optarguments); + ; break; case 'r': - tmp=0; - if (optarguments!=NULL) tmp=atoi(optarguments); - if (tmp>=4000) { - SAMPLE_RATE=tmp; - } else { + tmp = 0; + if(optarguments != NULL) + tmp = atoi(optarguments); + if(tmp >= 4000) + SAMPLE_RATE = tmp; + else { cerr << "ERROR:Incorrect sample rate: " << optarguments << endl; exit(1); - }; + } break; case 'b': - tmp=0; - if (optarguments!=NULL) tmp=atoi(optarguments); - if (tmp>=2) { - SOUND_BUFFER_SIZE=tmp; - } else { + tmp = 0; + if(optarguments != NULL) + tmp = atoi(optarguments); + if(tmp >= 2) + SOUND_BUFFER_SIZE = tmp; + else { cerr << "ERROR:Incorrect buffer size: " << optarguments << endl; exit(1); - }; + } break; case 'o': - tmp=0; - if (optarguments!=NULL) tmp=atoi(optarguments); - OSCIL_SIZE=tmp; - if (OSCIL_SIZE<MAX_AD_HARMONICS*2) OSCIL_SIZE=MAX_AD_HARMONICS*2; - OSCIL_SIZE=(int) pow(2,ceil(log (OSCIL_SIZE-1.0)/log(2.0))); - if (tmp!=OSCIL_SIZE) { - cerr << "\nOSCIL_SIZE is wrong (must be 2^n) or too small. Adjusting to "; + tmp = 0; + if(optarguments != NULL) + tmp = atoi(optarguments); + OSCIL_SIZE = tmp; + if(OSCIL_SIZE < MAX_AD_HARMONICS * 2) + OSCIL_SIZE = MAX_AD_HARMONICS * 2; + OSCIL_SIZE = (int) pow(2, ceil(log(OSCIL_SIZE - 1.0) / log(2.0))); + if(tmp != OSCIL_SIZE) { + cerr + << + "\nOSCIL_SIZE is wrong (must be 2^n) or too small. Adjusting to "; cerr << OSCIL_SIZE << "." << endl; } break; case 'S': - swaplr=1; + swaplr = 1; break; case 'D': dump.startnow(); break; case '?': cerr << "ERROR:Bad option or parameter.\n" << endl; - exitwithhelp=1; + exitwithhelp = 1; break; - }; - }; + } + } - if (exitwithhelp!=0) { + if(exitwithhelp != 0) { cout << "Usage: zynaddsubfx [OPTION]\n" << endl; - cout << " -h , --help \t\t\t\t display command-line help and exit" << endl; + cout << " -h , --help \t\t\t\t display command-line help and exit" + << endl; cout << " -l file, --load=FILE\t\t\t loads a .xmz file" << endl; - cout << " -L file, --load-instrument=FILE\t\t loads a .xiz file" << endl; + cout << " -L file, --load-instrument=FILE\t\t loads a .xiz file" + << endl; cout << " -r SR, --sample-rate=SR\t\t set the sample rate SR" << endl; - cout << " -b BS, --buffer-size=SR\t\t set the buffer size (granularity)" << endl; - cout << " -o OS, --oscil-size=OS\t\t set the ADsynth oscil. size" << endl; + cout + << " -b BS, --buffer-size=SR\t\t set the buffer size (granularity)" + << endl; + cout << " -o OS, --oscil-size=OS\t\t set the ADsynth oscil. size" + << endl; cout << " -S , --swap\t\t\t\t swap Left <--> Right" << endl; cout << " -D , --dump\t\t\t\t Dumps midi note ON/OFF commands" << endl; - cout << " -U , --no-gui\t\t\t\t Run ZynAddSubFX without user interface" << endl; + cout + << " -U , --no-gui\t\t\t\t Run ZynAddSubFX without user interface" + << endl; #ifdef JACKAUDIOOUT #ifdef OSSAUDIOOUT - cout << " -A , --not-use-jack\t\t\t Use OSS/ALSA instead of JACK" << endl; + cout << " -A , --not-use-jack\t\t\t Use OSS/ALSA instead of JACK" + << endl; #endif #endif #ifdef OS_WINDOWS - cout << "\nWARNING: On Windows systems, only short comandline parameters works." << endl; + cout + << + "\nWARNING: On Windows systems, only short comandline parameters works." + << endl; cout << " eg. instead '--buffer-size=512' use '-b 512'" << endl; #endif cout << '\n' << endl; - return(0); - }; + return 0; + } //--------- @@ -573,8 +636,8 @@ int main(int argc, char *argv[]) #ifdef USE_LASH #ifdef ALSAMIDIIN - ALSAMidiIn* alsamidi = dynamic_cast<ALSAMidiIn*>(Midi); - if (alsamidi) + ALSAMidiIn *alsamidi = dynamic_cast<ALSAMidiIn *>(Midi); + if(alsamidi) lash->setalsaid(alsamidi->getalsaid()); #endif #ifdef JACKAUDIOOUT @@ -582,43 +645,51 @@ int main(int argc, char *argv[]) #endif #endif - if (strlen(loadfile)>1) { - int tmp=master->loadXML(loadfile); - if (tmp<0) { - fprintf(stderr,"ERROR:Could not load master file %s .\n",loadfile); + if(strlen(loadfile) > 1) { + int tmp = master->loadXML(loadfile); + if(tmp < 0) { + fprintf(stderr, + "ERROR:Could not load master file %s .\n", + loadfile); exit(1); - } else { + } + else { master->applyparameters(); #ifndef DISABLE_GUI - if (noui==0) ui->refresh_master_ui(); + if(noui == 0) + ui->refresh_master_ui(); #endif cout << "Master file loaded." << endl; - }; - }; + } + } - if (strlen(loadinstrument)>1) { - int loadtopart=0; - int tmp=master->part[loadtopart]->loadXMLinstrument(loadinstrument); - if (tmp<0) { - cerr << "ERROR:Could not load instrument file " << loadinstrument << '.' << endl; + if(strlen(loadinstrument) > 1) { + int loadtopart = 0; + int tmp = master->part[loadtopart]->loadXMLinstrument(loadinstrument); + if(tmp < 0) { + cerr << "ERROR:Could not load instrument file " + << loadinstrument << '.' << endl; exit(1); - } else { + } + else { master->part[loadtopart]->applyparameters(); #ifndef DISABLE_GUI - if (noui==0) ui->refresh_master_ui(); + if(noui == 0) + ui->refresh_master_ui(); #endif cout << "Instrument file loaded." << endl; - }; - }; + } + } -#if !(defined(NONEMIDIIN)||defined(WINMIDIIN)||defined(VSTMIDIIN)) - pthread_create(&thr1,NULL,thread1,NULL); +#if !(defined(NONEMIDIIN) || defined(WINMIDIIN) || defined(VSTMIDIIN)) + pthread_create(&thr1, NULL, thread1, NULL); #endif #ifdef OSSAUDIOOUT //!(defined(JACKAUDIOOUT)||defined(JACK_RTAUDIOOUT)||defined(PAAUDIOOUT)||defined(VSTAUDIOOUT)) - if (!usejackit) pthread_create(&thr2,NULL,thread2,NULL); + if(!usejackit) + pthread_create(&thr2, NULL, thread2, NULL); #endif /*It is not working and I don't know why @@ -630,28 +701,29 @@ int main(int argc, char *argv[]) // setregid(getuid(),getuid()); #endif */ - if (noui==0) pthread_create(&thr3,NULL,thread3,NULL); + if(noui == 0) + pthread_create(&thr3, NULL, thread3, NULL); - pthread_create(&thr4,NULL,thread4,NULL); + pthread_create(&thr4, NULL, thread4, NULL); #ifdef WINMIDIIN InitWinMidi(master); #endif - while (Pexitprogram==0) { + while(Pexitprogram == 0) { #ifdef OS_LINUX usleep(100000); #elif OS_WINDOWS Sleep(100); #endif - }; + } #ifdef WINMIDIIN StopWinMidi(); #endif exitprogram(); - return(0); -}; + return 0; +} #else @@ -659,47 +731,50 @@ int main(int argc, char *argv[]) #include "Output/VSTaudiooutput.h" #define main main_plugin -extern "C" __declspec(dllexport) AEffect *main_plugin(audioMasterCallback audioMaster); +extern "C" __declspec(dllexport) AEffect * main_plugin( + audioMasterCallback audioMaster); -int instances=-1; +int instances = -1; -AEffect *main (audioMasterCallback audioMaster) +AEffect *main(audioMasterCallback audioMaster) { // if (audioMaster(0,audioMasterVersion,0,0,0,0)!=0) { // return(0); // }; - if (instances==-1) { - Midi=new NULLMidiIn(); - denormalkillbuf=new REALTYPE [SOUND_BUFFER_SIZE]; - for (int i=0;i<SOUND_BUFFER_SIZE;i++) denormalkillbuf[i]=(RND-0.5)*1e-16; - instances=0; - }; + if(instances == -1) { + Midi = new NULLMidiIn(); + denormalkillbuf = new REALTYPE [SOUND_BUFFER_SIZE]; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) + denormalkillbuf[i] = (RND - 0.5) * 1e-16; + instances = 0; + } - if (instances!=0) return(0);//don't allow multiple instances + if(instances != 0) + return 0; //don't allow multiple instances - AudioEffect *sintetizator=new VSTSynth(audioMaster); + AudioEffect *sintetizator = new VSTSynth(audioMaster); return sintetizator->getAeffect(); -}; +} -void* hInstance; -BOOL WINAPI DllMain (HINSTANCE hInst,DWORD dwReason,LPVOID lpvReserved) +void *hInstance; +BOOL WINAPI DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpvReserved) { - hInstance=hInst; - return(1); -}; + hInstance = hInst; + return 1; +} void *thread(void *arg) { - VSTSynth *vs=(VSTSynth *) arg; + VSTSynth *vs = (VSTSynth *) arg; /* FILE *a=fopen("aaaa1","a"); fprintf(a,"%lx %lx %lx -i=%d\n",vs,0,vs->vmaster,instances); fflush(a);fclose(a); */ - vs->ui=new MasterUI(vs->vmaster,&vs->Pexitprogram); + vs->ui = new MasterUI(vs->vmaster, &vs->Pexitprogram); /* a=fopen("aaaa1","a"); fprintf(a,"%lx %lx %lx\n",vs,vs->ui->master,vs->vmaster); @@ -713,9 +788,10 @@ void *thread(void *arg) fflush(a);fclose(a); */ - while (vs->Pexitprogram==0) Fl::wait(0.01); + while(vs->Pexitprogram == 0) + Fl::wait(0.01); - delete(vs->ui); + delete (vs->ui); Fl::wait(0.01); /* a=fopen("aaaa1","a"); @@ -725,15 +801,16 @@ void *thread(void *arg) pthread_exit(0); - return(0); -}; + return 0; +} //Parts of the VSTSynth class -VSTSynth::VSTSynth (audioMasterCallback audioMaster):AudioEffectX(audioMaster,1,0) +VSTSynth::VSTSynth(audioMasterCallback audioMaster):AudioEffectX(audioMaster, 1, + 0) { instances++; - if (audioMaster) { + if(audioMaster) { setNumInputs(0); setNumOutputs(2); setUniqueID('ZASF'); @@ -744,97 +821,97 @@ VSTSynth::VSTSynth (audioMasterCallback audioMaster):AudioEffectX(audioMaster,1, isSynth(true); programsAreChunks(true); - - }; + } - SAMPLE_RATE=config.cfg.SampleRate; - SOUND_BUFFER_SIZE=config.cfg.SoundBufferSize; - OSCIL_SIZE=config.cfg.OscilSize; - swaplr=config.cfg.SwapStereo; - this->Pexitprogram=0; + SAMPLE_RATE = config.cfg.SampleRate; + SOUND_BUFFER_SIZE = config.cfg.SoundBufferSize; + OSCIL_SIZE = config.cfg.OscilSize; + swaplr = config.cfg.SwapStereo; + this->Pexitprogram = 0; - this->vmaster=new Master(); - this->vmaster->swaplr=swaplr; + this->vmaster = new Master(); + this->vmaster->swaplr = swaplr; // FILE *a=fopen("aaaa0","a"); // fprintf(a,"%lx %lx %lx\n",this,this->ui,this->ui->masterwindow); // fflush(a);fclose(a); - pthread_create(&this->thr,NULL,thread,this); + pthread_create(&this->thr, NULL, thread, this); // suspend(); - -}; +} VSTSynth::~VSTSynth() { - this->Pexitprogram=1; + this->Pexitprogram = 1; - Sleep(200);//wait the thread to finish + Sleep(200); //wait the thread to finish // pthread_mutex_lock(&vmaster->mutex); - delete(this->vmaster); + delete (this->vmaster); instances--; -}; +} long VSTSynth::processEvents(VstEvents *events) { - for (int i=0;i<events->numEvents;i++) { - + for(int i = 0; i < events->numEvents; i++) { //debug stuff // FILE *a=fopen("events","a"); // fprintf(a,"%lx\n",events->events[i]->type); // fflush(a);fclose(a); - if ((events->events[i])->type != kVstMidiType) continue; - VstMidiEvent *ev= (VstMidiEvent*) events->events[i]; - unsigned char *data= (unsigned char *)ev->midiData; - int status=data[0]/16; - int cmdchan=data[0]&0x0f; + if((events->events[i])->type != kVstMidiType) + continue; + VstMidiEvent *ev = (VstMidiEvent *) events->events[i]; + unsigned char *data = (unsigned char *)ev->midiData; + int status = data[0] / 16; + int cmdchan = data[0] & 0x0f; int cntl; pthread_mutex_lock(&vmaster->mutex); - switch (status) { + switch(status) { case 0x8: - vmaster->NoteOff(cmdchan,data[1]&0x7f); + vmaster->NoteOff(cmdchan, data[1] & 0x7f); break; case 0x9: - if (data[2]==0) vmaster->NoteOff(cmdchan,data[1]&0x7f); - else vmaster->NoteOn(cmdchan,data[1]&0x7f,data[2]&0x7f); + if(data[2] == 0) + vmaster->NoteOff(cmdchan, data[1] & 0x7f); + else + vmaster->NoteOn(cmdchan, data[1] & 0x7f, data[2] & 0x7f); break; case 0xB: - cntl=Midi->getcontroller(data[1]&0x7f); - vmaster->SetController(cmdchan,cntl,data[2]&0x7f); + cntl = Midi->getcontroller(data[1] & 0x7f); + vmaster->SetController(cmdchan, cntl, data[2] & 0x7f); break; case 0xE: - vmaster->SetController(cmdchan,C_pitchwheel,data[1]+data[2]*(long int) 128-8192); + vmaster->SetController(cmdchan, C_pitchwheel, data[1] + data[2] + * (long int) 128 - 8192); break; - }; + } pthread_mutex_unlock(&vmaster->mutex); + } - }; - - return(1); -}; + return 1; +} -long VSTSynth::getChunk(void** data,bool isPreset) +long VSTSynth::getChunk(void **data, bool isPreset) { - int size=0; - size=vmaster->getalldata((char **)data); - return((long)size); -}; + int size = 0; + size = vmaster->getalldata((char **)data); + return (long)size; +} -long VSTSynth::setChunk(void *data,long size,bool isPreset) +long VSTSynth::setChunk(void *data, long size, bool isPreset) { - vmaster->putalldata((char*)data,size); - return(0); -}; + vmaster->putalldata((char *)data, size); + return 0; +} #endif