Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

TSE3::PhraseEdit Class Reference

An editable Phrase data type. More...

#include <PhraseEdit.h>

Inheritance diagram for TSE3::PhraseEdit:

Inheritance graph
[legend]
Collaboration diagram for TSE3::PhraseEdit:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 PhraseEdit (int noEvents=defaultSize)
virtual ~PhraseEdit ()
void reset (const MidiData *source=0)
void tidy (Clock stopTime=-1)
void timeShift (Clock delta)
PhrasecreatePhrase (PhraseList *pl, const std::string &title="") const
MidiEventoperator[] (size_t n)
void insert (MidiEvent event)
void erase (size_t n)
void erase (MidiEvent event)
void select (size_t index)
void selectRange (size_t from, size_t to)
void deselect (size_t index)
void clearSelection ()
void invertSelection ()
bool selection () const
size_t firstSelectionIndex () const
size_t lastSelectionIndex () const
void eraseSelection ()
bool modified () const
void setModified (bool m)

Static Public Attributes

const int defaultSize = 1024
const int tollerance = Clock::PPQN/2

Detailed Description

An editable Phrase data type.

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.

Tidiness
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 []().

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.

Author:
Pete Goodliffe
Version:
3.00
See also:
MidiData

Phrase


Constructor & Destructor Documentation

TSE3::PhraseEdit::PhraseEdit int  noEvents = defaultSize  )  [explicit]
 

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()).

Parameters:
noEvents Ignorable PhraseEdit size

virtual TSE3::PhraseEdit::~PhraseEdit  )  [virtual]
 


Member Function Documentation

void TSE3::PhraseEdit::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.

Parameters:
source MidiData to copy

void TSE3::PhraseEdit::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.

Parameters:
stopTime The 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 TSE3::PhraseEdit::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

timeShift(-recordingStartTime);

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.

Parameters:
delta Clock value to add to every event

Phrase* TSE3::PhraseEdit::createPhrase PhraseList pl,
const std::string &  title = ""
const
 

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.

Parameters:
pl PhraseList to insert the new Phrase into (and from which to source a new unique name, if required)
title New Phrase's title - leave blank to have one automatically generated
Returns:
New Phrase object spawned from the data in this PhraseEdit
Exceptions:
PhraseListError 
See also:
tidy

Phrase

PhraseList

MidiEvent& TSE3::PhraseEdit::operator[] size_t  n  )  [inline]
 

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!

Parameters:
n Index
Returns:
MidiEvent at index n

void TSE3::PhraseEdit::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.

Parameters:
MidiEvent to insert
See also:
tidy

void TSE3::PhraseEdit::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.

Parameters:
n Index of MidiEvent to remove

void TSE3::PhraseEdit::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.

Parameters:
event MidiEvent to remove

void TSE3::PhraseEdit::select size_t  index  ) 
 

Selects the MidiEvent at the specified index.

See also:
deselect

selectRange

void TSE3::PhraseEdit::selectRange size_t  from,
size_t  to
 

Selects every MidiEvent between the specified indexes.

See also:
select

deselect

void TSE3::PhraseEdit::deselect size_t  index  ) 
 

Deselects the MidiEvent at the specified index.

See also:
select

void TSE3::PhraseEdit::clearSelection  ) 
 

Clears any selection.

void TSE3::PhraseEdit::invertSelection  ) 
 

Inverts the selection status of every MidiEvent.

bool TSE3::PhraseEdit::selection  )  const [inline]
 

Returns true if any MidiEvent is selected.

Returns:
Whether any MidiEvent is selected

size_t TSE3::PhraseEdit::firstSelectionIndex  )  const [inline]
 

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 TSE3::PhraseEdit::lastSelectionIndex  )  const [inline]
 

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 TSE3::PhraseEdit::eraseSelection  ) 
 

Erases any MidiEvent that has been selected.

This may cause the modified event to be raised.

bool TSE3::PhraseEdit::modified  )  const [inline]
 

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

Returns:
Whether PhraseEdit has been modified

void TSE3::PhraseEdit::setModified bool  m  )  [inline]
 

Allows you to manually set the modified status.

This may cause the modified event to be raised.

Parameters:
m New modified status.


Member Data Documentation

const int TSE3::PhraseEdit::defaultSize = 1024 [static]
 

The default maximum no events in Phrase editor. These days the editor automatically grows so this is fairly redundant.

const int TSE3::PhraseEdit::tollerance = Clock::PPQN/2 [static]
 

The time allowance given for notes to be before start time when tidying.

See also:
tidy


The documentation for this class was generated from the following file:
Generated on Wed May 25 14:46:49 2005 for TSE3 by doxygen 1.3.2