The IQ signal from the radio is centered at DC and has a true bandwidth of Fs = 192 kHz. Therefore, I think I should do the following:
1. Upsample to 2*Fs (192 kHz to 384 kHz).
2. Frequency shift the signal by +Fs/2 (+96 kHz). This way, it is no longer DC centered.
3. Take the real part
It seems I am missing a step. After taking the real part, I lose half of my signal bandwidth. The power spectrum is symmetric about Fs (192 kHz), and there is only 96kHz of information in a 384 kHz real signal (there should be 192 kHz of information).
Which step am I missing, and what is the correct process to convert a fully complex IQ signal sampled at Fs to a real signal at 2*Fs?
I was missing a filtering step. So the correct operations are:
1. Upsample IQ to 2*Fs using: upsample(IQ,2)
2. Low pass filter at Fs/2 to remove periodic images outside of +/- Fs/2. This leaves the original complex signal of bandwidth Fs centered at DC.
3. Frequency shift upsampled signal by +Fs/2 (now the lowest frequency is at DC)
4. Take the real part to restore an even, real signal.
I'm glad you figured it out. I recently read this post:
I haven't actually tried it myself.
By the way, I decided to mostly forget using the higher level Matlab DSP routines, and just implement all of the functionality block by block (still using the DSP Toolbox). However, instead of using some higher level function that requires a real input, I am doing the complex processing myself with frequency shifters, filters, Hilbert transforms, etc.
It took a little playing around to figure out all of the signal input details:
1. Which channel is I and which is Q?
2. Is there a phase shift on the channel (e.g. +/-1 or +/-i)?
Once I got this straightened out, it was smooth sailing.
I know that his tread is now really old, but I'm thinking that the steps needed are in fact a lot simpler than the rest of the thread.
How about using the dsp.DigitalDownConverter on the real and imaginary parts independently and then recombining them into an new I/Q signal?
NewIQ = complex(dsp.DigitalDownConverter(real(IQ),...), dsp.DigitalDownConverter(imag(IQ)...));
What am I missing?