[Scummvm-cvs-logs] SF.net SVN: scummvm:[48204] scummvm/branches/branch-1-1-0/sound/mixer.cpp

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Mon Mar 8 22:54:54 CET 2010


Revision: 48204
          http://scummvm.svn.sourceforge.net/scummvm/?rev=48204&view=rev
Author:   fingolfin
Date:     2010-03-08 21:54:54 +0000 (Mon, 08 Mar 2010)

Log Message:
-----------
Backport: Fix bug #2872076 (MIXER: Division by 0 in rate conversion if w/o soundcd)

Modified Paths:
--------------
    scummvm/branches/branch-1-1-0/sound/mixer.cpp

Modified: scummvm/branches/branch-1-1-0/sound/mixer.cpp
===================================================================
--- scummvm/branches/branch-1-1-0/sound/mixer.cpp	2010-03-08 21:54:32 UTC (rev 48203)
+++ scummvm/branches/branch-1-1-0/sound/mixer.cpp	2010-03-08 21:54:54 UTC (rev 48204)
@@ -179,6 +179,9 @@
 
 void MixerImpl::setReady(bool ready) {
 	_mixerReady = ready;
+
+	// If the mixer is set to ready, then we better have a positive sample rate!
+	assert(!_mixerReady || _sampleRate > 0);
 }
 
 uint MixerImpl::getOutputRate() const {
@@ -241,6 +244,44 @@
 			}
 	}
 
+	// Check if the mixer is not ready. This most probably means that
+	// no Audio output is possible according to the backend (we should
+	// clarify this in the Mixer creation API, though).
+	//
+	// For now we deal with this by simply ignore the sound here, never
+	// scheduling it for playback, never giving it a valid sound
+	// handle. For a game engine, this is indistinguishable from a
+	// sound which finishes playback before playInputStream returns.
+	//
+	// This is certainly not ideal for many engine; e.g. if a game has
+	// scripts which sync by waiting for certain sounds to play, then
+	// this syncing is broken if we just remove the sound.
+	//
+	// We could try to be more graceful, by using TimerManager and
+	// emulating (or rather: faking) actual audio playback; essentially
+	// we run the mixer callback from a timer instead of an audio
+	// callback.
+	// However, this may very well lead to new problems of its own,
+	// plus it would complicate the Mixer code. It seems that a better
+	// solution would be to adapt backends to setup a fake mixer thread
+	// which calls the mixer callback. We'd then still need a way to
+	// signal the mixer / the client code that no actual audio playback
+	// takes places... Anyway, either way, we first would have to
+	// investigate ramifications of any such approach.
+	//
+	// And also, by far the best solution is to adapt engines to be
+	// properly aware of the possibility of missing audio, and how to
+	// deal with it; be it by refusing to launch (e.g. when audio is an
+	// integral part of a game), by switching to alternate script
+	// syncing means, etc. It also seems important to test every game
+	// individually in a system without audio, if we really want
+	// to support such systems.
+	if (!_mixerReady) {
+		if (autofreeStream == DisposeAfterUse::YES)
+			delete input;
+		return;
+	}
+
 	// Create the channel
 	Channel *chan = new Channel(this, type, input, autofreeStream, reverseStereo, id, permanent);
 	chan->setVolume(volume);
@@ -258,6 +299,7 @@
 
 	// Since the mixer callback has been called, the mixer must be ready...
 	_mixerReady = true;
+	assert(_sampleRate > 0);
 
 	//  zero the buf
 	memset(buf, 0, 2 * len * sizeof(int16));
@@ -334,7 +376,7 @@
 
 	const int index = handle._val % NUM_CHANNELS;
 	if (!_channels[index] || _channels[index]->getHandle()._val != handle._val)
-		return Timestamp(0, _sampleRate);
+		return Timestamp(0, _sampleRate ? _sampleRate : 1);
 
 	return _channels[index]->getElapsedTime();
 }


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