Song.h 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  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 <QHash>
  30. #include <QString>
  31. #include "TrackContainer.h"
  32. #include "Controller.h"
  33. #include "MeterModel.h"
  34. #include "Mixer.h"
  35. #include "VstSyncController.h"
  36. class AutomationTrack;
  37. class Pattern;
  38. class TimeLineWidget;
  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 TimePos
  73. {
  74. public:
  75. PlayPos( const int abs = 0 ) :
  76. TimePos( 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(TimePos const & pos)
  116. {
  117. m_elapsedMilliSeconds[m_playMode] = pos.getTimeInMilliseconds(getTempo());
  118. m_playPos[m_playMode].setTicks(pos.getTicks());
  119. }
  120. inline void setToTime(TimePos const & pos, PlayModes playMode)
  121. {
  122. m_elapsedMilliSeconds[playMode] = pos.getTimeInMilliseconds(getTempo());
  123. m_playPos[playMode].setTicks(pos.getTicks());
  124. }
  125. inline void setToTimeByTicks(tick_t ticks)
  126. {
  127. m_elapsedMilliSeconds[m_playMode] = TimePos::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] = TimePos::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 TimePos::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 PlayPos & getPlayPos()
  216. {
  217. return getPlayPos(m_playMode);
  218. }
  219. inline const PlayPos & getPlayPos() const
  220. {
  221. return getPlayPos(m_playMode);
  222. }
  223. void updateLength();
  224. bar_t length() const
  225. {
  226. return m_length;
  227. }
  228. bpm_t getTempo();
  229. AutomationPattern * tempoAutomationPattern() override;
  230. AutomationTrack * globalAutomationTrack()
  231. {
  232. return m_globalAutomationTrack;
  233. }
  234. //TODO: Add Q_DECL_OVERRIDE when Qt4 is dropped
  235. AutomatedValueMap automatedValuesAt(TimePos 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. const QString & projectFileName() const
  244. {
  245. return m_fileName;
  246. }
  247. bool isLoadingProject() const
  248. {
  249. return m_loadingProject;
  250. }
  251. void loadingCancelled()
  252. {
  253. m_isCancelled = true;
  254. Engine::mixer()->clearNewPlayHandles();
  255. }
  256. bool isCancelled()
  257. {
  258. return m_isCancelled;
  259. }
  260. bool isModified() const
  261. {
  262. return m_modified;
  263. }
  264. QString nodeName() const override
  265. {
  266. return "song";
  267. }
  268. virtual bool fixedTCOs() const
  269. {
  270. return false;
  271. }
  272. void addController( Controller * c );
  273. void removeController( Controller * c );
  274. const ControllerVector & controllers() const
  275. {
  276. return m_controllers;
  277. }
  278. MeterModel & getTimeSigModel()
  279. {
  280. return m_timeSigModel;
  281. }
  282. void exportProjectMidi(QString const & exportFileName) const;
  283. inline void setLoadOnLaunch(bool value) { m_loadOnLaunch = value; }
  284. SaveOptions &getSaveOptions() {
  285. return m_saveOptions;
  286. }
  287. bool isSavingProject() const;
  288. public slots:
  289. void playSong();
  290. void record();
  291. void playAndRecord();
  292. void playBB();
  293. void playPattern( const Pattern * patternToPlay, bool loop = true );
  294. void togglePause();
  295. void stop();
  296. void startExport();
  297. void stopExport();
  298. void setModified();
  299. void clearProject();
  300. void addBBTrack();
  301. private slots:
  302. void insertBar();
  303. void removeBar();
  304. void addSampleTrack();
  305. void addAutomationTrack();
  306. void setTempo();
  307. void setTimeSignature();
  308. void masterVolumeChanged();
  309. void savePos();
  310. void updateFramesPerTick();
  311. private:
  312. Song();
  313. Song( const Song & );
  314. virtual ~Song();
  315. inline bar_t currentBar() const
  316. {
  317. return m_playPos[m_playMode].getBar();
  318. }
  319. inline tick_t currentTick() const
  320. {
  321. return m_playPos[m_playMode].getTicks();
  322. }
  323. inline f_cnt_t currentFrame() const
  324. {
  325. return m_playPos[m_playMode].getTicks() * Engine::framesPerTick() +
  326. m_playPos[m_playMode].currentFrame();
  327. }
  328. void setPlayPos( tick_t ticks, PlayModes playMode );
  329. void saveControllerStates( QDomDocument & doc, QDomElement & element );
  330. void restoreControllerStates( const QDomElement & element );
  331. void removeAllControllers();
  332. void processAutomations(const TrackList& tracks, TimePos timeStart, fpp_t frames);
  333. void setModified(bool value);
  334. void setProjectFileName(QString const & projectFileName);
  335. AutomationTrack * m_globalAutomationTrack;
  336. IntModel m_tempoModel;
  337. MeterModel m_timeSigModel;
  338. int m_oldTicksPerBar;
  339. IntModel m_masterVolumeModel;
  340. IntModel m_masterPitchModel;
  341. ControllerVector m_controllers;
  342. int m_nLoadingTrack;
  343. QString m_fileName;
  344. QString m_oldFileName;
  345. bool m_modified;
  346. bool m_loadOnLaunch;
  347. volatile bool m_recording;
  348. volatile bool m_exporting;
  349. volatile bool m_exportLoop;
  350. volatile bool m_renderBetweenMarkers;
  351. volatile bool m_playing;
  352. volatile bool m_paused;
  353. bool m_savingProject;
  354. bool m_loadingProject;
  355. bool m_isCancelled;
  356. SaveOptions m_saveOptions;
  357. QHash<QString, int> m_errors;
  358. PlayModes m_playMode;
  359. PlayPos m_playPos[Mode_Count];
  360. bar_t m_length;
  361. const Pattern* m_patternToPlay;
  362. bool m_loopPattern;
  363. double m_elapsedMilliSeconds[Mode_Count];
  364. tick_t m_elapsedTicks;
  365. bar_t m_elapsedBars;
  366. VstSyncController m_vstSyncController;
  367. int m_loopRenderCount;
  368. int m_loopRenderRemaining;
  369. TimePos m_exportSongBegin;
  370. TimePos m_exportLoopBegin;
  371. TimePos m_exportLoopEnd;
  372. TimePos m_exportSongEnd;
  373. TimePos m_exportEffectiveLength;
  374. friend class LmmsCore;
  375. friend class SongEditor;
  376. friend class mainWindow;
  377. friend class ControllerRackView;
  378. signals:
  379. void projectLoaded();
  380. void playbackStateChanged();
  381. void playbackPositionChanged();
  382. void lengthChanged( int bars );
  383. void tempoChanged( bpm_t newBPM );
  384. void timeSignatureChanged( int oldTicksPerBar, int ticksPerBar );
  385. void controllerAdded( Controller * );
  386. void controllerRemoved( Controller * );
  387. void updateSampleTracks();
  388. void stopped();
  389. void modified();
  390. void projectFileNameChanged();
  391. } ;
  392. #endif