Recent

Author Topic: PortAudio Configure Device & CallBack  (Read 1021 times)

bbrx

  • New Member
  • *
  • Posts: 15
PortAudio Configure Device & CallBack
« on: February 13, 2025, 06:40:42 am »
Hello,
I'm trying to use PortAudio (compiled x64 with AsioSDK support on) and I have some trouble :
I got access violation outputParams.suggestedLatency := Pa_GetDeviceInfo(myAsioDeviceIndex)^.defaultLowOutputLatency;

but I don't understand why my callback function isn't recognized.
here ma declaration :

function AudioCallback(const pInputBuffer         : pointer;
                              pOutputBuffer              : pointer;
                         const {%H-}FramesPerBuffer : culong;
                         const {%H-}pTimeInfo       : PPaStreamCallbackTimeInfo;
                         {%H-}PAStatusFlags         : TPaStreamCallbackFlags;
                         pUserData                  : pointer) : CInt32; cdecl;
begin
  FillChar(pOutputBuffer^, FramesPerBuffer * SizeOf(Single) * 2, 0);  // pour 2 canaux en float32
  Result := 0;  // ou une valeur comme paContinue
end;     
...
here my call to callback
  LPaError := Pa_OpenStream(LPaStream, 0, 2, paFloat32, 44100, 256, @AudioCallback,  @Data);
    if not LPaError = 0 then Error;
...
Error msg :

unit1.pas(198,83) Error: Incompatible type for arg no. 7: Got "<address of function(const Pointer;Pointer;const LongWord;const PPaStreamCallbackTimeInfo;LongWord;Pointer):LongInt;CDecl>", expected "PPaStreamCallback"

I put a small demo project if you wish to test it.

Thanks for your help :)

TRon

  • Hero Member
  • *****
  • Posts: 4162
Re: PortAudio Configure Device & CallBack
« Reply #1 on: February 13, 2025, 07:10:04 am »
but I don't understand why my callback function isn't recognized.
It is because the definition of the Pa_OpenStream function in the portaudio header unit is wrong. Classic mistake as we do not use pointers to functions for a callback because the function itself is already a pointer.

Redefine the Pa_OpenStream function to match the actual definition.

PS: luckily it isn't obvious that all available portaudio headers can be tracked back to one original source. Copy-Pasta-Error  :D
« Last Edit: February 13, 2025, 07:30:20 am by TRon »
Today is tomorrow's yesterday.

bbrx

  • New Member
  • *
  • Posts: 15
Re: PortAudio Configure Device & CallBack
« Reply #2 on: February 13, 2025, 09:09:03 am »
Thanks TRon.

>It is because the definition of the Pa_OpenStream function in the portaudio header
Where ? in my declaration or in the wrapper?

TRon

  • Hero Member
  • *****
  • Posts: 4162
Re: PortAudio Configure Device & CallBack
« Reply #3 on: February 13, 2025, 09:13:33 am »
Where ? in my declaration or in the wrapper?
Inside the wrapper units (both uos and original one are wrongly defined)
Today is tomorrow's yesterday.

bbrx

  • New Member
  • *
  • Posts: 15
Re: PortAudio Configure Device & CallBack
« Reply #4 on: February 13, 2025, 09:46:55 am »
TRon,

I go to Portaudio declaration and I see this


PaError Pa_OpenDefaultStream   (   PaStream **    stream,
int    numInputChannels,
int    numOutputChannels,
PaSampleFormat    sampleFormat,
double    sampleRate,
unsigned long    framesPerBuffer,
PaStreamCallback *    streamCallback,
void *    userData
)   

The conversion is pascal is :

  TPaStreamCallback = function(const inputBuffer: Pointer;
                               outputBuffer: Pointer;
                               framesPerBuffer: Cardinal;
                               const timeInfo: PPaStreamCallbackTimeInfo;
                               statusFlags: TPaStreamCallbackFlags;
                               userData: Pointer): Integer; cdecl;
  PPaStreamCallback = TPaStreamCallback;

So where is the mistake ? I don't see and always a  same error

TRon

  • Hero Member
  • *****
  • Posts: 4162
Re: PortAudio Configure Device & CallBack
« Reply #5 on: February 13, 2025, 09:58:17 am »
TRon,

I go to Portaudio declaration and I see this

Code: C  [Select][+][-]
  1. PaError Pa_OpenDefaultStream    (       PaStream **     stream,
  2. int     numInputChannels,
  3. int     numOutputChannels,
  4. PaSampleFormat  sampleFormat,
  5. double  sampleRate,
  6. unsigned long   framesPerBuffer,
  7. PaStreamCallback *      streamCallback,  <<<--- in pascal a callback function is already a pointer
  8. void *  userData
  9. )      
  10.  

This c-function declaration is actually not the pa_openstream function (I agree it is almost the same but not quite)

But indeed, the pascal implementation of that function declaration is also wrong.

Quote
The conversion is pascal is :

No, that is the actual pascal callback function definition  ;D

Quote
So where is the mistake ? I don't see and always a  same error

The function declaration you should be looking for is:
Code: Pascal  [Select][+][-]
  1.   function Pa_OpenStream( var stream: PPaStream;
  2.                          inputParameters: PPaStreamParameters;
  3.                          outputParameters: PPaStreamParameters;
  4.                          sampleRate: cdouble;
  5.                          framesPerBuffer: culong;
  6.                          streamFlags: TPaStreamFlags;
  7.                          streamCallback: PPaStreamCallback;  <<<<<--- again, no need to declare it as a pointer just the callback function declaration.
  8.                          userData: Pointer ): TPaError; cdecl; external LibName;
  9.  
  10.  

