Nothern Utah WebSDR Logo - A skep with a Yagi
Using "KA9Q-Radio"
as a multi-band front end for the PA3FWM WebSDR

What this page is about

The PA3FWM WebSDR (see the site ""
 3 ) is widely used as a multi-user interface to virtual receivers allowing hundreds of people to use the same receive hardware simultaneously.

Typically, eight separate (hardware) receivers are required to fully populate the (maximum) eight bands that this can support - but using ka9q-radio and the RX888 Mk 2 simultaneous coverage of any eight bands between 2200 meters and 10 meters can be done with a single receiver.  This page describes how that might be done.


This document represents an effort on
my part to understand the operation of "ka9q-radio" and is not intended to be authoritative.

As such, this is a work in progress and will certainly contain many "blank spots" and errors.  What it is intended to do is to help the new user along and start to get the "feel" of how the pieces go together.

Please read EVERY document in the /docs directory of the "ka9q-radio" git - and refer back when you see something you don't understand!

For more information about ka9q-radio, go here:

Using KA9Q-Radio - link

This page has much more information about the internal workings of ka9q-radio and other examples of its use.

First, what is "KA9Q-Radio" - and why is it different from other SDR programs/suites?

One of the advantages of SDRs is the capability of receiving multiple signals at the same time - but this is typically exploited only in a limited fashion.  The limit of this capability is a combination of both the bandwidth of the acquisition device (e.g. how much spectrum the device is inhaling) and also the processing capability of the host computer.  Usually it's the latter point that has limited the usefulness/capability of many wide-bandwidth SDRs:  It is typical for each "instance" of a receiver used by a user to have to process data from the high-bandwidth acquisition stream - which may be several megasamples.  Because each per-user instance requires so much processing, this can make a multi-user receiver system "un-scalable" - that is, each user requires a significant amount of CPU processing.

In 2006, an article was published  1  that described what might be considered to be a mathematical "shortcut" when it comes to processing large amounts of data.  Without going into detail, the "traditional" method for producing a single virtual receivers is to crunch the full bandwidth data to yield - at least in an amateur radio application - only a narrow bandwidth - perhaps a few kHz for an SSB or FM signal or even a few 10s of kHz for a waterfall - and if multiple receivers are required, it's necessary to "re-crunch" the large amount of raw input data for each, individual receiver even through that mathematical operation for each receiver is expensive in CPU time and nearly identical.   A far more efficient method - potentially one that is many hundreds of times more efficient, depending on how much "economy of scale" was done - would be to do the "expensive" number crunching just once and then use that already-processed data to synthesize each, individual receiver - and it is this method, generally referred to "Overlap and Save" - that is used by KA9Q-Radio.

As an example of the "former" method:  If the "csdr"  2  utility is used on, say, an RTL-SDR with 2 MHz of bandwidth, a Raspberry Pi4 is capable of only handling 4-8 simultaneous receivers before all available CPU cycles are used:  This is one of the reasons why the open-source "OpenWebRX" server isn't particularly salable to a large number (e.g. dozens) of users.  Conversely, the PA3FWM WebSDR server (which is closed source) likely (unconfirmed!) uses same the techniques as KA9Q-Radio - which are noted in Footnote #1 -to allow hundreds of users on the same hardware platform as an OpenWebRX server that may be only to handle a half-dozen or so.

Using the aforementioned "Overlap and Save" method in reference #1, a Raspberry Pi4 running ka9q-radio can simultaneously decode every FM channel in the same 2 MHz bandwidth
simultaneously with plenty of processing power to spare!

KA9Q-radio is open-source and it may be found here: - and the instructions for compiling it along with a list of dependencies may be found here:

Hardware requirements:

This article describes using the RX-888 (Mk2) SDR which can operate at a sample rate exceeding 120 MSPS, implying a serial data rate well above 3 Gbps.  What this means is that for the RX-888 a USB3 port is required with the RX-888 being connected directly to it rather than through a USB hub.  Additionally, mid-high range Intel i5, i7 processor is necessary to operate the RX-888 at or above 60 MSPS - the rate at which it can inhale the entire LF, MF and HF spectrum.

