From e76a8a8eb6c68b1ffc048385c41cd1b542623449 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Thu, 24 Mar 2011 16:40:11 +0100 Subject: M4: Change MidiPlayer to derive from Audio::MidiPlayer Also fix the _driver double delete regression I recently introduced --- engines/m4/m4.cpp | 13 ++------- engines/m4/m4.h | 1 - engines/m4/midi.cpp | 76 +++++++++++------------------------------------------ engines/m4/midi.h | 27 +++---------------- 4 files changed, 22 insertions(+), 95 deletions(-) diff --git a/engines/m4/m4.cpp b/engines/m4/m4.cpp index d8d25f6895..4cc2bf8783 100644 --- a/engines/m4/m4.cpp +++ b/engines/m4/m4.cpp @@ -151,7 +151,6 @@ MadsM4Engine::~MadsM4Engine() { delete _palette; delete _globals; delete _sound; - delete _driver; delete _resourceManager; } @@ -159,16 +158,8 @@ Common::Error MadsM4Engine::run() { // Initialize backend _screen = new M4Surface(true); // Special form for creating screen reference - MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM); - bool native_mt32 = ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32")); - - _driver = MidiDriver::createMidi(dev); - if (native_mt32) - _driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); - - _midi = new MidiPlayer(this, _driver); - _midi->setGM(true); - _midi->setNativeMT32(native_mt32); + _midi = new MidiPlayer(this); + _midi->setGM(true); // FIXME: Really? Always? _saveLoad = new SaveLoad(this); _palette = new Palette(this); diff --git a/engines/m4/m4.h b/engines/m4/m4.h index f665df262b..a43f3e1387 100644 --- a/engines/m4/m4.h +++ b/engines/m4/m4.h @@ -148,7 +148,6 @@ protected: void shutdown(); - MidiDriver *_driver; MidiPlayer *_midi; public: diff --git a/engines/m4/midi.cpp b/engines/m4/midi.cpp index f4fe00319c..b982fc8129 100644 --- a/engines/m4/midi.cpp +++ b/engines/m4/midi.cpp @@ -28,14 +28,22 @@ #include "m4/m4.h" #include "m4/midi.h" +#include "audio/midiparser.h" +#include "common/config-manager.h" #include "common/memstream.h" namespace M4 { -MidiPlayer::MidiPlayer(MadsM4Engine *vm, MidiDriver *driver) : _vm(vm), _midiData(NULL), _driver(driver), _isPlaying(false), _isGM(false) { +MidiPlayer::MidiPlayer(MadsM4Engine *vm) : _vm(vm), _midiData(NULL), _isGM(false) { + + 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); assert(_driver); - memset(_channel, 0, sizeof(_channel)); - _masterVolume = 0; + if (_nativeMT32) + _driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); + _parser = MidiParser::createParser_SMF(); _parser->setMidiDriver(this); _parser->setTimerRate(_driver->getBaseTempo()); @@ -48,7 +56,7 @@ MidiPlayer::MidiPlayer(MadsM4Engine *vm, MidiDriver *driver) : _vm(vm), _midiDat MidiPlayer::~MidiPlayer() { _driver->setTimerCallback(NULL, NULL); _parser->setMidiDriver(NULL); - stopMusic(); + stop(); if (_driver) { _driver->close(); delete _driver; @@ -58,64 +66,12 @@ MidiPlayer::~MidiPlayer() { free(_midiData); } -void MidiPlayer::setVolume(int volume) { - Common::StackLock lock(_mutex); - - if (volume < 0) - volume = 0; - else if (volume > 255) - volume = 255; - - if (_masterVolume == volume) - return; - - _masterVolume = volume; - - for (int i = 0; i < 16; ++i) { - if (_channel[i]) { - _channel[i]->volume(_channelVolume[i] * _masterVolume / 255); - } - } -} - void MidiPlayer::send(uint32 b) { - byte channel = (byte)(b & 0x0F); - if ((b & 0xFFF0) == 0x07B0) { - // Adjust volume changes by master volume - byte volume = (byte)((b >> 16) & 0x7F); - _channelVolume[channel] = volume; - volume = volume * _masterVolume / 255; - b = (b & 0xFF00FFFF) | (volume << 16); - } else if ((b & 0xF0) == 0xC0 && !_isGM && !_nativeMT32) { + if ((b & 0xF0) == 0xC0 && !_isGM && !_nativeMT32) { b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8; } - else if ((b & 0xFFF0) == 0x007BB0) { - //Only respond to All Notes Off if this channel - //has currently been allocated - if (!_channel[b & 0x0F]) - return; - } - if (!_channel[channel]) - _channel[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel(); - - if (_channel[channel]) - _channel[channel]->send(b); -} - -void MidiPlayer::metaEvent(byte type, byte *data, uint16 length) { - switch (type) { - case 0x2F: - // End of track. (Not called when auto-looping.) - stopMusic(); - break; - case 0x51: - // Set tempo. Handled by the standard MIDI parser already. - break; - default: - warning("Unhandled meta event: %02x", type); - break; - } + Audio::MidiPlayer::send(b); } void MidiPlayer::onTimer(void *refCon) { @@ -127,7 +83,7 @@ void MidiPlayer::onTimer(void *refCon) { } void MidiPlayer::playMusic(const char *name, int32 vol, bool loop, int32 trigger, int32 scene) { - stopMusic(); + stop(); char fullname[144]; _vm->res()->changeExtension(fullname, name, "HMP"); @@ -157,7 +113,7 @@ void MidiPlayer::playMusic(const char *name, int32 vol, bool loop, int32 trigger _isPlaying = true; } -void MidiPlayer::stopMusic() { +void MidiPlayer::stop() { Common::StackLock lock(_mutex); _isPlaying = false; diff --git a/engines/m4/midi.h b/engines/m4/midi.h index cc3f62621d..e1f92cd4b6 100644 --- a/engines/m4/midi.h +++ b/engines/m4/midi.h @@ -28,32 +28,22 @@ #ifndef M4_MIDI_H #define M4_MIDI_H -#include "audio/mididrv.h" -#include "audio/midiparser.h" -#include "common/mutex.h" +#include "audio/midiplayer.h" namespace M4 { -class MidiPlayer : public MidiDriver_BASE { +class MidiPlayer : public Audio::MidiPlayer { public: - MidiPlayer(MadsM4Engine *vm, MidiDriver *driver); + MidiPlayer(MadsM4Engine *vm); ~MidiPlayer(); - bool isPlaying() const { return _isPlaying; } - - void setVolume(int volume); - int getVolume() const { return _masterVolume; } - - void setNativeMT32(bool b) { _nativeMT32 = b; } - bool hasNativeMT32() const{ return _nativeMT32; } void playMusic(const char *name, int32 vol, bool loop, int32 trigger, int32 scene); - void stopMusic(); + virtual void stop(); void setGM(bool isGM) { _isGM = isGM; } // MidiDriver_BASE interface implementation virtual void send(uint32 b); - virtual void metaEvent(byte type, byte *data, uint16 length); protected: static void onTimer(void *data); @@ -61,23 +51,14 @@ protected: MadsM4Engine *_vm; byte *_midiData; - MidiChannel *_channel[16]; - MidiDriver *_driver; - MidiParser *_parser; - byte _channelVolume[16]; - bool _nativeMT32; bool _isGM; - bool _isPlaying; bool _randomLoop; - byte _masterVolume; byte *_musicData; uint16 *_buf; size_t _musicDataSize; - Common::Mutex _mutex; - byte *convertHMPtoSMF(byte *data, uint32 inSize, uint32 &outSize); }; -- cgit v1.2.3