summaryrefslogtreecommitdiff
path: root/gtk2_ardour/volume_controller.cc
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2011-06-17 21:47:20 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2011-06-17 21:47:20 +0000
commit01e006e46e6d4dd0ab25e08bd44d13dd1e195886 (patch)
tree3ed1b959caa20fd0e117de2fcfa557738ae5aa86 /gtk2_ardour/volume_controller.cc
parentcb8bc87a542e35794a12e76a23594e63b3bad521 (diff)
some changes to try to make the monitor section gain controls work as intended, and along the way start to rationalize MotionFeedback/VolumeController classes
git-svn-id: svn://localhost/ardour2/branches/3.0@9746 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour/volume_controller.cc')
-rw-r--r--gtk2_ardour/volume_controller.cc111
1 files changed, 85 insertions, 26 deletions
diff --git a/gtk2_ardour/volume_controller.cc b/gtk2_ardour/volume_controller.cc
index bb6a5f1db3..8a382f6cb1 100644
--- a/gtk2_ardour/volume_controller.cc
+++ b/gtk2_ardour/volume_controller.cc
@@ -17,12 +17,17 @@
$Id: volume_controller.cc,v 1.4 2000/05/03 15:54:21 pbd Exp $
*/
+#include <algorithm>
+
#include <string.h>
#include <limits.h>
#include "pbd/controllable.h"
+#include "pbd/stacktrace.h"
#include "gtkmm2ext/gui_thread.h"
+
+#include "ardour/dB.h"
#include "ardour/utils.h"
#include "volume_controller.h"
@@ -30,45 +35,99 @@
using namespace Gtk;
VolumeController::VolumeController (Glib::RefPtr<Gdk::Pixbuf> p,
- Gtk::Adjustment *adj,
+ boost::shared_ptr<PBD::Controllable> c,
+ double def,
+ double step,
+ double page,
bool with_numeric,
- int subw, int subh)
-
- : MotionFeedback (p, MotionFeedback::Rotary, "", adj, with_numeric, subw, subh)
+ int subw,
+ int subh,
+ bool linear,
+ bool dB)
+
+ : MotionFeedback (p, MotionFeedback::Rotary, c, def, step, page, "", with_numeric, subw, subh)
+ , _linear (linear)
+ , _controllable_uses_dB (dB)
{
- get_adjustment()->signal_value_changed().connect (mem_fun (*this,&VolumeController::adjustment_value_changed));
+ set_print_func (VolumeController::_dB_printer, this);
+
+ if (step < 1.0) {
+ value->set_width_chars (6 + abs ((int) ceil (log10 (step))));
+ } else {
+ value->set_width_chars (5); // -NNdB
+ }
+
}
void
-VolumeController::set_controllable (boost::shared_ptr<PBD::Controllable> c)
+VolumeController::_dB_printer (char buf[32], const boost::shared_ptr<PBD::Controllable>& c, void* arg)
{
- MotionFeedback::set_controllable (c);
-
- controllable_connection.disconnect ();
-
- if (c) {
- c->Changed.connect (controllable_connection, MISSING_INVALIDATOR, boost::bind (&VolumeController::controllable_value_changed, this), gui_context());
- }
-
- controllable_value_changed ();
+ VolumeController* vc = reinterpret_cast<VolumeController*>(arg);
+ vc->dB_printer (buf, c);
}
void
-VolumeController::controllable_value_changed ()
+VolumeController::dB_printer (char buf[32], const boost::shared_ptr<PBD::Controllable>& c)
{
- boost::shared_ptr<PBD::Controllable> c = controllable();
- if (c) {
- get_adjustment()->set_value (gain_to_slider_position (c->get_value ()));
- }
+ if (c) {
+
+ if (_linear) {
+ /* controllable units are in dB so just show the value */
+ if (step_inc < 1.0) {
+ snprintf (buf, 32, "%.2f dB", c->get_value());
+ } else {
+ snprintf (buf, 32, "%ld dB", lrint (c->get_value()));
+ }
+ } else {
+
+ double gain_coefficient;
+
+ if (!_controllable_uses_dB) {
+ gain_coefficient = c->get_value();
+ } else {
+ double fract = (c->get_value() - c->lower()) / (c->upper() - c->lower());
+ gain_coefficient = slider_position_to_gain (fract);
+ }
+
+ if (step_inc < 1.0) {
+ snprintf (buf, 32, "%.2f dB", accurate_coefficient_to_dB (gain_coefficient));
+ } else {
+ snprintf (buf, 32, "%ld dB", lrint (accurate_coefficient_to_dB (gain_coefficient)));
+ }
+ }
+ } else {
+ snprintf (buf, sizeof (buf), "--");
+ }
}
-void
-VolumeController::adjustment_value_changed ()
+double
+VolumeController::to_control_value (double display_value)
{
- boost::shared_ptr<PBD::Controllable> c = controllable();
- if (c) {
- c->set_value (slider_position_to_gain (get_adjustment()->get_value()));
- }
+ double v;
+
+ /* display value is always clamped to 0.0 .. 1.0 */
+ display_value = std::max (0.0, std::min (1.0, display_value));
+
+ if (_linear) {
+ v = _controllable->lower() + ((_controllable->upper() - _controllable->lower()) * display_value);
+ } else {
+
+ v = slider_position_to_gain (display_value);
+ }
+
+ return v;
}
+double
+VolumeController::to_display_value (double control_value)
+{
+ double v;
+
+ if (_linear) {
+ v = (control_value - _controllable->lower ()) / (_controllable->upper() - _controllable->lower());
+ } else {
+ v = gain_to_slider_position (control_value);
+ }
+ return v;
+}