[Scummvm-cvs-logs] CVS: scummvm/backends/midi/mt32 i386.cpp,1.1,1.2 i386.h,1.1,1.2 mt32emu.h,1.4,1.5 part.cpp,1.1,1.2 part.h,1.1,1.2 partial.cpp,1.7,1.8 partial.h,1.4,1.5 structures.h,1.7,1.8 synth.cpp,1.20,1.21 synth.h,1.7,1.8 tables.cpp,1.1,1.2 tables.h,1.1,1.2

Jerome Fisher kingguppy at users.sourceforge.net
Sat Nov 13 20:14:09 CET 2004


Update of /cvsroot/scummvm/scummvm/backends/midi/mt32
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18901/mt32

Modified Files:
	i386.cpp i386.h mt32emu.h part.cpp part.h partial.cpp 
	partial.h structures.h synth.cpp synth.h tables.cpp tables.h 
Log Message:
MT32 MidiDriver:
- Cleanup

MT32Emu:
- Lots more cleanup.
- Properly implemented pitch bending (not fast, but theoretically perfect).
- Full position delta is now calculated before PCM interpolation/decimation is performed, so that pitch modifiers will be considered.
- Now reports when using SSE or 3DNow, and when the samplerate is invalid.


Index: i386.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/midi/mt32/i386.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- i386.cpp	6 Nov 2004 01:41:30 -0000	1.1
+++ i386.cpp	14 Nov 2004 04:13:14 -0000	1.2
@@ -21,7 +21,7 @@
 
 #include "mt32emu.h"
 
-#ifdef HAVE_X86
+#ifdef MT32EMU_HAVE_X86
 
 namespace MT32Emu {
 
@@ -628,7 +628,7 @@
 	return output;
 }
 
