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 /engines/sludge/sound.cpp | |
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
Diffstat (limited to 'engines/sludge/sound.cpp')
-rw-r--r-- | engines/sludge/sound.cpp | 356 |
1 files changed, 69 insertions, 287 deletions
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) { |