From c61600bfdda6608feb6a390d20e2e1200afe93f6 Mon Sep 17 00:00:00 2001 From: tobigun Date: Fri, 30 Apr 2010 13:49:10 +0000 Subject: portaudio playback (not used by default) segfault fixed git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@2321 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/media/UAudioCore_Portaudio.pas | 56 ++++++++++++++++++++++++++++++++++ src/media/UAudioInput_Portaudio.pas | 15 +++------ src/media/UAudioPlayback_Portaudio.pas | 22 ++++++------- 3 files changed, 71 insertions(+), 22 deletions(-) diff --git a/src/media/UAudioCore_Portaudio.pas b/src/media/UAudioCore_Portaudio.pas index 1c7e3ef5..c97b5d10 100644 --- a/src/media/UAudioCore_Portaudio.pas +++ b/src/media/UAudioCore_Portaudio.pas @@ -40,9 +40,13 @@ uses type TAudioCore_Portaudio = class + private + InitCount: integer; ///< keeps track of the number of Initialize/Terminate calls public constructor Create(); class function GetInstance(): TAudioCore_Portaudio; + function Initialize(): boolean; + function Terminate(): boolean; function GetPreferredApiIndex(): TPaHostApiIndex; function TestDevice(inParams, outParams: PPaStreamParameters; var sampleRate: double): boolean; end; @@ -92,6 +96,7 @@ var constructor TAudioCore_Portaudio.Create(); begin inherited; + InitCount := 0; end; class function TAudioCore_Portaudio.GetInstance(): TAudioCore_Portaudio; @@ -101,6 +106,57 @@ begin Result := Instance; end; +function TAudioCore_Portaudio.Initialize(): boolean; +var + Err: TPaError; +begin + // initialize only once + if (InitCount > 0) then + begin + Inc(InitCount); + Result := true; + Exit; + end; + + // init Portaudio + Err := Pa_Initialize(); + if (Err <> paNoError) then + begin + Log.LogError(Pa_GetErrorText(Err), 'TAudioCore_Portaudio.Initialize'); + Result := false; + Exit; + end; + + // only increment on success + Inc(InitCount); + Result := true; +end; + +function TAudioCore_Portaudio.Terminate(): boolean; +var + Err: TPaError; +begin + // decrement usage count + Dec(InitCount); + if (InitCount > 0) then + begin + // do not terminate yet + Result := true; + Exit; + end; + + // terminate if usage count is 0 + Err := Pa_Terminate(); + if (Err <> paNoError) then + begin + Log.LogError(Pa_GetErrorText(Err), 'TAudioCore_Portaudio.Terminate'); + Result := false; + Exit; + end; + + Result := true; +end; + function TAudioCore_Portaudio.GetPreferredApiIndex(): TPaHostApiIndex; var i: integer; diff --git a/src/media/UAudioInput_Portaudio.pas b/src/media/UAudioInput_Portaudio.pas index 92e549ff..c7364eb4 100644 --- a/src/media/UAudioInput_Portaudio.pas +++ b/src/media/UAudioInput_Portaudio.pas @@ -492,27 +492,20 @@ begin end; function TAudioInput_Portaudio.InitializeRecord(): boolean; -var - err: TPaError; begin + Result := false; AudioCore := TAudioCore_Portaudio.GetInstance(); // initialize portaudio - err := Pa_Initialize(); - if (err <> paNoError) then - begin - Log.LogError(Pa_GetErrorText(err), 'TAudioInput_Portaudio.InitializeRecord'); - Result := false; - Exit; - end; - + if (not AudioCore.Initialize()) then + Exit; Result := EnumDevices(); end; function TAudioInput_Portaudio.FinalizeRecord: boolean; begin CaptureStop; - Pa_Terminate(); + AudioCore.Terminate(); Result := inherited FinalizeRecord(); end; diff --git a/src/media/UAudioPlayback_Portaudio.pas b/src/media/UAudioPlayback_Portaudio.pas index ddbd03d6..6fbae6e3 100644 --- a/src/media/UAudioPlayback_Portaudio.pas +++ b/src/media/UAudioPlayback_Portaudio.pas @@ -307,22 +307,16 @@ var paApiIndex : TPaHostApiIndex; paApiInfo : PPaHostApiInfo; paOutDevice : TPaDeviceIndex; - err: TPaError; begin Result := false; - AudioCore := TAudioCore_Portaudio.GetInstance(); // initialize portaudio - err := Pa_Initialize(); - if(err <> paNoError) then - begin - Log.LogError(Pa_GetErrorText(err), 'TAudioInput_Portaudio.InitializeRecord'); + if (not AudioCore.Initialize()) then Exit; - end; paApiIndex := AudioCore.GetPreferredApiIndex(); - if(paApiIndex = -1) then + if (paApiIndex = -1) then begin Log.LogError('No working Audio-API found', 'TAudioPlayback_Portaudio.InitializeAudioPlaybackEngine'); Exit; @@ -364,13 +358,19 @@ end; procedure TAudioPlayback_Portaudio.StopAudioPlaybackEngine(); begin if (paStream <> nil) then - Pa_StopStream(paStream); + begin + Pa_CloseStream(paStream); + // wait until stream is closed, otherwise Terminate() might cause a segfault + while (Pa_IsStreamActive(paStream) = 1) do + ; + paStream := nil; + end; end; function TAudioPlayback_Portaudio.FinalizeAudioPlaybackEngine(): boolean; begin - Pa_Terminate(); - Result := true; + StopAudioPlaybackEngine(); + Result := AudioCore.Terminate(); end; function TAudioPlayback_Portaudio.GetLatency(): double; -- cgit v1.2.3