summaryrefslogtreecommitdiff
path: root/muse_qt4_evolution/muse/song.h
blob: 3ad574a00b653b645ae1935dd2e2344d96ce525c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
//=============================================================================
//  MusE
//  Linux Music Editor
//  $Id:$
//
//  Copyright (C) 2002-2006 by Werner Schweer and others
//
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License version 2.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//=============================================================================

#ifndef __SONG_H__
#define __SONG_H__

#include "undo.h"
#include "midiinport.h"
#include "midioutport.h"
#include "miditrack.h"
#include "midisynti.h"
#include "wavetrack.h"
#include "audioinput.h"
#include "audiooutput.h"
#include "audiogroup.h"
#include "synth.h"
#include "ctrl.h"
#include "midififo.h"

namespace AL {
      class Xml;
      class Marker;
      class MarkerList;
      class Pos;
      };

struct AudioMsg;
class Event;
class Track;
class Part;
class PartList;
class Marker;
class SettingsList;

#define SC_TRACK_INSERTED     1
#define SC_TRACK_REMOVED      2
#define SC_TRACK_MODIFIED     4
#define SC_PART_INSERTED      8
#define SC_PART_REMOVED       0x10
#define SC_PART_MODIFIED      0x20
#define SC_EVENT_INSERTED     0x40
#define SC_EVENT_REMOVED      0x80
#define SC_EVENT_MODIFIED     0x100
#define SC_SIG                0x200       // timing signature
#define SC_TEMPO              0x400       // tempo map changed
#define SC_MASTER             0x800       // master flag changed
#define SC_SELECTION          0x1000
#define SC_RECFLAG            0x10000
#define SC_ROUTE              0x20000
#define SC_CHANNELS           0x40000
#define SC_CONFIG             0x80000     // midiPort-midiDevice
#define SC_DRUMMAP            0x100000    // must update drumeditor
#define SC_AUTOMATION         0x800000
#define SC_RACK               0x1000000   // mixer rack changed
#define SC_CLIP_MODIFIED      0x2000000

//---------------------------------------------------------
//    Song
//---------------------------------------------------------

class Song : public QObject {
      Q_OBJECT

   public:
      enum POS        { CPOS = 0, LPOS, RPOS };
      enum FollowMode { NO, JUMP, CONTINUOUS };
      enum            { REC_OVERDUP, REC_REPLACE };
      enum            { CYCLE_NORMAL, CYCLE_MIX, CYCLE_REPLACE };
      enum { MARKER_CUR, MARKER_ADD, MARKER_REMOVE, MARKER_NAME,
         MARKER_TICK, MARKER_LOCK };

   private:
      QString _projectPath;
      QString _comment;
      bool _backupWritten;    // set after first "save" operation from
                              // user; used to make sure there will
                              // be only one backup for a session
      bool _created;          // project was created in current session
      QDateTime _createDate;

      MidiFifo eventFifo;

      int updateFlags;

      TrackList _tracks;      // tracklist as seen by arranger
      MidiTrackList  _midis;
      WaveTrackList _waves;
      InputList _inputs;      // audio input ports
      OutputList _outputs;    // audio output ports
      GroupList _groups;      // mixer groups
      SynthIList _synthIs;
      MidiSyntiList _midiSyntis;
      MidiOutPortList _midiOutPorts;
      MidiInPortList _midiInPorts;
      Track* _selectedTrack;

      UndoList* undoList;
      UndoList* redoList;
      Pos pos[3];
      AL::MarkerList* _markerList;
      bool seekInProgress;	// user initiated a seek

      bool _masterFlag;
      bool loopFlag;
      bool punchinFlag;
      bool punchoutFlag;
      bool recordFlag;
      bool soloFlag;
      int _recMode;
      int _cycleMode;
      bool _click;
      bool _quantize;
      unsigned _len;         // song len in ticks
      int _globalPitchShift;
      void readMarker(QDomNode);
      void restartJack();
      void undoPartModify(Part* oPart, Part* nPart, bool undo);

   public slots:

      void undo();
      void redo();

      void setTempo(int t);
      void setSig(const AL::TimeSignature&);

      void setMasterFlag(bool flag);
      void setLoop(bool f);
      void setRecord(bool f);
      void setPlay(bool f);
      void setStop(bool);
      void forward();
      void rewindStart();
      void rewind();
      void setPunchin(bool f);
      void setPunchout(bool f);
      void setClick(bool val);
      void toggleClick()            { setClick(!click()); }
      void gotoLeftMarker()         { setPos(0, lPos()); }
      void gotoRightMarker()        { setPos(0, rPos()); }

