ScummVM API documentation
mididrv.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_MIDIDRV_H
23 #define AUDIO_MIDIDRV_H
24 
25 #include "common/scummsys.h"
26 #include "common/str.h"
27 #include "common/stream.h"
28 #include "common/timer.h"
29 #include "common/array.h"
30 
31 class MidiChannel;
32 
44 enum MusicType {
45  MT_INVALID = -1, // Invalid output
46  MT_AUTO = 0, // Auto
47  MT_NULL, // Null
48  MT_PCSPK, // PC Speaker
49  MT_PCJR, // PCjr
50  MT_CMS, // CMS
51  MT_ADLIB, // AdLib
52  MT_C64, // C64
53  MT_AMIGA, // Amiga
54  MT_APPLEIIGS, // Apple IIGS
55  MT_TOWNS, // FM-TOWNS
56  MT_PC98, // PC98
57  MT_SEGACD, // SegaCD
58  MT_MACINTOSH, // Apple Macintosh
59 
60  // All devices after this one are treated as MIDI devices
61  MT_GM, // General MIDI
62  MT_MT32, // MT-32
63  MT_GS, // Roland GS
64  MT_MT540, // Casio MT-540
65  MT_CT460 // Casio CT-460 / CSM-1
66 };
67 
84  MDT_NONE = 0,
85  MDT_PCSPK = 1 << 0, // PC Speaker: Maps to MT_PCSPK and MT_PCJR
86  MDT_CMS = 1 << 1, // Creative Music System / Gameblaster: Maps to MT_CMS
87  MDT_PCJR = 1 << 2, // Tandy/PC Junior driver
88  MDT_ADLIB = 1 << 3, // AdLib: Maps to MT_ADLIB
89  MDT_C64 = 1 << 4,
90  MDT_AMIGA = 1 << 5,
91  MDT_APPLEIIGS = 1 << 6,
92  MDT_TOWNS = 1 << 7, // FM-TOWNS: Maps to MT_TOWNS
93  MDT_PC98 = 1 << 8, // PC-98: Maps to MT_PC98
94  MDT_SEGACD = 1 << 9,
95  MDT_MIDI = 1 << 10, // Real MIDI
96  MDT_PREFER_MT32 = 1 << 11, // MT-32 output is preferred
97  MDT_PREFER_GM = 1 << 12, // GM output is preferred
98  MDT_PREFER_FLUID = 1 << 13, // FluidSynth driver is preferred
99  MDT_MACINTOSH = 1 << 14,
100 
101  MDT_SUPPLIED_SOUND_FONT = 1 << 15, // Engine will supply sound font (allows checkDevice to pass if it would fail due to missing sound font)
102 };
103 
104 enum MidiDriverCheckFlags {
105  MDCK_NONE = 0,
106 
107  MDCK_SUPPLIED_SOUND_FONT = 1 << 0, // Sound font will be supplied by the engine
108  MDCK_AUTO = 1 << 1, // Driver is being checked for automatic selection (i.e. MIDI device is set to "auto")
109 };
110 
115 public:
116  static const uint8 MIDI_CHANNEL_COUNT = 16;
117  static const uint8 MIDI_RHYTHM_CHANNEL = 9;
118 
119  static const byte MIDI_COMMAND_NOTE_OFF = 0x80;
120  static const byte MIDI_COMMAND_NOTE_ON = 0x90;
121  static const byte MIDI_COMMAND_POLYPHONIC_AFTERTOUCH = 0xA0;
122  static const byte MIDI_COMMAND_CONTROL_CHANGE = 0xB0;
123  static const byte MIDI_COMMAND_PROGRAM_CHANGE = 0xC0;
124  static const byte MIDI_COMMAND_CHANNEL_AFTERTOUCH = 0xD0;
125  static const byte MIDI_COMMAND_PITCH_BEND = 0xE0;
126  static const byte MIDI_COMMAND_SYSTEM = 0xF0;
127 
128  static const byte MIDI_CONTROLLER_BANK_SELECT_MSB = 0x00;
129  static const byte MIDI_CONTROLLER_MODULATION = 0x01;
130  static const byte MIDI_CONTROLLER_DATA_ENTRY_MSB = 0x06;
131  static const byte MIDI_CONTROLLER_VOLUME = 0x07;
132  static const byte MIDI_CONTROLLER_BALANCE = 0x08;
133  static const byte MIDI_CONTROLLER_PANNING = 0x0A;
134  static const byte MIDI_CONTROLLER_EXPRESSION = 0x0B;
135  static const byte MIDI_CONTROLLER_BANK_SELECT_LSB = 0x20;
136  static const byte MIDI_CONTROLLER_DATA_ENTRY_LSB = 0x26;
137  static const byte MIDI_CONTROLLER_SUSTAIN = 0x40;
138  static const byte MIDI_CONTROLLER_PORTAMENTO = 0x41;
139  static const byte MIDI_CONTROLLER_SOSTENUTO = 0x42;
140  static const byte MIDI_CONTROLLER_SOFT = 0x43;
141  static const byte MIDI_CONTROLLER_REVERB = 0x5B;
142  static const byte MIDI_CONTROLLER_CHORUS = 0x5D;
143  static const byte MIDI_CONTROLLER_RPN_LSB = 0x64;
144  static const byte MIDI_CONTROLLER_RPN_MSB = 0x65;
145  static const byte MIDI_CONTROLLER_ALL_SOUND_OFF = 0x78;
146  static const byte MIDI_CONTROLLER_RESET_ALL_CONTROLLERS = 0x79;
147  static const byte MIDI_CONTROLLER_ALL_NOTES_OFF = 0x7B;
148  static const byte MIDI_CONTROLLER_OMNI_ON = 0x7C;
149  static const byte MIDI_CONTROLLER_OMNI_OFF = 0x7D;
150  static const byte MIDI_CONTROLLER_MONO_ON = 0x7E;
151  static const byte MIDI_CONTROLLER_POLY_ON = 0x7F;
152 
153  static const uint16 MIDI_RPN_PITCH_BEND_SENSITIVITY = 0x0000;
154  static const uint16 MIDI_RPN_MASTER_TUNING_FINE = 0x0001;
155  static const uint16 MIDI_RPN_MASTER_TUNING_COARSE = 0x0002;
156  static const uint16 MIDI_RPN_NULL = 0x7F7F;
157 
158  static const uint8 MIDI_META_END_OF_TRACK = 0x2F;
159  static const uint8 MIDI_META_SEQUENCER = 0x7F;
160 
161  static const uint16 MIDI_PITCH_BEND_DEFAULT = 0x2000;
162  static const uint8 MIDI_PANNING_DEFAULT = 0x40;
163  static const uint8 MIDI_EXPRESSION_DEFAULT = 0x7F;
164  static const uint16 MIDI_MASTER_TUNING_FINE_DEFAULT = 0x2000;
165  static const uint8 MIDI_MASTER_TUNING_COARSE_DEFAULT = 0x40;
166 
167  static const uint8 MT32_PITCH_BEND_SENSITIVITY_DEFAULT = 0x0C;
168  static const uint8 GM_PITCH_BEND_SENSITIVITY_DEFAULT = 0x02;
169  // Default reverb value on the Roland SC-55
170  static const uint8 GM_REVERB_DEFAULT = 0x28;
171 
172  static const uint8 GS_RHYTHM_FIRST_NOTE = 0x1B;
173  static const uint8 GS_RHYTHM_LAST_NOTE = 0x58;
174 
175  MidiDriver_BASE();
176 
177  virtual ~MidiDriver_BASE();
178 
185  virtual void send(uint32 b) = 0;
186 
192  virtual void send(int8 source, uint32 b) { send(b); }
193 
201  void send(byte status, byte firstOp, byte secondOp);
202 
208  void send(int8 source, byte status, byte firstOp, byte secondOp);
209 
220  virtual void sysEx(const byte *msg, uint16 length) { }
221 
234  virtual uint16 sysExNoDelay(const byte *msg, uint16 length) { sysEx(msg, length); return 0; }
235 
236  // TODO: Document this.
237  virtual void metaEvent(byte type, const byte *data, uint16 length) { }
238 
244  virtual void metaEvent(int8 source, byte type, const byte *data, uint16 length) { metaEvent(type, data, length); }
245 
262  virtual void stopAllNotes(bool stopSustainedNotes = false);
263 
272  virtual bool isReady(int8 source = -1) { return true; }
273 
274 protected:
275 
281 
283  uint32 _prevMillis;
284 
287 
289  void midiDumpInit();
290 
292  int midiDumpVarLength(const uint32 &delta);
293 
295  void midiDumpDelta();
296 
298  void midiDumpDo(uint32 b);
299 
301  void midiDumpSysEx(const byte *msg, uint16 length);
302 
304  void midiDumpFinish();
305 
306 };
307 
313 class MidiDriver : public MidiDriver_BASE {
314 public:
322  typedef uint32 DeviceHandle;
323 
324  enum DeviceStringType {
325  kDriverName,
326  kDriverId,
327  kDeviceName,
328  kDeviceId
329  };
330 
331  static Common::String musicType2GUIO(uint32 musicType);
332 
334  static MidiDriver *createMidi(DeviceHandle handle);
335 
337  static DeviceHandle detectDevice(int flags);
338 
340  static DeviceHandle getDeviceHandle(const Common::String &identifier);
341 
351  static bool checkDevice(DeviceHandle handle, int flags, bool quiet);
352 
354  static MusicType getMusicType(DeviceHandle handle);
355 
357  static Common::String getDeviceString(DeviceHandle handle, DeviceStringType type);
358 
360  void midiDriverCommonSend(uint32 b);
361 
363  void midiDriverCommonSysEx(const byte *msg, uint16 length);
364 
365 private:
366  // If detectDevice() detects MT32 and we have a preferred MT32 device
367  // we use this to force getMusicType() to return MT_MT32 so that we don't
368  // have to rely on the 'True Roland MT-32' config manager setting (since nobody
369  // would possibly think about activating 'True Roland MT-32' when he has set
370  // 'Music Driver' to '<default>')
371  static bool _forceTypeMT32;
372 
373 public:
374  virtual ~MidiDriver() { }
375 
376  static const byte _mt32ToGm[128];
377  static const byte _gmToMt32[128];
378 
383  enum {
384  MERR_CANNOT_CONNECT = 1,
385 // MERR_STREAMING_NOT_AVAILABLE = 2,
386  MERR_DEVICE_NOT_AVAILABLE = 3,
387  MERR_ALREADY_OPEN = 4
388  };
389 
390  enum {
391  // PROP_TIMEDIV = 1,
392  PROP_OLD_ADLIB = 2,
393  PROP_CHANNEL_MASK = 3,
394  // HACK: Not so nice, but our SCUMM AdLib code is in audio/
395  PROP_SCUMM_OPL3 = 4,
405  PROP_USER_VOLUME_SCALING = 5,
424  PROP_MIDI_DATA_REVERSE_PANNING = 6,
436  PROP_OPL_ACCURACY_MODE = 7,
456  PROP_OPL_CHANNEL_ALLOCATION_MODE = 8,
467  PROP_MILES_VERSION = 9,
481  PROP_OPL_RHYTHM_MODE_IGNORE_NOTE_OFF = 10
482  };
483 
488  virtual int open() = 0;
489 
493  virtual bool isOpen() const = 0;
494 
496  virtual void close() = 0;
497 
499  virtual uint32 property(int prop, uint32 param) { return 0; }
500 
502  static const char *getErrorName(int error_code);
503 
504  // HIGH-LEVEL SEMANTIC METHODS
505  virtual void setPitchBendRange(byte channel, uint range) {
506  send(MIDI_COMMAND_CONTROL_CHANGE | channel, MIDI_CONTROLLER_RPN_MSB, MIDI_RPN_PITCH_BEND_SENSITIVITY >> 8);
507  send(MIDI_COMMAND_CONTROL_CHANGE | channel, MIDI_CONTROLLER_RPN_LSB, MIDI_RPN_PITCH_BEND_SENSITIVITY & 0xFF);
508  send(MIDI_COMMAND_CONTROL_CHANGE | channel, MIDI_CONTROLLER_DATA_ENTRY_MSB, range); // Semi-tones
509  send(MIDI_COMMAND_CONTROL_CHANGE | channel, MIDI_CONTROLLER_DATA_ENTRY_LSB, 0); // Cents
510  send(MIDI_COMMAND_CONTROL_CHANGE | channel, MIDI_CONTROLLER_RPN_MSB, MIDI_RPN_NULL >> 8);
511  send(MIDI_COMMAND_CONTROL_CHANGE | channel, MIDI_CONTROLLER_RPN_LSB, MIDI_RPN_NULL & 0xFF);
512  }
513 
517  void sendMT32Reset();
518 
522  void sendGMReset();
523 
524  // Timing functions - MidiDriver now operates timers
525  virtual void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) = 0;
526 
528  virtual uint32 getBaseTempo() = 0;
529 
530  // Channel allocation functions
531  virtual MidiChannel *allocateChannel() = 0;
532  virtual MidiChannel *getPercussionChannel() = 0;
533 
534  // Allow an engine to supply its own soundFont data. This stream will be destroyed after use.
535  virtual void setEngineSoundFont(Common::SeekableReadStream *soundFontData) { }
536 
537  // Does this driver accept soundFont data?
538  virtual bool acceptsSoundFontData() { return false; }
539 };
540 
541 class MidiChannel {
542 public:
543  virtual ~MidiChannel() {}
544 
545  virtual MidiDriver *device() = 0;
546  virtual byte getNumber() = 0;
547  virtual void release() = 0;
548 
549  virtual void send(uint32 b) = 0; // 4-bit channel portion is ignored
550 
551  // Regular messages
552  virtual void noteOff(byte note) = 0;
553  virtual void noteOn(byte note, byte velocity) = 0;
554  virtual void programChange(byte program) = 0;
555  virtual void pitchBend(int16 bend) = 0; // -0x2000 to +0x1FFF
556 
557  // Control Change messages
558  virtual void controlChange(byte control, byte value) = 0;
559  virtual void modulationWheel(byte value) { controlChange(MidiDriver::MIDI_CONTROLLER_MODULATION, value); }
560  virtual void volume(byte value) { controlChange(MidiDriver::MIDI_CONTROLLER_VOLUME, value); }
561  virtual void panPosition(byte value) { controlChange(MidiDriver::MIDI_CONTROLLER_PANNING, value); }
562  virtual void pitchBendFactor(byte value) = 0;
563  virtual void transpose(int8 value) {}
564  virtual void detune(int16 value) { controlChange(17, value & 0xff); }
565  virtual void priority(byte value) { }
566  virtual void sustain(bool value) { controlChange(MidiDriver::MIDI_CONTROLLER_SUSTAIN, value ? 1 : 0); }
567  virtual void effectLevel(byte value) { controlChange(MidiDriver::MIDI_CONTROLLER_REVERB, value); }
568  virtual void chorusLevel(byte value) { controlChange(MidiDriver::MIDI_CONTROLLER_CHORUS, value); }
569  virtual void bankSelect(byte bank) {}
570  virtual void allNotesOff() { controlChange(MidiDriver::MIDI_CONTROLLER_ALL_NOTES_OFF, 0); }
571 
572  // SysEx messages
573  virtual void sysEx_customInstrument(uint32 type, const byte *instr, uint32 dataSize) = 0;
574 };
576 #endif
virtual uint32 property(int prop, uint32 param)
Definition: mididrv.h:499
void midiDumpDo(uint32 b)
Definition: str.h:59
int midiDumpVarLength(const uint32 &delta)
bool _midiDumpEnable
Definition: mididrv.h:280
uint32 DeviceHandle
Definition: mididrv.h:322
void midiDumpDelta()
MusicType
Definition: mididrv.h:44
void(* TimerProc)(void *refCon)
Definition: timer.h:42
MidiDriverFlags
Definition: mididrv.h:83
Definition: stream.h:745
virtual void stopAllNotes(bool stopSustainedNotes=false)
Definition: mididrv.h:313
virtual bool isReady(int8 source=-1)
Definition: mididrv.h:272
virtual void send(int8 source, uint32 b)
Definition: mididrv.h:192
Common::Array< byte > _midiDumpCache
Definition: mididrv.h:286
Definition: mididrv.h:114
void midiDumpSysEx(const byte *msg, uint16 length)
virtual void metaEvent(int8 source, byte type, const byte *data, uint16 length)
Definition: mididrv.h:244
Definition: mididrv.h:541
uint32 _prevMillis
Definition: mididrv.h:283
virtual void sysEx(const byte *msg, uint16 length)
Definition: mididrv.h:220
void midiDumpFinish()
virtual void send(uint32 b)=0
virtual uint16 sysExNoDelay(const byte *msg, uint16 length)
Definition: mididrv.h:234