Browse Source

SDL2: Implement SDL_GetDefaultAudioInfo() on the ALSA backend.

(cherry picked from commit 8d5984464ee242498a452699f77f6d7f6694124f)
vanfanel 2 weeks ago
parent
commit
28f2944947
1 changed files with 64 additions and 0 deletions
  1. 64 0
      src/audio/alsa/SDL_alsa_audio.c

+ 64 - 0
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;