making slow progress on sound quality

streamed oggs playback cleaning when not resampling, but flacs are still crap
This commit is contained in:
Bill Currie 2010-08-11 23:45:09 +00:00 committed by Jeff Teunissen
parent 65a748fc3c
commit 7502cd9ec5
7 changed files with 79 additions and 29 deletions

View file

@ -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

View file

@ -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:

View file

@ -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;
}

View file

@ -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)
{

View file

@ -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;

View file

@ -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:

View file

@ -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);