diff --git a/engine/client/s_load.c b/engine/client/s_load.c index 8e3925f4..ac018434 100644 --- a/engine/client/s_load.c +++ b/engine/client/s_load.c @@ -107,17 +107,18 @@ S_CreateDefaultSound */ static wavdata_t *S_CreateDefaultSound( void ) { - wavdata_t *sc; + wavdata_t *sc; + uint samples = SOUND_DMA_SPEED; + uint channels = 1; + uint width = 2; + size_t size = samples * width * channels; - sc = Mem_Calloc( sndpool, sizeof( wavdata_t )); - - sc->width = 2; - sc->channels = 1; - sc->loopStart = 0; + sc = Mem_Calloc( sndpool, sizeof( wavdata_t ) + size ); + sc->width = width; + sc->channels = channels; sc->rate = SOUND_DMA_SPEED; - sc->samples = SOUND_DMA_SPEED; - sc->size = sc->samples * sc->width * sc->channels; - sc->buffer = Mem_Calloc( sndpool, sc->size ); + sc->samples = samples; + sc->size = size; return sc; } diff --git a/engine/client/s_stream.c b/engine/client/s_stream.c index 7f3e2973..e9f105ec 100644 --- a/engine/client/s_stream.c +++ b/engine/client/s_stream.c @@ -16,6 +16,7 @@ GNU General Public License for more details. #include "common.h" #include "sound.h" #include "client.h" +#include "soundlib.h" static bg_track_t s_bgTrack; static musicfade_t musicfade; // controlled by game dlls @@ -212,7 +213,7 @@ void S_StreamBackgroundTrack( void ) while( ch->s_rawend < soundtime + ch->max_samples ) { - wavdata_t *info = FS_StreamInfo( s_bgTrack.stream ); + const stream_t *info = s_bgTrack.stream; bufferSamples = ch->max_samples - (ch->s_rawend - soundtime); diff --git a/engine/client/soundlib/snd_main.c b/engine/client/soundlib/snd_main.c index 1304f39a..8553405f 100644 --- a/engine/client/soundlib/snd_main.c +++ b/engine/client/soundlib/snd_main.c @@ -29,17 +29,20 @@ static void Sound_Reset( void ) static MALLOC_LIKE( FS_FreeSound, 1 ) wavdata_t *SoundPack( void ) { - wavdata_t *pack = Mem_Calloc( host.soundpool, sizeof( wavdata_t )); + wavdata_t *pack = Mem_Malloc( host.soundpool, sizeof( *pack ) + sound.size ); - pack->buffer = sound.wav; - pack->width = sound.width; - pack->rate = sound.rate; - pack->type = sound.type; pack->size = sound.size; pack->loopStart = sound.loopstart; pack->samples = sound.samples; - pack->channels = sound.channels; + pack->type = sound.type; pack->flags = sound.flags; + pack->rate = sound.rate; + pack->width = sound.width; + pack->channels = sound.channels; + memcpy( pack->buffer, sound.wav, sound.size ); + + Mem_Free( sound.wav ); + sound.wav = NULL; return pack; } @@ -132,7 +135,6 @@ free WAV buffer void FS_FreeSound( wavdata_t *pack ) { if( !pack ) return; - if( pack->buffer ) Mem_Free( pack->buffer ); Mem_Free( pack ); } @@ -199,33 +201,6 @@ stream_t *FS_OpenStream( const char *filename ) return stream; } -/* -================ -FS_StreamInfo - -get basic stream info -================ -*/ -wavdata_t *FS_StreamInfo( stream_t *stream ) -{ - static wavdata_t info; - - if( !stream ) return NULL; - - // fill structure - info.loopStart = 0; - info.rate = stream->rate; - info.width = stream->width; - info.channels = stream->channels; - info.flags = SOUND_STREAM; - info.size = stream->size; - info.buffer = NULL; - info.samples = 0; // not actual for streams - info.type = stream->type; - - return &info; -} - /* ================ FS_ReadStream diff --git a/engine/common/common.h b/engine/common/common.h index 8447d348..92f2ad6b 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -514,15 +514,15 @@ typedef enum typedef struct { - word rate; // num samples per second (e.g. 11025 - 11 khz) - byte width; // resolution - bum bits divided by 8 (8 bit is 1, 16 bit is 2) - byte channels; // num channels (1 - mono, 2 - stereo) + size_t size; // for bounds checking uint loopStart; // offset at this point sound will be looping while playing more than only once uint samples; // total samplecount in wav uint type; // compression type uint flags; // misc sound flags - byte *buffer; // sound buffer - size_t size; // for bounds checking + word rate; // num samples per second (e.g. 11025 - 11 khz) + byte width; // resolution - bum bits divided by 8 (8 bit is 1, 16 bit is 2) + byte channels; // num channels (1 - mono, 2 - stereo) + byte buffer[]; // sound buffer } wavdata_t; // @@ -534,7 +534,6 @@ void FS_FreeSound( wavdata_t *pack ); void FS_FreeStream( stream_t *stream ); wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size ) MALLOC_LIKE( FS_FreeSound, 1 ) WARN_UNUSED_RESULT; stream_t *FS_OpenStream( const char *filename ) MALLOC_LIKE( FS_FreeStream, 1 ) WARN_UNUSED_RESULT; -wavdata_t *FS_StreamInfo( stream_t *stream ); int FS_ReadStream( stream_t *stream, int bytes, void *buffer ); int FS_SetStreamPos( stream_t *stream, int newpos ); int FS_GetStreamPos( stream_t *stream ); diff --git a/engine/common/soundlib/snd_utils.c b/engine/common/soundlib/snd_utils.c index be4eafbd..d9930ba9 100644 --- a/engine/common/soundlib/snd_utils.c +++ b/engine/common/soundlib/snd_utils.c @@ -89,16 +89,6 @@ void Sound_Shutdown( void ) Mem_FreePool( &host.soundpool ); } -static byte *Sound_Copy( size_t size ) -{ - byte *out; - - out = Mem_Realloc( host.soundpool, sound.tempbuffer, size ); - sound.tempbuffer = NULL; - - return out; -} - uint GAME_EXPORT Sound_GetApproxWavePlayLen( const char *filepath ) { string name; @@ -378,6 +368,7 @@ static qboolean Sound_ResampleInternal( wavdata_t *sc, int outrate, int outwidth const int inwidth = sc->width; const int inchannels = sc->channels; const int incount = sc->samples; + const int insize = sc->size; qboolean handled = false; double stepscale; double t1, t2; @@ -431,22 +422,30 @@ static qboolean Sound_ResampleInternal( wavdata_t *sc, int outrate, int outwidth else // upsample case, w/ interpolation handled = Sound_ConvertUpsample( sc, inwidth, inchannels, incount, outwidth, outchannels, outcount, stepscale ); - t2 = Sys_DoubleTime(); - - if( handled ) + if( !handled ) { - if( t2 - t1 > 0.01f ) // critical, report to mod developer - Con_Printf( S_WARN "%s: from [%d bit %d Hz %dch] to [%d bit %d Hz %dch] (took %.3fs)\n", __func__, inwidth * 8, inrate, inchannels, outwidth * 8, outrate, outchannels, t2 - t1 ); - else - Con_Reportf( "%s: from [%d bit %d Hz %dch] to [%d bit %d Hz %dch] (took %.3fs)\n", __func__, inwidth * 8, inrate, inchannels, outwidth * 8, outrate, outchannels, t2 - t1 ); - } - else + // restore previously changed data + sc->rate = inrate; + sc->width = inwidth; + sc->channels = inchannels; + sc->samples = incount; + sc->size = insize; + Con_Printf( S_ERROR "%s: unsupported from [%d bit %d Hz %dch] to [%d bit %d Hz %dch]\n", __func__, inwidth * 8, inrate, inchannels, outwidth * 8, outrate, outchannels ); + return false; + } + + t2 = Sys_DoubleTime(); sc->rate = outrate; sc->width = outwidth; - return handled; + if( t2 - t1 > 0.01f ) // critical, report to mod developer + Con_Printf( S_WARN "%s: from [%d bit %d Hz %dch] to [%d bit %d Hz %dch] (took %.3fs)\n", __func__, inwidth * 8, inrate, inchannels, outwidth * 8, outrate, outchannels, t2 - t1 ); + else + Con_Reportf( "%s: from [%d bit %d Hz %dch] to [%d bit %d Hz %dch] (took %.3fs)\n", __func__, inwidth * 8, inrate, inchannels, outwidth * 8, outrate, outchannels, t2 - t1 ); + + return true; } qboolean Sound_Process( wavdata_t **wav, int rate, int width, int channels, uint flags ) @@ -464,8 +463,11 @@ qboolean Sound_Process( wavdata_t **wav, int rate, int width, int channels, uint if( result ) { - Mem_Free( snd->buffer ); // free original image buffer - snd->buffer = Sound_Copy( snd->size ); // unzone buffer + snd = Mem_Realloc( host.soundpool, snd, sizeof( *snd ) + snd->size ); + memcpy( snd->buffer, sound.tempbuffer, snd->size ); + + Mem_Free( sound.tempbuffer ); + sound.tempbuffer = NULL; } }