Alternative MPD LCD Display using smartie-utils

I liked the mpdlcd solution for displaying data on the Sure LCD, but I didn’t like that it used so much cpu, and it was sort of limited with what you could display. I have another solution that I’ve adapted from what I use with my Raspberry Pi and pifacecad. The initial steps are similar to what I used to display airplay metadata with smartie-utils, so I won’t repeat those here. The new mpd lcd data will now display: artist, title, album, output data like number of channels, bit-rate, and sample rate, and random, repeat, etc info. Isn’t that awesome? Well, I think it’s awesome. There are a couple drawbacks which might be deal breakers for some: there is no progress time and if the text is too long, it will not scroll. For some reason, the text scrolling actually kind of annoyed me anyway. I think it’s the flickering.

As an aside, showing the sample rate is very audiophile; I have no idea why. Seems like the bit-rate is more important. Anyways, now you can display both!

lcd2

Assuming we used this method to update our Sure LCD display, we should make the following updates.

Display Script

Create the main script for displaying the data.
sudo nano /etc/shairport/mpcdisplay.sh

Then paste the following:

#! /bin/sh
while : ; do
        mpc idle
(mpc current -f "[%artist%][[n%title%][n%album%]|[nn%name%]|[nn%file%]]" ; cat /proc/asound/card1/pcm0p/sub0/hw_params | awk 'FNR==4{c=$2">"} ; FNR==2{f=substr($2,2,2)"/"} ; FNR==5{r=$2/1000} ; END {printf(c)(f)(r)" "}' ; mpc | awk 'match($0,"random:") { r=substr($0,RSTART+8,2)} ; match($0,"repeat:") { t=substr($0,RSTART+8,2)} ; match($0,"single:") { s=substr($0,RSTART+8,2)} ; END { if ((t)=="on" && (s)=="on") print "Repeat One" ; else if ((r)=="of" && (t)=="on" && (s)=="of") print "Repeat All" ; else if ((r)=="on" && (t)=="of") print "Random" ; else if ((r)=="on" && (t)=="on" && (s)=="of") print "Rnd Rp All" ; else print "" }') | tclsh /etc/shairport/smartie/smartie-cat.tcl -tty /dev/ttyUSB0
done

Note: WordPress Jetpack Markdown Plugin is having a hard time understanding “\” in code blocks. In the above script, add those “\” back.
mpc current -f "[%artist%][[\n%title%][\n%album%]|[\n\n%name%]|[\n\n%file%]]"

This mpcdisplay.sh script uses the mpc idle command that lets you know when something in mpd has changed. The script runs in a loop where whenever mpc idle senses a change, it sends some parsed data to the display using smartie-utils. Since it’s not constantly refreshing itself every half second, it hardly uses any resources. Sweet.

Make it executable.
sudo chmod +x /etc/shairport/mpcdisplay.sh

Daemons

Now, disable mpdlcd and LCDd daemons.
sudo update-rc.d -f mpdlcd remove
sudo udpate-rc.d -f LCDd remove

Create a new daemon script for this mpcdisplay.
sudo nano /etc/init.d/mpcdisplay

#!/bin/sh

### BEGIN INIT INFO
# Provides:          mpcidle.py
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Put a short description of the service here
# Description:       Put a long description of the service here
### END INIT INFO

# Change the next 3 lines to suit where you install your script and what you want to call it
DIR=/etc/shairport
DAEMON=$DIR/mpcdisplay.sh
DAEMON_NAME=mpcdisplay

# This next line determines what user the script runs as.
# Root generally not recommended but necessary if you are using the Raspberry Pi GPIO from Python.
DAEMON_USER=root

# The process ID of the script when it runs is stored here:
PIDFILE=/var/run/$DAEMON_NAME.pid

. /lib/lsb/init-functions

do_start () {
    log_daemon_msg "Starting system $DAEMON_NAME daemon"
    start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --user $DAEMON_USER --chuid $DAEMON_USER --startas $DAEMON
    log_end_msg $?
}
do_stop () {
    log_daemon_msg "Stopping system $DAEMON_NAME daemon"
    start-stop-daemon --stop --pidfile $PIDFILE --retry 10
    log_end_msg $?
}

case "$1" in

    start|stop)
        do_${1}
        ;;

    restart|reload|force-reload)
        do_stop
        do_start
        ;;

    status)
        status_of_proc "$DAEMON_NAME" "$DAEMON" && exit 0 || exit $?
        ;;
    *)
        echo "Usage: /etc/init.d/$DAEMON_NAME {start|stop|restart|status}"
        exit 1
        ;;

esac
exit 0

Make it executable and daemonize it.
sudo chmod a+x /etc/init.d/mpcdisplay
sudo update-rc.d mpcdisplay defaults

Make it work with Shairport

Edit our shairport daemon.
sudo nano /etc/init.d/shairport

#! /bin/sh
# /etc/init.d/shairport
#
### BEGIN INIT INFO
# Provides:     shairport
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Put a short description of the service here
# Description:       Put a long description of the service here
### END INIT INFO

NAME="Livang Room"

case "$1" in
  start)
    /usr/local/bin/shairport -b 95 -d -a "$NAME" -w -B "mpc stop" -E "echo 'Airport Off' | tclsh /etc/shairport/smartie/smartie-cat.tcl -tty /dev/ttyUSB0" -M /etc/shairport
    ;;
  stop)
    kill -9 `pidof shairport`
    ;;
  *)
    echo "Usage: /etc/init.d/shairport {start|stop}"
    exit 1
    ;;
esac

exit 0
#

Update the command after start). You’re removing the kill mpcdlcd and the restarting of mpdlcd parts. After shairport finishes playing, it will now show “Airport Off” on the lcd display. Then reboot.

Bits

I found some weirdness which I never noticed with my Raspberry Pi. With my compressed music, the bit-rate is upsampled to 24 bit from 16 bit. I have no idea what’s causing this. This doesn’t happen with my ALAC files. My only guess is the codec Mint uses changes the bit rate when uncompressing it.

1 Comment

  1. I’ve got one remark regarding your otherwise accurate article.

    You write:
    “As an aside, showing the sample rate is very audiophile; I have no idea why. Seems like the bit-rate is more important. Anyways, now you can display both!”

    For audiophile purposes the bitrate isn’t that interesting at all. This kind of use assumes a bit-perfect set up, in which the actual bitrate reflects the actual amplitude (in bits) and the sample frequency of the raw (or lossless compressed) input file.

    For instance, with an input file encoded in 16bit/44.1kHz, the maximum bitrate is (16 * 44100 =) 705600 bits per second. But in real life this rate will drop because most samples need less than the maximum amplitude, for which it has (2^16 =) 65536 values available. mpd’s bitrate data field reflects the average of bits in the last second.

    Only when using (non-audiophile) lossy compression, the bitrate could indicate the audio quality.

    Regards,
    Ronald

Leave a Comment

Your email address will not be published. Required fields are marked *