aboutsummaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorJamieson Christian2003-05-31 22:04:21 +0000
committerJamieson Christian2003-05-31 22:04:21 +0000
commit6aba98450ba79682759e25dd7fbb22a053ae987f (patch)
treea572a206ac7db5a948bbecd31a8ac3e34fcfd8a6 /sound
parentac02e3d0d0d2fe2414e8e0cb5553ef835265c00a (diff)
downloadscummvm-rg350-6aba98450ba79682759e25dd7fbb22a053ae987f.tar.gz
scummvm-rg350-6aba98450ba79682759e25dd7fbb22a053ae987f.tar.bz2
scummvm-rg350-6aba98450ba79682759e25dd7fbb22a053ae987f.zip
Some Doxygen documentation. Just to test.
svn-id: r8195
Diffstat (limited to 'sound')
-rw-r--r--sound/midiparser.h153
1 files changed, 115 insertions, 38 deletions
diff --git a/sound/midiparser.h b/sound/midiparser.h
index d12664da93..be0b3e39a3 100644
--- a/sound/midiparser.h
+++ b/sound/midiparser.h
@@ -19,6 +19,8 @@
*
*/
+//! \brief Declarations related to the MidiParser class
+
#ifndef INCLUDED_MIDIPARSER
#define INCLUDED_MIDIPARSER
@@ -36,16 +38,27 @@ class MidiDriver;
//
//////////////////////////////////////////////////
+//! Maintains time and position state within a MIDI stream.
+/*! A single Tracker struct is used by MidiParser to keep track
+ * of its current position in the MIDI stream. The Tracker
+ * struct, however, allows alternative locations to be cached.
+ * See MidiParser::jumpToTick() for an example of tracking
+ * multiple locations within a MIDI stream. NOTE: It is
+ * important to also maintain pre-parsed EventInfo data for
+ * each Tracker location.
+ */
+
struct Tracker {
- byte * _play_pos;
- uint32 _play_time;
- uint32 _play_tick;
- uint32 _last_event_time;
- uint32 _last_event_tick;
- byte _running_status;
+ byte * _play_pos; //!< A pointer to the next event to be parsed
+ uint32 _play_time; //!< Current time in microseconds; may be in between event times
+ uint32 _play_tick; //!< Current MIDI tick; may be in between event ticks
+ uint32 _last_event_time; //!< The time, in microseconds, of the last event that was parsed
+ uint32 _last_event_tick; //!< The tick at which the last parsed event occurs
+ byte _running_status; //!< Cached MIDI command, for MIDI streams that rely on implied event codes
Tracker() { clear(); }
+ //! Copy constructor for each duplication of Tracker information.
Tracker (const Tracker &copy) :
_play_pos (copy._play_pos),
_play_time (copy._play_time),
@@ -55,6 +68,7 @@ struct Tracker {
_running_status (copy._running_status)
{ }
+ //! Clears all data; used by the constructor for initialization.
void clear() {
_play_pos = 0;
_play_time = 0;
@@ -65,30 +79,47 @@ struct Tracker {
}
};
+//! Provides comprehensive information on the next event in the MIDI stream.
+/*! An EventInfo struct is instantiated by format-specific implementations
+ * of MidiParser::parseNextEvent() each time another event is needed.
+ */
+
struct EventInfo {
- byte * start; // Points to delta
- uint32 delta;
- byte event;
+ byte * start; //!< Position in the MIDI stream where the event starts.
+ //!< For delta-based MIDI streams (e.g. SMF and XMIDI), this points to the delta.
+ uint32 delta; //!< The number of ticks after the previous event that this event should occur.
+ byte event; //!< Upper 4 bits are the command code, lower 4 bits are the MIDI channel.
+ //!< For META, event == 0xFF. For SysEx, event == 0xF0.
union {
struct {
- byte param1;
- byte param2;
+ byte param1; //!< The first parameter in a simple MIDI message.
+ byte param2; //!< The second parameter in a simple MIDI message.
} basic;
struct {
- byte type; // Used for METAs
- byte * data; // Used for SysEx and METAs
+ byte type; //!< For META events, this indicates the META type.
+ byte * data; //!< For META and SysEx events, this points to the start of the data.
} ext;
};
- uint32 length; // Used for SysEx and METAs, and note lengths
+ uint32 length; //!< For META and SysEx blocks, this indicates the length of the data.
+ //!< For Note On events, a non-zero value indicates that no Note Off event
+ //!< will occur, and the MidiParser will have to generate one itself.
+ //!< For all other events, this value should always be zero.
- byte channel() { return event & 0x0F; }
- byte command() { return event >> 4; }
+ byte channel() { return event & 0x0F; } //!< Separates the MIDI channel from the event.
+ byte command() { return event >> 4; } //!< Separates the command code from the event.
};
+//! Provides expiration tracking for hanging notes.
+/*! Hanging notes are used when a MIDI format does not include explicit Note Off
+ * events, or when "Smart Jump" is enabled so that active notes are intelligently
+ * expired when a jump occurs. The NoteTimer struct keeps track of how much
+ * longer a note should remain active before being turned off.
+ */
+
struct NoteTimer {
- byte channel;
- byte note;
- uint32 time_left;
+ byte channel; //!< The MIDI channel on which the note was played
+ byte note; //!< The note number for the active note
+ uint32 time_left; //!< The time, in microseconds, remaining before the note should be turned off
NoteTimer() : channel(0), note(0), time_left(0) {}
};
@@ -101,28 +132,48 @@ struct NoteTimer {
//
//////////////////////////////////////////////////
+//! A framework and common functionality for parsing MIDI streams.
+/*! The MidiParser provides a framework in which to load
+ * parse and traverse MIDI streams. Loading and parsing
+ * events for specific formats requires a class to be
+ * derived from MidiParser.
+ *
+ * The MidiParser must be provided with a MidiDriver interface,
+ * which it uses to transmit events. However, it does NOT
+ * automatically hook into the MidiDriver's timer callback
+ * or set up its timer rate from the MidiDriver. The client
+ * using the MidiParser must set the timer rate provide
+ * a means of firing the MidiParser's onTimer() method at
+ * appropriate intervals. The onTimer() event may be called
+ * by the client or by manually hooking and unhooking the
+ * MidiParser to the MidiDriver's timer callback.
+ */
+
class MidiParser {
private:
- uint16 _active_notes[128]; // Each uint16 is a bit mask for channels that have that note on
- NoteTimer _hanging_notes[32]; // Supports "smart" jump with notes still playing
- byte _hanging_notes_count;
+ uint16 _active_notes[128]; //!< Each uint16 is a bit mask for channels that have that note on.
+ NoteTimer _hanging_notes[32]; //!< Maintains expiration info for up to 32 notes.
+ //!< Used for "Smart Jump" and MIDI formats that do not include explicit Note Off events.
+ byte _hanging_notes_count; //!< Count of hanging notes, used to optimize expiration.
protected:
- MidiDriver *_driver;
- uint32 _timer_rate;
- uint32 _ppqn; // Pulses (ticks) Per Quarter Note
- uint32 _tempo; // Microseconds per quarter note
- uint32 _psec_per_tick; // Microseconds per tick (_tempo / _ppqn)
- bool _autoLoop; // For lightweight clients that don't monitor events
- bool _smartJump; // Support smart expiration of hanging notes when jumping
-
- byte * _tracks[32];
- byte _num_tracks;
- byte _active_track;
-
- Tracker _position;
- EventInfo _next_event;
- bool _abort_parse; // If a jump or some other interruption occurs
+ MidiDriver *_driver; //!< The device to which all events will be transmitted.
+ uint32 _timer_rate; //!< The time in microseconds between onTimer() calls. Obtained from the MidiDriver.
+ uint32 _ppqn; //!< Pulses Per Quarter Note. (We refer to "pulses" as "ticks".)
+ uint32 _tempo; //!< Microseconds per quarter note.
+ uint32 _psec_per_tick; //!< Microseconds per tick (_tempo / _ppqn).
+ bool _autoLoop; //!< For lightweight clients that don't provide their own flow control.
+ bool _smartJump; //!< Support smart expiration of hanging notes when jumping
+
+ byte * _tracks[32]; //!< Multi-track MIDI formats are supported, up to 32 tracks.
+ byte _num_tracks; //!< Count of total tracks for multi-track MIDI formats. 1 for single-track formats.
+ byte _active_track; //!< Keeps track of the currently active track, in multi-track formats.
+
+ Tracker _position; //!< The current time/position in the active track.
+ EventInfo _next_event; //!< The next event to transmit. Events are preparsed
+ //!< so each event is parsed only once; this permits
+ //!< simulated events in certain formats.
+ bool _abort_parse; //!< If a jump or other operation interrupts parsing, flag to abort.
protected:
static uint32 readVLQ (byte * &data);
@@ -134,13 +185,23 @@ protected:
void hangingNote (byte channel, byte note, uint32 ticks_left);
void hangAllActiveNotes();
- // Multi-byte read helpers
+ //! Platform independent BE uint32 read-and-advance.
+ /*! This help function reads Big Endian 32-bit numbers
+ * from a memory pointer, at the same time advancing
+ * the pointer.
+ */
uint32 read4high (byte * &data) {
uint32 val = 0;
int i;
for (i = 0; i < 4; ++i) val = (val << 8) | *data++;
return val;
}
+
+ //! Platform independent LE uint16 read-and-advance.
+ /*! This help function reads Little Endian 16-bit numbers
+ * from a memory pointer, at the same time advancing
+ * the pointer.
+ */
uint16 read2low (byte * &data) {
uint16 val = 0;
int i;
@@ -149,6 +210,22 @@ protected:
}
public:
+ //! Configuration options for MidiParser
+ /*! The following options can be set to modify MidiParser's
+ * behavior.
+ *
+ * \b mpMalformedPitchBends - Events containing a pitch bend
+ * command should be treated as single-byte padding before the
+ * real event. This allows the MidiParser to work with some
+ * malformed SMF files from Simon 1/2.
+ *
+ * \b mpAutoLoop - Sets auto-looping, which can be used by
+ * lightweight clients that don't provide their own flow control.
+ *
+ * \b mpSmartJump - Sets smart jumping, which intelligently
+ * expires notes that are active when a jump is made, rather
+ * than just cutting them off.
+ */
enum {
mpMalformedPitchBends = 1,
mpAutoLoop = 2,