## Practical noise reduction tips for biomedical ECG datasets

The Removal of 50/60Hz powerline interference from delicate information rich ECG biomedical waveforms is a challenging task! The challenge is further complicated by adjusting for the effects of EMG, such as a patient limb/torso movement or even breathing. A traditional approach adopted by many is to use a 2nd order IIR notch filter:

$$\displaystyle H(z)=\frac{1-2cosw_oz^{-1}+z^{-2}}{1-2rcosw_oz^{-1}+r^2z^{-2}}$$

where, $$w_o=\frac{2\pi f_o}{fs}$$ controls the centre frequency, $$f_o$$ of the notch, and $$r=1-\frac{\pi BW}{fs}$$ controls the bandwidth (-3dB point) of the notch.

### What’s the challenge?

As seen above, $$H(z)$$ is simple to implement, but the difficulty lies in finding an optimal value of $$r$$, as a desirable sharp notch means that the poles are close to unit circle (see right).

In the presence of stationary interference, e.g. the patient is absolutely still and effects of breathing on the sensor data are minimal this may not be a problem.

However, when considering the effects of EMG on the captured waveform (a much more realistic situation), the IIR filter’s feedback (poles) causes ringing on the filtered waveform, as illustrated below:

Contaminated ECG with non-stationary 50Hz powerline interference (IIR filtering)

As seen above, although a majority of the 50Hz powerline interference has been removed, there is still significant ringing around the main peaks (filtered output shown in red). This ringing is undesirable for many biomedical applications, as vital cardiac information such as the ST segment cannot be clearly analysed.

The frequency reponse of the IIR used to filter the above ECG data is shown below.

IIR notch filter frequency response

Analysing the plot it can be seen that the filter’s group delay (or average delay) is non-linear but almost zero in the passbands, which means no distortion. The group delay at 50Hz rises to 15 samples, which is the source of the ringing – where the closer to poles are to unit circle the greater the group delay.

ASN FilterScript offers designers the notch() function, which is a direct implemention of H(z), as shown below:

ClearH1;  // clear primary filter from cascade
ShowH2DM;   // show DM on chart

interface BW={0.1,10,.1,1};

Main()

F=50;
Hd=notch(F,BW,"symbolic");
Num = getnum(Hd); // define numerator coefficients
Den = getden(Hd); // define denominator coefficients
Gain = getgain(Hd); // define gain


## Savitzky-Golay FIR filters

A solution to the aforementioned mentioned ringing as well as noise reduction can be achieved by virtue of a Savitzky-Golay lowpass smoothing filter. These filters are FIR filters, and thus have no feedback coefficients and no ringing!

Savitzky-Golay (polynomial) smoothing filters or least-squares smoothing filters are generalizations of the FIR average filter that can better preserve the high-frequency content of the desired signal, at the expense of not removing as much noise as an FIR average. The particular formulation of Savitzky-Golay filters preserves various moment orders better than other smoothing methods, which tend to preserve peak widths and heights better than Savitzky-Golay. As such, Savitzky-Golay filters are very suitable for biomedical data, such as ECG datasets.

### Eliminating the 50Hz powerline component

Designing an 18th order Savitzky-Golay filter with a 4th order polynomial fit (see the example code below), we obtain an FIR filter with a zero distribution as shown on the right. However, as we wish to eliminate the 50Hz component completely, the tool’s P-Z editor can be used to nudge a zero pair (shown in green) to exactly 50Hz.

The resulting frequency response is shown below, where it can be seen that there is notch at exactly 50Hz, and the group delay of 9 samples (shown in purple) is constant across the frequency band.

FIR  Savitzky-Golay filter frequency response

Passing the tainted ECG dataset through our tweaked Savitzky-Golay filter, and adjusting for the group delay we obtain:

Contaminated ECG with non-stationary 50Hz powerline interference (FIR filtering)

As seen, there are no signs of ringing and the ST segments are now clearly visible for analysis. Notice also how the filter (shown in red) has reduced the measurement noise, emphasising the practicality of Savitzky-Golay filter’s for biomedical signal processing.

A Savitzky-Golay may be designed and optimised in ASN FilterScript via the savgolay() function, as follows:

ClearH1;  // clear primary filter from cascade

interface L = {2, 50,2,24};
interface P = {2, 10,1,4};

Main()

Hd=savgolay(L,P,"numeric");  // Design Savitzky-Golay lowpass
Num=getnum(Hd);
Den={1};
Gain=getgain(Hd);


## Deployment

This filter may now be deployed to variety of domains via the tool’s automatic code generator, enabling rapid deployment in Matlab, Python and embedded Arm Cortex-M devices.

## Deploying legacy analog filters to Arm Cortex-M processor cores

In recent years, major microcontroller IC vendors such as: ST, NXP, TI, ADI, Atmel/Microchip, Cypress, Maxim to name but a few have based their modern 32-bit microcontrollers on Arm’s Cortex-M processor cores. This exciting trend means that algorithms traditionally undertaken in expensive DSPs (digital signal processors) can now be integrated into a powerful low-cost and power efficient microcontroller packed full of a rich assortment of connectivity and peripheral options.

For many IC vendors, the coupling of DSP functionality with the flexibility of a low power microcontroller, has allowed them to offer their customers a generation of so called 32-bit enhanced microcontrollers suitable for a variety of practical applications. More importantly, this marriage of technologies has also allowed designers working on price critical IoT applications to implement complex algorithmic concepts, while at the same time keeping the overall product cost low and still achieving excellent low power performance.

## Upgrading legacy analog filters with the ASN Filter Designer

Analog filters have been around since the beginning of electronics, ranging from simple inductor-capacitor networks to more advanced active filters with op-amps. As such, there is a rich collection of tried and tested legacy filter designs for a broad range of sensor measurement applications.

ASN’s FilterScript symbolic math scripting language offers designers the ability to take an existing analog filter transfer function and transform it to digital with just a few lines of code. The ASN Filter Designer’s Arm automatic code generator analyses the designed digital filter and then automatically generates Arm CMSIS-DSP compliant C code suitable for direct implementation a Cortex-M based microcontroller.

### Arm CMSIS-DSP software framework

The Arm CMSIS-DSP (Cortex Microcontroller Software Interface Standard)  software framework is a rich collection of over sixty DSP functions (including various mathematical functions, such as sine and cosine; IIR/FIR filtering functions, complex math functions, and data types) developed by Arm that have been optimised for their range of Cortex-M processor cores. The framework makes extensive use of highly optimised SIMD (single instruction, multiple data) instructions, that perform multiple identical operations in a single cycle instruction. The SIMD instructions (if supported by the core) coupled together with other optimisations allow engineers to produce highly optimised signal processing applications for Cortex-M based micro-controllers quickly and simply.

## Mathematically modelling an analog circuit

Consider the active pre-emphasis filter shown below. The pre-emphasis filter has found particular use in audio work, since it is necessary to amplify the higher frequencies of the speech spectrum, whilst leaving the lower frequencies unaffected. The R and C values shown are only indented for the example, more practical values will depend on the application.A powerful method of reproducing the magnitude and phases characteristics of the analog filter in a digital implementation, is to mathematically model the circuit. This circuit may be analysed using Kirchhoff’s law, since the sum of currents into the op-amp’s inverting input must be equal to zero for negative feedback to work correctly – this results in a transfer function with a negative gain.

Therefore, using Ohm’s law, i.e. $$I=\frac{V}{R}$$,

$$\displaystyle\frac{X(s)}{R_3}=-\frac{U(s)}{C_1||R_2 + R_1}$$

After some algebraic manipulation, it can be seen that an expression for the circuit’s closed loop gain may be expressed as,

$$\displaystyle\frac{X(s)}{U(s)}=-\frac{R_3}{R_1}\frac{\left(s+\frac{1}{R_2C_1}\right)}{\left(s+\frac{R_1+R_2}{R_1R_2C_1}\right)}$$

substituting the values shown in the circuit diagram into the developed transfer function, yields

$$\displaystyle H(s)=-10\left(\frac{s+1000}{s+11000}\right)$$

### What sampling rate do we need?

Analysing the cut-off frequencies in $$H(s)$$, we see that the upper frequency is at $$11000 rad/sec$$ or $$1.75kHz$$. Therefore, setting the sampling rate to $$16kHz$$ should be adequate for modelling the filter in the digital domain.

The sampling rate options are avaliabe in the main filter design UI  (shown on the left).

### ASN FilterScript

$$H(s)$$ can be easily specified in FilterScript with the analogtf function, as follows:

Nb={1,1000};
Na={1,11000};

Ha=analogtf(Nb,Na,-10,"symbolic");


Notice how the negative gain may also be entered directly into function’s argument. The symbolic keyword generates a symbolic transfer function representation in the command window.

Applying the Bilinear z-transformation via the bilinear command with no pre-warping, i.e.

