コード例 #1
0
    def load_sink(self):
        sink_name = 'PulseEffects'

        self.load_sink_info()

        if not self.sink_is_loaded:
            args = []

            sink_properties = 'device.description=\'PulseEffects\''
            sink_properties += 'device.class=\'sound\''

            args.append('sink_name=' + sink_name)
            args.append('sink_properties=' + sink_properties)
            args.append('channels=2')
            args.append('rate=' + str(self.default_sink_rate))

            argument = ' '.join(map(str, args)).encode('ascii')

            module = b'module-null-sink'

            def module_idx(context, idx, user_data):
                pass

            self.module_idx_cb = p.pa_context_index_cb_t(module_idx)

            o = p.pa_context_load_module(self.ctx, module, argument,
                                         self.module_idx_cb, None)

            while p.pa_operation_get_state(o) == p.PA_OPERATION_RUNNING:
                pass

            p.pa_operation_unref(o)

            self.load_sink_info()
コード例 #2
0
    def get_server_info(self):
        o = p.pa_context_get_server_info(self.ctx, self.server_info_cb, None)

        while p.pa_operation_get_state(o) == p.PA_OPERATION_RUNNING:
            pass

        p.pa_operation_unref(o)
コード例 #3
0
    def load_source_info(self, name):
        o = p.pa_context_get_source_info_by_name(self.ctx, name.encode(),
                                                 self.source_info_cb, None)

        while p.pa_operation_get_state(o) == p.PA_OPERATION_RUNNING:
            pass

        p.pa_operation_unref(o)
コード例 #4
0
    def load_sink_info(self):
        sink_name = 'PulseEffects'

        o = p.pa_context_get_sink_info_by_name(self.ctx, sink_name.encode(),
                                               self.sink_info_cb, None)

        while p.pa_operation_get_state(o) == p.PA_OPERATION_RUNNING:
            pass

        p.pa_operation_unref(o)
コード例 #5
0
    def get_server_info(self):
        p.pa_threaded_mainloop_lock(self.main_loop)

        o = p.pa_context_get_server_info(self.ctx, self.server_info_cb, None)

        while p.pa_operation_get_state(o) == p.PA_OPERATION_RUNNING:
            p.pa_threaded_mainloop_wait(self.main_loop)

        p.pa_operation_unref(o)

        p.pa_threaded_mainloop_unlock(self.main_loop)
コード例 #6
0
    def find_sources(self):
        p.pa_threaded_mainloop_lock(self.main_loop)

        o = p.pa_context_get_source_info_list(self.ctx, self.source_info_cb,
                                              1)  # 1 for new

        while p.pa_operation_get_state(o) == p.PA_OPERATION_RUNNING:
            p.pa_threaded_mainloop_wait(self.main_loop)

        p.pa_operation_unref(o)

        p.pa_threaded_mainloop_unlock(self.main_loop)
コード例 #7
0
    def load_source_info(self, name):
        p.pa_threaded_mainloop_lock(self.main_loop)

        o = p.pa_context_get_source_info_by_name(self.ctx, name.encode(),
                                                 self.source_info_cb, None)

        while p.pa_operation_get_state(o) == p.PA_OPERATION_RUNNING:
            p.pa_threaded_mainloop_wait(self.main_loop)

        p.pa_operation_unref(o)

        p.pa_threaded_mainloop_unlock(self.main_loop)
コード例 #8
0
    def unload_module(self, module):
        user_data = p.ctx_success_cb_data()

        user_data.operation = 'unload_module'.encode('utf-8')

        p.pa_threaded_mainloop_lock(self.main_loop)

        o = p.pa_context_unload_module(self.ctx, module, self.ctx_success_cb,
                                       p.get_ref(user_data))

        while p.pa_operation_get_state(o) == p.PA_OPERATION_RUNNING:
            p.pa_threaded_mainloop_wait(self.main_loop)

        p.pa_operation_unref(o)

        p.pa_threaded_mainloop_unlock(self.main_loop)
