2025-11-22 17:36:48 +09:00
|
|
|
#include <MDE/Audio/Audio.h>
|
|
|
|
|
|
|
|
|
|
#ifdef USE_ALSA
|
|
|
|
|
#include <alsa/asoundlib.h>
|
|
|
|
|
|
|
|
|
|
typedef struct driver_context {
|
2025-11-22 17:56:29 +09:00
|
|
|
snd_pcm_t* device;
|
2025-11-22 17:36:48 +09:00
|
|
|
snd_pcm_hw_params_t* params;
|
|
|
|
|
} driver_context_t;
|
|
|
|
|
|
|
|
|
|
#include "pthread/decl.c"
|
|
|
|
|
|
2025-11-22 17:56:29 +09:00
|
|
|
static void drv_write(driver_t* drv, void* data, int frames) {
|
|
|
|
|
if(snd_pcm_writei(drv->context.device, data, frames) == -EPIPE) {
|
2025-11-22 17:36:48 +09:00
|
|
|
snd_pcm_prepare(drv->context.device);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-22 17:56:29 +09:00
|
|
|
static int drv_open(driver_t* drv) {
|
2025-11-22 17:36:48 +09:00
|
|
|
snd_pcm_uframes_t frames;
|
2025-11-22 17:56:29 +09:00
|
|
|
int rate = MDEAudioRate;
|
|
|
|
|
|
|
|
|
|
if(snd_pcm_open(&drv->context.device, "default", SND_PCM_STREAM_PLAYBACK, 0) < 0) {
|
2025-11-22 17:36:48 +09:00
|
|
|
MDEAudioClose(drv);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
snd_pcm_hw_params_malloc(&drv->context.params);
|
|
|
|
|
snd_pcm_hw_params_any(drv->context.device, drv->context.params);
|
2025-11-22 17:56:29 +09:00
|
|
|
|
|
|
|
|
if(snd_pcm_hw_params_set_access(drv->context.device, drv->context.params, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
|
2025-11-22 17:36:48 +09:00
|
|
|
MDEAudioClose(drv);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2025-11-22 17:56:29 +09:00
|
|
|
|
|
|
|
|
if(snd_pcm_hw_params_set_format(drv->context.device, drv->context.params, SND_PCM_FORMAT_S16) < 0) {
|
2025-11-22 17:36:48 +09:00
|
|
|
MDEAudioClose(drv);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-22 17:56:29 +09:00
|
|
|
if(snd_pcm_hw_params_set_channels(drv->context.device, drv->context.params, 2) < 0) {
|
2025-11-22 17:36:48 +09:00
|
|
|
MDEAudioClose(drv);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-22 17:56:29 +09:00
|
|
|
if(snd_pcm_hw_params_set_rate_near(drv->context.device, drv->context.params, &rate, 0) < 0) {
|
2025-11-22 17:36:48 +09:00
|
|
|
MDEAudioClose(drv);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-22 17:56:29 +09:00
|
|
|
if(snd_pcm_hw_params_set_rate(drv->context.device, drv->context.params, rate, 0) < 0) {
|
2025-11-22 17:36:48 +09:00
|
|
|
MDEAudioClose(drv);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-22 17:56:29 +09:00
|
|
|
if(snd_pcm_hw_params(drv->context.device, drv->context.params) < 0) {
|
2025-11-22 17:36:48 +09:00
|
|
|
MDEAudioClose(drv);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
snd_pcm_hw_params_get_period_size(drv->context.params, &frames, 0);
|
|
|
|
|
drv->frames = frames;
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-22 17:56:29 +09:00
|
|
|
static void drv_close(driver_t* drv) {
|
|
|
|
|
if(drv->context.device != NULL) {
|
2025-11-22 17:36:48 +09:00
|
|
|
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
|