From 12f20783b7ec8804825282fd04d9333ec83e31eb Mon Sep 17 00:00:00 2001 From: Florian Jung Date: Sun, 16 Jan 2011 18:18:39 +0100 Subject: Added waveforms and noise, changed foo++ into ++foo List of waveforms: 0=sin 1=abssin 2=half_sin 3=pulse-sin 4=square 5=sawtooth 6=pyramid 7=white noise --- TODO | 33 +++++++++++++------------- TODO.done | 6 ++++- synth/Makefile | 2 +- synth/OPTIMIZATIONS | 6 +++++ synth/channel.cpp | 34 +++++++++++++-------------- synth/defines.h | 2 +- synth/envelope.cpp | 2 +- synth/in_synth_cli.cpp | 10 ++++---- synth/jack.cpp | 52 ++++++++++++++++++++--------------------- synth/lfos.cpp | 14 +++++------ synth/main.cpp | 42 +++++++++++++++++++-------------- synth/note.cpp | 44 +++++++++++++++++----------------- synth/parser.cpp | 32 ++++++++++++------------- synth/programs.cpp | 8 +++---- synth/readwave.cpp | 2 +- synth/shared_object_manager.cpp | 6 ++--- synth/util.cpp | 8 +++---- 17 files changed, 159 insertions(+), 144 deletions(-) diff --git a/TODO b/TODO index d6704c7..6de4cb8 100644 --- a/TODO +++ b/TODO @@ -2,25 +2,12 @@ wenn man danach die noten spielen will. nicht reproduzierbar TODO für den synth -!! o im in-synth-cli auch die snh-freq setzen!!! - - o freq-envelopes und pfactor dafür auch für compiled_notes implementieren! - o envelopes nur alle N frames updaten auch bei compiled notes implementieren! - - o optimierung: foo++ durch ++foo ersetzen - o optimierung: bei allen iterationen: foo.end() cachen! - - o zu testen: funktionieren no-release-envs auch in compilierten noten? + o frameskip vlt nicht ++en? + o seltener cleanup rufen, stattdessen als inaktiv markieren + -> effekt: noten können wiederverwendet werden, seltenere ctor-aufrufe o RAM aufräumen? - o beide parser: envelopes von oscs mit out=0 standardmäßig deaktivieren - o envelope, filter, ggf. auch alles aus program.o im hauptprogramm - lassen? d.h. via init funktionspointer übergeben oder virtuelle - interfaceklassen benutzen (für envelope/filter z.B.) - - (o)bei program change vielleicht nicht _ALLE_ controller resetten? - o KSL mit powf und floats statt mit double umschreiben o statt lfo-nummer direkten zugriff auf curr_lfo angeben? o bei tremolo (und vibrato?): eventuell nicht prüfen, obs aktiviert @@ -29,7 +16,6 @@ TODO für den synth 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? @@ -46,11 +32,24 @@ TODO für den synth per RPN, NRPN o nur auf bestimmte channels reagieren + (o)bei program change vielleicht nicht _ALLE_ controller resetten? + (o)fehlerklassen für fatale fehler (von string abgeleitet) (o)bei filter-envelopes: ksr/ksl? nää. (o)resonanz-tremolo bei tiefpass? nää. +TODO für den compiler + o freq-envelopes und pfactor dafür auch für compiled_notes implementieren! + o envelopes nur alle N frames updaten auch bei compiled notes implementieren! + o zu testen: funktionieren no-release-envs auch in compilierten noten? + o envelopes von oscs mit out=0 standardmäßig deaktivieren + o envelope, filter, ggf. auch alles aus program.o im hauptprogramm + lassen? d.h. via init funktionspointer übergeben oder virtuelle + interfaceklassen benutzen (für envelope/filter z.B.) + + + TODO fürs CLI x ... diff --git a/TODO.done b/TODO.done index a83b6ed..26e7e06 100644 --- a/TODO.done +++ b/TODO.done @@ -69,7 +69,11 @@ TODO für den synth x im cli dürfen warnungen nicht mehr fatal sein x on-the-fly die LFOs ändern x funktioniert Channel::release_all bei gedrücktem HOLD oder SOSTENUTO? [ja] - x freq-envelopes: + x freq-envelopes + x im in-synth-cli auch die snh-freq setzen!!! + x optimierung: foo++ durch ++foo ersetzen + x optimierung: den relevanten iterationen: foo.end() cachen! + x mehr wellen für wave[] TODO fürs CLI diff --git a/synth/Makefile b/synth/Makefile index 0db09da..6258697 100644 --- a/synth/Makefile +++ b/synth/Makefile @@ -1,5 +1,5 @@ CXX=g++ -CFLAGS=-Wall -g +CFLAGS=-Wall -O2 CXXFLAGS=$(CFLAGS) LDFLAGS=-lm `pkg-config --cflags --libs jack` diff --git a/synth/OPTIMIZATIONS b/synth/OPTIMIZATIONS index b8bfe0d..07cbcff 100644 --- a/synth/OPTIMIZATIONS +++ b/synth/OPTIMIZATIONS @@ -8,6 +8,12 @@ Mögliche Optimierungen und filter-offset aus orig berechnen o 2% beim filter: evtl nur mit floats statt mit doubles rechnen? o <2% in note::get_sample u.a.: pitch-bending effizienter lösen? + o ??? Note's ctor kopiert viel unnötiges. besser: + channels bekommen je. eine kopie aller programme + noten bekommen nur noch pointer auf channeleigene kopie + note->set_param wird unnötig + pfactor-zeuch läuft extra: wird kopiert, und bei jeder + pfactor-änderung mit dem pfactor verrechnet x 0% beim channel::get_sample: pro note immer mehrere samples auf einmal holen (iterator braucht recht viel leistung) wird von g++ automatisch wegoptimiert -> ok diff --git a/synth/channel.cpp b/synth/channel.cpp index c2d0793..465facb 100644 --- a/synth/channel.cpp +++ b/synth/channel.cpp @@ -46,14 +46,14 @@ void Channel::cleanup() it=notes.erase(it); } else - it++; + ++it; } fixed_t Channel::get_sample() { fixed_t sum=0; - for (list::iterator it=notes.begin(); it!=notes.end(); it++) + for (list::iterator it=notes.begin(), end=notes.end(); it!=end; ++it) sum+=(*it)->get_sample(); return sum*volume >>SCALE; @@ -90,7 +90,7 @@ void Channel::note_off(int note) void Channel::really_do_note_off(int note) { - for (list::iterator it=notes.begin(); it!=notes.end(); it++) + for (list::iterator it=notes.begin(); it!=notes.end(); ++it) if ((*it)->get_note()==note) (*it)->release(); } @@ -147,7 +147,7 @@ void Channel::note_on(int note, int vel) { bool neednewnote=true; //if (always_reattack) always_reattack is always true when in polymode - for (it=notes.begin(); it!=notes.end(); it++) + for (it=notes.begin(); it!=notes.end(); ++it) if ( ((*it)->get_note()==note) && ((*it)->get_program()==program) ) { neednewnote=false; @@ -210,13 +210,13 @@ void Channel::apply_voice_limit() list::iterator it=notes.begin(); if (quick_release) - for (int i=0;irelease_quickly(quick_release); - it++; + ++it; } else - for (int i=0;idestroy(); it=notes.erase(it); @@ -251,7 +251,7 @@ void Channel::set_controller(int con,int val) void Channel::set_user_controller(int con, int val) { curr_prg.controller[con]=val; - for (set::iterator it=curr_prg.controller_affects[con].begin(); it!=curr_prg.controller_affects[con].end(); it++) + for (set::iterator it=curr_prg.controller_affects[con].begin(); it!=curr_prg.controller_affects[con].end(); ++it) recalc_param(*it,curr_prg); } @@ -262,7 +262,7 @@ void Channel::recalc_param(const parameter_t &par, program_t &prg) list *l; l=&(prg.formula[par]); - for (list::iterator it=l->begin(); it!=l->end(); it++) + for (list::iterator it=l->begin(); it!=l->end(); ++it) val+=curr_prg.controller[it->c]*it->f; if (val<0) val=0; @@ -296,7 +296,7 @@ void Channel::recalc_param(const parameter_t &par, program_t &prg) // waveform etc it's in int (i.e., val/ONE is very small, while // val is what we want) - for (list::iterator it=notes.begin(); it!=notes.end(); it++) + for (list::iterator it=notes.begin(); it!=notes.end(); ++it) (*it)->set_param(par, val); curr_prg.set_param(par, val); @@ -306,7 +306,7 @@ void Channel::reset_controllers() { program_t *orig=&program_settings[program]; - for (int i=0;i<128;i++) + for (int i=0;i<128;++i) set_user_controller(i,orig->controller[i]); } @@ -363,7 +363,7 @@ void Channel::set_real_portamento_frames() portamento_frames=0; list::iterator it; - for (it=notes.begin(); it!=notes.end(); it++) + for (it=notes.begin(); it!=notes.end(); ++it) (*it)->set_portamento_frames(portamento_frames); } @@ -378,7 +378,7 @@ void Channel::set_hold_pedal(bool newstate) //check for all held keys: is the key not pressed any more? // is the key not in sostenuto_keys? //if both conditions are fulfilled, release that note - for (set::iterator it=held_keys.begin(); it!=held_keys.end(); it++) + for (set::iterator it=held_keys.begin(); it!=held_keys.end(); ++it) if ( (pressed_keys.find(*it)==pressed_keys.end()) && (sostenuto_keys.find(*it)==sostenuto_keys.end()) ) note_off(*it); @@ -400,7 +400,7 @@ void Channel::set_sostenuto_pedal(bool newstate) else { if (hold_pedal_pressed==false) - for (set::iterator it=sostenuto_keys.begin(); it!=sostenuto_keys.end(); it++) + for (set::iterator it=sostenuto_keys.begin(); it!=sostenuto_keys.end(); ++it) if (pressed_keys.find(*it)==pressed_keys.end()) really_do_note_off(*it); @@ -439,7 +439,7 @@ void Channel::kill_program(int prog) it=notes.erase(it); } else - it++; + ++it; } void Channel::maybe_reload_program(int prog) @@ -451,7 +451,7 @@ void Channel::maybe_reload_program(int prog) void Channel::release_all() { list::iterator it; - for (it=notes.begin(); it!=notes.end(); it++) + for (it=notes.begin(); it!=notes.end(); ++it) (*it)->release(); } @@ -466,6 +466,6 @@ void Channel::set_pitch_bend(float val) pitchbend=pow(2.0,val/12.0)*ONE; list::iterator it; - for (it=notes.begin(); it!=notes.end(); it++) + for (it=notes.begin(); it!=notes.end(); ++it) (*it)->set_pitchbend(pitchbend); } diff --git a/synth/defines.h b/synth/defines.h index 34d745e..1421c30 100644 --- a/synth/defines.h +++ b/synth/defines.h @@ -56,7 +56,7 @@ extern float LFO_FREQ_HZ[]; #define WAVE_RES 44100 -#define N_WAVEFORMS 5 +#define N_WAVEFORMS 8 #define NO_CONT 128 diff --git a/synth/envelope.cpp b/synth/envelope.cpp index a6e79e0..13b1044 100644 --- a/synth/envelope.cpp +++ b/synth/envelope.cpp @@ -160,6 +160,6 @@ fixed_t Envelope::get_level() //must be called each frame break; } - t++; + ++t; return level; } diff --git a/synth/in_synth_cli.cpp b/synth/in_synth_cli.cpp index 7bf1fda..fd1570d 100644 --- a/synth/in_synth_cli.cpp +++ b/synth/in_synth_cli.cpp @@ -59,7 +59,7 @@ void lock_and_load_program(int prg_no, string file) else cout << "failed" << endl; - for (int i=0;imaybe_reload_program(prg_no); do_request(prg_no, false); @@ -139,7 +139,7 @@ void do_in_synth_cli() else if (command=="panic") { if ((params=="") || (params=="all")) - for (int i=0;ipanic(); else if (isnum(params)) { @@ -153,7 +153,7 @@ void do_in_synth_cli() else if (command=="release") { if ((params=="") || (params=="all")) - for (int i=0;irelease_all(); else if (isnum(params)) { @@ -180,7 +180,7 @@ void do_in_synth_cli() if ((num>=0) && (num<128)) { if (chanstr=="") - for (int i=0;ikill_program(num); else { @@ -228,7 +228,7 @@ void do_in_synth_cli() else if (command=="reset") { if ((params=="") || (params=="all")) - for (int i=0;ireset_controllers(); else if (isnum(params)) { diff --git a/synth/jack.cpp b/synth/jack.cpp index d0a6169..79c7b4a 100644 --- a/synth/jack.cpp +++ b/synth/jack.cpp @@ -30,14 +30,14 @@ void manage_program_lock(int prog, bool lock) //TODO woandershinschieben? program_lock[prog]=lock; if (lock) - for (int i=0;ikill_program(prog); } void process_request() { if (suspend_request.prog==-1) - for (int i=0;i<128;i++) + for (int i=0;i<128;++i) manage_program_lock(i,suspend_request.suspend); else manage_program_lock(suspend_request.prog,suspend_request.suspend); @@ -69,7 +69,7 @@ void init_jack() if (midi_in == NULL) throw string ("Registering MIDI IN failed"); - for (int i=0;i= xrun_n) { cout << "PANIC -- TOO MANY XRUNs! killing all voices" << endl<panic(); history.clear(); @@ -264,7 +264,7 @@ int process_callback(jack_nframes_t nframes, void *notused) - for (i=0;i=next_cleanup) { next_cleanup=lastframe+cleanup_interval; - for (i=0;icleanup(); } #ifdef DO_DEBUGGING_EVENTS @@ -396,9 +396,9 @@ int process_callback(jack_nframes_t nframes, void *notused) outtemp_nframes_left=0; } - for (i=0;i=event.time)) @@ -434,21 +434,21 @@ int process_callback(jack_nframes_t nframes, void *notused) channel[chan]->event(event.buffer[0], event.buffer[1], event.buffer[2]); } - n_events--; - curr_event++; + --n_events; + ++curr_event; //as long as there are some events left and getting one fails, get the next while ((n_events) && (jack_midi_event_get(&event, inport, curr_event /*, nframes */))) { - output_note("NOTE: lost a note :("); - n_events--; - curr_event++; + output_note("NOTE2: lost a note :("); + --n_events; + ++curr_event; } } maybe_calc_lfos(); - for (int j=0;jget_sample())/ONE*VOL_FACTOR; @@ -473,7 +473,7 @@ int process_callback(jack_nframes_t nframes, void *notused) #ifdef FRAMESKIP if (i!=nframes) // nicht aufgegangen? { - for (int j=0;jget_sample())/ONE*VOL_FACTOR; @@ -486,9 +486,9 @@ int process_callback(jack_nframes_t nframes, void *notused) outtemp_nframes_left=frameskip-nframes+i; - for (i=i; i=0) ? wave[0][i] : 0; - wave[3][i]=(i<=WAVE_RES/4) ? wave[0][i] : 0; + float temp1, temp2; + temp1=sin(i*2.0*3.141592654/WAVE_RES); + temp2=sin(i*3.141592654/WAVE_RES); + wave[0][i]=temp1*ONE; + wave[1][i]=temp2*ONE; + wave[2][i]=(i<=WAVE_RES/2) ? wave[0][i] : 0; + wave[3][i]= (i<=WAVE_RES/2) ? wave[1][i] : 0; wave[4][i]=(iwave_len, oscillator[i].custom_wave->samp_rate); @@ -108,7 +108,7 @@ Note::~Note() { int i; - for (i=0;ipfactor.filter_res, vel); pfactor.filter_offset=calc_pfactor(curr_prg->pfactor.filter_offset, vel); - for (int i=0;ipfactor.out[i], vel) * volume_factor; pfactor.freq_env_amount[i]=calc_pfactor(curr_prg->pfactor.freq_env_amount[i], vel); - for (int j=0;jpfactor.fm[i][j], vel); } } @@ -151,12 +151,12 @@ void Note::recalc_factors() void Note::apply_pfactor() { //apply pfactor to all necessary parameters - for (int i=0;i>SCALE; oscillator[i].freq_env_amount=orig.oscillator[i].freq_env_amount*pfactor.freq_env_amount[i] /ONE; //because it's a float - for (int j=0;j>SCALE; } filter_params.env_amount=orig.filter_params.env_amount*pfactor.filter_env /ONE; @@ -247,7 +247,7 @@ void Note::set_param(const parameter_t &p, fixed_t v) //ACHTUNG: bool Note::still_active() { - for (int i=0; i0) && (envelope[i]->still_active())) return true; @@ -259,7 +259,7 @@ bool Note::still_active() //when called a second time, there shall be no effect void Note::release_quickly(jack_nframes_t maxt) { - for (int i=0;iget_release() > maxt) envelope[i]->set_release(maxt); @@ -274,7 +274,7 @@ void Note::release_quickly(jack_nframes_t maxt) void Note::release() { - for (int i=0;irelease_key(); factor_env[i]->release_key(); @@ -286,7 +286,7 @@ void Note::release() void Note::reattack() { - for (int i=0;ireattack(); factor_env[i]->reattack(); @@ -301,7 +301,7 @@ void Note::do_ksl() { //osc.ksl is in Bel/octave (i.e. dB/10) //if ksl=1, this means that for each octave the loudness //decreases by half - for (int i=0;iset_max(ONE); @@ -312,7 +312,7 @@ void Note::do_ksl() void Note::do_ksr() { - for (int i=0;iset_ratefactor(1.0 / pow(freq>>SCALE, oscillator[i].ksr)); } @@ -329,7 +329,7 @@ fixed_t Note::get_sample() do_ksl(); - portamento_t++; + ++portamento_t; } fixed_t actual_freq=freq*pitchbend >>SCALE; @@ -352,7 +352,7 @@ fixed_t Note::get_sample() { sync_phase-=ONE; - for (i=0;i=envelope_update_frames) { env_frame_counter=0; - for (i=0;iget_level(); @@ -378,11 +378,11 @@ fixed_t Note::get_sample() } - for (i=0;i=filter_update_frames) { filter_update_counter=0; diff --git a/synth/parser.cpp b/synth/parser.cpp index cd4ed02..174e0ee 100644 --- a/synth/parser.cpp +++ b/synth/parser.cpp @@ -22,7 +22,7 @@ string extract_array_name(string s) int extract_array_index(string s, int dim) { size_t p=-1,p2; - for (int i=0;i extract_formula(string s) term_t tmp; list terms=extract_terms(s); - for (list::iterator term=terms.begin(); term!=terms.end(); term++) + for (list::iterator term=terms.begin(); term!=terms.end(); ++term) { list factors=extract_factors(term->substr(1)); double fac= ((*term)[0]=='+') ? 1.0 : -1.0; string cont=""; - for (list::iterator factor=factors.begin(); factor!=factors.end(); factor++) + for (list::iterator factor=factors.begin(); factor!=factors.end(); ++factor) { if (factor->find_first_not_of("0123456789.*/+-")==string::npos) { @@ -135,12 +135,12 @@ param_factor_t parse_pfactor(string s) //TODO fast dasselbe wie oben. mergen? list terms=extract_terms(s); - for (list::iterator term=terms.begin(); term!=terms.end(); term++) + for (list::iterator term=terms.begin(); term!=terms.end(); ++term) { list factors=extract_factors(term->substr(1)); double fac= ((*term)[0]=='+') ? 1.0 : -1.0; string cont=""; - for (list::iterator factor=factors.begin(); factor!=factors.end(); factor++) + for (list::iterator factor=factors.begin(); factor!=factors.end(); ++factor) { if (factor->find_first_not_of("0123456789.*/+-")==string::npos) { @@ -182,12 +182,12 @@ param_factor_t parse_pfactor(string s) //TODO fast dasselbe wie oben. mergen? void init_oscs(int n_osc, oscillator_t *osc) { - for (int i=0;i > formula; int controller_default[128]; - for (int i=0;i<128;i++) + for (int i=0;i<128;++i) controller_default[i]=0; filter_params_t filter; @@ -557,7 +557,7 @@ program_t parse(string fn) par.index=ind2; terms=extract_formula(strval); - for (list::iterator it=terms.begin(); it!=terms.end(); it++) + for (list::iterator it=terms.begin(); it!=terms.end(); ++it) if (it->c!=NO_CONT) affect[it->c].insert(par); @@ -632,11 +632,11 @@ program_t parse(string fn) bool neverending_tone=false; - for (map< parameter_t, list >::iterator it=formula.begin(); it!=formula.end(); it++) + for (map< parameter_t, list >::iterator it=formula.begin(); it!=formula.end(); ++it) if ((it->first.par==OUTPUT) && (env[it->first.osc].release<0)) neverending_tone=true; - for (int i=0;icleanup(); - for (i=0;i<(sizeof(controller_affects)/sizeof(*controller_affects));i++) + for (i=0;i<(sizeof(controller_affects)/sizeof(*controller_affects));++i) this->controller_affects[i]=that.controller_affects[i]; this->formula=that.formula; this->n_osc=that.n_osc; @@ -126,7 +126,7 @@ program_t& program_t::operator=(const program_t &that) memcpy(this->pfactor.freq_env_amount, that.pfactor.freq_env_amount, sizeof(param_factor_t)*n_osc); this->pfactor.fm=new param_factor_t* [n_osc]; - for (i=0;ipfactor.fm[i]=new param_factor_t [n_osc]; memcpy(this->pfactor.fm[i], that.pfactor.fm[i], sizeof(param_factor_t)*n_osc); diff --git a/synth/readwave.cpp b/synth/readwave.cpp index 08106ca..0b2c0a0 100644 --- a/synth/readwave.cpp +++ b/synth/readwave.cpp @@ -102,7 +102,7 @@ void read_wave(const char *fn, custom_wave_t *result) result->wave=new fixed_t[n_samples]; double sample; - for (int i=0;i=0;i--) + for (i=result.length()-1;i>=0;--i) if ((result[i]!=' ') && (result[i]!='\t')) break; -- cgit v1.2.1