0

High resolution multi-zone synchronised streaming solution with DAC8X and IQaudIO

Sharing my multi-zone music project and specifically how I employed the DAC8X... 
 
I've been wanting to replace my existing Sonos whole home audio system for a while. It functions adequately but is limited to 44100 16-bit stereo and the DACs aren't very good either. RPi's seemed an obvious choice of device and when the DAC8X was released I started planning the replacement. Thanks to  HiFiBerry support on this forum. 
 
Existing environment: 
- Streamers: Several Sonos S1 Connect and Play:5 devices. All units configured wireless only. 
- Media server: Mac Mini (also runs JRiver for theatre - separate setup). Connected to Ethernet switch. 
- Media: Formats: FLAC, DTS HD MA and DTS 5.1. Channels: 2, 6 and 8. Stored on USB 3 external drive connected to Mac Mini. 
- Network: Ubiquiti WiFi6 APs (3). 
- Power amplifiers: Rotel RKB-1508 (8 channel) and ICEpower 125ASX2 (2 channel). 
 
Minimum requirements for new solution: 
- Decode FLAC and DTS source material at playback time. 
- Convert 6 and 8 channel source material to stereo at playback time. 
- Equalise audio in the digital domain; several bands. 
- Resample to at least 96kHz using good quality algorithm at playback time. 
- 32-bit D to A conversion. 
- Synchronise playback across all zones. 
- Stream audio over WiFi to all zones. 
- Community support. 
- Reliable. 
- Cheaper than Sonos! 
I'm not aware of any off-the-shelf solution that meets these requirements.
 
My new system is as follows. 
Media player: RPi 4B 4GB running RaspiOS Bookworm, Mopidy, Mopidy-local, Mopidy-Iris, Mopidy-Pandora, Snapserver and Snapclient. The Mac disk volume containing the music files is mounted to a location configured in Mopidy.  I also configured a GStreamer pipeline that applies volume, Kaiser resampling, 10-band equalisation and 96000 S32LE 2 channel output. The Pi is on 5GHz network. 
 
Media streamer for living areas: RPi 5 4GB and DAC8X running Raspi OS Bookworm with DAC8X running 4 Snapclient instances each supporting one zone. The kernel detected the DAC8X upon adding the dtoverlay and rebooting - easy. I configured ALSA to split the DAC's 8 channels into 4 virtual stereo cards. No default sound card setting. No ~/.asoundrc file. RCA outputs connected to Rotel amplifier powering 8 Klipsch in-ceiling speakers for 4 stereo zones. Pi is on 5GHz network. 
Contents of /etc/asound.conf: 
# ALSA configuration to share stereo playback across all 4 3.5mm headphone outputs on DAC 8X.
#
# aplay -l shows the HiFiBerry DAC8X card as follows:
#       card 2: sndrpihifiberry [snd_rpi_hifiberry_dac8x], device 0: HifiBerry DAC8x HiFi pcm5102a-hifi-0 [HifiBerry DAC8x HiFi pcm5102a->
#         Subdevices: 0/1
#         Subdevice #0: subdevice #0
#
# Use the slave plugin to Define an alias for the 8 channel HiFiBerry DAC8X hardware sound card.
# The linux kernel knows this card as sndrpihifiberry. 
# The card only has one device (0) which provides all 8 channels.
pcm_slave.DAC8X_card {  # Name the alias for the hardware sound card
  pcm "hw:sndrpihifiberry,0" # Reference the card as it is known to the Linux kernel
  channels 8            # The card has 8 channels
# Define 4 virtual sound cards, each using 2 of the 8 available channels. 
# A virtual card can be referenced and used like a regular sound card. 
# There is a one-to-one relationship between virtual cards and snapclient instances
# ie one snapclient instance uses one virtual card to play stereo audio. 
# Each snapclient instance plays one audio zone. 
pcm.ZoneA {
  type plug;            # The plug plugin
  slave.pcm {
    type dshare         # dshare plugin allows sharing of multiple channels with more clients
    ipc_key 0264        # Unique key value used to identify the shared memory used to buffer audio
    slave DAC8X_card    # Reference the alias for the DAC8X sound card
    bindings [ 0 1 ]    # Bind 2 channels from the slave to this virtual card's 2 channels
  }
}
pcm.ZoneB {
  type plug;
  slave.pcm {
    type dshare
    ipc_key 0264
    slave DAC8X_card
    bindings [ 2 3 ]
  }
}
pcm.ZoneC {
  type plug;
  slave.pcm {
    type dshare
    ipc_key 0264
    slave DAC8X_card
    bindings [ 4 5 ]
  }
}
pcm.ZoneD {
  type plug;
  slave.pcm {
    type dshare
    ipc_key 0264
    slave DAC8X_card
    bindings [ 6 7 ]
  }
}
 
I also set up a media streamer for my office: RPi 4B 2GB and IQaudIO DAC running RaspiOS Bookworm and 1 Snapclient instance. RCA outputs connected to ICEpower amplifier powering 2 KEF speakers. 
 
Observations and tips: 
 
Sound quality: RPis with DAC8X and IQaudIO DACs sound much better than the Sonos Connect devices they replace. There is more detail and better channel separation.  If you use Mopidy, it is worth customising the GStreamer pipeline to improve audio quality. Here is mine (still being refined): 
 
output = audioconvert ! audio/x-raw,rate=96000,channels=2,format=F64LE 
! volume volume=0.5 
! audioresample resample-method=kaiser sinc-filter-mode=full quality=10 
! equalizer-10bands band0=+8.0 band1=+6.0 band2=+4.0 band3=+2.0 band4=-1.0 band5=-2.0 band6=-2.0 band7=-1.0 band8=-1.0 band9=-1.0
! audioconvert ! audio/x-raw,rate=96000,channels=2,format=S32LE 
! filesink location=/run/snapserver/snapfifo
 
Pi capacity: The Pi 4B and 5 have plenty of CPU, RAM and network and file I/O capacity for this purpose.  The GStreamer pipeline in particular is heavy work and the Pi 4 handles it easily. The Pi 5 easily streams 4 zones concurrently. 
 
Network performance: The Pi running Mopidy often shows 35Mbps network throughput when playing a multi-channel source eg 8 channel flac plus five 96000:32:2 streams to Snapclients). The Pi's initially wanted to use 2.4GHz so I band steered them to 5GHz using Ubiquity config.  Start with lower resolution audio (eg 44100 16 bit stereo) and work up to higher sample rates and sizes. Locate Pis in line of sight to router/AP if possible. Use Pi cases that don't block WiFi signal eg acrylic top rather than metal. I don't get audio dropouts. 
 
Happy to answer any questions and help anyone doing similar projects. 

2 comments

Please sign in to leave a comment.