NiCMidi 1.1.0
A MIDI library derived from J.D.Koftinoff jdksmidi
track.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
28
29
30#ifndef _NICMIDI_TRACK_H
31#define _NICMIDI_TRACK_H
32
33
34#include "manager.h"
35#include "midi.h"
36#include "sysex.h"
37#include "msg.h"
38
39#include <vector>
40#include <string>
41
44
54{
60};
61
62
64enum
65{
69};
71
72
86class MIDITrack {
87 public:
90 MIDITrack(MIDIClockTime end_time = 0);
92 MIDITrack(const MIDITrack &trk);
94 virtual ~MIDITrack() {}
95 // TODO: these should not be needed!
100 void Reset();
104 void Clear(bool mantain_end = false);
105
108 unsigned int GetNumEvents() const { return events.size(); }
110 bool IsValidEventNum(int ev_num) const
111 { return (0 <= ev_num && (unsigned int)ev_num < events.size()); }
113 bool IsEmpty() const { return events.size() == 1; }
115 MIDIClockTime GetEndTime() const { return events.back().GetTime(); }
117 unsigned int GetOutPort() const { return out_port; }
119 unsigned int GetInPort() const { return in_port; }
131 unsigned char GetType();
134 int GetRecChannel() { return (int)rec_chan; }
136 int GetTimeShift() const { return time_shift; }
140 unsigned char HasSysex();
143 MIDITimedMessage* GetEventAddress(unsigned int ev_num) { return &events[ev_num]; }
146 const MIDITimedMessage* GetEventAddress(unsigned int ev_num) const { return &events[ev_num]; }
149 MIDITimedMessage& GetEvent(unsigned int ev_num) { return events[ev_num]; }
152 const MIDITimedMessage& GetEvent(unsigned int ev_num) const { return events[ev_num]; }
153
157 bool SetEndTime(MIDIClockTime end_time);
160 bool SetChannel(int chan);
163 bool SetRecChannel(int chan);
166 bool SetInPort(unsigned int port);
169 bool SetOutPort(unsigned int port);
171 void SetTimeShift(int t) { time_shift = t; }
227 bool DeleteNote(const MIDITimedMessage& msg);
231 void PushEvent(const MIDITimedMessage& msg);
237 void InsertInterval(MIDIClockTime start, MIDIClockTime length, const MIDITrack* src = 0);
238 // if src == 0 only shift events of length clocks
242 void MakeInterval(MIDIClockTime start, MIDIClockTime end, MIDITrack* interval) const;
258 // TODO: restored old version: test this (involves even interval methods)
269 bool FindEventNumber(const MIDITimedMessage& msg, int *event_num,
270 int mode = COMPMODE_EQUAL) const;
276 bool FindEventNumber (MIDIClockTime time, int *event_num) const;
277
284 static void SetInsertMode(tInsMode mode);
285
288 enum {
299 INIT_STATUS = 0xff,
302 HAS_ONE_CHAN = 0x400,
304 HAS_SYSEX = 0x1000,
306 STATUS_DIRTY = 0x4000
307 };
308
309
310 protected:
314 void Analyze();
315
317 std::vector<MIDITimedMessage>
318 events; // The buffer of events
319 int status; // A bitfield used to determine the track type
320 signed char rec_chan; // The channel for recordng, or -1 for all channels
321 int time_shift; // The time shift in MIDI ticks
322 unsigned int in_port; // The in port id for recording midi events
323 unsigned int out_port; // The out port id for playing midi events
324
325 static tInsMode ins_mode; // See SetInsertMode()
327};
328
329
336 public:
340 void Reset();
342 MIDITrack* GetTrack() { return track; }
344 const MIDITrack* GetTrack() const { return track; }
346 void SetTrack(MIDITrack* trk);
348 MIDIClockTime GetCurrentTime() const { return cur_time; }
350 unsigned int GetCurrentEventNum() const { return cur_ev_num; }
352 int16_t GetProgram() const { return program; }
354 int16_t GetControl(unsigned char c) const
355 { return controls[c]; }
357 int16_t GetBender() const { return bender_value; }
359 int GetNotesOn() const { return num_notes_on; }
361 bool IsNoteOn(unsigned char n) const
362 { return (notes_on[n] > 0); }
364 bool IsPedalOn() const { return controls[64] > 64; }
369 bool FindNoteOff(unsigned char note, MIDITimedMessage** msg);
390 bool EventIsNow(const MIDITimedMessage& msg);
391 //bool GoToNextEvent(); unused use GetNextEvent()
392
393 protected:
395
396 bool Process(const MIDITimedMessage *msg);
397 void ScanEventsAtThisTime();
398 // warning: this can be used only when we reach the first
399 // event at a new time!
400
401 MIDITrack* track;
402 unsigned int cur_ev_num; // number of the current event
403 MIDIClockTime cur_time; // current time
404
405 int16_t program; // current program change, or -1
406 int16_t controls[128]; // value of every control change, or -1
407 int16_t bender_value; // last seen bender value
408 unsigned char num_notes_on; // number of notes currently on
409 unsigned char notes_on[128]; // 0 if off, or velocity
411};
412
413
414#endif
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
int GetRecChannel()
Returns the channel for recording (-1 for all channels).
Definition: track.h:134
bool SetInPort(unsigned int port)
Sets the input port of the track.
MIDITrack(MIDIClockTime end_time=0)
The constructor creates an empty track with only the EOT event.
int GetStatus()
Returns the entire status bitfield, so you can test individual properties of the track with an AND wi...
virtual ~MIDITrack()
The destructor deletes the events in the track.
Definition: track.h:94
void ReplaceInterval(MIDIClockTime start, MIDIClockTime end, const MIDITrack *src)
Replaces events from start to end with those in src.
bool IsEmpty() const
Returns true if the track has only the EOT event.
Definition: track.h:113
MIDITrack & operator=(const MIDITrack &trk)
The assignment operator.
void SetTimeShift(int t)
Sets the track time shift in MIDI ticks.
Definition: track.h:171
void ShrinkEndTime()
Sets the time of the EOT event equal to the time of the last (non data end) event of the track.
bool SetChannel(int chan)
Sets the channel of all MIDI channel events to chan (chan must be in the range 0 ....
void MakeInterval(MIDIClockTime start, MIDIClockTime end, MIDITrack *interval) const
Copies events from start to end into the track interval.
bool SetOutPort(unsigned int port)
Sets the output port of the track.
unsigned char HasSysex()
Returns non zero if the track contains MIDI SysEx messages.
bool IsValidEventNum(int ev_num) const
Returns true if ev_num is in the range 0 ... GetNumEvents() - 1.
Definition: track.h:110
unsigned char GetType()
Returns the track type (one of TYPE_MAIN, TYPE_TEXT, TYPE_CHAN, TYPE_IRREG_CHAN, TYPE_MIXED_CHAN,...
bool SetEndTime(MIDIClockTime end_time)
Sets the time of the EOT event.
bool InsertEvent(const MIDITimedMessage &msg, tInsMode mode=INSMODE_DEFAULT)
Inserts a single event into the track.
unsigned int GetInPort() const
Returns the MIDI in port id.
Definition: track.h:119
MIDITrack(const MIDITrack &trk)
The copy constructor.
bool DeleteEvent(const MIDITimedMessage &msg)
Deletes an event from the track.
void Reset()
Deletes all events leaving the track empty (i.e. with only the EOT event) and resets time_shift,...
MIDITimedMessage & GetEvent(unsigned int ev_num)
Returns a reference to an event in the track.
Definition: track.h:149
int GetChannel()
Returns the track channel (-1 if the track has not type TYPE_CHAN or TYPE_IRREG_CHAN).
unsigned int GetNumEvents() const
Returns the number of events in the track (if the track is empty this returns 1, for the EOT event).
Definition: track.h:108
bool InsertNote(const MIDITimedMessage &msg, MIDIClockTime len, tInsMode mode=INSMODE_DEFAULT)
Inserts a Note On and a Note Off event into the track.
@ HAS_RESET_SYSEX
Flag for reset sysex.
Definition: track.h:305
@ TYPE_SYSEX
Track has only common sysex events.
Definition: track.h:296
@ TYPE_RESET_SYSEX
Track has reset sysex (GM Reset, Gs Reset, XG Reset)
Definition: track.h:297
@ TYPE_MIXED_CHAN
Track has events with more than one channel.
Definition: track.h:294
@ STATUS_DIRTY
Track was edited, must call Analyze() to update its status.
Definition: track.h:306
@ TYPE_MAIN
Track has Main meta events (time, tempo, key ...) and no channel events.
Definition: track.h:290
@ HAS_TEXT_META
Flag for text meta.
Definition: track.h:301
@ HAS_ONE_CHAN
Flag for one channel.
Definition: track.h:302
@ TYPE_CHAN
Track is a normal channel track. You can find the channel with GetChannel()
Definition: track.h:292
@ TYPE_IRREG_CHAN
Track has channel events mixed with other (it can contain Main meta events)
Definition: track.h:293
@ TYPE_TEXT
Track has only text meta events (probably lyrics)
Definition: track.h:291
@ TYPE_BOTH_SYSEX
Track has both types of sysex.
Definition: track.h:298
@ INIT_STATUS
Internal use.
Definition: track.h:299
@ HAS_MANY_CHAN
Flag for more channels.
Definition: track.h:303
@ TYPE_UNKNOWN
None of the above.
Definition: track.h:295
@ HAS_SYSEX
Flag for common sysex.
Definition: track.h:304
@ HAS_MAIN_META
Flag for Main meta.
Definition: track.h:300
@ TYPE_EMPTY
Track is empty.
Definition: track.h:289
const MIDITimedMessage * GetEventAddress(unsigned int ev_num) const
Returns the address of an event in the track.
Definition: track.h:146
MIDIClockTime GetNoteLength(const MIDITimedMessage &msg) const
Returns the length in MIDI clocks of the given note.
void ClearInterval(MIDIClockTime start, MIDIClockTime end)
Deletes events from start to end, leaving subsequents unchanged.
void DeleteInterval(MIDIClockTime start, MIDIClockTime end)
Deletes events from start to end, shifting subsequents.
void PushEvent(const MIDITimedMessage &msg)
Inserts the event as last, adjusting the data end.
void CloseOpenEvents(MIDIClockTime from, MIDIClockTime to)
Cuts note and pedal events (searching to the time from) at the time to.
static void SetInsertMode(tInsMode mode)
Sets the default behaviour for the methods InsertEvent() and InsertNote().
bool DeleteNote(const MIDITimedMessage &msg)
Deletes a Note On and corresponding Note Off events from the track.
int GetTimeShift() const
Returns the track time shift in MIDI ticks.
Definition: track.h:136
bool FindEventNumber(MIDIClockTime time, int *event_num) const
Finds the first event in the track with the given time.
MIDIClockTime GetEndTime() const
Returns the time of the EOT event (i.e. the time length of the track).
Definition: track.h:115
bool SetRecChannel(int chan)
Sets the channel for recording (-1 for all channels).
void Clear(bool mantain_end=false)
Deletes all events leaving the track empty (i.e. with only the EOT event).
void InsertInterval(MIDIClockTime start, MIDIClockTime length, const MIDITrack *src=0)
Shifts forward by a length time the track events from start onwards.
void Analyze()
Analyses the events in the track upgrading its status attribute.
unsigned int GetOutPort() const
Returns the MIDI out port id.
Definition: track.h:117
MIDITimedMessage * GetEventAddress(unsigned int ev_num)
Returns the address of an event in the track.
Definition: track.h:143
const MIDITimedMessage & GetEvent(unsigned int ev_num) const
Returns a reference to an event in the track.
Definition: track.h:152
bool FindEventNumber(const MIDITimedMessage &msg, int *event_num, int mode=COMPMODE_EQUAL) const
Finds an event in the track matching a given event.
Forward iterator for moving along a MIDITrack.
Definition: track.h:335
bool IsPedalOn() const
Returns true if the hold pedal is on at current time.
Definition: track.h:364
MIDITrack * GetTrack()
Returns a pointer to the track the iterator is attached to.
Definition: track.h:342
int GetNotesOn() const
Returns the number of notes on at current time.
Definition: track.h:359
int16_t GetProgram() const
Returns the current track program (-1 if not set).
Definition: track.h:352
bool FindPedalOff(MIDITimedMessage **msg)
Finds the next hold pedal off MIDITimedMessage in the track.
MIDITrackIterator(MIDITrack *trk)
The constructor. You must specify the track which the iterator is attached to.
bool EventIsNow(const MIDITimedMessage &msg)
Returns true if at the current time there is an event of the same kind of msg (see MIDITimedMessage::...
bool GoToTime(MIDIClockTime time)
Goes to the given time, which becomes the current time.
bool GetNextEvent(MIDITimedMessage **msg)
Returns the next event in the track.
bool FindNoteOff(unsigned char note, MIDITimedMessage **msg)
Finds the next MIDITimedMessage in the track corresponding to the note off for the given note.
bool IsNoteOn(unsigned char n) const
Returns true if the given note is on at current time.
Definition: track.h:361
unsigned int GetCurrentEventNum() const
Returns the current event number in the track.
Definition: track.h:350
bool GetNextEventTime(MIDIClockTime *t) const
Gets the time of the next event in the track.
MIDIClockTime GetCurrentTime() const
Returns the current time of the iterator.
Definition: track.h:348
int16_t GetControl(unsigned char c) const
Returns the current value for the given control (-1 if not set).
Definition: track.h:354
void SetTrack(MIDITrack *trk)
Sets the iterator track (causes a reset).
void Reset()
Sets the current time to 0, updating the iterator status.
const MIDITrack * GetTrack() const
Returns a pointer to the track the iterator is attached to.
Definition: track.h:344
int16_t GetBender() const
Returns the current bender value.
Definition: track.h:357
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
@ COMPMODE_EQUAL
the method searches for an event matching equal operator.
Definition: track.h:66
@ COMPMODE_SAMEKIND
the method searches for an event matching the MIDITimedMessage::IsSameKind() method.
Definition: track.h:67
@ COMPMODE_TIME
the method searches for the first event with time equal to the event time.
Definition: track.h:68
@ INSMODE_REPLACE
replace if a same kind event was found, otherwise do nothing.
Definition: track.h:57
@ INSMODE_DEFAULT
follow the default behaviour (only used as default argument in methods MIDITrack::InsertEvent() and M...
Definition: track.h:55
@ INSMODE_INSERT
always insert events, if a same kind event was found keep both.
Definition: track.h:56
@ INSMODE_INSERT_OR_REPLACE_BUT_NOTE
as above, but allow two same note events at same time (don't replace, insert a new note).
Definition: track.h:59
@ INSMODE_INSERT_OR_REPLACE
replace if a same kind event was found, otherwise insert.
Definition: track.h:58
Contains the definition of the static class MIDIManager.
Contains the MIDI values enumerations (to have readable values instead of hexadecimal values) and som...
Contains the definition of the classes MIDIMessage and MIDITimedMessage.
Contains the definition of the class MIDISystemExclusive.