EasyFM FPGA FM stereo modulator with RDS and live stream MP3/WAV decoder


This page describes hardware/software for stand-alone FM broadcast modulator with RDS. The hadware is based on EasyDABv2, and no any modification is needed (in case if Low-Pass filter is used in output). If You have LFCN-225+ filter, you don't need any modifications and you only need to update board's firmware to switch into FM modulator. If Your filter - is RBP-204+, then broadcasting on FM band is not possibe, filter replacement to low-pass is needed. With this board and firmware You can broadcast on 88-108 MHz band as usual FM station.






 How it works

Stations often broadcast itselves on internet by using streaming servers, like ShoutCast or IceCast2 in MP3 format. The board connects to this server, decode the stream and do FM stereo modulation digital way as well as sending RDS data with station name and artist/song (if station sending them in the stream).


 Design Flow Diagram

 EasyFM inside FPGA

Implemented blocks

Here is Intellectual Property blocks, that has been used or implemented:

  1. SPI peripheral - this hardware block used to speed-up SPI bus up to 50MHz for all devices: W5500, M25P16 and AD9957.
  2. PicoBlaze6 CPU - is main microcontroller IP-core, used as data transfers arbiter and initializer for other IC's.
  3. AXI-4 Stream peripheral - used to speed-up SPI->AXI-Stream transfers for incoming data stream.
  4. MP3 Metadata extractor - it counts positions in the datastream, where ICY song titles and station's name are presented.
  5. FIFO Logic + 128Kb SRAM - this block and IC are used together to make FIFO buffer for income stream and pre-fill it during connection initialized, so internet connection latency will not interrupt playback.
  6. FIFO buffer - used to synchronize stream for different clocks between main stream logic and MP3 player.
  7. MP3 Decoder - this block converts MP3 stream to raw PCM. This block can be switched off manually in 06.05.2016 firmware update by connecting pads on pcb.
  8. FIFO buffer - this buffer reverts back clocking to main stream.
  9. Dynamic Resampler - this block converts all input MP3 sampling rate, that can be 32KHz/44,1KHz/48KHz to fixed value of 48KHz. This depends on input MP3 stream format.
  10. Interpolation FIR filter - this block used to upconvert samplerate from 48KHz to 192KHz. Also FIR coefficients are selected in Matlab script to produce 50us FM Pre-Emphasis and reject frequencies upper 16KHz.
  11. DDS - this IP-block produces 3 synchronized frequencies: 19KHz, 38KHz and 57KHz that needed to produce stereo signal with RDS.
  12. RDS Encoder - contains 3 sub-blocks: RDS-source buffer, RDS-enforcer and interpolation FIR filter with low-pass 2KHz cutoff frequency.
  13. Stereo Encoder Multiplexor - is main module, that do math for producing complex stereo signal with RDS sub-carrier. The formula - is looks like:
    mpx = (left+right) + (left-right) * 38khz + 19khz + (rds) * 57khz
  14. Interpolation FIR filter - converts 192KHz samplerate up to 2304KHz and low-pass output signal with 60KHz cutoff frequency.
  15. Quadrature DDS - converts real samples to quadrature samples with zero-frequency as carrier.
  16. FIFO Buffer - used to synchronize 100MHz system clock and 2304KHz DAC clock.
  17. ADI interface - block, that sending quadrature samples to AD9957 QDUC. 


Schematic and PCB

Please follow EasyDABv2 page for schematics and PCB, due they are equal. The one thing that you must carry on - is the output filter must be LOW-Pass, not band-pass.

Here is photo of difference between band-pass and low-pass filters:


 The signal

 The modulated output signal will looks like this:



Note that this board does not have compressor or limiter, so sound pre-processing must be done on encoder's side. Lot of stations are streaming already pre-processed signal, so it's ready for broadcasting without changes. But otherway, you need to do it on encoder's side. Here is example of ffmpeg application, that does soft-limiter before encoding: 

