From f4b30ecf6ebb8095eddfc62bb1e832b83b9d6527 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Thu, 24 Mar 2011 16:35:07 +0100 Subject: AGI: Change SoundGenMIDI to derive from Audio::MidiPlayer As a side effect, this fixes the incorrect handling of 'All Note Off' in SoundGenMIDI::send. --- engines/agi/sound_midi.cpp | 102 +++++++-------------------------------------- engines/agi/sound_midi.h | 38 ++++------------- 2 files changed, 22 insertions(+), 118 deletions(-) (limited to 'engines') diff --git a/engines/agi/sound_midi.cpp b/engines/agi/sound_midi.cpp index b58e1e50ab..2c6a189fbd 100644 --- a/engines/agi/sound_midi.cpp +++ b/engines/agi/sound_midi.cpp @@ -71,7 +71,7 @@ MIDISound::MIDISound(uint8 *data, uint32 len, int resnum, SoundMgr &manager) : A warning("Error creating MIDI sound from resource %d (Type %d, length %d)", resnum, _type, len); } -SoundGenMIDI::SoundGenMIDI(AgiEngine *vm, Audio::Mixer *pMixer) : SoundGen(vm, pMixer), _parser(0), _isPlaying(false), _isGM(false) { +SoundGenMIDI::SoundGenMIDI(AgiEngine *vm, Audio::Mixer *pMixer) : SoundGen(vm, pMixer), _isGM(false) { MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB); _driver = MidiDriver::createMidi(dev); assert(_driver); @@ -83,10 +83,6 @@ SoundGenMIDI::SoundGenMIDI(AgiEngine *vm, Audio::Mixer *pMixer) : SoundGen(vm, p _nativeMT32 = false; } - memset(_channel, 0, sizeof(_channel)); - memset(_channelVolume, 127, sizeof(_channelVolume)); - _masterVolume = 0; - int ret = _driver->open(); if (ret == 0) { if (_nativeMT32) @@ -114,67 +110,30 @@ SoundGenMIDI::~SoundGenMIDI() { delete[] _midiMusicData; } -void SoundGenMIDI::setChannelVolume(int channel) { - int newVolume = _channelVolume[channel] * _masterVolume / 255; - _channel[channel]->volume(newVolume); -} - -void SoundGenMIDI::setVolume(int volume) { - Common::StackLock lock(_mutex); - - volume = CLIP(volume, 0, 255); - if (_masterVolume == volume) - return; - _masterVolume = volume; - - for (int i = 0; i < 16; ++i) { - if (_channel[i]) { - setChannelVolume(i); - } - } -} - void SoundGenMIDI::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(); + Audio::MidiPlayer::send(b); +} + +void SoundGenMIDI::sendToChannel(byte channel, uint32 b) { + if (!_channelsTable[channel]) { + _channelsTable[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel(); // If a new channel is allocated during the playback, make sure // its volume is correctly initialized. - if (_channel[channel]) - setChannelVolume(channel); + if (_channelsTable[channel]) + _channelsTable[channel]->volume(_channelsVolume[channel] * _masterVolume / 255); } - if (_channel[channel]) - _channel[channel]->send(b); + if (_channelsTable[channel]) + _channelsTable[channel]->send(b); } -void SoundGenMIDI::metaEvent(byte type, byte *data, uint16 length) { - - switch (type) { - case 0x2F: // End of Track - stop(); - _vm->_sound->soundIsFinished(); - break; - default: - //warning("Unhandled meta event: %02x", type); - break; - } +void SoundGenMIDI::endOfTrack() { + stop(); + _vm->_sound->soundIsFinished(); } void SoundGenMIDI::onTimer(void *refCon) { @@ -212,37 +171,6 @@ void SoundGenMIDI::play(int resnum) { } } -void SoundGenMIDI::stop() { - Common::StackLock lock(_mutex); - - if (!_isPlaying) - return; - - _isPlaying = false; - if (_parser) { - _parser->unloadMusic(); - _parser = NULL; - } -} - -void SoundGenMIDI::pause() { - setVolume(-1); - _isPlaying = false; -} - -void SoundGenMIDI::resume() { - syncVolume(); - _isPlaying = true; -} - -void SoundGenMIDI::syncVolume() { - int volume = ConfMan.getInt("music_volume"); - if (ConfMan.getBool("mute")) { - volume = -1; - } - setVolume(volume); -} - /* channel / intrument setup: */ /* most songs are good with this: */ diff --git a/engines/agi/sound_midi.h b/engines/agi/sound_midi.h index f70a20f24a..9551673a4e 100644 --- a/engines/agi/sound_midi.h +++ b/engines/agi/sound_midi.h @@ -28,9 +28,7 @@ #ifndef AGI_SOUND_MIDI_H #define AGI_SOUND_MIDI_H -#include "audio/mididrv.h" -#include "audio/midiparser.h" -#include "common/mutex.h" +#include "audio/midiplayer.h" namespace Agi { @@ -46,52 +44,30 @@ protected: uint16 _type; ///< Sound resource type }; -class SoundGenMIDI : public SoundGen, public MidiDriver_BASE { +class SoundGenMIDI : public SoundGen, public Audio::MidiPlayer { public: SoundGenMIDI(AgiEngine *vm, Audio::Mixer *pMixer); ~SoundGenMIDI(); void play(int resnum); - void stop(); - - bool isPlaying() const { return _isPlaying; } - void setPlaying(bool playing) { _isPlaying = playing; } - - void setVolume(int volume); - int getVolume() const { return _masterVolume; } - void syncVolume(); - - void setNativeMT32(bool b) { _nativeMT32 = b; } - bool hasNativeMT32() const { return _nativeMT32; } - void pause(); - void resume(); - void setLoop(bool loop) { _looping = loop; } + void stop() { Audio::MidiPlayer::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); + + // Overload Audio::MidiPlayer method + virtual void sendToChannel(byte channel, uint32 b); + virtual void endOfTrack(); private: static void onTimer(void *data); - void setChannelVolume(int channel); - - MidiParser *_parser; - Common::Mutex _mutex; - MidiChannel *_channel[16]; - MidiDriver *_driver; MidiParser *_smfParser; - byte _channelVolume[16]; - bool _nativeMT32; bool _isGM; - bool _isPlaying; - bool _looping; - byte _masterVolume; - byte *_midiMusicData; SoundMgr *_manager; -- cgit v1.2.3