#include #include #include #include #include "env.h" #include "osc.h" #include "filter.h" #include "control.h" #include "voice.h" #include "engine.h" #include "psyn.h" static double _freqs[128]; struct engine_t _engine; void engine_init() { uint32_t i; for (i = 0; i < 128; i++) { _freqs[i] = 440.0 * pow(2.0, (i - 69.0) / 12.0); } osc_init(); env_init(&_engine.params[0].env, 0.0125, 0.025, 5.0, 0.0, 0.25); env_init(&_engine.params[1].env, 0.0, 0.0, 0.5, 0.0, 0.25); osc_setfreq(&_engine.lfo[0], 10.0); osc_setfreq(&_engine.lfo[1], 2.0); osc_setfreq(&_engine.lfo[2], 1.0); _engine.lfo[0].level = 1.0; _engine.lfo[1].level = 1.0; _engine.lfo[2].level = 1.0; } void engine_run(struct engine_t *engine, uint32_t samples, float *left, float *right) { struct voice_t *v; uint32_t pos; uint32_t i; for (pos = 0; pos < samples; pos++) { control_tick(&_engine.lowpass); left[pos] = 0.0; right[pos] = 0.0; for (i = 0; i < NUM_LFO; i++) { osc_tick(&_engine.lfo[i]); } v = _engine.voice; for (i = 0; i < NUM_POLYPHONY; i++, v++) { if (!v->playing) continue; voice_run(v, 1, left + pos, right + pos); } } } void engine_startvoice(struct engine_t *engine, uint8_t note, uint8_t velocity) { struct voice_t *v = engine->voice; 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++) { if (v->playing) continue; /* Constant voice parameters */ v->playing = true; 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; } } void engine_endvoice(struct engine_t *engine, uint8_t note, uint8_t velocity) { struct voice_t *v = engine->voice; uint32_t i; for (i = 0; i < NUM_POLYPHONY; i++, v++) { if (v->released > 0 || v->note != note) continue; 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; }