#include #include #include #include "osc.h" #include "env.h" #include "filter.h" #include "control.h" #include "voice.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, const struct engine_t *engine, 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->params[i].shape.value; voice->osc[i].level = engine->params[i].level.value; osc_setfreq(&voice->osc[i], freq * engine->params[i].freq_mult.value); osc_setphase(&voice->osc[i], engine->params[i].phase.value); } } 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, const struct engine_t *engine, uint32_t samples, float *left, float *right) { // uint32_t pos; int i; double a[VOICE_OSCILLATORS]; double l = 0.0; double r = 0.0; //for (pos = 0; pos < samples; pos++) { voice_tick(voice); 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) { voice->playing = false; return; } for (i = 0; i < VOICE_OSCILLATORS; i++) { const struct voice_param_t *params = &engine->params[i]; float ss; float pl = osc_getsample(&voice->osc[i]); float pr = pl; // Mix switch (params->pan_type) { case PAN_FIXED: pl *= params->pan_level; pr *= params->pan_level_r; break; case PAN_OSC: ss = osc_getsample(&voice->osc[params->pan_source]) * params->pan_level * 0.5; pl *= 0.5 + ss; pr *= 0.5 - ss; break; case PAN_LFO: ss = osc_getsample(&engine->lfo[params->pan_source]) * params->pan_level * 0.5; pl *= 0.5 + ss; pr *= 0.5 - ss; break; } l += a[i] * pl; r += a[i] * pr; } // 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(&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_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; // } }