def ctx_notify_cb(self, ctx, user_data):
        state = p.pa_context_get_state(ctx)

        if state == p.PA_CONTEXT_UNCONNECTED:
            self.log.debug(self.log_tag + 'pulseaudio context is unconnected')
        elif state == p.PA_CONTEXT_CONNECTING:
            self.log.debug(self.log_tag + 'pulseaudio context is connecting')
        elif state == p.PA_CONTEXT_AUTHORIZING:
            self.log.debug(self.log_tag + 'pulseaudio context is authorizing')
        elif state == p.PA_CONTEXT_SETTING_NAME:
            self.log.debug(self.log_tag + 'pulseaudio context is setting name')
        elif state == p.PA_CONTEXT_READY:
            self.log.debug(self.log_tag + 'pulseaudio context is ready')
            self.log.debug(self.log_tag + 'connected to server: ' +
                           p.pa_context_get_server(ctx).decode())
            self.log.debug(self.log_tag + 'server protocol version: ' +
                           str(p.pa_context_get_server_protocol_version(ctx)))

            p.pa_context_set_subscribe_callback(ctx, self.subscribe_cb, None)

            # subscribing to pulseaudio events

            subscription_mask = p.PA_SUBSCRIPTION_MASK_SINK_INPUT + \
                p.PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT + \
                p.PA_SUBSCRIPTION_MASK_SOURCE + \
                p.PA_SUBSCRIPTION_MASK_SINK + \
                p.PA_SUBSCRIPTION_MASK_SERVER

            udata = p.ctx_success_cb_data()

            udata.operation = 'subscribe'.encode('utf-8')

            p.pa_context_subscribe(ctx, subscription_mask, self.ctx_success_cb,
                                   p.get_ref(udata))

            self.event_ctx_ready.set()

        elif state == p.PA_CONTEXT_FAILED:
            self.log.critical(self.log_tag +
                              'failed to start pulseaudio context')
            self.log.critical(self.log_tag +
                              'unferencing pulseaudio context object')

            p.pa_context_unref(ctx)

        elif state == p.PA_CONTEXT_TERMINATED:
            self.log.debug(self.log_tag + 'pulseaudio context terminated')

            self.event_ctx_terminated.set()
    def exit(self):
        self.unload_sinks()

        self.log.info('sinks unloaded')

        self.log.info('disconnecting pulseaudio context')
        p.pa_context_disconnect(self.ctx)

        self.log.info('stopping pulseaudio threaded main loop')
        p.pa_threaded_mainloop_stop(self.main_loop)

        self.log.info('unferencing pulseaudio context object')
        p.pa_context_unref(self.ctx)

        self.log.info('freeing pulseaudio main loop object')
        p.pa_threaded_mainloop_free(self.main_loop)
    def exit(self):
        self.unload_sinks()
        self.log.debug(self.log_tag + 'sinks unloaded')

        self.drain_ctx()

        self.log.debug(self.log_tag + 'disconnecting pulseaudio context')
        p.pa_context_disconnect(self.ctx)

        self.event_ctx_terminated.wait()

        self.log.debug(self.log_tag + 'unferencing pulseaudio context object')
        p.pa_context_unref(self.ctx)

        self.log.debug(self.log_tag + 'stopping pulseaudio threaded main loop')
        p.pa_threaded_mainloop_stop(self.main_loop)

        self.log.debug(self.log_tag + 'freeing pulseaudio main loop object')
        p.pa_threaded_mainloop_free(self.main_loop)
    def context_notify(self, ctx, user_data):
        state = p.pa_context_get_state(ctx)

        if state == p.PA_CONTEXT_READY:
            self.log.info('pulseaudio context started')
            self.log.info('connected to server: ' +
                          p.pa_context_get_server(ctx).decode())
            self.log.info('server protocol version: ' +
                          str(p.pa_context_get_server_protocol_version(ctx)))

            p.pa_context_set_subscribe_callback(self.ctx, self.subscribe_cb,
                                                None)

            # subscribing to pulseaudio events

            subscription_mask = p.PA_SUBSCRIPTION_MASK_SINK_INPUT + \
                p.PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT + \
                p.PA_SUBSCRIPTION_MASK_SOURCE + \
                p.PA_SUBSCRIPTION_MASK_SERVER

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

            self.context_ok = True

        elif state == p.PA_CONTEXT_FAILED:
            self.log.critical('failed to start pulseaudio context')
            self.log.info('unferencing pulseaudio context object')
            p.pa_context_unref(self.ctx)

        elif state == p.PA_CONTEXT_TERMINATED:
            self.log.info('pulseaudio context terminated')

            self.log.info('unferencing pulseaudio context object')
            p.pa_context_unref(self.ctx)

            self.context_ok = False