I am trying to implement a digital High-Pass filter (IIR) with a cut off frequency around ~20Hz on a STM32H753ZI with the CMSIS DSP API. Every time I try to go test it, the output is no longer recognizable below the Fc but looks fine above it.
The way I'm creating the filter is by having MATLAB FDATOOL do most of the work then using the Direct II - Transposed form with a precision of a double.
Before anyone asked, yes the STM32H7 is equipped with a DP-FPU (Double Precision - FPU)
I was doing float precision before and could see why I couldn't go low that frequencies, but I would imagine with double precision I would have no problems.
Any suggestions?
Coefficients for HP Filter with Fc ~ 20Hz:
The order of the filters is : 11
The number of section of the filter is: 6
0.99982445967420, -1.99964891934840, 0.99982445967420, 1.99964816177700, -0.99964967691960,
0.99948849907220, -1.99897699814440, 0.99948849907220, 1.99897624082800, -0.99897775546090,
0.99919412499170, -1.99838824998340, 0.99919412499170, 1.99838749289000, -0.99838900707690,
0.99896509406540, -1.99793018813080, 0.99896509406540, 1.99792943121100, -0.99793094505080,
0.99881986128070, -1.99763972256140, 0.99881986128070, 1.99763896575200, -0.99764047937130,
0.99938486903600, -0.99938486903600, 0.00000000000000, 0.99876973807200, -0.00000000000000
Code:
/*
* DSP_FACTORY.c
*
* Created on: May 7, 2021
* Author: Christopher
*/
#define ARM_MATH_CM7
#include "main.h"
#include "arm_math.h"
#include "FILTER.h"
#include "CONSTANTS.h"
#include "OPCODE.h"
#include "I2S_FACTORY.h"
static double inputCompensator = 1.0;
static uint8_t volumeCurrent = 100;
static arm_biquad_cascade_df2T_instance_f64 audioStream_L;
static arm_biquad_cascade_df2T_instance_f64 audioStream_R;
void INIT_FILTER(uint8_t sourceMode) {
switch(sourceMode) {
case INPUT_INLINE:
arm_biquad_cascade_df2T_init_f64(&audioStream_L, 6, initFilter_96kHz_inline, pState_L_96kHz_inline);
arm_biquad_cascade_df2T_init_f64(&audioStream_R, 6, initFilter_96kHz_inline, pState_L_96kHz_inline);
break;
case INPUT_BLUETOOTH:
arm_biquad_cascade_df2T_init_f64(&audioStream_L, 8, initFilter_96kHz_inline, pState_L_44_1kHz_bluetooth);
arm_biquad_cascade_df2T_init_f64(&audioStream_R, 8, initFilter_96kHz_inline, pState_R_44_1kHz_bluetooth);
break;
}
}
void I2S_HALFCOMPLETE_CALLBACK() {
int * I2S1_RxBUFF = getI2S1_RxBUFF();
int * I2S1_TxBUFF = getI2S1_TxBUFF();
double INSAMPLE_I2S_L[1024];
double INSAMPLE_I2S_R[1024];
double OUTSAMPLE_I2S_L[1024];
double OUTSAMPLE_I2S_R[1024];
for (int i = 0; i < 2048; i ++){
if ( i % 2 == 0){ // R Samples
INSAMPLE_I2S_L[i-(i >> 1)] = (double) (I2S1_RxBUFF[i] << ADC_COMPENSATOR) * (0.01 * (double) volumeCurrent) * inputCompensator;
} else if ( i % 2 == 1){ // R Samples
INSAMPLE_I2S_R[i-1-((i-1)>>1)] = (double) (I2S1_RxBUFF[i] << ADC_COMPENSATOR) * (0.01 * (double) volumeCurrent) * inputCompensator;
}
}
arm_biquad_cascade_df2T_f64(&audioStream_L, INSAMPLE_I2S_L, OUTSAMPLE_I2S_L, 1024);
arm_biquad_cascade_df2T_f64(&audioStream_R, INSAMPLE_I2S_R, OUTSAMPLE_I2S_R, 1024);
for (int i = 0; i < 2048; i ++){
if (i % 2 == 0) { // L Samples
I2S1_TxBUFF[i] = (int)OUTSAMPLE_I2S_L[i-(i >> 1)];
} else if ( i % 2 == 1) { // R Samples
I2S1_TxBUFF[i] = (int)OUTSAMPLE_I2S_R[i-1-((i-1)>>1)];
}
}
}
void I2S_TRANSFERCOMPLETE_CALLBACK() {
int * I2S1_RxBUFF = getI2S1_RxBUFF();
int * I2S1_TxBUFF = getI2S1_TxBUFF();
double INSAMPLE_I2S_L[1024];
double INSAMPLE_I2S_R[1024];
double OUTSAMPLE_I2S_L[1024];
double OUTSAMPLE_I2S_R[1024];
for (int i = 2048; i < 4096; i ++){
if (i % 2 == 0){ // L Samples
INSAMPLE_I2S_L[i-(i >> 1)-1024] = (double) (I2S1_RxBUFF[i] << ADC_COMPENSATOR) * (0.01 * (double) volumeCurrent) * inputCompensator;
} else if ( i % 2 == 1){ // R Samples
INSAMPLE_I2S_R[i-1-((i-1)>>1)-1024] = (double) (I2S1_RxBUFF[i] << ADC_COMPENSATOR) * (0.01 * (double) volumeCurrent) * inputCompensator;
}
}
arm_biquad_cascade_df2T_f64(&audioStream_L, INSAMPLE_I2S_L, OUTSAMPLE_I2S_L, 1024);
arm_biquad_cascade_df2T_f64(&audioStream_R, INSAMPLE_I2S_R, OUTSAMPLE_I2S_R, 1024);
for (int i = 2048; i < 4096; i ++){
if (i % 2 == 0) { // L Samples
I2S1_TxBUFF[i] = (int)OUTSAMPLE_I2S_L[i-(i >> 1)-1024];
} else if ( i % 2 == 1) { // R Samples
I2S1_TxBUFF[i] = (int)OUTSAMPLE_I2S_R[i-1-((i-1)>>1)-1024];
}
}
}
void MUTE(uint8_t INPUT_AUDIO_SELECTOR) {
if((INPUT_AUDIO_SELECTOR == INPUT_INLINE) | (INPUT_AUDIO_SELECTOR == INPUT_BLUETOOTH))
SPI1->CR1 |= SPI_CR1_CSUSP;
while (!((SPI1->CR1) & (SPI_CR1_CSTART)));
DMA1_Stream0->CR &= ~DMA_SxCR_EN;
DMA1_Stream1->CR &= ~DMA_SxCR_EN;
SPI1->CR1 &= ~SPI_CR1_SPE;
}
void UNMUTE(uint8_t INPUT_AUDIO_SELECTOR) {
if((INPUT_AUDIO_SELECTOR == INPUT_INLINE) | (INPUT_AUDIO_SELECTOR == INPUT_BLUETOOTH))
DMA1_Stream0->CR |= DMA_SxCR_EN;
DMA1_Stream1->CR |= DMA_SxCR_EN;
SPI1->CR1 |= SPI_CR1_SPE;
SPI1->CR1 |= SPI_CR1_CSTART;
}
UPDATE 1:
... init_f64(&audioStream_R, ..., pState_L_ ...
\$\endgroup\$