X-Git-Url: http://git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=snd_wav.c;h=d23a8b5126487ca3b01196c8c5c17ffc61492565;hp=438db2ba8a0a95a189b5ac66f23b883c0496b453;hb=73f27d62983b6af1cb9a6971d0a4cb6275b91a07;hpb=775c4993063d7673903a2dfaebeacd1a9c71cbf7 diff --git a/snd_wav.c b/snd_wav.c index 438db2ba..d23a8b51 100644 --- a/snd_wav.c +++ b/snd_wav.c @@ -22,10 +22,10 @@ */ -#include "quakedef.h" +#include "darkplaces.h" #include "snd_main.h" #include "snd_wav.h" - +#include "sound.h" typedef struct wavinfo_s { @@ -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,25 +251,13 @@ static const snd_buffer_t* WAV_FetchSound (void *sfxfetcher, void **chfetcherpoi WAV_FreeSfx ==================== */ -static void WAV_FreeSfx (void *sfxfetcherdata) -{ - snd_buffer_t* sb = (snd_buffer_t *)sfxfetcherdata; - // Free the sound buffer - Mem_Free(sb); -} - -/* -==================== -WAV_GetFormat -==================== -*/ -static const snd_format_t* WAV_GetFormat (sfx_t* sfx) +static void WAV_FreeSfx(sfx_t *sfx) { - snd_buffer_t* sb = (snd_buffer_t *)sfx->fetcher_data; - return &sb->format; + // free the loaded sound data + Mem_Free(sfx->fetcher_data); } -const snd_fetcher_t wav_fetcher = { WAV_FetchSound, NULL, WAV_FreeSfx, WAV_GetFormat }; +const snd_fetcher_t wav_fetcher = { WAV_GetSamplesFloat, NULL, WAV_FreeSfx }; /* @@ -260,13 +265,14 @@ const snd_fetcher_t wav_fetcher = { WAV_FetchSound, NULL, WAV_FreeSfx, WAV_GetFo S_LoadWavFile ============== */ -qboolean S_LoadWavFile (const char *filename, sfx_t *sfx) +qbool 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) @@ -297,41 +303,47 @@ qboolean S_LoadWavFile (const char *filename, sfx_t *sfx) //if (info.channels == 2) // Log_Printf("stereosounds.log", "%s\n", sfx->name); - // We must convert the WAV data from little endian - // to the machine endianess before resampling it - if (info.width == 2 && mem_bigendian) + 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); + } } - - 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 = (unsigned int) ((double)info.loopstart * (double)sb->format.speed / (double)info.rate); + sfx->loopstart = info.loopstart; sfx->loopstart = min(sfx->loopstart, sfx->total_length); sfx->flags &= ~SFXFLAG_STREAMED; - Mem_Free (data); + Mem_Free(data); // we already got a copy of this in fetcher_data return true; }