From 11870c414460d8c9ea70651a979b1842e58569e5 Mon Sep 17 00:00:00 2001 From: Strangerke Date: Mon, 1 Dec 2014 14:07:09 +0100 Subject: ACCESS: Implement music player (WIP) --- engines/access/amazon/amazon_logic.cpp | 2 +- engines/access/room.cpp | 2 +- engines/access/sound.cpp | 84 ++++++++++++++++++++++++++++++---- engines/access/sound.h | 12 +++-- 4 files changed, 84 insertions(+), 16 deletions(-) diff --git a/engines/access/amazon/amazon_logic.cpp b/engines/access/amazon/amazon_logic.cpp index c330429ee6..de497c2a35 100644 --- a/engines/access/amazon/amazon_logic.cpp +++ b/engines/access/amazon/amazon_logic.cpp @@ -353,7 +353,7 @@ void Opening::doTitle() { } _vm->_midi->newMusic(1, 1); - _vm->_midi->_musicRepeat = false; + _vm->_midi->setLoop(false); _vm->_events->zeroKeys(); _vm->_room->loadRoom(0); _vm->_screen->clearScreen(); diff --git a/engines/access/room.cpp b/engines/access/room.cpp index 8ef61a9d68..a5873b2c38 100644 --- a/engines/access/room.cpp +++ b/engines/access/room.cpp @@ -184,7 +184,7 @@ void Room::loadRoomData(const byte *roomData) { if (roomInfo._musicFile._fileNum != -1) { _vm->_midi->loadMusic(roomInfo._musicFile); _vm->_midi->midiPlay(); - _vm->_midi->_musicRepeat = true; + _vm->_midi->setLoop(true); } _vm->_scaleH1 = roomInfo._scaleH1; diff --git a/engines/access/sound.cpp b/engines/access/sound.cpp index 316ac54d42..2d38a2c6bc 100644 --- a/engines/access/sound.cpp +++ b/engines/access/sound.cpp @@ -147,7 +147,20 @@ void SoundManager::freeSounds() { MusicManager::MusicManager(AccessEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) { _music = nullptr; _tempMusic = nullptr; - _musicRepeat = false; + _isLooping = false; + + MidiPlayer::createDriver(); + MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM); + + int retValue = _driver->open(); + if (retValue == 0) { + if (_nativeMT32) + _driver->sendMT32Reset(); + else + _driver->sendGMReset(); + + _driver->setTimerCallback(this, &timerCallback); + } } MusicManager::~MusicManager() { @@ -155,46 +168,92 @@ MusicManager::~MusicManager() { delete _tempMusic; } +void MusicManager::send(uint32 b) { + if ((b & 0xF0) == 0xC0 && !_nativeMT32) { + b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8; + } + + Audio::MidiPlayer::send(b); +} + void MusicManager::midiPlay() { - // TODO + warning("MusicManager::midiPlay"); + if (_music->_size < 4) { + error("midiPlay() wrong music resource size"); + } + + if (READ_BE_UINT32(_music->data()) != MKTAG('F', 'O', 'R', 'M')) + error("midiPlay() Unexpected signature"); + + stop(); + + _parser = MidiParser::createParser_XMIDI(); + + if (!_parser->loadMusic(_music->data(), _music->_size)) + error("midiPlay() wrong music resource"); + + _parser->setTrack(0); + _parser->setMidiDriver(this); + _parser->setTimerRate(_driver->getBaseTempo()); + _parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1); + _parser->property(MidiParser::mpSendSustainOffOnNotesOff, 1); + + // Handle music looping + _parser->property(MidiParser::mpAutoLoop, _isLooping); + // _isLooping = loop; + + setVolume(127); + _isPlaying = true; } bool MusicManager::checkMidiDone() { - // TODO - return true; + warning("MusicManager::checkMidiDone"); + return (!_isPlaying); } void MusicManager::midiRepeat() { - // TODO + warning("MusicManager::midiRepeat"); + if (!_parser) + return; + + _isLooping = true; + _parser->property(MidiParser::mpAutoLoop, _isLooping); + if (!_isPlaying) + _parser->setTrack(0); } void MusicManager::stopSong() { - // TODO + warning("MusicManager::stopSong"); + stop(); } void MusicManager::loadMusic(int fileNum, int subfile) { + warning("MusicManager::loadMusic %d %d", fileNum, subfile); _music = _vm->_files->loadFile(fileNum, subfile); } void MusicManager::loadMusic(FileIdent file) { + warning("MusicManager::loadMusic %d %d", file._fileNum, file._subfile); _music = _vm->_files->loadFile(file); } void MusicManager::newMusic(int musicId, int mode) { + warning("MusicManager::newMusic %d %d", musicId, mode); if (mode == 1) { stopSong(); freeMusic(); _music = _tempMusic; _tempMusic = nullptr; - _musicRepeat = true; - if (_music) - midiPlay(); + _isLooping = true; } else { - _musicRepeat = (mode == 2); + _isLooping = (mode == 2); _tempMusic = _music; stopSong(); loadMusic(97, musicId); } + + if (_music) + midiPlay(); } void MusicManager::freeMusic() { @@ -202,4 +261,9 @@ void MusicManager::freeMusic() { _music = nullptr; } +void MusicManager::setLoop(bool loop) { + _isLooping = loop; + if (_parser) + _parser->property(MidiParser::mpAutoLoop, _isLooping); +} } // End of namespace Access diff --git a/engines/access/sound.h b/engines/access/sound.h index 827a00f8b5..5089bd093b 100644 --- a/engines/access/sound.h +++ b/engines/access/sound.h @@ -26,6 +26,8 @@ #include "common/scummsys.h" #include "audio/mixer.h" #include "access/files.h" +#include "audio/midiplayer.h" +#include "audio/midiparser.h" #define MAX_SOUNDS 20 @@ -70,17 +72,17 @@ public: void freeSounds(); }; -class MusicManager { +class MusicManager : public Audio::MidiPlayer { private: AccessEngine *_vm; Audio::Mixer *_mixer; Resource *_tempMusic; -public: - bool _musicRepeat; - bool _playingSound; + // MidiDriver_BASE interface implementation + virtual void send(uint32 b); +public: Resource *_music; public: @@ -101,6 +103,8 @@ public: void loadMusic(int fileNum, int subfile); void loadMusic(FileIdent file); + + void setLoop(bool loop); }; } // End of namespace Access -- cgit v1.2.3