Помогите, пожалуйста, с получением спектра из wav файла. Я нашла следующий код на Дельфи
Код:
Const
noError = 0;
ReadError = 1;
HeaderError = 2;
DataError = 3;
FileCorrupt = 4;
IncorectFileFormat = 5;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
OpenDialog1: TOpenDialog;
Image1: TImage;
procedure Button1Click(Sender: TObject);
...
end;
TWaveHeaderChank = record
wFormatTag : Smallint;
wChannels : WORD;
wSamplesPerSec : Cardinal;
wAvgBytesPerSec: Cardinal;
wBlockAlign : WORD;
wBitsPerSample : WORD;
wcbSize : WORD;
end;
TWaveResult = record
ERROR : WORD;
wAvgBytesPerSec: Cardinal;
wBitsPerSample : WORD;
wChannels : WORD;
Data : TMemoryStream;
end;
var
Form1: TForm1;
.......
uses math;
Function ReadWave(FileName : AnsiString) : TWaveResult;
var
f : TFileStream;
wFileSize : Cardinal;
wChankSize : Cardinal;
ID : array[0..3] of Char;
Header : TWaveHeaderChank;
RealFileSize : Cardinal;
Begin
FillChar(Result, SizeOf(Result), 0);
Try
f := TFileStream.Create(FileName, fmOpenRead);
f.Seek(0, soFromBeginning);
f.ReadBuffer(ID[0], 4);
if String(ID) <> 'RIFF'
then
Begin
Result.ERROR := IncorectFileFormat;
f.Free;
exit;
end;
Form1.memo1.Lines.Add(String(ID));
f.ReadBuffer(wFileSize, 4);
Form1.memo1.Lines.Add('FileSize ' + intToStr(wFileSize));
if f.size <> (wFileSize + 8)
then
Begin
Result.ERROR := FileCorrupt;
f.Free;
exit;
end;
f.ReadBuffer(ID[0], 4);
Form1.memo1.Lines.Add(String(ID));
if String(ID) <> 'WAVE'
then
Begin
Result.ERROR := IncorectFileFormat;
f.Free;
exit;
end;
wChankSize := 0;
repeat
f.Seek(wChankSize, soFromCurrent);
f.ReadBuffer(ID[0], 4);
Form1.memo1.Lines.Add(String(ID));
f.ReadBuffer(wChankSize, 4);
if wChankSize > High(integer)
then
Begin
Result.ERROR := DataError;
f.Free;
exit;
end;
Form1.memo1.Lines.Add('chankSize ' + intToStr(wChankSize));
until (String(ID)='fmt ') or (String(ID)='data');
if String(ID)='data'
then
Begin
Result.ERROR := HeaderError;
f.Free;
exit;
end;
f.ReadBuffer(Header, Min(wChankSize, SizeOf(TWaveHeaderChank)));
Form1.memo1.Lines.Add('wChannels ' + intToStr(Header.wChannels));
Form1.memo1.Lines.Add('wSamplesPerSec ' + intToStr(Header.wSamplesPerSec));
Form1.memo1.Lines.Add('wBitsPerSample ' + intToStr(Header.wBitsPerSample));
if wChankSize > SizeOf(TWaveHeaderChank) then
f.Seek(wChankSize - SizeOf(TWaveHeaderChank), soFromCurrent);
if wChankSize >= SizeOf(TWaveHeaderChank)
then
Form1.memo1.Lines.Add('wcbSize ' + intToStr(Header.wcbSize));
wChankSize := 0;
repeat
f.Seek(wChankSize, soFromCurrent);
f.ReadBuffer(ID[0], 4);
Form1.memo1.Lines.Add(String(ID));
f.ReadBuffer(wChankSize, 4);
Form1.memo1.Lines.Add('chankSize ' + intToStr(wChankSize));
until String(ID)='data';
Result.ERROR := noError;
Result.wAvgBytesPerSec := Header.wAvgBytesPerSec;
Result.wBitsPerSample := Header.wBitsPerSample;
Result.wChannels := Header.wChannels;
Result.Data := TMemoryStream.Create;
Result.Data.Seek(0, soFromBeginning);
Result.Data.Size := wChankSize;
f.ReadBuffer(Result.Data.Memory^, wChankSize);
Except
Result.ERROR := ReadError;
end;
f.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
r : TWaveResult;
i : integer;
W1, W2 : SmallInt;
begin
memo1.Clear;
if opendialog1.Execute
then
r := ReadWave(opendialog1.FileName);
r.Data.seek(0, soFromBeginning);
Form1.Canvas.MoveTo(80, 150);
for i := 1 to r.Data.Size div 4
do Begin
r.Data.readBuffer(W1, 2);
r.Data.readBuffer(W2, 2);
Form1.Canvas.LineTo(round(80+2000/r.Data.Size*i), round(150+W1/100));
{Memo1.Lines.Add('Left-' + IntToStr(W1) + ' ' +'Right-' + IntToStr(W2)) }
end;
end;
end.
но где здесь находятся отсчеты? Как их можно получить, чтобы потом применить преобразование Фурье? Я хочу их использовать для распознавания диктора. Помогите, пожалуйста. Заранее благодарю.