NiCMidi 1.1.0
A MIDI library derived from J.D.Koftinoff jdksmidi
MIDITrack Class Reference

Manages a std::vector of MIDITimedMessage objects storing MIDI events, with methods for editing them. More...

#include <track.h>

Public Types

enum  {
  TYPE_EMPTY = 0 , TYPE_MAIN = 1 , TYPE_TEXT = 2 , TYPE_CHAN = 3 ,
  TYPE_IRREG_CHAN = 4 , TYPE_MIXED_CHAN = 5 , TYPE_UNKNOWN = 6 , TYPE_SYSEX = 7 ,
  TYPE_RESET_SYSEX = 8 , TYPE_BOTH_SYSEX = 9 , INIT_STATUS = 0xff , HAS_MAIN_META = 0x100 ,
  HAS_TEXT_META = 0x200 , HAS_ONE_CHAN = 0x400 , HAS_MANY_CHAN = 0x800 , HAS_SYSEX = 0x1000 ,
  HAS_RESET_SYSEX = 0x2000 , STATUS_DIRTY = 0x4000
}
 Used in the content analysis of a track. More...
 

Public Member Functions

 MIDITrack (MIDIClockTime end_time=0)
 The constructor creates an empty track with only the EOT event. More...
 
 MIDITrack (const MIDITrack &trk)
 The copy constructor. More...
 
virtual ~MIDITrack ()
 The destructor deletes the events in the track. More...
 
MIDITrackoperator= (const MIDITrack &trk)
 The assignment operator. More...
 
void Reset ()
 Deletes all events leaving the track empty (i.e. with only the EOT event) and resets time_shift, in_port, out_port to 0. More...
 
void Clear (bool mantain_end=false)
 Deletes all events leaving the track empty (i.e. with only the EOT event). More...
 
unsigned int GetNumEvents () const
 Returns the number of events in the track (if the track is empty this returns 1, for the EOT event). More...
 
bool IsValidEventNum (int ev_num) const
 Returns true if ev_num is in the range 0 ... GetNumEvents() - 1. More...
 
bool IsEmpty () const
 Returns true if the track has only the EOT event. More...
 
MIDIClockTime GetEndTime () const
 Returns the time of the EOT event (i.e. the time length of the track). More...
 
unsigned int GetOutPort () const
 Returns the MIDI out port id. More...
 
unsigned int GetInPort () const
 Returns the MIDI in port id. More...
 
int GetChannel ()
 Returns the track channel (-1 if the track has not type TYPE_CHAN or TYPE_IRREG_CHAN). More...
 
int GetStatus ()
 Returns the entire status bitfield, so you can test individual properties of the track with an AND with one of its bits. More...
 
unsigned char GetType ()
 Returns the track type (one of TYPE_MAIN, TYPE_TEXT, TYPE_CHAN, TYPE_IRREG_CHAN, TYPE_MIXED_CHAN, TYPE_UNKNOWN, TYPE_SYSEX, TYPE_RESET_SYSEX, TYPE_BOTH_SYSEX). More...
 
int GetRecChannel ()
 Returns the channel for recording (-1 for all channels). More...
 
int GetTimeShift () const
 Returns the track time shift in MIDI ticks. More...
 
unsigned char HasSysex ()
 Returns non zero if the track contains MIDI SysEx messages. More...
 
MIDITimedMessageGetEventAddress (unsigned int ev_num)
 Returns the address of an event in the track. More...
 
const MIDITimedMessageGetEventAddress (unsigned int ev_num) const
 Returns the address of an event in the track. More...
 
MIDITimedMessageGetEvent (unsigned int ev_num)
 Returns a reference to an event in the track. More...
 
const MIDITimedMessageGetEvent (unsigned int ev_num) const
 Returns a reference to an event in the track. More...
 
bool SetEndTime (MIDIClockTime end_time)
 Sets the time of the EOT event. More...
 
bool SetChannel (int chan)
 Sets the channel of all MIDI channel events to chan (chan must be in the range 0 ... 15). More...
 
bool SetRecChannel (int chan)
 Sets the channel for recording (-1 for all channels). More...
 
bool SetInPort (unsigned int port)
 Sets the input port of the track. More...
 
bool SetOutPort (unsigned int port)
 Sets the output port of the track. More...
 
void SetTimeShift (int t)
 Sets the track time shift in MIDI ticks. More...
 
void ShrinkEndTime ()
 Sets the time of the EOT event equal to the time of the last (non data end) event of the track. More...
 
MIDIClockTime GetNoteLength (const MIDITimedMessage &msg) const
 Returns the length in MIDI clocks of the given note. More...
 
bool InsertEvent (const MIDITimedMessage &msg, tInsMode mode=INSMODE_DEFAULT)
 Inserts a single event into the track. More...
 
bool InsertNote (const MIDITimedMessage &msg, MIDIClockTime len, tInsMode mode=INSMODE_DEFAULT)
 Inserts a Note On and a Note Off event into the track. More...
 
bool DeleteEvent (const MIDITimedMessage &msg)
 Deletes an event from the track. More...
 
bool DeleteNote (const MIDITimedMessage &msg)
 Deletes a Note On and corresponding Note Off events from the track. More...
 
void PushEvent (const MIDITimedMessage &msg)
 Inserts the event as last, adjusting the data end. More...
 
void InsertInterval (MIDIClockTime start, MIDIClockTime length, const MIDITrack *src=0)
 Shifts forward by a length time the track events from start onwards. More...
 
void MakeInterval (MIDIClockTime start, MIDIClockTime end, MIDITrack *interval) const
 Copies events from start to end into the track interval. More...
 
void DeleteInterval (MIDIClockTime start, MIDIClockTime end)
 Deletes events from start to end, shifting subsequents. More...
 
void ClearInterval (MIDIClockTime start, MIDIClockTime end)
 Deletes events from start to end, leaving subsequents unchanged. More...
 
void ReplaceInterval (MIDIClockTime start, MIDIClockTime end, const MIDITrack *src)
 Replaces events from start to end with those in src. More...
 
void CloseOpenEvents (MIDIClockTime from, MIDIClockTime to)
 Cuts note and pedal events (searching to the time from) at the time to. More...
 
bool FindEventNumber (const MIDITimedMessage &msg, int *event_num, int mode=COMPMODE_EQUAL) const
 Finds an event in the track matching a given event. More...
 
bool FindEventNumber (MIDIClockTime time, int *event_num) const
 Finds the first event in the track with the given time. More...
 

Static Public Member Functions

static void SetInsertMode (tInsMode mode)
 Sets the default behaviour for the methods InsertEvent() and InsertNote(). More...
 

Protected Member Functions

void Analyze ()
 Analyses the events in the track upgrading its status attribute. More...
 

Detailed Description

Manages a std::vector of MIDITimedMessage objects storing MIDI events, with methods for editing them.

Events are ordered by time and a MIDITrack has at least the MIDI data end meta-event (EOT) at its end (it cannot be deleted). Moreover, the Analyze() method examines the events in a track, classifying it into various types (for example, a master track contains only MIDI meta events, a single channel track contains events with the same MIDI channel, etc.) useful for editing purposes.

The following parameters are associated with the track:

  • The out port for playing
  • The in port for recording
  • The recording channel
  • The time shifting amount (in MIDI ticks)
Examples
test_advancedsequencer.cpp, test_advancedsequencer_noinput.cpp, test_recorder.cpp, test_sequencer.cpp, test_stepsequencer.cpp, and test_writefile.cpp.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum

Used in the content analysis of a track.

Values 0 ... 9 are track status types (which you can get with the GetStatus() method), others are for internal use.

Enumerator
TYPE_EMPTY 

Track is empty.

TYPE_MAIN 

Track has Main meta events (time, tempo, key ...) and no channel events.

TYPE_TEXT 

Track has only text meta events (probably lyrics)

TYPE_CHAN 

Track is a normal channel track. You can find the channel with GetChannel()

TYPE_IRREG_CHAN 

Track has channel events mixed with other (it can contain Main meta events)

TYPE_MIXED_CHAN 

Track has events with more than one channel.

TYPE_UNKNOWN 

None of the above.

TYPE_SYSEX 

Track has only common sysex events.

TYPE_RESET_SYSEX 

Track has reset sysex (GM Reset, Gs Reset, XG Reset)

TYPE_BOTH_SYSEX 

Track has both types of sysex.

INIT_STATUS 

Internal use.

HAS_MAIN_META 

Flag for Main meta.

HAS_TEXT_META 

Flag for text meta.

HAS_ONE_CHAN 

Flag for one channel.

HAS_MANY_CHAN 

Flag for more channels.

HAS_SYSEX 

Flag for common sysex.

HAS_RESET_SYSEX 

Flag for reset sysex.

STATUS_DIRTY 

Track was edited, must call Analyze() to update its status.

Constructor & Destructor Documentation

◆ MIDITrack() [1/2]

MIDITrack::MIDITrack ( MIDIClockTime  end_time = 0)

The constructor creates an empty track with only the EOT event.

