Et si votre iPhone pouvait envoyer n’importe quelle musique vers une sorte de platine vinyle virtuelle, avant que le son n’arrive sur vos HomePod ?
C’est exactement ce que nous allons construire avec un Raspberry Pi.
Le principe est assez réjouissant : depuis l’iPhone, on choisit simplement une nouvelle destination AirPlay appelée AirVinyl. Le Raspberry Pi reçoit alors le morceau, le traite en temps réel pour lui ajouter les petites imperfections qui font le charme du vinyle — souffle, craquements, légère instabilité de hauteur, coloration — puis renvoie le résultat vers les HomePod.
À l’usage, cela donne simplement :
iPhone
│
│ AirPlay
▼
AirVinyl
│
│ traitement « vinyle »
▼
HomePod
Et une fois l’installation terminée, tout démarre automatiquement avec le Raspberry Pi. Pas de commande à saisir avant d’écouter de la musique.
Sous le capot, notre petite chaîne audio ressemble à ceci :
iPhone
│
│ AirPlay
▼
Shairport Sync
│
│ PCM 16 bits / 44,1 kHz
▼
FFmpeg
│
│ wow + flutter
│ saturation
│ souffle
│ craquements
▼
OwnTone
│
│ AirPlay 2
▼
HomePod(s)
J’ai réalisé le projet avec un Raspberry Pi 3, preuve qu’il n’est même pas nécessaire de lui consacrer une machine récente.
L’idée de ce tutoriel est de progresser tranquillement : à chaque étape importante, on vérifie que tout fonctionne avant d’ajouter la suivante. Si quelque chose coince, on sait donc immédiatement où regarder.
1. Préparer le Raspberry Pi
J’ai choisi Raspberry Pi OS Lite 64 bits.
Nous n’avons besoin d’aucune interface graphique : AirVinyl va fonctionner comme un petit appareil audio autonome.
Dans Raspberry Pi Imager, configurez directement le Wi-Fi, SSH, votre utilisateur et un nom d’hôte. J’ai choisi :
AirVinyl
Après le premier démarrage, connectez-vous en SSH :
ssh alex@airvinyl.local
Évidemment, remplacez alex par votre utilisateur.
Petit contrôle avant de commencer
Les Raspberry Pi, surtout les anciens modèles, sont assez sensibles à leur alimentation. Autant vérifier tout de suite :
vcgencmd get_throttled
Le résultat parfait est :
throttled=0x0
Si vous l’obtenez, le Pi est correctement alimenté et nous pouvons continuer.
Mettez ensuite le système à jour :
sudo apt update
sudo apt full-upgrade -y
Puis installez déjà FFmpeg et les outils Avahi :
sudo apt install -y ffmpeg avahi-utils
2. Transformer le Raspberry Pi en récepteur AirPlay
La première brique s’appelle Shairport Sync.
Son rôle est simple :
iPhone
↓
AirPlay
↓
Raspberry Pi
Nous allons utiliser sa sortie pipe, qui permet de récupérer le son sous forme de données PCM brutes et de l’envoyer ensuite où nous voulons.
Installez les dépendances :
sudo apt install --no-install-recommends -y \
build-essential git autoconf automake libtool \
libpopt-dev libconfig-dev libasound2-dev \
avahi-daemon libavahi-client-dev \
libssl-dev libsoxr-dev \
libavutil-dev libavcodec-dev libavformat-dev \
systemd-dev
Téléchargez ensuite Shairport Sync :
cd ~
git clone https://github.com/mikebrady/shairport-sync.git
cd shairport-sync
autoreconf -fi
Configurez la compilation :
./configure \
--sysconfdir=/etc \
--with-alsa \
--with-soxr \
--with-avahi \
--with-ssl=openssl \
--with-systemd-startup \
--with-ffmpeg \
--with-pipe \
--with-metadata \
--with-metadata-pipe
Compilez :
make -j$(nproc)
sudo make install
Puis activez le service :
sudo systemctl enable shairport-sync
Vérification n°1 : avons-nous bien le bon Shairport ?
shairport-sync -V
Puis :
shairport-sync -h
Dans la sortie, vous devez notamment retrouver :
Available audio backends:
pipe
Parfait : notre Raspberry sait maintenant recevoir de l’AirPlay et nous laisser récupérer le signal audio.
3. Pourquoi utiliser AirPlay classique à l’entrée ?
AirVinyl utilise volontairement deux générations d’AirPlay :
iPhone
↓
AirPlay classique
↓
Shairport
puis :
OwnTone
↓
AirPlay 2
↓
HomePod
Ce choix nous simplifie beaucoup la vie.
AirPlay classique fournit parfaitement ce dont notre chaîne a besoin : un flux stéréo 16 bits / 44,1 kHz, que nous pouvons envoyer directement vers FFmpeg.
Il permet aussi de réserver le mécanisme de synchronisation PTP d’AirPlay 2 à OwnTone, qui en aura besoin pour communiquer avec les HomePod.
4. Installer OwnTone
Notre Raspberry sait recevoir de la musique. Il doit maintenant savoir la renvoyer vers des enceintes AirPlay.
C’est le rôle d’OwnTone.
Installez ses dépendances :
sudo apt install -y \
build-essential git autotools-dev autoconf automake libtool \
gettext gawk gperf bison flex \
libconfuse-dev libunistring-dev libsqlite3-dev \
libavcodec-dev libavformat-dev libavfilter-dev \
libswscale-dev libavutil-dev libasound2-dev \
libxml2-dev libgcrypt20-dev libavahi-client-dev \
zlib1g-dev libevent-dev libplist-dev libsodium-dev \
libjson-c-dev libwebsockets-dev \
libcurl4-openssl-dev libprotobuf-c-dev
Puis :
cd ~
git clone https://github.com/owntone/owntone-server.git
cd owntone-server
autoreconf -i
./configure \
--prefix=/usr \
--sysconfdir=/etc \
--localstatedir=/var \
--enable-install-user
make -j$(nproc)
sudo make install
5. Créer le « câble audio virtuel »
Shairport et OwnTone vont communiquer au moyen d’un FIFO, autrement dit un pipe Unix.
On peut vraiment le voir comme un câble audio virtuel :
Shairport ────────► OwnTone
Créons son dossier :
sudo mkdir -p /srv/airvinyl/library
Puis le pipe audio :
sudo mkfifo /srv/airvinyl/library/AirVinyl
sudo chmod 666 /srv/airvinyl/library/AirVinyl
Et celui des métadonnées :
sudo mkfifo /srv/airvinyl/library/AirVinyl.metadata
sudo chmod 666 /srv/airvinyl/library/AirVinyl.metadata
Vérification n°2 : nos pipes existent-ils ?
ls -l /srv/airvinyl/library/AirVinyl*
Les lignes doivent commencer par :
p
Par exemple :
prw-rw-rw-
Ce p indique qu’il s’agit bien de pipes.
6. Configurer OwnTone
Ouvrez :
sudo nano /etc/owntone.conf
Dans la section :
library {
indiquez :
directories = { "/srv/airvinyl/library" }
Nous n’avons pas besoin que le Raspberry joue lui-même le son sur sa sortie audio.
Dans :
audio {
mettez :
type = "disabled"
Démarrez OwnTone :
sudo systemctl enable --now owntone
sudo systemctl restart owntone
Vérification n°3 : OwnTone voit-il vos HomePod ?
Ouvrez dans votre navigateur :
http://airvinyl.local:3689
Dans :
Settings → Remotes & Outputs
vos appareils AirPlay devraient apparaître.
Vous pouvez également les voir depuis le terminal :
curl -s http://localhost:3689/api/outputs | python3 -m json.tool
Sélectionnez le HomePod sur lequel vous souhaitez faire le premier test.
Un détail qui nous a surpris pendant l’installation : le volume de sortie OwnTone était initialement à 50. Le résultat semblait anormalement faible.
Si nécessaire, mettez la sortie à 100 depuis l’interface OwnTone.
7. Configurer Shairport
Ouvrez :
sudo nano /etc/shairport-sync.conf
Nous allons appeler notre nouveau récepteur :
AirVinyl
La configuration générale devient :
general =
{
name = "AirVinyl";
service_type = "classic";
output_backend = "pipe";
};
Puis :
pipe =
{
name = "/srv/airvinyl/library/AirVinyl";
output_rate = 44100;
output_format = "S16_LE";
output_channels = 2;
};
Enfin :
metadata =
{
enabled = "yes";
include_cover_art = "yes";
pipe_name = "/srv/airvinyl/library/AirVinyl.metadata";
};
Redémarrez Shairport :
sudo systemctl restart shairport-sync
Vérification n°4 : AirVinyl est-il apparu sur l’iPhone ?
Vérifiez :
sudo systemctl status shairport-sync --no-pager
Vous devez obtenir :
Active: active (running)
Prenez maintenant votre iPhone et ouvrez le menu AirPlay.
Et normalement, petit moment satisfaisant :
AirVinyl
apparaît parmi vos enceintes.
Sélectionnez-le et lancez un morceau.
À ce stade, nous n’avons encore ajouté aucun effet. C’est volontaire.
Nous voulons d’abord valider ceci :
iPhone
↓
Shairport
↓
OwnTone
↓
HomePod
Pendant que la musique joue :
curl -s http://localhost:3689/api/player
Vous devez voir :
"state": "play"
Si le compteur de progression avance et que vous entendez la musique sur le HomePod, félicitations : vous avez déjà fabriqué un relais AirPlay avec un Raspberry Pi.
Maintenant, on va le transformer en platine vinyle.
8. Ajouter FFmpeg au milieu
Notre architecture devient :
Shairport
↓
FFmpeg
↓
OwnTone
Arrêtez Shairport :
sudo systemctl stop shairport-sync
Créez un nouveau pipe :
sudo mkfifo /srv/airvinyl/input.pcm
sudo chmod 666 /srv/airvinyl/input.pcm
Puis revenez dans :
sudo nano /etc/shairport-sync.conf
Dans la section pipe, remplacez :
name = "/srv/airvinyl/library/AirVinyl";
par :
name = "/srv/airvinyl/input.pcm";
Les métadonnées restent, elles, envoyées directement vers :
/srv/airvinyl/library/AirVinyl.metadata
9. Tester FFmpeg sans modifier le son
Avant d’ajouter des effets, vérifions simplement que FFmpeg peut s’insérer dans la chaîne sans rien casser.
Lancez :
ffmpeg -y \
-hide_banner \
-loglevel warning \
-f s16le \
-ar 44100 \
-ac 2 \
-i /srv/airvinyl/input.pcm \
-af "anull" \
-f s16le \
-ar 44100 \
-ac 2 \
/srv/airvinyl/library/AirVinyl
Dans un deuxième terminal :
sudo systemctl start shairport-sync
Relancez un morceau sur l’iPhone.
Vérification n°5
Si vous entendez exactement votre morceau comme avant, notre chaîne complète fonctionne :
iPhone
↓
Shairport
↓
FFmpeg
↓
OwnTone
↓
HomePod
Nous pouvons maintenant faire subir absolument ce que nous voulons au son.
10. Un petit test amusant avant le vrai vinyle
Pour être absolument certain que FFmpeg traite bien le signal, faisons quelque chose de volontairement spectaculaire.
Arrêtez Shairport :
sudo systemctl stop shairport-sync
Arrêtez FFmpeg avec :
Ctrl+C
Puis lancez :
ffmpeg -y \
-hide_banner \
-loglevel warning \
-f s16le \
-ar 44100 \
-ac 2 \
-i /srv/airvinyl/input.pcm \
-af "lowpass=f=2500,aecho=0.8:0.88:250:0.8,tremolo=f=4:d=0.8" \
-f s16le \
-ar 44100 \
-ac 2 \
/srv/airvinyl/library/AirVinyl
Puis :
sudo systemctl start shairport-sync
Relancez la musique.
Cette fois, il est impossible de ne pas entendre la différence : écho énorme, son étouffé, volume qui pulse.
Si vous avez ce résultat, tout est parfait.
On peut passer aux choses intéressantes.
11. Fabriquer notre son vinyle
Pour évoquer un disque, nous allons mélanger plusieurs petites imperfections plutôt que d’appliquer un énorme filtre caricatural.
Le signal musical va recevoir :
coloration
+
saturation douce
+
wow lent
+
flutter rapide
+
souffle
+
craquements aléatoires
Le wow est particulièrement intéressant : le pitch du morceau oscille très légèrement et lentement, comme avec une rotation imparfaite du disque.
Le flutter ajoute une fluctuation plus rapide et beaucoup plus petite.
Le souffle est généré directement par FFmpeg.
Les craquements sont eux aussi générés dynamiquement : ce n’est pas un fichier sonore qui tourne en boucle.
Résultat : ils n’apparaissent jamais exactement au même endroit.
12. Créer plusieurs presets
Créons d’abord le fichier qui mémorisera le preset choisi :
sudo mkdir -p /etc/airvinyl
Puis :
echo 'PRESET=vinyl' | sudo tee /etc/airvinyl/preset.conf
Nous allons proposer quatre modes :
bypass → aucun effet
hifi → vinyle très propre
vinyl → notre effet principal
worn → disque nettement plus usé
Créez :
sudo nano /usr/local/bin/airvinyl-dsp
Et collez :
#!/bin/bash
set -euo pipefail
INPUT="/srv/airvinyl/input.pcm"
OUTPUT="/srv/airvinyl/library/AirVinyl"
PRESET="${PRESET:-vinyl}"
ensure_fifo() {
if [[ ! -p "$1" ]]; then
rm -f "$1"
mkfifo "$1"
chmod 666 "$1"
fi
}
ensure_fifo "$INPUT"
ensure_fifo "$OUTPUT"
echo "AirVinyl DSP - preset: $PRESET"
case "$PRESET" in
bypass)
exec ffmpeg -y \
-hide_banner \
-loglevel warning \
-f s16le \
-ar 44100 \
-ac 2 \
-i "$INPUT" \
-af "anull" \
-f s16le \
-ar 44100 \
-ac 2 \
"$OUTPUT"
;;
hifi)
exec ffmpeg -y \
-hide_banner \
-loglevel warning \
-f s16le \
-ar 44100 \
-ac 2 \
-i "$INPUT" \
-af "highpass=f=25,lowpass=f=16000,equalizer=f=120:t=q:w=0.8:g=1.0,asoftclip=type=tanh:threshold=0.90:output=0.98:oversample=4,vibrato=f=0.33:d=0.004,vibrato=f=5.8:d=0.001" \
-f s16le \
-ar 44100 \
-ac 2 \
"$OUTPUT"
;;
vinyl)
exec ffmpeg -y \
-hide_banner \
-loglevel warning \
-f s16le \
-ar 44100 \
-ac 2 \
-i "$INPUT" \
-f lavfi \
-i "anoisesrc=r=44100:a=0.0025:c=pink" \
-f lavfi \
-i "aevalsrc=exprs='if(lt(random(0)\,0.00004)\,(random(1)*2-1)*0.25\,0)+if(lt(random(2)\,0.000003)\,(random(3)*2-1)*0.70\,0)':s=44100" \
-filter_complex \
"[0:a]highpass=f=28,lowpass=f=14000,equalizer=f=130:t=q:w=0.8:g=1.5,equalizer=f=4500:t=q:w=1.0:g=-1.2,asoftclip=type=tanh:threshold=0.82:output=0.95:oversample=4,vibrato=f=0.38:d=0.016,vibrato=f=6.1:d=0.003[music]; \
[1:a]highpass=f=150,lowpass=f=9000,pan=stereo|c0=c0|c1=c0[noise]; \
[2:a]highpass=f=700,lowpass=f=12000,pan=stereo|c0=c0|c1=c0[crackle]; \
[music][noise][crackle]amix=inputs=3:duration=first:normalize=0,alimiter=limit=0.97[out]" \
-map "[out]" \
-f s16le \
-ar 44100 \
-ac 2 \
"$OUTPUT"
;;
worn)
exec ffmpeg -y \
-hide_banner \
-loglevel warning \
-f s16le \
-ar 44100 \
-ac 2 \
-i "$INPUT" \
-f lavfi \
-i "anoisesrc=r=44100:a=0.006:c=pink" \
-f lavfi \
-i "aevalsrc=exprs='if(lt(random(0)\,0.00010)\,(random(1)*2-1)*0.35\,0)+if(lt(random(2)\,0.000008)\,(random(3)*2-1)*0.85\,0)':s=44100" \
-filter_complex \
"[0:a]highpass=f=40,lowpass=f=10500,equalizer=f=150:t=q:w=0.8:g=2.5,equalizer=f=4000:t=q:w=1.0:g=-2.0,asoftclip=type=tanh:threshold=0.72:output=0.92:oversample=4,vibrato=f=0.42:d=0.030,vibrato=f=6.5:d=0.006[music]; \
[1:a]highpass=f=120,lowpass=f=8500,pan=stereo|c0=c0|c1=c0[noise]; \
[2:a]highpass=f=600,lowpass=f=12000,pan=stereo|c0=c0|c1=c0[crackle]; \
[music][noise][crackle]amix=inputs=3:duration=first:normalize=0,alimiter=limit=0.97[out]" \
-map "[out]" \
-f s16le \
-ar 44100 \
-ac 2 \
"$OUTPUT"
;;
*)
echo "Preset AirVinyl inconnu: $PRESET" >&2
exit 1
;;
esac
Rendez le script exécutable :
sudo chmod +x /usr/local/bin/airvinyl-dsp
13. Faire fonctionner AirVinyl automatiquement
Nous voulons maintenant arriver au meilleur moment du projet :
allumer le Raspberry Pi et ne plus jamais avoir besoin de lancer FFmpeg manuellement.
Créons un service systemd :
sudo nano /etc/systemd/system/airvinyl-dsp.service
Contenu :
[Unit]
Description=AirVinyl DSP Processor
After=network-online.target owntone.service
Wants=network-online.target owntone.service
Before=shairport-sync.service
[Service]
Type=simple
EnvironmentFile=/etc/airvinyl/preset.conf
ExecStart=/usr/local/bin/airvinyl-dsp
Restart=always
RestartSec=1
[Install]
WantedBy=multi-user.target
Puis :
sudo systemctl daemon-reload
sudo systemctl enable airvinyl-dsp.service
Il faut maintenant indiquer à Shairport qu’il doit démarrer après notre moteur DSP :
sudo systemctl edit shairport-sync
Ajoutez :
[Unit]
Wants=airvinyl-dsp.service
After=airvinyl-dsp.service
Puis :
sudo systemctl daemon-reload
14. Ajouter une commande simple pour changer de preset
Créons :
sudo nano /usr/local/sbin/airvinyl-preset
Avec :
#!/bin/bash
set -euo pipefail
PRESET="${1:-}"
case "$PRESET" in
bypass|hifi|vinyl|worn)
;;
*)
echo "Usage: sudo airvinyl-preset {bypass|hifi|vinyl|worn}"
exit 1
;;
esac
echo "PRESET=$PRESET" > /etc/airvinyl/preset.conf
systemctl stop shairport-sync
systemctl restart airvinyl-dsp
systemctl start shairport-sync
echo "AirVinyl utilise maintenant le preset: $PRESET"
Puis :
sudo chmod +x /usr/local/sbin/airvinyl-preset
À partir de maintenant :
sudo airvinyl-preset vinyl
active le preset principal.
sudo airvinyl-preset hifi
donne une coloration beaucoup plus discrète.
sudo airvinyl-preset worn
sort le vieux disque qui a beaucoup vécu.
Et :
sudo airvinyl-preset bypass
désactive tous les effets.
15. Vérification finale : le test du reboot
Choisissez par exemple :
sudo airvinyl-preset vinyl
Puis redémarrez :
sudo reboot
Une fois le Pi revenu :
systemctl is-active owntone
systemctl is-active airvinyl-dsp
systemctl is-active shairport-sync
Les trois doivent répondre :
active
Et maintenant, plus aucune commande à saisir.
Prenez simplement votre iPhone, choisissez :
AirVinyl
et lancez votre morceau.
Le Raspberry Pi fait tout le reste.
Et le résultat ?
C’est probablement ma partie préférée du projet : l’effet fonctionne surtout grâce à l’accumulation de petites imperfections.
Avec le preset vinyl, on perçoit le souffle, les petits craquements se promènent dans l’espace stéréo, le pitch n’est plus tout à fait aussi mathématiquement stable et le signal est légèrement adouci.
Ce n’est pas un filtre « vieille radio ». La musique reste parfaitement écoutable.
Mais elle cesse d’être complètement parfaite.
Et c’est précisément là que le cerveau commence à entendre… un disque.
Le plus amusant reste que la source peut être absolument n’importe quoi : un serveur musical personnel, une application de streaming, un podcast ou un morceau récent.
Pour l’iPhone, AirVinyl n’est qu’une enceinte AirPlay supplémentaire.
Pour le Raspberry Pi, c’est un flux PCM sur lequel nous pouvons faire à peu près tout ce que FFmpeg permet.
Et pour les HomePod…
c’est comme si quelqu’un avait glissé une platine vinyle invisible au milieu du réseau.
La prochaine évolution naturelle serait d’ajouter une petite interface Web avec quatre gros boutons Bypass / Hi-Fi / Vinyl / Worn, puis quelques curseurs pour régler le souffle, les craquements, le wow et le flutter sans même ouvrir SSH.

Laisser un commentaire