summaryrefslogtreecommitdiff
path: root/example/aao_example.adb
blob: 51466f8ade30ae06c375fe2eba4f443645916f51 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98


--  Programmed by Jedidiah Barber
--  Released into the public domain

--  This program opens the default libao driver and plays a 440 Hz tone for one second


with

    Ada.Command_Line,
    Ada.Numerics.Elementary_Functions,
    Ada.Text_IO,
    Interfaces,
    Libao;


procedure AAO_Example is

    package ACom renames Ada.Command_Line;
    package Math renames Ada.Numerics.Elementary_Functions;
    package TIO renames Ada.Text_IO;

    My_Device : Libao.Device;
    My_Format : Libao.Sample_Format;

    Default_Driver : Libao.Driver_ID_Number;

begin


    TIO.Put_Line ("libao example program");


    --  Setup for default driver

    Default_Driver := Libao.Default_Driver_ID;

    My_Format := Libao.Create
       (Bits           => 16,
        Rate           => 44100,
        Channels       => 2,
        Byte_Format    => Libao.Little_Endian,
        Channel_Matrix => Libao.Stereo);


    --  Open driver

    begin
        My_Device.Open_Live
           (Driver_ID => Default_Driver,
            Format    => My_Format,
            Options   => Libao.Empty_Options);
    exception
        when Libao.Open_Device_Error | Libao.General_Failure =>
            TIO.Put_Line ("Error opening device.");
            ACom.Set_Exit_Status (ACom.Failure);
            return;
    end;


    --  Play some stuff

    --  This sine wave generation was directly translated from the C example,
    --  but it ends up being a little messy playing fast and loose like this.

    declare
        Buffer : Libao.Data_Buffer (1 .. 16 / 8 * 2 * 44100);

        type Wraparound is mod 65536;
        Sample : Wraparound;
    begin
        for I in Integer range 0 .. 44100 - 1 loop
            Sample := Wraparound (Integer (0.75 * 32768.0 *
                Math.Sin (2.0 * Ada.Numerics.Pi * 440.0 * Float (I) / 44100.0)) mod 65536);

            --  Put the same stuff in left and right channel
            Buffer (4 * I + 1) := Interfaces.Unsigned_8 (Sample and 16#FF#);
            Buffer (4 * I + 2) := Interfaces.Unsigned_8 ((Sample / 256) and 16#FF#);
            Buffer (4 * I + 3) := Interfaces.Unsigned_8 (Sample and 16#FF#);
            Buffer (4 * I + 4) := Interfaces.Unsigned_8 ((Sample / 256) and 16#FF#);
        end loop;

        My_Device.Play (Buffer);
    end;


    --  Close and shutdown

    --  Technically the binding will take care of closing open devices at the
    --  end of runtime, but it is always good practice to close them anyway.

    My_Device.Close;


end AAO_Example;