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

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Sat Jun 28 17:28:30 CEST 2008


Revision: 32828
          http://scummvm.svn.sourceforge.net/scummvm/?rev=32828&view=rev
Author:   fingolfin
Date:     2008-06-28 08:28:29 -0700 (Sat, 28 Jun 2008)

Log Message:
-----------
Patch ##1956946 (Audio::Mixer internal API revision) with some tweaks

Modified Paths:
--------------
    scummvm/trunk/backends/platform/gp2x/gp2x-common.h
    scummvm/trunk/backends/platform/gp2x/gp2x.cpp
    scummvm/trunk/backends/platform/psp/osys_psp.cpp
    scummvm/trunk/backends/platform/sdl/sdl.cpp
    scummvm/trunk/backends/platform/sdl/sdl.h
    scummvm/trunk/backends/platform/symbian/src/SymbianOS.cpp
    scummvm/trunk/backends/platform/symbian/src/SymbianOS.h
    scummvm/trunk/backends/platform/wince/wince-sdl.cpp
    scummvm/trunk/backends/platform/wince/wince-sdl.h
    scummvm/trunk/common/system.h
    scummvm/trunk/sound/mixer.cpp
    scummvm/trunk/sound/mixer.h

Added Paths:
-----------
    scummvm/trunk/sound/mixer_intern.h

