def __init__(self, sampling_rate):
        PipelineBase.__init__(self, sampling_rate)

        self.module_path = os.path.dirname(__file__)

        self.log_tag = 'apps: '

        self.settings = Gio.Settings('com.github.wwmm.pulseeffects.sinkinputs')

        self.builder = Gtk.Builder()

        self.builder.add_from_file(self.module_path + '/ui/effects_box.glade')

        self.ui_window = self.builder.get_object('window')

        self.stack = self.builder.get_object('stack')

        self.limiter = Limiter(self.settings)
        self.panorama = Panorama(self.settings)
        self.compressor = Compressor(self.settings)
        self.reverb = Reverb(self.settings)
        self.highpass = Highpass(self.settings)
        self.lowpass = Lowpass(self.settings)
        self.equalizer = Equalizer(self.settings)

        # adding effects widgets to the stack

        self.stack.add_titled(self.limiter.ui_window, 'Limiter',
                              _('Input Limiter'))
        self.stack.add_titled(self.panorama.ui_window, 'Panorama',
                              _('Panorama'))
        self.stack.add_titled(self.compressor.ui_window, 'Compressor',
                              _('Compressor'))
        self.stack.add_titled(self.reverb.ui_window, 'Reverb',
                              _('Reverberation'))
        self.stack.add_titled(self.highpass.ui_window, 'Highpass',
                              _('High pass'))
        self.stack.add_titled(self.lowpass.ui_window, 'Lowpass',
                              _('Low pass'))
        self.stack.add_titled(self.equalizer.ui_window, 'Equalizer',
                              _('Equalizer'))

        # on/off switches connections

        self.limiter.ui_limiter_enable.connect('state-set',
                                               self.on_limiter_enable)
        self.panorama.ui_panorama_enable.connect('state-set',
                                                 self.on_panorama_enable)
        self.compressor.ui_compressor_enable.connect('state-set',
                                                     self.on_compressor_enable)
        self.reverb.ui_reverb_enable.connect('state-set',
                                             self.on_reverb_enable)
        self.highpass.ui_highpass_enable.connect('state-set',
                                                 self.on_highpass_enable)
        self.lowpass.ui_lowpass_enable.connect('state-set',
                                               self.on_lowpass_enable)
        self.equalizer.ui_equalizer_enable.connect('state-set',
                                                   self.on_equalizer_enable)
    def __init__(self, sampling_rate):
        self.settings = Gio.Settings('com.github.wwmm.pulseeffects.sinkinputs')

        EffectsBase.__init__(self, sampling_rate, self.settings)

        self.log_tag = 'apps: '
        self.panorama_ready = False

        self.panorama = Panorama(self.settings)

        self.insert_in_listbox('panorama', 1)

        self.listbox.show_all()

        # adding effects widgets to the stack

        self.stack.add_named(self.limiter.ui_window, 'Limiter')
        self.stack.add_named(self.panorama.ui_window, 'Panorama')
        self.stack.add_named(self.compressor.ui_window, 'Compressor')
        self.stack.add_named(self.reverb.ui_window, 'Reverb')
        self.stack.add_named(self.highpass.ui_window, 'Highpass')
        self.stack.add_named(self.lowpass.ui_window, 'Lowpass')
        self.stack.add_named(self.equalizer.ui_window, 'Equalizer')

        # on/off switches connections
        self.panorama.ui_enable.connect('state-set', self.on_panorama_enable)
        self.compressor.ui_enable.connect('state-set',
                                          self.on_compressor_enable)
        self.reverb.ui_enable.connect('state-set', self.on_reverb_enable)
        self.highpass.ui_enable.connect('state-set', self.on_highpass_enable)
        self.lowpass.ui_enable.connect('state-set', self.on_lowpass_enable)
        self.equalizer.ui_enable.connect('state-set', self.on_equalizer_enable)

        # order of bind is important and may lead to load failure if
        # done otherwise

        if self.limiter.is_installed:
            self.limiter.bind()
        else:
            self.limiter.ui_window.set_sensitive(False)
            self.limiter.ui_limiter_enable.set_sensitive(False)

        if self.panorama.is_installed:
            self.panorama.bind()
        else:
            self.panorama.ui_window.set_sensitive(False)
            self.panorama.ui_enable.set_sensitive(False)

        if self.compressor.is_installed:
            self.compressor.bind()
        else:
            self.compressor.ui_window.set_sensitive(False)
            self.compressor.ui_enable.set_sensitive(False)

        self.reverb.bind()
        self.highpass.bind()
        self.lowpass.bind()
        self.equalizer.bind()
    def __init__(self, pulse_manager):
        self.pm = pulse_manager
        self.periodic_info_update = False

        EffectsBase.__init__(self, self.pm.default_sink_rate)

        self.log_tag = 'SIE - '

        pa_props = 'application.id=com.github.wwmm.pulseeffects.sinkinputs'

        self.set_pa_props(pa_props)

        self.set_source_monitor_name(self.pm.apps_sink_monitor_name)

        pulse_sink = os.environ.get('PULSE_SINK')

        if pulse_sink:
            self.set_output_sink_name(pulse_sink)

            self.log.debug('$PULSE_SINK = ' + pulse_sink)

            msg = 'user has $PULSE_SINK set. Using it as output device'

            self.log.debug(msg)
        else:
            self.set_output_sink_name(self.pm.default_sink_name)

        self.pm.connect('sink_input_added', self.on_app_added)
        self.pm.connect('sink_input_changed', self.on_app_changed)
        self.pm.connect('sink_input_removed', self.on_app_removed)
        self.pm.connect('stream_level_changed', self.on_stream_level_changed)

        self.exciter = Exciter()
        self.bass_enhancer = BassEnhancer()
        self.delay = Delay()
        self.stereo_enhancer = StereoEnhancer()
        self.stereo_spread = StereoSpread()
        self.crossfeed = Crossfeed()
        self.panorama = Panorama()
        self.maximizer = Maximizer()
        self.output_limiter = OutputLimiter()

        self.limiter.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.limiter')
        self.panorama.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.panorama')
        self.compressor.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.compressor')
        self.reverb.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.reverb')
        self.highpass.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.highpass')
        self.lowpass.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.lowpass')
        self.equalizer.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.equalizer')
        self.exciter.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.exciter')
        self.bass_enhancer.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.bassenhancer')
        self.delay.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.delay')
        self.stereo_enhancer.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.stereoenhancer')
        self.stereo_spread.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.stereospread')
        self.crossfeed.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.crossfeed')
        self.maximizer.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.maximizer')
        self.output_limiter.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.outputlimiter')

        # effects wrappers
        self.exciter_wrapper = GstInsertBin.InsertBin.new('exciter_wrapper')
        self.bass_enhancer_wrapper = GstInsertBin.InsertBin.new(
            'bass_enhancer_wrapper')
        self.delay_wrapper = GstInsertBin.InsertBin.new('delay_wrapper')
        self.stereo_enhancer_wrapper = GstInsertBin.InsertBin.new(
            'stereo_enhancer_wrapper')
        self.stereo_spread_wrapper = GstInsertBin.InsertBin.new(
            'stereo_spread_wrapper')
        self.crossfeed_wrapper = GstInsertBin.InsertBin.new(
            'crossfeed_wrapper')
        self.panorama_wrapper = GstInsertBin.InsertBin.new('panorama_wrapper')
        self.maximizer_wrapper = GstInsertBin.InsertBin.new(
            'maximizer_wrapper')
        self.output_limiter_wrapper = GstInsertBin.InsertBin.new(
            'output_limiter_wrapper')

        # appending effects wrappers to effects bin
        # the effects order is defined here

        self.effects_bin.append(self.limiter_wrapper, self.on_filter_added,
                                None)
        self.effects_bin.append(self.compressor_wrapper, self.on_filter_added,
                                None)
        self.effects_bin.append(self.highpass_wrapper, self.on_filter_added,
                                None)
        self.effects_bin.append(self.lowpass_wrapper, self.on_filter_added,
                                None)
        self.effects_bin.append(self.equalizer_wrapper, self.on_filter_added,
                                None)
        self.effects_bin.append(self.bass_enhancer_wrapper,
                                self.on_filter_added, None)
        self.effects_bin.append(self.exciter_wrapper, self.on_filter_added,
                                None)
        self.effects_bin.append(self.stereo_enhancer_wrapper,
                                self.on_filter_added, None)
        self.effects_bin.append(self.panorama_wrapper, self.on_filter_added,
                                None)
        self.effects_bin.append(self.stereo_spread_wrapper,
                                self.on_filter_added, None)
        self.effects_bin.append(self.reverb_wrapper, self.on_filter_added,
                                None)
        self.effects_bin.append(self.crossfeed_wrapper, self.on_filter_added,
                                None)
        self.effects_bin.append(self.delay_wrapper, self.on_filter_added, None)
        self.effects_bin.append(self.maximizer_wrapper, self.on_filter_added,
                                None)
        self.effects_bin.append(self.output_limiter_wrapper,
                                self.on_filter_added, None)
        self.effects_bin.append(self.spectrum_wrapper, self.on_filter_added,
                                None)
