lecture d'un fichier wav en C

lecture d'un fichier wav en C - C - Programmation

Marsh Posté le 16-05-2008 à 14:00:44    

Bonjour à tous;
Je suis débutante en C et je voudrais lire un fichier wav qui je connais pas sa taille des données( sans entete).  
mon brobleme est de savoir comment je peux copier ces données, à partir de fichier wav, dans un tableau ( applé sorite)
 
1/ comment je peux tirer la taille de mon fichier? (Taille)
2/ qulle sont les erreurs de mon programme situ ci-dessous?
 

Code :
  1. #include <stdio.h>
  2. #define NB_BYTE Taille // Taille que je vais la calculer
  3. main()
  4. unsigned char wav[Taille]; 
  5. unsigned char sortie[Taille - 44]; /
  6. unsigned char *audio_data;
  7. int fd;
  8. fd = int open("theevent-zoom.wav", O_RDWR);// faire un test sur l'open du fichier  
  9. if (fd != NULL)
  10.     {
  11. int fread(wav, NB_BYTE, fd);// faire un test sur le nb d'octets lu  
  12. audio_data = &wav[44];// audio_data pointe sur le début de données audio ( la taille de l'entet =44 octets
  13. // &wav[44] pointe sur le début des données 43 octets apres l'en-tete  
  14. int c_memcpy(ailleurs, &wav[44], NB_BYTE-44); // copie le contenu du fichier ver le tableau ( ailleurs)
  15. int fclose(fd);
  16.     }
  17. }


 
j'ai besoin de votre aide svp
merci d'avance.


Message édité par silia le 16-05-2008 à 14:03:57
Reply

Marsh Posté le 16-05-2008 à 14:00:44   

Reply

Marsh Posté le 16-05-2008 à 14:47:59    

Code :
  1. #define NB_BYTE Taille // Taille que je vais la calculer


 
Mauvaise pratique : "Taille" est une variable, définir une macro de cette façon pour masquer cette variable n'apporte rien sinon des problèmes de lisibilité de programme.
 

Code :
  1. main()


 
Invalide.
Il n'y a que deux prototypes de main() possibles :
   int main(void);
et
   int main(int, char**);
 

Code :
  1. unsigned char wav[Taille];
  2. unsigned char sortie[Taille - 44]; /


 
Outch.
Qu'est-ce que "Taille" ?
Cette variable n'est définie nul part. Et même si elle l'était, c'est une mauvaise idée d'utiliser les VLA (Variable-Length Array), sans compter que très peu de compilateur les implémentent correctement (nouvelle fonctionnalité de la norme C99 qui n'est pas encore implémentée partout).
Il faut d'abord calculer la taille, puis allouer de la mémoire de taille adéquate, avec les fonctions d'allocations malloc ou calloc.
 

Code :
  1. fd = int open("theevent-zoom.wav", O_RDWR);// faire un test sur l'open du fichier


Incorrect.

  • "int open" ne veut rien dire, tu confonds prototypage et utilisation de fonction. Bref, enlève le "int".
  • n'utilise pas "open" à moins de savoir exactement ce que tu fais : c'est une fonction système. Utilise fopen() à la place.


Code :
  1. if (fd != NULL)


Correct si tu utilises fopen() (et dans ce cas ta variable "fd" est un FILE* et non un int), incorrect avec open.
La fonction open() retourne un descripteur de fichier >= 0, en cas d'échec d'ouverture, la valeur retournée est -1.
Lire la manpage sur cette fonction pour plus d'information.
 

Code :
  1. int fread(wav, NB_BYTE, fd);// faire un test sur le nb d'octets lu


Encore un problème de confusion prototype/utilisation de fonction.
 
Un prototype de fonction permet de la définir en vue d'une utilisation ultérieure.
Par exemple, le prototype de la fonction fread() est :
   size_t fread(void *ptr, size_t  size,  size_t  nitems,  FILE *stream);
   (tu n'as pas à l'écrire toi-même, ce prototype est défini dans stdio.h)
 
Et pour utiliser la fonction, il suffit d'écrire :
   fread(pointeur sur lequel fread va écrire, taille d'un item, nombre d'items à lire, descripteur de fichier);
 
De plus, tu ne peux pas utiliser fread() avec un descripteur de fichier ouvert avec open().
De même, tu ne peux pas utiliser read() avec un descripteur de fichier ouvert avec fopen().
 
Ici la solution est simple : utilise fopen() plus haut avec un descripteur de fichier en FILE*.
 

Code :
  1. audio_data = &wav[44];// audio_data pointe sur le début de données audio ( la taille de l'entet =44 octets
  2. // &wav[44] pointe sur le début des données 43 octets apres l'en-tete


Ouh la, je ne suis pas sûr de comprendre ce que tu essaies de faire ici.
 
 
etc.
 
 
Je te suggère à ce stade de faire un tour sur des sites de tutoriaux ou de te procurer un bon livre de C.
 
Comme livre, il y a le sempiternel "Le Langage C", par Kernighan et Ritchie (bouquin surnommé affectueusement "le K&R" ). C'est la bible, c'est très simple d'utilisation et très bien expliqué.
 
Comme sites internet, tu peux faire un tour ici : http://mapage.noos.fr/emdel (plein de conseils, quelques liens vers des cours complets en lignes, etc).

Reply

Marsh Posté le 16-05-2008 à 14:59:24    

Merci Elmoricq de me repondre.
Pour (la variable) Taille, je l'ai utilisée pour vous éxpliquer qu' est une donnée que je dois la calculer avec un programme qui j'arrive pas à le faire.
 
Je resume mes questions:
1/ comment je peux tirer la taille d'un fichier wav?  
2/ comment on copie une partie de ce fichier et la mettre da,s un tableau.
 
Merci beaucoup Elmoricq

Reply

Marsh Posté le 16-05-2008 à 15:10:37    

Pour lire un fichier de taille inconnue, il y a deux approches :

  • lecture par bloc de données, dans un tableau alloué dynamiquement. On agrandit le tableau au fur et à mesure de la lecture, par gros blocs. Exemple (à ne pas reprendre tel quel, juste pour expliquer l'idée) : j'alloue 20kB dans un tableau, et je lis à coup de fread() par blocs de 512o. Une fois le tableau rempli, je l'agrandi à 40kB, et je poursuis ma lecture. S'il est rempli, je l'agrandis à 60kB, et ainsi de suite.  
  • Tu utilises fseek() pour te positionner en fin de fichier. En faisant une différence ftell(fin de fichier) - ftell(début de fichier), tu connais la taille totale du fichier, tu n'as plus qu'à te remettre en début, allouer ton tableau à la bonne taille, et commencer la lecture.  


Je n'aime pas la seconde méthode, parce que ça te force à parcourir 2x le fichier, ce qui est coûteux pour les gros fichiers... comme les .WAV, justement. Préconise la première méthode, qui te fera voir en plus des fonctions utiles en C, comme malloc(), realloc(), et consors.
 
Pour la lecture de données, fread() fait parfaitement l'affaire ici.

Reply

Marsh Posté le 16-05-2008 à 15:16:36    

Merci Elmoricq de m'aider

Reply

Marsh Posté le 18-05-2008 à 19:38:55    

Bonsoir à tous
Mr Elmoricq, j'ai consacré les deux derniers jours pour lire des cours de C et j'ai cherché des fonctions qui réalisent mon programme et en fin j'ai reussi de faire le faire. Mais malheureusemant à la complation j'ai des erreurs:
 

Code :
  1. c:\documents and settings\administrateur\mes documents\visual studio 2008\projects\test\test\lire wav.cpp(12) : warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
  2.         c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(237) : voir la déclaration de 'fopen'
  3. c:\documents and settings\administrateur\mes documents\visual studio 2008\projects\test\test\lire wav.cpp(18) : error C2440: '=' : impossible de convertir de 'void *' en 'char *'
  4.         La conversion de 'void*' en pointeur vers non 'void' nécessite un cast explicite


 
es ce que tu peux m'aider svp
 

Code :
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. char header[44];
  4. char *données  = NULL;
  5. int i = 0;
  6. int main(int argc, char *argv[])
  7. {
  8.     FILE *f = fopen("theevent-zoom.wav", "rb" );
  9. if (f != NULL)
  10.    {
  11.     fseek (f, 0, SEEK_END);
  12.     int taille = ftell(f) - 44;
  13.     fseek (f, 0, SEEK_SET);
  14.     data = malloc(taille);
  15. if (données != NULL)
  16. {
  17.     fread(header,44,1,f);// le curseur est à 44  
  18.     fread(données,sizeof *data,taille/sizeof *data,f);// lire les données apres les 44
  19.     fclose(f);
  20.           for (i = 0 ; i < taille-1 ; i++)
  21.         {
  22.             printf("%ld \n", données[i]);
  23.         }
  24.         for (i = 0 ; i <43 ; i++)
  25.         {
  26.             printf("%ld \n",  header[i]);        }
  27. }
  28. fclose (f); f = NULL; 
  29. }
  30. else
  31.    {
  32.       perror ("theevent-zoom.wav" );   }
  33. }


Message édité par silia le 18-05-2008 à 19:52:32
Reply

Marsh Posté le 18-05-2008 à 22:29:10    

1. n'est pas une erreur, mais un warning qui indique que la fonction fopen ne doit plus être utilisée avec l'environnement visual studio (2005 ou 2008).  
Si tu ne souhaites plus l'utiliser, il te suffit d'utiliser fopen_s à la place de fopen, mais cela aura pour conséquence de rendre ton code non portable.
Si tu souhaites l'utiliser quand même et ne pas avoir le warning, il te suffit de définir _CRT_SECURE_NO_WARNINGS dans les propriétés de ton projet (bouton droit sur le projet, propriétés, tu vas dans l'onglet C/C++ , section préprocesseur, et dans les définitions du préprocesseur, tu rajoutes _CRT_SECURE_NO_WARNINGS
2. va avec 1.
3. Bizarre, normalement, pas besoin de cast mais je ne vois pas la déclaration de "data". L'aurais tu oublié ?
 
- Je remarque un truc supplémentaire, tu as déclaré des variables avec des caractères interdits : "données" ne devrait pas fonctionner. Les seuls caractères autorisés pour un nom de variables sont les caractères alphanumériques et le caractère "_" , et de plus, on ne peut pas commencer un nom de variable par un chiffre ( a2 est autorisé, mais pas 2a).
 
- Ta fonction main doit retourner une valeur.


Message édité par xilebo le 18-05-2008 à 22:34:22
Reply

Marsh Posté le 18-05-2008 à 22:52:41    

Merci beaucoup xilebo, j'ai vraiment besoin d'aide.
pour la fonction fopen j'ai réglé le warning comme yu m'a dis.
 
la 3 eme erreur reste toujour, je pense que se trouve au niveau d'utilisation de ( malloc)
 

Code :
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. char header[44];
  4. char *data  = NULL;
  5. int i = 0;
  6. int main(int argc, char *argv[])
  7. {
  8.     FILE *f = fopen("theevent-zoom.wav", "rb" );
  9. if (f != NULL)
  10.    {
  11.     fseek (f, 0, SEEK_END);
  12.     int taille = ftell(f) - 44;
  13.     fseek (f, 0, SEEK_SET);
  14.     data = (char) malloc(taille);
  15. if (data != NULL)
  16. {
  17.     fread(header,44,1,f);// le curseur est à 44  
  18.     fread(data,sizeof *data,taille/sizeof *data,f);// lire les données apres les 44
  19.     fclose(f);
  20.         for (i = 0 ; i < taille-1 ; i++)
  21.         {
  22.             printf("%ld \n", data[i]);
  23.         }
  24.         for (i = 0 ; i <43 ; i++)
  25.         {
  26.             printf("%ld \n",  header[i]);        }
  27. }
  28. fclose (f);
  29. }
  30. else
  31.    {
  32.       perror ("theevent-zoom.wav" );   }
  33. return(0);
  34. }


 

Code :
  1. c:\documents and settings\administrateur\mes documents\visual studio 2008\projects\test\test\lire wav.cpp(14) : error C2440: '=' : impossible de convertir de 'char' en 'char *'
  2.         La conversion d'un type intégral en type pointeur nécessite reinterpret_cast, un cast de style C ou un cast de style fonction
  3. Le journal de génération a été enregistré à l'emplacement "file://c:\Documents and Settings\Administrateur\Mes documents\Visual Studio 2008\Projects\test\test\Debug\BuildLog.htm"
  4. test - 1 erreur(s), 0 avertissement(s)
  5. ========== Génération : 0 a réussi, 1 a échoué, 0 mis à jour, 0 a été ignoré ==========


 
Merci une autre fois


Message édité par silia le 18-05-2008 à 22:54:00
Reply

Marsh Posté le 19-05-2008 à 00:54:36    

Heu, .cpp est l'extension pour compiler en C++, pas étonnant qu'il te râle pour des conversions void * => char *. C++ != C.

Reply

Marsh Posté le 19-05-2008 à 13:01:21    

tpierron a écrit :

Heu, .cpp est l'extension pour compiler en C++, pas étonnant qu'il te râle pour des conversions void * => char *. C++ != C.


 
O non :(  
je suis sous visual C++ 2008 et comment je compile en C?

Reply

Marsh Posté le 19-05-2008 à 13:01:21   

Reply

Marsh Posté le 19-05-2008 à 13:10:55    

Tu sauvegardes des fichiers avec l'extension .c et tu les ajoutes à la main au programme (fichiers sources / ajout d'un élément existant) . enfin, c'est ce que je fais avec Visual 2005.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed