[alsa] list alsa devices/mixers suitable for playback

This commit is contained in:
whatdoineed2do/Ray 2020-04-16 17:11:05 +01:00
parent 24e3ac1a80
commit 0a08b93c24

View File

@ -1185,6 +1185,120 @@ alsa_write(struct output_buffer *obuf)
}
}
static void
alsa_device_log(int card, snd_ctl_card_info_t *info)
{
snd_ctl_t *hdl;
snd_mixer_t *mixer;
snd_mixer_elem_t *elem;
char hwdev[14]; // 'hw:' (3) + max_uint (10)
char *buf = NULL;
unsigned buf_size = 128;
unsigned buf_len = 0;
unsigned len;
int err;
snprintf(hwdev, sizeof(hwdev), "hw:%d", card);
err = snd_ctl_open(&hdl, hwdev, 0);
if (err < 0)
{
DPRINTF(E_WARN, L_LAUDIO, "Failed to probe ALSA card=%d - %s\n", card, snd_strerror(err));
return;
}
err = snd_ctl_card_info(hdl, info);
if (err < 0)
{
DPRINTF(E_WARN, L_LAUDIO, "Failed to probe ALSA (info) card=%d - %s\n", card, snd_strerror(err));
goto error;
}
err = snd_mixer_open(&mixer, 0);
if (err < 0)
{
DPRINTF(E_WARN, L_LAUDIO, "Failed to probe ALSA (mixer open) card=%d - %s\n", card, snd_strerror(err));
goto error;
}
err = snd_mixer_attach(mixer, hwdev);
if (err < 0)
{
DPRINTF(E_WARN, L_LAUDIO, "Failed to probe ALSA (mixer attach) card=%d - %s\n", card, snd_strerror(err));
goto errormixer;
}
err = snd_mixer_selem_register(mixer, NULL, NULL);
if (err < 0)
{
DPRINTF(E_WARN, L_LAUDIO, "Failed to probe ALSA (mixer setup) card=%d - %s\n", card, snd_strerror(err));
goto errormixer;
}
err = snd_mixer_load(mixer);
if (err < 0)
{
DPRINTF(E_WARN, L_LAUDIO, "Failed to probe ALSA (mixer setup) card=%d - %s\n", card, snd_strerror(err));
goto errormixer;
}
for (elem = snd_mixer_first_elem(mixer); elem; elem = snd_mixer_elem_next(elem))
{
if (snd_mixer_selem_has_common_volume(elem) || !snd_mixer_selem_has_playback_volume(elem))
continue;
len = strlen(snd_mixer_selem_get_name(elem)) + 3;
if (!buf)
{
if (buf_size < len*2)
buf_size = len*2;
buf = malloc(buf_size+1);
buf[0] = '\0';
buf_len = 0;
}
else
{
if (buf_len + len > buf_size)
{
buf_size += len + 128;
buf = realloc(buf, buf_size+1);
}
}
strcat(buf, "'");
strcat(buf, snd_mixer_selem_get_name(elem));
strcat(buf, "'");
strcat(buf, " ");
buf_len += len;
}
DPRINTF(E_INFO, L_LAUDIO, "Available ALSA playback/mixer(s) on '%s' (%s): %s\n", hwdev, snd_ctl_card_info_get_name(info), buf ? buf : "n/a");
errormixer:
snd_mixer_close(mixer);
error:
snd_ctl_close(hdl);
free(buf);
}
// walk all the alsa devices here and report valid playback mixers
static void
alsa_device_list()
{
snd_ctl_card_info_t *info = NULL;
int card = 0;
snd_ctl_card_info_alloca(&info);
while (card >= 0)
{
alsa_device_log(card, info);
if (snd_card_next(&card) < 0)
break;
}
}
static void
alsa_device_add(cfg_t* cfg_audio, int id)
{
@ -1244,6 +1358,8 @@ alsa_init(void)
if (type && (strcasecmp(type, "alsa") != 0))
return -1;
alsa_device_list();
alsa_sync_disable = cfg_getbool(cfg_audio, "sync_disable");
alsa_latency_history_size = cfg_getint(cfg_audio, "adjust_period_seconds");