From 3922f1c36f8d8e60f8537bcaead0422129ec58dd Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Wed, 1 Oct 2014 15:32:02 +0200 Subject: Add mute/unmute functions. REflect new functionality in aiomixer. --- src/aiomixer.cc | 78 +++++++++++++++++++++++++++++++++++++++++++-------------- src/audioio.cc | 34 +++++++++++++++++++++++++ src/audioio.h | 11 ++++++++ src/mixer.cc | 33 ++++++++++++++++++++++++ src/mixer.h | 10 ++++++++ 5 files changed, 147 insertions(+), 19 deletions(-) diff --git a/src/aiomixer.cc b/src/aiomixer.cc index 14d2e8a..dbf1ef1 100644 --- a/src/aiomixer.cc +++ b/src/aiomixer.cc @@ -56,6 +56,8 @@ static const char usage_str[] = " -C, --channels Get number of channels in mixer\n" " -l, --level n=m Set level of channel n to value m\n" " -l, --level n Get level of channel n\n" +" -m, --mute Get mute state\n" +" -m, --mute m Set mute state to m. either 1 (mute) or 0 (unmute)\n" " -r, --range Get range of mixer\n" " -c, --capture Get capture mode.\n" " -c, --capture n Set capture mode to n (1 or 0).\n" @@ -73,24 +75,36 @@ int main(int argc, char *argv[]) bool list_enums = false; bool range = false; bool num_channels = false; - + + bool show_mute = false; + int set_mute = -1; + + bool show_capture = false; + int set_capture = -1; + std::string enum_value; - std::string level_name; - std::string level_value; + int level_name = -1; + float level_value = -999999; int option_index = 0; while(1) { static struct option long_options[] = { {"list", no_argument, 0, 'L'}, + {"list-enum", no_argument, 0, 'E'}, {"enum", optional_argument, 0, 'e'}, + {"channels", no_argument, 0, 'C'}, {"level", required_argument, 0, 'l'}, + {"mute", optional_argument, 0, 'm'}, + {"range", no_argument, 0, 'r'}, + {"capture", optional_argument, 0, 'c'}, {"version", no_argument, 0, 'v'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; - c = getopt_long (argc, argv, "hvLe::l::rcE", long_options, &option_index); + c = getopt_long (argc, argv, "hvLe::l::rEm::Cc::", + long_options, &option_index); if (c == -1) break; @@ -104,10 +118,20 @@ int main(int argc, char *argv[]) range = true; break; - case 'c': + case 'C': num_channels = true; break; + case 'm': + if(!optarg) show_mute = true; + else set_mute = atoi(optarg); + break; + + case 'c': + if(!optarg) show_capture = true; + else set_capture = atoi(optarg); + break; + case 'E': list_enums = true; break; @@ -121,9 +145,9 @@ int main(int argc, char *argv[]) p = strchr(optarg, '='); if(p) { *p = '\0'; - level_value = p+1; + level_value = atof(p+1); } - level_name = optarg; + level_name = atoi(optarg); break; case '?': @@ -192,17 +216,15 @@ int main(int argc, char *argv[]) printf("Number of channels: %d\n", num); } - /* - for(int i = 0; i < num; i++) { - printf("Channel: %d\n", i); - float val = mix->level(i); - printf(" Level %fdB\n", val); - mix->setLevel(i, val - 1.1); - printf(" Level %fdB\n", mix->level(i)); - mix->setLevel(i, val); - printf(" Level %fdB\n", mix->level(i)); + if(level_name != -1) { + if(level_value > -999999) { + printf("Set channel %d level to %fdB\n", level_name, level_value); + mix->setLevel(level_name, level_value); + } else { + float l = mix->level(level_name); + printf("Channel %d level: %fdB\n", level_name, l); } - */ + } if(list_enums) { std::vector evs = mix->enumValues(); @@ -225,8 +247,26 @@ int main(int argc, char *argv[]) printf("Enum value: '%s'\n", ev.c_str()); } - // bool capt = mix->capture(); - // mix->setCapture(!capt); + if(show_mute) { + bool mute = mix->muted(); + printf("Mute value: %d\n", mute?1:0); + } + + if(set_mute != -1) { + printf("Set mute value: %d\n", set_mute); + mix->setMuted(set_mute==1?true:false); + } + + if(show_capture) { + bool capture = mix->capture(); + printf("Capture value: %d\n", capture?1:0); + } + + if(set_capture != -1) { + printf("Set capture value: %d\n", set_capture); + mix->setCapture(set_capture==1?true:false); + } + delete mix; } diff --git a/src/audioio.cc b/src/audioio.cc index f85ec11..eec9836 100644 --- a/src/audioio.cc +++ b/src/audioio.cc @@ -261,6 +261,40 @@ int aio_set_enum_value(struct aio_t *h, const char *name, const char *value) return 0; } +int aio_set_mute(struct aio_t *h, const char *name, int muted) +{ + CHECK_HANDLE(h); + + Mixer *m = h->device->getMixer(name); + if(!m) return NO_SUCH_CHANNEL; + + if(!m->isPlayback()) { + delete m; + return NO_SUCH_CHANNEL; + } + + m->setMuted(muted); + + return 0; +} + +int aio_get_mute(struct aio_t *h, const char *name, int *muted) +{ + CHECK_HANDLE(h); + + Mixer *m = h->device->getMixer(name); + if(!m) return NO_SUCH_CHANNEL; + + if(!m->isPlayback()) { + delete m; + return NO_SUCH_CHANNEL; + } + + m->setMuted(muted); + + return 0; +} + int aio_get_samplerate(struct aio_t *h) { CHECK_HANDLE(h); diff --git a/src/audioio.h b/src/audioio.h index e78813b..5f62e27 100644 --- a/src/audioio.h +++ b/src/audioio.h @@ -46,6 +46,7 @@ extern "C" { #define COULD_NOT_OPEN_DEVICE -110 #define INVALID_MIXER_LEVEL -111 #define NO_SUCH_ENUM -112 +#define NO_SUCH_CHANNEL -113 struct aio_t; @@ -185,6 +186,16 @@ int aio_get_enum_value(struct aio_t *handle, const char *name, int aio_set_enum_value(struct aio_t *handle, const char *name, const char *value); +/** + * Set mute state of a named channel. + */ +int aio_set_mute(struct aio_t *handle, const char *name, int muted); + +/** + * Get mute state of a named channel. + */ +int aio_get_mute(struct aio_t *handle, const char *name, int *muted); + /** * Get actual samplerate. * The samplerate set in ai_init may or may not match a possible samplerate for diff --git a/src/mixer.cc b/src/mixer.cc index 00cf156..dd9202c 100644 --- a/src/mixer.cc +++ b/src/mixer.cc @@ -336,3 +336,36 @@ bool Mixer::capture() return true; } + +void Mixer::setMuted(bool muted) +{ + if(!isPlayback()) return; + int p = muted?0:1; + int err; + err = snd_mixer_selem_set_playback_switch_all(elem, p); + if(err) { + printf("snd_mixer_selem_set_playback_switch_all: %s, %d\n", + snd_strerror(err), err); + } +} + +bool Mixer::muted() +{ + if(!isPlayback()) return false; + + int err; + + int num = numberOfChannels(); + for(int idx = 0; idx < num; idx++) { + int value; + err = snd_mixer_selem_get_playback_switch(elem, chanId(idx), &value); + if(err) { + printf(" snd_mixer_selem_get_playback_switch: %s, %d\n", + snd_strerror(err), err); + return true; + } + if(value == 0) return true; + } + + return false; +} diff --git a/src/mixer.h b/src/mixer.h index a5e5a98..1ea471e 100644 --- a/src/mixer.h +++ b/src/mixer.h @@ -120,6 +120,16 @@ public: */ range_t range(); + /** + * Mute/unmute this mixer (only playback channels). + */ + void setMuted(bool muted); + + /** + * Get mute/unmute state of this mixer (only playback channels). + */ + bool muted(); + private: snd_mixer_selem_channel_id_t chanId(int idx); -- cgit v1.2.3