[pulseaudio-discuss] [PATCH] Add checkbutton for disabling volume meters
Lukas Kramer
lu at 0x83.eu
Tue Jan 13 14:20:02 PST 2015
I've been asked to provide some information on my setup:
Video driver: xf86-video-ati, GPU is an ATI mobility radeon X600, I'm
not using compositing
High CPU utilisation also on another machine using proprietary nvidia driver
On 20/07/14 20:33, Lukas K wrote:
> 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];
>
>
More information about the pulseaudio-discuss
mailing list