From 706f6b01c0f5e44c18171b0c803ca5bbffcdb652 Mon Sep 17 00:00:00 2001 From: spl3g Date: Sun, 28 Sep 2025 17:57:42 +0300 Subject: Revamp the architecture --- src/main.c | 185 ++++++++++++++++++++----------------------------------------- 1 file changed, 60 insertions(+), 125 deletions(-) (limited to 'src/main.c') diff --git a/src/main.c b/src/main.c index 553ee89..f8972c1 100644 --- a/src/main.c +++ b/src/main.c @@ -1,119 +1,10 @@ #include +#include "sounds.h" #include -#include #include #include #include -#define SAMPLE_RATE 48000 -#define PERIOD_SIZE 480 -#define AMPLITUDE 10000 - -#define check(ret) \ - do { \ - int res = (ret); \ - if (res < 0) { \ - fprintf(stderr, "%s:%d ERROR: %s (%d)\n", \ - __FILE__, __LINE__, snd_strerror(res), res); \ - exit(1); \ - } \ - } while (0) - -typedef struct { - snd_pcm_t * pcm; - float *freqs; - size_t freqs_count; - bool should_stop; -} sound_thread_meta; - -int set_hw_params(snd_pcm_t *pcm) { - snd_pcm_hw_params_t *hw_params; - - snd_pcm_hw_params_alloca(&hw_params); - - check(snd_pcm_hw_params_any(pcm, hw_params)); - - unsigned int resample = 1; - check(snd_pcm_hw_params_set_rate_resample(pcm, hw_params, resample)); - check(snd_pcm_hw_params_set_access(pcm, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)); - check(snd_pcm_hw_params_set_format(pcm, hw_params, SND_PCM_FORMAT_S16_LE)); - check(snd_pcm_hw_params_set_channels(pcm, hw_params, 1)); - check(snd_pcm_hw_params_set_rate(pcm, hw_params, SAMPLE_RATE, 0)); - snd_pcm_uframes_t period_size = PERIOD_SIZE; - check(snd_pcm_hw_params_set_period_size_near(pcm, hw_params, &period_size, 0)); - snd_pcm_uframes_t buffer_size = period_size * 3; - check(snd_pcm_hw_params_set_buffer_size_near(pcm, hw_params, &buffer_size)); - check(snd_pcm_hw_params(pcm, hw_params)); - - return 0; -} - -short *gen_sine(short *buffer, size_t sample_count, float freq, float *phase) { - for (size_t i = 0; i < sample_count; i++) { - buffer[i] = AMPLITUDE * sinf(*phase); - *phase += 2 * M_PI * freq / SAMPLE_RATE; - if (*phase >= 2 * M_PI) *phase -= 2 * M_PI; - } - - return buffer; -} - -short *gen_square(short *buffer, size_t sample_count, float freq, float *phase) { - int samples_full_cycle = (float)SAMPLE_RATE / freq; - int samples_half_cycle = samples_full_cycle / 2.0f; - for (size_t i = 0; i < sample_count; i++) { - buffer[i] = *phase < samples_half_cycle ? AMPLITUDE : -AMPLITUDE; - *phase = (((int)*phase + 1) % samples_full_cycle); - } - return buffer; -} - -short *gen_saw(short *buffer, size_t sample_count, float freq, float *phase) { - int samples_full_cycle = (float)SAMPLE_RATE / freq; - int step = AMPLITUDE / samples_full_cycle; - - for (size_t i = 0; i < sample_count; i++) { - buffer[i] = *phase; - - *phase += step; - if (*phase >= AMPLITUDE) { - *phase = -AMPLITUDE; - } - } - - return buffer; -} - -void *sound_thread_generate(void *ptr) { - sound_thread_meta *meta = ptr; - - short buffer[PERIOD_SIZE]; - float phase = 0.0f; - - float prev_freq = meta->freqs[0]; - - while (!meta->should_stop) { - if (meta->freqs_count <= 0) { - continue; - } - - float freq = meta->freqs[0]; - if (freq != prev_freq) { - printf("%f\n", freq); - prev_freq = freq; - } - - gen_saw(buffer, PERIOD_SIZE, freq, &phase); - - snd_pcm_sframes_t written = snd_pcm_writei(meta->pcm, buffer, PERIOD_SIZE); - if (written < 0) { - snd_pcm_prepare(meta->pcm); // recover from xrun - } - } - - return NULL; -} - typedef struct { char key; float freq; @@ -139,25 +30,70 @@ int main() { InitWindow(800, 800, "crynth"); SetTargetFPS(60); - float freqs[10]; - - freqs[0] = 220; + message_queue queue; + mqueue_init(&queue); - sound_thread_meta soundgen = { + sound_thread_meta sound_thread_params = { .pcm = sound_device, - .freqs = freqs, - .freqs_count = 1, - .should_stop = false, + .queue = &queue, }; pthread_t sound_thread; - pthread_create(&sound_thread, NULL, sound_thread_generate, &soundgen); + pthread_create(&sound_thread, NULL, sound_thread_start, &sound_thread_params); + + /* synth_message param_message = { */ + /* .type = MSG_PARAM_CHANGE, */ + /* .param_change = { */ + /* .param_type = PARAM_OSC, */ + /* .value = OSC_SINE, */ + /* }, */ + /* }; */ + /* mqueue_push(&queue, param_message); */ + /* param_message = (synth_message){ */ + /* .type = MSG_PARAM_CHANGE, */ + /* .param_change = { */ + /* .param_type = PARAM_VOLUME, */ + /* .value = 0.2, */ + /* }, */ + /* }; */ + /* mqueue_push(&queue, param_message); */ + + int keys[12] = { + KEY_Z, + KEY_S, + KEY_X, + KEY_D, + KEY_C, + KEY_V, + KEY_G, + KEY_B, + KEY_H, + KEY_N, + KEY_J, + KEY_M, + }; while (!WindowShouldClose()) { - if (IsKeyDown(KEY_SPACE)) { - soundgen.freqs[0] = 900; - } else { - soundgen.freqs[0] = 500; + for (int i = 0; i < 12; i++) { + if (IsKeyPressed(keys[i])) { + synth_message message = { + .type = MSG_NOTE_ON, + .note = { + .note_id = i, + }, + }; + mqueue_push(&queue, message); + } + + if (IsKeyReleased(keys[i])) { + synth_message message = { + .type = MSG_NOTE_OFF, + .note = { + .note_id = i, + }, + }; + mqueue_push(&queue, message); + } } BeginDrawing(); @@ -165,12 +101,11 @@ int main() { EndDrawing(); } - soundgen.should_stop = true; + synth_message stop_msg = {.type = MSG_STOP}; + mqueue_push(&queue, stop_msg); CloseWindow(); pthread_join(sound_thread, NULL); - - check(snd_pcm_drop(sound_device)); check(snd_pcm_close(sound_device)); return 0; -- cgit v1.2.3