From 87b89d768d367a475bb553de295ac867909c28c9 Mon Sep 17 00:00:00 2001 From: Jedidiah Barber Date: Thu, 12 Oct 2023 17:39:45 +1300 Subject: Added callbacks for streams finishing --- src/portaudio-streams.adb | 138 +++++++++++++++++++++++++++++----------------- src/portaudio-streams.ads | 78 +++++++++++++++----------- 2 files changed, 132 insertions(+), 84 deletions(-) (limited to 'src') diff --git a/src/portaudio-streams.adb b/src/portaudio-streams.adb index 18a091e..ed837b9 100644 --- a/src/portaudio-streams.adb +++ b/src/portaudio-streams.adb @@ -285,7 +285,7 @@ package body Portaudio.Streams is Result : Callback_Result; begin - Result := Stream_Actual.Func + Result := Stream_Actual.Callfun (Input_Buffer, Output_Buffer, Frame_Amount (Frame_Count), @@ -300,6 +300,16 @@ package body Portaudio.Streams is return To_Cint (Result); end Stream_Callback_Hook; + procedure Stream_Finished_Callback_Hook + (Userdata : in System.Address) + is + Stream_Actual : Audio_Stream; + for Stream_Actual'Address use Userdata; + pragma Import (Ada, Stream_Actual); + begin + Stream_Actual.Finfun.all; + end Stream_Finished_Callback_Hook; + @@ -627,12 +637,12 @@ package body Portaudio.Streams is end Is_Format_Supported; procedure Open_Input - (Stream : in out Audio_Stream; - Input_Params : in Parameters; - Sample_Rate : in Hertz; - Buffer_Frames : in Frame_Amount; - Bunting : in Stream_Flags; - Callback : in Callback_Function) + (Stream : in out Audio_Stream; + Input_Params : in Parameters; + Sample_Rate : in Hertz; + Buffer_Frames : in Frame_Amount; + Bunting : in Stream_Flags; + Callback : in not null Callback_Function) is Code : Interfaces.C.int; begin @@ -649,22 +659,20 @@ package body Portaudio.Streams is Raise_Error (Code); raise Program_Error; else - Stream.Open := True; - Stream.Func := Callback; - Stream.Chin := Input_Params.My_Channels; - Stream.Chout := 0; - Stream.Sin := Input_Params.My_Samples; - Stream.Sout := 0; + Stream.Open := True; + Stream.Callfun := Callback; + Stream.Chin := Input_Params.My_Channels; + Stream.Sin := Input_Params.My_Samples; end if; end Open_Input; procedure Open_Output - (Stream : in out Audio_Stream; - Output_Params : in Parameters; - Sample_Rate : in Hertz; - Buffer_Frames : in Frame_Amount; - Bunting : in Stream_Flags; - Callback : in Callback_Function) + (Stream : in out Audio_Stream; + Output_Params : in Parameters; + Sample_Rate : in Hertz; + Buffer_Frames : in Frame_Amount; + Bunting : in Stream_Flags; + Callback : in not null Callback_Function) is Code : Interfaces.C.int; begin @@ -681,23 +689,21 @@ package body Portaudio.Streams is Raise_Error (Code); raise Program_Error; else - Stream.Open := True; - Stream.Func := Callback; - Stream.Chin := 0; - Stream.Chout := Output_Params.My_Channels; - Stream.Sin := 0; - Stream.Sout := Output_Params.My_Samples; + Stream.Open := True; + Stream.Callfun := Callback; + Stream.Chout := Output_Params.My_Channels; + Stream.Sout := Output_Params.My_Samples; end if; end Open_Output; procedure Open_Full - (Stream : in out Audio_Stream; - Input_Params : in Parameters; - Output_Params : in Parameters; - Sample_Rate : in Hertz; - Buffer_Frames : in Frame_Amount; - Bunting : in Stream_Flags; - Callback : in Callback_Function) + (Stream : in out Audio_Stream; + Input_Params : in Parameters; + Output_Params : in Parameters; + Sample_Rate : in Hertz; + Buffer_Frames : in Frame_Amount; + Bunting : in Stream_Flags; + Callback : in not null Callback_Function) is Code : Interfaces.C.int; begin @@ -714,12 +720,12 @@ package body Portaudio.Streams is Raise_Error (Code); raise Program_Error; else - Stream.Open := True; - Stream.Func := Callback; - Stream.Chin := Input_Params.My_Channels; - Stream.Chout := Output_Params.My_Channels; - Stream.Sin := Input_Params.My_Samples; - Stream.Sout := Output_Params.My_Samples; + Stream.Open := True; + Stream.Callfun := Callback; + Stream.Chin := Input_Params.My_Channels; + Stream.Chout := Output_Params.My_Channels; + Stream.Sin := Input_Params.My_Samples; + Stream.Sout := Output_Params.My_Samples; end if; end Open_Full; @@ -803,13 +809,13 @@ package body Portaudio.Streams is end Open_Full_Blocking; procedure Open_Default - (Stream : in out Audio_Stream; - Input_Channels : in Natural; - Output_Channels : in Natural; - Format : in Sample_Format; - Sample_Rate : in Hertz; - Buffer_Frames : in Frame_Amount; - Callback : in Callback_Function) + (Stream : in out Audio_Stream; + Input_Channels : in Natural; + Output_Channels : in Natural; + Format : in Sample_Format; + Sample_Rate : in Hertz; + Buffer_Frames : in Frame_Amount; + Callback : in not null Callback_Function) is Code : Interfaces.C.int; begin @@ -826,12 +832,12 @@ package body Portaudio.Streams is Raise_Error (Code); raise Program_Error; else - Stream.Open := True; - Stream.Func := Callback; - Stream.Chin := Interfaces.C.int (Input_Channels); - Stream.Chout := Interfaces.C.int (Output_Channels); - Stream.Sin := To_Cnum (Format); - Stream.Sout := To_Cnum (Format); + Stream.Open := True; + Stream.Callfun := Callback; + Stream.Chin := Interfaces.C.int (Input_Channels); + Stream.Chout := Interfaces.C.int (Output_Channels); + Stream.Sin := To_Cnum (Format); + Stream.Sout := To_Cnum (Format); end if; end Open_Default; @@ -880,6 +886,36 @@ package body Portaudio.Streams is end if; end Close; + procedure Set_Finished_Callback + (Stream : in out Audio_Stream; + Callback : in not null Stream_Finished_Function) + is + Code : Interfaces.C.int; + begin + Stream.Finfun := Callback; + Code := pa_set_stream_finished_callback + (Stream.Ptr, + Stream_Finished_Callback_Hook'Address); + if Code /= pa_no_error then + Raise_Error (Code); + raise Program_Error; + end if; + end Set_Finished_Callback; + + procedure Clear_Finished_Callback + (Stream : in out Audio_Stream) + is + Code : Interfaces.C.int; + begin + Code := pa_set_stream_finished_callback + (Stream.Ptr, + System.Null_Address); + if Code /= pa_no_error then + Raise_Error (Code); + raise Program_Error; + end if; + end Clear_Finished_Callback; + procedure Start (Stream : in Audio_Stream) is diff --git a/src/portaudio-streams.ads b/src/portaudio-streams.ads index c8d3e92..0f3d2ba 100644 --- a/src/portaudio-streams.ads +++ b/src/portaudio-streams.ads @@ -272,6 +272,8 @@ package Portaudio.Streams is Bunting : in Callback_Flags) return Callback_Result; + type Stream_Finished_Function is access procedure; + @@ -297,33 +299,33 @@ package Portaudio.Streams is return Boolean; procedure Open_Input - (Stream : in out Audio_Stream; - Input_Params : in Parameters; - Sample_Rate : in Hertz; - Buffer_Frames : in Frame_Amount; - Bunting : in Stream_Flags; - Callback : in Callback_Function) + (Stream : in out Audio_Stream; + Input_Params : in Parameters; + Sample_Rate : in Hertz; + Buffer_Frames : in Frame_Amount; + Bunting : in Stream_Flags; + Callback : in not null Callback_Function) with Pre => not Stream.Is_Open, Post => Stream.Is_Open; procedure Open_Output - (Stream : in out Audio_Stream; - Output_Params : in Parameters; - Sample_Rate : in Hertz; - Buffer_Frames : in Frame_Amount; - Bunting : in Stream_Flags; - Callback : in Callback_Function) + (Stream : in out Audio_Stream; + Output_Params : in Parameters; + Sample_Rate : in Hertz; + Buffer_Frames : in Frame_Amount; + Bunting : in Stream_Flags; + Callback : in not null Callback_Function) with Pre => not Stream.Is_Open, Post => Stream.Is_Open; procedure Open_Full - (Stream : in out Audio_Stream; - Input_Params : in Parameters; - Output_Params : in Parameters; - Sample_Rate : in Hertz; - Buffer_Frames : in Frame_Amount; - Bunting : in Stream_Flags; - Callback : in Callback_Function) + (Stream : in out Audio_Stream; + Input_Params : in Parameters; + Output_Params : in Parameters; + Sample_Rate : in Hertz; + Buffer_Frames : in Frame_Amount; + Bunting : in Stream_Flags; + Callback : in not null Callback_Function) with Pre => not Stream.Is_Open, Post => Stream.Is_Open; @@ -356,13 +358,13 @@ package Portaudio.Streams is Post => Stream.Is_Open; procedure Open_Default - (Stream : in out Audio_Stream; - Input_Channels : in Natural; - Output_Channels : in Natural; - Format : in Sample_Format; - Sample_Rate : in Hertz; - Buffer_Frames : in Frame_Amount; - Callback : in Callback_Function) + (Stream : in out Audio_Stream; + Input_Channels : in Natural; + Output_Channels : in Natural; + Format : in Sample_Format; + Sample_Rate : in Hertz; + Buffer_Frames : in Frame_Amount; + Callback : in not null Callback_Function) with Pre => not Stream.Is_Open and (Input_Channels > 0 or Output_Channels > 0), Post => Stream.Is_Open; @@ -383,6 +385,15 @@ package Portaudio.Streams is with Pre => Stream.Is_Open, Post => not Stream.Is_Open; + procedure Set_Finished_Callback + (Stream : in out Audio_Stream; + Callback : in not null Stream_Finished_Function) + with Pre => Stream.Is_Open and then Stream.Is_Stopped; + + procedure Clear_Finished_Callback + (Stream : in out Audio_Stream) + with Pre => Stream.Is_Open and then Stream.Is_Stopped; + procedure Start (Stream : in Audio_Stream) with Pre => Stream.Is_Open; @@ -495,13 +506,14 @@ private type Audio_Stream is tagged limited record - Ptr : System.Address; - Open : Boolean := False; - Func : Callback_Function; - Chin : Interfaces.C.int := 0; - Chout : Interfaces.C.int := 0; - Sin : Interfaces.C.unsigned_long := 0; - Sout : Interfaces.C.unsigned_long := 0; + Ptr : System.Address; + Open : Boolean := False; + Callfun : Callback_Function; + Finfun : Stream_Finished_Function; + Chin : Interfaces.C.int := 0; + Chout : Interfaces.C.int := 0; + Sin : Interfaces.C.unsigned_long := 0; + Sout : Interfaces.C.unsigned_long := 0; end record; -- cgit