# Finite Impulse Response Hilbert Transform (firhilb)

The firhilbf object in liquid implements a finite impulse response Hilbert transform which converts between real and complex time series. The interpolator takes a complex time series and produces real-valued samples at twice the sample rate. The decimator reverses the process by halving the sample rate of a real-valued time series to a complex-valued one.

Typical trade-offs between filter length, side-lobe suppression, and transition bandwidth apply. The firhilbf object uses a half-band filter to implement the transform as efficiently as possible. While any filter length can be accepted, the firhilbf object internally forces the length to be of the form \(n=4m+1\) to reduce the computational load. A half-band filter of this length has \(2m\) zeros and \(2m+1\) non-zero coefficients. Of these non-zero coefficients, the center is exactly \(1\) while the other \(2m\) are even symmetric, and therefore only \(m\) computations are needed.

**Figure [fig-filter-firhilb]**.
firhilbf
(Hilbert transform) decimator demonstration.
The small signal at
\(f=0.13\)
is due to aliasing as a result of
imperfect image rejection.

A graphical example of the Hilbert decimator can be seen in [fig-filter-firhilb] where a real-valued input sinusoid is converted into a complex sinusoid with half the number of samples. An example code listing is given below. Although firhilbf is a placeholder for both decimation (real to complex) and interpolation (complex to real), separate objects should be used for each task.

```
#include <liquid/liquid.h>
int main() {
unsigned int m=5; // filter semi-length
float slsl=60.0f; // filter sidelobe suppression level
// create Hilbert transform objects
firhilbf q0 = firhilbf_create(m,slsl);
firhilbf q1 = firhilbf_create(m,slsl);
float complex x; // interpolator input
float y[2]; // interpolator output
float complex z; // decimator output
// ...
// execute transforms
firhilbf_interp_execute(q0, x, y); // interpolator
firhilbf_decim_execute(q1, y, &z); // decimator
// clean up allocated memory
firhilbf_destroy(q0);
firhilbf_destroy(q1);
}
```

Listed below is the full interface to the firhilbf family of objects.

- firhilbf_create(m,As) creates a firhilbf object with a filter semi-length of \(m\) samples (equal to the delay) and a stop-band attenuation of \(A_s\) dB. The value of \(m\) must be at least 2. The internal filter has a length \(4m+1\) coefficients and is designed using the firdes_kaiser_window() method (see [section-filter-firdes-window] on FIR filter design using windowing functions).
- firhilbf_destroy(q) destroys the Hilbert transform object, freeing all internally-allocated memory.
- firhilbf_print(q) prints the internal properties of the object to the standard output.
- firhilbf_clear(q) clears the internal transform buffers.
- firhilbf_r2c_execute(q,x,*y) executes the real-to-complex transform as a half-band filter, rejecting the negative frequency band. The input \(x\) is a real sample; the output \(y\) is complex.
- firhilbf_c2r_execute(q,x,*y) executes the complex-to-real conversion as \(y = \Re\{x\}\) .
- firhilbf_decim_execute(q,*x,*y) executes the transform as a decimator, converting a 2-sample input array \(\vec{x}\) of real values into a single complex output value \(y\) .
- firhilbf_interp_execute(q,x,*y) executes the transform as a decimator, converting a single complex input sample \(x\) into a two real-valued samples stored in the output array \(\vec{y}\) .

For more detailed examples on Hilbert transforms in liquid,
refer to the files
examples/firhilb_decim_example.c
and
examples/firhilb_interp_example.c
located within the main liquid project directory.
*See also:*
resamp2
(
[section-filter-resamp2]
),
FIR filter design (
[section-filter-firdes]
).