Centralized multi-room audio setup with MPD and spotify integration

Today I found a solution to integrate spotify in my multi-room audio setup, as it took some time to get it working I want to share it here. But let me present the whole system. It is modular and can be realized with any hardware and only free software (except the spotify client).

Here is the outline:

  • 4 zones (kitchen, bath, terace, living) have a stereo speaker output
  • the audio output is generated on a 7.1 soundcard in the server, where the 8 channels are mapped to 4 stereo groups
  • the analog audio goes to individual amplifiers (matching rooms & speakers)
  • the server runs openHAB, mpd, a spotify client and many other software on linux
  • each family member has its own instance of mpd on the server (but also access to the others)
  • each mpd has the 4 output zones and a stream output configured
  • the mpd’s are controlled by clients on the families mobile phones, the openHAB mpd binding (rules use KNXs switch signal for control, a HABpanel shows most of the controls)
  • any spotify client in the home network can use the spotify client on server as a output device.
  • the spotify audio stream is looped back from the HDMI soundcard to a local stream on server, that is than played back by any of the mpd’s in any or multiple zones

The main advantages for me of this setup are:

  • audio in all zones is in perfect sync
  • centralized hardware, no RasPi or something like that hidden in corners of rooms
  • modular hardware, I can choose the DSP by bying the soundcard I want, I can choose the amp and the speakers
  • no closed (expensive) hardware, eg. Sonos, Russound etc. (which support do you get in some years? How do play different hardwares together?)
  • no additional traffic for audio in local network (audio goes via speaker cable), thus no connection loss/problems
  • central managed software (mpd, openhab, one mp3 storage)
  • can run without spotify premium
  • will work similar with any kind of streaming software
  • allows any aditional audio (e.g. door bell) to mixed to the active outputs, too

Here is a scheme of my actual audio setup:

The re-mapping of the 8 channels is done in alsa ( /etc/asound.conf ):

# the mixer provides the mixing of the 8 channels
pcm.dmixer {
    type dmix
    ipc_key 1099
    ipc_perm 0660
    slave {
        pcm "hw:1,0"
        rate 96000
        channels 8
        periods 128
        period_time 0
        period_size 1024
        buffer_size 4096
    }
    bindings {
        0 0
        1 1
        2 2
        3 3
        4 4
        5 5
        6 6
        7 7
    }
}

# here is the HDMI soundcard, which is used as default output from spotify
pcm.!default {
    type plug
    slave.pcm "mystream"
}

pcm.mystream {
    type plug
    slave {
        pcm "hw:0,0"
        rate 48000
        channels 2	
    }
}

# here I map the channels of the 7.1 sound card to 4 x 2.0 stereo channels
pcm.wohnzimmer {
    type plug
    slave {
        pcm "dmixer"
        channels 8
    }
    ttable.0.0 1
    ttable.1.1 1
}

pcm.bad {
    type plug
    slave {
        pcm "dmixer"
        channels 8
    }
    ttable.0.2 1
    ttable.1.3 1
}

# ... repeat with similar logic for the other two zones (channels:  0.4, 1.5, 0.6, 1.7) ! 

Four copies of mpd are running in parallel (actually it could be any number :wink:). Rename the instances to mpd1, mpd2, … each with its own config (mpd1.conf, …). My files look like this:

music_directory        "/myfolder/Musik"
playlist_directory    "/myfolder/software/mpd/playlists"
db_file            "/myfolder/software/mpd/mpd.db"
log_file        "/myfolder/software/mpd/mpd1.log" #and mpd2.log, mpd3 ...
pid_file        "/myfolder/software/mpd/mpd1.pid" #and mpd2.pid, mpd3 ...
state_file        "/myfolder/software/mpd/mpd1.state" #and mpd2.state, mpd3 ...
sticker_file            "/myfolder/software/mpd/sticker.sql"

user            "mpd"
port            "6601" #and 6602, 6603, 6604
gapless_mp3_playback    "yes"
auto_update            "yes"
zeroconf_enabled    "yes"
zeroconf_name        "User 1" #and 2, 3, 4

input {
        plugin "curl"
}

audio_output {
       type            "alsa"
       name            "mpd1-Kitchen" #and mpd2-kicthen, mpd3- ...
       device          "kitchen"
       mixer_type      "software"
       mixer_control   "PCM"
}

audio_output {
       type            "alsa"
       name            "mpd1-Living" #and mpd2-Living, mpd3- ...
       device          "Living"
       mixer_type      "software"
       mixer_control    "PCM"           # optional
}

audio_output {
       type            "alsa"
       name            "mpd1-Bath" #and mpd2-Bath, mpd3- ...
       device          "bath"
       mixer_type      "software"
       mixer_control    "PCM"           # optional
}

audio_output {
       type            "alsa"
       name            "mpd1-Terrace" #and mpd2-Terrace, mpd3- ...
       device          "terrace"
       mixer_type      "software"
       mixer_control    "PCM"           # optional
}

audio_output {
       type          "httpd"
       name          "mpd1-Stream" #and mpd2-Stream, mpd3- ...
       encoder       "vorbis" 
       port          "8001" #and 8002, 8003, 8004
       bitrate       "128"              # do not define if quality is defined
       format        "44100:16:1"
       always_on     "yes"              # prevent MPD from disconnecting all listeners when playback is stopped.
       tags          "yes"              # httpd supports sending tags to listening streams.
}

filesystem_charset    "UTF-8"
id3v1_encoding        "UTF-8"

The mobile phones run MPD control as clients. We like the easy access to the outputs. Most other mpd apps hide this well, and thus switching of zones becomes unpractical.

The server runs the normal spotify linux client and its output will go to the default audio sink (here alsa’s pcm.!default), which is mapped to my second sound hardware - the HDMI card. Normally the speaker is muted by the monitor hardware, thus the music can not be heard in the server cabinet :laughing:. The audio from this soundcard is looped back into an mp3-stream that the mpd’s can use as a input. I found this solution in the internet:
The command:

pacmd list-sources | grep name

shows device name to use, for me alsa_output.pci-0000_00_03.0.hdmi-stereo.monitor
A streaming software like VLC can form this into a stream file, e.g.:

cvlc -vvv pulse://alsa_output.pci-0000_00_03.0.hdmi-stereo.monitor --sout '#transcode{acodec=mpga,ab=128,channels=2}:standard{access=http,dst=localhost:8005/spotify.mp3}'

Other VLC transcode options should also work. My mpd plays back the stream from http://localhost:8005/spotify.mp3. I experience a delay of roughly 1-2 seconds between an action at the spotify app and the audible speaker output. This is OK for me, because all four zone outputs are in perfect sync and will be like this, ever!

7 Likes

What an awesome solution!!! Just one question. How do you control which playlist or song you play from Spotify?

Cheers, Rico

To control Spotify I use the Spotify app on my smartphone and just choose the server as a remote output.


So, anyone in the family can push their own Playlist from smartphone to the server. Works quite well.

Thanks!! I’ll have a go at this, but I’am not sure if the Spotify client will run on a raspberry pi!

Cheers, Rico

Hi, this is impressive. I have been looking to setup something like this. One question I have is whether it is possible to play 2 different Spotify instances at the same time to different zones. I think this would amount to running 2 Spotify client next to each other, I just don’t know whether this is possible.

To be fully honest, I had in mind running a Spotify client per zone so that the zone can be directly selected from the within Spotify app.

Thanks a lot for posting this though!

Best.

Props to the OP!

When i’ll have my own house this is the type of projet i’ll do.

1 Like

I don’t know. We have only one spotify client running. So far there was no need to run multiple instances. I still use the dirty hack to loop the spotify output through a sound card device and grep it with VLC. If you can find a way to connect to a spotify stream directly it will be straight forward. Probably you need a premium / family account to do this.

thanks for the reply. I do have a Spotify family plan. Do you mind sharing What 7.1 soundcard you have been using and weather you are happy with it?

I use a similar setup. But with the Logitech Media Server instead of mpd, which has a plugin for spotify that works great with the 5 accounts from the spotify family membership.

I have one centralized server and 5 airplay speakers. all can be adressed within logitech media server, which has (in my point of view) a very old and bad looking gui. But so far it just works an there is a binding for openhab as well.