예제 #1
0
 def play(self):
     if _debug:
         print('play')
     driver_listener.lock()
     driver_listener.async_operation(
         pa.pa_stream_cork(self.stream, 0, pa.pa_stream_success_cb_t(0),
                           None))
     if self._ended:
         driver_listener.async_operation(
             pa.pa_stream_trigger(self.stream, pa.pa_stream_success_cb_t(0),
                                  None))
     driver_listener.unlock()
예제 #2
0
    def play(self):
        if _debug:
            print "play"
        context.lock()
        context.async_operation(pa.pa_stream_cork(self.stream, 0, pa.pa_stream_success_cb_t(0), None))

        # If whole stream has already been written, trigger immediate
        # playback.
        if self._underflow_is_eos:
            context.async_operation(pa.pa_stream_trigger(self.stream, pa.pa_stream_success_cb_t(0), None))
        context.unlock()

        self._playing = True
예제 #3
0
파일: pulse.py 프로젝트: bitcraft/pyglet
 def play(self):
     if _debug:
         print('play')
     driver_listener.lock()
     driver_listener.async_operation(
         pa.pa_stream_cork(self.stream, 0,
                           pa.pa_stream_success_cb_t(0), None)
     )
     if self._ended:
         driver_listener.async_operation(
             pa.pa_stream_trigger(self.stream,
                                  pa.pa_stream_success_cb_t(0), None)
         )
     driver_listener.unlock()
예제 #4
0
    def play(self):
        if _debug:
            print 'play'
        context.lock()
        context.async_operation(
            pa.pa_stream_cork(self.stream, 0, pa.pa_stream_success_cb_t(0),
                              None))

        # If whole stream has already been written, trigger immediate
        # playback.
        if self._underflow_is_eos:
            context.async_operation(
                pa.pa_stream_trigger(self.stream, pa.pa_stream_success_cb_t(0),
                                     None))
        context.unlock()

        self._playing = True
예제 #5
0
 def stop(self):
     if _debug:
         print('stop')
     driver_listener.lock()
     driver_listener.async_operation(
         pa.pa_stream_cork(self.stream, 1, pa.pa_stream_success_cb_t(0),
                           None))
     driver_listener.unlock()
예제 #6
0
    def stop(self):
        if _debug:
            print "stop"
        context.lock()
        context.async_operation(pa.pa_stream_cork(self.stream, 1, pa.pa_stream_success_cb_t(0), None))
        context.unlock()

        self._playing = False
예제 #7
0
파일: pulse.py 프로젝트: bitcraft/pyglet
 def stop(self):
     if _debug:
         print('stop')
     driver_listener.lock()
     driver_listener.async_operation(
         pa.pa_stream_cork(self.stream, 1,
                           pa.pa_stream_success_cb_t(0), None)
     )
     driver_listener.unlock()
예제 #8
0
    def stop(self):
        if _debug:
            print 'stop'
        with context.lock:
            context.async_operation(
                pa.pa_stream_cork(self.stream, 1, pa.pa_stream_success_cb_t(0),
                                  None))

        self._playing = False
예제 #9
0
    def stop(self):
        if _debug:
            print 'stop'
        with context.lock:
            context.async_operation(
                    pa.pa_stream_cork(self.stream, 1,
                                pa.pa_stream_success_cb_t(0), None)
            )

        self._playing = False
예제 #10
0
    def play(self):
        if _debug:
            print 'play'
        with context.lock:
            context.async_operation(
                pa.pa_stream_cork(self.stream, 0,
                                pa.pa_stream_success_cb_t(0), None)
            )

            # If whole stream has already been written, trigger immediate
            # playback.        
            if self._underflow_is_eos:
                context.async_operation(
                    pa.pa_stream_trigger(self.stream, 
                                        pa.pa_stream_success_cb_t(0), None)
                )

            if self._buffer_underflow:
                self._write_cb(self.stream, None, None)

        self._playing = True
예제 #11
0
    def _write_cb(self, stream, bytes, data):
        if _debug:
            print 'write callback: %d bytes' % bytes

        # Asynchronously update time
        if self._events:
            context.async_operation(
                pa.pa_stream_update_timing_info(self.stream, 
                                                self._success_cb_func, None)
            )

        # Grab next audio packet, or leftovers from last callback.
        if self._buffered_audio_data:
            audio_data = self._buffered_audio_data
            self._buffered_audio_data = None
        else:
            audio_data = self.source_group.get_audio_data(bytes)

        seek_flag = pa.PA_SEEK_RELATIVE
        if self._clear_write:
            if _debug:
                print 'seek PA_SEEK_RELATIVE_ON_READ'
            seek_flag = pa.PA_SEEK_RELATIVE_ON_READ
            self._clear_write = False

        # Keep writing packets until `bytes` is depleted
        while audio_data and bytes > 0:
            if _debug:
                print 'packet', audio_data.timestamp
            if _debug and audio_data.events:
                print 'events', audio_data.events
            for event in audio_data.events:
                event_index = self._write_index + event.timestamp * \
                    self.source_group.audio_format.bytes_per_second
                self._events.append((event_index, event))

            consumption = min(bytes, audio_data.length)
            
            check(
                pa.pa_stream_write(self.stream,
                                   audio_data.data,
                                   consumption,
                                   pa.pa_free_cb_t(0),  # Data is copied
                                   0,
                                   seek_flag)
            )

            seek_flag = pa.PA_SEEK_RELATIVE
            self._read_index_valid = True
            self._timestamps.append((self._write_index, audio_data.timestamp))
            self._write_index += consumption
            self._underflow_is_eos = False

            if _debug:
                print 'write', consumption
            if consumption < audio_data.length:
                audio_data.consume(consumption, self.source_group.audio_format)
                self._buffered_audio_data = audio_data
                break

            bytes -= consumption
            if bytes > 0:
                audio_data = self.source_group.get_audio_data(bytes) #XXX name change

        if not audio_data:
            # Whole source group has been written.  Any underflow encountered
            # after now is the EOS.
            self._underflow_is_eos = True
            
            # In case the source group wasn't long enough to prebuffer stream
            # to PA's satisfaction, trigger immediate playback (has no effect
            # if stream is already playing).
            if self._playing:
                context.async_operation(
                     pa.pa_stream_trigger(self.stream, 
                                          pa.pa_stream_success_cb_t(0), None)
                )

        self._process_events()
예제 #12
0
    def __init__(self, source_group, player):
        super(PulseAudioPlayer, self).__init__(source_group, player)

        self._events = []
        self._timestamps = []  # List of (ref_time, timestamp)
        self._write_index = 0  # Current write index (tracked manually)
        self._read_index_valid = False # True only if buffer has non-stale data

        self._clear_write = False
        self._buffered_audio_data = None
        self._underflow_is_eos = False
        self._playing = False

        audio_format = source_group.audio_format
        assert audio_format

        # Create sample_spec
        sample_spec = pa.pa_sample_spec()
        if audio_format.sample_size == 8:
            sample_spec.format = pa.PA_SAMPLE_U8
        elif audio_format.sample_size == 16:
            if sys.byteorder == 'little':
                sample_spec.format = pa.PA_SAMPLE_S16LE
            else:
                sample_spec.format = pa.PA_SAMPLE_S16BE
        else:
            raise MediaException('Unsupported sample size')
        sample_spec.rate = audio_format.sample_rate
        sample_spec.channels = audio_format.channels
        channel_map = None

        try:
            context.lock()
            # Create stream
            self.stream = pa.pa_stream_new(context._context, 
                                           str(id(self)),
                                           sample_spec,
                                           channel_map)
            check_not_null(self.stream)

            # Callback trampoline for success operations
            self._success_cb_func = pa.pa_stream_success_cb_t(self._success_cb)
            self._context_success_cb_func = \
                pa.pa_context_success_cb_t(self._context_success_cb)

            # Callback for underflow (to detect EOS when expected pa_timestamp
            # does not get reached).
            self._underflow_cb_func = \
                pa.pa_stream_notify_cb_t(self._underflow_cb)
            pa.pa_stream_set_underflow_callback(self.stream,
                                                self._underflow_cb_func, None)

            # Callback for data write
            self._write_cb_func = pa.pa_stream_request_cb_t(self._write_cb)
            pa.pa_stream_set_write_callback(self.stream,
                                            self._write_cb_func, None)

            # Connect to sink
            device = None
            buffer_attr = None
            flags = (pa.PA_STREAM_START_CORKED |
                     pa.PA_STREAM_INTERPOLATE_TIMING)

            sync_stream = None  # TODO use this
            check(
                pa.pa_stream_connect_playback(self.stream, 
                                              device,
                                              buffer_attr, 
                                              flags,
                                              None, 
                                              sync_stream)
            )

            # Wait for stream readiness
            self._state_cb_func = pa.pa_stream_notify_cb_t(self._state_cb)
            pa.pa_stream_set_state_callback(self.stream, 
                                            self._state_cb_func, None)
            while pa.pa_stream_get_state(self.stream) == pa.PA_STREAM_CREATING:
                context.wait()

            if pa.pa_stream_get_state(self.stream) != pa.PA_STREAM_READY:
                check(-1)
        finally:
            context.unlock()

        self.set_volume(self._volume)

        if _debug:
            print 'stream ready'
