#include #include #include #include "osc.h" #include "env.h" #include "filter.h" #include "voice.h" #include "control.h" #include "engine.h" #include "psyn.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) { uint8_t i; // filter_init_rc(&voice->fil[0], 1000.0, 0.000000047); // filter_init_rc(&voice->fil[1], 47000.0, 0.000000047); // filter_init_freq(&voice->fil[0], freq); // 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_setphase(&voice->osc[0], 0.0); 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) { unsigned i; for (i = 0; i < VOICE_OSCILLATORS; i++) { osc_tick(voice->osc + i); } voice->sample++; } 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; float 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 // 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_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; // *right += voice->fil[0].last_out_r; // } }