      void setQuantize(bool val);
      void panic();
      void seqSignal(int fd);
      Track* addTrack(QAction*);
      void setMeasureLen(int l);
      void cmdChangePart(Part*, unsigned, unsigned);
      void cmdCreateLRPart(Track* track);
      void setPos(int, const AL::Pos&);
      void setPos(int, const AL::Pos&, bool sig, bool isSeek = true,
         bool adjustScrollbar = false);
      void routeChanged(QAction*);

   signals:
      void songChanged(int);
      void posChanged(int, const AL::Pos&, bool);
      void loopChanged(bool);
      void recordChanged(bool);
      void playChanged(bool);
      void punchinChanged(bool);
      void punchoutChanged(bool);
      void clickChanged(bool);
      void quantizeChanged(bool);
      void markerChanged(int);
      void midiPortsChanged();
      void midiEvent(const MidiEvent&);
      void trackAdded(Track*, int idx);
      void trackRemoved(Track*);
      void lenChanged(const AL::Pos&);
      void measureLenChanged(int);

      void recordChanged(Track*,bool);
      void muteChanged(Track*,bool);
      void soloChanged(Track*,bool);
      void offChanged(Track*,bool);
      void autoReadChanged(Track*,bool);
      void autoWriteChanged(Track*,bool);
      void trackSelectionChanged(Track*);
      void tempoChanged();

   public:
      Song();
      ~Song();

      void beat();
      void putEvent(const MidiEvent&);
      void endMsgCmd();
      void processMsg(AudioMsg* msg);

      bool dirty;
      bool backupWritten() const       { return _backupWritten; }
      void setBackupWritten(bool val)  { _backupWritten = val; }
      WaveTrack* bounceTrack;

      void updatePos();

      void read(QDomNode);
      void write(Xml&) const;

      void clear(bool signal);
      void update(int flags = -1);

      int globalPitchShift() const      { return _globalPitchShift; }
      void setGlobalPitchShift(int val) { _globalPitchShift = val; }

      //-----------------------------------------
      //   Marker
      //-----------------------------------------

      AL::MarkerList* marker() const { return _markerList; }
      AL::Marker* addMarker(const QString& s, const AL::Pos&);
      void removeMarker(AL::Marker*);
      AL::Marker* setMarkerName(AL::Marker*, const QString&);
      AL::Marker* setMarkerTick(AL::Marker*, int);
      AL::Marker* setMarkerLock(AL::Marker*, bool);
      void setMarkerCurrent(AL::Marker* m, bool f);

      //-----------------------------------------
      //   transport
      //-----------------------------------------

      const Pos& cPos() const       { return pos[0]; }
      const Pos& lPos() const       { return pos[1]; }
      const Pos& rPos() const       { return pos[2]; }
      unsigned cpos() const         { return pos[0].tick(); }
      unsigned lpos() const         { return pos[1].tick(); }
      unsigned rpos() const         { return pos[2].tick(); }

      bool loop() const             { return loopFlag; }
      bool record() const           { return recordFlag; }
      bool punchin() const          { return punchinFlag; }
      bool punchout() const         { return punchoutFlag; }
      bool masterFlag() const       { return _masterFlag; }
      void setRecMode(int val)      { _recMode = val; }
      int  recMode() const          { return _recMode; }
      void setCycleMode(int val)    { _cycleMode = val; }
      int cycleMode() const         { return _cycleMode; }
      bool click() const            { return _click; }
      bool quantize() const         { return _quantize; }
      void setStopPlay(bool);
      void stopRolling();

      //-----------------------------------------
      //    access tempomap/sigmap  (Mastertrack)
      //-----------------------------------------

      unsigned len() const { return _len; }
      int roundUpBar(int tick) const;
      int roundUpBeat(int tick) const;
      int roundDownBar(int tick) const;

      //-----------------------------------------
      //   event manipulations
      //-----------------------------------------

      bool addEvent(const Event&, Part*);
      void changeEvent(const Event&, const Event&, Part*);
      void deleteEvent(const Event&, Part*);
      void cmdChangeWave(QString original, QString tmpfile, unsigned sx, unsigned ex);

      //-----------------------------------------
      //   part manipulations
      //-----------------------------------------

      void cmdAddPart(Part* part);
      void addPart(Part* part);

      void cmdRemoveParts();
      void cmdRemovePart(Part* part);
      void removePart(Part* part);

      void cmdChangePart(Part* oldPart, Part* newPart);
      void changePart(Part*, Part*);

      void cmdSplitPart(Part* p, const Pos&);
      void cmdGluePart(Part* p);

