diff --git a/src/audio/alsa/SDL_alsa_audio.c b/src/audio/alsa/SDL_alsa_audio.c index 3e0e7acaf9..43d58e1fc5 100644 --- a/src/audio/alsa/SDL_alsa_audio.c +++ b/src/audio/alsa/SDL_alsa_audio.c @@ -83,6 +83,12 @@ static int (*ALSA_snd_device_name_hint)(int, const char *, void ***); static char *(*ALSA_snd_device_name_get_hint)(const void *, const char *); static int (*ALSA_snd_device_name_free_hint)(void **); static snd_pcm_sframes_t (*ALSA_snd_pcm_avail)(snd_pcm_t *); +static int (*ALSA_snd_pcm_info)(snd_pcm_t *, snd_pcm_info_t *); +static const char *(*ALSA_snd_pcm_info_get_name)(const snd_pcm_info_t *); +static int (*ALSA_snd_pcm_info_get_card)(const snd_pcm_info_t *); +static int (*ALSA_snd_card_get_name)(int, char **); +static int (*ALSA_snd_pcm_info_malloc)(snd_pcm_info_t **); +static int (*ALSA_snd_pcm_info_free)(snd_pcm_info_t *); #ifdef SND_CHMAP_API_VERSION static snd_pcm_chmap_t *(*ALSA_snd_pcm_get_chmap)(snd_pcm_t *); static int (*ALSA_snd_pcm_chmap_print)(const snd_pcm_chmap_t *map, size_t maxlen, char *buf); @@ -152,6 +158,11 @@ static int load_alsa_syms(void) SDL_ALSA_SYM(snd_device_name_get_hint); SDL_ALSA_SYM(snd_device_name_free_hint); SDL_ALSA_SYM(snd_pcm_avail); + SDL_ALSA_SYM(snd_pcm_info); + SDL_ALSA_SYM(snd_pcm_info_get_card); + SDL_ALSA_SYM(snd_card_get_name); + SDL_ALSA_SYM(snd_pcm_info_malloc); + SDL_ALSA_SYM(snd_pcm_info_free); #ifdef SND_CHMAP_API_VERSION SDL_ALSA_SYM(snd_pcm_get_chmap); SDL_ALSA_SYM(snd_pcm_chmap_print); @@ -466,6 +477,58 @@ static void ALSA_CloseDevice(_THIS) SDL_free(this->hidden); } +static int ALSA_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture) +{ + const char *device = "default"; + snd_pcm_t *pcm_handle; + snd_pcm_info_t *pcm_info; + snd_pcm_stream_t stream; + int card_index; + const char *dev_name; + char *card_name = NULL; + char final_name[256]; + + SDL_zero(final_name); + stream = iscapture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK; + + if (ALSA_snd_pcm_open(&pcm_handle, device, stream, SND_PCM_NONBLOCK) < 0) { + return SDL_SetError("ALSA: Couldn't open default device"); + } + + if (ALSA_snd_pcm_info_malloc(&pcm_info) < 0) { + ALSA_snd_pcm_close(pcm_handle); + return SDL_SetError("ALSA: Couldn't allocate pcm_info"); + } + + if (ALSA_snd_pcm_info(pcm_handle, pcm_info) < 0) { + ALSA_snd_pcm_info_free(pcm_info); + ALSA_snd_pcm_close(pcm_handle); + return SDL_SetError("ALSA: Couldn't get PCM info"); + } + + card_index = ALSA_snd_pcm_info_get_card(pcm_info); + dev_name = ALSA_snd_pcm_info_get_name(pcm_info); + + if (card_index >= 0 && ALSA_snd_card_get_name(card_index, &card_name) >= 0) { + SDL_snprintf(final_name, sizeof(final_name), "%s, %s", card_name, dev_name); + *name = SDL_strdup(final_name); + } else { + *name = SDL_strdup(dev_name ? dev_name : "Unknown ALSA Device"); + } + + if (spec) { + SDL_zero(*spec); + spec->freq = 48000; + spec->format = AUDIO_S16SYS; + spec->channels = 2; + spec->samples = 512; + } + + ALSA_snd_pcm_info_free(pcm_info); + ALSA_snd_pcm_close(pcm_handle); + return 0; +} + static int ALSA_set_buffer_size(_THIS, snd_pcm_hw_params_t *params) { int status; @@ -975,6 +1038,7 @@ static SDL_bool ALSA_Init(SDL_AudioDriverImpl *impl) impl->Deinitialize = ALSA_Deinitialize; impl->CaptureFromDevice = ALSA_CaptureFromDevice; impl->FlushCapture = ALSA_FlushCapture; + impl->GetDefaultAudioInfo = ALSA_GetDefaultAudioInfo; impl->HasCaptureSupport = SDL_TRUE; impl->SupportsNonPow2Samples = SDL_TRUE;