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

TSE3::MidiScheduler Class Reference

A MIDI interface providing scheduling facilities. More...

#include <MidiScheduler.h>

Inheritance diagram for TSE3::MidiScheduler:

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

Collaboration graph
[legend]
List of all members.

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 &)
MidiScheduleroperator= (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

Detailed Description

A MIDI interface providing scheduling facilities.

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.

Ports
The interface provides a number of MIDI "ports" (which may be added to or removed at run time, depending on the type of system TSE3 is running on).

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:
Time
As well as managing the MIDI ports, the MidiScheduler looks after a clock that it used to schedule delivery of these events. The API allows you to start/stop/move the time line, as well as set the clock's tempo.

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'.

Remote control
Additionally, the MidiScheduler provides a MIDI remote control facility, where certain MIDI notes can trigger transport start/stop.

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.

That's all folks
The MidiScheduler class does not incorporate a lot of other fancy utilities, like channel/port remapping, for example. Higher level TSE3 components do this, for example the MidiMapper class. The Transport class ties this all together.

Implementing a MidiScheduler
If you are porting TSE3 to another platform, you will need to implement this MidiScheduler interface. It uses the template method pattern (GoF book) - you have to implement a few member functions and the base MidiScheduler class looks after most of the logic.

These template methods are in the protected section near the end and are all pretty easy to understand.

Author:
Pete Goodliffe
Version:
3.01
See also:
MidiEvent


Constructor & Destructor Documentation

TSE3::MidiScheduler::MidiScheduler  ) 
 

virtual TSE3::MidiScheduler::~MidiScheduler  )  [virtual]
 

If the MidiScheduler is running, it will be stopped.

TSE3::MidiScheduler::MidiScheduler const MidiScheduler  )  [protected]
 


Member Function Documentation

const char* TSE3::MidiScheduler::implementationName  )  const [inline]
 

Returns a string describing the particular implementation of the MidiScheduler interface.

Returns:
Implementation name string

size_t TSE3::MidiScheduler::numPorts  )  const [inline]
 

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:
Number of MIDI ports this MidiScheduler provides

bool TSE3::MidiScheduler::validPort int  port  )  const
 

Returns whether the specified port number is valid.

Parameters:
port MIDI port number
Returns:
true if there is currently a port with that number

int TSE3::MidiScheduler::portNumber size_t  index  )  const [inline]
 

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.

Parameters:
index value
Returns:
Port number with specified index
See also:
numPorts

portNumbers

numberToIndex

size_t TSE3::MidiScheduler::numberToIndex int  number  )  const
 

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.

Parameters:
number Port number
Returns:
"Index" of this port
See also:
portNumber

void TSE3::MidiScheduler::portNumbers std::vector< int > &  numbers  )  const
 

Empties the contents of the supplied , and inserts into it every available port number.

Parameters:
numbers std::vector which is given the current MIDI port numbers

const char* TSE3::MidiScheduler::portName int  port  )  const
 

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.

Parameters:
port MIDI port number
Returns:
Port name string

const char* TSE3::MidiScheduler::portType int  port  )  const
 

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.

Parameters:
port MIDI port number
Returns:
Port type string

bool TSE3::MidiScheduler::portReadable int  port  )  const
 

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.

Parameters:
port MIDI port number
Returns:
Whether MidiEvent objects are readable from this port
See also:
portWritable

bool TSE3::MidiScheduler::portWriteable int  port  )  const
 

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.

Parameters:
port MIDI port number
Returns:
Whether MidiEvent objects are readable from this port
See also:
portReadable

bool TSE3::MidiScheduler::portInternal int  port  )  const
 

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.

Parameters:
port MIDI port number
Returns:
Whether the port connects to an internal or external MIDI device.
See also:
defaultInternalPort

defaultExternalPort

int TSE3::MidiScheduler::defaultInternalPort  )  const
 

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:
Default internal port, or MidiCommand::NoPort
See also:
defaultExternalPort

int TSE3::MidiScheduler::defaultExternalPort  )  const
 

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

Returns:
Default external port, or MidiCommand::NoPort
See also:
defaultInternalPort

void TSE3::MidiScheduler::start Clock  startTime  )  [inline]
 

Start the scheduler clock running, set to the given time.

Parameters:
startTime The time to start the scheduler at

void TSE3::MidiScheduler::start  )  [inline]
 

Start the scheduler clock at the current 'resting time' (as set by a call to stop).

void TSE3::MidiScheduler::stop Clock  stopTime = -1  ) 
 

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.

