diff options
author | Jedidiah Barber <contact@jedbarber.id.au> | 2023-07-17 21:03:46 +1200 |
---|---|---|
committer | Jedidiah Barber <contact@jedbarber.id.au> | 2023-07-17 21:03:46 +1200 |
commit | 8463ca926a038bab28772c56bf5b32b0a7403853 (patch) | |
tree | 7f1edea7571bb5e5b67b5f2b15e9a3140148a676 | |
parent | 17ed86acaee20590b3ef4d1eea10f2fd27bd3350 (diff) |
Sine wave blocking example added, fixed Buffer wrapping bug
-rw-r--r-- | example.gpr | 3 | ||||
-rw-r--r-- | example/sine_block.adb | 99 | ||||
-rw-r--r-- | src/portaudio-streams.adb | 48 | ||||
-rw-r--r-- | src/portaudio-streams.ads | 54 |
4 files changed, 155 insertions, 49 deletions
diff --git a/example.gpr b/example.gpr index 59431f1..3d48940 100644 --- a/example.gpr +++ b/example.gpr @@ -12,12 +12,13 @@ project Example is for Source_Dirs use ("example"); for Object_Dir use "obj"; for Exec_Dir use "bin"; - for Main use ("device_list.adb", "saw_back.adb"); + for Main use ("device_list.adb", "saw_back.adb", "sine_block.adb"); package Builder is for Executable ("device_list.adb") use "device_list"; for Executable ("saw_back.adb") use "saw_back"; + for Executable ("sine_block.adb") use "sine_block"; end Builder; diff --git a/example/sine_block.adb b/example/sine_block.adb new file mode 100644 index 0000000..52c46fe --- /dev/null +++ b/example/sine_block.adb @@ -0,0 +1,99 @@ + + +-- Programmed by Jedidiah Barber +-- Released into the public domain + + +with + + Ada.Numerics.Long_Elementary_Functions, + Ada.Text_IO, + Portaudio.Streams; + + +procedure Sine_Block is + + + package Num renames Ada.Numerics; + package Elem renames Ada.Numerics.Long_Elementary_Functions; + package TIO renames Ada.Text_IO; + package Paud renames Portaudio; + package Pstm renames Portaudio.Streams; + + + Play_Time : constant Paud.Time := 5.0; + Sample_Rate : constant Paud.Hertz := 44100.0; + Channels : constant Natural := 2; + Per_Buffer : constant Pstm.Frame_Amount := 1024; + + Sample_Array : Pstm.Float_32_Array (1 .. Natural (Per_Buffer) * Channels) := (others => 0.0); + Sample_Buffer : Pstm.Buffer := Pstm.Wrap (Sample_Array, Per_Buffer, Channels); + + type Table_Index is mod 200; + Sine_Table : array (Table_Index) of Pstm.Float_32; + + Left_Phase, Right_Phase : Table_Index := 0; + Left_Increment : Table_Index := 1; + Right_Increment : Table_Index := 3; + + Buffer_Count : Natural; + + Sine_Stream : Pstm.Audio_Stream; + + +begin + + + TIO.Put_Line ("PortAudio Test: output sine wave. " & + "Sample Rate = " & Paud.Hertz_Image (Sample_Rate) & ", " & + "Buffer Size =" & Pstm.Frame_Amount'Image (Per_Buffer)); + + for Index in Table_Index loop + Sine_Table (Index) := Pstm.Float_32 + (Elem.Sin (Long_Float (Index) / Long_Float (Table_Index'Last_Valid) * Num.Pi * 2.0)); + end loop; + + Sine_Stream.Open_Default_Blocking + (Input_Channels => 0, + Output_Channels => Channels, + Format => Pstm.Float_32_Format, + Sample_Rate => Sample_Rate, + Buffer_Frames => Per_Buffer); + + TIO.Put_Line ("Play 3 times, higher each time."); + + for Round in Integer range 1 .. 3 loop + TIO.Put_Line ("Play for " & Paud.Image (Play_Time) & " seconds."); + + Sine_Stream.Start; + + Buffer_Count := Integer (Play_Time) * Integer (Sample_Rate) / Integer (Per_Buffer); + for Fill in Integer range 1 .. Buffer_Count loop + + for Index in Pstm.Frame_Amount range 1 .. Per_Buffer loop + Sample_Buffer.Put (Index, 1, Sine_Table (Left_Phase)); + Sample_Buffer.Put (Index, 2, Sine_Table (Right_Phase)); + Left_Phase := Left_Phase + Left_Increment; + Right_Phase := Right_Phase + Right_Increment; + end loop; + + Sine_Stream.Write_Blocking (Sample_Buffer, Per_Buffer); + + end loop; + + Sine_Stream.Stop; + + Left_Increment := Left_Increment + 1; + Right_Increment := Right_Increment + 1; + + delay 1.0; + end loop; + + Sine_Stream.Close; + + TIO.Put_Line ("Test finished."); + + +end Sine_Block; + + diff --git a/src/portaudio-streams.adb b/src/portaudio-streams.adb index 0df71ee..cbcbe7d 100644 --- a/src/portaudio-streams.adb +++ b/src/portaudio-streams.adb @@ -485,81 +485,81 @@ package body Portaudio.Streams is end Put; function Wrap - (Store : access Float_32_Array; - Frames : in Frame_Amount; - Channels : in Natural) + (Store : in Float_32_Array; + Frames : in Frame_Amount; + Channels : in Natural) return Buffer is begin return (My_Sam_Code => pa_float_32, My_Channels => Channels, My_Frames => Frames, - My_Array => Store.all'Address); + My_Array => Store'Address); end Wrap; function Wrap - (Store : access Int_32_Array; - Frames : in Frame_Amount; - Channels : in Natural) + (Store : in Int_32_Array; + Frames : in Frame_Amount; + Channels : in Natural) return Buffer is begin return (My_Sam_Code => pa_int_32, My_Channels => Channels, My_Frames => Frames, - My_Array => Store.all'Address); + My_Array => Store'Address); end Wrap; function Wrap - (Store : access Int_24_Array; - Frames : in Frame_Amount; - Channels : in Natural) + (Store : in Int_24_Array; + Frames : in Frame_Amount; + Channels : in Natural) return Buffer is begin return (My_Sam_Code => pa_int_24, My_Channels => Channels, My_Frames => Frames, - My_Array => Store.all'Address); + My_Array => Store'Address); end Wrap; function Wrap - (Store : access Int_16_Array; - Frames : in Frame_Amount; - Channels : in Natural) + (Store : in Int_16_Array; + Frames : in Frame_Amount; + Channels : in Natural) return Buffer is begin return (My_Sam_Code => pa_int_16, My_Channels => Channels, My_Frames => Frames, - My_Array => Store.all'Address); + My_Array => Store'Address); end Wrap; function Wrap - (Store : access Int_8_Array; - Frames : in Frame_Amount; - Channels : in Natural) + (Store : in Int_8_Array; + Frames : in Frame_Amount; + Channels : in Natural) return Buffer is begin return (My_Sam_Code => pa_int_8, My_Channels => Channels, My_Frames => Frames, - My_Array => Store.all'Address); + My_Array => Store'Address); end Wrap; function Wrap - (Store : access UInt_8_Array; - Frames : in Frame_Amount; - Channels : in Natural) + (Store : in UInt_8_Array; + Frames : in Frame_Amount; + Channels : in Natural) return Buffer is begin return (My_Sam_Code => pa_uint_8, My_Channels => Channels, My_Frames => Frames, - My_Array => Store.all'Address); + My_Array => Store'Address); end Wrap; function Create diff --git a/src/portaudio-streams.ads b/src/portaudio-streams.ads index bdd6247..8acf758 100644 --- a/src/portaudio-streams.ads +++ b/src/portaudio-streams.ads @@ -57,6 +57,12 @@ package Portaudio.Streams is type Frame_Amount is new Interfaces.Unsigned_32; + -- Acts as a wrapper around the arrays given above. + -- This both avoids the use of void pointers, and also + -- allows for easier reference to arrays by frame/channel. + -- Since it is only a pointer wrapper, please ensure that + -- every Buffer lives at least as long as any array used + -- to make it. type Buffer is tagged private; function Kind @@ -156,46 +162,46 @@ package Portaudio.Streams is with Pre => Store.Kind = UInt_8_Format; function Wrap - (Store : access Float_32_Array; - Frames : in Frame_Amount; - Channels : in Natural) + (Store : in Float_32_Array; + Frames : in Frame_Amount; + Channels : in Natural) return Buffer - with Pre => Store.all'Length = Frames * Frame_Amount (Channels); + with Pre => Store'Length = Frames * Frame_Amount (Channels); function Wrap - (Store : access Int_32_Array; - Frames : in Frame_Amount; - Channels : in Natural) + (Store : in Int_32_Array; + Frames : in Frame_Amount; + Channels : in Natural) return Buffer - with Pre => Store.all'Length = Frames * Frame_Amount (Channels); + with Pre => Store'Length = Frames * Frame_Amount (Channels); function Wrap - (Store : access Int_24_Array; - Frames : in Frame_Amount; - Channels : in Natural) + (Store : in Int_24_Array; + Frames : in Frame_Amount; + Channels : in Natural) return Buffer - with Pre => Store.all'Length = Frames * Frame_Amount (Channels); + with Pre => Store'Length = Frames * Frame_Amount (Channels); function Wrap - (Store : access Int_16_Array; - Frames : in Frame_Amount; - Channels : in Natural) + (Store : in Int_16_Array; + Frames : in Frame_Amount; + Channels : in Natural) return Buffer - with Pre => Store.all'Length = Frames * Frame_Amount (Channels); + with Pre => Store'Length = Frames * Frame_Amount (Channels); function Wrap - (Store : access Int_8_Array; - Frames : in Frame_Amount; - Channels : in Natural) + (Store : in Int_8_Array; + Frames : in Frame_Amount; + Channels : in Natural) return Buffer - with Pre => Store.all'Length = Frames * Frame_Amount (Channels); + with Pre => Store'Length = Frames * Frame_Amount (Channels); function Wrap - (Store : access UInt_8_Array; - Frames : in Frame_Amount; - Channels : in Natural) + (Store : in UInt_8_Array; + Frames : in Frame_Amount; + Channels : in Natural) return Buffer - with Pre => Store.all'Length = Frames * Frame_Amount (Channels); + with Pre => Store'Length = Frames * Frame_Amount (Channels); type Parameters is private; |