Oops, lots of changes

master
Peter Nelson 2010-01-20 07:49:38 +00:00
parent a2f4261b7a
commit 2d4ffb346b
10 changed files with 391 additions and 47 deletions

View File

@ -6,11 +6,14 @@
#include "osc.h" #include "osc.h"
#include "filter.h" #include "filter.h"
#include "voice.h" #include "voice.h"
#include "control.h"
#include "engine.h" #include "engine.h"
#include "psyn.h" #include "psyn.h"
static double _freqs[128]; static double _freqs[128];
struct engine_t _engine;
void engine_init() void engine_init()
{ {
uint32_t i; uint32_t i;
@ -21,7 +24,14 @@ void engine_init()
osc_init(); osc_init();
env_init(&_env, 0.0125, 0.025, 5.0, 0.0, 0.25); env_init(&_env, 0.0125, 0.025, 5.0, 0.0, 0.25);
env_init(&_env2, 0.0125, 0.025, 0.5, 0.0, 0.25); env_init(&_env2, 0.0, 0.0, 0.5, 0.0, 0.25);
osc_setfreq(&_engine.osc[0], 10.0);
osc_setfreq(&_engine.osc[1], 2.0);
osc_setfreq(&_engine.osc[2], 1.0);
_engine.osc[0].level = 1.0;
_engine.osc[1].level = 1.0;
_engine.osc[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)
@ -31,14 +41,16 @@ void engine_run(struct engine_t *engine, uint32_t samples, float *left, float *r
uint32_t i; uint32_t i;
for (pos = 0; pos < samples; pos++) { for (pos = 0; pos < samples; pos++) {
control_tick(&_engine.lowpass);
left[pos] = 0.0; left[pos] = 0.0;
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.osc[i]);
} }
v = engine->voice; v = _engine.voice;
for (i = 0; i < NUM_POLYPHONY; i++, v++) { for (i = 0; i < NUM_POLYPHONY; i++, v++) {
if (!v->playing) continue; if (!v->playing) continue;
@ -52,6 +64,19 @@ void engine_startvoice(struct engine_t *engine, uint8_t note, uint8_t velocity)
struct voice_t *v = engine->voice; struct voice_t *v = engine->voice;
uint32_t i; uint32_t i;
if (engine->monosynth > 0) {
/* Constant voice parameters */
v->playing = true;
if (v->released || engine->monosynth == 1) v->sample = 0;
v->released = 0;
v->note = note;
v->velocity = velocity / 127.0;
/* Voice parameters which determine sound */
voice_init(v, _freqs[note]);
return;
}
for (i = 0; i < NUM_POLYPHONY; i++, v++) { for (i = 0; i < NUM_POLYPHONY; i++, v++) {
if (v->playing) continue; if (v->playing) continue;
@ -80,3 +105,25 @@ void engine_endvoice(struct engine_t *engine, uint8_t note, uint8_t velocity)
v->released = v->sample; v->released = v->sample;
} }
} }
void engine_controlchange(struct engine_t *engine, uint8_t controller, uint8_t value)
{
printf("Control change %u -> %u\n", controller, value);
}
void engine_programchange(struct engine_t *engine, uint8_t value)
{
printf("Program change %u\n", value);
}
void engine_aftertouch(struct engine_t *engine, uint8_t value)
{
// printf("Aftertouch %u\n", value);
engine->aftertouch.value = value / 127.0;
}
void engine_pitchchange(struct engine_t *engine, int16_t value)
{
printf("Pitch %d\n", value);
engine->pitchbend.value = value;
}

View File

@ -4,11 +4,28 @@
struct engine_t struct engine_t
{ {
struct control_t lowpass;
struct control_t modwheel;
struct control_t pitchbend;
struct control_t aftertouch;
struct control_t osc_shape[4];
struct control_t osc_level[4];
int monosynth;
struct osc_t osc[NUM_LFO]; struct osc_t osc[NUM_LFO];
struct voice_t voice[NUM_POLYPHONY]; struct voice_t voice[NUM_POLYPHONY];
}; };
extern struct engine_t _engine;
void engine_init(); void engine_init();
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);
void engine_startvoice(struct engine_t *engine, uint8_t note, uint8_t velocity); 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); void engine_endvoice(struct engine_t *engine, uint8_t note, uint8_t velocity);
void engine_controlchange(struct engine_t *engine, uint8_t controller, uint8_t value);
void engine_programchange(struct engine_t *engine, uint8_t value);
void engine_aftertouch(struct engine_t *engine, uint8_t value);
void engine_pitchchange(struct engine_t *engine, int16_t value);

