diff options
author | Eric Wong <normalperson@yhbt.net> | 2006-07-16 16:52:49 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2006-07-16 16:52:49 +0000 |
commit | ea6dc826a1c40047058ab7d86c848b32be3de25e (patch) | |
tree | 547aebfa3302e04a463ebeb6b7060647c1220d3a | |
parent | 6b2167a4440f2c8b3f138b2a3df26310edb41d5a (diff) | |
download | mpd-ea6dc826a1c40047058ab7d86c848b32be3de25e.tar.gz mpd-ea6dc826a1c40047058ab7d86c848b32be3de25e.tar.xz mpd-ea6dc826a1c40047058ab7d86c848b32be3de25e.zip |
volume: gracefully handle disconnected ALSA mixers
This should help with the previous set of patches against the ALSA
audio output. We should have fully disconnectable/reconnectable ALSA devices
now.
git-svn-id: https://svn.musicpd.org/mpd/trunk@4365 09075e82-0dd4-0310-85a5-a0d7c8717e4f
-rw-r--r-- | src/volume.c | 60 |
1 files changed, 36 insertions, 24 deletions
diff --git a/src/volume.c b/src/volume.c index 512b7f157..6fd68d778 100644 --- a/src/volume.c +++ b/src/volume.c @@ -185,6 +185,11 @@ static int changeOssVolumeLevel(FILE * fp, int change, int rel) { #endif #ifdef HAVE_ALSA +static void closeAlsaMixer(void) { + snd_mixer_close(volume_alsaMixerHandle); + volume_alsaMixerHandle = NULL; +} + static int prepAlsaMixer(char * card) { int err; snd_mixer_elem_t * elem; @@ -197,21 +202,21 @@ static int prepAlsaMixer(char * card) { } if((err = snd_mixer_attach(volume_alsaMixerHandle,card))<0) { - snd_mixer_close(volume_alsaMixerHandle); + closeAlsaMixer(); WARNING("problems problems attaching alsa mixer: %s\n", snd_strerror(err)); return -1; } if((err = snd_mixer_selem_register(volume_alsaMixerHandle,NULL,NULL))<0) { - snd_mixer_close(volume_alsaMixerHandle); + closeAlsaMixer(); WARNING("problems snd_mixer_selem_register'ing: %s\n", snd_strerror(err)); return -1; } - + if((err = snd_mixer_load(volume_alsaMixerHandle))<0) { - snd_mixer_close(volume_alsaMixerHandle); + closeAlsaMixer(); WARNING("problems snd_mixer_selem_register'ing: %s\n", snd_strerror(err)); return -1; @@ -246,12 +251,33 @@ static int prepAlsaMixer(char * card) { WARNING("can't find alsa mixer_control \"%s\"\n",controlName); - snd_mixer_close(volume_alsaMixerHandle); + closeAlsaMixer(); return -1; } -static void closeAlsaMixer() { - snd_mixer_close(volume_alsaMixerHandle); +static int prep_alsa_get_level(long *level) +{ + const char *cmd; + int err; + + if (!volume_alsaMixerHandle && prepAlsaMixer(volume_mixerDevice)<0) + return -1; + + if ((err = snd_mixer_handle_events(volume_alsaMixerHandle)) < 0) { + cmd = "handle_events"; + goto error; + } + if((err = snd_mixer_selem_get_playback_volume(volume_alsaElem, + SND_MIXER_SCHN_FRONT_LEFT, level)) < 0) { + cmd = "selem_get_playback_volume"; + goto error; + } + return 0; +error: + WARNING("problems getting alsa volume: %s (snd_mixer_%s)\n", + snd_strerror(err), cmd); + closeAlsaMixer(); + return -1; } static int getAlsaVolumeLevel() { @@ -259,18 +285,10 @@ static int getAlsaVolumeLevel() { long level; long max = volume_alsaMax; long min = volume_alsaMin; - int err; - - snd_mixer_handle_events(volume_alsaMixerHandle); - if((err = snd_mixer_selem_get_playback_volume(volume_alsaElem, - SND_MIXER_SCHN_FRONT_LEFT,&level))<0) { - WARNING("problems getting alsa volume: %s\n",snd_strerror(err)); + if (prep_alsa_get_level(&level) < 0) return -1; - } - snd_mixer_selem_get_playback_volume(volume_alsaElem, - SND_MIXER_SCHN_FRONT_LEFT,&level); ret = ((volume_alsaSet/100.0)*(max-min)+min)+0.5; if(volume_alsaSet>0 && ret==level) { ret = volume_alsaSet; @@ -288,15 +306,8 @@ static int changeAlsaVolumeLevel(FILE * fp, int change, int rel) { long min = volume_alsaMin; int err; - snd_mixer_handle_events(volume_alsaMixerHandle); - - if((err = snd_mixer_selem_get_playback_volume(volume_alsaElem, - SND_MIXER_SCHN_FRONT_LEFT,&level))<0) { - commandError(fp, ACK_ERROR_SYSTEM, "problems getting volume", - NULL); - WARNING("problems getting alsa volume: %s\n",snd_strerror(err)); + if (prep_alsa_get_level(&level) < 0) return -1; - } if (rel) { test = ((volume_alsaSet/100.0)*(max-min)+min)+0.5; @@ -322,6 +333,7 @@ static int changeAlsaVolumeLevel(FILE * fp, int change, int rel) { commandError(fp, ACK_ERROR_SYSTEM, "problems setting volume", NULL); WARNING("problems setting alsa volume: %s\n",snd_strerror(err)); + closeAlsaMixer(); return -1; } |