Search code examples
pythoncallbackpyaudio

Finding the argument of a parent function from a callback


How can I find the argument given to a function that's calling a callback function, from within the callback?

The below code (incomplete) will initiate an audio stream that calls a callback function. It uses pyaudio.

Right now, there are hard-coded stuff in the callback function. I'm trying to get rid of those.

I've read the pyaudio doc and I can't seem to be able to pass extra arguments to the callback function. I've read about the inspect python module, its getsource or getouterframes that seemed to be interesting for me, in order to hopefully get to the argument given to the PlayStream function, but that has led me nowhere.

How can I refer to the SoundGeneratorObject argument from within callback?

def PlayStream(SoundGeneratorObject):
    p = pyaudio.PyAudio()
    stream = p.open(format = p.get_format_from_width(SoundGeneratorObject.WIDTH), 
                 channels = SoundGeneratorObject.CHANNELS, 
                 rate = SoundGeneratorObject.BITRATE, 
                 frames_per_buffer = SoundGeneratorObject.CHUNKSIZE,
                 output = True,
                 stream_callback = callback)
    stream.start_stream()
    while stream.is_active():
        time.sleep(0.1)
    stream.stop_stream()
    stream.close()
    p.terminate()

def callback(in_data, frame_count, time_info, status_flags):
    signal = waves.next()
    return (signal, pyaudio.paContinue)

waves = SoundGenerator()
PlayStream(waves)

Solution

  • Can you do something like this to create a scope for the callback you're passing?

    def callback_maker(waves):
        def callback(in_data, frame_count, time_info, status_flags):
            # do stuff (waves is in scope)
            signal = waves.next()
            return (signal, pyaudio.paContinue)
        return callback
    

    If you can, use it like this:

    stream = p.open(format = p.get_format_from_width(SoundGeneratorObject.WIDTH), 
                    channels = SoundGeneratorObject.CHANNELS, 
                    rate = SoundGeneratorObject.BITRATE, 
                    frames_per_buffer = SoundGeneratorObject.CHUNKSIZE,
                    output = True,
                    stream_callback = callback_maker(SoundGeneratorObject))