mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-20 17:31:08 +00:00
make the cache/stream setup code common.
This commit is contained in:
parent
8205ac4544
commit
44aaec4f22
6 changed files with 149 additions and 213 deletions
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue