#include <MidiScheduler.h>
Inheritance diagram for TSE3::MidiScheduler:
Public Member Functions | |
MidiScheduler () | |
virtual | ~MidiScheduler () |
const char * | implementationName () const |
size_t | numPorts () const |
bool | validPort (int port) const |
int | portNumber (size_t index) const |
size_t | numberToIndex (int number) const |
void | portNumbers (std::vector< int > &numbers) const |
const char * | portName (int port) const |
const char * | portType (int port) const |
bool | portReadable (int port) const |
bool | portWriteable (int port) const |
bool | portInternal (int port) const |
int | defaultInternalPort () const |
int | defaultExternalPort () const |
void | start (Clock startTime) |
void | start () |
void | stop (Clock stopTime=-1) |
bool | running () const |
void | moveTo (Clock moveTime, Clock newTime) |
void | moveTo (Clock moveTime) |
Clock | clock () |
int | msecs () |
int | tempo () const |
void | setTempo (int newTempo, Clock changeTime) |
bool | eventWaiting () |
MidiEvent | rx () |
void | tx (MidiCommand mc) |
void | tx (MidiEvent event) |
void | txSysEx (int port, const unsigned char *data, size_t size) |
bool | remoteControl () const |
void | setRemoteControl (bool s) |
bool | consumeRemoveEvents () const |
unsigned int | startNote () const |
void | setStartNote (unsigned int n) |
unsigned int | stopNote () const |
void | setStopNote (unsigned int n) |
Protected Member Functions | |
MidiScheduler (const MidiScheduler &) | |
MidiScheduler & | operator= (const MidiScheduler &) |
virtual const char * | impl_implementationName () const=0 |
virtual const char * | impl_portName (int port) const=0 |
virtual const char * | impl_portType (int port) const=0 |
virtual bool | impl_portReadable (int port) const=0 |
virtual bool | impl_portWriteable (int port) const=0 |
virtual void | impl_start (Clock clock)=0 |
virtual void | impl_stop (Clock clock)=0 |
virtual void | impl_moveTo (Clock moveTime, Clock newTime)=0 |
virtual Clock | impl_clock ()=0 |
virtual int | impl_msecs ()=0 |
virtual void | impl_setTempo (int tempo, Clock changeTime)=0 |
virtual bool | impl_eventWaiting ()=0 |
virtual MidiEvent | impl_rx ()=0 |
virtual void | impl_tx (MidiCommand mc)=0 |
virtual void | impl_tx (MidiEvent mc)=0 |
virtual void | impl_txSysEx (int port, const unsigned char *data, size_t size)=0 |
int | addPort (int portIndex, bool isInternal, int requestedPort=0) |
void | removePort (int portIndex) |
void | clockStarted (Clock startTime) |
void | clockStopped (Clock stopTime) |
void | clockMoved (const Clock moveTime, Clock newTime) |
void | tempoChanged (int tempo, Clock changeTime) |
int | clockToMs (Clock time) |
Clock | msToClock (int ms) |
Protected Attributes | |
Clock | startClock |
The MidiScheduler provides the interface to the MIDI system (be it a software or hardware driver). On top of this it implements a timed stream for reception and transmission of MidiEvents.
This is the TSE3 platform independant interface to the underlying MIDI hardware. (In fact, it might not even be hardware, this could be the interface to a software synth).
To create a MidiScheduler you will need to use an object derived from this class. The MidiSchedulerFactory classes help you to create this.
These ports are referenced by a unique number. You read or write data from/to ports via the MidiEvent data type. The MidiEvent has a "port" number field which identifies which port the command is destined for.
As well as having numbers, the API allows you read a port name. You can also set a "preferred" name for each port. This allows the user to give a more useful name to the port (perhaps for use in a GUI).
Port numbers are not necessarily contiguous and can have any value - this will depend on the phyiscal MIDI device in use. In order to find out what port numbers are in use use the following APIs:
Note that there are two reserved special port numbers:The MidiScheduler can notify back to its clients if the timestream has moved, or been started/stopped by a device on the MIDI connection.
If the timestream is 'stopped' the MidiScheduler class will still remember a 'current' clock value, informally known as the 'resting clock'. When you ask for the time (see MidiScheduler::clock) you will be given this 'resting clock'.
The keys that are set to be "remote controls" will not be passed up through the API in a MidiEvent if remote control is enabled.
If you switch this facility on, you have to bear in mind that the only time the MidiScheduler gets a chance to investigate the input note stream is as you consume events from it. (For simplicity it doesn't have a clever background thread implementation).
Therefore, read events from the MidiScheduler in a timely manner.
These template methods are in the protected section near the end and are all pretty easy to understand.
|
|
|
If the MidiScheduler is running, it will be stopped. |
|
|
|
Returns a string describing the particular implementation of the MidiScheduler interface.
|
|
Returns the number of port addressable by this MidiScheduler. If this changes at any point the event is raised. When a port is created it is assigned a "number" - this could be any positive integer. This is its permanent reference ID. It is the port number that is specified in the MidiCommand or MidiEvent.
|
|
Returns whether the specified port number is valid.
|
|
Returns the "index"th port, if they were held in a list. So, to get the first port number set index to 0, for the seonc give index 1, and so on. If you specify a value of numPorts or above, the result is undefined.
|
|
Converts a port number to an index. This is the reverse operation of portNumber. If the port number is not valid, this will return zero.
|
|
Empties the contents of the supplied , and inserts into it every available port number.
|
|
Returns a string describing the port with the given number. If the port number is invalid the port name will be a suitable "invalid" string, not a zero pointer.
|
|
Returns a string describing the type of the port with the given number. If the port number is invalid the port name will be a suitable "invalid" string, not a zero pointer.
|
|
Returns whether or not the port is readable. If this function returns false, then you will never receive an event from rx from this port. If the port number is invalid, this will return false.
|
|
Returns whether or not the port is writeable. If this function returns false, then you can't send MidiEvent objects out via this port (with tx). If you specify this port number in a MidiEvent given to tx, the MidiEvent will be ignored. If the port number is invalid, this will return false.
|
|
Returns whether or not the port is "internal". If this function returns false, then MidiEvent objects sent here will be transmitted vai MIDI to an external device. If the port number is invalid, this will return false.
|
|
Returns a "default" internal port number. If you don't know which internal port to use, choose this one! If there are no internal ports, this returns MidiCommand::NoPort. (The default internal port will in fact be the first registered internal port from the platform implementation of MidiScheduler).
|
|
Returns a "default" external port number. If you don't know which external port to use, choose this one! If there are no external ports, this returns MidiCommand::NoPort. (The default external port will in fact be the first registered external port from the platform implementation of MidiScheduler).
|
|
Start the scheduler clock running, set to the given time.
|
|
Start the scheduler clock at the current 'resting time' (as set by a call to stop). |
|
Stop the scheduler clock and flush the Tx buffer instantaneously. The stopTime is remembered as a 'resting time' and subsequent calls to clock will return this value.
|
|
Enquire whether the scheduler clock is running.
|
|
Without stopping, move the scheduler clock to the given time newTime at time moveTime. Any further calls to clock() after this will return times in the new time line. If the scheduler is not running, this just sets the 'resting time'.
|
|
Without stopping, move the scheduler clock immediately.
|
|
Read the scheduler clock. This works whether the scheduler is running or not. If it has been stopped then it returns the time the scheduler was stopped at (or has since been moved to) - the 'resting time'.
|
|
Read the scheduler clock in milliseconds.
|
|
Read the tempo.
|
|
Set the tempo.
|
|
Enquire whether there is any data in the input buffer. This function will return true if there has been any input from any of the readable MIDI ports that you haven't yet read.
|
|
Return and remove a MidiEvent from scheduler receive buffer. Note that it is possible for this function to return a MidiEvent with MidiCommand_Invalid status. All TSE3 classes must be able to cope with these events flying around. If there is no event waiting (see eventWaiting()) then this API will return an invalid MidiEvent.
|
|
Transmit a MidiCommand immediately. This bypasses every other scheduled MidiEvent and is sent to the hardware before them.
|
|
Adds an event to scheduler transmit buffer, to be transmitted at the appropriate time. Events must be given to this method in time order. This is regardless of what port it is destined for. Note: if this is a MidiCommand_NoteOn, then the matching MidiCommand_NoteOff part of the MidiEvent is ignored, you have to schedule that separately. If the clock is not running, the event will not be scheduled and will just be ignored.
|
|
|
|
Read the remote control status.
|
|
Sets the remote control status.
|
|
|
|
Returns the start note. When pressed this note will cause the scheduler to start.
|
|
Sets the start note.
|
|
Returns the stop note. When pushed with the shift note held down, this note will cause the scheduler to stop.
|
|
Sets the stop note.
|
|
|
|
|
|
|
|
|
Current state is guaranteed to be stopped. Don't forget to call clockStarted if the start succeeds. Implemented in TSE3::Plt::AlsaMidiScheduler, TSE3::Plt::ArtsMidiScheduler, TSE3::Plt::OSSMidiScheduler, TSE3::Plt::RiscOsMidiScheduler, TSE3::Plt::Win32MidiScheduler, TSE3::Util::StreamMidiScheduler, and TSE3::Util::NullMidiScheduler. |
|
Current state is guaranteed to be started. The Don't forget to call clockStopped if the start succeeds. Implemented in TSE3::Plt::AlsaMidiScheduler, TSE3::Plt::ArtsMidiScheduler, TSE3::Plt::OSSMidiScheduler, TSE3::Plt::RiscOsMidiScheduler, TSE3::Plt::Win32MidiScheduler, TSE3::Util::StreamMidiScheduler, and TSE3::Util::NullMidiScheduler. |
|
Guaranteed running. Don't forget to call clockMoved if the start succeeds. Implemented in TSE3::Plt::AlsaMidiScheduler, TSE3::Plt::ArtsMidiScheduler, TSE3::Plt::OSSMidiScheduler, TSE3::Plt::RiscOsMidiScheduler, TSE3::Plt::Win32MidiScheduler, TSE3::Util::StreamMidiScheduler, and TSE3::Util::NullMidiScheduler. |
|
Guaranteed running. Implemented in TSE3::Plt::AlsaMidiScheduler, TSE3::Plt::ArtsMidiScheduler, TSE3::Plt::OSSMidiScheduler, TSE3::Plt::RiscOsMidiScheduler, TSE3::Plt::Win32MidiScheduler, TSE3::Util::StreamMidiScheduler, and TSE3::Util::NullMidiScheduler. |
|
Guaranteed running. Implemented in TSE3::Plt::AlsaMidiScheduler, TSE3::Plt::ArtsMidiScheduler, TSE3::Plt::OSSMidiScheduler, TSE3::Plt::RiscOsMidiScheduler, TSE3::Plt::Win32MidiScheduler, TSE3::Util::StreamMidiScheduler, and TSE3::Util::NullMidiScheduler. |
|
Guaranteed tempo > 0. For the duration of this method, tempo() will return the old tempo value. Don't forget to call clockMoved if the start succeeds. Implemented in TSE3::Plt::AlsaMidiScheduler, TSE3::Plt::ArtsMidiScheduler, TSE3::Plt::OSSMidiScheduler, TSE3::Plt::RiscOsMidiScheduler, TSE3::Plt::Win32MidiScheduler, TSE3::Util::StreamMidiScheduler, and TSE3::Util::NullMidiScheduler. |
|
|
You'll buffer all MidiEvents recieved. Returns the top buffered MidiEvent (or MidiEvent() if none are buffered). Implemented in TSE3::Plt::AlsaMidiScheduler, TSE3::Plt::ArtsMidiScheduler, TSE3::Plt::OSSMidiScheduler, TSE3::Plt::RiscOsMidiScheduler, TSE3::Plt::Win32MidiScheduler, TSE3::Util::StreamMidiScheduler, and TSE3::Util::NullMidiScheduler. |
|
Send this MidiCommand NOW. Bypass any queued events. Timer may be running or not. Implemented in TSE3::Plt::AlsaMidiScheduler, TSE3::Plt::ArtsMidiScheduler, TSE3::Plt::OSSMidiScheduler, TSE3::Plt::RiscOsMidiScheduler, TSE3::Plt::Win32MidiScheduler, TSE3::Util::StreamMidiScheduler, and TSE3::Util::NullMidiScheduler. |
|
Puts a MidiEvent on the queue ready for transmission. You will be given MidiEvents in time order, so your buffer can be a FIFO rather than a time-ordered queue. The MidiEvent will be for some time in the future, you will have to arrange to transmit it at the appropriate point. Timer may be running or not. Implemented in TSE3::Plt::AlsaMidiScheduler, TSE3::Plt::ArtsMidiScheduler, TSE3::Plt::OSSMidiScheduler, TSE3::Plt::RiscOsMidiScheduler, TSE3::Plt::Win32MidiScheduler, TSE3::Util::StreamMidiScheduler, and TSE3::Util::NullMidiScheduler. |
|
Send a sysex package now, bypassing the transsion queue. Implemented in TSE3::Plt::AlsaMidiScheduler, TSE3::Plt::ArtsMidiScheduler, TSE3::Plt::OSSMidiScheduler, TSE3::Plt::RiscOsMidiScheduler, TSE3::Plt::Win32MidiScheduler, TSE3::Util::StreamMidiScheduler, and TSE3::Util::NullMidiScheduler. |
|
Tells the MidiScheduler that your implementation has an available MIDI port. This is safe to call in your ctor. You can suggest a port number for the MidiScheduler, but you are not necessarily guaranteed to get it. If you don't want to go to the effort of constructing a port number, always specify zero. This function returns the actual port number you have been assigned.
|
|
You don't need to call removePort in your implementation's destructor. |
|
|
|
|
|
|
|
|
|
An internal method to convert Clock values to millisecond times. |
|
|
startClock holds the scheduler clock at hardware time '0'. Many interfaces always start the timer at a reference count of zero and use this variable to work out what MidiScheduler time this is. |