ik1xpv / ExtIO_sddc

ExtIO_sddc.dll - BreadBoard RF103 / HDSDR
Other
69 stars 26 forks source link

libsddc. Getting Complex IQ? #221

Open Aang23 opened 2 years ago

Aang23 commented 2 years ago

Hello, Since libsddc can now be used on Linux, I am implementing support in one of my projects. To do so, I need to get a complex float IQ stream of samples.

From my understanding, libsddc provides real samples only (at least from what I could find), so I ended up implementing my own conversion to an IQ stream... But digging a bit further, I seem to get 32M samples while the ADC is running at 64M, so perhaps I am mainly reading the samples wrong?

What format does the callback provide exactly?

Thanks!

fventuri commented 2 years ago

@Aang23 - libsddc just retrieves the samples from the ADC; that's pretty much it. The ADC being a physical device only sees and generates samples in the real domain; at the end of the day all it does is sampling the real input voltage from the antenna (plus amplifiers and attenuators), send that stream of real values to the USB port via the FX3 USB chip, and that's what your host PC receives though libsddc. Nothing else.

The concept of I/Q values in the complex domain comes from the theory of quad signals (see here for instance: https://dspguru.com/files/QuadSignals.pdf), and it is conceptually similar to mixing your antenna signal in the real domain with two sinusoidal wave forms (with a difference in phase of 90 degrees) to obtain the I and Q components.

If the numerical oscillator you use to mix the input signal has a frequency of 32MHz (64/2), you are going to get an I/Q signal with a sample rate of 32MHz; higher frequencies of the numerical oscillator would cause aliasing due to Nyquist theorem; another way to see this is that the maximum 'amount of information' you can extract from a 64 Msps signal is a pair of 32 Msps signals (the I and Q components) and that's about it.

Hope this helps, Franco

ik1xpv commented 2 years ago

Hi, thanks for the good news!

Just a note. In the decimation scheme The-Halfcomplex_dformat-DFT.html from http://www.fftw.org/fftw3_doc/ is used. For a real-to-complex transform you get N / 2 + 1 complex outputs for N real inputs (the redundant symmetric outputs are not generated). The 0 Hz component is in bin 0. fftwf_plan_dft_r2c_1d is used in fft_mt_r2iq.cpp

Ciao. Oscar

A copy of my early posts can be found at [BBRF103_posts_2017_2020.pdf] (https://github.com/ik1xpv/ExtIO_sddc/blob/617b501a263fa93f6edfd162d27f20d012f80326/hardware/BBRF103/BBRF103_posts_2017_2020.pdf).

Aang23 commented 2 years ago

Thanks @fventuri, a bit more details than needed but tanks :-) So, libsddc does indeed only dump uint16_t samples as floats in the callback? Then, I would really wonder why conv_r2iq is being called in sddc_open() if (ret_val->handler->Init(fx3, [ret_val](const float* data, uint32_t len){ Callback(ret_val,data,len);}, new conv_r2iq())) line 103.

My first thought was to implement the real-to-complex transform on my own, which I guess was the right decision... Digging into libsddc's code has just been slightly confusing.

You're welcome @ik1xpv! Though actually, is it not possible to push the RX888 above the 64M (real) samplerate? I remember reading in another issue 128M is also usable.

ik1xpv commented 2 years ago

@Aang23 the ADC software clk range is limited from 50M to 140M in config.cpp. In my hardware BBRF103 reaches 100+M while RX888 and RX888mkII samples reach 128+M rate. In the ExtIO_sddc.dll GUI an editbox inputs the ADC clk value. image

Aang23 commented 2 years ago

Thanks, so I assume that's a limitation of libsdc, which has a hardcoded maximum of 64M (ADC). Shouldn't be too hard to modify.

Edit : Got that to work.

Aang23 commented 2 years ago

Actually, when running at 128M, attempting to do anything else with libsddc (stopping the stream), will result in a lockup.

cozycactus commented 2 years ago

libsddc doesn't samples even 16 bits from adc. couldn't make it work in linux

cozycactus commented 2 years ago

here i tried to get streaming work on linux and macOS. seems its working till 150 MHz samplerate

https://github.com/cozycactus/rx888_test

Aang23 commented 2 years ago

libsddc doesn't samples even 16 bits from adc. couldn't make it work in linux

I see. Honestly, I'm considering either trying to get the old libsddc working for my purpose, or perhaps if your example @cozycactus also does work, maybe using it as a base (if you don't mind!).

While I have everything working with this repo's libsddc, I unfortunately have to say it's a bit rough and bulky as-is to keep in my SW for a single device.

This joins #208, but when my goal is simply to provide users with basic control over the device and being able to get samples out, packing the entire ExtIO's code is a bit cumbersome. A library designed more like the original libsddc with Windows support (perhaps possible through libusb as well to unify things though?) would be a lot more suited to this sort of usecase. As I said above, I'm possibly going to work on that when I do find some time, as patching the ExtIO codebase seems like more work in this case. The SDDC hardware is a quite solid option for many usecases otherwise especially for how affordable it is. (well done on this!)

Aang23 commented 2 years ago

@cozycactus Your code seems to work fine here. I will probably try to save samples and check there are no drops or such.