CuteLogger
Fast and simple logging solution for Qt based applications
multitrackmodel.h
1/*
2 * Copyright (c) 2013-2026 Meltytech, LLC
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef MULTITRACKMODEL_H
19#define MULTITRACKMODEL_H
20
21#include <MltPlaylist.h>
22#include <MltTractor.h>
23#include <QAbstractItemModel>
24#include <QByteArray>
25#include <QList>
26#include <QString>
27
28#include <memory>
29
30class SharedFrame;
31
32typedef enum {
33 PlaylistTrackType = 0,
34 BlackTrackType,
35 SilentTrackType,
36 AudioTrackType,
37 VideoTrackType
38} TrackType;
39
40// The role a track plays in a mix, used by the Audio Mixing Assistant to
41// decide how a track should be leveled and whether it should duck others.
42typedef enum {
43 UnassignedAudioRole = 0,
44 DialogueAudioRole,
45 BackgroundMusicAudioRole,
46 SoundEffectsAudioRole,
47 AmbienceAudioRole,
48 PremixedProgramAudioRole
49} AudioTrackRole;
50
51typedef struct
52{
53 TrackType type;
54 int number;
55 int mlt_index;
56 double audioLevel = -100.0;
57} Track;
58
59typedef QList<Track> TrackList;
60
61class MultitrackModel : public QAbstractItemModel
62{
63 Q_OBJECT
64 Q_PROPERTY(int trackHeight READ trackHeight WRITE setTrackHeight NOTIFY trackHeightChanged)
65 Q_PROPERTY(int trackHeaderWidth READ trackHeaderWidth WRITE setTrackHeaderWidth NOTIFY
66 trackHeaderWidthChanged FINAL)
67 Q_PROPERTY(double scaleFactor READ scaleFactor WRITE setScaleFactor NOTIFY scaleFactorChanged)
68 Q_PROPERTY(bool filtered READ isFiltered NOTIFY filteredChanged)
69 Q_PROPERTY(bool trackLevelIndicatorSupported READ trackLevelIndicatorSupported CONSTANT)
70 Q_PROPERTY(bool hasAudioTracks READ hasAudioTracks NOTIFY hasAudioTracksChanged)
71
72public:
74 enum {
75 NameRole = Qt::UserRole + 1,
76 CommentRole,
77 ResourceRole,
78 ServiceRole,
79 IsBlankRole,
80 StartRole,
81 DurationRole,
82 InPointRole,
83 OutPointRole,
84 FramerateRole,
85 IsMuteRole,
86 IsHiddenRole,
87 IsAudioRole,
88 AudioLevelRole,
89 AudioLevelsRole,
90 IsCompositeRole,
91 IsLockedRole,
92 FadeInRole,
93 FadeOutRole,
94 IsTransitionRole,
95 FileHashRole,
96 SpeedRole,
97 IsFilteredRole,
98 IsTopVideoRole,
99 IsBottomVideoRole,
100 IsTopAudioRole,
101 IsBottomAudioRole,
102 AudioIndexRole,
103 GroupRole,
104 GainRole,
105 GainEnabledRole,
106 IsAdjustmentRole,
107 AudioRoleRole,
108 };
109
110 explicit MultitrackModel(QObject *parent = 0);
111 ~MultitrackModel();
112
113 Mlt::Tractor *tractor() const { return m_tractor; }
114 const TrackList &trackList() const { return m_trackList; }
115
116 int rowCount(const QModelIndex &parent = QModelIndex()) const;
117 int columnCount(const QModelIndex &parent) const;
118 QVariant data(const QModelIndex &index, int role) const;
119 QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
120 QModelIndex makeIndex(int trackIndex, int clipIndex) const;
121 QModelIndex parent(const QModelIndex &index) const;
122 QHash<int, QByteArray> roleNames() const;
123 Q_INVOKABLE void audioLevelsReady(const QPersistentModelIndex &index);
124 const QByteArray *getAudioLevels(int trackIndex, int clipIndex) const;
125 void updateTrackAudioLevels(const SharedFrame &frame);
126 void updateTrackGains(int position);
127 void clearTrackAudioLevels();
128 bool createIfNeeded();
129 void addBackgroundTrack();
130 int addAudioTrack();
131 int addVideoTrack();
132 void removeTrack(int trackIndex);
133 void load();
134 void close();
135 int clipIndex(int trackIndex, int position);
136 void setClipGroup(int trackIndex, int position, int group);
137 void relinkTransitions(int trackIndex, int clipIndex);
138 bool trimClipInValid(int trackIndex, int clipIndex, int delta, bool ripple);
139 bool trimClipOutValid(int trackIndex, int clipIndex, int delta, bool ripple);
140 bool transitionOverlapValid(int fromTrack, int toTrack, int clipIndex, int position, bool ripple);
141 int trackHeight() const;
142 void setTrackHeight(int height);
143 int trackHeaderWidth() const;
144 void setTrackHeaderWidth(int width);
145 double scaleFactor() const;
146 void setScaleFactor(double scale);
147 bool isTransition(Mlt::Playlist &playlist, int clipIndex) const;
148 void insertTrack(int trackIndex, TrackType type = VideoTrackType);
149 void moveTrack(int fromTrackIndex, int toTrackIndex);
150 void insertOrAdjustBlankAt(QList<int> tracks, int position, int length);
151 bool mergeClipWithNext(int trackIndex, int clipIndex, bool dryrun);
152 std::unique_ptr<Mlt::ClipInfo> findClipByUuid(const QUuid &uuid,
153 int &trackIndex,
154 int &clipIndex);
155 std::unique_ptr<Mlt::ClipInfo> getClipInfo(int trackIndex, int clipIndex);
156 Q_INVOKABLE int clipStart(int trackIndex, int clipIndex);
157 QString getTrackName(int trackIndex);
158 AudioTrackRole getTrackRole(int trackIndex);
159 double getProjectTargetLoudness() const;
160 void setProjectTargetLoudness(double loudness);
161 int bottomVideoTrackIndex() const;
162 int mltIndexForTrack(int trackIndex) const;
163 bool checkForEmptyTracks(int trackIndex);
164 QString trackTransitionService();
165 bool trackLevelIndicatorSupported() const;
166 bool hasAudioTracks() const;
167 void beginBulkUpdate();
168 void endBulkUpdate(bool changed = true);
169 bool isBulkUpdating() const { return m_bulkUpdateDepth > 0; }
170
171signals:
172 void created();
173 void aboutToClose();
174 void closed();
175 void modified();
176 void seeked(int position, bool seekPlayer = true);
177 void trackHeightChanged();
178 void trackHeaderWidthChanged();
179 void scaleFactorChanged();
180 void showStatusMessage(QString);
181 void durationChanged();
182 void filteredChanged();
183 void hasAudioTracksChanged();
184 void reloadRequested();
185 void appended(int trackIndex, int clipIndex);
186 void inserted(int trackIndex, int clipIndex);
187 void overWritten(int trackIndex, int clipIndex);
188 void removing(Mlt::Service *service);
189 void noMoreEmptyTracks(bool isAudio);
190 void bulkUpdateFinished();
191
192public slots:
193 void refreshTrackList();
194 void setTrackName(int row, const QString &value);
195 void setTrackRole(int row, AudioTrackRole role);
196 void setTrackMute(int row, bool mute);
197 void setTrackHidden(int row, bool hidden);
198 void setTrackComposite(int row, bool composite);
199 void setTrackLock(int row, bool lock);
200 void setTrackGain(int row, double gain);
201 int trimClipIn(int trackIndex, int clipIndex, int delta, bool ripple, bool rippleAllTracks);
202 void notifyClipIn(int trackIndex, int clipIndex);
203 int trimClipOut(int trackIndex, int clipIndex, int delta, bool ripple, bool rippleAllTracks);
204 void notifyClipOut(int trackIndex, int clipIndex);
205 bool moveClip(
206 int fromTrack, int toTrack, int clipIndex, int position, bool ripple, bool rippleAllTracks);
207 int overwriteClip(int trackIndex, Mlt::Producer &clip, int position, bool seek = true);
208 QString overwrite(
209 int trackIndex, Mlt::Producer &clip, int position, bool seek = true, bool notify = true);
210 int insertClip(int trackIndex,
211 Mlt::Producer &clip,
212 int position,
213 bool rippleAllTracks,
214 bool seek = true,
215 bool notify = true);
216 int appendClip(int trackIndex, Mlt::Producer &clip, bool seek = true, bool notify = true);
217 void removeClip(int trackIndex, int clipIndex, bool rippleAllTracks);
218 void liftClip(int trackIndex, int clipIndex, bool consolidate = true);
219 void consolidateBlanks(int trackIndex);
220 void splitClip(int trackIndex, int clipIndex, int position);
221 void joinClips(int trackIndex, int clipIndex);
222 void changeGain(int trackIndex, int clipIndex, double gain);
223 void fadeIn(int trackIndex, int clipIndex, int duration);
224 void fadeOut(int trackIndex, int clipIndex, int duration);
225 bool addTransitionValid(int fromTrack, int toTrack, int clipIndex, int position, bool ripple);
226 int addTransition(int trackIndex, int clipIndex, int position, bool ripple, bool rippleAllTracks);
227 void removeTransition(int trackIndex, int clipIndex);
228 void removeTransitionByTrimIn(int trackIndex, int clipIndex, int delta);
229 void removeTransitionByTrimOut(int trackIndex, int clipIndex, int delta);
230 bool trimTransitionInValid(int trackIndex, int clipIndex, int delta);
231 bool resizeTransitionInByMoveValid(int trackIndex, int clipIndex, int position);
232 void trimTransitionIn(int trackIndex, int clipIndex, int delta, bool slip = false);
233 bool trimTransitionOutValid(int trackIndex, int clipIndex, int delta);
234 void trimTransitionOut(int trackIndex, int clipIndex, int delta, bool slip = false);
235 bool resizeTransitionValid(int trackIndex, int transitionIndex, int delta);
236 bool addTransitionByTrimInValid(int trackIndex, int clipIndex, int delta);
237 int addTransitionByTrimIn(int trackIndex, int clipIndex, int delta);
238 bool addTransitionByTrimOutValid(int trackIndex, int clipIndex, int delta);
239 void addTransitionByTrimOut(int trackIndex, int clipIndex, int delta);
240 bool removeTransitionByTrimInValid(int trackIndex, int clipIndex, int delta);
241 bool removeTransitionByTrimOutValid(int trackIndex, int clipIndex, int delta);
242 void filterAddedOrRemoved(Mlt::Producer *producer);
243 void onFilterChanged(Mlt::Service *service);
244 void reload(bool asynchronous = false);
245 void replace(int trackIndex, int clipIndex, Mlt::Producer &clip, bool copyFilters = true);
246
247private:
248 Mlt::Tractor *m_tractor;
249 TrackList m_trackList;
250 bool m_isMakingTransition;
251 bool m_trackLevelIndicatorSupported;
252 bool m_hasAudioTracks;
253 int m_trackGainPosition;
254 int m_bulkUpdateDepth = 0;
255 bool m_bulkAdjustBackgroundPending = false;
256 bool m_bulkAdjustTrackFiltersPending = false;
257 bool m_bulkRefreshBlocked = false;
258 bool m_bulkUpdateChanged = false;
259
260 void moveClipToEnd(Mlt::Playlist &playlist,
261 int trackIndex,
262 int clipIndex,
263 int position,
264 bool ripple,
265 bool rippleAllTracks);
266 void moveClipInBlank(Mlt::Playlist &playlist,
267 int trackIndex,
268 int clipIndex,
269 int position,
270 bool ripple,
271 bool rippleAllTracks,
272 int duration = 0);
273 void consolidateBlanks(Mlt::Playlist &playlist, int trackIndex);
274 void consolidateBlanksAllTracks();
275 void getAudioLevels();
276 void addBlackTrackIfNeeded();
277 void convertOldDoc();
278 void reorderMixTransitions();
279 Mlt::Transition *getTransition(const QString &name, int trackIndex) const;
280 Mlt::Filter *getFilter(const QString &name, int trackIndex) const;
281 Mlt::Filter *getFilter(const QString &name, Mlt::Service *service) const;
282 void removeBlankPlaceholder(Mlt::Playlist &playlist, int trackIndex);
283 void retainPlaylist();
284 void loadPlaylist();
285 void removeRegion(int trackIndex, int position, int length);
286 void clearMixReferences(int trackIndex, int clipIndex);
287 bool isFiltered(Mlt::Producer *producer = 0) const;
288 int getDuration();
289 void adjustServiceFilterDurations(Mlt::Service &service, int duration);
290 bool warnIfInvalid(Mlt::Service &service);
291 Mlt::Transition *getVideoBlendTransition(int trackIndex) const;
292 void refreshVideoBlendTransitions();
293 int bottomVideoTrackMltIndex() const;
294 bool hasEmptyTrack(TrackType trackType) const;
295 Mlt::Filter *ensureTrackAudioLevelFilter(Mlt::Producer *track, int mltTrackIndex) const;
296 void syncTrackAudioLevelFilterPrefixes();
297 void setTrackAudioLevel(int row, double audioLevel);
298 Mlt::Filter *ensureTrackVolumeFilter(Mlt::Producer *track);
299
300 friend class UndoHelper;
301
302private slots:
303 void adjustBackgroundDuration();
304 void adjustTrackFilters();
305};
306
307#endif // MULTITRACKMODEL_H
The SharedFrame provides thread safe access to Mlt::Frame data.
Definition sharedframe.h:49