psyn/voice.c

66 lines
1.4 KiB
C
Raw Normal View History

2010-01-13 10:35:51 +00:00
#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++;
}
2010-01-13 11:37:26 +00:00
static double _R = 4700.0;
static double _C = 0.000000047;
2010-01-13 10:35:51 +00:00
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) {
2010-01-13 11:37:26 +00:00
l += amplitude * voice->osc[1].tri * (1.0 + voice->osc[2].sin * 0.25);
r += amplitude * voice->osc[1].tri * (1.0 + voice->osc[2].sin * 0.25);
2010-01-13 10:35:51 +00:00
}
voice_filter(voice, l, r);
*left += voice->last_l;
*right += voice->last_r;
// }
}