As noted elsewhere in this document, ka9q-radio will also work with other popular SDR hardware:  These other receivers typically operate at lower bandwidths and may not require a USB3 interface or as-powerful processing - but the discussion of the use of these other devices is not covered here.  (To Do:  Another document giving a brief overview using these other devices.)

Installing ka9q-radio

Information about the installation of ka9q-radio may be found on the page:  ka9q_radio_installation

Using ka9q-radio with the RX-888 Mk2

There is also a page specific to using ka9q-radio with the RX-888 Mk2 SDR found here:  Using the ka9q-radio utility with the RX-888

It is STRONGLY recommended that you review both of the above pages, get ka9q-radio and the RX-888 installed and working before proceeding.

Configuring for WebSDR use

Important note about the 768 kHz maximum bandwidth coverage - Using the ALSA versus "RTL_TCP" signal paths:

This page describes a method by which up to 768 kHzof spectrum may be covered on a single WebSDR "band".  This maximum of 768 kHz is based on the hard-coded limits within the ALSA sound system in Linux and exceeding this requires a modification of the kernel.  While the "rtl_tcp" signal path does not have a 768 kHz limit, it is only 8 bits wide which means that it is significantly limited in its capability of conveying bandwidths where there are simultaneously both very weak and very strong signals.

The ka9q-radio software uses several configuration files that must be checked/modified.

Important - be aware of the following:

The configuration files discussed may be found in /etc/radio - but you may also note that copies of these same files are in the home directory (~/ka9q-radio).  As of this writing there are a few caveats related to these files:
It is expected that these inconsistencies will be resolved in future, but for now be prepared to back-up and restore your custom configuration files and beware!

Starting "rx888d"

The "rx888d" program is that which interfaces with the RX-888 hardware, placing the raw I/Q data on the network as multicast data.  Even running at half-bandwidth (e.g. 64.8 Msps rate) the bit rate from the RX-888 on the USB interface will exceed the capabilities of a Gig-E Ethernet port so data will usually be sent via local loopback.

The invocation of rx888 is:  ./rx888d g5rv &

This specifies the use of the [g5rv] section of the "rx888d.conf" file, described below.

The rx888d.conf file

The first of these is /etc/radio/rx888d.conf.  The contents of this file - and the other configuration files - are discussed on the page "Configuration files in KA9Q-Radio" (It is recommended that you read this file, too!) in detail so we'll go over only basics here.

If you look in the "default" version of this file you will see:

# ka9q customized
description = "G5RV RX888"
firmware = SDDC_FX3.img
samprate = 64800000    ;  2^8 * 3^4 * 5^5
# needs fftw3 wisdom and/or fft-threads >= 4 and some buffer tuning
# seems to lose data in the network path
# forward FFT for 129,600,000 Hz, 20ms and overlap = 5 is 3240000
#samprate = 129600000    ;  2^9 * 3^4 * 5^5
iface = eth0               ; force primary interface, avoid wifi
status = rx888-status.local
data = rx888-pcm.local
ssrc = 10
;gain = 1.5 ; dB
gain = 10 ;dB - near floor of NF curve, still not too high for my G5RV
gainmode = high ; higher gain range

Again, refer to "Configuration files in KA9Q-Radio" for details, but the above file need not be changed for reception from 0-30 MHz as the sample rate (64.8 Msps) is adequate for our needs.


Invoking "radiod" and using the "radiod@websdr.conf" file

The "radiod" program is that which pulls the individual receivers' spectral from the mass of raw receive data from the "rx888d".  For this we have a configuration file called "radiod@websdr.conf".

Here, we start "radiod" using the configuration file "radiod@websdr.conf":

./radiod radiod@websdr.conf &

The "radio@websdr.conf" file defines the "virtual" receivers that we need.  Here, we not only define the center frequency of each receiver, but also the "mode" on which the receiver operates and the sample rate at which this receiver operates.  As we'll see, we can define our own "modes" and bandwidths as our needs require.  For example, for some bands we'll need more bandwidth than others - 80 and 15 meters are significantly larger than 30, 17 and 12 meters, for example - and we can define these virtual receivers accordingly to provide reasonable bandwidth to cover them.

Important note:  Via the 16 bit ALSA interface the PA3FWM WebSDR is known to work properly ONLY at the following sample rates:  24, 48, 96, 192, 384 and 768 kHz.  It may work at 1536 and higher, but the ALSA kernel would need to be modified to allow it.

Let us consider an example of a configuration file that may be used to cover every amateur band from 0 to 30 MHz:

# allowable Opus block times: 2.5, 5, 10, 20, 40, 60, 80, 100, 120
overlap = 5
blocktime = 50
input = rx888-status.local
samprate = 768000
mode = websdr768
status = hf.local
fft-threads = 4

# Use 768 kHz BW to cover larger amateur bands
data = websdr768-pcm.local
mode = websdr768
freq = "3700k 5300k 7125k 14150k 21200k 28350k 28850k 29350k"
samprate = 768000
low = -383000
high = 383000
agc = 0
gain = 0

# 384 kHz to cover medium-sized amateur bands
data = websdr384-pcm.local
mode = websdr384
freq = "307k 1900k"
samprate = 384000
low = -191500
high = 191500
agc = 0
gain = 0

#192 kHz to cover the smaller amateur bands
data = websdr192-pcm.local
mode = websdr192
freq = "10090k 18118k 24940k"
samprate = 192000
low = -95750
high = 95750
agc = 0
gain = 0


For more information about the configuration files, see
"Configuration files in KA9Q-Radio".

In the [global] section of the file we see more or less what was copied from "radiod@hf.conf" - our template - with a few differences:

In the sections that follow we define virtual receivers with various bandwidth commensurate to the amateur bands that they cover.  Because we can arbitrarily define receivers and their bandwidths, we can select the sample rate of the virtual receiver to better-suit the band being covered.  For example, using 192 kHz for 30 meters makes sense as it is only 50 kHz wide, anyway - and running some bands at lower sample rates can reduce CPU loading in both radiod and the WebSDR.

In all sections, we have a few important definitions:
While the bandwidth, AGC and gain are actually defined in the "modes" file (described below) but it is a good idea to explicity define them here (again) should other defaults be specified in the radiod configuration file.

In the [WEBSDR_768] section we define bands that are large enough to require such bandwidth - namely 80, 20 and 15 meters.  40 meters is included in this section as there are signals of interest adjacent to this band.

In the [WEBSDR_384] section we define bands more appropriate to 384 kHz of coverage - namely a receiver centered at 307 kHz to cover both the 2200 and 630 meter bands and the U.S. 160 meter band which is 200 kHz wide.  The parameters that are modified are:
In the [WEBSDR_192] section we define those bands for which 192 kHz coverage is appropriate - namely the 30 meter band and the 17 and 12 meter bands.  The parameters that are modified are:
As mentioned earlier, the PA3FWM can (currently) support only eight bands simultaneously, so you might think that having more than eight frequencies is superfluous - but this is not necessarily so:

Adding websdr "modes" to "modes.conf"

Referenced above is a "mode" called "websdr".  The ka9q-radio package has the ability to arbitrarily define a mode in terms of type ("linear" as in am/cw/usb, etc. and not linear as in fm), sample rate, bandwidth, and several other parameters:  This is discussed in more detail in "Configuration files in KA9Q-Radio".    (Note:  See the warning at the top of the page about .conf files being overwritten when updates occur).  

For our purposes we need to add some new "modes" for WebSDR use and this is done in the "modes.conf" file.  Specifically, we need to supply I/Q data to the WebSDR and we would like to specify both the bandwidth and sample rate.

NOTE:  While ka9q-radio previously passed the sample rate and filter parameters so that they would not need to explicitly defined in the "radiod" configuration file, this may not be the case - particularly if you have defined defaults in that file.  Be prepared to explicity specify the sample rate, high/low filter edges, agc, gain and number of channels in the "radiod" configuration file.

