- 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.


SVN r1208 (trunk)
This commit is contained in:
Christoph Oelckers 2008-09-09 20:49:53 +00:00
parent 5ad25e5d07
commit e033cbf9f8
8 changed files with 218 additions and 174 deletions

View File

@ -1,4 +1,10 @@
September 9, 2008 (Changes by Graf Zahl) 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 - Fixed: FMODSoundRenderer::StartSound3D must set the static variable pointing
to the rolloff information back to NULL when starting the sound fails. to the rolloff information back to NULL when starting the sound fails.
- Fixed: Rolloff information was taken from the sfxinfo that contained the - Fixed: Rolloff information was taken from the sfxinfo that contained the

View File

@ -377,7 +377,7 @@ unsigned int S_GetMSLength(FSoundID sound)
} }
sfx = S_LoadSound(sfx); sfx = S_LoadSound(sfx);
if (sfx != NULL) return GSnd->GetMSLength(sfx); if (sfx != NULL) return GSnd->GetMSLength(sfx->data);
else return 0; else return 0;
} }
@ -483,7 +483,7 @@ int S_AddSoundLump (const char *logicalname, int lump)
{ {
sfxinfo_t newsfx; sfxinfo_t newsfx;
newsfx.data = NULL; newsfx.data.Clear();
newsfx.name = logicalname; newsfx.name = logicalname;
newsfx.lumpnum = lump; newsfx.lumpnum = lump;
newsfx.next = 0; newsfx.next = 0;

View File

@ -523,9 +523,10 @@ void S_CacheSound (sfxinfo_t *sfx)
void S_UnloadSound (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]); 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; SoundListener listener;
S_SetListener(listener, players[consoleplayer].camera); 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 else
{ {
chan = GSnd->StartSound (sfx, volume, pitch, chanflags, NULL); chan = GSnd->StartSound (sfx->data, volume, pitch, chanflags, NULL);
} }
if (chan == NULL && (chanflags & CHAN_LOOP)) if (chan == NULL && (chanflags & CHAN_LOOP))
{ {
@ -1099,12 +1100,12 @@ void S_RestartSound(FSoundChan *chan)
SoundListener listener; SoundListener listener;
S_SetListener(listener, players[consoleplayer].camera); 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); chan->Priority, pos, vel, chan->EntChannel, chan->ChanFlags, chan);
} }
else 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); assert(ochan == NULL || ochan == chan);
if (ochan != NULL) 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) sfxinfo_t *S_LoadSound(sfxinfo_t *sfx)
{ {
while (sfx->data == NULL) if (GSnd->IsNull()) return sfx;
while (!sfx->data.isValid())
{ {
unsigned int i; 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. // then set this one up as a link, and don't load the sound again.
for (i = 0; i < S_sfx.Size(); i++) 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); DPrintf ("Linked %s to %s (%d)\n", sfx->name.GetChars(), S_sfx[i].name.GetChars(), i);
sfx->link = 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]; return &S_sfx[i];
} }
} }
DPrintf("Loading sound \"%s\" (%td)\n", sfx->name.GetChars(), sfx - &S_sfx[0]); 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) if (sfx->lumpnum != sfx_empty)
{ {

View File

@ -35,6 +35,13 @@ struct FRolloffInfo
union { float MaxDistance; float RolloffFactor; }; union { float MaxDistance; float RolloffFactor; };
}; };
struct SoundHandle
{
void *data;
bool isValid() const { return data != NULL; }
void Clear() { data = NULL; }
};
// //
// SoundFX struct. // SoundFX struct.
@ -43,7 +50,7 @@ struct sfxinfo_t
{ {
// Next field is for use by the system sound interface. // Next field is for use by the system sound interface.
// A non-null data means the sound has been loaded. // A non-null data means the sound has been loaded.
void *data; SoundHandle data;
FString name; // [RH] Sound name defined in SNDINFO FString name; // [RH] Sound name defined in SNDINFO
int lumpnum; // lump number of sfx int lumpnum; // lump number of sfx
@ -65,7 +72,6 @@ struct sfxinfo_t
WORD bUsed:1; WORD bUsed:1;
WORD bSingular:1; WORD bSingular:1;
WORD bTentative:1; WORD bTentative:1;
WORD RolloffType:2;
unsigned int link; unsigned int link;
enum { NO_LINK = 0xffffffff }; enum { NO_LINK = 0xffffffff };

View File

@ -975,10 +975,6 @@ void FMODSoundRenderer::Shutdown()
{ {
if (Sys != NULL) if (Sys != NULL)
{ {
unsigned int i;
//S_StopAllChannels();
if (MusicGroup != NULL) if (MusicGroup != NULL)
{ {
MusicGroup->release(); MusicGroup->release();
@ -1005,16 +1001,6 @@ void FMODSoundRenderer::Shutdown()
WaterReverb = NULL; 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->close();
Sys->release(); Sys->release();
Sys = NULL; 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_RESULT result;
FMOD_MODE mode; FMOD_MODE mode;
FMOD::Channel *chan; FMOD::Channel *chan;
float freq; 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); 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? 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) if (FMOD_OK == result)
{ {
result = chan->getMode(&mode); result = chan->getMode(&mode);
@ -1386,8 +1371,8 @@ FSoundChan *FMODSoundRenderer::StartSound(sfxinfo_t *sfx, float vol, int pitch,
return CommonChannelSetup(chan, reuse_chan); return CommonChannelSetup(chan, reuse_chan);
} }
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; return NULL;
} }
//========================================================================== //==========================================================================
@ -1398,12 +1383,11 @@ FSoundChan *FMODSoundRenderer::StartSound(sfxinfo_t *sfx, float vol, int pitch,
CVAR(Float, snd_3dspread, 180, 0) 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, FRolloffInfo *rolloff, float distscale,
int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int pitch, int priority, const FVector3 &pos, const FVector3 &vel,
int channum, int chanflags, FSoundChan *reuse_chan) int channum, int chanflags, FSoundChan *reuse_chan)
{ {
int id = int(sfx - &S_sfx[0]);
FMOD_RESULT result; FMOD_RESULT result;
FMOD_MODE mode; FMOD_MODE mode;
FMOD::Channel *chan; FMOD::Channel *chan;
@ -1412,11 +1396,11 @@ FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, SoundListener *liste
int numchans; int numchans;
int def_priority; 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); freq = PITCH(def_freq, pitch);
// Change the sound's default priority before playing it. // 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 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 // 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 // with the same priority level but has no problem with kicking out sounds at
// higher priority levels if it needs to. // 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. // Then set the priority back.
if (def_priority >= 0) 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 // 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 // and is likely to be very similar, resulting in an amplitude twice what it
// would have been had it been mixed to mono. // 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) if (numchans > 1)
{ {
@ -1462,7 +1446,7 @@ FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, SoundListener *liste
{ {
mode = (mode & ~FMOD_LOOP_OFF) | FMOD_LOOP_NORMAL; 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->setMode(mode);
chan->setChannelGroup((chanflags & (CHAN_UI | CHAN_NOPAUSE)) ? SfxGroup : PausableSfx); chan->setChannelGroup((chanflags & (CHAN_UI | CHAN_NOPAUSE)) ? SfxGroup : PausableSfx);
@ -1484,7 +1468,7 @@ FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, SoundListener *liste
} }
GRolloff = NULL; 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; 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, const FVector3 &pos, int channum, int chanflags,
FMOD_MODE oldmode) const FMOD_MODE oldmode) const
{ {
@ -1737,7 +1721,7 @@ void FMODSoundRenderer::UpdateSoundParams3D(SoundListener *listener, FSoundChan
{ {
oldmode = FMOD_3D | FMOD_SOFTWARE; 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) if (mode != oldmode)
{ // Only set the mode if it changed. { // Only set the mode if it changed.
fchan->setMode(mode); fchan->setMode(mode);
@ -1891,110 +1875,88 @@ void FMODSoundRenderer::UpdateSounds()
Sys->update(); 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 // 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; DPrintf("Failed to allocate sample: Error %d\n", result);
BYTE *sfxdata; return retval;
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);
}
} }
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(); ((FMOD::Sound *)sfx.data)->release();
sfx->data = NULL;
} }
} }
@ -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; 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; return length;
} }

View File

@ -13,9 +13,10 @@ public:
void SetSfxVolume (float volume); void SetSfxVolume (float volume);
void SetMusicVolume (float volume); void SetMusicVolume (float volume);
bool LoadSound (sfxinfo_t *sfx); SoundHandle LoadSound(BYTE *sfxdata, int length);
void UnloadSound (sfxinfo_t *sfx); SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits);
unsigned int GetMSLength(sfxinfo_t *sfx); void UnloadSound (SoundHandle sfx);
unsigned int GetMSLength(SoundHandle sfx);
float GetOutputRate(); float GetOutputRate();
// Streaming sounds. // Streaming sounds.
@ -25,8 +26,8 @@ public:
void StopStream (SoundStream *stream); void StopStream (SoundStream *stream);
// Starts a sound. // Starts a sound.
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);
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);
// Stops a sound channel. // Stops a sound channel.
void StopSound (FSoundChan *chan); void StopSound (FSoundChan *chan);
@ -69,9 +70,7 @@ private:
void HandleChannelDelay(FMOD::Channel *chan, FSoundChan *reuse_chan, float freq) const; void HandleChannelDelay(FMOD::Channel *chan, FSoundChan *reuse_chan, float freq) const;
FSoundChan *CommonChannelSetup(FMOD::Channel *chan, FSoundChan *reuse_chan) 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; FMOD_MODE SetChanHeadSettings(SoundListener *listener, FMOD::Channel *chan, const FVector3 &pos, int channum, int chanflags, FMOD_MODE oldmode) const;
void DoLoad (void **slot, sfxinfo_t *sfx);
void getsfx (sfxinfo_t *sfx);
bool Init (); bool Init ();
void Shutdown (); void Shutdown ();