-#if USE_MMX > 0
+#if MT32EMU_USE_MMX > 0
 
 int i386_partialProductOutput(int len, Bit16s leftvol, Bit16s rightvol, Bit16s *partialBuf, Bit16s *mixedBuf) {
 	int tmplen = len >> 1;

Index: i386.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/midi/mt32/i386.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- i386.h	6 Nov 2004 01:41:30 -0000	1.1
+++ i386.h	14 Nov 2004 04:13:14 -0000	1.2
@@ -23,7 +23,7 @@
 #define MT32EMU_I386_H
 
 namespace MT32Emu {
-#ifdef HAVE_X86
+#ifdef MT32EMU_HAVE_X86
 
 // Function that detects the availablity of SSE SIMD instructions
 bool DetectSIMD();
@@ -34,7 +34,7 @@
 float iir_filter_3dnow(float input,float *hist1_ptr, float *coef_ptr, int revLevel);
 float iir_filter_normal(float input,float *hist1_ptr, float *coef_ptr, int revLevel);
 
-#if USE_MMX > 0
+#if MT32EMU_USE_MMX > 0
 int i386_partialProductOutput(int len, Bit16s leftvol, Bit16s rightvol, Bit16s *partialBuf, Bit16s *mixedBuf);
 int i386_mixBuffers(Bit16s * buf1, Bit16s *buf2, int len);
 int i386_mixBuffersRingMix(Bit16s * buf1, Bit16s *buf2, int len);

Index: mt32emu.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/midi/mt32/mt32emu.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- mt32emu.h	13 Nov 2004 19:24:37 -0000	1.4
+++ mt32emu.h	14 Nov 2004 04:13:14 -0000	1.5
@@ -22,15 +22,49 @@
 #ifndef MT32EMU_MT32EMU_H
 #define MT32EMU_MT32EMU_H
 
+// Debugging
+// Show the instruments played
+#define MT32EMU_MONITOR_INSTRUMENTS 1
+// Shows number of partials MT-32 is playing, and on which parts
+#define MT32EMU_MONITOR_PARTIALS 0
+// Dump drum patches to syx file for viewing
+#define MT32EMU_DRUMP_DRUMS 0
+// Output benchmarks for the filter implementations
+#define MT32EMU_BENCHMARK_FILTERS 0
+// Determines how the waveform cache file is handled (must be regenerated after sampling rate change)
+#define MT32EMU_WAVECACHEMODE 0 // Load existing cache if possible, otherwise generate and save cache
+//#define MT32EMU_WAVECACHEMODE 1 // Load existing cache if possible, otherwise generage but don't save cache
+//#define MT32EMU_WAVECACHEMODE 2 // Ignore existing cache, generate and save cache
+//#define MT32EMU_WAVECACHEMODE 3 // Ignore existing cache, generate but don't save cache
+
+// Configuration
+// The maximum number of partials playing simultaneously
+#define MT32EMU_MAX_PARTIALS 32
+// The maximum number of notes playing simultaneously per part.
+// No point making it more than MT32EMU_MAX_PARTIALS, since each note needs at least one partial.
+#define MT32EMU_MAX_POLY 32
+// This calculates the exact frequencies of notes as they are played, instead of offsetting from pre-cached semitones. Potentially very slow.
+#define MT32EMU_ACCURATENOTES 0
+
+#if (defined (_MSC_VER) && defined(_M_IX86)) || (defined(__GNUC__) && defined(__i386__))
+#define MT32EMU_HAVE_X86
+#endif
+
+#ifdef MT32EMU_HAVE_X86
+#define MT32EMU_USE_MMX 1
+#else
+#define MT32EMU_USE_MMX 0
+#endif
+
 #include "freeverb.h"
 
 #include "structures.h"
 #include "i386.h"
 #include "mt32_file.h"
+#include "tables.h"
 #include "partial.h"
 #include "partialManager.h"
 #include "part.h"
-#include "tables.h"
 #include "synth.h"
 
 #endif

Index: part.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/midi/mt32/part.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- part.cpp	6 Nov 2004 01:41:30 -0000	1.1
+++ part.cpp	14 Nov 2004 04:13:14 -0000	1.2
@@ -24,10 +24,6 @@
 
 #include "mt32emu.h"
 
-// Debugging stuff
-// Shows the instruments played
-#define DISPLAYINSTR 1
-
 namespace MT32Emu {
 
 static const Bit8u PartialStruct[13] = {
@@ -38,12 +34,9 @@
 	0, 1, 0, 1, 1, 0,
 	1, 3, 3, 2, 2, 2, 2 };
 
-static const Bit32u drumBend = 0x1000;
-
 // This caches the timbres/settings in use by the rhythm part
 static PatchCache drumCache[94][4];
-
-static volset drumPan[64];
+static StereoVolume drumPan[64];
 
 //FIXME:KG: Put this dpoly stuff somewhere better
 bool dpoly::isActive() {
@@ -76,39 +69,49 @@
 		rhythmTemp = NULL;
 	}
 	currentInstr[0] = 0;
+	currentInstr[10] = 0;
 	volume = 102;
 	volumesetting.leftvol = 32767;
 	volumesetting.rightvol = 32767;
-	bend = 0x1000;
+	bend = 0.0f;
 	memset(polyTable,0,sizeof(polyTable));
 	memset(patchCache, 0, sizeof(patchCache));
 
 	if (isRhythm) {
 		init = true;
-		RefreshDrumCache();
+		refreshDrumCache();
 	}
 	init = false;
 }
 
-void Part::SetHoldPedal(bool pedalval) {
+void Part::setHoldPedal(bool pedalval) {
 	if (holdpedal && !pedalval)
-		StopPedalHold();
+		stopPedalHold();
 	holdpedal = pedalval;
 }
 
-void Part::SetBend(int vol) {
+void Part::setBend(int midiBend) {
 	if (isRhythm) {
-		synth->printDebug("%s: Setting bend (%d) not supported on rhythm", name, vol);
+		synth->printDebug("%s: Setting bend (%d) not supported on rhythm", name, midiBend);
 		return;
 	}
-	//int tmpbend = ((vol - 0x2000) * (int)patchTemp->patch.benderRange) >> 13;
-	//bend = bendtable[tmpbend+24];
-
-	float bend_range = (float)patchTemp->patch.benderRange / 24;
-	bend = (Bit32u)(4096 + (vol - 8192) * bend_range);
+	// FIXME:KG: Slightly uneven increments, but I wanted min -1.0, centre 0.0 and max 1.0
+	if (midiBend <= 0x2000) {
+		bend = (midiBend - 0x2000) / (float)0x2000;
+	} else {
+		bend = (midiBend - 0x2000) / (float)0x1FFF;
+	}
+	// Loop through all partials to update their bend
+	for (int i = 0; i < MT32EMU_MAX_POLY; i++) {
+		for (int j = 0; j < 4; j++) {
+			if (polyTable[i].partials[j] != NULL) {
+				polyTable[i].partials[j]->setBend(bend);
+			}
+		}
+	}
 }
 
-void Part::SetModulation(int vol) {
+void Part::setModulation(int vol) {
 	if (isRhythm) {
 		synth->printDebug("%s: Setting modulation (%d) not supported on rhythm", name, vol);
 		return;
@@ -124,7 +127,7 @@
 	}
 }
 
-void Part::RefreshDrumCache() {
+void Part::refreshDrumCache() {
 	if (!isRhythm) {
 		synth->printDebug("ERROR: RefreshDrumCache() called on non-rhythm part");
 	}
@@ -133,7 +136,7 @@
 		int drumTimbre = rhythmTemp[m].timbre;
 		if (drumTimbre >= 94)
 			continue;
-		SetPatch(drumTimbre + 128); // This is to cache all the mapped drum timbres ahead of time
+		setPatch(drumTimbre + 128); // This is to cache all the mapped drum timbres ahead of time
 		Bit16s pan = rhythmTemp[m].panpot; // They use R-L 0-14...
 		// FIXME:KG: If I don't have left/right mixed up here, it's pure luck
 		if (pan < 7) {
@@ -146,7 +149,7 @@
 	}
 }
 
-int Part::FixBiaslevel(int srcpnt, int *dir) {
+int Part::fixBiaslevel(int srcpnt, int *dir) {
 	int noteat = srcpnt & 63;
 	int outnote;
 	*dir = 1;
@@ -158,7 +161,7 @@
 	return outnote;
 }
 
-int Part::FixKeyfollow(int srckey, int *dir) {
+int Part::fixKeyfollow(int srckey, int *dir) {
 	if (srckey>=0 && srckey<=16) {
 		//int keyfix[17] = { 256, 128, 64, 0, 32, 64, 96, 128, 128+32, 192, 192+32, 256, 256+64, 256+128, 512, 259, 269 };
 		int keyfix[17] = { 256*16, 128*16, 64*16, 0, 32*16, 64*16, 96*16, 128*16, (128+32)*16, 192*16, (192+32)*16, 256*16, (256+64)*16, (256+128)*16, (512)*16, 4100, 4116};
@@ -177,11 +180,11 @@
 	}
 }
 
-void Part::RefreshPatch() {
-	SetPatch(-1);
+void Part::refreshPatch() {
+	setPatch(-1);
 }
 
-void Part::AbortPoly(dpoly *poly) {
+void Part::abortPoly(dpoly *poly) {
 	if (!poly->isPlaying) {
 		return;
 	}
@@ -210,8 +213,7 @@
 	return (patchTemp->patch.timbreGroup * 64) + patchTemp->patch.timbreNum;
 }
 
-void Part::SetPatch(int patchNum) {
-	int pcm;
+void Part::setPatch(int patchNum) {
 	int absTimbreNum = -1; // Initialised to please compiler
 	TimbreParam timSrc;
 	if (isRhythm) {
@@ -232,7 +234,7 @@
 		timSrc = *timbreTemp;
 #if 0
 		// Immediately stop all partials on this part (this is apparently *not* the correct behaviour)
-		for (int m = 0; m < MAXPOLY; m++) {
+		for (int m = 0; m < MT32EMU_MAX_POLY; m++) {
 			AbortPoly(poly);
 		}
 #else
@@ -240,7 +242,7 @@
 		// if so then duplicate the cached data from the part to the partial so that
 		// we can change the part's cache without affecting the partial.
 		// Hopefully this is fairly rare.
-		for (int m = 0; m < MAXPOLY; m++) {
+		for (int m = 0; m < MT32EMU_MAX_POLY; m++) {
 			for (int i = 0; i < 4; i++) {
 				Partial *partial = polyTable[m].partials[i];
 				if (partial != NULL) {
@@ -255,7 +257,6 @@
 	}
 
 	memcpy(currentInstr, timSrc.common.name, 10);
-	currentInstr[10] = 0;
 
 	int partialCount = 0;
 	for (int t=0;t<4;t++) {
@@ -269,33 +270,31 @@
 
 		// Calculate and cache common parameters
 
-		pcm = timSrc.partial[t].wg.pcmwave;
-
 		patchCache[t].pcm = timSrc.partial[t].wg.pcmwave;
 		patchCache[t].useBender = (timSrc.partial[t].wg.bender == 1);
 
 		switch (t) {
 		case 0:
 			patchCache[t].PCMPartial = (PartialStruct[(int)timSrc.common.pstruct12] & 0x2) ? true : false;
-			patchCache[t].mix = PartialMixStruct[(int)timSrc.common.pstruct12];
+			patchCache[t].structureMix = PartialMixStruct[(int)timSrc.common.pstruct12];
 			patchCache[t].structurePosition = 0;
 			patchCache[t].structurePair = 1;
 			break;
 		case 1:
 			patchCache[t].PCMPartial = (PartialStruct[(int)timSrc.common.pstruct12] & 0x1) ? true : false;
-			patchCache[t].mix = PartialMixStruct[(int)timSrc.common.pstruct12];
+			patchCache[t].structureMix = PartialMixStruct[(int)timSrc.common.pstruct12];
 			patchCache[t].structurePosition = 1;
 			patchCache[t].structurePair = 0;
 			break;
 		case 2:
 			patchCache[t].PCMPartial = (PartialStruct[(int)timSrc.common.pstruct34] & 0x2) ? true : false;
-			patchCache[t].mix = PartialMixStruct[(int)timSrc.common.pstruct34];
+			patchCache[t].structureMix = PartialMixStruct[(int)timSrc.common.pstruct34];
 			patchCache[t].structurePosition = 0;
 			patchCache[t].structurePair = 3;
 			break;
 		case 3:
 			patchCache[t].PCMPartial = (PartialStruct[(int)timSrc.common.pstruct34] & 0x1) ? true : false;
-			patchCache[t].mix = PartialMixStruct[(int)timSrc.common.pstruct34];
+			patchCache[t].structureMix = PartialMixStruct[(int)timSrc.common.pstruct34];
 			patchCache[t].structurePosition = 1;
 			patchCache[t].structurePair = 2;
 			break;
@@ -306,7 +305,7 @@
 		patchCache[t].waveform = timSrc.partial[t].wg.waveform;
 		patchCache[t].pulsewidth = timSrc.partial[t].wg.pulsewid;
 		patchCache[t].pwsens = timSrc.partial[t].wg.pwvelo;
-		patchCache[t].pitchkeyfollow = FixKeyfollow(timSrc.partial[t].wg.keyfollow, &patchCache[t].pitchkeydir);
+		patchCache[t].pitchkeyfollow = fixKeyfollow(timSrc.partial[t].wg.keyfollow, &patchCache[t].pitchkeydir);
 
 		// Calculate and cache pitch stuff
 		patchCache[t].pitchshift = timSrc.partial[t].wg.coarse;
@@ -339,9 +338,9 @@
 		else
 			patchCache[t].ampenvdir = 0;
 
-		patchCache[t].ampbias[0] = FixBiaslevel(patchCache[t].ampEnv.biaspoint1, &patchCache[t].ampdir[0]);
+		patchCache[t].ampbias[0] = fixBiaslevel(patchCache[t].ampEnv.biaspoint1, &patchCache[t].ampdir[0]);
 		patchCache[t].ampblevel[0] = 12 - patchCache[t].ampEnv.biaslevel1;
-		patchCache[t].ampbias[1] = FixBiaslevel(patchCache[t].ampEnv.biaspoint2, &patchCache[t].ampdir[1]);
+		patchCache[t].ampbias[1] = fixBiaslevel(patchCache[t].ampEnv.biaspoint2, &patchCache[t].ampdir[1]);
 		patchCache[t].ampblevel[1] = 12 - patchCache[t].ampEnv.biaslevel2;
 		patchCache[t].ampdepth = patchCache[t].ampEnv.envvkf * patchCache[t].ampEnv.envvkf;
 		patchCache[t].ampsustain = patchCache[t].ampEnv.envlevel[3];
@@ -350,9 +349,9 @@
 		// Calculate and cache filter stuff
 		patchCache[t].filtEnv = timSrc.partial[t].tvf;
 		patchCache[t].tvfdepth = patchCache[t].filtEnv.envdkf;
-		patchCache[t].filtkeyfollow  = FixKeyfollow(patchCache[t].filtEnv.keyfollow, &patchCache[t].keydir);
+		patchCache[t].filtkeyfollow  = fixKeyfollow(patchCache[t].filtEnv.keyfollow, &patchCache[t].keydir);
 		patchCache[t].filtEnv.envdepth = (char)((float)patchCache[t].filtEnv.envdepth * 1.27);
-		patchCache[t].tvfbias = FixBiaslevel(patchCache[t].filtEnv.biaspoint, &patchCache[t].tvfdir);
+		patchCache[t].tvfbias = fixBiaslevel(patchCache[t].filtEnv.biaspoint, &patchCache[t].tvfdir);
 		patchCache[t].tvfblevel = patchCache[t].filtEnv.biaslevel;
 		patchCache[t].filtsustain  = patchCache[t].filtEnv.envlevel[3];
 
@@ -366,17 +365,22 @@
 		// Common parameters, stored redundantly
 		patchCache[t].partialCount = partialCount;
 		patchCache[t].sustain = (timSrc.common.nosustain == 0);
+		if (isRhythm) {
+			patchCache[t].benderRange = 0;
+		} else {
+			patchCache[t].benderRange = patchTemp->patch.benderRange;
+		}
 	}
 	//synth->printDebug("Res 1: %d 2: %d 3: %d 4: %d", patchCache[0].waveform, patchCache[1].waveform, patchCache[2].waveform, patchCache[3].waveform);
 
 	if (isRhythm)
 		memcpy(drumCache[absTimbreNum - 128], patchCache, sizeof(patchCache));
 	else
-		AllStop();
-#if DISPLAYINSTR == 1
-	synth->printDebug("%s: Recache, param %d (timbre: %s), %d partials", name, patchNum, currentInstr, partialCount);
+		allStop();
+#if MT32EMU_MONITOR_INSTRUMENTS == 1
+	synth->printDebug("%s: Recache, param %d (timbre: %s)", name, patchNum, currentInstr);
 	for (int i = 0; i < 4; i++) {
-		synth->printDebug(" %d: play=%s, pcm=%d, wave=%d", i, patchCache[i].playPartial ? "YES" : "NO", timSrc.partial[i].wg.pcmwave, timSrc.partial[i].wg.waveform);
+		synth->printDebug(" %d: play=%s, pcm=%s (%d), wave=%d", i, patchCache[i].playPartial ? "YES" : "NO", patchCache[i].PCMPartial ? "YES" : "NO", timSrc.partial[i].wg.pcmwave, timSrc.partial[i].wg.waveform);
 	}
 #endif
 }
@@ -385,11 +389,11 @@
 	return name;
 }
 
-void Part::SetVolume(int vol) {
+void Part::setVolume(int vol) {
 	volume = voltable[vol];
 }
 
-void Part::SetPan(int pan) {
+void Part::setPan(int pan) {
 	// FIXME:KG: This is unchangeable for drums (they always use drumPan), is that correct?
 	// FIXME:KG: There is no way to get a centred balance here... And the middle two
 	// pan settings have a distance of 1024, double the usual.
@@ -405,7 +409,7 @@
 	//synth->printDebug("%s (%s): Set pan to %d", name, currentInstr, panpot);
 }
 
-void Part::PlayNote(PartialManager *partialManager, int f, int vel) {
+void Part::playNote(PartialManager *partialManager, int f, int vel) {
 	int drumNum = -1; // Initialised to please compiler
 	int drumTimbre = -1; // As above
 	int freqNum;
@@ -436,10 +440,10 @@
 	// Haven't found any software that uses any of the other poly modes
 	// FIXME:KG: Should this also apply to rhythm?
 	if (!isRhythm) {
-		for (int i = 0; i < MAXPOLY; i++) {
+		for (int i = 0; i < MT32EMU_MAX_POLY; i++) {
 			if (polyTable[i].isActive() && (polyTable[i].note == f)) {
 				//AbortPoly(&polyTable[i]);
-				StopNote(f);
+				stopNote(f);
 				break;
 			}
 		}
@@ -455,12 +459,12 @@
 	}
 	// Find free note
 	int m;
-	for (m = 0; m < MAXPOLY; m++) {
+	for (m = 0; m < MT32EMU_MAX_POLY; m++) {
 		if (!polyTable[m].isActive()) {
 			break;
 		}
 	}
-	if (m == MAXPOLY) {
+	if (m == MT32EMU_MAX_POLY) {
 		synth->printDebug("%s (%s): No free poly to play note %d (vel %d)", name, currentInstr, f, vel);
 		return;
 	}
@@ -490,33 +494,32 @@
 		synth->printDebug("%s (%s): No partials to play for this instrument", name, this->currentInstr);
 
 	if (isRhythm) {
-		tpoly->bendptr = &drumBend;
 		tpoly->pansetptr = &drumPan[drumNum];
 		tpoly->reverb = rhythmTemp[drumNum].reverbSwitch > 0;
 	} else {
-		tpoly->bendptr = &bend;
 		tpoly->pansetptr = &volumesetting;
 		tpoly->reverb = patchTemp->patch.reverbSwitch > 0;
 	}
 	tpoly->sustain = patchCache[0].sustain;
 	tpoly->volumeptr = &volume;
 
+#if MT32EMU_MONITOR_INSTRUMENTS == 1
+	if (isRhythm) {
+		synth->printDebug("%s (%s): starting poly %d (drum %d, timbre %d) - Vel %d Key %d Vol %d", name, currentInstr, m, drumNum, drumTimbre, vel, f, volume);
+	} else {
+		synth->printDebug("%s (%s): starting poly %d - Vel %d Key %d Vol %d", name, currentInstr, m, vel, f, volume);
+	}
+#endif
+
 	for (int x = 0; x < 4; x++) {
 		if (tpoly->partials[x] != NULL) {
 			tpoly->partials[x]->startPartial(tpoly, &patchCache[x], tpoly->partials[patchCache[x].structurePair]);
+			tpoly->partials[x]->setBend(bend);
 		}
 	}
-
-#if DISPLAYINSTR == 1
-	if (isRhythm) {
-		synth->printDebug("%s (%s): starting note poly %d (drum %d, timbre %d) - Vel %d Vol %d", name, currentInstr, m, drumNum, drumTimbre, vel, volume);
-	} else {
-		synth->printDebug("%s (%s): starting note poly %d - Vel %d Freq %d Vol %d", name, currentInstr, m, vel, f, volume);
-	}
-#endif
 }
 
-static void StartDecayPoly(dpoly *tpoly) {
+static void startDecayPoly(dpoly *tpoly) {
 	if (tpoly->isDecay) {
 		return;
 	}
@@ -531,41 +534,41 @@
 	tpoly->isPlaying = false;
 }
 
-void Part::AllStop() {
-	for (int q = 0; q < MAXPOLY; q++) {
+void Part::allStop() {
+	for (int q = 0; q < MT32EMU_MAX_POLY; q++) {
 		dpoly *tpoly = &polyTable[q];
 		if (tpoly->isPlaying) {
-			StartDecayPoly(tpoly);
+			startDecayPoly(tpoly);
 		}
 	}
 }
 
-void Part::StopPedalHold() {
-	for (int q = 0; q < MAXPOLY; q++) {
+void Part::stopPedalHold() {
+	for (int q = 0; q < MT32EMU_MAX_POLY; q++) {
 		dpoly *tpoly;
 		tpoly = &polyTable[q];
 		if (tpoly->isActive() && tpoly->pedalhold)
-			StopNote(tpoly->note);
+			stopNote(tpoly->note);
 	}
 }
 
-void Part::StopNote(int f) {
+void Part::stopNote(int f) {
 	// Non-sustaining instruments ignore stop note commands.
 	// They die away eventually anyway
 	//if (!tpoly->sustain) return;
 
-#if DISPLAYINSTR == 1
-	synth->printDebug("%s (%s): stopping note %d", name, currentInstr, f);
+#if MT32EMU_MONITOR_INSTRUMENTS == 1
+	synth->printDebug("%s (%s): stopping key %d", name, currentInstr, f);
 #endif
 
 	if (f != -1) {
-		for (int q = 0; q < MAXPOLY; q++) {
+		for (int q = 0; q < MT32EMU_MAX_POLY; q++) {
 			dpoly *tpoly = &polyTable[q];
 			if (tpoly->isPlaying && tpoly->note == f) {
 				if (holdpedal)
 					tpoly->pedalhold = true;
 				else if (tpoly->sustain)
-					StartDecayPoly(tpoly);
+					startDecayPoly(tpoly);
 			}
 		}
 		return;
@@ -576,7 +579,7 @@
 	int oldest = -1;
 	Bit64s oldage = -1;
 
-	for (int q = 0; q < MAXPOLY; q++) {
+	for (int q = 0; q < MT32EMU_MAX_POLY; q++) {
 		dpoly *tpoly = &polyTable[q];
 
 		if (tpoly->isPlaying && !tpoly->isDecay) {
@@ -588,7 +591,7 @@
 	}
 
 	if (oldest!=-1) {
-		StartDecayPoly(&polyTable[oldest]);
+		startDecayPoly(&polyTable[oldest]);
 	}
 }
 

Index: part.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/midi/mt32/part.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- part.h	6 Nov 2004 01:41:30 -0000	1.1
+++ part.h	14 Nov 2004 04:13:14 -0000	1.2
@@ -22,12 +22,6 @@
 #ifndef MT32EMU_PART_H
 #define MT32EMU_PART_H
 
-#define AMPENV 0
-#define FILTENV 1
-#define PITCHENV 2
-
-#define MAXPOLY 64
-
 namespace MT32Emu {
 
 class PartialManager;
@@ -52,38 +46,38 @@
 
 	bool holdpedal;
 
-	volset volumesetting;
+	StereoVolume volumesetting;
 
 	PatchCache patchCache[4];
 
-	Bit32u bend;
+	float bend; // -1.0 .. +1.0 
 	Bit32s volume;
 
-	dpoly polyTable[MAXPOLY];
+	dpoly polyTable[MT32EMU_MAX_POLY];
 
-	void AbortPoly(dpoly *poly);
+	void abortPoly(dpoly *poly);
+
+	static int fixKeyfollow(int srckey, int *dir);
+	static int fixBiaslevel(int srcpnt, int *dir);
 
 public:
 	Part(Synth *synth, int usePartNum);
 	char *getName();
-	void PlayNote(PartialManager *partialManager, int f, int vel);
-	void StopNote(int f);
-	void AllStop();
-	void SetVolume(int vol);
-	void SetPan(int vol);
-	void SetBend(int vol);
-	void SetModulation(int vol);
-	void SetPatch(int patchnum);
-	void SetHoldPedal(bool pedalval);
-	void StopPedalHold();
-	void RefreshPatch();
-	void RefreshDrumCache();
+	void playNote(PartialManager *partialManager, int f, int vel);
+	void stopNote(int f);
+	void allStop();
+	void setVolume(int vol);
+	void setPan(int vol);
+	void setBend(int vol);
+	void setModulation(int vol);
+	void setPatch(int patchnum);
+	void setHoldPedal(bool pedalval);
+	void stopPedalHold();
+	void refreshPatch();
+	void refreshDrumCache();
 	void setPatch(PatchParam *patch);
 	void setTimbre(TimbreParam *timbre);
 	unsigned int getAbsTimbreNum();
-
-	int FixKeyfollow(int srckey, int *dir);
-	int FixBiaslevel(int srcpnt, int *dir);
 };
 
 }

Index: partial.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/midi/mt32/partial.cpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- partial.cpp	13 Nov 2004 19:24:37 -0000	1.7
+++ partial.cpp	14 Nov 2004 04:13:14 -0000	1.8
@@ -34,6 +34,9 @@
 	pair = NULL;
 }
 
+Partial::~Partial() {
+}
+
 int Partial::getOwnerPart() {
 	return ownerPart;
 }
@@ -62,12 +65,12 @@
 	}
 }
 
-void Partial::initKeyFollow(int freqNum) {
+void Partial::initKeyFollow(int key) {
 	// Setup partial keyfollow
 	// Note follow relative to middle C
 	int keyfollow;
-	int realfol = (freqNum * 2 - MIDDLEC * 2) / 2;
-	int antirealfol = (MIDDLEC * 2 - freqNum * 2) / 2;
+	int realfol = (key * 2 - MIDDLEC * 2) / 2;
+	int antirealfol = (MIDDLEC * 2 - key * 2) / 2;
 	// Calculate keyfollow for pitch
 	switch(patchCache->pitchkeydir) {
 	case -1:
@@ -99,7 +102,7 @@
 		keyfollow = (antirealfol * patchCache->filtkeyfollow) >> 12;
 		break;
 	case 0:
-		keyfollow = freqNum;
+		keyfollow = key;
 		break;
 	case 1:
 		keyfollow = (realfol * patchCache->filtkeyfollow) >> 12;
@@ -120,11 +123,11 @@
 	}
 	patchCache = useCache;
 	poly = usePoly;
-	mixType = patchCache->mix;
+	mixType = patchCache->structureMix;
 	structurePosition = patchCache->structurePosition;
 
 	play = true;
-	initKeyFollow(poly->freqnum);
+	initKeyFollow(poly->freqnum); // Initialises noteVal, filtVal and realVal
 	lfoPos = 0;
 	pulsewidth = patchCache->pulsewidth + pwveltable[patchCache->pwsens][poly->vel];
 	if (pulsewidth > 100) {
@@ -174,10 +177,10 @@
 	while (length--) {
 		Bit32s envval, ampval;
 		Bit32s ptemp = 0;
-		if (envs[AMPENV].sustaining)
+		if (envs[EnvelopeType_amp].sustaining)
 			ampval = ampEnvCache;
 		else {
-			if (envs[AMPENV].count<=0) {
+			if (envs[EnvelopeType_amp].count <= 0) {
 				ampval = getAmpEnvelope();
 				if (!play) {
 					deactivate();
@@ -192,26 +195,26 @@
 				}
 
 				ampval = voltable[ampval];
-				int tmpvel = poly->vel;
+				int tmpvel;
 				if (patchCache->ampenvdir == 1)
-					tmpvel = 127 - tmpvel;
+					tmpvel = 127 - poly->vel;
+				else
+					tmpvel = poly->vel;
 				ampval = (ampval * ampveltable[tmpvel][(int)patchCache->ampEnv.velosens]) >> 8;
-				//if (envs[AMPENV].sustaining)
+				//if (envs[EnvelopeType_amp].sustaining)
 				ampEnvCache = ampval;
 			} else
 				ampval = ampEnvCache;
-			--envs[AMPENV].count;
+			--envs[EnvelopeType_amp].count;
 		}
 
-		int delta = 0x10707;
-
 		// Calculate Pitch envelope
 		int lfoat = 0x1000;
 		int pdep;
 		if (pitchSustain) {
 			// Calculate LFO position
 			// LFO does not kick in completely until pitch envelope sustains
-			if (patchCache->lfodepth>0) {
+			if (patchCache->lfodepth > 0) {
 				lfoPos++;
 				if (lfoPos >= patchCache->lfoperiod)
 					lfoPos = 0;
@@ -228,18 +231,23 @@
 				pitchEnvCache = pdep;
 		}
 
+		int delta;
+		// These two are only for PCM partials, obviously
+		PCMWaveEntry *pcmWave = NULL; // Initialise to please compiler
+		int pcmAddr = 0; // Initialise to please compiler
+
 		// Get waveform - either PCM or synthesized sawtooth or square
 		if (patchCache->PCMPartial) {
 			// PCM partial
-			int addr,len;
-			sampleTable *tPCM = &synth->PCMList[patchCache->pcm];
+			int len;
+			pcmWave = &synth->PCMList[patchCache->pcm];
 
-			if (tPCM->aggSound == -1) {
-				delta = wavtabler[tPCM->pcmnum][noteVal];
-				addr = tPCM->addr;
-				len = tPCM->len;
+			if (pcmWave->aggSound == -1) {
+				delta = wavtabler[pcmWave->pcmnum][noteVal];
+				pcmAddr = pcmWave->addr;
+				len = pcmWave->len;
 				if (partialOff.pcmplace >= len) {
-					if (tPCM->loop) {
+					if (pcmWave->loop) {
 						partialOff.pcmplace = partialOff.pcmoffset = 0;
 						// FIXME:KG: Use this?: partialOff.pcmplace %= len;
 					} else {
@@ -249,57 +257,67 @@
 					}
 				}
 			} else {
-				int tmppcm = LoopPatterns[tPCM->aggSound][loopPos];
-				delta = looptabler[tPCM->aggSound][loopPos][noteVal];
-				addr = synth->PCM[tmppcm].addr;
+				int tmppcm = LoopPatterns[pcmWave->aggSound][loopPos];
+				delta = looptabler[pcmWave->aggSound][loopPos][noteVal];
+				pcmAddr = synth->PCM[tmppcm].addr;
 				len = synth->PCM[tmppcm].len;
 				if (partialOff.pcmplace >= len) {
 					loopPos++;
-					if (LoopPatterns[tPCM->aggSound][loopPos]==-1)
-						loopPos=0;
+					if (LoopPatterns[pcmWave->aggSound][loopPos] == -1)
+						loopPos = 0;
 					partialOff.pcmplace = partialOff.pcmoffset = 0;
 				}
 			}
+		} else {
+			// Synthesis partial
+			delta = 0x10707;
+			partialOff.pcmplace %= (Bit16u)(divtable[noteVal] >> 15);
+		}
 
-			if (ampval>0) {
-				int ra,rb,dist;
+		// Build delta for position of next sample
+		// Fix delta code
+		Bit64s tdelta = (Bit64s)delta;
+		tdelta = (tdelta * patchCache->fineshift) >> 12;
+		tdelta = (tdelta * pdep) >> 12;
+		tdelta = (tdelta * lfoat) >> 12;
+		tdelta = (tdelta * bendShift) >> 12;
+		delta = (int)tdelta;
+
+		if (ampval > 0) {
+			if (patchCache->PCMPartial) {
+				// Render PCM sample
+				int ra, rb, dist;
 				int taddr;
-				if (delta<0x10000) {
+				if (delta < 0x10000) {
 					// Linear sound interpolation
-					taddr = addr + partialOff.pcmplace;
+					taddr = pcmAddr + partialOff.pcmplace;
 					if (taddr >= ROMSIZE) {
 						synth->printDebug("Overflow ROMSIZE!");
 						taddr = ROMSIZE - 1;
 					}
 					ra = synth->romfile[taddr];
-					rb = synth->romfile[taddr+1];
-					dist = rb-ra;
+					//FIXME:KG: Deal with condition that taddr + 1 is past PCM length
+					rb = synth->romfile[taddr + 1];
+					dist = rb - ra;
 					ptemp = (ra + ((dist * (Bit32s)(partialOff.pcmoffset >> 8)) >> 8));
 				} else {
 					// Sound decimation
 					// The right way to do it is to use a lowpass filter on the waveform before selecting
 					// a point.  This is too slow.  The following approximates this as fast as possible
 					int idelta = delta >> 16;
-					taddr = addr + partialOff.pcmplace;
+					taddr = pcmAddr + partialOff.pcmplace;
 					ra = 0;
 					for (int ix = 0; ix < idelta; ix++)
 						ra += synth->romfile[taddr++];
 					ptemp = ra / idelta;
 				}
-			}
-		} else {
-			// Synthesis partial
-			int divis = divtable[noteVal] >> 15;
-
-			partialOff.pcmplace %= (Bit16u)divis;
-
-			if (ampval > 0) {
-				int wf = patchCache->waveform ;
+			} else {
+				// Render synthesised sample
+				int divis = divtable[noteVal] >> 15;
+				int wf = patchCache->waveform;
 				int toff = partialOff.pcmplace;
 				int minorplace = partialOff.pcmoffset >> 14;
 
-				int pa, pb;
-
 				Bit32s filtval = getFiltEnvelope();
 
 				//synth->printDebug("Filtval: %d", filtval);
@@ -308,7 +326,7 @@
 					// Square waveform.  Made by combining two pregenerated bandlimited
 					// sawtooth waveforms
 					// Pulse width is not yet correct
-
+					int pa, pb;
 					int hdivis = divis >> 1;
 					int divmark = smalldivtable[noteVal];
 
@@ -371,18 +389,9 @@
 			}
 		}
 
-		// Build delta for position of next sample
-		// Fix delta code
-		Bit64s tdelta = (Bit64s)delta;
-		tdelta = (tdelta * patchCache->fineshift)>>12;
-		tdelta = (tdelta * pdep)>>12;
-		tdelta = (tdelta * lfoat)>>12;
-		if (patchCache->useBender)
-			tdelta = (tdelta * *poly->bendptr)>>12;
-
 		// Add calculated delta to our waveform offset
 		Bit32u absOff = ((partialOff.pcmplace << 16) | partialOff.pcmoffset);
-		absOff += (int)tdelta;
+		absOff += delta;
 		partialOff.pcmplace = (Bit16u)((absOff & 0xFFFF0000) >> 16);
 		partialOff.pcmoffset = (Bit16u)(absOff & 0xFFFF);
 
@@ -390,17 +399,31 @@
 		ptemp = (ptemp * ampval) >> 9;
 		ptemp = (ptemp * *poly->volumeptr) >> 7;
 
-		envs[AMPENV].envpos++;
-		envs[PITCHENV].envpos++;
-		envs[FILTENV].envpos++;
+		envs[EnvelopeType_amp].envpos++;
+		envs[EnvelopeType_pitch].envpos++;
+		envs[EnvelopeType_filt].envpos++;
 
 		*partialBuf++ = (Bit16s)ptemp;
 	}
+	// We may have deactivated and broken out of the loop before the end of the buffer,
+	// if so then fill the remainder with 0s.
 	if (++length > 0)
 		memset(partialBuf, 0, length * 2);
 	return &myBuffer[0];
 }
 
+void Partial::setBend(float factor) {
+	if (!patchCache->useBender || factor == 0.0f) {
+		bendShift = 4096;
+		return;
+	}
+	// NOTE:KG: We can't do this smoothly with lookup tables, unless we use several MB.
+	float bendSemitones = factor * patchCache->benderRange; // -24 .. 24
+	float mult = powf(2.0f, bendSemitones / 12.0f);
+	synth->printDebug("setBend(): semitones=%f, mult=%f, factor=%f, benderRange=%d\n", bendSemitones, mult, factor, patchCache->benderRange);
+	bendShift = (int)(mult * 4096.0f);
+}
+
 Bit16s *Partial::mixBuffers(Bit16s * buf1, Bit16s *buf2, int len) {
 	if (buf1 == NULL)
 		return buf2;
@@ -408,7 +431,7 @@
 		return buf1;
 
 	Bit16s *outBuf = buf1;
-#if USE_MMX >= 1
+#if MT32EMU_USE_MMX >= 1
 	// KG: This seems to be fine
 	int donelen = i386_mixBuffers(buf1, buf2, len);
 	len -= donelen;
@@ -438,7 +461,7 @@
 	}
 
 	Bit16s *outBuf = buf1;
-#if USE_MMX >= 1
+#if MT32EMU_USE_MMX >= 1
 	// KG: This seems to be fine
 	int donelen = i386_mixBuffersRingMix(buf1, buf2, len);
 	len -= donelen;
@@ -471,7 +494,7 @@
 	}
 
 	Bit16s *outBuf = buf1;
-#if USE_MMX >= 1
+#if MT32EMU_USE_MMX >= 1
 	// FIXME:KG: Not really checked as working
 	int donelen = i386_mixBuffersRing(buf1, buf2, len);
 	len -= donelen;
@@ -585,7 +608,7 @@
 	leftvol = poly->pansetptr->leftvol;
 	rightvol = poly->pansetptr->rightvol;
 
-#if USE_MMX >= 2
+#if MT32EMU_USE_MMX >= 2
 	// FIXME:KG: This appears to introduce crackle
 	int donelen = i386_partialProductOutput(length, leftvol, rightvol, partialBuf, mixedBuf);
 	length -= donelen;
@@ -605,7 +628,7 @@
 
 	int cutoff,depth,keyfollow, realfollow;
 
-	envstatus *tStat  = &envs[FILTENV];
+	envstatus *tStat  = &envs[EnvelopeType_filt];
 
 	keyfollow = filtVal;
 	realfollow = realVal;
@@ -621,7 +644,7 @@
 		if (tStat->envstat==4) {
 			reshigh = patchCache->filtsustain;
 			if (!poly->sustain) {
-				startDecay(FILTENV, reshigh);
+				startDecay(EnvelopeType_filt, reshigh);
 			}
 		} else {
 			if ((tStat->envstat==-1) || (tStat->envpos >= tStat->envsize)) {
@@ -713,7 +736,7 @@
 Bit32s Partial::getAmpEnvelope() {
 	Bit32s tc;
 
-	envstatus *tStat = &envs[AMPENV];
+	envstatus *tStat = &envs[EnvelopeType_amp];
 
 	if (!play)
 		return 0;
@@ -754,7 +777,7 @@
 				//synth->printDebug("Envstat %d, size %d", tStat->envstat, tStat->envsize);
 				tc = patchCache->ampsustain;
 				if (!poly->sustain)
-					startDecay(AMPENV, tc);
+					startDecay(EnvelopeType_amp, tc);
 				else
 					tStat->sustaining = true;
 
@@ -815,7 +838,7 @@
 }
 
 Bit32s Partial::getPitchEnvelope() {
-	envstatus *tStat  = &envs[PITCHENV];
+	envstatus *tStat = &envs[EnvelopeType_pitch];
 
 	Bit32s tc;
 	pitchSustain = false;
@@ -832,7 +855,7 @@
 			if (poly->sustain)
 				pitchSustain = true;
 			else
-				startDecay(PITCHENV, tc);
+				startDecay(EnvelopeType_pitch, tc);
 		} else {
 			if ((tStat->envstat==-1) || (tStat->envpos >= tStat->envsize)) {
 				tStat->envstat++;
@@ -853,13 +876,13 @@
 }
 
 void Partial::startDecayAll() {
-	startDecay(AMPENV, envs[AMPENV].prevlevel);
-	startDecay(FILTENV, envs[FILTENV].prevlevel);
-	startDecay(PITCHENV, envs[PITCHENV].prevlevel);
+	startDecay(EnvelopeType_amp, envs[EnvelopeType_amp].prevlevel);
+	startDecay(EnvelopeType_filt, envs[EnvelopeType_filt].prevlevel);
+	startDecay(EnvelopeType_pitch, envs[EnvelopeType_pitch].prevlevel);
 	pitchSustain = false;
 }
 
-void Partial::startDecay(int envnum, Bit32s startval) {
+void Partial::startDecay(EnvelopeType envnum, Bit32s startval) {
 	envstatus *tStat  = &envs[envnum];
 
 	tStat->sustaining = false;
@@ -868,15 +891,15 @@
 	tStat->envbase = startval;
 
 	switch(envnum) {
-	case AMPENV:
+	case EnvelopeType_amp:
 		tStat->envsize = (decaytimetable[(int)patchCache->ampEnv.envtime[4]] * timekeytable[(int)patchCache->ampEnv.envtkf][poly->freqnum]) >> 8;
 		tStat->envdist = -startval;
 		break;
-	case FILTENV:
+	case EnvelopeType_filt:
 		tStat->envsize = (decaytimetable[(int)patchCache->filtEnv.envtime[4]] * timekeytable[(int)patchCache->filtEnv.envtkf][poly->freqnum]) >> 8;
 		tStat->envdist = -startval;
 		break;
-	case PITCHENV:
+	case EnvelopeType_pitch:
 		tStat->envsize = (decaytimetable[(int)patchCache->pitchEnv.time[3]] * timekeytable[(int)patchCache->pitchEnv.timekeyfollow][poly->freqnum]) >> 8 ;
 		tStat->envdist = patchCache->pitchEnv.level[4] - startval;
 		break;

Index: partial.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/midi/mt32/partial.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- partial.h	6 Nov 2004 01:41:30 -0000	1.4
+++ partial.h	14 Nov 2004 04:13:14 -0000	1.5
@@ -24,6 +24,14 @@
 
 namespace MT32Emu {
 
+class Synth;
+
+enum EnvelopeType {
+	EnvelopeType_amp = 0,
+	EnvelopeType_filt = 1,
+	EnvelopeType_pitch = 2
+};
+
 struct envstatus {
 	Bit32s envpos;
 	Bit32s envstat;
@@ -39,8 +47,6 @@
 	Bit32s count;
 };
 
-class Synth;
-
 // Class definition of MT-32 partials.  32 in all.
 class Partial {
 private:
@@ -80,6 +86,8 @@
 
 	dpoly *poly;
 
+	int bendShift;
+
 	Bit16s *mixBuffers(Bit16s * buf1, Bit16s * buf2, int len);
 	Bit16s *mixBuffersRingMix(Bit16s * buf1, Bit16s * buf2, int len);
 	Bit16s *mixBuffersRing(Bit16s * buf1, Bit16s * buf2, int len);
@@ -100,14 +108,16 @@
 	Bit64s age;
 
 	Partial(Synth *synth);
+	~Partial();
 
 	int getOwnerPart();
 	bool isActive();
 	void activate(int part);
 	void deactivate(void);
 	void startPartial(dpoly *usePoly, PatchCache *useCache, Partial *pairPartial);
-	void startDecay(int envnum, Bit32s startval);
+	void startDecay(EnvelopeType envnum, Bit32s startval);
 	void startDecayAll();
+	void setBend(float factor);
 	bool shouldReverb();
 
 	// Returns true only if data written to buffer

Index: structures.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/midi/mt32/structures.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- structures.h	13 Nov 2004 19:24:37 -0000	1.7
+++ structures.h	14 Nov 2004 04:13:14 -0000	1.8
@@ -22,19 +22,10 @@
 #ifndef MT32EMU_STRUCTURES_H
 #define MT32EMU_STRUCTURES_H
 
-#if (defined (_MSC_VER) && defined(_M_IX86)) || (defined(__GNUC__) && defined(__i386__))
-#define HAVE_X86
-#endif
-
-#define MAX_SAMPLE_OUTPUT 4096
-#ifdef HAVE_X86
-#define USE_MMX 1
-#else
-#define USE_MMX 0
-#endif
-
 namespace MT32Emu {
 
+const unsigned int MAX_SAMPLE_OUTPUT = 4096;
+
 #ifdef _MSC_VER
 #define  MT32EMU_ALIGN_PACKED __declspec(align(1))
 typedef unsigned __int64   Bit64u;
@@ -195,7 +186,8 @@
 #pragma pack()
 #endif
 
-struct sampleFormat {
+struct PCMWave {
+	char name[16];
 	Bit32u addr;
 	Bit32u len;
 	bool loop;
@@ -203,7 +195,7 @@
 	Bit32s ampval;
 };
 
-struct sampleTable {
+struct PCMWaveEntry {
 	Bit32u addr;
 	Bit32u len;
 	Bit32u pcmnum;
@@ -216,7 +208,7 @@
 	Bit16u pcmoffset;
 };
 
-struct volset {
+struct StereoVolume {
 	Bit16s leftvol;
 	Bit16s rightvol;
 };
@@ -257,6 +249,7 @@
 	int tvfdepth;
 
 	bool useBender;
+	float benderRange; // 0.0, 1.0, .., 24.0 (semitones)
 
 	TimbreParam::partialParam::envParam pitchEnv;
 	TimbreParam::partialParam::tvaParam ampEnv;
@@ -266,7 +259,7 @@
 	Bit32s pitchsustain;
 	Bit32s filtsustain;
 
-	Bit32u mix;
+	Bit32u structureMix;
 	int structurePosition;
 	int structurePair;
 
@@ -288,9 +281,8 @@
 	bool reverb;
 	bool isDecay;
 
-	const Bit32u *bendptr;
-	Bit32s *volumeptr;
-	volset *pansetptr;
+	const Bit32s *volumeptr;
+	const StereoVolume *pansetptr;
 
 	Partial *partials[4];
 

Index: synth.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/midi/mt32/synth.cpp,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- synth.cpp	13 Nov 2004 19:24:37 -0000	1.20
+++ synth.cpp	14 Nov 2004 04:13:14 -0000	1.21
@@ -19,21 +19,16 @@
  * IN THE SOFTWARE.
  */
 
-#define BENCHMARK 0
-
 #include <math.h>
 #include <string.h>
 #include <stdlib.h>
 #include <errno.h>
-#if BENCHMARK > 0
-#include <time.h>
-#endif
 
 #include "mt32emu.h"
 
-// Debugging stuff
-// Used to dump drum patches to syx file for viewing
-#define DUMPDRUMS 0
+#if MT32EMU_BENCHMARK_FILTERS > 0
+#include <time.h>
+#endif
 
 namespace MT32Emu {
 
@@ -347,7 +342,8 @@
 		return false;
 	}
 
-	for (int i=0;i<54;i++) {
+	Bit32u PCMReassign[54];
+	for (int i = 0; i < 54; i++) {
 		PCMReassign[i] = i;
 		PCM[i].tune = 220.0f;
 		PCM[i].ampval = 256;
@@ -378,6 +374,8 @@
 			if (cp != NULL) {
 				cp = strtok(NULL," \n\r");
 				if (cp != NULL) {
+					strncpy(PCM[patchcount].name, cp, 15);
+					PCM[patchcount].name[15] = 0;
 					cp = strtok(NULL," \n\r");
 					if (cp !=NULL) {
 						int newpcm = atoi(cp);
@@ -581,7 +579,7 @@
 		return false;
 	}
 
-#if DUMPDRUMS == 1
+#if MT32EMU_DUMP_DRUMS == 1
 	strcpy(&pathBuf[0], baseDir);
 	dumpDrums(strcat(&pathBuf[0],"drumsys.syx"));
 #endif
@@ -605,12 +603,14 @@
 		mt32ram.params.patches[i].timbreNum = i & 63;
 	}
 
-	TableInitialiser tableInitialiser;
-	tableInitialiser.initMT32Tables(this, PCM, (float)myProp.SampleRate);
-	if (myProp.UseDefault)
-		initReverb(0,5);
+	if (!TableInitialiser::initMT32Tables(this, PCM, (float)myProp.sampleRate)) {
+		report(ReportType_errorSampleRate, NULL);
+		return false;
+	}
+	if (myProp.useDefaultReverb)
+		initReverb(0, 5);
 	else
-		initReverb(myProp.RevType, myProp.RevTime);
+		initReverb(myProp.reverbType, myProp.reverbTime);
 
 	for (int i = 0; i < 9; i++) {
 		parts[i] = new Part(this, i);
@@ -619,14 +619,14 @@
 			// The patch is already set by the presets, now set the timbre it wants
 			parts[i]->setTimbre(&mt32ram.params.timbres[parts[i]->getAbsTimbreNum()].timbre);
 			// And refresh the part's cache
-			parts[i]->RefreshPatch();
+			parts[i]->refreshPatch();
 		}
 	}
 
 	// For resetting mt32 mid-execution
 	mt32default = mt32ram;
 
-#ifdef HAVE_X86
+#ifdef MT32EMU_HAVE_X86
 	bool availableSSE = DetectSIMD();
 	bool available3DNow = Detect3DNow();
 
@@ -646,7 +646,7 @@
 	}
 #endif
 
-#if BENCHMARK > 1
+#if MT32EMU_BENCHMARK_FILTERS > 1
 	// Benchmark 3DNow, Floating point, and SSE filters
 	clock_t start, end;
 	float histval[50];
@@ -691,7 +691,7 @@
 		return;
 
 	for (int t = 0; t < 4; t++) {
-		for (int m = 0; m < 128; m++) {
+		for (int m = 0; m < NUM_NOTES; m++) {
 			if (waveforms[t][m]!=NULL) {
 				delete[] waveforms[t][m];
 				waveforms[t][m] = NULL;
@@ -743,51 +743,52 @@
 	case 0x8:
 		//printDebug("Note OFF - Part %d", part);
 		// The MT-32 ignores velocity for note off
-		parts[part]->StopNote(note);
+		parts[part]->stopNote(note);
 		break;
 	case 0x9:
 		//printDebug("Note ON - Part %d, Note %d Vel %d", part, note, velocity);
 		if (velocity == 0) {
 			// MIDI defines note-on with velocity 0 as being the same as note-off with velocity 40
-			parts[part]->StopNote(note);
+			parts[part]->stopNote(note);
 		} else {
-			parts[part]->PlayNote(partialManager, note, velocity);
+			parts[part]->playNote(partialManager, note, velocity);
 		}
 		break;
 	case 0xB: // Control change
 		switch (note) {
 		case 0x01:  // Modulation
 			//printDebug("Modulation: %d", velocity);
-			parts[part]->SetModulation(velocity);
-			break;
-		case 0x0B:
-			//printDebug("Expression set: %d", velocity);
-			parts[part]->SetVolume(velocity);
+			parts[part]->setModulation(velocity);
 			break;
 		case 0x07:  // Set volume
 			//if (part!=3) return;
 			//printDebug("Volume set: %d", velocity);
-			parts[part]->SetVolume(velocity);
+			parts[part]->setVolume(velocity);
 			break;
 		case 0x0A:  // Pan
 			//printDebug("Pan set: %d", velocity);
-			parts[part]->SetPan(velocity);
+			parts[part]->setPan(velocity);
+			break;
+		case 0x0B:
+			//printDebug("Expression set: %d", velocity);
+			parts[part]->setVolume(velocity);
 			break;
 		case 0x40: // Hold pedal
 			//printDebug("Hold pedal set: %d", velocity);
-			parts[part]->SetHoldPedal(velocity>=64);
+			parts[part]->setHoldPedal(velocity>=64);
 			break;
 
-		case 0x7B: // All notes off
-			//printDebug("All notes off");
-			parts[part]->AllStop();
-			break;
 		case 0x79: // Reset all controllers
 			printDebug("Reset all controllers (NYI)");
 			break;
 
+		case 0x7B: // All notes off
+			//printDebug("All notes off");
+			parts[part]->allStop();
+			break;
+
 		default:
-			printDebug("Unknown MIDI Control code: 0x%02x - vel %02x",note, velocity);
+			printDebug("Unknown MIDI Control code: 0x%02x - vel 0x%02x", note, velocity);
 			break;
 		}
 
@@ -795,7 +796,7 @@
 	case 0xC: // Program change
 		//printDebug("Program change %01x", note);
 		if (part < 8) {
-			parts[part]->SetPatch(note);
+			parts[part]->setPatch(note);
 		} else {
 			printDebug("Program change attempted on rhythm part");
 		}
@@ -803,7 +804,7 @@
 	case 0xE: // Pitch bender
 		bend = (velocity << 7) | (note);
 		//printDebug("Pitch bender %02x", bend);
-		parts[part]->SetBend(bend);
+		parts[part]->setBend(bend);
 		break;
 	default:
 		printDebug("Unknown Midi code: 0x%01x - %02x - %02x", code, note, velocity);
@@ -936,8 +937,13 @@
 			timbreName[10] = 0;
 			printDebug("WRITE-PARTPATCH (%d-%d@%d..%d): %d; timbre=%d (%s)", firstPart, lastPart, off, off + len, i, absTimbreNum, timbreName);
 			if (parts[i] != NULL) {
-				parts[i]->setTimbre(&mt32ram.params.timbres[parts[i]->getAbsTimbreNum()].timbre);
-				parts[i]->RefreshPatch();
+				if (i == firstPart && off > 2) {
+					printDebug(" (Not updating timbre, since those values weren't touched)");
+				} else {
+					// Not sure whether we should do this at all, really.
+					parts[i]->setTimbre(&mt32ram.params.timbres[parts[i]->getAbsTimbreNum()].timbre);
+				}
+				parts[i]->refreshPatch();
 			}
 		}
 	} else if (addr >= MEMADDR(0x030110) && addr < MEMADDR(0x040000)) {
@@ -963,7 +969,7 @@
 			printDebug("WRITE-RHYTHM (%d-%d@%d..%d): %d; level=%02x, panpot=%02x, reverb=%02x, timbre=%d (%s)", firstDrum, lastDrum, off, off + len, i, mt32ram.params.rhythmSettings[i].outlevel, mt32ram.params.rhythmSettings[i].panpot, mt32ram.params.rhythmSettings[i].reverbSwitch, mt32ram.params.rhythmSettings[i].timbre, timbreName);
 		}
 		if (parts[8] != NULL) {
-			parts[8]->RefreshDrumCache();
+			parts[8]->refreshDrumCache();
 		}
 	} else if (addr >= MEMADDR(0x040000) && addr < MEMADDR(0x050000)) {
 		int off = addr - MEMADDR(0x040000);
@@ -982,7 +988,7 @@
 			instrumentName[10] = 0;
 			printDebug("WRITE-PARTTIMBRE (%d-%d@%d..%d): timbre=%d (%s)", firstPart, lastPart, off, off + len, i, instrumentName);
 			if (parts[i] != NULL) {
-				parts[i]->RefreshPatch();
+				parts[i]->refreshPatch();
 			}
 		}
 	}
@@ -1053,12 +1059,12 @@
 			// Does the real MT-32 automatically do this?
 			if (i >= 128 && parts[8] != NULL) {
 				// FIXME:KG: Only bother to re-cache when this timbre's actually in the rhythm map
-				parts[8]->SetPatch(i); // Re-cache this timbre
+				parts[8]->setPatch(i); // Re-cache this timbre
 			}
 			for (unsigned int part = 0; part < 8; part++) {
 				if (parts[part] != NULL) {
 					if (parts[part]->getAbsTimbreNum() == i) {
-						parts[part]->RefreshPatch();
+						parts[part]->refreshPatch();
 					}
 				}
 			}
@@ -1080,7 +1086,7 @@
 		for (unsigned int i = 0; i < 9; i++) {
 			//LOG(LOG_MISC|LOG_ERROR,"Part %d set to MIDI channel %d",i,mt32ram.params.system.chanAssign[i]);
 			if (mt32ram.params.system.chanAssign[i] == 16) {
-				parts[i]->AllStop();
+				parts[i]->allStop();
 			} else {
 				chantable[(int)mt32ram.params.system.chanAssign[i]] = (char)i;
 			}
@@ -1093,12 +1099,12 @@
 		report(ReportType_newReverbLevel, &mt32ram.params.system.reverbLevel);
 
 		if ((mt32ram.params.system.reverbMode != curRevMode) || (mt32ram.params.system.reverbTime != curRevTime)) {
-			if (myProp.UseDefault) {
+			if (myProp.useDefaultReverb) {
 				initReverb(mt32ram.params.system.reverbMode, mt32ram.params.system.reverbTime);
 				curRevLevel = mt32ram.params.system.reverbLevel;
 			} else {
-				initReverb(myProp.RevType, myProp.RevTime);
-				curRevLevel = myProp.RevLevel;
+				initReverb(myProp.reverbType, myProp.reverbTime);
+				curRevLevel = myProp.reverbLevel;
 			}
 		}
 
@@ -1127,9 +1133,9 @@
 		partialManager->DeactivateAll();
 		mt32ram = mt32default;
 		for (int i = 0; i < 8; i++) {
-			parts[i]->RefreshPatch();
+			parts[i]->refreshPatch();
 		}
-		parts[8]->RefreshDrumCache();
+		parts[8]->refreshDrumCache();
 		isEnabled = false;
 	} else {
 		printDebug("Sysex write to unrecognised address %06x", SYSEXMEMADDR(addr));
@@ -1195,7 +1201,7 @@
 }
 
 void ProduceOutput1(Bit16s *useBuf, Bit16s *stream, Bit32u len, Bit16s volume) {
-#if USE_MMX > 2
+#if MT32EMU_USE_MMX > 2
 	//FIXME:KG: This appears to introduce crackle
 	int donelen = i386_produceOutput1(useBuf, stream, len, volume);
 	len -= donelen;
@@ -1226,9 +1232,9 @@
 
 	partialManager->AgeAll();
 
-	if (myProp.UseReverb) {
+	if (myProp.useReverb) {
 		bool hasOutput = false;
-		for (unsigned int i = 0; i < MAXPARTIALS; i++) {
+		for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
 			if (partialManager->shouldReverb(i)) {
 				if (partialManager->ProduceOutput(i, &tmpBuffer[0], len)) {
 					ProduceOutput1(&tmpBuffer[0], stream, len, mastervolume);
@@ -1254,7 +1260,7 @@
 				m++;
 			}
 		}
-		for (unsigned int i = 0; i < MAXPARTIALS; i++) {
+		for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
 			if (!partialManager->shouldReverb(i)) {
 				if (partialManager->ProduceOutput(i, &tmpBuffer[0], len)) {
 					ProduceOutput1(&tmpBuffer[0], stream, len, mastervolume);
@@ -1262,7 +1268,7 @@
 			}
 		}
 	} else {
-		for (unsigned int i = 0; i < MAXPARTIALS; i++) {
+		for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
 			if (partialManager->ProduceOutput(i, &tmpBuffer[0], len))
 				ProduceOutput1(&tmpBuffer[0], stream, len, mastervolume);
 		}
@@ -1270,14 +1276,14 @@
 
 	partialManager->ClearAlreadyOutputed();
 
-#if MONITORPARTIALS == 1
+#if MT32EMU_MONITOR_PARTIALS == 1
 	samplepos += len;
 	if (samplepos > myProp.SampleRate * 5) {
 		samplepos = 0;
 		int partialUsage[9];
 		partialManager->GetPerPartPartialUsage(partialUsage);
 		printDebug("1:%02d 2:%02d 3:%02d 4:%02d 5:%02d 6:%02d 7:%02d 8:%02d", partialUsage[0], partialUsage[1], partialUsage[2], partialUsage[3], partialUsage[4], partialUsage[5], partialUsage[6], partialUsage[7]);
-		printDebug("Rhythm: %02d  TOTAL: %02d", partialUsage[8], MAXPARTIALS - partialManager->GetFreePartialCount());
+		printDebug("Rhythm: %02d  TOTAL: %02d", partialUsage[8], MT32EMU_MAX_PARTIALS - partialManager->GetFreePartialCount());
 	}
 #endif
 }

Index: synth.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/midi/mt32/synth.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- synth.h	13 Nov 2004 19:24:37 -0000	1.7
+++ synth.h	14 Nov 2004 04:13:14 -0000	1.8
@@ -24,17 +24,14 @@
 
 #include <stdarg.h>
 
-// Shows number of partials MT-32 is playing
-#define MONITORPARTIALS 0
-
-#define ROMSIZE (512 * 1024)
-#define PCMSIZE (ROMSIZE / 2)
-#define GRAN 512
-
 class revmodel;
 
 namespace MT32Emu {
 
+const int ROMSIZE = 512 * 1024;
+const int PCMSIZE = ROMSIZE / 2;
+const int GRAN = 512;
+
 class File;
 class TableInitialiser;
 class Partial;
@@ -48,38 +45,39 @@
 	ReportType_errorDrumpat    = 3,
 	ReportType_errorPatchlog   = 4,
 	ReportType_errorMT32ROM    = 5,
+	ReportType_errorSampleRate = 6,
 
 	// HW spec
-	ReportType_availableSSE    = 6,
-	ReportType_available3DNow  = 7,
-	ReportType_usingSSE        = 8,
-	ReportType_using3DNow      = 9,
+	ReportType_availableSSE    = 7,
+	ReportType_available3DNow  = 8,
+	ReportType_usingSSE        = 9,
+	ReportType_using3DNow      = 10,
 
 	// General info
-	ReportType_lcdMessage      = 10,
-	ReportType_devReset        = 11,
-	ReportType_devReconfig     = 12,
-	ReportType_newReverbMode   = 13,
-	ReportType_newReverbTime   = 14,
-	ReportType_newReverbLevel  = 15
+	ReportType_lcdMessage      = 11,
+	ReportType_devReset        = 12,
+	ReportType_devReconfig     = 13,
+	ReportType_newReverbMode   = 14,
+	ReportType_newReverbTime   = 15,
+	ReportType_newReverbLevel  = 16
 };
 
 struct SynthProperties {
 	// Sample rate to use in mixing
-	int SampleRate;
+	int sampleRate;
 
 	// Flag to activate reverb.  True = use reverb, False = no reverb
-	bool UseReverb;
-	// Flag True to use software set reverb settings, Flag False to set reverb settings in
+	bool useReverb;
+	// True to use software set reverb settings, False to set reverb settings in
 	// following parameters
-	bool UseDefault;
+	bool useDefaultReverb;
 	// When not using the default settings, this specifies one of the 4 reverb types
 	// 1 = Room 2 = Hall 3 = Plate 4 = Tap
-	unsigned char RevType;
+	unsigned char reverbType;
 	// This specifies the delay time, from 0-7 (not sure of the actual MT-32's measurement)
-	unsigned char RevTime;
+	unsigned char reverbTime;
 	// This specifies the reverb level, from 0-7 (not sure of the actual MT-32's measurement)
-	unsigned char RevLevel;
+	unsigned char reverbLevel;
 	// The name of the directory in which the ROM and data files are stored (with trailing slash/backslash)
 	// Not used if "openFile" is set. May be NULL in any case.
 	char *baseDir;
@@ -116,15 +114,14 @@
 private:
 	bool isEnabled;
 
-	sampleFormat PCM[54];
-	sampleTable PCMList[128];
-	Bit32u PCMReassign[54];
+	PCMWave PCM[54];
+	PCMWaveEntry PCMList[128];
 	Bit32s PCMLoopTable[54];
 
 	Bit16s romfile[PCMSIZE + GRAN];
 	Bit8s chantable[32];
 
-	#if MONITORPARTIALS == 1
+	#if MT32EMU_MONITOR_PARTIALS == 1
 	static Bit32s samplepos = 0;
 	#endif
 

Index: tables.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/midi/mt32/tables.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- tables.cpp	6 Nov 2004 01:41:30 -0000	1.1
+++ tables.cpp	14 Nov 2004 04:13:14 -0000	1.2
@@ -25,15 +25,6 @@
 
 #include "mt32emu.h"
 
-// Determines how the waveform cache file is handled (must be regenerated after sampling rate change)
-#define WAVECACHEMODE 0 // Load existing cache if possible, otherwise generate and save cache
-//#define WAVECACHEMODE 1 // Load existing cache if possible, otherwise generage but don't save cache
-//#define WAVECACHEMODE 2 // Ignore existing cache, generate and save cache
-//#define WAVECACHEMODE 3 // Ignore existing cache, generate but don't save cache
-
-// Constant tuning for now
-#define TUNING 440.0f
-
 namespace MT32Emu {
 
 //Amplitude time velocity follow exponential coefficients
@@ -95,26 +86,25 @@
 Bit32s decaytimetable[101];
 Bit32s lasttimetable[101];
 Bit32s voltable[128];
-Bit32s bendtable[49];
 float ResonFactor[31];
 float ResonInv[31];
 
 // Per-note initialisation tables follow
 
-Bit16s freqtable[NUMNOTES];
-Bit32s fildeptable[5][NUMNOTES];
-Bit32s timekeytable[5][NUMNOTES];
-int filttable[2][NUMNOTES][201];
-int nfilttable[NUMNOTES][101][101];
+Bit16s freqtable[NUM_NOTES];
+Bit32s fildeptable[5][NUM_NOTES];
+Bit32s timekeytable[5][NUM_NOTES];
+int filttable[2][NUM_NOTES][201];
+int nfilttable[NUM_NOTES][101][101];
 
-Bit32s divtable[NUMNOTES];
-Bit32s smalldivtable[NUMNOTES];
-Bit32u wavtabler[54][NUMNOTES];
-Bit32u looptabler[9][10][NUMNOTES];
-Bit32s sawtable[NUMNOTES][101];
+Bit32s divtable[NUM_NOTES];
+Bit32s smalldivtable[NUM_NOTES];
+Bit32u wavtabler[54][NUM_NOTES];
+Bit32u looptabler[9][10][NUM_NOTES];
+Bit32s sawtable[NUM_NOTES][101];
 
-Bit16s *waveforms[4][NUMNOTES];
-Bit32u waveformsize[4][NUMNOTES];
+Bit16s *waveforms[4][NUM_NOTES];
+Bit32u waveformsize[4][NUM_NOTES];
 static Bit16s tmpforms[4][65536];
 
 
@@ -126,7 +116,7 @@
 static void prewarp(double *a1, double *a2, double fc, double fs) {
 	double wp;
 
-	wp = 2.0 * fs * tan(PI * fc / fs);
+	wp = 2.0 * fs * tan(DOUBLE_PI * fc / fs);
 
 	*a2 = *a2 / (wp * wp);
 	*a1 = *a1 / wp;
@@ -331,8 +321,6 @@
 		//FIXME:KG: I'm fairly sure this is wrong... lf=100 should yield no fine-tuning (4096)?
 		finetable[lf] = (int)((powf(2.0f, (((float)lf / 200.0f) - 1.0f) / 12.0f)) * 4096.0f);
 	}
-	for (lf = 0; lf <= 48; lf++)
-		bendtable[lf] = (int)((powf(2.0f, (((float)lf / 12.0f) - 2.0f))) * 4096.0f);
 
 	float lff;
 	for (lf = 0; lf < 128; lf++) {
@@ -345,7 +333,7 @@
 
 	for (lf = 0; lf < 128; lf++) {
 		// Converts MIDI velocity to volume.
-		voltable[lf] = (int)(127.0 * pow((float)lf / 127.0, LN));
+		voltable[lf] = (int)(127.0 * pow((float)lf / 127.0, DOUBLE_LN));
 	}
 	for (lf = 0; lf < MAX_SAMPLE_OUTPUT; lf++) {
 		int myRand;
@@ -440,7 +428,7 @@
 				dval = 1;
 				ampbiastable[lf][distval] = 256;
 			} else {
-				amplog = powf(1.431817011f, (float)lf) / (float)PI;
+				amplog = powf(1.431817011f, (float)lf) / FLOAT_PI;
 				dval = ((128.0f - (float)distval) / 128.0f);
 				amplog = expf(amplog);
 				dval = powf(amplog, dval) / amplog;
@@ -459,8 +447,8 @@
 				dval = 1;
 				fbiastable[lf][distval] = 256;
 			} else {
-				//amplog = pow(1.431817011, filval) / (float)PI;
-				amplog = powf(1.531817011f, filval) / (float)PI;
+				//amplog = pow(1.431817011, filval) / FLOAT_PI;
+				amplog = powf(1.531817011f, filval) / FLOAT_PI;
 				dval = (128.0f - (float)distval) / 128.0f;
 				amplog = expf(amplog);
 				dval = powf(amplog,dval)/amplog;
@@ -519,7 +507,7 @@
 }
 
 void TableInitialiser::initWave(Synth *synth, File *file, bool reading, bool writing, int f, float freq, float rate, double ampsize, Bit32s div) {
-	double sd = (2.0*PI)/((((float)div/65536.0)) * 4.0);
+	double sd = (2.0 * DOUBLE_PI) / ((((float)div / 65536.0)) * 4.0);
 	waveformsize[0][f] = div >> 14;
 	waveformsize[1][f] = div >> 14;
 	waveformsize[2][f] = div >> 14;
@@ -541,15 +529,15 @@
 		int fa = 0;
 		memset(tmpforms, 0,sizeof(tmpforms));
 
-		while (sa <= (2.0 * PI)) {
+		while (sa <= (2.0 * DOUBLE_PI)) {
 			float sqp;
 
-			if (sa < PI) {
+			if (sa < DOUBLE_PI) {
 				sqp = -1;
-				sqp = (float)(sqp + (0.25 * (sa/PI)));
+				sqp = (float)(sqp + (0.25 * (sa/DOUBLE_PI)));
 			} else {
 				sqp=1;
-				sqp = (float)(sqp - (0.25 * ((sa-PI)/PI)));
+				sqp = (float)(sqp - (0.25 * ((sa - DOUBLE_PI)/DOUBLE_PI)));
 			}
 
 			saw = 0;
@@ -565,8 +553,8 @@
 			tmpforms[1][fa] = (Bit16s)(saw * ampsize / 2);
 
 			tmpforms[2][fa] = (Bit16s)(cos(dumbfire) * -ampsize);
-			tmpforms[3][fa * 2] = (Bit16s)(cos(sa - PI) * -ampsize);
-			tmpforms[3][fa * 2 + 1] = (Bit16s)(cos((sa + (sd / 2)) - PI) * -ampsize);
+			tmpforms[3][fa * 2] = (Bit16s)(cos(sa - DOUBLE_PI) * -ampsize);
+			tmpforms[3][fa * 2 + 1] = (Bit16s)(cos((sa + (sd / 2)) - DOUBLE_PI) * -ampsize);
 
 			fa++;
 			sa += sd;
@@ -628,7 +616,7 @@
 	}
 }
 
-void TableInitialiser::initNotes(Synth *synth, sampleFormat pcms[54], float rate) {
+void TableInitialiser::initNotes(Synth *synth, PCMWave pcms[54], float rate) {
 	char filename[32];
 	int intRate = (int)rate;
 	sprintf(filename, "waveformcache-%d.raw", intRate);
@@ -645,7 +633,7 @@
 	header[pos++] = (char)((intRate >> 8) & 0xFF);
 	header[pos++] = (char)((intRate >> 16) & 0xFF);
 	header[pos] = (char)((intRate >> 24) & 0xFF);
-#if WAVECACHEMODE < 2
+#if MT32EMU_WAVECACHEMODE < 2
 	file = synth->openFile(filename, File::OpenMode_read);
 	if (file != NULL) {
 		char fileHeader[16];
@@ -662,7 +650,7 @@
 		synth->printDebug("Unable to open %s for reading - will generate", filename);
 	}
 #endif
-#if WAVECACHEMODE == 0 || WAVECACHEMODE == 2
+#if MT32EMU_WAVECACHEMODE == 0 || MT32EMU_WAVECACHEMODE == 2
 	if (!reading) {
 		file = synth->openFile(filename, File::OpenMode_write);
 		if (file != NULL) {
@@ -710,9 +698,10 @@
 		synth->closeFile(file);
 }
 
-void TableInitialiser::initMT32Tables(Synth *synth, sampleFormat pcms[54], float sampleRate) {
+bool TableInitialiser::initMT32Tables(Synth *synth, PCMWave pcms[54], float sampleRate) {
 	if (sampleRate <= 0.0f) {
 		synth->printDebug("Bad sampleRate (%d <= 0.0f)", sampleRate);
+		return false;
 	}
 	if (initialisedSampleRate == 0.0f) {
 		initMT32ConstantTables(synth);
@@ -722,6 +711,7 @@
 	}
 	// This always needs to be done, to allocate the waveforms
 	initNotes(synth, pcms, sampleRate);
+	return true;
 }
 
 }

Index: tables.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/midi/mt32/tables.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- tables.h	6 Nov 2004 01:41:30 -0000	1.1
+++ tables.h	14 Nov 2004 04:13:15 -0000	1.2
@@ -22,44 +22,50 @@
 #ifndef MT32EMU_TABLES_H
 #define MT32EMU_TABLES_H
 
+namespace MT32Emu {
+
 // Mathematical constants
-#ifndef PI
-#define PI 3.1415926535897932384626433832795
-#endif
-#ifndef LN
-#define LN 2.30258509
-#endif
+const double DOUBLE_PI = 3.1415926535897932384626433832795;
+const double DOUBLE_LN = 2.3025850929940456840179914546844;
+const float FLOAT_PI = 3.1415926535897932384626433832795f;
+const float FLOAT_LN = 2.3025850929940456840179914546844f;
 
 // Filter settings
-#define FILTERGRAN 512
+const int FILTERGRAN = 512;
 
-#define MIDDLEC 60
+const int MIDDLEC = 60;
+const int MIDDLEA = 69; // By this I mean "A above middle C"
 
-#define NUMNOTES 128 // MIDI supports 128 notes/keys
+// Constant tuning for now. The manual claims "Standard pitch" is 442.0.
+// I assume they mean this is the MT-32 default pitch, and not concert pitch,
+// since the latter has been internationally defined as 440Hz for decades.
+// FIXME:KG: Keeping it at 440.0f for now, as in original. Check with CC
+const float TUNING = 440.0f;
 
-// Amplitude of waveform generator
-#define WGAMP (7168)
-//#define WGAMP (8192)
+const int NUM_NOTES = 128; // MIDI supports 128 notes/keys
 
-namespace MT32Emu {
+// Amplitude of waveform generator
+const int WGAMP = 7168; // 8192?
 
 class Synth;
 
+extern const Bit8s LoopPatterns[9][10];
+
 extern Bit16s smallnoise[MAX_SAMPLE_OUTPUT];
 
 // Some optimization stuff
 extern Bit32s keytable[217];
-extern Bit32s divtable[NUMNOTES];
-extern Bit32s smalldivtable[NUMNOTES];
-extern Bit32u wavtabler[54][NUMNOTES];
-extern Bit32u looptabler[9][10][NUMNOTES];
+extern Bit32s divtable[NUM_NOTES];
+extern Bit32s smalldivtable[NUM_NOTES];
+extern Bit32u wavtabler[54][NUM_NOTES];
+extern Bit32u looptabler[9][10][NUM_NOTES];
 extern Bit16s sintable[65536];
 extern Bit32u lfotable[101];
 extern Bit32s penvtable[16][101];
 extern Bit32s filveltable[128][101];
 extern Bit32s veltkeytable[5][128];
 extern Bit32s pulsetable[101];
-extern Bit32s sawtable[NUMNOTES][101];
+extern Bit32s sawtable[NUM_NOTES][101];
 extern Bit32s ampbiastable[13][128];
 extern Bit32s fbiastable[15][128];
 extern float filtcoeff[FILTERGRAN][31][8];
@@ -73,23 +79,23 @@
 extern Bit32s voltable[128];
 extern float ResonInv[31];
 
-extern Bit16s freqtable[NUMNOTES];
-extern Bit32s fildeptable[5][NUMNOTES];
-extern Bit32s timekeytable[5][NUMNOTES];
-extern int filttable[2][NUMNOTES][201];
-extern int nfilttable[NUMNOTES][101][101];
+extern Bit16s freqtable[NUM_NOTES];
+extern Bit32s fildeptable[5][NUM_NOTES];
+extern Bit32s timekeytable[5][NUM_NOTES];
+extern int filttable[2][NUM_NOTES][201];
+extern int nfilttable[NUM_NOTES][101][101];
 
 extern const Bit8s LoopPatterns[9][10];
 
-extern Bit16s *waveforms[4][NUMNOTES];
-extern Bit32u waveformsize[4][NUMNOTES];
+extern Bit16s *waveforms[4][NUM_NOTES];
+extern Bit32u waveformsize[4][NUM_NOTES];
 
 class TableInitialiser {
-	void initMT32ConstantTables(Synth *synth);
-	void initWave(Synth *synth, File *file, bool reading, bool writing, int f, float freq, float rate, double ampsize, Bit32s div);
-	void initNotes(Synth *synth, sampleFormat pcms[54], float rate);
+	static void initMT32ConstantTables(Synth *synth);
+	static void initWave(Synth *synth, File *file, bool reading, bool writing, int f, float freq, float rate, double ampsize, Bit32s div);
+	static void initNotes(Synth *synth, PCMWave pcms[54], float rate);
 public:
-	void initMT32Tables(Synth *synth, sampleFormat pcms[54], float sampleRate);
+	static bool initMT32Tables(Synth *synth, PCMWave pcms[54], float sampleRate);
 };
 
 }





More information about the Scummvm-git-logs mailing list