If it helps anyone, I have made a wav_buffer unit which allows you to create WAV format output to a stream like so:

Code:
Program WAV_buffer_test;
Uses
    Classes,
    wav_buffer;

Const
    cDuration_mSec    = 1000;
    cNumberOfChannels = 1;
    cSampleRate       = 44100;
    cBitsPerSample    = 16;
Var
    fs     : TFileStream;
    Buffer : TWAVBuffer;
    i      : LongWord;
    Sample : Single;
Begin
    fs := TFileStream.Create('c:\test.wav',fmCreate);
    Try
        Buffer := TWAVBuffer.Create(fs,cDuration_mSec,cNumberOfChannels,cBitsPerSample,cSampleRate);
        For i := 0 To Buffer.NumberOfSamples - 1 Do
        Begin
            // 1 complete sinewave cycle over the entire duration
            Sample := Sin(2 * PI * i / Buffer.NumberOfSamples);
            Buffer.WriteSamples([Sample]);
        End;
    Finally
        fs.Free;
    End;
End.
for 2 channels (stereo) just add another sample to the Buffer.WriteSamples line like so:

Code:
Buffer.WriteSamples([SampleL,SampleR]);
See unit below:

Code:
Unit wav_buffer;
{$IFDEF fpc}
{$MODE DELPHI} {$H+}
{$ENDIF}
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> +1.0 Then Sample &#58;= +1.0;
        // write sample to stream
        If FBitsPerSample = 8 Then
        Begin
            Sample_8Bit &#58;= 127 + Trunc&#40;127 * Sample&#41;;
            FStream.Write&#40;Sample_8Bit,SizeOf&#40;Sample_8Bit&#41;&#41;;
        End
        Else
        If FBitsPerSample = 16 Then
        Begin
            Sample_16Bit &#58;= Trunc&#40;32767 * Sample&#41;;
            FStream.Write&#40;Sample_16Bit,SizeOf&#40;Sample_16Bit&#41;&#41;;
        End;
    End;
End;
&#123;..............................................................................&#125;

&#123;..............................................................................&#125;
End.
I hope someone finds this useful :-)
cheers,
Paul