View File

@ -1,15 +1,18 @@
#include <string.h>
#include <math.h> #include <math.h>
#include "filter.h" #include "filter.h"
#include "psyn.h" #include "psyn.h"
void filter_init_rc(struct filter_t *filter, double R, double C) void filter_init_rc(struct filter_t *filter, double R, double C)
{ {
memset(filter, 0, sizeof *filter);
filter->k = 1.0 / (R * C) / _sample_rate; filter->k = 1.0 / (R * C) / _sample_rate;
filter->r = 1.0; filter->r = 1.0;
} }
void filter_init_freq(struct filter_t *filter, double freq) void filter_init_freq(struct filter_t *filter, double freq)
{ {
memset(filter, 0, sizeof *filter);
filter->k = (2.0 * M_PI * freq) / _sample_rate; filter->k = (2.0 * M_PI * freq) / _sample_rate;
filter->r = 1.0; filter->r = 1.0;
} }
@ -31,3 +34,52 @@ void filter_run_hp(struct filter_t *filter, double left, double right)
filter->last_in_l = left; filter->last_in_l = left;
filter->last_in_r = right; filter->last_in_r = right;
} }
void bw_filter_init_lp(struct bw_filter_t *f, double freq, double resonance)
{
double c = 1.0 / tan(M_PI * freq / _sample_rate);
f->a1 = 1.0 / (1.0 + resonance * c + c * c);
f->a2 = 2 * f->a1;
f->a3 = f->a1;
f->b1 = 2.0 * (1.0 - c * c) * f->a1;
f->b2 = (1.0 - resonance * c + c * c) * f->a1;
}
void bw_filter_run(struct bw_filter_t *f, double in_l, double in_r, double *out_l, double *out_r)
{
*out_l = f->a1 * in_l + f->a2 * f->in1_l + f->a3 * f->in2_l - f->b1 * f->out1_l - f->b2 * f->out2_l;
*out_r = f->a1 * in_r + f->a2 * f->in1_r + f->a3 * f->in2_r - f->b1 * f->out1_r - f->b2 * f->out2_r;
f->in2_l = f->in1_l;
f->in1_l = in_l;
f->out2_l = f->out1_l;
f->out1_l = *out_l;
f->in2_r = f->in1_r;
f->in1_r = in_r;
f->out2_r = f->out1_r;
f->out1_r = *out_r;
}
/*
The filter algo:
out(n) = a1 * in + a2 * in(n-1) + a3 * in(n-2) - b1*out(n-1) - b2*out(n-2)
Lowpass:
c = 1.0 / tan(pi * f / sample_rate);
a1 = 1.0 / ( 1.0 + r * c + c * c);
a2 = 2* a1;
a3 = a1;
b1 = 2.0 * ( 1.0 - c*c) * a1;
b2 = ( 1.0 - r * c + c * c) * a1;
Hipass:
c = tan(pi * f / sample_rate);
a1 = 1.0 / ( 1.0 + r * c + c * c);
a2 = -2*a1;
a3 = a1;
b1 = 2.0 * ( c*c - 1.0) * a1;
b2 = ( 1.0 - r * c + c * c) * a1;
*/

View File

