Ardour  9.0-pre0-582-g084a23a80d
automation_control.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007-2015 David Robillard <d@drobilla.net>
3  * Copyright (C) 2008-2017 Paul Davis <paul@linuxaudiosystems.com>
4  * Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net>
5  * Copyright (C) 2015-2019 Robin Gareus <robin@gareus.org>
6  * Copyright (C) 2015 Nick Mainsbridge <mainsbridge@gmail.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22 
23 #pragma once
24 
25 #include <map>
26 #include <memory>
27 
28 #include <glibmm/threads.h>
29 
30 #include "pbd/controllable.h"
31 
32 #include "evoral/types.h"
33 #include "evoral/Control.h"
34 
35 #include "ardour/automation_list.h"
38 #include "ardour/session_handle.h"
39 
41 
42 namespace ARDOUR {
43 
44 class Session;
45 class Automatable;
46 class ControlGroup;
47 
51  : public PBD::Controllable
52  , public Evoral::Control
53  , public ControlGroupMember
54  , public SessionHandleRef
55 {
56 public:
58  const Evoral::Parameter& parameter,
59  const ParameterDescriptor& desc,
60  std::shared_ptr<ARDOUR::AutomationList> l=std::shared_ptr<ARDOUR::AutomationList>(),
61  const std::string& name="",
63  );
64 
65  virtual ~AutomationControl ();
66 
67  std::shared_ptr<AutomationList> alist() const {
68  return std::dynamic_pointer_cast<AutomationList>(_list);
69  }
70 
71  void set_list (std::shared_ptr<Evoral::ControlList>);
72 
73  inline bool automation_playback() const {
74  return alist() ? alist()->automation_playback() : false;
75  }
76 
77  inline bool automation_write() const {
78  return alist() ? alist()->automation_write() : false;
79  }
80 
81  inline AutoState automation_state() const {
82  return alist() ? alist()->automation_state() : Off;
83  }
84 
86  void start_touch(timepos_t const & when);
87  void stop_touch(timepos_t const & when);
88 
89  /* inherited from PBD::Controllable. */
90  virtual double get_value () const;
91  virtual double get_save_value () const;
92 
93  /* inherited from PBD::Controllable.
94  * Derived classes MUST call ::writable() to verify
95  * that writing to the parameter is legal at that time.
96  */
97  void set_value (double value, PBD::Controllable::GroupControlDisposition group_override);
98  /* automation related value setting */
99  virtual bool writable () const;
100  /* Call to ::set_value() with no test for writable() because
101  * this is only used by automation playback.
102  */
103  void set_value_unchecked (double val) {
104  actually_set_value (val, PBD::Controllable::NoGroup);
105  }
106 
107  virtual void automation_run (samplepos_t start, pframes_t nframes);
108 
109  double lower() const { return _desc.lower; }
110  double upper() const { return _desc.upper; }
111  double normal() const { return _desc.normal; }
112  bool toggled() const { return _desc.toggled; }
113 
114  double internal_to_interface (double, bool rotary = false) const;
115  double interface_to_internal (double, bool rotary = false) const;
116 
117  virtual std::string get_user_string() const;
118 
119  const ParameterDescriptor& desc() const { return _desc; }
120 
121  const ARDOUR::Session& session() const { return _session; }
122  void commit_transaction (bool did_write);
123 
125 
126  void add_visually_linked_control (std::shared_ptr<AutomationControl> ctrl) {
127  _visually_linked_ctrls.push_back (ctrl);
128  }
129 
131  _visually_linked_ctrls.clear ();
132  }
133 
135  return _visually_linked_ctrls;
136  }
137 
138 protected:
139  std::shared_ptr<ControlGroup> _group;
140  std::shared_ptr<ControlGroup> _pushed_group;
141 
143 
144  bool check_rt (double val, Controllable::GroupControlDisposition gcd);
145 
146  /* derived classes may reimplement this, but should either
147  call this explicitly inside their version OR make sure that the
148  Controllable::Changed signal is emitted when necessary.
149  */
150 
152 
153  /* Session needs to call this method before it queues up the real
154  change for execution in a realtime context. C++ access control sucks.
155  */
156  friend class Session;
157  /* this is what the session invokes */
159  /* this will be invoked in turn on behalf of the group or the control by itself */
160  virtual void do_pre_realtime_queue_stuff (double new_value) {}
161 
163 
165 
166 private:
167  /* I am unclear on why we have to make ControlGroup a friend in order
168  to get access to the ::set_group() method when it is already
169  declared to be a friend in ControlGroupMember. Oh well.
170  */
171  friend class ControlGroup;
172  void set_group (std::shared_ptr<ControlGroup>);
173  bool push_group (std::shared_ptr<ControlGroup>);
174  bool pop_group ();
177 };
178 
179 
180 } // namespace ARDOUR
181 
WeakAutomationControlList _visually_linked_ctrls
void stop_touch(timepos_t const &when)
std::shared_ptr< ControlGroup > _group
std::shared_ptr< ControlGroup > _pushed_group
void set_group(std::shared_ptr< ControlGroup >)
AutoState automation_state() const
void set_value_unchecked(double val)
virtual std::string get_user_string() const
virtual void do_pre_realtime_queue_stuff(double new_value)
double interface_to_internal(double, bool rotary=false) const
void start_touch(timepos_t const &when)
void commit_transaction(bool did_write)
virtual bool writable() const
void set_automation_state(AutoState as)
virtual double get_value() const
WeakAutomationControlList visually_linked_controls() const
virtual void actually_set_value(double value, PBD::Controllable::GroupControlDisposition)
const ARDOUR::Session & session() const
double internal_to_interface(double, bool rotary=false) const
virtual void automation_run(samplepos_t start, pframes_t nframes)
AutomationControlList grouped_controls() const
PBD::ScopedConnection _state_changed_connection
virtual double get_save_value() const
void add_visually_linked_control(std::shared_ptr< AutomationControl > ctrl)
const ParameterDescriptor _desc
std::shared_ptr< AutomationList > alist() const
void pre_realtime_queue_stuff(double new_value, PBD::Controllable::GroupControlDisposition)
AutomationControl(ARDOUR::Session &, const Evoral::Parameter &parameter, const ParameterDescriptor &desc, std::shared_ptr< ARDOUR::AutomationList > l=std::shared_ptr< ARDOUR::AutomationList >(), const std::string &name="", PBD::Controllable::Flag flags=PBD::Controllable::Flag(0))
bool push_group(std::shared_ptr< ControlGroup >)
const ParameterDescriptor & desc() const
void set_value(double value, PBD::Controllable::GroupControlDisposition group_override)
bool check_rt(double val, Controllable::GroupControlDisposition gcd)
void set_list(std::shared_ptr< Evoral::ControlList >)
GtkImageIconNameData name
Definition: gtkimage.h:6
#define LIBARDOUR_API
PBD::PropertyDescriptor< timepos_t > start
uint32_t pframes_t
std::list< std::shared_ptr< AutomationControl > > AutomationControlList
std::list< std::weak_ptr< AutomationControl > > WeakAutomationControlList
Temporal::samplepos_t samplepos_t