mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-27 06:34:11 +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);
|
void (*setpos) (sfxbuffer_t *buffer, unsigned int pos);
|
||||||
sfx_t *sfx; //!< owning sfx_t instance
|
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 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.
|
/** Representation of sound loaded that is streamed in as needed.
|
||||||
|
@ -398,6 +398,12 @@ void SND_SetPaint (sfxbuffer_t *sc);
|
||||||
\ingroup sound_render
|
\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.
|
/** Copy/resample data into buffer, resampling as necessary.
|
||||||
\param sc buffer to write resampled sound
|
\param sc buffer to write resampled sound
|
||||||
\param data raw sample data
|
\param data raw sample data
|
||||||
|
|
|
@ -158,20 +158,21 @@ flac_write_func (const FLAC__StreamDecoder *decoder,
|
||||||
flacfile_t *ff = (flacfile_t *) client_data;
|
flacfile_t *ff = (flacfile_t *) client_data;
|
||||||
float *out;
|
float *out;
|
||||||
float scale = 2.0 / (1 << ff->info.bits_per_sample);
|
float scale = 2.0 / (1 << ff->info.bits_per_sample);
|
||||||
|
int step = ff->info.channels;
|
||||||
unsigned i, j;
|
unsigned i, j;
|
||||||
|
|
||||||
if (!ff->buffer)
|
if (!ff->buffer)
|
||||||
ff->buffer = malloc (ff->info.max_blocksize * ff->info.channels
|
ff->buffer = calloc (ff->info.max_blocksize * ff->info.channels,
|
||||||
* sizeof (float));
|
sizeof (float));
|
||||||
|
ff->size = frame->header.blocksize;
|
||||||
|
ff->pos = 0;
|
||||||
for (j = 0; j < ff->info.channels; j++) {
|
for (j = 0; j < ff->info.channels; j++) {
|
||||||
const FLAC__int32 *in = buffer[j];
|
const FLAC__int32 *in = buffer[j];
|
||||||
|
|
||||||
out = ff->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;
|
*out = *in++ * scale;
|
||||||
}
|
}
|
||||||
ff->size = frame->header.blocksize;
|
|
||||||
ff->pos = 0;
|
|
||||||
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
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)
|
if (flac_read (ff, data, info->frames) < 0)
|
||||||
goto bail;
|
goto bail;
|
||||||
SND_SetPaint (sc);
|
SND_SetPaint (sc);
|
||||||
|
SND_SetupResampler (sc, 0);
|
||||||
SND_Resample (sc, data, info->frames);
|
SND_Resample (sc, data, info->frames);
|
||||||
sc->head = sc->length;
|
sc->head = sc->length;
|
||||||
bail:
|
bail:
|
||||||
|
|
|
@ -381,14 +381,12 @@ SND_GetCache (long frames, int rate, int channels,
|
||||||
|
|
||||||
stepscale = (float) rate / snd_shm->speed;
|
stepscale = (float) rate / snd_shm->speed;
|
||||||
len = size = frames / stepscale;
|
len = size = frames / stepscale;
|
||||||
// printf ("%ld %d\n", frames, size);
|
|
||||||
size *= sizeof (float) * channels;
|
size *= sizeof (float) * channels;
|
||||||
sc = allocator (&block->cache, sizeof (sfxbuffer_t) + size, sfx->name);
|
sc = allocator (&block->cache, sizeof (sfxbuffer_t) + size, sfx->name);
|
||||||
if (!sc)
|
if (!sc)
|
||||||
return 0;
|
return 0;
|
||||||
memset (sc, 0, sizeof (sfxbuffer_t) + size);
|
memset (sc, 0, sizeof (sfxbuffer_t) + size);
|
||||||
sc->length = len;
|
sc->length = len;
|
||||||
sc->data = sc->sample_data;
|
|
||||||
memcpy (sc->data + len * channels, "\xde\xad\xbe\xef", 4);
|
memcpy (sc->data + len * channels, "\xde\xad\xbe\xef", 4);
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,21 +70,8 @@ SND_Resample (sfxbuffer_t *sc, float *data, int length)
|
||||||
SRC_DATA src_data;
|
SRC_DATA src_data;
|
||||||
|
|
||||||
stepscale = (double) snd_shm->speed / inrate;
|
stepscale = (double) snd_shm->speed / inrate;
|
||||||
|
|
||||||
outcount = length * stepscale;
|
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_in = data;
|
||||||
src_data.data_out = sc->data + sc->head * sc->channels;
|
src_data.data_out = sc->data + sc->head * sc->channels;
|
||||||
src_data.input_frames = length;
|
src_data.input_frames = length;
|
||||||
|
@ -97,6 +84,63 @@ SND_Resample (sfxbuffer_t *sc, float *data, int length)
|
||||||
check_buffer_integrity (sc, outwidth, __FUNCTION__);
|
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
|
void
|
||||||
SND_Convert (byte *idata, float *fdata, int frames, int channels, int width)
|
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 = snd_shm->speed * 0.3;
|
||||||
frames = (frames + 255) & ~255;
|
frames = (frames + 255) & ~255;
|
||||||
size = frames + 1; // one extra sample for the resampler
|
size = frames * info->channels * sizeof (float);
|
||||||
size *= info->channels * sizeof (float);
|
|
||||||
|
|
||||||
stream = calloc (1, sizeof (sfxstream_t) + size);
|
stream = calloc (1, sizeof (sfxstream_t) + size);
|
||||||
new_sfx->data.stream = stream;
|
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->file = file;
|
||||||
stream->sfx = new_sfx;
|
stream->sfx = new_sfx;
|
||||||
stream->resample = SND_Resample;
|
stream->resample = SND_Resample;
|
||||||
|
@ -150,10 +149,9 @@ SND_SFX_StreamOpen (sfx_t *sfx, void *file,
|
||||||
stream->buffer.advance = SND_StreamAdvance;
|
stream->buffer.advance = SND_StreamAdvance;
|
||||||
stream->buffer.setpos = SND_StreamSetPos;
|
stream->buffer.setpos = SND_StreamSetPos;
|
||||||
stream->buffer.sfx = new_sfx;
|
stream->buffer.sfx = new_sfx;
|
||||||
stream->buffer.data = &stream->buffer.sample_data[info->channels];
|
|
||||||
SND_SetPaint (&stream->buffer);
|
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
|
stream->buffer.setpos (&stream->buffer, 0); // pre-fill the buffer
|
||||||
|
|
||||||
return new_sfx;
|
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)
|
if (vorbis_read (vf, data, info->frames, info) < 0)
|
||||||
goto bail;
|
goto bail;
|
||||||
SND_SetPaint (sc);
|
SND_SetPaint (sc);
|
||||||
|
SND_SetupResampler (sc, 0);
|
||||||
SND_Resample (sc, data, info->frames);
|
SND_Resample (sc, data, info->frames);
|
||||||
sc->head = sc->length;
|
sc->head = sc->length;
|
||||||
bail:
|
bail:
|
||||||
|
|
|
@ -78,6 +78,7 @@ wav_callback_load (void *object, cache_allocator_t allocator)
|
||||||
info->channels, block, allocator);
|
info->channels, block, allocator);
|
||||||
buffer->sfx = sfx;
|
buffer->sfx = sfx;
|
||||||
SND_SetPaint (buffer);
|
SND_SetPaint (buffer);
|
||||||
|
SND_SetupResampler (buffer, 0);
|
||||||
SND_Resample (buffer, fdata, info->frames);
|
SND_Resample (buffer, fdata, info->frames);
|
||||||
buffer->head = buffer->length;
|
buffer->head = buffer->length;
|
||||||
free (data);
|
free (data);
|
||||||
|
|
Loading…
Reference in a new issue