Add support for 16-bit WAV sound lumps (#122)

* Add support for 16-bit WAV sound lumps

* Fix gcc build

* Made SOUNDHDRSIZE a variable

* Initialize SOUNDHDRSIZE
This commit is contained in:
Roman Fomin 2021-02-10 14:32:02 +07:00 committed by GitHub
parent 05aa665373
commit 212eb16c91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -133,7 +133,7 @@ static void stopchan(int handle)
channelinfo[handle].id = NULL;
}
#define SOUNDHDRSIZE 8
static int SOUNDHDRSIZE = 8;
//
// addsfx
@ -153,6 +153,7 @@ static boolean addsfx(sfxinfo_t *sfx, int channel, int pitch)
int lump;
// [FG] do not connect pitch-shifted samples to a sound SFX
unsigned int sfx_alen;
unsigned int bits;
void *sfx_data;
#ifdef RANGECHECK
@ -186,22 +187,66 @@ static boolean addsfx(sfxinfo_t *sfx, int channel, int pitch)
if(sfx->data == NULL || pitch != NORM_PITCH)
{
byte *data;
Uint32 samplerate, samplelen;
Uint32 samplerate, samplelen, samplecount;
// haleyjd: this should always be called (if lump is already loaded,
// W_CacheLumpNum handles that for us).
data = (byte *)W_CacheLumpNum(lump, PU_STATIC);
// [crispy] Check if this is a valid RIFF wav file
if (lumplen > 44 && memcmp(data, "RIFF", 4) == 0 && memcmp(data + 8, "WAVEfmt ", 8) == 0)
{
// Valid RIFF wav file
int check;
// Make sure this is a PCM format file
// "fmt " chunk size must == 16
check = data[16] | (data[17] << 8) | (data[18] << 16) | (data[19] << 24);
if (check != 16)
return false;
// Format must == 1 (PCM)
check = data[20] | (data[21] << 8);
if (check != 1)
return false;
// FIXME: can't handle stereo wavs
// Number of channels must == 1
check = data[22] | (data[23] << 8);
if (check != 1)
return false;
samplerate = data[24] | (data[25] << 8) | (data[26] << 16) | (data[27] << 24);
samplelen = data[40] | (data[41] << 8) | (data[42] << 16) | (data[43] << 24);
if (samplelen > lumplen - 44)
samplelen = lumplen - 44;
bits = data[34] | (data[35] << 8);
// Reject non 8 or 16 bit
if (bits != 16 && bits != 8)
return false;
SOUNDHDRSIZE = 44;
}
// Check the header, and ensure this is a valid sound
if(data[0] != 0x03 || data[1] != 0x00)
else if(data[0] == 0x03 || data[1] == 0x00)
{
samplerate = (data[3] << 8) | data[2];
samplelen = (data[7] << 24) | (data[6] << 16) | (data[5] << 8) | data[4];
// All Doom sounds are 8-bit
bits = 8;
SOUNDHDRSIZE = 8;
}
else
{
Z_ChangeTag(data, PU_CACHE);
return false;
}
samplerate = (data[3] << 8) | data[2];
samplelen = (data[7] << 24) | (data[6] << 16) | (data[5] << 8) | data[4];
// don't play sounds that think they're longer than they really are
if(samplelen > lumplen - SOUNDHDRSIZE)
{
@ -209,10 +254,12 @@ static boolean addsfx(sfxinfo_t *sfx, int channel, int pitch)
return false;
}
samplecount = samplelen / (bits / 8);
// [FG] do not connect pitch-shifted samples to a sound SFX
if (pitch == NORM_PITCH)
{
sfx_alen = (Uint32)(((ULong64)samplelen * snd_samplerate) / samplerate);
sfx_alen = (Uint32)(((ULong64)samplecount * snd_samplerate) / samplerate);
// [FG] double up twice: 8 -> 16 bit and mono -> stereo
sfx->alen = 4 * sfx_alen;
sfx->data = precache_sounds ? (malloc)(sfx->alen) : Z_Malloc(sfx->alen, PU_STATIC, &sfx->data);
@ -222,7 +269,7 @@ static boolean addsfx(sfxinfo_t *sfx, int channel, int pitch)
{
// [FG] spoof sound samplerate if using randomly pitched sounds
samplerate = (Uint32)(((ULong64)samplerate * steptable[pitch]) >> 16);
sfx_alen = (Uint32)(((ULong64)samplelen * snd_samplerate) / samplerate);
sfx_alen = (Uint32)(((ULong64)samplecount * snd_samplerate) / samplerate);
// [FG] double up twice: 8 -> 16 bit and mono -> stereo
channelinfo[channel].data = Z_Malloc(4 * sfx_alen, PU_STATIC, (void **)&channelinfo[channel].data);
sfx_data = channelinfo[channel].data;
@ -241,20 +288,36 @@ static boolean addsfx(sfxinfo_t *sfx, int channel, int pitch)
// do linear filtering operation
for(i = 0; i < sfx_alen && j < samplelen - 1; ++i)
{
int d = (((unsigned int)src[j ] * (0x10000 - stepremainder)) +
((unsigned int)src[j+1] * stepremainder)) >> 16;
int d;
if(d > 255)
d = 255;
else if(d < 0)
d = 0;
if (bits == 16)
{
d = ((Sint16)(src[j ] | (src[j+1] << 8)) * (0x10000 - stepremainder) +
(Sint16)(src[j+2] | (src[j+3] << 8)) * stepremainder) >> 16;
sample = d;
}
else
{
d = (((unsigned int)src[j ] * (0x10000 - stepremainder)) +
((unsigned int)src[j+1] * stepremainder)) >> 16;
if(d > 255)
d = 255;
else if(d < 0)
d = 0;
// [FG] expand 8->16 bits, mono->stereo
sample = (d-128)*256;
}
// [FG] expand 8->16 bits, mono->stereo
sample = (d-128)*256;
dest[2*i] = dest[2*i+1] = sample;
stepremainder += step;
j += (stepremainder >> 16);
if (bits == 16)
j += (stepremainder >> 16) * 2;
else
j += (stepremainder >> 16);
stepremainder &= 0xffff;
}