      PartList* getSelectedMidiParts() const;
      PartList* getSelectedWaveParts() const;

      void cmdMovePart(Part*, unsigned, Track*);
      void cmdLinkPart(Part*, unsigned, Track*);
      void cmdCopyPart(Part*, unsigned, Track*);
      void selectPart(Part*, bool add=false);

      //-----------------------------------------
      //   track manipulations
      //-----------------------------------------

      TrackList* tracks()             { return &_tracks;       }
      MidiTrackList* midis()          { return &_midis;        }
      WaveTrackList* waves()          { return &_waves;        }
      InputList* inputs()             { return &_inputs;       }
      OutputList* outputs()           { return &_outputs;      }
      GroupList* groups()             { return &_groups;       }
      SynthIList* syntis()            { return &_synthIs;      }
      MidiOutPortList* midiOutPorts() { return &_midiOutPorts; }
      MidiSyntiList* midiSyntis()     { return &_midiSyntis;   }
      MidiInPortList* midiInPorts()   { return &_midiInPorts;  }

      bool trackExists(Track*) const;
      Track* findTrack(const QString& name) const;

      void removeTrack(Track* track);
      void removeTrack1(Track* track);
      void removeTrack2(Track* track);
      void removeTrack3(Track* track);
      void changeTrackName(Track* track, const QString&);

      void swapTracks(int i1, int i2);
      void moveTrack(Track*, Track*);
      void cmdInsertTrack(Track*, int idx);
      void insertTrack(Track*, int idx);

      void insertTrack0(Track*, int idx);
      void insertTrack1(Track*, int idx);
      void insertTrack2(Track*);
      void readRoute(QDomNode);
      std::vector<QString>* synthesizer() const;

      void deselectTracks();
      void selectTrack(Track*);

      Track* selectedTrack() const { return _selectedTrack; }
      void updateSelectedTrack();

      //-----------------------------------------
      //   undo, redo
      //-----------------------------------------

      void startUndo();
      void endUndo(int);
      void undoOp(UndoOp::UndoType, int, Track*);
      void undoOp(UndoOp::UndoType, int, int, int = 0);
      void undoOp(UndoOp::UndoType, Part*);
      void undoOp(UndoOp::UndoType, const Event& oevent, const Event& nevent, Part*);
      void undoOp(UndoOp::UndoType type, const Event& nev, Part* part);
      void undoOp(UndoOp::UndoType, SigEvent* oevent, SigEvent* nevent);
      void undoOp(UndoOp::UndoType, Part* oPart, Part* nPart);
      void undoOp(UndoOp::UndoType, Track*, int, unsigned, CVal, CVal);
      void undoOp(UndoOp::UndoType, Track*, const QString&, const QString&);
      void undoOp(UndoOp::UndoType type, const char* changedFile, const char* changeData, int startframe, int endframe);
      bool doUndo1();
      void doUndo2();
      void doUndo3();
      bool doRedo1();
      void doRedo2();
      void doRedo3();

      void addUndo(UndoOp& i);

      //-----------------------------------------
      //   Controller
      //-----------------------------------------

      void cmdAddControllerVal(Track*, Ctrl*, const Pos&, CVal);
      void cmdAddControllerVal(Track*, int, const Pos&, CVal);
      void setControllerVal(Track*, Ctrl*, CVal);
      void setControllerVal(Track*, int, CVal);

      void cmdRemoveControllerVal(Track*,int,unsigned);
      void setAutoRead(Track*,bool);
      void setAutoWrite(Track*,bool);

      //-----------------------------------------
      //   Misc/Debug
      //-----------------------------------------

      void setLen(int);
      void dumpMaster();
      void addUpdateFlags(int f)  { updateFlags |= f; }
      bool solo() const           { return soloFlag; }
      void setRecordFlag(Track*, bool);
      void setMute(Track*,bool);
      void setMonitor(Track*,bool);
      void setSolo(Track*,bool);
      void setOff(Track*,bool);

      QString projectPath() const;
      QString absoluteProjectPath() const;
      QString projectName() const;
      void setProjectPath(const QString&);
      QString comment() const           { return _comment; }
      void setComment(const QString& s) { _comment = s; }
      void setCreated(bool val)         { _created = val; }
      bool created() const              { return _created; }
      QDateTime createDate() const      { return _createDate; }

      bool read(QFile* qf);
      void read30(QDomNode node);         // muse >= 1.0
      void read20(QDomNode node);         // muse < 1.0
      void read10(QDomNode);
      void updateCurrentMarker();
      };

extern Song* song;

#endif