summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO22
-rw-r--r--synth/note.cpp30
2 files changed, 27 insertions, 25 deletions
diff --git a/TODO b/TODO
index e031b3f..f8155f6 100644
--- a/TODO
+++ b/TODO
@@ -10,32 +10,34 @@ TODO für den synth
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 wave auf int*[] mit wave[i]=new int[] umbauen
+ x wave auf int*[] mit wave[i]=new int[] umbauen
-!!!o BUG: bei Note::set_param sollte statt dem eigentlichen param
+!!!x BUG: bei Note::set_param sollte statt dem eigentlichen param
der orig gesetzt werden und dann neu berechnet werden!
-!!!o BUG: bei release und reattack: BEIDE male die filter-envelope beachten!
+!!!x BUG: bei release und reattack: BEIDE male die filter-envelope beachten!
o KSL mit powf und floats statt mit double umschreiben
o statt lfo-nummer direkten zugriff auf curr_lfo angeben?
- o oscval-nullen kann in get_sample() weggelassen werden
+ x oscval-nullen kann in get_sample() weggelassen werden
o bei tremolo (und vibrato?): eventuell nicht prüfen, obs aktiviert
ist, sondern zur not einfach *1 rechnen?
- o in get_sample(), beim aufaddieren zum out (und vmtl auf fm-)wert:
+ x in get_sample(), beim aufaddieren zum out (und vmtl auch fm-)wert:
erst nach dem addieren scalen, statt für jeden faktor einzeln
o wenn sync global aus ist, kann auch osc.sync genullt werden
o beim default_program vielleicht auch ein optimiertes objekt benutzen?
- o filter_envelope könnte mit anderem ctor geinitet werden (weniger schreibarbeit)
- o notes compilieren und als .so-datei laden
+ x filter_envelope könnte mit anderem ctor geinitet werden (weniger schreibarbeit)
+ x notes compilieren und als .so-datei laden
o programme on-the-fly (um)laden
- o parser-klasse durch parse-funktion ersetzen
+ x parser-klasse durch parse-funktion ersetzen
- o reattack a) garnicht, b) immer, c) nur wenn schon in releasephase
+ x reattack a) garnicht, b) immer, c) nur wenn schon in releasephase
--> legatopedal!
o bei envelopes: releasephase abschalten (bei sustain bleiben)
+ o soft-pedal
+
o RAM aufräumen?
o jedes programm eigene LFOs?
@@ -56,7 +58,7 @@ TODO für den synth
o max_pitchbend per controller setzen?
o nur auf bestimmte channels reagieren
- o diverse pedale (soft, sostenuto, halte, legato (?))
+ x diverse pedale (soft, sostenuto, halte, legato (?))
(o)lfo-maxima getrennt regeln. nää
(o)bei filter-envelopes: ksr/ksl? nää.
diff --git a/synth/note.cpp b/synth/note.cpp
index a0d6226..86e4b2b 100644
--- a/synth/note.cpp
+++ b/synth/note.cpp
@@ -72,13 +72,7 @@ Note::Note(int n, float v, program_t &prg, jack_nframes_t pf, fixed_t pb, int pr
if (filter_params.enabled)
{
- filter_envelope=new Envelope(
- filter_params.env_settings.attack,
- filter_params.env_settings.decay,
- filter_params.env_settings.sustain,
- filter_params.env_settings.release,
- filter_params.env_settings.hold );
-
+ filter_envelope=new Envelope(filter_params.env_settings);
filter_update_counter=filter_update_frames;
}
@@ -170,8 +164,8 @@ void Note::set_param(const parameter_t &p, fixed_t v) //ACHTUNG:
case KSL: oscillator[p.osc].ksl=float(v)/ONE; break;
case FACTOR: oscillator[p.osc].factor=v; break;
- case MODULATION: oscillator[p.osc].fm_strength[p.index]=v*pfactor.fm[p.osc][p.index] >>SCALE; break;
- case OUTPUT: oscillator[p.osc].output=v*pfactor.out[p.osc] >>SCALE; break;
+ case MODULATION: orig.oscillator[p.osc].fm_strength[p.index]=v; apply_pfactor(); break;
+ case OUTPUT: orig.oscillator[p.osc].output=v; apply_pfactor(); break;
case TREMOLO: oscillator[p.osc].tremolo_depth=v; break;
case TREM_LFO: oscillator[p.osc].tremolo_lfo=v; break;
case VIBRATO: oscillator[p.osc].vibrato_depth=v; break;
@@ -180,7 +174,7 @@ void Note::set_param(const parameter_t &p, fixed_t v) //ACHTUNG:
case SYNC: oscillator[p.osc].sync=(v!=0); break;
case FILTER_ENABLED: output_note("NOTE: cannot enable filter in playing notes"); break;
- case FILTER_ENV_AMOUNT: filter_params.env_amount=float(v*pfactor.filter_env)/ONE/ONE; break;
+ case FILTER_ENV_AMOUNT: orig.filter_params.env_amount=float(v)/ONE; apply_pfactor(); break;
case FILTER_ATTACK:
if (filter_params.enabled)
@@ -217,8 +211,8 @@ void Note::set_param(const parameter_t &p, fixed_t v) //ACHTUNG:
output_note("NOTE: cannot set filter-hold when filter is disabled");
break;
- case FILTER_OFFSET: filter_params.freqfactor_offset=float(v*pfactor.filter_offset)/ONE/ONE; break;
- case FILTER_RESONANCE: filter_params.resonance=float(v*pfactor.filter_res)/ONE/ONE; break;
+ case FILTER_OFFSET: orig.filter_params.freqfactor_offset=float(v)/ONE; apply_pfactor(); break;
+ case FILTER_RESONANCE: orig.filter_params.resonance=float(v)/ONE; apply_pfactor(); break;
case FILTER_TREMOLO: filter_params.trem_strength=v; break;
case FILTER_TREM_LFO: filter_params.trem_lfo=v; break;
@@ -268,6 +262,9 @@ void Note::reattack()
{
for (int i=0;i<n_oscillators;i++)
envelope[i]->reattack();
+
+ if (filter_params.enabled)
+ filter_envelope->reattack();
}
@@ -340,12 +337,13 @@ fixed_t Note::get_sample()
for (i=0;i<n_oscillators;i++)
{
fm=0;
- oscval[i]=0;
for (j=0;j<n_oscillators;j++)
if (oscillator[i].fm_strength[j]!=0) //osc_j affects osc_i (FM)
- fm+=(old_oscval[j]*oscillator[i].fm_strength[j])>>SCALE;
+ fm+=old_oscval[j]*oscillator[i].fm_strength[j];
+ 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;
@@ -368,9 +366,11 @@ fixed_t Note::get_sample()
oscval[i]=oscval[i]* curr_lfo[oscillator[i].tremolo_lfo][oscillator[i].tremolo_depth] >> SCALE;
if (oscillator[i].output!=0)
- out+=oscillator[i].output*oscval[i] >>SCALE;
+ out+=oscillator[i].output*oscval[i];
}
+ out=out>>SCALE;
+
if (filter_params.enabled)
{
filter_update_counter++;