diff --git a/docs/rh-log.txt b/docs/rh-log.txt index e019fc59d..81bbdc7c4 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,10 @@ September 9, 2008 (Changes by Graf Zahl) +- Since loading of the sound lump is now done in S_LoadSound I added an IsNull + method to the SoundRenderer class so that this function doesn't need to + load the sound for the NullSoundRenderer. +- Took some more non-FMOD related code out of fmodsound.cpp, including the + code that checks for raw and Doom sounds. This means that sfxinfo_t is no + longer needed in the SoundRenderer class so I took out all references to it. - Fixed: FMODSoundRenderer::StartSound3D must set the static variable pointing to the rolloff information back to NULL when starting the sound fails. - Fixed: Rolloff information was taken from the sfxinfo that contained the diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index 84a9a9542..3bc4e993b 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -377,7 +377,7 @@ unsigned int S_GetMSLength(FSoundID sound) } sfx = S_LoadSound(sfx); - if (sfx != NULL) return GSnd->GetMSLength(sfx); + if (sfx != NULL) return GSnd->GetMSLength(sfx->data); else return 0; } @@ -483,7 +483,7 @@ int S_AddSoundLump (const char *logicalname, int lump) { sfxinfo_t newsfx; - newsfx.data = NULL; + newsfx.data.Clear(); newsfx.name = logicalname; newsfx.lumpnum = lump; newsfx.next = 0; diff --git a/src/s_sound.cpp b/src/s_sound.cpp index fb1bf85ac..db1eae740 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -523,9 +523,10 @@ void S_CacheSound (sfxinfo_t *sfx) void S_UnloadSound (sfxinfo_t *sfx) { - if (sfx->data != NULL) + if (sfx->data.isValid()) { - GSnd->UnloadSound(sfx); + GSnd->UnloadSound(sfx->data); + sfx->data.Clear(); DPrintf("Unloaded sound \"%s\" (%td)\n", sfx->name.GetChars(), sfx - &S_sfx[0]); } } @@ -1011,11 +1012,11 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO { SoundListener listener; S_SetListener(listener, players[consoleplayer].camera); - chan = GSnd->StartSound3D (sfx, &listener, volume, rolloff, attenuation, pitch, basepriority, pos, vel, channel, chanflags, NULL); + chan = GSnd->StartSound3D (sfx->data, &listener, volume, rolloff, attenuation, pitch, basepriority, pos, vel, channel, chanflags, NULL); } else { - chan = GSnd->StartSound (sfx, volume, pitch, chanflags, NULL); + chan = GSnd->StartSound (sfx->data, volume, pitch, chanflags, NULL); } if (chan == NULL && (chanflags & CHAN_LOOP)) { @@ -1099,12 +1100,12 @@ void S_RestartSound(FSoundChan *chan) SoundListener listener; S_SetListener(listener, players[consoleplayer].camera); - ochan = GSnd->StartSound3D(sfx, &listener, chan->Volume, chan->Rolloff, chan->DistanceScale, chan->Pitch, + ochan = GSnd->StartSound3D(sfx->data, &listener, chan->Volume, chan->Rolloff, chan->DistanceScale, chan->Pitch, chan->Priority, pos, vel, chan->EntChannel, chan->ChanFlags, chan); } else { - ochan = GSnd->StartSound(chan->SfxInfo, chan->Volume, chan->Pitch, chan->ChanFlags, chan); + ochan = GSnd->StartSound(sfx->data, chan->Volume, chan->Pitch, chan->ChanFlags, chan); } assert(ochan == NULL || ochan == chan); if (ochan != NULL) @@ -1188,7 +1189,9 @@ void S_Sound (const sector_t *sec, int channel, FSoundID sfxid, float volume, fl sfxinfo_t *S_LoadSound(sfxinfo_t *sfx) { - while (sfx->data == NULL) + if (GSnd->IsNull()) return sfx; + + while (!sfx->data.isValid()) { unsigned int i; @@ -1202,16 +1205,66 @@ sfxinfo_t *S_LoadSound(sfxinfo_t *sfx) // then set this one up as a link, and don't load the sound again. for (i = 0; i < S_sfx.Size(); i++) { - if (S_sfx[i].data && S_sfx[i].link == sfxinfo_t::NO_LINK && S_sfx[i].lumpnum == sfx->lumpnum) + if (S_sfx[i].data.isValid() && S_sfx[i].link == sfxinfo_t::NO_LINK && S_sfx[i].lumpnum == sfx->lumpnum) { DPrintf ("Linked %s to %s (%d)\n", sfx->name.GetChars(), S_sfx[i].name.GetChars(), i); sfx->link = i; + // This is necessary to avoid using the rolloff settings of the linked sound if its + // settings are different. + if (sfx->Rolloff.MinDistance == 0) sfx->Rolloff = S_Rolloff; return &S_sfx[i]; } } DPrintf("Loading sound \"%s\" (%td)\n", sfx->name.GetChars(), sfx - &S_sfx[0]); - if (!GSnd->LoadSound (sfx)) + + int size = Wads.LumpLength(sfx->lumpnum); + if (size > 0) + { + BYTE *sfxdata; + BYTE *sfxstart; + FWadLump wlump = Wads.OpenLumpNum(sfx->lumpnum); + sfxstart = sfxdata = new BYTE[size]; + wlump.Read(sfxdata, size); + SDWORD len = ((SDWORD *)sfxdata)[1]; + + // If the sound is raw, just load it as such. + // Otherwise, try the sound as DMX format. + // If that fails, let FMOD try and figure it out. + if (sfx->bLoadRAW || + (((BYTE *)sfxdata)[0] == 3 && ((BYTE *)sfxdata)[1] == 0 && len <= size - 8)) + { + int frequency; + + if (sfx->bLoadRAW) + { + len = Wads.LumpLength (sfx->lumpnum); + frequency = (sfx->bForce22050 ? 22050 : 11025); + } + else + { + frequency = ((WORD *)sfxdata)[1]; + if (frequency == 0) + { + frequency = 11025; + } + sfxstart = sfxdata + 8; + } + sfx->data = GSnd->LoadSoundRaw(sfxstart, len, frequency, 1, 8); + } + else + { + len = Wads.LumpLength (sfx->lumpnum); + sfx->data = GSnd->LoadSound(sfxstart, len); + } + + if (sfxdata != NULL) + { + delete[] sfxdata; + } + } + + if (!sfx->data.isValid()) { if (sfx->lumpnum != sfx_empty) { diff --git a/src/s_sound.h b/src/s_sound.h index 717247ad6..5a93ee87f 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -35,6 +35,13 @@ struct FRolloffInfo union { float MaxDistance; float RolloffFactor; }; }; +struct SoundHandle +{ + void *data; + + bool isValid() const { return data != NULL; } + void Clear() { data = NULL; } +}; // // SoundFX struct. @@ -43,7 +50,7 @@ struct sfxinfo_t { // Next field is for use by the system sound interface. // A non-null data means the sound has been loaded. - void *data; + SoundHandle data; FString name; // [RH] Sound name defined in SNDINFO int lumpnum; // lump number of sfx @@ -65,7 +72,6 @@ struct sfxinfo_t WORD bUsed:1; WORD bSingular:1; WORD bTentative:1; - WORD RolloffType:2; unsigned int link; enum { NO_LINK = 0xffffffff }; diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index f1ffdc656..903c3d5d8 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -975,10 +975,6 @@ void FMODSoundRenderer::Shutdown() { if (Sys != NULL) { - unsigned int i; - - //S_StopAllChannels(); - if (MusicGroup != NULL) { MusicGroup->release(); @@ -1005,16 +1001,6 @@ void FMODSoundRenderer::Shutdown() WaterReverb = NULL; } - // Free all loaded samples - for (i = 0; i < S_sfx.Size(); i++) - { - if (S_sfx[i].data != NULL) - { - ((FMOD::Sound *)S_sfx[i].data)->release(); - S_sfx[i].data = NULL; - } - } - Sys->close(); Sys->release(); Sys = NULL; @@ -1341,15 +1327,14 @@ SoundStream *FMODSoundRenderer::OpenStream(const char *filename_or_data, int fla // //========================================================================== -FSoundChan *FMODSoundRenderer::StartSound(sfxinfo_t *sfx, float vol, int pitch, int chanflags, FSoundChan *reuse_chan) +FSoundChan *FMODSoundRenderer::StartSound(SoundHandle sfx, float vol, int pitch, int chanflags, FSoundChan *reuse_chan) { - int id = int(sfx - &S_sfx[0]); FMOD_RESULT result; FMOD_MODE mode; FMOD::Channel *chan; float freq; - if (FMOD_OK == ((FMOD::Sound *)sfx->data)->getDefaults(&freq, NULL, NULL, NULL)) + if (FMOD_OK == ((FMOD::Sound *)sfx.data)->getDefaults(&freq, NULL, NULL, NULL)) { freq = PITCH(freq, pitch); } @@ -1359,7 +1344,7 @@ FSoundChan *FMODSoundRenderer::StartSound(sfxinfo_t *sfx, float vol, int pitch, } GRolloff = NULL; // Do 2D sounds need rolloff? - result = Sys->playSound(FMOD_CHANNEL_FREE, (FMOD::Sound *)sfx->data, true, &chan); + result = Sys->playSound(FMOD_CHANNEL_FREE, (FMOD::Sound *)sfx.data, true, &chan); if (FMOD_OK == result) { result = chan->getMode(&mode); @@ -1386,8 +1371,8 @@ FSoundChan *FMODSoundRenderer::StartSound(sfxinfo_t *sfx, float vol, int pitch, return CommonChannelSetup(chan, reuse_chan); } - DPrintf ("Sound %s failed to play: %d\n", sfx->name.GetChars(), result); - return 0; + //DPrintf ("Sound %s failed to play: %d\n", sfx->name.GetChars(), result); + return NULL; } //========================================================================== @@ -1398,12 +1383,11 @@ FSoundChan *FMODSoundRenderer::StartSound(sfxinfo_t *sfx, float vol, int pitch, CVAR(Float, snd_3dspread, 180, 0) -FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, SoundListener *listener, float vol, +FSoundChan *FMODSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FSoundChan *reuse_chan) { - int id = int(sfx - &S_sfx[0]); FMOD_RESULT result; FMOD_MODE mode; FMOD::Channel *chan; @@ -1412,11 +1396,11 @@ FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, SoundListener *liste int numchans; int def_priority; - if (FMOD_OK == ((FMOD::Sound *)sfx->data)->getDefaults(&def_freq, &def_vol, &def_pan, &def_priority)) + if (FMOD_OK == ((FMOD::Sound *)sfx.data)->getDefaults(&def_freq, &def_vol, &def_pan, &def_priority)) { freq = PITCH(def_freq, pitch); // Change the sound's default priority before playing it. - ((FMOD::Sound *)sfx->data)->setDefaults(def_freq, def_vol, def_pan, clamp(def_priority - priority, 1, 256)); + ((FMOD::Sound *)sfx.data)->setDefaults(def_freq, def_vol, def_pan, clamp(def_priority - priority, 1, 256)); } else { @@ -1432,18 +1416,18 @@ FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, SoundListener *liste // as long as the paremeters are set properly. It will first try to kick out sounds // with the same priority level but has no problem with kicking out sounds at // higher priority levels if it needs to. - result = Sys->playSound(FMOD_CHANNEL_FREE, (FMOD::Sound *)sfx->data, true, &chan); + result = Sys->playSound(FMOD_CHANNEL_FREE, (FMOD::Sound *)sfx.data, true, &chan); // Then set the priority back. if (def_priority >= 0) { - ((FMOD::Sound *)sfx->data)->setDefaults(def_freq, def_vol, def_pan, def_priority); + ((FMOD::Sound *)sfx.data)->setDefaults(def_freq, def_vol, def_pan, def_priority); } // Reduce volume of stereo sounds, because each channel will be summed together // and is likely to be very similar, resulting in an amplitude twice what it // would have been had it been mixed to mono. - if (FMOD_OK == ((FMOD::Sound *)sfx->data)->getFormat(NULL, NULL, &numchans, NULL)) + if (FMOD_OK == ((FMOD::Sound *)sfx.data)->getFormat(NULL, NULL, &numchans, NULL)) { if (numchans > 1) { @@ -1462,7 +1446,7 @@ FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, SoundListener *liste { mode = (mode & ~FMOD_LOOP_OFF) | FMOD_LOOP_NORMAL; } - mode = SetChanHeadSettings(listener, chan, sfx, pos, channum, chanflags, mode); + mode = SetChanHeadSettings(listener, chan, pos, channum, chanflags, mode); chan->setMode(mode); chan->setChannelGroup((chanflags & (CHAN_UI | CHAN_NOPAUSE)) ? SfxGroup : PausableSfx); @@ -1484,7 +1468,7 @@ FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, SoundListener *liste } GRolloff = NULL; - DPrintf ("Sound %s failed to play: %d\n", sfx->name.GetChars(), result); + //DPrintf ("Sound %s failed to play: %d\n", sfx->name.GetChars(), result); return 0; } @@ -1542,7 +1526,7 @@ void FMODSoundRenderer::HandleChannelDelay(FMOD::Channel *chan, FSoundChan *reus // //========================================================================== -FMOD_MODE FMODSoundRenderer::SetChanHeadSettings(SoundListener *listener, FMOD::Channel *chan, sfxinfo_t *sfx, +FMOD_MODE FMODSoundRenderer::SetChanHeadSettings(SoundListener *listener, FMOD::Channel *chan, const FVector3 &pos, int channum, int chanflags, FMOD_MODE oldmode) const { @@ -1737,7 +1721,7 @@ void FMODSoundRenderer::UpdateSoundParams3D(SoundListener *listener, FSoundChan { oldmode = FMOD_3D | FMOD_SOFTWARE; } - mode = SetChanHeadSettings(listener, fchan, chan->SfxInfo, pos, chan->EntChannel, chan->ChanFlags, oldmode); + mode = SetChanHeadSettings(listener, fchan, pos, chan->EntChannel, chan->ChanFlags, oldmode); if (mode != oldmode) { // Only set the mode if it changed. fchan->setMode(mode); @@ -1891,110 +1875,88 @@ void FMODSoundRenderer::UpdateSounds() Sys->update(); } +//========================================================================== +// +// FMODSoundRenderer :: LoadSoundRaw +// +//========================================================================== + +SoundHandle FMODSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits) +{ + FMOD_CREATESOUNDEXINFO exinfo = { sizeof(exinfo), }; + SoundHandle retval = { NULL }; + + if (length == 0) return retval; + + exinfo.length = length; + exinfo.numchannels = channels; + exinfo.defaultfrequency = frequency; + switch (bits) + { + case 8: + // Need to convert sample data from unsigned to signed. + for (int i = 0; i < length; ++i) + { + sfxdata[i] = sfxdata[i] - 128; + } + + case -8: + exinfo.format = FMOD_SOUND_FORMAT_PCM8; + break; + + case 16: + exinfo.format = FMOD_SOUND_FORMAT_PCM16; + break; + + case 32: + exinfo.format = FMOD_SOUND_FORMAT_PCM32; + break; + + default: + return retval; + } + + const FMOD_MODE samplemode = FMOD_3D | FMOD_OPENMEMORY | FMOD_SOFTWARE | FMOD_OPENRAW; + FMOD::Sound *sample; + FMOD_RESULT result; + + result = Sys->createSound((char *)sfxdata, samplemode, &exinfo, &sample); + if (result != FMOD_OK) + { + DPrintf("Failed to allocate sample: Error %d\n", result); + return retval; + } + retval.data = sample; + return retval; +} + //========================================================================== // // FMODSoundRenderer :: LoadSound // //========================================================================== -bool FMODSoundRenderer::LoadSound(sfxinfo_t *sfx) +SoundHandle FMODSoundRenderer::LoadSound(BYTE *sfxdata, int length) { - if (sfx->data == NULL) + FMOD_CREATESOUNDEXINFO exinfo = { sizeof(exinfo), }; + SoundHandle retval = { NULL }; + + if (length == 0) return retval; + + exinfo.length = length; + + const FMOD_MODE samplemode = FMOD_3D | FMOD_OPENMEMORY | FMOD_SOFTWARE; + FMOD::Sound *sample; + FMOD_RESULT result; + + result = Sys->createSound((char *)sfxdata, samplemode, &exinfo, &sample); + if (result != FMOD_OK) { - void **slot = &sfx->data; - BYTE *sfxdata; - BYTE *sfxstart; - int size; - FMOD_RESULT result; - FMOD_MODE samplemode; - FMOD_CREATESOUNDEXINFO exinfo = { sizeof(exinfo), }; - FMOD::Sound *sample; - - samplemode = FMOD_3D | FMOD_OPENMEMORY | FMOD_SOFTWARE; - - sfxdata = NULL; - sample = NULL; - - size = Wads.LumpLength(sfx->lumpnum); - if (size <= 0) return false; - - FWadLump wlump = Wads.OpenLumpNum(sfx->lumpnum); - sfxstart = sfxdata = new BYTE[size]; - wlump.Read(sfxdata, size); - SDWORD len = ((SDWORD *)sfxdata)[1]; - - // If the sound is raw, just load it as such. - // Otherwise, try the sound as DMX format. - // If that fails, let FMOD try and figure it out. - if (sfx->bLoadRAW || - (((BYTE *)sfxdata)[0] == 3 && ((BYTE *)sfxdata)[1] == 0 && len <= size - 8)) - { - int frequency; - - if (sfx->bLoadRAW) - { - len = Wads.LumpLength (sfx->lumpnum); - frequency = (sfx->bForce22050 ? 22050 : 11025); - } - else - { - frequency = ((WORD *)sfxdata)[1]; - if (frequency == 0) - { - frequency = 11025; - } - sfxstart = sfxdata + 8; - } - - exinfo.length = len; - exinfo.numchannels = 1; - exinfo.defaultfrequency = frequency; - exinfo.format = FMOD_SOUND_FORMAT_PCM8; - - samplemode |= FMOD_OPENRAW; - - // Need to convert sample data from unsigned to signed. - for (int i = 0; i < len; ++i) - { - sfxstart[i] = sfxstart[i] - 128; - } - } - else - { - exinfo.length = size; - } - - if (exinfo.length == 0) - { - DPrintf("Sample has a length of 0\n"); - } - else - { - result = Sys->createSound((char *)sfxstart, samplemode, &exinfo, &sample); - if (result != FMOD_OK) - { - DPrintf("Failed to allocate sample: Error %d\n", result); - - if (sfxdata != NULL) - { - delete[] sfxdata; - } - return false; - } - *slot = sample; - } - - if (sfxdata != NULL) - { - delete[] sfxdata; - } - - if (sample != NULL) - { - sample->setUserData(sfx); - } + DPrintf("Failed to allocate sample: Error %d\n", result); + return retval; } - return sfx->data != NULL; + retval.data = sample; + return retval; } //========================================================================== @@ -2003,12 +1965,11 @@ bool FMODSoundRenderer::LoadSound(sfxinfo_t *sfx) // //========================================================================== -void FMODSoundRenderer::UnloadSound(sfxinfo_t *sfx) +void FMODSoundRenderer::UnloadSound(SoundHandle sfx) { - if (sfx->data != NULL) + if (sfx.data != NULL) { - ((FMOD::Sound *)sfx->data)->release(); - sfx->data = NULL; + ((FMOD::Sound *)sfx.data)->release(); } } @@ -2018,13 +1979,13 @@ void FMODSoundRenderer::UnloadSound(sfxinfo_t *sfx) // //========================================================================== -unsigned int FMODSoundRenderer::GetMSLength(sfxinfo_t *sfx) +unsigned int FMODSoundRenderer::GetMSLength(SoundHandle sfx) { - if (sfx->data != NULL) + if (sfx.data != NULL) { unsigned int length; - if (((FMOD::Sound *)sfx->data)->getLength(&length, FMOD_TIMEUNIT_MS) == FMOD_OK) + if (((FMOD::Sound *)sfx.data)->getLength(&length, FMOD_TIMEUNIT_MS) == FMOD_OK) { return length; } diff --git a/src/sound/fmodsound.h b/src/sound/fmodsound.h index dc0b528b6..5c3061c1c 100644 --- a/src/sound/fmodsound.h +++ b/src/sound/fmodsound.h @@ -13,9 +13,10 @@ public: void SetSfxVolume (float volume); void SetMusicVolume (float volume); - bool LoadSound (sfxinfo_t *sfx); - void UnloadSound (sfxinfo_t *sfx); - unsigned int GetMSLength(sfxinfo_t *sfx); + SoundHandle LoadSound(BYTE *sfxdata, int length); + SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits); + void UnloadSound (SoundHandle sfx); + unsigned int GetMSLength(SoundHandle sfx); float GetOutputRate(); // Streaming sounds. @@ -25,8 +26,8 @@ public: void StopStream (SoundStream *stream); // Starts a sound. - FSoundChan *StartSound (sfxinfo_t *sfx, float vol, int pitch, int chanflags, FSoundChan *reuse_chan); - FSoundChan *StartSound3D (sfxinfo_t *sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FSoundChan *reuse_chan); + FSoundChan *StartSound (SoundHandle sfx, float vol, int pitch, int chanflags, FSoundChan *reuse_chan); + FSoundChan *StartSound3D (SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FSoundChan *reuse_chan); // Stops a sound channel. void StopSound (FSoundChan *chan); @@ -69,9 +70,7 @@ private: void HandleChannelDelay(FMOD::Channel *chan, FSoundChan *reuse_chan, float freq) const; FSoundChan *CommonChannelSetup(FMOD::Channel *chan, FSoundChan *reuse_chan) const; - FMOD_MODE SetChanHeadSettings(SoundListener *listener, FMOD::Channel *chan, sfxinfo_t *sfx, const FVector3 &pos, int channum, int chanflags, FMOD_MODE oldmode) const; - void DoLoad (void **slot, sfxinfo_t *sfx); - void getsfx (sfxinfo_t *sfx); + FMOD_MODE SetChanHeadSettings(SoundListener *listener, FMOD::Channel *chan, const FVector3 &pos, int channum, int chanflags, FMOD_MODE oldmode) const; bool Init (); void Shutdown (); diff --git a/src/sound/i_sound.cpp b/src/sound/i_sound.cpp index 5628b0021..3b65e718c 100644 --- a/src/sound/i_sound.cpp +++ b/src/sound/i_sound.cpp @@ -83,6 +83,8 @@ CVAR (Bool, snd_pitched, false, CVAR_ARCHIVE) SoundRenderer *GSnd; +void I_CloseSound (); + // // SFX API @@ -110,20 +112,27 @@ CUSTOM_CVAR (Float, snd_sfxvolume, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOIN class NullSoundRenderer : public SoundRenderer { public: + virtual bool IsNull() { return true; } void SetSfxVolume (float volume) { } void SetMusicVolume (float volume) { } - bool LoadSound (sfxinfo_t *sfx) + SoundHandle LoadSound(BYTE *sfxdata, int length) { - return true; + SoundHandle retval = { NULL }; + return retval; } - void UnloadSound (sfxinfo_t *sfx) + SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits) + { + SoundHandle retval = { NULL }; + return retval; + } + void UnloadSound (SoundHandle sfx) { } - unsigned int GetMSLength(sfxinfo_t *sfx) + unsigned int GetMSLength(SoundHandle sfx) { // Return something that isn't 0. This is only used by some // ambient sounds to specify a default minimum period. @@ -145,11 +154,11 @@ public: } // Starts a sound. (No, not really.) - FSoundChan *StartSound (sfxinfo_t *sfx, float vol, int pitch, int chanflags, FSoundChan *reuse_chan) + FSoundChan *StartSound (SoundHandle sfx, float vol, int pitch, int chanflags, FSoundChan *reuse_chan) { return NULL; } - FSoundChan *StartSound3D (sfxinfo_t *sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FSoundChan *reuse_chan) + FSoundChan *StartSound3D (SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FSoundChan *reuse_chan) { return NULL; } @@ -230,7 +239,7 @@ void I_InitSound () if (!GSnd->IsValid ()) { - delete GSnd; + I_CloseSound(); GSnd = new NullSoundRenderer; Printf (TEXTCOLOR_RED"Sound init failed. Using nosound.\n"); } @@ -239,12 +248,24 @@ void I_InitSound () } -void I_ShutdownSound (void) +void I_CloseSound () +{ + // Free all loaded samples + for (unsigned i = 0; i < S_sfx.Size(); i++) + { + S_UnloadSound(&S_sfx[i]); + } + + delete GSnd; + GSnd = NULL; +} + +void I_ShutdownSound() { if (GSnd != NULL) { - delete GSnd; - GSnd = NULL; + S_StopAllChannels(); + I_CloseSound(); } } @@ -257,11 +278,7 @@ CCMD (snd_reset) { I_ShutdownMusic(); S_EvictAllChannels(); - if (GSnd != NULL) - { - delete GSnd; - GSnd = NULL; - } + I_CloseSound(); I_InitSound(); S_RestartMusic(); S_RestoreEvictedChannels(); diff --git a/src/sound/i_sound.h b/src/sound/i_sound.h index 2d6308cf8..3e5d6339c 100644 --- a/src/sound/i_sound.h +++ b/src/sound/i_sound.h @@ -89,11 +89,13 @@ public: SoundRenderer (); virtual ~SoundRenderer (); + virtual bool IsNull() { return false; } virtual void SetSfxVolume (float volume) = 0; virtual void SetMusicVolume (float volume) = 0; - virtual bool LoadSound (sfxinfo_t *sfx) = 0; // load a sound from disk - virtual void UnloadSound (sfxinfo_t *sfx) = 0; // unloads a sound from memory - virtual unsigned int GetMSLength(sfxinfo_t *sfx) = 0; // Gets the length of a sound at its default frequency + virtual SoundHandle LoadSound(BYTE *sfxdata, int length) = 0; + virtual SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits) = 0; + virtual void UnloadSound (SoundHandle sfx) = 0; // unloads a sound from memory + virtual unsigned int GetMSLength(SoundHandle sfx) = 0; // Gets the length of a sound at its default frequency virtual float GetOutputRate() = 0; // Streaming sounds. @@ -101,8 +103,8 @@ public: virtual SoundStream *OpenStream (const char *filename, int flags, int offset, int length) = 0; // Starts a sound. - virtual FSoundChan *StartSound (sfxinfo_t *sfx, float vol, int pitch, int chanflags, FSoundChan *reuse_chan) = 0; - virtual FSoundChan *StartSound3D (sfxinfo_t *sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FSoundChan *reuse_chan) = 0; + virtual FSoundChan *StartSound (SoundHandle sfx, float vol, int pitch, int chanflags, FSoundChan *reuse_chan) = 0; + virtual FSoundChan *StartSound3D (SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FSoundChan *reuse_chan) = 0; // Stops a sound channel. virtual void StopSound (FSoundChan *chan) = 0;