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

nolange at users.sourceforge.net nolange at users.sourceforge.net
Sat Jul 4 18:24:15 CEST 2009


Revision: 42096
          http://scummvm.svn.sourceforge.net/scummvm/?rev=42096&view=rev
Author:   nolange
Date:     2009-07-04 16:24:15 +0000 (Sat, 04 Jul 2009)

Log Message:
-----------
Added tons of members to MaxTrax, songs get fully loaded and stored internally

Modified Paths:
--------------
    scummvm/branches/gsoc2009-mods/dists/msvc9/scummvm-tfmx.vcproj
    scummvm/branches/gsoc2009-mods/sound/mods/maxtrax.cpp
    scummvm/branches/gsoc2009-mods/sound/mods/maxtrax.h
    scummvm/branches/gsoc2009-mods/tfmx/mxtxplayer.cpp
    scummvm/branches/gsoc2009-mods/tfmx/tfmxplayer.cpp

Modified: scummvm/branches/gsoc2009-mods/dists/msvc9/scummvm-tfmx.vcproj
===================================================================
--- scummvm/branches/gsoc2009-mods/dists/msvc9/scummvm-tfmx.vcproj	2009-07-04 15:45:04 UTC (rev 42095)
+++ scummvm/branches/gsoc2009-mods/dists/msvc9/scummvm-tfmx.vcproj	2009-07-04 16:24:15 UTC (rev 42096)
@@ -1147,6 +1147,14 @@
 				<File
 					RelativePath="..\..\sound\mods\maxtrax.cpp"
 					>
+					<FileConfiguration
+						Name="Debug_Command|Win32"
+						>
+						<Tool
+							Name="VCCLCompilerTool"
+							AssemblerOutput="2"
+						/>
+					</FileConfiguration>
 				</File>
 				<File
 					RelativePath="..\..\sound\mods\maxtrax.h"

Modified: scummvm/branches/gsoc2009-mods/sound/mods/maxtrax.cpp
===================================================================
--- scummvm/branches/gsoc2009-mods/sound/mods/maxtrax.cpp	2009-07-04 15:45:04 UTC (rev 42095)
+++ scummvm/branches/gsoc2009-mods/sound/mods/maxtrax.cpp	2009-07-04 16:24:15 UTC (rev 42096)
@@ -29,4 +29,164 @@
 #include "common/util.h"
 #include "common/debug.h"
 
