class PhraseEdit

An editable Phrase data type. More...

Full nameTSE3::PhraseEdit
Definition#include <PhraseEdit.h>
InheritsTSE3::MidiData [public ], TSE3::Notifier [public ]
List of all Methods
Annotated List

Public Methods

Public Members

Detailed Description

This class provides an editable MidiData area. It is the mechanism used to generate Phrase objects.

The PhraseEdit object can be used as an area into which MidiEvent data is recorded in real time (it is used by the Transport class), or as the basic data structure for a GUI Phrase editor, for example.

For this latter mode of usage, the PhraseEdit class provides a number of callbacks (see PhraseEditListener) that can be used to keep the display updated.


The state of the PhraseEdit area can be one of:

It is up to the user to know if a PhraseEdit area may be untidy and to deal with it appropriately (i.e. make sure it is never played). After having tidied the data (by calling tidy()) the only way to make the data untidy is to write a MidiEvent directly using operator[]().

When the PhraseEdit is tidy, the safest way of modifying a MidiEvent is to remove it and the reinsert the modified MidiEvent.

Managing selected MidiEvent contents

The PhraseEdit object can manage the selection status of it's MidiEvent contents. This will be useful for GUI editors that use the PhraseEdit as the underlying data buffer.

Selections are denoted by the selected bit in the MidiCommand data type. You can use select() and deselect() to alter selection states.

For convenience the PhraseEdit class remembers the index of the first and last selected MidiEvent.

Working with selections only really makes sense when the data area is tidy. You can still use the selection facilities with an untidy data area, however.

Modification status

As an extra utility for GUI uses, the PhraseEdit class manages a 'modification' status. It allows the user to find out whether the data has been modified since the last reset(), and also fires an event off the first time it is modified.

Changing the selection does not affect the modified status.

Command classes

Use the following command classes to manipute this object in a undo/redo environment.

See also: MidiData, Phrase

explicit  PhraseEdit (int noEvents = defaultSize)


Create a PhraseEdit with the given number of events space reserved.

It is not really necessary to specify this size unless you know at least how many events will be inserted and reserving them will result in a worthwhile performance increase.

The PhaseEdit is initially created in an unmodified state (see modified()).

noEventsIgnorable PhraseEdit size

 ~PhraseEdit ()



void  reset (const MidiData *source = 0)


Resets the PhraseEdit area to be a copy of the given MidiData. If the source pointer is zero, the PhraseEdit area will be blank.

The modified status value will be cleared (see modified()) which may result in the modified event being raised.

sourceMidiData to copy

void  tidy (Clock stopTime = -1)


Tidies the MidiData (usually used after recording has stopped) This does a number of things, including adding any missing MidiCommand_NoteOffs and the conversion of sustain pedal usage into elongated notes. It removes all events before time zero (with a small tollerance)

The data in the PhraseEdit at this point could be in any state. MidiCommand_NoteOffs may be collated into the correct MidiEvent, or they may be in their own event (which they will be when just recorded). Events may be in time order, or in some completely random order.

It also collates all MidiCommand_NoteOffs into the appropriate MidiCommand_NoteOns so that the PhraseEdit area will contain valid data that can be streamed out through a Playable interface.

Prior to using tidy, you may need to apply timeShift().

This may cause the modified event to be raised.

stopTimeThe time of the end of this MidiData (e.g. the time recording stopped). If no stopTime is specified then it is inferred from the last event in the MidiData.

See also: tollerance

void  timeShift (Clock delta)


Shift the time of every event in the PhraseEdit by delta (the new event times are originalTime + delta).

This operation can be applied to tidy() or untidy PhraseEdit data.

You might want to use this method when recording MidiEvent data from an external source (using the Transport class) and you haven't started recording at the time zero. Once recording has finished you can "normalise" the recorded data to a reference start time of zero by calling


If you do this, you will want to timeShift BEFORE calling tidy(), so that you won't get a whole slew of events with minus times (which would not be "tidy" data).

In order for a Phrase to play in a Part correctly, you must ensure that it has a reference start time of zero, so you should take care to perform this operation. (Alternatively, use the App::Record class which does all this for you).

If you apply this method before calling tidy, don't forget to add the delta time to the tidy()'s stopTime parameter as well.

Note that this operation can leave data untidy.

This will cause the modified event to be raised.

deltaClock value to add to every event

Phrase * createPhrase (PhraseList *pl, const std::string &title = "")



Creates a Phrase from this MidiData and inserts it into the specified PhraseList. Make sure that you have done a tidy() first.

If you don't specify a title for the new Phrase then it will automatically be given a name that is guaranteed not to be used by any other Phrase in the PhraseList (you can find out what it is with Phrase::title()).

If a Phrase with the supplied title already exists in the PhraseList then a PhraseListError is thrown, and no new Phrase is created.

plPhraseList to insert the new Phrase into (and from which to source a new unique name, if required)
titleNew Phrase's title - leave blank to have one automatically generated

Returns: New Phrase object spawned from the data in this PhraseEdit

Throws: PhraseListError

See also: tidy, Phrase, PhraseList

MidiEvent & operator[] (size_t n)


Returns the nth MidiEvent in this MidiData object.

Note that, unlike the base MidiData class, this object is modifiable.

The value returned for an index that is out of range is undefined. The size() method describes the valid values.

If you set the event directly using this method you run the risk of leaving the PhraseEdit object 'untidy'.

Any data manipulation performed via this operator will not affect the modified status, and so no modified event will be raised.

In simple terms, use this method at your own risk!


Returns: MidiEvent at index n

Reimplemented from MidiData.

void  insert (MidiEvent event)


Insert a MidiEvent into the MidiData in time order.

Important note

If this is a MidiCommand_NoteOn then you really want the MidiEvent to also hold the ballancing MidiCommand_NoteOff in its 'second half'.

If it does then you can be assured that adding the MidiEvent to a 'tidied' PhraseEdit object will leave the object still 'tidy'. If you only add a MidiCommand_NoteOn/ MidiCommand_NoteOff without the ballancing MIDI command then the PhraseEdit is left 'untidy' and any use of it to create a Phrase and/or have it's data streamed out of a Playable interface is invalid.

This restriction is important in the use of the TSE3 library, if you don't use 'tidy' MidiData then playback will produce 'undefined' (very probably wrong) output.

This may cause the modified event to be raised.

MidiEventto insert

See also: tidy

void  erase (size_t n)


Remove a MidiEvent from the MidiData. The result is undefined if the index n is invalid.

This may cause the modified event to be raised.

nIndex of MidiEvent to remove

void  erase (MidiEvent event)


Remove a MidiEvent from the MidiData. If there isn't a MidiEvent * matching this one then no change occurs.

This may cause the modified event to be raised.

eventMidiEvent to remove

void  select (size_t index)


Selects the MidiEvent at the specified index.

See also: deselect, selectRange

void  selectRange (size_t from, size_t to)


Selects every MidiEvent between the specified indexes.

See also: select, deselect

void  deselect (size_t index)


Deselects the MidiEvent at the specified index.

See also: select

void  clearSelection ()


Clears any selection.

void  invertSelection ()


Inverts the selection status of every MidiEvent.

bool  selection ()



Returns true if any MidiEvent is selected.

Returns: Whether any MidiEvent is selected

size_t  firstSelectionIndex ()



Returns the index of the first selected MidiEvent. If no MidiEvent has been selected, returns the value of size().

Returns: The index of the first selected MidiEvent

size_t  lastSelectionIndex ()



Returns the index of the last selected MidiEvent. If no MidiEvent has been selected, returns the value of size().

Returns: The index of the last selected MidiEvent

void  eraseSelection ()


Erases any MidiEvent that has been selected.

This may cause the modified event to be raised.

bool  modified ()



Returns true if the PhraseEdit has been modified since creation or the last reset().

Returns: Whether PhraseEdit has been modified

void  setModified (bool m)


Allows you to manually set the modified status.

This may cause the modified event to be raised.

mNew modified status.

static const int defaultSize


static const int tollerance