HQ Music Player and Internet Radio With Smartphone Control – Raspberry Pi, PCM5102A, Node-RED

22K18619

Intro: HQ Music Player and Internet Radio With Smartphone Control – Raspberry Pi, PCM5102A, Node-RED

This is a high quality (and low cost) sound system based on a Raspberry Pi running Node-RED and using a PCM5102A digital audio decoder. It can run standalone as described here, or can be easily integrated with the Node-RED based home automation system shown in my earlier instructable. In the latter case the music system is just another page on the home automation system. Integration with the home automation system also means the music can be driven automatically – e.g. driven by time of day – or driven from presence detection (of mobile phone) to play a visitors favourite playlist automatically. The instructions here cover starting from scratch to the smartphone controlled music system. The instructions are detailed and most of the setup input can be copied and pasted. These have been directed at novice and above.

The instructions are in several steps, best done in order :

  • Initial setup of the Raspberry Pi (step 1)
  • Adding the high quality PCM5102A audio system (steps 2, 3)
  • Add music and playlists (step 4)
  • Installing Node-RED and the control system (step 5)
  • Customising the playlists (step 6)
  • Detailed description of the control system (step 7)

Cost wise the PCM5102A board is under $4 on ebay. The PCM5102A board has a 3.5mm socket for easy connection to a HiFi system. For setup I used a JBL dock.

It should work on any Pi. I used a Pi3 as I have an additional workload that needs the extra power.

Note: text in bold and italic is aimed to be copied and pasted into the Pi to save time.

22/3/2021
From today the BBC has brought its internet streaming inhouse and is not making its internet radio urls available to the public. Hence the links in the stations.m3u file to BBC stations no longer work. I have contacted the BBC asking them to remove this restrictive change. Others, especially those who the BBC is mandated to serve, might consider doing the same.

However a visit to http://www.radiofeeds.co.uk might prove worthwhile.

STEP 1: Raspberry Pi Setup.

First download Raspbian Stretch or Stretch Lite from https://www.raspberrypi.org/downloads/raspbian/

The instructions here are based on Stretch Lite that needs a bit more work but avoids a load of software that is not relevant to this application. If you want the Pi Desktop and other programs then start with the full version. The version available at the time of writing was June 2018 but others should work fine.

Unzip the file to a known location. Then run Etcher to download the image to an SD card. Etcher is free and downloadable from https://etcher.io/ and is straightforward to run:

After the card has been flashed add a blank file called ‘SSH’ to ‘boot’. This enables the Pi to be driven remotely and set up from a PC and hence take advantage of copy and paste of the text listed here.

Eject the card and plug it into the Pi.

Power up the Pi. When it is running find the IP address by logging onto your router. Alternatively, if using the full version of stretch, this can be found by connecting a monitor, mouse and keyboard and click the internet icon at the top right of the desktop. On Stretch Lite (with monitor and keyboard connected) use the instruction sudo ifconfig and look under wlan0>inet addr: . I find the router option by far the easiest.

For the remote connection run Putty (free download from https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html ) from a PC and enter the Pi’s IP address. Log on as ‘pi’ with password ‘raspberry’.

First revise the password and other settings via:

sudo raspi-config

(copy text then right click in Putty to paste)

First change the password.

I then change the network name (optional).

Under Interfacing options enable SSH.

Then right arrow twice and click Finish, and Yes to reboot. This will lose the Putty connection. Rather than close this wait a minute for the Pi to restart and the right click the Putty task bar and select ‘Restart Session’. Now log in using ‘pi’ and the new password.

Next update entering:

sudo apt-get -y update

Then upgrade entering:

sudo apt-get -y upgrade

This can take a while.

The pi is now ready for the audio and Node-RED installations that follow.

STEP 2: PCM5102A Hardware Setup

For reference the PCM5102A board looks like:

There are boards with other formats that should work OK.

The I2S pins are defined by a dtoverlay setting later. The connections required are (listed in PCB order with pins for the Pi A+/B+, 2, 3, Z):

Board Connect to &nbsp Pi Function VCC 5v pin 2 or 4 Power 3.3V XMT Generated on-board GND GND pin 6 or 14 Ground FLT GND Filter select (normal low) DMP GND De-emphasis (off low) SCL GND System clock – internally generated BCK GPIO18 pin 12 data bit clock DIN GPIO21 pin 40 data LCK GPIO19 pin 35 data word clock FMT GND Audio format (low I2S) XMT 3.3v Software mute (high off)

So 5 leads are required from the board to the Pi and 5 other pins have to be connected to ground, and one pin connected to the on-board 3.3v connection. I debated whether SCL needed to be connected to ground. However it is an input pin and should not be left floating and connecting to ground would only pose a problem if it was an output as well - which it is not. Noise on this pin would prevent the internal clock starting.

I made the board ground and 3.3v connections using fine enamel coated wire (28 SWG).

For the leads to the Pi I cut some Dupont leads in half and soldered the cut end to the board. Next time I would make up leads as the wire in the Dupont leads was thin/weak.

Board connected to Pi:

STEP 3: PCM5102A Software Setup

Power up and log onto the Pi via Putty.

First we need to disable the on-board sound by editing alsa-blacklist.conf:

sudo nano /etc/modprobe.d/alsa-blacklist.conf

add:

blacklist snd_bcm2835

Save and exit (^X, Y, enter).

Now, to set the IO for the connections, edit config.txt:

sudo nano /boot/config.txt

Add:

dtoverlay=hifiberry-dac

Remove or comment (#) the line:

dtparam=audio=on

Leave the line:

#dtparam=i2s=on

commented out.

Save and exit (^X, Y, enter).

Next add some alsa (sound) configuration:

sudo nano /etc/asound.conf

Paste the text below:

pcm.!default {

type hw

card 0

}

ctl.!default {

type hw

card 0

}

Save and exit (^X, Y, enter).

It is no harm to do a reboot. So:

sudo reboot

Restart the Putty session and test if everything is OK:

aplay -l

This should return:

**** List of PLAYBACK Hardware Devices ****

card 0: sndrpihifiberry [snd_rpi_hifiberry_dac], device 0: HifiBerry DAC HiFi pcm5102a-hifi-0 []

Subdevices: 1/1

Subdevice #0: subdevice #0

If you have an amplifier you can connect via a phono lead you can now test it via: speaker-test -D -c -twav So:

speaker-test -D default -c 2 -twav

This is a continuous test saying ‘front left’ and ‘front right’ alternately from the appropriate speakers.

Enter ^C to stop.

There are several players that can be used to try the card out. In my case I wanted to use MPD as it can be driven from Node-RED.

To get MPD (and MPC) working:

sudo apt-get -y update

sudo apt-get -y upgrade

sudo apt-get -y install mpd mpc

Note: mpc is a client that can drive mpd and is useful for testing.

Adding software volume control

This is an optional step that adds a software volume control into the sound processing sequence. The key ingredient, that took a frustrating day to find, is that MPD needs the soft volume control to be called ‘PCM’.

sudo nano /etc/asound.conf

add the following:

pcm.sftvol {

type softvol

slave.pcm "plughw:0"

control {

name "PCM"

card 0

}

}

Enter or change the pcm.!default section to:

pcm.!default {

type plug

slave.pcm "sftvol"

}

Save and exit (^X, Y, enter).

Now we can test it, as before:

speaker-test -D default -c 2 -twav

This should give alternating "front right" and "front left" from the respective speakers.

STEP 4: Add Music and Playlists

The internet radio is driven by a playlist of radio stations. The playlist is simply a list of the station URLs, one per line. The URLs can be found by searching on ‘Internet Radio URLs’. I also checked these out on my Windows PC using VLC media player. Notepad++ (free download) is a great editor to use as it includes line numbers. My playlist is attached and can be used as a starting point (stations.m3u).

We need to make directories for the playlists and music and tell mpc their locations.

First I added a 'Music' directory in the home/pi folder. Then I added a ‘playlists’ directory in the home/pi/Music folder. I used a FTP program - FileZilla (free) to do this remotely. This is also useful later to upload the radio playlist and music. To use FileZilla enter the Pi IP address in Host, then username (pi) and password, and Port 22 and then click Quickconnect.

We need to tell mpd where to look for music and playlists. So, via Putty:

sudo nano /etc/mpd.conf

Change the music directory line to read:

music_directory "/home/pi/Music"

and the playlist line to read:

playlist_directory "/home/pi/Music/playlists"

Save and exit (^X, Y, Enter).

I saved the radio stations playlist (on my PC) as stations.m3u . I then used FileZilla to put a copy into the playlist folder on the Pi.

We can now test mpd. First we must reboot so mpd reads the playlists. So, via Putty:

sudo reboot

Then restart the Putty session and load the playlist via:

mpc clear

mpc load stations

The 'clear' instruction removes any previously loaded playlists.

Then play:

mpc play 1

‘play 1’plays the station in line 1 of station.m3u. Note that later we will be sending commands directly to MPD and it uses 0 for the first line. You should now hear your radio station (BBC Radio 1 if using my playlist).

To stop enter:

mpc stop

We will add the Node-RED interface later.

For the music I simply copied some albums from the itunes folder on my PC to the home/pi/Music directory. This is easy using a FTP program such as FileZilla.

I used the same file structure i.e. Artist>Album>tracks

So the Music folder looks like:

After updating any music mpc needs to update its database. So:

mpc update

A playlist for the TajMahal folder can be created as follows:

mpc clear

mpc ls TajMahal | mpc add

you can check it looks OK via:

mpc playlist

I then found there was a permission problem stopping me save the playlist. This was solved by:

chmod a+w /home/pi/Music/playlists

The playlist can then be saved:

mpc save TajMahal

check it is there by

mpc lsplaylists

By the same procedure I created a playlist for TheNice.

Note that several playlists can be added to the running list. So when selecting playlists one first has to clear the existing list. So test with:

mpc clear

mpc load TajMahal

mpc play

So we now have some albums loaded and a couple of playlists for music and one with the list of our radio stations and mpd plays these OK.

STEP 5: Install/update Node-RED

Node-RED is best loaded using a program called node packet manager. So this has to be installed first. Node-RED also needs Node.js .

Start a Putty session and enter:

sudo apt-get -y install npm

Now upgrade npm:

sudo npm i -g npm@2.x

Note this takes a while…..

Now install node.js:

sudo npm install -g n

sudo n latest

Restart to complete the installations

sudo reboot

The PuTTY connection will be lost. So restart the session. Now check the installed versions:

node -v

I got v10.10.0

npm -v

I got v6.4.1

We can now install Node-RED:

sudo npm install -g --unsafe-perm node-red

This will give a couple of error messages because of an incorrect address. The system however does a ‘source compile’ to correct this problem. If you repeat the instruction above (not necessary) the errors do not occur.

If starting from Stretch Lite we also need files later to enable autostart of Node-RED:

sudo wget https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/nodered.service -O /lib/systemd/system/nodered.service/em>

sudo wget https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/node-red-start -O /usr/bin/node-red-start

sudo wget https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/node-red-stop -O /usr/bin/node-red-stop

sudo chmod +x /usr/bin/node-red-st*

sudo systemctl daemon-reload

We can now do an initial test of Node-RED. Enter:

node-red-pi --max-old-space-size=256

Wait for it to get running and you see the text ‘Started flows’.

Now open a browser, I use Chrome, and enter the pi IP address followed by :1880 i.e. something like 192.168.0.8:1880

You should now have the Node-RED programming page in view as below:

We need a couple of extra node types for this project. First there are some dashboard nodes for display of sliders, switches, buttons, dropdown lists on the interface page. These are installed by clicking the ’3 lines’ icon top right and selecting ‘Manage pallette’. Then click the Install tab and enter ‘dashboard’. If you don’t get a response click the refresh icon. At the time of writing there were 1617 sets of nodes available! With the dashboard nodes listed look for ‘node-red-dashboard’ and click the ‘install’ button and then ‘Install’. Now do the same again but searching on ‘mpd’ and install ‘node-red-contrib-mpd’. Clicking on the ‘Nodes’ tab will now show these have been added.

The last step to load the control system is a simple copy and paste job. Open the attached file on your PC in Notepad or equivalent and select all (ctrl+A) and copy (ctrl+C). Now in Node-RED click the ‘3 lines’ icon top right and select ‘Import’> ‘clipboard’ and paste (ctrl+V). Click ‘Import’ and the control system should appear, as below:

How easy is that? I have added a detailed description of the control system operation as Step 7 so you can modify/build on it.

Also set the display Theme to dark (or the play/pause icons will not show). In the right hand panel click the dashboard icon and then ‘Themes’ and select Style ‘Dark’.

Now click the ‘Deploy’ button to launch it. The MPD in and MPD out nodes should show ‘connected’.

The interface can be found at ‘Pi IP address’ :1880/#ui. If the three sections are not on top of each other reduce the window width until they do. The radio stations should work immediately. Click the radio icon so it turns green and select a radio station. The music part will need editing of the playlists to whatever you have loaded (see step 6).

Lastly we need to set Node-RED to start automatically when the Pi starts up.

So back in Putty enter ctrl+C to stop Node-RED. Then enter:

sudo systemctl enable nodered.service

If you ever need to disable this enter:

sudo systemctl disable nodered.service

Now for a last test restart the pi with:

sudo reboot

Log onto the interface at ‘Pi IP address’ :1880/#ui and check the functions work.

STEP 6: Customise the Playlists

The playlists for the radio and music in Node-RED have to be matched with the playlists set up in mpd.

The radio playlist is easiest as there is only one – stations.m3u.

First edit stations.m3u to add the stations you want to listen to. A good place to start is a search on ‘Internet Radio URLs’. With stations.m3u edited and transferred to the Pi (as shown earlier) we then need to edit the dropdown list that is used to select them. So open Node-RED at ‘Pi IP address’:1880 and double click on the ‘Station: ‘ node and then edit the options list, noting that option 0 is the first line/station in stations.m3u. The left box is the command number sent to mpd and the right box is the text that will appear in the drop-down list.

The music system is similar except we are selecting playlists rather than items within a playlist.

First import the albums to be played and set up the playlists in mpd as shown earlier. We then need to edit the drop-down list of playlists. Double click on the ‘Add Playlist:’ node and edit the options list. The first needs to be ‘None None’ to give the option to not add a playlist if the button is clicked in error. The rest are the desired playlists where the left box holds the name of the playlist saved in mpc and the right box shows the playlist as it will appear in the drop-down list.

The system is set play Radio 4 as default (item 3 in the stations playlist). The can be changed by double clicking the ‘Radio on/off’ node.

Look for the section:

var msg3 = {

payload: "3"

};

Change “3”to the ‘line number -1’ of the desired station (so first line is ‘0’). ‘msg3’ gets sent via a 100ms delay to the ‘Station:’ drop-down list.

When the nodes have been edited click the ‘Deploy’ button and then go to the user interface and check all works as it should.

The setup can be saved using a click on the ‘3 lines’ icon top right and select ‘Export’> ‘clipboard’.

Then open Notepad and paste (ctrl+V) and save the file.

STEP 7: Detailed Description of the Control System

This description should give a good understanding of how the system is set up. With this background the system can be tweaked to one’s own requirements.

The system has to do quite a bit when switching between radio and music because both the radio and music systems use playlists – but in different ways.

The radio just uses one playlist (of stations) and the system continuously plays the selected entry. The music system can add any number of playlists to the playlist it will run through. So the system needs to be able to add playlists and clear the running playing list. There is also an option to have the player select the tracks at random from the running playlist.

The core of the system is the on/off control. There are three states (Radio, Music and Off) that can be handled by two buttons (Radio and Music) that show red when off and green when on. The functions (Radio On/Off and Music On/Off) change several settings when the buttons change state. The first output sends an ‘Off’ to the other when turned on. This prevents both parts running at the same time. The second output sends ‘clear’ to the MPD player when each system is turned off – to clear the running playlist. There is no ‘replace playlist’ command so we need to first ‘clear’ and then ‘load’. This output is also used by radio system to load the stations playlist (load stations) when turned on. The third output on the Radio On/Off function sends a number for the default start station. This is set to ‘3’ for Radio 4 but can be changed as required. It would also be possible to save the last loaded station as a global variable hence reload the last used station. I will leave this as a simple challenge if you want to add this. The command to select the station is delayed by 0.1s to give time for the stations playlist to load first.

The music system has ‘Add Playlist:’ and ‘Clear List’ to manage the playlists and ‘random’, ‘pause/play’, ‘previous’ and ‘next’ buttons to control the playing. When the radio is turned on the Radio On/Off function sends commands to set random off, pause and set the ‘Add Playlist’ to the top entry – ‘None’.

The ‘Clear list’ node both sends ‘clear’ to ‘MPD out’ and, via the function ‘None’, sets the ‘Add Playlist:’ dropdown list to the ‘None’ entry.

Adding any playlist sets the play/pause button to pause.

The ‘MPD in’ node receives a JSON string with a load of information. The’ Title’, ‘Artist’ and ‘Album’ functions select these bits of data if they are present and puts them to the display.

Greater detail can be found by double clicking the nodes. The information panel on the right hand side gives additional detail on the node selected.

14 Comments

Nice project!
I seem to have a problem with the radio stations.
If I add them to the playlist I can play the stations and cycle through.
When I add the stations to the station dropdoen I keep getting this error:
[info] [mpd out:13aa2c55.b7e3d4] [MPD] - Error: [2@0] {} Bad song index
With valid index positions.
Any advice?
Sorry for slow reply - was only notified this evening. Well done solving this. If I get this error I will know what to do! Looks like you have a good feel for Node-Red. Glad to see you building on this project. Mike
Found the culprit.
When activating the radio:
1. the stations playlist is loaded
2. msg is send to the music button to turn it off, which sends the "clear" command to MPD, clearing the stations playlist

I added a 50ms delay to the load stations command to MPD
Nice tutorial/project!

I've only followed it until Step 3, since i only wanted to install the same jack audio board on my raspbery pi Zero.

I can hear the audio with `$ speaker-test -D default -c 2 -twav`, but it is not dual channel.
how can i configure alsa to obtain dual channel/stereo output?
Sounds like you have a hardware problem. The test should give 'front left' , 'front right, alternately from the two channels. Mike
You're right. I swaped the speakers and everything works now.
It is nice when the solution is simple! Well done. Mike
Nice! Works good for me!
I do have a question:

I can get sound to bt or soundcard, but how to set up for both??

this in /etc/asond.conf give bt
```
pcm.!default {
type plug
slave.pcm {
type bluealsa
device "91:AD:70:FD:8D:3C"
profile "a2dp"
}
}
ctl.!default {
type bluealsa
}
```
this in /etc/asond.conf give soundcard
```
pcm.!default {
type plug
slave.pcm "sftvol"
}

ctl.!default {
type hw
card 0
}

pcm.sftvol {
type softvol
slave.pcm "plughw:0"
control {
name "PCM"
card 0
}
}
```
I hope you have solution for this!

/Lennart

I am sorry but I have not tried this, and my only work with bluetooth has used external bluetooth cards (for input). I agree there should be a solution that enables what you want to do. I hope that posting on one of the relevant forums would help. It would be great if you could post your solution somewhere so others could also do this. Mike

interesting but what is the ip address of the raspberry pi?

The IP address is given by your router using a process called DHCP. Routers will stick to that number for a period one allocated. Hence you will have to follow the guidance here to find it. There is more information on the raspberry pi site. There is also an advanced function in most routers where one can allocate a specific number. This will need logging on to the router and identifying the Pi (and its MAC address). I have several Pi's and note the allocated IP address on a piece of sticky paper. I usually log onto the router to find IP addesses. Mike

Would it be possible to make the same project with a Pi Zero (W) ? It would allow to add a good quality audio output to the cheap board :)

Yes I would expect this to work on a Zero W. Note it will need a decent wireless connection for the internet radio so there may be a limit to how far it can be from your router. You will have to find this by experimentation. Let us know how you get on. I expect others will be interested. Mike

Nice project! Thank you!