Initial add of demod testing code.

pull/120/head
Mark Jessop 2019-02-27 20:11:55 +10:30
rodzic 89e21976fa
commit 5fc4f25072
8 zmienionych plików z 438 dodań i 3 usunięć

Wyświetl plik

@ -5,7 +5,7 @@
# Copyright (C) 2018 Mark Jessop <vk5qi@rfhead.net>
# Released under GNU GPL v3 or later
#
__version__ = "20190211-beta"
__version__ = "20190227-beta"
# Global Variables

Wyświetl plik

@ -246,12 +246,13 @@ class SondeDecoder(object):
# DFM06/DFM09 Sondes.
# As of 2019-02-10, dfm09ecc auto-detects if the signal is inverted,
# so we don't need to specify an invert flag.
# 2019-02-27: Added the --dist flag, which should reduce bad positions a bit.
# Note: Have removed a 'highpass 20' filter from the sox line, will need to re-evaluate if adding that is useful in the future.
decode_cmd = "%s %s-p %d -d %s %s-M fm -F9 -s 15k -f %d 2>/dev/null |" % (self.sdr_fm, bias_option, int(self.ppm), str(self.device_idx), gain_param, self.sonde_freq)
decode_cmd += "sox -t raw -r 15k -e s -b 16 -c 1 - -r 48000 -b 8 -t wav - highpass 20 lowpass 2000 2>/dev/null |"
# DFM decoder
decode_cmd += "./dfm09ecc -vv --ecc --json --auto 2>/dev/null"
decode_cmd += "./dfm09ecc -vv --ecc --json --dist --auto 2>/dev/null"
elif self.sonde_type == "M10":
# M10 Sondes

Wyświetl plik

@ -7,13 +7,14 @@
echo "Building rs_detect"
cd ../scan/
gcc rs_detect.c -lm -o rs_detect
gcc dft_detect.c -lm -o dft_detect
echo "Building RS92/RS41/DFM Demodulators"
cd ../demod/
gcc -c demod.c
gcc -c demod_dft.c
gcc rs92dm_dft.c demod_dft.o -lm -o rs92ecc -I../ecc/ -I../rs92
gcc rs41dm_dft.c demod_dft.o -lm -o rs41ecc -I../ecc/ -I../rs41
gcc rs41dm_dft.c demod_dft.o -lm -o rs41ecc -I../ecc/ -I../rs41 -w
gcc dfm09dm_dft.c demod_dft.o -lm -o dfm09ecc -I../ecc/ -I../dfm
# Build M10 decoder
echo "Building M10 Demodulator."
@ -25,6 +26,7 @@ g++ M10.cpp M10Decoder.cpp M10GeneralParser.cpp M10GtopParser.cpp M10TrimblePars
echo "Copying files into auto_rx directory."
cd ../auto_rx/
cp ../scan/rs_detect .
cp ../scan/dft_detect .
cp ../demod/rs92ecc .
cp ../demod/rs41ecc .
cp ../demod/dfm09ecc .

Wyświetl plik

