summaryrefslogtreecommitdiff
path: root/synth/programs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'synth/programs.cpp')
-rw-r--r--synth/programs.cpp224
1 files changed, 224 insertions, 0 deletions
diff --git a/synth/programs.cpp b/synth/programs.cpp
new file mode 100644
index 0000000..be82fed
--- /dev/null
+++ b/synth/programs.cpp
@@ -0,0 +1,224 @@
+#include <string>
+#include <cstring>
+
+#include "programs.h"
+#include "globals.h"
+
+using namespace std;
+
+oscillator_t::oscillator_t()
+{
+ phase=0;
+ fm_strength=NULL;
+
+ ksl=0;
+ ksr=0;
+
+ sync=false;
+
+ custom_wave=NULL;
+}
+
+oscillator_t& oscillator_t::operator=(const oscillator_t &that)
+{
+ if (this!=&that)
+ {
+ if (this->fm_strength)
+ delete [] this->fm_strength;
+
+ memcpy(this, &that, sizeof(*this));
+
+ this->fm_strength=new fixed_t[n_osc];
+ memcpy(this->fm_strength, that.fm_strength, sizeof(*that.fm_strength)*n_osc);
+
+ this->custom_wave=that.custom_wave;
+
+ return *this;
+ }
+ else
+ return *this;
+}
+
+program_t::program_t()
+{
+ osc_settings=NULL;
+ env_settings=NULL;
+ filter_settings.enabled=false;
+ sync_factor=0;
+ n_osc=0;
+
+ pfactor.fm=NULL;
+ pfactor.out=NULL;
+}
+
+program_t::~program_t()
+{
+ cleanup();
+}
+
+void program_t::cleanup()
+{
+ if (osc_settings)
+ {
+ for (unsigned int i=0;i<n_osc;i++)
+ delete [] osc_settings[i].fm_strength;
+ delete [] osc_settings;
+ }
+ if (env_settings)
+ delete [] env_settings;
+
+ if (pfactor.out)
+ delete [] pfactor.out;
+ if (pfactor.fm)
+ {
+ for (unsigned int i=0;i<n_osc;i++)
+ delete [] pfactor.fm[i];
+ delete [] pfactor.fm;
+ }
+}
+
+program_t& program_t::operator=(const program_t &that)
+{
+ if (this!=&that)
+ {
+ unsigned int i;
+
+ this->cleanup();
+
+ 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;
+
+ this->osc_settings=new oscillator_t[n_osc];
+ this->env_settings=new env_settings_t[n_osc];
+
+ memcpy(this->controller, that.controller, sizeof(that.controller));
+ copy(&that.osc_settings[0], &that.osc_settings[n_osc], this->osc_settings);
+ copy(&that.env_settings[0], &that.env_settings[n_osc], this->env_settings);
+
+ this->filter_settings=that.filter_settings;
+
+ this->sync_factor=that.sync_factor;
+
+
+
+ this->pfactor=that.pfactor;
+
+ this->pfactor.out=new param_factor_t [n_osc];
+ memcpy(this->pfactor.out, that.pfactor.out, sizeof(param_factor_t)*n_osc);
+
+ this->pfactor.fm=new param_factor_t* [n_osc];
+ for (i=0;i<n_osc;i++)
+ {
+ this->pfactor.fm[i]=new param_factor_t [n_osc];
+ memcpy(this->pfactor.fm[i], that.pfactor.fm[i], sizeof(param_factor_t)*n_osc);
+ }
+
+ return *this;
+ }
+ else
+ return *this;
+}
+
+void program_t::set_param(const parameter_t &p, fixed_t v) //ACHTUNG:
+{ //wenn das verändert wird, muss auch Note::set_param verändert werden!
+ switch(p.par)
+ {
+ case ATTACK: env_settings[p.osc].attack=v*samp_rate >>SCALE; break;
+ case DECAY: env_settings[p.osc].decay=v*samp_rate >>SCALE; break;
+ case SUSTAIN: env_settings[p.osc].sustain=v; break;
+ case RELEASE: env_settings[p.osc].release=v*samp_rate >>SCALE; break;
+ case HOLD: env_settings[p.osc].hold=(v!=0); break;
+
+ case KSR: osc_settings[p.osc].ksr=float(v)/ONE; break;
+ case KSL: osc_settings[p.osc].ksl=float(v)/ONE; break;
+
+ case FACTOR: osc_settings[p.osc].factor=v; break;
+ case MODULATION: osc_settings[p.osc].fm_strength[p.index]=v; break;
+ case OUTPUT: osc_settings[p.osc].output=v; break;
+ case TREMOLO: osc_settings[p.osc].tremolo_depth=v; break;
+ case TREM_LFO: osc_settings[p.osc].tremolo_lfo=v; break;
+ case VIBRATO: osc_settings[p.osc].vibrato_depth=v; break;
+ case VIB_LFO: osc_settings[p.osc].vibrato_lfo=v; break;
+ case WAVEFORM: osc_settings[p.osc].waveform=v; break;
+ case SYNC: osc_settings[p.osc].sync=(v!=0); break;
+
+ case FILTER_ENABLED: filter_settings.enabled=(v!=0); break;
+ case FILTER_ENV_AMOUNT: filter_settings.env_amount=float(v)/ONE; break;
+ case FILTER_ATTACK: filter_settings.env_settings.attack=v*samp_rate/filter_update_frames >>SCALE; break;
+ case FILTER_DECAY: filter_settings.env_settings.decay=v*samp_rate/filter_update_frames >>SCALE; break;
+ case FILTER_SUSTAIN: filter_settings.env_settings.sustain=v; break;
+ case FILTER_RELEASE: filter_settings.env_settings.release=v*samp_rate/filter_update_frames >>SCALE; break;
+ case FILTER_HOLD: filter_settings.env_settings.hold=(v!=0); break;
+ case FILTER_OFFSET: filter_settings.freqfactor_offset=float(v)/ONE; break;
+ case FILTER_RESONANCE: filter_settings.resonance=float(v)/ONE; break;
+ case FILTER_TREMOLO: filter_settings.trem_strength=v; break;
+ case FILTER_TREM_LFO: filter_settings.trem_lfo=v; break;
+
+ case SYNC_FACTOR: sync_factor=v; break;
+
+ default: throw string("trying to set an unknown parameter");
+ }
+}
+
+
+bool parameter_t::operator< (const struct parameter_t &b) const
+{
+ if (par!=b.par) return (par < b.par);
+ else if (osc!=b.osc) return (osc < b.osc);
+ else if (index!=b.index) return (index < b.index);
+ else return false; //they're equal
+}
+
+
+
+
+fixed_t calc_pfactor(param_factor_t &formula, fixed_t vel)
+{
+ return formula.offset + (formula.vel_amount * vel >>SCALE);
+}
+
+void init_default_program(program_t &p)
+{
+ p.n_osc=1;
+ p.osc_settings=new oscillator_t[1];
+ p.env_settings=new env_settings_t[1];
+ p.osc_settings[0].n_osc=1;
+ p.osc_settings[0].fm_strength=new fixed_t[1];
+ p.osc_settings[0].factor=ONE;
+ p.osc_settings[0].fm_strength[0]=0;
+ p.osc_settings[0].ksl=0;
+ p.osc_settings[0].ksr=0;
+ p.osc_settings[0].output=ONE;
+ p.osc_settings[0].tremolo_depth=0;
+ p.osc_settings[0].vibrato_depth=0;
+ p.osc_settings[0].waveform=0;
+ p.env_settings[0].attack=0;
+ p.env_settings[0].decay=0;
+ p.env_settings[0].sustain=ONE;
+ p.env_settings[0].release=3*samp_rate;
+ p.env_settings[0].hold=true;
+ p.filter_settings.enabled=false;
+
+
+ p.pfactor.out=new param_factor_t [1];
+ p.pfactor.fm=new param_factor_t* [1];
+
+ p.pfactor.filter_env.offset=ONE;
+ p.pfactor.filter_env.vel_amount=0;
+
+ p.pfactor.filter_res.offset=ONE;
+ p.pfactor.filter_res.vel_amount=0;
+ p.pfactor.filter_offset.offset=ONE;
+ p.pfactor.filter_offset.vel_amount=0;
+
+ p.pfactor.out[0].offset=0;
+ p.pfactor.out[0].vel_amount=ONE;
+
+ p.pfactor.fm[0]=new param_factor_t [1];
+ p.pfactor.fm[0][0].offset=ONE;
+ p.pfactor.fm[0][0].vel_amount=0;
+
+}
+