Add a checkbutton for disabling volume meters because of high CPU utilisation when updating them --- src/mainwindow.cc | 52 +++++++++++- src/mainwindow.h | 2 + src/minimalstreamwidget.cc | 19 ++++- src/minimalstreamwidget.h | 6 ++ src/pavucontrol.glade | 195 ++++++++++++++++++++++++++------------------- src/streamwidget.cc | 1 - src/streamwidget.h | 1 - 7 files changed, 190 insertions(+), 86 deletions(-) diff --git a/src/mainwindow.cc b/src/mainwindow.cc index 5a42318..7458039 100644 --- a/src/mainwindow.cc +++ b/src/mainwindow.cc @@ -93,6 +93,7 @@ MainWindow::MainWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder> x->get_widget("sinkTypeComboBox", sinkTypeComboBox); x->get_widget("sourceTypeComboBox", sourceTypeComboBox); x->get_widget("notebook", notebook); + x->get_widget("showVolumeMetersCheckButton", showVolumeMetersCheckButton); cardsVBox->set_reallocate_redraws(true); sourcesVBox->set_reallocate_redraws(true); @@ -109,6 +110,8 @@ MainWindow::MainWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder> sourceOutputTypeComboBox->signal_changed().connect(sigc::mem_fun(*this, &MainWindow::onSourceOutputTypeComboBoxChanged)); sinkTypeComboBox->signal_changed().connect(sigc::mem_fun(*this, &MainWindow::onSinkTypeComboBoxChanged)); sourceTypeComboBox->signal_changed().connect(sigc::mem_fun(*this, &MainWindow::onSourceTypeComboBoxChanged)); + showVolumeMetersCheckButton->signal_toggled().connect(sigc::mem_fun(*this, &MainWindow::onShowVolumeMetersCheckButtonToggled)); + GKeyFile* config = g_key_file_new(); g_assert(config); @@ -120,6 +123,10 @@ MainWindow::MainWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder> if (g_key_file_load_from_file (config, m_config_filename, flags, &err)) { int width = g_key_file_get_integer(config, "window", "width", NULL); int height = g_key_file_get_integer(config, "window", "height", NULL); + /* When upgrading from a previous version, set showVolumeMeters to TRUE (default from glade file), so users don't complain about missing volume meters. */ + if(g_key_file_has_key(config, "window", "showVolumeMeters", NULL)) { + showVolumeMetersCheckButton->set_active(g_key_file_get_boolean(config, "window", "showVolumeMeters", NULL)); + } int default_width, default_height; get_default_size(default_width, default_height); @@ -202,6 +209,7 @@ MainWindow::~MainWindow() { get_size(width, height); g_key_file_set_integer(config, "window", "width", width); g_key_file_set_integer(config, "window", "height", height); + g_key_file_set_integer(config, "window", "showVolumeMeters", showVolumeMetersCheckButton->get_active()); gsize filelen; GError *err = NULL; @@ -421,6 +429,7 @@ bool MainWindow::updateSink(const pa_sink_info &info) { is_new = true; w->setBaseVolume(info.base_volume); + w->setVolumeMeterVisible(showVolumeMetersCheckButton->get_active()); } w->updating = true; @@ -482,6 +491,7 @@ static void suspended_callback(pa_stream *s, void *userdata) { } static void read_callback(pa_stream *s, size_t length, void *userdata) { + printf("read from stream %p\n", s); MainWindow *w = static_cast<MainWindow*>(userdata); const void *data; double v; @@ -535,7 +545,8 @@ pa_stream* MainWindow::createMonitorStreamForSource(uint32_t source_idx, uint32_ pa_stream_set_suspended_callback(s, suspended_callback, this); flags = (pa_stream_flags_t) (PA_STREAM_DONT_MOVE | PA_STREAM_PEAK_DETECT | PA_STREAM_ADJUST_LATENCY | - (suspend ? PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND : PA_STREAM_NOFLAGS)); + (suspend ? PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND : PA_STREAM_NOFLAGS) | + (!showVolumeMetersCheckButton->get_active() ? PA_STREAM_START_CORKED : PA_STREAM_NOFLAGS)); if (pa_stream_connect_record(s, t, &attr, flags) < 0) { show_error(_("Failed to connect monitoring stream")); @@ -574,9 +585,10 @@ void MainWindow::updateSource(const pa_source_info &info) { is_new = true; w->setBaseVolume(info.base_volume); + w->setVolumeMeterVisible(showVolumeMetersCheckButton->get_active()); if (pa_context_get_server_protocol_version(get_context()) >= 13) - createMonitorStreamForSource(info.index, -1, !!(info.flags & PA_SOURCE_NETWORK)); + w->peak = createMonitorStreamForSource(info.index, -1, !!(info.flags & PA_SOURCE_NETWORK)); } w->updating = true; @@ -689,6 +701,7 @@ void MainWindow::updateSinkInput(const pa_sink_input_info &info) { w->index = info.index; w->clientIndex = info.client; is_new = true; + w->setVolumeMeterVisible(showVolumeMetersCheckButton->get_active()); if (pa_context_get_server_protocol_version(get_context()) >= 13) createMonitorStreamForSinkInput(w, info.sink); @@ -746,6 +759,7 @@ void MainWindow::updateSourceOutput(const pa_source_output_info &info) { w->index = info.index; w->clientIndex = info.client; is_new = true; + w->setVolumeMeterVisible(showVolumeMetersCheckButton->get_active()); } w->updating = true; @@ -1220,3 +1234,37 @@ void MainWindow::onSourceOutputTypeComboBoxChanged() { updateDeviceVisibility(); } + + +void MainWindow::onShowVolumeMetersCheckButtonToggled() { + bool state = showVolumeMetersCheckButton->get_active(); + printf("toggled %d\n", state); + for (std::map<uint32_t, SinkWidget*>::iterator it = sinkWidgets.begin() ; it != sinkWidgets.end(); it++) { + SinkWidget *sw = it->second; + if(sw->peak) { + pa_stream_cork(sw->peak, (int)!state, NULL, NULL); + } + sw->setVolumeMeterVisible(state); + } + for (std::map<uint32_t, SourceWidget*>::iterator it = sourceWidgets.begin() ; it != sourceWidgets.end(); it++) { + SourceWidget *sw = it->second; + if(sw->peak) { + pa_stream_cork(sw->peak, (int)!state, NULL, NULL); + } + sw->setVolumeMeterVisible(state); + } + for (std::map<uint32_t, SinkInputWidget*>::iterator it = sinkInputWidgets.begin() ; it != sinkInputWidgets.end(); it++) { + SinkInputWidget *sw = it->second; + if(sw->peak) { + pa_stream_cork(sw->peak, (int)!state, NULL, NULL); + } + sw->setVolumeMeterVisible(state); + } + for (std::map<uint32_t, SourceOutputWidget*>::iterator it = sourceOutputWidgets.begin() ; it != sourceOutputWidgets.end(); it++) { + SourceOutputWidget *sw = it->second; + if(sw->peak) { + pa_stream_cork(sw->peak, (int)!state, NULL, NULL); + } + sw->setVolumeMeterVisible(state); + } +} diff --git a/src/mainwindow.h b/src/mainwindow.h index 5c501f7..30e1ad0 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -68,6 +68,7 @@ public: Gtk::VBox *streamsVBox, *recsVBox, *sinksVBox, *sourcesVBox, *cardsVBox; Gtk::Label *noStreamsLabel, *noRecsLabel, *noSinksLabel, *noSourcesLabel, *noCardsLabel, *connectingLabel; Gtk::ComboBox *sinkInputTypeComboBox, *sourceOutputTypeComboBox, *sinkTypeComboBox, *sourceTypeComboBox; + Gtk::CheckButton *showVolumeMetersCheckButton; std::map<uint32_t, CardWidget*> cardWidgets; std::map<uint32_t, SinkWidget*> sinkWidgets; @@ -85,6 +86,7 @@ public: virtual void onSourceOutputTypeComboBoxChanged(); virtual void onSinkTypeComboBoxChanged(); virtual void onSourceTypeComboBoxChanged(); + virtual void onShowVolumeMetersCheckButtonToggled(); void setConnectionState(gboolean connected); void updateDeviceVisibility(); diff --git a/src/minimalstreamwidget.cc b/src/minimalstreamwidget.cc index 562739d..d1f26e1 100644 --- a/src/minimalstreamwidget.cc +++ b/src/minimalstreamwidget.cc @@ -29,8 +29,10 @@ MinimalStreamWidget::MinimalStreamWidget(BaseObjectType* cobject, const Glib::Re Gtk::VBox(cobject), peakProgressBar(), lastPeak(0), + peak(NULL), updating(false), - volumeMeterEnabled(false) { + volumeMeterEnabled(false), + volumeMeterVisible(true) { x->get_widget("channelsVBox", channelsVBox); x->get_widget("nameLabel", nameLabel); @@ -69,6 +71,19 @@ void MinimalStreamWidget::enableVolumeMeter() { return; volumeMeterEnabled = true; - peakProgressBar.show(); + if(volumeMeterVisible) { + peakProgressBar.show(); + } } +void MinimalStreamWidget::setVolumeMeterVisible(bool v) { + volumeMeterVisible=v; + if(v) { + if(volumeMeterEnabled) { + peakProgressBar.show(); + } + } + else { + peakProgressBar.hide(); + } +} diff --git a/src/minimalstreamwidget.h b/src/minimalstreamwidget.h index 7d5ee24..8bfc5bc 100644 --- a/src/minimalstreamwidget.h +++ b/src/minimalstreamwidget.h @@ -32,6 +32,7 @@ public: Gtk::Image *iconImage; Gtk::ProgressBar peakProgressBar; double lastPeak; + pa_stream *peak; bool updating; @@ -41,6 +42,11 @@ public: bool volumeMeterEnabled; void enableVolumeMeter(); void updatePeak(double v); + void setVolumeMeterVisible(bool v); + +private : + bool volumeMeterVisible; + }; #endif diff --git a/src/pavucontrol.glade b/src/pavucontrol.glade index 5116632..725a1dc 100644 --- a/src/pavucontrol.glade +++ b/src/pavucontrol.glade @@ -7,6 +7,66 @@ <property name="value">44.2408370972</property> <property name="step_increment">5</property> </object> + <object class="GtkWindow" id="channelWindow"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="title" translatable="yes">window2</property> + <child> + <object class="GtkHBox" id="channelWidget"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="channelLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="yalign">0</property> + <property name="label" translatable="yes"><b>left-front</b></property> + <property name="use_markup">True</property> + <property name="width_chars">15</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkHScale" id="volumeScale"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="adjustment">adjustment1</property> + <property name="digits">0</property> + <property name="draw_value">False</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="volumeLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="yalign">0</property> + <property name="xpad">8</property> + <property name="label" translatable="yes"><small>50%</small></property> + <property name="use_markup">True</property> + <property name="justify">right</property> + <property name="width_chars">9</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">2</property> + </packing> + </child> + </object> + </child> + </object> <object class="GtkWindow" id="cardWindow"> <property name="visible">True</property> <property name="can_focus">False</property> @@ -137,66 +197,6 @@ </object> </child> </object> - <object class="GtkWindow" id="channelWindow"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="title" translatable="yes">window2</property> - <child> - <object class="GtkHBox" id="channelWidget"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="channelLabel"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="xalign">0</property> - <property name="yalign">0</property> - <property name="label" translatable="yes"><b>left-front</b></property> - <property name="use_markup">True</property> - <property name="width_chars">15</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkHScale" id="volumeScale"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="adjustment">adjustment1</property> - <property name="digits">0</property> - <property name="draw_value">False</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="volumeLabel"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="xalign">1</property> - <property name="yalign">0</property> - <property name="xpad">8</property> - <property name="label" translatable="yes"><small>50%</small></property> - <property name="use_markup">True</property> - <property name="justify">right</property> - <property name="width_chars">9</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - </object> - </child> - </object> <object class="GtkWindow" id="deviceWindow"> <property name="visible">True</property> <property name="can_focus">False</property> @@ -278,7 +278,6 @@ <property name="spacing">3</property> <child> <object class="GtkToggleButton" id="muteToggleButton"> - <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> @@ -301,7 +300,6 @@ </child> <child> <object class="GtkToggleButton" id="lockToggleButton"> - <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> @@ -325,7 +323,6 @@ </child> <child> <object class="GtkToggleButton" id="defaultToggleButton"> - <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> @@ -430,7 +427,6 @@ <child> <object class="GtkCheckButton" id="encodingFormatPCM"> <property name="label" translatable="yes">PCM</property> - <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="sensitive">False</property> <property name="can_focus">True</property> @@ -442,7 +438,6 @@ <child> <object class="GtkCheckButton" id="encodingFormatAC3"> <property name="label" translatable="yes">AC3</property> - <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> @@ -456,7 +451,6 @@ <child> <object class="GtkCheckButton" id="encodingFormatDTS"> <property name="label" translatable="yes">DTS</property> - <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> @@ -470,7 +464,6 @@ <child> <object class="GtkCheckButton" id="encodingFormatEAC3"> <property name="label" translatable="yes">EAC3</property> - <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> @@ -484,7 +477,6 @@ <child> <object class="GtkCheckButton" id="encodingFormatMPEG"> <property name="label" translatable="yes">MPEG</property> - <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> @@ -500,7 +492,6 @@ <child> <object class="GtkCheckButton" id="encodingFormatAAC"> <property name="label" translatable="yes">AAC</property> - <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> @@ -698,7 +689,6 @@ <object class="GtkVBox" id="vbox20"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="border_width">12</property> <property name="spacing">12</property> <child> <object class="GtkNotebook" id="notebook"> @@ -1194,18 +1184,29 @@ <property name="can_focus">False</property> <property name="shadow_type">none</property> <child> - <object class="GtkVBox" id="cardsVBox"> + <object class="GtkVBox" id="vbox3"> <property name="visible">True</property> <property name="can_focus">False</property> <child> - <object class="GtkLabel" id="noCardsLabel"> + <object class="GtkVBox" id="cardsVBox"> <property name="visible">True</property> - <property name="sensitive">False</property> <property name="can_focus">False</property> - <property name="xpad">16</property> - <property name="ypad">16</property> - <property name="label" translatable="yes"><i>No cards available for configuration</i></property> - <property name="use_markup">True</property> + <child> + <object class="GtkLabel" id="noCardsLabel"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_focus">False</property> + <property name="xpad">16</property> + <property name="ypad">16</property> + <property name="label" translatable="yes"><i>No cards available for configuration</i></property> + <property name="use_markup">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> </object> <packing> <property name="expand">True</property> @@ -1213,6 +1214,43 @@ <property name="position">0</property> </packing> </child> + <child> + <object class="GtkVBox" id="vbox4"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkHSeparator" id="hseparator1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="showVolumeMetersCheckButton"> + <property name="label" translatable="yes">Show volume meters</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="active">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> </object> </child> </object> @@ -1412,7 +1450,6 @@ <child> <object class="GtkButton" id="deviceButton"> <property name="label" translatable="yes">Device</property> - <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> @@ -1440,7 +1477,6 @@ <property name="spacing">3</property> <child> <object class="GtkToggleButton" id="muteToggleButton"> - <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> @@ -1463,7 +1499,6 @@ </child> <child> <object class="GtkToggleButton" id="lockToggleButton"> - <property name="use_action_appearance">False</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> diff --git a/src/streamwidget.cc b/src/streamwidget.cc index 94363ec..9492f4b 100644 --- a/src/streamwidget.cc +++ b/src/streamwidget.cc @@ -31,7 +31,6 @@ /*** StreamWidget ***/ StreamWidget::StreamWidget(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& x) : MinimalStreamWidget(cobject, x), - peak(NULL), mpMainWindow(NULL) { x->get_widget("lockToggleButton", lockToggleButton); diff --git a/src/streamwidget.h b/src/streamwidget.h index b797ec5..160dc52 100644 --- a/src/streamwidget.h +++ b/src/streamwidget.h @@ -43,7 +43,6 @@ public: pa_channel_map channelMap; pa_cvolume volume; - pa_stream *peak; ChannelWidget *channelWidgets[PA_CHANNELS_MAX]; -- 2.0.2