HQ Music Player and Internet Radio With Smartphone Control – Raspberry Pi, PCM5102A, Node-RED
by FlyingDrMike in Circuits > Audio
22592 Views, 187 Favorites, 0 Comments
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.
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.
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 |   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:
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.
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.
Downloads
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.
Downloads
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.
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.