View File

@ -83,6 +83,8 @@ CVAR (Bool, snd_pitched, false, CVAR_ARCHIVE)
SoundRenderer *GSnd; SoundRenderer *GSnd;
void I_CloseSound ();
// //
// SFX API // SFX API
@ -110,20 +112,27 @@ CUSTOM_CVAR (Float, snd_sfxvolume, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOIN
class NullSoundRenderer : public SoundRenderer class NullSoundRenderer : public SoundRenderer
{ {
public: public:
virtual bool IsNull() { return true; }
void SetSfxVolume (float volume) void SetSfxVolume (float volume)
{ {
} }
void SetMusicVolume (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 // Return something that isn't 0. This is only used by some
// ambient sounds to specify a default minimum period. // ambient sounds to specify a default minimum period.
@ -145,11 +154,11 @@ public:
} }
// Starts a sound. (No, not really.) // 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; 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; return NULL;
} }
@ -230,7 +239,7 @@ void I_InitSound ()
if (!GSnd->IsValid ()) if (!GSnd->IsValid ())
{ {
delete GSnd; I_CloseSound();
GSnd = new NullSoundRenderer; GSnd = new NullSoundRenderer;
Printf (TEXTCOLOR_RED"Sound init failed. Using nosound.\n"); 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) if (GSnd != NULL)
{ {
delete GSnd; S_StopAllChannels();
GSnd = NULL; I_CloseSound();
} }
} }
@ -257,11 +278,7 @@ CCMD (snd_reset)
{ {
I_ShutdownMusic(); I_ShutdownMusic();
S_EvictAllChannels(); S_EvictAllChannels();
if (GSnd != NULL) I_CloseSound();
{
delete GSnd;
GSnd = NULL;
}
I_InitSound(); I_InitSound();
S_RestartMusic(); S_RestartMusic();
S_RestoreEvictedChannels(); S_RestoreEvictedChannels();

View File

@ -89,11 +89,13 @@ public:
SoundRenderer (); SoundRenderer ();
virtual ~SoundRenderer (); virtual ~SoundRenderer ();
virtual bool IsNull() { return false; }
virtual void SetSfxVolume (float volume) = 0; virtual void SetSfxVolume (float volume) = 0;
virtual void SetMusicVolume (float volume) = 0; virtual void SetMusicVolume (float volume) = 0;
virtual bool LoadSound (sfxinfo_t *sfx) = 0; // load a sound from disk virtual SoundHandle LoadSound(BYTE *sfxdata, int length) = 0;
virtual void UnloadSound (sfxinfo_t *sfx) = 0; // unloads a sound from memory virtual SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits) = 0;
virtual unsigned int GetMSLength(sfxinfo_t *sfx) = 0; // Gets the length of a sound at its default frequency 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; virtual float GetOutputRate() = 0;
// Streaming sounds. // Streaming sounds.
@ -101,8 +103,8 @@ public:
virtual SoundStream *OpenStream (const char *filename, int flags, int offset, int length) = 0; virtual SoundStream *OpenStream (const char *filename, int flags, int offset, int length) = 0;
// Starts a sound. // Starts a sound.
virtual FSoundChan *StartSound (sfxinfo_t *sfx, float vol, int pitch, int chanflags, FSoundChan *reuse_chan) = 0; virtual FSoundChan *StartSound (SoundHandle 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 *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. // Stops a sound channel.
virtual void StopSound (FSoundChan *chan) = 0; virtual void StopSound (FSoundChan *chan) = 0;