Pour récupérez le fichier zip du projet la première fois, ouvrir une console (alt+F2 et taper lxterm) puis taper dedans:
cd /mnt/etu/s4en/..... à compléter
puis copier coller (sélectionner le code qui suit puis clic sur le bouton central de la souris dans le terminal) :
wget https://bvdp.inetdoc.net/files/iut/tp_tns/TP_ARCHI_TNS.zip unzip TP_ARCHI_TNS.zip cd TP_ARCHI_TNS qtcreator TP_ARCHI_TNS.pro & echo "C est bon !"
Compiler et exécuter le projet.
Nous souhaitons maintenant intégrer les convertisseur dans la chaîne de traitement en les simulant par des fonctions:
Le schéma suivant représente l'agencement de ces deux fonctions relativement à FiltreUnEchantillon.
Implémenter les fonctions simuADC et simuDAC dans le fichier filtre.cpp.
Définir 2 variables globales nbBitsQuantDAC et nbBitsQuantADC à la valeur 10.
Tester ces 2 fonctions en les appelant depuis calculReponseFiltreEnLigne avec des valeurs d'entrées connues et vérifier les valeurs de retour en mode Debug pour au moins 3 points.
Intégrer dans la fonction calculReponseFiltreEnLigne l'appel de ces 2 fonctions pour les utiliser avec la fonction filtreUnEchantillon:
Régler les valeurs des variables globales:
Modifier la valeur des échantillons pour l'entrée du filtre. Un offset de 3.3V/2 doit être ajouté à chaque échantillon.
Faire le test du programme en traçant les réponses temporelles du filtre.
Les coefficients du filtre sont stockés dans des tableaux de valeurs codées en double. Nous souhaitons maintenant les approximer par codage en virgule fixe au format Q0.15.
Déterminer les types adéquats pour les paramètres d'entrée/sortie de la fonction quantCoeffsShortInt. Cette fonction prend en entrée:
Coder en C cette fonctions. On utilisera l'arrondi plutôt que la troncature pour le calcul.
Le code de la fonction quantCoeffsShortInt ci dessous doit être intégré dans filtre.cpp.
void quantCoeffsShortInt(double * tabDouble, short int * tabInt, double * tabDoubleQuant, int nbCoeffs, unsigned int nbBitsFractionnaire){ int i; long int temp; for (i=0;i<nbCoeffs;i++) { A FAIRE: affecter à la variable temp le résultat de la conversion de tabDouble[i] au format virgule fixe signé avec nbBitsFractionnaire bits après la virgule. //Vérifier qu'il n'y a pas de dépassement sinon saturer if (temp>( (1<<15)-1) ) temp= (1<<15)-1; if (temp<( -(1<<15)) ) temp=-(1<<15); tabInt[i]= (short int)temp; tabDoubleQuant[i]=tabInt[i] / (double)(1<<nbBitsFractionnaire); printf("coefficient %d valant %lf codé avec %d bits pour la partie fractionnaire: %d soit %lf\n",i,tabDouble[i],nbBitsFractionnaire,tabInt[i],tabDoubleQuant[i]); fflush(stdout); } }
Compléter cette fonction pour réaliser la conversion.
Tester cette fonction avec les constantes définies dans un tableau
double val[]={ 0, 0.999, 0.0001, 1, 2, -1, 0.5, -0.5};
Réaliser la conversion vers les formats Q0.15, Q3.12 et analyser les résultats. Indiquer quels coefficients ont été codés de manière:
Vous allez maintenant implémenter le filtre avec les calculs en virgule fixe. Nous traiterons uniquement des filtres RIF car les filtres RII sont plus complexes à dimensionner.
Indiquer le format de par application du calcul sur les entiers codant les nombres en virgule fixe.
On souhaite un résultat entier au format UQN.0 pour piloter le DAC. Avant l'ajout d'offset numérique sur la sortie dû au référencement par rapport au zéro, on utilise donc le codage au format Q(N-1).0. Quelle opération doit on effectuer pour convertir le résultat de à ce format?
En déduire l’intérêt d'avoir effectué les calculs intermédiaires sur 32 bits pour obtenir un résultat sur 16 bits.
Si la sortie de la fonction d'application du calcul doit être utilisée pour piloter un DAC 10 bits, indiquer les opérations à effectuer pour s'assurer que le résultat obtenu après conversion puisse être codé au format UQ10.0 (et donc Q(N-1).0 avant ajout d'offset numérique).
Le schéma suivant représente les différentes opérations et formats utilisés. Compléter les parties manquantes.
En vous inspirant du codage de la fonction double filtreUnEchantillon(double ek) (qui réalise un filtre RII), proposer une implémentation de unsigned short int filtreUnEchantillon_RIF(unsigned short int ek) qui réalise un filtre RIF en VIRGULE FIXE. Pour cela, vous modifierez le code imprimé sur la feuille distribuée pendant la séance ( https://bvdp.inetdoc.net/files/iut/tp_tns/filtreUnEchantillon.pdf ). Vous ferez valider cette étape d'analyse avant de réaliser le codage sur machine.
Pour le test, vous utiliserez le filtre RIF simple défini par les tableaux suivants:
const int NB_COEFF_B=3 ; double coeffB[NB_COEFF_B]={0.5,0.7,0.3}; const int NB_COEFF_A=1; double coeffA[NB_COEFF_A]={1};
Tester la réponse du filtre en utilisant la fonction double filtreUnEchantillon(double ek).
Pour l'implémentation en virgule fixe, vous devrez définir 4 pointeurs en variables globales:
short int * a_Q015; double * a_q; short int * b_Q015; double * b_q; short int *memoireVk_i;
Dans la fonction initFiltreUnEchantillon, vous réaliserez l'allocation dynamique des tableaux à la bonne taille:
a_Q015=new short int[NB_COEFF_A]; a_q=new double[NB_COEFF_A]; b_Q015=new short int[NB_COEFF_B]; b_q=new double[NB_COEFF_B]; memoireVk_i=new short int[NB_COEFF_B+1];
Toujours dans la fonction initFiltreUnEchantillon, vous réaliserez ensuite le codage en virgule fixe des coefficients en appelant la fonction de conversion:
printf("\n Coefficients a:\n"); quantCoeffsShortInt(a, a_Q015, a_q, NB_COEFF_A, NB_BITS_FRACTIONNAIRE); printf("\n Coefficients b:\n"); quantCoeffsShortInt(b, b_Q015, b_q, NB_COEFF_B, NB_BITS_FRACTIONNAIRE);
Puis vous initialiserez le contenu du tableau memoireVk_i à 0:
for (i=0;i<NB_COEFF_B+1;i++) memoireVk_i[i]=0;
Coder la fonction unsigned short int filtreUnEchantillon_RIF(unsigned short int ek) puis remplacez l'appel de double filtreUnEchantillon(double ek) par cette nouvelle fonction et vérifiez que les réponses temporelles sont inchangées.
Pour le test, vous utiliserez le filtre défini par les tableaux suivants:
const int NB_COEFF_B=201 ; double coeffB[NB_COEFF_B]={0.0010497657664069,0.0010248032141060,0.0008950989702105,0.0006754260236328,0.0003914824095416,0.0000766934492105,-0.0002321048737491,-0.0004995386970487,-0.0006964600877342,-0.0008039239652070,-0.0008157836216176,-0.0007394830559167,-0.0005948664932619,-0.0004111061172667,-0.0002221300434536,-0.0000611735162575,0.0000447598151640,0.0000796811308439,0.0000418604532548,-0.0000550716758918,-0.0001834867559374,-0.0003055590399293,-0.0003791090967164,-0.0003647560591893,-0.0002333866931914,0.0000271842699248,0.0004074693745616,0.0008744059311998,0.0013728937238789,0.0018309281895384,0.0021679805132536,0.0023057764653131,0.0021801999890144,0.0017527602862087,0.0010199632250395,0.0000190482922570,-0.0011711072134873,-0.0024345821147888,-0.0036284987472194,-0.0045978697208798,-0.0051937725260009,-0.0052928489822895,-0.0048157655121297,-0.0037421830301847,-0.0021200045223263,-0.0000671897708197,0.0022347930844576,0.0045558495491448,0.0066394125108034,0.0082298250869960,0.0091021062349281,0.0090907379538161,0.0081139702738372,0.0061904123965458,0.0034453596342308,0.0001053400669057,-0.0035193504333161,-0.0070629599518906,-0.0101409269984312,-0.0123912150958553,-0.0135159141893970,-0.0133183847721507,-0.0117314514765957,-0.0088329189234603,-0.0048459221009567,-0.0001232158250872,0.0048837149938801,0.0096680778553808,0.0137195341098129,0.0165789638233212,0.0178903118599852,0.0174436522975187,0.0152043335317103,0.0113244013729469,0.0061343135538643,0.0001150678565127,-0.0061469611180756,-0.0120181883656648,-0.0168831175207452,-0.0202099218564704,-0.0216092075118743,-0.0208793906867327,-0.0180333949515915,-0.0133032695303891,-0.0071216486525055,-0.0000814675096998,0.0071222518254061,0.0137626997041129,0.0191563866117297,0.0227351202843601,0.0241071081284681,0.0231004857065963,0.0197843647677042,0.0144648478539781,0.0076561189341496,0.0000294013994965,-0.0076550186151438,-0.0146256412959852,-0.0201792994512465,-0.0237539929269980,0.9750127221960708,-0.0237539929269980,-0.0201792994512465,-0.0146256412959852,-0.0076550186151438,0.0000294013994965,0.0076561189341496,0.0144648478539781,0.0197843647677042,0.0231004857065963,0.0241071081284681,0.0227351202843601,0.0191563866117297,0.0137626997041129,0.0071222518254061,-0.0000814675096998,-0.0071216486525055,-0.0133032695303891,-0.0180333949515915,-0.0208793906867327,-0.0216092075118743,-0.0202099218564704,-0.0168831175207452,-0.0120181883656648,-0.0061469611180756,0.0001150678565127,0.0061343135538643,0.0113244013729469,0.0152043335317103,0.0174436522975187,0.0178903118599852,0.0165789638233212,0.0137195341098129,0.0096680778553808,0.0048837149938801,-0.0001232158250872,-0.0048459221009567,-0.0088329189234603,-0.0117314514765957,-0.0133183847721507,-0.0135159141893970,-0.0123912150958553,-0.0101409269984312,-0.0070629599518906,-0.0035193504333161,0.0001053400669057,0.0034453596342308,0.0061904123965458,0.0081139702738372,0.0090907379538161,0.0091021062349281,0.0082298250869960,0.0066394125108034,0.0045558495491448,0.0022347930844576,-0.0000671897708197,-0.0021200045223263,-0.0037421830301847,-0.0048157655121297,-0.0052928489822895,-0.0051937725260009,-0.0045978697208798,-0.0036284987472194,-0.0024345821147888,-0.0011711072134873,0.0000190482922570,0.0010199632250395,0.0017527602862087,0.0021801999890144,0.0023057764653131,0.0021679805132536,0.0018309281895384,0.0013728937238789,0.0008744059311998,0.0004074693745616,0.0000271842699248,-0.0002333866931914,-0.0003647560591893,-0.0003791090967164,-0.0003055590399293,-0.0001834867559374,-0.0000550716758918,0.0000418604532548,0.0000796811308439,0.0000447598151640,-0.0000611735162575,-0.0002221300434536,-0.0004111061172667,-0.0005948664932619,-0.0007394830559167,-0.0008157836216176,-0.0008039239652070,-0.0006964600877342,-0.0004995386970487,-0.0002321048737491,0.0000766934492105,0.0003914824095416,0.0006754260236328,0.0008950989702105,0.0010248032141060,0.0010497657664069}; const int NB_COEFF_A=1; double coeffA[NB_COEFF_A]={1};
Dans le fichier tparchi1.cpp, régler FECH à 1000 (Hz) et tracer la réponse fréquentielle entre 0.1Hz et 500Hz pour 10000 échantillons de fréquences.
const double FECH=1000; const double FMIN=0.1; const double FMAX=(FECH/2.0); const int NB_FREQ=10000;
L’exécution du programme doit produire la réponse fréquentielle suivante:
Quelle est la fonction réalisée par ce filtre au niveau fréquentiel?
La réponse fréquentielle affichée est calculée uniquement grâce au valeur des coefficients. Vous allez maintenant vérifier le comportement du filtre au niveau temporel. Pour cela vous allez générer les réponses temporelles pour des signaux d'entrée sinusoïdaux et vérifier la réponse du filtre.
Afin de pouvoir utiliser le shield DAC (présenté sur: https://bvdp.inetdoc.net/wiki/doku.php?id=tpdacspi ), vous devez installer une librairie. Pour cela, copiez-collez dans une console après l'avoir ouverte avec ALT+F2 lxterm :
mkdir ~/sketchbook cd ~/sketchbook mkdir libraries cd libraries wget https://bvdp.inetdoc.net/files/iut/tp_dacspi/Tlv5637.zip unzip -o Tlv5637.zip rm Tlv5637.zip
Au lancement d'arduino, si c'est la première fois qu'il est exécuté sur cette machine, sélectionnez le dossier sketchbook.
La plateforme de traitement se compose de :
Dans ce TP nous allons mettre en place l'architecture qui permet de :
Les exercices suivants sont à réaliser à l'aide du dernier TD en complétant le code suivant.
#include <SPI.h> #include <Tlv5637.h> unsigned ek, sk_suiv; const int chipSelectPin = 3; TLV5637 DAC(chipSelectPin,REF_2048MV_TLV5637); ISR(TIMER2_COMPA_vect){ //PORTB |= 0x01 ; //à dé-commenter plus tard // Lancer une conversion ADC startADC0Conversion(); // Lire le résultat de la conversion ek = readADC0Conversion(); // Filtrer ek : appel du filtre avec ek en entrée et sk_suiv en sortie sk_suiv = ek ; //ecrire sk_suiv sur DACA //ecrire ek sur DACB pour vérification PORTB ^= 0x01 ; //à commenter plus tard //PORTB &= ~0x01 ; //à dé-commenter plus tard } void setupTimer2(unsigned char prescaler, unsigned int period){ TCCR2A = 0;// set entire TCCR2A register to 0 TCCR2B = 0;// same for TCCR2B TCNT2 = 0;//initialize counter value to 0 //compléter avec la configuration du TIMER 2 vue en TD } void setupDAC(){ //à compléter } void setupADC0(){ //à compléter } void startADC0Conversion(){ //à compléter } unsigned int readADC0Conversion(){ //à compléter } void setup() { setupADC0(); setupDAC(); cli(); setupTimer2(0, 0); sei(); Serial.begin(115200); DDRB |= 0x01 ; //set pin B[0] as output PORTB |= 0x01 ; //set PIN B[0] to high } void loop() { //exercice 2 : Générer une rampe sur la voie A du DAC }
Pour mettre en place un base de temps qui cadencera l'acquisition et le traitement, il est dans un premier temps nécessaire de compléter la fonction setupTimer, puis modifier la fonction setup pour lui passer les bons arguments (fréquence d’interruption 2kHz). Vérifiez le bon fonctionnement en observant le signal sur la broche D8 de l'arduino.
Le code fournit implémente déja le gestion d'interruption ISR(TIMER2_COMPA_vect). Dans cette fonction, le code mis en place complémente la sortie 8 (PORTB ^= 0x01) ce qui à pour effet de faire changer l'état de la broche 8 au rythme des interruptions générées par le timer 2.
Comme vu en TD, compléter les fonctions setupADC0, startADC0Conversion, readADC0Conversion pour respectivement :
Vérifiez le bon fonctionnement en complétant le code de la fonction loop pour afficher le résultat de la conversion (fonction Serial.println) dix fois par seconde (utilisation de la fonction delay). La carte shield TLV5637 dispose de deux potentiomètres marqués A0 et A1. Lorsque le cavalier au dessus du potentiomètre A0 est connecté, le canal A0 est connecté la sortie du montage pont diviseur réalisé à l'aide du potentiomètre. Pour tester l'ADC vous pouvez donc utiliser ce potentiomètre pour faire varier la tension en entrée de ADC0.
Comme vu en TD compléter le code de la fonction setupDAC(). Pour vérifier le fonctionnement, implémentez dans la fonction loop() la génération d'une rampe périodique de 0v à 4,096v sur la voie A du DAC.
On souhaite recopier sous interruption la tension d'entrée de l'ADC directement en sortie du DAC pour vérifier que l'Arduino est correctement configuré avant de passer au filtrage.
Modifiez et complétez le code de la fonction ISR(TIMER2_COMPA_vect) de la façon suivante:
ISR(TIMER2_COMPA_vect){ PORTB |= 0x01 ; // patte 8 à 1 pour mesurer le temps passé dans l'IT // Lancer une conversion ADC // Filtrer ek : appel du filtre avec ek en entrée et sk_suiv en sortie sk_suiv = ek ; // simple recopie b0=1 ! //ecrire sk_suiv sur DACA //ecrire aussi ek sur DACB pour comparaison // Lire le résultat de la conversion ek = PORTB &= ~0x01 ; // patte 8 à 0 }
IMPORTANT: Ne jamais connecter de signal sur l'entrée analogique A0 avant de s'être assuré avec l'oscilloscope que le signal soit dans la plage 0 à 5V!!!
Le signal connecté à l'entrée A0 du shield pourra avoir une amplitude crête à crête inférieure à 5V mais devra être centré sur 2.5V.
Sur la sortie A du DAC, la sortie du filtre est visible, avec une amplitude crête à crête maximale de 4.096V.
Sur la sortie B du DAC, une version numérisée et atténuée de l'entrée du filtre est visible, avec une amplitude crête à crête maximale de 4.096V.
Sur la broche 8 de l'Arduino, un signal périodique indique la fréquence de l'interruption Timer 2. La durée à l'état haut indique la durée nécessaire au traitement de l'interruption TIMER.
Il faut déclarer le filtre original (type double) comme sur Qt en variable globale et ajouter un tableau d'entiers pour stocker les coefficients du filtre au format Q0.15. Soit pour le filtre :
const int NB_COEFF_B=2 ; double coeffB[NB_COEFF_B]={0.5,0.5}; short int coeffB_i[NB_COEFF_B];
Vous devez initialiser le tableau coeffB_i dans la fonction setup() en appelant quantCoeffsShortInt(double * tabDouble, short int * tabInt, int nbCoeffs, unsigned int nbBitsFractionnaire). On rappelle que cette fonction a été testée dans Qt, néanmoins, il faut l'adapter pour l'arduino.
void quantCoeffsShortInt(double * tabDouble, short int * tabInt, int nbCoeffs, unsigned int nbBitsFractionnaire){ int i; long int temp; for (i=0;i<nbCoeffs;i++) { Serial.print(i,DEC); Serial.print(":"); Serial.print( tabDouble[i]); Serial.print(":"); temp= floor( (tabDouble[i] * (((unsigned long int)1)<<nbBitsFractionnaire) ) + 0.5) ; //1 <<nbBitsFractionnaire génère une valeur négative sans le cast //Vérifier qu'il n'y a pas de dépassement sinon saturer if (temp>( (1<<15)-1) ) temp= (1<<15)-1; if (temp<( -(1<<15)) ) temp=-(1<<15); tabInt[i]= (short int)temp; Serial.print( tabInt[i],DEC); Serial.print(":"); Serial.println( tabInt[i],HEX); } }
Copiez le code suivant et appelez-le correctement dans le sous-programme d'interruption pour calculer sk_temp à partir de ek. Vous devrez déclarer toutes les variables nécessaires.
unsigned int indice_ecr=0; const int NB_COEFF_B=2 ; double coeffB[NB_COEFF_B]={0.5,0.5}; const unsigned int MEMORYSIZE=NB_COEFF_B+1; const unsigned int NB_BITS_FRACTIONNAIRE = 15; short int memoireVk_i[MEMORYSIZE]; short int coeffB_i[NB_COEFF_B]; ///////////////////////////////////////////////////////////////// short int filtreUnEchantillon_i(short int ek){ short int temp; // calcul intermediaire int i; //indice de lecture pour les valeurs des coefficients du filtre int j; //indice de lecture pour les valeurs des coefficients du filtre int indice_lec; //indice de lecture pour les échantillons d'entrée long int skout; //valeur pour la sortie calculée //suppression offset numérique temp=ek-512; //pour un RIF, NB_COEFF_A=1 donc vktemp sera inchangé //rangement de la valeur calculée dans tableau vk à l'indice indice_ecr memoireVk_i[indice_ecr]=temp; //calcul de sk skout = 0; //valeur par défaut pour le résultat indice_lec = indice_ecr; for (i = 0; i <NB_COEFF_B; i++){ //N+1 itérations skout += (long int) coeffB_i[i] * (long int) memoireVk_i[indice_lec]; //ici le premier vk pris en compte est vk, donc on décremente indice_lec avant après utilisation indice_lec=indice_lec-1; if (indice_lec < 0) indice_lec = MEMORYSIZE - 1; } //incrémentation du pointeur d'écriture pour la prochaine itération indice_ecr = (indice_ecr + 1); if (indice_ecr>=MEMORYSIZE) indice_ecr=0; if (skout & (1<<(NB_BITS_FRACTIONNAIRE-1)) ) // calcul de l'arrondi skout = (skout >> NB_BITS_FRACTIONNAIRE ) + 1; else skout = (skout >> NB_BITS_FRACTIONNAIRE ) ; if (skout > 511 ) // saturation du résultat sur 10 bits skout = 511 ; else if (skout < -512 ) skout = -512 ; //ajout offset numérique return skout + 512; } /////////////////////////////////////////////////////////////////
Version filtre passe bas, fc=260Hz pour fe=2khz
#define SIZEFILTER_RIF 11 const double numCoeff_d_FILTRE_RIF[SIZEFILTER_RIF] = {-0.0349249458233189,-0.0370641891927234,0.0209236117413746,0.1368055347416942,0.2562279031324722,0.3071029997932009,0.2562279031324722,0.1368055347416942,0.0209236117413746,-0.0370641891927234,-0.0349249458233189};
Passe haut, fe=2khz, fpass (-1dB) =275Hz, fstop (-40dB) =200Hz, equiripple
coeff du filtre RIF 41 termes: num
#define SIZEFILTER_RIF 41 const double numCoeff_d_FILTRE_RIF[SIZEFILTER_RIF]={ 0.016244657856333,-0.018864421488768,-0.012238782422342,-0.005085409431928,0.003969691594410, 0.012267146479049, 0.015030618183398, 0.008966346831124, -0.004682203645285,-0.019357735197421,-0.025875762043837,-0.017435787337996, 0.005471034822059, 0.033037851847265, 0.049218355348873, 0.038520192602532, -0.006112347636894,-0.078041093847378,-0.157847718052422,-0.220135476387537,0.756344281504610,-0.220135476387537,-0.157847718052422,-0.078041093847378, -0.006112347636894, 0.038520192602532, 0.049218355348873, 0.033037851847265,0.005471034822059,-0.017435787337996,-0.025875762043837,-0.019357735197421, -0.004682203645285, 0.008966346831124, 0.015030618183398, 0.012267146479049,0.003969691594410,-0.005085409431928,-0.012238782422342,-0.018864421488768, 0.016244657856333};
Rejecteur 50Hz, fe=1khz, module de la fonction de transfert:
#define SIZEFILTER_RIF 201 const double numCoeff_d_FILTRE_RIF[SIZEFILTER_RIF] = {0.0010497657664069,0.0010248032141060,0.0008950989702105,0.0006754260236328,0.0003914824095416,0.0000766934492105,-0.0002321048737491,-0.0004995386970487,-0.0006964600877342,-0.0008039239652070,-0.0008157836216176,-0.0007394830559167,-0.0005948664932619,-0.0004111061172667,-0.0002221300434536,-0.0000611735162575,0.0000447598151640,0.0000796811308439,0.0000418604532548,-0.0000550716758918,-0.0001834867559374,-0.0003055590399293,-0.0003791090967164,-0.0003647560591893,-0.0002333866931914,0.0000271842699248,0.0004074693745616,0.0008744059311998,0.0013728937238789,0.0018309281895384,0.0021679805132536,0.0023057764653131,0.0021801999890144,0.0017527602862087,0.0010199632250395,0.0000190482922570,-0.0011711072134873,-0.0024345821147888,-0.0036284987472194,-0.0045978697208798,-0.0051937725260009,-0.0052928489822895,-0.0048157655121297,-0.0037421830301847,-0.0021200045223263,-0.0000671897708197,0.0022347930844576,0.0045558495491448,0.0066394125108034,0.0082298250869960,0.0091021062349281,0.0090907379538161,0.0081139702738372,0.0061904123965458,0.0034453596342308,0.0001053400669057,-0.0035193504333161,-0.0070629599518906,-0.0101409269984312,-0.0123912150958553,-0.0135159141893970,-0.0133183847721507,-0.0117314514765957,-0.0088329189234603,-0.0048459221009567,-0.0001232158250872,0.0048837149938801,0.0096680778553808,0.0137195341098129,0.0165789638233212,0.0178903118599852,0.0174436522975187,0.0152043335317103,0.0113244013729469,0.0061343135538643,0.0001150678565127,-0.0061469611180756,-0.0120181883656648,-0.0168831175207452,-0.0202099218564704,-0.0216092075118743,-0.0208793906867327,-0.0180333949515915,-0.0133032695303891,-0.0071216486525055,-0.0000814675096998,0.0071222518254061,0.0137626997041129,0.0191563866117297,0.0227351202843601,0.0241071081284681,0.0231004857065963,0.0197843647677042,0.0144648478539781,0.0076561189341496,0.0000294013994965,-0.0076550186151438,-0.0146256412959852,-0.0201792994512465,-0.0237539929269980,0.9750127221960708,-0.0237539929269980,-0.0201792994512465,-0.0146256412959852,-0.0076550186151438,0.0000294013994965,0.0076561189341496,0.0144648478539781,0.0197843647677042,0.0231004857065963,0.0241071081284681,0.0227351202843601,0.0191563866117297,0.0137626997041129,0.0071222518254061,-0.0000814675096998,-0.0071216486525055,-0.0133032695303891,-0.0180333949515915,-0.0208793906867327,-0.0216092075118743,-0.0202099218564704,-0.0168831175207452,-0.0120181883656648,-0.0061469611180756,0.0001150678565127,0.0061343135538643,0.0113244013729469,0.0152043335317103,0.0174436522975187,0.0178903118599852,0.0165789638233212,0.0137195341098129,0.0096680778553808,0.0048837149938801,-0.0001232158250872,-0.0048459221009567,-0.0088329189234603,-0.0117314514765957,-0.0133183847721507,-0.0135159141893970,-0.0123912150958553,-0.0101409269984312,-0.0070629599518906,-0.0035193504333161,0.0001053400669057,0.0034453596342308,0.0061904123965458,0.0081139702738372,0.0090907379538161,0.0091021062349281,0.0082298250869960,0.0066394125108034,0.0045558495491448,0.0022347930844576,-0.0000671897708197,-0.0021200045223263,-0.0037421830301847,-0.0048157655121297,-0.0052928489822895,-0.0051937725260009,-0.0045978697208798,-0.0036284987472194,-0.0024345821147888,-0.0011711072134873,0.0000190482922570,0.0010199632250395,0.0017527602862087,0.0021801999890144,0.0023057764653131,0.0021679805132536,0.0018309281895384,0.0013728937238789,0.0008744059311998,0.0004074693745616,0.0000271842699248,-0.0002333866931914,-0.0003647560591893,-0.0003791090967164,-0.0003055590399293,-0.0001834867559374,-0.0000550716758918,0.0000418604532548,0.0000796811308439,0.0000447598151640,-0.0000611735162575,-0.0002221300434536,-0.0004111061172667,-0.0005948664932619,-0.0007394830559167,-0.0008157836216176,-0.0008039239652070,-0.0006964600877342,-0.0004995386970487,-0.0002321048737491,0.0000766934492105,0.0003914824095416,0.0006754260236328,0.0008950989702105,0.0010248032141060,0.0010497657664069};
Passe-bande BP[50-100Hz], fe=1khz,
#define SIZEFILTER_RIF 101 const double CoeffB[SIZEFILTER_RIF] = {-0.00113754135600039,0.00145573551019635,0.00204757132637837,0.00263156294182860,0.00271333596419554,0.00209181864289657,0.000931323096882042,-0.000295253526426151,-0.00102072553574198,-0.000889774336090301,4.43083314764723e-06,0.00107786715387792,0.00148437917329484,0.000533571368047096,-0.00188920791601188,-0.00513244322430680,-0.00796026431933224,-0.00907718729044520,-0.00777797980615596,-0.00439743526773444,-0.000287855091834307,0.00274023252764250,0.00330580413329246,0.00125505519932939,-0.00206543063390858,-0.00429236660220396,-0.00315158375829297,0.00229242971458052,0.0108761998865694,0.0195399514396670,0.0245421070503854,0.0232190058461234,0.0154734208240917,0.00418954936970178,-0.00580409548159399,-0.00992700646926349,-0.00626756928856083,0.00294530495786515,0.0117123531725929,0.0125971807940101,0.000217527153081935,-0.0255798746481075,-0.0583939852764639,-0.0866769663502052,-0.0976561065793289,-0.0823880423296246,-0.0399479214643191,0.0211017548056543,0.0847783033982685,0.132738261013397,0.150547020990727,0.132738261013397,0.0847783033982685,0.0211017548056543,-0.0399479214643191,-0.0823880423296246,-0.0976561065793289,-0.0866769663502052,-0.0583939852764639,-0.0255798746481075,0.000217527153081935,0.0125971807940101,0.0117123531725929,0.00294530495786515,-0.00626756928856083,-0.00992700646926349,-0.00580409548159399,0.00418954936970178,0.0154734208240917,0.0232190058461234,0.0245421070503854,0.0195399514396670,0.0108761998865694,0.00229242971458052,-0.00315158375829297,-0.00429236660220396,-0.00206543063390858,0.00125505519932939,0.00330580413329246,0.00274023252764250,-0.000287855091834307,-0.00439743526773444,-0.00777797980615596,-0.00907718729044520,-0.00796026431933224,-0.00513244322430680,-0.00188920791601188,0.000533571368047096,0.00148437917329484,0.00107786715387792,4.43083314764723e-06,-0.000889774336090301,-0.00102072553574198,-0.000295253526426151,0.000931323096882042,0.00209181864289657,0.00271333596419554,0.00263156294182860,0.00204757132637837,0.00145573551019635,-0.00113754135600039};