AUDIO: Add pure virtual MidiDriver::isOpen() method

This in turn enables modifying MidiDriver_MPU401::close() to allow
it to be called on a midi driver that has not yet been opened.

The specific issue that triggered me to make these changes was a
crash-upon-quit in HUGO, caused by it instantiating a midi driver,
then encountering an error (missing hugo.dat) *before* having
opened the new midi driver; the general cleanup code then tries
to close the (not yet opened) midi driver -> kaboom

Also fixed some engines which were leaking MidiDriver instances.
This commit is contained in:
Max Horn 2011-03-21 15:42:17 +01:00
parent 92716d71ed
commit 8982fff1b7
43 changed files with 175 additions and 65 deletions

View file

@ -182,6 +182,11 @@ public:
*/ */
virtual int open() = 0; virtual int open() = 0;
/**
* Check whether the midi driver has already been opened.
*/
virtual bool isOpen() const = 0;
/** Close the midi driver. */ /** Close the midi driver. */
virtual void close() = 0; virtual void close() = 0;

View file

@ -105,11 +105,14 @@ MidiDriver_MPU401::~MidiDriver_MPU401() {
} }
void MidiDriver_MPU401::close() { void MidiDriver_MPU401::close() {
if (_timer_proc) if (_timer_proc) {
g_system->getTimerManager()->removeTimerProc(_timer_proc); g_system->getTimerManager()->removeTimerProc(_timer_proc);
_timer_proc = 0; _timer_proc = 0;
for (int i = 0; i < 16; ++i) }
send(0x7B << 8 | 0xB0 | i); if (isOpen()) {
for (int i = 0; i < 16; ++i)
send(0x7B << 8 | 0xB0 | i);
}
} }
uint32 MidiDriver_MPU401::property(int prop, uint32 param) { uint32 MidiDriver_MPU401::property(int prop, uint32 param) {

View file

@ -33,6 +33,7 @@
class MidiDriver_NULL : public MidiDriver_MPU401 { class MidiDriver_NULL : public MidiDriver_MPU401 {
public: public:
int open() { return 0; } int open() { return 0; }
bool isOpen() const { return true; }
void send(uint32 b) { } void send(uint32 b) { }
}; };

View file

@ -118,7 +118,7 @@ public:
byte getNumber() { return _channel; } byte getNumber() { return _channel; }
void release() { _allocated = false; } void release() { _allocated = false; }
void send (uint32 b); void send(uint32 b);
// Regular messages // Regular messages
void noteOff(byte note); void noteOff(byte note);

View file

@ -76,6 +76,8 @@ public:
return 0; return 0;
} }
bool isOpen() const { return _isOpen; }
virtual void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) { virtual void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) {
_timerProc = timer_proc; _timerProc = timer_proc;
_timerParam = timer_param; _timerParam = timer_param;

View file

@ -71,6 +71,7 @@ class MidiDriver_ALSA : public MidiDriver_MPU401 {
public: public:
MidiDriver_ALSA(int client, int port); MidiDriver_ALSA(int client, int port);
int open(); int open();
bool isOpen() const { return _isOpen; }
void close(); void close();
void send(uint32 b); void send(uint32 b);
void sysEx(const byte *msg, uint16 length); void sysEx(const byte *msg, uint16 length);

View file

@ -46,6 +46,7 @@ class MidiDriver_CAMD : public MidiDriver_MPU401 {
public: public:
MidiDriver_CAMD(); MidiDriver_CAMD();
int open(); int open();
bool isOpen() const { return _isOpen; }
void close(); void close();
void send(uint32 b); void send(uint32 b);
void sysEx(const byte *msg, uint16 length); void sysEx(const byte *msg, uint16 length);

View file

@ -72,7 +72,9 @@ do { \
class MidiDriver_CORE : public MidiDriver_MPU401 { class MidiDriver_CORE : public MidiDriver_MPU401 {
public: public:
MidiDriver_CORE(); MidiDriver_CORE();
~MidiDriver_CORE();
int open(); int open();
bool isOpen() const { return _auGraph != 0; }
void close(); void close();
void send(uint32 b); void send(uint32 b);
void sysEx(const byte *msg, uint16 length); void sysEx(const byte *msg, uint16 length);
@ -86,10 +88,18 @@ MidiDriver_CORE::MidiDriver_CORE()
: _auGraph(0) { : _auGraph(0) {
} }
MidiDriver_CORE::~MidiDriver_CORE() {
if (_auGraph) {
AUGraphStop(_auGraph);
DisposeAUGraph(_auGraph);
_auGraph = 0;
}
}
int MidiDriver_CORE::open() { int MidiDriver_CORE::open() {
OSStatus err = 0; OSStatus err = 0;
if (_auGraph) if (isOpen())
return MERR_ALREADY_OPEN; return MERR_ALREADY_OPEN;
// Open the Music Device. // Open the Music Device.
@ -176,7 +186,6 @@ bail:
void MidiDriver_CORE::close() { void MidiDriver_CORE::close() {
MidiDriver_MPU401::close(); MidiDriver_MPU401::close();
if (_auGraph) { if (_auGraph) {
AUGraphStop(_auGraph); AUGraphStop(_auGraph);
DisposeAUGraph(_auGraph); DisposeAUGraph(_auGraph);
@ -185,7 +194,7 @@ void MidiDriver_CORE::close() {
} }
void MidiDriver_CORE::send(uint32 b) { void MidiDriver_CORE::send(uint32 b) {
assert(_auGraph != NULL); assert(isOpen());
byte status_byte = (b & 0x000000FF); byte status_byte = (b & 0x000000FF);
byte first_byte = (b & 0x0000FF00) >> 8; byte first_byte = (b & 0x0000FF00) >> 8;
@ -198,7 +207,7 @@ void MidiDriver_CORE::sysEx(const byte *msg, uint16 length) {
unsigned char buf[266]; unsigned char buf[266];
assert(length + 2 <= ARRAYSIZE(buf)); assert(length + 2 <= ARRAYSIZE(buf));
assert(_auGraph != NULL); assert(isOpen());
// Add SysEx frame // Add SysEx frame
buf[0] = 0xF0; buf[0] = 0xF0;

View file

@ -56,6 +56,7 @@ public:
MidiDriver_CoreMIDI(); MidiDriver_CoreMIDI();
~MidiDriver_CoreMIDI(); ~MidiDriver_CoreMIDI();
int open(); int open();
bool isOpen() const { return mOutPort != 0 && mDest != 0; }
void close(); void close();
void send(uint32 b); void send(uint32 b);
void sysEx(const byte *msg, uint16 length); void sysEx(const byte *msg, uint16 length);
@ -80,7 +81,7 @@ MidiDriver_CoreMIDI::~MidiDriver_CoreMIDI() {
} }
int MidiDriver_CoreMIDI::open() { int MidiDriver_CoreMIDI::open() {
if (mDest) if (isOpen())
return MERR_ALREADY_OPEN; return MERR_ALREADY_OPEN;
OSStatus err = noErr; OSStatus err = noErr;
@ -106,7 +107,7 @@ int MidiDriver_CoreMIDI::open() {
void MidiDriver_CoreMIDI::close() { void MidiDriver_CoreMIDI::close() {
MidiDriver_MPU401::close(); MidiDriver_MPU401::close();
if (mOutPort && mDest) { if (isOpen()) {
MIDIPortDispose(mOutPort); MIDIPortDispose(mOutPort);
mOutPort = 0; mOutPort = 0;
mDest = 0; mDest = 0;
@ -114,8 +115,7 @@ void MidiDriver_CoreMIDI::close() {
} }
void MidiDriver_CoreMIDI::send(uint32 b) { void MidiDriver_CoreMIDI::send(uint32 b) {
assert(mOutPort != 0); assert(isOpen());
assert(mDest != 0);
// Extract the MIDI data // Extract the MIDI data
byte status_byte = (b & 0x000000FF); byte status_byte = (b & 0x000000FF);
@ -158,8 +158,7 @@ void MidiDriver_CoreMIDI::send(uint32 b) {
} }
void MidiDriver_CoreMIDI::sysEx(const byte *msg, uint16 length) { void MidiDriver_CoreMIDI::sysEx(const byte *msg, uint16 length) {
assert(mOutPort != 0); assert(isOpen());
assert(mDest != 0);
byte buf[384]; byte buf[384];
MIDIPacketList *packetList = (MIDIPacketList *)buf; MIDIPacketList *packetList = (MIDIPacketList *)buf;

View file

@ -57,6 +57,7 @@ class MidiDriver_DMEDIA : public MidiDriver_MPU401 {
public: public:
MidiDriver_DMEDIA(); MidiDriver_DMEDIA();
int open(); int open();
bool isOpen() const { return _isOpen; }
void close(); void close();
void send(uint32 b); void send(uint32 b);
void sysEx(const byte *msg, uint16 length); void sysEx(const byte *msg, uint16 length);
@ -179,7 +180,7 @@ void MidiDriver_DMEDIA::sysEx (const byte *msg, uint16 length) {
memcpy(buf, msg, length); memcpy(buf, msg, length);
buf[length] = MD_EOX; buf[length] = MD_EOX;
event.sysexmsg = buf; event.sysexmsg = buf;
event.msglen = length; event.msglen = length;
event.msg[0] = MD_SYSEX; event.msg[0] = MD_SYSEX;
event.msg[1] = 0; event.msg[1] = 0;
event.msg[2] = 0; event.msg[2] = 0;

View file

@ -55,6 +55,7 @@ class MidiDriver_SEQ : public MidiDriver_MPU401 {
public: public:
MidiDriver_SEQ(); MidiDriver_SEQ();
int open(); int open();
bool isOpen() const { return _isOpen; }
void close(); void close();
void send(uint32 b); void send(uint32 b);
void sysEx(const byte *msg, uint16 length); void sysEx(const byte *msg, uint16 length);

View file

@ -48,8 +48,9 @@
class MidiDriver_STMIDI : public MidiDriver_MPU401 { class MidiDriver_STMIDI : public MidiDriver_MPU401 {
public: public:
MidiDriver_STMIDI() : _isOpen (false) { } MidiDriver_STMIDI() : _isOpen (false) { }
int open(); int open();
bool isOpen() const { return _isOpen; }
void close(); void close();
void send(uint32 b); void send(uint32 b);
void sysEx(const byte *msg, uint16 length); void sysEx(const byte *msg, uint16 length);
@ -59,7 +60,7 @@ private:
}; };
int MidiDriver_STMIDI::open() { int MidiDriver_STMIDI::open() {
if ((_isOpen) && (!Bcostat(4))) if (_isOpen && (!Bcostat(4)))
return MERR_ALREADY_OPEN; return MERR_ALREADY_OPEN;
warning("ST Midi Port Open"); warning("ST Midi Port Open");
_isOpen = true; _isOpen = true;
@ -123,36 +124,36 @@ void MidiDriver_STMIDI::sysEx (const byte *msg, uint16 length) {
class StMidiMusicPlugin : public MusicPluginObject { class StMidiMusicPlugin : public MusicPluginObject {
public: public:
const char *getName() const { const char *getName() const {
return "STMIDI"; return "STMIDI";
} }
const char *getId() const { const char *getId() const {
return "stmidi"; return "stmidi";
} }
MusicDevices getDevices() const; MusicDevices getDevices() const;
Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const;
}; };
MusicDevices StMidiMusicPlugin::getDevices() const { MusicDevices StMidiMusicPlugin::getDevices() const {
MusicDevices devices; MusicDevices devices;
// TODO: Return a different music type depending on the configuration // TODO: Return a different music type depending on the configuration
// TODO: List the available devices // TODO: List the available devices
devices.push_back(MusicDevice(this, "", MT_GM)); devices.push_back(MusicDevice(this, "", MT_GM));
return devices; return devices;
} }
Common::Error StMidiMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { Common::Error StMidiMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
*mididriver = new MidiDriver_STMIDI(); *mididriver = new MidiDriver_STMIDI();
return Common::kNoError; return Common::kNoError;
} }
//#if PLUGIN_ENABLED_DYNAMIC(STMIDI) //#if PLUGIN_ENABLED_DYNAMIC(STMIDI)
//REGISTER_PLUGIN_DYNAMIC(STMIDI, PLUGIN_TYPE_MUSIC, StMidiMusicPlugin); //REGISTER_PLUGIN_DYNAMIC(STMIDI, PLUGIN_TYPE_MUSIC, StMidiMusicPlugin);
//#else //#else
REGISTER_PLUGIN_STATIC(STMIDI, PLUGIN_TYPE_MUSIC, StMidiMusicPlugin); REGISTER_PLUGIN_STATIC(STMIDI, PLUGIN_TYPE_MUSIC, StMidiMusicPlugin);
//#endif //#endif
#endif #endif

View file

@ -92,49 +92,50 @@ class MidiDriver_TIMIDITY : public MidiDriver_MPU401 {
public: public:
MidiDriver_TIMIDITY(); MidiDriver_TIMIDITY();
int open(); int open();
void close(); bool isOpen() const { return _isOpen; }
void send(uint32 b); void close();
void sysEx(const byte *msg, uint16 length); void send(uint32 b);
void sysEx(const byte *msg, uint16 length);
private: private:
/* standart routine to extract ip address from a string */ /* standart routine to extract ip address from a string */
in_addr_t host_to_addr(const char* address); in_addr_t host_to_addr(const char* address);
/* creates a tcp connection to TiMidity server, returns filedesc (like open()) */ /* creates a tcp connection to TiMidity server, returns filedesc (like open()) */
int connect_to_server(const char* hostname, unsigned short tcp_port); int connect_to_server(const char* hostname, unsigned short tcp_port);
/* send command to the server; printf-like; returns reply string */ /* send command to the server; printf-like; returns reply string */
char *timidity_ctl_command(const char *fmt, ...) GCC_PRINTF(2, 3); char *timidity_ctl_command(const char *fmt, ...) GCC_PRINTF(2, 3);
/* timidity data socket-related stuff */ /* timidity data socket-related stuff */
void timidity_meta_seq(int p1, int p2, int p3); void timidity_meta_seq(int p1, int p2, int p3);
int timidity_sync(int centsec); int timidity_sync(int centsec);
int timidity_eot(); int timidity_eot();
/* write() analogue for any midi data */ /* write() analogue for any midi data */
void timidity_write_data(const void *buf, size_t nbytes); void timidity_write_data(const void *buf, size_t nbytes);
/* get single line of server reply on control connection */ /* get single line of server reply on control connection */
int fdgets(char *buff, size_t buff_size); int fdgets(char *buff, size_t buff_size);
/* teardown connection to server */ /* teardown connection to server */
void teardown(); void teardown();
/* close (if needed) and nullify both control and data filedescs */ /* close (if needed) and nullify both control and data filedescs */
void close_all(); void close_all();
private: private:
bool _isOpen; bool _isOpen;
int _device_num; int _device_num;
int _control_fd; int _control_fd;
int _data_fd; int _data_fd;
/* buffer for partial data read from _control_fd - from timidity-io.c, see fdgets() */ /* buffer for partial data read from _control_fd - from timidity-io.c, see fdgets() */
char _controlbuffer[BUFSIZ]; char _controlbuffer[BUFSIZ];
int _controlbuffer_count; /* beginning of read pointer */ int _controlbuffer_count; /* beginning of read pointer */
int _controlbuffer_size; /* end of read pointer */ int _controlbuffer_size; /* end of read pointer */
}; };
MidiDriver_TIMIDITY::MidiDriver_TIMIDITY() { MidiDriver_TIMIDITY::MidiDriver_TIMIDITY() {
@ -149,9 +150,9 @@ MidiDriver_TIMIDITY::MidiDriver_TIMIDITY() {
} }
int MidiDriver_TIMIDITY::open() { int MidiDriver_TIMIDITY::open() {
char *res; char *res;
char timidity_host[MAXHOSTNAMELEN]; char timidity_host[MAXHOSTNAMELEN];
int timidity_port, data_port, i; int timidity_port, data_port, i;
/* count ourselves open */ /* count ourselves open */
if (_isOpen) if (_isOpen)

View file

@ -61,6 +61,7 @@ private:
public: public:
MidiDriver_WIN(int deviceIndex) : _isOpen(false), _device(deviceIndex) { } MidiDriver_WIN(int deviceIndex) : _isOpen(false), _device(deviceIndex) { }
int open(); int open();
bool isOpen() const { return _isOpen; }
void close(); void close();
void send(uint32 b); void send(uint32 b);
void sysEx(const byte *msg, uint16 length); void sysEx(const byte *msg, uint16 length);
@ -93,6 +94,8 @@ void MidiDriver_WIN::close() {
} }
void MidiDriver_WIN::send(uint32 b) { void MidiDriver_WIN::send(uint32 b) {
assert(_isOpen);
union { union {
DWORD dwData; DWORD dwData;
BYTE bData[4]; BYTE bData[4];

View file

@ -138,6 +138,10 @@ int SoundGenMIDI::open() {
return 0; return 0;
} }
bool SoundGenMIDI::isOpen() const {
return _driver && _driver->isOpen();
}
void SoundGenMIDI::close() { void SoundGenMIDI::close() {
stop(); stop();
if (_driver) if (_driver)

View file

@ -72,6 +72,7 @@ public:
// MidiDriver interface implementation // MidiDriver interface implementation
int open(); int open();
bool isOpen() const;
void close(); void close();
void send(uint32 b); void send(uint32 b);

View file

@ -85,11 +85,17 @@ int MidiPlayer::open() {
return 0; return 0;
} }
bool MidiPlayer::isOpen() const {
return _driver && _driver->isOpen();
}
void MidiPlayer::close() { void MidiPlayer::close() {
stop(); stop();
// _system->lockMutex(_mutex); // _system->lockMutex(_mutex);
if (_driver) if (_driver) {
delete _driver;
_driver->close(); _driver->close();
}
_driver = NULL; _driver = NULL;
clearConstructs(); clearConstructs();
// _system->unlockMutex(_mutex); // _system->unlockMutex(_mutex);

View file

@ -115,6 +115,7 @@ public:
public: public:
// MidiDriver interface implementation // MidiDriver interface implementation
int open(); int open();
bool isOpen() const;
void close(); void close();
void send(uint32 b); void send(uint32 b);

View file

@ -97,10 +97,16 @@ int MusicPlayer::open() {
return 0; return 0;
} }
bool MusicPlayer::isOpen() const {
return _driver && _driver->isOpen();
}
void MusicPlayer::close() { void MusicPlayer::close() {
stop(); stop();
if (_driver) if (_driver) {
_driver->close(); _driver->close();
delete _driver;
}
_driver = 0; _driver = 0;
} }

View file

@ -61,6 +61,7 @@ public:
// MidiDriver interface implementation // MidiDriver interface implementation
int open(); int open();
bool isOpen() const;
void close(); void close();
void send(uint32 b); void send(uint32 b);

View file

@ -264,6 +264,10 @@ int MusicPlayerMidi::open() {
return 0; return 0;
} }
bool MusicPlayerMidi::isOpen() const {
return _driver && _driver->isOpen();
}
void MusicPlayerMidi::close() {} void MusicPlayerMidi::close() {}
void MusicPlayerMidi::send(uint32 b) { void MusicPlayerMidi::send(uint32 b) {

View file

@ -95,6 +95,7 @@ public:
// MidiDriver interface // MidiDriver interface
virtual int open(); virtual int open();
virtual bool isOpen() const;
virtual void close(); virtual void close();
virtual void send(uint32 b); virtual void send(uint32 b);
virtual void metaEvent(byte type, byte *data, uint16 length); virtual void metaEvent(byte type, byte *data, uint16 length);

View file

@ -192,6 +192,10 @@ int MidiPlayer::open() {
return 0; return 0;
} }
bool MidiPlayer::isOpen() const {
return _driver && _driver->isOpen();
}
void MidiPlayer::close() { void MidiPlayer::close() {
stop(); stop();
_mutex.lock(); _mutex.lock();

View file

@ -60,6 +60,7 @@ public:
// MidiDriver interface // MidiDriver interface
int open(); int open();
bool isOpen() const;
MidiChannel *allocateChannel(); MidiChannel *allocateChannel();
MidiChannel *getPercussionChannel(); MidiChannel *getPercussionChannel();

View file

@ -55,6 +55,7 @@ public:
// DUMMY // DUMMY
int open() { return 0; } int open() { return 0; }
bool isOpen() const { return true; }
void close() {} void close() {}
MidiChannel *allocateChannel() { return 0; } MidiChannel *allocateChannel() { return 0; }

View file

@ -694,6 +694,10 @@ int MidiMusic::open() {
return 0; return 0;
} }
bool MidiMusic::isOpen() const {
return _driver != 0;
}
void MidiMusic::close() { void MidiMusic::close() {
} }

View file

@ -86,6 +86,7 @@ public:
//MidiDriver interface implementation //MidiDriver interface implementation
int open(); int open();
bool isOpen() const;
void close(); void close();
void send(uint32 b); void send(uint32 b);
void onTimer(); void onTimer();

View file

@ -83,10 +83,16 @@ int MidiPlayer::open() {
return 0; return 0;
} }
bool MidiPlayer::isOpen() const {
return _driver && _driver->isOpen();
}
void MidiPlayer::close() { void MidiPlayer::close() {
stopMusic(); stopMusic();
if (_driver) if (_driver) {
_driver->close(); _driver->close();
delete _driver;
}
_driver = 0; _driver = 0;
} }

View file

@ -54,6 +54,7 @@ public:
//MidiDriver interface implementation //MidiDriver interface implementation
int open(); int open();
bool isOpen() const;
void close(); void close();
void send(uint32 b); void send(uint32 b);

View file

@ -89,10 +89,16 @@ int MusicPlayer::open() {
return 0; return 0;
} }
bool MusicPlayer::isOpen() const {
return _driver && _driver->isOpen();
}
void MusicPlayer::close() { void MusicPlayer::close() {
stop(); stop();
if (_driver) if (_driver) {
_driver->close(); _driver->close();
delete _driver;
}
_driver = 0; _driver = 0;
} }

View file

@ -66,6 +66,7 @@ public:
//MidiDriver interface implementation //MidiDriver interface implementation
int open(); int open();
bool isOpen() const;
void close(); void close();
void send(uint32 b); void send(uint32 b);

View file

@ -222,6 +222,7 @@ public:
// MidiDriver interface // MidiDriver interface
int open(); int open();
bool isOpen() const;
void close(); void close();
void send(uint32 b); void send(uint32 b);
void metaEvent(byte type, byte *data, uint16 length); void metaEvent(byte type, byte *data, uint16 length);
@ -342,6 +343,10 @@ int MidiPlayer_MSC::open() {
return ret; return ret;
} }
bool MidiPlayer_MSC::isOpen() const {
return _driver && _driver->isOpen();
}
void MidiPlayer_MSC::close() { void MidiPlayer_MSC::close() {
stop(); stop();
_mutex.lock(); _mutex.lock();

View file

@ -59,6 +59,7 @@ public:
// MidiDriver interface // MidiDriver interface
int open(); int open();
bool isOpen() const;
void close(); void close();
void send(uint32 b); void send(uint32 b);
void metaEvent(byte type, byte *data, uint16 length); void metaEvent(byte type, byte *data, uint16 length);
@ -178,6 +179,10 @@ int MidiPlayer::open() {
return ret; return ret;
} }
bool MidiPlayer::isOpen() const {
return _driver && _driver->isOpen();
}
void MidiPlayer::close() { void MidiPlayer::close() {
stop(); stop();
_mutex.lock(); _mutex.lock();

View file

@ -78,8 +78,10 @@ MidiMusic::MidiMusic(QueenEngine *vm)
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); _driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
} }
} }
assert(_driver);
_driver->open(); int ret = _driver->open();
assert(ret == 0);
_driver->setTimerCallback(this, &timerCallback); _driver->setTimerCallback(this, &timerCallback);
if (_nativeMT32) if (_nativeMT32)

View file

@ -58,6 +58,7 @@ public:
//MidiDriver interface implementation //MidiDriver interface implementation
int open() { return 0; } int open() { return 0; }
bool isOpen() const { return true; }
void close() {} void close() {}
void send(uint32 b); void send(uint32 b);

View file

@ -50,6 +50,7 @@ MusicDriver::MusicDriver() : _isGM(false) {
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM); MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
_driver = MidiDriver::createMidi(dev); _driver = MidiDriver::createMidi(dev);
assert(_driver);
_driverType = MidiDriver::getMusicType(dev); _driverType = MidiDriver::getMusicType(dev);
if (isMT32()) if (isMT32())
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); _driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
@ -75,6 +76,10 @@ int MusicDriver::open() {
return 0; return 0;
} }
bool MusicDriver::isOpen() const {
return _driver->isOpen();
}
void MusicDriver::setVolume(int volume) { void MusicDriver::setVolume(int volume) {
volume = CLIP(volume, 0, 255); volume = CLIP(volume, 0, 255);

View file

@ -58,6 +58,7 @@ public:
//MidiDriver interface implementation //MidiDriver interface implementation
int open(); int open();
bool isOpen() const;
void close() { _driver->close(); } void close() { _driver->close(); }
void send(uint32 b); void send(uint32 b);

View file

@ -89,6 +89,7 @@ public:
return open(resMan); return open(resMan);
} }
virtual int open(ResourceManager *resMan) { return _driver->open(); } virtual int open(ResourceManager *resMan) { return _driver->open(); }
bool isOpen() const { return _driver->isOpen(); }
virtual void close() { _driver->close(); } virtual void close() { _driver->close(); }
virtual void send(uint32 b) { _driver->send(b); } virtual void send(uint32 b) { _driver->send(b); }
uint32 getBaseTempo() { return _driver->getBaseTempo(); } uint32 getBaseTempo() { return _driver->getBaseTempo(); }

View file

@ -284,6 +284,7 @@ public:
public: public:
// MidiDriver interface // MidiDriver interface
int open() { return 0; } int open() { return 0; }
bool isOpen() const { return true; }
void close() { } void close() { }
void send(uint32 b); void send(uint32 b);
const char *getErrorName(int error_code) { return "Unknown"; } const char *getErrorName(int error_code) { return "Unknown"; }

View file

@ -432,10 +432,16 @@ int MidiMusicPlayer::open() {
return 0; return 0;
} }
bool MidiMusicPlayer::isOpen() const {
return _driver && _driver->isOpen();
}
void MidiMusicPlayer::close() { void MidiMusicPlayer::close() {
stop(); stop();
if (_driver) if (_driver) {
_driver->close(); _driver->close();
delete _driver;
}
_driver = 0; _driver = 0;
} }

View file

@ -80,6 +80,7 @@ public:
//MidiDriver interface implementation //MidiDriver interface implementation
int open(); int open();
bool isOpen() const;
void close(); void close();
void send(uint32 b); void send(uint32 b);

View file

@ -110,6 +110,10 @@ int MidiPlayer::open() {
return ret; return ret;
} }
bool MidiPlayer::isOpen() const {
return _driver && _driver->isOpen();
}
void MidiPlayer::close() { void MidiPlayer::close() {
stop(); stop();
_mutex.lock(); _mutex.lock();

View file

@ -59,6 +59,7 @@ public:
// MidiDriver interface // MidiDriver interface
int open(); int open();
bool isOpen() const;
void close(); void close();
void send(uint32 b); void send(uint32 b);
void metaEvent(byte type, byte *data, uint16 length); void metaEvent(byte type, byte *data, uint16 length);