mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 07:14:56 +01:00
virtualize the way that AutomationController gets strings to display values, so that we can callback through the owner of an AutomationControl, not just rely on the value from the AutomationControl; make pan automation tracks use this to display more audio-centric values
git-svn-id: svn://localhost/ardour2/branches/3.0@8590 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
85e8be3fa4
commit
d116af22db
16 changed files with 122 additions and 20 deletions
|
|
@ -19,6 +19,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include "pbd/error.h"
|
#include "pbd/error.h"
|
||||||
|
|
||||||
|
|
@ -40,10 +41,10 @@
|
||||||
using namespace ARDOUR;
|
using namespace ARDOUR;
|
||||||
using namespace Gtk;
|
using namespace Gtk;
|
||||||
|
|
||||||
|
AutomationController::AutomationController(boost::shared_ptr<Automatable> owner, boost::shared_ptr<AutomationControl> ac, Adjustment* adj)
|
||||||
AutomationController::AutomationController(boost::shared_ptr<AutomationControl> ac, Adjustment* adj)
|
|
||||||
: BarController (*adj, ac)
|
: BarController (*adj, ac)
|
||||||
, _ignore_change(false)
|
, _ignore_change(false)
|
||||||
|
, _owner (owner)
|
||||||
, _controllable(ac)
|
, _controllable(ac)
|
||||||
, _adjustment(adj)
|
, _adjustment(adj)
|
||||||
{
|
{
|
||||||
|
|
@ -80,30 +81,18 @@ AutomationController::create(
|
||||||
} else {
|
} else {
|
||||||
assert(ac->parameter() == param);
|
assert(ac->parameter() == param);
|
||||||
}
|
}
|
||||||
return boost::shared_ptr<AutomationController>(new AutomationController(ac, adjustment));
|
return boost::shared_ptr<AutomationController>(new AutomationController(parent, ac, adjustment));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
AutomationController::get_label (int&)
|
AutomationController::get_label (int&)
|
||||||
{
|
{
|
||||||
std::stringstream s;
|
return _owner->value_as_string (_controllable);
|
||||||
|
|
||||||
// Hack to display CC rounded to int
|
|
||||||
if (_controllable->parameter().type() == MidiCCAutomation) {
|
|
||||||
s << (int)_controllable->get_value();
|
|
||||||
} else {
|
|
||||||
s << std::fixed << std::setprecision(3) << _controllable->get_value();
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.str ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AutomationController::display_effective_value()
|
AutomationController::display_effective_value()
|
||||||
{
|
{
|
||||||
//if ( ! _controllable->list()->automation_playback())
|
|
||||||
// return;
|
|
||||||
|
|
||||||
float value = _controllable->get_value();
|
float value = _controllable->get_value();
|
||||||
|
|
||||||
if (_adjustment->get_value() != value) {
|
if (_adjustment->get_value() != value) {
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ public:
|
||||||
void stop_updating ();
|
void stop_updating ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AutomationController (boost::shared_ptr<ARDOUR::AutomationControl> ac, Gtk::Adjustment* adj);
|
AutomationController (boost::shared_ptr<ARDOUR::Automatable> parent, boost::shared_ptr<ARDOUR::AutomationControl> ac, Gtk::Adjustment* adj);
|
||||||
std::string get_label (int&);
|
std::string get_label (int&);
|
||||||
|
|
||||||
void start_touch();
|
void start_touch();
|
||||||
|
|
@ -64,6 +64,7 @@ private:
|
||||||
void automation_state_changed();
|
void automation_state_changed();
|
||||||
|
|
||||||
bool _ignore_change;
|
bool _ignore_change;
|
||||||
|
boost::shared_ptr<ARDOUR::Automatable> _owner;
|
||||||
boost::shared_ptr<ARDOUR::AutomationControl> _controllable;
|
boost::shared_ptr<ARDOUR::AutomationControl> _controllable;
|
||||||
Gtk::Adjustment* _adjustment;
|
Gtk::Adjustment* _adjustment;
|
||||||
sigc::connection _screen_update_connection;
|
sigc::connection _screen_update_connection;
|
||||||
|
|
|
||||||
|
|
@ -148,6 +148,7 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session* s, boost::shared_ptr<Ro
|
||||||
|
|
||||||
name_label.set_text (shortpname);
|
name_label.set_text (shortpname);
|
||||||
name_label.set_alignment (Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
|
name_label.set_alignment (Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER);
|
||||||
|
name_label.set_name (X_("TrackParameterName"));
|
||||||
|
|
||||||
if (nomparent.length()) {
|
if (nomparent.length()) {
|
||||||
|
|
||||||
|
|
@ -161,7 +162,6 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session* s, boost::shared_ptr<Ro
|
||||||
plugname = new Label (pname);
|
plugname = new Label (pname);
|
||||||
plugname->set_name (X_("TrackPlugName"));
|
plugname->set_name (X_("TrackPlugName"));
|
||||||
plugname->show();
|
plugname->show();
|
||||||
name_label.set_name (X_("TrackParameterName"));
|
|
||||||
controls_table.remove (name_hbox);
|
controls_table.remove (name_hbox);
|
||||||
controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
|
||||||
plugname_packed = true;
|
plugname_packed = true;
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ public:
|
||||||
virtual void transport_stopped (framepos_t now);
|
virtual void transport_stopped (framepos_t now);
|
||||||
|
|
||||||
virtual std::string describe_parameter(Evoral::Parameter param);
|
virtual std::string describe_parameter(Evoral::Parameter param);
|
||||||
|
virtual std::string value_as_string (boost::shared_ptr<AutomationControl>) const;
|
||||||
|
|
||||||
AutoState get_parameter_automation_state (Evoral::Parameter param);
|
AutoState get_parameter_automation_state (Evoral::Parameter param);
|
||||||
virtual void set_parameter_automation_state (Evoral::Parameter param, AutoState);
|
virtual void set_parameter_automation_state (Evoral::Parameter param, AutoState);
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,8 @@ struct Pannable : public PBD::Stateful, public Automatable, public SessionHandle
|
||||||
return ((_auto_state & Write) || ((_auto_state & Touch) && touching()));
|
return ((_auto_state & Write) || ((_auto_state & Touch) && touching()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string value_as_string (boost::shared_ptr<AutomationControl>) const;
|
||||||
|
|
||||||
void start_touch (double when);
|
void start_touch (double when);
|
||||||
void stop_touch (bool mark, double when);
|
void stop_touch (bool mark, double when);
|
||||||
bool touching() const { return g_atomic_int_get (&_touching); }
|
bool touching() const { return g_atomic_int_get (&_touching); }
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,7 @@ class Panner : public PBD::Stateful, public PBD::ScopedConnectionList
|
||||||
|
|
||||||
virtual std::set<Evoral::Parameter> what_can_be_automated() const;
|
virtual std::set<Evoral::Parameter> what_can_be_automated() const;
|
||||||
virtual std::string describe_parameter (Evoral::Parameter);
|
virtual std::string describe_parameter (Evoral::Parameter);
|
||||||
|
virtual std::string value_as_string (boost::shared_ptr<AutomationControl>) const;
|
||||||
|
|
||||||
bool touching() const;
|
bool touching() const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -492,3 +492,23 @@ Automatable::clear_controls ()
|
||||||
_control_connections.drop_connections ();
|
_control_connections.drop_connections ();
|
||||||
ControlSet::clear_controls ();
|
ControlSet::clear_controls ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string
|
||||||
|
Automatable::value_as_string (boost::shared_ptr<AutomationControl> ac) const
|
||||||
|
{
|
||||||
|
std::stringstream s;
|
||||||
|
|
||||||
|
/* this is a the default fallback for this virtual method. Derived Automatables
|
||||||
|
are free to override this to display the values of their parameters/controls
|
||||||
|
in different ways.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Hack to display CC as integer value, rather than double
|
||||||
|
if (ac->parameter().type() == MidiCCAutomation) {
|
||||||
|
s << lrint (ac->get_value());
|
||||||
|
} else {
|
||||||
|
s << std::fixed << std::setprecision(3) << ac->get_value();
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.str ();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,11 @@
|
||||||
#include "ardour/automation_control.h"
|
#include "ardour/automation_control.h"
|
||||||
#include "ardour/automation_list.h"
|
#include "ardour/automation_list.h"
|
||||||
#include "ardour/pannable.h"
|
#include "ardour/pannable.h"
|
||||||
|
#include "ardour/panner.h"
|
||||||
#include "ardour/pan_controllable.h"
|
#include "ardour/pan_controllable.h"
|
||||||
#include "ardour/session.h"
|
#include "ardour/session.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
using namespace PBD;
|
using namespace PBD;
|
||||||
using namespace ARDOUR;
|
using namespace ARDOUR;
|
||||||
|
|
||||||
|
|
@ -245,6 +247,12 @@ Pannable::set_state (const XMLNode& root, int /*version - not used*/)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string
|
||||||
|
Pannable::value_as_string (boost::shared_ptr<AutomationControl> ac) const
|
||||||
|
{
|
||||||
|
if (_panner) {
|
||||||
|
return _panner->value_as_string (ac);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Automatable::value_as_string (ac);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -161,3 +161,9 @@ Panner::describe_parameter (Evoral::Parameter p)
|
||||||
{
|
{
|
||||||
return _pannable->describe_parameter (p);
|
return _pannable->describe_parameter (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string
|
||||||
|
Panner::value_as_string (boost::shared_ptr<AutomationControl> ac) const
|
||||||
|
{
|
||||||
|
return _pannable->value_as_string (ac);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,8 @@ class BarController : public Gtk::Frame
|
||||||
Gtk::SpinButton spinner;
|
Gtk::SpinButton spinner;
|
||||||
bool use_parent;
|
bool use_parent;
|
||||||
bool logarithmic;
|
bool logarithmic;
|
||||||
|
sigc::slot<std::string> _label_slot;
|
||||||
|
bool _use_slot;
|
||||||
|
|
||||||
virtual std::string get_label (int& /*x*/) {
|
virtual std::string get_label (int& /*x*/) {
|
||||||
return "";
|
return "";
|
||||||
|
|
|
||||||
|
|
@ -362,3 +362,27 @@ Panner1in2out::describe_parameter (Evoral::Parameter p)
|
||||||
return _pannable->describe_parameter (p);
|
return _pannable->describe_parameter (p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string
|
||||||
|
Panner1in2out::value_as_string (boost::shared_ptr<AutomationControl> ac) const
|
||||||
|
{
|
||||||
|
/* DO NOT USE LocaleGuard HERE */
|
||||||
|
double val = ac->get_value();
|
||||||
|
|
||||||
|
switch (ac->parameter().type()) {
|
||||||
|
case PanAzimuthAutomation:
|
||||||
|
/* We show the position of the center of the image relative to the left & right.
|
||||||
|
This is expressed as a pair of percentage values that ranges from (100,0)
|
||||||
|
(hard left) through (50,50) (hard center) to (0,100) (hard right).
|
||||||
|
|
||||||
|
This is pretty wierd, but its the way audio engineers expect it. Just remember that
|
||||||
|
the center of the USA isn't Kansas, its (50LA, 50NY) and it will all make sense.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return string_compose (_("L:%1 R:%2"), (int) rint (100.0 * (1.0 - val)),
|
||||||
|
(int) rint (100.0 * val));
|
||||||
|
|
||||||
|
default:
|
||||||
|
return _pannable->value_as_string (ac);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ class Panner1in2out : public Panner
|
||||||
static Panner* factory (boost::shared_ptr<Pannable>, Speakers&);
|
static Panner* factory (boost::shared_ptr<Pannable>, Speakers&);
|
||||||
|
|
||||||
std::string describe_parameter (Evoral::Parameter);
|
std::string describe_parameter (Evoral::Parameter);
|
||||||
|
std::string value_as_string (boost::shared_ptr<AutomationControl>) const;
|
||||||
|
|
||||||
XMLNode& state (bool full_state);
|
XMLNode& state (bool full_state);
|
||||||
XMLNode& get_state (void);
|
XMLNode& get_state (void);
|
||||||
|
|
|
||||||
|
|
@ -473,3 +473,30 @@ Panner2in2out::describe_parameter (Evoral::Parameter p)
|
||||||
return _pannable->describe_parameter (p);
|
return _pannable->describe_parameter (p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string
|
||||||
|
Panner2in2out::value_as_string (boost::shared_ptr<AutomationControl> ac) const
|
||||||
|
{
|
||||||
|
/* DO NOT USE LocaleGuard HERE */
|
||||||
|
double val = ac->get_value();
|
||||||
|
|
||||||
|
switch (ac->parameter().type()) {
|
||||||
|
case PanAzimuthAutomation:
|
||||||
|
/* We show the position of the center of the image relative to the left & right.
|
||||||
|
This is expressed as a pair of percentage values that ranges from (100,0)
|
||||||
|
(hard left) through (50,50) (hard center) to (0,100) (hard right).
|
||||||
|
|
||||||
|
This is pretty wierd, but its the way audio engineers expect it. Just remember that
|
||||||
|
the center of the USA isn't Kansas, its (50LA, 50NY) and it will all make sense.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return string_compose (_("L:%1 R:%2"), (int) rint (100.0 * (1.0 - val)),
|
||||||
|
(int) rint (100.0 * val));
|
||||||
|
|
||||||
|
case PanWidthAutomation:
|
||||||
|
return string_compose (_("Width: %1%%"), (int) floor (100.0 * val));
|
||||||
|
|
||||||
|
default:
|
||||||
|
return _pannable->value_as_string (ac);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ class Panner2in2out : public Panner
|
||||||
static Panner* factory (boost::shared_ptr<Pannable>, Speakers&);
|
static Panner* factory (boost::shared_ptr<Pannable>, Speakers&);
|
||||||
|
|
||||||
std::string describe_parameter (Evoral::Parameter);
|
std::string describe_parameter (Evoral::Parameter);
|
||||||
|
std::string value_as_string (boost::shared_ptr<AutomationControl>) const;
|
||||||
|
|
||||||
XMLNode& state (bool full_state);
|
XMLNode& state (bool full_state);
|
||||||
XMLNode& get_state (void);
|
XMLNode& get_state (void);
|
||||||
|
|
|
||||||
|
|
@ -313,3 +313,21 @@ VBAPanner::describe_parameter (Evoral::Parameter p)
|
||||||
return _pannable->describe_parameter (p);
|
return _pannable->describe_parameter (p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string
|
||||||
|
VBAPanner::value_as_string (boost::shared_ptr<AutomationControl> ac) const
|
||||||
|
{
|
||||||
|
/* DO NOT USE LocaleGuard HERE */
|
||||||
|
double val = ac->get_value();
|
||||||
|
|
||||||
|
switch (ac->parameter().type()) {
|
||||||
|
case PanAzimuthAutomation: /* direction */
|
||||||
|
return string_compose (_("%1"), val * 360.0);
|
||||||
|
|
||||||
|
case PanWidthAutomation: /* diffusion */
|
||||||
|
return string_compose (_("%1%%"), (int) floor (100.0 * fabs(val)));
|
||||||
|
|
||||||
|
default:
|
||||||
|
return _pannable->value_as_string (ac);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ public:
|
||||||
void set_azimuth_elevation (double azimuth, double elevation);
|
void set_azimuth_elevation (double azimuth, double elevation);
|
||||||
|
|
||||||
std::string describe_parameter (Evoral::Parameter);
|
std::string describe_parameter (Evoral::Parameter);
|
||||||
|
std::string value_as_string (boost::shared_ptr<AutomationControl>) const;
|
||||||
|
|
||||||
XMLNode& state (bool full_state);
|
XMLNode& state (bool full_state);
|
||||||
XMLNode& get_state ();
|
XMLNode& get_state ();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue