[Scummvm-cvs-logs] SF.net SVN: scummvm: [21302] scummvm/trunk/sound

eriktorbjorn at users.sourceforge.net eriktorbjorn at users.sourceforge.net
Tue Mar 14 15:02:08 CET 2006


Revision: 21302
Author:   eriktorbjorn
Date:     2006-03-14 15:01:44 -0800 (Tue, 14 Mar 2006)
ViewCVS:  http://svn.sourceforge.net/scummvm/?rev=21302&view=rev

Log Message:
-----------
Added workaround in FMOPL for the pathological case where a note was turned off
while still at the very beginning of the "attack" phase. This is the very
lowest point on the attack curve, yet it would continue from the beginning of
the release curve, i.e. its very highest point. This is what caused Kyra to
often play low-frequency notes at the very beginning of a new song. (That, and
a truly bizarre function for initialising the channels.)

The proper fix would be to locate the correct point on the release curve and
continue from there. For now, though, only handle the trivial case.

Modified Paths:
--------------
    scummvm/trunk/engines/kyra/sound_adlib.cpp
    scummvm/trunk/sound/fmopl.cpp
Modified: scummvm/trunk/engines/kyra/sound_adlib.cpp
===================================================================
--- scummvm/trunk/engines/kyra/sound_adlib.cpp	2006-03-14 20:09:32 UTC (rev 21301)
+++ scummvm/trunk/engines/kyra/sound_adlib.cpp	2006-03-14 23:01:44 UTC (rev 21302)
@@ -808,18 +808,17 @@
 	// including the two most significant frequency bit, and the octave -
 	// set to zero.
 	//
-	// This is very strange behaviour, and appears to be the cause of the
-	// bug where low-frequent notes are played at the beginning of a new
-	// sound. However, this is what the original does, and the bug does not
-	// seem to happen with current versions of the FMOPL code.
+	// This is very strange behaviour, and causes problems with the ancient
+	// FMOPL code we borrowed from AdPlug. I've added a workaround. See
+	// fmopl.cpp for more details.
 	//
-	// Unfortunately, we cannot use more recent versions because of license
-	// incompatibilities.
+	// More recent versions of the MAME FMOPL don't seem to have this
+	// problem, but cannot currently be used because of licensing and
+	// performance issues.
 	//
 	// Ken Silverman's Adlib emulator (which can be found on his Web page -
 	// http://www.advsys.net/ken - and as part of AdPlug) also seems to be
-	// proof against this particular bug, but is apparently not as feature
-	// complete as MAME's.
+	// immune, but is apparently not as feature complete as MAME's.
 
 	writeOPL(0xB0 + chan, 0x20);
 }

Modified: scummvm/trunk/sound/fmopl.cpp
===================================================================
--- scummvm/trunk/sound/fmopl.cpp	2006-03-14 20:09:32 UTC (rev 21301)
+++ scummvm/trunk/sound/fmopl.cpp	2006-03-14 23:01:44 UTC (rev 21302)
@@ -304,12 +304,41 @@
 inline void OPL_KEYOFF(OPL_SLOT *SLOT) {
 	if( SLOT->evm > ENV_MOD_RR) {
 		/* set envelope counter from envleope output */
-		SLOT->evm = ENV_MOD_RR;
-		if( !(SLOT->evc & EG_DST) )
+
+		// WORKAROUND: The Kyra engine does something very strange when
+		// starting a new song. For each channel:
+		//
+		// * The release rate is set to "fastest".
+		// * Any note is keyed off.
+		// * A very low-frequency note is keyed on.
+		//
+		// Usually, what happens next is that the real notes is keyed
+		// on immediately, in which case there's no problem.
+		//
+		// However, if the note is again keyed off (because the channel
+		// begins on a rest rather than a note), the envelope counter
+		// was moved from the very lowest point on the attack curve to
+		// the very highest point on the release curve.
+		//
+		// Again, this might not be a problem, if the release rate is
+		// still set to "fastest". But in many cases, it had already
+		// been increased. And, possibly because of inaccuracies in the
+		// envelope generator, that would cause the note to "fade out"
+		// for quite a long time.
+		//
+		// What we really need is a way to find the correct starting
+		// point for the envelope counter, and that may be what the
+		// commented-out line below is meant to do. For now, simply
+		// handle the pathological case.
+
+		if (SLOT->evm == ENV_MOD_AR && SLOT->evc == EG_AST)
+			SLOT->evc = EG_DED;
+		else if( !(SLOT->evc & EG_DST) )
 			//SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST;
 			SLOT->evc = EG_DST;
 		SLOT->eve = EG_DED;
 		SLOT->evs = SLOT->evsr;
+		SLOT->evm = ENV_MOD_RR;
 	}
 }
 


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