예제 #13
0
    def _write_cb(self, stream, bytes, data):
        if _debug:
            print 'write callback: %d bytes' % bytes

        # Asynchronously update time
        if self._events:
            context.async_operation(
                pa.pa_stream_update_timing_info(self.stream,
                                                self._success_cb_func, None))

        # Grab next audio packet, or leftovers from last callback.
        if self._buffered_audio_data:
            audio_data = self._buffered_audio_data
            self._buffered_audio_data = None
        else:
            audio_data = self.source_group.get_audio_data(bytes)

        seek_flag = pa.PA_SEEK_RELATIVE
        if self._clear_write:
            if _debug:
                print 'seek PA_SEEK_RELATIVE_ON_READ'
            seek_flag = pa.PA_SEEK_RELATIVE_ON_READ
            self._clear_write = False

        # Keep writing packets until `bytes` is depleted
        while audio_data and bytes > 0:
            if _debug:
                print 'packet', audio_data.timestamp
            if _debug and audio_data.events:
                print 'events', audio_data.events
            for event in audio_data.events:
                event_index = self._write_index + event.timestamp * \
                    self.source_group.audio_format.bytes_per_second
                self._events.append((event_index, event))

            consumption = min(bytes, audio_data.length)

            check(
                pa.pa_stream_write(
                    self.stream,
                    audio_data.data,
                    consumption,
                    pa.pa_free_cb_t(0),  # Data is copied
                    0,
                    seek_flag))

            seek_flag = pa.PA_SEEK_RELATIVE
            self._read_index_valid = True
            self._timestamps.append((self._write_index, audio_data.timestamp))
            self._write_index += consumption
            self._underflow_is_eos = False

            if _debug:
                print 'write', consumption
            if consumption < audio_data.length:
                audio_data.consume(consumption, self.source_group.audio_format)
                self._buffered_audio_data = audio_data
                break

            bytes -= consumption
            if bytes > 0:
                audio_data = self.source_group.get_audio_data(
                    bytes)  #XXX name change

        if not audio_data:
            # Whole source group has been written.  Any underflow encountered
            # after now is the EOS.
            self._underflow_is_eos = True

            # In case the source group wasn't long enough to prebuffer stream
            # to PA's satisfaction, trigger immediate playback (has no effect
            # if stream is already playing).
            if self._playing:
                context.async_operation(
                    pa.pa_stream_trigger(self.stream,
                                         pa.pa_stream_success_cb_t(0), None))

        self._process_events()
