Wednesday, January 15, 2014
Arduino Yun Grooveshark Radio
I got an Arduino Yun as Christmas preset this year. After a few days playing around with it, I decided that I wanted to turn it into an internet audio playback device. I found there is a cool python library to access Grooveshark, which is even cooler than traditional internet radios... I will explain here the steps to get it to work. I assume basic Linux and programming knowledge in my explanation.
The first step was to get USB audio working as per the explanations in here... easy...
Next step was to get some audio player running on the Linux side which would play an mp3 from a URL (rather than from file as madplay). I checked on the available packages and there was no mplayer, no vlc, no mpg123... crap... so I checked on how to compile my own packages. The first step was to compile linino image and packages:
git clone https://github.com/arduino/linino.git
cd linino/trunk
./scripts/feeds uninstall -a
rm -rf feeds
./scripts/feeds update -a
./scripts/feeds install -a
rm -f .config
git checkout .config
make oldconfig
make V=s
During this process I found some compile issues, in fact I did not get to build all the packages, but seems like it was enough to later build mpg123.
In order to build the mpg123 package, I got the makefile from here, copied it inside my linino tree in linino/trunk/package/feeds/packages/mpg123/ and then did:
make package/mpg123/compile V=s
Somehow that did not create a .ipk file to install in the yun, as I was expecting, but everything from the ipk package that should have been created was available in linino/trunk/build_dir/target-mips_r2_uClibc-0.9.33.2/mpg123-1.13.2/ipkg-install/, so I just had to copy that folder into a pen drive and from there into the yun filesystem.
When I tried to run mpg123 I faced another issue, libltdl shared library was missing. Seems like that library was built during the linino image compilation here: linino/trunk/staging_dir/target-mips_r2_uClibc-0.9.33.2/usr/lib/libltdl.so.7.3.0. As with mpg123 before, I copied it into a pen drive and into the filesystem of the yun. Et voila... mpg123 was working.
Unfortunately, sound quality alternated between OK and very bad (with stuttering sound). In order to fix this, I created the file /etc/asound.conf with the following contents:
pcm.dmixer {
type dmix
ipc_key 1024
ipc_key_add_uid false
ipc_perm 0666
slave {
pcm "hw:0,0"
### WARNING: do NOT add period_time, period_size or buffer_size here!!! ###
rate 44100
}
bindings {
0 0
1 1
}
}
pcm.dsp0 {
type plug
slave.pcm "dmixer"
}
pcm.!default {
type plug
slave.pcm "dmixer"
}
pcm.default {
type plug
slave.pcm "dmixer"
}
ctl.mixer0 {
type hw
card 0
}
This came from here. That seemed to fix the issues.
OK, so we now have mpg123 working, yuhuuu... next step was pygrooveshark. I downloaded it from here, put it into a pendrive and did:
python setup.py install
Based on the pygrooveshark radio example, I made this python script in /root/examples-pygrooveshark/radio_mpg123.py which takes a number representing the radio genre as parameter (17 is for METAL, if you want to try it from the command line):
from __future__ import print_function
import subprocess
import sys
from grooveshark import Client
from grooveshark.classes import Radio
client = Client()
client.init()
cmdargs = str(sys.argv)
for song in client.radio(sys.argv[1]):
print(song.name)
print(song.artist.name)
print(song.album.name)
sys.stdout.flush()
subprocess.call(['mpg123', song.stream.url])
Tried running it but found another issue. Do not remember the exact error, but basically python on the yun was built without SSL support. The solution was to copy the file linino/trunk/staging_dir/target-mips_r2_uClibc-0.9.33.2/root-ar71xx/usr/lib/python2.7/lib-dynload/_ssl.so in /usr/lib/python2.7/lib-dynload/_ssl.so in the yun filesystem. Once that was done, I was able to run pygrooveshark scripts from the yun linux terminal.
Last step was to get some way of launching the different radio genres from the arduino/AVR side. Here is the hardware setup:
And here the sketch running on the AVR side:
#include <FileIO.h>
#define GENRE_NONE 0
#define GENRE_ROCK 12
#define GENRE_BLUES 230
#define GENRE_ELECTRONICA 67
#define GENRE_CLASSICROCK 3529
#define GENRE_INDIE 136
#define GENRE_METAL 17
int stations[] = { GENRE_NONE,
GENRE_ROCK,
GENRE_BLUES,
GENRE_ELECTRONICA,
GENRE_CLASSICROCK,
GENRE_INDIE,
GENRE_METAL };
int genres;
int val = 0;
int prevVal = 0;
Process radio_process;
void setup() {
genres = sizeof(stations)/sizeof(int);
Bridge.begin();
Serial.begin(9600);
while(!Serial); // wait for Serial port to connect.
Serial.println("Grooveshark Radio example");
start_radio(val);
}
void loop() {
val = analogRead(3);
val = (val*genres)/1023;
if(val != prevVal) {
String text;
text = "Value: ";
text += val;
Serial.println(text);
start_radio(val);
prevVal = val;
}
while(radio_process.available() > 0){
char c = radio_process.read();
Serial.print(c);
}
delay(400);
}
void start_radio(int val) {
String parameter = "";
radio_process.close();
Process killer;
killer.begin("killall");
killer.addParameter("mpg123");
killer.run();
if(stations[val] != 0) {
radio_process.begin("python");
radio_process.addParameter("/root/examples-pygrooveshark/radio_mpg123.py");
parameter+= stations[val];
radio_process.addParameter(parameter);
radio_process.runAsynchronously();
}
else {
radio_process.begin("echo");
radio_process.addParameter("Do Nothing!!!");
radio_process.runAsynchronously();
}
}
I can change grooveshark radios by moving the potentiometer.
What is next? I have ordered an LCD screen and a rotary encoder for user interface. My plan is to allow playback of grooveshark user favourites and playlists, but that requires a lot more changes in both the AVR and Linux.
Labels:
arduino,
grooveshark,
linux,
python,
yun
Subscribe to:
Post Comments (Atom)
your blog describe a nice view of the things. It is very effective for the reader. Please post more blog related to this.
ReplyDeleteVisit :- radio Arduino