Does that help ?

PS: I do not offer a copy-paste solution because before we know it I am the sucker fixing all the errors in those header-files and I do not have any intention of doing so (nothing personal).
« Last Edit: February 13, 2025, 10:10:18 am by TRon »
Today is tomorrow's yesterday.

bbrx

  • New Member
  • *
  • Posts: 15
Re: PortAudio Configure Device & CallBack
« Reply #6 on: February 13, 2025, 10:08:59 am »
I'm trying to understand what you mean by saying "PaStreamCallback *      streamCallback,  <<<--- in pascal a callback function is already a pointer", so I need to change by TPaStreamCallbackTimeInfo; instead PaStreamCallback?

Like this ?

  function Pa_OpenStream( var stream: PPaStream;
                         inputParameters: PPaStreamParameters;
                         outputParameters: PPaStreamParameters;
                         sampleRate: cdouble;
                         framesPerBuffer: culong;
                         streamFlags: TPaStreamFlags;
                        streamCallback: TPaStreamCallbackTimeInfo;
                         userData: Pointer ): TPaError; cdecl; external LibName;   

TRon

  • Hero Member
  • *****
  • Posts: 4162
Re: PortAudio Configure Device & CallBack
« Reply #7 on: February 13, 2025, 10:11:59 am »
Like this ?
Heading in the right direction. Have a closer look at the type. We are not interested in the TimeInfo part  ;D
Today is tomorrow's yesterday.

bbrx

  • New Member
  • *
  • Posts: 15
Re: PortAudio Configure Device & CallBack
« Reply #8 on: February 13, 2025, 10:20:17 am »
I'll try, so  streamCallback: TPaStreamCallback;

  function Pa_OpenStream( var stream: PPaStream;
                         inputParameters: PPaStreamParameters;
                         outputParameters: PPaStreamParameters;
                         sampleRate: cdouble;
                         framesPerBuffer: culong;
                         streamFlags: TPaStreamFlags;
                         streamCallback: TPaStreamCallback;
                         userData: Pointer ): TPaError; cdecl; external LibNam

and
use on the code :
  LPaError := Pa_OpenStream(LPaStream, 0, 2, paFloat32, 44100, 256, AudioCallback,  @Data);   ? without  @

Sorry the night was hard for me :)

TRon

  • Hero Member
  • *****
  • Posts: 4162
Re: PortAudio Configure Device & CallBack
« Reply #9 on: February 13, 2025, 10:26:48 am »
In ObjFPC mode with @ in Delphi mode without.

I try to make it clearer.  Whenever you see this (or another function definition similar to it):
Code: Pascal  [Select][+][-]
  1.  TPaStreamCallback = function(
  2.       input: Pointer; output: Pointer;
  3.       frameCount: culong;
  4.       timeInfo: PPaStreamCallbackTimeInfo;
  5.       statusFlags: TPaStreamCallbackFlags;
  6.       userData: Pointer ): cint; cdecl;
  7.  
That means that you define a type which is typically used as/for a callback function. This 'function' is already treated as a pointer in Pascal, this in opposite to c which has to declare it specifically as a pointer.

I understand,m it all looks the same and there are only minor differences. Which is exactly the reason I never fix headers provided by someone else as it is much quicker to just write your own (and do it correctly right from the start).

It is amazing how long this (faulty) header is in circulation and being copied over and over and nobody ever seem to have noticed it is plain wrong and not working  :o

BTW: now your original code will still not compile but that is for complete other reasons, I think you already know why based on your commented code in that same project).
« Last Edit: February 13, 2025, 10:34:14 am by TRon »
Today is tomorrow's yesterday.

bbrx

  • New Member
  • *
  • Posts: 15
Re: PortAudio Configure Device & CallBack
« Reply #10 on: February 13, 2025, 10:35:23 am »
You right TRon, thank you for your time and your (great) explaination! :)  :D

TRon

  • Hero Member
  • *****
  • Posts: 4162
Re: PortAudio Configure Device & CallBack
« Reply #11 on: February 13, 2025, 10:40:26 am »
You're welcome.

The intention is to enable you to be able to fish on your own (in case of troubles just ask/verify), but no matter the case just make sure you get a good nights rest. Nothing is worse then sleep-deprived written code (I should know)  :)

Happy coding !
Today is tomorrow's yesterday.

Fred vS

  • Hero Member
  • *****
  • Posts: 3505
    • StrumPract is the musicians best friend
Re: PortAudio Configure Device & CallBack
« Reply #12 on: February 17, 2025, 09:26:11 pm »
Where ? in my declaration or in the wrapper?
Inside the wrapper units (both uos and original one are wrongly defined)

Oops, thanks for reminding me. I found back your audiostuff11.tar.xz and will look into it tonight and do the fixes.
[EDIT] uos_portaudio.pas was updated with your fixes, many thanks.
« Last Edit: February 17, 2025, 10:15:37 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

TRon

  • Hero Member
  • *****
  • Posts: 4162
Re: PortAudio Configure Device & CallBack
« Reply #13 on: February 18, 2025, 04:20:52 pm »
Oh, sorry Fred vS, otherwise I would have mentioned. I though you already fixed these. I also thought OP had included an older version of the uos portaudio unit.

Never too late  ... :)

Thank you for the fixes.
Today is tomorrow's yesterday.

 

TinyPortal © 2005-2018