24#ifndef AUDIO_MIDIPARSER_H
25#define AUDIO_MIDIPARSER_H
27#include "common/scummsys.h"
28#include "common/endian.h"
29#include "common/stream.h"
31#define AUDIO_MIDIPARSER_MAXIMUM_SUBTRACKS 35
79 bool isTracking()
const {
100 for (
int i = 0; i < AUDIO_MIDIPARSER_MAXIMUM_SUBTRACKS; i++) {
101 _subtracks[i].clear();
105 bool isTracking()
const {
106 for (
int i = 0; i < AUDIO_MIDIPARSER_MAXIMUM_SUBTRACKS; i++) {
107 if (_subtracks[i].isTracking())
113 bool isTracking(uint8 subtrack)
const {
114 assert(subtrack < AUDIO_MIDIPARSER_MAXIMUM_SUBTRACKS);
115 return _subtracks[subtrack].isTracking();
118 void stopTracking() {
119 for (
int i = 0; i < AUDIO_MIDIPARSER_MAXIMUM_SUBTRACKS; i++) {
120 _subtracks[i].stopTracking();
124 void stopTracking(uint8 subtrack) {
125 assert(subtrack < AUDIO_MIDIPARSER_MAXIMUM_SUBTRACKS);
126 _subtracks[subtrack].stopTracking();
356 static const uint8 MAXIMUM_TRACKS = 120;
357 static const uint8 MAXIMUM_SUBTRACKS = AUDIO_MIDIPARSER_MAXIMUM_SUBTRACKS;
380 const byte *
_tracks[MAXIMUM_TRACKS][MAXIMUM_SUBTRACKS];
408 static uint32 readVLQ(
const byte * &data);
409 virtual void resetTracking();
410 virtual void allNotesOff();
411 virtual void parseNextEvent(
EventInfo &info) = 0;
424 virtual bool processEvent(
const EventInfo &info,
bool fireEvents =
true);
426 void activeNote(
byte channel,
byte note,
bool active);
427 void hangingNote(
byte channel,
byte note, uint32 ticksLeft,
bool recycle =
true);
428 void hangAllActiveNotes();
437 virtual void sendToDriver(uint32 b);
438 void sendToDriver(
byte status,
byte firstOp,
byte secondOp) {
439 sendToDriver(status | ((uint32)firstOp << 8) | ((uint32)secondOp << 16));
441 virtual void sendMetaEventToDriver(
byte type,
const byte *data, uint16 length);
450 uint32 val = READ_BE_UINT32(data);
462 uint16 val = READ_LE_UINT16(data);
517 typedef void (*XMidiCallbackProc)(
byte eventData,
void *refCon);
522 virtual bool loadMusic(
const byte *data, uint32 size) = 0;
523 virtual void unloadMusic();
524 virtual void property(
int prop,
int value);
534 void setTimerRate(uint32 rate) {
_timerRate = rate; }
535 virtual void setTempo(uint32 tempo);
536 virtual void onTimer();
569 bool setTrack(
int track);
571 bool jumpToTick(uint32 tick,
bool fireEvents =
false,
bool stopNotes =
true,
bool dontSendNoteOn =
false);
585 virtual bool jumpToIndex(uint8 index,
bool stopNotes =
true) {
return false; }
587 void setLoopSection(uint32 startPoint, uint32 endPoint = 0);
588 void setLoopSectionMicroseconds(uint32 startPoint, uint32 endPoint = 0);
589 void clearLoopSection();
591 uint32 getPPQN() {
return _ppqn; }
594 static void defaultXMidiCallback(
byte eventData,
void *refCon);
596 static MidiParser *createParser_SMF(int8 source = -1);
597 static MidiParser *createParser_XMIDI(XMidiCallbackProc proc = defaultXMidiCallback,
void *refCon = 0,
int source = -1);
598 static MidiParser *createParser_QT(int8 source = -1);
599 static MidiParser *createParser_HMP(int8 source = -1);
600 static void timerCallback(
void *data) { ((
MidiParser *)data)->onTimer(); }
Definition: mididrv.h:114
Definition: midiparser.h:354
virtual bool jumpToIndex(uint8 index, bool stopNotes=true)
Definition: midiparser.h:585
bool _autoLoop
For lightweight clients that don't provide their own flow control.
Definition: midiparser.h:370
virtual void rebaseTracking()
uint32 _psecPerTick
Microseconds per tick (_tempo / _ppqn).
Definition: midiparser.h:368
EventInfo _nextSubtrackEvents[MAXIMUM_SUBTRACKS]
Definition: midiparser.h:389
bool _disableAllNotesOffMidiEvents
Don't send All Notes Off MIDI messages.
Definition: midiparser.h:378
bool _jumpingToTick
True if currently inside jumpToTick.
Definition: midiparser.h:394
@ mpDisableAutoStartPlayback
Definition: midiparser.h:513
@ mpSendSustainOffOnNotesOff
Definition: midiparser.h:496
@ mpCenterPitchWheelOnUnload
Definition: midiparser.h:490
@ mpDisableAllNotesOffMidiEvents
Definition: midiparser.h:506
@ mpAutoLoop
Definition: midiparser.h:478
@ mpSmartJump
Definition: midiparser.h:484
byte _numSubtracks[MAXIMUM_TRACKS]
The number of subtracks for each track.
Definition: midiparser.h:382
byte _hangingNotesCount
Count of hanging notes, used to optimize expiration.
Definition: midiparser.h:362
uint16 _activeNotes[128]
Each uint16 is a bit mask for channels that have that note on.
Definition: midiparser.h:359
const byte * _tracks[MAXIMUM_TRACKS][MAXIMUM_SUBTRACKS]
Multi-track MIDI formats are supported, up to 120 tracks with 20 subtracks each.
Definition: midiparser.h:380
uint32 _loopStartPoint
Start point (in ticks) of the looping section of the track.
Definition: midiparser.h:371
bool _pause
True if the parser has paused parsing.
Definition: midiparser.h:396
uint32 _loopStartPointMs
Start point (in microseconds) of the looping section of the track.
Definition: midiparser.h:373
byte _activeTrack
Keeps track of the currently active track, in multi-track formats.
Definition: midiparser.h:383
int8 _source
Definition: midiparser.h:405
uint32 _ppqn
Pulses Per Quarter Note. (We refer to "pulses" as "ticks".)
Definition: midiparser.h:366
uint32 _sysExDelay
Number of microseconds until the next SysEx event can be sent.
Definition: midiparser.h:369
uint32 read4high(const byte *&data)
Definition: midiparser.h:449
bool _sendSustainOffOnNotesOff
Send a sustain off on a notes off event, stopping hanging notes.
Definition: midiparser.h:377
EventInfo * _nextEvent
Definition: midiparser.h:386
Tracker _position
The current time/position in the active track.
Definition: midiparser.h:385
bool _abortParse
If a jump or other operation interrupts parsing, flag to abort.
Definition: midiparser.h:393
bool _disableAutoStartPlayback
Do not automatically start playback after parsing MIDI data or setting the track.
Definition: midiparser.h:379
virtual int32 determineDataSize(Common::SeekableReadStream *stream)
Definition: midiparser.h:531
NoteTimer _hangingNotes[32]
Used for "Smart Jump" and MIDI formats that do not include explicit Note Off events.
Definition: midiparser.h:360
uint32 _tempo
Microseconds per quarter note.
Definition: midiparser.h:367
bool _smartJump
Support smart expiration of hanging notes when jumping.
Definition: midiparser.h:375
virtual void onTrackStart(uint8 track)
Definition: midiparser.h:435
virtual bool hasJumpIndex(uint8 index)
Definition: midiparser.h:578
virtual void determineNextEvent()
uint32 _loopEndPointMs
End point (in microseconds) of the looping section of the track.
Definition: midiparser.h:374
uint32 _loopEndPoint
End point (in ticks) of the looping section of the track.
Definition: midiparser.h:372
uint16 read2low(const byte *&data)
Definition: midiparser.h:461
byte _numTracks
Count of total tracks for multi-track MIDI formats. 1 for single-track formats.
Definition: midiparser.h:381
bool _centerPitchWheelOnUnload
Center the pitch wheels when unloading a song.
Definition: midiparser.h:376
uint32 _timerRate
The time in microseconds between onTimer() calls. Obtained from the MidiDriver.
Definition: midiparser.h:365
bool _doParse
True if the parser should be parsing; false if it should not be active.
Definition: midiparser.h:395
MidiDriver_BASE * _driver
The device to which all events will be transmitted.
Definition: midiparser.h:364
Definition: midiparser.h:135
byte command() const
Separates the command code from the event.
Definition: midiparser.h:161
bool loop
Indicates that this event loops (part of) the MIDI data.
Definition: midiparser.h:156
uint8 subtrack
The subtrack containing this event.
Definition: midiparser.h:138
byte type
For META events, this indicates the META type.
Definition: midiparser.h:148
byte param1
The first parameter in a simple MIDI message.
Definition: midiparser.h:144
const byte * data
For META and SysEx events, this points to the start of the data.
Definition: midiparser.h:149
byte param2
The second parameter in a simple MIDI message.
Definition: midiparser.h:145
byte channel() const
Separates the MIDI channel from the event.
Definition: midiparser.h:160
byte event
Definition: midiparser.h:140
const byte * start
For delta-based MIDI streams (e.g. SMF and XMIDI), this points to the delta.
Definition: midiparser.h:136
bool noop
Definition: midiparser.h:157
uint32 length
Definition: midiparser.h:152
uint32 delta
The number of ticks after the previous event that this event should occur.
Definition: midiparser.h:139
Definition: midiparser.h:186
byte channel
The MIDI channel on which the note was played.
Definition: midiparser.h:187
uint32 timeLeft
The time, in microseconds, remaining before the note should be turned off.
Definition: midiparser.h:189
byte note
The note number for the active note.
Definition: midiparser.h:188
Definition: midiparser.h:62
const byte * _playPos
A pointer to the next event to be parsed.
Definition: midiparser.h:63
uint32 _lastEventTick
The tick at which the last parsed event occurs.
Definition: midiparser.h:65
uint32 _lastEventTime
The time, in microseconds, of the last event that was parsed.
Definition: midiparser.h:64
byte _runningStatus
Cached MIDI command, for MIDI streams that rely on implied event codes.
Definition: midiparser.h:66
Definition: midiparser.h:61
uint32 _playTick
Current MIDI tick; may be in between event ticks.
Definition: midiparser.h:85
uint32 _playTime
Current time in microseconds; may be in between event times.
Definition: midiparser.h:84
void clear()
Clears all data; used by the constructor for initialization.
Definition: midiparser.h:94
uint32 _lastEventTick
The tick at which the last parsed event across all subtracks occurs.
Definition: midiparser.h:88
uint32 _lastEventTime
Definition: midiparser.h:86