return val;
}
-static void FindNextChunk(char *name)
+static void FindNextChunk(const char *name)
{
while (1)
{
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))
}
}
-static void FindChunk(char *name)
+static void FindChunk(const char *name)
{
last_chunk = iff_data;
FindNextChunk (name);
/*
====================
-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);
+ }
}
/*
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 };
/*
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)
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)
//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;
}