-- Programmed by Jedidiah Barber -- Released into the public domain with Ada.Numerics.Long_Elementary_Functions, Ada.Text_IO, Interfaces, Portaudio.Streams; procedure Sine_Block is package Num renames Ada.Numerics; package Elem renames Ada.Numerics.Long_Elementary_Functions; package TIO renames Ada.Text_IO; package Paud renames Portaudio; package Pstm renames Portaudio.Streams; Play_Time : constant Paud.Time := 5.0; Sample_Rate : constant Paud.Hertz := 44100.0; Channels : constant Natural := 2; Per_Buffer : constant Pstm.Frame_Amount := 1024; -- Note how this array specifies the bounds in the initial value rather than the type. -- This is important because otherwise the aliasing would cause subtype mismatch errors. Sample_Array : aliased Pstm.Float_32_Array := (1 .. Natural (Per_Buffer) * Channels => 0.0); Sample_Buffer : Pstm.Buffer := Pstm.Wrap (Sample_Array, Per_Buffer, Channels); type Table_Index is mod 200; Sine_Table : array (Table_Index) of Interfaces.IEEE_Float_32; Left_Phase, Right_Phase : Table_Index := 0; Left_Increment : Table_Index := 1; Right_Increment : Table_Index := 3; Buffer_Count : Natural; Sine_Stream : Pstm.Audio_Stream; begin TIO.Put_Line ("PortAudio Test: output sine wave. " & "Sample Rate = " & Paud.Hertz_Image (Sample_Rate) & ", " & "Buffer Size =" & Pstm.Frame_Amount'Image (Per_Buffer)); for Index in Table_Index loop Sine_Table (Index) := Interfaces.IEEE_Float_32 (Elem.Sin (Long_Float (Index) / Long_Float (Table_Index'Last_Valid) * Num.Pi * 2.0)); end loop; Sine_Stream.Open_Default_Blocking (Input_Channels => 0, Output_Channels => Channels, Format => Pstm.Float_32_Format, Sample_Rate => Sample_Rate, Buffer_Frames => Per_Buffer); TIO.Put_Line ("Play 3 times, higher each time."); for Round in Integer range 1 .. 3 loop TIO.Put_Line ("Play for " & Paud.Image (Play_Time) & " seconds."); Sine_Stream.Start; Buffer_Count := Integer (Play_Time) * Integer (Sample_Rate) / Integer (Per_Buffer); for Fill in Integer range 1 .. Buffer_Count loop for Index in Pstm.Frame_Amount range 1 .. Per_Buffer loop Sample_Buffer.Put (Index, 1, Sine_Table (Left_Phase)); Sample_Buffer.Put (Index, 2, Sine_Table (Right_Phase)); Left_Phase := Left_Phase + Left_Increment; Right_Phase := Right_Phase + Right_Increment; end loop; Sine_Stream.Write_Blocking (Sample_Buffer, Per_Buffer); end loop; Sine_Stream.Stop; Left_Increment := Left_Increment + 1; Right_Increment := Right_Increment + 1; delay 1.0; end loop; Sine_Stream.Close; TIO.Put_Line ("Test finished."); end Sine_Block;