[Scummvm-cvs-logs] CVS: scummvm/sword1 music.cpp,1.6,1.7 music.h,1.2,1.3

Robert G?ffringmann lavosspawn at users.sourceforge.net
Sun Dec 21 18:48:01 CET 2003


Update of /cvsroot/scummvm/scummvm/sword1
In directory sc8-pr-cvs1:/tmp/cvs-serv7467/sword1

Modified Files:
	music.cpp music.h 
Log Message:
added code for non-looping music and implemented fading

Index: music.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword1/music.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- music.cpp	20 Dec 2003 09:12:54 -0000	1.6
+++ music.cpp	22 Dec 2003 02:47:43 -0000	1.7
@@ -32,12 +32,14 @@
 	_system = system;
 	_mixer = pMixer;
 	_mixer->setupPremix(passMixerFunc, this);
-	_fading = 0;
+	_fading = false;
 	_playing = false;
 	_loop = false;
 	_mutex = _system->create_mutex();
-	_waveSize = _wavePos = _bufPos = _smpInBuf = 0;
+	_fadeSmpInBuf = _fadeBufPos = _waveSize = _wavePos = _bufPos = _smpInBuf = 0;
 	assert(_mixer->getOutputRate() == 22050);
+	_fadeBuf = NULL;
+	_musicBuf = NULL;
 }
 
 SwordMusic::~SwordMusic() {
@@ -48,51 +50,103 @@
 	((SwordMusic*)param)->mixer(buf, len);
 }
 
-void SwordMusic::mixer(int16 *buf, uint len) {
+void SwordMusic::mixTo(int16 *src, int16 *dst, uint32 len) {
 	if (!_playing)
-		memset(buf, 0, 2 * len * sizeof(int16));
-	else {
-		_system->lock_mutex(_mutex);
-		len >>= 1;
-		if (len <= _smpInBuf) {
-			uint32 maxLen = BUFSIZE - _bufPos;
-			if (len >= maxLen) {
-				for (uint32 cnt = 0; cnt < maxLen; cnt++)
-					buf[(cnt << 2) | 0] = buf[(cnt << 2) | 1] =
-					buf[(cnt << 2) | 2] = buf[(cnt << 2) | 3] = (int16)READ_LE_UINT16(_musicBuf + _bufPos + cnt);
-				_smpInBuf -= maxLen;
-				_bufPos = 0;
-				len -= maxLen;
-				buf += maxLen * 4;
+		memset(dst, 0, len * 8);
+	if (!_fading) { // no fading, simply copy it over
+		for (uint32 cnt = 0; cnt < len; cnt++)
+			dst[(cnt << 2) | 0] = dst[(cnt << 2) | 1] =
+			dst[(cnt << 2) | 2] = dst[(cnt << 2) | 3] = (int16)READ_LE_UINT16(src + cnt);
+	} else {
+		if (_fadeBuf) { // do a cross fade
+			for (uint32 cnt = 0; cnt < len; cnt++) {
+				int16 resVal = ((int16)READ_LE_UINT16(_fadeBuf + _fadeBufPos) * _fadeVal) >> 15;
+				resVal += ((int16)READ_LE_UINT16(src + cnt) * (32768 - _fadeVal)) >> 15;
+				dst[(cnt << 2) | 0] = dst[(cnt << 2) | 1] =
+				dst[(cnt << 2) | 2] = dst[(cnt << 2) | 3] = resVal;
+				_fadeVal--;
+				_fadeBufPos++;
+				_fadeSmpInBuf--;
 			}
-			if (len) {
-				for (uint32 cnt = 0; cnt < len; cnt++)
-					buf[(cnt << 2) | 0] = buf[(cnt << 2) | 1] =
-					buf[(cnt << 2) | 2] = buf[(cnt << 2) | 3] = (int16)READ_LE_UINT16(_musicBuf + _bufPos + cnt);
-				_smpInBuf -= len;
-				_bufPos += len;
+			if ((!_fadeVal) || (!_fadeSmpInBuf)) {
+				free(_fadeBuf);
+				_fadeBuf = NULL;
+				_fading = false;
+			}
+			if (_fadeBufPos == BUFSIZE)
+				_fadeBufPos = 0;
+		} else { // simple fadeout
+			for (uint32 cnt = 0; cnt < len; cnt++) {
+				dst[(cnt << 2) | 0] = dst[(cnt << 2) | 1] =
+				dst[(cnt << 2) | 2] = dst[(cnt << 2) | 3] = 
+				((int16)READ_LE_UINT16(src + cnt) * _fadeVal) >> 15;
+				_fadeVal--;
+			}
+			if (!_fadeVal) {
+				_fading = _playing = false;
+				free(_musicBuf);
+				_musicBuf = NULL;
 			}
 		}
-		_system->unlock_mutex(_mutex);
 	}
 }
 
+void SwordMusic::mixer(int16 *buf, uint32 len) {
+	if (!_playing) {
+		memset(buf, 0, 2 * len * sizeof(int16));
+		return;
+	}
+	uint32 remain = 0;	
+	if (_smpInBuf < (len >> 1)) {
+		if (_loop)
+			return;
+		remain = (len >> 1) - _smpInBuf;
+		len = _smpInBuf << 1;
+	}
+	_system->lock_mutex(_mutex);
+	len >>= 1;
+	while (len) {
+		uint32 length = len;
+		length = MIN(length, BUFSIZE - _bufPos);
+		if (_fading) {
+			length = MIN(length, (uint32)_fadeVal);
+			length = MIN(length, _fadeSmpInBuf);
+			length = MIN(length, BUFSIZE - _fadeBufPos);
+		}
+		mixTo(_musicBuf + _bufPos, buf, length);
+		len -= length;
+		buf += 4 * length;
+		_bufPos += length;
+		_smpInBuf -= length;
+		if (_bufPos == BUFSIZE)
+			_bufPos = 0;
+	}
+	if (remain) {
+		memset(buf, 0, remain * 8);
+		_playing = false;
+	}
+	_system->unlock_mutex(_mutex);
+}
+
 void SwordMusic::stream(void) {
 	// make sure we've got enough samples in buffer.
-	if ((_smpInBuf < SAMPLERATE) && _playing) {
+	if ((_smpInBuf < 4 * SAMPLERATE) && _playing) {
 		_system->lock_mutex(_mutex);
 		uint32 loadTotal = BUFSIZE - _smpInBuf;
 		while (uint32 doLoad = loadTotal) {
 			if (BUFSIZE - ((_bufPos + _smpInBuf) % BUFSIZE) < loadTotal)
 				doLoad = BUFSIZE - (_bufPos + _smpInBuf) % BUFSIZE;
-			if (_waveSize - _wavePos < doLoad)
-				doLoad = _waveSize - _wavePos;
+			doLoad = MIN(doLoad, _waveSize - _wavePos);
+			
 			int16 *dest = _musicBuf + ((_bufPos + _smpInBuf) % BUFSIZE);
 			_musicFile.read(dest, doLoad * 2);
 			_wavePos += doLoad;
 			if (_wavePos == _waveSize) {
-				_wavePos = 0;
-				_musicFile.seek(WAVEHEADERSIZE);
+				if (_loop) {
+					_wavePos = 0;
+					_musicFile.seek(WAVEHEADERSIZE);
+				} else
+					loadTotal = doLoad;
 			}
 			loadTotal -= doLoad;
 			_smpInBuf += doLoad;
@@ -104,28 +158,49 @@
 void SwordMusic::startMusic(int32 tuneId, int32 loopFlag) {
 	_system->lock_mutex(_mutex);
 	_loop = (loopFlag > 0);
-	if (tuneId) {
+	if (tuneId) {		
 		if (_musicFile.isOpen())
 			_musicFile.close();
 		char fName[20];
 		sprintf(fName, "music/%s.wav", _tuneList[tuneId]);
 		_musicFile.open(fName);
 		if (_musicFile.isOpen()) {
+			if (_playing) { // do a cross fade
+				_fadeBuf = _musicBuf;
+				_fadeBufPos = _bufPos;
+				_fadeSmpInBuf = _smpInBuf;
+				_fading = true;
+				_fadeVal = 32768;
+			} else
+				_fading = false;
+			_musicBuf = (int16*)malloc(BUFSIZE * 2);
+
 			_musicFile.seek(0x28);
 			_waveSize = _musicFile.readUint32LE() / 2;
 			_wavePos = 0;
 			_smpInBuf = 0;
 			_bufPos = 0;
 			_playing = true;
-		} else
-			_playing = false;
-	} else
-		_playing = false;
+		} else {
+			_fading = true;
+			_fadeVal = 32768;
+			if (_fadeBuf) {
+				free(_fadeBuf);
+				_fadeBuf = NULL;
+			}
+		}
+	} else if (_playing)
+		fadeDown();
 	_system->unlock_mutex(_mutex);
 	stream();
 }
 
 void SwordMusic::fadeDown(void) {
-	warning("stub: SwordMusic::fadeDown");
+	_fadeVal = 32768;
+	_fading = true;
+	if (_fadeBuf) {
+		free(_fadeBuf);
+		_fadeBuf = NULL;
+	}
 }
 

Index: music.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword1/music.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- music.h	19 Dec 2003 01:08:30 -0000	1.2
+++ music.h	22 Dec 2003 02:47:43 -0000	1.3
@@ -28,7 +28,7 @@
 #define TOTAL_TUNES 270
 
 #define SAMPLERATE 11025
-#define BUFSIZE (4 * SAMPLERATE)
+#define BUFSIZE (6 * SAMPLERATE)
 #define WAVEHEADERSIZE 0x2C
 
 class SoundMixer;
@@ -44,16 +44,20 @@
 	File _musicFile;
 	OSystem *_system;
 	SoundMixer *_mixer;
-	uint16 _fading;
+	bool _fading;
+	uint16 _fadeVal;
 	bool _playing;
 	bool _loop;
 	OSystem::MutexRef _mutex;
 	static void passMixerFunc(void *param, int16 *buf, uint len);
-	void mixer(int16 *buf, uint len);
+	void mixTo(int16 *src, int16 *dst, uint32 len);
+	void mixer(int16 *buf, uint32 len);
 	static const char _tuneList[TOTAL_TUNES][8]; // in staticres.cpp
 	uint32 _waveSize, _wavePos;
+	int16 *_musicBuf; // samples for 6 seconds
 	uint32 _bufPos, _smpInBuf;
-	int16 _musicBuf[BUFSIZE]; // samples for 8 seconds
+	int16 *_fadeBuf;
+	uint32 _fadeBufPos, _fadeSmpInBuf;
 };
 
 #endif // BSMUSIC_H





More information about the Scummvm-git-logs mailing list