-#include "sound/mods/maxtrax.h"
\ No newline at end of file
+#include "sound/mods/maxtrax.h"
+
+namespace Audio {
+
+MaxTrax::MaxTrax(int rate, bool stereo)
+	: Paula(stereo, rate, rate/50), _patch(), _scores(), _numScores(), _microtonal() {
+}
+
+MaxTrax::~MaxTrax() {
+	stopMusic();
+	freePatches();
+	freeScores();
+}
+
+void MaxTrax::interrupt() {
+}
+
+void MaxTrax::stopMusic() {
+}
+
+void MaxTrax::freeScores() {
+	if (_scores) {
+		for (int i = 0; i < _numScores; ++i)
+			delete _scores[i].events;
+		delete _scores;
+		_scores = 0;
+	}
+	_numScores = 0;
+	memset(_microtonal, 0, sizeof(_microtonal));
+}
+
+void MaxTrax::freePatches() {
+	for (int i = 0; i < ARRAYSIZE(_patch); ++i) {
+		delete[] _patch[i].samplePtr;
+		delete[] _patch[i].attackPtr;
+	}
+	memset(_patch, 0, sizeof(_patch));
+}
+
+bool MaxTrax::load(Common::SeekableReadStream &musicData, bool loadScores, bool loadSamples) {
+	bool res = false;
+	stopMusic();
+	if (loadSamples)
+		freePatches();
+	if (loadScores)
+		freeScores();
+	// 0x0000: 4 Bytes Header "MXTX"
+	// 0x0004: uint16 tempo
+	// 0x0006: uint16 flags. bit0 = lowpassfilter, bit1 = attackvolume, bit15 = microtonal	
+	if (musicData.readUint32BE() != 0x4D585458) {
+		warning("Maxtrax: File is not a Maxtrax Module");
+		return false;
+	}
+	_playerCtx.tempo = musicData.readUint16BE();
+	const uint16 flags = musicData.readUint16BE();
+	_playerCtx.filterOn = (flags & 1) != 0;
+	_playerCtx.handleVolume = (flags & 2) != 0;
+	debug("Header: MXTX %02X %02X", _playerCtx.tempo, flags);
+
+	if (loadScores && flags & (1 << 15)) {
+		debug("Song has microtonal");
+		for (int i = 0; i < ARRAYSIZE(_microtonal); ++i)
+			_microtonal[i] = musicData.readUint16BE();
+	}
+
+	int scoresLoaded = 0;
+	// uint16 number of Scores
+	const uint16 scoresInFile = musicData.readUint16BE();
+
+	if (loadScores) {
+		const uint16 scoremax = 128; // some variable which is set upon initialisation of player
+		const uint16 tempScores = MIN(scoresInFile, scoremax);
+		debug("#Scores: %d, loading # of scores: %d", scoresInFile, tempScores);
+		Score *curScore =_scores = new Score[tempScores];
+		
+		for (int i = tempScores; i > 0; --i, ++curScore) {
+			const uint32 numEvents = musicData.readUint32BE();
+			Event *curEvent = curScore->events = new Event[numEvents];
+			for (int j = numEvents; j > 0; --j, ++curEvent) {
+				curEvent->command = musicData.readByte();
+				curEvent->parameter = musicData.readByte();
+				curEvent->startTime = musicData.readUint16BE();
+				curEvent->stopTime = musicData.readUint16BE();
+			}
+			curScore->numEvents = numEvents;
+		}
+		_numScores = scoresLoaded = tempScores;
+	}
+
+	if (false && !loadSamples)
+		return true;
+
+	// skip over remaining scores in file
+	for (int i = scoresInFile - scoresLoaded; i > 0; --i)
+		musicData.skip(musicData.readUint32BE() * 6);
+
+	for (int i = 0; i < _numScores; ++i)
+		outPutScore(_scores[i], i);
+
+	debug("samples start at filepos %08X", musicData.pos());
+	// uint16 number of Samples
+	const uint16 wavesInFile = musicData.readUint16BE();
+	if (loadSamples) {
+		for (int i = wavesInFile; i > 0; --i) {
+			// load disksample structure
+			const uint16 number = musicData.readUint16BE();
+			assert(number < ARRAYSIZE(_patch));
+			// pointer to samples needed?
+			Patch &curPatch = _patch[number];
+
+			curPatch.tune = musicData.readUint16BE();
+			curPatch.volume = musicData.readUint16BE();
+			curPatch.sampleOctaves = musicData.readUint16BE();
+			curPatch.sampleAttack = musicData.readUint32BE();
+			curPatch.sampleSustain = musicData.readUint32BE();
+			// each octave the number of samples doubles.
+			const uint32 totalSamples = (curPatch.sampleAttack + curPatch.sampleSustain) * ((1 << curPatch.sampleOctaves) - 1);
+			curPatch.attackLen = musicData.readUint16BE();
+			curPatch.releaseLen = musicData.readUint16BE();
+			const uint32 totalEnvs = curPatch.attackLen + curPatch.releaseLen;
+
+			debug("wave nr %d at %08X - %d octaves", number, musicData.pos(), curPatch.sampleOctaves);
+			// Allocate space for both attack and release Segment.
+			Envelope *envPtr = new Envelope[totalEnvs];
+			// Attack Segment
+			curPatch.attackPtr = envPtr;
+			// Release Segment
+			// curPatch.releasePtr = envPtr + curPatch.attackLen;
+
+			// Read Attack and Release Segments
+			for (int j = totalEnvs; j > 0; --j, ++envPtr) {
+				envPtr->duration = musicData.readUint16BE();
+				envPtr->volume = musicData.readUint16BE();
+			}
+
+			// read Samples
+			curPatch.samplePtr = new int8[totalSamples];
+			musicData.read(curPatch.samplePtr, totalSamples);
+		}
+	} else if (wavesInFile > 0){
+		uint32 skipLen = 3 * 2;
+		for (int i = wavesInFile; i > 0; --i) {
+			musicData.skip(skipLen);
+			const uint16 octaves = musicData.readUint16BE();
+			const uint32 attackLen = musicData.readUint32BE();
+			const uint32 sustainLen = musicData.readUint32BE();
+			const uint16 attackCount = musicData.readUint16BE();
+			const uint16 releaseCount = musicData.readUint16BE();
+			debug("wave nr %d at %08X", 0, musicData.pos());
+			
+			skipLen = attackCount * 4 + releaseCount * 4 
+				+ (attackLen + sustainLen) * ((1 << octaves) - 1)
+				+ 3 * 2;
+		}
+		musicData.skip(skipLen - 3 * 2);
+	}
+	debug("endpos %08X", musicData.pos());
+	return res;
+}
+
+}	// End of namespace Audio
\ No newline at end of file