Somewhere in the "modes.conf" file we add the following lines to define our new modes, having previously started with the already-defined "[iq]" mode as a template:

demod = linear
samprate = 768000
low =  -383000
high = 383000
channels = 2
agc = 0
gain = 0

demod = linear
samprate = 384000
low =  -191500
high = 191500
channels = 2
agc = 0
gain = 0

demod = linear
samprate = 192000
low =  -95750
high = 95750
channels = 2
agc = 0
gain = 0

These three sections define the sample rates that we need (768, 384 and 192 kHz) and their filtered bandwidths:


Above we see our three websdr "modes" - which differ only by the sample rate and the covered bandwidth.  It's worth noting that we can define arbitrary receiver bandwidths if we like using the "low" and "high" parameters to set the low and high edge with respect to the center frequency of our receiver.  In the case of the [websdr384] mode could theoretically define our edges as being -192000 and 192000 meaning that we have a total of 384 kHz - which is exactly as much as will fit within our 384 kHz sample rate using I/Q data.   In practice, we wouldn't want to do this.  As it happens, placing a signal exactly at the edge of either the upper or lower limit of the filter (e.g. right at + or - 192 kHz in this case) causes a odd noise effects that can cause significant disruption within several percent of passband but if we narrow the filter very slightly - say to +/- 190 kHz - this effect is very significantly reduced.

It might raise eyebrows that our defined filter bandwidth (+/- 192 kHz) is so close to that permitted by the sample rate in for the reasons that that no filter is perfect in that it might be able to cut off signals beyond this adequately and aliases in the form of signals just beyond the edge of the filter will appear just inside the other end of the spectrum.  
For those who have used sound card based receivers this may be a familiar problem:  A signal that is just above the upper end of the receiver will actually appear in weaker form at the bottom as an aliased response - the amount of diminution being related to how well the sound card's hardware filtering actually works.

In the case of ka9q-radio since we are synthesizing our virtual receiver bandwidths from a much larger pool of FFT data we have the advantage of more-easily being able to define our bandwidth in discrete segments of bandwidth within the FFT (called "bins") and when we need a given bandwidth we can, by knowing which bins contain the portion of spectrum that we need, select only those bins.  What this means is that we have a very close to a "brick wall" type of response and that we can, indeed, specify our receiver as being just 380 kHz wide at a 384 kHz sample rate!  In reality there is a tiny bit of aliasing at the edges owing to the fact that a signal in one of the FFT bins bleed slightly into their neighbors, but this effect is very minor and since the edge of a filter is typically placed outside an amateur band, it is unlikely to ever be noticed.

Get it up and running

At this point the reader should take a look at the following pages:
These pages describe the specific software configurations (and utilities) required for our task and from here on, it is presumed that these have been done and that they are working.

The "" file:

An additional script is required to get data from ka9q-radio to the WebSDR, via the loopback mechanism described above.  For this task we are going to use pcmcat - one of the programs that comes with ka9q-radio - to take the multicast stream from a virtual receiver and pass it into the ALSA system where it can be used by the WebSDR.

The contents of a sample "" file are as follows:

#! /bin/bash

# NOTICE:  Be sure that the ssrc values in this file MATCH the frequencies specified in your "radiod" configuration file!
# If the do NOT match, you will get no signals the bands where the ssrc and frequency do not match.

#kill any already-running instances
killall pcmcat

killall fplay
sleep 1

# A receiver's log file is called "logrx#" where "#" is the loopback channel # (e.g. "logrx0", "logrx1", etc.)

pcmcat $pcmdata -2 -s $ssrc | ./fplay -D plug:rx_ch$loopch -r $sr -c 2 -f s16_le --disable-softvol -B $buffer & # < /dev/null 2>> $logfile\rx$loopch &

pcmcat $pcmdata -2 -s $ssrc | ./fplay -D plug:rx_ch$loopch -r $sr -c 2 -f s16_le --disable-softvol -B $buffer & #  < /dev/null 2>> $logfile\rx$loopch &