@ -1,5 +1,6 @@
struct filter_t { struct filter_t
{
double k; double k;
double r; double r;
double v_l; double v_l;
@ -10,7 +11,22 @@ struct filter_t {
double last_out_r; double last_out_r;
}; };
struct bw_filter_t
{
double a1;
double a2;
double a3;
double b1;
double b2;
double in1_l, in2_l, out1_l, out2_l;
double in1_r, in2_r, out1_r, out2_r;
};
void filter_init_rc(struct filter_t *filter, double R, double C); void filter_init_rc(struct filter_t *filter, double R, double C);
void filter_init_freq(struct filter_t *filter, double freq); void filter_init_freq(struct filter_t *filter, double freq);
void filter_run_lp(struct filter_t *filter, double left, double right); void filter_run_lp(struct filter_t *filter, double left, double right);
void filter_run_hp(struct filter_t *filter, double left, double right); void filter_run_hp(struct filter_t *filter, double left, double right);
void bw_filter_init_lp(struct bw_filter_t *f, double freq, double resonance);
void bw_filter_run(struct bw_filter_t *f, double in_l, double in_r, double *out_l, double *out_r);

33
osc.c
View File

@ -3,24 +3,33 @@
#include "psyn.h" #include "psyn.h"
#include "osc.h" #include "osc.h"
double _sin_table[LOOKUP_SAMPLES + 1]; double _lookup_table[6][LOOKUP_SAMPLES + 1];
double _saw_table[LOOKUP_SAMPLES + 1];
double _tri_table[LOOKUP_SAMPLES + 1];
void osc_init() void osc_init()
{ {
int i; int i;
for (i = 0; i <= LOOKUP_SAMPLES; i++) { for (i = 0; i <= LOOKUP_SAMPLES; i++) {
_sin_table[i] = sin(2 * M_PI * (double)i / LOOKUP_SAMPLES); double ph = (double)i / LOOKUP_SAMPLES;
}
for (i = 0; i <= LOOKUP_SAMPLES; i++) { _lookup_table[0][i] = sin(2.0 * M_PI * ph);
_saw_table[i] = 1.0 - ((double)i / (LOOKUP_SAMPLES / 2));
} _lookup_table[1][i] = -1.0 + ph * 2.0;
for (i = 0; i <= LOOKUP_SAMPLES; i++) {
_tri_table[i] = (double)i / (LOOKUP_SAMPLES / 4); if (ph <= 0.25) _lookup_table[2][i] = ph * 4.0;
if (_tri_table[i] > 1.0) _tri_table[i] = 2.0 - _tri_table[i]; else if (ph <= 0.75) _lookup_table[2][i] = 2.0 - ph * 4.0;
if (_tri_table[i] < -1.0) _tri_table[i] = -2.0 - _tri_table[i]; else _lookup_table[2][i] = ph * 4.0 - 4.0;
//if (_tri_table[i] > 1.0) _tri_table[i] = 2.0 - _tri_table[i];
//if (_tri_table[i] < -1.0) _tri_table[i] = -2.0 - _tri_table[i];
_lookup_table[3][i] = (ph >= 0.5) ? -1.0 : 1.0;
if (ph < 0.5) _lookup_table[4][i] = -1.0 + ph * 4.0;
else _lookup_table[4][i] = 1.0 - 2.0 * ph;
if (ph > 0.5) _lookup_table[5][i] = 1.0 - ph;
else _lookup_table[5][i] = -1.0 + 8.0 * ph * ph;
} }
} }

40
osc.h
View File

@ -1,32 +1,50 @@
#define LOOKUP_SAMPLES 360 #define LOOKUP_SAMPLES 3600
extern double _sin_table[LOOKUP_SAMPLES + 1]; extern double _lookup_table[6][LOOKUP_SAMPLES + 1];
extern double _saw_table[LOOKUP_SAMPLES + 1];
extern double _tri_table[LOOKUP_SAMPLES + 1];
struct osc_t struct osc_t
{ {
double freq; double freq;
double step; double step;
double ramp; double ramp;
double level;
double sin; uint8_t shape;
double saw;
double tri;
}; };
void osc_init(); void osc_init();
void osc_setfreq(struct osc_t *osc, double freq); void osc_setfreq(struct osc_t *osc, double freq);
static inline void osc_setphase(struct osc_t *osc, double phase)
{
osc->ramp = LOOKUP_SAMPLES * phase;
}
static inline void osc_tick(struct osc_t *osc) static inline void osc_tick(struct osc_t *osc)
{ {
osc->ramp += osc->step; osc->ramp += osc->step;
if (osc->ramp > LOOKUP_SAMPLES) osc->ramp -= LOOKUP_SAMPLES; if (osc->ramp > LOOKUP_SAMPLES) osc->ramp -= LOOKUP_SAMPLES;
uint32_t pos = floor(osc->ramp); //uint32_t pos = floor(osc->ramp);
osc->sin = _sin_table[pos]; //osc->sin = _sin_table[pos];
osc->saw = _saw_table[pos]; //osc->saw = _saw_table[pos];
osc->tri = _tri_table[pos]; //osc->tri = _tri_table[pos];
}
static inline double osc_getsample(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)
{
double sample = osc->ramp + phase * LOOKUP_SAMPLES;
if (sample < 0.0) sample += LOOKUP_SAMPLES;
else if (sample > LOOKUP_SAMPLES) sample -= LOOKUP_SAMPLES;
uint32_t pos = sample;
return _lookup_table[osc->shape][pos] * osc->level;
} }

55
psyn.c
View File

@ -8,6 +8,7 @@
#include "osc.h" #include "osc.h"
#include "filter.h" #include "filter.h"
#include "voice.h" #include "voice.h"
#include "control.h"
#include "engine.h" #include "engine.h"
#include "psyn.h" #include "psyn.h"
@ -20,8 +21,10 @@ struct psyn_t
int midi_event_id; int midi_event_id;
float *out_l; float *out_l;
float *out_r; float *out_r;
float *ctrlMono;
struct engine_t eng; float *ctrlLP;
float *ctrlOscShape[4];
float *ctrlOscLevel[4];
}; };
static void psyn_init(struct psyn_t *psyn, uint32_t sample_rate) static void psyn_init(struct psyn_t *psyn, uint32_t sample_rate)
@ -78,6 +81,18 @@ static void connect_port(LV2_Handle lv2instance, uint32_t port, void *data)
case 2: case 2:
psyn->out_r = data; psyn->out_r = data;
break; break;
case 3:
psyn->ctrlMono = data;
break;
case 4:
psyn->ctrlLP = data;
break;
case 5: case 6: case 7: case 8:
psyn->ctrlOscShape[port - 5] = data;
break;
case 9: case 10: case 11: case 12:
psyn->ctrlOscLevel[port - 9] = data;
break;
} }
} }
@ -89,6 +104,7 @@ static void cleanup(LV2_Handle lv2instance)
static void run(LV2_Handle lv2instance, uint32_t sample_count) static void run(LV2_Handle lv2instance, uint32_t sample_count)
{ {
uint8_t i;
struct psyn_t *psyn = (struct psyn_t *)lv2instance; struct psyn_t *psyn = (struct psyn_t *)lv2instance;
uint32_t frame = 0; uint32_t frame = 0;
LV2_Event *ev = NULL; LV2_Event *ev = NULL;
@ -98,6 +114,13 @@ static void run(LV2_Handle lv2instance, uint32_t sample_count)
if (lv2_event_is_valid(&iterator)) ev = lv2_event_get(&iterator, NULL); 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;
for (i = 0; i < 4; i++) {
_engine.osc_shape[i].value = *psyn->ctrlOscShape[i];
_engine.osc_level[i].value = *psyn->ctrlOscLevel[i];
}
while (frame < sample_count) { while (frame < sample_count) {
uint32_t to; uint32_t to;
@ -107,22 +130,42 @@ static void run(LV2_Handle lv2instance, uint32_t sample_count)
to = sample_count; to = sample_count;
} }
engine_run(&psyn->eng, 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; frame = to;
if (ev != NULL) { if (ev != NULL) {
if (ev->type == 0) { if (ev->type == 0) {
psyn->event_ref->lv2_event_unref(psyn->event_ref->callback_data, ev); psyn->event_ref->lv2_event_unref(psyn->event_ref->callback_data, ev);
} else if (ev->type == psyn->midi_event_id && ev->size == 3) { } else if (ev->type == psyn->midi_event_id) {
uint8_t *data = (uint8_t *)(ev + 1); uint8_t *data = (uint8_t *)(ev + 1);
switch (data[0] & 0xF0) { switch (data[0] & 0xF0) {
case 0x80: case 0x80:
engine_endvoice(&psyn->eng, data[1], data[2]); engine_endvoice(&_engine, data[1], data[2]);
break; break;
case 0x90: case 0x90:
engine_startvoice(&psyn->eng, data[1], data[2]); engine_startvoice(&_engine, data[1], data[2]);
break;
case 0xA0:
engine_aftertouch(&_engine, data[2]);
break;
case 0xC0:
engine_programchange(&_engine, data[1]);
break;
case 0xB0:
engine_controlchange(&_engine, data[1], data[2]);
break;
case 0xD0:
engine_aftertouch(&_engine, data[1]);
break;
case 0xE0:
engine_pitchchange(&_engine, (data[1] | data[2] << 7) - 0x2000);
break; break;
} }
} }

View File

@ -34,4 +34,94 @@
lv2:index 2; lv2:index 2;
lv2:symbol "out R"; lv2:symbol "out R";
lv2:name "Audio Output R"; lv2:name "Audio Output R";
],
[
a lv2:InputPort, lv2:ControlPort;
lv2:index 3;
lv2:symbol "mono";
lv2:name "Mono mode";
lv2:minimum 0;
lv2:default 0;
lv2:maximum 2;
],
[
a lv2:InputPort, lv2:ControlPort;
lv2:index 4;
lv2:symbol "lp_freq";
lv2:name "Low Pass Filter Frequency";
lv2:minimum 1.0;
lv2:default 2000.0;
lv2:maximum 16000.0;
],
[
a lv2:InputPort, lv2:ControlPort;
lv2:index 5;
lv2:symbol "oscshape0";
lv2:name "Oscillator 0 shape";
lv2:minimum 0;
lv2:default 0;
lv2:maximum 5;
],
[
a lv2:InputPort, lv2:ControlPort;
lv2:index 6;
lv2:symbol "oscshape1";
lv2:name "Oscillator 1 shape";
lv2:minimum 0;
lv2:default 0;
lv2:maximum 5;
],
[
a lv2:InputPort, lv2:ControlPort;
lv2:index 7;
lv2:symbol "oscshape2";
lv2:name "Oscillator 2 shape";
lv2:minimum 0;
lv2:default 0;
lv2:maximum 5;
],
[
a lv2:InputPort, lv2:ControlPort;
lv2:index 8;
lv2:symbol "oscshape3";
lv2:name "Oscillator 3 shape";
lv2:minimum 0;
lv2:default 0;
lv2:maximum 5;
],
[
a lv2:InputPort, lv2:ControlPort;
lv2:index 9;
lv2:symbol "osclevel0";
lv2:name "Oscillator 0 level";
lv2:minimum 0;
lv2:default 1;
lv2:maximum 1;
],
[
a lv2:InputPort, lv2:ControlPort;
lv2:index 10;
lv2:symbol "osclevel1";
lv2:name "Oscillator 1 level";
lv2:minimum 0;
lv2:default 0;
lv2:maximum 1;
],
[
a lv2:InputPort, lv2:ControlPort;
lv2:index 11;
lv2:symbol "osclevel2";
lv2:name "Oscillator 2 level";
lv2:minimum 0;
lv2:default 0;
lv2:maximum 1;
],
[
a lv2:InputPort, lv2:ControlPort;
lv2:index 12;
lv2:symbol "osclevel3";
lv2:name "Oscillator 3 level";
lv2:minimum 0;
lv2:default 0;
lv2:maximum 1;
]. ].

77
voice.c
View File

@ -6,19 +6,39 @@
#include "env.h" #include "env.h"
#include "filter.h" #include "filter.h"
#include "voice.h" #include "voice.h"
#include "control.h"
#include "engine.h"
#include "psyn.h" #include "psyn.h"
#include "rng.h" #include "rng.h"
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, double freq)
{ {
uint8_t i;
// filter_init_rc(&voice->fil[0], 1000.0, 0.000000047); // filter_init_rc(&voice->fil[0], 1000.0, 0.000000047);
// filter_init_rc(&voice->fil[1], 47000.0, 0.000000047); // filter_init_rc(&voice->fil[1], 47000.0, 0.000000047);
filter_init_freq(&voice->fil[0], 2000.0); // filter_init_freq(&voice->fil[0], freq);
filter_init_freq(&voice->fil[1], 150.0); // filter_init_freq(&voice->fil[1], 150.0);
// bw_filter_init_lp(&voice->bw[0], _engine.lowpass.value, 1.0);
for (i = 0; i < VOICE_OSCILLATORS; i++) {
voice->osc[i].shape = _engine.osc_shape[i].value;
voice->osc[i].level = _engine.osc_level[i].value;
}
osc_setfreq(&voice->osc[0], freq); osc_setfreq(&voice->osc[0], freq);
osc_setfreq(&voice->osc[1], freq * 1.2); osc_setphase(&voice->osc[0], 0.0);
osc_setfreq(&voice->osc[2], freq * 5); 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)
@ -50,22 +70,53 @@ void voice_run(struct voice_t *voice, uint32_t samples, float *left, float *righ
amplitude *= voice->velocity; amplitude *= voice->velocity;
l = amplitude * voice->osc[0].sin * (1.0 + rng() * 0.25); float s;
r = amplitude * voice->osc[0].sin * (1.0 + rng() * 0.25);
s = osc_getsample(&voice->osc[0]);
l = amplitude * s;// * (1.0 + rng() * 0.25);
r = amplitude * s;// * (1.0 + rng() * 0.25);
amplitude = env_getamplitude(&_env2, voice->sample, voice->released) * voice->velocity * voice->velocity * 1.5; s = osc_getsample(&voice->osc[1]);
l += amplitude * s;
r += amplitude * s;
if (amplitude > 0.0) { s = osc_getsample(&voice->osc[2]);
l += amplitude * voice->osc[1].tri * (1.0 + voice->osc[2].sin * 0.25); l += amplitude * s;
r += amplitude * voice->osc[1].tri * (1.0 + voice->osc[2].sin * 0.25); r += amplitude * s;
}
*left += l; s = osc_getsample(&_engine.osc[0]);
*right += r; // Amplitude mod
// l *= 1.0 + s;
// r *= 1.0 + s;
// l = s * (1.0 + l);
// r = s * (1.0 + r);
// Ring mod
// l *= s;
// r *= s;
// amplitude = env_getamplitude(&_env2, voice->sample, voice->released) * voice->velocity * voice->velocity * 1.5;
// if (amplitude > 0.0) {
// float s1 = osc_getsample(&voice->osc[1]);
// float s2 = osc_getsample(&voice->osc[2]);
// l += amplitude * s1 * (1.0 + s2 * 0.25);
// r += amplitude * s1 * (1.0 + s2 * 0.25);
// }
// *left += l;
// *right += r;
double out_l, out_r;
double cutoff = max(env_getamplitude(&_env2, 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_lp(&voice->fil[0], l, r);
// filter_run_hp(&voice->fil[1], voice->fil[0].last_out_l, voice->fil[0].last_out_r); // filter_run_hp(&voice->fil[1], voice->fil[0].last_out_l, voice->fil[0].last_out_r);
*left += out_l;
*right += out_r;
// *left += voice->fil[0].last_out_l; // *left += voice->fil[0].last_out_l;
// *right += voice->fil[0].last_out_r; // *right += voice->fil[0].last_out_r;
// } // }

View File

@ -11,7 +11,8 @@ struct voice_t
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];
struct bw_filter_t bw[VOICE_FILTERS];
}; };
void voice_init(struct voice_t *voice, double freq); void voice_init(struct voice_t *voice, double freq);