summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS23
-rw-r--r--src/command.c18
-rw-r--r--src/volume.c114
-rw-r--r--src/volume.h4
4 files changed, 152 insertions, 7 deletions
diff --git a/AUTHORS b/AUTHORS
index 10c8966ab..2c9c7dfdd 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,10 +1,19 @@
-Developer -> Warren Dukes <shank@mercury.chem.pitt.edu>
-Developer -> tw-nym
-audiofile support and command.c cleanup -> normalperson
-setuid patch -> Nagilum
-'next' and 'previous' patch -> Niklas Hofer
-command.c and signal handling cleanup -> mackstann
-replayGain -> AliasMrJones
+General Development
+ - Warren Dukes <shank@mercury.chem.pitt.edu>
+ - tw-nym
+ - normalperson
+
+'next' and 'previous' command
+ - Niklas Hofer
+
+'mute' command
+ - danb
+
+setuid support
+ - nagilum
+
+replayGain support
+ - AliasMrJones
libid3tag and libmad copyrighted by Robert Leslie, http://www.underbit.com/products/mad
mp4ff copyrighted by M. Bakker, Ahead Software AG, http://www.nero.com
diff --git a/src/command.c b/src/command.c
index 2c307e0bb..438b55ffb 100644
--- a/src/command.c
+++ b/src/command.c
@@ -64,6 +64,7 @@
#define COMMAND_PREVIOUS "previous"
#define COMMAND_LISTALL "listall"
#define COMMAND_VOLUME "volume"
+#define COMMAND_MUTE "mute"
#define COMMAND_REPEAT "repeat"
#define COMMAND_RANDOM "random"
#define COMMAND_STATS "stats"
@@ -90,6 +91,7 @@
#define COMMAND_NOTCOMMANDS "notcommands"
#define COMMAND_STATUS_VOLUME "volume"
+#define COMMAND_STATUS_MUTE "mute"
#define COMMAND_STATUS_STATE "state"
#define COMMAND_STATUS_REPEAT "repeat"
#define COMMAND_STATUS_RANDOM "random"
@@ -248,6 +250,7 @@ int commandStatus(FILE * fp, unsigned int * permission, int argArrayLength,
}
myfprintf(fp,"%s: %i\n",COMMAND_STATUS_VOLUME,getVolumeLevel());
+ myfprintf(fp,"%s: %i\n",COMMAND_STATUS_MUTE,getVolumeMuteStatus());
myfprintf(fp,"%s: %i\n",COMMAND_STATUS_REPEAT,getPlaylistRepeatStatus());
myfprintf(fp,"%s: %i\n",COMMAND_STATUS_RANDOM,getPlaylistRandomStatus());
myfprintf(fp,"%s: %li\n",COMMAND_STATUS_PLAYLIST,getPlaylistVersion());
@@ -572,6 +575,20 @@ int handleSetVol(FILE * fp, unsigned int * permission, int argArrayLength,
return changeVolumeLevel(fp,level,0);
}
+int handleMute(FILE * fp, unsigned int * permission, int argArrayLength,
+ char ** argArray)
+{
+ int status;
+ char * test;
+
+ status = strtol(argArray[1],&test,10);
+ if(*test!='\0') {
+ commandError(fp, ACK_ERROR_ARG, "need an integer", NULL);
+ return -1;
+ }
+ return setVolumeMuteStatus(fp,status);
+}
+
int handleRepeat(FILE * fp, unsigned int * permission, int argArrayLength,
char ** argArray)
{
@@ -942,6 +959,7 @@ void initCommands() {
addCommand(COMMAND_PREVIOUS ,PERMISSION_CONTROL, 0, 0,handlePrevious,NULL);
addCommand(COMMAND_LISTALL ,PERMISSION_READ, 0, 1,handleListAll,NULL);
addCommand(COMMAND_VOLUME ,PERMISSION_CONTROL, 1, 1,handleVolume,NULL);
+ addCommand(COMMAND_MUTE ,PERMISSION_CONTROL, 1, 1,handleMute,NULL);
addCommand(COMMAND_REPEAT ,PERMISSION_CONTROL, 1, 1,handleRepeat,NULL);
addCommand(COMMAND_RANDOM ,PERMISSION_CONTROL, 1, 1,handleRandom,NULL);
addCommand(COMMAND_STATS ,PERMISSION_READ, 0, 0,handleStats,NULL);
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;
+ }
+}
diff --git a/src/volume.h b/src/volume.h
index efd4e158c..922512e2e 100644
--- a/src/volume.h
+++ b/src/volume.h
@@ -37,4 +37,8 @@ int getVolumeLevel();
int changeVolumeLevel(FILE * fp, int change, int rel);
+int getVolumeMuteStatus();
+
+int setVolumeMuteStatus(FILE * fp, int status);
+
#endif