pcmcat $pcmdata -2 -s $ssrc | ./fplay -D plug:rx_ch$loopch -r $sr -c 2 -f s16_le --disable-softvol -B $buffer & # < /dev/null 2>> $logfile\rx$loopch &

pcmcat $pcmdata -2 -s $ssrc | ./fplay -D plug:rx_ch$loopch -r $sr -c 2 -f s16_le --disable-softvol -B $buffer & # < /dev/null 2>> $logfile\rx$loopch &

pcmcat $pcmdata -2 -s $ssrc | ./fplay -D plug:rx_ch$loopch -r $sr -c 2 -f s16_le --disable-softvol -B $buffer & # < /dev/null 2>> $logfile\rx$loopch &

pcmcat $pcmdata -2 -s $ssrc | ./fplay -D plug:rx_ch$loopch -r $sr -c 2 -f s16_le --disable-softvol -B $buffer & # < /dev/null 2>> $logfile\rx$loopch &

pcmcat $pcmdata -2 -s $ssrc | ./fplay -D plug:rx_ch$loopch -r $sr -c 2 -f s16_le --disable-softvol -B $buffer & # < /dev/null 2>> $logfile\rx$loopch &

pcmcat $pcmdata -2 -s $ssrc | ./fplay -D plug:rx_ch$loopch -r $sr -c 2 -f s16_le --disable-softvol -B $buffer & # < /dev/null 2>> $logfile\rx$loopch &

Important:  This script should be executed before starting the WebSDR server, but after ka9q-radio is running.

The configurations in detail:
How this script works:

Included with ka9q-radio is a program called "pcmcat" - the name being related to the "cat" utility in Linux - that will spit out the data on the specified stream to STDOUT.  In the cases above, we are using data from the streams defined in "radiod@websdr.conf" namely "websdr768-pcm.local", "websdr384-pcm.local" and "websdr192-pcm.local" and we are further specifying the sub streams using the "ssrc" which happen to be designated by the tuned frequency.  Using the Linux "pipe" (the "|" character) we are feeding the data from pcmcat into the "fplay" utility (a version of "aplay" modified to be able to operate at higher than 192 kHz) to put this data into an ALSA loopback device (e.g. a "virtual" sound card) defined in the "asoundrc" file.

With the I/Q data now in a virtual ALSA device, it is available to the WebSDR as just another sound device (e.g. of type "plug") as described below.

Using the loopback in the "websdr.cfg" file

The PA3FWM WebSDR uses a file called "websdr.cfg" (typically located in ~/cfg) for its band/frequency configurations.  Based on our configuration, above, let's discuss some examples of the portion of that file that configures the bands.

Here is a definition for 80 meters based on what we have already described:

band 80
# loopbacks are used with "f_loopX_out" where "X" is the #band number, 0-7
device $plug:f_loop1_out0
centerfreq 3700
gain -20
samplerate 768000
# We get "swapped" I/Q data from ka9q-radio
# set "hpf" to zero to prevent "zero-Hz hole" in the middle of the receiver
hpf 0
noiseblanker 30
antenna wet noodle
extrazoom 1

In detail:

Antenna/signal level considerations

The use of individual receivers affords the installation of band-specific filters to prevent very strong out-of-band energy (e.g. SWBC -strong shortwave broadcast stations, local mediumwave/AM stations) from overloading the receiver.  With a receiver like the RX-888, this situation is more complicated:  Even with 16 bits, this is not enough bit depth/dynamic range to handle the entire range of expected signals under a wide variety of HF propagation conditions.

As-is, the gain of the RX-888 Mk2 is slightly too low to receive the 10 meter noise floor on a theoretical "flat" antenna system in a very quiet, rural area and it needs a bit of amplification.  If you do that, however, you will risk overload from strong SWBC signals and - particularly in the summer - the very high static levels present on the lower bands (160-40 meters).  If you are using the RX-888 for receiving all HF bands, you ARE risking overload at times, but there are ways to mitigate this:

Defining the "gain" setting in the "modes.conf" and in the "radiod" configuration files

Previously we defined the "AGC" as being off (a value of zero) and a gain value of zero.  For the WebSDR we would prefer that the AGC be turned off as this would defeat the utility of the "S" meter:  If the gain of the signal path varied due to AGC action, it would not be possible to properly calibrate the S meter - at least not without the WebSDR "knowing" the current gain setting.  (Comment:  This is possible to do, but currently not implemented.)

As for the "gain" value, a gain setting of zero means that the signal level being output by ka9q-radio is the same, in amplitude (represented by a 16 bit signed number) as the signal at that frequency being applied to the antenna port.  When connected to an antenna, however, there will surely be many other signals, meaning that it is unlikely that the 16 bit numerical value seen on the WebSDR's signal path for that band will have any relationship at all the raw 16 bit A/D converter value - and (almost) no matter what, that latter value will always be lower - probably MUCH lower!

This property arises when you consider that since the signal path feeding the WebSDR will have a narrow bandwidth compared to the acquisition bandwidth of the RX-888 (e.g. at best we will see 768 kHz of the 64.8 MHz sample rate) this means that the signal output from the virtual receivers can be extremely low - particularly on a band that is very quiet, or even "closed".  What this may mean is that on a higher band - say 12 or 10 meters - when it is closed and there are no local signals, you may get 16 bit values feeding the WebSDR's signal input for that band being represened by very few bits.

Fortunately, the PA3FWM WebSDR code has some diagnostic tools for this - specifically the "~~status" web page (this is detailed in the documentation supplied with the WebSDR code).  Take this example:

name     overruns readb.  blocks          timestamp  users 10sec_ADmin/max  ever_ADmin/max    source
80              1   8     119949  1698981790.889891  0        -378 369     -1441 1440    0,$plug:f_loop0_out0
60 1 8 55707 1698975063.039457 0 -233 213 -921 936 0,$plug:f_loop1_out0
40M 1 8 11405 1698973169.597555 0 -236 210 -1080 1050 0,$plug:f_loop2_out0
20M 1 8 213185 1698977049.885691 0 -100 109 -322 318 0,$plug:f_loop3_out0
17M 0 2 2450 1698972784.537468 0 -47 44 -220 231 0,$plug:f_loop4_out0
15M 1 8 3904 1698973131.501877 0 -36 35 -141 153 0,$plug:f_loop5_out0
12M 0 2 2342 1698973129.014715 0 -13 15 -80 76 0,$plug:f_loop6_out0
10M 1 8 1741 1698973140.366123 0 -13 14 -82 82 0,$plug:f_loop7_out0
In looking at the above values, we see something that is potentially alarming:  Knowing that these signals are on a 16 bit signal path, we can see that the 12 and 10 meter signals are generally representable by just 4 bits meaning that it is likely that quantization artifacts (intermodulation products, noise, etc.) will likely be present.  As a starting point, the signal level should be in the 100-300 range with no signals present (on a "dead" band) due to noise.  What this means is that one will likely need to tweak the gain settings over time to accommodate the signal levels ranging from strong summer static on the low bands to very low winter noise across all bands when they are "closed."

Prudent application of the "gain" setting in the configuration can help remedy this situation.  This value will scale the signals, in dB, by the value specified and effectively "amplifying" the result:  As the internal signal processing within ka9q-radio is done with greater precision than 16 bit signed arithmetic, this amplification will yield better fidelity of the outputted signal to the WebSDR (which is limited to 16 bit signed data) by multiplying it before it is converted to an integer value.

Setting the gain of the RX-888 front end and the signal path

