Parameterise most voice parameters
parent
d250b9044a
commit
13280feeec
20
engine.c
20
engine.c
|
@ -5,8 +5,8 @@
|
||||||
#include "env.h"
|
#include "env.h"
|
||||||
#include "osc.h"
|
#include "osc.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "voice.h"
|
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
|
#include "voice.h"
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
#include "psyn.h"
|
#include "psyn.h"
|
||||||
|
|
||||||
|
@ -23,15 +23,15 @@ void engine_init()
|
||||||
}
|
}
|
||||||
|
|
||||||
osc_init();
|
osc_init();
|
||||||
env_init(&_env, 0.0125, 0.025, 5.0, 0.0, 0.25);
|
env_init(&_engine.params[0].env, 0.0125, 0.025, 5.0, 0.0, 0.25);
|
||||||
env_init(&_env2, 0.0, 0.0, 0.5, 0.0, 0.25);
|
env_init(&_engine.params[1].env, 0.0, 0.0, 0.5, 0.0, 0.25);
|
||||||
|
|
||||||
osc_setfreq(&_engine.osc[0], 10.0);
|
osc_setfreq(&_engine.lfo[0], 10.0);
|
||||||
osc_setfreq(&_engine.osc[1], 2.0);
|
osc_setfreq(&_engine.lfo[1], 2.0);
|
||||||
osc_setfreq(&_engine.osc[2], 1.0);
|
osc_setfreq(&_engine.lfo[2], 1.0);
|
||||||
_engine.osc[0].level = 1.0;
|
_engine.lfo[0].level = 1.0;
|
||||||
_engine.osc[1].level = 1.0;
|
_engine.lfo[1].level = 1.0;
|
||||||
_engine.osc[2].level = 1.0;
|
_engine.lfo[2].level = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void engine_run(struct engine_t *engine, uint32_t samples, float *left, float *right)
|
void engine_run(struct engine_t *engine, uint32_t samples, float *left, float *right)
|
||||||
|
@ -47,7 +47,7 @@ void engine_run(struct engine_t *engine, uint32_t samples, float *left, float *r
|
||||||
right[pos] = 0.0;
|
right[pos] = 0.0;
|
||||||
|
|
||||||
for (i = 0; i < NUM_LFO; i++) {
|
for (i = 0; i < NUM_LFO; i++) {
|
||||||
osc_tick(&_engine.osc[i]);
|
osc_tick(&_engine.lfo[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
v = _engine.voice;
|
v = _engine.voice;
|
||||||
|
|
9
engine.h
9
engine.h
|
@ -1,5 +1,4 @@
|
||||||
|
|
||||||
#define NUM_LFO 4
|
|
||||||
#define NUM_POLYPHONY 32
|
#define NUM_POLYPHONY 32
|
||||||
|
|
||||||
struct engine_t
|
struct engine_t
|
||||||
|
@ -10,12 +9,12 @@ struct engine_t
|
||||||
struct control_t pitchbend;
|
struct control_t pitchbend;
|
||||||
struct control_t aftertouch;
|
struct control_t aftertouch;
|
||||||
|
|
||||||
struct control_t osc_shape[4];
|
|
||||||
struct control_t osc_level[4];
|
|
||||||
|
|
||||||
int monosynth;
|
int monosynth;
|
||||||
|
|
||||||
struct osc_t osc[NUM_LFO];
|
struct osc_t lfo[NUM_LFO];
|
||||||
|
struct voice_param_t params[VOICE_OSCILLATORS];
|
||||||
|
struct envelope_t cutoff_env;
|
||||||
|
|
||||||
struct voice_t voice[NUM_POLYPHONY];
|
struct voice_t voice[NUM_POLYPHONY];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
3
env.c
3
env.c
|
@ -3,9 +3,6 @@
|
||||||
#include "env.h"
|
#include "env.h"
|
||||||
#include "psyn.h"
|
#include "psyn.h"
|
||||||
|
|
||||||
struct envelope_t _env;
|
|
||||||
struct envelope_t _env2;
|
|
||||||
|
|
||||||
void env_init(struct envelope_t *env, double attack, double attack_hold, double decay, double sustain, double release)
|
void env_init(struct envelope_t *env, double attack, double attack_hold, double decay, double sustain, double release)
|
||||||
{
|
{
|
||||||
env->attack = attack;
|
env->attack = attack;
|
||||||
|
|
3
env.h
3
env.h
|
@ -15,9 +15,6 @@ struct envelope_t
|
||||||
double release_s;
|
double release_s;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct envelope_t _env;
|
|
||||||
extern struct envelope_t _env2;
|
|
||||||
|
|
||||||
void env_init(struct envelope_t *env, double attack, double attack_hold, double decay, double sustain, double release);
|
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(struct envelope_t *env, uint32_t sample, uint32_t released);
|
||||||
|
|
||||||
|
|
9
osc.h
9
osc.h
|
@ -3,6 +3,15 @@
|
||||||
|
|
||||||
extern double _lookup_table[6][LOOKUP_SAMPLES + 1];
|
extern double _lookup_table[6][LOOKUP_SAMPLES + 1];
|
||||||
|
|
||||||
|
enum {
|
||||||
|
OSC_SINE,
|
||||||
|
OSC_SAW,
|
||||||
|
OSC_TRIANGLE,
|
||||||
|
OSC_SQUARE,
|
||||||
|
OSC_MOOGSAW,
|
||||||
|
OSC_EXP,
|
||||||
|
};
|
||||||
|
|
||||||
struct osc_t
|
struct osc_t
|
||||||
{
|
{
|
||||||
double freq;
|
double freq;
|
||||||
|
|
7
psyn.c
7
psyn.c
|
@ -7,8 +7,9 @@
|
||||||
#include "lv2_uri_map.h"
|
#include "lv2_uri_map.h"
|
||||||
#include "osc.h"
|
#include "osc.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "voice.h"
|
#include "env.h"
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
|
#include "voice.h"
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
#include "psyn.h"
|
#include "psyn.h"
|
||||||
|
|
||||||
|
@ -117,8 +118,8 @@ static void run(LV2_Handle lv2instance, uint32_t sample_count)
|
||||||
control_setstep(&_engine.lowpass, *psyn->ctrlLP, sample_count);
|
control_setstep(&_engine.lowpass, *psyn->ctrlLP, sample_count);
|
||||||
_engine.monosynth = (int)*psyn->ctrlMono;
|
_engine.monosynth = (int)*psyn->ctrlMono;
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
_engine.osc_shape[i].value = *psyn->ctrlOscShape[i];
|
_engine.params[i].shape.value = *psyn->ctrlOscShape[i];
|
||||||
_engine.osc_level[i].value = *psyn->ctrlOscLevel[i];
|
_engine.params[i].level.value = *psyn->ctrlOscLevel[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
while (frame < sample_count) {
|
while (frame < sample_count) {
|
||||||
|
|
55
voice.c
55
voice.c
|
@ -5,8 +5,8 @@
|
||||||
#include "osc.h"
|
#include "osc.h"
|
||||||
#include "env.h"
|
#include "env.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "voice.h"
|
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
|
#include "voice.h"
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
#include "psyn.h"
|
#include "psyn.h"
|
||||||
#include "rng.h"
|
#include "rng.h"
|
||||||
|
@ -27,18 +27,12 @@ void voice_init(struct voice_t *voice, double freq)
|
||||||
// bw_filter_init_lp(&voice->bw[0], _engine.lowpass.value, 1.0);
|
// bw_filter_init_lp(&voice->bw[0], _engine.lowpass.value, 1.0);
|
||||||
|
|
||||||
for (i = 0; i < VOICE_OSCILLATORS; i++) {
|
for (i = 0; i < VOICE_OSCILLATORS; i++) {
|
||||||
voice->osc[i].shape = _engine.osc_shape[i].value;
|
voice->osc[i].shape = _engine.params[i].shape.value;
|
||||||
voice->osc[i].level = _engine.osc_level[i].value;
|
voice->osc[i].level = _engine.params[i].level.value;
|
||||||
}
|
|
||||||
|
|
||||||
osc_setfreq(&voice->osc[0], freq);
|
osc_setfreq(&voice->osc[i], freq * _engine.params[i].freq_mult.value);
|
||||||
osc_setphase(&voice->osc[0], 0.0);
|
osc_setphase(&voice->osc[i], _engine.params[i].phase.value);
|
||||||
osc_setfreq(&voice->osc[1], freq);// * 1.4983);
|
}
|
||||||
osc_setphase(&voice->osc[1], 0.25);
|
|
||||||
osc_setfreq(&voice->osc[2], freq * 2);
|
|
||||||
osc_setphase(&voice->osc[2], 0.0);
|
|
||||||
osc_setfreq(&voice->osc[3], 2500.0);
|
|
||||||
osc_setphase(&voice->osc[3], 0.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void voice_tick(struct voice_t *voice)
|
static inline void voice_tick(struct voice_t *voice)
|
||||||
|
@ -54,37 +48,34 @@ static inline void voice_tick(struct voice_t *voice)
|
||||||
void voice_run(struct voice_t *voice, uint32_t samples, float *left, float *right)
|
void voice_run(struct voice_t *voice, uint32_t samples, float *left, float *right)
|
||||||
{
|
{
|
||||||
// uint32_t pos;
|
// uint32_t pos;
|
||||||
double amplitude;
|
int i;
|
||||||
double l;
|
double a[VOICE_OSCILLATORS];
|
||||||
double r;
|
double l = 0.0;
|
||||||
|
double r = 0.0;
|
||||||
|
|
||||||
//for (pos = 0; pos < samples; pos++) {
|
//for (pos = 0; pos < samples; pos++) {
|
||||||
voice_tick(voice);
|
voice_tick(voice);
|
||||||
|
|
||||||
amplitude = env_getamplitude(&_env, voice->sample, voice->released);
|
double amplitude = 0.0;
|
||||||
|
for (i = 0; i < VOICE_OSCILLATORS; i++) {
|
||||||
|
a[i] = env_getamplitude(&_engine.params[i].env, voice->sample, voice->released);
|
||||||
|
amplitude += a[i];
|
||||||
|
a[i] *= voice->velocity;
|
||||||
|
}
|
||||||
|
|
||||||
if (amplitude <= 0.0001) {
|
if (amplitude <= 0.0001) {
|
||||||
voice->playing = false;
|
voice->playing = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
amplitude *= voice->velocity;
|
for (i = 0; i < VOICE_OSCILLATORS; i++) {
|
||||||
|
float s = osc_getsample(&voice->osc[i]);
|
||||||
|
|
||||||
float s;
|
// Mix
|
||||||
|
l += a[i] * s;
|
||||||
|
r += a[i] * s;
|
||||||
|
}
|
||||||
|
|
||||||
s = osc_getsample(&voice->osc[0]);
|
|
||||||
l = amplitude * s;// * (1.0 + rng() * 0.25);
|
|
||||||
r = amplitude * s;// * (1.0 + rng() * 0.25);
|
|
||||||
|
|
||||||
s = osc_getsample(&voice->osc[1]);
|
|
||||||
l += amplitude * s;
|
|
||||||
r += amplitude * s;
|
|
||||||
|
|
||||||
s = osc_getsample(&voice->osc[2]);
|
|
||||||
l += amplitude * s;
|
|
||||||
r += amplitude * s;
|
|
||||||
|
|
||||||
s = osc_getsample(&_engine.osc[0]);
|
|
||||||
// Amplitude mod
|
// Amplitude mod
|
||||||
// l *= 1.0 + s;
|
// l *= 1.0 + s;
|
||||||
// r *= 1.0 + s;
|
// r *= 1.0 + s;
|
||||||
|
@ -109,7 +100,7 @@ void voice_run(struct voice_t *voice, uint32_t samples, float *left, float *righ
|
||||||
|
|
||||||
double out_l, out_r;
|
double out_l, out_r;
|
||||||
|
|
||||||
double cutoff = max(env_getamplitude(&_env2, voice->sample, 0), _engine.aftertouch.value) * 8000.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_init_lp(&voice->bw[0], _engine.lowpass.value + cutoff, 1.0);
|
||||||
bw_filter_run(&voice->bw[0], l, r, &out_l, &out_r);
|
bw_filter_run(&voice->bw[0], l, r, &out_l, &out_r);
|
||||||
// filter_run_lp(&voice->fil[0], l, r);
|
// filter_run_lp(&voice->fil[0], l, r);
|
||||||
|
|
25
voice.h
25
voice.h
|
@ -1,5 +1,29 @@
|
||||||
#define VOICE_OSCILLATORS 4
|
#define VOICE_OSCILLATORS 4
|
||||||
#define VOICE_FILTERS 2
|
#define VOICE_FILTERS 2
|
||||||
|
#define NUM_LFO 4
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PAN_FIXED,
|
||||||
|
PAN_OSC,
|
||||||
|
PAN_LFO,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct voice_param_t
|
||||||
|
{
|
||||||
|
uint8_t pan_type;
|
||||||
|
union {
|
||||||
|
float pan;
|
||||||
|
uint8_t pan_osc;
|
||||||
|
uint8_t pan_lfo;
|
||||||
|
} u;
|
||||||
|
|
||||||
|
struct control_t shape;
|
||||||
|
struct control_t level;
|
||||||
|
struct control_t freq_mult;
|
||||||
|
struct control_t phase;
|
||||||
|
|
||||||
|
struct envelope_t env;
|
||||||
|
};
|
||||||
|
|
||||||
struct voice_t
|
struct voice_t
|
||||||
{
|
{
|
||||||
|
@ -9,6 +33,7 @@ struct voice_t
|
||||||
uint32_t released;
|
uint32_t released;
|
||||||
|
|
||||||
double velocity;
|
double velocity;
|
||||||
|
|
||||||
struct osc_t osc[VOICE_OSCILLATORS];
|
struct osc_t osc[VOICE_OSCILLATORS];
|
||||||
|
|
||||||
//struct filter_t fil[VOICE_FILTERS];
|
//struct filter_t fil[VOICE_FILTERS];
|
||||||
|
|
Loading…
Reference in New Issue