[Scummvm-cvs-logs] SF.net SVN: scummvm:[35177] scummvm/trunk/engines/kyra

lordhoto at users.sourceforge.net lordhoto at users.sourceforge.net
Sun Nov 30 03:38:09 CET 2008


Revision: 35177
          http://scummvm.svn.sourceforge.net/scummvm/?rev=35177&view=rev
Author:   lordhoto
Date:     2008-11-30 02:38:08 +0000 (Sun, 30 Nov 2008)

Log Message:
-----------
Implement fade out support for MIDI.

Modified Paths:
--------------
    scummvm/trunk/engines/kyra/sound.h
    scummvm/trunk/engines/kyra/sound_midi.cpp

Modified: scummvm/trunk/engines/kyra/sound.h
===================================================================
--- scummvm/trunk/engines/kyra/sound.h	2008-11-30 02:08:09 UTC (rev 35176)
+++ scummvm/trunk/engines/kyra/sound.h	2008-11-30 02:38:08 UTC (rev 35177)
@@ -324,6 +324,7 @@
 
 	void playTrack(uint8 track);
 	void haltTrack();
+	bool isPlaying();
 
 	void playSoundEffect(uint8 track);
 

Modified: scummvm/trunk/engines/kyra/sound_midi.cpp
===================================================================
--- scummvm/trunk/engines/kyra/sound_midi.cpp	2008-11-30 02:08:09 UTC (rev 35176)
+++ scummvm/trunk/engines/kyra/sound_midi.cpp	2008-11-30 02:38:08 UTC (rev 35177)
@@ -27,19 +27,17 @@
 #include "kyra/resource.h"
 
 #include "common/system.h"
+#include "common/config-manager.h"
 
 namespace Kyra {
 
-struct Controller {
-	byte controller;
-	byte value;
-};
-
 class MidiOutput : public MidiDriver {
 public:
 	MidiOutput(OSystem *system, MidiDriver *output, bool isMT32, bool defaultMT32);
 	~MidiOutput();
 
+	void setSourceVolume(int source, uint8 volume, bool apply=false);
+
 	void initSource(int source);
 	void deinitSource(int source);
 	void stopNotesOnChannel(int channel);
@@ -70,6 +68,11 @@
 	bool _isMT32;
 	bool _defaultMT32;
 
+	struct Controller {
+		byte controller;
+		byte value;
+	};
+
 	enum {
 		kChannelLocked = 0x80,
 		kChannelProtected = 0x40
@@ -92,6 +95,8 @@
 	int _curSource;
 
 	struct SoundSource {
+		byte volume;
+
 		int8 channelMap[16];
 		byte channelProgram[16];
 		int16 channelPW[16];
@@ -151,6 +156,9 @@
 		if (defaultPrograms[i] != 0xFF)
 			sendIntern(0xC0, i, defaultPrograms[i-1], 0x00);
 	}
+
+	for (int i = 0; i < 4; ++i)
+		initSource(i);
 }
 
 
@@ -162,8 +170,8 @@
 void MidiOutput::send(uint32 b) {
 	const byte event = b & 0xF0;
 	const byte channel = b & 0x0F;
-	const byte param1 = (b >>  8) & 0xFF;
-	const byte param2 = (b >> 16) & 0xFF;
+	byte param1 = (b >>  8) & 0xFF;
+	byte param2 = (b >> 16) & 0xFF;
 
 	if (event == 0xE0) {							// Pitch-Wheel
 		_channels[channel].pitchWheel = 
@@ -172,15 +180,9 @@
 		_channels[channel].program =
 		_sources[_curSource].channelProgram[channel] = param1;
 	} else if (event == 0xB0) {						// Controller change
-		for (int i = 0; i < 9; ++i) {
-			Controller &cont = _sources[_curSource].controllers[channel][i];
-			if (cont.controller == param1) {
-				cont.value = param2;
-				break;
-			}
-		}
-
-		if (param1 == 0x6E) {			// Lock Channel
+		if (param1 == 0x07) {
+			param1 = (param1 * _sources[_curSource].volume) >> 8;
+		} else if (param1 == 0x6E) {	// Lock Channel
 			if (param2 >= 0x40) {	// Lock Channel
 				int chan = lockChannel();
 				if (chan < 0)
@@ -202,6 +204,15 @@
 			// on track change, we simply ignore it.
 			return;
 		}
+
+		for (int i = 0; i < 9; ++i) {
+			Controller &cont = _sources[_curSource].controllers[channel][i];
+			if (cont.controller == param1) {
+				cont.value = param2;
+				break;
+			}
+		}
+
 	} else if (event == 0x90 || event == 0x80) {	// Note On/Off
 		if (!(_channels[channel].flags & kChannelLocked)) {
 			const bool remove = (event == 0x80) || (param2 == 0x00);
@@ -309,6 +320,21 @@
 	_output->metaEvent(type, data, length);
 }
 
+void MidiOutput::setSourceVolume(int source, uint8 volume, bool apply) {
+	_sources[source].volume = volume;
+
+	if (apply) {
+		for (int i = 0; i < 16; ++i) {
+			// Controller 0 in the state table should always be '7' aka
+			// volume control
+			byte realVol = (_channels[i].controllers[0].value * volume) >> 8;
+			_channels[i].controllers[0].value = realVol;
+
+			sendIntern(0xB0, i, 0x07, realVol);
+		}
+	}
+}
+
 void MidiOutput::initSource(int source) {
 	memset(_sources[source].notes, -1, sizeof(_sources[source].notes));
 
@@ -431,7 +457,7 @@
 		assert(_sfx[i]);
 	}
 
-	updateVolumeSettings();
+	_musicVolume = _sfxVolume = 0;
 }
 
 SoundMidiPC::~SoundMidiPC() {
@@ -467,6 +493,8 @@
 	_output = new MidiOutput(_vm->_system, _driver, _nativeMT32, !_useC55);
 	assert(_output);
 
+	updateVolumeSettings();
+
 	_music->setMidiDriver(_output);
 	_music->setTempo(_output->getBaseTempo());
 	_music->setTimerRate(_output->getBaseTempo());
@@ -488,7 +516,19 @@
 }
 
 void SoundMidiPC::updateVolumeSettings() {
-	//XXX
+	Common::StackLock lock(_mutex);
+
+	if (!_output)
+		return;
+
+	uint8 newMusVol = CLIP(ConfMan.getInt("music_volume"), 0, 255);
+	_sfxVolume = CLIP(ConfMan.getInt("sfx_volume"), 0, 255);
+
+	_output->setSourceVolume(0, newMusVol, newMusVol != _musicVolume);
+	_musicVolume = newMusVol;
+
+	for (int i = 1; i < 4; ++i)
+		_output->setSourceVolume(i, _sfxVolume, false);
 }
 
 void SoundMidiPC::loadSoundFile(uint file) {
@@ -529,6 +569,8 @@
 void SoundMidiPC::playTrack(uint8 track) {
 	Common::StackLock lock(_mutex);
 	_output->initSource(0);
+	_fadeMusicOut = false;
+	_output->setSourceVolume(0, _musicVolume, true);
 	_music->setTrack(track);
 }
 
@@ -540,6 +582,12 @@
 	_output->deinitSource(0);
 }
 
+bool SoundMidiPC::isPlaying() {
+	Common::StackLock lock(_mutex);
+
+	return _music->isPlaying();
+}
+
 void SoundMidiPC::playSoundEffect(uint8 track) {
 	Common::StackLock lock(_mutex);
 	for (int i = 0; i < 3; ++i) {
@@ -552,8 +600,10 @@
 }
 
 void SoundMidiPC::beginFadeOut() {
-	//FIXME: implement properly
-	haltTrack();
+	Common::StackLock lock(_mutex);
+
+	_fadeMusicOut = true;
+	_fadeStartTime = _vm->_system->getMillis();
 }
 
 void SoundMidiPC::onTimer(void *data) {
@@ -561,6 +611,31 @@
 
 	Common::StackLock lock(midi->_mutex);
 
+	if (midi->_fadeMusicOut) {
+		static const uint32 musicFadeTime = 1 * 1000;
+
+		if (midi->_fadeStartTime + musicFadeTime > midi->_vm->_system->getMillis()) {
+			byte volume = (byte)((musicFadeTime - (midi->_vm->_system->getMillis() - midi->_fadeStartTime)) * midi->_musicVolume / musicFadeTime);
+			midi->_output->setSourceVolume(0, volume, true);
+		} else {
+			for (int i = 0; i < 16; ++i)
+				midi->_output->stopNotesOnChannel(i);
+			for (int i = 0; i < 4; ++i)
+				midi->_output->deinitSource(i);			
+
+			midi->_output->setSoundSource(0);
+			midi->_music->stopPlaying();
+
+			for (int i = 0; i < 3; ++i) {
+				midi->_output->setSoundSource(i+1);
+				midi->_sfx[i]->stopPlaying();
+			}
+
+			midi->_output->setSourceVolume(0, midi->_musicVolume, true);
+			midi->_fadeMusicOut = false;
+		}
+	}
+
 	midi->_output->setSoundSource(0);
 	midi->_music->onTimer();
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list