From 760db962ea35fd898647cbcbf09e896a4a82f0ca Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Sat, 22 Nov 2025 17:36:48 +0900 Subject: [PATCH] layout --- CMakeLists.txt | 37 +++------- audio/CMakeLists.txt | 57 +++++++++++++++ audio/drv_alsa.c | 77 ++++++++++++++++++++ audio/drv_ao.c | 46 ++++++++++++ audio/pthread/body.c | 67 ++++++++++++++++++ audio/pthread/decl.c | 17 +++++ core/CMakeLists.txt | 1 + {src/core => core}/directory.c | 0 {src/core => core}/file.c | 0 {src/core => core}/string.c | 0 {src/core => core}/users.c | 0 src/audio/drv_alsa.c | 125 --------------------------------- 12 files changed, 273 insertions(+), 154 deletions(-) create mode 100644 audio/CMakeLists.txt create mode 100644 audio/drv_alsa.c create mode 100644 audio/drv_ao.c create mode 100644 audio/pthread/body.c create mode 100644 audio/pthread/decl.c create mode 100644 core/CMakeLists.txt rename {src/core => core}/directory.c (100%) rename {src/core => core}/file.c (100%) rename {src/core => core}/string.c (100%) rename {src/core => core}/users.c (100%) delete mode 100644 src/audio/drv_alsa.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 15353e2..c7c6352 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,10 +5,14 @@ project( include(GNUInstallDirs) macro(setup_lib dir name) + project( + mde${dir} + ) + file( GLOB MDE${name}_SRC - src/${dir}/*.c + *.c ) add_library( @@ -20,7 +24,7 @@ macro(setup_lib dir name) target_include_directories( MDE${name} PUBLIC - include + ../include ) install( @@ -30,33 +34,8 @@ macro(setup_lib dir name) ) endmacro() -setup_lib(core Core) -setup_lib(audio Audio) - -find_package(PkgConfig) -pkg_check_modules(ALSA alsa) -if(ALSA_FOUND) - target_include_directories( - MDEAudio - PRIVATE - ${ALSA_INCLUDE_DIRS} - ) - target_link_directories( - MDEAudio - PRIVATE - ${ALSA_LIBRARY_DIRS} - ) - target_link_libraries( - MDEAudio - PRIVATE - ${ALSA_LIBRARIES} pthread - ) - target_compile_definitions( - MDEAudio - PRIVATE - USE_ALSA - ) -endif() +add_subdirectory(core) +add_subdirectory(audio) install( DIRECTORY include/ diff --git a/audio/CMakeLists.txt b/audio/CMakeLists.txt new file mode 100644 index 0000000..5eae32d --- /dev/null +++ b/audio/CMakeLists.txt @@ -0,0 +1,57 @@ +setup_lib(audio Audio) + +find_package(PkgConfig) + +if(NOT BACKEND_FOUND) + pkg_check_modules(AO ao) + if(AO_FOUND) + target_include_directories( + MDEAudio + PRIVATE + ${AO_INCLUDE_DIRS} + ) + target_link_directories( + MDEAudio + PRIVATE + ${AO_LIBRARY_DIRS} + ) + target_link_libraries( + MDEAudio + PRIVATE + ${AO_LIBRARIES} pthread + ) + target_compile_definitions( + MDEAudio + PRIVATE + USE_AO + ) + set(BACKEND_FOUND 1) + endif() +endif() + +if(NOT BACKEND_FOUND) + pkg_check_modules(ALSA alsa) + if(ALSA_FOUND) + target_include_directories( + MDEAudio + PRIVATE + ${ALSA_INCLUDE_DIRS} + ) + target_link_directories( + MDEAudio + PRIVATE + ${ALSA_LIBRARY_DIRS} + ) + target_link_libraries( + MDEAudio + PRIVATE + ${ALSA_LIBRARIES} pthread + ) + target_compile_definitions( + MDEAudio + PRIVATE + USE_ALSA + ) + set(BACKEND_FOUND 1) + endif() +endif() diff --git a/audio/drv_alsa.c b/audio/drv_alsa.c new file mode 100644 index 0000000..adc8e52 --- /dev/null +++ b/audio/drv_alsa.c @@ -0,0 +1,77 @@ +#include + +#ifdef USE_ALSA +#include + +typedef struct driver_context { + snd_pcm_t* device; + snd_pcm_hw_params_t* params; +} driver_context_t; + +#include "pthread/decl.c" + +static void drv_write(driver_t* drv, void* data, int frames){ + if(snd_pcm_writei(drv->context.device, data, frames) == -EPIPE){ + snd_pcm_prepare(drv->context.device); + } +} + +static int drv_open(driver_t* drv){ + snd_pcm_uframes_t frames; + int rate = MDEAudioRate; + + if(snd_pcm_open(&drv->context.device, "default", SND_PCM_STREAM_PLAYBACK, 0) < 0){ + MDEAudioClose(drv); + return 0; + } + + snd_pcm_hw_params_malloc(&drv->context.params); + snd_pcm_hw_params_any(drv->context.device, drv->context.params); + + if(snd_pcm_hw_params_set_access(drv->context.device, drv->context.params, SND_PCM_ACCESS_RW_INTERLEAVED) < 0){ + MDEAudioClose(drv); + return 0; + } + + if(snd_pcm_hw_params_set_format(drv->context.device, drv->context.params, SND_PCM_FORMAT_S16) < 0){ + MDEAudioClose(drv); + return 0; + } + + if(snd_pcm_hw_params_set_channels(drv->context.device, drv->context.params, 2) < 0){ + MDEAudioClose(drv); + return 0; + } + + if(snd_pcm_hw_params_set_rate_near(drv->context.device, drv->context.params, &rate, 0) < 0){ + MDEAudioClose(drv); + return 0; + } + + if(snd_pcm_hw_params_set_rate(drv->context.device, drv->context.params, rate, 0) < 0){ + MDEAudioClose(drv); + return 0; + } + + if(snd_pcm_hw_params(drv->context.device, drv->context.params) < 0){ + MDEAudioClose(drv); + return 0; + } + + snd_pcm_hw_params_get_period_size(drv->context.params, &frames, 0); + drv->frames = frames; + + return 1; +} + + +static void drv_close(driver_t* drv){ + if(drv->context.device != NULL){ + snd_pcm_drain(drv->context.device); + snd_pcm_close(drv->context.device); + snd_pcm_hw_params_free(drv->context.params); + } +} + +#include "pthread/body.c" +#endif diff --git a/audio/drv_ao.c b/audio/drv_ao.c new file mode 100644 index 0000000..34985b1 --- /dev/null +++ b/audio/drv_ao.c @@ -0,0 +1,46 @@ +#include + +#ifdef USE_AO +#include + +typedef struct driver_context { + ao_sample_format format; + ao_device* device; +} driver_context_t; + +#include "pthread/decl.c" + +static void drv_write(driver_t* drv, void* data, int frames){ + ao_play(drv->context.device, (char*)data, frames * 2 * 2); +} + +static int drv_open(driver_t* drv){ + int id; + + ao_initialize(); + + drv->context.format.bits = 16; + drv->context.format.rate = MDEAudioRate; + drv->context.format.channels = 2; + drv->context.format.byte_format = AO_FMT_NATIVE; + drv->context.format.matrix = NULL; + + id = ao_default_driver_id(); + if((drv->context.device = ao_open_live(id, &drv->context.format, NULL)) == NULL){ + MDEAudioClose(drv); + return 0; + } + + drv->frames = 60 * MDEAudioRate / 1000; + + return 1; +} + +static void drv_close(driver_t* drv){ + if(drv->context.device != NULL){ + ao_close(drv->context.device); + } +} + +#include "pthread/body.c" +#endif diff --git a/audio/pthread/body.c b/audio/pthread/body.c new file mode 100644 index 0000000..ada33e1 --- /dev/null +++ b/audio/pthread/body.c @@ -0,0 +1,67 @@ +static void* thread_routine(void* arg){ + driver_t* drv = arg; + void* data; + + data = malloc(drv->frames * 2 * 2); + + while(1){ + drv->handler(drv, drv->user, data, drv->frames); + + drv_write(drv, data, drv->frames); + + pthread_mutex_lock(&drv->mutex); + if(drv->quit){ + pthread_mutex_unlock(&drv->mutex); + break; + } + pthread_mutex_unlock(&drv->mutex); + } + + free(data); + + return NULL; +} + +void* MDEAudioOpen(MDEAudioHandler handler, void* user){ + int rate = MDEAudioRate; + driver_t* drv = malloc(sizeof(*drv)); + memset(drv, 0, sizeof(*drv)); + + drv->quit = 0; + drv->handler = handler; + drv->user = user; + drv->init = 0; + + pthread_mutex_init(&drv->mutex, NULL); + + if(!(drv->init = drv_open(drv))){ + MDEAudioClose(drv); + return NULL; + } + + return drv; +} + +void MDEAudioClose(void* handle){ + driver_t* drv = handle; + void* ret; + + if(drv->init){ + pthread_mutex_lock(&drv->mutex); + drv->quit = 1; + pthread_mutex_unlock(&drv->mutex); + pthread_join(drv->thread, &ret); + } + + pthread_mutex_destroy(&drv->mutex); + + drv_close(drv); + + free(drv); +} + +void MDEAudioStart(void* handle){ + driver_t* drv = handle; + + pthread_create(&drv->thread, NULL, thread_routine, handle); +} diff --git a/audio/pthread/decl.c b/audio/pthread/decl.c new file mode 100644 index 0000000..8a80760 --- /dev/null +++ b/audio/pthread/decl.c @@ -0,0 +1,17 @@ +#include + +#include + +typedef struct driver { + driver_context_t context; + + int init; + int frames; + + MDEAudioHandler handler; + void* user; + + int quit; + pthread_t thread; + pthread_mutex_t mutex; +} driver_t; diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt new file mode 100644 index 0000000..d4127c6 --- /dev/null +++ b/core/CMakeLists.txt @@ -0,0 +1 @@ +setup_lib(core Core) diff --git a/src/core/directory.c b/core/directory.c similarity index 100% rename from src/core/directory.c rename to core/directory.c diff --git a/src/core/file.c b/core/file.c similarity index 100% rename from src/core/file.c rename to core/file.c diff --git a/src/core/string.c b/core/string.c similarity index 100% rename from src/core/string.c rename to core/string.c diff --git a/src/core/users.c b/core/users.c similarity index 100% rename from src/core/users.c rename to core/users.c diff --git a/src/audio/drv_alsa.c b/src/audio/drv_alsa.c deleted file mode 100644 index 8302556..0000000 --- a/src/audio/drv_alsa.c +++ /dev/null @@ -1,125 +0,0 @@ -#include - -#ifdef USE_ALSA -#include - -#include - -typedef struct driver { - MDEAudioHandler handler; - void* user; - snd_pcm_t* device; - snd_pcm_hw_params_t* params; - - int quit; - pthread_t thread; - pthread_mutex_t mutex; -} driver_t; - -static void* thread_routine(void* arg){ - driver_t* drv = arg; - snd_pcm_uframes_t frame; - void* data; - - snd_pcm_hw_params_get_period_size(drv->params, &frame, 0); - - data = malloc(frame * 2 * 2); - - while(1){ - drv->handler(drv, drv->user, data, frame); - if(snd_pcm_writei(drv->device, data, frame) == -EPIPE){ - snd_pcm_prepare(drv->device); - } - - pthread_mutex_lock(&drv->mutex); - if(drv->quit){ - pthread_mutex_unlock(&drv->mutex); - break; - } - pthread_mutex_unlock(&drv->mutex); - } - - free(data); - - return NULL; -} - -void* MDEAudioOpen(MDEAudioHandler handler, void* user){ - int rate = MDEAudioRate; - driver_t* drv = malloc(sizeof(*drv)); - memset(drv, 0, sizeof(*drv)); - - drv->quit = 0; - drv->handler = handler; - drv->user = user; - - if(snd_pcm_open(&drv->device, "default", SND_PCM_STREAM_PLAYBACK, 0) < 0){ - MDEAudioClose(drv); - return NULL; - } - - snd_pcm_hw_params_malloc(&drv->params); - snd_pcm_hw_params_any(drv->device, drv->params); - - if(snd_pcm_hw_params_set_access(drv->device, drv->params, SND_PCM_ACCESS_RW_INTERLEAVED) < 0){ - MDEAudioClose(drv); - return NULL; - } - - if(snd_pcm_hw_params_set_format(drv->device, drv->params, SND_PCM_FORMAT_S16) < 0){ - MDEAudioClose(drv); - return NULL; - } - - if(snd_pcm_hw_params_set_channels(drv->device, drv->params, 2) < 0){ - MDEAudioClose(drv); - return NULL; - } - - if(snd_pcm_hw_params_set_rate_near(drv->device, drv->params, &rate, 0) < 0){ - MDEAudioClose(drv); - return NULL; - } - - if(snd_pcm_hw_params_set_rate(drv->device, drv->params, rate, 0) < 0){ - MDEAudioClose(drv); - return NULL; - } - - if(snd_pcm_hw_params(drv->device, drv->params) < 0){ - MDEAudioClose(drv); - return NULL; - } - - pthread_mutex_init(&drv->mutex, NULL); - - return drv; -} - -void MDEAudioClose(void* handle){ - driver_t* drv = handle; - - if(drv->device != NULL){ - void* ret; - - pthread_mutex_lock(&drv->mutex); - drv->quit = 1; - pthread_mutex_unlock(&drv->mutex); - pthread_join(drv->thread, &ret); - - pthread_mutex_destroy(&drv->mutex); - - snd_pcm_drain(drv->device); - snd_pcm_close(drv->device); - snd_pcm_hw_params_free(drv->params); - } - - free(drv); -} - -void MDEAudioStart(void* handle){ - driver_t* drv = handle; - - pthread_create(&drv->thread, NULL, thread_routine, handle); -} -#endif