Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Demodulator as a standalone executable #23

Closed
flux242 opened this issue Aug 9, 2020 · 12 comments
Closed

Demodulator as a standalone executable #23

flux242 opened this issue Aug 9, 2020 · 12 comments

Comments

@flux242
Copy link

flux242 commented Aug 9, 2020

It would be nice to have a FM demodulator as a standalone application. If I do

iq_client --freq 0.023 |
tee >(./rs41mod ...) \
      >(./rs92mod ...)

it makes no sense for all decoders I start in parallel to demodulate the signal first. And without demodulator it is not possible to get audible signal

Input parameters for the demodulator could be at least bandpass filter paramters (e.g -0.5;0.5). Bandpass filter comes before the quadrature demodulator

@rs1729
Copy link
Owner

rs1729 commented Aug 9, 2020

All decoders in
https://github.com/rs1729/RS/tree/master/demod/mod
can demodulate/decode the iq_client IQ data. You can use the options --IQ 0.0 --lp (--lp: IF-lowpass) or --iq2 --lp (since the data is already decimated). There is also --iq0 for a simple FM-quad-demod, but the results are not so good.

E.g.
if the iq-wav-file is (a multiple of) 48kHz and the rs41 at frequency 0:
./iq_server --bo 32 rs41iq.wav

./iq_client --freq 0.0 | ./rs41mod -vx --IQ 0.0 --lp - 48000 32

Perhaps I could extract the FM-demodulor, however you can also use csdr for FM-demodulation (this should work for all decoders that need FM-data):

./iq_client --freq 0.0 | csdr bandpass_fir_fft_cc -0.18 0.18 0.01 | csdr fmdemod_quadri_cf | csdr limit_ff | csdr convert_f_s16 | sox -t raw -r 48000 -b 16 -e signed - -t wav - 2>/dev/null | ./rs41mod -vx

@rs1729
Copy link
Owner

rs1729 commented Aug 9, 2020

Probably iq_server could also FM-demodulate at a given frequency and send it to the client, but then it wouldn't be "iq_server"... For FM-demodulation the server would also need lowpass filter parameters.
Maybe it is better to do FM-demod on the client side, if necessary.

@flux242
Copy link
Author

flux242 commented Aug 10, 2020

yesyes, that's exactly what I'm currently doing with the csdr and the idea to get rid of it. I don't use internal decoders demodulators because it is less flexible as a solution with an external one. I could do additional DSP using sox for example and choose proper bandpass filter for a specific type of sonde. And I wouldn't implement demodulation on the server side as it would make the solution also less flexible.

@rs1729
Copy link
Owner

rs1729 commented Aug 10, 2020

I can check, how a simple standalone FM-demod (and lowpass in front) performs.

@flux242
Copy link
Author

flux242 commented Aug 10, 2020

do you mean a bandpass filter? Because if I want to demodulate an SSB then I would want to specify different values for left and right

@rs1729
Copy link
Owner

rs1729 commented Aug 10, 2020

It is symmetric with respect to 0 Hz. It was not meant to be a general purpose dsp library, sorry.
You could translate the signal off center, or use the optimized csdr library.

@rs1729
Copy link
Owner

rs1729 commented Aug 11, 2020

iq_fm.c
simple FM demodulation:

