@@ -843,10 +843,12 @@ def get_portaudio_version():
843843class _StreamBase (object ):
844844 """Base class for Raw{Input,Output}Stream."""
845845
846- def __init__ (self , kind , samplerate , blocksize , device , channels , dtype ,
847- latency , extra_settings , callback_wrapper , finished_callback ,
848- clip_off , dither_off , never_drop_input ,
849- prime_output_buffers_using_stream_callback ):
846+ def __init__ (self , kind , samplerate = None , blocksize = None , device = None ,
847+ channels = None , dtype = None , latency = None , extra_settings = None ,
848+ callback = None , finished_callback = None , clip_off = None ,
849+ dither_off = None , never_drop_input = None ,
850+ prime_output_buffers_using_stream_callback = None ,
851+ userdata = None ):
850852 if blocksize is None :
851853 blocksize = default .blocksize
852854 if clip_off is None :
@@ -904,16 +906,22 @@ def __init__(self, kind, samplerate, blocksize, device, channels, dtype,
904906 iparameters = _ffi .NULL
905907 oparameters = parameters
906908
907- if callback_wrapper :
908- self ._callback = _ffi .callback (
909- 'PaStreamCallback' , callback_wrapper , error = _lib .paAbort )
909+ if callback is None :
910+ callback = _ffi .NULL
911+ elif isinstance (callback , _ffi .CData ):
912+ # Use cast() to allow CData from different FFI instance:
913+ callback = _ffi .cast ('PaStreamCallback*' , callback )
910914 else :
911- self ._callback = _ffi .NULL
912-
915+ callback = _ffi .callback (
916+ 'PaStreamCallback' , callback , error = _lib .paAbort )
917+ # CFFI callback object is kept alive during stream lifetime:
918+ self ._callback = callback
919+ if userdata is None :
920+ userdata = _ffi .NULL
913921 self ._ptr = _ffi .new ('PaStream**' )
914922 _check (_lib .Pa_OpenStream (self ._ptr , iparameters , oparameters ,
915923 samplerate , blocksize , stream_flags ,
916- self . _callback , _ffi . NULL ),
924+ callback , userdata ),
917925 'Error opening {0}' .format (self .__class__ .__name__ ))
918926
919927 # dereference PaStream** --> PaStream*
@@ -933,14 +941,17 @@ def __init__(self, kind, samplerate, blocksize, device, channels, dtype,
933941 self ._latency = info .inputLatency , info .outputLatency
934942
935943 if finished_callback :
944+ if not isinstance (finished_callback , _ffi .CData ):
936945
937- def finished_callback_wrapper (_ ):
938- return finished_callback ()
946+ def finished_callback_wrapper (_ ):
947+ return finished_callback ()
939948
940- self ._finished_callback = _ffi .callback (
941- 'PaStreamFinishedCallback' , finished_callback_wrapper )
949+ finished_callback = _ffi .callback (
950+ 'PaStreamFinishedCallback' , finished_callback_wrapper )
951+ # CFFI callback object is kept alive during stream lifetime:
952+ self ._finished_callback = finished_callback
942953 _check (_lib .Pa_SetStreamFinishedCallback (self ._ptr ,
943- self . _finished_callback ))
954+ finished_callback ))
944955
945956 # Avoid confusion if something goes wrong before assigning self._ptr:
946957 _ptr = _ffi .NULL
0 commit comments