diff options
| author | yinsimei | 2017-06-09 07:55:03 +0200 | 
|---|---|---|
| committer | Eugene Sandulenko | 2017-07-13 18:27:45 +0200 | 
| commit | 747820bbede13235fbf2bd301ebae88ffa0ccf40 (patch) | |
| tree | 926b910ec5fec54378fea31c57426a7ea2f61e29 | |
| parent | 7b2a2123f4cfacf44ab51220c271121b1cb9ba89 (diff) | |
| download | scummvm-rg350-747820bbede13235fbf2bd301ebae88ffa0ccf40.tar.gz scummvm-rg350-747820bbede13235fbf2bd301ebae88ffa0ccf40.tar.bz2 scummvm-rg350-747820bbede13235fbf2bd301ebae88ffa0ccf40.zip | |
SLUDGE: get loop sound work for wav and ogg
| -rw-r--r-- | engines/sludge/main_loop.cpp | 5 | ||||
| -rw-r--r-- | engines/sludge/sound.cpp | 356 | 
2 files changed, 70 insertions, 291 deletions
| diff --git a/engines/sludge/main_loop.cpp b/engines/sludge/main_loop.cpp index 7498ab271d..6655b9b9de 100644 --- a/engines/sludge/main_loop.cpp +++ b/engines/sludge/main_loop.cpp @@ -361,11 +361,10 @@ int main_loop(const char *filename)  		cursor = SDL_CreateCursor(&data, &data, 1, 1, 0, 0);  		SDL_SetCursor(cursor);  	} - +#endif  	if (!(specialSettings & SPECIAL_SILENT)) {  		initSoundStuff(hMainWindow);  	} -#endif  	startNewFunctionNum(0, 0, NULL, noStack); @@ -391,9 +390,7 @@ int main_loop(const char *filename)  	delete[] gamePath; -#if 0  	killSoundStuff(); -#endif  #if defined(HAVE_GLES2)  	EGL_Close(); diff --git a/engines/sludge/sound.cpp b/engines/sludge/sound.cpp index 0aa9d57c86..88604dd5cd 100644 --- a/engines/sludge/sound.cpp +++ b/engines/sludge/sound.cpp @@ -20,12 +20,9 @@   *   */ -#if 0 -#include "AL/alure.h" -#endif -  #include "common/debug.h"  #include "common/file.h" +#include "common/memstream.h"  #include "audio/audiostream.h"  #include "audio/mixer.h" @@ -48,21 +45,18 @@  namespace Sludge {  bool soundOK = false; -bool cacheLoopySound = false;  bool SilenceIKillYou = false;  struct soundThing { -#if 0 -	alureStream *stream; -	ALuint playingOnSource; -#endif -	bool playing; -	int fileLoaded, vol;    //Used for sounds only. -	bool looping;           //Used for sounds only. +	Audio::SoundHandle handle; +	int fileLoaded, vol;    //Used for sounds only. (sound saving/loading) +	bool looping;      		//Used for sounds only. (sound saving/loading)  };  soundThing soundCache[MAX_SAMPLES]; +#if 0  soundThing modCache[MAX_MODS]; +#endif  int intpointers[MAX_SAMPLES];  int defVol = 128; @@ -74,30 +68,16 @@ const float modLoudness = 0.95f;   */  bool initSoundStuff(HWND hwnd) { -#if 0 -	if (!alureInitDevice(NULL, NULL)) { -		debugOut("Failed to open OpenAL device: %s\n", alureGetErrorString()); -		return 1; -	} - -	int a; -	for (a = 0; a < MAX_SAMPLES; a ++) { -		soundCache[a].stream = NULL; -		soundCache[a].playing = false; +	for (int a = 0; a < MAX_SAMPLES; a ++) {  		soundCache[a].fileLoaded = -1;  		soundCache[a].looping = false;  		intpointers[a] = a;  	} - -	for (a = 0; a < MAX_MODS; a ++) { +#if 0 +	for (int a = 0; a < MAX_MODS; a ++) {  		modCache[a].stream = NULL;  		modCache[a].playing = false;  	} - -	if (! alureUpdateInterval(0.01)) { -		debugOut("Failed to set Alure update interval: %s\n", alureGetErrorString()); -		return 1; -	}  #endif  	return soundOK = true;  } @@ -105,28 +85,14 @@ bool initSoundStuff(HWND hwnd) {  void killSoundStuff() {  	if (!soundOK)  		return; -#if 0 +  	SilenceIKillYou = true;  	for (int i = 0; i < MAX_SAMPLES; i ++) { -		if (soundCache[i].playing) { - -			if (! alureStopSource(soundCache[i].playingOnSource, AL_TRUE)) { -				debugOut("Failed to stop source: %s\n", -						alureGetErrorString()); -			} - -		} - -		if (soundCache[i].stream != NULL) { - -			if (! alureDestroyStream(soundCache[i].stream, 0, NULL)) { -				debugOut("Failed to destroy stream: %s\n", -						alureGetErrorString()); -			} - +		if (g_sludge->_mixer->isSoundHandleActive(soundCache[i].handle)) { +			g_sludge->_mixer->stopHandle(soundCache[i].handle);  		}  	} - +#if 0  	for (int i = 0; i < MAX_MODS; i ++) {  		if (modCache[i].playing) { @@ -146,11 +112,8 @@ void killSoundStuff() {  		}  	} - -	SilenceIKillYou = false; - -	alureShutdownDevice();  #endif +	SilenceIKillYou = false;  }  /* @@ -160,12 +123,11 @@ void killSoundStuff() {  void setMusicVolume(int a, int v) {  	if (!soundOK)  		return; - -	if (modCache[a].playing) {  #if 0 +	if (modCache[a].playing) {  		alSourcef(modCache[a].playingOnSource, AL_GAIN, (float) modLoudness * v / 256); -#endif  	} +#endif  }  void setDefaultMusicVolume(int v) { @@ -177,11 +139,9 @@ void setSoundVolume(int a, int v) {  		return;  	int ch = findInSoundCache(a);  	if (ch != -1) { -		if (soundCache[ch].playing) { +		if (g_sludge->_mixer->isSoundHandleActive(soundCache[ch].handle)) {  			soundCache[ch].vol = v; -#if 0 -			alSourcef(soundCache[ch].playingOnSource, AL_GAIN, (float) v / 256); -#endif +			g_sludge->_mixer->setChannelVolume(soundCache[ch].handle, v);  		}  	}  } @@ -286,26 +246,15 @@ void huntKillSound(int filenum) {  void freeSound(int a) {  	if (!soundOK)  		return; -#if 0 -	// Clear OpenAL errors to make sure they don't block anything: -	alGetError();  	SilenceIKillYou = true; -	if (soundCache[a].playing) { -		if (! alureStopSource(soundCache[a].playingOnSource, AL_TRUE)) { -			debugOut("Failed to stop source: %s\n", -					alureGetErrorString()); -		} -	} -	if (! alureDestroyStream(soundCache[a].stream, 0, NULL)) { -		debugOut("Failed to destroy stream: %s\n", -				alureGetErrorString()); +	if (g_sludge->_mixer->isSoundHandleActive(soundCache[a].handle)) { +		g_sludge->_mixer->stopHandle(soundCache[a].handle);  	} -	soundCache[a].stream = NULL;  	soundCache[a].fileLoaded = -1; -#endif +  	SilenceIKillYou = false;  } @@ -321,75 +270,6 @@ void huntKillFreeSound(int filenum) {  /*   * Loading and playing:   */ - -void playStream(int a, bool isMOD, bool loopy) { -#if 0 -	if (! soundOK) return; -	ALboolean ok; -	ALuint src; -	soundThing *st; -	void (*eos_callback)(void *userdata, ALuint source); - -	if (isMOD) { -		st = &modCache[a]; -		eos_callback = mod_eos_callback; -	} else { -		st = &soundCache[a]; -		eos_callback = sound_eos_callback; -	} - -	alGenSources(1, &src); -	if (alGetError() != AL_NO_ERROR) { -		debugOut("Failed to create OpenAL source!\n"); -		return; -	} - -	if (isMOD) { -		alSourcef(src, AL_GAIN, (float) modLoudness * defVol / 256); -	} else { -		alSourcef(src, AL_GAIN, (float) soundCache[a].vol / 256); -	} - -	if (loopy) { -		ok = alurePlaySourceStream(src, (*st).stream, -				NUM_BUFS, -1, eos_callback, &intpointers[a]); -	} else { -		ok = alurePlaySourceStream(src, (*st).stream, -				NUM_BUFS, 0, eos_callback, &intpointers[a]); -	} - -	if (!ok) { - -		debugOut("Failed to play stream: %s\n", alureGetErrorString()); -		alDeleteSources(1, &src); -		if (alGetError() != AL_NO_ERROR) { -			debugOut("Failed to delete OpenAL source!\n"); -		} - -		(*st).playingOnSource = 0; -	} else { -		(*st).playingOnSource = src; -		(*st).playing = true; -	} -#endif -} - -char *loadEntireFileToMemory(Common::SeekableReadStream *inputFile, -		uint32 size) { -	char *allData = new char[size]; -	if (!allData) -		return NULL; - -	size_t bytes_read = inputFile->read(allData, size); -	if (bytes_read != size && inputFile->err()) { -		debugOut("Reading error in loadEntireFileToMemory.\n"); -	} - -	finishAccess(); - -	return allData; -} -  bool playMOD(int f, int a, int fromTrack) {  #if 0  	// load sound @@ -464,7 +344,7 @@ bool stillPlayingSound(int ch) {  	if (soundOK)  		if (ch != -1)  			if (soundCache[ch].fileLoaded != -1) -				if (soundCache[ch].playing) +				if (g_sludge->_mixer->isSoundHandleActive(soundCache[ch].handle))  					return true;  	return false; @@ -493,26 +373,16 @@ bool forceRemoveSound() {  int emptySoundSlot = 0;  int findEmptySoundSlot() { -	int t; -	for (t = 0; t < MAX_SAMPLES; t++) { -		emptySoundSlot++; -		emptySoundSlot %= MAX_SAMPLES; -#if 0 -		if (soundCache[emptySoundSlot].stream == NULL) -		return emptySoundSlot; -#endif -	} - -	for (t = 0; t < MAX_SAMPLES; t++) { +	for (int t = 0; t < MAX_SAMPLES; t++) {  		emptySoundSlot++;  		emptySoundSlot %= MAX_SAMPLES; -		if (!soundCache[emptySoundSlot].playing) +		if (!g_sludge->_mixer->isSoundHandleActive(soundCache[emptySoundSlot].handle))  			return emptySoundSlot;  	}  	// Argh! They're all playing! Let's trash the oldest that's not looping... -	for (t = 0; t < MAX_SAMPLES; t++) { +	for (int t = 0; t < MAX_SAMPLES; t++) {  		emptySoundSlot++;  		emptySoundSlot %= MAX_SAMPLES;  		if (!soundCache[emptySoundSlot].looping) @@ -527,132 +397,72 @@ int findEmptySoundSlot() {  }  int cacheSound(int f) { +	return 0; // don't load source in advance +} +int makeSoundAudioStream(int f, Audio::AudioStream *&audiostream, bool loopy) {  	if (!soundOK)  		return -1; -	unsigned int chunkLength; -	int retval; -	bool loopy; -#if 0 -	loopy = cacheLoopySound; -	cacheLoopySound = false; - -	setResourceForFatal(f); - -	if (! soundOK) return 0; -  	int a = findInSoundCache(f); -	if (a != -1) { - -		if (soundCache[a].playing) { -			if (! alureStopSource(soundCache[a].playingOnSource, AL_TRUE)) { -				debugOut("Failed to stop source: %s\n", -						alureGetErrorString()); -			} -		} -		if (! alureRewindStream(soundCache[a].stream)) { -			debugOut("Failed to rewind stream: %s\n", -					alureGetErrorString()); +	if (a != -1) { // if this sound has been loaded before +		// still playing +		if (g_sludge->_mixer->isSoundHandleActive(soundCache[a].handle)) { +			g_sludge->_mixer->stopHandle(soundCache[a].handle); // stop it  		} - -		return a; +	} else { +		if (f == -2) +			return -1; +		a = findEmptySoundSlot(); +		freeSound(a);  	} -	if (f == -2) return -1; -	a = findEmptySoundSlot(); -	freeSound(a); +	setResourceForFatal(f);  	uint32 length = openFileFromNum(f); -	if (! length) return -1; - -	unsigned char *memImage; - -	bool tryAgain = true; - -	while (tryAgain) { -		memImage = (unsigned char *)loadEntireFileToMemory(bigDataFile, length); -		tryAgain = memImage == NULL; -		if (tryAgain) { -			if (! forceRemoveSound()) { -				fatal(ERROR_SOUND_MEMORY_LOW); -				return -1; -			} -		} -	} +	if (!length) +		return -1; -	chunkLength = 19200; +	uint curr_ptr = bigDataFile->pos(); +	Audio::RewindableAudioStream *stream = Audio::makeWAVStream(bigDataFile->readStream(length), DisposeAfterUse::NO); -	// Small looping sounds need small chunklengths. -	if (loopy) { -		if (length < NUM_BUFS * chunkLength) { -			chunkLength = length / NUM_BUFS; -		} -	} else if (length < chunkLength) { -		chunkLength = length; +#ifdef USE_VORBIS +	if (!stream) { +		bigDataFile->seek(curr_ptr); +		stream = Audio::makeVorbisStream(bigDataFile->readStream(length), DisposeAfterUse::NO);  	} +#endif +	finishAccess(); -	soundCache[a].stream = alureCreateStreamFromMemory(memImage, length, chunkLength, 0, NULL); - -	delete[] memImage; - -	if (soundCache[a].stream != NULL) { +	if (stream) { +		audiostream = Audio::makeLoopingAudioStream(stream, loopy ? 0 : 1);  		soundCache[a].fileLoaded = f;  		setResourceForFatal(-1); -		retval = a;  	} else { - -		debugOut("Failed to create stream from sound: %s\n", -				alureGetErrorString()); - +		audiostream = nullptr;  		warning(ERROR_SOUND_ODDNESS); -		soundCache[a].stream = NULL; -		soundCache[a].playing = false; -		soundCache[a].playingOnSource = 0;  		soundCache[a].fileLoaded = -1;  		soundCache[a].looping = false; -		retval = -1; +		return -1;  	} -#endif -	return retval; + +	return a;  }  bool startSound(int f, bool loopy) { -	if (loopy) // TODO: don't consider loop sound yet at this stage -		return false; -	// load sound -	setResourceForFatal(f); -	uint32 length = openFileFromNum(f); -	Common::SeekableReadStream *memImage = bigDataFile->readStream(length); -	if (memImage->size() != length || bigDataFile->err()) -		debug("Sound reading failed"); -	Audio::AudioStream *stream = Audio::makeWAVStream(memImage, DisposeAfterUse::NO); -#ifdef USE_VORBIS -	if (!stream) { -		stream = Audio::makeVorbisStream(memImage, DisposeAfterUse::NO); -	} -#endif -	delete memImage; -	if (!stream) -		return false; - -	// play sound -	Audio::SoundHandle soundHandle; -	g_sludge->_mixer->playStream(Audio::Mixer::kSFXSoundType, &soundHandle, stream, -1, Audio::Mixer::kMaxChannelVolume); -#if 0  	if (soundOK) { - -		cacheLoopySound = loopy; -		int a = cacheSound(f); +		// Load sound +		Audio::AudioStream *stream = nullptr; +		int a = makeSoundAudioStream(f, stream, loopy);  		if (a == -1) {  			debugOut("Failed to cache sound!\n");  			return false;  		} + +		// play sound  		soundCache[a].looping = loopy;  		soundCache[a].vol = defSoundVol; - -		playStream(a, false, loopy); +		g_sludge->_mixer->playStream(Audio::Mixer::kSFXSoundType, &soundCache[a].handle, stream, -1, soundCache[a].vol);  	} -#endif  	return true;  } @@ -760,54 +570,26 @@ static void list_eos_callback(void *list, ALuint source) {  }  #endif +// loop a list of sound  void playSoundList(soundList *s) { -#if 0  	if (soundOK) { -		cacheLoopySound = true; -		int a = cacheSound(s->sound); +		// Load sound +		Audio::AudioStream *stream; +		int a = makeSoundAudioStream(s->sound, stream, true);  		if (a == -1) {  			debugOut("Failed to cache sound!\n");  			return;  		} + +		// Play sound  		soundCache[a].looping = false;  		if (s->vol < 0) -		soundCache[a].vol = defSoundVol; +			soundCache[a].vol = defSoundVol;  		else -		soundCache[a].vol = s->vol; +			soundCache[a].vol = s->vol;  		s-> cacheIndex = a; - -		ALboolean ok; -		ALuint src; -		soundThing *st; - -		st = &soundCache[a]; - -		alGenSources(1, &src); -		if (alGetError() != AL_NO_ERROR) { -			debugOut("Failed to create OpenAL source!\n"); -			return; -		} - -		alSourcef(src, AL_GAIN, (float) soundCache[a].vol / 256); - -		ok = alurePlaySourceStream(src, (*st).stream, -				NUM_BUFS, 0, list_eos_callback, s); - -		if (!ok) { - -			debugOut("Failed to play stream: %s\n", alureGetErrorString()); -			alDeleteSources(1, &src); -			if (alGetError() != AL_NO_ERROR) { -				debugOut("Failed to delete OpenAL source!\n"); -			} - -			(*st).playingOnSource = 0; -		} else { -			(*st).playingOnSource = src; -			(*st).playing = true; -		} +		g_sludge->_mixer->playStream(Audio::Mixer::kSFXSoundType, &soundCache[a].handle, stream, -1, soundCache[a].vol);  	} -#endif  }  void playMovieStream(int a) { | 
