full chromatic scale, fix regression of crossfading, second row of keys

This commit is contained in:
veclavtalica
2024-06-24 16:28:19 +03:00
parent 561dece028
commit 1bb675d158
5 changed files with 91 additions and 18 deletions

View File

@ -15,8 +15,9 @@
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 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;
@ -28,8 +29,8 @@ static struct stfu_trojka stfu_sample_trojka(struct stfu_trojka synth, float buf
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;
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;

Binary file not shown.

View File

@ -24,6 +24,9 @@ static float crossfade_ring[CROSSFADE_RING_RANGE] = {0};
static size_t crossfade_ring_needle = 0;
static unsigned int crossfade_frames_left = 0;
// 1.0 is with A at 440
static float octave = 0.5;
static void stream(float *buffer, int num_frames, int num_channels) {
/* Fade away */
for (size_t i = 0; crossfade_frames_left > 0;
@ -53,10 +56,15 @@ static void init(void) {
// .stream_cb = stream,
});
synth.phasers[0] = stfu_init_phaser(220);
synth.phasers[1] = stfu_init_phaser(220 * 0.25);
synth.phasers[2] = stfu_init_phaser(220 * 2.0);
synth.freq_scales[0] = 1.0;
synth.freq_scales[1] = 0.25;
synth.freq_scales[2] = 2.0;
synth.indices[0] = 2.0;
synth.indices[1] = 10.0;
synth.feedback_gain = 0.25;
for (int i = 0; i < STFU_TROJKA_OP_COUNT; ++i) {
synth.envelopes[i] = stfu_init_envelope(
(struct stfu_envelope_point[]){[0] = {.dur = 0.02, .vol = 1.0},
@ -64,7 +72,6 @@ static void init(void) {
[2] = {.dur = 1.0, .vol = 0}},
3);
synth.gains[i] = 1.0;
synth.freq_scales[i] = 1.0;
}
}
@ -76,40 +83,103 @@ static void event(const sapp_event *e) {
if (e->key_repeat)
break;
bool key_was_pressed = false;
switch (e->key_code) {
case SAPP_KEYCODE_Z:
synth = stfu_press_trojka(synth, STFU_SCALE[0]);
key_was_pressed = true;
synth = stfu_press_trojka(synth, STFU_SCALE[0] * octave);
break;
case SAPP_KEYCODE_X:
synth = stfu_press_trojka(synth, STFU_SCALE[1]);
key_was_pressed = true;
synth = stfu_press_trojka(synth, STFU_SCALE[1] * octave);
break;
case SAPP_KEYCODE_C:
synth = stfu_press_trojka(synth, STFU_SCALE[2]);
key_was_pressed = true;
synth = stfu_press_trojka(synth, STFU_SCALE[2] * octave);
break;
case SAPP_KEYCODE_V:
synth = stfu_press_trojka(synth, STFU_SCALE[3]);
key_was_pressed = true;
synth = stfu_press_trojka(synth, STFU_SCALE[3] * octave);
break;
case SAPP_KEYCODE_B:
synth = stfu_press_trojka(synth, STFU_SCALE[4]);
key_was_pressed = true;
synth = stfu_press_trojka(synth, STFU_SCALE[4] * octave);
break;
case SAPP_KEYCODE_N:
synth = stfu_press_trojka(synth, STFU_SCALE[5]);
key_was_pressed = true;
synth = stfu_press_trojka(synth, STFU_SCALE[5] * octave);
break;
case SAPP_KEYCODE_M:
synth = stfu_press_trojka(synth, STFU_SCALE[6]);
key_was_pressed = true;
synth = stfu_press_trojka(synth, STFU_SCALE[6] * octave);
break;
case SAPP_KEYCODE_COMMA:
synth = stfu_press_trojka(synth, STFU_SCALE[7]);
key_was_pressed = true;
synth = stfu_press_trojka(synth, STFU_SCALE[7] * octave);
break;
case SAPP_KEYCODE_PERIOD:
synth = stfu_press_trojka(synth, STFU_SCALE[8]);
key_was_pressed = true;
synth = stfu_press_trojka(synth, STFU_SCALE[8] * octave);
break;
case SAPP_KEYCODE_SLASH:
synth = stfu_press_trojka(synth, STFU_SCALE[9]);
key_was_pressed = true;
synth = stfu_press_trojka(synth, STFU_SCALE[9] * octave);
break;
case SAPP_KEYCODE_A:
key_was_pressed = true;
synth = stfu_press_trojka(synth, STFU_SCALE[0] * (octave * 2));
break;
case SAPP_KEYCODE_S:
key_was_pressed = true;
synth = stfu_press_trojka(synth, STFU_SCALE[1] * (octave * 2));
break;
case SAPP_KEYCODE_D:
key_was_pressed = true;
synth = stfu_press_trojka(synth, STFU_SCALE[2] * (octave * 2));
break;
case SAPP_KEYCODE_F:
key_was_pressed = true;
synth = stfu_press_trojka(synth, STFU_SCALE[3] * (octave * 2));
break;
case SAPP_KEYCODE_G:
key_was_pressed = true;
synth = stfu_press_trojka(synth, STFU_SCALE[4] * (octave * 2));
break;
case SAPP_KEYCODE_H:
key_was_pressed = true;
synth = stfu_press_trojka(synth, STFU_SCALE[5] * (octave * 2));
break;
case SAPP_KEYCODE_J:
key_was_pressed = true;
synth = stfu_press_trojka(synth, STFU_SCALE[6] * (octave * 2));
break;
case SAPP_KEYCODE_K:
key_was_pressed = true;
synth = stfu_press_trojka(synth, STFU_SCALE[7] * (octave * 2));
break;
case SAPP_KEYCODE_L:
key_was_pressed = true;
synth = stfu_press_trojka(synth, STFU_SCALE[8] * (octave * 2));
break;
case SAPP_KEYCODE_SEMICOLON:
key_was_pressed = true;
synth = stfu_press_trojka(synth, STFU_SCALE[9] * (octave * 2));
break;
case SAPP_KEYCODE_APOSTROPHE:
key_was_pressed = true;
synth = stfu_press_trojka(synth, STFU_SCALE[10] * (octave * 2));
break;
default:
break;
}
if (key_was_pressed) {
crossfade_frames_left = STFU_CROSSFADE_BUFFER_FRAMES;
}
break;
}
default:

View File

@ -33,6 +33,8 @@ static const float STFU_SCALE[12] = {
STFU_NOTE_DOWNSCALE_FACTOR,
STFU_A4_FREQUENCY * STFU_NOTE_DOWNSCALE_FACTOR,
STFU_A4_FREQUENCY,
STFU_A4_FREQUENCY * STFU_NOTE_UPSCALE_FACTOR,
STFU_A4_FREQUENCY * STFU_NOTE_UPSCALE_FACTOR * STFU_NOTE_UPSCALE_FACTOR,
};
#endif