Raspberry Pi: Internet Ràdio

De Wikijoan
Dreceres ràpides: navegació, cerca

Contingut

Introducció

El que es busca és una cosa molt mínima, amb un sol pulsador. Apretar dues vegades ràpidament el botó per engegar/aturar la ràdio. Si està engegada, en anar apretant vaig canviant d'emissora.

Desenvolupament

Em baso en:

i concretament en Setting up MPD and MPC:

Tot el sistema està basat en mpd (music player daemon) i mpc (music player client), que són el servidor i el client (el client controla el servidor)

$ sudo apt-get install mpd mpc

El fitxer de configuració és /etc/mpd.conf

De la directiva audio_output no toco res:

audio_output {
        type            "alsa"
        name            "My ALSA Device"
        device          "hw:0,0"        # optional
        format          "44100:16:2"    # optional
        mixer_device    "default"       # optional
        mixer_control   "PCM"           # optional
        mixer_index     "0"             # optional
}

i de la directiva audio_input el link diu de registrar-se a last.fm (http://www.last.fm/) (jo ho he fet, joanillo/jq****), però en realitat he comprovat que no cal. La única cosa que necessita audio_input és una línia que posi plugin, encara que estigui buida:

input {
#       plugin          "lastfm"  
#       user            "joanillo"
#       password        "jq****"
plugin ""
#        plugin "curl"
#       proxy "proxy.isp.com:8080"
#       proxy_user "user"
#       proxy_password "password"
}

per tant la cosa queda molt simple.

last.fm és interessant perquè tenen una API i per tant pots programar les teves pròpies aplicacions d'escriptori o per a mòbil. Però d'altra banda sembla ser que tenen bastants problemes de llicències.

A /etc/modules he de fer referència al xip que té la RP, que és el SoC de Broadcom 2835:

snd_bcm2835

Tenim dos sortides d'audio: el jack stereo (sortida 1), i HDMI (sortida 2):

$ sudo amixer cset numid=3 1

Ara ja podem reiniciar el servei mpd:

$ sudo /etc/init.d/mpd restart

i puc començar a escoltar música:

$ mpc
volume:100%   repeat: on    random: off   single: off   consume: off

$ mpc add http://s1.radio.lclhst.net:1337/
$ mpc play
Minimal, Techno, Electro Sets @ http://radio.lclhst.net/: Patrick Schulz - Promotional Mix - October 2008
[playing] #1/1 0:04/0:00 (0%)
volume:100% repeat: on random: off single: off consume: off

funciona perfectament. A mi no em surt volume:100%, sinó que em surt volume: n/c.

Per controlar el volum per línia de comanda seria:

$ mpc volume 100

però a mi no em funciona (tot i que per defecte s'escolta bé al 100%). Si vull que funcioni he de fer:

$ joe /etc/mpd/mpd.conf
i descomentar
mixer_type                      "software"

aleshores ja puc controlar el volum per línia de comanda

$ mpc volume 50
$ mpc volume 100

Llistes de ràdio

He provat amb una ràdio d'Internet que fa música electrònica:

Server Status: Server is currently up and public.
Stream Title: Minimal, Techno, Electro Sets @ http://radio.lclhst.net/
Stream Genre: Electronic
Current Song: Wighnomy Brothers - Klangkino 30.10.2008

Si vull afegir noves ràdios ho faig amb la comanda add:

mpc add http://s1.radio.lclhst.net:1337/
mpc add http://s3.radio.lclhst.net:1337/

i veig les ràdios actives amb

$ mpc playlist

Puc fer sonar la primera o la segona ràdio fent:

$ mpc play 1
$ mpc play 2

Per esborrar la llista de ràdios:

$ mpc clear

Com trobo d'altres ràdios disponibles?:

És fàcil utilitzar les que tenen el format que conec. Per exemple:

# ACE FM
$ mpc add http://208.43.9.96:8106/
# vaughan radio
mpc add http://vaughanradio.streaming-pro.com:8012/
# disco music radio
mpc add http://www.discomusicradio.com:8100/

També hi ha una classificació per gèneres. Per escoltar jazz:

per ex,

Ara bé, què passa amb les URL que tenen format pls o m3u. Doncs molt fàcil, són fitxers de text que a dins tenen la URL a utilitzar. Una URL o vàries, doncs poden ser playlists.

Per exemple, amb iCatJazz, el contingut del fitxer http://directe-http.emissio.catradio.cat:8000/catradio.cat/icat_jazz.m3u és http://directe-http.emissio.catradio.cat:8000/catradio.cat/icat_jazz, i només s'ha de fer:

$ mpc add http://directe-http.emissio.catradio.cat:8000/catradio.cat/icat_jazz

El mateix per als fitxers pls:

$ cat aac_jazz.pls 
[playlist]
File1=http://188.165.20.29:8750
Title1=Server1-> >>> P O L S K A S T A C J A <<< - JAZZ (AACPLUS - Wymagany nowy winamp!)
Length1=-1
File2=http://188.165.22.29:8750
Title2=Server2-> >>> P O L S K A S T A C J A <<< - JAZZ (AACPLUS - Wymagany nowy winamp!)
Length2=-1
File3=http://87.98.236.207:80
Title3=Server3-> >>> P O L S K A S T A C J A <<< - JAZZ (AACPLUS - Wymagany nowy winamp!)
Length3=-1
File4=http://91.121.92.167:8700
Title4=Server1-> >>> P O L S K A S T A C J A <<<- JAZZ
Length4=-1
NumberOfEntries=4
Version=2

En aquest cas veig que conté diversos fitxers.

$ mpc playlist
ICat Jazz
>>> POLSKASTACJA .PL >>> - JAZZ (Polskie Radio),aacplus: Gerry Mulligan - Blues For Gerry

Es pot obtenir directament la informació que hi ha dins els fitxers (http://www.raspberrypi.org/phpBB3/viewtopic.php?f=9&t=4031). Un exemple de codi amb bash per obtenir Los 40 principales seria:

#!/bin/bash
rm LOS40*
wget http://provisioning.streamtheworld.com/pls/LOS40.pls
grep "File1=" LOS40.pls > streamaddr
mpc clear
mpc add $(sed 's/File1=//g' streamaddr)
mpc play

es tracta d'extreure la informació que hi ha dins el fitxer.

D'altres ràdios:

Recuperar la informació d'allò que estic escoltant

$ mpc playlist
ICat Jazz
>>> POLSKASTACJA .PL >>> - JAZZ (Polskie Radio),aacplus: Gerry Mulligan - Blues For Gerry

$ mpc play 1
$ mpc play 2

Amb l'opció -f puc filtrar la informació que em dona la comanda playlist:

$ mpc -f "[[%artist% - ]%title%]|[%file%]" playlist
http://directe-http.emissio.catradio.cat:8000/catradio.cat/icat_jazz
Fourplay - Put Our Hearts Together (Vocal Version)

$ mpc -f "[%title%]" playlist

Fourplay - Put Our Hearts Together (Vocal Version)


Programació

Es tracta de programar els scripts per arrencar/aturar el servidor mpd, i llegir les llstes de ràdio que he seleccionat. L'electrònica necessària és mínima, tant sols cal un botó i programar un pin GPIO. Evidentment la cosa es pot complicar amb una pantalla LCD per saber què estic escoltant, més botons, etc,... però no és l'objectiu.

El primer que hem de fer és que el dimoni mpd no arrenqui en l'inici del sistema. Un podria pensar que seria tan fàcil com canviar true per false en el fitxer /etc/init.d/mpd, però no. La solució està més avall, desactivar el dimoni amb rc-update.

radio_internet_v1.sh (versió 1):

#!/bin/bash

#functions
start_mpd ()
{
  echo Starting mpd...
  /etc/init.d/mpd start
  sleep 2
}

stop_mpd ()
{
  echo Stopping mpd...
  /etc/init.d/mpd stop
  sleep 2
}

play_radio ()
{
echo ${MYARRAY[$id_radio]}
mpc clear
mpc add ${MYARRAY[$id_radio]}
mpc play
}

#main program
llista="radio_internet.txt"

index=0

while read line ; do
   MYARRAY[$index]="$line"
   index=$(($index+1))
done < $llista  
                      
echo ${MYARRAY[0]}: ${MYARRAY[1]}
echo $index

RANG=$((($index+1)/2))
number=$RANDOM
let "number %= $RANG"
#           ^^
#echo "Random number less than $RANG  ---  $number"
id_radio=$((($number*2)+1))
echo "radio seleccionada: $id_radio"
                     
#start_mpd
play_radio

i la versió 4, radio_internet_v4.sh queda:

#!/bin/bash

#led
red=0
#botó
button=8

# functions:
setup ()
{
  gpio mode $red out
  gpio mode $button in
}

waitButton1sttime ()
{

  while [ `gpio read $button` = 1 ]; do
    espera=1
    sleep 0.03
  done
  
  #from: http://stackoverflow.com/questions/3683434/using-time-command-in-bash-script
  # UNIX timestamp concatenated with nanoseconds
  T="$(date +%s%N)"

  while [ `gpio read $button` = 0 ]; do
    sleep 0.03
  done
   
}
           
waitButton2ndtime ()
{

  T1="$(($(date +%s%N)-T))"
                  
  while [ `gpio read $button` = 1 ]  && [ $T1 -le 300000000 ]; do
    sleep 0.03
    # Time interval in nanoseconds
    T1="$(($(date +%s%N)-T))"
  done

  while [ `gpio read $button` = 0 ]; do
    sleep 0.03
  done

  if [ $T1 -le 300000000 ]; then
    #echo "start/stop dimoni"
    start_stop_mpd
  else
    #echo "canvi de canal"
    canvi_canal
  fi

}  
                            
       
start_stop_mpd ()
{
  for i in {1..5}
  do
    gpio write $red 1
    sleep .02
    gpio write $red 0
    sleep .02
  done
  if [ -z `pidof -s mpd` ]; then 
    echo "Starting mpd..."
    /etc/init.d/mpd start
  else
    echo "Stopping mpd..."
    /etc/init.d/mpd stop
  fi
  for i in {1..5}
  do
    gpio write $red 1
    sleep .02
    gpio write $red 0
    sleep .02
  done
}

canvi_canal ()
{
  if [ $id_radio -le $(($index-3)) ]; then
    id_radio=$(($id_radio+2))
  else
    id_radio=1
  fi
  echo
  echo ${MYARRAY[($id_radio-1)]}

  gpio write $red 1
  mpc clear
  mpc add ${MYARRAY[$id_radio]}
  mpc play
  gpio write $red 0
}

#main program
llista="radio_internet.txt"
index=0

while read line ; do
   MYARRAY[$index]="$line"
   index=$(($index+1))
done < $llista  
                      
#RANG=$((($index+1)/2))
#number=$RANDOM
#let "number %= $RANG"
##echo "Random number less than $RANG  ---  $number"
#id_radio=$((($number*2)+1))
 
echo Raspberry Pi Internet Radio
echo Joan Quintana - joanillo
echo www.joanillo.org
echo Dec 2012
echo

setup
while true; do
  waitButton1sttime
  waitButton2ndtime
done   

el ftixer on tinc les emissores és, per exemple (és una barreja d'emissores sense cap criteri). (No oblidar-se un retorn de carro al final). Fitxer radio_internet.txt:

#1 Catalunya Ràdio
http://directe-http.emissio.catradio.cat:8000/catradio.cat/cat_radio
#2 iCatFM
http://directe-http.emissio.catradio.cat:8000/catradio.cat/tot_cat
#3 iCat JAZZ
http://directe-http.emissio.catradio.cat:8000/catradio.cat/icat_jazz
#4 JAZZ AACPlus
http://188.165.20.29:8750
#5 Los 40 Principales
http://5253.live.streamtheworld.com:80/LOS40_SC
#6 Minimal, Techno, Electro Sets
http://s1.radio.lclhst.net:1337/
#7 ACE FM
http://208.43.9.96:8106/
#8 vaughan radio
http://vaughanradio.streaming-pro.com:8012/
#9 Catalunya Música
http://directe-http.emissio.catradio.cat:8000/catradio.cat/cat_classica

Ara només falta que aquest script s'executi en l'inici del sistema...

script inici del sistema

Es tracta de què s'executi el script com a root, una sola vegada, i abans d'iniciar sessió. Es tracta de ficar el script en el directori /etc/init.d, com si fos un dimoni. Demonitzar un script és en teoria fàcil, a la pràctica no ho és tant. La solució que a mi m'ha funcionat, pas per pas, és:

1. Primer de tot eliminar el dimoni mpd de l'inici automàtic del sistema. Això es fa fent update-rc mpd remove, o bé eliminar els softlinks que fan referència a mpd en els directoris /etc/rc.0 a /etc/rc.6.

2. copio radio_internet_vx.sh i radio_internet.txt al directori /etc/init.d

3. és important en el script ficar les rutes absolutes. Per exemple, substituir gpio per /usr/local/bin/gpio; sleep per /bin/sleep; date per /bin/date; mpc /usr/bin/mpc. Però això és clar és una tonteria. És millor ficar al principi de tot:

PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin

i el que sí que és important és ficar la ruta del fitxer on estan les emissores:

llista="/etc/init.d/radio_internet.txt"

4. Aprofitarem el script rc.local (i així m'evitaré fer els softlinks per al meu script). editar el fitxer /etc/init.d/rc.local i afegim una línia:

do_start() {
bash /etc/init.d/radio_internet_v4.sh
        if [ -x /etc/rc.local ]; then
...

El que fa aquest script és comprovar si existeix el directori rc.local (que existeix a Ubuntu però no pas a Debian). Jo el que faig és executar aquest script abans de fer la comprovació de l'existència de la carpeta. I el que és important és no oblidar-se el bash al davant.

5. reiniciem la BP i comprovem que arrenca bé el script

$ shutdown -r now

reconnectem

$ ssh pi@192.168.1.138
$ ps aux | grep mpd

$ ps aux | grep radio
root      1932  5.8  0.6   2796  1252 ?        S    22:17   0:03 bash /etc/init.d/radio_internet_v4.sh

radio_internet_v6.sh: (canvi: he canviat el pin al qual està connectat el botó. El pin 8 passa a ser el pin 1, però aquest canvi no és trivial, doncs per al pin 1 he de programar que estigui habilitat la resistència de pull-up, veure més avall)

#!/bin/bash
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin

#led
red=0
#botó
#button=8
button=1

# functions:
setup ()
{
  gpio mode $red out
  #gpio mode $button in
  gpio mode $button up
}

waitButton1sttime ()
{

  while [ `gpio read $button` = 1 ]; do
    sleep 0.03
  done
  
  #from: http://stackoverflow.com/questions/3683434/using-time-command-in-bash-script
  # UNIX timestamp concatenated with nanoseconds
  T="$(date +%s%N)"

  while [ `/usr/local/bin/gpio read $button` = 0 ]; do
    sleep 0.03
  done
   
}
           
waitButton2ndtime ()
{

  T1="$(($(date +%s%N)-T))"
                  
  while [ `gpio read $button` = 1 ]  && [ $T1 -le 300000000 ]; do
    sleep 0.03
    # Time interval in nanoseconds
    T1="$(($(date +%s%N)-T))"
  done

  while [ `gpio read $button` = 0 ]; do
    sleep 0.03
  done

  if [ $T1 -le 300000000 ]; then
    #echo "start/stop dimoni"
    start_stop_mpd
  else
    #echo "canvi de canal"
    canvi_canal
  fi

}  
                            
       
start_stop_mpd ()
{
  for i in {1..5}
  do
    gpio write $red 1
    sleep .02
    gpio write $red 0
    sleep .02
  done
  if [ -z `pidof -s mpd` ]; then 
    echo "Starting mpd..."
    /etc/init.d/mpd start
  else
    echo "Stopping mpd..."
    /etc/init.d/mpd stop
  fi
  for i in {1..5}
  do
    gpio write $red 1
    sleep .02
    gpio write $red 0
    sleep .02
  done
}

canvi_canal ()
{
  if [ $id_radio -le $(($index-3)) ]; then
    id_radio=$(($id_radio+2))
  else
    id_radio=1
  fi
  echo
  echo ${MYARRAY[($id_radio-1)]}

  gpio write $red 1
  mpc clear
  mpc add ${MYARRAY[$id_radio]}
  mpc play
  gpio write $red 0
}

#main program
llista="/etc/init.d/radio_internet.txt"
index=0

while read line ; do
   MYARRAY[$index]="$line"
   index=$(($index+1))
done < $llista  
                      
#RANG=$((($index+1)/2))
#number=$RANDOM
#let "number %= $RANG"
##echo "Random number less than $RANG  ---  $number"
#id_radio=$((($number*2)+1))
 
echo Raspberry Pi Internet Radio
echo Joan Quintana - joanillo
echo www.joanillo.org
echo Dec 2012
echo

setup
while true; do
  waitButton1sttime
  waitButton2ndtime
done    

Llistat d'emissores de Jazz europees

I aquí va el fitxer on tinc llistades 40 emissores de Jazz que funcionen per Internet: (radio_internet_jazz.txt)

# iCat Jazz Barcelona
http://directe-http.emissio.catradio.cat:8000/catradio.cat/icat_jazz
# Crooze.fm Antwerp Belgium
http://193.227.114.74:9000/
# Jazz FM Sofia Bulgaria
http://live.btvradio.bg:8000/jazz-fm.mp3
# Ro Jazz Prague
http://stream3.rozhlas.cz:8000/jazz_low.ogg
# DR P8 Jazz Copenhagen
http://live-icy.gss.dr.dk:8000/A/A22H.mp3
# Jazz Radio Lyon
http://broadcast.infomaniak.net:80/jazzradio-high.mp3
# Jazz Radio Classic Jazz Lyon
http://broadcast.infomaniak.net:80/jazz-wr01-128.mp3
# Jazz Radio Manouche Lyon
http://broadcast.infomaniak.net:80/jazz-wr02-128.mp3
# Jazz Radio New Orleans Lyon
http://broadcast.infomaniak.net:80/jazz-wr03-128.mp3
# Jazz Radio Electro Swing Lyon
http://broadcast.infomaniak.net:80/jazz-wr04-128.mp3
# Jazz Radio Jazz Contemporary Lyon
http://broadcast.infomaniak.net:80/jazz-wr05-128.mp3
# Jazz Radio Jazz Funk Lyon
http://broadcast.infomaniak.net:80/jazz-wr06-128.mp3
# Jazz Radio Jazz Gospel Lyon
http://broadcast.infomaniak.net:80/jazz-wr07-128.mp3
# Jazz Radio Jazz Groove Lyon
http://broadcast.infomaniak.net:80/jazz-wr08-128.mp3
# Jazz Radio Jazz Latin Lyon
http://broadcast.infomaniak.net:80/jazz-wr09-128.mp3
# Jazz Radio Jazz Soul Lyon
http://broadcast.infomaniak.net:80/jazz-wr10-128.mp3
# Jazz Radio Jazz Soul Food Lyon
http://broadcast.infomaniak.net:80/jazz-wr12-128.mp3
# Jazz Radio Black Music Lyon
http://broadcast.infomaniak.net:80/jazzblackmusic-high.mp3
# Jazz Radio Blues Lyon
http://broadcast.infomaniak.net:80/jazzblues-high.mp3
# Jazz Radio Ladies & Crooners Lyon
http://broadcast.infomaniak.net:80/jazzladiescrooners-high.mp3
# Jazz Radio Lounge Lyon
http://broadcast.infomaniak.net:80/jazzlounge-high.mp3
# LinasJazz
http://87.98.175.43:8010
# Swing FM Limoges
http://radio.swingfm.asso.fr:8000
# TSF Jazz Paris
http://tsfjazz.ice.infomaniak.ch:80/tsfjazz-high
# JazzRadio 101.9 Berlin
http://84.16.227.59:8250/;stream.mp3
# Coolradio Jazz Ingolstadt Germany
http://178.32.115.9:7040/coolradio-jazz-aac48.aacp
# FFH Digital Jazz Frankfurt
http://mp3.ffh.de/ffhchannels/hqjazz.mp3
# SR 2 - Off-Beat Saarbrücken Germany
http://gffstream.ic.llnwd.net/stream/gffstream_w25a
# Jazz Radio Budapest
http://194.38.105.21:8002/
# 90.9 Jazzy Budapest
http://online.jazzy.hu:80/stream/1/
# Jazz FM Skopje Macedonia
http://217.16.69.17:8000/jazz.mp3
# Radio 6 Jazz Hilversum Netherlands
http://icecast.omroep.nl:80/radio6-jazzjong-mp3
# NRK Jazz Oslo
http://lyd.nrk.no:80/nrk_radio_jazz_aac_h
# RadioJAZZ.fm Poland
http://stream.radiojazz.fm:8000/radiojazzfm-hi.mp3
# PolskaStacja Jazz Poland
http://188.165.20.29:8750
# RMF Smooth Jazz Kraków
http://files.kusmierz.be/rmf/smoothjazz-1facts.mp3
# Radio Crazy Jazz Switzerland
http://stream2138.init7.net:80
# Radio Crazy Modern Jazz Switzerland
http://stream2140.init7.net:80
# TSTU Jazz Ternopil Ukraine
http://radio.tstu.edu.ua:8000/jazz
# Jazz FM London
http://listen.onmyradio.net:8002/

pull-up pull-down resistors

Fins ara hem utilitzat la següent configuració, doncs el tutorial que seguia deia que aquest pin tenia un pull-up resistor.

button=8
gpio mode $button input

Bé, en general, els pins tenen tan un pull-up com un pull-down resistor, i es pot programar. Si jo faig button=1 el programa deixa de funcionar (suposo que per defecte està connectat al pull-down). Per tal de què funcioni per capturar senyals d'entrada he de fer servir la resistència de pull-up, i això es fa de la següent manera.

button=1
gpio mode $button up

En qualsevol cas, és un tema que no he trobat una informació clara i precisa. La man page de gpio diu:

       mode <pin> <mode>
              Set a pin into input, output or pwm mode. Can also use the literals up, down or tri to set the internal pull-up,
              pull-down or tristate (off) controls

Un tutorial de buttons i switches: http://www.cl.cam.ac.uk/~db434/raspi/buttons_and_switches/

Enllaços


creat per Joan Quintana Compte, desembre 2012

Eines de l'usuari
Espais de noms
Variants
Accions
Navegació
IES Jaume Balmes
Màquines recreatives
CNC
Informàtica musical
joanillo.org Planet
Eines