ffmpeg -f mp3 -i -af "aformat=channel_layouts=stereo, extrastereo=m=1.8,compand=attacks=0:points=-80/-80|-12.4/-12.4|-6/-8|0/-6.8|20/-2.8" \
-legacy_icecast 1 -content_type audio/mpeg -ice_name " TysaFM " -f mp3 -acodec libmp3lame -ar 48000 -ac 2 "icecast://source:password@"

This variant is not very good, since mp3 encoder may not strictly follow amplitude values, so after decoding it may be different and can be higher than needed again, so signal can be overmodulated. To work-around this issue in the future, the firmware will use FLAC codec instead of MP3, but for now there is new firmware, that able to use WAV/MP3 switchhing possibility. So you can send raw signed 16 bit interleaved stereo PCM samples to the board, just like MP3 throught IceCast2 server. To prepare input stream to be like real-commercial-radio (with hearable sound even in noisy environment), the compression and limiting alogrithms have to be used. In command-line example below there is such implementation:

  1. Normalize dynamic range of the input sound.
  2. Multi-band compressing by using LADSPA plugin. There is 8 bands, that is controlled by the compressor. Crossover frequencies are: 46Hz, 180Hz, 370Hz, 1.5KHz, 2.85KHz, 6.75KHz and 12KHz.
  3. Normalize and compress dynamic range of prepared sound.

The command-line for this implementation will look like:

ffmpeg -i \
-af "dynaudnorm=m=20" \
-af "ladspa=file=mbandcomp:p=mband_comp:c=c9=46|c19=180|c29=370|c39=1|c37=1" \
-af "ladspa=file=mbandcomp:p=mband_comp:c=c7=1|c9=370|c19=1500|c29=2850|c39=1|c37=1" \
-af "ladspa=file=mbandcomp:p=mband_comp:c=c7=1|c9=2850|c19=6750|c29=12000|c39=1" \
-af "dynaudnorm=g=11:s=8:p=0.80" \
-legacy_icecast 1 -content_type audio/wave -ice_name " TysaFM " \
-f s16le -acodec pcm_s16le -ar 48000 "icecast://source:password@"

Additional multiband compression LADSPA mbandcomp plugin can be found on github page. FFmpeg can do lot of variants of companding/limiting audio. Here is more variants to use: ffmpeg.org/ffmpeg-filters.html#compand


 Switching between WAV and MP3 modes

This feature added in 06.05.2016 update. To increase quality the RAW PCM format can be used in this design, so the board have to be modified, the 2 last pads of X2 connector have to be connected, as seen on this image. After this mod, the MP3 player core will be turned off and data will be passed thru to the complex stereo signal multiplexor. Please take a note, that wav format must be 48KHz 16bit signed 2 channels interleaved. This stream must be sent to Icecast2 server just like described in previous chapter. By using this format, you have full control of preparation of your signal by using compressing/limiting plugins.






This stand-alone analogue FM broadcast modulator needs only external internet radio stream in mp3 format (from icecast or shoutcast servers). It does decoding mp3 stream from it and then do stereo fm transmission with station/stream name as RDS PS and song title as RadioText, so no need PC at all, only internet connection to source stream. The board trying to re-connect to the stream source it it's failed.

Configuring samples for shoutcast or icecast server (other HTTP mp3 streaming stream servers is also possible to use):



 Source code

The full ISE project archive with all sources: EasyFMv3_mp3_final-08.06.2016.zip

There is also source code for some High-Level design files, that been used to produce logic blocks, they don't needed for ISE design, only if you familiar with Vivado HLS you can use and modify them: EasyFMv3_mp3-hls_sources.tar.gz



 Ready-made firmware

And here is produced firmware update script, that makes EasyFM mudulator for EasyDAB board: EasyFMv3_mp3_firmware_update-06.05.2016.tar.gz

Note, that You can always switch back to EasyDAB or EasyQDUC firmware by just running similar firmware update script from that device's page.






  • New firmware that allows to switch off MP3 decoder and use RAW PCM (WAV) format.