Mise en oeuvre d'un filtre IIR
Théorie des Filtres IIR : Filtrage Numérique IIR
L’Objectif est de réaliser le filtre d’ordre 4 ( 2 Stages ) évoqué dans Filtrage Numérique IIR
Après avoir déterminé les coefficients du filtre IIR, l’algorithme à appliquer au sein du processeur est du type :
Pour un Filtre d’ordre 2 :
|
|
Mise en Oeuvre
typedef struct
{
uint16_t numStages;
float32_t *pState;
float32_t *coef;
} arm_iir_instance_f32;
int IIR_filt_f32(arm_iir_instance_f32 *S, float* x, float* y)
{
unsigned int i;
float *wn_1_ptr,*wn_2_ptr,*coef_ptr;
float output=0.0;
float wn,wn_1,wn_2;
coef_ptr = S->coef; /* coefficient pointer */
wn_1_ptr = S->pState; /* first history */
wn_2_ptr = wn_1_ptr + 1; /* next history */
output = *x * (*coef_ptr++);
for (i = 0 ; i < S->numStages; i++)
{
wn_1 = *wn_1_ptr; /* history values */
wn_2 = *wn_2_ptr;
output = output - wn_1 * (*coef_ptr++);
wn = output - wn_2 * (*coef_ptr++); /* poles */
output = wn + wn_1 * (*coef_ptr++);
output = output + wn_2 * (*coef_ptr++); /* zeros */
*wn_2_ptr++ = *wn_1_ptr;
*wn_1_ptr++ = wn;
wn_1_ptr++;
wn_2_ptr++;
}
*y = output;
return 0;
}
Pour un filtre IIR d’ordre 4 ( numStage = 2 ), on rangera les coefficients dans un tableau de la manière suivante :
tab_coeff[0] : k
tab_coeff[1] : S0_beta1
tab_coeff[2] : S0_beta2
tab_coeff[3] : S0_alpha1
tab_coeff[4] : S0_alpha2
tab_coeff[5] : S1_beta1
tab_coeff[6] : S1_beta2
tab_coeff[7] : S1_alpha1
tab_coeff[8] : S1_alpha2
L’initialisation du filtre IIR se fait avec :
IIR_init_f32( &ARM_IIR_F32, 2, tab_coeff, tab_history, 1);
- ARM_IIR_F32 : structure de type arm_iir_instance_f32
- 2 : nombre de Stages
- tab_coeff : tableau de 9 éléments contenant les coefficients du filtre
- tab_history : tableau contenant les échantillons précédents pour le calcul du filtre ( de taille 4 )
Le calcul de l’échantillon de sortie du filtre pour chaque nouvel échantillon d’entrée se fait avec la fonction IIR_filt_f32(arm_iir_instance_f32 *S, float* x, float* y)
x_sample_f et y_sample_f sont de type float32_t, ainsi on aura :
void BSP_AUDIO_SAI_Interrupt_CallBack()
{
float32_t x_sample_f;
float32_t y_sample_f;
BSP_LED_On(LED1);
x_sample_f=(float32_t)rx_sample_L;
// SIGNAL PROCESSING ALGORITHM
IIR_filt_f32(&ARM_IIR_F32, &x_sample_f, &y_sample_f);
tx_sample_L = (int16_t)y_sample_f ;
tx_sample_R = tx_sample_L;
BSP_LED_Off(LED1);
return;
}
Q1. Tester la fonction IIR_filt_f32() avec des coefficients de filtres calculés par le script python synthese_iir_ordre4.py
REMARQUE : la fonction signal.iirfilter permet de calculer les coefficients de tout type de filtre IIR. ( cf gene_coeffs_IIR.py )
Q2. Compléter et tester la fonction IIR_calc_coeff_f32() afin de calculer les coefficients du filtre IIR d’ordre 4 pour une fréquence de coupure souhaitée.
Q3. Réaliser un synthétiseur à synthèse soustractive à base de filtre IIR. Les paramètres k et Q doivent pouvoir être réglables avec un potentiomètre du clavier maître.