@ -0,0 +1,117 @@
# Radiosonde Demodulator Testing Scripts
For these scripts to work, we need:
* The following directories created: samples, generated
* The various demodulator binaries (rs41ecc, rs_detect, etc... ) located in ../ Currently using:
* dfm09ecc, m10 (from radiosonde_auto_rx), rs41ecc, rs92ecc, rs_detect, dft_detect
* The above can just be built using the auto_rx build.sh script.
* CSDR installed and available on $PATH: https://github.com/simonyiszk/csdr
* The base high-snr samples located in ./samples/. These can be downloaded from http://rfhead.net/sondes/sonde_samples.tar.gz
* Python (2, will probably work in 3), with numpy available.
## generate_lowsnr.py
This script generates a set of low-SNR samples based on the base high-SNR samples in ./samples/
Calibrated-level noise is added to the sample to produce a file with a user-defined Eb/No ('SNR per-bit').
If everything works 'perfectly', we should expect all the different modems to have similar PER vs Eb/No performance.
However, real-world factors such as packet length, transmitter deviation, filter widths, etc will mess this up.
I wouldn't try and make too many comparions of the performance between different sonde demodulators. Better to strike
a baseline of current performance, and then try and improve on it.
The level of noise to add is determined based on the variance of the sample. Some checking of Eb/No of generated
samples has been performed with David Rowe's fsk demod, though only for the RS41 samples so far.
Modify the EBNO_RANGE variable to change the range of Eb/No values to generate. FSK demods generally fall over between about 10 and 16 dB.
Uncomment the various elements in the SAMPLES array to choose what sample to process.
Then, run with:
```
$ cd scripts
$ python generate_lowsnr.py
```
Notes:
* I suspect the variance measurement for the m10 sample is off. Its performing suspiciously better than the other sondes.
## test_demod.py
This script run the generated samples above through different demodulation chains.
Check the processing_type dict in the script for the differnet demodulation options.
Example:
```
# Demodulate all RS41 samples.
$ python test_demod.py -m rs41_csdr_fm_decode -f "../generated/rs41*.bin"
# Run dft_detect across all samples.
# python test_demod.py -m csdr_fm_dftdetect -f "../generated/*.bin"
```
The output is a csv of: filename, result
Depending on the mode, the result could be a packet count, or it could be a success/no success (in the case of the detection utilities).
# Sample Capture Information
- All captures have radiosonde signal at DC, or as close to DC as practicable.
- Captured using: rtl_sdr -f 402500400 -s 960k -g 49.6 -n 115200000 rs41_960k.bin
- Converted to 96k float IQ using: cat rs41_960k.bin | csdr convert_u8_f | csdr fir_decimate_cc 10 0.005 HAMMING > rs41_96k_float.bin
rs41_96k_float.bin - Vaisala RS41, Serial Number N3920808, 120 packets
rs92_96k_float.bin - Vaisala RS92, Serial Number M2513116, 120 packets
dfm09_96k_float.bin - Graw DFM09, Serial Number 637797, 96 Packets
m10_96k_float.bin - Meteomodem M10, 120 packets
imet4_96k_float.bin - iMet-4, Serial Number 15236, 119 packets
# Older Notes
## Reading data into Python
```
import numpy as np
data = np.fromfile('rs41_96k_float.bin', dtype='c8')
```
## Demodulation Examples
To run these examples, you will need csdr available on the path, and will need the various radiosonde demodulators as built by auto_rx.
Run the build.sh script in radiosonde_auto_rx/auto_rx to build these, then copy them to your working directory.
NOTE: These are not optimised. Have a look in the test_demod.py script for the 'optimal' demodulation commands.
### RS41
#### Using csdr as a FM demodulator:
$ cat samples/rs41_96k_float.bin | csdr fir_decimate_cc 2 0.005 HAMMING | csdr bandpass_fir_fft_cc -0.18 0.18 0.05 | csdr fmdemod_quadri_cf | csdr limit_ff | csdr convert_f_s16 | sox -t raw -r 48k -e signed-integer -b 16 -c 1 - -r 48000 -b 8 -t wav - | ../rs41ecc --ecc --ptu --crc
#### Using nanorx as a FM demodulator:
NOTE - Nanorx seems to invert the FM output, hence the -i option on rs41ecc
NOTE - As of v0.85, nanorx's FM demodulators are likely corrupting the RS41 signal
$ cat rs41_96k_float.bin | csdr convert_f_s16 | ./nanorx -i stdin -r 96k -m FM -t 10 -o - | sox -t raw -r 48k -e signed-integer -b 16 -c 1 - -r 48000 -b 8 -t wav - | ../rs41ecc --ecc --ptu --crc -i
### RS92
#### Using csdr as a FM demodulator:
$ cat rs92_96k_float.bin | csdr fir_decimate_cc 2 0.005 HAMMING | csdr bandpass_fir_fft_cc -0.18 0.18 0.05 | csdr fmdemod_quadri_cf | csdr limit_ff | csdr convert_f_s16 | sox -t raw -r 48k -e signed-integer -b 16 -c 1 - -r 48000 -b 8 -t wav - | ../rs92ecc
### DFM09
#### Using csdr as a FM demodulator:
$ cat dfm09_96k_float.bin | csdr fir_decimate_cc 2 0.005 HAMMING | csdr bandpass_fir_fft_cc -0.18 0.18 0.05 | csdr fmdemod_quadri_cf | csdr limit_ff | csdr convert_f_s16 | sox -t raw -r 48k -e signed-integer -b 16 -c 1 - -r 48000 -b 8 -t wav - | ../dfm09ecc --auto
### iMet 4
Note that the imet decoder isn't used in auto_rx yet. Build from the imet directory using:
$ gcc imet1rs_dft.c -lm -o imet1rs_dft
#### Using csdr as a FM demodulator:
$ cat imet4_96k_float.bin | csdr fir_decimate_cc 2 0.005 HAMMING | csdr bandpass_fir_fft_cc -0.18 0.18 0.05 | csdr fmdemod_quadri_cf | csdr limit_ff | csdr convert_f_s16 | sox -t raw -r 48k -e signed-integer -b 16 -c 1 - -r 48000 -b 8 -t wav - | ../imet1rs_dft

