SSB Demodulation

Started by b2508 8 years ago13 replieslatest reply 8 years ago2128 views

Hi all,

I am trying to do the USB SSB Demodulation in FPGA.

From what I understood, SSB demodulation is obtained by having 

m(t) - baseband message signal of frequency f_m (has peaks at +f_m and -f_m)

c(t) - carrier signal of frequency f_c 

and then

modulated_signal(t) = c(t)*(x(t)+j*H{x(t)})

This should have peak at f_c+f_m

After that real part of this is transmitted (peaks at f_c+f_m and - f_c - f_m) and at the receiver side it is downconverted to baseband and filtered.

After that I should have only the peak at f_m. Shouldn't I get the original signal by only taking the real part of this signal.

SSB Demodulation that I found online says that after downconversion I split downconverted signal into real and imag part, perform hilbert on imag and subtract it from real. 

Why is this necessary? What am I missing here?

[ - ]
Reply by karnNovember 6, 2016

SSB is narrow enough that it can be easily demodulated in software on a general purpose computer; you don't need an FPGA. I do it on a Raspberry Pi 3 with a small fraction of just one CPU core.

Here's how I do it. I start with the usual complex sample stream from a SDR: an analog tuner, quadrature downconverter and dual A/D converter. The tuner is set close to but not on the SSB signal. I.e., the SSB signal (which can be LSB or USB) consists entirely of positive or negative frequency components.

In software I generate a complex sinusoid [e^iwt = cos(wt) + i*sin(wt)] whose frequency w is the negative of the SSB suppressed carrier frequency. E.g., if the SSB carrier is at +5 kHz coming out of the A/Ds, I generate a complex sinusoid at -5 kHz. (You can easily generate each successive sample of a fixed-frequency complex sinusoid with a single complex multiply; you need sine and cosine only to set the frequency initially.) I then complex multiply the sinusoid by the signal to produce a new frequency-shifted complex signal with the suppressed carrier at exactly 0 Hz (or as close to it as I can get.)

If the signal is upper sideband, it will typically span the range +300 to +3000 Hz; if it is lower sideband, it will span -3000 to -300 Hz. So I feed it through a complex filter that passes the selected frequency range. The real output of this filter becomes my demodulated audio.

The imaginary part of the output consists of the hilbert transform of the real part. It sounds the same, so it can be discarded (or not computed at all).

I filter by fast convolution, i.e., I convert chunks of the input signal to the frequency domain with a fast Fourier transform (specifically the FFTW3 package), multiply by the desired frequency response, and convert back to the time domain with an inverse Fourier transform. (See "overlap-save method" in Wikipedia.) Because I don't need the imaginary component of the filter output, I can save some time with a complex-to-real inverse transform. The forward transform must be complex-to-complex, and the frequency domain multiplies are also complex.

The reason for the frequency shift operation before filtering is to avoid the artifacts around 0 Hz inherent to quadrature downconversion in analog hardware. There's usually a DC offset that is typically removed with a high pass filter, and you don't want that filter affecting your signal. Even with perfect DC removal there may be residual low frequency phase noise that you'd also like to avoid.

I can also demodulate both sidebands at the same time (i.e., ISB or independent sideband) using a single complex IFFT. The filter passes both negative and positive frequencies, but before performing the IFFT I add the complex conjugates of the negative frequency components to the positive frequency components, and subtract the complex conjugates of the positive frequency components from the negative components (using a temporary variable). This puts the lower sideband on the real IFFT output and the upper sideband on the imaginary IFFT output.

[ - ]
Reply by b2508November 6, 2016

In my system I have channelization which takes care of downconversion (quadrature) and filtering. So assumption is that I get baseband signal consisting of only that one SSB channel, at, say 4 kHz sample rate.

Than out of this signal, which in my opinion should be analytic signal, I need to demodulate it or rather - turn in to its original shape. Now it seems to me that nothing except taking real part of signal needs to be done.

[ - ]
Reply by karnNovember 6, 2016

