Multi-Zone Audio System

In August 9, 2016
3854 Views

My DIY Multi-Zone Audio System is powered by a server running the Logitech Media Server software at the back end and Raspberry Pi Zeros as ‘zone’ players. The full system is a very cheap alternative to other commercial systems available on the market, each zone costs roughly £70 for materials which could go up or down depending on the size of zone and audio quality requirements. The server can be any old computer or even another Raspberry Pi connected to external storage (media repository) although that is untested and may produce audio dropouts.

Basic Full System Schematic

Multi-Zone Audio System Schematic

Multi-Zone Audio System Schematic

I’ve also added a little voice control functionality (See short demo below – and try to ignore me rocking back and forth like a parrot, it’s a rare condition… prodigitis) to quench my voice activated desires!

OK, so let’s get down to the nitty gritty, the tools you’ll need and how to put it all together. I’ll divide it up into Server, Zone and finish with Android to complete things…

The Server

It should be noted that this hardware spec would be quite over-powered for a sole purpose audio server, this machine is also tasked with running my home automation server (OpenHAB) and serving up the odd movie to my Kodi box in the lounge.

Server Hardware

An old desktop PC kitted out with:

  • 4GB RAM
  • 1TB HDD (For OS & Backups)
  • 2TB HDD (For Media)
  • 10/100Mbit 3com NIC
  • Other spec is pointless to list here as it’s irrelevant

Server Software

  • OS – Ubuntu Server 15.10 (Wily)
  • Squeezebox Server (Logitech Media Server Version: 7.9.0)

Server Setup

I’m not going to go into detail with the server setup and configuration, there is more than enough material on-line which I’ll point you in the right direction. I’m happy to help anyone get unstuck though so just drop a comment below if you find yourself in a bit of a predicament!

The Logitech Media Server (LMS) or Squeezebox Server as it’s also known can be installed on many platforms so if you’re not comfortable with Linux then go ahead and install on a Windows or MAC machine.

LMS on Ubuntu – how to by Marshaleq @ tech-knowhow.com

LMS on Raspbian – how to by Tomek @ raspberry-at-home.com

LMS on Windows – how to

LMS on MAC – how to

The Zone(s)

Each zone comprises of a Raspberry Pi Zero with a Digital to Analogue Converter (DAC) mounted on top which outputs to a 30W amplifier and stereo ceiling speaker.  The Pi is also running a script which turns the amp on or off whether there is music playing or not.

Zone Hardware Requirements

Zone Hardware SetupIMG_20160809_120521

The first step to configuring the zone hardware is soldering the headers to both RPi Zero and the phatDAC, I completed this step before thinking about attaching a relay to one of the GPIOs so I had to cheat a little and solder a couple of wires directly to the board. A cleaner design would be to implement a stacking header on the phatDAC to breakout GPIO that’s not being utilised.

I have used GPIO 17 for the relay control but it is entirely up to you what pin is used (just remember to alter the relay script as required).

Zone hardware schematic

ZONE HARDWARE SCHEMATIC

Zone Software Requirements

Zone Software Setup

The Raspberry Pi is running PiCorePlayer which is a fast booting Microcore Linux with Squeezelite pre-installed, it’s very simple to configure and duplicate for multiple zones. Check the downloads page for the latest release or use the image I provide here which is current as of August 2016.

  • Download PiCorePlayer 3.0
    • md5 checksum – 680D542911DC642BB37A5D52C1DA1855
  • Write the image file to your microSD card using either DD (Linux) or Win32DiskImager (Windows)
  • Leave the SD card connected (We are going to add another file to the card for initial headless configuration)
  • Download the newconfig.cfg file and open in a text editor
    • md5 checksum – F9698A00621BE309C73919D46C44BA7B
  • Edit the first few lines with your own WiFi network details:
    • WIFI=”on”
    • SSID=”your_ssid”
    • PASSWORD=”your_wifi_password”
    • ENCRYPTION=”WPA”
  • Edit the Name, Output and Host fields:
    • NAME=”Your_Zone_Name”
    • OUTPUT=”hw:CARD=sndrpihifiberry”  #this is what worked for my phatDAC
    • HOST=”piCorePlayer” #the name you want this player to be seen on the network
  • Save the newconfig.cfg file and transfer to the root of your SD card
  • Put the SD card into the Raspberry Pi and boot
Zone Relay Control Script

Thanks to Charles Luzzato for the relay control script – his original script can be found here

The shell script polls the server to determine the status of the player i.e- whether the zone player is playing or not. If the player is playing then it changes the output of GPIO 17 to high (or low in my case as the relay operates in reverse).

There are a couple of ways to get a script onto the pi, I will explain the only method you need – Vim! Microcore Linux doesn’t come with Nano, Pico or Gedit so if you have never used Vi/Vim, you’re in for a little shock as it’s not the most intuitive terminal text editor, it is though, arguably the best!

The first thing you need to know is what address your pi has on the network, from Linux you can use Nmap or from Windows you can use Advanced IP Scanner.

Next we need to SSH into the pi, I like to use PuTTY from a windows machine.

The default login credentials for PiCorePlayer are:
user: tc
password: piCore

From the terminal type tc@piCorePlayer:~$vi relay.sh This will open the vi text editor with a new file called relay.sh.
When vi first opens it is in command mode, typing i will put you in insert mode. You can either manually type out the below script (recommended) or highlight, right click, copy and paste it into vi by simply right clicking. Remember to edit the MAC_ADDR, LMS_IP & GPIO variables to match your configuration. When done press ESC to enter command mode then Shift ZZ to save and exit.

