1
/* ScummVM - Graphic Adventure Engine
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.
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* as published by the Free Software Foundation; either version 2
10
* of the License, or (at your option) any later version.
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.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21
* $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-1-2-1/sound/mididrv.h $
22
* $Id: mididrv.h 52736 2010-09-15 22:00:20Z lordhoto $
26
#ifndef SOUND_MIDIDRV_H
27
#define SOUND_MIDIDRV_H
29
#include "common/scummsys.h"
30
#include "common/timer.h"
38
namespace Common { class String; }
41
* Music Driver Types, used to uniquely identify each music driver.
43
* The pseudo drivers are listed first, then all native drivers,
44
* then all other MIDI drivers, and finally the non-MIDI drivers.
46
* @todo Rename MidiDriverType to MusicDriverType
50
* Music types that music drivers can implement and engines can rely on.
53
MT_INVALID = -1, // Invalid output
56
MT_PCSPK, // PC Speaker
62
MT_APPLEIIGS, // Apple IIGS
65
MT_GM, // General MIDI
71
* A set of flags to be passed to detectDevice() which can be used to
72
* specify what kind of music driver is preferred / accepted.
74
* The flags (except for MDT_PREFER_MT32 and MDT_PREFER_GM) indicate whether a given driver
75
* type is acceptable. E.g. the TOWNS music driver could be returned by
76
* detectDevice if and only if MDT_TOWNS is specified.
78
* @todo Rename MidiDriverFlags to MusicDriverFlags
80
enum MidiDriverFlags {
82
MDT_PCSPK = 1 << 0, // PC Speaker: Maps to MD_PCSPK and MD_PCJR
83
MDT_CMS = 1 << 1, // Creative Music System / Gameblaster: Maps to MD_CMS
84
MDT_PCJR = 1 << 2, // Tandy/PC Junior driver
85
MDT_ADLIB = 1 << 3, // AdLib: Maps to MT_ADLIB
88
MDT_APPLEIIGS = 1 << 6,
89
MDT_TOWNS = 1 << 7, // FM-TOWNS: Maps to MT_TOWNS
90
MDT_PC98 = 1 << 8, // FM-TOWNS: Maps to MT_PC98
91
MDT_MIDI = 1 << 9, // Real MIDI
92
MDT_PREFER_MT32 = 1 << 10, // MT-32 output is preferred
93
MDT_PREFER_GM = 1 << 11 // GM output is preferred
97
* Abstract description of a MIDI driver. Used by the config file and command
98
* line parsing code, and also to be able to give the user a list of available
101
* @todo Rename MidiDriverType to MusicDriverType
105
* Abstract MIDI Driver Class
107
* @todo Rename MidiDriver to MusicDriver
114
* The value 0 is reserved for an invalid device for now.
115
* TODO: Maybe we should use -1 (i.e. 0xFFFFFFFF) as
118
typedef uint32 DeviceHandle;
120
enum DeviceStringType {
126
static uint32 musicType2GUIO(uint32 musicType);
128
/** Create music driver matching the given device handle, or NULL if there is no match. */
129
static MidiDriver *createMidi(DeviceHandle handle);
131
/** Returns device handle based on the present devices and the flags parameter. */
132
static DeviceHandle detectDevice(int flags);
134
/** Find the music driver matching the given driver name/description. */
135
static DeviceHandle getDeviceHandle(const Common::String &identifier);
137
/** Get the music type matching the given device handle, or MT_AUTO if there is no match. */
138
static MusicType getMusicType(DeviceHandle handle);
140
/** Get the device description string matching the given device handle and the given type. */
141
static Common::String getDeviceString(DeviceHandle handle, DeviceStringType type);
144
// If detectDevice() detects MT32 and we have a preferred MT32 device
145
// we use this to force getMusicType() to return MT_MT32 so that we don't
146
// have to rely on the 'True Roland MT-32' config manager setting (since nobody
147
// would possibly think about activating 'True Roland MT-32' when he has set
148
// 'Music Driver' to '<default>')
149
static bool _forceTypeMT32;
152
virtual ~MidiDriver() { }
154
static const byte _mt32ToGm[128];
155
static const byte _gmToMt32[128];
158
* Error codes returned by open.
159
* Can be converted to a string with getErrorName().
162
MERR_CANNOT_CONNECT = 1,
163
// MERR_STREAMING_NOT_AVAILABLE = 2,
164
MERR_DEVICE_NOT_AVAILABLE = 3,
165
MERR_ALREADY_OPEN = 4
171
PROP_CHANNEL_MASK = 3
175
* Open the midi driver.
176
* @return 0 if successful, otherwise an error code.
178
virtual int open() = 0;
180
/** Close the midi driver. */
181
virtual void close() = 0;
184
* Output a packed midi command to the midi stream.
185
* The 'lowest' byte (i.e. b & 0xFF) is the status
186
* code, then come (if used) the first and second
189
virtual void send(uint32 b) = 0;
192
* Output a midi command to the midi stream. Convenience wrapper
193
* around the usual 'packed' send method.
195
* Do NOT use this for sysEx transmission; instead, use the sysEx()
198
void send(byte status, byte firstOp, byte secondOp) {
199
send(status | ((uint32)firstOp << 8) | ((uint32)secondOp << 16));
202
/** Get or set a property. */
203
virtual uint32 property(int prop, uint32 param) { return 0; }
205
/** Retrieve a string representation of an error code. */
206
static const char *getErrorName(int error_code);
208
// HIGH-LEVEL SEMANTIC METHODS
209
virtual void setPitchBendRange(byte channel, uint range) {
210
send(0xB0 | channel, 101, 0);
211
send(0xB0 | channel, 100, 0);
212
send(0xB0 | channel, 6, range);
213
send(0xB0 | channel, 38, 0);
214
send(0xB0 | channel, 101, 127);
215
send(0xB0 | channel, 100, 127);
219
* Send a Roland MT-32 reset sysEx to the midi device.
221
void sendMT32Reset();
224
* Send a General MIDI reset sysEx to the midi device.
229
* Transmit a sysEx to the midi device.
231
* The given msg MUST NOT contain the usual SysEx frame, i.e.
232
* do NOT include the leading 0xF0 and the trailing 0xF7.
234
* Furthermore, the maximal supported length of a SysEx
235
* is 264 bytes. Passing longer buffers can lead to
236
* undefined behavior (most likely, a crash).
238
virtual void sysEx(const byte *msg, uint16 length) { }
240
virtual void sysEx_customInstrument(byte channel, uint32 type, const byte *instr) { }
242
virtual void metaEvent(byte type, byte *data, uint16 length) { }
244
// Timing functions - MidiDriver now operates timers
245
virtual void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) = 0;
247
/** The time in microseconds between invocations of the timer callback. */
248
virtual uint32 getBaseTempo() = 0;
250
// Channel allocation functions
251
virtual MidiChannel *allocateChannel() = 0;
252
virtual MidiChannel *getPercussionChannel() = 0;
257
virtual ~MidiChannel() {}
259
virtual MidiDriver *device() = 0;
260
virtual byte getNumber() = 0;
261
virtual void release() = 0;
263
virtual void send(uint32 b) = 0; // 4-bit channel portion is ignored
266
virtual void noteOff(byte note) = 0;
267
virtual void noteOn(byte note, byte velocity) = 0;
268
virtual void programChange(byte program) = 0;
269
virtual void pitchBend(int16 bend) = 0; // -0x2000 to +0x1FFF
271
// Control Change messages
272
virtual void controlChange(byte control, byte value) = 0;
273
virtual void modulationWheel(byte value) { controlChange(1, value); }
274
virtual void volume(byte value) { controlChange(7, value); }
275
virtual void panPosition(byte value) { controlChange(10, value); }
276
virtual void pitchBendFactor(byte value) = 0;
277
virtual void detune(byte value) { controlChange(17, value); }
278
virtual void priority(byte value) { }
279
virtual void sustain(bool value) { controlChange(64, value ? 1 : 0); }
280
virtual void effectLevel(byte value) { controlChange(91, value); }
281
virtual void chorusLevel(byte value) { controlChange(93, value); }
282
virtual void allNotesOff() { controlChange(123, 0); }
285
virtual void sysEx_customInstrument(uint32 type, const byte *instr) = 0;