summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJedidiah Barber <contact@jedbarber.id.au>2023-07-17 21:03:46 +1200
committerJedidiah Barber <contact@jedbarber.id.au>2023-07-17 21:03:46 +1200
commit8463ca926a038bab28772c56bf5b32b0a7403853 (patch)
tree7f1edea7571bb5e5b67b5f2b15e9a3140148a676
parent17ed86acaee20590b3ef4d1eea10f2fd27bd3350 (diff)
Sine wave blocking example added, fixed Buffer wrapping bug
-rw-r--r--example.gpr3
-rw-r--r--example/sine_block.adb99
-rw-r--r--src/portaudio-streams.adb48
-rw-r--r--src/portaudio-streams.ads54
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;