Car stereos have been standard accessories in automobiles since the late 1970s, and as audio technology has improved, car stereo systems have improved with them. However, even with these advances, car stereos still work based on the same basic procedures pioneered in the 1930s: playing sound so that different parts of the audio come from distinct right and left channels.
The antenna (not radio!) is primarily what determines how far your CB can send/receive - so invest wisely Longer antennas - and those mounted higher up - perform best To learn more, see our comprehensive guide on picking the right CB antenna.
Basic Stereo Sound
The most basic kind of stereo in a car -- or in any environment -- is the simple right and left channel stereo. This takes a piece of music recorded with two tracks -- recorded at different distances through different microphones -- and plays the two sounds through two different speaker systems, positioned to the listener's right and left. Each of those audio signals is called an 'audio channel.' In a car, the left and right channels usually refer to speakers planted in the doors of the passenger compartment. Even in systems with more than two speakers, the channels are split left and right.
Advanced Speaker Controls
A benefit of stereo sound using distinct right and left channel audio is better control over the sound that comes out in your car. Even the most basic car stereo systems give you independent volume controls over the left and right channels. More advanced controls may give you a graphical mixer, allowing you to fine-tune the audio using specific frequency ranges.
Speaker Quality
Most car audio systems have a pair of general speakers that try to replicate the full range of human hearing from 20 Hertz to 20,000 Hertz. According to Crutchfield Stereo Systems, most factory speakers are lower in quality than aftermarket speakers. While replacing all of your speakers at once saves on labor costs, if you're comfortable doing the speaker upgrades yourself, you can do it in stages. Replace the worst sounding speakers first; this gets you the greatest sound quality improvement for the least amount of money.
Quadraphonic and Surround Sound
Quadraphonic and Dolby Surround Sound systems add separate speakers for the higher-pitched sounds in music, often positioning them a bit forward of the 'baseline' speakers to enhance the illusion of different instruments being in different locations relative to the listener. Subwoofers are used to drive lower frequency sounds -- because these sounds aren't as directional as higher frequency ones, the subwoofer is usually a separate channel from the traditional or enhanced left and right speaker channels. While Quadraphonic sound systems usually have four speakers and an optional subwoofer, Dolby sound systems for cars have a subwoofer, and position four or six speakers in different locations through the passenger compartment.
- Digital Vision./Photodisc/Getty Images
More Articles
Prev Tutorial | Index | Next Tutorial2018-Feb-21 - Tutorial 3: Sourcing IQ Signals - the start of a real SDR
The files for this tutorial are available on github.com/ac2cz/SDR
Before we dive into the world of Quadrature Signals, we need to decide what hardware we will use for our software defined radio. We have several approaches we can take.
- We can use something like the softrock that supplies I and Q on each of the stereo channels of the sound card. You can build a receiver from a kit for $20.
- You can buy an SDR dongle like the FunCube Pro Plus which also supplies I and Q with a sound card interface, but with a better front end and filtering, especially for VHF and UHF. At more cost.
- You can use a USB Dongle such as the RTL-SDR or a host of others, but we will need to write some code to extract the audio because it does not act like a sound card. We will do that in Tutorial x
For this tutorial we are going to assume that I and Q audio is available on the stereo channels either read from a sound card or from a wav file. That means you have either built your own radio, are sourcing audio from a sound card based SDR like the Funcube Dongle or are using IQ audio from a third party SDR. If you have a different USB dongle then for now I suggest you open that in another SDR program and record some audio into an IQ file. You can then open the IQ file and process the data in these tutorials. We will frequently record audio and process from a wav file rather than directly from hardware because it is more repeatable and easier to debug. But note one thing. If your SDR is very wide bandwidth and you record that full bandwidth, then you may have difficulty with some of the earlier tutorials. Later we will show how to reduce wide bandwidths to a manageable size with decimation. For now record at a bandwidth like 192000 samples per second.
You can also use my test file if you are unable to record your own.
Simple Direct Conversion IQ Radio
Let's try to create the most simple IQ radio we can, using just the tools we have so far.
Our architecture will be as follows:
In the above architecture we have an IQ Source which supplies I and Q on the stereo channels of the sound card. Or we are reading I and Q samples from a wav file. We read the data into an FFT and display it. We can see the frequency that we will decode on the display and this frequency is passed to the Numerically Controlled Oscillator (NCO). The NCO feeds a software mixer which combines the output of the NCO with the IQ source. We then filter and output the results to the speaker or other sound card device.
People with experience homebrewing radios will recognize this as a direct conversion receiver. If you replace the IQ source with a Low Noise Amplifier (LNA), if the FFT display is replaced with a knob and dial and the NCO is replaced with a VFO, then we have a classic receiver. In fact if you have never built one of these with an NE602 and an LM386, then you should go do that. It is amazing what you can achieve with a handful of components.
A direct conversion receiver with a handful of components is a marvel, but it is not a high performer. It is double sideband, so we have every signal twice at slightly different frequencies. We get interference from stations that are on the other side of zero beat. The filtering is not sharp because it has to be done at audio frequencies. All of those problems are solvable in hardware, but with complex solutions. I built a very nice direct conversion transceiver for example, but you end up with a high component count.
Fortunately those issues are solvable in software with less complexity and with much higher performance. I won't say they are easily solved, or that it is trivial, because there are plenty of things that can go wrong. Some things, like filtering out the opposite side band are much easier in software, but other things, like understanding the Complex FFT results, require some work.
Re-run Tutorial 2
Perhaps you already did this. What happens if we just set our IQ source as the default sound card and run it in Tutorial 2? Or if we have a recording of IQ data, what happens if we let it run through Tutorial 2?
We need to make a couple of tweaks first. We set the 'sampleRate' value in the main method to 192000 and increase 'len', the size of the samples and FFT length, to 4096.
I am using a Funcube Dongle. I used another SDR to set the local oscillator frequency to 14020kHz, right in the middle of the CW section of the 20m band. I like HDSDR because it produces very good recordings, but you can use another 3rd party SDR if you like.
With that all setup, I ran the program again and get the following displayed in our LineChart:
That looks pretty interesting, but is it right? Does it show us anything meaningful? Let's compare that to what we see in something like HDSDR:
Hmm, it is not immediately obvious that they are the same, but it turns out they are. Sort of. Click on the images to make them bigger if you need to inspect them. It looks like our LineChart is just showing the right hand part of the display. On the HDSDR FFT we have a central DC spike at 14020. The local oscillator is the center frequency of our display. To the right of the DC spike we have a set of signals at about 14075kHz. This is the current craze for the digital mode FT8, so 14075 sounds about right. Our real FFT in our LineChart shows the local oscillator frequency in bin 0 on the left hand side of the display. It then shows the same FT8 signals starting about bin 1152. We calculate the bin bandwidth as 192000/4096 = 46.875Hz. So bin 1152 is an offset of 54000Hz or 54kHz. 14020 + 54 is 14074kHz. So these are definitely the same signals.
All this math is a bit tedious. We will update our display tool to show frequency shortly, but we first need to understand why we only have half of the spectrum that HDSDR has.
Our test took one stereo channel from the sound card and calculated the real FFT of it. HDSDR is taking both stereo channels, I and Q, and then calculating the Complex FFT. The result is twice as much bandwidth centered on the local oscillator. But that is not all. Look what happens if I change the local oscillator and have some clear signals on either side of the center frequency:
Uh, oh. We see the signals that HDSDR has on either side of the center frequency in our LineChart display. Except they are all on one side. It turns out that running the real FFT on one stereo channel has recreated the simple hardware direct conversion receiver in software. It is double sideband and the sidebands are 96kHz wide.
The solution to this is actually the same if we are building a high performance direct conversion receiver with electronic components or if we are building it in software. The incoming signal has already been split it into I and Q, which just means we have our signal and a copy of our signal delayed by 90 degrees or PI radians. The delayed signal is called the Quadrature Signal and is referred to as Q. We then process both I and Q to recover our signals. In that way we can demodulate any type of signal we want.
The Complex FFT and a better FFT display
Let's create a class to display a chunk of IQ data as a nice FFT result. This will be based on LineChart. We could extend it, but it is a such a simple class that we will make a copy and modify it from there. Our new class will be called FFTPanel.
Before we get deep into FFTPanel, we need to understand the Complex FFT, at least somewhat. As you read this it may all sound a bit, well, complicated. You don't need to understand everything but you do need to know how the data is laid out and how to calculate the magnitude and phase results. If we remember back to the Prev Tutorial the FFT algorithm was used to implement the real DFT, which decomposed our N signal samples into N/2+1 Cosine waves and N/2+1 Sine waves. We referred to the cosine and sine waves as the Real and Imaginary components of the signal.
In the Complex DFT both our input and output will have cosine and sine wave components.
For the input, the I input is the amplitude of the Cosine wave and is the real component while Q is the amplitude of the Sine wave and the imaginary component. Remember I said that Q is delayed 90 degrees, well a sine wave is 90 degrees out of phase with a cosine wave.
When we run the Complex FFT our output or frequency domain result again has real and imaginary parts. In the real DFT we just looked at the first half of the result. The other half is not calculated by the JTransforms real DFT because it is the mirror image. In the complex DFT the second half contains the negative frequencies.
Now negative frequencies sound a bit strange but as Radio Amateurs we are quite familiar with them. If we take an oscillator and mix it with an incoming signal we expect to get both Upper and Lower sideband signals, unless we filter one of them out. In that case we have both positive and negative frequencies in the mixing operation. We have exactly the same situation here. The Local Oscillator in our SDR has been mixed with the signal from our antenna. Our bandwidth is 192kHz, so we have 96kHz of positive and 96kHz of negative frequencies on either side of the local oscillator frequency. We can not display that with the real DFT because you can not distinguish positive frequencies from negative ones, but we can with the complex DFT.
In our program we will need to double the size of the input and output array, as shown in the layout below. For example, with a 16 point Complex FFT the input array needs to store 32 values. The output is also 32 values and then the Power Spectral Density (PSD) will be length 16.
The positive frequencies are stored in PSD bins 0 to N/2 and the negative frequencies are stored from N/2 to N-1. This is not the same layout that we will display to the user. We would expect the negative frequencies to be on the left, not the right. Bin 0 is our local oscillator frequency. Bin N/2 is half the sample rate.
It is worth knowing that our spectrum is periodic, meaning that our bins from N/2 to N-1 hold the same values as the bins from -N/2 to 0 (if we had calculatled them). So we can see that the negative frequencies do sit to the left of the local oscillator signal, but mathematically they repeat and the FFT algorithm stores the negative frequency results in the bins from N/2 to N-1. It is also worth knowing that all sampled spectrum are periodic. That is part of the weird world of DSP. It is also something we will need to take into account and we will discuss more when that is the case.
So, that is all we need to know for now. There is more in the DSP guide and other books, which I encourage you to read. Let's move on to the code to implement this.
FftPanel
So armed with this information, we copy LineChart and modify it. Let's change the constructor and the setData method to setup and do the FFT calculation. This is 'refactored', which is a fancy term for moved, from our previous main method. The good news is that it also got simpler. We had a special calculation in the DFT for the Power Spectral Density values at the start and end. It turns out that is not needed in the complex FFT where we can treat all results the same. Like before, we again average the results.
We also rewrite the paint routine. Much of the changes are pedestrian display code which have nothing to do with DSP, and you can see the reest of the changes in the FFTPanel class. The core is the display of the FFT itself, which is shown below. Notice that we draw it in two halves with the negative frequencies first. We have some tricky offsets to make sure that we scale bin numbers to the right location on the screen. We use the same 'getRatioPosition()' routine that we wrote for LineChart. In fact we made it 'static' which means we can reference it without instantiating a LineChart object.
In addition to the display loop, we change the axis labels. First we don't want to automatically scale the Y axis. For this test we pick a range of values from 0 to -120 and then plot the FFT result against that. One immediate question is why the Y axis magnitude values are negative. The answer is, because they are very small and we are showing the log value. We use log because they have a large range and are difficult to plot and visualize as raw values. The values we are plotting are the magnitude of the bin (sqrt ( Re^2 + Im^2) divided by the bin bandwidth. So we are showing the power for one Hz. The values are all less than 1. The log of a value less than 1 is negative. You can think about this as power in dBm/Hz.
Secondly, we want the X axis to be labeled with frequencies based on the center frequency of the SDR. To keep everything neat, I put the routines that draw the axis in two private methods 'drawHorizontalScale' and 'drawVerticalScale'. The only real complexity is calculating the frequencies given the positive and negative values. In the routine that draws the scale, we simply calculate the lower and upper bounds from the center frequency and then plot the labels from smallest to largest.
The 'drawVerticalScale' method is similar. You can see both of them in the FFTPanel class. With those created it is time to test it. I decided to modify the MainWindow class so that it passes the sampleRate, centerFrequency and FFT length into the FFTPanel class. That may be how we do it in the future, so it seems like a good way to go.
As a result, our main method becomes very simple. In fact this sort of approach where we code, test, and then refactor to make the code more readable and maintainable, is very common.
You may have noticed that SoundCard and WavFile now take an extra parameter, a boolean. Our current implementation extracts one stereo channel and returns it as doubles. We now want both stereo channels. Rather than just modify the code to provide both channels, we pass in a paramater so we can either extract one channel or both.
We need to modify the constructor, because this changes the size of the array that is returned, and the read method. SoundCard and WavFile get modified in the same way, here are the updated methods for SoundCard:
Running the test program
Let's run our new program. I set the center frequency in HDSDR to 7200kHz, the center of the phone portion of the 40m amateur band in the US. I then set the center frequency to 7200000 in the MainWindow call to FFTPanel and executed the program. We should get something like the below, shown side by side with the output from HDSDR:
That looks pretty good! We are seeing all the same signals across 40m phone. Now if we could just click on one of them and listen to it .... but that will need to wait for another tutorial.Prev Tutorial | Index | Next Tutorial
Enter Comments Here:
Comments on this post
No comments so far.