Hd=bilinear(Ha,0,"symbolic");

Notice how the bilinear command automatically scales numerator coefficients by -1, in order to account for the effect of the negative gain. The complete code is shown below:

Main()

Nb={1,1000};
Na={1,11000};

Ha=analogtf(Nb,Na,-10,"symbolic");
Hd=bilinear(Ha,0,"symbolic");

Num=getnum(Hd);
Den=getden(Hd);
Gain=getgain(Hd);


A comparison of the analog and discrete magnitude and phase spectra is shown below. Analysing the spectra, it can be seen that for a sampling rate of 16kHz the analog and digital filters are almost identical! This demonstrates the relative ease with which a designer can port their existing legacy analog designs into digital.

## Automatic code generation to Arm Cortex-M processors

As mentioned at the beginning of this article, the ASN filter designer’s automatic code generation engine facilitates the export of a designed filter to Cortex-M Arm based processor cores via the CMSIS-DSP software framework. The tool’s built-in analytics and help functions assist the designer in successfully configuring the design for deployment.

Before generating the code, the H2 filter (i.e. the filter designed in FilterScript) needs to be firstly re-optimised (transformed) to an H1 filter (main filter) structure for deployment. The options menu can be found under the P-Z tab in the main UI.

All floating point IIR filters designs must be based on Single Precision arithmetic and either a Direct Form I or Direct Form II Transposed filter structure. The Direct Form II Transposed structure is advocated for floating point implementation by virtue of its higher numerically accuracy.

Quantisation and filter structure settings can be found under the Q tab (as shown on the left). Setting Arithmetic to Single Precision and Structure to Direct Form II Transposed and clicking on the Apply button configures the IIR considered herein for the CMSIS-DSP software framework.

### Arm CMSIS-DSP application C code

Select the Arm CMSIS-DSP framework from the selection box in the filter summary window:

The automatically generated C code based on the CMSIS-DSP framework for direct implementation on an Arm based Cortex-M processor is shown below:

As seen, the automatic code generator generates all initialisation code, scaling and data structures needed to implement the IIR via the CMSIS-DSP library. This code may be directly used in any Cortex-M based development project – a complete Keil MDK example is available on Arm/Keil’s website. Notice that the tool’s code generator produces code for the Cortex-M4 core as default, please refer to the table below for the #define definition required for all supported cores.

 ARM_MATH_CM0 Cortex-M0 core. ARM_MATH_CM4 Cortex-M4 core. ARM_MATH_CM0PLUS Cortex-M0+ core. ARM_MATH_CM7 Cortex-M7 core. ARM_MATH_CM3 Cortex-M3 core. ARM_MATH_ARMV8MBL ARMv8M Baseline target (Cortex-M23 core). ARM_MATH_ARMV8MML ARMv8M Mainline target (Cortex-M33 core).

The main test loop code (not shown) centres around the arm_biquad_cascade_df2T_f32() function, which performs the filtering operation on a block of input data.

## What have we learned?

The ASN Filter Designer provides engineers with everything they need in order to port legacy analog filter designs to a variety of Cortex-M processor cores.

The FilterScript symbolic math scripting language offers designers the ability to take an existing analog filter transfer function and transform it to digital (via the Bilinear z-transform or matched z-transform) with just a few lines of code.

The Arm automatic code generator analyses the designed digital filter and then automatically generates Arm CMSIS-DSP compliant C code suitable for direct implementation on a Cortex-M based microcontroller.

### Extra resources

1. Step by step video tutorial of designing an IIR and deploying it to Keil MDK uVision.
2. Implementing Biquad IIR filters with the ASN Filter Designer and the Arm CMSIS-DSP software framework (ASN-AN025)
3. Keil MDK uVision example IIR filter project
4. Step by step instruction video of this tutorial Arm Webinar (requires registration)

## Upgrading legacy designs based on analog filters

Analog filters have been around since the beginning of electronics, ranging from simple inductor-capacitor networks to more advanced active filters with op-amps. As such, there is a rich collection of tried and tested legacy filter designs for a broad range of sensor measurement applications. However, with the performance requirements of modern IoT (Internet of Things) sensor measurement applications and lower product costs, digital filters integrated into the microcontroller’s application code are becoming the norm, but how can we get the best of both worlds?

Rather than re-inventing the wheel, product designers can take an existing analog filter transfer function, transform it to digital (via a transform) and implement it as digital filter in a microcontroller or DSP (digital signal processor). Although  analog-to-digital transforms have been around for decades, the availability of DSP design tooling for tweaking the ‘transformed digital filter’ has been somewhat limited, hindering the design and validation process.

