aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--audio/midiplayer.cpp44
-rw-r--r--audio/midiplayer.h73
-rw-r--r--engines/agi/sound_midi.cpp37
-rw-r--r--engines/agi/sound_midi.h13
-rw-r--r--engines/draci/music.cpp42
-rw-r--r--engines/draci/music.h9
-rw-r--r--engines/hugo/sound.cpp81
-rw-r--r--engines/hugo/sound.h8
-rw-r--r--engines/m4/midi.cpp55
-rw-r--r--engines/m4/midi.h5
-rw-r--r--engines/made/music.cpp43
-rw-r--r--engines/made/music.h7
-rw-r--r--engines/parallaction/sound_br.cpp61
-rw-r--r--engines/parallaction/sound_ns.cpp55
-rw-r--r--engines/tinsel/music.cpp8
-rw-r--r--engines/touche/midi.cpp43
-rw-r--r--engines/touche/midi.h9
17 files changed, 188 insertions, 405 deletions
diff --git a/audio/midiplayer.cpp b/audio/midiplayer.cpp
index d797ba281d..1e39b999f9 100644
--- a/audio/midiplayer.cpp
+++ b/audio/midiplayer.cpp
@@ -33,6 +33,7 @@ namespace Audio {
MidiPlayer::MidiPlayer() :
_driver(0),
_parser(0),
+ _midiData(0),
_isLooping(false),
_isPlaying(false),
_masterVolume(0),
@@ -45,19 +46,29 @@ MidiPlayer::MidiPlayer() :
}
MidiPlayer::~MidiPlayer() {
-// TODO
+ // FIXME/TODO: In some engines, stop() was called first;
+ // in others, _driver->setTimerCallback(NULL, NULL) came first.
+ // Hopefully, this make no real difference, but we should
+ // watch out for regressions.
+ stop();
+
+ // Unhook & unload the driver
+ if (_driver) {
+ _driver->setTimerCallback(0, 0);
+ _driver->close();
+ delete _driver;
+ _driver = 0;
+ }
}
void MidiPlayer::setVolume(int volume) {
volume = CLIP(volume, 0, 255);
-
if (_masterVolume == volume)
return;
Common::StackLock lock(_mutex);
_masterVolume = volume;
-
for (int i = 0; i < kNumChannels; ++i) {
if (_channelsTable[i]) {
_channelsTable[i]->volume(_channelsVolume[i] * _masterVolume / 255);
@@ -123,8 +134,7 @@ void MidiPlayer::endOfTrack() {
stop();
}
-#if 0
-void MidiPlayer::onTimer(void *data) {
+void MidiPlayer::timerCallback(void *data) {
assert(data);
((MidiPlayer *)data)->onTimer();
}
@@ -132,20 +142,13 @@ void MidiPlayer::onTimer(void *data) {
void MidiPlayer::onTimer() {
Common::StackLock lock(_mutex);
- // FIXME: There are various alternatives for this function:
+ // TODO: Maybe we can replace _isPlaying
+ // by a simple check for "_parser != 0" ?
-#if 0
- if (_parser) {
+ if (_isPlaying && _parser) {
_parser->onTimer();
}
-#elif 0
- if (_isPlaying) {
- assert(_parser);
- _parser->onTimer();
- }
-#endif
}
-#endif
void MidiPlayer::stop() {
@@ -154,8 +157,19 @@ void MidiPlayer::stop() {
_isPlaying = false;
if (_parser) {
_parser->unloadMusic();
+
+ // FIXME/TODO: The MidiParser destructor calls allNotesOff()
+ // but unloadMusic also does. To suppress double notes-off,
+ // we reset the midi driver of _parser before deleting it.
+ // This smells very fishy, in any case.
+ _parser->setMidiDriver(0);
+
+ delete _parser;
_parser = NULL;
}
+
+ free(_midiData);
+ _midiData = 0;
}
void MidiPlayer::pause() {
diff --git a/audio/midiplayer.h b/audio/midiplayer.h
index 7815489e0d..1bb7942343 100644
--- a/audio/midiplayer.h
+++ b/audio/midiplayer.h
@@ -47,11 +47,10 @@ namespace Audio {
* should perform memory management on the MidiParser object(s) being
* used, and possibly more.
*
- * Also, care should be taken to ensure that mutex locking is done right;
- * currently, it isn't: That is, many engines have (and already had before
- * this class was introduced) various potential deadlocks hiding in their
- * MIDI code, caused by a thread trying to lock a mutex twice -- this may
- * work on some systems, but on others is a sure way towards a deadlock.
+ * Also, pause/resume handling should be unified (we provide an implementation,
+ * but several subclasses use different ones).
+ *
+ * Also, care should be taken to ensure that mutex locking is done right.
*
* @todo Document origin of this class. It is based on code shared by
* several engines (e.g. DRACI says it copied it from MADE, which took
@@ -64,6 +63,7 @@ public:
// TODO: Implement ways to actually play stuff
//virtual void play(TODO);
+
// TODO: Document these
virtual void stop();
virtual void pause();
@@ -71,19 +71,42 @@ public:
bool isPlaying() const { return _isPlaying; }
+ /**
+ * Return the currently active master volume, in the range 0-255.
+ */
int getVolume() const { return _masterVolume; }
- virtual void setVolume(int volume); // FIXME: Overloaded by Tinsel
+
+ /**
+ * Set the master volume to the specified value in the range 0-255.
+ * (values outside this range are automatically clipped).
+ * This may cause suitable MIDI events to be sent to active channels.
+ *
+ * @todo This method currently does not do anything if the new volume
+ * matches the old volume. But some engines always update the
+ * volume (Parallaction, Tinsel, Touche, ...). This is why
+ * this method is currently virtual. We really should figure
+ * which way to do it, and then make this the default, and make
+ * this method non-virtual again.
+ */
+ virtual void setVolume(int volume);
+
+ /**
+ * Update the volume according to the ConfMan's 'music_volume'
+ * setting. also respects the 'mute' setting.
+ */
void syncVolume();
+ // TODO: Document this
bool hasNativeMT32() const { return _nativeMT32; }
- // MidiDriver_BASE interface
+ // MidiDriver_BASE implementation
virtual void send(uint32 b);
virtual void metaEvent(byte type, byte *data, uint16 length);
+protected:
/**
- * This method is invoked by send() after suitably filtering
- * the message b.
+ * This method is invoked by the default send() implementation,
+ * after suitably filtering the message b.
*/
virtual void sendToChannel(byte ch, uint32 b);
@@ -96,28 +119,46 @@ public:
*/
virtual void endOfTrack();
-protected:
-
-#if 0
- // TODO: Start to make use of these, once we figured
- // out the right way :)
- static void onTimer(void *data);
+ // TODO: Document this
virtual void onTimer();
-#endif
+
+ static void timerCallback(void *data);
enum {
+ /**
+ * The number of MIDI channels supported.
+ */
kNumChannels = 16
};
Common::Mutex _mutex;
MidiDriver *_driver;
+
+ /**
+ * A MidiParser instances, to be created by methods of a MidiPlayer
+ * subclass.
+ * @note The stop() method (and hence the destructor) invoke the
+ * unloadMusic() method of _parser and then delete it.
+ */
MidiParser *_parser;
+ /**
+ * This is an (optional) pointer to a malloc'ed buffer containing
+ * MIDI data used by _parser. The stop() method (and hence the
+ * destructor) will free this if set.
+ * Subclasses of this class may use _midiData, but don't have to
+ */
+ byte *_midiData;
+
MidiChannel *_channelsTable[kNumChannels];
uint8 _channelsVolume[kNumChannels];
bool _isLooping;
bool _isPlaying;
+
+ /**
+ * The master volume, in the range 0-255.
+ */
int _masterVolume; // FIXME: byte or int ?
bool _nativeMT32;
diff --git a/engines/agi/sound_midi.cpp b/engines/agi/sound_midi.cpp
index 2c6a189fbd..ff23a70808 100644
--- a/engines/agi/sound_midi.cpp
+++ b/engines/agi/sound_midi.cpp
@@ -90,24 +90,11 @@ SoundGenMIDI::SoundGenMIDI(AgiEngine *vm, Audio::Mixer *pMixer) : SoundGen(vm, p
else
_driver->sendGMReset();
- _driver->setTimerCallback(this, &onTimer);
+ // FIXME: We need to cast "this" here due to the effects of
+ // multiple inheritance. This hack can go away once this
+ // setTimerCallback() has been moved inside Audio::MidiPlayer code.
+ _driver->setTimerCallback(static_cast<Audio::MidiPlayer *>(this), &timerCallback);
}
-
- _smfParser = MidiParser::createParser_SMF();
- _midiMusicData = NULL;
-}
-
-SoundGenMIDI::~SoundGenMIDI() {
- _driver->setTimerCallback(NULL, NULL);
- stop();
- if (_driver) {
- _driver->close();
- delete _driver;
- _driver = 0;
- }
- _smfParser->setMidiDriver(NULL);
- delete _smfParser;
- delete[] _midiMusicData;
}
void SoundGenMIDI::send(uint32 b) {
@@ -136,14 +123,6 @@ void SoundGenMIDI::endOfTrack() {
_vm->_sound->soundIsFinished();
}
-void SoundGenMIDI::onTimer(void *refCon) {
- SoundGenMIDI *music = (SoundGenMIDI *)refCon;
- Common::StackLock lock(music->_mutex);
-
- if (music->_parser)
- music->_parser->onTimer();
-}
-
void SoundGenMIDI::play(int resnum) {
MIDISound *track;
@@ -154,10 +133,10 @@ void SoundGenMIDI::play(int resnum) {
track = (MIDISound *)_vm->_game.sounds[resnum];
// Convert AGI Sound data to MIDI
- int midiMusicSize = convertSND2MIDI(track->_data, &_midiMusicData);
+ int midiMusicSize = convertSND2MIDI(track->_data, &_midiData);
- if (_smfParser->loadMusic(_midiMusicData, midiMusicSize)) {
- MidiParser *parser = _smfParser;
+ MidiParser *parser = MidiParser::createParser_SMF();
+ if (parser->loadMusic(_midiData, midiMusicSize)) {
parser->setTrack(0);
parser->setMidiDriver(this);
parser->setTimerRate(_driver->getBaseTempo());
@@ -168,6 +147,8 @@ void SoundGenMIDI::play(int resnum) {
syncVolume();
_isPlaying = true;
+ } else {
+ delete parser;
}
}
diff --git a/engines/agi/sound_midi.h b/engines/agi/sound_midi.h
index 9551673a4e..5733358fee 100644
--- a/engines/agi/sound_midi.h
+++ b/engines/agi/sound_midi.h
@@ -28,6 +28,8 @@
#ifndef AGI_SOUND_MIDI_H
#define AGI_SOUND_MIDI_H
+#include "agi/sound.h"
+
#include "audio/midiplayer.h"
namespace Agi {
@@ -47,13 +49,12 @@ protected:
class SoundGenMIDI : public SoundGen, public Audio::MidiPlayer {
public:
SoundGenMIDI(AgiEngine *vm, Audio::Mixer *pMixer);
- ~SoundGenMIDI();
void play(int resnum);
+ // We must overload stop() here to implement the pure virtual
+ // stop() method of the SoundGen class.
void stop() { Audio::MidiPlayer::stop(); }
- void setGM(bool isGM) { _isGM = isGM; }
-
// MidiDriver_BASE interface implementation
virtual void send(uint32 b);
@@ -62,14 +63,8 @@ public:
virtual void endOfTrack();
private:
-
- static void onTimer(void *data);
-
- MidiParser *_smfParser;
bool _isGM;
- byte *_midiMusicData;
-
SoundMgr *_manager;
};
diff --git a/engines/draci/music.cpp b/engines/draci/music.cpp
index 77f51544d5..242e58e92c 100644
--- a/engines/draci/music.cpp
+++ b/engines/draci/music.cpp
@@ -47,9 +47,6 @@ MusicPlayer::MusicPlayer(const char *pathMask) : _pathMask(pathMask), _isGM(fals
if (_nativeMT32)
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
- _smfParser = MidiParser::createParser_SMF();
- _midiMusicData = NULL;
-
int ret = _driver->open();
if (ret == 0) {
if (_nativeMT32)
@@ -61,21 +58,8 @@ MusicPlayer::MusicPlayer(const char *pathMask) : _pathMask(pathMask), _isGM(fals
// 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();
- if (_driver) {
- _driver->close();
- delete _driver;
- _driver = 0;
+ _driver->setTimerCallback(this, &timerCallback);
}
- _smfParser->setMidiDriver(NULL);
- delete _smfParser;
- delete[] _midiMusicData;
}
void MusicPlayer::sendToChannel(byte channel, uint32 b) {
@@ -91,15 +75,9 @@ void MusicPlayer::sendToChannel(byte channel, uint32 b) {
_channelsTable[channel]->send(b);
}
-void MusicPlayer::onTimer(void *refCon) {
- MusicPlayer *music = (MusicPlayer *)refCon;
- Common::StackLock lock(music->_mutex);
-
- if (music->_parser)
- music->_parser->onTimer();
-}
-
void MusicPlayer::playSMF(int track, bool loop) {
+ Common::StackLock lock(_mutex);
+
if (_isPlaying && track == _track) {
debugC(2, kDraciSoundDebugLevel, "Already plaing track %d", track);
return;
@@ -109,24 +87,23 @@ void MusicPlayer::playSMF(int track, bool loop) {
_isGM = true;
-
// Load MIDI resource data
Common::File musicFile;
char musicFileName[40];
- sprintf(musicFileName, _pathMask.c_str(), track);
+ snprintf(musicFileName, sizeof(musicFileName), _pathMask.c_str(), track);
musicFile.open(musicFileName);
if (!musicFile.isOpen()) {
debugC(2, kDraciSoundDebugLevel, "Cannot open track %d", track);
return;
}
int midiMusicSize = musicFile.size();
- delete[] _midiMusicData;
- _midiMusicData = new byte[midiMusicSize];
- musicFile.read(_midiMusicData, midiMusicSize);
+ free(_midiData);
+ _midiData = (byte *)malloc(midiMusicSize);
+ musicFile.read(_midiData, midiMusicSize);
musicFile.close();
- if (_smfParser->loadMusic(_midiMusicData, midiMusicSize)) {
- MidiParser *parser = _smfParser;
+ MidiParser *parser = MidiParser::createParser_SMF();
+ if (parser->loadMusic(_midiData, midiMusicSize)) {
parser->setTrack(0);
parser->setMidiDriver(this);
parser->setTimerRate(_driver->getBaseTempo());
@@ -142,6 +119,7 @@ void MusicPlayer::playSMF(int track, bool loop) {
debugC(2, kDraciSoundDebugLevel, "Playing track %d", track);
} else {
debugC(2, kDraciSoundDebugLevel, "Cannot play track %d", track);
+ delete parser;
}
}
diff --git a/engines/draci/music.h b/engines/draci/music.h
index a1d0aaacb6..c0228074e5 100644
--- a/engines/draci/music.h
+++ b/engines/draci/music.h
@@ -37,27 +37,18 @@ namespace Draci {
class MusicPlayer : public Audio::MidiPlayer {
public:
MusicPlayer(const char *pathMask);
- ~MusicPlayer();
void playSMF(int track, bool loop);
void stop();
- void setGM(bool isGM) { _isGM = isGM; }
-
// Overload Audio::MidiPlayer method
virtual void sendToChannel(byte channel, uint32 b);
protected:
-
- static void onTimer(void *data);
-
- MidiParser *_smfParser;
Common::String _pathMask;
bool _isGM;
int _track;
-
- byte *_midiMusicData;
};
} // End of namespace Draci
diff --git a/engines/hugo/sound.cpp b/engines/hugo/sound.cpp
index f0a08829ed..24359a2c54 100644
--- a/engines/hugo/sound.cpp
+++ b/engines/hugo/sound.cpp
@@ -47,61 +47,46 @@
namespace Hugo {
-MidiPlayer::MidiPlayer()
- : _midiData(0) {
-
+MidiPlayer::MidiPlayer() {
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
_driver = MidiDriver::createMidi(dev);
assert(_driver);
_paused = false;
-}
-MidiPlayer::~MidiPlayer() {
- stop();
- Common::StackLock lock(_mutex);
- _driver->setTimerCallback(0, 0);
- _driver->close();
- delete _driver;
- _driver = 0;
- if (_parser)
- _parser->setMidiDriver(0);
- delete _parser;
+ int ret = _driver->open();
+ if (ret == 0) {
+ _driver->sendGMReset();
+
+ _driver->setTimerCallback(this, &timerCallback);
+ }
}
void MidiPlayer::play(uint8 *stream, uint16 size) {
debugC(3, kDebugMusic, "MidiPlayer::play");
- if (!stream) {
- stop();
- return;
- }
+
+ Common::StackLock lock(_mutex);
stop();
+ if (!stream)
+ return;
+
_midiData = (uint8 *)malloc(size);
if (_midiData) {
memcpy(_midiData, stream, size);
- Common::StackLock lock(_mutex);
syncVolume(); // FIXME: syncVolume calls setVolume which in turn also locks the mutex! ugh
+
+ _parser = MidiParser::createParser_SMF();
_parser->loadMusic(_midiData, size);
_parser->setTrack(0);
+ _parser->setMidiDriver(this);
+ _parser->setTimerRate(_driver->getBaseTempo());
_isLooping = false;
_isPlaying = true;
}
}
-void MidiPlayer::stop() {
- debugC(3, kDebugMusic, "MidiPlayer::stop");
-
- Common::StackLock lock(_mutex);
- if (_isPlaying) {
- _isPlaying = false;
- _parser->unloadMusic();
- free(_midiData);
- _midiData = 0;
- }
-}
-
void MidiPlayer::pause(bool p) {
_paused = p;
@@ -112,34 +97,14 @@ void MidiPlayer::pause(bool p) {
}
}
-void MidiPlayer::updateTimer() {
- if (_paused) {
- return;
- }
-
+void MidiPlayer::onTimer() {
Common::StackLock lock(_mutex);
- if (_isPlaying) {
+
+ if (!_paused && _isPlaying && _parser) {
_parser->onTimer();
}
}
-int MidiPlayer::open() {
- if (!_driver)
- return 255;
- int ret = _driver->open();
- if (ret)
- return ret;
-
- _driver->sendGMReset();
-
- _parser = MidiParser::createParser_SMF();
- _parser->setMidiDriver(this);
- _parser->setTimerRate(_driver->getBaseTempo());
- _driver->setTimerCallback(this, &timerCallback);
-
- return 0;
-}
-
void MidiPlayer::sendToChannel(byte channel, uint32 b) {
if (!_channelsTable[channel]) {
_channelsTable[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel();
@@ -154,12 +119,6 @@ void MidiPlayer::sendToChannel(byte channel, uint32 b) {
}
-void MidiPlayer::timerCallback(void *p) {
- MidiPlayer *player = (MidiPlayer *)p;
-
- player->updateTimer();
-}
-
SoundHandler::SoundHandler(HugoEngine *vm) : _vm(vm) {
_midiPlayer = new MidiPlayer();
_speakerStream = new Audio::PCSpeaker(_vm->_mixer->getOutputRate());
@@ -263,7 +222,7 @@ void SoundHandler::playSound(int16 sound, const byte priority) {
* Initialize for MCI sound and midi
*/
void SoundHandler::initSound() {
- _midiPlayer->open();
+ //_midiPlayer->open();
}
void SoundHandler::syncVolume() {
diff --git a/engines/hugo/sound.h b/engines/hugo/sound.h
index f3a141ac1e..d5f51704aa 100644
--- a/engines/hugo/sound.h
+++ b/engines/hugo/sound.h
@@ -42,23 +42,17 @@ namespace Hugo {
class MidiPlayer : public Audio::MidiPlayer {
public:
MidiPlayer();
- ~MidiPlayer();
void pause(bool p);
void play(uint8 *stream, uint16 size);
- void stop();
- void updateTimer();
- int open();
uint32 getBaseTempo();
// Overload Audio::MidiPlayer method
virtual void sendToChannel(byte channel, uint32 b);
+ virtual void onTimer();
private:
- static void timerCallback(void *p);
-
- uint8 *_midiData;
bool _paused;
};
diff --git a/engines/m4/midi.cpp b/engines/m4/midi.cpp
index b982fc8129..d58b92bf01 100644
--- a/engines/m4/midi.cpp
+++ b/engines/m4/midi.cpp
@@ -34,7 +34,7 @@
namespace M4 {
-MidiPlayer::MidiPlayer(MadsM4Engine *vm) : _vm(vm), _midiData(NULL), _isGM(false) {
+MidiPlayer::MidiPlayer(MadsM4Engine *vm) : _vm(vm), _isGM(false) {
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
_nativeMT32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32"));
@@ -44,26 +44,10 @@ MidiPlayer::MidiPlayer(MadsM4Engine *vm) : _vm(vm), _midiData(NULL), _isGM(false
if (_nativeMT32)
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
- _parser = MidiParser::createParser_SMF();
- _parser->setMidiDriver(this);
- _parser->setTimerRate(_driver->getBaseTempo());
-
int ret = _driver->open();
- if (ret == 0)
- _driver->setTimerCallback(this, &onTimer);
-}
-
-MidiPlayer::~MidiPlayer() {
- _driver->setTimerCallback(NULL, NULL);
- _parser->setMidiDriver(NULL);
- stop();
- if (_driver) {
- _driver->close();
- delete _driver;
+ if (ret == 0) {
+ _driver->setTimerCallback(this, &timerCallback);
}
- _driver = 0;
- delete _parser;
- free(_midiData);
}
void MidiPlayer::send(uint32 b) {
@@ -74,15 +58,9 @@ void MidiPlayer::send(uint32 b) {
Audio::MidiPlayer::send(b);
}
-void MidiPlayer::onTimer(void *refCon) {
- MidiPlayer *midi = (MidiPlayer *)refCon;
- Common::StackLock lock(midi->_mutex);
-
- if (midi->_isPlaying)
- midi->_parser->onTimer();
-}
-
void MidiPlayer::playMusic(const char *name, int32 vol, bool loop, int32 trigger, int32 scene) {
+ Common::StackLock lock(_mutex);
+
stop();
char fullname[144];
@@ -99,11 +77,10 @@ void MidiPlayer::playMusic(const char *name, int32 vol, bool loop, int32 trigger
_vm->res()->purge();
if (_midiData) {
- /*
- FILE *out = fopen("music.mid", "wb");
- fwrite(_midiData, smfSize, 1, out);
- fclose(out);
- */
+ _parser = MidiParser::createParser_SMF();
+ _parser->setMidiDriver(this);
+ _parser->setTimerRate(_driver->getBaseTempo());
+
_parser->loadMusic(_midiData, smfSize);
_parser->property(MidiParser::mpAutoLoop, loop);
}
@@ -113,20 +90,6 @@ void MidiPlayer::playMusic(const char *name, int32 vol, bool loop, int32 trigger
_isPlaying = true;
}
-void MidiPlayer::stop() {
- Common::StackLock lock(_mutex);
-
- _isPlaying = false;
- if (_parser) {
- _parser->unloadMusic();
- }
-
- if (_midiData) {
- free(_midiData);
- _midiData = NULL;
- }
-}
-
// This function will convert HMP music into type 1 SMF, which our SMF parser
// will be able to handle. It is based on Hans de Goede's HMP 2 MIDI file
// converter, which in turn is "based on the conversion algorithms found in
diff --git a/engines/m4/midi.h b/engines/m4/midi.h
index e1f92cd4b6..a544fb72aa 100644
--- a/engines/m4/midi.h
+++ b/engines/m4/midi.h
@@ -35,10 +35,8 @@ namespace M4 {
class MidiPlayer : public Audio::MidiPlayer {
public:
MidiPlayer(MadsM4Engine *vm);
- ~MidiPlayer();
void playMusic(const char *name, int32 vol, bool loop, int32 trigger, int32 scene);
- virtual void stop();
void setGM(bool isGM) { _isGM = isGM; }
@@ -46,10 +44,7 @@ public:
virtual void send(uint32 b);
protected:
- static void onTimer(void *data);
-
MadsM4Engine *_vm;
- byte *_midiData;
bool _isGM;
diff --git a/engines/made/music.cpp b/engines/made/music.cpp
index 054f8126d6..c8b13ba210 100644
--- a/engines/made/music.cpp
+++ b/engines/made/music.cpp
@@ -47,9 +47,6 @@ MusicPlayer::MusicPlayer() : _isGM(false) {
if (_nativeMT32)
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
- _xmidiParser = MidiParser::createParser_XMIDI();
- _smfParser = MidiParser::createParser_SMF();
-
int ret = _driver->open();
if (ret == 0) {
if (_nativeMT32)
@@ -57,22 +54,8 @@ MusicPlayer::MusicPlayer() : _isGM(false) {
else
_driver->sendGMReset();
- _driver->setTimerCallback(this, &onTimer);
- }
-}
-
-MusicPlayer::~MusicPlayer() {
- _driver->setTimerCallback(NULL, NULL);
- stop();
- if (_driver) {
- _driver->close();
- delete _driver;
- _driver = 0;
+ _driver->setTimerCallback(this, &timerCallback);
}
- _xmidiParser->setMidiDriver(NULL);
- _smfParser->setMidiDriver(NULL);
- delete _xmidiParser;
- delete _smfParser;
}
void MusicPlayer::send(uint32 b) {
@@ -83,15 +66,9 @@ void MusicPlayer::send(uint32 b) {
Audio::MidiPlayer::send(b);
}
-void MusicPlayer::onTimer(void *refCon) {
- MusicPlayer *music = (MusicPlayer *)refCon;
- Common::StackLock lock(music->_mutex);
-
- if (music->_isPlaying)
- music->_parser->onTimer();
-}
-
void MusicPlayer::playXMIDI(GenericResource *midiResource, MusicFlags flags) {
+ Common::StackLock lock(_mutex);
+
if (_isPlaying)
return;
@@ -101,8 +78,8 @@ void MusicPlayer::playXMIDI(GenericResource *midiResource, MusicFlags flags) {
_isGM = true;
- if (_xmidiParser->loadMusic(midiResource->getData(), midiResource->getSize())) {
- MidiParser *parser = _xmidiParser;
+ MidiParser *parser = MidiParser::createParser_XMIDI();
+ if (parser->loadMusic(midiResource->getData(), midiResource->getSize())) {
parser->setTrack(0);
parser->setMidiDriver(this);
parser->setTimerRate(_driver->getBaseTempo());
@@ -115,10 +92,14 @@ void MusicPlayer::playXMIDI(GenericResource *midiResource, MusicFlags flags) {
_isLooping = flags & MUSIC_LOOP;
_isPlaying = true;
+ } else {
+ delete parser;
}
}
void MusicPlayer::playSMF(GenericResource *midiResource, MusicFlags flags) {
+ Common::StackLock lock(_mutex);
+
if (_isPlaying)
return;
@@ -128,8 +109,8 @@ void MusicPlayer::playSMF(GenericResource *midiResource, MusicFlags flags) {
_isGM = true;
- if (_smfParser->loadMusic(midiResource->getData(), midiResource->getSize())) {
- MidiParser *parser = _smfParser;
+ MidiParser *parser = MidiParser::createParser_SMF();
+ if (parser->loadMusic(midiResource->getData(), midiResource->getSize())) {
parser->setTrack(0);
parser->setMidiDriver(this);
parser->setTimerRate(_driver->getBaseTempo());
@@ -141,6 +122,8 @@ void MusicPlayer::playSMF(GenericResource *midiResource, MusicFlags flags) {
_isLooping = flags & MUSIC_LOOP;
_isPlaying = true;
+ } else {
+ delete parser;
}
}
diff --git a/engines/made/music.h b/engines/made/music.h
index 8925440b75..f8f70cdad6 100644
--- a/engines/made/music.h
+++ b/engines/made/music.h
@@ -44,7 +44,6 @@ enum MusicFlags {
class MusicPlayer : public Audio::MidiPlayer {
public:
MusicPlayer();
- ~MusicPlayer();
void playXMIDI(GenericResource *midiResource, MusicFlags flags = MUSIC_NORMAL);
void playSMF(GenericResource *midiResource, MusicFlags flags = MUSIC_NORMAL);
@@ -52,16 +51,10 @@ public:
void pause();
void resume();
- void setGM(bool isGM) { _isGM = isGM; }
-
// MidiDriver_BASE interface implementation
virtual void send(uint32 b);
protected:
-
- static void onTimer(void *data);
-
- MidiParser *_xmidiParser, *_smfParser;
bool _isGM;
};
diff --git a/engines/parallaction/sound_br.cpp b/engines/parallaction/sound_br.cpp
index 9f807f5c73..ee53f9641e 100644
--- a/engines/parallaction/sound_br.cpp
+++ b/engines/parallaction/sound_br.cpp
@@ -205,30 +205,25 @@ class MidiPlayer_MSC : public Audio::MidiPlayer {
public:
MidiPlayer_MSC();
- ~MidiPlayer_MSC();
void play(Common::SeekableReadStream *stream);
- void stop();
- void pause(bool p);
- void updateTimer();
- void setVolume(int volume);
+ virtual void pause(bool p);
+ virtual void setVolume(int volume);
+ virtual void onTimer();
// MidiDriver_BASE interface
virtual void send(uint32 b);
-private:
- static void timerCallback(void *p);
+private:
void setVolumeInternal(int volume);
-
- uint8 *_midiData;
bool _paused;
};
MidiPlayer_MSC::MidiPlayer_MSC()
- : _midiData(0), _paused(false) {
+ : _paused(false) {
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
_driver = MidiDriver::createMidi(dev);
@@ -236,64 +231,42 @@ MidiPlayer_MSC::MidiPlayer_MSC()
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() {
- stop();
-
+void MidiPlayer_MSC::play(Common::SeekableReadStream *stream) {
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) {
- if (!stream) {
- stop();
+ stop();
+ if (!stream)
return;
- }
- stop();
int size = stream->size();
_midiData = (uint8 *)malloc(size);
if (_midiData) {
stream->read(_midiData, size);
delete stream;
- Common::StackLock lock(_mutex);
+ _parser = createParser_MSC();
_parser->loadMusic(_midiData, size);
_parser->setTrack(0);
+ _parser->setMidiDriver(this);
+ _parser->setTimerRate(_driver->getBaseTempo());
_isLooping = true;
_isPlaying = true;
}
}
-void MidiPlayer_MSC::stop() {
- Audio::MidiPlayer::stop();
- free(_midiData);
- _midiData = 0;
-}
-
void MidiPlayer_MSC::pause(bool p) {
_paused = p;
setVolumeInternal(_paused ? 0 : _masterVolume);
}
-void MidiPlayer_MSC::updateTimer() {
- if (_paused) {
- return;
- }
-
+void MidiPlayer_MSC::onTimer() {
Common::StackLock lock(_mutex);
- if (_isPlaying) {
+
+ if (!_paused && _isPlaying && _parser) {
_parser->onTimer();
}
}
@@ -329,12 +302,6 @@ void MidiPlayer_MSC::send(uint32 b) {
sendToChannel(ch, b);
}
-void MidiPlayer_MSC::timerCallback(void *p) {
- MidiPlayer_MSC *player = (MidiPlayer_MSC *)p;
-
- player->updateTimer();
-}
-
DosSoundMan_br::DosSoundMan_br(Parallaction_br *vm) : SoundMan_br(vm) {
_midiPlayer = new MidiPlayer_MSC();
assert(_midiPlayer);
diff --git a/engines/parallaction/sound_ns.cpp b/engines/parallaction/sound_ns.cpp
index 239ababb54..ba81314da6 100644
--- a/engines/parallaction/sound_ns.cpp
+++ b/engines/parallaction/sound_ns.cpp
@@ -43,22 +43,17 @@ class MidiPlayer : public Audio::MidiPlayer {
public:
MidiPlayer();
- ~MidiPlayer();
void play(Common::SeekableReadStream *stream);
- void stop();
void pause(bool p);
- void updateTimer();
+ virtual void onTimer();
private:
- static void timerCallback(void *p);
-
- uint8 *_midiData;
bool _paused;
};
MidiPlayer::MidiPlayer()
- : _midiData(0), _paused(false) {
+ : _paused(false) {
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
_driver = MidiDriver::createMidi(dev);
@@ -66,52 +61,33 @@ MidiPlayer::MidiPlayer()
int ret = _driver->open();
if (ret == 0) {
- _parser = MidiParser::createParser_SMF();
- _parser->setMidiDriver(this);
- _parser->setTimerRate(_driver->getBaseTempo());
_driver->setTimerCallback(this, &timerCallback);
}
}
-MidiPlayer::~MidiPlayer() {
- stop();
-
+void MidiPlayer::play(Common::SeekableReadStream *stream) {
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) {
- if (!stream) {
- stop();
+ stop();
+ if (!stream)
return;
- }
int size = stream->size();
-
_midiData = (uint8 *)malloc(size);
if (_midiData) {
stream->read(_midiData, size);
delete stream;
- Common::StackLock lock(_mutex);
+ _parser = MidiParser::createParser_SMF();
_parser->loadMusic(_midiData, size);
_parser->setTrack(0);
+ _parser->setMidiDriver(this);
+ _parser->setTimerRate(_driver->getBaseTempo());
_isLooping = true;
_isPlaying = true;
}
}
-void MidiPlayer::stop() {
- Audio::MidiPlayer::stop();
- free(_midiData);
- _midiData = 0;
-}
-
void MidiPlayer::pause(bool p) {
_paused = p;
@@ -122,23 +98,14 @@ void MidiPlayer::pause(bool p) {
}
}
-void MidiPlayer::updateTimer() {
- if (_paused) {
- return;
- }
-
+void MidiPlayer::onTimer() {
Common::StackLock lock(_mutex);
- if (_isPlaying) {
+
+ if (!_paused && _isPlaying && _parser) {
_parser->onTimer();
}
}
-void MidiPlayer::timerCallback(void *p) {
- MidiPlayer *player = (MidiPlayer *)p;
-
- player->updateTimer();
-}
-
DosSoundMan_ns::DosSoundMan_ns(Parallaction_ns *vm) : SoundMan_ns(vm), _playing(false) {
_midiPlayer = new MidiPlayer();
}
diff --git a/engines/tinsel/music.cpp b/engines/tinsel/music.cpp
index d53b98514d..3b9833b418 100644
--- a/engines/tinsel/music.cpp
+++ b/engines/tinsel/music.cpp
@@ -388,22 +388,22 @@ void DeleteMidiBuffer() {
MidiMusicPlayer::MidiMusicPlayer() {
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
- bool native_mt32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32"));
+ _nativeMT32 = ((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)
+ if (_nativeMT32)
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
int ret = _driver->open();
if (ret == 0) {
- if (native_mt32)
+ if (_nativeMT32)
_driver->sendMT32Reset();
else
_driver->sendGMReset();
- _driver->setTimerCallback(this, &onTimer);
+ _driver->setTimerCallback(this, &timerCallback);
}
}
diff --git a/engines/touche/midi.cpp b/engines/touche/midi.cpp
index bdf57880b8..c89375d876 100644
--- a/engines/touche/midi.cpp
+++ b/engines/touche/midi.cpp
@@ -44,8 +44,7 @@ static const uint8 _gmToRol[256] = {
};
-MidiPlayer::MidiPlayer()
- : _midiData(0) {
+MidiPlayer::MidiPlayer() {
// FIXME: Necessary?
memset(_channelsVolume, 0, sizeof(_channelsVolume));
@@ -55,9 +54,6 @@ MidiPlayer::MidiPlayer()
_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)
@@ -67,25 +63,18 @@ MidiPlayer::MidiPlayer()
}
}
-MidiPlayer::~MidiPlayer() {
- stop();
-
+void MidiPlayer::play(Common::ReadStream &stream, int size, bool loop) {
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) {
stop();
- _midiData = (uint8 *)malloc(size);
+ _midiData = (byte *)malloc(size);
if (_midiData) {
stream.read(_midiData, size);
- Common::StackLock lock(_mutex);
+ _parser = MidiParser::createParser_SMF();
+ _parser->setMidiDriver(this);
+ _parser->setTimerRate(_driver->getBaseTempo());
+
_parser->loadMusic(_midiData, size);
_parser->setTrack(0);
_isLooping = loop;
@@ -93,19 +82,6 @@ void MidiPlayer::play(Common::ReadStream &stream, int size, bool loop) {
}
}
-void MidiPlayer::stop() {
- Audio::MidiPlayer::stop();
- free(_midiData);
- _midiData = 0;
-}
-
-void MidiPlayer::updateTimer() {
- Common::StackLock lock(_mutex);
- if (_isPlaying) {
- _parser->onTimer();
- }
-}
-
void MidiPlayer::adjustVolume(int diff) {
setVolume(_masterVolume + diff);
}
@@ -135,9 +111,4 @@ void MidiPlayer::send(uint32 b) {
Audio::MidiPlayer::send(b);
}
-void MidiPlayer::timerCallback(void *p) {
- MidiPlayer *player = (MidiPlayer *)p;
- player->updateTimer();
-}
-
} // Touche namespace
diff --git a/engines/touche/midi.h b/engines/touche/midi.h
index 8f2f8507b7..f0f55e64e6 100644
--- a/engines/touche/midi.h
+++ b/engines/touche/midi.h
@@ -42,22 +42,13 @@ namespace Touche {
class MidiPlayer : public Audio::MidiPlayer {
public:
MidiPlayer();
- ~MidiPlayer();
void play(Common::ReadStream &stream, int size, bool loop = false);
- void stop();
- void updateTimer();
void adjustVolume(int diff);
void setVolume(int volume);
// MidiDriver_BASE interface
virtual void send(uint32 b);
-
-private:
-
- static void timerCallback(void *p);
-
- uint8 *_midiData;
};
} // namespace Touche