ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

mididrv.h

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #ifndef AUDIO_MIDIDRV_H
00024 #define AUDIO_MIDIDRV_H
00025 
00026 #include "common/scummsys.h"
00027 #include "common/str.h"
00028 #include "common/stream.h"
00029 #include "common/timer.h"
00030 #include "common/array.h"
00031 
00032 class MidiChannel;
00033 
00037 enum MusicType {
00038     MT_INVALID = -1,    // Invalid output
00039     MT_AUTO = 0,        // Auto
00040     MT_NULL,            // Null
00041     MT_PCSPK,           // PC Speaker
00042     MT_PCJR,            // PCjr
00043     MT_CMS,             // CMS
00044     MT_ADLIB,           // AdLib
00045     MT_C64,             // C64
00046     MT_AMIGA,           // Amiga
00047     MT_APPLEIIGS,       // Apple IIGS
00048     MT_TOWNS,           // FM-TOWNS
00049     MT_PC98,            // PC98
00050     MT_GM,              // General MIDI
00051     MT_MT32,            // MT-32
00052     MT_GS               // Roland GS
00053 };
00054 
00070 enum MidiDriverFlags {
00071     MDT_NONE        = 0,
00072     MDT_PCSPK       = 1 << 0,       // PC Speaker: Maps to MT_PCSPK and MT_PCJR
00073     MDT_CMS         = 1 << 1,       // Creative Music System / Gameblaster: Maps to MT_CMS
00074     MDT_PCJR        = 1 << 2,       // Tandy/PC Junior driver
00075     MDT_ADLIB       = 1 << 3,       // AdLib: Maps to MT_ADLIB
00076     MDT_C64         = 1 << 4,
00077     MDT_AMIGA       = 1 << 5,
00078     MDT_APPLEIIGS   = 1 << 6,
00079     MDT_TOWNS       = 1 << 7,       // FM-TOWNS: Maps to MT_TOWNS
00080     MDT_PC98        = 1 << 8,       // FM-TOWNS: Maps to MT_PC98
00081     MDT_MIDI        = 1 << 9,       // Real MIDI
00082     MDT_PREFER_MT32 = 1 << 10,      // MT-32 output is preferred
00083     MDT_PREFER_GM   = 1 << 11,      // GM output is preferred
00084     MDT_PREFER_FLUID= 1 << 12       // FluidSynth driver is preferred
00085 };
00086 
00090 class MidiDriver_BASE {
00091 public:
00092     MidiDriver_BASE();
00093 
00094     virtual ~MidiDriver_BASE();
00095 
00102     virtual void send(uint32 b) = 0;
00103 
00109     virtual void send(int8 source, uint32 b) { send(b); }
00110 
00118     void send(byte status, byte firstOp, byte secondOp);
00119     
00125     void send(int8 source, byte status, byte firstOp, byte secondOp);
00126 
00137     virtual void sysEx(const byte *msg, uint16 length) { }
00138 
00151     virtual uint16 sysExNoDelay(const byte *msg, uint16 length) { sysEx(msg, length); return 0; }
00152 
00153     // TODO: Document this.
00154     virtual void metaEvent(byte type, byte *data, uint16 length) { }
00155 
00161     virtual void metaEvent(int8 source, byte type, byte *data, uint16 length) { metaEvent(type, data, length); }
00162 protected:
00163 
00168     bool _midiDumpEnable;
00169 
00171     uint32 _prevMillis;
00172 
00174     Common::Array<byte> _midiDumpCache;
00175 
00177     void midiDumpInit();
00178 
00180     int midiDumpVarLength(const uint32 &delta);
00181 
00183     void midiDumpDelta();
00184 
00186     void midiDumpDo(uint32 b);
00187 
00189     void midiDumpSysEx(const byte *msg, uint16 length);
00190 
00192     void midiDumpFinish();
00193 
00194 };
00195 
00201 class MidiDriver : public MidiDriver_BASE {
00202 public:
00210     typedef uint32 DeviceHandle;
00211 
00212     enum DeviceStringType {
00213         kDriverName,
00214         kDriverId,
00215         kDeviceName,
00216         kDeviceId
00217     };
00218 
00219     static Common::String musicType2GUIO(uint32 musicType);
00220 
00222     static MidiDriver *createMidi(DeviceHandle handle);
00223 
00225     static DeviceHandle detectDevice(int flags);
00226 
00228     static DeviceHandle getDeviceHandle(const Common::String &identifier);
00229 
00231     static bool checkDevice(DeviceHandle handle);
00232 
00234     static MusicType getMusicType(DeviceHandle handle);
00235 
00237     static Common::String getDeviceString(DeviceHandle handle, DeviceStringType type);
00238 
00240     void midiDriverCommonSend(uint32 b);
00241 
00243     void midiDriverCommonSysEx(const byte *msg, uint16 length);
00244 
00245 protected:
00246     // True if stereo panning should be reversed.
00247     bool _reversePanning;
00248     // True if GS percussion channel volume should be scaled to match MT-32 volume.
00249     bool _scaleGSPercussionVolumeToMT32;
00250     // The currently selected GS instrument bank / variation for each channel.
00251     byte _gsBank[16];
00252 
00253 private:
00254     // If detectDevice() detects MT32 and we have a preferred MT32 device
00255     // we use this to force getMusicType() to return MT_MT32 so that we don't
00256     // have to rely on the 'True Roland MT-32' config manager setting (since nobody
00257     // would possibly think about activating 'True Roland MT-32' when he has set
00258     // 'Music Driver' to '<default>')
00259     static bool _forceTypeMT32;
00260 
00261 public:
00262     MidiDriver() : _reversePanning(false),
00263                     _scaleGSPercussionVolumeToMT32(false) {
00264         memset(_gsBank, 0, sizeof(_gsBank));
00265     }
00266     virtual ~MidiDriver() { }
00267 
00268     static const byte _mt32ToGm[128];
00269     static const byte _gmToMt32[128];
00270     static const byte _mt32DefaultInstruments[8];
00271     static const byte _mt32DefaultPanning[8];
00272     // Map for correcting Roland GS drumkit numbers.
00273     static const uint8 _gsDrumkitFallbackMap[128];
00274 
00279     enum {
00280         MERR_CANNOT_CONNECT = 1,
00281 //      MERR_STREAMING_NOT_AVAILABLE = 2,
00282         MERR_DEVICE_NOT_AVAILABLE = 3,
00283         MERR_ALREADY_OPEN = 4
00284     };
00285 
00286     enum {
00287 //      PROP_TIMEDIV = 1,
00288         PROP_OLD_ADLIB = 2,
00289         PROP_CHANNEL_MASK = 3,
00290         // HACK: Not so nice, but our SCUMM AdLib code is in audio/
00291         PROP_SCUMM_OPL3 = 4
00292     };
00293 
00298     virtual int open() = 0;
00299 
00303     virtual bool isOpen() const = 0;
00304 
00306     virtual void close() = 0;
00307 
00309     virtual uint32 property(int prop, uint32 param) { return 0; }
00310 
00312     static const char *getErrorName(int error_code);
00313 
00314     // HIGH-LEVEL SEMANTIC METHODS
00315     virtual void setPitchBendRange(byte channel, uint range) {
00316         send(0xB0 | channel, 101, 0);
00317         send(0xB0 | channel, 100, 0);
00318         send(0xB0 | channel,   6, range);
00319         send(0xB0 | channel,  38, 0);
00320         send(0xB0 | channel, 101, 127);
00321         send(0xB0 | channel, 100, 127);
00322     }
00323 
00329     void initMT32(bool initForGM);
00330 
00334     void sendMT32Reset();
00335 
00344     void initGM(bool initForMT32, bool enableGS);
00345 
00349     void sendGMReset();
00350 
00351     virtual void sysEx_customInstrument(byte channel, uint32 type, const byte *instr) { }
00352 
00353     // Timing functions - MidiDriver now operates timers
00354     virtual void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) = 0;
00355 
00357     virtual uint32 getBaseTempo() = 0;
00358 
00359     // Channel allocation functions
00360     virtual MidiChannel *allocateChannel() = 0;
00361     virtual MidiChannel *getPercussionChannel() = 0;
00362 
00363     // Allow an engine to supply its own soundFont data. This stream will be destroyed after use.
00364     virtual void setEngineSoundFont(Common::SeekableReadStream *soundFontData) { }
00365 
00366     // Does this driver accept soundFont data?
00367     virtual bool acceptsSoundFontData() { return false; }
00368 
00369 protected:
00379     byte correctInstrumentBank(byte outputChannel, byte patchId);
00380 };
00381 
00382 class MidiChannel {
00383 public:
00384     virtual ~MidiChannel() {}
00385 
00386     virtual MidiDriver *device() = 0;
00387     virtual byte getNumber() = 0;
00388     virtual void release() = 0;
00389 
00390     virtual void send(uint32 b) = 0; // 4-bit channel portion is ignored
00391 
00392     // Regular messages
00393     virtual void noteOff(byte note) = 0;
00394     virtual void noteOn(byte note, byte velocity) = 0;
00395     virtual void programChange(byte program) = 0;
00396     virtual void pitchBend(int16 bend) = 0; // -0x2000 to +0x1FFF
00397 
00398     // Control Change messages
00399     virtual void controlChange(byte control, byte value) = 0;
00400     virtual void modulationWheel(byte value) { controlChange(1, value); }
00401     virtual void volume(byte value) { controlChange(7, value); }
00402     virtual void panPosition(byte value) { controlChange(10, value); }
00403     virtual void pitchBendFactor(byte value) = 0;
00404     virtual void transpose(int8 value) {}
00405     virtual void detune(byte value) { controlChange(17, value); }
00406     virtual void priority(byte value) { }
00407     virtual void sustain(bool value) { controlChange(64, value ? 1 : 0); }
00408     virtual void effectLevel(byte value) { controlChange(91, value); }
00409     virtual void chorusLevel(byte value) { controlChange(93, value); }
00410     virtual void allNotesOff() { controlChange(123, 0); }
00411 
00412     // SysEx messages
00413     virtual void sysEx_customInstrument(uint32 type, const byte *instr) = 0;
00414 };
00415 
00416 #endif


Generated on Sat Jul 4 2020 05:01:03 for ResidualVM by doxygen 1.7.1
curved edge   curved edge