Parameters
end_timethe MIDI clock time of the EOT; this become the "time length" of the track

◆ MIDITrack() [2/2]

MIDITrack::MIDITrack ( const MIDITrack trk)

The copy constructor.

◆ ~MIDITrack()

virtual MIDITrack::~MIDITrack ( )
inlinevirtual

The destructor deletes the events in the track.

Member Function Documentation

◆ operator=()

MIDITrack & MIDITrack::operator= ( const MIDITrack trk)

The assignment operator.

◆ Reset()

void MIDITrack::Reset ( )

Deletes all events leaving the track empty (i.e. with only the EOT event) and resets time_shift, in_port, out_port to 0.

◆ Clear()

void MIDITrack::Clear ( bool  mantain_end = false)

Deletes all events leaving the track empty (i.e. with only the EOT event).

Parameters
mantain_endIf it is true the method doesn't change the time of the EOT, otherwise sets it to 0.

◆ GetNumEvents()

unsigned int MIDITrack::GetNumEvents ( ) const
inline

Returns the number of events in the track (if the track is empty this returns 1, for the EOT event).

◆ IsValidEventNum()

bool MIDITrack::IsValidEventNum ( int  ev_num) const
inline

Returns true if ev_num is in the range 0 ... GetNumEvents() - 1.

◆ IsEmpty()

bool MIDITrack::IsEmpty ( ) const
inline

Returns true if the track has only the EOT event.

◆ GetEndTime()

MIDIClockTime MIDITrack::GetEndTime ( ) const
inline

Returns the time of the EOT event (i.e. the time length of the track).

◆ GetOutPort()

unsigned int MIDITrack::GetOutPort ( ) const
inline

Returns the MIDI out port id.

◆ GetInPort()

unsigned int MIDITrack::GetInPort ( ) const
inline

Returns the MIDI in port id.

◆ GetChannel()

int MIDITrack::GetChannel ( )

Returns the track channel (-1 if the track has not type TYPE_CHAN or TYPE_IRREG_CHAN).

See Numbering conventions

Note
This is not const, because it may call Analyze(), causing an update of the track status.
Examples
test_recorder.cpp.

◆ GetStatus()

int MIDITrack::GetStatus ( )

Returns the entire status bitfield, so you can test individual properties of the track with an AND with one of its bits.

Note
This is not const, because it may call Analyze(), causing an update of the track status.

◆ GetType()

unsigned char MIDITrack::GetType ( )

Returns the track type (one of TYPE_MAIN, TYPE_TEXT, TYPE_CHAN, TYPE_IRREG_CHAN, TYPE_MIXED_CHAN, TYPE_UNKNOWN, TYPE_SYSEX, TYPE_RESET_SYSEX, TYPE_BOTH_SYSEX).

Note
This is not const, because it may call Analyze(), causing an update of the track status.

◆ GetRecChannel()

int MIDITrack::GetRecChannel ( )
inline

Returns the channel for recording (-1 for all channels).

See Numbering conventions

Examples
test_recorder.cpp.

◆ GetTimeShift()

int MIDITrack::GetTimeShift ( ) const
inline

Returns the track time shift in MIDI ticks.

◆ HasSysex()

unsigned char MIDITrack::HasSysex ( )

Returns non zero if the track contains MIDI SysEx messages.

In this case it can return one of TYPE_SYSEX, TYPE_RESET_SYSEX or TYPE_BOTH_SYSEX.

Note
This is not const, because it may call Analyze(), causing an update of the track status.

◆ GetEventAddress() [1/2]

MIDITimedMessage * MIDITrack::GetEventAddress ( unsigned int  ev_num)
inline

Returns the address of an event in the track.

Parameters
ev_numthe index of the event in the track (must be in the range 0 ... GetNumEvents() - 1).

◆ GetEventAddress() [2/2]

const MIDITimedMessage * MIDITrack::GetEventAddress ( unsigned int  ev_num) const
inline

Returns the address of an event in the track.

Parameters
ev_numthe index of the event in the track (must be in the range 0 ... GetNumEvents() - 1).

◆ GetEvent() [1/2]

MIDITimedMessage & MIDITrack::GetEvent ( unsigned int  ev_num)
inline

Returns a reference to an event in the track.

Parameters
ev_numthe index of the event in the track (must be in the range 0 ... GetNumEvents() - 1).
Examples
test_stepsequencer.cpp.

◆ GetEvent() [2/2]

const MIDITimedMessage & MIDITrack::GetEvent ( unsigned int  ev_num) const
inline

Returns a reference to an event in the track.

Parameters
ev_numthe index of the event in the track (must be in the range 0 ... GetNumEvents() - 1).

