]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - snd_wav.c
Add GL_ExtensionSupported in vid_null.c because vid_shared.c relies on
[xonotic/darkplaces.git] / snd_wav.c
index 8495518e3cdce82898e20535168a360b6193b044..6f861913335007bb2f155a68aa5b672c16cdaaee 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);
@@ -220,13 +226,24 @@ static wavinfo_t GetWavinfo (char *name, unsigned char *wav, int wavlength)
 
 /*
 ====================
-WAV_FetchSound
+WAV_GetSamplesFloat
 ====================
 */
-static const snd_buffer_t* WAV_FetchSound (void *sfxfetcher, void **chfetcherpointer, unsigned int *start, unsigned int nbsampleframes)
+static void WAV_GetSamplesFloat(channel_t *ch, sfx_t *sfx, int firstsampleframe, int numsampleframes, float *outsamplesfloat)
 {
-       *start = 0;
-       return (snd_buffer_t *)sfxfetcher;
+       int i, len = numsampleframes * sfx->format.channels;
+       if (sfx->format.width == 2)
+       {
+               const short *bufs = (const short *)sfx->fetcher_data + firstsampleframe * sfx->format.channels;
+               for (i = 0;i < len;i++)
+                       outsamplesfloat[i] = bufs[i] * (1.0f / 32768.0f);
+       }
+       else
+       {
+               const signed char *bufb = (const signed char *)sfx->fetcher_data + firstsampleframe * sfx->format.channels;
+               for (i = 0;i < len;i++)
+                       outsamplesfloat[i] = bufb[i] * (1.0f / 128.0f);
+       }
 }
 
 /*
@@ -234,30 +251,13 @@ static const snd_buffer_t* WAV_FetchSound (void *sfxfetcher, void **chfetcherpoi
 WAV_FreeSfx
 ====================
 */
-static void WAV_FreeSfx (sfx_t* sfx)
+static void WAV_FreeSfx(sfx_t *sfx)
 {
-       snd_buffer_t* sb = (snd_buffer_t *)sfx->fetcher_data;
-
-       // Free the sound buffer
-       sfx->memsize -= (sb->maxframes * sb->format.channels * sb->format.width) + sizeof (*sb) - sizeof (sb->samples);
-       Mem_Free(sb);
-
-       sfx->fetcher_data = NULL;
-       sfx->fetcher = NULL;
+       // free the loaded sound data
+       Mem_Free(sfx->fetcher_data);
 }
 
-/*
-====================
-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, WAV_GetFormat };
+const snd_fetcher_t wav_fetcher = { WAV_GetSamplesFloat, NULL, WAV_FreeSfx };
 
 
 /*
@@ -270,8 +270,9 @@ qboolean S_LoadWavFile (const char *filename, sfx_t *sfx)
        fs_offset_t filesize;
        unsigned char *data;
        wavinfo_t info;
-       snd_format_t wav_format;
-       snd_buffer_t* sb;
+       int i, len;
+       const unsigned char *inb;
+       unsigned char *outb;
 
        // Already loaded?
        if (sfx->fetcher != NULL)
@@ -289,7 +290,8 @@ qboolean S_LoadWavFile (const char *filename, sfx_t *sfx)
                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 (sfx->name, data, (int)filesize);
        if (info.channels < 1 || info.channels > 2)  // Stereo sounds are allowed (intended for music)
@@ -301,43 +303,46 @@ qboolean S_LoadWavFile (const char *filename, sfx_t *sfx)
        //if (info.channels == 2)
        //      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
+       sfx->format.speed = info.rate;
+       sfx->format.width = info.width;
+       sfx->format.channels = info.channels;
+       sfx->fetcher = &wav_fetcher;
+       sfx->fetcher_data = Mem_Alloc(snd_mempool, info.samples * sfx->format.width * sfx->format.channels);
+       sfx->total_length = info.samples;
+       sfx->memsize += filesize;
+       len = info.samples * sfx->format.channels * sfx->format.width;
+       inb = data + info.dataofs;
+       outb = (unsigned char *)sfx->fetcher_data;
        if (info.width == 2)
        {
-               unsigned int len, i;
-               short* ptr;
-
-               len = info.samples * info.channels;
-               ptr = (short*)(data + info.dataofs);
-               for (i = 0; i < len; i++)
-                       ptr[i] = LittleShort (ptr[i]);
+               if (mem_bigendian)
+               {
+                       // we have to byteswap the data at load (better than doing it while mixing)
+                       for (i = 0;i < len;i += 2)
+                       {
+                               outb[i] = inb[i+1];
+                               outb[i+1] = inb[i];
+                       }
+               }
+               else
+               {
+                       // we can just copy it straight
+                       memcpy(outb, inb, len);
+               }
        }
-#endif
-
-       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)
+       else
        {
-               Mem_Free(data);
-               return false;
+               // convert unsigned byte sound data to signed bytes for quicker mixing
+               for (i = 0;i < len;i++)
+                       outb[i] = inb[i] - 0x80;
        }
-       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 = (double)info.loopstart * (double)snd_renderbuffer->format.speed / (double)sb->format.speed;
+               sfx->loopstart = info.loopstart;
        sfx->loopstart = min(sfx->loopstart, sfx->total_length);
        sfx->flags &= ~SFXFLAG_STREAMED;
 
-       Mem_Free (data);
        return true;
 }