mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-24 05:03:17 -05:00
[alsa] list alsa devices/mixers suitable for playback
This commit is contained in:
parent
24e3ac1a80
commit
0a08b93c24
@ -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");
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user