Parameters:
stopTime The time at which to stop (-1 means immediately)

bool TSE3::MidiScheduler::running  )  const [inline]
 

Enquire whether the scheduler clock is running.

Returns:
Whether the clock is running

void TSE3::MidiScheduler::moveTo Clock  moveTime,
Clock  newTime
 

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'.

Parameters:
moveTime Time at which to perform the move
newTime Time to move to

void TSE3::MidiScheduler::moveTo Clock  moveTime  )  [inline]
 

Without stopping, move the scheduler clock immediately.

Parameters:
moveTime Time to move to

Clock TSE3::MidiScheduler::clock  )  [inline]
 

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'.

Returns:
MidiScheduler time value

int TSE3::MidiScheduler::msecs  )  [inline]
 

Read the scheduler clock in milliseconds.

Returns:
MidiScheduler time value in milliseconds

int TSE3::MidiScheduler::tempo  )  const [inline]
 

Read the tempo.

Returns:
Current tempo
See also:
setTempo

void TSE3::MidiScheduler::setTempo int  newTempo,
Clock  changeTime
[inline]
 

Set the tempo.

Parameters:
newTempo The new tempo value in beats per minute (1-256)
changeTime Only used if the scheduler is running to indicate when the tempo change occurs. Any further calls to clock() before changeTime will return bogus values, as they will be in the new tempo's time scale.
See also:
clock

tempo

bool TSE3::MidiScheduler::eventWaiting  )  [inline]
 

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.

Returns:
Whether there is any input data ready to be processed

MidiEvent TSE3::MidiScheduler::rx  ) 
 

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.

Returns:
A MidiEvent containing the data. If the status of the MidiCommand is zero, there wasn't a whole MidiCommand in the buffer.

void TSE3::MidiScheduler::tx MidiCommand  mc  ) 
 

Transmit a MidiCommand immediately.

This bypasses every other scheduled MidiEvent and is sent to the hardware before them.

Parameters:
mc The MidiCommand to transmit

void TSE3::MidiScheduler::tx MidiEvent  event  ) 
 

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.

Parameters:
event MidiEvent to schedule to transmission

void TSE3::MidiScheduler::txSysEx int  port,
const unsigned char *  data,
size_t  size
 

bool TSE3::MidiScheduler::remoteControl  )  const [inline]
 

Read the remote control status.

Returns:
true if remote control enabled, false if disabled
See also:
setRemoteControl

void TSE3::MidiScheduler::setRemoteControl bool  s  )  [inline]
 

Sets the remote control status.

Parameters:
s New remote control status
See also:
remoteControl

bool TSE3::MidiScheduler::consumeRemoveEvents  )  const [inline]
 

unsigned int TSE3::MidiScheduler::startNote  )  const [inline]
 

Returns the start note. When pressed this note will cause the scheduler to start.

Returns:
Start note
See also:
setStartNote

void TSE3::MidiScheduler::setStartNote unsigned int  n  )  [inline]
 

Sets the start note.

Parameters:
n New start note
See also:
startNote

unsigned int TSE3::MidiScheduler::stopNote  )  const [inline]
 

Returns the stop note. When pushed with the shift note held down, this note will cause the scheduler to stop.

Returns:
Stop note
See also:
setStopNote

void TSE3::MidiScheduler::setStopNote unsigned int  n  )  [inline]
 

Sets the stop note.

Parameters:
n New stop note
See also:
stopNote

MidiScheduler& TSE3::MidiScheduler::operator= const MidiScheduler  )  [protected]
 

virtual const char* TSE3::MidiScheduler::impl_implementationName  )  const [protected, pure virtual]
 

Implemented in TSE3::Plt::AlsaMidiScheduler, TSE3::Plt::ArtsMidiScheduler, TSE3::Plt::OSSMidiScheduler, TSE3::Plt::RiscOsMidiScheduler, TSE3::Plt::Win32MidiScheduler, TSE3::Util::StreamMidiScheduler, and TSE3::Util::NullMidiScheduler.

virtual const char* TSE3::MidiScheduler::impl_portName int  port  )  const [protected, pure virtual]
 

Implemented in TSE3::Plt::AlsaMidiScheduler, TSE3::Plt::ArtsMidiScheduler, TSE3::Plt::OSSMidiScheduler, TSE3::Plt::RiscOsMidiScheduler, TSE3::Plt::Win32MidiScheduler, TSE3::Util::StreamMidiScheduler, and TSE3::Util::NullMidiScheduler.

