diff --git a/include/snd_internal.h b/include/snd_internal.h index ace403c75..352138114 100644 --- a/include/snd_internal.h +++ b/include/snd_internal.h @@ -164,7 +164,7 @@ struct sfxbuffer_s { /** Sample data. The block at the beginning of the buffer (size depends on sample size) */ - float data[1]; + float data[]; }; /** Representation of sound loaded that is streamed in as needed. @@ -271,8 +271,8 @@ void SND_Memory_FreeBuffer (sfxbuffer_t *buffer); \param info \param loader */ -void SND_SFX_Cache (sfx_t *sfx, char *realname, wavinfo_t info, - cache_loader_t loader); +void SND_SFX_Block (sfx_t *sfx, char *realname, wavinfo_t info, + sfxbuffer_t *(*load) (sfxblock_t *block)); /** Stream sound data. Initializes streaming fields of sfx. \param sfx @@ -455,9 +455,9 @@ void SND_PaintChannels(snd_t *snd, unsigned int endtime); void SND_InitScaletable (snd_t *snd); /** Set the paint function of the sfxbuffer - \param sc sfxbuffer to set. + \param sb sfxbuffer to set. */ -void SND_SetPaint (sfxbuffer_t *sc); +void SND_SetPaint (sfxbuffer_t *sb); ///@} @@ -465,11 +465,14 @@ void SND_SetPaint (sfxbuffer_t *sc); \ingroup sound_render */ ///@{ + +unsigned SND_ResamplerFrames (sfx_t *sfx); + /** Set up the various parameters that depend on the actual sample rate. - \param sc buffer to setup + \param sb buffer to setup \param streamed non-zero if this is for a stream. */ -void SND_SetupResampler (sfxbuffer_t *sc, int streamed); +void SND_SetupResampler (sfxbuffer_t *sb, int streamed); /** Free memory allocated for the resampler. \param stream stream to pulldown @@ -477,11 +480,11 @@ void SND_SetupResampler (sfxbuffer_t *sc, int streamed); void SND_PulldownResampler (sfxstream_t *stream); /** Copy/resample data into buffer, resampling as necessary. - \param sc buffer to write resampled sound + \param sb buffer to write resampled sound \param data raw sample data \param length number of frames to resample */ -void SND_Resample (sfxbuffer_t *sc, float *data, int length); +void SND_Resample (sfxbuffer_t *sb, float *data, int length); /** Convert integer sample data to float sample data. \param idata integer data buffer @@ -612,17 +615,6 @@ int SND_StreamAdvance (sfxbuffer_t *buffer, unsigned int count); \param pos sample position with the stream */ void SND_StreamSetPos (sfxbuffer_t *buffer, unsigned int pos); - -/** Allocate a sound buffer from cache for cached sounds. - \param samples size in samples - \param rate sample rate - \param channels number of channels in input data - \param block cached sound descriptor to initialize - \param allocator cache allocator function - \return pointer to sound sample buffer (setup for block mode) -*/ -sfxbuffer_t *SND_GetCache (long samples, int rate, int channels, - sfxblock_t *block, cache_allocator_t allocator); ///@} #endif//__snd_internal_h diff --git a/libs/audio/renderer/flac.c b/libs/audio/renderer/flac.c index 53956e451..9868d12cd 100644 --- a/libs/audio/renderer/flac.c +++ b/libs/audio/renderer/flac.c @@ -279,7 +279,7 @@ flac_read (flacfile_t *ff, float *buf, int len) } static sfxbuffer_t * -flac_load (flacfile_t *ff, sfxblock_t *block, cache_allocator_t allocator) +flac_load (flacfile_t *ff, sfxblock_t *block) { float *data; sfxbuffer_t *sb = 0; @@ -289,10 +289,11 @@ flac_load (flacfile_t *ff, sfxblock_t *block, cache_allocator_t allocator) data = malloc (info->datalen); if (!data) goto bail; - sb = SND_GetCache (info->frames, info->rate, info->channels, - block, allocator); + unsigned buffer_frames = SND_ResamplerFrames (sfx); + sb = SND_Memory_AllocBuffer (buffer_frames * info->channels); if (!sb) goto bail; + sb->size = buffer_frames * info->channels; sb->sfx = sfx; if (flac_read (ff, data, info->frames) < 0) goto bail; @@ -307,31 +308,29 @@ flac_load (flacfile_t *ff, sfxblock_t *block, cache_allocator_t allocator) return sb; } -static void -flac_callback_load (void *object, cache_allocator_t allocator) +static sfxbuffer_t * +flac_callback_load (sfxblock_t *block) { QFile *file; flacfile_t *ff; - sfxblock_t *block = (sfxblock_t *) object; - file = QFS_FOpenFile (block->file); if (!file) - return; //FIXME Sys_Error? + return 0; if (!(ff = flac_open (file))) { Sys_Printf ("Input does not appear to be an Ogg bitstream.\n"); Qclose (file); - return; //FIXME Sys_Error? + return 0; } - flac_load (ff, block, allocator); + return flac_load (ff, block); } static void flac_cache (sfx_t *sfx, char *realname, flacfile_t *ff, wavinfo_t info) { flac_close (ff); - SND_SFX_Cache (sfx, realname, info, flac_callback_load); + SND_SFX_Block (sfx, realname, info, flac_callback_load); } static long diff --git a/libs/audio/renderer/snd_channels.c b/libs/audio/renderer/snd_channels.c index b41f30ae2..8b56415ff 100644 --- a/libs/audio/renderer/snd_channels.c +++ b/libs/audio/renderer/snd_channels.c @@ -287,7 +287,6 @@ s_play_f (void *_snd) dsprintf (name, "%s", Cmd_Argv (i)); } sfx = SND_PrecacheSound (snd, name->str); - printf ("%s %p\n", name->str, sfx); SND_StartSound (snd, hash++, 0, sfx, listener_origin, 1.0, 1.0); i++; } diff --git a/libs/audio/renderer/snd_mem.c b/libs/audio/renderer/snd_mem.c index d9715a9f8..4d4c5f2f4 100644 --- a/libs/audio/renderer/snd_mem.c +++ b/libs/audio/renderer/snd_mem.c @@ -115,7 +115,7 @@ SND_Memory_AllocBuffer (unsigned samples) // +4 for sentinel sfxbuffer_t *buffer = Z_TagMalloc (snd_zone, size + 4, 1); // place a sentinel at the end of the buffer for added safety - memcpy ((byte *) buffer->data + size, "\xde\xad\xbe\xef", 4); + memcpy (&buffer->data[samples], "\xde\xad\xbe\xef", 4); // clear buffer header memset (buffer, 0, sizeof (sfxbuffer_t)); return buffer; @@ -153,7 +153,7 @@ snd_open_fail (sfx_t *sfx) sfxbuffer_t * SND_CacheTouch (sfx_t *sfx) { - return Cache_Check (&sfx->data.block->cache); + return sfx->data.block->buffer; } sfxbuffer_t * @@ -165,29 +165,12 @@ SND_CacheGetBuffer (sfx_t *sfx) sfxbuffer_t * SND_CacheRetain (sfx_t *sfx) { - sfxblock_t *block = sfx->data.block; - block->buffer = Cache_TryGet (&block->cache); - if (!block->buffer) - Sys_Printf ("failed to cache sound!\n"); - return block->buffer; + return sfx->data.block->buffer; } void SND_CacheRelease (sfx_t *sfx) { - sfxblock_t *block = sfx->data.block; - // due to the possibly asynchronous nature of the mixer, the cache - // may have been flushed behind our backs - if (block->cache.data) { - if (!Cache_ReadLock (&block->cache)) { - Sys_Printf ("WARNING: taniwha screwed up in the sound engine: %s\n", - sfx->name); - return; - } - Cache_Release (&block->cache); - if (!Cache_ReadLock (&block->cache)) - block->buffer = 0; - } } sfxbuffer_t * @@ -420,25 +403,3 @@ bail: free (realname); return -1; } - -sfxbuffer_t * -SND_GetCache (long frames, int rate, int channels, - sfxblock_t *block, cache_allocator_t allocator) -{ - int len, size; - float stepscale; - sfxbuffer_t *sb; - sfx_t *sfx = block->sfx; - snd_t *snd = sfx->snd; - - stepscale = (float) rate / snd->speed; - len = size = frames / stepscale; - size *= sizeof (float) * channels; - sb = allocator (&block->cache, sizeof (sfxbuffer_t) + size, sfx->name); - if (!sb) - return 0; - memset (sb, 0, sizeof (sfxbuffer_t) + size); - sb->size = len; - memcpy (sb->data + len * channels, "\xde\xad\xbe\xef", 4); - return sb; -} diff --git a/libs/audio/renderer/snd_resample.c b/libs/audio/renderer/snd_resample.c index c243df764..97f4acbc4 100644 --- a/libs/audio/renderer/snd_resample.c +++ b/libs/audio/renderer/snd_resample.c @@ -62,6 +62,16 @@ check_buffer_integrity (sfxbuffer_t *sb, int width, const char *func) x[0], x[1], x[2], x[3]); } +unsigned +SND_ResamplerFrames (sfx_t *sfx) +{ + wavinfo_t *info = sfx->wavinfo (sfx); + snd_t *snd = sfx->snd; + int inrate = info->rate; + double stepscale = (double) snd->speed / inrate; + return info->frames * stepscale; +} + void SND_Resample (sfxbuffer_t *sb, float *data, int length) { diff --git a/libs/audio/renderer/snd_sfx.c b/libs/audio/renderer/snd_sfx.c index 3b63fde76..b801a94a0 100644 --- a/libs/audio/renderer/snd_sfx.c +++ b/libs/audio/renderer/snd_sfx.c @@ -79,8 +79,8 @@ snd_sfx_free (void *_sfx, void *unused) } void -SND_SFX_Cache (sfx_t *sfx, char *realname, wavinfo_t info, - cache_loader_t loader) +SND_SFX_Block (sfx_t *sfx, char *realname, wavinfo_t info, + sfxbuffer_t *(*load) (sfxblock_t *block)) { sfxblock_t *block = calloc (1, sizeof (sfxblock_t)); @@ -94,8 +94,7 @@ SND_SFX_Cache (sfx_t *sfx, char *realname, wavinfo_t info, block->sfx = sfx; block->file = realname; block->wavinfo = info; - - Cache_Add (&block->cache, block, loader); + block->buffer = load (block); } void diff --git a/libs/audio/renderer/vorbis.c b/libs/audio/renderer/vorbis.c index 2d1060e02..8c51660df 100644 --- a/libs/audio/renderer/vorbis.c +++ b/libs/audio/renderer/vorbis.c @@ -160,7 +160,7 @@ vorbis_read (OggVorbis_File *vf, float *buf, int len, wavinfo_t *info) } static sfxbuffer_t * -vorbis_load (OggVorbis_File *vf, sfxblock_t *block, cache_allocator_t allocator) +vorbis_load (OggVorbis_File *vf, sfxblock_t *block) { float *data; sfxbuffer_t *sb = 0; @@ -170,10 +170,11 @@ vorbis_load (OggVorbis_File *vf, sfxblock_t *block, cache_allocator_t allocator) data = malloc (info->datalen); if (!data) goto bail; - sb = SND_GetCache (info->frames, info->rate, info->channels, - block, allocator); + unsigned buffer_frames = SND_ResamplerFrames (sfx); + sb = SND_Memory_AllocBuffer (buffer_frames * info->channels); if (!sb) goto bail; + sb->size = buffer_frames * info->channels; sb->sfx = sfx; if (vorbis_read (vf, data, info->frames, info) < 0) goto bail; @@ -188,31 +189,29 @@ vorbis_load (OggVorbis_File *vf, sfxblock_t *block, cache_allocator_t allocator) return sb; } -static void -vorbis_callback_load (void *object, cache_allocator_t allocator) +static sfxbuffer_t * +vorbis_callback_load (sfxblock_t *block) { QFile *file; OggVorbis_File vf; - sfxblock_t *block = (sfxblock_t *) object; - file = QFS_FOpenFile (block->file); if (!file) - return; //FIXME Sys_Error? + return 0; if (ov_open_callbacks (file, &vf, 0, 0, callbacks) < 0) { Sys_Printf ("Input does not appear to be an Ogg bitstream.\n"); Qclose (file); - return; //FIXME Sys_Error? + return 0; } - vorbis_load (&vf, block, allocator); + return vorbis_load (&vf, block); } static void vorbis_cache (sfx_t *sfx, char *realname, OggVorbis_File *vf, wavinfo_t info) { ov_clear (vf); - SND_SFX_Cache (sfx, realname, info, vorbis_callback_load); + SND_SFX_Block (sfx, realname, info, vorbis_callback_load); } static long diff --git a/libs/audio/renderer/wav.c b/libs/audio/renderer/wav.c index 59379f295..fd27b2af7 100644 --- a/libs/audio/renderer/wav.c +++ b/libs/audio/renderer/wav.c @@ -54,10 +54,9 @@ typedef struct { QFile *file; } wav_file_t; -static void -wav_callback_load (void *object, cache_allocator_t allocator) +static sfxbuffer_t * +wav_callback_load (sfxblock_t *block) { - sfxblock_t *block = (sfxblock_t *) object; sfx_t *sfx = block->sfx; const char *name = (const char *) block->file; QFile *file; @@ -69,7 +68,7 @@ wav_callback_load (void *object, cache_allocator_t allocator) file = QFS_FOpenFile (name); if (!file) - return; //FIXME Sys_Error? + return 0; Qseek (file, info->dataofs, SEEK_SET); fdata_ofs = (info->datalen + sizeof (float) - 1) & ~(sizeof (float) - 1); @@ -81,21 +80,23 @@ wav_callback_load (void *object, cache_allocator_t allocator) SND_Convert (data, fdata, info->frames, info->channels, info->width); - buffer = SND_GetCache (info->frames, info->rate, - info->channels, block, allocator); + unsigned buffer_frames = SND_ResamplerFrames (sfx); + buffer = SND_Memory_AllocBuffer (buffer_frames * info->channels); + buffer->size = buffer_frames * info->channels; buffer->sfx = sfx; SND_SetPaint (buffer); SND_SetupResampler (buffer, 0); SND_Resample (buffer, fdata, info->frames); buffer->head = buffer->size; free (data); + return buffer; } static void wav_cache (sfx_t *sfx, char *realname, void *file, wavinfo_t info) { Qclose (file); - SND_SFX_Cache (sfx, realname, info, wav_callback_load); + SND_SFX_Block (sfx, realname, info, wav_callback_load); } static long