Définition d'un "struct" avec pointeurs

Résolu/Fermé
Nounours18200 Messages postés 121 Date d'inscription samedi 30 mars 2013 Statut Membre Dernière intervention 8 avril 2024 - Modifié le 17 oct. 2022 à 14:41
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 - 20 oct. 2022 à 14:23

Bonjour,

Dans un programme, je trouve la partie suivante:

struct fir_filter {
  short *coeffs;       // short means a range from -32 768 to 32 767
  short num_coeffs;    // num_coeffs must be an even number, 4 or higher
};

Il me semble comprendre que:

  • la structure s'appelle "fir_filter"
  • elle est constituée de 2 composantes: des "coeffs", et un entier court "num_coeffs".

On m'a dit aussi que l'étoile '*' devant "coeffs" est un pointeur: j'imagine que ça permet de définir de quoi est composé le "struct", et d'affecter les valeurs plus tard.

Ce que je ne comprends pas, c'est que je ne trouve nulle part dans ce programme un endroit où l'on définit la valeur de ces "coeffs" et de "num_coeffs"; supposons que je ne l'ai pas trouvé, avec quelle syntaxe définit-on a posteriori la valeur de chacun des "coeffs" ?

Merci

9 réponses

[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié le 17 oct. 2022 à 11:48

Bonjour à tous,
et Bonjour Nounours18200,

En C, un bloc comme :

struct fir_filter {
  short *coeffs;
  short num_coeffs;
};

définit un type "struct fir_filter".

Ce type sert, comme un autre type en C, à définir des variables.

Par exemple :

https://github.com/PaulStoffregen/Audio/blob/master/examples/Effects/Filter_FIR/Filter_FIR.ino

struct fir_filter {
  short *coeffs;
  short num_coeffs;    // num_coeffs must be an even number, 4 or higher
};

// index of current filter. Start with the low pass.
int fir_idx = 0;
struct fir_filter fir_list[] = {
  {low_pass , 100},    // low pass with cutoff at 1kHz and -60dB at 2kHz
  {band_pass, 100},    // bandpass 1200Hz - 1700Hz
  {NULL,      0}
};

Signifie, en ligne 8 ci-dessus :

  • qu'une variable "fir_list" de type tableau, pouvant contenir des éléments de type "struct fir_filter" est créée
  • que ce tableau est initialisé pour comporter 3 éléments de type "struct fir_filter"
  • le dernier de ces éléments sert juste de drapeau pour indiquer la fin du tableau
  • donc, en fait il y a 2 éléments de type "struct fir_filter" réellement utiles

Le premier élément du tableau (élément d'indice 0 de type "struct fir_filter") :

Le deuxième élément du tableau  (élément d'indice 1 de type "struct fir_filter") :

Si le code dont tu tires celui que tu postes sur le forum correspond à ce projet, tu as tes réponses, je suppose.

Si ce n'est pas le même, tu as une illustration d'une façon dont une telle struct peut être déclarée et initialisée avec des valeurs.

1
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié le 17 oct. 2022 à 13:00

(...)

Pour être complet, ces deux .h lopass_1000_44100.h et bandp_1200_1700.h contiennent des données brutes qui sont le contenu des deux tableaux et qui sont en fait intégrées par un include dans la définition de ces deux tableaux ici :

https://github.com/PaulStoffregen/Audio/blob/master/examples/Effects/Filter_FIR/filters.cpp

ces données brutes sont visiblement générées automatiquement et c'est pourquoi le programmeur a utilisé cette astuce de déporter les valeurs séparées par des virgules dans des fichiers séparés inclus par le pré-processeur.

As-tu fait une recherche sur le nom "coeffs"?

Ce conseil de yg_be et de NHenry, qui n'est pas faux, ne permettait pas ici de tomber sur les données que tu cherchais.

Dans ce code que j'ai trouvé en ligne, comme le contenu de la struct est initialisé lors de sa déclaration, avec l'indication du contenu à insérer dans chaque membre, le nom des membres n'a pas à être obligatoirement mentionné (et une recherche sur "coeff" ne permettait pas de tomber sur la ligne qui affecte les valeurs initiales), les valeurs correspondant au contenu de chaque membre étant affectées, par défaut, dans l'ordre de la définition du type.

A partir de C99, il est aussi possible de le faire en désignant les champs initialisés avec leurs noms.

Une syntaxe alternative à la précédente, et peut-être plus claire aurait été :

struct fir_filter fir_list[] = {
  {.coeffs = low_pass,  .num_coeffs = 100},  // low pass with cutoff at 1kHz and -60dB at 2kHz
  {.coeffs = band_pass, .num_coeffs = 100},  // bandpass 1200Hz - 1700Hz
  {.coeffs = NULL,      .num_coeffs = 0}
};
0
yg_be Messages postés 22722 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 25 avril 2024 1 476
15 oct. 2022 à 16:48

bonjour,

As-tu fait une recherche sur le nom "coeffs"?

(Ton imagination te conduit à faire des suppositions incorrectes)

0
NHenry Messages postés 15113 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 22 avril 2024 331
15 oct. 2022 à 21:02

En regardant rapidement, ça ressemble à une structure de déclaration d'un tableau avec :

coeffs qui est le pointeur sur le tableau

num_coeffs est le nombre d'éléments dans le tableau.


0
Nounours18200 Messages postés 121 Date d'inscription samedi 30 mars 2013 Statut Membre Dernière intervention 8 avril 2024 8
Modifié le 17 oct. 2022 à 14:42

En regardant rapidement, ça ressemble à une structure de déclaration d'un tableau avec : 

coeffs qui est le pointeur sur le tableau

num_coeffs est le nombre d'éléments dans le tableau.

Oui c'est bien ce que je pense aussi, mais il faut quand même bien déclarer les valeurs quelque part me semble-t-il ?

Surtout que vu le rôle du programme, ces coefficients sont forcément des constantes qui doivent impérativement être connues avant que le programme démarre...

J'ai bien fait une recherche de "*coeffs" sur l'ensemble du code, mais ça ne se trouve qu'à cet endroit là, donc j'en arrive à conclure que le programme n'est pas complet !

Vu que je ne maîtrise pas l'instruction "struct", je vais la remplacer par une instruction:

const short fir_filter[N] = (

  (short) (valeur du coeff1),
  (short) (valeur du coeff2),
  (short) (valeur du coeff3),

  etc...

  (short) (valeur du coeffN),
  (short) (32768 * -0.635640527595689)
);

"

Qu'en pensez-vous ?

Merci pour vos avis,

0
yg_be Messages postés 22722 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 25 avril 2024 1 476
16 oct. 2022 à 18:01

Je pense préférable de faire une de ces actions:

  1. étudier à quoi sert l'instruction "struct"
  2. supprimer l'instruction "struct"

Qu'essaies-tu de faire, en réalité?

0
NHenry Messages postés 15113 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 22 avril 2024 331
16 oct. 2022 à 20:07

Il ne faut pas chercher "*coeffs", je pense plus que ça serait utiliser en "coeffs[...]" donc recherches juste "coeffs".

1

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Nounours18200 Messages postés 121 Date d'inscription samedi 30 mars 2013 Statut Membre Dernière intervention 8 avril 2024 8
18 oct. 2022 à 18:24

Bonjour,

Je connais l'exemple cité par [Dal], il fait partie des exemples que l'on trouve notamment dans certaines vidéos YouTube.

Dans mon cas c'est un peu plus compliqué, car il y a plus loin dans le programme (dans la void loop) une instruction qui n'accepte que des constantes (type "const") et rien d'autre (même pas des "int").

J'ai donc besoin d'avoir un tableau de constantes "fir1_Coeffs[n]", qui fera plusieurs centaines d'éléments (après la phase de tests actuelle): impossible d'écrire "const xxx...." à la main autant de fois...

Chacune de ces constantes est calculée à partir d'un tableau de nombre à virgules (float) qui s'appelle "float Coeffs_bruts[ ]", dans lequel je recopie une liste de coefficients bruts.

Chaque constante de rang n est égale à "(short) (32768  * Coeffs_brut[n])".

Il faut donc faire cette petite multiplication, mais ne pouvant pas modifier une constante, j'ai essayé de déclarer des "int" à la place (pour pouvoir faire la multiplication) et alors l'instruction qui n'accepte que des "const" plante à la compilation...

Bref, il faut donc que j'arrive à remplir mon tableau des constantes avec le résultat de la multiplication.

La seule piste que j'ai trouvé pour l'instant, serait de déclarer un tableau de "int", de le remplir en faisant les multiplications, puis de transformer le type de "int" vers "const", en espérant que l'instruction rebelle n'y voit que du feu...

ça vous semble jouable ? et si oui comment faire concrètement ?

Merci

0
yg_be Messages postés 22722 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 25 avril 2024 1 476
18 oct. 2022 à 19:31

Quelle est cette instruction qui n'accepte que des constantes?

0
Nounours18200 Messages postés 121 Date d'inscription samedi 30 mars 2013 Statut Membre Dernière intervention 8 avril 2024 8
18 oct. 2022 à 20:51

C'est l'instruction de démarrage du filtre FIR, celle-ci:

fir1.begin(fir1_Coeffs, length);
0
yg_be Messages postés 22722 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 25 avril 2024 1 476
18 oct. 2022 à 21:18

Je ne vois pas en quoi elle n'accepterait que des constantes.
As-tu la déclaration de cette fonction?

0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083 > yg_be Messages postés 22722 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 25 avril 2024
Modifié le 19 oct. 2022 à 02:09

@yg_be StatutContributeur

fir1.begin(fir1_Coeffs, length);

je pense que tu as reconnu que cette instruction n'est pas du C, mais du C++, elle fait appel à une méthode "begin" d'un objet "fir1".

https://github.com/PaulStoffregen/Audio/blob/master/filter_fir.h#L41

C'est une instance de la classe AudioFilterFIR (toujours si je me fie au code que j'ai trouvé, vu que notre ami ne poste pas le sien ou n'indique pas où le trouver) qui fait partie de la bibliothèque Teensy Audio Library, le "prototype" de cette méthode est :

void begin(const short *cp, int n_coeffs)

@Nounours18200 StatutMembre

Nounours18200, tu dis que tu dois générer tes coefficients à partir d'un tableau Coeffs_brut[].

Chaque constante de rang n est égale à "(short) (32768  * Coeffs_brut[n])".

(...)

La seule piste que j'ai trouvé pour l'instant, serait de déclarer un tableau de "int", de le remplir en faisant les multiplications, puis de transformer le type de "int" vers "const", en espérant que l'instruction rebelle n'y voit que du feu...

Non, "const" n'est pas un type, ce mot-clé indique juste que la méthode begin n'est pas sensée modifier ce contenu. Le type est pointeur sur short, et il te faut donc un tableau de short et non pas de int, à passer à l'instruction concernée.

Si ta compilation échoue :

  • tu dois avoir un message d'erreur informatif que tu devrais poster sur le forum pour qu'on arrête de jouer aux devinettes
  • tu dois avoir un code source avec ton code tentant de faire ce que tu as fait provoquant cette erreur, et que tu devrais aussi poster (au moins avec la partie concernée et avec les déclarations de variables et types que tu utilises), si tu veux qu'on t'aide utilement, en précisant quelles sont les lignes auxquelles se référe(ent) le(s) message(s) d'erreur(s) du compilateur
0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749 > [Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024
19 oct. 2022 à 10:09

Juste pour préciser ce que dit [Dal]

Le type est pointeur sur short

... et le type de pointeur est const short *.

Signification :

  • Un tel pointeur se comporte comme un short * en lecture (pour lire *cp, *cp + i ou cp[i]) mais il déclenche une erreur de compilation s'il est utilisé en écriture (donc pour modifier *cp, *cp + i ou cp[i]).
  • Quand une fonction attend un const short *, on peut lui passer a fortiori un short * car c'est un type moins contraint et cohérent en termes de types.

Syntaxe :

  • Écrire const T * est équivalent à écrire T const * : dans les deux cas, c'est la donnée de type T qui est constante.
  • Si on écrit T * const, la donnée pointée est constante, mais pas le pointeur lui même.
  • Si on écrit const T * const (ou T const * const) le pointeur et la donnée pointée sont constants.

Comment l'utiliser proprement :

  • Préciser qu'une fonction n'a besoin d'un accès qu'en lecture seule sur la donnée pointée à un intérêt la rend la fonction utilisable pour n'importe donnée constante (comme par exemple pour strlen).
    • Cela inclue notamment les chaînes de caractères explicitement initialisées dans le programme.
      #include <string.h>
      #include <stdio.h>
      
      int main() {
          const char *s = "hello world";
          printf("%s\n", s);
          return 0;
      }
    • Dans le cas des méthodes, ajouter le mot clé const derrière la parenthèse fermante du prototype indique que la donnée pointée par this (donc, l'instance courante) est constante.

      #include <iostream>
      
      class Foo {
        private:
      
          int value;
      
        public:
      
          Foo(int value0):
            value(value0)
          {}
      
          inline int get_value() const {
              return this->value;
          }
      };
      
      int main() {
          using namespace std;
          const Foo foo(42);
          cout << foo.get_value() << endl;
          return 0;
      }
  • En pratique, maintenir le pointeur constant n'a pas vraiment d'intérêt pratique, car on passe une recopie du pointeur à la fonction, c'est pour ça qu'en pratique on ne le met jamais.

et il te faut donc un tableau de short et non pas de int, à passer à l'instruction concernée.

  • C'est clairement le plus propre, mais pas nécessaire dans l'absolu. En effet, on peut passer un pointeur d'un autre type, ce qui force à faire un cast (voir static_cast et dynamic_cast). On peut même faire sauter le qualifieur "const" avec un const_cast. En effet, du point de vue de la librairie C++, du moment que la zone allouée est suffisamment grande et cohérente avec ce qu'attend la fonction, cela suffit.
  • Mais généralement, et en C++ encore plus qu'en C, changer le type d'un pointeur est dans la grande majorité des cas une très mauvaise idée, à moins de savoir ce qu'on fait. C'est pourquoi, comme le dit [Dal], il vaut mieux s'assurer qu'on passe un pointeur qui a le bon type.

Bonne chance

0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié le 19 oct. 2022 à 11:28

Pour la résolution du problème de @Nounours18200 StatutMembre, comme le dit très clairement mamiemando :

Quand une fonction attend un const short *, on peut lui passer a fortiori un short * car c'est un type moins contraint et cohérent en termes de types.

Dès lors, le petit programme qui suit compile et s'exécute très bien en C++ et illustre ce que tu pourrais faire si tu tiens à générer ces données à l'exécution :

#include <iostream>
#include <ctime>
#include <cstdlib>

struct fir_filter {
  short *coeffs;       // short means a range from -32 768 to 32 767
  short num_coeffs;    // num_coeffs must be an even number, 4 or higher
};

void begin(const short *cp, int n_coeffs) {
        (void) cp;
        (void) n_coeffs;
        std::cout << "Je compile et m'exécute correctement en C++" << std::endl;
}

#define NCOEFFS (300)

int main() {
        double Coeffs_brut[NCOEFFS];

        // simuler la création d'un tableau préexistant de 300 nombres
        // décimaux Coeffs_brut[] entre -1 et 1
        srand(time(NULL));
        for (int n = 0; n < NCOEFFS; n++)
                Coeffs_brut[n] = -1.0 + (rand() / (RAND_MAX / 2.0));

        struct fir_filter myfir;

        myfir.num_coeffs = NCOEFFS;
        myfir.coeffs = (short *) malloc(sizeof(short) * NCOEFFS);
        for (int n = 0; n < NCOEFFS; n++)
                myfir.coeffs[n] = (short) (32768  * Coeffs_brut[n]);

        // simulation de l'appel à la méthode begin d'une instance 
        // de la classe AudioFilterFIR avec une fonction de prototype
        // identique
        begin(myfir.coeffs, myfir.num_coeffs);

        // quant on n'a plus besoin des données sur myfir.coeffs
        free(myfir.coeffs);

        return 0;
}

Je suppose que ton tableau Coeffs_brut[] de plusieurs centaines de coefficients bruts décimaux préexiste. Là je simule son contenu en générant aléatoirement des double entre -1 et 1 dans un tableau de 300 éléments.

Tu déclares ta struct fir_filter et alloues la mémoire nécessaire à son membre .coeffs qui est de type short *

Tu peux ensuite faire ton calcul dans une boucle pour générer à l'exécution le tableau de short, que tu peux passer à la fonction begin.

Le mot clef const signifie seulement qu'à l'intérieur de la fonction begin, le programme ne peut pas modifier ce qui est passé, et cela ne signifie pas que tu doives passer un tableau de const short.

Note cependant qu'en embarqué, l'abus d'allocation de mémoire sur le tas n'est sans doutes pas recommandé, et que tu pourrais, comme dans le programme d'exemple livré avec la bibliothèque, faire un précalcul, avec un programme séparé enregistrant ces données dans un fichier séparées par des virgules, pour les inclure en dur dans ton code avec une directive #include en utilisant une technique similaire à celle que j'ai commentée dans mes messages #6 et #7

Cela permet de regénérer ce fichier s'il doit changer souvent sans avoir à toucher au reste du code.

Si tu fais cela, tu n'auras plus à avoir le tableau Coeffs_brut[] dans ton code, ni faire une allocation de mémoire pour le membre .coeffs de la struct. Cela réduira la taille de ton code et la mémoire qu'il utilise.

0
Nounours18200 Messages postés 121 Date d'inscription samedi 30 mars 2013 Statut Membre Dernière intervention 8 avril 2024 8
Modifié le 20 oct. 2022 à 09:35

tu dois avoir un code source avec ton code tentant de faire ce que tu as fait provoquant cette erreur, et que tu devrais aussi poster (au moins avec la partie concernée et avec les déclarations de variables et types que tu utilises), si tu veux qu'on t'aide utilement, en précisant quelles sont les lignes auxquelles se référe(ent) le(s) message(s) d'erreur(s) du compilateur

Je n'ai aucun problème à poster mon code source , d'autant plus qu'il n'en est qu'au début et loin d'être fonctionnel, donc le voici.

Code source :

/*
\\DS1821\Datas\ELECTRONIQUE\TEENSY\Essais pgm\sketch_FIR_006\sketch_FIR_006.ino
*/
/*
Dans cette version 006, on remplace la déclaration"const short fir1_Coeffs[length];" par
"int" car les constantes doivent être définies avant les void, sinon ce ne sont pas des
constantes: cela génère un warnong à la compilation.
Mais génère une ereur ligne 142 sur "fir1.begin(fir1_Coeffs, length);" j'essaie de remplacer length par 57

Dans cette version 004 on crée un tableau de nombre à virgule listant tous les coefficients
donnés par les programmes de calcul des filtres, puis chacun de ces coefficient est
transformé en "constante Short" et multiplié par 32768, grâce à une boucle:
ainsi on peut recopier directement la liste des coefficients donnée par les programmes
de calcul en UNE SEULE FOIS.

Dans cette version 003 on rentre les 57 coefficients donnés par le site arc.id.au
à la place des 5 coefficients données par T-Filter, afin de pouvoir avoir un
test plus reésentatif.
Ce filtre de KAISER-BESSEL a été calculé avec les conditions suivantes:
Fa=0Hz    Fb=20000Hz
M(odd) length=57 pts
dF/2=1416Hz non modifiable sur le site
Fs=44100Hz
Att=60dB
*/

/*
On repart du sketch_002b qui passee à la compilation, pout y intégrer l'initialisation
de 57 coefficients depuis une liste, tel qu'imaginé dans sketch_004.ino
Dans cette verion 002 on rajoute les lignes telles que définies dans la vidéo:
https://www.youtube.com/watch?v=uf0KLkB93eY
qui montre:
-comment rentrer les coefficients du filtre,
-comment initialiser les objets créés par l'Audio Design Tool
-comment créer le void setup,

*/

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h> 
#include <SerialFlash.h>
#include <Bounce.h>
#include <filter_fir.h>

//This section has been copied from the Teensy FIR example
// If this pin is grounded the FIR filter is turned off
// which just passes the audio sraight through
// Don't use any of the pins listed above
#define PASSTHRU_PIN 1	//donc si je comprends bien il faut mettre la pin 1 à +3.3V ??
// If this pin goes low the next FIR filter in the list
// is switched in.
#define FILTER_PIN 0 //if I understand correctly, the input of the Filter is pin 0
/*
These lines are followed by two "debounce" instrutions that are unknown to me,
// seem to manage the buttons, that I don't use in my project, so I remove the "bounce" lines
*/

// GUItool: begin automatically generated code
AsyncAudioInputSPDIF3    spdif_async1;   //xy=145.3333282470703,121.33333587646484
AudioFilterFIR           fir1;           //xy=353.25,121.25
AudioOutputI2S           i2s1;           //xy=569.25,126.25
AudioConnection          patchCord1(spdif_async1, 0, fir1, 0);
AudioConnection          patchCord2(fir1, 0, i2s1, 0);
AudioControlSGTL5000     sgtl5000_1;     //xy=360.25,265.25
// GUItool: end automatically generated code


const int length = 57;	// définition de la longueur du filtre, i.e le nombre de coefficients

// Liste des 57 coefficients bruts donnés par lesite arc.id.au de calcul des fltres
float Coeffs_Bruts[] = { -0.000220, 0.000395, -0.000589, 0.000753, -0.000817, 0.000696, -0.000308,
 -0.000416, 0.001510, -0.002950, 0.004644, -0.006416, 0.008012, -0.009109, 0.009343, -0.008340, 
0.005765, -0.001367, -0.004979, 0.013234, -0.023175, 0.034397, -0.046329, 0.058275, -0.069471, 
0.079153, -0.086631, 0.091355, 0.907029, 0.091355, -0.086631, 0.079153, -0.069471, 0.058275, 
-0.046329, 0.034397, -0.023175, 0.013234, -0.004979, -0.001367, 0.005765, -0.008340, 0.009343, 
-0.009109, 0.008012, -0.006416, 0.004644, -0.002950, 0.001510, -0.000416, -0.000308, 0.000696, 
-0.000817, 0.000753, -0.000589, 0.000395, -0.000220};

// The declaration below seems similar to the "struct" declaration used in the Teensy FIR Filter example
// but the "const" approach has been said to be more optimized than the éstruct" approach
const short fir1_Coeffs[length]; // définition du tableau de constantes que l'on va calculer
								// à partir de la liste "Coeffs_Bruts" du dessus
								



//const int myInput = AUDIO_INPUT_MIC;  // removed from the Teensy FIR example
const int myInput = AUDIO_INPUT_LINEIN; // because my correct input is not MIC
			// d'autres exemples utilisent myInput = AUDIO_INPUT_LINEIN;
			// avec un diagramme AudioDesignTool dans le domaine digital aussi
			// par ex le prog "Invert Phase Audio Signal"
			
unsigned long last_time = millis(); // copied from the Teensy FIR example

void setup()
{
	Serial.begin(9600);	//copied from the Teensy FIR Filter example
	delay(300);			//copied from the Teensy FIR Filter example
	
	//transfère les Coeffs_Bruts dans le tableau LPF_Coeffs, sous forme "short"
	for (int i=1 ; i<=length ; i++) {
		fir1_Coeffs[i] == (short) (32768 * Coeffs_Bruts[i]);
		
		/* cette boucle if ne passe pas à la compilation, faudra demander pourquoi
		if (i == length){
			Serial.println("Tableau fir1_Coeffs initialisé");
			Serial.println("Length= ", length);
		}
		*/
		
	} //fin du remplissage du tableau fir1_Coeffs

	
	pinMode(PASSTHRU_PIN, INPUT_PULLUP); //probably activates the Pull-Up resistor because PASSTHRU_PIN is defined as an input
	pinMode(FILTER_PIN, INPUT_PULLUP);   //probably activates the Pull-Up resistor because FILTER_PIN is defined as an input

	//setup the audio shield
	AudioNoInterrupts(); // added to the Teensy FIR example: recommended in the video 
						 // what are the benefit ???
					     // mentionned at the very beginning
	
	AudioMemory(16); /*
		The numberBlocks input specifies how much memory to reserve for audio data. 
		Each block holds 128 audio samples, or approx 2.9 ms of sound. 
		*/
	// Enable the audio shield. select input. and enable output
	sgtl5000_1.enable(); //added: was it missing in the Teensy example
	sgtl5000_1.inputSelect(myInput); //il faut un "i" minuscule à inputSelect...
	/*
							dois-je mettre spdif_async1 ou bien LINEIN comme dans la video ???
							Je pense spdif_async1 puisque c'est le nom donné à AsyncAudioInputSPDIF3
							qui remplace le AudioInputI2S de la video
							Pas sûr car le pgm "Invert Phase Audio Signal" utilise bien
							AUDIO_INPUT_LINEIN, donc je laisse myInput défini à 
							AUDIO_INPUT_LINEIN
							*/
	sgtl5000_1.lineInLevel(5);
	sgtl5000_1.unmuteHeadphone(); 
	sgtl5000_1.volume(0.5); // I have a doubt about the parameter: is it correct ???
	
	fir1.begin(fir1_Coeffs, length); //initialize the fir filter 'fir1" declared before
	AudioInterrupts();	//as recommended in the video
	
	// Warn on the Serial Monitor if the passthru pin is grounded
	if(!digitalRead(PASSTHRU_PIN)) {
		Serial.print("PASSTHRU_PIN (");
		Serial.print(PASSTHRU_PIN);
		Serial.println(") is grounded");
	}
	
	// Warn if the filter pin is grounded: what for ??
	//it is supposed to be the filter input, isn't it ?
	if(!digitalRead(FILTER_PIN)) {
		Serial.print("FILTER_PIN (");
		Serial.print(FILTER_PIN);
		Serial.println(") is grounded");
	} 
  
	//ADDED to the Teensy FIR example (as recommended by the video)
	fir1.begin(fir1_Coeffs, 57); //Iniitialize the LPF filter as recommended by the AudioDesignTool
	
	Serial.print("fir1 Filter: begin done"); // displays on the Serial Monitor
	Serial.println("setup done");

}	
	
void loop()	//la video ne dit pas quoi faire dans cette boucle loop, 
			//et l'exemple de Teensy pas grand chose !
{

  // print information about resource usage
  // Proc = 18 (18),  Mem = 4 (5)
	if (millis() - last_time >= 2500) {
		Serial.print("Proc = ");
		Serial.print(AudioProcessorUsage());
		Serial.print(" (");    
		Serial.print(AudioProcessorUsageMax());
		Serial.print("),  Mem = ");
		Serial.print(AudioMemoryUsage());
		Serial.print(" (");    
		Serial.print(AudioMemoryUsageMax());
		Serial.println(")");
		last_time = millis();
	}
}

Le programme compile avec avec un Warning, et j'ai dû mettre en commentaire une boucle for car elle générait une erreur.

Comme entre-temps j'ai modifié le programme pour qu'il passe à la compilation, il ne me génère plus que le warning ci-après, dont je me passerais volontiers:

\\DS1821\Datas\ELECTRONIQUE\TEENSY\Essais pgm\sketch_FIR_006\sketch_FIR_006.ino:83:13: warning: uninitialized const 'fir1_Coeffs' [-fpermissive]
 const short fir1_Coeffs[length]; // définition du tableau de constantes que l'on va calculersuivant:

En attendant votre réponse, je vais étudier la réponse précédente sur le struct, const et les pointeurs (je ne maîtrise pas ces concepts !),

Merci

0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié le 19 oct. 2022 à 15:06

ligne 70, au lieu de const int length = 57; fais :

#define LENGTH (57)

en ligne 83, au lieu de ce que tu as écrit : const short fir1_Coeffs[length]; fais :

short fir1_Coeffs[LENGTH];

(sans const, car dans ton code tu ne traites pas ce tableau comme ayant un contenu constant, puisque tu le modifies)

Utilise aussi cette macro à la place de length en ligne 103 pour la borne de la boucle for.

Comme LENGTH est aussi la taille de ton tableau float Coeffs_Bruts[], tu pourrais aussi explicitement l'indiquer, juste pour être cohérent.

En ligne 104 remplace les == (opérateur d'égalité) par = (affectation) comme ceci :

fir1_Coeffs[i] = (short) (32768 * Coeffs_Bruts[i]);

(sinon, tu n'affectes rien à ton tableau fir1_Coeffs[])

Je n'ai pas bien compris si tu postais le résultat de la compilation du code que tu as posté ou pas, puisque tu dis que tu l'as modifié entre temps. Ce qui nous intéresse, comme je l'ai mentionné, c'est de disposer des messages d'erreur dont tu parlais et du code qui les génère.

Sur ce que tu as commenté et qui échouerai à la compilation tu n'indiques pas précisément de quoi il s'agit, mais en supposant qu'il s'agisse de ceci qui se trouve dans la boucle for de calcul :

		/* cette boucle if ne passe pas à la compilation, faudra demander pourquoi
		if (i == length){
			Serial.println("Tableau fir1_Coeffs initialisé");
			Serial.println("Length= ", length);
		}
		*/

Ce n'est pas le code d'une "boucle", mais d'un test.

Ce code est, par contre inséré dans la boucle for qui se termine, de toutes façons quand i arrive à la borne supérieure. Il est donc plus efficace de mettre ceci en dehors de la boucle for, et après celle-ci et sans nécessité de tester, puisque l'exécution est arrivée là par définition.

Serial.println("Tableau fir1_Coeffs initialisé");
Serial.println("Length = " + std::to_string(LENGTH));

Si la compilation échouait, c'était probablement à cause du 2ème Serial.println qui ne respecte pas les prototypes possibles pour cette méthode println :

https://www.arduino.cc/reference/en/language/functions/communication/serial/println/

Là aussi on aurait aimé que tu indiques le message d'erreur.

La prochaine fois, stp, au lieu de poster 400 lignes de trace de compilation, identifie les avertissements et erreurs générés qui s'y trouvent et poste les. Cela soulagera la lecture du fil :-)

0
Nounours18200 Messages postés 121 Date d'inscription samedi 30 mars 2013 Statut Membre Dernière intervention 8 avril 2024 8
19 oct. 2022 à 15:35

Je viens de résoudre le problème en comprenant mon erreur: je n'avais pas compris le rôle du mot-clef "const"...

La fonction en question fonctionne avec des "short", dont je déclare un tableau de "int short" que j'initialise dans le void setup à partir de la liste des coefficients float.

ça me laisse du temps pour étudier vos réponses relatives aux pointeurs, dont je vais certainement avoir besoin dans ma 2ème étape.

Merci à tous pour votre aide !

0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié le 20 oct. 2022 à 14:26

Salut Nounours18200,

En C (ou C++) "short" est la version raccourcie du type "int short". Les deux sont exactement synonymes et donc tu peux déclarer un tableau de "short" ou de "int short" sans que cela fasse aucune différence.

Dans mon dernier message, je te rappelais non seulement ton erreur concernant l'usage de const, que tu as donc bien comprise désormais, mais aussi d'autres :

https://forums.commentcamarche.net/forum/affich-37708741-definition-d-un-struct-avec-pointeurs#16

en particulier la confusion d'opérateur (== au lieu de =) faisant que, de toutes façon, ton code n'affectait rien au contenu du tableau calculé et ton tableau restait non initialisé et avec un contenu constitué de valeurs arbitraires au lieu de celles que tu as pris soin de calculer.

Veille à bien corriger cela aussi. Tu aurais intérêt, aussi, à traiter les autres problèmes que je signale dans ce message #16, à mon sens.

0