charlie-foxtrot / RTLSDR-Airband

Multichannel AM/NFM demodulator
GNU General Public License v3.0
761 stars 135 forks source link

Add option to remove DC Offset from I/Q data #127

Closed fr0sty1 closed 5 years ago

fr0sty1 commented 5 years ago

I'm seeing a very pronounced DC offset showing up at the RTL dongle's modulation frequency (462.800):

462.500   462.550   462.600   462.650   462.700   462.750   462.800   462.850   462.900   462.950   463.000   463.050   463.100   463.150  

  98/ 91    96/ 90   108/ 88    99/ 92   120/ 93   122/ 94   266/ 99   135/ 95   119/ 92   107/ 91   103/ 89    97/ 89   103/ 90   108/ 91  
 106/ 91   102/ 90   101/ 88   104/ 92   116/ 93   136/ 94   270/ 99*  141/ 95   115/ 92   106/ 91   103/ 89    92/ 89   101/ 90    94/ 91  
 100/ 91    96/ 90   109/ 88   112/ 92   109/ 93   134/ 94   272/ 99   135/ 95   113/ 92   119/ 91   102/ 90   107/ 89   102/ 90   108/ 91  
 111/ 91   101/ 90    96/ 88   109/ 92   115/ 93   133/ 94   274/ 99   140/ 95   118/ 92   108/ 91   101/ 90   104/ 89    98/ 90   116/ 91  
 106/ 91    98/ 90   108/ 88   101/ 92   117/ 93   130/ 94   282/ 99   141/ 95   116/ 92   107/ 91    98/ 90   108/ 89   109/ 90   104/ 91 

As you can see there is a significant spike in the noise around the modulation frequency. If I move the modulation frequency down to 462.500 the noise follows:

 462.500   462.550   462.600   462.650   462.700   462.750   462.800   462.850   462.900   462.950   463.000   463.050   463.100   463.150  

 282/ 98   132/ 92   118/ 91   109/ 90   104/ 89   102/ 88   105/ 89   104/ 88   109/ 90   105/ 89    99/ 87    87/ 79    74/ 67    72/ 62  
 269/ 98   141/ 92   119/ 91   106/ 90   101/ 89    94/ 88   103/ 89    97/ 88   104/ 90   106/ 89    96/ 87    86/ 79    71/ 67    67/ 62  
 291/ 98   145/ 92   119/ 91   103/ 90   101/ 89   100/ 88    96/ 89   103/ 88   105/ 90   102/ 89    99/ 87    89/ 79    71/ 67    69/ 62  

Here is a description of a solution: https://www.rtl-sdr.com/removing-that-center-frequency-dc-spike-in-gnuradio-the-easy-way/

szpajder commented 5 years ago

DC offset removal has to be done at full sampling speed. Hence, it is a computationally expensive operation.

Try running rtl_airband on an SDRPlay. Its API library performs DC offset removal behind the scenes. As a result, CPU usage is significantly higher than on RTLSDR, even with the same sampling rate.

Right now you can run rtl_airband with 4 RTL dongles simultaneously on a Raspberry Pi. With DC offset removal, it would not be possible.

Given the fact that rtl_airband uses FFT channelizer, a non-zero DC offset is not that much of a problem. Just set your center frequency, so that it does not coincide with frequencies of your channels.

fr0sty1 commented 5 years ago

I can move the center frequency over, but that means throwing away half the bandwidth if my channels of interest are closely spaced.

Why doesn't the noise estimate for auto-squelch also take this into account? If the estimated noise figures were closer to 'reality' there then I wouldn't have the problems I'm seeing with improper squelch activation due to the DC offset.

One other thing I notice in the code, it looks like there is a DC Offset removal step for NFM decoding, but am I right in saying that it is happening too late to be of help to the waterfall/squelch?

szpajder commented 5 years ago

I can move the center frequency over, but that means throwing away half the bandwidth if my channels of interest are closely spaced.

As far as I see, they are 50 kHz apart. So you can shift the centerfreq by 25 kHz and you should be fine. If not, you may additionally increase fft_size by two to get narrower bins and better selectivity.

Why doesn't the noise estimate for auto-squelch also take this into account?

Because there are other simpler ways to deal with this problem.

One other thing I notice in the code, it looks like there is a DC Offset removal step for NFM decoding, but am I right in saying that it is happening too late to be of help to the waterfall/squelch?

Yes.

fr0sty1 commented 5 years ago

As far as I see, they are 50 kHz apart. So you can shift the centerfreq by 25 kHz and you should be fine. If not, you may additionally increase fft_size by two to get narrower bins and better selectivity.

Thanks for the reply. Shifting the center frequency is probably my only remedy. However I already have 5kHz buckets (1.28M sample rate w/ 256 bins) and I see an increase (slight but noticeable) in the noise floor even 50kHz away which doesn't quite make sense if it was just a 0Hz problem (it should be contained in a single bucket). I'll keep playing around with it.

szpajder commented 5 years ago

However I already have 5kHz buckets (1.28M sample rate w/ 256 bins)

So it's the same as the default bucket width - 2.56 Msps, 512 bins.

If you leave these settings at their defaults, you will get twice as large bandwidth, and you can then put all your channels of interest to the left or to the right of the center frequency.

and I see an increase (slight but noticeable) in the noise floor even 50kHz away which doesn't quite make sense if it was just a 0Hz problem (it should be contained in a single bucket).

Fourier transform of a constant signal is a Dirac delta function only if the analysis time is infinite. In our case, it's 125 µs or 62.5 µs (depending on whether NFM support is enabled or not), so it's a bit shorter than infinity ;) No matter what you do, there will always be some leakage between bins. Things are perfect only in math textbooks.

fr0sty1 commented 5 years ago

I discovered that my Fitipower fc0012 really doesn't like 1.28MHz (or 2.56 for that matter). I switched to 2.88 (1/10th of the internal 28.8MHz clock) and the noise figures are now in the 20s.

NOTE: THIS IS INCORRECT. There is something strange with my RTL device where it ends up in a state with a very high noise floor. Changing gain/samplerate eventually clears it up for me, but I haven't had the problem often enough to determine any sort of pattern. If you get really high noise values try changing options around and see if the problem resolves itself.

fr0sty1 commented 5 years ago

No matter what you do, there will always be some leakage between bins.

This is correct and I did some research and found out exactly how much leakage there is. Before doing the FFT a "seven-term blackman-harris" window is applied to the I/Q sample. This creates a filter which has a main lobe width (-6dB) of 3.52 bins (https://www.edn.com/Home/PrintView?contentItemId=4440416) which is somewhat wide, but it has a maximum side lobe of -163dB.

The wide main lobe means that a signal 1.75bins away will leak in with only 6dB of attenuation but it also means that you can configure your FFT bin width to be ~1/3 of the width of the channel of interest and still receive it.