def write(self, audio_data, length): # Pass audio_data=None to write silence if length == 0: return 0 self.lock() p1 = ctypes.c_void_p() l1 = lib.DWORD() p2 = ctypes.c_void_p() l2 = lib.DWORD() self._buffer.Lock(self._write_cursor_ring, length, ctypes.byref(p1), l1, ctypes.byref(p2), l2, 0) assert length == l1.value + l2.value if audio_data: ctypes.memmove(p1, audio_data.data, l1.value) audio_data.consume(l1.value, self.source_group.audio_format) if l2.value: ctypes.memmove(p2, audio_data.data, l2.value) audio_data.consume(l2.value, self.source_group.audio_format) else: ctypes.memset(p1, 0, l1.value) if l2.value: ctypes.memset(p2, 0, l2.value) self._buffer.Unlock(p1, l1, p2, l2) self._write_cursor += length self._write_cursor_ring += length self._write_cursor_ring %= self._buffer_size self.unlock()
def update_play_cursor(self): self.lock() play_cursor_ring = lib.DWORD() self._buffer.GetCurrentPosition(play_cursor_ring, None) if play_cursor_ring.value < self._play_cursor_ring: # Wrapped around self._play_cursor += self._buffer_size - self._play_cursor_ring self._play_cursor_ring = 0 self._play_cursor += play_cursor_ring.value - self._play_cursor_ring self._play_cursor_ring = play_cursor_ring.value # Dispatch pending events pending_events = [] while self._events and self._events[0][0] <= self._play_cursor: _, event = self._events.pop(0) pending_events.append(event) if _debug: print 'Dispatching pending events:', pending_events print 'Remaining events:', self._events # Remove expired timestamps while self._timestamps and self._timestamps[0][0] < self._play_cursor: del self._timestamps[0] self.unlock() for event in pending_events: event._sync_dispatch_to_player(self.player)