Waw*_*hun 1 delphi matlab wav delphi-7
我现在尝试使用delphi读取.wav文件,这里是我的代码:
type
TWaveHeader = packed record
Marker_RIFF: array [0..3] of char;
ChunkSize: cardinal;
Marker_WAVE: array [0..3] of char;
Marker_fmt: array [0..3] of char;
SubChunkSize: cardinal;
FormatTag: word;
NumChannels: word;
SampleRate: longint;
BytesPerSecond: longint;
BytesPerSample: word;
BitsPerSample: word;
Marker_data: array [0..3] of char;
DataBytes: longint;
end;
TChannel = record
Data : array of double;
end;
Run Code Online (Sandbox Code Playgroud)
一些私人移民
private
wavehdr:TWaveHeader;
wavedata:array[0..3]of TChannel;
numsamples:integer;
Run Code Online (Sandbox Code Playgroud)
功能
FillChar(wavehdr, sizeof(wavehdr), 0);
Stream.Read(wavehdr, sizeof(wavehdr));
{ Log Header data }
with memo1.Lines do begin
Add('Filename : '+od.FileName);
Add('Header size : '+inttostr(sizeof(wavehdr)));
tmpstr := wavehdr.Marker_RIFF;
Add('RIFF ID : '+tmpstr+'');
Add('Chunk size : '+inttostr(wavehdr.ChunkSize));
tmpstr := wavehdr.Marker_WAVE;
Add('WAVE ID : '+tmpstr+'');
tmpstr := wavehdr.Marker_fmt;
Add('''fmt '' ID : '+tmpstr+''' ');
Add('SubChunk size : '+inttostr(wavehdr.SubChunkSize));
Add('Format : '+inttostr(wavehdr.FormatTag));
Add('Num Channels : '+inttostr(wavehdr.NumChannels));
Add('Sample rate : '+inttostr(wavehdr.SampleRate));
Add('Bytes per second : '+inttostr(wavehdr.BytesPerSecond));
Add('Bits per sample : '+inttostr(wavehdr.BitsPerSample));
Add('Block Align : '+inttostr((wavehdr.NumChannels*wavehdr.BitsPerSample)div 8));
end;
numsamples := (file.size div (wavehdr.NumChannels*wavehdr.BitsPerSample)div 8) div wavehdr.BytesPerSample;
case wavehdr.NumChannels of
1:begin
SetLength(wavedata[0].Data, numsamples);
Stream.Read(wavedata[0].Data[0], numsamples);
end;
2:begin
SetLength(wavedata[0].Data, numsamples);
SetLength(wavedata[1].Data, numsamples);
for i := 0 to high(wavedata[0].Data) do begin
Stream.Read(wavedata[0].Data[i], 2);
Stream.Read(wavedata[1].Data[i], 2);
end;
end;
end;
Run Code Online (Sandbox Code Playgroud)
上面的代码给出了与.wav标题完全相同的信息和细节(与MATLAB DOES相同),它是:
除了我计算的总样本数据(波数据的大小/波数据的块对齐)-44,44是wav的标题.它不准确,有时会错过5,1,10.我只测试了5个样本.这里有一个例子:
而且来自matlab和delphi的样本数据值也不同
classic1.wav MATLAB :(前10个值为leftchannel和rightchannel)
DELPHI :(前10个值为leftchannel和rightchannel)
我的问题是:
编辑:我跟着mBo建议并将其改为mbo建议
Data : array of SmallInt;
numsamples := wavehdr.DataBytes div (wavehdr.NumChannels * wavehdr.BitsPerSample div 8);
Stream.Read(wavedata[0].Data[i], SizeOf(SmallInt));
Run Code Online (Sandbox Code Playgroud)
口译部分我不确定,但我把它改成了
floattostr(wavedata[0].Data[i]/32768.0)
floattostr(wavedata[1].Data[i]/32768.0)
Run Code Online (Sandbox Code Playgroud)
结果我得到:
Wav文件(每个样本的位数:16)包含带符号的16位整数数据(SmallInt类型),但是您以float 8字节类型的Double数组读取数据.
你可以申报
Data : array of SmallInt;
Run Code Online (Sandbox Code Playgroud)
计算
numsamples := wavehdr.DataBytes div (wavehdr.NumChannels * wavehdr.BitsPerSample div 8);
Run Code Online (Sandbox Code Playgroud)
读它们为
Stream.Read(wavedata[0].Data[0], numsamples * SizeOf(SmallInt))
or multichannel case:
Stream.Read(wavedata[0].Data[i], SizeOf(SmallInt));
Run Code Online (Sandbox Code Playgroud)
然后将数据值解释为浮点数Data [i]/32768.0
注意,matlab值3.05175781250000e-05 = 1/32768.0是16位信号的最小量子