[Scummvm-cvs-logs] SF.net SVN: scummvm: [25292] scummvm/trunk/engines/gob

drmccoy at users.sourceforge.net drmccoy at users.sourceforge.net
Tue Jan 30 23:19:56 CET 2007


Revision: 25292
          http://scummvm.svn.sourceforge.net/scummvm/?rev=25292&view=rev
Author:   drmccoy
Date:     2007-01-30 14:19:55 -0800 (Tue, 30 Jan 2007)

Log Message:
-----------
- Changed _soundFlags and implemented "compositions"
- Changed Snd to be a permanent audiostream, to have better control over stopping, looping and compositions
- Some clean-up

Modified Paths:
--------------
    scummvm/trunk/engines/gob/game.cpp
    scummvm/trunk/engines/gob/game_v1.cpp
    scummvm/trunk/engines/gob/game_v2.cpp
    scummvm/trunk/engines/gob/global.cpp
    scummvm/trunk/engines/gob/global.h
    scummvm/trunk/engines/gob/gob.cpp
    scummvm/trunk/engines/gob/init.cpp
    scummvm/trunk/engines/gob/init_v1.cpp
    scummvm/trunk/engines/gob/init_v2.cpp
    scummvm/trunk/engines/gob/inter_v1.cpp
    scummvm/trunk/engines/gob/inter_v2.cpp
    scummvm/trunk/engines/gob/mult_v2.cpp
    scummvm/trunk/engines/gob/music.cpp
    scummvm/trunk/engines/gob/music.h
    scummvm/trunk/engines/gob/sound.cpp
    scummvm/trunk/engines/gob/sound.h

Modified: scummvm/trunk/engines/gob/game.cpp
===================================================================
--- scummvm/trunk/engines/gob/game.cpp	2007-01-30 21:02:42 UTC (rev 25291)
+++ scummvm/trunk/engines/gob/game.cpp	2007-01-30 22:19:55 UTC (rev 25292)
@@ -351,6 +351,13 @@
 	if ((slot < 0) || (slot >= 60) || (_soundSamples[slot] == 0))
 		return;
 
+	if (slot == _vm->_snd->getCompositionSlot()) {
+		if (_vm->_quitRequested)
+			_vm->_snd->stopComposition();
+		else
+			_vm->_snd->waitEndPlay();
+	}
+
 	if (_soundADL[slot]) {
 		if (_vm->_adlib && (_vm->_adlib->getIndex() == slot))
 			_vm->_adlib->stopPlay();

Modified: scummvm/trunk/engines/gob/game_v1.cpp
===================================================================
--- scummvm/trunk/engines/gob/game_v1.cpp	2007-01-30 21:02:42 UTC (rev 25291)
+++ scummvm/trunk/engines/gob/game_v1.cpp	2007-01-30 22:19:55 UTC (rev 25292)
@@ -579,8 +579,6 @@
 			_vm->_draw->animateCursor(-1);
 
 		_vm->_util->delay(10);
-
-		_vm->_snd->loopSounds();
 	}
 }
 

Modified: scummvm/trunk/engines/gob/game_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/game_v2.cpp	2007-01-30 21:02:42 UTC (rev 25291)
+++ scummvm/trunk/engines/gob/game_v2.cpp	2007-01-30 22:19:55 UTC (rev 25292)
@@ -92,18 +92,12 @@
 				_vm->_mult->initAll();
 				_vm->_mult->zeroMultData();
 
-/*				for (i = 0; i < 50; i++)
-					_vm->_draw->_spritesArray[i] = 0;*/
-
 				_vm->_draw->_spritesArray[20] = _vm->_draw->_frontSurface;
 				_vm->_draw->_spritesArray[21] = _vm->_draw->_backSurface;
 				_vm->_draw->_cursorSpritesBack = _vm->_draw->_cursorSprites;
 			} else
 				_vm->_inter->initControlVars(0);
 
-			for (i = 0; i < 20; i++)
-				_soundSamples[i] = 0;
-
 			_totTextData = 0;
 			_totResourceTable = 0;
 			_imFileData = 0;
@@ -661,8 +655,6 @@
 			_vm->_draw->animateCursor(-1);
 
 		_vm->_util->delay(10);
-
-		_vm->_snd->loopSounds();
 	}
 }
 

Modified: scummvm/trunk/engines/gob/global.cpp
===================================================================
--- scummvm/trunk/engines/gob/global.cpp	2007-01-30 21:02:42 UTC (rev 25291)
+++ scummvm/trunk/engines/gob/global.cpp	2007-01-30 22:19:55 UTC (rev 25292)
@@ -37,8 +37,7 @@
 	_videoMode = 0;
 
 	/* Sound */
-	_presentSound = 0x8000;	/* undefined values */
-	_soundFlags = 0x8000;
+	_soundFlags = 0;
 	_blasterPort = 0;
 	_disableSoundCfg = 0;
 

Modified: scummvm/trunk/engines/gob/global.h
===================================================================
--- scummvm/trunk/engines/gob/global.h	2007-01-30 21:02:42 UTC (rev 25291)
+++ scummvm/trunk/engines/gob/global.h	2007-01-30 22:19:55 UTC (rev 25292)
@@ -80,7 +80,6 @@
 
 	int16 _disableVideoCfg;
 
-	uint16 _presentSound;
 	uint16 _soundFlags;
 	int16 _disableSoundCfg;
 	int16 _blasterPort;

Modified: scummvm/trunk/engines/gob/gob.cpp
===================================================================
--- scummvm/trunk/engines/gob/gob.cpp	2007-01-30 21:02:42 UTC (rev 25291)
+++ scummvm/trunk/engines/gob/gob.cpp	2007-01-30 22:19:55 UTC (rev 25292)
@@ -614,14 +614,10 @@
 	else
 		error("GobEngine::init(): Unknown version of game engine");
 	_noMusic = MidiDriver::parseMusicDriver(ConfMan.get("music_driver")) == MD_NULL;
-	if (!(_features & Gob::GF_AMIGA) &&
-			(((_features & Gob::GF_MAC) && (_features & Gob::GF_GOB1)) ||
-			 (_features & Gob::GF_GOB2))) {
-		if (_noMusic)
-			_adlib = new Adlib_Dummy(this);
-		else
-			_adlib = new Adlib(this);
-	}
+	if (!_noMusic && !(_features & Gob::GF_AMIGA) &&
+	   (((_features & Gob::GF_MAC) && (_features & Gob::GF_GOB1)) ||
+	     (_features & Gob::GF_GOB2)))
+		_adlib = new Adlib(this);
 	_vm = this;
 
 	_system->beginGFXTransaction();
@@ -642,7 +638,7 @@
 
 	_global->_videoMode = 0x13;
 	_global->_useMouse = 1;
-	_global->_soundFlags = 0;
+	_global->_soundFlags = MIDI_FLAG | SPEAKER_FLAG | BLASTER_FLAG | ADLIB_FLAG;
 
 	if (ConfMan.hasKey("language"))
 		_language = Common::parseLanguage(ConfMan.get("language"));
@@ -687,7 +683,6 @@
 	//        640x480.
 
 	g_system->setFeatureState(OSystem::kFeatureAutoComputeDirtyRects, true);
-
 	return 0;
 }
 

Modified: scummvm/trunk/engines/gob/init.cpp
===================================================================
--- scummvm/trunk/engines/gob/init.cpp	2007-01-30 21:02:42 UTC (rev 25291)
+++ scummvm/trunk/engines/gob/init.cpp	2007-01-30 22:19:55 UTC (rev 25292)
@@ -50,18 +50,7 @@
 void Init::findBestCfg(void) {
 	_vm->_global->_videoMode = VIDMODE_VGA;
 	_vm->_global->_useMouse = _vm->_global->_mousePresent;
-	if (_vm->_global->_presentSound & BLASTER_FLAG)
-		_vm->_global->_soundFlags = BLASTER_FLAG | SPEAKER_FLAG | MIDI_FLAG;
-	else if (_vm->_global->_presentSound & PROAUDIO_FLAG)
-		_vm->_global->_soundFlags = PROAUDIO_FLAG | SPEAKER_FLAG | MIDI_FLAG;
-	else if (_vm->_global->_presentSound & ADLIB_FLAG)
-		_vm->_global->_soundFlags = ADLIB_FLAG | SPEAKER_FLAG | MIDI_FLAG;
-	else if (_vm->_global->_presentSound & INTERSOUND_FLAG)
-		_vm->_global->_soundFlags = INTERSOUND_FLAG | SPEAKER_FLAG;
-	else if (_vm->_global->_presentSound & SPEAKER_FLAG)
-		_vm->_global->_soundFlags = SPEAKER_FLAG;
-	else
-		_vm->_global->_soundFlags = 0;
+	_vm->_global->_soundFlags = MIDI_FLAG | SPEAKER_FLAG | BLASTER_FLAG | ADLIB_FLAG;
 }
 
 void Init::cleanup(void) {

Modified: scummvm/trunk/engines/gob/init_v1.cpp
===================================================================
--- scummvm/trunk/engines/gob/init_v1.cpp	2007-01-30 21:02:42 UTC (rev 25291)
+++ scummvm/trunk/engines/gob/init_v1.cpp	2007-01-30 22:19:55 UTC (rev 25292)
@@ -41,20 +41,13 @@
 		error("soundVideo: Video mode 0x%x is not supported!",
 		    _vm->_global->_videoMode);
 
-	//if ((flag & 4) == 0)
-	//	_vm->_video->findVideo();
-
 	_vm->_global->_mousePresent = 1;
 
 	_vm->_global->_inVM = 0;
 
-	_vm->_global->_presentSound = 0; // FIXME: sound is not supported yet
-
 	_vm->_global->_sprAllocated = 0;
 	_vm->_gtimer->enableTimer();
 
-	// _vm->_snd->setResetTimerFlag(debugFlag); // TODO
-
 	if (_vm->_global->_videoMode == 0x13)
 		_vm->_global->_colorCount = 256;
 
@@ -66,14 +59,6 @@
 
 	if (_vm->_global->_videoMode != 0)
 		_vm->_video->initSurfDesc(_vm->_global->_videoMode, 320, 200, PRIMARY_SURFACE);
-
-	if (_vm->_global->_soundFlags & MIDI_FLAG) {
-		_vm->_global->_soundFlags &= _vm->_global->_presentSound;
-		if (_vm->_global->_presentSound & ADLIB_FLAG)
-			_vm->_global->_soundFlags |= MIDI_FLAG;
-	} else {
-		_vm->_global->_soundFlags &= _vm->_global->_presentSound;
-	}
 }
 
 } // End of namespace Gob

Modified: scummvm/trunk/engines/gob/init_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/init_v2.cpp	2007-01-30 21:02:42 UTC (rev 25291)
+++ scummvm/trunk/engines/gob/init_v2.cpp	2007-01-30 22:19:55 UTC (rev 25292)
@@ -45,40 +45,24 @@
 	_vm->_draw->_frontSurface = &_vm->_global->_primarySurfDesc;
 	_vm->_video->initSurfDesc(_vm->_global->_videoMode, _vm->_video->_surfWidth, 200, 0x80);
 
-	//if ((flag & 4) == 0)
-	//	_vm->_video->findVideo();
-
 	_vm->_global->_mousePresent = 1;
 
 	_vm->_global->_inVM = 0;
 
-	_vm->_global->_presentSound = 0; // FIXME: sound is not supported yet
-
 	_vm->_global->_sprAllocated = 0;
 	_vm->_gtimer->enableTimer();
 
-	// _vm->_snd->setResetTimerFlag(debugFlag); // TODO
-
-	if (_vm->_global->_videoMode == 0x13)
+	if ((_vm->_global->_videoMode == 0x13) || (_vm->_global->_videoMode == 0x14))
 		_vm->_global->_colorCount = 256;
 
 	_vm->_global->_pPaletteDesc = &_vm->_global->_paletteStruct;
 	_vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaPalette;
 	_vm->_global->_pPaletteDesc->unused1 = _vm->_global->_unusedPalette1;
 	_vm->_global->_pPaletteDesc->unused2 = _vm->_global->_unusedPalette2;
-//	_vm->_global->_pPrimarySurfDesc = &_vm->_global->_primarySurfDesc;
 
 	if (_vm->_global->_videoMode != 0)
 		_vm->_video->initSurfDesc(_vm->_global->_videoMode, _vm->_video->_surfWidth, 200,
 				PRIMARY_SURFACE);
-
-	if (_vm->_global->_soundFlags & MIDI_FLAG) {
-		_vm->_global->_soundFlags &= _vm->_global->_presentSound;
-		if (_vm->_global->_presentSound & ADLIB_FLAG)
-			_vm->_global->_soundFlags |= MIDI_FLAG;
-	} else {
-		_vm->_global->_soundFlags &= _vm->_global->_presentSound;
-	}
 }
 
 } // End of namespace Gob

Modified: scummvm/trunk/engines/gob/inter_v1.cpp
===================================================================
--- scummvm/trunk/engines/gob/inter_v1.cpp	2007-01-30 21:02:42 UTC (rev 25291)
+++ scummvm/trunk/engines/gob/inter_v1.cpp	2007-01-30 22:19:55 UTC (rev 25292)
@@ -1205,7 +1205,7 @@
 	for (i = 0; i < 50; i++)
 		composition[i] = (int16)VAR_OFFSET(dataVar + i * 4);
 
-	_vm->_snd->playComposition(_vm->_game->_soundSamples, composition, freqVal);
+	_vm->_snd->playComposition(composition, freqVal);
 	return false;
 }
 

Modified: scummvm/trunk/engines/gob/inter_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/inter_v2.cpp	2007-01-30 21:02:42 UTC (rev 25291)
+++ scummvm/trunk/engines/gob/inter_v2.cpp	2007-01-30 22:19:55 UTC (rev 25292)
@@ -1401,7 +1401,16 @@
 }
 
 bool Inter_v2::o2_stopSound(char &cmdCount, int16 &counter, int16 &retFlag) {
-	_vm->_snd->stopSound(_vm->_parse->parseValExpr());
+	int16 expr;
+
+	expr = _vm->_parse->parseValExpr();
+
+	if (expr < 0) {
+		if (_vm->_adlib)
+			_vm->_adlib->stopPlay();
+	} else
+		_vm->_snd->stopSound(expr);
+
 	_soundEndTimeKey = 0;
 	return false;
 }

Modified: scummvm/trunk/engines/gob/mult_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/mult_v2.cpp	2007-01-30 21:02:42 UTC (rev 25291)
+++ scummvm/trunk/engines/gob/mult_v2.cpp	2007-01-30 22:19:55 UTC (rev 25292)
@@ -522,7 +522,6 @@
 
 		stop = doFadeAnim(stop);
 		stop = doSoundAnim(stop, _frame);
-		_vm->_snd->loopSounds();
 
 		if (_frame >= endFrame)
 			stopNoClear = 1;

Modified: scummvm/trunk/engines/gob/music.cpp
===================================================================
--- scummvm/trunk/engines/gob/music.cpp	2007-01-30 21:02:42 UTC (rev 25291)
+++ scummvm/trunk/engines/gob/music.cpp	2007-01-30 22:19:55 UTC (rev 25292)
@@ -82,7 +82,6 @@
 	_dataSize = 0;
 	_rate = _vm->_mixer->getOutputRate();
 	_opl = makeAdlibOPL(_rate);
-	_vm->_mixer->setupPremix(this, Audio::Mixer::kMusicSoundType);
 	_first = true;
 	_ended = false;
 	_playing = false;
@@ -92,74 +91,71 @@
 
 	for (i = 0; i < 16; i ++)
 		_pollNotes[i] = 0;
-
 	setFreqs();
+
+	_vm->_mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_handle,
+			this, -1, 255, 0, false, true);
 }
 
 Adlib::~Adlib(void) {
+	Common::StackLock slock(_mutex);
+
+	_vm->_mixer->stopHandle(_handle);
 	OPLDestroy(_opl);
 	if (_data && _needFree)
 		delete[] _data;
-	_vm->_mixer->setupPremix(0);
 }
 
-void Adlib::premixerCall(int16 *buf, uint len) {
-	_mutex.lock();
-	if (!_playing) {
-		memset(buf, 0, 2 * len * sizeof(int16));
-		_mutex.unlock();
-		return;
+int Adlib::readBuffer(int16 *buffer, const int numSamples) {
+	Common::StackLock slock(_mutex);
+	int samples;
+	int render;
+
+	if (!_playing || (numSamples < 0)) {
+		memset(buffer, 0, numSamples * sizeof(int16));
+		return numSamples;
 	}
-	else {
-		if (_first) {
-			memset(buf, 0, 2 * len * sizeof(int16));
+	if (_first) {
+		memset(buffer, 0, numSamples * sizeof(int16));
+		pollMusic();
+		return numSamples;
+	}
+
+	samples = numSamples;
+	while (samples && _playing) {
+		if (_samplesTillPoll) {
+			render = (samples > _samplesTillPoll) ?  (_samplesTillPoll) : (samples);
+			samples -= render;
+			_samplesTillPoll -= render;
+			YM3812UpdateOne(_opl, buffer, render);
+			buffer += render;
+		} else {
 			pollMusic();
-			_mutex.unlock();
-			return;
-		}
-		else {
-			uint32 render;
-			int16 *data = buf;
-			uint datalen = len;
-			while (datalen && _playing) {
-				if (_samplesTillPoll) {
-					render = (datalen > _samplesTillPoll) ?
-						(_samplesTillPoll) : (datalen);
-					datalen -= render;
-					_samplesTillPoll -= render;
-					YM3812UpdateOne(_opl, data, render);
-					data += render;
-				} else {
-					pollMusic();
-					if (_ended) {
-						memset(data, 0, datalen * sizeof(int16));
-						datalen = 0;
-					}
-				}
+			if (_ended) {
+				memset(buffer, 0, samples * sizeof(int16));
+				samples = 0;
 			}
 		}
-		if (_ended) {
-			_first = true;
-			_ended = false;
-			_playPos = _data + 3 + (_data[1] + 1) * 0x38;
-			_samplesTillPoll = 0;
-			if (_repCount == -1) {
-				reset();
-				setVoices();
-			} else if (_repCount > 0) {
-				_repCount--;
-				reset();
-				setVoices();
-			}
-			else
-				_playing = false;
+	}
+
+	if (_ended) {
+		_first = true;
+		_ended = false;
+		_playPos = _data + 3 + (_data[1] + 1) * 0x38;
+		_samplesTillPoll = 0;
+		if (_repCount == -1) {
+			reset();
+			setVoices();
+		} else if (_repCount > 0) {
+			_repCount--;
+			reset();
+			setVoices();
 		}
-		// Convert mono data to stereo
-		for (int i = (len - 1); i >= 0; i--) {
-			buf[2 * i] = buf[2 * i + 1] = buf[i];
-		}
+		else
+			_playing = false;
 	}
-	_mutex.unlock();
+
+	return numSamples;
 }
 
 void Adlib::writeOPL(byte reg, byte val) {
@@ -194,6 +190,7 @@
 }
 
 void Adlib::reset() {
+	_first = true;
 	OPLResetChip(_opl);
 	_samplesTillPoll = 0;
 
@@ -356,21 +353,12 @@
 			setVolume(channel, *(_playPos++));
 			setKey(channel, note, true, false);
 			break;
-		case 0x10:
-			warning("GOB2 Stub! ADL command 0x10");
-			break;
-		case 0x50:
-			warning("GOB2 Stub! ADL command 0x50");
-			break;
 		// Note on
 		case 0x90:
 			note = *(_playPos++);
 			_pollNotes[channel] = note;
 			setKey(channel, note, true, false);
 			break;
-		case 0x60:
-			warning("GOB2 Stub! ADL command 0x60");
-			break;
 		// Last note off
 		case 0x80:
 			note = _pollNotes[channel];

Modified: scummvm/trunk/engines/gob/music.h
===================================================================
--- scummvm/trunk/engines/gob/music.h	2007-01-30 21:02:42 UTC (rev 25291)
+++ scummvm/trunk/engines/gob/music.h	2007-01-30 22:19:55 UTC (rev 25292)
@@ -39,7 +39,7 @@
 class Adlib : public Audio::AudioStream {
 public:
 	Adlib(GobEngine *vm);
-	virtual ~Adlib();
+	~Adlib();
 
 	void lock() { _mutex.lock(); }
 	void unlock() { _mutex.unlock(); }
@@ -50,9 +50,8 @@
 	virtual void startPlay(void) { if (_data) _playing = true; }
 	virtual void stopPlay(void)
 	{
-		_mutex.lock();
+		Common::StackLock slock(_mutex);
 		_playing = false;
-		_mutex.unlock();
 	}
 	virtual void playTrack(const char *trackname);
 	virtual void playBgMusic(void);
@@ -61,12 +60,10 @@
 	virtual void unload(void);
 
 // AudioStream API
-	int readBuffer(int16 *buffer, const int numSamples) {
-		premixerCall(buffer, numSamples / 2);
-		return numSamples;
-	}
-	bool isStereo() const { return true; }
-	bool endOfData() const { return false; }
+	int readBuffer(int16 *buffer, const int numSamples);
+	bool isStereo() const { return false; }
+	bool endOfData() const { return !_playing; }
+	bool endOfStream() const { return false; }
 	int getRate() const { return _rate; }
 	
 protected:
@@ -74,6 +71,7 @@
 	static const char *_trackFiles[];
 	static const unsigned char _operators[];
 	static const unsigned char _volRegNums [];
+	Audio::SoundHandle _handle;
 	FM_OPL *_opl;
 	int _index;
 	byte *_data;
@@ -86,7 +84,7 @@
 	byte _notLin[11];
 	bool _notOn[11];
 	byte _pollNotes[16];
-	uint32 _samplesTillPoll;
+	int _samplesTillPoll;
 	int32 _repCount;
 	bool _playing;
 	bool _first;
@@ -95,7 +93,6 @@
 	Common::Mutex _mutex;
 	GobEngine *_vm;
 
-	void premixerCall(int16 *buf, uint len);
 	void writeOPL(byte reg, byte val);
 	void setFreqs(void);
 	void reset(void);
@@ -106,24 +103,6 @@
 	void pollMusic(void);
 };
 
-/**
- * A dummy class for the "null" sound driver
- */
-class Adlib_Dummy: public Adlib {
-public:
-	Adlib_Dummy(GobEngine *vm) : Adlib(vm) {}
-
-	virtual void startPlay(void) {};
-	virtual void stopPlay(void) {};
-	virtual void playTrack(const char *trackname) {};
-	virtual void playBgAdlib(void) {};
-	virtual bool load(const char *filename) { return true; }
-	virtual void load(byte *data, int index=-1) {}
-	virtual void unload(void) {};
-
-	virtual ~Adlib_Dummy() {};
-};
-
 } // End of namespace Gob
 
 #endif

Modified: scummvm/trunk/engines/gob/sound.cpp
===================================================================
--- scummvm/trunk/engines/gob/sound.cpp	2007-01-30 21:02:42 UTC (rev 25291)
+++ scummvm/trunk/engines/gob/sound.cpp	2007-01-30 22:19:55 UTC (rev 25292)
@@ -61,24 +61,21 @@
 }
 
 Snd::Snd(GobEngine *vm) : _vm(vm) {
-	//CleanupFuncPtr cleanupFunc;// = &snd_cleanupFuncCallback();
 	_cleanupFunc = 0;
-	for (int i = 0; i < ARRAYSIZE(_loopingSounds); i++)
-		_loopingSounds[i] = NULL;
 	_playingSound = 0;
-}
 
-void Snd::loopSounds(void) {
-	for (int i = 0; i < ARRAYSIZE(_loopingSounds); i++) {
-		SoundDesc *snd = _loopingSounds[i];
-		if (snd && !_vm->_mixer->isSoundHandleActive(snd->handle)) {
-			if (snd->repCount-- > 0) {
-				_vm->_mixer->playRaw(&snd->handle, snd->data, snd->size, snd->frequency, 0);
-			} else {
-				_loopingSounds[i] = NULL;
-			}
-		}
-	}
+	_rate = _vm->_mixer->getOutputRate();
+	_end = true;
+	_data = 0;
+	_length = 0;
+	_freq = 0;
+	_repCount = 0;
+	_offset = 0.0;
+
+	_compositionPos = -1;
+
+	_vm->_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_handle,
+			this, -1, 255, 0, false, true);
 }
 
 void Snd::setBlasterPort(int16 port) {return;}
@@ -94,30 +91,56 @@
 	_vm->_mixer->stopHandle(_speakerHandle);
 }
 
-void Snd::playSample(Snd::SoundDesc *sndDesc, int16 repCount, int16 frequency) {
-	if (frequency <= 0)
-		frequency = sndDesc->frequency;
+int8 Snd::getCompositionSlot(void) {
+	if (_compositionPos == -1)
+		return -1;
 
-	for (int i = 0; i < ARRAYSIZE(_loopingSounds); i++)
-		_loopingSounds[i] = 0;
-	_vm->_mixer->stopHandle(sndDesc->handle);
+	return _composition[_compositionPos];
+}
 
-	_vm->_mixer->playRaw(&sndDesc->handle, sndDesc->data, sndDesc->size, frequency, 0);
+void Snd::stopSound(int16 arg)
+{
+	Common::StackLock slock(_mutex);
 
-	sndDesc->repCount = repCount - 1;
-	sndDesc->frequency = frequency;
+	_data = 0;
+	_end = true;
+}
 
-	if (repCount > 1) {
-		for (int i = 0; i < ARRAYSIZE(_loopingSounds); i++) {
-			if (!_loopingSounds[i]) {
-				_loopingSounds[i] = sndDesc;
-				return;
-			}
+void Snd::waitEndPlay(void) {
+	while (!_end)
+		_vm->_util->longDelay(200);
+	stopSound(0);
+}
+
+void Snd::stopComposition(void) {
+	if (_compositionPos != -1) {
+		stopSound(0);
+		_compositionPos = -1;
+	}
+}
+
+void Snd::nextCompositionPos(void) {
+	int8 slot;
+
+	while ((++_compositionPos < 50) && ((slot = _composition[_compositionPos]) != -1)) {
+		if ((slot >= 0) && (slot <= 60) && (_vm->_game->_soundSamples[slot] != 0)
+				&& !(_vm->_game->_soundTypes[slot] & 8)) {
+			setSample(_vm->_game->_soundSamples[slot], 1, 0);
+			return;
 		}
-		warning("Looping sounds list is full");
 	}
+	_compositionPos = -1;
 }
 
+void Snd::playComposition(int16 *composition, int16 freqVal) {
+	waitEndPlay();
+	stopComposition();
+
+	for (int i = 0; i < 50; i++)
+		_composition[i] = composition[i];
+	nextCompositionPos();
+}
+
 void Snd::writeAdlib(int16 port, int16 data) {
 	return;
 }
@@ -133,20 +156,84 @@
 }
 
 void Snd::freeSoundDesc(Snd::SoundDesc *sndDesc, bool freedata) {
-	_vm->_mixer->stopHandle(sndDesc->handle);
+	if (sndDesc == _curSoundDesc)
+		stopSound(0);
 
-	for (int i = 0; i < ARRAYSIZE(_loopingSounds); i++) {
-		if (_loopingSounds[i] == sndDesc)
-			_loopingSounds[i] = NULL;
-	}
-
 	if (freedata) {
 		delete[] sndDesc->data;
 	}
 	delete sndDesc;
 }
 
-}                               // End of namespace Gob
+void Snd::setSample(Snd::SoundDesc *sndDesc, int16 repCount, int16 frequency) {
+	if (frequency <= 0)
+		frequency = sndDesc->frequency;
 
+	_curSoundDesc = sndDesc;
+	sndDesc->repCount = repCount - 1;
+	sndDesc->frequency = frequency;
 
+	_data = (int8 *) sndDesc->data;
+	_length = sndDesc->size;
+	_freq = frequency;
+	_ratio = ((double) _freq) / _rate;
+	_offset = 0.0;
+	_frac = 0;
+	_cur = 0;
+	_last = 0;
+	_repCount = repCount;
+	_end = false;
+	_playingSound = 0;
+}
 
+void Snd::playSample(Snd::SoundDesc *sndDesc, int16 repCount, int16 frequency) {
+	Common::StackLock slock(_mutex);
+
+	if (!_end)
+		return; 
+
+	setSample(sndDesc, repCount, frequency);
+	if (!_vm->_mixer->isSoundHandleActive(_handle))
+		_vm->_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_handle,
+				this, -1, 255, 0, false, true);
+}
+
+void Snd::checkEndSample(void) {
+	if (_compositionPos != -1)
+		nextCompositionPos();
+	else if ((_repCount == -1) || (--_repCount > 0)) {
+		_offset = 0.0;
+		_end = false;
+		_playingSound = 0;
+	} else {
+		_end = true;
+		_playingSound = 0;
+	}
+}
+
+int Snd::readBuffer(int16 *buffer, const int numSamples) {
+	memset(buffer, 0, numSamples);
+
+	for (int i = 0; i < numSamples; i++) {
+		Common::StackLock slock(_mutex);
+
+		if (!_data)
+			return i;
+		if (_end || (_offset >= _length))
+			checkEndSample();
+		if (_end)
+			return i;
+
+		*buffer++ = (int) (_last + (_cur - _last) * _frac);
+		_frac += _ratio;
+		while (_frac > 1) {
+			_frac -= 1;
+			_last = _cur;
+			_cur = _data[(int) _offset] << 8;
+		}
+		_offset += _ratio;
+	}
+	return numSamples;
+}
+
+} // End of namespace Gob

Modified: scummvm/trunk/engines/gob/sound.h
===================================================================
--- scummvm/trunk/engines/gob/sound.h	2007-01-30 21:02:42 UTC (rev 25291)
+++ scummvm/trunk/engines/gob/sound.h	2007-01-30 22:19:55 UTC (rev 25292)
@@ -28,7 +28,7 @@
 
 namespace Gob {
 
-class Snd {
+class Snd : public Audio::AudioStream {
 public:
 	struct SoundDesc {
 		Audio::SoundHandle handle;
@@ -45,7 +45,6 @@
 
 	typedef void (*CleanupFuncPtr) (int16);
 
-	SoundDesc *_loopingSounds[10]; // Should be enough
 	char _playingSound;
 	CleanupFuncPtr _cleanupFunc;
 
@@ -53,16 +52,23 @@
 	void speakerOn(int16 frequency, int32 length);
 	void speakerOff(void);
 	SoundDesc *loadSoundData(const char *path);
-	void stopSound(int16 arg){return;}
-	void loopSounds(void);
+	void stopSound(int16 arg);
 	void playSample(SoundDesc *sndDesc, int16 repCount, int16 frequency);
-	void playComposition(Snd::SoundDesc ** samples, int16 *composit, int16 freqVal) {;}
-	void waitEndPlay(void) {;}
+	void playComposition(int16 *composition, int16 freqVal);
+	void stopComposition(void);
+	int8 getCompositionSlot(void);
+	void waitEndPlay(void);
 
 	// This deletes sndDesc and stops playing the sample.
 	// If freedata is set, it also delete[]s the sample data.
 	void freeSoundDesc(SoundDesc *sndDesc, bool freedata=true);
 
+	int readBuffer(int16 *buffer, const int numSamples);
+	bool isStereo() const { return false; }
+	bool endOfData() const { return _end; }
+	bool endOfStream() const { return false; }
+	int getRate() const { return _rate; }
+
 protected:
 	// TODO: This is a very primitive square wave generator. The only thing is
 	//       has in common with the PC speaker is that it sounds terrible.
@@ -91,6 +97,26 @@
 	SquareWaveStream _speakerStream;
 	Audio::SoundHandle _speakerHandle;
 
+	Audio::SoundHandle *_activeHandle;
+	Audio::SoundHandle _compositionHandle;
+	int16 _composition[50];
+	int8 _compositionPos;
+
+	Audio::SoundHandle _handle;
+	Common::Mutex _mutex;
+	SoundDesc *_curSoundDesc;
+	bool _end;
+	int8 *_data;
+	uint32 _length;
+	uint32 _rate;
+	int32 _freq;
+	int32 _repCount;
+	double _offset;
+	double _ratio;
+	double _frac;
+	int16 _cur;
+	int16 _last;
+
 	GobEngine *_vm;
 
 	void cleanupFuncCallback() {;}
@@ -101,6 +127,9 @@
 	void writeAdlib(int16 port, int16 data);
 	void setBlasterPort(int16 port);
 	void setResetTimerFlag(char flag){return;}
+	void setSample(Snd::SoundDesc *sndDesc, int16 repCount, int16 frequency);
+	void checkEndSample(void);
+	void nextCompositionPos(void);
 };
 
 }				// End of namespace Gob


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