Decoding AM from SDR into sound?

Status
Not open for further replies.

Artlav

Full Member level 2
Joined
Nov 26, 2010
Messages
144
Helped
2
Reputation
4
Reaction score
2
Trophy points
1,298
Activity points
2,723
In short, how do you decode AM signal from I/Q samples into sound?

In details, i made an SDR that uses a PC sound card as ADC.
The local oscillator on it is set to 700KHz, there is a radio station at 731KHz.
With existing software i verified that the hardware works - the station is here and i can hear it.

Now, the goal is to make my own SDR software.
I can read the I/Q signals, at 96K samples, into a program on a PC.
When i do FFT on them, i see the target station at 31KHz in there.

And that's where i ran out of knowledge.
There is a lot of info on the net on how to make SDR hardware, but i wasn't able to find anything on how to make SDR software.

So, i have two sets of numbers that are I/Q samples, 96000 of them per second, and a frequency of the station.

How do i get sound out of them?
Where to begin, what names to google for, what to read?
 

For AM, you can throw away the Q, and take the amplitude of I
and there's your audio stream, badda-bing. Using the 31kHz as
the "IF" I suppose would work but might lose you some audio
quality (like you care, about AM audio quality to that degree).

I think you'd have less software burden if you could notch
filter the incoming signal, but if your gear can keep up with
FFT then the peak amplitude at 31kHz, slice by slice, is your
audio (though spectrum analyzers call this, "video").
 

A good collection of links.
Thanks, i'll be looking through them.

For AM, you can throw away the Q, and take the amplitude of I
and there's your audio stream, badda-bing. Using the 31kHz as
the "IF" I suppose would work but might lose you some audio
quality (like you care, about AM audio quality to that degree).
Not sure if that is the right thing.
The idea is that there can be several stations within the samples.
One might be at 50KHz, other at 10KHz.
I want to be able to "tune" to one or the other, and get audio.

In more serious SDRs the bandwidth is far greater than 90KHz, being able to do the above is the whole point of having it.
 

If the signal contains multiple stations, you'll gonna filter the signals...

Basically two approaches:

- extract carrier frequencies, e.g. by all-digital PLLs, perform synchronous demodulation (using complex I/Q signals) for each station, apply low pass filters to suppress OOB components.

or
- perform bandpass filtering for each station, apply envelope demodulation as suggested by dick_freebird
 

Looked through Dan Mills's links. It's either over my head, or not quite related.
All i got from there is how to do low- or high-pass filters in software, which is useful, but does not solve the main problem.

Meanwhile, had a limited success in getting audio.

The input is multiplied by cos(2*pi*31khz*(t/96000)), sample per sample.
This gives an approximation of "beat frequency" effect, subtracting the carrier and getting the "beats" of target sound.
That is followed by a low pass filter.

However, the sound quality is abysmal, with all sorts of noise.

My problem is that while i sort of understand what operations are needed to be performed, i just can't understand what they mean in terms of a sequence of samples containing wave amplitude that i have on hand.
 

You should also have gotten the use of a complex multiply as a mixer, which is part of the key to this thing.

Your input is an I/Q pair right?

Do a complex multiply by e^jwt at the carrier frequency (make a complex number sin wt + j cos wt where w is 31000 * 2 * pi radians/second and multiply the input by it) which will move your carrier to dc, then highpass at a few tens of Hz to remove the carrier and lowpass at a few KHz to provide selectivity.

The real part of the result is the recovered audio.

In a real program you would probably want to decimate after the mixer so that the filters and demodulators downstream can run at a lower sample rate but that is a detail.

Regards, Dan.
 
Hm, that seems to be a proper way to do what i was stumbling towards, thanks.
Bad news is, the result is only slightly better.

The sound is still poor.

There is a low-frequency component that sounds like smoothed wind sounds recorded by a very cheap microphone. Highpass does not help much before starting to eat the target sound.
And the sound itself sounds like it's coming from earphones a few meters away set to full volume. Distorted in hard to describe way.

Perhaps there is another approach?
HDSDR produces very clear sound from the same input signal somehow, and is much less sensitive to things like frequency being set exactly right.
 

It's not quite clear what's causing the bad signal quality. It may be a non-ideal first mixer (I/Q phase error, nonlinearity, intermodulation). Or carrier frequency offset.

Did you try to tune the first or second (digital) LO for zero beat frequency? As previously mentioned, you would preferably use a digital PLL to track the exact downmixed carrier frequency.
 

Try this,
Set up a selective bandpass filter to select just your desired signal say 31K +- 5KHz, now at any time the complex magnitude of thie resulting IQ pair (sqrt(I^2+Q^2)) is the envelope of the signal, highpass this and you should get your audio back.

Your wind sounds may be aliasing products, make sure your complex multiply is correct or you will be trying to produce a sum component at 62KHz which will not work real well at 96K sample rate.

A more sophisticated system is possible using a syncronous demodulator, somewhat tricky to implement well in software.

Have a look at the code in DTTSP and possibly GNU Radio both have examples.

73 M0HCN
 
Aha.
Now that works perfectly and sounds great.
Thanks!

Now it behaves similar to HDSDR - you don't need to track the carrier precisely, just put it close and the sound comes up.
 

One more question, while it's still related.
I tried to do band-pass filtering by doing FFT of the signal, removing (that is, setting them to (0,0) ) the unwanted frequencies, then doing reverse FFT.
However, that produce chirps in the sound - spikes at the start and end of the segment of samples.

It does not look like an FFT implementation issue - without altering the coefficients the signal gets reproduced cleanly after reverse FFT.

What can that be?
Is it even possible (or right thing to do) to do such filtering through FFT?
 

Ok, from what i gathered doing that is not quite possible.
Just removing the frequencies would produce ringing, due to the sharp transition invoked - while frequencies inside the bins will be zero, ones between the bins are free to change.
There is something about using window functions to help fix it, but that does not work, and the only description on how to do it properly i found was "it's difficult".

Another thing that does not work is copy-and-pasting the signal in frequency domain from where it is down to 0.
That produce pretty much exactly the same distorted sound as my first attempt with beat frequency.
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…