ScummVM API documentation
mt32gm.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_MT32GM_H
23 #define AUDIO_MT32GM_H
24 
25 #include "audio/mididrv.h"
26 #include "audio/mididrv_ms.h"
27 #include "common/list.h"
28 #include "common/mutex.h"
29 
112 public:
113  static const byte MT32_DEFAULT_INSTRUMENTS[8];
114  static const int16 MT32_DEFAULT_INSTRUMENTS_CONTROLLER_DEFAULTS[16];
115  static const byte MT32_DEFAULT_PANNING[8];
116  static const uint8 MT32_DEFAULT_CHANNEL_VOLUME = 102;
117  static const uint8 GM_DEFAULT_CHANNEL_VOLUME = 100;
118  // Map for correcting Roland GS drumkit numbers.
119  static const uint8 GS_DRUMKIT_FALLBACK_MAP[128];
120 
121  static const uint8 MT32_DISPLAY_NUM_CHARS = 20;
122  static const uint32 MT32_DISPLAY_MEMORY_ADDRESS = 0x20 << 14;
123 
124 protected:
125  static const uint8 MAXIMUM_MT32_ACTIVE_NOTES = 48;
126  static const uint8 MAXIMUM_GM_ACTIVE_NOTES = 96;
127 
128 protected:
136  // The source that last sent an event to this channel
137  int8 source;
138  // True if the source volume has been applied to this channel
139  bool sourceVolumeApplied;
140 
141  uint16 pitchWheel;
142  byte program;
143  // The Roland GS instrument bank
144  byte instrumentBank;
145  byte channelPressure;
146 
147  byte modulation;
148  // The volume specified by the MIDI data
149  byte volume;
150  // The volume set on the MIDI device. This is scaled using the source
151  // volume and optionally the user-specified volume setting.
152  byte scaledVolume;
153  byte panPosition;
154  byte expression;
155  bool sustain;
156 
157  // The currently selected Registered Parameter Number
158  uint16 rpn;
159  byte pitchBendSensitivity;
160 
161  MidiChannelControlData() : source(-1),
162  sourceVolumeApplied(false),
163  pitchWheel(MIDI_PITCH_BEND_DEFAULT),
164  program(0),
165  instrumentBank(0),
166  channelPressure(0),
167  modulation(0),
168  volume(0),
169  scaledVolume(0),
170  panPosition(MIDI_PANNING_DEFAULT),
171  expression(MIDI_EXPRESSION_DEFAULT),
172  sustain(false),
173  rpn(MIDI_RPN_NULL),
174  pitchBendSensitivity(0) { }
175  };
176 
180  struct MidiSource {
181  // Whether this source sends music or SFX MIDI data.
182  SourceType type;
183  // The source volume (relative volume for this source as defined by the game).
184  // Default is the default neutral value (255).
185  uint16 volume;
186  // The source volume level at which no scaling is performed (volume as defined
187  // in MIDI data is used directly). Volume values below this decrease volume,
188  // values above increase volume (up to the maximum MIDI channel volume).
189  // Set this to match the volume values used by the game engine to avoid having
190  // to convert them. Default value is 255; minimum value is 1.
191  uint16 neutralVolume;
192  // The volume level at which the fade started.
193  uint16 fadeStartVolume;
194  // The target volume level for the fade.
195  uint16 fadeEndVolume;
196  // How much us has passed since the start of the fade.
197  int32 fadePassedTime;
198  // The total duration of the fade (us).
199  int32 fadeDuration;
200  // The mapping of MIDI data channels to output channels for this source.
201  int8 channelMap[MIDI_CHANNEL_COUNT];
202  // Bitmask specifying which MIDI channels are available for use by this source.
203  uint16 availableChannels;
204 
206  neutralVolume(DEFAULT_SOURCE_NEUTRAL_VOLUME), fadeStartVolume(0),
207  fadeEndVolume(0), fadePassedTime(0), fadeDuration(0), availableChannels(0xFFFF) {
208  memset(channelMap, 0, sizeof(channelMap));
209  }
210  };
211 
216  struct ActiveNote {
217  int8 source;
218  uint8 channel;
219  uint8 note;
220  // True if the note is sustained. The note will turn off when the
221  // sustain controller for the MIDI channel is turned off.
222  bool sustain;
223 
224  ActiveNote() { clear(); }
225 
226  void clear() {
227  source = 0x7F;
228  channel = 0xFF;
229  note = 0xFF;
230  sustain = false;
231  }
232 
233  };
234 
240  struct SysExData {
241  byte data[270];
242  uint16 length;
243  int8 source;
244  SysExData() : length(0), source(-1) {
245  memset(data, 0, sizeof(data));
246  }
247  };
248 
249 public:
250  // Callback hooked up to the driver wrapped by the MIDI driver
251  // object. Executes onTimer and the external callback set by
252  // the setTimerCallback function.
253  static void timerCallback(void *data);
254 
255  MidiDriver_MT32GM(MusicType midiType);
257 
258  // MidiDriver interface
259  int open() override;
260  // Open the driver wrapping the specified MidiDriver instance.
261  virtual int open(MidiDriver *driver, bool nativeMT32);
262  void close() override;
263  bool isOpen() const override { return _isOpen; }
264  bool isReady(int8 source = -1) override;
265  uint32 property(int prop, uint32 param) override;
266 
267  using MidiDriver_BASE::send;
268  void send(uint32 b) override;
269  void send(int8 source, uint32 b) override;
270  void sysEx(const byte *msg, uint16 length) override;
271  uint16 sysExNoDelay(const byte *msg, uint16 length) override;
279  void sysExQueue(const byte *msg, uint16 length, int8 source = -1);
299  uint16 sysExMT32(const byte *msg, uint16 length, const uint32 targetAddress, bool queue = false, bool delay = true, int8 source = -1);
300  uint16 sysExMT32(const byte *msg, uint16 length, bool queue = false, bool delay = true, int8 source = -1);
301  void metaEvent(int8 source, byte type, const byte *data, uint16 length) override;
302 
303  void stopAllNotes(bool stopSustainedNotes = false) override;
307  void clearSysExQueue();
308  MidiChannel *allocateChannel() override;
309  MidiChannel *getPercussionChannel() override;
310  uint32 getBaseTempo() override;
311 
329  virtual bool allocateSourceChannels(uint8 source, uint8 numChannels);
334  void deinitSource(uint8 source) override;
335 
336 protected:
341  virtual void initControlData();
345  virtual void initMidiDevice();
352  virtual void initMT32(bool initForGM);
362  virtual void initGM(bool initForMT32, bool enableGS);
378  virtual void processEvent(int8 source, uint32 b, uint8 outputChannel,
379  MidiChannelControlData &controlData, bool channelLockedByOtherSource = false);
395  virtual void applyControllerDefaults(uint8 source, MidiChannelControlData &controlData, uint8 outputChannel, bool channelLockedByOtherSource);
406  virtual void noteOnOff(byte outputChannel, byte command, byte note, byte velocity,
407  int8 source, MidiChannelControlData &controlData);
420  virtual void polyAftertouch(byte outputChannel, byte note, byte pressure,
421  int8 source, MidiChannelControlData &controlData, bool channelLockedByOtherSource = false);
433  virtual void controlChange(byte outputChannel, byte controllerNumber, byte controllerValue,
434  int8 source, MidiChannelControlData &controlData, bool channelLockedByOtherSource = false);
447  virtual void programChange(byte outputChannel, byte patchId, int8 source,
448  MidiChannelControlData &controlData, bool channelLockedByOtherSource = false);
461  virtual void channelAftertouch(byte outputChannel, byte pressure, int8 source,
462  MidiChannelControlData &controlData, bool channelLockedByOtherSource = false);
476  virtual void pitchBend(byte outputChannel, uint8 pitchBendLsb, uint8 pitchBendMsb,
477  int8 source, MidiChannelControlData &controlData, bool channelLockedByOtherSource = false);
478 
482  virtual bool addActiveNote(uint8 outputChannel, uint8 note, int8 source);
486  virtual bool removeActiveNote(uint8 outputChannel, uint8 note, int8 source);
491  virtual void removeActiveNotes(uint8 outputChannel, bool sustainedNotes);
495  bool isOutputChannelUsed(int8 outputChannel);
501  virtual byte mapMT32InstrumentToGM(byte mt32Instrument);
507  virtual byte mapGMInstrumentToMT32(byte gmInstrument);
517  byte correctInstrumentBank(byte outputChannel, byte patchId);
518 
528  virtual int8 mapSourceChannel(uint8 source, uint8 dataChannel);
529 
530  void applySourceVolume(uint8 source) override;
531  void stopAllNotes(uint8 source, uint8 channel) override;
536  void onTimer() override;
537 
538  Common::Mutex _allocationMutex; // For operations on MIDI channel allocation
539  Common::Mutex _activeNotesMutex; // For operations on active notes registration
540 
541  // The wrapped MIDI driver.
542  MidiDriver *_driver;
543  // The type of MIDI data supplied to the driver: MT-32 or General MIDI.
544  MusicType _midiType;
545  // True if the MIDI output is an MT-32 (hardware or 100% emulated),
546  // false if the MIDI output is a General MIDI device.
547  bool _nativeMT32;
548  // True if the General MIDI output supports Roland GS for improved MT-32 mapping.
549  bool _enableGS;
550  // Indicates if the stereo panning in the MIDI data is reversed
551  // compared to the stereo panning of the intended MIDI device.
552  bool _midiDataReversePanning;
553  // Indicates if the stereo panning of the output MIDI device is
554  // reversed compared to the stereo panning of the type of MIDI
555  // device targeted by the MIDI data (i.e. MT-32 data playing on
556  // a GM device or the other way around).
557  bool _midiDeviceReversePanning;
558  // True if GS percussion channel volume should be scaled to match MT-32 volume.
559  bool _scaleGSPercussionVolumeToMT32;
560 
561  // True if this MIDI driver has been opened.
562  bool _isOpen;
563  // Bitmask of the MIDI channels in use by the output device.
564  uint16 _outputChannelMask;
565  int _baseFreq;
566 
567  // stores the controller values for each MIDI channel
568  MidiChannelControlData *_controlData[MIDI_CHANNEL_COUNT];
569  // The mapping of MIDI data channels to output channels for each source.
570  int8 _channelMap[MAXIMUM_SOURCES][MIDI_CHANNEL_COUNT];
571  // Bitmask specifying which MIDI channels are available for use by each source.
572  uint16 _availableChannels[MAXIMUM_SOURCES];
573 
574  // Maps used for MT-32 <> GM instrument mapping. Set these to an alternate
575  // 128 byte array to customize the mapping.
576  const byte *_mt32ToGMInstrumentMap;
577  const byte *_gmToMT32InstrumentMap;
578  // The maximum active notes for the current MIDI device.
579  uint8 _maximumActiveNotes;
580  // Active note registration
581  ActiveNote *_activeNotes;
582 
583  // The current number of microseconds that have to elapse before the next
584  // SysEx message can be sent.
585  uint32 _sysExDelay;
586  // Queue of SysEx messages to be sent to the MIDI device.
587  Common::List<SysExData> _sysExQueue;
588  // Mutex for write access to the SysEx queue.
589  Common::Mutex _sysExQueueMutex;
590 };
592 #endif
Definition: mt32gm.h:111
byte correctInstrumentBank(byte outputChannel, byte patchId)
bool isReady(int8 source=-1) override
void onTimer() override
virtual void channelAftertouch(byte outputChannel, byte pressure, int8 source, MidiChannelControlData &controlData, bool channelLockedByOtherSource=false)
virtual void programChange(byte outputChannel, byte patchId, int8 source, MidiChannelControlData &controlData, bool channelLockedByOtherSource=false)
virtual void controlChange(byte outputChannel, byte controllerNumber, byte controllerValue, int8 source, MidiChannelControlData &controlData, bool channelLockedByOtherSource=false)
virtual bool allocateSourceChannels(uint8 source, uint8 numChannels)
virtual int8 mapSourceChannel(uint8 source, uint8 dataChannel)
bool isOutputChannelUsed(int8 outputChannel)
void close() override
virtual void noteOnOff(byte outputChannel, byte command, byte note, byte velocity, int8 source, MidiChannelControlData &controlData)
Definition: mididrv_ms.h:86
MusicType
Definition: mididrv.h:44
Definition: list.h:44
virtual void removeActiveNotes(uint8 outputChannel, bool sustainedNotes)
virtual byte mapGMInstrumentToMT32(byte gmInstrument)
virtual void initMT32(bool initForGM)
Definition: mididrv.h:313
uint32 property(int prop, uint32 param) override
virtual void initMidiDevice()
void deinitSource(uint8 source) override
bool isOpen() const override
Definition: mt32gm.h:263
void applySourceVolume(uint8 source) override
virtual void initControlData()
static const uint8 MAXIMUM_SOURCES
Definition: mididrv_ms.h:92
Definition: mt32gm.h:216
virtual void processEvent(int8 source, uint32 b, uint8 outputChannel, MidiChannelControlData &controlData, bool channelLockedByOtherSource=false)
SourceType
Definition: mididrv_ms.h:110
virtual bool removeActiveNote(uint8 outputChannel, uint8 note, int8 source)
Definition: mutex.h:67
Definition: mt32gm.h:180
void send(uint32 b) override
virtual void pitchBend(byte outputChannel, uint8 pitchBendLsb, uint8 pitchBendMsb, int8 source, MidiChannelControlData &controlData, bool channelLockedByOtherSource=false)
void sysEx(const byte *msg, uint16 length) override
Definition: mididrv.h:541
uint16 sysExNoDelay(const byte *msg, uint16 length) override
int open() override
uint32 getBaseTempo() override
virtual void initGM(bool initForMT32, bool enableGS)
virtual void applyControllerDefaults(uint8 source, MidiChannelControlData &controlData, uint8 outputChannel, bool channelLockedByOtherSource)
static const uint16 DEFAULT_SOURCE_NEUTRAL_VOLUME
Definition: mididrv_ms.h:100
virtual void polyAftertouch(byte outputChannel, byte note, byte pressure, int8 source, MidiChannelControlData &controlData, bool channelLockedByOtherSource=false)
Definition: mt32gm.h:240
void sysExQueue(const byte *msg, uint16 length, int8 source=-1)
virtual bool addActiveNote(uint8 outputChannel, uint8 note, int8 source)
void metaEvent(int8 source, byte type, const byte *data, uint16 length) override
virtual void send(uint32 b)=0
virtual byte mapMT32InstrumentToGM(byte mt32Instrument)
uint16 sysExMT32(const byte *msg, uint16 length, const uint32 targetAddress, bool queue=false, bool delay=true, int8 source=-1)
void stopAllNotes(bool stopSustainedNotes=false) override