Well, if you have a filtered analytic baseband signal, then the job is already done. So yes, you just take the real part and send it to your speaker or headphone. Discard the imaginary part or just skip computing it in the first place.

It is important, though, that your filter removes the other sideband before you jettison the imaginary part. If you're receiving USB, then it must not pass negative frequencies. If you're receiving LSB, then it must block positive frequencies. Even though the signal itself doesn't contain those frequencies, there will still be noise and possibly interference in that range that you don't want.

You can think of taking the real part as adding a negative frequency component for each positive component (or vice versa) so that the imaginary parts cancel and leave a purely real signal.

E.g., if your signal is upper sideband and the modulating signal is a 1 kHz tone, then the analytic signal coming out of the filter would be

exp(j*2*pi*1000*t) = cos(2*pi*1000*t) + j*sin(2*pi*1000*t)

Taking the real part is equivalent to adding a tone at *minus* 1 kHz:

cos(2*pi*1000*t) + j*sin(2*pi*1000*t)

+ cos(2*pi*(-1000)*t) + j*sin(2*pi*(-1000)*t)

= 2*cos(2*pi*1000*t)

which is the same except for a constant scale factor of 2.

This works because cosine is a even function: cos(x) == cos(-x) while sine is an odd function: sin(x) == -sin(-x).

[ - ]
Reply by Rick LyonsNovember 6, 2016


   When you wrote "SSB Demodulation that I found online says that ..." it would be nice for us to know exactly which online SSB website you're referring to. Are you referring to the web page at:


If not, perhaps the above web page will be of some value to you.

[ - ]
Reply by JOSNovember 6, 2016

I think you are correct.  However, by converting the imaginary part so that it can be combined with the real part, you use all of the signal power instead of only half of it.

[ - ]
Reply by Tim WescottNovember 6, 2016

I'm not sure what you're missing -- perhaps the fact that if you downconvert with a single channel (no "imaginary" part), you'll get _both_ sidebands on receive.

So, take your modulated signal \( s(t) \).  Forgetting the negative portion of the frequency spectrum it has the intended signal at \( f_c + f_m \), and just downconverting by mixing with a signal at \( f_c \) will get you back your desired signal at \( f_m \).

But now take your modulated signal and add in an interfering signal at \( f_c - f_i \).  Mix with a signal at \( f_c \) and you'll get your desired signal at \( f_m \), but it'll have the interfering signal added in at \( f_i \).

The quadrature downconvert, hilbert, and add (or subtract, for the other sideband), significantly attenuates the undesired sideband.

(Sorry for all the messing around -- I lost my inline math mojo; I appear to have regained it)

[ - ]
Reply by b2508November 6, 2016

Thank you all for replies.

However, I do not fully understand the latest. 

Does the "downconvert with single channel" mean that I multiply signal with real sine instead of complex?

What I have in my system is already complex downconversion. And additional components should be filtered by the stage where I get the baseband modulated signal that I need to demodulate.

Is this interfering signal referring to the components coming from downconversion or it is some additional things that may come with the signal?

If the reason for this kind of demodulation that I asked about is saving of power, couldn't the same effect be gained by multiplying real part with 2?

I am not sure where I got this demodulation, I have done it long time ago in this way but now cant seem to understand why I did it that way :-)

[ - ]
Reply by Tim WescottNovember 6, 2016

Forgive me if I'm being overly pedantic, but until someone shows me a real system that has a quantity that is measured in imaginary numbers, you're not doing complex downconversion -- you're doing quadrature downconversion, which converts two channels (inphase and quadrature).  If you hold your mouth right it looks as if it is complex, but it isn't.

I don't know what your system is, or your system requirements, so I can't tell you why you chose the demodulation that you did.  However, commonly it's done to reject the opposite sideband.  You pretty much can't count on a convenient unoccupied channel adjacent to yours, unless you're really good friends with your local regulators.  Given an occupied channel, you want to attenuate the signal there.

[ - ]
Reply by b2508November 6, 2016

Hi all!

I have another question related to this topic. I understood why I need this type of demodulation and now I am trying to simulate the work of Hilbert Filter.

