Replace remaining references to 'param_id' (with 'parameter').
[ardour.git] / libs / ardour / ardour / automation_event.h
1 /*
2     Copyright (C) 2002 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_automation_event_h__
21 #define __ardour_automation_event_h__
22
23 #include <stdint.h>
24 #include <list>
25 #include <cmath>
26
27 #include <sigc++/signal.h>
28 #include <glibmm/thread.h>
29
30 #include <pbd/undo.h>
31 #include <pbd/xml++.h>
32 #include <pbd/statefuldestructible.h> 
33
34 #include <ardour/ardour.h>
35 #include <ardour/parameter.h>
36
37 namespace ARDOUR {
38
39 class Curve;
40
41 struct ControlEvent {
42
43     ControlEvent (double w, double v)
44             : when (w), value (v) { 
45             coeff[0] = coeff[1] = coeff[2] = coeff[3] = 0.0;
46         }
47
48     ControlEvent (const ControlEvent& other) 
49             : when (other.when), value (other.value) {
50             coeff[0] = coeff[1] = coeff[2] = coeff[3] = 0.0;
51         }
52     
53         double when;
54     double value;
55         double coeff[4]; ///< Used by Curve
56 };
57
58
59 class AutomationList : public PBD::StatefulDestructible
60 {
61   public:
62         typedef std::list<ControlEvent*> EventList;
63         typedef EventList::iterator iterator;
64         typedef EventList::const_iterator const_iterator;
65
66         AutomationList (Parameter id, double min_val, double max_val, double default_val);
67         AutomationList (const XMLNode&, Parameter id);
68         ~AutomationList();
69
70         AutomationList (const AutomationList&);
71         AutomationList (const AutomationList&, double start, double end);
72         AutomationList& operator= (const AutomationList&);
73         bool operator== (const AutomationList&);
74
75         Parameter parameter() const          { return _parameter; }
76         void      set_parameter(Parameter p) { _parameter = p; }
77
78         void freeze();
79         void thaw ();
80
81         EventList::size_type size() const { return _events.size(); }
82         bool empty() const { return _events.empty(); }
83
84         void reset_default (double val) {
85                 _default_value = val;
86         }
87
88         void clear ();
89         void x_scale (double factor);
90         bool extend_to (double);
91         void slide (iterator before, double distance);
92         
93         void reposition_for_rt_add (double when);
94         void rt_add (double when, double value);
95         void add (double when, double value);
96         /* this should be private but old-school automation loading needs it in IO/IOProcessor */
97         void fast_simple_add (double when, double value);
98
99         void reset_range (double start, double end);
100         void erase_range (double start, double end);
101         void erase (iterator);
102         void erase (iterator, iterator);
103         void move_range (iterator start, iterator end, double, double);
104         void modify (iterator, double, double);
105
106         AutomationList* cut (double, double);
107         AutomationList* copy (double, double);
108         void clear (double, double);
109
110         AutomationList* cut (iterator, iterator);
111         AutomationList* copy (iterator, iterator);
112         void clear (iterator, iterator);
113
114         bool paste (AutomationList&, double position, float times);
115
116         void set_automation_state (AutoState);
117         AutoState automation_state() const { return _state; }
118         sigc::signal<void> automation_style_changed;
119
120         void set_automation_style (AutoStyle m);
121         AutoStyle automation_style() const { return _style; }
122         sigc::signal<void> automation_state_changed;
123
124         bool automation_playback() const {
125                 return (_state & Play) || ((_state & Touch) && !_touching);
126         }
127         bool automation_write () const {
128                 return (_state & Write) || ((_state & Touch) && _touching);
129         }
130
131         void start_touch ();
132         void stop_touch ();
133         bool touching() const { return _touching; }
134
135         void set_yrange (double min, double max) {
136                 _min_yval = min;
137                 _max_yval = max;
138         }
139
140         double get_max_y() const { return _max_yval; }
141         double get_min_y() const { return _min_yval; }
142
143         void truncate_end (double length);
144         void truncate_start (double length);
145         
146         iterator begin() { return _events.begin(); }
147         iterator end() { return _events.end(); }
148
149         ControlEvent* back() { return _events.back(); }
150         ControlEvent* front() { return _events.front(); }
151
152         const_iterator const_begin() const { return _events.begin(); }
153         const_iterator const_end() const { return _events.end(); }
154
155         std::pair<AutomationList::iterator,AutomationList::iterator> control_points_adjacent (double when);
156
157         template<class T> void apply_to_points (T& obj, void (T::*method)(const AutomationList&)) {
158                 Glib::Mutex::Lock lm (_lock);
159                 (obj.*method)(*this);
160         }
161
162         sigc::signal<void> StateChanged;
163
164         XMLNode& get_state(void); 
165         int set_state (const XMLNode &s);
166         XMLNode& state (bool full);
167         XMLNode& serialize_events ();
168
169         void set_max_xval (double);
170         double get_max_xval() const { return _max_xval; }
171
172         double eval (double where) {
173                 Glib::Mutex::Lock lm (_lock);
174                 return unlocked_eval (where);
175         }
176
177         double rt_safe_eval (double where, bool& ok) {
178
179                 Glib::Mutex::Lock lm (_lock, Glib::TRY_LOCK);
180
181                 if ((ok = lm.locked())) {
182                         return unlocked_eval (where);
183                 } else {
184                         return 0.0;
185                 }
186         }
187
188         struct TimeComparator {
189                 bool operator() (const ControlEvent* a, const ControlEvent* b) { 
190                         return a->when < b->when;
191                 }
192         };
193         
194         struct LookupCache {
195             double left;  /* leftmost x coordinate used when finding "range" */
196             std::pair<AutomationList::const_iterator,AutomationList::const_iterator> range;
197         };
198
199         static sigc::signal<void, AutomationList*> AutomationListCreated;
200
201         const EventList& events() const { return _events; }
202         double default_value() const { return _default_value; }
203
204         // teeny const violations for Curve
205         mutable sigc::signal<void> Dirty;
206         Glib::Mutex& lock() const { return _lock; }
207         LookupCache& lookup_cache() const { return _lookup_cache; }
208         
209         /** Called by locked entry point and various private
210          * locations where we already hold the lock.
211          * 
212          * FIXME: Should this be private?  Curve needs it..
213          */
214         double unlocked_eval (double x) const;
215
216         Curve&       curve()       { return *_curve; }
217         const Curve& curve() const { return *_curve; }
218
219   protected:
220
221         /** Called by unlocked_eval() to handle cases of 3 or more control points.
222          */
223         virtual double multipoint_eval (double x) const; 
224
225         AutomationList* cut_copy_clear (double, double, int op);
226
227         int deserialize_events (const XMLNode&);
228         
229         void maybe_signal_changed ();
230         void mark_dirty ();
231         void _x_scale (double factor);
232
233         mutable LookupCache _lookup_cache;
234         
235         Parameter           _parameter;
236         EventList           _events;
237         mutable Glib::Mutex _lock;
238         int8_t              _frozen;
239         bool                _changed_when_thawed;
240         AutoState           _state;
241         AutoStyle           _style;
242         bool                _touching;
243         bool                _new_touch;
244         double              _max_xval;
245         double              _min_yval;
246         double              _max_yval;
247         double              _default_value;
248         bool                _sort_pending;
249         iterator            _rt_insertion_point;
250         double              _rt_pos;
251
252         Curve* _curve;
253 };
254
255 } // namespace
256
257 #endif /* __ardour_automation_event_h__ */