From 734544d457cb098c1d434798528670e0bf156cdb Mon Sep 17 00:00:00 2001 From: Jedidiah Barber Date: Thu, 20 Jul 2023 18:53:27 +1200 Subject: Completed command API --- src/libsndfile-commands.ads | 363 ++++++++++++++++++++++++++++++++------------ 1 file changed, 266 insertions(+), 97 deletions(-) (limited to 'src/libsndfile-commands.ads') diff --git a/src/libsndfile-commands.ads b/src/libsndfile-commands.ads index 8540fdc..45e5098 100644 --- a/src/libsndfile-commands.ads +++ b/src/libsndfile-commands.ads @@ -23,7 +23,7 @@ package Libsndfile.Commands is type Long_Float_Array is array (Positive range <>) of Long_Float; - type Format_Info is private; + type Format_Info is tagged private; function Major (Info : in Format_Info) @@ -46,16 +46,10 @@ package Libsndfile.Commands is return String; - type Embedded_Info is private; - - function Offset - (Info : in Embedded_Info) - return Count_Type; - - function Length - (Info : in Embedded_Info) - return Count_Type; - + type Embedded_Info is record + Offset : Count_Type; + Length : Count_Type; + end record; type Ambisonic is (Ambisonic_Unsupported, @@ -64,81 +58,20 @@ package Libsndfile.Commands is subtype Compression is Long_Float range 0.0 .. 1.0; - - type Broadcast_Info is private; - - function Create - (Description : in String; - Originator : in String; - Originator_Reference : in String; - Origination_Date : in String; - Origination_Time : in String; - Time_Reference_Low : in Interfaces.Unsigned_32; - Time_Reference_High : in Interfaces.Unsigned_32; - Version : in Short_Integer; - Umid : in String; - Reserved : in String; - Coding_History_Size : in Interfaces.Unsigned_32; - Coding_History : in String) - return Broadcast_Info - with Pre => - Description'Length <= 256 and - Originator'Length <= 32 and - Originator_Reference'Length <= 32 and - Origination_Date'Length <= 10 and - Origination_Time'Length <= 8 and - Umid'Length <= 64 and - Reserved'Length <= 190 and - Coding_History'Length <= 256; - - function Description - (Info : in Broadcast_Info) - return String; - - function Originator - (Info : in Broadcast_Info) - return String; - - function Originator_Reference - (Info : in Broadcast_Info) - return String; - - function Origination_Date - (Info : in Broadcast_Info) - return String; - - function Origination_Time - (Info : in Broadcast_Info) - return String; - - function Time_Reference_Low - (Info : in Broadcast_Info) - return Interfaces.Unsigned_32; - - function Time_Reference_High - (Info : in Broadcast_Info) - return Interfaces.Unsigned_32; - - function Version - (Info : in Broadcast_Info) - return Short_Integer; - - function Umid - (Info : in Broadcast_Info) - return String; - - function Reserved - (Info : in Broadcast_Info) - return String; - - function Coding_History_Size - (Info : in Broadcast_Info) - return Interfaces.Unsigned_32; - - function Coding_History - (Info : in Broadcast_Info) - return String; - + type Broadcast_Info is record + Description : String (1 .. 256); + Originator : String (1 .. 32); + Originator_Reference : String (1 .. 32); + Origination_Date : String (1 .. 10); + Origination_Time : String (1 .. 8); + Time_Reference_Low : Interfaces.Unsigned_32; + Time_Reference_High : Interfaces.Unsigned_32; + Version : Short_Integer; + Umid : String (1 .. 64); + Reserved : String (1 .. 190); + Coding_History_Size : Interfaces.Unsigned_32; + Coding_History : String (1 .. 256); + end record; type Channel_Map is (Map_Invalid, @@ -172,6 +105,117 @@ package Libsndfile.Commands is type Channel_Map_Array is array (Positive range <>) of Channel_Map; + + type Cart_Timer is record + Usage : String (1 .. 4); + Value : Interfaces.Integer_32; + end record; + + type Cart_Timer_Array is array (Positive range <>) of Cart_Timer; + + -- Is 1024 enough? Who knows! I hate this API + Max_Cart_Tag_Size : constant Natural := 1024; + + type Cart_Info (Tag_Size : Natural) is record + Version : String (1 .. 4); + Title : String (1 .. 64); + Artist : String (1 .. 64); + Cut_ID : String (1 .. 64); + Client_ID : String (1 .. 64); + Category : String (1 .. 64); + Classification : String (1 .. 64); + Out_Cue : String (1 .. 64); + Start_Date : String (1 .. 10); + Start_Time : String (1 .. 8); + End_Date : String (1 .. 10); + End_Time : String (1 .. 8); + Producer_App_ID : String (1 .. 64); + Producer_App_Version : String (1 .. 64); + User_Defined : String (1 .. 64); + Level_Reference : Long_Integer; + Post_Timers : Cart_Timer_Array (1 .. 8); + Reserved : String (1 .. 276); + URL : String (1 .. 1024); + Tag_Text : String (1 .. Tag_Size); + end record; + + + type Loop_Mode is + (No_Loop, + Loop_Forward, + Loop_Backward, + Loop_Alternating); + + type Beats_Per_Minute is delta 10.0**(-2) digits 5 range 0.0 .. 655.0; + + subtype MIDI_Note is Integer range -1 .. 127; + No_Note : constant MIDI_Note := -1; + + type Integer_Array is array (Positive range <>) of Integer; + + type Loop_Info is record + Time_Sig_Num : Short_Integer; + Time_Sig_Den : Short_Integer; + Mode : Loop_Mode; + Beats : Positive; + BPM : Beats_Per_Minute; + Root_Key : MIDI_Note; + Future : Integer_Array (1 .. 6); + end record; + + + -- Many of these fields should likely be something more specific + -- However it is hard to tell exactly what would be best + type Instrument_Data is record + Gain : Integer; + Basenote : Character; + Detune : Character; + Velocity_Low : Character; + Velocity_High : Character; + Key_Low : Character; + Key_High : Character; + end record; + + type Loop_Data is record + Mode : Loop_Mode; + Start : Interfaces.Unsigned_32; + Finish : Interfaces.Unsigned_32; + Count : Interfaces.Unsigned_32; + end record; + + type Loop_Data_Array is array (Positive range <>) of Loop_Data; + + type Instrument_Info is tagged private; + + function Create + (Base : in Instrument_Data; + Repeats : in Loop_Data_Array) + return Instrument_Info + with Pre => Repeats'Length <= 16; + + function Base + (Info : in Instrument_Info) + return Instrument_Data; + + function Repeats + (Info : in Instrument_Info) + return Loop_Data_Array + with Post => Repeats'Result'Length <= 16; + + + type Cue_Marker is record + Index : Integer; + Position : Interfaces.Unsigned_32; + FCC_Chunk : Integer; + Chunk_Start : Integer; + Block_Start : Integer; + Sample_Offset : Interfaces.Unsigned_32; + Name : String (1 .. 256); + end record; + + type Cue_Marker_Array is array (Positive range <>) of Cue_Marker; + + type Bitrate_Mode is (Constant_Mode, Average_Mode, @@ -184,7 +228,6 @@ package Libsndfile.Commands is -- Exceptions -- ------------------ - -- May be raised by Get_Signal_Maximum, Get_Maximum_All_Channels Command_Error : exception; @@ -359,23 +402,41 @@ package Libsndfile.Commands is (File : in Sound_File; Value : in Channel_Map_Array); - -- Get_Cart_Info goes here + function Get_Cart_Info + (File : in Sound_File) + return Cart_Info + with Post => Get_Cart_Info'Result.Tag_Size <= Max_Cart_Tag_Size; - -- Set_Cart_Info goes here + procedure Set_Cart_Info + (File : in Sound_File; + Info : in Cart_Info) + with Pre => Info.Tag_Size <= Max_Cart_Tag_Size; - -- Get_Loop_Info goes here + function Get_Loop_Info + (File : in Sound_File) + return Loop_Info; - -- Get_Instrument goes here + function Get_Instrument + (File : in Sound_File) + return Instrument_Info; - -- Set_Instrument goes here + procedure Set_Instrument + (File : in Sound_File; + Info : in Instrument_Info); function Get_Cue_Count (File : in Sound_File) return Interfaces.Unsigned_32; - -- Get_Cue goes here + function Get_Cue + (File : in Sound_File) + return Cue_Marker_Array + with Post => Get_Cue'Result'Length <= 100; - -- Set_Cue goes here + procedure Set_Cue + (File : in Sound_File; + Info : in Cue_Marker_Array) + with Pre => Info'Length <= 100; -- Why the hell would you design this command in this way? -- You shouldn't have to intentionally try to set the thing after writing @@ -405,23 +466,27 @@ private -- This corresponds to the C-side SF_FORMAT_INFO - type Format_Info is record + type C_Format_Info is record My_Format : Interfaces.C.int; My_Name : Interfaces.C.Strings.chars_ptr; My_Extension : Interfaces.C.Strings.chars_ptr; end record with Convention => C; + type Format_Info is tagged record + C_Data : C_Format_Info; + end record; + -- This cannot correspond to the C-side SF_EMBED_FILE_INFO struct since -- sf_count_t can vary - type Embedded_Info is record + type C_Embedded_Info is record My_Offset : Interfaces.Integer_64; My_Length : Interfaces.Integer_64; end record with Convention => C; -- This corresponds to the C-side SF_BROADCAST_INFO - type Broadcast_Info is record + type C_Broadcast_Info is record My_Description : Interfaces.C.char_array (1 .. 256); My_Originator : Interfaces.C.char_array (1 .. 32); My_Originator_Reference : Interfaces.C.char_array (1 .. 32); @@ -437,6 +502,110 @@ private end record with Convention => C; + -- This corresponds to the C-side SF_CART_TIMER + type C_Cart_Timer is record + My_Usage : Interfaces.C.char_array (1 .. 4); + My_Value : Interfaces.Integer_32; + end record with Convention => C; + + type C_Cart_Timer_Array is array (Positive range <>) of C_Cart_Timer; + + -- This corresponds to the C-side SF_CART_INFO + type C_Cart_Info is record + My_Version : Interfaces.C.char_array (1 .. 4); + My_Title : Interfaces.C.char_array (1 .. 64); + My_Artist : Interfaces.C.char_array (1 .. 64); + My_Cut_ID : Interfaces.C.char_array (1 .. 64); + My_Client_ID : Interfaces.C.char_array (1 .. 64); + My_Category : Interfaces.C.char_array (1 .. 64); + My_Classification : Interfaces.C.char_array (1 .. 64); + My_Out_Cue : Interfaces.C.char_array (1 .. 64); + My_Start_Date : Interfaces.C.char_array (1 .. 10); + My_Start_Time : Interfaces.C.char_array (1 .. 8); + My_End_Date : Interfaces.C.char_array (1 .. 10); + My_End_Time : Interfaces.C.char_array (1 .. 8); + My_Producer_App_ID : Interfaces.C.char_array (1 .. 64); + My_Producer_App_Version : Interfaces.C.char_array (1 .. 64); + My_User_Def : Interfaces.C.char_array (1 .. 64); + My_Level_Reference : Interfaces.C.long; + My_Post_Timers : C_Cart_Timer_Array (1 .. 8); + My_Reserved : Interfaces.C.char_array (1 .. 276); + My_URL : Interfaces.C.char_array (1 .. 1024); + My_Tag_Text_Size : Interfaces.C.unsigned; + My_Tag_Text : Interfaces.C.char_array + (1 .. Interfaces.C.size_t (Max_Cart_Tag_Size)); + end record with Convention => C; + + + type C_Int_Array is array (Positive range <>) of Interfaces.C.int; + + -- This corresponds to the C-side SF_LOOP_INFO struct + type C_Loop_Info is record + My_Time_Sig_Num : Interfaces.C.short; + My_Time_Sig_Den : Interfaces.C.short; + My_Loop_Mode : Interfaces.C.int; + My_Num_Beats : Interfaces.C.int; + My_BPM : Interfaces.C.C_float; + My_Root_Key : Interfaces.C.int; + My_Future : C_Int_Array (1 .. 6); + end record with Convention => C; + + + type C_Loop_Data is record + My_Mode : Interfaces.C.int; + My_Start : Interfaces.C.unsigned; + My_End : Interfaces.C.unsigned; + My_Count : Interfaces.C.unsigned; + end record with Convention => C; + + type C_Loop_Data_Array is array (Positive range <>) of C_Loop_Data; + + -- This corresponds to the C-side SF_INSTRUMENT struct + type C_Instrument_Info is record + My_Gain : Interfaces.C.int; + My_Basenote : Interfaces.C.char; + My_Detune : Interfaces.C.char; + My_Velocity_Lo : Interfaces.C.char; + My_Velocity_Hi : Interfaces.C.char; + My_Key_Lo : Interfaces.C.char; + My_Key_Hi : Interfaces.C.char; + My_Loop_Count : Interfaces.C.int; + My_Loops : C_Loop_Data_Array (1 .. 16); + end record with Convention => C; + + type Instrument_Info is tagged record + C_Data : C_Instrument_Info; + end record; + + + type C_Cue is record + My_Indx : Interfaces.Integer_32; + My_Position : Interfaces.Unsigned_32; + My_FCC_Chunk : Interfaces.Integer_32; + My_Chunk_Start : Interfaces.Integer_32; + My_Block_Start : Interfaces.Integer_32; + My_Sample_Offset : Interfaces.Unsigned_32; + My_Name : Interfaces.C.char_array (1 .. 256); + end record with Convention => C; + + type C_Cue_Array is array (Positive range <>) of C_Cue; + + -- This corresponds to the C-side SF_CUES struct + type C_Cue_Info is record + My_Cue_Count : Interfaces.C.int; + My_Cue_Points : C_Cue_Array (1 .. 100); + end record with Convention => C; + + + function To_Ada + (Num : in Interfaces.C.int) + return Loop_Mode; + + function To_C + (Enum : in Loop_Mode) + return Interfaces.C.int; + + end Libsndfile.Commands; -- cgit