summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO1
-rw-r--r--TODO.done2
-rw-r--r--note_compiler/main.cpp4
-rw-r--r--note_compiler/parser.cpp13
-rw-r--r--note_compiler/plugin_factory/infile.cpp106
-rw-r--r--note_compiler/programs.h1
-rw-r--r--note_compiler/templates/ctor.foot1
-rw-r--r--note_compiler/templates/head.12
-rw-r--r--note_compiler/templates/interface.14
-rw-r--r--synth/Makefile2
-rw-r--r--synth/channel.cpp21
-rw-r--r--synth/channel.h3
-rw-r--r--synth/jack.cpp2
-rw-r--r--synth/note.cpp8
-rw-r--r--synth/note.h2
-rw-r--r--synth/note_funcs.h2
-rw-r--r--synth/note_skel.cpp9
-rw-r--r--synth/note_skel.h2
18 files changed, 72 insertions, 113 deletions
diff --git a/TODO b/TODO
index a77ac04..845f723 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,5 @@
TODO für den synth
o bei envelopes: releasephase abschalten (bei sustain bleiben)
- o soft-pedal
o programme on-the-fly (um)laden
o RAM aufräumen?
diff --git a/TODO.done b/TODO.done
index c03e853..654ff17 100644
--- a/TODO.done
+++ b/TODO.done
@@ -59,7 +59,7 @@ TODO für den synth
x filter_envelope könnte mit anderem ctor geinitet werden (weniger schreibarbeit)
x notes compilieren und als .so-datei laden
x parser-klasse durch parse-funktion ersetzen
- x sostenuto-, halte-, legato-pedal
+ x sostenuto-, halte-, legato-, soft-pedal
TODO fürs CLI
diff --git a/note_compiler/main.cpp b/note_compiler/main.cpp
index 47ed685..4d3fcae 100644
--- a/note_compiler/main.cpp
+++ b/note_compiler/main.cpp
@@ -109,7 +109,7 @@ void write_ctor()
int i;
string tabtmp="";
- out << "Note::Note(int n, float v, program_t &prg, jack_nframes_t pf, fixed_t pb, int prg_no)\n"
+ out << "Note::Note(int n, float v, program_t &prg, jack_nframes_t pf, fixed_t pb, int prg_no, float vol_fac)\n"
"{\n"
"\tcurr_prg=&prg;\n"
"\t\n"
@@ -234,7 +234,7 @@ void write_recalc_factors()
out << "\tfor (int i=0;i<"<<prog.n_osc<<";i++)\n"
"\t{\n"
- "\t\tpfactor.out[i]=calc_pfactor(curr_prg->pfactor.out[i], vel);\n"
+ "\t\tpfactor.out[i]=calc_pfactor(curr_prg->pfactor.out[i], vel) * volume_factor;\n"
"\t\t\n"
"\t\tfor (int j=0;j<"<<prog.n_osc<<";j++)\n"
"\t\t\tpfactor.fm[i][j]=calc_pfactor(curr_prg->pfactor.fm[i][j], vel);\n"
diff --git a/note_compiler/parser.cpp b/note_compiler/parser.cpp
index c89ddd9..7fb3fa0 100644
--- a/note_compiler/parser.cpp
+++ b/note_compiler/parser.cpp
@@ -24,7 +24,6 @@ void init_oscs(int n_osc, oscillator_t *osc)
osc[i].output=0;
osc[i].output_const=true;
- osc[i].output_no_pfactor=false;
osc[i].waveform=0;
osc[i].waveform_const=true;
osc[i].factor=ONE;
@@ -370,13 +369,9 @@ program_t parse(string fn)
osc[ind].fm_strength_const[ind2]=false;
break;
case OUTPUT:
- if (state==4) // vel.-influence
- {
- if (isfloat(strval)) //is it a plain number, not a formula?
- osc[ind].output_no_pfactor=true;
- }
- else
- osc[ind].output_const=false; break;
+ if (state!=4) // not vel.-influence
+ osc[ind].output_const=false;
+ break;
case WAVEFORM:
osc[ind].waveform_const=false; break;
case FACTOR:
@@ -481,7 +476,7 @@ program_t parse(string fn)
for (int i=0;i<n_osc;i++)
- if ( (osc[i].output_no_pfactor==false) && !((osc[i].output==0) && (osc[i].output_const=true)) )
+ if ( !((osc[i].output==0) && (osc[i].output_const=true)) )
osc[i].output_const=false;
//end optimizations and checks
diff --git a/note_compiler/plugin_factory/infile.cpp b/note_compiler/plugin_factory/infile.cpp
index 3523fd8..54ad6e5 100644
--- a/note_compiler/plugin_factory/infile.cpp
+++ b/note_compiler/plugin_factory/infile.cpp
@@ -26,7 +26,7 @@ IntToStr_func_t* IntToStr=NULL;
class Note : public NoteSkel
{
public:
- Note(int n, float v,program_t &prg, jack_nframes_t pf, fixed_t pb, int prg_no);
+ Note(int n, float v,program_t &prg, jack_nframes_t pf, fixed_t pb, int prg_no, float vol_fac);
~Note();
fixed_t get_sample();
@@ -58,17 +58,14 @@ class Note : public NoteSkel
//sync is disabled
- LowPassFilter filter;
- filter_params_t filter_params;
- int filter_update_counter;
- Envelope *filter_envelope;
+ //filter is disabled
pfactor_value_t pfactor;
struct
{
oscillator_t osc0;
oscillator_t osc1;
- filter_params_t filter_params;
+ //filter is disabled
} orig;
// member variables end here
};
@@ -82,7 +79,7 @@ inline fixed_t init_custom_osc_phase(int len, fixed_t sr)
}
-Note::Note(int n, float v, program_t &prg, jack_nframes_t pf, fixed_t pb, int prg_no)
+Note::Note(int n, float v, program_t &prg, jack_nframes_t pf, fixed_t pb, int prg_no, float vol_fac)
{
curr_prg=&prg;
@@ -106,23 +103,18 @@ Note::Note(int n, float v, program_t &prg, jack_nframes_t pf, fixed_t pb, int pr
//initalize oscillator.phase to multiples of their wave resolution
osc0.phase=ONE * PHASE_INIT;
- osc1.phase=init_custom_osc_phase(osc1.custom_wave->wave_len, osc1.custom_wave->samp_rate);
+ osc1.phase=ONE * PHASE_INIT;
do_ksl();
- filter_params=prg.filter_settings;
- orig.filter_params=prg.filter_settings;
- filter_envelope=new Envelope(filter_params.env_settings);
- filter_update_counter=filter_update_frames;
-
-
portamento_frames=0;
set_portamento_frames(pf);
set_note(n);
freq=dest_freq;
set_vel(v);
+ set_vol_factor(vol_fac);
pitchbend=pb;
@@ -153,13 +145,9 @@ void Note::destroy()
void Note::recalc_factors()
{
- pfactor.filter_env=calc_pfactor(curr_prg->pfactor.filter_env, vel);
- pfactor.filter_res=calc_pfactor(curr_prg->pfactor.filter_res, vel);
- pfactor.filter_offset=calc_pfactor(curr_prg->pfactor.filter_offset, vel);
-
for (int i=0;i<2;i++)
{
- pfactor.out[i]=calc_pfactor(curr_prg->pfactor.out[i], vel);
+ pfactor.out[i]=calc_pfactor(curr_prg->pfactor.out[i], vel) * volume_factor;
for (int j=0;j<2;j++)
pfactor.fm[i][j]=calc_pfactor(curr_prg->pfactor.fm[i][j], vel);
@@ -167,10 +155,6 @@ void Note::recalc_factors()
}
void Note::apply_pfactor()
{
- filter_params.env_amount=orig.filter_params.env_amount*pfactor.filter_env /ONE;
- filter_params.freqfactor_offset=orig.filter_params.freqfactor_offset*pfactor.filter_offset /ONE;
- filter_params.resonance=orig.filter_params.resonance*pfactor.filter_res /ONE;
-
osc0.output=orig.osc0.output*pfactor.out[0] >>SCALE;
for (int i=0;i<2;i++)
osc0.fm_strength[i]=orig.osc0.fm_strength[i]*pfactor.fm[0][i] >>SCALE;
@@ -191,8 +175,6 @@ void Note::release()
{
env0->release_key();
env1->release_key();
-
- filter_envelope->release_key();
}
void Note::release_quickly(jack_nframes_t maxt)
{
@@ -209,8 +191,6 @@ void Note::reattack()
{
env0->reattack();
env1->reattack();
-
- filter_envelope->reattack();
}
void Note::do_ksr()
@@ -249,29 +229,18 @@ fixed_t Note::get_sample()
//sync is disabled
- osc0.phase+= (actual_freq*osc0.factor/samp_rate)>>SCALE;
- oscval[0] = wave[0][ ( ( osc0.phase + ( + (old_oscval[1] * osc0.fm_strength[1]) >>SCALE ) ) * WAVE_RES >>SCALE ) % WAVE_RES ] * env0->get_level() >>SCALE;
- //oscillator0 has no tremolo
+ osc0.phase+= ( (osc0.vibrato_depth==0) ? ((actual_freq*osc0.factor/samp_rate)>>SCALE) : (( (curr_lfo[osc0.vibrato_lfo][osc0.vibrato_depth]*actual_freq >>SCALE)*osc0.factor/samp_rate)>>SCALE) );
+ oscval[0] = wave[1][ ( ( osc0.phase + ( + (old_oscval[0] * 104857) + (old_oscval[1] * osc0.fm_strength[1]) >>SCALE ) ) * WAVE_RES >>SCALE ) % WAVE_RES ] * env0->get_level() >>SCALE;
+ if (osc0.tremolo_depth)
+ oscval[0] = oscval[0] * curr_lfo[0][osc0.tremolo_depth] >>SCALE;
- osc1.phase+= (actual_freq*osc1.factor/samp_rate)>>SCALE;
- oscval[1] = osc1.custom_wave->wave[ ( osc1.phase * osc1.custom_wave->samp_rate >>(2*SCALE) ) % osc1.custom_wave->wave_len ] * env1->get_level() >>SCALE;
+ osc1.phase+= ( (curr_lfo[osc1.vibrato_lfo][osc1.vibrato_depth]*actual_freq >>SCALE)*osc1.factor/samp_rate)>>SCALE;
+ oscval[1] = wave[0][ ( osc1.phase * WAVE_RES >>SCALE ) % WAVE_RES ] * env1->get_level() >>SCALE;
//oscillator1 has no tremolo
- fixed_t out = ( + osc0.output*oscval[0] + osc1.output*oscval[1] >>SCALE );
-
+ fixed_t out = ( + osc0.output*oscval[0] >>SCALE );
- filter_update_counter++;
- if (filter_update_counter>=filter_update_frames)
- {
- filter_update_counter=0;
-
- float cutoff= float(actual_freq)/ONE *
- float(curr_lfo[filter_params.trem_lfo][filter_params.trem_strength])/ONE *
- ( filter_params.freqfactor_offset + filter_envelope->get_level() * filter_params.env_amount / float(ONE) );
- filter.set_params( cutoff, filter_params.resonance );
- }
- filter.process_sample(&out);
return out;
}
@@ -318,47 +287,18 @@ void Note::set_param(const parameter_t &p, fixed_t v)
case MODULATION: sel_orig_osc->fm_strength[p.index]=v; apply_pfactor(); break;
case OUTPUT: sel_orig_osc->output=v; apply_pfactor(); break;
-
- case FILTER_ENABLED: output_note("NOTE: cannot enable filter in playing notes"); break;
- case FILTER_ENV_AMOUNT: orig.filter_params.env_amount=float(v)/ONE; apply_pfactor(); 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;
-
+ case FILTER_ENABLED:
+ case FILTER_ENV_AMOUNT:
case FILTER_ATTACK:
- if (filter_params.enabled)
- filter_envelope->set_attack(v*samp_rate/filter_update_frames >>SCALE);
- else
- output_note("NOTE: cannot set filter-attack when filter is disabled");
- break;
-
case FILTER_DECAY:
- if (filter_params.enabled)
- filter_envelope->set_decay(v*samp_rate/filter_update_frames >>SCALE);
- else
- output_note("NOTE: cannot set filter-decay when filter is disabled");
- break;
-
case FILTER_SUSTAIN:
- if (filter_params.enabled)
- filter_envelope->set_sustain(v);
- else
- output_note("NOTE: cannot set filter-sustain when filter is disabled");
- break;
-
case FILTER_RELEASE:
- if (filter_params.enabled)
- filter_envelope->set_release(v*samp_rate/filter_update_frames >>SCALE);
- else
- output_note("NOTE: cannot set filter-release when filter is disabled");
- break;
-
case FILTER_HOLD:
- if (filter_params.enabled)
- filter_envelope->set_hold(v!=0);
- else
- output_note("NOTE: cannot set filter-hold when filter is disabled");
+ case FILTER_OFFSET:
+ case FILTER_RESONANCE:
+ case FILTER_TREMOLO:
+ case FILTER_TREM_LFO:
+ output_note("NOTE: trying to set some filter-param, but filter is disabled");
break;
@@ -370,13 +310,13 @@ void Note::set_param(const parameter_t &p, fixed_t v)
-extern "C" NoteSkel* create_note(int n, float v,program_t &prg, jack_nframes_t pf, fixed_t pb, int prg_no)
+extern "C" NoteSkel* create_note(int n, float v,program_t &prg, jack_nframes_t pf, fixed_t pb, int prg_no, float vol_fac)
{
if (wave==NULL)
throw string("FATAL: trying to create a new note from a shared object without initalizing\n"
" the object first! this should /never/ happen, please contact the developer");
- return new Note(n,v,prg,pf,pb,prg_no);
+ return new Note(n,v,prg,pf,pb,prg_no,vol_fac);
}
extern "C" void init_vars(int sr, int fupfr, fixed_t **w, fixed_t **clfo, output_note_func_t* out_n, IntToStr_func_t* its)
diff --git a/note_compiler/programs.h b/note_compiler/programs.h
index 9025ba1..d7acd61 100644
--- a/note_compiler/programs.h
+++ b/note_compiler/programs.h
@@ -47,7 +47,6 @@ struct oscillator_t
bool *fm_strength_const;
fixed_t output;
bool output_const;
- bool output_no_pfactor;
int waveform;
bool waveform_const;
fixed_t factor;
diff --git a/note_compiler/templates/ctor.foot b/note_compiler/templates/ctor.foot
index 05d4421..5cc0631 100644
--- a/note_compiler/templates/ctor.foot
+++ b/note_compiler/templates/ctor.foot
@@ -4,6 +4,7 @@
set_note(n);
freq=dest_freq;
set_vel(v);
+ set_vol_factor(vol_fac);
pitchbend=pb;
diff --git a/note_compiler/templates/head.1 b/note_compiler/templates/head.1
index 6759f56..b50d694 100644
--- a/note_compiler/templates/head.1
+++ b/note_compiler/templates/head.1
@@ -26,7 +26,7 @@ IntToStr_func_t* IntToStr=NULL;
class Note : public NoteSkel
{
public:
- Note(int n, float v,program_t &prg, jack_nframes_t pf, fixed_t pb, int prg_no);
+ Note(int n, float v,program_t &prg, jack_nframes_t pf, fixed_t pb, int prg_no, float vol_fac);
~Note();
fixed_t get_sample();
diff --git a/note_compiler/templates/interface.1 b/note_compiler/templates/interface.1
index cacc175..2ccee41 100644
--- a/note_compiler/templates/interface.1
+++ b/note_compiler/templates/interface.1
@@ -1,10 +1,10 @@
-extern "C" NoteSkel* create_note(int n, float v,program_t &prg, jack_nframes_t pf, fixed_t pb, int prg_no)
+extern "C" NoteSkel* create_note(int n, float v,program_t &prg, jack_nframes_t pf, fixed_t pb, int prg_no, float vol_fac)
{
if (wave==NULL)
throw string("FATAL: trying to create a new note from a shared object without initalizing\n"
" the object first! this should /never/ happen, please contact the developer");
- return new Note(n,v,prg,pf,pb,prg_no);
+ return new Note(n,v,prg,pf,pb,prg_no,vol_fac);
}
extern "C" void init_vars(int sr, int fupfr, fixed_t **w, fixed_t **clfo, output_note_func_t* out_n, IntToStr_func_t* its)
diff --git a/synth/Makefile b/synth/Makefile
index c1d6dab..864c0a7 100644
--- a/synth/Makefile
+++ b/synth/Makefile
@@ -1,5 +1,5 @@
CXX=g++
-CFLAGS=-Wall -O2
+CFLAGS=-Wall -g
CXXFLAGS=$(CFLAGS)
LDFLAGS=-lm `pkg-config --cflags --libs jack`
diff --git a/synth/channel.cpp b/synth/channel.cpp
index 0042162..fe28e7d 100644
--- a/synth/channel.cpp
+++ b/synth/channel.cpp
@@ -28,6 +28,7 @@ Channel::Channel()
sostenuto_keys.clear();
hold_pedal_pressed=false;
legato_pedal_pressed=false;
+ curr_vol_factor=1.0;
}
Channel::~Channel()
@@ -117,12 +118,14 @@ void Channel::note_on(int note, int vel)
newnote = new Note(note,(float)vel/128.0,
curr_prg,
portamento_frames, pitchbend,
- program);
+ program,
+ curr_vol_factor);
else
newnote = curr_prg.create_func(note,(float)vel/128.0,
curr_prg,
portamento_frames, pitchbend,
- program);
+ program,
+ curr_vol_factor);
notes.push_back(newnote);
}
@@ -132,6 +135,7 @@ void Channel::note_on(int note, int vel)
n->set_note(note,n->still_active());
n->set_vel((float)vel/128.0);
if ((legato_pedal_pressed==false) || !n->still_active()) n->reattack();
+ n->set_vol_factor(curr_vol_factor);
//no need to push back. would become #1 instead of #1
}
}
@@ -145,6 +149,7 @@ void Channel::note_on(int note, int vel)
neednewnote=false;
(*it)->reattack();
(*it)->set_vel((float)vel/128.0);
+ (*it)->set_vol_factor(curr_vol_factor);
notes.push_back(*it); //reorder notes
notes.erase(it);
break;
@@ -157,12 +162,14 @@ void Channel::note_on(int note, int vel)
newnote = new Note(note,(float)vel/128.0,
curr_prg,
portamento_frames, pitchbend,
- program);
+ program,
+ curr_vol_factor);
else
newnote = curr_prg.create_func(note,(float)vel/128.0,
curr_prg,
portamento_frames, pitchbend,
- program);
+ program,
+ curr_vol_factor);
notes.push_back(newnote);
}
@@ -223,6 +230,7 @@ void Channel::set_controller(int con,int val)
case 65: set_portamento(val); break;
case 64: set_hold_pedal(val>=64); break;
case 66: set_sostenuto_pedal(val>=64); break;
+ case 67: set_soft_pedal(val>=64); break;
case 68: set_legato_pedal(val>=64); break;
case 119: set_quick_release(val);
case 120: panic(); break;
@@ -394,6 +402,11 @@ void Channel::set_legato_pedal(bool newstate)
{
legato_pedal_pressed=newstate;
}
+
+void Channel::set_soft_pedal(bool newstate)
+{
+ curr_vol_factor = (newstate==false) ? 1.0 : 0.5; //TODO richtigen wert!
+}
void Channel::panic()
{
diff --git a/synth/channel.h b/synth/channel.h
index b0a855a..9727ab8 100644
--- a/synth/channel.h
+++ b/synth/channel.h
@@ -40,6 +40,7 @@ class Channel
void set_hold_pedal(bool newstate);
void set_sostenuto_pedal(bool newstate);
void set_legato_pedal(bool newstate);
+ void set_soft_pedal(bool newstate);
float balL, balR;
private:
@@ -71,6 +72,8 @@ class Channel
set<int> sostenuto_keys;
bool legato_pedal_pressed;
+
+ float curr_vol_factor;
};
#endif
diff --git a/synth/jack.cpp b/synth/jack.cpp
index 3949722..0c98855 100644
--- a/synth/jack.cpp
+++ b/synth/jack.cpp
@@ -12,7 +12,7 @@
using namespace std;
-#define DO_DEBUGGING_EVENTS
+//#define DO_DEBUGGING_EVENTS
jack_port_t *midi_in;
jack_port_t *out_port[N_CHANNELS];
diff --git a/synth/note.cpp b/synth/note.cpp
index b6bfa22..91291d7 100644
--- a/synth/note.cpp
+++ b/synth/note.cpp
@@ -14,12 +14,9 @@ inline fixed_t init_custom_osc_phase(int len, fixed_t sr)
}
-Note::Note(int n, float v, program_t &prg, jack_nframes_t pf, fixed_t pb, int prg_no)
+Note::Note(int n, float v, program_t &prg, jack_nframes_t pf, fixed_t pb, int prg_no, float vol_fac)
{
-
curr_prg=&prg;
-
-
n_oscillators=prg.n_osc;
@@ -92,6 +89,7 @@ Note::Note(int n, float v, program_t &prg, jack_nframes_t pf, fixed_t pb, int pr
set_note(n);
freq=dest_freq;
set_vel(v);
+ set_vol_factor(vol_fac);
pitchbend=pb;
@@ -132,7 +130,7 @@ void Note::recalc_factors()
for (int i=0;i<n_oscillators;i++)
{
- pfactor.out[i]=calc_pfactor(curr_prg->pfactor.out[i], vel);
+ pfactor.out[i]=calc_pfactor(curr_prg->pfactor.out[i], vel) * volume_factor;
for (int j=0;j<n_oscillators;j++)
pfactor.fm[i][j]=calc_pfactor(curr_prg->pfactor.fm[i][j], vel);
diff --git a/synth/note.h b/synth/note.h
index 03a7180..cc043e6 100644
--- a/synth/note.h
+++ b/synth/note.h
@@ -12,7 +12,7 @@
class Note : public NoteSkel
{
public:
- Note(int n, float v,program_t &prg, jack_nframes_t pf, fixed_t pb, int prg_no);
+ Note(int n, float v,program_t &prg, jack_nframes_t pf, fixed_t pb, int prg_no, float vol_fac);
~Note();
fixed_t get_sample();
diff --git a/synth/note_funcs.h b/synth/note_funcs.h
index 2a9d3c0..08ea7f9 100644
--- a/synth/note_funcs.h
+++ b/synth/note_funcs.h
@@ -14,7 +14,7 @@ struct program_t;
typedef void output_note_func_t(string s);
typedef string IntToStr_func_t(int i);
-typedef NoteSkel* create_func_t (int, float, program_t&, jack_nframes_t, fixed_t, int);
+typedef NoteSkel* create_func_t (int, float, program_t&, jack_nframes_t, fixed_t, int, float);
typedef void init_func_t(int sr, int fupfr, fixed_t **w, fixed_t **clfo, output_note_func_t* out_n, IntToStr_func_t* its);
#endif
diff --git a/synth/note_skel.cpp b/synth/note_skel.cpp
index b028ca4..988f994 100644
--- a/synth/note_skel.cpp
+++ b/synth/note_skel.cpp
@@ -62,6 +62,14 @@ void NoteSkel::set_vel(float v)
apply_pfactor();
}
+void NoteSkel::set_vol_factor(float vol_fac)
+{
+ volume_factor=vol_fac;
+
+ recalc_factors();
+ apply_pfactor();
+}
+
void NoteSkel::set_portamento_frames(jack_nframes_t t)
{
portamento_frames=t;
@@ -72,3 +80,4 @@ int NoteSkel::get_program()
{
return program;
}
+
diff --git a/synth/note_skel.h b/synth/note_skel.h
index 6aebb8b..1afbe3a 100644
--- a/synth/note_skel.h
+++ b/synth/note_skel.h
@@ -21,6 +21,7 @@ class NoteSkel
void set_freq(float f, bool do_port);
void set_pitchbend(fixed_t pb);
void set_vel(float v);
+ void set_vol_factor(float vol_fac);
void set_portamento_frames(jack_nframes_t f);
virtual void release_quickly(jack_nframes_t maxt)=0;
@@ -44,6 +45,7 @@ class NoteSkel
jack_nframes_t portamento_t, portamento_frames;
pfactor_value_t pfactor;
+ float volume_factor;
int note;
int program;