NotePlayHandle.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. /*
  2. * NotePlayHandle.h - declaration of class NotePlayHandle which manages
  3. * playback of a single note by an instrument
  4. *
  5. * Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
  6. *
  7. * This file is part of LMMS - https://lmms.io
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public
  11. * License as published by the Free Software Foundation; either
  12. * version 2 of the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public
  20. * License along with this program (see COPYING); if not, write to the
  21. * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  22. * Boston, MA 02110-1301 USA.
  23. *
  24. */
  25. #ifndef NOTE_PLAY_HANDLE_H
  26. #define NOTE_PLAY_HANDLE_H
  27. #include <memory>
  28. #include "BasicFilters.h"
  29. #include "Note.h"
  30. #include "PlayHandle.h"
  31. #include "Track.h"
  32. #include "MemoryManager.h"
  33. class QReadWriteLock;
  34. class InstrumentTrack;
  35. class NotePlayHandle;
  36. typedef QList<NotePlayHandle *> NotePlayHandleList;
  37. typedef QList<const NotePlayHandle *> ConstNotePlayHandleList;
  38. class LMMS_EXPORT NotePlayHandle : public PlayHandle, public Note
  39. {
  40. MM_OPERATORS
  41. public:
  42. void * m_pluginData;
  43. std::unique_ptr<BasicFilters<>> m_filter;
  44. // length of the declicking fade in
  45. fpp_t m_fadeInLength;
  46. // specifies origin of NotePlayHandle
  47. enum Origins
  48. {
  49. OriginMidiClip, /*! playback of a note from a MIDI clip */
  50. OriginMidiInput, /*! playback of a MIDI note input event */
  51. OriginNoteStacking, /*! created by note stacking instrument function */
  52. OriginArpeggio, /*! created by arpeggio instrument function */
  53. OriginCount
  54. };
  55. typedef Origins Origin;
  56. NotePlayHandle( InstrumentTrack* instrumentTrack,
  57. const f_cnt_t offset,
  58. const f_cnt_t frames,
  59. const Note& noteToPlay,
  60. NotePlayHandle* parent = nullptr,
  61. int midiEventChannel = -1,
  62. Origin origin = OriginMidiClip );
  63. virtual ~NotePlayHandle();
  64. void * operator new ( size_t size, void * p )
  65. {
  66. return p;
  67. }
  68. void setVolume( volume_t volume ) override;
  69. void setPanning( panning_t panning ) override;
  70. int midiKey() const;
  71. int midiChannel() const
  72. {
  73. return m_midiChannel;
  74. }
  75. /*! convenience function that returns offset for the first period and zero otherwise,
  76. used by instruments to handle the offset: instruments have to check this property and
  77. add the correct number of empty frames in the beginning of the period */
  78. f_cnt_t noteOffset() const
  79. {
  80. return m_totalFramesPlayed == 0
  81. ? offset()
  82. : 0;
  83. }
  84. const float& frequency() const
  85. {
  86. return m_frequency;
  87. }
  88. /*! Returns frequency without pitch wheel influence */
  89. float unpitchedFrequency() const
  90. {
  91. return m_unpitchedFrequency;
  92. }
  93. /*! Renders one chunk using the attached instrument into the buffer */
  94. void play( sampleFrame* buffer ) override;
  95. /*! Returns whether playback of note is finished and thus handle can be deleted */
  96. bool isFinished() const override
  97. {
  98. return m_released && framesLeft() <= 0;
  99. }
  100. /*! Returns number of frames left for playback */
  101. f_cnt_t framesLeft() const;
  102. /*! Returns how many frames have to be rendered in current period */
  103. fpp_t framesLeftForCurrentPeriod() const;
  104. /*! Returns whether the play handle plays on a certain track */
  105. bool isFromTrack( const Track* _track ) const override;
  106. /*! Releases the note (and plays release frames) */
  107. void noteOff( const f_cnt_t offset = 0 );
  108. /*! Returns number of frames to be played until the note is going to be released */
  109. f_cnt_t framesBeforeRelease() const
  110. {
  111. return m_framesBeforeRelease;
  112. }
  113. /*! Returns how many frames were played since release */
  114. f_cnt_t releaseFramesDone() const
  115. {
  116. return m_releaseFramesDone;
  117. }
  118. /*! Returns the number of frames to be played after release according to
  119. the release times in the envelopes */
  120. f_cnt_t actualReleaseFramesToDo() const;
  121. /*! Returns total numbers of frames to play (including release frames) */
  122. f_cnt_t frames() const
  123. {
  124. return m_frames;
  125. }
  126. /*! Sets the total number of frames to play (including release frames) */
  127. void setFrames( const f_cnt_t _frames );
  128. /*! Returns whether note was released */
  129. bool isReleased() const
  130. {
  131. return m_released;
  132. }
  133. bool isReleaseStarted() const
  134. {
  135. return m_releaseStarted;
  136. }
  137. /*! Returns total numbers of frames played so far */
  138. f_cnt_t totalFramesPlayed() const
  139. {
  140. return m_totalFramesPlayed;
  141. }
  142. /*! Returns volume level at given frame (envelope/LFO) */
  143. float volumeLevel( const f_cnt_t frame );
  144. /*! Returns instrument track which is being played by this handle (const version) */
  145. const InstrumentTrack* instrumentTrack() const
  146. {
  147. return m_instrumentTrack;
  148. }
  149. /*! Returns instrument track which is being played by this handle */
  150. InstrumentTrack* instrumentTrack()
  151. {
  152. return m_instrumentTrack;
  153. }
  154. /*! Returns whether note has a parent, e.g. is not part of an arpeggio or a chord */
  155. bool hasParent() const
  156. {
  157. return m_hasParent;
  158. }
  159. /*! Returns origin of note */
  160. Origin origin() const
  161. {
  162. return m_origin;
  163. }
  164. /*! Returns whether note has children */
  165. bool isMasterNote() const
  166. {
  167. return m_subNotes.size() > 0 || m_hadChildren;
  168. }
  169. void setMasterNote()
  170. {
  171. m_hadChildren = true;
  172. setUsesBuffer( false );
  173. }
  174. /*! Returns whether note is muted */
  175. bool isMuted() const
  176. {
  177. return m_muted;
  178. }
  179. /*! Mutes playback of note */
  180. void mute();
  181. /*! Returns index of NotePlayHandle in vector of note-play-handles
  182. belonging to this instrument track - used by arpeggiator.
  183. Ignores child note-play-handles, returns -1 when called on one */
  184. int index() const;
  185. /*! Returns list of note-play-handles belonging to given instrument track.
  186. If allPlayHandles = true, also released note-play-handles and children
  187. are returned */
  188. static ConstNotePlayHandleList nphsOfInstrumentTrack( const InstrumentTrack* Track, bool allPlayHandles = false );
  189. /*! Returns whether given NotePlayHandle instance is equal to *this */
  190. bool operator==( const NotePlayHandle & _nph ) const;
  191. /*! Returns whether NotePlayHandle belongs to pattern track and pattern track is muted */
  192. bool isPatternTrackMuted()
  193. {
  194. return m_patternTrack && m_patternTrack->isMuted();
  195. }
  196. /*! Sets attached pattern track */
  197. void setPatternTrack(Track* t)
  198. {
  199. m_patternTrack = t;
  200. }
  201. /*! Process note detuning automation */
  202. void processTimePos( const TimePos& time );
  203. /*! Updates total length (m_frames) depending on a new tempo */
  204. void resize( const bpm_t newTempo );
  205. /*! Set song-global offset (relative to containing MIDI clip) in order to properly perform the note detuning */
  206. void setSongGlobalParentOffset( const TimePos& offset )
  207. {
  208. m_songGlobalParentOffset = offset;
  209. }
  210. /*! Returns song-global offset */
  211. const TimePos& songGlobalParentOffset() const
  212. {
  213. return m_songGlobalParentOffset;
  214. }
  215. void setFrequencyUpdate()
  216. {
  217. m_frequencyNeedsUpdate = true;
  218. }
  219. private:
  220. class BaseDetuning
  221. {
  222. MM_OPERATORS
  223. public:
  224. BaseDetuning( DetuningHelper* detuning );
  225. void setValue( float val )
  226. {
  227. m_value = val;
  228. }
  229. float value() const
  230. {
  231. return m_value;
  232. }
  233. private:
  234. float m_value;
  235. } ;
  236. void updateFrequency();
  237. InstrumentTrack* m_instrumentTrack; // needed for calling
  238. // InstrumentTrack::playNote
  239. f_cnt_t m_frames; // total frames to play
  240. f_cnt_t m_totalFramesPlayed; // total frame-counter - used for
  241. // figuring out whether a whole note
  242. // has been played
  243. f_cnt_t m_framesBeforeRelease; // number of frames after which note
  244. // is released
  245. f_cnt_t m_releaseFramesToDo; // total numbers of frames to be
  246. // played after release
  247. f_cnt_t m_releaseFramesDone; // number of frames done after
  248. // release of note
  249. NotePlayHandleList m_subNotes; // used for chords and arpeggios
  250. volatile bool m_released; // indicates whether note is released
  251. bool m_releaseStarted;
  252. bool m_hasMidiNote;
  253. bool m_hasParent; // indicates whether note has parent
  254. NotePlayHandle * m_parent; // parent note
  255. bool m_hadChildren;
  256. bool m_muted; // indicates whether note is muted
  257. Track* m_patternTrack; // related pattern track
  258. // tempo reaction
  259. bpm_t m_origTempo; // original tempo
  260. f_cnt_t m_origFrames; // original m_frames
  261. int m_origBaseNote;
  262. float m_frequency;
  263. float m_unpitchedFrequency;
  264. BaseDetuning* m_baseDetuning;
  265. TimePos m_songGlobalParentOffset;
  266. int m_midiChannel;
  267. Origin m_origin;
  268. bool m_frequencyNeedsUpdate; // used to update pitch
  269. } ;
  270. const int INITIAL_NPH_CACHE = 256;
  271. const int NPH_CACHE_INCREMENT = 16;
  272. class NotePlayHandleManager
  273. {
  274. MM_OPERATORS
  275. public:
  276. static void init();
  277. static NotePlayHandle * acquire( InstrumentTrack* instrumentTrack,
  278. const f_cnt_t offset,
  279. const f_cnt_t frames,
  280. const Note& noteToPlay,
  281. NotePlayHandle* parent = nullptr,
  282. int midiEventChannel = -1,
  283. NotePlayHandle::Origin origin = NotePlayHandle::OriginMidiClip );
  284. static void release( NotePlayHandle * nph );
  285. static void extend( int i );
  286. static void free();
  287. private:
  288. static NotePlayHandle ** s_available;
  289. static QReadWriteLock s_mutex;
  290. static std::atomic_int s_availableIndex;
  291. static int s_size;
  292. };
  293. #endif