[Scummvm-cvs-logs] scummvm master -> 4fd203ce40f348afecc9ff401773d5d401c7636a

bluegr bluegr at gmail.com
Tue Sep 24 10:35:14 CEST 2013


This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
eb84b9fc02 MT-32: Update to munt 1.3.0
4fd203ce40 NEWS: Mention update to munt 1.3.0


Commit: eb84b9fc02976c220b4b1d573d8ca84041de2e49
    https://github.com/scummvm/scummvm/commit/eb84b9fc02976c220b4b1d573d8ca84041de2e49
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2013-09-24T01:30:46-07:00

Commit Message:
MT-32: Update to munt 1.3.0

Changed paths:
    audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
    audio/softsynth/mt32/LA32WaveGenerator.cpp
    audio/softsynth/mt32/LA32WaveGenerator.h
    audio/softsynth/mt32/Partial.cpp
    audio/softsynth/mt32/Partial.h
    audio/softsynth/mt32/Synth.cpp
    audio/softsynth/mt32/Synth.h



diff --git a/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp b/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
index 486942b..0c9687b 100644
--- a/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
+++ b/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
@@ -315,15 +315,29 @@ void LA32PartialPair::generateNextSample(const PairType useMaster, const Bit32u
 	}
 }
 
+static inline float produceDistortedSample(float sample) {
+	if (sample < -1.0f) {
+		return sample + 2.0f;
+	} else if (1.0f < sample) {
+		return sample - 2.0f;
+	}
+	return sample;
+}
+
 float LA32PartialPair::nextOutSample() {
-	float outputSample;
-	if (ringModulated) {
-		float ringModulatedSample = masterOutputSample * slaveOutputSample;
-		outputSample = mixed ? masterOutputSample + ringModulatedSample : ringModulatedSample;
-	} else {
-		outputSample = masterOutputSample + slaveOutputSample;
+	if (!ringModulated) {
+		return masterOutputSample + slaveOutputSample;
 	}
-	return outputSample;
+	/*
+	 * SEMI-CONFIRMED: Ring modulation model derived from sample analysis of specially constructed patches which exploit distortion.
+	 * LA32 ring modulator found to produce distorted output in case if the absolute value of maximal amplitude of one of the input partials exceeds 8191.
+	 * This is easy to reproduce using synth partials with resonance values close to the maximum. It looks like an integer overflow happens in this case.
+	 * As the distortion is strictly bound to the amplitude of the complete mixed square + resonance wave in the linear space,
+	 * it is reasonable to assume the ring modulation is performed also in the linear space by sample multiplication.
+	 * Most probably the overflow is caused by limited precision of the multiplication circuit as the very similar distortion occurs with panning.
+	 */
+	float ringModulatedSample = produceDistortedSample(masterOutputSample) * produceDistortedSample(slaveOutputSample);
+	return mixed ? masterOutputSample + ringModulatedSample : ringModulatedSample;
 }
 
 void LA32PartialPair::deactivate(const PairType useMaster) {
diff --git a/audio/softsynth/mt32/LA32WaveGenerator.cpp b/audio/softsynth/mt32/LA32WaveGenerator.cpp
index 9ffc2ca..1d115c1 100644
--- a/audio/softsynth/mt32/LA32WaveGenerator.cpp
+++ b/audio/softsynth/mt32/LA32WaveGenerator.cpp
@@ -370,18 +370,12 @@ void LA32PartialPair::generateNextSample(const PairType useMaster, const Bit32u
 	}
 }
 
-Bit16s LA32PartialPair::unlogAndMixWGOutput(const LA32WaveGenerator &wg, const LogSample * const ringModulatingLogSample) {
-	if (!wg.isActive() || ((ringModulatingLogSample != NULL) && (ringModulatingLogSample->logValue == SILENCE.logValue))) {
+Bit16s LA32PartialPair::unlogAndMixWGOutput(const LA32WaveGenerator &wg) {
+	if (!wg.isActive()) {
 		return 0;
 	}
-	LogSample firstLogSample = wg.getOutputLogSample(true);
-	LogSample secondLogSample = wg.getOutputLogSample(false);
-	if (ringModulatingLogSample != NULL) {
-		LA32Utilites::addLogSamples(firstLogSample, *ringModulatingLogSample);
-		LA32Utilites::addLogSamples(secondLogSample, *ringModulatingLogSample);
-	}
-	Bit16s firstSample = LA32Utilites::unlog(firstLogSample);
-	Bit16s secondSample = LA32Utilites::unlog(secondLogSample);
+	Bit16s firstSample = LA32Utilites::unlog(wg.getOutputLogSample(true));
+	Bit16s secondSample = LA32Utilites::unlog(wg.getOutputLogSample(false));
 	if (wg.isPCMWave()) {
 		return Bit16s(firstSample + ((Bit32s(secondSample - firstSample) * wg.getPCMInterpolationFactor()) >> 7));
 	}
@@ -389,19 +383,32 @@ Bit16s LA32PartialPair::unlogAndMixWGOutput(const LA32WaveGenerator &wg, const L
 }
 
 Bit16s LA32PartialPair::nextOutSample() {
-	if (ringModulated) {
-		LogSample slaveFirstLogSample = slave.getOutputLogSample(true);
-		LogSample slaveSecondLogSample = slave.getOutputLogSample(false);
-		Bit16s sample = unlogAndMixWGOutput(master, &slaveFirstLogSample);
-		if (!slave.isPCMWave()) {
-			sample += unlogAndMixWGOutput(master, &slaveSecondLogSample);
-		}
-		if (mixed) {
-			sample += unlogAndMixWGOutput(master, NULL);
-		}
-		return sample;
+	if (!ringModulated) {
+		return unlogAndMixWGOutput(master) + unlogAndMixWGOutput(slave);
 	}
-	return unlogAndMixWGOutput(master, NULL) + unlogAndMixWGOutput(slave, NULL);
+
+	/*
+	 * SEMI-CONFIRMED: Ring modulation model derived from sample analysis of specially constructed patches which exploit distortion.
+	 * LA32 ring modulator found to produce distorted output in case if the absolute value of maximal amplitude of one of the input partials exceeds 8191.
+	 * This is easy to reproduce using synth partials with resonance values close to the maximum. It looks like an integer overflow happens in this case.
+	 * As the distortion is strictly bound to the amplitude of the complete mixed square + resonance wave in the linear space,
+	 * it is reasonable to assume the ring modulation is performed also in the linear space by sample multiplication.
+	 * Most probably the overflow is caused by limited precision of the multiplication circuit as the very similar distortion occurs with panning.
+	 */
+	Bit16s nonOverdrivenMasterSample = unlogAndMixWGOutput(master); // Store master partial sample for further mixing
+	Bit16s masterSample = nonOverdrivenMasterSample << 2;
+	masterSample >>= 2;
+
+	/* SEMI-CONFIRMED from sample analysis:
+	 * We observe that for partial structures with ring modulation the interpolation is not applied to the slave PCM partial.
+	 * It's assumed that the multiplication circuitry intended to perform the interpolation on the slave PCM partial
+	 * is borrowed by the ring modulation circuit (or the LA32 chip has a similar lack of resources assigned to each partial pair).
+	 */
+	Bit16s slaveSample = slave.isPCMWave() ? LA32Utilites::unlog(slave.getOutputLogSample(true)) : unlogAndMixWGOutput(slave);
+	slaveSample <<= 2;
+	slaveSample >>= 2;
+	Bit16s ringModulatedSample = Bit16s(((Bit32s)masterSample * (Bit32s)slaveSample) >> 13);
+	return mixed ? nonOverdrivenMasterSample + ringModulatedSample : ringModulatedSample;
 }
 
 void LA32PartialPair::deactivate(const PairType useMaster) {
diff --git a/audio/softsynth/mt32/LA32WaveGenerator.h b/audio/softsynth/mt32/LA32WaveGenerator.h
index 4bc04c7..b5f4ded 100644
--- a/audio/softsynth/mt32/LA32WaveGenerator.h
+++ b/audio/softsynth/mt32/LA32WaveGenerator.h
@@ -209,7 +209,7 @@ class LA32PartialPair {
 	bool ringModulated;
 	bool mixed;
 
-	static Bit16s unlogAndMixWGOutput(const LA32WaveGenerator &wg, const LogSample * const ringModulatingLogSample);
+	static Bit16s unlogAndMixWGOutput(const LA32WaveGenerator &wg);
 
 public:
 	enum PairType {
diff --git a/audio/softsynth/mt32/Partial.cpp b/audio/softsynth/mt32/Partial.cpp
index c7848f0..75e6740 100644
--- a/audio/softsynth/mt32/Partial.cpp
+++ b/audio/softsynth/mt32/Partial.cpp
@@ -24,15 +24,10 @@
 
 namespace MT32Emu {
 
-#ifdef INACCURATE_SMOOTH_PAN
-// Mok wanted an option for smoother panning, and we love Mok.
-static const float PAN_NUMERATOR_NORMAL[] = {0.0f, 0.5f, 1.0f, 1.5f, 2.0f, 2.5f, 3.0f, 3.5f, 4.0f, 4.5f, 5.0f, 5.5f, 6.0f, 6.5f, 7.0f};
-#else
-// CONFIRMED by Mok: These NUMERATOR values (as bytes, not floats, obviously) are sent exactly like this to the LA32.
-static const float PAN_NUMERATOR_NORMAL[] = {0.0f, 0.0f, 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f, 4.0f, 4.0f, 5.0f, 5.0f, 6.0f, 6.0f, 7.0f};
-#endif
-static const float PAN_NUMERATOR_MASTER[] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f};
-static const float PAN_NUMERATOR_SLAVE[]  = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 7.0f, 7.0f, 7.0f, 7.0f, 7.0f, 7.0f, 7.0f};
+static const Bit8u PAN_NUMERATOR_MASTER[] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7};
+static const Bit8u PAN_NUMERATOR_SLAVE[]  = {0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7};
+
+static const Bit32s PAN_FACTORS[] = {0, 18, 37, 55, 73, 91, 110, 128, 146, 165, 183, 201, 219, 238, 256};
 
 Partial::Partial(Synth *useSynth, int useDebugPartialNum) :
 	synth(useSynth), debugPartialNum(useDebugPartialNum), sampleNum(0) {
@@ -116,24 +111,30 @@ void Partial::startPartial(const Part *part, Poly *usePoly, const PatchCache *us
 	structurePosition = patchCache->structurePosition;
 
 	Bit8u panSetting = rhythmTemp != NULL ? rhythmTemp->panpot : part->getPatchTemp()->panpot;
-	float panVal;
 	if (mixType == 3) {
 		if (structurePosition == 0) {
-			panVal = PAN_NUMERATOR_MASTER[panSetting];
+			panSetting = PAN_NUMERATOR_MASTER[panSetting] << 1;
 		} else {
-			panVal = PAN_NUMERATOR_SLAVE[panSetting];
+			panSetting = PAN_NUMERATOR_SLAVE[panSetting] << 1;
 		}
 		// Do a normal mix independent of any pair partial.
 		mixType = 0;
 		pairPartial = NULL;
 	} else {
-		panVal = PAN_NUMERATOR_NORMAL[panSetting];
+		// Mok wanted an option for smoother panning, and we love Mok.
+#ifndef INACCURATE_SMOOTH_PAN
+		// CONFIRMED by Mok: exactly bytes like this (right shifted?) are sent to the LA32.
+		panSetting &= 0x0E;
+#endif
 	}
 
-	// FIXME: Sample analysis suggests that the use of panVal is linear, but there are some some quirks that still need to be resolved.
-	// FIXME: I suppose this should be panVal / 8 and undoubtly integer, clarify ASAP
-	stereoVolume.leftVol = panVal / 7.0f;
-	stereoVolume.rightVol = 1.0f - stereoVolume.leftVol;
+	leftPanValue = synth->reversedStereoEnabled ? 14 - panSetting : panSetting;
+	rightPanValue = 14 - leftPanValue;
+
+#if !MT32EMU_USE_FLOAT_SAMPLES
+	leftPanValue = PAN_FACTORS[leftPanValue];
+	rightPanValue = PAN_FACTORS[rightPanValue];
+#endif
 
 	// SEMI-CONFIRMED: From sample analysis:
 	// Found that timbres with 3 or 4 partials (i.e. one using two partial pairs) are mixed in two different ways.
@@ -150,8 +151,8 @@ void Partial::startPartial(const Part *part, Poly *usePoly, const PatchCache *us
 	// For my personal taste, this behaviour rather enriches the sounding and should be emulated.
 	// Also, the current partial allocator model probably needs to be refined.
 	if (debugPartialNum & 8) {
-		stereoVolume.leftVol = -stereoVolume.leftVol;
-		stereoVolume.rightVol = -stereoVolume.rightVol;
+		leftPanValue = -leftPanValue;
+		rightPanValue = -rightPanValue;
 	}
 
 	if (patchCache->PCMPartial) {
@@ -230,39 +231,6 @@ Bit32u Partial::getCutoffValue() {
 	return (tvf->getBaseCutoff() << 18) + cutoffModifierRampVal;
 }
 
-unsigned long Partial::generateSamples(Sample *partialBuf, unsigned long length) {
-	if (!isActive() || alreadyOutputed) {
-		return 0;
-	}
-	if (poly == NULL) {
-		synth->printDebug("[Partial %d] *** ERROR: poly is NULL at Partial::generateSamples()!", debugPartialNum);
-		return 0;
-	}
-	alreadyOutputed = true;
-
-	for (sampleNum = 0; sampleNum < length; sampleNum++) {
-		if (!tva->isPlaying() || !la32Pair.isActive(LA32PartialPair::MASTER)) {
-			deactivate();
-			break;
-		}
-		la32Pair.generateNextSample(LA32PartialPair::MASTER, getAmpValue(), tvp->nextPitch(), getCutoffValue());
-		if (hasRingModulatingSlave()) {
-			la32Pair.generateNextSample(LA32PartialPair::SLAVE, pair->getAmpValue(), pair->tvp->nextPitch(), pair->getCutoffValue());
-			if (!pair->tva->isPlaying() || !la32Pair.isActive(LA32PartialPair::SLAVE)) {
-				pair->deactivate();
-				if (mixType == 2) {
-					deactivate();
-					break;
-				}
-			}
-		}
-		*(partialBuf++) = la32Pair.nextOutSample();
-	}
-	unsigned long renderedSamples = sampleNum;
-	sampleNum = 0;
-	return renderedSamples;
-}
-
 bool Partial::hasRingModulatingSlave() const {
 	return pair != NULL && structurePosition == 0 && (mixType == 1 || mixType == 2);
 }
@@ -305,19 +273,52 @@ bool Partial::produceOutput(Sample *leftBuf, Sample *rightBuf, unsigned long len
 		synth->printDebug("[Partial %d] *** ERROR: poly is NULL at Partial::produceOutput()!", debugPartialNum);
 		return false;
 	}
-	Sample buffer[MAX_SAMPLES_PER_RUN];
-	unsigned long numGenerated = generateSamples(buffer, length);
-	for (unsigned int i = 0; i < numGenerated; i++) {
+	alreadyOutputed = true;
+
+	for (sampleNum = 0; sampleNum < length; sampleNum++) {
+		if (!tva->isPlaying() || !la32Pair.isActive(LA32PartialPair::MASTER)) {
+			deactivate();
+			break;
+		}
+		la32Pair.generateNextSample(LA32PartialPair::MASTER, getAmpValue(), tvp->nextPitch(), getCutoffValue());
+		if (hasRingModulatingSlave()) {
+			la32Pair.generateNextSample(LA32PartialPair::SLAVE, pair->getAmpValue(), pair->tvp->nextPitch(), pair->getCutoffValue());
+			if (!pair->tva->isPlaying() || !la32Pair.isActive(LA32PartialPair::SLAVE)) {
+				pair->deactivate();
+				if (mixType == 2) {
+					deactivate();
+					break;
+				}
+			}
+		}
+
+		// Although, LA32 applies panning itself, we assume here it is applied in the mixer, not within a pair.
+		// Applying the pan value in the log-space looks like a waste of unlog resources. Though, it needs clarification.
+		Sample sample = la32Pair.nextOutSample();
+
+		// FIXME: Sample analysis suggests that the use of panVal is linear, but there are some quirks that still need to be resolved.
 #if MT32EMU_USE_FLOAT_SAMPLES
-		*(leftBuf++) += buffer[i] * stereoVolume.leftVol;
-		*(rightBuf++) += buffer[i] * stereoVolume.rightVol;
+		Sample leftOut = (sample * (float)leftPanValue) / 14.0f;
+		Sample rightOut = (sample * (float)rightPanValue) / 14.0f;
+		*(leftBuf++) += leftOut;
+		*(rightBuf++) += rightOut;
 #else
-		*leftBuf = Synth::clipBit16s((Bit32s)*leftBuf + Bit32s(buffer[i] * stereoVolume.leftVol));
-		*rightBuf = Synth::clipBit16s((Bit32s)*rightBuf + Bit32s(buffer[i] * stereoVolume.rightVol));
+		// FIXME: Dividing by 7 (or by 14 in a Mok-friendly way) looks of course pointless. Need clarification.
+		// FIXME2: LA32 may produce distorted sound in case if the absolute value of maximal amplitude of the input exceeds 8191
+		// when the panning value is non-zero. Most probably the distortion occurs in the same way it does with ring modulation,
+		// and it seems to be caused by limited precision of the common multiplication circuit.
+		// From analysis of this overflow, it is obvious that the right channel output is actually found
+		// by subtraction of the left channel output from the input.
+		// Though, it is unknown whether this overflow is exploited somewhere.
+		Sample leftOut = Sample((sample * leftPanValue) >> 8);
+		Sample rightOut = Sample((sample * rightPanValue) >> 8);
+		*leftBuf = Synth::clipBit16s((Bit32s)*leftBuf + (Bit32s)leftOut);
+		*rightBuf = Synth::clipBit16s((Bit32s)*rightBuf + (Bit32s)rightOut);
 		leftBuf++;
 		rightBuf++;
 #endif
 	}
+	sampleNum = 0;
 	return true;
 }
 
diff --git a/audio/softsynth/mt32/Partial.h b/audio/softsynth/mt32/Partial.h
index 358cb9d..05c1c74 100644
--- a/audio/softsynth/mt32/Partial.h
+++ b/audio/softsynth/mt32/Partial.h
@@ -25,24 +25,22 @@ class Part;
 class TVA;
 struct ControlROMPCMStruct;
 
-struct StereoVolume {
-	float leftVol;
-	float rightVol;
-};
-
 // A partial represents one of up to four waveform generators currently playing within a poly.
 class Partial {
 private:
 	Synth *synth;
 	const int debugPartialNum; // Only used for debugging
-	// Number of the sample currently being rendered by generateSamples(), or 0 if no run is in progress
+	// Number of the sample currently being rendered by produceOutput(), or 0 if no run is in progress
 	// This is only kept available for debugging purposes.
 	unsigned long sampleNum;
 
+	// Actually, this is a 4-bit register but we abuse this to emulate inverted mixing.
+	// Also we double the value to enable INACCURATE_SMOOTH_PAN, with respect to MoK.
+	Bit32s leftPanValue, rightPanValue;
+
 	int ownerPart; // -1 if unassigned
 	int mixType;
 	int structurePosition; // 0 or 1 of a structure pair
-	StereoVolume stereoVolume;
 
 	// Only used for PCM partials
 	int pcmNum;
@@ -103,9 +101,6 @@ public:
 	// This function (unlike the one below it) returns processed stereo samples
 	// made from combining this single partial with its pair, if it has one.
 	bool produceOutput(Sample *leftBuf, Sample *rightBuf, unsigned long length);
-
-	// This function writes mono sample output to the provided buffer, and returns the number of samples written
-	unsigned long generateSamples(Sample *partialBuf, unsigned long length);
 };
 
 }
diff --git a/audio/softsynth/mt32/Synth.cpp b/audio/softsynth/mt32/Synth.cpp
index b76dc58..efba9b7 100644
--- a/audio/softsynth/mt32/Synth.cpp
+++ b/audio/softsynth/mt32/Synth.cpp
@@ -76,6 +76,7 @@ Synth::Synth(ReportHandler *useReportHandler) {
 	isOpen = false;
 	reverbEnabled = true;
 	reverbOverridden = false;
+	partialCount = DEFAULT_MAX_PARTIALS;
 
 	if (useReportHandler == NULL) {
 		reportHandler = new ReportHandler;
@@ -95,6 +96,7 @@ Synth::Synth(ReportHandler *useReportHandler) {
 	setMIDIDelayMode(MIDIDelayMode_DELAY_SHORT_MESSAGES_ONLY);
 	setOutputGain(1.0f);
 	setReverbOutputGain(1.0f);
+	setReversedStereoEnabled(false);
 	partialManager = NULL;
 	midiQueue = NULL;
 	lastReceivedMIDIEventTimestamp = 0;
@@ -172,6 +174,8 @@ MIDIDelayMode Synth::getMIDIDelayMode() const {
 	return midiDelayMode;
 }
 
+#if MT32EMU_USE_FLOAT_SAMPLES
+
 void Synth::setOutputGain(float newOutputGain) {
 	outputGain = newOutputGain;
 }
@@ -188,6 +192,39 @@ float Synth::getReverbOutputGain() const {
 	return reverbOutputGain;
 }
 
+#else // #if MT32EMU_USE_FLOAT_SAMPLES
+
+void Synth::setOutputGain(float newOutputGain) {
+	if (newOutputGain < 0.0f) newOutputGain = -newOutputGain;
+	if (256.0f < newOutputGain) newOutputGain = 256.0f;
+	outputGain = int(newOutputGain * 256.0f);
+}
+
+float Synth::getOutputGain() const {
+	return outputGain / 256.0f;
+}
+
+void Synth::setReverbOutputGain(float newReverbOutputGain) {
+	if (newReverbOutputGain < 0.0f) newReverbOutputGain = -newReverbOutputGain;
+	float maxValue = 256.0f / CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR;
+	if (maxValue < newReverbOutputGain) newReverbOutputGain = maxValue;
+	reverbOutputGain = int(newReverbOutputGain * 256.0f);
+}
+
+float Synth::getReverbOutputGain() const {
+	return reverbOutputGain / 256.0f;
+}
+
+#endif // #if MT32EMU_USE_FLOAT_SAMPLES
+
+void Synth::setReversedStereoEnabled(bool enabled) {
+	reversedStereoEnabled = enabled;
+}
+
+bool Synth::isReversedStereoEnabled() {
+	return reversedStereoEnabled;
+}
+
 bool Synth::loadControlROM(const ROMImage &controlROMImage) {
 	if (&controlROMImage == NULL) return false;
 	Common::File *file = controlROMImage.getFile();
@@ -1445,16 +1482,19 @@ void Synth::convertSamplesToOutput(Sample *target, const Sample *source, Bit32u
 		*(target++) = *(source++) * gain;
 	}
 #else
-	float gain = reverb ? reverbOutputGain * CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR : outputGain;
-	if (!reverb) {
+	int gain;
+	if (reverb) {
+		gain = int(reverbOutputGain * CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR);
+	} else {
+		gain = outputGain;
 		switch (dacInputMode) {
 		case DACInputMode_NICE:
 			// Since we're not shooting for accuracy here, don't worry about the rounding mode.
-			gain *= 2.0f;
+			gain <<= 1;
 			break;
 		case DACInputMode_GENERATION1:
 			while (len--) {
-				*target = clipBit16s(Bit32s(*source * gain));
+				*target = clipBit16s(Bit32s((*source * gain) >> 8));
 				*target = (*target & 0x8000) | ((*target << 1) & 0x7FFE);
 				source++;
 				target++;
@@ -1462,7 +1502,7 @@ void Synth::convertSamplesToOutput(Sample *target, const Sample *source, Bit32u
 			return;
 		case DACInputMode_GENERATION2:
 			while (len--) {
-				*target = clipBit16s(Bit32s(*source * gain));
+				*target = clipBit16s(Bit32s((*source * gain) >> 8));
 				*target = (*target & 0x8000) | ((*target << 1) & 0x7FFE) | ((*target >> 14) & 0x0001);
 				source++;
 				target++;
@@ -1473,7 +1513,7 @@ void Synth::convertSamplesToOutput(Sample *target, const Sample *source, Bit32u
 		}
 	}
 	while (len--) {
-		*(target++) = clipBit16s(Bit32s(*(source++) * gain));
+		*(target++) = clipBit16s(Bit32s((*(source++) * gain) >> 8));
 	}
 #endif
 }
diff --git a/audio/softsynth/mt32/Synth.h b/audio/softsynth/mt32/Synth.h
index 783d6e2..8816711 100644
--- a/audio/softsynth/mt32/Synth.h
+++ b/audio/softsynth/mt32/Synth.h
@@ -343,8 +343,16 @@ private:
 
 	MIDIDelayMode midiDelayMode;
 	DACInputMode dacInputMode;
+
+#if MT32EMU_USE_FLOAT_SAMPLES
 	float outputGain;
 	float reverbOutputGain;
+#else
+	int outputGain;
+	int reverbOutputGain;
+#endif
+
+	bool reversedStereoEnabled;
 
 	bool isOpen;
 
@@ -477,6 +485,9 @@ public:
 	void setReverbOutputGain(float);
 	float getReverbOutputGain() const;
 
+	void setReversedStereoEnabled(bool enabled);
+	bool isReversedStereoEnabled();
+
 	// Renders samples to the specified output stream.
 	// The length is in frames, not bytes (in 16-bit stereo,
 	// one frame is 4 bytes).


Commit: 4fd203ce40f348afecc9ff401773d5d401c7636a
    https://github.com/scummvm/scummvm/commit/4fd203ce40f348afecc9ff401773d5d401c7636a
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2013-09-24T01:34:14-07:00

Commit Message:
NEWS: Mention update to munt 1.3.0

Changed paths:
    NEWS



diff --git a/NEWS b/NEWS
index 98757ad..7a0487c 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,9 @@ For a more comprehensive changelog of the latest experimental code, see:
         https://github.com/scummvm/scummvm/commits/
 
 1.7.0 (????-??-??)
+ General:
+   - Updated MT-32 emulation code to version 1.3.0.
+
  Gob:
    - Improved video quality in Urban Runner
 






More information about the Scummvm-git-logs mailing list