-- Programmed by Jedidiah Barber -- Released into the public domain -- This program opens the file supplied as a command line argument. Except -- rather than the usual libsndfile open procedure, it uses the standard Ada -- library and libsndfile's virtual open. Then the program outputs the file -- info and closes the file. No modifications are made. with Ada.Command_Line, Ada.Directories, Ada.Direct_IO, Ada.Text_IO, Libsndfile.Virtual; use type Libsndfile.Count_Type; procedure Virtual_IO_Example is package ACom renames Ada.Command_Line; package ADir renames Ada.Directories; package DIO is new Ada.Direct_IO (Element_Type => Character); package TIO renames Ada.Text_IO; Virtual_File : DIO.File_Type; Current_Offset : Libsndfile.Count_Type := 1; function My_Length return Libsndfile.Count_Type is begin return Libsndfile.Count_Type (DIO.Size (Virtual_File)); end My_Length; function My_Seek (Offset : in Libsndfile.Count_Type; Whence : in Libsndfile.Seek_From) return Libsndfile.Count_Type is begin case Whence is when Libsndfile.From_Start => Current_Offset := 1 + Offset; when Libsndfile.From_Current => Current_Offset := Current_Offset + Offset; when Libsndfile.From_End => Current_Offset := Libsndfile.Count_Type (DIO.Size (Virtual_File)) + Offset; end case; if Current_Offset < 1 or Current_Offset > Libsndfile.Count_Type (DIO.Size (Virtual_File)) then Current_Offset := 1; return -1; else return Current_Offset; end if; end My_Seek; function My_Read (Data : out Libsndfile.Raw_Data; Bytes : in Libsndfile.Count_Type) return Libsndfile.Count_Type is Item : Character; Data_Position : Integer := 1; begin while Current_Offset <= Libsndfile.Count_Type (DIO.Size (Virtual_File)) and Data_Position - 1 < Integer (Bytes) loop DIO.Read (Virtual_File, Item, DIO.Count (Current_Offset)); Data (Data_Position) := Item; Current_Offset := Current_Offset + 1; Data_Position := Data_Position + 1; end loop; return Libsndfile.Count_Type (Data_Position - 1); end My_Read; function My_Write (Data : in Libsndfile.Raw_Data; Bytes : in Libsndfile.Count_Type) return Libsndfile.Count_Type is Item : Character; Data_Position : Integer := 1; begin while Current_Offset <= Libsndfile.Count_Type (DIO.Size (Virtual_File)) and Data_Position - 1 < Integer (Bytes) loop Item := Data (Data_Position); DIO.Write (Virtual_File, Item, DIO.Count (Current_Offset)); Current_Offset := Current_Offset + 1; Data_Position := Data_Position + 1; end loop; return Libsndfile.Count_Type (Data_Position - 1); end My_Write; function My_Tell return Libsndfile.Count_Type is begin return Current_Offset; end My_Tell; My_Info : Libsndfile.File_Info := Libsndfile.Blank_Info; Test_File : Libsndfile.Virtual.Virtual_Sound_File; begin if ACom.Argument_Count < 1 then TIO.Put_Line ("No filename provided"); ACom.Set_Exit_Status (ACom.Failure); return; end if; if not ADir.Exists (ACom.Argument (1)) then TIO.Put_Line ("File does not exist"); ACom.Set_Exit_Status (ACom.Failure); return; end if; TIO.Put_Line ("Load file " & ACom.Argument (1)); DIO.Open (Virtual_File, DIO.In_File, ACom.Argument (1)); Test_File.Open (Libsndfile.Read_Only, My_Info, My_Length'Unrestricted_Access, My_Seek'Unrestricted_Access, My_Read'Unrestricted_Access, My_Write'Unrestricted_Access, My_Tell'Unrestricted_Access); TIO.New_Line; TIO.Put_Line ("Open frame count:" & Libsndfile.Count_Type'Image (Libsndfile.Frames (My_Info))); TIO.Put_Line ("Open sample rate:" & Natural'Image (Libsndfile.Rate (My_Info))); TIO.Put_Line ("Open channel count:" & Natural'Image (Libsndfile.Channels (My_Info))); TIO.Put_Line ("Open major format: " & Libsndfile.Major_Format'Image (Libsndfile.Major (My_Info))); TIO.Put_Line ("Open minor format: " & Libsndfile.Minor_Format'Image (Libsndfile.Minor (My_Info))); TIO.Put_Line ("Open endianness: " & Libsndfile.Endianness'Image (Libsndfile.Endian (My_Info))); TIO.Put_Line ("Open section count:" & Natural'Image (Libsndfile.Sections (My_Info))); TIO.Put_Line ("Open seekable: " & Boolean'Image (Libsndfile.Seekable (My_Info))); TIO.New_Line; Test_File.Close; DIO.Close (Virtual_File); TIO.Put_Line ("File closed"); end Virtual_IO_Example;