Ardour  9.2-129-gdf5e1050bd
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 "pbd/controllable.h"
29 
30 #include "evoral/types.h"
31 #include "evoral/Control.h"
32 
33 #include "ardour/automation_list.h"
36 #include "ardour/session_handle.h"
37 
39 
40 namespace ARDOUR {
41 
42 class Session;
43 class Automatable;
44 class ControlGroup;
45 
49  : public PBD::Controllable
50  , public Evoral::Control
51  , public ControlGroupMember
52  , public SessionHandleRef
53 {
54 public:
56  const Evoral::Parameter& parameter,
57  const ParameterDescriptor& desc,
58  std::shared_ptr<ARDOUR::AutomationList> l=std::shared_ptr<ARDOUR::AutomationList>(),
59  const std::string& name="",
61  );
62 
63  virtual ~AutomationControl ();
64 
65  std::shared_ptr<AutomationList> alist() const {
66  return std::dynamic_pointer_cast<AutomationList>(_list);
67  }
68 
69  void set_list (std::shared_ptr<Evoral::ControlList>);
70 
71  inline bool automation_playback() const {
72  return alist() ? alist()->automation_playback() : false;
73  }
74 
75  inline bool automation_write() const {
76  return alist() ? alist()->automation_write() : false;
77  }
78 
79  inline AutoState automation_state() const {
80  return alist() ? alist()->automation_state() : Off;
81  }
82 
84  void start_touch(timepos_t const & when);
85  void stop_touch(timepos_t const & when);
86 
87  /* inherited from PBD::Controllable. */
88  virtual double get_value () const;
89  virtual double get_save_value () const;
90 
91  /* inherited from PBD::Controllable.
92  * Derived classes MUST call ::writable() to verify
93  * that writing to the parameter is legal at that time.
94  */
95  void set_value (double value, PBD::Controllable::GroupControlDisposition group_override);
96  /* automation related value setting */
97  virtual bool writable () const;
98  /* Call to ::set_value() with no test for writable() because
99  * this is only used by automation playback.
100  */
101  void set_value_unchecked (double val) {
102  actually_set_value (val, PBD::Controllable::NoGroup);
103  }
104 
105  virtual void automation_run (samplepos_t start, pframes_t nframes);
106 
107  double lower() const { return _desc.lower; }
108  double upper() const { return _desc.upper; }
109  double normal() const { return _desc.normal; }
110  bool toggled() const { return _desc.toggled; }
111 
112  double internal_to_interface (double, bool rotary = false) const;
113  double interface_to_internal (double, bool rotary = false) const;
114 
115  virtual std::string get_user_string() const;
116 
117  const ParameterDescriptor& desc() const { return _desc; }
118 
119  const ARDOUR::Session& session() const { return _session; }
120  void commit_transaction (bool did_write);
121 
123 
124  void add_visually_linked_control (std::shared_ptr<AutomationControl> ctrl) {
125  _visually_linked_ctrls.push_back (ctrl);
126  }
127 
129  _visually_linked_ctrls.clear ();
130  }
131 
133  return _visually_linked_ctrls;
134  }
135 
136 protected:
137  std::shared_ptr<ControlGroup> _group;
138  std::shared_ptr<ControlGroup> _pushed_group;
139 
141 
142  bool check_rt (double val, Controllable::GroupControlDisposition gcd);
143 
144  /* derived classes may reimplement this, but should either
145  call this explicitly inside their version OR make sure that the
146  Controllable::Changed signal is emitted when necessary.
147  */
148 
150 
151  /* Session needs to call this method before it queues up the real
152  change for execution in a realtime context. C++ access control sucks.
153  */
154  friend class Session;
155  /* this is what the session invokes */
157  /* this will be invoked in turn on behalf of the group or the control by itself */
158  virtual void do_pre_realtime_queue_stuff (double new_value) {}
159 
161 
163 
164 private:
165  /* I am unclear on why we have to make ControlGroup a friend in order
166  to get access to the ::set_group() method when it is already
167  declared to be a friend in ControlGroupMember. Oh well.
168  */
169  friend class ControlGroup;
170  void set_group (std::shared_ptr<ControlGroup>);
171  bool push_group (std::shared_ptr<ControlGroup>);
172  bool pop_group ();
175 };
176 
177 
178 } // namespace ARDOUR
179 
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