genode/repos/os/src/server/mixer
Norman Feske eba9c15746 Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:

* A class with virtual functions can no longer publicly inherit base
  classed without a vtable. The inherited object may either be moved
  to a member variable, or inherited privately. The latter would be
  used for classes that inherit 'List::Element' or 'Avl_node'. In order
  to enable the 'List' and 'Avl_tree' to access the meta data, the
  'List' must become a friend.

* Instead of adding a virtual destructor to abstract base classes,
  we inherit the new 'Interface' class, which contains a virtual
  destructor. This way, single-line abstract base classes can stay
  as compact as they are now. The 'Interface' utility resides in
  base/include/util/interface.h.

* With the new warnings enabled, all member variables must be explicitly
  initialized. Basic types may be initialized with '='. All other types
  are initialized with braces '{ ... }' or as class initializers. If
  basic types and non-basic types appear in a row, it is nice to only
  use the brace syntax (also for basic types) and align the braces.

* If a class contains pointers as members, it must now also provide a
  copy constructor and assignment operator. In the most cases, one
  would make them private, effectively disallowing the objects to be
  copied. Unfortunately, this warning cannot be fixed be inheriting
  our existing 'Noncopyable' class (the compiler fails to detect that
  the inheriting class cannot be copied and still gives the error).
  For now, we have to manually add declarations for both the copy
  constructor and assignment operator as private class members. Those
  declarations should be prepended with a comment like this:

        /*
         * Noncopyable
         */
        Thread(Thread const &);
        Thread &operator = (Thread const &);

  In the future, we should revisit these places and try to replace
  the pointers with references. In the presence of at least one
  reference member, the compiler would no longer implicitly generate
  a copy constructor. So we could remove the manual declaration.

Issue #465
2018-01-17 12:14:35 +01:00
..
mixer.cc Follow practices suggested by "Effective C++" 2018-01-17 12:14:35 +01:00
README mixer: add reporting and config handling 2015-11-18 12:22:07 +01:00
target.mk server/mixer: transition to new base API 2016-11-08 15:26:33 +01:00

The mixer component implements a simple Audio_out session mixer. Input
packets from multiple sources are mixed together into one output packet.


The mixer can be tested by executing the 'repos/os/run/mixer.run' run
script.


Configuration
=============

The mixer gets its configuration via a ROM module called 'mixer.config'.
The following configuration snippet illustrates its structure:

! <config>
!   <default out_volume="75" volume="25" muted="0"/>
!   <channel_list>
!     <channel type="input"  label="client" number="0" volume="75"  muted="1"/>
!     <channel type="input"  label="client" number="1" volume="15"  muted="1"/>
!     <channel type="output" label="master" number="0" volume="100" muted="0"/>
!     <channel type="output" label="master" number="1" volume="100" muted="0"/>
!   </channel_list>
! </config>

The '<default>' node is used to set up the initial settings for new clients.
According to this configuration every new client will start with a volume
level set to 25 and is not muted. The initial output volume level is set
to 75 (the volume level ranges from 0 to 100). The '<channel_list>' node
contains all (pre-)configured channels. Each '<channel>' node has several
mandatory attributes: 'type' specifies its type and is either 'input'
or 'output', the 'label' attribute contains the label of a client for an input
node and the label 'master' for an output node, 'number' specifies the channel
number (0 for left and 1 for right), the 'volume' attribute sets the volume
level and 'muted' marks the channel as muted. In addition, there are optional
read-only channel attributes which are mainly used by the channel list report.


Channel list report
===================

The mixer reports all available channels in its 'channel_list' report.
The report contains a `<channel_list>' node that is similar to the one
used in the 'mixer.config':

! <channel_list>
!   <channel type="input" label="client0" name="left"  number="0" active="1" volume="100" muted="0"/>
!   <channel type="input" label="client0" name="right" number="1" active="1" volume="100" muted="0"/>
!   <channel type="input" label="client1" name="left"  number="0" active="0" volume="25"  muted="0"/>
!   <channel type="input" label="client1" name="right" number="1" active="0" volume="25"  muted="0"/>
!   <channel type="output" label="master" name="left"  number="0" active="1" volume="100" muted="0"/>
!   <channel type="output" label="master" name="right" number="1" active="1" volume="100" muted="0"/>
! </channel_list>

Each channel node features all mandatory attributes as well as a few optional
ones. The 'name' attribute contains the name of the channel. It is the
alphanumeric description of the numeric 'number' attribute. The 'active'
attribute indicates whether a channel is currently playing or not.

A 'channel_list' report may by used to create a new configuration for the
mixer. Every time the available channels change, e.g. when a new client
appears, a new report is generated by the mixer. In return this report can
then be used to configure the volume level of the new client. A new report
is also generated after a new configuration has been applied by the mixer.