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