class SinkInputEffects(EffectsBase):
    def __init__(self, pulse_manager):
        self.pm = pulse_manager
        self.periodic_info_update = False

        EffectsBase.__init__(self, self.pm.default_sink_rate)

        self.log_tag = 'SIE - '

        pa_props = 'application.id=com.github.wwmm.pulseeffects.sinkinputs'

        self.set_pa_props(pa_props)

        self.set_source_monitor_name(self.pm.apps_sink_monitor_name)

        pulse_sink = os.environ.get('PULSE_SINK')

        if pulse_sink:
            self.set_output_sink_name(pulse_sink)

            self.log.debug('$PULSE_SINK = ' + pulse_sink)

            msg = 'user has $PULSE_SINK set. Using it as output device'

            self.log.debug(msg)
        else:
            self.set_output_sink_name(self.pm.default_sink_name)

        self.pm.connect('sink_input_added', self.on_app_added)
        self.pm.connect('sink_input_changed', self.on_app_changed)
        self.pm.connect('sink_input_removed', self.on_app_removed)
        self.pm.connect('stream_level_changed', self.on_stream_level_changed)

        self.exciter = Exciter()
        self.bass_enhancer = BassEnhancer()
        self.delay = Delay()
        self.stereo_enhancer = StereoEnhancer()
        self.stereo_spread = StereoSpread()
        self.crossfeed = Crossfeed()
        self.panorama = Panorama()
        self.maximizer = Maximizer()
        self.output_limiter = OutputLimiter()

        self.limiter.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.limiter')
        self.panorama.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.panorama')
        self.compressor.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.compressor')
        self.reverb.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.reverb')
        self.highpass.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.highpass')
        self.lowpass.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.lowpass')
        self.equalizer.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.equalizer')
        self.exciter.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.exciter')
        self.bass_enhancer.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.bassenhancer')
        self.delay.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.delay')
        self.stereo_enhancer.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.stereoenhancer')
        self.stereo_spread.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.stereospread')
        self.crossfeed.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.crossfeed')
        self.maximizer.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.maximizer')
        self.output_limiter.settings = Gio.Settings(
            'com.github.wwmm.pulseeffects.sinkinputs.outputlimiter')

        # effects wrappers
        self.exciter_wrapper = GstInsertBin.InsertBin.new('exciter_wrapper')
        self.bass_enhancer_wrapper = GstInsertBin.InsertBin.new(
            'bass_enhancer_wrapper')
        self.delay_wrapper = GstInsertBin.InsertBin.new('delay_wrapper')
        self.stereo_enhancer_wrapper = GstInsertBin.InsertBin.new(
            'stereo_enhancer_wrapper')
        self.stereo_spread_wrapper = GstInsertBin.InsertBin.new(
            'stereo_spread_wrapper')
        self.crossfeed_wrapper = GstInsertBin.InsertBin.new(
            'crossfeed_wrapper')
        self.panorama_wrapper = GstInsertBin.InsertBin.new('panorama_wrapper')
        self.maximizer_wrapper = GstInsertBin.InsertBin.new(
            'maximizer_wrapper')
        self.output_limiter_wrapper = GstInsertBin.InsertBin.new(
            'output_limiter_wrapper')

        # appending effects wrappers to effects bin
        # the effects order is defined here

        self.effects_bin.append(self.limiter_wrapper, self.on_filter_added,
                                None)
        self.effects_bin.append(self.compressor_wrapper, self.on_filter_added,
                                None)
        self.effects_bin.append(self.highpass_wrapper, self.on_filter_added,
                                None)
        self.effects_bin.append(self.lowpass_wrapper, self.on_filter_added,
                                None)
        self.effects_bin.append(self.equalizer_wrapper, self.on_filter_added,
                                None)
        self.effects_bin.append(self.bass_enhancer_wrapper,
                                self.on_filter_added, None)
        self.effects_bin.append(self.exciter_wrapper, self.on_filter_added,
                                None)
        self.effects_bin.append(self.stereo_enhancer_wrapper,
                                self.on_filter_added, None)
        self.effects_bin.append(self.panorama_wrapper, self.on_filter_added,
                                None)
        self.effects_bin.append(self.stereo_spread_wrapper,
                                self.on_filter_added, None)
        self.effects_bin.append(self.reverb_wrapper, self.on_filter_added,
                                None)
        self.effects_bin.append(self.crossfeed_wrapper, self.on_filter_added,
                                None)
        self.effects_bin.append(self.delay_wrapper, self.on_filter_added, None)
        self.effects_bin.append(self.maximizer_wrapper, self.on_filter_added,
                                None)
        self.effects_bin.append(self.output_limiter_wrapper,
                                self.on_filter_added, None)
        self.effects_bin.append(self.spectrum_wrapper, self.on_filter_added,
                                None)

    def init_ui(self):
        EffectsBase.init_ui(self)

        self.limiter.init_ui()
        self.compressor.init_ui()
        self.highpass.init_ui()
        self.lowpass.init_ui()
        self.equalizer.init_ui()
        self.bass_enhancer.init_ui()
        self.exciter.init_ui()
        self.delay.init_ui()
        self.stereo_enhancer.init_ui()
        self.stereo_spread.init_ui()
        self.crossfeed.init_ui()
        self.reverb.init_ui()
        self.panorama.init_ui()
        self.maximizer.init_ui()
        self.output_limiter.init_ui()

        self.add_to_listbox('limiter')
        self.add_to_listbox('compressor')
        self.add_to_listbox('highpass')
        self.add_to_listbox('lowpass')
        self.add_to_listbox('equalizer')
        self.add_to_listbox('bass_enhancer')
        self.add_to_listbox('exciter')
        self.add_to_listbox('stereo_enhancer')
        self.add_to_listbox('panorama')
        self.add_to_listbox('stereo_spread')
        self.add_to_listbox('reverb')
        self.add_to_listbox('crossfeed')
        self.add_to_listbox('delay')
        self.add_to_listbox('maximizer')
        self.add_to_listbox('output_limiter')

        self.listbox.show_all()

        # adding effects widgets to the stack

        self.stack.add_named(self.limiter.ui_window, 'limiter')
        self.stack.add_named(self.compressor.ui_window, 'compressor')
        self.stack.add_named(self.highpass.ui_window, 'highpass')
        self.stack.add_named(self.lowpass.ui_window, 'lowpass')
        self.stack.add_named(self.equalizer.ui_window, 'equalizer')
        self.stack.add_named(self.bass_enhancer.ui_window, 'bass_enhancer')
        self.stack.add_named(self.exciter.ui_window, 'exciter')
        self.stack.add_named(self.stereo_enhancer.ui_window, 'stereo_enhancer')
        self.stack.add_named(self.panorama.ui_window, 'panorama')
        self.stack.add_named(self.stereo_spread.ui_window, 'stereo_spread')
        self.stack.add_named(self.reverb.ui_window, 'reverb')
        self.stack.add_named(self.crossfeed.ui_window, 'crossfeed')
        self.stack.add_named(self.delay.ui_window, 'delay')
        self.stack.add_named(self.maximizer.ui_window, 'maximizer')
        self.stack.add_named(self.output_limiter.ui_window, 'output_limiter')

        # on/off switches connections
        self.limiter.ui_limiter_enable.connect('state-set',
                                               self.on_limiter_enable)
        self.compressor.ui_enable.connect('state-set',
                                          self.on_compressor_enable)
        self.highpass.ui_enable.connect('state-set', self.on_highpass_enable)
        self.lowpass.ui_enable.connect('state-set', self.on_lowpass_enable)
        self.equalizer.ui_enable.connect('state-set', self.on_equalizer_enable)
        self.exciter.ui_enable.connect('state-set', self.on_exciter_enable)
        self.bass_enhancer.ui_enable.connect('state-set',
                                             self.on_bass_enhancer_enable)
        self.delay.ui_enable.connect('state-set', self.on_delay_enable)
        self.stereo_enhancer.ui_enable.connect('state-set',
                                               self.on_stereo_enhancer_enable)
        self.stereo_spread.ui_enable.connect('state-set',
                                             self.on_stereo_spread_enable)
        self.crossfeed.ui_enable.connect('state-set', self.on_crossfeed_enable)
        self.reverb.ui_enable.connect('state-set', self.on_reverb_enable)
        self.panorama.ui_enable.connect('state-set', self.on_panorama_enable)
        self.maximizer.ui_enable.connect('state-set', self.on_maximizer_enable)
        self.output_limiter.ui_limiter_enable\
            .connect('state-set', self.on_output_limiter_enable)

        if self.limiter.is_installed:
            self.limiter.bind()
        else:
            self.limiter.ui_window.set_sensitive(False)
            self.limiter.ui_limiter_enable.set_sensitive(False)
            self.limiter.ui_img_state.hide()

        if self.compressor.is_installed:
            self.compressor.bind()
        else:
            self.compressor.ui_window.set_sensitive(False)
            self.compressor.ui_enable.set_sensitive(False)
            self.compressor.ui_img_state.hide()

        if self.exciter.is_installed:
            self.exciter.bind()
        else:
            self.exciter.ui_window.set_sensitive(False)
            self.exciter.ui_enable.set_sensitive(False)
            self.exciter.ui_img_state.hide()

        if self.bass_enhancer.is_installed:
            self.bass_enhancer.bind()
        else:
            self.bass_enhancer.ui_window.set_sensitive(False)
            self.bass_enhancer.ui_enable.set_sensitive(False)
            self.bass_enhancer.ui_img_state.hide()

        if self.delay.is_installed:
            self.delay.bind()
        else:
            self.delay.ui_window.set_sensitive(False)
            self.delay.ui_enable.set_sensitive(False)
            self.delay.ui_img_state.hide()

        if self.stereo_enhancer.is_installed:
            self.stereo_enhancer.bind()
        else:
            self.stereo_enhancer.ui_window.set_sensitive(False)
            self.stereo_enhancer.ui_enable.set_sensitive(False)
            self.stereo_enhancer.ui_img_state.hide()

        if self.stereo_spread.is_installed:
            self.stereo_spread.bind()
        else:
            self.stereo_spread.ui_window.set_sensitive(False)
            self.stereo_spread.ui_enable.set_sensitive(False)
            self.stereo_spread.ui_img_state.hide()

        if self.crossfeed.is_installed:
            self.crossfeed.bind()
        else:
            self.crossfeed.ui_window.set_sensitive(False)
            self.crossfeed.ui_enable.set_sensitive(False)
            self.crossfeed.ui_img_state.hide()

        if self.maximizer.is_installed:
            self.maximizer.bind()
        else:
            self.maximizer.ui_window.set_sensitive(False)
            self.maximizer.ui_enable.set_sensitive(False)
            self.maximizer.ui_img_state.hide()

        if self.output_limiter.is_installed:
            self.output_limiter.bind()
        else:
            self.output_limiter.ui_window.set_sensitive(False)
            self.output_limiter.ui_limiter_enable.set_sensitive(False)
            self.output_limiter.ui_img_state.hide()

        self.highpass.bind()
        self.lowpass.bind()
        self.equalizer.bind()
        self.reverb.bind()
        self.panorama.bind()

    def on_enable_app(self, obj, state, idx):
        if state:
            self.pm.move_sink_input_to_pulseeffects_sink(idx)
        else:
            self.pm.move_sink_input_to_default_sink(idx)

    def on_volume_changed(self, obj, idx, audio_channels):
        self.pm.set_sink_input_volume(idx, audio_channels, obj.get_value())

    def on_mute(self, button, idx, icon):
        state = button.get_active()

        if state:
            icon_name = 'audio-volume-muted-symbolic'
            icon.set_from_icon_name(icon_name, Gtk.IconSize.BUTTON)
        else:
            icon_name = 'audio-volume-high-symbolic'
            icon.set_from_icon_name(icon_name, Gtk.IconSize.BUTTON)

        self.pm.set_sink_input_mute(idx, state)

    def on_app_added(self, obj, parameters):
        EffectsBase.on_app_added(self, obj, parameters)

        if self.there_is_window:
            source_name = 'PulseEffects_apps.monitor'.encode('utf-8')
            app_idx = parameters['index']
            monitor_idx = app_idx
            app_name = parameters['name']
            connected = parameters['connected']
            corked = parameters['corked']

            if connected and not corked:
                self.streams[str(app_idx)] = self.pm.create_stream(
                    source_name, app_idx, app_name, monitor_idx)

    def on_app_changed(self, obj, parameters):
        EffectsBase.on_app_changed(self, obj, parameters)

        if self.there_is_window:
            source_name = 'PulseEffects_apps.monitor'.encode('utf-8')
            app_idx = parameters['index']
            monitor_idx = app_idx
            app_name = parameters['name']
            connected = parameters['connected']
            corked = parameters['corked']

            key = str(app_idx)

            if connected:
                if not corked and key not in self.streams:
                    self.streams[key] = self.pm.create_stream(
                        source_name, app_idx, app_name, monitor_idx)
                elif corked and key in self.streams:
                    self.pm.disconnect_stream(self.streams[key])

                    del self.streams[key]
            else:
                if key in self.streams:
                    del self.streams[key]

    def on_app_removed(self, obj, idx):
        EffectsBase.on_app_removed(self, obj, idx)

        key = str(idx)

        if key in self.streams:
            del self.streams[key]

    def disconnect_streams(self):
        for k in self.streams:
            self.pm.disconnect_stream(self.streams[k])

        self.streams.clear()

    def get_sink_input_info(self):
        for a in self.apps_list:
            idx = a[0]
            state = a[1]

            if state:  # connected and not corked
                self.pm.get_sink_input_info(idx)

        return self.periodic_info_update

    def post_messages(self, state):
        EffectsBase.post_messages(self, state)

        self.exciter.post_messages(state)
        self.bass_enhancer.post_messages(state)
        self.delay.post_messages(state)
        self.stereo_enhancer.post_messages(state)
        self.stereo_spread.post_messages(state)
        self.crossfeed.post_messages(state)
        self.panorama.post_messages(state)
        self.maximizer.post_messages(state)
        self.output_limiter.post_messages(state)

        self.periodic_info_update = state

        if state:
            GLib.timeout_add_seconds(5, self.get_sink_input_info)

    def on_message_element(self, bus, msg):
        EffectsBase.on_message_element(self, bus, msg)

        plugin = msg.src.get_name()

        if plugin == 'exciter_input_level':
            peak = msg.get_structure().get_value('peak')

            self.exciter.ui_update_input_level(peak)
        elif plugin == 'exciter_output_level':
            peak = msg.get_structure().get_value('peak')

            self.exciter.ui_update_output_level(peak)
        elif plugin == 'bass_enhancer_input_level':
            peak = msg.get_structure().get_value('peak')

            self.bass_enhancer.ui_update_input_level(peak)
        elif plugin == 'bass_enhancer_output_level':
            peak = msg.get_structure().get_value('peak')

            self.bass_enhancer.ui_update_output_level(peak)
        elif plugin == 'delay_input_level':
            peak = msg.get_structure().get_value('peak')

            self.delay.ui_update_input_level(peak)
        elif plugin == 'delay_output_level':
            peak = msg.get_structure().get_value('peak')

            self.delay.ui_update_output_level(peak)
        elif plugin == 'stereo_enhancer_input_level':
            peak = msg.get_structure().get_value('peak')

            self.stereo_enhancer.ui_update_input_level(peak)
        elif plugin == 'stereo_enhancer_output_level':
            peak = msg.get_structure().get_value('peak')

            self.stereo_enhancer.ui_update_output_level(peak)
        elif plugin == 'stereo_spread_input_level':
            peak = msg.get_structure().get_value('peak')

            self.stereo_spread.ui_update_input_level(peak)
        elif plugin == 'stereo_spread_output_level':
            peak = msg.get_structure().get_value('peak')

            self.stereo_spread.ui_update_output_level(peak)
        elif plugin == 'crossfeed_input_level':
            peak = msg.get_structure().get_value('peak')

            self.crossfeed.ui_update_input_level(peak)
        elif plugin == 'crossfeed_output_level':
            peak = msg.get_structure().get_value('peak')

            self.crossfeed.ui_update_output_level(peak)
        elif plugin == 'panorama_input_level':
            peak = msg.get_structure().get_value('peak')

            self.panorama.ui_update_input_level(peak)
        elif plugin == 'panorama_output_level':
            peak = msg.get_structure().get_value('peak')

            self.panorama.ui_update_output_level(peak)
        elif plugin == 'maximizer_input_level':
            peak = msg.get_structure().get_value('peak')

            self.maximizer.ui_update_input_level(peak)
        elif plugin == 'maximizer_output_level':
            peak = msg.get_structure().get_value('peak')

            self.maximizer.ui_update_output_level(peak)
        elif plugin == 'output_limiter_input_level':
            peak = msg.get_structure().get_value('peak')

            self.output_limiter.ui_update_limiter_input_level(peak)
        elif plugin == 'output_limiter_output_level':
            peak = msg.get_structure().get_value('peak')

            self.output_limiter.ui_update_limiter_output_level(peak)

        return True

    def on_exciter_enable(self, obj, state):
        if state:
            if not self.exciter_wrapper.get_by_name('exciter_bin'):
                self.exciter_wrapper.append(self.exciter.bin,
                                            self.on_filter_added, None)
        else:
            self.exciter_wrapper.remove(self.exciter.bin,
                                        self.on_filter_removed, None)

    def on_bass_enhancer_enable(self, obj, state):
        if state:
            if not self.bass_enhancer_wrapper.get_by_name('bass_enhancer_bin'):
                self.bass_enhancer_wrapper.append(self.bass_enhancer.bin,
                                                  self.on_filter_added, None)
        else:
            self.bass_enhancer_wrapper.remove(self.bass_enhancer.bin,
                                              self.on_filter_removed, None)

    def on_delay_enable(self, obj, state):
        if state:
            if not self.delay_wrapper.get_by_name('delay_bin'):
                self.delay_wrapper.append(self.delay.bin, self.on_filter_added,
                                          None)
        else:
            self.delay_wrapper.remove(self.delay.bin, self.on_filter_removed,
                                      None)

    def on_stereo_enhancer_enable(self, obj, state):
        if state:
            if not self.stereo_enhancer_wrapper.get_by_name(
                    'stereo_enhancer_bin'):
                self.stereo_enhancer_wrapper.append(self.stereo_enhancer.bin,
                                                    self.on_filter_added, None)
        else:
            self.stereo_enhancer_wrapper.remove(self.stereo_enhancer.bin,
                                                self.on_filter_removed, None)

    def on_stereo_spread_enable(self, obj, state):
        if state:
            if not self.stereo_spread_wrapper.get_by_name('stereo_spread_bin'):
                self.stereo_spread_wrapper.append(self.stereo_spread.bin,
                                                  self.on_filter_added, None)
        else:
            self.stereo_spread_wrapper.remove(self.stereo_spread.bin,
                                              self.on_filter_removed, None)

    def on_crossfeed_enable(self, obj, state):
        if state:
            if not self.crossfeed_wrapper.get_by_name('crossfeed_bin'):
                self.crossfeed_wrapper.append(self.crossfeed.bin,
                                              self.on_filter_added, None)
        else:
            self.crossfeed_wrapper.remove(self.crossfeed.bin,
                                          self.on_filter_removed, None)

    def on_panorama_enable(self, obj, state):
        if state:
            if not self.panorama_wrapper.get_by_name('panorama_bin'):
                self.panorama_wrapper.append(self.panorama.bin,
                                             self.on_filter_added, None)
        else:
            self.panorama_wrapper.remove(self.panorama.bin,
                                         self.on_filter_removed, None)

    def on_maximizer_enable(self, obj, state):
        if state:
            if not self.maximizer_wrapper.get_by_name('maximizer_bin'):
                self.maximizer_wrapper.append(self.maximizer.bin,
                                              self.on_filter_added, None)
        else:
            self.maximizer_wrapper.remove(self.maximizer.bin,
                                          self.on_filter_removed, None)

    def on_output_limiter_enable(self, obj, state):
        if state:
            if not self.output_limiter_wrapper.get_by_name(
                    'output_limiter_bin'):
                self.output_limiter_wrapper.append(self.output_limiter.bin,
                                                   self.on_filter_added, None)
        else:
            self.output_limiter_wrapper.remove(self.output_limiter.bin,
                                               self.on_filter_removed, None)

    def reset(self):
        EffectsBase.reset(self)

        self.exciter.reset()
        self.bass_enhancer.reset()
        self.delay.reset()
        self.stereo_enhancer.reset()
        self.stereo_spread.reset()
        self.crossfeed.reset()
        self.panorama.reset()
        self.maximizer.reset()
        self.output_limiter.reset()
