diff options
Diffstat (limited to 'src/volume.c')
-rw-r--r-- | src/volume.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/src/volume.c b/src/volume.c index c16938042..008aaac92 100644 --- a/src/volume.c +++ b/src/volume.c @@ -63,6 +63,9 @@ char * volume_mixerDevice = VOLUME_MIXER_DEVICE_DEFAULT; int volume_softwareSet = 100; +int volume_fakeMuteStatus = 0; +int volume_fakeLastUnmutedLevel = -1; + #ifdef HAVE_OSS int volume_ossFd; int volume_ossControl = SOUND_MIXER_PCM; @@ -443,6 +446,9 @@ int changeSoftwareVolume(FILE * fp, int change, int rel) { } int changeVolumeLevel(FILE * fp, int change, int rel) { + if(getVolumeMuteStatus()) + setVolumeMuteStatus(fp,0); + switch(volume_mixerType) { #ifdef HAVE_ALSA case VOLUME_MIXER_TYPE_ALSA: @@ -459,3 +465,111 @@ int changeVolumeLevel(FILE * fp, int change, int rel) { break; } } + +int getAlsaVolumeMuteStatus() { + int err; + int status; + + if((err = snd_mixer_selem_get_playback_switch(volume_alsaElem, + SND_MIXER_SCHN_FRONT_LEFT,&status))<0) { + WARNING("problems getting alsa mute status: %s\n", + snd_strerror(err)); + return -1; + } + + return !status; +} + +int setAlsaVolumeMuteStatus(FILE * fp, int status) { + int err; + + if(status == getVolumeMuteStatus()) + return 0; + + if((err = snd_mixer_selem_set_playback_switch_all(volume_alsaElem, + !status))<0) { + commandError(fp, ACK_ERROR_SYSTEM, "problems muting volume", + NULL); + WARNING("problems muting alsa volume: %s\n", snd_strerror(err)); + return -1; + } + + return 0; +} + +int getFakeVolumeMuteStatus() { + return volume_fakeMuteStatus; +} + +// Fake mute: just drop volume to 0 +int setFakeVolumeMuteStatus(FILE * fp, int status) { + // Don't call changeVolumeLevel while volume_fakeMuteStatus is set! + if(status && !getVolumeMuteStatus()) { + // Mute + int ret; + volume_fakeLastUnmutedLevel = getVolumeLevel(); + ret = changeVolumeLevel(fp,0,0); + volume_fakeMuteStatus = 1; + return ret; + } + else if(!status && getVolumeMuteStatus()){ + // Unmute + volume_fakeMuteStatus = 0; + return changeVolumeLevel(fp,volume_fakeLastUnmutedLevel,0); + } + else { + return 0; + } +} + +int getOssVolumeMuteStatus() { + return getFakeVolumeMuteStatus(); +} + +int setOssVolumeMuteStatus(FILE * fp, int status) { + return setFakeVolumeMuteStatus(fp,status); +} + +int getSoftwareVolumeMuteStatus() { + return getFakeVolumeMuteStatus(); +} + +int setSoftwareVolumeMuteStatus(FILE * fp, int status) { + return setFakeVolumeMuteStatus(fp,status); +} + +int getVolumeMuteStatus() { + switch(volume_mixerType) { +#ifdef HAVE_ALSA + case VOLUME_MIXER_TYPE_ALSA: + return getAlsaVolumeMuteStatus(); +#endif +#ifdef HAVE_OSS + case VOLUME_MIXER_TYPE_OSS: + return getOssVolumeMuteStatus(); +#endif + case VOLUME_MIXER_TYPE_SOFTWARE: + return getSoftwareVolumeMuteStatus(); + default: + return 0; + break; + } +} + +int setVolumeMuteStatus(FILE * fp, int status) { + switch(volume_mixerType) { +#ifdef HAVE_ALSA + case VOLUME_MIXER_TYPE_ALSA: + return setAlsaVolumeMuteStatus(fp,status); +#endif +#ifdef HAVE_OSS + case VOLUME_MIXER_TYPE_OSS: + return setOssVolumeMuteStatus(fp,status); +#endif + case VOLUME_MIXER_TYPE_SOFTWARE: + return setSoftwareVolumeMuteStatus(fp,status); + default: + return 0; + break; + } +} |