Namely, I simulate a real sine and want to create analytic signal by having x(t)+j*H{x(t))

When using built in function for Hilbert (in LabVIEW), this works. When I use Hilbert filter formula and try to calculate filter taps and then do the convolution with x(t) and account for delay I get signal which looks almost the same as H{x(t)} from the built in function but when I use it in formula above, negative frequency does not disappear, it is just slightly reduced.

I am not sure what is the reason for this, does anyone know? Is it possible that this version of Hilbert does not do the exact -90 degree shift?

[ - ]
Reply by Tim WescottNovember 6, 2016

Many things are possible.  I suggest you run a pure tone through your Hilbert transform and through the equivalent delay, and put those two results up on a graph.  You should see the same amplitude and a perfect 90 degree phase shift over all your frequencies of interest.

[ - ]
Reply by b2508November 6, 2016

Now I tried to multiply H{x(t)} with some gain, say 1.5 in the Hilbert function that works and got similar result - that it does not completely remove negative component.

I think the reason is that components that should cancel out do not  do that because they don't have the same amplitude. Hilbert coefficients that i use alter the amplitude of sine wave and the build in one does not.

How can I correctly set the gain of Hilbert Transform?

If I use this short simple one it also affects the amplitude.

[-1/7 0 -1/5 0 -1/3 0 -1 0 1 0 1/3 0 1/5 0 1/7] Sum of this filter is 0, so I am not sure if its the right way to calculate gain.

[ - ]
Reply by Tim WescottNovember 6, 2016

Hilbert transforms can't have non-zero gain at zero frequency.  You need to find the gain of your transform at the frequencies of interest.

Try looking at the FFT of the Hilbert?  Compare it to the FFT of 1, because different platforms scale their FFTs differently.

[ - ]
Reply by wolf22November 6, 2016

Reading the whole thread I come to the conclusion, that most people here think at first in discrete frequencies. This is wrong, because it lures one into neglecting the surroundings.

So in principle with all downmixing methods you always get both sidebands, but you are interested only in one of them. Never ignore the opposite sideband, it contains other signals or simply noise. So you need to suppress it.

The usual method to do so, is to mix the input with a I/Q mixer, so you get 2 signals and both contain both sidebands, folded one over the other sideband.

You also need to filter your signals to cut away all input, you are not interested in. After filtering both signals (I and Q) with a bandpass (yes, it needs a bandpass) you need to apply another phase shift of 90 degrees between the I and Q signals. Then you can add I+Q or subtract I-Q to cancel out the undesired sideband and voilà your demodulation is done. The amount of cancellation in the digital realm may be impressive high, nearly perfect - but the analog mixing before will limit it to approx. 40 dB, may be a little more.

So. Many people here suggest to add a Hilbert transformation to one of the I/Q signals while the other is simply delayed. I myself do not like this situation, because this introduces a additional unbalance between I and Q and therefore makes the suppression of the undesired sideband worse.

I prefer to add +45 degrees phase shift to one signal and -45 degrees phase shift to the other. The effect is the same, but the improvement is clearly visible:

- you can do this with the same FIR filter, which you already need to filter the signals.

- both signals are handled in the same way, because the filter kernels for I and Q (the filter's coefficients) are in fact the same, just only one mirrired around the central tap.

- there are no problems with amplitude problems of the Hilbert transformation.

- you do not need additional time (or FPGA logic) for the phase shift, because this is already done by proper generated filter coefficients.

One remark to the bandpass: you cannot phase shift DC and also not Fsample/2. So you need a bandpass to exclude both frequencies from the signal flow.

I have nearly the same problem as you, my problem in particular is, HOW to calculate the filter coefficients in realtime, because if you sit there listening to your radio, you certainly want to shift the upper and/or lower edge of your bandpass by simply turning the knob, if there is noise or something else annoying you. So the calculation of the filter kernel needs to be done in your radio. If this is no topic for you, then you can simply use a ready calculated kernel by using one of the programs from IOWA Hills Software.