A 2nd order analog lowpass filter is shown below, and in its simplest form, only 5 components are required to build the filter, which sounds easy. Right?

The pros

The most obvious advantage is that analog filters have an excellent resolution, as there are no ‘number of bits’ to consider. Analog filters have good EMC (electromagnetic compatibility) properties as there is no clock generating noise. There are no effects of aliasing, which is certainly true for the simpler op-amps, which don’t have any fancy chopping or auto-calibration circuitry built into them, and analog designs can be cheap which is great for cost sensitive applications.

### Sound great, but what’s the bad news?

Analog filters have several significant disadvantages that affect filter performance, such as component aging, temperature drift and component tolerance. Also, good performance requires good analog design skills and good PCB (printed circuit board) layout, which is hard to find in the contemporary skills market.

These disadvantages make digital filters much more attractive for modern applications, that require high repeatability of characteristics.  Looking at an example, let’s say that you want to manufacture 1000 measurement modules after optimising your filter design. With a digital solution you can be sure that the performance of your filter will be identical in all modules. This is certainly not the case with analog, as component tolerance, component aging and temperature drift mean that each module’s filter will have its own characteristics. Also, an analog filter’s frequency response remains fixed, i.e. a Butterworth filter will always be a Butterworth filter – any changes the frequency response would require physically changing components on the PCB – not ideal!

Digital filters are adaptive and flexible, we can design and implement a filter with any frequency response that we want, deploy it and then update the filter coefficients without changing anything on the PCB! It’s also easy to design digital filters with linear phase and at very low sampling frequencies – two things that are tricky with analog.

## Laplace to discrete/digital transforms

The three methods discussed herein essentially involve transforming a Laplace (analog) transfer function, $$H(s)$$ into a discrete transfer function, $$H(z)$$ such that an tried and tested analog filter that is already used in a design may be implemented on a microcontroller or DSP.

A selection of some useful Laplace to z-transforms are given in table below:

$$\begin{array}{ccc}\hline H(s) &\longleftrightarrow & H(z) \\ \hline 1 &\longleftrightarrow & 1 \\ \frac{\displaystyle1}{\displaystyle s} &\longleftrightarrow& \frac{\displaystyle 1}{\displaystyle 1-z^{\scriptstyle -1}}\\ \frac{\displaystyle 1}{\displaystyle s^{\scriptstyle 2}} &\longleftrightarrow& \frac{\displaystyle Tz^{\scriptstyle-1}}{\displaystyle (1-z^{\scriptstyle -1})^2}\\ \frac{\displaystyle 1}{\displaystyle s+a} &\longleftrightarrow& \frac{\displaystyle 1}{\displaystyle 1-e^{-aT}z^{-1}}\\ \frac{\displaystyle 1}{\displaystyle (s+a)^2} &\longleftrightarrow& \frac{\displaystyle z^{-1}(1-e^{-aT})}{\displaystyle a(1-z^{-1})(1-e^{-aT}z^{-1})}\\\hline \end{array}$$
A table of useful Laplace and z-transforms

### The Bilinear z-transform (BZT)

The Bilinear z-transform (BZT), simply converts an analog transfer function, $$H(s)$$ into a discrete transfer function, $$H(z)$$ by replacing all $$s$$ terms with the following:

$$\displaystyle s=\frac{2}{T}\frac{1-z^{-1}}{1+z^{-1}} \label{bzt}$$

where, $$T$$ is the discrete system’s sampling period. However, substituting $$s=j\Omega$$ and $$z=e^{jwT}$$ into the BZT equation and simplifying, notice that there is actually a non-linear relationship between the analog, $$\Omega$$ and discrete, $$w$$ frequencies. This relationship is shown below, and is due to the nonlinearity of the arctangent function.

$$\displaystyle \omega=2\tan^{-1}\left(\frac{\Omega T}{2}\right) \label{bzt_warp_def1}$$

Analysing the equation, it can be seen that the equally spaced  analog frequencies in the range $$-\infty<\Omega<\infty$$ are nonlinearly compressed in the frequency range $$-\pi<w<\pi$$ in the discrete domain. This relationship is referred to as frequency warping, and may be compensated for by pre-warping the analog frequencies by:

$$\displaystyle \Omega_c=\frac{2}{T}\tan\left(\frac{\Omega_d T}{2}\right) \label{bzt_warp_def2}$$