The importance of proper gain and signal levels feeding the RX-888 cannot be over-emphasized if good performance is to be obtained.  Consider the following two statements:
The RX-888 - like ALL other software-defined radios - use an analog-to-digital converter to acquire the raw signal data into the digital realm.  ALL analog-to-digital converters have a very defined limit of how much TOTAL signal power can be applied before it overloads, regardless of frequency.  In other words, you MUST keep this total signal power safely below the overload limit (e.g. "clipping" threshold) or else signals all across the spectrum will be disrupted.  It is imperative that one does their best to properly set the input signal level to achieve what are two conflicting requirements:
In other words, we have a problem:  Too little gain, our receiver is deaf - particularly on the high bands and too much gain, it overloads and everything is disrupted.By itself, the absolute sensitivity of the RX-888 (Mk2) is on the order of -152dBm/Hz.  For an urban installation where the noise level is fairly high, this may be adequate, but if you are lucky enough to have a very quiet RF environment - one that is near the ITU noise floor - you will find that the RX-888 (Mk2)'s sensitivity is about 15 dB lower than necessary to be able to hear weak signals on a quiet 10 meter band - and the situation.  What this means is that if you are planning to use the RX-888 (Mk2) in a very quiet RF environment, you will need 15-20 dB of amplification - and this must take into account losses of filters, splitters and feedline.

This issue was discussed in the following blog entry:  Measuring the signal dynamics of the RX-888 (Mk2) - link.

There is another problem that arises:  The noise floor of the HF spectrum is NOT flat:  Noise at 80 meters is on the order of 20dB higher than that at 10 meters which means that if you do add amplification, the RX-888 (Mk2) will very likely overload on signals in the low HF spectrum (1-10 MHz) alone:  This fact is true for ANY direct-sampling HF receiver that is intended to simultaneously receive everything up to 30 MHz - including the RX-888, KiwiSDR, Red Pitaya, and any other!

This issue was discussed in the following blog entry:  Revisiting the "Limited Attenuation High Pass" filter - again - link.  This article describes a sort of pre-emphasis (or "shelving") filter that significantly attenuates lower-frequency signals (<10 MHz) but progressively offers less attenuation by the time one gets to 30 MHz.  As the signal and noise levels at the lower end of HF are so high, the effect is not to remove low frequency signals, but to generally "equalize" signals across the HF spectrum so that low frequency and high frequency signals - and the corresponding noise floor - is more level across the frequency range.  In other words:  It minimizes the wasting of valuable A/D dynamic range on lower frequencies where the total noise power is very high and allows the insertion of the amplification that is needed to allow reception near 30 MHz while reducing the probability of overload.

In short:  To get decent performance from a full-bandwidth, you should:
Tools to do this:


As described above, it is certainly practical to use a single piece of receive hardware - the RX-888 Mk 2 - as the sole receiver for a PA3FWM receiver system.  The above configurations have actually been tested on the workbench and found to perform as expected.

(And no, it's not lost on my the irony that the techniques used by ka9q-radio are probably the same used by the PA3FWM software to efficiently provide the large number of individual virtual receivers that it does!)

For more information about ka9q-radio, go here:

Using KA9Q-Radio - link

This page has much more information about the internal workings of ka9q-radio and other examples of its use.


1 - Mark Borgerding, “Turning Overlap-Save into a Multiband Mixing, Downsampling Filter Bank”, IEEE Signal Processing Magazine, March 2006.

2 - The csdr tools by HA7ILM may be found here:  This represents a "toolbox" of signal processing engines that can do things like filter, decimate, shift, demodulate, convert formats, provide AGC and more.  These tools may be useful for additional filtering of signals.

3 - The PA3FWM at the University of Twente in the Netherlands uses an A/D converter that streams raw data via an Ethernet interface to a computer that uses graphics-card processors to do the heavy-lifting.  See these pages for more information:  and  P.T. de Boer, PA3FWM, provides a version of the WebSDR software that is similar to that operating at the University of Twente, but does not utilize GPU cores and bespoke hardware and is therefore more limited in bandwidth - but it still is extremely economical with its CPU power in servicing many users - even on computers of limited processor power allowing many times the number of users compared to OpenWebRX.  While I have no direct evidence that it does, I suspect that the PA3FWM WebSDR uses the technique described in Reference #1 to allow its very efficient use of CPU power to service many users simultaneously.


Additional information:
 Back to the Northern Utah WebSDR landing page