summaryrefslogtreecommitdiff
path: root/synth
diff options
context:
space:
mode:
Diffstat (limited to 'synth')
-rw-r--r--synth/TODO32
-rw-r--r--synth/TODO.done71
-rw-r--r--synth/main.cpp4
-rw-r--r--synth/parser.cpp673
-rw-r--r--synth/parser.h32
5 files changed, 350 insertions, 462 deletions
diff --git a/synth/TODO b/synth/TODO
deleted file mode 100644
index d507df0..0000000
--- a/synth/TODO
+++ /dev/null
@@ -1,32 +0,0 @@
-TODO für den synth
- o notes compilieren und als .so-datei laden
-
- o RAM aufräumen?
-
- o jedes programm eigene LFOs?
- o andere wellenformen bei LFOs?
- o mehr wellen für wave[]
-
- o parser: sehr redundante funktionen zusammenführen
- o parser: direkt in result schreiben?
-
- o attack und release ggf. auf niedrigen wert (<=0.01) initen, um
- knackser zu vermeiden?
-
- o chorus, reverb etc.
-
- o konnte-nicht-verbinden-warnung weniger schlimm machen
-
- o max_pitchbend per controller setzen?
- o nur auf bestimmte channels reagieren
-
- o diverse pedale (soft, sostenuto, halte, legato (?))
-
- (o)programs on-the-fly ändern (n_osc ändern)
- (o)lfo-maxima getrennt regeln. nää
- (o)bei filter-envelopes: ksr/ksl? nää.
- (o)resonanz-tremolo bei tiefpass? nää.
-
-
-TODO fürs CLI
- x ...
diff --git a/synth/TODO.done b/synth/TODO.done
deleted file mode 100644
index 0cd6d16..0000000
--- a/synth/TODO.done
+++ /dev/null
@@ -1,71 +0,0 @@
-TODO für den synth
- x knistern bei aktivem frameskip
- x tremolo und vibrato: phase nurnoch ++
- x rettack im monomode abschalten (sondern einfach nur freq ändern)
- x bei freqänderung: aufpassen, ob nicht das programm auch geändert
- wurde. wenn ja: delete && new
- x note-limit
- x stereo: pan/balance
- x envelopes on-the-fly ändern
- x programs laden
- x beim note-limit: statt abzuschneiden ausblenden
- x einstellmöglichkeiten via MIDI-controller
- x grund-controller bearbeiten
- x ein port pro channel
- x controllern einen defaultwert pro programm mitgeben
- x monophoner modus
- x reattack
- x alwaysreattack setzen können
- x portamento testen
- x memcheck-clean!
- x memcpy durch copy() plus operator= ersetzen?
- x pitch-bend
- x controller-reset
- x key scale level, key scale rate
- x akkurates note-on
- x frameskip
- x globale config-datei, oder alle programs in einem verz. einlesen etc.
- x auf dateifehler reagieren!
- x sampler-"oscs", d.h. laden von wav-dateien, die sich sonst
- wie oscs verhalten (fm möglich usw.)
- x analoge synthese auf den output jeder note anwenden
- x tiefpass via def.datei setzen: trem, env, res
- x tiefpass via controller setzen
- x osc-sync
- x bei genügend xruns noten töten
- x filter knackst
- x bei self-mod mit faktor 1 (auch ohne filter): segfault
- x bei starken vibratos: segfault, weil fm zu extrem wird
- x bei bug.prog: auch ohne filter: knacksen bei den meisten noten (z.B. C)
- x per velocity statt lautstärke andere params steuern
- x frameskip so implementieren, dass bufsize irrelevant ist
- x lfo_update_frames einstellbar machen
- sollte durch frameskip dividiert werden
- x tremolo- und vibrato-arrays sind mit mehreren MB zu groß!
- ein wert pro sample ist unnötig. könnte auch rechenzeit in
- calc_foo sparen, da seltener aufgerufen
- x sample-and-hold -> fm_strength, -> freq, -> VCF
- * bei osc-envelopes ggf. auch nur alle n frames neu setzen? [verschoben]
- * filter optimieren? (arbeiten momentan mit floats) [verschoben]
- verstehen, optimieren und dann profilen
- x stimmt die stereo-implementierung? [ja]
-
-
-TODO fürs CLI
- x filter_update_frames, lfo_update_frames in config, in sec (auch im CLI)
- x max_port_time einstellen
- x manuelle program -> datei - mappings
- x automatische mappings ( xxxIGNORIERT.prg, xxx ist die programmnummer),
- alle dateien eines verzeichnisses einlesen. bei nichtexistenz
- auf normalen sinus zurückfallen
- x konfigdateien lesen (inhalt wie CLI-optionen)
- x vibrato- und tremolo-frequenzen einstellen
- x cleanup-intervall setzen
- x space-sicher machen
- x fehlerbehandlung:
- syntaxfehler sollten übergangen werden, sofern möglich
- in parser: throw!, sonst: meckern und nächste zeile parsen
- x automatisch an alle midi-outs hängen
- x interface div-by-zero-sicher machen
-
-
diff --git a/synth/main.cpp b/synth/main.cpp
index deebf06..ae2e0d8 100644
--- a/synth/main.cpp
+++ b/synth/main.cpp
@@ -95,7 +95,6 @@ int main(int argc, char** argv)
lfo[i][j][k]= (1.0 + temp*(float(LFO_MAX)*k/N_LFO_LEVELS)) * ONE;
}
- Parser parser;
program_settings=new program_t[128];
for (i=0;i<128;i++)
@@ -104,8 +103,7 @@ int main(int argc, char** argv)
{
try
{
- parser.parse(programfile[i]);
- program_settings[i]=parser.get_results();
+ program_settings[i]=parse(programfile[i]);
}
catch (string err)
{
diff --git a/synth/parser.cpp b/synth/parser.cpp
index 52717a5..96648d6 100644
--- a/synth/parser.cpp
+++ b/synth/parser.cpp
@@ -1,3 +1,5 @@
+//uniniten
+
#include <cstdlib>
#include <fstream>
@@ -9,21 +11,32 @@
#include "readwave.h"
-Parser::Parser()
+string extract_array_name(string s)
{
- n_osc=0;
- osc=NULL;
- env=NULL;
- for (int i=0;i<128;i++)
- controller_default[i]=0;
+ size_t p;
+ p=s.find('[');
+ if (p!=string::npos)
+ return s.substr(0,p);
+ else
+ return s;
}
-Parser::~Parser()
+int extract_array_index(string s, int dim)
{
- uninit_stuff();
+ size_t p=-1,p2;
+ for (int i=0;i<dim;i++)
+ {
+ p=s.find('[',p+1);
+ if (p==string::npos) return -1;
+ }
+
+ p2=s.find(']',p+1);
+ if (p2==string::npos) return -1;
+
+ return atoi(s.substr(p+1,p2-p-1).c_str());
}
-list<string> Parser::extract_terms(string s)
+list<string> extract_terms(string s)
{
list<string> result;
@@ -43,7 +56,7 @@ list<string> Parser::extract_terms(string s)
return result;
}
-list<string> Parser::extract_factors(string s)
+list<string> extract_factors(string s)
{
list<string> result;
@@ -63,7 +76,7 @@ list<string> Parser::extract_factors(string s)
return result;
}
-list<term_t> Parser::extract_formula(string s)
+list<term_t> extract_formula(string s)
{
list<term_t> result;
term_t tmp;
@@ -116,7 +129,7 @@ list<term_t> Parser::extract_formula(string s)
return result;
}
-param_factor_t Parser::parse_pfactor(string s) //TODO fast dasselbe wie oben. mergen?
+param_factor_t parse_pfactor(string s) //TODO fast dasselbe wie oben. mergen?
{ //TODO cont müsste vel heißen FINDMICH ---> ^ ^ ^
param_factor_t result;
result.offset=0;
@@ -169,10 +182,8 @@ param_factor_t Parser::parse_pfactor(string s) //TODO fast dasselbe wie oben. me
return result;
}
-void Parser::init_stuff()
+void init_oscs(int n_osc, oscillator_t *osc)
{
- env=new env_settings_t[n_osc];
- osc=new oscillator_t[n_osc];
for (int i=0;i<n_osc;i++)
{
osc[i].n_osc=n_osc;
@@ -189,15 +200,23 @@ void Parser::init_stuff()
osc[i].vibrato_depth=0;
osc[i].vibrato_lfo=0;
osc[i].custom_wave=NULL;
-
-
+ }
+}
+
+void init_envs(int n_osc, env_settings_t *env)
+{
+ for (int i=0;i<n_osc;i++)
+ {
env[i].attack=0;
env[i].decay=0;
env[i].sustain=ONE;
env[i].release=0;
env[i].hold=true;
}
+}
+void init_filter(filter_params_t &filter)
+{
filter.enabled=false;
filter.env_amount=0;
filter.env_settings.attack=filter.env_settings.decay=
@@ -209,9 +228,10 @@ void Parser::init_stuff()
filter.resonance=0;
filter.trem_strength=0;
filter.trem_lfo=0;
-
-
-
+}
+
+void init_pfactors(int n_osc, pfactor_formula_t &pfactor)
+{
pfactor.out=new param_factor_t [n_osc];
pfactor.fm=new param_factor_t* [n_osc];
@@ -236,46 +256,12 @@ void Parser::init_stuff()
pfactor.fm[i][j].vel_amount=0;
}
}
-
-}
-void Parser::uninit_stuff()
-{
- if (osc)
- {
- for (int i=0;i<n_osc;i++)
- delete [] osc[i].fm_strength;
-
- delete [] osc;
- osc=NULL;
- }
- if (env)
- delete [] env;
}
-string Parser::extract_array_name(string s)
-{
- size_t p;
- p=s.find('[');
- if (p!=string::npos)
- return s.substr(0,p);
- else
- return s;
-}
-int Parser::extract_array_index(string s, int dim)
-{
- size_t p=-1,p2;
- for (int i=0;i<dim;i++)
- {
- p=s.find('[',p+1);
- if (p==string::npos) return -1;
- }
-
- p2=s.find(']',p+1);
- if (p2==string::npos) return -1;
-
- return atoi(s.substr(p+1,p2-p-1).c_str());
-}
+
+
+
//if this function fails, this WILL BE fatal if unhandled in the
//caller function. so this function throws errors
@@ -283,8 +269,28 @@ int Parser::extract_array_index(string s, int dim)
//state. if these settings are given to some oscillator_t by
//operator=, it will probably die while trying to create an array
//with size 0 or so.
-void Parser::parse(string fn)
+program_t parse(string fn)
{
+ int n_osc=0;
+ oscillator_t *osc=NULL;
+ env_settings_t *env=NULL;
+
+ set<parameter_t> affect[128];
+ map< parameter_t, list<term_t> > formula;
+ int controller_default[128];
+
+ for (int i=0;i<128;i++)
+ controller_default[i]=0;
+
+ filter_params_t filter;
+
+ pfactor_formula_t pfactor;
+
+ fixed_t sync_factor;
+
+
+
+
char buf[2000];
list<term_t> terms;
string line;
@@ -299,298 +305,299 @@ void Parser::parse(string fn)
int state;
- uninit_stuff();
-
ifstream f;
f.open(fn.c_str());
- if (f.good())
+ if (!f.good())
+ throw string ("could not open '"+fn+"'");
+ //else
+
+ state=0;
+ while (!f.eof())
{
- state=0;
- while (!f.eof())
+ f.getline(buf,sizeof(buf)/sizeof(*buf)-1);
+ line=buf;
+ line=remove_all_spaces(buf);
+ if ((line!="") && (line[0]!='#')) //ignore comments and empty lines
{
- f.getline(buf,sizeof(buf)/sizeof(*buf)-1);
- line=buf;
- line=remove_all_spaces(buf);
- if ((line!="") && (line[0]!='#')) //ignore comments and empty lines
+ if (line=="controllers:")
{
- if (line=="controllers:")
- {
- state=2;
- continue;
- }
- else if (line=="defaults:")
- {
- state=3;
- continue;
- }
- else if (line=="velocity:")
- {
- state=4;
- continue;
- }
+ state=2;
+ continue;
+ }
+ else if (line=="defaults:")
+ {
+ state=3;
+ continue;
+ }
+ else if (line=="velocity:")
+ {
+ state=4;
+ continue;
+ }
- var=extract_var(line);
- array=extract_array_name(var);
- strval=extract_val(line);
- val=atof(strval.c_str());
+ var=extract_var(line);
+ array=extract_array_name(var);
+ strval=extract_val(line);
+ val=atof(strval.c_str());
+
+ switch (state)
+ {
+ case 0: //expect and read number of oscillators
+ if (var!="oscillators")
+ throw string("need to know number of oscillators");
+ else
+ n_osc=val;
+
+ if (n_osc<=0) throw string("invalid number of oscillators");
+
+ //init stuff
+ env=new env_settings_t[n_osc];
+ osc=new oscillator_t[n_osc];
+ init_oscs(n_osc,osc);
+ init_envs(n_osc,env);
+ init_filter(filter);
+ init_pfactors(n_osc,pfactor);
+
+ state=1;
+ break;
- switch (state)
- {
- case 0: //expect and read number of oscillators
- if (var!="oscillators")
- throw string("need to know number of oscillators");
- else
- n_osc=val;
-
- if (n_osc<=0) throw string("invalid number of oscillators");
-
- init_stuff();
-
- state=1;
- break;
+ case 1: //read and set information about oscillator settings
+ p=param_to_enum(array);
+
+ ind=extract_array_index(var,1);
+ if ( param_needs_index(p) && (!((ind>=0) && (ind<n_osc))) )
+ throw string("out of array bounds");
+
- case 1: //read and set information about oscillator settings
- p=param_to_enum(array);
+ switch (p)
+ {
+ case MODULATION:
+ ind2=extract_array_index(var,2);
+ if (!((ind2>=0) && (ind2<n_osc)))
+ throw string("out of array bounds");
- ind=extract_array_index(var,1);
- if ( param_needs_index(p) && (!((ind>=0) && (ind<n_osc))) )
+ osc[ind].fm_strength[ind2]=val*ONE;
+ break;
+ case OUTPUT:
+ osc[ind].output=val*ONE;
+ break;
+ case WAVEFORM:
+ if (isfloat(strval))
+ {
+ osc[ind].waveform=int(val);
+ }
+ else
+ {
+ size_t pos=strval.find(':');
+ if (pos==string::npos)
+ throw string("expected 'freq:file.wav', found no ':'");
+
+ float given_freq=atof(strval.substr(0,pos).c_str());
+ string wavefile=strval.substr(pos+1);
+
+ if (given_freq<=0)
+ throw string("illegal freq specified for custom wave '"+wavefile+"'");
+
+ osc[ind].custom_wave=new custom_wave_t;
+ read_wave(wavefile.c_str(), osc[ind].custom_wave);
+ osc[ind].custom_wave->samp_rate/=given_freq;
+ }
+ break;
+ case FACTOR:
+ osc[ind].factor=val*ONE;
+ break;
+ case TREMOLO:
+ osc[ind].tremolo_depth=int(val);
+ break;
+ case TREM_LFO:
+ if (strval=="snh")
+ osc[ind].tremolo_lfo=SNH_LFO;
+ else
+ {
+ osc[ind].tremolo_lfo= int(val);
+ if ((val<0) || (val>=N_LFOS))
+ throw string("invalid value for tremolo_lfo");
+ }
+ break;
+ case VIBRATO:
+ osc[ind].vibrato_depth=val;
+ break;
+ case VIB_LFO:
+ if (strval=="snh")
+ osc[ind].vibrato_lfo= SNH_LFO;
+ else
+ {
+ osc[ind].vibrato_lfo= int(val);
+ if ((val<0) || (val>=N_LFOS))
+ throw string("invalid value for vibrato_lfo");
+ }
+ break;
+ case ATTACK:
+ env[ind].attack=val*samp_rate;
+ break;
+ case DECAY:
+ env[ind].decay=val*samp_rate;
+ break;
+ case SUSTAIN:
+ env[ind].sustain=val*ONE;
+ break;
+ case RELEASE:
+ env[ind].release=val*samp_rate;
+ break;
+ case HOLD:
+ env[ind].hold=(val!=0);
+ break;
+ case KSR:
+ osc[ind].ksr=val;
+ break;
+ case KSL:
+ osc[ind].ksl=val;
+ break;
+ case SYNC:
+ osc[ind].sync=(val!=0);
+ break;
+ case FILTER_ENABLED:
+ filter.enabled=(val!=0);
+ break;
+ case FILTER_ENV_AMOUNT:
+ filter.env_amount=val;
+ break;
+ case FILTER_ATTACK:
+ filter.env_settings.attack=val*samp_rate/filter_update_frames;
+ break;
+ case FILTER_DECAY:
+ filter.env_settings.decay=val*samp_rate/filter_update_frames;
+ break;
+ case FILTER_SUSTAIN:
+ filter.env_settings.sustain=val*ONE;
+ break;
+ case FILTER_RELEASE:
+ filter.env_settings.release=val*samp_rate/filter_update_frames;
+ break;
+ case FILTER_HOLD:
+ filter.env_settings.hold=(val!=0);
+ break;
+ case FILTER_OFFSET:
+ filter.freqfactor_offset=val;
+ break;
+ case FILTER_RESONANCE:
+ filter.resonance=val;
+ break;
+ case FILTER_TREMOLO:
+ filter.trem_strength=int(val);
+ break;
+ case FILTER_TREM_LFO:
+ if (strval=="snh")
+ filter.trem_lfo=SNH_LFO;
+ else
+ {
+ filter.trem_lfo=int(val);
+ if ((val<0) || (val>=N_LFOS))
+ throw string("invalid value for filter_trem_lfo");
+ }
+ break;
+ case SYNC_FACTOR:
+ sync_factor=val*ONE;
+ break;
+ default:
+ throw string("unknown variable ('"+array+"')");
+ }
+ break;
+
+ case 2: //read how controllers influence parameters
+ p=param_to_enum(array);
+
+ ind=extract_array_index(var,1);
+ if ( param_needs_index(p) && (!((ind>=0) && (ind<n_osc))) )
+ throw string("out of array bounds");
+
+ parameter_t par;
+ par.par=p;
+
+ if (par.par==UNKNOWN)
+ throw string("unknown variable ('"+array+"')");
+
+ if (par.par==MODULATION)
+ {
+ ind2=extract_array_index(var,2);
+ if (!((ind2>=0) && (ind2<n_osc)))
throw string("out of array bounds");
+ }
+
+ par.osc=ind;
+ par.index=ind2;
+
+ terms=extract_formula(strval);
+ for (list<term_t>::iterator it=terms.begin(); it!=terms.end(); it++)
+ if (it->c!=NO_CONT)
+ affect[it->c].insert(par);
+
+
+ formula[par]=terms;
+ break;
+
+ case 3: //read controller default values
+ if (array=="cont")
+ {
+ ind=extract_array_index(var,1);
+ if ((ind<0) || (ind>127))
+ throw string("out of array bounds");
- switch (p)
- {
- case MODULATION:
- ind2=extract_array_index(var,2);
- if (!((ind2>=0) && (ind2<n_osc)))
- throw string("out of array bounds");
+ if ((val<0) || (val>127))
+ throw string("value out of range");
- osc[ind].fm_strength[ind2]=val*ONE;
- break;
- case OUTPUT:
- osc[ind].output=val*ONE;
- break;
- case WAVEFORM:
- if (isfloat(strval))
- {
- osc[ind].waveform=int(val);
- }
- else
- {
- size_t pos=strval.find(':');
- if (pos==string::npos)
- throw string("expected 'freq:file.wav', found no ':'");
-
- float given_freq=atof(strval.substr(0,pos).c_str());
- string wavefile=strval.substr(pos+1);
-
- if (given_freq<=0)
- throw string("illegal freq specified for custom wave '"+wavefile+"'");
-
- osc[ind].custom_wave=new custom_wave_t;
- read_wave(wavefile.c_str(), osc[ind].custom_wave);
- osc[ind].custom_wave->samp_rate/=given_freq;
- }
- break;
- case FACTOR:
- osc[ind].factor=val*ONE;
- break;
- case TREMOLO:
- osc[ind].tremolo_depth=int(val);
- break;
- case TREM_LFO:
- if (strval=="snh")
- osc[ind].tremolo_lfo=SNH_LFO;
- else
- {
- osc[ind].tremolo_lfo= int(val);
- if ((val<0) || (val>=N_LFOS))
- throw string("invalid value for tremolo_lfo");
- }
- break;
- case VIBRATO:
- osc[ind].vibrato_depth=val;
- break;
- case VIB_LFO:
- if (strval=="snh")
- osc[ind].vibrato_lfo= SNH_LFO;
- else
- {
- osc[ind].vibrato_lfo= int(val);
- if ((val<0) || (val>=N_LFOS))
- throw string("invalid value for vibrato_lfo");
- }
- break;
- case ATTACK:
- env[ind].attack=val*samp_rate;
- break;
- case DECAY:
- env[ind].decay=val*samp_rate;
- break;
- case SUSTAIN:
- env[ind].sustain=val*ONE;
- break;
- case RELEASE:
- env[ind].release=val*samp_rate;
- break;
- case HOLD:
- env[ind].hold=(val!=0);
- break;
- case KSR:
- osc[ind].ksr=val;
- break;
- case KSL:
- osc[ind].ksl=val;
- break;
- case SYNC:
- osc[ind].sync=(val!=0);
- break;
- case FILTER_ENABLED:
- filter.enabled=(val!=0);
- break;
- case FILTER_ENV_AMOUNT:
- filter.env_amount=val;
- break;
- case FILTER_ATTACK:
- filter.env_settings.attack=val*samp_rate/filter_update_frames;
- break;
- case FILTER_DECAY:
- filter.env_settings.decay=val*samp_rate/filter_update_frames;
- break;
- case FILTER_SUSTAIN:
- filter.env_settings.sustain=val*ONE;
- break;
- case FILTER_RELEASE:
- filter.env_settings.release=val*samp_rate/filter_update_frames;
- break;
- case FILTER_HOLD:
- filter.env_settings.hold=(val!=0);
- break;
- case FILTER_OFFSET:
- filter.freqfactor_offset=val;
- break;
- case FILTER_RESONANCE:
- filter.resonance=val;
- break;
- case FILTER_TREMOLO:
- filter.trem_strength=int(val);
- break;
- case FILTER_TREM_LFO:
- if (strval=="snh")
- filter.trem_lfo=SNH_LFO;
- else
- {
- filter.trem_lfo=int(val);
- if ((val<0) || (val>=N_LFOS))
- throw string("invalid value for filter_trem_lfo");
- }
- break;
- case SYNC_FACTOR:
- sync_factor=val*ONE;
- break;
- default:
- throw string("unknown variable ('"+array+"')");
- }
- break;
-
- case 2: //read how controllers influence parameters
- p=param_to_enum(array);
-
- ind=extract_array_index(var,1);
- if ( param_needs_index(p) && (!((ind>=0) && (ind<n_osc))) )
- throw string("out of array bounds");
-
- parameter_t par;
- par.par=p;
-
- if (par.par==UNKNOWN)
- throw string("unknown variable ('"+array+"')");
+ controller_default[ind]=val;
+ }
+ else
+ throw string("expected cont, found '"+array+"'");
+
+ break;
+
+ case 4: //read velocity-influence over certain params
+ p=param_to_enum(array);
- if (par.par==MODULATION)
- {
+ ind=extract_array_index(var,1);
+ if ( param_needs_index(p) && (!((ind>=0) && (ind<n_osc))) )
+ throw string("out of array bounds");
+
+ switch(p)
+ {
+ case MODULATION:
ind2=extract_array_index(var,2);
if (!((ind2>=0) && (ind2<n_osc)))
throw string("out of array bounds");
- }
-
- par.osc=ind;
- par.index=ind2;
- terms=extract_formula(strval);
- for (list<term_t>::iterator it=terms.begin(); it!=terms.end(); it++)
- if (it->c!=NO_CONT)
- affect[it->c].insert(par);
-
-
- formula[par]=terms;
- break;
-
- case 3: //read controller default values
- if (array=="cont")
- {
- ind=extract_array_index(var,1);
+ pfactor.fm[ind][ind2]=parse_pfactor(strval);
+ break;
- if ((ind<0) || (ind>127))
- throw string("out of array bounds");
+ case OUTPUT:
+ pfactor.out[ind]=parse_pfactor(strval);
+ break;
- if ((val<0) || (val>127))
- throw string("value out of range");
-
- controller_default[ind]=val;
- }
- else
- throw string("expected cont, found '"+array+"'");
-
- break;
-
- case 4: //read velocity-influence over certain params
- p=param_to_enum(array);
-
- ind=extract_array_index(var,1);
- if ( param_needs_index(p) && (!((ind>=0) && (ind<n_osc))) )
- throw string("out of array bounds");
-
- switch(p)
- {
- case MODULATION:
- ind2=extract_array_index(var,2);
- if (!((ind2>=0) && (ind2<n_osc)))
- throw string("out of array bounds");
-
- pfactor.fm[ind][ind2]=parse_pfactor(strval);
- break;
-
- case OUTPUT:
- pfactor.out[ind]=parse_pfactor(strval);
- break;
-
- case FILTER_ENV_AMOUNT:
- pfactor.filter_env=parse_pfactor(strval);
- break;
-
- case FILTER_RESONANCE:
- pfactor.filter_res=parse_pfactor(strval);
- break;
-
- case FILTER_OFFSET:
- pfactor.filter_offset=parse_pfactor(strval);
- break;
-
- default:
- throw string("velocity cannot influence parameter '"+array+"'");
-
+ case FILTER_ENV_AMOUNT:
+ pfactor.filter_env=parse_pfactor(strval);
+ break;
+
+ case FILTER_RESONANCE:
+ pfactor.filter_res=parse_pfactor(strval);
+ break;
+
+ case FILTER_OFFSET:
+ pfactor.filter_offset=parse_pfactor(strval);
+ break;
+
+ default:
+ throw string("velocity cannot influence parameter '"+array+"'");
+
- }
- }
+ }
}
}
}
- else
- throw string ("could not open '"+fn+"'");
-}
-
-program_t Parser::get_results() const
-{
+
+
program_t result;
result.n_osc=n_osc;
@@ -613,6 +620,22 @@ program_t Parser::get_results() const
result.sync_factor=sync_factor;
result.pfactor=pfactor;
+
+
+
+ //clean up a bit
+
+ for (int i=0;i<n_osc;i++)
+ delete [] osc[i].fm_strength;
+
+ delete [] osc;
+ delete [] env;
+
+
+
+
return result;
}
+
+
diff --git a/synth/parser.h b/synth/parser.h
index 192226e..0af3c6a 100644
--- a/synth/parser.h
+++ b/synth/parser.h
@@ -12,36 +12,6 @@
using namespace std;
-class Parser
-{
- public:
- Parser();
- ~Parser();
- void parse(string fn);
- program_t get_results() const;
-
- private:
- void init_stuff();
- void uninit_stuff();
- static string extract_array_name(string s);
- static list<string> extract_terms(string s);
- static list<string> extract_factors(string s);
- static list<term_t> extract_formula(string s);
- static param_factor_t parse_pfactor(string s);
- static int extract_array_index(string s, int dim);
-
- int n_osc;
- oscillator_t *osc;
- env_settings_t *env;
- set<parameter_t> affect[128];
- map< parameter_t, list<term_t> > formula;
- int controller_default[128];
- filter_params_t filter;
-
- pfactor_formula_t pfactor;
-
- fixed_t sync_factor;
-};
-
+program_t parse(string fn);
#endif