where, $$\displaystyle\Omega_c$$ is the compensated or pre-warped analog frequency, and $$\displaystyle\Omega_d$$ is the desired analog frequency.

The ASN FilterScript command $$\texttt{bilinear}$$ may be used convert a Laplace transfer function into its discrete equivalent using the BZT transform. An example is given below.

### The Impulse Invariant Transform

The second transform, is referred to as the impulse invariant transform (IIT), since the poles of the Laplace transfer function are converted into their discrete equivalents, such that the discrete impulse response, $$h(n)$$ is identical to a regularly sampled representation of the analog impulse response (i.e., $$h(n)=h(nT)$$, where $$T$$ is the sampling rate, and $$t=nT$$). The IIT is a much more tedious transformation technique than the BZT, since the Laplace transfer function must be firstly expanded using partial fractions before applying the transform.

The transformation technique is defined below:

$$\displaystyle \frac{K}{s+a} \quad\longrightarrow\quad \frac{K}{1-e^{-aT}z^{-1}} \label{iit_def}$$

This method suffers from several constraints, since it does not allow for the transformation of zeros or individual constant terms (once expanded), and must have a high sampling rate in order to overcome the effects of spectral aliasing. Indeed, the effects of aliasing hinder this method considerably, such that the method should only be used when the requirement is to match the analog transfer function’s impulse response, since the resulting discrete model may have a different magnitude and phase spectrum (frequency response) to that of the original analog system. Consequently, the impulse invariant method is unsuitable for modelling highpass filters, and is therefore limited to the modelling of lowpass or bandpass type filters.

Due to the aforementioned limitations of the IIT method, it is currently not supported in ASN Filterscript.

### The Matched-z transformation

Another analog to discrete modelling technique is the matched-z transformation. As the name suggests, the transform converts the poles and zeros from the analog transfer function directly into poles and zeros in the z-plane. The transformation is described below, where $$T$$ is the sampling rate.

$$\displaystyle \frac{\prod\limits_{k=1}^q(s+b_k)}{\prod\limits_{k=1}^p(s+a_k)} \quad\longrightarrow\quad \frac{\prod\limits_{k=1}^q(1-e^{-b_kT}z^{-1})}{\prod\limits_{k=1}^p(1-e^{-a_kT}z^{-1})} \label{matchedz_def}$$

Analysing the transform equation, it can be seen that the transformed z-plane poles will be identical to the poles obtained with the impulse invariant method. However, notice that the positions of the zeros will be different, since the impulse invariant method cannot transform them.

The ASN Filterscript command $$\texttt{mztrans}$$ is available for this method.

## A detailed example

In order to demonstrate the ease of transforming analog filters into their discrete/digital equivalents using the analog to discrete transforms, an example of modelling with the BZT will now follow for a 2nd order lowpass analog filter.

A generalised 2nd order lowpass analog filter is given by:

$$\displaystyle H(s)=\frac{w_c^2}{s^2+2\zeta w_c s + w_c^2}$$

where, $$w_c=2\pi f_c$$ is the cut-off frequency and $$\zeta$$ sets the damping of the filter,  where a  $$\zeta=1/\sqrt{2}$$ is said to be critically damped or equal to -3dB at $$w_c$$. Many analog engineers choose to specify a quality factor, $$Q = \displaystyle\frac{1}{2\zeta}$$ or peaking factor for their designs. Substituting $$Q$$ into $$H(s)$$, we obtain:

$$\displaystyle H(s)=\frac{w_c^2}{s^2+ \displaystyle{\frac{w_c}{Q}s} + w_c^2}$$

Analysing, $$H(s)$$ notice that $$Q=1/\sqrt{2} = 0.707$$ also results in a critically damped response. Various values of $$Q$$ are shown below, and as seen when $$Q>1/\sqrt{2}$$ peaking occurs.

2nd order lowpass filter prototype magnitude spectrum for various value of Q:
notice that when $$Q>1/\sqrt{2}$$ peaking occurs.

Before applying the BZT in ASN FilterScript, the analog transfer function must be specified in an analog filter object. The following code sets up an analog filter object for the 2nd order lowpass prototype considered herein:

Main()

wc=2*pi*fc;
Nb={0,0,wc^2};
Na={1,wc/Q,wc^2};

Ha=analogtf(Nb,Na,1,"symbolic"); // make analog filter object


The $$\texttt{symbolic}$$ keyword generates a symbolic transfer function representation in the command window. For a sampling rate of $$f_s=500Hz$$ and $$f_c=30Hz$$ and $$Q=0.707$$, we obtain:

