Recent

Author Topic: [SOLVED] Initialize PortAudio and GetDeviceCount  (Read 3531 times)

tudi_x

  • Hero Member
  • *****
  • Posts: 532
[SOLVED] Initialize PortAudio and GetDeviceCount
« on: August 11, 2017, 04:46:13 pm »
hi All,
i am trying to get the device count (http://portaudio.com/docs/v19-doxydocs/querying_devices.html) using the PortAudio library on 64b I found in the uos library.
as per the code below the initialization (http://www.portaudio.com/docs/v19-doxydocs/initializing_portaudio.html) returns a zero code but the getdevice count returns a -10000 error code.
please advise what i am missing.

thank you

Code: Pascal  [Select][+][-]
  1. unit manage_portaudio;  //use in order to initialize and terminate working with portaudio
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   {$IFDEF UNIX}cthreads,{$ENDIF}
  9.   Classes,
  10.   SysUtils,
  11.   dynlibs;
  12.  
  13. function ManagePortAudio(const AFileName: string; ToInitialize, ToTerminate: boolean; out AResult: integer): boolean;
  14.  
  15. {mapping external function}
  16. type
  17.   //may return an error code
  18.   TManageLib = function(): integer; stdcall;
  19.  
  20. implementation
  21.  
  22. function ManagePortAudio(const AFileName: string; ToInitialize, ToTerminate: boolean; out AResult: integer): boolean;
  23. var
  24.   DLLInstance: THandle;
  25.   msg: TManageLib;
  26.  
  27. begin
  28.   Result := False;
  29.  
  30.   try
  31.     try
  32.       DLLInstance := SafeLoadLibrary(AFileName);
  33.  
  34.       if DLLInstance <> NilHandle then
  35.       begin
  36.  
  37.         if ToInitialize then
  38.         begin
  39.           msg := TManageLib(GetProcedureAddress(DLLInstance, 'Pa_Initialize'));
  40.         end;
  41.  
  42.         if ToTerminate then
  43.         begin
  44.           msg := TManageLib(GetProcedureAddress(DLLInstance, 'Pa_Terminate'));
  45.         end;
  46.  
  47.         if @msg <> nil then
  48.         begin
  49.           AResult := msg(); //runs also the function call
  50.           if AResult > -1 then
  51.             Result := True;
  52.         end;
  53.  
  54.       end;
  55.  
  56.     finally
  57.       FreeLibrary(DLLInstance);
  58.     end;
  59.   except
  60.     on E: Exception do
  61.     begin
  62.       AResult := -1;
  63.     end;
  64.   end;
  65. end;
  66.  
  67. end.

Code: Pascal  [Select][+][-]
  1. unit get_device_count;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   {$IFDEF UNIX}cthreads,{$ENDIF}
  9.   Classes,
  10.   SysUtils,
  11.   dynlibs
  12.   {$IFDEF MSWINDOWS}, Windows{$ENDIF};
  13.  
  14. function GetDeviceCount(const AFileName: string; out AResult: integer): boolean;
  15.  
  16. {mapping external function}
  17. type
  18.   TDeviceCount = function(): integer; stdcall;
  19.  
  20. implementation
  21.  
  22. {$IFDEF MSWINDOWS}
  23. function GetDeviceCount(const AFileName: string; out AResult: integer): boolean;
  24. var
  25.   DLLInstance: THandle;
  26.   c: TDeviceCount;
  27.  
  28. begin
  29.   Result := False;
  30.  
  31.   try
  32.     try
  33.       DLLInstance := SafeLoadLibrary(AFileName);
  34.  
  35.       if DLLInstance <> NilHandle then
  36.       begin
  37.         c := TDeviceCount(GetProcedureAddress(DLLInstance, 'Pa_GetDeviceCount'));
  38.  
  39.         if @c <> nil then
  40.         begin
  41.           AResult := c();  //runs the external function
  42.         end
  43.         else
  44.           AResult := -1;
  45.       end;
  46.  
  47.     finally
  48.       FreeLibrary(DLLInstance);
  49.     end;
  50.   except
  51.     on E: Exception do
  52.     begin
  53.       AResult := -2;
  54.     end;
  55.   end;
  56. end;
  57.  
  58. {$ENDIF}
  59.  
  60. end.

Code: Pascal  [Select][+][-]
  1. program learn_dlls;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   Classes,
  7.   SysUtils,
  8.   CustApp,
  9.   get_device_count,
  10.   manage_portaudio;
  11.  
  12. type
  13.   TWorkDLL = class(TCustomApplication)
  14.   protected
  15.     procedure DoRun; override;
  16.   public
  17.     constructor Create(TheOwner: TComponent); override;
  18.     destructor Destroy; override;
  19.   end;
  20.  
  21. const
  22.   LibPath = 'LibPortaudio-64.dll';
  23.  
  24.   procedure TWorkDLL.DoRun;
  25.   var
  26.     c: integer;
  27.  
  28.   begin
  29.     {$IFDEF MSWINDOWS}
  30.     {initialize library}
  31.     if ManagePortAudio(LibPath, True, False, c) then
  32.       Writeln(IntToStr(c))
  33.     else
  34.       Writeln('Error initialize: ' + IntToStr(c));
  35.  
  36.     {get the number of audio devices}
  37.     if GetDeviceCount(LibPath, c) then
  38.       Writeln(IntToStr(c))
  39.     else
  40.       Writeln('Error device count: ' + IntToStr(c));
  41.  
  42.     {free library}
  43.     if ManagePortAudio(LibPath, False, True, c) then
  44.       Writeln(IntToStr(c))
  45.     else
  46.       Writeln('Error terminate: ' + IntToStr(c));
  47.     {$ENDIF}
  48.     Terminate;
  49.   end;
  50.  
  51.   constructor TWorkDLL.Create(TheOwner: TComponent);
  52.   begin
  53.     inherited Create(TheOwner);
  54.     StopOnException := True;
  55.   end;
  56.  
  57.   destructor TWorkDLL.Destroy;
  58.   begin
  59.     inherited Destroy;
  60.   end;
  61.  
  62. var
  63.   Application: TWorkDLL;
  64. begin
  65.   Application := TWorkDLL.Create(nil);
  66.   Application.Title := 'Test_DLL';
  67.   Application.Run;
  68.   Application.Free;
  69. end.
« Last Edit: August 11, 2017, 05:39:43 pm by tudi_x »
Lazarus 2.0.2 64b on Debian LXDE 10

tudi_x

  • Hero Member
  • *****
  • Posts: 532
Re: Initialize PortAudio and GetDeviceCount
« Reply #1 on: August 11, 2017, 05:39:30 pm »
the issue was that the DLL was opened again and again.
reusing the DLL handle would get the device count.
Lazarus 2.0.2 64b on Debian LXDE 10

 

TinyPortal © 2005-2018