From 359b503ecc7c584bacda044a9cbe3c12f8da839c Mon Sep 17 00:00:00 2001 From: quou Date: Tue, 24 Sep 2024 20:30:27 +1000 Subject: audio --- 1bitjam.c | 4 +++ Makefile | 3 +- config.h | 3 ++ plat.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ plat.h | 4 +++ 5 files changed, 111 insertions(+), 1 deletion(-) diff --git a/1bitjam.c b/1bitjam.c index e811cba..c2a84e1 100644 --- a/1bitjam.c +++ b/1bitjam.c @@ -23,6 +23,7 @@ int entrypoint(int argc, const char** argv, Arena* m) { app_memory_size ); a = new_app(&h, game_name); + init_audio(); init_fps(&f, default_mpf); while (a->o) { fps_begin(&f); @@ -38,6 +39,8 @@ int entrypoint(int argc, const char** argv, Arena* m) { y--; if (a->btn_states[btn_down] & btn_state_pressed) y++; + if (a->btn_states[btn_shoot] & btn_state_just_pressed) + play_sound(30); ren_text(&r, 30, 60, "Hello"); ren_map(&r, 10, 5, &rect, get_bitmap(asset_id_hello_img)); ren_map(&r, x, y, &rect2, get_bitmap(asset_id_guy_img)); @@ -47,6 +50,7 @@ int entrypoint(int argc, const char** argv, Arena* m) { } fps_end(&f); } + deinit_audio(); deinit_app(a); return error_none; } diff --git a/Makefile b/Makefile index bf15054..bc07003 100644 --- a/Makefile +++ b/Makefile @@ -3,8 +3,9 @@ tool_compiler = gcc linker = gcc cflags = -I./ -g -DDEBUG -Dplat_x11 -Dplat_x86 \ -Dplat_posix -Dallocation_default_alignment=8 \ +-Dplat_pulse \ -Wall -Wextra -pedantic -std=c90 -lflags = -lX11 -lXi +lflags = -lX11 -lXi -lpulse -lpulse-simple -lpthread -lm target = 1bitjam int_dir = intermediate data_dir = data diff --git a/config.h b/config.h index 73df5f6..418e7f4 100644 --- a/config.h +++ b/config.h @@ -14,4 +14,7 @@ #define default_scale 3 #define default_mpf 50 +#define audio_buffer_size 64 +#define audio_sample_rate 8000 + #endif diff --git a/plat.c b/plat.c index 2101910..e178137 100644 --- a/plat.c +++ b/plat.c @@ -427,3 +427,101 @@ void app_end(App* a) { } #endif + + +#ifdef plat_pulse +#include "maths.h" +#define inline /* erm sir we are using C90 here... */ +#include +#include +#include +#include + +struct { + short* buf; + pa_simple* dev; + int r, play, time; + pthread_t worker; + pthread_mutex_t mutex; +} audio; + +void* audio_worker(void* arg) { + const int s = audio_buffer_size; + int i, c = 1; + short* buf = audio.buf; + pa_simple* dev = audio.dev; + (void)arg; + while (c) { + pthread_mutex_lock(&audio.mutex); + if (!audio.r) c = 0; + for ( + i = 0; + i < s && audio.play; + i++, audio.play--, audio.time++ + ) buf[i] = (short)(sin((double)audio.time / 0.05) * 16000.0); + pthread_mutex_unlock(&audio.mutex); + for (; i < s; i++) { + buf[i] = 0; + } + pa_simple_write(dev, buf, s * sizeof(short), 0); + } + return 0; +} + +void init_audio(void) { + pa_sample_spec sp = { 0 }; + sp.format = PA_SAMPLE_S16LE; + sp.channels = 1; + sp.rate = audio_sample_rate; + audio.dev = pa_simple_new( + 0, + game_name, + PA_STREAM_PLAYBACK, + 0, + "Game Audio", + &sp, + 0, + 0, + 0 + ); + audio.r = 0; + audio.play = 0; + if (!audio.dev) { + print_err("Failed to create audio device.\n"); + print_war("Running without audio.\n"); + return; + } + audio.r = 1; + audio.buf = malloc( + audio_buffer_size * + sizeof *audio.buf + ); + pthread_mutex_init(&audio.mutex, 0); + pthread_create( + &audio.worker, + 0, + audio_worker, + 0 + ); +} + +void deinit_audio(void) { + if (audio.dev) { + pthread_mutex_lock(&audio.mutex); + audio.r = 0; + pthread_mutex_unlock(&audio.mutex); + pthread_mutex_destroy(&audio.mutex); + pthread_join(audio.worker, 0); + pa_simple_drain(audio.dev, 0); + pa_simple_free(audio.dev); + free(audio.buf); + } +} + +void play_sound(int len) { + pthread_mutex_lock(&audio.mutex); + audio.play += len; + pthread_mutex_unlock(&audio.mutex); +} + +#endif diff --git a/plat.h b/plat.h index 27d8d0a..ac41b7e 100644 --- a/plat.h +++ b/plat.h @@ -73,4 +73,8 @@ void deinit_app(App* a); void app_begin(App* a); void app_end(App* a); +void init_audio(void); +void deinit_audio(void); +void play_sound(int len); + #endif -- cgit v1.2.3-54-g00ecf