![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
LUIS
Diff: digital_filter.cpp
- Revision:
- 0:43101a0b7a4c
diff -r 000000000000 -r 43101a0b7a4c digital_filter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/digital_filter.cpp Fri Oct 05 14:55:30 2018 +0000 @@ -0,0 +1,122 @@ +/** + * digital_filter.h + * + * Auteur : Ferdinand Piette (Avril 2011) + * Version : 1.0b + * + * Fourni des fonctions permettant d'appliquer des filtres numériques + * ayant pour fonction de transfert : + * + * b0*z + b1*z^-1 + ... + bN*z^-N + * H(z) = -------------------------------- + * 1 + a1*z^-1 + ... + aM*z^-M + */ + +#include <stdlib.h> +#include <stdio.h> + +#include "digital_filter.h" + +/** + * Initialise les coefficiants du filtre + * @param coef_a : les coefficients ai de la fonction de transfert du filtre + * @param coef_b : les coefficients bj de la fonction de transfert du filtre + * @param coef_a_size : le nombre de coefficients ai. Correspond à M dans la fonction de transfert du filtre + * @param coef_b_size : le nombre de coefficients bi. Correspond à N dans la fonction de transfert du filtre + * @param transfert_function : un pointeur vers la structure digital_filter_coefficient à initialiser + * Si coef_a_size = 0, alors on a la fonction de transfert d'un filtre RIF, sinon, on a celle d'un filtre RII + */ +void init_digital_filter_coefficient(struct digital_filter_coefficient * transfert_function, double * coef_a, int coef_a_size, double * coef_b, int coef_b_size) +{ + int i; + + // Création du tableau des coefficients a + transfert_function->numberOfCoef_a = coef_a_size; + transfert_function->coef_a = (double *)malloc(transfert_function->numberOfCoef_a * sizeof * transfert_function->coef_a); + for(i = 0; i < transfert_function->numberOfCoef_a; i++) + transfert_function->coef_a[i] = coef_a[i]; + + // Création du tableau des coefficients b + transfert_function->numberOfCoef_b = coef_b_size; + transfert_function->coef_b = (double *)malloc(transfert_function->numberOfCoef_b * sizeof * transfert_function->coef_b); + for(i = 0; i < transfert_function->numberOfCoef_b; i++) + transfert_function->coef_b[i] = coef_b[i]; +} + +/** + * Initialise le filtre + * @param coef_a : les coefficients ai de la fonction de transfert du filtre + * @param coef_b : les coefficients bj de la fonction de transfert du filtre + * @param coef_a_size : le nombre de coefficients ai. Correspond à M dans la fonction de transfert du filtre + * @param coef_b_size : le nombre de coefficients bi. Correspond à N dans la fonction de transfert du filtre + * @param filter : un pointeur vers la structure digital_filter à initialiser + * Si coef_a_size = 0, alors on se ramène à un filtre RIF, sinon, on a un filtre RII + */ +void init_digital_filter(struct digital_filter * filter, double * coef_a, int coef_a_size, double * coef_b, int coef_b_size) +{ + // Initialise les coefficients du filtre + init_digital_filter_coefficient(&filter->transfert_function, coef_a, coef_a_size, coef_b, coef_b_size); + + // Alloue l'espace mémoire pour les échantillons et les résultats + filter->samples = (double *)calloc(filter->transfert_function.numberOfCoef_b, sizeof * filter->samples); + filter->results = (double *)calloc(filter->transfert_function.numberOfCoef_a, sizeof * filter->results); + + // Initialise les pointeurs des tableaux d'échantillons et de résultats + filter->current_sample = 0; + filter->previous_result = filter->transfert_function.numberOfCoef_a-1; +} + +/** + * Calcul l'échantillon après filtrage + * @param sample : le nouvel échantillon que l'on veut filtrer + * @param filter : un pointeur vers la structure digital_filter contenant les informations du filtre (fonction de transfert et mémoire des échantillons précédents) + * @return l'échantillon après filtrage + */ +double filter_next_sample(digital_filter * filter, double sample) +{ + double result = 0; + int i; + + // Stocke en mémoire le nouvel échantillon + filter->samples[filter->current_sample] = sample; + + // Calcul le résultat du filtrage pour un filtre RIF ou RII + // (Prise en compte des échantillons précédent) + for(i = 0; i < filter->transfert_function.numberOfCoef_b; i++) + result += filter->transfert_function.coef_b[i] * filter->samples[modulo((filter->current_sample-i),filter->transfert_function.numberOfCoef_b)]; + + // Calcul le résultat du filtrage pour un filtre RII + // (Correction avec le résultat du filtrage des échantillons précédents) + for(i = 0; i < filter->transfert_function.numberOfCoef_a; i++) + result -= filter->transfert_function.coef_a[i] * filter->results[modulo((filter->previous_result-i),filter->transfert_function.numberOfCoef_a)]; + + // Met à jours les pointeurs des tableaux d'échantillons et de résultats + filter->current_sample = (filter->current_sample + 1) % filter->transfert_function.numberOfCoef_b; + if(filter->transfert_function.numberOfCoef_a > 0) + { + filter->previous_result = (filter->previous_result + 1) % filter->transfert_function.numberOfCoef_a; + filter->results[filter->previous_result] = result; // Garde en mémoire le résultat pour l'échantillon en cours + } + + return result; +} + +/** + * Définie l'opération de modulo dans les négatifs pour manipuler des buffers circulaires + * @param number : le nombre modulé + * @param n : le nombre modulant + * @return number modulo n + * modulo(-1, 3) = 2 + */ +int modulo(int number, int n) +{ + if(number >= 0) + return number%n; + + int result = (-1*number)%n; + + if(result > 0) + return n-result; + + return 0; +}