1 /*
2  * AutomationPattern.h - declaration of class AutomationPattern, which contains
3  *                       all information about an automation pattern
4  *
5  * Copyright (c) 2008-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
6  * Copyright (c) 2006-2008 Javier Serrano Polo <jasp00/at/users.sourceforge.net>
7  *
8  * This file is part of LMMS - https://lmms.io
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public
21  * License along with this program (see COPYING); if not, write to the
22  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA 02110-1301 USA.
24  *
25  */
26 
27 #ifndef AUTOMATION_PATTERN_H
28 #define AUTOMATION_PATTERN_H
29 
30 #include <QtCore/QMap>
31 #include <QtCore/QPointer>
32 
33 #include "Track.h"
34 
35 
36 class AutomationTrack;
37 class MidiTime;
38 
39 
40 
41 class EXPORT AutomationPattern : public TrackContentObject
42 {
43 	Q_OBJECT
44 public:
45 	enum ProgressionTypes
46 	{
47 		DiscreteProgression,
48 		LinearProgression,
49 		CubicHermiteProgression
50 	} ;
51 
52 	typedef QMap<int, float> timeMap;
53 	typedef QVector<QPointer<AutomatableModel> > objectVector;
54 
55 	AutomationPattern( AutomationTrack * _auto_track );
56 	AutomationPattern( const AutomationPattern & _pat_to_copy );
57 	virtual ~AutomationPattern();
58 
59 	bool addObject( AutomatableModel * _obj, bool _search_dup = true );
60 
61 	const AutomatableModel * firstObject() const;
62 	const objectVector& objects() const;
63 
64 	// progression-type stuff
progressionType()65 	inline ProgressionTypes progressionType() const
66 	{
67 		return m_progressionType;
68 	}
69 	void setProgressionType( ProgressionTypes _new_progression_type );
70 
getTension()71 	inline float getTension() const
72 	{
73 		return m_tension;
74 	}
75 	void setTension( QString _new_tension );
76 
77 	MidiTime timeMapLength() const;
78 	void updateLength();
79 
80 	MidiTime putValue( const MidiTime & time,
81 				const float value,
82 				const bool quantPos = true,
83 				const bool ignoreSurroundingPoints = true );
84 
85 	void removeValue( const MidiTime & time );
86 
87 	void recordValue(MidiTime time, float value);
88 
89 	MidiTime setDragValue( const MidiTime & time,
90 				const float value,
91 				const bool quantPos = true,
92 				const bool controlKey = false );
93 
94 	void applyDragValue();
95 
96 
isDragging()97 	bool isDragging() const
98 	{
99 		return m_dragging;
100 	}
101 
getTimeMap()102 	inline const timeMap & getTimeMap() const
103 	{
104 		return m_timeMap;
105 	}
106 
getTimeMap()107 	inline timeMap & getTimeMap()
108 	{
109 		return m_timeMap;
110 	}
111 
getTangents()112 	inline const timeMap & getTangents() const
113 	{
114 		return m_tangents;
115 	}
116 
getTangents()117 	inline timeMap & getTangents()
118 	{
119 		return m_tangents;
120 	}
121 
getMin()122 	inline float getMin() const
123 	{
124 		return firstObject()->minValue<float>();
125 	}
126 
getMax()127 	inline float getMax() const
128 	{
129 		return firstObject()->maxValue<float>();
130 	}
131 
hasAutomation()132 	inline bool hasAutomation() const
133 	{
134 		return m_timeMap.isEmpty() == false;
135 	}
136 
137 	float valueAt( const MidiTime & _time ) const;
138 	float *valuesAfter( const MidiTime & _time ) const;
139 
140 	const QString name() const;
141 
142 	// settings-management
143 	virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent );
144 	virtual void loadSettings( const QDomElement & _this );
145 
classNodeName()146 	static const QString classNodeName() { return "automationpattern"; }
nodeName()147 	QString nodeName() const { return classNodeName(); }
148 
149 	virtual TrackContentObjectView * createView( TrackView * _tv );
150 
151 
152 	static bool isAutomated( const AutomatableModel * _m );
153 	static QVector<AutomationPattern *> patternsForModel( const AutomatableModel * _m );
154 	static AutomationPattern * globalAutomationPattern( AutomatableModel * _m );
155 	static void resolveAllIDs();
156 
isRecording()157 	bool isRecording() const { return m_isRecording; }
setRecording(const bool b)158 	void setRecording( const bool b ) { m_isRecording = b; }
159 
quantization()160 	static int quantization() { return s_quantization; }
setQuantization(int q)161 	static void setQuantization(int q) { s_quantization = q; }
162 
163 public slots:
164 	void clear();
165 	void objectDestroyed( jo_id_t );
166 	void flipY( int min, int max );
167 	void flipY();
168 	void flipX( int length = -1 );
169 
170 private:
171 	void cleanObjects();
172 	void generateTangents();
173 	void generateTangents( timeMap::const_iterator it, int numToGenerate );
174 	float valueAt( timeMap::const_iterator v, int offset ) const;
175 
176 	AutomationTrack * m_autoTrack;
177 	QVector<jo_id_t> m_idsToResolve;
178 	objectVector m_objects;
179 	timeMap m_timeMap;	// actual values
180 	timeMap m_oldTimeMap;	// old values for storing the values before setDragValue() is called.
181 	timeMap m_tangents;	// slope at each point for calculating spline
182 	float m_tension;
183 	bool m_hasAutomation;
184 	ProgressionTypes m_progressionType;
185 
186 	bool m_dragging;
187 
188 	bool m_isRecording;
189 	float m_lastRecordedValue;
190 
191 	static int s_quantization;
192 
193 	static const float DEFAULT_MIN_VALUE;
194 	static const float DEFAULT_MAX_VALUE;
195 
196 	friend class AutomationPatternView;
197 
198 } ;
199 
200 
201 #endif
202