Monter une passerelle radio FM vers IP

Comment créer une passerelle permettant de diffuser une radio FM vers un flux de webradio ?

Lors de la cérémonie d'ouverture des JO Paris 2024 du 26/07, la fréquence FM 107.9 MHz a été autorisée par l'ARCOM pour les organisateurs. Nous avons été plusieurs franciliens à écouter cette fréquence en parallèle de la télévision. La portée étant limitée (émetteur Tour Eiffel, PAR 10kW), il était intéressant de proposer un flux web audio qui reprenne ce signal FM pour les quelques dizaines de passionnés qui n'étaient pas dans cette zone de réception. Voici une description du montage improvisé qui a servi.

Je ne rentre pas dans les détails de la réception FM, mais la première chose à contrôler est qu'on est bien en zone de couverture de la station voulue et qu'on dispose d'une antenne adaptée à la fréquence.

Pour décrire l'expérience, nous allons utiliser 2 types de matériels :

  • Une carte professionnelle PCIe AudioScience ASI8821
  • Une clé rtl-sdr v3 grand public

Serveur de diffusion

Pour diffuser une webradio, il nous faut un serveur connecté à internet, et un logiciel serveur de stream. On va installer le vénérable icecast. L'OS est Debian12

1apt install icecast2

créer le fichier /etc/default/icecast2

1# Full path to the server configuration file
2CONFIGFILE="/etc/icecast2/icecast.xml"
3
4# Name or ID of the user and group the daemon should run under
5USERID=icecast2
6GROUPID=icecast
7
8# vérifier que c'est bien à true
9ENABLE="true"

créer le fichier /etc/icecast2.xml (et changez les mots de passe !)

 1<icecast>
 2    <location>Paris</location>
 3    <admin>aerogus</admin>
 4    <limits>
 5        <clients>100</clients>
 6        <sources>16</sources>
 7        <queue-size>524288</queue-size>
 8        <client-timeout>30</client-timeout>
 9        <header-timeout>15</header-timeout>
10        <source-timeout>10</source-timeout>
11        <burst-on-connect>1</burst-on-connect>
12        <burst-size>65535</burst-size>
13    </limits>
14
15    <authentication>
16        <source-password>changeme</source-password>
17        <relay-password>changeme</relay-password>
18        <admin-user>changeme</admin-user>
19        <admin-password>changeme</admin-password>
20    </authentication>
21
22    <hostname>ice.aerogus.example</hostname>
23
24    <listen-socket>
25        <port>8000</port>
26    </listen-socket>
27
28    <http-headers>
29        <header name="Access-Control-Allow-Origin" value="*" />
30    </http-headers>
31
32    <fileserve>1</fileserve>
33
34    <mount type="default">
35        <charset>UTF-8</charset>
36    </mount>
37
38    <paths>
39        <basedir>/usr/share/icecast2</basedir>
40        <logdir>/var/log/icecast2</logdir>
41        <webroot>/usr/share/icecast2/web</webroot>
42        <adminroot>/usr/share/icecast2/admin</adminroot>
43        <alias source="/" destination="/status.xsl"/>
44    </paths>
45
46    <logging>
47        <accesslog>access.log</accesslog>
48        <errorlog>error.log</errorlog>
49        <loglevel>4</loglevel>
50        <logsize>10000</logsize>
51    </logging>
52
53    <security>
54        <chroot>0</chroot>
55        <changeowner>
56            <user>icecast2</user>
57            <group>icecast</group>
58        </changeowner>
59    </security>
60</icecast>

Activer le serveur

1systemctl start icecast2

Vérifier que le serveur est actif

1 systemctl status icecast2
2● icecast2.service - LSB: Icecast2 streaming media server
3     Loaded: loaded (/etc/init.d/icecast2; generated)
4     Active: active (running)

N'oubliez pas d'ouvrir le port tcp/8000 sur votre firewall.

Allez à l'url http://<hostname>:8000 qui vous affichera la page d'accueil d'Icecast.

Note: il date un peu (2021), mais en complément vous pouvez aussi lire l'article sur l'installation de Icecast avec support SSL.

Alimenter le serveur de diffusion via une carte AudioScience ASI8821

Carte ASI8821 connectée à un Raspberry Pi 5 muni d&#39;un hat PCIe

Je passe sur la compilation des drivers. On a juste besoin de savoir que la commande init-tuner permet de configurer la fréquence du tuner et la commande asihpirec permet de lire sur la sortie standard le flux audio issu d'un tuner de la carte.

 1#!/usr/bin/env bash
 2##
 3# Stream d'une carte AudioScience vers le serveur Icecast
 4##
 5
 6ADAPTER_ID=0 # 0 à 7
 7TUNER_ID=0 # 0 à 7
 8BAND="FM" # FM si mono, FM2 si stéréo
 9FREQUENCY=$1 # en kHz
10DEEMPHASIS=50 # en μs, standard européen
11
12# on règle le tuner à la bonne fréquence
13init-tuner --adapter $ADAPTER_ID --tuner $TUNER_ID --band $BAND --frequency $FREQUENCY --deemphasis=$DEEMPHASIS
14
15# --format 2=PCM16 Little Endian, 4=MPEG1 Layer II, 5=MPEG1 Layer III, 8=PCM16 Big Endian, 14=F32 (défaut = 2)
16
17# méthode 1: on lit la sortie PCM de la carte tuner,
18# on encode en MP3 et on envoie le flux à icecast
19asihpirec --adapter $ADAPTER_ID --stream-number $TUNER_ID --format 2 --samplerate 48000 --channels 2 | \
20  ffmpeg -re -f s16le -ac 2 -ar 48000 -i pipe: -c:a libmp3lame \
21  -ice_name "$FREQUENCY kHz FM" -ice_description "Démo passerelle FM vers IP" \
22  icecast://source:changeme@ice.aerogus.example:8000/$FREQUENCY.mp3
23
24# ou méthode 2: la carte AudioScience permettant l'encodage matériel MPEG1 Layer III,
25# profitons en pour alléger un peu l'utilisation CPU du Raspberry Pi
26asihpirec --adapter $ADAPTER_ID --stream-number $TUNER_ID --format 5 --samplerate 48000 --channels 2 | \
27  ffmpeg -re -f mp3 -i pipe: -c:a copy \
28  -ice_name "$FREQUENCY kHz FM" -ice_description "Démo passerelle FM vers IP" \
29  icecast://source:changeme@ice.aerogus.example:8000/$FREQUENCY.mp3

Le flux de diffusion public est alors de la forme http://ice.aerogus.example:8000/$FREQUENCY.mp3

Alimenter le serveur de diffusion via une clé rtl-sdr et SDR++

Une clé SDR est un récepteur RF qui met à disposition d'un logiciel un flux numérique brut dit IQ. C'est au logiciel d'interpréter ce flux et d'y appliquer le "décodage" nécessaire, la démodulation de fréquence dans notre cas. L'app SDR++ de ryzerth est un excellent outil SDR qui va appliquer cette démodulation et qui va permettre de diffuser un signal audio PCM 16 bits 48kHz mono/stéréo sur le réseau en UDP. C'est donc très proche de la méthode 1 AudioScience qu'on a vu plus haut.

clé RTL-SDR sur un Raspberry Pi

SDR++ diffusant en UDP via les sinks

1ffmpeg -re -f s16le -ar 48000 -ac 2 -i udp://127.0.0.1:2024 \
2  -c:a libmp3lame -ab 128k -ac 2 -ar 48000 \
3  -ice_name "Test FM" \
4  -ice_description "Radio FM reçue par SDR++, streamée PCM en UDP, convertie en MP3, envoyée à Icecast" \
5  icecast://source:changeme@ice.aerogus.example:8000/test.mp3

Le flux de diffusion public est de la forme http://ice.aerogus.example:8000/test.mp3

Ressources

comments powered by Disqus