aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/saga/music.cpp162
-rw-r--r--engines/saga/music.h37
2 files changed, 73 insertions, 126 deletions
diff --git a/engines/saga/music.cpp b/engines/saga/music.cpp
index 8554a22d90..90e3529472 100644
--- a/engines/saga/music.cpp
+++ b/engines/saga/music.cpp
@@ -44,15 +44,14 @@ namespace Saga {
#define MUSIC_SUNSPOT 26
MusicDriver::MusicDriver() : _isGM(false) {
- memset(_channelsTable, 0, sizeof(_channelsTable));
- _masterVolume = 0;
- _nativeMT32 = ConfMan.getBool("native_mt32");
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);
_driverType = MidiDriver::getMusicType(dev);
- if (isMT32())
+ if (_nativeMT32)
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
int retValue = _driver->open();
@@ -61,62 +60,76 @@ MusicDriver::MusicDriver() : _isGM(false) {
_driver->sendMT32Reset();
else
_driver->sendGMReset();
+
+ _driver->setTimerCallback(this, &timerCallback);
}
}
-MusicDriver::~MusicDriver() {
- _driver->close();
- delete _driver;
+void MusicDriver::send(uint32 b) {
+ if ((b & 0xF0) == 0xC0 && !_isGM && !_nativeMT32) {
+ // Remap MT32 instruments to General Midi
+ b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8;
+ }
+ Audio::MidiPlayer::send(b);
}
-void MusicDriver::setVolume(int volume) {
- volume = CLIP(volume, 0, 255);
-
- if (_masterVolume == volume)
- return;
-
- _masterVolume = volume;
+void MusicDriver::metaEvent(byte type, byte *data, uint16 length) {
+ // TODO: Seems SAGA does not want / need to handle end-of-track events?
+}
- Common::StackLock lock(_mutex);
+void MusicDriver::play(SagaEngine *vm, ByteArray *buffer, bool loop) {
+ if (buffer->size() < 4) {
+ error("Music::play() wrong music resource size");
+ }
- for (int i = 0; i < 16; ++i) {
- if (_channelsTable[i]) {
- _channelsTable[i]->volume(_channelsVolume[i] * _masterVolume / 255);
+ // Check if the game is using XMIDI or SMF music
+ if (vm->getGameId() == GID_IHNM && vm->isMacResources()) {
+ // Just set an XMIDI parser for Mac IHNM for now
+ _parser = MidiParser::createParser_XMIDI();
+ } else {
+ if (!memcmp(buffer->getBuffer(), "FORM", 4)) {
+ _parser = MidiParser::createParser_XMIDI();
+ // ITE had MT32 mapped instruments
+ _isGM = (vm->getGameId() != GID_ITE);
+ } else {
+ _parser = MidiParser::createParser_SMF();
+ // ITE with standalone MIDI files is General MIDI
+ _isGM = (vm->getGameId() == GID_ITE);
}
}
+
+ if (!_parser->loadMusic(buffer->getBuffer(), buffer->size()))
+ error("Music::play() 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, loop);
+// _isLooping = loop;
+
+ _isPlaying = true;
}
-void MusicDriver::send(uint32 b) {
- byte channel = (byte)(b & 0x0F);
- if ((b & 0xFFF0) == 0x07B0) {
- // Adjust volume changes by master volume
- byte volume = (byte)((b >> 16) & 0x7F);
- _channelsVolume[channel] = volume;
- volume = volume * _masterVolume / 255;
- b = (b & 0xFF00FFFF) | (volume << 16);
- } else if ((b & 0xF0) == 0xC0 && !_isGM && !isMT32()) {
- // Remap MT32 instruments to General Midi
- 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 (!_channelsTable[channel])
- return;
- }
+void MusicDriver::pause() {
+ _isPlaying = false;
+}
- if (!_channelsTable[channel])
- _channelsTable[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel();
- else
- _channelsTable[channel]->send(b);
+void MusicDriver::resume() {
+ _isPlaying = true;
}
+
Music::Music(SagaEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) {
_currentVolume = 0;
_currentMusicBuffer = NULL;
- _driver = new MusicDriver();
+ _player = new MusicDriver();
_digitalMusicContext = _vm->_resource->getContext(GAME_DIGITALMUSICFILE);
- if (!_driver->isAdlib())
+ if (!_player->isAdlib())
_musicContext = _vm->_resource->getContext(GAME_MUSICFILE_GM);
else
_musicContext = _vm->_resource->getContext(GAME_MUSICFILE_FM);
@@ -153,55 +166,19 @@ Music::Music(SagaEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) {
}
}
- // Check if the game is using XMIDI or SMF music
- if (_vm->getGameId() == GID_IHNM && _vm->isMacResources()) {
- // Just set an XMIDI parser for Mac IHNM for now
- _parser = MidiParser::createParser_XMIDI();
- } else {
- ByteArray resourceData;
- int resourceId = (_vm->getGameId() == GID_ITE ? 9 : 0);
- _vm->_resource->loadResource(_musicContext, resourceId, resourceData);
- if (resourceData.size() < 4) {
- error("Music::Music Unable to load midi resource data");
- }
- if (!memcmp(resourceData.getBuffer(), "FORM", 4)) {
- _parser = MidiParser::createParser_XMIDI();
- // ITE had MT32 mapped instruments
- _driver->setGM(_vm->getGameId() != GID_ITE);
- } else {
- _parser = MidiParser::createParser_SMF();
- // ITE with standalone MIDI files is General MIDI
- _driver->setGM(_vm->getGameId() == GID_ITE);
- }
- }
-
- _parser->setMidiDriver(_driver);
- _parser->setTimerRate(_driver->getBaseTempo());
- _parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
- _parser->property(MidiParser::mpSendSustainOffOnNotesOff, 1);
-
_digitalMusic = false;
}
Music::~Music() {
_vm->getTimerManager()->removeTimerProc(&musicVolumeGaugeCallback);
_mixer->stopHandle(_musicHandle);
- _driver->setTimerCallback(NULL, NULL);
- delete _driver;
- _parser->setMidiDriver(NULL);
- delete _parser;
+ delete _player;
}
void Music::musicVolumeGaugeCallback(void *refCon) {
((Music *)refCon)->musicVolumeGauge();
}
-void Music::onTimer(void *refCon) {
- Music *music = (Music *)refCon;
- Common::StackLock lock(music->_driver->_mutex);
- music->_parser->onTimer();
-}
-
void Music::musicVolumeGauge() {
int volume;
@@ -217,7 +194,7 @@ void Music::musicVolumeGauge() {
volume = 1;
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, volume);
- _driver->setVolume(volume);
+ _player->setVolume(volume);
if (_currentVolumePercent == 100) {
_vm->getTimerManager()->removeTimerProc(&musicVolumeGaugeCallback);
@@ -237,7 +214,7 @@ void Music::setVolume(int volume, int time) {
volume = 0;
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, volume);
- _driver->setVolume(volume);
+ _player->setVolume(volume);
_vm->getTimerManager()->removeTimerProc(&musicVolumeGaugeCallback);
_currentVolume = volume;
return;
@@ -247,7 +224,7 @@ void Music::setVolume(int volume, int time) {
}
bool Music::isPlaying() {
- return _mixer->isSoundHandleActive(_musicHandle) || _parser->isPlaying();
+ return _mixer->isSoundHandleActive(_musicHandle) || _player->isPlaying();
}
void Music::play(uint32 resourceId, MusicFlags flags) {
@@ -262,7 +239,7 @@ void Music::play(uint32 resourceId, MusicFlags flags) {
_trackNumber = resourceId;
_mixer->stopHandle(_musicHandle);
- _parser->unloadMusic();
+ _player->stop();
int realTrackNumber;
@@ -392,33 +369,20 @@ void Music::play(uint32 resourceId, MusicFlags flags) {
_vm->_resource->loadResource(_musicContext, resourceId, *_currentMusicBuffer);
}
- if (_currentMusicBuffer->size() < 4) {
- error("Music::play() wrong music resource size");
- }
-
- if (!_parser->loadMusic(_currentMusicBuffer->getBuffer(), _currentMusicBuffer->size()))
- error("Music::play() wrong music resource");
-
- _parser->setTrack(0);
- _driver->setTimerCallback(this, &onTimer);
-
+ _player->play(_vm, _currentMusicBuffer, (flags & MUSIC_LOOP));
setVolume(_vm->_musicVolume);
-
- // Handle music looping
- _parser->property(MidiParser::mpAutoLoop, (flags & MUSIC_LOOP) ? 1 : 0);
}
void Music::pause() {
- _driver->setTimerCallback(NULL, NULL);
+ _player->pause();
}
void Music::resume() {
- _driver->setTimerCallback(this, &onTimer);
+ _player->resume();
}
void Music::stop() {
- _driver->setTimerCallback(NULL, NULL);
- _parser->unloadMusic();
+ _player->stop();
}
} // End of namespace Saga
diff --git a/engines/saga/music.h b/engines/saga/music.h
index 25b54cf826..e67fbfb71a 100644
--- a/engines/saga/music.h
+++ b/engines/saga/music.h
@@ -28,8 +28,7 @@
#ifndef SAGA_MUSIC_H
#define SAGA_MUSIC_H
-#include "audio/mididrv.h"
-#include "audio/midiparser.h"
+#include "audio/midiplayer.h"
#include "audio/mixer.h"
#include "audio/decoders/mp3.h"
#include "audio/decoders/vorbis.h"
@@ -44,41 +43,26 @@ enum MusicFlags {
MUSIC_DEFAULT = 0xffff
};
-class MusicDriver : public MidiDriver_BASE {
+class MusicDriver : public Audio::MidiPlayer {
public:
MusicDriver();
- ~MusicDriver();
- void setVolume(int volume);
- int getVolume() { return _masterVolume; }
+ void play(SagaEngine *vm, ByteArray *buffer, bool loop);
+ virtual void pause();
+ virtual void resume();
bool isAdlib() { return _driverType == MT_ADLIB; }
- bool isMT32() { return _driverType == MT_MT32 || _nativeMT32; }
- void setGM(bool isGM) { _isGM = isGM; }
+
+ // FIXME
+ bool isPlaying() const { return _parser && _parser->isPlaying(); }
// 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; // FIXME: Make _mutex protected
+ virtual void metaEvent(byte type, byte *data, uint16 length);
protected:
-
- MidiChannel *_channelsTable[16];
- MidiDriver *_driver;
MusicType _driverType;
- byte _channelsVolume[16];
bool _isGM;
- bool _nativeMT32;
-
- byte _masterVolume;
-
- byte *_musicData;
- uint16 *_buf;
- size_t _musicDataSize;
};
class Music {
@@ -103,7 +87,7 @@ private:
SagaEngine *_vm;
Audio::Mixer *_mixer;
- MusicDriver *_driver;
+ MusicDriver *_player;
Audio::SoundHandle _musicHandle;
uint32 _trackNumber;
@@ -114,7 +98,6 @@ private:
ResourceContext *_musicContext;
ResourceContext *_digitalMusicContext;
- MidiParser *_parser;
static void musicVolumeGaugeCallback(void *refCon);