home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 November / CMCD1104.ISO / Software / Complet / ZynAddFX / Setup_ZynAddSubFX-2.1.1.exe / ADnote.C < prev    next >
Encoding:
C/C++ Source or Header  |  2004-07-13  |  34.8 KB  |  983 lines

  1. /*
  2.   ZynAddSubFX - a software synthesizer
  3.  
  4.   ADnote.C - The "additive" synthesizer
  5.   Copyright (C) 2002-2004 Nasca Octavian Paul
  6.   Author: Nasca Octavian Paul
  7.  
  8.   This program is free software; you can redistribute it and/or modify
  9.   it under the terms of version 2 of the GNU General Public License 
  10.   as published by the Free Software Foundation.
  11.  
  12.   This program is distributed in the hope that it will be useful,
  13.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.   GNU General Public License (version 2) for more details.
  16.  
  17.   You should have received a copy of the GNU General Public License (version 2)
  18.   along with this program; if not, write to the Free Software Foundation,
  19.   Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  20. */
  21.  
  22. #include <math.h>
  23. #include <stdlib.h>
  24. #include <stdio.h>
  25.  
  26.  
  27. #include "../globals.h"
  28. #include "../Misc/Util.h"
  29. #include "ADnote.h"
  30.  
  31.  
  32. ADnote::ADnote(ADnoteParameters *pars,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote_){
  33.     ready=0;
  34.     
  35.     tmpwave=new REALTYPE [SOUND_BUFFER_SIZE];
  36.     bypassl=new REALTYPE [SOUND_BUFFER_SIZE];
  37.     bypassr=new REALTYPE [SOUND_BUFFER_SIZE];
  38.  
  39.     partparams=pars;
  40.     ctl=ctl_;
  41.     portamento=portamento_;
  42.     midinote=midinote_;
  43.     NoteEnabled=ON;
  44.     basefreq=freq;
  45.     if (velocity>1.0) velocity=1.0;
  46.     this->velocity=velocity;  
  47.     time=0.0;
  48.     stereo=pars->GlobalPar.PStereo;
  49.  
  50.     NoteGlobalPar.Detune=getdetune(pars->GlobalPar.PDetuneType
  51.         ,pars->GlobalPar.PCoarseDetune,pars->GlobalPar.PDetune);
  52.     
  53.     if (pars->GlobalPar.PPanning==0) NoteGlobalPar.Panning=RND;
  54.     else NoteGlobalPar.Panning=pars->GlobalPar.PPanning/128.0;
  55.     
  56.  
  57.     NoteGlobalPar.FilterCenterPitch=pars->GlobalPar.GlobalFilter->getfreq()+//center freq
  58.         pars->GlobalPar.PFilterVelocityScale/127.0*6.0*  //velocity sensing
  59.         (VelF(velocity,pars->GlobalPar.PFilterVelocityScaleFunction)-1);
  60.  
  61.     if (pars->GlobalPar.PPunchStrength!=0) {
  62.         NoteGlobalPar.Punch.Enabled=1;
  63.     NoteGlobalPar.Punch.t=1.0;//start from 1.0 and to 0.0
  64.     NoteGlobalPar.Punch.initialvalue=( (pow(10,1.5*pars->GlobalPar.PPunchStrength/127.0)-1.0)
  65.         *VelF(velocity,pars->GlobalPar.PPunchVelocitySensing) );
  66.     REALTYPE time=pow(10,3.0*pars->GlobalPar.PPunchTime/127.0)/10000.0;//0.1 .. 100 ms
  67.     REALTYPE stretch=pow(440.0/freq,pars->GlobalPar.PPunchStretch/64.0);
  68.     NoteGlobalPar.Punch.dt=1.0/(time*SAMPLE_RATE*stretch);
  69.     } else NoteGlobalPar.Punch.Enabled=0;
  70.  
  71.     for (int nvoice=0;nvoice<NUM_VOICES;nvoice++){
  72.     pars->VoicePar[nvoice].OscilSmp->newrandseed(rand());
  73.     NoteVoicePar[nvoice].OscilSmp=NULL;
  74.     NoteVoicePar[nvoice].FMSmp=NULL;
  75.     NoteVoicePar[nvoice].VoiceOut=NULL;
  76.  
  77.     NoteVoicePar[nvoice].FMVoice=-1;
  78.     
  79.     if (pars->VoicePar[nvoice].Enabled==0) {
  80.         NoteVoicePar[nvoice].Enabled=OFF;
  81.         continue; //the voice is disabled
  82.     };
  83.  
  84.     NoteVoicePar[nvoice].Enabled=ON;
  85.     NoteVoicePar[nvoice].fixedfreq=pars->VoicePar[nvoice].Pfixedfreq;
  86.     NoteVoicePar[nvoice].fixedfreqET=pars->VoicePar[nvoice].PfixedfreqET;
  87.     
  88.     //use the Globalpars.detunetype if the detunetype is 0
  89.     if (pars->VoicePar[nvoice].PDetuneType!=0){
  90.             NoteVoicePar[nvoice].Detune=getdetune(pars->VoicePar[nvoice].PDetuneType
  91.         ,pars->VoicePar[nvoice].PCoarseDetune,8192);//coarse detune
  92.             NoteVoicePar[nvoice].FineDetune=getdetune(pars->VoicePar[nvoice].PDetuneType
  93.         ,0,pars->VoicePar[nvoice].PDetune);//fine detune
  94.     } else { 
  95.         NoteVoicePar[nvoice].Detune=getdetune(pars->GlobalPar.PDetuneType
  96.         ,pars->VoicePar[nvoice].PCoarseDetune,8192);//coarse detune
  97.         NoteVoicePar[nvoice].FineDetune=getdetune(pars->GlobalPar.PDetuneType
  98.         ,0,pars->VoicePar[nvoice].PDetune);//fine detune
  99.     };
  100.     if (pars->VoicePar[nvoice].PFMDetuneType!=0){ 
  101.         NoteVoicePar[nvoice].FMDetune=getdetune(pars->VoicePar[nvoice].PFMDetuneType
  102.         ,pars->VoicePar[nvoice].PFMCoarseDetune,pars->VoicePar[nvoice].PFMDetune);
  103.     } else {
  104.         NoteVoicePar[nvoice].FMDetune=getdetune(pars->GlobalPar.PDetuneType
  105.         ,pars->VoicePar[nvoice].PFMCoarseDetune,pars->VoicePar[nvoice].PFMDetune);
  106.     };
  107.  
  108.         oscposhi[nvoice]=0;oscposlo[nvoice]=0.0;
  109.         oscposhiFM[nvoice]=0;oscposloFM[nvoice]=0.0;
  110.     
  111.     NoteVoicePar[nvoice].OscilSmp=new REALTYPE[OSCIL_SIZE+OSCIL_SMP_EXTRA_SAMPLES];//the extra points contains the first point
  112.  
  113.     //Get the voice's oscil or external's voice oscil
  114.     int vc=nvoice; 
  115.     if (pars->VoicePar[nvoice].Pextoscil!=-1) vc=pars->VoicePar[nvoice].Pextoscil;
  116.     if (!pars->GlobalPar.Hrandgrouping) pars->VoicePar[vc].OscilSmp->newrandseed(rand());
  117.     oscposhi[nvoice]=pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp,getvoicebasefreq(nvoice),
  118.                      pars->VoicePar[nvoice].Presonance);
  119.  
  120.     //I store the first elments to the last position for speedups
  121.     for (int i=0;i<OSCIL_SMP_EXTRA_SAMPLES;i++) NoteVoicePar[nvoice].OscilSmp[OSCIL_SIZE+i]=NoteVoicePar[nvoice].OscilSmp[i];
  122.  
  123.     oscposhi[nvoice]+=(int)((pars->VoicePar[nvoice].Poscilphase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE*4);
  124.     oscposhi[nvoice]%=OSCIL_SIZE;
  125.     
  126.     
  127.     NoteVoicePar[nvoice].FreqLfo=NULL;
  128.     NoteVoicePar[nvoice].FreqEnvelope=NULL;
  129.  
  130.     NoteVoicePar[nvoice].AmpLfo=NULL;
  131.     NoteVoicePar[nvoice].AmpEnvelope=NULL;
  132.     
  133.     NoteVoicePar[nvoice].VoiceFilter=NULL;
  134.     NoteVoicePar[nvoice].FilterEnvelope=NULL;
  135.     NoteVoicePar[nvoice].FilterLfo=NULL;
  136.  
  137.     NoteVoicePar[nvoice].FilterCenterPitch=pars->VoicePar[nvoice].VoiceFilter->getfreq();
  138.         NoteVoicePar[nvoice].filterbypass=pars->VoicePar[nvoice].Pfilterbypass;
  139.     
  140.     switch(pars->VoicePar[nvoice].PFMEnabled){
  141.         case 1:NoteVoicePar[nvoice].FMEnabled=MORPH;break;
  142.         case 2:NoteVoicePar[nvoice].FMEnabled=RING_MOD;break;
  143.         case 3:NoteVoicePar[nvoice].FMEnabled=PHASE_MOD;break;
  144.         case 4:NoteVoicePar[nvoice].FMEnabled=FREQ_MOD;break;
  145.         case 5:NoteVoicePar[nvoice].FMEnabled=PITCH_MOD;break;
  146.         default:NoteVoicePar[nvoice].FMEnabled=NONE;
  147.     };
  148.  
  149.     NoteVoicePar[nvoice].FMVoice=pars->VoicePar[nvoice].PFMVoice;
  150.     NoteVoicePar[nvoice].FMFreqEnvelope=NULL;
  151.     NoteVoicePar[nvoice].FMAmpEnvelope=NULL;
  152.  
  153.     //Compute the Voice's modulator volume (incl. damping)
  154.     REALTYPE fmvoldamp=pow(440.0/getvoicebasefreq(nvoice),pars->VoicePar[nvoice].PFMVolumeDamp/64.0-1.0);
  155.     switch (NoteVoicePar[nvoice].FMEnabled){
  156.         case PHASE_MOD:fmvoldamp=pow(440.0/getvoicebasefreq(nvoice),pars->VoicePar[nvoice].PFMVolumeDamp/64.0);
  157.                NoteVoicePar[nvoice].FMVolume=(exp(pars->VoicePar[nvoice].PFMVolume/127.0*FM_AMP_MULTIPLIER)-1.0)*fmvoldamp*4.0;
  158.                break;
  159.         case FREQ_MOD:NoteVoicePar[nvoice].FMVolume=(exp(pars->VoicePar[nvoice].PFMVolume/127.0*FM_AMP_MULTIPLIER)-1.0)*fmvoldamp*4.0;
  160.                   break;
  161.     //    case PITCH_MOD:NoteVoicePar[nvoice].FMVolume=(pars->VoicePar[nvoice].PFMVolume/127.0*8.0)*fmvoldamp;//???????????
  162.     //              break;
  163.         default:if (fmvoldamp>1.0) fmvoldamp=1.0;
  164.                 NoteVoicePar[nvoice].FMVolume=pars->VoicePar[nvoice].PFMVolume/127.0*fmvoldamp;
  165.     };
  166.  
  167.     //Voice's modulator velocity sensing
  168.     NoteVoicePar[nvoice].FMVolume*=VelF(velocity,partparams->VoicePar[nvoice].PFMVelocityScaleFunction);
  169.  
  170.     FMoldsmp[nvoice]=0.0;//this is for FM (integration)
  171.  
  172.     firsttick[nvoice]=1;
  173.     NoteVoicePar[nvoice].DelayTicks=(int)((exp(pars->VoicePar[nvoice].PDelay/127.0*log(50.0))-1.0)/SOUND_BUFFER_SIZE/10.0*SAMPLE_RATE);
  174.   };
  175.  
  176.     initparameters();
  177.     ready=1;
  178. };
  179.  
  180.  
  181. /*
  182.  * Kill a voice of ADnote
  183.  */
  184. void ADnote::KillVoice(int nvoice){
  185.   
  186.     delete (NoteVoicePar[nvoice].OscilSmp);
  187.  
  188.     if (NoteVoicePar[nvoice].FreqEnvelope!=NULL) delete(NoteVoicePar[nvoice].FreqEnvelope);
  189.     NoteVoicePar[nvoice].FreqEnvelope=NULL;
  190.     
  191.     if (NoteVoicePar[nvoice].FreqLfo!=NULL) delete(NoteVoicePar[nvoice].FreqLfo);
  192.     NoteVoicePar[nvoice].FreqLfo=NULL;
  193.  
  194.     if (NoteVoicePar[nvoice].AmpEnvelope!=NULL) delete (NoteVoicePar[nvoice].AmpEnvelope);
  195.     NoteVoicePar[nvoice].AmpEnvelope=NULL;
  196.     
  197.     if (NoteVoicePar[nvoice].AmpLfo!=NULL) delete (NoteVoicePar[nvoice].AmpLfo);
  198.     NoteVoicePar[nvoice].AmpLfo=NULL;
  199.  
  200.     if (NoteVoicePar[nvoice].VoiceFilter!=NULL) delete (NoteVoicePar[nvoice].VoiceFilter);
  201.     NoteVoicePar[nvoice].VoiceFilter=NULL;
  202.  
  203.     if (NoteVoicePar[nvoice].FilterEnvelope!=NULL) delete (NoteVoicePar[nvoice].FilterEnvelope);
  204.     NoteVoicePar[nvoice].FilterEnvelope=NULL;
  205.  
  206.     if (NoteVoicePar[nvoice].FilterLfo!=NULL) delete (NoteVoicePar[nvoice].FilterLfo);
  207.     NoteVoicePar[nvoice].FilterLfo=NULL;
  208.  
  209.     if (NoteVoicePar[nvoice].FMFreqEnvelope!=NULL) delete (NoteVoicePar[nvoice].FMFreqEnvelope);
  210.     NoteVoicePar[nvoice].FMFreqEnvelope=NULL;
  211.     
  212.     if (NoteVoicePar[nvoice].FMAmpEnvelope!=NULL) delete (NoteVoicePar[nvoice].FMAmpEnvelope);
  213.     NoteVoicePar[nvoice].FMAmpEnvelope=NULL;
  214.     
  215.     if ((NoteVoicePar[nvoice].FMEnabled!=NONE)&&(NoteVoicePar[nvoice].FMVoice<0)) delete NoteVoicePar[nvoice].FMSmp;
  216.     
  217.     if (NoteVoicePar[nvoice].VoiceOut!=NULL) 
  218.     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
  219.  
  220.     NoteVoicePar[nvoice].Enabled=OFF;
  221. };
  222.  
  223. /*
  224.  * Kill the note
  225.  */
  226. void ADnote::KillNote(){
  227.     int nvoice;
  228.     for (nvoice=0;nvoice<NUM_VOICES;nvoice++){
  229.     if (NoteVoicePar[nvoice].Enabled==ON) KillVoice(nvoice);
  230.  
  231.     //delete VoiceOut
  232.     if (NoteVoicePar[nvoice].VoiceOut!=NULL) delete(NoteVoicePar[nvoice].VoiceOut);
  233.     NoteVoicePar[nvoice].VoiceOut=NULL;
  234.     };
  235.     
  236.     delete (NoteGlobalPar.FreqEnvelope);
  237.     delete (NoteGlobalPar.FreqLfo);
  238.     delete (NoteGlobalPar.AmpEnvelope);
  239.     delete (NoteGlobalPar.AmpLfo);
  240.     delete (NoteGlobalPar.GlobalFilterL);
  241.     if (stereo!=0) delete (NoteGlobalPar.GlobalFilterR);
  242.     delete (NoteGlobalPar.FilterEnvelope);
  243.     delete (NoteGlobalPar.FilterLfo);
  244.     
  245.     NoteEnabled=OFF;
  246. };
  247.  
  248. ADnote::~ADnote(){
  249.     if (NoteEnabled==ON) KillNote();
  250.     delete [] tmpwave;
  251.     delete [] bypassl;
  252.     delete [] bypassr;
  253. };
  254.  
  255.  
  256. /*
  257.  * Init the parameters
  258.  */
  259. void ADnote::initparameters(){
  260.     int nvoice,i,tmp[NUM_VOICES];
  261.  
  262.     // Global Parameters
  263.     NoteGlobalPar.FreqEnvelope=new Envelope(partparams->GlobalPar.FreqEnvelope,basefreq);
  264.     NoteGlobalPar.FreqLfo=new LFO(partparams->GlobalPar.FreqLfo,basefreq);
  265.     
  266.     NoteGlobalPar.AmpEnvelope=new Envelope(partparams->GlobalPar.AmpEnvelope,basefreq);
  267.     NoteGlobalPar.AmpLfo=new LFO(partparams->GlobalPar.AmpLfo,basefreq);
  268.  
  269.     NoteGlobalPar.Volume=4.0*pow(0.1,3.0*(1.0-partparams->GlobalPar.PVolume/96.0))//-60 dB .. 0 dB
  270.         *VelF(velocity,partparams->GlobalPar.PAmpVelocityScaleFunction);//velocity sensing
  271.  
  272.     NoteGlobalPar.AmpEnvelope->envout_dB();//discard the first envelope output
  273.     globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout();
  274.  
  275.     NoteGlobalPar.GlobalFilterL=new Filter(partparams->GlobalPar.GlobalFilter);
  276.     if (stereo!=0) NoteGlobalPar.GlobalFilterR=new Filter(partparams->GlobalPar.GlobalFilter);
  277.     
  278.     NoteGlobalPar.FilterEnvelope=new Envelope(partparams->GlobalPar.FilterEnvelope,basefreq);
  279.     NoteGlobalPar.FilterLfo=new LFO(partparams->GlobalPar.FilterLfo,basefreq);
  280.     NoteGlobalPar.FilterQ=partparams->GlobalPar.GlobalFilter->getq();
  281.     NoteGlobalPar.FilterFreqTracking=partparams->GlobalPar.GlobalFilter->getfreqtracking(basefreq);
  282.     
  283.     // Forbids the Modulation Voice to be greater or equal than voice
  284.     for (i=0;i<NUM_VOICES;i++) if (NoteVoicePar[i].FMVoice>=i) NoteVoicePar[i].FMVoice=-1;
  285.  
  286.     // Voice Parameter init
  287.     for (nvoice=0;nvoice<NUM_VOICES;nvoice++){
  288.         if (NoteVoicePar[nvoice].Enabled==0) continue;
  289.  
  290.     NoteVoicePar[nvoice].noisetype=partparams->VoicePar[nvoice].Type;
  291.     /* Voice Amplitude Parameters Init */
  292.     NoteVoicePar[nvoice].Volume=pow(0.1,3.0*(1.0-partparams->VoicePar[nvoice].PVolume/127.0)) // -60 dB .. 0 dB
  293.         *VelF(velocity,partparams->VoicePar[nvoice].PAmpVelocityScaleFunction);//velocity
  294.         
  295.     if (partparams->VoicePar[nvoice].PVolumeminus!=0) NoteVoicePar[nvoice].Volume=-NoteVoicePar[nvoice].Volume;
  296.  
  297.     if (partparams->VoicePar[nvoice].PPanning==0) 
  298.         NoteVoicePar[nvoice].Panning=RND;// random panning
  299.     else NoteVoicePar[nvoice].Panning=partparams->VoicePar[nvoice].PPanning/128.0;
  300.  
  301.     newamplitude[nvoice]=1.0;
  302.     if (partparams->VoicePar[nvoice].PAmpEnvelopeEnabled!=0) {
  303.         NoteVoicePar[nvoice].AmpEnvelope=new Envelope(partparams->VoicePar[nvoice].AmpEnvelope,basefreq);
  304.         NoteVoicePar[nvoice].AmpEnvelope->envout_dB();//discard the first envelope sample
  305.         newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpEnvelope->envout_dB();
  306.         };
  307.  
  308.     if (partparams->VoicePar[nvoice].PAmpLfoEnabled!=0){
  309.         NoteVoicePar[nvoice].AmpLfo=new LFO(partparams->VoicePar[nvoice].AmpLfo,basefreq);
  310.         newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpLfo->amplfoout();
  311.     };
  312.  
  313.     /* Voice Frequency Parameters Init */
  314.     if (partparams->VoicePar[nvoice].PFreqEnvelopeEnabled!=0)
  315.          NoteVoicePar[nvoice].FreqEnvelope=new Envelope(partparams->VoicePar[nvoice].FreqEnvelope,basefreq);
  316.  
  317.     if (partparams->VoicePar[nvoice].PFreqLfoEnabled!=0) NoteVoicePar[nvoice].FreqLfo=new LFO(partparams->VoicePar[nvoice].FreqLfo,basefreq);
  318.  
  319.     /* Voice Filter Parameters Init */
  320.     if (partparams->VoicePar[nvoice].PFilterEnabled!=0){
  321.         NoteVoicePar[nvoice].VoiceFilter=new Filter(partparams->VoicePar[nvoice].VoiceFilter);
  322.     };
  323.  
  324.     if (partparams->VoicePar[nvoice].PFilterEnvelopeEnabled!=0)
  325.         NoteVoicePar[nvoice].FilterEnvelope=new Envelope(partparams->VoicePar[nvoice].FilterEnvelope,basefreq);
  326.     
  327.     if (partparams->VoicePar[nvoice].PFilterLfoEnabled!=0)
  328.         NoteVoicePar[nvoice].FilterLfo=new LFO(partparams->VoicePar[nvoice].FilterLfo,basefreq);
  329.     
  330.     NoteVoicePar[nvoice].FilterFreqTracking=partparams->VoicePar[nvoice].VoiceFilter->getfreqtracking(basefreq);
  331.     
  332.     /* Voice Modulation Parameters Init */
  333.     if ((NoteVoicePar[nvoice].FMEnabled!=NONE)&&(NoteVoicePar[nvoice].FMVoice<0)){
  334.        partparams->VoicePar[nvoice].FMSmp->newrandseed(rand());
  335.         NoteVoicePar[nvoice].FMSmp=new REALTYPE[OSCIL_SIZE+OSCIL_SMP_EXTRA_SAMPLES];
  336.  
  337.        //Perform Anti-aliasing only on MORPH or RING MODULATION
  338.  
  339.        int vc=nvoice; 
  340.             if (partparams->VoicePar[nvoice].PextFMoscil!=-1) vc=partparams->VoicePar[nvoice].PextFMoscil;
  341.  
  342.        REALTYPE tmp=1.0;
  343.        if ((partparams->VoicePar[vc].FMSmp->Padaptiveharmonics!=0)||
  344.         (NoteVoicePar[nvoice].FMEnabled==MORPH)||
  345.         (NoteVoicePar[nvoice].FMEnabled==RING_MOD)){
  346.         tmp=getFMvoicebasefreq(nvoice);
  347.         };
  348.        if (!partparams->GlobalPar.Hrandgrouping) partparams->VoicePar[vc].FMSmp->newrandseed(rand());
  349.        
  350.        oscposhiFM[nvoice]=(oscposhi[nvoice]+partparams->VoicePar[vc].FMSmp->get(NoteVoicePar[nvoice].FMSmp,tmp)) % OSCIL_SIZE;
  351.        for (int i=0;i<OSCIL_SMP_EXTRA_SAMPLES;i++) NoteVoicePar[nvoice].FMSmp[OSCIL_SIZE+i]=NoteVoicePar[nvoice].FMSmp[i];
  352.        oscposhiFM[nvoice]+=(int)((partparams->VoicePar[nvoice].PFMoscilphase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE*4);
  353.        oscposhiFM[nvoice]%=OSCIL_SIZE;
  354.     };
  355.  
  356.     if (partparams->VoicePar[nvoice].PFMFreqEnvelopeEnabled!=0)
  357.         NoteVoicePar[nvoice].FMFreqEnvelope=new Envelope(partparams->VoicePar[nvoice].FMFreqEnvelope,basefreq);
  358.  
  359.     FMnewamplitude[nvoice]=NoteVoicePar[nvoice].FMVolume*ctl->fmamp.relamp;
  360.  
  361.     if (partparams->VoicePar[nvoice].PFMAmpEnvelopeEnabled!=0){
  362.         NoteVoicePar[nvoice].FMAmpEnvelope=new Envelope(partparams->VoicePar[nvoice].FMAmpEnvelope,basefreq);
  363.         FMnewamplitude[nvoice]*=NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB();
  364.     };
  365.     };
  366.  
  367.     for (nvoice=0;nvoice<NUM_VOICES;nvoice++){
  368.     for (i=nvoice+1;i<NUM_VOICES;i++) tmp[i]=0;
  369.     for (i=nvoice+1;i<NUM_VOICES;i++) 
  370.     if ((NoteVoicePar[i].FMVoice==nvoice)&&(tmp[i]==0)){
  371.             NoteVoicePar[nvoice].VoiceOut=new REALTYPE[SOUND_BUFFER_SIZE];
  372.         tmp[i]=1;
  373.     };
  374.     if (NoteVoicePar[nvoice].VoiceOut!=NULL) for (i=0;i<SOUND_BUFFER_SIZE;i++) NoteVoicePar[nvoice].VoiceOut[i]=0.0;
  375.     };
  376. };
  377.  
  378.  
  379.  
  380. /*
  381.  * Computes the frequency of an oscillator
  382.  */
  383. void ADnote::setfreq(int nvoice,REALTYPE freq){
  384.     REALTYPE speed;
  385.     freq=fabs(freq);
  386.     speed=freq*REALTYPE(OSCIL_SIZE)/(REALTYPE) SAMPLE_RATE;
  387.     if (speed>OSCIL_SIZE) speed=OSCIL_SIZE;
  388.  
  389.     F2I(speed,oscfreqhi[nvoice]);
  390.     oscfreqlo[nvoice]=speed-floor(speed);
  391. };   
  392.  
  393. /*
  394.  * Computes the frequency of an modullator oscillator
  395.  */
  396. void ADnote::setfreqFM(int nvoice,REALTYPE freq){
  397.     REALTYPE speed;
  398.     freq=fabs(freq);
  399.     speed=freq*REALTYPE(OSCIL_SIZE)/(REALTYPE) SAMPLE_RATE;
  400.     if (speed>OSCIL_SIZE) speed=OSCIL_SIZE;
  401.  
  402.     F2I(speed,oscfreqhiFM[nvoice]);
  403.     oscfreqloFM[nvoice]=speed-floor(speed);
  404. };
  405.  
  406. /*
  407.  * Get Voice base frequency
  408.  */
  409. REALTYPE ADnote::getvoicebasefreq(int nvoice){
  410.     REALTYPE detune=NoteVoicePar[nvoice].Detune/100.0+
  411.         NoteVoicePar[nvoice].FineDetune/100.0*ctl->bandwidth.relbw+
  412.     NoteGlobalPar.Detune/100.0;
  413.     if (NoteVoicePar[nvoice].fixedfreq==0) return(this->basefreq*pow(2,detune/12.0));
  414.     else {//the fixed freq is enabled
  415.         REALTYPE fixedfreq=440.0;
  416.         int fixedfreqET=NoteVoicePar[nvoice].fixedfreqET;
  417.         if (fixedfreqET!=0) {//if the frequency varies according the keyboard note 
  418.         REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0);
  419.         if (fixedfreqET<=64) fixedfreq*=pow(2.0,tmp);
  420.             else fixedfreq*=pow(3.0,tmp);
  421.         };
  422.         return(fixedfreq*pow(2.0,detune/12.0));
  423.     };
  424. };
  425.  
  426. /*
  427.  * Get Voice's Modullator base frequency
  428.  */
  429. REALTYPE ADnote::getFMvoicebasefreq(int nvoice){
  430.     REALTYPE detune=NoteVoicePar[nvoice].FMDetune/100.0;
  431.     return(getvoicebasefreq(nvoice)*pow(2,detune/12.0));
  432. };
  433.  
  434. /*
  435.  * Computes all the parameters for each tick
  436.  */
  437. void ADnote::computecurrentparameters(){
  438.     int nvoice;
  439.     REALTYPE voicefreq,voicepitch,filterpitch,filterfreq,FMfreq,FMrelativepitch,globalpitch,globalfilterpitch;
  440.     globalpitch=0.01*(NoteGlobalPar.FreqEnvelope->envout()+
  441.     NoteGlobalPar.FreqLfo->lfoout()*ctl->modwheel.relmod);
  442.     globaloldamplitude=globalnewamplitude;
  443.     globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout();
  444.     
  445.     globalfilterpitch=NoteGlobalPar.FilterEnvelope->envout()+NoteGlobalPar.FilterLfo->lfoout()
  446.                       +NoteGlobalPar.FilterCenterPitch;
  447.               
  448.     REALTYPE tmpfilterfreq=globalfilterpitch+ctl->filtercutoff.relfreq
  449.             +NoteGlobalPar.FilterFreqTracking;
  450.     
  451.     tmpfilterfreq=NoteGlobalPar.GlobalFilterL->getrealfreq(tmpfilterfreq);
  452.     
  453.     REALTYPE globalfilterq=NoteGlobalPar.FilterQ*ctl->filterq.relq;
  454.     NoteGlobalPar.GlobalFilterL->setfreq_and_q(tmpfilterfreq,globalfilterq);
  455.     if (stereo!=0) NoteGlobalPar.GlobalFilterR->setfreq_and_q(tmpfilterfreq,globalfilterq);
  456.  
  457.     //compute the portamento, if it is used by this note
  458.     REALTYPE portamentofreqrap=1.0;    
  459.     if (portamento!=0){//this voice use portamento
  460.     portamentofreqrap=ctl->portamento.freqrap;
  461.     if (ctl->portamento.used==0){//the portamento has finished
  462.         portamento=0;//this note is no longer "portamented"
  463.     };
  464.     };
  465.     
  466.     //compute parameters for all voices
  467.     for (nvoice=0;nvoice<NUM_VOICES;nvoice++){
  468.     if (NoteVoicePar[nvoice].Enabled!=ON) continue;
  469.     NoteVoicePar[nvoice].DelayTicks-=1;
  470.     if (NoteVoicePar[nvoice].DelayTicks>0) continue;
  471.         
  472.     /*******************/
  473.     /* Voice Amplitude */
  474.     /*******************/
  475.         oldamplitude[nvoice]=newamplitude[nvoice];
  476.     newamplitude[nvoice]=1.0;
  477.  
  478.     if (NoteVoicePar[nvoice].AmpEnvelope!=NULL)
  479.         newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpEnvelope->envout_dB();        
  480.  
  481.     if (NoteVoicePar[nvoice].AmpLfo!=NULL) 
  482.             newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpLfo->amplfoout();        
  483.  
  484.     /****************/
  485.     /* Voice Filter */
  486.     /****************/
  487.     if (NoteVoicePar[nvoice].VoiceFilter!=NULL){
  488.         filterpitch=NoteVoicePar[nvoice].FilterCenterPitch;  
  489.  
  490.         if (NoteVoicePar[nvoice].FilterEnvelope!=NULL) 
  491.         filterpitch+=NoteVoicePar[nvoice].FilterEnvelope->envout();
  492.  
  493.         if (NoteVoicePar[nvoice].FilterLfo!=NULL) 
  494.         filterpitch+=NoteVoicePar[nvoice].FilterLfo->lfoout();
  495.         
  496.         filterfreq=filterpitch+NoteVoicePar[nvoice].FilterFreqTracking;
  497.         filterfreq=NoteVoicePar[nvoice].VoiceFilter->getrealfreq(filterfreq);
  498.         
  499.         NoteVoicePar[nvoice].VoiceFilter->setfreq(filterfreq);
  500.     };
  501.  
  502.     if (NoteVoicePar[nvoice].noisetype==0){//compute only if the voice isn't noise
  503.  
  504.         /*******************/
  505.         /* Voice Frequency */
  506.         /*******************/
  507.         voicepitch=0.0;
  508.         if (NoteVoicePar[nvoice].FreqLfo!=NULL) 
  509.         voicepitch+=NoteVoicePar[nvoice].FreqLfo->lfoout()/100.0
  510.                      *ctl->bandwidth.relbw;
  511.  
  512.         if (NoteVoicePar[nvoice].FreqEnvelope!=NULL) voicepitch+=NoteVoicePar[nvoice].FreqEnvelope->envout()/100.0;
  513.         voicefreq=getvoicebasefreq(nvoice)*pow(2,(voicepitch+globalpitch)/12.0);//Hz frequency
  514.         voicefreq*=ctl->pitchwheel.relfreq;//change the frequency by the controller
  515.         setfreq(nvoice,voicefreq*portamentofreqrap);    
  516.  
  517.         /***************/
  518.         /*  Modulator */
  519.         /***************/
  520.         if (NoteVoicePar[nvoice].FMEnabled!=NONE){
  521.         FMrelativepitch=NoteVoicePar[nvoice].FMDetune/100.0;
  522.         if (NoteVoicePar[nvoice].FMFreqEnvelope!=NULL) FMrelativepitch+=NoteVoicePar[nvoice].FMFreqEnvelope->envout()/100;
  523.             FMfreq=pow(2.0,FMrelativepitch/12.0)*voicefreq*portamentofreqrap;
  524.         setfreqFM(nvoice,FMfreq);
  525.  
  526.         FMoldamplitude[nvoice]=FMnewamplitude[nvoice];
  527.         FMnewamplitude[nvoice]=NoteVoicePar[nvoice].FMVolume*ctl->fmamp.relamp;
  528.         if (NoteVoicePar[nvoice].FMAmpEnvelope!=NULL) 
  529.                 FMnewamplitude[nvoice]*=NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB();
  530.         };
  531.     };
  532.     
  533.     };
  534.     time+=(REALTYPE)SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE;
  535. };
  536.  
  537.  
  538. /*
  539.  * Fadein in a way that removes clicks but keep sound "punchy"
  540.  */
  541. inline void ADnote::fadein(REALTYPE *smps){
  542.     int zerocrossings=0;
  543.     for (int i=1;i<SOUND_BUFFER_SIZE;i++)
  544.     if ((smps[i-1]<0.0) && (smps[i]>0.0)) zerocrossings++;//this is only the possitive crossings
  545.  
  546.     REALTYPE tmp=(SOUND_BUFFER_SIZE-1.0)/(zerocrossings+1)/3.0;
  547.     if (tmp<8.0) tmp=8.0;
  548.  
  549.     int n;
  550.     F2I(tmp,n);//how many samples is the fade-in    
  551.     if (n>SOUND_BUFFER_SIZE) n=SOUND_BUFFER_SIZE;
  552.     for (int i=0;i<n;i++) {//fade-in
  553.     REALTYPE tmp=0.5-cos((REALTYPE)i/(REALTYPE) n*PI)*0.5;
  554.     smps[i]*=tmp;
  555.     };
  556. };
  557.  
  558. /*
  559.  * Computes the Oscillator (Without Modulation) - LinearInterpolation
  560.  */
  561. inline void ADnote::ComputeVoiceOscillator_LinearInterpolation(int nvoice){    
  562.     int i,poshi;
  563.     REALTYPE poslo;
  564.  
  565.     poshi=oscposhi[nvoice];
  566.     poslo=oscposlo[nvoice];
  567.     REALTYPE *smps=NoteVoicePar[nvoice].OscilSmp;
  568.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  569.     tmpwave[i]=smps[poshi]*(1.0-poslo)+smps[poshi+1]*poslo;
  570.     poslo+=oscfreqlo[nvoice];
  571.     if (poslo>=1.0) {
  572.             poslo-=1.0;    
  573.         poshi++;
  574.     };
  575.         poshi+=oscfreqhi[nvoice];    
  576.         poshi&=OSCIL_SIZE-1;
  577.     };
  578.     oscposhi[nvoice]=poshi;
  579.     oscposlo[nvoice]=poslo;
  580. };
  581.  
  582.  
  583.  
  584. /*
  585.  * Computes the Oscillator (Without Modulation) - CubicInterpolation
  586.  *
  587.  The differences from the Linear are to little to deserve to be used. This is because I am using a large OSCIL_SIZE (>512)
  588. inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int nvoice){    
  589.     int i,poshi;
  590.     REALTYPE poslo;
  591.  
  592.     poshi=oscposhi[nvoice];
  593.     poslo=oscposlo[nvoice];
  594.     REALTYPE *smps=NoteVoicePar[nvoice].OscilSmp;
  595.     REALTYPE xm1,x0,x1,x2,a,b,c;
  596.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  597.     xm1=smps[poshi];
  598.     x0=smps[poshi+1];
  599.     x1=smps[poshi+2];
  600.     x2=smps[poshi+3];
  601.     a=(3.0 * (x0-x1) - xm1 + x2) / 2.0;
  602.     b = 2.0*x1 + xm1 - (5.0*x0 + x2) / 2.0;
  603.     c = (x1 - xm1) / 2.0;
  604.     tmpwave[i]=(((a * poslo) + b) * poslo + c) * poslo + x0;
  605.     printf("a\n");
  606.     //tmpwave[i]=smps[poshi]*(1.0-poslo)+smps[poshi+1]*poslo;
  607.     poslo+=oscfreqlo[nvoice];
  608.     if (poslo>=1.0) {
  609.             poslo-=1.0;    
  610.         poshi++;
  611.     };
  612.         poshi+=oscfreqhi[nvoice];    
  613.         poshi&=OSCIL_SIZE-1;
  614.     };
  615.     oscposhi[nvoice]=poshi;
  616.     oscposlo[nvoice]=poslo;
  617. };
  618. */
  619. /*
  620.  * Computes the Oscillator (Morphing)
  621.  */
  622. inline void ADnote::ComputeVoiceOscillatorMorph(int nvoice){    
  623.     int i;
  624.     REALTYPE amp;
  625.     ComputeVoiceOscillator_LinearInterpolation(nvoice);    
  626.     if (FMnewamplitude[nvoice]>1.0) FMnewamplitude[nvoice]=1.0;
  627.     if (FMoldamplitude[nvoice]>1.0) FMoldamplitude[nvoice]=1.0;
  628.     
  629.     if (NoteVoicePar[nvoice].FMVoice>=0){
  630.     //if I use VoiceOut[] as modullator
  631.     int FMVoice=NoteVoicePar[nvoice].FMVoice;
  632.     for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  633.         amp=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice]
  634.                 ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE);
  635.         tmpwave[i]=tmpwave[i]*(1.0-amp)+amp*NoteVoicePar[FMVoice].VoiceOut[i];
  636.         };
  637.     } else {
  638.     int poshiFM=oscposhiFM[nvoice];
  639.     REALTYPE posloFM=oscposloFM[nvoice];
  640.  
  641.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  642.         amp=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice]
  643.                 ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE);
  644.         tmpwave[i]=tmpwave[i]*(1.0-amp)+amp
  645.                   *(NoteVoicePar[nvoice].FMSmp[poshiFM]*(1-posloFM)
  646.                +NoteVoicePar[nvoice].FMSmp[poshiFM+1]*posloFM);
  647.         posloFM+=oscfreqloFM[nvoice];
  648.         if (posloFM>=1.0) {
  649.             posloFM-=1.0;    
  650.         poshiFM++;
  651.         };
  652.             poshiFM+=oscfreqhiFM[nvoice];    
  653.             poshiFM&=OSCIL_SIZE-1;
  654.     };
  655.     oscposhiFM[nvoice]=poshiFM;
  656.     oscposloFM[nvoice]=posloFM;
  657.     };
  658. };
  659.  
  660. /*
  661.  * Computes the Oscillator (Ring Modulation)
  662.  */
  663. inline void ADnote::ComputeVoiceOscillatorRingModulation(int nvoice){    
  664.     int i;
  665.     REALTYPE amp;
  666.     ComputeVoiceOscillator_LinearInterpolation(nvoice);    
  667.     if (FMnewamplitude[nvoice]>1.0) FMnewamplitude[nvoice]=1.0;
  668.     if (FMoldamplitude[nvoice]>1.0) FMoldamplitude[nvoice]=1.0;
  669.     if (NoteVoicePar[nvoice].FMVoice>=0){
  670.     // if I use VoiceOut[] as modullator
  671.     for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  672.         amp=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice]
  673.                 ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE);
  674.         int FMVoice=NoteVoicePar[nvoice].FMVoice;
  675.         for (i=0;i<SOUND_BUFFER_SIZE;i++) 
  676.          tmpwave[i]*=(1.0-amp)+amp*NoteVoicePar[FMVoice].VoiceOut[i];
  677.     };
  678.     } else {
  679.     int poshiFM=oscposhiFM[nvoice];
  680.     REALTYPE posloFM=oscposloFM[nvoice];
  681.  
  682.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  683.         amp=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice]
  684.                 ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE);
  685.         tmpwave[i]*=( NoteVoicePar[nvoice].FMSmp[poshiFM]*(1.0-posloFM)
  686.                      +NoteVoicePar[nvoice].FMSmp[poshiFM+1]*posloFM)*amp
  687.              +(1.0-amp);
  688.         posloFM+=oscfreqloFM[nvoice];
  689.         if (posloFM>=1.0) {
  690.             posloFM-=1.0;    
  691.         poshiFM++;
  692.         };
  693.             poshiFM+=oscfreqhiFM[nvoice];    
  694.             poshiFM&=OSCIL_SIZE-1;
  695.     };
  696.     oscposhiFM[nvoice]=poshiFM;
  697.     oscposloFM[nvoice]=posloFM;
  698.     };
  699. };
  700.  
  701.  
  702.  
  703. /*
  704.  * Computes the Oscillator (Phase Modulation or Frequency Modulation)
  705.  */
  706. inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int nvoice,int FMmode){
  707.     int carposhi;
  708.     int i,FMmodfreqhi;
  709.     REALTYPE FMmodfreqlo,carposlo;
  710.     
  711.     if (NoteVoicePar[nvoice].FMVoice>=0){
  712.     //if I use VoiceOut[] as modulator
  713.     for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwave[i]=NoteVoicePar[NoteVoicePar[nvoice].FMVoice].VoiceOut[i];
  714.     } else {
  715.     //Compute the modulator and store it in tmpwave[]
  716.     int poshiFM=oscposhiFM[nvoice];
  717.     REALTYPE posloFM=oscposloFM[nvoice];
  718.  
  719.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  720.         tmpwave[i]=(NoteVoicePar[nvoice].FMSmp[poshiFM]*(1.0-posloFM)
  721.                    +NoteVoicePar[nvoice].FMSmp[poshiFM+1]*posloFM);
  722.         posloFM+=oscfreqloFM[nvoice];
  723.         if (posloFM>=1.0) {
  724.         posloFM=fmod(posloFM,1.0);
  725.         poshiFM++;
  726.         };
  727.             poshiFM+=oscfreqhiFM[nvoice];    
  728.             poshiFM&=OSCIL_SIZE-1;
  729.     };
  730.     oscposhiFM[nvoice]=poshiFM;
  731.     oscposloFM[nvoice]=posloFM;
  732.     };
  733.     // Amplitude interpolation
  734.     if (ABOVE_AMPLITUDE_THRESHOLD(FMoldamplitude[nvoice],FMnewamplitude[nvoice])){
  735.           for (i=0;i<SOUND_BUFFER_SIZE;i++){
  736.         tmpwave[i]*=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice]
  737.                       ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE);
  738.         };
  739.     } else for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwave[i]*=FMnewamplitude[nvoice];
  740.  
  741.  
  742.     //normalize makes all sample-rates, oscil_sizes toproduce same sound    
  743.     if (FMmode!=0){//Frequency modulation
  744.     REALTYPE normalize=OSCIL_SIZE/262144.0*44100.0/(REALTYPE)SAMPLE_RATE;
  745.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  746.         FMoldsmp[nvoice]=fmod(FMoldsmp[nvoice]+tmpwave[i]*normalize,OSCIL_SIZE);
  747.         tmpwave[i]=FMoldsmp[nvoice];
  748.     };
  749.     } else {//Phase modulation 
  750.     REALTYPE normalize=OSCIL_SIZE/262144.0;
  751.     for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwave[i]*=normalize;
  752.     };
  753.  
  754.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  755.     F2I(tmpwave[i],FMmodfreqhi);
  756.     FMmodfreqlo=fmod(tmpwave[i]+0.0000000001,1.0); 
  757.     if (FMmodfreqhi<0) FMmodfreqlo++;
  758.     
  759.     //carrier
  760.     carposhi=oscposhi[nvoice]+FMmodfreqhi;
  761.     carposlo=oscposlo[nvoice]+FMmodfreqlo;
  762.  
  763.     if (carposlo>=1.0) {
  764.         carposhi++;
  765.         carposlo=fmod(carposlo,1.0);
  766.     };
  767.     carposhi&=(OSCIL_SIZE-1);    
  768.         
  769.     tmpwave[i]=NoteVoicePar[nvoice].OscilSmp[carposhi]*(1.0-carposlo)
  770.               +NoteVoicePar[nvoice].OscilSmp[carposhi+1]*carposlo;
  771.  
  772.     oscposlo[nvoice]+=oscfreqlo[nvoice];
  773.     if (oscposlo[nvoice]>=1.0) {
  774.             oscposlo[nvoice]=fmod(oscposlo[nvoice],1.0);    
  775.         oscposhi[nvoice]++;
  776.     };
  777.             
  778.         oscposhi[nvoice]+=oscfreqhi[nvoice];    
  779.     oscposhi[nvoice]&=OSCIL_SIZE-1;
  780.     };
  781. };
  782.  
  783.  
  784. /*Calculeaza Oscilatorul cu PITCH MODULATION*/
  785. inline void ADnote::ComputeVoiceOscillatorPitchModulation(int nvoice){    
  786. //TODO
  787. };
  788.  
  789. /*
  790.  * Computes the Noise 
  791.  */
  792. inline void ADnote::ComputeVoiceNoise(int nvoice){    
  793.     for (int i=0;i<SOUND_BUFFER_SIZE;i++) tmpwave[i]=RND*2.0-1.0;
  794. };
  795.  
  796.  
  797.  
  798. /*
  799.  * Compute the ADnote samples 
  800.  * Returns 0 if the note is finished
  801.  */
  802. int ADnote::noteout(REALTYPE *outl,REALTYPE *outr){
  803.   int i,nvoice;
  804.     
  805.   for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  806.     outl[i]=denormalkillbuf[i];
  807.     outr[i]=denormalkillbuf[i];
  808.   };
  809.  
  810.   if (NoteEnabled==OFF) return(0);
  811.  
  812.   for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  813.     bypassl[i]=0.0;
  814.     bypassr[i]=0.0;
  815.   };
  816.   
  817.   computecurrentparameters();    
  818.  
  819.   for (nvoice=0;nvoice<NUM_VOICES;nvoice++){
  820.     if ((NoteVoicePar[nvoice].Enabled!=ON) || (NoteVoicePar[nvoice].DelayTicks>0)) continue;    
  821.     if (NoteVoicePar[nvoice].noisetype==0){//voice mode=sound
  822.         switch (NoteVoicePar[nvoice].FMEnabled){
  823.         case MORPH:ComputeVoiceOscillatorMorph(nvoice);break;
  824.         case RING_MOD:ComputeVoiceOscillatorRingModulation(nvoice);break;
  825.         case PHASE_MOD:ComputeVoiceOscillatorFrequencyModulation(nvoice,0);break;
  826.         case FREQ_MOD:ComputeVoiceOscillatorFrequencyModulation(nvoice,1);break;
  827.         //case PITCH_MOD:ComputeVoiceOscillatorPitchModulation(nvoice);break;
  828.         default:ComputeVoiceOscillator_LinearInterpolation(nvoice);
  829.         //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(nvoice);
  830.                 
  831.         };
  832.     } else ComputeVoiceNoise(nvoice);
  833.     // Voice Processing
  834.     
  835.      // Amplitude
  836.      if (ABOVE_AMPLITUDE_THRESHOLD(oldamplitude[nvoice],newamplitude[nvoice])){
  837.           int rest=SOUND_BUFFER_SIZE;
  838.           //test if the amplitude if raising and the difference is high
  839.       if ((newamplitude[nvoice]>oldamplitude[nvoice])&&((newamplitude[nvoice]-oldamplitude[nvoice])>0.25)){
  840.         rest=10;
  841.         if (rest>SOUND_BUFFER_SIZE) rest=SOUND_BUFFER_SIZE;
  842.         for (int i=0;i<SOUND_BUFFER_SIZE-rest;i++) tmpwave[i]*=oldamplitude[nvoice];
  843.       };
  844.           // Amplitude interpolation
  845.           for (i=0;i<rest;i++){
  846.         tmpwave[i+(SOUND_BUFFER_SIZE-rest)]*=INTERPOLATE_AMPLITUDE(oldamplitude[nvoice]
  847.          ,newamplitude[nvoice],i,rest);
  848.       };
  849.     } else for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwave[i]*=newamplitude[nvoice];
  850.  
  851.      // Fade in
  852.       if (firsttick[nvoice]!=0){
  853.           fadein(&tmpwave[0]);
  854.           firsttick[nvoice]=0;
  855.       };
  856.  
  857.  
  858.      // Filter
  859.      if (NoteVoicePar[nvoice].VoiceFilter!=NULL) NoteVoicePar[nvoice].VoiceFilter->filterout(&tmpwave[0]);
  860.  
  861.     //check if the amplitude envelope is finished, if yes, the voice will be fadeout
  862.       if (NoteVoicePar[nvoice].AmpEnvelope!=NULL) {
  863.     if (NoteVoicePar[nvoice].AmpEnvelope->finished()!=0)
  864.         for (i=0;i<SOUND_BUFFER_SIZE;i++) 
  865.                tmpwave[i]*=1.0-(REALTYPE)i/(REALTYPE)SOUND_BUFFER_SIZE;
  866.     //the voice is killed later
  867.       };
  868.     
  869.  
  870.      // Put the ADnote samples in VoiceOut (without appling Global volume, because I wish to use this voice as a modullator)
  871.      if (NoteVoicePar[nvoice].VoiceOut!=NULL) 
  872.     for (i=0;i<SOUND_BUFFER_SIZE;i++) NoteVoicePar[nvoice].VoiceOut[i]=tmpwave[i];
  873.  
  874.  
  875.      // Add the voice that do not bypass the filter to out
  876.       if (NoteVoicePar[nvoice].filterbypass==0){//no bypass
  877.           if (stereo==0) for (i=0;i<SOUND_BUFFER_SIZE;i++) outl[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume;//mono
  878.           else for (i=0;i<SOUND_BUFFER_SIZE;i++) {//stereo
  879.             outl[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume*NoteVoicePar[nvoice].Panning*2.0;
  880.             outr[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume*(1.0-NoteVoicePar[nvoice].Panning)*2.0;
  881.            };
  882.       } else {//bypass the filter
  883.           if (stereo==0) for (i=0;i<SOUND_BUFFER_SIZE;i++) bypassl[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume;//mono
  884.           else for (i=0;i<SOUND_BUFFER_SIZE;i++) {//stereo
  885.             bypassl[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume*NoteVoicePar[nvoice].Panning*2.0;
  886.             bypassr[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume*(1.0-NoteVoicePar[nvoice].Panning)*2.0;
  887.            };            
  888.       };
  889.     // chech if there is necesary to proces the voice longer (if the Amplitude envelope isn't finished)
  890.       if (NoteVoicePar[nvoice].AmpEnvelope!=NULL) {
  891.          if (NoteVoicePar[nvoice].AmpEnvelope->finished()!=0) KillVoice(nvoice);
  892.      };
  893.   };
  894.  
  895.  
  896.   //Processing Global parameters
  897.   NoteGlobalPar.GlobalFilterL->filterout(&outl[0]); 
  898.  
  899.   if (stereo==0) {
  900.     for (i=0;i<SOUND_BUFFER_SIZE;i++) {//set the right channel=left channel
  901.         outr[i]=outl[i];
  902.         bypassr[i]=bypassl[i];
  903.     } 
  904.   } else NoteGlobalPar.GlobalFilterR->filterout(&outr[0]); 
  905.   
  906.   for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  907.     outl[i]+=bypassl[i];
  908.     outr[i]+=bypassr[i];
  909.   };
  910.   
  911.   if (ABOVE_AMPLITUDE_THRESHOLD(globaloldamplitude,globalnewamplitude)){
  912.     // Amplitude Interpolation
  913.         for (i=0;i<SOUND_BUFFER_SIZE;i++){
  914.        REALTYPE tmpvol=INTERPOLATE_AMPLITUDE(globaloldamplitude
  915.               ,globalnewamplitude,i,SOUND_BUFFER_SIZE);
  916.        outl[i]*=tmpvol*NoteGlobalPar.Panning;
  917.        outr[i]*=tmpvol*(1.0-NoteGlobalPar.Panning); 
  918.         };
  919.   } else { 
  920.     for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  921.         outl[i]*=globalnewamplitude*NoteGlobalPar.Panning;
  922.         outr[i]*=globalnewamplitude*(1.0-NoteGlobalPar.Panning);
  923.     };
  924.   };
  925.  
  926.  //Apply the punch
  927.  if (NoteGlobalPar.Punch.Enabled!=0){
  928.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  929.     REALTYPE punchamp=NoteGlobalPar.Punch.initialvalue*NoteGlobalPar.Punch.t+1.0;
  930.     outl[i]*=punchamp;
  931.     outr[i]*=punchamp;
  932.     NoteGlobalPar.Punch.t-=NoteGlobalPar.Punch.dt;
  933.     if (NoteGlobalPar.Punch.t<0.0) {
  934.         NoteGlobalPar.Punch.Enabled=0;
  935.         break;
  936.     };
  937.     }; 
  938.  };
  939.       
  940.  // Check if the global amplitude is finished. 
  941.  // If it does, disable the note     
  942.  if (NoteGlobalPar.AmpEnvelope->finished()!=0) {
  943.         for (i=0;i<SOUND_BUFFER_SIZE;i++) {//fade-out
  944.         REALTYPE tmp=1.0-(REALTYPE)i/(REALTYPE)SOUND_BUFFER_SIZE;
  945.         outl[i]*=tmp;
  946.         outr[i]*=tmp;
  947.         };
  948.         KillNote(); 
  949.  };
  950.  return(1);
  951. };
  952.  
  953.  
  954. /*
  955.  * Relase the key (NoteOff)
  956.  */
  957. void ADnote::relasekey(){
  958. int nvoice;
  959.   for (nvoice=0;nvoice<NUM_VOICES;nvoice++){
  960.     if (NoteVoicePar[nvoice].Enabled==0) continue;
  961.     if (NoteVoicePar[nvoice].AmpEnvelope!=NULL) NoteVoicePar[nvoice].AmpEnvelope->relasekey(); 
  962.     if (NoteVoicePar[nvoice].FreqEnvelope!=NULL) NoteVoicePar[nvoice].FreqEnvelope->relasekey(); 
  963.     if (NoteVoicePar[nvoice].FilterEnvelope!=NULL) NoteVoicePar[nvoice].FilterEnvelope->relasekey(); 
  964.     if (NoteVoicePar[nvoice].FMFreqEnvelope!=NULL) NoteVoicePar[nvoice].FMFreqEnvelope->relasekey(); 
  965.     if (NoteVoicePar[nvoice].FMAmpEnvelope!=NULL) NoteVoicePar[nvoice].FMAmpEnvelope->relasekey(); 
  966.   };
  967.   NoteGlobalPar.FreqEnvelope->relasekey();
  968.   NoteGlobalPar.FilterEnvelope->relasekey();
  969.   NoteGlobalPar.AmpEnvelope->relasekey();
  970.  
  971. };
  972.  
  973. /*
  974.  * Check if the note is finished
  975.  */
  976. int ADnote::finished(){
  977.     if (NoteEnabled==ON) return(0);
  978.     else return(1);
  979. };
  980.  
  981.  
  982.  
  983.