Optimize automation-event process splitting
[ardour.git] / libs / ardour / ardour / automatable.h
1 /*
2     Copyright (C) 2000-2007 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #ifndef __ardour_automatable_h__
21 #define __ardour_automatable_h__
22
23 #include <map>
24 #include <set>
25 #include <string>
26
27 #include <boost/shared_ptr.hpp>
28
29 #include "pbd/rcu.h"
30 #include "pbd/signals.h"
31
32 #include "evoral/ControlSet.hpp"
33
34 #include "ardour/libardour_visibility.h"
35 #include "ardour/slavable.h"
36 #include "ardour/types.h"
37
38 class XMLNode;
39
40 namespace ARDOUR {
41
42 class Session;
43 class AutomationControl;
44
45 /* The inherited ControlSet is virtual because AutomatableSequence inherits
46  * from this AND EvoralSequence, which is also a ControlSet
47  */
48 class LIBARDOUR_API Automatable : virtual public Evoral::ControlSet, public Slavable
49 {
50 public:
51         Automatable(Session&);
52         Automatable (const Automatable& other);
53
54         virtual ~Automatable();
55
56         static bool skip_saving_automation; // to be used only by session-state
57
58         boost::shared_ptr<Evoral::Control> control_factory(const Evoral::Parameter& id);
59
60         boost::shared_ptr<AutomationControl> automation_control (PBD::ID const & id) const;
61         /* derived classes need to provide some way to search their own child
62            automatable's for a control. normally, we'd just make the method
63            above virtual, and let them override it. But that wouldn't
64            differentiate the "check children" and "just your own" cases.
65
66            We could theoretically just overload the above method with an extra
67            "bool recurse = default", but the rules of name hiding for C++ mean
68            that making a method virtual will hide other overloaded versions of
69            the same name. This means that virtual automation_control (PBD::ID
70            const &) would hide automation_control (Evoral::Parameter const &
71            id).
72
73            So, skip around all that with a different name.
74         */
75         virtual boost::shared_ptr<AutomationControl> automation_control_recurse (PBD::ID const & id) const {
76                 return automation_control (id);
77         }
78
79         boost::shared_ptr<AutomationControl> automation_control (const Evoral::Parameter& id) {
80                 return automation_control (id, false);
81         }
82         boost::shared_ptr<AutomationControl> automation_control (const Evoral::Parameter& id, bool create_if_missing);
83         boost::shared_ptr<const AutomationControl> automation_control (const Evoral::Parameter& id) const;
84
85         virtual void add_control(boost::shared_ptr<Evoral::Control>);
86         virtual bool find_next_event (double start, double end, Evoral::ControlEvent& ev, bool only_active = true) const;
87         void clear_controls ();
88
89         virtual void non_realtime_locate (samplepos_t now);
90         virtual void non_realtime_transport_stop (samplepos_t now, bool flush);
91
92         virtual void automation_run (samplepos_t, pframes_t, bool only_active = false);
93
94         virtual std::string describe_parameter(Evoral::Parameter param);
95
96         AutoState get_parameter_automation_state (Evoral::Parameter param);
97         virtual void set_parameter_automation_state (Evoral::Parameter param, AutoState);
98
99         void protect_automation ();
100
101         const std::set<Evoral::Parameter>& what_can_be_automated() const { return _can_automate_list; }
102         void what_has_existing_automation (std::set<Evoral::Parameter>&) const;
103
104         static const std::string xml_node_name;
105
106         int set_automation_xml_state (const XMLNode&, Evoral::Parameter default_param);
107         XMLNode& get_automation_xml_state();
108
109         PBD::Signal0<void> AutomationStateChanged;
110
111 protected:
112         Session& _a_session;
113
114         void can_automate(Evoral::Parameter);
115
116         virtual void automation_list_automation_state_changed (Evoral::Parameter, AutoState);
117         SerializedRCUManager<ControlList> _automated_controls;
118
119         int load_automation (const std::string& path);
120         int old_set_automation_state(const XMLNode&);
121
122         std::set<Evoral::Parameter> _can_automate_list;
123
124         samplepos_t _last_automation_snapshot;
125
126         SlavableControlList slavables () const { return SlavableControlList(); }
127
128 private:
129         inline void find_next_ac_event (boost::shared_ptr<AutomationControl>, double start, double end, Evoral::ControlEvent& ev) const;
130
131         PBD::ScopedConnectionList _control_connections; ///< connections to our controls' signals
132 };
133
134
135 } // namespace ARDOUR
136
137 #endif /* __ardour_automatable_h__ */