make the cache/stream setup code common.

This commit is contained in:
Bill Currie 2007-03-18 01:44:46 +00:00 committed by Jeff Teunissen
parent 8205ac4544
commit 44aaec4f22
6 changed files with 149 additions and 213 deletions

View file

@ -127,16 +127,14 @@ struct sfxstream_s {
void *file; //!< handle for "file" representing the stream
wavinfo_t wavinfo; //!< description of sound data
unsigned pos; //!< position of next sample within full stream
/** Seek to an absolute position within the stream, resetting the ring
buffer.
/** Resample raw data into internal format.
\param sc buffer to write resampled sound (sfxstream_s::buffer)
\param data raw sample data
\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 *);
/** Seek to an absolute position within the stream, resetting the ring
buffer.
/** Read data from the stream.
\param file handle for "file" representing the stream
(sfxstream_s::file)
\param data destination of read data
@ -164,7 +162,7 @@ struct sfxblock_s {
cache_user_t cache; //!< cached sound buffer (::sfxbuffer_s)
};
/** Representation of a sound being played
/** Representation of a sound being played.
*/
struct channel_s {
sfx_t *sfx; //!< sound played by this channel
@ -180,6 +178,14 @@ struct channel_s {
int master_vol; //!< 0-255 master volume
int phase; //!< phase shift between l-r in samples
int oldphase; //!< phase shift between l-r in samples
/** signal between main program and mixer thread that the channel is to be
stopped.
- 0 normal operation
- 1 signal from main program to mixer the channel is to be stopped
- 2 signal from the mixer to the main program indicating the mixer is
done with the channel and the main program is free to clear it.
*/
int stopped;
};
extern struct cvar_s *snd_loadas8bit;
@ -200,6 +206,35 @@ extern portable_samplepair_t snd_paintbuffer[PAINTBUFFER_SIZE * 2];
\ingroup sound_render_mix
*/
//@{
/** Cache sound data. Initializes caching fields of sfx.
\param sfx
\param realname
\param info
\param loader
*/
void SND_SFX_Cache (sfx_t *sfx, char *realname, wavinfo_t info,
cache_loader_t loader);
/** Stream sound data. Initializes streaming fields of sfx.
\param sfx
\param realname
\param info
\param open
*/
void SND_SFX_Stream (sfx_t *sfx, char *realname, wavinfo_t info,
sfx_t *(*open) (sfx_t *sfx));
/** Open a stream for playback.
\param sfx
\param read
\param seek
\param close
*/
sfx_t *SND_SFX_StreamOpen (sfx_t *sfx, void *file,
int (*read)(void *, byte *, int, wavinfo_t *),
int (*seek)(void *, int, wavinfo_t *),
void (*close) (sfx_t *));
/** Pre-load a sound into the cache.
\param sample name of sound to precache
*/

View file

@ -314,21 +314,8 @@ flac_callback_load (void *object, cache_allocator_t allocator)
static void
flac_cache (sfx_t *sfx, char *realname, flacfile_t *ff, wavinfo_t info)
{
sfxblock_t *block = calloc (1, sizeof (sfxblock_t));
close_flac (ff);
sfx->data = block;
sfx->wavinfo = SND_CacheWavinfo;
sfx->touch = SND_CacheTouch;
sfx->retain = SND_CacheRetain;
sfx->release = SND_CacheRelease;
block->sfx = sfx;
block->file = realname;
block->wavinfo = info;
Cache_Add (&block->cache, block, flac_callback_load);
SND_SFX_Cache (sfx, realname, info, flac_callback_load);
}
static int
@ -357,78 +344,32 @@ flac_stream_close (sfx_t *sfx)
}
static sfx_t *
flac_stream_open (sfx_t *_sfx)
flac_stream_open (sfx_t *sfx)
{
sfx_t *sfx;
sfxstream_t *stream = (sfxstream_t *) _sfx->data;
wavinfo_t *info = &stream->wavinfo;
int samples;
int size;
sfxstream_t *stream = (sfxstream_t *) sfx->data;
QFile *file;
void *f;
QFS_FOpenFile (stream->file, &file);
if (!file)
return 0;
sfx = calloc (1, sizeof (sfx_t));
samples = snd_shm->speed * 0.3;
size = samples = (samples + 255) & ~255;
if (!snd_loadas8bit->int_val)
size *= 2;
if (info->channels == 2)
size *= 2;
stream = calloc (1, sizeof (sfxstream_t) + size);
memcpy (stream->buffer.data + size, "\xde\xad\xbe\xef", 4);
sfx->name = _sfx->name;
sfx->data = stream;
sfx->wavinfo = SND_CacheWavinfo;
sfx->touch = sfx->retain = SND_StreamRetain;
sfx->release = SND_StreamRelease;
sfx->close = flac_stream_close;
stream->sfx = sfx;
stream->file = open_flac (file);
if (!stream->file) {
f = open_flac (file);
if (!f) {
Sys_Printf ("Input does not appear to be a flac bitstream.\n");
Qclose (file);
free (stream);
free (sfx);
return 0;
}
stream->resample = info->channels == 2 ? SND_ResampleStereo
: SND_ResampleMono;
stream->read = flac_stream_read;
stream->seek = flac_stream_seek;
stream->wavinfo = *info;
stream->buffer.length = samples;
stream->buffer.advance = SND_StreamAdvance;
stream->buffer.setpos = SND_StreamSetPos;
stream->buffer.sfx = sfx;
stream->resample (&stream->buffer, 0, 0, 0); // get sfx setup properly
stream->seek (stream->file, 0, &stream->wavinfo);
stream->buffer.advance (&stream->buffer, 0);
return sfx;
return SND_SFX_StreamOpen (sfx, f, flac_stream_read, flac_stream_seek,
flac_stream_close);
}
static void
flac_stream (sfx_t *sfx, char *realname, flacfile_t *ff, wavinfo_t info)
{
sfxstream_t *stream = calloc (1, sizeof (sfxstream_t));
close_flac (ff);
sfx->open = flac_stream_open;
sfx->wavinfo = SND_CacheWavinfo;
sfx->touch = sfx->retain = SND_StreamRetain;
sfx->release = SND_StreamRelease;
sfx->data = stream;
stream->file = realname;
stream->wavinfo = info;
SND_SFX_Stream (sfx, realname, info, flac_stream_open);
}
static wavinfo_t

View file

@ -191,7 +191,6 @@ void
SND_LoadMidi (QFile *file, sfx_t *sfx, char *realname)
{
wavinfo_t info;
sfxstream_t *stream = calloc (1, sizeof (sfxstream_t));
midi *handle;
unsigned char *local_buffer;
unsigned long int local_buffer_size = Qfilesize (file);
@ -220,14 +219,6 @@ SND_LoadMidi (QFile *file, sfx_t *sfx, char *realname)
Sys_DPrintf ("stream %s\n", realname);
// we init stream here cause we will only ever stream
sfx->open = midi_stream_open;
sfx->wavinfo = SND_CacheWavinfo;
sfx->touch = sfx->retain = SND_StreamRetain;
sfx->release = SND_StreamRelease;
sfx->data = stream;
stream->file = realname;
stream->wavinfo = info;
SND_SFX_Stream (sfx, realname, info, midi_stream_open);
}
#endif // HAVE_WILDMIDI

View file

@ -72,6 +72,89 @@ snd_sfx_free (void *_sfx, void *unused)
sfx->name = 0;
}
void
SND_SFX_Cache (sfx_t *sfx, char *realname, wavinfo_t info,
cache_loader_t loader)
{
sfxblock_t *block = calloc (1, sizeof (sfxblock_t));
sfx->data = block;
sfx->wavinfo = SND_CacheWavinfo;
sfx->touch = SND_CacheTouch;
sfx->retain = SND_CacheRetain;
sfx->release = SND_CacheRelease;
block->sfx = sfx;
block->file = realname;
block->wavinfo = info;
Cache_Add (&block->cache, block, loader);
}
void
SND_SFX_Stream (sfx_t *sfx, char *realname, wavinfo_t info,
sfx_t *(*open) (sfx_t *sfx))
{
sfxstream_t *stream = calloc (1, sizeof (sfxstream_t));
sfx->open = open;
sfx->wavinfo = SND_CacheWavinfo;
sfx->touch = sfx->retain = SND_StreamRetain;
sfx->release = SND_StreamRelease;
sfx->data = stream;
stream->file = realname;
stream->wavinfo = info;
}
sfx_t *
SND_SFX_StreamOpen (sfx_t *sfx, void *file,
int (*read)(void *, byte *, int, wavinfo_t *),
int (*seek)(void *, int, wavinfo_t *),
void (*close) (sfx_t *))
{
sfxstream_t *stream = (sfxstream_t *) sfx->data;
wavinfo_t *info = &stream->wavinfo;
int samples;
int size;
sfx_t *new_sfx = calloc (1, sizeof (sfx_t));
new_sfx->name = sfx->name;
new_sfx->wavinfo = SND_CacheWavinfo;
new_sfx->touch = new_sfx->retain = SND_StreamRetain;
new_sfx->release = SND_StreamRelease;
new_sfx->close = close;
samples = snd_shm->speed * 0.3;
size = samples = (samples + 255) & ~255;
if (!snd_loadas8bit->int_val)
size *= 2;
if (info->channels == 2)
size *= 2;
stream = calloc (1, sizeof (sfxstream_t) + size);
new_sfx->data = stream;
memcpy (stream->buffer.data + size, "\xde\xad\xbe\xef", 4);
stream->file = file;
stream->sfx = new_sfx;
stream->resample = info->channels == 2 ? SND_ResampleStereo
: SND_ResampleMono;
stream->read = read;
stream->seek = seek;
stream->buffer.length = samples;
stream->buffer.advance = SND_StreamAdvance;
stream->buffer.setpos = SND_StreamSetPos;
stream->buffer.sfx = new_sfx;
stream->resample (&stream->buffer, 0, 0, 0); // get sfx setup properly
stream->seek (stream->file, 0, &stream->wavinfo);
stream->buffer.advance (&stream->buffer, 0);
return new_sfx;
}
sfx_t *
SND_LoadSound (const char *name)
{

View file

@ -214,19 +214,8 @@ vorbis_callback_load (void *object, cache_allocator_t allocator)
static void
vorbis_cache (sfx_t *sfx, char *realname, OggVorbis_File *vf, wavinfo_t info)
{
sfxblock_t *block = calloc (1, sizeof (sfxblock_t));
ov_clear (vf);
sfx->data = block;
sfx->wavinfo = SND_CacheWavinfo;
sfx->touch = SND_CacheTouch;
sfx->retain = SND_CacheRetain;
sfx->release = SND_CacheRelease;
block->sfx = sfx;
block->file = realname;
block->wavinfo = info;
Cache_Add (&block->cache, block, vorbis_callback_load);
SND_SFX_Cache (sfx, realname, info, vorbis_callback_load);
}
static int
@ -252,78 +241,33 @@ vorbis_stream_close (sfx_t *sfx)
}
static sfx_t *
vorbis_stream_open (sfx_t *_sfx)
vorbis_stream_open (sfx_t *sfx)
{
sfx_t *sfx;
sfxstream_t *stream = (sfxstream_t *) _sfx->data;
wavinfo_t *info = &stream->wavinfo;
int samples;
int size;
sfxstream_t *stream = (sfxstream_t *) sfx->data;
QFile *file;
void *f;
QFS_FOpenFile (stream->file, &file);
if (!file)
return 0;
sfx = calloc (1, sizeof (sfx_t));
samples = snd_shm->speed * 0.3;
size = samples = (samples + 255) & ~255;
if (!snd_loadas8bit->int_val)
size *= 2;
if (info->channels == 2)
size *= 2;
stream = calloc (1, sizeof (sfxstream_t) + size);
memcpy (stream->buffer.data + size, "\xde\xad\xbe\xef", 4);
sfx->name = _sfx->name;
sfx->data = stream;
sfx->wavinfo = SND_CacheWavinfo;
sfx->touch = sfx->retain = SND_StreamRetain;
sfx->release = SND_StreamRelease;
sfx->close = vorbis_stream_close;
stream->sfx = sfx;
stream->file = malloc (sizeof (OggVorbis_File));
if (ov_open_callbacks (file, stream->file, 0, 0, callbacks) < 0) {
f = malloc (sizeof (OggVorbis_File));
if (ov_open_callbacks (file, f, 0, 0, callbacks) < 0) {
Sys_Printf ("Input does not appear to be an Ogg bitstream.\n");
Qclose (file);
free (stream);
free (sfx);
free (f);
return 0;
}
stream->resample = info->channels == 2 ? SND_ResampleStereo
: SND_ResampleMono;
stream->read = vorbis_stream_read;
stream->seek = vorbis_stream_seek;
stream->wavinfo = *info;
stream->buffer.length = samples;
stream->buffer.advance = SND_StreamAdvance;
stream->buffer.setpos = SND_StreamSetPos;
stream->buffer.sfx = sfx;
stream->resample (&stream->buffer, 0, 0, 0); // get sfx setup properly
stream->seek (stream->file, 0, &stream->wavinfo);
stream->buffer.advance (&stream->buffer, 0);
return sfx;
return SND_SFX_StreamOpen (sfx, f, vorbis_stream_read, vorbis_stream_seek,
vorbis_stream_close);
}
static void
vorbis_stream (sfx_t *sfx, char *realname, OggVorbis_File *vf, wavinfo_t info)
{
sfxstream_t *stream = calloc (1, sizeof (sfxstream_t));
ov_clear (vf);
sfx->open = vorbis_stream_open;
sfx->wavinfo = SND_CacheWavinfo;
sfx->touch = sfx->retain = SND_StreamRetain;
sfx->release = SND_StreamRelease;
sfx->data = stream;
stream->file = realname;
stream->wavinfo = info;
SND_SFX_Stream (sfx, realname, info, vorbis_stream_open);
}
void

View file

@ -82,19 +82,8 @@ wav_callback_load (void *object, cache_allocator_t allocator)
static void
wav_cache (sfx_t *sfx, char *realname, void *file, wavinfo_t info)
{
sfxblock_t *block = calloc (1, sizeof (sfxblock_t));
Qclose (file);
sfx->data = block;
sfx->wavinfo = SND_CacheWavinfo;
sfx->touch = SND_CacheTouch;
sfx->retain = SND_CacheRetain;
sfx->release = SND_CacheRelease;
block->sfx = sfx;
block->file = realname;
block->wavinfo = info;
Cache_Add (&block->cache, block, wav_callback_load);
SND_SFX_Cache (sfx, realname, info, wav_callback_load);
}
static int
@ -122,71 +111,24 @@ wav_stream_close (sfx_t *sfx)
}
static sfx_t *
wav_stream_open (sfx_t *_sfx)
wav_stream_open (sfx_t *sfx)
{
sfx_t *sfx;
sfxstream_t *stream = (sfxstream_t *) _sfx->data;
wavinfo_t *info = &stream->wavinfo;
int samples;
int size;
sfxstream_t *stream = (sfxstream_t *) sfx->data;
QFile *file;
QFS_FOpenFile (stream->file, &file);
if (!file)
return 0;
sfx = calloc (1, sizeof (sfx_t));
samples = snd_shm->speed * 0.3;
size = samples = (samples + 255) & ~255;
if (!snd_loadas8bit->int_val)
size *= 2;
if (info->channels == 2)
size *= 2;
stream = calloc (1, sizeof (sfxstream_t) + size);
memcpy (stream->buffer.data + size, "\xde\xad\xbe\xef", 4);
sfx->name = _sfx->name;
sfx->data = stream;
sfx->wavinfo = SND_CacheWavinfo;
sfx->touch = sfx->retain = SND_StreamRetain;
sfx->release = SND_StreamRelease;
sfx->close = wav_stream_close;
stream->sfx = sfx;
stream->file = file;
stream->resample = info->channels == 2 ? SND_ResampleStereo
: SND_ResampleMono;
stream->read = wav_stream_read;
stream->seek = wav_stream_seek;
stream->wavinfo = *info;
stream->buffer.length = samples;
stream->buffer.advance = SND_StreamAdvance;
stream->buffer.setpos = SND_StreamSetPos;
stream->buffer.sfx = sfx;
stream->resample (&stream->buffer, 0, 0, 0); // get sfx setup properly
stream->seek (stream->file, 0, &stream->wavinfo);
stream->buffer.advance (&stream->buffer, 0);
return sfx;
return SND_SFX_StreamOpen (sfx, file, wav_stream_read, wav_stream_seek,
wav_stream_close);
}
static void
wav_stream (sfx_t *sfx, char *realname, void *file, wavinfo_t info)
{
sfxstream_t *stream = calloc (1, sizeof (sfxstream_t));
Qclose (file);
sfx->open = wav_stream_open;
sfx->wavinfo = SND_CacheWavinfo;
sfx->touch = sfx->retain = SND_StreamRetain;
sfx->release = SND_StreamRelease;
sfx->data = stream;
stream->file = realname;
stream->wavinfo = info;
SND_SFX_Stream (sfx, realname, info, wav_stream_open);
}
static wavinfo_t