Example #5
0
    def __init__(self, pulse_manager):
        self.pm = pulse_manager
        self.settings = Gio.Settings('com.github.wwmm.pulseeffects.sinkinputs')

        EffectsBase.__init__(self, self.pm.default_sink_rate, self.settings)

        self.log_tag = 'apps: '

        self.set_source_monitor_name(self.pm.apps_sink_monitor_name)

        pulse_sink = os.environ.get('PULSE_SINK')

        if pulse_sink:
            self.set_output_sink_name(pulse_sink)

            self.log.info('$PULSE_SINK = ' + pulse_sink)

            msg = 'user has $PULSE_SINK set. Using it as output device'

            self.log.info(msg)
        else:
            self.set_output_sink_name(self.pm.default_sink_name)

        self.pm.connect('sink_input_added', self.on_app_added)
        self.pm.connect('sink_input_changed', self.on_app_changed)
        self.pm.connect('sink_input_removed', self.on_app_removed)
        self.pm.connect('sink_input_level_changed', self.on_app_level_changed)
        self.pm.connect('new_default_sink', self.update_output_sink_name)

        self.panorama = Panorama(self.settings)
        self.exciter = Exciter(self.settings)
        self.bass_enhancer = BassEnhancer(self.settings)
        self.maximizer = Maximizer(self.settings)
        self.output_limiter = OutputLimiter(self.settings)

        # effects wrappers
        self.panorama_wrapper = GstInsertBin.InsertBin.new('panorama_wrapper')
        self.exciter_wrapper = GstInsertBin.InsertBin.new('exciter_wrapper')
        self.bass_enhancer_wrapper = GstInsertBin.InsertBin.new(
            'bass_enhancer_wrapper')
        self.maximizer_wrapper = GstInsertBin.InsertBin.new(
            'maximizer_wrapper')
        self.output_limiter_wrapper = GstInsertBin.InsertBin.new(
            'output_limiter_wrapper')

        # appending effects wrappers to effects bin
        self.effects_bin.insert_after(self.panorama_wrapper,
                                      self.limiter_wrapper,
                                      self.on_filter_added, self.log_tag)

        self.effects_bin.insert_after(self.exciter_wrapper,
                                      self.equalizer_wrapper,
                                      self.on_filter_added, self.log_tag)

        self.effects_bin.insert_after(self.bass_enhancer_wrapper,
                                      self.exciter_wrapper,
                                      self.on_filter_added, self.log_tag)

        self.effects_bin.insert_after(self.maximizer_wrapper,
                                      self.bass_enhancer_wrapper,
                                      self.on_filter_added, self.log_tag)

        self.effects_bin.insert_before(self.output_limiter_wrapper,
                                       self.spectrum_wrapper,
                                       self.on_filter_added, self.log_tag)
