summaryrefslogtreecommitdiff
path: root/libs/ardour/ardour/automatable.h
blob: d99960334d00a464224c505811db5df0bcc6d937 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
    Copyright (C) 2000-2007 Paul Davis 

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#ifndef __ardour_automatable_h__
#define __ardour_automatable_h__

#include <set>
#include <map>
#include <boost/shared_ptr.hpp>
#include <ardour/session_object.h>
#include <ardour/automation_list.h>
#include <ardour/automation_control.h>
#include <ardour/event_type_map.h>
#include <evoral/ControlSet.hpp>
#include <evoral/Sequence.hpp>

namespace ARDOUR {

class Session;
class AutomationControl;


/** Note this class is abstract, actual objects must either be
 * an AutomatableControls or an AutomatableSequence
 */
class Automatable : virtual public Evoral::ControlSet
{
public:
	Automatable(Session&);
	Automatable();

	virtual ~Automatable() {}

	boost::shared_ptr<Evoral::Control>
	control_factory(const Evoral::Parameter& id);

	boost::shared_ptr<AutomationControl>
	automation_control (const Evoral::Parameter& id, bool create_if_missing=false);
	
	boost::shared_ptr<const AutomationControl>
	automation_control (const Evoral::Parameter& id) const;

	virtual void add_control(boost::shared_ptr<Evoral::Control>);
	
	virtual void automation_snapshot(nframes_t now, bool force);
	virtual void transport_stopped(nframes_t now);

	virtual string describe_parameter(Evoral::Parameter param);
	
	AutoState get_parameter_automation_state (Evoral::Parameter param, bool lock = true);
	virtual void set_parameter_automation_state (Evoral::Parameter param, AutoState);
	
	AutoStyle get_parameter_automation_style (Evoral::Parameter param);
	void set_parameter_automation_style (Evoral::Parameter param, AutoStyle);

	void protect_automation ();

	void what_has_visible_data(std::set<Evoral::Parameter>&) const;
	const std::set<Evoral::Parameter>& what_can_be_automated() const { return _can_automate_list; }

	void mark_automation_visible(Evoral::Parameter, bool);
	
	inline bool should_snapshot (nframes_t now) {
		return (_last_automation_snapshot > now
				|| (now - _last_automation_snapshot) > _automation_interval);
	}
	
	static void set_automation_interval (jack_nframes_t frames) {
		_automation_interval = frames;
	}

	static jack_nframes_t automation_interval() { 
		return _automation_interval;
	}
	
	typedef Evoral::ControlSet::Controls Controls;
	
	Evoral::ControlSet&       data()       { return *this; }
	const Evoral::ControlSet& data() const { return *this; }

	int set_automation_state (const XMLNode&, Evoral::Parameter default_param);
	XMLNode& get_automation_state();

  protected:
	Session& _a_session;

	void can_automate(Evoral::Parameter);

	virtual void auto_state_changed (Evoral::Parameter which) {}

	
	int load_automation (const std::string& path);
	int old_set_automation_state(const XMLNode&);

	std::set<Evoral::Parameter> _visible_controls;
	std::set<Evoral::Parameter> _can_automate_list;
	
	nframes_t        _last_automation_snapshot;
	static nframes_t _automation_interval;
};


/** Contains notes and controllers */
class AutomatableSequence : public Automatable, public Evoral::Sequence {
public:
	AutomatableSequence(Session& s, size_t size)
		: Evoral::ControlSet()
		, Automatable(s)
		, Evoral::Sequence(EventTypeMap::instance())
	{}
};


/** Contains only controllers */
class AutomatableControls : public Automatable {
public:
	AutomatableControls(Session& s) : Evoral::ControlSet(), Automatable(s) {}
};


} // namespace ARDOUR

#endif /* __ardour_automatable_h__ */