mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-17 22:50:51 +00:00
'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:
parent
52f41f8095
commit
714bd341fc
6 changed files with 127 additions and 23 deletions
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue