[Scummvm-cvs-logs] scummvm master -> 6cc0aca5b23cc63c51e8b0fb3f708854c0431d58

fingolfin max at quendi.de
Fri Mar 25 17:06:37 CET 2011


This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
baeb28d0e1 QUEEN: Remove leftover class forward declaration
9e65daef3b SAGA: Change Sage to use Audio::MidiPlayer
6cc0aca5b2 AUDIO: Document issues with semantics of Audio::MidiPlayer::isPlaying()


Commit: baeb28d0e160cb469d8c34e8f9863f2f29b2c132
    https://github.com/scummvm/scummvm/commit/baeb28d0e160cb469d8c34e8f9863f2f29b2c132
Author: Max Horn (max at quendi.de)
Date: 2011-03-25T08:20:43-07:00

Commit Message:
QUEEN: Remove leftover class forward declaration

Changed paths:
    engines/queen/midiadlib.cpp



diff --git a/engines/queen/midiadlib.cpp b/engines/queen/midiadlib.cpp
index c3bc6d1..b03c90f 100644
--- a/engines/queen/midiadlib.cpp
+++ b/engines/queen/midiadlib.cpp
@@ -30,8 +30,6 @@
 
 namespace Queen {
 
-class AdLibMidiChannel;
-
 class AdLibMidiDriver : public MidiDriver_Emulated {
 public:
 


Commit: 9e65daef3bed3218d6a593f58b1c9a04c0d09f0a
    https://github.com/scummvm/scummvm/commit/9e65daef3bed3218d6a593f58b1c9a04c0d09f0a
Author: Max Horn (max at quendi.de)
Date: 2011-03-25T09:00:54-07:00

Commit Message:
SAGA: Change Sage to use Audio::MidiPlayer

Changed paths:
    engines/saga/music.cpp
    engines/saga/music.h



diff --git a/engines/saga/music.cpp b/engines/saga/music.cpp
index 8554a22..90e3529 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 25b54cf..e67fbfb 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);


Commit: 6cc0aca5b23cc63c51e8b0fb3f708854c0431d58
    https://github.com/scummvm/scummvm/commit/6cc0aca5b23cc63c51e8b0fb3f708854c0431d58
Author: Max Horn (max at quendi.de)
Date: 2011-03-25T09:01:36-07:00

Commit Message:
AUDIO: Document issues with semantics of Audio::MidiPlayer::isPlaying()

Changed paths:
    audio/midiplayer.cpp
    audio/midiplayer.h



diff --git a/audio/midiplayer.cpp b/audio/midiplayer.cpp
index 1e39b99..613ad2e 100644
--- a/audio/midiplayer.cpp
+++ b/audio/midiplayer.cpp
@@ -174,8 +174,8 @@ void MidiPlayer::stop() {
 
 void MidiPlayer::pause() {
 //	debugC(2, kDraciSoundDebugLevel, "Pausing track %d", _track);
-	setVolume(-1);	// FIXME: This should be 0, shouldn't it?
 	_isPlaying = false;
+	setVolume(-1);	// FIXME: This should be 0, shouldn't it?
 }
 
 void MidiPlayer::resume() {
diff --git a/audio/midiplayer.h b/audio/midiplayer.h
index 1bb7942..fe96e0d 100644
--- a/audio/midiplayer.h
+++ b/audio/midiplayer.h
@@ -69,6 +69,24 @@ public:
 	virtual void pause();
 	virtual void resume();
 
+	/**
+	 * Return whether there is currently any MIDI music playing.
+	 *
+	 * @todo There is a subtle difference between the semantics of this in
+	 *       various subclasses, related to paused music: Namely, should this
+	 *       function return true or false if a MIDI song is currently loaded,
+	 *       but paused? In the base implementation of pause/resume, "false"
+	 *       will be returned (that is, it is not possible to distinguish between
+	 *       nothing being played, and an active but paused MIDI tune).
+	 *       But in several subclasses (e.g. in HUGO), there is a separate _paused
+	 *       variable, which is used to pause playback, and for these, "true"
+	 *       will be returned.
+	 *       And in SAGA, isPlaying is overwritten to return the value
+	 *       of _parser->isPlaying() (which should amount to "true" in the
+	 *       described situation).
+	 *       We really should unify this and clearly define the desired
+	 *       semantics of this method.
+	 */
 	bool isPlaying() const { return _isPlaying; }
 
 	/**






More information about the Scummvm-git-logs mailing list