Skip to content

Commit 539c31a

Browse files
committed
sampler example: check for input xruns, minor change to polling
1 parent 20a682c commit 539c31a

File tree

1 file changed

+29
-17
lines changed

1 file changed

+29
-17
lines changed

examples/sampler.py

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -97,28 +97,40 @@ def on_key_release(self, event):
9797
assert False, (event.char, sample.action)
9898

9999
def poll_ringbuffer(self, sample):
100+
# Setting polling rate based on input latency (which may change!).
101+
# NB: We are rounding up because PortAudio might report a latency of
102+
# less than 1 ms.
103+
self.after(int(self.stream.latency[0] * 1000) + 1,
104+
self._poll_ringbuffer, sample)
105+
106+
def _poll_ringbuffer(self, sample):
100107
assert sample.action is not None
101108
assert sample.action.type in (rtmixer.RECORD_RINGBUFFER,
102109
rtmixer.CANCEL)
103-
if sample.action not in self.stream.actions:
104-
# Recording is finished
105-
self.rec_counter -= 1
106-
if sample.action.type == rtmixer.CANCEL:
107-
# TODO: check for errors in CANCEL action?
108-
action = sample.action.action
109-
else:
110-
action = sample.action
111-
assert action.type == rtmixer.RECORD_RINGBUFFER
112-
if action.done_frames != action.total_frames:
113-
print('error while recording (ringbuffer too short?)')
114-
# TODO: check for xruns?
115-
# NB: We make sure that the ringbuffer is emptied after recording:
110+
if sample.action in self.stream.actions:
116111
sample.buffer.extend(sample.ringbuffer.read())
112+
self.poll_ringbuffer(sample)
113+
return
114+
115+
# Recording is finished
116+
self.rec_counter -= 1
117+
if sample.action.type == rtmixer.CANCEL:
118+
# TODO: check for errors in CANCEL action?
119+
# NB: The "inner" action had to be kept alive
120+
action = sample.action.action
117121
else:
118-
sample.buffer.extend(sample.ringbuffer.read())
119-
# Set polling rate based on input latency (which may change!):
120-
self.after(int(self.stream.latency[0] * 1000),
121-
self.poll_ringbuffer, sample)
122+
action = sample.action
123+
assert action.type == rtmixer.RECORD_RINGBUFFER
124+
if action.done_frames != action.total_frames:
125+
print('error while recording (ringbuffer too short?)')
126+
if action.stats.input_underflows:
127+
print('input underflows:', action.stats.input_underflows,
128+
'(in', action.stats.blocks, 'blocks)')
129+
if action.stats.input_overflows:
130+
print('input overflows:', action.stats.input_overflows,
131+
'(in', action.stats.blocks, 'blocks)')
132+
# NB: We make sure that the ringbuffer is emptied after recording:
133+
sample.buffer.extend(sample.ringbuffer.read())
122134

123135

124136
def main():

0 commit comments

Comments
 (0)