#include "synth.h" #include #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); } }