Applying the BZT via the $$\texttt{bilinear}$$ command,

 Hd=bilinear(Ha,"symbolic");

The complete frequency response of the transformed digital filter is shown below, where it can be seen that the at $$30Hz$$ the magnitude is $$-3dB$$ and the phase is $$-90^{\circ}$$, which is as expected. Notice also how the filter’s magnitude roll-off  is affected by the double zero pair at Nyquist (see the z-plane chart below), leading to differences from its analog cousin.

The pole-zero positions may be tweaked within ASN Filterscript or via the ASN Filter Designer’s interactive pole-zero z-plane plot editor by just using the mouse!

## Implementation

The complete code for transforming a generalised 2nd order analog  lowpass filter prototype into its digital equivalent using the BZT via ASN FilterScript is given below:


ClearH1;  // clear primary filter from cascade
interface Q = {0.1,10,0.02,0.707};
interface fc = {10,200,10,40};

Main()

wc=2*pi*fc;
Nb={0,0,wc^2};
Na={1,wc/Q,wc^2};

Ha=analogtf(Nb,Na,1,"symbolic"); // make analog filter object
Hd=bilinear(Ha,"symbolic"); // transform Ha via BZT into digital object, Hd

Num=getnum(Hd);
Den=getden(Hd);
Gain=getgain(Hd);



## All-pass filters

All-pass filters provide a simple way of altering/improving the phase response of an IIR without affecting its magnitude response. As such, they are commonly referred to as phase equalisers and have found particular use in digital audio applications.

In its simplest form, an All-pass  filter can be constructed from a first order transfer function, i.e.,

$$A(z)=\Large{\frac{r+z^{-1}}{1+r z^{-1}}} \, \, \normalsize{; r<1}$$

Analysing $$A(z)$$, notice that the pole and zero lie on the real z-plane axis and that the pole at radius $$r$$ has a zero at radius $$1/r$$, such that the poles and zeros are reciprocals of another. This property is key to the all-pass filter concept, as we will now see by expanding the concept further to a second order all-pass filter:

$$A(z)=\Large\frac{r^2-2rcos \left( \frac{2\pi f_c}{fs}\right) z^{-1}+z^{-2}}{1-2rcos \left( \frac{2\pi f_c}{fs}\right)z^{-1}+r^2 z^{-2}}$$

Where, $$f_c$$ is the centre frequency, $$r$$ is radius of the poles and $$f_s$$ is the sampling frequency. Notice how the numerator and denominator coefficients are arranged as a mirror image pair of one another.  The mirror image property is what gives the all-pass filter its desirable property, namely allowing the designer to alter the phase response while keeping the magnitude response constant or flat over the complete frequency spectrum.

Frequency response of all-pass filter:
Notice the constant magnitude spectrum (shown in blue).

## Implementation

An All-pass filter may be implemented in ASN FilterScript as follows:

ClearH1;  // clear primary filter from cascade

interface fc = {0,fs/2,1,fs/10};     // frequency value

Main()
Den = reverse(Num); // mirror image of Num
Gain = 1;



## All-pass Peaking/Bell filter

A  Peaking or Bell filter is a type of audio equalisation filter that boosts or attenuates the magnitude of a specified set of frequencies around a centre frequency in order to perform magnitude equalisation. As seen in the plot in the below, the filter gets its name from the shape of the its magnitude spectrum (blue line) which resembles a Bell curve.

Frequency response (magnitude shown in blue, phase shown in purple) of a 2nd order Bell filter peaking at 125Hz.

## All-pass filters

Central to the Bell filter is the so called All-pass filter. All-pass filters provide a simple way of altering/improving the phase response of an IIR without affecting its magnitude response. As such, they are commonly referred to as phase equalisers and have found particular use in digital audio applications.

A second order all-pass filter is defined as:

$$A(z)=\Large\frac{r^2-2rcos \left( \frac{2\pi f_c}{fs}\right) z^{-1}+z^{-2}}{1-2rcos \left( \frac{2\pi f_c}{fs}\right)z^{-1}+r^2 z^{-2}}$$

Notice how the numerator and denominator coefficients are arranged as a mirror image pair of one another.  The mirror image property is what gives the all-pass filter its desirable property, namely allowing the designer to alter the phase response while keeping the magnitude response constant or flat over the complete frequency spectrum.

A Bell filter can be constructed from the $$A(z)$$ filter by the following transfer function:

$$H(z)=\Large\frac{(1+K)+A(z)(1-K)}{2}$$

After some algebraic simplication, we obtain the transfer function for the Peaking or Bell filter as:

$$H(z)=\Large{\frac{1}{2}}\left[\normalsize{(1+K)} + \underbrace{\Large\frac{k_2 + k_1(1+k_2)z^{-1}+z^{-2}}{1+k_1(1+k_2)z^{-1}+k_2 z^{-2}}}_{all-pass filter}\normalsize{(1-K)} \right]$$

• $$K$$ is used to set the gain and sign of the peak
• $$k_1$$ sets the peak centre frequency
• $$k_2$$ sets the bandwidth of the peak

## Implementation

A Bell filter may easily be implemented in ASN FilterScript as follows:

ClearH1;  // clear primary filter from cascade
interface BW = {0,2,0.1,0.5}; // filter bandwidth
interface fc = {0, fs/2,fs/100,fs/4}; // peak/notch centre frequency
interface K = {0,3,0.1,0.5}; // gain/sign

Main()

k1=-cos(2*pi*fc/fs);
k2=(1-tan(BW/2))/(1+tan(BW/2));

Pz = {1,k1*(1+k2),k2}; // define denominator coefficients
Qz = {k2,k1*(1+k2),1}; // define numerator coefficients
Num = (Pz*(1+K) + Qz*(1-K))/2;
Den = Pz;
Gain = 1;


This code may now be used to design a suitable Bell filter, where the exact values of $$K, f_c$$ and $$BW$$ may be easily found by tweaking the interface variables and seeing the results in real-time, as described below.

## Designing the filter on the fly

Central to the interactivity of the FilterScript IDE (integrated development environment) are the so called interface variables. An interface variable is simply stated: a scalar input variable that can be used modify a symbolic expression without having to re-compile the code – allowing designers to design on the fly and quickly reach an optimal solution.

As seen in the code example above, interface variables must be defined in the initialisation section of the code, and may contain constants (such as, fs and pi) and simple mathematical operators, such as multiply * and / divide. Where, adding functions to an interface variable is not supported.

An interface variable is defined as vector expression:

interface name = {minimum, maximum, step_size, default_value};

Where, all entries must be real scalars values. Vectors and complex values will not compile.

All interface variables are modified via the interface variable controller GUI. After compiling the code, use the interface variable controller to tweak the interface variables values and see the effects on the transfer function. If testing on live audio, you may stream a loaded audio file and adjust the interface variables in real-time in order to hear the effects of the new settings.

## FIR Comb Filter

Comb filters have found use as powerline (50/60Hz) harmonic cancellation filters in audio applications, and form the basis of so called CIC (cascaded integrator–comb) filters used for anti-aliasing in decimation (sample rate reduction), and anti-imaging in interpolation (sample rate increase) applications.

The frequency response of a comb filter consists of a series of regularly-spaced troughs, giving the appearance of a comb. As seen in the plot below, the spacing of each trough appears at either odd or even harmonics of the desired fundamental frequency.

Frequency response of a typical FIR comb filter (odd harmonics cancellation):
$$f_s=500Hz$$,  $$f_c=25Hz$$, $$L=10$$ and $$\alpha=1$$

An FIR comb filter can be described by the following transfer function:

$$H(z)=1+\alpha z^{-L}$$
$$\Rightarrow Y(z)=X(z)\left[1+\alpha z^{-L}\right]$$

Clearly, the comb filter is simply a weighted delayed replica of itself, specifiied by $$L$$. Taking inverse z-transforms, we obtain the difference equation needed for implementation,

$$y(n)=x(n)+\alpha x(n-L)$$

where, $$\alpha$$ is used to set the Q (bandwidth) of the notch and may be either positive or negative depending on what type of frequency response is required. In order to elaborate on this, negative values of $$\alpha$$ have their first trough at DC and their second trough at the fundamental frequency. Clearly this type of comb filter can be used to remove any DC components from a measured waveform if so required. All subsequent troughs appear at even harmonics up to and including the Nyquist frequency.

Positive values of $$\alpha$$ on the other hand, only have troughs at the fundamental and odd harmonic frequencies, and as such cannot be used to remove any DC components.

## Application to powerline interference cancellation

The affectivity of the comb filter is dependent on the sampling frequency, $$f_s$$, as $$L$$ is limited to integer values only. Also, a relationship between $$f_s$$, as $$L$$ and will be dependent on the sign of $$\alpha$$. Thus, for the purposes of the mains cancellation application considered in this discussion, only positive values of will be considered, as we need only cancel odd harmonics.