コード例 #9
0
    def drain_ctx(self):
        o = p.pa_context_drain(self.ctx, self.ctx_drain_notify_cb, None)

        if o:
            p.pa_threaded_mainloop_lock(self.main_loop)

            while p.pa_operation_get_state(o) == p.PA_OPERATION_RUNNING:
                p.pa_threaded_mainloop_wait(self.main_loop)

            p.pa_threaded_mainloop_unlock(self.main_loop)

            self.log.debug(self.log_tag + 'drained pulseaudio context')

            p.pa_operation_unref(o)
        else:
            self.log.debug(self.log_tag + 'context is already drained')
コード例 #10
0
    def load_sink(self):
        sink_name = 'PulseEffects'

        self.load_sink_info()

        if not self.sink_is_loaded:
            self.log.info('loading Pulseeffects sink...')

            args = []

            sink_properties = 'device.description=\'PulseEffects\''
            sink_properties += 'device.class=\'sound\''

            args.append('sink_name=' + sink_name)
            args.append('sink_properties=' + sink_properties)
            args.append('channels=2')
            args.append('rate=' + str(self.default_sink_rate))

            argument = ' '.join(map(str, args)).encode('ascii')

            module = b'module-null-sink'

            def module_idx(context, idx, user_data):
                self.log.info('sink owner module index: ' + str(idx))

            self.module_idx_cb = p.pa_context_index_cb_t(module_idx)

            o = p.pa_context_load_module(self.ctx, module, argument,
                                         self.module_idx_cb, None)

            while p.pa_operation_get_state(o) == p.PA_OPERATION_RUNNING:
                pass

            p.pa_operation_unref(o)

            self.load_sink_info()

            if self.sink_is_loaded:
                self.log.info('Pulseeffects sink was successfully loaded')
                self.log.info('Pulseeffects sink index:' + str(self.sink_idx))
                self.log.info('Pulseeffects sink monitor name: ' +
                              self.sink_monitor_name +
                              '. We will process audio from this source.')
            else:
                self.log.critical('Could not load sink')
コード例 #11
0
    def load_sink(self, name, description, rate):
        self.sink_is_loaded = False

        self.load_sink_info(name)

        if not self.sink_is_loaded:
            args = []

            sink_properties = description
            sink_properties += 'device.class=\'sound\''

            args.append('sink_name=' + name)
            args.append('sink_properties=' + sink_properties)
            args.append('channels=2')
            args.append('rate=' + str(rate))

            argument = ' '.join(map(str, args)).encode('ascii')

            module = b'module-null-sink'

            def module_idx(context, idx, user_data):
                self.log.info('sink owner module index: ' + str(idx))

            self.module_idx_cb = p.pa_context_index_cb_t(module_idx)

            o = p.pa_context_load_module(self.ctx, module, argument,
                                         self.module_idx_cb, None)

            while p.pa_operation_get_state(o) == p.PA_OPERATION_RUNNING:
                pass

            p.pa_operation_unref(o)

            self.load_sink_info(name)

            if self.sink_is_loaded:
                return True
            else:
                return False
        else:
            return True
コード例 #12
0
    def load_sink(self, name, description, rate):
        self.sink_is_loaded = False

        self.load_sink_info(name)

        if not self.sink_is_loaded:
            args = []

            sink_properties = description
            sink_properties += 'device.class=\'sound\''

            args.append('sink_name=' + name)
            args.append('sink_properties=' + sink_properties)
            args.append('channels=2')
            args.append('rate=' + str(rate))

            argument = ' '.join(map(str, args)).encode('ascii')

            module = b'module-null-sink'

            p.pa_threaded_mainloop_lock(self.main_loop)

            o = p.pa_context_load_module(self.ctx, module, argument,
                                         self.module_idx_cb, None)

            while p.pa_operation_get_state(o) == p.PA_OPERATION_RUNNING:
                p.pa_threaded_mainloop_wait(self.main_loop)

            p.pa_operation_unref(o)

            p.pa_threaded_mainloop_unlock(self.main_loop)

            self.load_sink_info(name)  # checking if sink was loaded

            if self.sink_is_loaded:
                return True
            else:
                return False
        else:
            return True
コード例 #13
0
    def __init__(self):
        GObject.GObject.__init__(self)

        self.context_ok = False
        self.default_sink_name = ''
        self.sink_is_loaded = False
        self.sink_owner_module = -1
        self.sink_idx = -1
        self.sink_monitor_name = ''
        self.sink_inputs = []
        self.max_volume = p.PA_VOLUME_NORM

        self.log = logging.getLogger('PulseEffects')

        self.app_blacklist = [
            'PulseEffects', 'pulseeffects', 'gsd-media-keys', 'GNOME Shell',
            'libcanberra', 'gnome-pomodoro'
        ]

        self.media_blacklist = ['pulsesink probe']

        # wrapping callbacks
        self.ctx_cb = p.pa_context_notify_cb_t(self.context_status)
        self.server_info_cb = p.pa_server_info_cb_t(self.server_info)
        self.default_sink_info_cb = p.pa_sink_info_cb_t(self.default_sink_info)
        self.sink_info_cb = p.pa_sink_info_cb_t(self.sink_info)
        self.sink_input_info_cb = p.pa_sink_input_info_cb_t(
            self.sink_input_info)
        self.ctx_success_cb = p.pa_context_success_cb_t(self.ctx_success)
        self.subscribe_cb = p.pa_context_subscribe_cb_t(self.subscribe)

        # creating main loop and context
        self.main_loop = p.pa_threaded_mainloop_new()
        self.main_loop_api = p.pa_threaded_mainloop_get_api(self.main_loop)

        self.ctx = p.pa_context_new(self.main_loop_api, b'PulseEffects')

        p.pa_context_set_state_callback(self.ctx, self.ctx_cb, None)

        p.pa_context_connect(self.ctx, None, 0, None)

        p.pa_threaded_mainloop_start(self.main_loop)

        # waiting context

        while self.context_ok is False:
            pass

        # getting default sink name through server info

        o = p.pa_context_get_server_info(self.ctx, self.server_info_cb, None)

        while p.pa_operation_get_state(o) == p.PA_OPERATION_RUNNING:
            pass

        p.pa_operation_unref(o)

        self.log.info('default pulseaudio sink: ' + self.default_sink_name)

        # getting default sink rate through sink info. We set
        # module-null-sink to the same rate to reduce clock drift

        o = p.pa_context_get_sink_info_by_name(self.ctx,
                                               self.default_sink_name.encode(),
                                               self.default_sink_info_cb, None)

        while p.pa_operation_get_state(o) == p.PA_OPERATION_RUNNING:
            pass

        p.pa_operation_unref(o)

        self.log.info('default pulseaudio sink audio format: ' +
                      str(self.default_sink_format) +
                      '. We will use the same format.')
        self.log.info('default pulseaudio sink sampling rate: ' +
                      str(self.default_sink_rate) +
                      ' Hz. We will use the same rate.')

        # load source sink
        self.load_sink()

        # search sink inputs
        o = p.pa_context_get_sink_input_info_list(self.ctx,
                                                  self.sink_input_info_cb,
                                                  None)

        while p.pa_operation_get_state(o) == p.PA_OPERATION_RUNNING:
            pass

        p.pa_operation_unref(o)

        # subscribing to pulseaudio events
        p.pa_context_set_subscribe_callback(self.ctx, self.subscribe_cb, None)

        p.pa_context_subscribe(self.ctx, p.PA_SUBSCRIPTION_MASK_SINK_INPUT,
                               self.ctx_success_cb, None)