Aide - Recherche - Membres - Calendrier
Version complète : [CS4] La classe Sound et sa méthode extract
Centre de Formation Flash - Forums Adobe Flash > Adobe Flash > Programmation Actionscript > Actionscript 3
Pages : 1, 2, 3
tibibi
Bonsoir à tous,

Je tente de comprendre un peut les nouvelles fonctionnalités autour de la classe sound et j'ai pour l'instant ceci:

Action Script

var sound:Sound = new Sound();
var dynamicSound:Sound = new Sound();
var samples:ByteArray = new ByteArray();

sound.addEventListener( Event.COMPLETE, complete );
sound.load( new URLRequest( "sounds/sound.mp3" ) );

function complete( pEvt:Event ):void
{
dynamicSound.addEventListener( SampleDataEvent.SAMPLE_DATA, sampleData );
dynamicSound.play();
}

function sampleData( pEvt:SampleDataEvent ):void
{
samples.position = 0;

var len:Number = sound.extract( samples, 3000 );

var left:Number;
var right:Number;

samples.position = 0;

for ( var c:int=0; c < len; c++ )
{
left = samples.readFloat();
right = samples.readFloat();

pEvt.data.writeFloat( left );
pEvt.data.writeFloat( right );
}
}


Ça marche, mais dans la méthode extract, 3000 je l'ai obtenu empiriquement. Comment faire pour connaître le nombre de samples en fonction du son que l'on souhaite traiter?

Je donne un info que j'ai du mal à exploiter: The sample type is a 32-bit floating-point value (par canal)

Merci d'avance et bonne soirée icon_wink.gif
tibibi
En faite je viens de comprendre. On peut osciller entre 2048 et 8192 samples au sein de SampleDataEvent. Je suis en train de faire des testes pour voir combien ça grignote tout ça icon_mrgreen.gif

++icon_wink.gif

jeanphilippe
moi ce qui me tracasse c'est tout le monde me dit que c'est simple de récupérer et de sauver un bout de son grâce à extract mais personne ne monttre le chemin icon_sad.gif
tibibi
Personnellement, j'ai fais une 1er tentative et j'ai échoué mais rien n'est perdu. Le problème c'est que mon fichier fait 2.17Mo au bout de 10" et le problème de l'encodage reste entier derrière... Si j'arrive à quelque chose je post icon_biggrin.gif

++icon_wink.gif
jeanphilippe
moi aussi j'arrive à sauver un .wave sur le desktop mais il est inexploitable par la suite smile.gif
dada
Salut,
Citation (jeanphilippe @ Oct 25 2008, 09:54 AM) *
moi aussi j'arrive à sauver un .wave sur le desktop mais il est inexploitable par la suite smile.gif

Est-ce que tu ajoutes les bytes dans l'en-tête du fichier ? http://fr.wikipedia.org/wiki/WAVEform_audio_format
(j'ai pas essayé mais si ya pas çà, çà a peu de chance de marcher smile.gif )
tibibi
Citation (dada @ Oct 25 2008, 02:56 PM) *
Salut,

Est-ce que tu ajoutes les bytes dans l'en-tête du fichier ? http://fr.wikipedia.org/wiki/WAVEform_audio_format
(j'ai pas essayé mais si ya pas çà, çà a peu de chance de marcher smile.gif )


Pourquoi j'ai pas pensé à wikipédia icon_rolleyes.gif Je cherche de partout les entêtes... Merci Dada gourou.gif icon_biggrin.gif

++icon_wink.gif
tibibi
J'ai commencé à coder l'entête et dans la foulé je me poses des questions sur la latence de l'événement SAMPLE_DATA. Chez moi ça tourne autour de 278 mais n'ayant aucun point de comparaison je souhaiterai savoir ce que vous avez et ce que vous en pensez?

Action Script

trace( ( pEvt.position / 44.1) - soundChannel.position );


P.S sous AIR j'ai un gros problème:

Citation
1172: Definition flash.events:SampleDataEvent could not be found.


++icon_wink.gif
jeanphilippe
Citation (dada @ Oct 25 2008, 02:56 PM) *
Salut,

Est-ce que tu ajoutes les bytes dans l'en-tête du fichier ? http://fr.wikipedia.org/wiki/WAVEform_audio_format
(j'ai pas essayé mais si ya pas çà, çà a peu de chance de marcher smile.gif )

non
tu peux nous montrer ? icon_sad.gif
tibibi
Comme d'hab Thibault Imbert a 10 ans d'avance sur nous icon_cry.gif M'enfin... C'est la vie...

Toi aussi jeanphilippe, t'as 10 ans d'avance sur moi, tu négocies direct avec le grand manitou icon_cool.gif

icon_mrgreen.gif
jeanphilippe
bon, j'arrive à enregistrer le fichier son sur mon bureau, mais c'est du RAW
impossible del'utiliser sans passer par Audacity et l'exporter en mp3
je suis bloqué là smile.gif
tibibi
Citation (jeanphilippe @ Oct 26 2008, 07:13 AM) *
bon, j'arrive à enregistrer le fichier son sur mon bureau, mais c'est du RAW
impossible del'utiliser sans passer par Audacity et l'exporter en mp3
je suis bloqué là smile.gif


Et quel taille fait ton fichier pour 1 min de son par exemple? Parce que si j'ai bien compris le raw est un format audio non compressé. Si faut coder l'algo de compression, ça va pas être de la tarte... icon_mrgreen.gif

++icon_wink.gif

jeanphilippe
dans l'exemple de Thibault Imbert, si je save le son en wave donc en RAW , le fichier fait 28 mo icon_wink.gif
tibibi
J'ai une question icon_mrgreen.gif : SoundCodec ça sert à quoi et ça s'utilise comment?

++icon_wink.gif
jeanphilippe
Citation (tibibi @ Oct 26 2008, 08:17 PM) *
J'ai une question icon_mrgreen.gif : SoundCodec ça sert à quoi et ça s'utilise comment?

++icon_wink.gif

j'ai pas trouvé beaucoup d'infos à ce sujet icon_confused.gif
J'ai cru comprendre que flash.media.SoundCodec permettait de compresser le son du microphone icon_confused.gif
tibibi
Bon je suis enfin rentré chez moi et j'ai retrouvé mon PC icon_biggrin.gif Bosser sur un laptop c'est trop galère...

J'ai donc mon entête... On peut alors lire le fichier son mais c'est une horreur! C'est inaudible... jeanphilippe je te souhaite de mieux réussir parce que chez moi c'est affreux ma copine crise à chaque test icon_mrgreen.gif

Action Script

package fx.bidesign.format
{
import flash.utils.Endian;
import flash.utils.ByteArray;

import flash.events.Event;

public class FxWaveFormat
{

// writeHeader ( 2, 16, 44100 )
static public function writeHeader( channels:int, bits:int, rate:int, length:int ):ByteArray
{
var bytes: ByteArray = new ByteArray();

bytes.endian = Endian.LITTLE_ENDIAN;

bytes.writeUTFBytes( 'RIFF' );

bytes.writeInt( 0 );

bytes.writeUTFBytes( 'WAVE' );

bytes.writeUTFBytes( 'fmt ' );

bytes.writeInt( int( 16 ) );

bytes.writeShort( int( 1 ) );

bytes.writeShort( channels );

bytes.writeInt( rate );

bytes.writeInt( int( rate * channels * ( bits / 8 ) ) );

bytes.writeShort( int( channels * ( bits / 8 ) ) );

bytes.writeShort( bits );

bytes.writeUTFBytes( 'data' );

bytes.writeInt( length );

bytes.position = 0;

return bytes;
}
}
}


++icon_wink.gif
Xarald

Action Script

c'est affreux ma copine crise à chaque test icon_mrgreen.gif 


Fais lui la MAJ du fp 10 icon_mrgreen.gif icon_mrgreen.gif icon_mrgreen.gif
tibibi
icon_mrgreen.gif
jeanphilippe
Je testerai ça ce soir et te tiens au courant Tibibi!
Pour le moment, je viens de recevoir Adobe Creative Suite 4 Web Premium par courrier : donc en avant l'installation !
tibibi
Comme je t'envie icon_biggrin.gif Amuses-toi bien ++icon_wink.gif
jeanphilippe
arffff.... l'installation s'est faite impéccable mais je m'en doutais un peu, c'est une version anglaise icon_confused.gif
la pieuvre
moi je boycott l'achat tant qu'ils n'aurons pas une politique tarifaire normal en europe!! et nan ! smile.gif
jeanphilippe
Citation (la pieuvre @ Oct 27 2008, 04:36 PM) *
moi je boycott l'achat tant qu'ils n'aurons pas une politique tarifaire normal en europe!! et nan ! smile.gif

c'est ton choix smile.gif
la pieuvre
oui payer presque 2 fois prix des usa pour aucune différence ça m'énerve smile.gif (cd. mon avatar) wink.gif
la pieuvre
en fiat non c'est vraiment 2 fois plus chère 318,5 €(599$ ht évidemment) aux usa contre 649€ HT en France pour la version française dans les 2 cas. alors je veux bien que le bateau coûte chère mais quand même wink.gif
Joni
Citation
en fiat non c'est vraiment 2 fois plus chère


C'est sûr que si tu te fait livrer en Fiat, ça va coûter cher (essence, transport par ferry, pilote pour la voiture,...) icon_mrgreen.gif icon_mrgreen.gif icon_mrgreen.gif

Bon OK je sors -->
la pieuvre
icon_mrgreen.gif oups
dada

Action Script


bytes.writeInt( 0 );

Citation
FileSize (4 octets) : Taille du fichier moins 8 octets

Pourquoi tu mets zéro dans la longueur du fichier ?

Citation (jeanphilippe @ Oct 25 2008, 05:46 PM) *
tu peux nous montrer ? icon_sad.gif

Non car je l'ai jamais fait, mais je sais que c'est ce qu'il faut faire. smile.gif
tibibi
Citation (dada @ Oct 28 2008, 04:09 PM) *

Action Script


bytes.writeInt( 0 );


Pourquoi tu mets zéro dans la longueur du fichier ?
Non car je l'ai jamais fait, mais je sais que c'est ce qu'il faut faire. smile.gif


Bien vue, j'avais loopé ça icon_redface.gif J'ai fait une bétise, je modifie et je reviens... Merci ++icon_wink.gif
tibibi
Dada, j'ai rectifié mais malheureusement ça fait toujours un bruit horrible icon_sad.gif

Action Script

package fx.bidesign.format
{
import flash.utils.Endian;
import flash.utils.ByteArray;

import flash.events.Event;

public class FxWaveFormat
{

// writeHeader ( 2, 16, 44100 )
static public function writeHeader( channels:int, bits:int, rate:int, length:int ):ByteArray
{
var bytes: ByteArray = new ByteArray();

bytes.endian = Endian.LITTLE_ENDIAN;

bytes.writeUTFBytes( 'RIFF' );

bytes.writeInt( length - 8 );

bytes.writeUTFBytes( 'WAVE' );

bytes.writeUTFBytes( 'fmt ' );

bytes.writeInt( int( 16 ) );

bytes.writeShort( int( 1 ) );

bytes.writeShort( channels );

bytes.writeInt( rate );

bytes.writeInt( int( rate * channels * ( bits / 8 ) ) );

bytes.writeShort( int( channels * ( bits / 8 ) ) );

bytes.writeShort( bits );

bytes.writeUTFBytes( 'data' );

bytes.writeInt( length - 44 );

bytes.position = 0;

return bytes;
}
}
}


Si quelqu'un a une idée gourou.gif
jeanphilippe
tibibi : tu peux poster le reste du code que l'on puisse tester ? icon_wink.gif
tibibi
Voilà: (j'ai 2 boutons sur la scène: record et save)

Action Script

var sound:Sound = new Sound();
var dynamicSound:Sound = new Sound();
var soundChannel:SoundChannel = new SoundChannel();
var samples:ByteArray = new ByteArray();
var sndBytes:ByteArray = new ByteArray();
var fileBytes:ByteArray = new ByteArray();

var myFileRefSave:FileReference = new FileReference();

sound.addEventListener( Event.COMPLETE, complete );
sound.load( new URLRequest( "sounds/sound2.mp3" ) );

function complete( pEvt:Event ):void
{
record.addEventListener( MouseEvent.MOUSE_DOWN, startRecord );
}

function startRecord( pEvt:MouseEvent )
{
dynamicSound.addEventListener( SampleDataEvent.SAMPLE_DATA, sampleData );
soundChannel = dynamicSound.play();

save.addEventListener( MouseEvent.MOUSE_DOWN, stopRecord );
}

function sampleData( pEvt:SampleDataEvent ):void
{
samples.position = 0;

var len:Number = sound.extract( samples, 2048 );

var left:Number;
var right:Number;

samples.position = 0;

sndBytes.writeBytes( samples );

for ( var c:int=0; c < len; c++ )
{
left = samples.readFloat();
right = samples.readFloat();

pEvt.data.writeFloat( left );
pEvt.data.writeFloat( right );
}
}

function stopRecord( pEvt:MouseEvent )
{
trace( soundChannel.position );

fileBytes.writeBytes( FxWaveFormat.writeHeader( 2, 16, 44100, sndBytes.length ) );

fileBytes.writeBytes( sndBytes );

myFileRefSave.save( fileBytes, "snd.wav" );
}


++icon_wink.gif
jeanphilippe
merci !
je vais tester ce soir chez moi smile.gif

jeanphilippe
effectivement je viens de tester...
le wav fonctionne mais c'est une cacophonie icon_mrgreen.gif
tibibi
C'est là tout le problème icon_mrgreen.gif
jeanphilippe
tu crois que ça vient de l'entête ? de l'encodage ?
tibibi
Je n'en sais rien icon_sad.gif Dada sait peut-être... Je vais fouiller le net mais ça semble mal embarqué... Je pense que ça vient du bitrates par ce que le tx d'échantillonnage est de 1411 Kbits/s chez moi, c'est bizarre non?
jeanphilippe
tu le vois comment ?
tibibi
Dans les propriétés du fichier wave créé... Tu en penses quoi?
jeanphilippe
cad que je suis pas assez calé en sound pour décortiquer un wav icon_sad.gif icon_sad.gif icon_sad.gif
c'est dommage car on est pas loin du truc
enfin : c'est plutot TOI qui n'est pas loin du truc icon_lol.gif
en tous les cas merci Tibibi pour cette recherche smile.gif
je cherche de mon coté aussi....... icon_sad.gif
jeanphilippe
peut etre devrions nous demander conseil à Thibault Imbert ?
Tu en penses quoi ?
tibibi
Citation (jeanphilippe @ Oct 28 2008, 08:08 PM) *
cad que je suis pas assez calé en sound pour décortiquer un wav icon_sad.gif icon_sad.gif icon_sad.gif
c'est dommage car on est pas loin du truc
enfin : c'est plutot TOI qui n'est pas loin du truc icon_lol.gif
en tous les cas merci Tibibi pour cette recherche smile.gif
je cherche de mon coté aussi....... icon_sad.gif


Je te rassure, j'y connais rien non plus icon_mrgreen.gif J'y vais au feeling et j'espère qu'un petit expert pointe le bout de son nez icon_cool.gif
Merci à toi et dada pour vos conseils et je pense en effet qu'on est pas loin du truc icon_biggrin.gif

Si j'ai du nouveau, je post icon_smile.gif et oui thibault Imbert pourrais nous éclairer grandement je pense gourou.gif Si tu veux lui glisser un mot icon_mrgreen.gif

++icon_wink.gif
jeanphilippe
ok, j'essaie deal.gif
dada
Je vais regarder çà. Je suis à l'hotel alors j'ai pas grand chose à faire de plus.
jeanphilippe
cool !
merci dada smile.gif
dada
Te réjouis pas trop vite hein ! icon_mrgreen.gif
J'ai commencé à regarder la spec du format WAV déjà pour comprendre un peu ce que voulais dire tous ces trucs et je vérifie si ce qu'a écrit tibibi correspond à ce que je comprend des specs (déjà le temps de comprendre... une seule ptite erreur plante tout le format donc...). Je met des commentaires dans le code de l'en-tête aussi pour être sûr de pas louper un truc.

Pour l'instant dans le WAV j'ai une grosse friture mais en tendant l'oreille j'entend la musique censée être encodée, bien au fond de cette friture. Donc ya un truc qui merde mais ya un peu de positif. ^^ (remarque c'est ptet déjà ce que vous aviez icon_rolleyes.gif icon_mrgreen.gif ).
tibibi
Je crois qu'on est tous au même point à présent icon_mrgreen.gif

J'avoue que je pêche un peu là... Merci Dada d'avoir rejoint les rangs icon_biggrin.gif

++icon_wink.gif
dada
Citation (tibibi @ Oct 28 2008, 10:58 PM) *
Je crois qu'on est tous au même point à présent icon_mrgreen.gif

J'avoue que je pêche un peu là... Merci Dada d'avoir rejoint les rangs icon_biggrin.gif

J'ai pas beaucoup avancé... icon_confused.gif
J'en suis au stade où j'entend la musique avec la friture (un peu mieux qu'avant). Le truc pas normal : je dois spécifier un sample-rate de 88200 pour entendre le son en vitesse normale... Sinon il est 2 fois trop lent. Je vais voir si j'ai pas fait une erreur grossière, et arrêter là pour aujourd'hui. smile.gif En même temps, à part des commentaires j'ai pas fait grand chose de plus que toi (surtout de la recherche et des tests sur les valeurs).
dada
Voilà où j'en suis resté : http://dada.media-box.net/temp/monSon2.wav
Ya eu un peu de progrès depuis la friture hein ? icon_biggrin.gif

J'étais un peu étonné de voir que les samples du ByteArray étaient compris entre -1 et 1 (float 32 bits) alors que d'après les specs WAV les valeurs sont stockées en short (int 16 bits). Donc j'ai testé de convertir ces valeurs et çà a donné çà. smile.gif Du coup çà a aussi corrigé le problème de durée 2 fois trop longue qui venait de là (32 bits -> 16 bits). La friture, elle, venait du rapport signal/bruit beaucoup trop faible (on passe de valeurs audio faibles à des valeurs de 32767 !).^^

Voici la fonction de conversion (de test), en entrée le byteArray rempli par Sound.extract, et en sortie celui qu'on ajoute à la fin de l'en-tête.

Action Script

private function testConvert ( p:ByteArray ) :ByteArray
{
var ba:ByteArray = new ByteArray ( ) ;
ba.endian = Endian.LITTLE_ENDIAN;
p.position = 0;

while ( p.position < p.length )
ba.writeShort ( p.readFloat ( ) * 32767) ;

return ba;
}
C'est balot quand même, j'ai cherché un moment dans l'en-tête où était l'erreur, à lire et relire les specs sans trop faire gaffe à ce format de codage qui m'avait pourtant un peu interloqué. Puis avant de lacher l'affaire, j'me suis dit "autant tester çà"... rahhh c'est vraiment balot de pas avoir testé avant icon_biggrin.gif

Si vous voulez je vous mettrai mon projet de test demain (faudra que je nettoie un peu les essais en tout genre), j'ai peut-être modifié un truc ou deux dans l'en-tête au final.

Pour répondre à ta toute première question tibibi, on peut extraire la totalité d'un son comme çà, mais c'est très très lourd (mieux vaut le faire en "pseudo-streaming" que d'une traite, au moins on peut afficher une progression, ou même avec un Shader qui fait le travail dans un thread différent) :

Action Script


var durationSecondes:uint = _sound.length / 1000;
var bytesPerSecond:uint = sampleRate * bitsPerSample * channels / 8;
_sound.extract ( _samplesOut, durationSecondes * bytesPerSecond);
jeanphilippe
ça a l'air pas mal du tout dada smile.gif bravo
je veux bien voir le projet commenté icon_rolleyes.gif
merci
Ceci est une version "bas débit" de notre forum. Pour voir la version complète avec plus d'informations, la mise en page et les images, veuillez cliquer ici.
Invision Power Board © 2001-2009 Invision Power Services, Inc.