2008-11-01

Pulseaudio: controlling your volume needs

To get the most volume out of ones speakers (literally) one must first make sure that the underlying sound systems have their volumes at 100%. In my case pulseaudio runs on top of alsa and I had to run

alsamixer -c0

and maximize the needed outputs.

Moving on to PulseAudio I put these lines in my system.pa:

### Automatically restore the volume of streams and devices
load-module module-stream-restore
load-module module-device-restore

# Set some default volumes
load-module module-match table=/etc/pulse/match.table

I think it should be pretty self-explanatory.

Lastly, about the last line, I did not use module-match in my initial configuration, but having the ability to make a stream sound higher than the others made me add it. The basic problem here is that all streams get 100% volume at creation and to have a stream louder than the others forces one to lower all the other streams.

The solution is to use the module-match module, it reads its settings from a simple table formatted like this:

regexp volume
regexp volume
...

(Notice the space separator, this makes the regexps a bit harder to write)

regexp is a (I find out after digging in the source) Posix Extended Regular Expression
volume is the volume, the range is 0-65535 (= 0%-100%)

As I wanted all streams to start at 50% I made this table.

32767

(There's a space character before 32767)

Matching every stream and setting them to 50% (65536/2 - 1) the problem was solved.

I thought.

It turns out that my nicely remapped outputs (see my previous post) have their own remapped streams which of course also were turned to 50%.

As Posix Extended Regular Expressions does not, as far as I know, have any look-behind/ahead or don't-match-this-string functionality I figured that putting the rules in the right order would make my setup work. The documentation is very sparse so I did what one should not do: depend on the internals. The relevant loop is

for (r = u->rules; r; r = r->next) {
if (!regexec(&r->regex, n, 0, NULL, 0)) {
pa_cvolume cv;
pa_log_debug("changing volume of sink input '%s' to 0x%03x", n, r->volume);
pa_cvolume_set(&cv, si->sample_spec.channels, r->volume);
pa_sink_input_set_volume(si, &cv);
}
}

and as one can see the last rule wins. (I would have thought it would have been faster just terminating at the first hit, but what do I know ;))

This gives the final table:

32767
^Remapped.Stream$ 65535

(I used a dot between the words as using a space is not possible. It would probably have been more effective to use the hex code, or maybe [[:space:]])

2 comments:

Joakim said...
This comment has been removed by the author.
Joakim said...

Oh, sett till att komma med i bloggimporten nu ocksÄ ser jag, extra duktig sak =p :)