Son Wav en data

Programmation d'applications complexes
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

Son Wav en data

Message par Good07 »

Bonsoir à tous !

Pour continuer dans la rubrique tout en un , J'ai décidé d'écrire un programme qui transforme un fichier .wav en data. Malheureusement ce n'est pas si facile puisqu'il ne marche pas. :(
Enfin pas tout. Le programme lit bien le fichier son et le transforme bien en data, de -128 à +128. si vous voulez de 0 à 255 il suffit de rajouter
& $FF à la ligne 48 du programme.
De toute façon ça ne change rien le haut parleur produit un son muet (je viens d'inventer ça pour travailler en silence :lol: )
Je fait peut être une erreur quelque part...

Je pense que comme les images ce doit être possible mais je ne sais pas pourquoi celà ne fonctionne pas.

Si vous avez une idée voici le code du programme:

Code : Tout sélectionner

;--------------------------------------------------
;Good07
;Programme pour transformer des fichiers Wav en data
;Le 10/11/04
;Version PureBasic 3.92
;--------------------------------------------------
;
Global out.s
FileName$= OpenFileRequester("", "*.wav", ".wav", 0);On choisi le fichier .wav à transformer en data.
If OpenFile(1,FileName$)<>0                         ;Ouverture du fichier
  Longueur= FileSize(FileName$)                     ;On récupère sa longueur
  *tampon=AllocateMemory(Longueur)                  ;On alloue à l'adresse *tanpom un emplacement mémoire de la longueur du fichier
  ReadData(*tampon,Longueur)                        ;On transfère le contenu du fichier dans le tampon
EndIf
CloseFile(1) ; On ferme le fichier en lecture
name$=GetFilePart(filename$) ; on récupère son nom
name$=Left(name$,(Len(name$)-4)); et on enlève l'extention (.wav)
If CreateFile(0,"WaveData.pb") ;On donne un nom au programme et on ouvre un fichier en écriture 
  WriteStringN("; Fichier Wave en data"); Les ligne de dessous servent à créer le programme qui va lire les datas
  WriteStringN(" ")
  WriteStringN("InitSound()")
  WriteStringN("Restore Pong")
  WriteStringN("Read longueur.l")
  WriteStringN("*tampon=AllocateMemory(longueur)")
  WriteStringN("For n=0 To longueur-1")
  WriteStringN(" Read c.b")
  WriteStringN(" PokeB(*tampon+n,c)")
  WriteStringN("Next n")
  WriteStringN("resultat=CatchSound(1,*tampon)")
  WriteStringN("If resultat=0")
  ; Comme on ne peut pas écrire WriteStringN(""Attention"") (voir le Post de Dobro sur le sujet) on est coincé pour générer 
  ; la ligne de dessous.
  ; En utilisant un petit artifice on y arrive mais le programme généré va donner une syntaxe erreur sur cette ligne !
  ; Il faudra rajouter les "" manquant manuellement...Désolé. Mais si quelqu'un a une autre solution je suis preneur !
  WriteStringN(" MessageRequester"+"("+"Attention"+","+"le chargementdu son a échoué !"+","+"#PB_MessageRequester_Ok"+")")
  WriteStringN("EndIf")
  WriteStringN("PlaySound(1)")
  WriteStringN("End")
  WriteStringN(" ")
  WriteStringN("DataSection")
  WriteStringN(" ")
  WriteStringN(Name$+":")
  WriteStringN(" ")
  out="Data.l "
  WriteStringN(out+Str(longueur));Première ligne de data contient la longueur du fichier à lire.
  out="Data.b "
  For x=0 To Longueur-1; boucle qui lit le fichier en mémoire et le transforme en data
    c=PeekB(*tampon+x);& $FF 
    c$=Str(c)
    out=out+c$
    If z=25
      z=0
      WriteStringN(out)
      out="Data.b "
    ElseIf x<> Longueur-1
      out=out+","
    EndIf
    z=z+1
  Next x
  If z<26
    WriteStringN(out); si la dernière ligne n'est pas complète on écrit ce qui reste
  EndIf
  WriteStringN("EndDataSection") 
  CloseFile(0) 
EndIf 
KarLKoX
Messages : 1191
Inscription : jeu. 26/févr./2004 15:36
Localisation : France
Contact :

Message par KarLKoX »

Juste apres Playsound, commente le "end" et met une boucle pour laisser la lecture se faire sinon, ca saute à l'instruction suivante :)
"Qui baise trop bouffe un poil." P. Desproges
Avatar de l’utilisateur
Chris
Messages : 3731
Inscription : sam. 24/janv./2004 14:54
Contact :

Message par Chris »

Pour ton problème de " dans le message requester, il faut utiliser chr(34).

Code : Tout sélectionner

  q.s = Chr(34)
  WriteStringN(" MessageRequester"+"("+q+"Attention"+q+","+q+"le chargement du son a échoué !"+q+","+"#PB_MessageRequester_Ok"+")") 
Il faudrait également changer

Code : Tout sélectionner

WriteStringN("Restore Pong")
par

Code : Tout sélectionner

WriteStringN("Restore "+ name$)
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

Il faut mettre directement ton catchsound sur le data, j'ai pas testé mais c'est comme ça que je fais pour les images ;)

Code : Tout sélectionner

catchSount(#Son, ?SonData)
DataSection
  SonData :
  Data.b 0, 0, 0, 0
EndDataSection
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

Message par Good07 »

Bonsoir à tous :lol:

Désolé de vous répondre si tard, mais mon PC à été victime d'une attaque du virus W32/jeefo qui a infecté tous les exécutables.
J'avais envoyé une réponse ce matin mais il a du se passer quelque chose pendant l'envoi car je ne trouve pas ma réponse. :(

Bon cela ne fait rien, je vous remercie tous pour vos réponses.

Pour KarLKoX :
Merci. je me doutais bien que cela devais marché mais je ne voyais pas ce qui coinçais. J'aurai jamais pensé que c'était la fin du programme qui me coupais le son. :cry:

Pour Chris:
Merci pour Message Requester. C'était tellement évident que je n'y ai pas pensé. :oops:
Pour la ligne WritestringN("restore pong"), je l'avais déja corrigé mais je n'ai pas posté la bonne version. :oops:

Pour le Soldat Inconnu (qui gagne à être connu par ailleurs :lol: )
Merci je vais testé car avec tous ça je n'ai pas eu trop de temps.

Bon voici une nouvelle version corrigé des premiers bugs.

Code : Tout sélectionner

;--------------------------------------------------
;Good07
;Programme pour transformer des fichiers Wav en data
;Le 10/11/04
;Version PureBasic 3.92
;--------------------------------------------------
;
Global out.s
q.s = Chr(34)
FileName$= OpenFileRequester("", "*.wav", ".wav", 0);On choisi le fichier .wav à transformer en data.
If OpenFile(1,FileName$)<>0                         ;Ouverture du fichier
  Longueur= FileSize(FileName$)                     ;On récupère sa longueur
  *tampon=AllocateMemory(Longueur)                  ;On alloue à l'adresse *tanpom un emplacement mémoire de la longueur du fichier
  ReadData(*tampon,Longueur)                        ;On transfère le contenu du fichier dans le tampon
EndIf
CloseFile(1) ; On ferme le fichier en lecture
name$=GetFilePart(filename$) ; on récupère son nom
name$=Left(name$,(Len(name$)-4)); et on enlève l'extention (.wav)
If CreateFile(0,"WaveData.pb") ;On donne un nom au programme et on ouvre un fichier en écriture 
  WriteStringN("; Fichier Wave en data"); Les ligne de dessous servent à créer le programme qui va lire les datas
  WriteStringN(" ")
  WriteStringN("InitSound()")
  WriteStringN("Restore "+ name$); On ajoute le nom du fichier pour la restauration des datas (Utile si on a plusieurs sections)
  WriteStringN("Read longueur.l")
  WriteStringN("*tampon=AllocateMemory(longueur)")
  WriteStringN("For n=0 To longueur-1")
  WriteStringN(" Read c.b")
  WriteStringN(" PokeB(*tampon+n,c)")
  WriteStringN("Next n")
  WriteStringN("resultat=CatchSound(1,*tampon)")
  WriteStringN("If resultat=0")    
  WriteStringN(" MessageRequester"+"("+q+"Attention"+q+","+q+"le chargement du son a échoué !"+q+","+"#PB_MessageRequester_Ok"+")") 
  WriteStringN("EndIf")
  WriteStringN("PlaySound(1)")
  WriteStringN("Delay(10000)");Permet d'entendre le son avant la fin du programme. A supprimer si vous incorporez ce listing à votre 
  WriteStringN(" ")           ;programme
  WriteStringN("DataSection")
  WriteStringN(" ")
  WriteStringN(Name$+":")
  WriteStringN(" ")
  out="Data.l "
  WriteStringN(out+Str(longueur));Première ligne de data contient la longueur du fichier à lire.
  out="Data.b "
  For x=0 To Longueur-1; boucle qui lit le fichier en mémoire et le transforme en data
    c=PeekB(*tampon+x);& $FF 
    c$=Str(c)
    out=out+c$
    If z=25
      z=0
      WriteStringN(out)
      out="Data.b "
    ElseIf x<> Longueur-1
      out=out+","
    EndIf
    z=z+1
  Next x
  If z<26
    WriteStringN(out); si la dernière ligne n'est pas complète on écrit ce qui reste
  EndIf
  WriteStringN("EndDataSection") 
  CloseFile(0) 
EndIf 
MessageRequester("Programme","Le programme a été généré"+Chr(10)+"avec succé sous le nom"+Chr(10)+"WaveData.Pb",#PB_MessageRequester_Ok)
A+
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Je l'ai essayé, ça marche bien.

Mais pour m'être lancé dans cette aventure moi-même, je me suis rendu compte que l'emploie des datas à ce niveau est catastrophique et se limite à des fichiers de quelques Ko pour plusieurs raisons:

- la compilation des datas prends un temps énorme

- la reconstruction des fichiers à partir des datas n'est pas rapide

- Destructuration du code:la partie des datas occupant 95% du code donc navigation difficile

- la taille des datas rajoutés au code explose et très supérieur à la taille des fichiers originaux et pour cause.

Il est possible d'éviter toutes ces contraintes, notamment en employant une DLL, mais ça perd de son intérêt.

:)
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

la taille des datas rajoutés au code explose et très supérieur à la taille des fichiers originaux et pour cause.
pourquoi Nico ? , puique en principe les fichiers sont codé en hexa sur le disque, et que c'est ces codes hexa que tu lit et integre en Data
je dit pas de betise si je dit qu'il y a autant de code data que d'octet codé en hexa dans le fichier non ? 8O plus bien sur les lettres "data" et les virgules :D

mais c'est vrai que 1 kilo octets de wav fera au minimum 1024 datas ! :?
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Non, pas du tout!

Good07 lit les fichiers *.wav en octets donc les valeurs qu'il obtient oscille entre 127 et -128 en valeurs décimale.

Au mieux pour l'octet de valeur 0, sa représentation décimale "0" sera elle aussi sur 1 octet + la virgule donc au final 2 octets.

Au pire pour l'octet de valeur 128, sa représentation décimale "-128" sera sur 4 octets + la virgule donc au final 5 octets.

En plus il faut rajouter pour chaque ligne "Data.b "+2 caractères de fin de lignes.

Exemple pour un fichier Wav de 108 Ko j'obtiens un fichier data +code de 384Ko, le code seul ne représentant que 455 octets, j'ai un fichier 3 fois supérieur.

:)
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

Message par Good07 »

Bonjour Nico.

Je suis bien concient de ta remarque, puisque j'ai moi aussi fait des essais sur le sujet. Si on prend un fichier Wav très gros le temps de conversion est très rapide, mais par contre le chargement du programme généré met un certain temps car on arrive vite à un fichier de 10000 lignes. C'est vrai que le programme compilé est aussi plus gros. Mais l'intérêt pour moi c'était de savoir si j'arriverai à faire le programme, et d'avoir tous les sons lorsqu'on poste un listing sur le forum. Les sons des programmes de jeux étant souvent assez limités lors de la conception du programme. Mais il existe peut être une solution pour incorporer des fichiers codé en MP3 et là on revient à la remarque qui à été faite à Dobro (que je salus au passage :D ) de coder les images en jpg avant de les transformer en datas. Est-ce possible ?

Merci en tout cas pour votre aide et toutes vos remarques

A+ :BIG:
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

et si Good07 (Hello!) avait codé ses sons de 0-255 aurait'il gagné de la place ??? 8O :)

dans les data (j'ai pas essayé) , il y en a peut etre qui se suivent de la mem valeur !!

si c'est le cas souvent , il suffirai de rajouter un data de control avant chaque data de son , ce qui aurai pour effet de diminuerle nombre de data qui se suivent de la meme valeur ex :

le son d'origine

data 125,50,60,20,20,20,20,20,20,45,45,45,,46

le son compressé avec data de control

data 125,50,60,6,20,3,45,46

on part du principe que si le data est superieur a 10 on prend la valeur tel quel (valeur de son)
si le data est inferieur a 11 , c'est un data de control et a la decompression il indique combien de data se suivent et se ressemble
evidement pas plus de 10 data successif ne pourrai etre compressé ! :D

data *,*,6,20 <--- veut dir qu'il y a 6 fois le data 20 qui doit etre "joué"

ai-je été clair ? :? :lol:


evidement ce system suprime les data inf a 11 !!
ou bien faut remplacer ce caractere de control par une lettre !
puisque la compression c'est nous qu'on la fait ! on met ce qu'on veut :D
Dernière modification par Backup le ven. 12/nov./2004 11:28, modifié 2 fois.
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Oui :lol:
puique en principe les fichiers sont codé en hexa sur le disque
Non, c'est du binaire (base 2) "l'ordinateur c'est que des 0 et des 1", mais on utilise plus souvent sa représentation en Hexa (base 16) qui est plus facile à manipuler!


:)

[Edit:]
ça peut être marrant à faire mais personnellement j'utilise la compression des données avant de mettre sous forme de datas.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

Non, c'est du binaire (base 2)
oui c'est juste une representation , ça change rien ! :D

les editeur de disk represente en hexa , alors dans ma tete c'est plus simple de penser que c'est de l'hexa , mais oui bien sur c'es du binaire ! :D
Répondre