NiCMidi 1.1.0
A MIDI library derived from J.D.Koftinoff jdksmidi
multitrack.h
Go to the documentation of this file.
1/*
2 * NiCMidi - A C++ Class Library for MIDI
3 *
4 * Copyright (C) 2004 J.D. Koftinoff Software, Ltd.
5 * www.jdkoftinoff.com jeffk@jdkoftinoff.com
6 * Copyright (C) 2021, 2022 Nicola Cassetta
7 * https://github.com/ncassetta/NiCMidi
8 *
9 * This file is part of NiCMidi.
10 *
11 * NiCMidi is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as
13 * published by the Free Software Foundation, either version 3 of
14 * the License, or (at your option) any later version.
15 *
16 * NiCMidi is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with NiCMidi. If not, see <http://www.gnu.org/licenses/>.
23 */
24
25
29
30
31#ifndef _NICMIDI_MULTITRACK_H
32#define _NICMIDI_MULTITRACK_H
33
34#include "track.h"
35
36#include <vector>
37
38
39class MIDIEditMultiTrack; // forward declaration
40
51 public:
58 MIDIMultiTrack(unsigned int num_tracks = 0,
59 unsigned int cl_p_b = DEFAULT_CLKS_PER_BEAT);
60
64 virtual ~MIDIMultiTrack();
65
70 void Reset(unsigned int num_tracks = 0);
73 void ClearTracks(bool mantain_end = false);
74
76 unsigned int GetClksPerBeat() const { return clks_per_beat; }
79 MIDITrack* GetTrack(unsigned int trk_num) { return tracks[trk_num]; }
82 const MIDITrack* GetTrack(unsigned int trk_num) const
83 { return tracks[trk_num]; }
85 int GetTrackNum(MIDITrack* trk) const;
87 unsigned int GetNumTracks() const { return tracks.size(); }
89 unsigned int GetNumTracksWithEvents() const;
92 unsigned int GetNumEvents() const;
96 bool IsValidTrackNumber(unsigned int trk_num) const
97 { return (trk_num < tracks.size()); }
99 bool IsEmpty() const { return (GetNumEvents() == GetNumTracks() &&
100 GetEndTime() == 0); }
101
107 void SetClksPerBeat(unsigned int cl_p_b);
110 bool SetEndTime(MIDIClockTime end_time);
111
114
121 void AssignEventsToTracks (unsigned int trk_num = 0)
122 { return AssignEventsToTracks(GetTrack(trk_num)); }
128 bool InsertTrack(int trk_num = -1);
134 bool InsertTrack(const MIDITrack* trk, int trk_num = -1);
139 bool DeleteTrack(int trk_num = -1);
144 bool MoveTrack(int from, int to);
151 bool SetTrack(const MIDITrack* trk, unsigned int trk_num);
154 bool InsertEvent(unsigned int trk_num, const MIDITimedMessage& msg, tInsMode _ins_mode = INSMODE_DEFAULT);
156 bool InsertNote(unsigned int trk_num, const MIDITimedMessage& msg,
157 MIDIClockTime len, tInsMode _ins_mode = INSMODE_DEFAULT);
159 bool DeleteEvent(unsigned int trk_num, const MIDITimedMessage& msg);
161 bool DeleteNote(unsigned int trk_num, const MIDITimedMessage& msg);
162
163
164 void EditCopy(MIDIClockTime start, MIDIClockTime end, int tr_start,
165 int tr_end, MIDIEditMultiTrack* edit);
166 // makes a new interval in *edit, with tracks from tr_start to tr_end
167 void EditCut(MIDIClockTime start, MIDIClockTime end, MIDIEditMultiTrack* edit);
168 // deletes events and shifts subsequents (only on entire multitrack)
169 void EditClear(MIDIClockTime start, MIDIClockTime end, int tr_start, int tr_end);
170 // erase events in tracks tr_start ... tr_end
171 void EditInsert(MIDIClockTime start, int tr_start, int times, MIDIEditMultiTrack* edit);
172 // insert interval <edit> in <time_start>
173 // (if <edit> == 0 insert a blank interval)
174 void EditReplace(MIDIClockTime start, int tr_start, int times,
175 bool sysex, MIDIEditMultiTrack* edit);
176
177 protected:
178 unsigned int clks_per_beat;
181 std::vector<MIDITrack*> tracks; // The array of pointers to the MIDITrack objects
183};
184
185
194 // This is used only by the MIDIMultiTrackIterator, so all is protected
195 friend class MIDIMultiTrackIterator;
196
197 public:
198 // The constructor.
199 MIDIMultiTrackIteratorState(int n_tracks);
200
201 // . . . no need for dtor and others . . .
202 protected:
203 // Changes the number of tracks (this causes a reset of the state).
204 void SetNumTracks(unsigned int n);
205 // Sets the time to 0 and an undefined first event and track. Does not reset time shift mode.
206 // \warning this is, in general, **not** a valid state. Don't call this but MIDIMultiTrackIterator::Reset().
207 void Reset();
208 // Internal use.
209 int FindTrackOfFirstEvent();
210
211 unsigned int num_tracks; // The number of tracks
212 MIDIClockTime cur_time; // The current time
213 int cur_event_track; // The track of the next event
214 std::vector<int> next_event_number; // Array holding the next event for every track (or -1 if no events left)
215 std::vector<MIDIClockTime> next_event_time; // Array holding the next event time for every track
216 std::vector<bool> enabled; // Array for enabling and disabling tracks
217 bool time_shift_mode; // Time shift on/off
219};
220
221
231 public:
232
236 void Reset();
238 MIDIClockTime GetCurrentTime() const { return state.cur_time; }
240 bool GetTimeShiftMode() const { return state.time_shift_mode; }
248 const MIDIMultiTrackIteratorState& GetState() const { return state; }
252 void SetTimeShiftMode(bool f) { state.time_shift_mode = f; }
257 void SetEnable(unsigned int trk_num, bool f);
259 void SetState(const MIDIMultiTrackIteratorState& s) { state = s; }
274 bool GetNextEvent(int *track, MIDITimedMessage **msg);
280 bool GetNextEventOnTrack(int track, MIDITimedMessage **msg);
288 // Returns a pointer to the MIDIMultiTrack the iterator is attached to.
289 //MIDIMultiTrack* GetMultiTrack() { return multitrack; }
290 //const MIDIMultiTrack* GetMultiTrack() const { return multitrack; }
291
292 protected:
294 // Returns the time of the given MIDITimedMessage in the given track, taking into account the time
295 // shifting. This is the same time of the message if time shifting is off or _msg_ is not a channel
296 // or sysex message, otherwise this will return the message time plus the track offset.
297 MIDIClockTime GetShiftedTime(const MIDITimedMessage* msg, int trk);
298
299 MIDIMultiTrack* multitrack; // The MIDIMultiTrack the class refers to
300 MIDIMultiTrackIteratorState state; // The iterator state
302};
303
304
305
306class MIDIEditMultiTrack : public MIDIMultiTrack {
307 public:
308 MIDIEditMultiTrack(unsigned int cl_p_b = DEFAULT_CLKS_PER_BEAT) :
309 MIDIMultiTrack(cl_p_b), start_track(0), end_track(0) {}
310 virtual ~MIDIEditMultiTrack() {}
311
312 void SetStartTrack(int trk) { start_track = trk; }
313 void SetEndTrack(int trk) { end_track = trk; }
314 int GetStartTrack() const { return start_track; }
315 int GetEndTrack() const { return end_track; }
316
317 // these must be disabled in derived class: so they are declared but not implemented
318 void EditCopy(MIDIClockTime start, MIDIClockTime end, int tr_start,
319 int tr_end, MIDIEditMultiTrack* edit) {}
320 void EditCut(MIDIClockTime start, MIDIClockTime end, MIDIEditMultiTrack* edit) {}
321 void EditClear(MIDIClockTime start, MIDIClockTime end, int tr_start, int tr_end) {}
322 void EditInsert(MIDIClockTime start, int tr_start, int times,
323 bool sysex, MIDIEditMultiTrack* edit) {}
324 void EditReplace(MIDIClockTime start, int tr_start, int times,
325 bool sysex, MIDIEditMultiTrack* edit) {}
327
328
329 //void CopyTrack(int n, MIDIMultiTrack* trk);
330 // use operator= instead!
331 void CopyAll(MIDIMultiTrack* m);
332 // does a Clear and copy
333
334 private:
335
336 int start_track;
337 int end_track;
338
339
340};
341
342
343#endif
Holds an array of pointers to MIDITrack objects to be played simultaneously.
Definition: multitrack.h:50
bool IsValidTrackNumber(unsigned int trk_num) const
Returns true if trk_num is in thee range 0 ... GetNumTracks() - 1.
Definition: multitrack.h:96
bool InsertTrack(const MIDITrack *trk, int trk_num=-1)
Inserts a copy of the given track at position trk_num (trk_num must be in the range 0 ....
void AssignEventsToTracks(const MIDITrack *src)
This function is useful in dealing with MIDI format 0 files (with all events in an unique track).
const MIDITrack * GetTrack(unsigned int trk_num) const
Returns the pointer to the track.
Definition: multitrack.h:82
int GetTrackNum(MIDITrack *trk) const
Returns the number of the pointed track, -1 if the track is not in the multitrack.
void Reset(unsigned int num_tracks=0)
Deletes all the tracks in the Multitrack, resizes it to the given number of tracks and resets clks_pe...
MIDITrack * GetTrack(unsigned int trk_num)
Returns the pointer to the track.
Definition: multitrack.h:79
bool InsertNote(unsigned int trk_num, const MIDITimedMessage &msg, MIDIClockTime len, tInsMode _ins_mode=INSMODE_DEFAULT)
Inserts a Note On and a Note Off event into the track trk_num. See MIDITrack::InsertNote() for detail...
unsigned int GetClksPerBeat() const
Returns the MIDI clocks per beat of all tracks (i.e. the number of MIDI ticks in a quarter note).
Definition: multitrack.h:76
unsigned int GetNumTracks() const
Returns the number of allocated tracks.
Definition: multitrack.h:87
MIDIMultiTrack(const MIDIMultiTrack &mlt)
The copy constructor.
void SetClksPerBeat(unsigned int cl_p_b)
Changes the value of the clock per beat parameter for the tracks, updating the times of all MIDI even...
bool DeleteEvent(unsigned int trk_num, const MIDITimedMessage &msg)
Deletes the event msg from the track trk_num. See MIDITrack::DeleteEvent() for details.
unsigned int GetNumTracksWithEvents() const
Returns the number of tracks with events (other than EOT).
MIDIClockTime GetEndTime() const
Returns the end time of the longest track.
bool InsertEvent(unsigned int trk_num, const MIDITimedMessage &msg, tInsMode _ins_mode=INSMODE_DEFAULT)
Inserts the event msg in the track trk_num.
void ClearTracks(bool mantain_end=false)
Clears tracks events but mantains the tracks and their parameters.
bool MoveTrack(int from, int to)
Moves a track from the position from to the position to.
bool InsertTrack(int trk_num=-1)
Inserts a new empty track at position trk_num (trk_num must be in the range 0 ... GetNumTracks() - 1)...
virtual ~MIDIMultiTrack()
The destructor: The MIDIMultiTrack owns its tracks, so they are destroyed by this.
unsigned int clks_per_beat
The common clock per beat timing parameter for all tracks (this is the number of MIDI ticks for a qua...
Definition: multitrack.h:178
unsigned int GetNumEvents() const
Returns the total number of MIDI events in the multitrack (for every track there is at least the EOT)...
void AssignEventsToTracks(unsigned int trk_num=0)
The same as previous, but argument is the track number in the multitrack object himself.
Definition: multitrack.h:121
bool SetTrack(const MIDITrack *trk, unsigned int trk_num)
Copies the track trk into the position trk_num of the MIDIMultiTrack.
bool DeleteNote(unsigned int trk_num, const MIDITimedMessage &msg)
Deletes the note msg (msg must be a Note On) from the track _trk_num. See MIDITrack::DeleteNote() for...
bool DeleteTrack(int trk_num=-1)
Deletes the track trk_num and its events.
bool IsEmpty() const
Returns true if there are no events in the tracks and the end time is 0.
Definition: multitrack.h:99
MIDIMultiTrack(unsigned int num_tracks=0, unsigned int cl_p_b=DEFAULT_CLKS_PER_BEAT)
The constructor creates an object with given number of tracks (default no track) and base MIDI clocks...
void ShrinkEndTime()
Sets the time of the data end event equal to the time of the last event of every track.
bool SetEndTime(MIDIClockTime end_time)
Sets the time of the data end event to end_time.
MIDIMultiTrack & operator=(const MIDIMultiTrack &mlt)
The assignment operator.
A forward iterator for moving along a MIDIMultiTrack.
Definition: multitrack.h:230
MIDIMultiTrackIterator(MIDIMultiTrack *mlt)
The constructor creates the object and attaches it to the given MIDIMultiTrack.
void Reset()
Syncs num_tracks with the multitrack and resets time to 0. Does not reset time shift mode.
bool GetTimeShiftMode() const
Returns true if time shifting is on.
Definition: multitrack.h:240
MIDIClockTime GetCurrentTime() const
Gets the current time of the iterator.
Definition: multitrack.h:238
bool GetNextEventOnTrack(int track, MIDITimedMessage **msg)
Gets the next event in the multitrack on track track and updates the iterator state.
bool GetNextEventTime(MIDIClockTime *t) const
Gets the time of the next event in the multitrack (it can be different from current time if at curren...
bool GoToTime(MIDIClockTime time)
Goes to the given time, which becomes the current time, and sets then the current event as the first ...
const MIDIMultiTrackIteratorState & GetState() const
Gets the current MIDIMultiTrackIteratorState.
Definition: multitrack.h:248
bool GetNextEvent(int *track, MIDITimedMessage **msg)
Gets the next event in the multitrack in temporal order and updates the iterator state.
void SetEnable(unsigned int trk_num, bool f)
Enable or disable a track.
void SetTimeShiftMode(bool f)
Turns time shifting on and off.
Definition: multitrack.h:252
MIDIMultiTrackIteratorState & GetState()
Gets the current MIDIMultiTrackIteratorState.
Definition: multitrack.h:244
void SetState(const MIDIMultiTrackIteratorState &s)
Sets the given MIDIMultiTrackIteratorState as current state.
Definition: multitrack.h:259
Used by the MIDIMultiTrackIterator to keep track of the current state of the iterator.
Definition: multitrack.h:192
The MIDITimedMessage class inherits from the MIDIMessage and represents a message associated with a s...
Definition: msg.h:382
Manages a std::vector of MIDITimedMessage objects storing MIDI events, with methods for editing them.
Definition: track.h:86
unsigned long MIDIClockTime
The type of a variable which can hold a time in MIDI ticks.
Definition: midi.h:40
tInsMode
Defines the default behavior of the methods MIDITrack::InsertEvent() and MIDITrack::InsertNote() when...
Definition: track.h:54
const unsigned int DEFAULT_CLKS_PER_BEAT
The default clocks per beat parameter when initializing a MIDIMultiTrack.
Definition: midi.h:51
@ INSMODE_DEFAULT
follow the default behaviour (only used as default argument in methods MIDITrack::InsertEvent() and M...
Definition: track.h:55
Contains the definition of the classes MIDITrack and MIDITrackIterator.