Playing Audio over an USB Audio Interface on a Raspberry Pi from the Command-line
The Raspberry Pi powering our status screen is also connected to our office doorbell: Everytime someone rings the bell, the Pi plays a short audio file.
The Pi features an onboard audio output, but its quality is rather poor. So we decided to use an external USB audio interface instead. But how do we make the Pi use the external interface instead of its own audio output?
Also, all these tutorials talk about changing the Pi’s default audio output. This may be necessary in some circumstances, but often it’s not: Insteads simply specify the desired output each time a command to play some audio is run, and boom – we don’t have to care about the defaults at all.
Now let’s see how this works (note that this guide is for the current – November 2017 – version of Raspian Stretch Lite, but it should also work with Raspian Stretch Desktop).
Find the Correct “PCM Device”
The “PCM device” is the argument we’ll need to provide to
aplay, telling it which audio interface to use. How do we find it? Let’s have a look at the full list of devices
aplay knows about:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 $ aplay -L null Discard all samples (playback) or generate zero samples (capture) default:CARD=ALSA bcm2835 ALSA, bcm2835 ALSA Default Audio Device sysdefault:CARD=ALSA bcm2835 ALSA, bcm2835 ALSA Default Audio Device dmix:CARD=ALSA,DEV=0 bcm2835 ALSA, bcm2835 ALSA Direct sample mixing device […] default:CARD=Device USB Audio Device, USB Audio Default Audio Device sysdefault:CARD=Device USB Audio Device, USB Audio Default Audio Device front:CARD=Device,DEV=0 USB Audio Device, USB Audio Front speakers […]
One of the entries should look like
default:CARD=Device with an explanation like “USB Audio Device, Default Audio Device” next to is – that’s the one you’re looking for. Remember its name.
Play Sound from the Command-line
Once the correct PCM device is known, use
aplay to play a wave file over this interface:
1 $ aplay -D default:CARD=Device doorbell.wav
Adjusting the Volume from the Command-line
For adjusting the volume we’ll use
amixer. Unfortunately, you can’t use the same PCM device here – instead you have to provide the “card number”. This will most probably be “1” (“0” being the Pi’s internal audio device), but just try it out and check the device description:
1 2 3 4 5 6 7 $ amixer -c 1 info Card hw:1 'Device'/'C-Media Electronics Inc. USB Audio Device at usb-3f980000.usb-1.5, full speed' Mixer name : 'USB Mixer' Components : 'USB0d8c:0014' Controls : 9 Simple ctrls : 3
If the device description does not look like the audio interface you want to use, try
-c 2 instead (and so on).
Now we need to find out the correct “control” (most soundcards have multiple controls for things like “playback volume”, “microphone volume” etc.):
1 2 3 4 5 6 7 8 9 10 11 $ amixer -c 1 controls numid=3,iface=MIXER,name='Mic Playback Switch' numid=4,iface=MIXER,name='Mic Playback Volume' numid=7,iface=MIXER,name='Mic Capture Switch' numid=8,iface=MIXER,name='Mic Capture Volume' numid=9,iface=MIXER,name='Auto Gain Control' numid=5,iface=MIXER,name='Speaker Playback Switch' numid=6,iface=MIXER,name='Speaker Playback Volume' numid=2,iface=PCM,name='Capture Channel Map' numid=1,iface=PCM,name='Playback Channel Map'
We’re interested in the “Speaker Playback Volume” control. Note that it’s named
numid=6. Let’s have a look at its current value:
1 2 3 4 5 6 $ amixer -c 1 cget numid=6 numid=6,iface=MIXER,name='Speaker Playback Volume' ; type=INTEGER,access=rw---R--,values=2,min=0,max=37,step=0 : values=16,16 | dBminmaxmute-min=-37.00dB,max=0.00dB
Parsing this we understand that this control has two integer values with an allowed range of 0 to 37. Currently both values are set to 16. Apparently this control lets us set the volume for both stereo channels separately, and currently the volume is set to about 50%.
Now we know everything needed to construct a single command to set the volume to 100%:
1 $ amixer -c 1 cset numid=6 37,37
amixer to set the volume control (
numid=6) of the second sound card (
-c 1) to the values
37, 37 (100%).
TL;DR: Just Turn up the Volume and Play me a Sound!
Simply combine both commands from the previous sections:
1 $ amixer -c 1 cset numid=6 37,37; aplay -D default:CARD=Device doorbell.wav
And this is exactly what we use in our doorbell application.
Thinking about an IoT project, needing a prototype? We can do both, hardware and software.