mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 22:31:05 +00:00
making slow progress on sound quality
streamed oggs playback cleaning when not resampling, but flacs are still crap
This commit is contained in:
parent
65a748fc3c
commit
7502cd9ec5
7 changed files with 79 additions and 29 deletions
|
@ -121,13 +121,13 @@ struct sfxbuffer_s {
|
|||
*/
|
||||
void (*setpos) (sfxbuffer_t *buffer, unsigned int pos);
|
||||
sfx_t *sfx; //!< owning sfx_t instance
|
||||
/** Points to the beginning of the sample data within sample_data.
|
||||
/** resampler state information
|
||||
*/
|
||||
float *data;
|
||||
void *state;
|
||||
/** Sample data. The block at the beginning of the buffer (size depends on
|
||||
sample size) holds the state information for resampling.
|
||||
sample size)
|
||||
*/
|
||||
float sample_data[1];
|
||||
float data[1];
|
||||
};
|
||||
|
||||
/** Representation of sound loaded that is streamed in as needed.
|
||||
|
@ -398,6 +398,12 @@ void SND_SetPaint (sfxbuffer_t *sc);
|
|||
\ingroup sound_render
|
||||
*/
|
||||
//@{
|
||||
/** Set up the various parameters that depend on the actual sample rate.
|
||||
\param sc buffer to setup
|
||||
\param streamed non-zero if this is for a stream.
|
||||
*/
|
||||
void SND_SetupResampler (sfxbuffer_t *sc, int streamed);
|
||||
|
||||
/** Copy/resample data into buffer, resampling as necessary.
|
||||
\param sc buffer to write resampled sound
|
||||
\param data raw sample data
|
||||
|
|
|
@ -158,20 +158,21 @@ flac_write_func (const FLAC__StreamDecoder *decoder,
|
|||
flacfile_t *ff = (flacfile_t *) client_data;
|
||||
float *out;
|
||||
float scale = 2.0 / (1 << ff->info.bits_per_sample);
|
||||
int step = ff->info.channels;
|
||||
unsigned i, j;
|
||||
|
||||
if (!ff->buffer)
|
||||
ff->buffer = malloc (ff->info.max_blocksize * ff->info.channels
|
||||
* sizeof (float));
|
||||
ff->buffer = calloc (ff->info.max_blocksize * ff->info.channels,
|
||||
sizeof (float));
|
||||
ff->size = frame->header.blocksize;
|
||||
ff->pos = 0;
|
||||
for (j = 0; j < ff->info.channels; j++) {
|
||||
const FLAC__int32 *in = buffer[j];
|
||||
|
||||
out = ff->buffer + j;
|
||||
for (i = 0; i < frame->header.blocksize; i++, out += ff->info.channels)
|
||||
for (i = 0; i < ff->size; i++, out += step)
|
||||
*out = *in++ * scale;
|
||||
}
|
||||
ff->size = frame->header.blocksize;
|
||||
ff->pos = 0;
|
||||
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
|
@ -296,6 +297,7 @@ flac_load (flacfile_t *ff, sfxblock_t *block, cache_allocator_t allocator)
|
|||
if (flac_read (ff, data, info->frames) < 0)
|
||||
goto bail;
|
||||
SND_SetPaint (sc);
|
||||
SND_SetupResampler (sc, 0);
|
||||
SND_Resample (sc, data, info->frames);
|
||||
sc->head = sc->length;
|
||||
bail:
|
||||
|
|
|
@ -381,14 +381,12 @@ SND_GetCache (long frames, int rate, int channels,
|
|||
|
||||
stepscale = (float) rate / snd_shm->speed;
|
||||
len = size = frames / stepscale;
|
||||
// printf ("%ld %d\n", frames, size);
|
||||
size *= sizeof (float) * channels;
|
||||
sc = allocator (&block->cache, sizeof (sfxbuffer_t) + size, sfx->name);
|
||||
if (!sc)
|
||||
return 0;
|
||||
memset (sc, 0, sizeof (sfxbuffer_t) + size);
|
||||
sc->length = len;
|
||||
sc->data = sc->sample_data;
|
||||
memcpy (sc->data + len * channels, "\xde\xad\xbe\xef", 4);
|
||||
return sc;
|
||||
}
|
||||
|
|
|
@ -70,21 +70,8 @@ SND_Resample (sfxbuffer_t *sc, float *data, int length)
|
|||
SRC_DATA src_data;
|
||||
|
||||
stepscale = (double) snd_shm->speed / inrate;
|
||||
|
||||
outcount = length * stepscale;
|
||||
|
||||
sc->sfx->length = info->frames * stepscale;
|
||||
//printf ("%s %d %g %d\n", sc->sfx->name, length, stepscale, sc->sfx->length);
|
||||
if (info->loopstart != (unsigned int)-1)
|
||||
sc->sfx->loopstart = info->loopstart * stepscale;
|
||||
else
|
||||
sc->sfx->loopstart = (unsigned int)-1;
|
||||
|
||||
sc->channels = info->channels;
|
||||
|
||||
if (!length)
|
||||
return;
|
||||
|
||||
src_data.data_in = data;
|
||||
src_data.data_out = sc->data + sc->head * sc->channels;
|
||||
src_data.input_frames = length;
|
||||
|
@ -97,6 +84,63 @@ SND_Resample (sfxbuffer_t *sc, float *data, int length)
|
|||
check_buffer_integrity (sc, outwidth, __FUNCTION__);
|
||||
}
|
||||
|
||||
static void
|
||||
SND_ResampleStream (sfxbuffer_t *sc, float *data, int length)
|
||||
{
|
||||
SRC_DATA src_data;
|
||||
SRC_STATE *state = (SRC_STATE *) sc->state;
|
||||
|
||||
int outcount;
|
||||
double stepscale;
|
||||
wavinfo_t *info = sc->sfx->wavinfo (sc->sfx);
|
||||
int inrate = info->rate;
|
||||
|
||||
stepscale = (double) snd_shm->speed / inrate;
|
||||
outcount = length * stepscale;
|
||||
|
||||
src_data.data_in = data;
|
||||
src_data.data_out = sc->data + sc->head * sc->channels;
|
||||
src_data.input_frames = length;
|
||||
src_data.output_frames = outcount;
|
||||
src_data.src_ratio = stepscale;
|
||||
src_data.end_of_input = 0; //XXX
|
||||
|
||||
src_process (state, &src_data);
|
||||
}
|
||||
|
||||
void
|
||||
SND_SetupResampler (sfxbuffer_t *sc, int streamed)
|
||||
{
|
||||
double stepscale;
|
||||
wavinfo_t *info = sc->sfx->wavinfo (sc->sfx);
|
||||
int inrate = info->rate;
|
||||
|
||||
stepscale = (double) snd_shm->speed / inrate;
|
||||
|
||||
sc->sfx->length = info->frames * stepscale;
|
||||
if (info->loopstart != (unsigned int)-1)
|
||||
sc->sfx->loopstart = info->loopstart * stepscale;
|
||||
else
|
||||
sc->sfx->loopstart = (unsigned int)-1;
|
||||
|
||||
sc->channels = info->channels;
|
||||
|
||||
if (streamed) {
|
||||
int err;
|
||||
sfxstream_t *stream = sc->sfx->data.stream;
|
||||
|
||||
if (snd_shm->speed == inrate) {
|
||||
sc->state = 0;
|
||||
stream->resample = 0;
|
||||
} else {
|
||||
sc->state = src_new (SRC_LINEAR, info->channels, &err);
|
||||
stream->resample = SND_ResampleStream;
|
||||
}
|
||||
} else {
|
||||
sc->state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SND_Convert (byte *idata, float *fdata, int frames, int channels, int width)
|
||||
{
|
||||
|
|
|
@ -132,12 +132,11 @@ SND_SFX_StreamOpen (sfx_t *sfx, void *file,
|
|||
|
||||
frames = snd_shm->speed * 0.3;
|
||||
frames = (frames + 255) & ~255;
|
||||
size = frames + 1; // one extra sample for the resampler
|
||||
size *= info->channels * sizeof (float);
|
||||
size = frames * info->channels * sizeof (float);
|
||||
|
||||
stream = calloc (1, sizeof (sfxstream_t) + size);
|
||||
new_sfx->data.stream = stream;
|
||||
memcpy ((byte *) stream->buffer.sample_data + size, "\xde\xad\xbe\xef", 4);
|
||||
memcpy ((byte *) stream->buffer.data + size, "\xde\xad\xbe\xef", 4);
|
||||
stream->file = file;
|
||||
stream->sfx = new_sfx;
|
||||
stream->resample = SND_Resample;
|
||||
|
@ -150,10 +149,9 @@ 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[info->channels];
|
||||
SND_SetPaint (&stream->buffer);
|
||||
|
||||
stream->resample (&stream->buffer, 0, 0); // get sfx setup properly
|
||||
SND_SetupResampler (&stream->buffer, 1); // get sfx setup properly
|
||||
stream->buffer.setpos (&stream->buffer, 0); // pre-fill the buffer
|
||||
|
||||
return new_sfx;
|
||||
|
|
|
@ -174,6 +174,7 @@ vorbis_load (OggVorbis_File *vf, sfxblock_t *block, cache_allocator_t allocator)
|
|||
if (vorbis_read (vf, data, info->frames, info) < 0)
|
||||
goto bail;
|
||||
SND_SetPaint (sc);
|
||||
SND_SetupResampler (sc, 0);
|
||||
SND_Resample (sc, data, info->frames);
|
||||
sc->head = sc->length;
|
||||
bail:
|
||||
|
|
|
@ -78,6 +78,7 @@ wav_callback_load (void *object, cache_allocator_t allocator)
|
|||
info->channels, block, allocator);
|
||||
buffer->sfx = sfx;
|
||||
SND_SetPaint (buffer);
|
||||
SND_SetupResampler (buffer, 0);
|
||||
SND_Resample (buffer, fdata, info->frames);
|
||||
buffer->head = buffer->length;
|
||||
free (data);
|
||||
|
|
Loading…
Reference in a new issue