From 2f796b659626569c02dd5016dc3df45000e2b7e2 Mon Sep 17 00:00:00 2001 From: Florian Jung Date: Thu, 12 Apr 2012 22:35:44 +0200 Subject: use precalculated phase_increment instead of calculating it every frame: brings up to 33% speed boost! bugfix: ksr now uses dest_freq instead of (current) freq --- synth/OPTIMIZATIONS | 3 +++ synth/note.cpp | 44 ++++++++++++++++++++++++++++++++++---------- synth/note.h | 8 ++++++++ synth/note_skel.cpp | 2 ++ synth/note_skel.h | 2 ++ synth/profile.sh | 2 +- 6 files changed, 50 insertions(+), 11 deletions(-) diff --git a/synth/OPTIMIZATIONS b/synth/OPTIMIZATIONS index 4a22fd4..3ec667b 100644 --- a/synth/OPTIMIZATIONS +++ b/synth/OPTIMIZATIONS @@ -1,5 +1,8 @@ Sinnlose Optimierungen o if(foo.fm_strength!=0) ...: kein effekt, höchstens leichter anstieg! + o dauerndes nutzen von oscillator[i] durch einen curr_osc pointer + ersetzen (um etwa eine standardabweichung schneller -> kein + wirklicher effekt) Mögliche Optimierungen o ??? if (out>0) und was mit lfo: vlt das if weglassen? diff --git a/synth/note.cpp b/synth/note.cpp index f468a79..23267bf 100644 --- a/synth/note.cpp +++ b/synth/note.cpp @@ -50,6 +50,8 @@ Note::Note(int n, float v, program_t &prg, jack_nframes_t pf, fixed_t pb, int pr copy(&prg.osc_settings[0],&prg.osc_settings[n_oscillators],oscillator); copy(&prg.osc_settings[0],&prg.osc_settings[n_oscillators],orig.oscillator); + oscillator_phase_increment=new fixed_t[n_oscillators]; + fm_oscs=new list[n_oscillators]; for (int i=0;i> SCALE; break; case FREQ_ATTACK: factor_env[p.osc]->set_attack(v*samp_rate >>SCALE); break; case FREQ_DECAY: factor_env[p.osc]->set_decay(v*samp_rate >>SCALE); break; @@ -323,11 +330,27 @@ void Note::do_ksl() void Note::do_ksr() { for (int i=0;iset_ratefactor(1.0 / pow(freq>>SCALE, oscillator[i].ksr)); + envelope[i]->set_ratefactor(1.0 / pow(dest_freq>>SCALE, oscillator[i].ksr)); +} + +void Note::recalc_actual_freq() +{ + actual_freq=freq*pitchbend >>SCALE; + + sync_phase_increment=(actual_freq*sync_factor/samp_rate) >> SCALE; + + for (int i=0;i>SCALE; } fixed_t Note::get_sample() { + // maybe BOTTLENECK: possible optimisation: only execute every N frames if (freq!=dest_freq) { // the div.by.zero if p_frames=0 is avoided because then the @@ -337,13 +360,13 @@ fixed_t Note::get_sample() else //will only happen if p_t < p_frames -> p_frames is always > 0 -> div. ok freq = old_freq + (dest_freq-old_freq)*portamento_t/portamento_frames; + recalc_actual_freq(); + do_ksl(); ++portamento_t; } - fixed_t actual_freq=freq*pitchbend >>SCALE; - fixed_t *temp; temp=old_oscval; //swap the current and old oscval-pointers old_oscval=oscval; @@ -356,7 +379,7 @@ fixed_t Note::get_sample() if (sync_factor) { - sync_phase+=(actual_freq*sync_factor/samp_rate) >> SCALE; // BOTTLENECK + sync_phase+=sync_phase_increment; // phase-increment depends on: // - actual_freq (which depends on freq and pitchbend) // steadily updated while portamento-ing and whenever a pitchbend comes in @@ -389,6 +412,7 @@ fixed_t Note::get_sample() freqfactor_factor[i]=pow(2.0, oscillator[i].freq_env_amount*(factor_env[i]->get_level() - factor_env[i]->get_sustain())/ONE); oscillator[i].factor=orig.oscillator[i].factor*freqfactor_factor[i]; + recalc_oscillator_phase_increment(i); } } @@ -404,10 +428,10 @@ fixed_t Note::get_sample() fm=fm>>SCALE; //phase increases in one second, i.e. in samp_rate frames, by the osc's freq - if (oscillator[i].vibrato_depth!=0) - oscillator[i].phase+=( (curr_lfo[oscillator[i].vibrato_lfo][oscillator[i].vibrato_depth]*actual_freq >>SCALE)*oscillator[i].factor/samp_rate)>>SCALE; + if (oscillator[i].vibrato_depth!=0) // BOTTLENECK: update only on lfo recalculation + oscillator[i].phase+=oscillator_phase_increment[i]*curr_lfo[oscillator[i].vibrato_lfo][oscillator[i].vibrato_depth] >>SCALE; else - oscillator[i].phase+=(actual_freq*oscillator[i].factor/samp_rate)>>SCALE; // BOTTLENECK + oscillator[i].phase+=oscillator_phase_increment[i]; // phase-increment depends on: // - actual_freq (which depends on freq and pitchbend) // steadily updated while portamento-ing and whenever a pitchbend comes in diff --git a/synth/note.h b/synth/note.h index 379f2b1..3b8311e 100644 --- a/synth/note.h +++ b/synth/note.h @@ -24,6 +24,8 @@ class Note : public NoteSkel bool still_active(); void set_param(const parameter_t &p, fixed_t v); + void recalc_actual_freq(); + void destroy(); private: @@ -32,6 +34,8 @@ class Note : public NoteSkel void recalc_factors(); void apply_pfactor(); + + void recalc_oscillator_phase_increment(int osc); Envelope **envelope; @@ -45,10 +49,14 @@ class Note : public NoteSkel fixed_t *old_oscval; int n_oscillators; oscillator_t *oscillator; + fixed_t* oscillator_phase_increment; std::list* fm_oscs; fixed_t sync_factor; fixed_t sync_phase; + fixed_t sync_phase_increment; + + fixed_t actual_freq; pfactor_value_t pfactor; diff --git a/synth/note_skel.cpp b/synth/note_skel.cpp index 988f994..f3dd71f 100644 --- a/synth/note_skel.cpp +++ b/synth/note_skel.cpp @@ -18,6 +18,8 @@ NoteSkel::~NoteSkel() void NoteSkel::set_pitchbend(fixed_t pb) { pitchbend=pb; + + recalc_actual_freq(); } void NoteSkel::set_freq(float f) diff --git a/synth/note_skel.h b/synth/note_skel.h index 1afbe3a..4729aed 100644 --- a/synth/note_skel.h +++ b/synth/note_skel.h @@ -31,6 +31,8 @@ class NoteSkel virtual void set_param(const parameter_t &p, fixed_t v)=0; + virtual void recalc_actual_freq()=0; + virtual void destroy()=0; protected: diff --git a/synth/profile.sh b/synth/profile.sh index 921a5d4..a1b8096 100755 --- a/synth/profile.sh +++ b/synth/profile.sh @@ -7,6 +7,6 @@ else fi for ((i=1;i<=$cnt;i++)); do - /usr/bin/time -p ./synth -p 0:analog.prog -i 60 -x 1000:1 -a -m 2>&1 | grep 'user ' | sed 's/user //'; + /usr/bin/time -p ./synth -p 0:../../manyosc2.prog -i 60 -x 1000:1 -a -m 2>&1 | grep 'user ' | sed 's/user //'; #echo "$i / $cnt done" 1>&2 done | python avg_stddev.py -- cgit v1.2.3