volume: Support volumes up to 11.

This allows us to set volumes up to ~153% aka +11dB.

Also show the current dB value in the UI - as pavucontrol is a bit more
developer-friendly than other volume UIs displaying this by default makes
sense.
This commit is contained in:
Colin Guthrie 2011-03-09 21:50:29 +00:00
parent 9516b6f1dc
commit 297af52ae5
6 changed files with 42 additions and 28 deletions

View File

@ -27,20 +27,22 @@
#include "i18n.h" #include "i18n.h"
static bool show_decibel = true;
/*** ChannelWidget ***/ /*** ChannelWidget ***/
ChannelWidget::ChannelWidget(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& x) : ChannelWidget::ChannelWidget(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& x) :
Gtk::EventBox(cobject), Gtk::EventBox(cobject),
volumeScaleEnabled(true) { can_decibel(false),
volumeScaleEnabled(true),
last(false) {
x->get_widget("channelLabel", channelLabel); x->get_widget("channelLabel", channelLabel);
x->get_widget("volumeLabel", volumeLabel); x->get_widget("volumeLabel", volumeLabel);
x->get_widget("volumeScale", volumeScale); x->get_widget("volumeScale", volumeScale);
volumeScale->set_value(100.0); volumeScale->set_range((double)PA_VOLUME_MUTED, (double)PA_VOLUME_UI_MAX);
volumeScale->set_increments(1.0, 5.0); volumeScale->set_value((double)PA_VOLUME_NORM);
volumeScale->set_increments(((double)PA_VOLUME_NORM)/100.0, ((double)PA_VOLUME_NORM)/20.0);
setBaseVolume(PA_VOLUME_NORM);
volumeScale->signal_value_changed().connect(sigc::mem_fun(*this, &ChannelWidget::onVolumeScaleValueChanged)); volumeScale->signal_value_changed().connect(sigc::mem_fun(*this, &ChannelWidget::onVolumeScaleValueChanged));
} }
@ -59,24 +61,19 @@ void ChannelWidget::setVolume(pa_volume_t volume) {
char txt[64]; char txt[64];
v = ((gdouble) volume * 100) / PA_VOLUME_NORM; v = ((gdouble) volume * 100) / PA_VOLUME_NORM;
if (can_decibel) {
if (can_decibel && show_decibel) {
double dB = pa_sw_volume_to_dB(volume); double dB = pa_sw_volume_to_dB(volume);
if (dB > PA_DECIBEL_MININFTY)
if (dB > PA_DECIBEL_MININFTY) { snprintf(txt, sizeof(txt), "<small>%0.0f%% (%0.2fdB)</small>", v, dB);
snprintf(txt, sizeof(txt), "%0.2f dB", dB); else
volumeLabel->set_tooltip_text(txt); snprintf(txt, sizeof(txt), "<small>%0.0f%% (-&#8734;dB)</small>", v);
} else }
volumeLabel->set_tooltip_markup("-&#8734;dB"); else
volumeLabel->set_has_tooltip(TRUE); snprintf(txt, sizeof(txt), "%0.0f%%", v);
} else volumeLabel->set_markup(txt);
volumeLabel->set_has_tooltip(FALSE);
snprintf(txt, sizeof(txt), "%0.0f%%", v);
volumeLabel->set_text(txt);
volumeScaleEnabled = false; volumeScaleEnabled = false;
volumeScale->set_value(v > 100 ? 100 : v); volumeScale->set_value(volume > PA_VOLUME_UI_MAX ? PA_VOLUME_UI_MAX : volume);
volumeScaleEnabled = true; volumeScaleEnabled = true;
} }
@ -88,7 +85,7 @@ void ChannelWidget::onVolumeScaleValueChanged() {
if (minimalStreamWidget->updating) if (minimalStreamWidget->updating)
return; return;
pa_volume_t volume = (pa_volume_t) ((volumeScale->get_value() * PA_VOLUME_NORM) / 100); pa_volume_t volume = (pa_volume_t) volumeScale->get_value();
minimalStreamWidget->updateChannelVolume(channel, volume); minimalStreamWidget->updateChannelVolume(channel, volume);
} }
@ -102,17 +99,20 @@ void ChannelWidget::set_sensitive(bool enabled) {
void ChannelWidget::setBaseVolume(pa_volume_t v) { void ChannelWidget::setBaseVolume(pa_volume_t v) {
gtk_scale_add_mark(GTK_SCALE(volumeScale->gobj()), 0.0, (GtkPositionType) GTK_POS_BOTTOM, gtk_scale_clear_marks(GTK_SCALE(volumeScale->gobj()));
can_decibel ? _("<small>Silence</small>") : _("<small>Min</small>"));
gtk_scale_add_mark(GTK_SCALE(volumeScale->gobj()), 100.0, (GtkPositionType) GTK_POS_BOTTOM, _("<small>Max</small>")); gtk_scale_add_mark(GTK_SCALE(volumeScale->gobj()), (double)PA_VOLUME_MUTED, (GtkPositionType) GTK_POS_BOTTOM,
last ? (can_decibel ? _("<small>Silence</small>") : _("<small>Min</small>")) : NULL);
gtk_scale_add_mark(GTK_SCALE(volumeScale->gobj()), (double)PA_VOLUME_NORM, (GtkPositionType) GTK_POS_BOTTOM,
last ? _("<small>100% (0dB)</small>") : NULL);
if (v > PA_VOLUME_MUTED && v < PA_VOLUME_NORM) { if (v > PA_VOLUME_MUTED && v < PA_VOLUME_NORM) {
double p = ((double) v * 100) / PA_VOLUME_NORM; gtk_scale_add_mark(GTK_SCALE(volumeScale->gobj()), (double)v, (GtkPositionType) GTK_POS_BOTTOM,
gtk_scale_add_mark(GTK_SCALE(volumeScale->gobj()), p, (GtkPositionType) GTK_POS_BOTTOM, _("<small><i>Base</i></small>")); last ? _("<small><i>Base</i></small>") : NULL);
} }
} }
void ChannelWidget::setSteps(unsigned n) { void ChannelWidget::setSteps(unsigned n) {
volumeScale->set_increments(100.0/(n-1), 100.0/(n-1)); /*volumeScale->set_increments(100.0/(n-1), 100.0/(n-1));*/
} }

View File

@ -43,6 +43,7 @@ public:
bool can_decibel; bool can_decibel;
bool volumeScaleEnabled; bool volumeScaleEnabled;
bool last;
virtual void set_sensitive(bool enabled); virtual void set_sensitive(bool enabled);
virtual void setBaseVolume(pa_volume_t); virtual void setBaseVolume(pa_volume_t);

View File

@ -77,6 +77,7 @@ void DeviceWidget::setChannelMap(const pa_channel_map &m, bool can_decibel) {
cw->channelLabel->set_markup(text); cw->channelLabel->set_markup(text);
channelsVBox->pack_start(*cw, false, false, 0); channelsVBox->pack_start(*cw, false, false, 0);
} }
channelWidgets[m.channels-1]->last = true;
lockToggleButton->set_sensitive(m.channels > 1); lockToggleButton->set_sensitive(m.channels > 1);
} }

