# 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.

Time

PSD

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] ).