ScummVM API documentation
MidiStreamParser.h
1 /* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher
2  * Copyright (C) 2011-2022 Dean Beeler, Jerome Fisher, Sergey V. Mikayev
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation, either version 2.1 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef MT32EMU_MIDI_STREAM_PARSER_H
19 #define MT32EMU_MIDI_STREAM_PARSER_H
20 
21 #include "globals.h"
22 #include "Types.h"
23 
24 namespace MT32Emu {
25 
26 class Synth;
27 
28 // Interface for a user-supplied class to receive parsed well-formed MIDI messages.
29 class MT32EMU_EXPORT MidiReceiver {
30 public:
31  // Invoked when a complete short MIDI message is parsed in the input MIDI stream.
32  virtual void handleShortMessage(const Bit32u message) = 0;
33 
34  // Invoked when a complete well-formed System Exclusive MIDI message is parsed in the input MIDI stream.
35  virtual void handleSysex(const Bit8u stream[], const Bit32u length) = 0;
36 
37  // Invoked when a System Realtime MIDI message is parsed in the input MIDI stream.
38  virtual void handleSystemRealtimeMessage(const Bit8u realtime) = 0;
39 
40 protected:
41  ~MidiReceiver() {}
42 };
43 
44 // Interface for a user-supplied class to receive notifications of input MIDI stream parse errors.
45 class MT32EMU_EXPORT MidiReporter {
46 public:
47  // Invoked when an error occurs during processing the input MIDI stream.
48  virtual void printDebug(const char *debugMessage) = 0;
49 
50 protected:
51  ~MidiReporter() {}
52 };
53 
54 // Provides a context for parsing a stream of MIDI events coming from a single source.
55 // There can be multiple MIDI sources feeding MIDI events to a single Synth object.
56 // NOTE: Calls from multiple threads which feed a single Synth object with data must be explicitly synchronised,
57 // although, no synchronisation is required with the rendering thread.
58 class MT32EMU_EXPORT MidiStreamParserImpl {
59 public:
60  // The first two arguments provide for implementations of essential interfaces needed.
61  // The third argument specifies streamBuffer initial capacity. The buffer capacity should be large enough to fit the longest SysEx expected.
62  // If a longer SysEx occurs, streamBuffer is reallocated to the maximum size of MAX_STREAM_BUFFER_SIZE (32768 bytes).
63  // Default capacity is SYSEX_BUFFER_SIZE (1000 bytes) which is enough to fit SysEx messages in common use.
64  MidiStreamParserImpl(MidiReceiver &, MidiReporter &, Bit32u initialStreamBufferCapacity = SYSEX_BUFFER_SIZE);
65  virtual ~MidiStreamParserImpl();
66 
67  // Parses a block of raw MIDI bytes. All the parsed MIDI messages are sent in sequence to the user-supplied methods for further processing.
68  // SysEx messages are allowed to be fragmented across several calls to this method. Running status is also handled for short messages.
69  // NOTE: the total length of a SysEx message being fragmented shall not exceed MAX_STREAM_BUFFER_SIZE (32768 bytes).
70  void parseStream(const Bit8u *stream, Bit32u length);
71 
72  // Convenience method which accepts a Bit32u-encoded short MIDI message and sends it to the user-supplied method for further processing.
73  // The short MIDI message may contain no status byte, the running status is used in this case.
74  void processShortMessage(const Bit32u message);
75 
76 private:
77  Bit8u runningStatus;
78  Bit8u *streamBuffer;
79  Bit32u streamBufferCapacity;
80  Bit32u streamBufferSize;
81  MidiReceiver &midiReceiver;
82  MidiReporter &midiReporter;
83 
84  // Binary compatibility helper.
85  void *reserved;
86 
87  bool checkStreamBufferCapacity(const bool preserveContent);
88  bool processStatusByte(Bit8u &status);
89  Bit32u parseShortMessageStatus(const Bit8u stream[]);
90  Bit32u parseShortMessageDataBytes(const Bit8u stream[], Bit32u length);
91  Bit32u parseSysex(const Bit8u stream[], const Bit32u length);
92  Bit32u parseSysexFragment(const Bit8u stream[], const Bit32u length);
93 }; // class MidiStreamParserImpl
94 
95 // An abstract class that provides a context for parsing a stream of MIDI events coming from a single source.
96 class MT32EMU_EXPORT MidiStreamParser : public MidiStreamParserImpl, protected MidiReceiver, protected MidiReporter {
97 public:
98  // The argument specifies streamBuffer initial capacity. The buffer capacity should be large enough to fit the longest SysEx expected.
99  // If a longer SysEx occurs, streamBuffer is reallocated to the maximum size of MAX_STREAM_BUFFER_SIZE (32768 bytes).
100  // Default capacity is SYSEX_BUFFER_SIZE (1000 bytes) which is enough to fit SysEx messages in common use.
101  explicit MidiStreamParser(Bit32u initialStreamBufferCapacity = SYSEX_BUFFER_SIZE);
102 };
103 
104 class MT32EMU_EXPORT DefaultMidiStreamParser : public MidiStreamParser {
105 public:
106  explicit DefaultMidiStreamParser(Synth &synth, Bit32u initialStreamBufferCapacity = SYSEX_BUFFER_SIZE);
107  void setTimestamp(const Bit32u useTimestamp);
108  void resetTimestamp();
109 
110 protected:
111  void handleShortMessage(const Bit32u message);
112  void handleSysex(const Bit8u *stream, const Bit32u length);
113  void handleSystemRealtimeMessage(const Bit8u realtime);
114  void printDebug(const char *debugMessage);
115 
116 private:
117  Synth &synth;
118  bool timestampSet;
119  Bit32u timestamp;
120 };
121 
122 } // namespace MT32Emu
123 
124 #endif // MT32EMU_MIDI_STREAM_PARSER_H
Definition: MidiStreamParser.h:45
Definition: Analog.h:26
Definition: MidiStreamParser.h:58
Definition: MidiStreamParser.h:96
Definition: MidiStreamParser.h:29
Definition: Synth.h:131
Definition: MidiStreamParser.h:104