virtual const char* TSE3::MidiScheduler::impl_portType int  port  )  const [protected, pure virtual]
 

Implemented in TSE3::Plt::AlsaMidiScheduler, TSE3::Plt::ArtsMidiScheduler, TSE3::Plt::OSSMidiScheduler, TSE3::Plt::RiscOsMidiScheduler, TSE3::Plt::Win32MidiScheduler, TSE3::Util::StreamMidiScheduler, and TSE3::Util::NullMidiScheduler.

virtual bool TSE3::MidiScheduler::impl_portReadable int  port  )  const [protected, pure virtual]
 

Implemented in TSE3::Plt::AlsaMidiScheduler, TSE3::Plt::ArtsMidiScheduler, TSE3::Plt::OSSMidiScheduler, TSE3::Plt::RiscOsMidiScheduler, TSE3::Plt::Win32MidiScheduler, TSE3::Util::StreamMidiScheduler, and TSE3::Util::NullMidiScheduler.

virtual bool TSE3::MidiScheduler::impl_portWriteable int  port  )  const [protected, pure virtual]
 

Implemented in TSE3::Plt::AlsaMidiScheduler, TSE3::Plt::ArtsMidiScheduler, TSE3::Plt::OSSMidiScheduler, TSE3::Plt::RiscOsMidiScheduler, TSE3::Plt::Win32MidiScheduler, TSE3::Util::StreamMidiScheduler, and TSE3::Util::NullMidiScheduler.

virtual void TSE3::MidiScheduler::impl_start Clock  clock  )  [protected, pure virtual]
 

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.

virtual void TSE3::MidiScheduler::impl_stop Clock  clock  )  [protected, pure virtual]
 

Current state is guaranteed to be started. The clock value will not ever be -1.

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.

virtual void TSE3::MidiScheduler::impl_moveTo Clock  moveTime,
Clock  newTime
[protected, pure virtual]
 

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.

virtual Clock TSE3::MidiScheduler::impl_clock  )  [protected, pure virtual]
 

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.

virtual int TSE3::MidiScheduler::impl_msecs  )  [protected, pure virtual]
 

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.

virtual void TSE3::MidiScheduler::impl_setTempo int  tempo,
Clock  changeTime
[protected, pure virtual]
 

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.

virtual bool TSE3::MidiScheduler::impl_eventWaiting  )  [protected, pure virtual]
 

Implemented in TSE3::Plt::AlsaMidiScheduler, TSE3::Plt::ArtsMidiScheduler, TSE3::Plt::OSSMidiScheduler, TSE3::Plt::RiscOsMidiScheduler, TSE3::Plt::Win32MidiScheduler, TSE3::Util::StreamMidiScheduler, and TSE3::Util::NullMidiScheduler.

virtual MidiEvent TSE3::MidiScheduler::impl_rx  )  [protected, pure virtual]
 

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.

virtual void TSE3::MidiScheduler::impl_tx MidiCommand  mc  )  [protected, pure virtual]
 

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.

virtual void TSE3::MidiScheduler::impl_tx MidiEvent  mc  )  [protected, pure virtual]
 

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.

virtual void TSE3::MidiScheduler::impl_txSysEx int  port,
const unsigned char *  data,
size_t  size
[protected, pure virtual]
 

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.

int TSE3::MidiScheduler::addPort int  portIndex,
bool  isInternal,
int  requestedPort = 0
[protected]
 

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.

Parameters:
portIndex You implementation's port reference
isInternal Specify true if this is an internal sound generator, or false if it is a MIDI link to an external device.
requestedPort The port number you'd like to present to the user

void TSE3::MidiScheduler::removePort int  portIndex  )  [protected]
 

You don't need to call removePort in your implementation's destructor.

void TSE3::MidiScheduler::clockStarted Clock  startTime  )  [protected]
 

void TSE3::MidiScheduler::clockStopped Clock  stopTime  )  [protected]
 

void TSE3::MidiScheduler::clockMoved const Clock  moveTime,
Clock  newTime
[protected]
 

void TSE3::MidiScheduler::tempoChanged int  tempo,
Clock  changeTime
[protected]
 

int TSE3::MidiScheduler::clockToMs Clock  time  )  [inline, protected]
 

An internal method to convert Clock values to millisecond times.

Clock TSE3::MidiScheduler::msToClock int  ms  )  [inline, protected]
 

An internal method to convert millisecond time values to .


Member Data Documentation

Clock TSE3::MidiScheduler::startClock [protected]
 

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.


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