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/Microtonal.C | |
parent | 1bd4f2e8d9745cabb667b043171cad22c8577768 (diff) |
clean3
Diffstat (limited to 'muse_qt4_evolution/synti/zynaddsubfx/Misc/Microtonal.C')
-rw-r--r-- | muse_qt4_evolution/synti/zynaddsubfx/Misc/Microtonal.C | 514 |
1 files changed, 0 insertions, 514 deletions
diff --git a/muse_qt4_evolution/synti/zynaddsubfx/Misc/Microtonal.C b/muse_qt4_evolution/synti/zynaddsubfx/Misc/Microtonal.C deleted file mode 100644 index 30a3a71e..00000000 --- a/muse_qt4_evolution/synti/zynaddsubfx/Misc/Microtonal.C +++ /dev/null @@ -1,514 +0,0 @@ -/* - ZynAddSubFX - a software synthesizer - - Microtonal.C - Tuning settings and microtonal capabilities - 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 <string.h> -#include "Microtonal.h" - -#define MAX_LINE_SIZE 80 - -Microtonal::Microtonal(){ - Pname=new unsigned char[MICROTONAL_MAX_NAME_LEN]; - Pcomment=new unsigned char[MICROTONAL_MAX_NAME_LEN]; - defaults(); -}; - -void Microtonal::defaults(){ - Pinvertupdown=0; - Pinvertupdowncenter=60; - octavesize=12; - Penabled=0; - PAnote=69; - PAfreq=440.0; - Pscaleshift=64; - - Pfirstkey=0;Plastkey=127; - Pmiddlenote=60;Pmapsize=12; - Pmappingenabled=0; - - for (int i=0;i<128;i++) Pmapping[i]=i; - - for (int i=0;i<MAX_OCTAVE_SIZE;i++){ - octave[i].tuning=tmpoctave[i].tuning=pow(2,(i%octavesize+1)/12.0); - octave[i].type=tmpoctave[i].type=1; - octave[i].x1=tmpoctave[i].x1=(i%octavesize+1)*100; - octave[i].x2=tmpoctave[i].x2=0; - }; - octave[11].type=2;octave[11].x1=2;octave[11].x2=1; - for (int i=0;i<MICROTONAL_MAX_NAME_LEN;i++){ - Pname[i]='\0'; - Pcomment[i]='\0'; - }; - snprintf((char *) Pname,MICROTONAL_MAX_NAME_LEN,"12tET"); - snprintf((char *) Pcomment,MICROTONAL_MAX_NAME_LEN,"Equal Temperament 12 notes per octave"); - Pglobalfinedetune=64; -}; - -Microtonal::~Microtonal(){ - delete (Pname); - delete (Pcomment); -}; - -/* - * Get the size of the octave - */ -unsigned char Microtonal::getoctavesize(){ - if (Penabled!=0) return(octavesize); - else return(12); -}; - -/* - * Get the frequency according the note number - */ -REALTYPE Microtonal::getnotefreq(int note,int keyshift){ - // in this function will appears many times things like this: - // var=(a+b*100)%b - // I had written this way because if I use var=a%b gives unwanted results when a<0 - // This is the same with divisions. - - if ((Pinvertupdown!=0)&&((Pmappingenabled==0)||(Penabled==0))) note=(int) Pinvertupdowncenter*2-note; - - //compute global fine detune - REALTYPE globalfinedetunerap=pow(2.0,(Pglobalfinedetune-64.0)/1200.0);//-64.0 .. 63.0 cents - - if (Penabled==0) return(pow(2.0,(note-PAnote+keyshift)/12.0)*PAfreq*globalfinedetunerap);//12tET - - int scaleshift=((int)Pscaleshift-64+(int) octavesize*100)%octavesize; - - //compute the keyshift - REALTYPE rap_keyshift=1.0; - if (keyshift!=0){ - int kskey=(keyshift+(int)octavesize*100)%octavesize; - int ksoct=(keyshift+(int)octavesize*100)/octavesize-100; - rap_keyshift=(kskey==0) ? (1.0):(octave[kskey-1].tuning); - rap_keyshift*=pow(octave[octavesize-1].tuning,ksoct); - }; - - //if the mapping is enabled - if (Pmappingenabled!=0){ - if ((note<Pfirstkey)||(note>Plastkey)) return (-1.0); - //Compute how many mapped keys are from middle note to reference note - //and find out the proportion between the freq. of middle note and "A" note - int tmp=PAnote-Pmiddlenote,minus=0; - if (tmp<0) { tmp=-tmp; minus=1; }; - int deltanote=0; - for (int i=0;i<tmp;i++) if (Pmapping[i%Pmapsize]>=0) deltanote++; - REALTYPE rap_anote_middlenote=(deltanote==0) ? (1.0) : (octave[(deltanote-1)%octavesize].tuning); - if (deltanote!=0) rap_anote_middlenote*=pow(octave[octavesize-1].tuning,(deltanote-1)/octavesize); - if (minus!=0) rap_anote_middlenote=1.0/rap_anote_middlenote; - - //Convert from note (midi) to degree (note from the tunning) - int degoct=(note-(int)Pmiddlenote+(int) Pmapsize*200)/(int)Pmapsize-200; - int degkey=(note-Pmiddlenote+(int)Pmapsize*100)%Pmapsize; - degkey=Pmapping[degkey]; - if (degkey<0) return(-1.0);//this key is not mapped - - //invert the keyboard upside-down if it is asked for - //TODO: do the right way by using Pinvertupdowncenter - if (Pinvertupdown!=0){ - degkey=octavesize-degkey-1; - degoct=-degoct; - }; - //compute the frequency of the note - degkey=degkey+scaleshift; - degoct+=degkey/octavesize; - degkey%=octavesize; - - REALTYPE freq=(degkey==0) ? (1.0):octave[degkey-1].tuning; - freq*=pow(octave[octavesize-1].tuning,degoct); - freq*=PAfreq/rap_anote_middlenote; - freq*=globalfinedetunerap; - if (scaleshift!=0) freq/=octave[scaleshift-1].tuning; - return(freq*rap_keyshift); - } else {//if the mapping is disabled - int nt=note-PAnote+scaleshift; - int ntkey=(nt+(int)octavesize*100)%octavesize; - int ntoct=(nt-ntkey)/octavesize; - - REALTYPE oct=octave[octavesize-1].tuning; - REALTYPE freq=octave[(ntkey+octavesize-1)%octavesize].tuning*pow(oct,ntoct)*PAfreq; - if (ntkey==0) freq/=oct; - if (scaleshift!=0) freq/=octave[scaleshift-1].tuning; -// fprintf(stderr,"note=%d freq=%.3f cents=%d\n",note,freq,(int)floor(log(freq/PAfreq)/log(2.0)*1200.0+0.5)); - freq*=globalfinedetunerap; - return(freq*rap_keyshift); - }; -}; - - -/* - * Convert a line to tunings; returns -1 if it ok - */ -int Microtonal::linetotunings(unsigned int nline,const char *line){ - int x1=-1,x2=-1,type=-1; - REALTYPE x=-1.0,tmp,tuning=1.0; - if (strstr(line,"/")==NULL){ - if (strstr(line,".")==NULL){// M case (M=M/1) - sscanf(line,"%d",&x1); - x2=1; - type=2;//division - } else {// float number case - sscanf(line,"%f",&x); - if (x<0.000001) return(1); - type=1;//float type(cents) - }; - } else {// M/N case - sscanf(line,"%d/%d",&x1,&x2); - if ((x1<0)||(x2<0)) return(1); - if (x2==0) x2=1; - type=2;//division - }; - - if (x1<=0) x1=1;//not allow zero frequency sounds (consider 0 as 1) - - //convert to float if the number are too big - if ((type==2)&&((x1>(128*128*128-1))||(x2>(128*128*128-1)))){ - type=1; - x=((REALTYPE) x1)/x2; - }; - switch (type){ - case 1: x1=(int) floor(x); - tmp=fmod(x,1.0); - x2=(int) (floor (tmp*1e6)); - tuning=pow(2.0,x/1200.0); - break; - case 2: x=((REALTYPE)x1)/x2; - tuning=x; - break; - }; - - tmpoctave[nline].tuning=tuning; - tmpoctave[nline].type=type; - tmpoctave[nline].x1=x1; - tmpoctave[nline].x2=x2; - - return(-1);//ok -}; - -/* - * Convert the text to tunnings - */ -int Microtonal::texttotunings(const char *text){ - unsigned int i,k=0,nl=0; - char *lin; - lin=new char[MAX_LINE_SIZE+1]; - while (k<strlen(text)){ - for (i=0;i<MAX_LINE_SIZE;i++){ - lin[i]=text[k++]; - if (lin[i]<0x20) break; - }; - lin[i]='\0'; - if (strlen(lin)==0) continue; - int err=linetotunings(nl,lin); - if (err!=-1) { - delete [] lin; - return(nl);//Parse error - }; - nl++; - }; - delete [] lin; - if (nl>MAX_OCTAVE_SIZE) nl=MAX_OCTAVE_SIZE; - if (nl==0) return(-2);//the input is empty - octavesize=nl; - for (i=0;i<octavesize;i++){ - octave[i].tuning=tmpoctave[i].tuning; - octave[i].type=tmpoctave[i].type; - octave[i].x1=tmpoctave[i].x1; - octave[i].x2=tmpoctave[i].x2; - }; - return(-1);//ok -}; - -/* - * Convert the text to mapping - */ -void Microtonal::texttomapping(const char *text){ - unsigned int i,k=0; - char *lin; - lin=new char[MAX_LINE_SIZE+1]; - for (i=0;i<128;i++) Pmapping[i]=-1; - int tx=0; - while (k<strlen(text)){ - for (i=0;i<MAX_LINE_SIZE;i++){ - lin[i]=text[k++]; - if (lin[i]<0x20) break; - }; - lin[i]='\0'; - if (strlen(lin)==0) continue; - - int tmp=0; - if (sscanf(lin,"%d",&tmp)==0) tmp=-1; - if (tmp<-1) tmp=-1; - Pmapping[tx]=tmp; - - if ((tx++)>127) break; - }; - delete [] lin; - - if (tx==0) tx=1; - Pmapsize=tx; -}; - -/* - * Convert tunning to text line - */ -void Microtonal::tuningtoline(int n,char *line,int maxn){ - if ((n>octavesize) || (n>MAX_OCTAVE_SIZE)) { - line[0]='\0'; - return; - }; - if (octave[n].type==1) snprintf(line,maxn,"%d.%d",octave[n].x1,octave[n].x2); - if (octave[n].type==2) snprintf(line,maxn,"%d/%d",octave[n].x1,octave[n].x2); -}; - - -int Microtonal::loadline(FILE *file,char *line){ - do { - if (fgets(line,500,file)==0) return(1); - } while (line[0]=='!'); - return(0); -}; -/* - * Loads the tunnings from a scl file - */ -int Microtonal::loadscl(const char *filename){ - FILE *file=fopen(filename, "r"); - char tmp[500]; - fseek(file,0,SEEK_SET); - //loads the short description - if (loadline(file,&tmp[0])!=0) return(2); - for (int i=0;i<500;i++) if (tmp[i]<32) tmp[i]=0; - snprintf((char *) Pname,MICROTONAL_MAX_NAME_LEN,"%s",tmp); - snprintf((char *) Pcomment,MICROTONAL_MAX_NAME_LEN,"%s",tmp); - //loads the number of the notes - if (loadline(file,&tmp[0])!=0) return(2); - int nnotes=MAX_OCTAVE_SIZE; - sscanf(&tmp[0],"%d",&nnotes); - if (nnotes>MAX_OCTAVE_SIZE) return (2); - //load the tunnings - for (int nline=0;nline<nnotes;nline++){ - if (loadline(file,&tmp[0])!=0) return(2); - linetotunings(nline,&tmp[0]); - }; - fclose(file); - - octavesize=nnotes; - for (int i=0;i<octavesize;i++){ - octave[i].tuning=tmpoctave[i].tuning; - octave[i].type=tmpoctave[i].type; - octave[i].x1=tmpoctave[i].x1; - octave[i].x2=tmpoctave[i].x2; - }; - - return(0); -}; - -/* - * Loads the mapping from a kbm file - */ -int Microtonal::loadkbm(const char *filename){ - FILE *file=fopen(filename, "r"); - int x; - char tmp[500]; - - fseek(file,0,SEEK_SET); - //loads the mapsize - if (loadline(file,&tmp[0])!=0) return(2); - if (sscanf(&tmp[0],"%d",&x)==0) return(2); - if (x<1) x=0;if (x>127) x=127;//just in case... - Pmapsize=x; - //loads first MIDI note to retune - if (loadline(file,&tmp[0])!=0) return(2); - if (sscanf(&tmp[0],"%d",&x)==0) return(2); - if (x<1) x=0;if (x>127) x=127;//just in case... - Pfirstkey=x; - //loads last MIDI note to retune - if (loadline(file,&tmp[0])!=0) return(2); - if (sscanf(&tmp[0],"%d",&x)==0) return(2); - if (x<1) x=0;if (x>127) x=127;//just in case... - Plastkey=x; - //loads last the middle note where scale fro scale degree=0 - if (loadline(file,&tmp[0])!=0) return(2); - if (sscanf(&tmp[0],"%d",&x)==0) return(2); - if (x<1) x=0;if (x>127) x=127;//just in case... - Pmiddlenote=x; - //loads the reference note - if (loadline(file,&tmp[0])!=0) return(2); - if (sscanf(&tmp[0],"%d",&x)==0) return(2); - if (x<1) x=0;if (x>127) x=127;//just in case... - PAnote=x; - //loads the reference freq. - if (loadline(file,&tmp[0])!=0) return(2); - REALTYPE tmpPAfreq=440.0; - if (sscanf(&tmp[0],"%f",&tmpPAfreq)==0) return(2); - PAfreq=tmpPAfreq; - - //the scale degree(which is the octave) is not loaded, it is obtained by the tunnings with getoctavesize() method - if (loadline(file,&tmp[0])!=0) return(2); - - //load the mappings - if (Pmapsize!=0){ - for (int nline=0;nline<Pmapsize;nline++){ - if (loadline(file,&tmp[0])!=0) return(2); - if (sscanf(&tmp[0],"%d",&x)==0) x=-1; - Pmapping[nline]=x; - }; - Pmappingenabled=1; - } else { - Pmappingenabled=0; - Pmapping[0]=0; - Pmapsize=1; - }; - fclose(file); - - return(0); -}; - - - -void Microtonal::add2XML(XMLwrapper *xml){ - xml->addparstr("name",(char *) Pname); - xml->addparstr("comment",(char *) Pcomment); - - xml->addparbool("invert_up_down",Pinvertupdown); - xml->addparbool("invert_up_down_center",Pinvertupdowncenter); - - xml->addparbool("enabled",Penabled); - xml->addpar("global_fine_detune",Pglobalfinedetune); - - xml->addpar("a_note",PAnote); - xml->addparreal("a_freq",PAfreq); - - if ((Penabled==0)&&(xml->minimal)) return; - - xml->beginbranch("SCALE"); - xml->addpar("scale_shift",Pscaleshift); - xml->addpar("first_key",Pfirstkey); - xml->addpar("last_key",Plastkey); - xml->addpar("middle_note",Pmiddlenote); - - xml->beginbranch("OCTAVE"); - xml->addpar("octave_size",octavesize); - for (int i=0;i<octavesize;i++){ - xml->beginbranch("DEGREE",i); - if (octave[i].type==1){ - xml->addparreal("cents",octave[i].tuning); - }; - if (octave[i].type==2){ - xml->addpar("numerator",octave[i].x1); - xml->addpar("denominator",octave[i].x2); - }; - xml->endbranch(); - }; - xml->endbranch(); - - xml->beginbranch("KEYBOARD_MAPPING"); - xml->addpar("map_size",Pmapsize); - xml->addpar("mapping_enabled",Pmappingenabled); - for (int i=0;i<Pmapsize;i++){ - xml->beginbranch("KEYMAP",i); - xml->addpar("degree",Pmapping[i]); - xml->endbranch(); - }; - xml->endbranch(); - xml->endbranch(); -}; - -void Microtonal::getfromXML(XMLwrapper *xml){ - xml->getparstr("name",(char *) Pname,MICROTONAL_MAX_NAME_LEN); - xml->getparstr("comment",(char *) Pcomment,MICROTONAL_MAX_NAME_LEN); - - Pinvertupdown=xml->getparbool("invert_up_down",Pinvertupdown); - Pinvertupdowncenter=xml->getparbool("invert_up_down_center",Pinvertupdowncenter); - - Penabled=xml->getparbool("enabled",Penabled); - Pglobalfinedetune=xml->getpar127("global_fine_detune",Pglobalfinedetune); - - PAnote=xml->getpar127("a_note",PAnote); - PAfreq=xml->getparreal("a_freq",PAfreq,1.0,10000.0); - - if (xml->enterbranch("SCALE")){ - Pscaleshift=xml->getpar127("scale_shift",Pscaleshift); - Pfirstkey=xml->getpar127("first_key",Pfirstkey); - Plastkey=xml->getpar127("last_key",Plastkey); - Pmiddlenote=xml->getpar127("middle_note",Pmiddlenote); - - if (xml->enterbranch("OCTAVE")){ - octavesize=xml->getpar127("octave_size",octavesize); - for (int i=0;i<octavesize;i++){ - if (xml->enterbranch("DEGREE",i)==0) continue; - octave[i].x2=0; - octave[i].tuning=xml->getparreal("cents",octave[i].tuning); - octave[i].x1=xml->getpar127("numerator",octave[i].x1); - octave[i].x2=xml->getpar127("denominator",octave[i].x2); - - if (octave[i].x2!=0) octave[i].type=2; - else octave[i].type=1; - - xml->exitbranch(); - }; - xml->exitbranch(); - }; - - if (xml->enterbranch("KEYBOARD_MAPPING")){ - Pmapsize=xml->getpar127("map_size",Pmapsize); - Pmappingenabled=xml->getpar127("mapping_enabled",Pmappingenabled); - for (int i=0;i<Pmapsize;i++){ - if (xml->enterbranch("KEYMAP",i)==0) continue; - Pmapping[i]=xml->getpar127("degree",Pmapping[i]); - xml->exitbranch(); - }; - xml->exitbranch(); - }; - xml->exitbranch(); - }; -}; - - -int Microtonal::saveXML(char *filename){ - XMLwrapper *xml=new XMLwrapper(); - - xml->beginbranch("MICROTONAL"); - add2XML(xml); - xml->endbranch(); - - int result=xml->saveXMLfile(filename); - delete (xml); - return(result); -}; - -int Microtonal::loadXML(char *filename){ - XMLwrapper *xml=new XMLwrapper(); - if (xml->loadXMLfile(filename)<0) { - delete(xml); - return(-1); - }; - - if (xml->enterbranch("MICROTONAL")==0) return(-10); - getfromXML(xml); - xml->exitbranch(); - - delete(xml); - return(0); -}; - - |