[Scummvm-cvs-logs] SF.net SVN: scummvm:[43100] scummvm/branches/gsoc2009-mods/sound/mods

nolange at users.sourceforge.net nolange at users.sourceforge.net
Fri Aug 7 20:02:06 CEST 2009


Revision: 43100
          http://scummvm.svn.sourceforge.net/scummvm/?rev=43100&view=rev
Author:   nolange
Date:     2009-08-07 18:02:06 +0000 (Fri, 07 Aug 2009)

Log Message:
-----------
implemented "SPECIAL" commands
addid missing stacklock for a few public functions

Modified Paths:
--------------
    scummvm/branches/gsoc2009-mods/sound/mods/maxtrax.cpp
    scummvm/branches/gsoc2009-mods/sound/mods/maxtrax.h

Modified: scummvm/branches/gsoc2009-mods/sound/mods/maxtrax.cpp
===================================================================
--- scummvm/branches/gsoc2009-mods/sound/mods/maxtrax.cpp	2009-08-07 16:21:30 UTC (rev 43099)
+++ scummvm/branches/gsoc2009-mods/sound/mods/maxtrax.cpp	2009-08-07 18:02:06 UTC (rev 43100)
@@ -42,7 +42,10 @@
 	// div <= 1000 means time to small (or even 0)
 	return (div <= 1000) ? delta : (1000 * delta) / div;
 }
+int32 calcTempo(const uint16 tempo, uint16 vBlankFreq) {
+	return (int32)(((uint32)(tempo & 0xFFF0) << 8) / (uint16)(5 * vBlankFreq));
 }
+}
 
 namespace Audio {
 
@@ -61,6 +64,7 @@
 
 	_playerCtx.tempo = 120;
 	_playerCtx.tempoTime = 0;
+	_playerCtx.syncCallBack = 0;
 
 	for (int i = 0; i < ARRAYSIZE(_channelCtx); ++i)
 		resetChannel(_channelCtx[i], (i & 1) != 0);
@@ -99,44 +103,41 @@
 		int32 eventDelta = _playerCtx.nextEventTime - millis;
 		for (; eventDelta <= 0; eventDelta += (++curEvent)->startTime) {
 			const byte cmd = curEvent->command;
-			const byte data = curEvent->parameter;
-			const uint16 stopTime = curEvent->stopTime;
-			ChannelContext &channel = _channelCtx[data & 0x0F];
+			ChannelContext &channel = _channelCtx[curEvent->parameter & 0x0F];
 
 			// outPutEvent(*curEvent);
 			// debug("CurTime, EventDelta, NextDelta: %d, %d, %d", millis, eventDelta, eventDelta + curEvent[1].startTime );
 
 			if (cmd < 0x80) {	// Note
-				const uint16 vol = (data & 0xF0) >> 1;
-				const int8 voiceIndex = noteOn(channel, cmd, vol, kPriorityScore);
+				const int8 voiceIndex = noteOn(channel, cmd, (curEvent->parameter & 0xF0) >> 1, kPriorityScore);
 				if (voiceIndex >= 0) {
 					VoiceContext &voice = _voiceCtx[voiceIndex];
 					voice.stopEventCommand = cmd;
-					voice.stopEventParameter = data & 0x0F;
-					voice.stopEventTime = (eventDelta + stopTime) << 8;
+					voice.stopEventParameter = curEvent->parameter & 0x0F;
+					voice.stopEventTime = (eventDelta + curEvent->stopTime) << 8;
 				}
 
 			} else {
 				switch (cmd) {
 
 				case 0x80:	// TEMPO
-					if ((_playerCtx.tickUnit >> 8) > stopTime) {
-						setTempo(data << 4);
+					if ((_playerCtx.tickUnit >> 8) > curEvent->stopTime) {
+						_playerCtx.tickUnit = calcTempo(curEvent->parameter << 4, _playerCtx.vBlankFreq);
 						_playerCtx.tempoTime = 0;
 					} else {
 						_playerCtx.tempoStart = _playerCtx.tempo;
-						_playerCtx.tempoDelta = (data << 4) - _playerCtx.tempoStart;
-						_playerCtx.tempoTime  = (stopTime << 8);
+						_playerCtx.tempoDelta = (curEvent->parameter << 4) - _playerCtx.tempoStart;
+						_playerCtx.tempoTime  = (curEvent->stopTime << 8);
 						_playerCtx.tempoTicks = 0;
 					}
 					break;
 				
 				case 0xC0:	// PROGRAM
-					channel.patch = &_patch[stopTime & (kNumPatches - 1)];
+					channel.patch = &_patch[curEvent->stopTime & (kNumPatches - 1)];
 					break;
 
 				case 0xE0:	// BEND
-					channel.pitchBend = ((stopTime & 0x7F00) >> 1) | (stopTime & 0x7f);
+					channel.pitchBend = ((curEvent->stopTime & 0x7F00) >> 1) | (curEvent->stopTime & 0x7f);
 					channel.pitchReal = (((int32)channel.pitchBendRange * channel.pitchBend) >> 5) - (channel.pitchBendRange << 8);
 					channel.isAltered = true;
 					break;
@@ -151,7 +152,36 @@
 					// stop processing for this tick
 					goto endOfEventLoop;
 
-				case 0xA0:	// SPECIAL
+				case 0xA0: 	// SPECIAL
+					switch (curEvent->stopTime >> 8){
+					case 0x01:	// SPECIAL_SYNC
+						if (_playerCtx.syncCallBack)
+							_playerCtx.syncCallBack(curEvent->stopTime & 0xFF);
+						break;
+					case 0x02:	// SPECIAL_BEGINREP
+						// we allow a depth of 4 loops
+						for (int i = 0; i < ARRAYSIZE(_playerCtx.repeatPoint); ++i) {
+							if (!_playerCtx.repeatPoint[i]) {
+								_playerCtx.repeatPoint[i] = curEvent;
+								_playerCtx.repeatCount[i] = curEvent->stopTime & 0xFF;
+								break;
+							}
+						}
+						break;
+					case 0x03:	// SPECIAL_ENDREP
+						for (int i = ARRAYSIZE(_playerCtx.repeatPoint) - 1; i >= 0; --i) {
+							if (_playerCtx.repeatPoint[i]) {
+								if (_playerCtx.repeatCount[i]--)
+									curEvent = _playerCtx.repeatPoint[i]; // gets incremented by 1 at end of loop
+								else
+									_playerCtx.repeatPoint[i] = 0;
+								break;
+							}
+						}
+						break;
+					}
+					break;
+
 				case 0xB0:	// CONTROL
 					// TODO: controlChange((byte)stopTime, (byte)(stopTime >> 8))
 				default:
@@ -174,7 +204,7 @@
 				_playerCtx.tempoTime = 0;
 				newTempo += _playerCtx.tempoDelta;
 			}
-			setTempo(_playerCtx.tempoStart + newTempo);
+			_playerCtx.tickUnit = calcTempo(_playerCtx.tempoStart + newTempo, _playerCtx.vBlankFreq);
 		}
 	}
 
@@ -307,6 +337,11 @@
 	}
 }
 
