From 34691de22bb6014788447805367b490d2bfff4da Mon Sep 17 00:00:00 2001 From: vanfanel Date: Sun, 20 Jul 2025 14:23:45 +0200 Subject: [PATCH] SDL2: Fill the SDL_AudioSpec in add_device() --- src/audio/alsa/SDL_alsa_audio.c | 46 +++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/src/audio/alsa/SDL_alsa_audio.c b/src/audio/alsa/SDL_alsa_audio.c index 8f3a49c814..457d7ce575 100644 --- a/src/audio/alsa/SDL_alsa_audio.c +++ b/src/audio/alsa/SDL_alsa_audio.c @@ -62,6 +62,7 @@ static int (*ALSA_snd_pcm_hw_params_set_access)(snd_pcm_t *, snd_pcm_hw_params_t static int (*ALSA_snd_pcm_hw_params_set_format)(snd_pcm_t *, snd_pcm_hw_params_t *, snd_pcm_format_t); static int (*ALSA_snd_pcm_hw_params_set_channels)(snd_pcm_t *, snd_pcm_hw_params_t *, unsigned int); static int (*ALSA_snd_pcm_hw_params_get_channels)(const snd_pcm_hw_params_t *, unsigned int *); +static int (*ALSA_snd_pcm_hw_params_get_rate)(snd_pcm_hw_params_t *, unsigned int*, int*); static int (*ALSA_snd_pcm_hw_params_set_rate_near)(snd_pcm_t *, snd_pcm_hw_params_t *, unsigned int *, int *); static int (*ALSA_snd_pcm_hw_params_set_period_size_near)(snd_pcm_t *, snd_pcm_hw_params_t *, snd_pcm_uframes_t *, int *); static int (*ALSA_snd_pcm_hw_params_get_period_size)(const snd_pcm_hw_params_t *, snd_pcm_uframes_t *, int *); @@ -138,6 +139,7 @@ static int load_alsa_syms(void) SDL_ALSA_SYM(snd_pcm_hw_params_set_format); SDL_ALSA_SYM(snd_pcm_hw_params_set_channels); SDL_ALSA_SYM(snd_pcm_hw_params_get_channels); + SDL_ALSA_SYM(snd_pcm_hw_params_get_rate); SDL_ALSA_SYM(snd_pcm_hw_params_set_rate_near); SDL_ALSA_SYM(snd_pcm_hw_params_set_period_size_near); SDL_ALSA_SYM(snd_pcm_hw_params_get_period_size); @@ -780,6 +782,16 @@ static void add_device(const int iscapture, const char *name, void *hint, ALSA_D char *desc; char *handle = NULL; char *ptr; + snd_pcm_t *pcm_handle; + snd_pcm_stream_t stream; + snd_pcm_hw_params_t *hwparams; + + unsigned int freq = 0; + int dir; + unsigned int channels = 0; + snd_pcm_uframes_t samples = 0; + + SDL_AudioSpec spec; if (!dev) { return; @@ -819,12 +831,36 @@ static void add_device(const int iscapture, const char *name, void *hint, ALSA_D SDL_free(dev); return; } + stream = iscapture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK; + + if (ALSA_snd_pcm_open(&pcm_handle, handle, stream, SND_PCM_NONBLOCK) < 0) { + SDL_free(dev); + return; + } - /* Note that spec is NULL, because we are required to open the device before - * acquiring the mix format, making this information inaccessible at - * enumeration time - */ - SDL_AddAudioDevice(iscapture, desc, NULL, handle); + snd_pcm_hw_params_alloca(&hwparams); + ALSA_snd_pcm_hw_params_any(pcm_handle, hwparams); + + ALSA_snd_pcm_hw_params_get_rate(hwparams, &freq, &dir); + ALSA_snd_pcm_hw_params_get_channels(hwparams, &channels); + ALSA_snd_pcm_hw_params_get_period_size(hwparams, &samples, &dir); + + ALSA_snd_pcm_close(pcm_handle); + + /* Let's fill the spec */ + + spec.freq = freq; + spec.channels = channels; + spec.samples = samples; + spec.silence = 0; + spec.padding = 0; + /* Can't calculate size yet because this is an exploratory device opening + * so we don't know the sample format. + * Probably AUDIO_S16SYS/SND_PCM_FORMAT_S16_LE would be a good default + * if required.*/ + spec.size = 0; + + SDL_AddAudioDevice(iscapture, desc, &spec, handle); if (hint) { free(desc); }