Wyświetl plik

@ -0,0 +1,117 @@
#!/usr/bin/env python
#
# Generate Noisy Sonde Samples, with a calibrated Eb/No
#
# Run from ./scripts/ with
# $ python generate_lowsnr.py
#
# The generated files will end up in the 'generated' directory.
#
# Mark Jessop 2019-02
#
import numpy as np
import os
# Where to find the samples files.
# These are all expected to be 96khz float (dtype='c8') files.
SAMPLE_DIR = "./samples"
# Directory to output generated files
GENERATED_DIR = "./generated"
# Range of Eb/N0 SNRs to produce.
# 10-20 dB seems to be the range where the demodulators fall over.
EBNO_RANGE = np.arange(10,20,0.5)
# List of samples
# [filename, baud_date, threshold, sample_rate]
# filename = string, without path
# baud_rate = integer
# threshold = threshold for calculating variance. Deterimined by taking 20*np.log10(np.abs(data)) and looking for packets.
# sample_rate = input file sample rate.
SAMPLES = [
['rs41_96k_float.bin', 4800, -25.0, 96000],
['rs92_96k_float.bin', 2400, -100, 96000], # No threshold set, as signal is continuous.
['dfm09_96k_float.bin', 2500, -100, 96000], # Weird baud rate. No threshold set, as signal is continuous.
['m10_96k_float.bin', 9616, -18.0, 96000] # Really weird baud rate. WARNING - Samples output by this are a bit questionable at the moment.
]
def load_sample(filename):
_filename = os.path.join(SAMPLE_DIR, filename)
return np.fromfile(_filename, dtype='c8')
def save_sample(data, filename):
_filename = os.path.join(GENERATED_DIR, filename)
# We have to make sure to convert to complex64..
data.astype(dtype='c8').tofile(_filename)
# TODO: Allow saving as complex s16 - see view solution here: https://stackoverflow.com/questions/47086134/how-to-convert-a-numpy-complex-array-to-a-two-element-float-array
def calculate_variance(data, threshold=-100.0):
# Calculate the variance of a set of radiosonde samples.
# Optionally use a threshold to limit the sample the variance
# is calculated over to ones that actually have sonde packets in them.
_data_log = 20*np.log10(np.abs(data))
return np.var(data[_data_log>threshold])
def add_noise(data, variance, baud_rate, ebno, fs=96000, bitspersymbol=1.0):
# Add calibrated noise to a sample.
# Calculate Eb/No in linear units.
_ebno = 10.0**(ebno/10.0)
# Calculate the noise variance we need to add
_noise_variance = variance*fs/(baud_rate*_ebno*bitspersymbol)
# Generate complex random samples
_rand_i = np.sqrt(_noise_variance/2.0)*np.random.randn(len(data))
_rand_q = np.sqrt(_noise_variance/2.0)*np.random.randn(len(data))
return (data + (1j*_rand_i + _rand_q))
if __name__ == '__main__':
for _sample in SAMPLES:
# Extract the stuff we need from the entry.
_source = _sample[0]
_baud_rate = _sample[1]
_threshold = _sample[2]
_fs = _sample[3]
print("Generating samples for: %s" % _source)
# Read in source file.
_data = load_sample(_source)
# Calculate variance
_var = calculate_variance(_data, _threshold)
print("Calculated Variance: %.5f" % _var)
# Now loop through the ebno's and generate the output.
for ebno in EBNO_RANGE:
_data_noise = add_noise(_data, variance=_var, baud_rate=_baud_rate, ebno=ebno, fs=_fs)
_out_file = _source.split('.bin')[0] + "_%.1fdB"%ebno + ".bin"
save_sample(_data_noise, _out_file)
print("Saved file: %s" % _out_file)