Modified: scummvm/branches/gsoc2009-mods/sound/mods/maxtrax.h
===================================================================
--- scummvm/branches/gsoc2009-mods/sound/mods/maxtrax.h	2009-07-04 15:45:04 UTC (rev 42095)
+++ scummvm/branches/gsoc2009-mods/sound/mods/maxtrax.h	2009-07-04 16:24:15 UTC (rev 42096)
@@ -35,9 +35,101 @@
 	MaxTrax(int rate, bool stereo);
 	virtual ~MaxTrax();
 
+protected:
 	void interrupt();
+
+private:
+public:
+
+	uint16	_microtonal[128];
+
+	struct PlayerContext {
+		uint16	tempo;
+		bool	filterOn;
+		bool	handleVolume;
+
+	} _playerCtx;
+
+	struct Envelope {
+		uint16	duration;
+		uint16	volume;
+	};
+
+	struct Patch {
+		Envelope *attackPtr;
+		//Envelope *releasePtr;
+		uint16	attackLen;
+		uint16	releaseLen;
+
+		uint16	tune;
+		uint16	volume;
+
+		// this was the SampleData struct in the assembler source
+		int8	*samplePtr;
+		uint32	sampleAttack;
+		uint32	sampleSustain;
+		uint16	sampleOctaves;
+	} _patch[64];
+
+	struct Event {
+		uint16	startTime;
+		uint16	stopTime;
+		byte	command;
+		byte	parameter;
+	};
+
+	struct Score {
+		Event	*events;
+		uint32	numEvents;
+	} *_scores;
+
+	int _numScores;
+
+
+
+	bool load(Common::SeekableReadStream &musicData, bool loadScores = true, bool loadSamples = true);
+
+	void stopMusic();
+	void freePatches();
+	void freeScores();
+
+	static void outPutEvent(const Event &ev, int num = -1) {
+		struct {
+			byte cmd;
+			char *name;
+			char *param;
+		} COMMANDS[] = {
+			{0x80, "TEMPO   ", "TEMPO, N/A      "},
+			{0xa0, "SPECIAL ", "CHAN, SPEC # | VAL"},
+			{0xb0, "CONTROL ", "CHAN, CTRL # | VAL"},
+			{0xc0, "PROGRAM ", "CHANNEL, PROG # "},
+			{0xe0, "BEND    ", "CHANNEL, BEND VALUE"},
+			{0xf0, "SYSEX   ", "TYPE, SIZE      "},
+			{0xf8, "REALTIME", "REALTIME, N/A   "},
+			{0xff, "END     ", "N/A, N/A        "},
+			{0xff, "NOTE    ", "VOL | CHAN, STOP"},
+		};
+
+		int i = 0;
+		for (; i < ARRAYSIZE(COMMANDS) - 1 && ev.command != COMMANDS[i].cmd; ++i)
+			;
+
+		if (num == -1)
+			debug("Event    : %02X %s %s %02X %04X %04X", ev.command, COMMANDS[i].name, COMMANDS[i].param, ev.parameter, ev.startTime, ev.stopTime);
+		else
+			debug("Event %3d: %02X %s %s %02X %04X %04X", num, ev.command, COMMANDS[i].name, COMMANDS[i].param, ev.parameter, ev.startTime, ev.stopTime);
+	}
+
+	static void outPutScore(const Score &sc, int num = -1) {
+		if (num == -1)
+			debug("score   : %i Events", sc.numEvents);
+		else
+			debug("score %2d: %i Events", num, sc.numEvents);
+		for (uint i = 0; i < sc.numEvents; ++i)
+			outPutEvent(sc.events[i], i);
+		debug("");
+	}
 };
-
 }	// End of namespace Audio
 
 #endif
\ No newline at end of file

Modified: scummvm/branches/gsoc2009-mods/tfmx/mxtxplayer.cpp
===================================================================
--- scummvm/branches/gsoc2009-mods/tfmx/mxtxplayer.cpp	2009-07-04 15:45:04 UTC (rev 42095)
+++ scummvm/branches/gsoc2009-mods/tfmx/mxtxplayer.cpp	2009-07-04 16:24:15 UTC (rev 42096)
@@ -11,204 +11,132 @@
 
 #if defined(MXTX_CMDLINE_TOOL)
 
-// #include "tfmx/tfmxdebug.h"
-
 #define FILEDIR "" 
 
 using namespace Common;
 
 #define MUSICFILE "introscr.mx"
+#define SAMPLEFILE "introinst.mx"
 
-bool load(Common::SeekableReadStream &musicData) {
-	bool res = false;
-
-	char buf[2 * 1024];
-	uint16 tempo, flags;
-	uint16 numScores;
-
-	// 0x0000: 4 Bytes Header "MXTX"
-	// 0x0004: uint16 tempo
-	// 0x0006: uint16 flags. bit0 = lowpassfilter, bit1 = attackvolume, bit15 = microtonal
-	musicData.read(buf, 4);
-	tempo = musicData.readUint16BE();
-	flags = musicData.readUint16BE();
-	buf[4] = '\0';
-	debug("Header: %s %02X %02X", buf, tempo, flags);
-
-	if (flags & (1 << 15)) {
-		// uint16 microtonal[128]
-		musicData.skip(128 * 2);
+Audio::MaxTrax *loadMtmxfile(const char *mdatName, const char *smplName) {
+	FSNode fileDir(FILEDIR);
+	FSNode musicNode = fileDir.getChild(mdatName);
+	FSNode sampleNode = fileDir.getChild(smplName);
+	SeekableReadStream *musicIn = musicNode.createReadStream();
+	if (0 == musicIn) {
+		debug("Couldnt load file %s", mdatName);
+		return 0;
 	}
 
-	// uint16 number of Scores
-	numScores = musicData.readUint16BE();
-	debug("#Scores: %d", numScores);
-	int scoresLoaded = 0;
-	byte *scorePtr; // array of scorestructures
-	for (int i = 0; i < numScores; ++i) {
-		uint32 numEvents = musicData.readUint32BE();
-		uint32 dataLength = numEvents * 6;
-		const int scoremax = 128; // some variable which is set upon initialisation of player
-		if (scoresLoaded < scoremax) {
-			// allocate dataLength zeroed bytes
-			// increase _globaldata+glob_TotalScores and _maxtrax+mxtx_TotalScores
-			// load events data
-			debug("score %i: %i Events", scoresLoaded, numEvents);
-			for (int j = 0; j < numEvents; ++j) {
-				byte command, data;
-				uint16 startTime, stopTime;
-				command = musicData.readByte();
-				data = musicData.readByte();
-				startTime = musicData.readUint16BE();
-				stopTime = musicData.readUint16BE();
-				debug("cmd, data, start, stop: %02X, %02X, %04X, %04X", command, data, startTime, stopTime);
+	Audio::MaxTrax *mxtxPlay = new Audio::MaxTrax(44100, true);
 
-			}
-			debug("");
-			// store pointer to events and # events in scorePtr, then increase scorePtr by structsize
-			scoresLoaded++;
-		} else
-			musicData.skip(dataLength);
+	if (!strcmp(mdatName, smplName)) {	
+		SeekableReadStream *sampleIn = sampleNode.createReadStream();
+		if (0 == sampleIn) {
+			debug("Couldnt load file %s", smplName);
+			delete musicIn;
+			return 0;
+		}
+		mxtxPlay->load(*musicIn, true, false);
+		mxtxPlay->load(*sampleIn, false, true);
+		delete sampleIn;
+	} else {
+		mxtxPlay->load(*musicIn, true, true);
 	}
 
-	uint16 numSamples;
-	// uint16 number of Samples
-	numSamples = musicData.readUint16BE();
-	for (int i = 0; i < numSamples; ++i) {
-		// load disksample structure
-		uint16 number = musicData.readUint16BE();
-		uint16 tune = musicData.readUint16BE();
-		uint16 volume = musicData.readUint16BE();
-		uint16 octaves = musicData.readUint16BE();
-		uint32 attackLen = musicData.readUint32BE();
-		uint32 sustainLen = musicData.readUint32BE();
-		uint16 attackCount = musicData.readUint16BE();
-		uint16 releaseCount = musicData.readUint16BE();
+	delete musicIn;
 
-		byte *samplePtr = 0; // samplestructure ptrs
-		samplePtr += number;
+	return mxtxPlay;
+}
 
-		byte *patchPtr = 0; // array of patchstructs
-		patchPtr += number;
+void runFlac(int chan, int bits, int sr, const char *fileName);
 
-		// Tune and Volume Info
-		// copy tune, volume to patch_Tune, patch_Volume
+void modcmdmain(const int argc, const char *const argv[]) {
+	debug("Started Scumm&VM");
+	debug("Sound celebrating utility for malcoms menace & Various Malfunctions");
+	debug("");
 
-		// Attack Segment
-		int attacksize = attackCount * 4;
-		// allocate attacksize bytes
-		// store allocated Ptr in patch_Attack
-		// store attackCount in patch_AttackCount
+	Audio::MaxTrax *player = loadMtmxfile(MUSICFILE, SAMPLEFILE);
+	if (!player) {
+		debug("couldnt create MXTX-Player");
+		return;
+	}
 
-		// read attack segment
-		for (int j = 0; j < attackCount; ++j) {
-			uint16 envDuration = musicData.readUint16BE();
-			uint16 envVolume = musicData.readUint16BE();
-			// store into patch_Attack
-		}
+		int i = 1;
+	int playflag = 1;
+	bool hasCmd = false;
 
-		// Release Segment
-		int releasesize = releaseCount * 4;
-		// allocate releasesize bytes
-		// store allocated Ptr in patch_Release
-		// store attackCount in patch_ReleaseCount
-
-		// read release segment
-		for (int j = 0; j < releaseCount; ++j) {
-			uint16 envDuration = musicData.readUint16BE();
-			uint16 envVolume = musicData.readUint16BE();
-			// store into patch_Release
+	
+	while (i < argc && argv[i][0] == '-') {
+		int param;
+		if (!strcmp("-s", argv[i])) {
+			if (i + 1 < argc) {
+				param = atoi(argv[++i]);
+				debug( "play Song %02X", param);
+				
+				hasCmd = true;
+			}
+		} else  if (!strcmp("-flac", argv[i])) {
+			playflag = 2;
 		}
+		++i;
+	}
 
+	if (!hasCmd) {
+	}
 
+	int maxsecs = 10 * 60;
+	if (playflag == 1) {
+		// get Mixer, assume this never fails 
+		Audio::Mixer *mixer = g_system->getMixer();
 
+		Audio::SoundHandle soundH;
 
+		mixer->playInputStream(Audio::Mixer::kMusicSoundType, &soundH, player);
+		while (mixer->isSoundHandleActive(soundH) && --maxsecs)
+			g_system->delayMillis(1000);
+//		player->AllOff();
 
+//		while (mixer->isSoundHandleActive(soundH));
 
-
-
-
-
-
-
-
+		mixer->stopHandle(soundH);
+		player = 0;
 	}
 
-	/*		
+	if (playflag == 2) {
+		Common::FSNode file("out.raw");
+		WriteStream *wav = file.createWriteStream();
+		int16 buf[2 * 1024];
+		int32 maxsamples = (maxsecs <= 0) ? 0 : maxsecs * 44100;
+		while (!player->endOfData() && maxsamples > 0) {
+			int read = player->readBuffer(buf, ARRAYSIZE(buf));
+			wav->write(buf, read * 2);
+			maxsamples -= read/2;
+		}
+		delete wav;
 
-		STRUCTURE	PatchData,0
-			APTR	patch_Sample				; Amiga sample data		
-			APTR	patch_Attack				; array of env. segments	
-			APTR	patch_Release				; array of env. segments	
-			WORD	patch_AttackCount			; number of attack env.	
-			WORD	patch_ReleaseCount			; number of release env.	
-			WORD	patch_Volume				; sample volume 			
-			WORD	patch_Tune					; sample tuning			
-			BYTE	patch_Number				; self-identifing			
-			BYTE	patch_pad
-			LABEL	patch_sizeof
-			
-		STRUCTURE	DiskSample,0
-			WORD	dsamp_Number
-			WORD	dsamp_Tune
-			WORD	dsamp_Volume
-			WORD	dsamp_Octaves
-			LONG	dsamp_AttackLength
-			LONG	dsamp_SustainLength
-			WORD	dsamp_AttackCount
-			WORD	dsamp_ReleaseCount
-			LABEL	dsamp_sizeof
-
-		STRUCTURE	CookedEvent,0
-			BYTE	cev_Command
-			BYTE	cev_Data
-			WORD	cev_StartTime
-			WORD	cev_StopTime
-			LABEL	cev_sizeof
-
-		STRUCTURE	EnvelopeData,0
-			WORD	env_Duration				; duration in milliseconds	
-			WORD	env_Volume					; volume of envelope		
-			LABEL	env_sizeof
-
-		STRUCTURE	SampleData,0
-			APTR	samp_NextSample
-			APTR	samp_Waveform
-			LONG	samp_AttackSize
-			LONG	samp_SustainSize
-			LABEL	samp_sizeof
-			*/
-	return res;
-}
-
-void *loadMtmxfile(const char *mdatName) {
-	FSNode fileDir(FILEDIR);
-	FSNode musicNode = fileDir.getChild(mdatName);
-	SeekableReadStream *musicIn = musicNode.createReadStream();
-	if (0 == musicIn) {
-		debug("Couldnt load file %s", mdatName);
-		return 0;
+		runFlac(2, 16, 44100, "out.raw");
 	}
+	delete player;
 
-	load(*musicIn);
-
-
-	delete musicIn;
-
-	return 0;
-}
-
-void modcmdmain(const int argc, const char *const argv[]) {
-	debug("Started Scumm&VM");
-	debug("Sound celebrating utility for malcoms menace & Various Malfunctions");
-	debug("");
-
-	loadMtmxfile(MUSICFILE);
-
 #ifdef _MSC_VER
 	printf("\npress a key");
 	getc(stdin);
 #endif
 }
 
+void runFlac( int chan, int bits, int sr, const char *fileName) {
+	const char *format = "flac --endian="
+#ifdef SCUMM_BIG_ENDIAN
+			"big"
+#else
+			"little"
+#endif
+			" --channels=%d -f --bps=%d --sample-rate=%d --sign=signed --force-raw-format %s";
+	char cmd[1024];
+	sprintf(cmd, format, chan, bits, sr, fileName);
+			debug(cmd);
+	system(cmd);
+}
+
 #endif // #if defined(MXTX_CMDLINE_TOOL)
\ No newline at end of file

Modified: scummvm/branches/gsoc2009-mods/tfmx/tfmxplayer.cpp
===================================================================
--- scummvm/branches/gsoc2009-mods/tfmx/tfmxplayer.cpp	2009-07-04 15:45:04 UTC (rev 42095)
+++ scummvm/branches/gsoc2009-mods/tfmx/tfmxplayer.cpp	2009-07-04 16:24:15 UTC (rev 42096)
@@ -26,13 +26,13 @@
 	FSNode sampleNode = fileDir.getChild(sampleName);
 	SeekableReadStream *musicIn = musicNode.createReadStream();
 	if (0 == musicIn) {
-		debug("Couldnt load file %s", MUSICFILE);
+		debug("Couldnt load file %s", mdatName);
 		return 0;
 	}
 
 	SeekableReadStream *sampleIn = sampleNode.createReadStream();
 	if (0 == sampleIn) {
-		debug("Couldnt load file %s", SAMPLEFILE);
+		debug("Couldnt load file %s", sampleName);
 		delete musicIn;
 		return 0;
 	}


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