A software-based FM stereo encoder with RDS support.

If you have a sound card that is fast enough, (192000Hz  ideally) you can encode a stereo signal to modulate a simple FM transmitter to broadcast in stereo. That's pretty much what this program I wrote does. The program runs on Windows, Linux and Mac. Figure 1 shows a screenshot of the program.

Figure 1: Screenshot program on Linux.

JMPX has proved to be a popular program being the only cross-platform open source program of its kind. This year I was commission to add RDS (Radio Data System) support to JMPX by the kind people from Radio Galileo. I would like to thank Radio Galileo (Galileo Soc. Coop.) 100.5Mhz in Terni Italy and Federico Allegretti for their funding to the development of RDS support for JMPX.

RDS is a method to transmit information such as station name, song title, alternative frequencies, etc. from the radio station to the listener. The listener receives this information and it is displayed on a screen. In Europe it seems to be widely used but here in New Zealand not so much. It's a very handy protocol and now I think all FM radio stations should use it even if it is just used to transmit station name. The figure below shows my cell phone's radio receiving a test signal.

Cell phone radio receiving RDS
Figure 2: Cell phone radio receiving RDS.

Stereo information and RDS is is transmitted by using subcarriers. These subcarriers are well above human hearing frequency range (less than say 18 kHz) so you can't hear them. However, FM receivers have no such human limitations. Stereo information is transmitted at 38 kHz while RDS is transmitted at 57 kHz. For stereo there is also a pilot at 19 kHz.

Figure 3 shows a block diagram of the software excluding the RDS part, and figure 4 a block diagram of how the FM stereo encoder part works. Listing 1 shows pseudocode of the main routine of the code that produces the stereo signal.

Figure 3: A block diagram of JMPX excluding the RDS part.

Figure 4: A block diagram of the stereo encoder.

Listing 1: Main routine of the stereo code. This must be run 192,000 times a second!!!

Producing a stereo signal is quite simple as can be seen in figure 4. The low-pass filters and the pre-emphasis require more thinking. I decided to investigate and write down how to write a pre-emphasis (preemp) filter for FM radio. It makes interesting reading, and even if you can only understand a fraction of it, then it's well worth the read. Also it's interesting to note what sort of amount of effort goes into understanding just a little of something. You can read the document here at If after reading that you want to employ me to be your DSP engineer you've got my e-mail address.

The low-pass filters (the very first items in figure 3) are implemented using fast FIR filters. While very cool I don't investigate them here. The clippers are simply a nonlinear function that prevents hard clipping.

RDS is more complicated and I'll leave explaining how that works to another day. In the meantime the "RDS - Interactive Radio System - EN 50067 (1998)" PDF is what I followed to implement RDS.

Of course, to use the JMPX program your soundcard will need to be able to, as a bare minimum do 96000Hz sample rate and still be able to select 192000Hz. With a soundcard that can do 96000Hz you will be able to produce a stereo signal but no RDS signal. With the soundcard that can do 192000Hz you will be able to produce both the stereo signal and an RDS signal. On windows XP I was unable to select 192000 Hz only 96000Hz but on Windows 7 and all versions of Linux I have tried I have had no such problem. The sound cards I have tried have been an inbuilt soundcard on a Gigabyte GA-MA785GMT-UD2H motherboard, an Onda X240 computer, and an external Xonar U7; all have worked without any problems.

Also new for 2015 is I've changed some code around such as remove the necessity for the Boost libraries and used fast FIR filtering for the low pass filters. Now the code (both the dynamically liked library and the GUI) can be built using Qt creator (or from a console typeing qmake then make). I have put the source code on GitHub at jontio/JMPX which should make maintanace eaiser and eaiser for people to add features.

The Linux version has Jack support. The handy thing about Jack with this application is the flexibility. Below is a screenshot of me using Jack to send the output of music from Audacious2 to JMPX v1 then to the FM transmitter (Just one soundcard).

Figure 5: Using JMPX, Audacious2 and Jack to transmit FM Stereo music using one soundcard.

On windows you can achieve something similar by using VB Audio Cable. In the video below I am doing this to play music from MediaMonkey through VB Audio Cable into JMPX v2 then out to the soundcard and the FM transmitter. You also see the song title change on my cell phone when MediaMonkey plays a new song.

Video 1: Using JMPX v2, MediaMonkey and VB cable to transmit FM Stereo music using one soundcard.

I supply compiled Windows binaries but for Linux or Mac you will have to compile from source yourself. If you do wish to compile JMPX yourself you should visit the GitHub Repository for JMPX, download the latest source code (I suggest via `git clone`) and follow the compiling procedure. Currently information on compiling is rather scant but this should be expanded soon; generally it is a easy procedure once you know what your doing, any problems email me. In the JMPX wiki there is currently a detailed but out of date procedure on how to compile for the Raspberry Pi, please contribute and update or add to the wiki. Currently the build procedure is `qmake && make && make install` if using the command line.

JMPX downloads and links.

Jonti Olds.


Jonti. Last modified Tue, 25 Apr 2017 22:28:08 GMT.