AutomationClip.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*
  2. * AutomationClip.h - declaration of class AutomationClip, which contains
  3. * all information about an automation clip
  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. #ifndef AUTOMATION_CLIP_H
  27. #define AUTOMATION_CLIP_H
  28. #include <QtCore/QMap>
  29. #include <QtCore/QPointer>
  30. #include "AutomationNode.h"
  31. #include "Clip.h"
  32. class AutomationTrack;
  33. class TimePos;
  34. class LMMS_EXPORT AutomationClip : public Clip
  35. {
  36. Q_OBJECT
  37. public:
  38. enum ProgressionTypes
  39. {
  40. DiscreteProgression,
  41. LinearProgression,
  42. CubicHermiteProgression
  43. } ;
  44. typedef QMap<int, AutomationNode> timeMap;
  45. typedef QVector<QPointer<AutomatableModel>> objectVector;
  46. using TimemapIterator = timeMap::const_iterator;
  47. AutomationClip( AutomationTrack * _auto_track );
  48. AutomationClip( const AutomationClip & _clip_to_copy );
  49. virtual ~AutomationClip() = default;
  50. bool addObject( AutomatableModel * _obj, bool _search_dup = true );
  51. const AutomatableModel * firstObject() const;
  52. const objectVector& objects() const;
  53. // progression-type stuff
  54. inline ProgressionTypes progressionType() const
  55. {
  56. return m_progressionType;
  57. }
  58. void setProgressionType( ProgressionTypes _new_progression_type );
  59. inline float getTension() const
  60. {
  61. return m_tension;
  62. }
  63. void setTension( QString _new_tension );
  64. TimePos timeMapLength() const;
  65. void updateLength();
  66. TimePos putValue(
  67. const TimePos & time,
  68. const float value,
  69. const bool quantPos = true,
  70. const bool ignoreSurroundingPoints = true
  71. );
  72. TimePos putValues(
  73. const TimePos & time,
  74. const float inValue,
  75. const float outValue,
  76. const bool quantPos = true,
  77. const bool ignoreSurroundingPoints = true
  78. );
  79. void removeNode(const TimePos & time);
  80. void removeNodes(const int tick0, const int tick1);
  81. void resetNodes(const int tick0, const int tick1);
  82. void recordValue(TimePos time, float value);
  83. TimePos setDragValue( const TimePos & time,
  84. const float value,
  85. const bool quantPos = true,
  86. const bool controlKey = false );
  87. void applyDragValue();
  88. bool isDragging() const
  89. {
  90. return m_dragging;
  91. }
  92. inline const timeMap & getTimeMap() const
  93. {
  94. return m_timeMap;
  95. }
  96. inline timeMap & getTimeMap()
  97. {
  98. return m_timeMap;
  99. }
  100. inline float getMin() const
  101. {
  102. return firstObject()->minValue<float>();
  103. }
  104. inline float getMax() const
  105. {
  106. return firstObject()->maxValue<float>();
  107. }
  108. inline bool hasAutomation() const
  109. {
  110. return m_timeMap.isEmpty() == false;
  111. }
  112. float valueAt( const TimePos & _time ) const;
  113. float *valuesAfter( const TimePos & _time ) const;
  114. const QString name() const;
  115. // settings-management
  116. void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override;
  117. void loadSettings( const QDomElement & _this ) override;
  118. static const QString classNodeName() { return "automationclip"; }
  119. QString nodeName() const override { return classNodeName(); }
  120. ClipView * createView( TrackView * _tv ) override;
  121. static bool isAutomated( const AutomatableModel * _m );
  122. static QVector<AutomationClip *> clipsForModel( const AutomatableModel * _m );
  123. static AutomationClip * globalAutomationClip( AutomatableModel * _m );
  124. static void resolveAllIDs();
  125. bool isRecording() const { return m_isRecording; }
  126. void setRecording( const bool b ) { m_isRecording = b; }
  127. static int quantization() { return s_quantization; }
  128. static void setQuantization(int q) { s_quantization = q; }
  129. public slots:
  130. void clear();
  131. void objectDestroyed( jo_id_t );
  132. void flipY( int min, int max );
  133. void flipY();
  134. void flipX( int length = -1 );
  135. private:
  136. void cleanObjects();
  137. void generateTangents();
  138. void generateTangents(timeMap::iterator it, int numToGenerate);
  139. float valueAt( timeMap::const_iterator v, int offset ) const;
  140. // Mutex to make methods involving automation clips thread safe
  141. // Mutable so we can lock it from const objects
  142. mutable QMutex m_clipMutex;
  143. AutomationTrack * m_autoTrack;
  144. QVector<jo_id_t> m_idsToResolve;
  145. objectVector m_objects;
  146. timeMap m_timeMap; // actual values
  147. timeMap m_oldTimeMap; // old values for storing the values before setDragValue() is called.
  148. float m_tension;
  149. bool m_hasAutomation;
  150. ProgressionTypes m_progressionType;
  151. bool m_dragging;
  152. bool m_dragKeepOutValue; // Should we keep the current dragged node's outValue?
  153. float m_dragOutValue; // The outValue of the dragged node's
  154. bool m_isRecording;
  155. float m_lastRecordedValue;
  156. static int s_quantization;
  157. static const float DEFAULT_MIN_VALUE;
  158. static const float DEFAULT_MAX_VALUE;
  159. friend class AutomationClipView;
  160. friend class AutomationNode;
  161. } ;
  162. //Short-hand functions to access node values in an automation clip;
  163. // replacement for CPP macros with the same purpose; could be refactored
  164. // further in the future.
  165. inline float INVAL(AutomationClip::TimemapIterator it)
  166. {
  167. return it->getInValue();
  168. }
  169. inline float OUTVAL(AutomationClip::TimemapIterator it)
  170. {
  171. return it->getOutValue();
  172. }
  173. inline float OFFSET(AutomationClip::TimemapIterator it)
  174. {
  175. return it->getValueOffset();
  176. }
  177. inline float INTAN(AutomationClip::TimemapIterator it)
  178. {
  179. return it->getInTangent();
  180. }
  181. inline float OUTTAN(AutomationClip::TimemapIterator it)
  182. {
  183. return it->getOutTangent();
  184. }
  185. inline int POS(AutomationClip::TimemapIterator it)
  186. {
  187. return it.key();
  188. }
  189. #endif