Wyświetl plik

@ -0,0 +1,198 @@
#!/usr/bin/env python
#
# Run a set of files through a processing and decode chain, and handle the output.
#
# Mark Jessop 2019-02
#
# Refer to the README.md in this directory for instructions on use.
#
import glob
import argparse
import os
import sys
import subprocess
# Dictionary of available processing types.
processing_type = {
# RS41 Decoding
'rs41_csdr_fm_decode': {
# Decode a RS41 using a CSDR processing chain to do FM demodulation
# Decimate to 48 khz, filter, then demodulate.
#'demod' : "| csdr fir_decimate_cc 2 0.005 HAMMING 2>/dev/null | csdr bandpass_fir_fft_cc -0.18 0.18 0.05 2>/dev/null | csdr fmdemod_quadri_cf | csdr limit_ff | csdr convert_f_s16 | sox -t raw -r 48k -e signed-integer -b 16 -c 1 - -r 48000 -b 8 -t wav - 2>/dev/null| ",
# Decimate to a 24 kHz channel, demod, then interpolate back up to 48 kHz.
#'demod' : "| csdr fir_decimate_cc 4 0.005 HAMMING 2>/dev/null | csdr fmdemod_quadri_cf | csdr limit_ff | csdr rational_resampler_ff 2 1 0.005 HAMMING | csdr convert_f_s16 | sox -t raw -r 48k -e signed-integer -b 16 -c 1 - -r 48000 -b 8 -t wav - 2>/dev/null| ",
# Decimate to a 12 khz channel, demod, then interpolate back up to 48 kHz. - WORKS BEST
'demod' : "| csdr fir_decimate_cc 8 0.005 HAMMING 2>/dev/null | csdr fmdemod_quadri_cf | csdr limit_ff | csdr rational_resampler_ff 4 1 0.005 HAMMING | csdr convert_f_s16 | sox -t raw -r 48k -e signed-integer -b 16 -c 1 - -r 48000 -b 8 -t wav - 2>/dev/null| ",
# Decode using rs41ecc
'decode': "../rs41ecc --ecc --ptu --crc 2>/dev/null",
# Count the number of telemetry lines.
"post_process" : " | grep N3920808 | wc -l"
},
# RS92 Decoding
'rs92_csdr_fm_decode': {
# Decode a RS92 using a CSDR processing chain to do FM demodulation
# Decimate to 48 khz, filter to +/-4.8kHz, then demodulate. - WORKS BEST
'demod' : "| csdr fir_decimate_cc 2 0.005 HAMMING 2>/dev/null | csdr bandpass_fir_fft_cc -0.10 0.10 0.05 2>/dev/null | csdr fmdemod_quadri_cf | csdr limit_ff | csdr convert_f_s16 | sox -t raw -r 48k -e signed-integer -b 16 -c 1 - -r 48000 -b 8 -t wav - 2>/dev/null| ",
# Decimate to a 24 kHz channel, demod, then interpolate back up to 48 kHz.
#'demod' : "| csdr fir_decimate_cc 4 0.005 HAMMING 2>/dev/null | csdr fmdemod_quadri_cf | csdr limit_ff | csdr rational_resampler_ff 2 1 0.005 HAMMING | csdr convert_f_s16 | sox -t raw -r 48k -e signed-integer -b 16 -c 1 - -r 48000 -b 8 -t wav - 2>/dev/null| ",
# Decimate to a 12 khz channel, demod, then interpolate back up to 48 kHz.
#'demod' : "| csdr fir_decimate_cc 8 0.005 HAMMING 2>/dev/null | csdr fmdemod_quadri_cf | csdr limit_ff | csdr rational_resampler_ff 4 1 0.005 HAMMING | csdr convert_f_s16 | sox -t raw -r 48k -e signed-integer -b 16 -c 1 - -r 48000 -b 8 -t wav - 2>/dev/null| ",
# Decode using rs41ecc
'decode': "../rs92ecc -vx -v --crc --ecc --vel 2>/dev/null",
# Count the number of telemetry lines.
"post_process" : " | grep M2513116 | wc -l"
},
# DFM Decoding
'dfm_csdr_fm_decode': {
# Decode a DFM using a CSDR processing chain to do FM demodulation
# Decimate to 48 khz, filter to +/-6kHz, then demodulate.
#'demod' : "| csdr fir_decimate_cc 2 0.005 HAMMING 2>/dev/null | csdr bandpass_fir_fft_cc -0.12 0.12 0.05 2>/dev/null | csdr fmdemod_quadri_cf | csdr limit_ff | csdr convert_f_s16 | sox -t raw -r 48k -e signed-integer -b 16 -c 1 - -r 48000 -b 8 -t wav - 2>/dev/null| ",
# Decimate to a 24 kHz channel, demod, then interpolate back up to 48 kHz.
#'demod' : "| csdr fir_decimate_cc 4 0.005 HAMMING 2>/dev/null | csdr fmdemod_quadri_cf | csdr limit_ff | csdr rational_resampler_ff 2 1 0.005 HAMMING | csdr convert_f_s16 | sox -t raw -r 48k -e signed-integer -b 16 -c 1 - -r 48000 -b 8 -t wav - 2>/dev/null| ",
# Decimate to a 12 khz channel, demod, then interpolate back up to 48 kHz. - WORKS BEST
'demod' : "| csdr fir_decimate_cc 8 0.005 HAMMING 2>/dev/null | csdr fmdemod_quadri_cf | csdr limit_ff | csdr rational_resampler_ff 4 1 0.005 HAMMING | csdr convert_f_s16 | sox -t raw -r 48k -e signed-integer -b 16 -c 1 - -r 48000 -b 8 -t wav - 2>/dev/null| ",
# Decode using rs41ecc
'decode': "../dfm09ecc -vv --ecc --json --dist --auto 2>/dev/null",
# Count the number of telemetry lines.
"post_process" : " | grep frame | wc -l"
},
# M10 Radiosonde decoding.
'm10_csdr_fm_decode': {
# M10 Decoding
# Use a CSDR processing chain to do FM demodulation
# Decimate to 48 khz, filter, then demodulate. - WORKS BEST
'demod' : "| csdr fir_decimate_cc 2 0.005 HAMMING 2>/dev/null | csdr bandpass_fir_fft_cc -0.23 0.23 0.05 2>/dev/null | csdr fmdemod_quadri_cf | csdr limit_ff | csdr convert_f_s16 | sox -t raw -r 48k -e signed-integer -b 16 -c 1 - -r 48000 -b 8 -t wav - 2>/dev/null| ",
# Decimate to a 24 kHz channel, demod, then interpolate back up to 48 kHz.
#'demod' : "| csdr fir_decimate_cc 4 0.005 HAMMING 2>/dev/null | csdr fmdemod_quadri_cf | csdr limit_ff | csdr rational_resampler_ff 2 1 0.005 HAMMING | csdr convert_f_s16 | sox -t raw -r 48k -e signed-integer -b 16 -c 1 - -r 48000 -b 8 -t wav - 2>/dev/null| ",
# Decode using rs41ecc
'decode': "../m10 -b -b2 2>/dev/null",
# Count the number of telemetry lines.
"post_process" : "| wc -l"
},
# rs_detect - Sonde Detection.
# Current approach in auto_rx uses rtl_fm with a 22 khz sample rate (channel bw?) setting,
# then resamples up to 48 khz sampes to feed into rs_detect.
#
'csdr_fm_rsdetect': {
# Use a CSDR processing chain to do FM demodulation
# Using a ~22kHz wide filter, and 20 Hz high-pass
# Decimate to 48 khz, filter to ~22 kHz BW, then demod.
# rs_detect seem to like this better than the decimation approach.
#'demod' : "| csdr fir_decimate_cc 2 0.005 HAMMING 2>/dev/null | csdr bandpass_fir_fft_cc -0.23 0.23 0.05 2>/dev/null | csdr fmdemod_quadri_cf | csdr limit_ff | csdr convert_f_s16 | sox -t raw -r 48k -e signed-integer -b 16 -c 1 - -r 48000 -t wav - highpass 20 2>/dev/null| ",
# Decimate to 24 khz before passing into the FM demod. This is roughly equivalent to rtl_fm -r 22k
'demod' : "| csdr fir_decimate_cc 4 0.005 HAMMING 2>/dev/null | csdr fmdemod_quadri_cf | csdr limit_ff | csdr rational_resampler_ff 2 1 0.005 HAMMING | csdr convert_f_s16 | sox -t raw -r 48k -e signed-integer -b 16 -c 1 - -r 48000 -t wav - highpass 20 2>/dev/null| ",
# Decode using rs41ecc
'decode': "../rs_detect -z -t 8 2> /dev/null",
# Grep out the line containing the detected sonde type.
"post_process" : " | grep found"
},
# dft_detect - Sonde detection using DFT correlation
#
'csdr_fm_dftdetect': {
# Use a CSDR processing chain to do FM demodulation
# Filter to 22 khz channel bandwidth, then demodulate.
#'demod' : "| csdr fir_decimate_cc 2 0.005 HAMMING 2>/dev/null | csdr bandpass_fir_fft_cc -0.23 0.23 0.05 2>/dev/null | csdr fmdemod_quadri_cf | csdr limit_ff | csdr convert_f_s16 | sox -t raw -r 48k -e signed-integer -b 16 -c 1 - -r 48000 -t wav - 2>/dev/null| ",
# Decimate to a 24 kHz bandwidth, demodulator, then interpolate back up to 48 kHz.
'demod' : "| csdr fir_decimate_cc 4 0.005 HAMMING 2>/dev/null | csdr fmdemod_quadri_cf | csdr limit_ff | csdr rational_resampler_ff 2 1 0.005 HAMMING | csdr convert_f_s16 | sox -t raw -r 48k -e signed-integer -b 16 -c 1 - -r 48000 -t wav - highpass 20 2>/dev/null| ",
# Decode using rs41ecc
'decode': "../dft_detect 2>/dev/null",
# Grep out the line containing the detected sonde type.
"post_process" : " | grep \:"
},
# RS41 Decoding
'rs41_fsk_demod': {
# Shift up to ~24 khz, and then pass into fsk_demod.
'demod' : "| csdr shift_addition_cc 0.25 2>/dev/null | csdr convert_f_s16 | ../bin/fsk_demod --cs16 -b 1 -u 45000 2 96000 4800 - - 2>/dev/null | python ../bin/bit_to_samples.py 48000 4800 | sox -t raw -r 48k -e unsigned-integer -b 8 -c 1 - -r 48000 -b 8 -t wav - 2>/dev/null| ",
# Decode using rs41ecc
'decode': "../rs41ecc --ecc --ptu --crc 2>/dev/null",
# Count the number of telemetry lines.
"post_process" : " | grep N3920808 | wc -l"
},
# RS92 Decoding
'rs92_fsk_demod': {
# Not currently working - need to resolve segfault in dfk_demod when using 96 kHz Fs ans 2400 Rb
# Shift up to ~24 khz, and then pass into fsk_demod.
'demod' : "| csdr shift_addition_cc 0.25 2>/dev/null | csdr convert_f_s16 | ../bin/fsk_demod --cs16 -b 1 -u 45000 2 96000 2400 - - 2>/dev/null | python ../bin/bit_to_samples.py 48000 2400 | sox -t raw -r 48k -e unsigned-integer -b 8 -c 1 - -r 48000 -b 8 -t wav - 2>/dev/null| ",
# Decode using rs41ecc
'decode': ".../rs92ecc -vx -v --crc --ecc --vel 2>/dev/null",
# Count the number of telemetry lines.
"post_process" : " | grep M2513116 | wc -l"
},
'm10_fsk_demod': {
# Not currently working due to weird baud rate (9614). Doesnt work even with fractional resampling (slow down signal to make it appear to be 9600 baud).
# Shift up to ~24 khz, and then pass into fsk_demod.
'demod' : "| csdr shift_addition_cc 0.25 2>/dev/null | csdr convert_f_s16 | ../bin/tsrc - - 0.99854 -c | ../bin/fsk_demod --cs16 -b 1 -u 45000 2 96000 9600 - - 2>/dev/null | python ../bin/bit_to_samples.py 48000 9600 | sox -t raw -r 48k -e unsigned-integer -b 8 -c 1 - -r 48000 -b 8 -t wav - 2>/dev/null| ",
'decode': "../m10 -b -b2 2>/dev/null",
# Count the number of telemetry lines.
"post_process" : "| wc -l"
},
}
def run_analysis(mode, file_list, shift=0.0):
_mode = processing_type[mode]
_first = True
# Calculate the frequency offset to apply, if defined.
_shiftcmd = "| csdr shift_addition_cc %.5f 2>/dev/null" % (shift/96000.0)
# Iterate over the files in the supplied list.
for _file in file_list:
# Generate the command to run.
_cmd = "cat %s "%_file
# Add in an optional frequency error if supplied.
if shift != 0.0:
_cmd += _shiftcmd
# Add on the rest of the demodulation and decoding commands.
_cmd += _mode['demod'] + _mode['decode'] + _mode['post_process']
if _first:
print("Command: %s" % _cmd)
_first = False
# Run the command.
try:
_output = subprocess.check_output(_cmd, shell=True, stderr=None)
except:
_output = "error"
print("%s, %s" % (os.path.basename(_file), _output.strip()))
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-m", "--mode", type=str, default="rs41_csdr_fm_decode", help="Operation mode.")
parser.add_argument("-f", "--files", type=str, default="./generated/*.bin", help="Glob-path to files to run over.")
parser.add_argument("--shift", type=float, default=0.0, help="Shift the signal-under test by x Hz. Default is 0.")
args = parser.parse_args()
# Check the mode is valid.
if args.mode not in processing_type:
print("Error - invalid operating mode.")
print("Valid Modes: %s" % str(processing_type.keys()))
sys.exit(1)
# Get the list of files.
_file_list = glob.glob(args.files)
if len(_file_list) == 0:
print("No files found matching supplied path.")
sys.exit(1)
# Sort the list of files.
_file_list.sort()
run_analysis(args.mode, _file_list, shift=args.shift)