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()
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)
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()