◆ SetEndTime()

bool MIDITrack::SetEndTime ( MIDIClockTime  end_time)

Sets the time of the EOT event.

Parameters
end_timethe new EOT time. If there are events of other type after it the method fails and returns false.

◆ SetChannel()

bool MIDITrack::SetChannel ( int  chan)

Sets the channel of all MIDI channel events to chan (chan must be in the range 0 ... 15).

Returns
true if events were changed, false otherwise (ch was not a valid channel number).

◆ SetRecChannel()

bool MIDITrack::SetRecChannel ( int  chan)

Sets the channel for recording (-1 for all channels).

Returns
true if chan was in the correct range, false otherwise).

◆ SetInPort()

bool MIDITrack::SetInPort ( unsigned int  port)

Sets the input port of the track.

Returns
true if port is a valid port number, false otherwise.

◆ SetOutPort()

bool MIDITrack::SetOutPort ( unsigned int  port)

Sets the output port of the track.

Returns
true if port is a valid port number, false otherwise.

◆ SetTimeShift()

void MIDITrack::SetTimeShift ( int  t)
inline

Sets the track time shift in MIDI ticks.

◆ ShrinkEndTime()

void MIDITrack::ShrinkEndTime ( )

Sets the time of the EOT event equal to the time of the last (non data end) event of the track.

◆ GetNoteLength()

MIDIClockTime MIDITrack::GetNoteLength ( const MIDITimedMessage msg) const

Returns the length in MIDI clocks of the given note.

msg must be a Note On event present in the track (otherwise the function will return 0). It returns TIME_INFINITE if doesn't find the corresponding Note Off event in the track.

◆ InsertEvent()

bool MIDITrack::InsertEvent ( const MIDITimedMessage msg,
tInsMode  mode = INSMODE_DEFAULT 
)

Inserts a single event into the track.

It could be used for inserting Note On and Note Off events, but this is better done by InsertNote() which inserts both with a single call. The method handles automatically the data end message, moving it if needed, so you must not deal with it. It also determines the correct position of events with same MIDI time, using the MIDITimedMessage::CompareEventsForInsert() method for comparison.

Parameters
msgthe event to insert.
modethis determines the behaviour of the method if it finds an equal or similar event with same MIDI time in the track: it may replace the event or insert a new event anyway. If you leave the default parameter (INSMODE_DEFAULT) the method will follow the behaviour set by the static method SetInsertMode(), otherwise you may override it giving the last parameter. For details see INSMODE_DEFAULT (default), INSMODE_REPLACE, INSMODE_INSERT_OR_REPLACE, INSMODE_INSERT_OR_REPLACE_BUT_NOTE.
Returns
false in some situations in which the method cannot insert:
  • msg was an EndOfTrack (you cannot insert it)
  • __ins_mode_ was INSMODE_REPLACE but there is no event to replace
  • a memory error occurred. otherwise true.
Examples
test_advancedsequencer_noinput.cpp, test_stepsequencer.cpp, and test_writefile.cpp.

◆ InsertNote()

bool MIDITrack::InsertNote ( const MIDITimedMessage msg,
MIDIClockTime  len,
tInsMode  mode = INSMODE_DEFAULT 
)

Inserts a Note On and a Note Off event into the track.

Use this method for inserting note messages as InsertEvent() doesn't check the correct order of note on/note off. It handles automatically the EndOfTrack message, moving it if needed, so you must not deal with it. It also determines the correct position of events with same MIDI time, using the MIDITimedMessage::CompareEventsForInsert() method for comparison (so a Note Off always precedes a Note On with same time).

Parameters
msgmust be a Note On event.
lenthe length of the note: the method will create a Note Off event and put it after len MIDI clocks in the track.
modethe same for InsertEvent() (when replacing a note, the method finds and deletes both the old Note On and Note Off events).
Returns
false in some situations in which the method cannot insert:
  • msg was not a Note On event
  • mode was INSMODE_REPLACE but there is no event to replace
  • a memory error occurred. otherwise true.
Examples
test_advancedsequencer_noinput.cpp, test_stepsequencer.cpp, and test_writefile.cpp.

◆ DeleteEvent()

bool MIDITrack::DeleteEvent ( const MIDITimedMessage msg)

Deletes an event from the track.

Use DeleteNote() for safely deleting both Note On and Note Off. You cannot delete the data end event.

Parameters
msga copy of the event to delete.
Returns
false if an exact copy of the event was not found, or if a memory error occurred, otherwise true.
Examples
test_stepsequencer.cpp.

◆ DeleteNote()

bool MIDITrack::DeleteNote ( const MIDITimedMessage msg)

Deletes a Note On and corresponding Note Off events from the track.

Don't use DeleteEvent() for deleting notes.

Parameters
msga copy of the Note On event to delete.
Returns
false if an exact copy of the event was not found, or if a memory error occurred, otherwise true.
Examples
test_stepsequencer.cpp.

◆ PushEvent()

void MIDITrack::PushEvent ( const MIDITimedMessage msg)

Inserts the event as last, adjusting the data end.

This function should be used with caution, as it doesn't check temporal order and track consistency. You could use it if you would manually copy tracks (MIDIMultiTrack::AssignEventsToTracks() does it).

◆ InsertInterval()

void MIDITrack::InsertInterval ( MIDIClockTime  start,
MIDIClockTime  length,
const MIDITrack src = 0 
)

Shifts forward by a length time the track events from start onwards.

If src == 0 it leaves the newly created interval empty, otherwise copies the contents of src into it. The events in the time interval 0 ... length in src are copied into the start ... start + length times in the actual track. If the src end time is greater than length the copy process is truncated.

Warning
This is still experimental, not tested enough

◆ MakeInterval()

void MIDITrack::MakeInterval ( MIDIClockTime  start,
MIDIClockTime  end,
MIDITrack interval 
) const

Copies events from start to end into the track interval.

The events from start to end times in the actual track are copied into the 0 ... end - start times in interval.

Warning
This is still experimental, not tested enough

◆ DeleteInterval()

void MIDITrack::DeleteInterval ( MIDIClockTime  start,
MIDIClockTime  end 
)

Deletes events from start to end, shifting subsequents.

Warning
This is still experimental, not tested enough

◆ ClearInterval()

void MIDITrack::ClearInterval ( MIDIClockTime  start,
MIDIClockTime  end 
)

Deletes events from start to end, leaving subsequents unchanged.

Warning
This is still experimental, not tested enough

◆ ReplaceInterval()

void MIDITrack::ReplaceInterval ( MIDIClockTime  start,
MIDIClockTime  end,
const MIDITrack src 
)

Replaces events from start to end with those in src.

The events in the time interval 0 ... end - start in src are copied into the start ... end times in the actual track. If the src end time is greater than end - start the copy process is truncated.

Warning
This is still experimental, not tested enough

◆ CloseOpenEvents()

void MIDITrack::CloseOpenEvents ( MIDIClockTime  from,
MIDIClockTime  to 
)

Cuts note and pedal events (searching to the time from) at the time to.

All sounding notes and held pedals are truncated (the corresponding off events after the time to are deleted) and the pitch bend is reset. Events at time to are not truncated. This function is intended for "slicing" a track in cut, copy and paste editing.

◆ FindEventNumber() [1/2]

bool MIDITrack::FindEventNumber ( const MIDITimedMessage msg,
int *  event_num,
int  mode = COMPMODE_EQUAL 
) const

Finds an event in the track matching a given event.

Parameters
[in]msgthe event to look for
[out]event_numcontains the event number in the track if the event was found; otherwise it contains -1 if event time was invalid, or the number of the first event with the same event time.
[in]mode(compare mode) an enum value with the following meaning.
Returns
true if an event matching msg was found, false otherwise.
Examples
test_stepsequencer.cpp.

◆ FindEventNumber() [2/2]

bool MIDITrack::FindEventNumber ( MIDIClockTime  time,
int *  event_num 
) const

Finds the first event in the track with the given time.

Parameters
[in]timethe time to look for.
[out]event_numcontains the event number in the track if an event was found; otherwise it contains -1 if time was invalid, or the number of the last event before time.
Returns
true if an event with given time was found, false otherwise.

◆ SetInsertMode()

static void MIDITrack::SetInsertMode ( tInsMode  mode)
static

Sets the default behaviour for the methods InsertEvent() and InsertNote().

This can be overriden by them by mean of the last (default) parameter.

Parameters
modeone of INSMODE_INSERT, INSMODE_REPLACE, INSMODE_INSERT_OR_REPLACE, INSMODE_INSERT_OR_REPLACE_BUT_NOTE; default is INSMODE_INSERT_OR_REPLACE.
Note
INSMODE_DEFAULT is used only in the insert methods (as default argument) and does nothing if given as parameter here.

◆ Analyze()

void MIDITrack::Analyze ( )
protected

Analyses the events in the track upgrading its status attribute.

This is called automatically by GetType() when needed (i.e. the track was edited by one of the above methods and the status is no more valid), so has no utility for the user.


The documentation for this class was generated from the following file: