57 lines
1.9 KiB
C
57 lines
1.9 KiB
C
#if defined(STFU_MAIN) && !defined(STFU_TROJKA)
|
|
#define STFU_TROJKA
|
|
|
|
#include "../../phaser.c"
|
|
#include "../../envelope.c"
|
|
#include "../../config.h"
|
|
|
|
#define STFU_TROJKA_OP_COUNT 3
|
|
|
|
/* https://multimed.org/student/eim/en/04-FM.pdf */
|
|
|
|
// todo: A few more algorithm configurations.
|
|
// todo: Other oscillators.
|
|
|
|
struct stfu_trojka {
|
|
struct stfu_phaser phasers[STFU_TROJKA_OP_COUNT];
|
|
struct stfu_envelope envelopes[STFU_TROJKA_OP_COUNT];
|
|
float gains[STFU_TROJKA_OP_COUNT];
|
|
float freq_scales[STFU_TROJKA_OP_COUNT];
|
|
float key_frequency;
|
|
float feedback_gain; // todo: Separate gain for channels?
|
|
float left_feedback, right_feedback;
|
|
};
|
|
|
|
static struct stfu_trojka stfu_sample_trojka(struct stfu_trojka synth, float buffer[static 2]) {
|
|
for (int i = 0; i < STFU_TROJKA_OP_COUNT; ++i) {
|
|
synth.phasers[i] = stfu_pump_phaser(synth.phasers[i]);
|
|
synth.envelopes[i] = stfu_pump_envelope(synth.envelopes[i]);
|
|
}
|
|
|
|
float left_modulator_stack = synth.envelopes[1].v * sinf(synth.phasers[1].v + synth.envelopes[0].v * sinf(synth.phasers[0].v)) + synth.left_feedback * synth.feedback_gain;
|
|
float right_modulator_stack = synth.envelopes[1].v * sinf(synth.phasers[1].v + synth.envelopes[0].v * sinf(synth.phasers[0].v)) + synth.right_feedback * synth.feedback_gain;
|
|
|
|
synth.left_feedback = left_modulator_stack;
|
|
synth.right_feedback = right_modulator_stack;
|
|
|
|
float left = synth.envelopes[2].v * sinf(synth.phasers[2].v + left_modulator_stack);
|
|
float right =
|
|
synth.envelopes[2].v * sinf(synth.phasers[2].v + right_modulator_stack);
|
|
|
|
buffer[0] = left;
|
|
buffer[1] = right;
|
|
|
|
return synth;
|
|
}
|
|
|
|
static struct stfu_trojka stfu_press_trojka(struct stfu_trojka synth, float key_frequency) {
|
|
for (int i = 0; i < STFU_TROJKA_OP_COUNT; ++i) {
|
|
synth.phasers[i] = stfu_set_phaser_frequency(synth.phasers[i], key_frequency * synth.freq_scales[i]);
|
|
synth.envelopes[i] = stfu_trigger_envelope(synth.envelopes[i]);
|
|
}
|
|
|
|
return synth;
|
|
}
|
|
|
|
#endif
|