summaryrefslogtreecommitdiff
path: root/attic/muse_qt4_evolution/synti/zynaddsubfx/Synth/ADnote.C
diff options
context:
space:
mode:
Diffstat (limited to 'attic/muse_qt4_evolution/synti/zynaddsubfx/Synth/ADnote.C')
-rw-r--r--attic/muse_qt4_evolution/synti/zynaddsubfx/Synth/ADnote.C984
1 files changed, 0 insertions, 984 deletions
diff --git a/attic/muse_qt4_evolution/synti/zynaddsubfx/Synth/ADnote.C b/attic/muse_qt4_evolution/synti/zynaddsubfx/Synth/ADnote.C
deleted file mode 100644
index 574e2bea..00000000
--- a/attic/muse_qt4_evolution/synti/zynaddsubfx/Synth/ADnote.C
+++ /dev/null
@@ -1,984 +0,0 @@
-/*
- ZynAddSubFX - a software synthesizer
-
- ADnote.C - The "additive" synthesizer
- Copyright (C) 2002-2005 Nasca Octavian Paul
- Author: Nasca Octavian Paul
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License
- as published by the Free Software Foundation.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License (version 2) for more details.
-
- You should have received a copy of the GNU General Public License (version 2)
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <math.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-
-#include "../globals.h"
-#include "../Misc/Util.h"
-#include "ADnote.h"
-
-
-ADnote::ADnote(ADnoteParameters *pars,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote_){
- ready=0;
-
- tmpwave=new REALTYPE [SOUND_BUFFER_SIZE];
- bypassl=new REALTYPE [SOUND_BUFFER_SIZE];
- bypassr=new REALTYPE [SOUND_BUFFER_SIZE];
-
- 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;
- continue; //the voice is disabled
- };
-
- 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
-
- //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);
-
- //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;
-
- //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;//???????????
- // break;
- default:if (fmvoldamp>1.0) fmvoldamp=1.0;
- NoteVoicePar[nvoice].FMVolume=pars->VoicePar[nvoice].PFMVolume/127.0*fmvoldamp;
- };
-
- //Voice's modulator velocity sensing
- NoteVoicePar[nvoice].FMVolume*=VelF(velocity,partparams->VoicePar[nvoice].PFMVelocityScaleFunction);
-
- FMoldsmp[nvoice]=0.0;//this is for FM (integration)
-
- firsttick[nvoice]=1;
- NoteVoicePar[nvoice].DelayTicks=(int)((exp(pars->VoicePar[nvoice].PDelay/127.0*log(50.0))-1.0)/SOUND_BUFFER_SIZE/10.0*SAMPLE_RATE);
- };
-
- initparameters();
- ready=1;
-};
-
-
-/*
- * Kill a voice of ADnote
- */
-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;
-};
-
-/*
- * Kill the note
- */
-void ADnote::KillNote(){
- int nvoice;
- for (nvoice=0;nvoice<NUM_VOICES;nvoice++){
- if (NoteVoicePar[nvoice].Enabled==ON) KillVoice(nvoice);
-
- //delete VoiceOut
- if (NoteVoicePar[nvoice].VoiceOut!=NULL) delete(NoteVoicePar[nvoice].VoiceOut);
- NoteVoicePar[nvoice].VoiceOut=NULL;
- };
-
- 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);
-
- NoteEnabled=OFF;
-};
-
-ADnote::~ADnote(){
- if (NoteEnabled==ON) KillNote();
- delete [] tmpwave;
- delete [] bypassl;
- delete [] bypassr;
-};
-
-
-/*
- * Init the parameters
- */
-void ADnote::initparameters(){
- int nvoice,i,tmp[NUM_VOICES];
-
- // Global Parameters
- NoteGlobalPar.FreqEnvelope=new Envelope(partparams->GlobalPar.FreqEnvelope,basefreq);
- NoteGlobalPar.FreqLfo=new LFO(partparams->GlobalPar.FreqLfo,basefreq);
-
- NoteGlobalPar.AmpEnvelope=new Envelope(partparams->GlobalPar.AmpEnvelope,basefreq);
- NoteGlobalPar.AmpLfo=new LFO(partparams->GlobalPar.AmpLfo,basefreq);
-
- NoteGlobalPar.Volume=4.0*pow(0.1,3.0*(1.0-partparams->GlobalPar.PVolume/96.0))//-60 dB .. 0 dB
- *VelF(velocity,partparams->GlobalPar.PAmpVelocityScaleFunction);//velocity sensing
-
- NoteGlobalPar.AmpEnvelope->envout_dB();//discard the first envelope output
- globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout();
-
- NoteGlobalPar.GlobalFilterL=new Filter(partparams->GlobalPar.GlobalFilter);
- if (stereo!=0) NoteGlobalPar.GlobalFilterR=new Filter(partparams->GlobalPar.GlobalFilter);
-
- NoteGlobalPar.FilterEnvelope=new Envelope(partparams->GlobalPar.FilterEnvelope,basefreq);
- NoteGlobalPar.FilterLfo=new LFO(partparams->GlobalPar.FilterLfo,basefreq);
- NoteGlobalPar.FilterQ=partparams->GlobalPar.GlobalFilter->getq();
- NoteGlobalPar.FilterFreqTracking=partparams->GlobalPar.GlobalFilter->getfreqtracking(basefreq);
-
- // 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;
-
- // Voice Parameter init
- for (nvoice=0;nvoice<NUM_VOICES;nvoice++){
- if (NoteVoicePar[nvoice].Enabled==0) continue;
-
- NoteVoicePar[nvoice].noisetype=partparams->VoicePar[nvoice].Type;
- /* Voice Amplitude Parameters Init */
- NoteVoicePar[nvoice].Volume=pow(0.1,3.0*(1.0-partparams->VoicePar[nvoice].PVolume/127.0)) // -60 dB .. 0 dB
- *VelF(velocity,partparams->VoicePar[nvoice].PAmpVelocityScaleFunction);//velocity
-
- if (partparams->VoicePar[nvoice].PVolumeminus!=0) NoteVoicePar[nvoice].Volume=-NoteVoicePar[nvoice].Volume;
-
- if (partparams->VoicePar[nvoice].PPanning==0)
- NoteVoicePar[nvoice].Panning=RND;// random panning
- else NoteVoicePar[nvoice].Panning=partparams->VoicePar[nvoice].PPanning/128.0;
-
- newamplitude[nvoice]=1.0;
- if (partparams->VoicePar[nvoice].PAmpEnvelopeEnabled!=0) {
- NoteVoicePar[nvoice].AmpEnvelope=new Envelope(partparams->VoicePar[nvoice].AmpEnvelope,basefreq);
- NoteVoicePar[nvoice].AmpEnvelope->envout_dB();//discard the first envelope sample
- newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpEnvelope->envout_dB();
- };
-
- if (partparams->VoicePar[nvoice].PAmpLfoEnabled!=0){
- NoteVoicePar[nvoice].AmpLfo=new LFO(partparams->VoicePar[nvoice].AmpLfo,basefreq);
- newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpLfo->amplfoout();
- };
-
- /* Voice Frequency Parameters Init */
- if (partparams->VoicePar[nvoice].PFreqEnvelopeEnabled!=0)
- NoteVoicePar[nvoice].FreqEnvelope=new Envelope(partparams->VoicePar[nvoice].FreqEnvelope,basefreq);
-
- if (partparams->VoicePar[nvoice].PFreqLfoEnabled!=0) NoteVoicePar[nvoice].FreqLfo=new LFO(partparams->VoicePar[nvoice].FreqLfo,basefreq);
-
- /* Voice Filter Parameters Init */
- if (partparams->VoicePar[nvoice].PFilterEnabled!=0){
- NoteVoicePar[nvoice].VoiceFilter=new Filter(partparams->VoicePar[nvoice].VoiceFilter);
- };
-
- if (partparams->VoicePar[nvoice].PFilterEnvelopeEnabled!=0)
- NoteVoicePar[nvoice].FilterEnvelope=new Envelope(partparams->VoicePar[nvoice].FilterEnvelope,basefreq);
-
- if (partparams->VoicePar[nvoice].PFilterLfoEnabled!=0)
- NoteVoicePar[nvoice].FilterLfo=new LFO(partparams->VoicePar[nvoice].FilterLfo,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());
- NoteVoicePar[nvoice].FMSmp=new REALTYPE[OSCIL_SIZE+OSCIL_SMP_EXTRA_SAMPLES];
-
- //Perform Anti-aliasing only on MORPH or RING MODULATION
-
- int vc=nvoice;
- if (partparams->VoicePar[nvoice].PextFMoscil!=-1) vc=partparams->VoicePar[nvoice].PextFMoscil;
-
- REALTYPE tmp=1.0;
- if ((partparams->VoicePar[vc].FMSmp->Padaptiveharmonics!=0)||
- (NoteVoicePar[nvoice].FMEnabled==MORPH)||
- (NoteVoicePar[nvoice].FMEnabled==RING_MOD)){
- tmp=getFMvoicebasefreq(nvoice);
- };
- if (!partparams->GlobalPar.Hrandgrouping) partparams->VoicePar[vc].FMSmp->newrandseed(rand());
-
- 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;
- };
-
- if (partparams->VoicePar[nvoice].PFMFreqEnvelopeEnabled!=0)
- NoteVoicePar[nvoice].FMFreqEnvelope=new Envelope(partparams->VoicePar[nvoice].FMFreqEnvelope,basefreq);
-
- FMnewamplitude[nvoice]=NoteVoicePar[nvoice].FMVolume*ctl->fmamp.relamp;
-
- if (partparams->VoicePar[nvoice].PFMAmpEnvelopeEnabled!=0){
- NoteVoicePar[nvoice].FMAmpEnvelope=new Envelope(partparams->VoicePar[nvoice].FMAmpEnvelope,basefreq);
- FMnewamplitude[nvoice]*=NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB();
- };
- };
-
- 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 frequency of an oscillator
- */
-void ADnote::setfreq(int nvoice,REALTYPE 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);
-};
-
-/*
- * Computes the frequency of an modullator oscillator
- */
-void ADnote::setfreqFM(int nvoice,REALTYPE 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);
-};
-
-/*
- * Get Voice base frequency
- */
-REALTYPE ADnote::getvoicebasefreq(int nvoice){
- REALTYPE detune=NoteVoicePar[nvoice].Detune/100.0+
- NoteVoicePar[nvoice].FineDetune/100.0*ctl->bandwidth.relbw*bandwidthDetuneMultiplier+
- NoteGlobalPar.Detune/100.0;
-
- if (NoteVoicePar[nvoice].fixedfreq==0) return(this->basefreq*pow(2,detune/12.0));
- else {//the fixed freq is enabled
- REALTYPE fixedfreq=440.0;
- int fixedfreqET=NoteVoicePar[nvoice].fixedfreqET;
- if (fixedfreqET!=0) {//if the frequency varies according the keyboard note
- REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0);
- if (fixedfreqET<=64) fixedfreq*=pow(2.0,tmp);
- else fixedfreq*=pow(3.0,tmp);
- };
- return(fixedfreq*pow(2.0,detune/12.0));
- };
-};
-
-/*
- * Get Voice's Modullator base frequency
- */
-REALTYPE ADnote::getFMvoicebasefreq(int nvoice){
- REALTYPE detune=NoteVoicePar[nvoice].FMDetune/100.0;
- return(getvoicebasefreq(nvoice)*pow(2,detune/12.0));
-};
-
-/*
- * Computes all the parameters for each tick
- */
-void ADnote::computecurrentparameters(){
- int nvoice;
- REALTYPE voicefreq,voicepitch,filterpitch,filterfreq,FMfreq,FMrelativepitch,globalpitch,globalfilterpitch;
- globalpitch=0.01*(NoteGlobalPar.FreqEnvelope->envout()+
- NoteGlobalPar.FreqLfo->lfoout()*ctl->modwheel.relmod);
- globaloldamplitude=globalnewamplitude;
- globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout();
-
- globalfilterpitch=NoteGlobalPar.FilterEnvelope->envout()+NoteGlobalPar.FilterLfo->lfoout()
- +NoteGlobalPar.FilterCenterPitch;
-
- REALTYPE tmpfilterfreq=globalfilterpitch+ctl->filtercutoff.relfreq
- +NoteGlobalPar.FilterFreqTracking;
-
- tmpfilterfreq=NoteGlobalPar.GlobalFilterL->getrealfreq(tmpfilterfreq);
-
- REALTYPE globalfilterq=NoteGlobalPar.FilterQ*ctl->filterq.relq;
- NoteGlobalPar.GlobalFilterL->setfreq_and_q(tmpfilterfreq,globalfilterq);
- if (stereo!=0) NoteGlobalPar.GlobalFilterR->setfreq_and_q(tmpfilterfreq,globalfilterq);
-
- //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"
- };
- };
-
- //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;
-
- /*******************/
- /* Voice Amplitude */
- /*******************/
- oldamplitude[nvoice]=newamplitude[nvoice];
- newamplitude[nvoice]=1.0;
-
- if (NoteVoicePar[nvoice].AmpEnvelope!=NULL)
- newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpEnvelope->envout_dB();
-
- 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].FilterLfo!=NULL)
- filterpitch+=NoteVoicePar[nvoice].FilterLfo->lfoout();
-
- filterfreq=filterpitch+NoteVoicePar[nvoice].FilterFreqTracking;
- filterfreq=NoteVoicePar[nvoice].VoiceFilter->getrealfreq(filterfreq);
-
- NoteVoicePar[nvoice].VoiceFilter->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);
-
- /***************/
- /* 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;
-};
-
-
-/*
- * Fadein in a way that removes clicks but keep sound "punchy"
- */
-inline void ADnote::fadein(REALTYPE *smps){
- int zerocrossings=0;
- for (int i=1;i<SOUND_BUFFER_SIZE;i++)
- if ((smps[i-1]<0.0) && (smps[i]>0.0)) zerocrossings++;//this is only the possitive crossings
-
- REALTYPE tmp=(SOUND_BUFFER_SIZE-1.0)/(zerocrossings+1)/3.0;
- if (tmp<8.0) tmp=8.0;
-
- int n;
- F2I(tmp,n);//how many samples is the fade-in
- if (n>SOUND_BUFFER_SIZE) n=SOUND_BUFFER_SIZE;
- for (int i=0;i<n;i++) {//fade-in
- REALTYPE tmp=0.5-cos((REALTYPE)i/(REALTYPE) n*PI)*0.5;
- smps[i]*=tmp;
- };
-};
-
-/*
- * 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;
-};
-
-
-
-/*
- * 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)
-inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int nvoice){
- int i,poshi;
- REALTYPE 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;
- };
- oscposhi[nvoice]=poshi;
- oscposlo[nvoice]=poslo;
-};
-*/
-/*
- * Computes the Oscillator (Morphing)
- */
-inline void ADnote::ComputeVoiceOscillatorMorph(int nvoice){
- int i;
- REALTYPE amp;
- ComputeVoiceOscillator_LinearInterpolation(nvoice);
- if (FMnewamplitude[nvoice]>1.0) FMnewamplitude[nvoice]=1.0;
- if (FMoldamplitude[nvoice]>1.0) FMoldamplitude[nvoice]=1.0;
-
- if (NoteVoicePar[nvoice].FMVoice>=0){
- //if I use VoiceOut[] as modullator
- int FMVoice=NoteVoicePar[nvoice].FMVoice;
- for (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;
- };
-};
-
-/*
- * Computes the Oscillator (Ring Modulation)
- */
-inline void ADnote::ComputeVoiceOscillatorRingModulation(int nvoice){
- int i;
- REALTYPE amp;
- ComputeVoiceOscillator_LinearInterpolation(nvoice);
- if (FMnewamplitude[nvoice]>1.0) FMnewamplitude[nvoice]=1.0;
- if (FMoldamplitude[nvoice]>1.0) FMoldamplitude[nvoice]=1.0;
- if (NoteVoicePar[nvoice].FMVoice>=0){
- // if I use VoiceOut[] as modullator
- for (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;
- };
-};
-
-
-
-/*
- * Computes the Oscillator (Phase Modulation or Frequency Modulation)
- */
-inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int nvoice,int FMmode){
- int carposhi;
- int i,FMmodfreqhi;
- REALTYPE FMmodfreqlo,carposlo;
-
- 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;
- };
- // 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;
- };
-
- 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;
-
- if (carposlo>=1.0) {
- carposhi++;
- carposlo=fmod(carposlo,1.0);
- };
- carposhi&=(OSCIL_SIZE-1);
-
- tmpwave[i]=NoteVoicePar[nvoice].OscilSmp[carposhi]*(1.0-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]++;
- };
-
- oscposhi[nvoice]+=oscfreqhi[nvoice];
- oscposhi[nvoice]&=OSCIL_SIZE-1;
- };
-};
-
-
-/*Calculeaza Oscilatorul cu PITCH MODULATION*/
-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;
-};
-
-
-
-/*
- * Compute the ADnote samples
- * Returns 0 if the note is finished
- */
-int ADnote::noteout(REALTYPE *outl,REALTYPE *outr){
- int i,nvoice;
-
- 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;
- };
-
- 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;
- //case PITCH_MOD:ComputeVoiceOscillatorPitchModulation(nvoice);break;
- default:ComputeVoiceOscillator_LinearInterpolation(nvoice);
- //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(nvoice);
-
- };
- } else ComputeVoiceNoise(nvoice);
- // Voice Processing
-
- // Amplitude
- if (ABOVE_AMPLITUDE_THRESHOLD(oldamplitude[nvoice],newamplitude[nvoice])){
- int rest=SOUND_BUFFER_SIZE;
- //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];
- };
- // 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];
-
- // Fade in
- if (firsttick[nvoice]!=0){
- fadein(&tmpwave[0]);
- firsttick[nvoice]=0;
- };
-
-
- // Filter
- if (NoteVoicePar[nvoice].VoiceFilter!=NULL) NoteVoicePar[nvoice].VoiceFilter->filterout(&tmpwave[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
- };
-
-
- // 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];
-
-
- // 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;
- };
- };
- // 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);
- };
- };
-
-
- //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]);
-
- for (i=0;i<SOUND_BUFFER_SIZE;i++) {
- outl[i]+=bypassl[i];
- outr[i]+=bypassr[i];
- };
-
- 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;
- };
- };
- };
-
- // 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;
- };
- KillNote();
- };
- return(1);
-};
-
-
-/*
- * Relase the key (NoteOff)
- */
-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();
- };
- NoteGlobalPar.FreqEnvelope->relasekey();
- NoteGlobalPar.FilterEnvelope->relasekey();
- NoteGlobalPar.AmpEnvelope->relasekey();
-
-};
-
-/*
- * Check if the note is finished
- */
-int ADnote::finished(){
- if (NoteEnabled==ON) return(0);
- else return(1);
-};
-
-
-