Remove all static variables
parent
b26845ca1f
commit
fcb48f3dc4
60
engine.c
60
engine.c
|
@ -11,29 +11,25 @@
|
|||
#include "engine.h"
|
||||
#include "psyn.h"
|
||||
|
||||
static double _freqs[128];
|
||||
|
||||
struct engine_t _engine;
|
||||
|
||||
void engine_init()
|
||||
void engine_init(struct engine_t *engine)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < 128; i++) {
|
||||
_freqs[i] = 440.0 * pow(2.0, (i - 69.0) / 12.0);
|
||||
engine->freqs[i] = 440.0 * pow(2.0, (i - 69.0) / 12.0);
|
||||
}
|
||||
|
||||
osc_init();
|
||||
engine_load_program();
|
||||
engine_load_program(engine);
|
||||
}
|
||||
|
||||
void engine_load_program()
|
||||
void engine_load_program(struct engine_t *engine)
|
||||
{
|
||||
FILE *f = fopen("program.txt", "r");
|
||||
|
||||
while (!feof(f)) {
|
||||
char buf[1024];
|
||||
size_t l = fgets(buf, sizeof buf, f);
|
||||
fgets(buf, sizeof buf, f);
|
||||
|
||||
if (!strncmp(buf, "voice", 5)) {
|
||||
// Ignore voice
|
||||
|
@ -42,8 +38,8 @@ void engine_load_program()
|
|||
float freq;
|
||||
int r = sscanf(buf, "lfo %d %f", &lfo, &freq);
|
||||
if (r >= 2 && lfo >= 0 && lfo < NUM_LFO) {
|
||||
osc_setfreq(&_engine.lfo[lfo], freq);
|
||||
_engine.lfo[lfo].level = 1.0;
|
||||
osc_setfreq(&engine->lfo[lfo], freq);
|
||||
engine->lfo[lfo].level = 1.0;
|
||||
}
|
||||
} else if (!strncmp(buf, "osc", 3)) {
|
||||
int osc;
|
||||
|
@ -61,10 +57,10 @@ void engine_load_program()
|
|||
else if (!strcmp(sshape, "MOOGSAW")) shape = OSC_MOOGSAW;
|
||||
else if (!strcmp(sshape, "EXP")) shape = OSC_EXP;
|
||||
|
||||
_engine.params[osc].shape.value = shape;
|
||||
_engine.params[osc].level.value = level;
|
||||
_engine.params[osc].freq_mult.value = freq;
|
||||
_engine.params[osc].phase.value = phase;
|
||||
engine->params[osc].shape.value = shape;
|
||||
engine->params[osc].level.value = level;
|
||||
engine->params[osc].freq_mult.value = freq;
|
||||
engine->params[osc].phase.value = phase;
|
||||
}
|
||||
} else if (!strncmp(buf, "pan", 3)) {
|
||||
int pan;
|
||||
|
@ -75,17 +71,17 @@ void engine_load_program()
|
|||
if (r >= 4 && pan >= 0 && pan <= VOICE_OSCILLATORS) {
|
||||
int source = 0;
|
||||
if (!strcmp(ssource, "FIXED")) {
|
||||
_engine.params[pan].pan_type = PAN_FIXED;
|
||||
_engine.params[pan].pan_level = parm1;
|
||||
_engine.params[pan].pan_level_r = parm2;
|
||||
engine->params[pan].pan_type = PAN_FIXED;
|
||||
engine->params[pan].pan_level = parm1;
|
||||
engine->params[pan].pan_level_r = parm2;
|
||||
} else if (!strcmp(ssource, "OSC")) {
|
||||
_engine.params[pan].pan_type = PAN_OSC;
|
||||
_engine.params[pan].pan_source = parm1;
|
||||
_engine.params[pan].pan_level = parm2;
|
||||
engine->params[pan].pan_type = PAN_OSC;
|
||||
engine->params[pan].pan_source = parm1;
|
||||
engine->params[pan].pan_level = parm2;
|
||||
} else if (!strcmp(ssource, "LFO")) {
|
||||
_engine.params[pan].pan_type = PAN_LFO;
|
||||
_engine.params[pan].pan_source = parm1;
|
||||
_engine.params[pan].pan_level = parm2;
|
||||
engine->params[pan].pan_type = PAN_LFO;
|
||||
engine->params[pan].pan_source = parm1;
|
||||
engine->params[pan].pan_level = parm2;
|
||||
}
|
||||
}
|
||||
} else if (!strncmp(buf, "env", 3)) {
|
||||
|
@ -97,7 +93,7 @@ void engine_load_program()
|
|||
float release;
|
||||
int r = sscanf(buf, "env %d %f %f %f %f %f", &env, &attack, &hold, &decay, &sustain, &release);
|
||||
if (r >= 6 && env >= 0 && env < VOICE_OSCILLATORS) {
|
||||
env_init(&_engine.params[env].env, attack, hold, decay, sustain, release);
|
||||
env_init(&engine->params[env].env, attack, hold, decay, sustain, release);
|
||||
}
|
||||
} else if (!strncmp(buf, "cutoff_env", 10)) {
|
||||
int env;
|
||||
|
@ -108,7 +104,7 @@ void engine_load_program()
|
|||
float release;
|
||||
int r = sscanf(buf, "cutoff_env %d %f %f %f %f %f", &env, &attack, &hold, &decay, &sustain, &release);
|
||||
if (r >= 6 && env >= 0 && env < 1) {
|
||||
env_init(&_engine.cutoff_env, attack, hold, decay, sustain, release);
|
||||
env_init(&engine->cutoff_env, attack, hold, decay, sustain, release);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -122,20 +118,20 @@ void engine_run(struct engine_t *engine, uint32_t samples, float *left, float *r
|
|||
uint32_t i;
|
||||
|
||||
for (pos = 0; pos < samples; pos++) {
|
||||
control_tick(&_engine.lowpass);
|
||||
control_tick(&engine->lowpass);
|
||||
|
||||
left[pos] = 0.0;
|
||||
right[pos] = 0.0;
|
||||
|
||||
for (i = 0; i < NUM_LFO; i++) {
|
||||
osc_tick(&_engine.lfo[i]);
|
||||
osc_tick(&engine->lfo[i]);
|
||||
}
|
||||
|
||||
v = _engine.voice;
|
||||
v = engine->voice;
|
||||
for (i = 0; i < NUM_POLYPHONY; i++, v++) {
|
||||
if (!v->playing) continue;
|
||||
|
||||
voice_run(v, 1, left + pos, right + pos);
|
||||
voice_run(v, engine, 1, left + pos, right + pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -154,7 +150,7 @@ void engine_startvoice(struct engine_t *engine, uint8_t note, uint8_t velocity)
|
|||
v->velocity = velocity / 127.0;
|
||||
|
||||
/* Voice parameters which determine sound */
|
||||
voice_init(v, _freqs[note]);
|
||||
voice_init(v, engine, engine->freqs[note]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -169,7 +165,7 @@ void engine_startvoice(struct engine_t *engine, uint8_t note, uint8_t velocity)
|
|||
v->velocity = velocity / 127.0;
|
||||
|
||||
/* Voice parameters which determine sound */
|
||||
voice_init(v, _freqs[note]);
|
||||
voice_init(v, engine, engine->freqs[note]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
8
engine.h
8
engine.h
|
@ -16,12 +16,12 @@ struct engine_t
|
|||
struct envelope_t cutoff_env;
|
||||
|
||||
struct voice_t voice[NUM_POLYPHONY];
|
||||
|
||||
double freqs[128];
|
||||
};
|
||||
|
||||
extern struct engine_t _engine;
|
||||
|
||||
void engine_init();
|
||||
void engine_load_program();
|
||||
void engine_init(struct engine_t *engine);
|
||||
void engine_load_program(struct engine_t *engine);
|
||||
void engine_run(struct engine_t *engine, uint32_t samples, float *left, float *right);
|
||||
void engine_startvoice(struct engine_t *engine, uint8_t note, uint8_t velocity);
|
||||
void engine_endvoice(struct engine_t *engine, uint8_t note, uint8_t velocity);
|
||||
|
|
2
env.c
2
env.c
|
@ -17,7 +17,7 @@ void env_init(struct envelope_t *env, double attack, double attack_hold, double
|
|||
env->release_s = env->release * _sample_rate;
|
||||
}
|
||||
|
||||
double env_getamplitude(struct envelope_t *env, uint32_t sample, uint32_t released)
|
||||
double env_getamplitude(const struct envelope_t *env, uint32_t sample, uint32_t released)
|
||||
{
|
||||
double amplitude;
|
||||
|
||||
|
|
2
env.h
2
env.h
|
@ -16,5 +16,5 @@ struct envelope_t
|
|||
};
|
||||
|
||||
void env_init(struct envelope_t *env, double attack, double attack_hold, double decay, double sustain, double release);
|
||||
double env_getamplitude(struct envelope_t *env, uint32_t sample, uint32_t released);
|
||||
double env_getamplitude(const struct envelope_t *env, uint32_t sample, uint32_t released);
|
||||
|
||||
|
|
4
osc.h
4
osc.h
|
@ -42,13 +42,13 @@ static inline void osc_tick(struct osc_t *osc)
|
|||
//osc->tri = _tri_table[pos];
|
||||
}
|
||||
|
||||
static inline double osc_getsample(struct osc_t *osc)
|
||||
static inline double osc_getsample(const struct osc_t *osc)
|
||||
{
|
||||
uint32_t pos = osc->ramp;
|
||||
return _lookup_table[osc->shape][pos] * osc->level;
|
||||
}
|
||||
|
||||
static inline double osc_getsamplewithphase(struct osc_t *osc, float phase)
|
||||
static inline double osc_getsamplewithphase(const struct osc_t *osc, float phase)
|
||||
{
|
||||
double sample = osc->ramp + phase * LOOKUP_SAMPLES;
|
||||
if (sample < 0.0) sample += LOOKUP_SAMPLES;
|
||||
|
|
25
psyn.c
25
psyn.c
|
@ -26,13 +26,15 @@ struct psyn_t
|
|||
float *ctrlLP;
|
||||
float *ctrlOscShape[4];
|
||||
float *ctrlOscLevel[4];
|
||||
|
||||
struct engine_t engine;
|
||||
};
|
||||
|
||||
static void psyn_init(struct psyn_t *psyn, uint32_t sample_rate)
|
||||
{
|
||||
_sample_rate = sample_rate;
|
||||
|
||||
engine_init();
|
||||
engine_init(&psyn->engine);
|
||||
}
|
||||
|
||||
static LV2_Handle instantiate(
|
||||
|
@ -107,6 +109,7 @@ static void run(LV2_Handle lv2instance, uint32_t sample_count)
|
|||
{
|
||||
uint8_t i;
|
||||
struct psyn_t *psyn = (struct psyn_t *)lv2instance;
|
||||
struct engine_t *engine = &psyn->engine;
|
||||
uint32_t frame = 0;
|
||||
LV2_Event *ev = NULL;
|
||||
LV2_Event_Iterator iterator;
|
||||
|
@ -115,8 +118,8 @@ static void run(LV2_Handle lv2instance, uint32_t sample_count)
|
|||
|
||||
if (lv2_event_is_valid(&iterator)) ev = lv2_event_get(&iterator, NULL);
|
||||
|
||||
control_setstep(&_engine.lowpass, *psyn->ctrlLP, sample_count);
|
||||
_engine.monosynth = (int)*psyn->ctrlMono;
|
||||
control_setstep(&engine->lowpass, *psyn->ctrlLP, sample_count);
|
||||
engine->monosynth = (int)*psyn->ctrlMono;
|
||||
// for (i = 0; i < 4; i++) {
|
||||
// _engine.params[i].shape.value = *psyn->ctrlOscShape[i];
|
||||
// _engine.params[i].level.value = *psyn->ctrlOscLevel[i];
|
||||
|
@ -131,7 +134,7 @@ static void run(LV2_Handle lv2instance, uint32_t sample_count)
|
|||
to = sample_count;
|
||||
}
|
||||
|
||||
engine_run(&_engine, to - frame, psyn->out_l + frame, psyn->out_r + frame);
|
||||
engine_run(engine, to - frame, psyn->out_l + frame, psyn->out_r + frame);
|
||||
frame = to;
|
||||
|
||||
if (ev != NULL) {
|
||||
|
@ -142,31 +145,31 @@ static void run(LV2_Handle lv2instance, uint32_t sample_count)
|
|||
|
||||
switch (data[0] & 0xF0) {
|
||||
case 0x80:
|
||||
engine_endvoice(&_engine, data[1], data[2]);
|
||||
engine_endvoice(engine, data[1], data[2]);
|
||||
break;
|
||||
|
||||
case 0x90:
|
||||
engine_startvoice(&_engine, data[1], data[2]);
|
||||
engine_startvoice(engine, data[1], data[2]);
|
||||
break;
|
||||
|
||||
case 0xA0:
|
||||
engine_aftertouch(&_engine, data[2]);
|
||||
engine_aftertouch(engine, data[2]);
|
||||
break;
|
||||
|
||||
case 0xC0:
|
||||
engine_programchange(&_engine, data[1]);
|
||||
engine_programchange(engine, data[1]);
|
||||
break;
|
||||
|
||||
case 0xB0:
|
||||
engine_controlchange(&_engine, data[1], data[2]);
|
||||
engine_controlchange(engine, data[1], data[2]);
|
||||
break;
|
||||
|
||||
case 0xD0:
|
||||
engine_aftertouch(&_engine, data[1]);
|
||||
engine_aftertouch(engine, data[1]);
|
||||
break;
|
||||
|
||||
case 0xE0:
|
||||
engine_pitchchange(&_engine, (data[1] | data[2] << 7) - 0x2000);
|
||||
engine_pitchchange(engine, (data[1] | data[2] << 7) - 0x2000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
29
voice.c
29
voice.c
|
@ -16,7 +16,7 @@ static inline double max(double a, double b)
|
|||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
void voice_init(struct voice_t *voice, double freq)
|
||||
void voice_init(struct voice_t *voice, const struct engine_t *engine, double freq)
|
||||
{
|
||||
uint8_t i;
|
||||
// filter_init_rc(&voice->fil[0], 1000.0, 0.000000047);
|
||||
|
@ -27,11 +27,11 @@ void voice_init(struct voice_t *voice, double freq)
|
|||
// bw_filter_init_lp(&voice->bw[0], _engine.lowpass.value, 1.0);
|
||||
|
||||
for (i = 0; i < VOICE_OSCILLATORS; i++) {
|
||||
voice->osc[i].shape = _engine.params[i].shape.value;
|
||||
voice->osc[i].level = _engine.params[i].level.value;
|
||||
voice->osc[i].shape = engine->params[i].shape.value;
|
||||
voice->osc[i].level = engine->params[i].level.value;
|
||||
|
||||
osc_setfreq(&voice->osc[i], freq * _engine.params[i].freq_mult.value);
|
||||
osc_setphase(&voice->osc[i], _engine.params[i].phase.value);
|
||||
osc_setfreq(&voice->osc[i], freq * engine->params[i].freq_mult.value);
|
||||
osc_setphase(&voice->osc[i], engine->params[i].phase.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ static inline void voice_tick(struct voice_t *voice)
|
|||
voice->sample++;
|
||||
}
|
||||
|
||||
void voice_run(struct voice_t *voice, uint32_t samples, float *left, float *right)
|
||||
void voice_run(struct voice_t *voice, const struct engine_t *engine, uint32_t samples, float *left, float *right)
|
||||
{
|
||||
// uint32_t pos;
|
||||
int i;
|
||||
|
@ -58,7 +58,7 @@ void voice_run(struct voice_t *voice, uint32_t samples, float *left, float *righ
|
|||
|
||||
double amplitude = 0.0;
|
||||
for (i = 0; i < VOICE_OSCILLATORS; i++) {
|
||||
a[i] = env_getamplitude(&_engine.params[i].env, voice->sample, voice->released);
|
||||
a[i] = env_getamplitude(&engine->params[i].env, voice->sample, voice->released);
|
||||
amplitude += a[i];
|
||||
a[i] *= voice->velocity;
|
||||
}
|
||||
|
@ -69,23 +69,24 @@ void voice_run(struct voice_t *voice, uint32_t samples, float *left, float *righ
|
|||
}
|
||||
|
||||
for (i = 0; i < VOICE_OSCILLATORS; i++) {
|
||||
const struct voice_param_t *params = &engine->params[i];
|
||||
float ss;
|
||||
float pl = osc_getsample(&voice->osc[i]);
|
||||
float pr = pl;
|
||||
// Mix
|
||||
|
||||
switch (_engine.params[i].pan_type) {
|
||||
switch (params->pan_type) {
|
||||
case PAN_FIXED:
|
||||
pl *= _engine.params[i].pan_level;
|
||||
pr *= _engine.params[i].pan_level_r;
|
||||
pl *= params->pan_level;
|
||||
pr *= params->pan_level_r;
|
||||
break;
|
||||
case PAN_OSC:
|
||||
ss = osc_getsample(&voice->osc[_engine.params[i].pan_source]) * _engine.params[i].pan_level * 0.5;
|
||||
ss = osc_getsample(&voice->osc[params->pan_source]) * params->pan_level * 0.5;
|
||||
pl *= 0.5 + ss;
|
||||
pr *= 0.5 - ss;
|
||||
break;
|
||||
case PAN_LFO:
|
||||
ss = osc_getsample(&_engine.lfo[_engine.params[i].pan_source]) * _engine.params[i].pan_level * 0.5;
|
||||
ss = osc_getsample(&engine->lfo[params->pan_source]) * params->pan_level * 0.5;
|
||||
pl *= 0.5 + ss;
|
||||
pr *= 0.5 - ss;
|
||||
break;
|
||||
|
@ -119,8 +120,8 @@ void voice_run(struct voice_t *voice, uint32_t samples, float *left, float *righ
|
|||
|
||||
double out_l, out_r;
|
||||
|
||||
double cutoff = max(env_getamplitude(&_engine.cutoff_env, voice->sample, 0), _engine.aftertouch.value) * 8000.0;
|
||||
bw_filter_init_lp(&voice->bw[0], _engine.lowpass.value + cutoff, 1.0);
|
||||
double cutoff = max(env_getamplitude(&engine->cutoff_env, voice->sample, 0), engine->aftertouch.value) * 8000.0;
|
||||
bw_filter_init_lp(&voice->bw[0], engine->lowpass.value + cutoff, 1.0);
|
||||
bw_filter_run(&voice->bw[0], l, r, &out_l, &out_r);
|
||||
// filter_run_lp(&voice->fil[0], l, r);
|
||||
// filter_run_hp(&voice->fil[1], voice->fil[0].last_out_l, voice->fil[0].last_out_r);
|
||||
|
|
6
voice.h
6
voice.h
|
@ -38,5 +38,7 @@ struct voice_t
|
|||
struct bw_filter_t bw[VOICE_FILTERS];
|
||||
};
|
||||
|
||||
void voice_init(struct voice_t *voice, double freq);
|
||||
void voice_run(struct voice_t *voice, uint32_t samples, float *left, float *right);
|
||||
struct engine_t;
|
||||
|
||||
void voice_init(struct voice_t *voice, const struct engine_t *engine, double freq);
|
||||
void voice_run(struct voice_t *voice, const struct engine_t *engine, uint32_t samples, float *left, float *right);
|
||||
|
|
Loading…
Reference in New Issue