unit uttsSaida;

interface
uses
    Windows, Classes, sysutils, mmsystem;

const
    waveHeaderSize = 44;

procedure genWavHdr (pvet: pchar; veloc: longint; bits, channels: word; size: longint);
procedure inicSaida;
procedure produzSaida (nomeArq: string; totalAmostras: integer);

var
    saida: array [0..1000000] of smallInt;
    isaida: integer;
    arqSom: file;

implementation

procedure genWavHdr (pvet: pchar; veloc: longint; bits, channels: word; size: longint);
const
    wavHdr: array [0..waveHeaderSize-1] of byte = (
        $52, $49, $46, $46,    {'RIFF'}
        $ff, $ff, $ff, $ff,    {riff size}
        $57, $41, $56, $45, $66, $6d, $74, $20,    {'WAVEFMT '}
        $10, $00, $00, $00,    {hdr size}
        $01, $00, $01, $00, $11, $2b, $00, $00, $11, $2b, $00, $00, $01, $00, $08, $00,  {reg}
        $64, $61, $74, $61,    {'data'}
        $ff, $ff, $ff, $ff);   {data size}

var l: longint;
    p: pointer;
    lpFormat: PPCMWAVEFORMAT;

begin
    new (lpFormat);
    with lpFormat^, lpFormat^.wf do
        begin
            wFormatTag := WAVE_FORMAT_PCM;
            nSamplesPerSec := veloc;
            wBitsPerSample := bits;
            nChannels := channels;
            nBlockAlign := (wBitsPerSample div 8) * nChannels;
            nAvgBytesPerSec := nBlockAlign * nSamplesPerSec;
        end;

    p := @wavHdr[20];
    move (lpFormat^, p^, sizeof (lpFormat^));
    l := size + 36;
    p := @wavHdr[4];
    move (l, p^, sizeof (l));
    p := @wavHdr[40];
    move (size, p^, sizeof (size));

    move (wavHdr, pvet^, sizeof (wavHdr));
    dispose (lpFormat);
end;

procedure inicSaida;
begin
    iSaida := waveHeaderSize div sizeof (smallInt);
end;

procedure produzSaida (nomeArq: string; totalAmostras: integer);
var i: integer;
begin
    for i := totalAmostras-2500-1 downto 22 do
        begin
            saida[i+2500] := trunc(saida[i]*0.1 + saida[i+2500] * 0.9);
        end;

    genWavHdr (@saida, 16000, 16, 1, totalAmostras*2);
    if nomeArq = '' then
        sndplaySound (@saida, SND_ASYNC+SND_MEMORY)
    else
        begin
            assign (arqSom, nomeArq);
            rewrite (arqSom, 1);
            blockWrite (arqSom, saida, waveHeaderSize + iSaida*2);
            closefile (arqSom);
        end;
end;

end.
