ENGINES: Further simplify pseudo MidiDrivers; fix some regressions

The regression affected AGOS and maybe some others; specifically,
the real MidiDriver would have been deleted twice -- I previously
missed that the Engine instances takes care of freeing the real
MidiDriver, not the MidiPlayer wrapping it.

This commit should clarify the ownership of the real MidiDriver for
most pseudo MidiDrivers.
This commit is contained in:
Max Horn 2011-03-23 16:14:39 +01:00
parent 29847ea42d
commit e70fd59b35
31 changed files with 280 additions and 464 deletions

View File

@ -74,6 +74,7 @@ MIDISound::MIDISound(uint8 *data, uint32 len, int resnum, SoundMgr &manager) : A
SoundGenMIDI::SoundGenMIDI(AgiEngine *vm, Audio::Mixer *pMixer) : SoundGen(vm, pMixer), _parser(0), _isPlaying(false), _passThrough(false), _isGM(false) {
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB);
_driver = MidiDriver::createMidi(dev);
assert(_driver);
if (ConfMan.getBool("native_mt32") || MidiDriver::getMusicType(dev) == MT_MT32) {
_nativeMT32 = true;
@ -85,7 +86,17 @@ SoundGenMIDI::SoundGenMIDI(AgiEngine *vm, Audio::Mixer *pMixer) : SoundGen(vm, p
memset(_channel, 0, sizeof(_channel));
memset(_channelVolume, 127, sizeof(_channelVolume));
_masterVolume = 0;
this->open();
int ret = _driver->open();
if (ret == 0) {
if (_nativeMT32)
_driver->sendMT32Reset();
else
_driver->sendGMReset();
_driver->setTimerCallback(this, &onTimer);
}
_smfParser = MidiParser::createParser_SMF();
_midiMusicData = NULL;
}
@ -93,7 +104,11 @@ SoundGenMIDI::SoundGenMIDI(AgiEngine *vm, Audio::Mixer *pMixer) : SoundGen(vm, p
SoundGenMIDI::~SoundGenMIDI() {
_driver->setTimerCallback(NULL, NULL);
stop();
this->close();
if (_driver) {
_driver->close();
delete _driver;
_driver = 0;
}
_smfParser->setMidiDriver(NULL);
delete _smfParser;
delete[] _midiMusicData;
@ -119,32 +134,6 @@ void SoundGenMIDI::setVolume(int volume) {
}
}
int SoundGenMIDI::open() {
// Don't ever call open without first setting the output driver!
if (!_driver)
return 255;
int ret = _driver->open();
if (ret)
return ret;
_driver->setTimerCallback(this, &onTimer);
if (_nativeMT32)
_driver->sendMT32Reset();
else
_driver->sendGMReset();
return 0;
}
void SoundGenMIDI::close() {
stop();
if (_driver)
_driver->close();
_driver = 0;
}
void SoundGenMIDI::send(uint32 b) {
if (_passThrough) {
_driver->send(b);

View File

@ -70,12 +70,9 @@ public:
void setGM(bool isGM) { _isGM = isGM; }
// MidiDriver interface implementation
int open();
void close();
void send(uint32 b);
void metaEvent(byte type, byte *data, uint16 length);
// MidiDriver_BASE interface implementation
virtual void send(uint32 b);
virtual void metaEvent(byte type, byte *data, uint16 length);
private:

View File

@ -470,7 +470,6 @@ AGOSEngine::AGOSEngine(OSystem *syst)
_planarBuf = 0;
_midiEnabled = false;
_nativeMT32 = false;
_vgaTickCounter = 0;
@ -555,30 +554,13 @@ Common::Error AGOSEngine::init() {
((getFeatures() & GF_TALKIE) && getPlatform() == Common::kPlatformAcorn) ||
(getPlatform() == Common::kPlatformPC)) {
// Setup midi driver
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_ADLIB | MDT_MIDI | (getGameType() == GType_SIMON1 ? MDT_PREFER_MT32 : MDT_PREFER_GM));
_nativeMT32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32"));
_driver = MidiDriver::createMidi(dev);
if (_nativeMT32)
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
_midi.setNativeMT32(_nativeMT32);
_midi.mapMT32toGM(getGameType() != GType_SIMON2 && !_nativeMT32);
_midi.setDriver(_driver);
int ret = _midi.open();
int ret = _midi.open(getGameType());
if (ret)
warning("MIDI Player init failed: \"%s\"", MidiDriver::getErrorName (ret));
warning("MIDI Player init failed: \"%s\"", MidiDriver::getErrorName(ret));
_midi.setVolume(ConfMan.getInt("music_volume"), ConfMan.getInt("sfx_volume"));
_midiEnabled = true;
} else {
_driver = NULL;
}
// Setup mixer
@ -734,7 +716,7 @@ void AGOSEngine_Simon2::setupGame() {
_itemMemSize = 20000;
_tableMemSize = 100000;
// Check whether to use MT-32 MIDI tracks in Simon the Sorcerer 2
if (getGameType() == GType_SIMON2 && _nativeMT32)
if (getGameType() == GType_SIMON2 && _midi.hasNativeMT32())
_musicIndexBase = (1128 + 612) / 4;
else
_musicIndexBase = 1128 / 4;
@ -895,9 +877,6 @@ void AGOSEngine::setupGame() {
}
AGOSEngine::~AGOSEngine() {
_midi.close();
delete _driver;
_system->getAudioCDManager()->stop();
for (uint i = 0; i < _itemHeap.size(); i++) {

View File

@ -550,9 +550,7 @@ protected:
byte _lettersToPrintBuf[80];
MidiPlayer _midi;
MidiDriver *_driver;
bool _midiEnabled;
bool _nativeMT32;
int _vgaTickCounter;

View File

@ -25,6 +25,7 @@
#include "common/config-manager.h"
#include "common/file.h"
#include "common/system.h"
@ -62,15 +63,34 @@ MidiPlayer::MidiPlayer() {
}
MidiPlayer::~MidiPlayer() {
stop();
Common::StackLock lock(_mutex);
close();
if (_driver) {
_driver->close();
delete _driver;
}
_driver = NULL;
clearConstructs();
}
int MidiPlayer::open() {
// Don't ever call open without first setting the output driver!
int MidiPlayer::open(int gameType) {
// Don't call open() twice!
assert(!_driver);
// Setup midi driver
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_ADLIB | MDT_MIDI | (gameType == GType_SIMON1 ? MDT_PREFER_MT32 : MDT_PREFER_GM));
_nativeMT32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32"));
_driver = MidiDriver::createMidi(dev);
if (!_driver)
return 255;
if (_nativeMT32)
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
_map_mt32_to_gm = (gameType != GType_SIMON2 && !_nativeMT32);
int ret = _driver->open();
if (ret)
return ret;
@ -84,18 +104,6 @@ int MidiPlayer::open() {
return 0;
}
void MidiPlayer::close() {
stop();
// _system->lockMutex(_mutex);
if (_driver) {
delete _driver;
_driver->close();
}
_driver = NULL;
clearConstructs();
// _system->unlockMutex(_mutex);
}
void MidiPlayer::send(uint32 b) {
if (!_current)
return;
@ -305,12 +313,6 @@ void MidiPlayer::setDriver(MidiDriver *md) {
_driver = md;
}
void MidiPlayer::mapMT32toGM(bool map) {
Common::StackLock lock(_mutex);
_map_mt32_to_gm = map;
}
void MidiPlayer::setLoop(bool loop) {
Common::StackLock lock(_mutex);

View File

@ -97,8 +97,7 @@ public:
void loadXMIDI(Common::File *in, bool sfx = false);
void loadS1D(Common::File *in, bool sfx = false);
void mapMT32toGM(bool map);
void setNativeMT32(bool nativeMT32) { _nativeMT32 = nativeMT32; }
bool hasNativeMT32() const { return _nativeMT32; }
void setLoop(bool loop);
void startTrack(int track);
void queueTrack(int track, bool loop);
@ -113,13 +112,13 @@ public:
void setDriver(MidiDriver *md);
public:
// MidiDriver interface implementation
int open();
void close();
void send(uint32 b);
void metaEvent(byte type, byte *data, uint16 length);
int open(int gameType);
void setPassThrough(bool b) { _passThrough = b; }
// MidiDriver_BASE interface implementation
virtual void send(uint32 b);
virtual void metaEvent(byte type, byte *data, uint16 length);
};
} // End of namespace AGOS

View File

@ -162,18 +162,7 @@ int DraciEngine::init() {
_dubbingArchive = openAnyPossibleDubbing();
_sound = new Sound(_mixer);
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
bool native_mt32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32"));
//bool adlib = (MidiDriver::getMusicType(dev) == MT_ADLIB);
_midiDriver = MidiDriver::createMidi(dev);
if (native_mt32)
_midiDriver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
_music = new MusicPlayer(_midiDriver, musicPathMask);
_music->setNativeMT32(native_mt32);
_music->open();
//_music->setAdLib(adlib);
_music = new MusicPlayer(musicPathMask);
// Setup mixer
syncSoundSettings();
@ -404,7 +393,6 @@ DraciEngine::~DraciEngine() {
delete _sound;
delete _music;
delete _midiDriver;
delete _soundsArchive;
delete _dubbingArchive;

View File

@ -85,7 +85,6 @@ public:
AnimationManager *_anims;
Sound *_sound;
MusicPlayer *_music;
MidiDriver *_midiDriver;
Font *_smallFont;
Font *_bigFont;

View File

@ -36,18 +36,46 @@
namespace Draci {
MusicPlayer::MusicPlayer(MidiDriver *driver, const char *pathMask) : _parser(0), _driver(driver), _pathMask(pathMask), _looping(false), _isPlaying(false), _passThrough(false), _isGM(false), _track(-1) {
MusicPlayer::MusicPlayer(const char *pathMask) : _parser(0), _driver(0), _pathMask(pathMask), _looping(false), _isPlaying(false), _passThrough(false), _isGM(false), _track(-1) {
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
_nativeMT32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32"));
//bool adlib = (MidiDriver::getMusicType(dev) == MT_ADLIB);
_driver = MidiDriver::createMidi(dev);
assert(_driver);
if (_nativeMT32)
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
memset(_channel, 0, sizeof(_channel));
memset(_channelVolume, 127, sizeof(_channelVolume));
_masterVolume = 0;
_smfParser = MidiParser::createParser_SMF();
_midiMusicData = NULL;
int ret = _driver->open();
if (ret == 0) {
if (_nativeMT32)
_driver->sendMT32Reset();
else
_driver->sendGMReset();
// TODO: Load cmf.ins with the instrument table. It seems that an
// interface for such an operation is supported for AdLib. Maybe for
// this card, setting instruments is necessary.
_driver->setTimerCallback(this, &onTimer);
}
}
MusicPlayer::~MusicPlayer() {
_driver->setTimerCallback(NULL, NULL);
stop();
this->close();
if (_driver) {
_driver->close();
delete _driver;
_driver = 0;
}
_smfParser->setMidiDriver(NULL);
delete _smfParser;
delete[] _midiMusicData;
@ -75,37 +103,6 @@ void MusicPlayer::setVolume(int volume) {
}
}
int MusicPlayer::open() {
// Don't ever call open without first setting the output driver!
if (!_driver)
return 255;
int ret = _driver->open();
if (ret)
return ret;
if (_nativeMT32)
_driver->sendMT32Reset();
else
_driver->sendGMReset();
// TODO: Load cmf.ins with the instrument table. It seems that an
// interface for such an operation is supported for AdLib. Maybe for
// this card, setting instruments is necessary.
_driver->setTimerCallback(this, &onTimer);
return 0;
}
void MusicPlayer::close() {
stop();
if (_driver) {
_driver->close();
delete _driver;
}
_driver = 0;
}
void MusicPlayer::send(uint32 b) {
if (_passThrough) {
_driver->send(b);

View File

@ -38,7 +38,7 @@ namespace Draci {
class MusicPlayer : public MidiDriver_BASE {
public:
MusicPlayer(MidiDriver *driver, const char *pathMask);
MusicPlayer(const char *pathMask);
~MusicPlayer();
bool isPlaying() { return _isPlaying; }
@ -48,7 +48,6 @@ public:
int getVolume() { return _masterVolume; }
void syncVolume();
void setNativeMT32(bool b) { _nativeMT32 = b; }
bool hasNativeMT32() { return _nativeMT32; }
void playSMF(int track, bool loop);
void stop();
@ -59,21 +58,18 @@ public:
void setGM(bool isGM) { _isGM = isGM; }
// MidiDriver interface implementation
int open();
void close();
void send(uint32 b);
void metaEvent(byte type, byte *data, uint16 length);
MidiParser *_parser;
Common::Mutex _mutex;
// MidiDriver_BASE interface implementation
virtual void send(uint32 b);
virtual void metaEvent(byte type, byte *data, uint16 length);
protected:
static void onTimer(void *data);
void setChannelVolume(int channel);
MidiParser *_parser;
Common::Mutex _mutex;
MidiChannel *_channel[16];
MidiDriver *_driver;
MidiParser *_smfParser;

View File

@ -247,21 +247,10 @@ MusicPlayerMidi::~MusicPlayerMidi() {
delete _midiParser;
// Unload the MIDI Driver
if (_driver)
if (_driver) {
_driver->close();
delete _driver;
}
int MusicPlayerMidi::open() {
// Don't ever call open without first setting the output driver!
if (!_driver)
return 255;
int ret = _driver->open();
if (ret)
return ret;
return 0;
delete _driver;
}
}
void MusicPlayerMidi::send(uint32 b) {
@ -375,7 +364,9 @@ MusicPlayerXMI::MusicPlayerXMI(GroovieEngine *vm, const Common::String &gtlName)
// Create the driver
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
_driver = MidiDriver::createMidi(dev);
this->open();
assert(_driver);
_driver->open(); // TODO: Handle return value != 0 (indicating an error)
// Set the parser's driver
_midiParser->setMidiDriver(this);
@ -675,7 +666,9 @@ MusicPlayerMac::MusicPlayerMac(GroovieEngine *vm) : MusicPlayerMidi(vm) {
// Create the driver
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
_driver = MidiDriver::createMidi(dev);
this->open();
assert(_driver);
_driver->open(); // TODO: Handle return value != 0 (indicating an error)
// Set the parser's driver
_midiParser->setMidiDriver(this);

View File

@ -93,8 +93,7 @@ public:
MusicPlayerMidi(GroovieEngine *vm);
~MusicPlayerMidi();
// MidiDriver interface
virtual int open();
// MidiDriver_BASE interface
virtual void send(uint32 b);
virtual void metaEvent(byte type, byte *data, uint16 length);

View File

@ -60,7 +60,16 @@ MidiPlayer::MidiPlayer(MidiDriver *driver)
}
MidiPlayer::~MidiPlayer() {
close();
stop();
Common::StackLock lock(_mutex);
_driver->setTimerCallback(0, 0);
_driver->close();
delete _driver;
_driver = 0;
if (_parser)
_parser->setMidiDriver(0);
delete _parser;
}
bool MidiPlayer::isPlaying() const {
@ -179,19 +188,6 @@ int MidiPlayer::open() {
return 0;
}
void MidiPlayer::close() {
stop();
Common::StackLock lock(_mutex);
_driver->setTimerCallback(0, 0);
_driver->close();
delete _driver;
_driver = 0;
if (_parser)
_parser->setMidiDriver(0);
delete _parser;
}
void MidiPlayer::send(uint32 b) {
byte volume, ch = (byte)(b & 0xF);
debugC(9, kDebugMusic, "MidiPlayer::send, channel %d (volume is %d)", ch, _channelsVolume[ch]);

View File

@ -58,12 +58,11 @@ public:
void syncVolume();
void updateTimer();
// MidiDriver interface
int open();
void close();
void metaEvent(byte type, byte *data, uint16 length);
void send(uint32 b);
// MidiDriver_BASE interface
virtual void metaEvent(byte type, byte *data, uint16 length);
virtual void send(uint32 b);
int open();
uint32 getBaseTempo();
private:

View File

@ -97,8 +97,8 @@ SoundManager::~SoundManager() {
if (_driver) {
_driver->close();
delete _driver;
_driver = NULL;
}
_driver = NULL;
g_system->deleteMutex(_soundMutex);
}
@ -597,6 +597,7 @@ void SoundManager::doTimer() {
MidiMusic::MidiMusic(MidiDriver *driver, ChannelEntry channels[NUM_CHANNELS],
uint8 channelNum, uint8 soundNum, bool isMus, uint8 numChannels, void *soundData, uint32 size) {
_driver = driver;
assert(_driver);
_channels = channels;
_soundNumber = soundNum;
_channelNumber = channelNum;
@ -620,9 +621,7 @@ MidiMusic::MidiMusic(MidiDriver *driver, ChannelEntry channels[NUM_CHANNELS],
_parser->setMidiDriver(this);
_parser->setTimerRate(_driver->getBaseTempo());
this->open();
_soundData = (uint8 *) soundData;
_soundData = (uint8 *)soundData;
_soundSize = size;
// Check whether the music data is compressed - if so, decompress it for the duration
@ -654,7 +653,6 @@ MidiMusic::MidiMusic(MidiDriver *driver, ChannelEntry channels[NUM_CHANNELS],
MidiMusic::~MidiMusic() {
_parser->unloadMusic();
delete _parser;
this->close();
delete _decompressedSound;
}
@ -686,17 +684,6 @@ void MidiMusic::playMusic() {
_isPlaying = true;
}
int MidiMusic::open() {
// Don't ever call open without first setting the output driver!
if (!_driver)
return 255;
return 0;
}
void MidiMusic::close() {
}
void MidiMusic::send(uint32 b) {
if (_passThrough) {
_driver->send(b);
@ -749,7 +736,6 @@ void MidiMusic::stopMusic() {
debugC(ERROR_DETAILED, kLureDebugSounds, "MidiMusic::stopMusic sound %d", _soundNumber);
_isPlaying = false;
_parser->unloadMusic();
close();
}
} // End of namespace Lure

View File

@ -84,13 +84,11 @@ public:
void setPassThrough(bool b) { _passThrough = b; }
void toggleVChange();
//MidiDriver interface implementation
int open();
void close();
void send(uint32 b);
void onTimer();
// MidiDriver_BASE interface implementation
virtual void send(uint32 b);
virtual void metaEvent(byte type, byte *data, uint16 length);
void metaEvent(byte type, byte *data, uint16 length);
void onTimer();
uint8 channelNumber() { return _channelNumber; }
uint8 soundNumber() { return _soundNumber; }

View File

@ -39,14 +39,21 @@ MidiPlayer::MidiPlayer(MadsM4Engine *vm, MidiDriver *driver) : _vm(vm), _midiDat
_parser = MidiParser::createParser_SMF();
_parser->setMidiDriver(this);
_parser->setTimerRate(_driver->getBaseTempo());
open();
int ret = _driver->open();
if (ret == 0)
_driver->setTimerCallback(this, &onTimer);
}
MidiPlayer::~MidiPlayer() {
_driver->setTimerCallback(NULL, NULL);
_parser->setMidiDriver(NULL);
stopMusic();
close();
if (_driver) {
_driver->close();
delete _driver;
}
_driver = 0;
delete _parser;
free(_midiData);
}
@ -71,28 +78,6 @@ void MidiPlayer::setVolume(int volume) {
}
}
int MidiPlayer::open() {
// Don't ever call open without first setting the output driver!
if (!_driver)
return 255;
int ret = _driver->open();
if (ret)
return ret;
_driver->setTimerCallback(this, &onTimer);
return 0;
}
void MidiPlayer::close() {
stopMusic();
if (_driver) {
_driver->close();
delete _driver;
}
_driver = 0;
}
void MidiPlayer::send(uint32 b) {
if (_passThrough) {
_driver->send(b);

View File

@ -52,12 +52,9 @@ public:
void setGM(bool isGM) { _isGM = isGM; }
//MidiDriver interface implementation
int open();
void close();
void send(uint32 b);
void metaEvent(byte type, byte *data, uint16 length);
// MidiDriver_BASE interface implementation
virtual void send(uint32 b);
virtual void metaEvent(byte type, byte *data, uint16 length);
protected:
static void onTimer(void *data);

View File

@ -100,18 +100,7 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng
_script = new ScriptInterpreter(this);
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
bool native_mt32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32"));
//bool adlib = (MidiDriver::getMusicType(dev) == MT_ADLIB);
MidiDriver *driver = MidiDriver::createMidi(dev);
if (native_mt32)
driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
_music = new MusicPlayer(driver);
_music->setNativeMT32(native_mt32);
_music->open();
//_music->setAdLib(adlib);
_music = new MusicPlayer();
// Set default sound frequency
switch (getGameID()) {

View File

@ -37,17 +37,40 @@
namespace Made {
MusicPlayer::MusicPlayer(MidiDriver *driver) : _parser(0), _driver(driver), _looping(false), _isPlaying(false), _passThrough(false), _isGM(false) {
MusicPlayer::MusicPlayer() : _parser(0), _driver(0), _looping(false), _isPlaying(false), _passThrough(false), _isGM(false) {
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
_nativeMT32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32"));
//bool adlib = (MidiDriver::getMusicType(dev) == MT_ADLIB);
_driver = MidiDriver::createMidi(dev);
assert(_driver);
if (_nativeMT32)
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
memset(_channel, 0, sizeof(_channel));
_masterVolume = 0;
_xmidiParser = MidiParser::createParser_XMIDI();
_smfParser = MidiParser::createParser_SMF();
int ret = _driver->open();
if (ret == 0) {
if (_nativeMT32)
_driver->sendMT32Reset();
else
_driver->sendGMReset();
_driver->setTimerCallback(this, &onTimer);
}
}
MusicPlayer::~MusicPlayer() {
_driver->setTimerCallback(NULL, NULL);
stop();
this->close();
if (_driver) {
_driver->close();
delete _driver;
_driver = 0;
}
_xmidiParser->setMidiDriver(NULL);
_smfParser->setMidiDriver(NULL);
delete _xmidiParser;
@ -71,33 +94,6 @@ void MusicPlayer::setVolume(int volume) {
}
}
int MusicPlayer::open() {
// Don't ever call open without first setting the output driver!
if (!_driver)
return 255;
int ret = _driver->open();
if (ret)
return ret;
if (_nativeMT32)
_driver->sendMT32Reset();
else
_driver->sendGMReset();
_driver->setTimerCallback(this, &onTimer);
return 0;
}
void MusicPlayer::close() {
stop();
if (_driver) {
_driver->close();
delete _driver;
}
_driver = 0;
}
void MusicPlayer::send(uint32 b) {
if (_passThrough) {
_driver->send(b);

View File

@ -43,7 +43,7 @@ enum MusicFlags {
class MusicPlayer : public MidiDriver_BASE {
public:
MusicPlayer(MidiDriver *driver);
MusicPlayer();
~MusicPlayer();
bool isPlaying() { return _isPlaying; }
@ -52,8 +52,7 @@ public:
void setVolume(int volume);
int getVolume() { return _masterVolume; }
void setNativeMT32(bool b) { _nativeMT32 = b; }
bool hasNativeMT32() { return _nativeMT32; }
bool hasNativeMT32() const { return _nativeMT32; }
void playXMIDI(GenericResource *midiResource, MusicFlags flags = MUSIC_NORMAL);
void playSMF(GenericResource *midiResource, MusicFlags flags = MUSIC_NORMAL);
void stop();
@ -64,20 +63,17 @@ public:
void setGM(bool isGM) { _isGM = isGM; }
//MidiDriver interface implementation
int open();
void close();
void send(uint32 b);
void metaEvent(byte type, byte *data, uint16 length);
MidiParser *_parser;
Common::Mutex _mutex;
// MidiDriver_BASE interface implementation
virtual void send(uint32 b);
virtual void metaEvent(byte type, byte *data, uint16 length);
protected:
static void onTimer(void *data);
MidiParser *_parser;
Common::Mutex _mutex;
MidiChannel *_channel[16];
MidiDriver *_driver;
MidiParser *_xmidiParser, *_smfParser;

View File

@ -220,11 +220,9 @@ public:
int getVolume() const { return _masterVolume; }
void setLooping(bool loop) { _isLooping = loop; }
// MidiDriver interface
int open();
void close();
void send(uint32 b);
void metaEvent(byte type, byte *data, uint16 length);
// MidiDriver_BASE interface
virtual void send(uint32 b);
virtual void metaEvent(byte type, byte *data, uint16 length);
private:
@ -254,11 +252,25 @@ MidiPlayer_MSC::MidiPlayer_MSC(MidiDriver *driver)
_volume[i] = 127;
}
open();
int ret = _driver->open();
if (ret == 0) {
_parser = createParser_MSC();
_parser->setMidiDriver(this);
_parser->setTimerRate(_driver->getBaseTempo());
_driver->setTimerCallback(this, &timerCallback);
}
}
MidiPlayer_MSC::~MidiPlayer_MSC() {
close();
stop();
Common::StackLock lock(_mutex);
_driver->setTimerCallback(NULL, NULL);
_driver->close();
delete _driver;
_driver = 0;
_parser->setMidiDriver(NULL);
delete _parser;
}
void MidiPlayer_MSC::play(Common::SeekableReadStream *stream) {
@ -326,29 +338,6 @@ void MidiPlayer_MSC::setVolumeInternal(int volume) {
}
}
int MidiPlayer_MSC::open() {
int ret = _driver->open();
if (ret == 0) {
_parser = createParser_MSC();
_parser->setMidiDriver(this);
_parser->setTimerRate(_driver->getBaseTempo());
_driver->setTimerCallback(this, &timerCallback);
}
return ret;
}
void MidiPlayer_MSC::close() {
stop();
Common::StackLock lock(_mutex);
_driver->setTimerCallback(NULL, NULL);
_driver->close();
delete _driver;
_driver = 0;
_parser->setMidiDriver(NULL);
delete _parser;
}
void MidiPlayer_MSC::send(uint32 b) {
const byte ch = b & 0x0F;
byte param2 = (b >> 16) & 0xFF;

View File

@ -57,11 +57,9 @@ public:
int getVolume() const { return _masterVolume; }
void setLooping(bool loop) { _isLooping = loop; }
// MidiDriver interface
int open();
void close();
void send(uint32 b);
void metaEvent(byte type, byte *data, uint16 length);
// MidiDriver_BASE interface
virtual void send(uint32 b);
virtual void metaEvent(byte type, byte *data, uint16 length);
private:
@ -87,11 +85,25 @@ MidiPlayer::MidiPlayer(MidiDriver *driver)
_channelsVolume[i] = 127;
}
open();
int ret = _driver->open();
if (ret == 0) {
_parser = MidiParser::createParser_SMF();
_parser->setMidiDriver(this);
_parser->setTimerRate(_driver->getBaseTempo());
_driver->setTimerCallback(this, &timerCallback);
}
}
MidiPlayer::~MidiPlayer() {
close();
stop();
Common::StackLock lock(_mutex);
_driver->setTimerCallback(NULL, NULL);
_driver->close();
delete _driver;
_driver = 0;
_parser->setMidiDriver(NULL);
delete _parser;
}
void MidiPlayer::play(Common::SeekableReadStream *stream) {
@ -161,29 +173,6 @@ void MidiPlayer::setVolume(int volume) {
}
}
int MidiPlayer::open() {
int ret = _driver->open();
if (ret == 0) {
_parser = MidiParser::createParser_SMF();
_parser->setMidiDriver(this);
_parser->setTimerRate(_driver->getBaseTempo());
_driver->setTimerCallback(this, &timerCallback);
}
return ret;
}
void MidiPlayer::close() {
stop();
Common::StackLock lock(_mutex);
_driver->setTimerCallback(NULL, NULL);
_driver->close();
delete _driver;
_driver = 0;
_parser->setMidiDriver(NULL);
delete _parser;
}
void MidiPlayer::send(uint32 b) {
byte volume, ch = (byte)(b & 0xF);
switch (b & 0xFFF0) {

View File

@ -56,9 +56,9 @@ public:
void queueClear();
void toggleVChange();
//MidiDriver interface implementation
void send(uint32 b);
void metaEvent(byte type, byte *data, uint16 length);
// MidiDriver_BASE interface implementation
virtual void send(uint32 b);
virtual void metaEvent(byte type, byte *data, uint16 length);
protected:

View File

@ -55,27 +55,20 @@ MusicDriver::MusicDriver() : _isGM(false) {
if (isMT32())
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
this->open();
int retValue = _driver->open();
if (retValue == 0) {
if (_nativeMT32)
_driver->sendMT32Reset();
else
_driver->sendGMReset();
}
}
MusicDriver::~MusicDriver() {
this->close();
_driver->close();
delete _driver;
}
int MusicDriver::open() {
int retValue = _driver->open();
if (retValue)
return retValue;
if (_nativeMT32)
_driver->sendMT32Reset();
else
_driver->sendGMReset();
return 0;
}
void MusicDriver::setVolume(int volume) {
volume = CLIP(volume, 0, 255);

View File

@ -56,18 +56,14 @@ public:
bool isMT32() { return _driverType == MT_MT32 || _nativeMT32; }
void setGM(bool isGM) { _isGM = isGM; }
//MidiDriver interface implementation
int open();
bool isOpen() const;
void close() { _driver->close(); }
void send(uint32 b);
void metaEvent(byte type, byte *data, uint16 length) {}
// MidiDriver_BASE interface implementation
virtual void send(uint32 b);
virtual void metaEvent(byte type, byte *data, uint16 length) {}
void setTimerCallback(void *timerParam, void (*timerProc)(void *)) { _driver->setTimerCallback(timerParam, timerProc); }
uint32 getBaseTempo() { return _driver->getBaseTempo(); }
Common::Mutex _mutex;
Common::Mutex _mutex; // FIXME: Make _mutex protected
protected:

View File

@ -386,18 +386,41 @@ void DeleteMidiBuffer() {
midiBuffer.pDat = NULL;
}
MidiMusicPlayer::MidiMusicPlayer(MidiDriver *driver) : _parser(0), _driver(driver), _looping(false), _isPlaying(false) {
MidiMusicPlayer::MidiMusicPlayer() : _parser(0), _driver(0), _looping(false), _isPlaying(false) {
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
bool native_mt32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32"));
//bool adlib = (MidiDriver::getMusicType(dev) == MT_ADLIB);
_driver = MidiDriver::createMidi(dev);
assert(_driver);
if (native_mt32)
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
memset(_channel, 0, sizeof(_channel));
memset(_channelVolume, 0, sizeof(_channelVolume));
_masterVolume = 0;
this->open();
int ret = _driver->open();
if (ret == 0) {
if (native_mt32)
_driver->sendMT32Reset();
else
_driver->sendGMReset();
_driver->setTimerCallback(this, &onTimer);
}
_xmidiParser = MidiParser::createParser_XMIDI();
}
MidiMusicPlayer::~MidiMusicPlayer() {
_driver->setTimerCallback(NULL, NULL);
stop();
this->close();
if (_driver) {
_driver->close();
delete _driver;
_driver = 0;
}
_xmidiParser->setMidiDriver(NULL);
delete _xmidiParser;
}
@ -419,28 +442,6 @@ void MidiMusicPlayer::setVolume(int volume) {
}
}
int MidiMusicPlayer::open() {
// Don't ever call open without first setting the output driver!
if (!_driver)
return 255;
int ret = _driver->open();
if (ret)
return ret;
_driver->setTimerCallback(this, &onTimer);
return 0;
}
void MidiMusicPlayer::close() {
stop();
if (_driver) {
_driver->close();
delete _driver;
}
_driver = 0;
}
void MidiMusicPlayer::send(uint32 b) {
byte channel = (byte)(b & 0x0F);
if ((b & 0xFFF0) == 0x07B0) {

View File

@ -62,7 +62,7 @@ void dumpMusic();
class MidiMusicPlayer : public MidiDriver_BASE {
public:
MidiMusicPlayer(MidiDriver *driver);
MidiMusicPlayer();
~MidiMusicPlayer();
bool isPlaying() { return _isPlaying; }
@ -78,16 +78,12 @@ public:
void resume();
void setLoop(bool loop) { _looping = loop; }
//MidiDriver interface implementation
int open();
void close();
void send(uint32 b);
void metaEvent(byte type, byte *data, uint16 length);
// MidiDriver_BASE interface implementation
virtual void send(uint32 b);
virtual void metaEvent(byte type, byte *data, uint16 length);
// The original sets the "sequence timing" to 109 Hz, whatever that
// means. The default is 120.
uint32 getBaseTempo() { return _driver ? (109 * _driver->getBaseTempo()) / 120 : 0; }
protected:

View File

@ -856,23 +856,8 @@ TinselEngine::TinselEngine(OSystem *syst, const TinselGameDescription *gameDesc)
if (cd_num >= 0)
_system->getAudioCDManager()->openCD(cd_num);
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
bool native_mt32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32"));
//bool adlib = (MidiDriver::getMusicType(dev) == MT_ADLIB);
_driver = MidiDriver::createMidi(dev);
if (native_mt32)
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
_midiMusic = new MidiMusicPlayer(_driver);
_midiMusic = new MidiMusicPlayer();
_pcmMusic = new PCMMusicPlayer();
//_midiMusic->setNativeMT32(native_mt32);
//_midiMusic->setAdLib(adlib);
if (native_mt32)
_driver->sendMT32Reset();
else
_driver->sendGMReset();
_musicVolume = ConfMan.getInt("music_volume");
@ -896,7 +881,6 @@ TinselEngine::~TinselEngine() {
delete _midiMusic;
delete _pcmMusic;
delete _console;
delete _driver;
_screenSurface.free();
FreeSaveScenes();
FreeTextBuffer();

View File

@ -36,11 +36,34 @@ MidiPlayer::MidiPlayer()
: _driver(0), _parser(0), _midiData(0), _isLooping(false), _isPlaying(false), _masterVolume(0) {
memset(_channelsTable, 0, sizeof(_channelsTable));
memset(_channelsVolume, 0, sizeof(_channelsVolume));
open();
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
_nativeMT32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32"));
_driver = MidiDriver::createMidi(dev);
int ret = _driver->open();
if (ret == 0) {
_parser = MidiParser::createParser_SMF();
_parser->setMidiDriver(this);
_parser->setTimerRate(_driver->getBaseTempo());
_driver->setTimerCallback(this, &timerCallback);
if (_nativeMT32)
_driver->sendMT32Reset();
else
_driver->sendGMReset();
}
}
MidiPlayer::~MidiPlayer() {
close();
stop();
Common::StackLock lock(_mutex);
_driver->setTimerCallback(NULL, NULL);
_driver->close();
delete _driver;
_driver = 0;
_parser->setMidiDriver(NULL);
delete _parser;
}
void MidiPlayer::play(Common::ReadStream &stream, int size, bool loop) {
@ -88,37 +111,6 @@ void MidiPlayer::setVolume(int volume) {
}
}
int MidiPlayer::open() {
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
_nativeMT32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32"));
_driver = MidiDriver::createMidi(dev);
int ret = _driver->open();
if (ret == 0) {
_parser = MidiParser::createParser_SMF();
_parser->setMidiDriver(this);
_parser->setTimerRate(_driver->getBaseTempo());
_driver->setTimerCallback(this, &timerCallback);
if (_nativeMT32)
_driver->sendMT32Reset();
else
_driver->sendGMReset();
}
return ret;
}
void MidiPlayer::close() {
stop();
Common::StackLock lock(_mutex);
_driver->setTimerCallback(NULL, NULL);
_driver->close();
delete _driver;
_driver = 0;
_parser->setMidiDriver(NULL);
delete _parser;
}
void MidiPlayer::send(uint32 b) {
byte volume, ch = (byte)(b & 0xF);
switch (b & 0xFFF0) {

View File

@ -57,11 +57,9 @@ public:
int getVolume() const { return _masterVolume; }
void setLooping(bool loop) { _isLooping = loop; }
// MidiDriver interface
int open();
void close();
void send(uint32 b);
void metaEvent(byte type, byte *data, uint16 length);
// MidiDriver_BASE interface
virtual void send(uint32 b);
virtual void metaEvent(byte type, byte *data, uint16 length);
private: