aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/media/UAudioCore_Portaudio.pas56
-rw-r--r--src/media/UAudioInput_Portaudio.pas15
-rw-r--r--src/media/UAudioPlayback_Portaudio.pas22
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;