1 #pragma once 2 3 #ifndef TXSHSOUNDCOLUMN_INCLUDED 4 #define TXSHSOUNDCOLUMN_INCLUDED 5 6 #include "toonz/txshcolumn.h" 7 #include "toonz/txshcell.h" 8 #include "toonz/txshsoundlevel.h" 9 #include "tsound.h" 10 11 #include <QList> 12 #include <QTimer> 13 14 #undef DVAPI 15 #undef DVVAR 16 #ifdef TOONZLIB_EXPORTS 17 #define DVAPI DV_EXPORT_API 18 #define DVVAR DV_EXPORT_VAR 19 #else 20 #define DVAPI DV_IMPORT_API 21 #define DVVAR DV_IMPORT_VAR 22 #endif 23 24 //============================================================================= 25 // forward declarations 26 class TFilePath; 27 28 //============================================================================= 29 // ColumnLevel 30 //============================================================================= 31 32 class ColumnLevel { 33 TXshSoundLevelP m_soundLevel; 34 35 /*!Offsets: in frames. Start offset is a positive number.*/ 36 int m_startOffset; 37 /*!Offsets: in frames. End offset is a positive number(to subtract to..).*/ 38 int m_endOffset; 39 40 //! Starting frame in the timeline 41 int m_startFrame; 42 43 //! frameRate 44 double m_fps; 45 46 public: 47 ColumnLevel(TXshSoundLevel *soundLevel = 0, int startFrame = -1, 48 int startOffset = -1, int endOffset = -1, double fps = -1); 49 ~ColumnLevel(); 50 ColumnLevel *clone() const; 51 52 //! Overridden from TXshLevel getSoundLevel()53 TXshSoundLevel *getSoundLevel() const { return m_soundLevel.getPointer(); } setSoundLevel(TXshSoundLevelP level)54 void setSoundLevel(TXshSoundLevelP level) { m_soundLevel = level; } 55 56 void loadData(TIStream &is); 57 void saveData(TOStream &os); 58 59 void setStartOffset(int value); getStartOffset()60 int getStartOffset() const { return m_startOffset; } 61 62 void setEndOffset(int value); getEndOffset()63 int getEndOffset() const { return m_endOffset; } 64 65 void setOffsets(int startOffset, int endOffset); 66 67 //! Return the starting frame without offsets. setStartFrame(int frame)68 void setStartFrame(int frame) { m_startFrame = frame; } getStartFrame()69 int getStartFrame() const { return m_startFrame; } 70 71 //! Return the ending frame without offsets. 72 int getEndFrame() const; 73 74 //! Return frame count without offset. 75 int getFrameCount() const; 76 77 //! Return frame count with offset. 78 int getVisibleFrameCount() const; 79 80 //! Return start frame with offset. 81 int getVisibleStartFrame() const; 82 //! Return last frame with offset. 83 int getVisibleEndFrame() const; 84 //! Updates m_startOfset and m_endOffset. 85 void updateFrameRate(double newFrameRate); 86 setFrameRate(double fps)87 void setFrameRate(double fps) { m_fps = fps; } 88 }; 89 90 //============================================================================= 91 //! The TXshSoundColumn class provides a sound column in xsheet and allows its 92 //! management through cell concept. 93 /*!Inherits \b TXshCellColumn. */ 94 //============================================================================= 95 96 class DVAPI TXshSoundColumn final : public QObject, public TXshCellColumn { 97 Q_OBJECT 98 99 PERSIST_DECLARATION(TXshSoundColumn) 100 TSoundOutputDevice *m_player; 101 102 QList<ColumnLevel *> m_levels; // owner 103 104 /*!Used to menage current playback.*/ 105 TSoundTrackP m_currentPlaySoundTrack; 106 107 //! From 0.0 to 1.0 108 double m_volume; 109 bool m_isOldVersion; 110 111 QTimer m_timer; 112 113 public: 114 TXshSoundColumn(); 115 ~TXshSoundColumn(); 116 117 TXshColumn::ColumnType getColumnType() const override; getSoundColumn()118 TXshSoundColumn *getSoundColumn() override { return this; } 119 120 bool canSetCell(const TXshCell &cell) const override; 121 122 TXshColumn *clone() const override; 123 124 /*! Clear column and set src level. */ 125 void assignLevels(const TXshSoundColumn *src); 126 127 void loadData(TIStream &is) override; 128 void saveData(TOStream &os) override; 129 130 /*! r0 : min row not empty, r1 : max row not empty. Return row count.*/ 131 int getRange(int &r0, int &r1) const override; 132 /*! Last not empty row - first not empty row. */ 133 int getRowCount() const override; 134 /*! Return max row not empty. */ 135 int getMaxFrame() const override; 136 /*! Return min row not empty.*/ 137 int getFirstRow() const override; 138 139 const TXshCell &getCell(int row) const override; 140 TXshCell getSoundCell(int row); 141 void getCells(int row, int rowCount, TXshCell cells[]) override; 142 143 bool setCell(int row, const TXshCell &cell) override; 144 /*! Return false if cannot set cells.*/ 145 bool setCells(int row, int rowCount, const TXshCell cells[]) override; 146 147 void insertEmptyCells(int row, int rowCount) override; 148 149 void clearCells(int row, int rowCount) override; 150 void removeCells(int row, int rowCount) override; 151 152 /*! Check if frames from \b row to \b row+rowCount are in sequence and 153 * collapse level if it is true. */ 154 void updateCells(int row, int rowCount); 155 156 /*! Modify range of level sound in row. Return new range value of the level in 157 row. 158 N.B. Row must be the first or last cell of a sound level. */ 159 int modifyCellRange(int row, int delta, bool modifyStartValue); 160 161 bool isCellEmpty(int row) const override; 162 /*! r0 : min row not empty of level in row, r1 : max row not empty of level in 163 row. 164 Return true if level range is not empty.*/ 165 bool getLevelRange(int row, int &r0, int &r1) const override; 166 /*! r0 : min possible (without offset) row of level in row, r1 : max possible 167 (without offset) row of level in row. 168 Return true if level range is not empty.*/ 169 bool getLevelRangeWithoutOffset(int row, int &r0, int &r1) const; 170 171 /*! Only debug. */ 172 void checkColumn() const override; 173 174 void setXsheet(TXsheet *xsheet) override; 175 void setFrameRate(double fps); 176 void updateFrameRate(double fps); 177 178 //! From 0.0 to 1.0 179 void setVolume(double value); 180 double getVolume() const; 181 getCurrentPlaySoundTruck()182 TSoundTrackP getCurrentPlaySoundTruck() { return m_currentPlaySoundTrack; } 183 184 //! s0 and s1 are samples 185 void play(TSoundTrackP soundtrack, int s0, int s1, bool loop); 186 /*! Play the whole soundSequence, currentFrame it is used to compute an offset 187 when the user play a single level and hence the audio behind..*/ 188 void play(ColumnLevel *ss, int currentFrame); 189 void play(int currentFrame = 0); 190 void stop(); 191 192 bool isPlaying() const; 193 194 void scrub(int fromFrame, int toFrame); 195 196 TSoundTrackP getOverallSoundTrack( 197 int fromFrame = -1, int toFram = -1, double fps = -1, 198 TSoundTrackFormat format = TSoundTrackFormat()); 199 200 TSoundTrackP mixingTogether(const std::vector<TXshSoundColumn *> &vect, 201 int fromFrame = -1, int toFram = -1, 202 double fps = -1); 203 204 protected: 205 bool setCell(int row, const TXshCell &cell, bool updateSequence); 206 void removeCells(int row, int rowCount, bool shift); 207 208 void setCellInEmptyFrame(int row, const TXshCell &cell); 209 210 /*! If index == -1 insert soundColumnLevel at last and than order 211 * soundColumnLevel by startFrame. */ 212 void insertColumnLevel(ColumnLevel *columnLevel, int index = -1); 213 void removeColumnLevel(ColumnLevel *columnLevel); 214 215 ColumnLevel *getColumnLevelByFrame(int frame) const; 216 ColumnLevel *getColumnLevel(int index); 217 int getColumnLevelIndex(ColumnLevel *ss) const; 218 void clear(); 219 220 protected slots: 221 void onTimerOut(); 222 }; 223 224 #ifdef _WIN32 225 template class DV_EXPORT_API TSmartPointerT<TXshSoundColumn>; 226 #endif 227 typedef TSmartPointerT<TXshSoundColumn> TXshSoundColumnP; 228 229 #endif 230