Site logo
Stories around the Genode Operating System RSS feed
Josef Söntgen avatar

Audio pkgs with a twist for Sculpt


Managing the audio driver and mixer is somewhat involved as the generic pkgs require the use of a launcher for run-time changes. The “pkgs with config” mend this by storing the config in a file-system.

You can install the bsd_audio_drv_with_config and mixer_with_config pkg from my Sculpt depot located in the Multimedia section. They require two additional service routes:

  • file-system

    the service provider where the driver and mixer will store their configuration, recall_fs is a natural fit.

    The path of the audio driver config is <fs>/bsd_audio_drv_with_config/bsd_audio_drv.config whereas the mixer's config file is <fs>/mixer_with_config/mixer.config.

  • report

    the service provider where the driver and mixer will post their respective reports to, system_reports is a natural fit.

    The path of the audio driver report is <reports>/bsd_audio_drv_with_config/pci_audio_drv/mixer_state whereas the mixer's report is <reports>/mixer_with_config/mixer/channel_list.

With everything in place you can configure both components using the system-shell and vim at run-time.

In case of the driver you get its mixer state in the report that in return is used to configure it:

<mixer_state>
 <mixer field="inputs.dac-0:1" value="126,126"/>
 <mixer field="inputs.dac-2:3" value="126,126"/>
 <mixer field="record.adc-2:3_mute" value="off"/>
 <mixer field="record.adc-2:3" value="124,124"/>
 <mixer field="record.adc-0:1_mute" value="off"/>
 <mixer field="record.adc-0:1" value="124,124"/>
 <mixer field="inputs.mix_source" value="spkr3,mic2,beep"/>
 <mixer field="inputs.mix_spkr3" value="120,120"/>
 <mixer field="inputs.mix_mic2" value="120,120"/>
 <mixer field="inputs.mix_beep" value="120,120"/>
 <mixer field="inputs.mix2_source" value="dac-0:1,mix"/>
 <mixer field="inputs.mix3_source" value="dac-2:3,mix"/>
 <mixer field="inputs.mix4_source" value="dac-0:1,dac-2:3"/>
 <mixer field="inputs.mic" value="85,85"/>
 <mixer field="outputs.spkr_source" value="mix3"/>
 <mixer field="outputs.spkr_mute" value="off"/>
 <mixer field="outputs.spkr_eapd" value="on"/>
 <mixer field="outputs.hp_source" value="mix2"/>
 <mixer field="outputs.hp_mute" value="off"/>
 <mixer field="outputs.hp_boost" value="off"/>
 <mixer field="outputs.hp_eapd" value="on"/>
 <mixer field="outputs.spkr2_source" value="mix2"/>
 <mixer field="outputs.spkr2_mute" value="off"/>
 <mixer field="outputs.spkr2_boost" value="off"/>
 <mixer field="outputs.spkr2_eapd" value="on"/>
 <mixer field="inputs.spkr3" value="85,85"/>
 <mixer field="inputs.mic2" value="85,85"/>
 <mixer field="outputs.mic2_dir" value="input-vr80"/>
 <mixer field="record.adc-0:1_source" value="mic"/>
 <mixer field="record.adc-2:3_source" value="spkr3"/>
 <mixer field="outputs.hp_sense" value="unplugged"/>
 <mixer field="outputs.mic2_sense" value="unplugged"/>
 <mixer field="outputs.spkr_muters" value="hp"/>
 <mixer field="outputs.master" value="126,126"/>
 <mixer field="outputs.mute" value="off"/>
 <mixer field="outputs.slaves" value="dac-0:1,dac-2:3,spkr,hp,spkr2"/>
 <mixer field="record.volume" value="124,124"/>
 <mixer field="record.mute" value="off"/>
 <mixer field="record.slaves" value="adc-2:3,adc-0:1"/>
 <mixer field="record.enable" value="sysctl"/>
</mixer_state>

You might have spotted the <mixer field="outputs.master" value="126,126"/> entry. Putting

<config>
 <mixer field="outputs.master" value="255"/>
</config>

into the config will raise the volume to its maximum (if you omit the second value it is applied to both channels).

In case of the mixer the report contains the list of active channels:

<channel_list>
 <channel type="output" label="master" name="left" number="0" active="1" volume="100" muted="false"/>
 <channel type="output" label="master" name="right" number="1" active="1" volume="100" muted="false"/>
 <channel type="input" label="cmus -> cmus" name="left  number="0" active="1" volume="50" muted="false"/>
 <channel type="input" label="cmus -> cmus" name="right" number="1" active="1" volume="50" muted="false"/>
</channel_list>

Those can be added to the config:

<config>
 <default out_volume="75" volume="25" muted="false"/>
 <channel_list>
  <channel type="output" label="master" name="left" number="0" active="1" volume="100" muted="false"/>
  <channel type="output" label="master" name="right" number="1" active="1" volume="100" muted="false"/>
  <channel type="input" label="cmus -> cmus" name="left" number="0" active="1" volume="50" muted="false"/>
  <channel type="input" label="cmus -> cmus" name="right" number="1" active="1" volume="50" muted="false"/>
 </channel_list>
</config>

The default node configures the initial volume setting that is applied when no matching channel configuration is found.

More detailed information on how to configure both components can be found in the corresponding README file (repos/dde_bsd/README, repos/os/src/server/mixer/README) in the Genode repository.

As an additional goody there is also a packaged mixer that contains a Qt5-based GUI, gui_mixer_qt, that provides sliders for managing the volume. It works okay in practice but it is not well polished so the UX suffers a bit.