#!/bin/sh
. /home/tc/www/cgi-bin/pcp-functions
pcp_variables

##############################################
# Set the following according to your setup
##############################################
MAC_ADDR=00:0f:60:09:38:a7      # Raspberry Pi MAC address
LMS_IP=192.168.1.69     # LMS IP address
INTERVAL=0.5    # Set Poll interval
GPIO=17 # Set GPIO for relay
COMMAND="status 0 0"    # LMS player status command
DELAYOFF=20     # Delay in no. of intervals
COUNT=0
DEBUG=0
TURNED_ON=0
##############################################

if [ $DEBUG = 1 ]; then
  echo
  echo "MAC_ADDR : "$MAC_ADDR
  echo "LMS_IP : "$LMS_IP
  echo "INTERVAL : "$INTERVAL
  echo "GPIO : "$GPIO
  echo "COMMAND : "$COMMAND
  echo "DELAYOFF : "$DELAYOFF
  echo
fi

get_mode() {
  RESULT=`( echo "$MAC_ADDR $COMMAND"; echo exit ) | nc $LMS_IP 9090`
  echo $RESULT | grep "mode%3Aplay" > /dev/null 2>&1
  if [ $? == 0 ]; then
    echo "Playing. Count: $COUNT"
    COUNT=0
    if [ $TURNED_ON == 0 ]; then
      turn_on
    fi
  else
    if [ $COUNT -ge $DELAYOFF ]; then
      if [ $TURNED_ON == 1 ]; then
        turn_off
      fi
      COUNT=0
    else
      COUNT=$(($COUNT + 1))
      echo "Stopped. Count: $COUNT"
    fi
  fi
}

turn_on() {
  echo "1" > /sys/class/gpio/gpio$GPIO/value
  sleep .5
  echo "0" > /sys/class/gpio/gpio$GPIO/value
  TURNED_ON=1
}

turn_off() {
  echo "1" > /sys/class/gpio/gpio$GPIO/value
  sleep .5
  echo "0" > /sys/class/gpio/gpio$GPIO/value
  TURNED_ON=0
}
##############################################
# Initial GPIO setup
##############################################
sudo sh -c 'echo '"$GPIO"' > /sys/class/gpio/export'
# My relay is active low, so this reverses the logic
sudo sh -c 'echo "1" > /sys/class/gpio/gpio'"$GPIO"'/active_low'
sudo sh -c 'echo "out" > /sys/class/gpio/gpio'"$GPIO"'/direction'
echo "0" > /sys/class/gpio/gpio$GPIO/value


##############################################
# Loop forever. This uses less than 1% CPU, so it should be OK.
##############################################
while true
  do
    get_mode
    sleep $INTERVAL
  done

Change the permissions on the relay.sh file to allow for execution: tc@piCorePlayer:~$chmod 755 relay.sh
With the relay script saved we need to run the script at boot by editing the bootlocal.sh script:
tc@piCorePlayer:~$sudo vi /opt/bootlocal.sh Right below where it says : # put other system startup commands here
Insert the line : sudo sh /home/tc/relay.sh > /dev/null &
So the bootlocal.sh file should look something like this:
#!/bin/sh
# put other system startup commands here
sudo sh /home/tc/relay.sh > /dev/null &
GREEN="$(echo -e '\033[1;32m')"
echo
echo "${GREEN}Running bootlocal.sh..."
#pCPstart------
/home/tc/www/cgi-bin/do_rebootstuff.sh | tee -a /var/log/pcp_boot.log
#pCPstop------

Now, because PiCorePlayer runs entirely from RAM we need to make the changes we’ve made persistent by entering: tc@piCorePlayer:~$sudo filetool.sh -b
And that’s it! Done.

Android

I use Orange Squeeze as my main Squeezebox controller app, this is a premium app costing around £4 which I see as a good investment for a solid controller. There are other free options available such as Squeezer, the choice is up to you.

Tasker/AutoVoice/AutoSqueeze

In the short video above I’m demonstrating the use of voice control for the system, this is achieved by using Tasker, AutoVoice and AutoSqueeze. If you’ve never used Tasker before I suggest going through some tutorials to get the basics down, it’s an extremely powerful automation app which I will only be skimming the surface of in this post.
My Tasker profile is triggered with an AutoVoice Recognized event using regex (Regular Expression), the command is play (?<music>.+) in the (?<room>.+) This lets tasker know that two variables will be set, music and room. With a voice command: Play hello in the kitchen, the variables will be set as: %music = hello, %room = kitchen.

The Tasker Task can then use a series of IF/ELSE IF to determine the room variable then we can use AutoSqueeze to send a custom command to that zone player. In this case my command does a track search for whatever is stored in the %music variable, adds the tracks found to a playlist and plays. playlist loadtracks track.titlesearch=%music Custom commands can be derived from the Logitech Media Server Command Line Interface (CLI) page.
At this stage I can only play tracks which is quite limiting, I would like to extend the capabilities and build a fully comprehensive voice control system by adding artists and albums.

AutoVoice Event

AutoSqueeze Configuration

 
…To Be Continued

retro

A lover of how things work. Currently studying towards a BEng Computer Security & Forensics degree at Edinburgh Napier University. A Marine Mechanic to trade, also specialised in electrical/mechanical repair & maintenance.

Leave A Comment