1 /* 2 * Copyright (C) 2008-2014 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-2017 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 #ifndef __ardour_automation_event_h__ 24 #define __ardour_automation_event_h__ 25 26 #include <stdint.h> 27 #include <cstdlib> 28 #include <list> 29 #include <cmath> 30 31 #include <glibmm/threads.h> 32 33 #include "evoral/ControlList.h" 34 #include "evoral/Parameter.h" 35 36 #include "pbd/undo.h" 37 #include "pbd/xml++.h" 38 #include "pbd/statefuldestructible.h" 39 #include "pbd/properties.h" 40 #include "pbd/g_atomic_compat.h" 41 42 #include "ardour/ardour.h" 43 44 namespace ARDOUR { 45 46 class AutomationList; 47 class DoubleBeatsSamplesConverter; 48 49 /** A SharedStatefulProperty for AutomationLists */ 50 class LIBARDOUR_API AutomationListProperty : public PBD::SharedStatefulProperty<AutomationList> 51 { 52 public: AutomationListProperty(PBD::PropertyDescriptor<boost::shared_ptr<AutomationList>> d,Ptr p)53 AutomationListProperty (PBD::PropertyDescriptor<boost::shared_ptr<AutomationList> > d, Ptr p) 54 : PBD::SharedStatefulProperty<AutomationList> (d.property_id, p) 55 {} 56 AutomationListProperty(PBD::PropertyDescriptor<boost::shared_ptr<AutomationList>> d,Ptr o,Ptr c)57 AutomationListProperty (PBD::PropertyDescriptor<boost::shared_ptr<AutomationList> > d, Ptr o, Ptr c) 58 : PBD::SharedStatefulProperty<AutomationList> (d.property_id, o, c) 59 {} 60 61 PBD::PropertyBase* clone () const; 62 63 private: 64 /* No copy-construction nor assignment */ 65 AutomationListProperty (AutomationListProperty const &); 66 AutomationListProperty& operator= (AutomationListProperty const &); 67 }; 68 69 /** AutomationList is a stateful wrapper around Evoral::ControlList. 70 * It includes session-specifics (such as automation state), control logic (e.g. touch, signals) 71 * and acts as proxy to the underlying ControlList which holds the actual data. 72 */ 73 class LIBARDOUR_API AutomationList : public Evoral::ControlList, public PBD::StatefulDestructible 74 { 75 public: 76 AutomationList (const Evoral::Parameter& id, const Evoral::ParameterDescriptor& desc); 77 AutomationList (const Evoral::Parameter& id); 78 AutomationList (const XMLNode&, Evoral::Parameter id); 79 AutomationList (const AutomationList&); 80 AutomationList (const AutomationList&, double start, double end); 81 ~AutomationList(); 82 83 virtual boost::shared_ptr<ControlList> create(const Evoral::Parameter& id, 84 const Evoral::ParameterDescriptor& desc); 85 86 AutomationList& operator= (const AutomationList&); 87 88 void thaw (); 89 bool paste (const ControlList&, double, DoubleBeatsSamplesConverter const&); 90 91 void set_automation_state (AutoState); 92 AutoState automation_state() const; 93 PBD::Signal1<void, AutoState> automation_state_changed; 94 automation_playback()95 bool automation_playback() const { 96 return (_state & Play) || ((_state & (Touch | Latch)) && !touching()); 97 } automation_write()98 bool automation_write () const { 99 return ((_state & Write) || ((_state & (Touch | Latch)) && touching())); 100 } 101 102 PBD::Signal0<void> StateChanged; 103 104 static PBD::Signal1<void,AutomationList*> AutomationListCreated; 105 106 void start_write_pass (double when); 107 void write_pass_finished (double when, double thinning_factor=0.0); 108 109 void start_touch (double when); 110 void stop_touch (double when); 111 touching()112 bool touching () const { return g_atomic_int_get (&_touching) != 0; } writing()113 bool writing () const { return _state == Write; } touch_enabled()114 bool touch_enabled () const { return _state & (Touch | Latch); } 115 116 XMLNode& get_state (); 117 int set_state (const XMLNode &, int version); 118 119 Command* memento_command (XMLNode* before, XMLNode* after); 120 121 bool operator!= (const AutomationList &) const; 122 before()123 XMLNode* before () { XMLNode* rv = _before; _before = 0; return rv; } 124 void clear_history (); 125 void snapshot_history (bool need_lock); 126 127 ControlList::InterpolationStyle default_interpolation () const; 128 129 private: 130 void create_curve_if_necessary (); 131 int deserialize_events (const XMLNode&); 132 133 XMLNode& state (bool save_auto_state, bool need_lock); 134 XMLNode& serialize_events (bool need_lock); 135 136 void maybe_signal_changed (); 137 138 AutoState _state; 139 GATOMIC_QUAL gint _touching; 140 141 PBD::ScopedConnection _writepass_connection; 142 143 bool operator== (const AutomationList&) const { /* not called */ abort(); return false; } 144 XMLNode* _before; //used for undo of touch start/stop pairs. 145 146 }; 147 148 } // namespace 149 150 #endif /* __ardour_automation_event_h__ */ 151