예제 #14
0
    def __init__(self, source_group, player):
        super(PulseAudioPlayer, self).__init__(source_group, player)

        self._events = []
        self._timestamps = []  # List of (ref_time, timestamp)
        self._write_index = 0  # Current write index (tracked manually)
        self._read_index_valid = False  # True only if buffer has non-stale data

        self._clear_write = False
        self._buffered_audio_data = None
        self._underflow_is_eos = False
        self._playing = False

        audio_format = source_group.audio_format
        assert audio_format

        # Create sample_spec
        sample_spec = pa.pa_sample_spec()
        if audio_format.sample_size == 8:
            sample_spec.format = pa.PA_SAMPLE_U8
        elif audio_format.sample_size == 16:
            if sys.byteorder == 'little':
                sample_spec.format = pa.PA_SAMPLE_S16LE
            else:
                sample_spec.format = pa.PA_SAMPLE_S16BE
        else:
            raise MediaException('Unsupported sample size')
        sample_spec.rate = audio_format.sample_rate
        sample_spec.channels = audio_format.channels
        channel_map = None
        self.sample_rate = audio_format.sample_rate

        try:
            context.lock()
            # Create stream
            self.stream = pa.pa_stream_new(context._context, str(id(self)),
                                           sample_spec, channel_map)
            check_not_null(self.stream)

            # Callback trampoline for success operations
            self._success_cb_func = pa.pa_stream_success_cb_t(self._success_cb)
            self._context_success_cb_func = \
                pa.pa_context_success_cb_t(self._context_success_cb)

            # Callback for underflow (to detect EOS when expected pa_timestamp
            # does not get reached).
            self._underflow_cb_func = \
                pa.pa_stream_notify_cb_t(self._underflow_cb)
            pa.pa_stream_set_underflow_callback(self.stream,
                                                self._underflow_cb_func, None)

            # Callback for data write
            self._write_cb_func = pa.pa_stream_request_cb_t(self._write_cb)
            pa.pa_stream_set_write_callback(self.stream, self._write_cb_func,
                                            None)

            # Connect to sink
            device = None
            buffer_attr = None
            flags = (pa.PA_STREAM_START_CORKED
                     | pa.PA_STREAM_INTERPOLATE_TIMING
                     | pa.PA_STREAM_VARIABLE_RATE)

            sync_stream = None  # TODO use this
            check(
                pa.pa_stream_connect_playback(self.stream, device, buffer_attr,
                                              flags, None, sync_stream))

            # Wait for stream readiness
            self._state_cb_func = pa.pa_stream_notify_cb_t(self._state_cb)
            pa.pa_stream_set_state_callback(self.stream, self._state_cb_func,
                                            None)
            while pa.pa_stream_get_state(self.stream) == pa.PA_STREAM_CREATING:
                context.wait()

            if pa.pa_stream_get_state(self.stream) != pa.PA_STREAM_READY:
                check(-1)
        finally:
            context.unlock()

        self.set_volume(self._volume)

        if _debug:
            print 'stream ready'
