Skip to content

Commit 03764a8

Browse files
committed
Add "loop" argument to play()
1 parent ae2198e commit 03764a8

File tree

1 file changed

+14
-4
lines changed

1 file changed

+14
-4
lines changed

sounddevice.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,8 @@
253253
_last_callback = None
254254

255255

256-
def play(data, samplerate=None, mapping=None, blocking=False, **kwargs):
256+
def play(data, samplerate=None, mapping=None, blocking=False, loop=False,
257+
**kwargs):
257258
"""Play back an array of audio data.
258259
259260
Parameters
@@ -276,6 +277,8 @@ def play(data, samplerate=None, mapping=None, blocking=False, **kwargs):
276277
continues in the background), if ``True``, wait until playback
277278
is finished. A non-blocking invocation can be stopped with
278279
:func:`stop` or turned into a blocking one with :func:`wait`.
280+
loop : bool, optional
281+
Play `data` in a loop.
279282
280283
Other Parameters
281284
----------------
@@ -288,7 +291,7 @@ def play(data, samplerate=None, mapping=None, blocking=False, **kwargs):
288291
rec, playrec
289292
290293
"""
291-
ctx = _CallbackContext()
294+
ctx = _CallbackContext(loop=loop)
292295
ctx.frames = ctx.check_data(data, mapping, kwargs.get('device'))
293296

294297
def callback(outdata, frames, time, status):
@@ -2164,14 +2167,15 @@ class _CallbackContext(object):
21642167
input_mapping = output_mapping = None
21652168
silent_channels = None
21662169

2167-
def __init__(self):
2170+
def __init__(self, loop=False):
21682171
import threading
21692172
try:
21702173
import numpy
21712174
assert numpy # avoid "imported but unused" message (W0611)
21722175
except ImportError:
21732176
raise ImportError(
21742177
"NumPy must be installed for play()/rec()/playrec()")
2178+
self.loop = loop
21752179
self.event = threading.Event()
21762180
self.status = CallbackFlags()
21772181

@@ -2261,7 +2265,13 @@ def write_outdata(self, outdata):
22612265
outdata[:self.blocksize, self.output_mapping] = \
22622266
self.data[self.frame:self.frame + self.blocksize]
22632267
outdata[:self.blocksize, self.silent_channels] = 0
2264-
outdata[self.blocksize:] = 0
2268+
if self.loop and self.blocksize < len(outdata):
2269+
self.frame = 0
2270+
outdata = outdata[self.blocksize:]
2271+
self.blocksize = min(self.frames, len(outdata))
2272+
self.write_outdata(outdata)
2273+
else:
2274+
outdata[self.blocksize:] = 0
22652275

22662276
def callback_exit(self):
22672277
if not self.blocksize:

0 commit comments

Comments
 (0)