diff --git a/repos/os/src/server/mixer/mixer.cc b/repos/os/src/server/mixer/mixer.cc
index 8e9527693..346c36ea8 100644
--- a/repos/os/src/server/mixer/mixer.cc
+++ b/repos/os/src/server/mixer/mixer.cc
@@ -39,16 +39,6 @@
#include
-static bool verbose = false;
-
-template
-static inline void logv(ARGS&&... args)
-{
- if (verbose)
- Genode::log(args...);
-}
-
-
typedef Mixer::Channel Channel;
@@ -144,11 +134,25 @@ class Audio_out::Mixer
Genode::Attached_rom_dataspace _config_rom { env, "config" };
+ struct Verbose
+ {
+ bool const sessions;
+ bool const changes;
+
+ Verbose(Genode::Xml_node config)
+ :
+ sessions(config.attribute_value("verbose_sessions", false)),
+ changes(config.attribute_value("verbose_changes", false))
+ { }
+ };
+
+ Genode::Reconstructible _verbose { _config_rom.xml() };
+
/*
* Mixer output Audio_out connection
*/
Connection _left { env, "left", false, true };
- Connection _right { env, "right", false, true };;
+ Connection _right { env, "right", false, false };
Connection *_out[MAX_CHANNELS];
float _out_volume[MAX_CHANNELS];
@@ -193,7 +197,7 @@ class Audio_out::Mixer
*
* Each session in a channel is reported as an input node.
*/
- Genode::Reporter reporter { env, "channel_list" };
+ Genode::Reporter _reporter { env, "channel_list" };
/**
* Report available channels
@@ -203,10 +207,8 @@ class Audio_out::Mixer
*/
void _report_channels()
{
- reporter.enabled(true);
-
try {
- Genode::Reporter::Xml_generator xml(reporter, [&] () {
+ Genode::Reporter::Xml_generator xml(_reporter, [&] () {
/* output channels */
for_each_index(MAX_CHANNELS, [&] (int const i) {
Channel::Number const num = (Channel::Number)i;
@@ -219,7 +221,7 @@ class Audio_out::Mixer
xml.attribute("name", name);
xml.attribute("number", (int)num);
xml.attribute("volume", (int)vol);
- xml.attribute("muted", (long)0);
+ xml.attribute("muted", false);
});
});
@@ -347,7 +349,8 @@ class Audio_out::Mixer
*/
[&] {
sc->for_each_session([&] (Session_elem &session) {
- if (session.stopped() || session.muted) return;
+ if (session.stopped() || session.muted || session.volume < 0.01f)
+ return;
Packet *in = session.get_packet(offset);
@@ -419,8 +422,10 @@ class Audio_out::Mixer
*/
void _set_default_config(Genode::Xml_node const &node)
{
+ using namespace Genode;
+
try {
- Genode::Xml_node default_node = node.sub_node("default");
+ Xml_node default_node = node.sub_node("default");
long v = 0;
v = default_node.attribute_value("out_volume", 0);
@@ -429,13 +434,15 @@ class Audio_out::Mixer
v = default_node.attribute_value("volume", 0);
_default_volume = (float)v / MAX_VOLUME;
- v = default_node.attribute_value("muted", 1);
+ v = default_node.attribute_value("muted", false);
_default_muted = v ;
- logv("default settings: "
- "out_volume: ", (int)(MAX_VOLUME*_default_out_volume), " "
- "volume: ", (int)(MAX_VOLUME*_default_volume), " "
- "muted: ", _default_muted);
+ if (_verbose->changes) {
+ log("Set default "
+ "out_volume: ", (int)(MAX_VOLUME*_default_out_volume), " "
+ "volume: ", (int)(MAX_VOLUME*_default_volume), " "
+ "muted: ", _default_muted);
+ }
} catch (...) { Genode::warning("could not read mixer default values"); }
}
@@ -450,10 +457,14 @@ class Audio_out::Mixer
_config_rom.update();
Xml_node config_node = _config_rom.xml();
- verbose = config_node.attribute_value("verbose", verbose);
+ _verbose.construct(config_node);
_set_default_config(config_node);
+ /* reset out volume in case there is no 'channel_list' node */
+ _out_volume[LEFT] = _default_out_volume;
+ _out_volume[RIGHT] = _default_out_volume;
+
try {
Xml_node channel_list_node = config_node.sub_node("channel_list");
@@ -462,6 +473,7 @@ class Audio_out::Mixer
if (ch.type == Channel::Type::INPUT) {
_for_each_channel([&] (Channel::Number, Session_channel *sc) {
+
sc->for_each_session([&] (Session_elem &session) {
if (session.number != ch.number) return;
if (session.label != ch.label) return;
@@ -469,10 +481,13 @@ class Audio_out::Mixer
session.volume = (float)ch.volume / MAX_VOLUME;
session.muted = ch.muted;
- logv("label: '", ch.label, "' "
- "nr: ", (int)ch.number, " "
- "vol: ", (int)(MAX_VOLUME*session.volume), " "
- "muted: ", ch.muted);
+ if (_verbose->changes) {
+ log("Set label: '", ch.label, "' "
+ "channel: '", string_from_number(ch.number), "' "
+ "nr: ", (int)ch.number, " "
+ "volume: ", (int)(MAX_VOLUME*session.volume), " "
+ "muted: ", ch.muted);
+ }
});
});
}
@@ -482,14 +497,19 @@ class Audio_out::Mixer
_out_volume[i] = (float)ch.volume / MAX_VOLUME;
- logv("label: 'master' "
- "nr: ", (int)ch.number, " "
- "vol: ", (int)(MAX_VOLUME*_out_volume[i]), " "
- "muted: ", ch.muted);
+ if (_verbose->changes) {
+ log("Set label: 'master' "
+ "channel: '", string_from_number(ch.number), "' "
+ "nr: ", (int)ch.number, " "
+ "volume: ", (int)(MAX_VOLUME*_out_volume[i]), " "
+ "muted: ", ch.muted);
+ }
});
}
});
- } catch (...) { Genode::warning("mixer channel_list was invalid"); }
+ } catch (Xml_node::Nonexistent_sub_node) {
+ Genode::warning("channel_list node missing");
+ }
/*
* Report back any changes so a front-end can update its state
@@ -519,6 +539,8 @@ class Audio_out::Mixer
*/
Mixer(Genode::Env &env) : env(env)
{
+ _reporter.enabled(true);
+
_out[LEFT] = &_left;
_out[RIGHT] = &_right;
@@ -527,8 +549,6 @@ class Audio_out::Mixer
_config_rom.sigh(_handler_config);
_handle_config_update();
-
- _report_channels();
}
/**
@@ -562,11 +582,13 @@ class Audio_out::Mixer
session.volume = _default_volume;
session.muted = _default_muted;
- log("add label: \"", session.label, "\" "
- "channel: \"", string_from_number(ch), "\" "
- "nr: ", (int)ch, " "
- "volume: ", (int)(MAX_VOLUME*session.volume), " "
- "muted: ", session.muted);
+ if (_verbose->sessions) {
+ log("Add label: '", session.label, "' "
+ "channel: '", string_from_number(ch), "' "
+ "nr: ", (int)ch, " "
+ "volume: ", (int)(MAX_VOLUME*session.volume), " "
+ "muted: ", session.muted);
+ }
_channels[ch].insert(&session);
_report_channels();
@@ -577,9 +599,11 @@ class Audio_out::Mixer
*/
void remove_session(Channel::Number ch, Session_elem &session)
{
- log("remove label: \"", session.label, "\" "
- "channel: \"", string_from_number(ch), "\" "
- "nr: ", (int)ch);
+ if (_verbose->sessions) {
+ log("Remove label: '", session.label, "' "
+ "channel: '", string_from_number(ch), "' "
+ "nr: ", (int)ch);
+ }
_channels[ch].remove(&session);
_report_channels();
@@ -657,10 +681,12 @@ class Audio_out::Root : public Audio_out::Root_component
{
using namespace Genode;
- char label[MAX_LABEL_LEN];
- Arg_string::find_arg(args, "label").string(label,
- sizeof(label),
- "");
+ /*
+ * We only want to have the last part of the lable,
+ * e.g. 'client -> ' => 'client'.
+ */
+ Session_label const session_label = label_from_args(args);
+ Session_label const label = session_label.prefix();
char channel_name[MAX_CHANNEL_NAME_LEN];
Arg_string::find_arg(args, "channel").string(channel_name,
@@ -684,7 +710,7 @@ class Audio_out::Root : public Audio_out::Root_component
throw Genode::Service_denied();
Session_component *session = new (md_alloc())
- Session_component(_env, label, (Channel::Number)ch, _mixer);
+ Session_component(_env, label.string(), (Channel::Number)ch, _mixer);
if (++_sessions == 1) _mixer.start();
return session;