A command line interface based on FutureSDR meant to be
- a line-for-line replacement of csdr (original),
- yet able to pack pipelined command in one unique-flowgraph,
- with new commands and expression evaluation,
- able to launch simple GNU Radio Companion flowgraph within FutureSDR runtime,
- a testing tool for FutureSDR community blocks
Features:
- csdr retrocompatibility: ongoing
- GNU Radio flowgraph execution: ongoing
- all in one flow graph execution: single process, no more pipes!
- expression evaluation
- conversion of csdr commands into GNU Radio companion flowgraph wherever possible
- additional commands
In the csdr documentation about WFM demodulation, one can find the following command line:
rtl_sdr -s 240000 -f 89500000 -g 20 - | csdr convert_u8_f | csdr fmdemod_quadri_cf | csdr fractional_decimator_ff 5 | csdr deemphasis_wfm_ff 48000 50e-6 | csdr convert_f_s16 | mplayer -cache 1024 -quiet -rawaudio samplesize=2:channels=1:rate=48000 -demuxer rawaudio -
Does it works with fsdr-cli
? For sure! Just replace every csdr
with fsdr-cli
:
rtl_sdr -s 240000 -f 89500000 -g 20 - | fsdr-cli convert_u8_f | fsdr-cli fmdemod_quadri_cf | fsdr-cli fractional_decimator_ff 5 | fsdr-cli deemphasis_wfm_ff 48000 50e-6 | fsdr-cli convert_f_s16 | mplayer -cache 1024 -quiet -rawaudio samplesize=2:channels=1:rate=48000 -demuxer rawaudio -
But is it the most efficient way? No. One can benefit from FutureSDR efficient scheduling. You just need to transform it as such:
rtl_sdr -s 240000 -f 89500000 -g 20 - | fsdr-cli csdr convert_u8_f ! convert_ff_c ! fmdemod_quadri_cf ! fractional_decimator_ff 5 ! deemphasis_wfm_ff 48000 50e-6 ! convert_f_s16 | mplayer -cache 1024 -quiet -rawaudio samplesize=2:channels=1:rate=48000 -demuxer rawaudio -
Bascially, it is just a matter of replacing pipe |
with !
(escaping pipeline \|
is also working) so that your shell does not interpret them, and asking fsdr-cli
to interpret the command line as a multi-block of csdr
command. There is also one newly inserted block convert_ff_c
due to otherwise ill-typed workflow.
And by the way, why use mplayer
for sound output? There is also an audio
command:
rtl_sdr -s 240000 -f 89500000 -g 20 - | fsdr-cli csdr convert_u8_f ! convert_ff_c ! fmdemod_quadri_cf ! fractional_decimator_ff 5 ! deemphasis_wfm_ff 48000 50e-6 ! audio "48_000" 1
But maybe you are more used to GNURadio and would have come with the following workflow chain1.grc:
Well, it also works:
fsdr-cli grc tests/chain1.grc
All would run fine (even keeping the blocks' name):
$ ./target/release/fsdr-cli grc tests/chain1.grc
$ ./target/debug/fsdr-cli grc tests/chain1.grc
FutureSDR: DEBUG - in run_flowgraph
FutureSDR: DEBUG - Listening on 127.0.0.1:1337
FutureSDR: DEBUG - connect stream io
FutureSDR: DEBUG - connect message io
FutureSDR: DEBUG - init blocks
FutureSDR: DEBUG - wait for blocks init
FutureSDR: DEBUG - running blocks
FutureSDR: DEBUG - blocks_file_source_0 terminating
FutureSDR: DEBUG - blocks_char_to_float_0 terminating
FutureSDR: DEBUG - blocks_deinterleave_0 terminating
FutureSDR: DEBUG - blocks_float_to_complex_0 terminating
FutureSDR: DEBUG - analog_quadrature_demod_cf_0 terminating
FutureSDR: DEBUG - rational_resampler_xxx_0 terminating
FutureSDR: DEBUG - analog_fm_deemph_0 terminating
FutureSDR: DEBUG - blocks_float_to_short_0 terminating
FutureSDR: DEBUG - blocks_file_sink_0 terminating
FutureSDR: DEBUG - blocks_throttle_0 terminating
FutureSDR: DEBUG - audio_sink_0 terminating
fsdr-cli csdr load_c tests/test-nfm.c32 ! fir_decimate_cc 10 0.005 HAMMING ! fmdemod_quadri_cf ! limit_ff ! deemphasis_nfm_ff 48000 ! agc_ff ! audio 48000 1
fsdr-cli csdr load_u8 tests/test-am.u8 ! convert_u8_f ! convert_ff_c ! shift_addition_cc "((145M-144M400)/2_400_000)" ! fir_decimate_cc 16 0.005 HAMMING ! amdemod_cf ! fastdcblock_ff ! agc_ff ! limit_ff ! audio "48_000" 1
Oh by the way, did you notice that you no longer need python? Look at the shift_addition_cc
parameter.
Everywhere one can provide a value can also now provide an expression given it is in bracket "()". Due to bash rules, you may be required to surround them with quotes. You can also use constants pi
, e
, nan
, inf
, neg_inf
, tau
wherever appropriate.
One can also use multipliers notation like 145M500
would be interpreted as 145500000
. Valid multipliers are K
, M
, and G
. Also _
can be used as a separator to ease lisibility, eg 145_500_000
.
Just like with csdr
, one can simulate analog circuit with following commands to demodulate LSB:
fsdr-cli csdr load_c tests/ssb_lsb_256k_complex2.dat ! shift_addition_cc "(-51500/256000)" ! fir_decimate_cc "(256000/48000)" 0.005 HAMMING ! bandpass_fir_fft_cc -0.1 0.0 0.05 ! realpart_cf ! agc_ff ! limit_ff ! audio 48_000 1
Reminder:
bandpass_fir_fft_cc 0 0.1
for USBbandpass_fir_fft_cc -0.1 0
for LSB
Yet, thanks to newly added weaver_lsb_cf
and weaver_usb_cf
we may have better result with following commands line:
fsdr-cli csdr load_c tests/ssb_lsb_256k_complex2.dat ! shift_addition_cc "(-51500/256000)" ! rational_resampler_cc 48000 256000 ! weaver_usb_cf "(1500/48000)" ! gain_ff 0.00000008 ! limit_ff ! audio 48_000 1
So much more to experiment with! Just come to help. ;-
Syntax:
audio rate num_inputs
audio "48_000" 1
Create a sink from an audio device. The sink has num_inputs
floating streams as inputs.
Not all audio rate will be supported by your device, nor num_inputs
.
fsdr-cli
will try his best to find a compatible one but better for you to adapt the flowgraph.
Syntax:
load_u8 filename
load_f filename
load_c filename
Use the file as input.
Syntax:
rational_resampler_cc interp decim
Resample stream based on rational ratio: interp/decim
, just like rational_resampler_ff but on complex stream.
Syntax:
weaver_usb_cf mid_audio_freq_rate
weaver_lsb_cf mid_audio_freq_rate
weaver_usb_cf "(1500/48000)"
Apply weaver method for SSB decoding. Usually one take 1500Hz as the center of the audible audio bandwidth. Basically it acts as following flowgraph:
- realpart_cf1
- clipdetect_ff
- limit_ff231
- gain_ff
- clone
- through
- none
- yes_f
- detect_nan_ff
- dump_f
- dump_u8
- flowcontrol
- shift_math_cc
- shift_addition_cc231
- shift_addition_cc_test
- shift_table_cc
- shift_addfast_cc
- shift_unroll_cc
- decimating_shift_addition_cc
- shift_addition_fc
- dcblock_ff
- fastdcblock_ff3
- fmdemod_atan_cf
- fmdemod_quadri_cf4
- fmdemod_quadri_novect_cf
- deemphasis_wfm_ff4
- deemphasis_nfm_ff2
- amdemod_cf3
- amdemod_estimator_cf
- firdes_lowpass_f
- firdes_bandpass_c
- fir_decimate_cc231
- fir_interpolate_cc
- rational_resampler_ff
- fractional_decimator_ff4
- old_fractional_decimator_ff
- bandpass_fir_fft_cc1
- agc_ff31
- fastagc_ff2
- fft_cc
- fft_fc
- fft_benchmark
- logpower_cf
- encode_ima_adpcm_i16_u8
- decode_ima_adpcm_u8_i16
- compress_fft_adpcm_f_u8
- fft_exchange_sides_ff
- dsb_fc
- add_dcoffset_cc
- convert_f_samplerf
- fmmod_fc
- fixed_amplitude_cc
- mono2stereo_s16
- setbuf
- fifo
- psk31_varicode_encoder_u8_u8
- repeat_u8
- uniform_noise_f
- gaussian_noise_c
- pack_bits_8to1_u8_u8
- pack_bits_1to8_u8_u8
- awgn_cc
- add_n_zero_samples_at_beginning_f
- fft_one_side_ff
- logaveragepower_cf
- mono2stereo_s16
- psk31_varicode_decoder_u8_u8
- _fft2octave
- invert_u8_u8
- rtty_baudot2ascii_u8_u8
- binary_slicer_f_u8
- serial_line_decoder_f_u8
- pll_cc
- timing_recovery_cc
- octave_complex_c
- psk_modulator_u8_c
- duplicate_samples_ntimes_u8_u8
- psk31_interpolate_sine_cc
- differential_encoder_u8_u8
- differential_decoder_u8_u8
- bpsk_costas_loop_cc
- simple_agc_cc
- peaks_fir_cc
- firdes_peak_c
- normalized_timing_variance_u32_f
- pulse_shaping_filter_cc
- firdes_pulse_shaping_filter_f
- generic_slicer_f_u8
- plain_interpolate_cc
- dbpsk_decoder_c_u8
- bfsk_demod_cf
- add_const_cc
- pattern_search_u8_u8
- tee
- ?