-- Programmed by Jedidiah Barber -- Released into the public domain pragma Ada_2012; with Interfaces; private with Interfaces.C, System; package Portaudio.Streams is --------------------------------- -- Data Types and Structures -- --------------------------------- type Sample_Format is (Float_32_Format, Int_32_Format, Int_24_Format, Int_16_Format, Int_8_Format, UInt_8_Format); -- This type isn't usually available in Interfaces type Integer_24 is range -2 ** 23 .. 2 ** 23 - 1; for Integer_24'Size use 24; -- When declaring these arrays, ensure that the bounds are specified by the -- initial value and not the subtype. Otherwise you will get subtype mismatch -- errors due to the aliasing required by the Wrap functions further down. -- No, I'm not a fan of this quirk of Ada either. type Float_32_Array is array (Positive range <>) of Interfaces.IEEE_Float_32; type Int_32_Array is array (Positive range <>) of Interfaces.Integer_32; type Int_24_Array is array (Positive range <>) of Integer_24; type Int_16_Array is array (Positive range <>) of Interfaces.Integer_16; type Int_8_Array is array (Positive range <>) of Interfaces.Integer_8; type UInt_8_Array is array (Positive range <>) of Interfaces.Unsigned_8; type Frame_Amount is new Interfaces.Unsigned_32; -- Acts as a wrapper around the arrays given above. -- This both avoids the use of void pointers, and also -- allows for easier reference to arrays by frame/channel. -- Since it is only a pointer wrapper, please ensure that -- every Buffer lives at least as long as any array used -- to make it. type Buffer is tagged private; function Kind (Store : in Buffer) return Sample_Format; function Channels (Store : in Buffer) return Natural; function Frames (Store : in Buffer) return Frame_Amount; function Get (Store : in Buffer; Frame : in Frame_Amount; Channel : in Positive) return Interfaces.IEEE_Float_32 with Pre => Store.Kind = Float_32_Format; function Get (Store : in Buffer; Frame : in Frame_Amount; Channel : in Positive) return Interfaces.Integer_32 with Pre => Store.Kind = Int_32_Format; function Get (Store : in Buffer; Frame : in Frame_Amount; Channel : in Positive) return Integer_24 with Pre => Store.Kind = Int_24_Format; function Get (Store : in Buffer; Frame : in Frame_Amount; Channel : in Positive) return Interfaces.Integer_16 with Pre => Store.Kind = Int_16_Format; function Get (Store : in Buffer; Frame : in Frame_Amount; Channel : in Positive) return Interfaces.Integer_8 with Pre => Store.Kind = Int_8_Format; function Get (Store : in Buffer; Frame : in Frame_Amount; Channel : in Positive) return Interfaces.Unsigned_8 with Pre => Store.Kind = UInt_8_Format; procedure Put (Store : in Buffer; Frame : in Frame_Amount; Channel : in Positive; Value : in Interfaces.IEEE_Float_32) with Pre => Store.Kind = Float_32_Format; procedure Put (Store : in Buffer; Frame : in Frame_Amount; Channel : in Positive; Value : in Interfaces.Integer_32) with Pre => Store.Kind = Int_32_Format; procedure Put (Store : in Buffer; Frame : in Frame_Amount; Channel : in Positive; Value : in Integer_24) with Pre => Store.Kind = Int_24_Format; procedure Put (Store : in Buffer; Frame : in Frame_Amount; Channel : in Positive; Value : in Interfaces.Integer_16) with Pre => Store.Kind = Int_16_Format; procedure Put (Store : in Buffer; Frame : in Frame_Amount; Channel : in Positive; Value : in Interfaces.Integer_8) with Pre => Store.Kind = Int_8_Format; procedure Put (Store : in Buffer; Frame : in Frame_Amount; Channel : in Positive; Value : in Interfaces.Unsigned_8) with Pre => Store.Kind = UInt_8_Format; function Wrap (Store : aliased in Float_32_Array; Frames : in Frame_Amount; Channels : in Natural) return Buffer with Pre => Store'Length > 0 and Store'Length = Frames * Frame_Amount (Channels); function Wrap (Store : aliased in Int_32_Array; Frames : in Frame_Amount; Channels : in Natural) return Buffer with Pre => Store'Length > 0 and Store'Length = Frames * Frame_Amount (Channels); function Wrap (Store : aliased in Int_24_Array; Frames : in Frame_Amount; Channels : in Natural) return Buffer with Pre => Store'Length > 0 and Store'Length = Frames * Frame_Amount (Channels); function Wrap (Store : aliased in Int_16_Array; Frames : in Frame_Amount; Channels : in Natural) return Buffer with Pre => Store'Length > 0 and Store'Length = Frames * Frame_Amount (Channels); function Wrap (Store : aliased in Int_8_Array; Frames : in Frame_Amount; Channels : in Natural) return Buffer with Pre => Store'Length > 0 and Store'Length = Frames * Frame_Amount (Channels); function Wrap (Store : aliased in UInt_8_Array; Frames : in Frame_Amount; Channels : in Natural) return Buffer with Pre => Store'Length > 0 and Store'Length = Frames * Frame_Amount (Channels); type Parameters is private; function Create (Device : in Device_Index; Channels : in Natural; Format : in Sample_Format; Latency : in Time) return Parameters with Pre => Device /= No_Device; type Stream_Flags is private; function "+" (A, B : in Stream_Flags) return Stream_Flags; -- No flags No_Flag : constant Stream_Flags; -- Disable default clipping Clip_Off_Flag : constant Stream_Flags; -- Disable default dithering Dither_Off_Flag : constant Stream_Flags; -- Never drop input Never_Drop_Flag : constant Stream_Flags; -- Prime output buffers using stream callback Prime_Output_Flag : constant Stream_Flags; type Audio_Stream is tagged limited private; type Stream_Info is record Input_Latency : Time; Output_Latency : Time; Sample_Rate : Hertz; end record; type Callback_Result is (Continue, Complete, Finish); type Time_Info is record Input_ADC : Time; Current : Time; Output_DAC : Time; end record; type Callback_Flags is record Input_Underflow : Boolean; Input_Overflow : Boolean; Output_Underflow : Boolean; Output_Overflow : Boolean; Priming_Output : Boolean; end record; -- Due to how void pointers are wrapped into Buffers, -- the Output here is given as 'in' mode, but you can -- still write to it just fine using the Put subprograms type Callback_Function is access function (Input : in Buffer; Output : in Buffer; Frames : in Frame_Amount; Timing : in Time_Info; Bunting : in Callback_Flags) return Callback_Result; --------------- -- Utility -- --------------- function Is_Open (Stream : in Audio_Stream) return Boolean; ----------------------- -- API Subprograms -- ----------------------- function Is_Format_Supported (Input : access Parameters; Output : access Parameters; Rate : in Hertz) return Boolean; procedure Open_Input (Stream : in out Audio_Stream; Input_Params : in Parameters; Sample_Rate : in Hertz; Buffer_Frames : in Frame_Amount; Bunting : in Stream_Flags; Callback : in Callback_Function) with Pre => not Stream.Is_Open, Post => Stream.Is_Open; procedure Open_Output (Stream : in out Audio_Stream; Output_Params : in Parameters; Sample_Rate : in Hertz; Buffer_Frames : in Frame_Amount; Bunting : in Stream_Flags; Callback : in Callback_Function) with Pre => not Stream.Is_Open, Post => Stream.Is_Open; procedure Open_Full (Stream : in out Audio_Stream; Input_Params : in Parameters; Output_Params : in Parameters; Sample_Rate : in Hertz; Buffer_Frames : in Frame_Amount; Bunting : in Stream_Flags; Callback : in Callback_Function) with Pre => not Stream.Is_Open, Post => Stream.Is_Open; procedure Open_Input_Blocking (Stream : in out Audio_Stream; Input_Params : in Parameters; Sample_Rate : in Hertz; Buffer_Frames : in Frame_Amount; Bunting : in Stream_Flags) with Pre => not Stream.Is_Open, Post => Stream.Is_Open; procedure Open_Output_Blocking (Stream : in out Audio_Stream; Output_Params : in Parameters; Sample_Rate : in Hertz; Buffer_Frames : in Frame_Amount; Bunting : in Stream_Flags) with Pre => not Stream.Is_Open, Post => Stream.Is_Open; procedure Open_Full_Blocking (Stream : in out Audio_Stream; Input_Params : in Parameters; Output_Params : in Parameters; Sample_Rate : in Hertz; Buffer_Frames : in Frame_Amount; Bunting : in Stream_Flags) with Pre => not Stream.Is_Open, Post => Stream.Is_Open; procedure Open_Default (Stream : in out Audio_Stream; Input_Channels : in Natural; Output_Channels : in Natural; Format : in Sample_Format; Sample_Rate : in Hertz; Buffer_Frames : in Frame_Amount; Callback : in Callback_Function) with Pre => not Stream.Is_Open and (Input_Channels > 0 or Output_Channels > 0), Post => Stream.Is_Open; procedure Open_Default_Blocking (Stream : in out Audio_Stream; Input_Channels : in Natural; Output_Channels : in Natural; Format : in Sample_Format; Sample_Rate : in Hertz; Buffer_Frames : in Frame_Amount) with Pre => not Stream.Is_Open and (Input_Channels > 0 or Output_Channels > 0), Post => Stream.Is_Open; procedure Close (Stream : in out Audio_Stream) with Pre => Stream.Is_Open, Post => not Stream.Is_Open; procedure Start (Stream : in Audio_Stream) with Pre => Stream.Is_Open; procedure Stop (Stream : in Audio_Stream) with Pre => Stream.Is_Open; procedure Term (Stream : in Audio_Stream) with Pre => Stream.Is_Open; function Is_Stopped (Stream : in Audio_Stream) return Boolean with Pre => Stream.Is_Open; function Is_Active (Stream : in Audio_Stream) return Boolean with Pre => Stream.Is_Open; function Get_Info (Stream : in Audio_Stream) return Stream_Info with Pre => Stream.Is_Open; function Get_Time (Stream : in Audio_Stream) return Time with Pre => Stream.Is_Open; function Get_CPU_Load (Stream : in Audio_Stream) return Load with Pre => Stream.Is_Open; procedure Read_Blocking (Stream : in Audio_Stream; Store : in Buffer'Class; Frames : in Frame_Amount) with Pre => Stream.Is_Open and then Stream.Is_Active; procedure Write_Blocking (Stream : in Audio_Stream; Store : in Buffer'Class; Frames : in Frame_Amount) with Pre => Stream.Is_Open and then Stream.Is_Active; function Get_Read_Available (Stream : in Audio_Stream) return Frame_Amount with Pre => Stream.Is_Open and then Stream.Is_Active; function Get_Write_Available (Stream : in Audio_Stream) return Frame_Amount with Pre => Stream.Is_Open and then Stream.Is_Active; function Get_Sample_Size (Format : in Sample_Format) return Positive; private pragma Convention (C, Float_32_Array); pragma Convention (C, Int_32_Array); pragma Convention (C, Int_24_Array); pragma Convention (C, Int_16_Array); pragma Convention (C, Int_8_Array); pragma Convention (C, UInt_8_Array); type Buffer is tagged record My_Sam_Code : Interfaces.C.unsigned_long; My_Channels : Natural; My_Frames : Frame_Amount; My_Array : System.Address; end record; type Parameters is record My_Device : Interfaces.C.int; My_Channels : Interfaces.C.int; My_Samples : Interfaces.C.unsigned_long; My_Latency : Interfaces.C.double; My_Specific : System.Address; end record with Convention => C; type Stream_Flags is new Interfaces.C.unsigned_long; No_Flag : constant Stream_Flags with Import => True, Convention => C, External_Name => "pa_no_flag"; Clip_Off_Flag : constant Stream_Flags with Import => True, Convention => C, External_Name => "pa_clip_off"; Dither_Off_Flag : constant Stream_Flags with Import => True, Convention => C, External_Name => "pa_dither_off"; Never_Drop_Flag : constant Stream_Flags with Import => True, Convention => C, External_Name => "pa_never_drop_input"; Prime_Output_Flag : constant Stream_Flags with Import => True, Convention => C, External_Name => "pa_prime_output_buffers_using_stream_callback"; type Audio_Stream is tagged limited record Ptr : System.Address; Open : Boolean := False; Func : Callback_Function; Chin : Interfaces.C.int := 0; Chout : Interfaces.C.int := 0; Sin : Interfaces.C.unsigned_long := 0; Sout : Interfaces.C.unsigned_long := 0; end record; type C_Stream_Info is record My_Struct_Version : Interfaces.C.int; My_Input_Latency : Interfaces.C.double; My_Output_Latency : Interfaces.C.double; My_Sample_Rate : Interfaces.C.double; end record with Convention => C; type C_Callback_Time_Info is record My_Input_ADC : Interfaces.C.double; My_Current : Interfaces.C.double; My_Output_DAC : Interfaces.C.double; end record with Convention => C; function To_For_Sam (Num : in Interfaces.C.unsigned_long) return Sample_Format; function To_Cnum (Format : in Sample_Format) return Interfaces.C.unsigned_long; function To_Cint (Ret_Value : in Callback_Result) return Interfaces.C.int; end Portaudio.Streams;