summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJedidiah Barber <contact@jedbarber.id.au>2023-07-18 01:47:26 +1200
committerJedidiah Barber <contact@jedbarber.id.au>2023-07-18 01:47:26 +1200
commitbaac81253b3cc2e3addbbe6e90ec2a7abb5d56fd (patch)
tree88cb63624bcae8f944d670640094873a55610823
parentc36d37880986f734a69086b28ac6f0e9df7babab (diff)
Code cleanup, slight API improvement
-rw-r--r--example/aao_example.adb6
-rw-r--r--src/c_aao.c75
-rw-r--r--src/c_aao.h33
-rw-r--r--src/libao.adb262
-rw-r--r--src/libao.ads46
5 files changed, 174 insertions, 248 deletions
diff --git a/example/aao_example.adb b/example/aao_example.adb
index fd32e38..6851f54 100644
--- a/example/aao_example.adb
+++ b/example/aao_example.adb
@@ -46,7 +46,7 @@ begin
-- Open driver
begin
- My_Device := Libao.Open_Live
+ My_Device.Open_Live
(Driver_ID => Default_Driver,
Format => My_Format,
Options => Libao.Empty_Options);
@@ -80,7 +80,7 @@ begin
Buffer (4 * I + 4) := Character'Val ((Sample / 256) and 16#FF#);
end loop;
- Libao.Play (My_Device, Buffer);
+ My_Device.Play (Buffer);
end;
@@ -89,7 +89,7 @@ begin
-- Technically the binding will take care of closing open devices at the
-- end of runtime, but it is always good practice to close them anyway.
- Libao.Close (My_Device);
+ My_Device.Close;
end AAO_Example;
diff --git a/src/c_aao.c b/src/c_aao.c
index 731792d..7c6fe8d 100644
--- a/src/c_aao.c
+++ b/src/c_aao.c
@@ -9,65 +9,22 @@
-int type_live() {
- return AO_TYPE_LIVE;
-}
-
-int type_file() {
- return AO_TYPE_FILE;
-}
-
-
-
-int sample_little_endian() {
- return AO_FMT_LITTLE;
-}
-
-int sample_big_endian() {
- return AO_FMT_BIG;
-}
-
-int sample_native_endian() {
- return AO_FMT_NATIVE;
-}
-
-
-
-int error_no_driver() {
- return AO_ENODRIVER;
-}
-
-int error_not_file() {
- return AO_ENOTFILE;
-}
-
-int error_not_live() {
- return AO_ENOTLIVE;
-}
-
-int error_bad_option() {
- return AO_EBADOPTION;
-}
-
-int error_open_device() {
- return AO_EOPENDEVICE;
-}
-
-int error_open_file() {
- return AO_EOPENFILE;
-}
-
-int error_file_exists() {
- return AO_EFILEEXISTS;
-}
-
-int error_bad_format() {
- return AO_EBADFORMAT;
-}
-
-int error_fail() {
- return AO_EFAIL;
-}
+const int type_live = AO_TYPE_LIVE;
+const int type_file = AO_TYPE_FILE;
+
+const int sample_little_endian = AO_FMT_LITTLE;
+const int sample_big_endian = AO_FMT_BIG;
+const int sample_native_endian = AO_FMT_NATIVE;
+
+const int error_no_driver = AO_ENODRIVER;
+const int error_not_file = AO_ENOTFILE;
+const int error_not_live = AO_ENOTLIVE;
+const int error_bad_option = AO_EBADOPTION;
+const int error_open_device = AO_EOPENDEVICE;
+const int error_open_file = AO_EOPENFILE;
+const int error_file_exists = AO_EFILEEXISTS;
+const int error_bad_format = AO_EBADFORMAT;
+const int error_fail = AO_EFAIL;
diff --git a/src/c_aao.h b/src/c_aao.h
index d0a23a4..81f61ff 100644
--- a/src/c_aao.h
+++ b/src/c_aao.h
@@ -10,22 +10,23 @@
#include <ao/ao.h>
-int type_live();
-int type_file();
-
-int sample_little_endian();
-int sample_big_endian();
-int sample_native_endian();
-
-int error_no_driver();
-int error_not_file();
-int error_not_live();
-int error_bad_option();
-int error_open_device();
-int error_open_file();
-int error_file_exists();
-int error_bad_format();
-int error_fail();
+extern const int type_live;
+extern const int type_file;
+
+extern const int sample_little_endian;
+extern const int sample_big_endian;
+extern const int sample_native_endian;
+
+extern const int error_no_driver;
+extern const int error_not_file;
+extern const int error_not_live;
+extern const int error_bad_option;
+extern const int error_open_device;
+extern const int error_open_file;
+extern const int error_file_exists;
+extern const int error_bad_format;
+extern const int error_fail;
+
ao_info * info_item_get(ao_info ** items, int n);
diff --git a/src/libao.adb b/src/libao.adb
index e10582d..1f37875 100644
--- a/src/libao.adb
+++ b/src/libao.adb
@@ -20,16 +20,65 @@ package body Libao is
------------------------
+ -- Constants From C --
+ ------------------------
+
+ type_live : constant Interfaces.C.int;
+ pragma Import (C, type_live, "type_live");
+
+ type_file : constant Interfaces.C.int;
+ pragma Import (C, type_file, "type_file");
+
+
+ sample_little_endian : constant Interfaces.C.int;
+ pragma Import (C, sample_little_endian, "sample_little_endian");
+
+ sample_big_endian : constant Interfaces.C.int;
+ pragma Import (C, sample_big_endian, "sample_big_endian");
+
+ sample_native_endian : constant Interfaces.C.int;
+ pragma Import (C, sample_native_endian, "sample_native_endian");
+
+
+ error_no_driver : constant Interfaces.C.int;
+ pragma Import (C, error_no_driver, "error_no_driver");
+
+ error_not_file : constant Interfaces.C.int;
+ pragma Import (C, error_not_file, "error_not_file");
+
+ error_not_live : constant Interfaces.C.int;
+ pragma Import (C, error_not_live, "error_not_live");
+
+ error_bad_option : constant Interfaces.C.int;
+ pragma Import (C, error_bad_option, "error_bad_option");
+
+ error_open_device : constant Interfaces.C.int;
+ pragma Import (C, error_open_device, "error_open_device");
+
+ error_open_file : constant Interfaces.C.int;
+ pragma Import (C, error_open_file, "error_open_file");
+
+ error_file_exists : constant Interfaces.C.int;
+ pragma Import (C, error_file_exists, "error_file_exists");
+
+ error_bad_format : constant Interfaces.C.int;
+ pragma Import (C, error_bad_format, "error_bad_format");
+
+ error_fail : constant Interfaces.C.int;
+ pragma Import (C, error_fail, "error_fail");
+
+
+
+
+ ------------------------
-- Functions From C --
------------------------
procedure ao_initialize;
pragma Import (C, ao_initialize, "ao_initialize");
- pragma Inline (ao_initialize);
procedure ao_shutdown;
pragma Import (C, ao_shutdown, "ao_shutdown");
- pragma Inline (ao_shutdown);
function ao_append_option
@@ -38,19 +87,16 @@ package body Libao is
Value : in Interfaces.C.char_array)
return Interfaces.C.int;
pragma Import (C, ao_append_option, "ao_append_option");
- pragma Inline (ao_append_option);
function ao_append_global_option
(Key : in Interfaces.C.char_array;
Value : in Interfaces.C.char_array)
return Interfaces.C.int;
pragma Import (C, ao_append_global_option, "ao_append_global_option");
- pragma Inline (ao_append_global_option);
procedure ao_free_options
(Options : in System.Address);
pragma Import (C, ao_free_options, "ao_free_options");
- pragma Inline (ao_free_options);
function ao_open_live
(Driver_ID : in Interfaces.C.int;
@@ -58,7 +104,6 @@ package body Libao is
Options : in System.Address)
return System.Address;
pragma Import (C, ao_open_live, "ao_open_live");
- pragma Inline (ao_open_live);
function ao_open_file
(Driver_ID : in Interfaces.C.int;
@@ -68,7 +113,6 @@ package body Libao is
Options : in System.Address)
return System.Address;
pragma Import (C, ao_open_file, "ao_open_file");
- pragma Inline (ao_open_file);
function ao_play
(Output_Device : in System.Address;
@@ -76,130 +120,41 @@ package body Libao is
Num_Bytes : in Interfaces.Unsigned_32)
return Interfaces.C.int;
pragma Import (C, ao_play, "ao_play");
- pragma Inline (ao_play);
function ao_close
(Output_Device : in System.Address)
return Interfaces.C.int;
pragma Import (C, ao_close, "ao_close");
- pragma Inline (ao_close);
function ao_driver_id
(Short_Name : in Interfaces.C.char_array)
return Interfaces.C.int;
pragma Import (C, ao_driver_id, "ao_driver_id");
- pragma Inline (ao_driver_id);
function ao_default_driver_id
return Interfaces.C.int;
pragma Import (C, ao_default_driver_id, "ao_default_driver_id");
- pragma Inline (ao_default_driver_id);
function ao_driver_info
(Ident : in Interfaces.C.int)
return System.Address;
pragma Import (C, ao_driver_info, "ao_driver_info");
- pragma Inline (ao_driver_info);
function ao_driver_info_list
(Count : out Interfaces.C.int)
return System.Address;
pragma Import (C, ao_driver_info_list, "ao_driver_info_list");
- pragma Inline (ao_driver_info_list);
function ao_file_extension
(Ident : in Interfaces.C.int)
return Interfaces.C.Strings.chars_ptr;
pragma Import (C, ao_file_extension, "ao_file_extension");
- pragma Inline (ao_file_extension);
function ao_is_big_endian
return Interfaces.C.int;
pragma Import (C, ao_is_big_endian, "ao_is_big_endian");
- pragma Inline (ao_is_big_endian);
-
-
-
-
- function type_live
- return Interfaces.C.int;
- pragma Import (C, type_live, "type_live");
- pragma Inline (type_live);
-
- function type_file
- return Interfaces.C.int;
- pragma Import (C, type_file, "type_file");
- pragma Inline (type_file);
-
-
-
-
- function sample_little_endian
- return Interfaces.C.int;
- pragma Import (C, sample_little_endian, "sample_little_endian");
- pragma Inline (sample_little_endian);
-
- function sample_big_endian
- return Interfaces.C.int;
- pragma Import (C, sample_big_endian, "sample_big_endian");
- pragma Inline (sample_big_endian);
-
- function sample_native_endian
- return Interfaces.C.int;
- pragma Import (C, sample_native_endian, "sample_native_endian");
- pragma Inline (sample_native_endian);
-
-
-
-
- function error_no_driver
- return Interfaces.C.int;
- pragma Import (C, error_no_driver, "error_no_driver");
- pragma Inline (error_no_driver);
-
- function error_not_file
- return Interfaces.C.int;
- pragma Import (C, error_not_file, "error_not_file");
- pragma Inline (error_not_file);
-
- function error_not_live
- return Interfaces.C.int;
- pragma Import (C, error_not_live, "error_not_live");
- pragma Inline (error_not_live);
-
- function error_bad_option
- return Interfaces.C.int;
- pragma Import (C, error_bad_option, "error_bad_option");
- pragma Inline (error_bad_option);
-
- function error_open_device
- return Interfaces.C.int;
- pragma Import (C, error_open_device, "error_open_device");
- pragma Inline (error_open_device);
-
- function error_open_file
- return Interfaces.C.int;
- pragma Import (C, error_open_file, "error_open_file");
- pragma Inline (error_open_file);
-
- function error_file_exists
- return Interfaces.C.int;
- pragma Import (C, error_file_exists, "error_file_exists");
- pragma Inline (error_file_exists);
-
- function error_bad_format
- return Interfaces.C.int;
- pragma Import (C, error_bad_format, "error_bad_format");
- pragma Inline (error_bad_format);
-
- function error_fail
- return Interfaces.C.int;
- pragma Import (C, error_fail, "error_fail");
- pragma Inline (error_fail);
-
-
function info_item_get
@@ -210,8 +165,6 @@ package body Libao is
pragma Inline (info_item_get);
-
-
function info_kind_get
(Item : in System.Address)
return Interfaces.C.int;
@@ -262,16 +215,12 @@ package body Libao is
pragma Inline (info_option_key_get);
-
-
function get_errno
return Interfaces.C.int;
pragma Import (C, get_errno, "get_errno");
pragma Inline (get_errno);
-
-
function option_key
(Item : in System.Address)
return Interfaces.C.Strings.chars_ptr;
@@ -293,6 +242,40 @@ package body Libao is
+ ------------------------
+ -- Internal Utility --
+ ------------------------
+
+ procedure Do_Append
+ (Ptr : in out System.Address;
+ Key : in Interfaces.C.char_array;
+ Value : in Interfaces.C.char_array)
+ is
+ Result : Interfaces.C.int;
+ begin
+ Result := ao_append_option (Ptr, Key, Value);
+ if Result = 0 then
+ raise Storage_Error;
+ elsif Result /= 1 then
+ raise Program_Error;
+ end if;
+ end Do_Append;
+
+ procedure Do_Close
+ (Ptr : in System.Address)
+ is
+ Result : Interfaces.C.int := ao_close (Ptr);
+ begin
+ if Result = 0 then
+ raise Close_Device_Error;
+ elsif Result /= 1 then
+ raise Program_Error;
+ end if;
+ end Do_Close;
+
+
+
+
-----------------------------------
-- Controlled Type Subprograms --
-----------------------------------
@@ -494,21 +477,6 @@ package body Libao is
-- Device Setup/Playback/Teardown --
--------------------------------------
- procedure Do_Append
- (Ptr : in out System.Address;
- Key : in Interfaces.C.char_array;
- Value : in Interfaces.C.char_array)
- is
- Result : Interfaces.C.int;
- begin
- Result := ao_append_option (Ptr, Key, Value);
- if Result = 0 then
- raise Storage_Error;
- elsif Result /= 1 then
- raise Program_Error;
- end if;
- end Do_Append;
-
procedure Append
(This : in out Option_List;
Key : in String;
@@ -533,11 +501,11 @@ package body Libao is
end if;
end Append_Global_Option;
- function Open_Live
- (Driver_ID : in Driver_ID_Number;
- Format : in Sample_Format;
- Options : in Option_List'Class)
- return Device
+ procedure Open_Live
+ (Output : in out Device;
+ Driver_ID : in Driver_ID_Number;
+ Format : in Sample_Format'Class;
+ Options : in Option_List'Class)
is
Result : System.Address := ao_open_live
(Driver_ID => Interfaces.C.int (Driver_ID),
@@ -563,18 +531,19 @@ package body Libao is
raise Program_Error;
end if;
else
+ Output.Close;
Device_List.Append (Result);
- return (Ptr => Result);
+ Output.Ptr := Result;
end if;
end Open_Live;
- function Open_File
- (Driver_ID : in Driver_ID_Number;
- Filename : in String;
- Format : in Sample_Format;
- Options : in Option_List'Class;
- Overwrite : in Boolean := False)
- return Device
+ procedure Open_File
+ (Output : in out Device;
+ Driver_ID : in Driver_ID_Number;
+ Filename : in String;
+ Format : in Sample_Format'Class;
+ Options : in Option_List'Class;
+ Overwrite : in Boolean := False)
is
Result : System.Address := ao_open_file
(Driver_ID => Interfaces.C.int (Driver_ID),
@@ -604,17 +573,18 @@ package body Libao is
raise Program_Error;
end if;
else
+ Output.Close;
Device_List.Append (Result);
- return (Ptr => Result);
+ Output.Ptr := Result;
end if;
end Open_File;
procedure Play
- (Output_Device : in Device;
- Samples : in Data_Buffer)
+ (Output : in Device;
+ Samples : in Data_Buffer)
is
Result : Interfaces.C.int := ao_play
- (Output_Device => Output_Device.Ptr,
+ (Output_Device => Output.Ptr,
Samples => Interfaces.C.To_C (Item => String (Samples), Append_Nul => False),
Num_Bytes => Interfaces.Unsigned_32 (Samples'Length));
begin
@@ -623,27 +593,21 @@ package body Libao is
end if;
end Play;
- procedure Do_Close
- (Ptr : in System.Address)
- is
- Result : Interfaces.C.int := ao_close (Ptr);
- begin
- if Result = 0 then
- raise Close_Device_Error;
- elsif Result /= 1 then
- raise Program_Error;
- end if;
- end Do_Close;
-
procedure Close
- (Output_Device : in out Device) is
+ (Output : in out Device)
+ is
+ Found : Boolean := False;
begin
for Index in reverse Integer range Device_List.First_Index .. Device_List.Last_Index loop
- if Device_List.Element (Index) = Output_Device.Ptr then
+ if Device_List.Element (Index) = Output.Ptr then
Device_List.Delete (Index);
+ Found := True;
end if;
end loop;
- Do_Close (Output_Device.Ptr);
+ if Found then
+ Do_Close (Output.Ptr);
+ end if;
+ Output.Ptr := System.Null_Address;
end Close;
diff --git a/src/libao.ads b/src/libao.ads
index 9e1cde1..33ec49c 100644
--- a/src/libao.ads
+++ b/src/libao.ads
@@ -4,6 +4,10 @@
-- Released into the public domain
+with
+
+ Interfaces;
+
private with
Ada.Finalization,
@@ -25,7 +29,7 @@ package Libao is
type Data_Buffer is new String;
- type Device is private;
+ type Device is tagged private;
type Info is tagged private;
@@ -72,7 +76,7 @@ package Libao is
Empty_Options : constant Option_List;
- type Sample_Format is private;
+ type Sample_Format is tagged private;
type Channel_Mnemonic is (L, R, C, M, CL, CR, BL, BR, BC, SL, SR, LFE, A1, A2, A3, A4, X);
type Mnemonic_Array is array (Positive range <>) of Channel_Mnemonic;
@@ -144,26 +148,26 @@ package Libao is
(Key : in String;
Value : in String);
- function Open_Live
- (Driver_ID : in Driver_ID_Number;
- Format : in Sample_Format;
- Options : in Option_List'Class)
- return Device;
+ procedure Open_Live
+ (Output : in out Device;
+ Driver_ID : in Driver_ID_Number;
+ Format : in Sample_Format'Class;
+ Options : in Option_List'Class);
- function Open_File
- (Driver_ID : in Driver_ID_Number;
- Filename : in String;
- Format : in Sample_Format;
- Options : in Option_List'Class;
- Overwrite : in Boolean := False)
- return Device;
+ procedure Open_File
+ (Output : in out Device;
+ Driver_ID : in Driver_ID_Number;
+ Filename : in String;
+ Format : in Sample_Format'Class;
+ Options : in Option_List'Class;
+ Overwrite : in Boolean := False);
procedure Play
- (Output_Device : in Device;
- Samples : in Data_Buffer);
+ (Output : in Device;
+ Samples : in Data_Buffer);
procedure Close
- (Output_Device : in out Device);
+ (Output : in out Device);
@@ -216,13 +220,13 @@ private
(Ptr : in System.Address);
- type Device is record
- Ptr : System.Address;
+ type Device is tagged record
+ Ptr : System.Address := System.Null_Address;
end record;
type Info is tagged record
- Ptr : System.Address;
+ Ptr : System.Address := System.Null_Address;
end record;
@@ -259,7 +263,7 @@ private
(This : in out Sample_Format);
- -- Keep track of
+ -- Keep track of open devices
package Address_Vectors is new Ada.Containers.Vectors
(Index_Type => Positive,
Element_Type => System.Address,