Skip to content
This repository has been archived by the owner on Jun 23, 2023. It is now read-only.

Commit

Permalink
Enable loading 16 bit RIFF wavs in .wads. (#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
SmileTheory committed Feb 18, 2021
1 parent 995b063 commit 8d22abe
Showing 1 changed file with 75 additions and 19 deletions.
94 changes: 75 additions & 19 deletions prboom2/src/SDL/i_sound.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ typedef struct
// ... and a 0.16 bit remainder of last step.
unsigned int stepremainder;
unsigned int samplerate;
unsigned int bits;
float alpha;
int prevS;
// The channel data pointers, start and end.
const unsigned char *data;
const unsigned char *enddata;
Expand Down Expand Up @@ -166,21 +169,55 @@ static void stopchan(int i)
//
static int addsfx(int sfxid, int channel, const unsigned char *data, size_t len)
{
channel_info_t *ci = channelinfo + channel;
float rc, dt;

stopchan(channel);

channelinfo[channel].data = data;
/* Set pointer to end of raw data. */
channelinfo[channel].enddata = channelinfo[channel].data + len - 1;
channelinfo[channel].samplerate = (channelinfo[channel].data[3] << 8) + channelinfo[channel].data[2];
channelinfo[channel].data += 8; /* Skip header */
if (strncmp(data, "RIFF", 4) == 0 && strncmp(data + 8, "WAVEfmt ", 8) == 0)
{
// FIXME: can't handle stereo wavs
// ci->channels = data[22] | (data[23] << 8);
ci->samplerate = data[24] | (data[25] << 8) | (data[26] << 16)
| (data[27] << 24);
ci->bits = data[34] | (data[35] << 8);
ci->data = data + 44;
ci->enddata = data + 44 + (data[40] | (data[41] << 8) | (data[42] << 16)
| (data[43] << 24));
if (ci->enddata > data + len - 2)
ci->enddata = data + len - 2;
}
else
{
ci->samplerate = (data[3] << 8) + data[2];
ci->bits = 8;
ci->data = data + 8;
ci->enddata = data + len - 1;
}

ci->prevS = 0;

// Filter from chocolate doom i_sdlsound.c 682-695
// Low-pass filter for cutoff frequency f:
//
// For sampling rate r, dt = 1 / r
// rc = 1 / 2*pi*f
// alpha = dt / (rc + dt)

// Filter to the half sample rate of the original sound effect
// (maximum frequency, by nyquist)

channelinfo[channel].stepremainder = 0;
dt = 1.0f / snd_samplerate;
rc = 1.0f / (3.14f * ci->samplerate);
ci->alpha = dt / (rc + dt);

ci->stepremainder = 0;
// Should be gametic, I presume.
channelinfo[channel].starttime = gametic;
ci->starttime = gametic;

// Preserve sound SFX id,
// e.g. for avoiding duplicates of chainsaw.
channelinfo[channel].id = sfxid;
ci->id = sfxid;

return channel;
}
Expand Down Expand Up @@ -500,20 +537,34 @@ static void I_UpdateSound(void *unused, Uint8 *stream, int len)
// as well. Thus loop those channels.
for ( chan = 0; chan < numChannels; chan++ )
{
channel_info_t *ci = channelinfo + chan;

// Check channel, if active.
if (channelinfo[chan].data)
if (ci->data)
{
int s;
// Get the raw data from the channel.
// no filtering
//int s = channelinfo[chan].data[0] * 0x10000 - 0x800000;
//s = ci->data[0] * 0x10000 - 0x800000;

// linear filtering
// the old SRC did linear interpolation back into 8 bit, and then expanded to 16 bit.
// this does interpolation and 8->16 at same time, allowing slightly higher quality
int s = ((unsigned int)channelinfo[chan].data[0] * (0x10000 - channelinfo[chan].stepremainder))
+ ((unsigned int)channelinfo[chan].data[1] * (channelinfo[chan].stepremainder))
- 0x800000; // convert to signed
if (ci->bits == 16)
{
s = (short)(ci->data[0] | (ci->data[1] << 8)) * (255 - (ci->stepremainder >> 8))
+ (short)(ci->data[2] | (ci->data[3] << 8)) * (ci->stepremainder >> 8);
}
else
{
s = (ci->data[0] * (0x10000 - ci->stepremainder))
+ (ci->data[1] * (ci->stepremainder))
- 0x800000; // convert to signed
}

// lowpass
s = ci->prevS + ci->alpha * (s - ci->prevS);
ci->prevS = s;

// Add left and right part
// for this channel (sound)
Expand All @@ -522,18 +573,23 @@ static void I_UpdateSound(void *unused, Uint8 *stream, int len)

// full loudness (vol=127) is actually 127/191

dl += channelinfo[chan].leftvol * s / 49152; // >> 15;
dr += channelinfo[chan].rightvol * s / 49152; // >> 15;
dl += ci->leftvol * s / 49152; // >> 15;
dr += ci->rightvol * s / 49152; // >> 15;

// Increment index ???
channelinfo[chan].stepremainder += channelinfo[chan].step;
ci->stepremainder += ci->step;

// MSB is next sample???
channelinfo[chan].data += channelinfo[chan].stepremainder >> 16;
if (ci->bits == 16)
ci->data += (ci->stepremainder >> 16) * 2;
else
ci->data += ci->stepremainder >> 16;

// Limit to LSB???
channelinfo[chan].stepremainder &= 0xffff;
ci->stepremainder &= 0xffff;

// Check whether we are done.
if (channelinfo[chan].data >= channelinfo[chan].enddata)
if (ci->data >= ci->enddata)
stopchan(chan);
}
}
Expand Down

0 comments on commit 8d22abe

Please sign in to comment.