./iq_fm [--lpbw <lp>] [- <sr> <bps>] [--bo <bps_out> [--wav] [iqfile]
    --lpbw <lp>    :  lowpass bw in kHz, default 12.0
    - <sr> <bps>   :  input raw IQ data
    --bo <bps_out> :  bps=8,16,32 output bps
    --wav          :  output wav header
    [iqfile] : wav IQ-file or raw data (no iqfile: stdin)

output to stdout.
--wav output does not write the size/length. If necessary, correct wav header:
sox --ignore-length file_nolen.wav file.wav.
examples:

./iq_fm --lpbw 8.0 - 48000 16 --wav iq_data_48k16.raw > fm.wav
cat iq_data_48k32.raw | ./iq_fm --lpbw 8.0 - 48000 32 > fm_48k32.raw
./iq_fm --lpbw 8.0 --wav iq_data.wav > fm.wav

@rs1729 rs1729 closed this as completed Aug 11, 2020
@flux242
Copy link
Author

flux242 commented Aug 11, 2020

hmm, I can't seem get it to work. First of all something is wrong with the wav header if I add --wav
secondly, I can only demodulate noise.

This produces clear sonde sound:

cat /tmp/iqsamples.bin | ./csdr bandpass_fir_fft_cc -0.065 0.065 0.02 |     ./csdr fmdemod_quadri_cf | ./csdr limit_ff | ./csdr convert_f_s16 | sox -t raw -esigned-integer -b 16 -r 48000 - -b 8 -c 1 -t wav - highpass 10 gain +5 | aplay -r 48000 -f S8 -t wav -c 1 -B 500000 &> /dev/null

and this produces only noise:

cat /tmp/iqsamples.bin | ./iq_fm --lpbw 3.0 - 48000 16 | sox -t raw -esigned-integer -b 16 -r 48000 - -b 8 -c 1 -t wav - highpass 10 gain +5 | aplay -r 48000 -f S8 -t wav -c 1 -B 500000 &> /dev/null

/tmp/iqsamples.bin is recorded with the 'iq_client --freq ...'

@rs1729
Copy link
Owner

rs1729 commented Aug 11, 2020

What are the parameters of iqsamples.bin?
2 channels, sample rate 48000? And bps? If it is from iq_client, then it is the bps of the baseband data, or you set the bps with --bo <bps_out>.
If you read iqsamples.bin into csdr, then I guess it's float32?!
If so, then it should be
cat /tmp/iqsamples.bin | ./iq_fm --lpbw 3.0 - 48000 32 | sox -t raw -e float -b 32 ...
or
cat /tmp/iqsamples.bin | ./iq_fm --lpbw 3.0 - 48000 32 --bo 16 | sox -t raw -e signed -b 16 ...

If you try wav-output, e.g.
cat /tmp/iqsamples.bin | ./iq_fm --lpbw 3.0 - 48000 32 --bo 16 --wav | ...
the wav-header of the FM-audio does not know the length, so it depends if the following program can work with it.

remark:
- <sr> <bps> is for input,
--bo <bps_out> is optional for output.

EDIT:
if iqsamples.bin is sr=48000,bps=32,ch=2, check
./iq_fm --lpbw 3.0 - 48000 32 --bo 16 --wav /tmp/iqsamples.bin > iq_fm.wav
sox --ignore-length iq_fm.wav iq_fm_fix.wav
if iq_fm_fix.wavis 16bit fm-audio.

@flux242
Copy link
Author

flux242 commented Aug 11, 2020

ah, ok, right, now it works, thanks. I can't test it with the decoder and compare it with the csdr solution right now because there are no sondes currently flying and recorded signal in my iqsamples.bin is too weak. I'll let you know

@rs1729
Copy link
Owner

rs1729 commented Aug 11, 2020

If you have 48e3*0.065=3.12e3, i.e. -3.12kHz .. 3.12kHz bandwidth filter for csdr, better use --lpbw 6.0, i.e. 6kHz. The lp-bandwidth 6kHz is meant to be -3kHz .. +3kHz. The filter is not very steep, but 3kHz bw is maybe a bit narrow.
(At least that's what I intended to do, and I think I tested it also...)

EDIT:
Just remembered,
if (bw > 4.6 && bw < 24.0) lpIQ_bw = bw*1e3;
i.e. for lpbw < 4.6kHz or lpbw > 24.0kHz the default bandwidth of 12.0kHz is set!

@rs1729
Copy link
Owner

rs1729 commented Aug 13, 2020

@flux242

It would be nice to have a FM demodulator as a standalone application. If I do

iq_client --freq 0.023 |
tee >(./rs41mod ...) \
      >(./rs92mod ...)

it makes no sense for all decoders I start in parallel to demodulate the signal first.

Now I understand.
In your blog post you also wrote:

Despite the fact that all decoders can demodulate the decimated IQ stream I'm using the iq_fm because I start all decoders at the same time and then it is much more efficient to do demodulation only once for all of them. Well I do it twice with different filter parameters for different sonde groups.

As an alternative of starting all decoders at the same time one could use the dft_detect utility.

Actually dft_detect is doing FM-demodulation for a very similar reason, it's easier to detect/identify different radiosonde types in FM-data than in IQ-data.
Maybe dft_detect is more efficient than the decoders in parallel, and it can detect more radiosonde types.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants