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 
33 namespace 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 
88 enum 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 
106 public:
107  virtual ~MidiDriver_Miles_Xmidi_Timbres() { }
108 
120  virtual void processXMIDITimbreChunk(const byte *timbreListPtr, uint32 timbreListSize) = 0;
121 };
122 
124 public:
125  MidiDriver_Miles_Midi(MusicType midiType, MilesMT32InstrumentEntry *instrumentTablePtr, uint16 instrumentTableCount);
127 
128 public:
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 
146 protected:
147  void initControlData() override;
148  void initMidiDevice() override;
149  void applySourceVolume(uint8 source) override;
150 
151 private:
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 
163 private:
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 
307 extern MidiDriver_Multisource *MidiDriver_Miles_AdLib_create(const Common::Path &filenameAdLib, const Common::Path &filenameOPL3, Common::SeekableReadStream *streamAdLib = nullptr, Common::SeekableReadStream *streamOPL3 = nullptr);
308 
309 extern MidiDriver_Miles_Midi *MidiDriver_Miles_MT32_create(const Common::Path &instrumentDataFilename);
310 
311 extern 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: mt32gm.h:111
Definition: miles.h:123
Definition: mididrv_ms.h:86
MusicType
Definition: mididrv.h:44
Definition: path.h:52
Definition: stream.h:745
Definition: miles.h:93
void send(uint32 b) override
Definition: system.h:37