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  void metaEvent(int8 source, byte type, const byte *data, uint16 length) override;
301 
302  void stopAllNotes(bool stopSustainedNotes = false) override;
306  void clearSysExQueue();
307  MidiChannel *allocateChannel() override;
308  MidiChannel *getPercussionChannel() override;
309  uint32 getBaseTempo() override;
310 
328  virtual bool allocateSourceChannels(uint8 source, uint8 numChannels);
333  void deinitSource(uint8 source) override;
334 
335 protected:
340  virtual void initControlData();
344  virtual void initMidiDevice();
351  virtual void initMT32(bool initForGM);
361  virtual void initGM(bool initForMT32, bool enableGS);
377  virtual void processEvent(int8 source, uint32 b, uint8 outputChannel,
378  MidiChannelControlData &controlData, bool channelLockedByOtherSource = false);
394  virtual void applyControllerDefaults(uint8 source, MidiChannelControlData &controlData, uint8 outputChannel, bool channelLockedByOtherSource);
405  virtual void noteOnOff(byte outputChannel, byte command, byte note, byte velocity,
406  int8 source, MidiChannelControlData &controlData);
419  virtual void polyAftertouch(byte outputChannel, byte note, byte pressure,
420  int8 source, MidiChannelControlData &controlData, bool channelLockedByOtherSource = false);
432  virtual void controlChange(byte outputChannel, byte controllerNumber, byte controllerValue,
433  int8 source, MidiChannelControlData &controlData, bool channelLockedByOtherSource = false);
446  virtual void programChange(byte outputChannel, byte patchId, int8 source,
447  MidiChannelControlData &controlData, bool channelLockedByOtherSource = false);
460  virtual void channelAftertouch(byte outputChannel, byte pressure, int8 source,
461  MidiChannelControlData &controlData, bool channelLockedByOtherSource = false);
475  virtual void pitchBend(byte outputChannel, uint8 pitchBendLsb, uint8 pitchBendMsb,
476  int8 source, MidiChannelControlData &controlData, bool channelLockedByOtherSource = false);
477 
481  virtual bool addActiveNote(uint8 outputChannel, uint8 note, int8 source);
485  virtual bool removeActiveNote(uint8 outputChannel, uint8 note, int8 source);
490  virtual void removeActiveNotes(uint8 outputChannel, bool sustainedNotes);
494  bool isOutputChannelUsed(int8 outputChannel);
500  virtual byte mapMT32InstrumentToGM(byte mt32Instrument);
506  virtual byte mapGMInstrumentToMT32(byte gmInstrument);
516  byte correctInstrumentBank(byte outputChannel, byte patchId);
517 
527  virtual int8 mapSourceChannel(uint8 source, uint8 dataChannel);
528 
529  void applySourceVolume(uint8 source) override;
530  void stopAllNotes(uint8 source, uint8 channel) override;
535  void onTimer() override;
536 
537  Common::Mutex _allocationMutex; // For operations on MIDI channel allocation
538  Common::Mutex _activeNotesMutex; // For operations on active notes registration
539 
540  // The wrapped MIDI driver.
541  MidiDriver *_driver;
542  // The type of MIDI data supplied to the driver: MT-32 or General MIDI.
543  MusicType _midiType;
544  // True if the MIDI output is an MT-32 (hardware or 100% emulated),
545  // false if the MIDI output is a General MIDI device.
546  bool _nativeMT32;
547  // True if the General MIDI output supports Roland GS for improved MT-32 mapping.
548  bool _enableGS;
549  // Indicates if the stereo panning in the MIDI data is reversed
550  // compared to the stereo panning of the intended MIDI device.
551  bool _midiDataReversePanning;
552  // Indicates if the stereo panning of the output MIDI device is
553  // reversed compared to the stereo panning of the type of MIDI
554  // device targeted by the MIDI data (i.e. MT-32 data playing on
555  // a GM device or the other way around).
556  bool _midiDeviceReversePanning;
557  // True if GS percussion channel volume should be scaled to match MT-32 volume.
558  bool _scaleGSPercussionVolumeToMT32;
559 
560  // True if this MIDI driver has been opened.
561  bool _isOpen;
562  // Bitmask of the MIDI channels in use by the output device.
563  uint16 _outputChannelMask;
564  int _baseFreq;
565 
566  // stores the controller values for each MIDI channel
567  MidiChannelControlData *_controlData[MIDI_CHANNEL_COUNT];
568  // The mapping of MIDI data channels to output channels for each source.
569  int8 _channelMap[MAXIMUM_SOURCES][MIDI_CHANNEL_COUNT];
570  // Bitmask specifying which MIDI channels are available for use by each source.
571  uint16 _availableChannels[MAXIMUM_SOURCES];
572 
573  // Maps used for MT-32 <> GM instrument mapping. Set these to an alternate
574  // 128 byte array to customize the mapping.
575  const byte *_mt32ToGMInstrumentMap;
576  const byte *_gmToMT32InstrumentMap;
577  // The maximum active notes for the current MIDI device.
578  uint8 _maximumActiveNotes;
579  // Active note registration
580  ActiveNote *_activeNotes;
581 
582  // The current number of microseconds that have to elapse before the next
583  // SysEx message can be sent.
584  uint32 _sysExDelay;
585  // Queue of SysEx messages to be sent to the MIDI device.
586  Common::List<SysExData> _sysExQueue;
587  // Mutex for write access to the SysEx queue.
588  Common::Mutex _sysExQueueMutex;
589 };
591 #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