NotePlayHandle.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  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 "AtomicInt.h"
  28. #include "Note.h"
  29. #include "PlayHandle.h"
  30. #include "Track.h"
  31. #include "MemoryManager.h"
  32. class QReadWriteLock;
  33. class InstrumentTrack;
  34. class NotePlayHandle;
  35. template<ch_cnt_t=DEFAULT_CHANNELS> class BasicFilters;
  36. typedef QList<NotePlayHandle *> NotePlayHandleList;
  37. typedef QList<const NotePlayHandle *> ConstNotePlayHandleList;
  38. class EXPORT NotePlayHandle : public PlayHandle, public Note
  39. {
  40. MM_OPERATORS
  41. public:
  42. void * m_pluginData;
  43. BasicFilters<> * m_filter;
  44. // specifies origin of NotePlayHandle
  45. enum Origins
  46. {
  47. OriginPattern, /*! playback of a note from a pattern */
  48. OriginMidiInput, /*! playback of a MIDI note input event */
  49. OriginNoteStacking, /*! created by note stacking instrument function */
  50. OriginArpeggio, /*! created by arpeggio instrument function */
  51. OriginCount
  52. };
  53. typedef Origins Origin;
  54. NotePlayHandle( InstrumentTrack* instrumentTrack,
  55. const f_cnt_t offset,
  56. const f_cnt_t frames,
  57. const Note& noteToPlay,
  58. NotePlayHandle* parent = NULL,
  59. int midiEventChannel = -1,
  60. Origin origin = OriginPattern );
  61. virtual ~NotePlayHandle();
  62. void * operator new ( size_t size, void * p )
  63. {
  64. return p;
  65. }
  66. virtual void setVolume( volume_t volume );
  67. virtual void setPanning( panning_t panning );
  68. int midiKey() const;
  69. int midiChannel() const
  70. {
  71. return m_midiChannel;
  72. }
  73. /*! convenience function that returns offset for the first period and zero otherwise,
  74. used by instruments to handle the offset: instruments have to check this property and
  75. add the correct number of empty frames in the beginning of the period */
  76. f_cnt_t noteOffset() const
  77. {
  78. return m_totalFramesPlayed == 0
  79. ? offset()
  80. : 0;
  81. }
  82. const float& frequency() const
  83. {
  84. return m_frequency;
  85. }
  86. /*! Returns frequency without pitch wheel influence */
  87. float unpitchedFrequency() const
  88. {
  89. return m_unpitchedFrequency;
  90. }
  91. /*! Renders one chunk using the attached instrument into the buffer */
  92. virtual void play( sampleFrame* buffer );
  93. /*! Returns whether playback of note is finished and thus handle can be deleted */
  94. virtual bool isFinished() const
  95. {
  96. return m_released && framesLeft() <= 0;
  97. }
  98. /*! Returns number of frames left for playback */
  99. f_cnt_t framesLeft() const;
  100. /*! Returns how many frames have to be rendered in current period */
  101. fpp_t framesLeftForCurrentPeriod() const;
  102. /*! Returns whether the play handle plays on a certain track */
  103. virtual bool isFromTrack( const Track* _track ) const;
  104. /*! Releases the note (and plays release frames */
  105. void noteOff( const f_cnt_t offset = 0 );
  106. /*! Returns number of frames to be played until the note is going to be released */
  107. f_cnt_t framesBeforeRelease() const
  108. {
  109. return m_framesBeforeRelease;
  110. }
  111. /*! Returns how many frames were played since release */
  112. f_cnt_t releaseFramesDone() const
  113. {
  114. return m_releaseFramesDone;
  115. }
  116. /*! Returns the number of frames to be played after release according to
  117. the release times in the envelopes */
  118. f_cnt_t actualReleaseFramesToDo() const;
  119. /*! Returns total numbers of frames to play (including release frames) */
  120. f_cnt_t frames() const
  121. {
  122. return m_frames;
  123. }
  124. /*! Sets the total number of frames to play (including release frames) */
  125. void setFrames( const f_cnt_t _frames );
  126. /*! Returns whether note was released */
  127. bool isReleased() const
  128. {
  129. return m_released;
  130. }
  131. bool isReleaseStarted() const
  132. {
  133. return m_releaseStarted;
  134. }
  135. /*! Returns total numbers of frames played so far */
  136. f_cnt_t totalFramesPlayed() const
  137. {
  138. return m_totalFramesPlayed;
  139. }
  140. /*! Returns volume level at given frame (envelope/LFO) */
  141. float volumeLevel( const f_cnt_t frame );
  142. /*! Returns instrument track which is being played by this handle (const version) */
  143. const InstrumentTrack* instrumentTrack() const
  144. {
  145. return m_instrumentTrack;
  146. }
  147. /*! Returns instrument track which is being played by this handle */
  148. InstrumentTrack* instrumentTrack()
  149. {
  150. return m_instrumentTrack;
  151. }
  152. /*! Returns whether note has a parent, e.g. is not part of an arpeggio or a chord */
  153. bool hasParent() const
  154. {
  155. return m_hasParent;
  156. }
  157. /*! Returns origin of note */
  158. Origin origin() const
  159. {
  160. return m_origin;
  161. }
  162. /*! Returns whether note has children */
  163. bool isMasterNote() const
  164. {
  165. return m_subNotes.size() > 0 || m_hadChildren;
  166. }
  167. void setMasterNote()
  168. {
  169. m_hadChildren = true;
  170. setUsesBuffer( false );
  171. }
  172. /*! Returns whether note is muted */
  173. bool isMuted() const
  174. {
  175. return m_muted;
  176. }
  177. /*! Mutes playback of note */
  178. void mute();
  179. /*! Returns index of NotePlayHandle in vector of note-play-handles
  180. belonging to this instrument track - used by arpeggiator.
  181. Ignores child note-play-handles, returns -1 when called on one */
  182. int index() const;
  183. /*! Returns list of note-play-handles belonging to given instrument track.
  184. If allPlayHandles = true, also released note-play-handles and children
  185. are returned */
  186. static ConstNotePlayHandleList nphsOfInstrumentTrack( const InstrumentTrack* Track, bool allPlayHandles = false );
  187. /*! Returns whether given NotePlayHandle instance is equal to *this */
  188. bool operator==( const NotePlayHandle & _nph ) const;
  189. /*! Returns whether NotePlayHandle belongs to BB track and BB track is muted */
  190. bool isBbTrackMuted()
  191. {
  192. return m_bbTrack && m_bbTrack->isMuted();
  193. }
  194. /*! Sets attached BB track */
  195. void setBBTrack( Track* t )
  196. {
  197. m_bbTrack = t;
  198. }
  199. /*! Process note detuning automation */
  200. void processMidiTime( const MidiTime& time );
  201. /*! Updates total length (m_frames) depending on a new tempo */
  202. void resize( const bpm_t newTempo );
  203. /*! Set song-global offset (relative to containing pattern) in order to properly perform the note detuning */
  204. void setSongGlobalParentOffset( const MidiTime& offset )
  205. {
  206. m_songGlobalParentOffset = offset;
  207. }
  208. /*! Returns song-global offset */
  209. const MidiTime& songGlobalParentOffset() const
  210. {
  211. return m_songGlobalParentOffset;
  212. }
  213. void setFrequencyUpdate()
  214. {
  215. m_frequencyNeedsUpdate = true;
  216. }
  217. private:
  218. class BaseDetuning
  219. {
  220. MM_OPERATORS
  221. public:
  222. BaseDetuning( DetuningHelper* detuning );
  223. void setValue( float val )
  224. {
  225. m_value = val;
  226. }
  227. float value() const
  228. {
  229. return m_value;
  230. }
  231. private:
  232. float m_value;
  233. } ;
  234. void updateFrequency();
  235. InstrumentTrack* m_instrumentTrack; // needed for calling
  236. // InstrumentTrack::playNote
  237. f_cnt_t m_frames; // total frames to play
  238. f_cnt_t m_totalFramesPlayed; // total frame-counter - used for
  239. // figuring out whether a whole note
  240. // has been played
  241. f_cnt_t m_framesBeforeRelease; // number of frames after which note
  242. // is released
  243. f_cnt_t m_releaseFramesToDo; // total numbers of frames to be
  244. // played after release
  245. f_cnt_t m_releaseFramesDone; // number of frames done after
  246. // release of note
  247. NotePlayHandleList m_subNotes; // used for chords and arpeggios
  248. volatile bool m_released; // indicates whether note is released
  249. bool m_releaseStarted;
  250. bool m_hasMidiNote;
  251. bool m_hasParent; // indicates whether note has parent
  252. NotePlayHandle * m_parent; // parent note
  253. bool m_hadChildren;
  254. bool m_muted; // indicates whether note is muted
  255. Track* m_bbTrack; // related BB track
  256. // tempo reaction
  257. bpm_t m_origTempo; // original tempo
  258. f_cnt_t m_origFrames; // original m_frames
  259. int m_origBaseNote;
  260. float m_frequency;
  261. float m_unpitchedFrequency;
  262. BaseDetuning* m_baseDetuning;
  263. MidiTime m_songGlobalParentOffset;
  264. int m_midiChannel;
  265. Origin m_origin;
  266. bool m_frequencyNeedsUpdate; // used to update pitch
  267. } ;
  268. const int INITIAL_NPH_CACHE = 256;
  269. const int NPH_CACHE_INCREMENT = 16;
  270. class NotePlayHandleManager
  271. {
  272. MM_OPERATORS
  273. public:
  274. static void init();
  275. static NotePlayHandle * acquire( InstrumentTrack* instrumentTrack,
  276. const f_cnt_t offset,
  277. const f_cnt_t frames,
  278. const Note& noteToPlay,
  279. NotePlayHandle* parent = NULL,
  280. int midiEventChannel = -1,
  281. NotePlayHandle::Origin origin = NotePlayHandle::OriginPattern );
  282. static void release( NotePlayHandle * nph );
  283. static void extend( int i );
  284. private:
  285. static NotePlayHandle ** s_available;
  286. static QReadWriteLock s_mutex;
  287. static AtomicInt s_availableIndex;
  288. static int s_size;
  289. };
  290. #endif