diff options
author | Robert Jonsson <spamatica@gmail.com> | 2009-12-27 11:30:35 +0000 |
---|---|---|
committer | Robert Jonsson <spamatica@gmail.com> | 2009-12-27 11:30:35 +0000 |
commit | b703eab295330e6f81564fbb39a10a1a2fdd2f54 (patch) | |
tree | e46b5c9a6bc22fd661c15d1d2123f5bf631cef80 /muse_qt4_evolution/synti/zynaddsubfx/Misc/Part.C | |
parent | 5d5fa0fdf913907edbc3d2d29a7548f0cb658c94 (diff) |
moved old qt4 branch
Diffstat (limited to 'muse_qt4_evolution/synti/zynaddsubfx/Misc/Part.C')
-rw-r--r-- | muse_qt4_evolution/synti/zynaddsubfx/Misc/Part.C | 881 |
1 files changed, 881 insertions, 0 deletions
diff --git a/muse_qt4_evolution/synti/zynaddsubfx/Misc/Part.C b/muse_qt4_evolution/synti/zynaddsubfx/Misc/Part.C new file mode 100644 index 00000000..ceeeb7b6 --- /dev/null +++ b/muse_qt4_evolution/synti/zynaddsubfx/Misc/Part.C @@ -0,0 +1,881 @@ +/* + ZynAddSubFX - a software synthesizer + + Part.C - Part implementation + 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 "Part.h" +#include "Microtonal.h" +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +Part::Part(Microtonal *microtonal_,FFTwrapper *fft_, Master* master_){ + microtonal=microtonal_; + fft=fft_; + master=master_; + partoutl=new REALTYPE [SOUND_BUFFER_SIZE]; + partoutr=new REALTYPE [SOUND_BUFFER_SIZE]; + tmpoutl=new REALTYPE [SOUND_BUFFER_SIZE]; + tmpoutr=new REALTYPE [SOUND_BUFFER_SIZE]; + + for (int n=0;n<NUM_KIT_ITEMS;n++){ + kit[n].Pname=new unsigned char [PART_MAX_NAME_LEN]; + kit[n].adpars=NULL;kit[n].subpars=NULL;kit[n].padpars=NULL; + }; + + kit[0].adpars=new ADnoteParameters(fft); + kit[0].subpars=new SUBnoteParameters(); + kit[0].padpars=new PADnoteParameters(fft,master); +// ADPartParameters=kit[0].adpars; +// SUBPartParameters=kit[0].subpars; + + //Part's Insertion Effects init + for (int nefx=0;nefx<NUM_PART_EFX;nefx++) + partefx[nefx]=new EffectMgr(1,master); + + for (int n=0;n<NUM_PART_EFX+1;n++) { + partfxinputl[n]=new REALTYPE [SOUND_BUFFER_SIZE]; + partfxinputr[n]=new REALTYPE [SOUND_BUFFER_SIZE]; + Pefxbypass[n]=false; + }; + + killallnotes=0; + oldfreq=-1.0; + + int i,j; + for (i=0;i<POLIPHONY;i++){ + partnote[i].status=KEY_OFF; + partnote[i].note=-1; + partnote[i].itemsplaying=0; + for (j=0;j<NUM_KIT_ITEMS;j++){ + partnote[i].kititem[j].adnote=NULL; + partnote[i].kititem[j].subnote=NULL; + partnote[i].kititem[j].padnote=NULL; + }; + partnote[i].time=0; + }; + cleanup(); + + Pname=new unsigned char [PART_MAX_NAME_LEN]; + + oldvolumel=oldvolumer=0.5; + lastnote=-1; + + + defaults(); +}; + +void Part::defaults(){ + Penabled=0; + Pminkey=0; + Pmaxkey=127; + Pnoteon=1; + Ppolymode=1; + setPvolume(96); + Pkeyshift=64; + Prcvchn=0; + setPpanning(64); + Pvelsns=64; + Pveloffs=64; + Pkeylimit=15; + defaultsinstrument(); + ctl.defaults(); +}; + +void Part::defaultsinstrument(){ + ZERO(Pname,PART_MAX_NAME_LEN); + + info.Ptype=0; + ZERO(info.Pauthor,MAX_INFO_TEXT_SIZE+1); + ZERO(info.Pcomments,MAX_INFO_TEXT_SIZE+1); + + Pkitmode=0; + Pdrummode=0; + + for (int n=0;n<NUM_KIT_ITEMS;n++){ + kit[n].Penabled=0;kit[n].Pmuted=0; + kit[n].Pminkey=0;kit[n].Pmaxkey=127; + kit[n].Padenabled=0;kit[n].Psubenabled=0;kit[n].Ppadenabled=0; + ZERO(kit[n].Pname,PART_MAX_NAME_LEN); + kit[n].Psendtoparteffect=0; + if (n!=0) setkititemstatus(n,0); + }; + kit[0].Penabled=1; + kit[0].Padenabled=1; + kit[0].adpars->defaults(); + kit[0].subpars->defaults(); + kit[0].padpars->defaults(); + + for (int nefx=0;nefx<NUM_PART_EFX;nefx++) { + partefx[nefx]->defaults(); + Pefxroute[nefx]=0;//route to next effect + }; + +}; + + + +/* + * Cleanup the part + */ +void Part::cleanup(){ + for (int k=0;k<POLIPHONY;k++) KillNotePos(k); + + memcpy(partoutl, denormalkillbuf, sizeof(REALTYPE) * SOUND_BUFFER_SIZE); + memcpy(partoutr, denormalkillbuf, sizeof(REALTYPE) * SOUND_BUFFER_SIZE); + memset(tmpoutl, 0, sizeof(REALTYPE) * SOUND_BUFFER_SIZE); + memset(tmpoutr, 0, sizeof(REALTYPE) * SOUND_BUFFER_SIZE); + + ctl.resetall(); + for (int nefx=0;nefx<NUM_PART_EFX;nefx++) partefx[nefx]->cleanup(); + for (int n=0;n<NUM_PART_EFX+1;n++) { + memcpy(partfxinputl[n], denormalkillbuf, sizeof(REALTYPE) * SOUND_BUFFER_SIZE); + memcpy(partfxinputr[n], denormalkillbuf, sizeof(REALTYPE) * SOUND_BUFFER_SIZE); + }; +}; + +Part::~Part(){ + cleanup(); + for (int n=0;n<NUM_KIT_ITEMS;n++){ + if (kit[n].adpars!=NULL) delete (kit[n].adpars); + if (kit[n].subpars!=NULL) delete (kit[n].subpars); + if (kit[n].padpars!=NULL) delete (kit[n].padpars); + kit[n].adpars=NULL;kit[n].subpars=NULL;kit[n].padpars=NULL; + delete(kit[n].Pname); + }; + + delete (Pname); + delete (partoutl); + delete (partoutr); + delete (tmpoutl); + delete (tmpoutr); + for (int nefx=0;nefx<NUM_PART_EFX;nefx++) + delete (partefx[nefx]); + for (int n=0;n<NUM_PART_EFX+1;n++) { + delete (partfxinputl[n]); + delete (partfxinputr[n]); + }; +}; + +/* + * Note On Messages + */ +void Part::NoteOn(unsigned char note,unsigned char velocity,int masterkeyshift){ + int i,pos; + + lastnote=note; + if ((note<Pminkey)||(note>Pmaxkey)) return; + + pos=-1; + for (i=0;i<POLIPHONY;i++){ + if (partnote[i].status==KEY_OFF){ + pos=i; + break; + }; + }; + + if (Ppolymode==0){//if the mode is 'mono' turn off all other notes + for (i=0;i<POLIPHONY;i++) + if (partnote[i].status==KEY_PLAYING) NoteOff(partnote[i].note); + RelaseSustainedKeys(); + }; + + if (pos==-1){ + //test + fprintf(stderr,"%s","NOTES TOO MANY (> POLIPHONY) - (Part.C::NoteOn(..))\n"); + } else { + if (Pnoteon!=0){ + //start the note + partnote[pos].status=KEY_PLAYING; + partnote[pos].note=note; + + //this computes the velocity sensing of the part + REALTYPE vel=VelF(velocity/127.0,Pvelsns); + + //compute the velocity offset + vel+=(Pveloffs-64.0)/64.0; + if (vel<0.0) vel=0.0; else if (vel>1.0) vel=1.0; + + //compute the keyshift + int partkeyshift=(int)Pkeyshift-64; + int keyshift=masterkeyshift+partkeyshift; + + //initialise note frequency + REALTYPE notebasefreq; + if (Pdrummode==0){ + notebasefreq=microtonal->getnotefreq(note,keyshift); + if (notebasefreq<0.0) return;//the key is no mapped + } else { + notebasefreq=440.0*pow(2.0,(note-69.0)/12.0); + }; + + //Portamento + if (oldfreq<1.0) oldfreq=notebasefreq;//this is only the first note is played + + int portamento=ctl.initportamento(oldfreq,notebasefreq); + + if (portamento!=0) ctl.portamento.noteusing=pos; + oldfreq=notebasefreq; + + partnote[pos].itemsplaying=0; + if (Pkitmode==0){//init the notes for the "normal mode" + partnote[pos].kititem[0].sendtoparteffect=0; + if (kit[0].Padenabled!=0) partnote[pos].kititem[0].adnote=new ADnote(kit[0].adpars,&ctl,notebasefreq,vel,portamento,note); + if (kit[0].Psubenabled!=0) partnote[pos].kititem[0].subnote=new SUBnote(kit[0].subpars,&ctl,notebasefreq,vel,portamento,note); + if (kit[0].Ppadenabled!=0) partnote[pos].kititem[0].padnote=new PADnote(kit[0].padpars,&ctl,notebasefreq,vel,portamento,note); + if ((kit[0].Padenabled!=0)||(kit[0].Psubenabled!=0)||(kit[0].Ppadenabled!=0)) partnote[pos].itemsplaying++; + + } else {//init the notes for the "kit mode" + for (int item=0;item<NUM_KIT_ITEMS;item++){ + if (kit[item].Pmuted!=0) continue; + if ((note<kit[item].Pminkey)||(note>kit[item].Pmaxkey)) continue; + + int ci=partnote[pos].itemsplaying;//ci=current item + + partnote[pos].kititem[ci].sendtoparteffect=( kit[item].Psendtoparteffect<NUM_PART_EFX ? + kit[item].Psendtoparteffect: NUM_PART_EFX);//if this parameter is 127 for "unprocessed" + + if ((kit[item].adpars!=NULL)&&(kit[item].Padenabled)!=0) + partnote[pos].kititem[ci].adnote=new ADnote(kit[item].adpars,&ctl,notebasefreq,vel,portamento,note); + + if ((kit[item].subpars!=NULL)&&(kit[item].Psubenabled)!=0) + partnote[pos].kititem[ci].subnote=new SUBnote(kit[item].subpars,&ctl,notebasefreq,vel,portamento,note); + + if ((kit[item].padpars!=NULL)&&(kit[item].Ppadenabled)!=0) + partnote[pos].kititem[ci].padnote=new PADnote(kit[item].padpars,&ctl,notebasefreq,vel,portamento,note); + + if ((kit[item].adpars!=NULL)|| (kit[item].subpars!=NULL)) { + partnote[pos].itemsplaying++; + if ( ((kit[item].Padenabled!=0)||(kit[item].Psubenabled!=0)||(kit[item].Ppadenabled!=0)) + && (Pkitmode==2) ) break; + }; + }; + }; + }; + }; + + //this only relase the keys if there is maximum number of keys allowed + setkeylimit(Pkeylimit); +}; + +/* + * Note Off Messages + */ +void Part::NoteOff(unsigned char note){//relase the key + int i; + for (i=POLIPHONY-1;i>=0;i--){ //first note in, is first out if there are same note multiple times + if ((partnote[i].status==KEY_PLAYING)&&(partnote[i].note==note)) { + if (ctl.sustain.sustain==0){ //the sustain pedal is not pushed + RelaseNotePos(i); + break; + } else {//the sustain pedal is pushed + partnote[i].status=KEY_RELASED_AND_SUSTAINED; + }; + }; + }; +}; + +/* + * Controllers + */ +void Part::SetController(unsigned int type,int par){ + switch (type){ + case C_pitchwheel:ctl.setpitchwheel(par); + break; + case C_expression:ctl.setexpression(par); + setPvolume(Pvolume);//update the volume + break; + case C_portamento:ctl.setportamento(par); + break; + case C_panning:ctl.setpanning(par); + setPpanning(Ppanning);//update the panning + break; + case C_filtercutoff:ctl.setfiltercutoff(par); + break; + case C_filterq:ctl.setfilterq(par); + break; + case C_bandwidth:ctl.setbandwidth(par); + break; + case C_modwheel:ctl.setmodwheel(par); + break; + case C_fmamp:ctl.setfmamp(par); + break; + case C_volume:ctl.setvolume(par); + if (ctl.volume.receive!=0) volume=ctl.volume.volume; + else setPvolume(Pvolume); + break; + case C_sustain:ctl.setsustain(par); + if (ctl.sustain.sustain==0) RelaseSustainedKeys(); + break; + case C_allsoundsoff:AllNotesOff();//Panic + break; + case C_resetallcontrollers: + ctl.resetall(); + RelaseSustainedKeys(); + if (ctl.volume.receive!=0) volume=ctl.volume.volume; + else setPvolume(Pvolume); + setPvolume(Pvolume);//update the volume + setPpanning(Ppanning);//update the panning + + for (int item=0;item<NUM_KIT_ITEMS;item++){ + if (kit[item].adpars==NULL) continue; + kit[item].adpars->GlobalPar.Reson-> + sendcontroller(C_resonance_center,1.0); + + kit[item].adpars->GlobalPar.Reson-> + sendcontroller(C_resonance_bandwidth,1.0); + }; + //more update to add here if I add controllers + break; + case C_allnotesoff:RelaseAllKeys(); + break; + case C_resonance_center: + ctl.setresonancecenter(par); + for (int item=0;item<NUM_KIT_ITEMS;item++){ + if (kit[item].adpars==NULL) continue; + kit[item].adpars->GlobalPar.Reson-> + sendcontroller(C_resonance_center,ctl.resonancecenter.relcenter); + }; + break; + case C_resonance_bandwidth: + ctl.setresonancebw(par); + kit[0].adpars->GlobalPar.Reson-> + sendcontroller(C_resonance_bandwidth,ctl.resonancebandwidth.relbw); + break; + }; +}; +/* + * Relase the sustained keys + */ + +void Part::RelaseSustainedKeys(){ + for (int i=0;i<POLIPHONY;i++) + if (partnote[i].status==KEY_RELASED_AND_SUSTAINED) RelaseNotePos(i); +}; + +/* + * Relase all keys + */ + +void Part::RelaseAllKeys(){ + for (int i=0;i<POLIPHONY;i++){ + if ((partnote[i].status!=KEY_RELASED)&& + (partnote[i].status!=KEY_OFF)) //thanks to Frank Neumann + RelaseNotePos(i); + }; +}; + +/* + * Release note at position + */ +void Part::RelaseNotePos(int pos){ + + for (int j=0;j<NUM_KIT_ITEMS;j++){ + + if (partnote[pos].kititem[j].adnote!=NULL) + if (partnote[pos].kititem[j].adnote) + partnote[pos].kititem[j].adnote->relasekey(); + + if (partnote[pos].kititem[j].subnote!=NULL) + if (partnote[pos].kititem[j].subnote!=NULL) + partnote[pos].kititem[j].subnote->relasekey(); + + if (partnote[pos].kititem[j].padnote!=NULL) + if (partnote[pos].kititem[j].padnote) + partnote[pos].kititem[j].padnote->relasekey(); + }; + partnote[pos].status=KEY_RELASED; +}; + + +/* + * Kill note at position + */ +void Part::KillNotePos(int pos){ + partnote[pos].status=KEY_OFF; + partnote[pos].note=-1; + partnote[pos].time=0; + partnote[pos].itemsplaying=0; + + for (int j=0;j<NUM_KIT_ITEMS;j++){ + if (partnote[pos].kititem[j].adnote!=NULL) { + delete(partnote[pos].kititem[j].adnote); + partnote[pos].kititem[j].adnote=NULL; + }; + if (partnote[pos].kititem[j].subnote!=NULL) { + delete(partnote[pos].kititem[j].subnote); + partnote[pos].kititem[j].subnote=NULL; + }; + if (partnote[pos].kititem[j].padnote!=NULL) { + delete(partnote[pos].kititem[j].padnote); + partnote[pos].kititem[j].padnote=NULL; + }; + }; + if (pos==ctl.portamento.noteusing) { + ctl.portamento.noteusing=-1; + ctl.portamento.used=0; + }; +}; + + +/* + * Set Part's key limit + */ +void Part::setkeylimit(unsigned char Pkeylimit){ + this->Pkeylimit=Pkeylimit; + int keylimit=Pkeylimit; + if (keylimit==0) keylimit=POLIPHONY-5; + + //release old keys if the number of notes>keylimit + if (Ppolymode!=0){ + int notecount=0; + for (int i=0;i<POLIPHONY;i++){ + if ((partnote[i].status==KEY_PLAYING)||(partnote[i].status==KEY_RELASED_AND_SUSTAINED)) + notecount++; + }; + int oldestnotepos=-1,maxtime=0; + if (notecount>keylimit){//find out the oldest note + for (int i=0;i<POLIPHONY;i++){ + if ( ((partnote[i].status==KEY_PLAYING)||(partnote[i].status==KEY_RELASED_AND_SUSTAINED)) + && (partnote[i].time>maxtime)){ + maxtime=partnote[i].time; + oldestnotepos=i; + }; + }; + }; + if (oldestnotepos!=-1) RelaseNotePos(oldestnotepos); + }; +}; + + +/* + * Prepare all notes to be turned off + */ +void Part::AllNotesOff(){ + killallnotes=1; +}; + + +/* + * Compute Part samples and store them in the partoutl[] and partoutr[] + */ +void Part::ComputePartSmps(){ + int i, k; + int noteplay;//0 if there is nothing activated + for (int nefx=0;nefx<NUM_PART_EFX+1;nefx++){ + memset(partfxinputl[nefx], 0, sizeof(REALTYPE) * SOUND_BUFFER_SIZE); + memset(partfxinputr[nefx], 0, sizeof(REALTYPE) * SOUND_BUFFER_SIZE); + }; + + for (k=0;k<POLIPHONY;k++){ + if (partnote[k].status==KEY_OFF) continue; + noteplay=0; + partnote[k].time++; + //get the sampledata of the note and kill it if it's finished + + for (int item=0;item<partnote[k].itemsplaying;item++){ + + int sendcurrenttofx=partnote[k].kititem[item].sendtoparteffect; + + ADnote *adnote=partnote[k].kititem[item].adnote; + SUBnote *subnote=partnote[k].kititem[item].subnote; + PADnote *padnote=partnote[k].kititem[item].padnote; + //get from the ADnote + if (adnote!=NULL) { + noteplay++; + if (adnote->ready!=0) adnote->noteout(&tmpoutl[0],&tmpoutr[0]); + else { + memset(tmpoutl, 0, sizeof(REALTYPE) * SOUND_BUFFER_SIZE); + memset(tmpoutr, 0, sizeof(REALTYPE) * SOUND_BUFFER_SIZE); + } + if (adnote->finished()!=0){ + delete (adnote); + partnote[k].kititem[item].adnote=NULL; + }; + for (i=0;i<SOUND_BUFFER_SIZE;i++){//add the ADnote to part(mix) + partfxinputl[sendcurrenttofx][i]+=tmpoutl[i]; + partfxinputr[sendcurrenttofx][i]+=tmpoutr[i]; + }; + }; + //get from the SUBnote + if (subnote!=NULL) { + noteplay++; + if (subnote->ready!=0) subnote->noteout(&tmpoutl[0],&tmpoutr[0]); + else { + memset(tmpoutl, 0, sizeof(REALTYPE) * SOUND_BUFFER_SIZE); + memset(tmpoutr, 0, sizeof(REALTYPE) * SOUND_BUFFER_SIZE); + } + + for (i=0;i<SOUND_BUFFER_SIZE;i++){//add the SUBnote to part(mix) + partfxinputl[sendcurrenttofx][i]+=tmpoutl[i]; + partfxinputr[sendcurrenttofx][i]+=tmpoutr[i]; + }; + if (subnote->finished()!=0){ + delete (subnote); + partnote[k].kititem[item].subnote=NULL; + }; + }; + //get from the PADnote + if (padnote!=NULL) { + noteplay++; + if (padnote->ready!=0) padnote->noteout(&tmpoutl[0],&tmpoutr[0]); + else { + memset(tmpoutl, 0, sizeof(REALTYPE) * SOUND_BUFFER_SIZE); + memset(tmpoutr, 0, sizeof(REALTYPE) * SOUND_BUFFER_SIZE); + } + if (padnote->finished()!=0){ + delete (padnote); + partnote[k].kititem[item].padnote=NULL; + }; + for (i=0;i<SOUND_BUFFER_SIZE;i++){//add the PADnote to part(mix) + partfxinputl[sendcurrenttofx][i]+=tmpoutl[i]; + partfxinputr[sendcurrenttofx][i]+=tmpoutr[i]; + }; + }; + + }; + //Kill note if there is no synth on that note + if (noteplay==0) KillNotePos(k); + }; + + + //Apply part's effects and mix them + for (int nefx=0;nefx<NUM_PART_EFX;nefx++) { + if (!Pefxbypass[nefx]) { + partefx[nefx]->out(partfxinputl[nefx],partfxinputr[nefx]); + if (Pefxroute[nefx]==2){ + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + partfxinputl[nefx+1][i]+=partefx[nefx]->efxoutl[i]; + partfxinputr[nefx+1][i]+=partefx[nefx]->efxoutr[i]; + }; + }; + }; + int routeto=((Pefxroute[nefx]==0) ? nefx+1 : NUM_PART_EFX); + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + partfxinputl[routeto][i]+=partfxinputl[nefx][i]; + partfxinputr[routeto][i]+=partfxinputr[nefx][i]; + }; + + }; + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + partoutl[i]=partfxinputl[NUM_PART_EFX][i]; + partoutr[i]=partfxinputr[NUM_PART_EFX][i]; + }; + + //Kill All Notes if killallnotes!=0 + if (killallnotes!=0) { + for (i=0;i<SOUND_BUFFER_SIZE;i++) { + REALTYPE tmp=(SOUND_BUFFER_SIZE-i)/(REALTYPE) SOUND_BUFFER_SIZE; + partoutl[i]*=tmp; + partoutr[i]*=tmp; + tmpoutl[i]=0.0; + tmpoutr[i]=0.0; + }; + for (int k=0;k<POLIPHONY;k++) KillNotePos(k); + killallnotes=0; + for (int nefx=0;nefx<NUM_PART_EFX;nefx++) { + partefx[nefx]->cleanup(); + }; + }; + ctl.updateportamento(); +}; + +/* + * Parameter control + */ +void Part::setPvolume(char Pvolume_){ + Pvolume=Pvolume_; + volume=dB2rap((Pvolume-96.0)/96.0*40.0)*ctl.expression.relvolume; +}; + +void Part::setPpanning(char Ppanning_){ + Ppanning=Ppanning_; + panning=Ppanning/127.0+ctl.panning.pan; + if (panning<0.0) panning=0.0;else if (panning>1.0) panning=1.0; + +}; + +/* + * Enable or disable a kit item + */ +void Part::setkititemstatus(int kititem,int Penabled_){ + if ((kititem==0)&&(kititem>=NUM_KIT_ITEMS)) return;//nonexistent kit item and the first kit item is always enabled + kit[kititem].Penabled=Penabled_; + + bool resetallnotes=false; + if (Penabled_==0){ + if (kit[kititem].adpars!=NULL) delete (kit[kititem].adpars); + if (kit[kititem].subpars!=NULL) delete (kit[kititem].subpars); + if (kit[kititem].padpars!=NULL) { + delete (kit[kititem].padpars); + resetallnotes=true; + }; + kit[kititem].adpars=NULL;kit[kititem].subpars=NULL;kit[kititem].padpars=NULL; + kit[kititem].Pname[0]='\0'; + } else { + if (kit[kititem].adpars==NULL) kit[kititem].adpars=new ADnoteParameters(fft); + if (kit[kititem].subpars==NULL) kit[kititem].subpars=new SUBnoteParameters(); + if (kit[kititem].padpars==NULL) kit[kititem].padpars=new PADnoteParameters(fft,master); + }; + + if (resetallnotes) for (int k=0;k<POLIPHONY;k++) KillNotePos(k); +}; + + + +void Part::add2XMLinstrument(XMLwrapper *xml){ + xml->beginbranch("INFO"); + xml->addparstr("name",(char *)Pname); + xml->addparstr("author",(char *)info.Pauthor); + xml->addparstr("comments",(char *)info.Pcomments); + xml->addpar("type",info.Ptype); + xml->endbranch(); + + + xml->beginbranch("INSTRUMENT_KIT"); + xml->addpar("kit_mode",Pkitmode); + xml->addparbool("drum_mode",Pdrummode); + + for (int i=0;i<NUM_KIT_ITEMS;i++){ + xml->beginbranch("INSTRUMENT_KIT_ITEM",i); + xml->addparbool("enabled",kit[i].Penabled); + if (kit[i].Penabled!=0) { + xml->addparstr("name",(char *)kit[i].Pname); + + xml->addparbool("muted",kit[i].Pmuted); + xml->addpar("min_key",kit[i].Pminkey); + xml->addpar("max_key",kit[i].Pmaxkey); + + xml->addpar("send_to_instrument_effect",kit[i].Psendtoparteffect); + + xml->addparbool("add_enabled",kit[i].Padenabled); + if ((kit[i].Padenabled!=0)&&(kit[i].adpars!=NULL)){ + xml->beginbranch("ADD_SYNTH_PARAMETERS"); + kit[i].adpars->add2XML(xml); + xml->endbranch(); + }; + + xml->addparbool("sub_enabled",kit[i].Psubenabled); + if ((kit[i].Psubenabled!=0)&&(kit[i].subpars!=NULL)){ + xml->beginbranch("SUB_SYNTH_PARAMETERS"); + kit[i].subpars->add2XML(xml); + xml->endbranch(); + }; + + xml->addparbool("pad_enabled",kit[i].Ppadenabled); + if ((kit[i].Ppadenabled!=0)&&(kit[i].padpars!=NULL)){ + xml->beginbranch("PAD_SYNTH_PARAMETERS"); + kit[i].padpars->add2XML(xml); + xml->endbranch(); + }; + + }; + xml->endbranch(); + }; + xml->endbranch(); + + xml->beginbranch("INSTRUMENT_EFFECTS"); + for (int nefx=0;nefx<NUM_PART_EFX;nefx++){ + xml->beginbranch("INSTRUMENT_EFFECT",nefx); + xml->beginbranch("EFFECT"); + partefx[nefx]->add2XML(xml); + xml->endbranch(); + + xml->addpar("route",Pefxroute[nefx]); + partefx[nefx]->setdryonly(Pefxroute[nefx]==2); + xml->addparbool("bypass",Pefxbypass[nefx]); + xml->endbranch(); + }; + xml->endbranch(); +}; + + +void Part::add2XML(XMLwrapper *xml){ + //parameters + xml->addparbool("enabled",Penabled); + if ((Penabled==0)&&(xml->minimal)) return; + + xml->addpar("volume",Pvolume); + xml->addpar("panning",Ppanning); + + xml->addpar("min_key",Pminkey); + xml->addpar("max_key",Pmaxkey); + xml->addpar("key_shift",Pkeyshift); + xml->addpar("rcv_chn",Prcvchn); + + xml->addpar("velocity_sensing",Pvelsns); + xml->addpar("velocity_offset",Pveloffs); + + xml->addparbool("note_on",Pnoteon); + xml->addparbool("poly_mode",Ppolymode); + xml->addpar("key_limit",Pkeylimit); + + xml->beginbranch("INSTRUMENT"); + add2XMLinstrument(xml); + xml->endbranch(); + + xml->beginbranch("CONTROLLER"); + ctl.add2XML(xml); + xml->endbranch(); +}; + +int Part::saveXML(char *filename){ + XMLwrapper *xml; + xml=new XMLwrapper(); + + xml->beginbranch("INSTRUMENT"); + add2XMLinstrument(xml); + xml->endbranch(); + + int result=xml->saveXMLfile(filename); + delete (xml); + return(result); +}; + +int Part::loadXMLinstrument(const char *filename){ + XMLwrapper *xml=new XMLwrapper(); + if (xml->loadXMLfile(filename)<0) { + delete(xml); + return(-1); + }; + + if (xml->enterbranch("INSTRUMENT")==0) return(-10); + getfromXMLinstrument(xml); + xml->exitbranch(); + + delete(xml); + return(0); +}; + + +void Part::applyparameters(){ + for (int n=0;n<NUM_KIT_ITEMS;n++){ + if ((kit[n].padpars!=NULL)&&(kit[n].Ppadenabled!=0)) kit[n].padpars->applyparameters(true); + }; +}; + +void Part::getfromXMLinstrument(XMLwrapper *xml){ + if (xml->enterbranch("INFO")){ + xml->getparstr("name",(char *)Pname,PART_MAX_NAME_LEN); + xml->getparstr("author",(char *)info.Pauthor,MAX_INFO_TEXT_SIZE); + xml->getparstr("comments",(char *)info.Pcomments,MAX_INFO_TEXT_SIZE); + info.Ptype=xml->getpar("type",info.Ptype,0,16); + + xml->exitbranch(); + }; + + if (xml->enterbranch("INSTRUMENT_KIT")){ + Pkitmode=xml->getpar127("kit_mode",Pkitmode); + Pdrummode=xml->getparbool("drum_mode",Pdrummode); + + setkititemstatus(0,0); + for (int i=0;i<NUM_KIT_ITEMS;i++){ + if (xml->enterbranch("INSTRUMENT_KIT_ITEM",i)==0) continue; + setkititemstatus(i,xml->getparbool("enabled",kit[i].Penabled)); + if (kit[i].Penabled==0) { + xml->exitbranch(); + continue; + }; + + xml->getparstr("name",(char *)kit[i].Pname,PART_MAX_NAME_LEN); + + kit[i].Pmuted=xml->getparbool("muted",kit[i].Pmuted); + kit[i].Pminkey=xml->getpar127("min_key",kit[i].Pminkey); + kit[i].Pmaxkey=xml->getpar127("max_key",kit[i].Pmaxkey); + + kit[i].Psendtoparteffect=xml->getpar127("send_to_instrument_effect",kit[i].Psendtoparteffect); + + kit[i].Padenabled=xml->getparbool("add_enabled",kit[i].Padenabled); + if (xml->enterbranch("ADD_SYNTH_PARAMETERS")){ + kit[i].adpars->getfromXML(xml); + xml->exitbranch(); + }; + + kit[i].Psubenabled=xml->getparbool("sub_enabled",kit[i].Psubenabled); + if (xml->enterbranch("SUB_SYNTH_PARAMETERS")){ + kit[i].subpars->getfromXML(xml); + xml->exitbranch(); + }; + + kit[i].Ppadenabled=xml->getparbool("pad_enabled",kit[i].Ppadenabled); + if (xml->enterbranch("PAD_SYNTH_PARAMETERS")){ + kit[i].padpars->getfromXML(xml); + xml->exitbranch(); + }; + + xml->exitbranch(); + }; + + xml->exitbranch(); + }; + + + if (xml->enterbranch("INSTRUMENT_EFFECTS")){ + for (int nefx=0;nefx<NUM_PART_EFX;nefx++){ + if (xml->enterbranch("INSTRUMENT_EFFECT",nefx)==0) continue; + if (xml->enterbranch("EFFECT")){ + partefx[nefx]->getfromXML(xml); + xml->exitbranch(); + }; + + Pefxroute[nefx]=xml->getpar("route",Pefxroute[nefx],0,NUM_PART_EFX); + partefx[nefx]->setdryonly(Pefxroute[nefx]==2); + Pefxbypass[nefx]=xml->getparbool("bypass",Pefxbypass[nefx]); + xml->exitbranch(); + }; + xml->exitbranch(); + }; + +}; + +void Part::getfromXML(XMLwrapper *xml){ + Penabled=xml->getparbool("enabled",Penabled); + + setPvolume(xml->getpar127("volume",Pvolume)); + setPpanning(xml->getpar127("panning",Ppanning)); + + Pminkey=xml->getpar127("min_key",Pminkey); + Pmaxkey=xml->getpar127("max_key",Pmaxkey); + Pkeyshift=xml->getpar127("key_shift",Pkeyshift); + Prcvchn=xml->getpar127("rcv_chn",Prcvchn); + + Pvelsns=xml->getpar127("velocity_sensing",Pvelsns); + Pveloffs=xml->getpar127("velocity_offset",Pveloffs); + + Pnoteon=xml->getparbool("note_on",Pnoteon); + Ppolymode=xml->getparbool("poly_mode",Ppolymode); + Pkeylimit=xml->getpar127("key_limit",Pkeylimit); + + + if (xml->enterbranch("INSTRUMENT")){ + getfromXMLinstrument(xml); + xml->exitbranch(); + }; + + if (xml->enterbranch("CONTROLLER")){ + ctl.getfromXML(xml); + xml->exitbranch(); + }; + +}; + + + |