Add AutomationControl::set_value_unchecked() and AutomationControl::writable() and use them.
Classes derived from AutomationControl now check ::writable() in their ::set_value() methods to ensure that they do not attempt to overwrite data sent to them while automation playback is underway.
This commit is contained in:
parent
6ca3a1593e
commit
8d3a8ca913
@ -402,6 +402,14 @@ Amp::set_state (const XMLNode& node, int version)
|
||||
|
||||
void
|
||||
Amp::GainControl::set_value (double val)
|
||||
{
|
||||
if (writable()) {
|
||||
set_value_unchecked (val);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Amp::GainControl::set_value_unchecked (double val)
|
||||
{
|
||||
AutomationControl::set_value (std::max (std::min (val, (double)_desc.upper), (double)_desc.lower));
|
||||
_amp->session().set_dirty ();
|
||||
|
@ -91,6 +91,7 @@ public:
|
||||
}
|
||||
|
||||
void set_value (double val);
|
||||
void set_value_unchecked (double);
|
||||
|
||||
double internal_to_interface (double) const;
|
||||
double interface_to_internal (double) const;
|
||||
|
@ -81,9 +81,21 @@ public:
|
||||
void start_touch(double when);
|
||||
void stop_touch(bool mark, double when);
|
||||
|
||||
/* inherited from PBD::Controllable.
|
||||
* Derived classes MUST call ::writable() to verify
|
||||
* that writing to the parameter is legal at that time.
|
||||
*/
|
||||
void set_value (double);
|
||||
double get_value () const;
|
||||
|
||||
/* automation related value setting */
|
||||
virtual bool writable () const;
|
||||
/* Call to ::set_value() with no test for writable() because
|
||||
* this is only used by automation playback. We would like
|
||||
* to make it pure virtual
|
||||
*/
|
||||
virtual void set_value_unchecked (double val) {}
|
||||
|
||||
double lower() const { return _desc.lower; }
|
||||
double upper() const { return _desc.upper; }
|
||||
double normal() const { return _desc.normal; }
|
||||
|
@ -90,6 +90,8 @@ public:
|
||||
{}
|
||||
|
||||
void set_value (double val);
|
||||
void set_value_unchecked (double);
|
||||
bool writable() const { return true; }
|
||||
|
||||
MidiTrack* _route;
|
||||
};
|
||||
|
@ -48,6 +48,7 @@ public:
|
||||
|
||||
double lower () const;
|
||||
void set_value (double);
|
||||
void set_value_unchecked (double);
|
||||
|
||||
private:
|
||||
Pannable* owner;
|
||||
|
@ -95,6 +95,7 @@ class LIBARDOUR_API PluginInsert : public Processor
|
||||
boost::shared_ptr<AutomationList> list=boost::shared_ptr<AutomationList>());
|
||||
|
||||
void set_value (double val);
|
||||
void set_value_unchecked (double);
|
||||
double get_value (void) const;
|
||||
void catch_up_with_external_value (double val);
|
||||
XMLNode& get_state();
|
||||
@ -113,6 +114,7 @@ class LIBARDOUR_API PluginInsert : public Processor
|
||||
|
||||
void set_value (const Variant& val);
|
||||
void set_value (double val);
|
||||
void set_value_unchecked (double);
|
||||
double get_value (void) const;
|
||||
XMLNode& get_state();
|
||||
|
||||
|
@ -389,6 +389,7 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
|
||||
public:
|
||||
SoloControllable (std::string name, boost::shared_ptr<Route>);
|
||||
void set_value (double);
|
||||
void set_value_unchecked (double);
|
||||
double get_value () const;
|
||||
|
||||
private:
|
||||
@ -399,6 +400,7 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
|
||||
public:
|
||||
MuteControllable (std::string name, boost::shared_ptr<Route>);
|
||||
void set_value (double);
|
||||
void set_value_unchecked (double);
|
||||
double get_value () const;
|
||||
|
||||
/* Pretend to change value, but do not affect actual route mute. */
|
||||
|
@ -207,6 +207,7 @@ class LIBARDOUR_API Track : public Route, public PublicDiskstream
|
||||
RecEnableControl (boost::shared_ptr<Track> t);
|
||||
|
||||
void set_value (double);
|
||||
void set_value_unchecked (double);
|
||||
double get_value (void) const;
|
||||
|
||||
boost::weak_ptr<Track> track;
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "ardour/session.h"
|
||||
|
||||
#include "pbd/memento_command.h"
|
||||
#include "pbd/stacktrace.h"
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
@ -48,6 +49,16 @@ AutomationControl::~AutomationControl ()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
AutomationControl::writable() const
|
||||
{
|
||||
boost::shared_ptr<AutomationList> al = alist();
|
||||
if (al) {
|
||||
return al->automation_state() != Play;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Get the current effective `user' value based on automation state */
|
||||
double
|
||||
AutomationControl::get_value() const
|
||||
|
@ -716,6 +716,14 @@ MidiTrack::set_parameter_automation_state (Evoral::Parameter param, AutoState st
|
||||
|
||||
void
|
||||
MidiTrack::MidiControl::set_value(double val)
|
||||
{
|
||||
if (writable()) {
|
||||
set_value_unchecked (val);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MidiTrack::MidiControl::set_value_unchecked(double val)
|
||||
{
|
||||
const Evoral::Parameter ¶meter = _list ? _list->parameter() : Control::parameter();
|
||||
const Evoral::ParameterDescriptor &desc = EventTypeMap::instance().descriptor(parameter);
|
||||
|
@ -37,7 +37,15 @@ PanControllable::lower () const
|
||||
void
|
||||
PanControllable::set_value (double v)
|
||||
{
|
||||
boost::shared_ptr<Panner> p = owner->panner();
|
||||
if (writable()) {
|
||||
set_value_unchecked (v);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PanControllable::set_value_unchecked (double v)
|
||||
{
|
||||
boost::shared_ptr<Panner> p = owner->panner();
|
||||
|
||||
if (!p) {
|
||||
/* no panner: just do it */
|
||||
|
@ -405,7 +405,16 @@ PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t of
|
||||
const float val = c->list()->rt_safe_eval (now, valid);
|
||||
|
||||
if (valid) {
|
||||
c->set_value(val);
|
||||
/* This is the ONLY place where we are
|
||||
* allowed to call
|
||||
* AutomationControl::set_value_unchecked(). We
|
||||
* know that the control is in
|
||||
* automation playback mode, so no
|
||||
* check on writable() is required
|
||||
* (which must be done in AutomationControl::set_value()
|
||||
*
|
||||
*/
|
||||
c->set_value_unchecked(val);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1294,6 +1303,14 @@ PluginInsert::PluginControl::PluginControl (PluginInsert* p,
|
||||
/** @param val `user' value */
|
||||
void
|
||||
PluginInsert::PluginControl::set_value (double user_val)
|
||||
{
|
||||
if (writable()) {
|
||||
set_value_unchecked (user_val);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginInsert::PluginControl::set_value_unchecked (double user_val)
|
||||
{
|
||||
/* FIXME: probably should be taking out some lock here.. */
|
||||
|
||||
@ -1359,6 +1376,14 @@ PluginInsert::PluginPropertyControl::PluginPropertyControl (PluginInsert*
|
||||
|
||||
void
|
||||
PluginInsert::PluginPropertyControl::set_value (double user_val)
|
||||
{
|
||||
if (writable()) {
|
||||
set_value_unchecked (user_val);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginInsert::PluginPropertyControl::set_value_unchecked (double user_val)
|
||||
{
|
||||
/* Old numeric set_value(), coerce to appropriate datatype if possible.
|
||||
This is lossy, but better than nothing until Ardour's automation system
|
||||
|
@ -3847,6 +3847,14 @@ Route::SoloControllable::SoloControllable (std::string name, boost::shared_ptr<R
|
||||
|
||||
void
|
||||
Route::SoloControllable::set_value (double val)
|
||||
{
|
||||
if (writable()) {
|
||||
set_value_unchecked (val);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Route::SoloControllable::set_value_unchecked (double val)
|
||||
{
|
||||
const bool bval = ((val >= 0.5) ? true : false);
|
||||
|
||||
@ -3920,6 +3928,14 @@ Route::MuteControllable::set_superficial_value(bool muted)
|
||||
|
||||
void
|
||||
Route::MuteControllable::set_value (double val)
|
||||
{
|
||||
if (writable()) {
|
||||
set_value_unchecked (val);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Route::MuteControllable::set_value_unchecked (double val)
|
||||
{
|
||||
const bool bval = ((val >= 0.5) ? true : false);
|
||||
|
||||
|
@ -191,6 +191,14 @@ Track::RecEnableControl::RecEnableControl (boost::shared_ptr<Track> t)
|
||||
|
||||
void
|
||||
Track::RecEnableControl::set_value (double val)
|
||||
{
|
||||
if (writable()) {
|
||||
set_value_unchecked (val);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Track::RecEnableControl::set_value_unchecked (double val)
|
||||
{
|
||||
boost::shared_ptr<Track> t = track.lock ();
|
||||
if (!t) {
|
||||
|
Loading…
Reference in New Issue
Block a user