Marian Aldenhövel <[EMAIL PROTECTED]> writes: > Hi, > > I am using the FMOD audio-library with the pyFMOD python bindings. pyFMOD uses > ctypes.
I was looking into this recently, because another poster also asked about pyFMOD: which FMOD version do you use? I was only able to find fmodapi374.zip (for windows), and that version doesn't seem to work with the pyFMOD release I found. > It is possible to register callback functions with FMOD that are > called at certain points in the processing pipeline or when certain events > happen. > > I am expecially interested in the one that fires when a currently playing > stream ends. This is what the declaration in pyFMOD looks like: > > _FSOUND_Stream_SetEndCallback = > getattr(fmod,"[EMAIL PROTECTED]") > _FSOUND_Stream_SetEndCallback.restype = c_byte > def FSOUND_Stream_SetEndCallback(stream, callback, userdata): > result = _FSOUND_Stream_SetEndCallback(c_int(stream), c_int(callback), > c_int(userdata)) > if not result: raise fmod_exception() > > I cannot make it work, however. I tried: > > def _sound_end_callback(stream,buf,len,userdata): > print "_sound_end_callback(): Stream has reached the end." > > as simplest possible callback function. I am registering it like this: > > pyFMOD.FSOUND_Stream_SetEndCallback(_currenttrack,_sound_end_callback,0) > > And this is how my program dies: > > File "d:\projekte\eclipse\workspace\gettone\gettonesound.py", line > 175, in sound_tick > pyFMOD.FSOUND_Stream_SetEndCallback(_currenttrack,_sound_end_callback,0) > File "c:\programme\Python23\lib\site-packages\pyFMOD.py", line 690, > in FSOUND_Stream_SetEndCallback > result = _FSOUND_Stream_SetEndCallback(c_int(stream), > c_int(callback), c_int(userdata)) > TypeError: int expected instead of function instance The first problem is that the FSOUND_Stream_SetEndCallback function, as given, converts all parameters to integers. Second, you cannot pass a Python function directly as callback, you have to create a function prototype first which specifies calling convention, return type, and argument types. Third, you instantiate the prototype with a Python callable, which creates the C callable callback function, and use that in the FSOUND_Stream_SetEndCallback call. All in all, it should look similar (I can't test it!) to this code: _FSOUND_Stream_SetEndCallback = getattr(fmod,"[EMAIL PROTECTED]") _FSOUND_Stream_SetEndCallback.restype = c_byte def FSOUND_Stream_SetEndCallback(stream, callback, userdata): result = _FSOUND_Stream_SetEndCallback(c_int(stream), callback, c_int(userdata)) if not result: raise fmod_exception() # from the FMOD header file: ##typedef signed char (F_CALLBACKAPI *FSOUND_STREAMCALLBACK) ## (FSOUND_STREAM *stream, void *buff, int len, void *userdata); # funtion prototype FSOUND_STREAMCALLBACK = WINFUNCTYPE(c_char, c_int, c_void_p, c_int, c_void_p) # create callback function callback_function = FSOUND_STREAMCALLBACK(_sound_end_callback) # and then put it to work: FSOUND_Stream_SetEndCallback(stream, callback_function, userdata) You should also be aware that you have to keep the callback_function object alive *as long as the FMOD library is using it*! If you don't, it will probably crash. > I am very new to Python and have zero idea what the problem is nor how to > solve it. In some of my other languages I would have to explicitly make a > function pointer and possibly have to cast that to an int to pass it to > SetEndCallback, but that seems very inappropriate in Python... Thomas -- http://mail.python.org/mailman/listinfo/python-list