вот нашел исходник
Код:
Цитата:
Пример записи wav
Наконец дошли руки написал процедуру записи wav файлов.
Отмечаю следующие особенности: Запись TWaveHeaderChank следует обявлять с директивой packed, в связи с тем, что формат wav подразумевает выравнивание на границу 2 байт, а delphi по умалчанию выравнивает на границу 4 байт. Т.о. размер структуры TWaveHeaderChank без диретивы packed будет занимать 20 байт(структура в примере программ) вместо положенных 18.
Следующая программа записывает одноканальный wav файл длительностью 10 сек, 16 бит выборка. Звук будет напоминать свисты коротковолнового радиоприемника.
TWaveHeaderChank = packed record //Заголвок (чанк) формата
wFormatTag : Smallint;
wChannels : WORD;
wSamplesPerSec : Cardinal;
wAvgBytesPerSec: Cardinal;
wBlockAlign : WORD;
wBitsPerSample : WORD;
wcbSize : WORD;
end; -------------------------------------------------------------------
Const
noError = 0;
ReadError = 1;
HeaderError = 2;
DataError = 3;
FileCorrupt = 4;
IncorectFileFormat = 5;
HeaderWriteError = 6;
StreamError = 7; -------------------------------------------------------------------
Function WriteWave(FileName : AnsiString; data : TWaveResult) : WORD;
var
f : TFileStream;
wFileSize : Cardinal;
wChankSize : Cardinal;
ID : array[0..3] of Char;
Header : TWaveHeaderChank;
Begin
Result := noError;
Try
f := TFileStream.Create(FileName, fmCreate);
f.Seek(0, soFromBeginning);
Header.wFormatTag := 1;
Header.wChannels := data.wChannels;
Header.wSamplesPerSec := data.wSamplesPerSec;
Header.wBlockAlign := data.wChannels * (data.wBitsPerSample div 8);
Header.wAvgBytesPerSec:= data.wSamplesPerSec * Header.wBlockAlign;
Header.wBitsPerSample := data.wBitsPerSample;
Header.wcbSize := 0; //нет дополнительного блока
ID := 'RIFF';
f.WriteBuffer(ID, 4);
wFileSize := 0; //пока не известен
f.WriteBuffer(wFileSize, 4);
ID := 'WAVE';
f.WriteBuffer(ID, 4); //Запись идентификатора формата
ID := 'fmt ';
f.WriteBuffer(ID, 4); //Запись идентификатора чанка формата
wChankSize := SizeOf(Header);
f.WriteBuffer(wChankSize, 4); //Записьразмерачанка
f.WriteBuffer(Header, SizeOf(Header)); //Записьчанкаформата
except
Result := HeaderWriteError;
end;
Try
ID := 'data';
f.WriteBuffer(ID, 4); //Запись чанка данных
wChankSize := data.Data.Size; //Запись размера чанка
f.WriteBuffer(wChankSize, 4); //Записьданных
data.Data.Seek(0, soFromBeginning);
f.CopyFrom(data.Data, data.Data.Size);
except
Result := StreamError;
end;
f.Seek(SizeOf(ID), soFromBeginning); //Поискзаписиразмерафайла
wFileSize := f.Size - SizeOf(ID) - SizeOf(wFileSize);
f.Write(wFileSize, 4); //Запись размера файла - заголовок
f.Free;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
r : TWaveResult;
i : Integer;
d : SmallInt;
begin
r.ERROR := noError;
r.wSamplesPerSec := 44100;
r.wBitsPerSample := 16;
r.wChannels := 1;
r.Data := TMemoryStream.Create;
r.Data.Seek(0, soFromBeginning);
For i := 1 to 10 * r.wSamplesPerSec
do
Begin
d := Round(High(SmallInt) * Sin(2 * Pi * (5 * i / r.wSamplesPerSec) * (500 * i / r.wSamplesPerSec)));
r.Data.WriteBuffer(d, 2);
end;
WriteWave('Sample.wav', r);
r.Data.Free;
end;
|