    {==============================================================================

        tchtone.pas  -  Copyright (C) 1996 by Don Cross <dcross@intersrv.com>
                        http://www.intersrv.com/~dcross

        This is an example of how to use the unit WavIO.
        This program generates touch tone noises in a WAV file as output.

        Revision history [most recent first]:

    1996 December 22 [Don Cross]
        Improved comments.
        Made program print my URL.

    1996 December 21 [Don Cross]
        First web posted to
        http://www.intersrv.com/~dcross/wavio.html#pascal

    ==============================================================================}

    program TouchToneGenerator;

    uses WavIO;

    const
        SamplingRate = 22050;  { Hz }
        BitsPerSample = 16;

        { Divide the following two numbers by SamplingRate }
        { to obtain their equivalent time duration in seconds. }
        OnSamples = 3000;   { Number of samples tone is turned on }
        OffSamples = 1000;  { Number of samples of silence between tones }

    procedure OutputTones (
        var outWave: WaveFile;
        f1, f2: integer );
    var
        deltaAngle, yk, y1, y2, y3, xk, x1, x2, x3: real;
        i: integer;
        numWritten: word;
        data: array [0..0] of integer;
    begin
        deltaAngle := 2 * PI * f1 / SamplingRate;
        yk := 2 * cos(deltaAngle);
        y1 := sin ( -2 * deltaAngle );
        y2 := sin ( -deltaAngle );

        deltaAngle := 2 * PI * f2 / SamplingRate;
        xk := 2 * cos(deltaAngle);
        x1 := sin ( -2 * deltaAngle );
        x2 := sin ( -deltaAngle );

        for i := 1 to OffSamples do begin
            data[0] := 0;
            outWave.WriteSampleData ( 1, numWritten, data );
        end;

        for i := 1 to OnSamples do begin
            y3 := yk*y2 - y1;
            y1 := y2;
            y2 := y3;

            x3 := xk*x2 - x1;
            x1 := x2;
            x2 := x3;

            data[0] := Trunc ( (x3 + y3) * 16000 );
            outWave.WriteSampleData ( 1, numWritten, data );
        end;
    end;

    procedure GenerateTouchTones (
        var outWave: WaveFile;
        phoneNumber: string );
    var
        i, f1, f2: integer;
    begin
        for i := 1 to Length(phoneNumber) do begin
            if phoneNumber[i] in ['0'..'9','#','*'] then begin
                case phoneNumber[i] of
                    '1', '2', '3':  f1 := 697;
                    '4', '5', '6':  f1 := 770;
                    '7', '8', '9':  f1 := 852;
                    '*', '0', '#':  f1 := 941;
                end;

                case phoneNumber[i] of
                    '1', '4', '7', '*':  f2 := 1209;
                    '2', '5', '8', '0':  f2 := 1336;
                    '3', '6', '9', '#':  f2 := 1477;
                end;

                OutputTones ( outWave, f1, f2 );
            end;
        end;
    end;

    var
        outWave: WaveFile;
        success: boolean;

    begin
        writeln ( 'Touch Tone WAV File Generator - by Don Cross <dcross@intersrv.com>' );
        writeln ( 'http://www.intersrv.com/~dcross' );
        writeln;

        if ParamCount <> 2 then begin
            writeln ( 'Use:  TCHTONE phoneNumber outputWavFile' );
            halt(1);
        end;

        outWave.Init;
        outWave.OpenForWrite ( ParamStr(2), SamplingRate, BitsPerSample, 1, success );
        if not success then begin
            writeln ( 'Error opening file "', ParamStr(2), '" for write.' );
            halt(1);
        end;

        GenerateTouchTones ( outWave, ParamStr(1) );

        outWave.Close;
        outWave.Destroy;
        halt(0);
    end.