Deezer Flow Radio
The Flow Radio is a physical radio that has been hacked to link it to our Deezer Flow. This project has been initiated during the Deezer Hack Session of April: we had one day to constitute a team of six and reach our goal.
The idea was to fit our Deezer Audio Player in a Raspbian Linux Distribution, on a Raspberry Pi ; and then to fit the Raspberry Pi into a very old radio bought used on the Internet. Actually, the radio belonged to a woman living close to our office. Picking the radio up was quite easy. A search on the web revealed that the Schneider radio was built in 1959…
This hackathon project was quite special compared to other projects as it relied not only on software but also on hardware. We had to prepare the session and gather some basic equipment and components before starting working on it, in order to save us time. The most important equipment was the radio itself, the Raspberry Pi and electronic components.
To make the project more interesting, we specifically wanted that the old radio has at least two buttons and one potentiometer, so we could hack them in manners that led to (probably) interesting results. We had no clear idea about how to hack these interfaces, but as long as we could decide it during the day it was not yet a problem. The Schneider radio has three buttons and two potentiometers.
It was easier to get a Raspberry Pi. Many of the developers at Deezer play with these little and fantastic machines. We had a choice between three Rasps. We took the latest one, which natively supports wifi.
One of the developers happened to have basic electronic equipment: wires, soldering iron, resistors, potentiometers… We had to buy an analog/digital converter (MCP3008) as the Rasp PINs only receive digital signals, an amplifier to connect to the original speaker (if it was still working, which was not sure at that time), and an SD card to store the Raspbian OS.
Although Deezer has a robust and powerful player, which decodes our audio from our servers, it has never been ported to an ARM architecture so far.
Experimental work has been made by chance just before the hackathon, and we could finally use some test code. However, it was the first time the player would be adapted to a Raspberry, and it had to work! If not we had potential backups: to play only local tracks or download them first hand. These options were not really sexy, and we hoped hard to stream directly from the Raspberry.
Opening the radio
The old radio was not functioning anymore. One big question was what could be reused.
The power was not in there anymore, so we used a 9V battery to power the original assembly. It was not possible to hear any sound clearly. We realized quickly that some of the components were unplugged. We were not very confident about the original pieces and decided to test them one by one with a voltmeter.
Only the speaker, potentiometers, and buttons were useful for our project, and one by one we realized they were fully functional. When the speaker played music from an iPhone we connected through an open Jack cable we were very happy and very eased.
One of the two potentiometers was broken and we replaced it by an electric guitar potentiometer we had from a guitar player at Deezer. Little by little we could link the original components to our own circuit.
We also changed the original functioning of the three buttons to make them “pushable”. Initially, the buttons were exclusive. Because we finally decided to link the button to standard Deezer action: Repeat, Skip, and Like, we did not need the buttons to stay down. This was quite an easy mechanical trick to neutralize the hook.
The speaker was quite in good shape. As it’s a mono speaker and after considering an electronic assembly to transform a stereo to a mono signal, we decided to do this on the software side. It was definitely easier and faster. And at this stage of the project, we were already after lunch, and we wanted to move on!
Reading the Raspberry GPIOs
The GPIOs are the pins as visible on the Raspberry. The Raspberry Pi 3 has the following PINs:
From the list of these 40 pins, we must build our schema in order to link the three buttons, two potentiometers linked to the MCP3008 and the audio amplifier.
The Python program, which uses the Rpi GPIO library declares each GPIO as an input and reads, within a loop, the current value of each of them to check it and process it. Here is a simplified view of our program:
One of the great advantages concerning the team management is that this part of the project is autonomous from the schema assembly. We could easily split the team during the day and drastically improve our efficiency: hardware versus software. We had one button and one potentiometer to test our schema and to decide which GPIO to use. The final step of the day was to connect the assembly on the GPIO and theoretically it would work instantly. And it actually did!
Controlling the player
The audio player is written in C: it authenticates a valid Deezer user (we created one for the project) and handles the audio stream decryption.
The ARM compiler (armcc) was used and we had to recompile the player several times. The radio program is written in Python and controls the C player through system calls.
The user authentication is made using OAuth and the parameters are given through a hard coded file in the Raspberry. With this configuration, it is quite hard to personalize the radio with one’s account. It’s one of the limitations of this fast coded hackathon!
The player is given a list of Deezer song ids and play them one after the other. The loop itself catches electrical events from the three buttons and two potentiometers. From the following events, a specific player action is taken:
- Repeat Button: The current song ID is added again as the first element of the list and is played instantly
- Skip Button: The player is given the next element in the list and plays it instantly
- Discovery Potentiometer: When changed, the discovery value is sent as an input to the API. The resulted song ID list is given to the player and played immediately.
- Like Button: The public Deezer API is called with the song ID to like (no player action is taken)
The Discovery API
Deezer has a few mechanisms to control the discovery of a given mix or flow. However, they are not exposed via an API. As the Raspberry does not hold all the Deezer code stack and data, it was quite impossible to recover a list of song IDs according to a given discovery rate.
Besides, no discovery algorithms take as an entry such a thing as a discovery rate. The idea here was then to create a new private API, only in development, for our immediate needs. This API is currently only available in Deezer’s office, making the radio quite private! Come here to see it!
The Raspberry recovers the discovery potentiometer value and normalizes it between 0 and 100. A step of 10 is arbitrary set to avoid inopportune inaccuracy from the received signal (in fact, the analog values are constantly moving). We send the normalized value to our new Deezer API.
That API sends back a list of 10 tracks computed from the user’s profile. If the discovery value is close to 100 then many new song IDs are returned (not very popular, not listened by the user so far). On the contrary, popular tracks are returned and played one after the other.
Controlling the volume
Although it looks quite trivial, it has to be programmed! Recovering the value is exactly the same process than the discovery value (on another GPIO). However, the action is not to call a web API of course. We decided to call an internal Raspberry command called amixer (from Alsa Mixer). Another choice would have been controlling the Deezer player volume.
The Alsa Mixer controls the Master sound from a value from 0 to 65535, or a percentage. We decided to use the 0–65535 range as it provides a better accuracy. We observed that our Raspberry made audible sound from 22000 to 32000. The idea was then to map the potentiometer value to this range. A threshold is also set, but lower than 10 to have a better accuracy than the discovery.
After a day here is our old radio fully working. The main limitations are:
- Working only on Deezer network (hardcoded wifi configuration, and internal Discovery API)
- Hard coded user. We created a specific user for the Old Radio but the idea in the future is to be able to easily configure the radio to put anyone’s ID and make it personalized
As a bonus, here are more photos of the team working with wires.