Example #6
0
class SinkInputEffects(EffectsBase):
    def __init__(self, pulse_manager):
        self.pm = pulse_manager
        self.settings = Gio.Settings('com.github.wwmm.pulseeffects.sinkinputs')

        EffectsBase.__init__(self, self.pm.default_sink_rate, self.settings)

        self.log_tag = 'apps: '

        self.set_source_monitor_name(self.pm.apps_sink_monitor_name)

        pulse_sink = os.environ.get('PULSE_SINK')

        if pulse_sink:
            self.set_output_sink_name(pulse_sink)

            self.log.info('$PULSE_SINK = ' + pulse_sink)

            msg = 'user has $PULSE_SINK set. Using it as output device'

            self.log.info(msg)
        else:
            self.set_output_sink_name(self.pm.default_sink_name)

        self.pm.connect('sink_input_added', self.on_app_added)
        self.pm.connect('sink_input_changed', self.on_app_changed)
        self.pm.connect('sink_input_removed', self.on_app_removed)
        self.pm.connect('sink_input_level_changed', self.on_app_level_changed)
        self.pm.connect('new_default_sink', self.update_output_sink_name)

        self.panorama = Panorama(self.settings)
        self.exciter = Exciter(self.settings)
        self.bass_enhancer = BassEnhancer(self.settings)
        self.maximizer = Maximizer(self.settings)
        self.output_limiter = OutputLimiter(self.settings)

        # effects wrappers
        self.panorama_wrapper = GstInsertBin.InsertBin.new('panorama_wrapper')
        self.exciter_wrapper = GstInsertBin.InsertBin.new('exciter_wrapper')
        self.bass_enhancer_wrapper = GstInsertBin.InsertBin.new(
            'bass_enhancer_wrapper')
        self.maximizer_wrapper = GstInsertBin.InsertBin.new(
            'maximizer_wrapper')
        self.output_limiter_wrapper = GstInsertBin.InsertBin.new(
            'output_limiter_wrapper')

        # appending effects wrappers to effects bin
        self.effects_bin.insert_after(self.panorama_wrapper,
                                      self.limiter_wrapper,
                                      self.on_filter_added, self.log_tag)

        self.effects_bin.insert_after(self.exciter_wrapper,
                                      self.equalizer_wrapper,
                                      self.on_filter_added, self.log_tag)

        self.effects_bin.insert_after(self.bass_enhancer_wrapper,
                                      self.exciter_wrapper,
                                      self.on_filter_added, self.log_tag)

        self.effects_bin.insert_after(self.maximizer_wrapper,
                                      self.bass_enhancer_wrapper,
                                      self.on_filter_added, self.log_tag)

        self.effects_bin.insert_before(self.output_limiter_wrapper,
                                       self.spectrum_wrapper,
                                       self.on_filter_added, self.log_tag)

    def init_ui(self):
        EffectsBase.init_ui(self)

        self.panorama.init_ui()
        self.exciter.init_ui()
        self.bass_enhancer.init_ui()
        self.maximizer.init_ui()
        self.output_limiter.init_ui()

        self.insert_in_listbox('panorama', 2)
        self.add_to_listbox('exciter')
        self.add_to_listbox('bass_enhancer')
        self.add_to_listbox('maximizer')
        self.add_to_listbox('output_limiter')

        self.listbox.show_all()

        # adding effects widgets to the stack

        self.stack.add_named(self.limiter.ui_window, 'limiter')
        self.stack.add_named(self.panorama.ui_window, 'panorama')
        self.stack.add_named(self.compressor.ui_window, 'compressor')
        self.stack.add_named(self.reverb.ui_window, 'reverb')
        self.stack.add_named(self.highpass.ui_window, 'highpass')
        self.stack.add_named(self.lowpass.ui_window, 'lowpass')
        self.stack.add_named(self.equalizer.ui_window, 'equalizer')
        self.stack.add_named(self.exciter.ui_window, 'exciter')
        self.stack.add_named(self.bass_enhancer.ui_window, 'bass_enhancer')
        self.stack.add_named(self.maximizer.ui_window, 'maximizer')
        self.stack.add_named(self.output_limiter.ui_window, 'output_limiter')

        # on/off switches connections
        self.panorama.ui_enable.connect('state-set', self.on_panorama_enable)
        self.exciter.ui_enable.connect('state-set', self.on_exciter_enable)
        self.bass_enhancer.ui_enable.connect('state-set',
                                             self.on_bass_enhancer_enable)
        self.maximizer.ui_enable.connect('state-set', self.on_maximizer_enable)
        self.output_limiter.ui_limiter_enable\
            .connect('state-set', self.on_output_limiter_enable)

        if self.limiter.is_installed:
            self.limiter.bind()
        else:
            self.limiter.ui_window.set_sensitive(False)
            self.limiter.ui_limiter_enable.set_sensitive(False)

        if self.panorama.is_installed:
            self.panorama.bind()
        else:
            self.panorama.ui_window.set_sensitive(False)
            self.panorama.ui_enable.set_sensitive(False)

        if self.compressor.is_installed:
            self.compressor.bind()
        else:
            self.compressor.ui_window.set_sensitive(False)
            self.compressor.ui_enable.set_sensitive(False)

        if self.exciter.is_installed:
            self.exciter.bind()
        else:
            self.exciter.ui_window.set_sensitive(False)
            self.exciter.ui_enable.set_sensitive(False)

        if self.bass_enhancer.is_installed:
            self.bass_enhancer.bind()
        else:
            self.bass_enhancer.ui_window.set_sensitive(False)
            self.bass_enhancer.ui_enable.set_sensitive(False)

        if self.maximizer.is_installed:
            self.maximizer.bind()
        else:
            self.maximizer.ui_window.set_sensitive(False)
            self.maximizer.ui_enable.set_sensitive(False)

        if self.output_limiter.is_installed:
            self.output_limiter.bind()
        else:
            self.output_limiter.ui_window.set_sensitive(False)
            self.output_limiter.ui_limiter_enable.set_sensitive(False)

        self.reverb.bind()
        self.highpass.bind()
        self.lowpass.bind()
        self.equalizer.bind()

    def on_enable_app(self, obj, state, idx):
        if state:
            self.pm.move_sink_input_to_pulseeffects_sink(idx)
        else:
            self.pm.move_sink_input_to_default_sink(idx)

    def on_volume_changed(self, obj, idx, audio_channels):
        self.pm.set_sink_input_volume(idx, audio_channels, obj.get_value())

    def on_mute(self, button, idx, icon):
        state = button.get_active()

        if state:
            icon_name = 'audio-volume-muted-symbolic'
            icon.set_from_icon_name(icon_name, Gtk.IconSize.BUTTON)
        else:
            icon_name = 'audio-volume-high-symbolic'
            icon.set_from_icon_name(icon_name, Gtk.IconSize.BUTTON)

        self.pm.set_sink_input_mute(idx, state)

    def post_messages(self, state):
        EffectsBase.post_messages(self, state)

        self.panorama.post_messages(state)
        self.exciter.post_messages(state)
        self.bass_enhancer.post_messages(state)
        self.maximizer.post_messages(state)
        self.output_limiter.post_messages(state)

    def on_message_element(self, bus, msg):
        EffectsBase.on_message_element(self, bus, msg)

        plugin = msg.src.get_name()

        if plugin == 'panorama_input_level':
            peak = msg.get_structure().get_value('peak')

            self.panorama.ui_update_panorama_input_level(peak)
        elif plugin == 'panorama_output_level':
            peak = msg.get_structure().get_value('peak')

            self.panorama.ui_update_panorama_output_level(peak)
        elif plugin == 'exciter_input_level':
            peak = msg.get_structure().get_value('peak')

            self.exciter.ui_update_input_level(peak)
        elif plugin == 'exciter_output_level':
            peak = msg.get_structure().get_value('peak')

            self.exciter.ui_update_output_level(peak)
        elif plugin == 'bass_enhancer_input_level':
            peak = msg.get_structure().get_value('peak')

            self.bass_enhancer.ui_update_input_level(peak)
        elif plugin == 'bass_enhancer_output_level':
            peak = msg.get_structure().get_value('peak')

            self.bass_enhancer.ui_update_output_level(peak)
        elif plugin == 'maximizer_input_level':
            peak = msg.get_structure().get_value('peak')

            self.maximizer.ui_update_input_level(peak)
        elif plugin == 'maximizer_output_level':
            peak = msg.get_structure().get_value('peak')

            self.maximizer.ui_update_output_level(peak)
        elif plugin == 'output_limiter_input_level':
            peak = msg.get_structure().get_value('peak')

            self.output_limiter.ui_update_limiter_input_level(peak)
        elif plugin == 'output_limiter_output_level':
            peak = msg.get_structure().get_value('peak')

            self.output_limiter.ui_update_limiter_output_level(peak)

        return True

    def on_panorama_enable(self, obj, state):
        if state:
            if not self.panorama_wrapper.get_by_name('panorama_bin'):
                self.panorama_wrapper.append(self.panorama.bin,
                                             self.on_filter_added,
                                             self.log_tag)
        else:
            self.panorama_wrapper.remove(self.panorama.bin,
                                         self.on_filter_removed, self.log_tag)

    def on_exciter_enable(self, obj, state):
        if state:
            if not self.exciter_wrapper.get_by_name('exciter_bin'):
                self.exciter_wrapper.append(self.exciter.bin,
                                            self.on_filter_added, self.log_tag)
        else:
            self.exciter_wrapper.remove(self.exciter.bin,
                                        self.on_filter_removed, self.log_tag)

    def on_bass_enhancer_enable(self, obj, state):
        if state:
            if not self.bass_enhancer_wrapper.get_by_name('bass_enhancer_bin'):
                self.bass_enhancer_wrapper.append(self.bass_enhancer.bin,
                                                  self.on_filter_added,
                                                  self.log_tag)
        else:
            self.bass_enhancer_wrapper.remove(self.bass_enhancer.bin,
                                              self.on_filter_removed,
                                              self.log_tag)

    def on_maximizer_enable(self, obj, state):
        if state:
            if not self.maximizer_wrapper.get_by_name('maximizer_bin'):
                self.maximizer_wrapper.append(self.maximizer.bin,
                                              self.on_filter_added,
                                              self.log_tag)
        else:
            self.maximizer_wrapper.remove(self.maximizer.bin,
                                          self.on_filter_removed, self.log_tag)

    def on_output_limiter_enable(self, obj, state):
        if state:
            if not self.output_limiter_wrapper.get_by_name(
                    'output_limiter_bin'):
                self.output_limiter_wrapper.append(self.output_limiter.bin,
                                                   self.on_filter_added,
                                                   self.log_tag)
        else:
            self.output_limiter_wrapper.remove(self.output_limiter.bin,
                                               self.on_filter_removed,
                                               self.log_tag)

    def reset(self):
        EffectsBase.reset(self)

        self.panorama.reset()
        self.exciter.reset()
        self.bass_enhancer.reset()
        self.maximizer.reset()
        self.output_limiter.reset()
class SinkInputEffects(PipelineBase):

    def __init__(self, sampling_rate):
        PipelineBase.__init__(self, sampling_rate)

        self.module_path = os.path.dirname(__file__)

        self.log_tag = 'apps: '

        self.settings = Gio.Settings('com.github.wwmm.pulseeffects.sinkinputs')

        self.builder = Gtk.Builder()

        self.builder.add_from_file(self.module_path + '/ui/effects_box.glade')

        self.ui_window = self.builder.get_object('window')

        self.stack = self.builder.get_object('stack')

        self.limiter = Limiter(self.settings)
        self.panorama = Panorama(self.settings)
        self.compressor = Compressor(self.settings)
        self.reverb = Reverb(self.settings)
        self.highpass = Highpass(self.settings)
        self.lowpass = Lowpass(self.settings)
        self.equalizer = Equalizer(self.settings)

        # adding effects widgets to the stack

        self.stack.add_titled(self.limiter.ui_window, 'Limiter',
                              _('Input Limiter'))
        self.stack.add_titled(self.panorama.ui_window, 'Panorama',
                              _('Panorama'))
        self.stack.add_titled(self.compressor.ui_window, 'Compressor',
                              _('Compressor'))
        self.stack.add_titled(self.reverb.ui_window, 'Reverb',
                              _('Reverberation'))
        self.stack.add_titled(self.highpass.ui_window, 'Highpass',
                              _('High pass'))
        self.stack.add_titled(self.lowpass.ui_window, 'Lowpass',
                              _('Low pass'))
        self.stack.add_titled(self.equalizer.ui_window, 'Equalizer',
                              _('Equalizer'))

        # on/off switches connections

        self.limiter.ui_limiter_enable.connect('state-set',
                                               self.on_limiter_enable)
        self.panorama.ui_panorama_enable.connect('state-set',
                                                 self.on_panorama_enable)
        self.compressor.ui_compressor_enable.connect('state-set',
                                                     self.on_compressor_enable)
        self.reverb.ui_reverb_enable.connect('state-set',
                                             self.on_reverb_enable)
        self.highpass.ui_highpass_enable.connect('state-set',
                                                 self.on_highpass_enable)
        self.lowpass.ui_lowpass_enable.connect('state-set',
                                               self.on_lowpass_enable)
        self.equalizer.ui_equalizer_enable.connect('state-set',
                                                   self.on_equalizer_enable)

    def on_message_element(self, bus, msg):
        plugin = msg.src.get_name()

        if plugin == 'limiter_input_level':
            peak = msg.get_structure().get_value('peak')

            self.limiter.ui_update_limiter_input_level(peak)
        elif plugin == 'limiter_output_level':
            peak = msg.get_structure().get_value('peak')

            self.limiter.ui_update_limiter_output_level(peak)
        elif plugin == 'autovolume':
            if self.limiter.autovolume_enabled:
                peak = msg.get_structure().get_value('peak')

                max_value = max(peak)

                if max_value > self.limiter.autovolume_threshold:
                    self.limiter.auto_gain(max_value)
        elif plugin == 'panorama_input_level':
            peak = msg.get_structure().get_value('peak')

            self.panorama.ui_update_panorama_input_level(peak)
        elif plugin == 'panorama_output_level':
            peak = msg.get_structure().get_value('peak')

            self.panorama.ui_update_panorama_output_level(peak)
        elif plugin == 'compressor_input_level':
            peak = msg.get_structure().get_value('peak')

            self.compressor.ui_update_compressor_input_level(peak)
        elif plugin == 'compressor_output_level':
            peak = msg.get_structure().get_value('peak')

            self.compressor.ui_update_compressor_output_level(peak)
        elif plugin == 'reverb_input_level':
            peak = msg.get_structure().get_value('peak')

            self.reverb.ui_update_reverb_input_level(peak)
        elif plugin == 'reverb_output_level':
            peak = msg.get_structure().get_value('peak')

            self.reverb.ui_update_reverb_output_level(peak)
        elif plugin == 'highpass_input_level':
            peak = msg.get_structure().get_value('peak')

            self.highpass.ui_update_highpass_input_level(peak)
        elif plugin == 'highpass_output_level':
            peak = msg.get_structure().get_value('peak')

            self.highpass.ui_update_highpass_output_level(peak)
        elif plugin == 'lowpass_input_level':
            peak = msg.get_structure().get_value('peak')

            self.lowpass.ui_update_lowpass_input_level(peak)
        elif plugin == 'lowpass_output_level':
            peak = msg.get_structure().get_value('peak')

            self.lowpass.ui_update_lowpass_output_level(peak)
        elif plugin == 'equalizer_input_level':
            peak = msg.get_structure().get_value('peak')

            self.equalizer.ui_update_equalizer_input_level(peak)
        elif plugin == 'equalizer_output_level':
            peak = msg.get_structure().get_value('peak')

            self.equalizer.ui_update_equalizer_output_level(peak)
        elif plugin == 'spectrum':
            magnitudes = msg.get_structure().get_value('magnitude')

            cs = CubicSpline(self.spectrum_freqs,
                             magnitudes[:self.spectrum_nfreqs])

            magnitudes = cs(self.spectrum_x_axis)

            max_mag = np.amax(magnitudes)
            min_mag = self.spectrum_threshold

            if max_mag > min_mag:
                magnitudes = (min_mag - magnitudes) / min_mag

                self.emit('new_spectrum', magnitudes)

        return True

    def on_limiter_enable(self, obj, state):
        if state:
            self.effects_bin.prepend(self.limiter.bin, self.on_filter_added,
                                     self.log_tag)
        else:
            self.effects_bin.remove(self.limiter.bin, self.on_filter_removed,
                                    self.log_tag)

    def on_panorama_enable(self, obj, state):
        limiter_enabled = self.settings.get_value('limiter-state').unpack()

        if state:
            if limiter_enabled:
                self.effects_bin.insert_after(self.panorama.bin,
                                              self.limiter.bin,
                                              self.on_filter_added,
                                              self.log_tag)
            else:
                self.effects_bin.prepend(self.panorama.bin,
                                         self.on_filter_added, self.log_tag)
        else:
            self.effects_bin.remove(self.panorama.bin, self.on_filter_removed,
                                    self.log_tag)

    def on_compressor_enable(self, obj, state):
        limiter_enabled = self.settings.get_value('limiter-state').unpack()
        panorama_enabled = self.settings.get_value('panorama-state').unpack()

        if state:
            if panorama_enabled:
                self.effects_bin.insert_after(self.compressor.bin,
                                              self.panorama.bin,
                                              self.on_filter_added,
                                              self.log_tag)
            elif limiter_enabled:
                self.effects_bin.insert_after(self.compressor.bin,
                                              self.limiter.bin,
                                              self.on_filter_added,
                                              self.log_tag)
            else:
                self.effects_bin.prepend(self.compressor.bin,
                                         self.on_filter_added, self.log_tag)
        else:
            self.effects_bin.remove(self.compressor.bin,
                                    self.on_filter_removed,
                                    self.log_tag)

    def on_reverb_enable(self, obj, state):
        limiter_enabled = self.settings.get_value('limiter-state').unpack()
        panorama_enabled = self.settings.get_value('panorama-state').unpack()
        compressor_enabled = self.settings.get_value(
            'compressor-state').unpack()

        if state:
            if compressor_enabled:
                self.effects_bin.insert_after(self.reverb.bin,
                                              self.compressor.bin,
                                              self.on_filter_added,
                                              self.log_tag)
            elif panorama_enabled:
                self.effects_bin.insert_after(self.reverb.bin,
                                              self.panorama.bin,
                                              self.on_filter_added,
                                              self.log_tag)
            elif limiter_enabled:
                self.effects_bin.insert_after(self.reverb.bin,
                                              self.limiter.bin,
                                              self.on_filter_added,
                                              self.log_tag)
            else:
                self.effects_bin.prepend(self.reverb.bin,
                                         self.on_filter_added, self.log_tag)
        else:
            self.effects_bin.remove(self.reverb.bin, self.on_filter_removed,
                                    self.log_tag)

    def on_highpass_enable(self, obj, state):
        limiter_enabled = self.settings.get_value('limiter-state').unpack()
        panorama_enabled = self.settings.get_value('panorama-state').unpack()
        compressor_enabled = self.settings.get_value(
            'compressor-state').unpack()
        reverb_enabled = self.settings.get_value(
            'reverb-state').unpack()

        if state:
            if reverb_enabled:
                self.effects_bin.insert_after(self.highpass.bin,
                                              self.reverb.bin,
                                              self.on_filter_added,
                                              self.log_tag)
            elif compressor_enabled:
                self.effects_bin.insert_after(self.highpass.bin,
                                              self.compressor.bin,
                                              self.on_filter_added,
                                              self.log_tag)
            elif panorama_enabled:
                self.effects_bin.insert_after(self.highpass.bin,
                                              self.panorama.bin,
                                              self.on_filter_added,
                                              self.log_tag)
            elif limiter_enabled:
                self.effects_bin.insert_after(self.highpass.bin,
                                              self.limiter.bin,
                                              self.on_filter_added,
                                              self.log_tag)
            else:
                self.effects_bin.prepend(self.highpass.bin,
                                         self.on_filter_added, self.log_tag)
        else:
            self.effects_bin.remove(self.highpass.bin, self.on_filter_removed,
                                    self.log_tag)

    def on_lowpass_enable(self, obj, state):
        limiter_enabled = self.settings.get_value('limiter-state').unpack()
        panorama_enabled = self.settings.get_value('panorama-state').unpack()
        compressor_enabled = self.settings.get_value(
            'compressor-state').unpack()
        reverb_enabled = self.settings.get_value(
            'reverb-state').unpack()
        highpass_enabled = self.settings.get_value(
            'highpass-state').unpack()

        if state:
            if highpass_enabled:
                self.effects_bin.insert_after(self.lowpass.bin,
                                              self.highpass.bin,
                                              self.on_filter_added,
                                              self.log_tag)
            elif reverb_enabled:
                self.effects_bin.insert_after(self.lowpass.bin,
                                              self.reverb.bin,
                                              self.on_filter_added,
                                              self.log_tag)
            elif compressor_enabled:
                self.effects_bin.insert_after(self.lowpass.bin,
                                              self.compressor.bin,
                                              self.on_filter_added,
                                              self.log_tag)
            elif panorama_enabled:
                self.effects_bin.insert_after(self.lowpass.bin,
                                              self.panorama.bin,
                                              self.on_filter_added,
                                              self.log_tag)
            elif limiter_enabled:
                self.effects_bin.insert_after(self.lowpass.bin,
                                              self.limiter.bin,
                                              self.on_filter_added,
                                              self.log_tag)
            else:
                self.effects_bin.prepend(self.lowpass.bin,
                                         self.on_filter_added, self.log_tag)
        else:
            self.effects_bin.remove(self.lowpass.bin, self.on_filter_removed,
                                    self.log_tag)

    def on_equalizer_enable(self, obj, state):
        limiter_enabled = self.settings.get_value('limiter-state').unpack()
        panorama_enabled = self.settings.get_value('panorama-state').unpack()
        compressor_enabled = self.settings.get_value(
            'compressor-state').unpack()
        reverb_enabled = self.settings.get_value(
            'reverb-state').unpack()
        highpass_enabled = self.settings.get_value(
            'highpass-state').unpack()
        lowpass_enabled = self.settings.get_value(
            'lowpass-state').unpack()

        if state:
            if lowpass_enabled:
                self.effects_bin.insert_after(self.equalizer.bin,
                                              self.lowpass.bin,
                                              self.on_filter_added,
                                              self.log_tag)
            elif highpass_enabled:
                self.effects_bin.insert_after(self.equalizer.bin,
                                              self.highpass.bin,
                                              self.on_filter_added,
                                              self.log_tag)
            elif reverb_enabled:
                self.effects_bin.insert_after(self.equalizer.bin,
                                              self.reverb.bin,
                                              self.on_filter_added,
                                              self.log_tag)
            elif compressor_enabled:
                self.effects_bin.insert_after(self.equalizer.bin,
                                              self.compressor.bin,
                                              self.on_filter_added,
                                              self.log_tag)
            elif panorama_enabled:
                self.effects_bin.insert_after(self.equalizer.bin,
                                              self.panorama.bin,
                                              self.on_filter_added,
                                              self.log_tag)
            elif limiter_enabled:
                self.effects_bin.insert_after(self.equalizer.bin,
                                              self.limiter.bin,
                                              self.on_filter_added,
                                              self.log_tag)
            else:
                self.effects_bin.prepend(self.equalizer.bin,
                                         self.on_filter_added, self.log_tag)
        else:
            self.effects_bin.remove(self.equalizer.bin, self.on_filter_removed,
                                    self.log_tag)

    def enable_spectrum(self, state):
        if state:
            self.effects_bin.append(self.spectrum, self.on_filter_added,
                                    self.log_tag)
        else:
            self.effects_bin.remove(self.spectrum, self.on_filter_removed,
                                    self.log_tag)

    def init_ui(self):
        self.limiter.init_ui()
        self.panorama.init_ui()
        self.compressor.init_ui()
        self.reverb.init_ui()
        self.highpass.init_ui()
        self.lowpass.init_ui()
        self.equalizer.init_ui()

    def reset(self):
        self.limiter.reset()
        self.panorama.reset()
        self.compressor.reset()
        self.reverb.reset()
        self.highpass.reset()
        self.lowpass.reset()
        self.equalizer.reset()

        self.init_ui()
    def __init__(self, pulse_manager):
        self.pm = pulse_manager
        self.settings = Gio.Settings('com.github.wwmm.pulseeffects.sinkinputs')

        EffectsBase.__init__(self, self.pm.default_sink_rate, self.settings)

        self.log_tag = 'apps: '
        self.switch_on_all_apps = False
        self.panorama_ready = False

        self.set_source_monitor_name(self.pm.apps_sink_monitor_name)
        self.set_output_sink_name(self.pm.default_sink_name)

        self.pm.connect('sink_input_added', self.on_app_added)
        self.pm.connect('sink_input_changed', self.on_app_changed)
        self.pm.connect('sink_input_removed', self.on_app_removed)
        self.pm.connect('sink_input_level_changed', self.on_app_level_changed)

        self.panorama = Panorama(self.settings)

        self.insert_in_listbox('panorama', 2)

        self.listbox.show_all()

        # adding effects widgets to the stack

        self.stack.add_named(self.limiter.ui_window, 'limiter')
        self.stack.add_named(self.panorama.ui_window, 'panorama')
        self.stack.add_named(self.compressor.ui_window, 'compressor')
        self.stack.add_named(self.reverb.ui_window, 'reverb')
        self.stack.add_named(self.highpass.ui_window, 'highpass')
        self.stack.add_named(self.lowpass.ui_window, 'lowpass')
        self.stack.add_named(self.equalizer.ui_window, 'equalizer')

        # on/off switches connections
        self.panorama.ui_enable.connect('state-set', self.on_panorama_enable)
        self.compressor.ui_enable.connect('state-set',
                                          self.on_compressor_enable)
        self.reverb.ui_enable.connect('state-set', self.on_reverb_enable)
        self.highpass.ui_enable.connect('state-set', self.on_highpass_enable)
        self.lowpass.ui_enable.connect('state-set', self.on_lowpass_enable)
        self.equalizer.ui_enable.connect('state-set', self.on_equalizer_enable)

        # effects wrappers
        self.panorama_wrapper = GstInsertBin.InsertBin.new('panorama_wrapper')

        # appending effects wrappers to effects bin
        self.effects_bin.insert_after(self.panorama_wrapper,
                                      self.limiter_wrapper,
                                      self.on_filter_added,
                                      self.log_tag)

        if self.limiter.is_installed:
            self.limiter.bind()
        else:
            self.limiter.ui_window.set_sensitive(False)
            self.limiter.ui_limiter_enable.set_sensitive(False)

        if self.panorama.is_installed:
            self.panorama.bind()
        else:
            self.panorama.ui_window.set_sensitive(False)
            self.panorama.ui_enable.set_sensitive(False)

        if self.compressor.is_installed:
            self.compressor.bind()
        else:
            self.compressor.ui_window.set_sensitive(False)
            self.compressor.ui_enable.set_sensitive(False)

        self.reverb.bind()
        self.highpass.bind()
        self.lowpass.bind()
        self.equalizer.bind()
