[SCM] zynaddsubfx/master: Imported Upstream version 2.4.3

mira-guest at users.alioth.debian.org mira-guest at users.alioth.debian.org
Sun Jul 8 23:22:44 UTC 2012


The following commit has been merged in the master branch:
commit 274d947f7e55d83fe98fc4914d40ec9624f69ecc
Author: Jaromír Mikeš <mira.mikes at seznam.cz>
Date:   Mon Jul 9 01:19:15 2012 +0200

    Imported Upstream version 2.4.3

diff --git a/AUTHORS.txt b/AUTHORS.txt
index a1ffa13..1ddccc1 100644
--- a/AUTHORS.txt
+++ b/AUTHORS.txt
@@ -1,13 +1,26 @@
 Main author:
-	Nasca Octavian Paul
+        Nasca Octavian Paul
 
 Developers:
-	Mark McCurry
+        Mark McCurry
+        Harald Hvaal
 
 Contributors:
-	Gerald Folcher (legato, mono notes memory)
-	Lars Luthman (zombie fix,jack midi, LASH support)
-	Daniel Clemente (with a workaround of X11 repeated key bug)
+        Gerald Folcher (legato, mono notes memory)
+        Lars Luthman (zombie fix,jack midi, LASH support)
+        Daniel Clemente (with a workaround of X11 repeated key bug)
         Emmanuel Saracco (fix for JACK output)
         Achim Settelmeier (QUERTZ keyboard layout for virtual keyboard)
+        Jérémie Andréi (AZERTY keyboard layout, Array index fix, OSS failsafe)
+        Alexis Ballier (const char* <-> string mismatch, NULLMidi prototype fix)
+        Tobias Doerffel (static-instance variables fix, missing include fix)
+        James Morris (Memory leaks in FLTK GUI)
+        Alan Calvert (Portions of New IO)
+        Stephen Parry (DSSI rebuild)
+        Ryan Billing (APhaser)
+        Hans Petter Selasky (OSS Midi, FreeBSD support, Bank UI bug fix)
+        Damien Goutte-Gattat (Bank select midi support)
+        Lieven Moors (Spike/Circle waveform)
+        Olaf Schulz (MIDI Aftertouch support)
+        Jonathan Liles (NSM support)
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..edc7d27
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 2.8)
+set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/")
+project(zynaddsubfx)
+set(VERSION "2.4.3")
+
+enable_testing()
+include(CTestConfig.cmake)
+#Currently the only directory that uses cmake
+add_subdirectory(src)
+
+install(FILES AUTHORS.txt COPYING FAQ.txt HISTORY.txt README.txt
+	DESTINATION share/doc/zynaddsubfx
+	)
diff --git a/CTestConfig.cmake b/CTestConfig.cmake
new file mode 100644
index 0000000..bf4f379
--- /dev/null
+++ b/CTestConfig.cmake
@@ -0,0 +1,13 @@
+## This file should be placed in the root directory of your project.
+## Then modify the CMakeLists.txt file in the root directory of your
+## project to incorporate the testing dashboard.
+## # The following are required to uses Dart and the Cdash dashboard
+##   ENABLE_TESTING()
+##   INCLUDE(CTest)
+set(CTEST_PROJECT_NAME "ZynAddSubFX")
+set(CTEST_NIGHTLY_START_TIME "00:00:00 EST")
+
+set(CTEST_DROP_METHOD "http")
+set(CTEST_DROP_SITE "fundamental-code.com")
+set(CTEST_DROP_LOCATION "/CDash/submit.php?project=ZynAddSubFX")
+set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/ChangeLog b/ChangeLog
index 25d69fd..113447e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,4 @@
-6 Mar 2002  -(dupamasa - in jur de ora 4) Mi-a venit ideea exact cum sa fac cand ma plimbam pe strada Rolirudnap
+6 Mar 2002  -(dupamasa - in jur de ora 4) Mi-a venit ideea exact cum sa fac cand ma plimbam pe strada Pandurilor
 7/8 Mar 2002 - Started to do diagrams
 10 Mar 2002 - Started to write "voice"
 11 Mar 2002 - Heard first sound
@@ -828,6 +828,8 @@
 	    - Codul de recorder wav a fost rescris
 	    - Adaugata functia de export la sample-urile din PADsynth
 
+*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *
+
 20 Feb 2009 (Mark McCurry)
 	    - Made several functions accept 'constant char' over 'char' to
 	      prevent warnings
@@ -873,3 +875,162 @@
 	    
 10 Iul 2009 (Paul Nasca)
 	    - Update copyright info
+
+11 Jul 2009 (Mark McCurry)
+	    - Added Proportinal Portamento
+	    - Replaced Docbook with AsciiDoc
+
+18 Jul 2009 (Mark McCurry)
+	    - Enabled volume controller by default
+
+20 Jul 2009 (Mark McCurry)
+	    - Incorperated AZERTY layout by sourceforge user jimee
+
+02 Sep 2009 (Mark McCurry)
+	    - Incorperated const char* <-> string mismatch by Alexis Ballier 
+	    
+04 Sep 2009 (Mark McCurry)
+	    - Incorperated NULLMidiIn function prototype fix by Alexis Ballier
+
+07 Sep 2009 (Mark McCurry)
+	    - Fixed glitch in XMLwrapper, which would prevent file loading
+
+11 Sep 2009 (Mark McCurry)
+	    - Moved PADsynth_used from public struct to has/set methods in 
+	      XMLwrapper
+	    - Created wrapper functions, so that XMLwrapper can be somewhat
+	      usable when const
+	    - Removed multiple addparam methods and replaced it with one
+	      variable argument function
+	    - Replaced int2str, real2str, str2int, and str2real from XMLwrapper
+	      with stringTo<T> and stringFrom<T> function templates in Util.
+	    - Moved newFFTFREQS and deleteFFTFREQS from Util to FFTwrapper
+	    - Removed unneeded stack from XMLwrapper
+
+18 Sep 2009 (Mark McCurry)
+	    - Started to use versioning information in XMLwrapper
+	    - Remove last of stack helper functions in XMLwrapper
+	    - Added std::string retreval to XMLwrapper
+
+20 Sep 2009 (Paul Nasca)
+	    - Started to implement the Unison effect for ADsynth
+	    
+22 Sep 2009 (Paul Nasca)
+	    - Added vibratto and other features to Unison effect
+
+22 Sep 2009 (Mark McCurry)
+	    - Changed temporary data for Oscilgen from static to instance
+	      recommended by Tobias Doerffel
+	    - Fixed Memory leaks in UI based upon James Morris' patch
+
+23 Sep 2009 (Paul Nasca)
+	    - Added unison invert phase
+	    - Made unison frequency spread to depend on Bandwidth controllers and parameters
+	    - Added unison vibratto speed control and other improvements
+	    - bugfixes: Voice Amplitude Envelope and FM	    
+
+24 Sep 2009 (Paul Nasca)
+	    - Small enhancements and bugfixes to Unison
+	    - Started to implement Bandwidth to the Reverb effect
+		    
+25 Sep 2009 (Mark McCurry)
+	    - Allowed for XMLwrapper to retrieve strings stored in mxml TEXT
+	      fields
+29 Sep 2009 (Paul Nasca)
+	    - Remove the old (FFT based) Bandwidth effect to Reverb and started rewrite it (based on multivoice chorus/unison effect)
+
+01 Oct 2009 (Paul Nasca)
+	    - Corrected the ADsynth unison LFO rounding function 
+	    - Made Unison based on Bandwidth (in cents) parameter
+
+02 Oct 2009 (Mark McCurry)
+	    - Added OSS failsafe by Jérémie Andréi
+
+04 Oct 2009 (Mark McCurry)
+	    - fixed Ctest issues
+
+06 Oct 2009 (Mark McCurry)
+	    - Added first simple profiling test
+
+08 Oct 2009 (Mark McCurry)
+	    - 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
+
+28 Oct 2009 (Paul Nasca)
+	    - Disable "bw" control on Reverb when Bandwidth mode is not enabled
+
+30 Oct 2009 (Mark McCurry)
+	    - Commited first stage of Nio (New IO) WIP
+
+18 Nov 2009 (Mark McCurry)
+	    - Fixed segfault in VirKeyBoard
+
+02 Dec 2009 (Paul Nasca)
+		- Fixed a small typo on Virtual Keyboard
+
+10 Dec 2009 (Mark McCurry)
+	    - Separated out Presets and arrayed Presets to reduce warnings from
+	      the Wextra flag
+	    - Minor change to Filter_ and FormantFilter to reduce unwanted warnings
+
+13 Dec 2009 (Mark McCurry)
+	    - Deprecating Output system for the Nio system
+	    - General Code Cleanup
+	    - Adding OpenGL linking for proper compiles
+
+14 Jan 2010 (Mark McCurry)
+	    - Fixed No UI Flag "-U" as it was previously partially initializing
+	      the gui
+
+14 Feb 2010 (Stephen Parry)
+	    - DSSI Support Repaired
+
+14 Feb 2010 (Mark McCurry)
+	    - Made the Echo attempt to adjust the delay instead of erasing it
+	      when length is changed
+
+02 May 2010 (Mark McCurry)
+	    - Merging in cleanup from effects and adding APhaser by Ryan Billing
+
+27 Jun 2010 (Mark McCurry)
+	   - Aphaser and Phaser are within same effect now
+
+17 Aug 2010 (Paul Nasca)
+	   - small bugix on adsynth.cpp
+
+22 May 2010 (Mark McCurry)
+	  - Mergin Nio backend
+
+18 Aug 2011 (Mark McCurry)
+	  - Fixing DSSI subsystem
+
+29 Oct 2011 (Damien Goutte-Gattat)
+	  - Added Bank select midi support
+
+05 Feb 2012 (Liven Moors)
+	  - Added spike waveform to oscilator options
+
+06 Feb 2012 (Mark McCurry)
+	  - Adding --exec-after-init option
+
+22 Feb 2012 (Liven Moors)
+	  - Added circle waveform to oscilator options
+
+26 Mar 2012 (Mark McCurry)
+	  - Fixed Segfault in Oscillgen
+
+27 Mar 2012 (Mark McCurry)
+	  - Fixed chorus noise bug
+
+14 Apr 2012 (Mark McCurry)
+	  - Removed Nio debugging code
+
+18 Apr 2012 (Jonathan Liles)
+	  - Added Non-session-manager support
+
+31 Mar 2012 (Olaf Schulz)
+	  - Added Midi aftertouch support
diff --git a/ExternalPrograms/Controller/Controller.C b/ExternalPrograms/Controller/Controller.C
index b6dc8b7..ed94f25 100644
--- a/ExternalPrograms/Controller/Controller.C
+++ b/ExternalPrograms/Controller/Controller.C
@@ -6,69 +6,79 @@
 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
index 5083e80..5b83744 100644
--- a/ExternalPrograms/Controller/Controller.h
+++ b/ExternalPrograms/Controller/Controller.h
@@ -5,28 +5,29 @@
 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/ControllerUI.fl b/ExternalPrograms/Controller/ControllerUI.fl
index 1692c36..b83c9c0 100644
--- a/ExternalPrograms/Controller/ControllerUI.fl
+++ b/ExternalPrograms/Controller/ControllerUI.fl
@@ -1,8 +1,8 @@
 # data file for the Fltk User Interface Designer (fluid)
-version 1.0103 
+version 1.0110 
 header_name {.h} 
 code_name {.cxx}
-decl {\#include <FL/Fl_Box.h>} {public
+decl {\#include <FL/Fl_Box.H>} {selected public
 } 
 
 decl {\#include <stdlib.h>} {public
@@ -20,7 +20,7 @@ class Pad {: {public Fl_Box}
   }
   Function {temp_draw()} {} {
     code {/*int ox=x(),oy=y(),lx=w(),ly=h(),i,ix,iy,oiy;
-REALTYPE freqx;
+float freqx;
 
 fl_color(FL_BLACK);
 fl_rectf(ox,oy,lx,ly);
@@ -68,7 +68,7 @@ class ControllerUI {} {
       label {Midi Controller}
       callback {o->hide();
 exit(0);}
-      xywh {210 213 340 410} hide
+      xywh {210 213 340 410} type Double hide
     } {
       Fl_Counter {} {
         label {Output Channel}
@@ -85,27 +85,27 @@ exit(0);}
 refreshvalues();}
         xywh {10 50 75 20} down_box BORDER_BOX
       } {
-        menuitem {} {
+        MenuItem {} {
           label {But.1 X}
           xywh {0 0 100 20} labelfont 1 labelsize 12
         }
-        menuitem {} {
+        MenuItem {} {
           label {But.1 Y}
           xywh {10 10 100 20} labelfont 1 labelsize 12 divider
         }
-        menuitem {} {
+        MenuItem {} {
           label {But.2 X}
           xywh {10 10 100 20} labelfont 1 labelsize 12
         }
-        menuitem {} {
+        MenuItem {} {
           label {But.2 Y}
           xywh {20 20 100 20} labelfont 1 labelsize 12 divider
         }
-        menuitem {} {
+        MenuItem {} {
           label {But.3 X}
           xywh {20 20 100 20} labelfont 1 labelsize 12
         }
-        menuitem {} {
+        MenuItem {} {
           label {But.3 Y}
           xywh {30 30 100 20} labelfont 1 labelsize 12
         }
@@ -125,19 +125,19 @@ refreshvalues();}
 refreshvalues();}
         xywh {95 13 60 20} down_box BORDER_BOX labelsize 10 align 5
       } {
-        menuitem {} {
+        MenuItem {} {
           label OFF
           xywh {30 30 100 20} labelfont 1 labelsize 12
         }
-        menuitem {} {
+        MenuItem {} {
           label {Ctl.}
           xywh {20 20 100 20} labelfont 1 labelsize 12
         }
-        menuitem {} {
+        MenuItem {} {
           label RPN
           xywh {30 30 100 20} labelfont 1 labelsize 12 deactivate
         }
-        menuitem {} {
+        MenuItem {} {
           label NRPN
           xywh {40 40 100 20} labelfont 1 labelsize 12
         }
@@ -204,8 +204,7 @@ if (controller->pars[nbut].mode==1) ctlgroup->activate();
    else ctlgroup->deactivate();
 
 if (controller->pars[nbut].mode==3) nrpngroup->activate();
-   else nrpngroup->deactivate();} {selected
-    }
+   else nrpngroup->deactivate();} {}
   }
   Function {ControllerUI(Controller *controller_)} {} {
     code {nbut=0;
diff --git a/ExternalPrograms/Controller/main.C b/ExternalPrograms/Controller/main.C
index 8947b98..6018dc7 100644
--- a/ExternalPrograms/Controller/main.C
+++ b/ExternalPrograms/Controller/main.C
@@ -1,16 +1,16 @@
 #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
index 823fd32..bf567ff 100644
--- 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,76 @@
 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);
-	};
-				    
-    };
-    snd_seq_free_event(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
index a1a1dc7..9b5b83b 100644
--- 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,19 @@
 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
index 9d0667d..464f8bd 100644
--- a/ExternalPrograms/Spliter/main.C
+++ b/ExternalPrograms/Spliter/main.C
@@ -1,36 +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/FAQ.txt b/FAQ.txt
index 37e558b..c774ef3 100644
--- a/FAQ.txt
+++ b/FAQ.txt
@@ -23,5 +23,5 @@ A3) Look in src/globals.h and change there these values. You don't have to chang
 
 
 Q4) How do I enable Jack support on ZynAddSubFX ?
-A4) Look in "Makefile.inc" from "src/" directory for more information. It is highly recommended that the Jack samplerate to be equal to ZynAddSubFX samplerate (SAMPLE_RATE from globals.h), otherwise the resampling will be done and this will decrease the quality a bit.
+A4) If your system has the jack libraries installed, ZynAddSubFX should automatically build with jack support. It is highly recommended that the Jack samplerate to be equal to ZynAddSubFX samplerate (SAMPLE_RATE from globals.h), otherwise the resampling will be done and this will decrease the quality a bit.
 
diff --git a/HISTORY.txt b/HISTORY.txt
index 55c2e67..22f691f 100644
--- a/HISTORY.txt
+++ b/HISTORY.txt
@@ -1,4 +1,30 @@
-2.4.0 (15 Jul 2009)
+2.4.3 (15 Jun 2012)
+        - Non-session manager support
+        - Midi aftertouch support
+        - Documentation additions
+        - Somewhat more sane Nio defaults
+        - Misc bug fixes
+
+2.4.2 (26 Feb 2012)
+        - New IO backend support
+        - MIDI bank select
+        - Spike/Circle waveform
+        - Faster subsynth
+        - --exec-after-init flag
+        - Version information compiled in
+        - Misc Bug fixes
+
+2.4.1 (27 Jun 2010)
+        - Azerty layout
+        - XML bug fixes
+        - Vibrato/Unison additions
+        - Reverb rewrite
+        - DSSI support enabled
+        - Adding APhaser
+        - other bugfixes
+        - code cleanup
+
+2.4.0 (21 Jun 2009)
 	- extended mono functionality
 	- legato mode
 	- export functionality on PADsynth
diff --git a/README.txt b/README.txt
index a716d89..c8f419b 100644
--- a/README.txt
+++ b/README.txt
@@ -1,92 +1,83 @@
 ZynAddSubFX
 -----------
 It is a realtime software synthesizer for Linux and Windows with many features. Please see the docs for details.
-Copyright (c) 2002-2009 Nasca Octavian Paul and others.
+Copyright (c) 2002-2011 Nasca Octavian Paul and others contributors
 e-mail: zynaddsubfx AT yahoo D0T com
 ZynAddSubFX is free program and is distributed WITH NO WARRANTY. It is licensed under GNU General Public License version 2 (and only version 2) - see the file COPYING.
 
     --==## PLEASE SHARE YOUR INSTRUMENTS/MASTER SETTINGS ##==--
               --==## MADE WITH ZynAddSubFX ##==--
     Here is the mailing list where you can share your patches with others:
-      http://lists.sourceforge.net/mailman/listinfo/zynaddsubfx-user 
+      http://lists.sourceforge.net/mailman/listinfo/zynaddsubfx-user
 
 
-The project page is 
-    http://sourceforge.net/projects/zynaddsubfx   
-	or 
+The project page is
+    http://sourceforge.net/projects/zynaddsubfx
+    or
     http://zynaddsubfx.sourceforge.net
 
 ZynAddSubFX is also available on many Internet sites like:
-	http://www-ccrma.stanford.edu/planetccrma/software/soundapps.html (Planet CCRMA)
-	http://www.hitsquad.com/smm/programs/ZynAddSubFX/
-	http://freshmeat.net/projects/zynaddsubfx/
-	http://ibiblio.org/pub/Linux/apps/sound/midi/
-	or search "ZynAddSubFX" on a search engine (like www.google.com).
+    http://www-ccrma.stanford.edu/planetccrma/software/soundapps.html (Planet CCRMA)
+    http://www.hitsquad.com/smm/programs/ZynAddSubFX/
+    http://freshmeat.net/projects/zynaddsubfx/
+    http://ibiblio.org/pub/Linux/apps/sound/midi/
+    or search "ZynAddSubFX" on a search engine (like www.google.com).
+
 
-    
 Requirements:
 -------------
-               - a fast computer
-               - Linux (tested with RedHat 7.2,7.3,etc.) or Windows
-               - FFTW 2.x.x or 3.x.x (tested with fftw 2.0.5, 2.1.3, and 3.1.3) - necessary for
-  Fast Fourier computations
-	       - MXML-2.5 library from www.minixml.org
-	       - zlib library from http://www.zlib.org - this exists in most Linux distributions
-               - (for Linux) OpenSoundSystem (OSS) (if you don't have ALSA, only)
-	       - (for Windows) pthreads, portaudio
+- a fast computer
+- Linux or Windows
+- FFTW 3.x.x  - necessary for Fast Fourier computations
+- MXML-2.5 or more recent library from www.minixml.org
+- zlib library from http://www.zlib.org
+- (for Linux) OpenSoundSystem (OSS) (if you don't have ALSA, only)
+- (for Windows) pthreads, portaudio
 
 Not required, but recommended:
----------------------------
-
-    - FLTK 1.x.x (tested with fltk 1.1.0, 1.1.1, 1.1.2,etc.)
-    - ALSA 0.9.x or later (with OSS emulation, if you don't use JACK)
-    - JACKit - if you want to use it you must enable compilation for JACK in Makefile.inc
-    - a VST host for the VST version
+------------------------------
+- FLTK 1.x.x (tested with fltk 1.1.0, 1.1.1, 1.1.2,etc.)
+- ALSA 0.9.x or later (with OSS emulation, if you don't use JACK)
+- JACK
+- a VST host for the VST version [For more information see:
+  http://www.kvraudio.com/forum/viewtopic.php?t=268277&sid=95be0b6c9909300d566006428bcbb97d]
 
 Compilation:
 ------------
-    If you want to compile on Windows, please read compile.win32 file.
-    If you don't know how to compile, you may download binaries from Planet CCRMA (see above, on sites).
-    First set what should sound input/ouput should use in Makefile.inc in src/ directory.
-    Then "make" from the "src/" directory. Hope all goes right. If the compiler complains something about FFTwrapper.h and FFTW library headers(rfftw.h or fftw.h) please read the docs from DSP/FFTwrapper.h .
-    To compile the Spliter, run "make" from the "Spliter" directory. 
-    To compile the Controller, run "make" from the "Controller" directory. 
+    For the main program see doc/build.txt.
+    To compile the Spliter, run "make" from the "Spliter" directory.
+    To compile the Controller, run "make" from the "Controller" directory.
 
 Running on LINUX
 ----------------
-  *AUDIO OUTPUT
-   A) OSS (Open Sound System)
-   B) JACK (JACK Audio Connection Kit)
-    
-  *MIDI INPUT*
-    There are 2 possibilities of midi inputs (depends on what you have chosen in Makefile.inc to use - OSS or ALSA).
-    A) ALSA (Advanced Linux Sound Architecture)
-	1) Launch ZynAddSubFX
-	2) ZynAddSubFX will make a virtual MIDI port. 
-	   You can connect other midi devices (like a real MIDI keyboard, midi sequencers which supports ALSA or virtual keyboard - like vkeybd).
-	   To connect, use "aconnect" or "alsa-patch-bay"; usualy the port of ZynAddSubFX is 128:0 or 129:0.
-	3) You are ready to play
-	   
-	   It is possible to use midi sequencer/other software that doesn't supports ALSA with ZynAddSubFX, but this is a bit more complicated. 
-    	   Search on Internet for "HOWTO Use MIDI Sequencers With Softsynths" by Frank Barknecht, if you want to do this.
-
-
-    B) OSS (Open Sound System)
-       1) Launch ZynAddSubFX
-       2) Connect the MIDI keyboard 
-       
-       As you have seen the OSS option needs a real midi keyboard. If you don't have it, you can download/install ALSA from www.alsa-project.org
+Under linux there are several options for both audio output and MIDI input.
+Defaults are set at compile time and the desired backend can be set when starting ZynAddSubFX with the '-I' and '-O' options.
+The currently supported backends are:
+
+- Audio Output
+    * ALSA (Advanced Linux Sound Architecture)
+    * OSS (Open Sound System)
+    * JACK (JACK Audio Connection Kit)
+    * Port Audio
+
+- MIDI Input
+    * ALSA
+    * OSS
+    * JACK
 
 Running on WINDOWS
 ------------------
+NOTE: At this time only older versions of ZynAddSubFX were compiled on windows
+      See older versions on sf.net (ie version 2.2.1)
     If you launch zynaddsubfx.exe and nothing happens, you need pthreadGC.dll  in the same directory (or windows directory). The dll files are distribuited with ZynAddSubFX windows binaries.
     It might be possible that the latency will be very high. If this happens, you have to set the environment variable PA_MIN_LATENCY_MSEC to a value that represents the latency in miliseconds.
-	Eg: (in autoexec.bat or launched before running ZynAddSubFX) "set PA_MIN_LATENCY_MSEC=50"
+    Eg: (in autoexec.bat or launched before running ZynAddSubFX) "set PA_MIN_LATENCY_MSEC=50"
     Warning: if the value is too low, you might encounter severe dropouts on ZynAddSubFX. You'll have to set to a higher value and turn off automated background tasks (like virus scanners, email clients, etc.).
     If you have more cards, you can select the desired card where you can play audio with the environment variable "PA_RECOMMENDED_OUTPUT_DEVICE"
-	Eg: "set PA_RECOMMENDED_OUTPUT_DEVICE=1"
+    Eg: "set PA_RECOMMENDED_OUTPUT_DEVICE=1"
     A better way to set all of this, I will put on next versions.
 
+
 Please send me instruments,banks,master settings,songs(midi+...xmz files) done with ZynAddSubFX. I'll appreciate this.
 
 
diff --git a/ZynAddSubFX.lsm b/ZynAddSubFX.lsm
index 80920c1..0432298 100644
--- a/ZynAddSubFX.lsm
+++ b/ZynAddSubFX.lsm
@@ -1,22 +1,22 @@
 Begin4
 Title:		ZynAddSubFX 
-Version: 	2.4.0
-Entered-date: 	16-07-2009
-Description: 	A real-time software synthesizer for Linux and Windows with many 
+Version: 	2.2.1
+Entered-date: 	28-04-2005
+Description: 	A real-time software synthesizer for Linux with many 
 		features, including polyphony, multi-timbral and microtonal 
 		capabilities. It includes randomness of some parameters,which 
 		makes warm sounds, like analogue synthesizers.
 		The program has system/insertion effects, too.
 		ZynAddSubFX has much more features, don't let be cheated by
 		the size of the source code :) 
-Keywords: 	synthesizer,MIDI,ALSA,music,X11,microtonal,real-time,windows
-Author:		zynaddsubfx at yahoo.com (Nasca Paul) and others
-Maintained-by: 	zynaddsubfx at yahoo.com (Nasca Paul) and others
+Keywords: 	synthesizer,MIDI,ALSA,music,X11,microtonal,real-time
+Author:		zynaddsubfx at yahoo.com (Nasca Paul)
+Maintained-by: 	zynaddsubfx at yahoo.com (Nasca Paul)
 Primary-site: 	zynaddsubfx.sourceforge.net
 		sourceforge.net/projects/zynaddsubfx
-		920k ZynAddSubFX-2.4.0.tar.bz2  (source code)
+		920k ZynAddSubFX-2.2.0.tar.bz2  (source code)
 Alternate-site: 
 Original-site:
-Platforms: 	Linux with X11 or Windows
-Copying-policy: GNU General Public License (version 2 or later)
+Platforms: 	Linux with X11
+Copying-policy: GNU General Public License (version 2)
 End
diff --git a/banks/William_Godfrey_Collection/0078-Ghost Whistle.xiz b/banks/William_Godfrey_Collection/0078-Ghost Whistle.xiz
deleted file mode 100644
index 9b8c13f..0000000
Binary files a/banks/William_Godfrey_Collection/0078-Ghost Whistle.xiz and /dev/null differ
diff --git a/banks/William_Godfrey_Collection/0100-Far Reed.xiz b/banks/William_Godfrey_Collection/0100-Far Reed.xiz
deleted file mode 100644
index 9f41c3a..0000000
Binary files a/banks/William_Godfrey_Collection/0100-Far Reed.xiz and /dev/null differ
diff --git a/banks/William_Godfrey_Collection/0150-Full Choir.xiz b/banks/William_Godfrey_Collection/0150-Full Choir.xiz
deleted file mode 100644
index 86dfda6..0000000
Binary files a/banks/William_Godfrey_Collection/0150-Full Choir.xiz and /dev/null differ
diff --git a/bugs.txt b/bugs.txt
index 8b13789..e69de29 100644
--- a/bugs.txt
+++ b/bugs.txt
@@ -1 +0,0 @@
-
diff --git a/cmake/FindAlsa.cmake b/cmake/FindAlsa.cmake
new file mode 100644
index 0000000..23003b3
--- /dev/null
+++ b/cmake/FindAlsa.cmake
@@ -0,0 +1,69 @@
+# Alsa check, based on libkmid/configure.in.in.
+# Only the support for Alsa >= 0.9.x was included; 0.5.x was dropped (but feel free to re-add it if you need it)
+# It defines ...
+# It offers the following macros:
+#  ALSA_CONFIGURE_FILE(config_header) - generate a config.h, typical usage: 
+#                                       ALSA_CONFIGURE_FILE(${CMAKE_BINARY_DIR}/config-alsa.h)
+#  ALSA_VERSION_STRING(version_string)  looks for alsa/version.h and reads the version string into
+#                                       the first argument passed to the macro
+
+# Copyright (c) 2006, David Faure, <faure at kde.org>
+# Copyright (c) 2007, Matthias Kretz <kretz at kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+include(CheckIncludeFiles)
+include(CheckIncludeFileCXX)
+include(CheckLibraryExists)
+
+# Already done by toplevel
+find_library(ASOUND_LIBRARY asound)
+set(ASOUND_LIBRARY_DIR "")
+if(ASOUND_LIBRARY)
+   get_filename_component(ASOUND_LIBRARY_DIR ${ASOUND_LIBRARY} PATH)
+endif(ASOUND_LIBRARY)
+
+check_library_exists(asound snd_seq_create_simple_port "${ASOUND_LIBRARY_DIR}" HAVE_LIBASOUND2)
+if(HAVE_LIBASOUND2)
+    message(STATUS "Found ALSA: ${ASOUND_LIBRARY}")
+else(HAVE_LIBASOUND2)
+    message(STATUS "ALSA not found")
+endif(HAVE_LIBASOUND2)
+set(ALSA_FOUND ${HAVE_LIBASOUND2})
+
+find_path(ALSA_INCLUDES alsa/version.h)
+
+macro(ALSA_VERSION_STRING _result)
+    # check for version in alsa/version.h
+    if(ALSA_INCLUDES)
+        file(READ "${ALSA_INCLUDES}/alsa/version.h" _ALSA_VERSION_CONTENT)
+        string(REGEX REPLACE ".*SND_LIB_VERSION_STR.*\"(.*)\".*" "\\1" ${_result} ${_ALSA_VERSION_CONTENT})
+    else(ALSA_INCLUDES)
+        message(STATUS "ALSA version not known. ALSA output will probably not work correctly.")
+    endif(ALSA_INCLUDES)
+endmacro(ALSA_VERSION_STRING _result)
+
+
+get_filename_component(_FIND_ALSA_MODULE_DIR ${CMAKE_CURRENT_LIST_FILE} PATH)
+macro(ALSA_CONFIGURE_FILE _destFile)
+    check_include_files(sys/soundcard.h HAVE_SYS_SOUNDCARD_H)
+    check_include_files(machine/soundcard.h HAVE_MACHINE_SOUNDCARD_H)
+
+    check_include_files(linux/awe_voice.h HAVE_LINUX_AWE_VOICE_H)
+    check_include_files(awe_voice.h HAVE_AWE_VOICE_H)
+    check_include_files(/usr/src/sys/i386/isa/sound/awe_voice.h HAVE__USR_SRC_SYS_I386_ISA_SOUND_AWE_VOICE_H)
+    check_include_files(/usr/src/sys/gnu/i386/isa/sound/awe_voice.h HAVE__USR_SRC_SYS_GNU_I386_ISA_SOUND_AWE_VOICE_H)
+
+    check_include_file_cxx(sys/asoundlib.h HAVE_SYS_ASOUNDLIB_H)
+    check_include_file_cxx(alsa/asoundlib.h HAVE_ALSA_ASOUNDLIB_H)
+
+    check_library_exists(asound snd_pcm_resume "${ASOUND_LIBRARY_DIR}" ASOUND_HAS_SND_PCM_RESUME)
+    if(ASOUND_HAS_SND_PCM_RESUME)
+        set(HAVE_SND_PCM_RESUME 1)
+    endif(ASOUND_HAS_SND_PCM_RESUME)
+
+    configure_file(${_FIND_ALSA_MODULE_DIR}/config-alsa.h.cmake ${_destFile})
+endmacro(ALSA_CONFIGURE_FILE _destFile)
+
+mark_as_advanced(ALSA_INCLUDES ASOUND_LIBRARY)
diff --git a/cmake/FindJACK.cmake b/cmake/FindJACK.cmake
new file mode 100644
index 0000000..20379db
--- /dev/null
+++ b/cmake/FindJACK.cmake
@@ -0,0 +1,17 @@
+#Find JACK Audio Connection Kit
+
+include(LibFindMacros)
+libfind_pkg_check_modules(JACK jack)
+find_path(JACK_INCLUDE_DIR
+    NAMES jack/jack.h
+    PATHS ${JACK_INCLUDE_DIRS}
+    )
+
+find_library(JACK_LIBRARY
+    NAMES jack
+    PATHS ${JACK_LIBRARY_DIRS}
+    )
+
+set(JACK_PROCESS_INCLUDES JACK_INCLUDE_DIR)
+set(JACK_PROCESS_LIBS JACK_LIBRARY)
+libfind_process(JACK)
diff --git a/cmake/FindMYFLTK.cmake b/cmake/FindMYFLTK.cmake
new file mode 100644
index 0000000..5257112
--- /dev/null
+++ b/cmake/FindMYFLTK.cmake
@@ -0,0 +1,49 @@
+# The CMake supplied FindFLTK delivers FLTK_LIBRARIES as a full list of
+# static and shared libs, with full paths. We really want just a list of
+# the lib names. This slight perversion defines
+#  MYFLTK_FOUND       true or false
+#  MYFLTK_CONFIG      fltk-config executable
+#  FLTK_FLUID_EXECUTABLE    fluid executable
+#  MYFLTK_LDFLAGS   a list of libs required for linking
+#
+
+if (MYFLTK_LDFLAGS)
+  # in cache already
+  set(MYFLTK_FOUND TRUE)
+else (MYFLTK_LDFLAGS)
+    find_program (MYFLTK_CONFIG fltk-config)
+    if (MYFLTK_CONFIG)
+        execute_process (COMMAND ${MYFLTK_CONFIG} --ldflags OUTPUT_VARIABLE MYFLTK_LDFLAGS)
+    message("MYFLTK_LDFLAGS: ${MYFLTK_LDFLAGS}")
+    string(STRIP ${MYFLTK_LDFLAGS} MYFLTK_LIBS)
+    message("MYFLTK_LIBS: ${MYFLTK_LIBS}")
+    string(REPLACE "-l" "" MYFLTK_LIBS ${MYFLTK_LIBS})
+    message("MYFLTK_LIBS: ${MYFLTK_LIBS}")
+    string(REPLACE " " "; " MYFLTK_LIBS ${MYFLTK_LIBS})
+    message("MYFLTK_LINK_LIBS: ${MYFLTK_LINK_LIBS}")
+    #list(APPEND MYFLTK_LIBS ${MYFLTK_LINK_LIBS})
+    message("MYFLTK_LIBS: ${MYFLTK_LIBS}")
+    find_program (FLTK_FLUID_EXECUTABLE fluid)
+        if (FLTK_FLUID_EXECUTABLE)
+#            mark_as_advanced(MYFLTK_CONFIG)
+#            mark_as_advanced(FLTK_EXECUTABLE)
+#            mark_as_advanced(MYFLTK_LIBRARIES)
+            set(MYFLTK_FOUND TRUE)
+            set(FLTK_WRAP_UI 1)
+        endif(FLTK_FLUID_EXECUTABLE)
+    endif (MYFLTK_CONFIG)
+endif (MYFLTK_LDFLAGS)
+
+# message("MYFLTK_LDFLAGS: ${MYFLTK_LDFLAGS}")
+# message("FLTK_WRAP_UI: ${FLTK_WRAP_UI}")
+
+if (MYFLTK_FOUND)
+    if (NOT MYFLTK_FIND_QUIETLY)
+        message(STATUS "found ${MYFLTK_CONFIG}")
+        # message(STATUS "found ${FLTK_FLUID_EXECUTABLE}")
+    endif (NOT MYFLTK_FIND_QUIETLY)
+else (MYFLTK_FOUND)
+    if (MYFLTK_FIND_REQUIRED)
+      message(FATAL_ERROR "could not find MYFLTK, aborting.")
+    endif (MYFLTK_FIND_REQUIRED)
+endif (MYFLTK_FOUND)
diff --git a/cmake/FindOSS.cmake b/cmake/FindOSS.cmake
new file mode 100644
index 0000000..319c90e
--- /dev/null
+++ b/cmake/FindOSS.cmake
@@ -0,0 +1,9 @@
+# Find OSS (Open Sound System)
+find_path(OSS_INCLUDE_DIR sys/soundcard.h)
+set(OSS_LIBRARIES True)
+mark_as_advanced(OSS_INCLUDE_DIR)
+
+# handle the QUIETLY and REQUIRED arguments and set OSS_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(OSS DEFAULT_MSG OSS_LIBRARIES OSS_INCLUDE_DIR)
diff --git a/cmake/Findzlib.cmake b/cmake/Findzlib.cmake
new file mode 100644
index 0000000..49edafd
--- /dev/null
+++ b/cmake/Findzlib.cmake
@@ -0,0 +1,39 @@
+# - Find zlib
+# Find the native ZLIB includes and library
+#
+#  ZLIB_INCLUDE_DIRS - where to find zlib.h, etc.
+#  ZLIB_LIBRARIES    - List of libraries when using zlib.
+#  ZLIB_FOUND        - True if zlib found.
+
+#=============================================================================
+# Copyright 2001-2009 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distributed this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+IF (ZLIB_INCLUDE_DIR)
+  # Already in cache, be silent
+  SET(ZLIB_FIND_QUIETLY TRUE)
+ENDIF (ZLIB_INCLUDE_DIR)
+
+FIND_PATH(ZLIB_INCLUDE_DIR zlib.h)
+
+SET(ZLIB_NAMES z zlib zdll)
+FIND_LIBRARY(ZLIB_LIBRARY NAMES ${ZLIB_NAMES} )
+MARK_AS_ADVANCED( ZLIB_LIBRARY ZLIB_INCLUDE_DIR )
+
+# Per-recommendation
+SET(ZLIB_INCLUDE_DIRS "${ZLIB_INCLUDE_DIR}")
+SET(ZLIB_LIBRARIES    "${ZLIB_LIBRARY}")
+
+# handle the QUIETLY and REQUIRED arguments and set ZLIB_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZLIB DEFAULT_MSG ZLIB_LIBRARIES ZLIB_INCLUDE_DIRS)
diff --git a/compile.win32 b/compile.win32
deleted file mode 100644
index c21617d..0000000
--- a/compile.win32
+++ /dev/null
@@ -1,40 +0,0 @@
-ZynAddSubFX Compilation on Windows as standalone .EXE
------------------------------------------------------
-You don't have to compile it, there are Windows binaries available on the webpage.
-Anyway if you want to compile, good luck :)
-
-First, you have to download and install Mingw and MSYS (www.mingw.org). Download the FLTK sources (www.fltk.org), compile and install.
-Second, you have to download, compile and install pthreads for windows (http://sources.redhat.com/pthreads-win32). You need to compile in GC mode.
-Also, you have to compile the portaudio library (www.portaudio.com). It it doesn't install itself, and you must copy the header files to the "include" directories from mingw(msys) and compiled libraries to the "lib" directory from mingw.
-You need zlib and mxml-2.0.
-
-In short, the dependencies directories are (but some version might differ):
-MinGW-3.1.0-1.exe
-MSYS-1.0.10.exe
-fftw-3.0.1.tar.gz
-fltk-1.1.5rc2-source.tar.bz2
-mxml-2.0.tar.gz
-portaudio_v18_1.zip
-pthreads-2004-06-22.exe
-zlib-1.2.1.tar.bz2
-
-
-Change the Makefile.inc, and change the compilation options (like operating system,etc.). Now, run make from msys.
-After the compilation, copy in the dll files (pthreadGC.dll and (portaudio.dll if required)) to the directory where "zynaddsubfx.exe" is.
-Hope all goes right.
-
-ZynAddSubFX Compilation on Windows as VST plugin (dll file)
-----------------------------------------------------------
-Edit the Makefile.inc and set "WINDOWS_VST" to "YES". The audioout and midiin are automatically set to VST.
-Get the vstsdk2 (or 2.3) and copy it to the directory where ZynAddSubFX-2.x.x is.
-If you copy ZynAddSubFX in "C:\temp" and you will run "dir" you should see the ZynAddSubFX-2.x.x and "vstsdk2" in the same directory (C:\temp).
-
-Run the makefile. Hope all will goes right. Please notice that "make clean" removes the vst object files that you compiled form vstsdk2. That's why is recommended to keep a backup copy of these object files.
-You must copy the pthreads.dll file to windows directory (or else, ZynAddSubFX will not work). Btw: how can I make pthreads static?
-Copy the zynaddsubfx_vst.dll to your dll directory.
-
-BUGS only on vst port:
-Also, to avoid more bugs, I had limited ZynAddSubFX to one instance. Please report me how it behaves on various vst hosts.
-I hope that I will remove these bugs on later versions.
-
-
diff --git a/doc/Doxyfile b/doc/Doxyfile
new file mode 100644
index 0000000..f48cdff
--- /dev/null
+++ b/doc/Doxyfile
@@ -0,0 +1,309 @@
+# Doxyfile 1.5.7
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+DOXYFILE_ENCODING      = UTF-8
+PROJECT_NAME           = ZynAddSubFX
+PROJECT_NUMBER         = 2.3.0
+OUTPUT_DIRECTORY       = /home/mark/zynaddsubfx/doc/dox2/
+CREATE_SUBDIRS         = NO
+OUTPUT_LANGUAGE        = English
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = YES
+FULL_PATH_NAMES        = YES
+STRIP_FROM_PATH        = /home/mark/zynaddsubfx/src/
+STRIP_FROM_INC_PATH    = 
+SHORT_NAMES            = NO
+JAVADOC_AUTOBRIEF      = NO
+QT_AUTOBRIEF           = NO
+MULTILINE_CPP_IS_BRIEF = NO
+INHERIT_DOCS           = YES
+SEPARATE_MEMBER_PAGES  = NO
+TAB_SIZE               = 5
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = NO
+OPTIMIZE_OUTPUT_JAVA   = NO
+OPTIMIZE_FOR_FORTRAN   = NO
+OPTIMIZE_OUTPUT_VHDL   = NO
+BUILTIN_STL_SUPPORT    = NO
+CPP_CLI_SUPPORT        = NO
+SIP_SUPPORT            = NO
+IDL_PROPERTY_SUPPORT   = YES
+DISTRIBUTE_GROUP_DOC   = NO
+SUBGROUPING            = YES
+TYPEDEF_HIDES_STRUCT   = NO
+SYMBOL_CACHE_SIZE      = 0
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = NO
+EXTRACT_PRIVATE        = NO
+EXTRACT_STATIC         = NO
+EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_METHODS  = NO
+EXTRACT_ANON_NSPACES   = NO
+HIDE_UNDOC_MEMBERS     = YES
+HIDE_UNDOC_CLASSES     = YES
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = NO
+CASE_SENSE_NAMES       = YES
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = NO
+SORT_GROUP_NAMES       = NO
+SORT_BY_SCOPE_NAME     = NO
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES
+SHOW_DIRECTORIES       = NO
+SHOW_FILES             = YES
+SHOW_NAMESPACES        = YES
+FILE_VERSION_FILTER    = 
+LAYOUT_FILE            = 
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_NO_PARAMDOC       = NO
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = 
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = /home/mark/zynaddsubfx/src/
+INPUT_ENCODING         = UTF-8
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.d \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.idl \
+                         *.odl \
+                         *.cs \
+                         *.php \
+                         *.php3 \
+                         *.inc \
+                         *.m \
+                         *.mm \
+                         *.dox \
+                         *.py \
+                         *.f90 \
+                         *.f \
+                         *.vhd \
+                         *.vhdl \
+                         *.C \
+                         *.CC \
+                         *.C++ \
+                         *.II \
+                         *.I++ \
+                         *.H \
+                         *.HH \
+                         *.H++ \
+                         *.CS \
+                         *.PHP \
+                         *.PHP3 \
+                         *.M \
+                         *.MM \
+                         *.PY \
+                         *.F90 \
+                         *.F \
+                         *.VHD \
+                         *.VHDL
+RECURSIVE              = YES
+EXCLUDE                = 
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = 
+EXCLUDE_SYMBOLS        = 
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = *
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_PATTERNS        = 
+FILTER_SOURCE_FILES    = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = NO
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION    = NO
+REFERENCES_LINK_SOURCE = YES
+USE_HTAGS              = NO
+VERBATIM_HEADERS       = NO
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+COLS_IN_ALPHA_INDEX    = 5
+IGNORE_PREFIX          = 
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = YES
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = 
+HTML_FOOTER            = 
+HTML_STYLESHEET        = 
+HTML_ALIGN_MEMBERS     = YES
+HTML_DYNAMIC_SECTIONS  = NO
+GENERATE_DOCSET        = NO
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+CHM_INDEX_ENCODING     = 
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+GENERATE_QHP           = NO
+QCH_FILE               = 
+QHP_NAMESPACE          = org.doxygen.Project
+QHP_VIRTUAL_FOLDER     = doc
+QHG_LOCATION           = 
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = NONE
+TREEVIEW_WIDTH         = 250
+FORMULA_FONTSIZE       = 10
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = NO
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = YES
+USE_PDFLATEX           = YES
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = NO
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = YES
+INCLUDE_PATH           = 
+INCLUDE_FILE_PATTERNS  = 
+PREDEFINED             = 
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+TAGFILES               = 
+GENERATE_TAGFILE       = 
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = NO
+MSCGEN_PATH            = 
+HIDE_UNDOC_RELATIONS   = YES
+HAVE_DOT               = YES
+DOT_FONTNAME           = FreeSans
+DOT_FONTPATH           = 
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+GROUP_GRAPHS           = YES
+UML_LOOK               = YES
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = YES
+CALLER_GRAPH           = NO
+GRAPHICAL_HIERARCHY    = YES
+DIRECTORY_GRAPH        = YES
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+DOTFILE_DIRS           = 
+DOT_GRAPH_MAX_NODES    = 50
+MAX_DOT_GRAPH_DEPTH    = 1000
+DOT_TRANSPARENT        = NO
+DOT_MULTI_TARGETS      = NO
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+SEARCHENGINE           = NO
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 0000000..3ebc2e5
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,40 @@
+
+.PHONY: subdirs gen
+
+all: gen-files man xhtml chunked pdf
+
+gen-files:
+	cd gen; make
+
+
+xhtml: zynaddsubfx.txt envelope.txt intro.txt lfo.txt
+	asciidoc -a numbered -a toc -b html5 \
+		zynaddsubfx.txt
+
+chunked:
+	asciidoc --doctype=article   -b docbook \
+	          zynaddsubfx.txt
+	rm -rf ./zynaddsubfx.chunked
+	mkdir ./zynaddsubfx.chunked
+	rm -f "./zynaddsubfx.chunked/*.html"
+	ln -s ../images/ zynaddsubfx.chunked/images
+	xsltproc --stringparam html.stylesheet "./docbook-xsl.css" \
+	         --stringparam callout.graphics 0 \
+		 --stringparam navig.graphics 0 \
+		 --stringparam admon.textlabel 1 \
+		 --stringparam admon.graphics 0 \
+		 --nonet \
+	         --stringparam base.dir "zynaddsubfx.chunked/" \
+	         "/etc/asciidoc/docbook-xsl/chunked.xsl" \
+		 "./zynaddsubfx.xml" \
+
+pdf:
+	a2x -f pdf zynaddsubfx.txt
+
+man: zynaddsubfx.1.txt
+	a2x -f manpage zynaddsubfx.1.txt
+
+clean:
+	rm -f *~ *html *pdf *xml *tex *log zynaddsubfx.chunked/images
+	rm -r -f zynaddsubfx.chunked/
+
diff --git a/doc/adsynth.txt b/doc/adsynth.txt
new file mode 100644
index 0000000..7fdce6e
--- /dev/null
+++ b/doc/adsynth.txt
@@ -0,0 +1,80 @@
+AdSynth
+-------
+
+AdSynth, a primarily additive synthesis engine, is one of the three major
+synthesis engines available in ZynAddSubFX.
+The basic concept of this engine is the summation of a collection of voices,
+each of which consist of oscillators.
+
+High Level (Global)
+~~~~~~~~~~~~~~~~~~~
+
+AdSynth's global level consists of the elements shown in the below figure:
+
+.AdSynth Global Elements
+image::gen/ad-note.png[scalewidth="50%",width="700"]
+
+The global level of adsynth is almost entirely composed of previously discussed
+elements.
+However a few new features appear here, this includes velocity sensing, punch,
+detune options and realative bandwidth , and resonance.
+
+.AdSynth Global Window
+image::images/ad-global.png[]
+
+
+Velocity sensing is simply an exponental transformation from the note's velocity
+to some parameter change.
+The below diagram shows how the velocity senseing controls affects this
+translation over the whole range of possible note velocities.
+
+.Velocity Sensing Chart
+image::gen/velf.png[scalewidth="50%",width="600"]
+
+The puch of a note in AdSynth is a constant amplification to the output at the
+start of the note, with its length determined by the punch time and stretch and
+the amplitude being determined by the punch strength and velocity sensing.
+The relBW control in the frequency pane is effectively a multiplier for detuning
+all voices within an adnote.
+
+NOTE: TODO Talk about resonance
+
+
+The sum of the voices are passed through filters and amplification to produce
+the final sound.
+This could lead one to think that ad-note is just a bunch of minor
+postprocessing and at this level much of the sound generation is hidden.
+
+Voices
+~~~~~~
+
+The voice gives access to a similar setup to the global parameters and then some
+more, such as the modulator, oscillator, and unison features.
+
+.AdSynth Voice Window
+image::images/ad-voice.png[]
+
+Modulation
+^^^^^^^^^^
+
+Within the options for modulation, one can select:
+
+* Morph
+* Ring Modulation
+* Phase Modulation
+* Frequency Modulation
+* Disabled
+
+Unison
+^^^^^^
+
+Unison is useful in creating the chorus like sound of many simultaneous
+oscillators
+
+Oscillator
+~~~~~~~~~~
+
+NOTE: TODO show waveforms, talk about distortions somewhere, etc
+
+.Oscillator Window
+image::images/uioscil.png[]
diff --git a/doc/build.txt b/doc/build.txt
new file mode 100644
index 0000000..35de26a
--- /dev/null
+++ b/doc/build.txt
@@ -0,0 +1,59 @@
+Appendix B: Building ZynAddSubFX
+--------------------------------
+
+Introduction to CMake
+~~~~~~~~~~~~~~~~~~~~~
+
+********************************************************************
+Note: This section is mostly copied from the OpenSceneGraph wiki, at:
+http://www.openscenegraph.org/projects/osg/wiki/Build/CMake
+********************************************************************
+
+ZynAddSubFX uses CMake as its unified build system. CMake
+is able to read simple build scripts from the source tree and create
+from this a platform-specific build system. This build system can be in
+the form of VisualStudio project files, Unix Makefiles or XCode project
+files. CMake is able to automatically locate external dependencies, and
+allows you to toggle on/off module compilation and configure various
+build options.
+
+The use of a unified build system has allowed to avoid build breakages
+that were common in the previous build method of maintaining three
+separate build targets for VisualStudio, Unix "make" and XCode. It also
+reduces the maintenance burden for core developers and contributors.
+Taken together usage of CMake should result in better consistency and
+more stable builds across all platforms for end users and a greater
+productivity in development of new versions. Hopefully with greater
+consistency of builds across platforms it will be easier for developers
+to use the development version of ZynAddSubFX and help contribute
+to its testing and refinement, leading to a high-quality code base.
+
+Quick start guide
+~~~~~~~~~~~~~~~~~
+
+For the impatient ones, here is a quick guide on how to immediately
+build ZynAddSubFX from source.
+
+**************************************************************
+Note: This assumes that you already have a copy of the source.
+**************************************************************
+
+---------------------------------
+#enter the source directory
+cd zynaddsubfx
+
+#make a directory for an out-of-source build
+mkdir build
+cd build
+
+#generate a cmake build project here from the cmake root, which is
+#found in the directory below the current one
+cmake ..
+
+#OPTIONAL: Adjust compile variables in the Cache file:
+ccmake .
+
+#And finally, build as usual using make
+make
+---------------------------------
+
diff --git a/doc/controller.txt b/doc/controller.txt
new file mode 100644
index 0000000..8035565
--- /dev/null
+++ b/doc/controller.txt
@@ -0,0 +1,54 @@
+Controller
+---------
+
+image::./images/uicontroller.png[]
+
+General
+~~~~~~~
+
+* *ModWh*: Modullation Wheel depth
+* *Exp MWh*: Exponental Modulation Wheel (changes modulation scale to
+             exponental)
+* *BwDpth*: Bandwidth Depth
+* *Exp BW*: Exponental Bandwidth (changes badwidth scale to exponental)
+* *PanDpth*: Panning Depth
+* *FltQ*: Filter Q (ressonance) depth
+* *FltCut* Filter Cutoff frequency depth
+* *Expr*: enable/disable expression
+* *Vol*: enable/disable receiving volume controller
+* *FMamp*: enable/disable receiving Modulation Amplitude controller (76)
+* *Sustain*: enable/disable sustain pedal
+* *PWheelB.Rng (cents)*: Pitch Wheel Bend Range (cents; 100 cents = 1 halftone)
+
+Portamento
+~~~~~~~~~~
+
+* *Rcv.*: If the part receives portamento On/Off (65) controller
+* *time*: The duration of the portamento
+* *thresh*: The threshold of the portamento.
+It represents the minimum or the maximum number of halftones
+(or hundried cents) required to start the portamento. 
+The difference is computed between the last note and current note.
+* *th.type*: The threshold type.
+Checked means that the portamento activates when the difference of frequencies
+is above the threshold ("thresh"); not checked is for below the threshold.
+
+NOTE: The threshold refers to the frequencies and not to MIDI notes
+      (you should consider this if you use microtonal scales).
+
+
+Proportinal Portamento
+^^^^^^^^^^^^^^^^^^^^^^
+////
+TODO: add graphs to explain prp.rate and prp. depth
+////
+
+* *Propt.*: If the portamento is proportinal to ratio of frequencies
+* *Prp. Rate*: Ratio needed to double the time of portamento
+* *Prp. Dpth*: The divergence from 
+
+Resonance
+~~~~~~~~~
+
+* *CFdpth*: resonance center controller depth
+* *BWdpth*: resonance bandwidth controller depth 
diff --git a/doc/effects.txt b/doc/effects.txt
new file mode 100644
index 0000000..f13bb8a
--- /dev/null
+++ b/doc/effects.txt
@@ -0,0 +1,27 @@
+Effects
+-------
+
+Chorus
+~~~~~~
+
+image::./gen/chorus.png[width="700"]
+
+Distort
+~~~~~~~
+
+image::./gen/distort.png[width="700"]
+
+Dynamic Filter
+~~~~~~~~~~~~~
+
+image::./gen/dynamic.png[width="700"]
+
+Echo
+~~~~
+
+image::./gen/echo.png[width="700"]
+
+Reverb
+~~~~~~
+
+image::./gen/reverb.png[width="700"]
diff --git a/doc/envelope.txt b/doc/envelope.txt
new file mode 100644
index 0000000..157843e
--- /dev/null
+++ b/doc/envelope.txt
@@ -0,0 +1,131 @@
+Envelopes
+---------
+
+Introduction
+~~~~~~~~~~~~
+Envelopes control how the amplitude, the frequency, or the
+filter changes over time.
+
+Amplitude Envelopes
+~~~~~~~~~~~~~~~~~~~
+
+These envelopes controls the amplitude of the sound.
+In ZynAddSubFX, amplitude envelopes can be linear or logarithmic. 
+In the next image, it is shown the differences between these envelopes. 
+
+image::images/envelope1.png[Alt text]
+
+The amplitude envelope is divided into:
+
+* *Attack*: Begins at the Note On. The volume starts from 0 to the maximum.
+In ZynAddSubFX, the attack is always linear.
+* *Decay*: The volume drops from the maximum value to a level called "Sustain level"
+* *Sustain*: The volume remains constant until the key is depressed (Note Off).
+After this, the last stage take place.
+* *Release*: The volume drops to zero
+
+
+Frequency Envelopes
+~~~~~~~~~~~~~~~~~~~
+
+These envelopes controls the frequency (more exactly, the pitch) of
+the oscillators.
+The following picture draws the stages of these envelopes.
+
+image::images/envelope2.png[Alt text]
+
+The dotted line represents the real pitch of the sound without the
+envelope.
+
+The frequency envelopes are divided into 3 stages:
+
+* *Attack*: Begins at the Note On. The frequency starts from a certain value and
+glides to the real frequency of the note.
+* *Sustain*: The frequency is the same on over the sustain period 
+* *Release*: This stage begins on Note Off and glides the frequency of the note
+to a certain
+value
+
+Filter Envelopes
+~~~~~~~~~~~~~~~~
+These envelopes controls the cutoff frequency of the filters and are divided
+into
+
+image:images/envelope3.png[Alt Text]
+
+* *Attack*: Begins at the Note On. The cutoff frequency starts from a certain value and glides to another value
+* *Decay*: The cutoff frequency continues to glide to the real cutoff frequency value of the filter (dotted line)
+* *Sustain*: the cutoff frequency is the same on over the sustain period (dotted line)
+* *Release*: this stage begins on Note Off and glides the filter cutoff frequency of the note to a certain value 
+
+Freemode Envelopes
+~~~~~~~~~~~~~~~~~~
+
+For all envelope there is a mode that allows the user to set an arbitrary number of stages and control points. This mode is called Freemode.
+
+image:images/envelope4.png[Alt Text]
+
+Only stage that always remains defined is the Sustain, where the envelopes freezes until a Note Off event.
+
+User Interface
+~~~~~~~~~~~~~~
+All the envelope types has some common controls:
+
+* *E*: Shows a window that you can view the real envelope shape or convert to free mode to edit it
+* *Stretch*: How the envelope is stretched according the note.
+On the higher notes the envelopes are shorter than lower notes.
+In the leftmost value, the stretch is zero.
+The rightmost use a stretch of 200%; this means that the envelope is stretched about 4 times/octave.
+* *frcR*: Forced release.
+This means that if this option is turned on, the release will go to the final value, even if the sustain stage is not reached. Usually, this must be set.
+
+
+The parameters for Amplitude Envelopes for ZynAddSubFX are:
+
+image:images/uienvelope3.jpg[Alt Text]
+
+* *A.dt*: Attack duration
+* *D.dt*: Decay duration
+* *S.Val*: Sustain value
+* *R.dt*: Release time
+* *L*: If this option is set, the envelope is linear, otherwise, it will be
+logarithmic
+
+
+For Frequency Envelopes the interface has the following parameters:
+
+image:images/uienvelope2.jpg[Alt Text]
+
+* *A.val*: Attack value
+* *A.dt*: Attack duration
+* *R.dt*: Release time
+* *R.val*: Release value
+
+
+Filter Envelopes has the parameters:
+
+image:images/uienvelope1.jpg[Alt Text]
+
+* *A.val*: Attack value
+* *A.dt*: Attack duration
+* *D.val*: Decay value
+* *D.dt*: Decay time
+* *R.dt*: Release time
+* *R.val*: Release value
+
+The Freemode envelopes has a separate window to set the parameters and controls:
+
+image:images/uienvelope0.jpg[]
+
+*  *Control points*: You can move the points using the mouse.
+In the right on the windows, it is shown the total duration of the envelope.
+If the mouse button will be pressed on a control point, it will be shown the
+duration of the stage where the point is.
+* *FreeMode*: this button activates or deactivates the freemode mode.
+* *Add Point*: Adds the point next to the current selected point.
+You can select a point by clicking on it.
+* *Delete point*: Removes the point from the envelope.
+* *Sust.*: Set the sustain point. It is shown using the yellow line.
+* *Str.*: Envelope stretch
+
+
diff --git a/doc/filter.txt b/doc/filter.txt
new file mode 100644
index 0000000..f91502d
--- /dev/null
+++ b/doc/filter.txt
@@ -0,0 +1,34 @@
+Filters
+-------
+:Author: Mark McCurry
+:Date: July 5, 2009
+
+In ZynAddSubFX filters can be used at several different stages to
+increase or decrease a defined set of frequencys.
+
+Types
+~~~~~
+
+ZynAddSubFX currently supports a wide set of filters that it can provide
+
+image:images/filter0.png[]
+
+Values
+~~~~~~
+
+Each of these filters will be affected by their Q values, number of poles, and
+cutoff values.
+
+The folowing diagram shows the frequency response under different Q values:
+
+image:images/filter1.png[]
+
+The folowing diagram shows the frequency response under a different number of
+poles:
+
+image:images/filter2.png[]
+
+User Interface
+~~~~~~~~~~~~~~
+
+A picture of the UI will go here
diff --git a/doc/gen/Makefile b/doc/gen/Makefile
new file mode 100644
index 0000000..246441c
--- /dev/null
+++ b/doc/gen/Makefile
@@ -0,0 +1,14 @@
+SOURCES=velf.tex ad-note.tex echo.tex distort.tex dynamic.tex reverb.tex chorus.tex
+OBJECTS=$(SOURCES:.tex=.png)
+
+all:$(OBJECTS)
+
+%.png: %.tex
+	pdflatex -shell-escape $<
+	convert -trim -density 300 $(<:.tex=.pdf) $@
+	rm -f $(<:.tex=.pdf) $(<:.tex=.log) $(<:.tex=.aux) $(<:.tex=-pic*) $(<:.tex=.pgf-plot*)
+
+.PHONY: clean
+clean:
+	rm -f *.png *~ *.aux *.auxlock *.table *.log *.gnuplot *.dpth *.dep
+
diff --git a/doc/gen/ad-note.tex b/doc/gen/ad-note.tex
new file mode 100644
index 0000000..4dd3f3c
--- /dev/null
+++ b/doc/gen/ad-note.tex
@@ -0,0 +1,37 @@
+\documentclass{standalone}
+\usepackage{tikz}
+\usetikzlibrary{matrix,shapes,chains,scopes}
+\begin{document}
+\input{fig.sty}
+\begin{tikzpicture}
+    \matrix (mtx) [matrix of nodes, row sep=5mm, column sep=5mm] {
+    &
+    |[lfo]| Freq LFO   &
+    |[lfo]| Filter LFO &
+    |[lfo]| Amp LFO    &
+    &\\
+    |[block]| Base Fq. &
+    |[block]| Voices   &
+    |[block]| Filter   &
+    |[block, shape=isosceles triangle]| Volume &
+    {Output} \\
+    &
+    |[env]| Freq Env&
+    |[env]| Filter Env&
+    |[env]| Amp Env&\\
+    };
+
+    { [start chain=trunk]
+    \chainin (mtx-2-1)[join=by tip];
+    \chainin (mtx-2-2)[join=by tip];
+    \chainin (mtx-2-3)[join=by tip];
+    \chainin (mtx-2-4)[join=by tip];
+    \chainin (mtx-2-5)[join=by tip];
+    }
+    \foreach \i in {2,3,4}
+    {
+        \draw[->] (mtx-1-\i) -- (mtx-2-\i);
+        \draw[->] (mtx-3-\i) -- (mtx-2-\i);
+    }
+\end{tikzpicture}
+\end{document}
diff --git a/doc/gen/chorus.tex b/doc/gen/chorus.tex
new file mode 100644
index 0000000..87727e3
--- /dev/null
+++ b/doc/gen/chorus.tex
@@ -0,0 +1,38 @@
+\documentclass[12pt]{report}
+\pagestyle{empty}
+\usepackage{pst-sigsys}
+\usepackage{auto-pst-pdf}
+\begin{document}
+\begin{pspicture}[showgrid=false](0,-1)(8,2)
+    %Style
+    \psset{framesize=1 .65}
+    \psset{style=Arrow}
+
+    %In/Out
+    \rput(0,0){\rnode{in}{$x[n]$}}
+    \rput(8,0){\rnode{out}{$y[n]$}}
+
+    %Crossover
+    \psfblock[framesize=2 .65](1.5,0){cross}{Crossover}
+
+    %Feedback over fractional delay
+    \pscircleop(3,0){comb}
+    \psfblock[framesize=1.2 .65](4.5,0){delay}{$z^{-n.m}$}
+    \pnode(5.5,0){decoration}
+    \pscircleop[operation=times](4,1){fb}
+    \rput(4,1.5){Feedback}
+    \ncangle[angleA=90]{decoration}{fb}
+    \ncangle[angleA=180,angleB=90]{fb}{comb}
+
+    %subtract?
+    \pscircleop[operation=times] (6,0){sub}
+    \rput(6,-0.5){Subtract}
+
+    %Panning
+    \pscircleop[operation=times] (7,0){pan}
+    \rput(7,0.5){Panning}
+
+    %Connections
+    \nclist{ncline}{in,cross,comb,delay,sub,pan,out}
+\end{pspicture}
+\end{document}
diff --git a/doc/gen/distort.tex b/doc/gen/distort.tex
new file mode 100644
index 0000000..eb6b3a9
--- /dev/null
+++ b/doc/gen/distort.tex
@@ -0,0 +1,44 @@
+\documentclass[11pt]{report}
+\pagestyle{empty}
+\usepackage{pst-sigsys}
+\usepackage{auto-pst-pdf}
+\begin{document}
+\begin{pspicture}[showgrid=false](0,-2)(10,2)
+    %Style
+    \psset{framesize=1 .65}
+    \psset{style=Arrow}
+
+    %In/Out
+    \rput(0,0){\rnode{in}{$x[n]$}}
+    \rput(9.5,0){\rnode{out}{$y[n]$}}
+
+    %Panning
+    \rput(1,0.5){Panning}
+    \pscircleop[operation=times] (1,0){pan}
+    \ncline{in}{pan}
+
+    %Preamp
+    \rput(2,-0.5){Preamp}
+    \pscircleop[operation=times] (2,0){preamp}
+    \ncline{pan}{preamp}
+    
+    %Filtering
+    \psfblock(3,0){fil1}{Filter}
+    \ncline{preamp}{fil1}
+
+    %Distortion
+    \psfblock(4.5,0){shape}{$H(n)$}
+    \ncline{fil1}{shape}
+    
+    %Filtering
+    \psfblock(6,0){fil2}{Filter}
+    \ncline{shape}{fil2}
+
+    %Crossover
+    \psfblock[framesize=1.8 .65](8,0){cross}{Crossover}
+    \ncline{fil2}{cross}
+    \ncline{cross}{out}
+
+
+\end{pspicture}
+\end{document}
diff --git a/doc/gen/dynamic.tex b/doc/gen/dynamic.tex
new file mode 100644
index 0000000..aba6330
--- /dev/null
+++ b/doc/gen/dynamic.tex
@@ -0,0 +1,46 @@
+\documentclass[11pt]{report}
+\pagestyle{empty}
+\usepackage{pst-sigsys}
+\usepackage{auto-pst-pdf}
+\begin{document}
+\begin{pspicture}[showgrid=false](0,0)(8,2)
+    %Style
+    \psset{framesize=1 .65}
+    \psset{style=Arrow}
+
+    %In/Out
+    \rput(0,0){\rnode{in}{$x[n]$}}
+    \rput(8,0){\rnode{out}{$y[n]$}}
+
+    %Smoothing
+    \psfblock(1,1){smooth}{LPF}
+    \rput(1,1.6){smooth}
+    
+    %Sensing
+    \pscircleop[operation=times](2.5,1){sense}
+    \rput(2.5,1.5){sense}
+
+    %Combine
+    \pscircleop(4,1){comb}
+
+    %Depth
+    \pscircleop[operation=times](5.5,1){depth}
+    \rput(5.5,1.5){depth}
+
+    %LFO
+    \psfblock(7,1){lfo}{LFO}
+
+    %Filter
+    \psfblock(4,0){fil}{Filter}
+    
+    %Panning
+    \pscircleop[operation=times] (5.5,0){pan}
+    \rput(5.5,-0.5){Panning}
+
+    %Connections
+    \pnode(1,0){decoration}
+    \nclist{ncline}{in,fil,pan,out}
+    \nclist{ncline}{decoration,smooth,sense,comb,fil}
+    \nclist{ncline}{lfo,depth,comb}
+\end{pspicture}
+\end{document}
diff --git a/doc/gen/echo.tex b/doc/gen/echo.tex
new file mode 100644
index 0000000..22248b4
--- /dev/null
+++ b/doc/gen/echo.tex
@@ -0,0 +1,43 @@
+\documentclass[11pt]{report}
+\pagestyle{empty}
+\usepackage{pst-sigsys}
+\usepackage{auto-pst-pdf}
+\begin{document}
+\begin{pspicture}[showgrid=false](0,0)(8,2)
+    %Style
+    \psset{framesize=1 .65}
+    \psset{style=Arrow}
+
+    %In/Out
+    \rput(0,0){\rnode{in}{$x[n]$}}
+    \rput(8,0){\rnode{out}{$y[n]$}}
+
+    %Panning
+    \rput(1,0.5){Panning}
+    \pscircleop[operation=times] (1,0){pan}
+    \ncline{in}{pan}
+
+    %Crossover
+    \psfblock[framesize=1.8 .65](6,0){cross}{Crossover}
+
+    %Feedback
+    \rput(4,1.5){Feedback}
+    \pscircleop[operation=times](4,1){fb}
+    \ncangle[angleA=90,angleB=0]{cross}{fb}
+    \pscircleop(2,0){combine}
+    \ncline{pan}{combine}
+    \ncangle[angleA=180,angleB=90]{fb}{combine}
+
+    %Dampining
+    \psfblock(3,0){hidamp}{LPF}
+    \ncline{combine}{hidamp}
+    
+    %Delay
+    \psfblock(4.3,0){delay}{$z^{-n}$}
+    \ncline{hidamp}{delay}
+    \ncline{delay}{cross}
+    \ncline{cross}{out}
+
+
+\end{pspicture}
+\end{document}
diff --git a/doc/gen/fig.sty b/doc/gen/fig.sty
new file mode 100644
index 0000000..076954a
--- /dev/null
+++ b/doc/gen/fig.sty
@@ -0,0 +1,14 @@
+\tikzset{
+>=stealth,
+thick,
+block/.style={rectangle, draw=black!50, thick,
+              top color=white,
+              bottom color=red!50!black!20,
+              font=\itshape},
+op/.style={circle, draw=black!50, thick,
+           top color=white,bottom color=black!20,
+           font=\ttfamily},
+lfo/.style={block,bottom color=orange!80},
+env/.style={block,bottom color=yellow!80},
+tip/.style={->,shorten >=1pt}
+}
diff --git a/doc/gen/reverb.tex b/doc/gen/reverb.tex
new file mode 100644
index 0000000..ead3c5f
--- /dev/null
+++ b/doc/gen/reverb.tex
@@ -0,0 +1,50 @@
+\documentclass{standalone}
+\usepackage{tikz}
+\usetikzlibrary{matrix,shapes,chains,scopes}
+\begin{document}
+\input{fig.sty}
+
+\begin{tikzpicture}[
+    point/.style={coordinate},
+    every on chain/.style={rounded corners}]
+    %Style
+
+    \matrix[row sep=5mm, column sep=5mm] {
+    &
+    \node        (fb)  {$f_b$};&
+    \node        (del) {$Delay$};
+    &&&&& \\
+    &
+    \node[op]    (pb1) {$\times$};&
+    \node[block] (pb2) {$z^{-n}$}; &
+    &&&& \\
+
+    \node           (p1) {$x[n]$}; &
+    \node[op]       (p2) {$+$}; &
+    \node[point]    (p3) {};&
+    \node[block]    (p4) {HP/LP}; &
+    \node[block]    (p5) {Comb Filter}; &
+    \node[block]    (p6) {Allpass}; &
+    \node           (p7) {$y[n]$}; \\
+    };
+
+    \draw[->] (fb) -- (pb1);
+    \draw[->] (del) -- (pb2);
+    { [start chain=trunk]
+    \chainin (p1)[join=by tip];
+    \chainin (p2)[join=by tip] ;
+    \chainin (p3)[join=by {}];
+    %\chainin[join by={}] (p3);
+    { [start branch]
+    \chainin (pb2)[join=by tip];
+    \chainin (pb1)[join=by tip];
+    \chainin (p2)[join=by tip];
+    }
+    \chainin (p4)[join=by tip];
+    \chainin (p5)[join=by tip];
+    \chainin (p6)[join=by tip];
+    \chainin (p7)[join=by tip];
+    }
+
+\end{tikzpicture}
+\end{document}
diff --git a/doc/gen/velf.tex b/doc/gen/velf.tex
new file mode 100644
index 0000000..6388442
--- /dev/null
+++ b/doc/gen/velf.tex
@@ -0,0 +1,16 @@
+\documentclass{standalone}
+\usepackage{tikz,pgfplots}
+\begin{document}
+\begin{tikzpicture}
+    \begin{axis}[domain=0:1,samples=128,no markers,
+        xlabel=Note Velocity,ylabel=Param Magnitude,
+       legend style={ cells={anchor=east}, legend pos=outer north east}]
+        \addplot gnuplot{x^8^1};
+        \addlegendentry{max sensing}
+        \addplot gnuplot{x^(8^-1)};
+        \addlegendentry{min sensing}
+        \addplot gnuplot{x};
+        \addlegendentry{avg sensing}
+    \end{axis}
+\end{tikzpicture}
+\end{document}
diff --git a/doc/getting.txt b/doc/getting.txt
new file mode 100644
index 0000000..2959821
--- /dev/null
+++ b/doc/getting.txt
@@ -0,0 +1,65 @@
+Appendix C: Getting ZynAddSubFX
+-------------------------------
+
+Usually there are several methods to obtain a copy of ZynAddSubFX.
+
+SourceForge::
+    http://sourceforge.net/projects/zynaddsubfx/files/
+Distribuition::
+    apt/yum/others
+Git::
+    git://zynaddsubfx.git.sourceforge.net/gitroot/zynaddsubfx/zynaddsubfx
+
+Introduction to Git
+~~~~~~~~~~~~~~~~~~~
+
+For those who want to live on the bleeding edge or who want to assist with
+making sure that the next release has fewer bugs, you will want to get aquanted
+with git.
+Git is used to manage the source code for this project and can be used to
+quickly and easily get an up-to-date copy of the source code.
+
+Getting the Source Code
+^^^^^^^^^^^^^^^^^^^^^^^
+
+In order to get a copy of the ZynAddSubFX source code, all that needs to be done is:
+
+---------------------------------------------
+git clone git://zynaddsubfx.git.sourceforge.net/gitroot/zynaddsubfx/zynaddsubfx
+
+cd zynaddsubfx
+
+#Download additional resources
+git submodule init
+git submodule update
+---------------------------------------------
+
+You should now be in the directory of the source code.
+
+For simple steps on building, please see Appendix B of the manual.
+
+Checking out a branch
+^^^^^^^^^^^^^^^^^^^^^
+
+Lets say that development has extended into the creation of a new feature that
+you want to preview.
+For the sake of this guide, lets assume that the name of the branch that the
+feature is on is foo.
+
+-----------------------------------------
+#checkout the foo branch from sourceforge
+git checkout --track -b foo origin/foo
+
+#lets checkout the primary branch again
+git checkout master
+
+#hop back to the other branch
+git checkout foo
+----------------------------------------
+
+Now one should be able to change branches and go into the build directory (as
+described in Appendix B) and recompile ZynAddSubFX.
+
+NOTE: When using branches other than the master be aware that stability may
+      suffer
+
diff --git a/doc/images/ad-global.png b/doc/images/ad-global.png
new file mode 100644
index 0000000..9479a91
Binary files /dev/null and b/doc/images/ad-global.png differ
diff --git a/doc/images/ad-voice.png b/doc/images/ad-voice.png
new file mode 100644
index 0000000..8ee7b5f
Binary files /dev/null and b/doc/images/ad-voice.png differ
diff --git a/doc/images/envelope1.png b/doc/images/envelope1.png
new file mode 100644
index 0000000..fb41b7c
Binary files /dev/null and b/doc/images/envelope1.png differ
diff --git a/doc/images/envelope2.png b/doc/images/envelope2.png
new file mode 100644
index 0000000..2a241bc
Binary files /dev/null and b/doc/images/envelope2.png differ
diff --git a/doc/images/envelope3.png b/doc/images/envelope3.png
new file mode 100644
index 0000000..46de243
Binary files /dev/null and b/doc/images/envelope3.png differ
diff --git a/doc/images/envelope4.png b/doc/images/envelope4.png
new file mode 100644
index 0000000..6f9b3e9
Binary files /dev/null and b/doc/images/envelope4.png differ
diff --git a/doc/images/filter0.png b/doc/images/filter0.png
new file mode 100644
index 0000000..3545da5
Binary files /dev/null and b/doc/images/filter0.png differ
diff --git a/doc/images/filter1.png b/doc/images/filter1.png
new file mode 100644
index 0000000..35ffb17
Binary files /dev/null and b/doc/images/filter1.png differ
diff --git a/doc/images/filter2.png b/doc/images/filter2.png
new file mode 100644
index 0000000..836a514
Binary files /dev/null and b/doc/images/filter2.png differ
diff --git a/doc/images/lfo0.png b/doc/images/lfo0.png
new file mode 100644
index 0000000..381e7db
Binary files /dev/null and b/doc/images/lfo0.png differ
diff --git a/doc/images/lfo1.png b/doc/images/lfo1.png
new file mode 100644
index 0000000..db20026
Binary files /dev/null and b/doc/images/lfo1.png differ
diff --git a/doc/images/lfo2.png b/doc/images/lfo2.png
new file mode 100644
index 0000000..5eaeffb
Binary files /dev/null and b/doc/images/lfo2.png differ
diff --git a/doc/images/uicontroller.png b/doc/images/uicontroller.png
new file mode 100644
index 0000000..89b81c3
Binary files /dev/null and b/doc/images/uicontroller.png differ
diff --git a/doc/images/uienvelope0.jpg b/doc/images/uienvelope0.jpg
new file mode 100644
index 0000000..b5b4593
Binary files /dev/null and b/doc/images/uienvelope0.jpg differ
diff --git a/doc/images/uienvelope1.jpg b/doc/images/uienvelope1.jpg
new file mode 100644
index 0000000..0db6fe7
Binary files /dev/null and b/doc/images/uienvelope1.jpg differ
diff --git a/doc/images/uienvelope2.jpg b/doc/images/uienvelope2.jpg
new file mode 100644
index 0000000..c9006f1
Binary files /dev/null and b/doc/images/uienvelope2.jpg differ
diff --git a/doc/images/uienvelope3.jpg b/doc/images/uienvelope3.jpg
new file mode 100644
index 0000000..bba11d8
Binary files /dev/null and b/doc/images/uienvelope3.jpg differ
diff --git a/doc/images/uilfo.jpg b/doc/images/uilfo.jpg
new file mode 100644
index 0000000..b8f2c14
Binary files /dev/null and b/doc/images/uilfo.jpg differ
diff --git a/doc/images/uimain.png b/doc/images/uimain.png
new file mode 100644
index 0000000..5472fa5
Binary files /dev/null and b/doc/images/uimain.png differ
diff --git a/doc/images/uioscil.png b/doc/images/uioscil.png
new file mode 100644
index 0000000..2f891c0
Binary files /dev/null and b/doc/images/uioscil.png differ
diff --git a/doc/intro.txt b/doc/intro.txt
new file mode 100644
index 0000000..3ba6d72
--- /dev/null
+++ b/doc/intro.txt
@@ -0,0 +1,38 @@
+Getting Started
+---------------
+
+ZynAddSubFX is a fairly complex software synthesizer with a very large number of
+controls.
+As such, it is not alway obvious how to use ZynAddSubFX.
+
+Many applications under Linux transport MIDI over ALSA and transmit audio over
+JACK.
+ZynAddSubFX can be run in this configuration by running:
+
+------------------------------
+zynaddsubfx -I alsa -O jack -a
+------------------------------
+
+This sets the input driver to be alsa and the output driver to be jack, which
+should attempt to autoconnect to your soundcard as per the '-a' flag.
+If this is your first time running ZynAddSubFX, you will see a screen that lets
+you choose between the advanced and beginner interface.
+Currently the beginner interface is deprecated, so the advanced one is
+recommended.
+
+Now you should be able to see ZynAddSubFX's main window, from which you can
+setup patches, effects, and general configurations, but more importatnly it
+provides links into the parameters of the patches.
+ZynAddSubFX is a powerful tool with a number of base patches, but its true power
+lies in the ability to make your own patches.
+
+.Main Window
+image::./images/uimain.png[]
+
+For basic usage, you will want to use the button to the right of the enabled
+label.
+This button will allow for one to select the desired instrument from the banks
+that ZynAddSubFX has available.
+To play notes in ZynAddSubFX, either utilize the builtin virtual keyboard or
+connect your keyboard to the system and use aconnect to connect it to
+ZynAddSubFX (assuming that ALSA was used).
diff --git a/doc/lfo.txt b/doc/lfo.txt
new file mode 100644
index 0000000..082321d
--- /dev/null
+++ b/doc/lfo.txt
@@ -0,0 +1,65 @@
+LFO
+---
+:author: Paul Nasca
+
+Introduction
+~~~~~~~~~~~~
+
+"LFO" means Low Frequency Oscillator.
+These oscillators are not used to make sounds by themselves, but they changes
+somes parameters (like the frequencies, the amplitudes or the filters).
+
+The LFOs has some basic parameters:
+
+* *Delay*: This parameter sets how much time takes since the start of the
+           note to the start of the LFO
+* *Start Phase*: The possition that a LFO will start at
+* *Frequency*: How fast the LFO is (i.e. how fast the parameter's controlled by
+               the LFO changes)
+* *Depth*: The amplitude of the LFO (i.e. how much the parameter's controlled
+           by the LFO changes)
+
+image:images/lfo0.png[]
+
+Another important LFO parameter is the shape.
+There are many LFO Types according to the shape.
+ZynAddSubFX supports the folowing LFO shapes:
+
+image:images/lfo1.png[]
+
+Another parameter is the LFO Randomness.
+It modifies the LFO amplitude or the LFO frequency at random.
+In ZynAddSubFX you can choose how much the LFO frequency or LFO amplitude
+changes by this parameter.
+In the folowing images are shown some examples of randomness and how changes
+the shape of a triangle LFO.
+
+image:images/lfo2.png[]
+
+Other parameters are:
+
+* *Continous mode*: If this mode is used, the LFO will not start from "zero" on each new note, but it will be continuous. This is very usefull if you apply on filters to make interesting sweeps.
+* *Stretch*: It controlls how much the LFO frequency changes according to the
+note's frequency.
+It can vary from negative stretch (the LFO frequency is decreased on higher
+notes) to zero (the LFO frequency will be the same on all notes) to positive
+stretch (the LFO frequency will be increased on higher notes).
+
+User Interface
+~~~~~~~~~~~~~~
+
+In ZynAddSubFX, LFO parameters are shown as:
+
+image:images/uilfo.jpg[]
+
+Theese parameters are:
+
+* *Freq*: LFO Frequency
+* *Depth*: LFO Depth
+* *Start*: LFO Start Phase - 
+If this knob is at the lowest value, the LFO Start Phase will be random.
+* *Delay*: LFO Delay
+* *A.R.*: LFO Amplitude Randomnes
+* *F.R.*: LFO Frequency Randomness
+* *C.*: LFO Continous Mode
+* *Str.*: LFO Stretch - in the image above the LFO stretch is set to zero
diff --git a/doc/mididefaults.txt b/doc/mididefaults.txt
new file mode 100644
index 0000000..c8f33c4
--- /dev/null
+++ b/doc/mididefaults.txt
@@ -0,0 +1,22 @@
+Appendex A: MIDI Defaults
+-------------------------
+
+.Default MIDI Connections
+[literal]
+001 - Modulation Wheel
+007 - Volume
+010 - Pan
+011 - Expression
+064 - Sustain
+065 - Portamento Enable
+071 - Filter Q
+074 - Filter Cutoff
+075 - Bandwidth(*)
+076 - Modulation Amplitude(*)
+077 - Resonance Center Frequency(*)
+078 - Resonance Bandwidth(*)
+120 - All Sounds Off
+121 - Reset All Controllers
+123 - All Notes Off
+
+The entries with `(*)` are not within the General Midi specification
diff --git a/doc/nrpn.txt b/doc/nrpn.txt
new file mode 100644
index 0000000..94339ad
--- /dev/null
+++ b/doc/nrpn.txt
@@ -0,0 +1,162 @@
+NRPN (Non Registered Parameters Number)
+---------------------------------------
+
+NRPNs can control all system and insertion effect parameters.
+For example, you may change the reverb time when playing to keyboard or
+flanger's lfo frequency.
+You can disable the NRPN receiving by deselecting the "NRPN" checkbox from the
+main window (near "Master Keyshift" counter).
+The controls can be sent on any midi channel 
+(the midi channels numbers are ignored).
+
+The parameters are:
+
+- NRPN coarse (99 or 0x63)sets the system/insertion effects (4 for system effects or 8 for insertion effects)
+- NRPN fine (98 or 0x62)sets the number of the effect (first effect is 0)
+- Data entry coarse (6) sets the parameter number of effect to change(see below)
+- Data entry fine (26) sets the parameter of the effect
+
+You have to send NRPN coarse/fine before sending Data entry coarse/fine.
+If the effect/parameter doesn't exists or is set to none, then the NRPN is
+ignored.
+
+Example(all values in this example are hex):
+
+    B0 63 08 // Select the insertion effects
+    B0 62 01 // Select the second effect (remember: the first is 00 and not 01)
+    B0 06 00 // Select the effect parameter 00
+    B0 26 7F // Change the parameter of effect to the value 7F (127)
+
+WARNING: Changing of some of the effect parameters produces clicks when sounds
+passes thru these effects.
+I advise you to change only when the sound volume that passes thru the effect to be very low (or silence).
+Some parameters produce clicks when are changed very fast.
+
+Here are the effects parameter number (for Data entry coarse).
+The parameters that produces clicks are written in [red]#red# and have (AC)
+after their entry (always clicks).
+The parameter that produces clicks only when they are changed fast are written
+in [orange]#orange# and have a (FC) after the entry (Fast Clicks).
+Most parameters has the range from 0 to 127.
+When parameters have another range, it is written as [low...high] .
+
+Reverb
+~~~~~~
+
+[verse]
++[orange]#00 - Volume or Dry/Wet (FC)#
+[orange]#01 - Pan (FC)#
+02 - Reverb Time
+[orange]#03 - Initial Delay (FC)#
+04 - Initial Delay Feedback
+[grey]#05 - reserved#
+[grey]#06 - reserved#
+07 - Low Pass
+08 - High Pass
+09 - High Frequency Damping [64..127] 64=no damping
+[red]#10 - Reverb Type [0..1] 0 - Random, 1 - Freeverb (AC)#
+[red]#11 - Room Size (AC)#+
+
+Echo
+~~~~
+
+[verse]
++[orange]#00 - Volume or Dry/Wet (FC)#
+[orange]#01 - Pan (FC)#
+[red]#02 - Delay (AC)#
+[red]#03 - Delay between left and right (AC)#
+[orange]#04 - Left/Right Crossing (FC)#
+05 - Feedback
+06 - High Frequency Damp+
+
+
+Chorus
+~~~~~~
+
+[verse]
++[orange]#00 - Volume or Dry/Wet (FC)#
+[orange]#01 - Pan (FC)#
+02 - LFO Frequency
+03 - LFO Randomness
+04 - LFO Type [0..1]
+05 - LFO Stereo Difference
+06 - LFO Depth
+07 - Delay
+08 - Feedback
+[orange]#09 - Left/Right Crossing (FC)#
+[grey]#10 - reserved#
+[red]#11 - Mode [0..1] (0=add, 1=subtract) (AC)#+
+
+Phaser
+~~~~~~
+
+[verse]
++[orange]#00 - Volume or Dry/Wet (FC)#
+[orange]#01 - Pan (FC)#
+02 - LFO Frequency
+03 - LFO Randomness
+04 - LFO Type [0..1]
+05 - LFO Stereo Difference
+06 - LFO Depth
+07 - Feedback
+[red]#08 - Number of stages [0..11] (AC)#
+[orange]#09 - Let/Right Crossing (FC)#
+[red]#10 - Mode [0..1] (0=add, 1=subtract) (AC)#
+11 - Phase+
+
+AlienWah
+~~~~~~~~
+
+[verse]
++[orange]#00 - Volume or Dry/Wet (FC)#
+[orange]#01 - Pan (FC)#
+02 - LFO Frequency
+03 - LFO Randomness
+04 - LFO Type [0..1]
+05 - LFO Stereo Difference
+06 - LFO Depth
+07 - Feedback
+08 - Delay [0..100]
+[orange]#09 - Left/Right Crossing (FC)#
+10 - Phase+
+
+Distorsion
+~~~~~~~~~~
+
+[verse]
++[orange]#00 - Volume or Dry/Wet (FC)#
+[orange]#01 - Pan (FC)#
+02 - Left/Right Crossing
+[orange]#03 - Drive (FC)#
+[orange]#04 - Level (FC)#
+05 - Type [0..11]
+06 - Invert the signal (negate) [0..1]
+07 - Low Pass
+08 - High Pass
+09 - Mode [0.1] (0=mono,1=stereo)+
+
+EQ
+~~
+
+[verse]
++[orange]#00 - Gain (FC)#+
+
+All other settings of the EQ are shown in a different way.
+The N represent the band ("B." setting in the UI) and the first band is 0
+(and not 1), like it is shown in the UI.
+Change the "N" with the band you like.
+If you want to change a band that doesn't exist, the NRPN will be ignored.
+
+[verse]
++[red]#10+N*5 - Change the mode of the filter [0..9] (AC)#
+11+N*5 - Band's filter frequency
+12+N*5 - Band's filter gain
+13+N*5 - Band's filter Q (bandwidth or resonance)
+[grey]#14+N*5 - reserved#+
+
+Example of setting the gain on the second band:
+
+. The bands start counting from  0, so the second band is 1 => N=1.
+.  The formula is 12+N*5 => 12+1*5=17, so the number of effect parameter
+.  (for Data entry coarse) is 17.
+
diff --git a/doc/saving.txt b/doc/saving.txt
new file mode 100644
index 0000000..a45b663
--- /dev/null
+++ b/doc/saving.txt
@@ -0,0 +1,55 @@
+Persistence
+-----------
+
+As with most applications ZynAddSubFX allows for one to ave your work and reload
+it.
+
+Saving it all
+~~~~~~~~~~~~~
+
+One of the simplest ways to save your work is to save the entire session.
+This can be done through the File menu and will result in the creation of an
+.xmz file.
+Once created, this file will hold the settings for all settings within that
+session, such as microtonal tunings, all patches, system effects, insertion
+effects, etc...
+
+Saving Parts
+~~~~~~~~~~~~
+
+In many cases saving everything is not what is desired.
+Saving a patch later on is one such example.
+
+Patches
+^^^^^^^
+In order to save a patch, one can either save it from the instruments menu or
+through the bank window.
+
+With the instrument menu, one can just save the file to any given location with
+the .xiz extension.
+
+With the banks menu, one can assign a patch to a given slot with a bank.
+This instrument will remain here for future use until it is deleted.
+To see the physical location of the .xiz file, one should check the
+File->Settings->Bank_Root_Dirs window to see the paths for banks.
+
+NOTE: You need to have write permissions to add instruments to the bank.
+
+Presets
+^^^^^^^
+Have a favorite setting for an envelope, a difficult to reproduce oscillator?
+Then presets are for you.
+Presets allow for one to save the settings for any of the components which
+support copy/paste operations.
+This is done with preset files (.xpz), which get stored in the folders indicated
+by File->Settings->Preset_Root_Dirs.
+
+Summary
+~~~~~~~
+
+.Extension Summary
+[literal]
+xmz Everything
+xiz Instrument
+xsz Scale Settings
+xpz Presets
diff --git a/doc/zynaddsubfx.1.txt b/doc/zynaddsubfx.1.txt
new file mode 100644
index 0000000..854476c
--- /dev/null
+++ b/doc/zynaddsubfx.1.txt
@@ -0,0 +1,82 @@
+ZYNADDSUBFX(1)
+==============
+:doctype: manpage
+
+NAME
+----
+zynaddsubfx - a software synthesizer
+
+SYNOPSIS
+--------
+*zynaddsubfx* ['OPTIONS']
+
+DESCRIPTION
+-----------
+
+*zynaddsubfx* is a polyphonic multimbral synthesizer, which supports three
+synthesis engines and numerous effects to generate sound.
+
+1) ADsynth generates sounds by adding a number of voices.
+   Each voice has filters, envelopes, LFOs, morphing, modulation
+   (Ring Modulation, Phase Modulation... the modulators can have any
+   shape), resonance, etc...
+   Each voice includes a waveform generator with up to 128 sine/non-sine
+   harmonics.
+   You can use Fourier synthesis or if you don't like it you
+   can wave-shaping/filtering of functions.
+
+2) SUBsynth is a simple engine which makes sounds through
+   harmonic filtering of white noise
+
+3) PADsynth is an engine that makes very beautiful pads and other instruments,
+   which can be exported for use with other programs.
+
+Midi and audio support exists for OSS, ALSA, JACK, and others...
+
+OPTIONS
+-------
+
+*-h, --help*::
+    Display command-line help and exit
+*-v, --version*::
+    Display version and exit
+*-l, --load=FILE*::
+    Loads a .xmz file
+*-L, --load-instrument*=FILE::
+    Loads a .xiz file
+*-r --sample-rate*=SR::
+    Set the sample rate SR
+*-b, --buffer-size*=SR::
+    Set the buffer size, which determines the granularity of how often parameter
+    changes can be applied
+*-o, --oscil-size*=OS::
+    Set the ADsynth oscillator size
+*-S, --swap*::
+    Swap Left and Right output channels
+*-D, --dump*::
+    Dumps midi note ON/OFF commands
+*-U, --no-gui*::
+    Run ZynAddSubFX without user interface
+*-N, --named*=Name::
+    Postfix IO Name when possible
+*-a, --auto-connect*::
+    AutoConnect when using JACK
+*-O, --output*=engine::
+    Set Output Engine
+*-I, --input*=engine::
+    Set Input Engine
+*-e, --exec-after-init*=command::
+    Run post-initialization script. This script will be run after midi and audio
+    drivers have been initialized.
+
+BUGS
+----
+Please report any bugs to either the mailing list
+    zynaddsubfx-user at lists.sourceforge.net
+or the bugtracker
+    http://sourceforge.net/tracker/?group_id=62934
+
+AUTHOR
+------
+ZynAddSubFX was originally written by Nasca Octavian Paul. It is currently being
+maintained by Mark McCurry.
diff --git a/doc/zynaddsubfx.txt b/doc/zynaddsubfx.txt
new file mode 100644
index 0000000..26cd2dd
--- /dev/null
+++ b/doc/zynaddsubfx.txt
@@ -0,0 +1,31 @@
+Zynaddsubfx
+===========
+:Author: Paul Nasca and Mark McCurry
+
+This documentation is a work in progress
+
+include::intro.txt[]
+
+include::filter.txt[]
+
+include::lfo.txt[]
+
+include::envelope.txt[]
+
+include::adsynth.txt[]
+
+include::controller.txt[]
+
+include::effects.txt[]
+
+/////////////////////////////
+include::nrpn.txt[]
+/////////////////////////////
+
+include::saving.txt[]
+
+include::mididefaults.txt[]
+
+include::build.txt[]
+
+include::getting.txt[]
diff --git a/banks/Arpeggios/0001-Arpeggio1.xiz b/instruments/banks/Arpeggios/0001-Arpeggio1.xiz
similarity index 100%
rename from banks/Arpeggios/0001-Arpeggio1.xiz
rename to instruments/banks/Arpeggios/0001-Arpeggio1.xiz
diff --git a/banks/Arpeggios/0002-Arpeggio2.xiz b/instruments/banks/Arpeggios/0002-Arpeggio2.xiz
similarity index 100%
rename from banks/Arpeggios/0002-Arpeggio2.xiz
rename to instruments/banks/Arpeggios/0002-Arpeggio2.xiz
diff --git a/banks/Arpeggios/0003-Arpeggio3.xiz b/instruments/banks/Arpeggios/0003-Arpeggio3.xiz
similarity index 100%
rename from banks/Arpeggios/0003-Arpeggio3.xiz
rename to instruments/banks/Arpeggios/0003-Arpeggio3.xiz
diff --git a/banks/Arpeggios/0004-Arpeggio4.xiz b/instruments/banks/Arpeggios/0004-Arpeggio4.xiz
similarity index 100%
rename from banks/Arpeggios/0004-Arpeggio4.xiz
rename to instruments/banks/Arpeggios/0004-Arpeggio4.xiz
diff --git a/banks/Arpeggios/0005-Arpeggio5.xiz b/instruments/banks/Arpeggios/0005-Arpeggio5.xiz
similarity index 100%
rename from banks/Arpeggios/0005-Arpeggio5.xiz
rename to instruments/banks/Arpeggios/0005-Arpeggio5.xiz
diff --git a/banks/Arpeggios/0006-Aporggio6.xiz b/instruments/banks/Arpeggios/0006-Aporggio6.xiz
similarity index 100%
rename from banks/Arpeggios/0006-Aporggio6.xiz
rename to instruments/banks/Arpeggios/0006-Aporggio6.xiz
diff --git a/banks/Arpeggios/0007-Arpeggio7.xiz b/instruments/banks/Arpeggios/0007-Arpeggio7.xiz
similarity index 100%
rename from banks/Arpeggios/0007-Arpeggio7.xiz
rename to instruments/banks/Arpeggios/0007-Arpeggio7.xiz
diff --git a/banks/Arpeggios/0008-Arpeggio8.xiz b/instruments/banks/Arpeggios/0008-Arpeggio8.xiz
similarity index 100%
rename from banks/Arpeggios/0008-Arpeggio8.xiz
rename to instruments/banks/Arpeggios/0008-Arpeggio8.xiz
diff --git a/banks/Arpeggios/0009-Arpeggio9.xiz b/instruments/banks/Arpeggios/0009-Arpeggio9.xiz
similarity index 100%
rename from banks/Arpeggios/0009-Arpeggio9.xiz
rename to instruments/banks/Arpeggios/0009-Arpeggio9.xiz
diff --git a/banks/Arpeggios/0010-Arpeggio10.xiz b/instruments/banks/Arpeggios/0010-Arpeggio10.xiz
similarity index 100%
rename from banks/Arpeggios/0010-Arpeggio10.xiz
rename to instruments/banks/Arpeggios/0010-Arpeggio10.xiz
diff --git a/banks/Arpeggios/0011-Arpeggio11.xiz b/instruments/banks/Arpeggios/0011-Arpeggio11.xiz
similarity index 100%
rename from banks/Arpeggios/0011-Arpeggio11.xiz
rename to instruments/banks/Arpeggios/0011-Arpeggio11.xiz
diff --git a/banks/Arpeggios/0033-Sequence1.xiz b/instruments/banks/Arpeggios/0033-Sequence1.xiz
similarity index 100%
rename from banks/Arpeggios/0033-Sequence1.xiz
rename to instruments/banks/Arpeggios/0033-Sequence1.xiz
diff --git a/banks/Arpeggios/0034-Sequence2.xiz b/instruments/banks/Arpeggios/0034-Sequence2.xiz
similarity index 100%
rename from banks/Arpeggios/0034-Sequence2.xiz
rename to instruments/banks/Arpeggios/0034-Sequence2.xiz
diff --git a/banks/Arpeggios/0036-Echoed Synth.xiz b/instruments/banks/Arpeggios/0036-Echoed Synth.xiz
similarity index 100%
rename from banks/Arpeggios/0036-Echoed Synth.xiz
rename to instruments/banks/Arpeggios/0036-Echoed Synth.xiz
diff --git a/banks/Arpeggios/0037-Echo FX.xiz b/instruments/banks/Arpeggios/0037-Echo FX.xiz
similarity index 100%
rename from banks/Arpeggios/0037-Echo FX.xiz
rename to instruments/banks/Arpeggios/0037-Echo FX.xiz
diff --git a/banks/Arpeggios/0039-Soft Arpeggio1.xiz b/instruments/banks/Arpeggios/0039-Soft Arpeggio1.xiz
similarity index 100%
rename from banks/Arpeggios/0039-Soft Arpeggio1.xiz
rename to instruments/banks/Arpeggios/0039-Soft Arpeggio1.xiz
diff --git a/banks/Arpeggios/0040-Soft Arpeggio2.xiz b/instruments/banks/Arpeggios/0040-Soft Arpeggio2.xiz
similarity index 100%
rename from banks/Arpeggios/0040-Soft Arpeggio2.xiz
rename to instruments/banks/Arpeggios/0040-Soft Arpeggio2.xiz
diff --git a/banks/Arpeggios/0041-Soft Arpeggio3.xiz b/instruments/banks/Arpeggios/0041-Soft Arpeggio3.xiz
similarity index 100%
rename from banks/Arpeggios/0041-Soft Arpeggio3.xiz
rename to instruments/banks/Arpeggios/0041-Soft Arpeggio3.xiz
diff --git a/banks/Arpeggios/0042-Soft Arpeggio4.xiz b/instruments/banks/Arpeggios/0042-Soft Arpeggio4.xiz
similarity index 100%
rename from banks/Arpeggios/0042-Soft Arpeggio4.xiz
rename to instruments/banks/Arpeggios/0042-Soft Arpeggio4.xiz
diff --git a/banks/Arpeggios/0043-Soft Arpeggio5.xiz b/instruments/banks/Arpeggios/0043-Soft Arpeggio5.xiz
similarity index 100%
rename from banks/Arpeggios/0043-Soft Arpeggio5.xiz
rename to instruments/banks/Arpeggios/0043-Soft Arpeggio5.xiz
diff --git a/banks/Arpeggios/0065-Hyper Organ1.xiz b/instruments/banks/Arpeggios/0065-Hyper Organ1.xiz
similarity index 100%
rename from banks/Arpeggios/0065-Hyper Organ1.xiz
rename to instruments/banks/Arpeggios/0065-Hyper Organ1.xiz
diff --git a/banks/Arpeggios/0066-Hyper Arpeggio.xiz b/instruments/banks/Arpeggios/0066-Hyper Arpeggio.xiz
similarity index 100%
rename from banks/Arpeggios/0066-Hyper Arpeggio.xiz
rename to instruments/banks/Arpeggios/0066-Hyper Arpeggio.xiz
diff --git a/banks/Arpeggios/0068-Glass Arpeggio1.xiz b/instruments/banks/Arpeggios/0068-Glass Arpeggio1.xiz
similarity index 100%
rename from banks/Arpeggios/0068-Glass Arpeggio1.xiz
rename to instruments/banks/Arpeggios/0068-Glass Arpeggio1.xiz
diff --git a/banks/Arpeggios/0069-Glass Arpeggio2.xiz b/instruments/banks/Arpeggios/0069-Glass Arpeggio2.xiz
similarity index 100%
rename from banks/Arpeggios/0069-Glass Arpeggio2.xiz
rename to instruments/banks/Arpeggios/0069-Glass Arpeggio2.xiz
diff --git a/banks/Bass/0001-Bass 1.xiz b/instruments/banks/Bass/0001-Bass 1.xiz
similarity index 100%
rename from banks/Bass/0001-Bass 1.xiz
rename to instruments/banks/Bass/0001-Bass 1.xiz
diff --git a/banks/Bass/0002-Bass 2.xiz b/instruments/banks/Bass/0002-Bass 2.xiz
similarity index 100%
rename from banks/Bass/0002-Bass 2.xiz
rename to instruments/banks/Bass/0002-Bass 2.xiz
diff --git a/banks/Bass/0003-Bass 3 _analog_.xiz b/instruments/banks/Bass/0003-Bass 3 _analog_.xiz
similarity index 100%
rename from banks/Bass/0003-Bass 3 _analog_.xiz
rename to instruments/banks/Bass/0003-Bass 3 _analog_.xiz
diff --git a/banks/Bass/0004-Bass 4.xiz b/instruments/banks/Bass/0004-Bass 4.xiz
similarity index 100%
rename from banks/Bass/0004-Bass 4.xiz
rename to instruments/banks/Bass/0004-Bass 4.xiz
diff --git a/banks/Bass/0005-Bass 5.xiz b/instruments/banks/Bass/0005-Bass 5.xiz
similarity index 100%
rename from banks/Bass/0005-Bass 5.xiz
rename to instruments/banks/Bass/0005-Bass 5.xiz
diff --git a/banks/Bass/0006-Analogue Bass.xiz b/instruments/banks/Bass/0006-Analogue Bass.xiz
similarity index 100%
rename from banks/Bass/0006-Analogue Bass.xiz
rename to instruments/banks/Bass/0006-Analogue Bass.xiz
diff --git a/banks/Bass/0033-Wah Bass.xiz b/instruments/banks/Bass/0033-Wah Bass.xiz
similarity index 100%
rename from banks/Bass/0033-Wah Bass.xiz
rename to instruments/banks/Bass/0033-Wah Bass.xiz
diff --git a/banks/Bass/0035-FM Bass 1.xiz b/instruments/banks/Bass/0035-FM Bass 1.xiz
similarity index 100%
rename from banks/Bass/0035-FM Bass 1.xiz
rename to instruments/banks/Bass/0035-FM Bass 1.xiz
diff --git a/banks/Bass/0036-FM Bass 2.xiz b/instruments/banks/Bass/0036-FM Bass 2.xiz
similarity index 100%
rename from banks/Bass/0036-FM Bass 2.xiz
rename to instruments/banks/Bass/0036-FM Bass 2.xiz
diff --git a/banks/Brass/0001-FM Thrumpet.xiz b/instruments/banks/Brass/0001-FM Thrumpet.xiz
similarity index 100%
rename from banks/Brass/0001-FM Thrumpet.xiz
rename to instruments/banks/Brass/0001-FM Thrumpet.xiz
diff --git a/banks/Brass/0003-Synth Brazz 1.xiz b/instruments/banks/Brass/0003-Synth Brazz 1.xiz
similarity index 100%
rename from banks/Brass/0003-Synth Brazz 1.xiz
rename to instruments/banks/Brass/0003-Synth Brazz 1.xiz
diff --git a/banks/Brass/0004-Synth Brazz 2.xiz b/instruments/banks/Brass/0004-Synth Brazz 2.xiz
similarity index 100%
rename from banks/Brass/0004-Synth Brazz 2.xiz
rename to instruments/banks/Brass/0004-Synth Brazz 2.xiz
diff --git a/banks/Brass/0005-Synth Brass 3.xiz b/instruments/banks/Brass/0005-Synth Brass 3.xiz
similarity index 100%
rename from banks/Brass/0005-Synth Brass 3.xiz
rename to instruments/banks/Brass/0005-Synth Brass 3.xiz
diff --git a/banks/Brass/0006-Synth Brass 4.xiz b/instruments/banks/Brass/0006-Synth Brass 4.xiz
similarity index 100%
rename from banks/Brass/0006-Synth Brass 4.xiz
rename to instruments/banks/Brass/0006-Synth Brass 4.xiz
diff --git a/banks/Brass/0007-Synth Brass 5.xiz b/instruments/banks/Brass/0007-Synth Brass 5.xiz
similarity index 100%
rename from banks/Brass/0007-Synth Brass 5.xiz
rename to instruments/banks/Brass/0007-Synth Brass 5.xiz
diff --git a/banks/Brass/0009-Wah Brass.xiz b/instruments/banks/Brass/0009-Wah Brass.xiz
similarity index 100%
rename from banks/Brass/0009-Wah Brass.xiz
rename to instruments/banks/Brass/0009-Wah Brass.xiz
diff --git a/banks/Brass/0010-Solo Synth1.xiz b/instruments/banks/Brass/0010-Solo Synth1.xiz
similarity index 100%
rename from banks/Brass/0010-Solo Synth1.xiz
rename to instruments/banks/Brass/0010-Solo Synth1.xiz
diff --git a/banks/Brass/0011-Brazz 1.xiz b/instruments/banks/Brass/0011-Brazz 1.xiz
similarity index 100%
rename from banks/Brass/0011-Brazz 1.xiz
rename to instruments/banks/Brass/0011-Brazz 1.xiz
diff --git a/banks/Brass/0012-Brazz 2.xiz b/instruments/banks/Brass/0012-Brazz 2.xiz
similarity index 100%
rename from banks/Brass/0012-Brazz 2.xiz
rename to instruments/banks/Brass/0012-Brazz 2.xiz
diff --git a/banks/Brass/0033-Analog Brass 1.xiz b/instruments/banks/Brass/0033-Analog Brass 1.xiz
similarity index 100%
rename from banks/Brass/0033-Analog Brass 1.xiz
rename to instruments/banks/Brass/0033-Analog Brass 1.xiz
diff --git a/banks/Brass/0034-Analog Brass 2.xiz b/instruments/banks/Brass/0034-Analog Brass 2.xiz
similarity index 100%
rename from banks/Brass/0034-Analog Brass 2.xiz
rename to instruments/banks/Brass/0034-Analog Brass 2.xiz
diff --git a/banks/Brass/0035-Analog Brass 3.xiz b/instruments/banks/Brass/0035-Analog Brass 3.xiz
similarity index 100%
rename from banks/Brass/0035-Analog Brass 3.xiz
rename to instruments/banks/Brass/0035-Analog Brass 3.xiz
diff --git a/banks/Brass/0036-Analog Brass 4.xiz b/instruments/banks/Brass/0036-Analog Brass 4.xiz
similarity index 100%
rename from banks/Brass/0036-Analog Brass 4.xiz
rename to instruments/banks/Brass/0036-Analog Brass 4.xiz
diff --git a/banks/Brass/0065-Simple Brass.xiz b/instruments/banks/Brass/0065-Simple Brass.xiz
similarity index 100%
rename from banks/Brass/0065-Simple Brass.xiz
rename to instruments/banks/Brass/0065-Simple Brass.xiz
diff --git a/banks/Brass/0066-Fat Brass.xiz b/instruments/banks/Brass/0066-Fat Brass.xiz
similarity index 100%
rename from banks/Brass/0066-Fat Brass.xiz
rename to instruments/banks/Brass/0066-Fat Brass.xiz
diff --git a/banks/Brass/0067-Brass Pad1.xiz b/instruments/banks/Brass/0067-Brass Pad1.xiz
similarity index 100%
rename from banks/Brass/0067-Brass Pad1.xiz
rename to instruments/banks/Brass/0067-Brass Pad1.xiz
diff --git a/banks/Brass/0068-Brass Pad2.xiz b/instruments/banks/Brass/0068-Brass Pad2.xiz
similarity index 100%
rename from banks/Brass/0068-Brass Pad2.xiz
rename to instruments/banks/Brass/0068-Brass Pad2.xiz
diff --git a/banks/Choir and Voice/0001-AHH Choir 1.xiz b/instruments/banks/Choir and Voice/0001-AHH Choir 1.xiz
similarity index 100%
rename from banks/Choir and Voice/0001-AHH Choir 1.xiz
rename to instruments/banks/Choir and Voice/0001-AHH Choir 1.xiz
diff --git a/banks/Choir and Voice/0002-AHH Choir 2.xiz b/instruments/banks/Choir and Voice/0002-AHH Choir 2.xiz
similarity index 100%
rename from banks/Choir and Voice/0002-AHH Choir 2.xiz
rename to instruments/banks/Choir and Voice/0002-AHH Choir 2.xiz
diff --git a/banks/Choir and Voice/0003-EHH Choir 1.xiz b/instruments/banks/Choir and Voice/0003-EHH Choir 1.xiz
similarity index 100%
rename from banks/Choir and Voice/0003-EHH Choir 1.xiz
rename to instruments/banks/Choir and Voice/0003-EHH Choir 1.xiz
diff --git a/banks/Choir and Voice/0004-Voice OOH.xiz b/instruments/banks/Choir and Voice/0004-Voice OOH.xiz
similarity index 100%
rename from banks/Choir and Voice/0004-Voice OOH.xiz
rename to instruments/banks/Choir and Voice/0004-Voice OOH.xiz
diff --git a/banks/Choir and Voice/0005-Choir Pad1.xiz b/instruments/banks/Choir and Voice/0005-Choir Pad1.xiz
similarity index 100%
rename from banks/Choir and Voice/0005-Choir Pad1.xiz
rename to instruments/banks/Choir and Voice/0005-Choir Pad1.xiz
diff --git a/banks/Choir and Voice/0006-Choir Pad2.xiz b/instruments/banks/Choir and Voice/0006-Choir Pad2.xiz
similarity index 100%
rename from banks/Choir and Voice/0006-Choir Pad2.xiz
rename to instruments/banks/Choir and Voice/0006-Choir Pad2.xiz
diff --git a/banks/Choir and Voice/0007-Choir Pad3.xiz b/instruments/banks/Choir and Voice/0007-Choir Pad3.xiz
similarity index 100%
rename from banks/Choir and Voice/0007-Choir Pad3.xiz
rename to instruments/banks/Choir and Voice/0007-Choir Pad3.xiz
diff --git a/banks/Choir and Voice/0008-Choir Pad4.xiz b/instruments/banks/Choir and Voice/0008-Choir Pad4.xiz
similarity index 100%
rename from banks/Choir and Voice/0008-Choir Pad4.xiz
rename to instruments/banks/Choir and Voice/0008-Choir Pad4.xiz
diff --git a/banks/Choir and Voice/0009-Choir Pad5.xiz b/instruments/banks/Choir and Voice/0009-Choir Pad5.xiz
similarity index 100%
rename from banks/Choir and Voice/0009-Choir Pad5.xiz
rename to instruments/banks/Choir and Voice/0009-Choir Pad5.xiz
diff --git a/banks/Choir and Voice/0010-Choir Pad6.xiz b/instruments/banks/Choir and Voice/0010-Choir Pad6.xiz
similarity index 100%
rename from banks/Choir and Voice/0010-Choir Pad6.xiz
rename to instruments/banks/Choir and Voice/0010-Choir Pad6.xiz
diff --git a/banks/Choir and Voice/0033-Choir.xiz b/instruments/banks/Choir and Voice/0033-Choir.xiz
similarity index 100%
rename from banks/Choir and Voice/0033-Choir.xiz
rename to instruments/banks/Choir and Voice/0033-Choir.xiz
diff --git a/banks/Choir and Voice/0034-Slow Morph_Choir.xiz b/instruments/banks/Choir and Voice/0034-Slow Morph_Choir.xiz
similarity index 100%
rename from banks/Choir and Voice/0034-Slow Morph_Choir.xiz
rename to instruments/banks/Choir and Voice/0034-Slow Morph_Choir.xiz
diff --git a/banks/Choir and Voice/0035-Wah Choir.xiz b/instruments/banks/Choir and Voice/0035-Wah Choir.xiz
similarity index 100%
rename from banks/Choir and Voice/0035-Wah Choir.xiz
rename to instruments/banks/Choir and Voice/0035-Wah Choir.xiz
diff --git a/banks/Choir and Voice/0036-Eooooo.xiz b/instruments/banks/Choir and Voice/0036-Eooooo.xiz
similarity index 100%
rename from banks/Choir and Voice/0036-Eooooo.xiz
rename to instruments/banks/Choir and Voice/0036-Eooooo.xiz
diff --git a/banks/Choir and Voice/0037-Voiced Synth.xiz b/instruments/banks/Choir and Voice/0037-Voiced Synth.xiz
similarity index 100%
rename from banks/Choir and Voice/0037-Voiced Synth.xiz
rename to instruments/banks/Choir and Voice/0037-Voiced Synth.xiz
diff --git a/banks/Choir and Voice/0039-Ohh Choir.xiz b/instruments/banks/Choir and Voice/0039-Ohh Choir.xiz
similarity index 100%
rename from banks/Choir and Voice/0039-Ohh Choir.xiz
rename to instruments/banks/Choir and Voice/0039-Ohh Choir.xiz
diff --git a/banks/Choir and Voice/0065-Vocal Morph 1.xiz b/instruments/banks/Choir and Voice/0065-Vocal Morph 1.xiz
similarity index 100%
rename from banks/Choir and Voice/0065-Vocal Morph 1.xiz
rename to instruments/banks/Choir and Voice/0065-Vocal Morph 1.xiz
diff --git a/banks/Choir and Voice/0066-Vocal Morph 2.xiz b/instruments/banks/Choir and Voice/0066-Vocal Morph 2.xiz
similarity index 100%
rename from banks/Choir and Voice/0066-Vocal Morph 2.xiz
rename to instruments/banks/Choir and Voice/0066-Vocal Morph 2.xiz
diff --git a/banks/Choir and Voice/0067-Vocal Morph 3.xiz b/instruments/banks/Choir and Voice/0067-Vocal Morph 3.xiz
similarity index 100%
rename from banks/Choir and Voice/0067-Vocal Morph 3.xiz
rename to instruments/banks/Choir and Voice/0067-Vocal Morph 3.xiz
diff --git a/banks/Choir and Voice/0068-Vocal Morph 4.xiz b/instruments/banks/Choir and Voice/0068-Vocal Morph 4.xiz
similarity index 100%
rename from banks/Choir and Voice/0068-Vocal Morph 4.xiz
rename to instruments/banks/Choir and Voice/0068-Vocal Morph 4.xiz
diff --git a/banks/Choir and Voice/0069-Vocal Morph 5.xiz b/instruments/banks/Choir and Voice/0069-Vocal Morph 5.xiz
similarity index 100%
rename from banks/Choir and Voice/0069-Vocal Morph 5.xiz
rename to instruments/banks/Choir and Voice/0069-Vocal Morph 5.xiz
diff --git a/banks/Choir and Voice/0070-Vocal Morph 6.xiz b/instruments/banks/Choir and Voice/0070-Vocal Morph 6.xiz
similarity index 100%
rename from banks/Choir and Voice/0070-Vocal Morph 6.xiz
rename to instruments/banks/Choir and Voice/0070-Vocal Morph 6.xiz
diff --git a/banks/Choir and Voice/0071-Vocal Morph 7.xiz b/instruments/banks/Choir and Voice/0071-Vocal Morph 7.xiz
similarity index 100%
rename from banks/Choir and Voice/0071-Vocal Morph 7.xiz
rename to instruments/banks/Choir and Voice/0071-Vocal Morph 7.xiz
diff --git a/banks/William_Godfrey_Collection/0001-Xylophone.xiz b/instruments/banks/Collection/0001-Xylophone.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0001-Xylophone.xiz
rename to instruments/banks/Collection/0001-Xylophone.xiz
diff --git a/banks/William_Godfrey_Collection/0002-Vibraphone.xiz b/instruments/banks/Collection/0002-Vibraphone.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0002-Vibraphone.xiz
rename to instruments/banks/Collection/0002-Vibraphone.xiz
diff --git a/banks/William_Godfrey_Collection/0003-Soft Vibes.xiz b/instruments/banks/Collection/0003-Soft Vibes.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0003-Soft Vibes.xiz
rename to instruments/banks/Collection/0003-Soft Vibes.xiz
diff --git a/banks/William_Godfrey_Collection/0004-Simple Chimes.xiz b/instruments/banks/Collection/0004-Simple Chimes.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0004-Simple Chimes.xiz
rename to instruments/banks/Collection/0004-Simple Chimes.xiz
diff --git a/banks/William_Godfrey_Collection/0005-Silver Bell.xiz b/instruments/banks/Collection/0005-Silver Bell.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0005-Silver Bell.xiz
rename to instruments/banks/Collection/0005-Silver Bell.xiz
diff --git a/banks/William_Godfrey_Collection/0008-Ethereal.xiz b/instruments/banks/Collection/0008-Ethereal.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0008-Ethereal.xiz
rename to instruments/banks/Collection/0008-Ethereal.xiz
diff --git a/banks/William_Godfrey_Collection/0010-Trem Lead.xiz b/instruments/banks/Collection/0010-Trem Lead.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0010-Trem Lead.xiz
rename to instruments/banks/Collection/0010-Trem Lead.xiz
diff --git a/banks/William_Godfrey_Collection/0012-Trem Synth Piano 3.xiz b/instruments/banks/Collection/0012-Trem Synth Piano 3.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0012-Trem Synth Piano 3.xiz
rename to instruments/banks/Collection/0012-Trem Synth Piano 3.xiz
diff --git a/banks/William_Godfrey_Collection/0033-Trem Synth.xiz b/instruments/banks/Collection/0013-Trem Synth.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0033-Trem Synth.xiz
rename to instruments/banks/Collection/0013-Trem Synth.xiz
diff --git a/banks/William_Godfrey_Collection/0015-Simple Square.xiz b/instruments/banks/Collection/0015-Simple Square.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0015-Simple Square.xiz
rename to instruments/banks/Collection/0015-Simple Square.xiz
diff --git a/banks/William_Godfrey_Collection/0016-Full Square.xiz b/instruments/banks/Collection/0016-Full Square.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0016-Full Square.xiz
rename to instruments/banks/Collection/0016-Full Square.xiz
diff --git a/instruments/banks/Collection/0017-Super Square.xiz b/instruments/banks/Collection/0017-Super Square.xiz
new file mode 100644
index 0000000..f7ae92c
Binary files /dev/null and b/instruments/banks/Collection/0017-Super Square.xiz differ
diff --git a/banks/William_Godfrey_Collection/0018-Steel Wire.xiz b/instruments/banks/Collection/0018-Steel Wire.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0018-Steel Wire.xiz
rename to instruments/banks/Collection/0018-Steel Wire.xiz
diff --git a/instruments/banks/Collection/0019-Metal Drips.xiz b/instruments/banks/Collection/0019-Metal Drips.xiz
new file mode 100644
index 0000000..099b9da
Binary files /dev/null and b/instruments/banks/Collection/0019-Metal Drips.xiz differ
diff --git a/banks/William_Godfrey_Collection/0020-Fantasia.xiz b/instruments/banks/Collection/0020-Fantasia.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0020-Fantasia.xiz
rename to instruments/banks/Collection/0020-Fantasia.xiz
diff --git a/banks/William_Godfrey_Collection/0021-Soft.xiz b/instruments/banks/Collection/0021-Soft.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0021-Soft.xiz
rename to instruments/banks/Collection/0021-Soft.xiz
diff --git a/instruments/banks/Collection/0022-Ultra Soft.xiz b/instruments/banks/Collection/0022-Ultra Soft.xiz
new file mode 100644
index 0000000..7588585
Binary files /dev/null and b/instruments/banks/Collection/0022-Ultra Soft.xiz differ
diff --git a/banks/William_Godfrey_Collection/0077-Whistle.xiz b/instruments/banks/Collection/0023-Whistle.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0077-Whistle.xiz
rename to instruments/banks/Collection/0023-Whistle.xiz
diff --git a/instruments/banks/Collection/0024-Wipe Whistle.xiz b/instruments/banks/Collection/0024-Wipe Whistle.xiz
new file mode 100644
index 0000000..ac5ef46
Binary files /dev/null and b/instruments/banks/Collection/0024-Wipe Whistle.xiz differ
diff --git a/instruments/banks/Collection/0025-Ghost Whistle.xiz b/instruments/banks/Collection/0025-Ghost Whistle.xiz
new file mode 100644
index 0000000..e2b2301
Binary files /dev/null and b/instruments/banks/Collection/0025-Ghost Whistle.xiz differ
diff --git a/banks/William_Godfrey_Collection/0028-Echo Bubbles.xiz b/instruments/banks/Collection/0028-Echo Bubbles.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0028-Echo Bubbles.xiz
rename to instruments/banks/Collection/0028-Echo Bubbles.xiz
diff --git a/banks/William_Godfrey_Collection/0029-Full Strings.xiz b/instruments/banks/Collection/0029-Full Strings.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0029-Full Strings.xiz
rename to instruments/banks/Collection/0029-Full Strings.xiz
diff --git a/banks/William_Godfrey_Collection/0030-Slow Strings.xiz b/instruments/banks/Collection/0030-Slow Strings.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0030-Slow Strings.xiz
rename to instruments/banks/Collection/0030-Slow Strings.xiz
diff --git a/banks/William_Godfrey_Collection/0032-Pizzicato Strings.xiz b/instruments/banks/Collection/0032-Pizzicato Strings.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0032-Pizzicato Strings.xiz
rename to instruments/banks/Collection/0032-Pizzicato Strings.xiz
diff --git a/instruments/banks/Collection/0033-Sweep Synth.xiz b/instruments/banks/Collection/0033-Sweep Synth.xiz
new file mode 100644
index 0000000..5d0f632
Binary files /dev/null and b/instruments/banks/Collection/0033-Sweep Synth.xiz differ
diff --git a/banks/William_Godfrey_Collection/0034-Warm Synth.xiz b/instruments/banks/Collection/0034-Warm Synth.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0034-Warm Synth.xiz
rename to instruments/banks/Collection/0034-Warm Synth.xiz
diff --git a/banks/William_Godfrey_Collection/0035-Hard Synth.xiz b/instruments/banks/Collection/0035-Hard Synth.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0035-Hard Synth.xiz
rename to instruments/banks/Collection/0035-Hard Synth.xiz
diff --git a/banks/William_Godfrey_Collection/0036-Bright Synth.xiz b/instruments/banks/Collection/0036-Bright Synth.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0036-Bright Synth.xiz
rename to instruments/banks/Collection/0036-Bright Synth.xiz
diff --git a/banks/William_Godfrey_Collection/0037-Multi Synth.xiz b/instruments/banks/Collection/0037-Multi Synth.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0037-Multi Synth.xiz
rename to instruments/banks/Collection/0037-Multi Synth.xiz
diff --git a/banks/William_Godfrey_Collection/0038-Slow Saw.xiz b/instruments/banks/Collection/0038-Slow Saw.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0038-Slow Saw.xiz
rename to instruments/banks/Collection/0038-Slow Saw.xiz
diff --git a/banks/William_Godfrey_Collection/0039-Medium Saw.xiz b/instruments/banks/Collection/0039-Medium Saw.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0039-Medium Saw.xiz
rename to instruments/banks/Collection/0039-Medium Saw.xiz
diff --git a/banks/William_Godfrey_Collection/0040-Hard Saw.xiz b/instruments/banks/Collection/0040-Hard Saw.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0040-Hard Saw.xiz
rename to instruments/banks/Collection/0040-Hard Saw.xiz
diff --git a/banks/William_Godfrey_Collection/0041-Voiced Saw.xiz b/instruments/banks/Collection/0041-Voiced Saw.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0041-Voiced Saw.xiz
rename to instruments/banks/Collection/0041-Voiced Saw.xiz
diff --git a/instruments/banks/Collection/0042-Sweep Saw.xiz b/instruments/banks/Collection/0042-Sweep Saw.xiz
new file mode 100644
index 0000000..9e2b8a8
Binary files /dev/null and b/instruments/banks/Collection/0042-Sweep Saw.xiz differ
diff --git a/banks/William_Godfrey_Collection/0044-Wipe Synth.xiz b/instruments/banks/Collection/0044-Wipe Synth.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0044-Wipe Synth.xiz
rename to instruments/banks/Collection/0044-Wipe Synth.xiz
diff --git a/banks/William_Godfrey_Collection/0045-Hard Stereo Sweep Synth.xiz b/instruments/banks/Collection/0045-Hard Stereo Sweep Synth.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0045-Hard Stereo Sweep Synth.xiz
rename to instruments/banks/Collection/0045-Hard Stereo Sweep Synth.xiz
diff --git a/banks/William_Godfrey_Collection/0046-Master Synth Low.xiz b/instruments/banks/Collection/0046-Master Synth Low.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0046-Master Synth Low.xiz
rename to instruments/banks/Collection/0046-Master Synth Low.xiz
diff --git a/banks/William_Godfrey_Collection/0047-Master Synth High.xiz b/instruments/banks/Collection/0047-Master Synth High.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0047-Master Synth High.xiz
rename to instruments/banks/Collection/0047-Master Synth High.xiz
diff --git a/banks/William_Godfrey_Collection/0048-Sharp Synth.xiz b/instruments/banks/Collection/0048-Sharp Synth.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0048-Sharp Synth.xiz
rename to instruments/banks/Collection/0048-Sharp Synth.xiz
diff --git a/banks/William_Godfrey_Collection/0050-Fretless Bass.xiz b/instruments/banks/Collection/0050-Fretless Bass.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0050-Fretless Bass.xiz
rename to instruments/banks/Collection/0050-Fretless Bass.xiz
diff --git a/banks/William_Godfrey_Collection/0051-Decay Bass.xiz b/instruments/banks/Collection/0051-Decay Bass.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0051-Decay Bass.xiz
rename to instruments/banks/Collection/0051-Decay Bass.xiz
diff --git a/banks/William_Godfrey_Collection/0052-Steel Bass.xiz b/instruments/banks/Collection/0052-Steel Bass.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0052-Steel Bass.xiz
rename to instruments/banks/Collection/0052-Steel Bass.xiz
diff --git a/banks/William_Godfrey_Collection/0053-Synth Bass.xiz b/instruments/banks/Collection/0053-Synth Bass.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0053-Synth Bass.xiz
rename to instruments/banks/Collection/0053-Synth Bass.xiz
diff --git a/instruments/banks/Collection/0054-Distorted Bass.xiz b/instruments/banks/Collection/0054-Distorted Bass.xiz
new file mode 100644
index 0000000..8e99b44
Binary files /dev/null and b/instruments/banks/Collection/0054-Distorted Bass.xiz differ
diff --git a/banks/William_Godfrey_Collection/0057-Sub Delay.xiz b/instruments/banks/Collection/0057-Sub Delay.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0057-Sub Delay.xiz
rename to instruments/banks/Collection/0057-Sub Delay.xiz
diff --git a/banks/William_Godfrey_Collection/0058-Reed Organ.xiz b/instruments/banks/Collection/0058-Reed Organ.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0058-Reed Organ.xiz
rename to instruments/banks/Collection/0058-Reed Organ.xiz
diff --git a/banks/William_Godfrey_Collection/0059-Soft Organ.xiz b/instruments/banks/Collection/0059-Soft Organ.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0059-Soft Organ.xiz
rename to instruments/banks/Collection/0059-Soft Organ.xiz
diff --git a/banks/William_Godfrey_Collection/0060-Thin Pipe.xiz b/instruments/banks/Collection/0060-Thin Pipe.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0060-Thin Pipe.xiz
rename to instruments/banks/Collection/0060-Thin Pipe.xiz
diff --git a/banks/William_Godfrey_Collection/0061-Great Organ.xiz b/instruments/banks/Collection/0061-Great Organ.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0061-Great Organ.xiz
rename to instruments/banks/Collection/0061-Great Organ.xiz
diff --git a/banks/William_Godfrey_Collection/0062-Hammond Organ.xiz b/instruments/banks/Collection/0062-Hammond Organ.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0062-Hammond Organ.xiz
rename to instruments/banks/Collection/0062-Hammond Organ.xiz
diff --git a/instruments/banks/Collection/0063-Percussion Organ.xiz b/instruments/banks/Collection/0063-Percussion Organ.xiz
new file mode 100644
index 0000000..0b40032
Binary files /dev/null and b/instruments/banks/Collection/0063-Percussion Organ.xiz differ
diff --git a/banks/William_Godfrey_Collection/0064-Sines.xiz b/instruments/banks/Collection/0064-Sines.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0064-Sines.xiz
rename to instruments/banks/Collection/0064-Sines.xiz
diff --git a/banks/William_Godfrey_Collection/0067-Soft Flute.xiz b/instruments/banks/Collection/0067-Soft Flute.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0067-Soft Flute.xiz
rename to instruments/banks/Collection/0067-Soft Flute.xiz
diff --git a/banks/William_Godfrey_Collection/0068-Warm Flute.xiz b/instruments/banks/Collection/0068-Warm Flute.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0068-Warm Flute.xiz
rename to instruments/banks/Collection/0068-Warm Flute.xiz
diff --git a/banks/William_Godfrey_Collection/0071-Ocarina.xiz b/instruments/banks/Collection/0071-Ocarina.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0071-Ocarina.xiz
rename to instruments/banks/Collection/0071-Ocarina.xiz
diff --git a/banks/William_Godfrey_Collection/0073-Variable Reed.xiz b/instruments/banks/Collection/0073-Variable Reed.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0073-Variable Reed.xiz
rename to instruments/banks/Collection/0073-Variable Reed.xiz
diff --git a/banks/William_Godfrey_Collection/0075-Smooth.xiz b/instruments/banks/Collection/0075-Smooth.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0075-Smooth.xiz
rename to instruments/banks/Collection/0075-Smooth.xiz
diff --git a/banks/William_Godfrey_Collection/0042-Matrix.xiz b/instruments/banks/Collection/0077-Matrix.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0042-Matrix.xiz
rename to instruments/banks/Collection/0077-Matrix.xiz
diff --git a/banks/William_Godfrey_Collection/0043-Sweep Matrix.xiz b/instruments/banks/Collection/0078-Sweep Matrix.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0043-Sweep Matrix.xiz
rename to instruments/banks/Collection/0078-Sweep Matrix.xiz
diff --git a/banks/William_Godfrey_Collection/0079-Ice Field.xiz b/instruments/banks/Collection/0079-Ice Field.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0079-Ice Field.xiz
rename to instruments/banks/Collection/0079-Ice Field.xiz
diff --git a/banks/William_Godfrey_Collection/0080-Hollow Ice Field.xiz b/instruments/banks/Collection/0080-Hollow Ice Field.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0080-Hollow Ice Field.xiz
rename to instruments/banks/Collection/0080-Hollow Ice Field.xiz
diff --git a/banks/William_Godfrey_Collection/0081-Beyond.xiz b/instruments/banks/Collection/0081-Beyond.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0081-Beyond.xiz
rename to instruments/banks/Collection/0081-Beyond.xiz
diff --git a/banks/William_Godfrey_Collection/0083-Sweep Pad.xiz b/instruments/banks/Collection/0083-Sweep Pad.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0083-Sweep Pad.xiz
rename to instruments/banks/Collection/0083-Sweep Pad.xiz
diff --git a/banks/William_Godfrey_Collection/0084-Breathy Pad.xiz b/instruments/banks/Collection/0084-Breathy Pad.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0084-Breathy Pad.xiz
rename to instruments/banks/Collection/0084-Breathy Pad.xiz
diff --git a/banks/William_Godfrey_Collection/0085-Bottle.xiz b/instruments/banks/Collection/0085-Bottle.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0085-Bottle.xiz
rename to instruments/banks/Collection/0085-Bottle.xiz
diff --git a/banks/William_Godfrey_Collection/0086-ReedBank.xiz b/instruments/banks/Collection/0086-ReedBank.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0086-ReedBank.xiz
rename to instruments/banks/Collection/0086-ReedBank.xiz
diff --git a/banks/William_Godfrey_Collection/0087-Sweep Rushes.xiz b/instruments/banks/Collection/0087-Sweep Rushes.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0087-Sweep Rushes.xiz
rename to instruments/banks/Collection/0087-Sweep Rushes.xiz
diff --git a/banks/William_Godfrey_Collection/0088-Rushes.xiz b/instruments/banks/Collection/0088-Rushes.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0088-Rushes.xiz
rename to instruments/banks/Collection/0088-Rushes.xiz
diff --git a/banks/William_Godfrey_Collection/0089-Medium Rushes.xiz b/instruments/banks/Collection/0089-Medium Rushes.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0089-Medium Rushes.xiz
rename to instruments/banks/Collection/0089-Medium Rushes.xiz
diff --git a/banks/William_Godfrey_Collection/0090-Bright Rushes.xiz b/instruments/banks/Collection/0090-Bright Rushes.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0090-Bright Rushes.xiz
rename to instruments/banks/Collection/0090-Bright Rushes.xiz
diff --git a/banks/William_Godfrey_Collection/0091-Bright Rush Pipe.xiz b/instruments/banks/Collection/0091-Bright Rush Pipe.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0091-Bright Rush Pipe.xiz
rename to instruments/banks/Collection/0091-Bright Rush Pipe.xiz
diff --git a/banks/William_Godfrey_Collection/0092-Bright Rush Long Tail.xiz b/instruments/banks/Collection/0092-Bright Rush Long Tail.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0092-Bright Rush Long Tail.xiz
rename to instruments/banks/Collection/0092-Bright Rush Long Tail.xiz
diff --git a/banks/William_Godfrey_Collection/0093-Voyager.xiz b/instruments/banks/Collection/0093-Voyager.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0093-Voyager.xiz
rename to instruments/banks/Collection/0093-Voyager.xiz
diff --git a/banks/William_Godfrey_Collection/0094-Soft Voyager.xiz b/instruments/banks/Collection/0094-Soft Voyager.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0094-Soft Voyager.xiz
rename to instruments/banks/Collection/0094-Soft Voyager.xiz
diff --git a/banks/William_Godfrey_Collection/0095-Soft Voyager Reverse.xiz b/instruments/banks/Collection/0095-Soft Voyager Reverse.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0095-Soft Voyager Reverse.xiz
rename to instruments/banks/Collection/0095-Soft Voyager Reverse.xiz
diff --git a/banks/William_Godfrey_Collection/0096-Echo Choir.xiz b/instruments/banks/Collection/0096-Echo Choir.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0096-Echo Choir.xiz
rename to instruments/banks/Collection/0096-Echo Choir.xiz
diff --git a/banks/William_Godfrey_Collection/0097-Sharp.xiz b/instruments/banks/Collection/0097-Sharp.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0097-Sharp.xiz
rename to instruments/banks/Collection/0097-Sharp.xiz
diff --git a/instruments/banks/Collection/0098-Sharp and Warm.xiz b/instruments/banks/Collection/0098-Sharp and Warm.xiz
new file mode 100644
index 0000000..e9fa3ff
Binary files /dev/null and b/instruments/banks/Collection/0098-Sharp and Warm.xiz differ
diff --git a/banks/William_Godfrey_Collection/0098-Sharp and Deep.xiz b/instruments/banks/Collection/0099-Sharp and Deep.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0098-Sharp and Deep.xiz
rename to instruments/banks/Collection/0099-Sharp and Deep.xiz
diff --git a/banks/William_Godfrey_Collection/0099-Sharp Reed.xiz b/instruments/banks/Collection/0100-Sharp Reed.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0099-Sharp Reed.xiz
rename to instruments/banks/Collection/0100-Sharp Reed.xiz
diff --git a/instruments/banks/Collection/0101-Far Reed.xiz b/instruments/banks/Collection/0101-Far Reed.xiz
new file mode 100644
index 0000000..0c77ca7
Binary files /dev/null and b/instruments/banks/Collection/0101-Far Reed.xiz differ
diff --git a/banks/William_Godfrey_Collection/0103-Clarinet.xiz b/instruments/banks/Collection/0103-Clarinet.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0103-Clarinet.xiz
rename to instruments/banks/Collection/0103-Clarinet.xiz
diff --git a/banks/William_Godfrey_Collection/0102-Bassoon.xiz b/instruments/banks/Collection/0104-Bassoon.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0102-Bassoon.xiz
rename to instruments/banks/Collection/0104-Bassoon.xiz
diff --git a/banks/William_Godfrey_Collection/0106-Aooww.xiz b/instruments/banks/Collection/0106-Aooww.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0106-Aooww.xiz
rename to instruments/banks/Collection/0106-Aooww.xiz
diff --git a/banks/William_Godfrey_Collection/0107-Daooww.xiz b/instruments/banks/Collection/0107-Daooww.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0107-Daooww.xiz
rename to instruments/banks/Collection/0107-Daooww.xiz
diff --git a/banks/William_Godfrey_Collection/0108-Yaooww.xiz b/instruments/banks/Collection/0108-Yaooww.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0108-Yaooww.xiz
rename to instruments/banks/Collection/0108-Yaooww.xiz
diff --git a/banks/William_Godfrey_Collection/0109-Yiee.xiz b/instruments/banks/Collection/0109-Yiee.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0109-Yiee.xiz
rename to instruments/banks/Collection/0109-Yiee.xiz
diff --git a/banks/William_Godfrey_Collection/0110-Eeoow.xiz b/instruments/banks/Collection/0110-Eeoow.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0110-Eeoow.xiz
rename to instruments/banks/Collection/0110-Eeoow.xiz
diff --git a/banks/William_Godfrey_Collection/0112-Overdrive.xiz b/instruments/banks/Collection/0112-Overdrive.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0112-Overdrive.xiz
rename to instruments/banks/Collection/0112-Overdrive.xiz
diff --git a/banks/William_Godfrey_Collection/0113-Overdrive 2.xiz b/instruments/banks/Collection/0113-Overdrive 2.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0113-Overdrive 2.xiz
rename to instruments/banks/Collection/0113-Overdrive 2.xiz
diff --git a/banks/William_Godfrey_Collection/0114-Overdrive 3.xiz b/instruments/banks/Collection/0114-Overdrive 3.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0114-Overdrive 3.xiz
rename to instruments/banks/Collection/0114-Overdrive 3.xiz
diff --git a/banks/William_Godfrey_Collection/0116-Power Guitar 1.xiz b/instruments/banks/Collection/0116-Power Guitar 1.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0116-Power Guitar 1.xiz
rename to instruments/banks/Collection/0116-Power Guitar 1.xiz
diff --git a/banks/William_Godfrey_Collection/0117-Power Guitar 2.xiz b/instruments/banks/Collection/0117-Power Guitar 2.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0117-Power Guitar 2.xiz
rename to instruments/banks/Collection/0117-Power Guitar 2.xiz
diff --git a/banks/William_Godfrey_Collection/0120-Wet Brass.xiz b/instruments/banks/Collection/0120-Wet Brass.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0120-Wet Brass.xiz
rename to instruments/banks/Collection/0120-Wet Brass.xiz
diff --git a/instruments/banks/Collection/0122-Extended Rushes.xiz b/instruments/banks/Collection/0122-Extended Rushes.xiz
new file mode 100644
index 0000000..42da774
Binary files /dev/null and b/instruments/banks/Collection/0122-Extended Rushes.xiz differ
diff --git a/banks/William_Godfrey_Collection/0123-Prophesy.xiz b/instruments/banks/Collection/0123-Prophesy.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0123-Prophesy.xiz
rename to instruments/banks/Collection/0123-Prophesy.xiz
diff --git a/banks/William_Godfrey_Collection/0125-Pan Pipe 32.xiz b/instruments/banks/Collection/0125-Pan Pipe 32.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0125-Pan Pipe 32.xiz
rename to instruments/banks/Collection/0125-Pan Pipe 32.xiz
diff --git a/banks/William_Godfrey_Collection/0126-Pan Pipe.xiz b/instruments/banks/Collection/0126-Pan Pipe.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0126-Pan Pipe.xiz
rename to instruments/banks/Collection/0126-Pan Pipe.xiz
diff --git a/banks/William_Godfrey_Collection/0127-Pan Pipe 96.xiz b/instruments/banks/Collection/0127-Pan Pipe 96.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0127-Pan Pipe 96.xiz
rename to instruments/banks/Collection/0127-Pan Pipe 96.xiz
diff --git a/banks/William_Godfrey_Collection/0131-Lite Guitar.xiz b/instruments/banks/Collection/0131-Lite Guitar.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0131-Lite Guitar.xiz
rename to instruments/banks/Collection/0131-Lite Guitar.xiz
diff --git a/banks/William_Godfrey_Collection/0132-Trem Guitar.xiz b/instruments/banks/Collection/0132-Trem Guitar.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0132-Trem Guitar.xiz
rename to instruments/banks/Collection/0132-Trem Guitar.xiz
diff --git a/banks/William_Godfrey_Collection/0133-Smooth Guitar.xiz b/instruments/banks/Collection/0133-Smooth Guitar.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0133-Smooth Guitar.xiz
rename to instruments/banks/Collection/0133-Smooth Guitar.xiz
diff --git a/banks/William_Godfrey_Collection/0134-Nylon Guitar.xiz b/instruments/banks/Collection/0134-Nylon Guitar.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0134-Nylon Guitar.xiz
rename to instruments/banks/Collection/0134-Nylon Guitar.xiz
diff --git a/banks/William_Godfrey_Collection/0139-Home Piano.xiz b/instruments/banks/Collection/0139-Home Piano.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0139-Home Piano.xiz
rename to instruments/banks/Collection/0139-Home Piano.xiz
diff --git a/banks/William_Godfrey_Collection/0140-Moonlight Piano.xiz b/instruments/banks/Collection/0140-Moonlight Piano.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0140-Moonlight Piano.xiz
rename to instruments/banks/Collection/0140-Moonlight Piano.xiz
diff --git a/banks/William_Godfrey_Collection/0141-Soft Piano1.xiz b/instruments/banks/Collection/0141-Soft Piano1.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0141-Soft Piano1.xiz
rename to instruments/banks/Collection/0141-Soft Piano1.xiz
diff --git a/banks/William_Godfrey_Collection/0142-Soft Piano2.xiz b/instruments/banks/Collection/0142-Soft Piano2.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0142-Soft Piano2.xiz
rename to instruments/banks/Collection/0142-Soft Piano2.xiz
diff --git a/banks/William_Godfrey_Collection/0143-Space Piano.xiz b/instruments/banks/Collection/0143-Space Piano.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0143-Space Piano.xiz
rename to instruments/banks/Collection/0143-Space Piano.xiz
diff --git a/banks/William_Godfrey_Collection/0146-Space Voice.xiz b/instruments/banks/Collection/0146-Space Voice.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0146-Space Voice.xiz
rename to instruments/banks/Collection/0146-Space Voice.xiz
diff --git a/banks/William_Godfrey_Collection/0147-Space Voice 2.xiz b/instruments/banks/Collection/0147-Space Voice 2.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0147-Space Voice 2.xiz
rename to instruments/banks/Collection/0147-Space Voice 2.xiz
diff --git a/banks/William_Godfrey_Collection/0149-Soft Choir.xiz b/instruments/banks/Collection/0149-Soft Choir.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0149-Soft Choir.xiz
rename to instruments/banks/Collection/0149-Soft Choir.xiz
diff --git a/instruments/banks/Collection/0150-Full Choir.xiz b/instruments/banks/Collection/0150-Full Choir.xiz
new file mode 100644
index 0000000..c86dc61
Binary files /dev/null and b/instruments/banks/Collection/0150-Full Choir.xiz differ
diff --git a/banks/William_Godfrey_Collection/0151-Soft Ahh.xiz b/instruments/banks/Collection/0151-Soft Ahh.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0151-Soft Ahh.xiz
rename to instruments/banks/Collection/0151-Soft Ahh.xiz
diff --git a/banks/William_Godfrey_Collection/0152-Breathy Ahh.xiz b/instruments/banks/Collection/0152-Breathy Ahh.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0152-Breathy Ahh.xiz
rename to instruments/banks/Collection/0152-Breathy Ahh.xiz
diff --git a/banks/William_Godfrey_Collection/0155-Super Pad.xiz b/instruments/banks/Collection/0155-Super Pad.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0155-Super Pad.xiz
rename to instruments/banks/Collection/0155-Super Pad.xiz
diff --git a/banks/William_Godfrey_Collection/0156-Hyper Pad.xiz b/instruments/banks/Collection/0156-Hyper Pad.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0156-Hyper Pad.xiz
rename to instruments/banks/Collection/0156-Hyper Pad.xiz
diff --git a/banks/William_Godfrey_Collection/0157-Hyper Matrix.xiz b/instruments/banks/Collection/0157-Hyper Matrix.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0157-Hyper Matrix.xiz
rename to instruments/banks/Collection/0157-Hyper Matrix.xiz
diff --git a/banks/William_Godfrey_Collection/0158-Extreme.xiz b/instruments/banks/Collection/0158-Extreme.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0158-Extreme.xiz
rename to instruments/banks/Collection/0158-Extreme.xiz
diff --git a/banks/William_Godfrey_Collection/0160-Wind and Surf.xiz b/instruments/banks/Collection/0160-Wind and Surf.xiz
similarity index 100%
rename from banks/William_Godfrey_Collection/0160-Wind and Surf.xiz
rename to instruments/banks/Collection/0160-Wind and Surf.xiz
diff --git a/banks/Drums/0001-Drums Kit1.xiz b/instruments/banks/Drums/0001-Drums Kit1.xiz
similarity index 100%
rename from banks/Drums/0001-Drums Kit1.xiz
rename to instruments/banks/Drums/0001-Drums Kit1.xiz
diff --git a/banks/Dual/0001-Layered1.xiz b/instruments/banks/Dual/0001-Layered1.xiz
similarity index 100%
rename from banks/Dual/0001-Layered1.xiz
rename to instruments/banks/Dual/0001-Layered1.xiz
diff --git a/banks/Dual/0002-Layered2.xiz b/instruments/banks/Dual/0002-Layered2.xiz
similarity index 100%
rename from banks/Dual/0002-Layered2.xiz
rename to instruments/banks/Dual/0002-Layered2.xiz
diff --git a/banks/Dual/0005-Organ and Saw.xiz b/instruments/banks/Dual/0005-Organ and Saw.xiz
similarity index 100%
rename from banks/Dual/0005-Organ and Saw.xiz
rename to instruments/banks/Dual/0005-Organ and Saw.xiz
diff --git a/banks/Dual/0007-Organ Choir Pad1.xiz b/instruments/banks/Dual/0007-Organ Choir Pad1.xiz
similarity index 100%
rename from banks/Dual/0007-Organ Choir Pad1.xiz
rename to instruments/banks/Dual/0007-Organ Choir Pad1.xiz
diff --git a/banks/Dual/0008-Organ Choir Pad2.xiz b/instruments/banks/Dual/0008-Organ Choir Pad2.xiz
similarity index 100%
rename from banks/Dual/0008-Organ Choir Pad2.xiz
rename to instruments/banks/Dual/0008-Organ Choir Pad2.xiz
diff --git a/banks/Dual/0033-Rhodes Strings1.xiz b/instruments/banks/Dual/0033-Rhodes Strings1.xiz
similarity index 100%
rename from banks/Dual/0033-Rhodes Strings1.xiz
rename to instruments/banks/Dual/0033-Rhodes Strings1.xiz
diff --git a/banks/Dual/0034-Rhodes Strings2.xiz b/instruments/banks/Dual/0034-Rhodes Strings2.xiz
similarity index 100%
rename from banks/Dual/0034-Rhodes Strings2.xiz
rename to instruments/banks/Dual/0034-Rhodes Strings2.xiz
diff --git a/banks/Dual/0035-Rhodes Strings3.xiz b/instruments/banks/Dual/0035-Rhodes Strings3.xiz
similarity index 100%
rename from banks/Dual/0035-Rhodes Strings3.xiz
rename to instruments/banks/Dual/0035-Rhodes Strings3.xiz
diff --git a/banks/Dual/0036-Rhodes Strings4.xiz b/instruments/banks/Dual/0036-Rhodes Strings4.xiz
similarity index 100%
rename from banks/Dual/0036-Rhodes Strings4.xiz
rename to instruments/banks/Dual/0036-Rhodes Strings4.xiz
diff --git a/banks/Dual/0065-Dream of the Saw.xiz b/instruments/banks/Dual/0065-Dream of the Saw.xiz
similarity index 100%
rename from banks/Dual/0065-Dream of the Saw.xiz
rename to instruments/banks/Dual/0065-Dream of the Saw.xiz
diff --git a/banks/Fantasy/0001-Emptyness1.xiz b/instruments/banks/Fantasy/0001-Emptyness1.xiz
similarity index 100%
rename from banks/Fantasy/0001-Emptyness1.xiz
rename to instruments/banks/Fantasy/0001-Emptyness1.xiz
diff --git a/banks/Fantasy/0002-Emptyness2.xiz b/instruments/banks/Fantasy/0002-Emptyness2.xiz
similarity index 100%
rename from banks/Fantasy/0002-Emptyness2.xiz
rename to instruments/banks/Fantasy/0002-Emptyness2.xiz
diff --git a/banks/Fantasy/0003-Space Synth.xiz b/instruments/banks/Fantasy/0003-Space Synth.xiz
similarity index 100%
rename from banks/Fantasy/0003-Space Synth.xiz
rename to instruments/banks/Fantasy/0003-Space Synth.xiz
diff --git a/banks/Fantasy/0004-Weird Pad.xiz b/instruments/banks/Fantasy/0004-Weird Pad.xiz
similarity index 100%
rename from banks/Fantasy/0004-Weird Pad.xiz
rename to instruments/banks/Fantasy/0004-Weird Pad.xiz
diff --git a/banks/Fantasy/0006-Space SynthBrass.xiz b/instruments/banks/Fantasy/0006-Space SynthBrass.xiz
similarity index 100%
rename from banks/Fantasy/0006-Space SynthBrass.xiz
rename to instruments/banks/Fantasy/0006-Space SynthBrass.xiz
diff --git a/banks/Fantasy/0008-Space Voice1.xiz b/instruments/banks/Fantasy/0008-Space Voice1.xiz
similarity index 100%
rename from banks/Fantasy/0008-Space Voice1.xiz
rename to instruments/banks/Fantasy/0008-Space Voice1.xiz
diff --git a/banks/Fantasy/0009-Space Voice2.xiz b/instruments/banks/Fantasy/0009-Space Voice2.xiz
similarity index 100%
rename from banks/Fantasy/0009-Space Voice2.xiz
rename to instruments/banks/Fantasy/0009-Space Voice2.xiz
diff --git a/banks/Fantasy/0010-Space Voice3.xiz b/instruments/banks/Fantasy/0010-Space Voice3.xiz
similarity index 100%
rename from banks/Fantasy/0010-Space Voice3.xiz
rename to instruments/banks/Fantasy/0010-Space Voice3.xiz
diff --git a/banks/Fantasy/0011-Space Choir1.xiz b/instruments/banks/Fantasy/0011-Space Choir1.xiz
similarity index 100%
rename from banks/Fantasy/0011-Space Choir1.xiz
rename to instruments/banks/Fantasy/0011-Space Choir1.xiz
diff --git a/banks/Fantasy/0012-Space Choir2.xiz b/instruments/banks/Fantasy/0012-Space Choir2.xiz
similarity index 100%
rename from banks/Fantasy/0012-Space Choir2.xiz
rename to instruments/banks/Fantasy/0012-Space Choir2.xiz
diff --git a/banks/Fantasy/0014-Glass Voices.xiz b/instruments/banks/Fantasy/0014-Glass Voices.xiz
similarity index 100%
rename from banks/Fantasy/0014-Glass Voices.xiz
rename to instruments/banks/Fantasy/0014-Glass Voices.xiz
diff --git a/banks/Fantasy/0015-Strange Voice.xiz b/instruments/banks/Fantasy/0015-Strange Voice.xiz
similarity index 100%
rename from banks/Fantasy/0015-Strange Voice.xiz
rename to instruments/banks/Fantasy/0015-Strange Voice.xiz
diff --git a/banks/Fantasy/0033-ImpossibleDream1.xiz b/instruments/banks/Fantasy/0033-ImpossibleDream1.xiz
similarity index 100%
rename from banks/Fantasy/0033-ImpossibleDream1.xiz
rename to instruments/banks/Fantasy/0033-ImpossibleDream1.xiz
diff --git a/banks/Fantasy/0034-ImpossibleDream2.xiz b/instruments/banks/Fantasy/0034-ImpossibleDream2.xiz
similarity index 100%
rename from banks/Fantasy/0034-ImpossibleDream2.xiz
rename to instruments/banks/Fantasy/0034-ImpossibleDream2.xiz
diff --git a/banks/Fantasy/0035-ImpossibleDream3.xiz b/instruments/banks/Fantasy/0035-ImpossibleDream3.xiz
similarity index 100%
rename from banks/Fantasy/0035-ImpossibleDream3.xiz
rename to instruments/banks/Fantasy/0035-ImpossibleDream3.xiz
diff --git a/banks/Fantasy/0036-ImpossibleDream4.xiz b/instruments/banks/Fantasy/0036-ImpossibleDream4.xiz
similarity index 100%
rename from banks/Fantasy/0036-ImpossibleDream4.xiz
rename to instruments/banks/Fantasy/0036-ImpossibleDream4.xiz
diff --git a/banks/Fantasy/0037-ImpossibleDream5.xiz b/instruments/banks/Fantasy/0037-ImpossibleDream5.xiz
similarity index 100%
rename from banks/Fantasy/0037-ImpossibleDream5.xiz
rename to instruments/banks/Fantasy/0037-ImpossibleDream5.xiz
diff --git a/banks/Fantasy/0040-Delayed Echo.xiz b/instruments/banks/Fantasy/0040-Delayed Echo.xiz
similarity index 100%
rename from banks/Fantasy/0040-Delayed Echo.xiz
rename to instruments/banks/Fantasy/0040-Delayed Echo.xiz
diff --git a/banks/Fantasy/0041-Fade Down Echo.xiz b/instruments/banks/Fantasy/0041-Fade Down Echo.xiz
similarity index 100%
rename from banks/Fantasy/0041-Fade Down Echo.xiz
rename to instruments/banks/Fantasy/0041-Fade Down Echo.xiz
diff --git a/banks/Fantasy/0042-Rhodes Space1.xiz b/instruments/banks/Fantasy/0042-Rhodes Space1.xiz
similarity index 100%
rename from banks/Fantasy/0042-Rhodes Space1.xiz
rename to instruments/banks/Fantasy/0042-Rhodes Space1.xiz
diff --git a/banks/Fantasy/0043-Rhodes Space2.xiz b/instruments/banks/Fantasy/0043-Rhodes Space2.xiz
similarity index 100%
rename from banks/Fantasy/0043-Rhodes Space2.xiz
rename to instruments/banks/Fantasy/0043-Rhodes Space2.xiz
diff --git a/banks/Fantasy/0065-Long SpaceChoir1.xiz b/instruments/banks/Fantasy/0065-Long SpaceChoir1.xiz
similarity index 100%
rename from banks/Fantasy/0065-Long SpaceChoir1.xiz
rename to instruments/banks/Fantasy/0065-Long SpaceChoir1.xiz
diff --git a/banks/Fantasy/0066-Long SpaceChoir2.xiz b/instruments/banks/Fantasy/0066-Long SpaceChoir2.xiz
similarity index 100%
rename from banks/Fantasy/0066-Long SpaceChoir2.xiz
rename to instruments/banks/Fantasy/0066-Long SpaceChoir2.xiz
diff --git a/banks/Guitar/0001-Dist Guitar 1.xiz b/instruments/banks/Guitar/0001-Dist Guitar 1.xiz
similarity index 100%
rename from banks/Guitar/0001-Dist Guitar 1.xiz
rename to instruments/banks/Guitar/0001-Dist Guitar 1.xiz
diff --git a/banks/Guitar/0002-Dist Guitar 2.xiz b/instruments/banks/Guitar/0002-Dist Guitar 2.xiz
similarity index 100%
rename from banks/Guitar/0002-Dist Guitar 2.xiz
rename to instruments/banks/Guitar/0002-Dist Guitar 2.xiz
diff --git a/banks/Guitar/0003-Dist Guitar 3.xiz b/instruments/banks/Guitar/0003-Dist Guitar 3.xiz
similarity index 100%
rename from banks/Guitar/0003-Dist Guitar 3.xiz
rename to instruments/banks/Guitar/0003-Dist Guitar 3.xiz
diff --git a/banks/Guitar/0004-Dist Guitar 4.xiz b/instruments/banks/Guitar/0004-Dist Guitar 4.xiz
similarity index 100%
rename from banks/Guitar/0004-Dist Guitar 4.xiz
rename to instruments/banks/Guitar/0004-Dist Guitar 4.xiz
diff --git a/banks/Guitar/0005-Dist Guitar 5.xiz b/instruments/banks/Guitar/0005-Dist Guitar 5.xiz
similarity index 100%
rename from banks/Guitar/0005-Dist Guitar 5.xiz
rename to instruments/banks/Guitar/0005-Dist Guitar 5.xiz
diff --git a/banks/Guitar/0033-Trash Guitar 1.xiz b/instruments/banks/Guitar/0033-Trash Guitar 1.xiz
similarity index 100%
rename from banks/Guitar/0033-Trash Guitar 1.xiz
rename to instruments/banks/Guitar/0033-Trash Guitar 1.xiz
diff --git a/banks/Guitar/0034-Trash Guitar 2.xiz b/instruments/banks/Guitar/0034-Trash Guitar 2.xiz
similarity index 100%
rename from banks/Guitar/0034-Trash Guitar 2.xiz
rename to instruments/banks/Guitar/0034-Trash Guitar 2.xiz
diff --git a/banks/Guitar/0035-Short.xiz b/instruments/banks/Guitar/0035-Short.xiz
similarity index 100%
rename from banks/Guitar/0035-Short.xiz
rename to instruments/banks/Guitar/0035-Short.xiz
diff --git a/banks/Guitar/0065-Clean Guitar1.xiz b/instruments/banks/Guitar/0065-Clean Guitar1.xiz
similarity index 100%
rename from banks/Guitar/0065-Clean Guitar1.xiz
rename to instruments/banks/Guitar/0065-Clean Guitar1.xiz
diff --git a/banks/Guitar/0066-Electric Guitar.xiz b/instruments/banks/Guitar/0066-Electric Guitar.xiz
similarity index 100%
rename from banks/Guitar/0066-Electric Guitar.xiz
rename to instruments/banks/Guitar/0066-Electric Guitar.xiz
diff --git a/banks/Guitar/0097-Space Guitar.xiz b/instruments/banks/Guitar/0097-Space Guitar.xiz
similarity index 100%
rename from banks/Guitar/0097-Space Guitar.xiz
rename to instruments/banks/Guitar/0097-Space Guitar.xiz
diff --git a/banks/Misc/0001-Memories.xiz b/instruments/banks/Misc/0001-Memories.xiz
similarity index 100%
rename from banks/Misc/0001-Memories.xiz
rename to instruments/banks/Misc/0001-Memories.xiz
diff --git a/banks/Misc/0002-Bells 1.xiz b/instruments/banks/Misc/0002-Bells 1.xiz
similarity index 100%
rename from banks/Misc/0002-Bells 1.xiz
rename to instruments/banks/Misc/0002-Bells 1.xiz
diff --git a/banks/Misc/0003-Bells 2.xiz b/instruments/banks/Misc/0003-Bells 2.xiz
similarity index 100%
rename from banks/Misc/0003-Bells 2.xiz
rename to instruments/banks/Misc/0003-Bells 2.xiz
diff --git a/banks/Misc/0004-Bells 3.xiz b/instruments/banks/Misc/0004-Bells 3.xiz
similarity index 100%
rename from banks/Misc/0004-Bells 3.xiz
rename to instruments/banks/Misc/0004-Bells 3.xiz
diff --git a/banks/Misc/0005-Bells 4.xiz b/instruments/banks/Misc/0005-Bells 4.xiz
similarity index 100%
rename from banks/Misc/0005-Bells 4.xiz
rename to instruments/banks/Misc/0005-Bells 4.xiz
diff --git a/banks/Misc/0033-Trash Synth 1.xiz b/instruments/banks/Misc/0033-Trash Synth 1.xiz
similarity index 100%
rename from banks/Misc/0033-Trash Synth 1.xiz
rename to instruments/banks/Misc/0033-Trash Synth 1.xiz
diff --git a/banks/Misc/0034-Trash Synth 2.xiz b/instruments/banks/Misc/0034-Trash Synth 2.xiz
similarity index 100%
rename from banks/Misc/0034-Trash Synth 2.xiz
rename to instruments/banks/Misc/0034-Trash Synth 2.xiz
diff --git a/banks/Misc/0035-Trash Synth 3.xiz b/instruments/banks/Misc/0035-Trash Synth 3.xiz
similarity index 100%
rename from banks/Misc/0035-Trash Synth 3.xiz
rename to instruments/banks/Misc/0035-Trash Synth 3.xiz
diff --git a/banks/Misc/0036-Trash Synth 4.xiz b/instruments/banks/Misc/0036-Trash Synth 4.xiz
similarity index 100%
rename from banks/Misc/0036-Trash Synth 4.xiz
rename to instruments/banks/Misc/0036-Trash Synth 4.xiz
diff --git a/banks/Misc/0065-SuperSaw 1.xiz b/instruments/banks/Misc/0065-SuperSaw 1.xiz
similarity index 100%
rename from banks/Misc/0065-SuperSaw 1.xiz
rename to instruments/banks/Misc/0065-SuperSaw 1.xiz
diff --git a/banks/Misc/0066-SuperSaw 2.xiz b/instruments/banks/Misc/0066-SuperSaw 2.xiz
similarity index 100%
rename from banks/Misc/0066-SuperSaw 2.xiz
rename to instruments/banks/Misc/0066-SuperSaw 2.xiz
diff --git a/banks/Misc/0067-SuperSaw 3.xiz b/instruments/banks/Misc/0067-SuperSaw 3.xiz
similarity index 100%
rename from banks/Misc/0067-SuperSaw 3.xiz
rename to instruments/banks/Misc/0067-SuperSaw 3.xiz
diff --git a/banks/Misc/0068-SuperSaw 4.xiz b/instruments/banks/Misc/0068-SuperSaw 4.xiz
similarity index 100%
rename from banks/Misc/0068-SuperSaw 4.xiz
rename to instruments/banks/Misc/0068-SuperSaw 4.xiz
diff --git a/banks/Misc/0069-SuperSaw 5.xiz b/instruments/banks/Misc/0069-SuperSaw 5.xiz
similarity index 100%
rename from banks/Misc/0069-SuperSaw 5.xiz
rename to instruments/banks/Misc/0069-SuperSaw 5.xiz
diff --git a/banks/Misc/0070-SuperSaw 6.xiz b/instruments/banks/Misc/0070-SuperSaw 6.xiz
similarity index 100%
rename from banks/Misc/0070-SuperSaw 6.xiz
rename to instruments/banks/Misc/0070-SuperSaw 6.xiz
diff --git a/banks/Noises/0001-Synth Effect.xiz b/instruments/banks/Noises/0001-Synth Effect.xiz
similarity index 100%
rename from banks/Noises/0001-Synth Effect.xiz
rename to instruments/banks/Noises/0001-Synth Effect.xiz
diff --git a/banks/Noises/0002-Ioioioioioi.xiz b/instruments/banks/Noises/0002-Ioioioioioi.xiz
similarity index 100%
rename from banks/Noises/0002-Ioioioioioi.xiz
rename to instruments/banks/Noises/0002-Ioioioioioi.xiz
diff --git a/banks/Noises/0003-Noise1.xiz b/instruments/banks/Noises/0003-Noise1.xiz
similarity index 100%
rename from banks/Noises/0003-Noise1.xiz
rename to instruments/banks/Noises/0003-Noise1.xiz
diff --git a/banks/Noises/0004-Noise2.xiz b/instruments/banks/Noises/0004-Noise2.xiz
similarity index 100%
rename from banks/Noises/0004-Noise2.xiz
rename to instruments/banks/Noises/0004-Noise2.xiz
diff --git a/banks/Noises/0006-Wind.xiz b/instruments/banks/Noises/0006-Wind.xiz
similarity index 100%
rename from banks/Noises/0006-Wind.xiz
rename to instruments/banks/Noises/0006-Wind.xiz
diff --git a/banks/Noises/0033-Metal Sound 1.xiz b/instruments/banks/Noises/0033-Metal Sound 1.xiz
similarity index 100%
rename from banks/Noises/0033-Metal Sound 1.xiz
rename to instruments/banks/Noises/0033-Metal Sound 1.xiz
diff --git a/banks/Noises/0034-Metal Sound 2.xiz b/instruments/banks/Noises/0034-Metal Sound 2.xiz
similarity index 100%
rename from banks/Noises/0034-Metal Sound 2.xiz
rename to instruments/banks/Noises/0034-Metal Sound 2.xiz
diff --git a/banks/Noises/0035-Metal Sound 3.xiz b/instruments/banks/Noises/0035-Metal Sound 3.xiz
similarity index 100%
rename from banks/Noises/0035-Metal Sound 3.xiz
rename to instruments/banks/Noises/0035-Metal Sound 3.xiz
diff --git a/banks/Noises/0037-Metal Sound 4.xiz b/instruments/banks/Noises/0037-Metal Sound 4.xiz
similarity index 100%
rename from banks/Noises/0037-Metal Sound 4.xiz
rename to instruments/banks/Noises/0037-Metal Sound 4.xiz
diff --git a/banks/Noises/0038-Metal Sound 5.xiz b/instruments/banks/Noises/0038-Metal Sound 5.xiz
similarity index 100%
rename from banks/Noises/0038-Metal Sound 5.xiz
rename to instruments/banks/Noises/0038-Metal Sound 5.xiz
diff --git a/banks/Noises/0065-Short noise.xiz b/instruments/banks/Noises/0065-Short noise.xiz
similarity index 100%
rename from banks/Noises/0065-Short noise.xiz
rename to instruments/banks/Noises/0065-Short noise.xiz
diff --git a/banks/Organ/0001-Organ 1.xiz b/instruments/banks/Organ/0001-Organ 1.xiz
similarity index 100%
rename from banks/Organ/0001-Organ 1.xiz
rename to instruments/banks/Organ/0001-Organ 1.xiz
diff --git a/banks/Organ/0002-Organ 2.xiz b/instruments/banks/Organ/0002-Organ 2.xiz
similarity index 100%
rename from banks/Organ/0002-Organ 2.xiz
rename to instruments/banks/Organ/0002-Organ 2.xiz
diff --git a/banks/Organ/0003-Organ 3.xiz b/instruments/banks/Organ/0003-Organ 3.xiz
similarity index 100%
rename from banks/Organ/0003-Organ 3.xiz
rename to instruments/banks/Organ/0003-Organ 3.xiz
diff --git a/banks/Organ/0004-Organ 4.xiz b/instruments/banks/Organ/0004-Organ 4.xiz
similarity index 100%
rename from banks/Organ/0004-Organ 4.xiz
rename to instruments/banks/Organ/0004-Organ 4.xiz
diff --git a/banks/Organ/0005-Organ 5.xiz b/instruments/banks/Organ/0005-Organ 5.xiz
similarity index 100%
rename from banks/Organ/0005-Organ 5.xiz
rename to instruments/banks/Organ/0005-Organ 5.xiz
diff --git a/banks/Organ/0006-Organ 6.xiz b/instruments/banks/Organ/0006-Organ 6.xiz
similarity index 100%
rename from banks/Organ/0006-Organ 6.xiz
rename to instruments/banks/Organ/0006-Organ 6.xiz
diff --git a/banks/Organ/0007-Organ 7.xiz b/instruments/banks/Organ/0007-Organ 7.xiz
similarity index 100%
rename from banks/Organ/0007-Organ 7.xiz
rename to instruments/banks/Organ/0007-Organ 7.xiz
diff --git a/banks/Organ/0008-Organ 8.xiz b/instruments/banks/Organ/0008-Organ 8.xiz
similarity index 100%
rename from banks/Organ/0008-Organ 8.xiz
rename to instruments/banks/Organ/0008-Organ 8.xiz
diff --git a/banks/Organ/0009-Organ 9.xiz b/instruments/banks/Organ/0009-Organ 9.xiz
similarity index 100%
rename from banks/Organ/0009-Organ 9.xiz
rename to instruments/banks/Organ/0009-Organ 9.xiz
diff --git a/banks/Organ/0010-Organ 10.xiz b/instruments/banks/Organ/0010-Organ 10.xiz
similarity index 100%
rename from banks/Organ/0010-Organ 10.xiz
rename to instruments/banks/Organ/0010-Organ 10.xiz
diff --git a/banks/Organ/0011-Organ 11.xiz b/instruments/banks/Organ/0011-Organ 11.xiz
similarity index 100%
rename from banks/Organ/0011-Organ 11.xiz
rename to instruments/banks/Organ/0011-Organ 11.xiz
diff --git a/banks/Organ/0012-Organ 12.xiz b/instruments/banks/Organ/0012-Organ 12.xiz
similarity index 100%
rename from banks/Organ/0012-Organ 12.xiz
rename to instruments/banks/Organ/0012-Organ 12.xiz
diff --git a/banks/Organ/0033-Cathedral Organ1.xiz b/instruments/banks/Organ/0033-Cathedral Organ1.xiz
similarity index 100%
rename from banks/Organ/0033-Cathedral Organ1.xiz
rename to instruments/banks/Organ/0033-Cathedral Organ1.xiz
diff --git a/banks/Organ/0034-Cathedral Organ2.xiz b/instruments/banks/Organ/0034-Cathedral Organ2.xiz
similarity index 100%
rename from banks/Organ/0034-Cathedral Organ2.xiz
rename to instruments/banks/Organ/0034-Cathedral Organ2.xiz
diff --git a/banks/Organ/0035-Cathedral Organ3.xiz b/instruments/banks/Organ/0035-Cathedral Organ3.xiz
similarity index 100%
rename from banks/Organ/0035-Cathedral Organ3.xiz
rename to instruments/banks/Organ/0035-Cathedral Organ3.xiz
diff --git a/banks/Organ/0037-Church Organ 1.xiz b/instruments/banks/Organ/0037-Church Organ 1.xiz
similarity index 100%
rename from banks/Organ/0037-Church Organ 1.xiz
rename to instruments/banks/Organ/0037-Church Organ 1.xiz
diff --git a/banks/Organ/0038-Church Organ 2.xiz b/instruments/banks/Organ/0038-Church Organ 2.xiz
similarity index 100%
rename from banks/Organ/0038-Church Organ 2.xiz
rename to instruments/banks/Organ/0038-Church Organ 2.xiz
diff --git a/banks/Organ/0039-Church Organ 3.xiz b/instruments/banks/Organ/0039-Church Organ 3.xiz
similarity index 100%
rename from banks/Organ/0039-Church Organ 3.xiz
rename to instruments/banks/Organ/0039-Church Organ 3.xiz
diff --git a/banks/Organ/0040-Church Organ 4.xiz b/instruments/banks/Organ/0040-Church Organ 4.xiz
similarity index 100%
rename from banks/Organ/0040-Church Organ 4.xiz
rename to instruments/banks/Organ/0040-Church Organ 4.xiz
diff --git a/banks/Organ/0041-Church Organ Soft.xiz b/instruments/banks/Organ/0041-Church Organ Soft.xiz
similarity index 100%
rename from banks/Organ/0041-Church Organ Soft.xiz
rename to instruments/banks/Organ/0041-Church Organ Soft.xiz
diff --git a/banks/Organ/0065-Nice Organ 1.xiz b/instruments/banks/Organ/0065-Nice Organ 1.xiz
similarity index 100%
rename from banks/Organ/0065-Nice Organ 1.xiz
rename to instruments/banks/Organ/0065-Nice Organ 1.xiz
diff --git a/banks/Organ/0066-Nice Organ 2.xiz b/instruments/banks/Organ/0066-Nice Organ 2.xiz
similarity index 100%
rename from banks/Organ/0066-Nice Organ 2.xiz
rename to instruments/banks/Organ/0066-Nice Organ 2.xiz
diff --git a/banks/Organ/0067-Sub_Organ.xiz b/instruments/banks/Organ/0067-Sub_Organ.xiz
similarity index 100%
rename from banks/Organ/0067-Sub_Organ.xiz
rename to instruments/banks/Organ/0067-Sub_Organ.xiz
diff --git a/banks/Organ/0068-Square Organ.xiz b/instruments/banks/Organ/0068-Square Organ.xiz
similarity index 100%
rename from banks/Organ/0068-Square Organ.xiz
rename to instruments/banks/Organ/0068-Square Organ.xiz
diff --git a/banks/Organ/0069-Soft Organ 1.xiz b/instruments/banks/Organ/0069-Soft Organ 1.xiz
similarity index 100%
rename from banks/Organ/0069-Soft Organ 1.xiz
rename to instruments/banks/Organ/0069-Soft Organ 1.xiz
diff --git a/banks/Organ/0070-Soft Organ 2.xiz b/instruments/banks/Organ/0070-Soft Organ 2.xiz
similarity index 100%
rename from banks/Organ/0070-Soft Organ 2.xiz
rename to instruments/banks/Organ/0070-Soft Organ 2.xiz
diff --git a/banks/Organ/0071-Synth Organ.xiz b/instruments/banks/Organ/0071-Synth Organ.xiz
similarity index 100%
rename from banks/Organ/0071-Synth Organ.xiz
rename to instruments/banks/Organ/0071-Synth Organ.xiz
diff --git a/banks/Organ/0072-Fantasy Organ.xiz b/instruments/banks/Organ/0072-Fantasy Organ.xiz
similarity index 100%
rename from banks/Organ/0072-Fantasy Organ.xiz
rename to instruments/banks/Organ/0072-Fantasy Organ.xiz
diff --git a/banks/Organ/0097-Accordion Pad 1.xiz b/instruments/banks/Organ/0097-Accordion Pad 1.xiz
similarity index 100%
rename from banks/Organ/0097-Accordion Pad 1.xiz
rename to instruments/banks/Organ/0097-Accordion Pad 1.xiz
diff --git a/banks/Organ/0098-Accordion Pad 2.xiz b/instruments/banks/Organ/0098-Accordion Pad 2.xiz
similarity index 100%
rename from banks/Organ/0098-Accordion Pad 2.xiz
rename to instruments/banks/Organ/0098-Accordion Pad 2.xiz
diff --git a/banks/Organ/0099-Synth Accordion1.xiz b/instruments/banks/Organ/0099-Synth Accordion1.xiz
similarity index 100%
rename from banks/Organ/0099-Synth Accordion1.xiz
rename to instruments/banks/Organ/0099-Synth Accordion1.xiz
diff --git a/banks/Organ/0100-Synth Accordion2.xiz b/instruments/banks/Organ/0100-Synth Accordion2.xiz
similarity index 100%
rename from banks/Organ/0100-Synth Accordion2.xiz
rename to instruments/banks/Organ/0100-Synth Accordion2.xiz
diff --git a/banks/Organ/0101-Accordion 1.xiz b/instruments/banks/Organ/0101-Accordion 1.xiz
similarity index 100%
rename from banks/Organ/0101-Accordion 1.xiz
rename to instruments/banks/Organ/0101-Accordion 1.xiz
diff --git a/banks/Pads/0001-Sine Pad.xiz b/instruments/banks/Pads/0001-Sine Pad.xiz
similarity index 100%
rename from banks/Pads/0001-Sine Pad.xiz
rename to instruments/banks/Pads/0001-Sine Pad.xiz
diff --git a/banks/Pads/0002-sin2x  pad.xiz b/instruments/banks/Pads/0002-sin2x  pad.xiz
similarity index 100%
rename from banks/Pads/0002-sin2x  pad.xiz
rename to instruments/banks/Pads/0002-sin2x  pad.xiz
diff --git a/banks/Pads/0003-Analog Pad 1.xiz b/instruments/banks/Pads/0003-Analog Pad 1.xiz
similarity index 100%
rename from banks/Pads/0003-Analog Pad 1.xiz
rename to instruments/banks/Pads/0003-Analog Pad 1.xiz
diff --git a/banks/Pads/0004-Analog Pad 2.xiz b/instruments/banks/Pads/0004-Analog Pad 2.xiz
similarity index 100%
rename from banks/Pads/0004-Analog Pad 2.xiz
rename to instruments/banks/Pads/0004-Analog Pad 2.xiz
diff --git a/banks/Pads/0005-Square Pad 1.xiz b/instruments/banks/Pads/0005-Square Pad 1.xiz
similarity index 100%
rename from banks/Pads/0005-Square Pad 1.xiz
rename to instruments/banks/Pads/0005-Square Pad 1.xiz
diff --git a/banks/Pads/0006-Square Pad 2.xiz b/instruments/banks/Pads/0006-Square Pad 2.xiz
similarity index 100%
rename from banks/Pads/0006-Square Pad 2.xiz
rename to instruments/banks/Pads/0006-Square Pad 2.xiz
diff --git a/banks/Pads/0008-Resonance Pad1.xiz b/instruments/banks/Pads/0008-Resonance Pad1.xiz
similarity index 100%
rename from banks/Pads/0008-Resonance Pad1.xiz
rename to instruments/banks/Pads/0008-Resonance Pad1.xiz
diff --git a/banks/Pads/0009-Resonance Pad2.xiz b/instruments/banks/Pads/0009-Resonance Pad2.xiz
similarity index 100%
rename from banks/Pads/0009-Resonance Pad2.xiz
rename to instruments/banks/Pads/0009-Resonance Pad2.xiz
diff --git a/banks/Pads/0033-Synth Pad 1.xiz b/instruments/banks/Pads/0033-Synth Pad 1.xiz
similarity index 100%
rename from banks/Pads/0033-Synth Pad 1.xiz
rename to instruments/banks/Pads/0033-Synth Pad 1.xiz
diff --git a/banks/Pads/0034-Synth Pad 2.xiz b/instruments/banks/Pads/0034-Synth Pad 2.xiz
similarity index 100%
rename from banks/Pads/0034-Synth Pad 2.xiz
rename to instruments/banks/Pads/0034-Synth Pad 2.xiz
diff --git a/banks/Pads/0035-Synth Pad 3.xiz b/instruments/banks/Pads/0035-Synth Pad 3.xiz
similarity index 100%
rename from banks/Pads/0035-Synth Pad 3.xiz
rename to instruments/banks/Pads/0035-Synth Pad 3.xiz
diff --git a/banks/Pads/0036-Synth Pad 4.xiz b/instruments/banks/Pads/0036-Synth Pad 4.xiz
similarity index 100%
rename from banks/Pads/0036-Synth Pad 4.xiz
rename to instruments/banks/Pads/0036-Synth Pad 4.xiz
diff --git a/banks/Pads/0037-Synth Pad 5.xiz b/instruments/banks/Pads/0037-Synth Pad 5.xiz
similarity index 100%
rename from banks/Pads/0037-Synth Pad 5.xiz
rename to instruments/banks/Pads/0037-Synth Pad 5.xiz
diff --git a/banks/Pads/0065-Soft Pad.xiz b/instruments/banks/Pads/0065-Soft Pad.xiz
similarity index 100%
rename from banks/Pads/0065-Soft Pad.xiz
rename to instruments/banks/Pads/0065-Soft Pad.xiz
diff --git a/banks/Pads/0066-Flanged Pad 1.xiz b/instruments/banks/Pads/0066-Flanged Pad 1.xiz
similarity index 100%
rename from banks/Pads/0066-Flanged Pad 1.xiz
rename to instruments/banks/Pads/0066-Flanged Pad 1.xiz
diff --git a/banks/Pads/0097-Bell Pad.xiz b/instruments/banks/Pads/0097-Bell Pad.xiz
similarity index 100%
rename from banks/Pads/0097-Bell Pad.xiz
rename to instruments/banks/Pads/0097-Bell Pad.xiz
diff --git a/banks/Plucked/0001-Plucked 1.xiz b/instruments/banks/Plucked/0001-Plucked 1.xiz
similarity index 100%
rename from banks/Plucked/0001-Plucked 1.xiz
rename to instruments/banks/Plucked/0001-Plucked 1.xiz
diff --git a/banks/Plucked/0002-Plucked 2.xiz b/instruments/banks/Plucked/0002-Plucked 2.xiz
similarity index 100%
rename from banks/Plucked/0002-Plucked 2.xiz
rename to instruments/banks/Plucked/0002-Plucked 2.xiz
diff --git a/banks/Plucked/0003-Plucked 3.xiz b/instruments/banks/Plucked/0003-Plucked 3.xiz
similarity index 100%
rename from banks/Plucked/0003-Plucked 3.xiz
rename to instruments/banks/Plucked/0003-Plucked 3.xiz
diff --git a/banks/Plucked/0004-Plucked 4.xiz b/instruments/banks/Plucked/0004-Plucked 4.xiz
similarity index 100%
rename from banks/Plucked/0004-Plucked 4.xiz
rename to instruments/banks/Plucked/0004-Plucked 4.xiz
diff --git a/banks/Plucked/0005-Plucked 5.xiz b/instruments/banks/Plucked/0005-Plucked 5.xiz
similarity index 100%
rename from banks/Plucked/0005-Plucked 5.xiz
rename to instruments/banks/Plucked/0005-Plucked 5.xiz
diff --git a/banks/Plucked/0006-Plucked 6.xiz b/instruments/banks/Plucked/0006-Plucked 6.xiz
similarity index 100%
rename from banks/Plucked/0006-Plucked 6.xiz
rename to instruments/banks/Plucked/0006-Plucked 6.xiz
diff --git a/banks/Plucked/0033-Plucked String1.xiz b/instruments/banks/Plucked/0033-Plucked String1.xiz
similarity index 100%
rename from banks/Plucked/0033-Plucked String1.xiz
rename to instruments/banks/Plucked/0033-Plucked String1.xiz
diff --git a/banks/Plucked/0034-Plucked String2.xiz b/instruments/banks/Plucked/0034-Plucked String2.xiz
similarity index 100%
rename from banks/Plucked/0034-Plucked String2.xiz
rename to instruments/banks/Plucked/0034-Plucked String2.xiz
diff --git a/banks/Plucked/0036-Plucked Wah.xiz b/instruments/banks/Plucked/0036-Plucked Wah.xiz
similarity index 100%
rename from banks/Plucked/0036-Plucked Wah.xiz
rename to instruments/banks/Plucked/0036-Plucked Wah.xiz
diff --git a/banks/Plucked/0065-Plucked Pad1.xiz b/instruments/banks/Plucked/0065-Plucked Pad1.xiz
similarity index 100%
rename from banks/Plucked/0065-Plucked Pad1.xiz
rename to instruments/banks/Plucked/0065-Plucked Pad1.xiz
diff --git a/banks/Reed and Wind/0001-Flute 1.xiz b/instruments/banks/Reed and Wind/0001-Flute 1.xiz
similarity index 100%
rename from banks/Reed and Wind/0001-Flute 1.xiz
rename to instruments/banks/Reed and Wind/0001-Flute 1.xiz
diff --git a/banks/Reed and Wind/0002-Flute 2.xiz b/instruments/banks/Reed and Wind/0002-Flute 2.xiz
similarity index 100%
rename from banks/Reed and Wind/0002-Flute 2.xiz
rename to instruments/banks/Reed and Wind/0002-Flute 2.xiz
diff --git a/banks/Reed and Wind/0003-Flute 3.xiz b/instruments/banks/Reed and Wind/0003-Flute 3.xiz
similarity index 100%
rename from banks/Reed and Wind/0003-Flute 3.xiz
rename to instruments/banks/Reed and Wind/0003-Flute 3.xiz
diff --git a/banks/Reed and Wind/0005-FM Reed.xiz b/instruments/banks/Reed and Wind/0005-FM Reed.xiz
similarity index 100%
rename from banks/Reed and Wind/0005-FM Reed.xiz
rename to instruments/banks/Reed and Wind/0005-FM Reed.xiz
diff --git a/banks/Reed and Wind/0006-Clarinet.xiz b/instruments/banks/Reed and Wind/0006-Clarinet.xiz
similarity index 100%
rename from banks/Reed and Wind/0006-Clarinet.xiz
rename to instruments/banks/Reed and Wind/0006-Clarinet.xiz
diff --git a/banks/Reed and Wind/0007-Breathy1.xiz b/instruments/banks/Reed and Wind/0007-Breathy1.xiz
similarity index 100%
rename from banks/Reed and Wind/0007-Breathy1.xiz
rename to instruments/banks/Reed and Wind/0007-Breathy1.xiz
diff --git a/banks/Reed and Wind/0033-Reed 1.xiz b/instruments/banks/Reed and Wind/0033-Reed 1.xiz
similarity index 100%
rename from banks/Reed and Wind/0033-Reed 1.xiz
rename to instruments/banks/Reed and Wind/0033-Reed 1.xiz
diff --git a/banks/Reed and Wind/0034-Reed 2.xiz b/instruments/banks/Reed and Wind/0034-Reed 2.xiz
similarity index 100%
rename from banks/Reed and Wind/0034-Reed 2.xiz
rename to instruments/banks/Reed and Wind/0034-Reed 2.xiz
diff --git a/banks/Reed and Wind/0035-Reed 3.xiz b/instruments/banks/Reed and Wind/0035-Reed 3.xiz
similarity index 100%
rename from banks/Reed and Wind/0035-Reed 3.xiz
rename to instruments/banks/Reed and Wind/0035-Reed 3.xiz
diff --git a/banks/Reed and Wind/0036-Reed 4.xiz b/instruments/banks/Reed and Wind/0036-Reed 4.xiz
similarity index 100%
rename from banks/Reed and Wind/0036-Reed 4.xiz
rename to instruments/banks/Reed and Wind/0036-Reed 4.xiz
diff --git a/banks/Reed and Wind/0037-Reed 5.xiz b/instruments/banks/Reed and Wind/0037-Reed 5.xiz
similarity index 100%
rename from banks/Reed and Wind/0037-Reed 5.xiz
rename to instruments/banks/Reed and Wind/0037-Reed 5.xiz
diff --git a/banks/Reed and Wind/0038-Reed 6.xiz b/instruments/banks/Reed and Wind/0038-Reed 6.xiz
similarity index 100%
rename from banks/Reed and Wind/0038-Reed 6.xiz
rename to instruments/banks/Reed and Wind/0038-Reed 6.xiz
diff --git a/banks/Reed and Wind/0039-Reed 7.xiz b/instruments/banks/Reed and Wind/0039-Reed 7.xiz
similarity index 100%
rename from banks/Reed and Wind/0039-Reed 7.xiz
rename to instruments/banks/Reed and Wind/0039-Reed 7.xiz
diff --git a/banks/Reed and Wind/0040-Reed 8.xiz b/instruments/banks/Reed and Wind/0040-Reed 8.xiz
similarity index 100%
rename from banks/Reed and Wind/0040-Reed 8.xiz
rename to instruments/banks/Reed and Wind/0040-Reed 8.xiz
diff --git a/banks/Reed and Wind/0065-Fat Reed1.xiz b/instruments/banks/Reed and Wind/0065-Fat Reed1.xiz
similarity index 100%
rename from banks/Reed and Wind/0065-Fat Reed1.xiz
rename to instruments/banks/Reed and Wind/0065-Fat Reed1.xiz
diff --git a/banks/Reed and Wind/0066-Fat Reed2.xiz b/instruments/banks/Reed and Wind/0066-Fat Reed2.xiz
similarity index 100%
rename from banks/Reed and Wind/0066-Fat Reed2.xiz
rename to instruments/banks/Reed and Wind/0066-Fat Reed2.xiz
diff --git a/banks/Reed and Wind/0067-Fat Reed3 square.xiz b/instruments/banks/Reed and Wind/0067-Fat Reed3 square.xiz
similarity index 100%
rename from banks/Reed and Wind/0067-Fat Reed3 square.xiz
rename to instruments/banks/Reed and Wind/0067-Fat Reed3 square.xiz
diff --git a/banks/Reed and Wind/0068-Chorused Flute.xiz b/instruments/banks/Reed and Wind/0068-Chorused Flute.xiz
similarity index 100%
rename from banks/Reed and Wind/0068-Chorused Flute.xiz
rename to instruments/banks/Reed and Wind/0068-Chorused Flute.xiz
diff --git a/banks/Rhodes/0001-DX Rhodes 1.xiz b/instruments/banks/Rhodes/0001-DX Rhodes 1.xiz
similarity index 100%
rename from banks/Rhodes/0001-DX Rhodes 1.xiz
rename to instruments/banks/Rhodes/0001-DX Rhodes 1.xiz
diff --git a/banks/Rhodes/0002-DX Rhodes 2.xiz b/instruments/banks/Rhodes/0002-DX Rhodes 2.xiz
similarity index 100%
rename from banks/Rhodes/0002-DX Rhodes 2.xiz
rename to instruments/banks/Rhodes/0002-DX Rhodes 2.xiz
diff --git a/banks/Rhodes/0003-DX Rhodes 3.xiz b/instruments/banks/Rhodes/0003-DX Rhodes 3.xiz
similarity index 100%
rename from banks/Rhodes/0003-DX Rhodes 3.xiz
rename to instruments/banks/Rhodes/0003-DX Rhodes 3.xiz
diff --git a/banks/Rhodes/0004-DX Rhodes 4.xiz b/instruments/banks/Rhodes/0004-DX Rhodes 4.xiz
similarity index 100%
rename from banks/Rhodes/0004-DX Rhodes 4.xiz
rename to instruments/banks/Rhodes/0004-DX Rhodes 4.xiz
diff --git a/banks/Rhodes/0005-DX Rhodes 5.xiz b/instruments/banks/Rhodes/0005-DX Rhodes 5.xiz
similarity index 100%
rename from banks/Rhodes/0005-DX Rhodes 5.xiz
rename to instruments/banks/Rhodes/0005-DX Rhodes 5.xiz
diff --git a/banks/Rhodes/0007-Dig Rhodes.xiz b/instruments/banks/Rhodes/0007-Dig Rhodes.xiz
similarity index 100%
rename from banks/Rhodes/0007-Dig Rhodes.xiz
rename to instruments/banks/Rhodes/0007-Dig Rhodes.xiz
diff --git a/banks/Rhodes/0008-Synth Rhodes1.xiz b/instruments/banks/Rhodes/0008-Synth Rhodes1.xiz
similarity index 100%
rename from banks/Rhodes/0008-Synth Rhodes1.xiz
rename to instruments/banks/Rhodes/0008-Synth Rhodes1.xiz
diff --git a/banks/Rhodes/0009-Synth Rhodes2.xiz b/instruments/banks/Rhodes/0009-Synth Rhodes2.xiz
similarity index 100%
rename from banks/Rhodes/0009-Synth Rhodes2.xiz
rename to instruments/banks/Rhodes/0009-Synth Rhodes2.xiz
diff --git a/banks/Rhodes/0010-Synth Rhodes3.xiz b/instruments/banks/Rhodes/0010-Synth Rhodes3.xiz
similarity index 100%
rename from banks/Rhodes/0010-Synth Rhodes3.xiz
rename to instruments/banks/Rhodes/0010-Synth Rhodes3.xiz
diff --git a/banks/Rhodes/0012-Ice Rhodes1.xiz b/instruments/banks/Rhodes/0012-Ice Rhodes1.xiz
similarity index 100%
rename from banks/Rhodes/0012-Ice Rhodes1.xiz
rename to instruments/banks/Rhodes/0012-Ice Rhodes1.xiz
diff --git a/banks/Rhodes/0013-Ice Rhodes2.xiz b/instruments/banks/Rhodes/0013-Ice Rhodes2.xiz
similarity index 100%
rename from banks/Rhodes/0013-Ice Rhodes2.xiz
rename to instruments/banks/Rhodes/0013-Ice Rhodes2.xiz
diff --git a/banks/Rhodes/0014-Ice Rhodes3.xiz b/instruments/banks/Rhodes/0014-Ice Rhodes3.xiz
similarity index 100%
rename from banks/Rhodes/0014-Ice Rhodes3.xiz
rename to instruments/banks/Rhodes/0014-Ice Rhodes3.xiz
diff --git a/banks/Rhodes/0033-FM Rhodes 1.xiz b/instruments/banks/Rhodes/0033-FM Rhodes 1.xiz
similarity index 100%
rename from banks/Rhodes/0033-FM Rhodes 1.xiz
rename to instruments/banks/Rhodes/0033-FM Rhodes 1.xiz
diff --git a/banks/Rhodes/0034-FM Rhodes 2.xiz b/instruments/banks/Rhodes/0034-FM Rhodes 2.xiz
similarity index 100%
rename from banks/Rhodes/0034-FM Rhodes 2.xiz
rename to instruments/banks/Rhodes/0034-FM Rhodes 2.xiz
diff --git a/banks/Rhodes/0035-FM Rhodes 3.xiz b/instruments/banks/Rhodes/0035-FM Rhodes 3.xiz
similarity index 100%
rename from banks/Rhodes/0035-FM Rhodes 3.xiz
rename to instruments/banks/Rhodes/0035-FM Rhodes 3.xiz
diff --git a/banks/Rhodes/0036-FM Rhodes 4.xiz b/instruments/banks/Rhodes/0036-FM Rhodes 4.xiz
similarity index 100%
rename from banks/Rhodes/0036-FM Rhodes 4.xiz
rename to instruments/banks/Rhodes/0036-FM Rhodes 4.xiz
diff --git a/banks/Rhodes/0037-FM Rhodes 5.xiz b/instruments/banks/Rhodes/0037-FM Rhodes 5.xiz
similarity index 100%
rename from banks/Rhodes/0037-FM Rhodes 5.xiz
rename to instruments/banks/Rhodes/0037-FM Rhodes 5.xiz
diff --git a/banks/Rhodes/0038-FM Rhodes 6.xiz b/instruments/banks/Rhodes/0038-FM Rhodes 6.xiz
similarity index 100%
rename from banks/Rhodes/0038-FM Rhodes 6.xiz
rename to instruments/banks/Rhodes/0038-FM Rhodes 6.xiz
diff --git a/banks/Rhodes/0041-Soft Rhodes.xiz b/instruments/banks/Rhodes/0041-Soft Rhodes.xiz
similarity index 100%
rename from banks/Rhodes/0041-Soft Rhodes.xiz
rename to instruments/banks/Rhodes/0041-Soft Rhodes.xiz
diff --git a/banks/Rhodes/0042-Hard Rhodes1.xiz b/instruments/banks/Rhodes/0042-Hard Rhodes1.xiz
similarity index 100%
rename from banks/Rhodes/0042-Hard Rhodes1.xiz
rename to instruments/banks/Rhodes/0042-Hard Rhodes1.xiz
diff --git a/banks/Rhodes/0043-Hard Rhodes2.xiz b/instruments/banks/Rhodes/0043-Hard Rhodes2.xiz
similarity index 100%
rename from banks/Rhodes/0043-Hard Rhodes2.xiz
rename to instruments/banks/Rhodes/0043-Hard Rhodes2.xiz
diff --git a/banks/Rhodes/0044-Echo Rhodes.xiz b/instruments/banks/Rhodes/0044-Echo Rhodes.xiz
similarity index 100%
rename from banks/Rhodes/0044-Echo Rhodes.xiz
rename to instruments/banks/Rhodes/0044-Echo Rhodes.xiz
diff --git a/banks/Rhodes/0045-A long time ago.xiz b/instruments/banks/Rhodes/0045-A long time ago.xiz
similarity index 100%
rename from banks/Rhodes/0045-A long time ago.xiz
rename to instruments/banks/Rhodes/0045-A long time ago.xiz
diff --git a/banks/Rhodes/0065-Steel Rhodes.xiz b/instruments/banks/Rhodes/0065-Steel Rhodes.xiz
similarity index 100%
rename from banks/Rhodes/0065-Steel Rhodes.xiz
rename to instruments/banks/Rhodes/0065-Steel Rhodes.xiz
diff --git a/banks/Rhodes/0067-RhodesPad1.xiz b/instruments/banks/Rhodes/0067-RhodesPad1.xiz
similarity index 100%
rename from banks/Rhodes/0067-RhodesPad1.xiz
rename to instruments/banks/Rhodes/0067-RhodesPad1.xiz
diff --git a/banks/Rhodes/0068-RhodesPad2.xiz b/instruments/banks/Rhodes/0068-RhodesPad2.xiz
similarity index 100%
rename from banks/Rhodes/0068-RhodesPad2.xiz
rename to instruments/banks/Rhodes/0068-RhodesPad2.xiz
diff --git a/banks/Splited/0001-Strings and Reed1.xiz b/instruments/banks/Splited/0001-Strings and Reed1.xiz
similarity index 100%
rename from banks/Splited/0001-Strings and Reed1.xiz
rename to instruments/banks/Splited/0001-Strings and Reed1.xiz
diff --git a/banks/Splited/0002-Strings and Reed2.xiz b/instruments/banks/Splited/0002-Strings and Reed2.xiz
similarity index 100%
rename from banks/Splited/0002-Strings and Reed2.xiz
rename to instruments/banks/Splited/0002-Strings and Reed2.xiz
diff --git a/banks/Splited/0003-Strings and Flute.xiz b/instruments/banks/Splited/0003-Strings and Flute.xiz
similarity index 100%
rename from banks/Splited/0003-Strings and Flute.xiz
rename to instruments/banks/Splited/0003-Strings and Flute.xiz
diff --git a/banks/Splited/0033-Choir and Reed.xiz b/instruments/banks/Splited/0033-Choir and Reed.xiz
similarity index 100%
rename from banks/Splited/0033-Choir and Reed.xiz
rename to instruments/banks/Splited/0033-Choir and Reed.xiz
diff --git a/banks/Strings/0001-Saw Strings 1.xiz b/instruments/banks/Strings/0001-Saw Strings 1.xiz
similarity index 100%
rename from banks/Strings/0001-Saw Strings 1.xiz
rename to instruments/banks/Strings/0001-Saw Strings 1.xiz
diff --git a/banks/Strings/0002-Saw Strings 2.xiz b/instruments/banks/Strings/0002-Saw Strings 2.xiz
similarity index 100%
rename from banks/Strings/0002-Saw Strings 2.xiz
rename to instruments/banks/Strings/0002-Saw Strings 2.xiz
diff --git a/banks/Strings/0003-Saw Strings 3.xiz b/instruments/banks/Strings/0003-Saw Strings 3.xiz
similarity index 100%
rename from banks/Strings/0003-Saw Strings 3.xiz
rename to instruments/banks/Strings/0003-Saw Strings 3.xiz
diff --git a/banks/Strings/0004-Saw Strings 4.xiz b/instruments/banks/Strings/0004-Saw Strings 4.xiz
similarity index 100%
rename from banks/Strings/0004-Saw Strings 4.xiz
rename to instruments/banks/Strings/0004-Saw Strings 4.xiz
diff --git a/banks/Strings/0005-Saw Strings 5.xiz b/instruments/banks/Strings/0005-Saw Strings 5.xiz
similarity index 100%
rename from banks/Strings/0005-Saw Strings 5.xiz
rename to instruments/banks/Strings/0005-Saw Strings 5.xiz
diff --git a/banks/Strings/0006-Saw Strings 6.xiz b/instruments/banks/Strings/0006-Saw Strings 6.xiz
similarity index 100%
rename from banks/Strings/0006-Saw Strings 6.xiz
rename to instruments/banks/Strings/0006-Saw Strings 6.xiz
diff --git a/banks/Strings/0007-Saw Strings 7.xiz b/instruments/banks/Strings/0007-Saw Strings 7.xiz
similarity index 100%
rename from banks/Strings/0007-Saw Strings 7.xiz
rename to instruments/banks/Strings/0007-Saw Strings 7.xiz
diff --git a/banks/Strings/0008-Saw Strings 8.xiz b/instruments/banks/Strings/0008-Saw Strings 8.xiz
similarity index 100%
rename from banks/Strings/0008-Saw Strings 8.xiz
rename to instruments/banks/Strings/0008-Saw Strings 8.xiz
diff --git a/banks/Strings/0010-Strings Pad1.xiz b/instruments/banks/Strings/0010-Strings Pad1.xiz
similarity index 100%
rename from banks/Strings/0010-Strings Pad1.xiz
rename to instruments/banks/Strings/0010-Strings Pad1.xiz
diff --git a/banks/Strings/0011-Strings Pad2.xiz b/instruments/banks/Strings/0011-Strings Pad2.xiz
similarity index 100%
rename from banks/Strings/0011-Strings Pad2.xiz
rename to instruments/banks/Strings/0011-Strings Pad2.xiz
diff --git a/banks/Strings/0012-Strings Pad3.xiz b/instruments/banks/Strings/0012-Strings Pad3.xiz
similarity index 100%
rename from banks/Strings/0012-Strings Pad3.xiz
rename to instruments/banks/Strings/0012-Strings Pad3.xiz
diff --git a/banks/Strings/0013-Strings Pad4.xiz b/instruments/banks/Strings/0013-Strings Pad4.xiz
similarity index 100%
rename from banks/Strings/0013-Strings Pad4.xiz
rename to instruments/banks/Strings/0013-Strings Pad4.xiz
diff --git a/banks/Strings/0014-Strings Pad5.xiz b/instruments/banks/Strings/0014-Strings Pad5.xiz
similarity index 100%
rename from banks/Strings/0014-Strings Pad5.xiz
rename to instruments/banks/Strings/0014-Strings Pad5.xiz
diff --git a/banks/Strings/0015-Strings Pad6.xiz b/instruments/banks/Strings/0015-Strings Pad6.xiz
similarity index 100%
rename from banks/Strings/0015-Strings Pad6.xiz
rename to instruments/banks/Strings/0015-Strings Pad6.xiz
diff --git a/banks/Strings/0016-Sweep Pad 1.xiz b/instruments/banks/Strings/0016-Sweep Pad 1.xiz
similarity index 100%
rename from banks/Strings/0016-Sweep Pad 1.xiz
rename to instruments/banks/Strings/0016-Sweep Pad 1.xiz
diff --git a/banks/Strings/0017-Sweep Pad 1 Fat.xiz b/instruments/banks/Strings/0017-Sweep Pad 1 Fat.xiz
similarity index 100%
rename from banks/Strings/0017-Sweep Pad 1 Fat.xiz
rename to instruments/banks/Strings/0017-Sweep Pad 1 Fat.xiz
diff --git a/banks/Strings/0018-Sweep Pad 2.xiz b/instruments/banks/Strings/0018-Sweep Pad 2.xiz
similarity index 100%
rename from banks/Strings/0018-Sweep Pad 2.xiz
rename to instruments/banks/Strings/0018-Sweep Pad 2.xiz
diff --git a/banks/Strings/0019-Sweep Pad 3Wah.xiz b/instruments/banks/Strings/0019-Sweep Pad 3Wah.xiz
similarity index 100%
rename from banks/Strings/0019-Sweep Pad 3Wah.xiz
rename to instruments/banks/Strings/0019-Sweep Pad 3Wah.xiz
diff --git a/banks/Strings/0020-Sweep Pad 4.xiz b/instruments/banks/Strings/0020-Sweep Pad 4.xiz
similarity index 100%
rename from banks/Strings/0020-Sweep Pad 4.xiz
rename to instruments/banks/Strings/0020-Sweep Pad 4.xiz
diff --git a/banks/Strings/0033-Strings1.xiz b/instruments/banks/Strings/0033-Strings1.xiz
similarity index 100%
rename from banks/Strings/0033-Strings1.xiz
rename to instruments/banks/Strings/0033-Strings1.xiz
diff --git a/banks/Strings/0034-Dark Strings.xiz b/instruments/banks/Strings/0034-Dark Strings.xiz
similarity index 100%
rename from banks/Strings/0034-Dark Strings.xiz
rename to instruments/banks/Strings/0034-Dark Strings.xiz
diff --git a/banks/Strings/0035-Octave Pad.xiz b/instruments/banks/Strings/0035-Octave Pad.xiz
similarity index 100%
rename from banks/Strings/0035-Octave Pad.xiz
rename to instruments/banks/Strings/0035-Octave Pad.xiz
diff --git a/banks/Strings/0036-Fast Attack.xiz b/instruments/banks/Strings/0036-Fast Attack.xiz
similarity index 100%
rename from banks/Strings/0036-Fast Attack.xiz
rename to instruments/banks/Strings/0036-Fast Attack.xiz
diff --git a/banks/Strings/0038-Fat Saw.xiz b/instruments/banks/Strings/0038-Fat Saw.xiz
similarity index 100%
rename from banks/Strings/0038-Fat Saw.xiz
rename to instruments/banks/Strings/0038-Fat Saw.xiz
diff --git a/banks/Strings/0041-Saw 1.xiz b/instruments/banks/Strings/0041-Saw 1.xiz
similarity index 100%
rename from banks/Strings/0041-Saw 1.xiz
rename to instruments/banks/Strings/0041-Saw 1.xiz
diff --git a/banks/Strings/0042-Saw 2.xiz b/instruments/banks/Strings/0042-Saw 2.xiz
similarity index 100%
rename from banks/Strings/0042-Saw 2.xiz
rename to instruments/banks/Strings/0042-Saw 2.xiz
diff --git a/banks/Strings/0043-Saw 3.xiz b/instruments/banks/Strings/0043-Saw 3.xiz
similarity index 100%
rename from banks/Strings/0043-Saw 3.xiz
rename to instruments/banks/Strings/0043-Saw 3.xiz
diff --git a/banks/Strings/0044-Saw Pad.xiz b/instruments/banks/Strings/0044-Saw Pad.xiz
similarity index 100%
rename from banks/Strings/0044-Saw Pad.xiz
rename to instruments/banks/Strings/0044-Saw Pad.xiz
diff --git a/banks/Strings/0045-Soft Saw Pad.xiz b/instruments/banks/Strings/0045-Soft Saw Pad.xiz
similarity index 100%
rename from banks/Strings/0045-Soft Saw Pad.xiz
rename to instruments/banks/Strings/0045-Soft Saw Pad.xiz
diff --git a/banks/Strings/0046-Echoed Saw.xiz b/instruments/banks/Strings/0046-Echoed Saw.xiz
similarity index 100%
rename from banks/Strings/0046-Echoed Saw.xiz
rename to instruments/banks/Strings/0046-Echoed Saw.xiz
diff --git a/banks/Strings/0047-Vibratto Saw1.xiz b/instruments/banks/Strings/0047-Vibratto Saw1.xiz
similarity index 100%
rename from banks/Strings/0047-Vibratto Saw1.xiz
rename to instruments/banks/Strings/0047-Vibratto Saw1.xiz
diff --git a/banks/Strings/0048-Wah1.xiz b/instruments/banks/Strings/0048-Wah1.xiz
similarity index 100%
rename from banks/Strings/0048-Wah1.xiz
rename to instruments/banks/Strings/0048-Wah1.xiz
diff --git a/banks/Strings/0050-Synth Violin 1.xiz b/instruments/banks/Strings/0050-Synth Violin 1.xiz
similarity index 100%
rename from banks/Strings/0050-Synth Violin 1.xiz
rename to instruments/banks/Strings/0050-Synth Violin 1.xiz
diff --git a/banks/Strings/0051-Synth Violin 2 Fat.xiz b/instruments/banks/Strings/0051-Synth Violin 2 Fat.xiz
similarity index 100%
rename from banks/Strings/0051-Synth Violin 2 Fat.xiz
rename to instruments/banks/Strings/0051-Synth Violin 2 Fat.xiz
diff --git a/banks/Strings/0065-Simple Strings.xiz b/instruments/banks/Strings/0065-Simple Strings.xiz
similarity index 100%
rename from banks/Strings/0065-Simple Strings.xiz
rename to instruments/banks/Strings/0065-Simple Strings.xiz
diff --git a/banks/Strings/0066-Dual Strings.xiz b/instruments/banks/Strings/0066-Dual Strings.xiz
similarity index 100%
rename from banks/Strings/0066-Dual Strings.xiz
rename to instruments/banks/Strings/0066-Dual Strings.xiz
diff --git a/banks/Strings/0067-Dual Strings Oct1.xiz b/instruments/banks/Strings/0067-Dual Strings Oct1.xiz
similarity index 100%
rename from banks/Strings/0067-Dual Strings Oct1.xiz
rename to instruments/banks/Strings/0067-Dual Strings Oct1.xiz
diff --git a/banks/Strings/0068-Dual Strings Oct2.xiz b/instruments/banks/Strings/0068-Dual Strings Oct2.xiz
similarity index 100%
rename from banks/Strings/0068-Dual Strings Oct2.xiz
rename to instruments/banks/Strings/0068-Dual Strings Oct2.xiz
diff --git a/banks/Strings/0073-Morph Strings1.xiz b/instruments/banks/Strings/0073-Morph Strings1.xiz
similarity index 100%
rename from banks/Strings/0073-Morph Strings1.xiz
rename to instruments/banks/Strings/0073-Morph Strings1.xiz
diff --git a/banks/Synth/0001-Soft Synth 1.xiz b/instruments/banks/Synth/0001-Soft Synth 1.xiz
similarity index 100%
rename from banks/Synth/0001-Soft Synth 1.xiz
rename to instruments/banks/Synth/0001-Soft Synth 1.xiz
diff --git a/banks/Synth/0002-Soft Synth 2.xiz b/instruments/banks/Synth/0002-Soft Synth 2.xiz
similarity index 100%
rename from banks/Synth/0002-Soft Synth 2.xiz
rename to instruments/banks/Synth/0002-Soft Synth 2.xiz
diff --git a/banks/Synth/0004-Pulse Pad 1.xiz b/instruments/banks/Synth/0004-Pulse Pad 1.xiz
similarity index 100%
rename from banks/Synth/0004-Pulse Pad 1.xiz
rename to instruments/banks/Synth/0004-Pulse Pad 1.xiz
diff --git a/banks/Synth/0005-Pulse Pad 2.xiz b/instruments/banks/Synth/0005-Pulse Pad 2.xiz
similarity index 100%
rename from banks/Synth/0005-Pulse Pad 2.xiz
rename to instruments/banks/Synth/0005-Pulse Pad 2.xiz
diff --git a/banks/Synth/0006-Pulse Pad 3.xiz b/instruments/banks/Synth/0006-Pulse Pad 3.xiz
similarity index 100%
rename from banks/Synth/0006-Pulse Pad 3.xiz
rename to instruments/banks/Synth/0006-Pulse Pad 3.xiz
diff --git a/banks/Synth/0007-Analog Filter 1.xiz b/instruments/banks/Synth/0007-Analog Filter 1.xiz
similarity index 100%
rename from banks/Synth/0007-Analog Filter 1.xiz
rename to instruments/banks/Synth/0007-Analog Filter 1.xiz
diff --git a/banks/Synth/0008-Analog Filter 2.xiz b/instruments/banks/Synth/0008-Analog Filter 2.xiz
similarity index 100%
rename from banks/Synth/0008-Analog Filter 2.xiz
rename to instruments/banks/Synth/0008-Analog Filter 2.xiz
diff --git a/banks/Synth/0033-Phased Pad 1.xiz b/instruments/banks/Synth/0033-Phased Pad 1.xiz
similarity index 100%
rename from banks/Synth/0033-Phased Pad 1.xiz
rename to instruments/banks/Synth/0033-Phased Pad 1.xiz
diff --git a/banks/Synth/0034-Phased Pad 2.xiz b/instruments/banks/Synth/0034-Phased Pad 2.xiz
similarity index 100%
rename from banks/Synth/0034-Phased Pad 2.xiz
rename to instruments/banks/Synth/0034-Phased Pad 2.xiz
diff --git a/banks/Synth/0035-Phased Pad 3.xiz b/instruments/banks/Synth/0035-Phased Pad 3.xiz
similarity index 100%
rename from banks/Synth/0035-Phased Pad 3.xiz
rename to instruments/banks/Synth/0035-Phased Pad 3.xiz
diff --git a/banks/Synth/0037-Resonance Synth.xiz b/instruments/banks/Synth/0037-Resonance Synth.xiz
similarity index 100%
rename from banks/Synth/0037-Resonance Synth.xiz
rename to instruments/banks/Synth/0037-Resonance Synth.xiz
diff --git a/banks/Synth/0039-Multi-phase synth.xiz b/instruments/banks/Synth/0039-Multi-phase synth.xiz
similarity index 100%
rename from banks/Synth/0039-Multi-phase synth.xiz
rename to instruments/banks/Synth/0039-Multi-phase synth.xiz
diff --git a/banks/Synth/0065-Computer Lead1.xiz b/instruments/banks/Synth/0065-Computer Lead1.xiz
similarity index 100%
rename from banks/Synth/0065-Computer Lead1.xiz
rename to instruments/banks/Synth/0065-Computer Lead1.xiz
diff --git a/banks/Synth/0066-Computer Lead2.xiz b/instruments/banks/Synth/0066-Computer Lead2.xiz
similarity index 100%
rename from banks/Synth/0066-Computer Lead2.xiz
rename to instruments/banks/Synth/0066-Computer Lead2.xiz
diff --git a/banks/Synth/0067-Detuned Harmonic.xiz b/instruments/banks/Synth/0067-Detuned Harmonic.xiz
similarity index 100%
rename from banks/Synth/0067-Detuned Harmonic.xiz
rename to instruments/banks/Synth/0067-Detuned Harmonic.xiz
diff --git a/banks/Synth/0070-Solo Synth 1.xiz b/instruments/banks/Synth/0070-Solo Synth 1.xiz
similarity index 100%
rename from banks/Synth/0070-Solo Synth 1.xiz
rename to instruments/banks/Synth/0070-Solo Synth 1.xiz
diff --git a/banks/Synth/0097-FM Synth.xiz b/instruments/banks/Synth/0097-FM Synth.xiz
similarity index 100%
rename from banks/Synth/0097-FM Synth.xiz
rename to instruments/banks/Synth/0097-FM Synth.xiz
diff --git a/banks/SynthPiano/0001-Soft Piano 1.xiz b/instruments/banks/SynthPiano/0001-Soft Piano 1.xiz
similarity index 100%
rename from banks/SynthPiano/0001-Soft Piano 1.xiz
rename to instruments/banks/SynthPiano/0001-Soft Piano 1.xiz
diff --git a/banks/SynthPiano/0002-Soft Piano 2.xiz b/instruments/banks/SynthPiano/0002-Soft Piano 2.xiz
similarity index 100%
rename from banks/SynthPiano/0002-Soft Piano 2.xiz
rename to instruments/banks/SynthPiano/0002-Soft Piano 2.xiz
diff --git a/banks/SynthPiano/0004-Fantasy Bell.xiz b/instruments/banks/SynthPiano/0004-Fantasy Bell.xiz
similarity index 100%
rename from banks/SynthPiano/0004-Fantasy Bell.xiz
rename to instruments/banks/SynthPiano/0004-Fantasy Bell.xiz
diff --git a/banks/SynthPiano/0005-Synth Piano1.xiz b/instruments/banks/SynthPiano/0005-Synth Piano1.xiz
similarity index 100%
rename from banks/SynthPiano/0005-Synth Piano1.xiz
rename to instruments/banks/SynthPiano/0005-Synth Piano1.xiz
diff --git a/banks/SynthPiano/0006-Synth Piano2.xiz b/instruments/banks/SynthPiano/0006-Synth Piano2.xiz
similarity index 100%
rename from banks/SynthPiano/0006-Synth Piano2.xiz
rename to instruments/banks/SynthPiano/0006-Synth Piano2.xiz
diff --git a/banks/SynthPiano/0007-Termollo1.xiz b/instruments/banks/SynthPiano/0007-Termollo1.xiz
similarity index 100%
rename from banks/SynthPiano/0007-Termollo1.xiz
rename to instruments/banks/SynthPiano/0007-Termollo1.xiz
diff --git a/banks/SynthPiano/0008-Termollo2.xiz b/instruments/banks/SynthPiano/0008-Termollo2.xiz
similarity index 100%
rename from banks/SynthPiano/0008-Termollo2.xiz
rename to instruments/banks/SynthPiano/0008-Termollo2.xiz
diff --git a/banks/SynthPiano/0009-Termollo3.xiz b/instruments/banks/SynthPiano/0009-Termollo3.xiz
similarity index 100%
rename from banks/SynthPiano/0009-Termollo3.xiz
rename to instruments/banks/SynthPiano/0009-Termollo3.xiz
diff --git a/banks/SynthPiano/0011-Drop1.xiz b/instruments/banks/SynthPiano/0011-Drop1.xiz
similarity index 100%
rename from banks/SynthPiano/0011-Drop1.xiz
rename to instruments/banks/SynthPiano/0011-Drop1.xiz
diff --git a/banks/SynthPiano/0012-Drop2.xiz b/instruments/banks/SynthPiano/0012-Drop2.xiz
similarity index 100%
rename from banks/SynthPiano/0012-Drop2.xiz
rename to instruments/banks/SynthPiano/0012-Drop2.xiz
diff --git a/banks/SynthPiano/0033-Analog Piano 1.xiz b/instruments/banks/SynthPiano/0033-Analog Piano 1.xiz
similarity index 100%
rename from banks/SynthPiano/0033-Analog Piano 1.xiz
rename to instruments/banks/SynthPiano/0033-Analog Piano 1.xiz
diff --git a/banks/SynthPiano/0034-Analog Piano 2.xiz b/instruments/banks/SynthPiano/0034-Analog Piano 2.xiz
similarity index 100%
rename from banks/SynthPiano/0034-Analog Piano 2.xiz
rename to instruments/banks/SynthPiano/0034-Analog Piano 2.xiz
diff --git a/banks/SynthPiano/0035-Analog Piano 3.xiz b/instruments/banks/SynthPiano/0035-Analog Piano 3.xiz
similarity index 100%
rename from banks/SynthPiano/0035-Analog Piano 3.xiz
rename to instruments/banks/SynthPiano/0035-Analog Piano 3.xiz
diff --git a/banks/SynthPiano/0037-FM Synth1.xiz b/instruments/banks/SynthPiano/0037-FM Synth1.xiz
similarity index 100%
rename from banks/SynthPiano/0037-FM Synth1.xiz
rename to instruments/banks/SynthPiano/0037-FM Synth1.xiz
diff --git a/banks/SynthPiano/0039-BinaryPiano1.xiz b/instruments/banks/SynthPiano/0039-BinaryPiano1.xiz
similarity index 100%
rename from banks/SynthPiano/0039-BinaryPiano1.xiz
rename to instruments/banks/SynthPiano/0039-BinaryPiano1.xiz
diff --git a/banks/SynthPiano/0040-BinaryPiano2.xiz b/instruments/banks/SynthPiano/0040-BinaryPiano2.xiz
similarity index 100%
rename from banks/SynthPiano/0040-BinaryPiano2.xiz
rename to instruments/banks/SynthPiano/0040-BinaryPiano2.xiz
diff --git a/banks/SynthPiano/0043-Saw Piano 1.xiz b/instruments/banks/SynthPiano/0043-Saw Piano 1.xiz
similarity index 100%
rename from banks/SynthPiano/0043-Saw Piano 1.xiz
rename to instruments/banks/SynthPiano/0043-Saw Piano 1.xiz
diff --git a/banks/SynthPiano/0065-Synth Piano 1.xiz b/instruments/banks/SynthPiano/0065-Synth Piano 1.xiz
similarity index 100%
rename from banks/SynthPiano/0065-Synth Piano 1.xiz
rename to instruments/banks/SynthPiano/0065-Synth Piano 1.xiz
diff --git a/banks/SynthPiano/0066-Synth Piano 2.xiz b/instruments/banks/SynthPiano/0066-Synth Piano 2.xiz
similarity index 100%
rename from banks/SynthPiano/0066-Synth Piano 2.xiz
rename to instruments/banks/SynthPiano/0066-Synth Piano 2.xiz
diff --git a/banks/SynthPiano/0067-Synth Piano 3.xiz b/instruments/banks/SynthPiano/0067-Synth Piano 3.xiz
similarity index 100%
rename from banks/SynthPiano/0067-Synth Piano 3.xiz
rename to instruments/banks/SynthPiano/0067-Synth Piano 3.xiz
diff --git a/banks/SynthPiano/0068-Synth Piano 3 fat.xiz b/instruments/banks/SynthPiano/0068-Synth Piano 3 fat.xiz
similarity index 100%
rename from banks/SynthPiano/0068-Synth Piano 3 fat.xiz
rename to instruments/banks/SynthPiano/0068-Synth Piano 3 fat.xiz
diff --git a/banks/SynthPiano/0069-Synth Piano 3 det.xiz b/instruments/banks/SynthPiano/0069-Synth Piano 3 det.xiz
similarity index 100%
rename from banks/SynthPiano/0069-Synth Piano 3 det.xiz
rename to instruments/banks/SynthPiano/0069-Synth Piano 3 det.xiz
diff --git a/banks/SynthPiano/0070-Synth Piano 4.xiz b/instruments/banks/SynthPiano/0070-Synth Piano 4.xiz
similarity index 100%
rename from banks/SynthPiano/0070-Synth Piano 4.xiz
rename to instruments/banks/SynthPiano/0070-Synth Piano 4.xiz
diff --git a/banks/SynthPiano/0071-Synth Piano 5.xiz b/instruments/banks/SynthPiano/0071-Synth Piano 5.xiz
similarity index 100%
rename from banks/SynthPiano/0071-Synth Piano 5.xiz
rename to instruments/banks/SynthPiano/0071-Synth Piano 5.xiz
diff --git a/examples/0km.xmz b/instruments/examples/0km.xmz
similarity index 100%
rename from examples/0km.xmz
rename to instruments/examples/0km.xmz
diff --git a/examples/Arpeggio 1.xmz b/instruments/examples/Arpeggio 1.xmz
similarity index 100%
rename from examples/Arpeggio 1.xmz
rename to instruments/examples/Arpeggio 1.xmz
diff --git a/examples/Arpeggio 2.xmz b/instruments/examples/Arpeggio 2.xmz
similarity index 100%
rename from examples/Arpeggio 2.xmz
rename to instruments/examples/Arpeggio 2.xmz
diff --git a/examples/Arpeggio 3.xmz b/instruments/examples/Arpeggio 3.xmz
similarity index 100%
rename from examples/Arpeggio 3.xmz
rename to instruments/examples/Arpeggio 3.xmz
diff --git a/examples/Arpeggio 4.xmz b/instruments/examples/Arpeggio 4.xmz
similarity index 100%
rename from examples/Arpeggio 4.xmz
rename to instruments/examples/Arpeggio 4.xmz
diff --git a/examples/Arpeggio 5.xmz b/instruments/examples/Arpeggio 5.xmz
similarity index 100%
rename from examples/Arpeggio 5.xmz
rename to instruments/examples/Arpeggio 5.xmz
diff --git a/examples/Arpeggio 6.xmz b/instruments/examples/Arpeggio 6.xmz
similarity index 100%
rename from examples/Arpeggio 6.xmz
rename to instruments/examples/Arpeggio 6.xmz
diff --git a/examples/Arpeggio Dist 1.xmz b/instruments/examples/Arpeggio Dist 1.xmz
similarity index 100%
rename from examples/Arpeggio Dist 1.xmz
rename to instruments/examples/Arpeggio Dist 1.xmz
diff --git a/examples/Arpeggio Dist 2.xmz b/instruments/examples/Arpeggio Dist 2.xmz
similarity index 100%
rename from examples/Arpeggio Dist 2.xmz
rename to instruments/examples/Arpeggio Dist 2.xmz
diff --git a/examples/Arpeggio Flange 1.xmz b/instruments/examples/Arpeggio Flange 1.xmz
similarity index 100%
rename from examples/Arpeggio Flange 1.xmz
rename to instruments/examples/Arpeggio Flange 1.xmz
diff --git a/examples/Arpeggio Flange 2.xmz b/instruments/examples/Arpeggio Flange 2.xmz
similarity index 100%
rename from examples/Arpeggio Flange 2.xmz
rename to instruments/examples/Arpeggio Flange 2.xmz
diff --git a/examples/Choir Reeds.xmz b/instruments/examples/Choir Reeds.xmz
similarity index 100%
rename from examples/Choir Reeds.xmz
rename to instruments/examples/Choir Reeds.xmz
diff --git a/examples/Choir Strings SynthBrass.xmz b/instruments/examples/Choir Strings SynthBrass.xmz
similarity index 100%
rename from examples/Choir Strings SynthBrass.xmz
rename to instruments/examples/Choir Strings SynthBrass.xmz
diff --git a/examples/Dist Guitar Strings 1.xmz b/instruments/examples/Dist Guitar Strings 1.xmz
similarity index 100%
rename from examples/Dist Guitar Strings 1.xmz
rename to instruments/examples/Dist Guitar Strings 1.xmz
diff --git a/examples/Dist Guitar Strings 2.xmz b/instruments/examples/Dist Guitar Strings 2.xmz
similarity index 100%
rename from examples/Dist Guitar Strings 2.xmz
rename to instruments/examples/Dist Guitar Strings 2.xmz
diff --git a/examples/Drop.xmz b/instruments/examples/Drop.xmz
similarity index 100%
rename from examples/Drop.xmz
rename to instruments/examples/Drop.xmz
diff --git a/examples/Fantasy 1.xmz b/instruments/examples/Fantasy 1.xmz
similarity index 100%
rename from examples/Fantasy 1.xmz
rename to instruments/examples/Fantasy 1.xmz
diff --git a/examples/Fantasy 2.xmz b/instruments/examples/Fantasy 2.xmz
similarity index 100%
rename from examples/Fantasy 2.xmz
rename to instruments/examples/Fantasy 2.xmz
diff --git a/examples/Glass Choir.xmz b/instruments/examples/Glass Choir.xmz
similarity index 100%
rename from examples/Glass Choir.xmz
rename to instruments/examples/Glass Choir.xmz
diff --git a/examples/HighPass Saw Strings.xmz b/instruments/examples/HighPass Saw Strings.xmz
similarity index 100%
rename from examples/HighPass Saw Strings.xmz
rename to instruments/examples/HighPass Saw Strings.xmz
diff --git a/examples/Ice Rhodes Strings.xmz b/instruments/examples/Ice Rhodes Strings.xmz
similarity index 100%
rename from examples/Ice Rhodes Strings.xmz
rename to instruments/examples/Ice Rhodes Strings.xmz
diff --git a/examples/JI12.xsz b/instruments/examples/JI12.xsz
similarity index 100%
rename from examples/JI12.xsz
rename to instruments/examples/JI12.xsz
diff --git a/examples/Legatto 1.xmz b/instruments/examples/Legatto 1.xmz
similarity index 100%
rename from examples/Legatto 1.xmz
rename to instruments/examples/Legatto 1.xmz
diff --git a/examples/Legatto 2.xmz b/instruments/examples/Legatto 2.xmz
similarity index 100%
rename from examples/Legatto 2.xmz
rename to instruments/examples/Legatto 2.xmz
diff --git a/examples/Legatto Strings.xmz b/instruments/examples/Legatto Strings.xmz
similarity index 100%
rename from examples/Legatto Strings.xmz
rename to instruments/examples/Legatto Strings.xmz
diff --git a/examples/Octave Strings.xmz b/instruments/examples/Octave Strings.xmz
similarity index 100%
rename from examples/Octave Strings.xmz
rename to instruments/examples/Octave Strings.xmz
diff --git a/examples/Organ Choir Strings.xmz b/instruments/examples/Organ Choir Strings.xmz
similarity index 100%
rename from examples/Organ Choir Strings.xmz
rename to instruments/examples/Organ Choir Strings.xmz
diff --git a/examples/Saw.xmz b/instruments/examples/Saw.xmz
similarity index 100%
rename from examples/Saw.xmz
rename to instruments/examples/Saw.xmz
diff --git a/examples/Space 1.xmz b/instruments/examples/Space 1.xmz
similarity index 100%
rename from examples/Space 1.xmz
rename to instruments/examples/Space 1.xmz
diff --git a/examples/Space 2.xmz b/instruments/examples/Space 2.xmz
similarity index 100%
rename from examples/Space 2.xmz
rename to instruments/examples/Space 2.xmz
diff --git a/examples/Split_keyboard.xmz b/instruments/examples/Split_keyboard.xmz
similarity index 100%
rename from examples/Split_keyboard.xmz
rename to instruments/examples/Split_keyboard.xmz
diff --git a/examples/String Reverb.xmz b/instruments/examples/String Reverb.xmz
similarity index 100%
rename from examples/String Reverb.xmz
rename to instruments/examples/String Reverb.xmz
diff --git a/examples/Strings Reeds 1.xmz b/instruments/examples/Strings Reeds 1.xmz
similarity index 100%
rename from examples/Strings Reeds 1.xmz
rename to instruments/examples/Strings Reeds 1.xmz
diff --git a/examples/Strings Reeds 2.xmz b/instruments/examples/Strings Reeds 2.xmz
similarity index 100%
rename from examples/Strings Reeds 2.xmz
rename to instruments/examples/Strings Reeds 2.xmz
diff --git a/examples/Struck String Big Reverb 1.xmz b/instruments/examples/Struck String Big Reverb 1.xmz
similarity index 100%
rename from examples/Struck String Big Reverb 1.xmz
rename to instruments/examples/Struck String Big Reverb 1.xmz
diff --git a/examples/Struck String Big Reverb 2.xmz b/instruments/examples/Struck String Big Reverb 2.xmz
similarity index 100%
rename from examples/Struck String Big Reverb 2.xmz
rename to instruments/examples/Struck String Big Reverb 2.xmz
diff --git a/examples/Supersaw.xmz b/instruments/examples/Supersaw.xmz
similarity index 100%
rename from examples/Supersaw.xmz
rename to instruments/examples/Supersaw.xmz
diff --git a/examples/Synth Bells Choir Reverb.xmz b/instruments/examples/Synth Bells Choir Reverb.xmz
similarity index 100%
rename from examples/Synth Bells Choir Reverb.xmz
rename to instruments/examples/Synth Bells Choir Reverb.xmz
diff --git a/examples/Synth Piano Reverb.xmz b/instruments/examples/Synth Piano Reverb.xmz
similarity index 100%
rename from examples/Synth Piano Reverb.xmz
rename to instruments/examples/Synth Piano Reverb.xmz
diff --git a/examples/Synth.xmz b/instruments/examples/Synth.xmz
similarity index 100%
rename from examples/Synth.xmz
rename to instruments/examples/Synth.xmz
diff --git a/examples/bent_synth.xmz b/instruments/examples/bent_synth.xmz
similarity index 100%
rename from examples/bent_synth.xmz
rename to instruments/examples/bent_synth.xmz
diff --git a/examples/photons.xmz b/instruments/examples/photons.xmz
similarity index 100%
rename from examples/photons.xmz
rename to instruments/examples/photons.xmz
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..8ab8e74
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,321 @@
+#checking include/library paths
+message(STATUS "Checking Include Path" $ENV{CMAKE_INCLUDE_PATH} ${CMAKE_INCLUDE_PATH})
+message(STATUS "Checking Library Path" $ENV{CMAKE_LIBRARY_PATH} ${CMAKE_LIBRARY_PATH})
+
+#Dependency check
+find_package(PkgConfig REQUIRED)
+find_package(zlib REQUIRED)
+pkg_check_modules(FFTW REQUIRED fftw3)
+pkg_check_modules(MXML REQUIRED mxml)
+find_package(Threads   REQUIRED)
+find_package(OSS)
+find_package(Alsa)
+pkg_check_modules(JACK jack)
+pkg_check_modules(PORTAUDIO portaudio-2.0>=19)
+set(FLTK_SKIP_OPENGL true)
+find_package(FLTK)
+find_package(OpenGL) #for FLTK
+find_package(CxxTest)
+# lash
+pkg_search_module(LASH lash-1.0)
+mark_as_advanced(LASH_LIBRARIES)
+pkg_search_module(DSSI dssi>=0.9.0)
+mark_as_advanced(DSSI_LIBRARIES)
+pkg_search_module(LIBLO liblo>=0.26)
+mark_as_advanced(LIBLO_LIBRARIES)
+
+######### Settings ###########
+# NOTE: These cache variables should normally not be changed in this
+# file, but either in in CMakeCache.txt before compile, or by passing
+# parameters directly into cmake using the -D flag.
+SET (GuiModule fltk CACHE STRING "GUI module, either fltk, qt or off")
+SET (CompileTests ${CXXTEST_FOUND} CACHE BOOL "whether tests should be compiled in or not")
+SET (AlsaEnable ${ALSA_FOUND} CACHE BOOL
+    "Enable support for Advanced Linux Sound Architecture")
+SET (JackEnable ${JACK_FOUND} CACHE BOOL
+    "Enable support for JACK Audio Connection toolKit")
+SET (OssEnable ${OSS_FOUND} CACHE BOOL
+    "Enable support for Open Sound System")
+SET (PaEnable ${PORTAUDIO_FOUND} CACHE BOOL
+    "Enable support for Port Audio System")
+SET (LashEnable ${LASH_FOUND} CACHE BOOL
+    "Enable LASH Audio Session Handler")
+SET (DssiEnable ${DSSI_FOUND} CACHE BOOL
+    "Enable DSSI Plugin compilation")
+SET (LibloEnable ${LIBLO_FOUND} CACHE BOOL
+    "Enable Liblo")
+
+# Now, handle the incoming settings and set define flags/variables based
+# on this
+
+# Add version information
+add_definitions(-DVERSION="${VERSION}")
+
+# Give a good guess on the best Input/Output default backends
+if (JackEnable)
+    SET (DefaultOutput jack CACHE STRING
+        "Default Output module: [null, alsa, oss, jack, portaudio]")
+    # Override with perhaps more helpful midi backends
+    if (AlsaEnable)
+        SET (DefaultInput alsa CACHE STRING
+            "Default Input module: [null, alsa, oss, jack]")
+    elseif (OssEnable)
+        SET (DefaultInput oss CACHE STRING
+            "Default Input module: [null, alsa, oss, jack]")
+    else ()
+        SET (DefaultInput jack CACHE STRING
+            "Default Input module: [null, alsa, oss, jack]")
+    endif ()
+elseif (AlsaEnable)
+    SET (DefaultOutput alsa CACHE STRING
+        "Default Output module: [null, alsa, oss, jack, portaudio]")
+    SET (DefaultInput alsa CACHE STRING
+        "Default Input module: [null, alsa, oss, jack]")
+elseif (OssEnable)
+    SET (DefaultOutput oss CACHE STRING
+        "Default Output module: [null, alsa, oss, jack, portaudio]")
+    SET (DefaultInput oss CACHE STRING
+        "Default Input module: [null, alsa, oss, jack]")
+else()
+    SET (DefaultOutput null CACHE STRING
+        "Default Output module: [null, alsa, oss, jack, portaudio]")
+    SET (DefaultInput null CACHE STRING
+        "Default Input module: [null, alsa, oss, jack]")
+endif()
+
+
+
+if (GuiModule STREQUAL qt AND QT_FOUND)
+	set (QtGui TRUE)
+elseif(GuiModule STREQUAL fltk AND FLTK_FOUND)
+	set (FltkGui TRUE)
+elseif(GuiModule STREQUAL off)
+        add_definitions(-DDISABLE_GUI)
+else  ()
+        set (GuiModule off CACHE STRING "GUI module, either fltk, qt or off")
+        add_definitions(-DDISABLE_GUI)
+	message(STATUS "GUI module defaulting to off")
+endif()
+
+
+#Build Flags
+option (BuildForAMD_X86_64 "Build for AMD x86_64 system" OFF)
+option (BuildForCore2_X86_64 "Build for Intel Core2 x86_64 system" OFF)
+option (BuildForDebug "Include gdb debugging support" OFF)
+
+set(CMAKE_BUILD_TYPE "Release")
+
+set (BuildOptions_x86_64AMD
+    "-O3 -march=athlon64 -m64 -Wall -ffast-math -fno-finite-math-only -fomit-frame-pointer"
+  CACHE STRING "X86_64 compiler options"
+)
+
+set (BuildOptions_X86_64Core2
+    "-O3 -march=core2 -m64 -Wall -ffast-math -fno-finite-math-only -fomit-frame-pointer"
+  CACHE STRING "X86_64 compiler options"
+)
+
+set (BuildOptionsBasic
+    "-O3 -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer"
+    CACHE STRING "basic X86 complier options"
+)
+
+set (BuildOptionsDebug
+    "-O0 -g3 -ggdb -Wall -Wpointer-arith" CACHE STRING "Debug build flags")
+
+########### Settings dependant code ###########
+# From here on, the setting variables have  been prepared so concentrate
+# on the actual compiling.
+
+if(AlsaEnable)
+	list(APPEND AUDIO_LIBRARIES ${ASOUND_LIBRARY})
+	list(APPEND AUDIO_LIBRARY_DIRS ${ASOUND_LIBRARY_DIRS})
+	add_definitions(-DALSA=1)
+endif(AlsaEnable)
+
+if(JackEnable)
+	list(APPEND AUDIO_LIBRARIES ${JACK_LIBRARIES})
+	list(APPEND AUDIO_LIBRARY_DIRS ${JACK_LIBRARY_DIRS})
+	add_definitions(-DJACK=1)
+endif(JackEnable)
+
+if(OssEnable)
+	add_definitions(-DOSS=1)
+endif(OssEnable)
+
+if(PaEnable)
+	include_directories(${PORTAUDIO_INCLUDE_DIR})
+	add_definitions(-DPORTAUDIO=1)
+	list(APPEND AUDIO_LIBRARIES ${PORTAUDIO_LIBRARIES})
+	list(APPEND AUDIO_LIBRARY_DIRS ${PORTAUDIO_LIBRARY_DIRS})
+endif()
+
+if (CompileTests)
+	ENABLE_TESTING()
+endif()
+
+if(LashEnable)
+	include_directories(${LASH_INCLUDE_DIRS})
+	add_definitions(-DLASH=1)
+	list(APPEND AUDIO_LIBRARIES ${LASH_LIBRARIES})
+	list(APPEND AUDIO_LIBRARY_DIRS ${LASH_LIBRARY_DIRS})
+	message(STATUS "Compiling with lash")
+endif()
+if(LibloEnable)
+	include_directories(${LIBLO_INCLUDE_DIRS})
+	add_definitions(-DUSE_NSM=1)
+	list(APPEND AUDIO_LIBRARIES ${LIBLO_LIBRARIES})
+	list(APPEND AUDIO_LIBRARY_DIRS ${LIBLO_LIBRARY_DIRS})
+	message(STATUS "Compiling with liblo")
+endif()
+
+# other include directories
+include_directories(${ZLIB_INCLUDE_DIRS} ${MXML_INCLUDE_DIRS})
+
+add_definitions(
+	 -DASM_F2I_YES
+	 -g #TODO #todo put in a better location
+	 -Wall
+	 -Wextra
+	 )
+
+if (BuildForDebug)
+	set (CMAKE_BUILD_TYPE "Debug")
+	set (CMAKE_CXX_FLAGS_DEBUG ${BuildOptionsDebug})
+	message (STATUS "Building for ${CMAKE_BUILD_TYPE}, flags: ${CMAKE_CXX_FLAGS_DEBUG}")
+else (BuildForDebug)
+	set (CMAKE_BUILD_TYPE "Release")
+	if (BuildForAMD_X86_64)
+		set (CMAKE_CXX_FLAGS_RELEASE ${BuildOptions_x86_64AMD})
+	else (BuildForAMD_X86_64)
+		if (BuildForCore2_X86_64)
+			set (CMAKE_CXX_FLAGS_RELEASE ${BuildOptions_X86_64Core2})
+		else (BuildForCore2_X86_64)
+			set (CMAKE_CXX_FLAGS_RELEASE ${BuildOptionsBasic})
+		endif (BuildForCore2_X86_64)
+	endif (BuildForAMD_X86_64)
+	message (STATUS "Building for ${CMAKE_BUILD_TYPE}, flags: ${CMAKE_CXX_FLAGS_RELEASE}")
+endif (BuildForDebug)
+
+add_definitions(-fPIC)
+
+if(FLTK_FOUND)
+	mark_as_advanced(FORCE FLTK_BASE_LIBRARY)
+	mark_as_advanced(FORCE FLTK_CONFIG_SCRIPT)
+	mark_as_advanced(FORCE FLTK_DIR)
+	mark_as_advanced(FORCE FLTK_FLUID_EXECUTABLE)
+	mark_as_advanced(FORCE FLTK_FORMS_LIBRARY)
+	mark_as_advanced(FORCE FLTK_GL_LIBRARY)
+	mark_as_advanced(FORCE FLTK_IMAGES_LIBRARY)
+	mark_as_advanced(FORCE FLTK_INCLUDE_DIR)
+	mark_as_advanced(FORCE FLTK_MATH_LIBRARY)
+endif(FLTK_FOUND)
+
+if(FltkGui)
+	#UGLY WORKAROUND
+	find_program (MYFLTK_CONFIG fltk-config)
+	if (MYFLTK_CONFIG)
+		execute_process (COMMAND ${MYFLTK_CONFIG} --ldflags OUTPUT_VARIABLE MYFLTK_LDFLAGS)
+		string(STRIP ${MYFLTK_LDFLAGS} MYFLTK_LIBRARIES)
+	endif()
+
+	message(STATUS ${MYFLTK_LDFLAGS})
+
+
+	set(GUI_LIBRARIES ${FLTK_LIBRARIES} ${MYFLTK_LIBRARIES} ${OPENGL_LIBRARIES} zynaddsubfx_gui)
+
+	add_definitions(-DFLTK_GUI)
+
+	message(STATUS "Will build fltk gui")
+
+	include_directories(
+			${FLTK_INCLUDE_DIR}
+			"${CMAKE_CURRENT_SOURCE_DIR}/UI"
+			"${CMAKE_CURRENT_BINARY_DIR}/UI"
+			)
+
+	add_subdirectory(UI)
+endif()
+
+########### General section ##############
+# Following this should be only general compilation code, and no mention
+# of module-specific variables
+
+link_directories(${AUDIO_LIBRARY_DIRS} ${ZLIB_LIBRARY_DIRS} ${FFTW_LIBRARY_DIRS} ${MXML_LIBRARY_DIRS} ${FLTK_LIBRARY_DIRS})
+
+include_directories(
+	${CMAKE_CURRENT_SOURCE_DIR}
+	${CMAKE_CURRENT_BINARY_DIR}
+	)
+
+
+
+set(NONGUI_LIBRARIES
+	zynaddsubfx_misc
+	zynaddsubfx_synth
+	zynaddsubfx_effect
+	zynaddsubfx_params
+	zynaddsubfx_dsp
+	zynaddsubfx_nio
+	)
+
+add_subdirectory(Misc)
+add_subdirectory(Synth)
+add_subdirectory(Effects)
+add_subdirectory(Params)
+add_subdirectory(DSP)
+if(CompileTests)
+	add_subdirectory(Tests)
+endif(CompileTests)
+add_subdirectory(Nio)
+
+set(zynaddsubfx_SRCS
+	main.cpp
+	)
+
+message(STATUS "using link directories: ${AUDIO_LIBRARY_DIRS} ${ZLIB_LIBRARY_DIRS} ${FFTW_LIBRARY_DIRS} ${MXML_LIBRARY_DIRS} ${FLTK_LIBRARY_DIRS}")
+
+
+add_executable(zynaddsubfx
+	${zynaddsubfx_SRCS}
+)
+
+target_link_libraries(zynaddsubfx
+	${NONGUI_LIBRARIES}
+	${GUI_LIBRARIES}
+	${ZLIB_LIBRARIES}
+	${FFTW_LIBRARIES}
+	${MXML_LIBRARIES}
+	${NIO_LIBRARIES}
+	${AUDIO_LIBRARIES}
+	${OS_LIBRARIES}
+	pthread
+	)
+
+if (DssiEnable)
+	add_library(zynaddsubfx_dssi SHARED
+		Output/DSSIaudiooutput.cpp
+		)
+
+	target_link_libraries(zynaddsubfx_dssi
+		${NONGUI_LIBRARIES}
+		${ZLIB_LIBRARIES}
+		${FFTW_LIBRARY}
+        ${MXML_LIBRARIES}
+		${NIO_LIBRARIES}
+		${AUDIO_LIBRARIES}
+		${OS_LIBRARIES}
+		)
+	if (${CMAKE_SIZEOF_VOID_P} EQUAL "8")
+		install(TARGETS zynaddsubfx_dssi LIBRARY DESTINATION lib64/dssi/)
+	else ()
+		install(TARGETS zynaddsubfx_dssi LIBRARY DESTINATION lib/dssi/)
+	endif ()
+endif()
+
+message(STATUS "Link libraries: ${ZLIB_LIBRARY} ${FFTW_LIBRARY} ${MXML_LIBRARIES} ${AUDIO_LIBRARIES} ${OS_LIBRARIES}")
+install(TARGETS zynaddsubfx
+	RUNTIME DESTINATION bin
+	)
+
+include(CTest)
diff --git a/src/Controls/Control.cpp b/src/Controls/Control.cpp
deleted file mode 100644
index 36792fc..0000000
--- a/src/Controls/Control.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  Control.C - Control base class
-  Copyright (C) 2009-2009 Mark McCurry
-  Author: Mark McCurry
-
-  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 "Control.h"
-
-Control::Control(char ndefaultval)
-        :defaultval(ndefaultval),lockqueue(-1),locked(false)
-{}
-
-void Control::lock()
-{
-    locked=true;
-    lockqueue=-1;
-}
-
-void Control::ulock()
-{
-    if (locked&&lockqueue>=0)
-        setmVal(lockqueue);
-    locked=false;
-}
-
diff --git a/src/Controls/Control.h b/src/Controls/Control.h
deleted file mode 100644
index 2b6eaea..0000000
--- a/src/Controls/Control.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  Control.h - Control base class
-  Copyright (C) 2009-2009 Mark McCurry
-  Author: Mark McCurry
-
-  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 CONTROL_H
-#define CONTROL_H
-#include <string>
-/**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
-                         * and something attempts to update it*/
-    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
deleted file mode 100644
index 8309959..0000000
--- a/src/Controls/DelayCtl.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  DelayCtl.C - Control For Delays
-  Copyright (C) 2009-2009 Mark McCurry
-  Author: Mark McCurry
-
-  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 "DelayCtl.h"
-#include <sstream>
-
-DelayCtl::DelayCtl()
-        :Control(64),value(64/127.0*1.5) {} /**\todo finishme*/
-
-std::string DelayCtl::getString() const
-{
-    std::ostringstream buf;
-    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
-}
-
-char DelayCtl::getmVal() const
-{
-    return((char)(value/1.5*127.0));
-}
-
-float DelayCtl::getiVal() const
-{
-    return(value);
-}
diff --git a/src/Controls/DelayCtl.h b/src/Controls/DelayCtl.h
deleted file mode 100644
index c77d98d..0000000
--- a/src/Controls/DelayCtl.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  DelayCtl.h - Control For Delays
-  Copyright (C) 2009-2009 Mark McCurry
-  Author: Mark McCurry
-
-  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 "Control.h"
-
-#ifndef DELAYCTL_H
-#define DELAYCTL_H
-/**A Control for Delays
- *
- * 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;
-};
-
-#endif
-
diff --git a/src/Controls/Makefile b/src/Controls/Makefile
deleted file mode 100644
index 48bc4ae..0000000
--- a/src/Controls/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-include ../Makefile.inc
-
-objects=Control.o DelayCtl.o
-
-
-all: $(objects)
-
--include ../Make.deps
-
-.PHONY : clean
-clean: 
-	rm -f $(objects)
-	rm -f makeinclude.deps
-
diff --git a/src/DSP/AnalogFilter.cpp b/src/DSP/AnalogFilter.cpp
index 441dab0..e7f7cfe 100644
--- a/src/DSP/AnalogFilter.cpp
+++ b/src/DSP/AnalogFilter.cpp
@@ -1,9 +1,11 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  AnalogFilter.C - Several analog filters (lowpass, highpass...)
+  AnalogFilter.cpp - Several analog filters (lowpass, highpass...)
   Copyright (C) 2002-2005 Nasca Octavian Paul
+  Copyright (C) 2010-2010 Mark McCurry
   Author: Nasca Octavian Paul
+          Mark McCurry
 
   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
@@ -20,388 +22,375 @@
 
 */
 
-#include <math.h>
-#include <stdio.h>
+#include <cstring> //memcpy
+#include <cmath>
+
+#include "../Misc/Util.h"
 #include "AnalogFilter.h"
 
-AnalogFilter::AnalogFilter(unsigned char Ftype,REALTYPE Ffreq, REALTYPE Fq,unsigned char Fstages)
+AnalogFilter::AnalogFilter(unsigned char Ftype,
+                           float Ffreq,
+                           float Fq,
+                           unsigned char Fstages)
+    :type(Ftype),
+      stages(Fstages),
+      freq(Ffreq),
+      q(Fq),
+      gain(1.0),
+      abovenq(false),
+      oldabovenq(false)
 {
-    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;
+    for(int i = 0; i < 3; ++i)
+        coeff.c[i] = coeff.d[i] = oldCoeff.c[i] = oldCoeff.d[i] = 0.0f;
+    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 = false;
+    setfreq_and_q(Ffreq, Fq);
+    firsttime  = true;
+    coeff.d[0] = 0; //this is not used
+    outgain    = 1.0f;
+}
 
 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;
-};
-
-void AnalogFilter::computefiltercoefs()
+    for(int i = 0; i < MAX_FILTER_STAGES + 1; ++i) {
+        history[i].x1 = 0.0f;
+        history[i].x2 = 0.0f;
+        history[i].y1 = 0.0f;
+        history[i].y2 = 0.0f;
+        oldHistory[i] = history[i];
+    }
+    needsinterpolation = false;
+}
+
+void AnalogFilter::computefiltercoefs(void)
 {
-    REALTYPE tmp;
-    REALTYPE omega,sn,cs,alpha,beta;
-    int zerocoefs=0;//this is used if the freq is too high
+    float tmp;
+    bool  zerocoefs = false; //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;
+    float freq = this->freq;
+    if(freq > (synth->halfsamplerate_f - 500.0f)) {
+        freq      = synth->halfsamplerate_f - 500.0f;
+        zerocoefs = true;
+    }
+    if(freq < 0.1f)
+        freq = 0.1f;
     //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.0f)
+        q = 0.0f;
+    float tmpq, tmpgain;
+    if(stages == 0) {
+        tmpq    = q;
+        tmpgain = gain;
+    }
+    else {
+        tmpq    = (q > 1.0f) ? powf(q, 1.0f / (stages + 1)) : q;
+        tmpgain = powf(gain, 1.0f / (stages + 1));
+    }
+
+    //Alias Terms
+    float *c = coeff.c;
+    float *d = coeff.d;
+
+    //General Constants
+    const float omega = 2 * PI * freq / synth->samplerate_f;
+    const float sn    = sinf(omega), cs = cosf(omega);
+    float       alpha, beta;
 
     //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;
-        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;
-        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;
-        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;
-        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;
-        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;
-        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;
-        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;
-        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;
-        break;
-    default://wrong type
-        type=0;
-        computefiltercoefs();
-        break;
-    };
-};
-
-
-void AnalogFilter::setfreq(REALTYPE frequency)
+    switch(type) {
+        case 0: //LPF 1 pole
+            if(!zerocoefs)
+                tmp = expf(-2.0f * PI * freq / synth->samplerate_f);
+            else
+                tmp = 0.0f;
+            c[0]  = 1.0f - tmp;
+            c[1]  = 0.0f;
+            c[2]  = 0.0f;
+            d[1]  = tmp;
+            d[2]  = 0.0f;
+            order = 1;
+            break;
+        case 1: //HPF 1 pole
+            if(!zerocoefs)
+                tmp = expf(-2.0f * PI * freq / synth->samplerate_f);
+            else
+                tmp = 0.0f;
+            c[0]  = (1.0f + tmp) / 2.0f;
+            c[1]  = -(1.0f + tmp) / 2.0f;
+            c[2]  = 0.0f;
+            d[1]  = tmp;
+            d[2]  = 0.0f;
+            order = 1;
+            break;
+        case 2: //LPF 2 poles
+            if(!zerocoefs) {
+                alpha = sn / (2.0f * tmpq);
+                tmp   = 1 + alpha;
+                c[1]  = (1.0f - cs) / tmp;
+                c[0]  = c[2] = c[1] / 2.0f;
+                d[1]  = -2.0f * cs / tmp * -1.0f;
+                d[2]  = (1.0f - alpha) / tmp * -1.0f;
+            }
+            else {
+                c[0] = 1.0f;
+                c[1] = c[2] = d[1] = d[2] = 0.0f;
+            }
+            order = 2;
+            break;
+        case 3: //HPF 2 poles
+            if(!zerocoefs) {
+                alpha = sn / (2.0f * tmpq);
+                tmp   = 1 + alpha;
+                c[0]  = (1.0f + cs) / 2.0f / tmp;
+                c[1]  = -(1.0f + cs) / tmp;
+                c[2]  = (1.0f + cs) / 2.0f / tmp;
+                d[1]  = -2.0f * cs / tmp * -1.0f;
+                d[2]  = (1.0f - alpha) / tmp * -1.0f;
+            }
+            else
+                c[0] = c[1] = c[2] = d[1] = d[2] = 0.0f;
+            order = 2;
+            break;
+        case 4: //BPF 2 poles
+            if(!zerocoefs) {
+                alpha = sn / (2.0f * tmpq);
+                tmp   = 1.0f + alpha;
+                c[0]  = alpha / tmp *sqrtf(tmpq + 1.0f);
+                c[1]  = 0.0f;
+                c[2]  = -alpha / tmp *sqrtf(tmpq + 1.0f);
+                d[1]  = -2.0f * cs / tmp * -1.0f;
+                d[2]  = (1.0f - alpha) / tmp * -1.0f;
+            }
+            else
+                c[0] = c[1] = c[2] = d[1] = d[2] = 0.0f;
+            order = 2;
+            break;
+        case 5: //NOTCH 2 poles
+            if(!zerocoefs) {
+                alpha = sn / (2.0f * sqrtf(tmpq));
+                tmp   = 1.0f + alpha;
+                c[0]  = 1.0f / tmp;
+                c[1]  = -2.0f * cs / tmp;
+                c[2]  = 1.0f / tmp;
+                d[1]  = -2.0f * cs / tmp * -1.0f;
+                d[2]  = (1.0f - alpha) / tmp * -1.0f;
+            }
+            else {
+                c[0] = 1.0f;
+                c[1] = c[2] = d[1] = d[2] = 0.0f;
+            }
+            order = 2;
+            break;
+        case 6: //PEAK (2 poles)
+            if(!zerocoefs) {
+                tmpq *= 3.0f;
+                alpha = sn / (2.0f * tmpq);
+                tmp   = 1.0f + alpha / tmpgain;
+                c[0]  = (1.0f + alpha * tmpgain) / tmp;
+                c[1]  = (-2.0f * cs) / tmp;
+                c[2]  = (1.0f - alpha * tmpgain) / tmp;
+                d[1]  = -2.0f * cs / tmp * -1.0f;
+                d[2]  = (1.0f - alpha / tmpgain) / tmp * -1.0f;
+            }
+            else {
+                c[0] = 1.0f;
+                c[1] = c[2] = d[1] = d[2] = 0.0f;
+            }
+            order = 2;
+            break;
+        case 7: //Low Shelf - 2 poles
+            if(!zerocoefs) {
+                tmpq  = sqrtf(tmpq);
+                alpha = sn / (2.0f * tmpq);
+                beta  = sqrtf(tmpgain) / tmpq;
+                tmp   = (tmpgain + 1.0f) + (tmpgain - 1.0f) * cs + beta * sn;
+
+                c[0] = tmpgain
+                       * ((tmpgain
+                           + 1.0f) - (tmpgain - 1.0f) * cs + beta * sn) / tmp;
+                c[1] = 2.0f * tmpgain
+                       * ((tmpgain - 1.0f) - (tmpgain + 1.0f) * cs) / tmp;
+                c[2] = tmpgain
+                       * ((tmpgain
+                           + 1.0f) - (tmpgain - 1.0f) * cs - beta * sn) / tmp;
+                d[1] = -2.0f * ((tmpgain - 1.0f) + (tmpgain + 1.0f) * cs)
+                       / tmp * -1.0f;
+                d[2] = ((tmpgain + 1.0f) + (tmpgain - 1.0f) * cs - beta * sn)
+                       / tmp * -1.0f;
+            }
+            else {
+                c[0] = tmpgain;
+                c[1] = c[2] = d[1] = d[2] = 0.0f;
+            }
+            order = 2;
+            break;
+        case 8: //High Shelf - 2 poles
+            if(!zerocoefs) {
+                tmpq  = sqrtf(tmpq);
+                alpha = sn / (2.0f * tmpq);
+                beta  = sqrtf(tmpgain) / tmpq;
+                tmp   = (tmpgain + 1.0f) - (tmpgain - 1.0f) * cs + beta * sn;
+
+                c[0] = tmpgain
+                       * ((tmpgain
+                           + 1.0f) + (tmpgain - 1.0f) * cs + beta * sn) / tmp;
+                c[1] = -2.0f * tmpgain
+                       * ((tmpgain - 1.0f) + (tmpgain + 1.0f) * cs) / tmp;
+                c[2] = tmpgain
+                       * ((tmpgain
+                           + 1.0f) + (tmpgain - 1.0f) * cs - beta * sn) / tmp;
+                d[1] = 2.0f * ((tmpgain - 1.0f) - (tmpgain + 1.0f) * cs)
+                       / tmp * -1.0f;
+                d[2] = ((tmpgain + 1.0f) - (tmpgain - 1.0f) * cs - beta * sn)
+                       / tmp * -1.0f;
+            }
+            else {
+                c[0] = 1.0f;
+                c[1] = c[2] = d[1] = d[2] = 0.0f;
+            }
+            order = 2;
+            break;
+        default: //wrong type
+            type = 0;
+            computefiltercoefs();
+            break;
+    }
+}
+
+
+void AnalogFilter::setfreq(float 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.1f)
+        frequency = 0.1f;
+    float rap = freq / frequency;
+    if(rap < 1.0f)
+        rap = 1.0f / rap;
+
+    oldabovenq = abovenq;
+    abovenq    = frequency > (synth->halfsamplerate_f - 500.0f);
+
+    bool nyquistthresh = (abovenq ^ oldabovenq);
+
+
+    //if the frequency is changed fast, it needs interpolation
+    if((rap > 3.0f) || nyquistthresh) { //(now, filter and coeficients backup)
+        oldCoeff = coeff;
+        for(int i = 0; i < MAX_FILTER_STAGES + 1; ++i)
+            oldHistory[i] = history[i];
+        if(!firsttime)
+            needsinterpolation = true;
+    }
+    freq = frequency;
     computefiltercoefs();
-    firsttime=0;
+    firsttime = false;
+}
 
-};
-
-void AnalogFilter::setfreq_and_q(REALTYPE frequency,REALTYPE q_)
+void AnalogFilter::setfreq_and_q(float frequency, float q_)
 {
-    q=q_;
+    q = q_;
     setfreq(frequency);
-};
+}
 
-void AnalogFilter::setq(REALTYPE q_)
+void AnalogFilter::setq(float q_)
 {
-    q=q_;
+    q = q_;
     computefiltercoefs();
-};
+}
 
 void AnalogFilter::settype(int type_)
 {
-    type=type_;
+    type = type_;
     computefiltercoefs();
-};
+}
 
-void AnalogFilter::setgain(REALTYPE dBgain)
+void AnalogFilter::setgain(float 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(float *smp, fstage &hist,
+                                   const Coeff &coeff)
 {
-    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];
-            //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];
-            //output
-            smp[i]=y0;
-        };
-    };
-};
-void AnalogFilter::filterout(REALTYPE *smp)
+    if(order == 1)   //First order filter
+        for(int i = 0; i < synth->buffersize; ++i) {
+            float y0 = smp[i] * coeff.c[0] + hist.x1 * coeff.c[1]
+                       + hist.y1 * coeff.d[1];
+            hist.y1 = y0;
+            hist.x1 = smp[i];
+            smp[i]  = y0;
+        }
+    if(order == 2) //Second order filter
+        for(int i = 0; i < synth->buffersize; ++i) {
+            float y0 = smp[i] * coeff.c[0] + hist.x1 * coeff.c[1]
+                       + hist.x2 * coeff.c[2] + hist.y1 * coeff.d[1]
+                       + hist.y2 * coeff.d[2];
+            hist.y2 = hist.y1;
+            hist.y1 = y0;
+            hist.x2 = hist.x1;
+            hist.x1 = smp[i];
+            smp[i]  = y0;
+        }
+}
+
+void AnalogFilter::filterout(float *smp)
 {
-    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;
-        };
-        delete [] ismp;
-        needsinterpolation=0;
-    };
-
-    for (i=0;i<SOUND_BUFFER_SIZE;i++) smp[i]*=outgain;
-};
-
-REALTYPE AnalogFilter::H(REALTYPE freq)
+    for(int i = 0; i < stages + 1; ++i)
+        singlefilterout(smp, history[i], coeff);
+
+    if(needsinterpolation) {
+        //Merge Filter at old coeff with new coeff
+        float *ismp = getTmpBuffer();
+        memcpy(ismp, smp, synth->bufferbytes);
+
+        for(int i = 0; i < stages + 1; ++i)
+            singlefilterout(ismp, oldHistory[i], oldCoeff);
+
+        for(int i = 0; i < synth->buffersize; ++i) {
+            float x = (float)i / synth->buffersize_f;
+            smp[i] = ismp[i] * (1.0f - x) + smp[i] * x;
+        }
+        returnTmpBuffer(ismp);
+        needsinterpolation = false;
+    }
+
+    for(int i = 0; i < synth->buffersize; ++i)
+        smp[i] *= outgain;
+}
+
+float AnalogFilter::H(float 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));
-};
-
+    float fr = freq / synth->samplerate_f * PI * 2.0f;
+    float x  = coeff.c[0], y = 0.0f;
+    for(int n = 1; n < 3; ++n) {
+        x += cosf(n * fr) * coeff.c[n];
+        y -= sinf(n * fr) * coeff.c[n];
+    }
+    float h = x * x + y * y;
+    x = 1.0f;
+    y = 0.0f;
+    for(int n = 1; n < 3; ++n) {
+        x -= cosf(n * fr) * coeff.d[n];
+        y += sinf(n * fr) * coeff.d[n];
+    }
+    h = h / (x * x + y * y);
+    return powf(h, (stages + 1.0f) / 2.0f);
+}
diff --git a/src/DSP/AnalogFilter.h b/src/DSP/AnalogFilter.h
index e633f7a..5556c50 100644
--- a/src/DSP/AnalogFilter.h
+++ b/src/DSP/AnalogFilter.h
@@ -3,7 +3,9 @@
 
   Analog Filter.h - Several analog filters (lowpass, highpass...)
   Copyright (C) 2002-2005 Nasca Octavian Paul
+  Copyright (C) 2010-2010 Mark McCurry
   Author: Nasca Octavian Paul
+          Mark McCurry
 
   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
@@ -24,52 +26,60 @@
 #define ANALOG_FILTER_H
 
 #include "../globals.h"
-#include "Filter_.h"
+#include "Filter.h"
 
-/**Implementation of Several analog filters (lowpass, highpass...)*/
-class AnalogFilter:public Filter_
+/**Implementation of Several analog filters (lowpass, highpass...)
+ * Implemented with IIR filters
+ * Coefficients generated with "Cookbook formulae for audio EQ"*/
+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, float Ffreq, float Fq,
+                     unsigned char Fstages);
+        ~AnalogFilter();
+        void filterout(float *smp);
+        void setfreq(float frequency);
+        void setfreq_and_q(float frequency, float q_);
+        void setq(float q_);
+
+        void settype(int type_);
+        void setgain(float dBgain);
+        void setstages(int stages_);
+        void cleanup();
+
+        float H(float freq); //Obtains the response for a given frequency
+
+    private:
+        struct fstage {
+            float x1, x2; //Input History
+            float y1, y2; //Output History
+        } history[MAX_FILTER_STAGES + 1], oldHistory[MAX_FILTER_STAGES + 1];
+
+        struct Coeff {
+            float c[3], //Feed Forward
+                  d[3];    //Feed Back
+        } coeff, oldCoeff;
+        //old coeffs are used for interpolation when paremeters change quickly
+
+        //Apply IIR filter to Samples, with coefficients, and past history
+        void singlefilterout(float *smp, fstage &hist, const Coeff &coeff);
+        //Update coeff and order
+        void computefiltercoefs(void);
+
+        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.)
+        float freq;   //Frequency given in Hz
+        float q;      //Q factor (resonance or Q factor)
+        float gain;   //the gain of the filter (if are shelf/peak) filters
+
+        int order; //the order of the filter (number of poles)
+
+        bool needsinterpolation,      //Interpolation between coeff changes
+             firsttime;               //First Iteration of filter
+        bool abovenq,                 //if the frequency is above the nyquist
+             oldabovenq;              //if the last time was above nyquist
+                                      //(used to see if it needs interpolation)
 };
 
 
 #endif
-
diff --git a/src/DSP/CMakeLists.txt b/src/DSP/CMakeLists.txt
new file mode 100644
index 0000000..263a1ba
--- /dev/null
+++ b/src/DSP/CMakeLists.txt
@@ -0,0 +1,14 @@
+set(zynaddsubfx_dsp_SRCS
+	AnalogFilter.cpp
+	FFTwrapper.cpp
+	Filter.cpp
+	FormantFilter.cpp
+	SVFilter.cpp
+        Unison.cpp
+)
+
+add_library(zynaddsubfx_dsp STATIC
+	${zynaddsubfx_dsp_SRCS} 
+	)
+
+target_link_libraries(zynaddsubfx_dsp)
diff --git a/src/DSP/FFTwrapper.cpp b/src/DSP/FFTwrapper.cpp
index 11ee9a3..65fcebb 100644
--- a/src/DSP/FFTwrapper.cpp
+++ b/src/DSP/FFTwrapper.cpp
@@ -20,81 +20,66 @@
 
 */
 
-#include <math.h>
+#include <cmath>
+#include <cassert>
+#include <cstring>
 #include "FFTwrapper.h"
 
 FFTwrapper::FFTwrapper(int 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);
-#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);
-#endif
-};
+    fftsize  = fftsize_;
+    time     = new fftw_real[fftsize];
+    fft      = new fftw_complex[fftsize + 1];
+    planfftw = fftw_plan_dft_r2c_1d(fftsize,
+                                    time,
+                                    fft,
+                                    FFTW_ESTIMATE);
+    planfftw_inv = fftw_plan_dft_c2r_1d(fftsize,
+                                        fft,
+                                        time,
+                                        FFTW_ESTIMATE);
+}
 
 FFTwrapper::~FFTwrapper()
 {
-#ifdef FFTW_VERSION_2
-    rfftw_destroy_plan(planfftw);
-    rfftw_destroy_plan(planfftw_inv);
-#else
     fftw_destroy_plan(planfftw);
     fftw_destroy_plan(planfftw_inv);
-#endif
 
-    delete [] tmpfftdata1;
-    delete [] tmpfftdata2;
-};
+    delete [] time;
+    delete [] fft;
+}
 
-/*
- * do the Fast Fourier Transform
- */
-void FFTwrapper::smps2freqs(REALTYPE *smps,FFTFREQS freqs)
+void FFTwrapper::smps2freqs(const float *smps, fft_t *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];
-    };
-#else
-    for (int i=0;i<fftsize;i++) tmpfftdata1[i]=smps[i];
+    //Load data
+    for(int i = 0; i < fftsize; ++i)
+        time[i] = static_cast<double>(smps[i]);
+
+    //DFT
     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];
-    };
-#endif
-    tmpfftdata2[fftsize/2]=0.0;
-};
 
-/*
- * do the Inverse Fast Fourier Transform
- */
-void FFTwrapper::freqs2smps(FFTFREQS freqs,REALTYPE *smps)
+    //Grab data
+    memcpy((void *)freqs, (const void *)fft, fftsize * sizeof(double));
+}
+
+void FFTwrapper::freqs2smps(const fft_t *freqs, float *smps)
 {
-    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];
-#else
-    for (int i=0;i<fftsize/2;i++) {
-        tmpfftdata2[i]=freqs.c[i];
-        if (i!=0) tmpfftdata2[fftsize-i]=freqs.s[i];
-    };
+    //Load data
+    memcpy((void *)fft, (const void *)freqs, fftsize * sizeof(double));
+
+    //clear unused freq channel
+    fft[fftsize / 2][0] = 0.0f;
+    fft[fftsize / 2][1] = 0.0f;
+
+    //IDFT
     fftw_execute(planfftw_inv);
-    for (int i=0;i<fftsize;i++) smps[i]=tmpfftdata2[i];
-#endif
 
-};
+    //Grab data
+    for(int i = 0; i < fftsize; ++i)
+        smps[i] = static_cast<float>(time[i]);
+}
 
+void FFT_cleanup()
+{
+    fftw_cleanup();
+}
diff --git a/src/DSP/FFTwrapper.h b/src/DSP/FFTwrapper.h
index 8177c27..77941b3 100644
--- a/src/DSP/FFTwrapper.h
+++ b/src/DSP/FFTwrapper.h
@@ -22,46 +22,31 @@
 
 #ifndef FFT_WRAPPER_H
 #define FFT_WRAPPER_H
-
-#include "../globals.h"
-
-#ifdef FFTW_VERSION_2
-
-#include <fftw.h>
-
-/* If you got error messages about rfftw.h, replace the next include  line with "#include <srfftw.h>"
-or with "#include <drfftw.h> (if one doesn't work try the other). It may be necessary to replace
-the <fftw.h> with <dfftw.h> or <sfftw.h>. If the neither one doesn't work,
-please install latest version of fftw(recomanded from the sources) from www.fftw.org.
-If you'll install fftw3 you need to change the Makefile.inc
-Hope all goes right." */
-#include <rfftw.h>
-
-#else
-
 #include <fftw3.h>
-#define fftw_real double
-#define rfftw_plan fftw_plan
-#endif
+#include <complex>
+typedef double                  fftw_real;
+typedef std::complex<fftw_real> fft_t;
 
 /**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(const float *smps, fft_t *freqs);
+        void freqs2smps(const fft_t *freqs, float *smps);
+    private:
+        int fftsize;
+        fftw_real    *time;
+        fftw_complex *fft;
+        fftw_plan     planfftw, planfftw_inv;
 };
-#endif
 
+void FFT_cleanup();
+#endif
diff --git a/src/DSP/Filter.cpp b/src/DSP/Filter.cpp
index f94a342..7c7e92c 100644
--- a/src/DSP/Filter.cpp
+++ b/src/DSP/Filter.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  Filter.C - Filters, uses analog,formant,etc. filters
+  Filter.cpp - Filters, uses analog,formant,etc. filters
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -24,59 +24,39 @@
 #include <stdio.h>
 
 #include "Filter.h"
+#include "AnalogFilter.h"
+#include "FormantFilter.h"
+#include "SVFilter.h"
+#include "../Params/FilterParams.h"
 
-Filter::Filter(FilterParams *pars)
+Filter *Filter::generate(FilterParams *pars)
 {
-    unsigned char Ftype=pars->Ptype;
-    unsigned char Fstages=pars->Pstages;
-
-    category=pars->Pcategory;
-
-    switch (category) {
-    case 1:
-        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);
-        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());
-        break;
-    };
-};
-
-Filter::~Filter()
-{
-    delete (filter);
-};
-
-void Filter::filterout(REALTYPE *smp)
-{
-    filter->filterout(smp);
-};
-
-void Filter::setfreq(REALTYPE frequency)
+    unsigned char Ftype   = pars->Ptype;
+    unsigned char Fstages = pars->Pstages;
+
+    Filter *filter;
+    switch(pars->Pcategory) {
+        case 1:
+            filter = new FormantFilter(pars);
+            break;
+        case 2:
+            filter = new SVFilter(Ftype, 1000.0f, pars->getq(), Fstages);
+            filter->outgain = dB2rap(pars->getgain());
+            if(filter->outgain > 1.0f)
+                filter->outgain = sqrt(filter->outgain);
+            break;
+        default:
+            filter = new AnalogFilter(Ftype, 1000.0f, pars->getq(), Fstages);
+            if((Ftype >= 6) && (Ftype <= 8))
+                filter->setgain(pars->getgain());
+            else
+                filter->outgain = dB2rap(pars->getgain());
+            break;
+    }
+    return filter;
+}
+
+float Filter::getrealfreq(float freqpitch)
 {
-    filter->setfreq(frequency);
-};
-
-void Filter::setfreq_and_q(REALTYPE frequency,REALTYPE 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);
-};
-
+    return powf(2.0f, freqpitch + 9.96578428f); //log2(1000)=9.95748f
+}
diff --git a/src/DSP/Filter.h b/src/DSP/Filter.h
index 42bef55..41761e5 100644
--- a/src/DSP/Filter.h
+++ b/src/DSP/Filter.h
@@ -25,28 +25,21 @@
 
 #include "../globals.h"
 
-#include "Filter_.h"
-#include "AnalogFilter.h"
-#include "FormantFilter.h"
-#include "SVFilter.h"
-#include "../Params/FilterParams.h"
-
 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:
+        static float getrealfreq(float freqpitch);
+        static Filter *generate(class FilterParams * pars);
+
+        virtual ~Filter() {}
+        virtual void filterout(float *smp)    = 0;
+        virtual void setfreq(float frequency) = 0;
+        virtual void setfreq_and_q(float frequency, float q_) = 0;
+        virtual void setq(float q_) = 0;
+        virtual void setgain(float dBgain) = 0;
+
+    protected:
+        float outgain;
 };
 
-
 #endif
-
diff --git a/src/DSP/Filter_.h b/src/DSP/Filter_.h
deleted file mode 100644
index b3f2bad..0000000
--- a/src/DSP/Filter_.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  Filter_.h - This class is inherited by filter classes
-  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 FILTER__H
-#define FILTER__H
-
-#include "../globals.h"
-
-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:
-};
-
-
-#endif
-
diff --git a/src/DSP/FormantFilter.cpp b/src/DSP/FormantFilter.cpp
index 2972856..5df27df 100644
--- a/src/DSP/FormantFilter.cpp
+++ b/src/DSP/FormantFilter.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  FormantFilter.C - formant filters
+  FormantFilter.cpp - formant filters
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -20,157 +20,212 @@
 
 */
 
-#include <math.h>
-#include <stdio.h>
+#include <cmath>
+#include <cstdio>
+#include "../Misc/Util.h"
 #include "FormantFilter.h"
+#include "AnalogFilter.h"
+#include "../Params/FilterParams.h"
 
 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.0f, 10.0f, 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;
-};
+    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.0f;
+    for(int i = 0; i < numformants; ++i) {
+        currentformants[i].freq = 1000.0f;
+        currentformants[i].amp  = 1.0f;
+        currentformants[i].q    = 2.0f;
+    }
+
+    formantslowness = powf(1.0f - (pars->Pformantslowness / 128.0f), 3.0f);
+
+    sequencesize = pars->Psequencesize;
+    if(sequencesize == 0)
+        sequencesize = 1;
+    for(int k = 0; k < sequencesize; ++k)
+        sequence[k].nvowel = pars->Psequence[k].nvowel;
+
+    vowelclearness = powf(10.0f, (pars->Pvowelclearness - 32.0f) / 48.0f);
+
+    sequencestretch = powf(0.1f, (pars->Psequencestretch - 32.0f) / 48.0f);
+    if(pars->Psequencereversed)
+        sequencestretch *= -1.0f;
+
+    outgain = dB2rap(pars->getgain());
+
+    oldinput   = -1.0f;
+    Qfactor    = 1.0f;
+    oldQfactor = Qfactor;
+    firsttime  = 1;
+}
 
 FormantFilter::~FormantFilter()
 {
-    for (int i=0;i<numformants;i++) delete(formant[i]);
-    delete[] inbuffer;
-    delete[] tmpbuf;
-};
-
-
-
+    for(int i = 0; i < numformants; ++i)
+        delete (formant[i]);
+}
 
 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)
+void FormantFilter::setpos(float input)
 {
-    int p1,p2;
-
-    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)) {
-//	oldinput=input; daca setez asta, o sa faca probleme la schimbari foarte lente
-        firsttime=0;
+    int p1, p2;
+
+    if(firsttime != 0)
+        slowinput = input;
+    else
+        slowinput = slowinput
+                    * (1.0f - formantslowness) + input * formantslowness;
+
+    if((fabsf(oldinput - input) < 0.001f) && (fabsf(slowinput - input) < 0.001f)
+       && (fabsf(Qfactor - oldQfactor) < 0.001f)) {
+        //	oldinput=input; daca setez asta, o sa faca probleme la schimbari foarte lente
+        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;
+    }
+    else
+        oldinput = input;
+
+    float pos = fmodf(input * sequencestretch, 1.0f);
+    if(pos < 0.0f)
+        pos += 1.0f;
+
+    F2I(pos * sequencesize, p2);
+    p1 = p2 - 1;
+    if(p1 < 0)
+        p1 += sequencesize;
+
+    pos = fmodf(pos * sequencesize, 1.0f);
+    if(pos < 0.0f)
+        pos = 0.0f;
+    else
+    if(pos > 1.0f)
+        pos = 1.0f;
+    pos =
+        (atanf((pos * 2.0f
+                - 1.0f)
+               * vowelclearness) / atanf(vowelclearness) + 1.0f) * 0.5f;
+
+    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.0f - pos) + formantpar[p2][i].freq * pos;
+            currentformants[i].amp =
+                formantpar[p1][i].amp
+                * (1.0f - pos) + formantpar[p2][i].amp * pos;
+            currentformants[i].q =
+                formantpar[p1][i].q * (1.0f - 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.0f - formantslowness)
+                + (formantpar[p1][i].freq
+                   * (1.0f - pos) + formantpar[p2][i].freq * pos)
+                * formantslowness;
+
+            currentformants[i].amp =
+                currentformants[i].amp * (1.0f - formantslowness)
+                + (formantpar[p1][i].amp * (1.0f - pos)
+                   + formantpar[p2][i].amp * pos) * formantslowness;
+
+            currentformants[i].q = currentformants[i].q
+                                   * (1.0f - formantslowness)
+                                   + (formantpar[p1][i].q * (1.0f - pos)
+                                      + formantpar[p2][i].q
+                                      * pos) * formantslowness;
+
+
+            formant[i]->setfreq_and_q(currentformants[i].freq,
+                                      currentformants[i].q * Qfactor);
+        }
+
+    oldQfactor = Qfactor;
+}
+
+void FormantFilter::setfreq(float frequency)
+{
+    setpos(frequency);
+}
 
-            formant[i]->setfreq_and_q(currentformants[i].freq,currentformants[i].q*Qfactor);
-        };
-    };
+void FormantFilter::setq(float q_)
+{
+    Qfactor = q_;
+    for(int i = 0; i < numformants; ++i)
+        formant[i]->setq(Qfactor * currentformants[i].q);
+}
 
-    oldQfactor=Qfactor;
-};
+void FormantFilter::setgain(float /*dBgain*/)
+{}
 
-void FormantFilter::setfreq(REALTYPE frequency)
+inline float log_2(float x)
 {
-    setpos(frequency);
-};
+    return logf(x) / logf(2.0f);
+}
 
-void FormantFilter::setq(REALTYPE q_)
+void FormantFilter::setfreq_and_q(float frequency, float q_)
 {
-    Qfactor=q_;
-    for (int i=0;i<numformants;i++) formant[i]->setq(Qfactor*currentformants[i].q);
-};
+    //Convert form real freq[Hz]
+    const float freq = log_2(frequency) - 9.96578428f; //log2(1000)=9.95748f.
 
-void FormantFilter::setfreq_and_q(REALTYPE frequency,REALTYPE q_)
-{
-    Qfactor=q_;
-    setpos(frequency);
-};
+    Qfactor = q_;
+    setpos(freq);
+}
 
 
-void FormantFilter::filterout(REALTYPE *smp)
+void FormantFilter::filterout(float *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;
-        formant[j]->filterout(tmpbuf);
+    float *inbuffer = getTmpBuffer();
+
+    memcpy(inbuffer, smp, synth->bufferbytes);
+    memset(smp, 0, synth->bufferbytes);
 
-        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;
-    };
-};
+    for(int j = 0; j < numformants; ++j) {
+        float *tmpbuf = getTmpBuffer();
+        for(int i = 0; i < synth->buffersize; ++i)
+            tmpbuf[i] = inbuffer[i] * outgain;
+        formant[j]->filterout(tmpbuf);
 
+        if(ABOVE_AMPLITUDE_THRESHOLD(oldformantamp[j], currentformants[j].amp))
+            for(int i = 0; i < synth->buffersize; ++i)
+                smp[i] += tmpbuf[i]
+                          * INTERPOLATE_AMPLITUDE(oldformantamp[j],
+                                                  currentformants[j].amp,
+                                                  i,
+                                                  synth->buffersize);
+        else
+            for(int i = 0; i < synth->buffersize; ++i)
+                smp[i] += tmpbuf[i] * currentformants[j].amp;
+        returnTmpBuffer(tmpbuf);
+        oldformantamp[j] = currentformants[j].amp;
+    }
+    returnTmpBuffer(inbuffer);
+}
diff --git a/src/DSP/FormantFilter.h b/src/DSP/FormantFilter.h
index 33e641f..03b52cc 100644
--- a/src/DSP/FormantFilter.h
+++ b/src/DSP/FormantFilter.h
@@ -24,45 +24,43 @@
 #define FORMANT_FILTER_H
 
 #include "../globals.h"
-#include "Filter_.h"
-#include "AnalogFilter.h"
-#include "../Params/FilterParams.h"
+#include "Filter.h"
 
 
-class FormantFilter:public Filter_
+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_);
+    public:
+        FormantFilter(class FilterParams *pars);
+        ~FormantFilter();
+        void filterout(float *smp);
+        void setfreq(float frequency);
+        void setfreq_and_q(float frequency, float q_);
+        void setq(float q_);
+        void setgain(float dBgain);
 
-    void cleanup();
-private:
-    AnalogFilter *formant[FF_MAX_FORMANTS];
-    REALTYPE *inbuffer,*tmpbuf;
+        void cleanup(void);
 
-    struct {
-        REALTYPE freq,amp,q;//frequency,amplitude,Q
-    } formantpar[FF_MAX_VOWELS][FF_MAX_FORMANTS],currentformants[FF_MAX_FORMANTS];
+    private:
+        void setpos(float input);
 
-    struct {
-        unsigned char nvowel;
-    } sequence [FF_MAX_SEQUENCE];
 
-    REALTYPE oldformantamp[FF_MAX_FORMANTS];
+        class AnalogFilter * formant[FF_MAX_FORMANTS];
 
-    int sequencesize,numformants,firsttime;
-    REALTYPE oldinput,slowinput;
-    REALTYPE Qfactor,formantslowness,oldQfactor;
-    REALTYPE vowelclearness,sequencestretch;
+        struct {
+            float freq, amp, q; //frequency,amplitude,Q
+        } formantpar[FF_MAX_VOWELS][FF_MAX_FORMANTS],
+          currentformants[FF_MAX_FORMANTS];
 
-    void setpos(REALTYPE input);
+        struct {
+            unsigned char nvowel;
+        } sequence [FF_MAX_SEQUENCE];
 
-};
+        float oldformantamp[FF_MAX_FORMANTS];
 
+        int   sequencesize, numformants, firsttime;
+        float oldinput, slowinput;
+        float Qfactor, formantslowness, oldQfactor;
+        float vowelclearness, sequencestretch;
+};
 
 #endif
-
diff --git a/src/DSP/Makefile b/src/DSP/Makefile
deleted file mode 100644
index e5f817b..0000000
--- a/src/DSP/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-include ../Makefile.inc
-
-objects=FFTwrapper.o AnalogFilter.o FormantFilter.o SVFilter.o Filter.o
-
-
-all: $(objects)
-
--include ../Make.deps
-
-.PHONY : clean
-clean: 
-	rm -f $(objects)
-	rm -f makeinclude.deps
-
diff --git a/src/DSP/SVFilter.cpp b/src/DSP/SVFilter.cpp
index 28860ef..0431227 100644
--- a/src/DSP/SVFilter.cpp
+++ b/src/DSP/SVFilter.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  SVFilter.C - Several state-variable filters
+  SVFilter.cpp - Several state-variable filters
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -20,157 +20,159 @@
 
 */
 
-#include <math.h>
-#include <stdio.h>
+#include <cmath>
+#include <cstdio>
+#include <cstring>
+#include <cassert>
+#include <err.h>
+#include "../Misc/Util.h"
 #include "SVFilter.h"
 
-SVFilter::SVFilter(unsigned char Ftype,REALTYPE Ffreq, REALTYPE Fq,unsigned char Fstages)
+SVFilter::SVFilter(unsigned char Ftype, float Ffreq, float Fq,
+                   unsigned char Fstages)
+    :type(Ftype),
+      stages(Fstages),
+      freq(Ffreq),
+      q(Fq),
+      gain(1.0f),
+      needsinterpolation(false),
+      firsttime(true)
 {
-    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;
+    if(stages >= MAX_FILTER_STAGES)
+        stages = MAX_FILTER_STAGES;
+    outgain = 1.0f;
     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;
-};
-
-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);
-};
+    for(int i = 0; i < MAX_FILTER_STAGES + 1; ++i)
+        st[i].low = st[i].high = st[i].band = st[i].notch = 0.0f;
+    oldabovenq = false;
+    abovenq    = false;
+}
 
-
-void SVFilter::setfreq(REALTYPE frequency)
+void SVFilter::computefiltercoefs(void)
 {
-    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);
+    par.f = freq / synth->samplerate_f * 4.0f;
+    if(par.f > 0.99999f)
+        par.f = 0.99999f;
+    par.q      = 1.0f - atanf(sqrtf(q)) * 2.0f / PI;
+    par.q      = powf(par.q, 1.0f / (stages + 1));
+    par.q_sqrt = sqrtf(par.q);
+}
 
-    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;
+void SVFilter::setfreq(float frequency)
+{
+    if(frequency < 0.1f)
+        frequency = 0.1f;
+    float rap = freq / frequency;
+    if(rap < 1.0f)
+        rap = 1.0f / rap;
+
+    oldabovenq = abovenq;
+    abovenq    = frequency > (synth->samplerate_f / 2 - 500.0f);
+
+    bool nyquistthresh = (abovenq ^ oldabovenq);
+
+    //if the frequency is changed fast, it needs interpolation
+    if((rap > 3.0f) || nyquistthresh) { //(now, filter and coeficients backup)
+        if(!firsttime)
+            needsinterpolation = true;
+        ipar = par;
+    }
+    freq = frequency;
     computefiltercoefs();
-    firsttime=0;
-
-};
+    firsttime = false;
+}
 
-void SVFilter::setfreq_and_q(REALTYPE frequency,REALTYPE q_)
+void SVFilter::setfreq_and_q(float frequency, float q_)
 {
-    q=q_;
+    q = q_;
     setfreq(frequency);
-};
+}
 
-void SVFilter::setq(REALTYPE q_)
+void SVFilter::setq(float q_)
 {
-    q=q_;
+    q = q_;
     computefiltercoefs();
-};
+}
 
 void SVFilter::settype(int type_)
 {
-    type=type_;
+    type = type_;
     computefiltercoefs();
-};
+}
 
-void SVFilter::setgain(REALTYPE dBgain)
+void SVFilter::setgain(float 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(float *smp, fstage &x, parameters &par)
 {
-    int i;
-    REALTYPE *out=NULL;
-    switch (type) {
-    case 0:
-        out=&x.low;
-        break;
-    case 1:
-        out=&x.high;
-        break;
-    case 2:
-        out=&x.band;
-        break;
-    case 3:
-        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;
+    float *out = NULL;
+    switch(type) {
+        case 0:
+            out = &x.low;
+            break;
+        case 1:
+            out = &x.high;
+            break;
+        case 2:
+            out = &x.band;
+            break;
+        case 3:
+            out = &x.notch;
+            break;
+        default:
+            errx(1, "Impossible SVFilter type encountered [%d]", type);
+    }
+
+    for(int i = 0; i < synth->buffersize; ++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)
+void SVFilter::filterout(float *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;
-        };
-        delete [] ismp;
-        needsinterpolation=0;
-    };
-
-    for (i=0;i<SOUND_BUFFER_SIZE;i++) smp[i]*=outgain;
-
-};
-
+    for(int i = 0; i < stages + 1; ++i)
+        singlefilterout(smp, st[i], par);
+
+    if(needsinterpolation) {
+        float *ismp = getTmpBuffer();
+        memcpy(ismp, smp, synth->bufferbytes);
+
+        for(int i = 0; i < stages + 1; ++i)
+            singlefilterout(ismp, st[i], ipar);
+
+        for(int i = 0; i < synth->buffersize; ++i) {
+            float x = i / synth->buffersize_f;
+            smp[i] = ismp[i] * (1.0f - x) + smp[i] * x;
+        }
+        returnTmpBuffer(ismp);
+        needsinterpolation = false;
+    }
+
+    for(int i = 0; i < synth->buffersize; ++i)
+        smp[i] *= outgain;
+}
diff --git a/src/DSP/SVFilter.h b/src/DSP/SVFilter.h
index b2c88e0..2a17f0c 100644
--- a/src/DSP/SVFilter.h
+++ b/src/DSP/SVFilter.h
@@ -24,45 +24,46 @@
 #define SV_FILTER_H
 
 #include "../globals.h"
-#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;
-
+#include "Filter.h"
 
-    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;
+class SVFilter:public Filter
+{
+    public:
+        SVFilter(unsigned char Ftype,
+                 float Ffreq,
+                 float Fq,
+                 unsigned char Fstages);
+        ~SVFilter();
+        void filterout(float *smp);
+        void setfreq(float frequency);
+        void setfreq_and_q(float frequency, float q_);
+        void setq(float q_);
+
+        void settype(int type_);
+        void setgain(float dBgain);
+        void setstages(int stages_);
+        void cleanup();
+
+    private:
+        struct fstage {
+            float low, high, band, notch;
+        } st[MAX_FILTER_STAGES + 1];
+
+        struct parameters {
+            float f, q, q_sqrt;
+        } par, ipar;
+
+        void singlefilterout(float *smp, fstage &x, parameters &par);
+        void computefiltercoefs(void);
+        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.)
+        float freq; // Frequency given in Hz
+        float q;    // Q factor (resonance or Q factor)
+        float gain; // the gain of the filter (if are shelf/peak) filters
+
+        bool abovenq,   //if the frequency is above the nyquist
+             oldabovenq;
+        bool needsinterpolation, firsttime;
 };
 
-
 #endif
-
diff --git a/src/DSP/Unison.cpp b/src/DSP/Unison.cpp
new file mode 100644
index 0000000..f2bef69
--- /dev/null
+++ b/src/DSP/Unison.cpp
@@ -0,0 +1,197 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  Unison.cpp - Unison effect (multivoice chorus)
+  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
+*/
+
+#include <cmath>
+#include <cstring>
+#include <err.h>
+
+#include "Unison.h"
+
+Unison::Unison(int update_period_samples_, float max_delay_sec_)
+    :unison_size(0),
+      base_freq(1.0f),
+      uv(NULL),
+      update_period_samples(update_period_samples_),
+      update_period_sample_k(0),
+      max_delay((int)(synth->samplerate_f * max_delay_sec_) + 1),
+      delay_k(0),
+      first_time(false),
+      delay_buffer(NULL),
+      unison_amplitude_samples(0.0f),
+      unison_bandwidth_cents(10.0f)
+{
+    if(max_delay < 10)
+        max_delay = 10;
+    delay_buffer = new float[max_delay];
+    memset(delay_buffer, 0, max_delay * sizeof(float));
+    setSize(1);
+}
+
+Unison::~Unison() {
+    delete [] delay_buffer;
+    delete [] uv;
+}
+
+void Unison::setSize(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;
+    updateParameters();
+}
+
+void Unison::setBaseFrequency(float freq)
+{
+    base_freq = freq;
+    updateParameters();
+}
+
+void Unison::setBandwidth(float bandwidth)
+{
+    if(bandwidth < 0)
+        bandwidth = 0.0f;
+    if(bandwidth > 1200.0f)
+        bandwidth = 1200.0f;
+
+    /* If the bandwidth is too small, the audio may cancel itself out
+     * (due to the sign change of the outputs)
+     * TODO figure out the acceptable lower bound and codify it
+     */
+    unison_bandwidth_cents = bandwidth;
+    updateParameters();
+}
+
+void Unison::updateParameters(void)
+{
+    if(!uv)
+        return;
+    float increments_per_second = synth->samplerate_f
+                                  / (float) update_period_samples;
+//	printf("#%g, %g\n",increments_per_second,base_freq);
+    for(int i = 0; i < unison_size; ++i) {
+        float base = powf(UNISON_FREQ_SPAN, synth->numRandom() * 2.0f - 1.0f);
+        uv[i].relative_amplitude = base;
+        float period = base / base_freq;
+        float m      = 4.0f / (period * increments_per_second);
+        if(synth->numRandom() < 0.5f)
+            m = -m;
+        uv[i].step = m;
+//		printf("%g %g\n",uv[i].relative_amplitude,period);
+    }
+
+    float max_speed = powf(2.0f, unison_bandwidth_cents / 1200.0f);
+    unison_amplitude_samples = 0.125f * (max_speed - 1.0f)
+                               * synth->samplerate_f / base_freq;
+
+    //If functions exceed this limit, they should have requested a bigguer delay
+    //and thus are buggy
+    if(unison_amplitude_samples >= max_delay - 1) {
+        warnx("BUG: Unison amplitude samples too big");
+        warnx("Unision max_delay should be larger");
+        unison_amplitude_samples = max_delay - 2;
+    }
+
+    updateUnisonData();
+}
+
+void Unison::process(int bufsize, float *inbuf, float *outbuf)
+{
+    if(!uv)
+        return;
+    if(!outbuf)
+        outbuf = inbuf;
+
+    float volume    = 1.0f / sqrtf(unison_size);
+    float xpos_step = 1.0f / (float) update_period_samples;
+    float xpos      = (float) update_period_sample_k * xpos_step;
+    for(int i = 0; i < bufsize; ++i) {
+        if(update_period_sample_k++ >= update_period_samples) {
+            updateUnisonData();
+            update_period_sample_k = 0;
+            xpos = 0.0f;
+        }
+        xpos += xpos_step;
+        float in   = inbuf[i], out = 0.0f;
+        float sign = 1.0f;
+        for(int k = 0; k < unison_size; ++k) {
+            float vpos = uv[k].realpos1 * (1.0f - xpos) + uv[k].realpos2 * xpos;        //optimize
+            float pos  = (float)(delay_k + max_delay) - vpos - 1.0f;
+            int   posi;
+            F2I(pos, posi); //optimize!
+            if(posi >= max_delay)
+                posi -= max_delay;
+            float posf = pos - floorf(pos);
+            out +=
+                ((1.0f
+                  - 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;
+        delay_k = (++delay_k < max_delay) ? delay_k : 0;
+    }
+}
+
+void Unison::updateUnisonData()
+{
+    if(!uv)
+        return;
+
+    for(int k = 0; k < unison_size; ++k) {
+        float pos  = uv[k].position;
+        float step = uv[k].step;
+        pos += step;
+        if(pos <= -1.0f) {
+            pos  = -1.0f;
+            step = -step;
+        }
+        else
+        if(pos >= 1.0f) {
+            pos  = 1.0f;
+            step = -step;
+        }
+        float vibratto_val = (pos - 0.333333333f * pos * pos * pos) * 1.5f; //make the vibratto lfo smoother
+
+        //Relative amplitude is utilized, so the delay may be larger than the
+        //whole buffer, if the buffer is too small, this indicates a buggy call
+        //to Unison()
+        float newval = 1.0f + 0.5f
+                       * (vibratto_val + 1.0f) * 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;
+    }
+    first_time = false;
+}
diff --git a/src/DSP/Unison.h b/src/DSP/Unison.h
new file mode 100644
index 0000000..9df9462
--- /dev/null
+++ b/src/DSP/Unison.h
@@ -0,0 +1,73 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  Unison.h - Unison effect (multivoice chorus)
+  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 UNISON_H
+#define UNISON_H
+
+#include "../Misc/Util.h"
+
+//how much the unison frequencies varies (always >= 1.0)
+#define UNISON_FREQ_SPAN 2.0f
+
+class Unison
+{
+    public:
+        Unison(int update_period_samples_, float max_delay_sec_);
+        ~Unison();
+
+        void setSize(int new_size);
+        void setBaseFrequency(float freq);
+        void setBandwidth(float bandwidth_cents);
+
+        void process(int bufsize, float *inbuf, float *outbuf = NULL);
+
+    private:
+        void updateParameters(void);
+        void updateUnisonData(void);
+
+        int   unison_size;
+        float base_freq;
+        struct UnisonVoice {
+            float step;     //base LFO
+            float position;
+            float realpos1; //the position regarding samples
+            float realpos2;
+            float relative_amplitude;
+            float lin_fpos;
+            float lin_ffreq;
+            UnisonVoice() {
+                position = RND * 1.8f - 0.9f;
+                realpos1 = 0.0f;
+                realpos2 = 0.0f;
+                step     = 0.0f;
+                relative_amplitude = 1.0f;
+            }
+        } *uv;
+
+        int    update_period_samples;
+        int    update_period_sample_k;
+        int    max_delay, delay_k;
+        bool   first_time;
+        float *delay_buffer;
+        float  unison_amplitude_samples;
+        float  unison_bandwidth_cents;
+};
+#endif
diff --git a/src/Effects/Alienwah.cpp b/src/Effects/Alienwah.cpp
index a4bf58e..078a964 100644
--- a/src/Effects/Alienwah.cpp
+++ b/src/Effects/Alienwah.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  Alienwah.C - "AlienWah" effect
+  Alienwah.cpp - "AlienWah" effect
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -23,245 +23,213 @@
 #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(bool insertion_, float *efxoutl_, float *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<float>(fb, 0.0f);
+    oldclfor = complex<float>(fb, 0.0f);
+}
 
 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)
+//Apply the effect
+void Alienwah::out(const Stereo<float *> &smp)
 {
-    REALTYPE lfol,lfor; //Left/Right LFOs
-    complex<REALTYPE> clfol,clfor,out,tmp;
+    float lfol, lfor; //Left/Right LFOs
+    complex<float> clfol, clfor;
     /**\todo Rework, as optimization can be used when the new complex type is
      * utilized.
-     * Before all calculations needed to be done with individual REALTYPE,
+     * Before all calculations needed to be done with individual float,
      * 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.0f;
+    lfor *= depth * PI * 2.0f;
+    clfol = complex<float>(cosf(lfol + phase) * fb, sinf(lfol + phase) * fb); //rework
+    clfor = complex<float>(cosf(lfor + phase) * fb, sinf(lfor + phase) * fb); //rework
+
+    for(int i = 0; i < synth->buffersize; ++i) {
+        float x  = ((float) i) / synth->buffersize_f;
+        float x1 = 1.0f - x;
         //left
-        tmp=clfol*x+oldclfol*x1;
+        complex<float> tmp = clfol * x + oldclfol * x1;
 
-        out=tmp*oldl[oldk];
-        out.real()+=(1-fabs(fb))*smpsr[i]*(1.0-panning);
+        complex<float> out = tmp * oldl[oldk];
+        out.real() += (1 - fabs(fb)) * smp.l[i] * pangainL;
 
-        oldl[oldk]=out;
-        REALTYPE l=out.real()*10.0*(fb+0.1);
+        oldl[oldk] = out;
+        float l = out.real() * 10.0f * (fb + 0.1f);
 
         //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)) * smp.r[i] * pangainR;
 
-        oldr[oldk]=out;
-        REALTYPE r=out.real()*10.0*(fb+0.1);
+        oldr[oldk] = out;
+        float r = out.real() * 10.0f * (fb + 0.1f);
 
 
-        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;
-    };
+        efxoutl[i] = l * (1.0f - lrcross) + r * lrcross;
+        efxoutr[i] = r * (1.0f - lrcross) + l * lrcross;
+    }
 
-    oldclfol=clfol;
-    oldclfor=clfor;
+    oldclfol = clfol;
+    oldclfor = clfor;
+}
 
-};
-
-/*
- * Cleanup the effect
- */
-void Alienwah::cleanup()
+//Cleanup the effect
+void Alienwah::cleanup(void)
 {
-    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<float>(0.0f, 0.0f);
+        oldr[i] = complex<float>(0.0f, 0.0f);
+    }
+    oldk = 0;
+}
 
-/*
- * Parameter control
- */
 
-void Alienwah::setdepth(const unsigned char &Pdepth)
+//Parameter control
+void Alienwah::setdepth(unsigned char _Pdepth)
 {
-    this->Pdepth=Pdepth;
-    depth=(Pdepth/127.0);
-};
+    Pdepth = _Pdepth;
+    depth  = Pdepth / 127.0f;
+}
 
-void Alienwah::setfb(const unsigned char &Pfb)
+void Alienwah::setfb(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;
-};
-
-void Alienwah::setvolume(const unsigned char &Pvolume)
+    Pfb = _Pfb;
+    fb  = fabs((Pfb - 64.0f) / 64.1f);
+    fb  = sqrtf(fb);
+    if(fb < 0.4f)
+        fb = 0.4f;
+    if(Pfb < 64)
+        fb = -fb;
+}
+
+void Alienwah::setvolume(unsigned char _Pvolume)
 {
-    this->Pvolume=Pvolume;
-    outvolume=Pvolume/127.0;
-    if (insertion==0) volume=1.0;
-    else volume=outvolume;
-};
-
-void Alienwah::setpanning(const unsigned char &Ppanning)
+    Pvolume   = _Pvolume;
+    outvolume = Pvolume / 127.0f;
+    if(insertion == 0)
+        volume = 1.0f;
+    else
+        volume = outvolume;
+}
+
+void Alienwah::setphase(unsigned char _Pphase)
 {
-    this->Ppanning=Ppanning;
-    panning=Ppanning/127.0;
-};
+    Pphase = _Pphase;
+    phase  = (Pphase - 64.0f) / 64.0f * PI;
+}
 
-void Alienwah::setlrcross(const unsigned char &Plrcross)
+void Alienwah::setdelay(unsigned char _Pdelay)
 {
-    this->Plrcross=Plrcross;
-    lrcross=Plrcross/127.0;
-};
-
-void Alienwah::setphase(const unsigned char &Pphase)
-{
-    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;
+    Pdelay = (_Pdelay >= MAX_ALIENWAH_DELAY) ? MAX_ALIENWAH_DELAY : _Pdelay;
+    oldl   = new complex<float>[Pdelay];
+    oldr   = new complex<float>[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(int npar, 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:
-        setdelay(value);
-        break;
-    case 9:
-        setlrcross(value);
-        break;
-    case 10:
-        setphase(value);
-        break;
-    };
-};
-
-unsigned char Alienwah::getpar(const int &npar)const
+    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:
+            setdelay(value);
+            break;
+        case 9:
+            setlrcross(value);
+            break;
+        case 10:
+            setphase(value);
+            break;
+    }
+}
+
+unsigned char Alienwah::getpar(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(Pdelay);
-        break;
-    case 9:
-        return(Plrcross);
-        break;
-    case 10:
-        return(Pphase);
-        break;
-    default:
-        return (0);
-    };
-
-};
-
+    switch(npar) {
+        case 0:  return Pvolume;
+        case 1:  return Ppanning;
+        case 2:  return lfo.Pfreq;
+        case 3:  return lfo.Prandomness;
+        case 4:  return lfo.PLFOtype;
+        case 5:  return lfo.Pstereo;
+        case 6:  return Pdepth;
+        case 7:  return Pfb;
+        case 8:  return Pdelay;
+        case 9:  return Plrcross;
+        case 10: return Pphase;
+        default: return 0;
+    }
+}
diff --git a/src/Effects/Alienwah.h b/src/Effects/Alienwah.h
index e813737..4e0ea0a 100644
--- a/src/Effects/Alienwah.h
+++ b/src/Effects/Alienwah.h
@@ -22,8 +22,8 @@
 
 #ifndef ALIENWAH_H
 #define ALIENWAH_H
+
 #include <complex>
-#include "../globals.h"
 #include "Effect.h"
 #include "EffectLFO.h"
 
@@ -34,50 +34,47 @@ 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 insertion_ true for insertion Effect
+         * @param efxoutl_ Pointer to Alienwah's left channel output buffer
+         * @param efxoutr_ Pointer to Alienwah's left channel output buffer
+         * @return Initialized Alienwah
+         */
+        Alienwah(bool insertion_,
+                 float *const efxoutl_,
+                 float *const efxoutr_);
+        ~Alienwah();
+        void out(const Stereo<float *> &smp);
+
+        void setpreset(unsigned char npreset);
+        void changepar(int npar, unsigned char value);
+        unsigned char getpar(int npar) const;
+        void cleanup(void);
+
+    private:
+        //Alienwah Parameters
+        EffectLFO     lfo;      //lfo-ul Alienwah
+        unsigned char Pvolume;
+        unsigned char Pdepth;   //the depth of the Alienwah
+        unsigned char Pfb;      //feedback
+        unsigned char Pdelay;
+        unsigned char Pphase;
+
+
+        //Control Parameters
+        void setvolume(unsigned char _Pvolume);
+        void setdepth(unsigned char _Pdepth);
+        void setfb(unsigned char _Pfb);
+        void setdelay(unsigned char _Pdelay);
+        void setphase(unsigned char _Pphase);
+
+        //Internal Values
+        float fb, depth, phase;
+        complex<float> *oldl, *oldr;
+        complex<float>  oldclfol, oldclfor;
+        int oldk;
 };
 
 #endif
-
diff --git a/src/Effects/CMakeLists.txt b/src/Effects/CMakeLists.txt
new file mode 100644
index 0000000..0c15dfa
--- /dev/null
+++ b/src/Effects/CMakeLists.txt
@@ -0,0 +1,19 @@
+set(zynaddsubfx_effect_SRCS
+	Alienwah.cpp
+	Chorus.cpp
+	Distorsion.cpp
+	DynamicFilter.cpp
+	Echo.cpp
+	Effect.cpp
+	EffectLFO.cpp
+	EffectMgr.cpp
+	EQ.cpp
+	Phaser.cpp
+	Reverb.cpp
+)
+
+add_library(zynaddsubfx_effect STATIC
+	${zynaddsubfx_effect_SRCS} 
+	)
+
+target_link_libraries(zynaddsubfx_effect)
diff --git a/src/Effects/Chorus.cpp b/src/Effects/Chorus.cpp
index 66d54a7..ad29df6 100644
--- a/src/Effects/Chorus.cpp
+++ b/src/Effects/Chorus.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  Chorus.C - Chorus and Flange effects
+  Chorus.cpp - Chorus and Flange effects
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -26,291 +26,243 @@
 
 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(bool insertion_, float *const efxoutl_, float *efxoutr_)
+    :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0),
+      maxdelay((int)(MAX_CHORUS_DELAY / 1000.0f * synth->samplerate_f)),
+      delaySample(new float[maxdelay], new float[maxdelay])
 {
-    dlk=0;
-    drk=0;
-    //maxdelay=(int)(MAX_CHORUS_DELAY/1000.0*SAMPLE_RATE);
-    //delayl=new REALTYPE[maxdelay];
-    //delayr=new REALTYPE[maxdelay];
-
+    dlk = 0;
+    drk = 0;
     setpreset(Ppreset);
-
-    lfo.effectlfoout(&lfol,&lfor);
-    dl2=getdelay(lfol);
-    dr2=getdelay(lfor);
+    changepar(1, 64);
+    lfo.effectlfoout(&lfol, &lfor);
+    dl2 = getdelay(lfol);
+    dr2 = getdelay(lfor);
     cleanup();
-};
+}
 
-Chorus::~Chorus() {};
-
-/*
- * get the delay value in samples; xlfo is the current lfo value
- */
-REALTYPE Chorus::getdelay(REALTYPE xlfo)
+Chorus::~Chorus()
 {
-    REALTYPE result;
-    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);
-};
+    delete [] delaySample.l;
+    delete [] delaySample.r;
+}
 
-/*
- * Apply the effect
- */
-void Chorus::out(REALTYPE *smpsl,REALTYPE *smpsr)
+//get the delay value in samples; xlfo is the current lfo value
+float Chorus::getdelay(float xlfo)
 {
-    const Stereo<AuSample> input(AuSample(smpsl,SOUND_BUFFER_SIZE),AuSample(smpsr,SOUND_BUFFER_SIZE));
-    const REALTYPE one=1.0;
-    dl1=dl2;
-    dr1=dr2;
-    lfo.effectlfoout(&lfol,&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];
+    float result =
+        (Pflangemode) ? 0 : (delay + xlfo * depth) * synth->samplerate_f;
+
+    //check if delay is too big (caused by bad setdelay() and setdepth()
+    if((result + 0.5f) >= maxdelay) {
+        cerr
+        <<
+        "WARNING: Chorus.cpp::getdelay(..) too big delay (see setdelay and setdepth funcs.)"
+        << endl;
+        result = maxdelay - 1.0f;
+    }
+    return result;
+}
+
+//Apply the effect
+void Chorus::out(const Stereo<float *> &input)
+{
+    const float one = 1.0f;
+    dl1 = dl2;
+    dr1 = dr2;
+    lfo.effectlfoout(&lfol, &lfor);
+
+    dl2 = getdelay(lfol);
+    dr2 = getdelay(lfor);
+
+    for(int i = 0; i < synth->buffersize; ++i) {
+        float inL = input.l[i];
+        float inR = input.r[i];
         //LRcross
-        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;
+        Stereo<float> tmpc(inL, inR);
+        inL = tmpc.l * (1.0f - lrcross) + tmpc.r * lrcross;
+        inR = tmpc.r * (1.0f - 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
-
-        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;
+        float mdel =
+            (dl1 * (synth->buffersize - i) + dl2 * i) / synth->buffersize_f;
+        if(++dlk >= maxdelay)
+            dlk = 0;
+        float tmp = dlk - mdel + maxdelay * 2.0f; //where should I get the sample from
+
+        dlhi  = (int) tmp;
+        dlhi %= maxdelay;
+
+        float dlhi2 = (dlhi - 1 + maxdelay) % maxdelay;
+        float dllo  = 1.0f - fmod(tmp, one);
+        efxoutl[i] = cinterpolate(delaySample.l, maxdelay, dlhi2) * dllo
+                     + cinterpolate(delaySample.l, maxdelay,
+                                    dlhi) * (1.0f - 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++) {
-            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);
-    };
-};
-
-/*
- * Cleanup the effect
- */
-void Chorus::cleanup()
+        mdel = (dr1 * (synth->buffersize - i) + dr2 * i) / synth->buffersize_f;
+        if(++drk >= maxdelay)
+            drk = 0;
+        tmp = drk * 1.0f - mdel + maxdelay * 2.0f; //where should I get the sample from
+
+        dlhi  = (int) tmp;
+        dlhi %= maxdelay;
+
+        dlhi2      = (dlhi - 1 + maxdelay) % maxdelay;
+        dllo       = 1.0f - fmodf(tmp, one);
+        efxoutr[i] = cinterpolate(delaySample.r, maxdelay, dlhi2) * dllo
+                     + cinterpolate(delaySample.r, maxdelay,
+                                    dlhi) * (1.0f - dllo);
+        delaySample.r[dlk] = inR + efxoutr[i] * fb;
+    }
+
+    if(Poutsub)
+        for(int i = 0; i < synth->buffersize; ++i) {
+            efxoutl[i] *= -1.0f;
+            efxoutr[i] *= -1.0f;
+        }
+
+    for(int i = 0; i < synth->buffersize; ++i) {
+        efxoutl[i] *= pangainL;
+        efxoutr[i] *= pangainR;
+    }
+}
+
+//Cleanup the effect
+void Chorus::cleanup(void)
 {
-    delaySample.l().clear();
-    delaySample.r().clear();
-    //for (int i=0;i<maxdelay;i++){
-//	delayl[i]=0.0;
-//	delayr[i]=0.0;
-    //};
+    memset(delaySample.l, 0, maxdelay * sizeof(float));
+    memset(delaySample.r, 0, maxdelay * sizeof(float));
+}
 
-};
-
-/*
- * Parameter control
- */
-void Chorus::setdepth(const unsigned char &Pdepth)
+//Parameter control
+void Chorus::setdepth(unsigned char _Pdepth)
 {
-    this->Pdepth=Pdepth;
-    depth=(pow(8.0,(Pdepth/127.0)*2.0)-1.0)/1000.0;//seconds
-};
+    Pdepth = _Pdepth;
+    depth  = (powf(8.0f, (Pdepth / 127.0f) * 2.0f) - 1.0f) / 1000.0f; //seconds
+}
 
-void Chorus::setdelay(const unsigned char &Pdelay)
+void Chorus::setdelay(unsigned char _Pdelay)
 {
-    this->Pdelay=Pdelay;
-    delay=(pow(10.0,(Pdelay/127.0)*2.0)-1.0)/1000.0;//seconds
-};
+    Pdelay = _Pdelay;
+    delay  = (powf(10.0f, (Pdelay / 127.0f) * 2.0f) - 1.0f) / 1000.0f; //seconds
+}
 
-void Chorus::setfb(const unsigned char &Pfb)
+void Chorus::setfb(unsigned char _Pfb)
 {
-    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;
-};
+    Pfb = _Pfb;
+    fb  = (Pfb - 64.0f) / 64.1f;
+}
 
-void Chorus::setpanning(const unsigned char &Ppanning)
+void Chorus::setvolume(unsigned char _Pvolume)
 {
-    this->Ppanning=Ppanning;
-    panning=Ppanning/127.0;
-};
+    Pvolume   = _Pvolume;
+    outvolume = Pvolume / 127.0f;
+    volume    = (!insertion) ? 1.0f : outvolume;
+}
 
-void Chorus::setlrcross(const unsigned char &Plrcross)
-{
-    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(int npar, 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:
-        setdelay(value);
-        break;
-    case 8:
-        setfb(value);
-        break;
-    case 9:
-        setlrcross(value);
-        break;
-    case 10:
-        if (value>1) Pflangemode=1;
-        else Pflangemode=value;
-        break;
-    case 11:
-        if (value>1) Poutsub=1;
-        else Poutsub=value;
-        break;
-    };
-};
-
-unsigned char Chorus::getpar(const int &npar)const
+    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:
+            setdelay(value);
+            break;
+        case 8:
+            setfb(value);
+            break;
+        case 9:
+            setlrcross(value);
+            break;
+        case 10:
+            Pflangemode = (value > 1) ? 1 : value;
+            break;
+        case 11:
+            Poutsub = (value > 1) ? 1 : value;
+            break;
+    }
+}
+
+unsigned char Chorus::getpar(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(Pdelay);
-        break;
-    case 8:
-        return(Pfb);
-        break;
-    case 9:
-        return(Plrcross);
-        break;
-    case 10:
-        return(Pflangemode);
-        break;
-    case 11:
-        return(Poutsub);
-        break;
-    default:
-        return (0);
-    };
-
-};
-
+    switch(npar) {
+        case 0:  return Pvolume;
+        case 1:  return Ppanning;
+        case 2:  return lfo.Pfreq;
+        case 3:  return lfo.Prandomness;
+        case 4:  return lfo.PLFOtype;
+        case 5:  return lfo.Pstereo;
+        case 6:  return Pdepth;
+        case 7:  return Pdelay;
+        case 8:  return Pfb;
+        case 9:  return Plrcross;
+        case 10: return Pflangemode;
+        case 11: return Poutsub;
+        default: return 0;
+    }
+}
diff --git a/src/Effects/Chorus.h b/src/Effects/Chorus.h
index f12cbfa..ac9e95a 100644
--- a/src/Effects/Chorus.h
+++ b/src/Effects/Chorus.h
@@ -22,94 +22,85 @@
 
 #ifndef CHORUS_H
 #define CHORUS_H
-#include "../globals.h"
 #include "Effect.h"
 #include "EffectLFO.h"
-#include "../Samples/AuSample.h"
 #include "../Misc/Stereo.h"
 
-#define MAX_CHORUS_DELAY 250.0 //ms
+#define MAX_CHORUS_DELAY 250.0f //ms
 
 /**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 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(bool insertion_, float *efxoutl_, float *efxoutr_);
+        /**Destructor*/
+        ~Chorus();
+        void out(const Stereo<float *> &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(int npar, 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(int npar) const;
+        void cleanup(void);
 
-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
+        unsigned char Pvolume;
+        unsigned char Pdepth;      //the depth of the Chorus(ms)
+        unsigned char Pdelay;      //the delay (ms)
+        unsigned char Pfb;         //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
+        EffectLFO     lfo;         //lfo-ul chorus
 
 
-    //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(unsigned char _Pvolume);
+        void setdepth(unsigned char _Pdepth);
+        void setdelay(unsigned char _Pdelay);
+        void setfb(unsigned char _Pfb);
 
-    //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
+        float depth, delay, fb;
+        float dl1, dl2, dr1, dr2, lfol, lfor;
+        int   maxdelay;
+        Stereo<float *> delaySample;
+        int dlk, drk, dlhi;
+        float getdelay(float xlfo);
 };
 
 #endif
-
diff --git a/src/Effects/Distorsion.cpp b/src/Effects/Distorsion.cpp
index 6aeaab4..85d2645 100644
--- a/src/Effects/Distorsion.cpp
+++ b/src/Effects/Distorsion.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  Distorsion.C - Distorsion effect
+  Distorsion.cpp - Distorsion effect
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -20,167 +20,30 @@
 
 */
 
-#include <cmath>
 #include "Distorsion.h"
+#include "../DSP/AnalogFilter.h"
+#include "../Misc/WaveShapeSmps.h"
+#include <cmath>
 
-
-/*
- * Waveshape (this is called by OscilGen::waveshape and Distorsion::process)
- */
-
-void waveshapesmps(int n,REALTYPE *smps,unsigned char type,unsigned char drive)
-{
-    int i;
-    REALTYPE ws=drive/127.0;
-    REALTYPE tmpv;
-
-    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);
-        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;
-        };
-        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;
-        };
-        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;
-        break;
-    case 5:
-        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;
-        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;
-        };
-        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;
-        };
-        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;
-        };
-        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;
-        };
-        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);
-        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;
-        };
-        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;
-        };
-        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;
-        };
-        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(bool insertion_, float *efxoutl_, float *efxoutr_)
+    :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0),
+      Pvolume(50),
+      Pdrive(90),
+      Plevel(64),
+      Ptype(0),
+      Pnegate(0),
+      Plpf(127),
+      Phpf(0),
+      Pstereo(0),
+      Pprefiltering(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;
-
+    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);
     setpreset(Ppreset);
     cleanup();
-};
+}
 
 Distorsion::~Distorsion()
 {
@@ -188,240 +51,195 @@ Distorsion::~Distorsion()
     delete lpfr;
     delete hpfl;
     delete hpfr;
+}
 
-};
-
-/*
- * Cleanup the effect
- */
-void Distorsion::cleanup()
+//Cleanup the effect
+void Distorsion::cleanup(void)
 {
     lpfl->cleanup();
     hpfl->cleanup();
     lpfr->cleanup();
     hpfr->cleanup();
-};
+}
 
 
-/*
- * Apply the filters
- */
-
-void Distorsion::applyfilters(REALTYPE *efxoutl,REALTYPE *efxoutr)
+//Apply the filters
+void Distorsion::applyfilters(float *efxoutl, float *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)
+//Effect output
+void Distorsion::out(const Stereo<float *> &smp)
 {
-    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);
-
-    if (Pprefiltering==0) applyfilters(efxoutl,efxoutr);
-
-    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;
-
-        efxoutl[i]=lout*2.0*level;
-        efxoutr[i]=rout*2.0*level;
-
-    };
-
-};
-
-
-/*
- * Parameter control
- */
-void Distorsion::setvolume(const unsigned char &Pvolume)
+    float inputvol = powf(5.0f, (Pdrive - 32.0f) / 127.0f);
+    if(Pnegate)
+        inputvol *= -1.0f;
+
+    if(Pstereo) //Stereo
+        for(int i = 0; i < synth->buffersize; ++i) {
+            efxoutl[i] = smp.l[i] * inputvol * pangainL;
+            efxoutr[i] = smp.r[i] * inputvol * pangainR;
+        }
+    else //Mono
+        for(int i = 0; i < synth->buffersize; ++i)
+            efxoutl[i] = (smp.l[i] * pangainL + smp.r[i] * pangainR) * inputvol;
+
+    if(Pprefiltering)
+        applyfilters(efxoutl, efxoutr);
+
+    waveShapeSmps(synth->buffersize, efxoutl, Ptype + 1, Pdrive);
+    if(Pstereo)
+        waveShapeSmps(synth->buffersize, efxoutr, Ptype + 1, Pdrive);
+
+    if(!Pprefiltering)
+        applyfilters(efxoutl, efxoutr);
+
+    if(!Pstereo)
+        memcpy(efxoutr, efxoutl, synth->bufferbytes);
+
+    float level = dB2rap(60.0f * Plevel / 127.0f - 40.0f);
+    for(int i = 0; i < synth->buffersize; ++i) {
+        float lout = efxoutl[i];
+        float rout = efxoutr[i];
+        float l    = lout * (1.0f - lrcross) + rout * lrcross;
+        float r    = rout * (1.0f - lrcross) + lout * lrcross;
+        lout = l;
+        rout = r;
+
+        efxoutl[i] = lout * 2.0f * level;
+        efxoutr[i] = rout * 2.0f * level;
+    }
+}
+
+
+//Parameter control
+void Distorsion::setvolume(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 Distorsion::setpanning(const unsigned char &Ppanning)
-{
-    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;
-};
-
-void Distorsion::setlpf(const unsigned char &Plpf)
+    Pvolume = _Pvolume;
+
+    if(insertion == 0) {
+        outvolume = powf(0.01f, (1.0f - Pvolume / 127.0f)) * 4.0f;
+        volume    = 1.0f;
+    }
+    else
+        volume = outvolume = Pvolume / 127.0f;
+    if(Pvolume == 0)
+        cleanup();
+}
+
+void Distorsion::setlpf(unsigned char _Plpf)
 {
-    this->Plpf=Plpf;
-    REALTYPE fr=exp(pow(Plpf/127.0,0.5)*log(25000.0))+40;
+    Plpf = _Plpf;
+    float fr = expf(powf(Plpf / 127.0f, 0.5f) * logf(25000.0f)) + 40.0f;
     lpfl->setfreq(fr);
     lpfr->setfreq(fr);
-};
+}
 
-void Distorsion::sethpf(const unsigned char &Phpf)
+void Distorsion::sethpf(unsigned char _Phpf)
 {
-    this->Phpf=Phpf;
-    REALTYPE fr=exp(pow(Phpf/127.0,0.5)*log(25000.0))+20.0;
+    Phpf = _Phpf;
+    float fr = expf(powf(Phpf / 127.0f, 0.5f) * logf(25000.0f)) + 20.0f;
     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) //lower the volume if this is system effect
+        changepar(0, (int) (presets[npreset][0] / 1.5f));
+    Ppreset = npreset;
     cleanup();
-};
+}
 
 
-void Distorsion::changepar(const int &npar,const unsigned char &value)
+void Distorsion::changepar(int npar, unsigned char value)
 {
-    switch (npar) {
-    case 0:
-        setvolume(value);
-        break;
-    case 1:
-        setpanning(value);
-        break;
-    case 2:
-        setlrcross(value);
-        break;
-    case 3:
-        Pdrive=value;
-        break;
-    case 4:
-        Plevel=value;
-        break;
-    case 5:
-        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;
-        break;
-    case 7:
-        setlpf(value);
-        break;
-    case 8:
-        sethpf(value);
-        break;
-    case 9:
-        if (value>1) Pstereo=1;
-        else Pstereo=value;
-        break;
-    case 10:
-        Pprefiltering=value;
-        break;
-    };
-};
-
-unsigned char Distorsion::getpar(const int &npar)const
+    switch(npar) {
+        case 0:
+            setvolume(value);
+            break;
+        case 1:
+            setpanning(value);
+            break;
+        case 2:
+            setlrcross(value);
+            break;
+        case 3:
+            Pdrive = value;
+            break;
+        case 4:
+            Plevel = value;
+            break;
+        case 5:
+            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;
+            break;
+        case 7:
+            setlpf(value);
+            break;
+        case 8:
+            sethpf(value);
+            break;
+        case 9:
+            Pstereo = (value > 1) ? 1 : value;
+            break;
+        case 10:
+            Pprefiltering = value;
+            break;
+    }
+}
+
+unsigned char Distorsion::getpar(int npar) const
 {
-    switch (npar) {
-    case 0:
-        return(Pvolume);
-        break;
-    case 1:
-        return(Ppanning);
-        break;
-    case 2:
-        return(Plrcross);
-        break;
-    case 3:
-        return(Pdrive);
-        break;
-    case 4:
-        return(Plevel);
-        break;
-    case 5:
-        return(Ptype);
-        break;
-    case 6:
-        return(Pnegate);
-        break;
-    case 7:
-        return(Plpf);
-        break;
-    case 8:
-        return(Phpf);
-        break;
-    case 9:
-        return(Pstereo);
-        break;
-    case 10:
-        return(Pprefiltering);
-        break;
-    };
-    return(0);//in case of bogus parameter number
-};
-
+    switch(npar) {
+        case 0:  return Pvolume;
+        case 1:  return Ppanning;
+        case 2:  return Plrcross;
+        case 3:  return Pdrive;
+        case 4:  return Plevel;
+        case 5:  return Ptype;
+        case 6:  return Pnegate;
+        case 7:  return Plpf;
+        case 8:  return Phpf;
+        case 9:  return Pstereo;
+        case 10: return Pprefiltering;
+        default: return 0; //in case of bogus parameter number
+    }
+}
diff --git a/src/Effects/Distorsion.h b/src/Effects/Distorsion.h
index efe3b82..eb06a9c 100644
--- a/src/Effects/Distorsion.h
+++ b/src/Effects/Distorsion.h
@@ -23,51 +23,39 @@
 #ifndef DISTORSION_H
 #define DISTORSION_H
 
-#include "../globals.h"
-#include "../DSP/AnalogFilter.h"
 #include "Effect.h"
 
-//Waveshaping(called by Distorsion effect and waveshape from OscilGen)
-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);
-
-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;
-
+    public:
+        Distorsion(bool insertion, float *efxoutl_, float *efxoutr_);
+        ~Distorsion();
+        void out(const Stereo<float *> &smp);
+        void setpreset(unsigned char npreset);
+        void changepar(int npar, unsigned char value);
+        unsigned char getpar(int npar) const;
+        void cleanup(void);
+        void applyfilters(float *efxoutl, float *efxoutr);
+
+    private:
+        //Parameters
+        unsigned char Pvolume;       //Volume or E/R
+        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(unsigned char _Pvolume);
+        void setlpf(unsigned char _Plpf);
+        void sethpf(unsigned char _Phpf);
+
+        //Real Parameters
+        class AnalogFilter * lpfl, *lpfr, *hpfl, *hpfr;
 };
 
-
 #endif
-
diff --git a/src/Effects/DynamicFilter.cpp b/src/Effects/DynamicFilter.cpp
index b7b367e..1074fa7 100644
--- a/src/Effects/DynamicFilter.cpp
+++ b/src/Effects/DynamicFilter.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  DynamicFilter.C - "WahWah" effect and others
+  DynamicFilter.cpp - "WahWah" effect and others
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -22,323 +22,290 @@
 
 #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)
+#include "../DSP/Filter.h"
+
+DynamicFilter::DynamicFilter(bool insertion_, float *efxoutl_, float *efxoutr_)
+    :Effect(insertion_, efxoutl_, efxoutr_, new FilterParams(0, 64, 64), 0),
+      Pvolume(110),
+      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)
+// Apply the effect
+void DynamicFilter::out(const Stereo<float *> &smp)
 {
-    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();
+    float lfol, lfor;
+    lfo.effectlfoout(&lfol, &lfor);
+    lfol *= depth * 5.0f;
+    lfor *= depth * 5.0f;
+    const float freq = filterpars->getfreq();
+    const float q    = filterpars->getq();
 
-    for (i=0;i<SOUND_BUFFER_SIZE;i++) {
-        efxoutl[i]=smpsl[i];
-        efxoutr[i]=smpsr[i];
+    for(int i = 0; i < synth->buffersize; ++i) {
+        efxoutl[i] = smp.l[i];
+        efxoutr[i] = smp.r[i];
 
-        REALTYPE x=(fabs(smpsl[i])+fabs(smpsr[i]))*0.5;
-        ms1=ms1*(1.0-ampsmooth)+x*ampsmooth+1e-10;
-    };
+        const float x = (fabsf(smp.l[i]) + fabsf(smp.l[i])) * 0.5f;
+        ms1 = ms1 * (1.0f - ampsmooth) + x * ampsmooth + 1e-10;
+    }
 
+    const float ampsmooth2 = powf(ampsmooth, 0.2f) * 0.3f;
+    ms2 = ms2 * (1.0f - ampsmooth2) + ms1 * ampsmooth2;
+    ms3 = ms3 * (1.0f - ampsmooth2) + ms2 * ampsmooth2;
+    ms4 = ms4 * (1.0f - ampsmooth2) + ms3 * ampsmooth2;
+    const float rms = (sqrtf(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);
-
-    filterl->setfreq_and_q(frl,q);
-    filterr->setfreq_and_q(frr,q);
+    const float frl = Filter::getrealfreq(freq + lfol + rms);
+    const float frr = Filter::getrealfreq(freq + lfor + rms);
 
+    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);
-    };
-
-};
-
-/*
- * Cleanup the effect
- */
-void DynamicFilter::cleanup()
+    for(int i = 0; i < synth->buffersize; ++i) {
+        efxoutl[i] *= pangainL;
+        efxoutr[i] *= pangainR;
+    }
+}
+
+// Cleanup the effect
+void DynamicFilter::cleanup(void)
 {
     reinitfilter();
-    ms1=0.0;
-    ms2=0.0;
-    ms3=0.0;
-    ms4=0.0;
-};
+    ms1 = ms2 = ms3 = ms4 = 0.0f;
+}
 
 
-/*
- * Parameter control
- */
-
-void DynamicFilter::setdepth(const unsigned char &Pdepth)
+//Parameter control
+void DynamicFilter::setdepth(unsigned char _Pdepth)
 {
-    this->Pdepth=Pdepth;
-    depth=pow((Pdepth/127.0),2.0);
-};
+    Pdepth = _Pdepth;
+    depth  = powf(Pdepth / 127.0f, 2.0f);
+}
 
 
-void DynamicFilter::setvolume(const unsigned char &Pvolume)
+void DynamicFilter::setvolume(unsigned char _Pvolume)
 {
-    this->Pvolume=Pvolume;
-    outvolume=Pvolume/127.0;
-    if (insertion==0) volume=1.0;
-    else volume=outvolume;
-};
-
-void DynamicFilter::setpanning(const unsigned char &Ppanning)
+    Pvolume   = _Pvolume;
+    outvolume = Pvolume / 127.0f;
+    if(!insertion)
+        volume = 1.0f;
+    else
+        volume = outvolume;
+}
+
+void DynamicFilter::setampsns(unsigned char _Pampsns)
 {
-    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;
-};
-
-void DynamicFilter::reinitfilter()
+    Pampsns = _Pampsns;
+    ampsns  = powf(Pampsns / 127.0f, 2.5f) * 10.0f;
+    if(Pampsnsinv)
+        ampsns = -ampsns;
+    ampsmooth = expf(-Pampsmooth / 127.0f * 10.0f) * 0.99f;
+}
+
+void DynamicFilter::reinitfilter(void)
 {
-    if (filterl!=NULL) delete(filterl);
-    if (filterr!=NULL) delete(filterr);
-    filterl=new Filter(filterpars);
-    filterr=new Filter(filterpars);
-};
+    delete filterl;
+    delete filterr;
+    filterl = Filter::generate(filterpars);
+    filterr = Filter::generate(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) {
-    case 0:
-        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;
-        break;
-    case 2:
-        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;
-        // "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;
-        // "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;
-        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;
-        break;
-    };
+
+    switch(npreset) {
+        case 0:
+            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;
+            break;
+        case 2:
+            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;
+            // "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;
+            // "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;
+            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;
+            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) //lower the volume if this is system effect
+        changepar(0, presets[npreset][0] * 0.5f);
+    Ppreset = npreset;
     reinitfilter();
-};
+}
 
 
-void DynamicFilter::changepar(const int &npar,const unsigned char &value)
+void DynamicFilter::changepar(int npar, 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:
-        setampsns(value);
-        break;
-    case 8:
-        Pampsnsinv=value;
-        setampsns(Pampsns);
-        break;
-    case 9:
-        Pampsmooth=value;
-        setampsns(Pampsns);
-        break;
-    };
-};
-
-unsigned char DynamicFilter::getpar(const int &npar)const
+    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:
+            setampsns(value);
+            break;
+        case 8:
+            Pampsnsinv = value;
+            setampsns(Pampsns);
+            break;
+        case 9:
+            Pampsmooth = value;
+            setampsns(Pampsns);
+            break;
+    }
+}
+
+unsigned char DynamicFilter::getpar(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(Pampsns);
-        break;
-    case 8:
-        return(Pampsnsinv);
-        break;
-    case 9:
-        return(Pampsmooth);
-        break;
-    default:
-        return (0);
-    };
-
-};
-
+    switch(npar) {
+        case 0:  return Pvolume;
+        case 1:  return Ppanning;
+        case 2:  return lfo.Pfreq;
+        case 3:  return lfo.Prandomness;
+        case 4:  return lfo.PLFOtype;
+        case 5:  return lfo.Pstereo;
+        case 6:  return Pdepth;
+        case 7:  return Pampsns;
+        case 8:  return Pampsnsinv;
+        case 9:  return Pampsmooth;
+        default: return 0;
+    }
+}
diff --git a/src/Effects/DynamicFilter.h b/src/Effects/DynamicFilter.h
index 9c547c3..0b2c40d 100644
--- a/src/Effects/DynamicFilter.h
+++ b/src/Effects/DynamicFilter.h
@@ -22,51 +22,44 @@
 
 #ifndef DYNAMICFILTER_H
 #define DYNAMICFILTER_H
-#include "../globals.h"
+
 #include "Effect.h"
 #include "EffectLFO.h"
 
-#include "../DSP/Filter.h"
 /**DynamicFilter Effect*/
 class DynamicFilter:public Effect
 {
-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 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
-
-    //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();
-
-    //Internal Values
-    REALTYPE panning,depth,ampsns,ampsmooth;
-
-    Filter *filterl,*filterr;
-
-    REALTYPE ms1,ms2,ms3,ms4;//mean squares
+    public:
+        DynamicFilter(bool insertion_, float *efxoutl_, float *efxoutr_);
+        ~DynamicFilter();
+        void out(const Stereo<float *> &smp);
+
+        void setpreset(unsigned char npreset);
+        void changepar(int npar, unsigned char value);
+        unsigned char getpar(int npar) const;
+        void cleanup(void);
+
+    private:
+        //Parametrii DynamicFilter
+        EffectLFO     lfo;          //lfo-ul DynamicFilter
+        unsigned char Pvolume;      //Volume
+        unsigned char Pdepth;       //the depth of the lfo
+        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(unsigned char _Pvolume);
+        void setdepth(unsigned char _Pdepth);
+        void setampsns(unsigned char _Pampsns);
+
+        void reinitfilter(void);
+
+        //Internal Values
+        float depth, ampsns, ampsmooth;
+
+        class Filter * filterl, *filterr;
+        float ms1, ms2, ms3, ms4; //mean squares
 };
 
 #endif
-
diff --git a/src/Effects/EQ.cpp b/src/Effects/EQ.cpp
index b5f92ea..8d35405 100644
--- a/src/Effects/EQ.cpp
+++ b/src/Effects/EQ.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  EQ.C - EQ effect
+  EQ.cpp - EQ effect
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -22,193 +22,177 @@
 
 #include <cmath>
 #include "EQ.h"
+#include "../DSP/AnalogFilter.h"
 
-EQ::EQ(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_)
-        :Effect(insertion_,efxoutl_,efxoutr_,NULL,0)
+EQ::EQ(bool insertion_, float *efxoutl_, float *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.0f, 1.0f, 0);
+        filter[i].r = new AnalogFilter(6, 1000.0f, 1.0f, 0);
+    }
     //default values
-    Pvolume=50;
+    Pvolume = 50;
 
     setpreset(Ppreset);
     cleanup();
-};
+}
 
-EQ::~EQ()
-{
-};
 
-/*
- * Cleanup the effect
- */
-void EQ::cleanup()
+// Cleanup the effect
+void EQ::cleanup(void)
 {
-    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)
+//Effect output
+void EQ::out(const Stereo<float *> &smp)
 {
-    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(int i = 0; i < synth->buffersize; ++i) {
+        efxoutl[i] = smp.l[i] * volume;
+        efxoutr[i] = smp.r[i] * volume;
+    }
+
+    for(int i = 0; i < MAX_EQ_BANDS; ++i) {
+        if(filter[i].Ptype == 0)
+            continue;
         filter[i].l->filterout(efxoutl);
         filter[i].r->filterout(efxoutr);
-    };
-};
+    }
+}
 
 
-/*
- * Parameter control
- */
-void EQ::setvolume(const unsigned char &Pvolume)
+//Parameter control
+void EQ::setvolume(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;
-    };
-
-};
+    Pvolume   = _Pvolume;
+    outvolume = powf(0.005f, (1.0f - Pvolume / 127.0f)) * 10.0f;
+    volume    = (!insertion) ? 1.0f : outvolume;
+}
 
 
 void EQ::setpreset(unsigned char npreset)
 {
-    const int PRESET_SIZE=1;
-    const int NUM_PRESETS=2;
-    unsigned char presets[NUM_PRESETS][PRESET_SIZE]={
-        //EQ 1
-        {67},
-        //EQ 2
-        {67}
+    const int     PRESET_SIZE = 1;
+    const int     NUM_PRESETS = 2;
+    unsigned char presets[NUM_PRESETS][PRESET_SIZE] = {
+        {67}, //EQ 1
+        {67}  //EQ 2
     };
 
-    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(int npar, unsigned char value)
 {
-    switch (npar) {
-    case 0:
-        setvolume(value);
-        break;
-    };
-    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
-
-    REALTYPE tmp;
-    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);
-        };
-        break;
-    case 1:
-        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].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].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].l->setstages(value);
-        filter[nb].r->setstages(value);
-        break;
-    };
-};
-
-unsigned char EQ::getpar(const int &npar)const
+    switch(npar) {
+        case 0:
+            setvolume(value);
+            break;
+    }
+    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
+
+    float tmp;
+    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);
+            }
+            break;
+        case 1:
+            filter[nb].Pfreq = value;
+            tmp = 600.0f * powf(30.0f, (value - 64.0f) / 64.0f);
+            filter[nb].l->setfreq(tmp);
+            filter[nb].r->setfreq(tmp);
+            break;
+        case 2:
+            filter[nb].Pgain = value;
+            tmp = 30.0f * (value - 64.0f) / 64.0f;
+            filter[nb].l->setgain(tmp);
+            filter[nb].r->setgain(tmp);
+            break;
+        case 3:
+            filter[nb].Pq = value;
+            tmp = powf(30.0f, (value - 64.0f) / 64.0f);
+            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].l->setstages(value);
+            filter[nb].r->setstages(value);
+            break;
+    }
+}
+
+unsigned char EQ::getpar(int npar) const
 {
-    switch (npar) {
-    case 0:
-        return(Pvolume);
-        break;
-    };
-
-    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) {
-    case 0:
-        return(filter[nb].Ptype);
-        break;
-    case 1:
-        return(filter[nb].Pfreq);
-        break;
-    case 2:
-        return(filter[nb].Pgain);
-        break;
-    case 3:
-        return(filter[nb].Pq);
-        break;
-    case 4:
-        return(filter[nb].Pstages);
-        break;
-    };
-
-    return(0);//in case of bogus parameter number
-};
-
-
-
-
-REALTYPE EQ::getfreqresponse(REALTYPE freq)
+    switch(npar) {
+        case 0:
+            return Pvolume;
+            break;
+    }
+
+    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) {
+        case 0:
+            return filter[nb].Ptype;
+            break;
+        case 1:
+            return filter[nb].Pfreq;
+            break;
+        case 2:
+            return filter[nb].Pgain;
+            break;
+        case 3:
+            return filter[nb].Pq;
+            break;
+        case 4:
+            return filter[nb].Pstages;
+            break;
+        default: return 0; //in case of bogus parameter number
+    }
+}
+
+
+float EQ::getfreqresponse(float 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));
-};
-
-
+    float resp = 1.0f;
+    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
index 810dd6e..9dd14fb 100644
--- a/src/Effects/EQ.h
+++ b/src/Effects/EQ.h
@@ -23,38 +23,33 @@
 #ifndef EQ_H
 #define EQ_H
 
-#include "../globals.h"
-#include "../DSP/AnalogFilter.h"
 #include "Effect.h"
 
 /**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(bool insertion_, float *efxoutl_, float *efxoutr_);
+        ~EQ() {}
+        void out(const Stereo<float *> &smp);
+        void setpreset(unsigned char npreset);
+        void changepar(int npar, unsigned char value);
+        unsigned char getpar(int npar) const;
+        void cleanup(void);
+        float getfreqresponse(float freq);
+
+    private:
+        //Parameters
+        unsigned char Pvolume;
+
+        void setvolume(unsigned char _Pvolume);
+
+        struct {
+            //parameters
+            unsigned char Ptype, Pfreq, Pgain, Pq, Pstages;
+            //internal values
+            class AnalogFilter * l, *r;
+        } filter[MAX_EQ_BANDS];
 };
 
-
 #endif
-
-
diff --git a/src/Effects/Echo.cpp b/src/Effects/Echo.cpp
index 69b4a24..803bbf3 100644
--- a/src/Effects/Echo.cpp
+++ b/src/Effects/Echo.cpp
@@ -1,9 +1,11 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  Echo.C - Echo effect
+  Echo.cpp - Echo effect
   Copyright (C) 2002-2005 Nasca Octavian Paul
+  Copyright (C) 2009-2010 Mark McCurry
   Author: Nasca Octavian Paul
+          Mark McCurry
 
   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
@@ -21,233 +23,209 @@
 */
 
 #include <cmath>
-#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)
+#define MAX_DELAY 2
+
+Echo::Echo(bool insertion_, float *efxoutl_, float *efxoutr_)
+    :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0),
+      Pvolume(50),
+      Pdelay(60),
+      Plrdelay(100),
+      Pfb(40),
+      Phidamp(60),
+      delayTime(1),
+      lrdelay(0),
+      avgDelay(0),
+      delay(new float[(int)(MAX_DELAY * synth->samplerate)],
+            new float[(int)(MAX_DELAY * synth->samplerate)]),
+      old(0.0f),
+      pos(0),
+      delta(1),
+      ndelta(1)
 {
+    initdelays();
     setpreset(Ppreset);
-    cleanup();
 }
 
-Echo::~Echo() {}
+Echo::~Echo()
+{
+    delete[] delay.l;
+    delete[] delay.r;
+}
 
-/*
- * Cleanup the effect
- */
-void Echo::cleanup()
+//Cleanup the effect
+void Echo::cleanup(void)
 {
-    delaySample.left().clear();
-    delaySample.right().clear();
-    old=Stereo<REALTYPE>(0.0);
+    memset(delay.l, 0, MAX_DELAY * synth->samplerate * sizeof(float));
+    memset(delay.r, 0, MAX_DELAY * synth->samplerate * sizeof(float));
+    old = Stereo<float>(0.0f);
 }
 
+inline int max(int a, int b)
+{
+    return a > b ? a : b;
+}
 
-/*
- * Initialize the delays
- */
-void Echo::initdelays()
+//Initialize the delays
+void Echo::initdelays(void)
 {
-    /**\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;
+    cleanup();
+    //number of seconds to delay left chan
+    float dl = avgDelay - lrdelay;
 
-    delaySample.left()=AuSample(dl);
-    delaySample.right()=AuSample(dr);
+    //number of seconds to delay right chan
+    float dr = avgDelay + lrdelay;
 
-    cleanup();
+    ndelta.l = max(1, (int) (dl * synth->samplerate));
+    ndelta.r = max(1, (int) (dr * synth->samplerate));
 }
 
-/*
- * Effect output
- */
-void Echo::out(REALTYPE *const smpsl,REALTYPE *const smpsr)
+//Effect output
+void Echo::out(const Stereo<float *> &input)
 {
-//void Echo::out(const Stereo<AuSample> & input){ //ideal
-    REALTYPE l,r,ldl,rdl;/**\todo move l+r->? ldl+rdl->?*/
-    Stereo<AuSample> input(AuSample(smpsl,SOUND_BUFFER_SIZE),AuSample(smpsr,SOUND_BUFFER_SIZE));
-
-    for (int i=0;i<input.left().size();i++) {
-        ldl=delaySample.left()[kl];
-        rdl=delaySample.right()[kr];
-        l=ldl*(1.0-lrcross)+rdl*lrcross;
-        r=rdl*(1.0-lrcross)+ldl*lrcross;
-        ldl=l;
-        rdl=r;
+    for(int i = 0; i < synth->buffersize; ++i) {
+        float ldl = delay.l[pos.l];
+        float rdl = delay.r[pos.r];
+        ldl = ldl * (1.0f - lrcross) + rdl * lrcross;
+        rdl = rdl * (1.0f - lrcross) + ldl * lrcross;
 
-        efxoutl[i]=ldl*2.0;
-        efxoutr[i]=rdl*2.0;
+        efxoutl[i] = ldl * 2.0f;
+        efxoutr[i] = rdl * 2.0f;
 
-
-        ldl=input.left()[i]*panning-ldl*fb;
-        rdl=input.right()[i]*(1.0-panning)-rdl*fb;
+        ldl = input.l[i] * pangainL - ldl * fb;
+        rdl = input.r[i] * pangainR - rdl * fb;
 
         //LowPass Filter
-        delaySample.left()[kl]=ldl=ldl*hidamp+old.left()*(1.0-hidamp);
-        delaySample.right()[kr]=rdl=rdl*hidamp+old.right()*(1.0-hidamp);
-        old.left()=ldl;
-        old.right()=rdl;
-
-        if (++kl>=dl) kl=0;
-        if (++kr>=dr) kr=0;
-    };
-
+        old.l = delay.l[(pos.l + delta.l) % (MAX_DELAY * synth->samplerate)] =
+                    ldl * hidamp + old.l * (1.0f - hidamp);
+        old.r = delay.r[(pos.r + delta.r) % (MAX_DELAY * synth->samplerate)] =
+                    rdl * hidamp + old.r * (1.0f - hidamp);
+
+        //increment
+        ++pos.l; // += delta.l;
+        ++pos.r; // += delta.r;
+
+        //ensure that pos is still in bounds
+        pos.l %= MAX_DELAY * synth->samplerate;
+        pos.r %= MAX_DELAY * synth->samplerate;
+
+        //adjust delay if needed
+        delta.l = (15 * delta.l + ndelta.l) / 16;
+        delta.r = (15 * delta.r + ndelta.r) / 16;
+    }
 }
 
 
-/*
- * Parameter control
- */
-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();
-
-}
-
-void Echo::setpanning(const unsigned char & Ppanning)
+//Parameter control
+void Echo::setvolume(unsigned char _Pvolume)
 {
-    this->Ppanning=Ppanning;
-    panning=(Ppanning+0.5)/127.0;
+    Pvolume = _Pvolume;
+
+    if(insertion == 0) {
+        outvolume = powf(0.01f, (1.0f - Pvolume / 127.0f)) * 4.0f;
+        volume    = 1.0f;
+    }
+    else
+        volume = outvolume = Pvolume / 127.0f;
+    if(Pvolume == 0)
+        cleanup();
 }
 
-void Echo::setdelay(const unsigned char & Pdelay)
+void Echo::setdelay(unsigned char _Pdelay)
 {
-    delay.setmVal(Pdelay);
-    //this->Pdelay=Pdelay;
-    //delay=1+(int)(Pdelay/127.0*SAMPLE_RATE*1.5);//0 .. 1.5 sec
+    Pdelay   = _Pdelay;
+    avgDelay = (Pdelay / 127.0f * 1.5f); //0 .. 1.5 sec
     initdelays();
 }
 
-void Echo::setlrdelay(const unsigned char & Plrdelay)
+void Echo::setlrdelay(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;
+    float tmp;
+    Plrdelay = _Plrdelay;
+    tmp      =
+        (powf(2.0f, fabsf(Plrdelay - 64.0f) / 64.0f * 9.0f) - 1.0f) / 1000.0f;
+    if(Plrdelay < 64.0f)
+        tmp = -tmp;
+    lrdelay = tmp;
     initdelays();
 }
 
-void Echo::setlrcross(const unsigned char & Plrcross)
+void Echo::setfb(unsigned char _Pfb)
 {
-    this->Plrcross=Plrcross;
-    lrcross=Plrcross/127.0*1.0;
+    Pfb = _Pfb;
+    fb  = Pfb / 128.0f;
 }
 
-void Echo::setfb(const unsigned char & Pfb)
+void Echo::sethidamp(unsigned char _Phidamp)
 {
-    this->Pfb=Pfb;
-    fb=Pfb/128.0;
-}
-
-void Echo::sethidamp(const unsigned char & Phidamp)
-{
-    this->Phidamp=Phidamp;
-    hidamp=1.0-Phidamp/127.0;
+    Phidamp = _Phidamp;
+    hidamp  = 1.0f - Phidamp / 127.0f;
 }
 
 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]={
-        //Echo 1
-        {67,64,35,64,30,59,0},
-        //Echo 2
-        {67,64,21,64,30,59,0},
-        //Echo 3
-        {67,75,60,64,30,59,10},
-        //Simple Echo
-        {67,60,44,64,30,0,0},
-        //Canyon
-        {67,60,102,50,30,82,48},
-        //Panning Echo 1
-        {67,64,44,17,0,82,24},
-        //Panning Echo 2
-        {81,60,46,118,100,68,18},
-        //Panning Echo 3
-        {81,60,26,100,127,67,36},
-        //Feedback Echo
-        {62,64,28,64,100,90,55}
+    const int     PRESET_SIZE = 7;
+    const int     NUM_PRESETS = 9;
+    unsigned char presets[NUM_PRESETS][PRESET_SIZE] = {
+        {67, 64, 35,  64,  30,  59, 0 }, //Echo 1
+        {67, 64, 21,  64,  30,  59, 0 }, //Echo 2
+        {67, 75, 60,  64,  30,  59, 10}, //Echo 3
+        {67, 60, 44,  64,  30,  0,  0 }, //Simple Echo
+        {67, 60, 102, 50,  30,  82, 48}, //Canyon
+        {67, 64, 44,  17,  0,   82, 24}, //Panning Echo 1
+        {81, 60, 46,  118, 100, 68, 18}, //Panning Echo 2
+        {81, 60, 26,  100, 127, 67, 36}, //Panning Echo 3
+        {62, 64, 28,  64,  100, 90, 55}  //Feedback Echo
     };
 
-
-    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(int npar, unsigned char value)
 {
-    switch (npar) {
-    case 0:
-        setvolume(value);
-        break;
-    case 1:
-        setpanning(value);
-        break;
-    case 2:
-        setdelay(value);
-        break;
-    case 3:
-        setlrdelay(value);
-        break;
-    case 4:
-        setlrcross(value);
-        break;
-    case 5:
-        setfb(value);
-        break;
-    case 6:
-        sethidamp(value);
-        break;
-    };
+    switch(npar) {
+        case 0:
+            setvolume(value);
+            break;
+        case 1:
+            setpanning(value);
+            break;
+        case 2:
+            setdelay(value);
+            break;
+        case 3:
+            setlrdelay(value);
+            break;
+        case 4:
+            setlrcross(value);
+            break;
+        case 5:
+            setfb(value);
+            break;
+        case 6:
+            sethidamp(value);
+            break;
+    }
 }
 
-unsigned char Echo::getpar(const int & npar)const
+unsigned char Echo::getpar(int npar) const
 {
-    switch (npar) {
-    case 0:
-        return(Pvolume);
-        break;
-    case 1:
-        return(Ppanning);
-        break;
-    case 2:
-        return(delay.getmVal());
-        break;
-    case 3:
-        return(Plrdelay);
-        break;
-    case 4:
-        return(Plrcross);
-        break;
-    case 5:
-        return(Pfb);
-        break;
-    case 6:
-        return(Phidamp);
-        break;
-    };
-    return(0);// in case of bogus parameter number
+    switch(npar) {
+        case 0:  return Pvolume;
+        case 1:  return Ppanning;
+        case 2:  return Pdelay;
+        case 3:  return Plrdelay;
+        case 4:  return Plrcross;
+        case 5:  return Pfb;
+        case 6:  return Phidamp;
+        default: return 0; // in case of bogus parameter number
+    }
 }
-
diff --git a/src/Effects/Echo.h b/src/Effects/Echo.h
index 2daf81f..6b79adc 100644
--- a/src/Effects/Echo.h
+++ b/src/Effects/Echo.h
@@ -23,114 +23,82 @@
 #ifndef ECHO_H
 #define ECHO_H
 
-#include "../globals.h"
 #include "Effect.h"
-#include "../Samples/AuSample.h"
 #include "../Misc/Stereo.h"
-#include "../Controls/DelayCtl.h"
 
 /**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);
-
-    /**
-     * 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:
+        Echo(bool insertion_, float *efxoutl_, float *efxoutr_);
+        ~Echo();
+
+        void out(const Stereo<float *> &input);
+        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(int npar, 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(int npar) const;
+        int getnumparams(void);
+        void cleanup(void);
+    private:
+        //Parameters
+        unsigned char Pvolume;  /**<#1 Volume or Dry/Wetness*/
+        unsigned char Pdelay;   /**<#3 Delay of the Echo*/
+        unsigned char Plrdelay; /**<#4 L/R delay difference*/
+        unsigned char Pfb;      /**<#6Feedback*/
+        unsigned char Phidamp;  /**<#7Dampening of the Echo*/
+
+        void setvolume(unsigned char _Pvolume);
+        void setdelay(unsigned char _Pdelay);
+        void setlrdelay(unsigned char _Plrdelay);
+        void setfb(unsigned char _Pfb);
+        void sethidamp(unsigned char _Phidamp);
+
+        //Real Parameters
+        float fb, hidamp;
+        //Left/Right delay lengths
+        Stereo<int> delayTime;
+        float       lrdelay;
+        float       avgDelay;
+
+        void initdelays(void);
+        //2 channel ring buffer
+        Stereo<float *> delay;
+        Stereo<float>   old;
+
+        //position of reading/writing from delaysample
+        Stereo<int> pos;
+        //step size for delay buffer
+        Stereo<int> delta;
+        Stereo<int> ndelta;
 };
 
 #endif
-
diff --git a/src/Effects/Effect.cpp b/src/Effects/Effect.cpp
index b0b4dac..42eee79 100644
--- a/src/Effects/Effect.cpp
+++ b/src/Effects/Effect.cpp
@@ -1,8 +1,9 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  Effect.C - this class is inherited by the all effects(Reverb, Echo, ..)
+  Effect.cpp - this class is inherited by the all effects(Reverb, Echo, ..)
   Copyright (C) 2002-2005 Nasca Octavian Paul
+  Copyright 2011, Alan Calvert
   Author: Nasca Octavian Paul
 
   This program is free software; you can redistribute it and/or modify
@@ -21,10 +22,41 @@
 */
 
 #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_) {}
+#include "../Params/FilterParams.h"
+#include <cmath>
+
+Effect::Effect(bool insertion_, float *efxoutl_, float *efxoutr_,
+               FilterParams *filterpars_, unsigned char Ppreset_)
+    :Ppreset(Ppreset_),
+      efxoutl(efxoutl_),
+      efxoutr(efxoutr_),
+      filterpars(filterpars_),
+      insertion(insertion_)
+{}
+
+void Effect::out(float *const smpsl, float *const smpsr)
+{
+    out(Stereo<float *>(smpsl, smpsr));
+}
+
+void Effect::crossover(float &a, float &b, float crossover)
+{
+    float tmpa = a;
+    float tmpb = b;
+    a = tmpa * (1.0f - crossover) + tmpb * crossover;
+    b = tmpb * (1.0f - crossover) + tmpa * crossover;
+}
+
+void Effect::setpanning(char Ppanning_)
+{
+    Ppanning = Ppanning_;
+    float t = (Ppanning > 0) ? (float)(Ppanning - 1) / 126.0f : 0.0f;
+    pangainL = cosf(t * PI / 2.0f);
+    pangainR = cosf((1.0f - t) * PI / 2.0f);
+}
+
+void Effect::setlrcross(char Plrcross_)
+{
+    Plrcross = Plrcross_;
+    lrcross  = (float)Plrcross / 127.0f;
+}
diff --git a/src/Effects/Effect.h b/src/Effects/Effect.h
index 0da3d83..d4d4a46 100644
--- a/src/Effects/Effect.h
+++ b/src/Effects/Effect.h
@@ -26,78 +26,80 @@
 #include "../Misc/Util.h"
 #include "../globals.h"
 #include "../Params/FilterParams.h"
+#include "../Misc/Stereo.h"
 
+class FilterParams;
 
 /**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
+         * @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_, float *efxoutl_, float *efxoutr_,
+               FilterParams *filterpars_, unsigned char Ppreset_);
+        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(int npar, 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(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
+         */
+        void out(float *const smpsl, float *const smpsr);
+        virtual void out(const Stereo<float *> &smp) = 0;
+        /**Reset the state of the effect*/
+        virtual void cleanup(void) {}
+        virtual float getfreqresponse(float freq) { return freq; }
+
+        unsigned char Ppreset;   /**<Currently used preset*/
+        float *const  efxoutl; /**<Effect out Left Channel*/
+        float *const  efxoutr; /**<Effect out Right Channel*/
+        float 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
+                          * The out volume of such effects are always 1.0f, so
                           * this setting tells me how is the volume to the
                           * Master Output only.*/
 
-    REALTYPE volume;
+        float volume;
 
-    FilterParams *filterpars;/**<Parameters for filters used by Effect*/
-protected:
+        FilterParams *filterpars; /**<Parameters for filters used by Effect*/
 
-    const bool insertion;/**<If Effect is an insertion effect, insertion=1
-                           *otherwise, it should be insertion=0*/
+        //Perform L/R crossover
+        static void crossover(float &a, float &b, float crossover);
+
+    protected:
+        void setpanning(char Ppanning_);
+        void setlrcross(char Plrcross_);
+
+        const bool insertion;
+        //panning parameters
+        char  Ppanning;
+        float pangainL;
+        float pangainR;
+        char  Plrcross; // L/R mix
+        float lrcross;
 };
 
 #endif
-
diff --git a/src/Effects/EffectLFO.cpp b/src/Effects/EffectLFO.cpp
index 7bf6d85..f66b5fe 100644
--- a/src/Effects/EffectLFO.cpp
+++ b/src/Effects/EffectLFO.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  EffectLFO.C - Stereo LFO used by some effects
+  EffectLFO.cpp - Stereo LFO used by some effects
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -20,98 +20,92 @@
 
 */
 
-#include <cstdlib>
-#include <cmath>
-
 #include "EffectLFO.h"
+#include "../Misc/Util.h"
 
+#include <cmath>
 
-EffectLFO::EffectLFO()
+EffectLFO::EffectLFO(void)
+    :Pfreq(40),
+      Prandomness(0),
+      PLFOtype(0),
+      Pstereo(64),
+      xl(0.0f),
+      xr(0.0f),
+      ampl1(RND),
+      ampl2(RND),
+      ampr1(RND),
+      ampr2(RND),
+      lfornd(0.0f)
 {
-    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;
-};
+EffectLFO::~EffectLFO() {}
 
-EffectLFO::~EffectLFO()
+//Update the changed parameters
+void EffectLFO::updateparams(void)
 {
-};
+    float lfofreq = (powf(2.0f, Pfreq / 127.0f * 10.0f) - 1.0f) * 0.03f;
+    incx = fabsf(lfofreq) * synth->buffersize_f / synth->samplerate_f;
+    if(incx > 0.49999999f)
+        incx = 0.499999999f;  //Limit the Frequency
 
+    lfornd = Prandomness / 127.0f;
+    lfornd = (lfornd > 1.0f) ? 1.0f : lfornd;
 
-/*
- * Update the changed parameters
- */
-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
-
-    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;
+    xr      = fmodf(xl + (Pstereo - 64.0f) / 127.0f + 1.0f, 1.0f);
+}
 
-    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);
-};
-
-
-/*
- * Compute the shape of the LFO
- */
-REALTYPE EffectLFO::getlfoshape(REALTYPE x)
+//Compute the shape of the LFO
+float EffectLFO::getlfoshape(float x)
 {
-    REALTYPE out;
-    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;
-        break;
-        /**\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);
-};
-
-/*
- * LFO output
- */
-void EffectLFO::effectlfoout(REALTYPE *outl,REALTYPE *outr)
+    float out;
+    switch(lfotype) {
+        case 1: //EffectLFO_TRIANGLE
+            if((x > 0.0f) && (x < 0.25f))
+                out = 4.0f * x;
+            else
+            if((x > 0.25f) && (x < 0.75f))
+                out = 2.0f - 4.0f * x;
+            else
+                out = 4.0f * x - 4.0f;
+            break;
+        //when adding more, ensure ::updateparams() gets updated
+        default:
+            out = cosf(x * 2.0f * PI); //EffectLFO_SINE
+    }
+    return out;
+}
+
+//LFO output
+void EffectLFO::effectlfoout(float *outl, float *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;
-};
-
+    float out;
+
+    out = getlfoshape(xl);
+    if((lfotype == 0) || (lfotype == 1))
+        out *= (ampl1 + xl * (ampl2 - ampl1));
+    xl += incx;
+    if(xl > 1.0f) {
+        xl   -= 1.0f;
+        ampl1 = ampl2;
+        ampl2 = (1.0f - lfornd) + lfornd * RND;
+    }
+    *outl = (out + 1.0f) * 0.5f;
+
+    out = getlfoshape(xr);
+    if((lfotype == 0) || (lfotype == 1))
+        out *= (ampr1 + xr * (ampr2 - ampr1));
+    xr += incx;
+    if(xr > 1.0f) {
+        xr   -= 1.0f;
+        ampr1 = ampr2;
+        ampr2 = (1.0f - lfornd) + lfornd * RND;
+    }
+    *outr = (out + 1.0f) * 0.5f;
+}
diff --git a/src/Effects/EffectLFO.h b/src/Effects/EffectLFO.h
index 54a5951..e9571b8 100644
--- a/src/Effects/EffectLFO.h
+++ b/src/Effects/EffectLFO.h
@@ -23,31 +23,28 @@
 #ifndef EFFECT_LFO_H
 #define EFFECT_LFO_H
 
-#include "../globals.h"
 /**LFO for some of the Effect objects
  * \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(float *outl, float *outr);
+        void updateparams(void);
+        unsigned char Pfreq;
+        unsigned char Prandomness;
+        unsigned char PLFOtype;
+        unsigned char Pstereo; // 64 is centered
+    private:
+        float getlfoshape(float x);
+
+        float xl, xr;
+        float incx;
+        float ampl1, ampl2, ampr1, ampr2; //necessary for "randomness"
+        float lfointensity;
+        float lfornd;
+        char  lfotype;
 };
 
-
 #endif
-
diff --git a/src/Effects/EffectMgr.cpp b/src/Effects/EffectMgr.cpp
index 0811011..c2fce51 100644
--- a/src/Effects/EffectMgr.cpp
+++ b/src/Effects/EffectMgr.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  EffectMgr.C - Effect manager, an interface betwen the program and effects
+  EffectMgr.cpp - Effect manager, an interface betwen the program and effects
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -21,130 +21,125 @@
 */
 
 #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)
+#include "Effect.h"
+#include "Reverb.h"
+#include "Echo.h"
+#include "Chorus.h"
+#include "Distorsion.h"
+#include "EQ.h"
+#include "DynamicFilter.h"
+#include "../Misc/XMLwrapper.h"
+#include "../Params/FilterParams.h"
+
+#include <iostream>
+using namespace std;
+
+EffectMgr::EffectMgr(const bool insertion_, pthread_mutex_t *mutex_)
+    :insertion(insertion_),
+      efxoutl(new float[synth->buffersize]),
+      efxoutr(new float[synth->buffersize]),
+      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.*/
-//    efx=NULL;
-//    nefx=0;
-//    insertion=insertion_;
-//    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;
-    };
-//    filterpars=NULL;
-//    dryonly=false;
+    setpresettype("Peffect");
+    memset(efxoutl, 0, synth->bufferbytes);
+    memset(efxoutr, 0, synth->bufferbytes);
     defaults();
 }
 
 
 EffectMgr::~EffectMgr()
 {
-    if (efx!=NULL) delete efx;
-    delete []efxoutl;
-    delete []efxoutr;
+    delete efx;
+    delete [] efxoutl;
+    delete [] efxoutr;
 }
 
-void EffectMgr::defaults()
+void EffectMgr::defaults(void)
 {
     changeeffect(0);
     setdryonly(false);
 }
 
-/*
- * Change the effect
- */
-void EffectMgr::changeeffect(int nefx_)
+//Change the effect
+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*/
-    case 1:
-        efx=new Reverb(insertion,efxoutl,efxoutr);
-        break;
-    case 2:
-        efx=new Echo(insertion,efxoutl,efxoutr);
-        break;
-    case 3:
-        efx=new Chorus(insertion,efxoutl,efxoutr);
-        break;
-    case 4:
-        efx=new Phaser(insertion,efxoutl,efxoutr);
-        break;
-    case 5:
-        efx=new Alienwah(insertion,efxoutl,efxoutr);
-        break;
-    case 6:
-        efx=new Distorsion(insertion,efxoutl,efxoutr);
-        break;
-    case 7:
-        efx=new EQ(insertion,efxoutl,efxoutr);
-        break;
-    case 8:
-        efx=new DynamicFilter(insertion,efxoutl,efxoutr);
-        break;
+    if(nefx == _nefx)
+        return;
+    nefx = _nefx;
+    memset(efxoutl, 0, synth->bufferbytes);
+    memset(efxoutr, 0, synth->bufferbytes);
+    delete efx;
+    switch(nefx) {
+        case 1:
+            efx = new Reverb(insertion, efxoutl, efxoutr);
+            break;
+        case 2:
+            efx = new Echo(insertion, efxoutl, efxoutr);
+            break;
+        case 3:
+            efx = new Chorus(insertion, efxoutl, efxoutr);
+            break;
+        case 4:
+            efx = new Phaser(insertion, efxoutl, efxoutr);
+            break;
+        case 5:
+            efx = new Alienwah(insertion, efxoutl, efxoutr);
+            break;
+        case 6:
+            efx = new Distorsion(insertion, efxoutl, efxoutr);
+            break;
+        case 7:
+            efx = new EQ(insertion, efxoutl, efxoutr);
+            break;
+        case 8:
+            efx = new DynamicFilter(insertion, efxoutl, efxoutr);
+            break;
         //put more effect here
-    default:
-        efx=NULL;
-        break;//no effect (thru)
-    };
+        default:
+            efx = NULL;
+            break; //no effect (thru)
+    }
 
-    if (efx!=NULL) filterpars=efx->filterpars;
+    if(efx)
+        filterpars = efx->filterpars;
 }
 
-/*
- * Obtain the effect number
- */
-int EffectMgr::geteffect()
+//Obtain the effect number
+int EffectMgr::geteffect(void)
 {
-    return (nefx);
+    return nefx;
 }
 
-/*
- * Cleanup the current effect
- */
-void EffectMgr::cleanup()
+// Cleanup the current effect
+void EffectMgr::cleanup(void)
 {
-    if (efx!=NULL) efx->cleanup();
+    if(efx)
+        efx->cleanup();
 }
 
 
-/*
- * Get the preset of the current effect
- */
-
-unsigned char EffectMgr::getpreset()
+// Get the preset of the current effect
+unsigned char EffectMgr::getpreset(void)
 {
-    if (efx!=NULL) return(efx->Ppreset);
-    else return(0);
+    if(efx)
+        return efx->Ppreset;
+    else
+        return 0;
 }
 
-/*
- * Change the preset of the current effect
- */
+// Change the preset of the current effect
 void EffectMgr::changepreset_nolock(unsigned char npreset)
 {
-    if (efx!=NULL) efx->setpreset(npreset);
+    if(efx)
+        efx->setpreset(npreset);
 }
 
-/*
- * Change the preset of the current effect(with thread locking)
- */
+//Change the preset of the current effect(with thread locking)
 void EffectMgr::changepreset(unsigned char npreset)
 {
     pthread_mutex_lock(mutex);
@@ -153,180 +148,164 @@ void EffectMgr::changepreset(unsigned char npreset)
 }
 
 
-/*
- * Change a parameter of the current effect
- */
-void EffectMgr::seteffectpar_nolock(int npar,unsigned char value)
+//Change a parameter of the current effect
+void EffectMgr::seteffectpar_nolock(int npar, unsigned char value)
 {
-    if (efx==NULL) return;
-    efx->changepar(npar,value);
+    if(!efx)
+        return;
+    efx->changepar(npar, value);
 }
 
-/*
- * Change a parameter of the current effect (with thread locking)
- */
-void EffectMgr::seteffectpar(int npar,unsigned char value)
+// Change a parameter of the current effect (with thread locking)
+void EffectMgr::seteffectpar(int npar, unsigned char value)
 {
     pthread_mutex_lock(mutex);
-    seteffectpar_nolock(npar,value);
+    seteffectpar_nolock(npar, value);
     pthread_mutex_unlock(mutex);
 }
 
-/*
- * Get a parameter of the current effect
- */
+//Get a parameter of the current effect
 unsigned char EffectMgr::geteffectpar(int npar)
 {
-    if (efx==NULL) return(0);
-    return(efx->getpar(npar));
+    if(!efx)
+        return 0;
+    return efx->getpar(npar);
 }
 
-
-/*
- * Apply the effect
- */
-void EffectMgr::out(REALTYPE *smpsl,REALTYPE *smpsr)
+// Apply the effect
+void EffectMgr::out(float *smpsl, float *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) {
+        if(!insertion)
+            for(int i = 0; i < synth->buffersize; ++i) {
+                smpsl[i]   = 0.0f;
+                smpsr[i]   = 0.0f;
+                efxoutl[i] = 0.0f;
+                efxoutr[i] = 0.0f;
+            }
         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
-        /**\todo figure out why*/
-        for (i=0;i<SOUND_BUFFER_SIZE;i++) {
-            smpsl[i]=efxoutl[i];
-            smpsr[i]=efxoutr[i];
-        };
+    }
+    for(int i = 0; i < synth->buffersize; ++i) {
+        smpsl[i]  += denormalkillbuf[i];
+        smpsr[i]  += denormalkillbuf[i];
+        efxoutl[i] = 0.0f;
+        efxoutr[i] = 0.0f;
+    }
+    efx->out(smpsl, smpsr);
+
+    float volume = efx->volume;
+
+    if(nefx == 7) { //this is need only for the EQ effect
+        memcpy(smpsl, efxoutl, synth->bufferbytes);
+        memcpy(smpsr, efxoutr, synth->bufferbytes);
         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) {
+        float v1, v2;
+        if(volume < 0.5f) {
+            v1 = 1.0f;
+            v2 = volume * 2.0f;
+        }
+        else {
+            v1 = (1.0f - volume) * 2.0f;
+            v2 = 1.0f;
+        }
+        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(int i = 0; i < synth->buffersize; ++i) {
+                smpsl[i]   *= v1;
+                smpsr[i]   *= v1;
+                efxoutl[i] *= v2;
+                efxoutr[i] *= v2;
+            }
+        else // normal instrument/insertion effect
+            for(int i = 0; i < synth->buffersize; ++i) {
+                smpsl[i] = smpsl[i] * v1 + efxoutl[i] * v2;
+                smpsr[i] = smpsr[i] * v1 + efxoutr[i] * v2;
+            }
+    }
+    else // System effect
+        for(int i = 0; i < synth->buffersize; ++i) {
+            efxoutl[i] *= 2.0f * volume;
+            efxoutr[i] *= 2.0f * volume;
+            smpsl[i]    = efxoutl[i];
+            smpsr[i]    = efxoutr[i];
+        }
 }
 
-/*
- * Get the effect volume for the system effect
- */
-REALTYPE EffectMgr::sysefxgetvolume()
+
+// Get the effect volume for the system effect
+float EffectMgr::sysefxgetvolume(void)
 {
-    if (efx==NULL) return (1.0);
-    else return(efx->outvolume);
+    return (!efx) ? 1.0f : efx->outvolume;
 }
 
 
-/*
- * Get the EQ response
- */
-REALTYPE EffectMgr::getEQfreqresponse(REALTYPE freq)
+// Get the EQ response
+float EffectMgr::getEQfreqresponse(float freq)
 {
-    if (nefx==7) return(efx->getfreqresponse(freq));
-    else return(0.0);
+    return (nefx == 7) ? efx->getfreqresponse(freq) : 0.0f;
 }
 
 
 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 || !geteffect())
+        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) {
+        int par = geteffectpar(n);
+        if(par == 0)
+            continue;
+        xml->beginbranch("par_no", n);
+        xml->addpar("par", par);
         xml->endbranch();
-    };
-    if (filterpars!=NULL) {
+    }
+    if(filterpars) {
         xml->beginbranch("FILTER");
         filterpars->add2XML(xml);
         xml->endbranch();
-    };
+    }
     xml->endbranch();
 }
 
 void EffectMgr::getfromXML(XMLwrapper *xml)
 {
-    changeeffect(xml->getpar127("type",geteffect()));
-
-    if ((efx==NULL)||(geteffect()==0)) return;
+    changeeffect(xml->getpar127("type", geteffect()));
 
-    efx->Ppreset=xml->getpar127("preset",efx->Ppreset);
+    if(!efx || !geteffect())
+        return;
 
-    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;
+    efx->Ppreset = xml->getpar127("preset", efx->Ppreset);
 
-            int par=geteffectpar(n);
-            seteffectpar_nolock(n,xml->getpar127("par",par));
+    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));
             xml->exitbranch();
-        };
-        if (filterpars!=NULL) {
-            if (xml->enterbranch("FILTER")) {
+        }
+        if(filterpars)
+            if(xml->enterbranch("FILTER")) {
                 filterpars->getfromXML(xml);
                 xml->exitbranch();
-            };
-        };
+            }
         xml->exitbranch();
-    };
+    }
     cleanup();
 }
-
diff --git a/src/Effects/EffectMgr.h b/src/Effects/EffectMgr.h
index dd5d52c..256a8d8 100644
--- a/src/Effects/EffectMgr.h
+++ b/src/Effects/EffectMgr.h
@@ -24,12 +24,14 @@
 
 #include <pthread.h>
 
-#include "Effect.h"
-#include "Reverb.h"
-#include "Echo.h"
-#include "Chorus.h"
-#include "Phaser.h"
 #include "Alienwah.h"
+#include "Phaser.h"
+#include "../Params/Presets.h"
+
+class Effect;
+class FilterParams;
+class XMLwrapper;
+
 #include "Distorsion.h"
 #include "EQ.h"
 #include "DynamicFilter.h"
@@ -37,67 +39,48 @@
 #include "../Params/FilterParams.h"
 #include "../Params/Presets.h"
 
-
 /**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(const bool insertion_, pthread_mutex_t *mutex_);
+        ~EffectMgr();
+
+        void add2XML(XMLwrapper *xml);
+        void defaults(void);
+        void getfromXML(XMLwrapper *xml);
+
+        void out(float *smpsl, float *smpsr);
+
+        void setdryonly(bool value);
+
+        /**get the output(to speakers) volume of the systemeffect*/
+        float sysefxgetvolume(void);
+
+        void cleanup(void);
+
+        void changeeffect(int nefx_);
+        int geteffect(void);
+        void changepreset(unsigned char npreset);
+        void changepreset_nolock(unsigned char npreset);
+        unsigned char getpreset(void);
+        void seteffectpar(int npar, unsigned char value);
+        void seteffectpar_nolock(int npar, unsigned char value);
+        unsigned char geteffectpar(int npar);
+
+        const bool insertion;
+        float     *efxoutl, *efxoutr;
+
+        // used by UI
+        float getEQfreqresponse(float freq);
+
+        FilterParams *filterpars;
+
+    private:
+        int     nefx;
+        Effect *efx;
+        pthread_mutex_t *mutex;
+        bool dryonly;
 };
 
 #endif
-
diff --git a/src/Effects/Makefile b/src/Effects/Makefile
deleted file mode 100644
index 72f0246..0000000
--- a/src/Effects/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-include ../Makefile.inc
-
-objects=Alienwah.o Chorus.o Echo.o Effect.o \
-        EffectLFO.o EffectMgr.o Phaser.o Reverb.o \
-        Distorsion.o EQ.o DynamicFilter.o
-
-
-all: $(objects)
-
--include ../Make.deps
-
-.PHONY : clean
-clean: 
-	rm -f $(objects)
-	rm -f makeinclude.deps
-
diff --git a/src/Effects/Phaser.cpp b/src/Effects/Phaser.cpp
index f437fff..1dd26be 100644
--- a/src/Effects/Phaser.cpp
+++ b/src/Effects/Phaser.cpp
@@ -1,295 +1,462 @@
-/*
-  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()
-{
-    //if (oldl!=NULL) delete [] oldl;
-    //if (oldr!=NULL) delete [] oldr;
-};
-
-
-/*
- * 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;
-    //oldlgain=0.0;
-    //oldrgain=0.0;
-    oldgain=Stereo<REALTYPE>(0.0);
-    //for (int i=0;i<Pstages*2;i++) {
-    //oldl[i]=0.0;
-    //oldr[i]=0.0;
-    //};
-    old.left().clear();
-    old.right().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 (oldl!=NULL) delete [] oldl;
-    //if (oldr!=NULL) delete [] oldr;
-    if (Pstages>=MAX_PHASER_STAGES) this->Pstages=MAX_PHASER_STAGES-1;
-    else this->Pstages=Pstages;
-    //oldl=new REALTYPE[Pstages*2];
-    //oldr=new REALTYPE[Pstages*2];
-    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);
-    };
-
-};
-
+/*
+
+  Phaser.cpp  - Phasing and Approximate digital model of an analog JFET phaser.
+  Analog modeling implemented by Ryan Billing aka Transmogrifox.
+  ZynAddSubFX - a software synthesizer
+
+  Phaser.cpp - Phaser effect
+  Copyright (C) 2002-2005 Nasca Octavian Paul
+  Copyright (C) 2009-2010 Ryan Billing
+  Copyright (C) 2010-2010 Mark McCurry
+  Author: Nasca Octavian Paul
+          Ryan Billing
+          Mark McCurry
+
+  DSP analog modeling theory & practice largely influenced by various CCRMA publications, particularly works by Julius O. Smith.
+
+  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 <algorithm>
+#include "Phaser.h"
+
+using namespace std;
+
+#define PHASER_LFO_SHAPE 2
+#define ONE_  0.99999f        // To prevent LFO ever reaching 1.0f for filter stability purposes
+#define ZERO_ 0.00001f        // Same idea as above.
+
+Phaser::Phaser(const int &insertion_, float *efxoutl_, float *efxoutr_)
+    :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0), old(NULL), xn1(NULL),
+      yn1(NULL), diff(0.0f), oldgain(0.0f), fb(0.0f)
+{
+    analog_setup();
+    setpreset(Ppreset);
+    cleanup();
+}
+
+void Phaser::analog_setup()
+{
+    //model mismatch between JFET devices
+    offset[0]  = -0.2509303f;
+    offset[1]  = 0.9408924f;
+    offset[2]  = 0.998f;
+    offset[3]  = -0.3486182f;
+    offset[4]  = -0.2762545f;
+    offset[5]  = -0.5215785f;
+    offset[6]  = 0.2509303f;
+    offset[7]  = -0.9408924f;
+    offset[8]  = -0.998f;
+    offset[9]  = 0.3486182f;
+    offset[10] = 0.2762545f;
+    offset[11] = 0.5215785f;
+
+    barber = 0;  //Deactivate barber pole phasing by default
+
+    mis       = 1.0f;
+    Rmin      = 625.0f; // 2N5457 typical on resistance at Vgs = 0
+    Rmax      = 22000.0f; // Resistor parallel to FET
+    Rmx       = Rmin / Rmax;
+    Rconst    = 1.0f + Rmx; // Handle parallel resistor relationship
+    C         = 0.00000005f; // 50 nF
+    CFs       = 2.0f * synth->samplerate_f * C;
+    invperiod = 1.0f / synth->buffersize_f;
+}
+
+Phaser::~Phaser()
+{
+    if(xn1.l)
+        delete[] xn1.l;
+    if(yn1.l)
+        delete[] yn1.l;
+    if(xn1.r)
+        delete[] xn1.r;
+    if(yn1.r)
+        delete[] yn1.r;
+}
+
+/*
+ * Effect output
+ */
+void Phaser::out(const Stereo<float *> &input)
+{
+    if(Panalog)
+        AnalogPhase(input);
+    else
+        normalPhase(input);
+}
+
+void Phaser::AnalogPhase(const Stereo<float *> &input)
+{
+    Stereo<float> gain(0.0f), lfoVal(0.0f), mod(0.0f), g(0.0f), b(0.0f), hpf(
+        0.0f);
+
+    lfo.effectlfoout(&lfoVal.l, &lfoVal.r);
+    mod.l = lfoVal.l * width + (depth - 0.5f);
+    mod.r = lfoVal.r * width + (depth - 0.5f);
+
+    mod.l = limit(mod.l, ZERO_, ONE_);
+    mod.r = limit(mod.r, ZERO_, ONE_);
+
+    if(Phyper) {
+        //Triangle wave squared is approximately sin on bottom, tri on top
+        //Result is exponential sweep more akin to filter in synth with
+        //exponential generator circuitry.
+        mod.l *= mod.l;
+        mod.r *= mod.r;
+    }
+
+    //g.l,g.r is Vp - Vgs. Typical FET drain-source resistance follows constant/[1-sqrt(Vp - Vgs)]
+    mod.l = sqrtf(1.0f - mod.l);
+    mod.r = sqrtf(1.0f - mod.r);
+
+    diff.r = (mod.r - oldgain.r) * invperiod;
+    diff.l = (mod.l - oldgain.l) * invperiod;
+
+    g = oldgain;
+    oldgain = mod;
+
+    for(int i = 0; i < synth->buffersize; ++i) {
+        g.l += diff.l; // Linear interpolation between LFO samples
+        g.r += diff.r;
+
+        Stereo<float> xn(input.l[i] * pangainL, input.r[i] * pangainR);
+
+        if(barber) {
+            g.l = fmodf((g.l + 0.25f), ONE_);
+            g.r = fmodf((g.r + 0.25f), ONE_);
+        }
+
+        xn.l = applyPhase(xn.l, g.l, fb.l, hpf.l, yn1.l, xn1.l);
+        xn.r = applyPhase(xn.r, g.r, fb.r, hpf.r, yn1.r, xn1.r);
+
+
+        fb.l = xn.l * feedback;
+        fb.r = xn.r * feedback;
+        efxoutl[i] = xn.l;
+        efxoutr[i] = xn.r;
+    }
+
+    if(Poutsub) {
+        invSignal(efxoutl, synth->buffersize);
+        invSignal(efxoutr, synth->buffersize);
+    }
+}
+
+float Phaser::applyPhase(float x, float g, float fb,
+                         float &hpf, float *yn1, float *xn1)
+{
+    for(int j = 0; j < Pstages; ++j) { //Phasing routine
+        mis = 1.0f + offsetpct * offset[j];
+
+        //This is symmetrical.
+        //FET is not, so this deviates slightly, however sym dist. is
+        //better sounding than a real FET.
+        float d = (1.0f + 2.0f * (0.25f + g) * hpf * hpf * distortion) * mis;
+        Rconst = 1.0f + mis * Rmx;
+
+        // This is 1/R. R is being modulated to control filter fc.
+        float b    = (Rconst - g) / (d * Rmin);
+        float gain = (CFs - b) / (CFs + b);
+        yn1[j] = gain * (x + yn1[j]) - xn1[j];
+
+        //high pass filter:
+        //Distortion depends on the high-pass part of the AP stage.
+        hpf = yn1[j] + (1.0f - gain) * xn1[j];
+
+        xn1[j] = x;
+        x      = yn1[j];
+        if(j == 1)
+            x += fb;  //Insert feedback after first phase stage
+    }
+    return x;
+}
+void Phaser::normalPhase(const Stereo<float *> &input)
+{
+    Stereo<float> gain(0.0f), lfoVal(0.0f);
+
+    lfo.effectlfoout(&lfoVal.l, &lfoVal.r);
+    gain.l =
+        (expf(lfoVal.l
+              * PHASER_LFO_SHAPE) - 1) / (expf(PHASER_LFO_SHAPE) - 1.0f);
+    gain.r =
+        (expf(lfoVal.r
+              * PHASER_LFO_SHAPE) - 1) / (expf(PHASER_LFO_SHAPE) - 1.0f);
+
+    gain.l = 1.0f - phase * (1.0f - depth) - (1.0f - phase) * gain.l * depth;
+    gain.r = 1.0f - phase * (1.0f - depth) - (1.0f - phase) * gain.r * depth;
+
+    gain.l = limit(gain.l, ZERO_, ONE_);
+    gain.r = limit(gain.r, ZERO_, ONE_);
+
+    for(int i = 0; i < synth->buffersize; ++i) {
+        float x  = (float) i / synth->buffersize_f;
+        float x1 = 1.0f - x;
+        //TODO think about making panning an external feature
+        Stereo<float> xn(input.l[i] * pangainL + fb.l,
+                         input.r[i] * pangainR + fb.r);
+
+        Stereo<float> g(gain.l * x + oldgain.l * x1,
+                        gain.r * x + oldgain.r * x1);
+
+        xn.l = applyPhase(xn.l, g.l, old.l);
+        xn.r = applyPhase(xn.r, g.r, old.r);
+
+        //Left/Right crossing
+        crossover(xn.l, xn.r, lrcross);
+
+        fb.l = xn.l * feedback;
+        fb.r = xn.r * feedback;
+        efxoutl[i] = xn.l;
+        efxoutr[i] = xn.r;
+    }
+
+    oldgain = gain;
+
+    if(Poutsub) {
+        invSignal(efxoutl, synth->buffersize);
+        invSignal(efxoutr, synth->buffersize);
+    }
+}
+
+float Phaser::applyPhase(float x, float g, float *old)
+{
+    for(int j = 0; j < Pstages * 2; ++j) { //Phasing routine
+        float tmp = old[j];
+        old[j] = g * tmp + x;
+        x      = tmp - g * old[j];
+    }
+    return x;
+}
+
+/*
+ * Cleanup the effect
+ */
+void Phaser::cleanup()
+{
+    fb = oldgain = Stereo<float>(0.0f);
+    for(int i = 0; i < Pstages * 2; ++i) {
+        old.l[i] = 0.0f;
+        old.r[i] = 0.0f;
+    }
+    for(int i = 0; i < Pstages; ++i) {
+        xn1.l[i] = 0.0f;
+        yn1.l[i] = 0.0f;
+        xn1.r[i] = 0.0f;
+        yn1.r[i] = 0.0f;
+    }
+}
+
+/*
+ * Parameter control
+ */
+void Phaser::setwidth(unsigned char Pwidth)
+{
+    this->Pwidth = Pwidth;
+    width = ((float)Pwidth / 127.0f);
+}
+
+void Phaser::setfb(unsigned char Pfb)
+{
+    this->Pfb = Pfb;
+    feedback  = (float) (Pfb - 64) / 64.2f;
+}
+
+void Phaser::setvolume(unsigned char Pvolume)
+{
+    this->Pvolume = Pvolume;
+    outvolume     = Pvolume / 127.0f;
+    if(insertion == 0)
+        volume = 1.0f;
+    else
+        volume = outvolume;
+}
+
+void Phaser::setdistortion(unsigned char Pdistortion)
+{
+    this->Pdistortion = Pdistortion;
+    distortion = (float)Pdistortion / 127.0f;
+}
+
+void Phaser::setoffset(unsigned char Poffset)
+{
+    this->Poffset = Poffset;
+    offsetpct     = (float)Poffset / 127.0f;
+}
+
+void Phaser::setstages(unsigned char Pstages)
+{
+    if(xn1.l)
+        delete[] xn1.l;
+    if(yn1.l)
+        delete[] yn1.l;
+    if(xn1.r)
+        delete[] xn1.r;
+    if(yn1.r)
+        delete[] yn1.r;
+
+
+    this->Pstages = min(MAX_PHASER_STAGES, (int)Pstages);
+
+    old = Stereo<float *>(new float[Pstages * 2],
+                          new float[Pstages * 2]);
+
+    xn1 = Stereo<float *>(new float[Pstages],
+                          new float[Pstages]);
+
+    yn1 = Stereo<float *>(new float[Pstages],
+                          new float[Pstages]);
+
+    cleanup();
+}
+
+void Phaser::setphase(unsigned char Pphase)
+{
+    this->Pphase = Pphase;
+    phase = (Pphase / 127.0f);
+}
+
+void Phaser::setdepth(unsigned char Pdepth)
+{
+    this->Pdepth = Pdepth;
+    depth = (float)(Pdepth) / 127.0f;
+}
+
+
+void Phaser::setpreset(unsigned char npreset)
+{
+    const int     PRESET_SIZE = 15;
+    const int     NUM_PRESETS = 12;
+    unsigned char presets[NUM_PRESETS][PRESET_SIZE] = {
+        //Phaser
+        //0   1    2    3  4   5     6   7   8    9 10   11 12  13 14
+        {64, 64, 36,  0,   0, 64,  110, 64,  1,  0,   0, 20,
+         0, 0,
+         0 },
+        {64, 64, 35,  0,   0, 88,  40,  64,  3,  0,   0, 20, 0,  0,
+         0 },
+        {64, 64, 31,  0,   0, 66,  68,  107, 2,  0,   0, 20, 0,  0,
+         0 },
+        {39, 64, 22,  0,   0, 66,  67,  10,  5,  0,   1, 20, 0,  0,
+         0 },
+        {64, 64, 20,  0,   1, 110, 67,  78,  10, 0,   0, 20, 0,  0,
+         0 },
+        {64, 64, 53,  100, 0, 58,  37,  78,  3,  0,   0, 20, 0,  0,
+         0 },
+        //APhaser
+        //0   1    2   3   4   5     6   7   8    9 10   11 12  13 14
+        {64, 64, 14,  0,   1, 64,  64,  40,  4,  10,  0, 110,1,  20,
+         1 },
+        {64, 64, 14,  5,   1, 64,  70,  40,  6,  10,  0, 110,1,  20,
+         1 },
+        {64, 64, 9,   0,   0, 64,  60,  40,  8,  10,  0, 40, 0,  20,
+         1 },
+        {64, 64, 14,  10,  0, 64,  45,  80,  7,  10,  1, 110,1,  20,
+         1 },
+        {25, 64, 127, 10,  0, 64,  25,  16,  8,  100, 0, 25, 0,  20,
+         1 },
+        {64, 64, 1,   10,  1, 64,  70,  40,  12, 10,  0, 110,1,  20,
+         1 }
+    };
+    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(int npar, 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();
+            barber = (2 == value);
+            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);
+            setoffset(value);
+            break;
+        case 10:
+            Poutsub = min((int)value, 1);
+            break;
+        case 11:
+            setphase(value);
+            setwidth(value);
+            break;
+        case 12:
+            Phyper = min((int)value, 1);
+            break;
+        case 13:
+            setdistortion(value);
+            break;
+        case 14:
+            Panalog = value;
+            break;
+    }
+}
+
+unsigned char Phaser::getpar(int npar) const
+{
+    switch(npar) {
+        case 0:  return Pvolume;
+        case 1:  return Ppanning;
+        case 2:  return lfo.Pfreq;
+        case 3:  return lfo.Prandomness;
+        case 4:  return lfo.PLFOtype;
+        case 5:  return lfo.Pstereo;
+        case 6:  return Pdepth;
+        case 7:  return Pfb;
+        case 8:  return Pstages;
+        case 9:  return Plrcross;
+            return Poffset;      //same
+        case 10: return Poutsub;
+        case 11: return Pphase;
+            return Pwidth;      //same
+        case 12: return Phyper;
+        case 13: return Pdistortion;
+        case 14: return Panalog;
+        default: return 0;
+    }
+}
diff --git a/src/Effects/Phaser.h b/src/Effects/Phaser.h
index 700af3d..dd8a400 100644
--- a/src/Effects/Phaser.h
+++ b/src/Effects/Phaser.h
@@ -1,76 +1,98 @@
-/*
-  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
+  Copyright (C) 2009-2010 Ryan Billing
+  Copyright (C) 2010-2010 Mark McCurry
+  Author: Nasca Octavian Paul
+          Ryan Billing
+          Mark McCurry
+
+  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 "Effect.h"
+#include "EffectLFO.h"
+
+#define MAX_PHASER_STAGES 12
+
+class Phaser:public Effect
+{
+    public:
+        Phaser(const int &insertion_, float *efxoutl_, float *efxoutr_);
+        ~Phaser();
+        void out(const Stereo<float *> &input);
+        void setpreset(unsigned char npreset);
+        void changepar(int npar, unsigned char value);
+        unsigned char getpar(int npar) const;
+        void cleanup();
+
+    private:
+        //Phaser parameters
+        EffectLFO     lfo;          //Phaser modulator
+        unsigned char Pvolume;      //Used to set wet/dry mix
+        unsigned char Pdistortion;  //Model distortion added by FET element
+        unsigned char Pdepth;       //Depth of phaser sweep
+        unsigned char Pwidth;       //Phaser width (LFO amplitude)
+        unsigned char Pfb;          //feedback
+        unsigned char Poffset;      //Model mismatch between variable resistors
+        unsigned char Pstages;      //Number of first-order All-Pass stages
+        unsigned char Poutsub;      //if I wish to subtract the output instead of adding
+        unsigned char Pphase;
+        unsigned char Phyper;       //lfo^2 -- converts tri into hyper-sine
+        unsigned char Panalog;
+
+        //Control parameters
+        void setvolume(unsigned char Pvolume);
+        void setdepth(unsigned char Pdepth);
+        void setfb(unsigned char Pfb);
+        void setdistortion(unsigned char Pdistortion);
+        void setwidth(unsigned char Pwidth);
+        void setoffset(unsigned char Poffset);
+        void setstages(unsigned char Pstages);
+        void setphase(unsigned char Pphase);
+
+        //Internal Variables
+        bool  barber; //Barber pole phasing flag
+        float distortion, width, offsetpct;
+        float feedback, depth, phase;
+        Stereo<float *> old, xn1, yn1;
+        Stereo<float>   diff, oldgain, fb;
+        float invperiod;
+        float offset[12];
+
+        float mis;
+        float Rmin;     // 3N5457 typical on resistance at Vgs = 0
+        float Rmax;     // Resistor parallel to FET
+        float Rmx;      // Rmin/Rmax to avoid division in loop
+        float Rconst;   // Handle parallel resistor relationship
+        float C;        // Capacitor
+        float CFs;      // A constant derived from capacitor and resistor relationships
+
+        void analog_setup();
+        void AnalogPhase(const Stereo<float *> &input);
+        //analog case
+        float applyPhase(float x, float g, float fb,
+                         float &hpf, float *yn1, float *xn1);
+
+        void normalPhase(const Stereo<float *> &input);
+        float applyPhase(float x, float g, float *old);
+};
+
+#endif
diff --git a/src/Effects/Reverb.cpp b/src/Effects/Reverb.cpp
index 9434397..2d7884e 100644
--- a/src/Effects/Reverb.cpp
+++ b/src/Effects/Reverb.cpp
@@ -1,471 +1,498 @@
-/*
-  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];
-
-    //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;
-    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;
-};
-
-/*
- * 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;
-        //Initial delay r
-        if (idelay!=NULL) {
-            REALTYPE tmp=inputbuf[i]+idelay[idelayk]*idelayfb;
-            inputbuf[i]=idelay[idelayk];
-            idelay[idelayk]=tmp;
-            idelayk++;
-            if (idelayk>=idelaylen) idelayk=0;
-        };
-    };
-
-    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=2;
-    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}
-    };
-    int aptunings[NUM_TYPES][REV_APS]={
-        //this is unused (for random)
-        {0,0,0,0},
-        //Freeverb by Jezar at Dreampoint
-        {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();
-};
-
-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::setpreset(unsigned char npreset)
-{
-    const int PRESET_SIZE=12;
-    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},
-        //Cathedral2
-        {80,64,69,35,0,0,0,127,0,71,0,64},
-        //Cathedral3
-        {80,64,69,24,0,0,0,127,75,78,1,85},
-        //Hall1
-        {90,64,51,10,0,0,0,127,21,78,1,64},
-        //Hall2
-        {90,64,53,20,0,0,0,127,75,71,1,64},
-        //Room1
-        {100,64,33,0,0,0,0,127,0,106,0,30},
-        //Room2
-        {100,64,21,26,0,0,0,62,0,77,1,45},
-        //Basement
-        {110,64,14,0,0,0,0,127,5,71,0,25},
-        //Tunnel
-        {85,80,84,20,42,0,0,51,0,78,1,105},
-        //Echoed1
-        {95,64,26,60,71,0,0,114,0,64,1,64},
-        //Echoed2
-        {90,64,40,88,71,0,0,114,0,88,1,64},
-        //VeryLong1
-        {90,64,93,15,0,0,0,114,0,77,0,95},
-        //VeryLong2
-        {90,64,111,30,0,0,0,114,90,74,1,80}
-    };
-
-    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;
-    };
-};
-
-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;
-    };
-    return(0);//in case of bogus "parameter"
-};
-
+/*
+  ZynAddSubFX - a software synthesizer
+
+  Reverb.cpp - 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 "Reverb.h"
+#include "../Misc/Util.h"
+#include "../DSP/AnalogFilter.h"
+#include "../DSP/Unison.h"
+#include <cmath>
+
+//todo: EarlyReflections, Prdelay, Perbalance
+
+Reverb::Reverb(bool insertion_, float *efxoutl_, float *efxoutr_)
+    :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0),
+      // defaults
+      Pvolume(48),
+      Ptime(64),
+      Pidelay(40),
+      Pidelayfb(0),
+      Prdelay(0),
+      Perbalance(64),
+      Plpf(127),
+      Phpf(0),
+      Plohidamp(80),
+      Ptype(1),
+      Proomsize(64),
+      Pbandwidth(30),
+      roomsize(1.0f),
+      rs(1.0f),
+      bandwidth(NULL),
+      idelay(NULL),
+      lpf(NULL),
+      hpf(NULL) // no filter
+{
+    for(int i = 0; i < REV_COMBS * 2; ++i) {
+        comblen[i] = 800 + (int)(RND * 1400.0f);
+        combk[i]   = 0;
+        lpcomb[i]  = 0;
+        combfb[i]  = -0.97f;
+        comb[i]    = NULL;
+    }
+
+    for(int i = 0; i < REV_APS * 2; ++i) {
+        aplen[i] = 500 + (int)(RND * 500.0f);
+        apk[i]   = 0;
+        ap[i]    = NULL;
+    }
+    setpreset(Ppreset);
+    cleanup(); //do not call this before the comb initialisation
+}
+
+
+Reverb::~Reverb()
+{
+    delete [] idelay;
+    delete hpf;
+    delete lpf;
+
+    for(int i = 0; i < REV_APS * 2; ++i)
+        delete [] ap[i];
+    for(int i = 0; i < REV_COMBS * 2; ++i)
+        delete [] comb[i];
+
+    if(bandwidth)
+        delete bandwidth;
+}
+
+//Cleanup the effect
+void Reverb::cleanup(void)
+{
+    int i, j;
+    for(i = 0; i < REV_COMBS * 2; ++i) {
+        lpcomb[i] = 0.0f;
+        for(j = 0; j < comblen[i]; ++j)
+            comb[i][j] = 0.0f;
+    }
+
+    for(i = 0; i < REV_APS * 2; ++i)
+        for(j = 0; j < aplen[i]; ++j)
+            ap[i][j] = 0.0f;
+
+    if(idelay)
+        for(i = 0; i < idelaylen; ++i)
+            idelay[i] = 0.0f;
+    if(hpf)
+        hpf->cleanup();
+    if(lpf)
+        lpf->cleanup();
+}
+
+//Process one channel; 0=left, 1=right
+void Reverb::processmono(int ch, float *output, float *inputbuf)
+{
+    //todo: implement the high part from lohidamp
+
+    for(int j = REV_COMBS * ch; j < REV_COMBS * (ch + 1); ++j) {
+        int &ck = combk[j];
+        const int comblength = comblen[j];
+        float    &lpcombj    = lpcomb[j];
+
+        for(int i = 0; i < synth->buffersize; ++i) {
+            float fbout = comb[j][ck] * combfb[j];
+            fbout   = fbout * (1.0f - lohifb) + lpcombj * lohifb;
+            lpcombj = fbout;
+
+            comb[j][ck] = inputbuf[i] + fbout;
+            output[i]  += fbout;
+
+            if((++ck) >= comblength)
+                ck = 0;
+        }
+    }
+
+    for(int j = REV_APS * ch; j < REV_APS * (1 + ch); ++j) {
+        int &ak = apk[j];
+        const int aplength = aplen[j];
+        for(int i = 0; i < synth->buffersize; ++i) {
+            float tmp = ap[j][ak];
+            ap[j][ak] = 0.7f * tmp + output[i];
+            output[i] = tmp - 0.7f * ap[j][ak];
+            if((++ak) >= aplength)
+                ak = 0;
+        }
+    }
+}
+
+//Effect output
+void Reverb::out(const Stereo<float *> &smp)
+{
+    if(!Pvolume && insertion)
+        return;
+
+    float *inputbuf = getTmpBuffer();
+    for(int i = 0; i < synth->buffersize; ++i)
+        inputbuf[i] = (smp.l[i] + smp.r[i]) / 2.0f;
+
+    if(idelay)
+        for(int i = 0; i < synth->buffersize; ++i) {
+            //Initial delay r
+            float tmp = inputbuf[i] + idelay[idelayk] * idelayfb;
+            inputbuf[i]     = idelay[idelayk];
+            idelay[idelayk] = tmp;
+            idelayk++;
+            if(idelayk >= idelaylen)
+                idelayk = 0;
+        }
+
+    if(bandwidth)
+        bandwidth->process(synth->buffersize, inputbuf);
+
+    if(lpf)
+        lpf->filterout(inputbuf);
+    if(hpf)
+        hpf->filterout(inputbuf);
+
+    processmono(0, efxoutl, inputbuf); //left
+    processmono(1, efxoutr, inputbuf); //right
+    returnTmpBuffer(inputbuf);
+
+    float lvol = rs / REV_COMBS * pangainL;
+    float rvol = rs / REV_COMBS * pangainR;
+    if(insertion != 0) {
+        lvol *= 2.0f;
+        rvol *= 2.0f;
+    }
+    for(int i = 0; i < synth->buffersize; ++i) {
+        efxoutl[i] *= lvol;
+        efxoutr[i] *= rvol;
+    }
+}
+
+
+//Parameter control
+void Reverb::setvolume(unsigned char _Pvolume)
+{
+    Pvolume = _Pvolume;
+    if(!insertion) {
+        outvolume = powf(0.01f, (1.0f - Pvolume / 127.0f)) * 4.0f;
+        volume    = 1.0f;
+    }
+    else {
+        volume = outvolume = Pvolume / 127.0f;
+        if(Pvolume == 0)
+            cleanup();
+    }
+}
+
+void Reverb::settime(unsigned char _Ptime)
+{
+    Ptime = _Ptime;
+    float t = powf(60.0f, Ptime / 127.0f) - 0.97f;
+
+    for(int i = 0; i < REV_COMBS * 2; ++i)
+        combfb[i] =
+            -expf((float)comblen[i] / synth->samplerate_f * logf(0.001f) / t);
+    //the feedback is negative because it removes the DC
+}
+
+void Reverb::setlohidamp(unsigned char _Plohidamp)
+{
+    Plohidamp = (_Plohidamp < 64) ? 64 : _Plohidamp;
+    //remove this when the high part from lohidamp is added
+    if(Plohidamp == 64) {
+        lohidamptype = 0;
+        lohifb = 0.0f;
+    }
+    else {
+        if(Plohidamp < 64)
+            lohidamptype = 1;
+        if(Plohidamp > 64)
+            lohidamptype = 2;
+        float x = fabsf((float)(Plohidamp - 64) / 64.1f);
+        lohifb = x * x;
+    }
+}
+
+void Reverb::setidelay(unsigned char _Pidelay)
+{
+    Pidelay = _Pidelay;
+    float delay = powf(50.0f * Pidelay / 127.0f, 2.0f) - 1.0f;
+
+    if(idelay)
+        delete [] idelay;
+    idelay = NULL;
+
+    idelaylen = (int) (synth->samplerate_f * delay / 1000);
+    if(idelaylen > 1) {
+        idelayk = 0;
+        idelay  = new float[idelaylen];
+        memset(idelay, 0, idelaylen * sizeof(float));
+    }
+}
+
+void Reverb::setidelayfb(unsigned char _Pidelayfb)
+{
+    Pidelayfb = _Pidelayfb;
+    idelayfb  = Pidelayfb / 128.0f;
+}
+
+void Reverb::sethpf(unsigned char _Phpf)
+{
+    Phpf = _Phpf;
+    if(Phpf == 0) { //No HighPass
+        if(hpf)
+            delete hpf;
+        hpf = NULL;
+    }
+    else {
+        float fr = expf(powf(Phpf / 127.0f, 0.5f) * logf(10000.0f)) + 20.0f;
+        if(hpf == NULL)
+            hpf = new AnalogFilter(3, fr, 1, 0);
+        else
+            hpf->setfreq(fr);
+    }
+}
+
+void Reverb::setlpf(unsigned char _Plpf)
+{
+    Plpf = _Plpf;
+    if(Plpf == 127) { //No LowPass
+        if(lpf)
+            delete lpf;
+        lpf = NULL;
+    }
+    else {
+        float fr = expf(powf(Plpf / 127.0f, 0.5f) * logf(25000.0f)) + 40.0f;
+        if(!lpf)
+            lpf = new AnalogFilter(2, fr, 1, 0);
+        else
+            lpf->setfreq(fr);
+    }
+}
+
+void Reverb::settype(unsigned char _Ptype)
+{
+    Ptype = _Ptype;
+    const int NUM_TYPES = 3;
+    const 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   },
+        //duplicate of Freeverb by Jezar at Dreampoint
+        {1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617   }
+    };
+
+    const int aptunings[NUM_TYPES][REV_APS] = {
+        //this is unused (for random)
+        {0,   0,   0,   0    },
+        //Freeverb by Jezar at Dreampoint
+        {225, 341, 441, 556  },
+        //duplicate of Freeverb by Jezar at Dreampoint
+        {225, 341, 441, 556  }
+    };
+
+    if(Ptype >= NUM_TYPES)
+        Ptype = NUM_TYPES - 1;
+
+    // adjust the combs according to the samplerate
+    float samplerate_adjust = synth->samplerate_f / 44100.0f;
+    float tmp;
+    for(int i = 0; i < REV_COMBS * 2; ++i) {
+        if(Ptype == 0)
+            tmp = 800.0f + (int)(RND * 1400.0f);
+        else
+            tmp = combtunings[Ptype][i % REV_COMBS];
+        tmp *= roomsize;
+        if(i > REV_COMBS)
+            tmp += 23.0f;
+        tmp *= samplerate_adjust; //adjust the combs according to the samplerate
+        if(tmp < 10.0f)
+            tmp = 10.0f;
+        comblen[i] = (int) tmp;
+        combk[i]   = 0;
+        lpcomb[i]  = 0;
+        if(comb[i])
+            delete [] comb[i];
+        comb[i] = new float[comblen[i]];
+    }
+
+    for(int i = 0; i < REV_APS * 2; ++i) {
+        if(Ptype == 0)
+            tmp = 500 + (int)(RND * 500.0f);
+        else
+            tmp = aptunings[Ptype][i % REV_APS];
+        tmp *= roomsize;
+        if(i > REV_APS)
+            tmp += 23.0f;
+        tmp *= samplerate_adjust; //adjust the combs according to the samplerate
+        if(tmp < 10)
+            tmp = 10;
+        aplen[i] = (int) tmp;
+        apk[i]   = 0;
+        if(ap[i])
+            delete [] ap[i];
+        ap[i] = new float[aplen[i]];
+    }
+    delete bandwidth;
+    bandwidth = NULL;
+    if(Ptype == 2) { //bandwidth
+        //TODO the size of the unison buffer may be too small, though this has
+        //not been verified yet.
+        //As this cannot be resized in a RT context, a good upper bound should
+        //be found
+        bandwidth = new Unison(synth->buffersize / 4 + 1, 2.0f);
+        bandwidth->setSize(50);
+        bandwidth->setBaseFrequency(1.0f);
+    }
+    settime(Ptime);
+    cleanup();
+}
+
+void Reverb::setroomsize(unsigned char _Proomsize)
+{
+    Proomsize = _Proomsize;
+    if(!Proomsize)
+        this->Proomsize = 64;  //this is because the older versions consider roomsize=0
+    roomsize = (this->Proomsize - 64.0f) / 64.0f;
+    if(roomsize > 0.0f)
+        roomsize *= 2.0f;
+    roomsize = powf(10.0f, roomsize);
+    rs = sqrtf(roomsize);
+    settype(Ptype);
+}
+
+void Reverb::setbandwidth(unsigned char _Pbandwidth)
+{
+    Pbandwidth = _Pbandwidth;
+    float v = Pbandwidth / 127.0f;
+    if(bandwidth)
+        bandwidth->setBandwidth(powf(v, 2.0f) * 200.0f);
+}
+
+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)
+        changepar(0, presets[npreset][0] / 2);  //lower the volume if reverb is insertion effect
+    Ppreset = npreset;
+}
+
+
+void Reverb::changepar(int npar, unsigned char value)
+{
+    switch(npar) {
+        case 0:
+            setvolume(value);
+            break;
+        case 1:
+            setpanning(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(int npar) const
+{
+    switch(npar) {
+        case 0:  return Pvolume;
+        case 1:  return Ppanning;
+        case 2:  return Ptime;
+        case 3:  return Pidelay;
+        case 4:  return Pidelayfb;
+//      case 5:  return Prdelay;
+//      case 6:  return Perbalance;
+        case 7:  return Plpf;
+        case 8:  return Phpf;
+        case 9:  return Plohidamp;
+        case 10: return Ptype;
+        case 11: return Proomsize;
+        case 12: return Pbandwidth;
+        default: return 0;
+    }
+}
diff --git a/src/Effects/Reverb.h b/src/Effects/Reverb.h
index ddf5900..f84d806 100644
--- a/src/Effects/Reverb.h
+++ b/src/Effects/Reverb.h
@@ -1,127 +1,97 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  Reverb.h - 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
-
-*/
-
-#ifndef REVERB_H
-#define REVERB_H
-
-
-#include "../globals.h"
-#include "../DSP/AnalogFilter.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;
-
-    //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);
-
-    REALTYPE pan,erbalance;
-    //Parametrii 2
-    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];
-
-    //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 "Effect.h"
+
+#define REV_COMBS 8
+#define REV_APS 4
+
+/**Creates Reverberation Effects*/
+class Reverb:public Effect
+{
+    public:
+        Reverb(bool insertion_, float *efxoutl_, float *efxoutr_);
+        ~Reverb();
+        void out(const Stereo<float *> &smp);
+        void cleanup(void);
+
+        void setpreset(unsigned char npreset);
+        void changepar(int npar, unsigned char value);
+        unsigned char getpar(int npar) const;
+
+    private:
+        //Parametrii
+        unsigned char Pvolume;
+        unsigned char Ptime;        //duration
+        unsigned char Pidelay;      //initial delay
+        unsigned char Pidelayfb;    //initial feedback
+        unsigned char Prdelay;      //delay between ER/Reverbs
+        unsigned char Perbalance;   //EarlyReflections/Reverb Balance
+        unsigned char Plpf;
+        unsigned char Phpf;
+        unsigned char Plohidamp;    //Low/HighFrequency Damping
+        unsigned char Ptype;        //reverb type
+        unsigned char Proomsize;    //room size
+        unsigned char Pbandwidth;   //bandwidth
+
+        //parameter control
+        void setvolume(unsigned char _Pvolume);
+        void settime(unsigned char _Ptime);
+        void setlohidamp(unsigned char _Plohidamp);
+        void setidelay(unsigned char _Pidelay);
+        void setidelayfb(unsigned char _Pidelayfb);
+        void sethpf(unsigned char _Phpf);
+        void setlpf(unsigned char _Plpf);
+        void settype(unsigned char _Ptype);
+        void setroomsize(unsigned char _Proomsize);
+        void setbandwidth(unsigned char _Pbandwidth);
+        void processmono(int ch, float *output, float *inputbuf);
+
+        float erbalance;
+
+        //Parameters
+        int   lohidamptype;   //0=disable, 1=highdamp (lowpass), 2=lowdamp (highpass)
+        int   idelaylen, rdelaylen;
+        int   idelayk;
+        float lohifb;
+        float idelayfb;
+        float roomsize;
+        float rs;   //rs is used to "normalise" the volume according to the roomsize
+        int   comblen[REV_COMBS * 2];
+        int   aplen[REV_APS * 2];
+        class Unison * bandwidth;
+
+        //Internal Variables
+        float *comb[REV_COMBS * 2];
+        int    combk[REV_COMBS * 2];
+        float  combfb[REV_COMBS * 2]; //feedback-ul fiecarui filtru "comb"
+        float  lpcomb[REV_COMBS * 2]; //pentru Filtrul LowPass
+        float *ap[REV_APS * 2];
+        int    apk[REV_APS * 2];
+        float *idelay;
+        class AnalogFilter * lpf, *hpf; //filters
+};
+
+#endif
diff --git a/src/Input/ALSAMidiIn.cpp b/src/Input/ALSAMidiIn.cpp
deleted file mode 100644
index 5e27081..0000000
--- a/src/Input/ALSAMidiIn.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  ALSAMidiIn.C - Midi input for ALSA (this creates an ALSA virtual port)
-  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 "ALSAMidiIn.h"
-
-ALSAMidiIn::ALSAMidiIn()
-{
-    int alsaport;
-    inputok=false;
-
-    midi_handle=NULL;
-
-    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
-
-    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;
-};
-
-ALSAMidiIn::~ALSAMidiIn()
-{
-    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)
-{
-    snd_seq_event_t *midievent=NULL;
-    cmdtype=MidiNull;
-
-    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);
-
-    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;
-        break;
-    case SND_SEQ_EVENT_NOTEOFF:
-        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;
-        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;
-        //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;
-        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);
-        snd_seq_client_info_free(seq_info);
-        return id;
-    }
-    return -1;
-}
-
diff --git a/src/Input/ALSAMidiIn.h b/src/Input/ALSAMidiIn.h
deleted file mode 100644
index e467101..0000000
--- a/src/Input/ALSAMidiIn.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  ALSAMidiIn.h - Midi input for ALSA (this creates an ALSA virtual port)
-  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 ALSA_MIDI_IN_H
-#define ALSA_MIDI_IN_H
-
-#include <alsa/asoundlib.h>
-#include "MidiIn.h"
-
-
-/**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;
-};
-
-#endif
-
diff --git a/src/Input/Makefile b/src/Input/Makefile
deleted file mode 100644
index f461fc7..0000000
--- a/src/Input/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-include ../Makefile.inc
-
-objects=NULLMidiIn.o MidiIn.o
-
-ifeq ($(MIDIIN),ALSA) 
-objects+=ALSAMidiIn.o 
-endif
-
-ifeq ($(MIDIIN),OSS) 
-objects+=OSSMidiIn.o 
-endif
-
-ifeq ($(MIDIIN),WIN) 
-objects+=WINMidiIn.o 
-endif
-
-
-all: $(objects)
-
--include ../Make.deps
-
-.PHONY : clean
-clean: 
-	rm -f $(objects)
-	rm -f makeinclude.deps
-
diff --git a/src/Input/MidiIn.cpp b/src/Input/MidiIn.cpp
deleted file mode 100644
index 2355b3a..0000000
--- a/src/Input/MidiIn.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  MidiIn.C - This class is inherited by all the Midi input classes
-  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 "../globals.h"
-#include "MidiIn.h"
-
-int MidiIn::getcontroller(unsigned char b)
-{
-    /**\todo there might be a better way to do this*/
-    int ctl=C_NULL;
-    switch (b) {
-    case 1:
-        ctl=C_modwheel;//Modulation Wheel
-        break;
-    case 7:
-        ctl=C_volume;//Volume
-        break;
-    case 10:
-        ctl=C_panning;//Panning
-        break;
-    case 11:
-        ctl=C_expression;//Expression
-        break;
-    case 64:
-        ctl=C_sustain;//Sustain pedal
-        break;
-    case 65:
-        ctl=C_portamento;//Portamento
-        break;
-    case 71:
-        ctl=C_filterq;//Filter Q (Sound Timbre)
-        break;
-    case 74:
-        ctl=C_filtercutoff;//Filter Cutoff (Brightness)
-        break;
-    case 75:
-        ctl=C_bandwidth;//BandWidth
-        break;
-    case 76:
-        ctl=C_fmamp;//FM amplitude
-        break;
-    case 77:
-        ctl=C_resonance_center;//Resonance Center Frequency
-        break;
-    case 78:
-        ctl=C_resonance_bandwidth;//Resonance Bandwith
-        break;
-    case 120:
-        ctl=C_allsoundsoff;//All Sounds OFF
-        break;
-    case 121:
-        ctl=C_resetallcontrollers;//Reset All Controllers
-        break;
-    case 123:
-        ctl=C_allnotesoff;//All Notes OFF
-        break;
-        //RPN and NRPN
-    case 0x06:
-        ctl=C_dataentryhi;//Data Entry (Coarse)
-        break;
-    case 0x26:
-        ctl=C_dataentrylo;//Data Entry (Fine)
-        break;
-    case 99:
-        ctl=C_nrpnhi;//NRPN (Coarse)
-        break;
-    case 98:
-        ctl=C_nrpnlo;//NRPN (Fine)
-        break;
-    default:
-        ctl=C_NULL;//unknown controller
-        //fprintf(stderr,"Controller=%d , par=%d\n",midievent->data.control.param,cmdparams[1]);
-        break;
-    };
-    return(ctl);
-};
diff --git a/src/Input/MidiIn.h b/src/Input/MidiIn.h
deleted file mode 100644
index f02d10e..0000000
--- a/src/Input/MidiIn.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  MidiIn.h - This class is inherited by all the Midi input classes
-  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 MIDI_IN_H
-#define MIDI_IN_H
-
-#include "../globals.h"
-
-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*/
-};
-
-#endif
-
diff --git a/src/Input/NULLMidiIn.cpp b/src/Input/NULLMidiIn.cpp
deleted file mode 100644
index 6575f23..0000000
--- a/src/Input/NULLMidiIn.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  NULLMidiIn.C - a dummy Midi port
-  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 "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,unsigned char *cmdparams)
-{
-    cmdtype=MidiNull;
-};
-
diff --git a/src/Input/NULLMidiIn.h b/src/Input/NULLMidiIn.h
deleted file mode 100644
index f7c67a1..0000000
--- a/src/Input/NULLMidiIn.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  NULLMidiIn.h - a dummy Midi port
-  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 NULL_MIDI_IN_H
-#define NULL_MIDI_IN_H
-
-#include "MidiIn.h"
-
-
-/**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,unsigned char *cmdparams);
-
-private:
-};
-
-#endif
-
diff --git a/src/Input/OSSMidiIn.cpp b/src/Input/OSSMidiIn.cpp
deleted file mode 100644
index 440775a..0000000
--- a/src/Input/OSSMidiIn.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  OSSMidiIn.C - Midi input for Open Sound System
-  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 <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/soundcard.h>
-
-#include "OSSMidiIn.h"
-#include "../Misc/Util.h"
-
-OSSMidiIn::OSSMidiIn()
-{
-    inputok=false;
-    midi_handle=open(config.cfg.LinuxOSSSeqInDev,O_RDONLY,0);
-    if (midi_handle!=-1) inputok=true;
-
-    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);
-    }
-    return(tmp[1]);
-};
-
-unsigned char OSSMidiIn::getmidibyte()
-{
-    unsigned char b;
-    do {
-        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)
-{
-    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;
-    }
-
-    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>=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>=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
deleted file mode 100644
index 7626950..0000000
--- a/src/Input/OSSMidiIn.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  OSSMidiIn.h - Midi input for Open Sound System
-  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 OSS_MIDI_IN_H
-#define OSS_MIDI_IN_H
-
-#include "MidiIn.h"
-
-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
-
-};
-
-
-#endif
-
diff --git a/src/Input/WINMidiIn.cpp b/src/Input/WINMidiIn.cpp
deleted file mode 100644
index 155aa73..0000000
--- a/src/Input/WINMidiIn.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  WINMidiIn.C - Midi input for Windows
-  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 <stdlib.h>
-#include <stdio.h>
-#include <windows.h>
-#include <mmsystem.h>
-#include <pthread.h>
-
-#include "WINMidiIn.h"
-#include "MidiIn.h"
-#include "../Misc/Util.h"
-
-Master *winmaster;
-HMIDIIN winmidiinhandle;
-MidiIn midictl;//used to convert the controllers to ZynAddSubFX controllers
-
-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;
-        //printf("%x %x %x\n",cmd,par1,par2);fflush(stdout);
-        int cmdchan=cmd&0x0f;
-        int cmdtype=(cmd>>4)&0x0f;
-
-        int tmp=0;
-        pthread_mutex_lock(&winmaster->mutex);
-        switch (cmdtype) {
-        case(0x8)://noteon
-            winmaster->NoteOff(cmdchan,par1);
-            break;
-        case(0x9)://noteoff
-            winmaster->NoteOn(cmdchan,par1,par2&0xff);
-            break;
-        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);
-            break;
-        default:
-            break;
-        };
-        pthread_mutex_unlock(&winmaster->mutex);
-
-    };
-};
-
-void InitWinMidi(Master *master_)
-{
-    winmaster=master_;
-
-    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/Input/WINMidiIn.h b/src/Input/WINMidiIn.h
deleted file mode 100644
index db9fc79..0000000
--- a/src/Input/WINMidiIn.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  WINMidiIn.h - Midi input for Windows
-  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 WIN_MIDI_IN_H
-#define WIN_MIDI_IN_H
-
-
-#include "../Misc/Master.h"
-
-void InitWinMidi(Master *master_);
-void StopWinMidi();
-
-
-#endif
-
diff --git a/src/Makefile b/src/Makefile
deleted file mode 100644
index 598e0f7..0000000
--- a/src/Makefile
+++ /dev/null
@@ -1,134 +0,0 @@
-include Makefile.inc
-
-ifneq ($(MAKECMDGOALS),debug)
-  CXXFLAGS= -O6 -Wall -g 
-else 
-  CXXFLAGS= -O0 -Wall -Wpointer-arith 
-endif
-
-CXXFLAGS += -DOS_$(OS_PORT) -D$(MIDIIN)MIDIIN -DFFTW_VERSION_$(FFTW_VERSION) -DASM_F2I_$(ASM_F2I) -ggdb
-
-ifeq ($(DISABLE_GUI),YES)
-    CXXFLAGS += -DDISABLE_GUI
-else
-    CXXFLAGS += -DFLTK_GUI `fltk-config --cflags` 
-endif
-
-ifeq ($(AUDIOOUT),OSS_AND_JACK)
-    CXXFLAGS += -DOSSAUDIOOUT -DJACKAUDIOOUT 
-else
-    CXXFLAGS += -D$(AUDIOOUT)AUDIOOUT 
-endif
-
-export CXXFLAGS
-
-LIBS= -lm  -lmxml -lz
-ifneq ($(DISABLE_GUI),YES)
-    LIBS+=`fltk-config --ldflags` 
-endif
-
-ifeq ($(FFTW_VERSION),2)
-LIBS += -lrfftw -lfftw
-else
-LIBS += -lfftw3
-endif
-
-ifeq ($(OS_PORT),LINUX) 
-LIBS+= -lpthread
-else
-#dynamic linking
-#LIBS+= -lpthreadGC
-#static linking
-LIBS+= /usr/lib/libpthreadGC1.a
-endif
-
-ifeq ($(MIDIIN),ALSA) 
-LIBS+= -lasound
-endif
-
-ifeq ($(AUDIOOUT),PA) 
-LIBS+= -lportaudio
-endif
-
-ifeq ($(OS_PORT),WINDOWS) 
-LIBS+= -lwinmm
-endif
-
-
-ifeq ($(AUDIOOUT),OSS_AND_JACK) 
-CXXFLAGS += `pkg-config --cflags jack`
-LIBS+= `pkg-config --libs jack`
-endif
-
-ifeq ($(AUDIOOUT),JACK) 
-CXXFLAGS += `pkg-config --cflags jack`
-LIBS+= `pkg-config --libs jack`
-endif
-
-ifeq ($(AUDIOOUT),JACK_RT) 
-CXXFLAGS += `pkg-config --cflags jack`
-LIBS+= `pkg-config --libs jack`
-endif
-
-ifeq ($(LINUX_USE_LASH),YES)
-CXXFLAGS += `pkg-config --cflags lash-1.0` -DUSE_LASH
-LIBS+= `pkg-config --libs lash-1.0`
-endif
-
-
-objects=main.o
-SUBDIRS=Controls DSP Effects Input Misc Output Params Samples Synth Seq
-
-.PHONY: subdirs $(SUBDIRS)
-
-all:
-#	yes " " | head
-
-	$(MAKE) -C UI $@
-#	@sh -c "cd UI ; $(CXX) -MM -MG -w *.cc >> ../Make.deps ; cd .."
-	@for name in $(SUBDIRS); do sh -c "cd $$name ; $(CXX) -MM -MG -w *.cpp >> ../Make.deps ; cd .."; done
-	$(MAKE) subdirs
-	$(MAKE) objs
-	rm -f zynaddsubfx zynaddsubfx.exe
-	rm -f Make.deps 
-
-
-ifeq ($(AUDIOOUT),DSSI) 
-	$(CXX) -shared  -o zynaddsubfx.so */*.o *.o $(LIBS) 
-else
-ifeq ($(AUDIOOUT),VST) 
-	$(CXX) -shared -o zynaddsubfx_vst.dll */*.o *.o ../../vstsdk2/source/common/AudioEffect.cpp ../../vstsdk2/source/common/audioeffectx.cpp  $(LIBS) zynaddsubfx_gcc.def
-else
-
-
-ifeq ($(OS_PORT),LINUX) 
-	$(CXX) -o zynaddsubfx */*.o *.o $(LIBS)
-else
-	$(CXX) -o zynaddsubfx.exe */*.o *.o $(LIBS)
-endif 
-endif
-endif
-
-subdirs: $(SUBDIRS)
-
-$(SUBDIRS):
-	$(MAKE) -C $@
-
-
-objs:$(objects)
-
-debug: all
-
-main.o:Misc/Master.h Misc/Util.h Output/OSSaudiooutput.h\
-       Input/OSSMidiIn.h Input/ALSAMidiIn.h
-       
-
-.PHONY : clean
-clean: 
-	rm -f $(objects) zynaddsubfx zynaddsubfx_vst.dll zynaddsubfx.exe zynaddsubfx.so
-	@for name in $(SUBDIRS); do sh -c "make -C $$name $@"; done
-	rm -f Make.deps
-	rm -f */*.o *.o
-	rm -f ./*/*~ ./*~
-	$(MAKE) -C UI $@
-
diff --git a/src/Makefile.inc b/src/Makefile.inc
deleted file mode 100644
index 52ac90e..0000000
--- a/src/Makefile.inc
+++ /dev/null
@@ -1,83 +0,0 @@
-CXX=g++
-
-#You can set the on what OS is compiling (Linux/Windows)
-OS_PORT=LINUX
-#OS_PORT=WINDOWS
-
-#The version of the FFTW which is used (2 or 3)
-#FFTW_VERSION=2
-FFTW_VERSION=3
-
-#Assembler FLOAT to INT conversions
-ASM_F2I=YES
-#ASM_F2I=NO
-
-#Graphic user interface disable option (ZynAddSubFX will run only in text-mode)
-#DISABLE_GUI=YES
-DISABLE_GUI=NO
-
-# L I N U X   C O N F I G U R A T I O N
-#Next line sets the midi input. It can be "ALSA", "OSS" or "NONE".
-LINUX_MIDIIN=ALSA
-#LINUX_MIDIIN=OSS
-#LINUX_MIDIIN=NONE
-
-#Next lines sets the audio output (OSS/JACK/PA)
-#You may use only one at the time
-#If you use "OSS_AND_JACK",,at runtime, zynaddsubfx will run by the default with jack support and 
-#it will try OSS if JACK fails. At runtime you can set the OSS by default by command-line
-#parameters (run 'zynaddsubfx --help' for help) 
-
-#LINUX_AUDIOOUT=OSS_AND_JACK
-LINUX_AUDIOOUT=OSS
-#LINUX_AUDIOOUT=NONE
-#LINUX_AUDIOOUT=JACK
-#LINUX_AUDIOOUT=JACK_RT     JACK_RT support is broken
-#for PortAudio (PA)
-#LINUX_AUDIOOUT=PA
-
-
-#Next line sets if the synth is compiled for DSSI plugin (as .so file)
-#If this setting is "YES", MIDI in and AUDIOOUT are set automatically to DSSI
-LINUX_DSSI=NO
-#LINUX_DSSI=YES
-
-#Next line sets if the LASH session handler will be used
-#LINUX_USE_LASH=YES
-LINUX_USE_LASH=NO
-
-# W I N D O W S   C O N F I G U R A T I O N
-
-#Next line sets the midi input
-#WINDOWS_MIDIIN=NONE
-WINDOWS_MIDIIN=WIN
-
-#Next line sets the audio output
-#WINDOWS_AUDIOOUT=NONE
-WINDOWS_AUDIOOUT=PA
-
-#Next line sets if the synth is compiled for VST (as .dll file)
-#If this setting is "YES", MIDI in and AUDIOOUT are set automatically to VST
-WINDOWS_VST=NO
-#WINDOWS_VST=YES
-
-#configuration end 
-
-ifeq ($(OS_PORT),LINUX)
- MIDIIN=$(LINUX_MIDIIN)
- AUDIOOUT=$(LINUX_AUDIOOUT)
- WINDOWS_VST=NO
-    ifeq ($(LINUX_DSSI),YES)
-     MIDIIN=DSSI
-     AUDIOOUT=DSSI
-    endif
-else
- MIDIIN=$(WINDOWS_MIDIIN)
- AUDIOOUT=$(WINDOWS_AUDIOOUT)
- LINUX_DSSI=NO
-    ifeq ($(WINDOWS_VST),YES)
-     MIDIIN=VST
-     AUDIOOUT=VST
-    endif
-endif
-
diff --git a/src/Misc/Bank.cpp b/src/Misc/Bank.cpp
index 4c1b27a..1a673da 100644
--- a/src/Misc/Bank.cpp
+++ b/src/Misc/Bank.cpp
@@ -1,9 +1,11 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  Bank.h - Instrument Bank
+  Bank.cpp - Instrument Bank
   Copyright (C) 2002-2005 Nasca Octavian Paul
+  Copyright (C) 2010-2010 Mark McCurry
   Author: Nasca Octavian Paul
+          Mark McCurry
 
   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
@@ -26,6 +28,8 @@
 #include <stdlib.h>
 #include <dirent.h>
 #include <sys/stat.h>
+#include <algorithm>
+#include <iostream>
 
 #include <sys/types.h>
 #include <fcntl.h>
@@ -33,353 +37,278 @@
 #include <errno.h>
 
 #include "Config.h"
+#include "Util.h"
+#include "Part.h"
 
 #define INSTRUMENT_EXTENSION ".xiz"
 
 //if this file exists into a directory, this make the directory to be considered as a bank, even if it not contains a instrument file
 #define FORCE_BANK_DIR_FILE ".bankdir"
 
+using namespace std;
+
 Bank::Bank()
+    :defaultinsname(" ")
 {
-
-
-    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;
-    };
-
-    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;
-    };
-
     clearbank();
-};
+}
 
 /*
  * Get the name of an instrument from the bank
  */
-char *Bank::getname (unsigned int ninstrument)
+string 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)
+string 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;
+
+    return stringFrom(ninstrument + 1) + ". " + getname(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 string &newname, int newslot)
 {
-    if (emptyslot(ninstrument)) return;
+    if(emptyslot(ninstrument))
+        return;
 
-    char newfilename[1000+1],tmpfilename[100+1];
+    string newfilename;
+    char   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);
+    if(newslot >= 0)
+        snprintf(tmpfilename, 100, "%4d-%s", newslot + 1, newname.c_str());
+    else
+        snprintf(tmpfilename, 100, "%4d-%s", ninstrument + 1, newname.c_str());
 
     //add the zeroes at the start of filename
-    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 < 4; ++i)
+        if(tmpfilename[i] == ' ')
+            tmpfilename[i] = '0';
 
-//    printf("rename %s -> %s\n",ins[ninstrument].filename,newfilename);//////////////
+    newfilename = dirname + '/' + legalizeFilename(tmpfilename) + ".xiz";
 
-    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.c_str(), newfilename.c_str());
 
-};
+    ins[ninstrument].filename = newfilename;
+    ins[ninstrument].name     = legalizeFilename(tmpfilename); //TODO limit name to PART_MAX_NAME_LEN
+}
 
 /*
  * Check if there is no instrument on a slot from the bank
  */
-int Bank::emptyslot(unsigned int ninstrument)
+bool Bank::emptyslot(unsigned int ninstrument)
 {
-    if (ninstrument>=BANK_SIZE) return (1);
-    if (ins[ninstrument].filename==NULL) return(1);
+    if(ninstrument >= BANK_SIZE)
+        return true;
+    if(ins[ninstrument].filename.empty())
+        return true;
 
-    if (ins[ninstrument].used) return (0);
-    else return(1);
-};
+    if(ins[ninstrument].used)
+        return false;
+    else
+        return true;
+}
 
 /*
  * 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);
+    remove(ins[ninstrument].filename.c_str());
     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';
-
-    //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]='_';
-    };
-
-    strncat(tmpfilename,".xiz",maxfilename+10);
-
-    int fnsize=strlen(dirname)+strlen(tmpfilename)+10;
-    char *filename=new char[fnsize+4];
-    ZERO(filename,fnsize+2);
-
-    snprintf(filename,fnsize,"%s/%s",dirname,tmpfilename);
+    for(int i = 0; i < 4; ++i)
+        if(tmpfilename[i] == ' ')
+            tmpfilename[i] = '0';
 
-    remove(filename);
-    part->saveXML(filename);
-    addtobank(ninstrument,tmpfilename,(char *) part->Pname);
+    string filename = dirname + '/' + legalizeFilename(tmpfilename) + ".xiz";
 
-    delete[]filename;
-};
+    remove(filename.c_str());
+    part->saveXML(filename.c_str());
+    addtobank(ninstrument, legalizeFilename(tmpfilename), (char *) part->Pname);
+}
 
 /*
  * 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->AllNotesOff();
     part->defaultsinstrument();
 
-//    printf("load:  %s\n",ins[ninstrument].filename);
-
-    part->loadXMLinstrument(ins[ninstrument].filename);
-
-};
-
+    part->loadXMLinstrument(ins[ninstrument].filename.c_str());
+}
 
 /*
  * Makes current a bank directory
  */
-int Bank::loadbank(const char *bankdirname)
+int Bank::loadbank(string bankdirname)
 {
-    DIR *dir=opendir(bankdirname);
+    DIR *dir = opendir(bankdirname.c_str());
     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);
+    dirname = 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;
+        //check for extension
+        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);
+        string name = filename;
 
         //remove the file extension
-        for (int i=strlen(name)-1;i>=2;i--) {
-            if (name[i]=='.') {
-                name[i]='\0';
+        for(int i = name.size() - 1; i >= 2; i--)
+            if(name[i] == '.') {
+                name = name.substr(0, i);
                 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.substr(startname));
+        else
+            addtobank(-1, filename, name);
+    }
 
     closedir(dir);
 
-    if (dirname!=NULL) {
-        sprintf(config.cfg.currentBankDir,"%s",dirname);
-    };
+    if(!dirname.empty())
+        config.cfg.currentBankDir = 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 Bank::newbank(string newbankdirname)
 {
-    int result;
-    char tmpfilename[MAX_STRING_SIZE];
-    char bankdir[MAX_STRING_SIZE];
-    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);
-#ifdef OS_WINDOWS
-    result=mkdir(bankdir);
-#else
-    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);
-//    printf("%s\n",tmpfilename);
-    FILE *tmpfile=fopen(tmpfilename,"w+");
+    string bankdir;
+    bankdir = config.cfg.bankRootDirList[0];
+
+    if(((bankdir[bankdir.size() - 1]) != '/')
+       && ((bankdir[bankdir.size() - 1]) != '\\'))
+        bankdir += "/";
+
+    bankdir += newbankdirname;
+    if(mkdir(bankdir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0)
+        return -1;
+
+    const string tmpfilename = bankdir + '/' + FORCE_BANK_DIR_FILE;
+
+    FILE *tmpfile = fopen(tmpfilename.c_str(), "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.empty();
+}
 
 /*
  * 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);
-        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;
-    };
-
-};
-
-
-//a helper function that compares 2 banks[] arrays
-int Bank_compar(const void *a,const void *b)
+    if((n1 == n2) || (locked()))
+        return;
+    if(emptyslot(n1) && (emptyslot(n2)))
+        return;
+    if(emptyslot(n1)) //change n1 to n2 in order to make
+        swap(n1, n2);
+
+    if(emptyslot(n2)) { //this is just a movement from slot1 to slot2
+        setname(n1, getname(n1), n2);
+        ins[n2] = ins[n1];
+        ins[n1] = ins_t();
+    }
+    else {  //if both slots are used
+        if(ins[n1].name == ins[n2].name) //change the name of the second instrument if the name are equal
+            ins[n2].name += "2";
+
+        setname(n1, getname(n1), n2);
+        setname(n2, getname(n2), n1);
+        swap(ins[n2], ins[n1]);
+    }
+}
+
+
+bool Bank::bankstruct::operator<(const bankstruct &b) const
 {
-    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);
-};
-
+    return name < b.name;
+}
 
 /*
  * Re-scan for directories containing instrument banks
@@ -387,198 +316,153 @@ 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;
-    };
+    //remove old banks
+    banks.clear();
 
-    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_BANK_ROOT_DIRS; ++i)
+        if(!config.cfg.bankRootDirList[i].empty())
+            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;
-
-                banks[i].name=banks[j].name;
-                banks[i].dir=banks[j].dir;
-
-                banks[j].name=tmpname;
-                banks[j].dir=tmpdir;
-
-            };
-        };
-    };
+    sort(banks.begin(), banks.end());
 
     //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 < (int) banks.size() - 1; ++j)
+        for(int i = j + 1; i < (int) banks.size(); ++i) {
+            if(banks[i].name == banks[j].name) {
+                //add a [1] to the first bankname and [n] to others
+                banks[i].name = banks[i].name + '['
+                                + stringFrom(dupl + 2) + ']';
+                if(dupl == 0)
+                    banks[j].name += "[1]";
 
                 dupl++;
-            } else dupl=0;
-        };
-    };
-
-};
-
+            }
+            else
+                dupl = 0;
+        }
+}
 
 
 // private stuff
 
-void Bank::scanrootdir(char *rootdir)
+void Bank::scanrootdir(string rootdir)
 {
-//    printf("Scanning root dir:%s\n",rootdir);
-    DIR *dir=opendir(rootdir);
-    if (dir==NULL) return;
-
-    const int maxdirsize=1000;
-    struct {
-        char dir[maxdirsize];
-        char name[maxdirsize];
-    }bank;
-
-    const char *separator="/";
-    if (strlen(rootdir)) {
-        char tmp=rootdir[strlen(rootdir)-1];
-        if ((tmp=='/') || (tmp=='\\')) separator="";
-    };
+    DIR *dir = opendir(rootdir.c_str());
+    if(dir == NULL)
+        return;
+
+    bankstruct bank;
+
+    const char *separator = "/";
+    if(rootdir.size()) {
+        char tmp = rootdir[rootdir.size() - 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);
+        bank.dir  = rootdir + separator + dirname + '/';
+        bank.name = 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.c_str());
+        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
-            };
-        };
-
-        closedir(d);
+        while((fname = readdir(d))) {
+            if((strstr(fname->d_name, INSTRUMENT_EXTENSION) != NULL)
+               || (strstr(fname->d_name, FORCE_BANK_DIR_FILE) != NULL)) {
+                isbank = true;
+                break; //could put a #instrument counter here instead
+            }
+        }
 
-        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(isbank)
+            banks.push_back(bank);
 
-            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(d);
+    }
 
     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)
-{
-    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;
+    for(int i = 0; i < BANK_SIZE; ++i)
+        ins[i] = ins_t();
 
+    bankfiletitle.clear();
+    dirname.clear();
+}
 
-    if (pos<0) {//find a free position
-        for (int i=BANK_SIZE-1;i>=0;i--)
-            if (!ins[i].used) {
-                pos=i;
+int Bank::addtobank(int pos, string filename, string 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;
                 break;
-            };
+            }
 
-    };
-
-    if (pos<0) return (-1);//the bank is full
-
-    // printf("%s   %d\n",filename,pos);
+    if(pos < 0)
+        return -1;  //the bank is full
 
     deletefrombank(pos);
 
-    ins[pos].used=true;
-    snprintf(ins[pos].name,PART_MAX_NAME_LEN,"%s",name);
-
-    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);
+    ins[pos].used     = true;
+    ins[pos].name     = name;
+    ins[pos].filename = dirname + '/' + filename;
 
     //see if PADsynth is used
-    if (config.cfg.CheckPADsynth) {
-        XMLwrapper *xml=new XMLwrapper();
-        xml->checkfileinformation(ins[pos].filename);
+    if(config.cfg.CheckPADsynth) {
+        XMLwrapper xml;
+        xml.loadXMLfile(ins[pos].filename);
 
-        ins[pos].info.PADsynth_used=xml->information.PADsynth_used;
-        delete xml;
-    } else ins[pos].info.PADsynth_used=false;
+        ins[pos].info.PADsynth_used = xml.hasPadSynth();
+    }
+    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 >= (int) banks.size()))
+        return;
+    ins[pos] = ins_t();
+}
 
+Bank::ins_t::ins_t()
+    :used(false), name(""), filename("")
+{
+    info.PADsynth_used = false;
+}
diff --git a/src/Misc/Bank.h b/src/Misc/Bank.h
index 8359b54..5a7ed9d 100644
--- a/src/Misc/Bank.h
+++ b/src/Misc/Bank.h
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  Bank.C - Instrument Bank
+  Bank.h - Instrument Bank
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -23,86 +23,81 @@
 #ifndef BANK_H
 #define BANK_H
 
-#include "../globals.h"
-#include "XMLwrapper.h"
-#include "Part.h"
+#include <string>
+#include <vector>
 
+//entries in a bank
 #define BANK_SIZE 160
 
-/**
- * The max. number of banks that are used
- */
-#define MAX_NUM_BANKS 400
-
-/**The instrument Bank
- * \todo add in strings to replace char* */
+/**The instrument Bank*/
 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();
+        std::string getname(unsigned int ninstrument);
+        std::string getnamenumbered(unsigned int ninstrument);
+        void setname(unsigned int ninstrument,
+                     const std::string &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 true when slot is empty*/
+        bool 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, class Part * part);
+        /**Loads the given slot into a Part*/
+        void loadfromslot(unsigned int ninstrument, class 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(std::string bankdirname);
+        int newbank(std::string newbankdirname);
 
-    char *bankfiletitle; //this is shown on the UI of the bank (the title of the window)
-    int locked();
+        std::string 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 {
+            bool operator<(const bankstruct &b) const;
+            std::string dir;
+            std::string name;
+        };
 
-    bankstruct banks[MAX_NUM_BANKS];
+        std::vector<bankstruct> 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, std::string filename, std::string 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
+        std::string defaultinsname;
 
-    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 {
+            ins_t();
+            bool used;
+            std::string name;
+            std::string filename;
+            struct {
+                bool PADsynth_used;
+            } info;
+        } ins[BANK_SIZE];
 
-    char *dirname;
+        std::string dirname;
 
-    void scanrootdir(char *rootdir);//scans a root dir for banks
+        void scanrootdir(std::string rootdir); //scans a root dir for banks
 };
 
 #endif
-
diff --git a/src/Misc/CMakeLists.txt b/src/Misc/CMakeLists.txt
new file mode 100644
index 0000000..ade2ca3
--- /dev/null
+++ b/src/Misc/CMakeLists.txt
@@ -0,0 +1,27 @@
+include_directories(${MXML_INCLUDE_DIR})
+
+set(zynaddsubfx_misc_SRCS
+	Bank.cpp
+	Config.cpp
+	Dump.cpp
+	Master.cpp
+	Microtonal.cpp
+	Part.cpp
+	Util.cpp
+	XMLwrapper.cpp
+	Recorder.cpp
+	WavFile.cpp
+	WaveShapeSmps.cpp
+)
+
+
+
+if(LashEnable)
+    set(zynaddsubfx_misc_SRCS ${zynaddsubfx_misc_SRCS} LASHClient.cpp)
+endif()
+
+add_library(zynaddsubfx_misc STATIC
+	${zynaddsubfx_misc_SRCS}
+	)
+
+target_link_libraries(zynaddsubfx_misc zynaddsubfx_nio)
diff --git a/src/Misc/Config.cpp b/src/Misc/Config.cpp
index 9a29015..9e2a430 100644
--- a/src/Misc/Config.cpp
+++ b/src/Misc/Config.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  Config.C - Configuration file functions
+  Config.cpp - Configuration file functions
   Copyright (C) 2003-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -24,318 +24,277 @@
 #include <stdlib.h>
 #include <string.h>
 
-#ifdef OS_WINDOWS
-#include <windows.h>
-#include <mmsystem.h>
-#endif
 
 #include "Config.h"
 #include "XMLwrapper.h"
 
+using namespace std;
+
 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.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.WindowsWaveOutId=0;
-    cfg.WindowsMidiInId=0;
-
-    cfg.BankUIAutoClose=0;
-    cfg.DumpNotesToFile=0;
-    cfg.DumpAppend=1;
-
-    cfg.GzipCompression=3;
-
-    cfg.Interpolation=0;
-    cfg.CheckPADsynth=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;
-#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';
-    };
+    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");
 
-//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);
-    };
-#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.presetsDirList[i]=NULL;
-
-    char filename[MAX_STRING_SIZE];
-    getConfigFileName(filename,MAX_STRING_SIZE);
-    readConfig(filename);
+    cfg.DumpFile = "zynaddsubfx_dump.txt";
 
-    if (cfg.bankRootDirList[0]==NULL) {
-#if defined(OS_LINUX)
-        //banks
-        cfg.bankRootDirList[0]=new char[MAX_STRING_SIZE];
-        sprintf(cfg.bankRootDirList[0],"~/banks");
+    cfg.WindowsWaveOutId = 0;
+    cfg.WindowsMidiInId  = 0;
 
-        cfg.bankRootDirList[1]=new char[MAX_STRING_SIZE];
-        sprintf(cfg.bankRootDirList[1],"./");
+    cfg.BankUIAutoClose = 0;
+    cfg.DumpNotesToFile = 0;
+    cfg.DumpAppend      = 1;
 
-        cfg.bankRootDirList[2]=new char[MAX_STRING_SIZE];
-        sprintf(cfg.bankRootDirList[2],"/usr/share/zynaddsubfx/banks");
+    cfg.GzipCompression = 3;
 
-        cfg.bankRootDirList[3]=new char[MAX_STRING_SIZE];
-        sprintf(cfg.bankRootDirList[3],"/usr/local/share/zynaddsubfx/banks");
+    cfg.Interpolation = 0;
+    cfg.CheckPADsynth = 1;
 
-        cfg.bankRootDirList[4]=new char[MAX_STRING_SIZE];
-        sprintf(cfg.bankRootDirList[4],"../banks");
+    cfg.UserInterfaceMode = 0;
+    cfg.VirKeybLayout     = 1;
+    winwavemax = 1;
+    winmidimax = 1;
+    //try to find out how many input midi devices are there
+    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';
+    }
 
-        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],"./");
-
-#ifdef VSTAUDIOOUT
-        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");
-#endif
-        cfg.bankRootDirList[2]=new char[MAX_STRING_SIZE];
-        sprintf(cfg.bankRootDirList[2],"banks");
-
-#endif
-    };
-
-    if (cfg.presetsDirList[0]==NULL) {
-#if defined(OS_LINUX)
-        //presets
-        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[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");
+//get the midi input devices name
+    cfg.currentBankDir = "./testbnk";
 
-        cfg.presetsDirList[4]=new char[MAX_STRING_SIZE];
-        sprintf(cfg.presetsDirList[4],"/usr/local/share/zynaddsubfx/presets");
+    char filename[MAX_STRING_SIZE];
+    getConfigFileName(filename, MAX_STRING_SIZE);
+    readConfig(filename);
 
-#else
+    if(cfg.bankRootDirList[0].empty()) {
+        //banks
+        cfg.bankRootDirList[0] = "~/banks";
+        cfg.bankRootDirList[1] = "./";
+        cfg.bankRootDirList[2] = "/usr/share/zynaddsubfx/banks";
+        cfg.bankRootDirList[3] = "/usr/local/share/zynaddsubfx/banks";
+        cfg.bankRootDirList[4] = "../banks";
+        cfg.bankRootDirList[5] = "banks";
+    }
+
+    if(cfg.presetsDirList[0].empty()) {
         //presets
-        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");
-#else
-        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");
-#endif
-    };
-
-};
+        cfg.presetsDirList[0] = "./";
+        cfg.presetsDirList[1] = "../presets";
+        cfg.presetsDirList[2] = "presets";
+        cfg.presetsDirList[3] = "/usr/share/zynaddsubfx/presets";
+        cfg.presetsDirList[4] = "/usr/local/share/zynaddsubfx/presets";
+    }
+    cfg.LinuxALSAaudioDev = "default";
+    cfg.nameTag = "";
+}
 
 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)
+        cfg.bankRootDirList[i].clear();
+}
 
 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)
+        cfg.presetsDirList[i].clear();
+}
 
 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;
+    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);
+        cfg.DumpFile = xmlcfg.getparstr("dump_file", "");
+
+        cfg.GzipCompression = xmlcfg.getpar("gzip_compression",
+                                            cfg.GzipCompression,
+                                            0,
+                                            9);
+
+        cfg.currentBankDir = xmlcfg.getparstr("bank_current", "");
+        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);
-                xmlcfg->exitbranch();
-            };
-        };
+        for(int i = 0; i < MAX_BANK_ROOT_DIRS; ++i)
+            if(xmlcfg.enterbranch("BANKROOT", i)) {
+                cfg.bankRootDirList[i] = xmlcfg.getparstr("bank_root", "");
+                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);
-                xmlcfg->exitbranch();
-            };
-        };
+        for(int i = 0; i < MAX_BANK_ROOT_DIRS; ++i)
+            if(xmlcfg.enterbranch("PRESETSROOT", i)) {
+                cfg.presetsDirList[i] = xmlcfg.getparstr("presets_root", "");
+                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);
+        xmlcfg.exitbranch();
+    }
 
-    cfg.OscilSize=(int) pow(2,ceil(log (cfg.OscilSize-1.0)/log(2.0)));
-
-};
+    cfg.OscilSize = (int) powf(2, ceil(logf(cfg.OscilSize - 1.0f) / logf(2.0f)));
+}
 
 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].empty()) {
+            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].empty()) {
+            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;
-#ifdef OS_LINUX
-    snprintf(name,namesize,"%s%s",getenv("HOME"),"/.zynaddsubfxXML.cfg");
-#else
-    snprintf(name,namesize,"%s","zynaddsubfxXML.cfg");
-#endif
-
-};
-
+    name[0] = 0;
+    snprintf(name, namesize, "%s%s", getenv("HOME"), "/.zynaddsubfxXML.cfg");
+}
diff --git a/src/Misc/Config.h b/src/Misc/Config.h
index 9d4fef6..4b86390 100644
--- a/src/Misc/Config.h
+++ b/src/Misc/Config.h
@@ -23,49 +23,51 @@
 #ifndef CONFIG_H
 #define CONFIG_H
 #include "../globals.h"
+#include <string>
 #define MAX_STRING_SIZE 4000
 #define MAX_BANK_ROOT_DIRS 100
 
 /**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;
+            std::string DumpFile;
+            std::string bankRootDirList[MAX_BANK_ROOT_DIRS], currentBankDir;
+            std::string presetsDirList[MAX_BANK_ROOT_DIRS];
+            int CheckPADsynth;
+            int UserInterfaceMode;
+            int VirKeybLayout;
+            std::string LinuxALSAaudioDev;
+            std::string nameTag;
+        } 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
index 780d4b9..a605a66 100644
--- a/src/Misc/Control.h
+++ b/src/Misc/Control.h
@@ -27,74 +27,73 @@
 
 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
index cb1728e..e98074b 100644
--- a/src/Misc/Dump.cpp
+++ b/src/Misc/Dump.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  Dump.C - It dumps the notes to a text file
+  Dump.cpp - It dumps the notes to a text file
 
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
@@ -28,80 +28,94 @@ 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) {
+        int duration = tick * synth->buffersize_f / synth->samplerate_f;
+        fprintf(
+            file,
+            "\n# statistics: duration = %d seconds; keyspressed = %d\n\n\n\n",
+            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.c_str(), "a");
+        else
+            file = fopen(config.cfg.DumpFile.c_str(), "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",
+                synth->buffersize_f * 1000.0f / synth->samplerate_f);
+        fprintf(file, "SAMPLERATE = %d\n", synth->samplerate);
+        fprintf(file, "TICKSIZE = %d #samples\n", synth->buffersize);
+        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) {
-    case C_pitchwheel:
-        fprintf(file,"P %d -> %d %d\n",tick,chan,par);
-        break;
-    default:
-        fprintf(file,"C %d -> %d %d %d\n",tick,chan,type,par);
-        break;
-    };
+    if(file == NULL)
+        return;
+    switch(type) {
+        case C_pitchwheel:
+            fprintf(file, "P %d -> %d %d\n", tick, chan, par);
+            break;
+        default:
+            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
index d285eb9..dc543cf 100644
--- a/src/Misc/Dump.h
+++ b/src/Misc/Dump.h
@@ -30,34 +30,34 @@
  * \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
index 3434a05..57979a3 100644
--- a/src/Misc/LASHClient.cpp
+++ b/src/Misc/LASHClient.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  LASHClient.C - LASH support
+  LASHClient.cpp - LASH support
   Copyright (C) 2006-2009 Lars Luthman
   Author: Lars Luthman
 
@@ -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,9 @@ 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
index d0fa95b..1f3a494 100644
--- a/src/Misc/LASHClient.h
+++ b/src/Misc/LASHClient.h
@@ -28,39 +28,36 @@
 
 
 /** This class wraps up some functions for initialising and polling
- *  the LASH daemon.
- *  \todo fix indentation nonconformism
- *  \todo see why there is no destructor*/
+ *  the LASH daemon.*/
 class LASHClient
 {
-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);
-
-    /**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:
-
-    lash_client_t* client;
+    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);
+
+        /**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:
+
+        lash_client_t *client;
 };
 
 
 #endif
-
diff --git a/src/Misc/Makefile b/src/Misc/Makefile
deleted file mode 100644
index 7133063..0000000
--- a/src/Misc/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-include ../Makefile.inc
-
-objects=Bank.o Master.o Microtonal.o Part.o Util.o Config.o Dump.o XMLwrapper.o
-
-ifeq ($(LINUX_USE_LASH),YES)
-objects += LASHClient.o
-endif
-
-
-all: $(objects)
-
--include ../Make.deps
-
-.PHONY : clean
-clean: 
-	rm -f $(objects)
-	rm -f makeinclude.deps
-
diff --git a/src/Misc/Master.cpp b/src/Misc/Master.cpp
index d925ba0..37cf59f 100644
--- a/src/Misc/Master.cpp
+++ b/src/Misc/Master.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  Master.C - It sends Midi Messages to Parts, receives samples from parts,
+  Master.cpp - It sends Midi Messages to Parts, receives samples from parts,
              process them with system/insertion effects and mix them
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
@@ -23,501 +23,507 @@
 
 #include "Master.h"
 
+#include "Part.h"
+
+#include "../Params/LFOParams.h"
+#include "../Effects/EffectMgr.h"
+#include "../DSP/FFTwrapper.h"
+
 #include <stdio.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <iostream>
+#include <algorithm>
+#include <cmath>
 
 #include <unistd.h>
 
-Master::Master()
-{
-    swaplr=0;
-
-    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];
+using namespace std;
 
-    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;
-    };
+vuData::vuData(void)
+    :outpeakl(0.0f), outpeakr(0.0f), maxoutpeakl(0.0f), maxoutpeakr(0.0f),
+      rmspeakl(0.0f), rmspeakr(0.0f), clipped(0)
+{}
 
-    for (int i=0;i<SOUND_BUFFER_SIZE;i++) {
-        audiooutl[i]=0.0;
-        audiooutr[i]=0.0;
-    };
+Master::Master()
+{
+    swaplr = 0;
 
-    for (int npart=0;npart<NUM_MIDI_PARTS;npart++)
-        part[npart]=new Part(&microtonal,fft,&mutex);
+    pthread_mutex_init(&mutex, NULL);
+    pthread_mutex_init(&vumutex, NULL);
+    fft = new FFTwrapper(synth->oscilsize);
 
+    shutup = 0;
+    for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
+        vuoutpeakpart[npart] = 1e-9;
+        fakepeakpart[npart]  = 0;
+    }
 
+    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.0f;
     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++) {
-            //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);
-    };
-
-//	sysefx[0]->changeeffect(1);
+        for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
+            setPsysefxvol(npart, nefx, 0);
+
+        for(int nefxto = 0; nefxto < NUM_SYS_EFX; ++nefxto)
+            setPsysefxsend(nefx, nefxto, 0);
+    }
+
     microtonal.defaults();
     ShutUp();
-};
+}
 
-/*
- * Note On Messages (velocity=0 for NoteOff)
- */
-void Master::NoteOn(unsigned char chan,unsigned char note,unsigned char velocity)
+bool Master::mutexLock(lockset request)
+{
+    switch(request) {
+        case MUTEX_TRYLOCK:
+            return !pthread_mutex_trylock(&mutex);
+        case MUTEX_LOCK:
+            return !pthread_mutex_lock(&mutex);
+        case MUTEX_UNLOCK:
+            return !pthread_mutex_unlock(&mutex);
+    }
+    return false;
+}
+
+Master &Master::getInstance()
 {
-    dump.dumpnote(chan,note,velocity);
+    static Master *instance = NULL;
+    if(!instance)
+        instance = new Master;
 
-    noteon(chan,note,velocity);
-};
+    return *instance;
+}
 
 /*
- * Internal Note On (velocity=0 for NoteOff)
+ * Note On Messages (velocity=0 for NoteOff)
  */
-void Master::noteon(unsigned char chan,unsigned char note,unsigned char velocity)
+void Master::noteOn(char chan, char note, 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) {
+        for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
+            if(chan == part[npart]->Prcvchn) {
+                fakepeakpart[npart] = velocity * 2;
+                if(part[npart]->Penabled)
+                    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)
-{
-    dump.dumpnote(chan,note,0);
-
-    noteoff(chan,note);
-};
-
-/*
- * Internal Note Off
- */
-void Master::noteoff(unsigned char chan,unsigned char note)
+void Master::noteOff(char chan, char note)
 {
-    int npart;
-    for (npart=0;npart<NUM_MIDI_PARTS;npart++) {
-        if ((chan==part[npart]->Prcvchn) && (part[npart]->Penabled!=0))
+    for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
+        if((chan == part[npart]->Prcvchn) && part[npart]->Penabled)
             part[npart]->NoteOff(note);
-    };
-};
+}
 
 /*
- * Controllers
+ * Pressure Messages (velocity=0 for NoteOff)
  */
-void Master::SetController(unsigned char chan,unsigned int type,int par)
+void Master::polyphonicAftertouch(char chan, char note, char velocity)
 {
-    dump.dumpcontroller(chan,type,par);
+    if(velocity) {
+        for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
+            if(chan == part[npart]->Prcvchn)
+                if(part[npart]->Penabled)
+                    part[npart]->PolyphonicAftertouch(note, velocity, keyshift);
 
-    setcontroller(chan,type,par);
-};
+    }
+    else
+        this->noteOff(chan, note);
+}
 
 /*
- * Internal Controllers
+ * Controllers
  */
-void Master::setcontroller(unsigned char chan,unsigned int type,int par)
+void Master::setController(char chan, 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);
-                };
-                break;
-            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();
+            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);
+                    ;
+                    break;
             }
-            for (int nefx=0;nefx<NUM_INS_EFX;++nefx) {
+        ;
+    }
+    else
+    if(type == C_bankselectmsb) {      // Change current bank
+        if(((unsigned int)par < bank.banks.size())
+           && (bank.banks[par].dir != bank.bankfiletitle))
+            bank.loadbank(bank.banks[par].dir);
+    }
+    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();
-            }
         }
-    };
-};
+    }
+}
+
+void Master::setProgram(char chan, unsigned int pgm)
+{
+    for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
+        if(chan == part[npart]->Prcvchn) {
+            bank.loadfromslot(pgm, part[npart]);
+
+            //Hack to get pad note parameters to update
+            //this is not real time safe and makes assumptions about the calling
+            //convention of this function...
+            pthread_mutex_unlock(&mutex);
+            part[npart]->applyparameters();
+            pthread_mutex_lock(&mutex);
+        }
+}
+
+void Master::vuUpdate(const float *outl, const float *outr)
+{
+    //Peak computation (for vumeters)
+    vu.outpeakl = 1e-12;
+    vu.outpeakr = 1e-12;
+    for(int i = 0; i < synth->buffersize; ++i) {
+        if(fabs(outl[i]) > vu.outpeakl)
+            vu.outpeakl = fabs(outl[i]);
+        if(fabs(outr[i]) > vu.outpeakr)
+            vu.outpeakr = fabs(outr[i]);
+    }
+    if((vu.outpeakl > 1.0f) || (vu.outpeakr > 1.0f))
+        vu.clipped = 1;
+    if(vu.maxoutpeakl < vu.outpeakl)
+        vu.maxoutpeakl = vu.outpeakl;
+    if(vu.maxoutpeakr < vu.outpeakr)
+        vu.maxoutpeakr = vu.outpeakr;
 
+    //RMS Peak computation (for vumeters)
+    vu.rmspeakl = 1e-12;
+    vu.rmspeakr = 1e-12;
+    for(int i = 0; i < synth->buffersize; ++i) {
+        vu.rmspeakl += outl[i] * outl[i];
+        vu.rmspeakr += outr[i] * outr[i];
+    }
+    vu.rmspeakl = sqrt(vu.rmspeakl / synth->buffersize_f);
+    vu.rmspeakr = sqrt(vu.rmspeakr / synth->buffersize_f);
+
+    //Part Peak computation (for Part vumeters or fake part vumeters)
+    for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
+        vuoutpeakpart[npart] = 1.0e-12f;
+        if(part[npart]->Penabled != 0) {
+            float *outl = part[npart]->partoutl,
+            *outr = part[npart]->partoutr;
+            for(int i = 0; i < synth->buffersize; ++i) {
+                float tmp = fabs(outl[i] + outr[i]);
+                if(tmp > vuoutpeakpart[npart])
+                    vuoutpeakpart[npart] = tmp;
+            }
+            vuoutpeakpart[npart] *= volume;
+        }
+        else
+        if(fakepeakpart[npart] > 1)
+            fakepeakpart[npart]--;
+    }
+}
 
 /*
  * 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(float *outl, float *outr)
 {
-    int i,npart,nefx;
-
-    /*    //test!!!!!!!!!!!!! se poate bloca aici (mutex)
-        if (seq.play){
-    	int type,par1,par2,again,midichan;
-    	int ntrack=1;
-    //	    do{
-    		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);
-    	    	    };
-    		};
-    //	    } while (again);
-        };
-    */
-
-
-//    printf("zzzz\n");
-
-
-    //Swaps the Left channel with Right Channel (if it is asked for)
-    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;
-    };
+    //Swaps the Left channel with Right Channel
+    if(swaplr)
+        swap(outl, outr);
+
+    //clean up the output samples (should not be needed?)
+    memset(outl, 0, synth->bufferbytes);
+    memset(outr, 0, synth->bufferbytes);
 
     //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(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
+        if(part[npart]->Penabled != 0 && !pthread_mutex_trylock(&part[npart]->load_mutex)) {
+            part[npart]->ComputePartSmps();
+            pthread_mutex_unlock(&part[npart]->load_mutex);
+        }
+    }
 
     //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(int nefx = 0; nefx < NUM_INS_EFX; ++nefx)
+        if(Pinsparts[nefx] >= 0) {
+            int efxpart = Pinsparts[nefx];
+            if(part[efxpart]->Penabled)
+                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(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
+        if(part[npart]->Penabled == 0)
+            continue;
+
+        Stereo<float> newvol(part[npart]->volume),
+        oldvol(part[npart]->oldvolumel,
+               part[npart]->oldvolumer);
+
+        float pan = part[npart]->panning;
+        if(pan < 0.5f)
+            newvol.l *= pan * 2.0f;
+        else
+            newvol.r *= (1.0f - pan) * 2.0f;
+
+        //the volume or the panning has changed and needs interpolation
+        if(ABOVE_AMPLITUDE_THRESHOLD(oldvol.l, newvol.l)
+           || ABOVE_AMPLITUDE_THRESHOLD(oldvol.r, newvol.r)) {
+            for(int i = 0; i < synth->buffersize; ++i) {
+                Stereo<float> vol(INTERPOLATE_AMPLITUDE(oldvol.l, newvol.l,
+                                                        i, synth->buffersize),
+                                  INTERPOLATE_AMPLITUDE(oldvol.r, newvol.r,
+                                                        i, synth->buffersize));
+                part[npart]->partoutl[i] *= vol.l;
+                part[npart]->partoutr[i] *= vol.r;
+            }
+            part[npart]->oldvolumel = newvol.l;
+            part[npart]->oldvolumer = newvol.r;
+        }
+        else
+            for(int i = 0; i < synth->buffersize; ++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(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx) {
+        if(sysefx[nefx]->geteffect() == 0)
+            continue;  //the effect is disabled
 
+        float *tmpmixl = getTmpBuffer();
+        float *tmpmixr = getTmpBuffer();
         //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;
-        };
+        memset(tmpmixl, 0, synth->bufferbytes);
+        memset(tmpmixr, 0, synth->bufferbytes);
 
         //Mix the channels according to the part settings about System Effect
-        for (npart=0;npart<NUM_MIDI_PARTS;npart++) {
+        for(int 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;
-            };
-        };
+            const float vol = sysefxvol[nefx][npart];
+            for(int i = 0; i < synth->buffersize; ++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;
-                };
-            };
-        };
-
-        sysefx[nefx]->out(tmpmixl,tmpmixr);
+        for(int nefxfrom = 0; nefxfrom < nefx; ++nefxfrom)
+            if(Psysefxsend[nefxfrom][nefx] != 0) {
+                const float vol = sysefxsend[nefxfrom][nefx];
+                for(int i = 0; i < synth->buffersize; ++i) {
+                    tmpmixl[i] += sysefx[nefxfrom]->efxoutl[i] * vol;
+                    tmpmixr[i] += sysefx[nefxfrom]->efxoutr[i] * vol;
+                }
+            }
+
+        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;
-        };
+        const float outvol = sysefx[nefx]->sysefxgetvolume();
+        for(int i = 0; i < synth->buffersize; ++i) {
+            outl[i] += tmpmixl[i] * outvol;
+            outr[i] += tmpmixr[i] * outvol;
+        }
 
-    };
+        returnTmpBuffer(tmpmixl);
+        returnTmpBuffer(tmpmixr);
+    }
 
     //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(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
+        if(part[npart]->Penabled)   //only mix active parts
+            for(int i = 0; i < synth->buffersize; ++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);
-    };
-
-    //Master Volume
-    for (i=0;i<SOUND_BUFFER_SIZE;i++) {
-        outl[i]*=volume;
-        outr[i]*=volume;
-    };
+    for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx)
+        if(Pinsparts[nefx] == -2)
+            insefx[nefx]->out(outl, outr);
 
-    //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;
-
-    //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);
 
-    //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]--;
-        };
-    };
+    //Master Volume
+    for(int i = 0; i < synth->buffersize; ++i) {
+        outl[i] *= volume;
+        outr[i] *= volume;
+    }
 
+    if(!pthread_mutex_trylock(&vumutex)) {
+        vuUpdate(outl, outr);
+        pthread_mutex_unlock(&vumutex);
+    }
 
     //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) {
+        for(int i = 0; i < synth->buffersize; ++i) {
+            float tmp = (synth->buffersize_f - i) / synth->buffersize_f;
+            outl[i] *= tmp;
+            outr[i] *= tmp;
+        }
         ShutUp();
-    };
+    }
 
     //update the LFO's time
     LFOParams::time++;
 
-    if (HDDRecorder.recording()) HDDRecorder.recordbuffer(outl,outr);
     dump.inctick();
-};
-
-void Master::GetAudioOutSamples(int nsamples,int samplerate,REALTYPE *outl,REALTYPE *outr)
+}
+
+//TODO review the respective code from yoshimi for this
+//If memory serves correctly, libsamplerate was used
+void Master::GetAudioOutSamples(size_t nsamples,
+                                unsigned samplerate,
+                                float *outl,
+                                float *outr)
 {
-    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];
-
-            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);
-            };
-
-            ksample++;
-
-            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;
-            };
-        };
-    };
-};
+    static float *bufl = new float[synth->buffersize],
+    *bufr = new float[synth->buffersize];
+    static off_t  off  = 0;
+    static size_t smps = 0;
+
+    off_t out_off = 0;
+
+    //Fail when resampling rather than doing a poor job
+    if(synth->samplerate != samplerate) {
+        printf("darn it: %d vs %d\n", synth->samplerate, samplerate);
+        return;
+    }
+
+    while(nsamples) {
+        //use all available samples
+        if(nsamples >= smps) {
+            memcpy(outl + out_off, bufl + off, sizeof(float) * smps);
+            memcpy(outr + out_off, bufr + off, sizeof(float) * smps);
+
+            //generate samples
+            AudioOut(bufl, bufr);
+            off  = 0;
+            smps = synth->buffersize;
 
+            out_off  += smps;
+            nsamples -= smps;
+        }
+        else {   //use some samples
+            memcpy(outl + out_off, bufl + off, sizeof(float) * nsamples);
+            memcpy(outr + out_off, bufr + off, sizeof(float) * nsamples);
+            smps    -= nsamples;
+            off     += nsamples;
+            nsamples = 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;
-    delete [] tmpmixl;
-    delete [] tmpmixr;
-    delete (fft);
+    delete fft;
+    FFT_cleanup();
 
     pthread_mutex_destroy(&mutex);
-};
+    pthread_mutex_destroy(&vumutex);
+}
 
 
 /*
@@ -525,28 +531,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.0f) / 96.0f * 40.0f);
+}
 
 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]  = powf(0.1f, (1.0f - Pvol / 96.0f) * 2.0f);
+}
 
-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]  = powf(0.1f, (1.0f - Pvol / 96.0f) * 2.0f);
+}
 
 
 /*
@@ -554,15 +560,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 +578,88 @@ void Master::ShutUp()
  */
 void Master::vuresetpeaks()
 {
-    vuoutpeakl=1e-9;
-    vuoutpeakr=1e-9;
-    vumaxoutpeakl=1e-9;
-    vumaxoutpeakr=1e-9;
-    vuclipped=0;
-};
-
-
-
-void Master::applyparameters()
+    pthread_mutex_lock(&vumutex);
+    vu.outpeakl    = 1e-9;
+    vu.outpeakr    = 1e-9;
+    vu.maxoutpeakl = 1e-9;
+    vu.maxoutpeakr = 1e-9;
+    vu.clipped     = 0;
+    pthread_mutex_unlock(&vumutex);
+}
+
+vuData Master::getVuData()
+{
+    vuData tmp;
+    pthread_mutex_lock(&vumutex);
+    tmp = vu;
+    pthread_mutex_unlock(&vumutex);
+    return tmp;
+}
+
+void Master::applyparameters(bool lockmutex)
 {
-    for (int npart=0;npart<NUM_MIDI_PARTS;npart++) {
-        part[npart]->applyparameters();
-    };
-};
+    for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
+        part[npart]->applyparameters(lockmutex);
+}
 
 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 +669,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 +691,108 @@ 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
index 69f1a1e..32509a9 100644
--- a/src/Misc/Master.h
+++ b/src/Misc/Master.h
@@ -23,148 +23,153 @@
 
 #ifndef MASTER_H
 #define MASTER_H
-
 #include "../globals.h"
-#include "../Effects/EffectMgr.h"
-#include "Part.h"
-#include "../Output/Recorder.h"
 #include "Microtonal.h"
 
 #include "Bank.h"
+#include "Recorder.h"
 #include "Dump.h"
-#include "../Seq/Sequencer.h"
 #include "XMLwrapper.h"
 
+#include "../Params/Controller.h"
+
+typedef enum {
+    MUTEX_TRYLOCK, MUTEX_LOCK, MUTEX_UNLOCK
+} lockset;
+
 extern Dump dump;
+
+struct vuData {
+    vuData(void);
+    float outpeakl, outpeakr, maxoutpeakl, maxoutpeakr,
+          rmspeakl, rmspeakr;
+    int clipped;
+};
+
+
 /** It sends Midi Messages to Parts, receives samples from parts,
  *  process them with system/insertion effects and mix them */
 class Master
 {
-public:
-    /** Constructor*/
-    Master();
-    /** Destructor*/
-    ~Master();
+    public:
+        /** Constructor TODO make private*/
+        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);
+        static Master &getInstance();
 
-    /**This adds the parameters to the XML data*/
-    void add2XML(XMLwrapper *xml);
+        /**Saves all settings to a XML file
+         * @return 0 for ok or <0 if there is an error*/
+        int saveXML(const char *filename);
 
-    void defaults();
+        /**This adds the parameters to the XML data*/
+        void add2XML(XMLwrapper *xml);
 
+        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();
 
-    void getfromXML(XMLwrapper *xml);
+        /**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(bool lockmutex = true);
 
-    /**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);
+        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);
 
+        //Mutex control
+        /**Control the Master's mutex state.
+         * @param lockset either trylock, lock, or unlock.
+         * @return true when successful false otherwise.*/
+        bool mutexLock(lockset request);
 
-    //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(char chan, char note, char velocity);
+        void noteOff(char chan, char note);
+        void polyphonicAftertouch(char chan, char note, char velocity);
+        void setController(char chan, int type, int par);
+        void setProgram(char chan, unsigned int pgm);
+        //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);
+        void vuUpdate(const float *outl, const float *outr);
 
+        /**Audio Output*/
+        void AudioOut(float *outl, float *outr);
+        /**Audio Output (for callback mode). This allows the program to be controled by an external program*/
+        void GetAudioOutSamples(size_t nsamples,
+                                unsigned samplerate,
+                                float *outl,
+                                float *outr);
 
-    void partonoff(int npart,int what);
 
-    /**parts \todo see if this can be made to be dynamic*/
-    Part *part[NUM_MIDI_PARTS];
+        void partonoff(int npart, int what);
 
-    //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];
+        /**parts \todo see if this can be made to be dynamic*/
+        class Part * part[NUM_MIDI_PARTS];
 
-    //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
 
-    //effects
-    EffectMgr *sysefx[NUM_SYS_EFX];//system
-    EffectMgr *insefx[NUM_INS_EFX];//insertion
-//	void swapcopyeffects(int what,int type,int neff1,int neff2);
+        unsigned char Pvolume;
+        unsigned char Pkeyshift;
+        unsigned char Psysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS];
+        unsigned char Psysefxsend[NUM_SYS_EFX][NUM_SYS_EFX];
 
-    //HDD recorder
-    Recorder HDDRecorder;
+        //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);
 
-    //part that's apply the insertion effect; -1 to disable
-    short int Pinsparts[NUM_INS_EFX];
+        //effects
+        class EffectMgr * sysefx[NUM_SYS_EFX]; //system
+        class EffectMgr * insefx[NUM_INS_EFX]; //insertion
+//      void swapcopyeffects(int what,int type,int neff1,int neff2);
 
-    //peaks for VU-meter
-    void vuresetpeaks();
-    REALTYPE vuoutpeakl,vuoutpeakr,vumaxoutpeakl,vumaxoutpeakr,vurmspeakl,vurmspeakr;
-    int vuclipped;
+        //HDD recorder
+        Recorder HDDRecorder;
 
-    //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
+        //part that's apply the insertion effect; -1 to disable
+        short int Pinsparts[NUM_INS_EFX];
 
-    Controller ctl;
-    int swaplr;//1 if L and R are swapped
 
-    //Sequencer
-    Sequencer seq;
+        //peaks for VU-meter
+        void vuresetpeaks();
+        //get VU-meter data
+        vuData getVuData();
 
-    //other objects
-    Microtonal microtonal;
-    Bank bank;
+        //peaks for part VU-meters
+        /**\todo synchronize this with a mutex*/
+        float vuoutpeakpart[NUM_MIDI_PARTS];
+        unsigned char fakepeakpart[NUM_MIDI_PARTS]; //this is used to compute the "peak" when the part is disabled
 
-    FFTwrapper *fft;
-    pthread_mutex_t mutex;
+        Controller ctl;
+        bool       swaplr; //if L and R are swapped
 
-private:
-    REALTYPE volume;
-    REALTYPE sysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS];
-    REALTYPE sysefxsend[NUM_SYS_EFX][NUM_SYS_EFX];
+        //other objects
+        Microtonal microtonal;
+        Bank       bank;
 
-    //Temporary mixing samples for part samples which is sent to system effect
-    REALTYPE *tmpmixl;
-    REALTYPE *tmpmixr;
+        class FFTwrapper * fft;
+        pthread_mutex_t mutex;
+        pthread_mutex_t vumutex;
 
 
-    int keyshift;
-
-    //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);
-
+    private:
+        bool   nullRun;
+        vuData vu;
+        float  volume;
+        float  sysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS];
+        float  sysefxsend[NUM_SYS_EFX][NUM_SYS_EFX];
+        int    keyshift;
 };
 
-
 #endif
-
diff --git a/src/Misc/Microtonal.cpp b/src/Misc/Microtonal.cpp
index fe90d5e..fc0e015 100644
--- a/src/Misc/Microtonal.cpp
+++ b/src/Misc/Microtonal.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  Microtonal.C - Tuning settings and microtonal capabilities
+  Microtonal.cpp - Tuning settings and microtonal capabilities
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -28,517 +28,667 @@
 
 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.0f;
+    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 = powf(
+                               2,
+                               (i % octavesize
+                                + 1) / 12.0f);
+        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()
+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)
+float 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
+    float globalfinedetunerap = powf(2.0f,
+                                     (Pglobalfinedetune - 64.0f) / 1200.0f);       //-64.0f .. 63.0f cents
 
-    if (Penabled==0) return(pow(2.0,(note-PAnote+keyshift)/12.0)*PAfreq*globalfinedetunerap);//12tET
+    if(Penabled == 0)
+        return powf(2.0f,
+                    (note - PAnote
+                     + keyshift) / 12.0f) * 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);
-    };
+    float rap_keyshift = 1.0f;
+    if(keyshift != 0) {
+        int kskey = (keyshift + (int)octavesize * 100) % octavesize;
+        int ksoct = (keyshift + (int)octavesize * 100) / octavesize - 100;
+        rap_keyshift  = (kskey == 0) ? (1.0f) : (octave[kskey - 1].tuning);
+        rap_keyshift *= powf(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.0f;
         //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++;
+        float rap_anote_middlenote =
+            (deltanote ==
+             0) ? (1.0f) : (octave[(deltanote - 1) % octavesize].tuning);
+        if(deltanote != 0)
+            rap_anote_middlenote *=
+                powf(octave[octavesize - 1].tuning,
+                     (deltanote - 1) / octavesize);
+        if(minus != 0)
+            rap_anote_middlenote = 1.0f / 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.0f;           //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;
-//	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);
-    };
-};
+        degkey  = degkey + scaleshift;
+        degoct += degkey / octavesize;
+        degkey %= octavesize;
+
+        float freq = (degkey == 0) ? (1.0f) : octave[degkey - 1].tuning;
+        freq *= powf(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;
+
+        float oct  = octave[octavesize - 1].tuning;
+        float freq =
+            octave[(ntkey + octavesize - 1) % octavesize].tuning * powf(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(logf(freq/PAfreq)/logf(2.0f)*1200.0f+0.5f));
+        freq *= globalfinedetunerap;
+        return freq * rap_keyshift;
+    }
+}
+
+bool Microtonal::operator==(const Microtonal &micro) const
+{
+    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
+
+    //for floats
+#define FMCREQ(x) if(!((x < micro.x + 0.0001f) && (x > micro.x - 0.0001f))) \
+        return true
+
+    MCREQ(Pinvertupdown);
+    MCREQ(Pinvertupdowncenter);
+    MCREQ(octavesize);
+    MCREQ(Penabled);
+    MCREQ(PAnote);
+    FMCREQ(PAfreq);
+    MCREQ(Pscaleshift);
+
+    MCREQ(Pfirstkey);
+    MCREQ(Plastkey);
+    MCREQ(Pmiddlenote);
+    MCREQ(Pmapsize);
+    MCREQ(Pmappingenabled);
+
+    for(int i = 0; i < 128; ++i)
+        MCREQ(Pmapping[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))
+        return true;
+    if(strcmp((const char *)this->Pcomment, (const char *)micro.Pcomment))
+        return true;
+    MCREQ(Pglobalfinedetune);
+    return false;
+
+    //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;
+    float x  = -1.0f, tmp, tuning = 1.0f;
+    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.000001f)
+                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) {
-    case 1:
-        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;
-        break;
-    };
-
-    tmpoctave[nline].tuning=tuning;
-    tmpoctave[nline].type=type;
-    tmpoctave[nline].x1=x1;
-    tmpoctave[nline].x2=x2;
-
-    return(-1);//ok
-};
+    if((type == 2)
+       && ((x1 > (128 * 128 * 128 - 1)) || (x2 > (128 * 128 * 128 - 1)))) {
+        type = 1;
+        x    = ((float) x1) / x2;
+    }
+    switch(type) {
+        case 1:
+            x1     = (int) floor(x);
+            tmp    = fmod(x, 1.0f);
+            x2     = (int) (floor(tmp * 1e6));
+            tuning = powf(2.0f, x / 1200.0f);
+            break;
+        case 2:
+            x      = ((float)x1) / x2;
+            tuning = x;
+            break;
+    }
+
+    tmpoctave[nline].tuning = tuning;
+    tmpoctave[nline].type   = type;
+    tmpoctave[nline].x1     = x1;
+    tmpoctave[nline].x2     = x2;
+
+    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.%06d", 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;
+    float tmpPAfreq = 440.0f;
+    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)
+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->addparbool("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->getparbool("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);
+    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.0f, 10000.0f);
+
+    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;
+                    //populate fields for display
+                    float x = logf(octave[i].tuning) / LOG_2 * 1200.0f;
+                    octave[i].x1 = (int) floor(x);
+                    octave[i].x2 = (int) (floor(fmodf(x, 1.0f) * 1e6));
+                }
 
-    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(char *filename)
+
+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(char *filename)
+int Microtonal::loadXML(const char *filename)
 {
-    XMLwrapper *xml=new XMLwrapper();
-    if (xml->loadXMLfile(filename)<0) {
-        delete(xml);
-        return(-1);
-    };
-
-    if (xml->enterbranch("MICROTONAL")==0) return(-10);
+    XMLwrapper *xml = new XMLwrapper();
+    if(xml->loadXMLfile(filename) < 0) {
+        delete (xml);
+        return -1;
+    }
+
+    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
index a987da8..638a159 100644
--- a/src/Misc/Microtonal.h
+++ b/src/Misc/Microtonal.h
@@ -35,88 +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);
-
-
-    //Parameters
-    /**if the keys are inversed (the pitch is lower to keys from the right direction) \todo figure out why this is not a bool*/
-    unsigned char Pinvertupdown;
-
-    /**the central key of the inversion*/
-    unsigned char Pinvertupdowncenter;
-
-    /**0 for 12 key temperate scale, 1 for microtonal
-     * \todo find one good reason why this is not a bool*/
-    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];
-
-    unsigned char Pglobalfinedetune;
-
-    // Functions
-    /** Return the current octave size
-     * \todo why is this not an int?*/
-    unsigned char getoctavesize();
-    void tuningtoline(int n,char *line,int maxn);
-    int loadscl(const char *filename);//load the tunnings from a .scl file
-    int loadkbm(const char *filename);//load the mapping from .kbm file
-    int texttotunings(const char *text);
-    void texttomapping(const char *text);
-    unsigned char *Pname;
-    unsigned char *Pcomment;
-
-    void add2XML(XMLwrapper *xml);
-    void getfromXML(XMLwrapper *xml);
-    int saveXML(char *filename);
-    int loadXML(char *filename);
-
-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
+         */
+        float 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*/
+        float 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.05946f for one halftone)
+            // or 2.0f for one octave
+            float 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
index d00d0c3..4054a8e 100644
--- a/src/Misc/Part.cpp
+++ b/src/Misc/Part.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  Part.C - Part implementation
+  Part.cpp - Part implementation
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -22,448 +22,604 @@
 
 #include "Part.h"
 #include "Microtonal.h"
+#include "Util.h"
+#include "XMLwrapper.h"
+#include "../Effects/EffectMgr.h"
+#include "../Params/ADnoteParameters.h"
+#include "../Params/SUBnoteParameters.h"
+#include "../Params/PADnoteParameters.h"
+#include "../Synth/ADnote.h"
+#include "../Synth/SUBnote.h"
+#include "../Synth/PADnote.h"
+#include "../DSP/FFTwrapper.h"
 #include <stdlib.h>
 #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);
-//    ADPartParameters=kit[0].adpars;
-//    SUBPartParameters=kit[0].subpars;
+    microtonal = microtonal_;
+    fft      = fft_;
+    mutex    = mutex_;
+    pthread_mutex_init(&load_mutex, NULL);
+    partoutl = new float [synth->buffersize];
+    partoutr = new float [synth->buffersize];
+
+    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);
 
     //Part's Insertion Effects init
-    for (int nefx=0;nefx<NUM_PART_EFX;nefx++)
-        partefx[nefx]=new EffectMgr(1,mutex);
-
-    for (int n=0;n<NUM_PART_EFX+1;n++) {
-        partfxinputl[n]=new REALTYPE [SOUND_BUFFER_SIZE];
-        partfxinputr[n]=new REALTYPE [SOUND_BUFFER_SIZE];
-        Pefxbypass[n]=false;
-    };
-
-    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();
+    for(int nefx = 0; nefx < NUM_PART_EFX; ++nefx) {
+        partefx[nefx]    = new EffectMgr(1, mutex);
+        Pefxbypass[nefx] = false;
+    }
 
-    Pname=new unsigned char [PART_MAX_NAME_LEN];
+    for(int n = 0; n < NUM_PART_EFX + 1; ++n) {
+        partfxinputl[n] = new float [synth->buffersize];
+        partfxinputr[n] = new float [synth->buffersize];
+    }
 
-    oldvolumel=oldvolumer=0.5;
-    lastnote=-1;
-    lastpos=0; // lastpos will store previously used NoteOn(...)'s pos.
-    lastlegatomodevalid=false; // To store previous legatomodevalid value.
+    killallnotes = 0;
+    oldfreq      = -1.0f;
+
+    for(int i = 0; i < POLIPHONY; ++i) {
+        partnote[i].status = KEY_OFF;
+        partnote[i].note   = -1;
+        partnote[i].itemsplaying = 0;
+        for(int 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];
 
+    oldvolumel = oldvolumer = 0.5f;
+    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
+    }
+}
 
 
 
 /*
  * Cleanup the part
  */
-void Part::cleanup()
+void Part::cleanup(bool final)
 {
-    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 < synth->buffersize; ++i) {
+        partoutl[i] = final ? 0.0f : denormalkillbuf[i];
+        partoutr[i] = final ? 0.0f : denormalkillbuf[i];
+    }
     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 < synth->buffersize; ++i) {
+            partfxinputl[n][i] = final ? 0.0f : denormalkillbuf[i];
+            partfxinputr[n][i] = final ? 0.0f : 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;
+    cleanup(true);
+    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.cpp::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.cpp::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);
+        float vel = VelF(velocity / 127.0f, 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.0f) / 64.0f;
+        if(vel < 0.0f)
+            vel = 0.0f;
+        else
+        if(vel > 1.0f)
+            vel = 1.0f;
 
         //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);
-        };
+        float notebasefreq;
+        if(Pdrummode == 0) {
+            notebasefreq = microtonal->getnotefreq(note, keyshift);
+            if(notebasefreq < 0.0f)
+                return;                  //the key is no mapped
+        }
+        else
+            notebasefreq = 440.0f * powf(2.0f, (note - 69.0f) / 12.0f);
+        ;
 
         //Portamento
-        if (oldfreq<1.0) oldfreq=notebasefreq;//this is only the first note is played
+        if(oldfreq < 1.0f)
+            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->legatonote(notebasefreq,
+                                                                vel,
+                                                                portamento,
+                                                                note,
+                                                                true); //'true' is to tell it it's being called from here.
+                    partnote[posb].kititem[0].adnote->legatonote(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->legatonote(
+                        notebasefreq, vel, portamento, note, true);
+                    partnote[posb].kititem[0].subnote->legatonote(
+                        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->legatonote(
+                        notebasefreq, vel, portamento, note, true);
+                    partnote[posb].kititem[0].padnote->legatonote(
+                        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))
-                        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);
+            }
+            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->legatonote(
+                            notebasefreq, vel, portamento, note, true);
+                        partnote[posb].kititem[ci].adnote->legatonote(
+                            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->legatonote(
+                            notebasefreq, vel, portamento, note, true);
+                        partnote[posb].kititem[ci].subnote->legatonote(
+                            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->legatonote(
+                            notebasefreq, vel, portamento, note, true);
+                        partnote[posb].kititem[ci].padnote->legatonote(
+                            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
+
+                //if this parameter is 127 for "unprocessed"
+                partnote[pos].kititem[ci].sendtoparteffect =
+                    (kit[item].Psendtoparteffect < NUM_PART_EFX ?
+                     kit[item].Psendtoparteffect : NUM_PART_EFX);
+
+                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
@@ -473,107 +629,166 @@ 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);
-
-    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 {
+    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()))
+                    MonoMemRenote();  // To play most recent still held note.
+                else
                     RelaseNotePos(i);
-                    /// break;
-                }
-            } else {//the sustain pedal is pushed
-                partnote[i].status=KEY_RELASED_AND_SUSTAINED;
+                /// break;
             }
+            else    //the sustain pedal is pushed
+                partnote[i].status = KEY_RELASED_AND_SUSTAINED;
         }
-    }
-};
+}
+
+void Part::PolyphonicAftertouch(unsigned char note,
+                                unsigned char velocity,
+                                int masterkeyshift)
+{
+    (void) masterkeyshift;
+    if(!Pnoteon || (note < Pminkey) || (note > Pmaxkey))
+        return;
+    if(Pdrummode)
+        return;
+
+    // MonoMem stuff:
+    if(!Ppolymode)   // if Poly is off
+
+        monomem[note].velocity = velocity;       // Store this note's velocity.
+
+
+    for(int i = 0; i < POLIPHONY; ++i)
+        if((partnote[i].note == note) && (partnote[i].status == KEY_PLAYING)) {
+            /* update velocity */
+            // compute the velocity offset
+            float vel =
+                VelF(velocity / 127.0f, Pvelsns) + (Pveloffs - 64.0f) / 64.0f;
+            vel = (vel < 0.0f) ? 0.0f : vel;
+            vel = (vel > 1.0f) ? 1.0f : vel;
+
+            if(!Pkitmode) { // "normal mode"
+                if(kit[0].Padenabled)
+                    partnote[i].kititem[0].adnote->setVelocity(vel);
+                if(kit[0].Psubenabled)
+                    partnote[i].kititem[0].subnote->setVelocity(vel);
+                if(kit[0].Ppadenabled)
+                    partnote[i].kititem[0].padnote->setVelocity(vel);
+            }
+            else     // "kit mode"
+                for(int item = 0; item < NUM_KIT_ITEMS; ++item) {
+                    if(kit[item].Pmuted)
+                        continue;
+                    if((note < kit[item].Pminkey)
+                       || (note > kit[item].Pmaxkey))
+                        continue;
+
+                    if(kit[item].Padenabled)
+                        partnote[i].kititem[item].adnote->setVelocity(vel);
+                    if(kit[item].Psubenabled)
+                        partnote[i].kititem[item].subnote->setVelocity(vel);
+                    if(kit[item].Ppadenabled)
+                        partnote[i].kititem[item].padnote->setVelocity(vel);
+                }
+        }
+
+}
 
 /*
  * Controllers
  */
-void Part::SetController(unsigned int type,int par)
+void Part::SetController(unsigned int type, int par)
 {
-    switch (type) {
-    case C_pitchwheel:
-        ctl.setpitchwheel(par);
-        break;
-    case C_expression:
-        ctl.setexpression(par);
-        setPvolume(Pvolume);//update the volume
-        break;
-    case C_portamento:
-        ctl.setportamento(par);
-        break;
-    case C_panning:
-        ctl.setpanning(par);
-        setPpanning(Ppanning);//update the panning
-        break;
-    case C_filtercutoff:
-        ctl.setfiltercutoff(par);
-        break;
-    case C_filterq:
-        ctl.setfilterq(par);
-        break;
-    case C_bandwidth:
-        ctl.setbandwidth(par);
-        break;
-    case C_modwheel:
-        ctl.setmodwheel(par);
-        break;
-    case C_fmamp:
-        ctl.setfmamp(par);
-        break;
-    case C_volume:
-        ctl.setvolume(par);
-        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();
-        break;
-    case C_allsoundsoff:
-        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;
-            kit[item].adpars->GlobalPar.Reson->
-            sendcontroller(C_resonance_center,1.0);
-
-            kit[item].adpars->GlobalPar.Reson->
-            sendcontroller(C_resonance_bandwidth,1.0);
-        };
-        //more update to add here if I add controllers
-        break;
-    case C_allnotesoff:
-        RelaseAllKeys();
-        break;
-    case C_resonance_center:
-        ctl.setresonancecenter(par);
-        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);
-        };
-        break;
-    case C_resonance_bandwidth:
-        ctl.setresonancebw(par);
-        kit[0].adpars->GlobalPar.Reson->
-        sendcontroller(C_resonance_bandwidth,ctl.resonancebandwidth.relbw);
-        break;
-    };
-};
+    switch(type) {
+        case C_pitchwheel:
+            ctl.setpitchwheel(par);
+            break;
+        case C_expression:
+            ctl.setexpression(par);
+            setPvolume(Pvolume); //update the volume
+            break;
+        case C_portamento:
+            ctl.setportamento(par);
+            break;
+        case C_panning:
+            ctl.setpanning(par);
+            setPpanning(Ppanning); //update the panning
+            break;
+        case C_filtercutoff:
+            ctl.setfiltercutoff(par);
+            break;
+        case C_filterq:
+            ctl.setfilterq(par);
+            break;
+        case C_bandwidth:
+            ctl.setbandwidth(par);
+            break;
+        case C_modwheel:
+            ctl.setmodwheel(par);
+            break;
+        case C_fmamp:
+            ctl.setfmamp(par);
+            break;
+        case C_volume:
+            ctl.setvolume(par);
+            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();
+            break;
+        case C_allsoundsoff:
+            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;
+                kit[item].adpars->GlobalPar.Reson->
+                sendcontroller(C_resonance_center, 1.0f);
+
+                kit[item].adpars->GlobalPar.Reson->
+                sendcontroller(C_resonance_bandwidth, 1.0f);
+            }
+            //more update to add here if I add controllers
+            break;
+        case C_allnotesoff:
+            RelaseAllKeys();
+            break;
+        case C_resonance_center:
+            ctl.setresonancecenter(par);
+            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);
+            }
+            break;
+        case C_resonance_bandwidth:
+            ctl.setresonancebw(par);
+            kit[0].adpars->GlobalPar.Reson->
+            sendcontroller(C_resonance_bandwidth, ctl.resonancebandwidth.relbw);
+            break;
+    }
+}
 /*
  * Relase the sustained keys
  */
@@ -581,13 +796,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.
-            MonoMemRenote(); // To play most recent still held note.
+    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
@@ -595,25 +811,23 @@ 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);
-    }
 }
 
 /*
@@ -621,23 +835,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;
+}
 
 
 /*
@@ -645,30 +857,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;
+    }
+}
 
 
 /*
@@ -676,30 +888,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;
+        if(notecount > keylimit)   //find out the oldest note
+            for(int i = 0; i < POLIPHONY; ++i) {
+                int maxtime = 0;
+                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);
+    }
+}
 
 
 /*
@@ -707,275 +923,258 @@ void Part::setkeylimit(unsigned char Pkeylimit)
  */
 void Part::AllNotesOff()
 {
-    killallnotes=1;
-};
+    killallnotes = 1;
+}
+
+void Part::RunNote(unsigned int k)
+{
+    unsigned noteplay = 0;
+    for(int item = 0; item < partnote[k].itemsplaying; ++item) {
+        int sendcurrenttofx = partnote[k].kititem[item].sendtoparteffect;
+
+        for(unsigned type = 0; type < 3; ++type) {
+            //Select a note
+            SynthNote **note;
+            if(type == 0)
+                note = &partnote[k].kititem[item].adnote;
+            else
+            if(type == 1)
+                note = &partnote[k].kititem[item].subnote;
+            else
+            if(type == 2)
+                note = &partnote[k].kititem[item].padnote;
+
+            //Process if it exists
+            if(!(*note))
+                continue;
+            noteplay++;
 
+            float *tmpoutr = getTmpBuffer();
+            float *tmpoutl = getTmpBuffer();
+            (*note)->noteout(&tmpoutl[0], &tmpoutr[0]);
+
+            if((*note)->finished()) {
+                delete (*note);
+                (*note) = NULL;
+            }
+            for(int i = 0; i < synth->buffersize; ++i) { //add the note to part(mix)
+                partfxinputl[sendcurrenttofx][i] += tmpoutl[i];
+                partfxinputr[sendcurrenttofx][i] += tmpoutr[i];
+            }
+            returnTmpBuffer(tmpoutr);
+            returnTmpBuffer(tmpoutl);
+        }
+    }
+
+    //Kill note if there is no synth on that note
+    if(noteplay == 0)
+        KillNotePos(k);
+}
 
 /*
  * Compute Part samples and store them in the partoutl[] and partoutr[]
  */
 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;
+    for(unsigned nefx = 0; nefx < NUM_PART_EFX + 1; ++nefx)
+        for(int i = 0; i < synth->buffersize; ++i) {
+            partfxinputl[nefx][i] = 0.0f;
+            partfxinputr[nefx][i] = 0.0f;
+        }
+
+    for(unsigned k = 0; k < POLIPHONY; ++k) {
+        if(partnote[k].status == KEY_OFF)
+            continue;
         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++) {
-
-            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;
-            //get from the ADnote
-            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) {
-                    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];
-                };
-            };
-            //get from the SUBnote
-            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) {
-                    delete (subnote);
-                    partnote[k].kititem[item].subnote=NULL;
-                };
-            };
-            //get from the PADnote
-            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) {
-                    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];
-                };
-            };
-
-        };
-        //Kill note if there is no synth on that note
-        if (noteplay==0) KillNotePos(k);
-    };
+        RunNote(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(int i = 0; i < synth->buffersize; ++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(int i = 0; i < synth->buffersize; ++i) {
+            partfxinputl[routeto][i] += partfxinputl[nefx][i];
+            partfxinputr[routeto][i] += partfxinputr[nefx][i];
+        }
+    }
+    for(int i = 0; i < synth->buffersize; ++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(int i = 0; i < synth->buffersize; ++i) {
+            float tmp = (synth->buffersize_f - i) / synth->buffersize_f;
+            partoutl[i] *= tmp;
+            partoutr[i] *= tmp;
+        }
+        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.0f) / 96.0f * 40.0f) * 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.0f + ctl.panning.pan;
+    if(panning < 0.0f)
+        panning = 0.0f;
+    else
+    if(panning > 1.0f)
+        panning = 1.0f;
+}
 
 /*
  * 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);
-    };
-
-    if (resetallnotes) 	for (int k=0;k<POLIPHONY;k++) KillNotePos(k);
-};
-
+            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);
+}
 
 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);
@@ -984,154 +1183,160 @@ void Part::add2XML(XMLwrapper *xml)
     xml->beginbranch("CONTROLLER");
     ctl.add2XML(xml);
     xml->endbranch();
-};
+}
 
-int Part::saveXML(char *filename)
+int Part::saveXML(const 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)
+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()
+void Part::applyparameters(bool lockmutex) /*{*/
 {
-    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(lockmutex);
+} /*}*/
 
 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
index 1ac12a5..4221f28 100644
--- a/src/Misc/Part.h
+++ b/src/Misc/Part.h
@@ -26,177 +26,176 @@
 #define MAX_INFO_TEXT_SIZE 1000
 
 #include "../globals.h"
-#include "../Params/ADnoteParameters.h"
-#include "../Params/SUBnoteParameters.h"
-#include "../Params/PADnoteParameters.h"
-#include "../Synth/ADnote.h"
-#include "../Synth/SUBnote.h"
-#include "../Synth/PADnote.h"
 #include "../Params/Controller.h"
 #include "../Misc/Microtonal.h"
-#include "../DSP/FFTwrapper.h"
-#include "../Effects/EffectMgr.h"
-#include "XMLwrapper.h"
 
 #include <list> // For the monomemnotes list.
 
+class EffectMgr;
+class ADnoteParameters;
+class SUBnoteParameters;
+class PADnoteParameters;
+class SynthNote;
+class XMLWrapper;
+class FFTwrapper;
+
 /** 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
-
-    /* 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)
-
-
-    //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 defaults();
-    void defaultsinstrument();
-
-    void applyparameters();
-
-    void getfromXML(XMLwrapper *xml);
-    void getfromXMLinstrument(XMLwrapper *xml);
-
-    void cleanup();
-
-//      ADnoteParameters *ADPartParameters;
-//      SUBnoteParameters *SUBPartParameters;
+        // Midi commands implemented
+        void NoteOn(unsigned char note,
+                    unsigned char velocity,
+                    int masterkeyshift);
+        void NoteOff(unsigned char note);
+        void PolyphonicAftertouch(unsigned char note,
+                                  unsigned char velocity,
+                                  int masterkeyshift);
+        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 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];
+        /* 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)
 
-    //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)
+        //saves the instrument settings to a XML file
+        //returns 0 for ok or <0 if there is an error
+        int saveXML(const char *filename);
+        int loadXMLinstrument(const char *filename);
 
-    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
+        void add2XML(XMLwrapper *xml);
+        void add2XMLinstrument(XMLwrapper *xml);
 
-    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;
+        void defaults();
+        void defaultsinstrument();
 
+        void applyparameters(bool lockmutex = true);
 
-    REALTYPE *partoutl;//Left channel output of the part
-    REALTYPE *partoutr;//Right channel output of the part
+        void getfromXML(XMLwrapper *xml);
+        void getfromXMLinstrument(XMLwrapper *xml);
 
-    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
+        void cleanup(bool final = false);
 
-    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 {
-            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      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;
+
+
+        float *partoutl; //Left channel output of the part
+        float *partoutr; //Right channel output of the part
+
+        float *partfxinputl[NUM_PART_EFX + 1], //Left and right signal that pass thru part effects;
+        *partfxinputr[NUM_PART_EFX + 1];          //partfxinput l/r [NUM_PART_EFX] is for "no effect" buffer
+
+        enum NoteStatus {
+            KEY_OFF, KEY_PLAYING, KEY_RELASED_AND_SUSTAINED, KEY_RELASED
+        };
+
+        float volume, oldvolumel, oldvolumer; //this is applied by Master
+        float 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;
+        pthread_mutex_t load_mutex;
+
+        int lastnote;
+
+    private:
+        void RunNote(unsigned k);
+        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 {
+                SynthNote *adnote,
+                   *subnote,
+                   *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];
+
+        float oldfreq;    //this is used for portamento
+        Microtonal *microtonal;
+        FFTwrapper *fft;
 };
 
 #endif
-
diff --git a/src/Misc/Recorder.cpp b/src/Misc/Recorder.cpp
new file mode 100644
index 0000000..78aef06
--- /dev/null
+++ b/src/Misc/Recorder.cpp
@@ -0,0 +1,93 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  Recorder.cpp - Records sound to a file
+  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 <sys/stat.h>
+#include "Recorder.h"
+#include "WavFile.h"
+#include "../Nio/OutMgr.h"
+#include "../Nio/WavEngine.h"
+
+Recorder::Recorder()
+    :status(0), notetrigger(0)
+{}
+
+Recorder::~Recorder()
+{
+    if(recording() == 1)
+        stop();
+}
+
+int Recorder::preparefile(std::string filename_, int overwrite)
+{
+    if(!overwrite) {
+        struct stat fileinfo;
+        int statr;
+        statr = stat(filename_.c_str(), &fileinfo);
+        if(statr == 0)   //file exists
+            return 1;
+    }
+
+    OutMgr::getInstance(). wave->newFile(new WavFile(filename_,
+                                                     synth->samplerate, 2));
+
+    status = 1; //ready
+
+    return 0;
+}
+
+void Recorder::start()
+{
+    notetrigger = 0;
+    status      = 2; //recording
+}
+
+void Recorder::stop()
+{
+    OutMgr::getInstance(). wave->Stop();
+    OutMgr::getInstance(). wave->destroyFile();
+    status = 0;
+}
+
+void Recorder::pause()
+{
+    status = 0;
+    OutMgr::getInstance(). wave->Stop();
+}
+
+int Recorder::recording()
+{
+    if((status == 2) && (notetrigger != 0))
+        return 1;
+    else
+        return 0;
+}
+
+void Recorder::triggernow()
+{
+    if(status == 2) {
+        if(notetrigger != 1)
+            OutMgr::getInstance().wave->Start();
+        notetrigger = 1;
+    }
+}
+
+//TODO move recorder inside nio system
diff --git a/src/Misc/Recorder.h b/src/Misc/Recorder.h
new file mode 100644
index 0000000..0e3f02f
--- /dev/null
+++ b/src/Misc/Recorder.h
@@ -0,0 +1,54 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  Recorder.h - Records sound to a file
+  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 RECORDER_H
+#define RECORDER_H
+#include <string>
+#include "../globals.h"
+
+/**Records sound to a file*/
+class Recorder
+{
+    public:
+
+        Recorder();
+        ~Recorder();
+        /**Prepare the given file.
+         * @returns 1 if the file exists */
+        int preparefile(std::string filename_, int overwrite);
+        void start();
+        void stop();
+        void pause();
+        int recording();
+        void triggernow();
+
+        /** Status:
+         *  0 - not ready(no file selected),
+         *  1 - ready
+         *  2 - recording */
+        int status;
+
+    private:
+        int notetrigger;
+};
+
+#endif
diff --git a/src/Misc/Stereo.cpp b/src/Misc/Stereo.cpp
index fde2960..ac2f317 100644
--- a/src/Misc/Stereo.cpp
+++ b/src/Misc/Stereo.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  Stereo.C - Object for storing a pair of objects
+  Stereo.cpp - Object for storing a pair of objects
   Copyright (C) 2009-2009 Mark McCurry
   Author: Mark McCurry
 
@@ -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)
+    :l(left), r(right)
 {}
 
-template <class T>
+template<class T>
 Stereo<T>::Stereo(const T &val)
-        :leftChannel(val),rightChannel(val)
+    :l(val), r(val)
 {}
 
-template <class T>
-void Stereo<T>::operator=(const Stereo<T> & nstr)
+template<class T>
+Stereo<T> &Stereo<T>::operator=(const Stereo<T> &nstr)
 {
-    leftChannel=nstr.leftChannel;
-    rightChannel=nstr.rightChannel;
+    l = nstr.l;
+    r = nstr.r;
+    return *this;
 }
diff --git a/src/Misc/Stereo.h b/src/Misc/Stereo.h
index b9c71b3..516d318 100644
--- a/src/Misc/Stereo.h
+++ b/src/Misc/Stereo.h
@@ -21,47 +21,20 @@
 #ifndef STEREO_H
 #define STEREO_H
 
-template <class T>
-class Stereo
-{
-public:
-    Stereo(const T &left,const T &right);
+template<class T>
+struct Stereo {
+    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() {};
+        /**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;
+        Stereo<T> &operator=(const Stereo<T> &smp);
 
+        //data
+        T l, r;
 };
 #include "Stereo.cpp"
 #endif
-
diff --git a/src/Misc/Util.cpp b/src/Misc/Util.cpp
index 5069a9e..d75ab2f 100644
--- a/src/Misc/Util.cpp
+++ b/src/Misc/Util.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  Util.C - Miscellaneous functions
+  Util.cpp - Miscellaneous functions
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -21,8 +21,11 @@
 */
 
 #include "Util.h"
+#include <vector>
+#include <cassert>
 #include <math.h>
 #include <stdio.h>
+#include <err.h>
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -30,93 +33,190 @@
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
+#include <sched.h>
 
-int SAMPLE_RATE=44100;
-int SOUND_BUFFER_SIZE=256;
-int OSCIL_SIZE=1024;
+
+prng_t prng_state = 0x1234;
 
 Config config;
-REALTYPE *denormalkillbuf;
+float *denormalkillbuf;
 
 
 /*
  * Transform the velocity according the scaling parameter (velocity sensing)
  */
-REALTYPE VelF(REALTYPE velocity,unsigned char scaling)
+float VelF(float 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));
-};
+    float x;
+    x = powf(VELOCITY_MAX_SCALE, (64.0f - scaling) / 64.0f);
+    if((scaling == 127) || (velocity > 0.99f))
+        return 1.0f;
+    else
+        return powf(velocity, x);
+}
 
 /*
  * Get the detune in cents
  */
-REALTYPE getdetune(unsigned char type,unsigned short int coarsedetune,unsigned short int finedetune)
+float 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;
+    float det = 0.0f, octdet = 0.0f, cdet = 0.0f, findet = 0.0f;
     //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.0f;
 
     //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;
-        break;
-    case 3:
-        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;
-        break;
+        case 2:
+            cdet   = fabs(cdetune * 10.0f);
+            findet = fabs(fdetune / 8192.0f) * 10.0f;
+            break;
+        case 3:
+            cdet   = fabs(cdetune * 100);
+            findet = powf(10, fabs(fdetune / 8192.0f) * 3.0f) / 10.0f - 0.1f;
+            break;
+        case 4:
+            cdet   = fabs(cdetune * 701.95500087f); //perfect fifth
+            findet =
+                (powf(2, fabs(fdetune / 8192.0f) * 12.0f) - 1.0f) / 4095 * 1200;
+            break;
         //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"
-        break;
-    };
-    if (finedetune<8192) findet=-findet;
-    if (cdetune<0) cdet=-cdet;
-
-    det=octdet+cdet+findet;
-    return(det);
-};
+        default:
+            cdet   = fabs(cdetune * 50.0f);
+            findet = fabs(fdetune / 8192.0f) * 35.0f; //almost like "Paul's Sound Designer 2"
+            break;
+    }
+    if(finedetune < 8192)
+        findet = -findet;
+    if(cdetune < 0)
+        cdet = -cdet;
+
+    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;
+}
 
-void newFFTFREQS(FFTFREQS *f,int size)
+void set_realtime()
 {
-    f->c=new REALTYPE[size];
-    f->s=new REALTYPE[size];
-    for (int i=0;i<size;i++) {
-        f->c[i]=0.0;
-        f->s[i]=0.0;
-    };
-};
-void deleteFFTFREQS(FFTFREQS *f)
+    sched_param sc;
+    sc.sched_priority = 60;
+    //if you want get "sched_setscheduler undeclared" from compilation,
+    //you can safely remove the folowing line:
+    sched_setscheduler(0, SCHED_FIFO, &sc);
+    //if (err==0) printf("Real-time");
+}
+
+void os_sleep(long length)
+{
+    usleep(length);
+}
+
+std::string legalizeFilename(std::string filename)
 {
-    delete[] f->c;
-    delete[] f->s;
-    f->c=f->s=NULL;
+    for(int i = 0; i < (int) filename.size(); ++i) {
+        char c = filename[i];
+        if(!(isdigit(c) || isalpha(c) || (c == '-') || (c == ' ')))
+            filename[i] = '_';
+    }
+    return filename;
+}
+
+void invSignal(float *sig, size_t len)
+{
+    for(size_t i = 0; i < len; ++i)
+        sig[i] *= -1.0f;
+}
+
+//Some memory pools for short term buffer use
+//(avoid the use of new in RT thread(s))
+
+struct pool_entry {
+    bool   free;
+    float *dat;
 };
+typedef std::vector<pool_entry> pool_t;
+typedef pool_t::iterator        pool_itr_t;
+
+pool_t pool;
 
+float *getTmpBuffer()
+{
+    for(pool_itr_t itr = pool.begin(); itr != pool.end(); ++itr)
+        if(itr->free) { //Use Pool
+            itr->free = false;
+            return itr->dat;
+        }
+    pool_entry p; //Extend Pool
+    p.free = false;
+    p.dat  = new float[synth->buffersize];
+    pool.push_back(p);
+
+    return p.dat;
+}
+
+void returnTmpBuffer(float *buf)
+{
+    for(pool_itr_t itr = pool.begin(); itr != pool.end(); ++itr)
+        if(itr->dat == buf) { //Return to Pool
+            itr->free = true;
+            return;
+        }
+    fprintf(stderr,
+            "ERROR: invalid buffer returned %s %d\n",
+            __FILE__,
+            __LINE__);
+}
+
+void clearTmpBuffers(void)
+{
+    for(pool_itr_t itr = pool.begin(); itr != pool.end(); ++itr) {
+        if(!itr->free) //Warn about used buffers
+            warn("Temporary buffer (%p) about to be freed may be in use",
+                 itr->dat);
+        delete [] itr->dat;
+    }
+    pool.clear();
+}
+
+float SYNTH_T::numRandom() const
+{
+    return RND;
+}
+
+float interpolate(const float *data, size_t len, float pos)
+{
+    assert(len > (size_t)pos + 1);
+    const int l_pos      = (int)pos,
+              r_pos      = l_pos + 1;
+    const float leftness = pos - l_pos;
+    return data[l_pos] * leftness + data[r_pos] * (1.0f - leftness);
+}
+
+float cinterpolate(const float *data, size_t len, float pos)
+{
+    const int l_pos      = ((int)pos) % len,
+              r_pos      = (l_pos + 1) % len;
+    const float leftness = pos - l_pos;
+    return data[l_pos] * leftness + data[r_pos] * (1.0f - leftness);
+}
diff --git a/src/Misc/Util.h b/src/Misc/Util.h
index 66c313b..1c1545d 100644
--- a/src/Misc/Util.h
+++ b/src/Misc/Util.h
@@ -23,23 +23,101 @@
 #ifndef UTIL_H
 #define UTIL_H
 
-#include <pthread.h>
-#include "../globals.h"
-#include "Microtonal.h"
-#include "../DSP/FFTwrapper.h"
+#include <string>
+#include <sstream>
+#include <stdint.h>
 #include "Config.h"
+#include "../globals.h"
 
 //Velocity Sensing function
-extern REALTYPE VelF(REALTYPE velocity,unsigned char scaling);
+extern float VelF(float 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 float 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*/
+/**Try to set current thread to realtime priority program priority
+ * \todo see if the right pid is being sent
+ * \todo see if this is having desired effect, if not then look at
+ * pthread_attr_t*/
+void set_realtime();
 
-extern Config config;
+/**Os independent sleep in microsecond*/
+void os_sleep(long length);
 
-#endif
+std::string legalizeFilename(std::string filename);
+
+extern float *denormalkillbuf; /**<the buffer to add noise in order to avoid denormalisation*/
+
+extern class Config config;
+
+void invSignal(float *sig, size_t len);
+
+//Memory pool for temporary buffers
+//No allocation in *normal* case
+//All should be sized to synth->buffersize
+float *getTmpBuffer();
+void returnTmpBuffer(float *buf);
+void clearTmpBuffers(void);
+
+template<class T>
+std::string stringFrom(T x)
+{
+    std::stringstream ss;
+    ss << x;
+    return ss.str();
+}
+
+template<class T>
+T stringTo(const char *x)
+{
+    std::string str = x != NULL ? x : "0"; //should work for the basic float/int
+    std::stringstream ss(str);
+    T ans;
+    ss >> ans;
+    return ans;
+}
+
+template<class T>
+T limit(T val, T min, T max)
+{
+    return val < min ? min : (val > max ? max : val);
+}
 
+//Random number generator
+
+typedef uint32_t prng_t;
+extern prng_t prng_state;
+
+// Portable Pseudo-Random Number Generator
+inline prng_t prng_r(prng_t &p)
+{
+    return p = p * 1103515245 + 12345;
+}
+
+inline prng_t prng(void)
+{
+    return prng_r(prng_state) & 0x7fffffff;
+}
+
+inline void sprng(prng_t p)
+{
+    prng_state = p;
+}
+
+/*
+ * The random generator (0.0f..1.0f)
+ */
+# define INT32_MAX      (2147483647)
+#define RND (prng() / (INT32_MAX * 1.0f))
+
+//Linear Interpolation
+float interpolate(const float *data, size_t len, float pos);
+
+//Linear circular interpolation
+float cinterpolate(const float *data, size_t len, float pos);
+
+#endif
diff --git a/src/Misc/WavFile.cpp b/src/Misc/WavFile.cpp
new file mode 100644
index 0000000..78db9d5
--- /dev/null
+++ b/src/Misc/WavFile.cpp
@@ -0,0 +1,97 @@
+/*
+  Copyright (C) 2006 Nasca Octavian Paul
+  Author: Nasca Octavian Paul
+          Mark McCurry
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License (version 2) for more details.
+
+  You should have received a copy of the GNU General Public License (version 2)
+  along with this program; if not, write to the Free Software Foundation,
+  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+*/
+
+#include <cstdio>
+#include <cstring>
+#include <cstdlib>
+#include <iostream>
+#include "WavFile.h"
+using namespace std;
+
+WavFile::WavFile(string filename, int samplerate, int channels)
+    :sampleswritten(0), samplerate(samplerate), channels(channels),
+      file(fopen(filename.c_str(), "w"))
+
+{
+    if(file) {
+        cout << "INFO: Making space for wave file header" << endl;
+        //making space for the header written at destruction
+        char tmp[44];
+        memset(tmp, 0, 44 * sizeof(char));
+        fwrite(tmp, 1, 44, file);
+    }
+}
+
+WavFile::~WavFile()
+{
+    if(file) {
+        cout << "INFO: Writing wave file header" << endl;
+
+        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);
+
+        fclose(file);
+        file = NULL;
+    }
+}
+
+bool WavFile::good() const
+{
+    return file;
+}
+
+void WavFile::writeStereoSamples(int nsmps, short int *smps)
+{
+    if(file) {
+        fwrite(smps, nsmps, 4, file);
+        sampleswritten += nsmps;
+    }
+}
+
+void WavFile::writeMonoSamples(int nsmps, short int *smps)
+{
+    if(file) {
+        fwrite(smps, nsmps, 2, file);
+        sampleswritten += nsmps;
+    }
+}
diff --git a/src/Misc/WavFile.h b/src/Misc/WavFile.h
new file mode 100644
index 0000000..4b29efa
--- /dev/null
+++ b/src/Misc/WavFile.h
@@ -0,0 +1,44 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  WavFile.h - Records sound to a file
+  Copyright (C) 2008 Nasca Octavian Paul
+  Author: Nasca Octavian Paul
+          Mark McCurry
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License (version 2) for more details.
+
+  You should have received a copy of the GNU General Public License (version 2)
+  along with this program; if not, write to the Free Software Foundation,
+  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+*/
+
+#ifndef WAVFILE_H
+#define WAVFILE_H
+#include <string>
+
+class WavFile
+{
+    public:
+        WavFile(std::string filename, int samplerate, int channels);
+        ~WavFile();
+
+        bool good() const;
+
+        void writeMonoSamples(int nsmps, short int *smps);
+        void writeStereoSamples(int nsmps, short int *smps);
+
+    private:
+        int   sampleswritten;
+        int   samplerate;
+        int   channels;
+        FILE *file;
+};
+#endif
diff --git a/src/Misc/WaveShapeSmps.cpp b/src/Misc/WaveShapeSmps.cpp
new file mode 100644
index 0000000..cf28129
--- /dev/null
+++ b/src/Misc/WaveShapeSmps.cpp
@@ -0,0 +1,189 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  WaveShapeSmps.cpp - Sample Distortion
+  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 "WaveShapeSmps.h"
+#include <cmath>
+
+void waveShapeSmps(int n,
+                   float *smps,
+                   unsigned char type,
+                   unsigned char drive)
+{
+    int   i;
+    float ws = drive / 127.0f;
+    float tmpv;
+
+    switch(type) {
+        case 1:
+            ws = powf(10, ws * ws * 3.0f) - 1.0f + 0.001f; //Arctangent
+            for(i = 0; i < n; ++i)
+                smps[i] = atanf(smps[i] * ws) / atanf(ws);
+            break;
+        case 2:
+            ws = ws * ws * 32.0f + 0.0001f; //Asymmetric
+            if(ws < 1.0f)
+                tmpv = sinf(ws) + 0.1f;
+            else
+                tmpv = 1.1f;
+            for(i = 0; i < n; ++i)
+                smps[i] = sinf(smps[i] * (0.1f + ws - ws * smps[i])) / tmpv;
+            ;
+            break;
+        case 3:
+            ws = ws * ws * ws * 20.0f + 0.0001f; //Pow
+            for(i = 0; i < n; ++i) {
+                smps[i] *= ws;
+                if(fabs(smps[i]) < 1.0f) {
+                    smps[i] = (smps[i] - powf(smps[i], 3.0f)) * 3.0f;
+                    if(ws < 1.0f)
+                        smps[i] /= ws;
+                }
+                else
+                    smps[i] = 0.0f;
+            }
+            break;
+        case 4:
+            ws = ws * ws * ws * 32.0f + 0.0001f; //Sine
+            if(ws < 1.57f)
+                tmpv = sinf(ws);
+            else
+                tmpv = 1.0f;
+            for(i = 0; i < n; ++i)
+                smps[i] = sinf(smps[i] * ws) / tmpv;
+            break;
+        case 5:
+            ws = ws * ws + 0.000001f; //Quantisize
+            for(i = 0; i < n; ++i)
+                smps[i] = floor(smps[i] / ws + 0.5f) * ws;
+            break;
+        case 6:
+            ws = ws * ws * ws * 32 + 0.0001f; //Zigzag
+            if(ws < 1.0f)
+                tmpv = sinf(ws);
+            else
+                tmpv = 1.0f;
+            for(i = 0; i < n; ++i)
+                smps[i] = asinf(sinf(smps[i] * ws)) / tmpv;
+            break;
+        case 7:
+            ws = powf(2.0f, -ws * ws * 8.0f); //Limiter
+            for(i = 0; i < n; ++i) {
+                float tmp = smps[i];
+                if(fabs(tmp) > ws) {
+                    if(tmp >= 0.0f)
+                        smps[i] = 1.0f;
+                    else
+                        smps[i] = -1.0f;
+                }
+                else
+                    smps[i] /= ws;
+            }
+            break;
+        case 8:
+            ws = powf(2.0f, -ws * ws * 8.0f); //Upper Limiter
+            for(i = 0; i < n; ++i) {
+                float tmp = smps[i];
+                if(tmp > ws)
+                    smps[i] = ws;
+                smps[i] *= 2.0f;
+            }
+            break;
+        case 9:
+            ws = powf(2.0f, -ws * ws * 8.0f); //Lower Limiter
+            for(i = 0; i < n; ++i) {
+                float tmp = smps[i];
+                if(tmp < -ws)
+                    smps[i] = -ws;
+                smps[i] *= 2.0f;
+            }
+            break;
+        case 10:
+            ws = (powf(2.0f, ws * 6.0f) - 1.0f) / powf(2.0f, 6.0f); //Inverse Limiter
+            for(i = 0; i < n; ++i) {
+                float tmp = smps[i];
+                if(fabs(tmp) > ws) {
+                    if(tmp >= 0.0f)
+                        smps[i] = tmp - ws;
+                    else
+                        smps[i] = tmp + ws;
+                }
+                else
+                    smps[i] = 0;
+            }
+            break;
+        case 11:
+            ws = powf(5, ws * ws * 1.0f) - 1.0f; //Clip
+            for(i = 0; i < n; ++i)
+                smps[i] = smps[i]
+                          * (ws + 0.5f) * 0.9999f - floor(
+                    0.5f + smps[i] * (ws + 0.5f) * 0.9999f);
+            break;
+        case 12:
+            ws = ws * ws * ws * 30 + 0.001f; //Asym2
+            if(ws < 0.3f)
+                tmpv = ws;
+            else
+                tmpv = 1.0f;
+            for(i = 0; i < n; ++i) {
+                float tmp = smps[i] * ws;
+                if((tmp > -2.0f) && (tmp < 1.0f))
+                    smps[i] = tmp * (1.0f - tmp) * (tmp + 2.0f) / tmpv;
+                else
+                    smps[i] = 0.0f;
+            }
+            break;
+        case 13:
+            ws = ws * ws * ws * 32.0f + 0.0001f; //Pow2
+            if(ws < 1.0f)
+                tmpv = ws * (1 + ws) / 2.0f;
+            else
+                tmpv = 1.0f;
+            for(i = 0; i < n; ++i) {
+                float tmp = smps[i] * ws;
+                if((tmp > -1.0f) && (tmp < 1.618034f))
+                    smps[i] = tmp * (1.0f - tmp) / tmpv;
+                else
+                if(tmp > 0.0f)
+                    smps[i] = -1.0f;
+                else
+                    smps[i] = -2.0f;
+            }
+            break;
+        case 14:
+            ws = powf(ws, 5.0f) * 80.0f + 0.0001f; //sigmoid
+            if(ws > 10.0f)
+                tmpv = 0.5f;
+            else
+                tmpv = 0.5f - 1.0f / (expf(ws) + 1.0f);
+            for(i = 0; i < n; ++i) {
+                float tmp = smps[i] * ws;
+                if(tmp < -10.0f)
+                    tmp = -10.0f;
+                else
+                if(tmp > 10.0f)
+                    tmp = 10.0f;
+                tmp     = 0.5f - 1.0f / (expf(tmp) + 1.0f);
+                smps[i] = tmp / tmpv;
+            }
+            break;
+    }
+}
diff --git a/src/Misc/WaveShapeSmps.h b/src/Misc/WaveShapeSmps.h
new file mode 100644
index 0000000..980eb28
--- /dev/null
+++ b/src/Misc/WaveShapeSmps.h
@@ -0,0 +1,31 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  WaveShapeSmps.h - Sample distortions
+  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 WAVESHAPESMPS_H
+#define WAVESHAPESMPS_H
+
+//Waveshaping(called by Distorsion effect and waveshape from OscilGen)
+void waveShapeSmps(int n,
+                   float *smps,
+                   unsigned char type,
+                   unsigned char drive);
+
+#endif
diff --git a/src/Misc/XMLwrapper.cpp b/src/Misc/XMLwrapper.cpp
index 2731d41..0fd40f3 100644
--- a/src/Misc/XMLwrapper.cpp
+++ b/src/Misc/XMLwrapper.cpp
@@ -1,9 +1,11 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  XMLwrapper.C - XML wrapper
+  XMLwrapper.cpp - XML wrapper
   Copyright (C) 2003-2005 Nasca Octavian Paul
+  Copyright (C) 2009-2009 Mark McCurry
   Author: Nasca Octavian Paul
+          Mark McCurry
 
   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
@@ -21,547 +23,601 @@
 */
 
 #include "XMLwrapper.h"
+#include <cstring>
 #include <stdio.h>
 #include <stdlib.h>
+#include <cstdarg>
 #include <zlib.h>
+#include <iostream>
+#include <sstream>
 
 #include "../globals.h"
 #include "Util.h"
 
 using namespace std;
 
-int xml_k=0;
-char tabs[STACKSIZE+2];
+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));
+}
 
-XMLwrapper::XMLwrapper()
+//temporary const overload of mxmlElementGetAttr
+const char *mxmlElementGetAttr(const mxml_node_t *node, const char *name)
 {
-    ZERO(&parentstack,(int)sizeof(parentstack));
-    ZERO(&values,(int)sizeof(values));
+    return mxmlElementGetAttr(const_cast<mxml_node_t *>(node), name);
+}
 
-    minimal=true;
-    stackpos=0;
+XMLwrapper::XMLwrapper()
+{
+    version.Major    = 2;
+    version.Minor    = 4;
+    version.Revision = 3;
 
-    information.PADsynth_used=false;
+    minimal = true;
 
-    tree=mxmlNewElement(MXML_NO_PARENT,"?xml version=\"1.0\" encoding=\"UTF-8\"?");
-    /*  for mxml 2.1 (and older)
+    node = tree = mxmlNewElement(MXML_NO_PARENT,
+                                 "?xml version=\"1.0f\" encoding=\"UTF-8\"?");
+    /*  for mxml 2.1f (and older)
         tree=mxmlNewElement(MXML_NO_PARENT,"?xml");
-        mxmlElementSetAttr(tree,"version","1.0");
+        mxmlElementSetAttr(tree,"version","1.0f");
         mxmlElementSetAttr(tree,"encoding","UTF-8");
     */
 
-    mxml_node_t *doctype=mxmlNewElement(tree,"!DOCTYPE");
-    mxmlElementSetAttr(doctype,"ZynAddSubFX-data",NULL);
-
-    node=root=mxmlNewElement(tree,"ZynAddSubFX-data");
+    mxml_node_t *doctype = mxmlNewElement(tree, "!DOCTYPE");
+    mxmlElementSetAttr(doctype, "ZynAddSubFX-data", NULL);
 
-    mxmlElementSetAttr(root,"version-major","1");
-    mxmlElementSetAttr(root,"version-minor","1");
-    mxmlElementSetAttr(root,"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=addparams0("INFORMATION");
+    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);
-};
-
-bool XMLwrapper::checkfileinformation(const char *filename)
-{
-    stackpos=0;
-    ZERO(&parentstack,(int)sizeof(parentstack));
-    information.PADsynth_used=false;
-
-    if (tree!=NULL) mxmlDelete(tree);
-    tree=NULL;
-    char *xmldata=doloadfile(filename);
-    if (xmldata==NULL) return(-1);//the file could not be loaded or uncompressed
-
-
-    char *start=strstr(xmldata,"<INFORMATION>");
-    char *end=strstr(xmldata,"</INFORMATION>");
-
-    if ((start==NULL)||(end==NULL)||(start>end)) {
-        delete []xmldata;
-        return(false);
-    };
-    end+=strlen("</INFORMATION>");
-    end[0]='\0';
-
-    tree=mxmlNewElement(MXML_NO_PARENT,"?xml");
-    node=root=mxmlLoadString(tree,xmldata,MXML_OPAQUE_CALLBACK);
-    if (root==NULL) {
-        delete []xmldata;
-        mxmlDelete(tree);
-        node=root=tree=NULL;
-        return(false);
-    };
-
-    root=mxmlFindElement(tree,tree,"INFORMATION",NULL,NULL,MXML_DESCEND);
-    push(root);
-
-    if (root==NULL) {
-        delete []xmldata;
+    if(tree)
         mxmlDelete(tree);
-        node=root=tree=NULL;
-        return(false);
-    };
-
-    information.PADsynth_used=getparbool("PADsynth_used",false);
-
-    exitbranch();
-    if (tree!=NULL) mxmlDelete(tree);
-    delete []xmldata;
-    node=root=tree=NULL;
+}
 
-    return(true);
-};
+void XMLwrapper::setPadSynth(bool enabled)
+{
+    /**@bug this might create multiple nodes when only one is needed*/
+    mxml_node_t *oldnode = node;
+    node = info;
+    //Info storing
+    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;
+    else
+        return false;
+}
 
 
 /* SAVE XML members */
 
-int XMLwrapper::saveXMLfile(const string &filename)
+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()
+char *XMLwrapper::getXMLdata() const
 {
-    xml_k=0;
-    ZERO(tabs,STACKSIZE+2);
+    xml_k = 0;
 
-    mxml_node_t *oldnode=node;
+    char *xmldata = mxmlSaveAllocString(tree, XMLwrapper_whitespace_callback);
 
-    node=info;
-    //Info storing
-    addparbool("PADsynth_used",information.PADsynth_used);
-
-    node=oldnode;
-    char *xmldata=mxmlSaveAllocString(tree,XMLwrapper_whitespace_callback);
+    return xmldata;
+}
 
-    return(xmldata);
-};
 
-
-int XMLwrapper::dosavefile(const char *filename,int compression,const char *xmldata)
+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)
 {
-    addparams2("par","name",name.c_str(),"value",int2str(val));
-};
+    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, float val)
 {
-    addparams2("par_real","name",name.c_str(),"value",real2str(val));
-};
+    addparams("par_real", 2, "name", name.c_str(), "value",
+              stringFrom<float>(val).c_str());
+}
 
-void XMLwrapper::addparbool(const string &name,int val)
+void XMLwrapper::addparbool(const string &name, int val)
 {
-    if (val!=0) addparams2("par_bool","name",name.c_str(),"value","yes");
-    else addparams2("par_bool","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)
 {
-    push(node);
-    node=addparams0(name.c_str());
-};
+    if(verbose)
+        cout << "beginbranch()" << name << endl;
+    node = addparams(name.c_str(), 0);
+}
 
-void XMLwrapper::beginbranch(const string &name,int id)
+void XMLwrapper::beginbranch(const string &name, int id)
 {
-    push(node);
-    node=addparams1(name.c_str(),"id",int2str(id));
-};
+    if(verbose)
+        cout << "beginbranch(" << id << ")" << name << endl;
+    node = addparams(name.c_str(), 1, "id", stringFrom<int>(id).c_str());
+}
 
 void XMLwrapper::endbranch()
 {
-    node=pop();
-};
+    if(verbose)
+        cout << "endbranch()" << node << "-" << node->value.element.name
+             << " To "
+             << node->parent << "-" << node->parent->value.element.name << endl;
+    node = node->parent;
+}
 
 
+//workaround for memory leak
+const char *trimLeadingWhite(const char *c)
+{
+    while(isspace(*c))
+        ++c;
+    return c;
+}
 
 /* LOAD XML members */
 
 int XMLwrapper::loadXMLfile(const string &filename)
 {
-    if (tree!=NULL) mxmlDelete(tree);
-    tree=NULL;
-
-    ZERO(&parentstack,(int)sizeof(parentstack));
-    ZERO(&values,(int)sizeof(values));
-
-    stackpos=0;
+    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, trimLeadingWhite(
+                                     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
-    push(root);
+    //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"));
 
-    values.xml_version.major=str2int(mxmlElementGetAttr(root,"version-major"));
-    values.xml_version.minor=str2int(mxmlElementGetAttr(root,"version-minor"));
+    if(verbose)
+        cout << "loadXMLfile() version: " << version.Major << '.'
+             << version.Minor << '.' << version.Revision << endl;
 
-    return(0);
-};
+    return 0;
+}
 
 
-char *XMLwrapper::doloadfile(const string &filename)
+char *XMLwrapper::doloadfile(const string &filename) const
 {
-    char *xmldata=NULL;
-    int filesize=-1;
+    char  *xmldata = NULL;
+    gzFile gzfile  = gzopen(filename.c_str(), "rb");
 
-    //try get filesize as gzip data (first)
-    gzFile gzfile=gzopen(filename.c_str(),"rb");
-    if (gzfile!=NULL) {//this is a gzip file
-        // first check it's size
-        while (!gzeof(gzfile)) {
-            gzseek (gzfile,1024*1024,SEEK_CUR);
-            if (gztell(gzfile)>10000000) {
-                gzclose(gzfile);
-                goto notgzip;//the file is too big
-            };
-        };
-        filesize=gztell(gzfile);
+    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
 
-        //rewind the file and load the data
-        xmldata=new char[filesize+1];
-        ZERO(xmldata,filesize+1);
+        fetchBuf[bufSize] = 0; //force null termination
 
-        gzrewind(gzfile);
-        gzread(gzfile,xmldata,filesize);
+        while(bufSize == (read = gzread(gzfile, fetchBuf, bufSize)))
+            strBuf << fetchBuf;
 
-        gzclose(gzfile);
-        return (xmldata);
-    } else {//this is not a gzip file
-notgzip:
-        FILE *file=fopen(filename.c_str(),"rb");
-        if (file==NULL) return(NULL);
-        fseek(file,0,SEEK_END);
-        filesize=ftell(file);
+        fetchBuf[read] = 0; //Truncate last partial read
+        strBuf << fetchBuf;
 
-        xmldata=new char [filesize+1];
-        ZERO(xmldata,filesize+1);
+        gzclose(gzfile);
 
-        rewind(file);
-        fread(xmldata,filesize,1,file);
+        //Place data in output format
+        string tmp = strBuf.str();
+        xmldata = new char[tmp.size() + 1];
+        strncpy(xmldata, tmp.c_str(), tmp.size() + 1);
+    }
 
-        fclose(file);
-        return(xmldata);
-    };
-};
+    return xmldata;
+}
 
 bool XMLwrapper::putXMLdata(const char *xmldata)
 {
-    if (tree!=NULL) mxmlDelete(tree);
-    tree=NULL;
-
-    ZERO(&parentstack,(int)sizeof(parentstack));
-    ZERO(&values,(int)sizeof(values));
-
-    stackpos=0;
-
-    if (xmldata==NULL) return (false);
+    if(tree != NULL)
+        mxmlDelete(tree);
 
-    root=tree=mxmlLoadString(NULL,xmldata,MXML_OPAQUE_CALLBACK);
+    tree = NULL;
+    if(xmldata == NULL)
+        return false;
 
-    if (tree==NULL) return(false);
+    root = tree = mxmlLoadString(NULL, trimLeadingWhite(
+                                     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);;
-    push(root);
+    node = root = mxmlFindElement(tree,
+                                  tree,
+                                  "ZynAddSubFX-data",
+                                  NULL,
+                                  NULL,
+                                  MXML_DESCEND);
+    if(root == NULL)
+        return false;
 
-    return(true);
-};
+    return true;
+}
 
 
 
 int XMLwrapper::enterbranch(const string &name)
 {
-    node=mxmlFindElement(peek(),peek(),name.c_str(),NULL,NULL,MXML_DESCEND_FIRST);
-    if (node==NULL) return(0);
+    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;
 
-    push(node);
-    return(1);
-};
+    node = tmp;
+    return 1;
+}
 
-int XMLwrapper::enterbranch(const string &name,int id)
+int XMLwrapper::enterbranch(const string &name, int id)
 {
-    snprintf(tmpstr,TMPSTR_SIZE,"%d",id);
-    node=mxmlFindElement(peek(),peek(),name.c_str(),"id",tmpstr,MXML_DESCEND_FIRST);
-    if (node==NULL) return(0);
+    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;
 
-    push(node);
-    return(1);
-};
+    node = tmp;
+    return 1;
+}
 
 
 void XMLwrapper::exitbranch()
 {
-    pop();
-};
+    if(verbose)
+        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)
+int XMLwrapper::getbranchid(int min, int max) const
 {
-    int id=str2int(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)
+int XMLwrapper::getpar(const string &name, int defaultpar, int min,
+                       int max) const
 {
-    node=mxmlFindElement(peek(),peek(),"par","name",name.c_str(),MXML_DESCEND_FIRST);
-    if (node==NULL) return(defaultpar);
+    const mxml_node_t *tmp = mxmlFindElement(node,
+                                             node,
+                                             "par",
+                                             "name",
+                                             name.c_str(),
+                                             MXML_DESCEND_FIRST);
 
-    const char *strval=mxmlElementGetAttr(node,"value");
-    if (strval==NULL) return(defaultpar);
+    if(tmp == NULL)
+        return defaultpar;
 
-    int val=str2int(strval);
-    if (val<min) val=min;
-    else if (val>max) val=max;
+    const char *strval = mxmlElementGetAttr(tmp, "value");
+    if(strval == NULL)
+        return defaultpar;
 
-    return(val);
-};
+    int val = stringTo<int>(strval);
+    if(val < min)
+        val = min;
+    else
+    if(val > max)
+        val = max;
 
-int XMLwrapper::getpar127(const string &name,int defaultpar)
-{
-    return(getpar(name,defaultpar,0,127));
-};
+    return val;
+}
 
-int XMLwrapper::getparbool(const string &name,int defaultpar)
+int XMLwrapper::getpar127(const string &name, int defaultpar) const
 {
-    node=mxmlFindElement(peek(),peek(),"par_bool","name",name.c_str(),MXML_DESCEND_FIRST);
-    if (node==NULL) return(defaultpar);
-
-    const char *strval=mxmlElementGetAttr(node,"value");
-    if (strval==NULL) return(defaultpar);
+    return getpar(name, defaultpar, 0, 127);
+}
 
-    if ((strval[0]=='Y')||(strval[0]=='y')) return(1);
-    else return(0);
-};
-
-void XMLwrapper::getparstr(const string &name,char *par,int maxstrlen)
+int XMLwrapper::getparbool(const string &name, int defaultpar) const
 {
-    ZERO(par,maxstrlen);
-    node=mxmlFindElement(peek(),peek(),"string","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 (node==NULL) return;
-    if (node->child==NULL) return;
-    if (node->child->type!=MXML_OPAQUE) return;
+    if(tmp == NULL)
+        return defaultpar;
 
-    snprintf(par,maxstrlen,"%s",node->child->value.element.name);
+    const char *strval = mxmlElementGetAttr(tmp, "value");
+    if(strval == NULL)
+        return defaultpar;
 
-};
+    if((strval[0] == 'Y') || (strval[0] == 'y'))
+        return 1;
+    else
+        return 0;
+}
 
-REALTYPE XMLwrapper::getparreal(const char *name,REALTYPE defaultpar)
+void XMLwrapper::getparstr(const string &name, char *par, int maxstrlen) const
 {
-    node=mxmlFindElement(peek(),peek(),"par_real","name",name,MXML_DESCEND_FIRST);
-    if (node==NULL) return(defaultpar);
-
-    const char *strval=mxmlElementGetAttr(node,"value");
-    if (strval==NULL) return(defaultpar);
+    ZERO(par, maxstrlen);
+    const mxml_node_t *tmp = mxmlFindElement(node,
+                                             node,
+                                             "string",
+                                             "name",
+                                             name.c_str(),
+                                             MXML_DESCEND_FIRST);
 
-    return(str2real(strval));
-};
-
-REALTYPE XMLwrapper::getparreal(const char *name,REALTYPE defaultpar,REALTYPE min,REALTYPE max)
-{
-    REALTYPE result=getparreal(name,defaultpar);
-
-    if (result<min) result=min;
-    else if (result>max) result=max;
-    return(result);
-};
-
-
-/** Private members **/
-
-char *XMLwrapper::int2str(int x)
-{
-    snprintf(tmpstr,TMPSTR_SIZE,"%d",x);
-    return(tmpstr);
-};
-
-char *XMLwrapper::real2str(REALTYPE x)
-{
-    snprintf(tmpstr,TMPSTR_SIZE,"%g",x);
-    return(tmpstr);
-};
+    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);
+        return;
+    }
+}
 
-int XMLwrapper::str2int(const char *str)
+string XMLwrapper::getparstr(const string &name,
+                             const std::string &defaultpar) const
 {
-    if (str==NULL) return(0);
-    int result=strtol(str,NULL,10);
-    return(result);
-};
+    const mxml_node_t *tmp = mxmlFindElement(node,
+                                             node,
+                                             "string",
+                                             "name",
+                                             name.c_str(),
+                                             MXML_DESCEND_FIRST);
 
-REALTYPE XMLwrapper::str2real(const char *str)
-{
-    if (str==NULL) return(0.0);
-    REALTYPE result=strtod(str,NULL);
-    return(result);
-};
+    if((tmp == NULL) || (tmp->child == NULL))
+        return defaultpar;
 
+    if((tmp->child->type == MXML_OPAQUE)
+       && (tmp->child->value.element.name != NULL))
+        return tmp->child->value.element.name;
 
-mxml_node_t *XMLwrapper::addparams0(const char *name)
-{
-    mxml_node_t *element=mxmlNewElement(node,name);
-    return(element);
-};
+    if((tmp->child->type == MXML_TEXT)
+       && (tmp->child->value.text.string != NULL))
+        return tmp->child->value.text.string;
 
-mxml_node_t *XMLwrapper::addparams1(const char *name,const char *par1,const char *val1)
-{
-    mxml_node_t *element=mxmlNewElement(node,name);
-    mxmlElementSetAttr(element,par1,val1);
-    return(element);
-};
+    return defaultpar;
+}
 
-mxml_node_t *XMLwrapper::addparams2(const char *name,const char *par1,const char *val1,const char *par2, const char *val2)
+float XMLwrapper::getparreal(const char *name, float defaultpar) const
 {
-    mxml_node_t *element=mxmlNewElement(node,name);
-    mxmlElementSetAttr(element,par1,val1);
-    mxmlElementSetAttr(element,par2,val2);
-    return(element);
-};
-
+    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;
 
+    return stringTo<float>(strval);
+}
 
-void XMLwrapper::push(mxml_node_t *node)
+float XMLwrapper::getparreal(const char *name,
+                             float defaultpar,
+                             float min,
+                             float max) const
 {
-    if (stackpos>=STACKSIZE-1) {
-        printf("BUG!: XMLwrapper::push() - full parentstack\n");
-        return;
-    };
-    stackpos++;
-    parentstack[stackpos]=node;
-
-//    printf("push %d - %s\n",stackpos,node->value.element.name);
-
-};
-mxml_node_t *XMLwrapper::pop()
-{
-    if (stackpos<=0) {
-        printf("BUG!: XMLwrapper::pop() - empty parentstack\n");
-        return (root);
-    };
-    mxml_node_t *node=parentstack[stackpos];
-    parentstack[stackpos]=NULL;
+    float result = getparreal(name, defaultpar);
 
-//    printf("pop %d - %s\n",stackpos,node->value.element.name);
-
-    stackpos--;
-    return(node);
-};
-
-mxml_node_t *XMLwrapper::peek()
-{
-    if (stackpos<=0) {
-        printf("BUG!: XMLwrapper::peek() - empty parentstack\n");
-        return (root);
-    };
-    return(parentstack[stackpos]);
-};
+    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
+{
+    /**@todo make this function send out a good error message if something goes
+     * wrong**/
+    mxml_node_t *element = mxmlNewElement(node, name);
+
+    if(params) {
+        va_list variableList;
+        va_start(variableList, params);
+
+        const char *ParamName;
+        const char *ParamValue;
+        while(params--) {
+            ParamName  = va_arg(variableList, const char *);
+            ParamValue = va_arg(variableList, const char *);
+            if(verbose)
+                cout << "addparams()[" << params << "]=" << name << " "
+                     << ParamName << "=\"" << ParamValue << "\"" << endl;
+            mxmlElementSetAttr(element, ParamName, ParamValue);
+        }
+    }
+    return element;
+}
diff --git a/src/Misc/XMLwrapper.h b/src/Misc/XMLwrapper.h
index 6b6849f..077c32d 100644
--- a/src/Misc/XMLwrapper.h
+++ b/src/Misc/XMLwrapper.h
@@ -1,9 +1,11 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  XML.h - XML wrapper
+  XMLwrapper.h - XML wrapper
   Copyright (C) 2003-2005 Nasca Octavian Paul
+  Copyright (C) 2009-2009 Mark McCurry
   Author: Nasca Octavian Paul
+          Mark McCurry
 
   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
@@ -22,156 +24,248 @@
 
 #include <mxml.h>
 #include <string>
-#ifndef REALTYPE
-#define REALTYPE float
+#ifndef float
+#define float float
 #endif
 
 #ifndef XML_WRAPPER_H
 #define XML_WRAPPER_H
 
-#define TMPSTR_SIZE 50
-
-//the maxim tree depth
-#define STACKSIZE 100
-
+/**Mxml wrapper*/
 class XMLwrapper
 {
-public:
-    XMLwrapper();
-    ~XMLwrapper();
-
-    /********************************/
-    /*         SAVE to XML          */
-    /********************************/
-
-    //returns 0 if ok or -1 if the file cannot be saved
-    int saveXMLfile(const std::string &filename);
-
-    //returns the new allocated string that contains the XML data (used for clipboard)
-    //the string is NULL terminated
-    char *getXMLdata();
-
-    //add simple parameter (name and value)
-    void addpar(const std::string &name,int val);
-    void addparreal(const std::string &name,REALTYPE val);
-
-    //add boolean parameter (name and boolean value)
-    //if the value is 0 => "yes", else "no"
-    void addparbool(const std::string &name,int val);
-
-    //add string parameter (name and string)
-    void addparstr(const std::string &name,const std::string &val);
-
-    //add a branch
-    void beginbranch(const std::string &name);
-    void beginbranch(const std::string &name, int id);
-
-    //this must be called after each branch (nodes that contains child nodes)
-    void endbranch();
-
-    /********************************/
-    /*        LOAD from XML         */
-    /********************************/
-
-    //returns 0 if ok or -1 if the file cannot be loaded
-    int loadXMLfile(const std::string &filename);
-
-    //used by the clipboard
-    bool putXMLdata(const char *xmldata);
-
-    //enter into the branch
-    //returns 1 if is ok, or 0 otherwise
-    int enterbranch(const std::string &name);
-
-
-    //enter into the branch with 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);
-
-    //it returns the parameter and limits it between min and max
-    //if min==max==0, it will not limit it
-    //if no parameter will be here, the defaultpar will be returned
-    int getpar(const std::string &name,int defaultpar,int min,int max);
-
-    //the same as getpar, but the limits are 0 and 127
-    int getpar127(const std::string &name,int defaultpar);
-
-    int getparbool(const std::string &name,int defaultpar);
-
-    void getparstr(const std::string &name,char *par,int maxstrlen);
-    REALTYPE getparreal(const char *name,REALTYPE defaultpar);
-    REALTYPE getparreal(const char *name,REALTYPE defaultpar,REALTYPE min,REALTYPE max);
-
-    bool minimal;//false if all parameters will be stored (used only for clipboard)
-
-    struct {
-        bool PADsynth_used;
-    }information;
-
-    //opens a file and parse only the "information" data on it
-    //returns "true" if all went ok or "false" on errors
-    bool checkfileinformation(const char *filename);
-
-private:
-
-    int dosavefile(const char *filename,int compression,const char *xmldata);
-    char *doloadfile(const std::string &filename);
-
-
-    mxml_node_t *tree;//all xml data
-    mxml_node_t *root;//xml data used by zynaddsubfx
-    mxml_node_t *node;//current node
-    mxml_node_t *info;//this node is used to store the information about the data
-
-    //adds params like this:
-    // <name>
-    //returns the node
-    mxml_node_t *addparams0(const char *name);
-
-    //adds params like this:
-    // <name par1="val1">
-    //returns the node
-    mxml_node_t *addparams1(const char *name,const char *par1,const char *val1);
-
-    //adds params like this:
-    // <name par1="val1" par2="val2">
-    //returns the node
-    mxml_node_t *addparams2(const char *name,const char *par1,const char *val1,const char *par2, const char *val2);
-
-    char *int2str(int x);
-    char *real2str(REALTYPE x);
-
-    int str2int(const char *str);
-    REALTYPE str2real(const char *str);
-
-    char tmpstr[TMPSTR_SIZE];
-
-
-    //this is used to store the parents
-    mxml_node_t *parentstack[STACKSIZE];
-    int stackpos;
-
-
-    void push(mxml_node_t *node);
-    mxml_node_t *pop();
-    mxml_node_t *peek();
-
-    //theese are used to store the values
-    struct {
+    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 float value of the node.
+         */
+        void addparreal(const std::string &name, float 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.
+         */
+        float getparreal(const char *name, float 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
+         */
+        float getparreal(const char *name,
+                         float defaultpar,
+                         float min,
+                         float 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,minor;
-        }xml_version;
-    }values;
-
+            int Major; /**<major version number.*/
+            int Minor; /**<minor version number.*/
+            int Revision; /**<version revision number.*/
+        } version;
 };
 
 #endif
diff --git a/src/Nio/AlsaEngine.cpp b/src/Nio/AlsaEngine.cpp
new file mode 100644
index 0000000..434e2fb
--- /dev/null
+++ b/src/Nio/AlsaEngine.cpp
@@ -0,0 +1,366 @@
+/*
+    AlsaEngine.cpp
+
+    Copyright 2009, Alan Calvert
+              2010, Mark McCurry
+
+    This file is part of ZynAddSubFX, which is free software: you can
+    redistribute it and/or modify it under the terms of the GNU General
+    Public License as published by the Free Software Foundation, either
+    version 3 of the License, or (at your option) any later version.
+
+    ZynAddSubFX 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 for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with ZynAddSubFX.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <iostream>
+#include <cmath>
+
+using namespace std;
+
+#include "../Misc/Util.h"
+#include "../Misc/Config.h"
+#include "InMgr.h"
+#include "AlsaEngine.h"
+
+AlsaEngine::AlsaEngine()
+    :AudioOut()
+{
+    audio.buffer = new short[synth->buffersize * 2];
+    name = "ALSA";
+    audio.handle = NULL;
+
+    midi.handle  = NULL;
+    midi.alsaId  = -1;
+    midi.pThread = 0;
+}
+
+AlsaEngine::~AlsaEngine()
+{
+    Stop();
+    delete[] audio.buffer;
+}
+
+void *AlsaEngine::_AudioThread(void *arg)
+{
+    return (static_cast<AlsaEngine *>(arg))->AudioThread();
+}
+
+void *AlsaEngine::AudioThread()
+{
+    set_realtime();
+    return processAudio();
+}
+
+bool AlsaEngine::Start()
+{
+    return openAudio() && openMidi();
+}
+
+void AlsaEngine::Stop()
+{
+    if(getMidiEn())
+        setMidiEn(false);
+    if(getAudioEn())
+        setAudioEn(false);
+    snd_config_update_free_global();
+}
+
+void AlsaEngine::setMidiEn(bool nval)
+{
+    if(nval)
+        openMidi();
+    else
+        stopMidi();
+}
+
+bool AlsaEngine::getMidiEn() const
+{
+    return midi.handle;
+}
+
+void AlsaEngine::setAudioEn(bool nval)
+{
+    if(nval)
+        openAudio();
+    else
+        stopAudio();
+}
+
+bool AlsaEngine::getAudioEn() const
+{
+    return audio.handle;
+}
+
+void *AlsaEngine::_MidiThread(void *arg)
+{
+    return static_cast<AlsaEngine *>(arg)->MidiThread();
+}
+
+
+void *AlsaEngine::MidiThread(void)
+{
+    snd_seq_event_t *event;
+    MidiEvent ev;
+    set_realtime();
+    while(snd_seq_event_input(midi.handle, &event) > 0) {
+        //ensure ev is empty
+        ev.channel = 0;
+        ev.num     = 0;
+        ev.value   = 0;
+        ev.type    = 0;
+
+        if(!event)
+            continue;
+        switch(event->type) {
+            case SND_SEQ_EVENT_NOTEON:
+                if(event->data.note.note) {
+                    ev.type    = M_NOTE;
+                    ev.channel = event->data.note.channel;
+                    ev.num     = event->data.note.note;
+                    ev.value   = event->data.note.velocity;
+                    InMgr::getInstance().putEvent(ev);
+                }
+                break;
+
+            case SND_SEQ_EVENT_NOTEOFF:
+                ev.type    = M_NOTE;
+                ev.channel = event->data.note.channel;
+                ev.num     = event->data.note.note;
+                ev.value   = 0;
+                InMgr::getInstance().putEvent(ev);
+                break;
+
+            case SND_SEQ_EVENT_KEYPRESS:
+                ev.type    = M_PRESSURE;
+                ev.channel = event->data.note.channel;
+                ev.num     = event->data.note.note;
+                ev.value   = event->data.note.velocity;
+                InMgr::getInstance().putEvent(ev);
+                break;
+
+            case SND_SEQ_EVENT_PITCHBEND:
+                ev.type    = M_CONTROLLER;
+                ev.channel = event->data.control.channel;
+                ev.num     = C_pitchwheel;
+                ev.value   = event->data.control.value;
+                InMgr::getInstance().putEvent(ev);
+                break;
+
+            case SND_SEQ_EVENT_CONTROLLER:
+                ev.type    = M_CONTROLLER;
+                ev.channel = event->data.control.channel;
+                ev.num     = event->data.control.param;
+                ev.value   = event->data.control.value;
+                InMgr::getInstance().putEvent(ev);
+                break;
+
+            case SND_SEQ_EVENT_PGMCHANGE:
+                ev.type    = M_PGMCHANGE;
+                ev.channel = event->data.control.channel;
+                ev.num     = event->data.control.value;
+                InMgr::getInstance().putEvent(ev);
+                break;
+
+            case SND_SEQ_EVENT_RESET: // reset to power-on state
+                ev.type    = M_CONTROLLER;
+                ev.channel = event->data.control.channel;
+                ev.num     = C_resetallcontrollers;
+                ev.value   = 0;
+                InMgr::getInstance().putEvent(ev);
+                break;
+
+            case SND_SEQ_EVENT_PORT_SUBSCRIBED: // ports connected
+                if(true)
+                    cout << "Info, alsa midi port connected" << endl;
+                break;
+
+            case SND_SEQ_EVENT_PORT_UNSUBSCRIBED: // ports disconnected
+                if(true)
+                    cout << "Info, alsa midi port disconnected" << endl;
+                break;
+
+            case SND_SEQ_EVENT_SYSEX:   // system exclusive
+            case SND_SEQ_EVENT_SENSING: // midi device still there
+                break;
+
+            default:
+                if(true)
+                    cout << "Info, other non-handled midi event, type: "
+                         << (int)event->type << endl;
+                break;
+        }
+        snd_seq_free_event(event);
+    }
+    return NULL;
+}
+
+bool AlsaEngine::openMidi()
+{
+    if(getMidiEn())
+        return true;
+
+    int alsaport;
+    midi.handle = NULL;
+
+    if(snd_seq_open(&midi.handle, "default", SND_SEQ_OPEN_INPUT, 0) != 0)
+        return false;
+
+    snd_seq_set_client_name(midi.handle, "ZynAddSubFX");
+
+    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 false;
+
+    pthread_attr_t attr;
+
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+    pthread_create(&midi.pThread, &attr, _MidiThread, this);
+    return true;
+}
+
+void AlsaEngine::stopMidi()
+{
+    if(!getMidiEn())
+        return;
+
+    snd_seq_t *handle = midi.handle;
+    if((NULL != midi.handle) && midi.pThread)
+        pthread_cancel(midi.pThread);
+    midi.handle = NULL;
+    if(handle)
+        snd_seq_close(handle);
+}
+
+short *AlsaEngine::interleave(const Stereo<float *> &smps)
+{
+    /**\todo TODO fix repeated allocation*/
+    short *shortInterleaved = audio.buffer;
+    memset(shortInterleaved, 0, bufferSize * 2 * sizeof(short));
+    int    idx = 0; //possible off by one error here
+    double scaled;
+    for(int frame = 0; frame < bufferSize; ++frame) { // with a nod to libsamplerate ...
+        scaled = smps.l[frame] * (8.0f * 0x10000000);
+        shortInterleaved[idx++] = (short int)(lrint(scaled) >> 16);
+        scaled = smps.r[frame] * (8.0f * 0x10000000);
+        shortInterleaved[idx++] = (short int)(lrint(scaled) >> 16);
+    }
+    return shortInterleaved;
+}
+
+bool AlsaEngine::openAudio()
+{
+    if(getAudioEn())
+        return true;
+
+    int rc = 0;
+    /* Open PCM device for playback. */
+    audio.handle = NULL;
+    rc = snd_pcm_open(&audio.handle, "hw:0",
+                      SND_PCM_STREAM_PLAYBACK, 0);
+    if(rc < 0) {
+        fprintf(stderr,
+                "unable to open pcm device: %s\n",
+                snd_strerror(rc));
+        return false;
+    }
+
+    /* Allocate a hardware parameters object. */
+    snd_pcm_hw_params_alloca(&audio.params);
+
+    /* Fill it in with default values. */
+    snd_pcm_hw_params_any(audio.handle, audio.params);
+
+    /* Set the desired hardware parameters. */
+
+    /* Interleaved mode */
+    snd_pcm_hw_params_set_access(audio.handle, audio.params,
+                                 SND_PCM_ACCESS_RW_INTERLEAVED);
+
+    /* Signed 16-bit little-endian format */
+    snd_pcm_hw_params_set_format(audio.handle, audio.params,
+                                 SND_PCM_FORMAT_S16_LE);
+
+    /* Two channels (stereo) */
+    snd_pcm_hw_params_set_channels(audio.handle, audio.params, 2);
+
+    audio.sampleRate = synth->samplerate;
+    snd_pcm_hw_params_set_rate_near(audio.handle, audio.params,
+                                    &audio.sampleRate, NULL);
+
+    audio.frames = 512;
+    snd_pcm_hw_params_set_period_size_near(audio.handle,
+                                           audio.params, &audio.frames, NULL);
+
+    audio.periods = 4;
+    snd_pcm_hw_params_set_periods_near(audio.handle,
+                                       audio.params, &audio.periods, NULL);
+
+    /* Write the parameters to the driver */
+    rc = snd_pcm_hw_params(audio.handle, audio.params);
+    if(rc < 0) {
+        fprintf(stderr,
+                "unable to set hw parameters: %s\n",
+                snd_strerror(rc));
+        return false;
+    }
+
+    /* Set buffer size (in frames). The resulting latency is given by */
+    /* latency = periodsize * periods / (rate * bytes_per_frame)     */
+    snd_pcm_hw_params_set_buffer_size(audio.handle,
+                                      audio.params,
+                                      synth->buffersize);
+
+    //snd_pcm_hw_params_get_period_size(audio.params, &audio.frames, NULL);
+    //snd_pcm_hw_params_get_period_time(audio.params, &val, NULL);
+
+
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+    pthread_create(&audio.pThread, &attr, _AudioThread, this);
+    return true;
+}
+
+void AlsaEngine::stopAudio()
+{
+    if(!getAudioEn())
+        return;
+
+    snd_pcm_t *handle = audio.handle;
+    audio.handle = NULL;
+    pthread_join(audio.pThread, NULL);
+    snd_pcm_drain(handle);
+    if(snd_pcm_close(handle))
+        cout << "Error: in snd_pcm_close " << __LINE__ << ' ' << __FILE__
+             << endl;
+}
+
+void *AlsaEngine::processAudio()
+{
+    while(audio.handle) {
+        audio.buffer = interleave(getNext());
+        snd_pcm_t *handle = audio.handle;
+        int rc = snd_pcm_writei(handle, audio.buffer, synth->buffersize);
+        if(rc == -EPIPE) {
+            /* EPIPE means underrun */
+            cerr << "underrun occurred" << endl;
+            snd_pcm_prepare(handle);
+        }
+        else
+        if(rc < 0)
+            cerr << "error from writei: " << snd_strerror(rc) << endl;
+    }
+    return NULL;
+}
diff --git a/src/Nio/AlsaEngine.h b/src/Nio/AlsaEngine.h
new file mode 100644
index 0000000..0b9cc3c
--- /dev/null
+++ b/src/Nio/AlsaEngine.h
@@ -0,0 +1,82 @@
+/*
+    AlsaEngine.h
+
+    Copyright 2009, Alan Calvert
+              2010, Mark McCurry
+
+    This file is part of ZynAddSubFX, which is free software: you can
+    redistribute it and/or modify it under the terms of the GNU General
+    Public License as published by the Free Software Foundation, either
+    version 3 of the License, or (at your option) any later version.
+
+    ZynAddSubFX 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 for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with ZynAddSubFX.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef ALSA_ENGINE_H
+#define ALSA_ENGINE_H
+
+#include <pthread.h>
+#include <string>
+#include <alsa/asoundlib.h>
+#include <queue>
+
+#include "AudioOut.h"
+#include "MidiIn.h"
+#include "OutMgr.h"
+#include "../Misc/Stereo.h"
+
+class AlsaEngine:public AudioOut, MidiIn
+{
+    public:
+        AlsaEngine();
+        ~AlsaEngine();
+
+        bool Start();
+        void Stop();
+
+        void setAudioEn(bool nval);
+        bool getAudioEn() const;
+        void setMidiEn(bool nval);
+        bool getMidiEn() const;
+
+    protected:
+        void *AudioThread();
+        static void *_AudioThread(void *arg);
+        void *MidiThread();
+        static void *_MidiThread(void *arg);
+
+    private:
+        bool openMidi();
+        void stopMidi();
+        bool openAudio();
+        void stopAudio();
+
+        short *interleave(const Stereo<float *> &smps);
+
+        struct {
+            std::string device;
+            snd_seq_t  *handle;
+            int alsaId;
+            pthread_t pThread;
+        } midi;
+
+        struct {
+            snd_pcm_t *handle;
+            snd_pcm_hw_params_t *params;
+            unsigned int      sampleRate;
+            snd_pcm_uframes_t frames;
+            unsigned int      periods;
+            short    *buffer;
+            pthread_t pThread;
+        } audio;
+
+        void *processAudio();
+};
+
+#endif
diff --git a/src/Nio/AudioOut.cpp b/src/Nio/AudioOut.cpp
new file mode 100644
index 0000000..8c4f2d4
--- /dev/null
+++ b/src/Nio/AudioOut.cpp
@@ -0,0 +1,58 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  AudioOut.h - Audio Output superclass
+  Copyright (C) 2009-2010 Mark McCurry
+  Author: Mark McCurry
+
+  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 <iostream>
+#include <cstring>
+#include "SafeQueue.h"
+
+using namespace std;
+
+#include "OutMgr.h"
+#include "../Misc/Master.h"
+#include "AudioOut.h"
+
+AudioOut::AudioOut()
+    :samplerate(synth->samplerate), bufferSize(synth->buffersize)
+{}
+
+AudioOut::~AudioOut()
+{}
+
+void AudioOut::setSamplerate(int _samplerate)
+{
+    samplerate = _samplerate;
+}
+
+int AudioOut::getSampleRate()
+{
+    return samplerate;
+}
+
+void AudioOut::setBufferSize(int _bufferSize)
+{
+    bufferSize = _bufferSize;
+}
+
+const Stereo<float *> AudioOut::getNext()
+{
+    return OutMgr::getInstance().tick(bufferSize);
+}
diff --git a/src/Nio/AudioOut.h b/src/Nio/AudioOut.h
new file mode 100644
index 0000000..f8e1a97
--- /dev/null
+++ b/src/Nio/AudioOut.h
@@ -0,0 +1,61 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  AudioOut.h - Audio Output superclass
+  Copyright (C) 2009-2010 Mark McCurry
+  Author: Mark McCurry
+
+  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 AUDIO_OUT_H
+#define AUDIO_OUT_H
+
+#include "../Misc/Stereo.h"
+#include "../globals.h"
+#include "Engine.h"
+
+class AudioOut:public virtual Engine
+{
+    public:
+        AudioOut();
+        virtual ~AudioOut();
+
+        /**Sets the Sample Rate of this Output
+         * (used for getNext()).*/
+        void setSamplerate(int _samplerate);
+
+        /**Sets the Samples required per Out of this driver
+         * not a realtime opperation */
+        int getSampleRate();
+        void setBufferSize(int _bufferSize);
+
+        /**Sets the Frame Size for output*/
+        void bufferingSize(int nBuffering);
+        int bufferingSize();
+
+        virtual void setAudioEn(bool nval) = 0;
+        virtual bool getAudioEn() const    = 0;
+
+    protected:
+        /**Get the next sample for output.
+         * (has nsamples sampled at a rate of samplerate)*/
+        const Stereo<float *> getNext();
+
+        int samplerate;
+        int bufferSize;
+};
+
+#endif
diff --git a/src/Nio/CMakeLists.txt b/src/Nio/CMakeLists.txt
new file mode 100644
index 0000000..c4882a3
--- /dev/null
+++ b/src/Nio/CMakeLists.txt
@@ -0,0 +1,49 @@
+#Defaults:
+#         - Wave Output (enabled with the record function)
+#         - Null Output
+#         - Null Output Running by default
+#         - Managed with OutMgr
+set(zynaddsubfx_nio_SRCS
+    WavEngine.cpp
+    NulEngine.cpp
+    AudioOut.cpp
+    MidiIn.cpp
+    OutMgr.cpp
+    InMgr.cpp
+    Engine.cpp
+    EngineMgr.cpp
+    Nio.cpp
+    )
+
+set(zynaddsubfx_nio_lib )
+
+add_definitions(-DOUT_DEFAULT="${DefaultOutput}")
+add_definitions(-DIN_DEFAULT="${DefaultInput}")
+
+if(JackEnable)
+    include_directories(${JACK_INCLUDE_DIR})
+    list(APPEND zynaddsubfx_nio_SRCS JackEngine.cpp)
+    list(APPEND zynaddsubfx_nio_lib ${JACK_LIBRARIES})
+endif(JackEnable)
+
+if(PaEnable)
+    include_directories(${PORTAUDIO_INCLUDE_DIR})
+    list(APPEND zynaddsubfx_nio_SRCS PaEngine.cpp)
+    list(APPEND zynaddsubfx_nio_lib ${PORTAUDIO_LIBRARIES})
+endif(PaEnable)
+
+if(AlsaEnable)
+    list(APPEND zynaddsubfx_nio_SRCS AlsaEngine.cpp)
+    list(APPEND zynaddsubfx_nio_lib ${ASOUND_LIBRARY})
+endif(AlsaEnable)
+
+if(OssEnable)
+    list(APPEND zynaddsubfx_nio_SRCS OssEngine.cpp)
+endif(OssEnable)
+
+
+add_library(zynaddsubfx_nio STATIC
+    ${zynaddsubfx_nio_SRCS} 
+    )
+
+target_link_libraries(zynaddsubfx_nio zynaddsubfx_misc) #for WavFile
diff --git a/src/Nio/Engine.cpp b/src/Nio/Engine.cpp
new file mode 100644
index 0000000..5e846b7
--- /dev/null
+++ b/src/Nio/Engine.cpp
@@ -0,0 +1,28 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  Engine.cpp - Audio Driver base class
+  Copyright (C) 2009-2010 Mark McCurry
+  Author: Mark McCurry
+
+  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 "Engine.h"
+
+Engine::Engine()
+{}
+
+Engine::~Engine()
+{}
diff --git a/src/Nio/Engine.h b/src/Nio/Engine.h
new file mode 100644
index 0000000..9de4422
--- /dev/null
+++ b/src/Nio/Engine.h
@@ -0,0 +1,41 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  Engine.h - Audio Driver base class
+  Copyright (C) 2009-2010 Mark McCurry
+  Author: Mark McCurry
+
+  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 ENGINE_H
+#define ENGINE_H
+#include <string>
+/**Marker for input/output driver*/
+class Engine
+{
+    public:
+        Engine();
+        virtual ~Engine();
+
+        /**Start the Driver with all capabilities
+         * @return true on success*/
+        virtual bool Start() = 0;
+        /**Completely stop the Driver*/
+        virtual void Stop() = 0;
+
+        std::string name;
+};
+#endif
diff --git a/src/Nio/EngineMgr.cpp b/src/Nio/EngineMgr.cpp
new file mode 100644
index 0000000..ee8f7b9
--- /dev/null
+++ b/src/Nio/EngineMgr.cpp
@@ -0,0 +1,156 @@
+#include "EngineMgr.h"
+#include <algorithm>
+#include <iostream>
+#include "Nio.h"
+#include "InMgr.h"
+#include "OutMgr.h"
+#include "AudioOut.h"
+#include "MidiIn.h"
+#include "NulEngine.h"
+#if OSS
+#include "OssEngine.h"
+#endif
+#if ALSA
+#include "AlsaEngine.h"
+#endif
+#if JACK
+#include "JackEngine.h"
+#endif
+#if PORTAUDIO
+#include "PaEngine.h"
+#endif
+
+using namespace std;
+
+EngineMgr &EngineMgr::getInstance()
+{
+    static EngineMgr instance;
+    return instance;
+}
+
+EngineMgr::EngineMgr()
+{
+    Engine *defaultEng = new NulEngine();
+
+    //conditional compiling mess (but contained)
+    engines.push_back(defaultEng);
+#if OSS
+    engines.push_back(new OssEngine());
+#endif
+#if ALSA
+    engines.push_back(new AlsaEngine());
+#endif
+#if JACK
+    engines.push_back(new JackEngine());
+#endif
+#if PORTAUDIO
+    engines.push_back(new PaEngine());
+#endif
+
+    defaultOut = dynamic_cast<AudioOut *>(defaultEng);
+
+    defaultIn = dynamic_cast<MidiIn *>(defaultEng);
+
+    //Accept command line/compile time options
+    if(!Nio::defaultSink.empty())
+        setOutDefault(Nio::defaultSink);
+
+    if(!Nio::defaultSource.empty())
+        setInDefault(Nio::defaultSource);
+}
+
+EngineMgr::~EngineMgr()
+{
+    for(list<Engine *>::iterator itr = engines.begin();
+        itr != engines.end(); ++itr)
+        delete *itr;
+}
+
+Engine *EngineMgr::getEng(string name)
+{
+    transform(name.begin(), name.end(), name.begin(), ::toupper);
+    for(list<Engine *>::iterator itr = engines.begin();
+        itr != engines.end(); ++itr)
+        if((*itr)->name == name)
+            return *itr;
+    return NULL;
+}
+
+bool EngineMgr::start()
+{
+    bool expected = true;
+    if(!(defaultOut && defaultIn)) {
+        cerr << "ERROR: It looks like someone broke the Nio Output\n"
+             << "       Attempting to recover by defaulting to the\n"
+             << "       Null Engine." << endl;
+        defaultOut = dynamic_cast<AudioOut *>(getEng("NULL"));
+        defaultIn  = dynamic_cast<MidiIn *>(getEng("NULL"));
+    }
+
+    OutMgr::getInstance(). currentOut = defaultOut;
+    InMgr::getInstance().  current    = defaultIn;
+
+    //open up the default output(s)
+    cout << "Starting Audio: " << defaultOut->name << endl;
+    defaultOut->setAudioEn(true);
+    if(defaultOut->getAudioEn())
+        cout << "Audio Started" << endl;
+    else {
+        expected = false;
+        cerr << "ERROR: The default audio output failed to open!" << endl;
+        OutMgr::getInstance(). currentOut =
+            dynamic_cast<AudioOut *>(getEng("NULL"));
+        OutMgr::getInstance(). currentOut->setAudioEn(true);
+    }
+
+    cout << "Starting MIDI: " << defaultIn->name << endl;
+    defaultIn->setMidiEn(true);
+    if(defaultIn->getMidiEn())
+        cout << "MIDI Started" << endl;
+    else { //recover
+        expected = false;
+        cerr << "ERROR: The default MIDI input failed to open!" << endl;
+        InMgr::getInstance(). current = dynamic_cast<MidiIn *>(getEng("NULL"));
+        InMgr::getInstance(). current->setMidiEn(true);
+    }
+
+    //Show if expected drivers were booted
+    return expected;
+}
+
+void EngineMgr::stop()
+{
+    for(list<Engine *>::iterator itr = engines.begin();
+        itr != engines.end(); ++itr)
+        (*itr)->Stop();
+}
+
+bool EngineMgr::setInDefault(string name)
+{
+    MidiIn *chosen;
+    if((chosen = dynamic_cast<MidiIn *>(getEng(name)))) {    //got the input
+        defaultIn = chosen;
+        return true;
+    }
+
+    //Warn user
+    cerr << "Error: " << name << " is not a recognized MIDI input source"
+         << endl;
+    cerr << "       Defaulting to the NULL input source" << endl;
+
+    return false;
+}
+
+bool EngineMgr::setOutDefault(string name)
+{
+    AudioOut *chosen;
+    if((chosen = dynamic_cast<AudioOut *>(getEng(name)))) {    //got the output
+        defaultOut = chosen;
+        return true;
+    }
+
+    //Warn user
+    cerr << "Error: " << name << " is not a recognized audio backend" << endl;
+    cerr << "       Defaulting to the NULL audio backend" << endl;
+    return false;
+}
diff --git a/src/Nio/EngineMgr.h b/src/Nio/EngineMgr.h
new file mode 100644
index 0000000..4d56d29
--- /dev/null
+++ b/src/Nio/EngineMgr.h
@@ -0,0 +1,43 @@
+#ifndef ENGINE_MGR_H
+#define ENGINE_MGR_H
+
+#include <list>
+#include <string>
+#include "Engine.h"
+
+
+class MidiIn;
+class AudioOut;
+class OutMgr;
+/**Container/Owner of the long lived Engines*/
+class EngineMgr
+{
+    public:
+        static EngineMgr &getInstance();
+        ~EngineMgr();
+
+        /**Gets requested engine
+         * @param name case unsensitive name of engine
+         * @return pointer to Engine or NULL
+         */
+        Engine *getEng(std::string name);
+
+        /**Start up defaults*/
+        bool start();
+
+        /**Stop all engines*/
+        void stop();
+
+        std::list<Engine *> engines;
+
+        //return false on failure
+        bool setInDefault(std::string name);
+        bool setOutDefault(std::string name);
+
+        //default I/O
+        AudioOut *defaultOut;
+        MidiIn   *defaultIn;
+    private:
+        EngineMgr();
+};
+#endif
diff --git a/src/Nio/InMgr.cpp b/src/Nio/InMgr.cpp
new file mode 100644
index 0000000..af8d63c
--- /dev/null
+++ b/src/Nio/InMgr.cpp
@@ -0,0 +1,129 @@
+#include "InMgr.h"
+#include "MidiIn.h"
+#include "EngineMgr.h"
+#include "../Misc/Master.h"
+#include <iostream>
+
+using namespace std;
+
+ostream &operator<<(ostream &out, const MidiEvent &ev)
+{
+    switch(ev.type) {
+        case M_NOTE:
+            out << "MidiNote: note(" << ev.num << ")\n"
+            << "          channel(" << ev.channel << ")\n"
+            << "          velocity(" << ev.value << ")";
+            break;
+
+        case M_CONTROLLER:
+            out << "MidiCtl: controller(" << ev.num << ")\n"
+            << "         channel(" << ev.channel << ")\n"
+            << "         value(" << ev.value << ")";
+            break;
+
+        case M_PGMCHANGE:
+            out << "PgmChange: program(" << ev.num << ")\n"
+            << "           channel(" << ev.channel << ")";
+            break;
+    }
+
+    return out;
+}
+
+MidiEvent::MidiEvent()
+    :channel(0), type(0), num(0), value(0)
+{}
+
+InMgr &InMgr::getInstance()
+{
+    static InMgr instance;
+    return instance;
+}
+
+InMgr::InMgr()
+    :queue(100), master(Master::getInstance())
+{
+    current = NULL;
+    sem_init(&work, PTHREAD_PROCESS_PRIVATE, 0);
+}
+
+InMgr::~InMgr()
+{
+    //lets stop the consumer thread
+    sem_destroy(&work);
+}
+
+void InMgr::putEvent(MidiEvent ev)
+{
+    if(queue.push(ev)) //check for error
+        cerr << "ERROR: Midi Ringbuffer is FULL" << endl;
+    else
+        sem_post(&work);
+}
+
+void InMgr::flush()
+{
+    MidiEvent ev;
+    while(!sem_trywait(&work)) {
+        queue.pop(ev);
+        //cout << ev << endl;
+
+        switch(ev.type) {
+            case M_NOTE:
+                dump.dumpnote(ev.channel, ev.num, ev.value);
+
+                if(ev.value)
+                    master.noteOn(ev.channel, ev.num, ev.value);
+                else
+                    master.noteOff(ev.channel, ev.num);
+                break;
+
+            case M_CONTROLLER:
+                dump.dumpcontroller(ev.channel, ev.num, ev.value);
+                master.setController(ev.channel, ev.num, ev.value);
+                break;
+
+            case M_PGMCHANGE:
+                master.setProgram(ev.channel, ev.num);
+                break;
+            case M_PRESSURE:
+                master.polyphonicAftertouch(ev.channel, ev.num, ev.value);
+                break;
+        }
+    }
+}
+
+bool InMgr::setSource(string name)
+{
+    MidiIn *src = getIn(name);
+
+    if(!src)
+        return false;
+
+    if(current)
+        current->setMidiEn(false);
+    current = src;
+    current->setMidiEn(true);
+
+    bool success = current->getMidiEn();
+
+    //Keep system in a valid state (aka with a running driver)
+    if(!success)
+        (current = getIn("NULL"))->setMidiEn(true);
+
+    return success;
+}
+
+string InMgr::getSource() const
+{
+    if(current)
+        return current->name;
+    else
+        return "ERROR";
+}
+
+MidiIn *InMgr::getIn(string name)
+{
+    EngineMgr &eng = EngineMgr::getInstance();
+    return dynamic_cast<MidiIn *>(eng.getEng(name));
+}
diff --git a/src/Nio/InMgr.h b/src/Nio/InMgr.h
new file mode 100644
index 0000000..03dcad0
--- /dev/null
+++ b/src/Nio/InMgr.h
@@ -0,0 +1,52 @@
+#ifndef INMGR_H
+#define INMGR_H
+
+#include <string>
+#include <semaphore.h>
+#include "SafeQueue.h"
+
+enum midi_type {
+    M_NOTE = 1,
+    M_CONTROLLER = 2,
+    M_PGMCHANGE  = 3,
+    M_PRESSURE   = 4
+};    //type=1 for note, type=2 for controller, type=3 for program change
+//type=4 for polyphonic aftertouch
+
+struct MidiEvent {
+    MidiEvent();
+    int channel; //the midi channel for the event
+    int type;    //type=1 for note, type=2 for controller
+    int num;     //note, controller or program number
+    int value;   //velocity or controller value
+};
+
+//super simple class to manage the inputs
+class InMgr
+{
+    public:
+        static InMgr &getInstance();
+        ~InMgr();
+
+        void putEvent(MidiEvent ev);
+
+        /**Flush the Midi Queue*/
+        void flush();
+
+        bool setSource(std::string name);
+
+        std::string getSource() const;
+
+        friend class EngineMgr;
+    private:
+        InMgr();
+        class MidiIn *getIn(std::string name);
+        SafeQueue<MidiEvent> queue;
+        sem_t work;
+        class MidiIn * current;
+
+        /**the link to the rest of zyn*/
+        class Master & master;
+};
+
+#endif
diff --git a/src/Nio/JackEngine.cpp b/src/Nio/JackEngine.cpp
new file mode 100644
index 0000000..8af0c38
--- /dev/null
+++ b/src/Nio/JackEngine.cpp
@@ -0,0 +1,402 @@
+/*
+    JackEngine.cpp
+
+    Copyright 2009, Alan Calvert
+
+    This file is part of yoshimi, which is free software: you can
+    redistribute it and/or modify it under the terms of the GNU General
+    Public License as published by the Free Software Foundation, either
+    version 3 of the License, or (at your option) any later version.
+
+    yoshimi 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 for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with yoshimi.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <iostream>
+
+#include <jack/midiport.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <cassert>
+#include <cstring>
+
+#include "Nio.h"
+#include "InMgr.h"
+
+#include "JackEngine.h"
+
+using namespace std;
+
+extern char *instance_name;
+
+JackEngine::JackEngine()
+    :AudioOut(), jackClient(NULL)
+{
+    name = "JACK";
+    audio.jackSamplerate = 0;
+    audio.jackNframes    = 0;
+    for(int i = 0; i < 2; ++i) {
+        audio.ports[i]     = NULL;
+        audio.portBuffs[i] = NULL;
+    }
+    midi.inport = NULL;
+}
+
+bool JackEngine::connectServer(string server)
+{
+    bool autostart_jack = true;
+    if(jackClient)
+        return true;
+
+    string clientname = "zynaddsubfx";
+    string postfix    = Nio::getPostfix();
+    if(!postfix.empty())
+        clientname += "_" + postfix;
+    jack_status_t jackstatus;
+    bool use_server_name = server.size() && server.compare("default") != 0;
+    jack_options_t jopts = (jack_options_t)
+                           (((!instance_name
+                              && use_server_name) ? JackServerName :
+                             JackNullOption)
+                            | ((autostart_jack) ? JackNullOption :
+                               JackNoStartServer));
+
+    if(instance_name)
+        jackClient = jack_client_open(instance_name, jopts, &jackstatus);
+    else {
+        if(use_server_name)
+            jackClient = jack_client_open(
+                clientname.c_str(), jopts, &jackstatus,
+                server.c_str());
+        else
+            jackClient = jack_client_open(
+                clientname.c_str(), jopts, &jackstatus);
+    }
+
+
+    if(NULL != jackClient)
+        return true;
+    else
+        cerr << "Error, failed to open jack client on server: " << server
+             << " status " << jackstatus << endl;
+    return false;
+}
+
+bool JackEngine::connectJack()
+{
+    connectServer("");
+    if(NULL != jackClient) {
+        setBufferSize(jack_get_buffer_size(jackClient));
+        int chk;
+        jack_set_error_function(_errorCallback);
+        jack_set_info_function(_infoCallback);
+        if(jack_set_buffer_size_callback(jackClient, _bufferSizeCallback, this))
+            cerr << "Error setting the bufferSize callback" << endl;
+        if((chk = jack_set_xrun_callback(jackClient, _xrunCallback, this)))
+            cerr << "Error setting jack xrun callback" << endl;
+        if(jack_set_process_callback(jackClient, _processCallback, this)) {
+            cerr << "Error, JackEngine failed to set process callback" << endl;
+            return false;
+        }
+        if(jack_activate(jackClient)) {
+            cerr << "Error, failed to activate jack client" << endl;
+            return false;
+        }
+
+        return true;
+    }
+    else
+        cerr << "Error, NULL jackClient through Start()" << endl;
+    return false;
+}
+
+void JackEngine::disconnectJack()
+{
+    if(jackClient) {
+        cout << "Deactivating and closing JACK client" << endl;
+
+        jack_deactivate(jackClient);
+        jack_client_close(jackClient);
+        jackClient = NULL;
+    }
+}
+
+bool JackEngine::Start()
+{
+    return openMidi() && openAudio();
+}
+
+void JackEngine::Stop()
+{
+    stopMidi();
+    stopAudio();
+}
+
+void JackEngine::setMidiEn(bool nval)
+{
+    if(nval)
+        openMidi();
+    else
+        stopMidi();
+}
+
+bool JackEngine::getMidiEn() const
+{
+    return midi.inport;
+}
+
+void JackEngine::setAudioEn(bool nval)
+{
+    if(nval)
+        openAudio();
+    else
+        stopAudio();
+}
+
+bool JackEngine::getAudioEn() const
+{
+    return audio.ports[0];
+}
+
+bool JackEngine::openAudio()
+{
+    if(getAudioEn())
+        return true;
+
+    if(!getMidiEn())
+        if(!connectJack())
+            return false;
+
+
+    const char *portnames[] = { "out_1", "out_2" };
+    for(int port = 0; port < 2; ++port)
+        audio.ports[port] = jack_port_register(
+            jackClient,
+            portnames[port],
+            JACK_DEFAULT_AUDIO_TYPE,
+            JackPortIsOutput
+            | JackPortIsTerminal,
+            0);
+    if((NULL != audio.ports[0]) && (NULL != audio.ports[1])) {
+        audio.jackSamplerate = jack_get_sample_rate(jackClient);
+        audio.jackNframes    = jack_get_buffer_size(jackClient);
+        samplerate = audio.jackSamplerate;
+        bufferSize = audio.jackNframes;
+
+
+        //Attempt to autoConnect when specified
+        if(Nio::autoConnect) {
+            const char **outPorts = jack_get_ports(
+                jackClient,
+                NULL,
+                NULL,
+                JackPortIsPhysical
+                | JackPortIsInput);
+            if(outPorts != NULL) {
+                //Verify that stereo is available
+                assert(outPorts[0]);
+                assert(outPorts[1]);
+
+                //Connect to physical outputs
+                jack_connect(jackClient, jack_port_name(
+                                 audio.ports[0]), outPorts[0]);
+                jack_connect(jackClient, jack_port_name(
+                                 audio.ports[1]), outPorts[1]);
+            }
+            else
+                cerr << "Warning, No outputs to autoconnect to" << endl;
+        }
+        return true;
+    }
+    else
+        cerr << "Error, failed to register jack audio ports" << endl;
+    return false;
+}
+
+void JackEngine::stopAudio()
+{
+    for(int i = 0; i < 2; ++i) {
+        jack_port_t *port = audio.ports[i];
+        audio.ports[i] = NULL;
+        if(NULL != port)
+            jack_port_unregister(jackClient, port);
+    }
+    if(!getMidiEn())
+        disconnectJack();
+}
+
+bool JackEngine::openMidi()
+{
+    if(getMidiEn())
+        return true;
+    if(!getAudioEn())
+        if(!connectJack())
+            return false;
+
+    midi.inport = jack_port_register(jackClient, "midi_input",
+                                     JACK_DEFAULT_MIDI_TYPE,
+                                     JackPortIsInput | JackPortIsTerminal, 0);
+    return midi.inport;
+}
+
+void JackEngine::stopMidi()
+{
+    jack_port_t *port = midi.inport;
+    midi.inport = NULL;
+    if(port)
+        jack_port_unregister(jackClient, port);
+
+    if(!getAudioEn())
+        disconnectJack();
+}
+
+int JackEngine::clientId()
+{
+    if(NULL != jackClient)
+        return (long)jack_client_thread_id(jackClient);
+    else
+        return -1;
+}
+
+string JackEngine::clientName()
+{
+    if(NULL != jackClient)
+        return string(jack_get_client_name(jackClient));
+    else
+        cerr << "Error, clientName() with null jackClient" << endl;
+    return string("Oh, yoshimi :-(");
+}
+
+int JackEngine::_processCallback(jack_nframes_t nframes, void *arg)
+{
+    return static_cast<JackEngine *>(arg)->processCallback(nframes);
+}
+
+int JackEngine::processCallback(jack_nframes_t nframes)
+{
+    bool okaudio = true;
+
+    if((NULL != audio.ports[0]) && (NULL != audio.ports[1]))
+        okaudio = processAudio(nframes);
+    if(okaudio)
+        handleMidi(nframes);
+    return okaudio ? 0 : -1;
+}
+
+bool JackEngine::processAudio(jack_nframes_t nframes)
+{
+    for(int port = 0; port < 2; ++port) {
+        audio.portBuffs[port] =
+            (jsample_t *)jack_port_get_buffer(audio.ports[port], nframes);
+        if(NULL == audio.portBuffs[port]) {
+            cerr << "Error, failed to get jack audio port buffer: "
+                 << port << endl;
+            return false;
+        }
+    }
+
+    Stereo<float *> smp = getNext();
+
+    //Assumes size of smp.l == nframes
+    memcpy(audio.portBuffs[0], smp.l, bufferSize * sizeof(float));
+    memcpy(audio.portBuffs[1], smp.r, bufferSize * sizeof(float));
+    return true;
+}
+
+int JackEngine::_xrunCallback(void *)
+{
+    cerr << "Jack reports xrun" << endl;
+    return 0;
+}
+
+void JackEngine::_errorCallback(const char *msg)
+{
+    cerr << "Jack reports error: " << msg << endl;
+}
+
+void JackEngine::_infoCallback(const char *msg)
+{
+    cerr << "Jack info message: " << msg << endl;
+}
+
+int JackEngine::_bufferSizeCallback(jack_nframes_t nframes, void *arg)
+{
+    return static_cast<JackEngine *>(arg)->bufferSizeCallback(nframes);
+}
+
+int JackEngine::bufferSizeCallback(jack_nframes_t nframes)
+{
+    cerr << "Jack buffer resized" << endl;
+    setBufferSize(nframes);
+    return 0;
+}
+
+void JackEngine::handleMidi(unsigned long frames)
+{
+    if(!midi.inport)
+        return;
+    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;
+
+    while(jack_midi_event_get(&jack_midi_event, midi_buf,
+                              event_index++) == 0) {
+        MidiEvent ev;
+        midi_data  = jack_midi_event.buffer;
+        type       = midi_data[0] & 0xF0;
+        ev.channel = midi_data[0] & 0x0F;
+
+        switch(type) {
+            case 0x80: /* note-off */
+                ev.type  = M_NOTE;
+                ev.num   = midi_data[1];
+                ev.value = 0;
+                InMgr::getInstance().putEvent(ev);
+                break;
+
+            case 0x90: /* note-on */
+                ev.type  = M_NOTE;
+                ev.num   = midi_data[1];
+                ev.value = midi_data[2];
+                InMgr::getInstance().putEvent(ev);
+                break;
+
+            case 0xA0: /* pressure, aftertouch */
+                ev.type  = M_PRESSURE;
+                ev.num   = midi_data[1];
+                ev.value = midi_data[2];
+                InMgr::getInstance().putEvent(ev);
+                break;
+
+            case 0xB0: /* controller */
+                ev.type  = M_CONTROLLER;
+                ev.num   = midi_data[1];
+                ev.value = midi_data[2];
+                InMgr::getInstance().putEvent(ev);
+                break;
+
+            case 0xC0: /* program change */
+                ev.type  = M_PGMCHANGE;
+                ev.num   = midi_data[1];
+                ev.value = 0;
+                InMgr::getInstance().putEvent(ev);
+                break;
+
+            case 0xE0: /* pitch bend */
+                ev.type  = M_CONTROLLER;
+                ev.num   = C_pitchwheel;
+                ev.value = ((midi_data[2] << 7) | midi_data[1]) - 8192;
+                InMgr::getInstance().putEvent(ev);
+                break;
+
+                /* XXX TODO: handle MSB/LSB controllers and RPNs and NRPNs */
+        }
+    }
+}
diff --git a/src/Nio/JackEngine.h b/src/Nio/JackEngine.h
new file mode 100644
index 0000000..1184ce8
--- /dev/null
+++ b/src/Nio/JackEngine.h
@@ -0,0 +1,88 @@
+/*
+    JackEngine.h
+
+    Copyright 2009, Alan Calvert
+
+    This file is part of yoshimi, which is free software: you can
+    redistribute it and/or modify it under the terms of the GNU General
+    Public License as published by the Free Software Foundation, either
+    version 3 of the License, or (at your option) any later version.
+
+    yoshimi 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 for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with yoshimi.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef JACK_ENGINE_H
+#define JACK_ENGINE_H
+
+#include <string>
+#include <pthread.h>
+#include <semaphore.h>
+#include <jack/jack.h>
+#include <pthread.h>
+
+#include "MidiIn.h"
+#include "AudioOut.h"
+
+typedef jack_default_audio_sample_t jsample_t;
+
+class JackEngine:public AudioOut, MidiIn
+{
+    public:
+        JackEngine();
+        ~JackEngine() { }
+
+        bool Start();
+        void Stop();
+
+        void setMidiEn(bool nval);
+        bool getMidiEn() const;
+
+        void setAudioEn(bool nval);
+        bool getAudioEn() const;
+
+        int getBuffersize() { return audio.jackNframes; }
+
+        std::string clientName();
+        int clientId();
+
+    protected:
+
+        int processCallback(jack_nframes_t nframes);
+        static int _processCallback(jack_nframes_t nframes, void *arg);
+        int bufferSizeCallback(jack_nframes_t nframes);
+        static int _bufferSizeCallback(jack_nframes_t nframes, void *arg);
+        static void _errorCallback(const char *msg);
+        static void _infoCallback(const char *msg);
+        static int _xrunCallback(void *arg);
+
+    private:
+        bool connectServer(std::string server);
+        bool connectJack();
+        void disconnectJack();
+        bool openAudio();
+        void stopAudio();
+        bool processAudio(jack_nframes_t nframes);
+        bool openMidi();
+        void stopMidi();
+
+        jack_client_t *jackClient;
+        struct audio {
+            unsigned int jackSamplerate;
+            unsigned int jackNframes;
+            jack_port_t *ports[2];
+            jsample_t   *portBuffs[2];
+        } audio;
+        struct midi {
+            jack_port_t *inport;
+        } midi;
+
+        void handleMidi(unsigned long frames);
+};
+
+#endif
diff --git a/src/Nio/MidiIn.cpp b/src/Nio/MidiIn.cpp
new file mode 100644
index 0000000..3635bde
--- /dev/null
+++ b/src/Nio/MidiIn.cpp
@@ -0,0 +1,77 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  MidiIn.C - This class is inherited by all the Midi input classes
+  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 "MidiIn.h"
+#include "../globals.h"
+#include "InMgr.h"
+
+void MidiIn::midiProcess(unsigned char head,
+                         unsigned char num,
+                         unsigned char value)
+{
+    MidiEvent     ev;
+    unsigned char chan = head & 0x0f;
+    switch(head & 0xf0) {
+        case 0x80: //Note Off
+            ev.type    = M_NOTE;
+            ev.channel = chan;
+            ev.num     = num;
+            ev.value   = 0;
+            InMgr::getInstance().putEvent(ev);
+            break;
+        case 0x90: //Note On
+            ev.type    = M_NOTE;
+            ev.channel = chan;
+            ev.num     = num;
+            ev.value   = value;
+            InMgr::getInstance().putEvent(ev);
+            break;
+        case 0xA0: /* pressure, aftertouch */
+            ev.type    = M_PRESSURE;
+            ev.channel = chan;
+            ev.num     = num;
+            ev.value   = value;
+            InMgr::getInstance().putEvent(ev);
+            break;
+        case 0xb0: //Controller
+            ev.type    = M_CONTROLLER;
+            ev.channel = chan;
+            ev.num     = num;
+            ev.value   = value;
+            InMgr::getInstance().putEvent(ev);
+            break;
+        case 0xc0: //Program Change
+            ev.type    = M_PGMCHANGE;
+            ev.channel = chan;
+            ev.num     = num;
+            ev.value   = 0;
+            InMgr::getInstance().putEvent(ev);
+            break;
+        case 0xe0: //Pitch Wheel
+            ev.type    = M_CONTROLLER;
+            ev.channel = chan;
+            ev.num     = C_pitchwheel;
+            ev.value   = (num + value * (int) 128) - 8192;
+            InMgr::getInstance().putEvent(ev);
+            break;
+    }
+}
diff --git a/src/Nio/MidiIn.h b/src/Nio/MidiIn.h
new file mode 100644
index 0000000..780a67f
--- /dev/null
+++ b/src/Nio/MidiIn.h
@@ -0,0 +1,43 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  MidiIn.h - This class is inherited by all the Midi input classes
+  Copyright (C) 2002-2005 Nasca Octavian Paul
+  Copyright (C) 2009-2010 Mark McCurry
+  Author: Nasca Octavian Paula
+          Mark McCurry
+
+  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 MIDI_IN_H
+#define MIDI_IN_H
+
+#include "Engine.h"
+
+/**This class is inherited by all the Midi input classes*/
+class MidiIn:public virtual Engine
+{
+    public:
+        /**Enables or disables driver based upon value*/
+        virtual void setMidiEn(bool nval) = 0;
+        /**Returns if driver is initialized*/
+        virtual bool getMidiEn() const = 0;
+        static void midiProcess(unsigned char head,
+                                unsigned char num,
+                                unsigned char value);
+};
+
+#endif
diff --git a/src/Nio/Nio.cpp b/src/Nio/Nio.cpp
new file mode 100644
index 0000000..ee8d8f1
--- /dev/null
+++ b/src/Nio/Nio.cpp
@@ -0,0 +1,117 @@
+#include "Nio.h"
+#include "OutMgr.h"
+#include "InMgr.h"
+#include "EngineMgr.h"
+#include "MidiIn.h"
+#include "AudioOut.h"
+#include <iostream>
+#include <algorithm>
+using std::string;
+using std::set;
+using std::cerr;
+using std::endl;
+
+InMgr     *in  = NULL;
+OutMgr    *out = NULL;
+EngineMgr *eng = NULL;
+string     postfix;
+
+bool   Nio::autoConnect   = false;
+string Nio::defaultSource = IN_DEFAULT;
+string Nio::defaultSink   = OUT_DEFAULT;
+
+void Nio::init(void)
+{
+    in  = &InMgr::getInstance(); //Enable input wrapper
+    out = &OutMgr::getInstance(); //Initialize the Output Systems
+    eng = &EngineMgr::getInstance(); //Initialize The Engines
+}
+
+bool Nio::start()
+{
+    init();
+    return eng->start();
+}
+
+void Nio::stop()
+{
+    eng->stop();
+}
+
+void Nio::setDefaultSource(string name)
+{
+    std::transform(name.begin(), name.end(), name.begin(), ::toupper);
+    defaultSource = name;
+}
+
+void Nio::setDefaultSink(string name)
+{
+    std::transform(name.begin(), name.end(), name.begin(), ::toupper);
+    defaultSink = name;
+}
+
+bool Nio::setSource(string name)
+{
+    return in->setSource(name);
+}
+
+bool Nio::setSink(string name)
+{
+    return out->setSink(name);
+}
+
+void Nio::setPostfix(std::string post)
+{
+    postfix = post;
+}
+
+std::string Nio::getPostfix(void)
+{
+    return postfix;
+}
+
+set<string> Nio::getSources(void)
+{
+    set<string> sources;
+    for(std::list<Engine *>::iterator itr = eng->engines.begin();
+        itr != eng->engines.end(); ++itr)
+        if(dynamic_cast<MidiIn *>(*itr))
+            sources.insert((*itr)->name);
+    return sources;
+}
+
+set<string> Nio::getSinks(void)
+{
+    set<string> sinks;
+    for(std::list<Engine *>::iterator itr = eng->engines.begin();
+        itr != eng->engines.end(); ++itr)
+        if(dynamic_cast<AudioOut *>(*itr))
+            sinks.insert((*itr)->name);
+    return sinks;
+}
+
+string Nio::getSource()
+{
+    return in->getSource();
+}
+
+string Nio::getSink()
+{
+    return out->getSink();
+}
+
+#if JACK
+#include <jack/jack.h>
+void Nio::preferedSampleRate(unsigned &rate)
+{
+    jack_client_t *client = jack_client_open("temp-client",
+                                             JackNoStartServer, 0);
+    if(client) {
+        rate = jack_get_sample_rate(client);
+        jack_client_close(client);
+    }
+}
+#else
+void Nio::preferedSampleRate(unsigned &)
+{}
+#endif
diff --git a/src/Nio/Nio.h b/src/Nio/Nio.h
new file mode 100644
index 0000000..0cae472
--- /dev/null
+++ b/src/Nio/Nio.h
@@ -0,0 +1,38 @@
+#ifndef NIO_H
+#define NIO_H
+#include <string>
+#include <set>
+
+/**Interface to Nio Subsystem
+ *
+ * Should be only externally included header */
+namespace Nio
+{
+    void init(void);
+    bool start(void);
+    void stop(void);
+
+    void setDefaultSource(std::string name);
+    void setDefaultSink(std::string name);
+
+    bool setSource(std::string name);
+    bool setSink(std::string name);
+
+    void setPostfix(std::string post);
+    std::string getPostfix(void);
+
+    std::set<std::string> getSources(void);
+    std::set<std::string> getSinks(void);
+
+    std::string getSource(void);
+    std::string getSink(void);
+
+    //Get the prefered sample rate from jack (if running)
+    void preferedSampleRate(unsigned &rate);
+
+    extern bool autoConnect;
+    extern std::string defaultSource;
+    extern std::string defaultSink;
+};
+
+#endif
diff --git a/src/Nio/NulEngine.cpp b/src/Nio/NulEngine.cpp
new file mode 100644
index 0000000..633e2ae
--- /dev/null
+++ b/src/Nio/NulEngine.cpp
@@ -0,0 +1,113 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  OSSaudiooutput.C - Audio output for Open Sound System
+  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 "NulEngine.h"
+#include "../globals.h"
+
+#include <unistd.h>
+#include <iostream>
+
+using namespace std;
+
+NulEngine::NulEngine()
+    :AudioOut(), pThread(NULL)
+{
+    name = "NULL";
+    playing_until.tv_sec  = 0;
+    playing_until.tv_usec = 0;
+}
+
+void *NulEngine::_AudioThread(void *arg)
+{
+    return (static_cast<NulEngine *>(arg))->AudioThread();
+}
+
+void *NulEngine::AudioThread()
+{
+    while(pThread) {
+        getNext();
+
+        struct timeval now;
+        int remaining = 0;
+        gettimeofday(&now, NULL);
+        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 {
+            remaining = (playing_until.tv_usec - now.tv_usec)
+                        + (playing_until.tv_sec - now.tv_sec) * 1000000;
+            if(remaining > 10000) //Don't sleep() less than 10ms.
+                //This will add latency...
+                usleep(remaining - 10000);
+            if(remaining < 0)
+                cerr << "WARNING - too late" << endl;
+        }
+        playing_until.tv_usec += synth->buffersize * 1000000
+                                 / synth->samplerate;
+        if(remaining < 0)
+            playing_until.tv_usec -= remaining;
+        playing_until.tv_sec  += playing_until.tv_usec / 1000000;
+        playing_until.tv_usec %= 1000000;
+    }
+    return NULL;
+}
+
+NulEngine::~NulEngine()
+{}
+
+bool NulEngine::Start()
+{
+    setAudioEn(true);
+    return getAudioEn();
+}
+
+void NulEngine::Stop()
+{
+    setAudioEn(false);
+}
+
+void NulEngine::setAudioEn(bool nval)
+{
+    if(nval) {
+        if(!getAudioEn()) {
+            pthread_t     *thread = new pthread_t;
+            pthread_attr_t attr;
+            pthread_attr_init(&attr);
+            pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+            pThread = thread;
+            pthread_create(pThread, &attr, _AudioThread, this);
+        }
+    }
+    else
+    if(getAudioEn()) {
+        pthread_t *thread = pThread;
+        pThread = NULL;
+        pthread_join(*thread, NULL);
+        delete thread;
+    }
+}
+
+bool NulEngine::getAudioEn() const
+{
+    return pThread;
+}
diff --git a/src/Nio/NulEngine.h b/src/Nio/NulEngine.h
new file mode 100644
index 0000000..1834180
--- /dev/null
+++ b/src/Nio/NulEngine.h
@@ -0,0 +1,56 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  NulEngine.h - Dummy In/Out driver
+  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 NUL_ENGINE_H
+#define NUL_ENGINE_H
+
+#include <sys/time.h>
+#include <pthread.h>
+#include "../globals.h"
+#include "AudioOut.h"
+#include "MidiIn.h"
+
+class NulEngine:public AudioOut, MidiIn
+{
+    public:
+        NulEngine();
+        ~NulEngine();
+
+        bool Start();
+        void Stop();
+
+        void setAudioEn(bool nval);
+        bool getAudioEn() const;
+
+        void setMidiEn(bool) {}
+        bool getMidiEn() const {return true; }
+
+    protected:
+        void *AudioThread();
+        static void *_AudioThread(void *arg);
+
+    private:
+        struct timeval playing_until;
+        pthread_t     *pThread;
+};
+
+#endif
diff --git a/src/Nio/OssEngine.cpp b/src/Nio/OssEngine.cpp
new file mode 100644
index 0000000..a958766
--- /dev/null
+++ b/src/Nio/OssEngine.cpp
@@ -0,0 +1,281 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  OSSaudiooutput.C - Audio output for Open Sound System
+  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 "OssEngine.h"
+#include "../Misc/Util.h"
+#include "../globals.h"
+
+#include <cstring>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/soundcard.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <iostream>
+
+#include "InMgr.h"
+
+using namespace std;
+
+OssEngine::OssEngine()
+    :AudioOut(), engThread(NULL)
+{
+    name = "OSS";
+
+    midi.handle  = -1;
+    audio.handle = -1;
+
+    audio.smps = new short[synth->buffersize * 2];
+    memset(audio.smps, 0, synth->bufferbytes);
+}
+
+OssEngine::~OssEngine()
+{
+    Stop();
+    delete [] audio.smps;
+}
+
+bool OssEngine::openAudio()
+{
+    if(audio.handle != -1)
+        return true;  //already open
+
+    int snd_bitsize    = 16;
+    int snd_fragment   = 0x00080009; //fragment size (?);
+    int snd_stereo     = 1; //stereo;
+    int snd_format     = AFMT_S16_LE;
+    int snd_samplerate = synth->samplerate;
+
+    audio.handle = open(config.cfg.LinuxOSSWaveOutDev, O_WRONLY, 0);
+    if(audio.handle == -1) {
+        cerr << "ERROR - I can't open the "
+             << config.cfg.LinuxOSSWaveOutDev << '.' << endl;
+        return false;
+    }
+    ioctl(audio.handle, SNDCTL_DSP_RESET, NULL);
+    ioctl(audio.handle, SNDCTL_DSP_SETFMT, &snd_format);
+    ioctl(audio.handle, SNDCTL_DSP_STEREO, &snd_stereo);
+    ioctl(audio.handle, SNDCTL_DSP_SPEED, &snd_samplerate);
+    ioctl(audio.handle, SNDCTL_DSP_SAMPLESIZE, &snd_bitsize);
+    ioctl(audio.handle, SNDCTL_DSP_SETFRAGMENT, &snd_fragment);
+
+    if(!getMidiEn()) {
+        pthread_attr_t attr;
+        pthread_attr_init(&attr);
+        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+        engThread = new pthread_t;
+        pthread_create(engThread, &attr, _thread, this);
+    }
+
+    return true;
+}
+
+void OssEngine::stopAudio()
+{
+    int handle = audio.handle;
+    if(handle == -1) //already closed
+        return;
+    audio.handle = -1;
+
+    if(!getMidiEn() && engThread)
+        pthread_join(*engThread, NULL);
+    delete engThread;
+    engThread = NULL;
+
+    close(handle);
+}
+
+bool OssEngine::Start()
+{
+    bool good = true;
+
+    if(!openAudio()) {
+        cerr << "Failed to open OSS audio" << endl;
+        good = false;
+    }
+
+    if(!openMidi()) {
+        cerr << "Failed to open OSS midi" << endl;
+        good = false;
+    }
+
+    return good;
+}
+
+void OssEngine::Stop()
+{
+    stopAudio();
+    stopMidi();
+}
+
+void OssEngine::setMidiEn(bool nval)
+{
+    if(nval)
+        openMidi();
+    else
+        stopMidi();
+}
+
+bool OssEngine::getMidiEn() const
+{
+    return midi.handle != -1;
+}
+
+void OssEngine::setAudioEn(bool nval)
+{
+    if(nval)
+        openAudio();
+    else
+        stopAudio();
+}
+
+bool OssEngine::getAudioEn() const
+{
+    return audio.handle != -1;
+}
+
+bool OssEngine::openMidi()
+{
+    int handle = midi.handle;
+    if(handle != -1)
+        return true;  //already open
+
+    handle = open(config.cfg.LinuxOSSSeqInDev, O_RDONLY, 0);
+
+    if(-1 == handle)
+        return false;
+    midi.handle = handle;
+
+    if(!getAudioEn()) {
+        pthread_attr_t attr;
+        pthread_attr_init(&attr);
+        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+        engThread = new pthread_t;
+        pthread_create(engThread, &attr, _thread, this);
+    }
+
+    return true;
+}
+
+void OssEngine::stopMidi()
+{
+    int handle = midi.handle;
+    if(handle == -1) //already closed
+        return;
+
+    midi.handle = -1;
+
+    if(!getAudioEn() && engThread) {
+        pthread_join(*engThread, NULL);
+        delete engThread;
+        engThread = NULL;
+    }
+
+    close(handle);
+}
+
+void *OssEngine::_thread(void *arg)
+{
+    return (static_cast<OssEngine *>(arg))->thread();
+}
+
+void *OssEngine::thread()
+{
+    unsigned char tmp[4] = {0, 0, 0, 0};
+    set_realtime();
+    while(getAudioEn() || getMidiEn()) {
+        if(getAudioEn()) {
+            const Stereo<float *> smps = getNext();
+
+            float l, r;
+            for(int i = 0; i < synth->buffersize; ++i) {
+                l = smps.l[i];
+                r = smps.r[i];
+
+                if(l < -1.0f)
+                    l = -1.0f;
+                else
+                if(l > 1.0f)
+                    l = 1.0f;
+                if(r < -1.0f)
+                    r = -1.0f;
+                else
+                if(r > 1.0f)
+                    r = 1.0f;
+
+                audio.smps[i * 2]     = (short int) (l * 32767.0f);
+                audio.smps[i * 2 + 1] = (short int) (r * 32767.0f);
+            }
+            int handle = audio.handle;
+            if(handle != -1)
+                write(handle, audio.smps, synth->buffersize * 4);  // *2 because is 16 bit, again * 2 because is stereo
+            else
+                break;
+        }
+
+        //Collect up to 30 midi events
+        for(int k = 0; k < 30 && getMidiEn(); ++k) {
+            static char escaped;
+
+            memset(tmp, 0, 4);
+
+            if(escaped) {
+                tmp[0]  = escaped;
+                escaped = 0;
+            }
+            else {
+                getMidi(tmp);
+                if(!(tmp[0] & 0x80))
+                    continue;
+            }
+            getMidi(tmp + 1);
+            if(tmp[1] & 0x80) {
+                escaped = tmp[1];
+                tmp[1]  = 0;
+            }
+            else {
+                getMidi(tmp + 2);
+                if(tmp[2] & 0x80) {
+                    escaped = tmp[2];
+                    tmp[2]  = 0;
+                }
+                else {
+                    getMidi(tmp + 3);
+                    if(tmp[3] & 0x80) {
+                        escaped = tmp[3];
+                        tmp[3]  = 0;
+                    }
+                }
+            }
+            midiProcess(tmp[0], tmp[1], tmp[2]);
+        }
+    }
+    pthread_exit(NULL);
+    return NULL;
+}
+
+void OssEngine::getMidi(unsigned char *midiPtr)
+{
+    read(midi.handle, midiPtr, 1);
+}
diff --git a/src/Nio/OssEngine.h b/src/Nio/OssEngine.h
new file mode 100644
index 0000000..cdccc81
--- /dev/null
+++ b/src/Nio/OssEngine.h
@@ -0,0 +1,76 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  OSSaudiooutput.h - Audio output for Open Sound System
+  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 OSS_ENGINE_H
+#define OSS_ENGINE_H
+
+#include <sys/time.h>
+#include "../globals.h"
+#include "AudioOut.h"
+#include "MidiIn.h"
+
+class OssEngine:public AudioOut, MidiIn
+{
+    public:
+        OssEngine();
+        ~OssEngine();
+
+        bool Start();
+        void Stop();
+
+        void setAudioEn(bool nval);
+        bool getAudioEn() const;
+
+        void setMidiEn(bool nval);
+        bool getMidiEn() const;
+
+
+    protected:
+        void *thread();
+        static void *_thread(void *arg);
+
+    private:
+        pthread_t *engThread;
+
+        //Audio
+        bool openAudio();
+        void stopAudio();
+
+        struct audio {
+            int handle;
+            short int *smps; //Samples to be sent to soundcard
+            bool en;
+        } audio;
+
+        //Midi
+        bool openMidi();
+        void stopMidi();
+        void getMidi(unsigned char *midiPtr);
+
+        struct midi {
+            int  handle;
+            bool en;
+            bool run;
+        } midi;
+};
+
+#endif
diff --git a/src/Nio/OutMgr.cpp b/src/Nio/OutMgr.cpp
new file mode 100644
index 0000000..ea270bf
--- /dev/null
+++ b/src/Nio/OutMgr.cpp
@@ -0,0 +1,182 @@
+#include "OutMgr.h"
+#include <algorithm>
+#include <iostream>
+#include <cassert>
+#include "AudioOut.h"
+#include "Engine.h"
+#include "EngineMgr.h"
+#include "InMgr.h"
+#include "WavEngine.h"
+#include "../Misc/Master.h"
+#include "../Misc/Util.h" //for set_realtime()
+
+using namespace std;
+
+OutMgr &OutMgr::getInstance()
+{
+    static OutMgr instance;
+    return instance;
+}
+
+OutMgr::OutMgr()
+    :wave(new WavEngine()),
+      priBuf(new float[4096],
+             new float[4096]), priBuffCurrent(priBuf),
+      master(Master::getInstance())
+{
+    currentOut = NULL;
+    stales     = 0;
+    master     = Master::getInstance();
+
+    //init samples
+    outr = new float[synth->buffersize];
+    outl = new float[synth->buffersize];
+    memset(outl, 0, synth->bufferbytes);
+    memset(outr, 0, synth->bufferbytes);
+}
+
+OutMgr::~OutMgr()
+{
+    delete wave;
+    delete [] priBuf.l;
+    delete [] priBuf.r;
+    delete [] outr;
+    delete [] outl;
+}
+
+/* Sequence of a tick
+ * 1) lets see if we have any stuff to do via midi
+ * 2) Lets do that stuff
+ * 3) Lets see if the event queue has anything for us
+ * 4) Lets empty that out
+ * 5) Lets remove old/stale samples
+ * 6) Lets see if we need to generate samples
+ * 7) Lets generate some
+ * 8) Lets return those samples to the primary and secondary outputs
+ * 9) Lets wait for another tick
+ */
+const Stereo<float *> OutMgr::tick(unsigned int frameSize)
+{
+    pthread_mutex_lock(&(master.mutex));
+    InMgr::getInstance().flush();
+    pthread_mutex_unlock(&(master.mutex));
+    //SysEv->execute();
+    removeStaleSmps();
+    while(frameSize > storedSmps()) {
+        pthread_mutex_lock(&(master.mutex));
+        master.AudioOut(outl, outr);
+        pthread_mutex_unlock(&(master.mutex));
+        addSmps(outl, outr);
+    }
+    stales = frameSize;
+    return priBuf;
+}
+
+AudioOut *OutMgr::getOut(string name)
+{
+    return dynamic_cast<AudioOut *>(EngineMgr::getInstance().getEng(name));
+}
+
+string OutMgr::getDriver() const
+{
+    return currentOut->name;
+}
+
+bool OutMgr::setSink(string name)
+{
+    AudioOut *sink = getOut(name);
+
+    if(!sink)
+        return false;
+
+    if(currentOut)
+        currentOut->setAudioEn(false);
+
+    currentOut = sink;
+    currentOut->setAudioEn(true);
+
+    bool success = currentOut->getAudioEn();
+
+    //Keep system in a valid state (aka with a running driver)
+    if(!success)
+        (currentOut = getOut("NULL"))->setAudioEn(true);
+
+    return success;
+}
+
+string OutMgr::getSink() const
+{
+    if(currentOut)
+        return currentOut->name;
+    else {
+        cerr << "BUG: No current output in OutMgr " << __LINE__ << endl;
+        return "ERROR";
+    }
+    return "ERROR";
+}
+
+//perform a cheap linear interpolation for resampling
+//This will result in some distortion at frame boundries
+//returns number of samples produced
+static size_t resample(float *dest,
+                       const float *src,
+                       float s_in,
+                       float s_out,
+                       size_t elms)
+{
+    size_t out_elms = elms * s_out / s_in;
+    float  r_pos    = 0.0f;
+    for(int i = 0; i < (int)out_elms; ++i, r_pos += s_in / s_out)
+        dest[i] = interpolate(src, elms, r_pos);
+
+    return out_elms;
+}
+
+void OutMgr::addSmps(float *l, float *r)
+{
+    //allow wave file to syphon off stream
+    wave->push(Stereo<float *>(l, r), synth->buffersize);
+
+    const int s_out = currentOut->getSampleRate(),
+              s_sys = synth->samplerate;
+
+    if(s_out != s_sys) { //we need to resample
+        const size_t steps = resample(priBuffCurrent.l,
+                                      l,
+                                      s_sys,
+                                      s_out,
+                                      synth->buffersize);
+        resample(priBuffCurrent.r, r, s_sys, s_out, synth->buffersize);
+
+        priBuffCurrent.l += steps;
+        priBuffCurrent.r += steps;
+    }
+    else { //just copy the samples
+        memcpy(priBuffCurrent.l, l, synth->bufferbytes);
+        memcpy(priBuffCurrent.r, r, synth->bufferbytes);
+        priBuffCurrent.l += synth->buffersize;
+        priBuffCurrent.r += synth->buffersize;
+    }
+}
+
+void OutMgr::removeStaleSmps()
+{
+    if(!stales)
+        return;
+
+    const int leftover = storedSmps() - stales;
+
+    assert(leftover > -1);
+
+    //leftover samples [seen at very low latencies]
+    if(leftover) {
+        memmove(priBuf.l, priBuffCurrent.l - leftover, leftover * sizeof(float));
+        memmove(priBuf.r, priBuffCurrent.r - leftover, leftover * sizeof(float));
+        priBuffCurrent.l = priBuf.l + leftover;
+        priBuffCurrent.r = priBuf.r + leftover;
+    }
+    else
+        priBuffCurrent = priBuf;
+
+    stales = 0;
+}
diff --git a/src/Nio/OutMgr.h b/src/Nio/OutMgr.h
new file mode 100644
index 0000000..a1cdd8b
--- /dev/null
+++ b/src/Nio/OutMgr.h
@@ -0,0 +1,64 @@
+#ifndef OUTMGR_H
+#define OUTMGR_H
+
+#include "../Misc/Stereo.h"
+#include <list>
+#include <string>
+#include <semaphore.h>
+
+
+class AudioOut;
+class OutMgr
+{
+    public:
+        static OutMgr &getInstance();
+        ~OutMgr();
+
+        /**Execute a tick*/
+        const Stereo<float *> tick(unsigned int frameSize);
+
+        /**Request a new set of samples
+         * @param n number of requested samples (defaults to 1)
+         * @return -1 for locking issues 0 for valid request*/
+        void requestSamples(unsigned int n = 1);
+
+        /**Gets requested driver
+         * @param name case unsensitive name of driver
+         * @return pointer to Audio Out or NULL
+         */
+        AudioOut *getOut(std::string name);
+
+        /**Gets the name of the first running driver
+         * Deprecated
+         * @return if no running output, "" is returned
+         */
+        std::string getDriver() const;
+
+        bool setSink(std::string name);
+
+        std::string getSink() const;
+
+        class WavEngine * wave;     /**<The Wave Recorder*/
+        friend class EngineMgr;
+    private:
+        OutMgr();
+        void addSmps(float *l, float *r);
+        unsigned int  storedSmps() const {return priBuffCurrent.l - priBuf.l; }
+        void removeStaleSmps();
+
+        AudioOut *currentOut; /**<The current output driver*/
+
+        sem_t requested;
+
+        /**Buffer*/
+        Stereo<float *> priBuf;          //buffer for primary drivers
+        Stereo<float *> priBuffCurrent; //current array accessor
+
+        float *outl;
+        float *outr;
+        class Master & master;
+
+        int stales;
+};
+
+#endif
diff --git a/src/Nio/PaEngine.cpp b/src/Nio/PaEngine.cpp
new file mode 100644
index 0000000..d41543b
--- /dev/null
+++ b/src/Nio/PaEngine.cpp
@@ -0,0 +1,118 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  PaEngine.cpp - Audio output for PortAudio
+  Copyright (C) 2002 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 "PaEngine.h"
+#include <iostream>
+
+using namespace std;
+
+PaEngine::PaEngine()
+    :stream(NULL)
+{
+    name = "PA";
+}
+
+
+PaEngine::~PaEngine()
+{
+    Stop();
+}
+
+bool PaEngine::Start()
+{
+    if(getAudioEn())
+        return true;
+    Pa_Initialize();
+
+    PaStreamParameters outputParameters;
+    outputParameters.device = Pa_GetDefaultOutputDevice();
+    if(outputParameters.device == paNoDevice) {
+        cerr << "Error: No default output device." << endl;
+        Pa_Terminate();
+        return false;
+    }
+    outputParameters.channelCount     = 2; /* stereo output */
+    outputParameters.sampleFormat     = paFloat32; /* 32 bit floating point output */
+    outputParameters.suggestedLatency =
+        Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+
+
+    Pa_OpenStream(&stream,
+                  NULL,
+                  &outputParameters,
+                  synth->samplerate,
+                  synth->buffersize,
+                  0,
+                  PAprocess,
+                  (void *) this);
+    Pa_StartStream(stream);
+    return true;
+}
+
+void PaEngine::setAudioEn(bool nval)
+{
+    if(nval)
+        Start();
+    else
+        Stop();
+}
+
+bool PaEngine::getAudioEn() const
+{
+    return stream;
+}
+
+int PaEngine::PAprocess(const void *inputBuffer,
+                        void *outputBuffer,
+                        unsigned long framesPerBuffer,
+                        const PaStreamCallbackTimeInfo *outTime,
+                        PaStreamCallbackFlags flags,
+                        void *userData)
+{
+    (void) inputBuffer;
+    (void) outTime;
+    (void) flags;
+    return static_cast<PaEngine *>(userData)->process((float *) outputBuffer,
+                                                      framesPerBuffer);
+}
+
+int PaEngine::process(float *out, unsigned long framesPerBuffer)
+{
+    const Stereo<float *> smp = getNext();
+    for(unsigned i = 0; i < framesPerBuffer; ++i) {
+        *out++ = smp.l[i];
+        *out++ = smp.r[i];
+    }
+
+    return 0;
+}
+
+void PaEngine::Stop()
+{
+    if(!getAudioEn())
+        return;
+    Pa_StopStream(stream);
+    Pa_CloseStream(stream);
+    stream = NULL;
+    Pa_Terminate();
+}
diff --git a/src/Nio/PaEngine.h b/src/Nio/PaEngine.h
new file mode 100644
index 0000000..12fd766
--- /dev/null
+++ b/src/Nio/PaEngine.h
@@ -0,0 +1,57 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  PAaudiooutput.h - Audio output for PortAudio
+  Copyright (C) 2002 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 PA_ENGINE_H
+#define PA_ENGINE_H
+
+#include <portaudio.h>
+
+#include "../globals.h"
+#include "AudioOut.h"
+
+class PaEngine:public AudioOut
+{
+    public:
+        PaEngine();
+        ~PaEngine();
+
+        bool Start();
+        void Stop();
+
+        void setAudioEn(bool nval);
+        bool getAudioEn() const;
+
+    protected:
+        static int PAprocess(const void *inputBuffer,
+                             void *outputBuffer,
+                             unsigned long framesPerBuffer,
+                             const PaStreamCallbackTimeInfo *outTime,
+                             PaStreamCallbackFlags flags,
+                             void *userData);
+        int process(float *out, unsigned long framesPerBuffer);
+    private:
+        PaStream *stream;
+};
+
+
+void PAfinish();
+
+#endif
diff --git a/src/Nio/SafeQueue.cpp b/src/Nio/SafeQueue.cpp
new file mode 100644
index 0000000..734413c
--- /dev/null
+++ b/src/Nio/SafeQueue.cpp
@@ -0,0 +1,82 @@
+
+template<class T>
+SafeQueue<T>::SafeQueue(size_t maxlen)
+    :writePtr(0), readPtr(0), bufSize(maxlen)
+{
+    sem_init(&w_space, PTHREAD_PROCESS_PRIVATE, maxlen - 1);
+    sem_init(&r_space, PTHREAD_PROCESS_PRIVATE, 0);
+    buffer = new T[maxlen];
+}
+
+template<class T>
+SafeQueue<T>::~SafeQueue()
+{
+    sem_destroy(&w_space);
+    sem_destroy(&r_space);
+    delete [] buffer;
+}
+
+template<class T>
+unsigned int SafeQueue<T>::size() const
+{
+    return rSpace();
+}
+
+template<class T>
+unsigned int SafeQueue<T>::rSpace() const
+{
+    int space = 0;
+    sem_getvalue(&r_space, &space);
+    return space;
+}
+
+template<class T>
+unsigned int SafeQueue<T>::wSpace() const
+{
+    int space = 0;
+    sem_getvalue(&w_space, &space);
+    return space;
+}
+
+template<class T>
+int SafeQueue<T>::push(const T &in)
+{
+    if(!wSpace())
+        return -1;
+
+    //ok, there is space to write
+    size_t w = (writePtr + 1) % bufSize;
+    buffer[w] = in;
+    writePtr  = w;
+
+    //adjust ranges
+    sem_wait(&w_space); //guaranteed not to wait
+    sem_post(&r_space);
+    return 0;
+}
+
+template<class T>
+int SafeQueue<T>::pop(T &out)
+{
+    if(!rSpace())
+        return -1;
+
+    //ok, there is space to read
+    size_t r = (readPtr + 1) % bufSize;
+    out     = buffer[r];
+    readPtr = r;
+
+    //adjust ranges
+    sem_wait(&r_space); //guaranteed not to wait
+    sem_post(&w_space);
+    return 0;
+}
+
+template<class T>
+void SafeQueue<T>::clear()
+{
+    //thread unsafe
+    while(!sem_trywait(&r_space))
+        sem_post(&w_space);
+    readPtr = writePtr;
+}
diff --git a/src/Nio/SafeQueue.h b/src/Nio/SafeQueue.h
new file mode 100644
index 0000000..7b41166
--- /dev/null
+++ b/src/Nio/SafeQueue.h
@@ -0,0 +1,46 @@
+
+#ifndef SAFEQUEUE_H
+#define SAFEQUEUE_H
+#include <cstdlib>
+#include <semaphore.h>
+
+/**
+ * C++ thread safe lockless queue
+ * Based off of jack's ringbuffer*/
+template<class T>
+class SafeQueue
+{
+    public:
+        SafeQueue(size_t maxlen);
+        ~SafeQueue();
+
+        /**Return read size*/
+        unsigned int size() const;
+
+        /**Returns 0 for normal
+         * Returns -1 on error*/
+        int push(const T &in);
+        int pop(T &out);
+
+        //clears reading space
+        void clear();
+
+    private:
+        unsigned int wSpace() const;
+        unsigned int rSpace() const;
+
+        //write space
+        mutable sem_t w_space;
+        //read space
+        mutable sem_t r_space;
+
+        //next writing spot
+        size_t writePtr;
+        //next reading spot
+        size_t readPtr;
+        const size_t bufSize;
+        T *buffer;
+};
+
+#include "SafeQueue.cpp"
+#endif
diff --git a/src/Nio/WavEngine.cpp b/src/Nio/WavEngine.cpp
new file mode 100644
index 0000000..9d0d2df
--- /dev/null
+++ b/src/Nio/WavEngine.cpp
@@ -0,0 +1,134 @@
+/*
+  Copyright (C) 2006 Nasca Octavian Paul
+  Author: Nasca Octavian Paul
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License (version 2) for more details.
+
+  You should have received a copy of the GNU General Public License (version 2)
+  along with this program; if not, write to the Free Software Foundation,
+  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+*/
+
+#include "WavEngine.h"
+#include <cstdio>
+#include <iostream>
+#include <cstdlib>
+#include "../Misc/WavFile.h"
+#include "../Misc/Util.h"
+
+using namespace std;
+
+WavEngine::WavEngine()
+    :AudioOut(), file(NULL), buffer(synth->samplerate * 4), pThread(NULL)
+{
+    sem_init(&work, PTHREAD_PROCESS_PRIVATE, 0);
+}
+
+WavEngine::~WavEngine()
+{
+    Stop();
+    sem_destroy(&work);
+    destroyFile();
+}
+
+bool WavEngine::openAudio()
+{
+    return file && file->good();
+}
+
+bool WavEngine::Start()
+{
+    if(pThread)
+        return true;
+    pThread = new pthread_t;
+
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+    pthread_create(pThread, &attr, _AudioThread, this);
+
+    return true;
+}
+
+void WavEngine::Stop()
+{
+    if(!pThread)
+        return;
+
+    pthread_t *tmp = pThread;
+    pThread = NULL;
+
+    sem_post(&work);
+    pthread_join(*tmp, NULL);
+    delete pThread;
+}
+
+void WavEngine::push(Stereo<float *> smps, size_t len)
+{
+    if(!pThread)
+        return;
+
+
+    //copy the input [overflow when needed]
+    for(size_t i = 0; i < len; ++i) {
+        buffer.push(*smps.l++);
+        buffer.push(*smps.r++);
+    }
+    sem_post(&work);
+}
+
+void WavEngine::newFile(WavFile *_file)
+{
+    //ensure system is clean
+    destroyFile();
+    file = _file;
+
+    //check state
+    if(!file->good())
+        cerr
+        << "ERROR: WavEngine handed bad file output WavEngine::newFile()"
+        << endl;
+}
+
+void WavEngine::destroyFile()
+{
+    if(file)
+        delete file;
+    file = NULL;
+}
+
+void *WavEngine::_AudioThread(void *arg)
+{
+    return (static_cast<WavEngine *>(arg))->AudioThread();
+}
+
+void *WavEngine::AudioThread()
+{
+    short *recordbuf_16bit = new short[2 * synth->buffersize];
+
+    while(!sem_wait(&work) && pThread) {
+        for(int i = 0; i < synth->buffersize; ++i) {
+            float left = 0.0f, right = 0.0f;
+            buffer.pop(left);
+            buffer.pop(right);
+            recordbuf_16bit[2 * i] = limit((int)(left * 32767.0f),
+                                           -32768,
+                                           32767);
+            recordbuf_16bit[2 * i + 1] = limit((int)(right * 32767.0f),
+                                               -32768,
+                                               32767);
+        }
+        file->writeStereoSamples(synth->buffersize, recordbuf_16bit);
+    }
+
+    delete[] recordbuf_16bit;
+
+    return NULL;
+}
diff --git a/src/Nio/WavEngine.h b/src/Nio/WavEngine.h
new file mode 100644
index 0000000..8f55238
--- /dev/null
+++ b/src/Nio/WavEngine.h
@@ -0,0 +1,61 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  WavEngine.h - Records sound to a file
+  Copyright (C) 2008 Nasca Octavian Paul
+  Author: Nasca Octavian Paul
+          Mark McCurry
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License (version 2) for more details.
+
+  You should have received a copy of the GNU General Public License (version 2)
+  along with this program; if not, write to the Free Software Foundation,
+  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+*/
+
+#ifndef WAVENGINE_H
+#define WAVENGINE_H
+#include "AudioOut.h"
+#include <string>
+#include <pthread.h>
+#include <semaphore.h>
+#include "SafeQueue.h"
+
+class WavFile;
+class WavEngine:public AudioOut
+{
+    public:
+        WavEngine();
+        ~WavEngine();
+
+        bool openAudio();
+        bool Start();
+        void Stop();
+
+        void setAudioEn(bool /*nval*/) {}
+        bool getAudioEn() const {return true; }
+
+        void push(Stereo<float *> smps, size_t len);
+
+        void newFile(WavFile *_file);
+        void destroyFile();
+
+    protected:
+        void *AudioThread();
+        static void *_AudioThread(void *arg);
+
+    private:
+        WavFile *file;
+        sem_t    work;
+        SafeQueue<float> buffer;
+
+        pthread_t *pThread;
+};
+#endif
diff --git a/src/Output/DSSIaudiooutput.cpp b/src/Output/DSSIaudiooutput.cpp
index 7137abc..162836c 100644
--- a/src/Output/DSSIaudiooutput.cpp
+++ b/src/Output/DSSIaudiooutput.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  DSSIaudiooutput.C - Audio functions for DSSI
+  DSSIaudiooutput.cpp - Audio functions for DSSI
   Copyright (C) 2002 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -20,269 +20,679 @@
 
 */
 
+/*
+ * Inital working DSSI output code contributed by Stephen G. Parry
+ */
+
 //this file contains code used from trivial_synth.c from
-//the DSSI (published by Steve Harris under public domain) as a template
-//the code is incomplete
-#include <string.h>
-#include "DSSIaudiooutput.h"
+//the DSSI (published by Steve Harris under public domain) as a template.
 
-static LADSPA_Descriptor *tsLDescriptor = NULL;
-static DSSI_Descriptor *tsDDescriptor = NULL;
+#include "DSSIaudiooutput.h"
+#include "../Misc/Config.h"
+#include "../Misc/Bank.h"
+#include "../Misc/Util.h"
+#include <string.h>
+#include <limits.h>
+
+using std::string;
+using std::vector;
+
+//
+// Static stubs for LADSPA member functions
+//
+// LADSPA is essentially a C handle based API; This plug-in implementation is
+// a C++ OO one so we need stub functions to map from C API calls to C++ object
+// method calls.
+void DSSIaudiooutput::stub_connectPort(LADSPA_Handle instance,
+                                       unsigned long port,
+                                       LADSPA_Data *data)
+{
+    getInstance(instance)->connectPort(port, data);
+}
 
-typedef struct {
-    LADSPA_Data *outl;
-    LADSPA_Data *outr;
-//    note_data data[MIDI_NOTES];
-//    float omega[MIDI_NOTES];
-} TS;
+void DSSIaudiooutput::stub_activate(LADSPA_Handle instance)
+{
+    getInstance(instance)->activate();
+}
 
+void DSSIaudiooutput::stub_run(LADSPA_Handle instance,
+                               unsigned long sample_count)
+{
+    getInstance(instance)->run(sample_count);
+}
 
-static void cleanupTS(LADSPA_Handle instance)
+void DSSIaudiooutput::stub_deactivate(LADSPA_Handle instance)
 {
-    free(instance);
+    getInstance(instance)->deactivate();
 }
-static void connectPortTS(LADSPA_Handle instance, unsigned long port,
-                          LADSPA_Data * data)
+
+
+void DSSIaudiooutput::stub_cleanup(LADSPA_Handle instance)
 {
-    TS *plugin;
-    plugin = (TS *) instance;
-    switch (port) {
-    case 0:
-        plugin->outl = data;
-        break;
-    case 1:
-        plugin->outr = data;
-        break;
-    }
+    DSSIaudiooutput *plugin_instance = getInstance(instance);
+    plugin_instance->cleanup();
+    delete plugin_instance;
 }
 
+
 const LADSPA_Descriptor *ladspa_descriptor(unsigned long index)
 {
-    switch (index) {
-    case 0:
-        return tsLDescriptor;
-    default:
-        return NULL;
-    }
+    return DSSIaudiooutput::getLadspaDescriptor(index);
+}
+
+//
+// Static stubs for DSSI member functions
+//
+// DSSI is essentially a C handle based API; This plug-in implementation is
+// a C++ OO one so we need stub functions to map from C API calls to C++ object
+// method calls.
+const DSSI_Program_Descriptor *DSSIaudiooutput::stub_getProgram(
+    LADSPA_Handle instance,
+    unsigned long index)
+{
+    return getInstance(instance)->getProgram(index);
+}
+
+void DSSIaudiooutput::stub_selectProgram(LADSPA_Handle instance,
+                                         unsigned long bank,
+                                         unsigned long program)
+{
+    getInstance(instance)->selectProgram(bank, program);
+}
+
+int DSSIaudiooutput::stub_getMidiControllerForPort(LADSPA_Handle instance,
+                                                   unsigned long port)
+{
+    return getInstance(instance)->getMidiControllerForPort(port);
+}
+
+void DSSIaudiooutput::stub_runSynth(LADSPA_Handle instance,
+                                    unsigned long sample_count,
+                                    snd_seq_event_t *events,
+                                    unsigned long event_count)
+{
+    getInstance(instance)->runSynth(sample_count, events, event_count);
 }
 
 const DSSI_Descriptor *dssi_descriptor(unsigned long index)
 {
-//    FILE *a=fopen("/tmp/zzzzz11z","w");
-//    fprintf(a,"aaaaaaaaaaa  TEST\n");
-//    fclose(a);
-    switch (index) {
-    case 0:
-        return tsDDescriptor;
-    default:
+    return DSSIaudiooutput::getDssiDescriptor(index);
+}
+
+//
+// LADSPA member functions
+//
+
+/**
+ * Instantiates a plug-in.
+ *
+ * This LADSPA member function instantiates a plug-in.
+ * Note that instance initialisation should generally occur in
+ * activate() rather than here.
+ *
+ * Zyn Implementation
+ * ------------------
+ * This implementation creates a C++ class object and hides its pointer
+ * in the handle by type casting.
+ *
+ * @param descriptor [in] the descriptor for this plug-in
+ * @param s_rate [in] the sample rate
+ * @return the plug-in instance handle if successful else NULL
+ */
+LADSPA_Handle DSSIaudiooutput::instantiate(const LADSPA_Descriptor *descriptor,
+                                           unsigned long s_rate)
+{
+    if(descriptor->UniqueID == dssiDescriptor->LADSPA_Plugin->UniqueID)
+        return (LADSPA_Handle)(new DSSIaudiooutput(s_rate));
+    else
         return NULL;
+}
+
+/**
+ * Connects a port on an instantiated plug-in.
+ *
+ * This LADSPA member function connects a port on an instantiated plug-in to a
+ * memory location at which a block of data for the port will be read/written.
+ * The data location is expected to be an array of LADSPA_Data for audio ports
+ * or a single LADSPA_Data value for control ports. Memory issues will be
+ * managed by the host. The plug-in must read/write the data at these locations
+ * every time run() or run_adding() is called and the data present at the time
+ * of this connection call should not be considered meaningful.
+ *
+ * Zyn Implementation
+ * ------------------
+ * The buffer pointers are stored as member variables
+ *
+ * @param port [in] the port to be connected
+ * @param data [in] the data buffer to write to / read from
+ */
+void DSSIaudiooutput::connectPort(unsigned long port, LADSPA_Data *data)
+{
+    switch(port) {
+        case 0:
+            outl = data;
+            break;
+        case 1:
+            outr = data;
+            break;
     }
 }
 
-static LADSPA_Handle instantiateTS(const LADSPA_Descriptor * descriptor,
-                                   unsigned long s_rate)
+/**
+ * Initialises a plug-in instance and activates it for use.
+ *
+ * This LADSPA member function initialises a plug-in instance and activates it
+ * for use. This is separated from instantiate() to aid real-time support and
+ * so that hosts can reinitialise a plug-in instance by calling deactivate() and
+ * then activate(). In this case the plug-in instance must reset all state
+ * information dependent on the history of the plug-in instance except for any
+ * data locations provided by connect_port() and any gain set by
+ * set_run_adding_gain().
+ *
+ * Zyn Implementation
+ * ------------------
+ * Currently this does nothing; Care must be taken as to code placed here as
+ * too much code here seems to cause time-out problems in jack-dssi-host.
+*/
+void DSSIaudiooutput::activate()
+{}
+
+/**
+ * Runs an instance of a plug-in for a block.
+ *
+ * This LADSPA member function runs an instance of a plug-in for a block.
+ * Note that if an activate() function exists then it must be called before
+ * run() or run_adding(). If deactivate() is called for a plug-in instance then
+ * the plug-in instance may not be reused until activate() has been called again.
+ *
+ * Zyn Implementation
+ * ------------------
+ * This is a LADSPA function that does not process any MIDI events; it is hence
+ * implemented by simply calling runSynth() with an empty event list.
+ *
+ * @param sample_count [in] the block size (in samples) for which the plug-in instance may run
+ */
+void DSSIaudiooutput::run(unsigned long sample_count)
 {
+    runSynth(sample_count, NULL, (unsigned long)0);
+}
 
-    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);
-        }
-    */
-    return (LADSPA_Handle) plugin_data;
+/**
+ * Counterpart to activate().
+ *
+ * This LADSPA member function is the counterpart to activate() (see above).
+ * Deactivation is not similar to pausing as the plug-in instance will be
+ * reinitialised when activate() is called to reuse it.
+ *
+ * Zyn Implementation
+ * ------------------
+ * Currently this function does nothing.
+ */
+void DSSIaudiooutput::deactivate()
+{}
+
+/**
+ * Deletes a plug-in instance that is no longer required.
+ *
+ * LADSPA member function; once an instance of a plug-in has been finished with
+ * it can be deleted using this function. The instance handle ceases to be
+ * valid after this call.
+ *
+ * If activate() was called for a plug-in instance then a corresponding call to
+ * deactivate() must be made before cleanup() is called.
+ *
+ * Zyn Implementation
+ * ------------------
+ * Currently cleanup is deferred to the destructor that is invoked after cleanup()
+ */
+void DSSIaudiooutput::cleanup()
+{}
+
+/**
+ * Initial entry point for the LADSPA plug-in library.
+ *
+ * This LADSPA function is the initial entry point for the plug-in library.
+ * The LADSPA host looks for this entry point in each shared library object it
+ * finds and then calls the function to enumerate the plug-ins within the
+ * library.
+ *
+ * Zyn Implementation
+ * ------------------
+ * As the Zyn plug-in is a DSSI plug-in, the LADSPA descriptor is embedded inside
+ * the DSSI descriptor, which is created by DSSIaudiooutput::initDssiDescriptor()
+ * statically when the library is loaded. This function then merely returns a pointer
+ * to that embedded descriptor.
+ *
+ * @param index [in] the index number of the plug-in within the library.
+ * @return if index is in range, a pointer to the plug-in descriptor is returned, else NULL
+ */
+const LADSPA_Descriptor *DSSIaudiooutput::getLadspaDescriptor(
+    unsigned long index)
+{
+    if((index > 0) || (dssiDescriptor == NULL))
+        return NULL;
+    else
+        return dssiDescriptor->LADSPA_Plugin;
 }
 
-static void activateTS(LADSPA_Handle instance)
+//
+// DSSI member functions
+//
+
+/**
+ * Provides a description of a program available on this synth.
+ *
+ * This DSSI member function pointer provides a description of a program (named
+ * preset sound) available on this synth.
+ *
+ * Zyn Implementation
+ * ------------------
+ * The instruments in all Zyn's bank directories, as shown by the `instrument
+ * -> show instrument bank` command, are enumerated to the host by this
+ * function, allowing access to all those instruments.
+ * The first time an instrument is requested, the bank it is in and any
+ * unmapped ones preceding that are mapped; all the instruments names and
+ * filenames from those banks are stored in the programMap member variable for
+ * later use. This is done on demand in this way, rather than up front in one
+ * go because loading all the instrument names in one go can lead to timeouts
+ * and zombies.
+ *
+ * @param index [in] index into the plug-in's list of
+ * programs, not a program number as represented by the Program
+ * field of the DSSI_Program_Descriptor.  (This distinction is
+ * needed to support synths that use non-contiguous program or
+ * bank numbers.)
+ * @return a DSSI_Program_Descriptor pointer that is
+ * guaranteed to be valid only until the next call to get_program,
+ * deactivate, or configure, on the same plug-in instance, or NULL if index is out of range.
+ */
+const DSSI_Program_Descriptor *DSSIaudiooutput::getProgram(unsigned long index)
 {
-    TS *plugin_data = (TS *) instance;
+    static DSSI_Program_Descriptor retVal;
 
-//    for (i=0; i<MIDI_NOTES; i++) {
-//	plugin_data->data[i].active = 0;
-//    }
-}
+    /* Make sure we have the list of banks loaded */
+    initBanks();
 
+    /* Make sure that the bank containing the instrument has been mapped */
+    while(index >= programMap.size() && mapNextBank())
+        /* DO NOTHING MORE */;
+
+    if(index >= programMap.size())
+        /* No more instruments */
+        return NULL;
+    else {
+        /* OK, return the instrument */
+        retVal.Name    = programMap[index].name.c_str();
+        retVal.Program = programMap[index].program;
+        retVal.Bank    = programMap[index].bank;
+        return &retVal;
+    }
+}
 
-static void runTS(LADSPA_Handle instance, unsigned long sample_count,
-                  snd_seq_event_t *events, unsigned long event_count)
+/**
+ * Selects a new program for this synth.
+ *
+ * This DSSI member function selects a new program for this synth.  The program
+ * change will take effect immediately at the start of the next run_synth()
+ * call. An invalid bank / instrument combination is ignored.
+ *
+ * Zyn Implementation
+ * ------------------
+ * the banks and instruments are as shown in the `instrument -> show instrument
+ * bank` command in Zyn. The bank no is a 1-based index into the list of banks
+ * Zyn loads and shows in the drop down and the program number is the
+ * instrument within that bank.
+ *
+ * @param bank [in] the bank number to select
+ * @param program [in] the program number within the bank to select
+ */
+void DSSIaudiooutput::selectProgram(unsigned long bank, unsigned long program)
 {
-    TS *plugin_data = (TS *) instance;
-//    LADSPA_Data *const output = plugin_data->output;
-//    LADSPA_Data freq = *(plugin_data->freq);
-//    LADSPA_Data vol = *(plugin_data->vol);
-//    note_data *data = plugin_data->data;
-    unsigned long pos;
-    unsigned long event_pos;
-    unsigned long note;
-
-    /*    if (freq < 1.0) {
-    	freq = 440.0f;
-        }
-        if (vol < 0.000001) {
-    	vol = 1.0f;
-        }
+    initBanks();
+//    cerr << "selectProgram(" << (bank & 0x7F) << ':' << ((bank >> 7) & 0x7F) << "," << program  << ")" << '\n';
+    if((bank < master->bank.banks.size()) && (program < BANK_SIZE)) {
+        const std::string bankdir = master->bank.banks[bank].dir;
+        if(!bankdir.empty()) {
+            pthread_mutex_lock(&master->mutex);
 
-        if (event_count > 0) {
-    	printf("trivial_synth: have %ld events\n", event_count);
-        }
+            /* We have to turn off the CheckPADsynth functionality, else
+             * the program change takes way too long and we get timeouts
+             * and hence zombies (!) */
+            int save = config.cfg.CheckPADsynth;
+            config.cfg.CheckPADsynth = 0;
 
-        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;
-    		}
-    	    }
-    	}
+            /* Load the bank... */
+            master->bank.loadbank(bankdir);
+
+            /* restore the CheckPADsynth flag */
+            config.cfg.CheckPADsynth = save;
+
+            /* Now load the instrument... */
+            master->bank.loadfromslot((unsigned int)program, master->part[0]);
+
+            pthread_mutex_unlock(&master->mutex);
         }
-        */
+    }
 }
 
+/**
+ * Returns the MIDI controller number or NRPN for a input control port
+ *
+ * This DSSI member function returns the MIDI controller number or NRPN that
+ * should be mapped to the given input control port. If the given port should
+ * not have any MIDI controller mapped to it, the function will return DSSI_NONE.
+ * The behaviour of this function is undefined if the given port
+ * number does not correspond to an input control port.
+ *
+ * Zyn Implementation
+ * ------------------
+ * Currently Zyn does not define any controller ports, but may do in the future.
+ *
+ * @param port [in] the input controller port
+ * @return the CC and NRPN values shifted and ORed together.
+ */
+int DSSIaudiooutput::getMidiControllerForPort(unsigned long port)
+{
+    return DSSI_NONE;
+}
 
-static void runTSWrapper(LADSPA_Handle instance,
-                         unsigned long sample_count)
+/**
+ * Runs the synth for a block.
+ *
+ * This DSSI member function runs the synth for a block.  This is identical in
+ * function to the LADSPA run() function, except that it also supplies events
+ * to the synth.
+ *
+ * Zyn Implementation
+ * ------------------
+ * Zyn implements synthesis in Master::GetAudioOutSamples; runSynth calls this
+ * function in chunks delimited by the sample_count and the frame indexes in
+ * the events block, calling the appropriate NoteOn, NoteOff and SetController
+ * members of Master to process the events supplied between each chunk.
+ *
+ * @param sample_count [in] the block size (in samples) for which the synth
+ * instance may run.
+ * @param events [in] The Events pointer points to a block of ALSA
+ * sequencer events, used to communicate MIDI and related events to the synth.
+ * Each event must be timestamped relative to the start of the block,
+ * (mis)using the ALSA "tick time" field as a frame count. The host is
+ * responsible for ensuring that events with differing timestamps are already
+ * ordered by time. Must not include NOTE (only NOTE_ON / NOTE_OFF), LSB or MSB
+ * events.
+ * @param event_count [in] the number of entries in the `events` block
+ */
+void DSSIaudiooutput::runSynth(unsigned long sample_count,
+                               snd_seq_event_t *events,
+                               unsigned long event_count)
 {
-    runTS(instance, sample_count, NULL, 0);
+    unsigned long from_frame       = 0;
+    unsigned long event_index      = 0;
+    unsigned long next_event_frame = 0;
+    unsigned long to_frame = 0;
+    pthread_mutex_lock(&master->mutex);
+
+    do {
+        /* Find the time of the next event, if any */
+        if((events == NULL) || (event_index >= event_count))
+            next_event_frame = ULONG_MAX;
+        else
+            next_event_frame = events[event_index].time.tick;
+
+        /* find the end of the sub-sample to be processed this time round... */
+        /* if the next event falls within the desired sample interval... */
+        if((next_event_frame < sample_count) && (next_event_frame >= to_frame))
+            /* set the end to be at that event */
+            to_frame = next_event_frame;
+        else
+            /* ...else go for the whole remaining sample */
+            to_frame = sample_count;
+        if(from_frame < to_frame) {
+            // call master to fill from `from_frame` to `to_frame`:
+            master->GetAudioOutSamples(to_frame - from_frame,
+                                       (int)sampleRate,
+                                       &(outl[from_frame]),
+                                       &(outr[from_frame]));
+            // next sub-sample please...
+            from_frame = to_frame;
+        }
+
+        // Now process any event(s) at the current timing point
+        while(events != NULL && event_index < event_count
+              && events[event_index].time.tick == to_frame) {
+            if(events[event_index].type == SND_SEQ_EVENT_NOTEON)
+                master->noteOn(events[event_index].data.note.channel,
+                               events[event_index].data.note.note,
+                               events[event_index].data.note.velocity);
+            else
+            if(events[event_index].type == SND_SEQ_EVENT_NOTEOFF)
+                master->noteOff(events[event_index].data.note.channel,
+                                events[event_index].data.note.note);
+            else
+            if(events[event_index].type == SND_SEQ_EVENT_CONTROLLER)
+                master->setController(events[event_index].data.control.channel,
+                                      events[event_index].data.control.param,
+                                      events[event_index].data.control.value);
+            else {}
+            event_index++;
+        }
+
+        // Keep going until we have the desired total length of sample...
+    } while(to_frame < sample_count);
+
+    pthread_mutex_unlock(&master->mutex);
 }
 
-int getControllerTS(LADSPA_Handle instance, unsigned long port)
+/**
+ * Initial entry point for the DSSI plug-in library.
+ *
+ * This DSSI function is the initial entry point for the plug-in library.
+ * The DSSI host looks for this entry point in each shared library object it
+ * finds and then calls the function to enumerate the plug-ins within the
+ * library.
+ *
+ * Zyn Implementation
+ * ------------------
+ * The descriptor is created statically by DSSIaudiooutput::initDssiDescriptor()
+ * when the plug-in library is loaded. This function merely returns a pointer to
+ * that descriptor.
+ *
+ * @param index [in] the index number of the plug-in within the library.
+ * @return if index is in range, a pointer to the plug-in descriptor is returned, else NULL
+ */
+const DSSI_Descriptor *DSSIaudiooutput::getDssiDescriptor(unsigned long index)
 {
-    return -1;
+    if((index > 0) || (dssiDescriptor == NULL))
+        return NULL;
+    else
+        return dssiDescriptor;
 }
 
-void _init()
+//
+// Internal member functions
+//
+
+// Initialise the DSSI descriptor, statically:
+DSSI_Descriptor *DSSIaudiooutput::dssiDescriptor =
+    DSSIaudiooutput::initDssiDescriptor();
+
+/**
+ * Initializes the DSSI (and LADSPA) descriptor, returning it is an object.
+ */
+DSSI_Descriptor *DSSIaudiooutput::initDssiDescriptor()
 {
-    char **port_names;
-    LADSPA_PortDescriptor *port_descriptors;
-    LADSPA_PortRangeHint *port_range_hints;
-
-    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";
-        tsLDescriptor->Properties = 0;
-        tsLDescriptor->Name = "ZynAddSubFX";
-        tsLDescriptor->Maker = "Nasca Octavian Paul <zynaddsubfx at yahoo.com>";
-        tsLDescriptor->Copyright = "GNU General Public License v.2";
-        tsLDescriptor->PortCount = 2;
-
-        port_descriptors = (LADSPA_PortDescriptor *)
-                           calloc(tsLDescriptor->PortCount, sizeof
-                                  (LADSPA_PortDescriptor));
-        tsLDescriptor->PortDescriptors =
-            (const LADSPA_PortDescriptor *) port_descriptors;
-
-        port_range_hints = (LADSPA_PortRangeHint *)
-                           calloc(tsLDescriptor->PortCount, sizeof
-                                  (LADSPA_PortRangeHint));
-        tsLDescriptor->PortRangeHints =
-            (const LADSPA_PortRangeHint *) port_range_hints;
-
-        port_names = (char **) calloc(tsLDescriptor->PortCount, sizeof(char *));
-        tsLDescriptor->PortNames = (const char **) port_names;
-
-        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->connect_port = connectPortTS;
-        tsLDescriptor->deactivate = NULL;
-        tsLDescriptor->instantiate = instantiateTS;
-        tsLDescriptor->run = runTSWrapper;
-        tsLDescriptor->run_adding = NULL;
-        tsLDescriptor->set_run_adding_gain = NULL;
+    DSSI_Descriptor *newDssiDescriptor = new DSSI_Descriptor;
+
+    LADSPA_PortDescriptor *newPortDescriptors;
+    const char **newPortNames;
+    LADSPA_PortRangeHint *newPortRangeHints;
+
+    if(newDssiDescriptor) {
+        LADSPA_Descriptor *newLadspaDescriptor = new LADSPA_Descriptor;
+        if(newLadspaDescriptor) {
+            newLadspaDescriptor->UniqueID   = 100;
+            newLadspaDescriptor->Label      = "ZASF";
+            newLadspaDescriptor->Properties = 0;
+            newLadspaDescriptor->Name  = "ZynAddSubFX";
+            newLadspaDescriptor->Maker =
+                "Nasca Octavian Paul <zynaddsubfx at yahoo.com>";
+            newLadspaDescriptor->Copyright = "GNU General Public License v.2";
+            newLadspaDescriptor->PortCount = 2;
+
+            newPortNames    = new const char *[newLadspaDescriptor->PortCount];
+            newPortNames[0] = "Output L";
+            newPortNames[1] = "Output R";
+            newLadspaDescriptor->PortNames = newPortNames;
+
+            newPortDescriptors =
+                new LADSPA_PortDescriptor[newLadspaDescriptor->PortCount];
+            newPortDescriptors[0] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+            newPortDescriptors[1] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO;
+            newLadspaDescriptor->PortDescriptors = newPortDescriptors;
+
+            newPortRangeHints =
+                new LADSPA_PortRangeHint[newLadspaDescriptor->PortCount];
+            newPortRangeHints[0].HintDescriptor = 0;
+            newPortRangeHints[1].HintDescriptor = 0;
+            newLadspaDescriptor->PortRangeHints = newPortRangeHints;
+
+            newLadspaDescriptor->activate     = stub_activate;
+            newLadspaDescriptor->cleanup      = stub_cleanup;
+            newLadspaDescriptor->connect_port = stub_connectPort;
+            newLadspaDescriptor->deactivate   = stub_deactivate;
+            newLadspaDescriptor->instantiate  = instantiate;
+            newLadspaDescriptor->run = stub_run;
+            newLadspaDescriptor->run_adding = NULL;
+            newLadspaDescriptor->set_run_adding_gain = NULL;
+        }
+        newDssiDescriptor->LADSPA_Plugin    = newLadspaDescriptor;
+        newDssiDescriptor->DSSI_API_Version = 1;
+        newDssiDescriptor->configure   = NULL;
+        newDssiDescriptor->get_program = stub_getProgram;
+        newDssiDescriptor->get_midi_controller_for_port =
+            stub_getMidiControllerForPort;
+        newDssiDescriptor->select_program      = stub_selectProgram;
+        newDssiDescriptor->run_synth           = stub_runSynth;
+        newDssiDescriptor->run_synth_adding    = NULL;
+        newDssiDescriptor->run_multiple_synths = NULL;
+        newDssiDescriptor->run_multiple_synths_adding = NULL;
     }
 
-    tsDDescriptor = (DSSI_Descriptor *) malloc(sizeof(DSSI_Descriptor));
-    if (tsDDescriptor) {
-        tsDDescriptor->DSSI_API_Version = 1;
-        tsDDescriptor->LADSPA_Plugin = tsLDescriptor;
-        tsDDescriptor->configure = NULL;
-        tsDDescriptor->get_program = NULL;
-        tsDDescriptor->get_midi_controller_for_port = getControllerTS;
-        tsDDescriptor->select_program = NULL;
-        tsDDescriptor->run_synth = runTS;
-        tsDDescriptor->run_synth_adding = NULL;
-        tsDDescriptor->run_multiple_synths = NULL;
-        tsDDescriptor->run_multiple_synths_adding = NULL;
-    }
+    dssiDescriptor = newDssiDescriptor;
 
-};
+    return dssiDescriptor;
+}
 
-void _fini()
+/**
+ * Converts a LADSPA / DSSI handle into a DSSIaudiooutput instance.
+ *
+ * @param instance [in]
+ * @return the instance
+ */
+DSSIaudiooutput *DSSIaudiooutput::getInstance(LADSPA_Handle instance)
 {
-};
+    return (DSSIaudiooutput *)(instance);
+}
 
+SYNTH_T *synth;
 
+/**
+ * The private sole constructor for the DSSIaudiooutput class.
+ *
+ * Only ever called via instantiate().
+ * @param sampleRate [in] the sample rate to be used by the synth.
+ * @return
+ */
+DSSIaudiooutput::DSSIaudiooutput(unsigned long sampleRate)
+{
+    synth = new SYNTH_T;
+    synth->samplerate = sampleRate;
 
+    this->sampleRate  = sampleRate;
+    this->banksInited = false;
 
+    config.init();
 
+    sprng(time(NULL));
+    denormalkillbuf = new float [synth->buffersize];
+    for(int i = 0; i < synth->buffersize; i++)
+        denormalkillbuf[i] = (RND - 0.5f) * 1e-16;
 
+    this->master = new Master();
+}
 
-//the constructor and the destructor are defined in main.C
-/*
-void VSTSynth::process (float **inputs, float **outputs, long sampleframes){
-    float *outl=outputs[0];
-    float *outr=outputs[1];
-    pthread_mutex_lock(&vmaster->mutex);
-     vmaster->GetAudioOutSamples(sampleframes,(int) getSampleRate(),outl,outr);
-    pthread_mutex_unlock(&vmaster->mutex);
-};
-
-void VSTSynth::processReplacing (float **inputs, float **outputs, long 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);
-};
-
-bool VSTSynth::getVendorString(char *txt){
-	strcpy(txt,"Nasca O. Paul");
-	return(true);
-};
-
-bool VSTSynth::getProductString(char *txt){
-	strcpy(txt,"ZynAddSubFX");
-	return(true);
-};
-
-void VSTSynth::resume(){
-	wantEvents();
-};
+/**
+ * The destructor for the DSSIaudiooutput class
+ * @return
+ */
+DSSIaudiooutput::~DSSIaudiooutput()
+{}
+
+/**
+ * Ensures the list of bank (directories) has been initialised.
+ */
+void DSSIaudiooutput::initBanks(void)
+{
+    if(!banksInited) {
+        pthread_mutex_lock(&master->mutex);
+        master->bank.rescanforbanks();
+        banksInited = true;
+        pthread_mutex_unlock(&master->mutex);
+    }
+}
 
-*/
+/**
+ * constructor for the internally used ProgramDescriptor class
+ *
+ * @param _bank [in] bank number
+ * @param _program [in] program number
+ * @param _name [in] instrument / sample name
+ * @return
+ */
+DSSIaudiooutput::ProgramDescriptor::ProgramDescriptor(unsigned long _bank,
+                                                      unsigned long _program,
+                                                      char *_name)
+    :bank(_bank), program(_program), name(_name)
+{}
+
+/**
+ * The map of programs available; held as a single shared statically allocated object.
+ */
+vector<DSSIaudiooutput::ProgramDescriptor> DSSIaudiooutput::programMap =
+    vector<DSSIaudiooutput::ProgramDescriptor>();
+
+/**
+ * Index controlling the map of banks
+ */
+long DSSIaudiooutput::bankNoToMap = 1;
+
+/**
+ * Queries and maps the next available bank of instruments.
+ *
+ * If the program index requested to getProgram() lies beyond the banks mapped to date,
+ * this member function is called to map the next one.
+ * @return true if a new bank has been found and mapped, else false.
+ */
+bool DSSIaudiooutput::mapNextBank()
+{
+    pthread_mutex_lock(&master->mutex);
+    Bank &bank = master->bank;
+    bool  retval;
+    if((bankNoToMap >= (int)bank.banks.size())
+       || bank.banks[bankNoToMap].dir.empty())
+        retval = false;
+    else {
+        bank.loadbank(bank.banks[bankNoToMap].dir);
+        for(unsigned long instrument = 0; instrument < BANK_SIZE;
+            ++instrument) {
+            string insName = bank.getname(instrument);
+            if(!insName.empty() && (insName[0] != '\0') && (insName[0] != ' '))
+                programMap.push_back(ProgramDescriptor(bankNoToMap, instrument,
+                                                       const_cast<char *>(
+                                                           insName.c_str())));
+        }
+        bankNoToMap++;
+        retval = true;
+    }
+    pthread_mutex_unlock(&master->mutex);
+    return retval;
+}
diff --git a/src/Output/DSSIaudiooutput.h b/src/Output/DSSIaudiooutput.h
index 6ca808f..f7eaaf3 100644
--- a/src/Output/DSSIaudiooutput.h
+++ b/src/Output/DSSIaudiooutput.h
@@ -26,34 +26,98 @@
 
 #include "../globals.h"
 #include "../Misc/Master.h"
-#include "../UI/MasterUI.h"
 
 #include <dssi.h>
 #include <ladspa.h>
+#include <vector>
 
-/*
-class VSTSynth:public AudioEffectX{
+class DSSIaudiooutput
+{
     public:
-	VSTSynth (audioMasterCallback audioMaster);
-	~VSTSynth();
+        //
+        // Static stubs for LADSPA member functions
+        //
+        static void stub_connectPort(LADSPA_Handle instance,
+                                     unsigned long port,
+                                     LADSPA_Data *data);
+        static void stub_activate(LADSPA_Handle instance);
+        static void stub_run(LADSPA_Handle instance, unsigned long sample_count);
+        static void stub_deactivate(LADSPA_Handle Instance);
+        static void stub_cleanup(LADSPA_Handle instance);
+
+        //
+        // Static stubs for DSSI member functions
+        //
+        static const DSSI_Program_Descriptor *stub_getProgram(
+            LADSPA_Handle instance,
+            unsigned long Index);
+        static void stub_selectProgram(LADSPA_Handle instance,
+                                       unsigned long bank,
+                                       unsigned long program);
+        static int stub_getMidiControllerForPort(LADSPA_Handle instance,
+                                                 unsigned long port);
+        static void stub_runSynth(LADSPA_Handle instance,
+                                  unsigned long sample_count,
+                                  snd_seq_event_t *events,
+                                  unsigned long event_count);
+
+        /*
+         * LADSPA member functions
+         */
+        static LADSPA_Handle instantiate(const LADSPA_Descriptor *descriptor,
+                                         unsigned long s_rate);
+        void connectPort(unsigned long port, LADSPA_Data *data);
+        void activate();
+        void run(unsigned long sample_count);
+        void deactivate();
+        void cleanup();
+        static const LADSPA_Descriptor *getLadspaDescriptor(unsigned long index);
+
+        /*
+         * DSSI member functions
+         */
+        const DSSI_Program_Descriptor *getProgram(unsigned long Index);
+        void selectProgram(unsigned long bank, unsigned long program);
+        int getMidiControllerForPort(unsigned long port);
+        void runSynth(unsigned long sample_count,
+                      snd_seq_event_t *events,
+                      unsigned long event_count);
+        static const DSSI_Descriptor *getDssiDescriptor(unsigned long index);
+
+        struct ProgramDescriptor {
+            unsigned long bank;
+            unsigned long program;
+            std::string   name;
+            ProgramDescriptor(unsigned long _bank,
+                              unsigned long _program,
+                              char *_name);
+        };
 
-	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();
+    private:
 
-	virtual long getChunk(void** data,bool isPreset=false);
-	virtual void setChunk(void *data,long size,bool isPreset=false);
+        DSSIaudiooutput(unsigned long sampleRate);
+        ~DSSIaudiooutput();
+        static DSSI_Descriptor *initDssiDescriptor();
+        static DSSIaudiooutput *getInstance(LADSPA_Handle instance);
+        void initBanks();
+        bool mapNextBank();
 
-	MasterUI *ui;
-	int Pexitprogram;
+        LADSPA_Data *outl;
+        LADSPA_Data *outr;
+        long    sampleRate;
+        Master *master;
+        static DSSI_Descriptor *dssiDescriptor;
+        static std::string      bankDirNames[];
+        static
+        std::vector<ProgramDescriptor> programMap;
 
-        Master *vmaster;
-	pthread_t thr;
+        /**
+         * Flag controlling the list of bank directories
+         */
+        bool banksInited;
+
+        static
+        long bankNoToMap;
 };
-*/
-#endif
 
+#endif
diff --git a/src/Output/JACK_RTaudiooutput.cpp b/src/Output/JACK_RTaudiooutput.cpp
deleted file mode 100644
index ca568e0..0000000
--- a/src/Output/JACK_RTaudiooutput.cpp
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  JACKaudiooutput.C - Audio output for JACK
-  Copyright (C) 2002 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 <stdlib.h>
-#include <string.h>
-#include <pthread.h>
-#include <unistd.h>
-
-
-extern "C"
-{
-#include <jack/ringbuffer.h>
-};
-#include "JACKaudiooutput.h"
-
-Master *jackmaster;
-jack_client_t *jackclient;
-jack_port_t *outport_left,*outport_right;
-jack_ringbuffer_t *rb=NULL;
-
-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);
-void jackshutdown(void *arg);
-
-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;
-    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);
-
-    /*
-    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);
-};
-
-void *thread_blocked(void *arg)
-{
-    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);
-
-    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
-    pthread_mutex_lock(&zyn_thread_lock);
-
-    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);
-            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);
-    };
-    pthread_mutex_unlock(&zyn_thread_lock);
-
-    return(0);
-};
-
-
-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;
-        };
-    };
-    /*    if (jack_ringbuffer_read_space(rb)>=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;
-    	};
-        };
-    */
-    if (pthread_mutex_trylock(&zyn_thread_lock)==0) {
-        pthread_cond_signal(&more_data);
-        pthread_mutex_unlock(&zyn_thread_lock);
-    };
-
-    return(0);
-};
-
-void JACKfinish()
-{
-    jackfinish=1;
-    jack_ringbuffer_free(rb);
-    jack_client_close(jackclient);
-
-    usleep(100000);
-    delete(jackoutl);
-    delete(jackoutr);
-};
-
-int jacksrate(jack_nframes_t nframes,void *arg)
-{
-
-    return(0);
-};
-
-void jackshutdown(void *arg)
-{
-};
-
-
-
diff --git a/src/Output/JACKaudiooutput.cpp b/src/Output/JACKaudiooutput.cpp
deleted file mode 100644
index 82f9736..0000000
--- a/src/Output/JACKaudiooutput.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  JACKaudiooutput.C - Audio output for JACK
-  Copyright (C) 2002 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 <stdlib.h>
-#include <jack/midiport.h>
-#include "JACKaudiooutput.h"
-
-Master *jackmaster;
-jack_client_t *jackclient;
-char jackname[100];
-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);
-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);
-    };
-
-    /*
-    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);
-};
-
-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)) {
-        JACKhandlemidi(nframes);
-        jackmaster->GetAudioOutSamples(nframes,jack_get_sample_rate(jackclient),outl,outr);
-        pthread_mutex_unlock(&jackmaster->mutex);
-    } else {
-        memset(outl, 0, sizeof(jack_default_audio_sample_t) * nframes);
-        memset(outr, 0, sizeof(jack_default_audio_sample_t) * nframes);
-    }
-
-    return(0);
-};
-
-void JACKfinish()
-{
-    jack_client_close(jackclient);
-};
-
-int jacksrate(jack_nframes_t nframes,void *arg)
-{
-
-    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);
-    jack_midi_event_t jack_midi_event;
-    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) {
-        midi_data = jack_midi_event.buffer;
-        type = midi_data[0] & 0xF0;
-        chan = midi_data[0] & 0x0F;
-
-        switch (type) {
-
-        case 0x80: /* note-off */
-            jackmaster->NoteOff(chan, midi_data[1]);
-            break;
-
-        case 0x90: /* note-on */
-            jackmaster->NoteOn(chan, midi_data[1], midi_data[2]);
-            break;
-
-        case 0xB0: /* controller */
-            jackmaster->SetController(chan, midi_data[1], midi_data[2]);
-            break;
-
-        case 0xE0: /* pitch bend */
-            jackmaster->SetController(chan, C_pitchwheel,
-                                      ((midi_data[2] << 7) | midi_data[1]));
-            break;
-
-            /* XXX TODO: handle MSB/LSB controllers and RPNs and NRPNs */
-        }
-    }
-
-}
-
-
-const char* JACKgetname()
-{
-    if (jackclient != NULL)
-        return jackname;
-    return NULL;
-}
diff --git a/src/Output/JACKaudiooutput.h b/src/Output/JACKaudiooutput.h
deleted file mode 100644
index 7061f8c..0000000
--- a/src/Output/JACKaudiooutput.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  JACKaudiooutput.h - Audio output for JACK
-  Copyright (C) 2002 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 JACK_AUDIO_OUTPUT_H
-#define JACK_AUDIO_OUTPUT_H
-
-#include <jack/jack.h>
-
-#include "../globals.h"
-#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)."
-#endif
-
-
-
-
-bool JACKaudiooutputinit(Master *master_);
-void JACKfinish();
-void JACKhandlemidi(unsigned long frames);
-const char* JACKgetname();
-
-#endif
-
diff --git a/src/Output/Makefile b/src/Output/Makefile
deleted file mode 100644
index 13e926c..0000000
--- a/src/Output/Makefile
+++ /dev/null
@@ -1,42 +0,0 @@
-include ../Makefile.inc
-
-objects=Recorder.o WAVaudiooutput.o
-
-ifeq ($(AUDIOOUT),OSS_AND_JACK)
-objects+=OSSaudiooutput.o JACKaudiooutput.o
-endif
-
-ifeq ($(AUDIOOUT),JACK)
-objects+=JACKaudiooutput.o
-endif
-
-ifeq ($(AUDIOOUT),DSSI)
-objects+=DSSIaudiooutput.o
-endif
-
-ifeq ($(AUDIOOUT),JACK_RT)
-objects+=JACK_RTaudiooutput.o
-endif
-
-ifeq ($(AUDIOOUT),PA)
-objects+=PAaudiooutput.o
-endif
-
-ifeq ($(AUDIOOUT),OSS)
-objects+=OSSaudiooutput.o
-endif
-
-ifeq ($(AUDIOOUT),VST)
-objects+=VSTaudiooutput.o
-endif
-
-
-all: $(objects)
-
--include ../Make.deps
-
-.PHONY : clean
-clean: 
-	rm -f $(objects)
-	rm -f makeinclude.deps
-
diff --git a/src/Output/OSSaudiooutput.cpp b/src/Output/OSSaudiooutput.cpp
deleted file mode 100644
index d10d32c..0000000
--- a/src/Output/OSSaudiooutput.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  OSSaudiooutput.C - Audio output for Open Sound System
-  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 <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <sys/soundcard.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-#include <iostream>
-
-#include "OSSaudiooutput.h"
-#include "../Misc/Util.h"
-#include "../globals.h"
-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;
-
-    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;
-        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);
-
-};
-
-
-/*
- * 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)
-{
-    int i;
-    REALTYPE l,r;
-    if (snd_handle<0) 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
-};
-
-
-OSSaudiooutput::~OSSaudiooutput()
-{
-    close(snd_handle);
-    delete [] smps;
-};
-
diff --git a/src/Output/OSSaudiooutput.h b/src/Output/OSSaudiooutput.h
deleted file mode 100644
index 3f130e0..0000000
--- a/src/Output/OSSaudiooutput.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  OSSaudiooutput.h - Audio output for Open Sound System
-  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 OSS_AUDIO_OUTPUT_H
-#define OSS_AUDIO_OUTPUT_H
-
-#include "../globals.h"
-
-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;
-
-    short int *smps;//Samples to be sent to soundcard
-};
-
-#endif
-
diff --git a/src/Output/PAaudiooutput.cpp b/src/Output/PAaudiooutput.cpp
deleted file mode 100644
index 161153f..0000000
--- a/src/Output/PAaudiooutput.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  PAaudiooutput.C - Audio output for PortAudio
-  Copyright (C) 2002 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 "PAaudiooutput.h"
-
-Master *PAmaster;
-PaStream *stream;
-REALTYPE *outl,*outr;
-
-int PAprocess(void *inputBuffer,void *outputBuffer,
-              unsigned long framesPerBuffer,
-              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);
-    };
-
-    pthread_mutex_lock(&PAmaster->mutex);
-    PAmaster->GetAudioOutSamples(SOUND_BUFFER_SIZE,SAMPLE_RATE,outl,outr);
-    pthread_mutex_unlock(&PAmaster->mutex);
-
-    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];
-    };
-
-    return(0);
-};
-
-void PAaudiooutputinit(Master *master_)
-{
-    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_StartStream(stream);
-};
-
-void PAfinish()
-{
-    Pa_StopStream(stream);
-    delete (outl);
-    delete (outr);
-};
-
-
-
-
diff --git a/src/Output/PAaudiooutput.h b/src/Output/PAaudiooutput.h
deleted file mode 100644
index 942011d..0000000
--- a/src/Output/PAaudiooutput.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  PAaudiooutput.h - Audio output for PortAudio
-  Copyright (C) 2002 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 PA_AUDIO_OUTPUT_H
-#define PA_AUDIO_OUTPUT_H
-
-#include <portaudio.h>
-
-#include "../globals.h"
-#include "../Misc/Master.h"
-
-void PAaudiooutputinit(Master *master_);
-void PAfinish();
-
-#endif
-
diff --git a/src/Output/Recorder.cpp b/src/Output/Recorder.cpp
deleted file mode 100644
index 388ab7f..0000000
--- a/src/Output/Recorder.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  Recorder.C - Records sound to a file
-  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 <sys/stat.h>
-#include "Recorder.h"
-
-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;
-    }
-};
-
-Recorder::~Recorder()
-{
-    if (recording()==1) stop();
-    delete [] recordbuf_16bit;
-};
-
-int Recorder::preparefile(std::string filename_,int overwrite)
-{
-    if (!overwrite) {
-        struct stat fileinfo;
-        int statr;
-        statr = stat(filename_.c_str(),&fileinfo);
-        if (statr == 0) {//file exists
-            return 1;
-        }
-    }
-
-    if (!wav.newfile(filename_, SAMPLE_RATE,2)) return 2;
-
-    status=1;//ready
-
-    return(0);
-};
-
-void Recorder::start()
-{
-    notetrigger=0;
-    status=2;//recording
-};
-
-void Recorder::stop()
-{
-    wav.close();
-    status=0;
-};
-
-void Recorder::pause()
-{
-    status=0;
-};
-
-int Recorder::recording()
-{
-    if ((status==2)&&(notetrigger!=0)) return(1);
-    else return(0);
-};
-
-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);
-};
-
-void Recorder::triggernow()
-{
-    if (status==2) notetrigger=1;
-};
diff --git a/src/Output/Recorder.h b/src/Output/Recorder.h
deleted file mode 100644
index 059f710..0000000
--- a/src/Output/Recorder.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  Recorder.h - Records sound to a file
-  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 RECORDER_H
-#define RECORDER_H
-#include <string>
-#include "../globals.h"
-#include "WAVaudiooutput.h"
-
-/**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;
-};
-
-#endif
diff --git a/src/Output/VSTaudiooutput.cpp b/src/Output/VSTaudiooutput.cpp
deleted file mode 100644
index 6441ab0..0000000
--- a/src/Output/VSTaudiooutput.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  VSTaudiooutput.C - Audio output for VST
-  Copyright (C) 2002 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 <string.h>
-#include "VSTaudiooutput.h"
-
-//the constructor and the destructor are defined in main.C
-
-void VSTSynth::process (float **inputs, float **outputs, long sampleframes)
-{
-    float *outl=outputs[0];
-    float *outr=outputs[1];
-    pthread_mutex_lock(&vmaster->mutex);
-    vmaster->GetAudioOutSamples(sampleframes,(int) getSampleRate(),outl,outr);
-    pthread_mutex_unlock(&vmaster->mutex);
-};
-
-void VSTSynth::processReplacing (float **inputs, float **outputs, long 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);
-};
-
-bool VSTSynth::getVendorString(char *txt)
-{
-    strcpy(txt,"Nasca O. Paul");
-    return(true);
-};
-
-bool VSTSynth::getProductString(char *txt)
-{
-    strcpy(txt,"ZynAddSubFX");
-    return(true);
-};
-
-void VSTSynth::resume()
-{
-    wantEvents();
-};
-
-
diff --git a/src/Output/VSTaudiooutput.h b/src/Output/VSTaudiooutput.h
deleted file mode 100644
index 116f330..0000000
--- a/src/Output/VSTaudiooutput.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  VSTaudiooutput.h - Audio output for VST
-  Copyright (C) 2002 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 VST_AUDIO_OUTPUT_H
-#define VST_AUDIO_OUTPUT_H
-
-#include <pthread.h>
-
-#include "../globals.h"
-#include "../Misc/Master.h"
-#include "../UI/MasterUI.h"
-
-#include "../../../vstsdk2/source/common/audioeffectx.h"
-
-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;
-};
-
-#endif
-
diff --git a/src/Output/WAVaudiooutput.cpp b/src/Output/WAVaudiooutput.cpp
deleted file mode 100644
index fc03243..0000000
--- a/src/Output/WAVaudiooutput.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
-  Copyright (C) 2006 Nasca Octavian Paul
-  Author: Nasca Octavian Paul
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of version 2 of the GNU General Public License
-  as published by the Free Software Foundation.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License (version 2) for more details.
-
-  You should have received a copy of the GNU General Public License (version 2)
-  along with this program; if not, write to the Free Software Foundation,
-  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "WAVaudiooutput.h"
-using namespace std;
-
-WAVaudiooutput::WAVaudiooutput()
-{
-    file=NULL;
-    sampleswritten=0;
-    samplerate=44100;
-};
-
-WAVaudiooutput::~WAVaudiooutput()
-{
-    close();
-};
-
-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;
-    char tmp[44];
-    fwrite(tmp,1,44,file);
-    return(true);
-};
-
-void WAVaudiooutput::close()
-{
-    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);
-
-        fclose(file);
-        file=NULL;
-    }
-};
-
-void WAVaudiooutput::write_stereo_samples(int nsmps,short int *smps)
-{
-    if (!file) return;
-    fwrite(smps,nsmps,4,file);
-    sampleswritten+=nsmps;
-};
-
-void WAVaudiooutput::write_mono_samples(int nsmps,short int *smps)
-{
-    if (!file) return;
-    fwrite(smps,nsmps,2,file);
-    sampleswritten+=nsmps;
-};
-
-
diff --git a/src/Output/WAVaudiooutput.h b/src/Output/WAVaudiooutput.h
deleted file mode 100644
index 54abae8..0000000
--- a/src/Output/WAVaudiooutput.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
-
-  Copyright (C) 2008 Nasca Octavian Paul
-  Author: Nasca Octavian Paul
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of version 2 of the GNU General Public License
-  as published by the Free Software Foundation.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License (version 2) for more details.
-
-  You should have received a copy of the GNU General Public License (version 2)
-  along with this program; if not, write to the Free Software Foundation,
-  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-*/
-
-#ifndef WAVOUTPUT_H
-#define WAVOUTPUT_H
-#include <string>
-
-class WAVaudiooutput
-{
-public:
-    WAVaudiooutput();
-    ~WAVaudiooutput();
-
-    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);
-
-private:
-    int sampleswritten;
-    int samplerate;
-    int channels;
-    FILE *file;
-};
-#endif
diff --git a/src/Params/ADnoteParameters.cpp b/src/Params/ADnoteParameters.cpp
index 5fb6ce7..adb937f 100644
--- a/src/Params/ADnoteParameters.cpp
+++ b/src/Params/ADnoteParameters.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  ADnoteParameters.C - Parameters for ADnote (ADsynth)
+  ADnoteParameters.cpp - Parameters for ADnote (ADsynth)
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -25,131 +25,163 @@
 #include <math.h>
 
 #include "ADnoteParameters.h"
-
-ADnoteParameters::ADnoteParameters(FFTwrapper *fft_):Presets()
+#include "EnvelopeParams.h"
+#include "LFOParams.h"
+#include "../Misc/XMLwrapper.h"
+#include "../DSP/FFTwrapper.h"
+#include "../Synth/OscilGen.h"
+#include "../Synth/Resonance.h"
+#include "FilterParams.h"
+
+int ADnote_unison_sizes[] =
+{1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 25, 30, 40, 50, 0};
+
+ADnoteParameters::ADnoteParameters(FFTwrapper *fft_)
+    :PresetsArray()
 {
     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.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);
+    for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice)
+        EnableVoice(nvoice);
 
-    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();
+    defaults();
+}
 
-    for (int nvoice=0;nvoice<NUM_VOICES;nvoice++) EnableVoice(nvoice);
+ADnoteGlobalParam::ADnoteGlobalParam()
+{
+    FreqEnvelope = new EnvelopeParams(0, 0);
+    FreqEnvelope->ASRinit(64, 50, 64, 60);
+    FreqLfo = new LFOParams(70, 0, 64, 0, 0, 0, 0, 0);
 
-    defaults();
-};
+    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);
+    Reson     = new Resonance();
+}
 
 void ADnoteParameters::defaults()
 {
     //Default Parameters
+    GlobalPar.defaults();
+
+    for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice)
+        defaults(nvoice);
+
+    VoicePar[0].Enabled = 1;
+}
+
+void ADnoteGlobalParam::defaults()
+{
     /* Frequency Global Parameters */
-    GlobalPar.PStereo=1;//stereo
-    GlobalPar.PDetune=8192;//zero
-    GlobalPar.PCoarseDetune=0;
-    GlobalPar.PDetuneType=1;
-    GlobalPar.FreqEnvelope->defaults();
-    GlobalPar.FreqLfo->defaults();
-    GlobalPar.PBandwidth=64;
+    PStereo = 1; //stereo
+    PDetune = 8192; //zero
+    PCoarseDetune = 0;
+    PDetuneType   = 1;
+    FreqEnvelope->defaults();
+    FreqLfo->defaults();
+    PBandwidth = 64;
 
     /* Amplitude Global Parameters */
-    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;
+    PVolume  = 90;
+    PPanning = 64; //center
+    PAmpVelocityScaleFunction = 64;
+    AmpEnvelope->defaults();
+    AmpLfo->defaults();
+    PPunchStrength = 0;
+    PPunchTime     = 60;
+    PPunchStretch  = 64;
+    PPunchVelocitySensing = 72;
+    Hrandgrouping = 0;
 
     /* Filter Global Parameters*/
-    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++) {
-        defaults(nvoice);
-    };
-    VoicePar[0].Enabled=1;
-};
+    PFilterVelocityScale = 64;
+    PFilterVelocityScaleFunction = 64;
+    GlobalFilter->defaults();
+    FilterEnvelope->defaults();
+    FilterLfo->defaults();
+    Reson->defaults();
+}
 
 /*
  * Defaults a voice
  */
 void ADnoteParameters::defaults(int n)
 {
-    int nvoice=n;
-    VoicePar[nvoice].Enabled=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;
+    VoicePar[n].defaults();
+}
+
+void ADnoteVoiceParam::defaults()
+{
+    Enabled = 0;
+
+    Unison_size = 1;
+    Unison_frequency_spread = 60;
+    Unison_stereo_spread    = 64;
+    Unison_vibratto = 64;
+    Unison_vibratto_speed = 64;
+    Unison_invert_phase   = 0;
+
+    Type = 0;
+    Pfixedfreq    = 0;
+    PfixedfreqET  = 0;
+    Presonance    = 1;
+    Pfilterbypass = 0;
+    Pextoscil     = -1;
+    PextFMoscil   = -1;
+    Poscilphase   = 64;
+    PFMoscilphase = 64;
+    PDelay                    = 0;
+    PVolume                   = 100;
+    PVolumeminus              = 0;
+    PPanning                  = 64; //center
+    PDetune                   = 8192; //8192=0
+    PCoarseDetune             = 0;
+    PDetuneType               = 0;
+    PFreqLfoEnabled           = 0;
+    PFreqEnvelopeEnabled      = 0;
+    PAmpEnvelopeEnabled       = 0;
+    PAmpLfoEnabled            = 0;
+    PAmpVelocityScaleFunction = 127;
+    PFilterEnabled            = 0;
+    PFilterEnvelopeEnabled    = 0;
+    PFilterLfoEnabled         = 0;
+    PFMEnabled                = 0;
 
     //I use the internal oscillator (-1)
-    VoicePar[nvoice].PFMVoice=-1;
+    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;
+    PFMVolume       = 90;
+    PFMVolumeDamp   = 64;
+    PFMDetune       = 8192;
+    PFMCoarseDetune = 0;
+    PFMDetuneType   = 0;
+    PFMFreqEnvelopeEnabled   = 0;
+    PFMAmpEnvelopeEnabled    = 0;
+    PFMVelocityScaleFunction = 64;
 
-    VoicePar[nvoice].OscilSmp->defaults();
-    VoicePar[nvoice].FMSmp->defaults();
+    OscilSmp->defaults();
+    FMSmp->defaults();
 
-    VoicePar[nvoice].AmpEnvelope->defaults();
-    VoicePar[nvoice].AmpLfo->defaults();
+    AmpEnvelope->defaults();
+    AmpLfo->defaults();
 
-    VoicePar[nvoice].FreqEnvelope->defaults();
-    VoicePar[nvoice].FreqLfo->defaults();
+    FreqEnvelope->defaults();
+    FreqLfo->defaults();
 
-    VoicePar[nvoice].VoiceFilter->defaults();
-    VoicePar[nvoice].FilterEnvelope->defaults();
-    VoicePar[nvoice].FilterLfo->defaults();
+    VoiceFilter->defaults();
+    FilterEnvelope->defaults();
+    FilterLfo->defaults();
 
-    VoicePar[nvoice].FMFreqEnvelope->defaults();
-    VoicePar[nvoice].FMAmpEnvelope->defaults();
-};
+    FMFreqEnvelope->defaults();
+    FMAmpEnvelope->defaults();
+}
 
 
 
@@ -158,491 +190,603 @@ 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].enable(fft, GlobalPar.Reson);
+}
+
+void ADnoteVoiceParam::enable(FFTwrapper *fft, Resonance *Reson)
+{
+    OscilSmp = new OscilGen(fft, Reson);
+    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);
+    AmpEnvelope = new EnvelopeParams(64, 1);
+    AmpEnvelope->ADSRinit_dB(0, 100, 127, 100);
+    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);
+    FreqEnvelope = new EnvelopeParams(0, 0);
+    FreqEnvelope->ASRinit(30, 40, 64, 60);
+    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);
+    VoiceFilter    = new FilterParams(2, 50, 60);
+    FilterEnvelope = new EnvelopeParams(0, 0);
+    FilterEnvelope->ADSRinit_filter(90, 70, 40, 70, 10, 40);
+    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);
-};
+    FMFreqEnvelope = new EnvelopeParams(0, 0);
+    FMFreqEnvelope->ASRinit(20, 90, 40, 80);
+    FMAmpEnvelope = new EnvelopeParams(64, 1);
+    FMAmpEnvelope->ADSRinit(80, 90, 127, 100);
+}
 
 /*
  * Get the Multiplier of the fine detunes of the voices
  */
-REALTYPE ADnoteParameters::getBandwidthDetuneMultiplier()
+float ADnoteParameters::getBandwidthDetuneMultiplier()
 {
-    REALTYPE bw=(GlobalPar.PBandwidth-64.0)/64.0;
-    bw=pow(2.0,bw*pow(fabs(bw),0.2)*5.0);
+    float bw = (GlobalPar.PBandwidth - 64.0f) / 64.0f;
+    bw = powf(2.0f, bw * powf(fabs(bw), 0.2f) * 5.0f);
 
-    return(bw);
-};
+    return bw;
+}
 
+/*
+ * Get the unison spread in cents for a voice
+ */
+
+float ADnoteParameters::getUnisonFrequencySpreadCents(int nvoice) {
+    float unison_spread = VoicePar[nvoice].Unison_frequency_spread / 127.0f;
+    unison_spread = powf(unison_spread * 2.0f, 2.0f) * 50.0f; //cents
+    return unison_spread;
+}
 
 /*
  * Kill the voice
  */
 void ADnoteParameters::KillVoice(int nvoice)
 {
-    delete (VoicePar[nvoice].OscilSmp);
-    delete (VoicePar[nvoice].FMSmp);
+    VoicePar[nvoice].kill();
+}
+
+void ADnoteVoiceParam::kill()
+{
+    delete OscilSmp;
+    delete FMSmp;
 
-    delete (VoicePar[nvoice].AmpEnvelope);
-    delete (VoicePar[nvoice].AmpLfo);
+    delete AmpEnvelope;
+    delete AmpLfo;
 
-    delete (VoicePar[nvoice].FreqEnvelope);
-    delete (VoicePar[nvoice].FreqLfo);
+    delete FreqEnvelope;
+    delete FreqLfo;
 
-    delete (VoicePar[nvoice].VoiceFilter);
-    delete (VoicePar[nvoice].FilterEnvelope);
-    delete (VoicePar[nvoice].FilterLfo);
+    delete VoiceFilter;
+    delete FilterEnvelope;
+    delete FilterLfo;
 
-    delete (VoicePar[nvoice].FMFreqEnvelope);
-    delete (VoicePar[nvoice].FMAmpEnvelope);
-};
+    delete FMFreqEnvelope;
+    delete FMAmpEnvelope;
+}
+
+
+ADnoteGlobalParam::~ADnoteGlobalParam()
+{
+    delete FreqEnvelope;
+    delete FreqLfo;
+    delete AmpEnvelope;
+    delete AmpLfo;
+    delete GlobalFilter;
+    delete FilterEnvelope;
+    delete FilterLfo;
+    delete Reson;
+}
 
 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++) {
+    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::add2XMLsection(XMLwrapper *xml,int n)
+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;
+
+    VoicePar[nvoice].add2XML(xml, fmoscilused);
+}
+
+void ADnoteVoiceParam::add2XML(XMLwrapper *xml, bool fmoscilused)
+{
+    xml->addpar("type", Type);
 
-    xml->addparbool("enabled",VoicePar[nvoice].Enabled);
-    if (((VoicePar[nvoice].Enabled==0)&&(oscilused==0)&&(fmoscilused==0))&&(xml->minimal)) return;
+    xml->addpar("unison_size", Unison_size);
+    xml->addpar("unison_frequency_spread",
+                Unison_frequency_spread);
+    xml->addpar("unison_stereo_spread", Unison_stereo_spread);
+    xml->addpar("unison_vibratto", Unison_vibratto);
+    xml->addpar("unison_vibratto_speed", Unison_vibratto_speed);
+    xml->addpar("unison_invert_phase", Unison_invert_phase);
 
-    xml->addpar("type",VoicePar[nvoice].Type);
-    xml->addpar("delay",VoicePar[nvoice].PDelay);
-    xml->addparbool("resonance",VoicePar[nvoice].Presonance);
+    xml->addpar("delay", PDelay);
+    xml->addparbool("resonance", Presonance);
 
-    xml->addpar("ext_oscil",VoicePar[nvoice].Pextoscil);
-    xml->addpar("ext_fm_oscil",VoicePar[nvoice].PextFMoscil);
+    xml->addpar("ext_oscil", Pextoscil);
+    xml->addpar("ext_fm_oscil", PextFMoscil);
 
-    xml->addpar("oscil_phase",VoicePar[nvoice].Poscilphase);
-    xml->addpar("oscil_fm_phase",VoicePar[nvoice].PFMoscilphase);
+    xml->addpar("oscil_phase", Poscilphase);
+    xml->addpar("oscil_fm_phase", PFMoscilphase);
 
-    xml->addparbool("filter_enabled",VoicePar[nvoice].PFilterEnabled);
-    xml->addparbool("filter_bypass",VoicePar[nvoice].Pfilterbypass);
+    xml->addparbool("filter_enabled", PFilterEnabled);
+    xml->addparbool("filter_bypass", Pfilterbypass);
 
-    xml->addpar("fm_enabled",VoicePar[nvoice].PFMEnabled);
+    xml->addpar("fm_enabled", PFMEnabled);
 
     xml->beginbranch("OSCIL");
-    VoicePar[nvoice].OscilSmp->add2XML(xml);
+    OscilSmp->add2XML(xml);
     xml->endbranch();
 
 
     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", PPanning);
+    xml->addpar("volume", PVolume);
+    xml->addparbool("volume_minus", PVolumeminus);
+    xml->addpar("velocity_sensing", PAmpVelocityScaleFunction);
+
+    xml->addparbool("amp_envelope_enabled",
+                    PAmpEnvelopeEnabled);
+    if((PAmpEnvelopeEnabled != 0) || (!xml->minimal)) {
         xml->beginbranch("AMPLITUDE_ENVELOPE");
-        VoicePar[nvoice].AmpEnvelope->add2XML(xml);
+        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", PAmpLfoEnabled);
+    if((PAmpLfoEnabled != 0) || (!xml->minimal)) {
         xml->beginbranch("AMPLITUDE_LFO");
-        VoicePar[nvoice].AmpLfo->add2XML(xml);
+        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", Pfixedfreq);
+    xml->addpar("fixed_freq_et", PfixedfreqET);
+    xml->addpar("detune", PDetune);
+    xml->addpar("coarse_detune", PCoarseDetune);
+    xml->addpar("detune_type", PDetuneType);
+
+    xml->addparbool("freq_envelope_enabled",
+                    PFreqEnvelopeEnabled);
+    if((PFreqEnvelopeEnabled != 0) || (!xml->minimal)) {
         xml->beginbranch("FREQUENCY_ENVELOPE");
-        VoicePar[nvoice].FreqEnvelope->add2XML(xml);
+        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", PFreqLfoEnabled);
+    if((PFreqLfoEnabled != 0) || (!xml->minimal)) {
         xml->beginbranch("FREQUENCY_LFO");
-        VoicePar[nvoice].FreqLfo->add2XML(xml);
+        FreqLfo->add2XML(xml);
         xml->endbranch();
-    };
+    }
     xml->endbranch();
 
 
-    if ((VoicePar[nvoice].PFilterEnabled!=0)||(!xml->minimal)) {
+    if((PFilterEnabled != 0) || (!xml->minimal)) {
         xml->beginbranch("FILTER_PARAMETERS");
         xml->beginbranch("FILTER");
-        VoicePar[nvoice].VoiceFilter->add2XML(xml);
+        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",
+                        PFilterEnvelopeEnabled);
+        if((PFilterEnvelopeEnabled != 0) || (!xml->minimal)) {
             xml->beginbranch("FILTER_ENVELOPE");
-            VoicePar[nvoice].FilterEnvelope->add2XML(xml);
+            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",
+                        PFilterLfoEnabled);
+        if((PFilterLfoEnabled != 0) || (!xml->minimal)) {
             xml->beginbranch("FILTER_LFO");
-            VoicePar[nvoice].FilterLfo->add2XML(xml);
+            FilterLfo->add2XML(xml);
             xml->endbranch();
-        };
+        }
         xml->endbranch();
-    };
+    }
 
-    if ((VoicePar[nvoice].PFMEnabled!=0)||(fmoscilused!=0)||(!xml->minimal)) {
+    if((PFMEnabled != 0) || (fmoscilused != 0)
+       || (!xml->minimal)) {
         xml->beginbranch("FM_PARAMETERS");
-        xml->addpar("input_voice",VoicePar[nvoice].PFMVoice);
+        xml->addpar("input_voice", PFMVoice);
 
-        xml->addpar("volume",VoicePar[nvoice].PFMVolume);
-        xml->addpar("volume_damp",VoicePar[nvoice].PFMVolumeDamp);
-        xml->addpar("velocity_sensing",VoicePar[nvoice].PFMVelocityScaleFunction);
+        xml->addpar("volume", PFMVolume);
+        xml->addpar("volume_damp", PFMVolumeDamp);
+        xml->addpar("velocity_sensing",
+                    PFMVelocityScaleFunction);
 
-        xml->addparbool("amp_envelope_enabled",VoicePar[nvoice].PFMAmpEnvelopeEnabled);
-        if ((VoicePar[nvoice].PFMAmpEnvelopeEnabled!=0)||(!xml->minimal)) {
+        xml->addparbool("amp_envelope_enabled",
+                        PFMAmpEnvelopeEnabled);
+        if((PFMAmpEnvelopeEnabled != 0) || (!xml->minimal)) {
             xml->beginbranch("AMPLITUDE_ENVELOPE");
-            VoicePar[nvoice].FMAmpEnvelope->add2XML(xml);
+            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", PFMDetune);
+        xml->addpar("coarse_detune", PFMCoarseDetune);
+        xml->addpar("detune_type", PFMDetuneType);
 
-        xml->addparbool("freq_envelope_enabled",VoicePar[nvoice].PFMFreqEnvelopeEnabled);
-        if ((VoicePar[nvoice].PFMFreqEnvelopeEnabled!=0)||(!xml->minimal)) {
+        xml->addparbool("freq_envelope_enabled",
+                        PFMFreqEnvelopeEnabled);
+        if((PFMFreqEnvelopeEnabled != 0) || (!xml->minimal)) {
             xml->beginbranch("FREQUENCY_ENVELOPE");
-            VoicePar[nvoice].FMFreqEnvelope->add2XML(xml);
+            FMFreqEnvelope->add2XML(xml);
             xml->endbranch();
-        };
+        }
 
         xml->beginbranch("OSCIL");
-        VoicePar[nvoice].FMSmp->add2XML(xml);
+        FMSmp->add2XML(xml);
         xml->endbranch();
 
         xml->endbranch();
         xml->endbranch();
-    };
-};
-
+    }
+}
 
-void ADnoteParameters::add2XML(XMLwrapper *xml)
+void ADnoteGlobalParam::add2XML(XMLwrapper *xml)
 {
-    xml->addparbool("stereo",GlobalPar.PStereo);
+    xml->addparbool("stereo", 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", 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("harmonic_randomness_grouping", Hrandgrouping);
 
     xml->beginbranch("AMPLITUDE_ENVELOPE");
-    GlobalPar.AmpEnvelope->add2XML(xml);
+    AmpEnvelope->add2XML(xml);
     xml->endbranch();
 
     xml->beginbranch("AMPLITUDE_LFO");
-    GlobalPar.AmpLfo->add2XML(xml);
+    AmpLfo->add2XML(xml);
     xml->endbranch();
     xml->endbranch();
 
     xml->beginbranch("FREQUENCY_PARAMETERS");
-    xml->addpar("detune",GlobalPar.PDetune);
+    xml->addpar("detune", PDetune);
 
-    xml->addpar("coarse_detune",GlobalPar.PCoarseDetune);
-    xml->addpar("detune_type",GlobalPar.PDetuneType);
+    xml->addpar("coarse_detune", PCoarseDetune);
+    xml->addpar("detune_type", PDetuneType);
 
-    xml->addpar("bandwidth",GlobalPar.PBandwidth);
+    xml->addpar("bandwidth", PBandwidth);
 
     xml->beginbranch("FREQUENCY_ENVELOPE");
-    GlobalPar.FreqEnvelope->add2XML(xml);
+    FreqEnvelope->add2XML(xml);
     xml->endbranch();
 
     xml->beginbranch("FREQUENCY_LFO");
-    GlobalPar.FreqLfo->add2XML(xml);
+    FreqLfo->add2XML(xml);
     xml->endbranch();
     xml->endbranch();
 
 
     xml->beginbranch("FILTER_PARAMETERS");
-    xml->addpar("velocity_sensing_amplitude",GlobalPar.PFilterVelocityScale);
-    xml->addpar("velocity_sensing",GlobalPar.PFilterVelocityScaleFunction);
+    xml->addpar("velocity_sensing_amplitude", PFilterVelocityScale);
+    xml->addpar("velocity_sensing", PFilterVelocityScaleFunction);
 
     xml->beginbranch("FILTER");
-    GlobalPar.GlobalFilter->add2XML(xml);
+    GlobalFilter->add2XML(xml);
     xml->endbranch();
 
     xml->beginbranch("FILTER_ENVELOPE");
-    GlobalPar.FilterEnvelope->add2XML(xml);
+    FilterEnvelope->add2XML(xml);
     xml->endbranch();
 
     xml->beginbranch("FILTER_LFO");
-    GlobalPar.FilterLfo->add2XML(xml);
+    FilterLfo->add2XML(xml);
     xml->endbranch();
     xml->endbranch();
 
     xml->beginbranch("RESONANCE");
-    GlobalPar.Reson->add2XML(xml);
+    Reson->add2XML(xml);
     xml->endbranch();
+}
 
-    for (int nvoice=0;nvoice<NUM_VOICES;nvoice++) {
-        xml->beginbranch("VOICE",nvoice);
-        add2XMLsection(xml,nvoice);
+void ADnoteParameters::add2XML(XMLwrapper *xml)
+{
+    GlobalPar.add2XML(xml);
+    for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice) {
+        xml->beginbranch("VOICE", nvoice);
+        add2XMLsection(xml, nvoice);
         xml->endbranch();
-    };
-};
+    }
+}
 
 
-void ADnoteParameters::getfromXML(XMLwrapper *xml)
+void ADnoteGlobalParam::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.AmpEnvelope->getfromXML(xml);
+    PStereo = xml->getparbool("stereo", PStereo);
+
+    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);
+        Hrandgrouping = xml->getpar127("harmonic_randomness_grouping",
+                                       Hrandgrouping);
+
+        if(xml->enterbranch("AMPLITUDE_ENVELOPE")) {
+            AmpEnvelope->getfromXML(xml);
             xml->exitbranch();
-        };
+        }
 
-        if (xml->enterbranch("AMPLITUDE_LFO")) {
-            GlobalPar.AmpLfo->getfromXML(xml);
+        if(xml->enterbranch("AMPLITUDE_LFO")) {
+            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")) {
+        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);
 
         xml->enterbranch("FREQUENCY_ENVELOPE");
-        GlobalPar.FreqEnvelope->getfromXML(xml);
+        FreqEnvelope->getfromXML(xml);
         xml->exitbranch();
 
         xml->enterbranch("FREQUENCY_LFO");
-        GlobalPar.FreqLfo->getfromXML(xml);
+        FreqLfo->getfromXML(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")) {
+        PFilterVelocityScale = xml->getpar127("velocity_sensing_amplitude",
+                                              PFilterVelocityScale);
+        PFilterVelocityScaleFunction = xml->getpar127(
+            "velocity_sensing",
+            PFilterVelocityScaleFunction);
 
         xml->enterbranch("FILTER");
-        GlobalPar.GlobalFilter->getfromXML(xml);
+        GlobalFilter->getfromXML(xml);
         xml->exitbranch();
 
         xml->enterbranch("FILTER_ENVELOPE");
-        GlobalPar.FilterEnvelope->getfromXML(xml);
+        FilterEnvelope->getfromXML(xml);
         xml->exitbranch();
 
         xml->enterbranch("FILTER_LFO");
-        GlobalPar.FilterLfo->getfromXML(xml);
-        xml->exitbranch();
+        FilterLfo->getfromXML(xml);
         xml->exitbranch();
-    };
-
-    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);
+    if(xml->enterbranch("RESONANCE")) {
+        Reson->getfromXML(xml);
         xml->exitbranch();
-    };
-
+    }
+}
 
-};
-
-void ADnoteParameters::getfromXMLsection(XMLwrapper *xml,int n)
+void ADnoteParameters::getfromXML(XMLwrapper *xml)
 {
-    int nvoice=n;
-    if (nvoice>=NUM_VOICES) return;
-
-    VoicePar[nvoice].Enabled=xml->getparbool("enabled",0);
-
-    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);
+    GlobalPar.getfromXML(xml);
 
-    VoicePar[nvoice].Pextoscil=xml->getpar("ext_oscil",-1,-1,nvoice-1);
-    VoicePar[nvoice].PextFMoscil=xml->getpar("ext_fm_oscil",-1,-1,nvoice-1);
+    for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice) {
+        VoicePar[nvoice].Enabled = 0;
+        if(xml->enterbranch("VOICE", nvoice) == 0)
+            continue;
+        getfromXMLsection(xml, nvoice);
+        xml->exitbranch();
+    }
+}
 
-    VoicePar[nvoice].Poscilphase=xml->getpar127("oscil_phase",VoicePar[nvoice].Poscilphase);
-    VoicePar[nvoice].PFMoscilphase=xml->getpar127("oscil_fm_phase",VoicePar[nvoice].PFMoscilphase);
+void ADnoteParameters::getfromXMLsection(XMLwrapper *xml, int n)
+{
+    int nvoice = n;
+    if(nvoice >= NUM_VOICES)
+        return;
 
-    VoicePar[nvoice].PFilterEnabled=xml->getparbool("filter_enabled",VoicePar[nvoice].PFilterEnabled);
-    VoicePar[nvoice].Pfilterbypass=xml->getparbool("filter_bypass",VoicePar[nvoice].Pfilterbypass);
+    VoicePar[nvoice].getfromXML(xml, nvoice);
+}
 
-    VoicePar[nvoice].PFMEnabled=xml->getpar127("fm_enabled",VoicePar[nvoice].PFMEnabled);
 
-    if (xml->enterbranch("OSCIL")) {
-        VoicePar[nvoice].OscilSmp->getfromXML(xml);
+void ADnoteVoiceParam::getfromXML(XMLwrapper *xml, unsigned nvoice)
+{
+    Enabled     = xml->getparbool("enabled", 0);
+    Unison_size = xml->getpar127("unison_size", Unison_size);
+    Unison_frequency_spread = xml->getpar127("unison_frequency_spread",
+                                             Unison_frequency_spread);
+    Unison_stereo_spread = xml->getpar127("unison_stereo_spread",
+                                          Unison_stereo_spread);
+    Unison_vibratto = xml->getpar127("unison_vibratto", Unison_vibratto);
+    Unison_vibratto_speed = xml->getpar127("unison_vibratto_speed",
+                                           Unison_vibratto_speed);
+    Unison_invert_phase = xml->getpar127("unison_invert_phase",
+                                         Unison_invert_phase);
+
+    Type       = xml->getpar127("type", Type);
+    PDelay     = xml->getpar127("delay", PDelay);
+    Presonance = xml->getparbool("resonance", Presonance);
+
+    Pextoscil   = xml->getpar("ext_oscil", -1, -1, nvoice - 1);
+    PextFMoscil = xml->getpar("ext_fm_oscil", -1, -1, nvoice - 1);
+
+    Poscilphase    = xml->getpar127("oscil_phase", Poscilphase);
+    PFMoscilphase  = xml->getpar127("oscil_fm_phase", PFMoscilphase);
+    PFilterEnabled = xml->getparbool("filter_enabled", PFilterEnabled);
+    Pfilterbypass  = xml->getparbool("filter_bypass", Pfilterbypass);
+    PFMEnabled     = xml->getpar127("fm_enabled", PFMEnabled);
+
+    if(xml->enterbranch("OSCIL")) {
+        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);
+    if(xml->enterbranch("AMPLITUDE_PARAMETERS")) {
+        PPanning     = xml->getpar127("panning", PPanning);
+        PVolume      = xml->getpar127("volume", PVolume);
+        PVolumeminus = xml->getparbool("volume_minus", PVolumeminus);
+        PAmpVelocityScaleFunction = xml->getpar127("velocity_sensing",
+                                                   PAmpVelocityScaleFunction);
 
-        VoicePar[nvoice].PAmpEnvelopeEnabled=xml->getparbool("amp_envelope_enabled",VoicePar[nvoice].PAmpEnvelopeEnabled);
-        if (xml->enterbranch("AMPLITUDE_ENVELOPE")) {
-            VoicePar[nvoice].AmpEnvelope->getfromXML(xml);
+        PAmpEnvelopeEnabled = xml->getparbool("amp_envelope_enabled",
+                                              PAmpEnvelopeEnabled);
+        if(xml->enterbranch("AMPLITUDE_ENVELOPE")) {
+            AmpEnvelope->getfromXML(xml);
             xml->exitbranch();
-        };
+        }
 
-        VoicePar[nvoice].PAmpLfoEnabled=xml->getparbool("amp_lfo_enabled",VoicePar[nvoice].PAmpLfoEnabled);
-        if (xml->enterbranch("AMPLITUDE_LFO")) {
-            VoicePar[nvoice].AmpLfo->getfromXML(xml);
+        PAmpLfoEnabled = xml->getparbool("amp_lfo_enabled", PAmpLfoEnabled);
+        if(xml->enterbranch("AMPLITUDE_LFO")) {
+            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")) {
-            VoicePar[nvoice].FreqEnvelope->getfromXML(xml);
+    }
+
+    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);
+        PFreqEnvelopeEnabled = xml->getparbool("freq_envelope_enabled",
+                                               PFreqEnvelopeEnabled);
+
+        if(xml->enterbranch("FREQUENCY_ENVELOPE")) {
+            FreqEnvelope->getfromXML(xml);
             xml->exitbranch();
-        };
+        }
 
-        VoicePar[nvoice].PFreqLfoEnabled=xml->getparbool("freq_lfo_enabled",VoicePar[nvoice].PFreqLfoEnabled);
-        if (xml->enterbranch("FREQUENCY_LFO")) {
-            VoicePar[nvoice].FreqLfo->getfromXML(xml);
+        PFreqLfoEnabled = xml->getparbool("freq_lfo_enabled", PFreqLfoEnabled);
+
+        if(xml->enterbranch("FREQUENCY_LFO")) {
+            FreqLfo->getfromXML(xml);
             xml->exitbranch();
-        };
+        }
         xml->exitbranch();
-    };
+    }
 
-    if (xml->enterbranch("FILTER_PARAMETERS")) {
-        if (xml->enterbranch("FILTER")) {
-            VoicePar[nvoice].VoiceFilter->getfromXML(xml);
+    if(xml->enterbranch("FILTER_PARAMETERS")) {
+        if(xml->enterbranch("FILTER")) {
+            VoiceFilter->getfromXML(xml);
             xml->exitbranch();
-        };
+        }
 
-        VoicePar[nvoice].PFilterEnvelopeEnabled=xml->getparbool("filter_envelope_enabled",VoicePar[nvoice].PFilterEnvelopeEnabled);
-        if (xml->enterbranch("FILTER_ENVELOPE")) {
-            VoicePar[nvoice].FilterEnvelope->getfromXML(xml);
+        PFilterEnvelopeEnabled = xml->getparbool("filter_envelope_enabled",
+                                                 PFilterEnvelopeEnabled);
+        if(xml->enterbranch("FILTER_ENVELOPE")) {
+            FilterEnvelope->getfromXML(xml);
             xml->exitbranch();
-        };
+        }
 
-        VoicePar[nvoice].PFilterLfoEnabled=xml->getparbool("filter_lfo_enabled",VoicePar[nvoice].PFilterLfoEnabled);
-        if (xml->enterbranch("FILTER_LFO")) {
-            VoicePar[nvoice].FilterLfo->getfromXML(xml);
+        PFilterLfoEnabled = xml->getparbool("filter_lfo_enabled",
+                                            PFilterLfoEnabled);
+        if(xml->enterbranch("FILTER_LFO")) {
+            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")) {
-            VoicePar[nvoice].FMAmpEnvelope->getfromXML(xml);
+    }
+
+    if(xml->enterbranch("FM_PARAMETERS")) {
+        PFMVoice      = xml->getpar("input_voice", PFMVoice, -1, nvoice - 1);
+        PFMVolume     = xml->getpar127("volume", PFMVolume);
+        PFMVolumeDamp = xml->getpar127("volume_damp", PFMVolumeDamp);
+        PFMVelocityScaleFunction = xml->getpar127("velocity_sensing",
+                                                  PFMVelocityScaleFunction);
+
+        PFMAmpEnvelopeEnabled = xml->getparbool("amp_envelope_enabled",
+                                                PFMAmpEnvelopeEnabled);
+        if(xml->enterbranch("AMPLITUDE_ENVELOPE")) {
+            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")) {
-                VoicePar[nvoice].FMFreqEnvelope->getfromXML(xml);
+        }
+
+        if(xml->enterbranch("MODULATOR")) {
+            PFMDetune = xml->getpar("detune", PFMDetune, 0, 16383);
+            PFMCoarseDetune = xml->getpar("coarse_detune",
+                                          PFMCoarseDetune,
+                                          0,
+                                          16383);
+            PFMDetuneType = xml->getpar127("detune_type", PFMDetuneType);
+
+            PFMFreqEnvelopeEnabled = xml->getparbool("freq_envelope_enabled",
+                                                     PFMFreqEnvelopeEnabled);
+            if(xml->enterbranch("FREQUENCY_ENVELOPE")) {
+                FMFreqEnvelope->getfromXML(xml);
                 xml->exitbranch();
-            };
+            }
 
-            if (xml->enterbranch("OSCIL")) {
-                VoicePar[nvoice].FMSmp->getfromXML(xml);
+            if(xml->enterbranch("OSCIL")) {
+                FMSmp->getfromXML(xml);
                 xml->exitbranch();
-            };
+            }
 
             xml->exitbranch();
-        };
+        }
         xml->exitbranch();
-    };
-};
-
-
+    }
+}
diff --git a/src/Params/ADnoteParameters.h b/src/Params/ADnoteParameters.h
index 8b35f92..291d5b4 100644
--- a/src/Params/ADnoteParameters.h
+++ b/src/Params/ADnoteParameters.h
@@ -25,24 +25,31 @@
 
 
 #include "../globals.h"
-#include "EnvelopeParams.h"
-#include "LFOParams.h"
-#include "FilterParams.h"
-#include "../Synth/OscilGen.h"
-#include "../Synth/Resonance.h"
 #include "../Misc/Util.h"
-#include "../Misc/XMLwrapper.h"
-#include "../DSP/FFTwrapper.h"
-#include "Presets.h"
+#include "PresetsArray.h"
 
-enum FMTYPE {NONE,MORPH,RING_MOD,PHASE_MOD,FREQ_MOD,PITCH_MOD};
+class EnvelopeParams;
+class LFOParams;
+class FilterParams;
+class Resonance;
+class OscilGen;
+class FFTwrapper;
+
+enum FMTYPE {
+    NONE, MORPH, RING_MOD, PHASE_MOD, FREQ_MOD, PITCH_MOD
+};
+extern int ADnote_unison_sizes[];
 
 /*****************************************************************/
 /*                    GLOBAL PARAMETERS                          */
 /*****************************************************************/
 
 struct ADnoteGlobalParam {
-
+    ADnoteGlobalParam();
+    ~ADnoteGlobalParam();
+    void defaults();
+    void add2XML(XMLwrapper *xml);
+    void getfromXML(XMLwrapper *xml);
     /* The instrument type  - MONO/STEREO
     If the mode is MONO, the panning of voices are not used
     Stereo=1, Mono=0. */
@@ -53,24 +60,24 @@ 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 */
+              1 - left
+             64 - center
+            127 - right */
     unsigned char PPanning;
 
     unsigned char PVolume;
@@ -81,7 +88,8 @@ struct ADnoteGlobalParam {
 
     LFOParams *AmpLfo;
 
-    unsigned char PPunchStrength,PPunchTime,PPunchStretch,PPunchVelocitySensing;
+    unsigned char PPunchStrength, PPunchTime, PPunchStretch,
+                  PPunchVelocitySensing;
 
     /******************************************
     *        FILTER GLOBAL PARAMETERS        *
@@ -111,10 +119,32 @@ struct ADnoteGlobalParam {
 /*                    VOICE PARAMETERS                     */
 /***********************************************************/
 struct ADnoteVoiceParam {
-
+    void getfromXML(XMLwrapper *xml, unsigned nvoice);
+    void add2XML(XMLwrapper *xml, bool fmoscilused);
+    void defaults();
+    void enable(FFTwrapper *fft, Resonance *Reson);
+    void kill();
     /** If the voice is enabled */
     unsigned char Enabled;
 
+    /** How many subvoices are used in this voice */
+    unsigned char Unison_size;
+
+    /** 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;
+
+    /** 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;
 
@@ -125,11 +155,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;
@@ -159,12 +189,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;
 
 
     /***************************
@@ -172,9 +202,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;
 
@@ -188,12 +218,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;
 
 
 
@@ -206,12 +236,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   *
@@ -247,37 +277,40 @@ 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
+class ADnoteParameters:public PresetsArray
 {
-public:
-    ADnoteParameters(FFTwrapper *fft_);
-    ~ADnoteParameters();
-
-    ADnoteGlobalParam GlobalPar;
-    ADnoteVoiceParam VoicePar[NUM_VOICES];
-
-    void defaults();
-    void add2XML(XMLwrapper *xml);
-    void getfromXML(XMLwrapper *xml);
-
-    REALTYPE getBandwidthDetuneMultiplier();
-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);
+
+        float getBandwidthDetuneMultiplier();
+        float 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/CMakeLists.txt b/src/Params/CMakeLists.txt
new file mode 100644
index 0000000..85ab4c8
--- /dev/null
+++ b/src/Params/CMakeLists.txt
@@ -0,0 +1,19 @@
+set(zynaddsubfx_params_SRCS
+	ADnoteParameters.cpp
+	Controller.cpp
+	EnvelopeParams.cpp
+	FilterParams.cpp
+	LFOParams.cpp
+	PADnoteParameters.cpp
+	Presets.cpp
+	PresetsArray.cpp
+	PresetsStore.cpp
+	SUBnoteParameters.cpp
+
+)
+
+add_library(zynaddsubfx_params STATIC
+	${zynaddsubfx_params_SRCS} 
+	)
+
+target_link_libraries(zynaddsubfx_params zynaddsubfx_misc)
diff --git a/src/Params/Controller.cpp b/src/Params/Controller.cpp
index 1b6f9f8..3634386 100644
--- a/src/Params/Controller.cpp
+++ b/src/Params/Controller.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  Controller.C - (Midi) Controllers implementation
+  Controller.cpp - (Midi) Controllers implementation
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -28,47 +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=0;
-    sustain.receive=1;
-    NRPN.receive=1;
-
-    portamento.portamento=0;
-    portamento.used=0;
-    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.0f, 440.0f, false); // Now has a third argument
     setportamento(0);
-
-};
+}
 
 void Controller::resetall()
 {
-    setpitchwheel(0);//center
+    setpitchwheel(0); //center
     setexpression(127);
     setpanning(64);
     setfiltercutoff(64);
@@ -82,257 +83,337 @@ 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;
+    float cents = value / 8192.0f;
+    cents *= pitchwheel.bendrange;
+    pitchwheel.relfreq = powf(2, cents / 1200.0f);
     //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.0f;
+    else
+        expression.relvolume = 1.0f;
+}
 
 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.0f - 0.5f) * (panning.depth / 64.0f);
+}
 
 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.0f) * filtercutoff.depth / 4096.0f * 3.321928f;         //3.3219f..=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 = powf(30.0f, (value - 64.0f) / 64.0f * (filterq.depth / 64.0f));
+}
 
 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) {
+        float tmp = powf(25.0f, powf(bandwidth.depth / 127.0f, 1.5f)) - 1.0f;
+        if((value < 64) && (bandwidth.depth >= 64))
+            tmp = 1.0f;
+        bandwidth.relbw = (value / 64.0f - 1.0f) * tmp + 1.0f;
+        if(bandwidth.relbw < 0.01f)
+            bandwidth.relbw = 0.01f;
+    }
+    else
+        bandwidth.relbw =
+            powf(25.0f, (value - 64.0f) / 64.0f * (bandwidth.depth / 64.0f));
+    ;
+}
 
 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) {
+        float tmp =
+            powf(25.0f, powf(modwheel.depth / 127.0f, 1.5f) * 2.0f) / 25.0f;
+        if((value < 64) && (modwheel.depth >= 64))
+            tmp = 1.0f;
+        modwheel.relmod = (value / 64.0f - 1.0f) * tmp + 1.0f;
+        if(modwheel.relmod < 0.0f)
+            modwheel.relmod = 0.0f;
+    }
+    else
+        modwheel.relmod =
+            powf(25.0f, (value - 64.0f) / 64.0f * (modwheel.depth / 80.0f));
+}
 
 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.0f;
+    if(fmamp.receive != 0)
+        fmamp.relamp = value / 127.0f;
+    else
+        fmamp.relamp = 1.0f;
+}
 
 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 = powf(0.1f, (127 - value) / 127.0f * 2.0f);
+    else
+        volume.volume = 1.0f;
+}
 
 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 );
-};
-
-// I added a third argument to pass legato status,
-// when legatoflag is true it means "there's a legato in progress".
-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(float oldfreq,
+                               float newfreq,
+                               bool legatoflag)
 {
-    portamento.x=0.0;
+    portamento.x = 0.0f;
 
-    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
+    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;
+    ;
+
+    float portamentotime = powf(100.0f, portamento.time / 127.0f) / 50.0f; //portamento time in seconds
+
+    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 *=
+                powf(oldfreq / newfreq
+                     / (portamento.propRate / 127.0f * 3 + .05),
+                     (portamento.propDepth / 127.0f * 1.6f + .2));
+        else                  //1 is the center of propDepth
+            portamentotime *=
+                powf(newfreq / oldfreq
+                     / (portamento.propRate / 127.0f * 3 + .05),
+                     (portamento.propDepth / 127.0f * 1.6f + .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 *= powf(0.1f,
+                               (portamento.updowntimestretch - 64) / 63.0f);
+    }
+    if((portamento.updowntimestretch < 64) && (newfreq > oldfreq)) {
+        if(portamento.updowntimestretch == 0)
+            return 0;
+        portamentotime *= powf(0.1f,
+                               (64.0f - portamento.updowntimestretch) / 64.0f);
     }
-    if ((portamento.updowntimestretch<64)&&(newfreq>oldfreq)) {
-        if (portamento.updowntimestretch==0) return(0);
-        portamentotime*=pow(0.1,(64.0-portamento.updowntimestretch)/64.0);
-    };
 
-    portamento.dx=SOUND_BUFFER_SIZE/(portamentotime*SAMPLE_RATE);
-    portamento.origfreqrap=oldfreq/newfreq;
+    //printf("%f->%f : Time %f\n",oldfreq,newfreq,portamentotime);
 
-    REALTYPE tmprap=( (portamento.origfreqrap>1.0) ?
-                      (portamento.origfreqrap) :
-                      (1.0/portamento.origfreqrap) );
+    portamento.dx = synth->buffersize_f / (portamentotime * synth->samplerate_f);
+    portamento.origfreqrap = oldfreq / newfreq;
 
-    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);
+    float tmprap = ((portamento.origfreqrap > 1.0f) ?
+                    (portamento.origfreqrap) :
+                    (1.0f / portamento.origfreqrap));
 
-    portamento.used=1;
-    portamento.freqrap=portamento.origfreqrap;
-    return (1);
-};
+    float thresholdrap = powf(2.0f, portamento.pitchthresh / 12.0f);
+    if((portamento.pitchthreshtype == 0) && (tmprap - 0.00001f > thresholdrap))
+        return 0;
+    if((portamento.pitchthreshtype == 1) && (tmprap + 0.00001f < thresholdrap))
+        return 0;
+
+    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.0f) {
+        portamento.x    = 1.0f;
+        portamento.used = 0;
+    }
+    portamento.freqrap =
+        (1.0f - 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 =
+        powf(3.0f, (value - 64.0f) / 64.0f * (resonancecenter.depth / 64.0f));
+}
 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 =
+        powf(1.5f, (value - 64.0f) / 64.0f * (resonancebandwidth.depth / 127.0f));
+}
 
 
 //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) {
-    case C_nrpnhi:
-        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
-        break;
-    case C_dataentryhi:
-        if ((NRPN.parhi>=0)&&(NRPN.parlo>=0)) NRPN.valhi=value;
-        break;
-    case C_dataentrylo:
-        if ((NRPN.parhi>=0)&&(NRPN.parlo>=0)) NRPN.vallo=value;
-        break;
-    };
-};
+    switch(type) {
+        case C_nrpnhi:
+            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
+            break;
+        case C_dataentryhi:
+            if((NRPN.parhi >= 0) && (NRPN.parlo >= 0))
+                NRPN.valhi = value;
+            break;
+        case C_dataentrylo:
+            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("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);
-
-    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
index 600c85a..22483ea 100644
--- a/src/Params/Controller.h
+++ b/src/Params/Controller.h
@@ -30,152 +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);
-    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);
-
-    int initportamento(REALTYPE oldfreq,REALTYPE newfreq,bool legatoflag);//returns 1 if the portamento's conditions are true, else return 0
-    void updateportamento(); //update portamento values
-
-    // 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;
-
-        unsigned char receive,time;
-        /**pitchthresh is the threshold of enabling protamento \todo see if this should be an int*/
-        unsigned char pitchthresh;
-        /**pitchthreshtype -> 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 portanemto' means when the frequency is rising (eg: the portamento is from 200Hz to 300 Hz)
-         * 'down portanemto' means when the frequency is lowering (eg: the portamento is from 300Hz to 200 Hz)
-         */
-        unsigned char updowntimestretch;
-
-        REALTYPE freqrap;/**<this value is used to compute the actual portamento*/
-        int noteusing;/**this is used by the Part for knowing which note uses the portamento*/
-        int used;/**<if a the portamento is used by a note \todo see if this can be a bool*/
-        //internal data
-        REALTYPE x,dx;//x is from 0.0 (start portamento) to 1.0 (finished portamento), dx is x increment
-        REALTYPE origfreqrap;// this is used for computing oldfreq value from x
-    } 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:
+    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(float oldfreq, float 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
+            float     relfreq; //the relative frequency (default is 1.0f)
+        } pitchwheel;
+
+        struct { //Expression
+            int   data;
+            float relvolume;
+            unsigned char receive;
+        } expression;
+
+        struct { //Panning
+            int   data;
+            float pan;
+            unsigned char depth;
+        } panning;
+
+
+        struct { //Filter cutoff
+            int   data;
+            float relfreq;
+            unsigned char depth;
+        } filtercutoff;
+
+        struct { //Filter Q
+            int   data;
+            float relq;
+            unsigned char depth;
+        } filterq;
+
+        struct { //Bandwidth
+            int   data;
+            float relbw;
+            unsigned char depth;
+            unsigned char exponential;
+        } bandwidth;
+
+        struct { //Modulation Wheel
+            int   data;
+            float relmod;
+            unsigned char depth;
+            unsigned char exponential;
+        } modwheel;
+
+        struct { //FM amplitude
+            int   data;
+            float relamp;
+            unsigned char receive;
+        } fmamp;
+
+        struct { //Volume
+            int   data;
+            float 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.93f 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.*/
+            float 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.0f (start portamento) to 1.0f (finished portamento)*/
+            float x;
+            /**dx is the increment to x when updateportamento is called*/
+            float dx;
+            /** this is used for computing oldfreq value from x*/
+            float origfreqrap;
+        } portamento;
+
+        struct { //Resonance Center Frequency
+            int   data;
+            float relcenter;
+            unsigned char depth;
+        } resonancecenter;
+
+        struct { //Resonance Bandwidth
+            int   data;
+            float 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
index fa2d957..a06704d 100644
--- a/src/Params/EnvelopeParams.cpp
+++ b/src/Params/EnvelopeParams.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  EnvelopeParams.C - Parameters for Envelope
+  EnvelopeParams.cpp - Parameters for Envelope
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -26,264 +26,271 @@
 #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)
+float EnvelopeParams::getdt(char i)
 {
-    REALTYPE result=(pow(2.0,Penvdt[(int)i]/127.0*12.0)-1.0)*10.0;//miliseconds
-    return(result);
-};
+    float result = (powf(2.0f, Penvdt[(int)i] / 127.0f * 12.0f) - 1.0f) * 10.0f; //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) {
-    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;
-        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;
-        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;
-        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;
-        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;
-        break;
-    };
-};
+    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;
+            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;
+            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;
+            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;
+            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;
+            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
index d7d44c8..0b3e99c 100644
--- a/src/Params/EnvelopeParams.h
+++ b/src/Params/EnvelopeParams.h
@@ -28,59 +28,62 @@
 #include "Presets.h"
 
 #define MAX_ENVELOPE_POINTS 40
-#define MIN_ENVELOPE_DB -40
+#define MIN_ENVELOPE_DB -400
 
 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);
+
+        float 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
index 861b6d3..81309d6 100644
--- a/src/Params/FilterParams.cpp
+++ b/src/Params/FilterParams.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  FilterParams.C - Parameters for filter
+  FilterParams.cpp - Parameters for filter
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -20,63 +20,67 @@
 
 */
 
+#include "FilterParams.h"
+#include "../Misc/Util.h"
 #include <math.h>
 #include <stdio.h>
 #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_)
+    :PresetsArray()
 {
     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.0f); //some random freqs
+        Pvowels[j].formants[i].q    = 64;
+        Pvowels[j].formants[i].amp  = 127;
+    }
+}
 
 
 /*
@@ -87,280 +91,302 @@ 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;
+}
 
 
 /*
  * Parameter control
  */
-REALTYPE FilterParams::getfreq()
+float FilterParams::getfreq()
 {
-    return((Pfreq/64.0-1.0)*5.0);
-};
+    return (Pfreq / 64.0f - 1.0f) * 5.0f;
+}
 
-REALTYPE FilterParams::getq()
+float FilterParams::getq()
 {
-    return(exp(pow((REALTYPE) Pq/127.0,2)*log(1000.0))-0.9);
-};
-REALTYPE FilterParams::getfreqtracking(REALTYPE notefreq)
+    return expf(powf((float) Pq / 127.0f, 2) * logf(1000.0f)) - 0.9f;
+}
+float FilterParams::getfreqtracking(float notefreq)
 {
-    return(log(notefreq/440.0)*(Pfreqtrack-64.0)/(64.0*LOG_2));
-};
+    return logf(notefreq / 440.0f) * (Pfreqtrack - 64.0f) / (64.0f * LOG_2);
+}
 
-REALTYPE FilterParams::getgain()
+float FilterParams::getgain()
 {
-    return((Pgain/64.0-1.0)*30.0);//-30..30dB
-};
+    return (Pgain / 64.0f - 1.0f) * 30.0f; //-30..30dB
+}
 
 /*
  * Get the center frequency of the formant's graph
  */
-REALTYPE FilterParams::getcenterfreq()
+float FilterParams::getcenterfreq()
 {
-    return(10000.0*pow(10,-(1.0-Pcenterfreq/127.0)*2.0));
-};
+    return 10000.0f * powf(10, -(1.0f - Pcenterfreq / 127.0f) * 2.0f);
+}
 
 /*
  * Get the number of octave that the formant functions applies to
  */
-REALTYPE FilterParams::getoctavesfreq()
+float FilterParams::getoctavesfreq()
 {
-    return(0.25+10.0*Poctavesfreq/127.0);
-};
+    return 0.25f + 10.0f * Poctavesfreq / 127.0f;
+}
 
 /*
  * Get the frequency from x, where x is [0..1]
  */
-REALTYPE FilterParams::getfreqx(REALTYPE x)
+float FilterParams::getfreqx(float x)
 {
-    if (x>1.0) x=1.0;
-    REALTYPE octf=pow(2.0,getoctavesfreq());
-    return(getcenterfreq()/sqrt(octf)*pow(octf,x));
-};
+    if(x > 1.0f)
+        x = 1.0f;
+    float octf = powf(2.0f, getoctavesfreq());
+    return getcenterfreq() / sqrt(octf) * powf(octf, x);
+}
 
 /*
  * Get the x coordinate from frequency (used by the UI)
  */
-REALTYPE FilterParams::getfreqpos(REALTYPE freq)
+float FilterParams::getfreqpos(float freq)
 {
-    return((log(freq)-log(getfreqx(0.0)))/log(2.0)/getoctavesfreq());
-};
+    return (logf(freq) - logf(getfreqx(0.0f))) / logf(2.0f) / 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, float *freqs)
 {
-    REALTYPE c[3],d[3];
-    REALTYPE filter_freq,filter_q,filter_amp;
-    REALTYPE omega,sn,cs,alpha;
+    float c[3], d[3];
+    float filter_freq, filter_q, filter_amp;
+    float 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.0f;
 
     //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.0f ? powf(filter_q, 1.0f / (Pstages + 1)) : filter_q);
+
+        filter_amp = getformantamp(Pvowels[nvowel].formants[nformant].amp);
+
+
+        if(filter_freq <= (synth->samplerate / 2 - 100.0f)) {
+            omega = 2 * PI * filter_freq / synth->samplerate_f;
+            sn    = sinf(omega);
+            cs    = cosf(omega);
+            alpha = sn / (2 * filter_q);
+            float 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) {
+            float freq = getfreqx(i / (float) nfreqs);
+            if(freq > synth->samplerate / 2) {
+                for(int tmp = i; tmp < nfreqs; ++tmp)
+                    freqs[tmp] = 0.0f;
                 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;
-    };
-
-};
+            }
+            float fr = freq / synth->samplerate * PI * 2.0f;
+            float x  = c[0], y = 0.0f;
+            for(int n = 1; n < 3; ++n) {
+                x += cosf(n * fr) * c[n];
+                y -= sinf(n * fr) * c[n];
+            }
+            float h = x * x + y * y;
+            x = 1.0f;
+            y = 0.0f;
+            for(int n = 1; n < 3; ++n) {
+                x -= cosf(n * fr) * d[n];
+                y += sinf(n * fr) * d[n];
+            }
+            h = h / (x * x + y * y);
+
+            freqs[i] += powf(h, (Pstages + 1.0f) / 2.0f) * filter_amp;
+        }
+    }
+    for(int i = 0; i < nfreqs; ++i) {
+        if(freqs[i] > 0.000000001f)
+            freqs[i] = rap2dB(freqs[i]) + getgain();
+        else
+            freqs[i] = -90.0f;
+    }
+}
 
 /*
  * Transforms a parameter to the real value
  */
-REALTYPE FilterParams::getformantfreq(unsigned char freq)
+float FilterParams::getformantfreq(unsigned char freq)
 {
-    REALTYPE result=getfreqx(freq/127.0);
-    return(result);
-};
+    float result = getfreqx(freq / 127.0f);
+    return result;
+}
 
-REALTYPE FilterParams::getformantamp(unsigned char amp)
+float FilterParams::getformantamp(unsigned char amp)
 {
-    REALTYPE result=pow(0.1,(1.0-amp/127.0)*4.0);
-    return(result);
-};
+    float result = powf(0.1f, (1.0f - amp / 127.0f) * 4.0f);
+    return result;
+}
 
-REALTYPE FilterParams::getformantq(unsigned char q)
+float FilterParams::getformantq(unsigned char q)
 {
     //temp
-    REALTYPE result=pow(25.0,(q-32.0)/64.0);
-    return(result);
-};
+    float result = powf(25.0f, (q - 32.0f) / 64.0f);
+    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
index 89c8b46..22a1a94 100644
--- a/src/Params/FilterParams.h
+++ b/src/Params/FilterParams.h
@@ -25,77 +25,78 @@
 
 #include "../globals.h"
 #include "../Misc/XMLwrapper.h"
-#include "Presets.h"
+#include "PresetsArray.h"
 
-class FilterParams:public Presets
+class FilterParams:public PresetsArray
 {
-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);
+
+        float getfreq();
+        float getq();
+        float getfreqtracking(float notefreq);
+        float 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);
+        float getcenterfreq();
+        float getoctavesfreq();
+        float getfreqpos(float freq);
+        float getfreqx(float x);
 
-    void formantfilterH(int nvowel,int nfreqs,REALTYPE *freqs);//used by UI
+        void formantfilterH(int nvowel, int nfreqs, float *freqs); //used by UI
 
-    REALTYPE getformantfreq(unsigned char freq);
-    REALTYPE getformantamp(unsigned char amp);
-    REALTYPE getformantq(unsigned char q);
+        float getformantfreq(unsigned char freq);
+        float getformantamp(unsigned char amp);
+        float 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
index a124c59..72f2269 100644
--- a/src/Params/LFOParams.cpp
+++ b/src/Params/LFOParams.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  LFOParams.C - Parameters for LFO
+  LFOParams.cpp - Parameters for LFO
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -27,73 +27,78 @@
 
 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_) {
-    case 0:
-        setpresettype("Plfofrequency");
-        break;
-    case 1:
-        setpresettype("Plfoamplitude");
-        break;
-    case 2:
-        setpresettype("Plfofilter");
-        break;
-    };
-    Dfreq=Pfreq_;
-    Dintensity=Pintensity_;
-    Dstartphase=Pstartphase_;
-    DLFOtype=PLFOtype_;
-    Drandomness=Prandomness_;
-    Ddelay=Pdelay_;
-    Dcontinous=Pcontinous_;
-    fel=fel_;
-    time=0;
+    switch(fel_) {
+        case 0:
+            setpresettype("Plfofrequency");
+            break;
+        case 1:
+            setpresettype("Plfoamplitude");
+            break;
+        case 2:
+            setpresettype("Plfofilter");
+            break;
+    }
+    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.0f;
+    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.0f, 1.0f);
+    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
index a650d27..6ca3071 100644
--- a/src/Params/LFOParams.h
+++ b/src/Params/LFOParams.h
@@ -28,38 +28,44 @@
 
 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*/
+        float 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/Makefile b/src/Params/Makefile
deleted file mode 100644
index 4500ede..0000000
--- a/src/Params/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-include ../Makefile.inc
-
-objects=ADnoteParameters.o EnvelopeParams.o FilterParams.o \
-        LFOParams.o SUBnoteParameters.o PADnoteParameters.o Controller.o Presets.o PresetsStore.o
-
-
-all: $(objects)
-
--include ../Make.deps
-
-.PHONY : clean
-clean: 
-	rm -f $(objects)
-	rm -f makeinclude.deps
-
diff --git a/src/Params/PADnoteParameters.cpp b/src/Params/PADnoteParameters.cpp
index 3143cb8..8d612b5 100644
--- a/src/Params/PADnoteParameters.cpp
+++ b/src/Params/PADnoteParameters.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  PADnoteParameters.C - Parameters for PADnote (PADsynth)
+  PADnoteParameters.cpp - Parameters for PADnote (PADsynth)
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -21,606 +21,691 @@
 */
 #include <math.h>
 #include "PADnoteParameters.h"
-#include "../Output/WAVaudiooutput.h"
-using namespace std;
+#include "../Misc/WavFile.h"
 
-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.0f;
+}
 
 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)
+float PADnoteParameters::getprofile(float *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.0f;
+    const int supersample = 16;
+    float     basepar     = powf(2.0f, (1.0f - Php.base.par1 / 127.0f) * 12.0f);
+    float     freqmult    = floor(powf(2.0f,
+                                       Php.freqmult / 127.0f
+                                       * 5.0f) + 0.000001f);
+
+    float modfreq = floor(powf(2.0f,
+                               Php.modulator.freq / 127.0f
+                               * 5.0f) + 0.000001f);
+    float modpar1 = powf(Php.modulator.par1 / 127.0f, 4.0f) * 5.0f / sqrt(
+        modfreq);
+    float amppar1 =
+        powf(2.0f, powf(Php.amp.par1 / 127.0f, 2.0f) * 10.0f) - 0.999f;
+    float amppar2 = (1.0f - Php.amp.par2 / 127.0f) * 0.998f + 0.001f;
+    float width   = powf(150.0f / (Php.width + 22.0f), 2.0f);
+
+    for(int i = 0; i < size * supersample; ++i) {
+        bool  makezero = false;
+        float x = i * 1.0f / (size * (float) supersample);
+
+        float 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.5f) * width + 0.5f;
+        if(x < 0.0f) {
+            x = 0.0f;
+            makezero = true;
+        }
+        else
+        if(x > 1.0f) {
+            x = 1.0f;
+            makezero = true;
+        }
 
         //compute the full profile or one half
-        switch (Php.onehalf) {
-        case 1:
-            x=x*0.5+0.5;
-            break;
-        case 2:
-            x=x*0.5;
-            break;
-        };
+        switch(Php.onehalf) {
+            case 1:
+                x = x * 0.5f + 0.5f;
+                break;
+            case 2:
+                x = x * 0.5f;
+                break;
+        }
 
-        REALTYPE x_before_freq_mult=x;
+        float 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 += sinf(x_before_freq_mult * 3.1415926f * modfreq) * modpar1;
+        x  = fmod(x + 1000.0f, 1.0f) * 2.0f - 1.0f;
 
 
         //this is the base function of the profile
-        REALTYPE f;
-        switch (Php.base.type) {
-        case 1:
-            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));
-            break;
-        default:
-            f=exp(-(x*x)*basepar);
-            break;
-        };
-        if (makezero) f=0.0;
+        float f;
+        switch(Php.base.type) {
+            case 1:
+                f = expf(-(x * x) * basepar);
+                if(f < 0.4f)
+                    f = 0.0f;
+                else
+                    f = 1.0f;
+                break;
+            case 2:
+                f = expf(-(fabs(x)) * sqrt(basepar));
+                break;
+            default:
+                f = expf(-(x * x) * basepar);
+                break;
+        }
+        if(makezero)
+            f = 0.0f;
 
-        REALTYPE amp=1.0;
-        origx=origx*2.0-1.0;
+        float amp = 1.0f;
+        origx = origx * 2.0f - 1.0f;
 
         //compute the amplitude multiplier
-        switch (Php.amp.type) {
-        case 1:
-            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)));
-            break;
-        case 3:
-            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) {
-            case 0:
-                finalsmp=amp*(1.0-amppar2)+finalsmp*amppar2;
-                break;
+        switch(Php.amp.type) {
             case 1:
-                finalsmp*=amp*(1.0-amppar2)+amppar2;
+                amp = expf(-(origx * origx) * 10.0f * amppar1);
                 break;
             case 2:
-                finalsmp=finalsmp/(amp+pow(amppar2,4.0)*20.0+0.0001);
+                amp = 0.5f
+                      * (1.0f
+                         + cosf(3.1415926f * origx * sqrt(amppar1 * 4.0f + 1.0f)));
                 break;
             case 3:
-                finalsmp=amp/(finalsmp+pow(amppar2,4.0)*20.0+0.0001);
+                amp = 1.0f
+                      / (powf(origx * (amppar1 * 2.0f + 0.8f), 14.0f) + 1.0f);
                 break;
-            };
-        };
-
-        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);
+        //apply the amplitude multiplier
+        float finalsmp = f;
+        if(Php.amp.type != 0)
+            switch(Php.amp.mode) {
+                case 0:
+                    finalsmp = amp * (1.0f - amppar2) + finalsmp * amppar2;
+                    break;
+                case 1:
+                    finalsmp *= amp * (1.0f - amppar2) + amppar2;
+                    break;
+                case 2:
+                    finalsmp = finalsmp
+                               / (amp + powf(amppar2, 4.0f) * 20.0f + 0.0001f);
+                    break;
+                case 3:
+                    finalsmp = amp
+                               / (finalsmp
+                                  + powf(amppar2, 4.0f) * 20.0f + 0.0001f);
+                    break;
+            }
+        ;
+
+        smp[i / supersample] += finalsmp / supersample;
+    }
+
+    //normalize the profile (make the max. to be equal to 1.0f)
+    float max = 0.0f;
+    for(int i = 0; i < size; ++i) {
+        if(smp[i] < 0.0f)
+            smp[i] = 0.0f;
+        if(smp[i] > max)
+            max = smp[i];
+    }
+    if(max < 0.00001f)
+        max = 1.0f;
+    for(int i = 0; i < size; ++i)
+        smp[i] /= max;
+
+    if(!Php.autoscale)
+        return 0.5f;
 
     //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;
-    };
+    float sum = 0.0f;
+    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.0f)
+            break;
+    }
 
-    REALTYPE result=1.0-2.0*i/(REALTYPE) size;
-    return(result);
-};
+    float result = 1.0f - 2.0f * i / (float) size;
+    return result;
+}
 
 /*
  * Compute the real bandwidth in cents and returns it
  * Also, sets the bandwidth parameter
  */
-REALTYPE PADnoteParameters::setPbandwidth(int Pbandwidth)
+float 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;
+    float result = powf(Pbandwidth / 1000.0f, 1.1f);
+    result = powf(10.0f, result * 4.0f) * 0.25f;
+    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) {
-    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;
-        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;
-        break;
-    case 3:
-        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;
-        break;
-    case 5:
-        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;
-        break;
-    default:
-        result=n;
-        break;
-    };
-
-    REALTYPE par3=Phrpos.par3/255.0;
-
-    REALTYPE iresult=floor(result+0.5);
-    REALTYPE dresult=result-iresult;
-
-    result=iresult+(1.0-par3)*dresult;
-
-    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)
+float PADnoteParameters::getNhr(int n)
 {
-    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;
-    //get the harmonic structure from the oscillator (I am using the frequency amplitudes, only)
-    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;
-
-        //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) {
-        case 0:
-            power=1.0;
-            break;
+    float result = 1.0f;
+    float par1   = powf(10.0f, -(1.0f - Phrpos.par1 / 255.0f) * 3.0f);
+    float par2   = Phrpos.par2 / 255.0f;
+
+    float n0     = n - 1.0f;
+    float tmp    = 0.0f;
+    int   thresh = 0;
+    switch(Phrpos.type) {
         case 1:
-            power=0.0;
+            thresh = (int)(par2 * par2 * 100.0f) + 1;
+            if(n < thresh)
+                result = n;
+            else
+                result = 1.0f + n0 + (n0 - thresh + 1.0f) * par1 * 8.0f;
             break;
         case 2:
-            power=0.25;
+            thresh = (int)(par2 * par2 * 100.0f) + 1;
+            if(n < thresh)
+                result = n;
+            else
+                result = 1.0f + n0 - (n0 - thresh + 1.0f) * par1 * 0.90f;
             break;
         case 3:
-            power=0.5;
+            tmp    = par1 * 100.0f + 1.0f;
+            result = powf(n0 / tmp, 1.0f - par2 * 0.8f) * tmp + 1.0f;
             break;
         case 4:
-            power=0.75;
+            result = n0
+                     * (1.0f
+                        - par1)
+                     + powf(n0 * 0.1f, par2 * 3.0f
+                            + 1.0f) * par1 * 10.0f + 1.0f;
             break;
         case 5:
-            power=1.5;
+            result = n0
+                     + sinf(n0 * par2 * par2 * PI
+                            * 0.999f) * sqrt(par1) * 2.0f + 1.0f;
             break;
         case 6:
-            power=2.0;
+            tmp    = powf(par2 * 2.0f, 2.0f) + 0.1f;
+            result = n0 * powf(1.0f + par1 * powf(n0 * 0.8f, tmp), tmp) + 1.0f;
             break;
-        case 7:
-            power=-0.5;
+        default:
+            result = n;
             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;
-            };
-        };
-    };
-};
+    }
+
+    float par3 = Phrpos.par3 / 255.0f;
+
+    float iresult = floor(result + 0.5f);
+    float dresult = result - iresult;
+
+    result = iresult + (1.0f - par3) * dresult;
+
+    return result;
+}
 
 /*
- * Generates the long spectrum for non-Bandwidth modes (only amplitudes are generated; phases will be random)
+ * Generates the long spectrum for Bandwidth mode (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_bandwidthMode(float *spectrum,
+                                                       int size,
+                                                       float basefreq,
+                                                       float *profile,
+                                                       int profilesize,
+                                                       float bwadjust)
 {
-    for (int i=0;i<size;i++) spectrum[i]=0.0;
+    for(int i = 0; i < size; ++i)
+        spectrum[i] = 0.0f;
 
-    REALTYPE harmonics[OSCIL_SIZE/2];
-    for (int i=0;i<OSCIL_SIZE/2;i++) harmonics[i]=0.0;
+    float harmonics[synth->oscilsize / 2];
+    for(int i = 0; i < synth->oscilsize / 2; ++i)
+        harmonics[i] = 0.0f;
     //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;
+    float max = 0.0f;
+    for(int i = 0; i < synth->oscilsize / 2; ++i)
+        if(harmonics[i] > max)
+            max = harmonics[i];
+    if(max < 0.000001f)
+        max = 1;
+    for(int i = 0; i < synth->oscilsize / 2; ++i)
+        harmonics[i] /= max;
+
+    for(int nh = 1; nh < synth->oscilsize / 2; ++nh) { //for each harmonic
+        float realfreq = getNhr(nh) * basefreq;
+        if(realfreq > synth->samplerate_f * 0.49999f)
+            break;
+        if(realfreq < 20.0f)
+            break;
+        if(harmonics[nh - 1] < 1e-4)
+            continue;
+
+        //compute the bandwidth of each harmonic
+        float bandwidthcents = setPbandwidth(Pbandwidth);
+        float bw =
+            (powf(2.0f, bandwidthcents / 1200.0f) - 1.0f) * basefreq / bwadjust;
+        float power = 1.0f;
+        switch(Pbwscale) {
+            case 0:
+                power = 1.0f;
+                break;
+            case 1:
+                power = 0.0f;
+                break;
+            case 2:
+                power = 0.25f;
+                break;
+            case 3:
+                power = 0.5f;
+                break;
+            case 4:
+                power = 0.75f;
+                break;
+            case 5:
+                power = 1.5f;
+                break;
+            case 6:
+                power = 2.0f;
+                break;
+            case 7:
+                power = -0.5f;
+                break;
+        }
+        bw = bw * powf(realfreq / basefreq, power);
+        int ibw = (int)((bw / (synth->samplerate_f * 0.5f) * size)) + 1;
+
+        float amp = harmonics[nh - 1];
+        if(resonance->Penabled)
+            amp *= resonance->getfreqresponse(realfreq);
+
+        if(ibw > profilesize) { //if the bandwidth is larger than the profilesize
+            float rap   = sqrt((float)profilesize / (float)ibw);
+            int   cfreq =
+                (int) (realfreq
+                       / (synth->samplerate_f * 0.5f) * 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
+            float rap = sqrt((float)ibw / (float)profilesize);
+            float ibasefreq = realfreq / (synth->samplerate_f * 0.5f) * size;
+            for(int i = 0; i < profilesize; ++i) {
+                float idfreq = i / (float)profilesize - 0.5f;
+                idfreq *= ibw;
+                int   spfreq  = (int) (idfreq + ibasefreq);
+                float fspfreq = fmod((double)idfreq + ibasefreq, 1.0f);
+                if(spfreq <= 0)
+                    continue;
+                if(spfreq >= size - 1)
+                    break;
+                spectrum[spfreq] += amp * profile[i] * rap
+                                    * (1.0f - 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(float *spectrum,
+                                                    int size,
+                                                    float basefreq)
+{
+    for(int i = 0; i < size; ++i)
+        spectrum[i] = 0.0f;
+
+    float harmonics[synth->oscilsize / 2];
+    for(int i = 0; i < synth->oscilsize / 2; ++i)
+        harmonics[i] = 0.0f;
+    //get the harmonic structure from the oscillator (I am using the frequency amplitudes, only)
+    oscilgen->get(harmonics, basefreq, false);
 
-    for (int nh=1;nh<OSCIL_SIZE/2;nh++) {//for each harmonic
-        REALTYPE realfreq=getNhr(nh)*basefreq;
+    //normalize
+    float max = 0.0f;
+    for(int i = 0; i < synth->oscilsize / 2; ++i)
+        if(harmonics[i] > max)
+            max = harmonics[i];
+    if(max < 0.000001f)
+        max = 1;
+    for(int i = 0; i < synth->oscilsize / 2; ++i)
+        harmonics[i] /= max;
+
+    for(int nh = 1; nh < synth->oscilsize / 2; ++nh) { //for each harmonic
+        float 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 > synth->samplerate_f * 0.49999f)
+            break;
+        if(realfreq < 20.0f)
+            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;
-            };
-        };
-    };
-
-};
+        float amp = harmonics[nh - 1];
+        if(resonance->Penabled)
+            amp *= resonance->getfreqresponse(realfreq);
+        int cfreq = (int) (realfreq / (synth->samplerate_f * 0.5f) * 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;
+                float val1   = spectrum[old];
+                float val2   = spectrum[k];
+                float idelta = 1.0f / delta;
+                for(int i = 0; i < delta; ++i) {
+                    float x = idelta * i;
+                    spectrum[old + i] = val1 * (1.0f - 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;
-    REALTYPE spectrum[spectrumsize];
-    int profilesize=512;
-    REALTYPE profile[profilesize];
+    const int samplesize   = (((int) 1) << (Pquality.samplesize + 14));
+    int       spectrumsize = samplesize / 2;
+    float     spectrum[spectrumsize];
+    int       profilesize = 512;
+    float     profile[profilesize];
 
 
-    REALTYPE bwadjust=getprofile(profile,profilesize);
+    float 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;
+    float basefreq = 65.406f * powf(2.0f, Pquality.basenote / 2);
+    if(Pquality.basenote % 2 == 1)
+        basefreq *= 1.5f;
+
+    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);
+    fft_t      *fftfreqs = new fft_t[samplesize / 2];
+
+    float 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.0f) * (float)nsample / samplemax;
+    for(int nsample = 0; nsample < samplemax; ++nsample) {
+        float tmp = adj[nsample] - adj[samplemax - 1] * 0.5f;
+        float basefreqadjust = powf(2.0f, tmp);
+
+        if(Pmode == 0)
+            generatespectrum_bandwidthMode(spectrum,
+                                           spectrumsize,
+                                           basefreq * basefreqadjust,
+                                           profile,
+                                           profilesize,
+                                           bwadjust);
+        else
+            generatespectrum_otherModes(spectrum, spectrumsize,
+                                        basefreq * basefreqadjust);
+
+        const int extra_samples = 5; //the last samples contains the first samples (used for linear/cubic interpolation)
+        newsample.smp = new float[samplesize + extra_samples];
+
+        newsample.smp[0] = 0.0f;
+        for(int i = 1; i < spectrumsize; ++i) //randomize the phases
+            fftfreqs[i] = std::polar(spectrum[i], (float)RND * 6.29f);
+        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;
+        float rms = 0.0f;
+        for(int i = 0; i < samplesize; ++i)
+            rms += newsample.smp[i] * newsample.smp[i];
+        rms = sqrt(rms);
+        if(rms < 0.000001f)
+            rms = 1.0f;
+        rms *= sqrt(262144.0f / samplesize);
+        for(int i = 0; i < samplesize; ++i)
+            newsample.smp[i] *= 1.0f / rms * 50.0f;
 
         //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);
-    deleteFFTFREQS(&fftfreqs);
+            sample[nsample].smp      = newsample.smp;
+            sample[nsample].size     = samplesize;
+            sample[nsample].basefreq = basefreq * basefreqadjust;
+        }
+        newsample.smp = NULL;
+    }
+    delete (fft);
+    delete[] 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);
-    };
-};
-
-void PADnoteParameters::export2wav(string basefilename)
+    }
+    else
+        for(int i = samplemax; i < PAD_MAX_SAMPLES; ++i)
+            deletesample(i);
+    ;
+}
+
+void PADnoteParameters::export2wav(std::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";
-        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);
-            wav.write_mono_samples(nsmps, smps);
-            wav.close();
-        };
-    };
-};
-
-
+        snprintf(tmpstr, 20, "_%02d", k + 1);
+        std::string filename = basefilename + std::string(tmpstr) + ".wav";
+        WavFile     wav(filename, synth->samplerate, 1);
+        if(wav.good()) {
+            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.0f);
+            wav.writeMonoSamples(nsmps, smps);
+        }
+    }
+}
 
 void PADnoteParameters::add2XML(XMLwrapper *xml)
 {
-    xml->information.PADsynth_used=true;
+    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 +717,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 +750,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 +766,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 +781,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 +860,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 +877,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 +898,5 @@ void PADnoteParameters::getfromXML(XMLwrapper *xml)
         FilterLfo->getfromXML(xml);
         xml->exitbranch();
         xml->exitbranch();
-    };
-};
-
-
+    }
+}
diff --git a/src/Params/PADnoteParameters.h b/src/Params/PADnoteParameters.h
index eacd676..b328321 100644
--- a/src/Params/PADnoteParameters.h
+++ b/src/Params/PADnoteParameters.h
@@ -35,134 +35,143 @@
 #include "FilterParams.h"
 #include "Presets.h"
 #include <string>
+#include <pthread.h>
 
 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.0f-1.0f that represents the estimation perceived bandwidth
+        float getprofile(float *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
-
-    struct {//where are positioned the harmonics (on integer multimplier or different places)
-        unsigned char type;
-        unsigned char par1,par2,par3;//0..255
-    }Phrpos;
+            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
+        float setPbandwidth(int Pbandwidth); //returns the BandWidth in cents
+        float 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;
+            float  basefreq;
+            float *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(float *spectrum,
+                                            int size,
+                                            float basefreq,
+                                            float *profile,
+                                            int profilesize,
+                                            float bwadjust);
+        void generatespectrum_otherModes(float *spectrum,
+                                         int size,
+                                         float basefreq);
+        void deletesamples();
+        void deletesample(int n);
 
-    FFTwrapper *fft;
-    pthread_mutex_t *mutex;
+        FFTwrapper *fft;
+        pthread_mutex_t *mutex;
 };
 
 
diff --git a/src/Params/Presets.cpp b/src/Params/Presets.cpp
index 40c78c2..d96fc53 100644
--- a/src/Params/Presets.cpp
+++ b/src/Params/Presets.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  Presets.C - Presets and Clipboard management
+  Presets.cpp - Presets and Clipboard management
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -26,113 +26,94 @@
 
 Presets::Presets()
 {
-    type[0]=0;
-    nelement=-1;
-};
+    type[0] = 0;
+}
 
 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);
+    //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);
+    add2XML(xml);
     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);
+}
 
 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);
-            return;
-        };
-        if (!presetsstore.pasteclipboard(xml)) {
-            delete(xml);
-            nelement=-1;
+    strcpy(type, this->type);
+    //strcat(type, "n");
+
+    if(npreset == 0)
+        if(strstr(type, "Plfo") != NULL)
+            strcpy(type, "Plfo");
+
+    XMLwrapper *xml = new XMLwrapper();
+    if(npreset == 0) {
+        if(!checkclipboardtype()) {
+            delete (xml);
             return;
-        };
-    } else {
-        if (!presetsstore.pastepreset(xml,npreset)) {
-            delete(xml);
-            nelement=-1;
+        }
+        if(!presetsstore.pasteclipboard(xml)) {
+            delete (xml);
             return;
-        };
-    };
+        }
+    }
+    else
+    if(!presetsstore.pastepreset(xml, npreset)) {
+        delete (xml);
+        return;
+    }
 
-    if (xml->enterbranch(type)==0) {
-        nelement=-1;
+    if(xml->enterbranch(type) == 0)
         return;
-    };
-    if (nelement==-1) {
-        defaults();
-        getfromXML(xml);
-    } else {
-        defaults(nelement);
-        getfromXMLsection(xml,nelement);
-    };
-    xml->exitbranch();
 
-    delete(xml);
-    nelement=-1;
-};
+    defaults();
+    getfromXML(xml);
 
-bool Presets::checkclipboardtype()
-{
-    char type[MAX_PRESETTYPE_SIZE];
-    strcpy(type,this->type);
-    if (nelement!=-1) strcat(type,"n");
+    xml->exitbranch();
 
-    return(presetsstore.checkclipboardtype(type));
-};
+    delete (xml);
+}
 
-void Presets::setelement(int n)
+bool Presets::checkclipboardtype()
 {
-    nelement=n;
-};
+    return presetsstore.checkclipboardtype(type);
+}
 
 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
index 4f4bf78..a64d25e 100644
--- a/src/Params/Presets.h
+++ b/src/Params/Presets.h
@@ -30,31 +30,27 @@
 /**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;
+    friend class PresetsArray;
+    public:
+        Presets();
+        virtual ~Presets();
+
+        virtual void copy(const char *name); /**<if name==NULL, the clipboard is used*/
+        virtual void paste(int npreset); //npreset==0 for clipboard
+        virtual 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;
 };
 
 #endif
-
diff --git a/src/Params/PresetsArray.cpp b/src/Params/PresetsArray.cpp
new file mode 100644
index 0000000..420b681
--- /dev/null
+++ b/src/Params/PresetsArray.cpp
@@ -0,0 +1,136 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  PresetsArray.cpp - PresetsArray and Clipboard management
+  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 "PresetsArray.h"
+#include <string.h>
+
+
+PresetsArray::PresetsArray()
+{
+    type[0]  = 0;
+    nelement = -1;
+}
+
+PresetsArray::~PresetsArray()
+{}
+
+void PresetsArray::setpresettype(const char *type)
+{
+    strcpy(this->type, type);
+}
+
+void PresetsArray::copy(const char *name)
+{
+    XMLwrapper *xml = new XMLwrapper();
+
+    //used only for the clipboard
+    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");
+    ;
+
+    xml->beginbranch(type);
+    if(nelement == -1)
+        add2XML(xml);
+    else
+        add2XMLsection(xml, nelement);
+    xml->endbranch();
+
+    if(name == NULL)
+        presetsstore.copyclipboard(xml, type);
+    else
+        presetsstore.copypreset(xml, type, name);
+
+    delete (xml);
+    nelement = -1;
+}
+
+void PresetsArray::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);
+            return;
+        }
+        if(!presetsstore.pasteclipboard(xml)) {
+            delete (xml);
+            nelement = -1;
+            return;
+        }
+    }
+    else
+    if(!presetsstore.pastepreset(xml, npreset)) {
+        delete (xml);
+        nelement = -1;
+        return;
+    }
+
+    if(xml->enterbranch(type) == 0) {
+        nelement = -1;
+        return;
+    }
+    if(nelement == -1) {
+        defaults();
+        getfromXML(xml);
+    }
+    else {
+        defaults(nelement);
+        getfromXMLsection(xml, nelement);
+    }
+    xml->exitbranch();
+
+    delete (xml);
+    nelement = -1;
+}
+
+bool PresetsArray::checkclipboardtype()
+{
+    char type[MAX_PRESETTYPE_SIZE];
+    strcpy(type, this->type);
+    if(nelement != -1)
+        strcat(type, "n");
+
+    return presetsstore.checkclipboardtype(type);
+}
+
+void PresetsArray::setelement(int n)
+{
+    nelement = n;
+}
diff --git a/src/Params/PresetsArray.h b/src/Params/PresetsArray.h
new file mode 100644
index 0000000..1b17e40
--- /dev/null
+++ b/src/Params/PresetsArray.h
@@ -0,0 +1,59 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  PresetsArray.h - PresetsArray and Clipboard management
+  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 PRESETSARRAY_H
+#define PRESETSARRAY_H
+
+#include "../Misc/XMLwrapper.h"
+
+#include "Presets.h"
+
+/**PresetsArray and Clipboard management*/
+class PresetsArray:public Presets
+{
+    public:
+        PresetsArray();
+        virtual ~PresetsArray();
+
+        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)    = 0;
+        virtual void getfromXMLsection(XMLwrapper *xml, int n) = 0;
+        virtual void defaults(int n) = 0;
+        int nelement;
+};
+
+#endif
diff --git a/src/Params/PresetsStore.cpp b/src/Params/PresetsStore.cpp
index b5c77d1..b37c123 100644
--- a/src/Params/PresetsStore.cpp
+++ b/src/Params/PresetsStore.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  PresetsStore.C - Presets and Clipboard store
+  PresetsStore.cpp - Presets and Clipboard store
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -19,6 +19,9 @@
   Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 
 */
+#include <iostream>
+#include <algorithm>
+#include <cctype>
 #include <stdlib.h>
 #include <string.h>
 #include <dirent.h>
@@ -27,169 +30,155 @@
 #include "PresetsStore.h"
 #include "../Misc/Util.h"
 
+using namespace std;
+
 PresetsStore presetsstore;
 
 PresetsStore::PresetsStore()
 {
-    clipboard.data=NULL;
-    clipboard.type[0]=0;
-
-    for (int i=0;i<MAX_PRESETS;i++) {
-        presets[i].file=NULL;
-        presets[i].name=NULL;
-    };
-
-};
+    clipboard.data    = NULL;
+    clipboard.type[0] = 0;
+}
 
 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);
-};
-
-bool PresetsStore::checkclipboardtype(char *type)
+    if(clipboard.data != NULL)
+        xml->putXMLdata(clipboard.data);
+    else
+        return false;
+    return true;
+}
+
+bool PresetsStore::checkclipboardtype(const 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;
-        };
-    };
-
-};
+    presets.clear();
+}
 
 //a helper function that compares 2 presets[]
-int Presets_compar(const void *a,const void *b)
+bool PresetsStore::presetstruct::operator<(const presetstruct &b) const
 {
-    struct PresetsStore::presetstruct *p1= (PresetsStore::presetstruct *)a;
-    struct PresetsStore::presetstruct *p2= (PresetsStore::presetstruct *)b;
-    if (((p1->name)==NULL)||((p2->name)==NULL)) return(0);
+    return name < b.name;
+}
 
-    return(strcasecmp(p1->name,p2->name)<0);
-};
 
-
-void PresetsStore::rescanforpresets(char *type)
+void PresetsStore::rescanforpresets(const string &type)
 {
+    //std::cout << "Scanning For Presets" << std::endl;
+    //std::cout << "Of Type: " << type << std::endl;
+
     clearpresets();
-    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;
+    string ftype = "." + type + ".xpz";
+
+    for(int i = 0; i < MAX_BANK_ROOT_DIRS; ++i) {
+        if(config.cfg.presetsDirList[i].empty())
+            continue;
+
+        //open directory
+        string dirname = config.cfg.presetsDirList[i];
+        DIR   *dir     = opendir(dirname.c_str());
+        if(dir == NULL)
+            continue;
         struct dirent *fn;
-        while ((fn=readdir(dir))) {
-            const char *filename=fn->d_name;
-            if (strstr(filename,ftype)==NULL) continue;
 
+        //check all files in directory
+        while((fn = readdir(dir))) {
+            string filename = fn->d_name;
+            if(filename.find(ftype) == string::npos)
+                continue;
 
-            presets[presetk].file=new char [MAX_STRING_SIZE];
-            presets[presetk].name=new char [MAX_STRING_SIZE];
-            char tmpc=dirname[strlen(dirname)-1];
+            //ensure proper path is formed
+            char tmpc = dirname[dirname.size() - 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);
+            if((tmpc == '/') || (tmpc == '\\'))
+                tmps = "";
+            else
+                tmps = "/";
+
+            string location = "" + dirname + tmps + filename;
 
-            char *tmp=strstr(presets[presetk].name,ftype);
-            if (tmp!=NULL) tmp[0]='\0';
-            presetk++;
-            if (presetk>=MAX_PRESETS) return;
-        };
+            //trim file type off of name
+            string name = filename.substr(0, filename.find(ftype));
+
+            //put on list
+            presets.push_back(presetstruct(location, name));
+        }
 
         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)
-{
-    char filename[MAX_STRING_SIZE],tmpfilename[MAX_STRING_SIZE];
+    sort(presets.begin(), presets.end());
+}
 
-    if (config.cfg.presetsDirList[0]==NULL) return;
 
-    snprintf(tmpfilename,MAX_STRING_SIZE,"%s",name);
+void PresetsStore::copypreset(XMLwrapper *xml, char *type, string name)
+{
+    if(config.cfg.presetsDirList[0].empty())
+        return;
 
     //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];
+    name = legalizeFilename(name);
+
+    //make path legal
+    const string dirname = config.cfg.presetsDirList[0];
+    char tmpc = dirname[dirname.size() - 1];
     const char *tmps;
-    if ((tmpc=='/')||(tmpc=='\\')) tmps="";
-    else tmps="/";
+    if((tmpc == '/') || (tmpc == '\\'))
+        tmps = "";
+    else
+        tmps = "/";
 
-    snprintf(filename,MAX_STRING_SIZE,"%s%s%s.%s.xpz",dirname,tmps,name,type);
+    string filename("" + dirname + tmps + name + type);
 
     xml->saveXMLfile(filename);
-};
+}
 
-bool PresetsStore::pastepreset(XMLwrapper *xml, int npreset)
+bool PresetsStore::pastepreset(XMLwrapper *xml, unsigned 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);
-};
-
-void PresetsStore::deletepreset(int npreset)
+    if(npreset >= presets.size())
+        return false;
+    string filename = presets[npreset].file;
+    if(filename.empty())
+        return false;
+    bool result = (xml->loadXMLfile(filename) >= 0);
+    return result;
+}
+
+void PresetsStore::deletepreset(unsigned int npreset)
 {
     npreset--;
-    if (npreset>=MAX_PRESETS) return;
-    char *filename=presets[npreset].file;
-    if (filename==NULL) return;
-    remove(filename);
-};
-
+    if(npreset >= presets.size())
+        return;
+    string filename = presets[npreset].file;
+    if(filename.empty())
+        return;
+    remove(filename.c_str());
+}
diff --git a/src/Params/PresetsStore.h b/src/Params/PresetsStore.h
index 8ff602b..355ed52 100644
--- a/src/Params/PresetsStore.h
+++ b/src/Params/PresetsStore.h
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  PresetsStore.C - Presets and Clipboard store
+  PresetsStore.cpp - Presets and Clipboard store
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -20,45 +20,47 @@
 
 */
 
+#include <string>
+#include <vector>
 #include "../Misc/XMLwrapper.h"
 #include "../Misc/Config.h"
 
 #define MAX_PRESETTYPE_SIZE 30
-#define MAX_PRESETS 1000
 
 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(const char *type);
+
+        //presets stuff
+        void copypreset(XMLwrapper *xml, char *type, std::string name);
+        bool pastepreset(XMLwrapper *xml, unsigned int npreset);
+        void deletepreset(unsigned int npreset);
+
+        struct presetstruct {
+            presetstruct(std::string _file, std::string _name)
+                :file(_file), name(_name) {}
+            bool operator<(const presetstruct &b) const;
+            std::string file;
+            std::string name;
+        };
+        std::vector<presetstruct> presets;
+
+        void rescanforpresets(const std::string &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
index 963af09..f4e6db9 100644
--- a/src/Params/SUBnoteParameters.cpp
+++ b/src/Params/SUBnoteParameters.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  SUBnoteParameters.C - Parameters for SUBnote (SUBsynth)
+  SUBnoteParameters.cpp - Parameters for SUBnote (SUBsynth)
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -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,162 @@ 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
index a0ebd8f..111841e 100644
--- a/src/Params/SUBnoteParameters.h
+++ b/src/Params/SUBnoteParameters.h
@@ -31,76 +31,73 @@
 
 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.0f)
+        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
deleted file mode 100644
index 56edbae..0000000
--- a/src/Samples/AuSample.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  AuSample.h - Object for storing information on audio samples (for one channel)
-  Copyright (C) 2009-2009 Mark McCurry
-  Author: Mark McCurry
-
-  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 "AuSample.h"
-
-AuSample::AuSample(const int &length)
-        : Sample(length) {}
-
-AuSample::AuSample(float *input,const int &length)
-        : Sample(input,length) {}
-
diff --git a/src/Samples/AuSample.h b/src/Samples/AuSample.h
deleted file mode 100644
index 99fae77..0000000
--- a/src/Samples/AuSample.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  AuSample.h - Object for storing information on audio samples (for one channel)
-  Copyright (C) 2009-2009 Mark McCurry
-  Author: Mark McCurry
-
-  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 AUSAMPLE_H
-#define AUSAMPLE_H
-
-#include "Sample.h"
-#include "FqSample.h"
-
-class AuSample : public Sample
-{
-public:
-    AuSample(const int &length);
-    AuSample(float *input,const int &length);
-    FqSample getFqSample();/**\todo implement this*/
-
-};
-#endif
-
diff --git a/src/Samples/FqSample.cpp b/src/Samples/FqSample.cpp
deleted file mode 100644
index 6f800bf..0000000
--- a/src/Samples/FqSample.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  FqSample.C - Object for storing information on samples
-  Copyright (C) 2009-2009 Mark McCurry
-  Author: Mark McCurry
-
-  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 "FqSample.h"
-
-FqSample::FqSample(const int &length)
-        :Sample(length)
-{}
-
-FqSample::FqSample(float *input,const int &length)
-        : Sample(input,length)
-{}
-
-FqSample::~FqSample()
-{}
-
diff --git a/src/Samples/FqSample.h b/src/Samples/FqSample.h
deleted file mode 100644
index 14a2123..0000000
--- a/src/Samples/FqSample.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  FqSample.h - Object for storing information on samples
-  Copyright (C) 2009-2009 Mark McCurry
-  Author: Mark McCurry
-
-  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 MONOSAMPLE_H
-#define MONOSAMPLE_H
-
-#include "FqSample.h"
-#include "Sample.h"
-
-class FqSample : public Sample
-{
-public:
-    FqSample(const int &length);
-    FqSample(float *input,const int &length);
-    ~FqSample();
-    //FqSample &operator=(const FqSample &smp);
-    //float *dontuse(){return buffer;};
-};
-#endif
-
diff --git a/src/Samples/Makefile b/src/Samples/Makefile
deleted file mode 100644
index 5b49bcb..0000000
--- a/src/Samples/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-include ../Makefile.inc
-
-objects=Sample.o AuSample.o FqSample.o
-
-
-all: $(objects)
-
--include ../Make.deps
-
-.PHONY : clean
-clean: 
-	rm -f $(objects)
-	rm -f makeinclude.deps
-
diff --git a/src/Samples/Sample.cpp b/src/Samples/Sample.cpp
deleted file mode 100644
index be9c7be..0000000
--- a/src/Samples/Sample.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  Sample.C - Object for storing information on samples
-  Copyright (C) 2009-2009 Mark McCurry
-  Author: Mark McCurry
-
-  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 "Sample.h"
-
-Sample::Sample(const Sample &smp)
-        : bufferSize(smp.bufferSize)
-{
-    buffer=new float[bufferSize];
-    for (int i=0;i<bufferSize;++i)
-        *(i+buffer)=*(i+smp.buffer);
-}
-
-Sample::Sample(const int &length)
-        : bufferSize(length)
-{
-    if (length<1)
-        bufferSize=1;
-    buffer=new float[bufferSize];
-    clear();
-}
-
-Sample::Sample(float *input,const int &length)
-        : bufferSize(length)
-{
-    if (length>0) {
-        buffer=new float[length];
-        for (int i=0;i<length;++i)
-            *(buffer+i)=*(input+i);
-    } else {
-        buffer=new float[1];
-        bufferSize=1;
-        *buffer=0;
-    }
-}
-
-Sample::~Sample()
-{
-    delete[] buffer;
-}
-
-void Sample::clear()
-{
-    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 {
-        delete[] buffer;
-        buffer=new float[smp.bufferSize];
-        bufferSize=smp.bufferSize;
-        for (int i=0;i<bufferSize;++i)
-            *(i+buffer)=*(i+smp.buffer);
-    }
-}
-
diff --git a/src/Samples/Sample.h b/src/Samples/Sample.h
deleted file mode 100644
index 51f41b1..0000000
--- a/src/Samples/Sample.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  Sample.h - Object for storing information on samples
-  Copyright (C) 2009-2009 Mark McCurry
-  Author: Mark McCurry
-
-  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 SAMPLE_H
-#define SAMPLE_H
-
-/**
- * Base Class for Samples
- */
-class Sample
-{
-public:
-    Sample(const Sample &smp);
-    Sample(const int &length);
-    Sample(float *input,const int &length);
-    ~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*/
-    float &operator[](int index) {
-        return *(buffer+index%bufferSize);
-    };
-    /**Provides the indexing operator for const Samples*/
-    const float &operator[](int index)const {
-        return *(buffer+index%bufferSize);
-    };
-    /**Provides the assignment operator*/
-    void operator=(const Sample &smp);
-    /**Provides direct access to the buffer to allow for transition
-     *
-     * This method should be removed to ensure encapsulation once
-     * it is integrated into the code*/
-    float *dontuse() {
-        return buffer;
-    };
-private:
-    int bufferSize;
-    float *buffer;
-
-
-};
-#endif
-
diff --git a/src/Seq/MIDIEvents.cpp b/src/Seq/MIDIEvents.cpp
deleted file mode 100644
index 42618c1..0000000
--- a/src/Seq/MIDIEvents.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  MIDIEvents.C - It stores the midi events from midi file or sequencer
-  Copyright (C) 2003-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 "MIDIEvents.h"
-#include <stdlib.h>
-#include <stdio.h>
-
-MIDIEvents::MIDIEvents()
-{
-};
-
-MIDIEvents::~MIDIEvents()
-{
-};
-
-
-/************** Track stuff ***************/
-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;
-//    printf("Wx%x ",(int) l->current);
-//    printf("-> %d  \n",l->current->ev.deltatime);
-    l->size++;
-};
-
-void MIDIEvents::readevent(list *l,event *ev)
-{
-    if (l->current==NULL) {
-        ev->type=-1;
-        return;
-    };
-    *ev=l->current->ev;
-    l->current=l->current->next;
-
-    //test
-    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;
-};
-
-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);
-    };
-    deletelistreference(l);
-};
-
-void MIDIEvents::deletelistreference(list *l)
-{
-    l->current=l->first=NULL;
-    l->size=0;
-    l->length=0.0;
-};
diff --git a/src/Seq/MIDIEvents.h b/src/Seq/MIDIEvents.h
deleted file mode 100644
index 5b3b6f1..0000000
--- a/src/Seq/MIDIEvents.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  MIDIEvents.h - It stores the midi events from midi file or sequencer
-  Copyright (C) 2003-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 MIDI_EVENTS_H
-#define MIDI_EVENTS_H
-
-#include "../globals.h"
-#define NUM_MIDI_TRACKS NUM_MIDI_CHANNELS
-
-/**storage the midi events from midi file or sequencer
- * \todo this looks quite like a remake of a linked list
- *       if it is, then it should be rewritten to use <list>*/
-class MIDIEvents
-{
-    friend class MIDIFile;
-public:
-    MIDIEvents();
-    ~MIDIEvents();
-
-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];
-
-    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
deleted file mode 100644
index 61e748d..0000000
--- a/src/Seq/MIDIFile.cpp
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  MIDIFile.C - MIDI file loader
-  Copyright (C) 2003-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 <stdio.h>
-#include <string.h>
-#include "MIDIFile.h"
-
-
-MIDIFile::MIDIFile()
-{
-    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);
-
-    char header[4];
-    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')) {
-        fclose(file);
-        return(-1);
-    };
-
-    //get the filesize
-    fseek(file,0,SEEK_END);
-    midifilesize=ftell(file);
-    rewind(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);
-};
-
-int MIDIFile::parsemidifile(MIDIEvents *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 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 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.");
-    };
-
-    if (ntracks>=NUM_MIDI_TRACKS) ntracks=NUM_MIDI_TRACKS-1;
-
-    for (int n=0;n<ntracks;n++) {
-        if (parsetrack(n)<0) {
-            clearmidifile();
-            return(-1);
-        };
-    };
-
-    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);
-};
-
-//private members
-
-
-int MIDIFile::parsetrack(int ntrack)
-{
-    printf("\n--==*Reading track %d **==--\n",ntrack);
-
-    int chunk=getint32();//MTrk
-    if (chunk!=0x4d54726b) return(-1);
-
-    int size=getint32();
-    printf("size = %d\n",size);
-
-    int oldmidifilek=midifilek;
-
-    unsigned char lastmsg=0;
-    unsigned int dt=0;
-
-    while (!midieof) {
-        unsigned int msgdeltatime=getvarint32();
-
-///	printf("MSGDELTATIME = %d\n",msgdeltatime);
-
-//	dt+=msgdeltatime;
-
-        int msg=peekbyte();
-///	printf("raw msg=0x%x     ",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;
-
-        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;
-            break;
-        case 0xa0 ... 0xaf://aftertouch - ignored
-            skipnbytes(2);
-            break;
-        case 0xb0 ... 0xbf://control change
-            parsecontrolchange(ntrack,msg & 0x0f,dt);
-            dt=0;
-            break;
-        case 0xc0 ... 0xcf://program change - ignored
-            skipnbytes(1);
-            break;
-        case 0xd0 ... 0xdf://channel pressure - ignored
-            skipnbytes(1);
-            break;
-        case 0xe0 ... 0xef://channel mode messages
-            skipnbytes(2);
-            break;
-        case 0xf0://sysex - ignored
-            while (getbyte()!=0xf7) {
-                if (midieof) break;
-            };
-            break;
-        case 0xf7://sysex (another type) - ignored
-            skipnbytes(getvarint32());
-            break;
-
-        case 0xff://meta-event
-            mtype=getbyte();
-            mlength=getbyte();
-            parsemetaevent(mtype,mlength);
-            break;
-
-        default:
-            getbyte();
-            printf("UNKNOWN message! 0x%x\n",msg);
-            return(-1);
-            break;
-        };
-
-
-
-        if (midieof) 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);
-};
-
-
-void MIDIFile::parsenoteoff(char ntrack,char chan,unsigned int dt)
-{
-    unsigned char note;
-    note=getbyte();
-
-    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;
-
-    printf("Note off:%d \n",note);
-
-    ///test
-//    ntrack=0;
-
-    me->writeevent(&me->miditrack[(int)ntrack].record,&me->tmpevent);
-
-};
-
-
-void MIDIFile::parsenoteon(char ntrack,char chan,unsigned int dt)
-{
-    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);
-
-
-
-};
-
-void MIDIFile::parsecontrolchange(char ntrack,char chan,unsigned int dt)
-{
-    unsigned char control,value;
-    control=getbyte();
-    value=getbyte();
-
-    if (chan>=NUM_MIDI_CHANNELS) return;
-
-    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);
-
-};
-
-void MIDIFile::parsepitchwheel(char ntrack,char chan, unsigned int dt)
-{
-    unsigned char valhi,vallo;
-    vallo=getbyte();
-    valhi=getbyte();
-
-    if (chan>=NUM_MIDI_CHANNELS) return;
-
-    int value=(int)valhi*128+vallo;
-
-    printf("[dt %d] Pitch wheel:%d\n",dt,value);
-
-};
-
-void MIDIFile::parsemetaevent(unsigned char mtype,unsigned char mlength)
-{
-    int oldmidifilek=midifilek;
-    printf("meta-event type=0x%x  length=%d\n",mtype,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);
-};
-
-
-unsigned int MIDIFile::convertdt(unsigned int dt)
-{
-    double result=dt;
-    printf("DT=%d\n",dt);
-
-    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;
-};
-
-unsigned char MIDIFile::getbyte()
-{
-    if (midifilek>=midifilesize) {
-        midieof=true;
-        return(0);
-    };
-
-///    printf("(%d) ",midifile[midifilek]);
-    return(midifile[midifilek++]);
-};
-
-unsigned char MIDIFile::peekbyte()
-{
-    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 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 int MIDIFile::getvarint32()
-{
-    unsigned long result=0;
-    unsigned char b;
-
-///    printf("\n[start]");
-
-    if ((result = getbyte()) & 0x80) {
-        result &= 0x7f;
-        do  {
-            b=getbyte();
-            result = (result << 7) + (b & 0x7f);
-        } 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;
-    };
-};
-
diff --git a/src/Seq/MIDIFile.h b/src/Seq/MIDIFile.h
deleted file mode 100644
index 7f83158..0000000
--- a/src/Seq/MIDIFile.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  MIDIFile.h - MIDI file loader
-  Copyright (C) 2003-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 MIDIFILE_H
-#define MIDIFILE_H
-
-#include "../globals.h"
-#include "MIDIEvents.h"
-
-/**MIDI file loader*/
-class 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);
-
-    //returns -1 if there is an error, otherwise 0
-    int parsemidifile(MIDIEvents *me_);
-
-private:
-    MIDIEvents *me;
-
-    unsigned char *midifile;
-    int midifilesize,midifilek;
-    bool midieof;
-
-    //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 add_dt(char ntrack, unsigned int dt);
-
-    void clearmidifile();
-
-    //convert the delta-time to internal format
-    unsigned int convertdt(unsigned int dt);
-
-    /* Low Level MIDIfile functions */
-
-    //get a byte from the midifile
-    unsigned char getbyte();
-
-    //peek the current byte from the midifile
-    unsigned char peekbyte();
-
-    //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();
-
-    //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;
-
-};
-
-#endif
-
diff --git a/src/Seq/Makefile b/src/Seq/Makefile
deleted file mode 100644
index e4742c9..0000000
--- a/src/Seq/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-include ../Makefile.inc
-
-objects=MIDIEvents.o MIDIFile.o Sequencer.o
-
-
-all: $(objects)
-
--include ../Make.deps
-
-.PHONY : clean
-clean: 
-	rm -f $(objects)
-	rm -f makeinclude.deps
-
diff --git a/src/Seq/Sequencer.cpp b/src/Seq/Sequencer.cpp
deleted file mode 100644
index d0a32f1..0000000
--- a/src/Seq/Sequencer.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  Sequencer.C - The Sequencer
-  Copyright (C) 2003-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 <math.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <sys/time.h>
-#include <time.h>
-
-#include "Sequencer.h"
-
-
-
-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;
-        resettime(&playtime[i]);
-    };
-
-    setplayspeed(0);
-};
-
-Sequencer::~Sequencer()
-{
-    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);
-
-    for (int i=0;i<NUM_MIDI_TRACKS;i++) {
-        deletelist(&miditrack[i].record);
-    };
-    if (midifile.parsemidifile(this)<0) return(-1);
-
-    //copy the "record" track to the main track
-    for (int i=0;i<NUM_MIDI_TRACKS;i++) {
-        deletelist(&miditrack[i].track);
-        miditrack[i].track=miditrack[i].record;
-        deletelistreference(&miditrack[i].record);
-    };
-    return(0);
-};
-
-
-
-void Sequencer::startplay()
-{
-    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++) {
-        rewindlist(&miditrack[i].track);
-    };
-    play=1;
-
-};
-void Sequencer::stopplay()
-{
-    if (play==0) return;
-    play=0;
-};
-
-// ************ Player stuff ***************
-
-int Sequencer::getevent(char ntrack,int *midich, int *type,int *par1, int *par2)
-{
-    *type=0;
-    if (play==0) return(-1);
-
-    //test
-//    if (ntrack!=0) return(-1);
-
-    updatecounter(&playtime[(int)ntrack]);
-
-//    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);
-//    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);
-
-    *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;
-
-//    printf("%f   -  %d %d \n",nextevent[ntrack].time,par1,par2);
-    return(0);//?? sau 1
-};
-
-/************** Timer stuff ***************/
-
-void Sequencer::resettime(timestruct *t)
-{
-    t->abs=0.0;
-    t->rel=0.0;
-
-    timeval tval;
-
-    t->last=0.0;
-#ifndef OS_WINDOWS
-    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;
-#ifndef OS_WINDOWS
-    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;
-
-//    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);
-};
-
diff --git a/src/Seq/Sequencer.h b/src/Seq/Sequencer.h
deleted file mode 100644
index 7798c99..0000000
--- a/src/Seq/Sequencer.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  Sequencer.h - The Sequencer
-  Copyright (C) 2003-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 SEQUENCER_H
-#define SEQUENCER_H
-
-#include "../globals.h"
-#include "MIDIEvents.h"
-#include "MIDIFile.h"
-
-/**The Sequencer
- * \todo restructure some of this code*/
-class Sequencer:public MIDIEvents
-{
-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);
-
-    /**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);
-
-    void startplay();
-    void stopplay();
-
-
-    int play;
-    int playspeed;//viteza de rulare (0.1x-10x), 0=1.0x, 128=10x
-    void setplayspeed(int speed);
-
-private:
-
-    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];
-
-    void resettime(timestruct *t);
-    void updatecounter(timestruct *t);//this updates the timer values
-
-    /* Player only*/
-
-    struct {
-        event ev;
-        double time;
-    } nextevent[NUM_MIDI_TRACKS];
-
-    double realplayspeed;
-
-};
-
-#endif
-
diff --git a/src/Synth/ADnote.cpp b/src/Synth/ADnote.cpp
index d6a0b7b..2bd2454 100644
--- a/src/Synth/ADnote.cpp
+++ b/src/Synth/ADnote.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  ADnote.C - The "additive" synthesizer
+  ADnote.cpp - The "additive" synthesizer
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -19,405 +19,634 @@
   Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */
 
-#include <math.h>
-#include <stdlib.h>
-#include <stdio.h>
-
+#include <cmath>
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
 
 #include "../globals.h"
 #include "../Misc/Util.h"
+#include "../DSP/Filter.h"
+#include "OscilGen.h"
 #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_,
+               float freq,
+               float velocity,
+               int portamento_,
+               int midinote_,
+               bool besilent)
+    :SynthNote(freq, velocity, portamento_, midinote, besilent)
 {
-    ready=0;
-
-    tmpwave=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;
-
-        if (pars->VoicePar[nvoice].Enabled==0) {
-            NoteVoicePar[nvoice].Enabled=OFF;
+    tmpwavel = new float [synth->buffersize];
+    tmpwaver = new float [synth->buffersize];
+    bypassl  = new float [synth->buffersize];
+    bypassr  = new float [synth->buffersize];
+
+    partparams = pars;
+    ctl = ctl_;
+    portamento  = portamento_;
+    midinote    = midinote_;
+    NoteEnabled = ON;
+    basefreq    = freq;
+    if(velocity > 1.0f)
+        velocity = 1.0f;
+    this->velocity = velocity;
+    time   = 0.0f;
+    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.0f;
+
+
+    NoteGlobalPar.FilterCenterPitch = pars->GlobalPar.GlobalFilter->getfreq() //center freq
+                                      + pars->GlobalPar.PFilterVelocityScale
+                                      / 127.0f * 6.0f                                  //velocity sensing
+                                      * (VelF(velocity,
+                                              pars->GlobalPar.
+                                              PFilterVelocityScaleFunction) - 1);
+
+    if(pars->GlobalPar.PPunchStrength != 0) {
+        NoteGlobalPar.Punch.Enabled = 1;
+        NoteGlobalPar.Punch.t = 1.0f; //start from 1.0f and to 0.0f
+        NoteGlobalPar.Punch.initialvalue =
+            ((powf(10, 1.5f * pars->GlobalPar.PPunchStrength / 127.0f) - 1.0f)
+             * VelF(velocity,
+                    pars->GlobalPar.PPunchVelocitySensing));
+        float time =
+            powf(10, 3.0f * pars->GlobalPar.PPunchTime / 127.0f) / 10000.0f;   //0.1f .. 100 ms
+        float stretch = powf(440.0f / freq,
+                             pars->GlobalPar.PPunchStretch / 64.0f);
+        NoteGlobalPar.Punch.dt = 1.0f / (time * synth->samplerate_f * stretch);
+    }
+    else
+        NoteGlobalPar.Punch.Enabled = 0;
+
+    for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice) {
+        pars->VoicePar[nvoice].OscilSmp->newrandseed(prng());
+        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.0f;
+        int unison = pars->VoicePar[nvoice].Unison_size;
+        if(unison < 1)
+            unison = 1;
+
+        //compute unison
+        unison_size[nvoice] = unison;
+
+        unison_base_freq_rap[nvoice] = new float[unison];
+        unison_freq_rap[nvoice]      = new float[unison];
+        unison_invert_phase[nvoice]  = new bool[unison];
+        float unison_spread = pars->getUnisonFrequencySpreadCents(
+            nvoice);
+        float unison_real_spread = powf(2.0f, (unison_spread * 0.5f) / 1200.0f);
+        float unison_vibratto_a  = pars->VoicePar[nvoice].Unison_vibratto
+                                   / 127.0f;                                     //0.0f .. 1.0f
+
+
+        switch(unison) {
+            case 1:
+                unison_base_freq_rap[nvoice][0] = 1.0f; //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.0f / unison_real_spread;
+                unison_base_freq_rap[nvoice][1] = unison_real_spread;
+            };
+                break;
+            default: { //unison for more than 2 subvoices
+                float unison_values[unison];
+                float min = -1e-6, max = 1e-6;
+                for(int k = 0; k < unison; ++k) {
+                    float step = (k / (float) (unison - 1)) * 2.0f - 1.0f; //this makes the unison spread more uniform
+                    float val  = step + (RND * 2.0f - 1.0f) / (unison - 1);
+                    unison_values[k] = limit(val, min, max);
+                }
+                float diff = max - min;
+                for(int k = 0; k < unison; ++k) {
+                    unison_values[k] =
+                        (unison_values[k] - (max + min) * 0.5f) / diff;             //the lowest value will be -1 and the highest will be 1
+                    unison_base_freq_rap[nvoice][k] =
+                        powf(2.0f, (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.0f
+                                                  + (unison_base_freq_rap[
+                                                         nvoice][k] - 1.0f)
+                                                  * (1.0f - unison_vibratto_a);
+        unison_vibratto[nvoice].step      = new float[unison];
+        unison_vibratto[nvoice].position  = new float[unison];
+        unison_vibratto[nvoice].amplitude =
+            (unison_real_spread - 1.0f) * unison_vibratto_a;
+
+        float increments_per_second = synth->samplerate_f / synth->buffersize_f;
+        float vibratto_base_period  = 0.25f
+                                      * powf(
+            2.0f,
+            (1.0f
+             - pars->VoicePar[nvoice].
+             Unison_vibratto_speed
+             / 127.0f) * 4.0f);
+        for(int k = 0; k < unison; ++k) {
+            unison_vibratto[nvoice].position[k] = RND * 1.8f - 0.9f;
+            //make period to vary randomly from 50% to 200% vibratto base period
+            float vibratto_period = vibratto_base_period
+                                    * powf(2.0f, RND * 2.0f - 1.0f);
+
+            float m = 4.0f / (vibratto_period * increments_per_second);
+            if(RND < 0.5f)
+                m = -m;
+            unison_vibratto[nvoice].step[k] = m;
+        }
+
+        if(unison == 1) { //no vibratto for a single voice
+            unison_vibratto[nvoice].step[0]     = 0.0f;
+            unison_vibratto[nvoice].position[0] = 0.0f;
+            unison_vibratto[nvoice].amplitude   = 0.0f;
+        }
+
+        //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.5f);
+                    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 float[unison];
+        oscfreqhiFM[nvoice] = new unsigned int[unison];
+        oscfreqloFM[nvoice] = new float[unison];
+        oscposhi[nvoice]    = new int[unison];
+        oscposlo[nvoice]    = new float[unison];
+        oscposhiFM[nvoice]  = new unsigned int[unison];
+        oscposloFM[nvoice]  = new float[unison];
 
-        NoteVoicePar[nvoice].Enabled=ON;
-        NoteVoicePar[nvoice].fixedfreq=pars->VoicePar[nvoice].Pfixedfreq;
-        NoteVoicePar[nvoice].fixedfreqET=pars->VoicePar[nvoice].PfixedfreqET;
+        NoteVoicePar[nvoice].Enabled     = ON;
+        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);
-        };
-
-        oscposhi[nvoice]=0;
-        oscposlo[nvoice]=0.0;
-        oscposhiFM[nvoice]=0;
-        oscposloFM[nvoice]=0.0;
-
-        NoteVoicePar[nvoice].OscilSmp=new REALTYPE[OSCIL_SIZE+OSCIL_SMP_EXTRA_SAMPLES];//the extra points contains the first point
+        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.0f;
+            oscposhiFM[nvoice][k] = 0;
+            oscposloFM[nvoice][k] = 0.0f;
+        }
+
+        //the extra points contains the first point
+        NoteVoicePar[nvoice].OscilSmp =
+            new float[synth->oscilsize + OSCIL_SMP_EXTRA_SAMPLES];
 
         //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());
-        oscposhi[nvoice]=pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp,getvoicebasefreq(nvoice),
-                         pars->VoicePar[nvoice].Presonance);
+        int vc = nvoice;
+        if(pars->VoicePar[nvoice].Pextoscil != -1)
+            vc = pars->VoicePar[nvoice].Pextoscil;
+        if(!pars->GlobalPar.Hrandgrouping)
+            pars->VoicePar[vc].OscilSmp->newrandseed(prng());
+        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];
-
-        oscposhi[nvoice]+=(int)((pars->VoicePar[nvoice].Poscilphase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE*4);
-        oscposhi[nvoice]%=OSCIL_SIZE;
-
-
-        NoteVoicePar[nvoice].FreqLfo=NULL;
-        NoteVoicePar[nvoice].FreqEnvelope=NULL;
-
-        NoteVoicePar[nvoice].AmpLfo=NULL;
-        NoteVoicePar[nvoice].AmpEnvelope=NULL;
-
-        NoteVoicePar[nvoice].VoiceFilter=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;
-            break;
-        case 2:
-            NoteVoicePar[nvoice].FMEnabled=RING_MOD;
-            break;
-        case 3:
-            NoteVoicePar[nvoice].FMEnabled=PHASE_MOD;
-            break;
-        case 4:
-            NoteVoicePar[nvoice].FMEnabled=FREQ_MOD;
-            break;
-        case 5:
-            NoteVoicePar[nvoice].FMEnabled=PITCH_MOD;
-            break;
-        default:
-            NoteVoicePar[nvoice].FMEnabled=NONE;
-        };
-
-        NoteVoicePar[nvoice].FMVoice=pars->VoicePar[nvoice].PFMVoice;
-        NoteVoicePar[nvoice].FMFreqEnvelope=NULL;
-        NoteVoicePar[nvoice].FMAmpEnvelope=NULL;
+        for(int i = 0; i < OSCIL_SMP_EXTRA_SAMPLES; ++i)
+            NoteVoicePar[nvoice].OscilSmp[synth->oscilsize
+                                          + i] =
+                NoteVoicePar[nvoice].OscilSmp[i];
+
+        oscposhi_start +=
+            (int)((pars->VoicePar[nvoice].Poscilphase
+                   - 64.0f) / 128.0f * synth->oscilsize + synth->oscilsize * 4);
+        oscposhi_start %= synth->oscilsize;
+
+        for(int k = 0; k < unison; ++k) {
+            oscposhi[nvoice][k] = oscposhi_start;
+            oscposhi_start      = (int)(RND * (synth->oscilsize - 1)); //put random starting point for other subvoices
+        }
+
+        NoteVoicePar[nvoice].FreqLfo      = NULL;
+        NoteVoicePar[nvoice].FreqEnvelope = NULL;
+
+        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;
+                break;
+            case 2:
+                NoteVoicePar[nvoice].FMEnabled = RING_MOD;
+                break;
+            case 3:
+                NoteVoicePar[nvoice].FMEnabled = PHASE_MOD;
+                break;
+            case 4:
+                NoteVoicePar[nvoice].FMEnabled = FREQ_MOD;
+                break;
+            case 5:
+                NoteVoicePar[nvoice].FMEnabled = PITCH_MOD;
+                break;
+            default:
+                NoteVoicePar[nvoice].FMEnabled = NONE;
+        }
+
+        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) {
-        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;
-            break;
-        case FREQ_MOD:
-            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;//???????????
+        float fmvoldamp = powf(440.0f / getvoicebasefreq(
+                                   nvoice),
+                               pars->VoicePar[nvoice].PFMVolumeDamp / 64.0f
+                               - 1.0f);
+        switch(NoteVoicePar[nvoice].FMEnabled) {
+            case PHASE_MOD:
+                fmvoldamp =
+                    powf(440.0f / getvoicebasefreq(
+                             nvoice), pars->VoicePar[nvoice].PFMVolumeDamp
+                         / 64.0f);
+                NoteVoicePar[nvoice].FMVolume =
+                    (expf(pars->VoicePar[nvoice].PFMVolume / 127.0f
+                          * FM_AMP_MULTIPLIER) - 1.0f) * fmvoldamp * 4.0f;
+                break;
+            case FREQ_MOD:
+                NoteVoicePar[nvoice].FMVolume =
+                    (expf(pars->VoicePar[nvoice].PFMVolume / 127.0f
+                          * FM_AMP_MULTIPLIER) - 1.0f) * fmvoldamp * 4.0f;
+                break;
+            //    case PITCH_MOD:NoteVoicePar[nvoice].FMVolume=(pars->VoicePar[nvoice].PFMVolume/127.0f*8.0f)*fmvoldamp;//???????????
             //	          break;
-        default:
-            if (fmvoldamp>1.0) fmvoldamp=1.0;
-            NoteVoicePar[nvoice].FMVolume=pars->VoicePar[nvoice].PFMVolume/127.0*fmvoldamp;
-        };
+            default:
+                if(fmvoldamp > 1.0f)
+                    fmvoldamp = 1.0f;
+                NoteVoicePar[nvoice].FMVolume =
+                    pars->VoicePar[nvoice].PFMVolume
+                    / 127.0f * fmvoldamp;
+        }
 
         //Voice's modulator velocity sensing
-        NoteVoicePar[nvoice].FMVolume*=VelF(velocity,partparams->VoicePar[nvoice].PFMVelocityScaleFunction);
+        NoteVoicePar[nvoice].FMVolume *=
+            VelF(velocity,
+                 partparams->VoicePar[nvoice].PFMVelocityScaleFunction);
+
+        FMoldsmp[nvoice] = new float [unison];
+        for(int k = 0; k < unison; ++k)
+            FMoldsmp[nvoice][k] = 0.0f;                     //this is for FM (integration)
+
+        firsttick[nvoice] = 1;
+        NoteVoicePar[nvoice].DelayTicks =
+            (int)((expf(pars->VoicePar[nvoice].PDelay / 127.0f
+                        * logf(50.0f))
+                   - 1.0f) / synth->buffersize_f / 10.0f * synth->samplerate_f);
+    }
 
-        FMoldsmp[nvoice]=0.0;//this is for FM (integration)
+    max_unison = 1;
+    for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice)
+        if(unison_size[nvoice] > max_unison)
+            max_unison = unison_size[nvoice];
 
-        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);
-    };
 
-    initparameters();
-    ready=1;
-};
+    tmpwave_unison = new float *[max_unison];
+    for(int k = 0; k < max_unison; ++k) {
+        tmpwave_unison[k] = new float[synth->buffersize];
+        memset(tmpwave_unison[k], 0, synth->bufferbytes);
+    }
 
+    initparameters();
+}
 
 // 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::legatonote(float freq, float velocity, int portamento_,
+                        int midinote_, bool externcall)
 {
-    ADnoteParameters *pars=partparams;
-    //Controller *ctl_=ctl;
+    ADnoteParameters *pars = partparams;
 
     // 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;
-                return;
-            }
-        }
-        if (Legato.msg==LM_ToNorm) Legato.msg=LM_Norm;
-    }
+    if(legato.update(freq, velocity, portamento_, midinote_, externcall))
+        return;
 
-    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.0f)
+        velocity = 1.0f;
+    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.0f;
 
+    //center freq
+    NoteGlobalPar.FilterCenterPitch = pars->GlobalPar.GlobalFilter->getfreq()
+                                      + pars->GlobalPar.PFilterVelocityScale
+                                      / 127.0f * 6.0f          //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)
+            continue;  //(gf) Stay the same as first note in legato.
 
-    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(prng());
 
-        ///oscposhi[nvoice]=pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp,getvoicebasefreq(nvoice),pars->VoicePar[nvoice].Presonance);
-        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[synth->oscilsize
+                                          + 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);
-
-        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;
-            break;
-        case FREQ_MOD:
-            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;//???????????
+        float fmvoldamp = powf(440.0f / getvoicebasefreq(nvoice),
+                               pars->VoicePar[nvoice].PFMVolumeDamp / 64.0f
+                               - 1.0f);
+
+        switch(NoteVoicePar[nvoice].FMEnabled) {
+            case PHASE_MOD:
+                fmvoldamp =
+                    powf(440.0f / getvoicebasefreq(
+                             nvoice), pars->VoicePar[nvoice].PFMVolumeDamp
+                         / 64.0f);
+                NoteVoicePar[nvoice].FMVolume =
+                    (expf(pars->VoicePar[nvoice].PFMVolume / 127.0f
+                          * FM_AMP_MULTIPLIER) - 1.0f) * fmvoldamp * 4.0f;
+                break;
+            case FREQ_MOD:
+                NoteVoicePar[nvoice].FMVolume =
+                    (expf(pars->VoicePar[nvoice].PFMVolume / 127.0f
+                          * FM_AMP_MULTIPLIER) - 1.0f) * fmvoldamp * 4.0f;
+                break;
+            //    case PITCH_MOD:NoteVoicePar[nvoice].FMVolume=(pars->VoicePar[nvoice].PFMVolume/127.0f*8.0f)*fmvoldamp;//???????????
             //	          break;
-        default:
-            if (fmvoldamp>1.0) fmvoldamp=1.0;
-            NoteVoicePar[nvoice].FMVolume=pars->VoicePar[nvoice].PFMVolume/127.0*fmvoldamp;
-        };
+            default:
+                if(fmvoldamp > 1.0f)
+                    fmvoldamp = 1.0f;
+                NoteVoicePar[nvoice].FMVolume =
+                    pars->VoicePar[nvoice].PFMVolume
+                    / 127.0f * 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)((expf(pars->VoicePar[nvoice].PDelay / 127.0f
+                        * logf(50.0f))
+                   - 1.0f) / synth->buffersize_f / 10.0f * synth->samplerate_f);
+    }
 
     ///    initparameters();
 
     ///////////////
     // Altered content of initparameters():
 
-    int nvoice,i,tmp[NUM_VOICES];
+    int 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.0f
+                           * powf(0.1f, 3.0f
+                                  * (1.0f - partparams->GlobalPar.PVolume
+                                     / 96.0f))                                      //-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(int 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(unsigned 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 =
+            powf(0.1f, 3.0f
+                 * (1.0f - partparams->VoicePar[nvoice].PVolume / 127.0f))             // -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.0f;
 
-        if (partparams->VoicePar[nvoice].PVolumeminus!=0) NoteVoicePar[nvoice].Volume=-NoteVoicePar[nvoice].Volume;
+        newamplitude[nvoice] = 1.0f;
+        if((partparams->VoicePar[nvoice].PAmpEnvelopeEnabled != 0)
+           && (NoteVoicePar[nvoice].AmpEnvelope != NULL))
+            newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpEnvelope->envout_dB();
 
-        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();
-        };
+        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)) {
-            partparams->VoicePar[nvoice].FMSmp->newrandseed(rand());
+        if((NoteVoicePar[nvoice].FMEnabled != NONE)
+           && (NoteVoicePar[nvoice].FMVoice < 0)) {
+            partparams->VoicePar[nvoice].FMSmp->newrandseed(prng());
 
             //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());
+            if(!partparams->GlobalPar.Hrandgrouping)
+                partparams->VoicePar[vc].FMSmp->newrandseed(prng());
 
-            ///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];
-            ///oscposhiFM[nvoice]+=(int)((partparams->VoicePar[nvoice].PFMoscilphase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE*4);
-            ///oscposhiFM[nvoice]%=OSCIL_SIZE;
-        };
+            for(int i = 0; i < OSCIL_SMP_EXTRA_SAMPLES; ++i)
+                NoteVoicePar[nvoice].FMSmp[synth->oscilsize + i] =
+                    NoteVoicePar[nvoice].FMSmp[i];
+        }
 
-        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();
-        };
-    };
-
-    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;
-            };
-        ///      if (NoteVoicePar[nvoice].VoiceOut!=NULL) for (i=0;i<SOUND_BUFFER_SIZE;i++) NoteVoicePar[nvoice].VoiceOut[i]=0.0;
-    };
-    ///////////////
+        if((partparams->VoicePar[nvoice].PFMAmpEnvelopeEnabled != 0)
+           && (NoteVoicePar[nvoice].FMAmpEnvelope != NULL))
+            FMnewamplitude[nvoice] *=
+                NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB();
+    }
 
-    // End of the ADlegatonote function.
-};
+    for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice) {
+        for(unsigned i = nvoice + 1; i < NUM_VOICES; ++i)
+            tmp[i] = 0;
+        for(unsigned i = nvoice + 1; i < NUM_VOICES; ++i)
+            if((NoteVoicePar[i].FMVoice == nvoice) && (tmp[i] == 0))
+                tmp[i] = 1;
+    }
+}
 
 
 /*
@@ -425,77 +654,56 @@ void ADnote::ADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int
  */
 void ADnote::KillVoice(int nvoice)
 {
-
-    delete []NoteVoicePar[nvoice].OscilSmp;
-
-    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].VoiceFilter!=NULL) delete (NoteVoicePar[nvoice].VoiceFilter);
-    NoteVoicePar[nvoice].VoiceFilter=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)
-        for (int i=0;i<SOUND_BUFFER_SIZE;i++) NoteVoicePar[nvoice].VoiceOut[i]=0.0;//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 [] 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;
+
+    NoteVoicePar[nvoice].kill();
+}
 
 /*
  * Kill the note
  */
 void ADnote::KillNote()
 {
-    int nvoice;
-    for (nvoice=0;nvoice<NUM_VOICES;nvoice++) {
-        if (NoteVoicePar[nvoice].Enabled==ON) KillVoice(nvoice);
+    for(unsigned 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)
+            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);
-    delete (NoteGlobalPar.FilterEnvelope);
-    delete (NoteGlobalPar.FilterLfo);
+    NoteGlobalPar.kill();
 
-    NoteEnabled=OFF;
-};
+    NoteEnabled = OFF;
+}
 
 ADnote::~ADnote()
 {
-    if (NoteEnabled==ON) KillNote();
-    delete [] tmpwave;
+    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;
+}
 
 
 /*
@@ -503,368 +711,456 @@ ADnote::~ADnote()
  */
 void ADnote::initparameters()
 {
-    int nvoice,i,tmp[NUM_VOICES];
+    int tmp[NUM_VOICES];
 
     // Global Parameters
-    NoteGlobalPar.FreqEnvelope=new Envelope(partparams->GlobalPar.FreqEnvelope,basefreq);
-    NoteGlobalPar.FreqLfo=new LFO(partparams->GlobalPar.FreqLfo,basefreq);
+    NoteGlobalPar.initparameters(partparams->GlobalPar, basefreq, velocity,
+                                 stereo);
 
-    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.AmpEnvelope->envout_dB(); //discard the first envelope output
+    globalnewamplitude = NoteGlobalPar.Volume
+                         * NoteGlobalPar.AmpEnvelope->envout_dB()
+                         * NoteGlobalPar.AmpLfo->amplfoout();
 
     // 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(int 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(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice) {
+        Voice &vce = NoteVoicePar[nvoice];
+        ADnoteVoiceParam &param = partparams->VoicePar[nvoice];
 
-        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(vce.Enabled == 0)
+            continue;
 
-        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();
-        };
+        vce.noisetype = param.Type;
+        /* Voice Amplitude Parameters Init */
+        vce.Volume = powf(0.1f, 3.0f * (1.0f - param.PVolume / 127.0f)) // -60dB..0dB
+                     * VelF(velocity, param.PAmpVelocityScaleFunction);
+
+        if(param.PVolumeminus)
+            vce.Volume = -vce.Volume;
+
+        if(param.PPanning == 0)
+            vce.Panning = RND;  // random panning
+        else
+            vce.Panning = param.PPanning / 128.0f;
+
+        newamplitude[nvoice] = 1.0f;
+        if(param.PAmpEnvelopeEnabled) {
+            vce.AmpEnvelope = new Envelope(param.AmpEnvelope, basefreq);
+            vce.AmpEnvelope->envout_dB(); //discard the first envelope sample
+            newamplitude[nvoice] *= vce.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(param.PAmpLfoEnabled) {
+            vce.AmpLfo = new LFO(param.AmpLfo, basefreq);
+            newamplitude[nvoice] *= vce.AmpLfo->amplfoout();
+        }
 
         /* Voice Frequency Parameters Init */
-        if (partparams->VoicePar[nvoice].PFreqEnvelopeEnabled!=0)
-            NoteVoicePar[nvoice].FreqEnvelope=new Envelope(partparams->VoicePar[nvoice].FreqEnvelope,basefreq);
+        if(param.PFreqEnvelopeEnabled != 0)
+            vce.FreqEnvelope = new Envelope(param.FreqEnvelope, basefreq);
 
-        if (partparams->VoicePar[nvoice].PFreqLfoEnabled!=0) NoteVoicePar[nvoice].FreqLfo=new LFO(partparams->VoicePar[nvoice].FreqLfo,basefreq);
+        if(param.PFreqLfoEnabled != 0)
+            vce.FreqLfo = new LFO(param.FreqLfo, basefreq);
 
         /* Voice Filter Parameters Init */
-        if (partparams->VoicePar[nvoice].PFilterEnabled!=0) {
-            NoteVoicePar[nvoice].VoiceFilter=new Filter(partparams->VoicePar[nvoice].VoiceFilter);
-        };
+        if(param.PFilterEnabled != 0) {
+            vce.VoiceFilterL = Filter::generate(param.VoiceFilter);
+            vce.VoiceFilterR = Filter::generate(param.VoiceFilter);
+        }
 
-        if (partparams->VoicePar[nvoice].PFilterEnvelopeEnabled!=0)
-            NoteVoicePar[nvoice].FilterEnvelope=new Envelope(partparams->VoicePar[nvoice].FilterEnvelope,basefreq);
+        if(param.PFilterEnvelopeEnabled != 0)
+            vce.FilterEnvelope = new Envelope(param.FilterEnvelope, basefreq);
 
-        if (partparams->VoicePar[nvoice].PFilterLfoEnabled!=0)
-            NoteVoicePar[nvoice].FilterLfo=new LFO(partparams->VoicePar[nvoice].FilterLfo,basefreq);
+        if(param.PFilterLfoEnabled != 0)
+            vce.FilterLfo = new LFO(param.FilterLfo, basefreq);
 
-        NoteVoicePar[nvoice].FilterFreqTracking=partparams->VoicePar[nvoice].VoiceFilter->getfreqtracking(basefreq);
+        vce.FilterFreqTracking =
+            param.VoiceFilter->getfreqtracking(basefreq);
 
         /* Voice Modulation Parameters Init */
-        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];
+        if((vce.FMEnabled != NONE) && (vce.FMVoice < 0)) {
+            param.FMSmp->newrandseed(prng());
+            vce.FMSmp = new float[synth->oscilsize + 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;
+            int vc = nvoice;
+            if(param.PextFMoscil != -1)
+                vc = param.PextFMoscil;
+
+            float tmp = 1.0f;
+            if((partparams->VoicePar[vc].FMSmp->Padaptiveharmonics != 0)
+               || (vce.FMEnabled == MORPH)
+               || (vce.FMEnabled == RING_MOD))
+                tmp = getFMvoicebasefreq(nvoice);
+
+            if(!partparams->GlobalPar.Hrandgrouping)
+                partparams->VoicePar[vc].FMSmp->newrandseed(prng());
+
+            for(int k = 0; k < unison_size[nvoice]; ++k)
+                oscposhiFM[nvoice][k] = (oscposhi[nvoice][k]
+                                         + partparams->VoicePar[vc].FMSmp->get(
+                                             vce.FMSmp, tmp))
+                                        % synth->oscilsize;
+
+            for(int i = 0; i < OSCIL_SMP_EXTRA_SAMPLES; ++i)
+                vce.FMSmp[synth->oscilsize + i] = vce.FMSmp[i];
+            int oscposhiFM_add =
+                (int)((param.PFMoscilphase
+                       - 64.0f) / 128.0f * synth->oscilsize
+                      + synth->oscilsize * 4);
+            for(int k = 0; k < unison_size[nvoice]; ++k) {
+                oscposhiFM[nvoice][k] += oscposhiFM_add;
+                oscposhiFM[nvoice][k] %= synth->oscilsize;
+            }
+        }
 
-            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());
+        if(param.PFMFreqEnvelopeEnabled != 0)
+            vce.FMFreqEnvelope = new Envelope(param.FMFreqEnvelope, basefreq);
 
-            oscposhiFM[nvoice]=(oscposhi[nvoice]+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];
-            oscposhiFM[nvoice]+=(int)((partparams->VoicePar[nvoice].PFMoscilphase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE*4);
-            oscposhiFM[nvoice]%=OSCIL_SIZE;
-        };
+        FMnewamplitude[nvoice] = vce.FMVolume * ctl->fmamp.relamp;
 
-        if (partparams->VoicePar[nvoice].PFMFreqEnvelopeEnabled!=0)
-            NoteVoicePar[nvoice].FMFreqEnvelope=new Envelope(partparams->VoicePar[nvoice].FMFreqEnvelope,basefreq);
+        if(param.PFMAmpEnvelopeEnabled != 0) {
+            vce.FMAmpEnvelope = new Envelope(param.FMAmpEnvelope,
+                                             basefreq);
+            FMnewamplitude[nvoice] *= vce.FMAmpEnvelope->envout_dB();
+        }
+    }
 
-        FMnewamplitude[nvoice]=NoteVoicePar[nvoice].FMVolume*ctl->fmamp.relamp;
+    for(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice) {
+        for(int i = nvoice + 1; i < NUM_VOICES; ++i)
+            tmp[i] = 0;
+        for(int i = nvoice + 1; i < NUM_VOICES; ++i)
+            if((NoteVoicePar[i].FMVoice == nvoice) && (tmp[i] == 0)) {
+                NoteVoicePar[nvoice].VoiceOut = new float[synth->buffersize];
+                tmp[i] = 1;
+            }
 
-        if (partparams->VoicePar[nvoice].PFMAmpEnvelopeEnabled!=0) {
-            NoteVoicePar[nvoice].FMAmpEnvelope=new Envelope(partparams->VoicePar[nvoice].FMAmpEnvelope,basefreq);
-            FMnewamplitude[nvoice]*=NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB();
-        };
-    };
+        if(NoteVoicePar[nvoice].VoiceOut)
+            memset(NoteVoicePar[nvoice].VoiceOut, 0, synth->bufferbytes);
+    }
+}
 
-    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.0f;
+        return;
+    }
+    float relbw = ctl->bandwidth.relbw * bandwidthDetuneMultiplier;
+    for(int k = 0; k < unison_size[nvoice]; ++k) {
+        float pos  = unison_vibratto[nvoice].position[k];
+        float step = unison_vibratto[nvoice].step[k];
+        pos += step;
+        if(pos <= -1.0f) {
+            pos  = -1.0f;
+            step = -step;
+        }
+        if(pos >= 1.0f) {
+            pos  = 1.0f;
+            step = -step;
+        }
+        float vibratto_val = (pos - 0.333333333f * pos * pos * pos) * 1.5f; //make the vibratto lfo smoother
+        unison_freq_rap[nvoice][k] = 1.0f
+                                     + ((unison_base_freq_rap[nvoice][k]
+                                         - 1.0f) + 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 freq)
+void ADnote::setfreq(int nvoice, float in_freq)
 {
-    REALTYPE speed;
-    freq=fabs(freq);
-    speed=freq*REALTYPE(OSCIL_SIZE)/(REALTYPE) SAMPLE_RATE;
-    if (speed>OSCIL_SIZE) speed=OSCIL_SIZE;
-
-    F2I(speed,oscfreqhi[nvoice]);
-    oscfreqlo[nvoice]=speed-floor(speed);
-};
+    for(int k = 0; k < unison_size[nvoice]; ++k) {
+        float freq  = fabs(in_freq) * unison_freq_rap[nvoice][k];
+        float speed = freq * synth->oscilsize_f / synth->samplerate_f;
+        if(speed > synth->oscilsize_f)
+            speed = synth->oscilsize_f;
+
+        F2I(speed, oscfreqhi[nvoice][k]);
+        oscfreqlo[nvoice][k] = speed - floor(speed);
+    }
+}
 
 /*
  * Computes the frequency of an modullator oscillator
  */
-void ADnote::setfreqFM(int nvoice,REALTYPE freq)
+void ADnote::setfreqFM(int nvoice, float in_freq)
 {
-    REALTYPE speed;
-    freq=fabs(freq);
-    speed=freq*REALTYPE(OSCIL_SIZE)/(REALTYPE) SAMPLE_RATE;
-    if (speed>OSCIL_SIZE) speed=OSCIL_SIZE;
-
-    F2I(speed,oscfreqhiFM[nvoice]);
-    oscfreqloFM[nvoice]=speed-floor(speed);
-};
+    for(int k = 0; k < unison_size[nvoice]; ++k) {
+        float freq  = fabs(in_freq) * unison_freq_rap[nvoice][k];
+        float speed = freq * synth->oscilsize_f / synth->samplerate_f;
+        if(speed > synth->samplerate_f)
+            speed = synth->samplerate_f;
+
+        F2I(speed, oscfreqhiFM[nvoice][k]);
+        oscfreqloFM[nvoice][k] = speed - floor(speed);
+    }
+}
 
 /*
  * Get Voice base frequency
  */
-REALTYPE ADnote::getvoicebasefreq(int nvoice)
+float 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));
-    };
-};
+    float detune = NoteVoicePar[nvoice].Detune / 100.0f
+                   + NoteVoicePar[nvoice].FineDetune / 100.0f
+                   * ctl->bandwidth.relbw * bandwidthDetuneMultiplier
+                   + NoteGlobalPar.Detune / 100.0f;
+
+    if(NoteVoicePar[nvoice].fixedfreq == 0)
+        return this->basefreq * powf(2, detune / 12.0f);
+    else { //the fixed freq is enabled
+        float fixedfreq   = 440.0f;
+        int   fixedfreqET = NoteVoicePar[nvoice].fixedfreqET;
+        if(fixedfreqET != 0) { //if the frequency varies according the keyboard note
+            float tmp =
+                (midinote
+                 - 69.0f) / 12.0f
+                * (powf(2.0f, (fixedfreqET - 1) / 63.0f) - 1.0f);
+            if(fixedfreqET <= 64)
+                fixedfreq *= powf(2.0f, tmp);
+            else
+                fixedfreq *= powf(3.0f, tmp);
+        }
+        return fixedfreq * powf(2.0f, detune / 12.0f);
+    }
+}
 
 /*
  * Get Voice's Modullator base frequency
  */
-REALTYPE ADnote::getFMvoicebasefreq(int nvoice)
+float ADnote::getFMvoicebasefreq(int nvoice) const
 {
-    REALTYPE detune=NoteVoicePar[nvoice].FMDetune/100.0;
-    return(getvoicebasefreq(nvoice)*pow(2,detune/12.0));
-};
+    float detune = NoteVoicePar[nvoice].FMDetune / 100.0f;
+    return getvoicebasefreq(nvoice) * powf(2, detune / 12.0f);
+}
 
 /*
  * 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;
+    float voicefreq, voicepitch, filterpitch, filterfreq, FMfreq,
+          FMrelativepitch, globalpitch, globalfilterpitch;
+    globalpitch = 0.01f * (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;
+
+    float tmpfilterfreq = globalfilterpitch + ctl->filtercutoff.relfreq
+                          + NoteGlobalPar.FilterFreqTracking;
+
+    tmpfilterfreq = Filter::getrealfreq(tmpfilterfreq);
+
+    float 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"
-        };
-    };
+    float portamentofreqrap = 1.0f;
+    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);
 
         /*******************/
         /* Voice Amplitude */
         /*******************/
-        oldamplitude[nvoice]=newamplitude[nvoice];
-        newamplitude[nvoice]=1.0;
+        oldamplitude[nvoice] = newamplitude[nvoice];
+        newamplitude[nvoice] = 1.0f;
 
-        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].VoiceFilter!=NULL) {
-            filterpitch=NoteVoicePar[nvoice].FilterCenterPitch;
-
-            if (NoteVoicePar[nvoice].FilterEnvelope!=NULL)
-                filterpitch+=NoteVoicePar[nvoice].FilterEnvelope->envout();
+        if(NoteVoicePar[nvoice].VoiceFilterL != NULL) {
+            filterpitch = NoteVoicePar[nvoice].FilterCenterPitch;
 
-            if (NoteVoicePar[nvoice].FilterLfo!=NULL)
-                filterpitch+=NoteVoicePar[nvoice].FilterLfo->lfoout();
+            if(NoteVoicePar[nvoice].FilterEnvelope != NULL)
+                filterpitch += NoteVoicePar[nvoice].FilterEnvelope->envout();
 
-            filterfreq=filterpitch+NoteVoicePar[nvoice].FilterFreqTracking;
-            filterfreq=NoteVoicePar[nvoice].VoiceFilter->getrealfreq(filterfreq);
+            if(NoteVoicePar[nvoice].FilterLfo != NULL)
+                filterpitch += NoteVoicePar[nvoice].FilterLfo->lfoout();
 
-            NoteVoicePar[nvoice].VoiceFilter->setfreq(filterfreq);
-        };
+            filterfreq = filterpitch + NoteVoicePar[nvoice].FilterFreqTracking;
+            filterfreq = Filter::getrealfreq(filterfreq);
 
-        if (NoteVoicePar[nvoice].noisetype==0) {//compute only if the voice isn't noise
+            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
             /*******************/
             /* 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.0f;
+            if(NoteVoicePar[nvoice].FreqLfo != NULL)
+                voicepitch += NoteVoicePar[nvoice].FreqLfo->lfoout() / 100.0f
+                              * ctl->bandwidth.relbw;
+
+            if(NoteVoicePar[nvoice].FreqEnvelope != NULL)
+                voicepitch += NoteVoicePar[nvoice].FreqEnvelope->envout()
+                              / 100.0f;
+            voicefreq = getvoicebasefreq(nvoice)
+                        * powf(2, (voicepitch + globalpitch) / 12.0f);                //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.0f;
+                if(NoteVoicePar[nvoice].FMFreqEnvelope != NULL)
+                    FMrelativepitch +=
+                        NoteVoicePar[nvoice].FMFreqEnvelope->envout() / 100;
+                FMfreq =
+                    powf(2.0f, FMrelativepitch
+                         / 12.0f) * 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 += synth->buffersize_f / synth->samplerate_f;
+}
 
 
 /*
  * Fadein in a way that removes clicks but keep sound "punchy"
  */
-inline void ADnote::fadein(REALTYPE *smps)
+inline void ADnote::fadein(float *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 < synth->buffersize; ++i)
+        if((smps[i - 1] < 0.0f) && (smps[i] > 0.0f))
+            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;
+    float tmp = (synth->buffersize_f - 1.0f) / (zerocrossings + 1) / 3.0f;
+    if(tmp < 8.0f)
+        tmp = 8.0f;
 
     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 > synth->buffersize)
+        n = synth->buffersize;
+    for(int i = 0; i < n; ++i) { //fade-in
+        float tmp = 0.5f - cosf((float)i / (float) n * PI) * 0.5f;
+        smps[i] *= tmp;
+    }
+}
 
 /*
  * Computes the Oscillator (Without Modulation) - LinearInterpolation
  */
 inline void ADnote::ComputeVoiceOscillator_LinearInterpolation(int nvoice)
 {
-    int i,poshi;
-    REALTYPE poslo;
-
-    poshi=oscposhi[nvoice];
-    poslo=oscposlo[nvoice];
-    REALTYPE *smps=NoteVoicePar[nvoice].OscilSmp;
-    for (i=0;i<SOUND_BUFFER_SIZE;i++) {
-        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;
-    oscposlo[nvoice]=poslo;
-};
+    int   i, poshi;
+    float poslo;
+
+    for(int k = 0; k < unison_size[nvoice]; ++k) {
+        poshi = oscposhi[nvoice][k];
+        poslo = oscposlo[nvoice][k];
+        int    freqhi = oscfreqhi[nvoice][k];
+        float  freqlo = oscfreqlo[nvoice][k];
+        float *smps   = NoteVoicePar[nvoice].OscilSmp;
+        float *tw     = tmpwave_unison[k];
+        for(i = 0; i < synth->buffersize; ++i) {
+            tw[i]  = smps[poshi] * (1.0f - poslo) + smps[poshi + 1] * poslo;
+            poslo += freqlo;
+            if(poslo >= 1.0f) {
+                poslo -= 1.0f;
+                poshi++;
+            }
+            poshi += freqhi;
+            poshi &= synth->oscilsize - 1;
+        }
+        oscposhi[nvoice][k] = poshi;
+        oscposlo[nvoice][k] = poslo;
+    }
+}
 
 
 
 /*
  * Computes the Oscillator (Without Modulation) - CubicInterpolation
  *
- The differences from the Linear are to little to deserve to be used. This is because I am using a large OSCIL_SIZE (>512)
+ The differences from the Linear are to little to deserve to be used. This is because I am using a large synth->oscilsize (>512)
 inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int nvoice){
     int i,poshi;
-    REALTYPE poslo;
+    float poslo;
 
     poshi=oscposhi[nvoice];
     poslo=oscposlo[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];
-        poshi&=OSCIL_SIZE-1;
+    float *smps=NoteVoicePar[nvoice].OscilSmp;
+    float xm1,x0,x1,x2,a,b,c;
+    for (i=0;i<synth->buffersize;i++){
+    xm1=smps[poshi];
+    x0=smps[poshi+1];
+    x1=smps[poshi+2];
+    x2=smps[poshi+3];
+    a=(3.0f * (x0-x1) - xm1 + x2) / 2.0f;
+    b = 2.0f*x1 + xm1 - (5.0f*x0 + x2) / 2.0f;
+    c = (x1 - xm1) / 2.0f;
+    tmpwave[i]=(((a * poslo) + b) * poslo + c) * poslo + x0;
+    printf("a\n");
+    //tmpwave[i]=smps[poshi]*(1.0f-poslo)+smps[poshi+1]*poslo;
+    poslo+=oscfreqlo[nvoice];
+    if (poslo>=1.0f) {
+            poslo-=1.0f;
+        poshi++;
+    };
+        poshi+=oscfreqhi[nvoice];
+        poshi&=synth->oscilsize-1;
     };
     oscposhi[nvoice]=poshi;
     oscposlo[nvoice]=poslo;
@@ -875,182 +1171,260 @@ inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int nvoice){
  */
 inline void ADnote::ComputeVoiceOscillatorMorph(int nvoice)
 {
-    int i;
-    REALTYPE amp;
+    int   i;
+    float amp;
     ComputeVoiceOscillator_LinearInterpolation(nvoice);
-    if (FMnewamplitude[nvoice]>1.0) FMnewamplitude[nvoice]=1.0;
-    if (FMoldamplitude[nvoice]>1.0) FMoldamplitude[nvoice]=1.0;
+    if(FMnewamplitude[nvoice] > 1.0f)
+        FMnewamplitude[nvoice] = 1.0f;
+    if(FMoldamplitude[nvoice] > 1.0f)
+        FMoldamplitude[nvoice] = 1.0f;
 
-    if (NoteVoicePar[nvoice].FMVoice>=0) {
+    if(NoteVoicePar[nvoice].FMVoice >= 0) {
         //if I use VoiceOut[] as modullator
-        int FMVoice=NoteVoicePar[nvoice].FMVoice;
-        for (i=0;i<SOUND_BUFFER_SIZE;i++) {
-            amp=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice]
-                                      ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE);
-            tmpwave[i]=tmpwave[i]*(1.0-amp)+amp*NoteVoicePar[FMVoice].VoiceOut[i];
-        };
-    } else {
-        int poshiFM=oscposhiFM[nvoice];
-        REALTYPE posloFM=oscposloFM[nvoice];
-
-        for (i=0;i<SOUND_BUFFER_SIZE;i++) {
-            amp=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice]
-                                      ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE);
-            tmpwave[i]=tmpwave[i]*(1.0-amp)+amp
-                       *(NoteVoicePar[nvoice].FMSmp[poshiFM]*(1-posloFM)
-                         +NoteVoicePar[nvoice].FMSmp[poshiFM+1]*posloFM);
-            posloFM+=oscfreqloFM[nvoice];
-            if (posloFM>=1.0) {
-                posloFM-=1.0;
-                poshiFM++;
-            };
-            poshiFM+=oscfreqhiFM[nvoice];
-            poshiFM&=OSCIL_SIZE-1;
-        };
-        oscposhiFM[nvoice]=poshiFM;
-        oscposloFM[nvoice]=posloFM;
-    };
-};
+        int FMVoice = NoteVoicePar[nvoice].FMVoice;
+        for(int k = 0; k < unison_size[nvoice]; ++k) {
+            float *tw = tmpwave_unison[k];
+            for(i = 0; i < synth->buffersize; ++i) {
+                amp = INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice],
+                                            FMnewamplitude[nvoice],
+                                            i,
+                                            synth->buffersize);
+                tw[i] = tw[i]
+                        * (1.0f
+                           - amp) + amp * NoteVoicePar[FMVoice].VoiceOut[i];
+            }
+        }
+    }
+    else
+        for(int k = 0; k < unison_size[nvoice]; ++k) {
+            int    poshiFM  = oscposhiFM[nvoice][k];
+            float  posloFM  = oscposloFM[nvoice][k];
+            int    freqhiFM = oscfreqhiFM[nvoice][k];
+            float  freqloFM = oscfreqloFM[nvoice][k];
+            float *tw = tmpwave_unison[k];
+
+            for(i = 0; i < synth->buffersize; ++i) {
+                amp = INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice],
+                                            FMnewamplitude[nvoice],
+                                            i,
+                                            synth->buffersize);
+                tw[i] = tw[i] * (1.0f - amp) + amp
+                        * (NoteVoicePar[nvoice].FMSmp[poshiFM] * (1 - posloFM)
+                           + NoteVoicePar[nvoice].FMSmp[poshiFM + 1] * posloFM);
+                posloFM += freqloFM;
+                if(posloFM >= 1.0f) {
+                    posloFM -= 1.0f;
+                    poshiFM++;
+                }
+                poshiFM += freqhiFM;
+                poshiFM &= synth->oscilsize - 1;
+            }
+            oscposhiFM[nvoice][k] = poshiFM;
+            oscposloFM[nvoice][k] = posloFM;
+        }
+}
 
 /*
  * Computes the Oscillator (Ring Modulation)
  */
 inline void ADnote::ComputeVoiceOscillatorRingModulation(int nvoice)
 {
-    int i;
-    REALTYPE amp;
+    int   i;
+    float 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(FMnewamplitude[nvoice] > 1.0f)
+        FMnewamplitude[nvoice] = 1.0f;
+    if(FMoldamplitude[nvoice] > 1.0f)
+        FMoldamplitude[nvoice] = 1.0f;
+    if(NoteVoicePar[nvoice].FMVoice >= 0)
         // if I use VoiceOut[] as modullator
-        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++)
-                tmpwave[i]*=(1.0-amp)+amp*NoteVoicePar[FMVoice].VoiceOut[i];
-        };
-    } else {
-        int poshiFM=oscposhiFM[nvoice];
-        REALTYPE posloFM=oscposloFM[nvoice];
-
-        for (i=0;i<SOUND_BUFFER_SIZE;i++) {
-            amp=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice]
-                                      ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE);
-            tmpwave[i]*=( NoteVoicePar[nvoice].FMSmp[poshiFM]*(1.0-posloFM)
-                          +NoteVoicePar[nvoice].FMSmp[poshiFM+1]*posloFM)*amp
-                        +(1.0-amp);
-            posloFM+=oscfreqloFM[nvoice];
-            if (posloFM>=1.0) {
-                posloFM-=1.0;
-                poshiFM++;
-            };
-            poshiFM+=oscfreqhiFM[nvoice];
-            poshiFM&=OSCIL_SIZE-1;
-        };
-        oscposhiFM[nvoice]=poshiFM;
-        oscposloFM[nvoice]=posloFM;
-    };
-};
+        for(int k = 0; k < unison_size[nvoice]; ++k) {
+            float *tw = tmpwave_unison[k];
+            for(i = 0; i < synth->buffersize; ++i) {
+                amp = INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice],
+                                            FMnewamplitude[nvoice],
+                                            i,
+                                            synth->buffersize);
+                int FMVoice = NoteVoicePar[nvoice].FMVoice;
+                tw[i] *= (1.0f - amp) + amp * NoteVoicePar[FMVoice].VoiceOut[i];
+            }
+        }
+    else
+        for(int k = 0; k < unison_size[nvoice]; ++k) {
+            int    poshiFM  = oscposhiFM[nvoice][k];
+            float  posloFM  = oscposloFM[nvoice][k];
+            int    freqhiFM = oscfreqhiFM[nvoice][k];
+            float  freqloFM = oscfreqloFM[nvoice][k];
+            float *tw = tmpwave_unison[k];
+
+            for(i = 0; i < synth->buffersize; ++i) {
+                amp = INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice],
+                                            FMnewamplitude[nvoice],
+                                            i,
+                                            synth->buffersize);
+                tw[i] *= (NoteVoicePar[nvoice].FMSmp[poshiFM] * (1.0f - posloFM)
+                          + NoteVoicePar[nvoice].FMSmp[poshiFM
+                                                       + 1] * posloFM) * amp
+                         + (1.0f - amp);
+                posloFM += freqloFM;
+                if(posloFM >= 1.0f) {
+                    posloFM -= 1.0f;
+                    poshiFM++;
+                }
+                poshiFM += freqhiFM;
+                poshiFM &= synth->oscilsize - 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;
-    int i,FMmodfreqhi;
-    REALTYPE FMmodfreqlo,carposlo;
+    int   carposhi = 0;
+    int   i, FMmodfreqhi = 0;
+    float FMmodfreqlo = 0, carposlo = 0;
 
-    if (NoteVoicePar[nvoice].FMVoice>=0) {
+    if(NoteVoicePar[nvoice].FMVoice >= 0)
         //if I use VoiceOut[] as modulator
-        for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwave[i]=NoteVoicePar[NoteVoicePar[nvoice].FMVoice].VoiceOut[i];
-    } else {
-        //Compute the modulator and store it in tmpwave[]
-        int poshiFM=oscposhiFM[nvoice];
-        REALTYPE posloFM=oscposloFM[nvoice];
-
-        for (i=0;i<SOUND_BUFFER_SIZE;i++) {
-            tmpwave[i]=(NoteVoicePar[nvoice].FMSmp[poshiFM]*(1.0-posloFM)
-                        +NoteVoicePar[nvoice].FMSmp[poshiFM+1]*posloFM);
-            posloFM+=oscfreqloFM[nvoice];
-            if (posloFM>=1.0) {
-                posloFM=fmod(posloFM,1.0);
-                poshiFM++;
-            };
-            poshiFM+=oscfreqhiFM[nvoice];
-            poshiFM&=OSCIL_SIZE-1;
-        };
-        oscposhiFM[nvoice]=poshiFM;
-        oscposloFM[nvoice]=posloFM;
-    };
+        for(int k = 0; k < unison_size[nvoice]; ++k) {
+            float *tw = tmpwave_unison[k];
+            memcpy(tw, NoteVoicePar[NoteVoicePar[nvoice].FMVoice].VoiceOut,
+                   synth->bufferbytes);
+        }
+    else
+        //Compute the modulator and store it in tmpwave_unison[][]
+        for(int k = 0; k < unison_size[nvoice]; ++k) {
+            int    poshiFM  = oscposhiFM[nvoice][k];
+            float  posloFM  = oscposloFM[nvoice][k];
+            int    freqhiFM = oscfreqhiFM[nvoice][k];
+            float  freqloFM = oscfreqloFM[nvoice][k];
+            float *tw = tmpwave_unison[k];
+
+            for(i = 0; i < synth->buffersize; ++i) {
+                tw[i] =
+                    (NoteVoicePar[nvoice].FMSmp[poshiFM] * (1.0f - posloFM)
+                     + NoteVoicePar[nvoice].FMSmp[poshiFM + 1] * posloFM);
+                posloFM += freqloFM;
+                if(posloFM >= 1.0f) {
+                    posloFM = fmod(posloFM, 1.0f);
+                    poshiFM++;
+                }
+                poshiFM += freqhiFM;
+                poshiFM &= synth->oscilsize - 1;
+            }
+            oscposhiFM[nvoice][k] = poshiFM;
+            oscposloFM[nvoice][k] = posloFM;
+        }
     // Amplitude interpolation
-    if (ABOVE_AMPLITUDE_THRESHOLD(FMoldamplitude[nvoice],FMnewamplitude[nvoice])) {
-        for (i=0;i<SOUND_BUFFER_SIZE;i++) {
-            tmpwave[i]*=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice]
-                                              ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE);
-        };
-    } else for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwave[i]*=FMnewamplitude[nvoice];
-
-
-    //normalize makes all sample-rates, oscil_sizes toproduce same sound
-    if (FMmode!=0) {//Frequency modulation
-        REALTYPE normalize=OSCIL_SIZE/262144.0*44100.0/(REALTYPE)SAMPLE_RATE;
-        for (i=0;i<SOUND_BUFFER_SIZE;i++) {
-            FMoldsmp[nvoice]=fmod(FMoldsmp[nvoice]+tmpwave[i]*normalize,OSCIL_SIZE);
-            tmpwave[i]=FMoldsmp[nvoice];
-        };
-    } else {//Phase modulation
-        REALTYPE normalize=OSCIL_SIZE/262144.0;
-        for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwave[i]*=normalize;
-    };
+    if(ABOVE_AMPLITUDE_THRESHOLD(FMoldamplitude[nvoice],
+                                 FMnewamplitude[nvoice]))
+        for(int k = 0; k < unison_size[nvoice]; ++k) {
+            float *tw = tmpwave_unison[k];
+            for(i = 0; i < synth->buffersize; ++i)
+                tw[i] *= INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice],
+                                               FMnewamplitude[nvoice],
+                                               i,
+                                               synth->buffersize);
+        }
+    else
+        for(int k = 0; k < unison_size[nvoice]; ++k) {
+            float *tw = tmpwave_unison[k];
+            for(i = 0; i < synth->buffersize; ++i)
+                tw[i] *= FMnewamplitude[nvoice];
+        }
 
-    for (i=0;i<SOUND_BUFFER_SIZE;i++) {
-        F2I(tmpwave[i],FMmodfreqhi);
-        FMmodfreqlo=fmod(tmpwave[i]+0.0000000001,1.0);
-        if (FMmodfreqhi<0) FMmodfreqlo++;
 
-        //carrier
-        carposhi=oscposhi[nvoice]+FMmodfreqhi;
-        carposlo=oscposlo[nvoice]+FMmodfreqlo;
+    //normalize: makes all sample-rates, oscil_sizes to produce same sound
+    if(FMmode != 0) { //Frequency modulation
+        float normalize = synth->oscilsize_f / 262144.0f * 44100.0f
+                          / synth->samplerate_f;
+        for(int k = 0; k < unison_size[nvoice]; ++k) {
+            float *tw    = tmpwave_unison[k];
+            float  fmold = FMoldsmp[nvoice][k];
+            for(i = 0; i < synth->buffersize; ++i) {
+                fmold = fmod(fmold + tw[i] * normalize, synth->oscilsize);
+                tw[i] = fmold;
+            }
+            FMoldsmp[nvoice][k] = fmold;
+        }
+    }
+    else {  //Phase modulation
+        float normalize = synth->oscilsize_f / 262144.0f;
+        for(int k = 0; k < unison_size[nvoice]; ++k) {
+            float *tw = tmpwave_unison[k];
+            for(i = 0; i < synth->buffersize; ++i)
+                tw[i] *= normalize;
+        }
+    }
 
-        if (carposlo>=1.0) {
-            carposhi++;
-            carposlo=fmod(carposlo,1.0);
-        };
-        carposhi&=(OSCIL_SIZE-1);
+    //do the modulation
+    for(int k = 0; k < unison_size[nvoice]; ++k) {
+        float *tw     = tmpwave_unison[k];
+        int    poshi  = oscposhi[nvoice][k];
+        float  poslo  = oscposlo[nvoice][k];
+        int    freqhi = oscfreqhi[nvoice][k];
+        float  freqlo = oscfreqlo[nvoice][k];
+
+        for(i = 0; i < synth->buffersize; ++i) {
+            F2I(tw[i], FMmodfreqhi);
+            FMmodfreqlo = fmod(tw[i] + 0.0000000001f, 1.0f);
+            if(FMmodfreqhi < 0)
+                FMmodfreqlo++;
+
+            //carrier
+            carposhi = poshi + FMmodfreqhi;
+            carposlo = poslo + FMmodfreqlo;
+
+            if(carposlo >= 1.0f) {
+                carposhi++;
+                carposlo = fmod(carposlo, 1.0f);
+            }
+            carposhi &= (synth->oscilsize - 1);
 
-        tmpwave[i]=NoteVoicePar[nvoice].OscilSmp[carposhi]*(1.0-carposlo)
-                   +NoteVoicePar[nvoice].OscilSmp[carposhi+1]*carposlo;
+            tw[i] = NoteVoicePar[nvoice].OscilSmp[carposhi]
+                    * (1.0f - carposlo)
+                    + NoteVoicePar[nvoice].OscilSmp[carposhi
+                                                    + 1] * carposlo;
 
-        oscposlo[nvoice]+=oscfreqlo[nvoice];
-        if (oscposlo[nvoice]>=1.0) {
-            oscposlo[nvoice]=fmod(oscposlo[nvoice],1.0);
-            oscposhi[nvoice]++;
-        };
+            poslo += freqlo;
+            if(poslo >= 1.0f) {
+                poslo = fmod(poslo, 1.0f);
+                poshi++;
+            }
 
-        oscposhi[nvoice]+=oscfreqhi[nvoice];
-        oscposhi[nvoice]&=OSCIL_SIZE-1;
-    };
-};
+            poshi += freqhi;
+            poshi &= synth->oscilsize - 1;
+        }
+        oscposhi[nvoice][k] = poshi;
+        oscposlo[nvoice][k] = poslo;
+    }
+}
 
 
 /*Calculeaza Oscilatorul cu PITCH MODULATION*/
-inline void ADnote::ComputeVoiceOscillatorPitchModulation(int nvoice)
+inline void ADnote::ComputeVoiceOscillatorPitchModulation(int /*nvoice*/)
 {
 //TODO
-};
+}
 
 /*
  * Computes the Noise
  */
 inline void ADnote::ComputeVoiceNoise(int nvoice)
 {
-    for (int i=0;i<SOUND_BUFFER_SIZE;i++) tmpwave[i]=RND*2.0-1.0;
-};
+    for(int k = 0; k < unison_size[nvoice]; ++k) {
+        float *tw = tmpwave_unison[k];
+        for(int i = 0; i < synth->buffersize; ++i)
+            tw[i] = RND * 2.0f - 1.0f;
+    }
+}
 
 
 
@@ -1058,234 +1432,266 @@ 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(float *outl, float *outr)
 {
-    int i,nvoice;
+    memcpy(outl, denormalkillbuf, synth->bufferbytes);
+    memcpy(outr, denormalkillbuf, synth->bufferbytes);
 
-    for (i=0;i<SOUND_BUFFER_SIZE;i++) {
-        outl[i]=denormalkillbuf[i];
-        outr[i]=denormalkillbuf[i];
-    };
-
-    if (NoteEnabled==OFF) return(0);
-
-    for (i=0;i<SOUND_BUFFER_SIZE;i++) {
-        bypassl[i]=0.0;
-        bypassr[i]=0.0;
-    };
+    if(NoteEnabled == OFF)
+        return 0;
 
+    memset(bypassl, 0, synth->bufferbytes);
+    memset(bypassr, 0, synth->bufferbytes);
     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) {
-            case MORPH:
-                ComputeVoiceOscillatorMorph(nvoice);
-                break;
-            case RING_MOD:
-                ComputeVoiceOscillatorRingModulation(nvoice);
-                break;
-            case PHASE_MOD:
-                ComputeVoiceOscillatorFrequencyModulation(nvoice,0);
-                break;
-            case FREQ_MOD:
-                ComputeVoiceOscillatorFrequencyModulation(nvoice,1);
-                break;
+    for(unsigned 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;
+                case RING_MOD:
+                    ComputeVoiceOscillatorRingModulation(nvoice);
+                    break;
+                case PHASE_MOD:
+                    ComputeVoiceOscillatorFrequencyModulation(nvoice, 0);
+                    break;
+                case FREQ_MOD:
+                    ComputeVoiceOscillatorFrequencyModulation(nvoice, 1);
+                    break;
                 //case PITCH_MOD:ComputeVoiceOscillatorPitchModulation(nvoice);break;
-            default:
-                ComputeVoiceOscillator_LinearInterpolation(nvoice);
-                //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(nvoice);
-
-            };
-        } else ComputeVoiceNoise(nvoice);
+                default:
+                    ComputeVoiceOscillator_LinearInterpolation(nvoice);
+                    //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(nvoice);
+            }
+        else
+            ComputeVoiceNoise(nvoice);
         // Voice Processing
 
+
+        //mix subvoices into voice
+        memset(tmpwavel, 0, synth->bufferbytes);
+        if(stereo)
+            memset(tmpwaver, 0, synth->bufferbytes);
+        for(int k = 0; k < unison_size[nvoice]; ++k) {
+            float *tw = tmpwave_unison[k];
+            if(stereo) {
+                float stereo_pos = 0;
+                if(unison_size[nvoice] > 1)
+                    stereo_pos = k
+                                 / (float)(unison_size[nvoice]
+                                           - 1) * 2.0f - 1.0f;
+                float stereo_spread = unison_stereo_spread[nvoice] * 2.0f; //between 0 and 2.0f
+                if(stereo_spread > 1.0f) {
+                    float stereo_pos_1 = (stereo_pos >= 0.0f) ? 1.0f : -1.0f;
+                    stereo_pos =
+                        (2.0f
+                         - stereo_spread) * stereo_pos
+                        + (stereo_spread - 1.0f) * stereo_pos_1;
+                }
+                else
+                    stereo_pos *= stereo_spread;
+
+                if(unison_size[nvoice] == 1)
+                    stereo_pos = 0.0f;
+                float panning = (stereo_pos + 1.0f) * 0.5f;
+
+
+                float lvol = (1.0f - panning) * 2.0f;
+                if(lvol > 1.0f)
+                    lvol = 1.0f;
+
+                float rvol = panning * 2.0f;
+                if(rvol > 1.0f)
+                    rvol = 1.0f;
+
+                if(unison_invert_phase[nvoice][k]) {
+                    lvol = -lvol;
+                    rvol = -rvol;
+                }
+
+                for(int i = 0; i < synth->buffersize; ++i)
+                    tmpwavel[i] += tw[i] * lvol;
+                for(int i = 0; i < synth->buffersize; ++i)
+                    tmpwaver[i] += tw[i] * rvol;
+            }
+            else
+                for(int i = 0; i < synth->buffersize; ++i)
+                    tmpwavel[i] += tw[i];
+        }
+
+
+        float unison_amplitude = 1.0f / sqrt(unison_size[nvoice]); //reduce the amplitude for large unison sizes
         // Amplitude
-        if (ABOVE_AMPLITUDE_THRESHOLD(oldamplitude[nvoice],newamplitude[nvoice])) {
-            int rest=SOUND_BUFFER_SIZE;
+        float oldam = oldamplitude[nvoice] * unison_amplitude;
+        float newam = newamplitude[nvoice] * unison_amplitude;
+
+        if(ABOVE_AMPLITUDE_THRESHOLD(oldam, newam)) {
+            int rest = synth->buffersize;
             //test if the amplitude if raising and the difference is high
-            if ((newamplitude[nvoice]>oldamplitude[nvoice])&&((newamplitude[nvoice]-oldamplitude[nvoice])>0.25)) {
-                rest=10;
-                if (rest>SOUND_BUFFER_SIZE) rest=SOUND_BUFFER_SIZE;
-                for (int i=0;i<SOUND_BUFFER_SIZE-rest;i++) tmpwave[i]*=oldamplitude[nvoice];
-            };
+            if((newam > oldam) && ((newam - oldam) > 0.25f)) {
+                rest = 10;
+                if(rest > synth->buffersize)
+                    rest = synth->buffersize;
+                for(int i = 0; i < synth->buffersize - rest; ++i)
+                    tmpwavel[i] *= oldam;
+                if(stereo)
+                    for(int i = 0; i < synth->buffersize - rest; ++i)
+                        tmpwaver[i] *= oldam;
+            }
             // Amplitude interpolation
-            for (i=0;i<rest;i++) {
-                tmpwave[i+(SOUND_BUFFER_SIZE-rest)]*=INTERPOLATE_AMPLITUDE(oldamplitude[nvoice]
-                                                     ,newamplitude[nvoice],i,rest);
-            };
-        } else for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwave[i]*=newamplitude[nvoice];
+            for(int i = 0; i < rest; ++i) {
+                float amp = INTERPOLATE_AMPLITUDE(oldam, newam, i, rest);
+                tmpwavel[i + (synth->buffersize - rest)] *= amp;
+                if(stereo)
+                    tmpwaver[i + (synth->buffersize - rest)] *= amp;
+            }
+        }
+        else {
+            for(int i = 0; i < synth->buffersize; ++i)
+                tmpwavel[i] *= newam;
+            if(stereo)
+                for(int i = 0; i < synth->buffersize; ++i)
+                    tmpwaver[i] *= newam;
+        }
 
         // Fade in
-        if (firsttick[nvoice]!=0) {
-            fadein(&tmpwave[0]);
-            firsttick[nvoice]=0;
-        };
+        if(firsttick[nvoice] != 0) {
+            fadein(&tmpwavel[0]);
+            if(stereo)
+                fadein(&tmpwaver[0]);
+            firsttick[nvoice] = 0;
+        }
 
 
         // Filter
-        if (NoteVoicePar[nvoice].VoiceFilter!=NULL) NoteVoicePar[nvoice].VoiceFilter->filterout(&tmpwave[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++)
-                    tmpwave[i]*=1.0-(REALTYPE)i/(REALTYPE)SOUND_BUFFER_SIZE;
-            //the voice is killed later
-        };
+        if(NoteVoicePar[nvoice].AmpEnvelope != NULL)
+            if(NoteVoicePar[nvoice].AmpEnvelope->finished() != 0) {
+                for(int i = 0; i < synth->buffersize; ++i)
+                    tmpwavel[i] *= 1.0f - (float)i / synth->buffersize_f;
+                if(stereo)
+                    for(int i = 0; i < synth->buffersize; ++i)
+                        tmpwaver[i] *= 1.0f - (float)i / synth->buffersize_f;
+            }
+        //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)
-            for (i=0;i<SOUND_BUFFER_SIZE;i++) NoteVoicePar[nvoice].VoiceOut[i]=tmpwave[i];
+        if(NoteVoicePar[nvoice].VoiceOut != NULL) {
+            if(stereo)
+                for(int i = 0; i < synth->buffersize; ++i)
+                    NoteVoicePar[nvoice].VoiceOut[i] = tmpwavel[i]
+                                                       + tmpwaver[i];
+            else   //mono
+                for(int i = 0; i < synth->buffersize; ++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==0) for (i=0;i<SOUND_BUFFER_SIZE;i++) outl[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume;//mono
-            else for (i=0;i<SOUND_BUFFER_SIZE;i++) {//stereo
-                    outl[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume*NoteVoicePar[nvoice].Panning*2.0;
-                    outr[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume*(1.0-NoteVoicePar[nvoice].Panning)*2.0;
-                };
-        } else {//bypass the filter
-            if (stereo==0) for (i=0;i<SOUND_BUFFER_SIZE;i++) bypassl[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume;//mono
-            else for (i=0;i<SOUND_BUFFER_SIZE;i++) {//stereo
-                    bypassl[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume*NoteVoicePar[nvoice].Panning*2.0;
-                    bypassr[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume*(1.0-NoteVoicePar[nvoice].Panning)*2.0;
-                };
-        };
+        if(NoteVoicePar[nvoice].filterbypass == 0) { //no bypass
+            if(stereo)
+                for(int i = 0; i < synth->buffersize; ++i) { //stereo
+                    outl[i] += tmpwavel[i] * NoteVoicePar[nvoice].Volume
+                               * NoteVoicePar[nvoice].Panning * 2.0f;
+                    outr[i] += tmpwaver[i] * NoteVoicePar[nvoice].Volume
+                               * (1.0f - NoteVoicePar[nvoice].Panning) * 2.0f;
+                }
+            else
+                for(int i = 0; i < synth->buffersize; ++i) //mono
+                    outl[i] += tmpwavel[i] * NoteVoicePar[nvoice].Volume;
+        }
+        else {  //bypass the filter
+            if(stereo)
+                for(int i = 0; i < synth->buffersize; ++i) { //stereo
+                    bypassl[i] += tmpwavel[i] * NoteVoicePar[nvoice].Volume
+                                  * NoteVoicePar[nvoice].Panning * 2.0f;
+                    bypassr[i] += tmpwaver[i] * NoteVoicePar[nvoice].Volume
+                                  * (1.0f
+                                     - NoteVoicePar[nvoice].Panning) * 2.0f;
+                }
+            else
+                for(int i = 0; i < synth->buffersize; ++i) //mono
+                    bypassl[i] += tmpwavel[i] * NoteVoicePar[nvoice].Volume;
+        }
         // 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];
-        }
-    } else NoteGlobalPar.GlobalFilterR->filterout(&outr[0]);
+    if(stereo == 0) { //set the right channel=left channel
+        memcpy(outr, outl, synth->bufferbytes);
+        memcpy(bypassr, bypassl, synth->bufferbytes);
+    }
+    else
+        NoteGlobalPar.GlobalFilterR->filterout(&outr[0]);
 
-    for (i=0;i<SOUND_BUFFER_SIZE;i++) {
-        outl[i]+=bypassl[i];
-        outr[i]+=bypassr[i];
-    };
+    for(int i = 0; i < synth->buffersize; ++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);
-        };
-    };
-
-//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;
-                break;
-            };
-        };
-    };
-
-
-    // Apply legato-specific sound signal modifications
-    if (Legato.silent) { // Silencer
-        if (Legato.msg!=LM_FadeIn) {
-            for (i=0;i<SOUND_BUFFER_SIZE;i++) {
-                outl[i]=0.0;
-                outr[i]=0.0;
-            }
+        for(int i = 0; i < synth->buffersize; ++i) {
+            float tmpvol = INTERPOLATE_AMPLITUDE(globaloldamplitude,
+                                                 globalnewamplitude,
+                                                 i,
+                                                 synth->buffersize);
+            outl[i] *= tmpvol * NoteGlobalPar.Panning;
+            outr[i] *= tmpvol * (1.0f - NoteGlobalPar.Panning);
         }
-    }
-    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) {
-                // 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);
-                break;
-            }
+    else
+        for(int i = 0; i < synth->buffersize; ++i) {
+            outl[i] *= globalnewamplitude * NoteGlobalPar.Panning;
+            outr[i] *= globalnewamplitude * (1.0f - NoteGlobalPar.Panning);
         }
-        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++) {
-            Legato.decounter--;
-            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;
-        }
-        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++) {
-            Legato.decounter--;
-            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;
-                // 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);
+
+    //Apply the punch
+    if(NoteGlobalPar.Punch.Enabled != 0)
+        for(int i = 0; i < synth->buffersize; ++i) {
+            float punchamp = NoteGlobalPar.Punch.initialvalue
+                             * NoteGlobalPar.Punch.t + 1.0f;
+            outl[i] *= punchamp;
+            outr[i] *= punchamp;
+            NoteGlobalPar.Punch.t -= NoteGlobalPar.Punch.dt;
+            if(NoteGlobalPar.Punch.t < 0.0f) {
+                NoteGlobalPar.Punch.Enabled = 0;
                 break;
             }
-            Legato.fade.m-=Legato.fade.step;
-            outl[i]*=Legato.fade.m;
-            outr[i]*=Legato.fade.m;
         }
-        break;
-    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;
-        };
+    // Apply legato-specific sound signal modifications
+    legato.apply(*this, outl, outr);
+
+
+    // Check if the global amplitude is finished.
+    // If it does, disable the note
+    if(NoteGlobalPar.AmpEnvelope->finished()) {
+        for(int i = 0; i < synth->buffersize; ++i) { //fade-out
+            float tmp = 1.0f - (float)i / synth->buffersize_f;
+            outl[i] *= tmp;
+            outr[i] *= tmp;
+        }
         KillNote();
-    };
-    return(1);
-};
+    }
+    return 1;
+}
 
 
 /*
@@ -1293,29 +1699,102 @@ 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(int nvoice = 0; nvoice < NUM_VOICES; ++nvoice)
+        NoteVoicePar[nvoice].releasekey();
     NoteGlobalPar.FreqEnvelope->relasekey();
     NoteGlobalPar.FilterEnvelope->relasekey();
     NoteGlobalPar.AmpEnvelope->relasekey();
-
-};
+}
 
 /*
  * Check if the note is finished
  */
-int ADnote::finished()
+int ADnote::finished() const
 {
-    if (NoteEnabled==ON) return(0);
-    else return(1);
-};
+    if(NoteEnabled == ON)
+        return 0;
+    else
+        return 1;
+}
+
+void ADnote::Voice::releasekey()
+{
+    if(!Enabled)
+        return;
+    if(AmpEnvelope)
+        AmpEnvelope->relasekey();
+    if(FreqEnvelope)
+        FreqEnvelope->relasekey();
+    if(FilterEnvelope)
+        FilterEnvelope->relasekey();
+    if(FMFreqEnvelope)
+        FMFreqEnvelope->relasekey();
+    if(FMAmpEnvelope)
+        FMAmpEnvelope->relasekey();
+}
+
+template<class T>
+static inline void nullify(T &t) {delete t; t = NULL; }
+template<class T>
+static inline void arrayNullify(T &t) {delete [] t; t = NULL; }
+
+void ADnote::Voice::kill()
+{
+    arrayNullify(OscilSmp);
+    nullify(FreqEnvelope);
+    nullify(FreqLfo);
+    nullify(AmpEnvelope);
+    nullify(AmpLfo);
+    nullify(VoiceFilterL);
+    nullify(VoiceFilterR);
+    nullify(FilterEnvelope);
+    nullify(FilterLfo);
+    nullify(FMFreqEnvelope);
+    nullify(FMAmpEnvelope);
+
+    if((FMEnabled != NONE) && (FMVoice < 0)) {
+        delete[] FMSmp;
+        FMSmp = NULL;
+    }
+
+    if(VoiceOut)
+        memset(VoiceOut, 0, synth->bufferbytes);
+    //do not delete, yet: perhaps is used by another voice
+
+    Enabled = OFF;
+}
+
+void ADnote::Global::kill()
+{
+    nullify(FreqEnvelope);
+    nullify(FreqLfo);
+    nullify(AmpEnvelope);
+    nullify(AmpLfo);
+    nullify(GlobalFilterL);
+    nullify(GlobalFilterR);
+    nullify(FilterEnvelope);
+    nullify(FilterLfo);
+}
+
+void ADnote::Global::initparameters(const ADnoteGlobalParam &param,
+                                    float basefreq, float velocity,
+                                    bool stereo)
+{
+    FreqEnvelope = new Envelope(param.FreqEnvelope, basefreq);
+    FreqLfo      = new LFO(param.FreqLfo, basefreq);
+
+    AmpEnvelope = new Envelope(param.AmpEnvelope, basefreq);
+    AmpLfo      = new LFO(param.AmpLfo, basefreq);
 
+    Volume = 4.0f * powf(0.1f, 3.0f * (1.0f - param.PVolume / 96.0f)) //-60 dB .. 0 dB
+             * VelF(velocity, param.PAmpVelocityScaleFunction);     //sensing
 
+    GlobalFilterL = Filter::generate(param.GlobalFilter);
+    if(stereo)
+        GlobalFilterR = Filter::generate(param.GlobalFilter);
 
+    FilterEnvelope = new Envelope(param.FilterEnvelope, basefreq);
+    FilterLfo      = new LFO(param.FilterLfo, basefreq);
+    FilterQ = param.GlobalFilter->getq();
+    FilterFreqTracking = param.GlobalFilter->getfreqtracking(basefreq);
+}
diff --git a/src/Synth/ADnote.h b/src/Synth/ADnote.h
index 1ec2583..53420ee 100644
--- a/src/Synth/ADnote.h
+++ b/src/Synth/ADnote.h
@@ -23,257 +23,303 @@
 #ifndef AD_NOTE_H
 #define AD_NOTE_H
 
-#include "../globals.h"
+#include "SynthNote.h"
 #include "Envelope.h"
 #include "LFO.h"
-#include "../DSP/Filter.h"
 #include "../Params/ADnoteParameters.h"
 #include "../Params/Controller.h"
 
 //Globals
 
 /**FM amplitude tune*/
-#define FM_AMP_MULTIPLIER 14.71280603
+#define FM_AMP_MULTIPLIER 14.71280603f
 
 #define OSCIL_SMP_EXTRA_SAMPLES 5
 
 /**The "additive" synthesizer*/
-class ADnote    //ADDitive note
+class ADnote:public SynthNote
 {
-public:
-    ADnote(ADnoteParameters *pars,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote_,bool besilent);//(gf)Added the besilent parameter to tell it to start silent (if true).
-    ~ADnote();
+    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_, float freq,
+               float velocity, int portamento_, int midinote_,
+               bool besilent);
+        /**Destructor*/
+        ~ADnote();
+
+        /**Alters the playing note for legato effect*/
+        void legatonote(float freq, float velocity, int portamento_,
+                        int midinote_, bool externcall);
+
+        int noteout(float *outl, float *outr);
+        void relasekey();
+        int finished() const;
+    private:
+
+        /**Changes the frequency of an oscillator.
+         * @param nvoice voice to run computations on
+         * @param in_freq new frequency*/
+        void setfreq(int nvoice, float in_freq);
+        /**Set the frequency of the modulator oscillator*/
+        void setfreqFM(int nvoice, float 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 float getvoicebasefreq(int nvoice) const;
+        /**Get modulator's base frequency*/
+        inline float 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);
+        //  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(float *smps) const;
+
+
+        //GLOBALS
+        ADnoteParameters *partparams;
+        unsigned char     stereo; //if the note is stereo (allows note Panning)
+        int   midinote;
+        float velocity, basefreq;
+
+        ONOFFTYPE   NoteEnabled;
+        Controller *ctl;
+
+        /*****************************************************************/
+        /*                    GLOBAL PARAMETERS                          */
+        /*****************************************************************/
+
+        struct Global {
+            void kill();
+            void initparameters(const ADnoteGlobalParam &param,
+                                float basefreq, float velocity,
+                                bool stereo);
+            /******************************************
+            *     FREQUENCY GLOBAL PARAMETERS        *
+            ******************************************/
+            float Detune;  //cents
+
+            Envelope *FreqEnvelope;
+            LFO      *FreqLfo;
+
+            /********************************************
+            *     AMPLITUDE GLOBAL PARAMETERS          *
+            ********************************************/
+            float Volume;  // [ 0 .. 1 ]
+
+            float Panning;  // [ 0 .. 1 ]
+
+            Envelope *AmpEnvelope;
+            LFO      *AmpLfo;
+
+            struct {
+                int   Enabled;
+                float initialvalue, dt, t;
+            } Punch;
+
+            /******************************************
+            *        FILTER GLOBAL PARAMETERS        *
+            ******************************************/
+            class Filter * GlobalFilterL, *GlobalFilterR;
+
+            float FilterCenterPitch;  //octaves
+            float FilterQ;
+            float FilterFreqTracking;
+
+            Envelope *FilterEnvelope;
+
+            LFO *FilterLfo;
+        } NoteGlobalPar;
+
+
 
-    void ADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote_, bool externcall);
+        /***********************************************************/
+        /*                    VOICE PARAMETERS                     */
+        /***********************************************************/
+        struct Voice {
+            void releasekey();
+            void kill();
+            /* If the voice is enabled */
+            ONOFFTYPE Enabled;
 
-    int noteout(REALTYPE *outl,REALTYPE *outr);
-    void relasekey();
-    int finished();
+            /* Voice Type (sound/noise)*/
+            int noisetype;
 
+            /* Filter Bypass */
+            int filterbypass;
 
-    /*ready - this is 0 if it is not ready (the parameters has to be computed)
-     or other value if the parameters has been computed and if it is ready to output*/
-    char ready;
+            /* Delay (ticks) */
+            int DelayTicks;
 
-private:
+            /* Waveform of the Voice */
+            float *OscilSmp;
 
-    void setfreq(int nvoice,REALTYPE freq);
-    void setfreqFM(int nvoice,REALTYPE freq);
-    void computecurrentparameters();
-    void initparameters();
-    void KillVoice(int nvoice);
-    void KillNote();
-    inline REALTYPE getvoicebasefreq(int nvoice);
-    inline REALTYPE getFMvoicebasefreq(int nvoice);
-    inline void ComputeVoiceOscillator_LinearInterpolation(int nvoice);
-    inline void ComputeVoiceOscillator_CubicInterpolation(int nvoice);
-    inline void ComputeVoiceOscillatorMorph(int nvoice);
-    inline void ComputeVoiceOscillatorRingModulation(int nvoice);
-    inline void ComputeVoiceOscillatorFrequencyModulation(int nvoice,int FMmode);//FMmode=0 for phase modulation, 1 for Frequency modulation
-    //  inline void ComputeVoiceOscillatorFrequencyModulation(int nvoice);
-    inline void ComputeVoiceOscillatorPitchModulation(int nvoice);
+            /************************************
+            *     FREQUENCY PARAMETERS          *
+            ************************************/
+            int fixedfreq; //if the frequency is fixed to 440 Hz
+            int fixedfreqET; //if the "fixed" frequency varies according to the note (ET)
 
-    inline void ComputeVoiceNoise(int nvoice);
+            // cents = basefreq*VoiceDetune
+            float Detune, FineDetune;
 
-    inline void fadein(REALTYPE *smps);
+            Envelope *FreqEnvelope;
+            LFO      *FreqLfo;
 
 
-    //GLOBALS
-    ADnoteParameters *partparams;
-    unsigned char stereo;//if the note is stereo (allows note Panning)
-    int midinote;
-    REALTYPE velocity,basefreq;
+            /***************************
+            *   AMPLITUDE PARAMETERS   *
+            ***************************/
 
-    ONOFFTYPE NoteEnabled;
-    Controller *ctl;
+            /* Panning 0.0f=left, 0.5f - center, 1.0f = right */
+            float Panning;
+            float Volume;  // [-1.0f .. 1.0f]
 
-    /*****************************************************************/
-    /*                    GLOBAL PARAMETERS                          */
-    /*****************************************************************/
+            Envelope *AmpEnvelope;
+            LFO      *AmpLfo;
 
-    struct ADnoteGlobal {
-        /******************************************
-        *     FREQUENCY GLOBAL PARAMETERS        *
-        ******************************************/
-        REALTYPE Detune;//cents
+            /*************************
+            *   FILTER PARAMETERS    *
+            *************************/
 
-        Envelope *FreqEnvelope;
-        LFO *FreqLfo;
+            class Filter * VoiceFilterL;
+            class Filter * VoiceFilterR;
 
-        /********************************************
-        *     AMPLITUDE GLOBAL PARAMETERS          *
-        ********************************************/
-        REALTYPE Volume;// [ 0 .. 1 ]
+            float FilterCenterPitch;  /* Filter center Pitch*/
+            float FilterFreqTracking;
 
-        REALTYPE Panning;// [ 0 .. 1 ]
+            Envelope *FilterEnvelope;
+            LFO      *FilterLfo;
 
-        Envelope *AmpEnvelope;
-        LFO *AmpLfo;
 
-        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;
-
-
-
-    /***********************************************************/
-    /*                    VOICE PARAMETERS                     */
-    /***********************************************************/
-    struct ADnoteVoice {
-        /* If the voice is enabled */
-        ONOFFTYPE Enabled;
-
-        /* Voice Type (sound/noise)*/
-        int noisetype;
-
-        /* Filter Bypass */
-        int filterbypass;
-
-        /* Delay (ticks) */
-        int DelayTicks;
-
-        /* Waveform of the Voice */
-        REALTYPE *OscilSmp;
+            /****************************
+            *   MODULLATOR PARAMETERS   *
+            ****************************/
 
-        /************************************
-        *     FREQUENCY PARAMETERS          *
-        ************************************/
-        int fixedfreq;//if the frequency is fixed to 440 Hz
-        int fixedfreqET;//if the "fixed" frequency varies according to the note (ET)
+            FMTYPE FMEnabled;
 
-        // cents = basefreq*VoiceDetune
-        REALTYPE Detune,FineDetune;
+            int FMVoice;
 
-        Envelope *FreqEnvelope;
-        LFO *FreqLfo;
+            // Voice Output used by other voices if use this as modullator
+            float *VoiceOut;
 
+            /* Wave of the Voice */
+            float *FMSmp;
 
-        /***************************
-        *   AMPLITUDE PARAMETERS   *
-        ***************************/
+            float FMVolume;
+            float FMDetune;  //in cents
 
-        /* Panning 0.0=left, 0.5 - center, 1.0 = right */
-        REALTYPE Panning;
-        REALTYPE Volume;// [-1.0 .. 1.0]
+            Envelope *FMFreqEnvelope;
+            Envelope *FMAmpEnvelope;
+        } NoteVoicePar[NUM_VOICES];
 
-        Envelope *AmpEnvelope;
-        LFO *AmpLfo;
 
-        /*************************
-        *   FILTER PARAMETERS    *
-        *************************/
+        /********************************************************/
+        /*    INTERNAL VALUES OF THE NOTE AND OF THE VOICES     */
+        /********************************************************/
 
-        Filter *VoiceFilter;
+        //time from the start of the note
+        float time;
 
-        REALTYPE FilterCenterPitch;/* Filter center Pitch*/
-        REALTYPE FilterFreqTracking;
+        //the size of unison for a single voice
+        int unison_size[NUM_VOICES];
 
-        Envelope *FilterEnvelope;
-        LFO *FilterLfo;
+        //the stereo spread of the unison subvoices (0.0f=mono,1.0f=max)
+        float unison_stereo_spread[NUM_VOICES];
 
+        //fractional part (skip)
+        float *oscposlo[NUM_VOICES], *oscfreqlo[NUM_VOICES];
 
-        /****************************
-        *   MODULLATOR PARAMETERS   *
-        ****************************/
+        //integer part (skip)
+        int *oscposhi[NUM_VOICES], *oscfreqhi[NUM_VOICES];
 
-        FMTYPE FMEnabled;
+        //fractional part (skip) of the Modullator
+        float *oscposloFM[NUM_VOICES], *oscfreqloFM[NUM_VOICES];
 
-        int FMVoice;
+        //the unison base_value
+        float *unison_base_freq_rap[NUM_VOICES];
 
-        // Voice Output used by other voices if use this as modullator
-        REALTYPE *VoiceOut;
+        //how the unison subvoice's frequency is changed (1.0f for no change)
+        float *unison_freq_rap[NUM_VOICES];
 
-        /* Wave of the Voice */
-        REALTYPE *FMSmp;
+        //which subvoice has phase inverted
+        bool *unison_invert_phase[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;
-
-    //fractional part (skip)
-    REALTYPE oscposlo[NUM_VOICES],oscfreqlo[NUM_VOICES];
-
-    //integer part (skip)
-    int oscposhi[NUM_VOICES],oscfreqhi[NUM_VOICES];
-
-    //fractional part (skip) of the Modullator
-    REALTYPE oscposloFM[NUM_VOICES],oscfreqloFM[NUM_VOICES];
+        //unison vibratto
+        struct {
+            float  amplitude; //amplitude which be added to unison_freq_rap
+            float *step; //value which increments the position
+            float *position; //between -1.0f and 1.0f
+        } unison_vibratto[NUM_VOICES];
 
-    //integer part (skip) of the Modullator
-    unsigned short int oscposhiFM[NUM_VOICES],oscfreqhiFM[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];
+        //integer part (skip) of the Modullator
+        unsigned int *oscposhiFM[NUM_VOICES], *oscfreqhiFM[NUM_VOICES];
 
-    //used by Frequency Modulation (for integration)
-    REALTYPE FMoldsmp[NUM_VOICES];
+        //used to compute and interpolate the amplitudes of voices and modullators
+        float oldamplitude[NUM_VOICES],
+              newamplitude[NUM_VOICES],
+              FMoldamplitude[NUM_VOICES],
+              FMnewamplitude[NUM_VOICES];
 
-    //temporary buffer
-    REALTYPE *tmpwave;
+        //used by Frequency Modulation (for integration)
+        float *FMoldsmp[NUM_VOICES];
 
-    //Filter bypass samples
-    REALTYPE *bypassl,*bypassr;
+        //temporary buffer
+        float  *tmpwavel;
+        float  *tmpwaver;
+        int     max_unison;
+        float **tmpwave_unison;
 
-    //interpolate the amplitudes
-    REALTYPE globaloldamplitude,globalnewamplitude;
+        //Filter bypass samples
+        float *bypassl, *bypassr;
 
-    //1 - if it is the fitst tick (used to fade in the sound)
-    char firsttick[NUM_VOICES];
+        //interpolate the amplitudes
+        float globaloldamplitude, globalnewamplitude;
 
-    //1 if the note has portamento
-    int portamento;
+        //1 - if it is the fitst tick (used to fade in the sound)
+        char firsttick[NUM_VOICES];
 
-    //how the fine detunes are made bigger or smaller
-    REALTYPE bandwidthDetuneMultiplier;
+        //1 if the note has portamento
+        int portamento;
 
-    // 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;
+        //how the fine detunes are made bigger or smaller
+        float bandwidthDetuneMultiplier;
 };
 
 #endif
-
-
-
-
diff --git a/src/Synth/CMakeLists.txt b/src/Synth/CMakeLists.txt
new file mode 100644
index 0000000..34b0223
--- /dev/null
+++ b/src/Synth/CMakeLists.txt
@@ -0,0 +1,17 @@
+set(zynaddsubfx_synth_SRCS
+	SynthNote.cpp
+	ADnote.cpp
+	Envelope.cpp
+	LFO.cpp
+	OscilGen.cpp
+	PADnote.cpp
+	Resonance.cpp
+	SUBnote.cpp
+)
+
+add_library(zynaddsubfx_synth STATIC
+	${zynaddsubfx_synth_SRCS} 
+	)
+
+target_link_libraries(zynaddsubfx_synth)
+
diff --git a/src/Synth/Envelope.cpp b/src/Synth/Envelope.cpp
index 83450e3..d03a2d6 100644
--- a/src/Synth/Envelope.cpp
+++ b/src/Synth/Envelope.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  Envelope.C - Envelope implementation
+  Envelope.cpp - Envelope implementation
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -20,67 +20,76 @@
 
 */
 
-#include <stdio.h>
+#include <cmath>
 #include "Envelope.h"
+#include "../Params/EnvelopeParams.h"
 
-Envelope::Envelope(EnvelopeParams *envpars,REALTYPE basefreq)
+Envelope::Envelope(EnvelopeParams *envpars, float 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     = powf(440.0f / basefreq, envpars->Penvstretch / 64.0f);
+    linearenvelope = envpars->Plinearenvelope;
 
-    if (envpars->Pfreemode==0) envpars->converttofree();
+    if(envpars->Pfreemode == 0)
+        envpars->converttofree();
 
-    REALTYPE bufferdt=SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE;
+    float bufferdt = synth->buffersize_f / synth->samplerate_f;
 
-    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) {
-        case 2:
-            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];
-            break;
-        case 4:
-            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;
-            break;
-        default:
-            envval[i]=envpars->Penvval[i]/127.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;
-};
+    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) {
+        float tmp = envpars->getdt(i) / 1000.0f * envstretch;
+        if(tmp > bufferdt)
+            envdt[i] = bufferdt / tmp;
+        else
+            envdt[i] = 2.0f;  //any value larger than 1
+
+        switch(mode) {
+            case 2:
+                envval[i] = (1.0f - envpars->Penvval[i] / 127.0f) * -40;
+                break;
+            case 3:
+                envval[i] =
+                    (powf(2, 6.0f
+                          * fabs(envpars->Penvval[i]
+                                 - 64.0f) / 64.0f) - 1.0f) * 100.0f;
+                if(envpars->Penvval[i] < 64)
+                    envval[i] = -envval[i];
+                break;
+            case 4:
+                envval[i] = (envpars->Penvval[i] - 64.0f) / 64.0f * 6.0f; //6 octaves (filtru)
+                break;
+            case 5:
+                envval[i] = (envpars->Penvval[i] - 64.0f) / 64.0f * 10;
+                break;
+            default:
+                envval[i] = envpars->Penvval[i] / 127.0f;
+        }
+    }
+
+    envdt[0] = 1.0f;
+
+    currentpoint = 1; //the envelope starts from 1
+    keyreleased  = false;
+    t = 0.0f;
+    envfinish = false;
+    inct      = envdt[1];
+    envoutval = 0.0f;
+}
 
 Envelope::~Envelope()
-{
-};
+{}
 
 
 /*
@@ -88,89 +97,102 @@ Envelope::~Envelope()
  */
 void Envelope::relasekey()
 {
-    if (keyreleased==1) return;
-    keyreleased=1;
-    if (forcedrelase!=0) t=0.0;
-};
+    if(keyreleased)
+        return;
+    keyreleased = true;
+    if(forcedrelase != 0)
+        t = 0.0f;
+}
 
 /*
  * Envelope Output
  */
-REALTYPE Envelope::envout()
+float 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);
-};
+    float out;
+
+    if(envfinish) { //if the envelope is finished
+        envoutval = envval[envpoints - 1];
+        return envoutval;
+    }
+    if((currentpoint == envsustain + 1) && !keyreleased) { //if it is sustaining now
+        envoutval = envval[envsustain];
+        return envoutval;
+    }
+
+    if(keyreleased && (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.00000001f)
+            out = envval[tmp];
+        else
+            out = envoutval + (envval[tmp] - envoutval) * t;
+        t += envdt[tmp] * envstretch;
+
+        if(t >= 1.0f) {
+            currentpoint = envsustain + 2;
+            forcedrelase = 0;
+            t    = 0.0f;
+            inct = envdt[currentpoint];
+            if((currentpoint >= envpoints) || (envsustain < 0))
+                envfinish = true;
+        }
+        return out;
+    }
+    if(inct >= 1.0f)
+        out = envval[currentpoint];
+    else
+        out = envval[currentpoint - 1]
+              + (envval[currentpoint] - envval[currentpoint - 1]) * t;
+
+    t += inct;
+    if(t >= 1.0f) {
+        if(currentpoint >= envpoints - 1)
+            envfinish = true;
+        else
+            currentpoint++;
+        t    = 0.0f;
+        inct = envdt[currentpoint];
+    }
+
+    envoutval = out;
+    return out;
+}
 
 /*
  * Envelope Output (dB)
  */
-REALTYPE Envelope::envout_dB()
+float 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];
+    float out;
+    if(linearenvelope != 0)
+        return envout();
+
+    if((currentpoint == 1) && (!keyreleased || (forcedrelase == 0))) { //first point is always lineary interpolated
+        float v1 = dB2rap(envval[0]);
+        float v2 = dB2rap(envval[1]);
+        out = v1 + (v2 - v1) * t;
+
+        t += inct;
+        if(t >= 1.0f) {
+            t    = 0.0f;
+            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.001f)
+            envoutval = rap2dB(out);
+        else
+            envoutval = MIN_ENVELOPE_DB;
+    }
+    else
+        out = dB2rap(envout());
 
-    return(out);
-};
+    return out;
+}
 
-int Envelope::finished()
+bool Envelope::finished() const
 {
-    return(envfinish);
-};
-
+    return envfinish;
+}
diff --git a/src/Synth/Envelope.h b/src/Synth/Envelope.h
index 60a17ed..ee75e0a 100644
--- a/src/Synth/Envelope.h
+++ b/src/Synth/Envelope.h
@@ -23,44 +23,40 @@
 #ifndef ENVELOPE_H
 #define ENVELOPE_H
 
-#include <math.h>
 #include "../globals.h"
 #include "../Params/EnvelopeParams.h"
 
 /**Implementation of a general Envelope*/
 class Envelope
 {
-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;
-
-    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
+    public:
+
+        /**Constructor*/
+        Envelope(class EnvelopeParams *envpars, float basefreq);
+        /**Destructor*/
+        ~Envelope();
+        void relasekey();
+        float envout();
+        float envout_dB();
+        /**Determines the status of the Envelope
+         * @return returns 1 if the envelope is finished*/
+        bool finished() const;
+    private:
+        int   envpoints;
+        int   envsustain;    //"-1" means disabled
+        float envdt[MAX_ENVELOPE_POINTS]; //millisecons
+        float envval[MAX_ENVELOPE_POINTS]; // [0.0f .. 1.0f]
+        float envstretch;
+        int   linearenvelope;
+
+        int   currentpoint;    //current envelope point (starts from 1)
+        int   forcedrelase;
+        bool  keyreleased;    //if the key was released
+        bool  envfinish;
+        float t; // the time from the last point
+        float inct; // the time increment
+        float envoutval; //used to do the forced release
 };
 
 
 #endif
-
diff --git a/src/Synth/LFO.cpp b/src/Synth/LFO.cpp
index 3c1d996..af9d10d 100644
--- a/src/Synth/LFO.cpp
+++ b/src/Synth/LFO.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  LFO.C - LFO implementation
+  LFO.cpp - LFO implementation
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -20,138 +20,164 @@
 
 */
 
+#include "LFO.h"
+#include "../Misc/Util.h"
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <math.h>
 
-#include "LFO.h"
-
-
-LFO::LFO(LFOParams *lfopars,REALTYPE basefreq)
+LFO::LFO(LFOParams *lfopars, float 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;
+    float lfostretch = powf(basefreq / 440.0f,
+                            (lfopars->Pstretch - 64.0f) / 63.0f);           //max 2x/octave
+
+    float lfofreq =
+        (powf(2, lfopars->Pfreq * 10.0f) - 1.0f) / 12.0f * lfostretch;
+    incx = fabs(lfofreq) * synth->buffersize_f / synth->samplerate_f;
+
+    if(lfopars->Pcontinous == 0) {
+        if(lfopars->Pstartphase == 0)
+            x = RND;
+        else
+            x = fmod((lfopars->Pstartphase - 64.0f) / 127.0f + 1.0f, 1.0f);
+    }
+    else {
+        float tmp = fmod(lfopars->time * incx, 1.0f);
+        x = fmod((lfopars->Pstartphase - 64.0f) / 127.0f + 1.0f + tmp, 1.0f);
+    }
 
     //Limit the Frequency(or else...)
-    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;
-
-//    lfofreqrnd=pow(lfopars->Pfreqrand/127.0,2.0)*2.0*4.0;
-    lfofreqrnd=pow(lfopars->Pfreqrand/127.0,2.0)*4.0;
-
-    switch (lfopars->fel) {
-    case 1:
-        lfointensity=lfopars->Pintensity/127.0;
-        break;
-    case 2:
-        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
-        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);
+    if(incx > 0.49999999f)
+        incx = 0.499999999f;
+
+
+    lfornd = lfopars->Prandomness / 127.0f;
+    if(lfornd < 0.0f)
+        lfornd = 0.0f;
+    else
+    if(lfornd > 1.0f)
+        lfornd = 1.0f;
+
+//    lfofreqrnd=powf(lfopars->Pfreqrand/127.0f,2.0f)*2.0f*4.0f;
+    lfofreqrnd = powf(lfopars->Pfreqrand / 127.0f, 2.0f) * 4.0f;
+
+    switch(lfopars->fel) {
+        case 1:
+            lfointensity = lfopars->Pintensity / 127.0f;
+            break;
+        case 2:
+            lfointensity = lfopars->Pintensity / 127.0f * 4.0f;
+            break; //in octave
+        default:
+            lfointensity = powf(2, lfopars->Pintensity / 127.0f * 11.0f) - 1.0f; //in centi
+            x -= 0.25f; //chance the starting phase
+            break;
+    }
+
+    amp1     = (1 - lfornd) + lfornd * RND;
+    amp2     = (1 - lfornd) + lfornd * RND;
+    lfotype  = lfopars->PLFOtype;
+    lfodelay = lfopars->Pdelay / 127.0f * 4.0f; //0..4 sec
+    incrnd   = nextincrnd = 1.0f;
+    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
  */
-REALTYPE LFO::lfoout()
+float LFO::lfoout()
 {
-    REALTYPE out;
-    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;
-        break;
-    case 2: //LFO_SQUARE
-        if (x<0.5) out=-1;
-        else   out=1;
-        break;
-    case 3: //LFO_RAMPUP
-        out=(x-0.5)*2.0;
-        break;
-    case 4: //LFO_RAMPDOWN
-        out=(0.5-x)*2.0;
-        break;
-    case 5: //LFO_EXP_DOWN 1
-        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;
-        break;
-    default:
-        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;
+    float out;
+    switch(lfotype) {
+        case 1: //LFO_TRIANGLE
+            if((x >= 0.0f) && (x < 0.25f))
+                out = 4.0f * x;
+            else
+            if((x > 0.25f) && (x < 0.75f))
+                out = 2 - 4 * x;
+            else
+                out = 4.0f * x - 4.0f;
+            break;
+        case 2: //LFO_SQUARE
+            if(x < 0.5f)
+                out = -1;
+            else
+                out = 1;
+            break;
+        case 3: //LFO_RAMPUP
+            out = (x - 0.5f) * 2.0f;
+            break;
+        case 4: //LFO_RAMPDOWN
+            out = (0.5f - x) * 2.0f;
+            break;
+        case 5: //LFO_EXP_DOWN 1
+            out = powf(0.05f, x) * 2.0f - 1.0f;
+            break;
+        case 6: //LFO_EXP_DOWN 2
+            out = powf(0.001f, x) * 2.0f - 1.0f;
+            break;
+        default:
+            out = cosf(x * 2.0f * PI); //LFO_SINE
+    }
+
+
+    if((lfotype == 0) || (lfotype == 1))
+        out *= lfointensity * (amp1 + x * (amp2 - amp1));
+    else
+        out *= lfointensity * amp2;
+    if(lfodelay < 0.00001f) {
+        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.0f - x) + nextincrnd * x);
+            if(tmp > 1.0f)
+                tmp = 1.0f;
+            else
+            if(tmp < 0.0f)
+                tmp = 0.0f;
+            x += incx * tmp;
+        }
+        if(x >= 1) {
+            x    = fmod(x, 1.0f);
+            amp1 = amp2;
+            amp2 = (1 - lfornd) + lfornd * RND;
 
             computenextincrnd();
-        };
-    } else lfodelay-=(REALTYPE)SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE;
-    return(out);
-};
+        }
+    }
+    else
+        lfodelay -= synth->buffersize_f / synth->samplerate_f;
+    return out;
+}
 
 /*
  * LFO out (for amplitude)
  */
-REALTYPE LFO::amplfoout()
+float 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);
-};
+    float out;
+    out = 1.0f - lfointensity + lfoout();
+    if(out < -1.0f)
+        out = -1.0f;
+    else
+    if(out > 1.0f)
+        out = 1.0f;
+    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 = powf(0.5f, lfofreqrnd) + RND * (powf(2.0f, lfofreqrnd) - 1.0f);
+}
diff --git a/src/Synth/LFO.h b/src/Synth/LFO.h
index 12d0132..2b933a3 100644
--- a/src/Synth/LFO.h
+++ b/src/Synth/LFO.h
@@ -29,32 +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, float basefreq);
+        /**Deconstructor*/
+        ~LFO();
+        float lfoout();
+        float amplfoout();
+    private:
+        float x;
+        float incx, incrnd, nextincrnd;
+        float amp1, amp2; // used for randomness
+        float lfointensity;
+        float lfornd, lfofreqrnd;
+        float lfodelay;
+        /**\todo see if an enum would be better here*/
+        char lfotype;
+        int  freqrndenabled;
+
+
+        void computenextincrnd();
 };
 
 #endif
-
diff --git a/src/Synth/Makefile b/src/Synth/Makefile
deleted file mode 100644
index dc8924e..0000000
--- a/src/Synth/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-include ../Makefile.inc
-
-objects=ADnote.o Envelope.o LFO.o OscilGen.o SUBnote.o Resonance.o PADnote.o
-
-
-all: $(objects)
-
--include ../Make.deps
-
-.PHONY : clean
-clean: 
-	rm -f $(objects)
-	rm -f makeinclude.deps
-
diff --git a/src/Synth/OscilGen.cpp b/src/Synth/OscilGen.cpp
index b708ba7..3351d82 100644
--- a/src/Synth/OscilGen.cpp
+++ b/src/Synth/OscilGen.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  OscilGen.C - Waveform generator for ADnote
+  OscilGen.cpp - Waveform generator for ADnote
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -20,527 +20,381 @@
 
 */
 
+#include "OscilGen.h"
+#include "../Misc/WaveShapeSmps.h"
+
+#include <cassert>
 #include <stdlib.h>
 #include <math.h>
 #include <stdio.h>
 
-#include "OscilGen.h"
-#include "../Effects/Distorsion.h"
 
-REALTYPE *OscilGen::tmpsmps;//this array stores some termporary data and it has SOUND_BUFFER_SIZE elements
-FFTFREQS OscilGen::outoscilFFTfreqs;
+//operations on FFTfreqs
+inline void clearAll(fft_t *freqs)
+{
+    memset(freqs, 0, synth->oscilsize / 2 * sizeof(fft_t));
+}
 
+inline void clearDC(fft_t *freqs)
+{
+    freqs[0] = fft_t(0.0f, 0.0f);
+}
 
-OscilGen::OscilGen(FFTwrapper *fft_,Resonance *res_):Presets()
+//return magnitude squared
+inline float normal(const fft_t *freqs, off_t x)
 {
-    setpresettype("Poscilgen");
-    fft=fft_;
-    res=res_;
-    newFFTFREQS(&oscilFFTfreqs,OSCIL_SIZE/2);
-    newFFTFREQS(&basefuncFFTfreqs,OSCIL_SIZE/2);
+    return norm(freqs[x]);
+}
 
-    randseed=1;
-    ADvsPAD=false;
+//return magnitude
+inline float abs(const fft_t *freqs, off_t x)
+{
+    return abs(freqs[x]);
+}
 
-    defaults();
-};
+//return angle aka phase from a sine (not cosine wave)
+inline float arg(const fft_t *freqs, off_t x)
+{
+    const fft_t tmp(freqs[x].imag(), freqs[x].real());
+    return arg(tmp);
+}
 
-OscilGen::~OscilGen()
+/**
+ * Take frequency spectrum and ensure values are normalized based upon
+ * magnitude to 0<=x<=1
+ */
+void normalize(fft_t *freqs)
 {
-    deleteFFTFREQS(&basefuncFFTfreqs);
-    deleteFFTFREQS(&oscilFFTfreqs);
-};
+    float normMax = 0.0f;
+    for(int i = 0; i < synth->oscilsize / 2; ++i) {
+        //magnitude squared
+        const float norm = normal(freqs, i);
+        if(normMax < norm)
+            normMax = norm;
+    }
 
+    const float max = sqrt(normMax);
+    if(max < 1e-8) //data is all ~zero, do not amplify noise
+        return;
 
-void OscilGen::defaults()
+    for(int i = 0; i < synth->oscilsize / 2; ++i)
+        freqs[i] /= max;
+}
+
+//Full RMS normalize
+void rmsNormalize(fft_t *freqs)
 {
+    float sum = 0.0f;
+    for(int i = 1; i < synth->oscilsize / 2; ++i)
+        sum += normal(freqs, i);
 
-    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();
-};
+    if(sum < 0.000001f)
+        return;  //data is all ~zero, do not amplify noise
 
-void OscilGen::convert2sine(int magtype)
+    const float gain = 1.0f / sqrt(sum);
+
+    for(int i = 1; i < synth->oscilsize / 2; ++i)
+        freqs[i] *= gain;
+}
+
+#define DIFF(par) (old ## par != P ## par)
+
+OscilGen::OscilGen(FFTwrapper *fft_, Resonance *res_):Presets()
 {
-    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;
+    assert(fft_);
 
-    defaults();
+    setpresettype("Poscilgen");
+    fft = fft_;
+    res = res_;
 
-    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;
+    tmpsmps = new float[synth->oscilsize];
+    outoscilFFTfreqs = new fft_t[synth->oscilsize / 2];
+    oscilFFTfreqs    = new fft_t[synth->oscilsize / 2];
+    basefuncFFTfreqs = new fft_t[synth->oscilsize / 2];
 
-        Phphase[i]=64-(int) (64.0*newphase/PI);
-        if (Phphase[i]>127) Phphase[i]=127;
+    randseed = 1;
+    ADvsPAD  = false;
 
-        if (Phmag[i]==64) Phphase[i]=64;
-    };
-    deleteFFTFREQS(&freqs);
-    prepare();
-};
+    defaults();
+}
 
-/*
- * Base Functions - START
- */
-REALTYPE OscilGen::basefunc_pulse(REALTYPE x,REALTYPE a)
+OscilGen::~OscilGen()
 {
-    return((fmod(x,1.0)<a)?-1.0:1.0);
-};
+    delete[] tmpsmps;
+    delete[] outoscilFFTfreqs;
+    delete[] basefuncFFTfreqs;
+    delete[] oscilFFTfreqs;
+}
 
-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)
-{
-    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)
+void OscilGen::defaults()
 {
-    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);
-};
+    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.0f;
+        hphase[i]  = 0.0f;
+        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;
+
+    clearAll(oscilFFTfreqs);
+    clearAll(basefuncFFTfreqs);
+    oscilprepared = 0;
+    oldfilterpars = 0;
+    oldsapars     = 0;
+    prepare();
+}
 
-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)
+void OscilGen::convert2sine()
 {
-    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);
-};
+    float  mag[MAX_AD_HARMONICS], phase[MAX_AD_HARMONICS];
+    float  oscil[synth->oscilsize];
+    fft_t *freqs = new fft_t[synth->oscilsize / 2];
+
+    get(oscil, -1.0f);
+    FFTwrapper *fft = new FFTwrapper(synth->oscilsize);
+    fft->smps2freqs(oscil, freqs);
+    delete (fft);
+
+    normalize(freqs);
+
+    mag[0]   = 0;
+    phase[0] = 0;
+    for(int i = 0; i < MAX_AD_HARMONICS; ++i) {
+        mag[i]   = abs(freqs, i + 1);
+        phase[i] = arg(freqs, i + 1);
+    }
 
-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)
-{
-    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+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));
-};
+    defaults();
 
-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));
-};
-/*
- * Base Functions - END
- */
+    for(int i = 0; i < MAX_AD_HARMONICS - 1; ++i) {
+        float newmag   = mag[i];
+        float newphase = phase[i];
 
+        Phmag[i] = (int) ((newmag) * 64.0f) + 64;
+
+        Phphase[i] = 64 - (int) (64.0f * newphase / PI);
+        if(Phphase[i] > 127)
+            Phphase[i] = 127;
+
+        if(Phmag[i] == 64)
+            Phphase[i] = 64;
+    }
+    delete[] freqs;
+    prepare();
+}
 
 /*
  * Get the base function
  */
-void OscilGen::getbasefunction(REALTYPE *smps)
+void OscilGen::getbasefunction(float *smps)
 {
-    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;
-
-    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;
-        break;
-    case 2:
-        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;
-        break;
-    };
+    int   i;
+    float par = (Pbasefuncpar + 0.5f) / 128.0f;
+    if(Pbasefuncpar == 64)
+        par = 0.5f;
 
-//    printf("%.5f %.5f\n",basefuncmodulationpar1,basefuncmodulationpar3);
+    float basefuncmodulationpar1 = Pbasefuncmodulationpar1 / 127.0f,
+          basefuncmodulationpar2 = Pbasefuncmodulationpar2 / 127.0f,
+          basefuncmodulationpar3 = Pbasefuncmodulationpar3 / 127.0f;
 
-    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
+            basefuncmodulationpar1 =
+                (powf(2, basefuncmodulationpar1 * 5.0f) - 1.0f) / 10.0f;
+            basefuncmodulationpar3 =
+                floor((powf(2, basefuncmodulationpar3 * 5.0f) - 1.0f));
+            if(basefuncmodulationpar3 < 0.9999f)
+                basefuncmodulationpar3 = -1.0f;
             break;
         case 2:
-            t=t+sin((t*basefuncmodulationpar3+basefuncmodulationpar2)*2.0*PI)*basefuncmodulationpar1;//sine
+            basefuncmodulationpar1 =
+                (powf(2, basefuncmodulationpar1 * 5.0f) - 1.0f) / 10.0f;
+            basefuncmodulationpar3 = 1.0f
+                                     + floor((powf(2, basefuncmodulationpar3
+                                                   * 5.0f) - 1.0f));
             break;
         case 3:
-            t=t+pow((1.0-cos((t+basefuncmodulationpar2)*2.0*PI))*0.5,basefuncmodulationpar3)*basefuncmodulationpar1;//power
+            basefuncmodulationpar1 =
+                (powf(2, basefuncmodulationpar1 * 7.0f) - 1.0f) / 10.0f;
+            basefuncmodulationpar3 = 0.01f
+                                     + (powf(2, basefuncmodulationpar3
+                                             * 16.0f) - 1.0f) / 10.0f;
             break;
-        };
+    }
 
-        t=t-floor(t);
+    base_func func = getBaseFunction(Pcurrentbasefunc);
+
+    for(i = 0; i < synth->oscilsize; ++i) {
+        float t = i * 1.0f / synth->oscilsize;
+
+        switch(Pbasefuncmodulation) {
+            case 1:
+                t = t * basefuncmodulationpar3 + sinf(
+                    (t
+                     + basefuncmodulationpar2) * 2.0f
+                    * PI) * basefuncmodulationpar1;                              //rev
+                break;
+            case 2:
+                t = t + sinf(
+                    (t * basefuncmodulationpar3
+                     + basefuncmodulationpar2) * 2.0f
+                    * PI) * basefuncmodulationpar1;                              //sine
+                break;
+            case 3:
+                t = t + powf((1.0f - cosf(
+                                  (t
+                                   + basefuncmodulationpar2) * 2.0f
+                                  * PI)) * 0.5f,
+                             basefuncmodulationpar3) * basefuncmodulationpar1; //power
+                break;
+        }
+
+        t = t - floor(t);
+
+        if(func)
+            smps[i] = func(t, par);
+        else
+            smps[i] = -sinf(2.0f * PI * i / synth->oscilsize);
+    }
+}
 
-        switch (Pcurrentbasefunc) {
-        case 1:
-            smps[i]=basefunc_triangle(t,par);
-            break;
-        case 2:
-            smps[i]=basefunc_pulse(t,par);
-            break;
-        case 3:
-            smps[i]=basefunc_saw(t,par);
-            break;
-        case 4:
-            smps[i]=basefunc_power(t,par);
-            break;
-        case 5:
-            smps[i]=basefunc_gauss(t,par);
-            break;
-        case 6:
-            smps[i]=basefunc_diode(t,par);
-            break;
-        case 7:
-            smps[i]=basefunc_abssine(t,par);
-            break;
-        case 8:
-            smps[i]=basefunc_pulsesine(t,par);
-            break;
-        case 9:
-            smps[i]=basefunc_stretchsine(t,par);
-            break;
-        case 10:
-            smps[i]=basefunc_chirp(t,par);
-            break;
-        case 11:
-            smps[i]=basefunc_absstretchsine(t,par);
-            break;
-        case 12:
-            smps[i]=basefunc_chebyshev(t,par);
-            break;
-        case 13:
-            smps[i]=basefunc_sqr(t,par);
-            break;
-        default:
-            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) {
-        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);
-            break;
-        case 2:
-            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);
-            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;
-            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);
-            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
-            break;
-        case 7:
-            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;
-            break;
-        case 8:
-            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
-            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
-            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;
-            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;
-            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
-            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);
-            break;
-        };
+    if(Pfiltertype == 0)
+        return;
 
+    const float par    = 1.0f - Pfilterpar1 / 128.0f;
+    const float par2   = Pfilterpar2 / 127.0f;
+    filter_func filter = getFilter(Pfiltertype);
 
-        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;
-    };
+    for(int i = 1; i < synth->oscilsize / 2; ++i)
+        oscilFFTfreqs[i] *= filter(i, par, par2);
+
+    normalize(oscilFFTfreqs);
+}
 
-    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;
-        };
-        //in this case basefuncFFTfreqs_ are not used
+        fft->smps2freqs(tmpsmps, basefuncFFTfreqs);
+        clearDC(basefuncFFTfreqs);
     }
-    oscilprepared=0;
-    oldbasefunc=Pcurrentbasefunc;
-    oldbasepar=Pbasefuncpar;
-    oldbasefuncmodulation=Pbasefuncmodulation;
-    oldbasefuncmodulationpar1=Pbasefuncmodulationpar1;
-    oldbasefuncmodulationpar2=Pbasefuncmodulationpar2;
-    oldbasefuncmodulationpar3=Pbasefuncmodulationpar3;
-};
+    else //in this case basefuncFFTfreqs are not used
+        clearAll(basefuncFFTfreqs);
+    oscilprepared = 0;
+    oldbasefunc   = Pcurrentbasefunc;
+    oldbasepar    = Pbasefuncpar;
+    oldbasefuncmodulation     = Pbasefuncmodulation;
+    oldbasefuncmodulationpar1 = Pbasefuncmodulationpar1;
+    oldbasefuncmodulationpar2 = Pbasefuncmodulationpar2;
+    oldbasefuncmodulationpar3 = Pbasefuncmodulationpar3;
+}
+
+inline void normalize(float *smps, size_t N)
+{
+    //Find max
+    float max = 0.0f;
+    for(size_t i = 0; i < N; ++i)
+        if(max < fabs(smps[i]))
+            max = fabs(smps[i]);
+    if(max < 0.00001f)
+        max = 1.0f;
+
+    //Normalize to +-1
+    for(size_t i = 0; i < N; ++i)
+        smps[i] /= max;
+}
 
 /*
  * Waveshape
  */
 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
+    clearDC(oscilFFTfreqs);
     //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(int i = 1; i < synth->oscilsize / 8; ++i) {
+        float gain = i / (synth->oscilsize / 8.0f);
+        oscilFFTfreqs[synth->oscilsize / 2 - i] *= gain;
+    }
+    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;
+    normalize(tmpsmps, synth->oscilsize);
 
     //Do the waveshaping
-    waveshapesmps(OSCIL_SIZE,tmpsmps,Pwaveshapingfunction,Pwaveshaping);
+    waveShapeSmps(synth->oscilsize, tmpsmps, Pwaveshapingfunction, Pwaveshaping);
 
-    fft->smps2freqs(tmpsmps,oscilFFTfreqs);//perform FFT
-};
+    fft->smps2freqs(tmpsmps, oscilFFTfreqs); //perform FFT
+}
 
 
 /*
@@ -550,80 +404,87 @@ void OscilGen::modulation()
 {
     int i;
 
-    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;
-
-    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;
-        break;
-    case 2:
-        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;
-        break;
-    };
+    oldmodulation     = Pmodulation;
+    oldmodulationpar1 = Pmodulationpar1;
+    oldmodulationpar2 = Pmodulationpar2;
+    oldmodulationpar3 = Pmodulationpar3;
+    if(Pmodulation == 0)
+        return;
 
-    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];
 
-    //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;
-
-    //Do the modulation
-    for (i=0;i<OSCIL_SIZE;i++) {
-        REALTYPE t=i*1.0/OSCIL_SIZE;
+    float modulationpar1 = Pmodulationpar1 / 127.0f,
+          modulationpar2 = 0.5f - Pmodulationpar2 / 127.0f,
+          modulationpar3 = Pmodulationpar3 / 127.0f;
 
-        switch (Pmodulation) {
+    switch(Pmodulation) {
         case 1:
-            t=t*modulationpar3+sin((t+modulationpar2)*2.0*PI)*modulationpar1;//rev
+            modulationpar1 = (powf(2, modulationpar1 * 7.0f) - 1.0f) / 100.0f;
+            modulationpar3 = floor((powf(2, modulationpar3 * 5.0f) - 1.0f));
+            if(modulationpar3 < 0.9999f)
+                modulationpar3 = -1.0f;
             break;
         case 2:
-            t=t+sin((t*modulationpar3+modulationpar2)*2.0*PI)*modulationpar1;//sine
+            modulationpar1 = (powf(2, modulationpar1 * 7.0f) - 1.0f) / 100.0f;
+            modulationpar3 = 1.0f
+                             + floor((powf(2, modulationpar3 * 5.0f) - 1.0f));
             break;
         case 3:
-            t=t+pow((1.0-cos((t+modulationpar2)*2.0*PI))*0.5,modulationpar3)*modulationpar1;//power
+            modulationpar1 = (powf(2, modulationpar1 * 9.0f) - 1.0f) / 100.0f;
+            modulationpar3 = 0.01f
+                             + (powf(2, modulationpar3 * 16.0f) - 1.0f) / 10.0f;
             break;
-        };
+    }
 
-        t=(t-floor(t))*OSCIL_SIZE;
+    clearDC(oscilFFTfreqs); //remove the DC
+    //reduce the amplitude of the freqs near the nyquist
+    for(i = 1; i < synth->oscilsize / 8; ++i) {
+        float tmp = i / (synth->oscilsize / 8.0f);
+        oscilFFTfreqs[synth->oscilsize / 2 - i] *= tmp;
+    }
+    fft->freqs2smps(oscilFFTfreqs, tmpsmps);
+    int    extra_points = 2;
+    float *in = new float[synth->oscilsize + extra_points];
 
-        int poshi=(int) t;
-        REALTYPE poslo=t-floor(t);
+    //Normalize
+    normalize(tmpsmps, synth->oscilsize);
 
-        tmpsmps[i]=in[poshi]*(1.0-poslo)+in[poshi+1]*poslo;
-    };
+    for(i = 0; i < synth->oscilsize; ++i)
+        in[i] = tmpsmps[i];
+    for(i = 0; i < extra_points; ++i)
+        in[i + synth->oscilsize] = tmpsmps[i];
 
-    delete [] in;
-    fft->smps2freqs(tmpsmps,oscilFFTfreqs);//perform FFT
-};
+    //Do the modulation
+    for(i = 0; i < synth->oscilsize; ++i) {
+        float t = i * 1.0f / synth->oscilsize;
+
+        switch(Pmodulation) {
+            case 1:
+                t = t * modulationpar3
+                    + sinf((t + modulationpar2) * 2.0f * PI) * modulationpar1; //rev
+                break;
+            case 2:
+                t = t
+                    + sinf((t * modulationpar3
+                            + modulationpar2) * 2.0f * PI) * modulationpar1; //sine
+                break;
+            case 3:
+                t = t + powf((1.0f - cosf(
+                                  (t + modulationpar2) * 2.0f * PI)) * 0.5f,
+                             modulationpar3) * modulationpar1; //power
+                break;
+        }
+
+        t = (t - floor(t)) * synth->oscilsize;
+
+        int   poshi = (int) t;
+        float poslo = t - floor(t);
+
+        tmpsmps[i] = in[poshi] * (1.0f - poslo) + in[poshi + 1] * poslo;
+    }
 
+    delete [] in;
+    fft->smps2freqs(tmpsmps, oscilFFTfreqs); //perform FFT
+}
 
 
 /*
@@ -631,477 +492,450 @@ void OscilGen::modulation()
  */
 void OscilGen::spectrumadjust()
 {
-    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);
-        break;
-    case 2:
-        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;
-        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;
-
-
-    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) {
+    if(Psatype == 0)
+        return;
+    float par = Psapar / 127.0f;
+    switch(Psatype) {
         case 1:
-            mag=pow(mag,par);
+            par = 1.0f - par * 2.0f;
+            if(par >= 0.0f)
+                par = powf(5.0f, par);
+            else
+                par = powf(8.0f, par);
             break;
         case 2:
-            if (mag<par) mag=0.0;
+            par = powf(10.0f, (1.0f - par) * 3.0f) * 0.25f;
             break;
         case 3:
-            mag/=par;
-            if (mag>1.0) mag=1.0;
+            par = powf(10.0f, (1.0f - par) * 3.0f) * 0.25f;
             break;
-        };
-        oscilFFTfreqs.c[i]=mag*cos(phase);
-        oscilFFTfreqs.s[i]=mag*sin(phase);
-    };
+    }
+
 
-};
+    normalize(oscilFFTfreqs);
+
+    for(int i = 0; i < synth->oscilsize / 2; ++i) {
+        float mag   = abs(oscilFFTfreqs, i);
+        float phase = arg(oscilFFTfreqs, i);
+
+        switch(Psatype) {
+            case 1:
+                mag = powf(mag, par);
+                break;
+            case 2:
+                if(mag < par)
+                    mag = 0.0f;
+                break;
+            case 3:
+                mag /= par;
+                if(mag > 1.0f)
+                    mag = 1.0f;
+                break;
+        }
+        oscilFFTfreqs[i] = std::polar<fftw_real>(mag, 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;
+
+    int   harmonicshift = -Pharmonicshift;
+    fft_t h;
+
+    if(harmonicshift > 0)
+        for(int i = synth->oscilsize / 2 - 2; i >= 0; i--) {
+            int oldh = i - harmonicshift;
+            if(oldh < 0)
+                h = 0.0f;
+            else
+                h = oscilFFTfreqs[oldh + 1];
+            oscilFFTfreqs[i + 1] = h;
+        }
+    else
+        for(int i = 0; i < synth->oscilsize / 2 - 1; ++i) {
+            int oldh = i + abs(harmonicshift);
+            if(oldh >= (synth->oscilsize / 2 - 1))
+                h = 0.0f;
+            else {
+                h = oscilFFTfreqs[oldh + 1];
+                if(abs(h) < 0.000001f)
+                    h = 0.0f;
+            }
+
+            oscilFFTfreqs[i + 1] = h;
+        }
+
+    clearDC(oscilFFTfreqs);
+}
 
 /*
  * 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))
+    if((oldbasepar != Pbasefuncpar) || (oldbasefunc != Pcurrentbasefunc)
+       || DIFF(basefuncmodulation) || DIFF(basefuncmodulationpar1)
+       || DIFF(basefuncmodulationpar2) || DIFF(basefuncmodulationpar3))
         changebasefunction();
 
-    for (i=0;i<MAX_AD_HARMONICS;i++) hphase[i]=(Phphase[i]-64.0)/64.0*PI/(i+1);
-
-    for (i=0;i<MAX_AD_HARMONICS;i++) {
-        hmagnew=1.0-fabs(Phmag[i]/64.0-1.0);
-        switch (Phmagtype) {
-        case 1:
-            hmag[i]=exp(hmagnew*log(0.01));
-            break;
-        case 2:
-            hmag[i]=exp(hmagnew*log(0.001));
-            break;
-        case 3:
-            hmag[i]=exp(hmagnew*log(0.0001));
-            break;
-        case 4:
-            hmag[i]=exp(hmagnew*log(0.00001));
-            break;
-        default:
-            hmag[i]=1.0-hmagnew;
-            break;
-        };
-
-        if (Phmag[i]<64) hmag[i]=-hmag[i];
-    };
+    for(int i = 0; i < MAX_AD_HARMONICS; ++i)
+        hphase[i] = (Phphase[i] - 64.0f) / 64.0f * PI / (i + 1);
+
+    for(int i = 0; i < MAX_AD_HARMONICS; ++i) {
+        const float hmagnew = 1.0f - fabs(Phmag[i] / 64.0f - 1.0f);
+        switch(Phmagtype) {
+            case 1:
+                hmag[i] = expf(hmagnew * logf(0.01f));
+                break;
+            case 2:
+                hmag[i] = expf(hmagnew * logf(0.001f));
+                break;
+            case 3:
+                hmag[i] = expf(hmagnew * logf(0.0001f));
+                break;
+            case 4:
+                hmag[i] = expf(hmagnew * logf(0.00001f));
+                break;
+            default:
+                hmag[i] = 1.0f - hmagnew;
+                break;
+        }
+
+        if(Phmag[i] < 64)
+            hmag[i] = -hmag[i];
+    }
 
     //remove the harmonics where Phmag[i]==64
-    for (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(int i = 0; i < MAX_AD_HARMONICS; ++i)
+        if(Phmag[i] == 64)
+            hmag[i] = 0.0f;
+
+
+    clearAll(oscilFFTfreqs);
+    if(Pcurrentbasefunc == 0)   //the sine case
+        for(int i = 0; i < MAX_AD_HARMONICS - 1; ++i) {
+            oscilFFTfreqs[i
+                          + 1].real() = -hmag[i]
+                                        * sinf(hphase[i] * (i + 1)) / 2.0f;
+            oscilFFTfreqs[i
+                          + 1].imag() = hmag[i]
+                                        * cosf(hphase[i] * (i + 1)) / 2.0f;
+        }
+    else
+        for(int j = 0; j < MAX_AD_HARMONICS; ++j) {
+            if(Phmag[j] == 64)
+                continue;
+            for(int i = 1; i < synth->oscilsize / 2; ++i) {
+                int k = i * (j + 1);
+                if(k >= synth->oscilsize / 2)
+                    break;
+                oscilFFTfreqs[k] += basefuncFFTfreqs[i] * std::polar<fftw_real>(
+                    hmag[j],
+                    hphase[j] * k);
+            }
+        }
+
+    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;
+    clearDC(oscilFFTfreqs);
 
-    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(fft_t *f, float freq)
 {
-    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;
+    if(Padaptiveharmonics == 0 /*||(freq<1.0f)*/)
+        return;
+    if(freq < 1.0f)
+        freq = 440.0f;
 
-    REALTYPE hc=0.0,hs=0.0;
-    REALTYPE basefreq=30.0*pow(10.0,Padaptiveharmonicsbasefreq/128.0);
-    REALTYPE power=(Padaptiveharmonicspower+1.0)/101.0;
+    fft_t *inf = new fft_t[synth->oscilsize / 2];
+    for(int i = 0; i < synth->oscilsize / 2; ++i)
+        inf[i] = f[i];
+    clearAll(f);
+    clearDC(inf);
 
-    REALTYPE rap=freq/basefreq;
+    float hc = 0.0f, hs = 0.0f;
+    float basefreq = 30.0f * powf(10.0f, Padaptiveharmonicsbasefreq / 128.0f);
+    float power    = (Padaptiveharmonicspower + 1.0f) / 101.0f;
 
-    rap=pow(rap,power);
+    float rap = freq / basefreq;
 
-    bool down=false;
-    if (rap>1.0) {
-        rap=1.0/rap;
-        down=true;
-    };
+    rap = powf(rap, power);
+
+    bool down = false;
+    if(rap > 1.0f) {
+        rap  = 1.0f / 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);
+    for(int i = 0; i < synth->oscilsize / 2 - 2; ++i) {
+        float h    = i * rap;
+        int   high = (int)(i * rap);
+        float low  = fmod(h, 1.0f);
 
-        if (high>=(OSCIL_SIZE/2-2)) {
+        if(high >= (synth->oscilsize / 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;
-        };
-    };
+        else {
+            if(down) {
+                f[high].real()     += inf[i].real() * (1.0f - low);
+                f[high].imag()     += inf[i].imag() * (1.0f - low);
+                f[high + 1].real() += inf[i].real() * low;
+                f[high + 1].imag() += inf[i].imag() * low;
+            }
+            else {
+                hc = inf[high].real()
+                     * (1.0f - low) + inf[high + 1].real() * low;
+                hs = inf[high].imag()
+                     * (1.0f - low) + inf[high + 1].imag() * low;
+            }
+            if(fabs(hc) < 0.000001f)
+                hc = 0.0f;
+            if(fabs(hs) < 0.000001f)
+                hs = 0.0f;
+        }
+
+        if(!down) {
+            if(i == 0) { //corect the aplitude of the first harmonic
+                hc *= rap;
+                hs *= rap;
+            }
+            f[i] = fft_t(hc, 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);
-};
+    f[1] += f[0];
+    clearDC(f);
+    delete[] inf;
+}
 
-void OscilGen::adaptiveharmonicpostprocess(REALTYPE *f,int size)
+void OscilGen::adaptiveharmonicpostprocess(fft_t *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];
-            };
-        };
-    };
+    if(Padaptiveharmonics <= 1)
+        return;
+    fft_t *inf = new fft_t[size];
+    float  par = Padaptiveharmonicspar * 0.01f;
+    par = 1.0f - powf((1.0f - par), 1.5f);
+
+    for(int i = 0; i < size; ++i) {
+        inf[i] = f[i] * double(par);
+        f[i]  *= (1.0f - par);
+    }
 
-    delete(inf);
-};
 
+    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];
+    }
 
-
-/*
- * Get the oscillator function
- */
-short int OscilGen::get(REALTYPE *smps,REALTYPE freqHz)
-{
-    return(this->get(smps,freqHz,0));
-};
+    delete [] inf;
+}
 
 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)
+bool OscilGen::needPrepare(void)
 {
-    int i;
-    int nyquist,outpos;
+    bool outdated = false;
+
+    //Check function parameters
+    if((oldbasepar != Pbasefuncpar) || (oldbasefunc != Pcurrentbasefunc)
+       || DIFF(hmagtype) || DIFF(waveshaping) || DIFF(waveshapingfunction))
+        outdated = true;
+
+    //Check filter parameters
+    if(oldfilterpars != Pfiltertype * 256 + Pfilterpar1 + Pfilterpar2 * 65536
+       + Pfilterbeforews * 16777216) {
+        outdated      = true;
+        oldfilterpars = Pfiltertype * 256 + Pfilterpar1 + Pfilterpar2 * 65536
+                        + Pfilterbeforews * 16777216;
+    }
 
-    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;
-    };
+    //Check spectrum adjustments
+    if(oldsapars != Psatype * 256 + Psapar) {
+        outdated  = true;
+        oldsapars = Psatype * 256 + Psapar;
+    }
 
-    if ((oldbasefuncmodulation!=Pbasefuncmodulation)||
-            (oldbasefuncmodulationpar1!=Pbasefuncmodulationpar1)||
-            (oldbasefuncmodulationpar2!=Pbasefuncmodulationpar2)||
-            (oldbasefuncmodulationpar3!=Pbasefuncmodulationpar3))
-        oscilprepared=0;
+    //Check function modulation
+    if(DIFF(basefuncmodulation) || DIFF(basefuncmodulationpar1)
+       || DIFF(basefuncmodulationpar2) || DIFF(basefuncmodulationpar3))
+        outdated = true;
 
-    if ((oldmodulation!=Pmodulation)||
-            (oldmodulationpar1!=Pmodulationpar1)||
-            (oldmodulationpar2!=Pmodulationpar2)||
-            (oldmodulationpar3!=Pmodulationpar3))
-        oscilprepared=0;
+    //Check overall modulation
+    if(DIFF(modulation) || DIFF(modulationpar1)
+       || DIFF(modulationpar2) || DIFF(modulationpar3))
+        outdated = true;
 
-    if (oldharmonicshift!=Pharmonicshift+Pharmonicshiftfirst*256) oscilprepared=0;
+    //Check harmonic shifts
+    if(oldharmonicshift != Pharmonicshift + Pharmonicshiftfirst * 256)
+        outdated = true;
 
-    if (oscilprepared!=1) prepare();
+    return outdated == true || oscilprepared == false;
+}
 
-    outpos=(int)((RND*2.0-1.0)*(REALTYPE) OSCIL_SIZE*(Prand-64.0)/64.0);
-    outpos=(outpos+2*OSCIL_SIZE) % OSCIL_SIZE;
+/*
+ * Get the oscillator function
+ */
+short int OscilGen::get(float *smps, float freqHz, int resonance)
+{
+    if(needPrepare())
+        prepare();
 
+    int outpos =
+        (int)((RND * 2.0f
+               - 1.0f) * synth->oscilsize_f * (Prand - 64.0f) / 64.0f);
+    outpos = (outpos + 2 * synth->oscilsize) % synth->oscilsize;
 
-    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;
+    clearAll(outoscilFFTfreqs);
 
+    int nyquist = (int)(0.5f * synth->samplerate_f / fabs(freqHz)) + 2;
+    if(ADvsPAD)
+        nyquist = (int)(synth->oscilsize / 2);
+    if(nyquist > synth->oscilsize / 2)
+        nyquist = synth->oscilsize / 2;
 
-    int realnyquist=nyquist;
+    //Process harmonics
+    {
+        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 = synth->oscilsize / 2;
+        for(int i = 1; i < nyquist - 1; ++i)
+            outoscilFFTfreqs[i] = oscilFFTfreqs[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[1],
+                                    synth->oscilsize / 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(int i = nyquist; i < synth->oscilsize / 2; ++i)
+            outoscilFFTfreqs[i] = fft_t(0.0f, 0.0f);
 
     // 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.0f) && (!ADvsPAD)) {
+        const float rnd = PI * powf((Prand - 64.0f) / 64.0f, 2.0f);
+        for(int i = 1; i < nyquist - 1; ++i) //to Nyquist only for AntiAliasing
+            outoscilFFTfreqs[i] *=
+                std::polar<fftw_real>(1.0f, (float)(rnd * i * RND));
+    }
 
     //Harmonic Amplitude Randomness
-    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) {
-        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;
-            };
-            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;
-            };
-            break;
-        };
-        srand(realrnd+1);
-    };
-
-    if ((freqHz>0.1)&&(resonance!=0)) res->applyres(nyquist-1,outoscilFFTfreqs,freqHz);
+    if((freqHz > 0.1f) && (!ADvsPAD)) {
+        unsigned int realrnd = prng();
+        sprng(randseed);
+        float power     = Pamprandpower / 127.0f;
+        float normalize = 1.0f / (1.2f - power);
+        switch(Pamprandtype) {
+            case 1:
+                power = power * 2.0f - 0.5f;
+                power = powf(15.0f, power);
+                for(int i = 1; i < nyquist - 1; ++i)
+                    outoscilFFTfreqs[i] *= powf(RND, power) * normalize;
+                break;
+            case 2:
+                power = power * 2.0f - 0.5f;
+                power = powf(15.0f, power) * 2.0f;
+                float rndfreq = 2 * PI * RND;
+                for(int i = 1; i < nyquist - 1; ++i)
+                    outoscilFFTfreqs[i] *= powf(fabs(sinf(i * rndfreq)), power)
+                                           * normalize;
+                break;
+        }
+        sprng(realrnd + 1);
+    }
 
-    //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((freqHz > 0.1f) && (resonance != 0))
+        res->applyres(nyquist - 1, outoscilFFTfreqs, freqHz);
 
+    rmsNormalize(outoscilFFTfreqs);
 
-    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((ADvsPAD) && (freqHz > 0.1f)) //in this case the smps will contain the freqs
+        for(int i = 1; i < synth->oscilsize / 2; ++i)
+            smps[i - 1] = abs(outoscilFFTfreqs, i);
+    else {
+        fft->freqs2smps(outoscilFFTfreqs, smps);
+        for(int i = 0; i < synth->oscilsize; ++i)
+            smps[i] *= 0.25f;                     //correct the amplitude
+    }
 
-    if (Prand<64) return(outpos);
-    else return(0);
-};
+    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, float *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(n > synth->oscilsize / 2)
+        n = synth->oscilsize / 2;
+
+    for(int i = 1; i < n; ++i) {
+        if(what == 0)
+            spc[i - 1] = abs(oscilFFTfreqs, i);
+        else {
+            if(Pcurrentbasefunc == 0)
+                spc[i - 1] = ((i == 1) ? (1.0f) : (0.0f));
+            else
+                spc[i - 1] = abs(basefuncFFTfreqs, 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(what == 0) {
+        for(int i = 0; i < n; ++i)
+            outoscilFFTfreqs[i] = fft_t(spc[i], spc[i]);
+        memset(outoscilFFTfreqs + n, 0,
+               (synth->oscilsize / 2 - n) * sizeof(fft_t));
+        adaptiveharmonic(outoscilFFTfreqs, 0.0f);
+        adaptiveharmonicpostprocess(outoscilFFTfreqs, n - 1);
+        for(int i = 0; i < n; ++i)
+            spc[i] = outoscilFFTfreqs[i].imag();
+    }
+}
 
 
 /*
@@ -1109,184 +943,561 @@ void OscilGen::getspectrum(int n, REALTYPE *spc,int what)
  */
 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];
-    };
-
-    oldbasefunc=Pcurrentbasefunc=127;
+    for(int i = 0; i < synth->oscilsize / 2; ++i)
+        basefuncFFTfreqs[i] = oscilFFTfreqs[i];
 
+    oldbasefunc = Pcurrentbasefunc = 127;
     prepare();
-};
+}
 
 
 /*
  * Get the base function for UI
  */
-void OscilGen::getcurrentbasefunction(REALTYPE *smps)
+void OscilGen::getcurrentbasefunction(float *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;
-
-        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;
+    if(Pcurrentbasefunc == 127) {
+        normalize(basefuncFFTfreqs);
 
         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 < synth->oscilsize / 2; ++i) {
+            float xc = basefuncFFTfreqs[i].real();
+            float xs = basefuncFFTfreqs[i].imag();
+            if((fabs(xs) > 0.00001f) && (fabs(xs) > 0.00001f)) {
+                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);
+            xml->exitbranch();
+        }
+        xml->exitbranch();
+    }
 
-    Phmagtype=xml->getpar127("harmonic_mag_type",Phmagtype);
+    if(Pcurrentbasefunc != 0)
+        changebasefunction();
 
-    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);
+    if(xml->enterbranch("BASE_FUNCTION")) {
+        for(int i = 1; i < synth->oscilsize / 2; ++i)
+            if(xml->enterbranch("BF_HARMONIC", i)) {
+                basefuncFFTfreqs[i].real() = xml->getparreal("cos", 0.0f);
+                basefuncFFTfreqs[i].imag() = xml->getparreal("sin", 0.0f);
+                xml->exitbranch();
+            }
+        xml->exitbranch();
 
-    Pmodulation=xml->getpar127("modulation",Pmodulation);
-    Pmodulationpar1=xml->getpar127("modulation_par1",Pmodulationpar1);
-    Pmodulationpar2=xml->getpar127("modulation_par2",Pmodulationpar2);
-    Pmodulationpar3=xml->getpar127("modulation_par3",Pmodulationpar3);
+        clearDC(basefuncFFTfreqs);
+        normalize(basefuncFFTfreqs);
+    }
+}
 
-    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);
+//Define basic functions
+#define FUNC(b) float basefunc_ ## b(float x, float a)
 
-    Psatype=xml->getpar127("spectrum_adjust_type",Psatype);
-    Psapar=xml->getpar127("spectrum_adjust_par",Psapar);
+FUNC(pulse)
+{
+    return (fmod(x, 1.0f) < a) ? -1.0f : 1.0f;
+}
 
-    Prand=xml->getpar127("rand",Prand);
-    Pamprandtype=xml->getpar127("amp_rand_type",Pamprandtype);
-    Pamprandpower=xml->getpar127("amp_rand_power",Pamprandpower);
+FUNC(saw)
+{
+    if(a < 0.00001f)
+        a = 0.00001f;
+    else
+    if(a > 0.99999f)
+        a = 0.99999f;
+    x = fmod(x, 1);
+    if(x < a)
+        return x / a * 2.0f - 1.0f;
+    else
+        return (1.0f - x) / (1.0f - a) * 2.0f - 1.0f;
+}
+
+FUNC(triangle)
+{
+    x = fmod(x + 0.25f, 1);
+    a = 1 - a;
+    if(a < 0.00001f)
+        a = 0.00001f;
+    if(x < 0.5f)
+        x = x * 4 - 1.0f;
+    else
+        x = (1.0f - x) * 4 - 1.0f;
+    x /= -a;
+    if(x < -1.0f)
+        x = -1.0f;
+    if(x > 1.0f)
+        x = 1.0f;
+    return x;
+}
+
+FUNC(power)
+{
+    x = fmod(x, 1);
+    if(a < 0.00001f)
+        a = 0.00001f;
+    else
+    if(a > 0.99999f)
+        a = 0.99999f;
+    return powf(x, expf((a - 0.5f) * 10.0f)) * 2.0f - 1.0f;
+}
+
+FUNC(gauss)
+{
+    x = fmod(x, 1) * 2.0f - 1.0f;
+    if(a < 0.00001f)
+        a = 0.00001f;
+    return expf(-x * x * (expf(a * 8) + 5.0f)) * 2.0f - 1.0f;
+}
 
-    Pharmonicshift=xml->getpar("harmonic_shift",Pharmonicshift,-64,64);
-    Pharmonicshiftfirst=xml->getparbool("harmonic_shift_first",Pharmonicshiftfirst);
+FUNC(diode)
+{
+    if(a < 0.00001f)
+        a = 0.00001f;
+    else
+    if(a > 0.99999f)
+        a = 0.99999f;
+    a = a * 2.0f - 1.0f;
+    x = cosf((x + 0.5f) * 2.0f * PI) - a;
+    if(x < 0.0f)
+        x = 0.0f;
+    return x / (1.0f - a) * 2 - 1.0f;
+}
+
+FUNC(abssine)
+{
+    x = fmod(x, 1);
+    if(a < 0.00001f)
+        a = 0.00001f;
+    else
+    if(a > 0.99999f)
+        a = 0.99999f;
+    return sinf(powf(x, expf((a - 0.5f) * 5.0f)) * PI) * 2.0f - 1.0f;
+}
+
+FUNC(pulsesine)
+{
+    if(a < 0.00001f)
+        a = 0.00001f;
+    x = (fmod(x, 1) - 0.5f) * expf((a - 0.5f) * logf(128));
+    if(x < -0.5f)
+        x = -0.5f;
+    else
+    if(x > 0.5f)
+        x = 0.5f;
+    x = sinf(x * PI * 2.0f);
+    return x;
+}
+
+FUNC(stretchsine)
+{
+    x = fmod(x + 0.5f, 1) * 2.0f - 1.0f;
+    a = (a - 0.5f) * 4;
+    if(a > 0.0f)
+        a *= 2;
+    a = powf(3.0f, a);
+    float b = powf(fabs(x), a);
+    if(x < 0)
+        b = -b;
+    return -sinf(b * PI);
+}
+
+FUNC(chirp)
+{
+    x = fmod(x, 1.0f) * 2.0f * PI;
+    a = (a - 0.5f) * 4;
+    if(a < 0.0f)
+        a *= 2.0f;
+    a = powf(3.0f, a);
+    return sinf(x / 2.0f) * sinf(a * x * x);
+}
+
+FUNC(absstretchsine)
+{
+    x = fmod(x + 0.5f, 1) * 2.0f - 1.0f;
+    a = (a - 0.5f) * 9;
+    a = powf(3.0f, a);
+    float b = powf(fabs(x), a);
+    if(x < 0)
+        b = -b;
+    return -powf(sinf(b * PI), 2);
+}
+
+FUNC(chebyshev)
+{
+    a = a * a * a * 30.0f + 1.0f;
+    return cosf(acosf(x * 2.0f - 1.0f) * a);
+}
 
-    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);
+FUNC(sqr)
+{
+    a = a * a * a * a * 160.0f + 0.001f;
+    return -atanf(sinf(x * 2.0f * PI) * a);
+}
 
+FUNC(spike)
+{
+    float b = a * 0.66666; // the width of the range: if a == 0.5, b == 0.33333
+
+    if(x < 0.5) {
+        if(x < (0.5 - (b / 2.0)))
+            return 0.0;
+        else {
+            x = (x + (b / 2) - 0.5) * (2.0 / b); // shift to zero, and expand to range from 0 to 1
+            return x * (2.0 / b); // this is the slope: 1 / (b / 2)
+        }
+    }
+    else {
+        if(x > (0.5 + (b / 2.0)))
+            return 0.0;
+        else {
+            x = (x - 0.5) * (2.0 / b);
+            return (1 - x) * (2.0 / b);
+        }
+    }
+}
 
-    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();
-    };
+FUNC(circle)
+{
+    // a is parameter: 0 -> 0.5 -> 1 // O.5 = circle
+    float b, y;
+
+    b = 2 - (a * 2); // b goes from 2 to 0
+    x = x * 4;
+
+    if(x < 2) {
+        x = x - 1; // x goes from -1 to 1
+        if((x < -b) || (x > b))
+            y = 0;
+        else
+            y = sqrt(1 - (pow(x, 2) / pow(b, 2)));  // normally * a^2, but a stays 1
+    }
+    else {
+        x = x - 3; // x goes from -1 to 1 as well
+        if((x < -b) || (x > b))
+            y = 0;
+        else
+            y = -sqrt(1 - (pow(x, 2) / pow(b, 2)));
+    }
+    return y;
+}
+
+typedef float (*base_func)(float, float);
 
-    if (Pcurrentbasefunc!=0) changebasefunction();
+base_func getBaseFunction(unsigned char func)
+{
+    if(!func)
+        return NULL;
+
+    if(func == 127) //should be the custom wave
+        return NULL;
+
+    func--;
+    assert(func < 15);
+    base_func functions[] = {
+        basefunc_triangle,
+        basefunc_pulse,
+        basefunc_saw,
+        basefunc_power,
+        basefunc_gauss,
+        basefunc_diode,
+        basefunc_abssine,
+        basefunc_pulsesine,
+        basefunc_stretchsine,
+        basefunc_chirp,
+        basefunc_absstretchsine,
+        basefunc_chebyshev,
+        basefunc_sqr,
+        basefunc_spike,
+        basefunc_circle,
+    };
+    return functions[func];
+}
 
+//And filters
 
-    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();
-            };
+#define FILTER(x) float osc_ ## x(unsigned int i, float par, float par2)
+FILTER(lp)
+{
+    float gain = powf(1.0f - par * par * par * 0.99f, i);
+    float tmp  = par2 * par2 * par2 * par2 * 0.5f + 0.0001f;
+    if(gain < tmp)
+        gain = powf(gain, 10.0f) / powf(tmp, 9.0f);
+    return gain;
+}
+
+FILTER(hp1)
+{
+    float gain = 1.0f - powf(1.0f - par * par, i + 1);
+    return powf(gain, par2 * 2.0f + 0.1f);
+}
 
+FILTER(hp1b)
+{
+    if(par < 0.2f)
+        par = par * 0.25f + 0.15f;
+    float gain = 1.0f - powf(1.0f - par * par * 0.999f + 0.001f,
+                             i * 0.05f * i + 1.0f);
+    float tmp = powf(5.0f, par2 * 2.0f);
+    return powf(gain, tmp);
+}
+
+FILTER(bp1)
+{
+    float gain = i + 1 - powf(2, (1.0f - par) * 7.5f);
+    gain = 1.0f / (1.0f + gain * gain / (i + 1.0f));
+    float tmp = powf(5.0f, par2 * 2.0f);
+    gain = powf(gain, tmp);
+    if(gain < 1e-5)
+        gain = 1e-5;
+    return gain;
+}
+
+FILTER(bs1)
+{
+    float gain = i + 1 - powf(2, (1.0f - par) * 7.5f);
+    gain = powf(atanf(gain / (i / 10.0f + 1)) / 1.57f, 6);
+    return powf(gain, par2 * par2 * 3.9f + 0.1f);
+}
 
-        };
-        xml->exitbranch();
+FILTER(lp2)
+{
+    return (i + 1 >
+            powf(2, (1.0f - par) * 10) ? 0.0f : 1.0f) * par2 + (1.0f - par2);
+}
 
-        REALTYPE max=0.0;
+FILTER(hp2)
+{
+    if(par == 1)
+        return 1.0f;
+    return (i + 1 >
+            powf(2, (1.0f - par) * 7) ? 1.0f : 0.0f) * par2 + (1.0f - par2);
+}
 
-        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;
+FILTER(bp2)
+{
+    return (fabs(powf(2,
+                      (1.0f
+                       - par)
+                      * 7)
+                 - i) > i / 2 + 1 ? 0.0f : 1.0f) * par2 + (1.0f - par2);
+}
+
+FILTER(bs2)
+{
+    return (fabs(powf(2,
+                      (1.0f
+                       - par)
+                      * 7)
+                 - i) < i / 2 + 1 ? 0.0f : 1.0f) * par2 + (1.0f - par2);
+}
+
+bool floatEq(float a, float b)
+{
+    const float fudge = .01;
+    return a + fudge > b && a - fudge < b;
+}
 
-        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;
-        };
+FILTER(cos)
+{
+    float tmp = powf(5.0f, par2 * 2.0f - 1.0f);
+    tmp = powf(i / 32.0f, tmp) * 32.0f;
+    if(floatEq(par2 * 127.0f, 64.0f))
+        tmp = i;
+    float gain = cosf(par * par * PI / 2.0f * tmp);
+    gain *= gain;
+    return gain;
+}
+
+FILTER(sin)
+{
+    float tmp = powf(5.0f, par2 * 2.0f - 1.0f);
+    tmp = powf(i / 32.0f, tmp) * 32.0f;
+    if(floatEq(par2 * 127.0f, 64.0f))
+        tmp = i;
+    float gain = sinf(par * par * PI / 2.0f * tmp);
+    gain *= gain;
+    return gain;
+}
+
+FILTER(low_shelf)
+{
+    float p2 = 1.0f - par + 0.2f;
+    float x  = i / (64.0f * p2 * p2);
+    if(x < 0.0f)
+        x = 0.0f;
+    else
+    if(x > 1.0f)
+        x = 1.0f;
+    float tmp = powf(1.0f - par2, 2.0f);
+    return cosf(x * PI) * (1.0f - tmp) + 1.01f + tmp;
+}
+
+FILTER(s)
+{
+    unsigned int tmp = (int) (powf(2.0f, (1.0f - par) * 7.2f));
+    float gain = 1.0f;
+    if(i == tmp)
+        gain = powf(2.0f, par2 * par2 * 8.0f);
+    return gain;
+}
+#undef FILTER
+
+typedef float (*filter_func)(unsigned int, float, float);
+filter_func getFilter(unsigned char func)
+{
+    if(!func)
+        return NULL;
+
+    func--;
+    assert(func < 13);
+    filter_func functions[] = {
+        osc_lp,
+        osc_hp1,
+        osc_hp1b,
+        osc_bp1,
+        osc_bs1,
+        osc_lp2,
+        osc_hp2,
+        osc_bp2,
+        osc_bs2,
+        osc_cos,
+        osc_sin,
+        osc_low_shelf,
+        osc_s
     };
-};
-
+    return functions[func];
+}
diff --git a/src/Synth/OscilGen.h b/src/Synth/OscilGen.h
index 4969be1..483a385 100644
--- a/src/Synth/OscilGen.h
+++ b/src/Synth/OscilGen.h
@@ -25,154 +25,151 @@
 
 #include "../globals.h"
 #include "../Misc/XMLwrapper.h"
-#include "Resonance.h"
 #include "../DSP/FFTwrapper.h"
 #include "../Params/Presets.h"
+#include "Resonance.h"
 
 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*/
+        //returns where should I start getting samples, used in block type randomness
+        short get(float *smps, float freqHz, int resonance = 0);
+        //if freqHz is smaller than 0, return the "un-randomized" sample for UI
 
-    void getbasefunction(REALTYPE *smps);
+        void getbasefunction(float *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, float *spc, int what); //what=0 pt. oscil,1 pt. basefunc
+        void getcurrentbasefunction(float *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();
 
-    //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
 
-    static REALTYPE *tmpsmps;//this array stores some termporary data and it has SOUND_BUFFER_SIZE elements
-    static FFTFREQS outoscilFFTfreqs;
+    private:
+        //This array stores some termporary data and it has OSCIL_SIZE elements
+        float *tmpsmps;
+        fft_t *outoscilFFTfreqs;
 
-private:
-
-    REALTYPE hmag[MAX_AD_HARMONICS],hphase[MAX_AD_HARMONICS];//the magnituides and the phases of the sine/nonsine harmonics
+        float 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();
+
+        //Check system for needed updates
+        bool needPrepare(void);
 
+        //Do the adaptive harmonic stuff
+        void adaptiveharmonic(fft_t *f, float 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(fft_t *f, int size);
+
+        //Internal Data
+        unsigned char oldbasefunc, oldbasepar, oldhmagtype,
+                      oldwaveshapingfunction, oldwaveshaping;
+        int oldfilterpars, oldsapars, oldbasefuncmodulation,
+            oldbasefuncmodulationpar1, oldbasefuncmodulationpar2,
+            oldbasefuncmodulationpar3, oldharmonicshift;
+        int oldmodulation, oldmodulationpar1, oldmodulationpar2,
+            oldmodulationpar3;
+
+
+        fft_t *basefuncFFTfreqs; //Base Function Frequencies
+        fft_t *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;
 };
 
+typedef float (*filter_func)(unsigned int, float, float);
+filter_func getFilter(unsigned char func);
+typedef float (*base_func)(float, float);
+base_func getBaseFunction(unsigned char func);
+
 
 #endif
diff --git a/src/Synth/PADnote.cpp b/src/Synth/PADnote.cpp
index 71b85de..1778b33 100644
--- a/src/Synth/PADnote.cpp
+++ b/src/Synth/PADnote.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  PADnote.C - The "pad" synthesizer
+  pADnote.cpp - The "pad" synthesizer
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -21,218 +21,167 @@
 #include <math.h>
 #include "PADnote.h"
 #include "../Misc/Config.h"
-
-PADnote::PADnote(PADnoteParameters *parameters, Controller *ctl_,REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool besilent)
+#include "../DSP/Filter.h"
+
+PADnote::PADnote(PADnoteParameters *parameters,
+                 Controller *ctl_,
+                 float freq,
+                 float velocity,
+                 int portamento_,
+                 int midinote,
+                 bool besilent)
+    :SynthNote(freq, velocity, portamento_, midinote, besilent)
 {
-    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;
-    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);
-        };
-
-    };
-
-    firsttime=true;
-    released=false;
-    realfreq=basefreq;
-    NoteGlobalPar.Detune=getdetune(pars->PDetuneType
-                                   ,pars->PCoarseDetune,pars->PDetune);
-
+    pars = parameters;
 
-    //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));
-//	printf("(mindist=%g) %i %g                  %g\n",mindist,i,dist,pars->sample[i].basefreq);
-
-        if (dist<mindist) {
-            nsample=i;
-            mindist=dist;
-        };
-    };
+    ctl = ctl_;
+    firsttime = true;
+    setup(freq, velocity, portamento_, midinote);
+}
 
-    int size=pars->sample[nsample].size;
-    if (size==0) size=1;
 
+void PADnote::setup(float freq,
+                    float velocity,
+                    int portamento_,
+                    int midinote,
+                    bool legato)
+{
+    portamento     = portamento_;
+    this->velocity = velocity;
+    finished_      = false;
 
-    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];
+    if(pars->Pfixedfreq == 0)
+        basefreq = freq;
+    else {
+        basefreq = 440.0f;
+        int fixedfreqET = pars->PfixedfreqET;
+        if(fixedfreqET != 0) { //if the frequency varies according the keyboard note
+            float tmp =
+                (midinote
+                 - 69.0f) / 12.0f
+                * (powf(2.0f, (fixedfreqET - 1) / 63.0f) - 1.0f);
+            if(fixedfreqET <= 64)
+                basefreq *= powf(2.0f, tmp);
+            else
+                basefreq *= powf(3.0f, tmp);
+        }
+    }
 
+    firsttime = true;
+    released  = false;
+    realfreq  = basefreq;
+    if(!legato)
+        NoteGlobalPar.Detune = getdetune(pars->PDetuneType, pars->PCoarseDetune,
+                                         pars->PDetune);
 
 
-    if (pars->PPanning==0) NoteGlobalPar.Panning=RND;
-    else NoteGlobalPar.Panning=pars->PPanning/128.0;
+    //find out the closest note
+    float logfreq = logf(basefreq * powf(2.0f, NoteGlobalPar.Detune / 1200.0f));
+    float mindist = fabs(logfreq - logf(pars->sample[0].basefreq + 0.0001f));
+    nsample = 0;
+    for(int i = 1; i < PAD_MAX_SAMPLES; ++i) {
+        if(pars->sample[i].smp == NULL)
+            break;
+        float dist = fabs(logfreq - logf(pars->sample[i].basefreq + 0.0001f));
+
+        if(dist < mindist) {
+            nsample = i;
+            mindist = dist;
+        }
+    }
 
-    NoteGlobalPar.FilterCenterPitch=pars->GlobalFilter->getfreq()+//center freq
-                                    pars->PFilterVelocityScale/127.0*6.0*  //velocity sensing
-                                    (VelF(velocity,pars->PFilterVelocityScaleFunction)-1);
+    int size = pars->sample[nsample].size;
+    if(size == 0)
+        size = 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(!legato) { //not sure
+        poshi_l = (int)(RND * (size - 1));
+        if(pars->PStereo != 0)
+            poshi_r = (poshi_l + size / 2) % size;
+        else
+            poshi_r = poshi_l;
+        poslo = 0.0f;
+    }
 
 
-    NoteGlobalPar.FreqEnvelope=new Envelope(pars->FreqEnvelope,basefreq);
-    NoteGlobalPar.FreqLfo=new LFO(pars->FreqLfo,basefreq);
+    if(pars->PPanning == 0)
+        NoteGlobalPar.Panning = RND;
+    else
+        NoteGlobalPar.Panning = pars->PPanning / 128.0f;
+
+    NoteGlobalPar.FilterCenterPitch = pars->GlobalFilter->getfreq() //center freq
+                                      + pars->PFilterVelocityScale / 127.0f
+                                      * 6.0f                                //velocity sensing
+                                      * (VelF(velocity,
+                                              pars->
+                                              PFilterVelocityScaleFunction) - 1);
+
+    if(!legato) {
+        if(pars->PPunchStrength != 0) {
+            NoteGlobalPar.Punch.Enabled = 1;
+            NoteGlobalPar.Punch.t = 1.0f; //start from 1.0f and to 0.0f
+            NoteGlobalPar.Punch.initialvalue =
+                ((powf(10, 1.5f * pars->PPunchStrength / 127.0f) - 1.0f)
+                 * VelF(velocity,
+                        pars->PPunchVelocitySensing));
+            float time =
+                powf(10, 3.0f * pars->PPunchTime / 127.0f) / 10000.0f;             //0.1f .. 100 ms
+            float stretch = powf(440.0f / freq, pars->PPunchStretch / 64.0f);
+            NoteGlobalPar.Punch.dt = 1.0f
+                                     / (time * synth->samplerate_f * stretch);
+        }
+        else
+            NoteGlobalPar.Punch.Enabled = 0;
 
-    NoteGlobalPar.AmpEnvelope=new Envelope(pars->AmpEnvelope,basefreq);
-    NoteGlobalPar.AmpLfo=new LFO(pars->AmpLfo,basefreq);
+        NoteGlobalPar.FreqEnvelope = new Envelope(pars->FreqEnvelope, basefreq);
+        NoteGlobalPar.FreqLfo      = new LFO(pars->FreqLfo, 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.AmpEnvelope = new Envelope(pars->AmpEnvelope, basefreq);
+        NoteGlobalPar.AmpLfo      = new LFO(pars->AmpLfo, basefreq);
+    }
 
-    NoteGlobalPar.AmpEnvelope->envout_dB();//discard the first envelope output
-    globaloldamplitude=globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout();
+    NoteGlobalPar.Volume = 4.0f
+                           * powf(0.1f, 3.0f * (1.0f - pars->PVolume / 96.0f))      //-60 dB .. 0 dB
+                           * VelF(velocity, pars->PAmpVelocityScaleFunction); //velocity sensing
 
-    NoteGlobalPar.GlobalFilterL=new Filter(pars->GlobalFilter);
-    NoteGlobalPar.GlobalFilterR=new Filter(pars->GlobalFilter);
+    NoteGlobalPar.AmpEnvelope->envout_dB(); //discard the first envelope output
+    globaloldamplitude = globalnewamplitude = NoteGlobalPar.Volume
+                                              * NoteGlobalPar.AmpEnvelope->
+                                              envout_dB()
+                                              * NoteGlobalPar.AmpLfo->amplfoout();
 
-    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);
+    if(!legato) {
+        NoteGlobalPar.GlobalFilterL = Filter::generate(pars->GlobalFilter);
+        NoteGlobalPar.GlobalFilterR = Filter::generate(pars->GlobalFilter);
 
-    ready=1;///sa il pun pe asta doar cand e chiar gata
+        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);
 
-    if (parameters->sample[nsample].smp==NULL) {
-        finished_=true;
+    if(pars->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::legatonote(float freq,
+                         float velocity,
+                         int portamento_,
+                         int midinote,
+                         bool externcall)
 {
-    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;
-                return;
-            }
-        }
-        if (Legato.msg==LM_ToNorm) Legato.msg=LM_Norm;
-    }
-
-    portamento=portamento_;
-    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);
-        };
-    };
-
-    released=false;
-    realfreq=basefreq;
-
-    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;
-        };
-    };
-
-    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;
-
-    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.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);
-
-
-    if (parameters->sample[nsample].smp==NULL) {
-        finished_=true;
+    if(legato.update(freq, velocity, portamento_, midinote, externcall))
         return;
-    };
 
-    // End of the PADlegatonote function.
-};
+    setup(freq, velocity, portamento_, midinote, true);
+}
 
 
 PADnote::~PADnote()
@@ -245,283 +194,239 @@ PADnote::~PADnote()
     delete (NoteGlobalPar.GlobalFilterR);
     delete (NoteGlobalPar.FilterEnvelope);
     delete (NoteGlobalPar.FilterLfo);
-    delete [] tmpwave;
-};
+}
 
 
-inline void PADnote::fadein(REALTYPE *smps)
+inline void PADnote::fadein(float *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 < synth->buffersize; ++i)
+        if((smps[i - 1] < 0.0f) && (smps[i] > 0.0f))
+            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;
+    float tmp = (synth->buffersize_f - 1.0f) / (zerocrossings + 1) / 3.0f;
+    if(tmp < 8.0f)
+        tmp = 8.0f;
 
     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 > synth->buffersize)
+        n = synth->buffersize;
+    for(int i = 0; i < n; ++i) { //fade-in
+        float tmp = 0.5f - cosf((float)i / (float) n * PI) * 0.5f;
+        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();
+    float globalpitch, globalfilterpitch;
+    globalpitch = 0.01f * (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;
+    float tmpfilterfreq = globalfilterpitch + ctl->filtercutoff.relfreq
+                          + NoteGlobalPar.FilterFreqTracking;
 
-    tmpfilterfreq=NoteGlobalPar.GlobalFilterL->getrealfreq(tmpfilterfreq);
+    tmpfilterfreq = Filter::getrealfreq(tmpfilterfreq);
 
-    REALTYPE globalfilterq=NoteGlobalPar.FilterQ*ctl->filterq.relq;
-    NoteGlobalPar.GlobalFilterL->setfreq_and_q(tmpfilterfreq,globalfilterq);
-    NoteGlobalPar.GlobalFilterR->setfreq_and_q(tmpfilterfreq,globalfilterq);
+    float 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"
-        };
-    };
+    float portamentofreqrap = 1.0f;
+    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
+               * powf(2.0f, globalpitch / 12.0f) * ctl->pitchwheel.relfreq;
+}
 
 
-int PADnote::Compute_Linear(REALTYPE *outl,REALTYPE *outr,int freqhi,REALTYPE freqlo)
+int PADnote::Compute_Linear(float *outl,
+                            float *outr,
+                            int freqhi,
+                            float 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)
+    float *smps = pars->sample[nsample].smp;
+    if(smps == NULL) {
+        finished_ = true;
+        return 1;
+    }
+    int size = pars->sample[nsample].size;
+    for(int i = 0; i < synth->buffersize; ++i) {
+        poshi_l += freqhi;
+        poshi_r += freqhi;
+        poslo   += freqlo;
+        if(poslo >= 1.0f) {
+            poshi_l += 1;
+            poshi_r += 1;
+            poslo   -= 1.0f;
+        }
+        if(poshi_l >= size)
+            poshi_l %= size;
+        if(poshi_r >= size)
+            poshi_r %= size;
+
+        outl[i] = smps[poshi_l] * (1.0f - poslo) + smps[poshi_l + 1] * poslo;
+        outr[i] = smps[poshi_r] * (1.0f - poslo) + smps[poshi_r + 1] * poslo;
+    }
+    return 1;
+}
+int PADnote::Compute_Cubic(float *outl,
+                           float *outr,
+                           int freqhi,
+                           float 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;
+    float *smps = pars->sample[nsample].smp;
+    if(smps == NULL) {
+        finished_ = true;
+        return 1;
+    }
+    int   size = pars->sample[nsample].size;
+    float xm1, x0, x1, x2, a, b, c;
+    for(int i = 0; i < synth->buffersize; ++i) {
+        poshi_l += freqhi;
+        poshi_r += freqhi;
+        poslo   += freqlo;
+        if(poslo >= 1.0f) {
+            poshi_l += 1;
+            poshi_r += 1;
+            poslo   -= 1.0f;
+        }
+        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.0f * (x0 - x1) - xm1 + x2) * 0.5f;
+        b       = 2.0f * x1 + xm1 - (5.0f * x0 + x2) * 0.5f;
+        c       = (x1 - xm1) * 0.5f;
         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.0f * (x0 - x1) - xm1 + x2) * 0.5f;
+        b       = 2.0f * x1 + xm1 - (5.0f * x0 + x2) * 0.5f;
+        c       = (x1 - xm1) * 0.5f;
         outr[i] = (((a * poslo) + b) * poslo + c) * poslo + x0;
-    };
-    return(1);
-};
+    }
+    return 1;
+}
 
 
-int PADnote::noteout(REALTYPE *outl,REALTYPE *outr)
+int PADnote::noteout(float *outl, float *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;
+    float *smps = pars->sample[nsample].smp;
+    if(smps == NULL) {
+        for(int i = 0; i < synth->buffersize; ++i) {
+            outl[i] = 0.0f;
+            outr[i] = 0.0f;
+        }
+        return 1;
+    }
+    float smpfreq = pars->sample[nsample].basefreq;
 
 
-    REALTYPE freqrap=realfreq/smpfreq;
-    int freqhi=(int) (floor(freqrap));
-    REALTYPE freqlo=freqrap-floor(freqrap);
+    float freqrap = realfreq / smpfreq;
+    int   freqhi  = (int) (floor(freqrap));
+    float 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 < synth->buffersize; ++i) {
+            float punchamp = NoteGlobalPar.Punch.initialvalue
+                             * NoteGlobalPar.Punch.t + 1.0f;
+            outl[i] *= punchamp;
+            outr[i] *= punchamp;
+            NoteGlobalPar.Punch.t -= NoteGlobalPar.Punch.dt;
+            if(NoteGlobalPar.Punch.t < 0.0f) {
+                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 < synth->buffersize; ++i) {
+            float tmpvol = INTERPOLATE_AMPLITUDE(globaloldamplitude,
+                                                 globalnewamplitude,
+                                                 i,
+                                                 synth->buffersize);
+            outl[i] *= tmpvol * NoteGlobalPar.Panning;
+            outr[i] *= tmpvol * (1.0f - NoteGlobalPar.Panning);
+        }
+    else
+        for(int i = 0; i < synth->buffersize; ++i) {
+            outl[i] *= globalnewamplitude * NoteGlobalPar.Panning;
+            outr[i] *= globalnewamplitude * (1.0f - 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;
-            }
-        }
-    }
-    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) {
-                // 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);
-                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++) {
-            Legato.decounter--;
-            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;
-        }
-        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++) {
-            Legato.decounter--;
-            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;
-                // 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);
-                break;
-            }
-            Legato.fade.m-=Legato.fade.step;
-            outl[i]*=Legato.fade.m;
-            outr[i]*=Legato.fade.m;
+    legato.apply(*this, outl, outr);
+
+    // Check if the global amplitude is finished.
+    // If it does, disable the note
+    if(NoteGlobalPar.AmpEnvelope->finished() != 0) {
+        for(int i = 0; i < synth->buffersize; ++i) { //fade-out
+            float tmp = 1.0f - (float)i / synth->buffersize_f;
+            outl[i] *= tmp;
+            outr[i] *= tmp;
         }
-        break;
-    default :
-        break;
+        finished_ = 1;
     }
 
+    return 1;
+}
 
-    // 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);
-};
-
-int PADnote::finished()
+int PADnote::finished() const
 {
-    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
index 4722857..f401996 100644
--- a/src/Synth/PADnote.h
+++ b/src/Synth/PADnote.h
@@ -21,105 +21,100 @@
 #ifndef PAD_NOTE_H
 #define PAD_NOTE_H
 
+#include "SynthNote.h"
 #include "../globals.h"
 #include "../Params/PADnoteParameters.h"
 #include "../Params/Controller.h"
 #include "Envelope.h"
 #include "LFO.h"
-#include "../DSP/Filter.h"
 #include "../Params/Controller.h"
 
 /**The "pad" synthesizer*/
-class PADnote
+class PADnote:public SynthNote
 {
-public:
-    PADnote(PADnoteParameters *parameters, Controller *ctl_,REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool besilent);
-    ~PADnote();
+    public:
+        PADnote(PADnoteParameters *parameters,
+                Controller *ctl_,
+                float freq,
+                float velocity,
+                int portamento_,
+                int midinote,
+                bool besilent);
+        ~PADnote();
+
+        void legatonote(float freq, float velocity, int portamento_,
+                        int midinote, bool externcall);
+
+        int noteout(float *outl, float *outr);
+        int finished() const;
+        void relasekey();
+    private:
+        void setup(float freq, float velocity, int portamento_,
+                   int midinote, bool legato = false);
+        void fadein(float *smps);
+        void computecurrentparameters();
+        bool finished_;
+        PADnoteParameters *pars;
+
+        int   poshi_l, poshi_r;
+        float poslo;
+
+        float basefreq;
+        bool  firsttime, released;
+
+        int nsample, portamento;
+
+        int Compute_Linear(float *outl,
+                           float *outr,
+                           int freqhi,
+                           float freqlo);
+        int Compute_Cubic(float *outl,
+                          float *outr,
+                          int freqhi,
+                          float 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;
-
-private:
-    void fadein(REALTYPE *smps);
-    void computecurrentparameters();
-    bool finished_;
-    PADnoteParameters *pars;
+        struct {
+            /******************************************
+            *     FREQUENCY GLOBAL PARAMETERS        *
+            ******************************************/
+            float Detune;  //cents
 
-    int poshi_l,poshi_r;
-    REALTYPE poslo;
+            Envelope *FreqEnvelope;
+            LFO      *FreqLfo;
 
-    REALTYPE basefreq;
-    bool firsttime,released;
+            /********************************************
+             *     AMPLITUDE GLOBAL PARAMETERS          *
+             ********************************************/
+            float Volume;  // [ 0 .. 1 ]
 
-    int nsample,portamento;
+            float Panning;  // [ 0 .. 1 ]
 
-    int Compute_Linear(REALTYPE *outl,REALTYPE *outr,int freqhi,REALTYPE freqlo);
-    int Compute_Cubic(REALTYPE *outl,REALTYPE *outr,int freqhi,REALTYPE freqlo);
+            Envelope *AmpEnvelope;
+            LFO      *AmpLfo;
 
+            struct {
+                int   Enabled;
+                float initialvalue, dt, t;
+            } Punch;
 
-    struct {
-        /******************************************
-        *     FREQUENCY GLOBAL PARAMETERS        *
-        ******************************************/
-        REALTYPE Detune;//cents
+            /******************************************
+            *        FILTER GLOBAL PARAMETERS        *
+            ******************************************/
+            class Filter * GlobalFilterL, *GlobalFilterR;
 
-        Envelope *FreqEnvelope;
-        LFO *FreqLfo;
+            float FilterCenterPitch;  //octaves
+            float FilterQ;
+            float FilterFreqTracking;
 
-        /********************************************
-         *     AMPLITUDE GLOBAL PARAMETERS          *
-         ********************************************/
-        REALTYPE Volume;// [ 0 .. 1 ]
+            Envelope *FilterEnvelope;
 
-        REALTYPE Panning;// [ 0 .. 1 ]
+            LFO *FilterLfo;
+        } NoteGlobalPar;
 
-        Envelope *AmpEnvelope;
-        LFO *AmpLfo;
 
-        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;
+        float globaloldamplitude, globalnewamplitude, velocity, realfreq;
+        Controller *ctl;
 };
 
 
diff --git a/src/Synth/Resonance.cpp b/src/Synth/Resonance.cpp
index fcf043d..4eb4e01 100644
--- a/src/Synth/Resonance.cpp
+++ b/src/Synth/Resonance.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  Resonance.C - Resonance
+  Resonance.cpp - Resonance
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -23,101 +23,116 @@
 #include <stdlib.h>
 #include "Resonance.h"
 
-
-#include <stdio.h>
-
 Resonance::Resonance():Presets()
 {
     setpresettype("Presonance");
     defaults();
-};
+}
 
 Resonance::~Resonance()
-{
-};
+{}
 
 
 void Resonance::defaults()
 {
-    Penabled=0;
-    PmaxdB=20;
-    Pcenterfreq=64;//1 kHz
-    Poctavesfreq=64;
-    Pprotectthefundamental=0;
-    ctlcenter=1.0;
-    ctlbw=1.0;
-    for (int i=0;i<N_RES_POINTS;i++) Prespoints[i]=64;
-};
+    Penabled     = 0;
+    PmaxdB       = 20;
+    Pcenterfreq  = 64; //1 kHz
+    Poctavesfreq = 64;
+    Pprotectthefundamental = 0;
+    ctlcenter = 1.0f;
+    ctlbw     = 1.0f;
+    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, fft_t *fftdata, float 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
+    float sum = 0.0f,
+          l1  = logf(getfreqx(0.0f) * ctlcenter),
+          l2  = logf(2.0f) * getoctavesfreq() * ctlbw;
+
+    for(int i = 0; i < N_RES_POINTS; ++i)
+        if(sum < Prespoints[i])
+            sum = Prespoints[i];
+    if(sum < 1.0f)
+        sum = 1.0f;
+
+    for(int i = 1; i < n; ++i) {
+        float x = (logf(freq * i) - l1) / l2; //compute where the n-th hamonics fits to the graph
+        if(x < 0.0f)
+            x = 0.0f;
+
+        x *= N_RES_POINTS;
+        float 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;
+        float y =
+            (Prespoints[kx1]
+             * (1.0f - dx) + Prespoints[kx2] * dx) / 127.0f - sum / 127.0f;
+
+        y = powf(10.0f, y * PmaxdB / 20.0f);
+
+        if((Pprotectthefundamental != 0) && (i == 1))
+            y = 1.0f;
+
+        fftdata[i] *= y;
+    }
+}
 
 /*
  * Gets the response at the frequency "freq"
  */
 
-REALTYPE Resonance::getfreqresponse(REALTYPE freq)
+float Resonance::getfreqresponse(float 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);
-};
+    float l1 = logf(getfreqx(0.0f) * ctlcenter),
+          l2 = logf(2.0f) * getoctavesfreq() * ctlbw, sum = 0.0f;
+
+    for(int i = 0; i < N_RES_POINTS; ++i)
+        if(sum < Prespoints[i])
+            sum = Prespoints[i];
+    if(sum < 1.0f)
+        sum = 1.0f;
+
+    float x = (logf(freq) - l1) / l2; //compute where the n-th hamonics fits to the graph
+    if(x < 0.0f)
+        x = 0.0f;
+    x *= N_RES_POINTS;
+    float 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;
+    float result =
+        (Prespoints[kx1]
+         * (1.0f - dx) + Prespoints[kx2] * dx) / 127.0f - sum / 127.0f;
+    result = powf(10.0f, result * PmaxdB / 20.0f);
+    return result;
+}
 
 
 /*
@@ -125,129 +140,137 @@ 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;
-    };
-};
+    float old = Prespoints[0];
+    for(int i = 0; i < N_RES_POINTS; ++i) {
+        old = old * 0.4f + Prespoints[i] * 0.6f;
+        Prespoints[i] = (int) old;
+    }
+    old = Prespoints[N_RES_POINTS - 1];
+    for(int i = N_RES_POINTS - 1; i > 0; i--) {
+        old = old * 0.4f + Prespoints[i] * 0.6f;
+        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.0f);
+    for(int i = 0; i < N_RES_POINTS; ++i) {
+        Prespoints[i] = r;
+        if((RND < 0.1f) && (type == 0))
+            r = (int)(RND * 127.0f);
+        if((RND < 0.3f) && (type == 1))
+            r = (int)(RND * 127.0f);
+        if(type == 2)
+            r = (int)(RND * 127.0f);
+    }
     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 - cosf(x * PI)) * 0.5f;
+                Prespoints[x1 + k] = (int)(y1 * (1.0f - 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)
+float Resonance::getfreqx(float x)
 {
-    if (x>1.0) x=1.0;
-    REALTYPE octf=pow(2.0,getoctavesfreq());
-    return(getcenterfreq()/sqrt(octf)*pow(octf,x));
-};
+    if(x > 1.0f)
+        x = 1.0f;
+    float octf = powf(2.0f, getoctavesfreq());
+    return getcenterfreq() / sqrt(octf) * powf(octf, x);
+}
 
 /*
  * Get the x coordinate from frequency (used by the UI)
  */
-REALTYPE Resonance::getfreqpos(REALTYPE freq)
+float Resonance::getfreqpos(float freq)
 {
-    return((log(freq)-log(getfreqx(0.0)))/log(2.0)/getoctavesfreq());
-};
+    return (logf(freq) - logf(getfreqx(0.0f))) / logf(2.0f) / getoctavesfreq();
+}
 
 /*
  * Get the center frequency of the resonance graph
  */
-REALTYPE Resonance::getcenterfreq()
+float Resonance::getcenterfreq()
 {
-    return(10000.0*pow(10,-(1.0-Pcenterfreq/127.0)*2.0));
-};
+    return 10000.0f * powf(10, -(1.0f - Pcenterfreq / 127.0f) * 2.0f);
+}
 
 /*
  * Get the number of octave that the resonance functions applies to
  */
-REALTYPE Resonance::getoctavesfreq()
+float Resonance::getoctavesfreq()
 {
-    return(0.25+10.0*Poctavesfreq/127.0);
-};
+    return 0.25f + 10.0f * Poctavesfreq / 127.0f;
+}
 
-void Resonance::sendcontroller(MidiControllers ctl,REALTYPE par)
+void Resonance::sendcontroller(MidiControllers ctl, float 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
index 458ace0..7778571 100644
--- a/src/Synth/Resonance.h
+++ b/src/Synth/Resonance.h
@@ -26,44 +26,45 @@
 #include "../Misc/Util.h"
 #include "../Misc/XMLwrapper.h"
 #include "../Params/Presets.h"
+#include "../DSP/FFTwrapper.h"
 
 #define N_RES_POINTS 256
 
 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);
+    public:
+        Resonance();
+        ~Resonance();
+        void setpoint(int n, unsigned char p);
+        void applyres(int n, fft_t *fftdata, float freq);
+        void smooth();
+        void interpolatepeaks(int type);
+        void randomize(int type);
 
-    void add2XML(XMLwrapper *xml);
-    void defaults();
-    void getfromXML(XMLwrapper *xml);
+        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);
+        float getfreqpos(float freq);
+        float getfreqx(float x);
+        float getfreqresponse(float freq);
+        float getcenterfreq();
+        float getoctavesfreq();
+        void sendcontroller(MidiControllers ctl, float 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
+        //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)
+        //controllers
+        float ctlcenter; //center frequency(relative)
+        float ctlbw; //bandwidth(relative)
 
-private:
+    private:
 };
 
 #endif
diff --git a/src/Synth/SUBnote.cpp b/src/Synth/SUBnote.cpp
index b366622..eb9b0df 100644
--- a/src/Synth/SUBnote.cpp
+++ b/src/Synth/SUBnote.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  SUBnote.C - The "subtractive" synthesizer
+  SUBnote.cpp - The "subtractive" synthesizer
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -20,427 +20,359 @@
 
 */
 
-#include <math.h>
-#include <stdlib.h>
-#include <stdio.h>
+#include <cmath>
+#include <cstdlib>
+#include <cstdio>
+#include <cassert>
 #include "../globals.h"
 #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_,
+                 float freq,
+                 float velocity,
+                 int portamento_,
+                 int midinote,
+                 bool besilent)
+    :SynthNote(freq, velocity, portamento_, midinote, besilent)
 {
-    ready=0;
-
-    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;
+    pars = parameters;
+    ctl  = ctl_;
+    NoteEnabled = ON;
+    setup(freq, velocity, portamento_, midinote);
+}
+
+void SUBnote::setup(float freq,
+                    float velocity,
+                    int portamento_,
+                    int midinote,
+                    bool legato)
+{
+    portamento  = portamento_;
+    NoteEnabled = ON;
+    volume      = powf(0.1f, 3.0f * (1.0f - pars->PVolume / 96.0f)); //-60 dB .. 0 dB
+    volume     *= VelF(velocity, pars->PAmpVelocityScaleFunction);
+    if(pars->PPanning != 0)
+        panning = pars->PPanning / 127.0f;
+    else
+        panning = RND;
+    if(!legato) {
+        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.0f;
+        int fixedfreqET = pars->PfixedfreqET;
+        if(fixedfreqET != 0) { //if the frequency varies according the keyboard note
+            float tmp =
+                (midinote
+                 - 69.0f) / 12.0f
+                * (powf(2.0f, (fixedfreqET - 1) / 63.0f) - 1.0f);
+            if(fixedfreqET <= 64)
+                basefreq *= powf(2.0f, tmp);
+            else
+                basefreq *= powf(3.0f, tmp);
+        }
+    }
+    float detune = getdetune(pars->PDetuneType,
+                             pars->PCoarseDetune,
+                             pars->PDetune);
+    basefreq *= powf(2.0f, detune / 1200.0f); //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);
-
-    GlobalFilterL=NULL;
-    GlobalFilterR=NULL;
-    GlobalFilterEnvelope=NULL;
+    GlobalFilterCenterPitch = pars->GlobalFilter->getfreq() //center freq
+                              + (pars->PGlobalFilterVelocityScale / 127.0f
+                                 * 6.0f)                                           //velocity sensing
+                              * (VelF(velocity,
+                                      pars->PGlobalFilterVelocityScaleFunction)
+                                 - 1);
+
+    if(!legato) {
+        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;
-        return;
-    };
-
-
-    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 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;
-
-        //Bandwidth Scale
-        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);
-
-        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 hmagnew=1.0-pars->Phmag[pos[n]]/127.0;
-        REALTYPE hgain;
-
-        switch (pars->Phmagtype) {
-        case 1:
-            hgain=exp(hmagnew*log(0.01));
-            break;
-        case 2:
-            hgain=exp(hmagnew*log(0.001));
-            break;
-        case 3:
-            hgain=exp(hmagnew*log(0.0001));
-            break;
-        case 4:
-            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);
-        };
-    };
-
-    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);
-
-    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)
-{
-    //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;
-                return;
-            }
-        }
-        if (Legato.msg==LM_ToNorm) Legato.msg=LM_Norm;
+    int harmonics = 0;
+    for(int n = 0; n < MAX_SUB_HARMONICS; ++n) {
+        if(pars->Phmag[n] == 0)
+            continue;
+        if(n * basefreq > synth->samplerate_f / 2.0f)
+            break;                            //remove the freqs above the Nyquist freq
+        pos[harmonics++] = n;
     }
-
-    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;
-
-    ///start=pars->Pstart;
-
-    int pos[MAX_SUB_HARMONICS];
-
-    if (pars->Pfixedfreq==0) basefreq=freq;
+    if(!legato)
+        firstnumharmonics = numharmonics = harmonics;
     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
+        if(harmonics > firstnumharmonics)
+            numharmonics = firstnumharmonics;
+        else
+            numharmonics = harmonics;
+    }
 
-    //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;
+
+    if(numharmonics == 0) {
+        NoteEnabled = OFF;
         return;
-    };
+    }
 
 
-    //how much the amplitude is normalised (because the harmonics)
-    REALTYPE reduceamp=0.0;
+    if(!legato) {
+        lfilter = new bpfilter[numstages * numharmonics];
+        if(stereo != 0)
+            rfilter = new bpfilter[numstages * numharmonics];
+    }
 
-    for (int n=0;n<numharmonics;n++) {
+    //how much the amplitude is normalised (because the harmonics)
+    float reduceamp = 0.0f;
 
-        REALTYPE freq=basefreq*(pos[n]+1);
+    for(int n = 0; n < numharmonics; ++n) {
+        float 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;
+        float bw =
+            powf(10, (pars->Pbandwidth - 127.0f) / 127.0f * 4) * numstages;
 
         //Bandwidth Scale
-        bw*=pow(1000/freq,(pars->Pbwscale-64.0)/64.0*3.0);
+        bw *= powf(1000 / freq, (pars->Pbwscale - 64.0f) / 64.0f * 3.0f);
 
         //Relative BandWidth
-        bw*=pow(100,(pars->Phrelbw[pos[n]]-64.0)/64.0);
+        bw *= powf(100, (pars->Phrelbw[pos[n]] - 64.0f) / 64.0f);
 
-        if (bw>25.0) bw=25.0;
+        if(bw > 25.0f)
+            bw = 25.0f;
 
         //try to keep same amplitude on all freqs and bw. (empirically)
-        REALTYPE gain=sqrt(1500.0/(bw*freq));
-
-        REALTYPE hmagnew=1.0-pars->Phmag[pos[n]]/127.0;
-        REALTYPE hgain;
+        float gain = sqrt(1500.0f / (bw * freq));
 
-        switch (pars->Phmagtype) {
-        case 1:
-            hgain=exp(hmagnew*log(0.01));
-            break;
-        case 2:
-            hgain=exp(hmagnew*log(0.001));
-            break;
-        case 3:
-            hgain=exp(hmagnew*log(0.0001));
-            break;
-        case 4:
-            hgain=exp(hmagnew*log(0.00001));
-            break;
-        default:
-            hgain=1.0-hmagnew;
-        };
-        gain*=hgain;
-        reduceamp+=hgain;
+        float hmagnew = 1.0f - pars->Phmag[pos[n]] / 127.0f;
+        float 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;
-
-    oldpitchwheel=0;
-    oldbandwidth=64;
-
-    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);
-    };
+        switch(pars->Phmagtype) {
+            case 1:
+                hgain = expf(hmagnew * logf(0.01f));
+                break;
+            case 2:
+                hgain = expf(hmagnew * logf(0.001f));
+                break;
+            case 3:
+                hgain = expf(hmagnew * logf(0.0001f));
+                break;
+            case 4:
+                hgain = expf(hmagnew * logf(0.00001f));
+                break;
+            default:
+                hgain = 1.0f - hmagnew;
+        }
+        gain      *= hgain;
+        reduceamp += hgain;
+
+        for(int nph = 0; nph < numstages; ++nph) {
+            float amp = 1.0f;
+            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);
+        }
+    }
 
-    // end of the altered initparameters function content.
-    ///////////////
+    if(reduceamp < 0.001f)
+        reduceamp = 1.0f;
+    volume /= reduceamp;
+
+    oldpitchwheel = 0;
+    oldbandwidth  = 64;
+    if(!legato) {
+        if(pars->Pfixedfreq == 0)
+            initparameters(basefreq);
+        else
+            initparameters(basefreq / 440.0f * freq);
+    }
+    else {
+        if(pars->Pfixedfreq == 0)
+            freq = basefreq;
+        else
+            freq *= basefreq / 440.0f;
+
+        if(pars->PGlobalFilterEnabled != 0) {
+            globalfiltercenterq      = pars->GlobalFilter->getq();
+            GlobalFilterFreqTracking = pars->GlobalFilter->getfreqtracking(
+                basefreq);
+        }
+    }
 
-    oldamplitude=newamplitude;
+    oldamplitude = newamplitude;
+}
 
-    // End of the SUBlegatonote function.
-};
+void SUBnote::legatonote(float freq, float velocity, int portamento_,
+                         int midinote, bool externcall)
+{
+    // Manage legato stuff
+    if(legato.update(freq, velocity, portamento_, midinote, externcall))
+        return;
 
+    setup(freq, velocity, portamento_, midinote, true);
+}
 
 SUBnote::~SUBnote()
 {
-    if (NoteEnabled!=OFF) KillNote();
-    delete [] tmpsmp;
-    delete [] tmprnd;
-};
+    if(NoteEnabled != OFF)
+        KillNote();
+}
 
 /*
  * 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;
+        delete FreqEnvelope;
+        delete BandWidthEnvelope;
+        delete GlobalFilterL;
+        delete GlobalFilterR;
+        delete GlobalFilterEnvelope;
+        NoteEnabled = OFF;
+    }
+}
 
 
 /*
  * Compute the filters coefficients
  */
-void SUBnote::computefiltercoefs(bpfilter &filter,REALTYPE freq,REALTYPE bw,REALTYPE gain)
+void SUBnote::computefiltercoefs(bpfilter &filter,
+                                 float freq,
+                                 float bw,
+                                 float gain)
 {
-    if (freq>SAMPLE_RATE/2.0-200.0) {
-        freq=SAMPLE_RATE/2.0-200.0;
-    };
+    if(freq > synth->samplerate_f / 2.0f - 200.0f)
+        freq = synth->samplerate_f / 2.0f - 200.0f;
 
-    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 (alpha>1) alpha=1;
-    if (alpha>bw) alpha=bw;
+    float omega = 2.0f * PI * freq / synth->samplerate_f;
+    float sn    = sinf(omega);
+    float cs    = cosf(omega);
+    float alpha = sn * sinh(LOG_2 / 2.0f * 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.0f + alpha) * filter.amp * gain;
+    filter.b2 = -alpha / (1.0f + alpha) * filter.amp * gain;
+    filter.a1 = -2.0f * cs / (1.0f + alpha);
+    filter.a2 = (1.0f - alpha) / (1.0f + alpha);
+}
 
 
 /*
  * Initialise the filters
  */
-void SUBnote::initfilter(bpfilter &filter,REALTYPE freq,REALTYPE bw,REALTYPE amp,REALTYPE mag)
+void SUBnote::initfilter(bpfilter &filter,
+                         float freq,
+                         float bw,
+                         float amp,
+                         float 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.0f;
+    filter.xn2 = 0.0f;
+
+    if(start == 0) {
+        filter.yn1 = 0.0f;
+        filter.yn2 = 0.0f;
+    }
+    else {
+        float a = 0.1f * mag; //empirically
+        float p = RND * 2.0f * PI;
+        if(start == 1)
+            a *= RND;
+        filter.yn1 = a * cosf(p);
+        filter.yn2 = a * cosf(p + freq * 2.0f * PI / synth->samplerate_f);
 
         //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 > synth->samplerate_f * 0.96f) {
+            filter.yn1 = 0.0f;
+            filter.yn2 = 0.0f;
+        }
+    }
 
-    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.0f);
+}
 
 /*
  * Do the filtering
  */
-void SUBnote::filter(bpfilter &filter,REALTYPE *smps)
+inline float SUBnote::SubFilter(bpfilter &filter, const float input) const
 {
-    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;
-
-    };
-};
+    const float out = input * filter.b0 + filter.b2 * filter.xn2
+                      - filter.a1 * filter.yn1 - filter.a2 * filter.yn2;
+    filter.xn2 = filter.xn1;
+    filter.xn1 = input;
+    filter.yn2 = filter.yn1;
+    filter.yn1 = out;
+    return out;
+}
+
+void SUBnote::filter(bpfilter &filter, float *smps)
+{
+    assert(synth->buffersize % 8 == 0);
+    for(int i = 0; i < synth->buffersize; i += 8) {
+        smps[i]     = SubFilter(filter, smps[i]);
+        smps[i + 1] = SubFilter(filter, smps[i + 1]);
+        smps[i + 2] = SubFilter(filter, smps[i + 2]);
+        smps[i + 3] = SubFilter(filter, smps[i + 3]);
+        smps[i + 4] = SubFilter(filter, smps[i + 4]);
+        smps[i + 5] = SubFilter(filter, smps[i + 5]);
+        smps[i + 6] = SubFilter(filter, smps[i + 6]);
+        smps[i + 7] = SubFilter(filter, smps[i + 7]);
+    }
+}
 
 /*
  * Init Parameters
  */
-void SUBnote::initparameters(REALTYPE freq)
+void SUBnote::initparameters(float 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 = Filter::generate(pars->GlobalFilter);
+        if(stereo)
+            GlobalFilterR = Filter::generate(pars->GlobalFilter);
+        GlobalFilterEnvelope = new Envelope(pars->GlobalFilterEnvelope,
+                                            freq);
+        GlobalFilterFreqTracking = pars->GlobalFilter->getfreqtracking(basefreq);
+    }
     computecurrentparameters();
-};
+}
 
 
 /*
@@ -448,213 +380,176 @@ 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;
+    if((FreqEnvelope != NULL) || (BandWidthEnvelope != NULL)
+       || (oldpitchwheel != ctl->pitchwheel.data)
+       || (oldbandwidth != ctl->bandwidth.data)
+       || (portamento != 0)) {
+        float envfreq = 1.0f;
+        float envbw   = 1.0f;
+        float gain    = 1.0f;
+
+        if(FreqEnvelope != NULL) {
+            envfreq = FreqEnvelope->envout() / 1200;
+            envfreq = powf(2.0f, 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 = powf(2, envbw);
+        }
+        envbw *= ctl->bandwidth.relbw; //bandwidth controller
+
+        float tmpgain = 1.0f / 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.0f;
+                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.0f;
+                    computefiltercoefs(
+                        rfilter[nph + n * numstages],
+                        rfilter[nph + n
+                                * numstages].freq * envfreq,
+                        rfilter[nph + n * numstages].bw * envbw,
+                        gain);
+                }
 
-    //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);
-    };
+        oldbandwidth  = ctl->bandwidth.data;
+        oldpitchwheel = ctl->pitchwheel.data;
+    }
+    newamplitude = volume * AmpEnvelope->envout_dB() * 2.0f;
 
-};
+    //Filter
+    if(GlobalFilterL != NULL) {
+        float globalfilterpitch = GlobalFilterCenterPitch
+                                  + GlobalFilterEnvelope->envout();
+        float filterfreq = globalfilterpitch + ctl->filtercutoff.relfreq
+                           + GlobalFilterFreqTracking;
+        filterfreq = Filter::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(float *outl, float *outr)
 {
-    int i;
+    memcpy(outl, denormalkillbuf, synth->bufferbytes);
+    memcpy(outr, denormalkillbuf, synth->bufferbytes);
 
-    for (i=0;i<SOUND_BUFFER_SIZE;i++) {
-        outl[i]=denormalkillbuf[i];
-        outr[i]=denormalkillbuf[i];
-    };
-
-    if (NoteEnabled==OFF) return(0);
+    if(NoteEnabled == OFF)
+        return 0;
 
+    float *tmprnd = getTmpBuffer();
+    float *tmpsmp = getTmpBuffer();
     //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++) tmpsmp[i]=tmprnd[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];
-    };
+    for(int i = 0; i < synth->buffersize; ++i)
+        tmprnd[i] = RND * 2.0f - 1.0f;
+    for(int n = 0; n < numharmonics; ++n) {
+        memcpy(tmpsmp, tmprnd, synth->bufferbytes);
+        for(int nph = 0; nph < numstages; ++nph)
+            filter(lfilter[nph + n * numstages], tmpsmp);
+        for(int i = 0; i < synth->buffersize; ++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++) {
-            for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpsmp[i]=tmprnd[i];
-            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 for (i=0;i<SOUND_BUFFER_SIZE;i++) outr[i]=outl[i];
-
-    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;
-    computecurrentparameters();
-
-    // Apply legato-specific sound signal modifications
-    if (Legato.silent) { // Silencer
-        if (Legato.msg!=LM_FadeIn) {
-            for (i=0;i<SOUND_BUFFER_SIZE;i++) {
-                outl[i]=0.0;
-                outr[i]=0.0;
-            }
+    if(stereo != 0) {
+        for(int i = 0; i < synth->buffersize; ++i)
+            tmprnd[i] = RND * 2.0f - 1.0f;
+        for(int n = 0; n < numharmonics; ++n) {
+            memcpy(tmpsmp, tmprnd, synth->bufferbytes);
+            for(int nph = 0; nph < numstages; ++nph)
+                filter(rfilter[nph + n * numstages], tmpsmp);
+            for(int i = 0; i < synth->buffersize; ++i)
+                outr[i] += tmpsmp[i];
         }
+        if(GlobalFilterR != NULL)
+            GlobalFilterR->filterout(&outr[0]);
     }
-    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) {
-                // 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);
-                break;
-            }
+    else
+        memcpy(outr, outl, synth->bufferbytes);
+    returnTmpBuffer(tmprnd);
+    returnTmpBuffer(tmpsmp);
+
+    if(firsttick != 0) {
+        int n = 10;
+        if(n > synth->buffersize)
+            n = synth->buffersize;
+        for(int i = 0; i < n; ++i) {
+            float ampfadein = 0.5f - 0.5f * cosf(
+                (float) i / (float) n * PI);
+            outl[i] *= ampfadein;
+            outr[i] *= ampfadein;
         }
-        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++) {
-            Legato.decounter--;
-            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;
+        firsttick = 0;
+    }
+
+    if(ABOVE_AMPLITUDE_THRESHOLD(oldamplitude, newamplitude))
+        // Amplitude interpolation
+        for(int i = 0; i < synth->buffersize; ++i) {
+            float tmpvol = INTERPOLATE_AMPLITUDE(oldamplitude,
+                                                 newamplitude,
+                                                 i,
+                                                 synth->buffersize);
+            outl[i] *= tmpvol * panning;
+            outr[i] *= tmpvol * (1.0f - panning);
         }
-        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++) {
-            Legato.decounter--;
-            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;
-                // 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);
-                break;
-            }
-            Legato.fade.m-=Legato.fade.step;
-            outl[i]*=Legato.fade.m;
-            outr[i]*=Legato.fade.m;
+    else
+        for(int i = 0; i < synth->buffersize; ++i) {
+            outl[i] *= newamplitude * panning;
+            outr[i] *= newamplitude * (1.0f - panning);
         }
-        break;
-    default :
-        break;
-    }
+
+    oldamplitude = newamplitude;
+    computecurrentparameters();
+
+    // Apply legato-specific sound signal modifications
+    legato.apply(*this, outl, outr);
 
     // 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(int i = 0; i < synth->buffersize; ++i) { //fade-out
+            float tmp = 1.0f - (float)i / synth->buffersize_f;
+            outl[i] *= tmp;
+            outr[i] *= tmp;
+        }
         KillNote();
-    };
-    return(1);
-};
+    }
+    return 1;
+}
 
 /*
  * Relase Key (Note Off)
@@ -662,17 +557,21 @@ 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)
+        FreqEnvelope->relasekey();
+    if(BandWidthEnvelope)
+        BandWidthEnvelope->relasekey();
+    if(GlobalFilterEnvelope)
+        GlobalFilterEnvelope->relasekey();
+}
 
 /*
  * Check if the note is finished
  */
-int SUBnote::finished()
+int SUBnote::finished() const
 {
-    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
index 48b55f1..21e4062 100644
--- a/src/Synth/SUBnote.h
+++ b/src/Synth/SUBnote.h
@@ -23,96 +23,86 @@
 #ifndef SUB_NOTE_H
 #define SUB_NOTE_H
 
+#include "SynthNote.h"
 #include "../globals.h"
 #include "../Params/SUBnoteParameters.h"
 #include "../Params/Controller.h"
 #include "Envelope.h"
 #include "../DSP/Filter.h"
 
-class SUBnote
+class SUBnote:public SynthNote
 {
-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);
-    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_, float freq,
+                float velocity, int portamento_, int midinote, bool besilent);
+        ~SUBnote();
+
+        void legatonote(float freq, float velocity, int portamento_,
+                        int midinote, bool externcall);
+
+        int noteout(float *outl, float *outr); //note output,return 0 if the note is finished
+        void relasekey();
+        int finished() const;
+    private:
+
+        void setup(float freq,
+                   float velocity,
+                   int portamento_,
+                   int midinote,
+                   bool legato = false);
+        void computecurrentparameters();
+        void initparameters(float 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
+        float     basefreq;
+        float     panning;
+        Envelope *AmpEnvelope;
+        Envelope *FreqEnvelope;
+        Envelope *BandWidthEnvelope;
+
+        Filter *GlobalFilterL, *GlobalFilterR;
+
+        Envelope *GlobalFilterEnvelope;
+
+        //internal values
+        ONOFFTYPE NoteEnabled;
+        int       firsttick, portamento;
+        float     volume, oldamplitude, newamplitude;
+
+        float GlobalFilterCenterPitch; //octaves
+        float GlobalFilterFreqTracking;
+
+        struct bpfilter {
+            float freq, bw, amp; //filter parameters
+            float a1, a2, b0, b2; //filter coefs. b1=0
+            float xn1, xn2, yn1, yn2; //filter internal values
+        };
+
+        void initfilter(bpfilter &filter,
+                        float freq,
+                        float bw,
+                        float amp,
+                        float mag);
+        void computefiltercoefs(bpfilter &filter,
+                                float freq,
+                                float bw,
+                                float gain);
+        inline float SubFilter(bpfilter &filter, float input) const;
+        inline void filter(bpfilter &filter, float *smps);
+
+        bpfilter *lfilter, *rfilter;
+
+        Controller *ctl;
+        int   oldpitchwheel, oldbandwidth;
+        float globalfiltercenterq;
 };
 
-
-
-
 #endif
-
diff --git a/src/Synth/SynthNote.cpp b/src/Synth/SynthNote.cpp
new file mode 100644
index 0000000..578a117
--- /dev/null
+++ b/src/Synth/SynthNote.cpp
@@ -0,0 +1,134 @@
+#include "SynthNote.h"
+#include "../globals.h"
+#include <cstring>
+
+SynthNote::SynthNote(float freq, float vel, int port, int note, bool quiet)
+    :legato(freq, vel, port, note, quiet)
+{}
+
+SynthNote::Legato::Legato(float freq, float vel, int port,
+                          int note, bool quiet)
+{
+    // Initialise some legato-specific vars
+    msg = LM_Norm;
+    fade.length = (int)(synth->samplerate_f * 0.005f);      // 0.005f seems ok.
+    if(fade.length < 1)
+        fade.length = 1;                    // (if something's fishy)
+    fade.step  = (1.0f / fade.length);
+    decounter  = -10;
+    param.freq = freq;
+    param.vel  = vel;
+    param.portamento = port;
+    param.midinote   = note;
+    lastfreq = 0.0f;
+    silent   = quiet;
+}
+
+int SynthNote::Legato::update(float freq, float velocity, int portamento_,
+                              int midinote_, bool externcall)
+{
+    if(externcall)
+        msg = LM_Norm;
+    if(msg != LM_CatchUp) {
+        lastfreq   = param.freq;
+        param.freq = freq;
+        param.vel  = velocity;
+        param.portamento = portamento_;
+        param.midinote   = midinote_;
+        if(msg == LM_Norm) {
+            if(silent) {
+                fade.m = 0.0f;
+                msg    = LM_FadeIn;
+            }
+            else {
+                fade.m = 1.0f;
+                msg    = LM_FadeOut;
+                return 1;
+            }
+        }
+        if(msg == LM_ToNorm)
+            msg = LM_Norm;
+    }
+    return 0;
+}
+
+void SynthNote::Legato::apply(SynthNote &note, float *outl, float *outr)
+{
+    if(silent) // Silencer
+        if(msg != LM_FadeIn) {
+            memset(outl, 0, synth->bufferbytes);
+            memset(outr, 0, synth->bufferbytes);
+        }
+    switch(msg) {
+        case LM_CatchUp: // Continue the catch-up...
+            if(decounter == -10)
+                decounter = fade.length;
+            //Yea, could be done without the loop...
+            for(int i = 0; i < synth->buffersize; ++i) {
+                decounter--;
+                if(decounter < 1) {
+                    // Catching-up done, we can finally set
+                    // the note to the actual parameters.
+                    decounter = -10;
+                    msg = LM_ToNorm;
+                    note.legatonote(param.freq, param.vel, param.portamento,
+                                    param.midinote, false);
+                    break;
+                }
+            }
+            break;
+        case LM_FadeIn: // Fade-in
+            if(decounter == -10)
+                decounter = fade.length;
+            silent = false;
+            for(int i = 0; i < synth->buffersize; ++i) {
+                decounter--;
+                if(decounter < 1) {
+                    decounter = -10;
+                    msg = LM_Norm;
+                    break;
+                }
+                fade.m  += fade.step;
+                outl[i] *= fade.m;
+                outr[i] *= fade.m;
+            }
+            break;
+        case LM_FadeOut: // Fade-out, then set the catch-up
+            if(decounter == -10)
+                decounter = fade.length;
+            for(int i = 0; i < synth->buffersize; ++i) {
+                decounter--;
+                if(decounter < 1) {
+                    for(int j = i; j < synth->buffersize; ++j) {
+                        outl[j] = 0.0f;
+                        outr[j] = 0.0f;
+                    }
+                    decounter = -10;
+                    silent    = true;
+                    // Fading-out done, now set the catch-up :
+                    decounter = fade.length;
+                    msg = LM_CatchUp;
+                    //This freq should make this now silent note to catch-up/resync
+                    //with the heard note for the same length it stayed at the
+                    //previous freq during the fadeout.
+                    float catchupfreq = param.freq * (param.freq / lastfreq);
+                    note.legatonote(catchupfreq, param.vel, param.portamento,
+                                    param.midinote, false);
+                    break;
+                }
+                fade.m  -= fade.step;
+                outl[i] *= fade.m;
+                outr[i] *= fade.m;
+            }
+            break;
+        default:
+            break;
+    }
+}
+
+void SynthNote::setVelocity(float velocity_) {
+    legato.setSilent(true); //Let legato.update(...) returns 0.
+    legatonote(legato.getFreq(), velocity_,
+               legato.getPortamento(), legato.getMidinote(), true);
+    legato.setDecounter(0); //avoid chopping sound due fade-in
+}
diff --git a/src/Synth/SynthNote.h b/src/Synth/SynthNote.h
new file mode 100644
index 0000000..3058e5d
--- /dev/null
+++ b/src/Synth/SynthNote.h
@@ -0,0 +1,86 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  Note.h - Abstract Base Class for synthesizers
+  Copyright (C) 2010-2010 Mark McCurry
+  Author: Mark McCurry
+
+  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 SYNTH_NOTE_H
+#define SYNTH_NOTE_H
+#include "../globals.h"
+#include "../Params/FilterParams.h"
+
+class SynthNote
+{
+    public:
+        SynthNote(float freq, float vel, int port, int note, bool quiet);
+        virtual ~SynthNote() {}
+
+        /**Compute Output Samples
+         * @return 0 if note is finished*/
+        virtual int noteout(float *outl, float *outr) = 0;
+
+        //TODO fix this spelling error [noisey commit]
+        /**Release the key for the note and start release portion of envelopes.*/
+        virtual void relasekey() = 0;
+
+        /**Return if note is finished.
+         * @return finished=1 unfinished=0*/
+        virtual int finished() const = 0;
+
+        virtual void legatonote(float freq, float velocity,
+                                int portamento_, int midinote_,
+                                bool externcall) = 0;
+        /* For polyphonic aftertouch needed */
+        void setVelocity(float velocity_);
+    protected:
+        // Legato transitions
+        class Legato
+        {
+            public:
+                Legato(float freq, float vel, int port,
+                       int note, bool quiet);
+
+                void apply(SynthNote &note, float *outl, float *outr);
+                int update(float freq, float velocity, int portamento_,
+                           int midinote_, bool externalcall);
+
+            private:
+                bool      silent;
+                float     lastfreq;
+                LegatoMsg msg;
+                int       decounter;
+                struct { // Fade In/Out vars
+                    int   length;
+                    float m, step;
+                } fade;
+                struct { // Note parameters
+                    float freq, vel;
+                    int   portamento, midinote;
+                } param;
+
+            public: /* Some get routines for legatonote calls (aftertouch feature)*/
+                float getFreq() {return param.freq; }
+                float getVelocity() {return param.vel; }
+                int getPortamento() {return param.portamento; }
+                int getMidinote() {return param.midinote; }
+                void setSilent(bool silent_) {silent = silent_; }
+                void setDecounter(int decounter_) {decounter = decounter_; }
+        } legato;
+};
+
+#endif
diff --git a/src/Tests/AdNoteTest.h b/src/Tests/AdNoteTest.h
new file mode 100644
index 0000000..fe5e172
--- /dev/null
+++ b/src/Tests/AdNoteTest.h
@@ -0,0 +1,176 @@
+#include <cxxtest/TestSuite.h>
+#include <iostream>
+#include <fstream>
+#include <ctime>
+#include <string>
+#include "../Misc/Master.h"
+#include "../Misc/Util.h"
+#include "../Synth/ADnote.h"
+#include "../Params/Presets.h"
+#include "../DSP/FFTwrapper.h"
+#include "../globals.h"
+
+using namespace std;
+SYNTH_T *synth;
+
+class AdNoteTest:public CxxTest::TestSuite
+{
+    public:
+
+        ADnote       *note;
+        Master       *master;
+        FFTwrapper   *fft;
+        Controller   *controller;
+        unsigned char testnote;
+
+
+        float *outR, *outL;
+
+        void setUp() {
+            //First the sensible settings and variables that have to be set:
+            synth = new SYNTH_T;
+            synth->buffersize = 256;
+
+            outL = new float[synth->buffersize];
+            for(int i = 0; i < synth->buffersize; ++i)
+                *(outL + i) = 0;
+            outR = new float[synth->buffersize];
+            for(int i = 0; i < synth->buffersize; ++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 float[synth->buffersize];
+            for(int i = 0; i < synth->buffersize; ++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...
+
+            fft = new FFTwrapper(synth->oscilsize);
+            //prepare the default settings
+            ADnoteParameters *defaultPreset = new ADnoteParameters(fft);
+
+            //Assert defaults
+            TS_ASSERT(!defaultPreset->VoicePar[1].Enabled);
+
+            XMLwrapper *wrap = new XMLwrapper();
+            cout << string(SOURCE_DIR) + string("/guitar-adnote.xmz")
+                 << endl;
+            wrap->loadXMLfile(string(SOURCE_DIR)
+                              + string("/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();
+
+            //verify xml was loaded
+            TS_ASSERT(defaultPreset->VoicePar[1].Enabled);
+
+
+
+            controller = new Controller();
+
+            //lets go with.... 50! as a nice note
+            testnote = 50;
+            float freq = 440.0f * powf(2.0f, (testnote - 69.0f) / 12.0f);
+
+            note = new ADnote(defaultPreset,
+                              controller,
+                              freq,
+                              120,
+                              0,
+                              testnote,
+                              false);
+
+            delete defaultPreset;
+            delete wrap;
+        }
+
+        void willNoteBeRunButIsHereForLinkingReasonsHowsThisForCamelCaseEh()
+        {
+            master = new Master();
+        }
+
+        void tearDown() {
+            delete note;
+            delete controller;
+            delete fft;
+            delete [] outL;
+            delete [] outR;
+            delete [] denormalkillbuf;
+            FFT_cleanup();
+            delete synth;
+        }
+
+        void testDefaults() {
+            int sampleCount = 0;
+
+//#define WRITE_OUTPUT
+
+#ifdef WRITE_OUTPUT
+            ofstream file("adnoteout", ios::out);
+#endif
+            note->noteout(outL, outR);
+#ifdef WRITE_OUTPUT
+            for(int i = 0; i < synth->buffersize; ++i)
+                file << outL[i] << std::endl;
+
+#endif
+            sampleCount += synth->buffersize;
+
+            TS_ASSERT_DELTA(outL[255], 0.254609f, 0.0001f);
+
+            note->relasekey();
+
+
+            note->noteout(outL, outR);
+            sampleCount += synth->buffersize;
+            TS_ASSERT_DELTA(outL[255], -0.102197f, 0.0001f);
+
+            note->noteout(outL, outR);
+            sampleCount += synth->buffersize;
+            TS_ASSERT_DELTA(outL[255], -0.111422f, 0.0001f);
+
+            note->noteout(outL, outR);
+            sampleCount += synth->buffersize;
+            TS_ASSERT_DELTA(outL[255], -0.021375f, 0.0001f);
+
+            note->noteout(outL, outR);
+            sampleCount += synth->buffersize;
+            TS_ASSERT_DELTA(outL[255], 0.149882f, 0.0001f);
+
+            while(!note->finished()) {
+                note->noteout(outL, outR);
+#ifdef WRITE_OUTPUT
+                for(int i = 0; i < synth->buffersize; ++i)
+                    file << outL[i] << std::endl;
+
+#endif
+                sampleCount += synth->buffersize;
+            }
+#ifdef WRITE_OUTPUT
+            file.close();
+#endif
+
+            TS_ASSERT_EQUALS(sampleCount, 9472);
+        }
+
+#define OUTPUT_PROFILE
+#ifdef OUTPUT_PROFILE
+        void testSpeed() {
+            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
+
+            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/CMakeLists.txt b/src/Tests/CMakeLists.txt
new file mode 100644
index 0000000..4f17420
--- /dev/null
+++ b/src/Tests/CMakeLists.txt
@@ -0,0 +1,24 @@
+#for tests looking for files stored in the source dir
+add_definitions(-DSOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
+
+CXXTEST_ADD_TEST(ControllerTest ControllerTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ControllerTest.h)
+CXXTEST_ADD_TEST(EchoTest EchoTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/EchoTest.h)
+#CXXTEST_ADD_TEST(SampleTest SampleTest.h)
+CXXTEST_ADD_TEST(MicrotonalTest MicrotonalTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/MicrotonalTest.h)
+CXXTEST_ADD_TEST(XMLwrapperTest XMLwrapper.cpp ${CMAKE_CURRENT_SOURCE_DIR}/XMLwrapperTest.h)
+CXXTEST_ADD_TEST(ADnoteTest AdNoteTest.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/AdNoteTest.h)
+CXXTEST_ADD_TEST(SUBnoteTest SubNoteTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/SubNoteTest.h)
+CXXTEST_ADD_TEST(OscilGenTest OscilGenTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/OscilGenTest.h)
+CXXTEST_ADD_TEST(RandTest RandTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/RandTest.h)
+
+set(test_lib ${NONGUI_LIBRARIES} ${ZLIB_LIBRARY} ${FFTW_LIBRARIES} ${MXML_LIBRARIES} pthread)
+message(STATUS "Linking tests with: ${test_lib}")
+target_link_libraries(ADnoteTest     ${test_lib})
+target_link_libraries(SUBnoteTest    ${test_lib})
+target_link_libraries(ControllerTest ${test_lib})
+target_link_libraries(EchoTest       ${test_lib})
+target_link_libraries(MicrotonalTest ${test_lib})
+target_link_libraries(OscilGenTest   ${test_lib})
+target_link_libraries(XMLwrapperTest ${test_lib})
+target_link_libraries(RandTest       ${test_lib})
diff --git a/src/Tests/ControllerTest.h b/src/Tests/ControllerTest.h
new file mode 100644
index 0000000..1a6147a
--- /dev/null
+++ b/src/Tests/ControllerTest.h
@@ -0,0 +1,75 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  ControllerTest.h - CxxTest for Params/Controller
+  Copyright (C) 2009-2009 Mark McCurry
+  Author: Mark McCurry
+
+  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 <cxxtest/TestSuite.h>
+#include <iostream>
+#include "../Params/Controller.h"
+#include "../globals.h"
+SYNTH_T *synth;
+
+class ControllerTest:public CxxTest::TestSuite
+{
+    public:
+        void setUp() {
+            synth   = new SYNTH_T;
+            testCtl = new Controller();
+        }
+
+        void tearDown() {
+            delete testCtl;
+            delete synth;
+        }
+
+
+        void testPortamentoRange() {
+            //Initialize portamento
+            testCtl->setportamento(127);
+            testCtl->portamento.time = 127;
+            testCtl->initportamento(40.0f, 400.0f, false);
+            //Bounds Check
+            while(testCtl->portamento.used) {
+                TS_ASSERT((0.0f <= testCtl->portamento.x)
+                          && (testCtl->portamento.x <= 1.0f));
+                TS_ASSERT((0.1f <= testCtl->portamento.freqrap)
+                          && (testCtl->portamento.freqrap <= 1.0f));
+                testCtl->updateportamento();
+            }
+            TS_ASSERT((0.0f <= testCtl->portamento.x)
+                      && (testCtl->portamento.x <= 1.0f));
+            TS_ASSERT((0.1f <= testCtl->portamento.freqrap)
+                      && (testCtl->portamento.freqrap <= 1.0f));
+        }
+
+        void testPortamentoValue() {
+            testCtl->setportamento(127);
+            testCtl->portamento.time = 127;
+            testCtl->initportamento(40.0f, 400.0f, 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.0290249f, 0.000001f)
+            TS_ASSERT_DELTA(testCtl->portamento.freqrap, 0.126122f, 0.000001f)
+        }
+
+    private:
+        Controller *testCtl;
+};
diff --git a/src/Tests/EchoTest.h b/src/Tests/EchoTest.h
index a9afc9b..08e5e9d 100644
--- a/src/Tests/EchoTest.h
+++ b/src/Tests/EchoTest.h
@@ -21,106 +21,105 @@
 */
 #include <cxxtest/TestSuite.h>
 #include <cmath>
+#include <cstdlib>
+#include <iostream>
 #include "../Effects/Echo.h"
 #include "../globals.h"
+SYNTH_T *synth;
 
-int SOUND_BUFFER_SIZE=256;
-int SAMPLE_RATE=1024;
+using namespace std;
 
-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;
-        inL=new float[SOUND_BUFFER_SIZE];
-        for (int i=0;i<SOUND_BUFFER_SIZE;++i)
-            *(inL+i)=0;
-        inR=new float[SOUND_BUFFER_SIZE];
-        for (int i=0;i<SOUND_BUFFER_SIZE;++i)
-            *(inR+i)=0;
-        testFX=new Echo(true,outL,outR);
-    }
-
-    void tearDown() {
-        delete[] inL;
-        delete[] inR;
-        delete[] outL;
-        delete[] outR;
-        delete testFX;
-    }
-
-
-    void testInit() {
-        //Make sure that the output will be zero at start
-        //(given a zero input)
-        testFX->out(inL,inR);
-        for (int i=0;i<SOUND_BUFFER_SIZE;++i)
-            TS_ASSERT_EQUALS(outL[i],0.0);
-        for (int i=0;i<SOUND_BUFFER_SIZE;++i)
-            TS_ASSERT_EQUALS(outR[i],0.0);
-    }
-
-    void testClear() {
-        char DELAY=2;
-        testFX->changepar(DELAY,127);
-        for (int i=0;i<SOUND_BUFFER_SIZE;++i)
-            *(inL+i)=1.0;
-        for (int i=0;i<SOUND_BUFFER_SIZE;++i)
-            *(inR+i)=1.0;
-        for (int i=0;i<50;++i)
-            testFX->out(inL,inR);
-        for (int i=0;i<SOUND_BUFFER_SIZE;++i) {
-            TS_ASSERT_DIFFERS(outL[i],0.0);
-            TS_ASSERT_DIFFERS(outR[i],0.0)
+    public:
+        void setUp() {
+            synth = new SYNTH_T;
+            outL  = new float[synth->buffersize];
+            for(int i = 0; i < synth->buffersize; ++i)
+                outL[i] = 0.0f;
+            outR = new float[synth->buffersize];
+            for(int i = 0; i < synth->buffersize; ++i)
+                outR[i] = 0.0f;
+            input = new Stereo<float *>(new float[synth->buffersize],
+                                        new float[synth->buffersize]);
+            for(int i = 0; i < synth->buffersize; ++i)
+                input->l[i] = input->r[i] = 0.0f;
+            testFX = new Echo(true, outL, outR);
         }
-        //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(inL,inR);
-        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() {
-        for (int i=0;i<SOUND_BUFFER_SIZE;++i)
-            *(inL+i)=1.0;
-        for (int i=0;i<SOUND_BUFFER_SIZE;++i)
-            *(inR+i)=1.0;
-        char FEEDBACK=5;
-        testFX->changepar(FEEDBACK,127);
-        for (int i=0;i<4;++i)
-            testFX->out(inL,inR);
-        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
-        for (int i=0;i<SOUND_BUFFER_SIZE;++i)
-            *(inL+i)=0.0;
-        for (int i=0;i<SOUND_BUFFER_SIZE;++i)
-            *(inR+i)=0.0;
-        //give the echo time to fade based upon zero input and high feedback
-        for (int i=0;i<50;++i)
-            testFX->out(inL,inR);
-        TS_ASSERT_LESS_THAN(abs(outL[0]+outR[0])/2, amp);
-    }
 
+        void tearDown() {
+            delete[] input->r;
+            delete[] input->l;
+            delete input;
+            delete[] outL;
+            delete[] outR;
+            delete testFX;
+            delete synth;
+        }
 
 
+        void testInit() {
+            //Make sure that the output will be zero at start
+            //(given a zero input)
+            testFX->out(*input);
+            for(int i = 0; i < synth->buffersize; ++i) {
+                TS_ASSERT_DELTA(outL[i], 0.0f, 0.0001f);
+                TS_ASSERT_DELTA(outR[i], 0.0f, 0.0001f);
+            }
+        }
 
+        void testClear() {
+            char DELAY = 2;
+            testFX->changepar(DELAY, 127);
+
+            //flood with high input
+            for(int i = 0; i < synth->buffersize; ++i)
+                input->r[i] = input->l[i] = 1.0f;
+
+            for(int i = 0; i < 500; ++i)
+                testFX->out(*input);
+            for(int i = 0; i < synth->buffersize; ++i) {
+                TS_ASSERT_DIFFERS(outL[i], 0.0f);
+                TS_ASSERT_DIFFERS(outR[i], 0.0f)
+            }
+            //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 < synth->buffersize; ++i) {
+                TS_ASSERT_DELTA(outL[i], 0.0f, 0.0001f);
+                TS_ASSERT_DELTA(outR[i], 0.0f, 0.0001f);
+            }
+        }
+        //Insures that the proper decay occurs with high feedback
+        void testDecaywFb() {
+            //flood with high input
+            for(int i = 0; i < synth->buffersize; ++i)
+                input->r[i] = input->l[i] = 1.0f;
+            char FEEDBACK = 5;
+            testFX->changepar(FEEDBACK, 127);
+            for(int i = 0; i < 100; ++i)
+                testFX->out(*input);
+            for(int i = 0; i < synth->buffersize; ++i) {
+                TS_ASSERT_DIFFERS(outL[i], 0.0f);
+                TS_ASSERT_DIFFERS(outR[i], 0.0f)
+            }
+            float amp = abs(outL[0] + outR[0]) / 2;
+            //reset input to zero
+            for(int i = 0; i < synth->buffersize; ++i)
+                input->r[i] = input->l[i] = 0.0f;
+
+            //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_EQUALS(abs(outL[0] + outR[0]) / 2, amp);
+        }
 
-private:
-    float *inL,*inR,*outR,*outL;
-    Echo *testFX;
 
+    private:
+        Stereo<float *> *input;
+        float *outR, *outL;
+        Echo  *testFX;
 };
diff --git a/src/Tests/MicrotonalTest.h b/src/Tests/MicrotonalTest.h
new file mode 100644
index 0000000..ae0641c
--- /dev/null
+++ b/src/Tests/MicrotonalTest.h
@@ -0,0 +1,136 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  MicrotonalTest.h - CxxTest for Misc/Microtonal
+  Copyright (C) 2009-2009 Mark McCurry
+  Author: Mark McCurry
+
+  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 <cxxtest/TestSuite.h>
+#include <iostream>
+#include "../Misc/Microtonal.h"
+#include <cstring>
+#include <string>
+#include <cstdio>
+#include "../globals.h"
+SYNTH_T *synth;
+
+using namespace std;
+
+class MicrotonalTest:public CxxTest::TestSuite
+{
+    public:
+        void setUp() {
+            synth     = new SYNTH_T;
+            testMicro = new Microtonal();
+        }
+
+        void tearDown() {
+            delete testMicro;
+            delete synth;
+        }
+
+        //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.0f);
+            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.4997f, 0.0001f);
+        }
+
+        //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);
+        }
+
+#if 0
+        /**\todo Test Saving/loading from file*/
+
+        //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*/
+#endif
+
+    private:
+        Microtonal *testMicro;
+};
diff --git a/src/Tests/OscilGenTest.h b/src/Tests/OscilGenTest.h
new file mode 100644
index 0000000..1c7c5d4
--- /dev/null
+++ b/src/Tests/OscilGenTest.h
@@ -0,0 +1,120 @@
+#include <cxxtest/TestSuite.h>
+#include <string>
+#include "../Synth/OscilGen.h"
+#include "../globals.h"
+SYNTH_T *synth;
+
+using namespace std;
+
+class OscilGenTest:public CxxTest::TestSuite
+{
+    public:
+        float  freq;
+        float *outR, *outL;
+        FFTwrapper *fft;
+        OscilGen   *oscil;
+
+        void setUp() {
+            synth = new SYNTH_T;
+            //First the sensible settings and variables that have to be set:
+            synth->buffersize = 256;
+            synth->oscilsize  = 1024;
+
+            outL = new float[synth->oscilsize];
+            outR = new float[synth->oscilsize];
+            memset(outL, 0, sizeof(float) * synth->oscilsize);
+            memset(outR, 0, sizeof(float) * synth->oscilsize);
+
+            //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 float[synth->buffersize];
+            for(int i = 0; i < synth->buffersize; ++i)
+                denormalkillbuf[i] = 0;
+
+            //prepare the default settings
+            fft   = new FFTwrapper(synth->oscilsize);
+            oscil = new OscilGen(fft, NULL);
+
+            //Assert defaults [TODO]
+
+
+            XMLwrapper *wrap = new XMLwrapper();
+            wrap->loadXMLfile(string(SOURCE_DIR)
+                              + string("/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"));
+            TS_ASSERT(wrap->enterbranch("VOICE", 0));
+            TS_ASSERT(wrap->enterbranch("OSCIL"));
+            oscil->getfromXML(wrap);
+            delete wrap;
+
+            //verify xml was loaded [TODO]
+
+            //lets go with.... 50! as a nice note
+            const char testnote = 50;
+            freq = 440.0f * powf(2.0f, (testnote - 69.0f) / 12.0f);
+        }
+
+        void tearDown() {
+            delete oscil;
+            delete fft;
+            delete[] outL;
+            delete[] outR;
+            delete[] denormalkillbuf;
+            FFT_cleanup();
+            delete synth;
+        }
+
+        //verifies that initialization occurs
+        void testInit(void)
+        {
+            oscil->get(outL, freq);
+        }
+
+        void testOutput(void)
+        {
+            oscil->get(outL, freq);
+            TS_ASSERT_DELTA(outL[23], -0.044547f, 0.0001f);
+            TS_ASSERT_DELTA(outL[129], -0.018169f, 0.0001f);
+            TS_ASSERT_DELTA(outL[586], 0.045647f, 0.0001f);
+            TS_ASSERT_DELTA(outL[1023], -0.038334f, 0.0001f);
+        }
+
+        void testSpectrum(void)
+        {
+            oscil->getspectrum(synth->oscilsize / 2, outR, 1);
+            TS_ASSERT_DELTA(outR[0], 350.698059f, 0.0001f);
+            TS_ASSERT_DELTA(outR[1], 228.889267f, 0.0001f);
+            TS_ASSERT_DELTA(outR[2], 62.187931f, 0.0001f);
+            TS_ASSERT_DELTA(outR[3], 22.295225f, 0.0001f);
+            TS_ASSERT_DELTA(outR[4], 6.942001f, 0.0001f);
+            TS_ASSERT_DELTA(outR[26], 0.015110f, 0.0001f);
+            TS_ASSERT_DELTA(outR[47], 0.003425f, 0.0001f);
+            TS_ASSERT_DELTA(outR[65], 0.001293f, 0.0001f);
+        }
+
+        //performance testing
+        void testSpeed() {
+            const int samps = 15000;
+
+            int t_on = clock(); // timer before calling func
+            for(int i = 0; i < samps; ++i)
+                oscil->prepare();
+            int t_off = clock(); // timer when func returns
+
+            printf("OscilGenTest: %f seconds for %d prepares.\n",
+                   (static_cast<float>(t_off - t_on)) / CLOCKS_PER_SEC, samps);
+
+            t_on = clock(); // timer before calling func
+            for(int i = 0; i < samps; ++i)
+                oscil->get(outL, freq);
+            t_off = clock(); // timer when func returns
+
+            printf("OscilGenTest: %f seconds for %d gets.\n",
+                   (static_cast<float>(t_off - t_on)) / CLOCKS_PER_SEC, samps);
+        }
+};
diff --git a/src/Tests/RandTest.h b/src/Tests/RandTest.h
new file mode 100644
index 0000000..2a51e95
--- /dev/null
+++ b/src/Tests/RandTest.h
@@ -0,0 +1,41 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  RandTest.h - CxxTest for Pseudo-Random Number Generator
+  Copyright (C) 2009-2009 Mark McCurry
+  Author: Mark McCurry
+
+  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 "../Misc/Util.h"
+SYNTH_T *synth;
+
+#include <cstdlib>
+#include <cstdio>
+#include <cxxtest/TestSuite.h>
+
+class RandTest:public CxxTest::TestSuite
+{
+    public:
+        void testPRNG(void) {
+            //verify RND returns expected pattern when unseeded
+            TS_ASSERT_DELTA(RND, 0.607781, 0.00001);
+            TS_ASSERT_DELTA(RND, 0.591761, 0.00001);
+            TS_ASSERT_DELTA(RND, 0.186133, 0.00001);
+            TS_ASSERT_DELTA(RND, 0.286319, 0.00001);
+            TS_ASSERT_DELTA(RND, 0.511766, 0.00001);
+        }
+};
diff --git a/src/Tests/SampleTest.h b/src/Tests/SampleTest.h
deleted file mode 100644
index 0e84b19..0000000
--- a/src/Tests/SampleTest.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
-  ZynAddSubFX - a software synthesizer
-
-  SampleTest.h - CxxTest for Samples
-  Copyright (C) 2009-2009 Mark McCurry
-  Author: Mark McCurry
-
-  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 <cxxtest/TestSuite.h>
-#include "../Samples/AuSample.h"
-
-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);
-    }
-
-    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(fl, 50);
-        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
new file mode 100644
index 0000000..b97a342
--- /dev/null
+++ b/src/Tests/SubNoteTest.h
@@ -0,0 +1,161 @@
+//Based Upon AdNoteTest.h
+#include <cxxtest/TestSuite.h>
+#include <iostream>
+#include <fstream>
+#include <ctime>
+#include <string>
+#include "../Misc/Master.h"
+#include "../Misc/Util.h"
+#include "../Synth/SUBnote.h"
+#include "../Params/Presets.h"
+#include "../globals.h"
+SYNTH_T *synth;
+
+using namespace std;
+
+class SubNoteTest:public CxxTest::TestSuite
+{
+    public:
+
+        SUBnote      *note;
+        Master       *master;
+        Controller   *controller;
+        unsigned char testnote;
+
+
+        float *outR, *outL;
+
+        void setUp() {
+            synth = new SYNTH_T;
+            //First the sensible settings and variables that have to be set:
+            synth->buffersize = 256;
+
+            outL = new float[synth->buffersize];
+            for(int i = 0; i < synth->buffersize; ++i)
+                *(outL + i) = 0;
+            outR = new float[synth->buffersize];
+            for(int i = 0; i < synth->buffersize; ++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 float[synth->buffersize];
+            for(int i = 0; i < synth->buffersize; ++i)
+                denormalkillbuf[i] = 0;
+
+            //prepare the default settings
+            SUBnoteParameters *defaultPreset = new SUBnoteParameters();
+            XMLwrapper *wrap = new XMLwrapper();
+            wrap->loadXMLfile(string(SOURCE_DIR)
+                              + string("/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);
+
+            controller = new Controller();
+
+            //lets go with.... 50! as a nice note
+            testnote = 50;
+            float freq = 440.0f * powf(2.0f, (testnote - 69.0f) / 12.0f);
+
+            note = new SUBnote(defaultPreset,
+                               controller,
+                               freq,
+                               120,
+                               0,
+                               testnote,
+                               false);
+            delete wrap;
+            delete defaultPreset;
+        }
+
+        void willNoteBeRunButIsHereForLinkingReasonsHowsThisForCamelCaseEh()
+        {
+            master = new Master();
+        }
+
+        void tearDown() {
+            delete controller;
+            delete note;
+            delete [] outL;
+            delete [] outR;
+            delete [] denormalkillbuf;
+            clearTmpBuffers();
+            delete synth;
+        }
+
+        void testDefaults() {
+            //Note: if these tests fail it is due to the relationship between
+            //global.h::RND and SUBnote.cpp
+
+            int sampleCount = 0;
+
+//#define WRITE_OUTPUT
+
+#ifdef WRITE_OUTPUT
+            ofstream file("subnoteout", ios::out);
+#endif
+            note->noteout(outL, outR);
+#ifdef WRITE_OUTPUT
+            for(int i = 0; i < synth->buffersize; ++i)
+                file << outL[i] << std::endl;
+
+#endif
+            sampleCount += synth->buffersize;
+
+            TS_ASSERT_DELTA(outL[255], 0.0000f, 0.0001f);
+
+            note->relasekey();
+
+
+            note->noteout(outL, outR);
+            sampleCount += synth->buffersize;
+            TS_ASSERT_DELTA(outL[255], 0.0016f, 0.0001f);
+
+            note->noteout(outL, outR);
+            sampleCount += synth->buffersize;
+            TS_ASSERT_DELTA(outL[255], -0.0000f, 0.0001f);
+
+            note->noteout(outL, outR);
+            sampleCount += synth->buffersize;
+            TS_ASSERT_DELTA(outL[255], -0.0013f, 0.0001f);
+
+            note->noteout(outL, outR);
+            sampleCount += synth->buffersize;
+            TS_ASSERT_DELTA(outL[255], -0.0002f, 0.0001f);
+
+            while(!note->finished()) {
+                note->noteout(outL, outR);
+#ifdef WRITE_OUTPUT
+                for(int i = 0; i < synth->buffersize; ++i)
+                    file << outL[i] << std::endl;
+
+#endif
+                sampleCount += synth->buffersize;
+            }
+#ifdef WRITE_OUTPUT
+            file.close();
+#endif
+
+            TS_ASSERT_EQUALS(sampleCount, 2304);
+        }
+
+#define OUTPUT_PROFILE
+#ifdef OUTPUT_PROFILE
+        void testSpeed() {
+            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
+
+            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
new file mode 100644
index 0000000..bf31ae0
--- /dev/null
+++ b/src/Tests/XMLwrapperTest.h
@@ -0,0 +1,70 @@
+/*
+  ZynAddSubFX - a software synthesizer
+
+  XMLwrapperTest.h - CxxTest for Misc/XMLwrapper
+  Copyright (C) 2009-2009 Mark McCurry
+  Author: Mark McCurry
+
+  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 <cxxtest/TestSuite.h>
+#include "../Misc/XMLwrapper.h"
+#include <string>
+#include "../globals.h"
+SYNTH_T *synth;
+using namespace std;
+
+class XMLwrapperTest:public CxxTest::TestSuite
+{
+    public:
+        void setUp() {
+            xmla = new XMLwrapper;
+            xmlb = new XMLwrapper;
+        }
+
+
+        void testAddPar() {
+            xmla->addpar("my Pa*_ramet at er", 75);
+            TS_ASSERT_EQUALS(xmla->getpar("my Pa*_ramet at er", 0, -200, 200), 75);
+        }
+
+        //here to verify that no leaks occur
+        void testLoad() {
+            string location = string(SOURCE_DIR) + string(
+                "/Tests/guitar-adnote.xmz");
+            xmla->loadXMLfile(location);
+        }
+
+        void testAnotherLoad()
+        {
+            string dat =
+                "\n<?xml version=\"1.0f\" encoding=\"UTF-8\"?>\n\
+<!DOCTYPE ZynAddSubFX-data>\n\
+<ZynAddSubFX-data version-major=\"2\" version-minor=\"4\"\n\
+version-revision=\"1\" ZynAddSubFX-author=\"Nasca Octavian Paul\">\n\
+</ZynAddSubFX-data>\n";
+            xmlb->putXMLdata(dat.c_str());
+        }
+
+        void tearDown() {
+            delete xmla;
+            delete xmlb;
+        }
+
+
+    private:
+        XMLwrapper *xmla;
+        XMLwrapper *xmlb;
+};
diff --git a/src/Tests/guitar-adnote.xmz b/src/Tests/guitar-adnote.xmz
new file mode 100644
index 0000000..7f0d2c7
--- /dev/null
+++ b/src/Tests/guitar-adnote.xmz
@@ -0,0 +1,3835 @@
+
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE ZynAddSubFX-data>
+<ZynAddSubFX-data version-major="2" version-minor="4"
+version-revision="1" ZynAddSubFX-author="Nasca Octavian Paul">
+<INFORMATION>
+<par_bool name="PADsynth_used" value="yes" />
+</INFORMATION>
+<BASE_PARAMETERS>
+<par name="max_midi_parts" value="16" />
+<par name="max_kit_items_per_instrument" value="16" />
+<par name="max_system_effects" value="4" />
+<par name="max_insertion_effects" value="8" />
+<par name="max_instrument_effects" value="3" />
+<par name="max_addsynth_voices" value="8" />
+</BASE_PARAMETERS>
+<MASTER>
+<par name="volume" value="80" />
+<par name="key_shift" value="64" />
+<par_bool name="nrpn_receive" value="yes" />
+<MICROTONAL>
+<string name="name">12tET</string>
+<string name="comment">Equal Temperament 12 notes per octave</string>
+<par_bool name="invert_up_down" value="no" />
+<par name="invert_up_down_center" value="60" />
+<par_bool name="enabled" value="no" />
+<par name="global_fine_detune" value="64" />
+<par name="a_note" value="69" />
+<par_real name="a_freq" value="440" />
+</MICROTONAL>
+<PART id="0">
+<par_bool name="enabled" value="yes" />
+<par name="volume" value="96" />
+<par name="panning" value="64" />
+<par name="min_key" value="0" />
+<par name="max_key" value="127" />
+<par name="key_shift" value="64" />
+<par name="rcv_chn" value="0" />
+<par name="velocity_sensing" value="64" />
+<par name="velocity_offset" value="64" />
+<par_bool name="note_on" value="yes" />
+<par_bool name="poly_mode" value="yes" />
+<par name="legato_mode" value="0" />
+<par name="key_limit" value="15" />
+<INSTRUMENT>
+<INFO>
+<string name="name">Dist Guitar 2</string>
+<string name="author"></string>
+<string name="comments"></string>
+<par name="type" value="0" />
+</INFO>
+<INSTRUMENT_KIT>
+<par name="kit_mode" value="0" />
+<par_bool name="drum_mode" value="no" />
+<INSTRUMENT_KIT_ITEM id="0">
+<par_bool name="enabled" value="yes" />
+<string name="name"></string>
+<par_bool name="muted" value="no" />
+<par name="min_key" value="0" />
+<par name="max_key" value="127" />
+<par name="send_to_instrument_effect" value="0" />
+<par_bool name="add_enabled" value="yes" />
+<ADD_SYNTH_PARAMETERS>
+<par_bool name="stereo" value="yes" />
+<AMPLITUDE_PARAMETERS>
+<par name="volume" value="73" />
+<par name="panning" value="74" />
+<par name="velocity_sensing" value="85" />
+<par name="punch_strength" value="25" />
+<par name="punch_time" value="40" />
+<par name="punch_stretch" value="64" />
+<par name="punch_velocity_sensing" value="72" />
+<par name="harmonic_randomness_grouping" value="0" />
+<AMPLITUDE_ENVELOPE>
+<par_bool name="free_mode" value="no" />
+<par name="env_points" value="4" />
+<par name="env_sustain" value="2" />
+<par name="env_stretch" value="69" />
+<par_bool name="forced_release" value="yes" />
+<par_bool name="linear_envelope" value="no" />
+<par name="A_dt" value="0" />
+<par name="D_dt" value="93" />
+<par name="R_dt" value="47" />
+<par name="A_val" value="64" />
+<par name="D_val" value="64" />
+<par name="S_val" value="0" />
+<par name="R_val" value="64" />
+</AMPLITUDE_ENVELOPE>
+<AMPLITUDE_LFO>
+<par_real name="freq" value="0.629921" />
+<par name="intensity" value="0" />
+<par name="start_phase" value="64" />
+<par name="lfo_type" value="0" />
+<par name="randomness_amplitude" value="0" />
+<par name="randomness_frequency" value="0" />
+<par name="delay" value="0" />
+<par name="stretch" value="64" />
+<par_bool name="continous" value="no" />
+</AMPLITUDE_LFO>
+</AMPLITUDE_PARAMETERS>
+<FREQUENCY_PARAMETERS>
+<par name="detune" value="8192" />
+<par name="coarse_detune" value="0" />
+<par name="detune_type" value="1" />
+<par name="bandwidth" value="64" />
+<FREQUENCY_ENVELOPE>
+<par_bool name="free_mode" value="no" />
+<par name="env_points" value="3" />
+<par name="env_sustain" value="1" />
+<par name="env_stretch" value="0" />
+<par_bool name="forced_release" value="no" />
+<par_bool name="linear_envelope" value="no" />
+<par name="A_dt" value="7" />
+<par name="D_dt" value="10" />
+<par name="R_dt" value="48" />
+<par name="A_val" value="65" />
+<par name="D_val" value="64" />
+<par name="S_val" value="64" />
+<par name="R_val" value="58" />
+</FREQUENCY_ENVELOPE>
+<FREQUENCY_LFO>
+<par_real name="freq" value="0.543307" />
+<par name="intensity" value="29" />
+<par name="start_phase" value="64" />
+<par name="lfo_type" value="0" />
+<par name="randomness_amplitude" value="0" />
+<par name="randomness_frequency" value="0" />
+<par name="delay" value="19" />
+<par name="stretch" value="64" />
+<par_bool name="continous" value="no" />
+</FREQUENCY_LFO>
+</FREQUENCY_PARAMETERS>
+<FILTER_PARAMETERS>
+<par name="velocity_sensing_amplitude" value="34" />
+<par name="velocity_sensing" value="64" />
+<FILTER>
+<par name="category" value="0" />
+<par name="type" value="2" />
+<par name="freq" value="70" />
+<par name="q" value="40" />
+<par name="stages" value="0" />
+<par name="freq_track" value="64" />
+<par name="gain" value="64" />
+</FILTER>
+<FILTER_ENVELOPE>
+<par_bool name="free_mode" value="no" />
+<par name="env_points" value="4" />
+<par name="env_sustain" value="2" />
+<par name="env_stretch" value="0" />
+<par_bool name="forced_release" value="yes" />
+<par_bool name="linear_envelope" value="no" />
+<par name="A_dt" value="40" />
+<par name="D_dt" value="70" />
+<par name="R_dt" value="60" />
+<par name="A_val" value="64" />
+<par name="D_val" value="64" />
+<par name="S_val" value="64" />
+<par name="R_val" value="64" />
+</FILTER_ENVELOPE>
+<FILTER_LFO>
+<par_real name="freq" value="0.629921" />
+<par name="intensity" value="0" />
+<par name="start_phase" value="64" />
+<par name="lfo_type" value="0" />
+<par name="randomness_amplitude" value="0" />
+<par name="randomness_frequency" value="0" />
+<par name="delay" value="0" />
+<par name="stretch" value="64" />
+<par_bool name="continous" value="no" />
+</FILTER_LFO>
+</FILTER_PARAMETERS>
+<RESONANCE>
+<par_bool name="enabled" value="no" />
+</RESONANCE>
+<VOICE id="0">
+<par_bool name="enabled" value="yes" />
+<par name="type" value="0" />
+<par name="unison_size" value="1" />
+<par name="unison_frequency_spread" value="60" />
+<par name="unison_stereo_spread" value="64" />
+<par name="unison_vibratto" value="64" />
+<par name="unison_vibratto_speed" value="64" />
+<par name="unison_invert_phase" value="0" />
+<par name="delay" value="0" />
+<par_bool name="resonance" value="yes" />
+<par name="ext_oscil" value="-1" />
+<par name="ext_fm_oscil" value="-1" />
+<par name="oscil_phase" value="31" />
+<par name="oscil_fm_phase" value="93" />
+<par_bool name="filter_enabled" value="yes" />
+<par_bool name="filter_bypass" value="no" />
+<par name="fm_enabled" value="1" />
+<OSCIL>
+<par name="harmonic_mag_type" value="0" />
+<par name="base_function" value="9" />
+<par name="base_function_par" value="76" />
+<par name="base_function_modulation" value="0" />
+<par name="base_function_modulation_par1" value="64" />
+<par name="base_function_modulation_par2" value="64" />
+<par name="base_function_modulation_par3" value="32" />
+<par name="modulation" value="0" />
+<par name="modulation_par1" value="64" />
+<par name="modulation_par2" value="64" />
+<par name="modulation_par3" value="32" />
+<par name="wave_shaping" value="64" />
+<par name="wave_shaping_function" value="0" />
+<par name="filter_type" value="0" />
+<par name="filter_par1" value="64" />
+<par name="filter_par2" value="64" />
+<par name="filter_before_wave_shaping" value="0" />
+<par name="spectrum_adjust_type" value="0" />
+<par name="spectrum_adjust_par" value="64" />
+<par name="rand" value="127" />
+<par name="amp_rand_type" value="0" />
+<par name="amp_rand_power" value="64" />
+<par name="harmonic_shift" value="0" />
+<par_bool name="harmonic_shift_first" value="no" />
+<par name="adaptive_harmonics" value="0" />
+<par name="adaptive_harmonics_base_frequency" value="128" />
+<par name="adaptive_harmonics_power" value="100" />
+<HARMONICS>
+<HARMONIC id="1">
+<par name="mag" value="74" />
+<par name="phase" value="64" />
+</HARMONIC>
+<HARMONIC id="2">
+<par name="mag" value="127" />
+<par name="phase" value="64" />
+</HARMONIC>
+</HARMONICS>
+</OSCIL>
+<AMPLITUDE_PARAMETERS>
+<par name="panning" value="6" />
+<par name="volume" value="100" />
+<par_bool name="volume_minus" value="no" />
+<par name="velocity_sensing" value="127" />
+<par_bool name="amp_envelope_enabled" value="yes" />
+<AMPLITUDE_ENVELOPE>
+<par_bool name="free_mode" value="no" />
+<par name="env_points" value="4" />
+<par name="env_sustain" value="2" />
+<par name="env_stretch" value="64" />
+<par_bool name="forced_release" value="yes" />
+<par_bool name="linear_envelope" value="no" />
+<par name="A_dt" value="22" />
+<par name="D_dt" value="83" />
+<par name="R_dt" value="100" />
+<par name="A_val" value="64" />
+<par name="D_val" value="64" />
+<par name="S_val" value="127" />
+<par name="R_val" value="64" />
+</AMPLITUDE_ENVELOPE>
+<par_bool name="amp_lfo_enabled" value="yes" />
+<AMPLITUDE_LFO>
+<par_real name="freq" value="0.743661" />
+<par name="intensity" value="32" />
+<par name="start_phase" value="64" />
+<par name="lfo_type" value="0" />
+<par name="randomness_amplitude" value="0" />
+<par name="randomness_frequency" value="0" />
+<par name="delay" value="30" />
+<par name="stretch" value="64" />
+<par_bool name="continous" value="no" />
+</AMPLITUDE_LFO>
+</AMPLITUDE_PARAMETERS>
+<FREQUENCY_PARAMETERS>
+<par_bool name="fixed_freq" value="no" />
+<par name="fixed_freq_et" value="0" />
+<par name="detune" value="12040" />
+<par name="coarse_detune" value="0" />
+<par name="detune_type" value="0" />
+<par_bool name="freq_envelope_enabled" value="yes" />
+<FREQUENCY_ENVELOPE>
+<par_bool name="free_mode" value="no" />
+<par name="env_points" value="3" />
+<par name="env_sustain" value="1" />
+<par name="env_stretch" value="8" />
+<par_bool name="forced_release" value="no" />
+<par_bool name="linear_envelope" value="no" />
+<par name="A_dt" value="57" />
+<par name="D_dt" value="10" />
+<par name="R_dt" value="81" />
+<par name="A_val" value="39" />
+<par name="D_val" value="64" />
+<par name="S_val" value="64" />
+<par name="R_val" value="47" />
+</FREQUENCY_ENVELOPE>
+<par_bool name="freq_lfo_enabled" value="yes" />
+<FREQUENCY_LFO>
+<par_real name="freq" value="0.590551" />
+<par name="intensity" value="18" />
+<par name="start_phase" value="64" />
+<par name="lfo_type" value="0" />
+<par name="randomness_amplitude" value="0" />
+<par name="randomness_frequency" value="0" />
+<par name="delay" value="0" />
+<par name="stretch" value="64" />
+<par_bool name="continous" value="yes" />
+</FREQUENCY_LFO>
+</FREQUENCY_PARAMETERS>
+<FILTER_PARAMETERS>
+<FILTER>
+<par name="category" value="0" />
+<par name="type" value="2" />
+<par name="freq" value="65" />
+<par name="q" value="68" />
+<par name="stages" value="0" />
+<par name="freq_track" value="64" />
+<par name="gain" value="64" />
+</FILTER>
+<par_bool name="filter_envelope_enabled" value="yes" />
+<FILTER_ENVELOPE>
+<par_bool name="free_mode" value="no" />
+<par name="env_points" value="4" />
+<par name="env_sustain" value="2" />
+<par name="env_stretch" value="0" />
+<par_bool name="forced_release" value="no" />
+<par_bool name="linear_envelope" value="no" />
+<par name="A_dt" value="80" />
+<par name="D_dt" value="88" />
+<par name="R_dt" value="10" />
+<par name="A_val" value="65" />
+<par name="D_val" value="21" />
+<par name="S_val" value="64" />
+<par name="R_val" value="40" />
+</FILTER_ENVELOPE>
+<par_bool name="filter_lfo_enabled" value="yes" />
+<FILTER_LFO>
+<par_real name="freq" value="0.363701" />
+<par name="intensity" value="46" />
+<par name="start_phase" value="64" />
+<par name="lfo_type" value="0" />
+<par name="randomness_amplitude" value="0" />
+<par name="randomness_frequency" value="0" />
+<par name="delay" value="0" />
+<par name="stretch" value="64" />
+<par_bool name="continous" value="no" />
+</FILTER_LFO>
+</FILTER_PARAMETERS>
+<FM_PARAMETERS>
+<par name="input_voice" value="-1" />
+<par name="volume" value="46" />
+<par name="volume_damp" value="36" />
+<par name="velocity_sensing" value="92" />
+<par_bool name="amp_envelope_enabled" value="yes" />
+<AMPLITUDE_ENVELOPE>
+<par_bool name="free_mode" value="no" />
+<par name="env_points" value="4" />
+<par name="env_sustain" value="2" />
+<par name="env_stretch" value="46" />
+<par_bool name="forced_release" value="yes" />
+<par_bool name="linear_envelope" value="no" />
+<par name="A_dt" value="66" />
+<par name="D_dt" value="76" />
+<par name="R_dt" value="86" />
+<par name="A_val" value="64" />
+<par name="D_val" value="64" />
+<par name="S_val" value="111" />
+<par name="R_val" value="64" />
+</AMPLITUDE_ENVELOPE>
+<MODULATOR>
+<par name="detune" value="6444" />
+<par name="coarse_detune" value="2048" />
+<par name="detune_type" value="2" />
+<par_bool name="freq_envelope_enabled" value="yes" />
+<FREQUENCY_ENVELOPE>
+<par_bool name="free_mode" value="no" />
+<par name="env_points" value="3" />
+<par name="env_sustain" value="1" />
+<par name="env_stretch" value="0" />
+<par_bool name="forced_release" value="no" />
+<par_bool name="linear_envelope" value="no" />
+<par name="A_dt" value="102" />
+<par name="D_dt" value="10" />
+<par name="R_dt" value="68" />
+<par name="A_val" value="33" />
+<par name="D_val" value="64" />
+<par name="S_val" value="64" />
+<par name="R_val" value="28" />
+</FREQUENCY_ENVELOPE>
+<OSCIL>
+<par name="harmonic_mag_type" value="0" />
+<par name="base_function" value="0" />
+<par name="base_function_par" value="64" />
+<par name="base_function_modulation" value="0" />
+<par name="base_function_modulation_par1" value="64" />
+<par name="base_function_modulation_par2" value="64" />
+<par name="base_function_modulation_par3" value="32" />
+<par name="modulation" value="0" />
+<par name="modulation_par1" value="64" />
+<par name="modulation_par2" value="64" />
+<par name="modulation_par3" value="32" />
+<par name="wave_shaping" value="64" />
+<par name="wave_shaping_function" value="0" />
+<par name="filter_type" value="0" />
+<par name="filter_par1" value="64" />
+<par name="filter_par2" value="64" />
+<par name="filter_before_wave_shaping" value="0" />
+<par name="spectrum_adjust_type" value="0" />
+<par name="spectrum_adjust_par" value="64" />
+<par name="rand" value="64" />
+<par name="amp_rand_type" value="0" />
+<par name="amp_rand_power" value="64" />
+<par name="harmonic_shift" value="0" />
+<par_bool name="harmonic_shift_first" value="no" />
+<par name="adaptive_harmonics" value="0" />
+<par name="adaptive_harmonics_base_frequency" value="128" />
+<par name="adaptive_harmonics_power" value="100" />
+<HARMONICS>
+<HARMONIC id="1">
+<par name="mag" value="127" />
+<par name="phase" value="64" />
+</HARMONIC>
+</HARMONICS>
+</OSCIL>
+</MODULATOR>
+</FM_PARAMETERS>
+</VOICE>
+<VOICE id="1">
+<par_bool name="enabled" value="yes" />
+<par name="type" value="0" />
+<par name="unison_size" value="1" />
+<par name="unison_frequency_spread" value="60" />
+<par name="unison_stereo_spread" value="64" />
+<par name="unison_vibratto" value="64" />
+<par name="unison_vibratto_speed" value="64" />
+<par name="unison_invert_phase" value="0" />
+<par name="delay" value="0" />
+<par_bool name="resonance" value="yes" />
+<par name="ext_oscil" value="0" />
+<par name="ext_fm_oscil" value="-1" />
+<par name="oscil_phase" value="64" />
+<par name="oscil_fm_phase" value="64" />
+<par_bool name="filter_enabled" value="no" />
+<par_bool name="filter_bypass" value="no" />
+<par name="fm_enabled" value="0" />
+<OSCIL>
+<par name="harmonic_mag_type" value="0" />
+<par name="base_function" value="0" />
+<par name="base_function_par" value="64" />
+<par name="base_function_modulation" value="0" />
+<par name="base_function_modulation_par1" value="64" />
+<par name="base_function_modulation_par2" value="64" />
+<par name="base_function_modulation_par3" value="32" />
+<par name="modulation" value="0" />
+<par name="modulation_par1" value="64" />
+<par name="modulation_par2" value="64" />
+<par name="modulation_par3" value="32" />
+<par name="wave_shaping" value="64" />
+<par name="wave_shaping_function" value="0" />
+<par name="filter_type" value="0" />
+<par name="filter_par1" value="64" />
+<par name="filter_par2" value="64" />
+<par name="filter_before_wave_shaping" value="0" />
+<par name="spectrum_adjust_type" value="0" />
+<par name="spectrum_adjust_par" value="64" />
+<par name="rand" value="64" />
+<par name="amp_rand_type" value="0" />
+<par name="amp_rand_power" value="64" />
+<par name="harmonic_shift" value="0" />
+<par_bool name="harmonic_shift_first" value="no" />
+<par name="adaptive_harmonics" value="0" />
+<par name="adaptive_harmonics_base_frequency" value="128" />
+<par name="adaptive_harmonics_power" value="100" />
+<HARMONICS>
+<HARMONIC id="1">
+<par name="mag" value="127" />
+<par name="phase" value="64" />
+</HARMONIC>
+</HARMONICS>
+</OSCIL>
+<AMPLITUDE_PARAMETERS>
+<par name="panning" value="0" />
+<par name="volume" value="100" />
+<par_bool name="volume_minus" value="no" />
+<par name="velocity_sensing" value="127" />
+<par_bool name="amp_envelope_enabled" value="no" />
+<par_bool name="amp_lfo_enabled" value="no" />
+</AMPLITUDE_PARAMETERS>
+<FREQUENCY_PARAMETERS>
+<par_bool name="fixed_freq" value="no" />
+<par name="fixed_freq_et" value="0" />
+<par name="detune" value="7902" />
+<par name="coarse_detune" value="0" />
+<par name="detune_type" value="0" />
+<par_bool name="freq_envelope_enabled" value="no" />
+<par_bool name="freq_lfo_enabled" value="yes" />
+<FREQUENCY_LFO>
+<par_real name="freq" value="0.393701" />
+<par name="intensity" value="20" />
+<par name="start_phase" value="66" />
+<par name="lfo_type" value="0" />
+<par name="randomness_amplitude" value="0" />
+<par name="randomness_frequency" value="0" />
+<par name="delay" value="0" />
+<par name="stretch" value="64" />
+<par_bool name="continous" value="yes" />
+</FREQUENCY_LFO>
+</FREQUENCY_PARAMETERS>
+</VOICE>
+<VOICE id="2">
+<par_bool name="enabled" value="yes" />
+<par name="type" value="0" />
+<par name="unison_size" value="1" />
+<par name="unison_frequency_spread" value="60" />
+<par name="unison_stereo_spread" value="64" />
+<par name="unison_vibratto" value="64" />
+<par name="unison_vibratto_speed" value="64" />
+<par name="unison_invert_phase" value="0" />
+<par name="delay" value="0" />
+<par_bool name="resonance" value="yes" />
+<par name="ext_oscil" value="0" />
+<par name="ext_fm_oscil" value="-1" />
+<par name="oscil_phase" value="64" />
+<par name="oscil_fm_phase" value="64" />
+<par_bool name="filter_enabled" value="no" />
+<par_bool name="filter_bypass" value="no" />
+<par name="fm_enabled" value="0" />
+<OSCIL>
+<par name="harmonic_mag_type" value="0" />
+<par name="base_function" value="0" />
+<par name="base_function_par" value="64" />
+<par name="base_function_modulation" value="0" />
+<par name="base_function_modulation_par1" value="64" />
+<par name="base_function_modulation_par2" value="64" />
+<par name="base_function_modulation_par3" value="32" />
+<par name="modulation" value="0" />
+<par name="modulation_par1" value="64" />
+<par name="modulation_par2" value="64" />
+<par name="modulation_par3" value="32" />
+<par name="wave_shaping" value="64" />
+<par name="wave_shaping_function" value="0" />
+<par name="filter_type" value="0" />
+<par name="filter_par1" value="64" />
+<par name="filter_par2" value="64" />
+<par name="filter_before_wave_shaping" value="0" />
+<par name="spectrum_adjust_type" value="0" />
+<par name="spectrum_adjust_par" value="64" />
+<par name="rand" value="64" />
+<par name="amp_rand_type" value="0" />
+<par name="amp_rand_power" value="64" />
+<par name="harmonic_shift" value="0" />
+<par_bool name="harmonic_shift_first" value="no" />
+<par name="adaptive_harmonics" value="0" />
+<par name="adaptive_harmonics_base_frequency" value="128" />
+<par name="adaptive_harmonics_power" value="100" />
+<HARMONICS>
+<HARMONIC id="1">
+<par name="mag" value="127" />
+<par name="phase" value="64" />
+</HARMONIC>
+</HARMONICS>
+</OSCIL>
+<AMPLITUDE_PARAMETERS>
+<par name="panning" value="127" />
+<par name="volume" value="100" />
+<par_bool name="volume_minus" value="no" />
+<par name="velocity_sensing" value="127" />
+<par_bool name="amp_envelope_enabled" value="no" />
+<par_bool name="amp_lfo_enabled" value="no" />
+</AMPLITUDE_PARAMETERS>
+<FREQUENCY_PARAMETERS>
+<par_bool name="fixed_freq" value="no" />
+<par name="fixed_freq_et" value="0" />
+<par name="detune" value="8192" />
+<par name="coarse_detune" value="0" />
+<par name="detune_type" value="0" />
+<par_bool name="freq_envelope_enabled" value="no" />
+<par_bool name="freq_lfo_enabled" value="yes" />
+<FREQUENCY_LFO>
+<par_real name="freq" value="0.393701" />
+<par name="intensity" value="18" />
+<par name="start_phase" value="67" />
+<par name="lfo_type" value="0" />
+<par name="randomness_amplitude" value="0" />
+<par name="randomness_frequency" value="0" />
+<par name="delay" value="0" />
+<par name="stretch" value="64" />
+<par_bool name="continous" value="yes" />
+</FREQUENCY_LFO>
+</FREQUENCY_PARAMETERS>
+</VOICE>
+<VOICE id="3">
+<par_bool name="enabled" value="yes" />
+<par name="type" value="0" />
+<par name="unison_size" value="1" />
+<par name="unison_frequency_spread" value="60" />
+<par name="unison_stereo_spread" value="64" />
+<par name="unison_vibratto" value="64" />
+<par name="unison_vibratto_speed" value="64" />
+<par name="unison_invert_phase" value="0" />
+<par name="delay" value="0" />
+<par_bool name="resonance" value="yes" />
+<par name="ext_oscil" value="-1" />
+<par name="ext_fm_oscil" value="-1" />
+<par name="oscil_phase" value="64" />
+<par name="oscil_fm_phase" value="64" />
+<par_bool name="filter_enabled" value="no" />
+<par_bool name="filter_bypass" value="no" />
+<par name="fm_enabled" value="0" />
+<OSCIL>
+<par name="harmonic_mag_type" value="0" />
+<par name="base_function" value="0" />
+<par name="base_function_par" value="64" />
+<par name="base_function_modulation" value="0" />
+<par name="base_function_modulation_par1" value="64" />
+<par name="base_function_modulation_par2" value="64" />
+<par name="base_function_modulation_par3" value="32" />
+<par name="modulation" value="0" />
+<par name="modulation_par1" value="64" />
+<par name="modulation_par2" value="64" />
+<par name="modulation_par3" value="32" />
+<par name="wave_shaping" value="64" />
+<par name="wave_shaping_function" value="0" />
+<par name="filter_type" value="0" />
+<par name="filter_par1" value="64" />
+<par name="filter_par2" value="64" />
+<par name="filter_before_wave_shaping" value="0" />
+<par name="spectrum_adjust_type" value="0" />
+<par name="spectrum_adjust_par" value="64" />
+<par name="rand" value="64" />
+<par name="amp_rand_type" value="0" />
+<par name="amp_rand_power" value="64" />
+<par name="harmonic_shift" value="0" />
+<par_bool name="harmonic_shift_first" value="no" />
+<par name="adaptive_harmonics" value="0" />
+<par name="adaptive_harmonics_base_frequency" value="128" />
+<par name="adaptive_harmonics_power" value="100" />
+<HARMONICS>
+<HARMONIC id="2">
+<par name="mag" value="127" />
+<par name="phase" value="64" />
+</HARMONIC>
+<HARMONIC id="3">
+<par name="mag" value="126" />
+<par name="phase" value="64" />
+</HARMONIC>
+<HARMONIC id="8">
+<par name="mag" value="94" />
+<par name="phase" value="64" />
+</HARMONIC>
+</HARMONICS>
+</OSCIL>
+<AMPLITUDE_PARAMETERS>
+<par name="panning" value="64" />
+<par name="volume" value="127" />
+<par_bool name="volume_minus" value="no" />
+<par name="velocity_sensing" value="70" />
+<par_bool name="amp_envelope_enabled" value="yes" />
+<AMPLITUDE_ENVELOPE>
+<par_bool name="free_mode" value="no" />
+<par name="env_points" value="4" />
+<par name="env_sustain" value="2" />
+<par name="env_stretch" value="64" />
+<par_bool name="forced_release" value="yes" />
+<par_bool name="linear_envelope" value="no" />
+<par name="A_dt" value="4" />
+<par name="D_dt" value="20" />
+<par name="R_dt" value="100" />
+<par name="A_val" value="64" />
+<par name="D_val" value="64" />
+<par name="S_val" value="1" />
+<par name="R_val" value="64" />
+</AMPLITUDE_ENVELOPE>
+<par_bool name="amp_lfo_enabled" value="no" />
+</AMPLITUDE_PARAMETERS>
+<FREQUENCY_PARAMETERS>
+<par_bool name="fixed_freq" value="no" />
+<par name="fixed_freq_et" value="0" />
+<par name="detune" value="8192" />
+<par name="coarse_detune" value="0" />
+<par name="detune_type" value="0" />
+<par_bool name="freq_envelope_enabled" value="no" />
+<par_bool name="freq_lfo_enabled" value="no" />
+</FREQUENCY_PARAMETERS>
+</VOICE>
+<VOICE id="4">
+<par_bool name="enabled" value="no" />
+</VOICE>
+<VOICE id="5">
+<par_bool name="enabled" value="no" />
+</VOICE>
+<VOICE id="6">
+<par_bool name="enabled" value="no" />
+</VOICE>
+<VOICE id="7">
+<par_bool name="enabled" value="no" />
+</VOICE>
+</ADD_SYNTH_PARAMETERS>
+<par_bool name="sub_enabled" value="no" />
+<par_bool name="pad_enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="1">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="2">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="3">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="4">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="5">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="6">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="7">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="8">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="9">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="10">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="11">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="12">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="13">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="14">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="15">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+</INSTRUMENT_KIT>
+<INSTRUMENT_EFFECTS>
+<INSTRUMENT_EFFECT id="0">
+<EFFECT>
+<par name="type" value="6" />
+<par name="preset" value="4" />
+<EFFECT_PARAMETERS>
+<par_no id="0">
+<par name="par" value="112" />
+</par_no>
+<par_no id="1">
+<par name="par" value="65" />
+</par_no>
+<par_no id="2">
+<par name="par" value="35" />
+</par_no>
+<par_no id="3">
+<par name="par" value="97" />
+</par_no>
+<par_no id="4">
+<par name="par" value="29" />
+</par_no>
+<par_no id="7">
+<par name="par" value="83" />
+</par_no>
+</EFFECT_PARAMETERS>
+</EFFECT>
+<par name="route" value="0" />
+<par_bool name="bypass" value="no" />
+</INSTRUMENT_EFFECT>
+<INSTRUMENT_EFFECT id="1">
+<EFFECT>
+<par name="type" value="7" />
+<par name="preset" value="0" />
+<EFFECT_PARAMETERS>
+<par_no id="0">
+<par name="par" value="56" />
+</par_no>
+<par_no id="10">
+<par name="par" value="7" />
+</par_no>
+<par_no id="11">
+<par name="par" value="69" />
+</par_no>
+<par_no id="12">
+<par name="par" value="89" />
+</par_no>
+<par_no id="13">
+<par name="par" value="36" />
+</par_no>
+<par_no id="15">
+<par name="par" value="6" />
+</par_no>
+<par_no id="16">
+<par name="par" value="76" />
+</par_no>
+<par_no id="17">
+<par name="par" value="64" />
+</par_no>
+<par_no id="18">
+<par name="par" value="32" />
+</par_no>
+<par_no id="20">
+<par name="par" value="9" />
+</par_no>
+<par_no id="21">
+<par name="par" value="86" />
+</par_no>
+<par_no id="22">
+<par name="par" value="75" />
+</par_no>
+<par_no id="23">
+<par name="par" value="64" />
+</par_no>
+<par_no id="26">
+<par name="par" value="36" />
+</par_no>
+<par_no id="27">
+<par name="par" value="90" />
+</par_no>
+<par_no id="28">
+<par name="par" value="57" />
+</par_no>
+<par_no id="31">
+<par name="par" value="64" />
+</par_no>
+<par_no id="32">
+<par name="par" value="64" />
+</par_no>
+<par_no id="33">
+<par name="par" value="64" />
+</par_no>
+<par_no id="36">
+<par name="par" value="64" />
+</par_no>
+<par_no id="37">
+<par name="par" value="64" />
+</par_no>
+<par_no id="38">
+<par name="par" value="64" />
+</par_no>
+<par_no id="41">
+<par name="par" value="64" />
+</par_no>
+<par_no id="42">
+<par name="par" value="64" />
+</par_no>
+<par_no id="43">
+<par name="par" value="64" />
+</par_no>
+<par_no id="46">
+<par name="par" value="64" />
+</par_no>
+<par_no id="47">
+<par name="par" value="64" />
+</par_no>
+<par_no id="48">
+<par name="par" value="64" />
+</par_no>
+</EFFECT_PARAMETERS>
+</EFFECT>
+<par name="route" value="0" />
+<par_bool name="bypass" value="no" />
+</INSTRUMENT_EFFECT>
+<INSTRUMENT_EFFECT id="2">
+<EFFECT>
+<par name="type" value="0" />
+</EFFECT>
+<par name="route" value="0" />
+<par_bool name="bypass" value="no" />
+</INSTRUMENT_EFFECT>
+</INSTRUMENT_EFFECTS>
+</INSTRUMENT>
+<CONTROLLER>
+<par name="pitchwheel_bendrange" value="200" />
+<par_bool name="expression_receive" value="yes" />
+<par name="panning_depth" value="64" />
+<par name="filter_cutoff_depth" value="64" />
+<par name="filter_q_depth" value="64" />
+<par name="bandwidth_depth" value="64" />
+<par name="mod_wheel_depth" value="80" />
+<par_bool name="mod_wheel_exponential" value="no" />
+<par_bool name="fm_amp_receive" value="yes" />
+<par_bool name="volume_receive" value="no" />
+<par_bool name="sustain_receive" value="yes" />
+<par_bool name="portamento_receive" value="yes" />
+<par name="portamento_time" value="64" />
+<par name="portamento_pitchthresh" value="3" />
+<par name="portamento_pitchthreshtype" value="1" />
+<par name="portamento_portamento" value="0" />
+<par name="portamento_updowntimestretch" value="64" />
+<par name="portamento_proportional" value="0" />
+<par name="portamento_proprate" value="80" />
+<par name="portamento_propdepth" value="90" />
+<par name="resonance_center_depth" value="64" />
+<par name="resonance_bandwidth_depth" value="64" />
+</CONTROLLER>
+</PART>
+<PART id="1">
+<par_bool name="enabled" value="yes" />
+<par name="volume" value="96" />
+<par name="panning" value="64" />
+<par name="min_key" value="0" />
+<par name="max_key" value="127" />
+<par name="key_shift" value="64" />
+<par name="rcv_chn" value="1" />
+<par name="velocity_sensing" value="64" />
+<par name="velocity_offset" value="64" />
+<par_bool name="note_on" value="yes" />
+<par_bool name="poly_mode" value="yes" />
+<par name="legato_mode" value="0" />
+<par name="key_limit" value="15" />
+<INSTRUMENT>
+<INFO>
+<string name="name"></string>
+<string name="author"></string>
+<string name="comments"></string>
+<par name="type" value="0" />
+</INFO>
+<INSTRUMENT_KIT>
+<par name="kit_mode" value="0" />
+<par_bool name="drum_mode" value="no" />
+<INSTRUMENT_KIT_ITEM id="0">
+<par_bool name="enabled" value="yes" />
+<string name="name"></string>
+<par_bool name="muted" value="no" />
+<par name="min_key" value="0" />
+<par name="max_key" value="127" />
+<par name="send_to_instrument_effect" value="0" />
+<par_bool name="add_enabled" value="no" />
+<par_bool name="sub_enabled" value="yes" />
+<SUB_SYNTH_PARAMETERS>
+<par name="num_stages" value="4" />
+<par name="harmonic_mag_type" value="0" />
+<par name="start" value="2" />
+<HARMONICS>
+<HARMONIC id="0">
+<par name="mag" value="127" />
+<par name="relbw" value="31" />
+</HARMONIC>
+<HARMONIC id="1">
+<par name="mag" value="99" />
+<par name="relbw" value="57" />
+</HARMONIC>
+<HARMONIC id="2">
+<par name="mag" value="90" />
+<par name="relbw" value="82" />
+</HARMONIC>
+<HARMONIC id="3">
+<par name="mag" value="75" />
+<par name="relbw" value="74" />
+</HARMONIC>
+<HARMONIC id="4">
+<par name="mag" value="75" />
+<par name="relbw" value="64" />
+</HARMONIC>
+<HARMONIC id="5">
+<par name="mag" value="92" />
+<par name="relbw" value="47" />
+</HARMONIC>
+<HARMONIC id="6">
+<par name="mag" value="112" />
+<par name="relbw" value="107" />
+</HARMONIC>
+<HARMONIC id="8">
+<par name="mag" value="122" />
+<par name="relbw" value="64" />
+</HARMONIC>
+</HARMONICS>
+<AMPLITUDE_PARAMETERS>
+<par_bool name="stereo" value="yes" />
+<par name="volume" value="96" />
+<par name="panning" value="64" />
+<par name="velocity_sensing" value="90" />
+<AMPLITUDE_ENVELOPE>
+<par_bool name="free_mode" value="no" />
+<par name="env_points" value="4" />
+<par name="env_sustain" value="2" />
+<par name="env_stretch" value="64" />
+<par_bool name="forced_release" value="yes" />
+<par_bool name="linear_envelope" value="no" />
+<par name="A_dt" value="0" />
+<par name="D_dt" value="40" />
+<par name="R_dt" value="25" />
+<par name="A_val" value="64" />
+<par name="D_val" value="64" />
+<par name="S_val" value="127" />
+<par name="R_val" value="64" />
+</AMPLITUDE_ENVELOPE>
+</AMPLITUDE_PARAMETERS>
+<FREQUENCY_PARAMETERS>
+<par_bool name="fixed_freq" value="no" />
+<par name="fixed_freq_et" value="103" />
+<par name="detune" value="8192" />
+<par name="coarse_detune" value="0" />
+<par name="detune_type" value="1" />
+<par name="bandwidth" value="40" />
+<par name="bandwidth_scale" value="38" />
+<par_bool name="freq_envelope_enabled" value="yes" />
+<FREQUENCY_ENVELOPE>
+<par_bool name="free_mode" value="no" />
+<par name="env_points" value="3" />
+<par name="env_sustain" value="1" />
+<par name="env_stretch" value="64" />
+<par_bool name="forced_release" value="no" />
+<par_bool name="linear_envelope" value="no" />
+<par name="A_dt" value="18" />
+<par name="D_dt" value="10" />
+<par name="R_dt" value="60" />
+<par name="A_val" value="86" />
+<par name="D_val" value="64" />
+<par name="S_val" value="64" />
+<par name="R_val" value="64" />
+</FREQUENCY_ENVELOPE>
+<par_bool name="band_width_envelope_enabled" value="yes" />
+<BANDWIDTH_ENVELOPE>
+<par_bool name="free_mode" value="no" />
+<par name="env_points" value="3" />
+<par name="env_sustain" value="1" />
+<par name="env_stretch" value="64" />
+<par_bool name="forced_release" value="no" />
+<par_bool name="linear_envelope" value="no" />
+<par name="A_dt" value="70" />
+<par name="D_dt" value="10" />
+<par name="R_dt" value="60" />
+<par name="A_val" value="100" />
+<par name="D_val" value="64" />
+<par name="S_val" value="64" />
+<par name="R_val" value="64" />
+</BANDWIDTH_ENVELOPE>
+</FREQUENCY_PARAMETERS>
+<FILTER_PARAMETERS>
+<par_bool name="enabled" value="yes" />
+<FILTER>
+<par name="category" value="0" />
+<par name="type" value="4" />
+<par name="freq" value="80" />
+<par name="q" value="40" />
+<par name="stages" value="0" />
+<par name="freq_track" value="64" />
+<par name="gain" value="64" />
+</FILTER>
+<par name="filter_velocity_sensing" value="64" />
+<par name="filter_velocity_sensing_amplitude" value="64" />
+<FILTER_ENVELOPE>
+<par_bool name="free_mode" value="no" />
+<par name="env_points" value="4" />
+<par name="env_sustain" value="2" />
+<par name="env_stretch" value="0" />
+<par_bool name="forced_release" value="yes" />
+<par_bool name="linear_envelope" value="no" />
+<par name="A_dt" value="40" />
+<par name="D_dt" value="70" />
+<par name="R_dt" value="60" />
+<par name="A_val" value="98" />
+<par name="D_val" value="64" />
+<par name="S_val" value="64" />
+<par name="R_val" value="64" />
+</FILTER_ENVELOPE>
+</FILTER_PARAMETERS>
+</SUB_SYNTH_PARAMETERS>
+<par_bool name="pad_enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="1">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="2">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="3">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="4">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="5">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="6">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="7">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="8">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="9">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="10">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="11">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="12">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="13">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="14">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="15">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+</INSTRUMENT_KIT>
+<INSTRUMENT_EFFECTS>
+<INSTRUMENT_EFFECT id="0">
+<EFFECT>
+<par name="type" value="0" />
+</EFFECT>
+<par name="route" value="0" />
+<par_bool name="bypass" value="no" />
+</INSTRUMENT_EFFECT>
+<INSTRUMENT_EFFECT id="1">
+<EFFECT>
+<par name="type" value="0" />
+</EFFECT>
+<par name="route" value="0" />
+<par_bool name="bypass" value="no" />
+</INSTRUMENT_EFFECT>
+<INSTRUMENT_EFFECT id="2">
+<EFFECT>
+<par name="type" value="0" />
+</EFFECT>
+<par name="route" value="0" />
+<par_bool name="bypass" value="no" />
+</INSTRUMENT_EFFECT>
+</INSTRUMENT_EFFECTS>
+</INSTRUMENT>
+<CONTROLLER>
+<par name="pitchwheel_bendrange" value="200" />
+<par_bool name="expression_receive" value="yes" />
+<par name="panning_depth" value="64" />
+<par name="filter_cutoff_depth" value="64" />
+<par name="filter_q_depth" value="64" />
+<par name="bandwidth_depth" value="64" />
+<par name="mod_wheel_depth" value="80" />
+<par_bool name="mod_wheel_exponential" value="no" />
+<par_bool name="fm_amp_receive" value="yes" />
+<par_bool name="volume_receive" value="yes" />
+<par_bool name="sustain_receive" value="yes" />
+<par_bool name="portamento_receive" value="yes" />
+<par name="portamento_time" value="64" />
+<par name="portamento_pitchthresh" value="3" />
+<par name="portamento_pitchthreshtype" value="1" />
+<par name="portamento_portamento" value="0" />
+<par name="portamento_updowntimestretch" value="64" />
+<par name="portamento_proportional" value="0" />
+<par name="portamento_proprate" value="80" />
+<par name="portamento_propdepth" value="90" />
+<par name="resonance_center_depth" value="64" />
+<par name="resonance_bandwidth_depth" value="64" />
+</CONTROLLER>
+</PART>
+<PART id="2">
+<par_bool name="enabled" value="yes" />
+<par name="volume" value="96" />
+<par name="panning" value="64" />
+<par name="min_key" value="0" />
+<par name="max_key" value="127" />
+<par name="key_shift" value="64" />
+<par name="rcv_chn" value="2" />
+<par name="velocity_sensing" value="64" />
+<par name="velocity_offset" value="64" />
+<par_bool name="note_on" value="yes" />
+<par_bool name="poly_mode" value="yes" />
+<par name="legato_mode" value="0" />
+<par name="key_limit" value="15" />
+<INSTRUMENT>
+<INFO>
+<string name="name"></string>
+<string name="author"></string>
+<string name="comments"></string>
+<par name="type" value="0" />
+</INFO>
+<INSTRUMENT_KIT>
+<par name="kit_mode" value="0" />
+<par_bool name="drum_mode" value="no" />
+<INSTRUMENT_KIT_ITEM id="0">
+<par_bool name="enabled" value="yes" />
+<string name="name"></string>
+<par_bool name="muted" value="no" />
+<par name="min_key" value="0" />
+<par name="max_key" value="127" />
+<par name="send_to_instrument_effect" value="0" />
+<par_bool name="add_enabled" value="no" />
+<par_bool name="sub_enabled" value="no" />
+<par_bool name="pad_enabled" value="yes" />
+<PAD_SYNTH_PARAMETERS>
+<par_bool name="stereo" value="yes" />
+<par name="mode" value="0" />
+<par name="bandwidth" value="500" />
+<par name="bandwidth_scale" value="0" />
+<HARMONIC_PROFILE>
+<par name="base_type" value="0" />
+<par name="base_par1" value="80" />
+<par name="frequency_multiplier" value="0" />
+<par name="modulator_par1" value="0" />
+<par name="modulator_frequency" value="30" />
+<par name="width" value="127" />
+<par name="amplitude_multiplier_type" value="0" />
+<par name="amplitude_multiplier_mode" value="0" />
+<par name="amplitude_multiplier_par1" value="80" />
+<par name="amplitude_multiplier_par2" value="64" />
+<par_bool name="autoscale" value="yes" />
+<par name="one_half" value="0" />
+</HARMONIC_PROFILE>
+<OSCIL>
+<par name="harmonic_mag_type" value="0" />
+<par name="base_function" value="127" />
+<par name="base_function_par" value="42" />
+<par name="base_function_modulation" value="0" />
+<par name="base_function_modulation_par1" value="64" />
+<par name="base_function_modulation_par2" value="64" />
+<par name="base_function_modulation_par3" value="32" />
+<par name="modulation" value="0" />
+<par name="modulation_par1" value="64" />
+<par name="modulation_par2" value="64" />
+<par name="modulation_par3" value="32" />
+<par name="wave_shaping" value="64" />
+<par name="wave_shaping_function" value="0" />
+<par name="filter_type" value="0" />
+<par name="filter_par1" value="64" />
+<par name="filter_par2" value="64" />
+<par name="filter_before_wave_shaping" value="0" />
+<par name="spectrum_adjust_type" value="0" />
+<par name="spectrum_adjust_par" value="64" />
+<par name="rand" value="127" />
+<par name="amp_rand_type" value="0" />
+<par name="amp_rand_power" value="64" />
+<par name="harmonic_shift" value="0" />
+<par_bool name="harmonic_shift_first" value="no" />
+<par name="adaptive_harmonics" value="0" />
+<par name="adaptive_harmonics_base_frequency" value="128" />
+<par name="adaptive_harmonics_power" value="100" />
+<HARMONICS>
+<HARMONIC id="1">
+<par name="mag" value="127" />
+<par name="phase" value="64" />
+</HARMONIC>
+<HARMONIC id="2">
+<par name="mag" value="42" />
+<par name="phase" value="48" />
+</HARMONIC>
+<HARMONIC id="5">
+<par name="mag" value="79" />
+<par name="phase" value="64" />
+</HARMONIC>
+</HARMONICS>
+<BASE_FUNCTION>
+<BF_HARMONIC id="1">
+<par_real name="cos" value="-0.586935" />
+<par_real name="sin" value="1" />
+</BF_HARMONIC>
+<BF_HARMONIC id="2">
+<par_real name="cos" value="0.284664" />
+<par_real name="sin" value="0.509771" />
+</BF_HARMONIC>
+<BF_HARMONIC id="3">
+<par_real name="cos" value="0.00548861" />
+<par_real name="sin" value="0.00011789" />
+</BF_HARMONIC>
+<BF_HARMONIC id="4">
+<par_real name="cos" value="-0.150973" />
+<par_real name="sin" value="0.245014" />
+</BF_HARMONIC>
+<BF_HARMONIC id="5">
+<par_real name="cos" value="0.110217" />
+<par_real name="sin" value="0.207732" />
+</BF_HARMONIC>
+<BF_HARMONIC id="6">
+<par_real name="cos" value="-0.301957" />
+<par_real name="sin" value="0.524045" />
+</BF_HARMONIC>
+<BF_HARMONIC id="7">
+<par_real name="cos" value="-0.0885982" />
+<par_real name="sin" value="0.137104" />
+</BF_HARMONIC>
+<BF_HARMONIC id="8">
+<par_real name="cos" value="0.0665272" />
+<par_real name="sin" value="0.132167" />
+</BF_HARMONIC>
+<BF_HARMONIC id="9">
+<par_real name="cos" value="0.005478" />
+<par_real name="sin" value="0.000353421" />
+</BF_HARMONIC>
+<BF_HARMONIC id="10">
+<par_real name="cos" value="-0.0635812" />
+<par_real name="sin" value="0.0939035" />
+</BF_HARMONIC>
+<BF_HARMONIC id="11">
+<par_real name="cos" value="0.0466126" />
+<par_real name="sin" value="0.0977767" />
+</BF_HARMONIC>
+<BF_HARMONIC id="12">
+<par_real name="cos" value="0.154579" />
+<par_real name="sin" value="0.267494" />
+</BF_HARMONIC>
+<BF_HARMONIC id="13">
+<par_real name="cos" value="-0.0500581" />
+<par_real name="sin" value="0.0706158" />
+</BF_HARMONIC>
+<BF_HARMONIC id="14">
+<par_real name="cos" value="0.0351901" />
+<par_real name="sin" value="0.0780907" />
+</BF_HARMONIC>
+<BF_HARMONIC id="15">
+<par_real name="cos" value="0.00545682" />
+<par_real name="sin" value="0.000588208" />
+</BF_HARMONIC>
+<BF_HARMONIC id="16">
+<par_real name="cos" value="-0.0415629" />
+<par_real name="sin" value="0.0560411" />
+</BF_HARMONIC>
+<BF_HARMONIC id="17">
+<par_real name="cos" value="0.0277648" />
+<par_real name="sin" value="0.0653231" />
+</BF_HARMONIC>
+<BF_HARMONIC id="18">
+<par_real name="cos" value="0.00831725" />
+<par_real name="sin" value="0.000766919" />
+</BF_HARMONIC>
+<BF_HARMONIC id="19">
+<par_real name="cos" value="-0.0357137" />
+<par_real name="sin" value="0.0460534" />
+</BF_HARMONIC>
+<BF_HARMONIC id="20">
+<par_real name="cos" value="0.0225387" />
+<par_real name="sin" value="0.0563597" />
+</BF_HARMONIC>
+<BF_HARMONIC id="21">
+<par_real name="cos" value="0.0054251" />
+<par_real name="sin" value="0.000821755" />
+</BF_HARMONIC>
+<BF_HARMONIC id="22">
+<par_real name="cos" value="-0.0314275" />
+<par_real name="sin" value="0.0387773" />
+</BF_HARMONIC>
+<BF_HARMONIC id="23">
+<par_real name="cos" value="0.018652" />
+<par_real name="sin" value="0.0497112" />
+</BF_HARMONIC>
+<BF_HARMONIC id="24">
+<par_real name="cos" value="-0.0736757" />
+<par_real name="sin" value="0.129278" />
+</BF_HARMONIC>
+<BF_HARMONIC id="25">
+<par_real name="cos" value="-0.0281414" />
+<par_real name="sin" value="0.0332373" />
+</BF_HARMONIC>
+<BF_HARMONIC id="26">
+<par_real name="cos" value="0.0156415" />
+<par_real name="sin" value="0.0445755" />
+</BF_HARMONIC>
+<BF_HARMONIC id="27">
+<par_real name="cos" value="0.00538291" />
+<par_real name="sin" value="0.00105357" />
+</BF_HARMONIC>
+<BF_HARMONIC id="28">
+<par_real name="cos" value="-0.0255337" />
+<par_real name="sin" value="0.0288764" />
+</BF_HARMONIC>
+<BF_HARMONIC id="29">
+<par_real name="cos" value="0.013236" />
+<par_real name="sin" value="0.0404826" />
+</BF_HARMONIC>
+<BF_HARMONIC id="30">
+<par_real name="cos" value="0.0630907" />
+<par_real name="sin" value="0.109981" />
+</BF_HARMONIC>
+<BF_HARMONIC id="31">
+<par_real name="cos" value="-0.0234072" />
+<par_real name="sin" value="0.025353" />
+</BF_HARMONIC>
+<BF_HARMONIC id="32">
+<par_real name="cos" value="0.0112659" />
+<par_real name="sin" value="0.0371387" />
+</BF_HARMONIC>
+<BF_HARMONIC id="33">
+<par_real name="cos" value="0.00533036" />
+<par_real name="sin" value="0.00128317" />
+</BF_HARMONIC>
+<BF_HARMONIC id="34">
+<par_real name="cos" value="-0.0216345" />
+<par_real name="sin" value="0.022446" />
+</BF_HARMONIC>
+<BF_HARMONIC id="35">
+<par_real name="cos" value="0.00961967" />
+<par_real name="sin" value="0.0343507" />
+</BF_HARMONIC>
+<BF_HARMONIC id="36">
+<par_real name="cos" value="0.00817314" />
+<par_real name="sin" value="0.00152045" />
+</BF_HARMONIC>
+<BF_HARMONIC id="37">
+<par_real name="cos" value="-0.0201293" />
+<par_real name="sin" value="0.0200061" />
+</BF_HARMONIC>
+<BF_HARMONIC id="38">
+<par_real name="cos" value="0.00822111" />
+<par_real name="sin" value="0.0319865" />
+</BF_HARMONIC>
+<BF_HARMONIC id="39">
+<par_real name="cos" value="0.00526757" />
+<par_real name="sin" value="0.00151006" />
+</BF_HARMONIC>
+<BF_HARMONIC id="40">
+<par_real name="cos" value="-0.0188313" />
+<par_real name="sin" value="0.0179289" />
+</BF_HARMONIC>
+<BF_HARMONIC id="41">
+<par_real name="cos" value="0.00701632" />
+<par_real name="sin" value="0.0299528" />
+</BF_HARMONIC>
+<BF_HARMONIC id="42">
+<par_real name="cos" value="-0.0411762" />
+<par_real name="sin" value="0.0734385" />
+</BF_HARMONIC>
+<BF_HARMONIC id="43">
+<par_real name="cos" value="-0.0176972" />
+<par_real name="sin" value="0.016139" />
+</BF_HARMONIC>
+<BF_HARMONIC id="44">
+<par_real name="cos" value="0.00596609" />
+<par_real name="sin" value="0.0281816" />
+</BF_HARMONIC>
+<BF_HARMONIC id="45">
+<par_real name="cos" value="0.00519467" />
+<par_real name="sin" value="0.00173378" />
+</BF_HARMONIC>
+<BF_HARMONIC id="46">
+<par_real name="cos" value="-0.0166948" />
+<par_real name="sin" value="0.0145807" />
+</BF_HARMONIC>
+<BF_HARMONIC id="47">
+<par_real name="cos" value="0.00504126" />
+<par_real name="sin" value="0.0266224" />
+</BF_HARMONIC>
+<BF_HARMONIC id="48">
+<par_real name="cos" value="0.040002" />
+<par_real name="sin" value="0.0710745" />
+</BF_HARMONIC>
+<BF_HARMONIC id="49">
+<par_real name="cos" value="-0.0157999" />
+<par_real name="sin" value="0.0132119" />
+</BF_HARMONIC>
+<BF_HARMONIC id="50">
+<par_real name="cos" value="0.00421965" />
+<par_real name="sin" value="0.0252368" />
+</BF_HARMONIC>
+<BF_HARMONIC id="51">
+<par_real name="cos" value="0.00511182" />
+<par_real name="sin" value="0.00195385" />
+</BF_HARMONIC>
+<BF_HARMONIC id="52">
+<par_real name="cos" value="-0.0149939" />
+<par_real name="sin" value="0.0120003" />
+</BF_HARMONIC>
+<BF_HARMONIC id="53">
+<par_real name="cos" value="0.00348411" />
+<par_real name="sin" value="0.0239949" />
+</BF_HARMONIC>
+<BF_HARMONIC id="54">
+<par_real name="cos" value="0.00793616" />
+<par_real name="sin" value="0.0022475" />
+</BF_HARMONIC>
+<BF_HARMONIC id="55">
+<par_real name="cos" value="-0.0142621" />
+<par_real name="sin" value="0.0109206" />
+</BF_HARMONIC>
+<BF_HARMONIC id="56">
+<par_real name="cos" value="0.0028212" />
+<par_real name="sin" value="0.0228736" />
+</BF_HARMONIC>
+<BF_HARMONIC id="57">
+<par_real name="cos" value="0.00501922" />
+<par_real name="sin" value="0.00216982" />
+</BF_HARMONIC>
+<BF_HARMONIC id="58">
+<par_real name="cos" value="-0.0135932" />
+<par_real name="sin" value="0.00995273" />
+</BF_HARMONIC>
+<BF_HARMONIC id="59">
+<par_real name="cos" value="0.00222018" />
+<par_real name="sin" value="0.0218543" />
+</BF_HARMONIC>
+<BF_HARMONIC id="60">
+<par_real name="cos" value="-0.0283351" />
+<par_real name="sin" value="0.0514637" />
+</BF_HARMONIC>
+<BF_HARMONIC id="61">
+<par_real name="cos" value="-0.0129779" />
+<par_real name="sin" value="0.00908063" />
+</BF_HARMONIC>
+<BF_HARMONIC id="62">
+<par_real name="cos" value="0.00167243" />
+<par_real name="sin" value="0.0209219" />
+</BF_HARMONIC>
+<BF_HARMONIC id="63">
+<par_real name="cos" value="0.00491707" />
+<par_real name="sin" value="0.00238123" />
+</BF_HARMONIC>
+<BF_HARMONIC id="64">
+<par_real name="cos" value="-0.0124086" />
+<par_real name="sin" value="0.00829118" />
+</BF_HARMONIC>
+<BF_HARMONIC id="65">
+<par_real name="cos" value="0.0011709" />
+<par_real name="sin" value="0.0200643" />
+</BF_HARMONIC>
+<BF_HARMONIC id="66">
+<par_real name="cos" value="0.0292786" />
+<par_real name="sin" value="0.0537015" />
+</BF_HARMONIC>
+<BF_HARMONIC id="67">
+<par_real name="cos" value="-0.0118793" />
+<par_real name="sin" value="0.00757364" />
+</BF_HARMONIC>
+<BF_HARMONIC id="68">
+<par_real name="cos" value="0.000709812" />
+<par_real name="sin" value="0.0192715" />
+</BF_HARMONIC>
+<BF_HARMONIC id="69">
+<par_real name="cos" value="0.00480561" />
+<par_real name="sin" value="0.00258764" />
+</BF_HARMONIC>
+<BF_HARMONIC id="70">
+<par_real name="cos" value="-0.0113848" />
+<par_real name="sin" value="0.00691909" />
+</BF_HARMONIC>
+<BF_HARMONIC id="71">
+<par_real name="cos" value="0.000284347" />
+<par_real name="sin" value="0.0185351" />
+</BF_HARMONIC>
+<BF_HARMONIC id="72">
+<par_real name="cos" value="0.00761104" />
+<par_real name="sin" value="0.00293552" />
+</BF_HARMONIC>
+<BF_HARMONIC id="73">
+<par_real name="cos" value="-0.0109209" />
+<par_real name="sin" value="0.00632009" />
+</BF_HARMONIC>
+<BF_HARMONIC id="74">
+<par_real name="cos" value="-0.000109516" />
+<par_real name="sin" value="0.0178481" />
+</BF_HARMONIC>
+<BF_HARMONIC id="75">
+<par_real name="cos" value="0.00468508" />
+<par_real name="sin" value="0.00278863" />
+</BF_HARMONIC>
+<BF_HARMONIC id="76">
+<par_real name="cos" value="-0.0104841" />
+<par_real name="sin" value="0.00577037" />
+</BF_HARMONIC>
+<BF_HARMONIC id="77">
+<par_real name="cos" value="-0.000475173" />
+<par_real name="sin" value="0.0172048" />
+</BF_HARMONIC>
+<BF_HARMONIC id="78">
+<par_real name="cos" value="-0.0215994" />
+<par_real name="sin" value="0.0398762" />
+</BF_HARMONIC>
+<BF_HARMONIC id="79">
+<par_real name="cos" value="-0.0100713" />
+<par_real name="sin" value="0.00526462" />
+</BF_HARMONIC>
+<BF_HARMONIC id="80">
+<par_real name="cos" value="-0.000815505" />
+<par_real name="sin" value="0.0166" />
+</BF_HARMONIC>
+<BF_HARMONIC id="81">
+<par_real name="cos" value="0.00455576" />
+<par_real name="sin" value="0.00298378" />
+</BF_HARMONIC>
+<BF_HARMONIC id="82">
+<par_real name="cos" value="-0.00967999" />
+<par_real name="sin" value="0.00479828" />
+</BF_HARMONIC>
+<BF_HARMONIC id="83">
+<par_real name="cos" value="-0.00113298" />
+<par_real name="sin" value="0.0160296" />
+</BF_HARMONIC>
+<BF_HARMONIC id="84">
+<par_real name="cos" value="0.0229208" />
+<par_real name="sin" value="0.0439837" />
+</BF_HARMONIC>
+<BF_HARMONIC id="85">
+<par_real name="cos" value="-0.009308" />
+<par_real name="sin" value="0.00436746" />
+</BF_HARMONIC>
+<BF_HARMONIC id="86">
+<par_real name="cos" value="-0.00142971" />
+<par_real name="sin" value="0.0154898" />
+</BF_HARMONIC>
+<BF_HARMONIC id="87">
+<par_real name="cos" value="0.00441794" />
+<par_real name="sin" value="0.00317269" />
+</BF_HARMONIC>
+<BF_HARMONIC id="88">
+<par_real name="cos" value="-0.00895342" />
+<par_real name="sin" value="0.00396878" />
+</BF_HARMONIC>
+<BF_HARMONIC id="89">
+<par_real name="cos" value="-0.00170752" />
+<par_real name="sin" value="0.0149777" />
+</BF_HARMONIC>
+<BF_HARMONIC id="90">
+<par_real name="cos" value="0.00720426" />
+<par_real name="sin" value="0.0035728" />
+</BF_HARMONIC>
+<BF_HARMONIC id="91">
+<par_real name="cos" value="-0.00861464" />
+<par_real name="sin" value="0.0035993" />
+</BF_HARMONIC>
+<BF_HARMONIC id="92">
+<par_real name="cos" value="-0.00196802" />
+<par_real name="sin" value="0.0144903" />
+</BF_HARMONIC>
+<BF_HARMONIC id="93">
+<par_real name="cos" value="0.00427192" />
+<par_real name="sin" value="0.00335498" />
+</BF_HARMONIC>
+<BF_HARMONIC id="94">
+<par_real name="cos" value="-0.00829023" />
+<par_real name="sin" value="0.00325647" />
+</BF_HARMONIC>
+<BF_HARMONIC id="95">
+<par_real name="cos" value="-0.00221258" />
+<par_real name="sin" value="0.0140254" />
+</BF_HARMONIC>
+<BF_HARMONIC id="96">
+<par_real name="cos" value="-0.0175751" />
+<par_real name="sin" value="0.0327984" />
+</BF_HARMONIC>
+<BF_HARMONIC id="97">
+<par_real name="cos" value="-0.00797899" />
+<par_real name="sin" value="0.00293804" />
+</BF_HARMONIC>
+<BF_HARMONIC id="98">
+<par_real name="cos" value="-0.00244242" />
+<par_real name="sin" value="0.0135808" />
+</BF_HARMONIC>
+<BF_HARMONIC id="99">
+<par_real name="cos" value="0.00411804" />
+<par_real name="sin" value="0.00353027" />
+</BF_HARMONIC>
+<BF_HARMONIC id="100">
+<par_real name="cos" value="-0.00767981" />
+<par_real name="sin" value="0.00264203" />
+</BF_HARMONIC>
+<BF_HARMONIC id="101">
+<par_real name="cos" value="-0.00265862" />
+<par_real name="sin" value="0.0131547" />
+</BF_HARMONIC>
+<BF_HARMONIC id="102">
+<par_real name="cos" value="0.0185817" />
+<par_real name="sin" value="0.037832" />
+</BF_HARMONIC>
+<BF_HARMONIC id="103">
+<par_real name="cos" value="-0.00739178" />
+<par_real name="sin" value="0.00236668" />
+</BF_HARMONIC>
+<BF_HARMONIC id="104">
+<par_real name="cos" value="-0.00286212" />
+<par_real name="sin" value="0.0127456" />
+</BF_HARMONIC>
+<BF_HARMONIC id="105">
+<par_real name="cos" value="0.00395663" />
+<par_real name="sin" value="0.0036982" />
+</BF_HARMONIC>
+<BF_HARMONIC id="106">
+<par_real name="cos" value="-0.00711405" />
+<par_real name="sin" value="0.00211044" />
+</BF_HARMONIC>
+<BF_HARMONIC id="107">
+<par_real name="cos" value="-0.00305376" />
+<par_real name="sin" value="0.012352" />
+</BF_HARMONIC>
+<BF_HARMONIC id="108">
+<par_real name="cos" value="0.00672393" />
+<par_real name="sin" value="0.00414868" />
+</BF_HARMONIC>
+<BF_HARMONIC id="109">
+<par_real name="cos" value="-0.00684589" />
+<par_real name="sin" value="0.00187192" />
+</BF_HARMONIC>
+<BF_HARMONIC id="110">
+<par_real name="cos" value="-0.0032343" />
+<par_real name="sin" value="0.0119726" />
+</BF_HARMONIC>
+<BF_HARMONIC id="111">
+<par_real name="cos" value="0.00378807" />
+<par_real name="sin" value="0.00385845" />
+</BF_HARMONIC>
+<BF_HARMONIC id="112">
+<par_real name="cos" value="-0.00658666" />
+<par_real name="sin" value="0.00164987" />
+</BF_HARMONIC>
+<BF_HARMONIC id="113">
+<par_real name="cos" value="-0.0034044" />
+<par_real name="sin" value="0.0116063" />
+</BF_HARMONIC>
+<BF_HARMONIC id="114">
+<par_real name="cos" value="-0.0150059" />
+<par_real name="sin" value="0.0280588" />
+</BF_HARMONIC>
+<BF_HARMONIC id="115">
+<par_real name="cos" value="-0.00633577" />
+<par_real name="sin" value="0.00144318" />
+</BF_HARMONIC>
+<BF_HARMONIC id="116">
+<par_real name="cos" value="-0.00356467" />
+<par_real name="sin" value="0.0112522" />
+</BF_HARMONIC>
+<BF_HARMONIC id="117">
+<par_real name="cos" value="0.00361272" />
+<par_real name="sin" value="0.00401069" />
+</BF_HARMONIC>
+<BF_HARMONIC id="118">
+<par_real name="cos" value="-0.00609273" />
+<par_real name="sin" value="0.00125083" />
+</BF_HARMONIC>
+<BF_HARMONIC id="119">
+<par_real name="cos" value="-0.00371564" />
+<par_real name="sin" value="0.0109093" />
+</BF_HARMONIC>
+<BF_HARMONIC id="120">
+<par_real name="cos" value="0.0153286" />
+<par_real name="sin" value="0.0336055" />
+</BF_HARMONIC>
+<BF_HARMONIC id="121">
+<par_real name="cos" value="-0.00585706" />
+<par_real name="sin" value="0.00107192" />
+</BF_HARMONIC>
+<BF_HARMONIC id="122">
+<par_real name="cos" value="-0.0038578" />
+<par_real name="sin" value="0.0105768" />
+</BF_HARMONIC>
+<BF_HARMONIC id="123">
+<par_real name="cos" value="0.00343099" />
+<par_real name="sin" value="0.00415462" />
+</BF_HARMONIC>
+<BF_HARMONIC id="124">
+<par_real name="cos" value="-0.00562837" />
+<par_real name="sin" value="0.000905613" />
+</BF_HARMONIC>
+<BF_HARMONIC id="125">
+<par_real name="cos" value="-0.00399161" />
+<par_real name="sin" value="0.0102541" />
+</BF_HARMONIC>
+<BF_HARMONIC id="126">
+<par_real name="cos" value="0.00617957" />
+<par_real name="sin" value="0.00465382" />
+</BF_HARMONIC>
+<BF_HARMONIC id="127">
+<par_real name="cos" value="-0.0054063" />
+<par_real name="sin" value="0.000751163" />
+</BF_HARMONIC>
+<BF_HARMONIC id="128">
+<par_real name="cos" value="-0.00411745" />
+<par_real name="sin" value="0.0099404" />
+</BF_HARMONIC>
+<BF_HARMONIC id="129">
+<par_real name="cos" value="0.00324327" />
+<par_real name="sin" value="0.00428996" />
+</BF_HARMONIC>
+<BF_HARMONIC id="130">
+<par_real name="cos" value="-0.00519051" />
+<par_real name="sin" value="0.000607879" />
+</BF_HARMONIC>
+<BF_HARMONIC id="131">
+<par_real name="cos" value="-0.0042357" />
+<par_real name="sin" value="0.00963527" />
+</BF_HARMONIC>
+<BF_HARMONIC id="132">
+<par_real name="cos" value="-0.0133147" />
+<par_real name="sin" value="0.0246662" />
+</BF_HARMONIC>
+<BF_HARMONIC id="133">
+<par_real name="cos" value="-0.00498071" />
+<par_real name="sin" value="0.000475133" />
+</BF_HARMONIC>
+<BF_HARMONIC id="134">
+<par_real name="cos" value="-0.00434669" />
+<par_real name="sin" value="0.00933812" />
+</BF_HARMONIC>
+<BF_HARMONIC id="135">
+<par_real name="cos" value="0.00304999" />
+<par_real name="sin" value="0.00441645" />
+</BF_HARMONIC>
+<BF_HARMONIC id="136">
+<par_real name="cos" value="-0.00477664" />
+<par_real name="sin" value="0.000352346" />
+</BF_HARMONIC>
+<BF_HARMONIC id="137">
+<par_real name="cos" value="-0.00445073" />
+<par_real name="sin" value="0.00904849" />
+</BF_HARMONIC>
+<BF_HARMONIC id="138">
+<par_real name="cos" value="0.0127215" />
+<par_real name="sin" value="0.0305155" />
+</BF_HARMONIC>
+<BF_HARMONIC id="139">
+<par_real name="cos" value="-0.00457807" />
+<par_real name="sin" value="0.000238988" />
+</BF_HARMONIC>
+<BF_HARMONIC id="140">
+<par_real name="cos" value="-0.00454809" />
+<par_real name="sin" value="0.00876597" />
+</BF_HARMONIC>
+<BF_HARMONIC id="141">
+<par_real name="cos" value="0.00285158" />
+<par_real name="sin" value="0.00453385" />
+</BF_HARMONIC>
+<BF_HARMONIC id="142">
+<par_real name="cos" value="-0.00438479" />
+<par_real name="sin" value="0.000134566" />
+</BF_HARMONIC>
+<BF_HARMONIC id="143">
+<par_real name="cos" value="-0.00463905" />
+<par_real name="sin" value="0.00849016" />
+</BF_HARMONIC>
+<BF_HARMONIC id="144">
+<par_real name="cos" value="0.00558194" />
+<par_real name="sin" value="0.00508036" />
+</BF_HARMONIC>
+<BF_HARMONIC id="145">
+<par_real name="cos" value="-0.00419659" />
+<par_real name="sin" value="3.8626e-05" />
+</BF_HARMONIC>
+<BF_HARMONIC id="146">
+<par_real name="cos" value="-0.00472385" />
+<par_real name="sin" value="0.00822073" />
+</BF_HARMONIC>
+<BF_HARMONIC id="147">
+<par_real name="cos" value="0.00264847" />
+<par_real name="sin" value="0.00464195" />
+</BF_HARMONIC>
+<BF_HARMONIC id="148">
+<par_real name="cos" value="-0.00401331" />
+<par_real name="sin" value="-4.92532e-05" />
+</BF_HARMONIC>
+<BF_HARMONIC id="149">
+<par_real name="cos" value="-0.0048027" />
+<par_real name="sin" value="0.00795735" />
+</BF_HARMONIC>
+<BF_HARMONIC id="150">
+<par_real name="cos" value="-0.0121954" />
+<par_real name="sin" value="0.0221025" />
+</BF_HARMONIC>
+<BF_HARMONIC id="151">
+<par_real name="cos" value="-0.0038348" />
+<par_real name="sin" value="-0.000129464" />
+</BF_HARMONIC>
+<BF_HARMONIC id="152">
+<par_real name="cos" value="-0.00487581" />
+<par_real name="sin" value="0.00769974" />
+</BF_HARMONIC>
+<BF_HARMONIC id="153">
+<par_real name="cos" value="0.00244113" />
+<par_real name="sin" value="0.00474053" />
+</BF_HARMONIC>
+<BF_HARMONIC id="154">
+<par_real name="cos" value="-0.0036609" />
+<par_real name="sin" value="-0.000202373" />
+</BF_HARMONIC>
+<BF_HARMONIC id="155">
+<par_real name="cos" value="-0.00494338" />
+<par_real name="sin" value="0.00744765" />
+</BF_HARMONIC>
+<BF_HARMONIC id="156">
+<par_real name="cos" value="0.0105292" />
+<par_real name="sin" value="0.0281353" />
+</BF_HARMONIC>
+<BF_HARMONIC id="157">
+<par_real name="cos" value="-0.0034915" />
+<par_real name="sin" value="-0.000268321" />
+</BF_HARMONIC>
+<BF_HARMONIC id="158">
+<par_real name="cos" value="-0.00500559" />
+<par_real name="sin" value="0.00720084" />
+</BF_HARMONIC>
+<BF_HARMONIC id="159">
+<par_real name="cos" value="0.00223" />
+<par_real name="sin" value="0.00482944" />
+</BF_HARMONIC>
+<BF_HARMONIC id="160">
+<par_real name="cos" value="-0.00332648" />
+<par_real name="sin" value="-0.00032763" />
+</BF_HARMONIC>
+<BF_HARMONIC id="161">
+<par_real name="cos" value="-0.00506261" />
+<par_real name="sin" value="0.0069591" />
+</BF_HARMONIC>
+<BF_HARMONIC id="162">
+<par_real name="cos" value="0.00494278" />
+<par_real name="sin" value="0.00542209" />
+</BF_HARMONIC>
+<BF_HARMONIC id="163">
+<par_real name="cos" value="-0.00316573" />
+<par_real name="sin" value="-0.000380599" />
+</BF_HARMONIC>
+<BF_HARMONIC id="164">
+<par_real name="cos" value="-0.0051146" />
+<par_real name="sin" value="0.00672223" />
+</BF_HARMONIC>
+<BF_HARMONIC id="165">
+<par_real name="cos" value="0.00201556" />
+<par_real name="sin" value="0.00490852" />
+</BF_HARMONIC>
+<BF_HARMONIC id="166">
+<par_real name="cos" value="-0.00300916" />
+<par_real name="sin" value="-0.000427514" />
+</BF_HARMONIC>
+<BF_HARMONIC id="167">
+<par_real name="cos" value="-0.00516171" />
+<par_real name="sin" value="0.00649007" />
+</BF_HARMONIC>
+<BF_HARMONIC id="168">
+<par_real name="cos" value="-0.0114675" />
+<par_real name="sin" value="0.0200701" />
+</BF_HARMONIC>
+<BF_HARMONIC id="169">
+<par_real name="cos" value="-0.00285668" />
+<par_real name="sin" value="-0.00046864" />
+</BF_HARMONIC>
+<BF_HARMONIC id="170">
+<par_real name="cos" value="-0.00520409" />
+<par_real name="sin" value="0.00626244" />
+</BF_HARMONIC>
+<BF_HARMONIC id="171">
+<par_real name="cos" value="0.00179827" />
+<par_real name="sin" value="0.00497764" />
+</BF_HARMONIC>
+<BF_HARMONIC id="172">
+<par_real name="cos" value="-0.00270822" />
+<par_real name="sin" value="-0.000504231" />
+</BF_HARMONIC>
+<BF_HARMONIC id="173">
+<par_real name="cos" value="-0.00524186" />
+<par_real name="sin" value="0.00603922" />
+</BF_HARMONIC>
+<BF_HARMONIC id="174">
+<par_real name="cos" value="0.00862188" />
+<par_real name="sin" value="0.0262136" />
+</BF_HARMONIC>
+<BF_HARMONIC id="175">
+<par_real name="cos" value="-0.0025637" />
+<par_real name="sin" value="-0.000534526" />
+</BF_HARMONIC>
+<BF_HARMONIC id="176">
+<par_real name="cos" value="-0.00527517" />
+<par_real name="sin" value="0.00582025" />
+</BF_HARMONIC>
+<BF_HARMONIC id="177">
+<par_real name="cos" value="0.00157863" />
+<par_real name="sin" value="0.0050367" />
+</BF_HARMONIC>
+<BF_HARMONIC id="178">
+<par_real name="cos" value="-0.00242305" />
+<par_real name="sin" value="-0.000559754" />
+</BF_HARMONIC>
+<BF_HARMONIC id="179">
+<par_real name="cos" value="-0.00530413" />
+<par_real name="sin" value="0.00560544" />
+</BF_HARMONIC>
+<BF_HARMONIC id="180">
+<par_real name="cos" value="0.00427461" />
+<par_real name="sin" value="0.00567459" />
+</BF_HARMONIC>
+<BF_HARMONIC id="181">
+<par_real name="cos" value="-0.00228622" />
+<par_real name="sin" value="-0.000580129" />
+</BF_HARMONIC>
+<BF_HARMONIC id="182">
+<par_real name="cos" value="-0.00532886" />
+<par_real name="sin" value="0.00539466" />
+</BF_HARMONIC>
+<BF_HARMONIC id="183">
+<par_real name="cos" value="0.00135711" />
+<par_real name="sin" value="0.00508561" />
+</BF_HARMONIC>
+<BF_HARMONIC id="184">
+<par_real name="cos" value="-0.00215316" />
+<par_real name="sin" value="-0.00059586" />
+</BF_HARMONIC>
+<BF_HARMONIC id="185">
+<par_real name="cos" value="-0.00534948" />
+<par_real name="sin" value="0.00518782" />
+</BF_HARMONIC>
+<BF_HARMONIC id="186">
+<par_real name="cos" value="-0.0110151" />
+<par_real name="sin" value="0.0183864" />
+</BF_HARMONIC>
+<BF_HARMONIC id="187">
+<par_real name="cos" value="-0.00202381" />
+<par_real name="sin" value="-0.000607143" />
+</BF_HARMONIC>
+<BF_HARMONIC id="188">
+<par_real name="cos" value="-0.00536609" />
+<par_real name="sin" value="0.00498484" />
+</BF_HARMONIC>
+<BF_HARMONIC id="189">
+<par_real name="cos" value="0.0011342" />
+<par_real name="sin" value="0.00512431" />
+</BF_HARMONIC>
+<BF_HARMONIC id="190">
+<par_real name="cos" value="-0.00189813" />
+<par_real name="sin" value="-0.000614167" />
+</BF_HARMONIC>
+<BF_HARMONIC id="191">
+<par_real name="cos" value="-0.0053788" />
+<par_real name="sin" value="0.00478563" />
+</BF_HARMONIC>
+<BF_HARMONIC id="192">
+<par_real name="cos" value="0.00692356" />
+<par_real name="sin" value="0.0245934" />
+</BF_HARMONIC>
+<BF_HARMONIC id="193">
+<par_real name="cos" value="-0.00177608" />
+<par_real name="sin" value="-0.000617113" />
+</BF_HARMONIC>
+<BF_HARMONIC id="194">
+<par_real name="cos" value="-0.00538771" />
+<par_real name="sin" value="0.00459011" />
+</BF_HARMONIC>
+<BF_HARMONIC id="195">
+<par_real name="cos" value="0.000910385" />
+<par_real name="sin" value="0.00515278" />
+</BF_HARMONIC>
+<BF_HARMONIC id="196">
+<par_real name="cos" value="-0.00165762" />
+<par_real name="sin" value="-0.000616155" />
+</BF_HARMONIC>
+<BF_HARMONIC id="197">
+<par_real name="cos" value="-0.00539291" />
+<par_real name="sin" value="0.00439823" />
+</BF_HARMONIC>
+<BF_HARMONIC id="198">
+<par_real name="cos" value="0.00359039" />
+<par_real name="sin" value="0.0058353" />
+</BF_HARMONIC>
+<BF_HARMONIC id="199">
+<par_real name="cos" value="-0.00154271" />
+<par_real name="sin" value="-0.00061146" />
+</BF_HARMONIC>
+<BF_HARMONIC id="200">
+<par_real name="cos" value="-0.00539452" />
+<par_real name="sin" value="0.00420992" />
+</BF_HARMONIC>
+<BF_HARMONIC id="201">
+<par_real name="cos" value="0.000686154" />
+<par_real name="sin" value="0.00517099" />
+</BF_HARMONIC>
+<BF_HARMONIC id="202">
+<par_real name="cos" value="-0.00143132" />
+<par_real name="sin" value="-0.00060319" />
+</BF_HARMONIC>
+<BF_HARMONIC id="203">
+<par_real name="cos" value="-0.00539261" />
+<par_real name="sin" value="0.00402513" />
+</BF_HARMONIC>
+<BF_HARMONIC id="204">
+<par_real name="cos" value="-0.0107583" />
+<par_real name="sin" value="0.0169337" />
+</BF_HARMONIC>
+<BF_HARMONIC id="205">
+<par_real name="cos" value="-0.00132343" />
+<par_real name="sin" value="-0.000591499" />
+</BF_HARMONIC>
+<BF_HARMONIC id="206">
+<par_real name="cos" value="-0.00538727" />
+<par_real name="sin" value="0.00384381" />
+</BF_HARMONIC>
+<BF_HARMONIC id="207">
+<par_real name="cos" value="0.000461997" />
+<par_real name="sin" value="0.00517897" />
+</BF_HARMONIC>
+<BF_HARMONIC id="208">
+<par_real name="cos" value="-0.00121899" />
+<par_real name="sin" value="-0.000576539" />
+</BF_HARMONIC>
+<BF_HARMONIC id="209">
+<par_real name="cos" value="-0.00537861" />
+<par_real name="sin" value="0.00366592" />
+</BF_HARMONIC>
+<BF_HARMONIC id="210">
+<par_real name="cos" value="0.00538897" />
+<par_real name="sin" value="0.0231723" />
+</BF_HARMONIC>
+<BF_HARMONIC id="211">
+<par_real name="cos" value="-0.00111799" />
+<par_real name="sin" value="-0.000558456" />
+</BF_HARMONIC>
+<BF_HARMONIC id="212">
+<par_real name="cos" value="-0.0053667" />
+<par_real name="sin" value="0.00349142" />
+</BF_HARMONIC>
+<BF_HARMONIC id="213">
+<par_real name="cos" value="0.000238399" />
+<par_real name="sin" value="0.00517675" />
+</BF_HARMONIC>
+<BF_HARMONIC id="214">
+<par_real name="cos" value="-0.0010204" />
+<par_real name="sin" value="-0.00053739" />
+</BF_HARMONIC>
+<BF_HARMONIC id="215">
+<par_real name="cos" value="-0.00535163" />
+<par_real name="sin" value="0.00332027" />
+</BF_HARMONIC>
+<BF_HARMONIC id="216">
+<par_real name="cos" value="0.00290328" />
+<par_real name="sin" value="0.00590358" />
+</BF_HARMONIC>
+<BF_HARMONIC id="217">
+<par_real name="cos" value="-0.00092619" />
+<par_real name="sin" value="-0.000513478" />
+</BF_HARMONIC>
+<BF_HARMONIC id="218">
+<par_real name="cos" value="-0.00533348" />
+<par_real name="sin" value="0.00315245" />
+</BF_HARMONIC>
+<BF_HARMONIC id="219">
+<par_real name="cos" value="1.58442e-05" />
+<par_real name="sin" value="0.00516439" />
+</BF_HARMONIC>
+<BF_HARMONIC id="220">
+<par_real name="cos" value="-0.000835346" />
+<par_real name="sin" value="-0.000486854" />
+</BF_HARMONIC>
+<BF_HARMONIC id="221">
+<par_real name="cos" value="-0.00531234" />
+<par_real name="sin" value="0.00298791" />
+</BF_HARMONIC>
+<BF_HARMONIC id="222">
+<par_real name="cos" value="-0.0106388" />
+<par_real name="sin" value="0.0156338" />
+</BF_HARMONIC>
+<BF_HARMONIC id="223">
+<par_real name="cos" value="-0.000747843" />
+<par_real name="sin" value="-0.000457648" />
+</BF_HARMONIC>
+<BF_HARMONIC id="224">
+<par_real name="cos" value="-0.00528829" />
+<par_real name="sin" value="0.00282665" />
+</BF_HARMONIC>
+<BF_HARMONIC id="225">
+<par_real name="cos" value="-0.000205189" />
+<par_real name="sin" value="0.00514197" />
+</BF_HARMONIC>
+<BF_HARMONIC id="226">
+<par_real name="cos" value="-0.000663658" />
+<par_real name="sin" value="-0.000425985" />
+</BF_HARMONIC>
+<BF_HARMONIC id="227">
+<par_real name="cos" value="-0.0052614" />
+<par_real name="sin" value="0.00266863" />
+</BF_HARMONIC>
+<BF_HARMONIC id="228">
+<par_real name="cos" value="0.00399131" />
+<par_real name="sin" value="0.0218819" />
+</BF_HARMONIC>
+<BF_HARMONIC id="229">
+<par_real name="cos" value="-0.000582773" />
+<par_real name="sin" value="-0.000391988" />
+</BF_HARMONIC>
+<BF_HARMONIC id="230">
+<par_real name="cos" value="-0.00523176" />
+<par_real name="sin" value="0.00251383" />
+</BF_HARMONIC>
+<BF_HARMONIC id="231">
+<par_real name="cos" value="-0.000424225" />
+<par_real name="sin" value="0.00510961" />
+</BF_HARMONIC>
+<BF_HARMONIC id="232">
+<par_real name="cos" value="-0.000505167" />
+<par_real name="sin" value="-0.000355779" />
+</BF_HARMONIC>
+<BF_HARMONIC id="233">
+<par_real name="cos" value="-0.00519944" />
+<par_real name="sin" value="0.00236225" />
+</BF_HARMONIC>
+<BF_HARMONIC id="234">
+<par_real name="cos" value="0.00222635" />
+<par_real name="sin" value="0.00588073" />
+</BF_HARMONIC>
+<BF_HARMONIC id="235">
+<par_real name="cos" value="-0.00043082" />
+<par_real name="sin" value="-0.000317474" />
+</BF_HARMONIC>
+<BF_HARMONIC id="236">
+<par_real name="cos" value="-0.00516452" />
+<par_real name="sin" value="0.00221385" />
+</BF_HARMONIC>
+<BF_HARMONIC id="237">
+<par_real name="cos" value="-0.000640798" />
+<par_real name="sin" value="0.00506744" />
+</BF_HARMONIC>
+<BF_HARMONIC id="238">
+<par_real name="cos" value="-0.000359712" />
+<par_real name="sin" value="-0.000277187" />
+</BF_HARMONIC>
+<BF_HARMONIC id="239">
+<par_real name="cos" value="-0.00512709" />
+<par_real name="sin" value="0.00206863" />
+</BF_HARMONIC>
+<BF_HARMONIC id="240">
+<par_real name="cos" value="-0.010612" />
+<par_real name="sin" value="0.0144341" />
+</BF_HARMONIC>
+<BF_HARMONIC id="241">
+<par_real name="cos" value="-0.000291824" />
+<par_real name="sin" value="-0.000235033" />
+</BF_HARMONIC>
+<BF_HARMONIC id="242">
+<par_real name="cos" value="-0.00508721" />
+<par_real name="sin" value="0.00192658" />
+</BF_HARMONIC>
+<BF_HARMONIC id="243">
+<par_real name="cos" value="-0.000854446" />
+<par_real name="sin" value="0.0050156" />
+</BF_HARMONIC>
+<BF_HARMONIC id="244">
+<par_real name="cos" value="-0.000227137" />
+<par_real name="sin" value="-0.000191119" />
+</BF_HARMONIC>
+<BF_HARMONIC id="245">
+<par_real name="cos" value="-0.00504496" />
+<par_real name="sin" value="0.00178767" />
+</BF_HARMONIC>
+<BF_HARMONIC id="246">
+<par_real name="cos" value="0.00271518" />
+<par_real name="sin" value="0.0206757" />
+</BF_HARMONIC>
+<BF_HARMONIC id="247">
+<par_real name="cos" value="-0.000165631" />
+<par_real name="sin" value="-0.000145554" />
+</BF_HARMONIC>
+<BF_HARMONIC id="248">
+<par_real name="cos" value="-0.00500042" />
+<par_real name="sin" value="0.00165191" />
+</BF_HARMONIC>
+<BF_HARMONIC id="249">
+<par_real name="cos" value="-0.00106472" />
+<par_real name="sin" value="0.00495427" />
+</BF_HARMONIC>
+<BF_HARMONIC id="250">
+<par_real name="cos" value="-0.000107286" />
+<par_real name="sin" value="-9.8444e-05" />
+</BF_HARMONIC>
+<BF_HARMONIC id="251">
+<par_real name="cos" value="-0.00495366" />
+<par_real name="sin" value="0.00151929" />
+</BF_HARMONIC>
+<BF_HARMONIC id="252">
+<par_real name="cos" value="0.00157232" />
+<par_real name="sin" value="0.00576991" />
+</BF_HARMONIC>
+<BF_HARMONIC id="253">
+<par_real name="cos" value="-5.20824e-05" />
+<par_real name="sin" value="-4.98921e-05" />
+</BF_HARMONIC>
+<BF_HARMONIC id="254">
+<par_real name="cos" value="-0.00490475" />
+<par_real name="sin" value="0.00138978" />
+</BF_HARMONIC>
+<BF_HARMONIC id="255">
+<par_real name="cos" value="-0.00127117" />
+<par_real name="sin" value="0.00488365" />
+</BF_HARMONIC>
+<BF_HARMONIC id="257">
+<par_real name="cos" value="-0.00485378" />
+<par_real name="sin" value="0.0012634" />
+</BF_HARMONIC>
+<BF_HARMONIC id="258">
+<par_real name="cos" value="-0.0106428" />
+<par_real name="sin" value="0.0132987" />
+</BF_HARMONIC>
+<BF_HARMONIC id="259">
+<par_real name="cos" value="4.8982e-05" />
+<par_real name="sin" value="5.11324e-05" />
+</BF_HARMONIC>
+<BF_HARMONIC id="260">
+<par_real name="cos" value="-0.00480081" />
+<par_real name="sin" value="0.00114012" />
+</BF_HARMONIC>
+<BF_HARMONIC id="261">
+<par_real name="cos" value="-0.00147338" />
+<par_real name="sin" value="0.00480396" />
+</BF_HARMONIC>
+<BF_HARMONIC id="262">
+<par_real name="cos" value="9.48848e-05" />
+<par_real name="sin" value="0.000103407" />
+</BF_HARMONIC>
+<BF_HARMONIC id="263">
+<par_real name="cos" value="-0.00474592" />
+<par_real name="sin" value="0.00101994" />
+</BF_HARMONIC>
+<BF_HARMONIC id="264">
+<par_real name="cos" value="0.00155234" />
+<par_real name="sin" value="0.0195226" />
+</BF_HARMONIC>
+<BF_HARMONIC id="265">
+<par_real name="cos" value="0.00013773" />
+<par_real name="sin" value="0.000156728" />
+</BF_HARMONIC>
+<BF_HARMONIC id="266">
+<par_real name="cos" value="-0.00468918" />
+<par_real name="sin" value="0.000902861" />
+</BF_HARMONIC>
+<BF_HARMONIC id="267">
+<par_real name="cos" value="-0.00167091" />
+<par_real name="sin" value="0.00471544" />
+</BF_HARMONIC>
+<BF_HARMONIC id="268">
+<par_real name="cos" value="0.00017754" />
+<par_real name="sin" value="0.000210999" />
+</BF_HARMONIC>
+<BF_HARMONIC id="269">
+<par_real name="cos" value="-0.00463067" />
+<par_real name="sin" value="0.00078887" />
+</BF_HARMONIC>
+<BF_HARMONIC id="270">
+<par_real name="cos" value="0.000953214" />
+<par_real name="sin" value="0.00557612" />
+</BF_HARMONIC>
+<BF_HARMONIC id="271">
+<par_real name="cos" value="0.000214338" />
+<par_real name="sin" value="0.000266129" />
+</BF_HARMONIC>
+<BF_HARMONIC id="272">
+<par_real name="cos" value="-0.00457045" />
+<par_real name="sin" value="0.000677962" />
+</BF_HARMONIC>
+<BF_HARMONIC id="273">
+<par_real name="cos" value="-0.00186337" />
+<par_real name="sin" value="0.00461835" />
+</BF_HARMONIC>
+<BF_HARMONIC id="274">
+<par_real name="cos" value="0.000248147" />
+<par_real name="sin" value="0.000322026" />
+</BF_HARMONIC>
+<BF_HARMONIC id="275">
+<par_real name="cos" value="-0.0045086" />
+<par_real name="sin" value="0.000570131" />
+</BF_HARMONIC>
+<BF_HARMONIC id="276">
+<par_real name="cos" value="-0.0107025" />
+<par_real name="sin" value="0.0122042" />
+</BF_HARMONIC>
+<BF_HARMONIC id="277">
+<par_real name="cos" value="0.000278992" />
+<par_real name="sin" value="0.000378599" />
+</BF_HARMONIC>
+<BF_HARMONIC id="278">
+<par_real name="cos" value="-0.0044452" />
+<par_real name="sin" value="0.000465371" />
+</BF_HARMONIC>
+<BF_HARMONIC id="279">
+<par_real name="cos" value="-0.00205036" />
+<par_real name="sin" value="0.00451296" />
+</BF_HARMONIC>
+<BF_HARMONIC id="280">
+<par_real name="cos" value="0.000306897" />
+<par_real name="sin" value="0.00043576" />
+</BF_HARMONIC>
+<BF_HARMONIC id="281">
+<par_real name="cos" value="-0.00438031" />
+<par_real name="sin" value="0.000363675" />
+</BF_HARMONIC>
+<BF_HARMONIC id="282">
+<par_real name="cos" value="0.000498973" />
+<par_real name="sin" value="0.0184023" />
+</BF_HARMONIC>
+<BF_HARMONIC id="283">
+<par_real name="cos" value="0.000331888" />
+<par_real name="sin" value="0.000493422" />
+</BF_HARMONIC>
+<BF_HARMONIC id="284">
+<par_real name="cos" value="-0.00431402" />
+<par_real name="sin" value="0.000265037" />
+</BF_HARMONIC>
+<BF_HARMONIC id="285">
+<par_real name="cos" value="-0.0022315" />
+<par_real name="sin" value="0.00439958" />
+</BF_HARMONIC>
+<BF_HARMONIC id="286">
+<par_real name="cos" value="0.000353993" />
+<par_real name="sin" value="0.0005515" />
+</BF_HARMONIC>
+<BF_HARMONIC id="287">
+<par_real name="cos" value="-0.00424638" />
+<par_real name="sin" value="0.00016945" />
+</BF_HARMONIC>
+<BF_HARMONIC id="288">
+<par_real name="cos" value="0.000380193" />
+<par_real name="sin" value="0.00530605" />
+</BF_HARMONIC>
+<BF_HARMONIC id="289">
+<par_real name="cos" value="0.000373238" />
+<par_real name="sin" value="0.000609909" />
+</BF_HARMONIC>
+<BF_HARMONIC id="290">
+<par_real name="cos" value="-0.00417747" />
+<par_real name="sin" value="7.69066e-05" />
+</BF_HARMONIC>
+<BF_HARMONIC id="291">
+<par_real name="cos" value="-0.00240644" />
+<par_real name="sin" value="0.00427851" />
+</BF_HARMONIC>
+<BF_HARMONIC id="292">
+<par_real name="cos" value="0.000389651" />
+<par_real name="sin" value="0.000668565" />
+</BF_HARMONIC>
+<BF_HARMONIC id="293">
+<par_real name="cos" value="-0.00410736" />
+<par_real name="sin" value="-1.26013e-05" />
+</BF_HARMONIC>
+<BF_HARMONIC id="294">
+<par_real name="cos" value="-0.0107676" />
+<par_real name="sin" value="0.0111357" />
+</BF_HARMONIC>
+<BF_HARMONIC id="295">
+<par_real name="cos" value="0.000403263" />
+<par_real name="sin" value="0.000727389" />
+</BF_HARMONIC>
+<BF_HARMONIC id="296">
+<par_real name="cos" value="-0.00403614" />
+<par_real name="sin" value="-9.90816e-05" />
+</BF_HARMONIC>
+<BF_HARMONIC id="297">
+<par_real name="cos" value="-0.00257482" />
+<par_real name="sin" value="0.0041501" />
+</BF_HARMONIC>
+<BF_HARMONIC id="298">
+<par_real name="cos" value="0.000414103" />
+<par_real name="sin" value="0.000786299" />
+</BF_HARMONIC>
+<BF_HARMONIC id="299">
+<par_real name="cos" value="-0.00396385" />
+<par_real name="sin" value="-0.000182543" />
+</BF_HARMONIC>
+<BF_HARMONIC id="300">
+<par_real name="cos" value="-0.000446151" />
+<par_real name="sin" value="0.0173025" />
+</BF_HARMONIC>
+<BF_HARMONIC id="301">
+<par_real name="cos" value="0.000422201" />
+<par_real name="sin" value="0.000845217" />
+</BF_HARMONIC>
+<BF_HARMONIC id="302">
+<par_real name="cos" value="-0.00389059" />
+<par_real name="sin" value="-0.000262995" />
+</BF_HARMONIC>
+<BF_HARMONIC id="303">
+<par_real name="cos" value="-0.00273631" />
+<par_real name="sin" value="0.00401469" />
+</BF_HARMONIC>
+<BF_HARMONIC id="304">
+<par_real name="cos" value="0.000427591" />
+<par_real name="sin" value="0.000904065" />
+</BF_HARMONIC>
+<BF_HARMONIC id="305">
+<par_real name="cos" value="-0.00381641" />
+<par_real name="sin" value="-0.000340448" />
+</BF_HARMONIC>
+<BF_HARMONIC id="306">
+<par_real name="cos" value="-0.000136753" />
+<par_real name="sin" value="0.00496791" />
+</BF_HARMONIC>
+<BF_HARMONIC id="307">
+<par_real name="cos" value="0.000430304" />
+<par_real name="sin" value="0.000962767" />
+</BF_HARMONIC>
+<BF_HARMONIC id="308">
+<par_real name="cos" value="-0.00374139" />
+<par_real name="sin" value="-0.000414913" />
+</BF_HARMONIC>
+<BF_HARMONIC id="309">
+<par_real name="cos" value="-0.0028906" />
+<par_real name="sin" value="0.00387264" />
+</BF_HARMONIC>
+<BF_HARMONIC id="310">
+<par_real name="cos" value="0.000430375" />
+<par_real name="sin" value="0.00102125" />
+</BF_HARMONIC>
+<BF_HARMONIC id="311">
+<par_real name="cos" value="-0.00366561" />
+<par_real name="sin" value="-0.0004864" />
+</BF_HARMONIC>
+<BF_HARMONIC id="312">
+<par_real name="cos" value="-0.0108189" />
+<par_real name="sin" value="0.0100851" />
+</BF_HARMONIC>
+<BF_HARMONIC id="313">
+<par_real name="cos" value="0.000427838" />
+<par_real name="sin" value="0.00107944" />
+</BF_HARMONIC>
+<BF_HARMONIC id="314">
+<par_real name="cos" value="-0.00358912" />
+<par_real name="sin" value="-0.000554923" />
+</BF_HARMONIC>
+<BF_HARMONIC id="315">
+<par_real name="cos" value="-0.00303741" />
+<par_real name="sin" value="0.00372434" />
+</BF_HARMONIC>
+<BF_HARMONIC id="316">
+<par_real name="cos" value="0.00042273" />
+<par_real name="sin" value="0.00113726" />
+</BF_HARMONIC>
+<BF_HARMONIC id="317">
+<par_real name="cos" value="-0.003512" />
+<par_real name="sin" value="-0.000620495" />
+</BF_HARMONIC>
+<BF_HARMONIC id="318">
+<par_real name="cos" value="-0.00128291" />
+<par_real name="sin" value="0.0162167" />
+</BF_HARMONIC>
+<BF_HARMONIC id="319">
+<par_real name="cos" value="0.000415086" />
+<par_real name="sin" value="0.00119464" />
+</BF_HARMONIC>
+<BF_HARMONIC id="320">
+<par_real name="cos" value="-0.00343432" />
+<par_real name="sin" value="-0.000683129" />
+</BF_HARMONIC>
+<BF_HARMONIC id="321">
+<par_real name="cos" value="-0.00317646" />
+<par_real name="sin" value="0.00357018" />
+</BF_HARMONIC>
+<BF_HARMONIC id="322">
+<par_real name="cos" value="0.000404945" />
+<par_real name="sin" value="0.00125152" />
+</BF_HARMONIC>
+<BF_HARMONIC id="323">
+<par_real name="cos" value="-0.00335615" />
+<par_real name="sin" value="-0.00074284" />
+</BF_HARMONIC>
+<BF_HARMONIC id="324">
+<par_real name="cos" value="-0.000588994" />
+<par_real name="sin" value="0.00457131" />
+</BF_HARMONIC>
+<BF_HARMONIC id="325">
+<par_real name="cos" value="0.000392344" />
+<par_real name="sin" value="0.00130782" />
+</BF_HARMONIC>
+<BF_HARMONIC id="326">
+<par_real name="cos" value="-0.00327756" />
+<par_real name="sin" value="-0.000799645" />
+</BF_HARMONIC>
+<BF_HARMONIC id="327">
+<par_real name="cos" value="-0.0033075" />
+<par_real name="sin" value="0.00341056" />
+</BF_HARMONIC>
+<BF_HARMONIC id="328">
+<par_real name="cos" value="0.000377324" />
+<par_real name="sin" value="0.00136347" />
+</BF_HARMONIC>
+<BF_HARMONIC id="329">
+<par_real name="cos" value="-0.00319861" />
+<par_real name="sin" value="-0.00085356" />
+</BF_HARMONIC>
+<BF_HARMONIC id="330">
+<par_real name="cos" value="-0.0108406" />
+<par_real name="sin" value="0.00904913" />
+</BF_HARMONIC>
+<BF_HARMONIC id="331">
+<par_real name="cos" value="0.000359925" />
+<par_real name="sin" value="0.00141843" />
+</BF_HARMONIC>
+<BF_HARMONIC id="332">
+<par_real name="cos" value="-0.00311938" />
+<par_real name="sin" value="-0.000904602" />
+</BF_HARMONIC>
+<BF_HARMONIC id="333">
+<par_real name="cos" value="-0.00343029" />
+<par_real name="sin" value="0.0032459" />
+</BF_HARMONIC>
+<BF_HARMONIC id="334">
+<par_real name="cos" value="0.000340189" />
+<par_real name="sin" value="0.00147261" />
+</BF_HARMONIC>
+<BF_HARMONIC id="335">
+<par_real name="cos" value="-0.00303992" />
+<par_real name="sin" value="-0.000952791" />
+</BF_HARMONIC>
+<BF_HARMONIC id="336">
+<par_real name="cos" value="-0.00201076" />
+<par_real name="sin" value="0.0151433" />
+</BF_HARMONIC>
+<BF_HARMONIC id="337">
+<par_real name="cos" value="0.000318158" />
+<par_real name="sin" value="0.00152595" />
+</BF_HARMONIC>
+<BF_HARMONIC id="338">
+<par_real name="cos" value="-0.00296032" />
+<par_real name="sin" value="-0.000998146" />
+</BF_HARMONIC>
+<BF_HARMONIC id="339">
+<par_real name="cos" value="-0.00354463" />
+<par_real name="sin" value="0.00307663" />
+</BF_HARMONIC>
+<BF_HARMONIC id="340">
+<par_real name="cos" value="0.000293875" />
+<par_real name="sin" value="0.0015784" />
+</BF_HARMONIC>
+<BF_HARMONIC id="341">
+<par_real name="cos" value="-0.00288064" />
+<par_real name="sin" value="-0.00104069" />
+</BF_HARMONIC>
+<BF_HARMONIC id="342">
+<par_real name="cos" value="-0.00096945" />
+<par_real name="sin" value="0.00412698" />
+</BF_HARMONIC>
+<BF_HARMONIC id="343">
+<par_real name="cos" value="0.000267384" />
+<par_real name="sin" value="0.00162989" />
+</BF_HARMONIC>
+<BF_HARMONIC id="344">
+<par_real name="cos" value="-0.00280093" />
+<par_real name="sin" value="-0.00108044" />
+</BF_HARMONIC>
+<BF_HARMONIC id="345">
+<par_real name="cos" value="-0.00365032" />
+<par_real name="sin" value="0.00290319" />
+</BF_HARMONIC>
+<BF_HARMONIC id="346">
+<par_real name="cos" value="0.00023873" />
+<par_real name="sin" value="0.00168036" />
+</BF_HARMONIC>
+<BF_HARMONIC id="347">
+<par_real name="cos" value="-0.00272128" />
+<par_real name="sin" value="-0.00111742" />
+</BF_HARMONIC>
+<BF_HARMONIC id="348">
+<par_real name="cos" value="-0.0108201" />
+<par_real name="sin" value="0.00802838" />
+</BF_HARMONIC>
+<BF_HARMONIC id="349">
+<par_real name="cos" value="0.000207961" />
+<par_real name="sin" value="0.00172977" />
+</BF_HARMONIC>
+<BF_HARMONIC id="350">
+<par_real name="cos" value="-0.00264174" />
+<par_real name="sin" value="-0.00115166" />
+</BF_HARMONIC>
+<BF_HARMONIC id="351">
+<par_real name="cos" value="-0.00374721" />
+<par_real name="sin" value="0.00272602" />
+</BF_HARMONIC>
+<BF_HARMONIC id="352">
+<par_real name="cos" value="0.000175122" />
+<par_real name="sin" value="0.00177804" />
+</BF_HARMONIC>
+<BF_HARMONIC id="353">
+<par_real name="cos" value="-0.00256237" />
+<par_real name="sin" value="-0.00118318" />
+</BF_HARMONIC>
+<BF_HARMONIC id="354">
+<par_real name="cos" value="-0.00262936" />
+<par_real name="sin" value="0.0140837" />
+</BF_HARMONIC>
+<BF_HARMONIC id="355">
+<par_real name="cos" value="0.000140261" />
+<par_real name="sin" value="0.00182513" />
+</BF_HARMONIC>
+<BF_HARMONIC id="356">
+<par_real name="cos" value="-0.00248325" />
+<par_real name="sin" value="-0.001212" />
+</BF_HARMONIC>
+<BF_HARMONIC id="357">
+<par_real name="cos" value="-0.00383515" />
+<par_real name="sin" value="0.00254558" />
+</BF_HARMONIC>
+<BF_HARMONIC id="358">
+<par_real name="cos" value="0.000103427" />
+<par_real name="sin" value="0.00187099" />
+</BF_HARMONIC>
+<BF_HARMONIC id="359">
+<par_real name="cos" value="-0.00240444" />
+<par_real name="sin" value="-0.00123816" />
+</BF_HARMONIC>
+<BF_HARMONIC id="360">
+<par_real name="cos" value="-0.00127274" />
+<par_real name="sin" value="0.00364653" />
+</BF_HARMONIC>
+<BF_HARMONIC id="361">
+<par_real name="cos" value="6.46698e-05" />
+<par_real name="sin" value="0.00191555" />
+</BF_HARMONIC>
+<BF_HARMONIC id="362">
+<par_real name="cos" value="-0.002326" />
+<par_real name="sin" value="-0.00126168" />
+</BF_HARMONIC>
+<BF_HARMONIC id="363">
+<par_real name="cos" value="-0.00391402" />
+<par_real name="sin" value="0.00236232" />
+</BF_HARMONIC>
+<BF_HARMONIC id="364">
+<par_real name="cos" value="2.4039e-05" />
+<par_real name="sin" value="0.00195878" />
+</BF_HARMONIC>
+<BF_HARMONIC id="365">
+<par_real name="cos" value="-0.00224799" />
+<par_real name="sin" value="-0.0012826" />
+</BF_HARMONIC>
+<BF_HARMONIC id="366">
+<par_real name="cos" value="-0.010748" />
+<par_real name="sin" value="0.00702631" />
+</BF_HARMONIC>
+<BF_HARMONIC id="367">
+<par_real name="cos" value="-1.8414e-05" />
+<par_real name="sin" value="0.00200062" />
+</BF_HARMONIC>
+<BF_HARMONIC id="368">
+<par_real name="cos" value="-0.00217047" />
+<par_real name="sin" value="-0.00130093" />
+</BF_HARMONIC>
+<BF_HARMONIC id="369">
+<par_real name="cos" value="-0.00398372" />
+<par_real name="sin" value="0.00217672" />
+</BF_HARMONIC>
+<BF_HARMONIC id="370">
+<par_real name="cos" value="-6.26374e-05" />
+<par_real name="sin" value="0.00204102" />
+</BF_HARMONIC>
+<BF_HARMONIC id="371">
+<par_real name="cos" value="-0.00209351" />
+<par_real name="sin" value="-0.00131672" />
+</BF_HARMONIC>
+<BF_HARMONIC id="372">
+<par_real name="cos" value="-0.00313908" />
+<par_real name="sin" value="0.0130423" />
+</BF_HARMONIC>
+<BF_HARMONIC id="373">
+<par_real name="cos" value="-0.000108579" />
+<par_real name="sin" value="0.00207994" />
+</BF_HARMONIC>
+<BF_HARMONIC id="374">
+<par_real name="cos" value="-0.00201716" />
+<par_real name="sin" value="-0.00132999" />
+</BF_HARMONIC>
+<BF_HARMONIC id="375">
+<par_real name="cos" value="-0.00404418" />
+<par_real name="sin" value="0.00198923" />
+</BF_HARMONIC>
+<BF_HARMONIC id="376">
+<par_real name="cos" value="-0.000156184" />
+<par_real name="sin" value="0.00211734" />
+</BF_HARMONIC>
+<BF_HARMONIC id="377">
+<par_real name="cos" value="-0.00194149" />
+<par_real name="sin" value="-0.00134079" />
+</BF_HARMONIC>
+<BF_HARMONIC id="378">
+<par_real name="cos" value="-0.00149532" />
+<par_real name="sin" value="0.00314224" />
+</BF_HARMONIC>
+<BF_HARMONIC id="379">
+<par_real name="cos" value="-0.000205401" />
+<par_real name="sin" value="0.00215317" />
+</BF_HARMONIC>
+<BF_HARMONIC id="380">
+<par_real name="cos" value="-0.00186655" />
+<par_real name="sin" value="-0.00134914" />
+</BF_HARMONIC>
+<BF_HARMONIC id="381">
+<par_real name="cos" value="-0.00409536" />
+<par_real name="sin" value="0.00180033" />
+</BF_HARMONIC>
+<BF_HARMONIC id="382">
+<par_real name="cos" value="-0.000256173" />
+<par_real name="sin" value="0.00218739" />
+</BF_HARMONIC>
+<BF_HARMONIC id="383">
+<par_real name="cos" value="-0.0017924" />
+<par_real name="sin" value="-0.00135508" />
+</BF_HARMONIC>
+<BF_HARMONIC id="384">
+<par_real name="cos" value="-0.0106172" />
+<par_real name="sin" value="0.0060485" />
+</BF_HARMONIC>
+<BF_HARMONIC id="385">
+<par_real name="cos" value="-0.000308445" />
+<par_real name="sin" value="0.00221995" />
+</BF_HARMONIC>
+<BF_HARMONIC id="386">
+<par_real name="cos" value="-0.0017191" />
+<par_real name="sin" value="-0.00135865" />
+</BF_HARMONIC>
+<BF_HARMONIC id="387">
+<par_real name="cos" value="-0.00413721" />
+<par_real name="sin" value="0.0016105" />
+</BF_HARMONIC>
+<BF_HARMONIC id="388">
+<par_real name="cos" value="-0.000362162" />
+<par_real name="sin" value="0.00225083" />
+</BF_HARMONIC>
+<BF_HARMONIC id="389">
+<par_real name="cos" value="-0.0016467" />
+<par_real name="sin" value="-0.00135989" />
+</BF_HARMONIC>
+<BF_HARMONIC id="390">
+<par_real name="cos" value="-0.00354132" />
+<par_real name="sin" value="0.0120253" />
+</BF_HARMONIC>
+<BF_HARMONIC id="391">
+<par_real name="cos" value="-0.000417267" />
+<par_real name="sin" value="0.00227999" />
+</BF_HARMONIC>
+<BF_HARMONIC id="392">
+<par_real name="cos" value="-0.00157526" />
+<par_real name="sin" value="-0.00135883" />
+</BF_HARMONIC>
+<BF_HARMONIC id="393">
+<par_real name="cos" value="-0.00416976" />
+<par_real name="sin" value="0.0014202" />
+</BF_HARMONIC>
+<BF_HARMONIC id="394">
+<par_real name="cos" value="-0.000473702" />
+<par_real name="sin" value="0.00230738" />
+</BF_HARMONIC>
+<BF_HARMONIC id="395">
+<par_real name="cos" value="-0.00150483" />
+<par_real name="sin" value="-0.00135552" />
+</BF_HARMONIC>
+<BF_HARMONIC id="396">
+<par_real name="cos" value="-0.00163552" />
+<par_real name="sin" value="0.00262673" />
+</BF_HARMONIC>
+<BF_HARMONIC id="397">
+<par_real name="cos" value="-0.000531411" />
+<par_real name="sin" value="0.00233297" />
+</BF_HARMONIC>
+<BF_HARMONIC id="398">
+<par_real name="cos" value="-0.00143548" />
+<par_real name="sin" value="-0.00134999" />
+</BF_HARMONIC>
+<BF_HARMONIC id="399">
+<par_real name="cos" value="-0.00419301" />
+<par_real name="sin" value="0.00122991" />
+</BF_HARMONIC>
+<BF_HARMONIC id="400">
+<par_real name="cos" value="-0.000590334" />
+<par_real name="sin" value="0.00235674" />
+</BF_HARMONIC>
+<BF_HARMONIC id="401">
+<par_real name="cos" value="-0.00136724" />
+<par_real name="sin" value="-0.0013423" />
+</BF_HARMONIC>
+<BF_HARMONIC id="402">
+<par_real name="cos" value="-0.0104237" />
+<par_real name="sin" value="0.00510206" />
+</BF_HARMONIC>
+<BF_HARMONIC id="403">
+<par_real name="cos" value="-0.000650413" />
+<par_real name="sin" value="0.00237865" />
+</BF_HARMONIC>
+<BF_HARMONIC id="404">
+<par_real name="cos" value="-0.00130017" />
+<par_real name="sin" value="-0.00133248" />
+</BF_HARMONIC>
+<BF_HARMONIC id="405">
+<par_real name="cos" value="-0.00420702" />
+<par_real name="sin" value="0.0010401" />
+</BF_HARMONIC>
+<BF_HARMONIC id="406">
+<par_real name="cos" value="-0.000711588" />
+<par_real name="sin" value="0.00239868" />
+</BF_HARMONIC>
+<BF_HARMONIC id="407">
+<par_real name="cos" value="-0.00123432" />
+<par_real name="sin" value="-0.00132057" />
+</BF_HARMONIC>
+<BF_HARMONIC id="408">
+<par_real name="cos" value="-0.00383877" />
+<par_real name="sin" value="0.0110401" />
+</BF_HARMONIC>
+<BF_HARMONIC id="409">
+<par_real name="cos" value="-0.000773801" />
+<par_real name="sin" value="0.00241679" />
+</BF_HARMONIC>
+<BF_HARMONIC id="410">
+<par_real name="cos" value="-0.00116974" />
+<par_real name="sin" value="-0.00130663" />
+</BF_HARMONIC>
+<BF_HARMONIC id="411">
+<par_real name="cos" value="-0.00421185" />
+<par_real name="sin" value="0.00085123" />
+</BF_HARMONIC>
+<BF_HARMONIC id="412">
+<par_real name="cos" value="-0.000836991" />
+<par_real name="sin" value="0.00243295" />
+</BF_HARMONIC>
+<BF_HARMONIC id="413">
+<par_real name="cos" value="-0.00110648" />
+<par_real name="sin" value="-0.0012907" />
+</BF_HARMONIC>
+<BF_HARMONIC id="414">
+<par_real name="cos" value="-0.00169363" />
+<par_real name="sin" value="0.00211273" />
+</BF_HARMONIC>
+<BF_HARMONIC id="415">
+<par_real name="cos" value="-0.000901098" />
+<par_real name="sin" value="0.00244716" />
+</BF_HARMONIC>
+<BF_HARMONIC id="416">
+<par_real name="cos" value="-0.00104458" />
+<par_real name="sin" value="-0.00127282" />
+</BF_HARMONIC>
+<BF_HARMONIC id="417">
+<par_real name="cos" value="-0.0042076" />
+<par_real name="sin" value="0.000663772" />
+</BF_HARMONIC>
+<BF_HARMONIC id="418">
+<par_real name="cos" value="-0.00096606" />
+<par_real name="sin" value="0.00245937" />
+</BF_HARMONIC>
+<BF_HARMONIC id="419">
+<par_real name="cos" value="-0.000984094" />
+<par_real name="sin" value="-0.00125305" />
+</BF_HARMONIC>
+<BF_HARMONIC id="420">
+<par_real name="cos" value="-0.0101656" />
+<par_real name="sin" value="0.004195" />
+</BF_HARMONIC>
+<BF_HARMONIC id="421">
+<par_real name="cos" value="-0.00103182" />
+<par_real name="sin" value="0.00246957" />
+</BF_HARMONIC>
+<BF_HARMONIC id="422">
+<par_real name="cos" value="-0.000925064" />
+<par_real name="sin" value="-0.00123144" />
+</BF_HARMONIC>
+<BF_HARMONIC id="423">
+<par_real name="cos" value="-0.00419439" />
+<par_real name="sin" value="0.00047818" />
+</BF_HARMONIC>
+<BF_HARMONIC id="424">
+<par_real name="cos" value="-0.00109831" />
+<par_real name="sin" value="0.00247774" />
+</BF_HARMONIC>
+<BF_HARMONIC id="425">
+<par_real name="cos" value="-0.000867532" />
+<par_real name="sin" value="-0.00120803" />
+</BF_HARMONIC>
+<BF_HARMONIC id="426">
+<par_real name="cos" value="-0.00403552" />
+<par_real name="sin" value="0.0100951" />
+</BF_HARMONIC>
+<BF_HARMONIC id="427">
+<par_real name="cos" value="-0.00116547" />
+<par_real name="sin" value="0.00248387" />
+</BF_HARMONIC>
+<BF_HARMONIC id="428">
+<par_real name="cos" value="-0.000811542" />
+<par_real name="sin" value="-0.00118287" />
+</BF_HARMONIC>
+<BF_HARMONIC id="429">
+<par_real name="cos" value="-0.00417236" />
+<par_real name="sin" value="0.000294904" />
+</BF_HARMONIC>
+<BF_HARMONIC id="430">
+<par_real name="cos" value="-0.00123324" />
+<par_real name="sin" value="0.00248793" />
+</BF_HARMONIC>
+<BF_HARMONIC id="431">
+<par_real name="cos" value="-0.000757134" />
+<par_real name="sin" value="-0.00115602" />
+</BF_HARMONIC>
+<BF_HARMONIC id="432">
+<par_real name="cos" value="-0.00167184" />
+<par_real name="sin" value="0.00161271" />
+</BF_HARMONIC>
+<BF_HARMONIC id="433">
+<par_real name="cos" value="-0.00130157" />
+<par_real name="sin" value="0.00248991" />
+</BF_HARMONIC>
+<BF_HARMONIC id="434">
+<par_real name="cos" value="-0.000704349" />
+<par_real name="sin" value="-0.00112754" />
+</BF_HARMONIC>
+<BF_HARMONIC id="435">
+<par_real name="cos" value="-0.00414167" />
+<par_real name="sin" value="0.000114387" />
+</BF_HARMONIC>
+<BF_HARMONIC id="436">
+<par_real name="cos" value="-0.00137037" />
+<par_real name="sin" value="0.0024898" />
+</BF_HARMONIC>
+<BF_HARMONIC id="437">
+<par_real name="cos" value="-0.000653225" />
+<par_real name="sin" value="-0.00109746" />
+</BF_HARMONIC>
+<BF_HARMONIC id="438">
+<par_real name="cos" value="-0.00984361" />
+<par_real name="sin" value="0.00333582" />
+</BF_HARMONIC>
+<BF_HARMONIC id="439">
+<par_real name="cos" value="-0.00143961" />
+<par_real name="sin" value="0.00248759" />
+</BF_HARMONIC>
+<BF_HARMONIC id="440">
+<par_real name="cos" value="-0.000603799" />
+<par_real name="sin" value="-0.00106585" />
+</BF_HARMONIC>
+<BF_HARMONIC id="441">
+<par_real name="cos" value="-0.0041025" />
+<par_real name="sin" value="-6.29366e-05" />
+</BF_HARMONIC>
+<BF_HARMONIC id="442">
+<par_real name="cos" value="-0.0015092" />
+<par_real name="sin" value="0.00248326" />
+</BF_HARMONIC>
+<BF_HARMONIC id="443">
+<par_real name="cos" value="-0.000556108" />
+<par_real name="sin" value="-0.00103277" />
+</BF_HARMONIC>
+<BF_HARMONIC id="444">
+<par_real name="cos" value="-0.00413718" />
+<par_real name="sin" value="0.00919876" />
+</BF_HARMONIC>
+<BF_HARMONIC id="445">
+<par_real name="cos" value="-0.00157909" />
+<par_real name="sin" value="0.00247681" />
+</BF_HARMONIC>
+<BF_HARMONIC id="446">
+<par_real name="cos" value="-0.000510185" />
+<par_real name="sin" value="-0.000998265" />
+</BF_HARMONIC>
+<BF_HARMONIC id="447">
+<par_real name="cos" value="-0.00405508" />
+<par_real name="sin" value="-0.000236644" />
+</BF_HARMONIC>
+<BF_HARMONIC id="448">
+<par_real name="cos" value="-0.00164922" />
+<par_real name="sin" value="0.00246823" />
+</BF_HARMONIC>
+<BF_HARMONIC id="449">
+<par_real name="cos" value="-0.000466065" />
+<par_real name="sin" value="-0.000962394" />
+</BF_HARMONIC>
+<BF_HARMONIC id="450">
+<par_real name="cos" value="-0.00157425" />
+<par_real name="sin" value="0.0011387" />
+</BF_HARMONIC>
+<BF_HARMONIC id="451">
+<par_real name="cos" value="-0.00171952" />
+<par_real name="sin" value="0.00245752" />
+</BF_HARMONIC>
+<BF_HARMONIC id="452">
+<par_real name="cos" value="-0.00042378" />
+<par_real name="sin" value="-0.000925216" />
+</BF_HARMONIC>
+<BF_HARMONIC id="453">
+<par_real name="cos" value="-0.00399962" />
+<par_real name="sin" value="-0.000406322" />
+</BF_HARMONIC>
+<BF_HARMONIC id="454">
+<par_real name="cos" value="-0.00178994" />
+<par_real name="sin" value="0.00244466" />
+</BF_HARMONIC>
+<BF_HARMONIC id="455">
+<par_real name="cos" value="-0.00038336" />
+<par_real name="sin" value="-0.000886788" />
+</BF_HARMONIC>
+<BF_HARMONIC id="456">
+<par_real name="cos" value="-0.00946061" />
+<par_real name="sin" value="0.00253305" />
+</BF_HARMONIC>
+<BF_HARMONIC id="457">
+<par_real name="cos" value="-0.0018604" />
+<par_real name="sin" value="0.00242967" />
+</BF_HARMONIC>
+<BF_HARMONIC id="458">
+<par_real name="cos" value="-0.000344834" />
+<par_real name="sin" value="-0.000847169" />
+</BF_HARMONIC>
+<BF_HARMONIC id="459">
+<par_real name="cos" value="-0.00393638" />
+<par_real name="sin" value="-0.00057157" />
+</BF_HARMONIC>
+<BF_HARMONIC id="460">
+<par_real name="cos" value="-0.00193086" />
+<par_real name="sin" value="0.00241253" />
+</BF_HARMONIC>
+<BF_HARMONIC id="461">
+<par_real name="cos" value="-0.000308231" />
+<par_real name="sin" value="-0.000806418" />
+</BF_HARMONIC>
+<BF_HARMONIC id="462">
+<par_real name="cos" value="-0.00415082" />
+<par_real name="sin" value="0.00835961" />
+</BF_HARMONIC>
+<BF_HARMONIC id="463">
+<par_real name="cos" value="-0.00200124" />
+<par_real name="sin" value="0.00239326" />
+</BF_HARMONIC>
+<BF_HARMONIC id="464">
+<par_real name="cos" value="-0.000273576" />
+<par_real name="sin" value="-0.000764594" />
+</BF_HARMONIC>
+<BF_HARMONIC id="465">
+<par_real name="cos" value="-0.00386563" />
+<par_real name="sin" value="-0.000732001" />
+</BF_HARMONIC>
+<BF_HARMONIC id="466">
+<par_real name="cos" value="-0.00207148" />
+<par_real name="sin" value="0.00237184" />
+</BF_HARMONIC>
+<BF_HARMONIC id="467">
+<par_real name="cos" value="-0.000240895" />
+<par_real name="sin" value="-0.000721758" />
+</BF_HARMONIC>
+<BF_HARMONIC id="468">
+<par_real name="cos" value="-0.00140673" />
+<par_real name="sin" value="0.000701925" />
+</BF_HARMONIC>
+<BF_HARMONIC id="469">
+<par_real name="cos" value="-0.00214153" />
+<par_real name="sin" value="0.0023483" />
+</BF_HARMONIC>
+<BF_HARMONIC id="470">
+<par_real name="cos" value="-0.000210211" />
+<par_real name="sin" value="-0.00067797" />
+</BF_HARMONIC>
+<BF_HARMONIC id="471">
+<par_real name="cos" value="-0.00378765" />
+<par_real name="sin" value="-0.000887242" />
+</BF_HARMONIC>
+<BF_HARMONIC id="472">
+<par_real name="cos" value="-0.00221132" />
+<par_real name="sin" value="0.00232262" />
+</BF_HARMONIC>
+<BF_HARMONIC id="473">
+<par_real name="cos" value="-0.000181547" />
+<par_real name="sin" value="-0.000633292" />
+</BF_HARMONIC>
+<BF_HARMONIC id="474">
+<par_real name="cos" value="-0.00902149" />
+<par_real name="sin" value="0.00179485" />
+</BF_HARMONIC>
+<BF_HARMONIC id="475">
+<par_real name="cos" value="-0.00228079" />
+<par_real name="sin" value="0.00229483" />
+</BF_HARMONIC>
+<BF_HARMONIC id="476">
+<par_real name="cos" value="-0.000154922" />
+<par_real name="sin" value="-0.000587785" />
+</BF_HARMONIC>
+<BF_HARMONIC id="477">
+<par_real name="cos" value="-0.00370277" />
+<par_real name="sin" value="-0.00103694" />
+</BF_HARMONIC>
+<BF_HARMONIC id="478">
+<par_real name="cos" value="-0.00234988" />
+<par_real name="sin" value="0.00226493" />
+</BF_HARMONIC>
+<BF_HARMONIC id="479">
+<par_real name="cos" value="-0.000130357" />
+<par_real name="sin" value="-0.000541512" />
+</BF_HARMONIC>
+<BF_HARMONIC id="480">
+<par_real name="cos" value="-0.00408501" />
+<par_real name="sin" value="0.00758564" />
+</BF_HARMONIC>
+<BF_HARMONIC id="481">
+<par_real name="cos" value="-0.00241854" />
+<par_real name="sin" value="0.00223292" />
+</BF_HARMONIC>
+<BF_HARMONIC id="482">
+<par_real name="cos" value="-0.000107868" />
+<par_real name="sin" value="-0.000494535" />
+</BF_HARMONIC>
+<BF_HARMONIC id="483">
+<par_real name="cos" value="-0.00361131" />
+<par_real name="sin" value="-0.00118074" />
+</BF_HARMONIC>
+<BF_HARMONIC id="484">
+<par_real name="cos" value="-0.00248669" />
+<par_real name="sin" value="0.00219883" />
+</BF_HARMONIC>
+<BF_HARMONIC id="485">
+<par_real name="cos" value="-8.74726e-05" />
+<par_real name="sin" value="-0.000446916" />
+</BF_HARMONIC>
+<BF_HARMONIC id="486">
+<par_real name="cos" value="-0.00117686" />
+<par_real name="sin" value="0.000312603" />
+</BF_HARMONIC>
+<BF_HARMONIC id="487">
+<par_real name="cos" value="-0.00255428" />
+<par_real name="sin" value="0.00216266" />
+</BF_HARMONIC>
+<BF_HARMONIC id="488">
+<par_real name="cos" value="-6.91844e-05" />
+<par_real name="sin" value="-0.000398719" />
+</BF_HARMONIC>
+<BF_HARMONIC id="489">
+<par_real name="cos" value="-0.00351361" />
+<par_real name="sin" value="-0.00131833" />
+</BF_HARMONIC>
+<BF_HARMONIC id="490">
+<par_real name="cos" value="-0.00262126" />
+<par_real name="sin" value="0.00212443" />
+</BF_HARMONIC>
+<BF_HARMONIC id="491">
+<par_real name="cos" value="-5.30167e-05" />
+<par_real name="sin" value="-0.000350008" />
+</BF_HARMONIC>
+<BF_HARMONIC id="492">
+<par_real name="cos" value="-0.00853301" />
+<par_real name="sin" value="0.00112869" />
+</BF_HARMONIC>
+<BF_HARMONIC id="493">
+<par_real name="cos" value="-0.00268756" />
+<par_real name="sin" value="0.00208416" />
+</BF_HARMONIC>
+<BF_HARMONIC id="494">
+<par_real name="cos" value="-3.89813e-05" />
+<par_real name="sin" value="-0.000300846" />
+</BF_HARMONIC>
+<BF_HARMONIC id="495">
+<par_real name="cos" value="-0.00341004" />
+<par_real name="sin" value="-0.0014494" />
+</BF_HARMONIC>
+<BF_HARMONIC id="496">
+<par_real name="cos" value="-0.00275313" />
+<par_real name="sin" value="0.00204186" />
+</BF_HARMONIC>
+<BF_HARMONIC id="497">
+<par_real name="cos" value="-2.70881e-05" />
+<par_real name="sin" value="-0.000251297" />
+</BF_HARMONIC>
+<BF_HARMONIC id="498">
+<par_real name="cos" value="-0.00394964" />
+<par_real name="sin" value="0.00688405" />
+</BF_HARMONIC>
+<BF_HARMONIC id="499">
+<par_real name="cos" value="-0.0028179" />
+<par_real name="sin" value="0.00199755" />
+</BF_HARMONIC>
+<BF_HARMONIC id="500">
+<par_real name="cos" value="-1.73457e-05" />
+<par_real name="sin" value="-0.000201425" />
+</BF_HARMONIC>
+<BF_HARMONIC id="501">
+<par_real name="cos" value="-0.00330098" />
+<par_real name="sin" value="-0.00157366" />
+</BF_HARMONIC>
+<BF_HARMONIC id="502">
+<par_real name="cos" value="-0.00288183" />
+<par_real name="sin" value="0.00195126" />
+</BF_HARMONIC>
+<BF_HARMONIC id="503">
+<par_real name="cos" value="-9.76103e-06" />
+<par_real name="sin" value="-0.000151295" />
+</BF_HARMONIC>
+<BF_HARMONIC id="504">
+<par_real name="cos" value="-0.000893711" />
+<par_real name="sin" value="-2.03193e-05" />
+</BF_HARMONIC>
+<BF_HARMONIC id="505">
+<par_real name="cos" value="-0.00294485" />
+<par_real name="sin" value="0.001903" />
+</BF_HARMONIC>
+<BF_HARMONIC id="506">
+<par_real name="cos" value="-4.33953e-06" />
+<par_real name="sin" value="-0.000100971" />
+</BF_HARMONIC>
+<BF_HARMONIC id="507">
+<par_real name="cos" value="-0.00318682" />
+<par_real name="sin" value="-0.00169084" />
+</BF_HARMONIC>
+<BF_HARMONIC id="508">
+<par_real name="cos" value="-0.00300692" />
+<par_real name="sin" value="0.00185281" />
+</BF_HARMONIC>
+<BF_HARMONIC id="509">
+<par_real name="cos" value="-1.08508e-06" />
+<par_real name="sin" value="-5.05179e-05" />
+</BF_HARMONIC>
+<BF_HARMONIC id="510">
+<par_real name="cos" value="-0.00800357" />
+<par_real name="sin" value="0.000541017" />
+</BF_HARMONIC>
+<BF_HARMONIC id="511">
+<par_real name="cos" value="-0.00306797" />
+<par_real name="sin" value="0.0018007" />
+</BF_HARMONIC>
+</BASE_FUNCTION>
+</OSCIL>
+<RESONANCE>
+<par_bool name="enabled" value="no" />
+</RESONANCE>
+<HARMONIC_POSITION>
+<par name="type" value="0" />
+<par name="parameter1" value="64" />
+<par name="parameter2" value="64" />
+<par name="parameter3" value="0" />
+</HARMONIC_POSITION>
+<SAMPLE_QUALITY>
+<par name="samplesize" value="3" />
+<par name="basenote" value="4" />
+<par name="octaves" value="3" />
+<par name="samples_per_octave" value="2" />
+</SAMPLE_QUALITY>
+<AMPLITUDE_PARAMETERS>
+<par name="volume" value="90" />
+<par name="panning" value="64" />
+<par name="velocity_sensing" value="64" />
+<par name="punch_strength" value="0" />
+<par name="punch_time" value="60" />
+<par name="punch_stretch" value="64" />
+<par name="punch_velocity_sensing" value="72" />
+<AMPLITUDE_ENVELOPE>
+<par_bool name="free_mode" value="no" />
+<par name="env_points" value="4" />
+<par name="env_sustain" value="2" />
+<par name="env_stretch" value="64" />
+<par_bool name="forced_release" value="yes" />
+<par_bool name="linear_envelope" value="no" />
+<par name="A_dt" value="0" />
+<par name="D_dt" value="40" />
+<par name="R_dt" value="25" />
+<par name="A_val" value="64" />
+<par name="D_val" value="64" />
+<par name="S_val" value="127" />
+<par name="R_val" value="64" />
+</AMPLITUDE_ENVELOPE>
+<AMPLITUDE_LFO>
+<par_real name="freq" value="0.629921" />
+<par name="intensity" value="24" />
+<par name="start_phase" value="64" />
+<par name="lfo_type" value="0" />
+<par name="randomness_amplitude" value="0" />
+<par name="randomness_frequency" value="0" />
+<par name="delay" value="0" />
+<par name="stretch" value="64" />
+<par_bool name="continous" value="no" />
+</AMPLITUDE_LFO>
+</AMPLITUDE_PARAMETERS>
+<FREQUENCY_PARAMETERS>
+<par name="fixed_freq" value="0" />
+<par name="fixed_freq_et" value="0" />
+<par name="detune" value="8192" />
+<par name="coarse_detune" value="0" />
+<par name="detune_type" value="1" />
+<FREQUENCY_ENVELOPE>
+<par_bool name="free_mode" value="no" />
+<par name="env_points" value="3" />
+<par name="env_sustain" value="1" />
+<par name="env_stretch" value="0" />
+<par_bool name="forced_release" value="no" />
+<par_bool name="linear_envelope" value="no" />
+<par name="A_dt" value="50" />
+<par name="D_dt" value="10" />
+<par name="R_dt" value="60" />
+<par name="A_val" value="64" />
+<par name="D_val" value="64" />
+<par name="S_val" value="64" />
+<par name="R_val" value="64" />
+</FREQUENCY_ENVELOPE>
+<FREQUENCY_LFO>
+<par_real name="freq" value="0.551181" />
+<par name="intensity" value="0" />
+<par name="start_phase" value="64" />
+<par name="lfo_type" value="0" />
+<par name="randomness_amplitude" value="0" />
+<par name="randomness_frequency" value="0" />
+<par name="delay" value="0" />
+<par name="stretch" value="64" />
+<par_bool name="continous" value="no" />
+</FREQUENCY_LFO>
+</FREQUENCY_PARAMETERS>
+<FILTER_PARAMETERS>
+<par name="velocity_sensing_amplitude" value="64" />
+<par name="velocity_sensing" value="64" />
+<FILTER>
+<par name="category" value="0" />
+<par name="type" value="2" />
+<par name="freq" value="111" />
+<par name="q" value="95" />
+<par name="stages" value="0" />
+<par name="freq_track" value="64" />
+<par name="gain" value="64" />
+</FILTER>
+<FILTER_ENVELOPE>
+<par_bool name="free_mode" value="no" />
+<par name="env_points" value="4" />
+<par name="env_sustain" value="2" />
+<par name="env_stretch" value="0" />
+<par_bool name="forced_release" value="yes" />
+<par_bool name="linear_envelope" value="no" />
+<par name="A_dt" value="40" />
+<par name="D_dt" value="70" />
+<par name="R_dt" value="60" />
+<par name="A_val" value="64" />
+<par name="D_val" value="64" />
+<par name="S_val" value="64" />
+<par name="R_val" value="64" />
+</FILTER_ENVELOPE>
+<FILTER_LFO>
+<par_real name="freq" value="0.629921" />
+<par name="intensity" value="0" />
+<par name="start_phase" value="64" />
+<par name="lfo_type" value="0" />
+<par name="randomness_amplitude" value="0" />
+<par name="randomness_frequency" value="0" />
+<par name="delay" value="0" />
+<par name="stretch" value="64" />
+<par_bool name="continous" value="no" />
+</FILTER_LFO>
+</FILTER_PARAMETERS>
+</PAD_SYNTH_PARAMETERS>
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="1">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="2">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="3">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="4">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="5">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="6">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="7">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="8">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="9">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="10">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="11">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="12">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="13">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="14">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+<INSTRUMENT_KIT_ITEM id="15">
+<par_bool name="enabled" value="no" />
+</INSTRUMENT_KIT_ITEM>
+</INSTRUMENT_KIT>
+<INSTRUMENT_EFFECTS>
+<INSTRUMENT_EFFECT id="0">
+<EFFECT>
+<par name="type" value="0" />
+</EFFECT>
+<par name="route" value="0" />
+<par_bool name="bypass" value="no" />
+</INSTRUMENT_EFFECT>
+<INSTRUMENT_EFFECT id="1">
+<EFFECT>
+<par name="type" value="0" />
+</EFFECT>
+<par name="route" value="0" />
+<par_bool name="bypass" value="no" />
+</INSTRUMENT_EFFECT>
+<INSTRUMENT_EFFECT id="2">
+<EFFECT>
+<par name="type" value="0" />
+</EFFECT>
+<par name="route" value="0" />
+<par_bool name="bypass" value="no" />
+</INSTRUMENT_EFFECT>
+</INSTRUMENT_EFFECTS>
+</INSTRUMENT>
+<CONTROLLER>
+<par name="pitchwheel_bendrange" value="200" />
+<par_bool name="expression_receive" value="yes" />
+<par name="panning_depth" value="64" />
+<par name="filter_cutoff_depth" value="64" />
+<par name="filter_q_depth" value="64" />
+<par name="bandwidth_depth" value="64" />
+<par name="mod_wheel_depth" value="80" />
+<par_bool name="mod_wheel_exponential" value="no" />
+<par_bool name="fm_amp_receive" value="yes" />
+<par_bool name="volume_receive" value="yes" />
+<par_bool name="sustain_receive" value="yes" />
+<par_bool name="portamento_receive" value="yes" />
+<par name="portamento_time" value="64" />
+<par name="portamento_pitchthresh" value="3" />
+<par name="portamento_pitchthreshtype" value="1" />
+<par name="portamento_portamento" value="0" />
+<par name="portamento_updowntimestretch" value="64" />
+<par name="portamento_proportional" value="0" />
+<par name="portamento_proprate" value="80" />
+<par name="portamento_propdepth" value="90" />
+<par name="resonance_center_depth" value="64" />
+<par name="resonance_bandwidth_depth" value="64" />
+</CONTROLLER>
+</PART>
+<PART id="3">
+<par_bool name="enabled" value="no" />
+</PART>
+<PART id="4">
+<par_bool name="enabled" value="no" />
+</PART>
+<PART id="5">
+<par_bool name="enabled" value="no" />
+</PART>
+<PART id="6">
+<par_bool name="enabled" value="no" />
+</PART>
+<PART id="7">
+<par_bool name="enabled" value="no" />
+</PART>
+<PART id="8">
+<par_bool name="enabled" value="no" />
+</PART>
+<PART id="9">
+<par_bool name="enabled" value="no" />
+</PART>
+<PART id="10">
+<par_bool name="enabled" value="no" />
+</PART>
+<PART id="11">
+<par_bool name="enabled" value="no" />
+</PART>
+<PART id="12">
+<par_bool name="enabled" value="no" />
+</PART>
+<PART id="13">
+<par_bool name="enabled" value="no" />
+</PART>
+<PART id="14">
+<par_bool name="enabled" value="no" />
+</PART>
+<PART id="15">
+<par_bool name="enabled" value="no" />
+</PART>
+<SYSTEM_EFFECTS>
+<SYSTEM_EFFECT id="0">
+<EFFECT>
+<par name="type" value="0" />
+</EFFECT>
+<VOLUME id="0">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="1">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="2">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="3">
+<par name="vol" value="64" />
+</VOLUME>
+<VOLUME id="4">
+<par name="vol" value="64" />
+</VOLUME>
+<VOLUME id="5">
+<par name="vol" value="64" />
+</VOLUME>
+<VOLUME id="6">
+<par name="vol" value="64" />
+</VOLUME>
+<VOLUME id="7">
+<par name="vol" value="64" />
+</VOLUME>
+<VOLUME id="8">
+<par name="vol" value="64" />
+</VOLUME>
+<VOLUME id="9">
+<par name="vol" value="64" />
+</VOLUME>
+<VOLUME id="10">
+<par name="vol" value="64" />
+</VOLUME>
+<VOLUME id="11">
+<par name="vol" value="64" />
+</VOLUME>
+<VOLUME id="12">
+<par name="vol" value="64" />
+</VOLUME>
+<VOLUME id="13">
+<par name="vol" value="64" />
+</VOLUME>
+<VOLUME id="14">
+<par name="vol" value="64" />
+</VOLUME>
+<VOLUME id="15">
+<par name="vol" value="64" />
+</VOLUME>
+<SENDTO id="1">
+<par name="send_vol" value="0" />
+</SENDTO>
+<SENDTO id="2">
+<par name="send_vol" value="0" />
+</SENDTO>
+<SENDTO id="3">
+<par name="send_vol" value="0" />
+</SENDTO>
+</SYSTEM_EFFECT>
+<SYSTEM_EFFECT id="1">
+<EFFECT>
+<par name="type" value="0" />
+</EFFECT>
+<VOLUME id="0">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="1">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="2">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="3">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="4">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="5">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="6">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="7">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="8">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="9">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="10">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="11">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="12">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="13">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="14">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="15">
+<par name="vol" value="0" />
+</VOLUME>
+<SENDTO id="2">
+<par name="send_vol" value="0" />
+</SENDTO>
+<SENDTO id="3">
+<par name="send_vol" value="0" />
+</SENDTO>
+</SYSTEM_EFFECT>
+<SYSTEM_EFFECT id="2">
+<EFFECT>
+<par name="type" value="0" />
+</EFFECT>
+<VOLUME id="0">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="1">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="2">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="3">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="4">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="5">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="6">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="7">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="8">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="9">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="10">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="11">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="12">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="13">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="14">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="15">
+<par name="vol" value="0" />
+</VOLUME>
+<SENDTO id="3">
+<par name="send_vol" value="0" />
+</SENDTO>
+</SYSTEM_EFFECT>
+<SYSTEM_EFFECT id="3">
+<EFFECT>
+<par name="type" value="0" />
+</EFFECT>
+<VOLUME id="0">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="1">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="2">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="3">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="4">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="5">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="6">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="7">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="8">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="9">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="10">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="11">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="12">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="13">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="14">
+<par name="vol" value="0" />
+</VOLUME>
+<VOLUME id="15">
+<par name="vol" value="0" />
+</VOLUME>
+</SYSTEM_EFFECT>
+</SYSTEM_EFFECTS>
+<INSERTION_EFFECTS>
+<INSERTION_EFFECT id="0">
+<par name="part" value="-1" />
+<EFFECT>
+<par name="type" value="0" />
+</EFFECT>
+</INSERTION_EFFECT>
+<INSERTION_EFFECT id="1">
+<par name="part" value="-1" />
+<EFFECT>
+<par name="type" value="0" />
+</EFFECT>
+</INSERTION_EFFECT>
+<INSERTION_EFFECT id="2">
+<par name="part" value="-1" />
+<EFFECT>
+<par name="type" value="0" />
+</EFFECT>
+</INSERTION_EFFECT>
+<INSERTION_EFFECT id="3">
+<par name="part" value="-1" />
+<EFFECT>
+<par name="type" value="0" />
+</EFFECT>
+</INSERTION_EFFECT>
+<INSERTION_EFFECT id="4">
+<par name="part" value="-1" />
+<EFFECT>
+<par name="type" value="0" />
+</EFFECT>
+</INSERTION_EFFECT>
+<INSERTION_EFFECT id="5">
+<par name="part" value="-1" />
+<EFFECT>
+<par name="type" value="0" />
+</EFFECT>
+</INSERTION_EFFECT>
+<INSERTION_EFFECT id="6">
+<par name="part" value="-1" />
+<EFFECT>
+<par name="type" value="0" />
+</EFFECT>
+</INSERTION_EFFECT>
+<INSERTION_EFFECT id="7">
+<par name="part" value="-1" />
+<EFFECT>
+<par name="type" value="0" />
+</EFFECT>
+</INSERTION_EFFECT>
+</INSERTION_EFFECTS>
+</MASTER>
+</ZynAddSubFX-data>
diff --git a/src/Tests/make.sh b/src/Tests/make.sh
deleted file mode 100755
index 841a7ab..0000000
--- a/src/Tests/make.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-cd ../
-make
-cd Tests
-cxxtestgen.py --error-printer -o runner.cpp SampleTest.h EchoTest.h
-g++ -g -o runner runner.cpp ../Samples/AuSample.o ../Samples/Sample.o ../Effects/Echo.o ../Effects/Effect.o ../Controls/Control.o ../Controls/DelayCtl.o 
diff --git a/src/UI/ADnoteUI.fl b/src/UI/ADnoteUI.fl
index 4888eae..748156c 100644
--- a/src/UI/ADnoteUI.fl
+++ b/src/UI/ADnoteUI.fl
@@ -1,5 +1,5 @@
 # data file for the Fltk User Interface Designer (fluid)
-version 1.0107 
+version 1.0109 
 header_name {.h} 
 code_name {.cc}
 decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} 
@@ -178,19 +178,19 @@ class ADvoiceUI {open : {public Fl_Group}
   } {
     Fl_Window ADnoteVoiceParameters {
       label Voice
-      xywh {225 174 765 525} type Double hide
-      class Fl_Group
+      xywh {69 185 765 575} type Double
+      class Fl_Group visible
     } {
-      Fl_Group voiceparametersgroup {
-        xywh {0 0 765 525} box THIN_UP_BOX color 48
+      Fl_Group voiceparametersgroup {open
+        xywh {0 0 765 580} box THIN_UP_BOX color 48
         code0 {if (pars->VoicePar[nvoice].Enabled==0) o->deactivate();}
       } {
-        Fl_Group voicemodegroup {
-          xywh {0 5 760 515}
+        Fl_Group voicemodegroup {open
+          xywh {0 5 760 575}
         } {
           Fl_Group voiceFMparametersgroup {
             label MODULATOR
-            xywh {530 5 230 515} box THIN_UP_FRAME color 48 labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 17
+            xywh {530 5 230 565} box THIN_UP_FRAME color 48 labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 17
             code0 {if (pars->VoicePar[nvoice].PFMEnabled==0) o->deactivate();}
           } {
             Fl_Group modfrequency {
@@ -209,7 +209,7 @@ class ADvoiceUI {open : {public Fl_Group}
                 callback {pars->VoicePar[nvoice].PFMFreqEnvelopeEnabled=(int)o->value();
 if (o->value()==0) voiceFMfreqenvgroup->deactivate();
 else voiceFMfreqenvgroup->activate();
-o->redraw();} selected
+o->redraw();}
                 tooltip {Forced Relase} xywh {545 295 50 10} down_box DOWN_BOX labelfont 1 labelsize 10
                 code0 {o->value(pars->VoicePar[nvoice].PFMFreqEnvelopeEnabled);}
               }
@@ -298,10 +298,10 @@ o->redraw();}
               }
             }
             Fl_Group modoscil {
-              xywh {535 365 220 150}
+              xywh {535 365 220 200}
             } {
               Fl_Group fmoscil {open
-                xywh {535 405 220 110} box THIN_DOWN_BOX color 32 selection_color 71 labelcolor 179
+                xywh {535 425 220 140} box THIN_DOWN_BOX color 32 selection_color 71 labelcolor 179
                 code0 {oscFM=new Oscilloscope(o->x(),o->y(),o->w(),o->h(),"");}
                 code1 {int nv=nvoice; if (pars->VoicePar[nvoice].PextFMoscil>=0) nv=pars->VoicePar[nvoice].PextFMoscil;}
                 code2 {oscFM->init(pars->VoicePar[nv].FMSmp,0,pars->VoicePar[nvoice].PFMoscilphase,master);}
@@ -326,7 +326,7 @@ oscedit=new OscilEditor(pars->VoicePar[nv].FMSmp,fmoscil,NULL,NULL,master);}
                 callback {pars->VoicePar[nvoice].PFMoscilphase=64-(int)o->value();
 oscFM->phase=64-(int) o->value();
 fmoscil->redraw();}
-                xywh {665 395 65 10} type {Horz Knob} box FLAT_BOX labelsize 10 align 5 minimum -64 maximum 63 step 1
+                xywh {665 400 65 10} type {Horz Knob} box FLAT_BOX labelsize 10 align 5 minimum -64 maximum 63 step 1
                 code0 {o->value(64-pars->VoicePar[nvoice].PFMoscilphase);}
               }
               Fl_Choice {} {
@@ -340,7 +340,7 @@ if ((int) o->value() != 0) {
     changeFMoscilbutton->labelcolor(FL_BLACK);
 };
 voiceFMparametersgroup->redraw();} open
-                xywh {560 390 75 15} down_box BORDER_BOX labelsize 10 textfont 1 textsize 10
+                xywh {560 395 75 15} down_box BORDER_BOX labelsize 10 textfont 1 textsize 10
                 code0 {o->add("Internal");}
                 code1 {char tmp[50]; for (int i=0;i<nvoice;i++) {sprintf(tmp,"ExtM.%2d",i+1);o->add(tmp);};}
                 code3 {o->value(pars->VoicePar[nvoice].PextFMoscil+1);}
@@ -548,6 +548,58 @@ voiceonbutton->redraw();} open
             code1 {char tmp[50]; for (int i=0;i<nvoice;i++) {sprintf(tmp,"Ext.%2d",i+1);o->add(tmp);};}
             code3 {o->value(pars->VoicePar[nvoice].Pextoscil+1);}
           } {}
+          Fl_Group {} {open
+            xywh {5 525 515 45} box ENGRAVED_BOX
+          } {
+            Fl_Dial {} {
+              label Stereo
+              callback {pars->VoicePar[nvoice].Unison_stereo_spread=(int)o->value();}
+              tooltip {Stereo Spread} xywh {285 540 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1
+              code0 {o->value(pars->VoicePar[nvoice].Unison_stereo_spread);}
+              class WidgetPDial
+            }
+            Fl_Choice {} {
+              label Unison
+              callback {pars->set_unison_size_index(nvoice,(int) o->value());} open selected
+              tooltip {Unison size} xywh {10 545 75 20} down_box BORDER_BOX labelfont 1 align 5 textfont 1 textsize 10
+              code0 {o->add("OFF");char tmp[100];for (int i=1;ADnote_unison_sizes[i];i++){snprintf(tmp,100,"size %d",ADnote_unison_sizes[i]);o->add(tmp);};}
+              code1 {o->value(pars->get_unison_size_index(nvoice));}
+            } {}
+            Fl_Dial {} {
+              label Vibratto
+              callback {pars->VoicePar[nvoice].Unison_vibratto=(int)o->value();}
+              tooltip Vibratto xywh {340 540 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1
+              code0 {o->value(pars->VoicePar[nvoice].Unison_vibratto);}
+              class WidgetPDial
+            }
+            Fl_Choice {} {
+              label Invert
+              callback {pars->VoicePar[nvoice].Unison_invert_phase=(int) o->value();} open
+              tooltip {Phase Invert} xywh {445 545 65 15} down_box BORDER_BOX labelsize 11 align 5 textfont 1 textsize 10
+              code0 {o->add("None");o->add("Random");char tmp[100];for (int i=2;i<=5;i++){snprintf(tmp,100,"%d %%",100/i);o->add(tmp);};}
+              code1 {o->value(pars->VoicePar[nvoice].Unison_invert_phase);}
+            } {}
+            Fl_Slider {} {
+              label {Frequency Spread}
+              callback {pars->VoicePar[nvoice].Unison_frequency_spread=(int)o->value();
+unisonspreadoutput->do_callback();}
+              tooltip {Frequency Spread of the Unison} xywh {95 547 125 13} type {Horz Knob} box FLAT_BOX labelsize 12 align 1 maximum 127 step 1 value 64
+              code0 {o->value(pars->VoicePar[nvoice].Unison_frequency_spread);}
+            }
+            Fl_Value_Output unisonspreadoutput {
+              label {(cents)}
+              callback {o->value(pars->getUnisonFrequencySpreadCents(nvoice));}
+              xywh {225 545 40 15} labelsize 10 align 5 maximum 1000 step 0.1 textfont 1 textsize 10
+              code0 {o->value(pars->getUnisonFrequencySpreadCents(nvoice));}
+            }
+            Fl_Dial {} {
+              label {Vib.speed}
+              callback {pars->VoicePar[nvoice].Unison_vibratto_speed=(int)o->value();}
+              tooltip {Vibratto Average Speed} xywh {390 540 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1
+              code0 {o->value(pars->VoicePar[nvoice].Unison_vibratto_speed);}
+              class WidgetPDial
+            }
+          }
         }
         Fl_Group {} {
           label AMPLITUDE
@@ -728,7 +780,8 @@ o->redraw();}
 pars=NULL;
 oscedit=NULL;} {}
   }
-  Function {init(ADnoteParameters *parameters,int nvoice_,Master *master_)} {} {
+  Function {init(ADnoteParameters *parameters,int nvoice_,Master *master_)} {open
+  } {
     code {pars=parameters;
 nvoice=nvoice_;
 master=master_;
@@ -752,7 +805,7 @@ if (oscedit!=NULL) {
   decl {Master *master;} {}
 } 
 
-class ADnoteUI {: {public PresetsUI_}
+class ADnoteUI {open : {public PresetsUI_}
 } {
   Function {make_window()} {open private
   } {
@@ -967,10 +1020,10 @@ resui->resonancewindow->show();}
     }
     Fl_Window ADnoteVoice {
       label {ADsynth Voice Parameters}
-      xywh {53 58 765 560} type Double hide
+      xywh {152 271 765 620} type Double visible
     } {
       Fl_Group advoice {
-        xywh {0 0 760 525} box BORDER_BOX
+        xywh {0 0 760 575} box BORDER_BOX
         code0 {o->init(pars,nvoice,master);}
         code1 {o->show();}
         class ADvoiceUI
@@ -978,7 +1031,7 @@ resui->resonancewindow->show();}
       Fl_Button {} {
         label {Close Window}
         callback {ADnoteVoice->hide();}
-        xywh {300 530 195 25} box THIN_UP_BOX labelfont 1
+        xywh {300 585 195 25} box THIN_UP_BOX labelfont 1
       }
       Fl_Counter currentvoicecounter {
         label {Current Voice}
@@ -986,23 +1039,23 @@ resui->resonancewindow->show();}
 advoice->hide();
 ADnoteVoice->remove(advoice);
 delete advoice;
-advoice=new ADvoiceUI(0,0,765,525);
+advoice=new ADvoiceUI(0,0,765,585);
 ADnoteVoice->add(advoice);
 advoice->init(pars,nvoice,master);
 advoice->show();
 ADnoteVoice->redraw();}
-        xywh {5 530 130 25} type Simple labelfont 1 align 8 minimum 0 maximum 2 step 1 value 1 textfont 1 textsize 13
+        xywh {5 585 130 25} type Simple labelfont 1 align 8 minimum 0 maximum 2 step 1 value 1 textfont 1 textsize 13
         code0 {o->bounds(1,NUM_VOICES);}
       }
       Fl_Button {} {
         label C
         callback {presetsui->copy(pars,nvoice);}
-        xywh {700 535 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7
+        xywh {700 590 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7
       }
       Fl_Button {} {
         label P
         callback {presetsui->paste(pars,this,nvoice);}
-        xywh {730 535 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7
+        xywh {730 590 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7
       }
     }
     Fl_Window ADnoteVoiceList {
diff --git a/src/UI/BankUI.fl b/src/UI/BankUI.fl
index 7aa8e7e..d54cbef 100644
--- a/src/UI/BankUI.fl
+++ b/src/UI/BankUI.fl
@@ -1,5 +1,5 @@
 # data file for the Fltk User Interface Designer (fluid)
-version 1.0107 
+version 1.0110 
 header_name {.h} 
 code_name {.cc}
 decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} 
@@ -24,20 +24,28 @@ decl {\#include <FL/Fl_File_Chooser.H>} {public
 decl {\#include "../Misc/Master.h"} {public
 } 
 
+decl {\#include "../Misc/Part.h"} {selected public
+} 
+
 decl {\#include "../Misc/Bank.h"} {public
 } 
 
 decl {\#include "../Misc/Config.h"} {public
 } 
 
+decl {\#include "../Misc/Util.h"} {public
+} 
+
 class BankProcess_ {} {
   Function {process()} {open return_type {virtual void}
-  } {}
+  } {
+    code {;} {}
+  }
   decl {Bank *bank;} {public
   }
 } 
 
-class BankSlot {open : {public Fl_Button,BankProcess_}
+class BankSlot {: {public Fl_Button,BankProcess_}
 } {
   Function {BankSlot(int x,int y, int w, int h, const char *label=0):Fl_Button(x,y,w,h,label)} {} {
     code {what=NULL;
@@ -59,8 +67,7 @@ int tmp=Fl_Button::handle(event);
 if ((*what!=0) && Fl::event_inside(this)) (bp->*fnc)();
 return(tmp);} {}
   }
-  Function {init(int nslot_, int *what_, int *whatslot_,void (BankProcess_:: *fnc_)(void),BankProcess_ *bp_,Bank *bank_,int *nselected_)} {open
-  } {
+  Function {init(int nslot_, int *what_, int *whatslot_,void (BankProcess_:: *fnc_)(void),BankProcess_ *bp_,Bank *bank_,int *nselected_)} {} {
     code {nslot=nslot_;
 what=what_;
 whatslot=whatslot_;
@@ -74,21 +81,22 @@ labelsize(13);
 align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_CLIP);
 
 highlight=0;
-refresh();} {selected
-    }
+refresh();} {}
   }
   Function {refresh()} {} {
-    code {if (bank->emptyslot(nslot)) {
-	color(46);
-} else {
-	if (bank->isPADsynth_used(nslot)) color(26);
-		else color(51);
-};
+    code {if (bank->emptyslot(nslot))
+    color(46);
+else if (bank->isPADsynth_used(nslot)) 
+    color(26);
+else 
+    color(51);
+
 
-if (*nselected==nslot) color(6);
+if (*nselected==nslot) 
+    color(6);
 
 
-label(bank->getnamenumbered(nslot));} {}
+copy_label(bank->getnamenumbered(nslot).c_str());} {}
   }
   decl {int *what,*whatslot,nslot,highlight, *nselected;} {}
   decl {void (BankProcess_:: *fnc)(void);} {}
@@ -100,9 +108,9 @@ class BankUI {: {public BankProcess_}
   Function {make_window()} {} {
     Fl_Window bankuiwindow {
       label Bank
-      xywh {4 64 785 575} type Double hide
-      code0 {o->label(bank->bankfiletitle);}
-      code1 {if (bank->bankfiletitle==NULL) o->label ("Choose a bank from the bank list on the left (or go to settings if to configure the bank location) or choose 'New Bank...' to make a new bank.");}
+      xywh {5 64 785 575} type Double hide
+      code0 {o->label(bank->bankfiletitle.c_str());}
+      code1 {if (bank->bankfiletitle.empty()) o->label ("Choose a bank from the bank list on the left (or go to settings if to configure the bank location) or choose 'New Bank...' to make a new bank.");}
     } {
       Fl_Button {} {
         label Close
@@ -193,13 +201,13 @@ refreshmainwindow();}
       }
       Fl_Choice banklist {
         callback {int n=o->value();
-char *dirname=bank->banks[n].dir;
-if (dirname==NULL) return;
+std::string dirname=bank->banks[n].dir;
+if (dirname.empty()) return;
 
 if (bank->loadbank(dirname)==2)
-       fl_alert("Error: Could not load the bank from the directory\\n%s.",dirname);
+       fl_alert("Error: Could not load the bank from the directory\\n%s.",dirname.c_str());
 for (int i=0;i<BANK_SIZE;i++) bs[i]->refresh();
-refreshmainwindow();} open
+refreshmainwindow();}
         xywh {5 8 220 20} down_box BORDER_BOX labelfont 1 align 0 textfont 1 textsize 11
       } {}
       Fl_Button {} {
@@ -248,17 +256,17 @@ rescan_for_banks();} {}
     code {int slot=this->slot;
 
 if ((what==2)&&(bank->emptyslot(slot)==0)&&(mode!=4)) {//Rename slot
-    const char *tmp=fl_input("Slot (instrument) name:",(const char *)bank->getname(slot));
+    const char *tmp=fl_input("Slot (instrument) name:",bank->getname(slot).c_str());
     if (tmp!=NULL) bank->setname(slot,tmp,-1);
     bs[slot]->refresh();
 };
 
 if ((what==1)&&(mode==1)&&(!bank->emptyslot(slot))){//Reads from slot
-    pthread_mutex_lock(&master->mutex);
+    pthread_mutex_lock(&master->part[*npart]->load_mutex);
      bank->loadfromslot(slot,master->part[*npart]);
-    pthread_mutex_unlock(&master->mutex);
+    pthread_mutex_unlock(&master->part[*npart]->load_mutex);
     master->part[*npart]->applyparameters();
-    snprintf((char *)master->part[*npart]->Pname,PART_MAX_NAME_LEN,"%s",bank->getname(slot));
+    snprintf((char *)master->part[*npart]->Pname,PART_MAX_NAME_LEN,"%s",bank->getname(slot).c_str());
      cbwig->do_callback();
      
      if (config.cfg.BankUIAutoClose!=0)
@@ -270,9 +278,9 @@ if ((what==1)&&(mode==2)){//save(write) to slot
      if (!bank->emptyslot(slot)){
        if (!fl_choice("Overwrite the slot no. %d ?","No","Yes",NULL,slot+1)) goto nooverwriteslot;
       };
-       pthread_mutex_lock(&master->mutex);
+       pthread_mutex_lock(&master->part[*npart]->load_mutex);
         bank->savetoslot(slot,master->part[*npart]);
-       pthread_mutex_unlock(&master->mutex);
+       pthread_mutex_unlock(&master->part[*npart]->load_mutex);
 
        bs[slot]->refresh();
        mode=1;readbutton->value(1);writebutton->value(0);
@@ -308,7 +316,7 @@ if (mode==4){//swap
 if (mode!=4) refreshmainwindow();} {}
   }
   Function {refreshmainwindow()} {} {
-    code {bankuiwindow->label(bank->bankfiletitle);
+    code {bankuiwindow->label(bank->bankfiletitle.c_str());
 mode=1;readbutton->value(1);writebutton->value(0);clearbutton->value(0);swapbutton->value(0);
 nselected=-1;
 if (bank->locked()){
@@ -320,7 +328,8 @@ if (bank->locked()){
     clearbutton->activate();
     swapbutton->activate();
 };
-for (int i=0;i<BANK_SIZE;i++) bs[i]->refresh();} {}
+for (int i=0;i<BANK_SIZE;i++) 
+   bs[i]->refresh();} {}
   }
   Function {removeselection()} {} {
     code {if (nselected>=0) {
@@ -331,12 +340,14 @@ for (int i=0;i<BANK_SIZE;i++) bs[i]->refresh();} {}
   }
   Function {rescan_for_banks()} {} {
     code {banklist->clear();
-banklist->add(" ");
 bank->rescanforbanks();
 
-for (int i=1;i<MAX_NUM_BANKS;i++) {
-    if (bank->banks[i].name!=NULL) banklist->add(bank->banks[i].name);
-};} {}
+for (unsigned int i=0;i<bank->banks.size();i++) {
+     banklist->add(bank->banks[i].name.c_str());
+}
+if (banklist->size() == 0)
+     banklist->add(" ");
+} {}
   }
   Function {simplesetmode(bool beginnerui)} {} {
     code {readbutton->value(1);
diff --git a/src/UI/CMakeLists.txt b/src/UI/CMakeLists.txt
new file mode 100644
index 0000000..aa6aeb7
--- /dev/null
+++ b/src/UI/CMakeLists.txt
@@ -0,0 +1,36 @@
+set(UI_fl_files
+    ADnoteUI.fl
+    BankUI.fl
+    ConfigUI.fl
+    EffUI.fl
+    EnvelopeUI.fl
+    FilterUI.fl
+    LFOUI.fl
+    MasterUI.fl
+    MicrotonalUI.fl
+    OscilGenUI.fl
+    PADnoteUI.fl
+    PartUI.fl
+    PresetsUI.fl
+    ResonanceUI.fl
+    SUBnoteUI.fl
+    VirKeyboard.fl
+)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+set_source_files_properties(UI/MasterUI.h PROPERTIES GENERATED 1)
+fltk_wrap_ui(zynaddsubfx_gui ${UI_fl_files})
+
+if(LibloEnable)
+    set(zynaddsubfx_gui_FLTK_UI_SRCS ${zynaddsubfx_gui_FLTK_UI_SRCS} NSM.C NSM/Client.C)
+endif()
+
+add_library(zynaddsubfx_gui STATIC
+	${UI_objs}
+	${zynaddsubfx_gui_FLTK_UI_SRCS}
+        NioUI.cpp
+        WidgetPDial.cpp
+	)
+
+target_link_libraries(zynaddsubfx_gui ${FLTK_LIBRARIES} ${MYFLTK_LIBRARIES})
diff --git a/src/UI/ConfigUI.fl b/src/UI/ConfigUI.fl
index a17872f..b1437e1 100644
--- a/src/UI/ConfigUI.fl
+++ b/src/UI/ConfigUI.fl
@@ -1,5 +1,5 @@
 # data file for the Fltk User Interface Designer (fluid)
-version 1.0106 
+version 1.0107 
 header_name {.h} 
 code_name {.cc}
 decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} 
@@ -60,35 +60,35 @@ setsamplerateinput();}
               xywh {20 50 85 20} down_box BORDER_BOX textsize 10
               code0 {o->value(getsamplerateorder());}
             } {
-              menuitem {} {
+              MenuItem {} {
                 label Custom
                 xywh {10 10 100 20} labelfont 1
               }
-              menuitem {} {
+              MenuItem {} {
                 label 16000Hz
                 xywh {30 30 100 20} labelfont 1
               }
-              menuitem {} {
+              MenuItem {} {
                 label 22050Hz
                 xywh {20 20 100 20} labelfont 1
               }
-              menuitem {} {
+              MenuItem {} {
                 label 32000Hz
                 xywh {30 30 100 20} labelfont 1
               }
-              menuitem {} {
+              MenuItem {} {
                 label 44100Hz
                 xywh {40 40 100 20} labelfont 1
               }
-              menuitem {} {
+              MenuItem {} {
                 label 48000Hz
                 xywh {50 50 100 20} labelfont 1
               }
-              menuitem {} {
+              MenuItem {} {
                 label 88200Hz
                 xywh {60 60 100 20} labelfont 1
               }
-              menuitem {} {
+              MenuItem {} {
                 label 96000Hz
                 xywh {70 70 100 20} labelfont 1
               }
@@ -122,35 +122,35 @@ config.cfg.SoundBufferSize=strtoul(o->value(),&tmp,10);}
             tooltip {ADSynth Oscillator Size (samples)} xywh {175 80 75 20} down_box BORDER_BOX labelfont 1 labelsize 11 textsize 10
             code0 {o->value( (int) (log(config.cfg.OscilSize/128.0-1.0)/log(2)) +1);}
           } {
-            menuitem {} {
+            MenuItem {} {
               label 128
               xywh {25 25 100 20} labelfont 1
             }
-            menuitem {} {
+            MenuItem {} {
               label 256
               xywh {35 35 100 20} labelfont 1
             }
-            menuitem {} {
+            MenuItem {} {
               label 512
               xywh {45 45 100 20} labelfont 1
             }
-            menuitem {} {
+            MenuItem {} {
               label 1024
               xywh {45 45 100 20} labelfont 1
             }
-            menuitem {} {
+            MenuItem {} {
               label 2048
               xywh {55 55 100 20} labelfont 1
             }
-            menuitem {} {
+            MenuItem {} {
               label 4096
               xywh {55 55 100 20} labelfont 1
             }
-            menuitem {} {
+            MenuItem {} {
               label 8192
               xywh {65 65 100 20} labelfont 1
             }
-            menuitem {} {
+            MenuItem {} {
               label 16384
               xywh {75 75 100 20} labelfont 1
             }
@@ -168,9 +168,9 @@ config.cfg.SoundBufferSize=strtoul(o->value(),&tmp,10);}
           } {
             Fl_File_Input {} {
               label {Dump File}
-              callback {snprintf(config.cfg.DumpFile,config.maxstringsize,"%s",o->value());}
+              callback {config.cfg.DumpFile = o->value();} selected
               xywh {20 170 220 35} align 5
-              code0 {o->insert(config.cfg.DumpFile);}
+              code0 {o->insert(config.cfg.DumpFile.c_str());}
             }
             Fl_Check_Button {} {
               label {Dump notes}
@@ -241,37 +241,41 @@ midiinputnamebox->label(config.winmididevices[config.cfg.WindowsMidiInId].name);
             xywh {175 105 75 15} down_box BORDER_BOX labelsize 10 textsize 11
             code0 {o->value(config.cfg.Interpolation);}
           } {
-            menuitem {} {
+            MenuItem {} {
               label {Linear(fast)}
               xywh {0 0 100 20} labelfont 1 labelsize 10
             }
-            menuitem {} {
+            MenuItem {} {
               label {Cubic(slow)}
               xywh {10 10 100 20} labelfont 1 labelsize 10
             }
           }
           Fl_Choice {} {
             label {Virtual Keyboard Layout}
-            callback {config.cfg.VirKeybLayout=(int) o->value();;} open selected
+            callback {config.cfg.VirKeybLayout=(int) o->value();;}
             xywh {155 235 85 20} down_box BORDER_BOX labelsize 12 textfont 1 textsize 11
             code0 {o->value(config.cfg.VirKeybLayout);}
           } {
-            menuitem {} {
+            MenuItem {} {
               label { }
               xywh {5 5 100 20} labelfont 1 labelsize 11 deactivate
             }
-            menuitem {} {
+            MenuItem {} {
               label QWERTY
               xywh {15 15 100 20} labelfont 1 labelsize 11
             }
-            menuitem {} {
+            MenuItem {} {
               label Dvorak
               xywh {25 25 100 20} labelfont 1 labelsize 11
             }
-            menuitem {} {
+            MenuItem {} {
               label QWERTZ
               xywh {35 35 100 20} labelfont 1 labelsize 11
             }
+            MenuItem {} {
+              label AZERTY
+              xywh {45 45 100 20} labelfont 1 labelsize 11
+            }
           }
         }
         Fl_Group {} {
@@ -391,31 +395,30 @@ readpresetcfg();} {}
     code {rootsbrowse->clear();
 
 for (int i=0;i<MAX_BANK_ROOT_DIRS;i++){
-  if (config.cfg.bankRootDirList[i]!=NULL) rootsbrowse->add(config.cfg.bankRootDirList[i]);
+  if (!config.cfg.bankRootDirList[i].empty())
+    rootsbrowse->add(config.cfg.bankRootDirList[i].c_str());
 };} {}
   }
   Function {writebankcfg()} {} {
     code {config.clearbankrootdirlist();
 
 for (int n=0;n<rootsbrowse->size();n++){ 
-     config.cfg.bankRootDirList[n]=new char [MAX_STRING_SIZE];
-     strncpy(config.cfg.bankRootDirList[n],rootsbrowse->text(n+1),MAX_STRING_SIZE);
+     config.cfg.bankRootDirList[n] = rootsbrowse->text(n+1);
 };} {}
   }
   Function {readpresetcfg()} {} {
     code {presetbrowse->clear();
 
-for (int i=0;i<MAX_BANK_ROOT_DIRS;i++){
-  if (config.cfg.presetsDirList[i]!=NULL) presetbrowse->add(config.cfg.presetsDirList[i]);
+for(int i=0;i<MAX_BANK_ROOT_DIRS;i++){
+  if(!config.cfg.presetsDirList[i].empty())
+   presetbrowse->add(config.cfg.presetsDirList[i].c_str());
 };} {}
   }
   Function {writepresetcfg()} {} {
     code {config.clearpresetsdirlist();
 
-for (int n=0;n<presetbrowse->size();n++){ 
-     config.cfg.presetsDirList[n]=new char [MAX_STRING_SIZE];
-     strncpy(config.cfg.presetsDirList[n],presetbrowse->text(n+1),MAX_STRING_SIZE);
-};} {}
+for (int n=0;n<presetbrowse->size();n++)
+     config.cfg.presetsDirList[n] = presetbrowse->text(n+1);} {}
   }
   Function {getsamplerateorder()} {return_type int
   } {
diff --git a/src/UI/EffUI.fl b/src/UI/EffUI.fl
index e2712f1..340cc89 100644
--- a/src/UI/EffUI.fl
+++ b/src/UI/EffUI.fl
@@ -36,7 +36,7 @@ decl {\#include "../Effects/EffectMgr.h"} {public
 decl {\#include "PresetsUI.h"} {public
 } 
 
-class EQGraph {selected : {public Fl_Box}
+class EQGraph {: {public Fl_Box}
 } {
   Function {EQGraph(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} {
     code {eff=NULL;
@@ -47,9 +47,9 @@ maxdB=30;} {}
 oldx=-1;
 khzval=-1;} {}
   }
-  Function {draw_freq_line(REALTYPE freq,int type)} {} {
+  Function {draw_freq_line(float freq,int type)} {} {
     code {fl_color(FL_GRAY);
-REALTYPE freqx=getfreqpos(freq);
+float freqx=getfreqpos(freq);
 switch(type){
   case 0:if (active_r()) fl_color(FL_WHITE);
             else fl_color(205,205,205);
@@ -66,7 +66,7 @@ if ((freqx>0.0)&&(freqx<1.0))
   }
   Function {draw()} {} {
     code {int ox=x(),oy=y(),lx=w(),ly=h(),i,iy,oiy;
-REALTYPE freqx;
+float freqx;
 
 if (active_r()) fl_color(0,70,150);
        else fl_color(80,120,160);
@@ -107,7 +107,7 @@ draw_freq_line(20000.0,1);
 fl_line_style(FL_DOT);
 int GY=6;if (ly<GY*3) GY=-1;
 for (i=1;i<GY;i++){
-   int tmp=(int)(ly/(REALTYPE)GY*i);
+   int tmp=(int)(ly/(float)GY*i);
    fl_line(ox+2,oy+tmp,ox+lx-2,oy+tmp);
 };
 
@@ -118,8 +118,8 @@ if (active_r()) fl_color(FL_YELLOW);
 fl_line_style(FL_SOLID);
 oiy=getresponse(ly,getfreqx(0.0));
 for (i=1;i<lx;i++){
-   REALTYPE frq=getfreqx(i/(REALTYPE) lx);
-   if (frq>SAMPLE_RATE/2) break;
+   float frq=getfreqx(i/(float) lx);
+   if (frq>synth->samplerate/2) break;
    iy=getresponse(ly,frq);
    if ((oiy>=0) && (oiy<ly) &&
        (iy>=0) && (iy<ly) )
@@ -127,9 +127,9 @@ for (i=1;i<lx;i++){
    oiy=iy;
 };} {}
   }
-  Function {getresponse(int maxy,REALTYPE freq)} {return_type int
+  Function {getresponse(int maxy,float freq)} {return_type int
   } {
-    code {REALTYPE dbresp=eff->getEQfreqresponse(freq);
+    code {float dbresp=eff->getEQfreqresponse(freq);
 int idbresp=(int) ((dbresp/maxdB+1.0)*maxy/2.0);
 
 
@@ -138,18 +138,18 @@ int idbresp=(int) ((dbresp/maxdB+1.0)*maxy/2.0);
 
 return(idbresp);} {}
   }
-  Function {getfreqx(REALTYPE x)} {return_type REALTYPE
+  Function {getfreqx(float x)} {return_type float
   } {
     code {if (x>1.0) x=1.0;
-return(20.0*pow((REALTYPE)1000.0,x));} {}
+return(20.0*pow((float)1000.0,x));} {}
   }
-  Function {getfreqpos(REALTYPE freq)} {return_type REALTYPE
+  Function {getfreqpos(float freq)} {return_type float
   } {
     code {if (freq<0.00001) freq=0.00001;
 return(log(freq/20.0)/log(1000.0));} {}
   }
   decl {int oldx,oldy;} {}
-  decl {REALTYPE khzval;} {public
+  decl {float khzval;} {public
   }
   decl {EffectMgr *eff;} {}
   decl {int maxdB;} {}
@@ -179,7 +179,7 @@ if (filterwindow!=NULL){
   }
   Function {make_null_window()} {} {
     Fl_Window effnullwindow {
-      xywh {287 379 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide
+      xywh {216 539 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide
       class Fl_Group
     } {
       Fl_Text_Display {} {
@@ -259,8 +259,10 @@ refresh(eff);}
       }
       Fl_Choice revp10 {
         label Type
-        callback {eff->seteffectpar(10,(int) o->value());}
-        xywh {110 15 75 15} down_box BORDER_BOX color 14 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7
+        callback {eff->seteffectpar(10,(int) o->value());
+if (eff->geteffectpar(10)==2) revp12->activate();
+	else revp12->deactivate();}
+        xywh {110 15 85 15} down_box BORDER_BOX color 14 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7
       } {
         MenuItem {} {
           label Random
@@ -270,6 +272,10 @@ refresh(eff);}
           label Freeverb
           xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7
         }
+        MenuItem {} {
+          label Bandwidth
+          xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7
+        }
       }
       Fl_Dial revp0 {
         label Vol
@@ -301,10 +307,11 @@ refresh(eff);}
         tooltip {Initial Delay Feedback} xywh {155 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127
         class WidgetPDial
       }
-      Fl_Dial revp5 {
-        label {R.delay}
-        callback {eff->seteffectpar(5,(int) o->value());}
+      Fl_Dial revp12 {
+        label bw
+        callback {eff->seteffectpar(12,(int) o->value());}
         xywh {200 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 deactivate
+        code0 {if (eff->geteffectpar(10)==2) o->activate();}
         class WidgetPDial
       }
       Fl_Dial revp6 {
@@ -337,7 +344,7 @@ refresh(eff);}
 if (Fl::event_button1()) x=(int)o->value();
    else o->value(x);
 eff->seteffectpar(11,x);}
-        tooltip RoomSize xywh {190 10 25 25} box ROUND_UP_BOX labelfont 1 labelsize 8 align 8 minimum 1 maximum 127 step 1
+        tooltip RoomSize xywh {200 10 25 25} box ROUND_UP_BOX labelfont 1 labelsize 8 align 8 minimum 1 maximum 127 step 1
         class WidgetPDial
       }
     }
@@ -577,14 +584,14 @@ refresh(eff);}
   }
   Function {make_phaser_window()} {} {
     Fl_Window effphaserwindow {
-      xywh {389 213 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide
+      xywh {75 25 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide
       class Fl_Group
     } {
       Fl_Choice phaserp {
         label Preset
         callback {eff->changepreset((int)o->value());
 refresh(eff);}
-        xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7
+        xywh {10 15 100 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7
       } {
         MenuItem {} {
           label {Phaser 1}
@@ -610,6 +617,30 @@ refresh(eff);}
           label {Phaser 6}
           xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7
         }
+        MenuItem {} {
+          label {APhaser 1}
+          xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7
+        }
+        MenuItem {} {
+          label {APhaser 2}
+          xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7
+        }
+        MenuItem {} {
+          label {APhaser 3}
+          xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7
+        }
+        MenuItem {} {
+          label {APhaser 4}
+          xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7
+        }
+        MenuItem {} {
+          label {APhaser 5}
+          xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7
+        }
+        MenuItem {} {
+          label {APhaser 6} selected
+          xywh {90 90 100 20} labelfont 1 labelsize 10 labelcolor 7
+        }
       }
       Fl_Text_Display {} {
         label Phaser
@@ -630,70 +661,86 @@ refresh(eff);}
       Fl_Dial phaserp2 {
         label Freq
         callback {eff->seteffectpar(2,(int) o->value());}
-        tooltip {LFO frequency} xywh {85 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127
+        tooltip {LFO frequency} xywh {85 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127
         class WidgetPDial
       }
       Fl_Dial phaserp3 {
         label Rnd
         callback {eff->seteffectpar(3,(int) o->value());}
-        tooltip {LFO randomness} xywh {120 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127
+        tooltip {LFO randomness} xywh {120 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127
         class WidgetPDial
       }
+      Fl_Choice phaserp4 {
+        label LFO
+        callback {eff->seteffectpar(4,(int) o->value());}
+        tooltip {LFO function} xywh {245 55 40 15} down_box BORDER_BOX labelfont 1 labelsize 10 align 130 textsize 8
+      } {
+        MenuItem {} {
+          label SIN
+          xywh {15 15 100 20} labelfont 1 labelsize 10
+        }
+        MenuItem {} {
+          label TRI
+          xywh {25 25 100 20} labelfont 1 labelsize 10
+        }
+      }
       Fl_Dial phaserp5 {
         label {St.df}
         callback {eff->seteffectpar(5,(int) o->value());}
-        tooltip {Left/Right Channel Phase Shift} xywh {200 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127
+        tooltip {Left/Right Channel Phase Shift} xywh {155 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127
         class WidgetPDial
       }
       Fl_Dial phaserp6 {
         label Dpth
         callback {eff->seteffectpar(6,(int) o->value());}
-        tooltip {LFO Depth} xywh {235 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127
+        tooltip {LFO Depth} xywh {120 5 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 maximum 127
         class WidgetPDial
       }
       Fl_Dial phaserp7 {
         label Fb
         callback {eff->seteffectpar(7,(int) o->value());}
-        tooltip Feedback xywh {270 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127
+        tooltip Feedback xywh {185 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127
         class WidgetPDial
       }
+      Fl_Counter phaserp8 {
+        label Stages
+        callback {eff->seteffectpar(8,(int) o->value());}
+        xywh {290 55 35 15} type Simple labelfont 1 labelsize 11 minimum 0 maximum 127 step 1
+        code0 {o->range(1,MAX_PHASER_STAGES);}
+      }
       Fl_Dial phaserp9 {
         label {L/R}
         callback {eff->seteffectpar(9,(int) o->value());}
-        tooltip {Channel Routing} xywh {345 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127
+        tooltip {Channel Routing} xywh {215 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127
         class WidgetPDial
       }
       Fl_Check_Button phaserp10 {
         label Substract
         callback {eff->seteffectpar(10,(int) o->value());}
-        tooltip {inverts output} xywh {185 10 74 20} box THIN_UP_BOX down_box DOWN_BOX color 230 labelfont 1 labelsize 10
-      }
-      Fl_Choice phaserp4 {
-        label {LFO type}
-        callback {eff->seteffectpar(4,(int) o->value());}
-        tooltip {LFO function} xywh {155 50 40 15} down_box BORDER_BOX labelfont 1 labelsize 10 align 130 textsize 8
-      } {
-        MenuItem {} {
-          label SINE
-          xywh {15 15 100 20} labelfont 1 labelsize 10
-        }
-        MenuItem {} {
-          label TRI
-          xywh {25 25 100 20} labelfont 1 labelsize 10
-        }
-      }
-      Fl_Counter phaserp8 {
-        label Stages
-        callback {eff->seteffectpar(8,(int) o->value());}
-        xywh {305 55 35 15} type Simple labelfont 1 labelsize 11 minimum 0 maximum 127 step 1
-        code0 {o->range(1,MAX_PHASER_STAGES);}
+        tooltip {inverts output} xywh {200 10 74 20} box THIN_UP_BOX down_box DOWN_BOX color 230 labelfont 1 labelsize 10
       }
       Fl_Dial phaserp11 {
         label Phase
         callback {eff->seteffectpar(11,(int) o->value());}
-        xywh {155 10 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 maximum 127
+        xywh {155 5 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 maximum 127
         class WidgetPDial
       }
+      Fl_Check_Button phaserp12 {
+        label {hyp.}
+        callback {eff->seteffectpar(12,(int) o->value());}
+        tooltip hyper xywh {245 35 55 15} down_box DOWN_BOX
+      }
+      Fl_Dial phaserp13 {
+        label dist
+        callback {eff->seteffectpar(13,(int) o->value());}
+        tooltip Distortion xywh {340 50 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127
+        class WidgetPDial
+      }
+      Fl_Check_Button phaserp14 {
+        label Analog
+        callback {eff->seteffectpar(14,(int) o->value());}
+        xywh {305 35 70 15} down_box DOWN_BOX
+      }
     }
   }
   Function {make_alienwah_window()} {} {
@@ -1263,7 +1310,8 @@ effdynamicfilterwindow->position(px,py);
 
 refresh(eff);} {}
   }
-  Function {refresh(EffectMgr *eff_)} {} {
+  Function {refresh(EffectMgr *eff_)} {open
+  } {
     code {eff=eff_;
 this->hide();
 
@@ -1293,13 +1341,14 @@ switch(eff->geteffect()){
 	revp2->value(eff->geteffectpar(2));
 	revp3->value(eff->geteffectpar(3));
 	revp4->value(eff->geteffectpar(4));
-	revp5->value(eff->geteffectpar(5));
+	//revp5->value(eff->geteffectpar(5));
 	revp6->value(eff->geteffectpar(6));
 	revp7->value(eff->geteffectpar(7));
 	revp8->value(eff->geteffectpar(8));
 	revp9->value(eff->geteffectpar(9));
 	revp10->value(eff->geteffectpar(10));
 	revp11->value(eff->geteffectpar(11));
+	revp12->value(eff->geteffectpar(12));
             
         effreverbwindow->show();
         break; 
@@ -1343,6 +1392,9 @@ switch(eff->geteffect()){
 	phaserp9->value(eff->geteffectpar(9));
 	phaserp10->value(eff->geteffectpar(10));
 	phaserp11->value(eff->geteffectpar(11));
+	phaserp12->value(eff->geteffectpar(12));
+	phaserp13->value(eff->geteffectpar(13));
+	phaserp14->value(eff->geteffectpar(14));
 	effphaserwindow->show();
         break; 
      case 5:
@@ -1412,7 +1464,8 @@ switch(eff->geteffect()){
 
 this->show();} {}
   }
-  Function {refresh()} {} {
+  Function {refresh()} {open
+  } {
     code {refresh(eff);} {}
   }
   decl {EffectMgr *eff;} {}
diff --git a/src/UI/EnvelopeUI.fl b/src/UI/EnvelopeUI.fl
index eef5ad6..f765572 100644
--- a/src/UI/EnvelopeUI.fl
+++ b/src/UI/EnvelopeUI.fl
@@ -63,7 +63,7 @@ for (int i=1;i<npoints;i++) sum+=env->getdt(i)+1;
 float sumbefore=0;//the sum of all points before the computed point
 for (int i=1;i<=n;i++) sumbefore+=env->getdt(i)+1;
 
-return((int) (sumbefore/(REALTYPE) sum*lx));} {}
+return((int) (sumbefore/(float) sum*lx));} {}
   }
   Function {getpointy(int n)} {return_type int
   } {
diff --git a/src/UI/FilterUI.fl b/src/UI/FilterUI.fl
index e2da82e..a72c749 100644
--- a/src/UI/FilterUI.fl
+++ b/src/UI/FilterUI.fl
@@ -1,5 +1,5 @@
 # data file for the Fltk User Interface Designer (fluid)
-version 1.0106 
+version 1.0110 
 header_name {.h} 
 code_name {.cc}
 decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} 
@@ -9,10 +9,12 @@ decl {//License: GNU GPL version 2 or later} {}
 decl {\#include "WidgetPDial.h"} {public
 } 
 
-decl {\#include <stdio.h>} {public
+decl {\#include <cmath>} {} 
+
+decl {\#include <stdio.h>} {global
 } 
 
-decl {\#include <stdlib.h>} {public
+decl {\#include <stdlib.h>} {selected global
 } 
 
 decl {\#include "../globals.h"} {public
@@ -49,10 +51,10 @@ graphpoints=NULL;} {}
 nvowel=nvowel_;
 nformant=nformant_;
 oldx=-1;
-graphpoints=new REALTYPE [w()];} {}
+graphpoints=new float [w()];} {}
   }
-  Function {draw_freq_line(REALTYPE freq,int type)} {} {
-    code {REALTYPE freqx=pars->getfreqpos(freq);
+  Function {draw_freq_line(float freq,int type)} {} {
+    code {float freqx=pars->getfreqpos(freq);
 switch(type){
   case 0:fl_line_style(FL_SOLID);break;
   case 1:fl_line_style(FL_DOT);break;
@@ -68,7 +70,7 @@ if ((freqx>0.0)&&(freqx<1.0))
   } {
     code {int maxdB=30;
 int ox=x(),oy=y(),lx=w(),ly=h(),i,oiy;
-REALTYPE freqx;
+float freqx;
 
 fl_color(FL_BLACK);
 fl_rectf(ox,oy,lx,ly);
@@ -105,7 +107,7 @@ draw_freq_line(20000.0,1);
 fl_line_style(FL_DOT);
 int GY=10;if (ly<GY*3) GY=-1;
 for (i=1;i<GY;i++){
-   int tmp=(int)(ly/(REALTYPE)GY*i);
+   int tmp=(int)(ly/(float)GY*i);
    fl_line(ox+2,oy+tmp,ox+lx-2,oy+tmp);
 };
 
@@ -146,7 +148,7 @@ for (i=1;i<lx;i++){
   decl {FilterParams *pars;} {}
   decl {int oldx,oldy;} {}
   decl {int *nvowel,*nformant;} {}
-  decl {REALTYPE *graphpoints;} {}
+  decl {float *graphpoints;} {}
 } 
 
 class FilterUI {: {public Fl_Group,PresetsUI_}
@@ -180,39 +182,39 @@ pars->changed=true;}
           tooltip {The Filter type} xywh {10 50 50 15} down_box BORDER_BOX labelsize 10 align 5 textsize 10
           code1 {o->value(pars->Ptype);}
         } {
-          menuitem {} {
+          MenuItem {} {
             label LPF1
             xywh {40 40 100 20} labelfont 1 labelsize 10
           }
-          menuitem {} {
+          MenuItem {} {
             label HPF1
             xywh {50 50 100 20} labelfont 1 labelsize 10
           }
-          menuitem {} {
+          MenuItem {} {
             label LPF2
             xywh {60 60 100 20} labelfont 1 labelsize 10
           }
-          menuitem {} {
+          MenuItem {} {
             label HPF2
             xywh {70 70 100 20} labelfont 1 labelsize 10
           }
-          menuitem {} {
+          MenuItem {} {
             label BPF2
             xywh {82 82 100 20} labelfont 1 labelsize 10
           }
-          menuitem {} {
+          MenuItem {} {
             label NF2
             xywh {94 94 100 20} labelfont 1 labelsize 10
           }
-          menuitem {} {
+          MenuItem {} {
             label PkF2
             xywh {104 104 100 20} labelfont 1 labelsize 10
           }
-          menuitem {} {
+          MenuItem {} {
             label LSh2
             xywh {114 114 100 20} labelfont 1 labelsize 10
           }
-          menuitem {} {
+          MenuItem {} {
             label HSh2
             xywh {124 124 100 20} labelfont 1 labelsize 10
           }
@@ -224,19 +226,19 @@ pars->changed=true;}
           tooltip {The Filter type} xywh {10 50 50 15} down_box BORDER_BOX labelsize 10 align 5 textsize 10
           code1 {o->value(pars->Ptype);}
         } {
-          menuitem {} {
+          MenuItem {} {
             label 1LPF
             xywh {134 134 100 20} labelfont 1 labelsize 10
           }
-          menuitem {} {
+          MenuItem {} {
             label 1HPF
             xywh {144 144 100 20} labelfont 1 labelsize 10
           }
-          menuitem {} {
+          MenuItem {} {
             label 1BPF
             xywh {154 154 100 20} labelfont 1 labelsize 10
           }
-          menuitem {} {
+          MenuItem {} {
             label 1NF
             xywh {164 164 100 20} labelfont 1 labelsize 10
           }
@@ -248,15 +250,15 @@ pars->changed=true;}
           tooltip {The Category of the Filter (Analog/Formantic/etc.)} xywh {10 20 60 15} down_box BORDER_BOX labelsize 10 align 5 textsize 10
           code0 {o->value(pars->Pcategory);}
         } {
-          menuitem {} {
+          MenuItem {} {
             label Analog
             xywh {50 50 100 20} labelfont 1 labelsize 10
           }
-          menuitem {} {
+          MenuItem {} {
             label Formant
             xywh {60 60 100 20} labelfont 1 labelsize 10
           }
-          menuitem {} {
+          MenuItem {} {
             label StVarF
             xywh {70 70 100 20} labelfont 1 labelsize 10
           }
@@ -558,8 +560,7 @@ if ((categ==0)||(categ==2)) {
         cfreqdial->label("BS.pos");
 };
 
-filterparamswindow->redraw();} {selected
-    }
+filterparamswindow->redraw();} {}
   }
   Function {init(FilterParams *filterpars_,unsigned char *velsnsamp_,unsigned char *velsns_)} {} {
     code {pars=filterpars_;
diff --git a/src/UI/Makefile b/src/UI/Makefile
deleted file mode 100644
index 6219e0b..0000000
--- a/src/UI/Makefile
+++ /dev/null
@@ -1,41 +0,0 @@
-include ../Makefile.inc
-
-%.cc  : %.fl
-	fluid -c $<
-
-objects=WidgetPDial.o PresetsUI.o EnvelopeUI.o LFOUI.o FilterUI.o VirKeyboard.o ConfigUI.o\
-	SUBnoteUI.o ResonanceUI.o OscilGenUI.o ADnoteUI.o PADnoteUI.o EffUI.o BankUI.o \
-	PartUI.o MicrotonalUI.o SeqUI.o MasterUI.o 
-ifeq ($(DISABLE_GUI),YES)
-    objects=
-endif
-
-all: $(objects)
-
-WidgetPDial.o: WidgetPDial.fl WidgetPDial.cc WidgetPDial.h
-PresetsUI.o: PresetsUI.fl PresetsUI.cc PresetsUI.h
-EnvelopeUI.o: EnvelopeUI.fl EnvelopeUI.cc EnvelopeUI.h
-LFOUI.o: LFOUI.fl LFOUI.cc LFOUI.h
-FilterUI.o: FilterUI.fl FilterUI.cc FilterUI.h
-
-ResonanceUI.o:ResonanceUI.fl ResonanceUI.cc ResonanceUI.h
-OscilGenUI.o:OscilGenUI.fl OscilGenUI.cc OscilGenUI.h
-ADnoteUI.o:ADnoteUI.fl ADnoteUI.cc ADnoteUI.h
-SUBnoteUI.o:SUBnoteUI.fl SUBnoteUI.cc SUBnoteUI.h
-PADnoteUI.o:PADnoteUI.fl PADnoteUI.cc PADnoteUI.h
-
-EffUI.o: EffUI.fl EffUI.cc EffUI.h
-BankUI.o: BankUI.fl BankUI.cc BankUI.h
-PartUI.o: PartUI.fl PartUI.cc PartUI.h
-
-VirKeyboard.o:  VirKeyboard.fl VirKeyboard.cc VirKeyboard.h
-ConfigUI.o: ConfigUI.fl ConfigUI.cc ConfigUI.h
-MicrotonalUI.o: MicrotonalUI.fl MicrotonalUI.cc MicrotonalUI.h
-SeqUI.o: SeqUI.fl SeqUI.cc SeqUI.h
-MasterUI.o:  MasterUI.fl MasterUI.cc MasterUI.h
-
-.PHONY : clean
-clean: 
-	rm -f $(objects)
-	rm -f makeinclude.deps
-	rm -f *.h *.cc
diff --git a/src/UI/MasterUI.fl b/src/UI/MasterUI.fl
index b0c77d7..794348c 100644
--- a/src/UI/MasterUI.fl
+++ b/src/UI/MasterUI.fl
@@ -1,9 +1,8 @@
 # data file for the Fltk User Interface Designer (fluid)
-version 1.0109 
+version 1.0110 
 header_name {.h} 
 code_name {.cc}
-decl {//Copyright (c) 2002-2009 Nasca Octavian Paul} {selected
-} 
+decl {//Copyright (c) 2002-2009 Nasca Octavian Paul} {} 
 
 decl {//License: GNU GPL version 2 or later} {} 
 
@@ -43,10 +42,10 @@ decl {\#include "PartUI.h"} {public
 decl {\#include "MicrotonalUI.h"} {public
 } 
 
-decl {\#include "SeqUI.h"} {public
+decl {\#include "PresetsUI.h"} {public
 } 
 
-decl {\#include "PresetsUI.h"} {public
+decl {\#include "NioUI.h"} {public global
 } 
 
 decl {\#include "../Misc/Master.h"} {public
@@ -58,6 +57,12 @@ decl {\#include "../Misc/Part.h"} {public
 decl {\#include "../Misc/Util.h"} {public
 } 
 
+decl {\#if USE_NSM
+\#include "NSM.H"
+extern NSM_Client *nsm;
+\#endif} {public
+} 
+
 decl {\#include "../globals.h"} {public
 } 
 
@@ -82,15 +87,17 @@ oldrmsdbr=0.0;} {}
 
 int ox=x(); int oy=y(); int lx=w(); int ly=h();
 
-pthread_mutex_lock(&master->mutex);
-REALTYPE dbl=rap2dB(master->vuoutpeakl);
-REALTYPE dbr=rap2dB(master->vuoutpeakr);
-REALTYPE rmsdbl=rap2dB(master->vurmspeakl);
-REALTYPE rmsdbr=rap2dB(master->vurmspeakr);
-REALTYPE maxdbl=rap2dB(master->vumaxoutpeakl);
-REALTYPE maxdbr=rap2dB(master->vumaxoutpeakr);
-int clipped=master->vuclipped;
-pthread_mutex_unlock(&master->mutex);
+vuData data = master->getVuData();
+
+//pthread_mutex_lock(&master->mutex);
+float dbl=rap2dB(data.outpeakl);
+float dbr=rap2dB(data.outpeakr);
+float rmsdbl=rap2dB(data.rmspeakl);
+float rmsdbr=rap2dB(data.rmspeakr);
+float maxdbl=rap2dB(data.maxoutpeakl);
+float maxdbr=rap2dB(data.maxoutpeakr);
+int clipped=data.clipped;
+//pthread_mutex_unlock(&master->mutex);
 
 dbl=(MIN_DB-dbl)/MIN_DB; 
 if (dbl<0.0) dbl=0.0;
@@ -147,7 +154,7 @@ fl_rectf(ox+idbr,oy,VULENX-idbr,VULENY,0,0,0);
 fl_rectf(ox+idbl,oy+ly/2,VULENX-idbl,VULENY,0,0,0);
 
 //draw the scales
-REALTYPE  tmp=VULENX*1.0/MIN_DB;
+float  tmp=VULENX*1.0/MIN_DB;
 for (int i=1;i<1-MIN_DB;i++){
    int tx=VULENX+(int) (tmp*i);
    fl_rectf(ox+tx,oy,1,VULENY+ly/2,0,160,200);
@@ -182,9 +189,9 @@ if ((maxdbr>MIN_DB-20)){
 int ox=x(); int oy=y(); int lx=w(); int ly=h();
 
 if (!active_r()){
-  pthread_mutex_lock(&master->mutex);
+  pthread_mutex_lock(&master->vumutex);
    int fakedb=master->fakepeakpart[npart];
-  pthread_mutex_unlock(&master->mutex);
+  pthread_mutex_unlock(&master->vumutex);
   fl_rectf(ox,oy,lx,ly,140,140,140);
   if (fakedb>0){
     fakedb=(int)(fakedb/255.0*ly)+4;
@@ -195,9 +202,9 @@ if (!active_r()){
 };
 
 //draw the vu lines
-pthread_mutex_lock(&master->mutex);
- REALTYPE db=rap2dB(master->vuoutpeakpart[npart]);
-pthread_mutex_unlock(&master->mutex);
+pthread_mutex_lock(&master->vumutex);
+ float db=rap2dB(master->vuoutpeakpart[npart]);
+pthread_mutex_unlock(&master->vumutex);
 
 db=(MIN_DB-db)/MIN_DB; 
 if (db<0.0) db=0.0;
@@ -212,7 +219,7 @@ fl_rectf(ox,oy,lx,ly-idb,0,0,0);
 
 
 //draw the scales
-REALTYPE  tmp=ly*1.0/MIN_DB;
+float  tmp=ly*1.0/MIN_DB;
  for (int i=1;i<1-MIN_DB;i++){
     int ty=ly+(int) (tmp*i);
     if (i%5==0) fl_rectf(ox,oy+ly-ty,lx,1,0,160,200);
@@ -230,7 +237,7 @@ REALTYPE  tmp=ly*1.0/MIN_DB;
   Function {tick(void *v)} {return_type {static void}
   } {
     code {tickdraw((VUMeter *) v);
-Fl::add_timeout(1.0/25.0,tick,v);//25 fps} {}
+Fl::add_timeout(1.0/18.0,tick,v);//18 fps} {}
   }
   Function {handle(int event)} {return_type int
   } {
@@ -275,7 +282,8 @@ labelsize(10);
 align(FL_ALIGN_TOP);
 
 value(master->Psysefxsend[neff1][neff2]);
-char tmp[20];snprintf(tmp,20,"%d->%d",neff1+1,neff2+1);this->label(strdup(tmp));} {}
+char tmp[20];snprintf(tmp,20,"%d->%d",neff1+1,neff2+1);
+this->copy_label(tmp);} {}
   }
   Function {~SysEffSend()} {} {
     code {hide();} {}
@@ -302,7 +310,7 @@ class Panellistitem {: {public Fl_Group}
       class Fl_Group
     } {
       Fl_Group panellistitemgroup {
-        private xywh {0 20 70 240} box PLASTIC_THIN_UP_BOX
+        private xywh {0 20 70 240} box THIN_UP_BOX
         code0 {if (master->part[npart]->Penabled==0) o->deactivate();}
       } {
         Fl_Group {} {
@@ -341,10 +349,10 @@ bankui->show();}
    bankui->cbwig->value(npart+1);
    bankui->cbwig->do_callback();
 };}
-          xywh {15 235 40 20} box PLASTIC_UP_BOX labelsize 10
+          xywh {15 235 40 20} labelsize 10
         }
         Fl_Choice partrcv {
-          callback {master->part[npart]->Prcvchn=(int) o->value();} open
+          callback {master->part[npart]->Prcvchn=(int) o->value();}
           tooltip {receive from Midi channel} xywh {10 213 50 15} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10
           code0 {char nrstr[10]; for(int i=0;i<NUM_MIDI_CHANNELS;i++){sprintf(nrstr,"Ch%d",i+1);if (i!=9) o->add(nrstr); else o->add("Dr10");};}
           code1 {o->value(master->part[npart]->Prcvchn);}
@@ -367,7 +375,7 @@ if ((int) o->value()==0) panellistitemgroup->deactivate();
 
 o->redraw();}
         private xywh {5 0 45 20} down_box DOWN_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 24
-        code0 {char tmp[10];snprintf(tmp,10,"%d",npart+1);o->label(strdup(tmp));}
+        code0 {char tmp[10];snprintf(tmp,10,"%d",npart+1);o->copy_label(tmp);}
         code1 {o->value(master->part[npart]->Penabled);}
       }
     }
@@ -386,8 +394,7 @@ make_window();
 panellistitem->show();
 end();} {}
   }
-  Function {refresh()} {open
-  } {
+  Function {refresh()} {} {
     code {partenabled->value(master->part[npart]->Penabled);
 if (master->part[npart]->Penabled!=0) panellistitemgroup->activate();
      else panellistitemgroup->deactivate();
@@ -414,19 +421,27 @@ panellistitemgroup->redraw();} {}
   decl {BankUI *bankui;} {}
 } 
 
-class MasterUI {} {
-  Function {make_window()} {} {
+class MasterUI {open
+} {
+  Function {make_window()} {open
+  } {
     Fl_Window masterwindow {
       label zynaddsubfx
       callback {\#ifdef VSTAUDIOOUT
 fl_alert("ZynAddSubFX could not be closed this way, because it's a VST plugin. Please use the host aplication to close it.");
 \#else
-if (fl_choice("Exit and leave the unsaved data?","No","Yes",NULL)) {
+if ((
+\#if USE_NSM 
+(nsm && nsm->is_active())
+\#else
+0
+\#endif
+ || fl_choice("Exit and leave the unsaved data?","No","Yes",NULL))) {
     config.save();
     *exitprogram=1;
 };
-\#endif}
-      xywh {31 206 390 465} type Double xclass zynaddsubfx visible
+\#endif} open
+      xywh {887 248 390 465} type Double xclass zynaddsubfx visible
     } {
       Fl_Menu_Bar mastermenu {
         xywh {-5 0 690 25}
@@ -447,7 +462,16 @@ if (fl_choice("Exit and leave the unsaved data?","No","Yes",NULL)) {
           }
           MenuItem {} {
             label {&Save All Parameters...}
-            callback {do_save_master();}
+            callback {\#if USE_NSM
+            if ( nsm && nsm->is_active() )
+            {
+                do_save_master( nsm->project_filename );
+            }
+            else
+\#endif
+            {
+                 do_save_master();
+            }}
             xywh {10 10 100 20} divider
           }
           MenuItem {} {
@@ -507,7 +531,13 @@ updatepanel();}
           MenuItem {} {
             label {&Settings...}
             callback {configui->show();}
-            xywh {25 25 100 20} divider
+            xywh {25 25 100 20}
+          }
+          MenuItem {} {
+            label {N&io Settings}
+            callback {nioui.refresh();
+nioui.show();}
+            xywh {0 0 36 21} divider
           }
           MenuItem {} {
             label {&Copyright...}
@@ -628,16 +658,6 @@ if (result!=0) fl_alert("Error: Could not save the file.");}
           }
         }
         Submenu {} {
-          label {&Sequencer}
-          xywh {0 0 100 20} hide
-        } {
-          MenuItem {} {
-            label {Show &Sequencer...}
-            callback {sequi->show();}
-            xywh {0 0 100 20}
-          }
-        }
-        Submenu {} {
           label Misc
           xywh {10 10 100 20}
         } {
@@ -673,7 +693,7 @@ if (result!=0) fl_alert("Error: Could not save the file.");}
 pthread_mutex_lock(&master->mutex);
 master->shutup=1;
 pthread_mutex_unlock(&master->mutex);}
-        xywh {293 29 92 31} box PLASTIC_UP_BOX color 231 labelfont 1
+        xywh {293 29 92 31} color 231 labelfont 1
       }
       Fl_Group partuigroup {
         xywh {0 242 390 183} box ENGRAVED_FRAME
@@ -689,7 +709,7 @@ pthread_mutex_unlock(&master->mutex);}
         xywh {0 80 390 160}
       } {
         Fl_Group {} {
-          label {System Effects} open
+          label {System Effects}
           xywh {0 100 390 140} box ENGRAVED_FRAME labeltype EMBOSSED_LABEL labelsize 15 align 25
         } {
           Fl_Counter syseffnocounter {
@@ -891,7 +911,7 @@ pthread_mutex_unlock(&master->mutex);}
       Fl_Button {} {
         label Scales
         callback {microtonalui->show();}
-        xywh {330 80 56 19} box PLASTIC_UP_BOX color 231 labeltype ENGRAVED_LABEL labelfont 1
+        xywh {330 80 56 19} color 231 labeltype ENGRAVED_LABEL labelfont 1
       }
       Fl_Group {} {
         xywh {172 30 117 45} box ENGRAVED_BOX
@@ -971,7 +991,7 @@ simplenpartcounter->do_callback();}
       Fl_Button {} {
         label vK
         callback {virkeyboard->show();}
-        tooltip {Virtual Keyboard} xywh {292 80 35 19} box PLASTIC_UP_BOX color 231 labeltype ENGRAVED_LABEL labelfont 1
+        tooltip {Virtual Keyboard} xywh {292 80 35 19} color 231 labeltype ENGRAVED_LABEL labelfont 1
       }
       Fl_Button {} {
         label {R.D.}
@@ -990,7 +1010,11 @@ globalfinedetuneslider->do_callback();}
         label {Panel Window}
         callback {updatepanel();
 panelwindow->show();}
-        tooltip {Panel Window} xywh {293 62 92 16} box PLASTIC_UP_BOX color 183 labelfont 1 labelsize 10
+        tooltip {Panel Window} xywh {293 62 92 16} color 183 labelfont 1 labelsize 10
+      }
+      Fl_Button sm_indicator1 {
+        label SM selected
+        xywh {350 5 35 15} box ROUNDED_BOX down_box ROUNDED_BOX color 45 selection_color 93 labelfont 3 labelcolor 39 deactivate
       }
     }
     Fl_Window aboutwindow {
@@ -1043,18 +1067,18 @@ GNU General Public License for details.}
       label {ZynAddSubFX Panel}
       xywh {89 59 630 635} type Double hide
     } {
-      Fl_Scroll {} {open
+      Fl_Scroll {} {
         xywh {0 5 570 310} type HORIZONTAL box THIN_UP_BOX
       } {
-        Fl_Pack {} {open
+        Fl_Pack {} {
           xywh {5 10 560 285} type HORIZONTAL
           code0 {for (int i=0;i<NUM_MIDI_PARTS/2;i++){panellistitem[i]=new Panellistitem(0,0,70,260,"");panellistitem[i]->init(master,i,bankui);}}
         } {}
       }
-      Fl_Scroll {} {open
+      Fl_Scroll {} {
         xywh {0 320 570 310} type HORIZONTAL box THIN_UP_BOX
       } {
-        Fl_Pack {} {open
+        Fl_Pack {} {
           xywh {5 325 560 285} type HORIZONTAL
           code0 {for (int i=NUM_MIDI_PARTS/2;i<NUM_MIDI_PARTS;i++){panellistitem[i]=new Panellistitem(0,0,70,260,"");panellistitem[i]->init(master,i,bankui);}}
         } {}
@@ -1080,10 +1104,10 @@ if (fl_choice("Exit and leave the unsaved data?","No","Yes",NULL)) {
 	config.save();
 	*exitprogram=1;
 };
-\#endif}
-      xywh {400 405 600 335} type Double hide
+\#endif} open
+      xywh {672 121 600 335} type Double visible
     } {
-      Fl_Menu_Bar {} {
+      Fl_Menu_Bar simplemastermenu {
         xywh {0 0 690 25}
       } {
         Submenu {} {
@@ -1102,7 +1126,16 @@ if (fl_choice("Exit and leave the unsaved data?","No","Yes",NULL)) {
           }
           MenuItem {} {
             label {&Save All Parameters...}
-            callback {do_save_master();}
+            callback {\#if USE_NSM
+            if ( nsm && nsm->is_active() )
+            {
+                do_save_master( nsm->project_filename );
+            }
+            else
+\#endif
+            {
+                 do_save_master();
+            }}
             xywh {20 20 100 20} divider
           }
           MenuItem {} {
@@ -1182,7 +1215,7 @@ if (result==-10) fl_alert("Error: Could not load the file\\nbecause it is not an
    bankui->cbwig->do_callback();
 };
 bankui->show();}
-          xywh {130 72 205 18} box PLASTIC_THIN_DOWN_BOX down_box FLAT_BOX color 247 labelfont 1 labelsize 11 align 208
+          xywh {130 72 205 18} box THIN_DOWN_BOX down_box FLAT_BOX color 247 labelfont 1 labelsize 11 align 208
         }
         Fl_Slider partpanning {
           label Pan
@@ -1288,7 +1321,7 @@ if ((int) o->value()==0) simplelistitemgroup->deactivate();
 
 o->redraw();}
         private xywh {250 40 85 20} down_box DOWN_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 24
-        code0 {//char tmp[10];snprintf(tmp,10,"%d",npart+1);o->label(strdup(tmp));}
+        code0 {//char tmp[10];snprintf(tmp,10,"%d",npart+1);o->copy_label(tmp);}
         code1 {o->value(master->part[npart]->Penabled);}
       }
       Fl_Box virkeys {
@@ -1305,7 +1338,7 @@ o->redraw();}
         } {
           Fl_Group {} {
             label {System Effects}
-            xywh {345 55 245 155} box ENGRAVED_FRAME labelfont 1 labelsize 12 align 18
+            xywh {345 55 245 155} box ENGRAVED_FRAME labelfont 1 labelsize 12 align 18 hide
           } {
             Fl_Counter simplesyseffnocounter {
               label {Sys.Effect No.}
@@ -1387,7 +1420,7 @@ pthread_mutex_unlock(&master->mutex);}
           }
           Fl_Group {} {
             label {Insertion Effects}
-            xywh {345 55 245 155} box ENGRAVED_FRAME labelfont 1 labelsize 12 align 18 hide
+            xywh {345 55 245 155} box ENGRAVED_FRAME labelfont 1 labelsize 12 align 18
           } {
             Fl_Counter simpleinseffnocounter {
               label {Ins.Effect No.}
@@ -1525,7 +1558,7 @@ pthread_mutex_unlock(&master->mutex);}
 pthread_mutex_lock(&master->mutex);
 master->shutup=1;
 pthread_mutex_unlock(&master->mutex);}
-        xywh {5 149 115 31} box PLASTIC_UP_BOX color 231 labelfont 1 labelsize 11
+        xywh {5 149 115 31} color 231 labelfont 1 labelsize 11
       }
       Fl_Button {} {
         label Reset
@@ -1559,6 +1592,10 @@ virkeys->take_focus();}
         tooltip {Midi Octave} xywh {5 195 55 20} type Simple labelsize 11 align 8 when 6 minimum 0 maximum 5 step 1 textfont 1 textsize 11
         code0 {o->value(virkeys->midioct);}
       }
+      Fl_Button sm_indicator2 {
+        label SM
+        xywh {560 5 35 15} box ROUNDED_BOX down_box ROUNDED_BOX color 45 selection_color 93 labelfont 3 labelcolor 39 deactivate
+      }
     }
     Fl_Window selectuiwindow {
       label {User Interface mode}
@@ -1578,7 +1615,7 @@ virkeys->take_focus();}
         callback {config.cfg.UserInterfaceMode=1;
 masterwindow->show();
 selectuiwindow->hide();}
-        xywh {10 165 100 35} box PLASTIC_UP_BOX color 229 labelfont 1 labelsize 16
+        xywh {10 165 100 35} color 229 labelfont 1 labelsize 16
       }
       Fl_Box {} {
         label {.. if you have used ZynAddSubFX before, or you like to have full controll to all parameters.}
@@ -1589,7 +1626,7 @@ selectuiwindow->hide();}
         callback {simplemasterwindow->show();
 selectuiwindow->hide();
 config.cfg.UserInterfaceMode=2;}
-        xywh {10 80 100 65} box PLASTIC_UP_BOX color 238 labelfont 1 labelsize 16
+        xywh {10 80 100 65} color 238 labelfont 1 labelsize 16
       }
       Fl_Box {} {
         label {..if you are a beginner, you prefer using presets or you prefer to use simpler user interfaces. Most functionality of ZynAddSubFX will be hidden in this mode to make simple the learning/using it.}
@@ -1633,7 +1670,6 @@ microtonalui=new MicrotonalUI(&master->microtonal);
 virkeyboard=new VirKeyboard(master);
 bankui=new BankUI(master,&npart);
 configui=new ConfigUI();
-sequi=new SeqUI(master);
 
 make_window();
 presetsui=new PresetsUI();
@@ -1643,19 +1679,22 @@ simplerefresh();} {}
   }
   Function {~MasterUI()} {} {
     code {masterwindow->hide();
-delete (masterwindow);
+delete masterwindow;
+simplemasterwindow->hide();
+delete simplemasterwindow;
 aboutwindow->hide();
-delete (aboutwindow);
+delete aboutwindow;
 syseffsendwindow->hide();
-delete(syseffsendwindow);
+delete syseffsendwindow;
 
-delete (virkeyboard);
-delete (microtonalui);
-delete (bankui);
-delete (configui);
-delete (sequi);
+delete virkeyboard;
+delete microtonalui;
+delete bankui;
+delete configui;
 
-delete(presetsui);} {}
+delete presetsui;
+delete panelwindow;
+delete selectuiwindow;} {}
   }
   Function {showUI()} {} {
     code {switch (config.cfg.UserInterfaceMode){
@@ -1687,9 +1726,8 @@ simplemaxkcounter->value(master->part[npart]->Pmaxkey);
 simplepartkeyshiftcounter->value(master->part[npart]->Pkeyshift-64);
 simplesyseffsend->value(master->Psysefxvol[nsyseff][npart]);} {}
   }
-  Function {do_new_master()} {} {
-    code {if (fl_choice("Clear *ALL* the parameters ?","No","Yes",NULL)){
-       delete microtonalui;
+  Function {do_new_master_unconditional()} {} {
+    code {delete microtonalui;
 
        pthread_mutex_lock(&master->mutex);
 	master->defaults();
@@ -1697,10 +1735,32 @@ simplesyseffsend->value(master->Psysefxvol[nsyseff][npart]);} {}
 	
        npartcounter->value(1);
        refresh_master_ui();
-
-};
-
-updatepanel();} {}
+       updatepanel();} {}
+  }
+  Function {do_new_master()} {} {
+    code {if (fl_choice("Clear *ALL* the parameters ?","No","Yes",NULL)){
+         do_new_master_unconditional();
+         }} {}
+  }
+  Function {do_load_master_unconditional(const char *filename, const char *display_name)} {return_type int
+  } {
+    code {pthread_mutex_lock(&master->mutex);
+    //clear all parameters
+    master->defaults();
+    
+    //load the data
+    int result=master->loadXML(filename);
+    
+    master->applyparameters(false);
+    pthread_mutex_unlock(&master->mutex);
+    
+    npartcounter->value(1);
+    refresh_master_ui();
+    updatepanel();
+
+    if (result>=0) setfilelabel(display_name);
+    
+    return result;} {}
   }
   Function {do_load_master(const char* file = NULL)} {} {
     code {const char *filename;
@@ -1712,21 +1772,7 @@ updatepanel();} {}
     filename = file;
   }
 
-
-pthread_mutex_lock(&master->mutex);
-  //clear all parameters
-  master->defaults();
-
-  //load the data
-  int result=master->loadXML(filename);
-pthread_mutex_unlock(&master->mutex);
-master->applyparameters();
-
-npartcounter->value(1);
-refresh_master_ui();
-updatepanel();
-if (result>=0) setfilelabel(filename);
-
+  int result = do_load_master_unconditional( filename, filename );
 
 if (result==-10) fl_alert("Error: Could not load the file\\nbecause it is not a zynaddsubfx parameters file.");
       else if (result<0) fl_alert("Error: Could not load the file.");} {}
@@ -1757,8 +1803,15 @@ result=master->saveXML(filename);
 pthread_mutex_unlock(&master->mutex);
 
 if (result<0) fl_alert("Error: Could not save the file.");
-	else setfilelabel(filename);
-
+	else
+{
+\#if USE_NSM
+        if ( nsm && nsm->is_active() )
+             setfilelabel( nsm->display_name );
+        else
+\#endif
+             setfilelabel(filename);
+}
 updatepanel();} {}
   }
   Function {refresh_master_ui()} {} {
@@ -1795,7 +1848,6 @@ bankui->hide();} {}
   }
   decl {Master *master;} {}
   decl {MicrotonalUI *microtonalui;} {}
-  decl {SeqUI *sequi;} {}
   decl {BankUI *bankui;} {}
   decl {int ninseff,npart;} {}
   decl {int nsyseff;} {}
@@ -1806,4 +1858,5 @@ bankui->hide();} {}
   decl {int swapefftype;} {}
   decl {char masterwindowlabel[100];} {}
   decl {Panellistitem *panellistitem[NUM_MIDI_PARTS];} {}
+  decl {NioUI nioui;} {}
 } 
diff --git a/src/UI/NSM.C b/src/UI/NSM.C
new file mode 100644
index 0000000..dee0ff3
--- /dev/null
+++ b/src/UI/NSM.C
@@ -0,0 +1,133 @@
+
+/*******************************************************************************/
+/* Copyright (C) 2012 Jonathan Moore Liles                                     */
+/*                                                                             */
+/* This program is free software; you can redistribute it and/or modify it     */
+/* under the terms of the GNU General Public License as published by the       */
+/* Free Software Foundation; either version 2 of the License, or (at your      */
+/* option) any later version.                                                  */
+/*                                                                             */
+/* 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 for   */
+/* more details.                                                               */
+/*                                                                             */
+/* You should have received a copy of the GNU General Public License along     */
+/* with This program; see the file COPYING.  If not,write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+/*******************************************************************************/
+
+
+#include "NSM.H"
+
+#include "../Nio/Nio.h"
+
+#include "MasterUI.h"
+#include <FL/Fl.H>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+extern int Pexitprogram;
+extern MasterUI *ui;
+
+extern NSM_Client *nsm;
+extern char       *instance_name;
+
+NSM_Client::NSM_Client()
+{
+    project_filename = 0;
+    display_name     = 0;
+}
+
+int command_open(const char *name,
+                 const char *display_name,
+                 const char *client_id,
+                 char **out_msg);
+int command_save(char **out_msg);
+
+int
+NSM_Client::command_save(char **out_msg)
+{
+    (void) out_msg;
+    int r = ERR_OK;
+
+    ui->do_save_master(project_filename);
+
+    return r;
+}
+
+int
+NSM_Client::command_open(const char *name,
+                         const char *display_name,
+                         const char *client_id,
+                         char **out_msg)
+{
+    Nio::stop();
+
+    if(instance_name)
+        free(instance_name);
+
+    instance_name = strdup(client_id);
+
+    Nio::start();
+
+    char *new_filename;
+
+    asprintf(&new_filename, "%s.xmz", name);
+
+    struct stat st;
+
+    int r = ERR_OK;
+
+    if(0 == stat(new_filename, &st)) {
+        if(ui->do_load_master_unconditional(new_filename, display_name) < 0) {
+            *out_msg = strdup("Failed to load for unknown reason");
+            r = ERR_GENERAL;
+
+            return r;
+        }
+    }
+    else
+        ui->do_new_master_unconditional();
+
+    if(project_filename)
+        free(project_filename);
+
+    if(this->display_name)
+        free(this->display_name);
+
+    project_filename = new_filename;
+
+    this->display_name = strdup(display_name);
+
+    return r;
+}
+
+void
+NSM_Client::command_active(bool active)
+{
+    if(active) {
+        const_cast<Fl_Menu_Item *>(ui->mastermenu->find_item(
+                                       "&File/&Open Parameters..."))->
+        deactivate();
+        const_cast<Fl_Menu_Item *>(ui->simplemastermenu->find_item(
+                                       "&File/&Open Parameters..."))->
+        deactivate();
+        ui->sm_indicator1->value(1);
+        ui->sm_indicator2->value(1);
+        ui->sm_indicator1->tooltip(session_manager_name());
+        ui->sm_indicator2->tooltip(session_manager_name());
+    }
+    else {
+        const_cast<Fl_Menu_Item *>(ui->mastermenu->find_item(
+                                       "&File/&Open Parameters..."))->activate();
+        const_cast<Fl_Menu_Item *>(ui->simplemastermenu->find_item(
+                                       "&File/&Open Parameters..."))->activate();
+        ui->sm_indicator1->value(0);
+        ui->sm_indicator2->value(0);
+        ui->sm_indicator1->tooltip(NULL);
+        ui->sm_indicator2->tooltip(NULL);
+    }
+}
diff --git a/src/UI/NSM.H b/src/UI/NSM.H
new file mode 100644
index 0000000..1c70de9
--- /dev/null
+++ b/src/UI/NSM.H
@@ -0,0 +1,45 @@
+
+/*******************************************************************************/
+/* Copyright (C) 2012 Jonathan Moore Liles                                     */
+/*                                                                             */
+/* This program is free software; you can redistribute it and/or modify it     */
+/* under the terms of the GNU General Public License as published by the       */
+/* Free Software Foundation; either version 2 of the License, or (at your      */
+/* option) any later version.                                                  */
+/*                                                                             */
+/* 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 for   */
+/* more details.                                                               */
+/*                                                                             */
+/* You should have received a copy of the GNU General Public License along     */
+/* with This program; see the file COPYING.  If not,write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+/*******************************************************************************/
+
+#pragma once
+
+#if USE_NSM
+#include "NSM/Client.H"
+
+class NSM_Client:public NSM::Client
+{
+    public:
+
+        char *project_filename;
+        char *display_name;
+
+        NSM_Client();
+        ~NSM_Client() { }
+
+    protected:
+
+        int command_open(const char *name,
+                         const char *display_name,
+                         const char *client_id,
+                         char **out_msg);
+        int command_save(char **out_msg);
+
+        void command_active(bool active);
+};
+#endif
diff --git a/src/UI/NSM/Client.C b/src/UI/NSM/Client.C
new file mode 100644
index 0000000..83141e2
--- /dev/null
+++ b/src/UI/NSM/Client.C
@@ -0,0 +1,403 @@
+
+/*******************************************************************************/
+/* Copyright (C) 2012 Jonathan Moore Liles                                     */
+/*                                                                             */
+/* This program is free software; you can redistribute it and/or modify it     */
+/* under the terms of the GNU General Public License as published by the       */
+/* Free Software Foundation; either version 2 of the License, or (at your      */
+/* option) any later version.                                                  */
+/*                                                                             */
+/* 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 for   */
+/* more details.                                                               */
+/*                                                                             */
+/* You should have received a copy of the GNU General Public License along     */
+/* with This program; see the file COPYING.  If not,write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+/*******************************************************************************/
+
+#include "Client.H"
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+
+namespace NSM
+{
+/************************/
+/* OSC Message Handlers */
+/************************/
+
+#undef OSC_REPLY
+#undef OSC_REPLY_ERR
+
+#define OSC_REPLY(value) lo_send_from(((NSM::Client *)user_data)->nsm_addr, \
+                                      ((NSM::Client *)user_data)->_server, \
+                                      LO_TT_IMMEDIATE, \
+                                      "/reply", \
+                                      "ss", \
+                                      path, \
+                                      value)
+
+#define OSC_REPLY_ERR(errcode, value) lo_send_from( \
+        ((NSM::Client *)user_data)->nsm_addr, \
+        ((NSM::Client *)user_data)->_server, \
+        LO_TT_IMMEDIATE, \
+        "/error", \
+        "sis", \
+        path, \
+        errcode, \
+        value)
+
+    Client::Client()
+    {
+        nsm_addr      = 0;
+        nsm_client_id = 0;
+        _session_manager_name = 0;
+        nsm_is_active = false;
+        _server = 0;
+        _st     = 0;
+    }
+
+    Client::~Client()
+    {
+        if(_st)
+            stop();
+
+        if(_st)
+            lo_server_thread_free(_st);
+        else
+            lo_server_free(_server);
+    }
+
+    void
+    Client::announce(const char *application_name,
+                     const char *capabilities,
+                     const char *process_name)
+    {
+        // MESSAGE( "Announcing to NSM" );
+
+        lo_address to = lo_address_new_from_url(nsm_url);
+
+        if(!to)
+            //    MESSAGE( "Bad address" );
+            return;
+
+        int pid = (int)getpid();
+
+        lo_send_from(to,
+                     _server,
+                     LO_TT_IMMEDIATE,
+                     "/nsm/server/announce",
+                     "sssiii",
+                     application_name,
+                     capabilities,
+                     process_name,
+                     1,
+                     /* api_major_version */
+                     0,
+                     /* api_minor_version */
+                     pid);
+
+        lo_address_free(to);
+    }
+
+    void
+    Client::progress(float p)
+    {
+        if(nsm_is_active)
+            lo_send_from(nsm_addr,
+                         _server,
+                         LO_TT_IMMEDIATE,
+                         "/nsm/client/progress",
+                         "f",
+                         p);
+    }
+
+    void
+    Client::is_dirty(void)
+    {
+        if(nsm_is_active)
+            lo_send_from(nsm_addr,
+                         _server,
+                         LO_TT_IMMEDIATE,
+                         "/nsm/client/is_dirty",
+                         "");
+    }
+
+    void
+    Client::is_clean(void)
+    {
+        if(nsm_is_active)
+            lo_send_from(nsm_addr,
+                         _server,
+                         LO_TT_IMMEDIATE,
+                         "/nsm/client/is_clean",
+                         "");
+    }
+
+    void
+    Client::message(int priority, const char *msg)
+    {
+        if(nsm_is_active)
+            lo_send_from(nsm_addr,
+                         _server,
+                         LO_TT_IMMEDIATE,
+                         "/nsm/client/message",
+                         "is",
+                         priority,
+                         msg);
+    }
+
+
+    void
+    Client::broadcast(lo_message msg)
+    {
+        if(nsm_is_active)
+            lo_send_message_from(nsm_addr,
+                                 _server,
+                                 "/nsm/server/broadcast",
+                                 msg);
+    }
+
+    void
+    Client::check(int timeout)
+    {
+        if(lo_server_wait(_server, timeout))
+            while(lo_server_recv_noblock(_server, 0)) {}
+    }
+
+    void
+    Client::start()
+    {
+        lo_server_thread_start(_st);
+    }
+
+    void
+    Client::stop()
+    {
+        lo_server_thread_stop(_st);
+    }
+
+    int
+    Client::init(const char *nsm_url)
+    {
+        this->nsm_url = nsm_url;
+
+        lo_address addr = lo_address_new_from_url(nsm_url);
+        int proto = lo_address_get_protocol(addr);
+        lo_address_free(addr);
+
+        _server = lo_server_new_with_proto(NULL, proto, NULL);
+
+        if(!_server)
+            return -1;
+
+        lo_server_add_method(_server, "/error", "sis", &Client::osc_error, this);
+        lo_server_add_method(_server,
+                             "/reply",
+                             "ssss",
+                             &Client::osc_announce_reply,
+                             this);
+        lo_server_add_method(_server,
+                             "/nsm/client/open",
+                             "sss",
+                             &Client::osc_open,
+                             this);
+        lo_server_add_method(_server,
+                             "/nsm/client/save",
+                             "",
+                             &Client::osc_save,
+                             this);
+        lo_server_add_method(_server,
+                             "/nsm/client/session_is_loaded",
+                             "",
+                             &Client::osc_session_is_loaded,
+                             this);
+        lo_server_add_method(_server, NULL, NULL, &Client::osc_broadcast, this);
+
+        return 0;
+    }
+
+    int
+    Client::init_thread(const char *nsm_url)
+    {
+        this->nsm_url = nsm_url;
+
+        lo_address addr = lo_address_new_from_url(nsm_url);
+        int proto = lo_address_get_protocol(addr);
+        lo_address_free(addr);
+
+        _st     = lo_server_thread_new_with_proto(NULL, proto, NULL);
+        _server = lo_server_thread_get_server(_st);
+
+        if(!_server || !_st)
+            return -1;
+
+        lo_server_thread_add_method(_st,
+                                    "/error",
+                                    "sis",
+                                    &Client::osc_error,
+                                    this);
+        lo_server_thread_add_method(_st,
+                                    "/reply",
+                                    "ssss",
+                                    &Client::osc_announce_reply,
+                                    this);
+        lo_server_thread_add_method(_st,
+                                    "/nsm/client/open",
+                                    "sss",
+                                    &Client::osc_open,
+                                    this);
+        lo_server_thread_add_method(_st,
+                                    "/nsm/client/save",
+                                    "",
+                                    &Client::osc_save,
+                                    this);
+        lo_server_thread_add_method(_st,
+                                    "/nsm/client/session_is_loaded",
+                                    "",
+                                    &Client::osc_session_is_loaded,
+                                    this);
+        lo_server_thread_add_method(_st,
+                                    NULL,
+                                    NULL,
+                                    &Client::osc_broadcast,
+                                    this);
+
+        return 0;
+    }
+
+/************************/
+/* OSC Message Handlers */
+/************************/
+
+    int
+    Client::osc_broadcast(const char *path,
+                          const char *types,
+                          lo_arg **argv,
+                          int argc,
+                          lo_message msg,
+                          void *user_data)
+    {
+        return ((NSM::Client *)user_data)->command_broadcast(path, msg);
+    }
+
+    int
+    Client::osc_save(const char *path,
+                     const char *types,
+                     lo_arg **argv,
+                     int argc,
+                     lo_message msg,
+                     void *user_data)
+    {
+        char *out_msg = NULL;
+
+        int r = ((NSM::Client *)user_data)->command_save(&out_msg);
+
+        if(r)
+            OSC_REPLY_ERR(r, (out_msg ? out_msg : ""));
+        else
+            OSC_REPLY("OK");
+
+        if(out_msg)
+            free(out_msg);
+
+        return 0;
+    }
+
+    int
+    Client::osc_open(const char *path,
+                     const char *types,
+                     lo_arg **argv,
+                     int argc,
+                     lo_message msg,
+                     void *user_data)
+    {
+        char *out_msg = NULL;
+
+        NSM::Client *nsm = (NSM::Client *)user_data;
+
+        nsm->nsm_client_id = strdup(&argv[2]->s);
+
+        int r = ((NSM::Client *)user_data)->command_open(&argv[0]->s,
+                                                         &argv[1]->s,
+                                                         &argv[2]->s,
+                                                         &out_msg);
+
+        if(r)
+            OSC_REPLY_ERR(r, (out_msg ? out_msg : ""));
+        else
+            OSC_REPLY("OK");
+
+        if(out_msg)
+            free(out_msg);
+
+        return 0;
+    }
+
+    int
+    Client::osc_session_is_loaded(const char *path,
+                                  const char *types,
+                                  lo_arg **argv,
+                                  int argc,
+                                  lo_message msg,
+                                  void *user_data)
+    {
+        NSM::Client *nsm = (NSM::Client *)user_data;
+
+        nsm->command_session_is_loaded();
+
+        return 0;
+    }
+
+    int
+    Client::osc_error(const char *path,
+                      const char *types,
+                      lo_arg **argv,
+                      int argc,
+                      lo_message msg,
+                      void *user_data)
+    {
+        if(strcmp(&argv[0]->s, "/nsm/server/announce"))
+            return -1;
+
+        NSM::Client *nsm = (NSM::Client *)user_data;
+
+
+//        WARNING( "Failed to register with NSM: %s", &argv[2]->s );
+        nsm->nsm_is_active = false;
+
+        nsm->command_active(nsm->nsm_is_active);
+
+        return 0;
+    }
+
+    int
+    Client::osc_announce_reply(const char *path,
+                               const char *types,
+                               lo_arg **argv,
+                               int argc,
+                               lo_message msg,
+                               void *user_data)
+    {
+        if(strcmp(&argv[0]->s, "/nsm/server/announce"))
+            return -1;
+
+        NSM::Client *nsm = (NSM::Client *)user_data;
+
+//        MESSAGE( "Successfully registered. NSM says: %s", &argv[1]->s );
+        nsm->nsm_is_active = true;
+        nsm->_session_manager_name = strdup(&argv[2]->s);
+        nsm->nsm_addr =
+            lo_address_new_from_url(lo_address_get_url(lo_message_get_source(
+                                                           msg)));
+
+        nsm->command_active(nsm->nsm_is_active);
+
+        return 0;
+    }
+};
diff --git a/src/UI/NSM/Client.H b/src/UI/NSM/Client.H
new file mode 100644
index 0000000..e515c71
--- /dev/null
+++ b/src/UI/NSM/Client.H
@@ -0,0 +1,143 @@
+
+/*******************************************************************************/
+/* Copyright (C) 2012 Jonathan Moore Liles                                     */
+/*                                                                             */
+/* This program is free software; you can redistribute it and/or modify it     */
+/* under the terms of the GNU General Public License as published by the       */
+/* Free Software Foundation; either version 2 of the License, or (at your      */
+/* option) any later version.                                                  */
+/*                                                                             */
+/* 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 for   */
+/* more details.                                                               */
+/*                                                                             */
+/* You should have received a copy of the GNU General Public License along     */
+/* with This program; see the file COPYING.  If not,write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+/*******************************************************************************/
+
+#pragma once
+
+#include <lo/lo.h>
+
+namespace NSM
+{
+    class Client
+    {
+        private:
+
+            const char *nsm_url;
+
+            lo_server _server;
+            lo_server_thread _st;
+            lo_address       nsm_addr;
+
+            bool  nsm_is_active;
+            char *nsm_client_id;
+            char *_session_manager_name;
+
+        public:
+
+            enum {
+                ERR_OK      = 0,
+                ERR_GENERAL = -1,
+                ERR_INCOMPATIBLE_API = -2,
+                ERR_BLACKLISTED      = -3,
+                ERR_LAUNCH_FAILED    = -4,
+                ERR_NO_SUCH_FILE     = -5,
+                ERR_NO_SESSION_OPEN  = -6,
+                ERR_UNSAVED_CHANGES  = -7,
+                ERR_NOT_NOW = -8
+            };
+
+            Client();
+            virtual ~Client();
+
+            bool is_active(void) { return nsm_is_active; }
+
+            const char *session_manager_name(void) {
+                return
+                    _session_manager_name;
+            }
+
+            /* Client->Server methods */
+            void is_dirty(void);
+            void is_clean(void);
+            void progress(float f);
+            void message(int priority, const char *msg);
+            void announce(const char *appliction_name,
+                          const char *capabilities,
+                          const char *process_name);
+
+            void broadcast(lo_message msg);
+
+            /* init without threading */
+            int init(const char *nsm_url);
+            /* init with threading */
+            int init_thread(const char *nsm_url);
+
+            /* call this periodically to check for new messages */
+            void check(int timeout = 0);
+
+            /* or call these to start and stop a thread (must do your own locking in handler!) */
+            void start(void);
+            void stop(void);
+
+        protected:
+
+            /* Server->Client methods */
+            virtual int command_open(const char *name,
+                                     const char *display_name,
+                                     const char *client_id,
+                                     char **out_msg) = 0;
+            virtual int command_save(char **out_msg) = 0;
+
+            virtual void command_active(bool) { }
+
+            virtual void command_session_is_loaded(void) { }
+
+            /* invoked when an unrecognized message is received. Should return 0 if you handled it, -1 otherwise. */
+            virtual int command_broadcast(const char *, lo_message) { return -1; }
+
+        private:
+
+            /* osc handlers */
+            static int osc_open(const char *path,
+                                const char *types,
+                                lo_arg **argv,
+                                int argc,
+                                lo_message msg,
+                                void *user_data);
+            static int osc_save(const char *path,
+                                const char *types,
+                                lo_arg **argv,
+                                int argc,
+                                lo_message msg,
+                                void *user_data);
+            static int osc_announce_reply(const char *path,
+                                          const char *types,
+                                          lo_arg **argv,
+                                          int argc,
+                                          lo_message msg,
+                                          void *user_data);
+            static int osc_error(const char *path,
+                                 const char *types,
+                                 lo_arg **argv,
+                                 int argc,
+                                 lo_message msg,
+                                 void *user_data);
+            static int osc_session_is_loaded(const char *path,
+                                             const char *types,
+                                             lo_arg **argv,
+                                             int argc,
+                                             lo_message msg,
+                                             void *user_data);
+            static int osc_broadcast(const char *path,
+                                     const char *types,
+                                     lo_arg **argv,
+                                     int argc,
+                                     lo_message msg,
+                                     void *user_data);
+    };
+};
diff --git a/src/UI/NioUI.cpp b/src/UI/NioUI.cpp
new file mode 100644
index 0000000..8e253b3
--- /dev/null
+++ b/src/UI/NioUI.cpp
@@ -0,0 +1,76 @@
+#include "NioUI.h"
+#include "../Nio/Nio.h"
+#include <cstdio>
+#include <iostream>
+#include <cstring>
+#include <FL/Fl_Pack.H>
+#include <FL/Fl_Spinner.H>
+#include <FL/Enumerations.H>
+#include <FL/Fl_Choice.H>
+#include <FL/Fl_Tabs.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Text_Display.H>
+
+using namespace std;
+
+NioUI::NioUI()
+    :Fl_Window(200, 100, 400, 400, "New IO Controls")
+{
+    //hm, I appear to be leaking memory
+    Fl_Group *settings = new Fl_Group(0, 20, 400, 400 - 35, "Settings");
+    {
+        audio = new Fl_Choice(60, 80, 100, 25, "Audio");
+        audio->callback(audioCallback);
+        midi = new Fl_Choice(60, 100, 100, 25, "Midi");
+        midi->callback(midiCallback);
+    }
+    settings->end();
+
+    //initialize midi list
+    {
+        set<string> midiList = Nio::getSources();
+        string      source   = Nio::getSource();
+        int midival = 0;
+        for(set<string>::iterator itr = midiList.begin();
+            itr != midiList.end(); ++itr) {
+            midi->add(itr->c_str());
+            if(*itr == source)
+                midival = midi->size() - 2;
+        }
+        midi->value(midival);
+    }
+
+    //initialize audio list
+    {
+        set<string> audioList = Nio::getSinks();
+        string      sink      = Nio::getSink();
+        int audioval = 0;
+        for(set<string>::iterator itr = audioList.begin();
+            itr != audioList.end(); ++itr) {
+            audio->add(itr->c_str());
+            if(*itr == sink)
+                audioval = audio->size() - 2;
+        }
+        audio->value(audioval);
+    }
+    resizable(this);
+    size_range(400, 300);
+}
+
+NioUI::~NioUI()
+{}
+
+void NioUI::refresh()
+{}
+
+void NioUI::midiCallback(Fl_Widget *c)
+{
+    bool good = Nio::setSource(static_cast<Fl_Choice *>(c)->text());
+    static_cast<Fl_Choice *>(c)->textcolor(fl_rgb_color(255 * !good, 0, 0));
+}
+
+void NioUI::audioCallback(Fl_Widget *c)
+{
+    bool good = Nio::setSink(static_cast<Fl_Choice *>(c)->text());
+    static_cast<Fl_Choice *>(c)->textcolor(fl_rgb_color(255 * !good, 0, 0));
+}
diff --git a/src/UI/NioUI.h b/src/UI/NioUI.h
new file mode 100644
index 0000000..f894997
--- /dev/null
+++ b/src/UI/NioUI.h
@@ -0,0 +1,20 @@
+#ifndef NIOUI_H
+#define NIOUT_H
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+
+class NioUI:public Fl_Window
+{
+    public:
+        NioUI();
+        ~NioUI();
+        void refresh();
+    private:
+        class Fl_Choice * midi;
+        class Fl_Choice * audio;
+        static void midiCallback(Fl_Widget *c);
+        static void audioCallback(Fl_Widget *c);
+};
+
+#endif
diff --git a/src/UI/OscilGenUI.fl b/src/UI/OscilGenUI.fl
index 4d15dc8..7736977 100644
--- a/src/UI/OscilGenUI.fl
+++ b/src/UI/OscilGenUI.fl
@@ -1,8 +1,9 @@
 # data file for the Fltk User Interface Designer (fluid)
-version 1.0109 
+version 1.0110 
 header_name {.h} 
 code_name {.cc}
-decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} 
+decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {selected
+} 
 
 decl {//License: GNU GPL version 2 or later} {} 
 
@@ -65,10 +66,10 @@ master=master_;} {}
 const int maxdb=60;//must be multiple of 10
 int GX=2;
 int n=lx/GX-1;
-if (n>OSCIL_SIZE/2) n=OSCIL_SIZE/2;
+if (n>synth->oscilsize/2) n=synth->oscilsize/2;
 
-REALTYPE x;
-REALTYPE* spc=new REALTYPE[n];
+float x;
+float* spc=new float[n];
 for (i=0;i<n;i++) spc[i]=0.0;
 
 pthread_mutex_lock(&master->mutex);
@@ -77,7 +78,7 @@ if (oscbase==0) oscil->getspectrum(n,spc,0);
 pthread_mutex_unlock(&master->mutex);
 
 //normalize
-REALTYPE max=0;
+float max=0;
 for (i=0;i<n;i++){
    x=fabs(spc[i]);
    if (max<x) max=x;
@@ -92,7 +93,7 @@ if (this->active_r()) fl_color(this->parent()->selection_color());
 fl_line_style(FL_DOT);
 
 for (i=1;i<maxdb/10;i++){
-  int ky=(int)((REALTYPE)i*ly*10.0/maxdb)/2;
+  int ky=(int)((float)i*ly*10.0/maxdb)/2;
   ky*=2;
   fl_line(ox,oy+ky-1,ox+lx-2,oy+ky-1);
 };
@@ -119,8 +120,7 @@ for (i=0;i<n;i++){
    int val=(int) ((ly-2)*x);
    if (val>0) fl_line(ox+tmp,oy+ly-2-val,ox+tmp,oy+ly-2);
 }
-delete [] spc;} {selected
-    }
+delete [] spc;} {}
   }
   decl {OscilGen *oscil;} {}
   decl {int oscbase;} {}
@@ -129,7 +129,9 @@ delete [] spc;} {selected
 
 class PSlider {: {public Fl_Slider}
 } {
-  Function {PSlider(int x,int y, int w, int h, const char *label=0):Fl_Slider(x,y,w,h,label)} {} {}
+  Function {PSlider(int x,int y, int w, int h, const char *label=0):Fl_Slider(x,y,w,h,label)} {} {
+    code {;} {}
+  }
   Function {handle(int event)} {return_type int
   } {
     code {int X=x(),Y=y(),W=w(),H=h();
@@ -179,7 +181,7 @@ master=master_;} {}
   }
   Function {draw()} {} {
     code {int ox=x(),oy=y(),lx=w(),ly=h()-1,i;
-REALTYPE smps[OSCIL_SIZE];
+float smps[synth->oscilsize];
 pthread_mutex_lock(&master->mutex);
 if (oscbase==0) oscil->get(smps,-1.0);
     else oscil->getcurrentbasefunction(smps);
@@ -191,8 +193,8 @@ if (damage()!=1){
 };
 
 //normalize
-REALTYPE max=0;
-for (i=0;i<OSCIL_SIZE;i++)
+float max=0;
+for (i=0;i<synth->oscilsize;i++)
    if (max<fabs(smps[i])) max=fabs(smps[i]);
 //fprintf(stderr,"%.4f\\n",max);
 if (max<0.00001) max=1.0;
@@ -204,12 +206,12 @@ if (this->active_r()) fl_color(this->parent()->labelcolor());
     else fl_color(this->parent()->color());
 int GX=16;if (lx<GX*3) GX=-1;
 for (i=1;i<GX;i++){
-   int tmp=(int)(lx/(REALTYPE)GX*i);
+   int tmp=(int)(lx/(float)GX*i);
    fl_line(ox+tmp,oy+2,ox+tmp,oy+ly-2);
 };
 int GY=8;if (ly<GY*3) GY=-1;
 for (i=1;i<GY;i++){
-   int tmp=(int)(ly/(REALTYPE)GY*i);
+   int tmp=(int)(ly/(float)GY*i);
    fl_line(ox+2,oy+tmp,ox+lx-2,oy+tmp);
 };
 
@@ -221,12 +223,12 @@ if (this->active_r()) fl_color(this->parent()->selection_color());
 int lw=1;
 //if ((lx<135)||(ly<135)) lw=1;
 fl_line_style(0,lw);
-int ph=(int)((phase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE);
+int ph=(int)((phase-64.0)/128.0*synth->oscilsize+synth->oscilsize);
 for (i=1;i<lx;i++){
-   int k1=(int)((REALTYPE)OSCIL_SIZE*(i-1)/lx)+ph;
-   int k2=(int)((REALTYPE)OSCIL_SIZE*i/lx)+ph;
-   REALTYPE y1=smps[k1%OSCIL_SIZE]/max;
-   REALTYPE y2=smps[k2%OSCIL_SIZE]/max;
+   int k1=(int)((float)synth->oscilsize*(i-1)/lx)+ph;
+   int k2=(int)((float)synth->oscilsize*i/lx)+ph;
+   float y1=smps[k1%synth->oscilsize]/max;
+   float y2=smps[k2%synth->oscilsize]/max;
    fl_line(i-1+ox,(int)(y1*ly/2.0)+oy+ly/2,i+ox,(int)(y2*ly/2.0)+oy+ly/2);
 };} {}
   }
@@ -511,6 +513,14 @@ if ((oscil->Pcurrentbasefunc==0)||(oscil->Pcurrentbasefunc==127)) basefuncmodula
             label Sqr
             xywh {122 122 100 20} labelfont 1 labelsize 11
           }
+          MenuItem {} {
+            label Spike
+            xywh {122 122 100 20} labelfont 1 labelsize 11
+          }
+          MenuItem {} {
+            label Circle
+            xywh {122 122 100 20} labelfont 1 labelsize 11
+          }
         }
         Fl_Box {} {
           label {Base Func.}
@@ -1023,7 +1033,7 @@ redrawoscil();}
         callback {if (!fl_choice("Convert to SINE?","No","Yes",NULL)) return;
 
 pthread_mutex_lock(&master->mutex);
- oscil->convert2sine(0);
+ oscil->convert2sine();
 pthread_mutex_unlock(&master->mutex);
 
 redrawoscil();
diff --git a/src/UI/PADnoteUI.fl b/src/UI/PADnoteUI.fl
index 74441c1..ea3e098 100644
--- a/src/UI/PADnoteUI.fl
+++ b/src/UI/PADnoteUI.fl
@@ -61,9 +61,9 @@ this->pars=pars;} {}
   Function {draw()} {} {
     code {int ox=x(),oy=y(),lx=w(),ly=h();
 if (!visible()) return;
-REALTYPE smps[lx];
+float smps[lx];
 
-REALTYPE realbw=pars->getprofile(smps,lx);
+float realbw=pars->getprofile(smps,lx);
 bool active=active_r();
 
 //draw the equivalent bandwidth
@@ -140,14 +140,14 @@ for (int i=1;i<maxharmonic;i++){
 	fl_line_style(FL_DOT);
 	if (i%5==0) fl_line_style(0);
 	if (i%10==0) fl_color(160,160,160);
-	int kx=(int)(lx/(REALTYPE)maxharmonic*i);
+	int kx=(int)(lx/(float)maxharmonic*i);
 	fl_line(ox+kx,oy,ox+kx,oy+ly);
 };
 
 
 
-int n=OSCIL_SIZE/2;
-REALTYPE spc[n];
+int n=synth->oscilsize/2;
+float spc[n];
 for (int i=0;i<n;i++) spc[i]=0.0;
 
 pthread_mutex_lock(&master->mutex);
@@ -156,21 +156,21 @@ pthread_mutex_unlock(&master->mutex);
 
 
 //normalize
-REALTYPE max=0;
+float max=0;
 for (int i=0;i<n;i++){
-   REALTYPE x=fabs(spc[i]);
+   float x=fabs(spc[i]);
    if (max<x) max=x;
 }
 if (max<0.000001) max=1.0;
 max=max*1.05;
 
-REALTYPE spectrum[lx];
+float spectrum[lx];
 for (int i=0;i<lx;i++) spectrum[i]=0;
 
 
 for (int i=1;i<n;i++){
-	REALTYPE nhr=pars->getNhr(i);
-	int kx=(int)(lx/(REALTYPE)maxharmonic*nhr);
+	float nhr=pars->getNhr(i);
+	int kx=(int)(lx/(float)maxharmonic*nhr);
 	if ((kx<0)||(kx>lx)) continue;
 
         spectrum[kx]=spc[i-1]/max+1e-9;
@@ -185,12 +185,12 @@ if (pars->Pmode==2){
    for (int i=1;i<lx;i++){
 	if ((spectrum[i]>1e-10)||(i==(lx-1))){
 		int delta=i-old;
-		REALTYPE val1=spectrum[old];
-		REALTYPE val2=spectrum[i];
+		float val1=spectrum[old];
+		float val2=spectrum[i];
 
-		REALTYPE idelta=1.0/delta;
+		float idelta=1.0/delta;
 		for (int j=0;j<delta;j++){
-			REALTYPE x=idelta*j;
+			float x=idelta*j;
 			spectrum[old+j]=val1*(1.0-x)+val2*x;
 		};
 		old=i;
@@ -200,7 +200,7 @@ if (pars->Pmode==2){
 };
 
 for (int i=0;i<lx;i++){
-	REALTYPE x=spectrum[i];
+	float x=spectrum[i];
         if (x>dB2rap(-maxdb)) x=rap2dB(x)/maxdb+1;
              else continue;
        	int yy=(int)(x*ly);
diff --git a/src/UI/PartUI.fl b/src/UI/PartUI.fl
index 3a72885..5202bf8 100644
--- a/src/UI/PartUI.fl
+++ b/src/UI/PartUI.fl
@@ -1,5 +1,5 @@
 # data file for the Fltk User Interface Designer (fluid)
-version 1.0107 
+version 1.0110 
 header_name {.h} 
 code_name {.cc}
 decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} 
@@ -42,9 +42,9 @@ decl {\#include "../Misc/Master.h"} {public
 decl {\#include "../Misc/Part.h"} {public
 } 
 
-class PartSysEffSend {open : {public Fl_Group}
+class PartSysEffSend {: {public Fl_Group}
 } {
-  Function {make_window()} {open private
+  Function {make_window()} {private
   } {
     Fl_Window syseffsend {
       private xywh {584 83 90 35} type Double hide
@@ -52,11 +52,11 @@ class PartSysEffSend {open : {public Fl_Group}
     } {
       Fl_Dial {} {
         label 01
-        callback {master->setPsysefxvol(npart,neff,(int) o->value());} selected
+        callback {master->setPsysefxvol(npart,neff,(int) o->value());}
         xywh {0 0 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 align 130 maximum 127 step 1
         code0 {o->size(25,25);}
         code1 {o->value(master->Psysefxvol[neff][npart]);}
-        code2 {char tmp[10];snprintf(tmp,10,"%d",neff+1);o->label(strdup(tmp));}
+        code2 {char tmp[10];snprintf(tmp,10,"%d",neff+1);o->copy_label(tmp);}
         class WidgetPDial
       }
     }
@@ -83,11 +83,6 @@ end();} {}
   decl {int npart;} {}
 } 
 
-class PartUI_ {} {
-  Function {showparameters(int kititem,int engine)} {return_type virtual
-  } {}
-} 
-
 class PartKitItem {: {public Fl_Group}
 } {
   Function {make_window()} {private
@@ -212,7 +207,7 @@ o->redraw();
 partui->showparameters(n,-1);//use to delete the ui, if it is not to item 0
 } else o->value(1);}
         private xywh {30 0 20 15} down_box DOWN_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 4
-        code0 {snprintf(label,10,"%d",n+1);o->label(strdup(label));}
+        code0 {snprintf(label,10,"%d",n+1);o->label(label);}
         code1 {o->value(part->kit[n].Penabled);}
         code2 {if (n==0) o->deactivate();}
       }
@@ -254,7 +249,8 @@ partui->showparameters(n,-1);//use to delete the ui, if it is not to item 0
 } else o->value(1);}
     }
   }
-  Function {init(Part *part_,int n_,Master *master_,PartUI_ *partui_)} {} {
+  Function {init(Part *part_,int n_,Master *master_,class PartUI *partui_)} {selected
+  } {
     code {part=part_;
 n=n_;
 partui=partui_;
@@ -271,12 +267,12 @@ end();} {}
   decl {int n;} {}
   decl {Master *master;} {}
   decl {char label[10];} {}
-  decl {PartUI_ *partui;} {}
+  decl {class PartUI *partui;} {}
 } 
 
-class PartUI {open : {public Fl_Group,PartUI_}
+class PartUI {: {public Fl_Group}
 } {
-  Function {make_window()} {open private
+  Function {make_window()} {private
   } {
     Fl_Window partgroup {
       private xywh {424 178 385 180} type Double hide
@@ -457,7 +453,7 @@ if (part->Penabled==0) partgroupui->deactivate();
     }
     Fl_Window ctlwindow {
       label Controllers
-      private xywh {198 472 460 130} type Double hide
+      private xywh {542 212 500 130} type Double hide
     } {
       Fl_Check_Button {} {
         label Expr
@@ -540,8 +536,8 @@ if (part->ctl.sustain.receive==0) {
         xywh {5 105 210 20} box THIN_UP_BOX
       }
       Fl_Group {} {
-        label Portamento open
-        xywh {280 15 120 85} box ENGRAVED_FRAME labelfont 1 labelsize 10
+        label Portamento
+        xywh {280 15 160 90} box ENGRAVED_FRAME labelfont 1 labelsize 10
       } {
         Fl_Check_Button {} {
           label Rcv
@@ -565,7 +561,7 @@ if (part->ctl.sustain.receive==0) {
         Fl_Check_Button {} {
           label {th.type}
           callback {part->ctl.portamento.pitchthreshtype=(int) o->value();}
-          tooltip {Threshold type (min/max)} xywh {370 70 15 15} down_box DOWN_BOX labelsize 10 align 2
+          tooltip {Threshold type (min/max)} xywh {365 70 15 15} down_box DOWN_BOX labelsize 10 align 2
           code0 {o->value(part->ctl.portamento.pitchthreshtype);}
         }
         Fl_Box {} {
@@ -581,22 +577,46 @@ part->ctl.portamento.updowntimestretch=x;}
           code0 {o->value(part->ctl.portamento.updowntimestretch);}
           class WidgetPDial
         }
+        Fl_Dial propta {
+          label {Prp.Rate}
+          callback {part->ctl.portamento.propRate=(int) o->value();}
+          tooltip {Distance required to double change from nonpropotinal portamento time} xywh {405 20 25 25} labelsize 9 maximum 127 step 1
+          code0 {o->value(part->ctl.portamento.propRate);}
+          class WidgetPDial
+        }
+        Fl_Dial proptb {
+          label {Prp.Dpth}
+          callback {part->ctl.portamento.propDepth=(int) o->value();}
+          tooltip {The difference from nonproportinal portamento} xywh {405 60 25 25} labelsize 9 maximum 127 step 1
+          code0 {o->value(part->ctl.portamento.propDepth);}
+          class WidgetPDial
+        }
+        Fl_Check_Button {} {
+          label {Proprt.}
+          callback {part->ctl.portamento.proportional=(int) o->value();
+if(o->value()){propta->activate();proptb->activate();}
+else {propta->deactivate();proptb->deactivate();}}
+          tooltip {Enable Proportinal Portamento (over fixed Portamento)} xywh {285 40 50 15} box THIN_UP_BOX down_box DOWN_BOX labelsize 9
+          code0 {o->value(part->ctl.portamento.proportional);}
+          code1 {if(o->value()){propta->activate();proptb->activate();}}
+          code2 {else {propta->deactivate();proptb->deactivate();}}
+        }
       }
       Fl_Group {} {
-        label Resonance open
-        xywh {400 15 45 85} box ENGRAVED_BOX labelfont 1 labelsize 10
+        label Resonance
+        xywh {440 15 50 90} box ENGRAVED_BOX labelfont 1 labelsize 10
       } {
         Fl_Dial {} {
           label BWdpth
           callback {part->ctl.resonancebandwidth.depth=(int) o->value();}
-          tooltip {BandWidth controller depth} xywh {410 60 25 25} labelsize 10 maximum 127 step 1
+          tooltip {BandWidth controller depth} xywh {450 60 25 25} labelsize 10 maximum 127 step 1
           code0 {o->value(part->ctl.resonancebandwidth.depth);}
           class WidgetPDial
         }
         Fl_Dial {} {
           label CFdpth
           callback {part->ctl.resonancecenter.depth=(int) o->value();}
-          tooltip {Center Frequency controller Depth} xywh {410 20 25 25} labelsize 10 maximum 127 step 1
+          tooltip {Center Frequency controller Depth} xywh {450 20 25 25} labelsize 10 maximum 127 step 1
           code0 {o->value(part->ctl.resonancecenter.depth);}
           class WidgetPDial
         }
@@ -1025,7 +1045,7 @@ char tmp[10];
 while (klimits[k]!=0){
 	sprintf(tmp,"%d",klimits[k]);
 	keylimitlist->add(tmp);
-	if ((val==-1)){
+	if (val==-1){
 		if (klimits[k]>part->Pkeylimit) val=k;
 	};
 	k++;
diff --git a/src/UI/PresetsUI.fl b/src/UI/PresetsUI.fl
index 0378d62..820cd2f 100644
--- a/src/UI/PresetsUI.fl
+++ b/src/UI/PresetsUI.fl
@@ -1,8 +1,8 @@
 # data file for the Fltk User Interface Designer (fluid)
-version 1.0105 
+version 1.0110 
 header_name {.h} 
 code_name {.cc}
-decl {\#include <FL/fl_ask.H>} {public
+decl {\#include <FL/fl_ask.H>} {selected public
 } 
 
 decl {\#include <stdio.h>} {public
@@ -11,14 +11,20 @@ decl {\#include <stdio.h>} {public
 decl {\#include <stdlib.h>} {public
 } 
 
+decl {\#include "../Params/PresetsArray.h"} {} 
+
 decl {\#include "../Params/Presets.h"} {public
 } 
 
 class PresetsUI_ {} {
   Function {refresh()} {open return_type {virtual void}
-  } {}
+  } {
+    code {;} {}
+  }
   Function {~PresetsUI_()} {open return_type virtual
-  } {}
+  } {
+    code {;} {}
+  }
 } 
 
 class PresetsUI {} {
@@ -96,7 +102,7 @@ if (strlen(tmp)>0) {
 }else{
 	pastepbutton->activate();
 	deletepbutton->activate();
-};} selected
+};}
         xywh {10 25 245 320} type Hold
       }
       Fl_Button pastepbutton {
@@ -171,11 +177,15 @@ if (but) {
    };} {}
   }
   Function {copy(Presets *p,int n)} {} {
-    code {p->setelement(n);
+    code {PresetsArray *pre = dynamic_cast<PresetsArray *>(p);
+if(pre)
+    pre->setelement(n);
 copy(p);} {}
   }
   Function {paste(Presets *p,PresetsUI_ *pui,int n)} {} {
-    code {p->setelement(n);
+    code {PresetsArray *pre = dynamic_cast<PresetsArray *>(p);
+if(pre)
+    pre->setelement(n);
 paste(p,pui);} {}
   }
   Function {rescan()} {} {
@@ -183,11 +193,12 @@ paste(p,pui);} {}
 pastebrowse->clear();
 p->rescanforpresets();
 
-for (int i=0;i<MAX_PRESETS;i++){
-   char *name=presetsstore.presets[i].name;
-   if (name==NULL) break;
-   copybrowse->add(name);
-   pastebrowse->add(name);
+for (unsigned int i=0;i<presetsstore.presets.size();i++){
+   std::string name=presetsstore.presets[i].name;
+   if(name.empty())
+       continue;
+   copybrowse->add(name.c_str());
+   pastebrowse->add(name.c_str());
 };} {}
   }
   decl {Presets *p;} {public
diff --git a/src/UI/ResonanceUI.fl b/src/UI/ResonanceUI.fl
index 3c06c52..f02ab42 100644
--- a/src/UI/ResonanceUI.fl
+++ b/src/UI/ResonanceUI.fl
@@ -46,8 +46,8 @@ dbvalue=dbvalue_;
 oldx=-1;
 khzval=-1;} {}
   }
-  Function {draw_freq_line(REALTYPE freq,int type)} {} {
-    code {REALTYPE freqx=respar->getfreqpos(freq);
+  Function {draw_freq_line(float freq,int type)} {} {
+    code {float freqx=respar->getfreqpos(freq);
 switch(type){
   case 0:fl_line_style(FL_SOLID);break;
   case 1:fl_line_style(FL_DOT);break;
@@ -61,7 +61,7 @@ if ((freqx>0.0)&&(freqx<1.0))
   }
   Function {draw()} {} {
     code {int ox=x(),oy=y(),lx=w(),ly=h(),i,ix,iy,oiy;
-REALTYPE freqx;
+float freqx;
 
 fl_color(FL_BLACK);
 fl_rectf(ox,oy,lx,ly);
@@ -98,7 +98,7 @@ draw_freq_line(20000.0,1);
 fl_line_style(FL_DOT);
 int GY=10;if (ly<GY*3) GY=-1;
 for (i=1;i<GY;i++){
-   int tmp=(int)(ly/(REALTYPE)GY*i);
+   int tmp=(int)(ly/(float)GY*i);
    fl_line(ox+2,oy+tmp,ox+lx-2,oy+tmp);
 };
 
@@ -146,7 +146,7 @@ if ((event==FL_PUSH)||(event==FL_DRAG)){
     };
    for (int i=0;i<x2-x1;i++){
       int sn=(int)((i+x1)*1.0/w()*N_RES_POINTS);
-      REALTYPE yy=(y2-y1)*1.0/(x2-x1)*i;
+      float yy=(y2-y1)*1.0/(x2-x1)*i;
       int sp=127-(int)((y1+yy)/h()*127);
       if (leftbutton!=0) respar->setpoint(sn,sp);
          else respar->setpoint(sn,64);
@@ -179,7 +179,7 @@ this->applybutton=applybutton;} {}
   decl {Fl_Value_Output *dbvalue;} {}
   decl {Resonance *respar;} {}
   decl {int oldx,oldy;} {}
-  decl {REALTYPE khzval;} {public
+  decl {float khzval;} {public
   }
   decl {Fl_Widget *cbwidget,*applybutton;} {}
 } 
diff --git a/src/UI/SeqUI.fl b/src/UI/SeqUI.fl
deleted file mode 100644
index 343719c..0000000
--- a/src/UI/SeqUI.fl
+++ /dev/null
@@ -1,73 +0,0 @@
-# data file for the Fltk User Interface Designer (fluid)
-version 1.0105 
-header_name {.h} 
-code_name {.cc}
-decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} 
-
-decl {//License: GNU GPL version 2 or later} {} 
-
-decl {\#include "../globals.h"} {public
-} 
-
-decl {\#include "../Misc/Master.h"} {public
-} 
-
-decl {\#include "WidgetPDial.h"} {public
-} 
-
-class SeqUI {} {
-  Function {make_window()} {} {
-    Fl_Window seqwin {
-      label {Sequencer - ZynAddSubFX}
-      xywh {104 235 280 265} type Double hide
-    } {
-      Fl_Group {} {
-        label Player
-        xywh {120 20 100 65} box ENGRAVED_BOX labelfont 1
-      } {
-        Fl_Button playbutton {
-          label Play
-          callback {o->deactivate();
-stopbutton_play->activate();
-
-master->seq.startplay();}
-          tooltip {Start Playing} xywh {130 30 30 30} box DIAMOND_UP_BOX color 79 labelfont 1 labelsize 13 align 2
-        }
-        Fl_Button stopbutton_play {
-          label Stop
-          callback {o->deactivate();
-playbutton->activate();
-
-master->seq.stopplay();}
-          tooltip {Stop Playing} xywh {175 29 30 31} box THIN_UP_BOX color 4 labelfont 1 labelsize 13 align 2 deactivate
-        }
-      }
-      Fl_Button {} {
-        label {Open test.mid}
-        callback {master->seq.importmidifile("test.mid");}
-        xywh {20 25 75 55} align 128
-      }
-      Fl_Value_Slider {} {
-        label {Play speed}
-        callback {master->seq.setplayspeed((int) o->value());}
-        xywh {15 105 190 20} type {Horz Knob} minimum -128 maximum 128 step 1
-        code0 {o->value(master->seq.playspeed);}
-      }
-      Fl_Box {} {
-        label {This is not finished} selected
-        xywh {25 155 225 90} labelfont 1 labelsize 22 align 128
-      }
-    }
-  }
-  Function {SeqUI(Master *master_)} {open
-  } {
-    code {master=master_;
-
-make_window();} {}
-  }
-  decl {Master *master} {}
-  Function {show()} {open
-  } {
-    code {seqwin->show();} {}
-  }
-} 
diff --git a/src/UI/VirKeyboard.fl b/src/UI/VirKeyboard.fl
index d3f7016..cad04bd 100644
--- a/src/UI/VirKeyboard.fl
+++ b/src/UI/VirKeyboard.fl
@@ -1,5 +1,5 @@
 # data file for the Fltk User Interface Designer (fluid)
-version 1.0107 
+version 1.0110 
 header_name {.h} 
 code_name {.cc}
 decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} 
@@ -21,7 +21,7 @@ decl {\#include "../globals.h"} {public
 decl {\#include "../Misc/Master.h"} {public
 } 
 
-decl {\#include "../Input/MidiIn.h"} {public
+decl {\#include "../Misc/Util.h"} {selected public
 } 
 
 decl {\#include "WidgetPDial.h"} {public
@@ -41,6 +41,10 @@ decl {const int keysoct1qwertz[]={'q','2','w','3','e','r','5','t','6','z','7','u
 
 decl {const int keysoct2qwertz[]={'y','s','x','d','c','v','g','b','h','n','j','m',',','l','.',246,'-',0};} {} 
 
+decl {const int keysoct1az[]={'a',233,'z','\\"','e','r','(','t','-','y',232,'u','i',231,'o',224,'p',65106,'=','$',0};} {} 
+
+decl {const int keysoct2az[]={'w','s','x','d','c','v','g','b','h','n','j',',',';','l',':','m','!',0};} {} 
+
 class VirKeys {: {public Fl_Box}
 } {
   decl {static const int N_OCT=6;} {}
@@ -134,7 +138,7 @@ if ((event==FL_PUSH)||(event==FL_DRAG)||(event==FL_RELEASE)){
        };
    };
 
-   if (((event==FL_PUSH)||(event==FL_DRAG))&&
+   if ((kpos!=-1)&&((event==FL_PUSH)||(event==FL_DRAG))&&
        (Fl::event_shift()==0)) {
         presskey(kpos,1,1);
    };
@@ -158,6 +162,9 @@ if (config.cfg.VirKeybLayout==2) {
 }else if (config.cfg.VirKeybLayout==3) {
 	keysoct1=keysoct1qwertz;
 	keysoct2=keysoct2qwertz;
+}else if (config.cfg.VirKeybLayout==4) {
+	keysoct1=keysoct1az;
+	keysoct2=keysoct2az;
 };
 
 if ((event==FL_KEYDOWN)||(event==FL_KEYUP)){
@@ -177,8 +184,7 @@ if ((event==FL_KEYDOWN)||(event==FL_KEYUP)){
 
 return(1);} {}
   }
-  Function {presskey(int nk,int exclusive,int type)} {selected
-  } {
+  Function {presskey(int nk,int exclusive,int type)} {} {
     code {//Exclusive means that multiple keys can be pressed at once
 //when the user uses the shift key
 if (nk>=N_OCT*12) return;
@@ -199,7 +205,7 @@ if (rndvelocity!=0){
 };
 
 pthread_mutex_lock(&master->mutex);
- master->NoteOn(midich,nk+midioct*12,(int)vel);
+master->noteOn(midich,nk+midioct*12,(int)vel);
 pthread_mutex_unlock(&master->mutex);} {}
   }
   Function {relasekey(int nk,int type)} {} {
@@ -213,7 +219,7 @@ pressed[nk]=0;
 damage(1);
 
 pthread_mutex_lock(&master->mutex);
- master->NoteOff(midich,nk+12*midioct);
+master->noteOff(midich,nk+12*midioct);
 pthread_mutex_unlock(&master->mutex);} {}
   }
   Function {relaseallkeys(int type)} {} {
@@ -287,7 +293,7 @@ virkeyboardwindow->hide();}
         callback {int ctl=midictl;
 
 pthread_mutex_lock(&master->mutex);
- master->SetController(virkeys->midich,ctl,(int) o->value());
+master->setController(virkeys->midich,ctl,(int) o->value());
 pthread_mutex_unlock(&master->mutex);
 virkeys->take_focus();}
         tooltip {Controller value} xywh {605 10 15 115} type {Vert Fill} box ENGRAVED_BOX selection_color 229 labelsize 8 align 5 minimum 127 maximum 0 step 1 value 64 textsize 7
@@ -369,7 +375,7 @@ virkeys->take_focus();}
       Fl_Roller pitchwheelroller {
         label Pwh
         callback {pthread_mutex_lock(&master->mutex);
- master->SetController(virkeys->midich,C_pitchwheel,-(int) o->value());
+master->setController(virkeys->midich,C_pitchwheel,-(int) o->value());
 pthread_mutex_unlock(&master->mutex);
 virkeys->take_focus();}
         tooltip {Pitch Wheel} xywh {625 10 20 95} box PLASTIC_UP_BOX labelsize 8 align 1 when 3 minimum -8192 maximum 8192 step 64
@@ -403,6 +409,9 @@ virkeys->take_focus();} open
 midictl=75;
 make_window();} {}
   }
+  Function {~VirKeyboard()} {} {
+    code {delete virkeyboardwindow;} {}
+  }
   Function {show()} {} {
     code {virkeyboardwindow->show();} {}
   }
diff --git a/src/UI/WidgetPDial.cpp b/src/UI/WidgetPDial.cpp
new file mode 100644
index 0000000..3ad4f6a
--- /dev/null
+++ b/src/UI/WidgetPDial.cpp
@@ -0,0 +1,250 @@
+// generated by Fast Light User Interface Designer (fluid) version 1.0107f
+
+#include "WidgetPDial.h"
+#include <cstdio>
+#include <iostream>
+#include <cmath>
+#include <string>
+#include <FL/Fl_Tooltip.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Menu_Window.H>
+#include "../Misc/Util.h"
+//Copyright (c) 2003-2005 Nasca Octavian Paul
+//License: GNU GPL version 2 or later
+
+using namespace std;
+
+class TipWin:public Fl_Menu_Window
+{
+    public:
+        TipWin();
+        void draw();
+        void showValue(float f);
+        void setText(const char *c);
+        void showText();
+    private:
+        void redraw();
+        const char *getStr() const;
+        string tip;
+        string text;
+        bool   textmode;
+};
+
+TipWin::TipWin():Fl_Menu_Window(1, 1)
+{
+    set_override();
+    end();
+}
+
+void TipWin::draw()
+{
+    //setup window
+    draw_box(FL_BORDER_BOX, 0, 0, w(), h(), Fl_Color(175));
+    fl_color(FL_BLACK);
+    fl_font(labelfont(), labelsize());
+
+    //Draw the current string
+    fl_draw(getStr(), 3, 3, w() - 6, h() - 6,
+            Fl_Align(FL_ALIGN_LEFT | FL_ALIGN_WRAP));
+}
+
+void TipWin::showValue(float f)
+{
+    //convert the value to a string
+    char tmp[10];
+    snprintf(tmp, 9, "%.2f", f);
+    tip = tmp;
+
+    textmode = false;
+    redraw();
+    show();
+}
+
+void TipWin::setText(const char *c)
+{
+    text     = c;
+    textmode = true;
+    redraw();
+}
+
+void TipWin::showText()
+{
+    if(!text.empty()) {
+        textmode = true;
+        redraw();
+        show();
+    }
+}
+
+void TipWin::redraw()
+{
+    // Recalc size of window
+    fl_font(labelfont(), labelsize());
+    int W = 0, H = 0;
+    fl_measure(getStr(), W, H, 0);
+    //provide a bit of extra space
+    W += 8;
+    H += 4;
+    size(W, H);
+    Fl_Menu_Window::redraw();
+}
+
+const char *TipWin::getStr() const
+{
+    return (textmode ? text : tip).c_str();
+}
+
+//static int numobj = 0;
+
+WidgetPDial::WidgetPDial(int x, int y, int w, int h, const char *label)
+    :Fl_Dial(x, y, w, h, label), oldvalue(0.0f), pos(false), textset(false)
+{
+    //cout << "[" << label << "] There are now " << ++numobj << endl;
+    Fl_Group *save = Fl_Group::current();
+    tipwin = new TipWin();
+    tipwin->hide();
+    Fl_Group::current(save);
+}
+
+WidgetPDial::~WidgetPDial()
+{
+    //cout << "There are now " << --numobj << endl;
+    delete tipwin;
+}
+
+int WidgetPDial::handle(int event)
+{
+    double dragsize, min = minimum(), max = maximum();
+    int    my;
+
+    switch(event) {
+        case FL_PUSH:
+            oldvalue = value();
+        case FL_DRAG:
+            getPos();
+            tipwin->showValue(value());
+            my = -(Fl::event_y() - y() - h() / 2);
+
+            dragsize = 200.0f;
+            if(Fl::event_state(FL_BUTTON1) == 0)
+                dragsize *= 10;
+
+            value(limit(oldvalue + my / dragsize * (max - min), min, max));
+            value_damage();
+            if(this->when() != 0)
+                do_callback();
+            return 1;
+        case FL_ENTER:
+            getPos();
+            tipwin->showText();
+            return 1;
+        case FL_HIDE:
+        case FL_LEAVE:
+            tipwin->hide();
+            resetPos();
+            break;
+        case FL_RELEASE:
+            tipwin->hide();
+            resetPos();
+            if(this->when() == 0)
+                do_callback();
+            return 1;
+            break;
+    }
+    return 0;
+}
+
+void WidgetPDial::drawgradient(int cx, int cy, int sx, double m1, double m2)
+{
+    for(int i = (int)(m1 * sx); i < (int)(m2 * sx); i++) {
+        double tmp = 1.0f - powf(i * 1.0f / sx, 2.0f);
+        pdialcolor(140
+                   + (int) (tmp
+                            * 90), 140
+                   + (int)(tmp * 90), 140 + (int) (tmp * 100));
+        fl_arc(cx + sx / 2 - i / 2, cy + sx / 2 - i / 2, i, i, 0, 360);
+    }
+}
+
+void WidgetPDial::draw()
+{
+    int cx = x(), cy = y(), sx = w(), sy = h();
+
+    //clears the button face
+    pdialcolor(190, 190, 200);
+    fl_pie(cx - 1, cy - 1, sx + 2, sy + 2, 0, 360);
+
+    //Draws the button face (gradinet)
+    drawgradient(cx, cy, sx, 0.5f, 1.0f);
+
+    double val = (value() - minimum()) / (maximum() - minimum());
+
+    //draws the scale
+    pdialcolor(220, 220, 250);
+    double a1 = angle1(), a2 = angle2();
+    for(int i = 0; i < 12; i++) {
+        double a = -i / 12.0f * 360.0f - val * (a2 - a1) - a1;
+        fl_pie(cx, cy, sx, sy, a + 270 - 3, a + 3 + 270);
+    }
+
+    drawgradient(cx, cy, sx, 0.0f, 0.75f);
+
+    //draws the value
+    double a = -(a2 - a1) * val - a1;
+
+    //draws the max and min points
+    pdialcolor(0, 100, 200);
+    int xp =
+        (int)(cx + sx / 2.0f + sx / 2.0f * sinf(angle1() / 180.0f * 3.141592f));
+    int yp =
+        (int)(cy + sy / 2.0f + sy / 2.0f * cosf(angle1() / 180.0f * 3.141592f));
+    fl_pie(xp - 2, yp - 2, 4, 4, 0, 360);
+
+    xp = (int)(cx + sx / 2.0f + sx / 2.0f * sinf(angle2() / 180.0f * 3.141592f));
+    yp = (int)(cy + sy / 2.0f + sy / 2.0f * cosf(angle2() / 180.0f * 3.141592f));
+    fl_pie(xp - 2, yp - 2, 4, 4, 0, 360);
+
+    fl_push_matrix();
+
+    fl_translate(cx + sx / 2, cy + sy / 2);
+    fl_rotate(a - 90.0f);
+
+    fl_translate(sx / 2, 0);
+
+    fl_begin_polygon();
+    pdialcolor(0, 0, 0);
+    fl_vertex(-10, -4);
+    fl_vertex(-10, 4);
+    fl_vertex(0, 0);
+    fl_end_polygon();
+
+    fl_pop_matrix();
+}
+
+void WidgetPDial::pdialcolor(int r, int g, int b)
+{
+    if(active_r())
+        fl_color(r, g, b);
+    else
+        fl_color(160 - (160 - r) / 3, 160 - (160 - b) / 3, 160 - (160 - b) / 3);
+}
+
+void WidgetPDial::tooltip(const char *c)
+{
+    tipwin->setText(c);
+    textset = true;
+}
+
+void WidgetPDial::getPos()
+{
+    if(!pos) {
+        tipwin->position(Fl::event_x_root(), Fl::event_y_root() + 20);
+        pos = true;
+    }
+}
+
+void WidgetPDial::resetPos()
+{
+    pos = false;
+}
diff --git a/src/UI/WidgetPDial.fl b/src/UI/WidgetPDial.fl
deleted file mode 100644
index 0fed5b5..0000000
--- a/src/UI/WidgetPDial.fl
+++ /dev/null
@@ -1,251 +0,0 @@
-# data file for the Fltk User Interface Designer (fluid)
-version 1.0109 
-header_name {.h} 
-code_name {.cc}
-decl {//Copyright (c) 2003-2005 Nasca Octavian Paul} {} 
-
-decl {//License: GNU GPL version 2 or later} {} 
-
-decl {\#include <FL/Fl_Dial.H>} {public
-} 
-
-decl {\#include <FL/fl_draw.H>} {public
-} 
-
-decl {\#include <FL/Fl_Tooltip.H>} {public
-} 
-
-decl {\#include <math.h>} {public
-} 
-
-decl {\#include <string.h>} {public
-} 
-
-decl {\#include <stdio.h>} {public
-} 
-
-decl {\#include <FL/Fl_Group.H>} {public
-} 
-
-decl {\#include <FL/Fl_Menu_Window.H>} {public
-} 
-
-class TipWin {: {public Fl_Menu_Window}
-} {
-  Function {TipWin():Fl_Menu_Window(1,1)} {} {
-    code {strcpy(tip, "X.XX");
-set_override();
-end();} {}
-  }
-  Function {draw()} {return_type void
-  } {
-    code {draw_box(FL_BORDER_BOX, 0, 0, w(), h(), Fl_Color(175));
-        fl_color(FL_BLACK);
-        fl_font(labelfont(), labelsize());
-        if(textmode)
-             fl_draw(text, 3, 3, w()-6, h()-6, Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_WRAP));
-        else
-             fl_draw(tip, 3, 3, w()-6, h()-6, Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_WRAP));} {}
-  }
-  Function {value(float f)} {return_type void
-  } {
-    code {sprintf(tip, "%.2f", f);
-textmode=false;
-        // Recalc size of window
-        fl_font(labelfont(), labelsize());
-        int W = w(), H = h();
-        fl_measure(tip, W, H, 0);
-        W += 8;
-        size(W, H);
-        redraw();} {}
-  }
-  Function {setText(const char * c)} {return_type void
-  } {
-    code {strcpy(text,c);
-textmode=true;
-        // Recalc size of window
-        fl_font(labelfont(), labelsize());
-        int W = w(), H = h();
-        fl_measure(text, W, H, 0);
-        W += 8;
-        size(W, H);
-        redraw();} {}
-  }
-  Function {setTextmode()} {return_type void
-  } {
-    code {textmode=true;
-        // Recalc size of window
-        fl_font(labelfont(), labelsize());
-        int W = w(), H = h();
-        fl_measure(text, W, H, 0);
-        W += 8;
-        size(W, H);
-        redraw();} {}
-  }
-  decl {char tip[40];} {}
-  decl {bool textmode;} {}
-  decl {char text[400];//bad stuff will happen if too much is put in this (perhaps dynamically allocate?)} {}
-} 
-
-class WidgetPDial {: {public Fl_Dial}
-} {
-  Function {WidgetPDial(int x,int y, int w, int h, const char *label=0):Fl_Dial(x,y,w,h,label)} {} {
-    code {callback(value_cb, (void*)this);
-Fl_Group *save = Fl_Group::current();
-tipwin = new TipWin();
-tipwin->hide();
-Fl_Group::current(save);
-oldvalue=0.0;
-pos=false;
-textset=false;} {}
-  }
-  Function {~WidgetPDial()} {} {
-    code {delete tipwin;} {}
-  }
-  Function {handle(int event)} {return_type int
-  } {
-    code {double dragsize,v,min=minimum(),max=maximum();
-int my;
-
-switch (event){
-case FL_PUSH:
-     oldvalue=value();
-case FL_DRAG:
-     if(!pos){
-         tipwin->position(Fl::event_x_root(), Fl::event_y_root()+20);
-         pos=true;
-     }
-     tipwin->value(value());
-     tipwin->show();
-     my=-(Fl::event_y()-y()-h()/2);
-
-     dragsize=200.0;
-     if (Fl::event_state(FL_BUTTON1)==0) dragsize*=10;
-     v=oldvalue+my/dragsize*(max-min);
-     if (v<min) v=min;
-        else if (v>max) v=max;
-
-     //printf("%d   %g    %g\\n",my,v,oldvalue);     
-     value(v);
-     value_damage();
-     if (this->when()!=0) do_callback();
-     return(1); 
-     break;
-case FL_ENTER:
-     if(textset){
-         if(!pos){
-             tipwin->position(Fl::event_x_root(), Fl::event_y_root()+20);
-             pos=true;
-         }
-         tipwin->setTextmode();
-         tipwin->show();
-         return(1);} 
-     break;
-case FL_HIDE:
-case FL_LEAVE:
-     tipwin->hide();
-     pos=false;
-     break;
-case FL_RELEASE:
-     tipwin->hide();
-     pos=false;
-     if (this->when()==0) do_callback();
-	return(1);
-     break;
-};
-return(0);} {selected
-    }
-  }
-  Function {drawgradient(int cx,int cy,int sx,double m1,double m2)} {return_type void
-  } {
-    code {for (int i=(int)(m1*sx);i<(int)(m2*sx);i++){
-   double tmp=1.0-pow(i*1.0/sx,2.0);
-   pdialcolor(140+(int) (tmp*90),140+(int)(tmp*90),140+(int) (tmp*100));
-   fl_arc(cx+sx/2-i/2,cy+sx/2-i/2,i,i,0,360);
-};} {}
-  }
-  Function {draw()} {} {
-    code {int cx=x(),cy=y(),sx=w(),sy=h();
-
-
-//clears the button face
-pdialcolor(190,190,200);
-fl_pie(cx-1,cy-1,sx+2,sy+2,0,360);
-
-//Draws the button face (gradinet)
-drawgradient(cx,cy,sx,0.5,1.0);
-
-double val=(value()-minimum())/(maximum()-minimum());
-
-//draws the scale
-pdialcolor(220,220,250);
-double a1=angle1(),a2=angle2();
-for (int i=0;i<12;i++){
-   double a=-i/12.0*360.0-val*(a2-a1)-a1;
-   fl_pie(cx,cy,sx,sy,a+270-3,a+3+270);
-};
-
-drawgradient(cx,cy,sx,0.0,0.75);
-
-//draws the value
-double a=-(a2-a1)*val-a1;
-
-
-
-
-
-//draws the max and min points
-pdialcolor(0,100,200);
-int xp=(int)(cx+sx/2.0+sx/2.0*sin(angle1()/180.0*3.141592));
-int yp=(int)(cy+sy/2.0+sy/2.0*cos(angle1()/180.0*3.141592));
-fl_pie(xp-2,yp-2,4,4,0,360);
-
-xp=(int)(cx+sx/2.0+sx/2.0*sin(angle2()/180.0*3.141592));
-yp=(int)(cy+sy/2.0+sy/2.0*cos(angle2()/180.0*3.141592));
-fl_pie(xp-2,yp-2,4,4,0,360);
-
-
-
-
-
-fl_push_matrix();
-
-  fl_translate(cx+sx/2,cy+sy/2);
-  fl_rotate(a-90.0); 
-
-  fl_translate(sx/2,0);
-
-
-  fl_begin_polygon();
-   pdialcolor(0,0,0);
-   fl_vertex(-10,-4);
-   fl_vertex(-10,4);
-   fl_vertex(0,0);  
-  fl_end_polygon();
- 
-
-fl_pop_matrix();} {}
-  }
-  Function {pdialcolor(int r,int g,int b)} {} {
-    code {if (active_r()) fl_color(r,g,b);
-   else fl_color(160-(160-r)/3,160-(160-b)/3,160-(160-b)/3);} {}
-  }
-  Function {value_cb2()} {return_type void
-  } {
-    code {tipwin->value(value());} {}
-  }
-  Function {value_cb(Fl_Widget*, void*data)} {return_type {static void}
-  } {
-    code {WidgetPDial *val = (WidgetPDial*)data;
-        val->value_cb2();} {}
-  }
-  Function {tooltip(const char * c)} {return_type void
-  } {
-    code {tipwin->setText(c);
-textset=true;} {}
-  }
-  decl {bool textset;} {}
-  decl {bool pos;} {}
-  decl {double oldvalue;} {}
-  decl {TipWin *tipwin;} {}
-} 
diff --git a/src/UI/WidgetPDial.h b/src/UI/WidgetPDial.h
new file mode 100644
index 0000000..3f8cd71
--- /dev/null
+++ b/src/UI/WidgetPDial.h
@@ -0,0 +1,26 @@
+// generated by Fast Light User Interface Designer (fluid) version 1.0107f
+
+#ifndef WIDGETPDIAL_h
+#define WIDGETPDIAL_h
+#include <FL/Fl_Dial.H>
+
+
+class WidgetPDial:public Fl_Dial
+{
+    public:
+        WidgetPDial(int x, int y, int w, int h, const char *label = 0);
+        ~WidgetPDial();
+        int handle(int event);
+        void drawgradient(int cx, int cy, int sx, double m1, double m2);
+        void draw();
+        void pdialcolor(int r, int g, int b);
+        void tooltip(const char *c);
+    private:
+        void getPos();
+        void resetPos();
+        double oldvalue;
+        bool   pos;
+        bool   textset;
+        class TipWin * tipwin;
+};
+#endif
diff --git a/src/globals.h b/src/globals.h
index f13da7d..e0ec5c4 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -24,37 +24,8 @@
 
 #ifndef GLOBALS_H
 #define GLOBALS_H
+#include <stdint.h>
 
-//What float type I use for internal sampledata
-#define REALTYPE float
-
-struct FFTFREQS {
-    REALTYPE *s,*c;//sine and cosine components
-};
-
-extern void newFFTFREQS(FFTFREQS *f,int size);
-extern void deleteFFTFREQS(FFTFREQS *f);
-
-/**Sampling rate*/
-extern int SAMPLE_RATE;
-
-/**
- * The size of a sound buffer (or the granularity)
- * All internal transfer of sound data use buffer of this size
- * All parameters are constant during this period of time, exception
- * some parameters(like amplitudes) which are linear interpolated.
- * If you increase this you'll ecounter big latencies, but if you
- * decrease this the CPU requirements gets high.
- */
-extern int SOUND_BUFFER_SIZE;
-
-
-/**
- * The size of ADnote Oscillator
- * Decrease this => poor quality
- * Increase this => CPU requirements gets high (only at start of the note)
- */
-extern int OSCIL_SIZE;
 
 /**
  * The number of harmonics of additive synth
@@ -120,7 +91,7 @@ extern int OSCIL_SIZE;
 /*
  * How is applied the velocity sensing
  */
-#define VELOCITY_MAX_SCALE 8.0
+#define VELOCITY_MAX_SCALE 8.0f
 
 /*
  * The maximum length of instrument's name
@@ -131,7 +102,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
 
@@ -148,60 +119,79 @@ extern int OSCIL_SIZE;
 #define FF_MAX_FORMANTS 12
 #define FF_MAX_SEQUENCE 8
 
-#define LOG_2 0.693147181
-#define PI 3.1415926536
-#define LOG_10 2.302585093
+#define LOG_2 0.693147181f
+#define PI 3.1415926536f
+#define LOG_10 2.302585093f
 
 /*
  * The threshold for the amplitude interpolation used if the amplitude
  * is changed (by LFO's or Envelope's). If the change of the amplitude
  * is below this, the amplitude is not interpolated
  */
-#define AMPLITUDE_INTERPOLATION_THRESHOLD 0.0001
+#define AMPLITUDE_INTERPOLATION_THRESHOLD 0.0001f
 
 /*
  * 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.0f * fabs((b) - (a)) \
+                                          / (fabs((b) + (a) \
+                                                  + 0.0000000001f))) > \
+                                         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)) * (float)(x) \
+                                              / (float) (size))
 
 
 /*
  * dB
  */
-#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 ZERO(data,size) {char *data_=(char *) data;for (int i=0;i<size;i++) data_[i]=0;};
-
-enum ONOFFTYPE {OFF=0,ON=1};
+#define dB2rap(dB) ((expf((dB) * LOG_10 / 20.0f)))
+#define rap2dB(rap) ((20 * logf(rap) / LOG_10))
+
+#define ZERO(data, size) {char *data_ = (char *) data; for(int i = 0; \
+                                                           i < size; \
+                                                           i++) \
+                              data_[i] = 0; }
+#define ZERO_float(data, size) {float *data_ = (float *) data; \
+                                for(int i = 0; \
+                                    i < size; \
+                                    i++) \
+                                    data_[i] = 0.0f; }
+
+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_bankselectmsb = 0, C_pitchwheel = 1000, C_NULL = 1001,
+    C_expression    = 11, C_panning = 10, C_bankselectlsb = 32,
+    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.49999999f) \
+                                     : "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.0f)));
 #endif
 
 
@@ -210,5 +200,50 @@ enum LegatoMsg {LM_Norm, LM_FadeIn, LM_FadeOut, LM_CatchUp, LM_ToNorm};
 #define O_BINARY 0
 #endif
 
-#endif
+//temporary include for synth->{samplerate/buffersize} members
+struct SYNTH_T {
+    SYNTH_T(void)
+        :samplerate(44100), buffersize(256), oscilsize(1024)
+    {
+        alias();
+    }
+
+    /**Sampling rate*/
+    unsigned int samplerate;
+
+    /**
+     * The size of a sound buffer (or the granularity)
+     * All internal transfer of sound data use buffer of this size
+     * All parameters are constant during this period of time, exception
+     * some parameters(like amplitudes) which are linear interpolated.
+     * If you increase this you'll ecounter big latencies, but if you
+     * decrease this the CPU requirements gets high.
+     */
+    int buffersize;
+
+    /**
+     * The size of ADnote Oscillator
+     * Decrease this => poor quality
+     * Increase this => CPU requirements gets high (only at start of the note)
+     */
+    int oscilsize;
+
+    //Alias for above terms
+    float samplerate_f;
+    float halfsamplerate_f;
+    float buffersize_f;
+    int   bufferbytes;
+    float oscilsize_f;
+
+    inline void alias(void)
+    {
+        halfsamplerate_f = (samplerate_f = samplerate) / 2.0f;
+        buffersize_f     = buffersize;
+        bufferbytes      = buffersize * sizeof(float);
+        oscilsize_f      = oscilsize;
+    }
+    float numRandom(void) const; //defined in Util.cpp for now
+};
 
+extern SYNTH_T *synth;
+#endif
diff --git a/src/launch_zynaddsubfx.bat b/src/launch_zynaddsubfx.bat
deleted file mode 100644
index aa1a560..0000000
--- a/src/launch_zynaddsubfx.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-set PA_MIN_LATENCY_MSEC=70
-start zynaddsubfx.exe
-exit
diff --git a/src/main.cpp b/src/main.cpp
index f3054af..22a5836 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,7 +1,7 @@
 /*
   ZynAddSubFX - a software synthesizer
 
-  main.c  -  Main file of the synthesizer
+  main.cpp  -  Main file of the synthesizer
   Copyright (C) 2002-2005 Nasca Octavian Paul
   Author: Nasca Octavian Paul
 
@@ -20,39 +20,27 @@
 
 */
 
-#include <stdio.h>//remove once iostream is used
 #include <iostream>
+#include <cmath>
+#include <cctype>
+#include <algorithm>
+#include <signal.h>
 
 #include <unistd.h>
 #include <pthread.h>
 
-#ifdef OS_LINUX
 #include <getopt.h>
-#elif OS_WINDOIWS
-#include <winbase.h>
-#include <windows.h>
-#endif
 
 #include "Misc/Master.h"
+#include "Misc/Part.h"
 #include "Misc/Util.h"
 #include "Misc/Dump.h"
 extern Dump dump;
 
-#ifdef ALSAMIDIIN
-#include "Input/ALSAMidiIn.h"
-#endif
-
-#ifdef OSSMIDIIN
-#include "Input/OSSMidiIn.h"
-#endif
-
-#if (defined(NONEMIDIIN)||defined(VSTMIDIIN))
-#include "Input/NULLMidiIn.h"
-#endif
+#include <FL/Fl.H>
 
-#ifdef WINMIDIIN
-#include "Input/WINMidiIn.h"
-#endif
+//Nio System
+#include "Nio/Nio.h"
 
 #ifndef DISABLE_GUI
 #ifdef QT_GUI
@@ -72,775 +60,426 @@ 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 thr4;
+Master   *master;
+SYNTH_T  *synth;
+int       swaplr = 0; //1 for left-right swapping
 
-#ifdef JACKAUDIOOUT
-#include "Output/JACKaudiooutput.h"
-#endif
+int Pexitprogram = 0;     //if the UI set this to 1, the program will exit
 
-#ifdef JACK_RTAUDIOOUT
-#include "Output/JACKaudiooutput.h"
-#endif
-
-#ifdef PAAUDIOOUT
-#include "Output/PAaudiooutput.h"
-#endif
-
-#ifdef OSSAUDIOOUT
-#include "Output/OSSaudiooutput.h"
-OSSaudiooutput *audioout;
-#endif
-
-#ifdef USE_LASH
+#if LASH
 #include "Misc/LASHClient.h"
-LASHClient *lash;
+LASHClient *lash = NULL;
 #endif
 
-MidiIn *Midi;
-int Pexitprogram=0;//if the UI set this to 1, the program will exit
-
-/*
- * Try to get the realtime priority
- */
-void set_realtime()
-{
-#ifdef OS_LINUX
-    sched_param sc;
-
-    sc.sched_priority=50;
+#if USE_NSM
+#include "UI/NSM.H"
 
-    //if you want get "sched_setscheduler undeclared" from compilation, you can safely remove the folowing line
-    sched_setscheduler(0,SCHED_FIFO,&sc);
-//    if (err==0) printf("Real-time");
+NSM_Client *nsm = 0;
 #endif
-};
-
-/*
- * Midi input thread
- */
-#if !(defined(WINMIDIIN)||defined(VSTMIDIIN))
-void *thread1(void *arg)
-{
-    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;
 
-    set_realtime();
-    while (Pexitprogram==0) {
-        Midi->getmidicmd(cmdtype,cmdchan,cmdparams);
-        note=cmdparams[0];
-        vel=cmdparams[1];
+char *instance_name = 0;
 
-        pthread_mutex_lock(&master->mutex);
+void exitprogram();
 
-        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);
-};
-#endif
-
-/*
- * Wave output thread (for OSS AUDIO out)
- */
-#if defined(OSSAUDIOOUT)
-//!(defined(JACKAUDIOOUT)||defined(JACK_RTAUDIOOUT)||defined(PAAUDIOOUT)||defined(VSTAUDIOOUT))
-
-void *thread2(void *arg)
+//cleanup on signaled exit
+void sigterm_exit(int /*sig*/)
 {
-    REALTYPE outputl[SOUND_BUFFER_SIZE];
-    REALTYPE outputr[SOUND_BUFFER_SIZE];
-
-    set_realtime();
-    while (Pexitprogram==0) {
-        pthread_mutex_lock(&master->mutex);
-        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);
-};
-#endif
-
-/*
- * User Interface thread
- */
-
-
-void *thread3(void *arg)
-{
-#ifndef DISABLE_GUI
-
-#ifdef FLTK_GUI
-    ui->showUI();
-
-    while (Pexitprogram==0) {
-#ifdef USE_LASH
-        string filename;
-        switch (lash->checkevents(filename)) {
-        case LASHClient::Save:
-            ui->do_save_master(filename);
-            lash->confirmevent(LASHClient::Save);
-            break;
-        case LASHClient::Restore:
-            ui->do_load_master(filename);
-            lash->confirmevent(LASHClient::Restore);
-            break;
-        case LASHClient::Quit:
-            Pexitprogram = 1;
-        default:
-            break;
-        }
-#endif //USE_LASH
-        Fl::wait();
-    }
-
-#elif defined QT_GUI
-    app = new QApplication(0, 0);
-    ui=new MasterUI(master, 0);
-    ui->show();
-    app->exec();
-#endif //defined QT_GUI
-
-#endif //DISABLE_GUI
-    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;
-            do {
-                again=master->seq.getevent(ntrack,&midichan,&type,&par1,&par2);
-//		printf("ntrack=%d again=%d\n",ntrack,again);
-                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]);
-
-
-
-                    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);
-                    };
-                    pthread_mutex_unlock(&master->mutex);
-                };
-            } while (again>0);
-
-        };
-//if (!realtime player) atunci fac asta
-//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-#ifdef OS_LINUX
-        usleep(1000);
-#elif OS_WINDOWS
-        Sleep(1);
-#endif
-    };
-
-    return(0);
-};
+    Pexitprogram = 1;
+}
 
 /*
  * Program initialisation
  */
-
-
-void initprogram()
+void initprogram(void)
 {
     cerr.precision(1);
     cerr << std::fixed;
-#ifndef JACKAUDIOOUT
-#ifndef JACK_RTAUDIOOUT
-    cerr << "\nSample Rate = \t\t" << SAMPLE_RATE << endl;
-#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 << "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;
-
-    OscilGen::tmpsmps=new REALTYPE[OSCIL_SIZE];
-    newFFTFREQS(&OscilGen::outoscilFFTfreqs,OSCIL_SIZE/2);
-
-    master=new Master();
-    master->swaplr=swaplr;
-
-#if defined(JACKAUDIOOUT)
-    if (usejackit) {
-        bool tmp=JACKaudiooutputinit(master);
-#if defined(OSSAUDIOOUT)
-        if (!tmp) cout << "\nUsing OSS instead." << endl;
-#else
-        if (!tmp) exit(1);
-#endif
-        usejackit=tmp;
-    };
-#endif
-#if defined(OSSAUDIOOUT)
-    if (!usejackit) audioout=new OSSaudiooutput();
-    else audioout=NULL;
-#endif
+    cerr << "\nSample Rate = \t\t" << synth->samplerate << endl;
+    cerr << "Sound Buffer Size = \t" << synth->buffersize << " samples" << endl;
+    cerr << "Internal latency = \t" << synth->buffersize_f * 1000.0f
+    / synth->samplerate_f << " ms" << endl;
+    cerr << "ADsynth Oscil.Size = \t" << synth->oscilsize << " samples" << endl;
 
-#ifdef JACK_RTAUDIOOUT
-    JACKaudiooutputinit(master);
-#endif
-#ifdef PAAUDIOOUT
-    PAaudiooutputinit(master);
-#endif
 
-#ifdef ALSAMIDIIN
-    Midi=new ALSAMidiIn();
-#endif
-#ifdef OSSMIDIIN
-    Midi=new OSSMidiIn();
-#endif
-#if (defined(NONEMIDIIN)||(defined(VSTMIDIIN)))
-    Midi=new NULLMidiIn();
-#endif
-#ifndef DISABLE_GUI
-    ui=new MasterUI(master,&Pexitprogram);
-#endif
-};
+    master = &Master::getInstance();
+    master->swaplr = swaplr;
+
+    signal(SIGINT, sigterm_exit);
+    signal(SIGTERM, sigterm_exit);
+}
 
 /*
  * Program exit
  */
 void exitprogram()
 {
+    //ensure that everything has stopped with the mutex wait
     pthread_mutex_lock(&master->mutex);
-#ifdef OSSAUDIOOUT
-    delete(audioout);
-#endif
-#ifdef JACKAUDIOOUT
-    if (usejackit) JACKfinish();
-#endif
-#ifdef JACK_RTAUDIOOUT
-    JACKfinish();
-#endif
-#ifdef PAAUDIOOUT
-    PAfinish();
-#endif
+    pthread_mutex_unlock(&master->mutex);
+
+    Nio::stop();
 
 #ifndef DISABLE_GUI
-    delete(ui);
+    delete ui;
 #endif
-    delete(Midi);
-    delete(master);
-
-#ifdef USE_LASH
-    delete(lash);
+#if LASH
+    if(lash)
+        delete lash;
+#endif
+#if USE_NSM
+    if(nsm)
+        delete nsm;
 #endif
 
-//    pthread_mutex_unlock(&master->mutex);
     delete [] denormalkillbuf;
-    delete [] OscilGen::tmpsmps;
-    deleteFFTFREQS(&OscilGen::outoscilFFTfreqs);
-
-};
-
-#ifdef OS_WINDOWS
-#define ARGSIZE 100
-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]);
-            };
-        };
-    (*index)++;
-    return(result);
-};
-int opterr=0;
-#undef ARGSIZE
+}
 
-#endif
-
-#ifndef VSTAUDIOOUT
 int main(int argc, char *argv[])
 {
-
-#ifdef USE_LASH
-    lash = new LASHClient(&argc, &argv);
-#endif
-
+    synth = new SYNTH_T;
     config.init();
     dump.startnow();
-    int noui=0;
-#ifdef JACKAUDIOOUT
-    usejackit=true;//use jack by default
-#endif
-    cerr<<"\nZynAddSubFX - Copyright (c) 2002-2009 Nasca Octavian Paul and others"<<endl;
+    int noui = 0;
+    cerr
+    << "\nZynAddSubFX - Copyright (c) 2002-2011 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;
-#else
-    if (argc==1) cerr << "Try 'zynaddsubfx -h' for command-line options.\n" << endl;
-#endif
+    if(argc == 1)
+        cerr << "Try 'zynaddsubfx --help' for command-line options." << endl;
+
     /* 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;
+    synth->samplerate = config.cfg.SampleRate;
+    synth->buffersize = config.cfg.SoundBufferSize;
+    synth->oscilsize  = config.cfg.OscilSize;
+    swaplr = config.cfg.SwapStereo;
+
+    Nio::preferedSampleRate(synth->samplerate);
+
+    synth->alias(); //build aliases
+
+    sprng(time(NULL));
 
     /* 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'
+        },
+        {
+            "dummy", 2, NULL, 'Y'
+        },
+        {
+            "help", 2, NULL, 'h'
+        },
+        {
+            "version", 2, NULL, 'v'
+        },
+        {
+            "named", 1, NULL, 'N'
+        },
+        {
+            "auto-connect", 0, NULL, 'a'
+        },
+        {
+            "output", 1, NULL, 'O'
+        },
+        {
+            "input", 1, NULL, 'I'
+        },
+        {
+            "exec-after-init", 1, NULL, 'e'
+        },
+        {
+            0, 0, 0, 0
+        }
     };
-#endif
-    opterr=0;
-    int option_index=0,opt,exitwithhelp=0;
+    opterr = 0;
+    int option_index = 0, opt, exitwithhelp = 0, exitwithversion = 0;
+
+    string loadfile, loadinstrument, execAfterInit;
 
-    char loadfile[1001];
-    ZERO(loadfile,1001);
-    char loadinstrument[1001];
-    ZERO(loadinstrument,1001);
+    while(1) {
+        int tmp = 0;
 
-    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;
-#else
-        opt=getopt(argc,argv,"l:L:r:b:o:hSDUAY",&option_index);
-        char *optarguments=&winoptarguments[0];
-#endif
+        opt = getopt_long(argc,
+                          argv,
+                          "l:L:r:b:o:I:O:N:e:hvaSDUY",
+                          opts,
+                          &option_index);
+        char *optarguments = optarg;
 
-        if (opt==-1) break;
+#define GETOP(x) if(optarguments) \
+        x = optarguments
+#define GETOPNUM(x) if(optarguments) \
+        x = atoi(optarguments)
 
-        int tmp;
-        switch (opt) {
-        case 'h':
-            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.
-		      */
-            break;
-        case 'U':
-            noui=1;
-            break;
-        case 'A':
-#ifdef JACKAUDIOOUT
-#ifdef OSSAUDIOOUT
-            usejackit=false;
-#endif
-#endif
-            break;
-        case 'l':
-            tmp=0;
-            if (optarguments!=NULL) {
-                snprintf(loadfile,1000,"%s",optarguments);
-            };
-            break;
-        case 'L':
-            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 {
-                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 {
-                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 ";
-                cerr << OSCIL_SIZE << "." << endl;
-            }
-            break;
-        case 'S':
-            swaplr=1;
-            break;
-        case 'D':
-            dump.startnow();
-            break;
-        case '?':
-            cerr << "ERROR:Bad option or parameter.\n" << endl;
-            exitwithhelp=1;
+
+        if(opt == -1)
             break;
-        };
-    };
 
-    if (exitwithhelp!=0) {
-        cout << "Usage: zynaddsubfx [OPTION]\n" << 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 << "  -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 << "  -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;
-#ifdef JACKAUDIOOUT
-#ifdef OSSAUDIOOUT
-        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 << "  eg. instead '--buffer-size=512' use '-b 512'" << endl;
-#endif
-        cout << '\n' << endl;
-        return(0);
-    };
+        switch(opt) {
+            case 'h':
+                exitwithhelp = 1;
+                break;
+            case 'v':
+                exitwithversion = 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.
+                     */
+                break;
+            case 'U':
+                noui = 1;
+                break;
+            case 'l':
+                GETOP(loadfile);
+                break;
+            case 'L':
+                GETOP(loadinstrument);
+                break;
+            case 'r':
+                GETOPNUM(synth->samplerate);
+                if(synth->samplerate < 4000) {
+                    cerr << "ERROR:Incorrect sample rate: " << optarguments
+                         << endl;
+                    exit(1);
+                }
+                break;
+            case 'b':
+                GETOPNUM(synth->buffersize);
+                if(synth->buffersize < 2) {
+                    cerr << "ERROR:Incorrect buffer size: " << optarguments
+                         << endl;
+                    exit(1);
+                }
+                break;
+            case 'o':
+                if(optarguments)
+                    synth->oscilsize = tmp = atoi(optarguments);
+                if(synth->oscilsize < MAX_AD_HARMONICS * 2)
+                    synth->oscilsize = MAX_AD_HARMONICS * 2;
+                synth->oscilsize =
+                    (int) powf(2,
+                               ceil(logf(synth->oscilsize - 1.0f) / logf(2.0f)));
+                if(tmp != synth->oscilsize)
+                    cerr
+                    <<
+                    "synth->oscilsize is wrong (must be 2^n) or too small. Adjusting to "
+                    << synth->oscilsize << "." << endl;
+                break;
+            case 'S':
+                swaplr = 1;
+                break;
+            case 'D':
+                dump.startnow();
+                break;
+            case 'N':
+                Nio::setPostfix(optarguments);
+                break;
+            case 'I':
+                if(optarguments)
+                    Nio::setDefaultSource(optarguments);
+                break;
+            case 'O':
+                if(optarguments)
+                    Nio::setDefaultSink(optarguments);
+                break;
+            case 'a':
+                Nio::autoConnect = true;
+                break;
+            case 'e':
+                GETOP(execAfterInit);
+                break;
+            case '?':
+                cerr << "ERROR:Bad option or parameter.\n" << endl;
+                exitwithhelp = 1;
+                break;
+        }
+    }
 
-    //---------
+    synth->alias();
 
-    initprogram();
+    if(exitwithversion) {
+        cout << "Version: " << VERSION << endl;
+        return 0;
+    }
+    if(exitwithhelp != 0) {
+        cout << "Usage: zynaddsubfx [OPTION]\n\n"
+             << "  -h , --help \t\t\t\t Display command-line help and exit\n"
+             << "  -v , --version \t\t\t Display version and exit\n"
+             << "  -l file, --load=FILE\t\t\t Loads a .xmz file\n"
+             << "  -L file, --load-instrument=FILE\t Loads a .xiz file\n"
+             << "  -r SR, --sample-rate=SR\t\t Set the sample rate SR\n"
+             <<
+        "  -b BS, --buffer-size=SR\t\t Set the buffer size (granularity)\n"
+             << "  -o OS, --oscil-size=OS\t\t Set the ADsynth oscil. size\n"
+             << "  -S , --swap\t\t\t\t Swap Left <--> Right\n"
+             << "  -D , --dump\t\t\t\t Dumps midi note ON/OFF commands\n"
+             <<
+        "  -U , --no-gui\t\t\t\t Run ZynAddSubFX without user interface\n"
+             << "  -N , --named\t\t\t\t Postfix IO Name when possible\n"
+             << "  -a , --auto-connect\t\t\t AutoConnect when using JACK\n"
+             << "  -O , --output\t\t\t\t Set Output Engine\n"
+             << "  -I , --input\t\t\t\t Set Input Engine\n"
+             << "  -e , --exec-after-init\t\t Run post-initialization script\n"
+             << endl;
+
+        return 0;
+    }
 
-#ifdef USE_LASH
-#ifdef ALSAMIDIIN
-    ALSAMidiIn* alsamidi = dynamic_cast<ALSAMidiIn*>(Midi);
-    if (alsamidi)
-        lash->setalsaid(alsamidi->getalsaid());
-#endif
-#ifdef JACKAUDIOOUT
-    lash->setjackname(JACKgetname());
-#endif
-#endif
+    //produce denormal buf
+    denormalkillbuf = new float [synth->buffersize];
+    for(int i = 0; i < synth->buffersize; ++i)
+        denormalkillbuf[i] = (RND - 0.5f) * 1e-16;
+
+    initprogram();
 
-    if (strlen(loadfile)>1) {
-        int tmp=master->loadXML(loadfile);
-        if (tmp<0) {
-            fprintf(stderr,"ERROR:Could not load master file  %s .\n",loadfile);
+    if(!loadfile.empty()) {
+        int tmp = master->loadXML(loadfile.c_str());
+        if(tmp < 0) {
+            cerr << "ERROR: Could not load master file " << loadfile
+                 << "." << endl;
             exit(1);
-        } else {
+        }
+        else {
             master->applyparameters();
-#ifndef DISABLE_GUI
-            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(!loadinstrument.empty()) {
+        int loadtopart = 0;
+        int tmp = master->part[loadtopart]->loadXMLinstrument(
+            loadinstrument.c_str());
+        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();
-#endif
             cout << "Instrument file loaded." << endl;
-        };
-    };
-
-
-#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);
-#endif
-
-    /*It is not working and I don't know why
-    //drop the suid-root permisions
-    #if !(defined(JACKAUDIOOUT)||defined(PAAUDIOOUT)||defined(VSTAUDIOOUT)|| (defined (WINMIDIIN)) )
-          setuid(getuid());
-          seteuid(getuid());
-    //      setreuid(getuid(),getuid());
-    //      setregid(getuid(),getuid());
-    #endif
-    */
-    if (noui==0) pthread_create(&thr3,NULL,thread3,NULL);
-
-    pthread_create(&thr4,NULL,thread4,NULL);
-#ifdef WINMIDIIN
-    InitWinMidi(master);
-#endif
-
-    while (Pexitprogram==0) {
-#ifdef OS_LINUX
-        usleep(100000);
-#elif OS_WINDOWS
-        Sleep(100);
-#endif
-    };
-
-#ifdef WINMIDIIN
-    StopWinMidi();
-#endif
-
-    exitprogram();
-    return(0);
-};
-
-
-#else
-
-#include "Output/VSTaudiooutput.h"
-
-#define main main_plugin
-extern "C" __declspec(dllexport) AEffect *main_plugin(audioMasterCallback audioMaster);
-
-int instances=-1;
-
-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!=0) return(0);//don't allow multiple instances
-
-    AudioEffect *sintetizator=new VSTSynth(audioMaster);
-
-    return sintetizator->getAeffect();
-};
-
-void* hInstance;
-BOOL WINAPI DllMain (HINSTANCE hInst,DWORD dwReason,LPVOID lpvReserved)
-{
-    hInstance=hInst;
-    return(1);
-};
-
-void *thread(void *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);
-
-    /*    a=fopen("aaaa1","a");
-        fprintf(a,"%lx %lx %lx\n",vs,vs->ui->master,vs->vmaster);
-        fflush(a);fclose(a);
-    */
-
-    vs->ui->showUI();
-
-    /*    a=fopen("aaaa1","a");
-        fprintf(a,"%lx %lx %lx\n",vs,vs->ui,vs->vmaster);
-        fflush(a);fclose(a);
-    */
-
-    while (vs->Pexitprogram==0) Fl::wait(0.01);
-
-    delete(vs->ui);
-    Fl::wait(0.01);
-
-    /*    a=fopen("aaaa1","a");
-        fprintf(a,"EXIT\n");
-        fflush(a);fclose(a);
-    */
-
-
-    pthread_exit(0);
-    return(0);
-};
-
-//Parts of the VSTSynth class
-VSTSynth::VSTSynth (audioMasterCallback audioMaster):AudioEffectX(audioMaster,1,0)
-{
-    instances++;
-
-    if (audioMaster) {
-        setNumInputs(0);
-        setNumOutputs(2);
-        setUniqueID('ZASF');
-        canProcessReplacing();
-//    hasVu(false);
-//    hasClip(false);
-
-        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;
-
-    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);
-
-//    suspend();
+        }
+    }
 
-};
+    //Run the Nio system
+    bool ioGood = Nio::start();
 
+    if(!execAfterInit.empty()) {
+        cout << "Executing user supplied command: " << execAfterInit << endl;
+        if(system(execAfterInit.c_str()) == -1)
+            cerr << "Command Failed..." << endl;
+    }
 
 
-VSTSynth::~VSTSynth()
-{
-    this->Pexitprogram=1;
+#ifndef DISABLE_GUI
+    ui = new MasterUI(master, &Pexitprogram);
 
-    Sleep(200);//wait the thread to finish
+    if(!noui) {
+        ui->showUI();
 
-//    pthread_mutex_lock(&vmaster->mutex);
+        if(!ioGood)
+            fl_alert(
+                "Default IO did not initialize.\nDefaulting to NULL backend.");
+    }
 
+#endif
 
-    delete(this->vmaster);
+#ifndef DISABLE_GUI
+#if USE_NSM
+    char *nsm_url = getenv("NSM_URL");
 
-    instances--;
-};
+    if(nsm_url) {
+        nsm = new NSM_Client;
 
-long VSTSynth::processEvents(VstEvents *events)
-{
-    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;
-        int cntl;
-
-        pthread_mutex_lock(&vmaster->mutex);
-        switch (status) {
-        case 0x8:
-            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);
-            break;
-        case 0xB:
-            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);
-            break;
-        };
-        pthread_mutex_unlock(&vmaster->mutex);
+        if(!nsm->init(nsm_url))
+            nsm->announce("ZynAddSubFX", ":switch:", argv[0]);
+        else {
+            delete nsm;
+            nsm = NULL;
+        }
+    }
+#endif
+#endif
 
-    };
+#if USE_NSM
+    if(!nsm)
+#endif
+    {
+#if LASH
+        lash = new LASHClient(&argc, &argv);
+#ifndef DISABLE_GUI
+        ui->sm_indicator1->value(1);
+        ui->sm_indicator2->value(1);
+        ui->sm_indicator1->tooltip("LASH");
+        ui->sm_indicator2->tooltip("LASH");
+#endif
+#endif
+    }
 
-    return(1);
-};
+    while(Pexitprogram == 0) {
+#ifndef DISABLE_GUI
+#if USE_NSM
+        if(nsm) {
+            nsm->check();
+            goto done;
+        }
+#endif
+#if LASH
+        {
+            string filename;
+            switch(lash->checkevents(filename)) {
+                case LASHClient::Save:
+                    ui->do_save_master(filename.c_str());
+                    lash->confirmevent(LASHClient::Save);
+                    break;
+                case LASHClient::Restore:
+                    ui->do_load_master(filename.c_str());
+                    lash->confirmevent(LASHClient::Restore);
+                    break;
+                case LASHClient::Quit:
+                    Pexitprogram = 1;
+                default:
+                    break;
+            }
+        }
+#endif //LASH
 
-long VSTSynth::getChunk(void** data,bool isPreset)
-{
-    int size=0;
-    size=vmaster->getalldata((char **)data);
-    return((long)size);
-};
+done:
 
-long VSTSynth::setChunk(void *data,long size,bool isPreset)
-{
-    vmaster->putalldata((char*)data,size);
-    return(0);
-};
+        Fl::wait(0.1f);
+#else
+        usleep(100000);
 #endif
+    }
 
+    exitprogram();
+    return 0;
+}
diff --git a/src/zynaddsubfx.nsi b/src/zynaddsubfx.nsi
deleted file mode 100644
index 11feefb..0000000
--- a/src/zynaddsubfx.nsi
+++ /dev/null
@@ -1,181 +0,0 @@
-; Script generated by the HM NIS Edit Script Wizard and modified by Nasca Paul.
-
-; HM NIS Edit Wizard helper defines
-!define PRODUCT_NAME "ZynAddSubFX"
-!define PRODUCT_VERSION "2.2.0"
-!define PRODUCT_PUBLISHER "Nasca Octavian Paul"
-!define PRODUCT_WEB_SITE "http://zynaddsubfx.sourceforge.net"
-!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\zynaddsubfx.exe"
-!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
-!define PRODUCT_UNINST_ROOT_KEY "HKLM"
-
-SetCompressor lzma
-
-; MUI 1.67 compatible ------
-!include "MUI.nsh"
-
-; MUI Settings
-!define MUI_ABORTWARNING
-!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico"
-!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
-/*
-var VSTDIR ;
-
-Function .onInit
-;         StrCpy  "$INSTDIR" $VSTDIR
-FunctionEnd
-*/
-
-; Welcome page
-!insertmacro MUI_PAGE_WELCOME
-; License page
-!insertmacro MUI_PAGE_LICENSE "COPYING.txt"
-; Components page
-!insertmacro MUI_PAGE_COMPONENTS
-; Directory page
-!insertmacro MUI_PAGE_DIRECTORY
-/*
-;VST directory
-PageEx directory
-       DirVar $VSTDIR
-PageExEnd
-*/
-
-; Instfiles page
-!insertmacro MUI_PAGE_INSTFILES
-; Finish page
-!insertmacro MUI_PAGE_FINISH
-
-; Uninstaller pages
-!insertmacro MUI_UNPAGE_INSTFILES
-
-; Language files
-!insertmacro MUI_LANGUAGE "English"
-
-; Reserve files
-!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
-
-; MUI end ------
-
-
-Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
-OutFile "Setup_ZynAddSubFX.exe"
-InstallDir "$PROGRAMFILES\ZynAddSubFX"
-InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
-;ShowInstDetails show
-;ShowUnInstDetails show
-
-
-Section "-Required" SEC01
-  SetOutPath "$INSTDIR"
-  SetOverwrite ifnewer
-  File "README.txt"
-  File "HISTORY.txt"
-  File "FAQ.txt"
-  File "COPYING.txt"
-  File "ChangeLog.txt"
-  File "bugs.txt"
-;  File "Warning.txt"
-  File "zynaddsubfx_icon.ico"
-  File /r "banks"
-  File /r "examples"
-  File /r "presets"
-
-  SetOutPath "$SYSDIR"
-  File "pthreadGC1.dll"
-SectionEnd
-
-Section "Standalone" SEC02
-  SetOutPath "$INSTDIR"
-  File "zynaddsubfx.exe"
-  File "launch_zynaddsubfx.bat"
-  CreateDirectory "$SMPROGRAMS\ZynAddSubFX"
-  CreateShortCut "$SMPROGRAMS\ZynAddSubFX\ZynAddSubFX low latency.lnk" "$INSTDIR\launch_zynaddsubfx.bat" "-Y" "$INSTDIR\zynaddsubfx_icon.ico" 
-  CreateShortCut "$SMPROGRAMS\ZynAddSubFX\ZynAddSubFX.lnk" "$INSTDIR\zynaddsubfx.exe" "-Y" "$INSTDIR\zynaddsubfx_icon.ico"
-  CreateShortCut "$DESKTOP\ZynAddSubFX.lnk" "$INSTDIR\launch_zynaddsubfx.bat" "-Y" "$INSTDIR\zynaddsubfx_icon.ico"
-SectionEnd
-
-;Section /o "VST Plugin" SEC03
-;  SetOutPath "$INSTDIR\VST"
-;  File "zynaddsubfx_vst.dll"
-;SectionEnd
-
-Section /o "Source Code" SEC04
-  SetOutPath "$INSTDIR"
-  File /r "source code"
-SectionEnd
-
-Section -AdditionalIcons
-  WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}"
-  CreateShortCut "$SMPROGRAMS\ZynAddSubFX\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url"
-
-; sa sterg uninstall icon
-  CreateShortCut "$SMPROGRAMS\ZynAddSubFX\Uninstall.lnk" "$INSTDIR\uninst.exe"
-SectionEnd
-
-Section -Post
-  WriteUninstaller "$INSTDIR\uninst.exe"
-  WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\zynaddsubfx.exe"
-  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
-  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe"
-  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\zynaddsubfx.exe"
-  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
-  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
-  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
-SectionEnd
-
-; Section descriptions
-!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
-  !insertmacro MUI_DESCRIPTION_TEXT ${SEC01} "Required files for ZynAddSubFX "
-  !insertmacro MUI_DESCRIPTION_TEXT ${SEC02} "ZynAddSubFX as a standalone synth"
-;  !insertmacro MUI_DESCRIPTION_TEXT ${SEC03} "ZynAddSubFX as a VST plugin (not stable on every host)"
-  !insertmacro MUI_DESCRIPTION_TEXT ${SEC04} "Full source code of ZynAddSubFX"
-!insertmacro MUI_FUNCTION_DESCRIPTION_END
-
-
-Function un.onUninstSuccess
-  HideWindow
-  MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer."
-FunctionEnd
-
-Function un.onInit
-  MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Are you sure you want to completely remove $(^Name) and all of its components? $\r (INCLUDING THE USER-MADE INSTRUMENTS,ETC !!!)" IDYES +2
-  Abort
-FunctionEnd
-
-Section Uninstall
-  Delete "$INSTDIR\README.txt"
-  Delete "$INSTDIR\HISTORY.txt"
-  Delete "$INSTDIR\FAQ.txt"
-  Delete "$INSTDIR\COPYING.txt"
-  Delete "$INSTDIR\ChangeLog.txt"
-  Delete "$INSTDIR\bugs.txt"
-  Delete "$INSTDIR\Warning.txt"
-  Delete "$INSTDIR\zynaddsubfx.exe"
-  Delete "$INSTDIR\zynaddsubfx.url"
-  Delete "$INSTDIR\launch_zynaddsubfx.bat"
-  Delete "$INSTDIR\zynaddsubfxXML.cfg"
-  Delete "$INSTDIR\uninst.exe"
-  Delete "$INSTDIR\zynaddsubfx.ico"
-  Delete "$INSTDIR\zynaddsubfx_icon.ico"
-  RMDir /r "$INSTDIR\banks"
-  RMDir /r "$INSTDIR\examples"
-  RMDir /r "$INSTDIR\presets"
-  RMDir /r "$INSTDIR\source code"
-  RMDir /r "$INSTDIR\VST"
-
-  Delete "$SMPROGRAMS\ZynAddSubFX\Uninstall.lnk"
-  Delete "$SMPROGRAMS\ZynAddSubFX\Website.lnk"
-  Delete "$STARTMENU.lnk"
-  Delete "$DESKTOP\ZynAddSubFX.lnk"
-  Delete "$SMPROGRAMS\ZynAddSubFX\ZynAddSubFX.lnk"
-  Delete "$SMPROGRAMS\ZynAddSubFX\ZynAddSubFX low latency.lnk"
-
-  RMDir "$SMPROGRAMS\ZynAddSubFX"
-  RMDir "$INSTDIR"
-  RMDir ""
-
-  DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
-  DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"
-  SetAutoClose true
-SectionEnd
diff --git a/src/zynaddsubfx_gcc.def b/src/zynaddsubfx_gcc.def
deleted file mode 100644
index 191df4e..0000000
--- a/src/zynaddsubfx_gcc.def
+++ /dev/null
@@ -1,3 +0,0 @@
-LIBRARY			ZYNADDSUBFX
-DESCRIPTION		'ZynAddSubFX for VST'
-EXPORTS			main=main_plugin
diff --git a/style.cfg b/style.cfg
new file mode 100644
index 0000000..ba66d99
--- /dev/null
+++ b/style.cfg
@@ -0,0 +1,1218 @@
+# Uncrustify 0.53
+
+#
+# General options
+#
+
+# The type of line endings
+newlines                                 = lf       # auto/lf/crlf/cr
+
+# The original size of tabs in the input
+input_tab_size                           = 4        # number
+
+# The size of tabs in the output (only used if align_with_tabs=true)
+output_tab_size                          = 4        # number
+
+# The ascii value of the string escape char, usually 92 (\) or 94 (^). (Pawn)
+string_escape_char                       = 92       # number
+
+# Alternate string escape char for Pawn. Only works right before the quote char.
+string_escape_char2                      = 0        # number
+
+#
+# Indenting
+#
+
+# The number of columns to indent per level.
+# Usually 2, 3, 4, or 8.
+indent_columns                           = 4        # number
+
+# How to use tabs when indenting code
+# 0=spaces only
+# 1=indent with tabs, align with spaces
+# 2=indent and align with tabs
+indent_with_tabs                         = 0        # number
+
+# Whether to indent strings broken by '\' so that they line up
+indent_align_string                      = true    # false/true
+
+# The number of spaces to indent multi-line XML strings.
+# Requires indent_align_string=True
+indent_xml_string                        = 0        # number
+
+# Spaces to indent '{' from level
+indent_brace                             = 0        # number
+
+# Whether braces are indented to the body level
+indent_braces                            = false    # false/true
+
+# Disabled indenting function braces if indent_braces is true
+indent_braces_no_func                    = false    # false/true
+
+# Indent based on the size of the brace parent, ie 'if' => 3 spaces, 'for' => 4 spaces, etc.
+indent_brace_parent                      = false    # false/true
+
+# Whether the 'namespace' body is indented
+indent_namespace                         = true    # false/true
+
+# Whether the 'extern "C"' body is indented
+indent_extern                            = true    # false/true
+
+# Whether the 'class' body is indented
+indent_class                             = true    # false/true
+
+# Whether to indent the stuff after a leading class colon
+indent_class_colon                       = true    # false/true
+
+# False=treat 'else\nif' as 'else if' for indenting purposes
+# True=indent the 'if' one level
+indent_else_if                           = false    # false/true
+
+# Amount to indent variable declarations after a open brace. neg=relative, pos=absolute
+indent_var_def_blk                       = 0        # number
+
+# True:  indent continued function call parameters one indent level
+# False: align parameters under the open paren
+indent_func_call_param                   = false    # false/true
+
+# Same as indent_func_call_param, but for function defs
+indent_func_def_param                    = false    # false/true
+
+# Same as indent_func_call_param, but for function protos
+indent_func_proto_param                  = false    # false/true
+
+# Same as indent_func_call_param, but for class declarations
+indent_func_class_param                  = false    # false/true
+
+# Same as indent_func_call_param, but for class variable constructors
+indent_func_ctor_var_param               = false    # false/true
+
+# Same as indent_func_call_param, but for templates
+indent_template_param                    = false    # false/true
+
+# Double the indent for indent_func_xxx_param options
+indent_func_param_double                 = false    # false/true
+
+# Indentation column for standalone 'const' function decl/proto qualifier
+indent_func_const                        = 0        # number
+
+# Indentation column for standalone 'throw' function decl/proto qualifier
+indent_func_throw                        = 0        # number
+
+# The number of spaces to indent a continued '->' or '.'
+# Usually set to 0, 1, or indent_columns.
+indent_member                            = 0        # number
+
+# Spaces to indent single line ('//') comments on lines before code
+indent_sing_line_comments                = 0        # number
+
+# If set, will indent trailing single line ('//') comments relative
+# to the code instead of trying to keep the same absolute column
+indent_relative_single_line_comments     = false    # false/true
+
+# Spaces to indent 'case' from 'switch'
+# Usually 0 or indent_columns.
+indent_switch_case                       = 4        # number
+
+# Spaces to shift the 'case' line, without affecting any other lines
+# Usually 0.
+indent_case_shift                        = 0        # number
+
+# Spaces to indent '{' from 'case'.
+# By default, the brace will appear under the 'c' in case.
+# Usually set to 0 or indent_columns.
+indent_case_brace                        = 0        # number
+
+# Whether to indent comments found in first column
+indent_col1_comment                      = false    # false/true
+
+# How to indent goto labels
+#  >0 : absolute column where 1 is the leftmost column
+#  <=0 : subtract from brace indent
+indent_label                             = 1        # number
+
+# Same as indent_label, but for access specifiers that are followed by a colon
+indent_access_spec                       = 1        # number
+
+# Indent the code after an access specifier by one level.
+# If set, this option forces 'indent_access_spec=0'
+indent_access_spec_body                  = true    # false/true
+
+# If an open paren is followed by a newline, indent the next line so that it lines up after the open paren (not recommended)
+indent_paren_nl                          = false    # false/true
+
+# Controls the indent of a close paren after a newline.
+# 0: Indent to body level
+# 1: Align under the open paren
+# 2: Indent to the brace level
+indent_paren_close                       = 1        # number
+
+# Controls the indent of a comma when inside a paren.If TRUE, aligns under the open paren
+indent_comma_paren                       = false    # false/true
+
+# Controls the indent of a BOOL operator when inside a paren.If TRUE, aligns under the open paren
+indent_bool_paren                        = false    # false/true
+
+# If an open square is followed by a newline, indent the next line so that it lines up after the open square (not recommended)
+indent_square_nl                         = false    # false/true
+
+# Don't change the relative indent of ESQL/C 'EXEC SQL' bodies
+indent_preserve_sql                      = false    # false/true
+
+# Align continued statements at the '='. Default=True
+# If FALSE or the '=' is followed by a newline, the next line is indent one tab.
+indent_align_assign                      = true     # false/true
+
+#
+# Spacing options
+#
+
+# Add or remove space around arithmetic operator '+', '-', '/', '*', etc
+sp_arith                                 = force      # ignore/add/remove/force
+
+# Add or remove space around assignment operator '=', '+=', etc
+sp_assign                                = force      # ignore/add/remove/force
+
+# Add or remove space before assignment operator '=', '+=', etc. Overrides sp_assign.
+sp_before_assign                         = ignore   # ignore/add/remove/force
+
+# Add or remove space after assignment operator '=', '+=', etc. Overrides sp_assign.
+sp_after_assign                          = ignore   # ignore/add/remove/force
+
+# Add or remove space around assignment '=' in enum
+sp_enum_assign                           = force      # ignore/add/remove/force
+
+# Add or remove space before assignment '=' in enum. Overrides sp_enum_assign.
+sp_enum_before_assign                    = ignore   # ignore/add/remove/force
+
+# Add or remove space after assignment '=' in enum. Overrides sp_enum_assign.
+sp_enum_after_assign                     = ignore   # ignore/add/remove/force
+
+# Add or remove space around preprocessor '##' concatenation operator
+sp_pp_concat                             = add      # ignore/add/remove/force
+
+# Add or remove space after preprocessor '#' stringify operator
+sp_pp_stringify                          = add      # ignore/add/remove/force
+
+# Add or remove space around boolean operators '&&' and '||'
+sp_bool                                  = force      # ignore/add/remove/force
+
+# Add or remove space around compare operator '<', '>', '==', etc
+sp_compare                               = force      # ignore/add/remove/force
+
+# Add or remove space inside '(' and ')'
+sp_inside_paren                          = remove   # ignore/add/remove/force
+
+# Add or remove space between nested parens
+sp_paren_paren                           = remove   # ignore/add/remove/force
+
+# Whether to balance spaces inside nested parens
+sp_balance_nested_parens                 = false    # false/true
+
+# Add or remove space between ')' and '{'
+sp_paren_brace                           = force   # ignore/add/remove/force
+
+# Add or remove space before pointer star '*'
+sp_before_ptr_star                       = force   # ignore/add/remove/force
+
+# Add or remove space before pointer star '*' that isn't followed by a variable name
+# If set to 'ignore', sp_before_ptr_star is used instead.
+sp_before_unnamed_ptr_star               = ignore   # ignore/add/remove/force
+
+# Add or remove space between pointer stars '*'
+sp_between_ptr_star                      = remove   # ignore/add/remove/force
+
+# Add or remove space after pointer star '*', if followed by a word.
+sp_after_ptr_star                        = remove   # ignore/add/remove/force
+
+# Add or remove space after a pointer star '*', if followed by a func proto/def.
+sp_after_ptr_star_func                   = remove   # ignore/add/remove/force
+
+# Add or remove space before a pointer star '*', if followed by a func proto/def.
+sp_before_ptr_star_func                  = force   # ignore/add/remove/force
+
+# Add or remove space before a reference sign '&'
+sp_before_byref                          = force   # ignore/add/remove/force
+
+# Add or remove space before a reference sign '&' that isn't followed by a variable name
+# If set to 'ignore', sp_before_byref is used instead.
+sp_before_unnamed_byref                  = ignore   # ignore/add/remove/force
+
+# Add or remove space after reference sign '&', if followed by a word.
+sp_after_byref                           = remove   # ignore/add/remove/force
+
+# Add or remove space after a reference sign '&', if followed by a func proto/def.
+sp_after_byref_func                      = ignore   # ignore/add/remove/force
+
+# Add or remove space before a reference sign '&', if followed by a func proto/def.
+sp_before_byref_func                     = ignore   # ignore/add/remove/force
+
+# Add or remove space between type and word
+sp_after_type                            = remove    # ignore/add/remove/force
+
+# Add or remove space in 'template <' vs 'template<'.
+# If set to ignore, sp_before_angle is used.
+sp_template_angle                        = ignore   # ignore/add/remove/force
+
+# Add or remove space before '<>'
+sp_before_angle                          = remove   # ignore/add/remove/force
+
+# Add or remove space inside '<' and '>'
+sp_inside_angle                          = remove   # ignore/add/remove/force
+
+# Add or remove space after '<>'
+sp_after_angle                           = ignore   # ignore/add/remove/force
+
+# Add or remove space between '<>' and '(' as found in 'new List<byte>();'
+sp_angle_paren                           = remove   # ignore/add/remove/force
+
+# Add or remove space between '<>' and a word as in 'List<byte> m;'
+sp_angle_word                            = ignore   # ignore/add/remove/force
+
+# Add or remove space before '(' of 'if', 'for', 'switch', and 'while'
+sp_before_sparen                         = remove   # ignore/add/remove/force
+
+# Add or remove space inside if-condition '(' and ')'
+sp_inside_sparen                         = remove   # ignore/add/remove/force
+
+# Add or remove space before if-condition ')'. Overrides sp_inside_sparen.
+sp_inside_sparen_close                   = remove   # ignore/add/remove/force
+
+# Add or remove space after ')' of 'if', 'for', 'switch', and 'while'
+sp_after_sparen                          = remove   # ignore/add/remove/force
+
+# Add or remove space between ')' and '{' of 'if', 'for', 'switch', and 'while'
+sp_sparen_brace                          = force   # ignore/add/remove/force
+
+# Add or remove space between 'invariant' and '(' in the D language.
+sp_invariant_paren                       = ignore   # ignore/add/remove/force
+
+# Add or remove space after the ')' in 'invariant (C) c' in the D language.
+sp_after_invariant_paren                 = ignore   # ignore/add/remove/force
+
+# Add or remove space before empty statement ';' on 'if', 'for' and 'while'
+sp_special_semi                          = ignore   # ignore/add/remove/force
+
+# Add or remove space before ';'
+sp_before_semi                           = remove   # ignore/add/remove/force
+
+# Add or remove space before ';' in non-empty 'for' statements
+sp_before_semi_for                       = remove   # ignore/add/remove/force
+
+# Add or remove space before a semicolon of an empty part of a for statment.
+sp_before_semi_for_empty                 = remove   # ignore/add/remove/force
+
+# Add or remove space after the final semicolon of an empty part of a for statment: for ( ; ; <here> ).
+sp_after_semi_for_empty                  = remove   # ignore/add/remove/force
+
+# Add or remove space before '[' (except '[]')
+sp_before_square                         = ignore   # ignore/add/remove/force
+
+# Add or remove space before '[]'
+sp_before_squares                        = ignore   # ignore/add/remove/force
+
+# Add or remove space inside '[' and ']'
+sp_inside_square                         = remove   # ignore/add/remove/force
+
+# Add or remove space after ','
+sp_after_comma                           = force   # ignore/add/remove/force
+
+# Add or remove space before ','
+sp_before_comma                          = remove   # ignore/add/remove/force
+
+# Add or remove space after class ':'
+sp_after_class_colon                     = remove   # ignore/add/remove/force
+
+# Add or remove space before class ':'
+sp_before_class_colon                    = remove   # ignore/add/remove/force
+
+# Add or remove space before case ':'
+sp_before_case_colon                     = remove   # ignore/add/remove/force
+
+# Add or remove space between 'operator' and operator sign
+sp_after_operator                        = ignore   # ignore/add/remove/force
+
+# Add or remove space between the operator symbol and the open paren, as in 'operator ++('
+sp_after_operator_sym                    = ignore   # ignore/add/remove/force
+
+# Add or remove space after C/D cast, ie 'cast(int)a' vs 'cast(int) a' or '(int)a' vs '(int) a'
+sp_after_cast                            = ignore   # ignore/add/remove/force
+
+# Add or remove spaces inside cast parens
+sp_inside_paren_cast                     = remove   # ignore/add/remove/force
+
+# Add or remove space between the type and open paren in a C++ cast, ie 'int(exp)' vs 'int (exp)'
+sp_cpp_cast_paren                        = remove   # ignore/add/remove/force
+
+# Add or remove space between 'sizeof' and '('
+sp_sizeof_paren                          = remove   # ignore/add/remove/force
+
+# Add or remove space after the tag keyword (Pawn)
+sp_after_tag                             = ignore   # ignore/add/remove/force
+
+# Add or remove space inside enum '{' and '}'
+sp_inside_braces_enum                    = ignore   # ignore/add/remove/force
+
+# Add or remove space inside struct/union '{' and '}'
+sp_inside_braces_struct                  = remove   # ignore/add/remove/force
+
+# Add or remove space inside '{' and '}'
+sp_inside_braces                         = ignore   # ignore/add/remove/force
+
+# Add or remove space inside '{}'
+sp_inside_braces_empty                   = ignore   # ignore/add/remove/force
+
+# Add or remove space between return type and function name
+# A minimum of 1 is forced except for pointer return types.
+sp_type_func                             = ignore   # ignore/add/remove/force
+
+# Add or remove space between function name and '(' on function declaration
+sp_func_proto_paren                      = remove   # ignore/add/remove/force
+
+# Add or remove space between function name and '(' on function definition
+sp_func_def_paren                        = remove   # ignore/add/remove/force
+
+# Add or remove space inside empty function '()'
+sp_inside_fparens                        = remove   # ignore/add/remove/force
+
+# Add or remove space inside function '(' and ')'
+sp_inside_fparen                         = remove   # ignore/add/remove/force
+
+# Add or remove space between ']' and '(' when part of a function call.
+sp_square_fparen                         = ignore   # ignore/add/remove/force
+
+# Add or remove space between ')' and '{' of function
+sp_fparen_brace                          = force   # ignore/add/remove/force
+
+# Add or remove space between function name and '(' on function calls
+sp_func_call_paren                       = remove   # ignore/add/remove/force
+
+# Add or remove space between the user function name and '(' on function calls
+# You need to set a keyword to be a user function, like this: 'set func_call_user _' in the config file.
+sp_func_call_user_paren                  = ignore   # ignore/add/remove/force
+
+# Add or remove space between a constructor/destructor and the open paren
+sp_func_class_paren                      = remove   # ignore/add/remove/force
+
+# Add or remove space between 'return' and '('
+sp_return_paren                          = remove   # ignore/add/remove/force
+
+# Add or remove space between '__attribute__' and '('
+sp_attribute_paren                       = ignore   # ignore/add/remove/force
+
+# Add or remove space between 'defined' and '(' in '#if defined (FOO)'
+sp_defined_paren                         = ignore   # ignore/add/remove/force
+
+# Add or remove space between 'throw' and '(' in 'throw (something)'
+sp_throw_paren                           = ignore   # ignore/add/remove/force
+
+# Add or remove space between macro and value
+sp_macro                                 = ignore   # ignore/add/remove/force
+
+# Add or remove space between macro function ')' and value
+sp_macro_func                            = ignore   # ignore/add/remove/force
+
+# Add or remove space between 'else' and '{' if on the same line
+sp_else_brace                            = force   # ignore/add/remove/force
+
+# Add or remove space between '}' and 'else' if on the same line
+sp_brace_else                            = ignore   # ignore/add/remove/force
+
+# Add or remove space between '}' and the name of a typedef on the same line
+sp_brace_typedef                         = ignore   # ignore/add/remove/force
+
+# Add or remove space between 'catch' and '{' if on the same line
+sp_catch_brace                           = ignore   # ignore/add/remove/force
+
+# Add or remove space between '}' and 'catch' if on the same line
+sp_brace_catch                           = ignore   # ignore/add/remove/force
+
+# Add or remove space between 'finally' and '{' if on the same line
+sp_finally_brace                         = ignore   # ignore/add/remove/force
+
+# Add or remove space between '}' and 'finally' if on the same line
+sp_brace_finally                         = ignore   # ignore/add/remove/force
+
+# Add or remove space between 'try' and '{' if on the same line
+sp_try_brace                             = ignore   # ignore/add/remove/force
+
+# Add or remove space between get/set and '{' if on the same line
+sp_getset_brace                          = ignore   # ignore/add/remove/force
+
+# Add or remove space before the '::' operator
+sp_before_dc                             = remove   # ignore/add/remove/force
+
+# Add or remove space after the '::' operator
+sp_after_dc                              = remove   # ignore/add/remove/force
+
+# Add or remove around the D named array initializer ':' operator
+sp_d_array_colon                         = ignore   # ignore/add/remove/force
+
+# Add or remove space after the '!' (not) operator.
+sp_not                                   = remove   # ignore/add/remove/force
+
+# Add or remove space after the '~' (invert) operator.
+sp_inv                                   = remove   # ignore/add/remove/force
+
+# Add or remove space after the '&' (address-of) operator.
+# This does not affect the spacing after a '&' that is part of a type.
+sp_addr                                  = remove   # ignore/add/remove/force
+
+# Add or remove space around the '.' or '->' operators
+sp_member                                = remove   # ignore/add/remove/force
+
+# Add or remove space after the '*' (dereference) operator.
+# This does not affect the spacing after a '*' that is part of a type.
+sp_deref                                 = remove   # ignore/add/remove/force
+
+# Add or remove space after '+' or '-', as in 'x = -5' or 'y = +7'
+sp_sign                                  = remove   # ignore/add/remove/force
+
+# Add or remove space before or after '++' and '--', as in '(--x)' or 'y++;'
+sp_incdec                                = remove   # ignore/add/remove/force
+
+# Add or remove space before a backslash-newline at the end of a line
+sp_before_nl_cont                        = force      # ignore/add/remove/force
+
+# Add or remove space after the scope '+' or '-', as in '-(void) foo;' or '+(int) bar;'
+sp_after_oc_scope                        = ignore   # ignore/add/remove/force
+
+# Add or remove space after the colon in message specs
+# '-(int) f:(int) x;' vs '-(int) f: (int) x;'
+sp_after_oc_colon                        = ignore   # ignore/add/remove/force
+
+# Add or remove space before the colon in message specs
+# '-(int) f: (int) x;' vs '-(int) f : (int) x;'
+sp_before_oc_colon                       = ignore   # ignore/add/remove/force
+
+# Add or remove space after the colon in message specs
+# '[object setValue:1];' vs '[object setValue: 1];'
+sp_after_send_oc_colon                   = ignore   # ignore/add/remove/force
+
+# Add or remove space before the colon in message specs
+# '[object setValue:1];' vs '[object setValue :1];'
+sp_before_send_oc_colon                  = ignore   # ignore/add/remove/force
+
+# Add or remove space after the (type) in message specs
+# '-(int) f: (int) x;' vs '-(int) f: (int)x;'
+sp_after_oc_type                         = ignore   # ignore/add/remove/force
+
+# Add or remove space around the ':' in 'b ? t : f'
+sp_cond_colon                            = ignore   # ignore/add/remove/force
+
+# Add or remove space around the '?' in 'b ? t : f'
+sp_cond_question                         = ignore   # ignore/add/remove/force
+
+# Fix the spacing between 'case' and the label. Only 'ignore' and 'force' make sense here.
+sp_case_label                            = ignore   # ignore/add/remove/force
+
+# Control the space around the D '..' operator.
+sp_range                                 = ignore   # ignore/add/remove/force
+
+# Control the space after the opening of a C++ comment '// A' vs '//A'
+sp_cmt_cpp_start                         = ignore   # ignore/add/remove/force
+
+#
+# Code alignment (not left column spaces/tabs)
+#
+
+# Whether to keep non-indenting tabs
+align_keep_tabs                          = false    # false/true
+
+# Whether to use tabs for alinging
+align_with_tabs                          = false    # false/true
+
+# Whether to bump out to the next tab when aligning
+align_on_tabstop                         = false    # false/true
+
+# Whether to left-align numbers
+align_number_left                        = false    # false/true
+
+# Align variable definitions in prototypes and functions
+align_func_params                        = false    # false/true
+
+# Align parameters in single-line functions that have the same name.
+# The function names must already be aligned with each other.
+align_same_func_call_params              = false    # false/true
+
+# The span for aligning variable definitions (0=don't align)
+align_var_def_span                       = 1        # number
+
+# How to align the star in variable definitions.
+#  0=Part of the type     'void *   foo;'
+#  1=Part of the variable 'void     *foo;'
+#  2=Dangling             'void    *foo;'
+align_var_def_star_style                 = 2        # number
+
+# How to align the '&' in variable definitions.
+#  0=Part of the type
+#  1=Part of the variable
+#  2=Dangling
+align_var_def_amp_style                  = 2        # number
+
+# The threshold for aligning variable definitions (0=no limit)
+align_var_def_thresh                     = 5        # number
+
+# The gap for aligning variable definitions
+align_var_def_gap                        = 1        # number
+
+# Whether to align the colon in struct bit fields
+align_var_def_colon                      = false    # false/true
+
+# Whether to align any attribute after the variable name
+align_var_def_attribute                  = false    # false/true
+
+# Whether to align inline struct/enum/union variable definitions
+align_var_def_inline                     = false    # false/true
+
+# The span for aligning on '=' in assignments (0=don't align)
+align_assign_span                        = 1        # number
+
+# The threshold for aligning on '=' in assignments (0=no limit)
+align_assign_thresh                      = 5    # number
+
+# The span for aligning on '=' in enums (0=don't align)
+align_enum_equ_span                      = 1        # number
+
+# The threshold for aligning on '=' in enums (0=no limit)
+align_enum_equ_thresh                    = 5        # number
+
+# The span for aligning struct/union (0=don't align)
+align_var_struct_span                    = 1        # number
+
+# The threshold for aligning struct/union member definitions (0=no limit)
+align_var_struct_thresh                  = 5        # number
+
+# The gap for aligning struct/union member definitions
+align_var_struct_gap                     = 0        # number
+
+# The span for aligning struct initializer values (0=don't align)
+align_struct_init_span                   = 1        # number
+
+# The minimum space between the type and the synonym of a typedef
+align_typedef_gap                        = 0        # number
+
+# The span for aligning single-line typedefs (0=don't align)
+align_typedef_span                       = 1        # number
+
+# How to align typedef'd functions with other typedefs
+# 0: Don't mix them at all
+# 1: align the open paren with the types
+# 2: align the function type name with the other type names
+align_typedef_func                       = 0        # number
+
+# Controls the positioning of the '*' in typedefs. Just try it.
+# 0: Align on typdef type, ignore '*'
+# 1: The '*' is part of type name: typedef int  *pint;
+# 2: The '*' is part of the type, but dangling: typedef int *pint;
+align_typedef_star_style                 = 0        # number
+
+# Controls the positioning of the '&' in typedefs. Just try it.
+# 0: Align on typdef type, ignore '&'
+# 1: The '&' is part of type name: typedef int  &pint;
+# 2: The '&' is part of the type, but dangling: typedef int &pint;
+align_typedef_amp_style                  = 0        # number
+
+# The span for aligning comments that end lines (0=don't align)
+align_right_cmt_span                     = 0        # number
+
+# If aligning comments, mix with comments after '}' and #endif with less than 3 spaces before the comment
+align_right_cmt_mix                      = false    # false/true
+
+# If a trailing comment is more than this number of columns away from the text it follows,
+# it will qualify for being aligned.
+align_right_cmt_gap                      = 0        # number
+
+# Align trailing comment at or beyond column N; 'pulls in' comments as a bonus side effect (0=ignore)
+align_right_cmt_at_col                   = 0        # number
+
+# The span for aligning function prototypes (0=don't align)
+align_func_proto_span                    = 0        # number
+
+# Minimum gap between the return type and the function name.
+align_func_proto_gap                     = 0        # number
+
+# Align function protos on the 'operator' keyword instead of what follows
+align_on_operator                        = false    # false/true
+
+# Whether to mix aligning prototype and variable declarations.
+# If true, align_var_def_XXX options are used instead of align_func_proto_XXX options.
+align_mix_var_proto                      = false    # false/true
+
+# Align single-line functions with function prototypes, uses align_func_proto_span
+align_single_line_func                   = false    # false/true
+
+# Aligning the open brace of single-line functions.
+# Requires align_single_line_func=true, uses align_func_proto_span
+align_single_line_brace                  = false    # false/true
+
+# Gap for align_single_line_brace.
+align_single_line_brace_gap              = 0        # number
+
+# The span for aligning ObjC msg spec (0=don't align)
+align_oc_msg_spec_span                   = 0        # number
+
+# Whether to align macros wrapped with a backslash and a newline.
+# This will not work right if the macro contains a multi-line comment.
+align_nl_cont                            = false    # false/true
+
+# The minimum space between label and value of a preprocessor define
+align_pp_define_gap                      = 0        # number
+
+# The span for aligning on '#define' bodies (0=don't align)
+align_pp_define_span                     = 0        # number
+
+# Align lines that start with '<<' with previous '<<'. Default=true
+align_left_shift                         = true     # false/true
+
+#
+# Newline adding and removing options
+#
+
+# Whether to collapse empty blocks between '{' and '}'
+nl_collapse_empty_body                   = true    # false/true
+
+# Don't split one-line braced assignments - 'foo_t f = { 1, 2 };'
+nl_assign_leave_one_liners               = true    # false/true
+
+# Don't split one-line braced statements inside a class xx { } body
+nl_class_leave_one_liners                = false    # false/true
+
+# Don't split one-line enums: 'enum foo { BAR = 15 };'
+nl_enum_leave_one_liners                 = false    # false/true
+
+# Don't split one-line get or set functions
+nl_getset_leave_one_liners               = true     # false/true
+
+# Don't split one-line function definitions - 'int foo() { return 0; }'
+nl_func_leave_one_liners                 = true    # false/true
+
+# Don't split one-line if/else statements - 'if(a) b++;'
+nl_if_leave_one_liners                   = false    # false/true
+
+# Add or remove newlines at the start of the file
+nl_start_of_file                         = ignore   # ignore/add/remove/force
+
+# The number of newlines at the start of the file (only used if nl_start_of_file is 'add' or 'force'
+nl_start_of_file_min                     = 0        # number
+
+# Add or remove newline at the end of the file
+nl_end_of_file                           = force   # ignore/add/remove/force
+
+# The number of newlines at the end of the file (only used if nl_end_of_file is 'add' or 'force')
+nl_end_of_file_min                       = 1        # number
+
+# Add or remove newline between '=' and '{'
+nl_assign_brace                          = ignore   # ignore/add/remove/force
+
+# Add or remove newline between '=' and '[' (D only)
+nl_assign_square                         = ignore   # ignore/add/remove/force
+
+# Add or remove newline after '= [' (D only). Will also affect the newline before the ']'
+nl_after_square_assign                   = ignore   # ignore/add/remove/force
+
+# The number of newlines after a block of variable definitions
+nl_func_var_def_blk                      = 0        # number
+
+# Add or remove newline between a function call's ')' and '{', as in:
+# list_for_each(item, &list) { }
+nl_fcall_brace                           = force   # ignore/add/remove/force
+
+# Add or remove newline between 'enum' and '{'
+nl_enum_brace                            = remove   # ignore/add/remove/force
+
+# Add or remove newline between 'struct and '{'
+nl_struct_brace                          = remove   # ignore/add/remove/force
+
+# Add or remove newline between 'union' and '{'
+nl_union_brace                           = remove   # ignore/add/remove/force
+
+# Add or remove newline between 'if' and '{'
+nl_if_brace                              = remove   # ignore/add/remove/force
+
+# Add or remove newline between '}' and 'else'
+nl_brace_else                            = force   # ignore/add/remove/force
+
+# Add or remove newline between 'else if' and '{'
+# If set to ignore, nl_if_brace is used instead
+nl_elseif_brace                          = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'else' and '{'
+nl_else_brace                            = remove   # ignore/add/remove/force
+
+# Add or remove newline between 'else' and 'if'
+nl_else_if                               = add   # ignore/add/remove/force
+
+# Add or remove newline between '}' and 'finally'
+nl_brace_finally                         = force   # ignore/add/remove/force
+
+# Add or remove newline between 'finally' and '{'
+nl_finally_brace                         = remove   # ignore/add/remove/force
+
+# Add or remove newline between 'try' and '{'
+nl_try_brace                             = remove   # ignore/add/remove/force
+
+# Add or remove newline between get/set and '{'
+nl_getset_brace                          = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'for' and '{'
+nl_for_brace                             = remove   # ignore/add/remove/force
+
+# Add or remove newline between 'catch' and '{'
+nl_catch_brace                           = remove   # ignore/add/remove/force
+
+# Add or remove newline between '}' and 'catch'
+nl_brace_catch                           = force   # ignore/add/remove/force
+
+# Add or remove newline between 'while' and '{'
+nl_while_brace                           = remove   # ignore/add/remove/force
+
+# Add or remove newline between 'do' and '{'
+nl_do_brace                              = remove   # ignore/add/remove/force
+
+# Add or remove newline between '}' and 'while' of 'do' statement
+nl_brace_while                           = remove   # ignore/add/remove/force
+
+# Add or remove newline between 'switch' and '{'
+nl_switch_brace                          = remove   # ignore/add/remove/force
+
+# Add a newline between ')' and '{' if the ')' is on a different line than the if/for/etc.
+# Overrides nl_for_brace, nl_if_brace, nl_switch_brace, nl_while_switch, and nl_catch_brace.
+nl_multi_line_cond                       = false    # false/true
+
+# Force a newline in a define after the macro name for multi-line defines.
+nl_multi_line_define                     = false    # false/true
+
+# Whether to put a newline before 'case' statement
+nl_before_case                           = false    # false/true
+
+# Add or remove newline between ')' and 'throw'
+nl_before_throw                          = ignore   # ignore/add/remove/force
+
+# Whether to put a newline after 'case' statement
+nl_after_case                            = false    # false/true
+
+# Newline between namespace and {
+nl_namespace_brace                       = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'template<>' and whatever follows.
+nl_template_class                        = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'class' and '{'
+nl_class_brace                           = force   # ignore/add/remove/force
+
+# Add or remove newline after each ',' in the constructor member initialization
+nl_class_init_args                       = ignore   # ignore/add/remove/force
+
+# Add or remove newline between return type and function name in definition
+nl_func_type_name                        = ignore   # ignore/add/remove/force
+
+# Add or remove newline between function scope and name in a definition
+# Controls the newline after '::' in 'void A::f() { }'
+nl_func_scope_name                       = ignore   # ignore/add/remove/force
+
+# Add or remove newline between return type and function name in a prototype
+nl_func_proto_type_name                  = ignore   # ignore/add/remove/force
+
+# Add or remove newline between a function name and the opening '('
+nl_func_paren                            = remove   # ignore/add/remove/force
+
+# Add or remove newline after '(' in a function declaration
+nl_func_decl_start                       = ignore   # ignore/add/remove/force
+
+# Add or remove newline after each ',' in a function declaration
+nl_func_decl_args                        = ignore   # ignore/add/remove/force
+
+# Add or remove newline before the ')' in a function declaration
+nl_func_decl_end                         = ignore   # ignore/add/remove/force
+
+# Add or remove newline between function signature and '{'
+nl_fdef_brace                            = ignore   # ignore/add/remove/force
+
+# Whether to put a newline after 'return' statement
+nl_after_return                          = false    # false/true
+
+# Add or remove a newline between the return keyword and return expression.
+nl_return_expr                           = ignore   # ignore/add/remove/force
+
+# Whether to put a newline after semicolons, except in 'for' statements
+nl_after_semicolon                       = false    # false/true
+
+# Whether to put a newline after brace open.
+# This also adds a newline before the matching brace close.
+nl_after_brace_open                      = true    # false/true
+
+# If nl_after_brace_open and nl_after_brace_open_cmt are true, a newline is
+# placed between the open brace and a trailing single-line comment.
+nl_after_brace_open_cmt                  = false    # false/true
+
+# Whether to put a newline after a virtual brace open.
+# These occur in un-braced if/while/do/for statement bodies.
+nl_after_vbrace_open                     = true    # false/true
+
+# Whether to put a newline after a brace close.
+# Does not apply if followed by a necessary ';'.
+nl_after_brace_close                     = false    # false/true
+
+# Whether to alter newlines in '#define' macros
+nl_define_macro                          = false    # false/true
+
+# Whether to not put blanks after '#ifxx', '#elxx', or before '#endif'
+nl_squeeze_ifdef                         = false    # false/true
+
+# Add or remove newline before 'if'
+nl_before_if                             = ignore   # ignore/add/remove/force
+
+# Add or remove newline after 'if'
+nl_after_if                              = ignore   # ignore/add/remove/force
+
+# Add or remove newline before 'for'
+nl_before_for                            = ignore   # ignore/add/remove/force
+
+# Add or remove newline after 'for'
+nl_after_for                             = ignore   # ignore/add/remove/force
+
+# Add or remove newline before 'while'
+nl_before_while                          = ignore   # ignore/add/remove/force
+
+# Add or remove newline after 'while'
+nl_after_while                           = ignore   # ignore/add/remove/force
+
+# Add or remove newline before 'switch'
+nl_before_switch                         = ignore   # ignore/add/remove/force
+
+# Add or remove newline after 'switch'
+nl_after_switch                          = ignore   # ignore/add/remove/force
+
+# Add or remove newline before 'do'
+nl_before_do                             = ignore   # ignore/add/remove/force
+
+# Add or remove newline after 'do'
+nl_after_do                              = ignore   # ignore/add/remove/force
+
+# Whether to double-space commented-entries in struct/enum
+nl_ds_struct_enum_cmt                    = false    # false/true
+
+# Whether to double-space before the close brace of a struct/union/enum
+nl_ds_struct_enum_close_brace            = false    # false/true
+
+# Add or remove a newline around a class colon.
+# Related to pos_class_colon, nl_class_init_args, and pos_comma.
+nl_class_colon                           = ignore   # ignore/add/remove/force
+
+# Change simple unbraced if statements into a one-liner
+# 'if(b)\n i++;' => 'if(b) i++;'
+nl_create_if_one_liner                   = false    # false/true
+
+# Change simple unbraced for statements into a one-liner
+# 'for (i=0;i<5;i++)\n foo(i);' => 'for (i=0;i<5;i++) foo(i);'
+nl_create_for_one_liner                  = false    # false/true
+
+# Change simple unbraced while statements into a one-liner
+# 'while (i<5)\n foo(i++);' => 'while (i<5) foo(i++);'
+nl_create_while_one_liner                = false    # false/true
+
+#
+# Positioning options
+#
+
+# The position of arithmetic operators in wrapped expressions
+pos_arith                                = lead    # ignore/lead/trail
+
+# The position of assignment in wrapped expressions
+pos_assign                               = trail   # ignore/lead/trail
+
+# The position of boolean operators in wrapped expressions
+pos_bool                                 = lead     # ignore/lead/trail
+
+# The position of the comma in wrapped expressions
+pos_comma                                = trail   # ignore/lead/trail
+
+# The position of the comma in the constructor initialization list
+pos_class_comma                          = trail   # ignore/lead/trail
+
+# The position of colons between constructor and member initialization
+pos_class_colon                          = lead   # ignore/lead/trail
+
+#
+# Line Splitting options
+#
+
+# Try to limit code width to N number of columns
+code_width                               = 80        # number
+
+# Whether to fully split long 'for' statements at semi-colons
+ls_for_split_full                        = true    # false/true
+
+# Whether to fully split long function protos/calls at commas
+ls_func_split_full                       = true    # false/true
+
+#
+# Blank line options
+#
+
+# The maximum consecutive newlines
+nl_max                                   = 0        # number
+
+# The number of newlines after a function prototype, if followed by another function prototype
+nl_after_func_proto                      = 0        # number
+
+# The number of newlines after a function prototype, if not followed by another function prototype
+nl_after_func_proto_group                = 0        # number
+
+# The number of newlines after '}' of a multi-line function body
+nl_after_func_body                       = 0        # number
+
+# The number of newlines after '}' of a single line function body
+nl_after_func_body_one_liner             = 0        # number
+
+# The minimum number of newlines before a multi-line comment.
+# Doesn't apply if after a brace open or another multi-line comment.
+nl_before_block_comment                  = 0        # number
+
+# The minimum number of newlines before a single-line C comment.
+# Doesn't apply if after a brace open or other single-line C comments.
+nl_before_c_comment                      = 0        # number
+
+# The minimum number of newlines before a CPP comment.
+# Doesn't apply if after a brace open or other CPP comments.
+nl_before_cpp_comment                    = 0        # number
+
+# Whether to force a newline after a mulit-line comment.
+nl_after_multiline_comment               = false    # false/true
+
+# The number of newlines before a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label.
+# Will not change the newline count if after a brace open.
+# 0 = No change.
+nl_before_access_spec                    = 0        # number
+
+# The number of newlines after a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label.
+# 0 = No change.
+nl_after_access_spec                     = 0        # number
+
+# The number of newlines between a function def and the function comment.
+# 0 = No change.
+nl_comment_func_def                      = 0        # number
+
+# The number of newlines after a try-catch-finally block that isn't followed by a brace close.
+# 0 = No change.
+nl_after_try_catch_finally               = 0        # number
+
+# The number of newlines before and after a property, indexer or event decl.
+# 0 = No change.
+nl_around_cs_property                    = 0        # number
+
+# The number of newlines between the get/set/add/remove handlers in C#.
+# 0 = No change.
+nl_between_get_set                       = 0        # number
+
+# Whether to remove blank lines after '{'
+eat_blanks_after_open_brace              = true    # false/true
+
+# Whether to remove blank lines before '}'
+eat_blanks_before_close_brace            = true    # false/true
+
+#
+# Code modifying options (non-whitespace)
+#
+
+# Add or remove braces on single-line 'do' statement
+mod_full_brace_do                        = ignore   # ignore/add/remove/force
+
+# Add or remove braces on single-line 'for' statement
+mod_full_brace_for                       = remove   # ignore/add/remove/force
+
+# Add or remove braces on single-line function defintions. (Pawn)
+mod_full_brace_function                  = ignore   # ignore/add/remove/force
+
+# Add or remove braces on single-line 'if' statement. Will not remove the braces if they contain an 'else'.
+mod_full_brace_if                        = remove   # ignore/add/remove/force
+
+# Don't remove braces around statements that span N newlines
+mod_full_brace_nl                        = 0        # number
+
+# Add or remove braces on single-line 'while' statement
+mod_full_brace_while                     = ignore   # ignore/add/remove/force
+
+# Add or remove unnecessary paren on 'return' statement
+mod_paren_on_return                      = remove   # ignore/add/remove/force
+
+# Whether to change optional semicolons to real semicolons
+mod_pawn_semicolon                       = false    # false/true
+
+# Add parens on 'while' and 'if' statement around bools
+mod_full_paren_if_bool                   = true    # false/true
+
+# Whether to remove superfluous semicolons
+mod_remove_extra_semicolon               = true    # false/true
+
+# If a function body exceeds the specified number of newlines and doesn't have a comment after
+# the close brace, a comment will be added.
+mod_add_long_function_closebrace_comment = 0        # number
+
+# If a switch body exceeds the specified number of newlines and doesn't have a comment after
+# the close brace, a comment will be added.
+mod_add_long_switch_closebrace_comment   = 0        # number
+
+# If an #ifdef body exceeds the specified number of newlines and doesn't have a comment after
+# the #else, a comment will be added.
+mod_add_long_ifdef_endif_comment         = 0        # number
+
+# If an #ifdef or #else body exceeds the specified number of newlines and doesn't have a comment after
+# the #endif, a comment will be added.
+mod_add_long_ifdef_else_comment          = 0        # number
+
+# If TRUE, will sort consecutive single-line 'import' statements [Java, D]
+mod_sort_import                          = false    # false/true
+
+# If TRUE, will sort consecutive single-line 'using' statements [C#]
+mod_sort_using                           = false    # false/true
+
+# If TRUE, will sort consecutive single-line '#include' statements [C/C++] and '#import' statements [Obj-C]
+# This is generally a bad idea, as it may break your code.
+mod_sort_include                         = false    # false/true
+
+# If TRUE, it will move a 'break' that appears after a fully braced 'case' before the close brace.
+mod_move_case_break                      = false    # false/true
+
+# If TRUE, it will remove a void 'return;' that appears as the last statement in a function.
+mod_remove_empty_return                  = false    # false/true
+
+#
+# Comment modifications
+#
+
+# Try to wrap comments at cmt_width columns
+cmt_width                                = 0        # number
+
+# If false, disable all multi-line comment changes, including cmt_width and leading chars.
+# Default is true.
+cmt_indent_multi                         = false    # false/true
+
+# Whether to group c-comments that look like they are in a block
+cmt_c_group                              = false    # false/true
+
+# Whether to put an empty '/*' on the first line of the combined c-comment
+cmt_c_nl_start                           = false    # false/true
+
+# Whether to put a newline before the closing '*/' of the combined c-comment
+cmt_c_nl_end                             = false    # false/true
+
+# Whether to group cpp-comments that look like they are in a block
+cmt_cpp_group                            = false    # false/true
+
+# Whether to put an empty '/*' on the first line of the combined cpp-comment
+cmt_cpp_nl_start                         = false    # false/true
+
+# Whether to put a newline before the closing '*/' of the combined cpp-comment
+cmt_cpp_nl_end                           = false    # false/true
+
+# Whether to change cpp-comments into c-comments
+cmt_cpp_to_c                             = false    # false/true
+
+# Whether to put a star on subsequent comment lines
+cmt_star_cont                            = false    # false/true
+
+# The number of spaces to insert at the start of subsequent comment lines
+cmt_sp_before_star_cont                  = 0        # number
+
+# The number of spaces to insert after the star on subsequent comment lines
+cmt_sp_after_star_cont                   = 1        # number
+
+# For multi-line comments with a '*' lead, remove leading spaces if the first and last lines of
+# the comment are the same length. Default=True
+cmt_multi_check_last                     = true     # false/true
+
+# The filename that contains text to insert at the head of a file if the file doesn't start with a C/C++ comment.
+# Will substitue $(filename) with the current file's name.
+cmt_insert_file_header                   = ""         # string
+
+# The filename that contains text to insert at the end of a file if the file doesn't end with a C/C++ comment.
+# Will substitue $(filename) with the current file's name.
+cmt_insert_file_footer                   = ""         # string
+
+# The filename that contains text to insert before a function implementation if the function isn't preceeded with a C/C++ comment.
+# Will substitue $(function) with the function name and $(javaparam) with the javadoc @param and @return stuff.
+# Will also substitute $(fclass) with the class name: void CFoo::Bar() { ... }
+cmt_insert_func_header                   = ""         # string
+
+# The filename that contains text to insert before a class if the class isn't preceeded with a C/C++ comment.
+# Will substitue $(class) with the class name.
+cmt_insert_class_header                  = ""         # string
+
+# If a preprocessor is encountered when stepping backwards from a function name, then
+# this option decides whether the comment should be inserted.
+# Affects cmt_insert_func_header and cmt_insert_class_header.
+cmt_insert_before_preproc                = false    # false/true
+
+#
+# Preprocessor options
+#
+
+# Control indent of preprocessors inside #if blocks at brace level 0
+pp_indent                                = ignore   # ignore/add/remove/force
+
+# Whether to indent #if/#else/#endif at the brace level (true) or from column 1 (false)
+pp_indent_at_level                       = false    # false/true
+
+# If pp_indent_at_level=false, specifies the number of columns to indent per level. Default=1.
+pp_indent_count                          = 1        # number
+
+# Add or remove space after # based on pp_level of #if blocks
+pp_space                                 = ignore   # ignore/add/remove/force
+
+# Sets the number of spaces added with pp_space
+pp_space_count                           = 0        # number
+
+# The indent for #region and #endregion in C# and '#pragma region' in C/C++
+pp_indent_region                         = 0        # number
+
+# Whether to indent the code between #region and #endregion
+pp_region_indent_code                    = false    # false/true
+
+# If pp_indent_at_level=true, sets the indent for #if, #else, and #endif when not at file-level
+pp_indent_if                             = 0        # number
+
+# Control whether to indent the code between #if, #else and #endif when not at file-level
+pp_if_indent_code                        = false    # false/true
+
+# Whether to indent '#define' at the brace level (true) or from column 1 (false)
+pp_define_at_level                       = false    # false/true
+
+# You can force a token to be a type with the 'type' option.
+# Example:
+# type myfoo1 myfoo2
+#
+# You can create custom macro-based indentation using macro-open,
+# macro-else and macro-close.
+# Example:
+# macro-open  BEGIN_TEMPLATE_MESSAGE_MAP
+# macro-open  BEGIN_MESSAGE_MAP
+# macro-close END_MESSAGE_MAP
+#
+# You can assign any keyword to any type with the set option.
+# set func_call_user _ N_
+#
+# The full syntax description of all custom definition config entries
+# is shown below:
+#
+# define custom tokens as:
+# - embed whitespace in token using '' escape character, or
+#   put token in quotes
+# - these: ' " and ` are recognized as quote delimiters
+#
+# type token1 token2 token3 ...
+#             ^ optionally specify multiple tokens on a single line
+# define def_token output_token
+#                  ^ output_token is optional, then NULL is assumed
+# macro-open token
+# macro-close token
+# macro-else token
+# set id token1 token2 ...
+#               ^ optionally specify multiple tokens on a single line
+#     ^ id is one of the names in token_enum.h sans the CT_ prefix,
+#       e.g. PP_PRAGMA
+#
+# all tokens are separated by any mix of ',' commas, '=' equal signs
+# and whitespace (space, tab)
+#
diff --git a/style.sh b/style.sh
new file mode 100755
index 0000000..08d93ee
--- /dev/null
+++ b/style.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+uncrustify -c style.cfg --no-backup -l CPP `find . | grep -e "\.h$"`
+uncrustify -c style.cfg --no-backup -l CPP `find . | grep -e "\.cpp$"`
+#cover nsm code
+uncrustify -c style.cfg --no-backup -l CPP `find . | grep -e "\.H$"`
+uncrustify -c style.cfg --no-backup -l CPP `find . | grep -e "\.C$"`

-- 
zynaddsubfx packaging



More information about the pkg-multimedia-commits mailing list