Hi all,
I'm re-posting my TWAVBuffer class code as the previous time I posted it, the output code was garbled, and I also want to test the new formatter

[pascal]
Unit wav_buffer;
{$IFDEF fpc}
{$MODE DELPHI}
{$ENDIF}
{$H+}
Interface

Uses
Classes;

Type
{................................................. .............................}
TWAVBuffer = Class
Private
FStream : TStream;
FDuration_mSec : LongWord;
FNumberOfChannels : Byte;
FBitsPerSample : Byte;
FSampleRate : LongWord;
FNumberOfSamples : LongWord;
FDataSize : LongWord;
Procedure WriteWAVHeader;
Public
Constructor Create(Const AStream : TStream;
Const ADuration_mSec : LongWord;
Const ANumberOfChannels : Byte;
Const ABitsPerSample : Byte;
Const ASampleRate : LongWord);
Procedure Reset;
Procedure WriteSamples(Const ASamples : Array Of Single);
Property NumberOfSamples : LongWord Read FNumberOfSamples;
End;
{................................................. .............................}

Implementation

{................................................. .............................}

{................................................. .............................}
Constructor TWAVBuffer.Create(Const AStream : TStream;
Const ADuration_mSec : LongWord;
Const ANumberOfChannels : Byte;
Const ABitsPerSample : Byte;
Const ASampleRate : LongWord);
Begin
FStream := AStream;
FDuration_mSec := ADuration_mSec;
FNumberOfChannels := ANumberOfChannels;
FBitsPerSample := ABitsPerSample;
FSampleRate := ASampleRate;
If Not (FNumberOfChannels In[1,2]) Then FNumberOfChannels := 1;
If Not (FBitsPerSample In[8,16]) Then FBitsPerSample := 8;
FNumberOfSamples := (FDuration_mSec * FSampleRate) Div 1000;
FDataSize := (FBitsPerSample Shr 3) * FNumberOfChannels * FNumberOfSamples;
WriteWAVHeader;
End;
{................................................. .............................}

{................................................. .............................}
Procedure TWAVBuffer.WriteWAVHeader;
Const
WAVE_FORMAT_PCM = 1;
RiffId : AnsiString = 'RIFF';
WaveId : AnsiString = 'WAVE';
FmtId : AnsiString = 'fmt ';
DataId : AnsiString = 'data';

Type
TWaveHeader = Packed Record
wFormatTag : Word; { format type }
nChannels : Word; { number of channels (i.e. mono, stereo, etc.) }
nSamplesPerSec : LongWord; { sample rate }
nAvgBytesPerSec : LongWord; { for buffer estimation }
nBlockAlign : Word; { block size of data }
wBitsPerSample : Word; { number of bits per sample of mono data }
cbSize : Word; { the count in bytes of the size of }
End;
Var
WaveHeader : TWaveHeader;
RiffCount : Integer;
TempInt : LongWord;
Begin
With WaveHeader Do
Begin
wFormatTag := WAVE_FORMAT_PCM;
nChannels := FNumberOfChannels;
nSamplesPerSec := FSampleRate;
wBitsPerSample := FBitsPerSample;
nBlockAlign := nChannels * wBitsPerSample Shr 3;
nAvgBytesPerSec := nSamplesPerSec * nBlockAlign;
cbSize := 0;
End;
{Calculate length of sound data and of file data}
RiffCount := Length(WaveId) + Length(FmtId) + SizeOf(LongWord) +
SizeOf(TWaveHeader) + Length(DataId) + SizeOf(LongWord) + FDataSize; // file data
{write out the wave header}
FStream.Write(RiffId[1] , 4); // 'RIFF'
FStream.Write(RiffCount , SizeOf(LongWord)); // file data size
FStream.Write(WaveId[1] , Length(WaveId)); // 'WAVE'
FStream.Write(FmtId[1] , Length(FmtId)); // 'fmt '
TempInt := SizeOf(TWaveHeader);
FStream.Write(TempInt , SizeOf(LongWord)); // TWaveFormat data size
FStream.Write(WaveHeader , SizeOf(WaveHeader)); // WaveFormatEx record
FStream.Write(DataId[1] , Length(DataId)); // 'data'
FStream.Write(FDataSize , SizeOf(LongWord)); // sound data size
End;
{................................................. .............................}

{................................................. .............................}
Procedure TWAVBuffer.Reset;
Begin
FStream.Seek(0,soFromBeginning);
WriteWAVHeader;
End;
{................................................. .............................}

{................................................. .............................}
Procedure TWAVBuffer.WriteSamples(Const ASamples : Array Of Single);
Var
Sample_8Bit : Byte;
Sample_16Bit : SmallInt;
Sample : Single;
i : Integer;
Begin
For i := 0 To High(ASamples) Do
Begin
Sample := ASamples[i];
// clip sample to between [-1,+1]
If Sample < -1.0 Then Sample := -1.0
Else If Sample > +1.0 Then Sample := +1.0;
// write sample to stream
If FBitsPerSample = 8 Then
Begin
Sample_8Bit := 127 + Trunc(127 * Sample);
FStream.Write(Sample_8Bit,SizeOf(Sample_8Bit));
End
Else
If FBitsPerSample = 16 Then
Begin
Sample_16Bit := Trunc(32767 * Sample);
FStream.Write(Sample_16Bit,SizeOf(Sample_16Bit));
End;
End;
End;
{................................................. .............................}

{................................................. .............................}
End.
[/pascal]

cheers,
Paul