summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJedidiah Barber <contact@jedbarber.id.au>2023-07-15 20:18:26 +1200
committerJedidiah Barber <contact@jedbarber.id.au>2023-07-15 20:18:26 +1200
commit543cd19ab514ec632d965acd5177c5bf6695520f (patch)
treee15caec44e57a91c608f48c4f9a2bb38d4e76727
Initial commit
-rw-r--r--bin/.gitignore4
-rw-r--r--example.gpr31
-rw-r--r--example/device_list.adb202
-rw-r--r--example/saw_back.adb80
-rw-r--r--lib/.gitignore4
-rw-r--r--obj/.gitignore4
-rw-r--r--portadao.gpr24
-rw-r--r--readme.txt50
-rw-r--r--src/c_portadao.c125
-rw-r--r--src/c_portadao.h94
-rw-r--r--src/portaudio.adb2038
-rw-r--r--src/portaudio.ads933
-rw-r--r--unlicense.txt24
13 files changed, 3613 insertions, 0 deletions
diff --git a/bin/.gitignore b/bin/.gitignore
new file mode 100644
index 0000000..ea7f887
--- /dev/null
+++ b/bin/.gitignore
@@ -0,0 +1,4 @@
+
+
+*
+!.gitignore
diff --git a/example.gpr b/example.gpr
new file mode 100644
index 0000000..59431f1
--- /dev/null
+++ b/example.gpr
@@ -0,0 +1,31 @@
+
+
+with "portadao";
+
+
+project Example is
+
+
+ for languages use ("Ada");
+
+
+ for Source_Dirs use ("example");
+ for Object_Dir use "obj";
+ for Exec_Dir use "bin";
+ for Main use ("device_list.adb", "saw_back.adb");
+
+
+ package Builder is
+ for Executable ("device_list.adb") use "device_list";
+ for Executable ("saw_back.adb") use "saw_back";
+ end Builder;
+
+
+ package Compiler is
+ for Default_Switches("Ada") use ("-gnaty4aAbcefhiklM100nprt");
+ end Compiler;
+
+
+end Example;
+
+
diff --git a/example/device_list.adb b/example/device_list.adb
new file mode 100644
index 0000000..f9f6e65
--- /dev/null
+++ b/example/device_list.adb
@@ -0,0 +1,202 @@
+
+
+-- Programmed by Jedidiah Barber
+-- Released into the public domain
+
+
+with
+
+ Ada.Characters.Latin_1,
+ Ada.Text_IO,
+ Portaudio;
+
+use type
+
+ Portaudio.Device_Index,
+ Portaudio.Time;
+
+
+procedure Device_List is
+
+
+ package Latin renames Ada.Characters.Latin_1;
+ package TIO renames Ada.Text_IO;
+ package Paud renames Portaudio;
+
+
+ function Image
+ (Num : in Integer)
+ return String
+ is
+ Test_Out : String := Integer'Image (Num);
+ begin
+ if Test_Out (Test_Out'First) = ' ' then
+ return Test_Out (Test_Out'First + 1 .. Test_Out'Last);
+ else
+ return Test_Out;
+ end if;
+ end Image;
+
+
+ function Image
+ (Num : in Paud.Time)
+ return String is
+ begin
+ if Num < 0.0 then
+ return "N/A";
+ else
+ return Paud.Image (Num * 1000.0) & "ms";
+ end if;
+ end Image;
+
+
+ function Image
+ (Num : in Paud.Hertz)
+ return String is
+ begin
+ return Paud.Hertz_Image (Num / 1000.0) & "kHz";
+ end Image;
+
+
+ procedure Put_Supported_Standard_Sample_Rates
+ (In_Params : access Paud.Stream_Parameters;
+ Out_Params : access Paud.Stream_Parameters)
+ is
+ Standard_Sample_Rates : array (Positive range <>) of Paud.Hertz :=
+ (8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0,
+ 32000.0, 44100.0, 48000.0, 88200.0, 96000.0, 192000.0);
+ Put_Counter : Natural := 0;
+ begin
+ for Rate of Standard_Sample_Rates loop
+ if Paud.Is_Format_Supported (In_Params, Out_Params, Rate) then
+ case Put_Counter is
+ when 0 =>
+ TIO.Put (Latin.HT & Image (Rate));
+ Put_Counter := 1;
+ when 4 =>
+ TIO.Put (Latin.LF & Latin.HT & Image (Rate));
+ Put_Counter := 1;
+ when others =>
+ TIO.Put (", " & Image (Rate));
+ Put_Counter := Put_Counter + 1;
+ end case;
+ end if;
+ end loop;
+ if Put_Counter = 0 then
+ TIO.Put_Line ("None");
+ else
+ TIO.New_Line;
+ end if;
+ end Put_Supported_Standard_Sample_Rates;
+
+
+ Num_Devices : Natural;
+
+ Current_Device : Paud.Device_Info;
+ Current_Host_API : Paud.Host_API_Info;
+ Displayed_Default : Boolean;
+
+ Input_Params : aliased Paud.Stream_Parameters;
+ Output_Params : aliased Paud.Stream_Parameters;
+
+
+begin
+
+
+ TIO.Put_Line ("PortAudio version: " & Paud.Image (Paud.Get_Version));
+ TIO.Put_Line ("Version text: " & Paud.Get_Version_Info.Text);
+
+ Num_Devices := Paud.Get_Device_Count;
+ TIO.Put_Line ("Number of devices = " & Image (Num_Devices));
+
+ for Index in Paud.Device_Index (1) .. Paud.Device_Index (Num_Devices) loop
+ Current_Device := Paud.Get_Device_Info (Index);
+ Current_Host_API := Paud.Get_Host_API_Info (Current_Device.Host_API);
+ Displayed_Default := False;
+
+ TIO.New_Line;
+ TIO.Put_Line ("--------------------------------------- device #" &
+ Image (Integer (Index)));
+
+ if Index = Paud.Get_Default_Input_Device then
+ TIO.Put ("[ Default Input");
+ Displayed_Default := True;
+ elsif Index = Current_Host_API.Default_Input_Device then
+ TIO.Put ("[ Default " & Current_Host_API.Name & " Input");
+ Displayed_Default := True;
+ end if;
+
+ if Index = Paud.Get_Default_Output_Device then
+ if Displayed_Default then
+ TIO.Put (",");
+ else
+ TIO.Put ("[");
+ end if;
+ TIO.Put (" Default Output");
+ Displayed_Default := True;
+ elsif Index = Current_Host_API.Default_Output_Device then
+ if Displayed_Default then
+ TIO.Put (",");
+ else
+ TIO.Put ("[");
+ end if;
+ TIO.Put (" Default " & Current_Host_API.Name & " Output");
+ Displayed_Default := True;
+ end if;
+
+ if Displayed_Default then
+ TIO.Put_Line (" ]");
+ end if;
+
+ TIO.Put_Line ("Name = " & Current_Device.Name);
+ TIO.Put_Line ("Host API = " & Current_Host_API.Name);
+ TIO.Put_Line ("Max inputs = " & Image (Current_Device.Max_Input_Channels) &
+ ", Max outputs = " & Image (Current_Device.Max_Output_Channels));
+
+ TIO.Put_Line ("Default low input latency = " & Image
+ (Current_Device.Default_Low_Input_Latency));
+ TIO.Put_Line ("Default low output latency = " & Image
+ (Current_Device.Default_Low_Output_Latency));
+ TIO.Put_Line ("Default high input latency = " & Image
+ (Current_Device.Default_High_Input_Latency));
+ TIO.Put_Line ("Default high output latency = " & Image
+ (Current_Device.Default_High_Output_Latency));
+
+ TIO.Put_Line ("Default sample rate = " & Image
+ (Current_Device.Default_Sample_Rate));
+
+ Input_Params := Paud.Create
+ (Index, Current_Device.Max_Input_Channels, Paud.Int_16_Sample, 0.0);
+ Output_Params := Paud.Create
+ (Index, Current_Device.Max_Output_Channels, Paud.Int_16_Sample, 0.0);
+
+ if Current_Device.Max_Input_Channels > 0 then
+ TIO.Put_Line ("Supported standard sample rates");
+ TIO.Put_Line (" for half-duplex 16 bit " &
+ Image (Current_Device.Max_Input_Channels) & " channel input =");
+ Put_Supported_Standard_Sample_Rates (Input_Params'Access, null);
+ end if;
+
+ if Current_Device.Max_Output_Channels > 0 then
+ TIO.Put_Line ("Supported standard sample rates");
+ TIO.Put_Line (" for half-duplex 16 bit " &
+ Image (Current_Device.Max_Output_Channels) & " channel output =");
+ Put_Supported_Standard_Sample_Rates (null, Output_Params'Access);
+ end if;
+
+ if Current_Device.Max_Input_Channels > 0 and Current_Device.Max_Output_Channels > 0 then
+ TIO.Put_Line ("Supported standard sample rates");
+ TIO.Put_Line (" for full-duplex 16 bit " &
+ Image (Current_Device.Max_Input_Channels) & " channel input, " &
+ Image (Current_Device.Max_Output_Channels) & " channel output =");
+ Put_Supported_Standard_Sample_Rates (Input_Params'Access, Output_Params'Access);
+ end if;
+ end loop;
+
+ TIO.New_Line;
+ TIO.Put_Line ("----------------------------------------------");
+
+
+end Device_List;
+
+
diff --git a/example/saw_back.adb b/example/saw_back.adb
new file mode 100644
index 0000000..c266964
--- /dev/null
+++ b/example/saw_back.adb
@@ -0,0 +1,80 @@
+
+
+-- Programmed by Jedidiah Barber
+-- Released into the public domain
+
+
+with
+
+ Ada.Text_IO,
+ Portaudio;
+
+use type
+
+ Portaudio.Float_32;
+
+
+procedure Saw_Back is
+
+
+ Left_Phase, Right_Phase : Portaudio.Float_32 := 0.0;
+
+
+ function Saw_Callback
+ (Input : in Portaudio.Sample_Buffer;
+ Output : in Portaudio.Sample_Buffer;
+ Frames : in Portaudio.Frame_Amount;
+ Timing : in Portaudio.Callback_Time_Info;
+ Flags : in Portaudio.Callback_Flags)
+ return Portaudio.Callback_Result is
+ begin
+
+ for Frame in 1 .. Frames loop
+ Output.Put (Frame, 1, Left_Phase);
+ Output.Put (Frame, 2, Right_Phase);
+
+ Left_Phase := Left_Phase + 0.01;
+ if Left_Phase >= 1.0 then
+ Left_Phase := -1.0;
+ end if;
+
+ Right_Phase := Right_Phase + 0.03;
+ if Right_Phase >= 1.0 then
+ Right_Phase := -1.0;
+ end if;
+ end loop;
+
+ return Portaudio.Continue;
+
+ end Saw_Callback;
+
+
+ Saw_Stream : Portaudio.Audio_Stream;
+
+
+begin
+
+
+ Ada.Text_IO.Put_Line ("PortAudio Test: output sawtooth wave.");
+
+ Saw_Stream.Open_Default
+ (Input_Channels => 0,
+ Output_Channels => 2,
+ Format => Portaudio.Float_32_Sample,
+ Sample_Rate => 44100.0,
+ Buffer_Frames => 256,
+ Callback => Saw_Callback'Unrestricted_Access);
+
+ Saw_Stream.Start;
+
+ delay 4.0;
+
+ Saw_Stream.Stop;
+ Saw_Stream.Close;
+
+ Ada.Text_IO.Put_Line ("Test finished.");
+
+
+end Saw_Back;
+
+
diff --git a/lib/.gitignore b/lib/.gitignore
new file mode 100644
index 0000000..ea7f887
--- /dev/null
+++ b/lib/.gitignore
@@ -0,0 +1,4 @@
+
+
+*
+!.gitignore
diff --git a/obj/.gitignore b/obj/.gitignore
new file mode 100644
index 0000000..ea7f887
--- /dev/null
+++ b/obj/.gitignore
@@ -0,0 +1,4 @@
+
+
+*
+!.gitignore
diff --git a/portadao.gpr b/portadao.gpr
new file mode 100644
index 0000000..abe4d26
--- /dev/null
+++ b/portadao.gpr
@@ -0,0 +1,24 @@
+
+
+library project PortAdao is
+
+
+ for Languages use ("Ada", "C");
+
+
+ for Source_Dirs use ("src");
+ for Object_Dir use "obj";
+ for Library_Dir use "lib";
+ for Library_Name use "portadao";
+ for Library_Kind use "dynamic";
+
+
+ package Compiler is
+ for Default_Switches ("Ada") use ("-gnaty4aAbcefhiklM100nprt");
+ for Default_Switches ("C") use ("-Wall", "-Wextra");
+ end Compiler;
+
+
+end PortAdao;
+
+
diff --git a/readme.txt b/readme.txt
new file mode 100644
index 0000000..167f86a
--- /dev/null
+++ b/readme.txt
@@ -0,0 +1,50 @@
+
+
+PortAudio Binding for the Ada Programming Language
+==================================================
+
+
+Overview
+--------
+
+This is a thick binding, so effort has been made to get rid of all C-isms and
+C-specific types wherever possible.
+
+
+Dependencies
+------------
+
+GNAT (build)
+gprbuild (build)
+PortAudio (run)
+
+
+Build Instructions
+------------------
+
+Ensure that all dependencies are installed, including any developer or header
+packages for PortAudio. Then the following commands will build and install the
+binding:
+
+ gprbuild portadao.gpr
+ gprinstall -p -m portadao.gpr
+
+The other gpr file, example.gpr, can be used to build the few short example and
+test programs provided.
+
+
+Further Information
+-------------------
+
+API of PortAudio:
+http://files.portaudio.com/docs/v19-doxydocs/portaudio_8h.html
+
+
+Credits and Legal
+-----------------
+
+This binding and the Ada test/example programs were written by Jedidiah Barber.
+
+All code is released into the public domain.
+
+
diff --git a/src/c_portadao.c b/src/c_portadao.c
new file mode 100644
index 0000000..fc2e3b0
--- /dev/null
+++ b/src/c_portadao.c
@@ -0,0 +1,125 @@
+
+
+// Programmed by Jedidiah Barber
+// Released into the public domain
+
+
+#include <stdio.h>
+#include <unistd.h>
+#include <portaudio.h>
+#include "c_portadao.h"
+
+
+
+const int pa_no_error = paNoError;
+const int pa_not_initialized = paNotInitialized;
+const int pa_unanticipated_host_error = paUnanticipatedHostError;
+const int pa_invalid_channel_count = paInvalidChannelCount;
+const int pa_invalid_sample_rate = paInvalidSampleRate;
+const int pa_invalid_device = paInvalidDevice;
+const int pa_invalid_flag = paInvalidFlag;
+const int pa_sample_format_not_supported = paSampleFormatNotSupported;
+const int pa_bad_io_device_combination = paBadIODeviceCombination;
+const int pa_insufficient_memory = paInsufficientMemory;
+const int pa_buffer_too_big = paBufferTooBig;
+const int pa_buffer_too_small = paBufferTooSmall;
+const int pa_null_callback = paNullCallback;
+const int pa_bad_stream_ptr = paBadStreamPtr;
+const int pa_timed_out = paTimedOut;
+const int pa_internal_error = paInternalError;
+const int pa_device_unavailable = paDeviceUnavailable;
+const int pa_incompatible_host_api_specific_stream_info = paIncompatibleHostApiSpecificStreamInfo;
+const int pa_stream_is_stopped = paStreamIsStopped;
+const int pa_stream_is_not_stopped = paStreamIsNotStopped;
+const int pa_input_overflowed = paInputOverflowed;
+const int pa_output_underflowed = paOutputUnderflowed;
+const int pa_host_api_not_found = paHostApiNotFound;
+const int pa_invalid_host_api = paInvalidHostApi;
+const int pa_cannot_read_from_a_callback_stream = paCanNotReadFromACallbackStream;
+const int pa_cannot_write_to_a_callback_stream = paCanNotWriteToACallbackStream;
+const int pa_cannot_read_from_an_output_only_stream = paCanNotReadFromAnOutputOnlyStream;
+const int pa_cannot_write_to_an_input_only_stream = paCanNotWriteToAnInputOnlyStream;
+const int pa_incompatible_stream_host_api = paIncompatibleStreamHostApi;
+const int pa_bad_buffer_ptr = paBadBufferPtr;
+
+const int pa_in_development = paInDevelopment;
+const int pa_direct_sound = paDirectSound;
+const int pa_mme = paMME;
+const int pa_asio = paASIO;
+const int pa_sound_manager = paSoundManager;
+const int pa_core_audio = paCoreAudio;
+const int pa_oss = paOSS;
+const int pa_alsa = paALSA;
+const int pa_al = paAL;
+const int pa_beos = paBeOS;
+const int pa_wdmks = paWDMKS;
+const int pa_jack = paJACK;
+const int pa_wasapi = paWASAPI;
+const int pa_audio_science_hpi = paAudioScienceHPI;
+const int pa_sndio = paSndio;
+
+const int pa_no_device = paNoDevice;
+
+const unsigned long pa_float_32 = paFloat32;
+const unsigned long pa_int_32 = paInt32;
+const unsigned long pa_int_24 = paInt24;
+const unsigned long pa_int_16 = paInt16;
+const unsigned long pa_int_8 = paInt8;
+const unsigned long pa_uint_8 = paUInt8;
+
+const int pa_format_is_supported = paFormatIsSupported;
+
+const unsigned long pa_no_flag = paNoFlag;
+const unsigned long pa_clip_off = paClipOff;
+const unsigned long pa_dither_off = paDitherOff;
+const unsigned long pa_never_drop_input = paNeverDropInput;
+const unsigned long pa_prime_output_buffers_using_stream_callback =
+ paPrimeOutputBuffersUsingStreamCallback;
+
+const int pa_continue = paContinue;
+const int pa_complete = paComplete;
+const int pa_abort = paAbort;
+
+const unsigned long pa_input_underflow = paInputUnderflow;
+const unsigned long pa_input_overflow = paInputOverflow;
+const unsigned long pa_output_underflow = paOutputUnderflow;
+const unsigned long pa_output_overflow = paOutputOverflow;
+const unsigned long pa_priming_output = paPrimingOutput;
+
+
+
+int fd_backup;
+int suppressed = 0;
+
+void suppress_stderr() {
+ fflush(stderr);
+ fd_backup = dup(STDERR_FILENO);
+ //if (freopen("/dev/null", "w", stderr) == NULL) {
+ // freopen("nul", "w", stderr);
+ //}
+ close(STDERR_FILENO);
+ suppressed = 1;
+}
+
+void restore_stderr() {
+ fflush(stderr);
+ dup2(fd_backup, fileno(stderr));
+ close(fd_backup);
+ suppressed = 0;
+}
+
+int apa_init(int stop_msg) {
+ if (stop_msg) {
+ suppress_stderr();
+ }
+ return Pa_Initialize();
+}
+
+int apa_term() {
+ if (suppressed) {
+ restore_stderr();
+ }
+ return Pa_Terminate();
+}
+
+
diff --git a/src/c_portadao.h b/src/c_portadao.h
new file mode 100644
index 0000000..9bcd3be
--- /dev/null
+++ b/src/c_portadao.h
@@ -0,0 +1,94 @@
+
+
+// Programmed by Jedidiah Barber
+// Released into the public domain
+
+
+#ifndef PORTADAO_GUARD
+#define PORTADAO_GUARD
+
+#include <portaudio.h>
+
+
+extern const int pa_no_error;
+extern const int pa_not_initialized;
+extern const int pa_unanticipated_host_error;
+extern const int pa_invalid_channel_count;
+extern const int pa_invalid_sample_rate;
+extern const int pa_invalid_device;
+extern const int pa_invalid_flag;
+extern const int pa_sample_format_not_supported;
+extern const int pa_bad_io_device_combination;
+extern const int pa_insufficient_memory;
+extern const int pa_buffer_too_big;
+extern const int pa_buffer_too_small;
+extern const int pa_null_callback;
+extern const int pa_bad_stream_ptr;
+extern const int pa_timed_out;
+extern const int pa_internal_error;
+extern const int pa_device_unavailable;
+extern const int pa_incompatible_host_api_specific_stream_info;
+extern const int pa_stream_is_stopped;
+extern const int pa_stream_is_not_stopped;
+extern const int pa_input_overflowed;
+extern const int pa_output_underflowed;
+extern const int pa_host_api_not_found;
+extern const int pa_invalid_host_api;
+extern const int pa_cannot_read_from_a_callback_stream;
+extern const int pa_cannot_write_to_a_callback_stream;
+extern const int pa_cannot_read_from_an_output_only_stream;
+extern const int pa_cannot_write_to_an_input_only_stream;
+extern const int pa_incompatible_stream_host_api;
+extern const int pa_bad_buffer_ptr;
+
+extern const int pa_in_development;
+extern const int pa_direct_sound;
+extern const int pa_mme;
+extern const int pa_asio;
+extern const int pa_sound_manager;
+extern const int pa_core_audio;
+extern const int pa_oss;
+extern const int pa_alsa;
+extern const int pa_al;
+extern const int pa_beos;
+extern const int pa_wdmks;
+extern const int pa_jack;
+extern const int pa_wasapi;
+extern const int pa_audio_science_hpi;
+extern const int pa_sndio;
+
+extern const int pa_no_device;
+
+extern const unsigned long pa_float_32;
+extern const unsigned long pa_int_32;
+extern const unsigned long pa_int_24;
+extern const unsigned long pa_int_16;
+extern const unsigned long pa_int_8;
+extern const unsigned long pa_uint_8;
+
+extern const int pa_format_is_supported;
+
+extern const unsigned long pa_no_flag;
+extern const unsigned long pa_clip_off;
+extern const unsigned long pa_dither_off;
+extern const unsigned long pa_never_drop_input;
+extern const unsigned long pa_prime_output_buffers_using_stream_callback;
+
+extern const int pa_continue;
+extern const int pa_complete;
+extern const int pa_abort;
+
+extern const unsigned long pa_input_underflow;
+extern const unsigned long pa_input_overflow;
+extern const unsigned long pa_output_underflow;
+extern const unsigned long pa_output_overflow;
+extern const unsigned long pa_priming_output;
+
+
+int apa_init(int msg);
+int apa_term();
+
+
+#endif
+
+
diff --git a/src/portaudio.adb b/src/portaudio.adb
new file mode 100644
index 0000000..5b75a97
--- /dev/null
+++ b/src/portaudio.adb
@@ -0,0 +1,2038 @@
+
+
+-- Programmed by Jedidiah Barber
+-- Released into the public domain
+
+
+with
+
+ Ada.Strings.Fixed,
+ Interfaces.C.Strings,
+ System.Address_To_Access_Conversions;
+
+use type
+
+ Interfaces.C.double,
+ Interfaces.C.int,
+ Interfaces.C.long,
+ Interfaces.C.unsigned_long,
+ Interfaces.Unsigned_32,
+ System.Address;
+
+
+package body Portaudio is
+
+
+ ------------------------
+ -- Constants From C --
+ ------------------------
+
+ pa_no_error : constant Interfaces.C.int;
+ pragma Import (C, pa_no_error, "pa_no_error");
+
+ pa_not_initialized : constant Interfaces.C.int;
+ pragma Import (C, pa_not_initialized, "pa_not_initialized");
+
+ pa_unanticipated_host_error : constant Interfaces.C.int;
+ pragma Import (C, pa_unanticipated_host_error, "pa_unanticipated_host_error");
+
+ pa_invalid_channel_count : constant Interfaces.C.int;
+ pragma Import (C, pa_invalid_channel_count, "pa_invalid_channel_count");
+
+ pa_invalid_sample_rate : constant Interfaces.C.int;
+ pragma Import (C, pa_invalid_sample_rate, "pa_invalid_sample_rate");
+
+ pa_invalid_device : constant Interfaces.C.int;
+ pragma Import (C, pa_invalid_device, "pa_invalid_device");
+
+ pa_invalid_flag : constant Interfaces.C.int;
+ pragma Import (C, pa_invalid_flag, "pa_invalid_flag");
+
+ pa_sample_format_not_supported : constant Interfaces.C.int;
+ pragma Import (C, pa_sample_format_not_supported, "pa_sample_format_not_supported");
+
+ pa_bad_io_device_combination : constant Interfaces.C.int;
+ pragma Import (C, pa_bad_io_device_combination, "pa_bad_io_device_combination");
+
+ pa_insufficient_memory : constant Interfaces.C.int;
+ pragma Import (C, pa_insufficient_memory, "pa_insufficient_memory");
+
+ pa_buffer_too_big : constant Interfaces.C.int;
+ pragma Import (C, pa_buffer_too_big, "pa_buffer_too_big");
+
+ pa_buffer_too_small : constant Interfaces.C.int;
+ pragma Import (C, pa_buffer_too_small, "pa_buffer_too_small");
+
+ pa_null_callback : constant Interfaces.C.int;
+ pragma Import (C, pa_null_callback, "pa_null_callback");
+
+ pa_bad_stream_ptr : constant Interfaces.C.int;
+ pragma Import (C, pa_bad_stream_ptr, "pa_bad_stream_ptr");
+
+ pa_timed_out : constant Interfaces.C.int;
+ pragma Import (C, pa_timed_out, "pa_timed_out");
+
+ pa_internal_error : constant Interfaces.C.int;
+ pragma Import (C, pa_internal_error, "pa_internal_error");
+
+ pa_device_unavailable : constant Interfaces.C.int;
+ pragma Import (C, pa_device_unavailable, "pa_device_unavailable");
+
+ pa_incompatible_host_api_specific_stream_info : constant Interfaces.C.int;
+ pragma Import (C, pa_incompatible_host_api_specific_stream_info,
+ "pa_incompatible_host_api_specific_stream_info");
+
+ pa_stream_is_stopped : constant Interfaces.C.int;
+ pragma Import (C, pa_stream_is_stopped, "pa_stream_is_stopped");
+
+ pa_stream_is_not_stopped : constant Interfaces.C.int;
+ pragma Import (C, pa_stream_is_not_stopped, "pa_stream_is_not_stopped");
+
+ pa_input_overflowed : constant Interfaces.C.int;
+ pragma Import (C, pa_input_overflowed, "pa_input_overflowed");
+
+ pa_output_underflowed : constant Interfaces.C.int;
+ pragma Import (C, pa_output_underflowed, "pa_output_underflowed");
+
+ pa_host_api_not_found : constant Interfaces.C.int;
+ pragma Import (C, pa_host_api_not_found, "pa_host_api_not_found");
+
+ pa_invalid_host_api : constant Interfaces.C.int;
+ pragma Import (C, pa_invalid_host_api, "pa_invalid_host_api");
+
+ pa_cannot_read_from_a_callback_stream : constant Interfaces.C.int;
+ pragma Import (C, pa_cannot_read_from_a_callback_stream,
+ "pa_cannot_read_from_a_callback_stream");
+
+ pa_cannot_write_to_a_callback_stream : constant Interfaces.C.int;
+ pragma Import (C, pa_cannot_write_to_a_callback_stream,
+ "pa_cannot_write_to_a_callback_stream");
+
+ pa_cannot_read_from_an_output_only_stream : constant Interfaces.C.int;
+ pragma Import (C, pa_cannot_read_from_an_output_only_stream,
+ "pa_cannot_read_from_an_output_only_stream");
+
+ pa_cannot_write_to_an_input_only_stream : constant Interfaces.C.int;
+ pragma Import (C, pa_cannot_write_to_an_input_only_stream,
+ "pa_cannot_write_to_an_input_only_stream");
+
+ pa_incompatible_stream_host_api : constant Interfaces.C.int;
+ pragma Import (C, pa_incompatible_stream_host_api, "pa_incompatible_stream_host_api");
+
+ pa_bad_buffer_ptr : constant Interfaces.C.int;
+ pragma Import (C, pa_bad_buffer_ptr, "pa_bad_buffer_ptr");
+
+
+ pa_in_development : constant Interfaces.C.int;
+ pragma Import (C, pa_in_development, "pa_in_development");
+
+ pa_direct_sound : constant Interfaces.C.int;
+ pragma Import (C, pa_direct_sound, "pa_direct_sound");
+
+ pa_mme : constant Interfaces.C.int;
+ pragma Import (C, pa_mme, "pa_mme");
+
+ pa_asio : constant Interfaces.C.int;
+ pragma Import (C, pa_asio, "pa_asio");
+
+ pa_sound_manager : constant Interfaces.C.int;
+ pragma Import (C, pa_sound_manager, "pa_sound_manager");
+
+ pa_core_audio : constant Interfaces.C.int;
+ pragma Import (C, pa_core_audio, "pa_core_audio");
+
+ pa_oss : constant Interfaces.C.int;
+ pragma Import (C, pa_oss, "pa_oss");
+
+ pa_alsa : constant Interfaces.C.int;
+ pragma Import (C, pa_alsa, "pa_alsa");
+
+ pa_al : constant Interfaces.C.int;
+ pragma Import (C, pa_al, "pa_al");
+
+ pa_beos : constant Interfaces.C.int;
+ pragma Import (C, pa_beos, "pa_beos");
+
+ pa_wdmks : constant Interfaces.C.int;
+ pragma Import (C, pa_wdmks, "pa_wdmks");
+
+ pa_jack : constant Interfaces.C.int;
+ pragma Import (C, pa_jack, "pa_jack");
+
+ pa_wasapi : constant Interfaces.C.int;
+ pragma Import (C, pa_wasapi, "pa_wasapi");
+
+ pa_audio_science_hpi : constant Interfaces.C.int;
+ pragma Import (C, pa_audio_science_hpi, "pa_audio_science_hpi");
+
+ pa_sndio : constant Interfaces.C.int;
+ pragma Import (C, pa_sndio, "pa_sndio");
+
+
+ pa_no_device : constant Interfaces.C.int;
+ pragma Import (C, pa_no_device, "pa_no_device");
+
+
+ pa_float_32 : constant Interfaces.C.unsigned_long;
+ pragma Import (C, pa_float_32, "pa_float_32");
+
+ pa_int_32 : constant Interfaces.C.unsigned_long;
+ pragma Import (C, pa_int_32, "pa_int_32");
+
+ pa_int_24 : constant Interfaces.C.unsigned_long;
+ pragma Import (C, pa_int_24, "pa_int_24");
+
+ pa_int_16 : constant Interfaces.C.unsigned_long;
+ pragma Import (C, pa_int_16, "pa_int_16");
+
+ pa_int_8 : constant Interfaces.C.unsigned_long;
+ pragma Import (C, pa_int_8, "pa_int_8");
+
+ pa_uint_8 : constant Interfaces.C.unsigned_long;
+ pragma Import (C, pa_uint_8, "pa_uint_8");
+
+
+ pa_format_is_supported : constant Interfaces.C.int;
+ pragma Import (C, pa_format_is_supported, "pa_format_is_supported");
+
+
+ pa_continue : constant Interfaces.C.int;
+ pragma Import (C, pa_continue, "pa_continue");
+
+ pa_complete : constant Interfaces.C.int;
+ pragma Import (C, pa_complete, "pa_complete");
+
+ pa_abort : constant Interfaces.C.int;
+ pragma Import (C, pa_abort, "pa_abort");
+
+
+ pa_input_underflow : constant Interfaces.C.unsigned_long;
+ pragma Import (C, pa_input_underflow, "pa_input_underflow");
+
+ pa_input_overflow : constant Interfaces.C.unsigned_long;
+ pragma Import (C, pa_input_overflow, "pa_input_overflow");
+
+ pa_output_underflow : constant Interfaces.C.unsigned_long;
+ pragma Import (C, pa_output_underflow, "pa_output_underflow");
+
+ pa_output_overflow : constant Interfaces.C.unsigned_long;
+ pragma Import (C, pa_output_overflow, "pa_output_overflow");
+
+ pa_priming_output : constant Interfaces.C.unsigned_long;
+ pragma Import (C, pa_priming_output, "pa_priming_output");
+
+
+
+
+ ------------------------
+ -- Functions From C --
+ ------------------------
+
+ function pa_get_version
+ return Interfaces.C.int;
+ pragma Import (C, pa_get_version, "Pa_GetVersion");
+
+ function pa_get_version_info
+ return System.Address;
+ pragma Import (C, pa_get_version_info, "Pa_GetVersionInfo");
+
+ function pa_get_error_text
+ (Code : in Interfaces.C.int)
+ return Interfaces.C.Strings.chars_ptr;
+ pragma Import (C, pa_get_error_text, "Pa_GetErrorText");
+
+ function pa_initialize
+ (Sup : in Interfaces.C.int)
+ return Interfaces.C.int;
+ pragma Import (C, pa_initialize, "apa_init");
+
+ function pa_terminate
+ return Interfaces.C.int;
+ pragma Import (C, pa_terminate, "apa_term");
+
+ function pa_get_host_api_count
+ return Interfaces.C.int;
+ pragma Import (C, pa_get_host_api_count, "Pa_GetHostApiCount");
+
+ function pa_get_default_host_api
+ return Interfaces.C.int;
+ pragma Import (C, pa_get_default_host_api, "Pa_GetDefaultHostApi");
+
+ function pa_get_host_api_info
+ (Index : in Interfaces.C.int)
+ return System.Address;
+ pragma Import (C, pa_get_host_api_info, "Pa_GetHostApiInfo");
+
+ function pa_host_api_type_id_to_host_api_index
+ (Kind : in Interfaces.C.int)
+ return Interfaces.C.int;
+ pragma Import (C, pa_host_api_type_id_to_host_api_index, "Pa_HostApiTypeIdToHostApiIndex");
+
+ function pa_host_api_device_index_to_device_index
+ (Host : in Interfaces.C.int;
+ Dev : in Interfaces.C.int)
+ return Interfaces.C.int;
+ pragma Import (C, pa_host_api_device_index_to_device_index,
+ "Pa_HostApiDeviceIndexToDeviceIndex");
+
+ function pa_get_last_host_error_info
+ return System.Address;
+ pragma Import (C, pa_get_last_host_error_info, "Pa_GetLastHostErrorInfo");
+
+ function pa_get_device_count
+ return Interfaces.C.int;
+ pragma Import (C, pa_get_device_count, "Pa_GetDeviceCount");
+
+ function pa_get_default_input_device
+ return Interfaces.C.int;
+ pragma Import (C, pa_get_default_input_device, "Pa_GetDefaultInputDevice");
+
+ function pa_get_default_output_device
+ return Interfaces.C.int;
+ pragma Import (C, pa_get_default_output_device, "Pa_GetDefaultOutputDevice");
+
+ function pa_get_device_info
+ (Index : in Interfaces.C.int)
+ return System.Address;
+ pragma Import (C, pa_get_device_info, "Pa_GetDeviceInfo");
+
+ function pa_is_format_supported
+ (Input : in System.Address;
+ Output : in System.Address;
+ Rate : in Interfaces.C.double)
+ return Interfaces.C.int;
+ pragma Import (C, pa_is_format_supported, "Pa_IsFormatSupported");
+
+ function pa_open_stream
+ (Stream : in out System.Address;
+ In_Params : in System.Address;
+ Out_Params : in System.Address;
+ Rate : in Interfaces.C.double;
+ Frames : in Interfaces.C.unsigned_long;
+ Flags : in Interfaces.C.unsigned_long;
+ Callback : in System.Address;
+ Userdata : in System.Address)
+ return Interfaces.C.int;
+ pragma Import (C, pa_open_stream, "Pa_OpenStream");
+
+ function pa_open_default_stream
+ (Stream : in out System.Address;
+ In_Chans : in Interfaces.C.int;
+ Out_Chans : in Interfaces.C.int;
+ Format : in Interfaces.C.unsigned_long;
+ Rate : in Interfaces.C.double;
+ Frames : in Interfaces.C.unsigned_long;
+ Callback : in System.Address;
+ Userdata : in System.Address)
+ return Interfaces.C.int;
+ pragma Import (C, pa_open_default_stream, "Pa_OpenDefaultStream");
+
+ function pa_close_stream
+ (Stream : in System.Address)
+ return Interfaces.C.int;
+ pragma Import (C, pa_close_stream, "Pa_CloseStream");
+
+ function pa_set_stream_finished_callback
+ (Stream : in System.Address;
+ Callback : in System.Address)
+ return Interfaces.C.int;
+ pragma Import (C, pa_set_stream_finished_callback, "Pa_SetStreamFinishedCallback");
+
+ function pa_start_stream
+ (Stream : in System.Address)
+ return Interfaces.C.int;
+ pragma Import (C, pa_start_stream, "Pa_StartStream");
+
+ function pa_stop_stream
+ (Stream : in System.Address)
+ return Interfaces.C.int;
+ pragma Import (C, pa_stop_stream, "Pa_StopStream");
+
+ function pa_abort_stream
+ (Stream : in System.Address)
+ return Interfaces.C.int;
+ pragma Import (C, pa_abort_stream, "Pa_AbortStream");
+
+ function pa_is_stream_stopped
+ (Stream : in System.Address)
+ return Interfaces.C.int;
+ pragma Import (C, pa_is_stream_stopped, "Pa_IsStreamStopped");
+
+ function pa_is_stream_active
+ (Stream : in System.Address)
+ return Interfaces.C.int;
+ pragma Import (C, pa_is_stream_active, "Pa_IsStreamActive");
+
+ function pa_get_stream_info
+ (Stream : in System.Address)
+ return System.Address;
+ pragma Import (C, pa_get_stream_info, "Pa_GetStreamInfo");
+
+ function pa_get_stream_time
+ (Stream : in System.Address)
+ return Interfaces.C.double;
+ pragma Import (C, pa_get_stream_time, "Pa_GetStreamTime");
+
+ function pa_get_stream_cpu_load
+ (Stream : in System.Address)
+ return Interfaces.C.double;
+ pragma Import (C, pa_get_stream_cpu_load, "Pa_GetStreamCpuLoad");
+
+ function pa_read_stream
+ (Stream : in System.Address;
+ Buffer : in System.Address;
+ Frames : in Interfaces.C.unsigned_long)
+ return Interfaces.C.int;
+ pragma Import (C, pa_read_stream, "Pa_ReadStream");
+
+ function pa_write_stream
+ (Stream : in System.Address;
+ Buffer : in System.Address;
+ Frames : in Interfaces.C.unsigned_long)
+ return Interfaces.C.int;
+ pragma Import (C, pa_write_stream, "Pa_WriteStream");
+
+ function pa_get_stream_read_available
+ (Stream : in System.Address)
+ return Interfaces.C.long;
+ pragma Import (C, pa_get_stream_read_available, "Pa_GetStreamReadAvailable");
+
+ function pa_get_stream_write_available
+ (Stream : in System.Address)
+ return Interfaces.C.long;
+ pragma Import (C, pa_get_stream_write_available, "Pa_GetStreamWriteAvailable");
+
+ function pa_get_sample_size
+ (Form : in Interfaces.C.unsigned_long)
+ return Interfaces.C.int;
+ pragma Import (C, pa_get_sample_size, "Pa_GetSampleSize");
+
+
+
+
+ ------------------------
+ -- Internal Utility --
+ ------------------------
+
+ procedure Raise_Error
+ (Num : in Interfaces.C.int) is
+ begin
+ if Num = pa_not_initialized then
+ raise Not_Initialized_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_unanticipated_host_error then
+ declare
+ Info : C_Host_Error_Info;
+ for Info'Address use pa_get_last_host_error_info;
+ pragma Import (Ada, Info);
+ begin
+ raise Unanticipated_Host_Error with
+ Host_API_Kind'Image (To_Hat_Kind (Info.My_Host_API_Type)) & " " &
+ Interfaces.C.Strings.Value (Info.My_Error_Text);
+ end;
+ elsif Num = pa_invalid_channel_count then
+ raise Invalid_Channel_Count_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_invalid_sample_rate then
+ raise Invalid_Sample_Rate_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_invalid_device then
+ raise Invalid_Device_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_invalid_flag then
+ raise Invalid_Flag_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_sample_format_not_supported then
+ raise Sample_Format_Not_Supported_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_bad_io_device_combination then
+ raise Bad_IO_Device_Combination_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_insufficient_memory then
+ raise Storage_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_buffer_too_big then
+ raise Buffer_Too_Big_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_buffer_too_small then
+ raise Buffer_Too_Small_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_null_callback then
+ raise Null_Callback_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_bad_stream_ptr then
+ raise Bad_Stream_Pointer_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_timed_out then
+ raise Timed_Out_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_internal_error then
+ raise Internal_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_device_unavailable then
+ raise Device_Unavailable_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_incompatible_host_api_specific_stream_info then
+ raise Incompatible_Host_API_Specific_Stream_Info_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_stream_is_stopped then
+ raise Stream_Is_Stopped_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_stream_is_not_stopped then
+ raise Stream_Is_Not_Stopped_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_input_overflowed then
+ raise Input_Overflowed_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_output_underflowed then
+ raise Output_Underflowed_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_host_api_not_found then
+ raise Host_API_Not_Found_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_invalid_host_api then
+ raise Invalid_Host_API_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_cannot_read_from_a_callback_stream then
+ raise Can_Not_Read_From_A_Callback_Stream_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_cannot_write_to_a_callback_stream then
+ raise Can_Not_Write_To_A_Callback_Stream_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_cannot_read_from_an_output_only_stream then
+ raise Can_Not_Read_From_An_Output_Only_Stream_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_cannot_write_to_an_input_only_stream then
+ raise Can_Not_Write_To_An_Input_Only_Stream_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_incompatible_stream_host_api then
+ raise Incompatible_Stream_Host_API_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ elsif Num = pa_bad_buffer_ptr then
+ raise Bad_Buffer_Pointer_Error with
+ Interfaces.C.Strings.Value (pa_get_error_text (Num));
+ else
+ raise General_Failure;
+ end if;
+ end Raise_Error;
+
+ function To_Hat_Kind
+ (Num : in Interfaces.C.int)
+ return Host_API_Kind is
+ begin
+ if Num = pa_in_development then
+ return In_Development;
+ elsif Num = pa_direct_sound then
+ return Direct_Sound_Host;
+ elsif Num = pa_mme then
+ return MME_Host;
+ elsif Num = pa_asio then
+ return ASIO_Host;
+ elsif Num = pa_sound_manager then
+ return Sound_Manager_Host;
+ elsif Num = pa_core_audio then
+ return Core_Audio_Host;
+ elsif Num = pa_oss then
+ return OSS_Host;
+ elsif Num = pa_alsa then
+ return ALSA_Host;
+ elsif Num = pa_al then
+ return AL_Host;
+ elsif Num = pa_beos then
+ return BeOS_Host;
+ elsif Num = pa_wdmks then
+ return WDMKS_Host;
+ elsif Num = pa_jack then
+ return JACK_Host;
+ elsif Num = pa_wasapi then
+ return WASAPI_Host;
+ elsif Num = pa_audio_science_hpi then
+ return Audio_Science_HPI_Host;
+ elsif Num = pa_sndio then
+ return Sndio_Host;
+ else
+ raise Program_Error;
+ end if;
+ end To_Hat_Kind;
+
+ function To_Cint
+ (Ident : in Host_API_Kind)
+ return Interfaces.C.int is
+ begin
+ case Ident is
+ when In_Development => return pa_in_development;
+ when Direct_Sound_Host => return pa_direct_sound;
+ when MME_Host => return pa_mme;
+ when ASIO_Host => return pa_asio;
+ when Sound_Manager_Host => return pa_sound_manager;
+ when Core_Audio_Host => return pa_core_audio;
+ when OSS_Host => return pa_oss;
+ when ALSA_Host => return pa_alsa;
+ when AL_Host => return pa_al;
+ when BeOS_Host => return pa_beos;
+ when WDMKS_Host => return pa_wdmks;
+ when JACK_Host => return pa_jack;
+ when WASAPI_Host => return pa_wasapi;
+ when Audio_Science_HPI_Host => return pa_audio_science_hpi;
+ when Sndio_Host => return pa_sndio;
+ end case;
+ end To_Cint;
+
+ function To_For_Sam
+ (Num : in Interfaces.C.unsigned_long)
+ return Sample_Format is
+ begin
+ if Num = pa_float_32 then
+ return Float_32_Sample;
+ elsif Num = pa_int_32 then
+ return Int_32_Sample;
+ elsif Num = pa_int_24 then
+ return Int_24_Sample;
+ elsif Num = pa_int_16 then
+ return Int_16_Sample;
+ elsif Num = pa_int_8 then
+ return Int_8_Sample;
+ elsif Num = pa_uint_8 then
+ return UInt_8_Sample;
+ else
+ raise Program_Error;
+ end if;
+ end To_For_Sam;
+
+ function To_Cnum
+ (Form : in Sample_Format)
+ return Interfaces.C.unsigned_long is
+ begin
+ case Form is
+ when Float_32_Sample => return pa_float_32;
+ when Int_32_Sample => return pa_int_32;
+ when Int_24_Sample => return pa_int_24;
+ when Int_16_Sample => return pa_int_16;
+ when Int_8_Sample => return pa_int_8;
+ when UInt_8_Sample => return pa_uint_8;
+ end case;
+ end To_Cnum;
+
+ function To_Cint
+ (Result : in Callback_Result)
+ return Interfaces.C.int is
+ begin
+ case Result is
+ when Continue => return pa_continue;
+ when Complete => return pa_complete;
+ when Finish => return pa_abort;
+ end case;
+ end To_Cint;
+
+
+
+
+ -----------------------------------
+ -- Controlled Type Subprograms --
+ -----------------------------------
+
+ procedure Finalize
+ (This : in out Final_Controller)
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_terminate;
+ if Code /= pa_no_error then
+ Raise_Error (Code);
+ raise Program_Error;
+ end if;
+ end Finalize;
+
+
+
+
+ ----------------------
+ -- Callback Hooks --
+ ----------------------
+
+ function Stream_Callback_Hook
+ (Input_Ptr : in System.Address;
+ Output_Ptr : in System.Address;
+ Frame_Count : in Interfaces.C.unsigned_long;
+ Time_Ptr : in System.Address;
+ Flag_Mask : in Interfaces.C.unsigned_long;
+ Userdata : in System.Address)
+ return Interfaces.C.int
+ is
+ Stream_Actual : Audio_Stream;
+ for Stream_Actual'Address use Userdata;
+ pragma Import (Ada, Stream_Actual);
+
+ Input_Buffer : Sample_Buffer :=
+ (My_Sam_Code => Stream_Actual.Sin,
+ My_Channels => Natural (Stream_Actual.Chin),
+ My_Frames => Frame_Amount (Frame_Count),
+ My_Array => Input_Ptr);
+
+ Output_Buffer : Sample_Buffer :=
+ (My_Sam_Code => Stream_Actual.Sout,
+ My_Channels => Natural (Stream_Actual.Chout),
+ My_Frames => Frame_Amount (Frame_Count),
+ My_Array => Output_Ptr);
+
+ Result : Callback_Result;
+ begin
+ Result := Stream_Actual.Func
+ (Input_Buffer,
+ Output_Buffer,
+ Frame_Amount (Frame_Count),
+ (Ptr => Time_Ptr),
+ Callback_Flags (Flag_Mask));
+ return To_Cint (Result);
+ end Stream_Callback_Hook;
+
+
+
+
+ ---------------------------------
+ -- Data Types and Structures --
+ ---------------------------------
+
+ function "<"
+ (A, B : in Version_Number)
+ return Boolean is
+ begin
+ return (A.Major < B.Major) or else
+ (A.Major = B.Major and A.Minor < B.Minor) or else
+ (A.Major = B.Major and A.Minor = B.Minor and A.Subminor < B.Subminor);
+ end "<";
+
+ function Image
+ (Num : in Version_Number)
+ return String
+ is
+ function Img
+ (Int : in Integer)
+ return String is
+ begin
+ return Ada.Strings.Fixed.Trim (Integer'Image (Int), Ada.Strings.Both);
+ end Img;
+ begin
+ return Img (Num.Major) & "." & Img (Num.Minor) & "." & Img (Num.Subminor);
+ end Image;
+
+
+ function Major
+ (Version : in Version_Info)
+ return Natural
+ is
+ Internal : C_Version_Info;
+ for Internal'Address use Version.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return Natural (Internal.My_Major);
+ end Major;
+
+ function Minor
+ (Version : in Version_Info)
+ return Natural
+ is
+ Internal : C_Version_Info;
+ for Internal'Address use Version.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return Natural (Internal.My_Minor);
+ end Minor;
+
+ function Subminor
+ (Version : in Version_Info)
+ return Natural
+ is
+ Internal : C_Version_Info;
+ for Internal'Address use Version.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return Natural (Internal.My_Subminor);
+ end Subminor;
+
+ function Revision
+ (Version : in Version_Info)
+ return String
+ is
+ Internal : C_Version_Info;
+ for Internal'Address use Version.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return Interfaces.C.Strings.Value (Internal.My_Revision);
+ end Revision;
+
+ function Text
+ (Version : in Version_Info)
+ return String
+ is
+ Internal : C_Version_Info;
+ for Internal'Address use Version.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return Interfaces.C.Strings.Value (Internal.My_Text);
+ end Text;
+
+
+ function Kind
+ (Info : in Host_API_Info)
+ return Host_API_Kind
+ is
+ Internal : C_Host_API_Info;
+ for Internal'Address use Info.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return To_Hat_Kind (Internal.My_Host_API_Type);
+ end Kind;
+
+ function Name
+ (Info : in Host_API_Info)
+ return String
+ is
+ Internal : C_Host_API_Info;
+ for Internal'Address use Info.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return Interfaces.C.Strings.Value (Internal.My_Name);
+ end Name;
+
+ function Device_Count
+ (Info : in Host_API_Info)
+ return Natural
+ is
+ Internal : C_Host_API_Info;
+ for Internal'Address use Info.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return Natural (Internal.My_Device_Count);
+ end Device_Count;
+
+ function Default_Input_Device
+ (Info : in Host_API_Info)
+ return Device_Index
+ is
+ Internal : C_Host_API_Info;
+ for Internal'Address use Info.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ if Internal.My_Default_Input = pa_no_device then
+ return No_Device;
+ else
+ return Device_Index (Internal.My_Default_Input) + 1;
+ end if;
+ end Default_Input_Device;
+
+ function Default_Output_Device
+ (Info : in Host_API_Info)
+ return Device_Index
+ is
+ Internal : C_Host_API_Info;
+ for Internal'Address use Info.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ if Internal.My_Default_Output = pa_no_device then
+ return No_Device;
+ else
+ return Device_Index (Internal.My_Default_Output) + 1;
+ end if;
+ end Default_Output_Device;
+
+
+ function Image
+ (Num : in Time)
+ return String
+ is
+ Test_Out : String := Time'Image (Num);
+ Mark_Start : Integer := Test_Out'First;
+ Mark_End : Integer := Test_Out'Last;
+ begin
+ if Test_Out (Mark_Start) = ' ' then
+ Mark_Start := Mark_Start + 1;
+ end if;
+ while Test_Out (Mark_End) = '0' loop
+ Mark_End := Mark_End - 1;
+ end loop;
+ if Test_Out (Mark_End) = '.' then
+ Mark_End := Mark_End - 1;
+ end if;
+ return Test_Out (Mark_Start .. Mark_End);
+ end Image;
+
+
+ function Hertz_Image
+ (Num : in Hertz)
+ return String
+ is
+ type Large_Hack is delta 10.0**(-10) digits 30;
+ Converted : Large_Hack := Large_Hack (Num);
+ Prelim : String := Large_Hack'Image (Converted);
+ Test_Out : String :=
+ (if Prelim (Prelim'Last) /= '9' then Prelim
+ elsif Prelim (Prelim'First) = '-' then Large_Hack'Image (Large_Hack'Pred (Converted))
+ else Large_Hack'Image (Large_Hack'Succ (Converted)));
+ Mark_Start : Integer := Test_Out'First + 1;
+ Mark_End : Integer := Test_Out'Last;
+ begin
+ while Test_Out (Mark_End) = '0' loop
+ Mark_End := Mark_End - 1;
+ end loop;
+ if Test_Out (Mark_End) = '.' then
+ Mark_End := Mark_End - 1;
+ end if;
+ return Test_Out (Mark_Start .. Mark_End);
+ end Hertz_Image;
+
+
+ function Load_Image
+ (Num : in Load)
+ return String
+ is
+ type Two_Digit_Hack is delta 10.0**(-2) digits 4;
+ Test_Out : String := Two_Digit_Hack'Image (Two_Digit_Hack (Num));
+ Mark_Start : Integer := Test_Out'First + 1;
+ Mark_End : Integer := Test_Out'Last;
+ begin
+ while Test_Out (Mark_End) = '0' loop
+ Mark_End := Mark_End - 1;
+ end loop;
+ if Test_Out (Mark_End) = '.' then
+ Mark_End := Mark_End - 1;
+ end if;
+ return Test_Out (Mark_Start .. Mark_End);
+ end Load_Image;
+
+
+ function Name
+ (Info : in Device_Info)
+ return String
+ is
+ Internal : C_Device_Info;
+ for Internal'Address use Info.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return Interfaces.C.Strings.Value (Internal.My_Name);
+ end Name;
+
+ function Host_API
+ (Info : in Device_Info)
+ return Host_API_Index
+ is
+ Internal : C_Device_Info;
+ for Internal'Address use Info.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return Host_API_Index (Internal.My_Host_API_Index + 1);
+ end Host_API;
+
+ function Max_Input_Channels
+ (Info : in Device_Info)
+ return Natural
+ is
+ Internal : C_Device_Info;
+ for Internal'Address use Info.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return Natural (Internal.My_Input_Channels);
+ end Max_Input_Channels;
+
+ function Max_Output_Channels
+ (Info : in Device_Info)
+ return Natural
+ is
+ Internal : C_Device_Info;
+ for Internal'Address use Info.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return Natural (Internal.My_Output_Channels);
+ end Max_Output_Channels;
+
+ function Default_Low_Input_Latency
+ (Info : in Device_Info)
+ return Time
+ is
+ Internal : C_Device_Info;
+ for Internal'Address use Info.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return Time (Internal.My_Low_Input_Latency);
+ end Default_Low_Input_Latency;
+
+ function Default_Low_Output_Latency
+ (Info : in Device_Info)
+ return Time
+ is
+ Internal : C_Device_Info;
+ for Internal'Address use Info.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return Time (Internal.My_Low_Output_Latency);
+ end Default_Low_Output_Latency;
+
+ function Default_High_Input_Latency
+ (Info : in Device_Info)
+ return Time
+ is
+ Internal : C_Device_Info;
+ for Internal'Address use Info.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return Time (Internal.My_High_Input_Latency);
+ end Default_High_Input_Latency;
+
+ function Default_High_Output_Latency
+ (Info : in Device_Info)
+ return Time
+ is
+ Internal : C_Device_Info;
+ for Internal'Address use Info.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return Time (Internal.My_High_Output_Latency);
+ end Default_High_Output_Latency;
+
+ function Default_Sample_Rate
+ (Info : in Device_Info)
+ return Hertz
+ is
+ Internal : C_Device_Info;
+ for Internal'Address use Info.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return Hertz (Internal.My_Sample_Rate);
+ end Default_Sample_Rate;
+
+
+ function Kind
+ (Buffer : in Sample_Buffer)
+ return Sample_Format is
+ begin
+ return To_For_Sam (Buffer.My_Sam_Code);
+ end Kind;
+
+ function Channels
+ (Buffer : in Sample_Buffer)
+ return Natural is
+ begin
+ return Buffer.My_Channels;
+ end Channels;
+
+ function Frames
+ (Buffer : in Sample_Buffer)
+ return Frame_Amount is
+ begin
+ return Buffer.My_Frames;
+ end Frames;
+
+ function Get
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive)
+ return Float_32
+ is
+ Actual : Float_32_Array (1 .. Buffer.My_Channels * Integer (Buffer.My_Frames));
+ for Actual'Address use Buffer.My_Array;
+ pragma Import (Ada, Actual);
+ begin
+ return Actual ((Integer (Frame) - 1) * Buffer.My_Channels + Channel);
+ end Get;
+
+ function Get
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive)
+ return Int_32
+ is
+ Actual : Int_32_Array (1 .. Buffer.My_Channels * Integer (Buffer.My_Frames));
+ for Actual'Address use Buffer.My_Array;
+ pragma Import (Ada, Actual);
+ begin
+ return Actual ((Integer (Frame) - 1) * Buffer.My_Channels + Channel);
+ end Get;
+
+ function Get
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive)
+ return Int_24
+ is
+ Actual : Int_24_Array (1 .. Buffer.My_Channels * Integer (Buffer.My_Frames));
+ for Actual'Address use Buffer.My_Array;
+ pragma Import (Ada, Actual);
+ begin
+ return Actual ((Integer (Frame) - 1) * Buffer.My_Channels + Channel);
+ end Get;
+
+ function Get
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive)
+ return Int_16
+ is
+ Actual : Int_16_Array (1 .. Buffer.My_Channels * Integer (Buffer.My_Frames));
+ for Actual'Address use Buffer.My_Array;
+ pragma Import (Ada, Actual);
+ begin
+ return Actual ((Integer (Frame) - 1) * Buffer.My_Channels + Channel);
+ end Get;
+
+ function Get
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive)
+ return Int_8
+ is
+ Actual : Int_8_Array (1 .. Buffer.My_Channels * Integer (Buffer.My_Frames));
+ for Actual'Address use Buffer.My_Array;
+ pragma Import (Ada, Actual);
+ begin
+ return Actual ((Integer (Frame) - 1) * Buffer.My_Channels + Channel);
+ end Get;
+
+ function Get
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive)
+ return UInt_8
+ is
+ Actual : UInt_8_Array (1 .. Buffer.My_Channels * Integer (Buffer.My_Frames));
+ for Actual'Address use Buffer.My_Array;
+ pragma Import (Ada, Actual);
+ begin
+ return Actual ((Integer (Frame) - 1) * Buffer.My_Channels + Channel);
+ end Get;
+
+ procedure Put
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive;
+ Value : in Float_32)
+ is
+ Actual : Float_32_Array (1 .. Buffer.My_Channels * Integer (Buffer.My_Frames));
+ for Actual'Address use Buffer.My_Array;
+ pragma Import (Ada, Actual);
+ begin
+ Actual ((Integer (Frame) - 1) * Buffer.My_Channels + Channel) := Value;
+ end Put;
+
+ procedure Put
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive;
+ Value : in Int_32)
+ is
+ Actual : Int_32_Array (1 .. Buffer.My_Channels * Integer (Buffer.My_Frames));
+ for Actual'Address use Buffer.My_Array;
+ pragma Import (Ada, Actual);
+ begin
+ Actual ((Integer (Frame) - 1) * Buffer.My_Channels + Channel) := Value;
+ end Put;
+
+ procedure Put
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive;
+ Value : in Int_24)
+ is
+ Actual : Int_24_Array (1 .. Buffer.My_Channels * Integer (Buffer.My_Frames));
+ for Actual'Address use Buffer.My_Array;
+ pragma Import (Ada, Actual);
+ begin
+ Actual ((Integer (Frame) - 1) * Buffer.My_Channels + Channel) := Value;
+ end Put;
+
+ procedure Put
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive;
+ Value : in Int_16)
+ is
+ Actual : Int_16_Array (1 .. Buffer.My_Channels * Integer (Buffer.My_Frames));
+ for Actual'Address use Buffer.My_Array;
+ pragma Import (Ada, Actual);
+ begin
+ Actual ((Integer (Frame) - 1) * Buffer.My_Channels + Channel) := Value;
+ end Put;
+
+ procedure Put
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive;
+ Value : in Int_8)
+ is
+ Actual : Int_8_Array (1 .. Buffer.My_Channels * Integer (Buffer.My_Frames));
+ for Actual'Address use Buffer.My_Array;
+ pragma Import (Ada, Actual);
+ begin
+ Actual ((Integer (Frame) - 1) * Buffer.My_Channels + Channel) := Value;
+ end Put;
+
+ procedure Put
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive;
+ Value : in UInt_8)
+ is
+ Actual : UInt_8_Array (1 .. Buffer.My_Channels * Integer (Buffer.My_Frames));
+ for Actual'Address use Buffer.My_Array;
+ pragma Import (Ada, Actual);
+ begin
+ Actual ((Integer (Frame) - 1) * Buffer.My_Channels + Channel) := Value;
+ end Put;
+
+
+ function Wrap
+ (Store : access Float_32_Array;
+ Frames : in Frame_Amount;
+ Channels : in Natural)
+ return Sample_Buffer is
+ begin
+ return
+ (My_Sam_Code => pa_float_32,
+ My_Channels => Channels,
+ My_Frames => Frames,
+ My_Array => Store.all'Address);
+ end Wrap;
+
+ function Wrap
+ (Store : access Int_32_Array;
+ Frames : in Frame_Amount;
+ Channels : in Natural)
+ return Sample_Buffer is
+ begin
+ return
+ (My_Sam_Code => pa_int_32,
+ My_Channels => Channels,
+ My_Frames => Frames,
+ My_Array => Store.all'Address);
+ end Wrap;
+
+ function Wrap
+ (Store : access Int_24_Array;
+ Frames : in Frame_Amount;
+ Channels : in Natural)
+ return Sample_Buffer is
+ begin
+ return
+ (My_Sam_Code => pa_int_24,
+ My_Channels => Channels,
+ My_Frames => Frames,
+ My_Array => Store.all'Address);
+ end Wrap;
+
+ function Wrap
+ (Store : access Int_16_Array;
+ Frames : in Frame_Amount;
+ Channels : in Natural)
+ return Sample_Buffer is
+ begin
+ return
+ (My_Sam_Code => pa_int_16,
+ My_Channels => Channels,
+ My_Frames => Frames,
+ My_Array => Store.all'Address);
+ end Wrap;
+
+ function Wrap
+ (Store : access Int_8_Array;
+ Frames : in Frame_Amount;
+ Channels : in Natural)
+ return Sample_Buffer is
+ begin
+ return
+ (My_Sam_Code => pa_int_8,
+ My_Channels => Channels,
+ My_Frames => Frames,
+ My_Array => Store.all'Address);
+ end Wrap;
+
+ function Wrap
+ (Store : access UInt_8_Array;
+ Frames : in Frame_Amount;
+ Channels : in Natural)
+ return Sample_Buffer is
+ begin
+ return
+ (My_Sam_Code => pa_uint_8,
+ My_Channels => Channels,
+ My_Frames => Frames,
+ My_Array => Store.all'Address);
+ end Wrap;
+
+
+ function Create
+ (Device : in Device_Index;
+ Channels : in Natural;
+ Format : in Sample_Format;
+ Latency : in Time)
+ return Stream_Parameters is
+ begin
+ return
+ (My_Device => Interfaces.C.int (Device) - 1,
+ My_Channels => Interfaces.C.int (Channels),
+ My_Samples => To_Cnum (Format),
+ My_Latency => Interfaces.C.double (Latency),
+ My_Specific => System.Null_Address);
+ end Create;
+
+
+ function "+"
+ (A, B : in Stream_Flags)
+ return Stream_Flags is
+ begin
+ return Stream_Flags (Interfaces.C.unsigned_long (A) or Interfaces.C.unsigned_long (B));
+ end "+";
+
+
+ function Input_Latency
+ (Info : in Stream_Info)
+ return Time
+ is
+ Internal : C_Stream_Info;
+ for Internal'Address use Info.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return Time (Internal.My_Input_Latency);
+ end Input_Latency;
+
+ function Output_Latency
+ (Info : in Stream_Info)
+ return Time
+ is
+ Internal : C_Stream_Info;
+ for Internal'Address use Info.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return Time (Internal.My_Output_Latency);
+ end Output_Latency;
+
+ function Sample_Rate
+ (Info : in Stream_Info)
+ return Hertz
+ is
+ Internal : C_Stream_Info;
+ for Internal'Address use Info.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return Hertz (Internal.My_Sample_Rate);
+ end Sample_Rate;
+
+
+ function Input_ADC_Time
+ (Info : in Callback_Time_Info)
+ return Time
+ is
+ Internal : C_Callback_Time_Info;
+ for Internal'Address use Info.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return Time (Internal.My_Input_ADC);
+ end Input_ADC_Time;
+
+ function Current_Time
+ (Info : in Callback_Time_Info)
+ return Time
+ is
+ Internal : C_Callback_Time_Info;
+ for Internal'Address use Info.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return Time (Internal.My_Current);
+ end Current_Time;
+
+ function Output_DAC_Time
+ (Info : in Callback_Time_Info)
+ return Time
+ is
+ Internal : C_Callback_Time_Info;
+ for Internal'Address use Info.Ptr;
+ pragma Import (Ada, Internal);
+ begin
+ return Time (Internal.My_Output_DAC);
+ end Output_DAC_Time;
+
+
+ function Has_Input_Underflow
+ (Flags : in Callback_Flags)
+ return Boolean is
+ begin
+ return (Interfaces.C.unsigned_long (Flags) and pa_input_underflow) /= 0;
+ end Has_Input_Underflow;
+
+ function Has_Input_Overflow
+ (Flags : in Callback_Flags)
+ return Boolean is
+ begin
+ return (Interfaces.C.unsigned_long (Flags) and pa_input_overflow) /= 0;
+ end Has_Input_Overflow;
+
+ function Has_Output_Underflow
+ (Flags : in Callback_Flags)
+ return Boolean is
+ begin
+ return (Interfaces.C.unsigned_long (Flags) and pa_output_underflow) /= 0;
+ end Has_Output_Underflow;
+
+ function Has_Output_Overflow
+ (Flags : in Callback_Flags)
+ return Boolean is
+ begin
+ return (Interfaces.C.unsigned_long (Flags) and pa_output_overflow) /= 0;
+ end Has_Output_Overflow;
+
+ function Has_Priming_Output
+ (Flags : in Callback_Flags)
+ return Boolean is
+ begin
+ return (Interfaces.C.unsigned_long (Flags) and pa_priming_output) /= 0;
+ end Has_Priming_Output;
+
+
+
+
+ ---------------
+ -- Utility --
+ ---------------
+
+ function Is_Open
+ (Stream : in Audio_Stream)
+ return Boolean is
+ begin
+ return Stream.Open;
+ end Is_Open;
+
+
+
+
+ -------------------------------
+ -- Auxiliary API Interface --
+ -------------------------------
+
+ function Get_Version
+ return Version_Number
+ is
+ Raw : Interfaces.Unsigned_32 := Interfaces.Unsigned_32 (pa_get_version);
+ Result : Version_Number;
+ begin
+ Result.Major := Natural (Interfaces.Shift_Right (Raw, 16) and 16#FF#);
+ Result.Minor := Natural (Interfaces.Shift_Right (Raw, 8) and 16#FF#);
+ Result.Subminor := Natural (Raw and 16#FF#);
+ return Result;
+ end Get_Version;
+
+ function Get_Version_Info
+ return Version_Info is
+ begin
+ return (Ptr => pa_get_version_info);
+ end Get_Version_Info;
+
+ function Get_Host_API_Count
+ return Natural
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_get_host_api_count;
+ if Code < 0 then
+ Raise_Error (Code);
+ raise Program_Error;
+ else
+ return Natural (Code);
+ end if;
+ end Get_Host_API_Count;
+
+ function Get_Default_Host_API
+ return Host_API_Index
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_get_default_host_api;
+ if Code < 0 then
+ Raise_Error (Code);
+ raise Program_Error;
+ else
+ return Host_API_Index (Code) + 1;
+ end if;
+ end Get_Default_Host_API;
+
+ function Get_Host_API_Info
+ (Index : in Host_API_Index)
+ return Host_API_Info
+ is
+ Result : System.Address;
+ begin
+ Result := pa_get_host_api_info (Interfaces.C.int (Index) - 1);
+ if Result = System.Null_Address then
+ raise General_Failure;
+ else
+ return (Ptr => Result);
+ end if;
+ end Get_Host_API_Info;
+
+ function To_Host_API_Index
+ (Kind : in Host_API_Kind)
+ return Host_API_Index
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_host_api_type_id_to_host_api_index (To_Cint (Kind));
+ if Code < 0 then
+ Raise_Error (Code);
+ raise Program_Error;
+ else
+ return Host_API_Index (Code) + 1;
+ end if;
+ end To_Host_API_Index;
+
+ function To_Device_Index
+ (Host_API : in Host_API_Index;
+ Host_Device : in Positive)
+ return Device_Index
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_host_api_device_index_to_device_index
+ (Interfaces.C.int (Host_API) - 1,
+ Interfaces.C.int (Host_API) - 1);
+ if Code < 0 then
+ Raise_Error (Code);
+ raise Program_Error;
+ else
+ return Device_Index (Code + 1);
+ end if;
+ end To_Device_Index;
+
+ function Get_Device_Count
+ return Natural
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_get_device_count;
+ if Code < 0 then
+ Raise_Error (Code);
+ raise Program_Error;
+ else
+ return Natural (Code);
+ end if;
+ end Get_Device_Count;
+
+ function Get_Default_Input_Device
+ return Device_Index
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_get_default_input_device;
+ if Code = pa_no_device then
+ return No_Device;
+ else
+ return Device_Index (Code + 1);
+ end if;
+ end Get_Default_Input_Device;
+
+ function Get_Default_Output_Device
+ return Device_Index
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_get_default_output_device;
+ if Code = pa_no_device then
+ return No_Device;
+ else
+ return Device_Index (Code + 1);
+ end if;
+ end Get_Default_Output_Device;
+
+ function Get_Device_Info
+ (Index : in Device_Index)
+ return Device_Info
+ is
+ Result : System.Address;
+ begin
+ Result := pa_get_device_info (Interfaces.C.int (Index) - 1);
+ if Result = System.Null_Address then
+ raise General_Failure;
+ else
+ return (Ptr => Result);
+ end if;
+ end Get_Device_Info;
+
+ function Is_Format_Supported
+ (Input : access Stream_Parameters;
+ Output : access Stream_Parameters;
+ Rate : in Hertz)
+ return Boolean
+ is
+ Code : Interfaces.C.int;
+ package Param_Conversions is new System.Address_To_Access_Conversions (Stream_Parameters);
+ Input_Address : System.Address :=
+ Param_Conversions.To_Address (Param_Conversions.Object_Pointer (Input));
+ Output_Address : System.Address :=
+ Param_Conversions.To_Address (Param_Conversions.Object_Pointer (Output));
+ begin
+ Code := pa_is_format_supported
+ (Input_Address,
+ Output_Address,
+ Interfaces.C.double (Rate));
+ return Code = pa_format_is_supported;
+ end Is_Format_Supported;
+
+ function Get_Sample_Size
+ (Format : in Sample_Format)
+ return Positive
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_get_sample_size (To_Cnum (Format));
+ if Code <= 0 then
+ Raise_Error (Code);
+ raise Program_Error;
+ else
+ return Positive (Code);
+ end if;
+ end Get_Sample_Size;
+
+
+
+
+ ----------------------------
+ -- Stream API Interface --
+ ----------------------------
+
+ procedure Open_Input
+ (Stream : in out Audio_Stream;
+ Input_Params : in Stream_Parameters;
+ Sample_Rate : in Hertz;
+ Buffer_Frames : in Frame_Amount;
+ Flags : in Stream_Flags;
+ Callback : in Callback_Function)
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_open_stream
+ (Stream.Ptr,
+ Input_Params'Address,
+ System.Null_Address,
+ Interfaces.C.double (Sample_Rate),
+ Interfaces.C.unsigned_long (Buffer_Frames),
+ Interfaces.C.unsigned_long (Flags),
+ Stream_Callback_Hook'Address,
+ Stream'Address);
+ if Code /= pa_no_error then
+ Raise_Error (Code);
+ raise Program_Error;
+ else
+ Stream.Open := True;
+ Stream.Func := Callback;
+ Stream.Chin := Input_Params.My_Channels;
+ Stream.Chout := 0;
+ Stream.Sin := Input_Params.My_Samples;
+ Stream.Sout := 0;
+ end if;
+ end Open_Input;
+
+ procedure Open_Output
+ (Stream : in out Audio_Stream;
+ Output_Params : in Stream_Parameters;
+ Sample_Rate : in Hertz;
+ Buffer_Frames : in Frame_Amount;
+ Flags : in Stream_Flags;
+ Callback : in Callback_Function)
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_open_stream
+ (Stream.Ptr,
+ System.Null_Address,
+ Output_Params'Address,
+ Interfaces.C.double (Sample_Rate),
+ Interfaces.C.unsigned_long (Buffer_Frames),
+ Interfaces.C.unsigned_long (Flags),
+ Stream_Callback_Hook'Address,
+ Stream'Address);
+ if Code /= pa_no_error then
+ Raise_Error (Code);
+ raise Program_Error;
+ else
+ Stream.Open := True;
+ Stream.Func := Callback;
+ Stream.Chin := 0;
+ Stream.Chout := Output_Params.My_Channels;
+ Stream.Sin := 0;
+ Stream.Sout := Output_Params.My_Samples;
+ end if;
+ end Open_Output;
+
+ procedure Open_Full
+ (Stream : in out Audio_Stream;
+ Input_Params : in Stream_Parameters;
+ Output_Params : in Stream_Parameters;
+ Sample_Rate : in Hertz;
+ Buffer_Frames : in Frame_Amount;
+ Flags : in Stream_Flags;
+ Callback : in Callback_Function)
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_open_stream
+ (Stream.Ptr,
+ Input_Params'Address,
+ Output_Params'Address,
+ Interfaces.C.double (Sample_Rate),
+ Interfaces.C.unsigned_long (Buffer_Frames),
+ Interfaces.C.unsigned_long (Flags),
+ Stream_Callback_Hook'Address,
+ Stream'Address);
+ if Code /= pa_no_error then
+ Raise_Error (Code);
+ raise Program_Error;
+ else
+ Stream.Open := True;
+ Stream.Func := Callback;
+ Stream.Chin := Input_Params.My_Channels;
+ Stream.Chout := Output_Params.My_Channels;
+ Stream.Sin := Input_Params.My_Samples;
+ Stream.Sout := Output_Params.My_Samples;
+ end if;
+ end Open_Full;
+
+ procedure Open_Input_Blocking
+ (Stream : in out Audio_Stream;
+ Input_Params : in Stream_Parameters;
+ Sample_Rate : in Hertz;
+ Buffer_Frames : in Frame_Amount;
+ Flags : in Stream_Flags)
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_open_stream
+ (Stream.Ptr,
+ Input_Params'Address,
+ System.Null_Address,
+ Interfaces.C.double (Sample_Rate),
+ Interfaces.C.unsigned_long (Buffer_Frames),
+ Interfaces.C.unsigned_long (Flags),
+ System.Null_Address,
+ System.Null_Address);
+ if Code /= pa_no_error then
+ Raise_Error (Code);
+ raise Program_Error;
+ else
+ Stream.Open := True;
+ end if;
+ end Open_Input_Blocking;
+
+ procedure Open_Output_Blocking
+ (Stream : in out Audio_Stream;
+ Output_Params : in Stream_Parameters;
+ Sample_Rate : in Hertz;
+ Buffer_Frames : in Frame_Amount;
+ Flags : in Stream_Flags)
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_open_stream
+ (Stream.Ptr,
+ System.Null_Address,
+ Output_Params'Address,
+ Interfaces.C.double (Sample_Rate),
+ Interfaces.C.unsigned_long (Buffer_Frames),
+ Interfaces.C.unsigned_long (Flags),
+ System.Null_Address,
+ System.Null_Address);
+ if Code /= pa_no_error then
+ Raise_Error (Code);
+ raise Program_Error;
+ else
+ Stream.Open := True;
+ end if;
+ end Open_Output_Blocking;
+
+ procedure Open_Full_Blocking
+ (Stream : in out Audio_Stream;
+ Input_Params : in Stream_Parameters;
+ Output_Params : in Stream_Parameters;
+ Sample_Rate : in Hertz;
+ Buffer_Frames : in Frame_Amount;
+ Flags : in Stream_Flags)
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_open_stream
+ (Stream.Ptr,
+ Input_Params'Address,
+ Output_Params'Address,
+ Interfaces.C.double (Sample_Rate),
+ Interfaces.C.unsigned_long (Buffer_Frames),
+ Interfaces.C.unsigned_long (Flags),
+ System.Null_Address,
+ System.Null_Address);
+ if Code /= pa_no_error then
+ Raise_Error (Code);
+ raise Program_Error;
+ else
+ Stream.Open := True;
+ end if;
+ end Open_Full_Blocking;
+
+ 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)
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_open_default_stream
+ (Stream.Ptr,
+ Interfaces.C.int (Input_Channels),
+ Interfaces.C.int (Output_Channels),
+ To_Cnum (Format),
+ Interfaces.C.double (Sample_Rate),
+ Interfaces.C.unsigned_long (Buffer_Frames),
+ Stream_Callback_Hook'Address,
+ Stream'Address);
+ if Code /= pa_no_error then
+ Raise_Error (Code);
+ raise Program_Error;
+ else
+ Stream.Open := True;
+ Stream.Func := Callback;
+ Stream.Chin := Interfaces.C.int (Input_Channels);
+ Stream.Chout := Interfaces.C.int (Output_Channels);
+ Stream.Sin := To_Cnum (Format);
+ Stream.Sout := To_Cnum (Format);
+ end if;
+ end Open_Default;
+
+ 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)
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_open_default_stream
+ (Stream.Ptr,
+ Interfaces.C.int (Input_Channels),
+ Interfaces.C.int (Output_Channels),
+ To_Cnum (Format),
+ Interfaces.C.double (Sample_Rate),
+ Interfaces.C.unsigned_long (Buffer_Frames),
+ System.Null_Address,
+ System.Null_Address);
+ if Code /= pa_no_error then
+ Raise_Error (Code);
+ raise Program_Error;
+ else
+ Stream.Open := True;
+ end if;
+ end Open_Default_Blocking;
+
+ procedure Close
+ (Stream : in out Audio_Stream)
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_close_stream (Stream.Ptr);
+ if Code /= pa_no_error then
+ Raise_Error (Code);
+ raise Program_Error;
+ else
+ Stream.Open := False;
+ Stream.Chin := 0;
+ Stream.Chout := 0;
+ Stream.Sin := 0;
+ Stream.Sout := 0;
+ end if;
+ end Close;
+
+ procedure Start
+ (Stream : in Audio_Stream)
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_start_stream (Stream.Ptr);
+ if Code /= pa_no_error then
+ Raise_Error (Code);
+ raise Program_Error;
+ end if;
+ end Start;
+
+ procedure Stop
+ (Stream : in Audio_Stream)
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_stop_stream (Stream.Ptr);
+ if Code /= pa_no_error then
+ Raise_Error (Code);
+ raise Program_Error;
+ end if;
+ end Stop;
+
+ procedure Term
+ (Stream : in Audio_Stream)
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_abort_stream (Stream.Ptr);
+ if Code /= pa_no_error then
+ Raise_Error (Code);
+ raise Program_Error;
+ end if;
+ end Term;
+
+ function Is_Stopped
+ (Stream : in Audio_Stream)
+ return Boolean
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_is_stream_stopped (Stream.Ptr);
+ if Code = 1 then
+ return True;
+ elsif Code = 0 then
+ return False;
+ else
+ Raise_Error (Code);
+ raise Program_Error;
+ end if;
+ end Is_Stopped;
+
+ function Is_Active
+ (Stream : in Audio_Stream)
+ return Boolean
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_is_stream_active (Stream.Ptr);
+ if Code = 1 then
+ return True;
+ elsif Code = 0 then
+ return False;
+ else
+ Raise_Error (Code);
+ raise Program_Error;
+ end if;
+ end Is_Active;
+
+ function Get_Info
+ (Stream : in Audio_Stream)
+ return Stream_Info'Class
+ is
+ Result : System.Address;
+ begin
+ Result := pa_get_stream_info (Stream.Ptr);
+ if Result = System.Null_Address then
+ raise General_Failure;
+ else
+ return Info : Stream_Info := (Ptr => Result);
+ end if;
+ end Get_Info;
+
+ function Get_Time
+ (Stream : in Audio_Stream)
+ return Time
+ is
+ Result : Interfaces.C.double;
+ begin
+ Result := pa_get_stream_time (Stream.Ptr);
+ if Result = 0.0 then
+ raise General_Failure;
+ else
+ return Time (Result);
+ end if;
+ end Get_Time;
+
+ function Get_CPU_Load
+ (Stream : in Audio_Stream)
+ return Load is
+ begin
+ return Load (pa_get_stream_cpu_load (Stream.Ptr));
+ end Get_CPU_Load;
+
+ procedure Read_Blocking
+ (Stream : in Audio_Stream;
+ Buffer : in Sample_Buffer'Class;
+ Frames : in Frame_Amount)
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_read_stream
+ (Stream.Ptr,
+ Buffer.My_Array,
+ Interfaces.C.unsigned_long (Frames));
+ if Code /= pa_no_error then
+ Raise_Error (Code);
+ raise Program_Error;
+ end if;
+ end Read_Blocking;
+
+ procedure Write_Blocking
+ (Stream : in Audio_Stream;
+ Buffer : in Sample_Buffer'Class;
+ Frames : in Frame_Amount)
+ is
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_write_stream
+ (Stream.Ptr,
+ Buffer.My_Array,
+ Interfaces.C.unsigned_long (Frames));
+ if Code /= pa_no_error then
+ Raise_Error (Code);
+ raise Program_Error;
+ end if;
+ end Write_Blocking;
+
+ function Get_Read_Available
+ (Stream : in Audio_Stream)
+ return Frame_Amount
+ is
+ Code : Interfaces.C.long;
+ begin
+ Code := pa_get_stream_read_available (Stream.Ptr);
+ if Code < 0 then
+ Raise_Error (Interfaces.C.int (Code));
+ raise Program_Error;
+ else
+ return Frame_Amount (Code);
+ end if;
+ end Get_Read_Available;
+
+ function Get_Write_Available
+ (Stream : in Audio_Stream)
+ return Frame_Amount
+ is
+ Code : Interfaces.C.long;
+ begin
+ Code := pa_get_stream_write_available (Stream.Ptr);
+ if Code < 0 then
+ Raise_Error (Interfaces.C.int (Code));
+ raise Program_Error;
+ else
+ return Frame_Amount (Code);
+ end if;
+ end Get_Write_Available;
+
+
+
+
+begin
+
+ declare
+ Code : Interfaces.C.int;
+ begin
+ Code := pa_initialize (Boolean'Pos (True));
+ if Code /= pa_no_error then
+ Raise_Error (Code);
+ raise Program_Error;
+ end if;
+ end;
+
+end Portaudio;
+
+
diff --git a/src/portaudio.ads b/src/portaudio.ads
new file mode 100644
index 0000000..bc07a44
--- /dev/null
+++ b/src/portaudio.ads
@@ -0,0 +1,933 @@
+
+
+-- Programmed by Jedidiah Barber
+-- Released into the public domain
+
+
+with
+
+ Interfaces;
+
+private with
+
+ Ada.Finalization,
+ Interfaces.C.Strings,
+ System;
+
+
+package Portaudio is
+
+
+ -----------------------
+ -- Data Types and Structures --
+ -----------------------
+
+ type Version_Number is record
+ Major : Natural;
+ Minor : Natural;
+ Subminor : Natural;
+ end record;
+
+ function "<"
+ (A, B : in Version_Number)
+ return Boolean;
+
+ function Image
+ (Num : in Version_Number)
+ return String;
+
+
+ type Version_Info is tagged private;
+
+ function Major
+ (Version : in Version_Info)
+ return Natural;
+
+ function Minor
+ (Version : in Version_Info)
+ return Natural;
+
+ function Subminor
+ (Version : in Version_Info)
+ return Natural;
+
+ function Revision
+ (Version : in Version_Info)
+ return String;
+
+ function Text
+ (Version : in Version_Info)
+ return String;
+
+
+ type Host_API_Kind is
+ (In_Development,
+ Direct_Sound_Host,
+ MME_Host,
+ ASIO_Host,
+ Sound_Manager_Host,
+ Core_Audio_Host,
+ OSS_Host,
+ ALSA_Host,
+ AL_Host,
+ BeOS_Host,
+ WDMKS_Host,
+ JACK_Host,
+ WASAPI_Host,
+ Audio_Science_HPI_Host,
+ Sndio_Host);
+
+ type Host_API_Index is new Positive;
+
+
+ type Device_Index is new Natural;
+
+ No_Device : constant Device_Index;
+
+
+ type Host_API_Info is tagged private;
+
+ function Kind
+ (Info : in Host_API_Info)
+ return Host_API_Kind;
+
+ function Name
+ (Info : in Host_API_Info)
+ return String;
+
+ function Device_Count
+ (Info : in Host_API_Info)
+ return Natural;
+
+ function Default_Input_Device
+ (Info : in Host_API_Info)
+ return Device_Index;
+
+ function Default_Output_Device
+ (Info : in Host_API_Info)
+ return Device_Index;
+
+
+ type Time is delta 10.0**(-4) digits 12;
+
+ function Image
+ (Num : in Time)
+ return String;
+
+
+ subtype Hertz is Long_Float
+ with Static_Predicate => Hertz >= 0.0;
+
+ function Hertz_Image
+ (Num : in Hertz)
+ return String;
+
+
+ subtype Load is Long_Float
+ with Static_Predicate => Load >= 0.0;
+
+ function Load_Image
+ (Num : in Load)
+ return String;
+
+
+ type Device_Info is tagged private;
+
+ function Name
+ (Info : in Device_Info)
+ return String;
+
+ function Host_API
+ (Info : in Device_Info)
+ return Host_API_Index;
+
+ function Max_Input_Channels
+ (Info : in Device_Info)
+ return Natural;
+
+ function Max_Output_Channels
+ (Info : in Device_Info)
+ return Natural;
+
+ function Default_Low_Input_Latency
+ (Info : in Device_Info)
+ return Time;
+
+ function Default_Low_Output_Latency
+ (Info : in Device_Info)
+ return Time;
+
+ function Default_High_Input_Latency
+ (Info : in Device_Info)
+ return Time;
+
+ function Default_High_Output_Latency
+ (Info : in Device_Info)
+ return Time;
+
+ function Default_Sample_Rate
+ (Info : in Device_Info)
+ return Hertz;
+
+
+ type Sample_Format is
+ (Float_32_Sample,
+ Int_32_Sample,
+ Int_24_Sample,
+ Int_16_Sample,
+ Int_8_Sample,
+ UInt_8_Sample);
+
+
+ type Float_32 is new Float;
+ for Float_32'Size use 32;
+ type Float_32_Array is array (Positive range <>) of Float_32;
+
+ type Int_32 is new Interfaces.Integer_32;
+ type Int_32_Array is array (Positive range <>) of Int_32;
+
+ type Int_24 is range -2 ** 23 .. 2 ** 23 - 1;
+ for Int_24'Size use 24;
+ type Int_24_Array is array (Positive range <>) of Int_24;
+
+ type Int_16 is new Interfaces.Integer_16;
+ type Int_16_Array is array (Positive range <>) of Int_16;
+
+ type Int_8 is new Interfaces.Integer_8;
+ type Int_8_Array is array (Positive range <>) of Int_8;
+
+ type UInt_8 is new Interfaces.Unsigned_8;
+ type UInt_8_Array is array (Positive range <>) of UInt_8;
+
+
+ type Frame_Amount is new Interfaces.Unsigned_32;
+
+
+ type Sample_Buffer is tagged private;
+
+ function Kind
+ (Buffer : in Sample_Buffer)
+ return Sample_Format;
+
+ function Channels
+ (Buffer : in Sample_Buffer)
+ return Natural;
+
+ function Frames
+ (Buffer : in Sample_Buffer)
+ return Frame_Amount;
+
+ function Get
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive)
+ return Float_32
+ with Pre => Buffer.Kind = Float_32_Sample;
+
+ function Get
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive)
+ return Int_32
+ with Pre => Buffer.Kind = Int_32_Sample;
+
+ function Get
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive)
+ return Int_24
+ with Pre => Buffer.Kind = Int_24_Sample;
+
+ function Get
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive)
+ return Int_16
+ with Pre => Buffer.Kind = Int_16_Sample;
+
+ function Get
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive)
+ return Int_8
+ with Pre => Buffer.Kind = Int_8_Sample;
+
+ function Get
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive)
+ return UInt_8
+ with Pre => Buffer.Kind = UInt_8_Sample;
+
+ procedure Put
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive;
+ Value : in Float_32)
+ with Pre => Buffer.Kind = Float_32_Sample;
+
+ procedure Put
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive;
+ Value : in Int_32)
+ with Pre => Buffer.Kind = Int_32_Sample;
+
+ procedure Put
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive;
+ Value : in Int_24)
+ with Pre => Buffer.Kind = Int_24_Sample;
+
+ procedure Put
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive;
+ Value : in Int_16)
+ with Pre => Buffer.Kind = Int_16_Sample;
+
+ procedure Put
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive;
+ Value : in Int_8)
+ with Pre => Buffer.Kind = Int_8_Sample;
+
+ procedure Put
+ (Buffer : in Sample_Buffer;
+ Frame : in Frame_Amount;
+ Channel : in Positive;
+ Value : in UInt_8)
+ with Pre => Buffer.Kind = UInt_8_Sample;
+
+
+ function Wrap
+ (Store : access Float_32_Array;
+ Frames : in Frame_Amount;
+ Channels : in Natural)
+ return Sample_Buffer
+ with Pre => Store.all'Length = Frames * Frame_Amount (Channels);
+
+ function Wrap
+ (Store : access Int_32_Array;
+ Frames : in Frame_Amount;
+ Channels : in Natural)
+ return Sample_Buffer
+ with Pre => Store.all'Length = Frames * Frame_Amount (Channels);
+
+ function Wrap
+ (Store : access Int_24_Array;
+ Frames : in Frame_Amount;
+ Channels : in Natural)
+ return Sample_Buffer
+ with Pre => Store.all'Length = Frames * Frame_Amount (Channels);
+
+ function Wrap
+ (Store : access Int_16_Array;
+ Frames : in Frame_Amount;
+ Channels : in Natural)
+ return Sample_Buffer
+ with Pre => Store.all'Length = Frames * Frame_Amount (Channels);
+
+ function Wrap
+ (Store : access Int_8_Array;
+ Frames : in Frame_Amount;
+ Channels : in Natural)
+ return Sample_Buffer
+ with Pre => Store.all'Length = Frames * Frame_Amount (Channels);
+
+ function Wrap
+ (Store : access UInt_8_Array;
+ Frames : in Frame_Amount;
+ Channels : in Natural)
+ return Sample_Buffer
+ with Pre => Store.all'Length = Frames * Frame_Amount (Channels);
+
+
+ type Stream_Parameters is private;
+
+ function Create
+ (Device : in Device_Index;
+ Channels : in Natural;
+ Format : in Sample_Format;
+ Latency : in Time)
+ return Stream_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 tagged private;
+
+ function Input_Latency
+ (Info : in Stream_Info)
+ return Time;
+
+ function Output_Latency
+ (Info : in Stream_Info)
+ return Time;
+
+ function Sample_Rate
+ (Info : in Stream_Info)
+ return Hertz;
+
+
+ type Callback_Result is (Continue, Complete, Finish);
+
+
+ type Callback_Time_Info is tagged private;
+
+ function Input_ADC_Time
+ (Info : in Callback_Time_Info)
+ return Time;
+
+ function Current_Time
+ (Info : in Callback_Time_Info)
+ return Time;
+
+ function Output_DAC_Time
+ (Info : in Callback_Time_Info)
+ return Time;
+
+
+ type Callback_Flags is private;
+
+ function Has_Input_Underflow
+ (Flags : in Callback_Flags)
+ return Boolean;
+
+ function Has_Input_Overflow
+ (Flags : in Callback_Flags)
+ return Boolean;
+
+ function Has_Output_Underflow
+ (Flags : in Callback_Flags)
+ return Boolean;
+
+ function Has_Output_Overflow
+ (Flags : in Callback_Flags)
+ return Boolean;
+
+ function Has_Priming_Output
+ (Flags : in Callback_Flags)
+ return Boolean;
+
+
+ -- Due to how void pointers are wrapped into Sample_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 Sample_Buffer;
+ Output : in Sample_Buffer;
+ Frames : in Frame_Amount;
+ Timing : in Callback_Time_Info;
+ Flags : in Callback_Flags)
+ return Callback_Result;
+
+
+
+
+ ------------------
+ -- Exceptions --
+ ------------------
+
+ Not_Initialized_Error : exception;
+
+ Unanticipated_Host_Error : exception;
+
+ Invalid_Channel_Count_Error : exception;
+
+ Invalid_Sample_Rate_Error : exception;
+
+ Invalid_Device_Error : exception;
+
+ Invalid_Flag_Error : exception;
+
+ Sample_Format_Not_Supported_Error : exception;
+
+ Bad_IO_Device_Combination_Error : exception;
+
+ Buffer_Too_Big_Error : exception;
+
+ Buffer_Too_Small_Error : exception;
+
+ Null_Callback_Error : exception;
+
+ Bad_Stream_Pointer_Error : exception;
+
+ Timed_Out_Error : exception;
+
+ Internal_Error : exception;
+
+ Device_Unavailable_Error : exception;
+
+ Incompatible_Host_API_Specific_Stream_Info_Error : exception;
+
+ Stream_Is_Stopped_Error : exception;
+
+ Stream_Is_Not_Stopped_Error : exception;
+
+ Input_Overflowed_Error : exception;
+
+ Output_Underflowed_Error : exception;
+
+ Host_API_Not_Found_Error : exception;
+
+ Invalid_Host_API_Error : exception;
+
+ Can_Not_Read_From_A_Callback_Stream_Error : exception;
+
+ Can_Not_Write_To_A_Callback_Stream_Error : exception;
+
+ Can_Not_Read_From_An_Output_Only_Stream_Error : exception;
+
+ Can_Not_Write_To_An_Input_Only_Stream_Error : exception;
+
+ Incompatible_Stream_Host_API_Error : exception;
+
+ Bad_Buffer_Pointer_Error : exception;
+
+ Can_Not_Initialize_Recursively_Error : exception;
+
+ General_Failure : exception;
+
+
+
+
+ ---------------
+ -- Utility --
+ ---------------
+
+ function Is_Open
+ (Stream : in Audio_Stream)
+ return Boolean;
+
+
+
+
+ -------------------------------
+ -- Auxiliary API Interface --
+ -------------------------------
+
+ function Get_Version
+ return Version_Number;
+
+ function Get_Version_Info
+ return Version_Info;
+
+ function Get_Host_API_Count
+ return Natural;
+
+ function Get_Default_Host_API
+ return Host_API_Index
+ with Post => Get_Default_Host_API'Result in
+ Host_API_Index (1) .. Host_API_Index (Get_Host_API_Count);
+
+ function Get_Host_API_Info
+ (Index : in Host_API_Index)
+ return Host_API_Info
+ with Pre => Index in Host_API_Index (1) .. Host_API_Index (Get_Host_API_Count);
+
+ function To_Host_API_Index
+ (Kind : in Host_API_Kind)
+ return Host_API_Index
+ with Post => To_Host_API_Index'Result in
+ Host_API_Index (1) .. Host_API_Index (Get_Host_API_Count);
+
+ function To_Device_Index
+ (Host_API : in Host_API_Index;
+ Host_Device : in Positive)
+ return Device_Index
+ with Pre => Host_API in Host_API_Index (1) .. Host_API_Index (Get_Host_API_Count) and
+ Host_Device in 1 .. Get_Host_API_Info (Host_API).Device_Count,
+ Post => To_Device_Index'Result in
+ Device_Index (1) .. Device_Index (Get_Device_Count);
+
+ function Get_Device_Count
+ return Natural;
+
+ function Get_Default_Input_Device
+ return Device_Index;
+
+ function Get_Default_Output_Device
+ return Device_Index;
+
+ function Get_Device_Info
+ (Index : in Device_Index)
+ return Device_Info
+ with Pre => Index in Device_Index (1) .. Device_Index (Get_Device_Count);
+
+ function Is_Format_Supported
+ (Input : access Stream_Parameters;
+ Output : access Stream_Parameters;
+ Rate : in Hertz)
+ return Boolean;
+
+ function Get_Sample_Size
+ (Format : in Sample_Format)
+ return Positive;
+
+
+
+
+ ----------------------------
+ -- Stream API Interface --
+ ----------------------------
+
+ procedure Open_Input
+ (Stream : in out Audio_Stream;
+ Input_Params : in Stream_Parameters;
+ Sample_Rate : in Hertz;
+ Buffer_Frames : in Frame_Amount;
+ Flags : 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 Stream_Parameters;
+ Sample_Rate : in Hertz;
+ Buffer_Frames : in Frame_Amount;
+ Flags : 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 Stream_Parameters;
+ Output_Params : in Stream_Parameters;
+ Sample_Rate : in Hertz;
+ Buffer_Frames : in Frame_Amount;
+ Flags : 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 Stream_Parameters;
+ Sample_Rate : in Hertz;
+ Buffer_Frames : in Frame_Amount;
+ Flags : 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 Stream_Parameters;
+ Sample_Rate : in Hertz;
+ Buffer_Frames : in Frame_Amount;
+ Flags : 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 Stream_Parameters;
+ Output_Params : in Stream_Parameters;
+ Sample_Rate : in Hertz;
+ Buffer_Frames : in Frame_Amount;
+ Flags : 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'Class
+ 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;
+ Buffer : in Sample_Buffer'Class;
+ Frames : in Frame_Amount)
+ with Pre => Stream.Is_Open and then Stream.Is_Active;
+
+ procedure Write_Blocking
+ (Stream : in Audio_Stream;
+ Buffer : in Sample_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;
+
+
+private
+
+
+ pragma Linker_Options ("-lportaudio");
+
+
+
+
+ type C_Version_Info is record
+ My_Major : Interfaces.C.int;
+ My_Minor : Interfaces.C.int;
+ My_Subminor : Interfaces.C.int;
+ My_Revision : Interfaces.C.Strings.chars_ptr;
+ My_Text : Interfaces.C.Strings.chars_ptr;
+ end record with Convention => C;
+
+ type Version_Info is tagged record
+ Ptr : System.Address;
+ end record;
+
+
+ type C_Host_Error_Info is record
+ My_Host_API_Type : Interfaces.C.int;
+ My_Error_Code : Interfaces.C.long;
+ My_Error_Text : Interfaces.C.Strings.chars_ptr;
+ end record with Convention => C;
+
+
+ type C_Host_API_Info is record
+ My_Struct_Version : Interfaces.C.int;
+ My_Host_API_Type : Interfaces.C.int;
+ My_Name : Interfaces.C.Strings.chars_ptr;
+ My_Device_Count : Interfaces.C.int;
+ My_Default_Input : Interfaces.C.int;
+ My_Default_Output : Interfaces.C.int;
+ end record with Convention => C;
+
+ type Host_API_Info is tagged record
+ Ptr : System.Address;
+ end record;
+
+
+ type C_Device_Info is record
+ My_Struct_Version : Interfaces.C.int;
+ My_Name : Interfaces.C.Strings.chars_ptr;
+ My_Host_API_Index : Interfaces.C.int;
+ My_Input_Channels : Interfaces.C.int;
+ My_Output_Channels : Interfaces.C.int;
+ My_Low_Input_Latency : Interfaces.C.double;
+ My_Low_Output_Latency : Interfaces.C.double;
+ My_High_Input_Latency : Interfaces.C.double;
+ My_High_Output_Latency : Interfaces.C.double;
+ My_Sample_Rate : Interfaces.C.double;
+ end record with Convention => C;
+
+ type Device_Info is tagged record
+ Ptr : System.Address;
+ end record;
+
+
+ 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 Sample_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 Stream_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 Stream_Info is tagged record
+ Ptr : System.Address;
+ end record;
+
+
+ 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;
+
+ type Callback_Time_Info is tagged record
+ Ptr : System.Address;
+ end record;
+
+
+ type Callback_Flags is new Interfaces.C.unsigned_long;
+
+
+
+
+ No_Device : constant Device_Index := 0;
+
+
+
+
+ procedure Raise_Error
+ (Num : in Interfaces.C.int);
+
+ function To_Hat_Kind
+ (Num : in Interfaces.C.int)
+ return Host_API_Kind;
+
+ function To_Cint
+ (Ident : in Host_API_Kind)
+ return Interfaces.C.int;
+
+ function To_For_Sam
+ (Num : in Interfaces.C.unsigned_long)
+ return Sample_Format;
+
+ function To_Cnum
+ (Form : in Sample_Format)
+ return Interfaces.C.unsigned_long;
+
+ function To_Cint
+ (Result : in Callback_Result)
+ return Interfaces.C.int;
+
+
+
+
+ -- The clunky way of ensuring that PortAudio is always shut down properly
+
+ type Final_Controller is new Ada.Finalization.Controlled with null record;
+
+ overriding procedure Finalize
+ (This : in out Final_Controller);
+
+ Cleanup : Final_Controller;
+
+
+end Portaudio;
+
+
diff --git a/unlicense.txt b/unlicense.txt
new file mode 100644
index 0000000..68a49da
--- /dev/null
+++ b/unlicense.txt
@@ -0,0 +1,24 @@
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <http://unlicense.org/>