stfu/Source/Instruments/Trojka/trojka.c
2024-06-29 18:15:06 +03:00

66 lines
2.1 KiB
C

#if defined(STFU_MAIN) && !defined(STFU_TROJKA)
#define STFU_TROJKA
#include "../../config.h"
#include "../../envelope.c"
#include "../../phaser.c"
#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]; // todo: Combine with indices?
float freq_scales[STFU_TROJKA_OP_COUNT];
float indices[STFU_TROJKA_OP_COUNT - 1]; /* 1 to 100 */
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 * synth.indices[1] *
sinf(synth.phasers[1].v + synth.envelopes[0].v * synth.indices[0] *
sinf(synth.phasers[0].v)) +
synth.left_feedback * synth.feedback_gain;
float right_modulator_stack = left_modulator_stack;
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