ALSA and Pulseaudio random jots
Background
This is just things I wrote down while trying to make aplay play sound through a fake module-based Pulseaudio sink. Spoiler: I failed.
Spoiler II: Sometimes people ask me question about posts I write. I don’t think I’ll answer any on this post. I’ll probably forget all about this five minutes from now.
So –
It all worked fine as long as there was only one of those sinks, because it was set to the default of Pulseaudio, and apparently aplay was ready to consider Pulseaudio as a sound card, playing sound to whatever the user configured as its sink (on Pulseaudio’s configuration interface). But what if I wanted two of those at the same time. Problem.
The following segment in /etc/pulse/default.pa indeed creates two sources and sinks in Pulseaudio’s environment:
load-module module-file-sink file=/dev/xillybus_audio rate=48000 load-module module-file-source file=/dev/xillybus_audio rate=48000 load-module module-file-sink file=/dev/xillybus_audio2 rate=48000 load-module module-file-source file=/dev/xillybus_audio2 rate=48000
Using “pacmd list-sources” and “pacmd list-sinks”, I have found Pulseaudio’s names for these, so that it’s possible to record and play with
parecord -d 'fifo_input' --file-format=wav --rate=44100 > junk.wav
or
parecord -d 'fifo_input.2' --file-format=wav --rate=44100 > junk.wav
and then play the sound back with
paplay -d 'fifo_output' junk.wav
or
paplay -d 'fifo_output.2' junk.wav
And there’s always the possibility to fake old-style /dev/dsp devices with padsp, and use them with whatever application that work with these.
ALSA random jots
/usr/share/alsa/alsa.conf defines the well-known PCM names “hw:” included, as pcm.hw { … } and also lists the other files to look at. So it’s definitely the place to start looking for understanding those name conventions. Or maybe the ‘hw:” prefix is no more than a reference to the ALSA hw plugin…?
The device’s name is used in aplay when in calls snd_pcm_open(), which is an alsa-lib call. In other words, aplay doesn’t use Pulseaudio in this case.
It’s part of alsa-lib, in src/pcm/pcm.c. This function calls snd_pcm_open_noupdate(), which in turn calls snd_config_search_definition() with the device name. If it returns with an error, we get the
ALSA lib pcm.c:2217:(snd_pcm_open_noupdate) Unknown PCM fifo_input arecord: main:682: audio open error: No such file or directory
snd_config_search_definition() is defined in src/conf.c. It strips off anything after a ‘:’ (if such exists) and calls snd_config_search_alias_hooks() with the stripped name. So crucial question seems to be how to convince pulseaudio to inject an alias to the file sink, as it does when it’s the default.
It looks like snd_device_name_hint() is useful (supersedes the deprecated snd_names_list() in src/names.c). The following C code snippet (found here)
{ char **hints; /* Enumerate sound devices */ int err = snd_device_name_hint(-1, "pcm", (void***)&hints); if (err != 0) return;//Error! Just return char** n = hints; while (*n != NULL) { char *name = snd_device_name_get_hint(*n, "NAME"); if (name != NULL && 0 != strcmp("null", name)) { printf("Name hint: %s\n", name); free(name); } n++; } snd_device_name_free_hint((void**)hints); }
prints out (on my PC, note that the “hw” name isn’t listed).
Name hint: default Name hint: front:CARD=Intel,DEV=0 Name hint: surround40:CARD=Intel,DEV=0 Name hint: surround41:CARD=Intel,DEV=0 Name hint: surround50:CARD=Intel,DEV=0 Name hint: surround51:CARD=Intel,DEV=0 Name hint: surround71:CARD=Intel,DEV=0 Name hint: iec958:CARD=Intel,DEV=0 Name hint: hdmi:CARD=HDMI
BTW, when Pulseaudio is shut down on a machine where only “default” is listed (no ALSA cards), “default” goes away, and there’s “pulse” instead.
This page talks about ALSA tweaking.
The format of the asound.conf file is described on this page. The C library reference, mentioning the naming convention is here.
Pulseaudio jot
Download pulseaudio’s source with
git clone git://anongit.freedesktop.org/pulseaudio/pulseaudio
An interesting function is pa_alsa_source_new() in src/modules/alsa/alsa-source.c.