View File

@ -150,6 +150,7 @@
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="xalign">0</property> <property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">&lt;b&gt;left-front&lt;/b&gt;</property> <property name="label" translatable="yes">&lt;b&gt;left-front&lt;/b&gt;</property>
<property name="use_markup">True</property> <property name="use_markup">True</property>
<property name="width_chars">15</property> <property name="width_chars">15</property>
@ -179,7 +180,11 @@
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="xalign">1</property> <property name="xalign">1</property>
<property name="label" translatable="yes">50%</property> <property name="yalign">0</property>
<property name="xpad">8</property>
<property name="label" translatable="yes">&lt;small&gt;50%&lt;/small&gt;</property>
<property name="use_markup">True</property>
<property name="justify">right</property>
<property name="width_chars">9</property> <property name="width_chars">9</property>
</object> </object>
<packing> <packing>

View File

@ -34,6 +34,11 @@
#define GLADE_FILE "pavucontrol.glade" #define GLADE_FILE "pavucontrol.glade"
#endif #endif
/* Can be removed when PulseAudio 0.9.23 or newer is required */
#ifndef PA_VOLUME_UI_MAX
# define PA_VOLUME_UI_MAX (pa_sw_volume_from_dB(+11.0))
#endif
enum SinkInputType { enum SinkInputType {
SINK_INPUT_ALL, SINK_INPUT_ALL,
SINK_INPUT_CLIENT, SINK_INPUT_CLIENT,

View File

@ -78,6 +78,8 @@ void StreamWidget::setChannelMap(const pa_channel_map &m, bool can_decibel) {
cw->channelLabel->set_markup(text); cw->channelLabel->set_markup(text);
channelsVBox->pack_start(*cw, false, false, 0); channelsVBox->pack_start(*cw, false, false, 0);
} }
channelWidgets[m.channels-1]->last = true;
channelWidgets[m.channels-1]->setBaseVolume(PA_VOLUME_NORM);
lockToggleButton->set_sensitive(m.channels > 1); lockToggleButton->set_sensitive(m.channels > 1);
} }