A simple relationship for determining  $$L$$ can be summarized for positive values of $$\alpha$$ as follows:

$$L=ceil\left( \large{\frac{f_s}{2f_c}}\right)$$

where, $$f_c$$ is the desired centre point of the fundamental notch frequency. Based on this expression, we can re-calculate the sampling frequency, such that $$f_c$$ is a true multiple of $$f_s$$

$$f_{snew}=2f_c L$$

## Example

For the example considered herein, i.e. $$f_s=500Hz$$ and $$f_c=25Hz$$, we obtain $$L=10$$. However, if $$f_c=60Hz$$, we would need $$L=5$$, and a new sampling rate of $$600Hz$$ respectively, although it’s interesting to note that $$f_s=480Hz$$ for $$L=4$$ would also suffice.

## Implementation

An FIR comb filter may be implemented in ASN FilterScript as follows:

ClearH1;  // clear primary filter from cascade
interface L = {4,20,1,5}; // delay
interface alpha = {-1,1,0.01,1};

Main()
Num = {1,zeros(L-1),alpha}; // numerator coefficients
Den = {1};
Gain = 1/sum(abs(Num));


## Fractional Farrow Delay Filter

In signal processing, the need sometimes arises to nudge or fine-tune the sampling instants of a signal by a fraction of a sample. An FIR Farrow delay filter is typically employed to achieve this task, and may be combined with a traditional integer delay line in order to achieve a universal fractional length delay line.

A Fractional delay based on an FIR Farrow structure may be defined as:

$$H(z)=(1-\alpha)+\alpha z^{-1}; \; 0 \leq \alpha \leq 1$$

Which produces a fractional linear delay of $$\alpha$$ between 0 and 1 samples. However, a more universal building block can be achieved by combining the Farrow delay structure with an integer delay, $$\Delta$$

$$H(z)=(1-\alpha) z^{-\Delta}+\alpha z^{-(\Delta+1)}$$

The plot shown below shows the magnitude (blue) and phase (purple) spectra for $$\Delta=9, \, \alpha=0.52$$. As seen, the fractional delay element results in a non-flat magnitude spectrum at higher frequencies.

Frequency reponse of Farrow delay filter.

## Implementation

A Farrow delay filter may be implemented in ASN FilterScript as follows:

ClearH1;  // clear primary filter from cascade

interface alpha = {0,1,0.02,.5}; // fractional delay
interface D = {1,30,1,10};       // integer delay

Main()
Num = {zeros(D),1-alpha,alpha}; // numerator coefficients
Den = {1};                      // denominator coefficient
Gain = 1/sum(Num);              // normalise gain at DC


## The moving average filter

The moving average (MA) filter is perhaps one of the most widely used FIR filters due to its conceptual simplicity and ease of implementation. As seen in the diagram below, notice that the filter doesn’t require any multiplications, just additions and a delay line, making it very suitable for many extreme low-power embedded devices with basic computational capabilities.

However, despite its simplicity, the moving average filter is optimal for reducing random noise while retaining a sharp step response, making it a versatile building block for smart sensor signal processing applications.

A moving average filter of length $$L$$ for an input signal $$x(n)$$ may be defined as follows:

$$y(n)=\large{\frac{1}{L}}\normalsize{\sum\limits_{k=0}^{L-1}x(n-k)}$$ for $$\normalsize{n=0,1,2,3….}$$

Where, a simple rule of thumb states that the amount of noise reduction is equal to the square-root of the number of points in the average. For example, an MA of length 9 will result in a factor 3 noise reduction.

Frequency response of an MA filter of length 9. Notice the poor stopband attentuation at around -20dB.

• Most commonly used digital lowpass filter.
• Optimal for reducing random noise while retaining a sharp step response.
• Good smoother (time domain).
• Unity valued filter coefficients, no MAC (multiply and accumulate) operations required.
• Conceptually simple to implement.

• Inflexible frequency response: nudging a conjugate zero pair results in non-unity coefficients.
• Poor lowpass filter (frequency domain): slow roll-off and terrible stopband attenuation characteristics.

## Implementation

The MA filter may be implemented in ASN FilterScript as follows:

ClearH1;  // clear primary filter from cascade

Main()
Hd=movaver(8,"symbolic");  // design a MA of length 8
Num = getnum(Hd);   // define numerator coefficients
Den = {1};          // define denominator coefficients
Gain = getgain(Hd); // define gain