A-weighting equalisation: Designing and deploying to Arm Cortex-M devices

Modern embedded processors, software frameworks and design tooling now allow engineers to apply advanced measurement concepts to smart factories as part of the I4.0 revolution.

In recent years, PM (predictive maintenance) of machines has received great attention, as factories look to maximise their production efficiency while at the same time retaining the invaluable skills of experienced foremen and production workers.

Traditionally, a foreman would walk around the shop floor and listen to the sounds a machine would make to get an idea of impending failure. With the advent of I4.0 technology, microphones, edge DSP algorithms and ML may now be employed in order to ‘listen’ to the sounds a machine makes and then make a classification and prediction.

One of the major challenges is how to make a computer hear like a human.

Physics of the human ear

An illustration of the human ear shown on the right. As seen, the basic task of the ear is to translate sound (air vibration) into electrical nerve impulses for the brain to interpret.

How does it work?

The ear achieves this via three bones (Stapes, Incus and Malleus) that act as a mechanical amplifier for vibrations received at the eardrum. These amplified sounds are then passed onto the Cochlea via the Oval window (not shown). The Cochlea (shown in purple) is filled with a fluid that moves in response to the vibrations from the oval window. As the fluid moves, thousands of nerve endings are set into motion. These nerve endings transform sound vibrations into electrical impulses that travel along the auditory nerve fibres to the brain for analysis.

Modelling perceived sound

Due to complexity of the fluidic mechanical construction of the human auditory system, low and high frequencies are typically not discernible. Researchers over the years have found that humans are most perceptive to sounds in the 1-6kHz range, although this range varies according to the subject’s physical health.

This research led to the definition of a set of weighting curves: the so-called A, B, C and D weighting curves, which equalises a microphone’s frequency response. These weighting curves aim to bring the digital and physical worlds closer together by allowing a computerised microphone-based system to hear like a human.

The A-weighing curve is the most widely used as it is mandated by IEC-61672 to be fitted to all sound level meters. The B and D curves are hardly ever used, but C-weighting may be used for testing the impact of noise in telecoms systems.

The frequency response of the A-weighting curve is shown above, where it can be seen that sounds entering our ears are de-emphasised below 500Hz and are most perceptible between 0.5-6kHz. Notice that the curve is unspecified above 20kHz, as this exceeds the human hearing range.

ASN FilterScript

ASN’s FilterScript symbolic math scripting language offers designers the ability to take an analog filter transfer function and transform it to its digital equivalent with just a few lines of code.

The analog transfer functions of the A and C-weighting curves are given below:

$$H_A(s) \approx \displaystyle{7.39705×10^9 \cdot s^4 \over (s + 129.4)^2\quad(s + 676.7)\quad (s + 4636)\quad (s + 76655)^2}$$

$$H_C(s) \approx \displaystyle{5.91797×10^9 \cdot s^2\over(s + 129.4)^2\quad (s + 76655)^2}$$

These analog transfer functions may be transformed into their digital equivalents via the bilinear() function. However, notice that $$H_A(s)$$ requires a significant amount of algebracic manipulation in order to extract the denominator cofficients in powers of $$s$$.

Convolution

A simple trick to perform polynomial multiplication is to use linear convolution, which is the same algebraic operation as multiplying two polynomials together. This may be easily performed via Filterscript’s conv() function, as follows:

y=conv(a,b);


As a simple example, the multiplication of $$(s^2+2s+10)$$ with $$(s+5)$$, would be defined as the following three lines of FilterScript code:

a={1,2,10};
b={1,5};
y=conv(a,b);


which yields, 1 7 20 50  or $$(s^3+7s^2+20s+50)$$

For the A-weighting curve Laplace transfer function, the complete FilterScript code is given below:

ClearH1;  // clear primary filter from cascade

Main() // main loop

a={1, 129.4};
b={1, 676.7};
c={1, 4636};
d={1, 76655};

aa=conv(a,a); // polynomial multiplication
dd=conv(d,d);

aab=conv(aa,b);
aabc=conv(aab,c);

Na=conv(aabc,dd);
Nb = {0 ,0 , 1 ,0 ,0 , 0, 0}; // define numerator coefficients
G = 7.397e+09; // define gain

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

Num = getnum(Hd);
Den = getden(Hd);
Gain = getgain(Hd)/computegain(Hd,1e3); // set gain to 0dB@1kHz



Frequency response of analog vs digital A-weighting filter for $$f_s=48kHz$$. As seen, the digital equivalent magnitude response matches the ideal analog magnitude response very closely until $$6kHz$$.

The ITU-R 486–4 weighting curve

Another weighting curve of interest is the ITU-R 486–4 weighting curve, developed by the BBC. Unlike the A-weighting filter, the ITU-R 468–4 curve describes subjective loudness for broadband stimuli. The main disadvantage of the A-weighting curve is that it underestimates the loudness judgement of real-world stimuli particularly in the frequency band from about 1–9 kHz.

Due to the precise definition of the 486–4 weighting curve, there is no analog transfer function available. Instead the standard provides a table of amplitudes and frequencies – see here. This specification may be directly entered into Filterscript’s firarb() function for designing a suitable FIR filter, as shown below:

ClearH1;  // clear primary filter from cascade
ShowH2DM;

interface L = {10,400,10,250}; // filter order

Main()

// ITU-R 468 Weighting
A={-29.9,-23.9,-19.8,-13.8,-7.8,-1.9,0,5.6,9,10.5,11.7,12.2,12,11.4,10.1,8.1,0,-5.3,-11.7,-22.2};
F={63,100,200,400,800,1e3,2e3,3.15e3,4e3,5e3,6.3e3,7.1e3,8e3,9e3,1e4,1.25e4,1.4e4,1.6e4,2e4};

A={-30,A};  //  specify arb response
F={0,F,fs/2};   //

Hd=firarb(L,A,F,"blackman","numeric");

Num=getnum(Hd);
Den={1};
Gain=getgain(Hd);



Frequency response of an ITU-R 468-4 FIR filter designed with Filterscript’s firarb() function  for $$f_s=48kHz$$

As seen, FilterScript provides the designer with a very powerful symbolic scripting language for designing weighting curve filters. The following discussion now focuses on deployment of the A-weighting filter to an Arm based processor via the tool’s automatic code generator. The concepts and steps demonstrated below are equally valid for FIR filters.

Automatic code generation to Arm processor cores via CMSIS-DSP

The ASN Filter Designer’s automatic code generation engine facilitates the export of a designed filter to Cortex-M Arm based processors 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.

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 ASN Filter Designer’s automatic code generator generates all initialisation code, scaling and data structures needed to implement the A-weighting filter IIR filter via Arm’s CMSIS-DSP library.

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)