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