'copy' streams on openning. fixes the shared stream issues, though other

problems might arrise (eg, running out of file handles or memory)
This commit is contained in:
Bill Currie 2003-04-20 07:19:51 +00:00
parent 52f41f8095
commit 714bd341fc
6 changed files with 127 additions and 23 deletions

View file

@ -54,6 +54,8 @@ struct sfx_s
struct sfxbuffer_s *(*touch) (sfx_t *sfx);
struct sfxbuffer_s *(*retain) (sfx_t *sfx);
struct wavinfo_s *(*wavinfo) (sfx_t *sfx);
sfx_t *(*open) (sfx_t *sfx);
void (*close) (sfx_t *sfx);
void (*release) (sfx_t *sfx);
};

View file

@ -260,8 +260,10 @@ SND_PickChannel (int entnum, int entchannel)
if (first_to_die == -1)
return NULL;
if (channels[first_to_die].sfx)
if (channels[first_to_die].sfx) {
channels[first_to_die].sfx->close (channels[first_to_die].sfx);
channels[first_to_die].sfx = NULL;
}
return &channels[first_to_die];
}
@ -351,13 +353,18 @@ SND_StartSound (int entnum, int entchannel, sfx_t *sfx, const vec3_t origin,
// new channel
if (!sfx->retain (sfx)) {
if (target_chan->sfx)
target_chan->sfx->close (target_chan->sfx);
target_chan->sfx = NULL;
return; // couldn't load the sound's data
}
target_chan->sfx = sfx;
if (!(target_chan->sfx = sfx->open (sfx))) {
sfx->release (sfx);
return;
}
target_chan->pos = 0.0;
target_chan->end = paintedtime + sfx->length;
target_chan->end = paintedtime + target_chan->sfx->length;
sfx->release (sfx);
// if an identical sound has also been started this frame, offset the pos
@ -390,6 +397,8 @@ SND_StopSound (int entnum, int entchannel)
if (channels[i].entnum == entnum
&& channels[i].entchannel == entchannel) {
channels[i].end = 0;
if (channels[i].sfx)
channels[i].sfx->close (channels[i].sfx);
channels[i].sfx = NULL;
return;
}
@ -407,8 +416,10 @@ SND_StopAllSounds (qboolean clear)
total_channels = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; // no statics
for (i = 0; i < MAX_CHANNELS; i++)
if (channels[i].sfx)
if (channels[i].sfx) {
channels[i].sfx->close (channels[i].sfx);
channels[i].sfx = NULL;
}
memset (channels, 0, MAX_CHANNELS * sizeof (channel_t));
@ -467,7 +478,10 @@ SND_StaticSound (sfx_t *sfx, const vec3_t origin, float vol,
return;
}
ss->sfx = sfx;
if (!(ss->sfx = sfx->open (sfx))) {
sfx->release (sfx);
return;
}
VectorCopy (origin, ss->origin);
ss->master_vol = vol;
ss->dist_mult = (attenuation / 64) / sound_nominal_clip_dist;
@ -498,15 +512,18 @@ SND_UpdateAmbientSounds (void)
l = Mod_PointInLeaf (listener_origin, *render_data.worldmodel);
if (!l || !ambient_level->value) {
for (ambient_channel = 0; ambient_channel < NUM_AMBIENTS;
ambient_channel++)
ambient_channel++) {
if (channels[ambient_channel].sfx)
channels[ambient_channel].sfx->close (channels[ambient_channel].sfx);
channels[ambient_channel].sfx = NULL;
}
return;
}
for (ambient_channel = 0; ambient_channel < NUM_AMBIENTS;
ambient_channel++) {
chan = &channels[ambient_channel];
chan->sfx = ambient_sfx[ambient_channel];
chan->sfx = ambient_sfx[ambient_channel]->open (ambient_sfx[ambient_channel]);
vol = ambient_level->value * l->ambient_sound_level[ambient_channel];
if (vol < 8)

View file

@ -71,6 +71,12 @@ snd_noop (sfx_t *sfx)
{
}
static sfx_t *
snd_open (sfx_t *sfx)
{
return sfx;
}
sfxbuffer_t *
SND_CacheTouch (sfx_t *sfx)
{
@ -263,6 +269,8 @@ SND_Load (sfx_t *sfx)
sfx->touch = sfx->retain = snd_fail;
sfx->release = snd_noop;
sfx->close = snd_noop;
sfx->open = snd_open;
dsprintf (name, "sound/%s", sfx->name);
_QFS_FOpenFile (name->str, &file, foundname, 1);

View file

@ -219,6 +219,7 @@ SND_PaintChannels (unsigned int endtime)
ch->end = ltime + ch->sfx->length - ch->pos;
} else { // channel just stopped
ch->sfx->release (ch->sfx);
ch->sfx->close (ch->sfx);
ch->sfx = NULL;
break;
}

View file

@ -241,36 +241,59 @@ vorbis_stream_seek (void *file, int pos, wavinfo_t *info)
}
static void
vorbis_stream (sfx_t *sfx, char *realname, OggVorbis_File *vf, wavinfo_t info)
vorbis_stream_close (sfx_t *sfx)
{
sfxstream_t *stream;
sfxstream_t *stream = (sfxstream_t *)sfx->data;
ov_clear (stream->file);
free (stream);
free (sfx);
}
static sfx_t *
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;
QFile *file;
QFS_FOpenFile (stream->file, &file);
if (!file)
return 0;
sfx = calloc (1, sizeof (sfx_t));
samples = shm->speed * 0.3;
size = samples = (samples + 255) & ~255;
if (!snd_loadas8bit->int_val)
size *= 2;
if (info.channels == 2)
if (info->channels == 2)
size *= 2;
stream = calloc (1, sizeof (sfxstream_t) + size);
memcpy (stream->buffer.data + size, "\xde\xad\xbe\xef", 4);
free (realname);
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));
memcpy (stream->file, vf, sizeof (OggVorbis_File));;
stream->resample = info.channels == 2 ? SND_ResampleStereo
if (ov_open_callbacks (file, stream->file, 0, 0, callbacks) < 0) {
Sys_Printf ("Input does not appear to be an Ogg bitstream.\n");
Qclose (file);
free (stream);
free (sfx);
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->wavinfo = *info;
stream->buffer.length = samples;
stream->buffer.advance = SND_StreamAdvance;
@ -280,6 +303,24 @@ vorbis_stream (sfx_t *sfx, char *realname, OggVorbis_File *vf, wavinfo_t info)
stream->seek (stream->file, 0, &stream->wavinfo);
stream->buffer.advance (&stream->buffer, 0);
return sfx;
}
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;
}
void

View file

@ -112,35 +112,52 @@ wav_stream_seek (void *file, int pos, wavinfo_t *info)
}
static void
wav_stream (sfx_t *sfx, char *realname, void *file, wavinfo_t info)
wav_stream_close (sfx_t *sfx)
{
sfxstream_t *stream;
sfxstream_t *stream = (sfxstream_t *)sfx->data;
Qclose (stream->file);
free (stream);
free (sfx);
}
static sfx_t *
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;
QFile *file;
QFS_FOpenFile (stream->file, &file);
if (!file)
return 0;
sfx = calloc (1, sizeof (sfx_t));
samples = shm->speed * 0.3;
size = samples = (samples + 255) & ~255;
if (!snd_loadas8bit->int_val)
size *= 2;
if (info.channels == 2)
if (info->channels == 2)
size *= 2;
stream = calloc (1, sizeof (sfxstream_t) + size);
memcpy (stream->buffer.data + size, "\xde\xad\xbe\xef", 4);
free (realname);
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
stream->resample = info->channels == 2 ? SND_ResampleStereo
: SND_ResampleMono;
stream->read = wav_stream_read;
stream->seek = wav_stream_seek;
stream->wavinfo = info;
stream->wavinfo = *info;
stream->buffer.length = samples;
stream->buffer.advance = SND_StreamAdvance;
@ -150,6 +167,24 @@ wav_stream (sfx_t *sfx, char *realname, void *file, wavinfo_t info)
stream->seek (stream->file, 0, &stream->wavinfo);
stream->buffer.advance (&stream->buffer, 0);
return sfx;
}
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;
}
static wavinfo_t