aboutsummaryrefslogtreecommitdiffstats
path: root/cmake/src/media/UAudioCore_Portaudio.pas
diff options
context:
space:
mode:
Diffstat (limited to 'cmake/src/media/UAudioCore_Portaudio.pas')
-rw-r--r--cmake/src/media/UAudioCore_Portaudio.pas88
1 files changed, 72 insertions, 16 deletions
diff --git a/cmake/src/media/UAudioCore_Portaudio.pas b/cmake/src/media/UAudioCore_Portaudio.pas
index 25ceae3c..c97b5d10 100644
--- a/cmake/src/media/UAudioCore_Portaudio.pas
+++ b/cmake/src/media/UAudioCore_Portaudio.pas
@@ -40,11 +40,15 @@ 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;
+ function TestDevice(inParams, outParams: PPaStreamParameters; var sampleRate: double): boolean;
end;
implementation
@@ -92,6 +96,7 @@ var
constructor TAudioCore_Portaudio.Create();
begin
inherited;
+ InitCount := 0;
end;
class function TAudioCore_Portaudio.GetInstance(): TAudioCore_Portaudio;
@@ -101,9 +106,60 @@ 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;
+ i: integer;
apiIndex: TPaHostApiIndex;
apiInfo: PPaHostApiInfo;
begin
@@ -112,11 +168,11 @@ begin
// select preferred sound-API
for i:= 0 to High(ApiPreferenceOrder) do
begin
- if(ApiPreferenceOrder[i] <> paDefaultApi) then
+ if (ApiPreferenceOrder[i] <> paDefaultApi) then
begin
// check if API is available
apiIndex := Pa_HostApiTypeIdToHostApiIndex(ApiPreferenceOrder[i]);
- if(apiIndex >= 0) then
+ if (apiIndex >= 0) then
begin
// we found an API but we must check if it works
// (on linux portaudio might detect OSS but does not provide
@@ -132,7 +188,7 @@ begin
end;
// None of the preferred APIs is available -> use default
- if(result < 0) then
+ if (result < 0) then
begin
result := Pa_GetDefaultHostApi();
end;
@@ -141,9 +197,9 @@ end;
{*
* Portaudio test callback used by TestDevice().
*}
-function TestCallback(input: Pointer; output: Pointer; frameCount: Longword;
+function TestCallback(input: pointer; output: pointer; frameCount: longword;
timeInfo: PPaStreamCallbackTimeInfo; statusFlags: TPaStreamCallbackFlags;
- inputDevice: Pointer): Integer; cdecl;
+ inputDevice: pointer): integer; cdecl;
begin
// this callback is called only once
result := paAbort;
@@ -189,15 +245,15 @@ end;
* So we have to provide the possibility to manually select an output device
* in the UltraStar options if we want to use portaudio instead of SDL.
*)
-function TAudioCore_Portaudio.TestDevice(inParams, outParams: PPaStreamParameters; var sampleRate: Double): boolean;
+function TAudioCore_Portaudio.TestDevice(inParams, outParams: PPaStreamParameters; var sampleRate: double): boolean;
+const
+ altSampleRates: array[0..1] of double = (44100, 48000); // alternative sample-rates
var
- stream: PPaStream;
- err: TPaError;
+ stream: PPaStream;
+ err: TPaError;
cbWorks: boolean;
cbPolls: integer;
- i: integer;
-const
- altSampleRates: array[0..1] of Double = (44100, 48000); // alternative sample-rates
+ i: integer;
begin
Result := false;
@@ -206,7 +262,7 @@ begin
// check if device supports our input-format
err := Pa_IsFormatSupported(inParams, outParams, sampleRate);
- if(err <> paNoError) then
+ if (err <> paNoError) then
begin
// we cannot fix the error -> exit
if (err <> paInvalidSampleRate) then
@@ -244,14 +300,14 @@ begin
err := Pa_OpenStream(stream, inParams, outParams, sampleRate,
paFramesPerBufferUnspecified,
paNoFlag, @TestCallback, nil);
- if(err <> paNoError) then
+ if (err <> paNoError) then
begin
exit;
end;
// start the callback
err := Pa_StartStream(stream);
- if(err <> paNoError) then
+ if (err <> paNoError) then
begin
Pa_CloseStream(stream);
exit;