ScummVM API documentation
miles.h
1/* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22#ifndef AUDIO_MILES_MIDIDRIVER_H
23#define AUDIO_MILES_MIDIDRIVER_H
24
25#include "audio/mididrv.h"
26#include "audio/mt32gm.h"
27
28#include "common/error.h"
29#include "common/mutex.h"
30#include "common/queue.h"
31#include "common/stream.h"
32
33namespace Audio {
34
43// Miles Audio supported controllers for control change messages
44#define MILES_CONTROLLER_SELECT_PATCH_BANK 114
45#define MILES_CONTROLLER_PROTECT_VOICE 112
46#define MILES_CONTROLLER_PROTECT_TIMBRE 113
47#define MILES_CONTROLLER_LOCK_CHANNEL 110
48#define MILES_CONTROLLER_PROTECT_CHANNEL 111
49#define MILES_CONTROLLER_PITCH_RANGE 6
50#define MILES_CONTROLLER_PATCH_REVERB 59
51#define MILES_CONTROLLER_PATCH_BENDER 60
52#define MILES_CONTROLLER_REVERB_MODE 61
53#define MILES_CONTROLLER_REVERB_TIME 62
54#define MILES_CONTROLLER_REVERB_LEVEL 63
55#define MILES_CONTROLLER_RHYTHM_KEY_TIMBRE 58
56
57// 3 SysEx controllers, each range 5
58// 32-36 for 1st queue
59// 37-41 for 2nd queue
60// 42-46 for 3rd queue
61#define MILES_CONTROLLER_SYSEX_RANGE_BEGIN 32
62#define MILES_CONTROLLER_SYSEX_RANGE_END 46
63
64#define MILES_CONTROLLER_SYSEX_QUEUE_COUNT 3
65#define MILES_CONTROLLER_SYSEX_QUEUE_SIZE 32
66
67#define MILES_CONTROLLER_SYSEX_COMMAND_ADDRESS1 0
68#define MILES_CONTROLLER_SYSEX_COMMAND_ADDRESS2 1
69#define MILES_CONTROLLER_SYSEX_COMMAND_ADDRESS3 2
70#define MILES_CONTROLLER_SYSEX_COMMAND_DATA 3
71#define MILES_CONTROLLER_SYSEX_COMMAND_FINAL_DATA 4
72
73#define MILES_CONTROLLER_XMIDI_RANGE_BEGIN 110
74#define MILES_CONTROLLER_XMIDI_RANGE_END 120
75
76#define MILES_MT32_PATCHES_COUNT 128
77#define MILES_MT32_CUSTOMTIMBRE_COUNT 64
78
79#define MILES_MT32_PATCHDATA_COMMONPARAMETER_SIZE 14
80#define MILES_MT32_PATCHDATA_PARTIALPARAMETER_SIZE 58
81#define MILES_MT32_PATCHDATA_PARTIALPARAMETERS_COUNT 4
82#define MILES_MT32_PATCHDATA_TOTAL_SIZE (MILES_MT32_PATCHDATA_COMMONPARAMETER_SIZE + (MILES_MT32_PATCHDATA_PARTIALPARAMETER_SIZE * MILES_MT32_PATCHDATA_PARTIALPARAMETERS_COUNT))
83
84// Some engines using Miles assume a source neutral
85// volume of 256, so use this by default.
86#define MILES_DEFAULT_SOURCE_NEUTRAL_VOLUME 256
87
88enum MilesVersion {
89 MILES_VERSION_2 = 2,
90 MILES_VERSION_3
91};
92
94 byte bankId;
95 byte patchId;
96 byte commonParameter[MILES_MT32_PATCHDATA_COMMONPARAMETER_SIZE];
97 byte partialParameters[MILES_MT32_PATCHDATA_PARTIALPARAMETERS_COUNT][MILES_MT32_PATCHDATA_PARTIALPARAMETER_SIZE];
98};
99
106public:
108
120 virtual void processXMIDITimbreChunk(const byte *timbreListPtr, uint32 timbreListSize) = 0;
121};
122
124public:
125 MidiDriver_Miles_Midi(MusicType midiType, MilesMT32InstrumentEntry *instrumentTablePtr, uint16 instrumentTableCount);
127
128public:
130 void send(int8 source, uint32 b) override;
131
138 void deinitSource(uint8 source) override;
139
140 void stopAllNotes(bool stopSustainedNotes = false) override;
141
142 uint32 property(int prop, uint32 param) override;
143
144 void processXMIDITimbreChunk(const byte *timbreListPtr, uint32 timbreListSize) override;
145
146protected:
147 void initControlData() override;
148 void initMidiDevice() override;
149 void applySourceVolume(uint8 source) override;
150
151private:
152 void writeRhythmSetup(byte note, byte customTimbreId);
153 void writePatchTimbre(byte patchId, byte timbreGroup, byte timbreId, bool useSysExQueue = false);
154 void writePatchByte(byte patchId, byte index, byte patchValue);
155 void writeToSystemArea(byte index, byte value);
156
157 const MilesMT32InstrumentEntry *searchCustomInstrument(byte patchBank, byte patchId);
158 int16 searchCustomTimbre(byte patchBank, byte patchId);
159
160 void setupPatch(byte patchBank, byte patchId, bool useSysExQueue = false);
161 int16 installCustomTimbre(byte patchBank, byte patchId);
162
163private:
170 struct MilesMidiChannelControlData : MidiChannelControlData {
171 // Custom timbre data
172 byte currentPatchBank;
173
174 bool usingCustomTimbre;
175 byte currentCustomTimbreId;
176
177 MilesMidiChannelControlData() : currentPatchBank(0),
178 usingCustomTimbre(false),
179 currentCustomTimbreId(0) { }
180 };
181
182 struct MidiChannelEntry {
183 // True if this channel is locked. A locked channel will
184 // only accept MIDI messages from the source that locked it.
185 bool locked;
186 // The channel in the MIDI data of the lock source that
187 // is assigned to this locked output channel. This is a
188 // reverse lookup for MidiSource::channelMap.
189 // -1 if the channel is not locked.
190 int8 lockDataChannel;
191 // True if this channel is protected from locking.
192 // The channel can still be locked, but unprotected
193 // channels will be prioritized.
194 bool lockProtected;
195 // The source that protected this channel from locking.
196 // -1 if the channel is not protected.
197 int8 protectedSource;
198
199 // The number of notes currently active on the channel.
200 uint8 activeNotes;
201
202 // The MIDI controller values currently used by the channel.
203 MilesMidiChannelControlData *currentData;
204 // The MIDI controller values set by the sources which are
205 // not currently using the channel because it is locked.
206 // These values will be set on the channel when the channel
207 // is unlocked.
208 MilesMidiChannelControlData *unlockData;
209
210 MidiChannelEntry() : locked(false),
211 lockDataChannel(-1),
212 lockProtected(false),
213 protectedSource(-1),
214 activeNotes(0),
215 currentData(0),
216 unlockData(0) { }
217 };
218
224 void controlChange(byte outputChannel, byte controllerNumber, byte controllerValue, int8 source, MidiChannelControlData &controlData, bool channelLockedByOtherSource = false) override;
225 bool addActiveNote(uint8 outputChannel, uint8 note, int8 source) override;
226 bool removeActiveNote(uint8 outputChannel, uint8 note, int8 source) override;
231 void removeActiveNotes(uint8 outputChannel, bool sustainedNotes) override;
237 void lockChannel(uint8 source, uint8 dataChannel);
245 int8 findLockChannel(bool useProtectedChannels = false);
250 void unlockChannel(uint8 outputChannel);
256 void programChange(byte outputChannel, byte patchId, int8 source, MidiChannelControlData &controlData, bool channelLockedByOtherSource = false) override;
257
258 void stopNotesOnChannel(uint8 outputChannelNumber);
259
260 struct MidiCustomTimbreEntry {
261 bool used;
262 bool protectionEnabled;
263 byte currentPatchBank;
264 byte currentPatchId;
265
266 uint32 lastUsedNoteCounter;
267
268 MidiCustomTimbreEntry() : used(false),
269 protectionEnabled(false),
270 currentPatchBank(0),
271 currentPatchId(0),
272 lastUsedNoteCounter(0) {}
273 };
274
275 struct MilesMT32SysExQueueEntry {
276 uint32 targetAddress;
277 byte dataPos;
278 byte data[MILES_CONTROLLER_SYSEX_QUEUE_SIZE];
279
280 MilesMT32SysExQueueEntry() : targetAddress(0),
281 dataPos(0) {
282 memset(data, 0, sizeof(data));
283 }
284 };
285
286 // the version of Miles AIL/MSS to emulate
287 MilesVersion _milesVersion;
288
289 // stores information about all MIDI channels
290 MidiChannelEntry _midiChannels[MIDI_CHANNEL_COUNT];
291
292 // stores information about all custom timbres
293 MidiCustomTimbreEntry _customTimbres[MILES_MT32_CUSTOMTIMBRE_COUNT];
294
295 byte _patchesBank[MILES_MT32_PATCHES_COUNT];
296
297 // holds all instruments
298 MilesMT32InstrumentEntry *_instrumentTablePtr;
299 uint16 _instrumentTableCount;
300
301 uint32 _noteCounter; // used to figure out, which timbres are outdated
302
303 // Queues for Miles SysEx controllers
304 MilesMT32SysExQueueEntry _milesSysExQueues[MILES_CONTROLLER_SYSEX_QUEUE_COUNT];
305};
306
307extern MidiDriver_Multisource *MidiDriver_Miles_AdLib_create(const Common::Path &filenameAdLib, const Common::Path &filenameOPL3, Common::SeekableReadStream *streamAdLib = nullptr, Common::SeekableReadStream *streamOPL3 = nullptr);
308
309extern MidiDriver_Miles_Midi *MidiDriver_Miles_MT32_create(const Common::Path &instrumentDataFilename);
310
311extern MidiDriver_Miles_Midi *MidiDriver_Miles_MIDI_create(MusicType midiType, const Common::Path &instrumentDataFilename);
313} // End of namespace Audio
314
315#endif // AUDIO_MILES_MIDIDRIVER_H
Definition: miles.h:123
void deinitSource(uint8 source) override
void send(int8 source, uint32 b) override
void stopAllNotes(bool stopSustainedNotes=false) override
void initMidiDevice() override
void applySourceVolume(uint8 source) override
void processXMIDITimbreChunk(const byte *timbreListPtr, uint32 timbreListSize) override
uint32 property(int prop, uint32 param) override
void initControlData() override
virtual void processXMIDITimbreChunk(const byte *timbreListPtr, uint32 timbreListSize)=0
Definition: path.h:52
Definition: stream.h:745
Definition: mt32gm.h:111
void send(uint32 b) override
Definition: mididrv_ms.h:86
MusicType
Definition: mididrv.h:44
Definition: system.h:39
Definition: miles.h:93