Song.h 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. /*
  2. * Song.h - class song - the root of the model-tree
  3. *
  4. * Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
  5. *
  6. * This file is part of LMMS - https://lmms.io
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2 of the License, or (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 GNU
  16. * General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public
  19. * License along with this program (see COPYING); if not, write to the
  20. * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  21. * Boston, MA 02110-1301 USA.
  22. *
  23. */
  24. #ifndef SONG_H
  25. #define SONG_H
  26. #include <utility>
  27. #include <QtCore/QSharedMemory>
  28. #include <QtCore/QVector>
  29. #include "TrackContainer.h"
  30. #include "Controller.h"
  31. #include "MeterModel.h"
  32. #include "Mixer.h"
  33. #include "VstSyncController.h"
  34. #include "Groove.h"
  35. class AutomationTrack;
  36. class Pattern;
  37. class TimeLineWidget;
  38. class Groove;
  39. const bpm_t MinTempo = 10;
  40. const bpm_t DefaultTempo = 140;
  41. const bpm_t MaxTempo = 999;
  42. const tick_t MaxSongLength = 9999 * DefaultTicksPerBar;
  43. class LMMS_EXPORT Song : public TrackContainer
  44. {
  45. Q_OBJECT
  46. mapPropertyFromModel( int,getTempo,setTempo,m_tempoModel );
  47. mapPropertyFromModel( int,masterPitch,setMasterPitch,m_masterPitchModel );
  48. mapPropertyFromModel( int,masterVolume,setMasterVolume, m_masterVolumeModel );
  49. public:
  50. enum PlayModes
  51. {
  52. Mode_None,
  53. Mode_PlaySong,
  54. Mode_PlayBB,
  55. Mode_PlayPattern,
  56. Mode_PlayAutomationPattern,
  57. Mode_Count
  58. } ;
  59. struct SaveOptions {
  60. /**
  61. * Should we discard MIDI ControllerConnections from project files?
  62. */
  63. BoolModel discardMIDIConnections{false};
  64. void setDefaultOptions() {
  65. discardMIDIConnections.setValue(false);
  66. }
  67. };
  68. void clearErrors();
  69. void collectError( const QString error );
  70. bool hasErrors();
  71. QString errorSummary();
  72. class PlayPos : public MidiTime
  73. {
  74. public:
  75. PlayPos( const int abs = 0 ) :
  76. MidiTime( abs ),
  77. m_timeLine( NULL ),
  78. m_currentFrame( 0.0f )
  79. {
  80. }
  81. inline void setCurrentFrame( const float f )
  82. {
  83. m_currentFrame = f;
  84. }
  85. inline float currentFrame() const
  86. {
  87. return m_currentFrame;
  88. }
  89. inline void setJumped( const bool jumped )
  90. {
  91. m_jumped = jumped;
  92. }
  93. inline bool jumped() const
  94. {
  95. return m_jumped;
  96. }
  97. TimeLineWidget * m_timeLine;
  98. private:
  99. float m_currentFrame;
  100. bool m_jumped;
  101. } ;
  102. void processNextBuffer();
  103. inline int getLoadingTrackCount() const
  104. {
  105. return m_nLoadingTrack;
  106. }
  107. inline int getMilliseconds() const
  108. {
  109. return m_elapsedMilliSeconds[m_playMode];
  110. }
  111. inline int getMilliseconds(PlayModes playMode) const
  112. {
  113. return m_elapsedMilliSeconds[playMode];
  114. }
  115. inline void setToTime(MidiTime const & midiTime)
  116. {
  117. m_elapsedMilliSeconds[m_playMode] = midiTime.getTimeInMilliseconds(getTempo());
  118. m_playPos[m_playMode].setTicks(midiTime.getTicks());
  119. }
  120. inline void setToTime(MidiTime const & midiTime, PlayModes playMode)
  121. {
  122. m_elapsedMilliSeconds[playMode] = midiTime.getTimeInMilliseconds(getTempo());
  123. m_playPos[playMode].setTicks(midiTime.getTicks());
  124. }
  125. inline void setToTimeByTicks(tick_t ticks)
  126. {
  127. m_elapsedMilliSeconds[m_playMode] = MidiTime::ticksToMilliseconds(ticks, getTempo());
  128. m_playPos[m_playMode].setTicks(ticks);
  129. }
  130. inline void setToTimeByTicks(tick_t ticks, PlayModes playMode)
  131. {
  132. m_elapsedMilliSeconds[playMode] = MidiTime::ticksToMilliseconds(ticks, getTempo());
  133. m_playPos[playMode].setTicks(ticks);
  134. }
  135. inline int getBars() const
  136. {
  137. return currentBar();
  138. }
  139. inline int ticksPerBar() const
  140. {
  141. return MidiTime::ticksPerBar(m_timeSigModel);
  142. }
  143. // Returns the beat position inside the bar, 0-based
  144. inline int getBeat() const
  145. {
  146. return getPlayPos().getBeatWithinBar(m_timeSigModel);
  147. }
  148. // the remainder after bar and beat are removed
  149. inline int getBeatTicks() const
  150. {
  151. return getPlayPos().getTickWithinBeat(m_timeSigModel);
  152. }
  153. inline int getTicks() const
  154. {
  155. return currentTick();
  156. }
  157. inline f_cnt_t getFrames() const
  158. {
  159. return currentFrame();
  160. }
  161. inline bool isPaused() const
  162. {
  163. return m_paused;
  164. }
  165. inline bool isPlaying() const
  166. {
  167. return m_playing == true && m_exporting == false;
  168. }
  169. inline bool isStopped() const
  170. {
  171. return m_playing == false && m_paused == false;
  172. }
  173. inline bool isExporting() const
  174. {
  175. return m_exporting;
  176. }
  177. inline void setExportLoop( bool exportLoop )
  178. {
  179. m_exportLoop = exportLoop;
  180. }
  181. inline bool isRecording() const
  182. {
  183. return m_recording;
  184. }
  185. inline void setLoopRenderCount(int count)
  186. {
  187. if (count < 1)
  188. m_loopRenderCount = 1;
  189. else
  190. m_loopRenderCount = count;
  191. m_loopRenderRemaining = m_loopRenderCount;
  192. }
  193. inline int getLoopRenderCount() const
  194. {
  195. return m_loopRenderCount;
  196. }
  197. bool isExportDone() const;
  198. int getExportProgress() const;
  199. inline void setRenderBetweenMarkers( bool renderBetweenMarkers )
  200. {
  201. m_renderBetweenMarkers = renderBetweenMarkers;
  202. }
  203. inline PlayModes playMode() const
  204. {
  205. return m_playMode;
  206. }
  207. inline PlayPos & getPlayPos( PlayModes pm )
  208. {
  209. return m_playPos[pm];
  210. }
  211. inline const PlayPos & getPlayPos( PlayModes pm ) const
  212. {
  213. return m_playPos[pm];
  214. }
  215. inline const PlayPos & getPlayPos() const
  216. {
  217. return getPlayPos(m_playMode);
  218. }
  219. void updateLength();
  220. bar_t length() const
  221. {
  222. return m_length;
  223. }
  224. bpm_t getTempo();
  225. AutomationPattern * tempoAutomationPattern() override;
  226. AutomationTrack * globalAutomationTrack()
  227. {
  228. return m_globalAutomationTrack;
  229. }
  230. Groove * globalGroove()
  231. {
  232. return m_globalGroove;
  233. }
  234. //TODO: Add Q_DECL_OVERRIDE when Qt4 is dropped
  235. AutomatedValueMap automatedValuesAt(MidiTime time, int tcoNum = -1) const override;
  236. // file management
  237. void createNewProject();
  238. void createNewProjectFromTemplate( const QString & templ );
  239. void loadProject( const QString & filename );
  240. bool guiSaveProject();
  241. bool guiSaveProjectAs( const QString & filename );
  242. bool saveProjectFile( const QString & filename );
  243. void setGlobalGroove(Groove * groove);
  244. const QString & projectFileName() const
  245. {
  246. return m_fileName;
  247. }
  248. bool isLoadingProject() const
  249. {
  250. return m_loadingProject;
  251. }
  252. void loadingCancelled()
  253. {
  254. m_isCancelled = true;
  255. Engine::mixer()->clearNewPlayHandles();
  256. }
  257. bool isCancelled()
  258. {
  259. return m_isCancelled;
  260. }
  261. bool isModified() const
  262. {
  263. return m_modified;
  264. }
  265. QString nodeName() const override
  266. {
  267. return "song";
  268. }
  269. virtual bool fixedTCOs() const
  270. {
  271. return false;
  272. }
  273. void addController( Controller * c );
  274. void removeController( Controller * c );
  275. const ControllerVector & controllers() const
  276. {
  277. return m_controllers;
  278. }
  279. MeterModel & getTimeSigModel()
  280. {
  281. return m_timeSigModel;
  282. }
  283. void exportProjectMidi(QString const & exportFileName) const;
  284. inline void setLoadOnLauch(bool value) { m_loadOnLaunch = value; }
  285. SaveOptions &getSaveOptions() {
  286. return m_saveOptions;
  287. }
  288. bool isSavingProject() const;
  289. public slots:
  290. void playSong();
  291. void record();
  292. void playAndRecord();
  293. void playBB();
  294. void playPattern( const Pattern * patternToPlay, bool loop = true );
  295. void togglePause();
  296. void stop();
  297. void setPlayPos( tick_t ticks, PlayModes playMode );
  298. void startExport();
  299. void stopExport();
  300. void setModified();
  301. void clearProject();
  302. void addBBTrack();
  303. private slots:
  304. void insertBar();
  305. void removeBar();
  306. void addSampleTrack();
  307. void addAutomationTrack();
  308. void setTempo();
  309. void setTimeSignature();
  310. void masterVolumeChanged();
  311. void savePos();
  312. void updateFramesPerTick();
  313. private:
  314. Song();
  315. Song( const Song & );
  316. virtual ~Song();
  317. inline bar_t currentBar() const
  318. {
  319. return m_playPos[m_playMode].getBar();
  320. }
  321. inline tick_t currentTick() const
  322. {
  323. return m_playPos[m_playMode].getTicks();
  324. }
  325. inline f_cnt_t currentFrame() const
  326. {
  327. return m_playPos[m_playMode].getTicks() * Engine::framesPerTick() +
  328. m_playPos[m_playMode].currentFrame();
  329. }
  330. void saveControllerStates( QDomDocument & doc, QDomElement & element );
  331. void restoreControllerStates( const QDomElement & element );
  332. void removeAllControllers();
  333. void processAutomations(const TrackList& tracks, MidiTime timeStart, fpp_t frames);
  334. void setModified(bool value);
  335. void setProjectFileName(QString const & projectFileName);
  336. AutomationTrack * m_globalAutomationTrack;
  337. Groove * m_globalGroove;
  338. IntModel m_tempoModel;
  339. MeterModel m_timeSigModel;
  340. int m_oldTicksPerBar;
  341. IntModel m_masterVolumeModel;
  342. IntModel m_masterPitchModel;
  343. ControllerVector m_controllers;
  344. int m_nLoadingTrack;
  345. QString m_fileName;
  346. QString m_oldFileName;
  347. bool m_modified;
  348. bool m_loadOnLaunch;
  349. volatile bool m_recording;
  350. volatile bool m_exporting;
  351. volatile bool m_exportLoop;
  352. volatile bool m_renderBetweenMarkers;
  353. volatile bool m_playing;
  354. volatile bool m_paused;
  355. bool m_savingProject;
  356. bool m_loadingProject;
  357. bool m_isCancelled;
  358. SaveOptions m_saveOptions;
  359. QStringList m_errors;
  360. PlayModes m_playMode;
  361. PlayPos m_playPos[Mode_Count];
  362. bar_t m_length;
  363. const Pattern* m_patternToPlay;
  364. bool m_loopPattern;
  365. double m_elapsedMilliSeconds[Mode_Count];
  366. tick_t m_elapsedTicks;
  367. bar_t m_elapsedBars;
  368. VstSyncController m_vstSyncController;
  369. int m_loopRenderCount;
  370. int m_loopRenderRemaining;
  371. MidiTime m_exportSongBegin;
  372. MidiTime m_exportLoopBegin;
  373. MidiTime m_exportLoopEnd;
  374. MidiTime m_exportSongEnd;
  375. MidiTime m_exportEffectiveLength;
  376. friend class LmmsCore;
  377. friend class SongEditor;
  378. friend class mainWindow;
  379. friend class ControllerRackView;
  380. signals:
  381. void projectLoaded();
  382. void playbackStateChanged();
  383. void playbackPositionChanged();
  384. void lengthChanged( int bars );
  385. void tempoChanged( bpm_t newBPM );
  386. void timeSignatureChanged( int oldTicksPerBar, int ticksPerBar );
  387. void controllerAdded( Controller * );
  388. void controllerRemoved( Controller * );
  389. void updateSampleTracks();
  390. void stopped();
  391. void modified();
  392. void projectFileNameChanged();
  393. } ;
  394. #endif