class SinkInputEffects(EffectsBase):

    def __init__(self, pulse_manager):
        self.pm = pulse_manager
        self.settings = Gio.Settings('com.github.wwmm.pulseeffects.sinkinputs')

        EffectsBase.__init__(self, self.pm.default_sink_rate, self.settings)

        self.log_tag = 'apps: '
        self.switch_on_all_apps = False
        self.panorama_ready = False

        self.set_source_monitor_name(self.pm.apps_sink_monitor_name)
        self.set_output_sink_name(self.pm.default_sink_name)

        self.pm.connect('sink_input_added', self.on_app_added)
        self.pm.connect('sink_input_changed', self.on_app_changed)
        self.pm.connect('sink_input_removed', self.on_app_removed)
        self.pm.connect('sink_input_level_changed', self.on_app_level_changed)

        self.panorama = Panorama(self.settings)

        self.insert_in_listbox('panorama', 2)

        self.listbox.show_all()

        # adding effects widgets to the stack

        self.stack.add_named(self.limiter.ui_window, 'limiter')
        self.stack.add_named(self.panorama.ui_window, 'panorama')
        self.stack.add_named(self.compressor.ui_window, 'compressor')
        self.stack.add_named(self.reverb.ui_window, 'reverb')
        self.stack.add_named(self.highpass.ui_window, 'highpass')
        self.stack.add_named(self.lowpass.ui_window, 'lowpass')
        self.stack.add_named(self.equalizer.ui_window, 'equalizer')

        # on/off switches connections
        self.panorama.ui_enable.connect('state-set', self.on_panorama_enable)
        self.compressor.ui_enable.connect('state-set',
                                          self.on_compressor_enable)
        self.reverb.ui_enable.connect('state-set', self.on_reverb_enable)
        self.highpass.ui_enable.connect('state-set', self.on_highpass_enable)
        self.lowpass.ui_enable.connect('state-set', self.on_lowpass_enable)
        self.equalizer.ui_enable.connect('state-set', self.on_equalizer_enable)

        # effects wrappers
        self.panorama_wrapper = GstInsertBin.InsertBin.new('panorama_wrapper')

        # appending effects wrappers to effects bin
        self.effects_bin.insert_after(self.panorama_wrapper,
                                      self.limiter_wrapper,
                                      self.on_filter_added,
                                      self.log_tag)

        if self.limiter.is_installed:
            self.limiter.bind()
        else:
            self.limiter.ui_window.set_sensitive(False)
            self.limiter.ui_limiter_enable.set_sensitive(False)

        if self.panorama.is_installed:
            self.panorama.bind()
        else:
            self.panorama.ui_window.set_sensitive(False)
            self.panorama.ui_enable.set_sensitive(False)

        if self.compressor.is_installed:
            self.compressor.bind()
        else:
            self.compressor.ui_window.set_sensitive(False)
            self.compressor.ui_enable.set_sensitive(False)

        self.reverb.bind()
        self.highpass.bind()
        self.lowpass.bind()
        self.equalizer.bind()

    def on_enable_app(self, obj, state, idx):
        if state:
            self.pm.move_sink_input_to_pulseeffects_sink(idx)
        else:
            self.pm.move_sink_input_to_default_sink(idx)

    def on_volume_changed(self, obj, idx, audio_channels):
        self.pm.set_sink_input_volume(idx, audio_channels, obj.get_value())

    def on_mute(self, button, idx, icon):
        state = button.get_active()

        if state:
            icon_name = 'audio-volume-muted-symbolic'
            icon.set_from_icon_name(icon_name, Gtk.IconSize.BUTTON)
        else:
            icon_name = 'audio-volume-high-symbolic'
            icon.set_from_icon_name(icon_name, Gtk.IconSize.BUTTON)

        self.pm.set_sink_input_mute(idx, state)

    def on_listbox_row_activated(self, obj, row):
        EffectsBase.on_listbox_row_activated(self, obj, row)

        name = row.get_name()

        if name == 'panorama':
            self.stack.set_visible_child(self.panorama.ui_window)

    def on_message_element(self, bus, msg):
        EffectsBase.on_message_element(self, bus, msg)

        plugin = msg.src.get_name()

        if plugin == 'panorama_input_level':
            peak = msg.get_structure().get_value('peak')

            self.panorama.ui_update_panorama_input_level(peak)
        elif plugin == 'panorama_output_level':
            peak = msg.get_structure().get_value('peak')

            self.panorama.ui_update_panorama_output_level(peak)

        return True

    def on_panorama_enable(self, obj, state):
        if state:
            self.panorama_wrapper.append(self.panorama.bin,
                                         self.on_filter_added,
                                         self.log_tag)
        else:
            self.panorama_wrapper.remove(self.panorama.bin,
                                         self.on_filter_removed,
                                         self.log_tag)

    def reset(self):
        EffectsBase.reset(self)

        self.panorama.reset()
class SinkInputEffects(EffectsBase):
    def __init__(self, sampling_rate):
        self.settings = Gio.Settings('com.github.wwmm.pulseeffects.sinkinputs')

        EffectsBase.__init__(self, sampling_rate, self.settings)

        self.log_tag = 'apps: '
        self.panorama_ready = False

        self.panorama = Panorama(self.settings)

        self.insert_in_listbox('panorama', 1)

        self.listbox.show_all()

        # adding effects widgets to the stack

        self.stack.add_named(self.limiter.ui_window, 'Limiter')
        self.stack.add_named(self.panorama.ui_window, 'Panorama')
        self.stack.add_named(self.compressor.ui_window, 'Compressor')
        self.stack.add_named(self.reverb.ui_window, 'Reverb')
        self.stack.add_named(self.highpass.ui_window, 'Highpass')
        self.stack.add_named(self.lowpass.ui_window, 'Lowpass')
        self.stack.add_named(self.equalizer.ui_window, 'Equalizer')

        # on/off switches connections
        self.panorama.ui_enable.connect('state-set', self.on_panorama_enable)
        self.compressor.ui_enable.connect('state-set',
                                          self.on_compressor_enable)
        self.reverb.ui_enable.connect('state-set', self.on_reverb_enable)
        self.highpass.ui_enable.connect('state-set', self.on_highpass_enable)
        self.lowpass.ui_enable.connect('state-set', self.on_lowpass_enable)
        self.equalizer.ui_enable.connect('state-set', self.on_equalizer_enable)

        # order of bind is important and may lead to load failure if
        # done otherwise

        if self.limiter.is_installed:
            self.limiter.bind()
        else:
            self.limiter.ui_window.set_sensitive(False)
            self.limiter.ui_limiter_enable.set_sensitive(False)

        if self.panorama.is_installed:
            self.panorama.bind()
        else:
            self.panorama.ui_window.set_sensitive(False)
            self.panorama.ui_enable.set_sensitive(False)

        if self.compressor.is_installed:
            self.compressor.bind()
        else:
            self.compressor.ui_window.set_sensitive(False)
            self.compressor.ui_enable.set_sensitive(False)

        self.reverb.bind()
        self.highpass.bind()
        self.lowpass.bind()
        self.equalizer.bind()

    def on_listbox_row_activated(self, obj, row):
        EffectsBase.on_listbox_row_activated(self, obj, row)

        name = row.get_name()

        if name == 'panorama':
            self.stack.set_visible_child(self.panorama.ui_window)

    def on_message_element(self, bus, msg):
        EffectsBase.on_message_element(self, bus, msg)

        plugin = msg.src.get_name()

        if plugin == 'panorama_input_level':
            peak = msg.get_structure().get_value('peak')

            self.panorama.ui_update_panorama_input_level(peak)
        elif plugin == 'panorama_output_level':
            peak = msg.get_structure().get_value('peak')

            self.panorama.ui_update_panorama_output_level(peak)

        return True

    def on_panorama_enable(self, obj, state):
        self.panorama_ready = False

        if state:
            limiter_enabled = self.settings.get_value('limiter-state').unpack()

            if limiter_enabled:
                while not self.limiter_ready:
                    pass

                self.effects_bin.insert_after(self.panorama.bin,
                                              self.limiter.bin,
                                              self.on_panorama_added,
                                              self.log_tag)
            else:
                self.effects_bin.prepend(self.panorama.bin,
                                         self.on_panorama_added, self.log_tag)
        else:
            self.effects_bin.remove(self.panorama.bin, self.on_filter_removed,
                                    self.log_tag)

    def on_compressor_enable(self, obj, state):
        self.compressor_ready = False

        if state:
            limiter_enabled = self.settings.get_value('limiter-state').unpack()
            panorama_enabled = self.settings.get_value(
                'panorama-state').unpack()

            if panorama_enabled:
                while not self.panorama_ready:
                    pass

                self.effects_bin.insert_after(self.compressor.bin,
                                              self.panorama.bin,
                                              self.on_compressor_added,
                                              self.log_tag)
            elif limiter_enabled:
                while not self.limiter_ready:
                    pass

                self.effects_bin.insert_after(self.compressor.bin,
                                              self.limiter.bin,
                                              self.on_compressor_added,
                                              self.log_tag)
            else:
                self.effects_bin.prepend(self.compressor.bin,
                                         self.on_compressor_added,
                                         self.log_tag)
        else:
            self.effects_bin.remove(self.compressor.bin,
                                    self.on_filter_removed, self.log_tag)

    def on_reverb_enable(self, obj, state):
        self.reverb_ready = False

        if state:
            limiter_enabled = self.settings.get_value('limiter-state').unpack()
            panorama_enabled = self.settings.get_value(
                'panorama-state').unpack()
            compressor_enabled = self.settings.get_value(
                'compressor-state').unpack()

            if compressor_enabled:
                while not self.compressor_ready:
                    pass

                self.effects_bin.insert_after(self.reverb.bin,
                                              self.compressor.bin,
                                              self.on_reverb_added,
                                              self.log_tag)
            elif panorama_enabled:
                while not self.panorama_ready:
                    pass

                self.effects_bin.insert_after(self.reverb.bin,
                                              self.panorama.bin,
                                              self.on_reverb_added,
                                              self.log_tag)
            elif limiter_enabled:
                while not self.limiter_ready:
                    pass

                self.effects_bin.insert_after(self.reverb.bin,
                                              self.limiter.bin,
                                              self.on_reverb_added,
                                              self.log_tag)
            else:
                self.effects_bin.prepend(self.reverb.bin, self.on_reverb_added,
                                         self.log_tag)
        else:
            self.effects_bin.remove(self.reverb.bin, self.on_filter_removed,
                                    self.log_tag)

    def on_highpass_enable(self, obj, state):
        self.highpass_ready = False

        if state:
            limiter_enabled = self.settings.get_value('limiter-state').unpack()
            panorama_enabled = self.settings.get_value(
                'panorama-state').unpack()
            compressor_enabled = self.settings.get_value(
                'compressor-state').unpack()
            reverb_enabled = self.settings.get_value('reverb-state').unpack()

            if reverb_enabled:
                while not self.reverb_ready:
                    pass

                self.effects_bin.insert_after(self.highpass.bin,
                                              self.reverb.bin,
                                              self.on_highpass_added,
                                              self.log_tag)
            elif compressor_enabled:
                while not self.compressor_ready:
                    pass

                self.effects_bin.insert_after(self.highpass.bin,
                                              self.compressor.bin,
                                              self.on_highpass_added,
                                              self.log_tag)
            elif panorama_enabled:
                while not self.panorama_ready:
                    pass

                self.effects_bin.insert_after(self.highpass.bin,
                                              self.panorama.bin,
                                              self.on_highpass_added,
                                              self.log_tag)
            elif limiter_enabled:
                while not self.limiter_ready:
                    pass

                self.effects_bin.insert_after(self.highpass.bin,
                                              self.limiter.bin,
                                              self.on_highpass_added,
                                              self.log_tag)
            else:
                self.effects_bin.prepend(self.highpass.bin,
                                         self.on_highpass_added, self.log_tag)
        else:
            self.effects_bin.remove(self.highpass.bin, self.on_filter_removed,
                                    self.log_tag)

    def on_lowpass_enable(self, obj, state):
        self.lowpass_ready = False

        if state:
            limiter_enabled = self.settings.get_value('limiter-state').unpack()
            panorama_enabled = self.settings.get_value(
                'panorama-state').unpack()
            compressor_enabled = self.settings.get_value(
                'compressor-state').unpack()
            reverb_enabled = self.settings.get_value('reverb-state').unpack()
            highpass_enabled = self.settings.get_value(
                'highpass-state').unpack()

            if highpass_enabled:
                while not self.highpass_ready:
                    pass

                self.effects_bin.insert_after(self.lowpass.bin,
                                              self.highpass.bin,
                                              self.on_lowpass_added,
                                              self.log_tag)
            elif reverb_enabled:
                while not self.reverb_ready:
                    pass

                self.effects_bin.insert_after(self.lowpass.bin,
                                              self.reverb.bin,
                                              self.on_lowpass_added,
                                              self.log_tag)
            elif compressor_enabled:
                while not self.compressor_ready:
                    pass

                self.effects_bin.insert_after(self.lowpass.bin,
                                              self.compressor.bin,
                                              self.on_lowpass_added,
                                              self.log_tag)
            elif panorama_enabled:
                while not self.panorama_ready:
                    pass

                self.effects_bin.insert_after(self.lowpass.bin,
                                              self.panorama.bin,
                                              self.on_lowpass_added,
                                              self.log_tag)
            elif limiter_enabled:
                while not self.limiter_ready:
                    pass

                self.effects_bin.insert_after(self.lowpass.bin,
                                              self.limiter.bin,
                                              self.on_lowpass_added,
                                              self.log_tag)
            else:
                self.effects_bin.prepend(self.lowpass.bin,
                                         self.on_lowpass_added, self.log_tag)
        else:
            self.effects_bin.remove(self.lowpass.bin, self.on_filter_removed,
                                    self.log_tag)

    def on_equalizer_enable(self, obj, state):
        self.equalizer_ready = False

        if state:
            limiter_enabled = self.settings.get_value('limiter-state').unpack()
            panorama_enabled = self.settings.get_value(
                'panorama-state').unpack()
            compressor_enabled = self.settings.get_value(
                'compressor-state').unpack()
            reverb_enabled = self.settings.get_value('reverb-state').unpack()
            highpass_enabled = self.settings.get_value(
                'highpass-state').unpack()
            lowpass_enabled = self.settings.get_value('lowpass-state').unpack()

            if lowpass_enabled:
                while not self.lowpass_ready:
                    pass

                self.effects_bin.insert_after(self.equalizer.bin,
                                              self.lowpass.bin,
                                              self.on_equalizer_added,
                                              self.log_tag)
            elif highpass_enabled:
                while not self.highpass_ready:
                    pass

                self.effects_bin.insert_after(self.equalizer.bin,
                                              self.highpass.bin,
                                              self.on_equalizer_added,
                                              self.log_tag)
            elif reverb_enabled:
                while not self.reverb_ready:
                    pass

                self.effects_bin.insert_after(self.equalizer.bin,
                                              self.reverb.bin,
                                              self.on_equalizer_added,
                                              self.log_tag)
            elif compressor_enabled:
                while not self.compressor_ready:
                    pass

                self.effects_bin.insert_after(self.equalizer.bin,
                                              self.compressor.bin,
                                              self.on_equalizer_added,
                                              self.log_tag)
            elif panorama_enabled:
                while not self.panorama_ready:
                    pass

                self.effects_bin.insert_after(self.equalizer.bin,
                                              self.panorama.bin,
                                              self.on_equalizer_added,
                                              self.log_tag)
            elif limiter_enabled:
                while not self.limiter_ready:
                    pass

                self.effects_bin.insert_after(self.equalizer.bin,
                                              self.limiter.bin,
                                              self.on_equalizer_added,
                                              self.log_tag)
            else:
                self.effects_bin.prepend(self.equalizer.bin,
                                         self.on_equalizer_added, self.log_tag)
        else:
            self.effects_bin.remove(self.equalizer.bin, self.on_filter_removed,
                                    self.log_tag)

    def on_panorama_added(self, bin, element, success, user_data):
        bin_name = element.get_name()
        plugin_name = bin_name.split('_')[0]

        if success:
            self.panorama_ready = True
            self.log.info(user_data + plugin_name + ' plugin was enabled')
        else:
            self.log.critical(user_data + 'failed to enable ' + plugin_name)

    def reset(self):
        self.limiter.reset()
        self.panorama.reset()
        self.compressor.reset()
        self.reverb.reset()
        self.highpass.reset()
        self.lowpass.reset()
        self.equalizer.reset()