AUDIO: Added dump-midi mechanism
This mechanism is enabled by '--dump-midi' command line parameter. The midi events are printed to screen, and dumped to 'dump.mid' file.
This commit is contained in:
parent
1fb3d61b56
commit
3b4810aab4
22 changed files with 243 additions and 23 deletions
|
@ -1428,6 +1428,8 @@ arguments -- see the next section.
|
|||
supported by some MIDI drivers)
|
||||
--multi-midi Enable combination of AdLib and native MIDI
|
||||
--native-mt32 True Roland MT-32 (disable GM emulation)
|
||||
--dump-midi Dumps MIDI events to 'dump.mid', until quitting from game
|
||||
(if file already exists, it will be overwritten)
|
||||
--enable-gs Enable Roland GS mode for MIDI playback
|
||||
--output-rate=RATE Select output sample rate in Hz (e.g. 22050)
|
||||
--opl-driver=DRIVER Select AdLib (OPL) emulator (db, mame, nuked)
|
||||
|
|
|
@ -935,7 +935,7 @@ public:
|
|||
|
||||
int open();
|
||||
void close();
|
||||
void send(uint32 b);
|
||||
void send(uint32 b) override;
|
||||
void send(byte channel, uint32 b); // Supports higher than channel 15
|
||||
uint32 property(int prop, uint32 param);
|
||||
bool isOpen() const { return _isOpen; }
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "common/textconsole.h"
|
||||
#include "common/translation.h"
|
||||
#include "common/util.h"
|
||||
#include "common/file.h"
|
||||
#include "gui/message.h"
|
||||
#include "audio/mididrv.h"
|
||||
#include "audio/musicplugin.h"
|
||||
|
@ -441,3 +442,128 @@ void MidiDriver::sendGMReset() {
|
|||
sysEx(resetSysEx, sizeof(resetSysEx));
|
||||
g_system->delayMillis(100);
|
||||
}
|
||||
|
||||
|
||||
void MidiDriver_BASE::midiDumpInit() {
|
||||
g_system->displayMessageOnOSD(_("Starting MIDI dump"));
|
||||
_midiDumpCache.clear();
|
||||
_prevMillis = g_system->getMillis(true);
|
||||
}
|
||||
|
||||
int MidiDriver_BASE::midiDumpVarLength(const uint32 &delta) {
|
||||
// MIDI file format has a very strange representation - "Variable Length Values"
|
||||
// we're using only *7* bits of each byte for the data
|
||||
// the MSB bit is 1 for all bytes, except the last one
|
||||
if (delta <= 127) {
|
||||
// "Variable Length Values" of 1 byte
|
||||
debugN("0x%02x", delta);
|
||||
_midiDumpCache.push_back(delta);
|
||||
return 1;
|
||||
} else {
|
||||
// "Variable Length Values" of 2 bytes
|
||||
// theoretically, "Variable Length Values" can have more than 2 bytes, but it won't happen in our use case
|
||||
byte msb = delta / 128;
|
||||
msb |= 0x80;
|
||||
byte lsb = delta % 128;
|
||||
debugN("0x%02x,0x%02x", msb, lsb);
|
||||
_midiDumpCache.push_back(msb);
|
||||
_midiDumpCache.push_back(lsb);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
void MidiDriver_BASE::midiDumpDelta() {
|
||||
uint32 millis = g_system->getMillis(true);
|
||||
uint32 delta = millis - _prevMillis;
|
||||
_prevMillis = millis;
|
||||
|
||||
debugN("MIDI : delta(");
|
||||
int varLength = midiDumpVarLength(delta);
|
||||
if (varLength == 1)
|
||||
debugN("),\t ");
|
||||
else
|
||||
debugN("), ");
|
||||
}
|
||||
|
||||
void MidiDriver_BASE::midiDumpDo(uint32 b) {
|
||||
const byte status = b & 0xff;
|
||||
const byte firstOp = (b >> 8) & 0xff;
|
||||
const byte secondOp = (b >> 16) & 0xff;
|
||||
|
||||
midiDumpDelta();
|
||||
debugN("message(0x%02x 0x%02x", status, firstOp);
|
||||
|
||||
_midiDumpCache.push_back(status);
|
||||
_midiDumpCache.push_back(firstOp);
|
||||
|
||||
if (status < 0xc0 || status > 0xdf) {
|
||||
_midiDumpCache.push_back(secondOp);
|
||||
debug(" 0x%02x)", secondOp);
|
||||
} else
|
||||
debug(")");
|
||||
}
|
||||
|
||||
void MidiDriver_BASE::midiDumpSysEx(const byte *msg, uint16 length) {
|
||||
midiDumpDelta();
|
||||
_midiDumpCache.push_back(0xf0);
|
||||
debugN("0xf0, length(");
|
||||
midiDumpVarLength(length + 1); // +1 because of closing 0xf7
|
||||
debugN("), sysex[");
|
||||
for (int i = 0; i < length; i++) {
|
||||
debugN("0x%x, ", msg[i]);
|
||||
_midiDumpCache.push_back(msg[i]);
|
||||
}
|
||||
debug("0xf7]\t\t");
|
||||
_midiDumpCache.push_back(0xf7);
|
||||
}
|
||||
|
||||
|
||||
void MidiDriver_BASE::midiDumpFinish() {
|
||||
Common::DumpFile *midiDumpFile = new Common::DumpFile();
|
||||
midiDumpFile->open("dump.mid");
|
||||
midiDumpFile->write("MThd\0\0\0\x6\0\x1\0\x2", 12); // standard MIDI file header, with two tracks
|
||||
midiDumpFile->write("\x1\xf4", 2); // division - 500 ticks per beat, i.e. a quarter note. Each tick is 1ms
|
||||
midiDumpFile->write("MTrk", 4); // start of first track - doesn't contain real data, it's just common practice to use two tracks
|
||||
midiDumpFile->writeUint32BE(4); // first track size
|
||||
midiDumpFile->write("\0\xff\x2f\0", 4); // meta event - end of track
|
||||
midiDumpFile->write("MTrk", 4); // start of second track
|
||||
midiDumpFile->writeUint32BE(_midiDumpCache.size() + 4); // track size (+4 because of the 'end of track' event)
|
||||
midiDumpFile->write(_midiDumpCache.data(), _midiDumpCache.size());
|
||||
midiDumpFile->write("\0\xff\x2f\0", 4); // meta event - end of track
|
||||
midiDumpFile->finalize();
|
||||
midiDumpFile->close();
|
||||
const char msg[] = "Ending MIDI dump, created 'dump.mid'";
|
||||
g_system->displayMessageOnOSD(_(msg)); //TODO: why it doesn't appear?
|
||||
debug(_(msg));
|
||||
}
|
||||
|
||||
MidiDriver_BASE::MidiDriver_BASE() {
|
||||
_midiDumpEnable = ConfMan.getBool("dump_midi");
|
||||
if (_midiDumpEnable) {
|
||||
midiDumpInit();
|
||||
}
|
||||
}
|
||||
|
||||
MidiDriver_BASE::~MidiDriver_BASE() {
|
||||
if (_midiDumpEnable && !_midiDumpCache.empty()) {
|
||||
midiDumpFinish();
|
||||
}
|
||||
}
|
||||
|
||||
void MidiDriver_BASE::send(byte status, byte firstOp, byte secondOp) {
|
||||
send(status | ((uint32)firstOp << 8) | ((uint32)secondOp << 16));
|
||||
}
|
||||
|
||||
void MidiDriver::midiDriverCommonSend(uint32 b) {
|
||||
if (_midiDumpEnable) {
|
||||
midiDumpDo(b);
|
||||
}
|
||||
}
|
||||
|
||||
void MidiDriver::midiDriverCommonSysEx(const byte *msg, uint16 length) {
|
||||
if (_midiDumpEnable) {
|
||||
midiDumpSysEx(msg, length);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "common/scummsys.h"
|
||||
#include "common/str.h"
|
||||
#include "common/timer.h"
|
||||
#include "common/array.h"
|
||||
|
||||
class MidiChannel;
|
||||
|
||||
|
@ -86,7 +87,9 @@ enum MidiDriverFlags {
|
|||
*/
|
||||
class MidiDriver_BASE {
|
||||
public:
|
||||
virtual ~MidiDriver_BASE() { }
|
||||
MidiDriver_BASE();
|
||||
|
||||
virtual ~MidiDriver_BASE();
|
||||
|
||||
/**
|
||||
* Output a packed midi command to the midi stream.
|
||||
|
@ -96,6 +99,7 @@ public:
|
|||
*/
|
||||
virtual void send(uint32 b) = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Output a midi command to the midi stream. Convenience wrapper
|
||||
* around the usual 'packed' send method.
|
||||
|
@ -103,10 +107,8 @@ public:
|
|||
* Do NOT use this for sysEx transmission; instead, use the sysEx()
|
||||
* method below.
|
||||
*/
|
||||
void send(byte status, byte firstOp, byte secondOp) {
|
||||
send(status | ((uint32)firstOp << 8) | ((uint32)secondOp << 16));
|
||||
}
|
||||
|
||||
void send(byte status, byte firstOp, byte secondOp);
|
||||
|
||||
/**
|
||||
* Transmit a sysEx to the midi device.
|
||||
*
|
||||
|
@ -121,6 +123,39 @@ public:
|
|||
|
||||
// TODO: Document this.
|
||||
virtual void metaEvent(byte type, byte *data, uint16 length) { }
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Enables midi dumping to a 'dump.mid' file and to debug messages on screen
|
||||
* It's set by '--dump-midi' command line parameter
|
||||
*/
|
||||
bool _midiDumpEnable;
|
||||
|
||||
/** Used for MIDI dumping delta calculation */
|
||||
uint32 _prevMillis;
|
||||
|
||||
/** Stores all MIDI events, will be written to disk after an engine quits */
|
||||
Common::Array<byte> _midiDumpCache;
|
||||
|
||||
/** Initialize midi dumping mechanism, called only if enabled */
|
||||
void midiDumpInit();
|
||||
|
||||
/** Handles MIDI file variable length dumping */
|
||||
int midiDumpVarLength(const uint32 &delta);
|
||||
|
||||
/** Handles MIDI file time delta dumping */
|
||||
void midiDumpDelta();
|
||||
|
||||
/** Performs dumping of MIDI commands, called only if enabled */
|
||||
void midiDumpDo(uint32 b);
|
||||
|
||||
/** Performs dumping of MIDI SysEx commands, called only if enabled */
|
||||
void midiDumpSysEx(const byte *msg, uint16 length);
|
||||
|
||||
/** Writes the captured MIDI events to disk, called only if enabled */
|
||||
void midiDumpFinish();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -166,6 +201,13 @@ public:
|
|||
/** Get the device description string matching the given device handle and the given type. */
|
||||
static Common::String getDeviceString(DeviceHandle handle, DeviceStringType type);
|
||||
|
||||
/** Common operations to be done by all drivers on start of send */
|
||||
void midiDriverCommonSend(uint32 b);
|
||||
|
||||
/** Common operations to be done by all drivers on start of sysEx */
|
||||
void midiDriverCommonSysEx(const byte *msg, uint16 length);
|
||||
|
||||
|
||||
private:
|
||||
// If detectDevice() detects MT32 and we have a preferred MT32 device
|
||||
// we use this to force getMusicType() to return MT_MT32 so that we don't
|
||||
|
|
|
@ -115,7 +115,7 @@ public:
|
|||
bool hasNativeMT32() const { return _nativeMT32; }
|
||||
|
||||
// MidiDriver_BASE implementation
|
||||
virtual void send(uint32 b);
|
||||
virtual void send(uint32 b) override;
|
||||
virtual void metaEvent(byte type, byte *data, uint16 length);
|
||||
|
||||
protected:
|
||||
|
|
|
@ -123,7 +123,7 @@ public:
|
|||
// MidiDriver
|
||||
int open();
|
||||
void close();
|
||||
void send(uint32 b);
|
||||
void send(uint32 b) override;
|
||||
MidiChannel *allocateChannel() { return NULL; }
|
||||
MidiChannel *getPercussionChannel() { return NULL; }
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ public:
|
|||
void close();
|
||||
bool isOpen() const { return _isOpen; }
|
||||
|
||||
void send(uint32 b);
|
||||
void send(uint32 b) override;
|
||||
|
||||
MidiChannel *allocateChannel() {
|
||||
if (_driver)
|
||||
|
|
|
@ -70,7 +70,7 @@ public:
|
|||
virtual int open();
|
||||
virtual bool isOpen() const;
|
||||
virtual void close();
|
||||
virtual void send(uint32 b);
|
||||
virtual void send(uint32 b) override;
|
||||
virtual void sysEx(const byte *msg, uint16 length);
|
||||
virtual void setTimerCallback(void *timerParam,
|
||||
Common::TimerManager::TimerProc timerProc);
|
||||
|
|
|
@ -64,7 +64,7 @@ public:
|
|||
|
||||
int open();
|
||||
void close();
|
||||
void send(uint32 b);
|
||||
void send(uint32 b) override;
|
||||
|
||||
MidiChannel *allocateChannel();
|
||||
MidiChannel *getPercussionChannel();
|
||||
|
@ -227,6 +227,8 @@ void MidiDriver_FluidSynth::close() {
|
|||
}
|
||||
|
||||
void MidiDriver_FluidSynth::send(uint32 b) {
|
||||
midiDriverCommonSend(b);
|
||||
|
||||
//byte param3 = (byte) ((b >> 24) & 0xFF);
|
||||
uint param2 = (byte) ((b >> 16) & 0xFF);
|
||||
uint param1 = (byte) ((b >> 8) & 0xFF);
|
||||
|
|
|
@ -122,7 +122,7 @@ public:
|
|||
|
||||
int open();
|
||||
void close();
|
||||
void send(uint32 b);
|
||||
void send(uint32 b) override;
|
||||
void setPitchBendRange(byte channel, uint range);
|
||||
void sysEx(const byte *msg, uint16 length);
|
||||
|
||||
|
@ -227,6 +227,8 @@ int MidiDriver_MT32::open() {
|
|||
}
|
||||
|
||||
void MidiDriver_MT32::send(uint32 b) {
|
||||
midiDriverCommonSend(b);
|
||||
|
||||
Common::StackLock lock(_mutex);
|
||||
_service.playMsg(b);
|
||||
}
|
||||
|
@ -243,6 +245,7 @@ void MidiDriver_MT32::setPitchBendRange(byte channel, uint range) {
|
|||
}
|
||||
|
||||
void MidiDriver_MT32::sysEx(const byte *msg, uint16 length) {
|
||||
midiDriverCommonSysEx(msg, length);
|
||||
if (msg[0] == 0xf0) {
|
||||
Common::StackLock lock(_mutex);
|
||||
_service.playSysex(msg, length);
|
||||
|
|
|
@ -73,7 +73,7 @@ public:
|
|||
int open();
|
||||
bool isOpen() const { return _isOpen; }
|
||||
void close();
|
||||
void send(uint32 b);
|
||||
void send(uint32 b) override;
|
||||
void sysEx(const byte *msg, uint16 length);
|
||||
|
||||
private:
|
||||
|
@ -186,6 +186,8 @@ void MidiDriver_ALSA::send(uint32 b) {
|
|||
return;
|
||||
}
|
||||
|
||||
midiDriverCommonSend(b);
|
||||
|
||||
unsigned int midiCmd[4];
|
||||
ev.type = SND_SEQ_EVENT_OSS;
|
||||
|
||||
|
@ -268,6 +270,8 @@ void MidiDriver_ALSA::sysEx(const byte *msg, uint16 length) {
|
|||
|
||||
assert(length + 2 <= ARRAYSIZE(buf));
|
||||
|
||||
midiDriverCommonSysEx(msg, length);
|
||||
|
||||
// Add SysEx frame
|
||||
buf[0] = 0xF0;
|
||||
memcpy(buf + 1, msg, length);
|
||||
|
|
|
@ -50,7 +50,7 @@ public:
|
|||
int open();
|
||||
bool isOpen() const { return _isOpen; }
|
||||
void close();
|
||||
void send(uint32 b);
|
||||
void send(uint32 b) override;
|
||||
void sysEx(const byte *msg, uint16 length);
|
||||
|
||||
private:
|
||||
|
@ -122,6 +122,8 @@ void MidiDriver_CAMD::send(uint32 b) {
|
|||
return;
|
||||
}
|
||||
|
||||
midiDriverCommonSend(b);
|
||||
|
||||
ULONG data = READ_LE_UINT32(&b);
|
||||
_ICamd->PutMidi(_midi_link, data);
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ public:
|
|||
int open();
|
||||
bool isOpen() const { return _auGraph != 0; }
|
||||
void close();
|
||||
void send(uint32 b);
|
||||
void send(uint32 b) override;
|
||||
void sysEx(const byte *msg, uint16 length);
|
||||
|
||||
private:
|
||||
|
@ -280,6 +280,8 @@ void MidiDriver_CORE::close() {
|
|||
void MidiDriver_CORE::send(uint32 b) {
|
||||
assert(isOpen());
|
||||
|
||||
midiDriverCommonSend(b);
|
||||
|
||||
byte status_byte = (b & 0x000000FF);
|
||||
byte first_byte = (b & 0x0000FF00) >> 8;
|
||||
byte second_byte = (b & 0x00FF0000) >> 16;
|
||||
|
|
|
@ -58,7 +58,7 @@ public:
|
|||
int open();
|
||||
bool isOpen() const { return mOutPort != 0 && mDest != 0; }
|
||||
void close();
|
||||
void send(uint32 b);
|
||||
void send(uint32 b) override;
|
||||
void sysEx(const byte *msg, uint16 length);
|
||||
|
||||
private:
|
||||
|
@ -118,6 +118,8 @@ void MidiDriver_CoreMIDI::close() {
|
|||
void MidiDriver_CoreMIDI::send(uint32 b) {
|
||||
assert(isOpen());
|
||||
|
||||
midiDriverCommonSend(b);
|
||||
|
||||
// Extract the MIDI data
|
||||
byte status_byte = (b & 0x000000FF);
|
||||
byte first_byte = (b & 0x0000FF00) >> 8;
|
||||
|
|
|
@ -58,7 +58,7 @@ public:
|
|||
int open();
|
||||
bool isOpen() const { return _isOpen; }
|
||||
void close();
|
||||
void send(uint32 b);
|
||||
void send(uint32 b) override;
|
||||
void sysEx(const byte *msg, uint16 length);
|
||||
|
||||
private:
|
||||
|
@ -135,6 +135,8 @@ void MidiDriver_DMEDIA::close() {
|
|||
}
|
||||
|
||||
void MidiDriver_DMEDIA::send(uint32 b) {
|
||||
midiDriverCommonSend(b);
|
||||
|
||||
MDevent event;
|
||||
byte status_byte = (b & 0x000000FF);
|
||||
byte first_byte = (b & 0x0000FF00) >> 8;
|
||||
|
@ -177,6 +179,8 @@ void MidiDriver_DMEDIA::sysEx (const byte *msg, uint16 length) {
|
|||
|
||||
assert(length + 2 <= 256);
|
||||
|
||||
midiDriverCommonSysEx(msg, length);
|
||||
|
||||
memcpy(buf, msg, length);
|
||||
buf[length] = MD_EOX;
|
||||
event.sysexmsg = buf;
|
||||
|
|
|
@ -57,7 +57,7 @@ public:
|
|||
int open();
|
||||
bool isOpen() const { return _isOpen; }
|
||||
void close();
|
||||
void send(uint32 b);
|
||||
void send(uint32 b) override;
|
||||
void sysEx(const byte *msg, uint16 length);
|
||||
|
||||
private:
|
||||
|
@ -109,6 +109,8 @@ void MidiDriver_SEQ::close() {
|
|||
}
|
||||
|
||||
void MidiDriver_SEQ::send(uint32 b) {
|
||||
midiDriverCommonSend(b);
|
||||
|
||||
unsigned char buf[256];
|
||||
int position = 0;
|
||||
|
||||
|
@ -157,6 +159,8 @@ void MidiDriver_SEQ::sysEx(const byte *msg, uint16 length) {
|
|||
|
||||
assert(length + 2 <= 266);
|
||||
|
||||
midiDriverCommonSysEx(msg, length);
|
||||
|
||||
buf[position++] = SEQ_MIDIPUTC;
|
||||
buf[position++] = 0xF0;
|
||||
buf[position++] = _device_num;
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
int open();
|
||||
bool isOpen() const { return hdl != NULL; }
|
||||
void close();
|
||||
void send(uint32 b);
|
||||
void send(uint32 b) override;
|
||||
void sysEx(const byte *msg, uint16 length);
|
||||
|
||||
private:
|
||||
|
@ -80,6 +80,8 @@ void MidiDriver_Sndio::send(uint32 b) {
|
|||
unsigned char buf[4];
|
||||
unsigned int len;
|
||||
|
||||
midiDriverCommonSend(b);
|
||||
|
||||
if (!hdl)
|
||||
return;
|
||||
buf[0] = b & 0xff;
|
||||
|
@ -107,6 +109,8 @@ void MidiDriver_Sndio::sysEx(const byte *msg, uint16 length) {
|
|||
|
||||
assert(length + 2 <= ARRAYSIZE(buf));
|
||||
|
||||
midiDriverCommonSysEx(msg, length);
|
||||
|
||||
// Add SysEx frame
|
||||
buf[0] = 0xF0;
|
||||
memcpy(buf + 1, msg, length);
|
||||
|
|
|
@ -51,7 +51,7 @@ public:
|
|||
int open();
|
||||
bool isOpen() const { return _isOpen; }
|
||||
void close();
|
||||
void send(uint32 b);
|
||||
void send(uint32 b) override;
|
||||
void sysEx(const byte *msg, uint16 length);
|
||||
|
||||
private:
|
||||
|
@ -72,6 +72,7 @@ void MidiDriver_STMIDI::close() {
|
|||
}
|
||||
|
||||
void MidiDriver_STMIDI::send(uint32 b) {
|
||||
midiDriverCommonSend(b);
|
||||
|
||||
byte status_byte = (b & 0x000000FF);
|
||||
byte first_byte = (b & 0x0000FF00) >> 8;
|
||||
|
@ -109,6 +110,8 @@ void MidiDriver_STMIDI::sysEx (const byte *msg, uint16 length) {
|
|||
return;
|
||||
}
|
||||
|
||||
midiDriverCommonSysEx(msg, length);
|
||||
|
||||
const byte *chr = msg;
|
||||
warning("Sending SysEx Message");
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ public:
|
|||
int open();
|
||||
bool isOpen() const { return _isOpen; }
|
||||
void close();
|
||||
void send(uint32 b);
|
||||
void send(uint32 b) override;
|
||||
void sysEx(const byte *msg, uint16 length);
|
||||
|
||||
private:
|
||||
|
@ -445,6 +445,8 @@ void MidiDriver_TIMIDITY::send(uint32 b) {
|
|||
unsigned char buf[256];
|
||||
int position = 0;
|
||||
|
||||
midiDriverCommonSend(b);
|
||||
|
||||
switch (b & 0xF0) {
|
||||
case 0x80:
|
||||
case 0x90:
|
||||
|
@ -491,6 +493,8 @@ void MidiDriver_TIMIDITY::sysEx(const byte *msg, uint16 length) {
|
|||
|
||||
assert(length + 2 <= 266);
|
||||
|
||||
midiDriverCommonSysEx(msg, length);
|
||||
|
||||
buf[position++] = SEQ_MIDIPUTC;
|
||||
buf[position++] = 0xF0;
|
||||
buf[position++] = _device_num;
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include "common/translation.h"
|
||||
#include "common/textconsole.h"
|
||||
#include "common/error.h"
|
||||
|
||||
#include <mmsystem.h>
|
||||
|
||||
////////////////////////////////////////
|
||||
|
@ -61,7 +60,7 @@ public:
|
|||
int open();
|
||||
bool isOpen() const { return _isOpen; }
|
||||
void close();
|
||||
void send(uint32 b);
|
||||
void send(uint32 b) override;
|
||||
void sysEx(const byte *msg, uint16 length);
|
||||
};
|
||||
|
||||
|
@ -94,6 +93,8 @@ void MidiDriver_WIN::close() {
|
|||
void MidiDriver_WIN::send(uint32 b) {
|
||||
assert(_isOpen);
|
||||
|
||||
midiDriverCommonSend(b);
|
||||
|
||||
union {
|
||||
DWORD dwData;
|
||||
BYTE bData[4];
|
||||
|
@ -107,6 +108,7 @@ void MidiDriver_WIN::send(uint32 b) {
|
|||
check_error(midiOutShortMsg(_mo, u.dwData));
|
||||
}
|
||||
|
||||
|
||||
void MidiDriver_WIN::sysEx(const byte *msg, uint16 length) {
|
||||
if (!_isOpen)
|
||||
return;
|
||||
|
@ -118,6 +120,8 @@ void MidiDriver_WIN::sysEx(const byte *msg, uint16 length) {
|
|||
|
||||
assert(length+2 <= 266);
|
||||
|
||||
midiDriverCommonSysEx(msg, length);
|
||||
|
||||
midiOutUnprepareHeader(_mo, &_streamHeader, sizeof(_streamHeader));
|
||||
|
||||
// Add SysEx frame
|
||||
|
|
|
@ -131,6 +131,8 @@ static const char HELP_STRING[] =
|
|||
" supported by some MIDI drivers)\n"
|
||||
" --multi-midi Enable combination AdLib and native MIDI\n"
|
||||
" --native-mt32 True Roland MT-32 (disable GM emulation)\n"
|
||||
" --dump-midi Dumps MIDI events to 'dump.mid', until quitting from game\n"
|
||||
" (if file already exists, it will be overwritten)\n"
|
||||
" --enable-gs Enable Roland GS mode for MIDI playback\n"
|
||||
" --output-rate=RATE Select output sample rate in Hz (e.g. 22050)\n"
|
||||
" --opl-driver=DRIVER Select AdLib (OPL) emulator (db, mame"
|
||||
|
@ -233,6 +235,7 @@ void registerDefaults() {
|
|||
|
||||
ConfMan.registerDefault("multi_midi", false);
|
||||
ConfMan.registerDefault("native_mt32", false);
|
||||
ConfMan.registerDefault("dump_midi", false);
|
||||
ConfMan.registerDefault("enable_gs", false);
|
||||
ConfMan.registerDefault("midi_gain", 100);
|
||||
|
||||
|
@ -654,6 +657,9 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
|
|||
DO_LONG_OPTION_BOOL("native-mt32")
|
||||
END_OPTION
|
||||
|
||||
DO_LONG_OPTION_BOOL("dump-midi")
|
||||
END_OPTION
|
||||
|
||||
DO_LONG_OPTION_BOOL("enable-gs")
|
||||
END_OPTION
|
||||
|
||||
|
|
|
@ -449,6 +449,12 @@ extern "C" int scummvm_main(int argc, const char * const argv[]) {
|
|||
return res.getCode();
|
||||
}
|
||||
|
||||
if (settings.contains("dump-midi")) {
|
||||
// Store this command line setting in ConfMan, since all transient settings are destroyed
|
||||
ConfMan.registerDefault("dump_midi", true);
|
||||
}
|
||||
|
||||
|
||||
// Init the backend. Must take place after all config data (including
|
||||
// the command line params) was read.
|
||||
system.initBackend();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue