pyFMOD writing a callback function in Python

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Marian Aldenhövel

    #1

    pyFMOD writing a callback function in Python

    Hi,

    I am using the FMOD audio-library with the pyFMOD python bindings. pyFMOD uses
    ctypes. 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_S etEndCallback@1 2")
    _FSOUND_Stream_ SetEndCallback. restype = c_byte
    def FSOUND_Stream_S etEndCallback(s tream, 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_call back(stream,buf ,len,userdata):
    print "_sound_end_cal lback(): Stream has reached the end."

    as simplest possible callback function. I am registering it like this:

    pyFMOD.FSOUND_S tream_SetEndCal lback(_currentt rack,_sound_end _callback,0)

    And this is how my program dies:

    File "d:\projekte\ec lipse\workspace \gettone\getton esound.py", line 175, in
    sound_tick
    pyFMOD.FSOUND_S tream_SetEndCal lback(_currentt rack,_sound_end _callback,0)
    File "c:\programme\P ython23\lib\sit e-packages\pyFMOD .py", line 690, in
    FSOUND_Stream_S etEndCallback
    result = _FSOUND_Stream_ SetEndCallback( c_int(stream), c_int(callback) ,
    c_int(userdata) )
    TypeError: int expected instead of function instance

    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...

    Ciao, MM
    --
    Marian Aldenhövel, Rosenhain 23, 53123 Bonn. +49 228 624013.

    "Wir brauchen keine Opposition, wir sind bereits Demokraten."
  • Thomas Heller

    #2
    Re: pyFMOD writing a callback function in Python

    Marian Aldenhövel <marian@mba-software.de> writes:
    [color=blue]
    > Hi,
    >
    > I am using the FMOD audio-library with the pyFMOD python bindings. pyFMOD uses
    > ctypes.[/color]

    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.
    [color=blue]
    > 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_S etEndCallback@1 2")
    > _FSOUND_Stream_ SetEndCallback. restype = c_byte
    > def FSOUND_Stream_S etEndCallback(s tream, 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_call back(stream,buf ,len,userdata):
    > print "_sound_end_cal lback(): Stream has reached the end."
    >
    > as simplest possible callback function. I am registering it like this:
    >
    > pyFMOD.FSOUND_S tream_SetEndCal lback(_currentt rack,_sound_end _callback,0)
    >
    > And this is how my program dies:
    >
    > File "d:\projekte\ec lipse\workspace \gettone\getton esound.py", line
    > 175, in sound_tick
    > pyFMOD.FSOUND_S tream_SetEndCal lback(_currentt rack,_sound_end _callback,0)
    > File "c:\programme\P ython23\lib\sit e-packages\pyFMOD .py", line 690,
    > in FSOUND_Stream_S etEndCallback
    > result = _FSOUND_Stream_ SetEndCallback( c_int(stream),
    > c_int(callback) , c_int(userdata) )
    > TypeError: int expected instead of function instance[/color]

    The first problem is that the FSOUND_Stream_S etEndCallback 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_S etEndCallback call.
    All in all, it should look similar (I can't test it!) to this code:

    _FSOUND_Stream_ SetEndCallback = getattr(fmod,"_ FSOUND_Stream_S etEndCallback@1 2")
    _FSOUND_Stream_ SetEndCallback. restype = c_byte
    def FSOUND_Stream_S etEndCallback(s tream, 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_STREAMC ALLBACK)
    ## (FSOUND_STREAM *stream, void *buff, int len, void *userdata);

    # funtion prototype
    FSOUND_STREAMCA LLBACK = WINFUNCTYPE(c_c har, c_int, c_void_p, c_int, c_void_p)

    # create callback function
    callback_functi on = FSOUND_STREAMCA LLBACK(_sound_e nd_callback)

    # and then put it to work:

    FSOUND_Stream_S etEndCallback(s tream, callback_functi on, userdata)


    You should also be aware that you have to keep the callback_functi on
    object alive *as long as the FMOD library is using it*! If you don't,
    it will probably crash.
    [color=blue]
    > 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...[/color]

    Thomas

    Comment

    • Gary Bishop

      #3
      Re: pyFMOD writing a callback function in Python

      Check out pySonic, a new FMOD wrapper written with Pyrex. Much more Pythonic.

      gb


      Comment

      • Marian Aldenhövel

        #4
        Re: pyFMOD writing a callback function in Python

        Hi,
        [color=blue]
        > I was only able to find fmodapi374.zip (for windows), and that version doesn't
        > seem to work with the pyFMOD release I found.[/color]

        I found that too. But I could easily fix pyFMOD to use the FMOD 374. A few of
        the exports have been renamed and parameters have been added to others. As the
        total size of all parameters are encoded in the exported names all of these
        errors are caught when importing so you can fix them one by one by looking it
        up in the FMOD-Docs.
        [color=blue]
        > All in all, it should look similar (I can't test it!) to this code:[/color]

        I will try that when I get around to playing with the stuff again.
        [color=blue]
        > You should also be aware that you have to keep the callback_functi on
        > object alive *as long as the FMOD library is using it*![/color]

        While very obvious I am prone to forget that sometime :-).

        Ciao, MM
        --
        Marian Aldenhövel, Rosenhain 23, 53123 Bonn. +49 228 624013.

        "Wir brauchen keine Opposition, wir sind bereits Demokraten."

        Comment

        • Marian Aldenhövel

          #5
          Re: pyFMOD writing a callback function in Python

          Hi,
          [color=blue]
          > Check out pySonic, a new FMOD wrapper written with Pyrex. Much more Pythonic.[/color]

          I have only found Win32-Downloads. The same is true for pyFMOD. What options
          do I have to make it work on Linux?

          Ciao, MM
          --
          Marian Aldenhövel, Rosenhain 23, 53123 Bonn. +49 228 624013.

          "Wir brauchen keine Opposition, wir sind bereits Demokraten."

          Comment

          • kdahlhaus@yahoo.com

            #6
            Re: pyFMOD writing a callback function in Python

            Any opinion on pyFMOD vs. pySonic?

            Comment

            • Gary Bishop

              #7
              Re: pyFMOD writing a callback function in Python

              I haven't tried it on Linux but I believe it should work. FMOD works on Linux as does Pyrex.
              I don't think there is any win32 specific code. Grab the source and try building it. You'll
              likely have to fool with the libraries and includes in setup.py.

              gb

              Marian Aldenh?vel <marian@mba-software.de> wrote:[color=blue]
              > Hi,[/color]
              [color=blue][color=green]
              > > Check out pySonic, a new FMOD wrapper written with Pyrex. Much more Pythonic.[/color][/color]
              [color=blue]
              > I have only found Win32-Downloads. The same is true for pyFMOD. What options
              > do I have to make it work on Linux?[/color]

              Comment

              Working...