1 pièce(s) jointe(s)
Données différentes entre array statique et array dynamique
Bonjour,
Soit
Code:
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 |
Ensuite,
Code:
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 |
puis j'initialise des variables, puis je remplis les buffers :
Code:
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 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...
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 :
Pièce jointe 632370
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 :
Code:
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])); |
pour voir ce qui se passe et bien sûr, le log montre que les données sont identiques.
C'est donc la fonction SaveToWav (qui vient ensuite), qui met sa pagaille ?
Mais comment ?
Code:
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; |
Vous voulez voir WriteBuf ? Yakà demander :
Code:
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; |
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:
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; |
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 ?
É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...