Partage
  • Partager sur Facebook
  • Partager sur Twitter

Le format WAVE

Comment l'exploiter !

16 décembre 2009 à 9:06:52

Bonjour,
Pour les valeurs codées sur 16 bits tu indiques que la valeur peut aller de -32268 à 32267. Ne serait-ce pas plutôt de -32767 à +32767 ?


Ha bien vu en effet :p mais pour être exact je pense que c'est de -32768 à +32767
  • Partager sur Facebook
  • Partager sur Twitter
16 décembre 2009 à 11:38:35

Intéressant le tuto :)
Une petite question : c'est normale que la taille du fichier générer fait 2.52 MB pour 14 seconde ?
Il y a un petit warning a corriger aussi, ligne 221:
\Desktop\sd\main.c||In function `main':|
\Desktop\sd\main.c|221|warning: missing braces around initializer|
\Desktop\sd\main.c|221|warning: (near initialization for `wav.riff')|
\Desktop\sd\main.c|221|warning: missing initializer|
\Desktop\sd\main.c|221|warning: (near initialization for `wav.taille')|
||=== Build finished: 0 errors, 4 warnings ===|
  • Partager sur Facebook
  • Partager sur Twitter
16 décembre 2009 à 12:29:09

Citation : Azimut2

Bonjour,
Pour les valeurs codées sur 16 bits tu indiques que la valeur peut aller de -32268 à 32267. Ne serait-ce pas plutôt de -32767 à +32767 ?


Non les valeurs sont bien codées sur -32768 - 32767 ;)

Petit test rapide (C99) :

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

int main(void) {
	printf("%d\n", INT16_MAX);
	printf("%d\n", INT16_MIN);
	return EXIT_SUCCESS;
}

Nous donne :

32767
-32768


@ sercus i (tiens j'avais jamais vu que yavais un 'i' dans ton pseudo :euh: ) :
Le warning n'est pas vraiment important c'est GCC qui le met ... mais c'est tout à fait correct ;)
Pour le faire disparaître tu mets juste une deuxième accolade dans l'initialisation de la structure parce que j'initialise un tableau :)

Sinon pour la taille du fichier oui c'est normal ;)
Lis mon premier post je l'ai expliqué :)
Comme c'est un format non compressé si tu mets en stéréo, que tu codes ton signal sur 16 bits et en 44.1 khz ça nous donnera :

<math>\(14 * 44100 * 2 * \frac{16} {8} = 2469600\)</math>

Au final il faut ajouter les 44 octets de la structure ce qui nous donne : 2469644 octets -> 2.47 Mo
Pourquoi on a pas la même taille ? Aucune idée :p
Chez moi le fichier fait bien la taille que j'ai indiquée :euh:
  • Partager sur Facebook
  • Partager sur Twitter
16 décembre 2009 à 14:11:27

Citation

Sinon pour la taille du fichier oui c'est normal ;)
Lis mon premier post je l'ai expliqué :)
Comme c'est un format non compressé si tu mets en stéréo, que tu codes ton signal sur 16 bits et en 44.1 khz ça nous donnera :

<math>\(14 * 44100 * 2 * \frac{16} {8} = 2469600\)</math>
Au final il faut ajouter les 44 octets de la structure ce qui nous donne : 2469644 octets -> 2.47 Mo


Ok, c'est plus claire maintenant on comprend comment la taille est calculée, merci pour toutes ces précisions .

Citation

Pourquoi on a pas la même taille ? Aucune idée :p
Chez moi le fichier fait bien la taille que j'ai indiquée :euh:


Je vois que chez toi la taille est affichée en M octets alors que chez moi c'est en M bytes, mon avis sur certaines architectures le byte ne doit pas faire la même taille qu'un octet, il peut varie entre 6,7,8,9 bits alors qu'un octet fait toujours 8 bits, je pense que c'est la raison .
  • Partager sur Facebook
  • Partager sur Twitter
17 décembre 2009 à 5:14:32

J'ai créé des fichiers correspondants aux notes de musiques (1 fichier par note) mais j'ai aussi un petit "grésillon" à la fin de la note. Comme remarqué plus haut, la dernière sinusoïde est incomplète. Pour éviter ce problème j'ai modifié la durée pour ne prendre en compte qu'un nombre entier de sinusoïdes.

Citation

wav->subTaille2 = wav->ByteRate * (ceil(N_SEC/xperiode)*xperiode)+2;


Maintenant il me reste à régler un autre problème.
Quand je lance la lecture de plusieurs fichiers à la suite par plusieurs sndPlaySound consécutifs, j'ai encore un petit "grésillon" derrière chaque note.
  • Partager sur Facebook
  • Partager sur Twitter
17 décembre 2009 à 8:51:59

Ca vient aussi du fait que tes sinusoïdes ne doivent pas "se suivre" correctement comme expliqué ci-dessus :)
Il faut que la fin de la première sinusoïde soit le prolongement de la seconde sinon il y a des grésillons ;)
  • Partager sur Facebook
  • Partager sur Twitter
17 décembre 2009 à 11:45:51

Non les valeurs sont bien codées sur -32768 - 32767


Oui sur ce point je suis d'accord avec toi, mais la question c'est : pourquoi dans ton programme multiplies-tu le sinus par 32267 alors que le maximum est 32767?
Cela à un rapport avec la qualité du son? :euh:

data[cpt] = convertirEndian(sin(val) * 32267);
  • Partager sur Facebook
  • Partager sur Twitter
17 décembre 2009 à 12:01:33

Non en fait c'est l'amplitude des sinusoïdes. Si tu préfère c'est le volume du son ^^
Si tu multiplies par un facteur plus petit tu obtiendras un son plus faible ;)
Par contre pour obtenir un son plus élevé (et je ne rentrerai pas dans les détails) c'est plus complexe.
  • Partager sur Facebook
  • Partager sur Twitter
17 décembre 2009 à 19:47:16

Non en fait c'est l'amplitude des sinusoïdes. Si tu préfère c'est le volume du son


Merci pour cette précision ;)


Sinon j'ai une autre question, en fait je suis entrain d'essayer de lire des fichiers wave en streaming avec les fonctions de base de la SDL. Jusque là tout va bien, cependant ces fichiers wave sont encodés en 8 bits et j'aimerais les lire en 16 bits...

Pour ce faire je récupère chaque octets que je souhaite lire et je lui soustrait 128 (pour signer la courbe donc) et ensuite je le multiplie par 256. Histoire d'avoir un bout de code sous les yeux, voilà en gros ce que je fait :

for(i = 0; i < nombreOctetALire; i+=2)
{
    octet = fgetc(fichier);
    octet = (octet - 128) * 256;
    //Après quoi je l'ajoute dans un tableau de char non signe pour pouvoir être lu par la SDL...
}


J'aurais voulu savoir si c'était bien la bonne méthode ou si je m'y prends comme un pieds pour la conversion :p
  • Partager sur Facebook
  • Partager sur Twitter
17 décembre 2009 à 20:23:18

Pour ton calcul je dirais qu'il n'y a rien d'incorrect.
Par contre pour ton code je te dirais que c'est incorrect !
Un fichier .wav doit être ouvert en mode binaire et non en "texte" du coup le fgetc n'est pas bon :)
Dans le fond ce n'est pas incorrect en soit mais c'est préférable ^^
  • Partager sur Facebook
  • Partager sur Twitter
17 décembre 2009 à 20:26:50

Salut,

Pourquoi ne pas en faire un tutoriel ?
  • Partager sur Facebook
  • Partager sur Twitter
17 décembre 2009 à 20:35:46

Parce que c'est incomplet, et que je préfère que tout le monde participe :)
  • Partager sur Facebook
  • Partager sur Twitter
17 décembre 2009 à 20:37:08

Un fichier .wav doit être ouvert en mode binaire et non en "texte" du coup le fgetc n'est pas bon


En fait j'ai ouvert le fichier en binaire avec fopen mais j'utilise la fonction fgetc, je dois utiliser fread plutôt ?
  • Partager sur Facebook
  • Partager sur Twitter
17 décembre 2009 à 20:42:07

Citation : Pouet_forever

Parce que c'est incomplet, et que je préfère que tout le monde participe :)


Mais tu as matière ici, à faire un tuto...
Ce topic va disparaitre, un tuto, non!

Il reste des points à améliorer, mais ce que tu proposes ici peut faire un très bon tuto.

Et, ce topic pourra toujours servir pour les questions.

  • Partager sur Facebook
  • Partager sur Twitter
Zeste de Savoir, le site qui en a dans le citron !
17 décembre 2009 à 20:48:07

Si tu as ouvert ton fichier en binaire il faut le lire en binaire :)

Sinon pour faire ça en tuto je verrai si j'ai le courage ^^
Il reste encore pas mal de choses à dire ...
  • Partager sur Facebook
  • Partager sur Twitter
17 décembre 2009 à 21:01:27

Merci pour tes réponses je vais donc adapter mon code en conséquence ;)

PS : un tutoriel serait en effet une bonne idée ^^
  • Partager sur Facebook
  • Partager sur Twitter
17 décembre 2009 à 21:30:32

Sous visual studio vous avez :
__int32 et __int16.
Vous pouvez donc faire :
typedef __int16 int16_t;
typedef __int32 int32_t;
  • Partager sur Facebook
  • Partager sur Twitter
17 décembre 2009 à 22:37:56

@ Taurre : Je retire ce que j'ai dit pour le fgetc() !
Apparemment (et je viens de le voir) tu peux très bien utiliser fgetc(), fputc(), fread() et fwrite() pour lire les fichiers binaires :)
  • Partager sur Facebook
  • Partager sur Twitter
18 décembre 2009 à 11:02:27

Ha d'accord merci ^^
Note je pense que je vais garder fread puisqu'il permet de lire plus d'un octet à la fois ;)
  • Partager sur Facebook
  • Partager sur Twitter
23 décembre 2009 à 16:44:05

J'ai créé 2 fichiers WAV correspondant chacun à une note de musique. J'aimerais créer un seul fichier contenant ces 2 notes. Comment faire ?
  • Partager sur Facebook
  • Partager sur Twitter
23 décembre 2009 à 18:03:29

Tu ouvres tout simplement chaque fichier et tu recrée une en-tête pour le fichier final. Ensuite tu concatènes tes 2 fichiers (sans les en-têtes). Si tu fais ça il faut bien veiller à ce que tes 2 fichiers soient exactement pareil (càd fréquence, nb canaux, etc.) auquel cas il te faudra les transformer dans le format du fichier final :)
  • Partager sur Facebook
  • Partager sur Twitter
24 décembre 2009 à 16:27:32

J'essaie de faire un fichier pour écouter les 2 notes en même temps. Pour cela j'ai créé un fichier pour chaque note.
Maintenant je crée un fichier résultant avec une partie entête de 44 octets, jusque là tout va bien. Pour la partie data, je prends 2 octets du fichier 1 et 2 octets du fichier 2. Je les "desindianise" puis les summarize puis les "reindianise", mais cela ne me marche pas.
  • Partager sur Facebook
  • Partager sur Twitter
25 décembre 2009 à 5:33:07

Non ça ne marche pas comme ça ^^
Si ton fichier est en stéréo (2 canaux) tes données seront ordonnées de cette manière : D G D G D G D G D G où D correspond à Droite et G à Gauche.
Donc si tu veux faire une note différente pour tes 2 canaux il faut que tu mettes le contenu correspondant au canal Droit par exemple de ton fichier 1 et que tu le mette dans le canal droit de ton fichier final.
Tu fais pareil avec ton fichier 2 mais avec le canal gauche :)
Au final ça donne ça :

GF2 DF1 GF2 DF1 GF2 DF1 GF2 DF1 GF2 DF1 etc...
  • Partager sur Facebook
  • Partager sur Twitter
25 décembre 2009 à 17:11:45

Je veux que les 2 canaux soient identiques et que chaque canal fasse entendre les 2 notes en même temps. Faut-il summarizer dans ce cas-là en divisant par 2 pour ne pas monter l'intensité ? Ce que je veux savoir c'est comment faire la summarization.
Est-ce qu'il faut faire comme cela ?
octets du fichier 1 (partie data)
X1 X2 X3 X4 X5 X6 ...
octets du fichier 2 (partie data)
Y1 Y2 Y3 Y4 Y5 Y6 ...

Pour les 2 premiers octets
((X2 X1) + (Y2 Y1))/2 = (Z2 Z1) ==> (Z1 Z2)


  • Partager sur Facebook
  • Partager sur Twitter
25 décembre 2009 à 18:52:28

En théorie je te répondrais que ça marche comme ça ^^
En pratique je suis pas sûr :euh:
Je vais me renseigner :)
  • Partager sur Facebook
  • Partager sur Twitter
3 février 2010 à 16:52:47

C'est bien comme cela que ça marche. J'ai même mis 6 notes en même temps et cela fonctionne nickel.
  • Partager sur Facebook
  • Partager sur Twitter
4 février 2010 à 0:35:13

Tout simplement du délire :lol: . :-°

Citation : GurneyH

Mais tu as matière ici, à faire un tuto...
Ce topic va disparaitre, un tuto, non!

Il reste des points à améliorer, mais ce que tu proposes ici peut faire un très bon tuto.

Et, ce topic pourra toujours servir pour les questions.



+1 .

EDIT : @Pouet_forever -> Pour le format : http://www.mega-nerd.com/libsndfile/api.html (si je ne me trompe pas ce qui est chose fréquente ces temps-ci) :) .




  • Partager sur Facebook
  • Partager sur Twitter
10 février 2010 à 21:56:31

Citation : Pouet_forever

Pour une fréquence de 1hz on a une seule sinusoïde dans 1 seconde.
Pour une fréquence de 2hz on a 2 sinusoïdes, 3hz on a 2 3 sinusoïdes, etc...



Petite erreur, sinon un très bon post. ;)
Sérieusement, j'en ferai un tuto, (on peut réagir dans les commentaires, ou bien tu peux faire un topic pour les réactions du tuto).
Tu pourrais même faire plusieurs chapitres, essayer d'expliquer les différentes compressions (mp3, ogg, etc.).

Et comme TP: la création d'une petite bibliothèque qui donne toutes les infos sur le fichier (échantillonage, temps total, etc.).

Je suis sûr qu'un paquet de Zéros seraient intéressés !

Si t'as besoin "d'aide" pour l'écriture ou quoi.... n'hésite pas :-°

J'ai de la documentation assez complète sur les fichiers (WAV, MP3, S3M, MP2, etc.).
La majorité de la doc vient de: http://www.wotsit.org/ (un must, je suppose que tu connais).

Piano
  • Partager sur Facebook
  • Partager sur Twitter