 |
Northern
Utah WebSDR
Using the "libmirisdr-4" utility for reception |
What's this, then?
In the page that refers to this one (link) there
are other pages discuss the use of the SDRPlay RSP1a for use with the
PA3FWM WebSDR, how to configure a Linux system to allow up to 768 kHz
of bandwidth with "aplay", a "fast" (768 kHz capable) version
of "aloop", getting I/Q data from this using the "sdrplayalsa utility"
and using the "csdr" program to convert to baseband.
The aforementioned use of the SDRPlay relies on the "Version 3" API by
SDRPlay itself which, unfortunately, is not open-sourced - and it's a
bit buggy, with no way to fix it other than hope that the SDRPlay folks get around to it.
"libmirisdr-4"
There is
an open-source driver collectively known as "libmirisdr-4" that will talk to this same hardware. This driver is much
less well-developed and has fewer features than the SDRPlay drivers - and a few drawbacks (to be discussed in the conclusion) - but I decided to taking a crack at making it work.
This page is NOT intended
to be an exhaustive guide to using libmirisdr (and "miri_sdr", the actual driver) but rather more of a
place where I have placed various notes and comments on what I have done
to make it work: If I find libmirisdr to be useful, I may add to
it - but even if not, others might find this useful.
Getting and compiling
The most current version (as of this writing) is "libmirisdr-4" found at the Git of f4exb here: https://github.com/f4exb/libmirisdr-4
To install:
git clone https://github.com/f4exb/libmirisdr-4
cd libmirisdr-4
mkdir build
cd build
cmake -Wno-dev -DCMAKE_INSTALL_PREFIX=~/libmirisdr-4 ..
make -j4 install
When successfully done you will find the binaries in
/libmirisdr-4/bin - notably "miri_sdr" and "miri_fm". Only
"miri_sdr" is discussed in detail here.
Using
To invoke, go to the directory with the binary ( /libmirisdr-4/bin" in the example above)
and type "./miri_sdr" and you'll get the list of command-line arguments
which require a bit of explanation. Since I'm not terribly
familiar with the internals, I'm sketchy on some of the details.
- -f frequency to tune [Hz]: Pretty self-explanatory as this sets the center frequency. The driver will automatically select the appropriate front-end filtering within the hardware.
- Usage: -f 5000000 - Tune to 5.000000 MHz
- -m sample format -
The options are "504" for 8 bit signed, "384" for 12 bit (plus 2 bits)
- I have no idea what that's about, "336" for 12 bit signed data and
"252" for 14 bit signed data.
- Except for "504" (the 8-bit signed format)
the data is represented as 16 bit signed (little-endian) data.
For the best performance, you will want to use "252" for the
highest-resolution data from the ADC, but there are sample rate versus
bit-depth resolution limits which are mentioned in official SDRPlay
literature, namely that one must operate at 6 MSPS and below for 14
bits, with lower bit depth limits at higher rates.
- Usage: -m 252 - Use the "14 bit" mode
- -e USB transfer
mode: 1 = Isochronous mode (default - maximum of 196.608 Mbits/sec) and
2=Bulk (333Mbits/sec, host computer dependent).
- I believe that the SDRPlay drivers uses option 1, the
default. Experience has shown that most USB ports on computers
are actually interfaced by hubs and that the root controller can
accommodate only a single RSP device: Some "fancy" USB3 devices
have individual root controllers for each port, but this is NOT the
norm. It may
be that using mode "2" (bulk) may allow more than one device to be used
on this hardware, provided that the total bit rate is within its
capability, but this is only conjecture.
- Usage: -e 1 - This is the default
- -i IF Mode.
The listed modes are "0" (Zero), "450000" (450 kHz), "1620000"
(1620 kHz) and "2048000" (2048 kHz). The default is "zero" which
means that tuned frequency set with the "-f" parameter will occur at "zero" Hz in the raw I/Q passband.
- The RSP hardware - like may similar - have a "zero Hz
hole" right at DC that is a few 10s of Hz wide with some low-level
noise extending to a few hundred Hz on either side. What this
means is that if you tune in a signal with its carrier exactly in the center you will find that the carrier is removed - particularly problematic with AM detection.
- The existence of this "zero Hz hole" is why most SDR
software avoids tuning signals right at dead center of the conversion
frequency.
- If using this for a "general coverage" fixed-tuned
receiver as in a WebSDR, the default of "zero" would be used, the tuned
frequency being chosen carefully to minimize the likelihood of it
landing on a commonly-used frequency.
- Usage: -i 0 - Zero IF, which is the default.
- I believe that the other values will offset automatically to avoid the "Zero Hz Hole" mentioned above.
- -w BW Mode.
This places a low-pass filter in the sample path, after
conversion from RF to baseband. The available values are:
- 8000000 (8 MHz - default)
- Additional information:
- 200, 300, 600 kHz and 1536 kHz bandwidths:
- It would appear that these filters are implemented in
silicon on the MSi001 tuner chip. According to the MSi001 data
sheet, the 200, 300, 600 and 1535 kHz bandwidths are taken at the
-0.5dB point.
- The specifications indicate that at 2x the bandwidth
that the attenuation is typically 39dB, 71 dB at 4x the bandwidth and
100dB at 8x bandwidth.
- 5 MHz, 6 MHz, 7 MHz and 8 MHz bandwidths:
- The data sheet further specifies 4.6, 5.6, 6.5 and 7.4
MHz bandwidths at the -0.5dB point rather than the 5, 6, 7 and 8 MHz
bandwidths (respectively) implying a passband drop-off quite a bit higher than 0.5dB at the edges.
- The specifications indicate that at 2x the bandwidth the attenuation is typically -43dB, -63dB at 3x and 100 dB at 4x.
- The "band pass" filters are likely implemented as
low-pass filters within the MSi001 and are actually
at half
the frequency stated - but since we are sampling both I and Q, we can
processes signal both above and below the "zero" frequency, hence the "doubled" bandwidth.
- It makes no sense to select a filter that is wider
than the sample rate as this will simply result in terrible image
responses unless you precede the receiver itself with strong band-pass
filtering.
- Usage: -w 600000 - Set a 600 kHz BW filter
- -s sample rate.
The default is 2048000 Hz. The lowest sample rate is not
specified, but it is believed to be 1300000 (1.3 MHz) and the highest
may be 12000000 (12 MHz) - but as noted above, there are limitations of
sample format (number of bits) when you get above 6 MHz sample rate.
- The RSP1 specifications show the following, which may or may not apply to other devices:
- 14 bits: 2 MSPS - 6.048 MSPS
- 12 bits: 6.048 MSPS - 8.084 MSPS
- 10 bits: 8.064 MSPS - 9.216 MSPS
- 8 bits: >9.2156 MSPS.
- The maximum bandwidth is not specified in the data sheet or the manual, but it's mentioned to be "10 MHz" in several places.
- Usage: -s 1536000 - Set a 1.536 MSPS rate
- -d device index.
When invoked, the program will output information on the devices
it found, enumerating them as follows in this example:
- " 0: SDRPlay, RSP1A, SN: 00000001"
- This is where we run into a major problem with using this driver.
- It does not seem to be able to resolve the serial number of the device. What this means is that if you have multiple devices on your system, you cannot differentiate them uniquely and select them.
- If all of these devices are connected to the same antenna feed via a splitter, this may not be much of a problem
- If you have, say, one device on an HF antenna and
another on a VHF antenna, you have a problem: You'll get no HF
signals on the VHF antenna and likely vice-versa!
- Possible work-arounds for this that need to be investigated:
- Use "dmesg" to determine the serial number: The
full serial number appears when the devices are enumerated at boot and it may
be possible to tie this with a specific device.
- Use the SDRPlay software to enumerate the devices: They might be in the same order as here - but that needs to be investigated.
- Both of these hinge on the idea that "libmirsdr" orders the devices in the same way that these others do, but this is not (yet?) known to be true!
- Usage: -d 1 - Select device #1
- -T Device
type: 0 = default, 1 = SDRPlay. This option needs to be
investigated, but with with an RSP1a, option 1 does NOT work.
- -g gain.
This
sets the "gain" of the receiver. For this setting, the
information given on the command line and the source code conflict.
Below is a table showing gain values and the resulting A/D signal
levels with different values on this parameter using an RSP1a at a
frequency of 7.25 MHz.
- A value of "0" is indicated as being an "automatic" (AGC) but this does not yield consistent results, nor does it seem to be "disabled" of set to a fixed value. Consider a gain value of 0 to be unusable.
Setting of "-g" |
Signal level for 12 dB SINAD |
Calculated MDS |
A/D severe clipping level (dBm) |
1 |
-55.0 (S9+18) |
-71.5 (S9+1.5) |
+33 (S9+106) |
2 |
-64.0 (S9+9) |
-80.5 (S8) |
+23 (S9+96) |
3 |
-72.0 (S9+1) |
-88.5 (S6+) |
+13 (S9+86) |
4 |
-82.0 (S7+) |
-98.5 (S5) |
+3 (S9+76) |
5 |
-92.0 (S6) |
-108.5 (S3) |
-7 (S9+66) |
6 |
-95.0 (S5+) |
-114.5 (S2+) |
-17 (S9+56) |
7 |
-95.0 (S5+) |
-111.5 (S2+) |
-27 (S9+46) |
8 |
-95.0 (S5+) |
-111.5 (S2+) |
-37 (S9+36) |
9 |
-95.0 (S5+) |
-111.5 (S2+) |
-47 (S9+26) |
10 |
-95.0 (S5+) |
-111.5 (S2+) |
-57 (S9+16) |
- Discussion:
- This information tells us several things:
- For each step of "-g" value from 1 through 10, there is an increase in apparent signal path gain by 10 dB.
- Settings of 1, 2 and 3 are, for all practical purposes, useless:
- The "Severe Clipping Level" - which is higher than
that at which distortion products start to appear on the waterfall - is
that at which the level from the A/D converter is very frequently
reaching +/- the maximum value according to the bit depth, and for 14
bits, this is approximately +/- 8192. A power input of +23 dBm (200 milliwatts) or higher would likely damage the RSP1a.
- For these settings, the MDS (minimum discernible signal of 3 dB S/N in a 500 Hz bandwidth) will be "S9" for -g = 3, and "10" and "20" over for 2 and 1, respectively.
- There is no difference in sensitivity
among settings 6-10, but the "clipping level" from the A/D converter is
affected proportionally. While one could "hear" the same signals
no matter if the setting is 6, 7, 8, 9 or 10, the lower the setting,
the fewer "bits" will be present to represent the signal which will
degrade weak-signal performance overall, particularly in the presence
of other signals.
- For a "typical" HF installation, a gain setting of 6 or 7 would be a good starting point, assuming the use of 14 bit depth. If the 8 bit depth is used, expect significant weak-signal degradation as compared to the above chart.
- It would seem that for HF, the "miri_sdr" driver sets
an internal attenuation value to be approximately equal to that
of "LNA State 3" (18 dB of LNA attenuation) that cannot be switched out. This amount of attenuation results in marginal HF performance on the higher bands (15 meters and higher) when a unity-gain antenna in a "quiet" (minimal man-made noise) is used.
- It would be preferable if the code allowed the gain and LNA configurations to be controlled separately.
- A step size of 10 dB is too large for an externally-controlled AGC (e.g. the application doing the adjustment the gain). Step sizes as small as 1 dB are known to be possible with the RSP1a hardware.
- For convenience, the above table includes the signal level in IRU "S" units - assuming a properly-calibrated S-meter. (Note that Elecraft and Flex have S-meters that are close to the IRU standards - most Japanese-made radios are not.)
- See the web page "Observations from using an SDRPlay RSP1a on the on the HF bands - link for more information about the gain and dynamics of this hardware.
- The source code suggests that different values of
gain/attenuation are automatically selected for VHF/UHF to
further-increase sensitivity: The above data would not apply if that is the case.
- -b output block size (default: 16 * 16384 = 262144) Not
sure about the impact of this other than too-small a block size may
make it more susceptible to underruns and too large may increase
latency - to be investigated.
- -S Force sync output (default async). I have yet to research this.
The last argument is either a filename, or simply a hyphen ( - ) -
the latter indicating that the output should go to STDOUT. If you
want to "record" raw I/Q data to a file, you would use the filename.
Example command line invocation:
./miri_sdr -f 2500000 -w 200000 -m 252 -s 1536000 -
Where:
- The center frequency is 2.5 Mhz
- The bandwidth is 200 kHz. For our example immediately below, the narrowest-possible hardware bandwidth is appropriate.
- The "mode" is 384 for 14 bit signed little-endian integers: These will be packed into 16 bit signed integers
- The sample rate is 1.536 Msps
- The "-" at the end dumps the output to STDIO rather than a file.
Example with csdr:
"csdr" was written by HA7ILM and may be found here: https://github.com/ha7ilm/csdr
You can find real-world examples of using csdr on this page: Using CSDR for auxiliary receivers on a WebSDR system - link.
This software suite consists of the raw tools necessary to take a raw I/Q stream, filter and demodulate it as the example shows:
./miri_sdr -f 2500000 -w 200000 -m
384 -s 1536000 - | csdr convert_s16_f | csdr fir_decimate_cc 32
0.01 HAMMING | csdr bandpass_fir_fft_cc -0.1 0.1 0.05 | csdr amdemod_cf
| csdr fastdcblock_ff | csdr agc_ff | csdr limit_ff | csdr
convert_f_s16 | csdr mono2stereo_s16 | aplay -r 48000 -c2 -f s16_le
In this example we have the same configuration of "miri_sdr" as above (e.g. tuned to 2.5 Mhz) but are using CSDR to decimate and AM demodulate it as follows:
- csdr convert_s16_f - This takes the raw data from "miri_sdr" and converts to the floating point format that csdr wants.
- csdr fir_decimate_cc 32 0.001 HAMMING
- This decimates the 1536 kHz raw stream by 32 to yield exactly 48 kHz
- the sample rate that we want at the end. The "0.01" is the
bandwidth (0.001 * 1536000 = 15360 Hz) of the result using a HAMMING
window filter. This filter isn't particularly sharp, but it will
suit our demonstration.
- By the act of decimation and filtering, one can "gain" A/D
resolution by oversampling. For example, we are sampling our raw
data at 1536 kHz, but decimating to 48 kHz, a factor of 32: Since
the square root of 32 is 5.66, this implies a bit more than 2 bits of
added precision. What this also means is that if we were to use a
higher rate - such as 3072 kHz and decimate by 64, instead, we'd (theoretically) add 3 bits of precision to our data - at the expense of higher CPU utilization, of course!
- Practically speaking it isn't really a great idea to go
from 1536 kHz to 48 kHz in a single decimating step. Since our
usable bandwidth after this is +/- 24 kHz from center, we would need to
have good filtering beyond this to attenuate undesired signals that
will alias into the passband - but this is difficult and "expensive" (in terms of CPU power)
to do such filtering and still yield anything resembling a full
48 kHz bandwidth with reasonable anti-aliasing filtering. One
would, instead, likely have to do this in two steps, possibly with the
use of a "strong" bandpass filter between.
- csdr bandpass_fir_fft_cc -0.1 0.1 0.05
- This does an FIR bandpass and since this follows the
decimation-by-32, we are already at 48 kHz: The "-0.1" and "0.1"
specify the lower and upper edge of the bandpass as a ratio of the
sample rate (48000 * 0.1 = 4800) and the 0.05 is the "transition width"
(e.g. "sharpness") of the filter.
- csdr amdemod_cf - This does an AM demodulation of the signal stream.
- There is an important caveat with this example:
Since our center frequency is tuned to 2.5 MHz, that means that
an AM signal with its carrier right at 2.5 MHz will fall into the "zero
Hz hole" mentioned before, so this example is the wrong way to go about it - but I purposely chose it to demonstrate the need to stay out of the "hole"
- For receiving AM, one would shift the center frequency off slightly (a few 10s of kHz, perhaps) and the use the "csdr shift_addition_cc"
function to mathematically re-center it within the raw I/Q stream:
At this point the "zero Hz hole" would be mathematical rather
than in actual hardware where it is no longer a problem. See the web page mentioned above for more details.
- Example #1: If the frequency is 2.51 MHz (2510000 Hz) one would add "csdr shift_addition_cc 0.006510416666"
just after "csdr convert_s16_f" to cause the raw I/Q data to be
"shifted" by 10 kHz. This "shift addition" step is being done at
the receiver acquisition rate of 1536 kHz in this example so we could
shift it plus or minus a few hundred kHz.
- Example #2:
Also tuning to 2.51 MHz, we could, instead, shift the audio by 10
kHz after the "csdr fir_decimate_cc 32 0.001 HAMMING" step with: "csdr shift_addition_cc 0.208333"
. This will take far less processing power than Example #1,
above, but since we have already decimated by 32 to a 48 kHz bandwidth
we would have to take into account the fact that our working bandwidth
is less than +/- 24 kHz from center and the fact that the filtering built into our "decimate" step will also limit the usable tuning range.
- csdr agc_ff - This applies an automatic gain control to the demodulated signal.
- csdr limit ff - This prevents the audio from exceeding limits set by this function (e.g. noise bursts, clicks) - the default is suitable for our purposes.
- csdr convert_f_s16 - This converts from the floating point back to signed 16 bit (little-endian) integer data.
- csdr mono2stereo_s16 - As the name implies, this makes a 2-channel mono signal out of a single-channel mono signal
- aplay -r 48000 -c2 -f s16_le - This will cause the audio to play on the default audio output device.
Using with a WebSDR system
Referring to other documents on this site
mentioned above, we can apply what we no know to make this usable with
a PA3FWM WebSDR. To accomplish this we must decimate to the input
rate of the WebSDR - and let's assume that we have it configured for a
768 kHz bandwidth (see the article "Operating a WebSDR receiver at 384 or 768 kHz using the 16 bit signal path" - link and related at this site.
A possible configuration is as follows:
./miri_sdr -f 2510000 -w
600000 -m 384 -s 1536000 - | csdr convert_s16_f | csdr fir_decimate_cc
2 0.45 HAMMING | csdr limit_ff | csdr convert_f_s16 | aplay -r 768000
-c2 -f s16_le --disable-softvol -B 50000 -D plug:rx_ch0
In this example we are tuned to 2.51 MHz with a hardware bandwidth
of 600 kHz using the 14 bit mode and a raw sample rate of 1536 kHz,
sending the output to several instances of csdr. Using csdr, we
convert to floating point, decimate by two to yield 768 kHz, prevent
clipping, and then convert back to signed 16 bit and then send it to
our loopback device using "aplay" configured for 768 kHz and
two-channel audio.
In testing this, it's noted that the decimation filter doesn't seem to have quite the effect expected (e.g. it didn't seem to be filtering at all based on experiments with differing bandwidth settings),
but the hardware filter (set to 600 kHz) seemed to do a reasonable job.
Practically speaking, an instance of "csdr bandpass_fir_fft_cc"
could be used before and after the decimation to provide additional
filter, at the expense of CPU utilization.
Experiments were also done with the "gain" (-g) parameter and it
was noted that the default amount of gain (0) was still too high for typical HF use: As noted below a means of adjusting the RSP1a's other gain parameter (attenuation, actually) doesn't seem to be available via the interface, but more testing is warranted.
CPU Utilization
The "test" computer is quite old, running an Intel E5400 dual-core
Pentium at 2.7 GHz: Not a speed demon, but plenty good for
testing.
- For the above configuration, the CPU utilization
for the above configuration is about 13% for the "miri_sdr" instance,
about 8% for "aplay", and about 24% for the instances of "csdr".
This implies a total utilization of about 45%, but this is spread
across both cores.
- Using the SDRPlay API, the "sdrplayalsa" and "aplay" to
accomplish the same thing showed about 34% for two API instances, 13 %
for two instances of "sdrplayalsa". This implies a total
utilization of about 47%, also spread across both cores.
This would imply that - within the scope of this testing - that the CPU utilization is about the same for each of these methods.
Limitations of "miri_sdr:
As mentioned above, there are some issues with "libmirisdr" as it's presently understood:
- The inability to identify/select specific devices.
As mentioned above, if you have more than one device in your
system, you can't easily identify it as this is currently implemented.
- Gain control.
At the time of writing, the gain control function of this driver
is not well understood as it does not correlate well with the
documented gain functions in SDRPlay devices. For example:
- The gain values supported are 0.0-10.2, but the RSP1a, for
example, has a "gain reduction" value that can be varied from "20dB" to
"59dB". What control range is actually available for the RSP1a,
to continue the example.
- The RSP1a also has an "LNA Gain" setting that affects attenuation in 6 dB (or larger)
steps, apparently by setting an attenuator and/or bypassing an
amplifier stage. There seems to be no corresponding setting.
- Based on a cursory look at the source code, it appears
that at least some of the concerns are accounted for, but not reflected
in the command line arguments.
- LNA Bias.
There doesn't appear to be a way to turn on/off LNA bias, so
assume that it is present unless you verify otherwise - although there
is a block of source code that mentions it.
- No control of filters. The RSP hardware contains filters to remove AM, FM, DAB, etc. that don't appear in the list of commands.
- No ability to change parameters dynamically.
Although I could have easily missed it, there doesn't seem to be
a means of changing parameters such as frequency and gain while it's
running, but I'm sure that it's there!
Other comments:
It would seem that other devices use the same Mirics chipset.
Based on a glance at the file "devices.c" in the source code,
this seems to cover SDRPlay RSP1a and RSP2.
Other devices that appear to use the same/similar chip sets and - based
on the source code - may work include the "VTX3D", Hauppauge WinTV
133559 LF, AverMedia A859 Pure DBTV, IO-Data GV-TV100 stick and Logitec
LDT-1S310U/J. Most of these device are intended for TV reception
and likely will not work well at HF at least without modification and/or additional filtering.
Conclusion:
In testing, the
"miri_sdr" utility/driver shows promise and warrants further
investigation: If there are features present that I missed -
particularly in terms of methods to enumerating multiple devices -
please let me know using the email address below.
Additional
information:
- For general information about this WebSDR system -
including contact info - go to the about
page (link).
- For the latest news about this system and current issues,
visit the latest news
page (link).
- For more information about this server you may contact
Clint, KA7OEI using his callsign at ka7oei dot com.
- For more information about the WebSDR project in general -
including information about other WebSDR servers worldwide and
additional technical information - go to http://www.websdr.org
Back to the Northern Utah WebSDR landing page