+void MaxTrax::setTempo(const uint16 tempo) {
+	Common::StackLock lock(_mutex);
+	_playerCtx.tickUnit = calcTempo(tempo, _playerCtx.vBlankFreq);
+}
+
 void MaxTrax::stopMusic() {
 	Common::StackLock lock(_mutex);
 	_playerCtx.musicPlaying = false;
@@ -327,6 +362,8 @@
 	_playerCtx.scoreIndex = songIndex;
 	_playerCtx.ticks = 0;
 
+	for (int i = 0; i < ARRAYSIZE(_playerCtx.repeatPoint); ++i)
+		_playerCtx.repeatPoint[i] = 0;
 	for (int i = 0; i < ARRAYSIZE(_voiceCtx); ++i)
 		killVoice((byte)i);
 	for (int i = 0; i < kNumChannels; ++i)

Modified: scummvm/branches/gsoc2009-mods/sound/mods/maxtrax.h
===================================================================
--- scummvm/branches/gsoc2009-mods/sound/mods/maxtrax.h	2009-08-07 16:21:30 UTC (rev 43099)
+++ scummvm/branches/gsoc2009-mods/sound/mods/maxtrax.h	2009-08-07 18:02:06 UTC (rev 43100)
@@ -43,11 +43,15 @@
 	bool playSong(int songIndex, bool loop = false);
 	void advanceSong(int advance = 1);
 	int playNote(byte note, byte patch, uint16 duration, uint16 volume, bool rightSide);
-	void setVolume(const byte volume) { _playerCtx.volume = volume; }
-	void setTempo(const uint16 tempo) {
-		_playerCtx.tickUnit = (int32)(((uint32)(tempo & 0xFFF0) << 8) / (uint16)(5 * _playerCtx.vBlankFreq));
-	}
+	void setVolume(const byte volume) { Common::StackLock lock(_mutex); _playerCtx.volume = volume; }
+	void setTempo(const uint16 tempo);
 	void stopMusic();
+	/**
+	 * Set a callback function for sync-events.
+	 * @param callback Callback function, will be called synchronously, so DONT modify the player 
+	 *		directly in response
+	 */
+	void setSignalCallback(void (*callback) (int)) { Common::StackLock lock(_mutex); _playerCtx.syncCallBack = callback; }
 
 protected:
 	void interrupt();
@@ -95,6 +99,10 @@
 		int		scoreIndex;
 		const Event	*nextEvent;
 		int32	nextEventTime;
+
+		void (*syncCallBack) (int);
+		const Event	*repeatPoint[4];
+		byte	repeatCount[4];
 	} _playerCtx;
 
 	struct Envelope {


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