class Application(Gtk.Application): def __init__(self): app_id = 'com.github.wwmm.pulseeffects' app_flags = Gio.ApplicationFlags.HANDLES_COMMAND_LINE GLib.set_application_name('PulseEffects') GLib.setenv('PULSE_PROP_media.role', 'production', True) GLib.setenv('PULSE_PROP_application.icon_name', 'pulseeffects', True) Gtk.Application.__init__(self, application_id=app_id, flags=app_flags) self.add_main_option('no-window', ord('n'), GLib.OptionFlags.NONE, GLib.OptionArg.NONE, 'do not show window', None) def do_startup(self): Gtk.Application.do_startup(self) self.ui_initialized = False self.module_path = os.path.dirname(__file__) log_format = '%(asctime)s.%(msecs)d - %(name)s - %(levelname)s' log_format = log_format + ' - %(message)s' logging.basicConfig(format=log_format, datefmt='%H:%M:%S', level=logging.INFO) self.log = logging.getLogger('PulseEffects') self.gtk_settings = Gtk.Settings.get_default() self.settings = Gio.Settings('com.github.wwmm.pulseeffects') # creating user presets folder self.user_config_dir = os.path.join(GLib.get_user_config_dir(), 'PulseEffects') os.makedirs(self.user_config_dir, exist_ok=True) # pulseaudio self.pm = PulseManager() self.pm.load_apps_sink() self.pm.load_mic_sink() # ui initializations self.builder = Gtk.Builder() self.builder.add_from_file(self.module_path + '/ui/main_ui.glade') self.builder.connect_signals(self) self.window = self.builder.get_object('MainWindow') self.server_info_label = self.builder.get_object('server_info_label') self.window.set_application(self) self.create_appmenu() # gstreamer sink input effects self.sie = SinkInputEffects(self.pm.default_sink_rate) self.sie.set_source_monitor_name(self.pm.apps_sink_monitor_name) self.sie.set_output_sink_name(self.pm.default_sink_name) # gstreamer source outputs effects self.soe = SourceOutputEffects(self.pm.default_source_rate) self.soe.set_source_monitor_name(self.pm.default_source_name) self.soe.set_output_sink_name('PulseEffects_mic') self.draw_spectrum = DrawSpectrum(self) self.init_theme() self.init_settings_menu() self.init_buffer_time() self.init_latency_time() self.list_sink_inputs = ListSinkInputs(self.sie, self.pm) self.list_source_outputs = ListSourceOutputs(self.soe, self.pm) self.list_sink_inputs.connect('app_removed', self.on_app_removed) self.list_source_outputs.connect('app_removed', self.on_app_removed) self.init_spectrum_widgets() self.init_stack_widgets() # this connection is changed inside the stack switch handler # depending on the selected child. The connection below is not # permanent but just a default self.spectrum_handler_id = self.sie.connect( 'new_spectrum', self.draw_spectrum.on_new_spectrum) # searching for apps self.pm.find_sink_inputs() self.pm.find_source_outputs() def do_activate(self): self.window.present() self.ui_initialized = True def do_command_line(self, command_line): options = command_line.get_options_dict() if options.contains("no-window"): self.log.info('Running as a background service') else: self.activate() return 0 def do_shutdown(self): Gtk.Application.do_shutdown(self) self.sie.set_state('null') self.soe.set_state('null') self.pm.exit() def create_appmenu(self): menu = Gio.Menu() menu.append('About', 'app.about') menu.append('Quit', 'app.quit') self.set_app_menu(menu) about_action = Gio.SimpleAction.new('about', None) about_action.connect('activate', self.onAbout) self.add_action(about_action) quit_action = Gio.SimpleAction.new('quit', None) quit_action.connect('activate', lambda action, parameter: self.quit()) self.add_action(quit_action) def init_theme(self): switch = self.builder.get_object('theme_switch') use_dark = self.settings.get_value('use-dark-theme').unpack() switch.set_active(use_dark) def on_theme_switch_state_set(self, obj, state): self.gtk_settings.props.gtk_application_prefer_dark_theme = state out = GLib.Variant('b', state) self.settings.set_value('use-dark-theme', out) def init_stack_widgets(self): self.stack = self.builder.get_object('stack') self.stack.add_named(self.sie.ui_window, 'sink_inputs') self.stack.child_set_property(self.sie.ui_window, 'icon-name', 'audio-speakers-symbolic') self.stack.add_named(self.soe.ui_window, "source_outputs") self.stack.child_set_property(self.soe.ui_window, 'icon-name', 'audio-input-microphone-symbolic') self.stack_current_child_name = 'sink_inputs' server_info = str(self.pm.default_sink_format) + ', ' + \ '{:.1f}'.format(round( self.pm.default_sink_rate / 1000.0, 1)) + ' kHz' self.server_info_label.set_text(server_info) def on_visible_child_changed(stack, visible_child): name = stack.get_visible_child_name() if name == 'sink_inputs': if self.stack_current_child_name == 'source_outputs': self.soe.disconnect(self.spectrum_handler_id) self.spectrum_handler_id = self.sie.connect( 'new_spectrum', self.draw_spectrum.on_new_spectrum) self.stack_current_child_name = 'sink_inputs' server_info = str(self.pm.default_sink_format) + ', ' + \ '{:.1f}'.format(round( self.pm.default_sink_rate / 1000.0, 1)) + ' kHz' self.server_info_label.set_text(server_info) elif name == 'source_outputs': if self.stack_current_child_name == 'sink_inputs': self.sie.disconnect(self.spectrum_handler_id) self.spectrum_handler_id = self.soe.connect( 'new_spectrum', self.draw_spectrum.on_new_spectrum) self.stack_current_child_name = 'source_outputs' server_info = str(self.pm.default_source_format) + ', ' + \ '{:.1f}'.format(round( self.pm.default_source_rate / 1000.0, 1)) + ' kHz' self.server_info_label.set_text(server_info) self.draw_spectrum.clear() self.stack.connect("notify::visible-child", on_visible_child_changed) def init_settings_menu(self): button = self.builder.get_object('settings_popover_button') menu = self.builder.get_object('settings_menu') popover = Gtk.Popover.new(button) popover.props.transitions_enabled = True popover.add(menu) def button_clicked(arg): if popover.get_visible(): popover.hide() else: popover.show_all() button.connect("clicked", button_clicked) def init_buffer_time(self): value = self.settings.get_value('buffer-time').unpack() buffer_time = self.builder.get_object('buffer_time') buffer_time.set_value(value) self.sie.init_buffer_time(value * 1000) self.soe.init_buffer_time(value * 1000) def on_buffer_time_value_changed(self, obj): value = obj.get_value() out = GLib.Variant('i', value) self.settings.set_value('buffer-time', out) if self.ui_initialized: self.sie.set_buffer_time(value * 1000) self.soe.set_buffer_time(value * 1000) else: self.sie.init_buffer_time(value * 1000) self.soe.init_buffer_time(value * 1000) def init_latency_time(self): value = self.settings.get_value('latency-time').unpack() latency_time = self.builder.get_object('latency_time') latency_time.set_value(value) self.sie.init_latency_time(value * 1000) # self.soe.init_latency_time(value * 1000) def on_latency_time_value_changed(self, obj): value = obj.get_value() out = GLib.Variant('i', value) self.settings.set_value('latency-time', out) if self.ui_initialized: self.sie.set_latency_time(value * 1000) # self.soe.set_latency_time(value * 1000) else: self.sie.init_latency_time(value * 1000) # self.soe.init_latency_time(value * 1000) def init_spectrum_widgets(self): show_spectrum_switch = self.builder.get_object('show_spectrum') spectrum_n_points_obj = self.builder.get_object('spectrum_n_points') show_spectrum = self.settings.get_value('show-spectrum').unpack() spectrum_n_points = self.settings.get_value( 'spectrum-n-points').unpack() show_spectrum_switch.set_active(show_spectrum) spectrum_n_points_obj.set_value(spectrum_n_points) self.sie.set_spectrum_n_points(spectrum_n_points) self.soe.set_spectrum_n_points(spectrum_n_points) if show_spectrum: self.draw_spectrum.show() else: self.draw_spectrum.hide() def on_show_spectrum_state_set(self, obj, state): if state: self.draw_spectrum.show() self.sie.enable_spectrum(True) self.soe.enable_spectrum(True) else: self.sie.enable_spectrum(False) self.soe.enable_spectrum(False) self.draw_spectrum.hide() out = GLib.Variant('b', state) self.settings.set_value('show-spectrum', out) def on_spectrum_n_points_value_changed(self, obj): value = obj.get_value() out = GLib.Variant('i', value) self.settings.set_value('spectrum-n-points', out) self.sie.set_spectrum_n_points(value) self.soe.set_spectrum_n_points(value) def on_app_removed(self, obj): self.window.resize(1, 1) def on_reset_all_settings_clicked(self, obj): self.settings.reset('buffer-time') self.settings.reset('latency-time') self.settings.reset('show-spectrum') self.settings.reset('spectrum-n-points') self.settings.reset('use-dark-theme') self.init_theme() self.init_buffer_time() self.init_latency_time() self.init_spectrum_widgets() self.stack.set_visible_child(self.sie.ui_window) self.sie.reset() self.soe.reset() def add_file_filter(self, dialog): file_filter = Gtk.FileFilter() file_filter.set_name("preset") file_filter.add_mime_type("text/plain") dialog.add_filter(file_filter) def on_save_user_preset_clicked(self, obj): dialog = Gtk.FileChooserDialog( '', self.window, Gtk.FileChooserAction.SAVE, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE, Gtk.ResponseType.OK)) dialog.set_current_folder(self.user_config_dir) dialog.set_current_name('user.preset') self.add_file_filter(dialog) response = dialog.run() if response == Gtk.ResponseType.OK: path = dialog.get_filename() if not path.endswith(".preset"): path += ".preset" s = SavePresets(path) s.save_sink_inputs_presets(self.sie.settings) s.save_source_outputs_presets(self.soe.settings) s.write_config() dialog.destroy() def on_load_user_preset_clicked(self, obj): dialog = Gtk.FileChooserDialog( '', self.window, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) dialog.set_current_folder(self.user_config_dir) self.add_file_filter(dialog) response = dialog.run() if response == Gtk.ResponseType.OK: path = dialog.get_filename() l = LoadPresets(path) l.load_sink_inputs_presets(self.sie.settings) l.load_source_outputs_presets(self.soe.settings) dialog.destroy() def onAbout(self, action, parameter): builder = Gtk.Builder() builder.add_from_file(self.module_path + '/ui/about.glade') dialog = builder.get_object('about_dialog') dialog.set_transient_for(self.window) dialog.run() dialog.destroy()
class Application(Gtk.Application): def __init__(self): app_id = 'com.github.wwmm.pulseeffects' app_flags = Gio.ApplicationFlags.HANDLES_COMMAND_LINE GLib.set_application_name('PulseEffects') GLib.setenv('PULSE_PROP_application.icon_name', 'pulseeffects', True) GLib.setenv('PULSE_PROP_application.id', 'com.github.wwmm.pulseeffects', True) GLib.setenv('PULSE_PROP_application.version', '3.2.1', True) Gtk.Application.__init__(self, application_id=app_id, flags=app_flags) GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, 2, self.quit) # sigint help_msg = _('Quit PulseEffects. Useful when running in service mode.') self.add_main_option('quit', ord('q'), GLib.OptionFlags.NONE, GLib.OptionArg.NONE, help_msg, None) help_msg = _('Show available presets.') self.add_main_option('presets', ord('p'), GLib.OptionFlags.NONE, GLib.OptionArg.NONE, help_msg, None) help_msg = _('Load a preset. Example: pulseeffects -l music') self.add_main_option('load-preset', ord('l'), GLib.OptionFlags.NONE, GLib.OptionArg.STRING, help_msg, None) def do_startup(self): Gtk.Application.do_startup(self) self.ui_initialized = False self.running_as_service = False self.module_path = os.path.dirname(__file__) log_format = '%(asctime)s.%(msecs)d - %(name)s - %(levelname)s' log_format = log_format + ' - %(message)s' logging.basicConfig(format=log_format, datefmt='%H:%M:%S', level=logging.INFO) self.log = logging.getLogger('PulseEffects') self.gtk_settings = Gtk.Settings.get_default() self.settings = Gio.Settings('com.github.wwmm.pulseeffects') # creating user presets folder self.user_config_dir = os.path.join(GLib.get_user_config_dir(), 'PulseEffects') os.makedirs(self.user_config_dir, exist_ok=True) # autostart file path autostart_file_name = 'autostart/pulseeffects-service.desktop' self.autostart_file = os.path.join(GLib.get_user_config_dir(), autostart_file_name) self.create_appmenu() # custom css styles self.apply_css_style('listbox.css') icon_theme = Gtk.IconTheme.get_default() icon_theme.append_search_path(self.module_path + '/ui') # pulseaudio self.pm = PulseManager() self.pm.load_apps_sink() self.pm.load_mic_sink() self.sie = SinkInputEffects(self.pm) self.soe = SourceOutputEffects(self.pm) if self.props.flags & Gio.ApplicationFlags.IS_SERVICE: self.running_as_service = True self.init_ui() self.sie.post_messages(False) self.soe.post_messages(False) self.pm.find_sink_inputs() self.pm.find_source_outputs() self.log.info(_('Running in background')) self.hold() def init_ui(self): self.builder = Gtk.Builder.new_from_file(self.module_path + '/ui/main_ui.glade') self.builder.connect_signals(self) self.window = self.builder.get_object('MainWindow') self.window.set_application(self) self.window.connect('destroy', self.on_window_destroy) image_test = self.builder.get_object('image_test') image_test.set_from_icon_name('pulseeffects-sine-symbolic', Gtk.IconSize.BUTTON) self.sie.init_ui() self.soe.init_ui() self.draw_spectrum = DrawSpectrum(self) self.init_settings_menu() self.init_buffer_time() self.init_latency_time() self.init_spectrum_widgets() self.init_stack_widgets() self.init_autostart_switch() # Gsettings bindings flag = Gio.SettingsBindFlags.DEFAULT switch_apps = self.builder.get_object('enable_all_apps') switch_theme = self.builder.get_object('theme_switch') self.settings.bind('use-dark-theme', switch_theme, 'active', flag) self.settings.bind('use-dark-theme', self.gtk_settings, 'gtk_application_prefer_dark_theme', flag) self.settings.bind('enable-all-apps', switch_apps, 'active', flag) self.settings.bind('enable-all-apps', self.sie, 'switch_on_all_apps', flag) self.settings.bind('enable-all-apps', self.soe, 'switch_on_all_apps', flag) # this connection is changed inside the stack switch handler # depending on the selected child. The connection below is not # permanent but just a default self.spectrum_handler_id = self.sie.connect( 'new_spectrum', self.draw_spectrum.on_new_spectrum) self.presets = PresetsManager(self) self.ui_initialized = True self.sie.there_is_window = True self.soe.there_is_window = True def on_window_destroy(self, window): self.ui_initialized = False self.sie.there_is_window = False self.soe.there_is_window = False if self.running_as_service: self.sie.post_messages(False) self.soe.post_messages(False) def do_activate(self): if not self.ui_initialized: self.init_ui() self.pm.find_sink_inputs() self.pm.find_source_outputs() self.window.present() self.sie.post_messages(True) self.soe.post_messages(True) def do_command_line(self, command_line): options = command_line.get_options_dict() if options.contains('quit'): self.quit() elif options.contains('presets'): self.presets.list_presets() elif options.contains('load-preset'): value = options.lookup_value('load-preset', None).unpack() self.presets.load_preset(value) else: self.do_activate() return Gtk.Application.do_command_line(self, command_line) def do_shutdown(self): Gtk.Application.do_shutdown(self) self.sie.set_state('null') self.soe.set_state('null') self.pm.exit() def create_appmenu(self): menu = Gio.Menu() menu.append('About', 'app.about') menu.append('Quit', 'app.quit') self.set_app_menu(menu) about_action = Gio.SimpleAction.new('about', None) about_action.connect('activate', self.onAbout) self.add_action(about_action) quit_action = Gio.SimpleAction.new('quit', None) quit_action.connect('activate', lambda action, parameter: self.quit()) self.add_action(quit_action) def init_stack_widgets(self): self.stack = self.builder.get_object('stack') self.stack.add_named(self.sie.ui_window, 'sink_inputs') self.stack.child_set_property(self.sie.ui_window, 'icon-name', 'audio-speakers-symbolic') self.stack.add_named(self.soe.ui_window, "source_outputs") self.stack.child_set_property(self.soe.ui_window, 'icon-name', 'audio-input-microphone-symbolic') self.stack_current_child_name = 'sink_inputs' self.stack.connect("notify::visible-child", self.on_stack_visible_child_changed) def on_stack_visible_child_changed(self, stack, visible_child): name = stack.get_visible_child_name() if name == 'sink_inputs': if self.stack_current_child_name == 'source_outputs': self.soe.disconnect(self.spectrum_handler_id) self.spectrum_handler_id = self.sie.connect( 'new_spectrum', self.draw_spectrum.on_new_spectrum) self.stack_current_child_name = 'sink_inputs' elif name == 'source_outputs': if self.stack_current_child_name == 'sink_inputs': self.sie.disconnect(self.spectrum_handler_id) self.spectrum_handler_id = self.soe.connect( 'new_spectrum', self.draw_spectrum.on_new_spectrum) self.stack_current_child_name = 'source_outputs' self.draw_spectrum.clear() def init_settings_menu(self): button = self.builder.get_object('settings_popover_button') menu = self.builder.get_object('settings_menu') popover = Gtk.Popover.new(button) popover.props.transitions_enabled = True popover.add(menu) def button_clicked(arg): if popover.get_visible(): popover.hide() else: popover.show_all() button.connect("clicked", button_clicked) def init_buffer_time(self): value = self.settings.get_value('buffer-time').unpack() buffer_time = self.builder.get_object('buffer_time') buffer_time.set_value(value) self.sie.init_buffer_time(value * 1000) def on_buffer_time_value_changed(self, obj): value = obj.get_value() out = GLib.Variant('i', value) self.settings.set_value('buffer-time', out) if self.ui_initialized: self.sie.set_buffer_time(value * 1000) else: self.sie.init_buffer_time(value * 1000) def init_latency_time(self): value = self.settings.get_value('latency-time').unpack() latency_time = self.builder.get_object('latency_time') latency_time.set_value(value) self.sie.init_latency_time(value * 1000) def on_latency_time_value_changed(self, obj): value = obj.get_value() out = GLib.Variant('i', value) self.settings.set_value('latency-time', out) if self.ui_initialized: self.sie.set_latency_time(value * 1000) else: self.sie.init_latency_time(value * 1000) def init_autostart_switch(self): switch = self.builder.get_object('enable_autostart') if os.path.isfile(self.autostart_file): switch.set_state(True) else: switch.set_state(False) def on_enable_autostart_state_set(self, obj, state): if state: with open(self.autostart_file, "w") as f: f.write('[Desktop Entry]\n') f.write('Name=PulseEffects\n') f.write('Comment=PulseEffects Service\n') f.write('Exec=pulseeffects --gapplication-service\n') f.write('Icon=pulseeffects\n') f.write('StartupNotify=false\n') f.write('Terminal=false\n') f.write('Type=Application\n') else: os.remove(self.autostart_file) def init_spectrum_widgets(self): show_spectrum_switch = self.builder.get_object('show_spectrum') spectrum_n_points_obj = self.builder.get_object('spectrum_n_points') show_spectrum = self.settings.get_value('show-spectrum').unpack() spectrum_n_points = self.settings.get_value( 'spectrum-n-points').unpack() show_spectrum_switch.set_active(show_spectrum) spectrum_n_points_obj.set_value(spectrum_n_points) self.sie.set_spectrum_n_points(spectrum_n_points) self.soe.set_spectrum_n_points(spectrum_n_points) if show_spectrum: self.draw_spectrum.show() else: self.draw_spectrum.hide() def on_show_spectrum_state_set(self, obj, state): if state: self.draw_spectrum.show() self.sie.enable_spectrum(True) self.soe.enable_spectrum(True) else: self.sie.enable_spectrum(False) self.soe.enable_spectrum(False) self.draw_spectrum.hide() out = GLib.Variant('b', state) self.settings.set_value('show-spectrum', out) def on_spectrum_n_points_value_changed(self, obj): value = obj.get_value() out = GLib.Variant('i', value) self.settings.set_value('spectrum-n-points', out) self.sie.set_spectrum_n_points(value) self.soe.set_spectrum_n_points(value) def apply_css_style(self, css_file): provider = Gtk.CssProvider() css_file = Gio.File.new_for_path(self.module_path + '/ui/' + css_file) provider.load_from_file(css_file) screen = Gdk.Screen.get_default() priority = Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION Gtk.StyleContext.add_provider_for_screen(screen, provider, priority) def on_test_clicked(self, obj): t = Test(self.pm) t.run() def on_reset_all_settings_clicked(self, obj): self.settings.reset('buffer-time') self.settings.reset('latency-time') self.settings.reset('show-spectrum') self.settings.reset('spectrum-n-points') self.settings.reset('use-dark-theme') self.settings.reset('enable-all-apps') self.init_buffer_time() self.init_latency_time() self.init_spectrum_widgets() self.stack.set_visible_child(self.sie.ui_window) self.sie.reset() self.soe.reset() def onAbout(self, action, parameter): builder = Gtk.Builder() builder.add_from_file(self.module_path + '/ui/about.glade') dialog = builder.get_object('about_dialog') dialog.set_transient_for(self.window) dialog.run() dialog.destroy()
class Application(Gtk.Application): def __init__(self): app_id = 'com.github.wwmm.pulseeffects' app_flags = Gio.ApplicationFlags.HANDLES_COMMAND_LINE GLib.set_application_name('PulseEffects') GLib.setenv('PULSE_PROP_application.icon_name', 'pulseeffects', True) GLib.setenv('PULSE_PROP_application.id', 'com.github.wwmm.pulseeffects', True) GLib.setenv('PULSE_PROP_application.version', '3.2.3', True) GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, 2, self.quit) # sigint Gtk.Application.__init__(self, application_id=app_id, flags=app_flags) help_msg = _('Quit PulseEffects. Useful when running in service mode.') self.add_main_option('quit', ord('q'), GLib.OptionFlags.NONE, GLib.OptionArg.NONE, help_msg, None) help_msg = _('Show available presets.') self.add_main_option('presets', ord('p'), GLib.OptionFlags.NONE, GLib.OptionArg.NONE, help_msg, None) help_msg = _('Load a preset. Example: pulseeffects -l music') self.add_main_option('load-preset', ord('l'), GLib.OptionFlags.NONE, GLib.OptionArg.STRING, help_msg, None) log_format = '%(asctime)s.%(msecs)d - %(name)s - %(levelname)s' log_format = log_format + ' - %(message)s' logging.basicConfig(format=log_format, datefmt='%H:%M:%S', level=logging.INFO) self.log = logging.getLogger('PulseEffects') self.log_tag = 'MAIN - ' if os.environ.get('PULSEEFFECTS_DEBUG'): self.log.setLevel(logging.DEBUG) self.log.debug(self.log_tag + 'debug logging enabled') def do_startup(self): Gtk.Application.do_startup(self) self.ui_initialized = False self.window_activated = False self.running_as_service = False self.module_path = os.path.dirname(__file__) self.sink_list = [] self.source_list = [] self.gtk_settings = Gtk.Settings.get_default() self.settings = Gio.Settings('com.github.wwmm.pulseeffects') # creating user presets folder self.user_config_dir = os.path.join(GLib.get_user_config_dir(), 'PulseEffects') os.makedirs(self.user_config_dir, exist_ok=True) # autostart file path autostart_file_name = 'autostart/pulseeffects-service.desktop' self.autostart_file = os.path.join(GLib.get_user_config_dir(), autostart_file_name) self.create_appmenu() # custom css styles self.apply_css_style('listbox.css') icon_theme = Gtk.IconTheme.get_default() icon_theme.append_search_path(self.module_path + '/ui') # pulseaudio self.pm = PulseManager() self.pm.connect('new_default_sink', self.on_new_default_sink) self.pm.connect('new_default_source', self.on_new_default_source) self.pm.connect('sink_added', self.on_sink_added) self.pm.connect('sink_removed', self.on_sink_removed) self.pm.connect('source_added', self.on_source_added) self.pm.connect('source_removed', self.on_source_removed) flag = Gio.SettingsBindFlags.DEFAULT self.settings.bind('use-default-sink', self.pm, 'use_default_sink', flag) self.settings.bind('use-default-source', self.pm, 'use_default_source', flag) # sink inputs and source outputs effects managers self.sie = SinkInputEffects(self.pm) self.soe = SourceOutputEffects(self.pm) self.settings.bind('enable-all-apps', self.sie, 'switch_on_all_apps', flag) self.settings.bind('enable-all-apps', self.soe, 'switch_on_all_apps', flag) # output effects pipeline latency self.settings.bind('buffer-out', self.sie.audio_src, 'buffer-time', flag) self.settings.bind('latency-out', self.sie.audio_src, 'latency-time', flag) self.settings.bind('buffer-out', self.sie.audio_sink, 'buffer-time', flag) self.settings.bind('latency-out', self.sie.audio_sink, 'latency-time', flag) # input effects pipeline latency self.settings.bind('buffer-in', self.soe.audio_src, 'buffer-time', flag) self.settings.bind('latency-in', self.soe.audio_src, 'latency-time', flag) self.settings.bind('buffer-in', self.soe.audio_sink, 'buffer-time', flag) self.settings.bind('latency-in', self.soe.audio_sink, 'latency-time', flag) self.presets = PresetsManager(self) if self.props.flags & Gio.ApplicationFlags.IS_SERVICE: self.running_as_service = True self.init_ui() self.sie.post_messages(False) self.soe.post_messages(False) self.pm.find_sink_inputs() self.pm.find_source_outputs() self.log.info(self.log_tag + _('Running in background')) self.hold() def init_ui(self): self.builder = Gtk.Builder.new_from_file(self.module_path + '/ui/main_ui.glade') self.builder.connect_signals(self) self.window = self.builder.get_object('MainWindow') self.window.set_application(self) self.window.connect('destroy', self.on_window_destroy) self.sie.init_ui() self.soe.init_ui() self.draw_spectrum = DrawSpectrum(self) self.init_spectrum_widgets() self.init_stack_widgets() self.init_autostart_switch() # Gsettings bindings flag = Gio.SettingsBindFlags.DEFAULT flag_invert_boolean = Gio.SettingsBindFlags.INVERT_BOOLEAN enable_all_apps = self.builder.get_object('enable_all_apps') theme_switch = self.builder.get_object('theme_switch') use_default_sink = self.builder.get_object('use_default_sink') use_default_source = self.builder.get_object('use_default_source') self.ui_output_device = self.builder.get_object('output_device') self.ui_input_device = self.builder.get_object('input_device') buffer_out = self.builder.get_object('buffer_out') latency_out = self.builder.get_object('latency_out') buffer_in = self.builder.get_object('buffer_in') latency_in = self.builder.get_object('latency_in') self.settings.bind('use-dark-theme', theme_switch, 'active', flag) self.settings.bind('use-dark-theme', self.gtk_settings, 'gtk_application_prefer_dark_theme', flag) self.settings.bind('enable-all-apps', enable_all_apps, 'active', flag) self.settings.bind('use-default-sink', use_default_sink, 'active', flag) self.settings.bind('use-default-sink', self.ui_output_device, 'sensitive', flag | flag_invert_boolean) self.settings.bind('use-default-source', use_default_source, 'active', flag) self.settings.bind('use-default-source', self.ui_input_device, 'sensitive', flag | flag_invert_boolean) self.settings.bind('buffer-out', buffer_out, 'value', flag) self.settings.bind('latency-out', latency_out, 'value', flag) self.settings.bind('buffer-in', buffer_in, 'value', flag) self.settings.bind('latency-in', latency_in, 'value', flag) # this connection is changed inside the stack switch handler # depending on the selected child. The connection below is not # permanent but just a default self.spectrum_handler_id = self.sie.connect( 'new_spectrum', self.draw_spectrum.on_new_spectrum) self.presets.load_menu() self.ui_initialized = True def on_window_destroy(self, window): self.ui_initialized = False self.window_activated = False self.sie.there_is_window = False self.soe.there_is_window = False self.sie.disconnect_streams() self.soe.disconnect_streams() if self.running_as_service: self.sie.post_messages(False) self.soe.post_messages(False) def do_activate(self): if not self.ui_initialized: self.init_ui() self.window.present() self.window_activated = True self.sie.there_is_window = True self.soe.there_is_window = True if self.running_as_service: # adding to ui devices found while in background self.update_output_dev_combobox() self.update_input_dev_combobox() self.pm.find_sink_inputs() self.pm.find_source_outputs() self.pm.find_sinks() self.pm.find_sources() self.sie.post_messages(True) self.soe.post_messages(True) def do_command_line(self, command_line): options = command_line.get_options_dict() if options.contains('quit'): self.quit() elif options.contains('presets'): self.presets.list_presets() elif options.contains('load-preset'): value = options.lookup_value('load-preset', None).unpack() self.presets.load_preset(value) else: self.do_activate() return Gtk.Application.do_command_line(self, command_line) def do_shutdown(self): Gtk.Application.do_shutdown(self) self.sie.set_state('null') self.soe.set_state('null') self.sie.pe_is_closing = True self.soe.pe_is_closing = True self.pm.exit() def create_appmenu(self): menu = Gio.Menu() menu.append('About', 'app.about') menu.append('Quit', 'app.quit') self.set_app_menu(menu) about_action = Gio.SimpleAction.new('about', None) about_action.connect('activate', self.onAbout) self.add_action(about_action) quit_action = Gio.SimpleAction.new('quit', None) quit_action.connect('activate', lambda action, parameter: self.quit()) self.add_action(quit_action) def init_stack_widgets(self): self.stack = self.builder.get_object('stack') self.stack.add_named(self.sie.ui_window, 'sink_inputs') self.stack.child_set_property(self.sie.ui_window, 'icon-name', 'audio-speakers-symbolic') self.stack.add_named(self.soe.ui_window, 'source_outputs') self.stack.child_set_property(self.soe.ui_window, 'icon-name', 'audio-input-microphone-symbolic') self.stack_current_child_name = 'sink_inputs' self.stack.connect('notify::visible-child', self.on_stack_visible_child_changed) def on_stack_visible_child_changed(self, stack, visible_child): name = stack.get_visible_child_name() if name == 'sink_inputs': if self.stack_current_child_name == 'source_outputs': self.soe.disconnect(self.spectrum_handler_id) self.spectrum_handler_id = self.sie.connect( 'new_spectrum', self.draw_spectrum.on_new_spectrum) self.stack_current_child_name = 'sink_inputs' elif name == 'source_outputs': if self.stack_current_child_name == 'sink_inputs': self.sie.disconnect(self.spectrum_handler_id) self.spectrum_handler_id = self.soe.connect( 'new_spectrum', self.draw_spectrum.on_new_spectrum) self.stack_current_child_name = 'source_outputs' self.draw_spectrum.clear() def init_autostart_switch(self): switch = self.builder.get_object('enable_autostart') if os.path.isfile(self.autostart_file): switch.set_state(True) else: switch.set_state(False) def on_enable_autostart_state_set(self, obj, state): if state: with open(self.autostart_file, 'w') as f: f.write('[Desktop Entry]\n') f.write('Name=PulseEffects\n') f.write('Comment=PulseEffects Service\n') f.write('Exec=pulseeffects --gapplication-service\n') f.write('Icon=pulseeffects\n') f.write('StartupNotify=false\n') f.write('Terminal=false\n') f.write('Type=Application\n') f.close() self.log.debug(self.log_tag + 'autostart_file created successfully') else: os.remove(self.autostart_file) self.log.debug(self.log_tag + 'autostart_file removed successfully') def init_spectrum_widgets(self): show_spectrum_switch = self.builder.get_object('show_spectrum') spectrum_n_points_obj = self.builder.get_object('spectrum_n_points') show_spectrum = self.settings.get_value('show-spectrum').unpack() spectrum_n_points = self.settings.get_value( 'spectrum-n-points').unpack() show_spectrum_switch.set_active(show_spectrum) spectrum_n_points_obj.set_value(spectrum_n_points) self.sie.set_spectrum_n_points(spectrum_n_points) self.soe.set_spectrum_n_points(spectrum_n_points) if show_spectrum: self.draw_spectrum.show() else: self.draw_spectrum.hide() def on_show_spectrum_state_set(self, obj, state): if state: self.draw_spectrum.show() self.sie.enable_spectrum(True) self.soe.enable_spectrum(True) else: self.sie.enable_spectrum(False) self.soe.enable_spectrum(False) self.draw_spectrum.hide() out = GLib.Variant('b', state) self.settings.set_value('show-spectrum', out) def on_spectrum_n_points_value_changed(self, obj): value = obj.get_value() out = GLib.Variant('i', value) self.settings.set_value('spectrum-n-points', out) self.sie.set_spectrum_n_points(value) self.soe.set_spectrum_n_points(value) def on_new_default_sink(self, obj, value): if self.ui_initialized: for s in self.sink_list: name = s['name'] if name == value: idx = self.sink_list.index(s) self.ui_output_device.set_active(idx) self.soe.set_webrtc_probe_src(name + '.monitor') else: self.sie.set_output_sink_name(value) self.soe.set_webrtc_probe_src(value + '.monitor') def on_new_default_source(self, obj, value): if self.ui_initialized: for s in self.source_list: name = s['name'] if name == self.pm.default_source_name: idx = self.source_list.index(s) self.ui_input_device.set_active(idx) else: self.soe.set_source_monitor_name(value) def update_output_dev_combobox(self): active_text = self.ui_output_device.get_active_text() use_default = self.settings.get_value('use-default-sink').unpack() self.ui_output_device.remove_all() if use_default: for s in self.sink_list: name = s['name'] self.ui_output_device.append_text(name) if name == self.pm.default_sink_name: idx = self.sink_list.index(s) self.ui_output_device.set_active(idx) else: active_is_set = False for s in self.sink_list: name = s['name'] self.ui_output_device.append_text(name) if not active_is_set: if name == active_text: idx = self.sink_list.index(s) self.ui_output_device.set_active(idx) active_is_set = True elif name == self.pm.default_sink_name: idx = self.sink_list.index(s) self.ui_output_device.set_active(idx) active_is_set = True def update_input_dev_combobox(self): active_text = self.ui_input_device.get_active_text() use_default = self.settings.get_value('use-default-source').unpack() self.ui_input_device.remove_all() if use_default: for s in self.source_list: name = s['name'] self.ui_input_device.append_text(name) if name == self.pm.default_source_name: idx = self.source_list.index(s) self.ui_input_device.set_active(idx) else: active_is_set = False for s in self.source_list: name = s['name'] self.ui_input_device.append_text(name) if not active_is_set: if name == active_text: idx = self.source_list.index(s) self.ui_input_device.set_active(idx) active_is_set = True elif name == self.pm.default_source_name: idx = self.source_list.index(s) self.ui_input_device.set_active(idx) active_is_set = True def on_sink_added(self, obj, sink): add_to_list = True for s in self.sink_list: if s['idx'] == sink['idx']: add_to_list = False break if add_to_list: self.sink_list.append(sink) self.log.debug(self.log_tag + 'added sink: ' + sink['name']) if self.ui_initialized: self.update_output_dev_combobox() def on_sink_removed(self, obj, idx): for s in self.sink_list: if s['idx'] == idx: name = s['name'] self.sink_list.remove(s) self.log.debug(self.log_tag + 'removed sink: ' + name) if self.ui_initialized: self.update_output_dev_combobox() break def on_source_added(self, obj, source): add_to_list = True for s in self.source_list: if s['idx'] == source['idx']: add_to_list = False break if add_to_list: self.source_list.append(source) self.log.debug(self.log_tag + 'added source: ' + source['name']) if self.ui_initialized: self.update_input_dev_combobox() def on_source_removed(self, obj, idx): for s in self.source_list: if s['idx'] == idx: name = s['name'] self.source_list.remove(s) self.log.debug(self.log_tag + 'removed source: ' + name) if self.ui_initialized: self.update_input_dev_combobox() break def on_use_default_sink_toggled(self, obj): state = obj.get_active() if state: for s in self.sink_list: name = s['name'] if name == self.pm.default_sink_name: idx = self.sink_list.index(s) self.ui_output_device.set_active(idx) self.log.debug(self.log_tag + 'using default sink') def on_use_default_source_toggled(self, obj): state = obj.get_active() if state: for s in self.source_list: name = s['name'] if name == self.pm.default_source_name: idx = self.source_list.index(s) self.ui_input_device.set_active(idx) self.log.debug(self.log_tag + 'using default source') def on_output_device_changed(self, obj): name = obj.get_active_text() for s in self.sink_list: if s['name'] == name: self.sie.set_output_sink_name(name) self.soe.set_webrtc_probe_src(name + '.monitor') self.log.debug(self.log_tag + 'output device changed: ' + name) def on_input_device_changed(self, obj): name = obj.get_active_text() for s in self.source_list: if s['name'] == name: self.soe.set_source_monitor_name(name) self.log.debug(self.log_tag + 'input device changed: ' + name) def apply_css_style(self, css_file): provider = Gtk.CssProvider() css_file = Gio.File.new_for_path(self.module_path + '/ui/' + css_file) provider.load_from_file(css_file) screen = Gdk.Screen.get_default() priority = Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION Gtk.StyleContext.add_provider_for_screen(screen, provider, priority) def on_test_clicked(self, obj): t = Test(self.pm) t.run() def on_reset_all_settings_clicked(self, obj): self.settings.reset('buffer-in') self.settings.reset('buffer-out') self.settings.reset('latency-in') self.settings.reset('latency-out') self.settings.reset('show-spectrum') self.settings.reset('spectrum-n-points') self.settings.reset('use-dark-theme') self.settings.reset('enable-all-apps') self.settings.reset('use-default-sink') self.settings.reset('use-default-source') self.init_spectrum_widgets() self.stack.set_visible_child(self.sie.ui_window) self.sie.reset() self.soe.reset() def onAbout(self, action, parameter): builder = Gtk.Builder() builder.add_from_file(self.module_path + '/ui/about.glade') dialog = builder.get_object('about_dialog') dialog.set_transient_for(self.window) dialog.run() dialog.destroy()
class Application(Gtk.Application): def __init__(self): app_id = 'com.github.wwmm.pulseeffects' GLib.set_application_name('PulseEffects') GLib.setenv('PULSE_PROP_media.role', 'production', True) GLib.setenv('PULSE_PROP_application.icon_name', 'pulseeffects', True) Gtk.Application.__init__(self, application_id=app_id) self.ui_initialized = False self.generating_test_signal = False self.module_path = os.path.dirname(__file__) log_format = '%(asctime)s.%(msecs)d - %(name)s - %(levelname)s' log_format = log_format + ' - %(message)s' logging.basicConfig(format=log_format, datefmt='%H:%M:%S', level=logging.INFO) self.log = logging.getLogger('PulseEffects') self.settings = Gio.Settings('com.github.wwmm.pulseeffects') # pulseaudio self.pm = PulseManager() # gstreamer audio effects self.gst = GstEffects(self.pm.default_sink_rate) self.gst.set_source_monitor_name(self.pm.sink_monitor_name) self.gst.set_output_sink_name(self.pm.default_sink_name) # creating user presets folder self.user_config_dir = os.path.expanduser('~/.config/PulseEffects') os.makedirs(self.user_config_dir, exist_ok=True) def do_startup(self): Gtk.Application.do_startup(self) self.builder = Gtk.Builder() ui_handlers = { 'on_MainWindow_delete_event': self.on_MainWindow_delete_event, 'on_buffer_time_value_changed': self.on_buffer_time_value_changed, 'on_latency_time_value_changed': self.on_latency_time_value_changed, 'on_panorama_value_changed': self.on_panorama_value_changed, 'on_save_user_preset_clicked': self.on_save_user_preset_clicked, 'on_load_user_preset_clicked': self.on_load_user_preset_clicked } self.builder.add_from_file(self.module_path + '/ui/main_ui.glade') self.builder.add_from_file(self.module_path + '/ui/headerbar.glade') headerbar = self.builder.get_object('headerbar') self.window = self.builder.get_object('MainWindow') self.window.set_titlebar(headerbar) self.window.set_application(self) self.create_appmenu() self.setup_limiter = SetupLimiter(self) self.setup_compressor = SetupCompressor(self) self.setup_reverb = SetupReverb(self) self.setup_equalizer = SetupEqualizer(self) self.test_signal = TestSignal(self) self.spectrum = Spectrum(self) self.list_apps = ListApps(self) ui_handlers.update(self.setup_limiter.handlers) ui_handlers.update(self.setup_compressor.handlers) ui_handlers.update(self.setup_reverb.handlers) ui_handlers.update(self.setup_equalizer.handlers) ui_handlers.update(self.spectrum.handlers) ui_handlers.update(self.list_apps.handlers) self.builder.connect_signals(ui_handlers) self.setup_limiter.init() self.setup_compressor.init() self.setup_reverb.init() self.setup_equalizer.init() self.test_signal.init() self.spectrum.init() self.list_apps.init() self.init_settings_menu() # buffer-time buffer_time_obj = self.builder.get_object('buffer_time') buffer_time = self.settings.get_value('buffer-time').unpack() buffer_time_obj.set_value(buffer_time) self.init_buffer_time() # latency-time latency_time_obj = self.builder.get_object('latency_time') latency_time = self.settings.get_value('latency-time').unpack() latency_time_obj.set_value(latency_time) self.init_latency_time() # stereo panorama self.panorama = self.builder.get_object('panorama') panorama_user = self.settings.get_value('panorama').unpack() self.panorama.set_value(panorama_user) self.init_panorama() # label for sink format and rate sink_rate_label = self.builder.get_object('sink_rate') sink_rate_label.set_text(self.pm.default_sink_format + ', ' + str(self.pm.default_sink_rate) + ' Hz') # now that all elements were initialized we set pipeline to ready self.gst.set_state('ready') def do_activate(self): self.window.present() self.ui_initialized = True self.pm.find_sink_inputs() def on_MainWindow_delete_event(self, event, data): self.gst.set_state('null') self.pm.unload_sink() self.pm.context_disconnect() self.quit() def create_appmenu(self): menu = Gio.Menu() menu.append('About', 'app.about') menu.append('Quit', 'app.quit') self.set_app_menu(menu) about_action = Gio.SimpleAction.new('about', None) about_action.connect('activate', self.onAbout) self.add_action(about_action) quit_action = Gio.SimpleAction.new('quit', None) quit_action.connect('activate', self.on_MainWindow_delete_event) self.add_action(quit_action) def init_settings_menu(self): button = self.builder.get_object('settings_popover_button') menu = self.builder.get_object('settings_menu') popover = Gtk.Popover.new(button) popover.props.transitions_enabled = True popover.add(menu) def button_clicked(arg): if popover.get_visible(): popover.hide() else: popover.show_all() button.connect("clicked", button_clicked) def init_buffer_time(self): value = self.settings.get_value('buffer-time').unpack() self.gst.set_buffer_time(value * 1000) def on_buffer_time_value_changed(self, obj): value = obj.get_value() out = GLib.Variant('i', value) self.settings.set_value('buffer-time', out) if self.ui_initialized: self.gst.set_buffer_time(value * 1000) else: self.gst.init_buffer_time(value * 1000) def init_latency_time(self): value = self.settings.get_value('latency-time').unpack() self.gst.set_latency_time(value * 1000) def on_latency_time_value_changed(self, obj): value = obj.get_value() out = GLib.Variant('i', value) self.settings.set_value('latency-time', out) if self.ui_initialized: self.gst.set_latency_time(value * 1000) else: self.gst.init_latency_time(value * 1000) def init_panorama(self): value = self.settings.get_value('panorama').unpack() self.gst.set_panorama(value) def on_panorama_value_changed(self, obj): value = obj.get_value() self.gst.set_panorama(value) out = GLib.Variant('d', value) self.settings.set_value('panorama', out) def add_file_filter(self, dialog): file_filter = Gtk.FileFilter() file_filter.set_name("preset") file_filter.add_mime_type("text/plain") dialog.add_filter(file_filter) def on_save_user_preset_clicked(self, obj): dialog = Gtk.FileChooserDialog('', self.window, Gtk.FileChooserAction.SAVE, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE, Gtk.ResponseType.OK)) dialog.set_current_folder(self.user_config_dir) dialog.set_current_name('user.preset') self.add_file_filter(dialog) response = dialog.run() if response == Gtk.ResponseType.OK: path = dialog.get_filename() if not path.endswith(".preset"): path += ".preset" output = open(path, 'w') config = configparser.ConfigParser() limiter = self.settings.get_value('limiter-user') config['limiter'] = {'input gain': str(limiter[0]), 'limit': str(limiter[1]), 'release time': str(limiter[2])} panorama = self.settings.get_value('panorama') config['panorama'] = {'panorama': str(panorama)} compressor = self.settings.get_value('compressor-user') config['compressor'] = {'rms-peak': str(compressor[0]), 'attack': str(compressor[1]), 'release': str(compressor[2]), 'threshold': str(compressor[3]), 'ratio': str(compressor[4]), 'knee': str(compressor[5]), 'makeup': str(compressor[6])} reverb = self.settings.get_value('reverb-user') config['reverb'] = {'room size': str(reverb[0]), 'damping': str(reverb[1]), 'width': str(reverb[2]), 'level': str(reverb[3])} equalizer_preamp = self.settings.get_value('equalizer-preamp') equalizer = self.settings.get_value('equalizer-user') equalizer_highpass_cutoff = self.settings.get_value( 'equalizer-highpass-cutoff') equalizer_highpass_poles = self.settings.get_value( 'equalizer-highpass-poles') equalizer_lowpass_cutoff = self.settings.get_value( 'equalizer-lowpass-cutoff') equalizer_lowpass_poles = self.settings.get_value( 'equalizer-lowpass-poles') config['equalizer'] = {'preamp': str(equalizer_preamp), 'band0': str(equalizer[0]), 'band1': str(equalizer[1]), 'band2': str(equalizer[2]), 'band3': str(equalizer[3]), 'band4': str(equalizer[4]), 'band5': str(equalizer[5]), 'band6': str(equalizer[6]), 'band7': str(equalizer[7]), 'band8': str(equalizer[8]), 'band9': str(equalizer[9]), 'band10': str(equalizer[10]), 'band11': str(equalizer[11]), 'band12': str(equalizer[12]), 'band13': str(equalizer[13]), 'band14': str(equalizer[14]), 'highpass_cutoff': str(equalizer_highpass_cutoff), 'highpass_poles': str(equalizer_highpass_poles), 'lowpass_cutoff': str(equalizer_lowpass_cutoff), 'lowpass_poles': str(equalizer_lowpass_poles)} config.write(output) dialog.destroy() def on_load_user_preset_clicked(self, obj): dialog = Gtk.FileChooserDialog('', self.window, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) dialog.set_current_folder(self.user_config_dir) self.add_file_filter(dialog) response = dialog.run() if response == Gtk.ResponseType.OK: path = dialog.get_filename() config = configparser.ConfigParser() config.read(path) limiter = dict(config['limiter']).values() limiter = [float(v) for v in limiter] self.setup_limiter.apply_limiter_preset(limiter) panorama_value = config.getfloat('panorama', 'panorama', fallback=0.0) self.panorama.set_value(panorama_value) compressor = dict(config['compressor']).values() compressor = [float(v) for v in compressor] self.setup_compressor.apply_compressor_preset(compressor) reverb = dict(config['reverb']).values() reverb = [float(v) for v in reverb] self.setup_reverb.apply_reverb_preset(reverb) equalizer_preamp = config.getfloat('equalizer', 'preamp') highpass_cutoff_freq = config.getint('equalizer', 'highpass_cutoff', fallback=20) highpass_poles = config.getint('equalizer', 'highpass_poles', fallback=4) lowpass_cutoff_freq = config.getint('equalizer', 'lowpass_cutoff', fallback=20000) lowpass_poles = config.getint('equalizer', 'lowpass_poles', fallback=4) equalizer_band0 = config.getfloat('equalizer', 'band0') equalizer_band1 = config.getfloat('equalizer', 'band1') equalizer_band2 = config.getfloat('equalizer', 'band2') equalizer_band3 = config.getfloat('equalizer', 'band3') equalizer_band4 = config.getfloat('equalizer', 'band4') equalizer_band5 = config.getfloat('equalizer', 'band5') equalizer_band6 = config.getfloat('equalizer', 'band6') equalizer_band7 = config.getfloat('equalizer', 'band7') equalizer_band8 = config.getfloat('equalizer', 'band8') equalizer_band9 = config.getfloat('equalizer', 'band9') equalizer_band10 = config.getfloat('equalizer', 'band10') equalizer_band11 = config.getfloat('equalizer', 'band11') equalizer_band12 = config.getfloat('equalizer', 'band12') equalizer_band13 = config.getfloat('equalizer', 'band13') equalizer_band14 = config.getfloat('equalizer', 'band14') equalizer_bands = [equalizer_band0, equalizer_band1, equalizer_band2, equalizer_band3, equalizer_band4, equalizer_band5, equalizer_band6, equalizer_band7, equalizer_band8, equalizer_band9, equalizer_band10, equalizer_band11, equalizer_band12, equalizer_band13, equalizer_band14] self.setup_equalizer.eq_preamp.set_value(equalizer_preamp) self.setup_equalizer.apply_eq_preset(equalizer_bands) self.setup_equalizer.eq_highpass_cutoff_freq.set_value( highpass_cutoff_freq) self.setup_equalizer.eq_highpass_poles.set_value(highpass_poles) self.setup_equalizer.eq_lowpass_cutoff_freq.set_value( lowpass_cutoff_freq) self.setup_equalizer.eq_lowpass_poles.set_value(lowpass_poles) dialog.destroy() def onAbout(self, action, parameter): builder = Gtk.Builder() builder.add_from_file(self.module_path + '/ui/about.glade') dialog = builder.get_object('about_dialog') dialog.set_transient_for(self.window) dialog.run() dialog.destroy()