diff options
author | Robert Jonsson <spamatica@gmail.com> | 2011-03-07 19:01:11 +0000 |
---|---|---|
committer | Robert Jonsson <spamatica@gmail.com> | 2011-03-07 19:01:11 +0000 |
commit | e40fc849149dd97c248866a4a1d026dda5e57b62 (patch) | |
tree | b12b358f3b3a0608001d30403358f8443118ec5f /muse_qt4_evolution/synti/zynaddsubfx/Misc/Master.C | |
parent | 1bd4f2e8d9745cabb667b043171cad22c8577768 (diff) |
clean3
Diffstat (limited to 'muse_qt4_evolution/synti/zynaddsubfx/Misc/Master.C')
-rw-r--r-- | muse_qt4_evolution/synti/zynaddsubfx/Misc/Master.C | 680 |
1 files changed, 0 insertions, 680 deletions
diff --git a/muse_qt4_evolution/synti/zynaddsubfx/Misc/Master.C b/muse_qt4_evolution/synti/zynaddsubfx/Misc/Master.C deleted file mode 100644 index 99a1ac28..00000000 --- a/muse_qt4_evolution/synti/zynaddsubfx/Misc/Master.C +++ /dev/null @@ -1,680 +0,0 @@ -/* - ZynAddSubFX - a software synthesizer - - Master.C - 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 - - 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 "Master.h" - -#include <stdio.h> -#include <sys/stat.h> -#include <sys/types.h> - -#include <unistd.h> - -Master::Master(){ - swaplr=0; - - busy = false; - 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]; - - ksoundbuffersamples=0; - 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; - }; - - memset(audiooutl, 0, sizeof(REALTYPE) * SOUND_BUFFER_SIZE); - memset(audiooutr, 0, sizeof(REALTYPE) * SOUND_BUFFER_SIZE); - - for (int npart=0;npart<NUM_MIDI_PARTS;npart++) - part[npart]=new Part(µtonal,fft,this); - - - //Insertion Effects init - for (int nefx=0;nefx<NUM_INS_EFX;nefx++) - insefx[nefx]=new EffectMgr(1,this); - - //System Effects init - for (int nefx=0;nefx<NUM_SYS_EFX;nefx++) { - sysefx[nefx]=new EffectMgr(0,this); - }; - - - defaults(); -}; - -void Master::defaults(){ - volume=1.0; - setPvolume(80); - setPkeyshift(64); - - for (int npart=0;npart<NUM_MIDI_PARTS;npart++){ - part[npart]->defaults(); - part[npart]->Prcvchn=npart%NUM_MIDI_CHANNELS; - }; - - partonoff(0,1);//enable the first part - - for (int nefx=0;nefx<NUM_INS_EFX;nefx++) { - insefx[nefx]->defaults(); - Pinsparts[nefx]=-1; - }; - - //System Effects init - 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); - microtonal.defaults(); - ShutUp(); -}; - -/* - * Note On Messages (velocity=0 for NoteOff) - */ -void Master::NoteOn(unsigned char chan,unsigned char note,unsigned char velocity){ - dump.dumpnote(chan,note,velocity); - - noteon(chan,note,velocity); -}; - -/* - * Internal Note On (velocity=0 for NoteOff) - */ -void Master::noteon(unsigned char chan,unsigned char note,unsigned char velocity){ - 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); - }; - 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){ - int npart; - for (npart=0;npart<NUM_MIDI_PARTS;npart++){ - if ((chan==part[npart]->Prcvchn) && (part[npart]->Penabled!=0)) - part[npart]->NoteOff(note); - }; -}; - -/* - * Controllers - */ -void Master::SetController(unsigned char chan,unsigned int type,int par){ - dump.dumpcontroller(chan,type,par); - - setcontroller(chan,type,par); -}; - -/* - * Internal Controllers - */ -void Master::setcontroller(unsigned char chan,unsigned int type,int par){ - if ((type==C_dataentryhi)||(type==C_dataentrylo)|| - (type==C_nrpnhi)||(type==C_nrpnlo)){//Process RPN and NRPN by the Master (ignore the chan) - ctl.setparameternumber(type,par); - - 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); - }; - }; -}; - - -/* - * Enable/Disable a part - */ -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; - part[npart]->cleanup(); - 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; - }; -}; - -/* - * Master audio out (the final sound) - */ - -void Master::AudioOut(REALTYPE* outl, REALTYPE* outr) - { - int i,npart,nefx; - - //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 - memset(outl, 0, sizeof(REALTYPE) * SOUND_BUFFER_SIZE); - memset(outr, 0, sizeof(REALTYPE) * SOUND_BUFFER_SIZE); - - //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(); - - //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); - } - } - - - //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; - } - } - } - - - //System effects - for (nefx=0;nefx<NUM_SYS_EFX;nefx++){ - if (sysefx[nefx]->geteffect()==0) continue;//the effect is disabled - - //Clean up the samples used by the system effects - memset(tmpmixl, 0, sizeof(REALTYPE) * SOUND_BUFFER_SIZE); - memset(tmpmixr, 0, sizeof(REALTYPE) * SOUND_BUFFER_SIZE); - - //Mix the channels according to the part settings about System Effect - for (npart=0;npart<NUM_MIDI_PARTS;npart++){ - //skip if the part has no output to effect - if (Psysefxvol[nefx][npart]==0) continue; - - //skip if the part is disabled - 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; - }; - }; - - // 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); - - //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; - }; - - }; - - //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]; - } - } - - //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; - } - - //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]--; - }; - }; - - - //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; - } - ShutUp(); - } - - //update the LFO's time - LFOParams::time++; - - if (HDDRecorder.recording()) - HDDRecorder.recordbuffer(outl,outr); - dump.inctick(); - }; - -//--------------------------------------------------------- -// GetAudioOutSamples -//--------------------------------------------------------- - -void Master::GetAudioOutSamples(int nsamples, REALTYPE* outl, REALTYPE* outr) - { - int dstOffset = 0; - while (nsamples) { - if (ksoundbuffersamples <= 0) { - AudioOut(audiooutl, audiooutr); - ksoundbuffersamples = SOUND_BUFFER_SIZE; - } - int n = nsamples > ksoundbuffersamples ? ksoundbuffersamples : nsamples; - int srcOffset = SOUND_BUFFER_SIZE - ksoundbuffersamples; - memcpy(outl + dstOffset, audiooutl + srcOffset, n * sizeof(REALTYPE)); - memcpy(outr + dstOffset, audiooutr + srcOffset, n * sizeof(REALTYPE)); - nsamples -= n; - dstOffset += n; - ksoundbuffersamples -= n; - } - } - -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]); - - delete [] audiooutl; - delete [] audiooutr; - delete [] tmpmixl; - delete [] tmpmixr; - delete (fft); - -}; - - -/* - * Parameter control - */ -void Master::setPvolume(char Pvolume_){ - Pvolume=Pvolume_; - volume=dB2rap((Pvolume-96.0)/96.0*40.0); -}; - -void Master::setPkeyshift(char Pkeyshift_){ - Pkeyshift=Pkeyshift_; - keyshift=(int)Pkeyshift-64; -}; - - -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); -}; - -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); -}; - - -/* - * Panic! (Clean up all parts and effects) - */ -void Master::ShutUp(){ - 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(); - vuresetpeaks(); - shutup=0; -}; - - -/* - * Reset peaks and clear the "cliped" flag (for VU-meter) - */ -void Master::vuresetpeaks(){ - vuoutpeakl=1e-9;vuoutpeakr=1e-9;vumaxoutpeakl=1e-9;vumaxoutpeakr=1e-9; - vuclipped=0; -}; - - - -void Master::applyparameters(){ - for (int npart=0;npart<NUM_MIDI_PARTS;npart++){ - part[npart]->applyparameters(); - }; -}; - -void Master::add2XML(XMLwrapper *xml){ - xml->addpar("volume",Pvolume); - xml->addpar("key_shift",Pkeyshift); - xml->addparbool("nrpn_receive",ctl.NRPN.receive); - - xml->beginbranch("MICROTONAL"); - microtonal.add2XML(xml); - xml->endbranch(); - - 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); - 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]); - xml->endbranch(); - }; - - 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]); - - xml->beginbranch("EFFECT"); - insefx[nefx]->add2XML(xml); - xml->endbranch(); - xml->endbranch(); - }; - - xml->endbranch(); - -}; - - -int Master::getalldata(char **data){ - XMLwrapper *xml=new XMLwrapper(); - - xml->beginbranch("MASTER"); - - busy = true; - add2XML(xml); - busy = false; - - xml->endbranch(); - - *data=xml->getXMLdata(); - delete (xml); - return(strlen(*data)+1); -}; - -void Master::putalldata(char *data,int size){ - XMLwrapper *xml=new XMLwrapper(); - if (!xml->putXMLdata(data)) { - delete(xml); - return; - }; - - if (xml->enterbranch("MASTER")==0) return; - - busy = true; - getfromXML(xml); - busy = false; - - xml->exitbranch(); - - delete(xml); -}; - -int Master::saveXML(char *filename){ - XMLwrapper *xml=new XMLwrapper(); - - xml->beginbranch("MASTER"); - add2XML(xml); - xml->endbranch(); - - int result=xml->saveXMLfile(filename); - delete (xml); - return(result); -}; - - - -int Master::loadXML(char *filename){ - 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); -}; - -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); - - - 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")){ - 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")){ - 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])); - 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])); - 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")){ - insefx[nefx]->getfromXML(xml); - xml->exitbranch(); - }; - xml->exitbranch(); - - }; - - xml->exitbranch(); - }; - -}; - - - - |