66 lines
1.3 KiB
C
66 lines
1.3 KiB
C
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <math.h>
|
|
#include "osc.h"
|
|
#include "env.h"
|
|
#include "voice.h"
|
|
#include "psyn.h"
|
|
|
|
static inline void voice_tick(struct voice_t *voice)
|
|
{
|
|
unsigned i;
|
|
for (i = 0; i < VOICE_OSCILLATORS; i++) {
|
|
osc_tick(voice->osc + i);
|
|
}
|
|
|
|
voice->sample++;
|
|
}
|
|
|
|
static double _R = 2.7;
|
|
static double _C = 4.3;
|
|
|
|
static inline void voice_filter(struct voice_t *voice, float l, float r)
|
|
{
|
|
double k = 1.0 / (_R * _C) / _sample_rate;
|
|
|
|
voice->last_l += k * (l - voice->last_l);
|
|
voice->last_r += k * (r - voice->last_r);
|
|
}
|
|
|
|
void voice_run(struct voice_t *voice, uint32_t samples, float *left, float *right)
|
|
{
|
|
// uint32_t pos;
|
|
double amplitude;
|
|
double l;
|
|
double r;
|
|
|
|
//for (pos = 0; pos < samples; pos++) {
|
|
voice_tick(voice);
|
|
|
|
amplitude = env_getamplitude(&_env, voice->sample, voice->released);
|
|
|
|
if (amplitude <= 0.0001) {
|
|
voice->playing = false;
|
|
return;
|
|
}
|
|
|
|
amplitude *= voice->velocity;
|
|
|
|
l = amplitude * voice->osc[0].saw;
|
|
r = amplitude * voice->osc[0].saw;
|
|
|
|
amplitude = env_getamplitude(&_env2, voice->sample, voice->released) * voice->velocity * voice->velocity * 1.5;
|
|
|
|
if (amplitude > 0.0) {
|
|
l *= voice->osc[1].tri * (1.0 + voice->osc[2].sin * 0.25);
|
|
r *= voice->osc[1].tri * (1.0 + voice->osc[2].sin * 0.25);
|
|
}
|
|
|
|
voice_filter(voice, l, r);
|
|
|
|
*left += voice->last_l;
|
|
*right += voice->last_r;
|
|
// }
|
|
}
|