Bonjour,
Soit
Ensuite,
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 type TByteArray = array of byte; procedure TForm1.btnTestWriterClick(Sender: TObject); var Sbuffer: array[0..44099] of byte; // ancien, ok Dbuffer: TByteArray; // nouveau, kc
puis j'initialise des variables, puis je remplis les buffers :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 begin asize := SizeOf(Sbuffer); showmessage(inttostr(asize)); //44100, ok asr := 44100; SetLength(Dbuffer, asr); showmessage(inttostr(length(Dbuffer))); //44100, ok //jusque là on est bon, alors on continue : for i := 0 to asr-1 do Sbuffer[i] := 0; // init buffer for i := 0 to asr-1 do Dbuffer[i] := 0; // init buffer
Je les enregistre (c'est la même fonction d'écriture, utilisée par l'un puis par l'autre buffer), je les ouvre avec un éditeur hexa et... les données ne sont pas les mêmes ! Au début, 3 blocs de 4 bytes en plus (sortis d'où ?) dans Dbuffer (le dynamique). Après ça s'arrange. Et à la fin il lui manque 3 blocs de 4 bytes, évidemment...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 for i := 0 to asr-1 do begin SineCount := SineCount + (Frequency / asr); Sbuffer[i] := Round(Sin(SineCount * 2 * PI) * Amplitude*127); Dbuffer[i] := Sbuffer[i]; end;
Je vous mets une 'tite image du début des deux fichiers, avec le pas bon en haut et en rouge transparent ce qui est en trop :
Si quelqu'un a une idée...
PS : merci pour tes vœux, Gilles, les miens en retour.
EDIT : une précision, qui a peut-être son importance, j'ai rajouté un petit test :
pour voir ce qui se passe et bien sûr, le log montre que les données sont identiques.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 ... Dbuffer[i] := Sbuffer[i]; if i < 50 then memo.Lines.Add(inttostr(i)+' S: '+inttostr(Sbuffer[i])+' D: '+inttostr(Dbuffer[i]));
C'est donc la fonction SaveToWav (qui vient ensuite), qui met sa pagaille ?
Mais comment ?
Vous voulez voir WriteBuf ? Yakà demander :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 function SaveToWav(const aFilename:String; var LeBuffer; aBufferSize, aBitsPerSample, aSampleRate, aChannelCount :Integer): Boolean; var wTmp :TWavWriter; begin Result := False; wTmp := TWavWriter.Create; with wTmp do try StoreToFile(aFilename); // création du fichier récepteur // création des données fmt.BitsPerSample := aBitsPerSample; fmt.SampleRate := aSampleRate; fmt.Channels := aChannelCount; // 2 lignes missing : fmt.BlockAlign := aChannelCount * aBitsPerSample div 8; fmt.ByteRate := fmt.BlockAlign * aSampleRate; WriteBuf(LeBuffer, aBufferSize); Result := true; finally Free; end; end;
Pas de quoi fouetter un chat, et c'est un peu pareil avec StoreToFile, qui commence par créer un TFileStream, qui sera rempli par un StoreToStream :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 function TWavWriter.WriteBuf(var Buffer; BufferSize: Integer): Integer; var sz: Integer; begin Result := 0; with fStream do begin sz := Write(Buffer, BufferSize); if sz < 0 then Exit; Inc(Result, sz); end; end;
Il ne reste plus que FlushHeader comme coupable potentiel mais alors, la grande question se pose : pourquoi juste 12 bytes en plus au début du datachunk quand on appelle la fonction pour la seconde fois ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 function TWavWriter.StoreToStream(AStream:TStream):Boolean; begin fStream := AStream; FFreeStreamOnClose := False; with fmt, ChunkHeader do begin ID := AUDIO_CHUNK_ID_fmt; Size := SizeOf(fmt) - SizeOf(ChunkHeader); Format := AUDIO_FORMAT_PCM; end; Result := FlushHeader; end;
Étant entendu que j'ai attaqué ce post avec les deux arrays ensemble pour montrer les articulations, après m'être rendu compte que travailler avec uniquement la dynamique posait un problème...
Partager