@ -152,13 +152,13 @@ static unsigned int SND_GetDelay(const sfx_t *sfx, float maxseconds)
{
{
unsigned int delay ;
unsigned int delay ;
delay = maxseconds * fmod_samplerate ;
if ( delay > sfx - > samples )
delay = sfx - > samples ;
delay = maxseconds * 1000 ;
if ( delay > sfx - > length )
delay = sfx - > length ;
if ( delay > 0 )
if ( delay > 0 )
delay = rand ( ) % delay ;
delay = rand ( ) % delay ;
return delay ;
return delay * fmod_samplerate / 1000 ;
}
}
/*
/*
@ -285,8 +285,17 @@ void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f
FMOD_VectorCopy ( origin , position ) ;
FMOD_VectorCopy ( origin , position ) ;
FMOD_Channel_Set3DAttributes ( channel , & position , NULL ) ;
FMOD_Channel_Set3DAttributes ( channel , & position , NULL ) ;
FMOD_Channel_SetMode ( channel , FMOD_LOOP_OFF ) ; / / TODO : some entity sounds do need to loop , e . g . moving elevators . How is this done ?
FMOD_Channel_SetVolume ( channel , fvol ) ;
FMOD_Channel_SetVolume ( channel , fvol ) ;
if ( sfx - > loopstart > = 0 )
{
FMOD_Channel_SetMode ( channel , FMOD_LOOP_NORMAL ) ;
FMOD_Channel_SetLoopPoints ( channel , sfx - > loopstart , FMOD_TIMEUNIT_MS , sfx - > loopend , FMOD_TIMEUNIT_MS ) ;
}
else
{
FMOD_Channel_SetMode ( channel , FMOD_LOOP_OFF ) ;
}
/ / Anything coming from the view entity will always be full volume , and entchannel - 1 is used for local sounds ( e . g . menu sounds )
/ / Anything coming from the view entity will always be full volume , and entchannel - 1 is used for local sounds ( e . g . menu sounds )
if ( entchannel < 0 | | entnum = = cl . viewentity )
if ( entchannel < 0 | | entnum = = cl . viewentity )
@ -442,13 +451,13 @@ sfxcache_t *S_LoadSound(sfx_t *s)
{
{
char namebuffer [ 256 ] ;
char namebuffer [ 256 ] ;
byte * data ;
byte * data ;
int len , h ;
wavinfo_t info ;
FMOD_CREATESOUNDEXINFO exinfo ;
FMOD_CREATESOUNDEXINFO exinfo ;
FMOD_RESULT result ;
FMOD_RESULT result ;
# if _DEBUG
# if _DEBUG
FMOD_SOUND_TYPE type ;
FMOD_SOUND_TYPE type ;
FMOD_SOUND_FORMAT format ;
FMOD_SOUND_FORMAT format ;
int channels , bits , loopcount ;
int channels , bits ;
# endif
# endif
if ( ! fmod_system )
if ( ! fmod_system )
@ -461,11 +470,6 @@ sfxcache_t *S_LoadSound(sfx_t *s)
q_strlcpy ( namebuffer , " sound/ " , sizeof ( namebuffer ) ) ;
q_strlcpy ( namebuffer , " sound/ " , sizeof ( namebuffer ) ) ;
q_strlcat ( namebuffer , s - > name , sizeof ( namebuffer ) ) ;
q_strlcat ( namebuffer , s - > name , sizeof ( namebuffer ) ) ;
/ / We need to briefly open the file to figure out its length , which FMOD needs to know
len = COM_OpenFile ( namebuffer , & h , NULL ) ;
if ( h > = 0 )
COM_CloseFile ( h ) ;
data = COM_LoadHunkFile ( namebuffer , NULL ) ;
data = COM_LoadHunkFile ( namebuffer , NULL ) ;
if ( ! data )
if ( ! data )
{
{
@ -473,9 +477,16 @@ sfxcache_t *S_LoadSound(sfx_t *s)
return NULL ;
return NULL ;
}
}
info = GetWavinfo ( s - > name , data , com_filesize ) ;
if ( ! info . channels )
{
Con_Printf ( " Invalid WAV file: %s \n " , namebuffer ) ;
return NULL ;
}
memset ( & exinfo , 0 , sizeof ( FMOD_CREATESOUNDEXINFO ) ) ;
memset ( & exinfo , 0 , sizeof ( FMOD_CREATESOUNDEXINFO ) ) ;
exinfo . cbsize = sizeof ( FMOD_CREATESOUNDEXINFO ) ;
exinfo . cbsize = sizeof ( FMOD_CREATESOUNDEXINFO ) ;
exinfo . length = len ;
exinfo . length = com_filesize ;
result = FMOD_System_CreateSound ( fmod_system , ( const char * ) data , FMOD_3D | FMOD_OPENMEMORY , & exinfo , & s - > sound ) ;
result = FMOD_System_CreateSound ( fmod_system , ( const char * ) data , FMOD_3D | FMOD_OPENMEMORY , & exinfo , & s - > sound ) ;
if ( result ! = FMOD_OK )
if ( result ! = FMOD_OK )
@ -484,12 +495,21 @@ sfxcache_t *S_LoadSound(sfx_t *s)
return NULL ;
return NULL ;
}
}
FMOD_Sound_GetLength ( s - > sound , & s - > samples , FMOD_TIMEUNIT_PCM ) ;
/ / Collect data required for looping and delay
if ( info . loopstart > = 0 )
{
s - > loopstart = info . loopstart * 1000 / info . rate ;
s - > loopend = info . samples * 1000 / info . rate ;
}
else
{
s - > loopstart = s - > loopend = - 1 ;
}
FMOD_Sound_GetLength ( s - > sound , & s - > length , FMOD_TIMEUNIT_MS ) ;
# if _DEBUG
# if _DEBUG
FMOD_Sound_GetFormat ( s - > sound , & type , & format , & channels , & bits ) ;
FMOD_Sound_GetFormat ( s - > sound , & type , & format , & channels , & bits ) ;
FMOD_Sound_GetLoopCount ( s - > sound , & loopcount ) ;
Con_DPrintf ( " [FMOD] Loaded sound '%s': type %d, format %d, %d channel(s), %d bits, %d samples, loopcount = %d \n " , s - > name , type , format , channels , bits , s - > samples , loopcount ) ;
Con_DPrintf ( " [FMOD] Loaded sound '%s': type %d, format %d, %d channel(s), %d bits, %d ms, %d samples, loopstart = %d \n " , s - > name , type , format , channels , bits , s - > length , info . samples , s - > loopstart ) ;
# endif
# endif
return NULL ; / / Return value is unused ; FMOD has its own internal cache , we never need to use Quake ' s sfxcache_t
return NULL ; / / Return value is unused ; FMOD has its own internal cache , we never need to use Quake ' s sfxcache_t