Files
2026-10-27 22:10:43 +01:00

35 lines
1.4 KiB
C

#include "synth.h"
#include <math.h>
#define SAMPLE_RATE 44100.0f
void play_note(Note *note, int16_t *buffer, int buffer_size) {
for (int i = 0; i < buffer_size; i++) {
// update phase counter
note->phase = fmodf(note->phase + note->freq / SAMPLE_RATE, 1.0f);
// oscillator
float sample = 0.0f;
switch (note->form) {
case WAVE_SINE: sample = sinf(2.0f * (float) M_PI * note->phase); break;
case WAVE_SAW: sample = 2.0f * note->phase - 1.0f; break;
case WAVE_SQUARE: sample = note->phase < 0.5f ? 1.0f : -1.0f; break;
case WAVE_TRIANGLE: sample = 4.0f * fabsf(note->phase - 0.5f) - 1.0f; break;
default: break;
}
//note->lp += note->filter_cutoff * (sample - note->lp);
//sample = note->lp;
// basic attack / release
// convert attack / release time to a number of steps to reach target gain
float attack_step = 0.2f / ((note->attack_ms / 1000.0f) * SAMPLE_RATE);
float release_step = 0.2f / ((note->release_ms / 1000.0f) * SAMPLE_RATE);
note->gain = note->is_playing
? fminf(note->gain + attack_step, 0.2f) // attack
: fmaxf(note->gain - release_step, 0); // release
// convert sample to 16-bit signed integer and apply gain
buffer[i] = (int16_t) (note->gain * sample * (float) INT16_MAX);
}
}