AirPlay, Shairport Sync, ALSA and Volume Control
This is a quick post about AirPlay, Shairport Sync, ALSA and volume control. I mainly play vinyl but when I stream Spotify I usually do it from my Mac to my DIY AirPlay receiver. It is built around a Raspberry Pi 2 Model B with a HiFiBerry DAC+ running Shairport Sync. I can not praise Mike Brady enough for the time and effort he has put into this stellar piece of software.
The HiFiBerry DAC+ is capable of outputting some 2 Vrms but I wanted to explore the difference between the different options for volume control. Why? Because the Spotify application got a volume control. My Mac got a volume output setting (often controlled by the keys F12 (volume up) and F11 (volume down). My AirPlay receiver got volume control in ALSA and Shairport Sync. How does it all add up? This is what drove me to make some tests and I am documenting my results in case it might be of interest for somebody else.
I conducted these tests sending a test signal (1 kHz) from my Mac over AirPlay to my AirPlay receiver. I measured the output voltage from the HiFiBerry DAC+ with a true Vrms digital multi-meter. The test signal was measured for each step of the volume control on the Mac. From 0% (mute) up to 100%. I used the resolution of the F11 and F12 buttons. These are the steps on the Mac in percent:
100 |
94 |
88 |
81 |
75 |
69 |
63 |
56 |
50 |
44 |
38 |
31 |
25 |
19 |
13 |
6 |
0 |
And this is how they plot in a chart:
It seems totally linear compared to the logarithmic volume control (stepped attenuator) on my preamp:
But the stepped attenuator is expressed in dB so how is the linear percentage on the Mac volume control mapped to output voltage on my AirPlay receiver? Shairport Sync is using software volume control by default. It also uses the mixer's native range and a standard profile (somewhat logarithmic) by default. This can all be configured to your liking.
The easiest way to measure how the volume control in percentage on my Mac is translated to my AirPlay receiver is to reconfigure Shairport Sync to use hardware volume control and read the corresponding value in alsamixer. This is what I got with the mixer's native range, standard and flat profile:
AirPlay % |
ALSA HW Standard % |
ALSA HW Flat % |
100 |
100 |
100 |
94 |
87 |
78 |
88 |
78 |
61 |
81 |
68 |
47 |
75 |
61 |
37 |
69 |
53 |
29 |
63 |
47 |
22 |
56 |
38 |
17 |
50 |
30 |
14 |
44 |
24 |
11 |
38 |
20 |
8 |
31 |
16 |
7 |
25 |
12 |
5 |
19 |
10 |
4 |
13 |
6 |
3 |
6 |
3 |
2 |
0 |
2 |
2 |
And this is what it looks like in a chart:
I find it a bit strange that the flat profile seems more logarithmic than the standard profile.
But this is all in percent what about dB and Vrms? And is there any differences between hardware and software volume control? These are the Vrms values measured for each step (the values for software volume control was taken with ALSA mixer @ 100%):
ALSA HW Standard Vrms |
ALSA HW Flat Vrms |
ALSA SW Standard Vrms |
ALSA SW Flat Vrms |
2,127 |
2,127 |
2,128 |
2,127 |
1,418 |
1,0051 |
1,5001 |
1,0621 |
1,0051 |
0,4766 |
1,0621 |
0,5322 |
0,6725 |
0,2258 |
0,7519 |
0,2665 |
0,4765 |
0,1069 |
0,5322 |
0,1334 |
0,3187 |
0,0505 |
0.3767 |
0,0667 |
0,2258 |
0,0238 |
0,2665 |
0,0332 |
0,1132 |
0,0111 |
0,1429 |
0,0164 |
0,06 |
0,0055 |
0,0766 |
0,0080 |
0,0299 |
0,0025 |
0,0409 |
0,0040 |
0,0157 |
0,0014 |
0,0218 |
0,0020 |
0,0078 |
0,001 |
0,0115 |
0,0013 |
0,0041 |
0,0008 |
0,0061 |
0,0010 |
0,002 |
0,0009 |
0,0031 |
0,0009 |
0,0014 |
0,0009 |
0,0012 |
0,0009 |
0,001 |
0,0009 |
0,0010 |
0,0009 |
0,0009 |
0,0009 |
0,0009 |
0,0009 |
And this is what it looks like in a chart:
My takeaway from this is that it is no major difference from a Vrms point of view between hardware and software volume control. But it might depend on your native range. My HiFiBerry DAC+ got a native range of 0..-103.5 dB, amixer reports:numid=1,iface=MIXER,name='Digital Playback Volume'
; type=INTEGER,access=rw---R--,values=2,min=0,max=207,step=0
: values=157,157
| dBscale-min=-103.50dB,step=0.50dB,mute=1
To me this is far from optimal. My preamps stepped attenuator got a range of 0..-62 dB and I think that is pretty perfect. One way to correct this is to use the volume_range_db setting in Shairport Sync. This is the difference between the native mixer range (default) and volume_range_db = 60;
AirPlay % |
ALSA HW Standard % |
ALSA HW Standard Vrms |
ALSA HW Standard 60dB % |
ALSA HW Standard 60dB Vrms |
100 |
100 |
2,127 |
100 |
2,128 |
94 |
87 |
1,418 |
93 |
1,6842 |
88 |
78 |
1,0051 |
86 |
1,3391 |
81 |
68 |
0,6725 |
79 |
1,0645 |
75 |
61 |
0,4765 |
75 |
0,8962 |
69 |
53 |
0,3187 |
69 |
0,7123 |
63 |
47 |
0,2258 |
64 |
0,5662 |
56 |
38 |
0,1132 |
56 |
0,3788 |
50 |
30 |
0,06 |
50 |
0,2683 |
44 |
24 |
0,0299 |
44 |
0,1794 |
38 |
20 |
0,0157 |
38 |
0,1200 |
31 |
16 |
0,0078 |
33 |
0,0802 |
25 |
12 |
0,0041 |
30 |
0,0567 |
19 |
10 |
0,002 |
26 |
0,0378 |
13 |
6 |
0,0014 |
19 |
0,0155 |
6 |
3 |
0,001 |
14 |
0,0055 |
0 |
2 |
0,0009 |
2 |
0,0014 |
And this is what it looks like in charts:
Is this useful? Lets say you feed your Airplay receiver to a preamp with an input sensitivity of 1.0 Vrms. You also want the AirPlay volume control to span 0..-60 dB. Using my Airplay receiver as an example the output of the Airplay Receiver can be as much as 2.128 Vrms. ALSA HW Standard 60 dB equals 1.0645 Vrms @ 79%. Set ALSA mixer to 79% (and save it with "sudo alsactl store") and use Shairport Sync software volume control with volume_range_db = 60; Max volume will now be 1.0645 Vrms and the range of the volume control will be 0..-60 dB.
With flexibility comes complexity but sometimes it is needed to get things totally right...