Skip to content

Commit 0be8320

Browse files
committed
Replace global _stream and _event with a single _CallbackContext
1 parent 2dc7601 commit 0be8320

File tree

1 file changed

+32
-31
lines changed

1 file changed

+32
-31
lines changed

sounddevice.py

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,7 @@
234234
'uint8': _lib.paUInt8,
235235
}
236236

237-
_stream = None
238-
_event = None
237+
_last_callback = None
239238

240239

241240
def play(data, samplerate=None, mapping=None, blocking=False, **kwargs):
@@ -431,19 +430,15 @@ def callback(indata, outdata, frames, time, status):
431430
def wait():
432431
"""Wait for :func:`play`/:func:`rec`/:func:`playrec` to be finished.
433432
434-
Playback/recording can be stopped with a :obj:`KeyboardInterrupt`.
433+
Playback/recording can be stopped with a :class:`KeyboardInterrupt`.
435434
436435
"""
437-
global _event
438-
if _event is None:
439-
return
440-
try:
441-
_event.wait()
442-
finally:
443-
stop()
436+
global _last_callback
437+
if _last_callback:
438+
_last_callback.wait()
444439

445440

446-
def stop():
441+
def stop(ignore_errors=True):
447442
"""Stop playback/recording.
448443
449444
This only stops :func:`play`, :func:`rec` and :func:`playrec`, but
@@ -452,13 +447,9 @@ def stop():
452447
:class:`RawInputStream`, :class:`RawOutputStream`.
453448
454449
"""
455-
global _stream
456-
try:
457-
_stream.close()
458-
except AttributeError:
459-
pass # If stop() is called before play()
460-
except PortAudioError:
461-
pass # If stop() is called multiple times
450+
global _last_callback
451+
if _last_callback:
452+
_last_callback.stream.close(ignore_errors)
462453

463454

464455
def print_devices():
@@ -2091,10 +2082,7 @@ def __init__(self):
20912082
except ImportError:
20922083
raise ImportError(
20932084
"NumPy must be installed for play()/rec()/playrec()")
2094-
stop() # Stop previous playback/recording
2095-
global _event
2096-
# self.event is kept alive even if _event is re-bound
2097-
_event = self.event = threading.Event()
2085+
self.event = threading.Event()
20982086
self.logger = _logging.getLogger(__name__)
20992087
self.status = CallbackFlags()
21002088

@@ -2196,16 +2184,29 @@ def finished_callback(self):
21962184

21972185
def start_stream(self, StreamClass, samplerate, channels, dtype, callback,
21982186
blocking, **kwargs):
2199-
global _stream
2200-
_stream = StreamClass(samplerate=samplerate,
2201-
channels=channels,
2202-
dtype=dtype,
2203-
callback=callback,
2204-
finished_callback=self.finished_callback,
2205-
**kwargs)
2206-
_stream.start()
2187+
stop() # Stop previous playback/recording
2188+
self.stream = StreamClass(samplerate=samplerate,
2189+
channels=channels,
2190+
dtype=dtype,
2191+
callback=callback,
2192+
finished_callback=self.finished_callback,
2193+
**kwargs)
2194+
self.stream.start()
2195+
global _last_callback
2196+
_last_callback = self
22072197
if blocking:
2208-
wait()
2198+
self.wait()
2199+
2200+
def wait(self):
2201+
"""Wait for finished_callback.
2202+
2203+
Can be interrupted with a KeyboardInterrupt.
2204+
2205+
"""
2206+
try:
2207+
self.event.wait()
2208+
finally:
2209+
self.stream.close()
22092210

22102211

22112212
def _check_mapping(mapping, channels):

0 commit comments

Comments
 (0)