mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-21 18:01:15 +00:00
make the resampling state a little more self-contained. this should make
This commit is contained in:
parent
bfee029249
commit
0af43cf016
7 changed files with 126 additions and 79 deletions
|
@ -120,7 +120,13 @@ struct sfxbuffer_s {
|
|||
*/
|
||||
void (*setpos) (sfxbuffer_t *buffer, unsigned int pos);
|
||||
sfx_t *sfx; //!< owning sfx_t instance
|
||||
byte data[4]; //!< sample data
|
||||
/** Points to the beginning of the sample data within sample_data.
|
||||
*/
|
||||
byte *data;
|
||||
/** Sample data. The block at the beginning of the buffer (size depends on
|
||||
sample size) holds the state information for resampling.
|
||||
*/
|
||||
byte sample_data[4];
|
||||
};
|
||||
|
||||
/** Representation of sound loaded that is streamed in as needed.
|
||||
|
@ -136,7 +142,7 @@ struct sfxstream_s {
|
|||
\param length number of raw samples to resample
|
||||
\param prev pointer to end of last resample for smoothing
|
||||
*/
|
||||
void (*resample)(sfxbuffer_t *, byte *, int, void *);
|
||||
void (*resample)(sfxbuffer_t *, byte *, int);
|
||||
/** Read data from the stream.
|
||||
\param file handle for "file" representing the stream
|
||||
(sfxstream_s::file)
|
||||
|
@ -395,17 +401,15 @@ void SND_SetPaint (sfxbuffer_t *sc);
|
|||
\param sc buffer to write resampled sound
|
||||
\param data raw sample data
|
||||
\param length number of raw samples to resample
|
||||
\param prev pointer to end of last resample for smoothing
|
||||
*/
|
||||
void SND_ResampleMono (sfxbuffer_t *sc, byte *data, int length, void *prev);
|
||||
void SND_ResampleMono (sfxbuffer_t *sc, byte *data, int length);
|
||||
|
||||
/** Copy/resample stereo data into sample buffer, resampling as necessary.
|
||||
\param sc buffer to write resampled sound
|
||||
\param data raw sample data
|
||||
\param length number of raw samples to resample
|
||||
\param prev pointer to end of last resample for smoothing
|
||||
*/
|
||||
void SND_ResampleStereo (sfxbuffer_t *sc, byte *data, int length, void *prev);
|
||||
void SND_ResampleStereo (sfxbuffer_t *sc, byte *data, int length);
|
||||
//@}
|
||||
|
||||
|
||||
|
|
|
@ -345,7 +345,7 @@ flac_load (flacfile_t *ff, sfxblock_t *block, cache_allocator_t allocator)
|
|||
byte *data;
|
||||
sfxbuffer_t *sc = 0;
|
||||
sfx_t *sfx = block->sfx;
|
||||
void (*resample)(sfxbuffer_t *, byte *, int, void *);
|
||||
void (*resample)(sfxbuffer_t *, byte *, int);
|
||||
wavinfo_t *info = &block->wavinfo;
|
||||
|
||||
switch (ff->info.channels) {
|
||||
|
@ -372,7 +372,7 @@ flac_load (flacfile_t *ff, sfxblock_t *block, cache_allocator_t allocator)
|
|||
if (flac_read (ff, data, info->datalen) < 0)
|
||||
goto bail;
|
||||
SND_SetPaint (sc);
|
||||
resample (sc, data, info->samples, 0);
|
||||
resample (sc, data, info->samples);
|
||||
sc->head = sc->length;
|
||||
bail:
|
||||
if (data)
|
||||
|
|
|
@ -157,16 +157,13 @@ SND_StreamWavinfo (sfx_t *sfx)
|
|||
}
|
||||
|
||||
static void
|
||||
read_samples (sfxbuffer_t *buffer, int count, void *prev)
|
||||
read_samples (sfxbuffer_t *buffer, int count)
|
||||
{
|
||||
|
||||
if (buffer->head + count > buffer->length) {
|
||||
int s = (buffer->length - 1);
|
||||
|
||||
count -= buffer->length - buffer->head;
|
||||
read_samples (buffer, buffer->length - buffer->head, prev);
|
||||
prev = buffer->data + s * buffer->bps;
|
||||
read_samples (buffer, count, prev);
|
||||
read_samples (buffer, buffer->length - buffer->head);
|
||||
read_samples (buffer, count);
|
||||
} else {
|
||||
float stepscale;
|
||||
int samples, size;
|
||||
|
@ -183,7 +180,7 @@ read_samples (sfxbuffer_t *buffer, int count, void *prev)
|
|||
byte *data = alloca (size);
|
||||
if (stream->read (stream->file, data, size, info) != size)
|
||||
Sys_Printf ("%s r\n", sfx->name);
|
||||
stream->resample (buffer, data, samples, prev);
|
||||
stream->resample (buffer, data, samples);
|
||||
} else {
|
||||
if (stream->read (stream->file, buffer->data, size, info) != size)
|
||||
Sys_Printf ("%s nr\n", sfx->name);
|
||||
|
@ -198,7 +195,6 @@ static void
|
|||
fill_buffer (sfx_t *sfx, sfxstream_t *stream, sfxbuffer_t *buffer,
|
||||
wavinfo_t *info, unsigned int headpos)
|
||||
{
|
||||
void *prev;
|
||||
unsigned int samples;
|
||||
unsigned int loop_samples = 0;
|
||||
|
||||
|
@ -220,23 +216,17 @@ fill_buffer (sfx_t *sfx, sfxstream_t *stream, sfxbuffer_t *buffer,
|
|||
int s = buffer->head - 1;
|
||||
if (!buffer->head)
|
||||
s += buffer->length;
|
||||
prev = buffer->data + s * buffer->bps;
|
||||
} else {
|
||||
prev = 0;
|
||||
}
|
||||
read_samples (buffer, samples, prev);
|
||||
read_samples (buffer, samples);
|
||||
}
|
||||
if (loop_samples) {
|
||||
if (buffer->head != buffer->tail) {
|
||||
int s = buffer->head - 1;
|
||||
if (!buffer->head)
|
||||
s += buffer->length;
|
||||
prev = buffer->data + s * buffer->bps;
|
||||
} else {
|
||||
prev = 0;
|
||||
}
|
||||
stream->seek (stream->file, info->loopstart, info);
|
||||
read_samples (buffer, loop_samples, prev);
|
||||
read_samples (buffer, loop_samples);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -403,6 +393,7 @@ SND_GetCache (long samples, int rate, int inwidth, int channels,
|
|||
return 0;
|
||||
memset (sc, 0, sizeof (sfxbuffer_t) + size);
|
||||
sc->length = len;
|
||||
sc->data = sc->sample_data;
|
||||
memcpy (sc->data + size, "\xde\xad\xbe\xef", 4);
|
||||
return sc;
|
||||
}
|
||||
|
|
|
@ -61,6 +61,39 @@ typedef struct {
|
|||
cvar_t *snd_loadas8bit;
|
||||
cvar_t *snd_interp;
|
||||
|
||||
static inline int
|
||||
snd_convert_8_to_8 (byte data)
|
||||
{
|
||||
return data - 128;
|
||||
}
|
||||
|
||||
static inline int
|
||||
snd_convert_8_to_16 (byte data)
|
||||
{
|
||||
return snd_convert_8_to_8 (data) << 8;
|
||||
}
|
||||
|
||||
static inline int
|
||||
snd_convert_16_to_16 (short data)
|
||||
{
|
||||
return LittleShort (data);
|
||||
}
|
||||
|
||||
static inline int
|
||||
snd_convert_16_to_8 (short data)
|
||||
{
|
||||
return snd_convert_16_to_16 (data) >> 8;
|
||||
}
|
||||
|
||||
#define FAST_RESAMPLE(in,out,count,convert) \
|
||||
do { \
|
||||
int i; \
|
||||
\
|
||||
for (i = 0; i < count; i++) { \
|
||||
*out++ = convert (*in++); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static void
|
||||
check_buffer_integrity (sfxbuffer_t *sc, int width, const char *func)
|
||||
{
|
||||
|
@ -71,8 +104,9 @@ check_buffer_integrity (sfxbuffer_t *sc, int width, const char *func)
|
|||
}
|
||||
|
||||
void
|
||||
SND_ResampleMono (sfxbuffer_t *sc, byte *data, int length, void *prev)
|
||||
SND_ResampleMono (sfxbuffer_t *sc, byte *data, int length)
|
||||
{
|
||||
void *prev = 0;
|
||||
byte *ib, *ob, *pb;
|
||||
int fracstep, outcount, sample, samplefrac, srcsample, i;
|
||||
float stepscale;
|
||||
|
@ -84,6 +118,9 @@ SND_ResampleMono (sfxbuffer_t *sc, byte *data, int length, void *prev)
|
|||
short zero_s[1];
|
||||
byte zero_b[1];
|
||||
|
||||
if (sc->data != sc->sample_data)
|
||||
prev = sc->data;
|
||||
|
||||
is = (short *) data;
|
||||
os = (short *) sc->data;
|
||||
ib = data;
|
||||
|
@ -111,18 +148,16 @@ SND_ResampleMono (sfxbuffer_t *sc, byte *data, int length, void *prev)
|
|||
else
|
||||
sc->sfx->loopstart = (unsigned int)-1;
|
||||
|
||||
if (snd_loadas8bit->int_val) {
|
||||
if (snd_loadas8bit->int_val)
|
||||
sc->bps = outwidth = 1;
|
||||
if (prev) {
|
||||
zero_s[0] = ((char *)prev)[0];
|
||||
zero_b[0] = ((char *)prev)[0] + 128;
|
||||
}
|
||||
} else {
|
||||
else
|
||||
sc->bps = outwidth = 2;
|
||||
if (prev) {
|
||||
|
||||
if (prev) {
|
||||
if (inwidth == 1)
|
||||
zero_b[0] = ((char *)prev)[0];
|
||||
else
|
||||
zero_s[0] = ((short *)prev)[0];
|
||||
zero_b[0] = (((short *)prev)[0] >> 8) + 128;
|
||||
}
|
||||
}
|
||||
|
||||
if (!length)
|
||||
|
@ -131,29 +166,19 @@ SND_ResampleMono (sfxbuffer_t *sc, byte *data, int length, void *prev)
|
|||
// resample / decimate to the current source rate
|
||||
if (stepscale == 1) {
|
||||
if (inwidth == 1) {
|
||||
if (outwidth == 1) {
|
||||
for (i = 0; i < outcount; i++) {
|
||||
*ob++ = *ib++ - 128;
|
||||
}
|
||||
} else if (outwidth == 2) {
|
||||
for (i = 0; i < outcount; i++) {
|
||||
*os++ = (*ib++ - 128) << 8;
|
||||
}
|
||||
} else {
|
||||
if (outwidth == 1)
|
||||
FAST_RESAMPLE (ib, ob, outcount, snd_convert_8_to_8);
|
||||
else if (outwidth == 2)
|
||||
FAST_RESAMPLE (ib, os, outcount, snd_convert_8_to_16);
|
||||
else
|
||||
goto general_Mono;
|
||||
}
|
||||
} else if (inwidth == 2) {
|
||||
if (outwidth == 1) {
|
||||
for (i = 0; i < outcount; i++) {
|
||||
*ob++ = LittleShort (*is++) >> 8;
|
||||
}
|
||||
} else if (outwidth == 2) {
|
||||
for (i = 0; i < outcount; i++) {
|
||||
*os++ = LittleShort (*is++);
|
||||
}
|
||||
} else {
|
||||
if (outwidth == 1)
|
||||
FAST_RESAMPLE (is, ob, outcount, snd_convert_16_to_8);
|
||||
else if (outwidth == 2)
|
||||
FAST_RESAMPLE (is, os, outcount, snd_convert_16_to_16);
|
||||
else
|
||||
goto general_Mono;
|
||||
}
|
||||
}
|
||||
} else { // general case
|
||||
general_Mono:
|
||||
|
@ -165,12 +190,12 @@ general_Mono:
|
|||
int s1, s2;
|
||||
|
||||
if (inwidth == 2) {
|
||||
s1 = LittleShort (*ps);
|
||||
s2 = LittleShort (*is);
|
||||
s1 = snd_convert_16_to_16 (*ps);
|
||||
s2 = snd_convert_16_to_16 (*is);
|
||||
ps = is++;
|
||||
} else {
|
||||
s1 = (*pb - 128) << 8;
|
||||
s2 = (*ib - 128) << 8;
|
||||
s1 = snd_convert_8_to_16 (*pb);
|
||||
s2 = snd_convert_8_to_16 (*ib);
|
||||
pb = ib++;
|
||||
}
|
||||
for (j = 0; j < points; j++) {
|
||||
|
@ -187,6 +212,12 @@ general_Mono:
|
|||
ob += points;
|
||||
}
|
||||
}
|
||||
if (prev) {
|
||||
if (inwidth == 1)
|
||||
((char *)prev)[0] = *pb;
|
||||
else
|
||||
((short *)prev)[0] = *ps;
|
||||
}
|
||||
} else {
|
||||
samplefrac = 0;
|
||||
fracstep = stepscale * 256;
|
||||
|
@ -194,9 +225,9 @@ general_Mono:
|
|||
srcsample = samplefrac >> 8;
|
||||
samplefrac += fracstep;
|
||||
if (inwidth == 2)
|
||||
sample = LittleShort (is[srcsample]);
|
||||
sample = snd_convert_16_to_16 (is[srcsample]);
|
||||
else
|
||||
sample = (ib[srcsample] - 128) << 8;
|
||||
sample = snd_convert_8_to_16 (ib[srcsample]);
|
||||
if (outwidth == 2)
|
||||
os[i] = sample;
|
||||
else
|
||||
|
@ -208,8 +239,9 @@ general_Mono:
|
|||
}
|
||||
|
||||
void
|
||||
SND_ResampleStereo (sfxbuffer_t *sc, byte *data, int length, void *prev)
|
||||
SND_ResampleStereo (sfxbuffer_t *sc, byte *data, int length)
|
||||
{
|
||||
void *prev = 0;
|
||||
int fracstep, outcount, outwidth, samplefrac, srcsample, sl, sr, i;
|
||||
float stepscale;
|
||||
stereo8_t *ib, *ob, *pb;
|
||||
|
@ -220,6 +252,9 @@ SND_ResampleStereo (sfxbuffer_t *sc, byte *data, int length, void *prev)
|
|||
stereo16_t zero_s;
|
||||
stereo8_t zero_b;
|
||||
|
||||
if (sc->data != sc->sample_data)
|
||||
prev = sc->data;
|
||||
|
||||
is = (stereo16_t *) data;
|
||||
os = (stereo16_t *) sc->data;
|
||||
ib = (stereo8_t *) data;
|
||||
|
@ -249,20 +284,18 @@ SND_ResampleStereo (sfxbuffer_t *sc, byte *data, int length, void *prev)
|
|||
if (snd_loadas8bit->int_val) {
|
||||
outwidth = 1;
|
||||
sc->bps = 2;
|
||||
if (prev) {
|
||||
zero_s.left = ((char *)prev)[0];
|
||||
zero_s.right = ((char *)prev)[1];
|
||||
zero_b.left = ((char *)prev)[0] + 128;
|
||||
zero_b.right = ((char *)prev)[1] + 128;
|
||||
}
|
||||
} else {
|
||||
outwidth = 2;
|
||||
sc->bps = 4;
|
||||
if (prev) {
|
||||
}
|
||||
|
||||
if (prev) {
|
||||
if (inwidth == 1) {
|
||||
zero_b.left = ((char *)prev)[0];
|
||||
zero_b.right = ((char *)prev)[1];
|
||||
} else {
|
||||
zero_s.left = ((short *)prev)[0];
|
||||
zero_s.right = ((short *)prev)[1];
|
||||
zero_b.left = (((short *)prev)[0] >> 8) + 128;
|
||||
zero_b.right = (((short *)prev)[1] >> 8) + 128;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -340,6 +373,15 @@ general_Stereo:
|
|||
ob += points;
|
||||
}
|
||||
}
|
||||
if (prev) {
|
||||
if (inwidth == 1) {
|
||||
((char *)prev)[0] = pb->left;
|
||||
((char *)prev)[1] = pb->right;
|
||||
} else {
|
||||
((short *)prev)[0] = ps->left;
|
||||
((short *)prev)[1] = ps->right;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
samplefrac = 0;
|
||||
fracstep = stepscale * 256;
|
||||
|
|
|
@ -119,6 +119,7 @@ SND_SFX_StreamOpen (sfx_t *sfx, void *file,
|
|||
wavinfo_t *info = &stream->wavinfo;
|
||||
int samples;
|
||||
int size;
|
||||
int width;
|
||||
|
||||
sfx_t *new_sfx = calloc (1, sizeof (sfx_t));
|
||||
|
||||
|
@ -131,15 +132,18 @@ SND_SFX_StreamOpen (sfx_t *sfx, void *file,
|
|||
new_sfx->close = close;
|
||||
|
||||
samples = snd_shm->speed * 0.3;
|
||||
size = samples = (samples + 255) & ~255;
|
||||
samples = (samples + 255) & ~255;
|
||||
size = samples + 1; // one extra sample for the resampler
|
||||
width = 1;
|
||||
if (!snd_loadas8bit->int_val)
|
||||
size *= 2;
|
||||
width *= 2;
|
||||
if (info->channels == 2)
|
||||
size *= 2;
|
||||
width *= 2;
|
||||
size *= width;
|
||||
|
||||
stream = calloc (1, sizeof (sfxstream_t) + size);
|
||||
new_sfx->data.stream = stream;
|
||||
memcpy (stream->buffer.data + size, "\xde\xad\xbe\xef", 4);
|
||||
memcpy (stream->buffer.sample_data + size, "\xde\xad\xbe\xef", 4);
|
||||
stream->file = file;
|
||||
stream->sfx = new_sfx;
|
||||
stream->resample = info->channels == 2 ? SND_ResampleStereo
|
||||
|
@ -153,9 +157,15 @@ SND_SFX_StreamOpen (sfx_t *sfx, void *file,
|
|||
stream->buffer.advance = SND_StreamAdvance;
|
||||
stream->buffer.setpos = SND_StreamSetPos;
|
||||
stream->buffer.sfx = new_sfx;
|
||||
stream->buffer.data = &stream->buffer.sample_data[width];
|
||||
if (info->width == 1) {
|
||||
stream->buffer.sample_data[0] = 128;
|
||||
if (info->channels == 2)
|
||||
stream->buffer.sample_data[1] = 128;
|
||||
}
|
||||
SND_SetPaint (&stream->buffer);
|
||||
|
||||
stream->resample (&stream->buffer, 0, 0, 0); // get sfx setup properly
|
||||
stream->resample (&stream->buffer, 0, 0); // get sfx setup properly
|
||||
stream->seek (stream->file, 0, &stream->wavinfo);
|
||||
|
||||
stream->buffer.advance (&stream->buffer, 0);
|
||||
|
|
|
@ -156,7 +156,7 @@ vorbis_load (OggVorbis_File *vf, sfxblock_t *block, cache_allocator_t allocator)
|
|||
byte *data;
|
||||
sfxbuffer_t *sc = 0;
|
||||
sfx_t *sfx = block->sfx;
|
||||
void (*resample)(sfxbuffer_t *, byte *, int, void *);
|
||||
void (*resample)(sfxbuffer_t *, byte *, int);
|
||||
wavinfo_t *info = &block->wavinfo;
|
||||
|
||||
switch (info->channels) {
|
||||
|
@ -183,7 +183,7 @@ vorbis_load (OggVorbis_File *vf, sfxblock_t *block, cache_allocator_t allocator)
|
|||
if (vorbis_read (vf, data, info->datalen) < 0)
|
||||
goto bail;
|
||||
SND_SetPaint (sc);
|
||||
resample (sc, data, info->samples, 0);
|
||||
resample (sc, data, info->samples);
|
||||
sc->head = sc->length;
|
||||
bail:
|
||||
if (data)
|
||||
|
|
|
@ -73,9 +73,9 @@ wav_callback_load (void *object, cache_allocator_t allocator)
|
|||
buffer->sfx = sfx;
|
||||
SND_SetPaint (buffer);
|
||||
if (info->channels == 2)
|
||||
SND_ResampleStereo (buffer, data, info->samples, 0);
|
||||
SND_ResampleStereo (buffer, data, info->samples);
|
||||
else
|
||||
SND_ResampleMono (buffer, data, info->samples, 0);
|
||||
SND_ResampleMono (buffer, data, info->samples);
|
||||
buffer->head = buffer->length;
|
||||
free (data);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue