First off, I want to say a big thank you to bastibl & argilo who are currently maintaining gr-rds and helped me a lot to change the code so that their application works flawlessly on an Orange Pi Zero 3. Also a big shoutout to all former devs of gr-rds who layed the base!
There are three apps for FM-MPX on Linux:
StereoTool -> Takes up quite some resources, no CLI
JMPX -> no CLI, no dynamic RDS
mpxgen -> doesn't work
Nonetheless, I was determined to bring this application onto my Orange Pi. A CLI was important to me, because it allows the user to remote-control it using SSH.
So, this is probably the cheapest & smallest link receiver & MPX generator you can imagine (except for an old mini PC that you still have laying around maybe, will work with that too of course). It uses GnuRadio, gr-rds and a Python-script to generate the whole MPX. It costs about 30-35€ for the OPi Zero 3 (Allwinner H618 Quad-Core Cortex-A53, 2GB RAM), the heatsink & the extension board with the audio jack. If you take the 1GB version, which should suffice in theory, it's only 25-30€ in sale. The extension board isn't necessary as the OPi can output analogue audio via it's GPIO pins - you could easily connect it to a RCA or BNC socket depending on what you need for your tx. The whole system can be remote controlled via SSH. By adding a cheap, 8€ 4g dongle from Aliexpress, you can access it from anywhere using a DynDNS service.
A RPi Zero 2W might work as well, I still have one laying around, I might try it. RAM usage isn't really an issue here - less than 100mb for both gr-rds & FFMPEG. CPU load on the OPi is at about 5-8% when both FFMPEG & the gr-rds-script are running.
The original code from basti & argilo needed some change to work as a standalone MPX encoder. With their help, I removed the rf section in the end and changed the code's sample rate & buffer size to optimize it and save CPU power.
I installed Debian Bookworm server 1.0.4, 6.1 kernel, from the official Orange Pi site. I then changed the deps to the official debian ones, installed FFMPEG, GnuRadio & deps, gr-rds and launched it.
Steps & commands:
Code: Select all
Install debian server on the OPi's micro-SD card.
https://drive.google.com/drive/folders/10zlO-0mMz-fqRQOKAOWX-mQA_UbN_C1n
Here are the other distros for the OPi: http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-Zero-3.html
Connect to screen with HDMI to micro-HDMI cable (with an adapter you'll not be able to use the USB-C port) and connect keyboard. Put in the micro-SD card. Connect USB-C power.
Connect to wifi:
nmcli dev wifi
sudo nmcli dev wifi connect your_wifi_name password your_wifi_passwd
Show the OPi's local IP address:
ip addr show wlan0
Log in onto the OPi using Putty & Filezilla (to copy files onto it):
Host name (or IP address): OPi's local ip that we just found out
Port: 22
Connection type: SSH
User: orangepi
Password: orangepi
===> For gods sake change those after logging in the first time!
In Putty, under 'Connections > SSH' tick 'Share connections if possible'.
Change repos to official debian ones:
sudo tee /etc/apt/sources.list > /dev/null <<EOF
deb http://deb.debian.org/debian/ bookworm main contrib non-free non-free-firmware
deb-src http://deb.debian.org/debian/ bookworm main contrib non-free non-free-firmware
deb http://deb.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware
deb-src http://deb.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware
deb http://deb.debian.org/debian/ bookworm-updates main contrib non-free non-free-firmware
deb-src http://deb.debian.org/debian/ bookworm-updates main contrib non-free non-free-firmware
EOF
Create persistent loopback device with fixed card number (virtual sound card):
echo "snd-aloop" | sudo tee -a /etc/modules
Set fixed names for the loopback-device:
sudo cat <<EOT >> /etc/asound.conf
pcm.loopback_playback {
type hw
card "Loopback"
device 0
subdevice 0
}
pcm.loopback_capture {
type hw
card "Loopback"
device 1
subdevice 0
}
EOT
Install FFMPEG:
sudo apt update
sudo apt install ffmpeg
Install GnuRadio & dependencies:
sudo apt update
sudo apt install libvolk2-dev libboost-locale-dev xvfb gnuradio gnuradio-dev cmake git doxygen
Clone gr-rds Github repository:
git clone https://github.com/bastibl/gr-rds.git
cd gr-rds
Compile & install gr-rds:
mkdir build
cd build
cmake ..
make
sudo make install
sudo ldconfig
On another PC, open GnuRadio's GUI and edit the "rds_tx_for_opi_1.0.grc" to your liking - it's easier this way. Set the correct input and output sound cards, RDS settings, pilot & subcarrier level. Export it as a python script by clicking on "Generate the flow graph" next to the play button. Copy the .py-file to the Orange Pi Zero 3 using for example FileZilla.
Start audio stream to loopback device:
ffmpeg -re -i "Alex Metric - The Q.mp3" -ar 48000 -f alsa "hw:3,0"
=> You can change the input to your liking. It is possible to input a webstream, e.g. http://198.245.62.81:8008 [ffmpeg -re -i "http://198.245.62.81:8008" -ar 48000 -f alsa "hw:0,0"].
You can even set a playlist.txt file with a pre-produced programme to be played.
This would look like this:
ffmpeg -f concat -safe 0 -i "playlist.txt" -ar 48000 -f alsa "hw:0,0"
The playlist file should be in the same folder like the files and you should cd the working directory to that folder. The playlist file should look like this:
file 'file1.wav'
file 'file2.wav'
file 'file3.wav'
====> IMPORTANT: Before you do so, you need to make sure to find out, which card number (e.g. 0, 1, 2) represents the loopback card. This isn't persistent and might change after reboots. Otherwise follow my instruction and set a fixed name for the loopback devices, e.g. "loopback_playback". Usually, hw:x,1 is the playback device and hw:x,0 the record device.
Start the MPX-generator-script from the command line - you need to cd to the folder to which you copied the script earlier of course. Otherwise you can add the whole path, e.g. /home/user/xxx, in front of the filename:
python3 rds_tx_for_opi_1_0.py
PROFIT!
To do's:
- Test for stability & audio quality
- Add dynamic PS (working on it)
- Maybe write a script that does all the steps I listed to further simplify the process
Thanks for reading & please correct me, if I made some mistakes