예제 #15
0
파일: pulse.py 프로젝트: bitcraft/pyglet
    def __init__(self, audio_format):
        super().__init__(audio_format)

        sample_spec = pa.pa_sample_spec()
        if audio_format.sample_size == 8:
            sample_spec.format = pa.PA_SAMPLE_U8
        elif audio_format.sample_size == 16:
            if sys.byteorder == 'little':
                sample_spec.format = pa.PA_SAMPLE_S16LE
            else:
                sample_spec.format = pa.PA_SAMPLE_S16BE
        else:
            raise MediaException('Unsupported sample size')
        sample_spec.rate = audio_format.sample_rate
        sample_spec.channels = audio_format.channels
        channel_map = None

        device = None
        buffer_attr = None
        flags = (pa.PA_STREAM_START_CORKED |
                 pa.PA_STREAM_INTERPOLATE_TIMING)
        volume = None

        # TODO should expose sync_stream, since soundspace example sounds
        # noticeably out of sync with PA.
        sync_stream = None

        try:
            driver_listener.lock()
            self.stream = pa.pa_stream_new(context,
                                           str(id(self)),
                                           sample_spec,
                                           channel_map)
            check_not_null(self.stream)
            check(
                pa.pa_stream_connect_playback(self.stream,
                                              device,
                                              buffer_attr,
                                              flags,
                                              volume,
                                              sync_stream)
            )
        finally:
            driver_listener.unlock()

        self._timestamps = list()  # List of (pa_time, timestamp)
        self._write_time = 0.0
        self._timestamp = 0.0
        self._timestamp_pa_time = 0.0
        self._eos_count = 0
        self._ended = False
        self._ended_underflowed = False

        # Callback trampoline for success operations
        self._success_cb_func = pa.pa_stream_success_cb_t(self._success_cb)

        # Callback for underflow (to detect EOS when expected pa_timestamp
        # does not get reached).
        self._underflow_cb_func = pa.pa_stream_notify_cb_t(self._underflow_cb)
        pa.pa_stream_set_underflow_callback(self.stream,
                                            self._underflow_cb_func, None)

        # Wait for stream readiness
        self._state_cb_func = pa.pa_stream_notify_cb_t(self._state_cb)
        pa.pa_stream_set_state_callback(self.stream, self._state_cb_func, None)
        driver_listener.lock()
        while pa.pa_stream_get_state(self.stream) == pa.PA_STREAM_CREATING:
            driver_listener.wait()
        driver_listener.unlock()

        if _debug:
            print('stream ready')
예제 #16
0
    def __init__(self, audio_format):
        super().__init__(audio_format)

        sample_spec = pa.pa_sample_spec()
        if audio_format.sample_size == 8:
            sample_spec.format = pa.PA_SAMPLE_U8
        elif audio_format.sample_size == 16:
            if sys.byteorder == 'little':
                sample_spec.format = pa.PA_SAMPLE_S16LE
            else:
                sample_spec.format = pa.PA_SAMPLE_S16BE
        else:
            raise MediaException('Unsupported sample size')
        sample_spec.rate = audio_format.sample_rate
        sample_spec.channels = audio_format.channels
        channel_map = None

        device = None
        buffer_attr = None
        flags = (pa.PA_STREAM_START_CORKED | pa.PA_STREAM_INTERPOLATE_TIMING)
        volume = None

        # TODO should expose sync_stream, since soundspace example sounds
        # noticeably out of sync with PA.
        sync_stream = None

        try:
            driver_listener.lock()
            self.stream = pa.pa_stream_new(context, str(id(self)), sample_spec,
                                           channel_map)
            check_not_null(self.stream)
            check(
                pa.pa_stream_connect_playback(self.stream, device, buffer_attr,
                                              flags, volume, sync_stream))
        finally:
            driver_listener.unlock()

        self._timestamps = list()  # List of (pa_time, timestamp)
        self._write_time = 0.0
        self._timestamp = 0.0
        self._timestamp_pa_time = 0.0
        self._eos_count = 0
        self._ended = False
        self._ended_underflowed = False

        # Callback trampoline for success operations
        self._success_cb_func = pa.pa_stream_success_cb_t(self._success_cb)

        # Callback for underflow (to detect EOS when expected pa_timestamp
        # does not get reached).
        self._underflow_cb_func = pa.pa_stream_notify_cb_t(self._underflow_cb)
        pa.pa_stream_set_underflow_callback(self.stream,
                                            self._underflow_cb_func, None)

        # Wait for stream readiness
        self._state_cb_func = pa.pa_stream_notify_cb_t(self._state_cb)
        pa.pa_stream_set_state_callback(self.stream, self._state_cb_func, None)
        driver_listener.lock()
        while pa.pa_stream_get_state(self.stream) == pa.PA_STREAM_CREATING:
            driver_listener.wait()
        driver_listener.unlock()

        if _debug:
            print('stream ready')