def prepare(self, source): if not source.audio_format: # TODO avoid creating in this case. return format = { 8: asound.SND_PCM_FORMAT_U8, 16: asound.SND_PCM_FORMAT_S16, 24: asound.SND_PCM_FORMAT_S24, # probably won't work 32: asound.SND_PCM_FORMAT_S32 }.get(source.audio_format.sample_size) if format is None: raise ALSAException('Unsupported audio format.') check(asound.snd_pcm_hw_params_set_access(self.pcm, self.hwparams, asound.SND_PCM_ACCESS_RW_INTERLEAVED)) check(asound.snd_pcm_hw_params_set_format(self.pcm, self.hwparams, format)) check(asound.snd_pcm_hw_params_set_channels(self.pcm, self.hwparams, source.audio_format.channels)) check(asound.snd_pcm_hw_params_set_rate(self.pcm, self.hwparams, source.audio_format.sample_rate, 0)) check(asound.snd_pcm_hw_params_set_buffer_size(self.pcm, self.hwparams, int(self._ring_buffer_time * source.audio_format.sample_rate))) check(asound.snd_pcm_hw_params(self.pcm, self.hwparams)) if alsa_debug: check(asound.snd_pcm_dump(self.pcm, debug_output)) self.can_pause = asound.snd_pcm_hw_params_can_pause(self.hwparams)
def __init__(self, audio_format): super(ALSAAudioPlayer, self).__init__(audio_format) format = { 8: asound.SND_PCM_FORMAT_U8, 16: asound.SND_PCM_FORMAT_S16, 24: asound.SND_PCM_FORMAT_S24, # probably won't work 32: asound.SND_PCM_FORMAT_S32 }.get(audio_format.sample_size) if format is None: raise ALSAException('Unsupported audio format.') self.pcm = ctypes.POINTER(asound.snd_pcm_t)() self.hwparams = ctypes.POINTER(asound.snd_pcm_hw_params_t)() self.swparams = ctypes.POINTER(asound.snd_pcm_sw_params_t)() check(asound.snd_pcm_open(ctypes.byref(self.pcm), self._device_name, asound.SND_PCM_STREAM_PLAYBACK, asound.SND_PCM_NONBLOCK)) check(asound.snd_pcm_hw_params_malloc(ctypes.byref(self.hwparams))) check(asound.snd_pcm_sw_params_malloc(ctypes.byref(self.swparams))) check(asound.snd_pcm_hw_params_any(self.pcm, self.hwparams)) check(asound.snd_pcm_hw_params_set_access(self.pcm, self.hwparams, asound.SND_PCM_ACCESS_RW_INTERLEAVED)) check(asound.snd_pcm_hw_params_set_format(self.pcm, self.hwparams, format)) check(asound.snd_pcm_hw_params_set_channels(self.pcm, self.hwparams, audio_format.channels)) rate = ctypes.c_uint(audio_format.sample_rate) dir = ctypes.c_int(0) check(asound.snd_pcm_hw_params_set_rate_near(self.pcm, self.hwparams, rate, dir)) # Note actual sample rate is in rate.value. Ignored for now because # difference is negligible. buffer_size = int(self._buffer_time * audio_format.sample_rate) bs = asound.snd_pcm_uframes_t(buffer_size) check(asound.snd_pcm_hw_params_set_buffer_size_near(self.pcm, self.hwparams, bs)) # Actual buffer size is in bs.value. Ignored for now. check(asound.snd_pcm_hw_params(self.pcm, self.hwparams)) if alsa_debug: asound.snd_output_printf(debug_output, 'New device: %s\n' % self._device_name) check(asound.snd_pcm_dump(self.pcm, debug_output)) self.can_pause = asound.snd_pcm_hw_params_can_pause(self.hwparams) # List of (alsatime, timestamp) self._timestamps = [] self._stop_alsatime = None self._eos_count = 0 self._playing = False