ALSA LADSPA Plugin Chain For FM Transmission
I found a great tool for enhancing audio for FM transmission and adding RDS text to the signal, Stereo Tool. It's free to use the basic features but it costs $600+ to unlock all of the FM-related features if you want to use them. In the free version they have a beep tone that goes off every few seconds when you are using unlicensed features.
Turns out that it is possible to do similar enhancements using the LADSPA plugins in ALSA. As an example, here's the /etc/asound.conf that I use with my radio station Linux server, a Raspberry Pi using a cheap Behringer U-Control UCA 202 digital/analog converter. (Note the use of the hw:1,0 device for output, which corresponds to the USB DAC device.)
With this config you would direct output to the "radio" device to use the LAPDSPA plugin chain, .i.e., "aplay -D radio some.wav"
# Make USB DAC the default device pcm.!default { type hw card 1 } ctl.!default { type hw card 1 } # LADSPA plugin chain for radio station processing pcm.radio { type plug slave.pcm "ladspa" hint { show on description "in -> equal -> declip -> compressor -> limiter -> dmix -> out" } } # LADSPA plugins: # "listplugins" to see the list of installed plugins # "analyseplugin <filename>" to see plugin controls # Use "ardour2" to experiment with plugin settings pcm.ladspa { type ladspa slave.pcm dmixplug path "/usr/lib/ladspa" plugins { 0 { # Equalizer - FM curve (approx, should cut at 19kHz, not 16) label Eq input { # 31 Hz, -48 to 24, default -30 # 63 Hz, -48 to 24, default 0 # 125 Hz, -48 to 24, default 0 # 250 Hz, -48 to 24, default 0 # 500 Hz, -48 to 24, default 0 # 1 kHz, -48 to 24, default 0 # 2 kHz, -48 to 24, default 0 # 4 kHz, -48 to 24, default 0 # 8 kHz, -48 to 24, default 0 # 16 kHz, -48 to 24, default 0 controls [ -30 0 0 0 0 0 0 0 0 -30 ] } } 1 { # Expander - remove low-level noise/hiss label se4 input { # RMS/peak, 0 to 1, default 0 # Attack time (ms), 1.5 to 400, default 101.125 # Release time (ms), 2 to 800, default 401 # Threshold level (dB), -30 to 0, default 0 # Ratio (1:n), 1 to 20, default 1 # Knee radius (dB), 1 to 10, default 3.25 # Attenuation (dB), -24 to 0, default 0 controls [ 1 101.125 401 -26 10 3.25 0 ] } } 2 { # Compressor label sc4 input { # RMS/peak, 0 to 1, default 0 # Attack time (ms), 1.5 to 400, default 101.125 # Release time (ms), 2 to 800, default 401 # Threshold level (dB), -30 to 0, default 0 # Ratio (1:n), 1 to 20, default 1 # Knee radius (dB), 1 to 10, default 3.25 # Makeup gain (dB), 0 to 24, default 0 controls [ 0.9 101.125 401 -10 2 3.25 0 ] } } 3 { # Limiter label fastLookaheadLimiter input { # Input gain (dB), -20 to 20, default 0 # Limit (dB), -20 to 0, default 0 # Release time (s), 0.01 to 2, default 0.5075 controls [ 10 0 0.8 ] } } } } # Rate converter set up, dmixplug acts as intermediary between LADSPA plugin # and dmix, which cannot connect directly pcm.dmixplug { type plug slave.pcm dmixer } pcm.dmixer { type asym playback.pcm { # See plugin:dmix at http://www.alsa-project.org/alsa-doc/alsa-lib/pcm_plugins.html type dmix ipc_key 5678291 ipc_key_add_uid true slave { pcm "hw:1,0" format S16_LE rate 44100 channels 2 buffer_size 5000000 } } capture.pcm { type null } }