pyFMOD writing a callback function in Python
Thomas Heller
theller at python.net
Thu Feb 10 13:21:25 EST 2005
Marian Aldenhövel <marian at mba-software.de> 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,"_FSOUND_Stream_SetEndCallback at 12")
> _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,"_FSOUND_Stream_SetEndCallback at 12")
_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
More information about the Python-list
mailing list