]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - snd_wav.c
cleaned up the fix for solid water in q1bsp dedicated servers
[xonotic/darkplaces.git] / snd_wav.c
index 89bd6c6e4cd9f5ba45406507929aa235c883345d..b55c36653358524b8dd636f341323c92dfeb41a8 100644 (file)
--- a/snd_wav.c
+++ b/snd_wav.c
@@ -65,7 +65,7 @@ static int GetLittleLong(void)
        return val;
 }
 
-static void FindNextChunk(char *name)
+static void FindNextChunk(const char *name)
 {
        while (1)
        {
@@ -84,6 +84,12 @@ static void FindNextChunk(char *name)
                        data_p = NULL;
                        return;
                }
+               if (data_p + iff_chunk_len > iff_end)
+               {
+                       // truncated chunk!
+                       data_p = NULL;
+                       return;
+               }
                data_p -= 8;
                last_chunk = data_p + 8 + ( (iff_chunk_len + 1) & ~1 );
                if (!strncmp((const char *)data_p, name, 4))
@@ -91,7 +97,7 @@ static void FindNextChunk(char *name)
        }
 }
 
-static void FindChunk(char *name)
+static void FindChunk(const char *name)
 {
        last_chunk = iff_data;
        FindNextChunk (name);
@@ -223,9 +229,10 @@ static wavinfo_t GetWavinfo (char *name, unsigned char *wav, int wavlength)
 WAV_FetchSound
 ====================
 */
-static const sfxbuffer_t* WAV_FetchSound (channel_t* ch, unsigned int start, unsigned int nbsamples)
+static const snd_buffer_t* WAV_FetchSound (void *sfxfetcher, void **chfetcherpointer, unsigned int *start, unsigned int nbsampleframes)
 {
-       return (sfxbuffer_t *)ch->sfx->fetcher_data;
+       *start = 0;
+       return (snd_buffer_t *)sfxfetcher;
 }
 
 /*
@@ -233,19 +240,25 @@ static const sfxbuffer_t* WAV_FetchSound (channel_t* ch, unsigned int start, uns
 WAV_FreeSfx
 ====================
 */
-static void WAV_FreeSfx (sfx_t* sfx)
+static void WAV_FreeSfx (void *sfxfetcherdata)
 {
-       sfxbuffer_t* sb = (sfxbuffer_t *)sfx->fetcher_data;
-
+       snd_buffer_t* sb = (snd_buffer_t *)sfxfetcherdata;
        // Free the sound buffer
-       sfx->memsize -= (sb->length * sfx->format.channels * sfx->format.width) + sizeof (*sb) - sizeof (sb->data);
        Mem_Free(sb);
+}
 
-       sfx->fetcher_data = NULL;
-       sfx->fetcher = NULL;
+/*
+====================
+WAV_GetFormat
+====================
+*/
+static const snd_format_t* WAV_GetFormat (sfx_t* sfx)
+{
+       snd_buffer_t* sb = (snd_buffer_t *)sfx->fetcher_data;
+       return &sb->format;
 }
 
-const snd_fetcher_t wav_fetcher = { WAV_FetchSound, NULL, WAV_FreeSfx };
+const snd_fetcher_t wav_fetcher = { WAV_FetchSound, NULL, WAV_FreeSfx, WAV_GetFormat };
 
 
 /*
@@ -253,17 +266,16 @@ const snd_fetcher_t wav_fetcher = { WAV_FetchSound, NULL, WAV_FreeSfx };
 S_LoadWavFile
 ==============
 */
-qboolean S_LoadWavFile (const char *filename, sfx_t *s)
+qboolean S_LoadWavFile (const char *filename, sfx_t *sfx)
 {
        fs_offset_t filesize;
        unsigned char *data;
        wavinfo_t info;
-       int len;
-       size_t memsize;
-       sfxbuffer_t* sb;
+       snd_format_t wav_format;
+       snd_buffer_t* sb;
 
        // Already loaded?
-       if (s->fetcher != NULL)
+       if (sfx->fetcher != NULL)
                return true;
 
        // Load the file
@@ -278,50 +290,24 @@ qboolean S_LoadWavFile (const char *filename, sfx_t *s)
                return false;
        }
 
-       Con_DPrintf ("Loading WAV file \"%s\"\n", filename);
+       if (developer_loading.integer >= 2)
+               Con_Printf ("Loading WAV file \"%s\"\n", filename);
 
-       info = GetWavinfo (s->name, data, (int)filesize);
-       // Stereo sounds are allowed (intended for music)
-       if (info.channels < 1 || info.channels > 2)
+       info = GetWavinfo (sfx->name, data, (int)filesize);
+       if (info.channels < 1 || info.channels > 2)  // Stereo sounds are allowed (intended for music)
        {
-               Con_Printf("%s has an unsupported number of channels (%i)\n",s->name, info.channels);
+               Con_Printf("%s has an unsupported number of channels (%i)\n",sfx->name, info.channels);
                Mem_Free(data);
                return false;
        }
        //if (info.channels == 2)
-       //      Log_Printf("stereosounds.log", "%s\n", s->name);
-
-       // calculate resampled length
-       len = (int) ((double) info.samples * (double) shm->format.speed / (double) info.rate);
-       len = len * info.width * info.channels;
-
-       memsize = len + sizeof (*sb) - sizeof (sb->data);
-       sb = (sfxbuffer_t *)Mem_Alloc (snd_mempool, memsize);
-       if (sb == NULL)
-       {
-               Con_Printf("failed to allocate memory for sound \"%s\"\n", s->name);
-               Mem_Free(data);
-               return false;
-       }
-       s->memsize += memsize;
-
-       s->fetcher = &wav_fetcher;
-       s->fetcher_data = sb;
-       s->format.speed = info.rate;
-       s->format.width = info.width;
-       s->format.channels = info.channels;
-       if (info.loopstart < 0)
-               s->loopstart = -1;
-       else
-               s->loopstart = (int)((double)info.loopstart * (double)shm->format.speed / (double)s->format.speed);
-       s->flags &= ~SFXFLAG_STREAMED;
+       //      Log_Printf("stereosounds.log", "%s\n", sfx->name);
 
-#if BYTE_ORDER != LITTLE_ENDIAN
        // We must convert the WAV data from little endian
        // to the machine endianess before resampling it
-       if (info.width == 2)
+       if (info.width == 2 && mem_bigendian)
        {
-               int i;
+               unsigned int len, i;
                short* ptr;
 
                len = info.samples * info.channels;
@@ -329,12 +315,28 @@ qboolean S_LoadWavFile (const char *filename, sfx_t *s)
                for (i = 0; i < len; i++)
                        ptr[i] = LittleShort (ptr[i]);
        }
-#endif
 
-       sb->length = (int)ResampleSfx (data + info.dataofs, info.samples, &s->format, sb->data, s->name);
-       s->format.speed = shm->format.speed;
-       s->total_length = sb->length;
-       sb->offset = 0;
+       wav_format.speed = info.rate;
+       wav_format.width = info.width;
+       wav_format.channels = info.channels;
+       sb = Snd_CreateSndBuffer (data + info.dataofs, info.samples, &wav_format, snd_renderbuffer->format.speed);
+       if (sb == NULL)
+       {
+               Mem_Free(data);
+               return false;
+       }
+       sfx->fetcher = &wav_fetcher;
+       sfx->fetcher_data = sb;
+
+       sfx->total_length = sb->nbframes;
+       sfx->memsize += sb->maxframes * sb->format.channels * sb->format.width + sizeof (*sb) - sizeof (sb->samples);
+
+       if (info.loopstart < 0)
+               sfx->loopstart = sfx->total_length;
+       else
+               sfx->loopstart = (unsigned int) ((double)info.loopstart * (double)sb->format.speed / (double)info.rate);
+       sfx->loopstart = min(sfx->loopstart, sfx->total_length);
+       sfx->flags &= ~SFXFLAG_STREAMED;
 
        Mem_Free (data);
        return true;