C callbacks getting a value of 0! Bug in D?

Johnson Jones via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Aug 27 18:57:27 PDT 2017


Trying to set a callback for portaudio and it's seeing zero for 
the value passed.

Pa_OpenStream(&stream, input, output, sampleRate, cast(ulong)0, 
cast(PaStreamFlags)(PaStreamFlags.NoFlag + 
0*PaStreamFlags.PrimeOutputBuffersUsingStreamCallback),
									 cast(PaStreamCallback)(a,b,c,d,e,f){
		callbackCalled = true;
										 return 0;
									 }, null);

I am using a debug build of portaudio that prints out all the 
parameters before anything else, so it's not an issue with 
portaudio.

I've tried passing a normal function:

__gshared int sawtooth(const(void)* inputBuffer, void* 
outputBuffer, ulong framesPerBuffer, 
const(PaStreamCallbackTimeInfo)* timeInfo, PaStreamCallbackFlags 
statusFlags, void *userData)
{ return 0; }

and passing it as &sawtooth.

with the same issue.

I've tried changing the calling convention and using __gshared 
but the value is always 0. It seems other values are 0 too and 
can't seem to get any value in to the callback(Even a random one).


The output essentially always looks like this:


Opening Stream!
Pa_OpenStream called:
         PaStream** stream: 0x00823EA0
         PaStreamParameters *inputParameters: NULL
         PaStreamParameters *outputParameters: 0x02C6C1C0
         PaDeviceIndex outputParameters->device: 3
         int outputParameters->channelCount: 4
         PaSampleFormat outputParameters->sampleFormat: 1
         PaTime outputParameters->suggestedLatency: 0.135000
         void *outputParameters->hostApiSpecificStreamInfo: 
0x00000000
         double sampleRate: 44100
         unsigned long framesPerBuffer: 256
         PaStreamFlags streamFlags: 0x0
         PaStreamCallback *streamCallback: 0x00000000
         void *userData: 0x00000000
Pa_GetSampleSize called:
         PaSampleFormat format: 8
Pa_GetSampleSize returned:
         int: 2
Pa_GetSampleSize called:
         PaSampleFormat format: 8
Pa_GetSampleSize returned:
         int: 2
Pa_GetSampleSize called:
         PaSampleFormat format: 1
Pa_GetSampleSize returned:
         int: 4
Pa_GetSampleSize called:
         PaSampleFormat format: 8
Pa_GetSampleSize returned:
         int: 2
Pa_GetSampleSize called:
         PaSampleFormat format: 8
Pa_GetSampleSize returned:
         int: 2
Pa_OpenStream returned:
         *(PaStream** stream): 0x03BEAD50
         PaError: 0 ( Success )


everything seems correct except:

         PaStreamCallback *streamCallback: 0x00000000
         void *userData: 0x00000000

You can find the full code at

https://forum.dlang.org/thread/lkbswgpsgxynhfyzwfqz@forum.dlang.org			


This is either a bug in D, an issue with calling conventions, or 
how one passes the data.


The original portaudio open stream function, so you can see that 
it simply prints it's arguments:

PaError Pa_OpenStream( PaStream** stream,
                        const PaStreamParameters *inputParameters,
                        const PaStreamParameters *outputParameters,
                        double sampleRate,
                        unsigned long framesPerBuffer,
                        PaStreamFlags streamFlags,
                        PaStreamCallback *streamCallback,
                        void *userData )
{
     PaError result;
     PaUtilHostApiRepresentation *hostApi = 0;
     PaDeviceIndex hostApiInputDevice = paNoDevice, 
hostApiOutputDevice = paNoDevice;
     PaStreamParameters hostApiInputParameters, 
hostApiOutputParameters;
     PaStreamParameters *hostApiInputParametersPtr, 
*hostApiOutputParametersPtr;


#ifdef PA_LOG_API_CALLS
     PA_LOGAPI_ENTER_PARAMS( "Pa_OpenStream" );
     PA_LOGAPI(("\tPaStream** stream: 0x%p\n", stream ));

     if( inputParameters == NULL ){
         PA_LOGAPI(("\tPaStreamParameters *inputParameters: 
NULL\n" ));
     }else{
         PA_LOGAPI(("\tPaStreamParameters *inputParameters: 
0x%p\n", inputParameters ));
         PA_LOGAPI(("\tPaDeviceIndex inputParameters->device: 
%d\n", inputParameters->device ));
         PA_LOGAPI(("\tint inputParameters->channelCount: %d\n", 
inputParameters->channelCount ));
         PA_LOGAPI(("\tPaSampleFormat 
inputParameters->sampleFormat: %d\n", 
inputParameters->sampleFormat ));
         PA_LOGAPI(("\tPaTime inputParameters->suggestedLatency: 
%f\n", inputParameters->suggestedLatency ));
         PA_LOGAPI(("\tvoid 
*inputParameters->hostApiSpecificStreamInfo: 0x%p\n", 
inputParameters->hostApiSpecificStreamInfo ));
     }

     if( outputParameters == NULL ){
         PA_LOGAPI(("\tPaStreamParameters *outputParameters: 
NULL\n" ));
     }else{
         PA_LOGAPI(("\tPaStreamParameters *outputParameters: 
0x%p\n", outputParameters ));
         PA_LOGAPI(("\tPaDeviceIndex outputParameters->device: 
%d\n", outputParameters->device ));
         PA_LOGAPI(("\tint outputParameters->channelCount: %d\n", 
outputParameters->channelCount ));
         PA_LOGAPI(("\tPaSampleFormat 
outputParameters->sampleFormat: %d\n", 
outputParameters->sampleFormat ));
         PA_LOGAPI(("\tPaTime outputParameters->suggestedLatency: 
%f\n", outputParameters->suggestedLatency ));
         PA_LOGAPI(("\tvoid 
*outputParameters->hostApiSpecificStreamInfo: 0x%p\n", 
outputParameters->hostApiSpecificStreamInfo ));
     }

     PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate ));
     PA_LOGAPI(("\tunsigned long framesPerBuffer: %d\n", 
framesPerBuffer ));
     PA_LOGAPI(("\tPaStreamFlags streamFlags: 0x%x\n", streamFlags 
));
     PA_LOGAPI(("\tPaStreamCallback *streamCallback: 0x%p\n", 
streamCallback ));
     PA_LOGAPI(("\tvoid *userData: 0x%p\n", userData ));
#endif


and this is how I define it in the code(which you can see if you 
follow the link):

PaError function(PaStream** stream, const PaStreamParameters 
*inputParameters, const PaStreamParameters *outputParameters, 
double sampleRate, ulong framesPerBuffer, PaStreamFlags 
streamFlags, PaStreamCallback streamCallback, void *userData) 
Pa_OpenStream;

I can play audio if I do a hard write, but obviously that is 
generally useless.

This seems like it might be a bug in D in that the last 
parameters are invalid. user_data, which is passing a simple 
pointer is also 0, when it isn't.

Even trying something like

PaError function(PaStream** stream, const PaStreamParameters 
*inputParameters, const PaStreamParameters *outputParameters, 
double sampleRate, ulong framesPerBuffer, PaStreamFlags 
streamFlags, size_t streamCallback, size_t userData) 
Pa_OpenStream;

and passing numbers still shows zero values!


Any ideas?


More information about the Digitalmars-d-learn mailing list