Modified: scummvm/trunk/backends/platform/gp2x/gp2x-common.h
===================================================================
--- scummvm/trunk/backends/platform/gp2x/gp2x-common.h	2008-06-28 15:27:40 UTC (rev 32827)
+++ scummvm/trunk/backends/platform/gp2x/gp2x-common.h	2008-06-28 15:28:29 UTC (rev 32828)
@@ -37,7 +37,7 @@
 #include <SDL_gp2x.h>
 
 namespace Audio {
-	class Mixer;
+	class MixerImpl;
 }
 
 namespace Common {
@@ -367,7 +367,7 @@
 	Common::SaveFileManager *_savefile;
 	FilesystemFactory *getFilesystemFactory();
 
-	Audio::Mixer *_mixer;
+	Audio::MixerImpl *_mixer;
 
 	SDL_TimerID _timerID;
 	Common::TimerManager *_timer;

Modified: scummvm/trunk/backends/platform/gp2x/gp2x.cpp
===================================================================
--- scummvm/trunk/backends/platform/gp2x/gp2x.cpp	2008-06-28 15:27:40 UTC (rev 32827)
+++ scummvm/trunk/backends/platform/gp2x/gp2x.cpp	2008-06-28 15:28:29 UTC (rev 32828)
@@ -40,7 +40,7 @@
 #include "backends/timer/default/default-timer.h"
 #include "backends/plugins/posix/posix-provider.h"
 #include "backends/fs/posix/posix-fs-factory.h" // for getFilesystemFactory()
-#include "sound/mixer.h"
+#include "sound/mixer_intern.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -225,8 +225,7 @@
 	// Create and hook up the mixer, if none exists yet (we check for this to
 	// allow subclasses to provide their own).
 	if (_mixer == 0) {
-		_mixer = new Audio::Mixer();
-		setSoundCallback(Audio::Mixer::mixCallback, _mixer);
+		setupMixer();
 	}
 
 	// Create and hook up the timer manager, if none exists yet (we check for
@@ -445,7 +444,7 @@
 #pragma mark --- Audio ---
 #pragma mark -
 
-bool OSystem_GP2X::setSoundCallback(SoundProc proc, void *param) {
+void OSystem_GP2X::setupMixer() {
 	SDL_AudioSpec desired;
 	SDL_AudioSpec obtained;
 

Modified: scummvm/trunk/backends/platform/psp/osys_psp.cpp
===================================================================
--- scummvm/trunk/backends/platform/psp/osys_psp.cpp	2008-06-28 15:27:40 UTC (rev 32827)
+++ scummvm/trunk/backends/platform/psp/osys_psp.cpp	2008-06-28 15:28:29 UTC (rev 32828)
@@ -34,7 +34,7 @@
 #include "backends/timer/default/default-timer.h"
 #include "graphics/surface.h"
 #include "graphics/scaler.h"
-#include "sound/mixer.h"
+#include "sound/mixer_intern.h"
 
 #include <pspgu.h>
 
@@ -99,7 +99,7 @@
 
 void OSystem_PSP::initBackend() {
 	_savefile = new DefaultSaveFileManager();
-	_mixer = new Audio::Mixer();
+	_mixer = new Audio::MixerImpl(this);
 	_timer = new DefaultTimerManager();
 	setSoundCallback(Audio::Mixer::mixCallback, _mixer);
 	setTimerCallback(&timer_handler, 10);

Modified: scummvm/trunk/backends/platform/sdl/sdl.cpp
===================================================================
--- scummvm/trunk/backends/platform/sdl/sdl.cpp	2008-06-28 15:27:40 UTC (rev 32827)
+++ scummvm/trunk/backends/platform/sdl/sdl.cpp	2008-06-28 15:28:29 UTC (rev 32828)
@@ -30,7 +30,7 @@
 
 #include "backends/saves/default/default-saves.h"
 #include "backends/timer/default/default-timer.h"
-#include "sound/mixer.h"
+#include "sound/mixer_intern.h"
 
 #include "icons/scummvm.xpm"
 
@@ -131,9 +131,7 @@
 	// Create and hook up the mixer, if none exists yet (we check for this to
 	// allow subclasses to provide their own).
 	if (_mixer == 0) {
-		_mixer = new Audio::Mixer();
-		bool result = setSoundCallback(Audio::Mixer::mixCallback, _mixer);
-		_mixer->setReady(result);
+		setupMixer();
 	}
 
 	// Create and hook up the timer manager, if none exists yet (we check for
@@ -391,7 +389,15 @@
 #pragma mark --- Audio ---
 #pragma mark -
 
-bool OSystem_SDL::setSoundCallback(SoundProc proc, void *param) {
+void OSystem_SDL::mixCallback(void *sys, byte *samples, int len) {
+	OSystem_SDL *this_ = (OSystem_SDL *)sys;
+	assert(this_);
+
+	if (this_->_mixer)
+		this_->_mixer->mixCallback(samples, len);
+}
+
+void OSystem_SDL::setupMixer() {
 	SDL_AudioSpec desired;
 	SDL_AudioSpec obtained;
 
@@ -415,25 +421,32 @@
 	desired.format = AUDIO_S16SYS;
 	desired.channels = 2;
 	desired.samples = (uint16)samples;
-	desired.callback = proc;
-	desired.userdata = param;
+	desired.callback = mixCallback;
+	desired.userdata = this;
+
+	// Create the mixer instance
+	assert(!_mixer);
+	_mixer = new Audio::MixerImpl(this);
+	assert(_mixer);
+
 	if (SDL_OpenAudio(&desired, &obtained) != 0) {
 		warning("Could not open audio device: %s", SDL_GetError());
-		return false;
+		_samplesPerSec = 0;
+		_mixer->setReady(false);
+	} else {
+		// Note: This should be the obtained output rate, but it seems that at
+		// least on some platforms SDL will lie and claim it did get the rate
+		// even if it didn't. Probably only happens for "weird" rates, though.
+		_samplesPerSec = obtained.freq;
+		debug(1, "Output sample rate: %d Hz", _samplesPerSec);
+	
+		// Tell the mixer that we are ready and start the sound processing
+		_mixer->setOutputRate(_samplesPerSec);
+		_mixer->setReady(true);
+		SDL_PauseAudio(0);
 	}
-	// Note: This should be the obtained output rate, but it seems that at
-	// least on some platforms SDL will lie and claim it did get the rate
-	// even if it didn't. Probably only happens for "weird" rates, though.
-	_samplesPerSec = obtained.freq;
-	debug(1, "Output sample rate: %d Hz", _samplesPerSec);
-	SDL_PauseAudio(0);
-	return true;
 }
 
-int OSystem_SDL::getOutputSampleRate() const {
-	return _samplesPerSec;
-}
-
 Audio::Mixer *OSystem_SDL::getMixer() {
 	assert(_mixer);
 	return _mixer;

Modified: scummvm/trunk/backends/platform/sdl/sdl.h
===================================================================
--- scummvm/trunk/backends/platform/sdl/sdl.h	2008-06-28 15:27:40 UTC (rev 32827)
+++ scummvm/trunk/backends/platform/sdl/sdl.h	2008-06-28 15:28:29 UTC (rev 32828)
@@ -38,7 +38,7 @@
 
 
 namespace Audio {
-	class Mixer;
+	class MixerImpl;
 }
 
 namespace Common {
@@ -134,8 +134,9 @@
 	virtual bool pollEvent(Common::Event &event); // overloaded by CE backend
 
 	// Set function that generates samples
-	typedef void (*SoundProc)(void *param, byte *buf, int len);
-	virtual bool setSoundCallback(SoundProc proc, void *param); // overloaded by CE backend
+	virtual void setupMixer();
+	static void mixCallback(void *s, byte *samples, int len);
+
 	virtual Audio::Mixer *getMixer();
 
 	// Poll CD status
@@ -186,7 +187,6 @@
 
 	virtual void setWindowCaption(const char *caption);
 	virtual bool openCD(int drive);
-	virtual int getOutputSampleRate() const;
 
 	virtual bool hasFeature(Feature f);
 	virtual void setFeatureState(Feature f, bool enable);
@@ -371,7 +371,7 @@
 
 
 	Common::SaveFileManager *_savefile;
-	Audio::Mixer *_mixer;
+	Audio::MixerImpl *_mixer;
 
 	SDL_TimerID _timerID;
 	Common::TimerManager *_timer;

Modified: scummvm/trunk/backends/platform/symbian/src/SymbianOS.cpp
===================================================================
--- scummvm/trunk/backends/platform/symbian/src/SymbianOS.cpp	2008-06-28 15:27:40 UTC (rev 32827)
+++ scummvm/trunk/backends/platform/symbian/src/SymbianOS.cpp	2008-06-28 15:28:29 UTC (rev 32828)
@@ -173,11 +173,8 @@
 	OSystem_SDL::quit();
 }
 
-bool OSystem_SDL_Symbian::setSoundCallback(SoundProc proc, void *param) {
+void OSystem_SDL_Symbian::setupMixer() {
 
-	// First save the proc and param
-	_sound_proc_param = param;
-	_sound_proc = proc;
 	SDL_AudioSpec desired;
 	SDL_AudioSpec obtained;
 
@@ -207,48 +204,53 @@
 	desired.format = AUDIO_S16SYS;
 	desired.channels = 2;
 	desired.samples = (uint16)samples;
-#ifdef S60
 	desired.callback = symbianMixCallback;
 	desired.userdata = this;
-#else
-	desired.callback = proc;
-	desired.userdata = param;
-#endif
+
+	// Create the mixer instance
+	assert(!_mixer);
+	_mixer = new Audio::MixerImpl(this);
+	assert(_mixer);
+
 	if (SDL_OpenAudio(&desired, &obtained) != 0) {
 		warning("Could not open audio device: %s", SDL_GetError());
-		return false;
+		_samplesPerSec = 0;
+		_mixer->setReady(false);
+	} else {
+		// Note: This should be the obtained output rate, but it seems that at
+		// least on some platforms SDL will lie and claim it did get the rate
+		// even if it didn't. Probably only happens for "weird" rates, though.
+		_samplesPerSec = obtained.freq;
+		_channels = obtained.channels;
+	
+		// Need to create mixbuffer for stereo mix to downmix
+		if (_channels != 2) {
+			_stereo_mix_buffer = new byte [obtained.size*2];//*2 for stereo values
+		}
+	
+		// Tell the mixer that we are ready and start the sound processing
+		_mixer->setOutputRate(_samplesPerSec);
+		_mixer->setReady(true);
+		SDL_PauseAudio(0);
 	}
-	// Note: This should be the obtained output rate, but it seems that at
-	// least on some platforms SDL will lie and claim it did get the rate
-	// even if it didn't. Probably only happens for "weird" rates, though.
-	_samplesPerSec = obtained.freq;
-	_channels = obtained.channels;
-
-	// Need to create mixbuffer for stereo mix to downmix
-	if (_channels != 2) {
-		_stereo_mix_buffer = new byte [obtained.size*2];//*2 for stereo values
-	}
-
-	SDL_PauseAudio(0);
-	return true;
 }
 
 /**
  * The mixer callback function, passed on to OSystem::setSoundCallback().
  * This simply calls the mix() method.
  */
-void OSystem_SDL_Symbian::symbianMixCallback(void *s, byte *samples, int len) {
-	static_cast <OSystem_SDL_Symbian*>(s)->symbianMix(samples,len);
-}
+void OSystem_SDL_Symbian::symbianMixCallback(void *sys, byte *samples, int len) {
+	OSystem_SDL_Symbian *this_ = (OSystem_SDL_Symbian *)sys;
+	assert(this_);
 
+	if (!this_->_mixer)
+		return;
 
-/**
- * Actual mixing implementation
- */
-void OSystem_SDL_Symbian::symbianMix(byte *samples, int len) {
+#ifdef S60
 	// If not stereo then we need to downmix
 	if (_channels != 2) {
-		_sound_proc(_sound_proc_param, _stereo_mix_buffer, len * 2);
+		this_->_mixer->mixCallback(_stereo_mix_buffer, len * 2);
+
 		int16 *bitmixDst = (int16 *)samples;
 		int16 *bitmixSrc = (int16 *)_stereo_mix_buffer;
 
@@ -258,9 +260,12 @@
 			bitmixSrc += 2;
 		}
 	} else
-		_sound_proc(_sound_proc_param, samples, len);
+#else
+	this_->_mixer->mixCallback(samples, len);
+#endif
 }
 
+
 /**
  * This is an implementation by the remapKey function
  * @param SDL_Event to remap

Modified: scummvm/trunk/backends/platform/symbian/src/SymbianOS.h
===================================================================
--- scummvm/trunk/backends/platform/symbian/src/SymbianOS.h	2008-06-28 15:27:40 UTC (rev 32827)
+++ scummvm/trunk/backends/platform/symbian/src/SymbianOS.h	2008-06-28 15:28:29 UTC (rev 32828)
@@ -58,7 +58,7 @@
 	// This function is overridden by the symbian port in order to provide MONO audio
 	// downmix is done by supplying our own audiocallback
 	//
-	virtual bool setSoundCallback(SoundProc proc, void *param); // overloaded by CE backend
+	virtual void setupMixer(); // overloaded by CE backend
 
 	// Overloaded from SDL_Commmon
 	void quit();
@@ -70,11 +70,6 @@
 	//
 	static void symbianMixCallback(void *s, byte *samples, int len);
 
-	//
-	// Actual mixing implementation
-	//
-	void symbianMix(byte *samples, int len);
-
 	virtual FilesystemFactory *getFilesystemFactory();
 public:
 	// vibration support
@@ -121,8 +116,6 @@
 	// Audio
 	int _channels;
 
-	SoundProc _sound_proc;
-	void *_sound_proc_param;
 	byte *_stereo_mix_buffer;
 
 	// Used to handle joystick navi zones

Modified: scummvm/trunk/backends/platform/wince/wince-sdl.cpp
===================================================================
--- scummvm/trunk/backends/platform/wince/wince-sdl.cpp	2008-06-28 15:27:40 UTC (rev 32827)
+++ scummvm/trunk/backends/platform/wince/wince-sdl.cpp	2008-06-28 15:28:29 UTC (rev 32828)
@@ -35,7 +35,7 @@
 #include "base/main.h"
 #include "base/plugins.h"
 
-#include "sound/mixer.h"
+#include "sound/mixer_intern.h"
 #include "sound/fmopl.h"
 
 #include "backends/timer/default/default-timer.h"
@@ -404,7 +404,7 @@
 	// Instantiate our own sound mixer
 	// mixer init is postponed until a game engine is selected.
 	if (_mixer == 0) {
-		_mixer = new Audio::Mixer();
+		_mixer = new Audio::Mixer(this);
 	}
 
 	// Create the timer. CE SDL does not support multiple timers (SDL_AddTimer).
@@ -770,7 +770,7 @@
 	_toolbarHandler.setVisible(false);
 }
 
-bool OSystem_WINCE3::setSoundCallback(SoundProc proc, void *param) {
+void OSystem_WINCE3::setupMixer(SoundProc proc, void *param) {
 	SDL_AudioSpec desired;
 	int thread_priority;
 
@@ -785,12 +785,16 @@
 	desired.channels = 2;
 	desired.samples = 128;
 	desired.callback = private_sound_proc;
-	desired.userdata = param;
+	desired.userdata = this;
 
+	// Create the mixer instance
+	assert(!_mixer);
+	_mixer = new Audio::MixerImpl(this);
+	assert(_mixer);
+
 	// Add sound thread priority
-	if (!ConfMan.hasKey("sound_thread_priority")) {
+	if (!ConfMan.hasKey("sound_thread_priority"))
 		thread_priority = THREAD_PRIORITY_NORMAL;
-	}
 	else
 		thread_priority = ConfMan.getInt("sound_thread_priority");
 
@@ -799,16 +803,24 @@
 	SDL_CloseAudio();
 	if (SDL_OpenAudio(&desired, NULL) != 0) {
 		warning("Could not open audio device: %s", SDL_GetError());
-		return false;
+		_mixer->setReady(false);
+
+	} else {
+		debug(1, "Sound opened OK, mixing at %d Hz", _sampleRate);
+
+		// Tell the mixer that we are ready and start the sound processing
+		_mixer->setOutputRate(_sampleRate);
+		_mixer->setReady(true);
+		SDL_PauseAudio(0);
 	}
-	else
-		debug(1, "Sound opened OK, mixing at %d Hz", _sampleRate);
-	SDL_PauseAudio(0);
-	return true;
 }
 
 void OSystem_WINCE3::private_sound_proc(void *param, byte *buf, int len) {
-	(*_originalSoundProc)(param, buf, len);
+	OSystem_WINCE3 *this_ = (OSystem_WINCE3 *)param;
+	assert(this_);
+
+	if (this_->_mixer)
+		this_->_mixer->mixCallback(buf, len);
 	if (!_soundMaster)
 		memset(buf, 0, len);
 }
@@ -838,7 +850,7 @@
 }
 #endif
 
-void OSystem_WINCE3::get_sample_rate() {
+void OSystem_WINCE3::compute_sample_rate() {
 	// Force at least medium quality FM synthesis for FOTAQ
 	Common::String gameid(ConfMan.get("gameid"));
 	if (gameid == "queen") {
@@ -875,9 +887,8 @@
 
 	//update_game_settings();
 	// finalize mixer init
-	get_sample_rate();
-	bool result = setSoundCallback(Audio::Mixer::mixCallback, _mixer);
-	_mixer->setReady(result);
+	compute_sample_rate();
+	setupMixer();
 
 	// handle the actual event
 	OSystem_SDL::setWindowCaption(caption);
@@ -1050,7 +1061,7 @@
 		}
 	}
 
-	get_sample_rate();
+	compute_sample_rate();
 }
 
 void OSystem_WINCE3::initSize(uint w, uint h) {

Modified: scummvm/trunk/backends/platform/wince/wince-sdl.h
===================================================================
--- scummvm/trunk/backends/platform/wince/wince-sdl.h	2008-06-28 15:27:40 UTC (rev 32827)
+++ scummvm/trunk/backends/platform/wince/wince-sdl.h	2008-06-28 15:28:29 UTC (rev 32828)
@@ -82,7 +82,7 @@
 	// Overloaded from SDL_Commmon
 	void quit();
 	// Overloaded from SDL_Commmon (master volume and sample rate subtleties)
-	bool setSoundCallback(SoundProc proc, void *param);
+	void setupMixer();
 	// Overloaded from OSystem
 	//void engineInit();
 	void getTimeAndDate(struct tm &t) const;
@@ -160,13 +160,12 @@
 #endif
 
 	static void private_sound_proc(void *param, byte *buf, int len);
-	static SoundProc _originalSoundProc;
 
 	bool update_scalers();
 	void create_toolbar();
 	void update_game_settings();
 	void check_mappings();
-	void get_sample_rate();
+	void compute_sample_rate();
 
 	void retrieve_mouse_location(int &x, int &y);
 

Modified: scummvm/trunk/common/system.h
===================================================================
--- scummvm/trunk/common/system.h	2008-06-28 15:27:40 UTC (rev 32827)
+++ scummvm/trunk/common/system.h	2008-06-28 15:28:29 UTC (rev 32828)
@@ -814,15 +814,6 @@
 	 */
 	virtual Audio::Mixer *getMixer() = 0;
 
-	/**
-	 * Determine the output sample rate. Audio data provided by the sound
-	 * callback will be played using this rate.
-	 * @note Client code other than the sound mixer should _not_ use this
-	 *       method. Instead, call Mixer::getOutputRate()!
-	 * @return the output sample rate
-	 */
-	virtual int getOutputSampleRate() const = 0;
-
 	//@}
 
 

Modified: scummvm/trunk/sound/mixer.cpp
===================================================================
--- scummvm/trunk/sound/mixer.cpp	2008-06-28 15:27:40 UTC (rev 32827)
+++ scummvm/trunk/sound/mixer.cpp	2008-06-28 15:28:29 UTC (rev 32828)
@@ -27,7 +27,7 @@
 #include "common/util.h"
 #include "common/system.h"
 
-#include "sound/mixer.h"
+#include "sound/mixer_intern.h"
 #include "sound/rate.h"
 #include "sound/audiostream.h"
 
@@ -103,33 +103,39 @@
 #pragma mark -
 
 
-Mixer::Mixer() {
-	_syst = g_system;
+MixerImpl::MixerImpl(OSystem *system)
+	: _syst(system), _sampleRate(0), _mixerReady(false), _handleSeed(0) {
 
-	_handleSeed = 0;
+	int i;
 
-	int i = 0;
-
 	for (i = 0; i < ARRAYSIZE(_volumeForSoundType); i++)
 		_volumeForSoundType[i] = kMaxMixerVolume;
 
 	for (i = 0; i != NUM_CHANNELS; i++)
 		_channels[i] = 0;
-
-	_mixerReady = false;
 }
 
-Mixer::~Mixer() {
+MixerImpl::~MixerImpl() {
 	for (int i = 0; i != NUM_CHANNELS; i++)
 		delete _channels[i];
 }
 
-uint Mixer::getOutputRate() const {
-	return (uint)_syst->getOutputSampleRate();
+void MixerImpl::setReady(bool ready) {
+	_mixerReady = ready;
 }
 
-void Mixer::insertChannel(SoundHandle *handle, Channel *chan) {
+uint MixerImpl::getOutputRate() const {
+	return _sampleRate;
+}
 
+void MixerImpl::setOutputRate(uint sampleRate) {
+	if (_sampleRate != 0 && _sampleRate != sampleRate)
+		error("Changing the Audio::Mixer output sample rate is not supported");
+	_sampleRate = sampleRate;
+}
+
+void MixerImpl::insertChannel(SoundHandle *handle, Channel *chan) {
+
 	int index = -1;
 	for (int i = 0; i != NUM_CHANNELS; i++) {
 		if (_channels[i] == 0) {
@@ -138,7 +144,7 @@
 		}
 	}
 	if (index == -1) {
-		warning("Mixer::out of mixer slots");
+		warning("MixerImpl::out of mixer slots");
 		delete chan;
 		return;
 	}
@@ -151,7 +157,7 @@
 	}
 }
 
-void Mixer::playRaw(
+void MixerImpl::playRaw(
 			SoundType type,
 			SoundHandle *handle,
 			void *sound,
@@ -166,7 +172,7 @@
 	playInputStream(type, handle, input, id, volume, balance, true, false, ((flags & Mixer::FLAG_REVERSE_STEREO) != 0));
 }
 
-void Mixer::playInputStream(
+void MixerImpl::playInputStream(
 			SoundType type,
 			SoundHandle *handle,
 			AudioStream *input,
@@ -198,8 +204,13 @@
 	insertChannel(handle, chan);
 }
 
-void Mixer::mix(int16 *buf, uint len) {
+void MixerImpl::mixCallback(byte *samples, uint len) {
+	assert(samples);
+
 	Common::StackLock lock(_mutex);
+	
+	int16 *buf = (int16 *)samples;
+	len >>= 2;
 
 	// Since the mixer callback has been called, the mixer must be ready...
 	_mixerReady = true;
@@ -218,15 +229,7 @@
 		}
 }
 
-void Mixer::mixCallback(void *s, byte *samples, int len) {
-	assert(s);
-	assert(samples);
-	// Len is the number of bytes in the buffer; we divide it by
-	// four to get the number of samples (stereo 16 bit).
-	((Mixer *)s)->mix((int16 *)samples, len >> 2);
-}
-
-void Mixer::stopAll() {
+void MixerImpl::stopAll() {
 	Common::StackLock lock(_mutex);
 	for (int i = 0; i != NUM_CHANNELS; i++) {
 		if (_channels[i] != 0 && !_channels[i]->isPermanent()) {
@@ -236,7 +239,7 @@
 	}
 }
 
-void Mixer::stopID(int id) {
+void MixerImpl::stopID(int id) {
 	Common::StackLock lock(_mutex);
 	for (int i = 0; i != NUM_CHANNELS; i++) {
 		if (_channels[i] != 0 && _channels[i]->getId() == id) {
@@ -246,7 +249,7 @@
 	}
 }
 
-void Mixer::stopHandle(SoundHandle handle) {
+void MixerImpl::stopHandle(SoundHandle handle) {
 	Common::StackLock lock(_mutex);
 
 	// Simply ignore stop requests for handles of sounds that already terminated
@@ -258,7 +261,7 @@
 	_channels[index] = 0;
 }
 
-void Mixer::setChannelVolume(SoundHandle handle, byte volume) {
+void MixerImpl::setChannelVolume(SoundHandle handle, byte volume) {
 	Common::StackLock lock(_mutex);
 
 	const int index = handle._val % NUM_CHANNELS;
@@ -268,7 +271,7 @@
 	_channels[index]->setVolume(volume);
 }
 
-void Mixer::setChannelBalance(SoundHandle handle, int8 balance) {
+void MixerImpl::setChannelBalance(SoundHandle handle, int8 balance) {
 	Common::StackLock lock(_mutex);
 
 	const int index = handle._val % NUM_CHANNELS;
@@ -278,7 +281,7 @@
 	_channels[index]->setBalance(balance);
 }
 
-uint32 Mixer::getSoundElapsedTime(SoundHandle handle) {
+uint32 MixerImpl::getSoundElapsedTime(SoundHandle handle) {
 	Common::StackLock lock(_mutex);
 
 	const int index = handle._val % NUM_CHANNELS;
@@ -288,7 +291,7 @@
 	return _channels[index]->getElapsedTime();
 }
 
-void Mixer::pauseAll(bool paused) {
+void MixerImpl::pauseAll(bool paused) {
 	Common::StackLock lock(_mutex);
 	for (int i = 0; i != NUM_CHANNELS; i++) {
 		if (_channels[i] != 0) {
@@ -297,7 +300,7 @@
 	}
 }
 
-void Mixer::pauseID(int id, bool paused) {
+void MixerImpl::pauseID(int id, bool paused) {
 	Common::StackLock lock(_mutex);
 	for (int i = 0; i != NUM_CHANNELS; i++) {
 		if (_channels[i] != 0 && _channels[i]->getId() == id) {
@@ -307,7 +310,7 @@
 	}
 }
 
-void Mixer::pauseHandle(SoundHandle handle, bool paused) {
+void MixerImpl::pauseHandle(SoundHandle handle, bool paused) {
 	Common::StackLock lock(_mutex);
 
 	// Simply ignore (un)pause requests for sounds that already terminated
@@ -318,7 +321,7 @@
 	_channels[index]->pause(paused);
 }
 
-bool Mixer::isSoundIDActive(int id) {
+bool MixerImpl::isSoundIDActive(int id) {
 	Common::StackLock lock(_mutex);
 	for (int i = 0; i != NUM_CHANNELS; i++)
 		if (_channels[i] && _channels[i]->getId() == id)
@@ -326,7 +329,7 @@
 	return false;
 }
 
-int Mixer::getSoundID(SoundHandle handle) {
+int MixerImpl::getSoundID(SoundHandle handle) {
 	Common::StackLock lock(_mutex);
 	const int index = handle._val % NUM_CHANNELS;
 	if (_channels[index] && _channels[index]->_handle._val == handle._val)
@@ -334,13 +337,13 @@
 	return 0;
 }
 
-bool Mixer::isSoundHandleActive(SoundHandle handle) {
+bool MixerImpl::isSoundHandleActive(SoundHandle handle) {
 	Common::StackLock lock(_mutex);
 	const int index = handle._val % NUM_CHANNELS;
 	return _channels[index] && _channels[index]->_handle._val == handle._val;
 }
 
-bool Mixer::hasActiveChannelOfType(SoundType type) {
+bool MixerImpl::hasActiveChannelOfType(SoundType type) {
 	Common::StackLock lock(_mutex);
 	for (int i = 0; i != NUM_CHANNELS; i++)
 		if (_channels[i] && _channels[i]->_type == type)
@@ -348,7 +351,7 @@
 	return false;
 }
 
-void Mixer::setVolumeForSoundType(SoundType type, int volume) {
+void MixerImpl::setVolumeForSoundType(SoundType type, int volume) {
 	assert(0 <= type && type < ARRAYSIZE(_volumeForSoundType));
 
 	// Check range
@@ -363,7 +366,7 @@
 	_volumeForSoundType[type] = volume;
 }
 
-int Mixer::getVolumeForSoundType(SoundType type) const {
+int MixerImpl::getVolumeForSoundType(SoundType type) const {
 	assert(0 <= type && type < ARRAYSIZE(_volumeForSoundType));
 
 	return _volumeForSoundType[type];
@@ -443,7 +446,7 @@
 	// Convert the number of samples into a time duration. To avoid
 	// overflow, this has to be done in a somewhat non-obvious way.
 
-	uint rate = _mixer->getOutputRate();
+	uint32 rate = _mixer->getOutputRate();
 
 	uint32 seconds = _samplesConsumed / rate;
 	uint32 milliseconds = (1000 * (_samplesConsumed % rate)) / rate;

Modified: scummvm/trunk/sound/mixer.h
===================================================================
--- scummvm/trunk/sound/mixer.h	2008-06-28 15:27:40 UTC (rev 32827)
+++ scummvm/trunk/sound/mixer.h	2008-06-28 15:28:29 UTC (rev 32828)
@@ -38,6 +38,7 @@
 class AudioStream;
 class Channel;
 class Mixer;
+class MixerImpl;
 
 /**
  * A SoundHandle instances corresponds to a specific sound
@@ -47,7 +48,7 @@
  */
 class SoundHandle {
 	friend class Channel;
-	friend class Mixer;
+	friend class MixerImpl;
 	uint32 _val;
 public:
 	inline SoundHandle() : _val(0xFFFFFFFF) {}
@@ -104,24 +105,9 @@
 		kMaxMixerVolume = 256
 	};
 
-private:
-	enum {
-		NUM_CHANNELS = 16
-	};
-
-	OSystem *_syst;
-	Common::Mutex _mutex;
-
-	int _volumeForSoundType[4];
-
-	uint32 _handleSeed;
-	Channel *_channels[NUM_CHANNELS];
-
-	bool _mixerReady;
-
 public:
-	Mixer();
-	~Mixer();
+	Mixer() {}
+	virtual ~Mixer() {}
 
 
 
@@ -132,8 +118,10 @@
 	 * sync with an audio stream. In particular, the Adlib MIDI emulation...
 	 *
 	 * @return whether the mixer is ready and setup
+	 *
+	 * @todo get rid of this?
 	 */
-	bool isReady() const { return _mixerReady; }
+	virtual bool isReady() const = 0;
 
 
 
@@ -143,12 +131,12 @@
 	 * (using the makeLinearInputStream factory function), which is then
 	 * passed on to playInputStream.
 	 */
-	void playRaw(
+	virtual void playRaw(
 		SoundType type,
 		SoundHandle *handle,
 		void *sound, uint32 size, uint rate, byte flags,
 		int id = -1, byte volume = kMaxChannelVolume, int8 balance = 0,
-		uint32 loopStart = 0, uint32 loopEnd = 0);
+		uint32 loopStart = 0, uint32 loopEnd = 0) = 0;
 
 	/**
 	 * Start playing the given audio input stream.
@@ -170,35 +158,35 @@
 	 *                  not stop this particular stream
 	 * @param reverseStereo	a flag indicating whether left and right channels shall be swapped
 	 */
-	void playInputStream(
+	virtual void playInputStream(
 		SoundType type,
 		SoundHandle *handle,
 		AudioStream *input,
 		int id = -1, byte volume = kMaxChannelVolume, int8 balance = 0,
 		bool autofreeStream = true,
 		bool permanent = false,
-		bool reverseStereo = false);
+		bool reverseStereo = false) = 0;
 
 
 
 	/**
 	 * Stop all currently playing sounds.
 	 */
-	void stopAll();
+	virtual void stopAll() = 0;
 
 	/**
 	 * Stop playing the sound with given ID.
 	 *
 	 * @param id the ID of the sound to affect
 	 */
-	void stopID(int id);
+	virtual void stopID(int id) = 0;
 
 	/**
 	 * Stop playing the sound corresponding to the given handle.
 	 *
 	 * @param handle the sound to affect
 	 */
-	void stopHandle(SoundHandle handle);
+	virtual void stopHandle(SoundHandle handle) = 0;
 
 
 
@@ -208,7 +196,7 @@
 	 *
 	 * @param paused true to pause everything, false to unpause
 	 */
-	void pauseAll(bool paused);
+	virtual void pauseAll(bool paused) = 0;
 
 	/**
 	 * Pause/unpause the sound with the given ID.
@@ -216,7 +204,7 @@
 	 * @param id the ID of the sound to affect
 	 * @param paused true to pause the sound, false to unpause it
 	 */
-	void pauseID(int id, bool paused);
+	virtual void pauseID(int id, bool paused) = 0;
 
 	/**
 	 * Pause/unpause the sound corresponding to the given handle.
@@ -224,7 +212,7 @@
 	 * @param handle the sound to affect
 	 * @param paused true to pause the sound, false to unpause it
 	 */
-	void pauseHandle(SoundHandle handle, bool paused);
+	virtual void pauseHandle(SoundHandle handle, bool paused) = 0;
 
 
 
@@ -234,7 +222,7 @@
 	 * @param id the ID of the sound to query
 	 * @return true if the sound is active
 	 */
-	bool isSoundIDActive(int id);
+	virtual bool isSoundIDActive(int id) = 0;
 
 	/**
 	 * Get the sound ID of handle sound
@@ -242,7 +230,7 @@
 	 * @param handle sound to query
 	 * @return sound ID if active
 	 */
-	int getSoundID(SoundHandle handle);
+	virtual int getSoundID(SoundHandle handle) = 0;
 
 	/**
 	 * Check if a sound with the given handle is active.
@@ -250,7 +238,7 @@
 	 * @param handle sound to query
 	 * @return true if the sound is active
 	 */
-	bool isSoundHandleActive(SoundHandle handle);
+	virtual bool isSoundHandleActive(SoundHandle handle) = 0;
 
 
 
@@ -260,7 +248,7 @@
 	 * @param handle the sound to affect
 	 * @param volume the new channel volume (0 - kMaxChannelVolume)
 	 */
-	void setChannelVolume(SoundHandle handle, byte volume);
+	virtual void setChannelVolume(SoundHandle handle, byte volume) = 0;
 
 	/**
 	 * Set the channel balance for the given handle.
@@ -269,12 +257,12 @@
 	 * @param balance the new channel balance:
 	 *        (-127 ... 0 ... 127) corresponds to (left ... center ... right)
 	 */
-	void setChannelBalance(SoundHandle handle, int8 balance);
+	virtual void setChannelBalance(SoundHandle handle, int8 balance) = 0;
 
 	/**
 	 * Get approximation of for how long the channel has been playing.
 	 */
-	uint32 getSoundElapsedTime(SoundHandle handle);
+	virtual uint32 getSoundElapsedTime(SoundHandle handle) = 0;
 
 	/**
 	 * Check whether any channel of the given sound type is active.
@@ -284,7 +272,7 @@
 	 * @param  type the sound type to look for
 	 * @return true if any channels of the specified type are active.
 	 */
-	bool hasActiveChannelOfType(SoundType type);
+	virtual bool hasActiveChannelOfType(SoundType type) = 0;
 
 	/**
 	 * Set the volume for the given sound type.
@@ -292,7 +280,7 @@
 	 * @param type the sound type
 	 * @param volume the new global volume, 0 - kMaxMixerVolume
 	 */
-	void setVolumeForSoundType(SoundType type, int volume);
+	virtual void setVolumeForSoundType(SoundType type, int volume) = 0;
 
 	/**
 	 * Query the global volume.
@@ -300,7 +288,7 @@
 	 * @param type the sound type
 	 * @return the global music volume, 0 - kMaxMixerVolume
 	 */
-	int getVolumeForSoundType(SoundType type) const;
+	virtual int getVolumeForSoundType(SoundType type) const = 0;
 
 	/**
 	 * Query the system's audio output sample rate. This returns
@@ -308,26 +296,7 @@
 	 *
 	 * @return the output sample rate in Hz
 	 */
-	uint getOutputRate() const;
-
-protected:
-	void insertChannel(SoundHandle *handle, Channel *chan);
-
-	/**
-	 * Internal main method -- all the actual mixing work is done from here.
-	 */
-	void mix(int16 * buf, uint len);
-
-	// FIXME: temporary "public" to allow access to mixCallback
-	// from within OSystem::makeMixer()
-public:
-	/**
-	 * The mixer callback function, passed on to OSystem::setSoundCallback().
-	 * This simply calls the mix() method.
-	 */
-	static void mixCallback(void *s, byte *samples, int len);
-
-	void setReady(bool ready) { _mixerReady = ready; }
+	virtual uint getOutputRate() const = 0;
 };
 
 

Added: scummvm/trunk/sound/mixer_intern.h
===================================================================
--- scummvm/trunk/sound/mixer_intern.h	                        (rev 0)
+++ scummvm/trunk/sound/mixer_intern.h	2008-06-28 15:28:29 UTC (rev 32828)
@@ -0,0 +1,154 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef SOUND_MIXER_INTERN_H
+#define SOUND_MIXER_INTERN_H
+
+#include "common/scummsys.h"
+#include "common/mutex.h"
+#include "sound/mixer.h"
+
+namespace Audio {
+
+/**
+ * The (default) implementation of the ScummVM audio mixing subsystem.
+ *
+ * Backends are responsible for allocating (and later releasing) an instance
+ * of this class, which engines can access via OSystem::getMixer().
+ *
+ * Initialisation of instances of this class usually happens as follows:
+ * 1) Creat a new Audio::MixerImpl instance.
+ * 2) Set the hardware output sample rate via the setSampleRate() method.
+ * 3) Hook up the mixCallback() in a suitable audio processing thread/callback.
+ * 4) Change the mixer into ready mode via setReady(true).
+ * 5) Start audio processing (e.g. by resuming the audio thread, if applicable).
+ *
+ * In the future, we might make it possible for backends to provide
+ * (partial) alternative implementations of the mixer, e.g. to make
+ * better use of native sound mixing support on low-end devices.
+ *
+ * @see OSystem::getMixer()
+ */
+class MixerImpl : public Mixer {
+private:
+	enum {
+		NUM_CHANNELS = 16
+	};
+
+	OSystem *_syst;
+	Common::Mutex _mutex;
+
+	uint _sampleRate;
+	bool _mixerReady;
+	uint32 _handleSeed;
+
+	int _volumeForSoundType[4];
+	Channel *_channels[NUM_CHANNELS];
+
+
+public:
+	MixerImpl(OSystem *system);
+	~MixerImpl();
+
+	virtual bool isReady() const { return _mixerReady; }
+
+	virtual void playRaw(
+		SoundType type,
+		SoundHandle *handle,
+		void *sound, uint32 size, uint rate, byte flags,
+		int id = -1, byte volume = 255, int8 balance = 0,
+		uint32 loopStart = 0, uint32 loopEnd = 0);
+
+	virtual void playInputStream(
+		SoundType type,
+		SoundHandle *handle,
+		AudioStream *input,
+		int id = -1, byte volume = 255, int8 balance = 0,
+		bool autofreeStream = true,
+		bool permanent = false,
+		bool reverseStereo = false);
+
+
+
+	virtual void stopAll();
+	virtual void stopID(int id);
+	virtual void stopHandle(SoundHandle handle);
+
+	virtual void pauseAll(bool paused);
+	virtual void pauseID(int id, bool paused);
+	virtual void pauseHandle(SoundHandle handle, bool paused);
+
+	virtual bool isSoundIDActive(int id);
+	virtual int getSoundID(SoundHandle handle);
+
+	virtual bool isSoundHandleActive(SoundHandle handle);
+
+	virtual void setChannelVolume(SoundHandle handle, byte volume);
+	virtual void setChannelBalance(SoundHandle handle, int8 balance);
+
+	virtual uint32 getSoundElapsedTime(SoundHandle handle);
+
+	virtual bool hasActiveChannelOfType(SoundType type);
+
+	virtual void setVolumeForSoundType(SoundType type, int volume);
+	virtual int getVolumeForSoundType(SoundType type) const;
+
+	virtual uint getOutputRate() const;
+
+protected:
+	void insertChannel(SoundHandle *handle, Channel *chan);
+
+public:
+	/**
+	 * The mixer callback function, to be called at regular intervals by
+	 * the backend (e.g. from an audio mixing thread). All the actual mixing
+	 * work is done from here.
+	 */
+	void mixCallback(byte *samples, uint len);
+
+	/**
+	 * Set the internal 'is ready' flag of the mixer.
+	 * Backends should invoke Mixer::setReady(true) once initialisation of
+	 * their audio system has been completed (and in particular, *after*
+	 * setOutputRate() has been called).
+	 */
+	void setReady(bool ready);
+	
+	/**
+	 * Set the output sample rate.
+	 *
+	 * @param sampleRate	the new output sample rate
+	 *
+	 * @note Right now, this can be done exactly ONCE. That is, the mixer
+	 * currently does not support changing the output sample rate after it
+	 * has been set for the first time.  This may change in the future.
+	 */
+	void setOutputRate(uint sampleRate);
+};
+
+
+} // End of namespace Audio
+
+#endif


Property changes on: scummvm/trunk/sound/mixer_intern.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Date Rev Author URL Id
Name: svn:eol-style
   + native


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