# Obtain I/Q Components from a Real Signal On the Fly - Hilbert Transform or Digital Downconversion?

I'm planning to build a data acquisition system for a software-defined radio receiver. Basically, it just uses an ADC which samples an analog signal and send the signal to a processor. And then a stream of samples would be fed into a host computer with Software-Defined Radio software packages for signal processing. And since the frequency I'm working on is fairly low, I want to simply run the ADC at twice the Nyquist frequency without having separate I/Q channels, and also, I plan to use Zero-IF.

Most SDR programs designed to natively work with analytic signals, not real signals, so converting the real samples of the signal to I/Q components inside the hardware on the fly before it reaches the host computer is desirable. However, I don't have any prior knowledge on signal processing, and I'm struggling to come up with a solution, but after reading everything I can find on the web, there are basically two options (as mentioned, I don't have any DSP knowledge, it's possible that I'm misguided.).

1. Digital Downconversion: Multiply the signal with sin(ωt) and cos(ωt) independently for I and Q. It's basically recreates an I/Q mixer digitally, and common in Low-IF radio receivers.

• To me, this concept appears easy to understand, and its implementation is straightforward, just multiply. Although it would mean the frequency of my analytic signal must be shifted, but I don't think it's a big deal, I may as well upconvert the signal a little bit or switch to Low-IF, if DDC is easier overall.
2. Hilbert Transform: Compute the Discrete Hilbert Transform on the real samples to obtain the analytic signal.

• To me, I have no idea on how to implement it. It seems to be a lot of different approaches of doing it.

(1) Calculate the Hilbert Transform via direct convolution. This method seems to suffer from a number of limitations. André Bergner said "a direct convolution is very slow opposed to a FFT based [...] Secondly, the HT kernel has a singularity at zero and the numerical computation of the convolution integral is ill-posed".

(2) Calculate the FFT. Deleting the negative frequencies. Applying the inverse FFT.

(3) Model the transform as a time-invariant filter and implement it as such.

Initially, I thought using digital downconvertion would be convenient because... First, I don't know what I'm supposed to do to implement a Hilbert Transform, especially when using it on incoming samples on the fly, digital downconvertion seems to be easier to implement. Also, a Hilbert Transform looks like a "lossy" process, and some information would be lost due window size of the FFT/filter, but DDC is "lossless". Also, DDC looks much faster as only multiplication is used.

But at a closer look, it isn't really the case. In DDC, both the I and Q channel needs to be filtered afterwards as well, by definition all practical digital filters are approximations, it's incorrect to say DDC is less "lossy" than DHT. Also, the requirement of using two filters rather than modeling the DHT in a single digital filter, means that DDC potentially is slower the DHT. There are also various concerns about the numerically-controller oscillators in DDC.

My questions are,

1. If the objective is only for creating a naive implementation for obtaining I/Q components from a stream of samples for a real signal on the fly, which method is better in terms of simplicity and ease of understanding?

2. If the objective is for creating an output of the best "quality", which method is preferable?

3. If the objective is for creating an efficient program on a signal processor with limited computing power, which method is better in terms of performance?

4. If a Hilbert Transformer is desirable, what would be an appropriate method to implement it? Are there any reference implementation? What should I start from? In particular, the hilbert() function is most scientific computing software packages seems only designed to work on an existing array of data, but not a continuous stream of data, an implementation with demonstration of using windowing is appreciated.

5. Overall, which method is appropriate for my application?

• Both approaches can work. In my opinion, #1 is both the easiest to understand and to implement. One question about your project description, though: how do you intend to implement a zero-IF receiver with only one ADC? Inherently, once you've downconverted your signal to a zero IF (baseband), you need to have both I and Q components to represent it. If you want to sample it with one ADC only, then you would need to use some nonzero IF. You can often get better performance by doing this if you can. – Jason R Jan 21 at 2:42

[Update: I mentioned a possible +3dB processing gain by including the Hilbert Transform prior to DDC for the case of a real IF signal in the first version of this post, which @MattL questioned so I dug into this further and confirmed that there is no such processing gain, so the only advantage to doing that would be to simplify filtering since it would provide an image rejection.]

1. For a quick implementation I recommend sampling to a digital IF frequency ($$F_s/4$$ is an excellent choice), and then doing a digital down conversion with a complex NCO (quadrature down-conversion) which creates the I/Q components for your baseband signal. Note if the IF frequency could be guaranteed to be exactly $$F_s/4$$, or if an approximate result is ok because you can do a phase rotation at baseband to correct residual frequency offsets, then the two outputs (sine and cosine) of the complex NCO would simply be:

1 0 -1 0 1 0 -1 0

0 1 0 -1 0 1 0 -1

Very convenient!

Also $$F_s/4$$ or any multiple thereof such as $$3F_s/4$$, $$5F_s/4$$, etc for undersampling which provides the same result as above also simplifies your analog filtering since your alias frequencies (that you must filter out prior to conversion) will be spaced at equal distances in this case.

2. For optimum performance, a Hilbert Transform can be included either digitally at the digital IF frequency prior to the quadrature down-conversion OR in the analog prior to the ADC to convert your real signal $$s(t)$$ to a complex signal $$s(t) + j\hat s(t)$$ where $$\hat s (t)$$ is the Hilbert Transform of $$s(t)$$. The narrower your actual signal bandwidth as a fraction of the IF frequency, the easier it is to implement. In the analog they are done with quadrature hybrids that provide an in-phase and quadrature representation of the signal such as these here: https://www.minicircuits.com/WebStore/90_180_degree_hybrid.html and there are common digital filter design techniques (in Matlab/Octave and Python) available to design a Hilbert transform digitally.

The benefit of this approach is to eliminate image frequencies which simplifies filtering requirements. I explain this in more detail with the help of graphics at this posting here: Frequency shifting of a quadrature mixed signal

Other variants: Do the quadrature hybrid in the analog and then use two ADC's to sample each output as I and Q. If the sampling rate is at the carrier frequency at the output of the quadrature hybrid then the ADC will perform the down conversion function, or the ADC’s can be at an IF frequency with a full complex digital downconverter done digitally. Do the downconversion with two analog mixers where the RF or IF signal is fed into the input of both mixers and the sine and cosine of the carrier is multiplied with each creating baseband I and Q signals that can then be directly sampled by dual ADC’s. When the mixers are directly at the RF carrier this is called Zero-IF. If a quadrature hybrid can be included prior to the mixers this would offer the same advantages to be described above at the complexity of doing that.

3. For this one I think you will need to answer once you are familiar with the options. What has best performance for limited computing power is difficult to answer generally. Certainly option 1 is simpler and has a 3 dB penalty over doing 2 but that may not be an issue for you. That is the trade you will need to make.

4. I wouldn't be able to provide detailed design instructions (beyond what is typically answered here), but digitally this is done as a digital filter design; you design two all-pass digital filters that pass all frequencies in your pass band and each has a phase that tracks the other offset by 90° (Phase tracking filters). The tools I mentioned (Matlab/Octave/Python Scipy.Signal) all have tools to help come up with such filter coefficients.

5. Looking forward to hearing about your progress and what you decide for that!

• Do you have a reference for that 3 dB advantage of the Hilbert transform method over down-conversion and low pass filtering? At a first glance I don't really see why that should be the case. – Matt L. Jan 21 at 9:12
• "Similar to this approach is to do the quadrature hybrid in the analog and then use two ADC's to sample directly at baseband." - Yes, I'm aware of this approach but I read that it requires additional calibrations and corrections to avoid spurious signals due to I/Q imbalance, and it's especially difficult to match the two analog signal paths if I want to build them from discrete electronic parts, which is my motivation to do it in the digital domain even it requires a faster single-channel ADC. – 比尔盖子 Jan 21 at 10:41
• Yes I am always motivated to do it in the digital domain, but all that matching you mention is also done for a most part in the digital domain. If you simply buy one of the components I mentioned it is trivial. If you signal is narrow band compared the carrier frequency where you do the 90 degree split, it is also trivial to make. I have built analog variants with decades of bandwidth but that is not so trivial. – Dan Boschen Jan 21 at 12:24
• @MattL no reference and always the chance I am mistaken. This is something I have verified on my own designs but consider this simple example of a real signal at the input to a lossless analog 90 degree splitter with a finite SNR where the noise has also been amplified above thermal prior to the split. The SNR at each output will be the same - agree? – Dan Boschen Jan 21 at 12:28
• @DanBoschen Thanks for the datasheet! This stuff is just another one of those examples of something that is seemingly simple enough to pick up and use but is difficult when it comes down to explaining the details for a general case given all of the assumptions and theoretical particularities involved...almost to the point of getting philosophical. – Envidia Jan 23 at 19:17