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

Wrong cutoff frequency for SSB Demodulator #355

Closed
Vort opened this issue May 29, 2019 · 9 comments
Closed

Wrong cutoff frequency for SSB Demodulator #355

Vort opened this issue May 29, 2019 · 9 comments

Comments

@Vort
Copy link
Contributor

Vort commented May 29, 2019

Here is the test file: fox_news.zip
It should be possible to demodulate it in LSB mode.
First problem is that once file is loaded, there is no sound.
But if you will be able to get sound, next problem rises:
Setting of cutoff frequency to 9 kHz works fine.
But setting it to 10 kHz result in approximatly the same 9 kHz bandwidth.
Setting it to 10.9 kHz makes bandwidth even lower: 8 kHz:
ssb1
ssb2

@f4exb
Copy link
Owner

f4exb commented May 29, 2019

When trying to demodulate an AM signal with the SSB demod you should filter out the carrier else it will result in considerable energy on DC that will blank out the rest of the audio. So first thing set the low cut at say -0.3 kHz.

Now that you can use 48k audio the issue is that it allows unrealistic values for the filter because it is based on audio rate and not on channel rate. You can even set the span at 24 kHz! The filter width should not exceed about 75% of the total available bandwidth else you reach interpolation filter corner effects. Here it means ~9 kHz. If something is to be done it is probably in the area of the GUI limits not in the DSP.

Note that this is a corner use case since the SSB demod is used for relatively narrow bandwidth signals or at least reasonably sized vs the available bandwidth.

@Vort
Copy link
Contributor Author

Vort commented May 30, 2019

The filter width should not exceed about 75% of the total available bandwidth else you reach interpolation filter corner effects.

It is better to have corner effects in corner cases than totally incorrect results.
Honestly, I don't completely understand the problem.
It looks like with interpolation and decimation you can make any desired bandwidth out of the source signal.
For example, you can extend 12 kHz signal to 24 kHz and then apply 12 * 1.5 = 18 kHz filter to it.
Anyway, does this change breaks something?
It helps me with this problem:

diff --git a/sdrbase/dsp/interpolator.cpp b/sdrbase/dsp/interpolator.cpp
index 467ed0a..3881a84 100644
--- a/sdrbase/dsp/interpolator.cpp
+++ b/sdrbase/dsp/interpolator.cpp
@@ -94,7 +94,7 @@ void Interpolator::create(int phaseSteps, double sampleRate, double cutoff, doub
 		phaseSteps, // number of polyphases
 		1.0, // gain
 		phaseSteps * sampleRate, // sampling frequency
-		cutoff, // hz beginning of transition band
+		cutoff > sampleRate ? sampleRate : cutoff, // hz beginning of transition band
 		nbTapsPerPhase);
 
 	// init state 

"No sound" problem will remain however.
Maybe it is related to uninitialized data somewhere if you did not encountered it.

@f4exb
Copy link
Owner

f4exb commented May 30, 2019

It looks like with interpolation and decimation you can make any desired bandwidth out of the source signal.
For example, you can extend 12 kHz signal to 24 kHz and then apply 12 * 1.5 = 18 kHz filter to it.

No you cannot extend signal to what is not available in the source signal. if your source has 12 kHz bandwidth (12 kS./s sample rate with complex samples) you cannot extend the signal to 24 kHz by interpolation. If you do not apply low-pass filtering during interpolation what appears above 12 kHz is just the folding of the same signal.

The interpolator lets you define the width of the filter with the cutoff parameter and it should remain like this. What you could challenge is the call to the interpolator. In SSB demod it is like this:

m_interpolator.create(16, inputSampleRate, m_Bandwidth * 1.5f, 2.0f);

Because the interpolator filter is not boxcar I have extended it to 50% in excess of the FFT filter bandwidth (FFT filter is almost boxcar shape). This is to avoid significant attenuation in the upper part of the FFT filtered signal. This is fine until the bandwidth reaches input sample rate which happens now. When audio sample rate had to be lower or equal to input sample rate the m_Bandwidth of the FFT filter was hard limited to half the audio sample rate but now this cannot be the case. If you keep the same logic the FFT filter bandwidth should be limited to half the audio sample rate or half the input sample rate whichever is the lower.

The other option you suggest (but should be done in the SSB demod not in the interpolator) is also consistent and in fact is to put the FFT filter bandwidth limit at the audio sample rate or at the input sample rate whichever is the lower. In that case you can expect significant attenuation in the upper frequencies of the filtered signal when the FFT filter bandwidth is close to the maximum allowed.

In any case the FFT filter bandwidth range has to be limited depending on audio or input sample rate whichever is the lower.

@f4exb
Copy link
Owner

f4exb commented May 30, 2019

Basically the 3 calls to m_interpolator.create in ssbdemod.cpp have to be modified like this (with the m_inputSampleRate inputSampleRate variant):

        Real interpolatorBandwidth = (m_Bandwidth * 1.5f) > m_inputSampleRate ? m_inputSampleRate : (m_Bandwidth * 1.5f);
        m_interpolator.create(16, m_inputSampleRate, interpolatorBandwidth, 2.0f);

Then the bandwidth has to be limited by the input sample rate. That is 100% of input sample rate instead of 75% but the logic is the same and should be put in the GUI.

@Vort
Copy link
Contributor Author

Vort commented May 30, 2019

If you do not apply low-pass filtering during interpolation what appears above 12 kHz is just the folding of the same signal.

This is to avoid significant attenuation in the upper part of the FFT filtered signal.

And if you apply 18 kHz filter to 2x interpolated signal (12 kHz -> 24kHz), there will be almost no attenuation in 0 .. 12 kHz range.
Do not know why interpolator failed this task.

but should be done in the SSB demod not in the interpolator

Are there any possibility that interpolator will work fine with cutoff > sampleRate?

@f4exb
Copy link
Owner

f4exb commented May 30, 2019

Are there any possibility that interpolator will work fine with cutoff > sampleRate?

Definitely not. I think you should read about interpolation in DSP. Anything above input sample rate is rubbish and risks to fold in the useful signal band. So the interpolator filter HAS to be limited by input sample rate (here 12 kHz).

Anyway on dev now you will find a version that hard limits FFT bandwidth and interpolator filter bandwidth to input sample rate which allows you to take the maximum possible advantage of the available bandwidth.

@Vort
Copy link
Contributor Author

Vort commented May 30, 2019

Definitely not.

So why not to put limiting code (or assertion) inside Interpolator::create ?

@f4exb
Copy link
Owner

f4exb commented May 30, 2019

This is internal and internally you should know what you are doing.

@Vort
Copy link
Contributor Author

Vort commented May 30, 2019

Ok, demodulation now works better, so this ticket can be closed.

By the way, std::min will be definitely shorter and even may work faster:
Real interpolatorBandwidth = std::min(m_Bandwidth * 1.5f, (Real)inputSampleRate);

Sound problem is extracted to #356.

@Vort Vort closed this as completed May 30, 2019
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