mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 23:32:09 +00:00
[sound] Move stream buffers into locked memory
Streams are the easy one as they were never in the cache. As a side effect, sfxstream_t is much smaller as it no longer has the buffer embedded in the struct.
This commit is contained in:
parent
855b9dccc0
commit
deab21cb4b
5 changed files with 110 additions and 32 deletions
|
@ -62,15 +62,15 @@ struct sfx_s
|
|||
unsigned int loopstart;
|
||||
|
||||
union {
|
||||
struct sfxstream_s *stream;
|
||||
struct sfxblock_s *block;
|
||||
sfxstream_t *stream;
|
||||
sfxblock_t *block;
|
||||
} data;
|
||||
|
||||
struct sfxbuffer_s *(*touch) (sfx_t *sfx);
|
||||
struct sfxbuffer_s *(*retain) (sfx_t *sfx);
|
||||
sfxbuffer_t *(*touch) (sfx_t *sfx);
|
||||
sfxbuffer_t *(*retain) (sfx_t *sfx);
|
||||
void (*release) (sfx_t *sfx);
|
||||
|
||||
struct sfxbuffer_s *(*getbuffer) (sfx_t *sfx);
|
||||
sfxbuffer_t *(*getbuffer) (sfx_t *sfx);
|
||||
struct wavinfo_s *(*wavinfo) (sfx_t *sfx);
|
||||
|
||||
sfx_t *(*open) (sfx_t *sfx);
|
||||
|
@ -207,7 +207,7 @@ struct sfxstream_s {
|
|||
\param pos frame position with the stream
|
||||
*/
|
||||
int (*seek)(sfxstream_t *stream, int pos);
|
||||
sfxbuffer_t buffer; //<! stream's ring buffer
|
||||
sfxbuffer_t *buffer; //<! stream's ring buffer
|
||||
};
|
||||
|
||||
/** Representation of sound loaded into memory as a full block.
|
||||
|
@ -256,6 +256,11 @@ extern portable_samplepair_t snd_paintbuffer[PAINTBUFFER_SIZE * 2];
|
|||
|
||||
///@}
|
||||
|
||||
void SND_Memory_Init_Cvars (void);
|
||||
int SND_Memory_Init (void);
|
||||
sfxbuffer_t *SND_Memory_AllocBuffer (unsigned samples);
|
||||
void SND_Memory_FreeBuffer (sfxbuffer_t *buffer);
|
||||
|
||||
/** \defgroup sound_render_sfx Sound sfx
|
||||
\ingroup sound_render_mix
|
||||
*/
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
|
||||
#include "snd_internal.h"
|
||||
|
||||
static qboolean snd_initialized = false;
|
||||
static int snd_blocked = 0;
|
||||
|
||||
static unsigned soundtime; // sample PAIRS
|
||||
|
@ -333,12 +332,11 @@ s_stop_all_sounds_f (void)
|
|||
static void
|
||||
s_startup (void)
|
||||
{
|
||||
if (!snd_initialized)
|
||||
if (!SND_Memory_Init ()) {
|
||||
return;
|
||||
|
||||
}
|
||||
if (!snd_output_funcs->init (&snd)) {
|
||||
Sys_Printf ("S_Startup: S_O_Init failed.\n");
|
||||
sound_started = 0;
|
||||
Sys_Printf ("S_Startup: output init failed.\n");
|
||||
return;
|
||||
}
|
||||
if (!snd.xfer)
|
||||
|
@ -362,6 +360,8 @@ s_init_cvars (void)
|
|||
Cvar_Register (&snd_mixahead_cvar, 0, 0);
|
||||
Cvar_Register (&snd_noextraupdate_cvar, 0, 0);
|
||||
Cvar_Register (&snd_show_cvar, 0, 0);
|
||||
|
||||
SND_Memory_Init_Cvars ();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -379,8 +379,6 @@ s_init (void)
|
|||
Cmd_AddCommand ("snd_force_unblock", s_snd_force_unblock,
|
||||
"fix permanently blocked sound");
|
||||
|
||||
snd_initialized = true;
|
||||
|
||||
s_startup ();
|
||||
|
||||
if (sound_started == 0) // sound startup failed? Bail out.
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
/*
|
||||
snd_mem.c
|
||||
|
||||
sound caching
|
||||
sound memory management
|
||||
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
Copyright (C) 2003 Bill Currie <bill@taniwha.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
|
@ -35,10 +36,6 @@
|
|||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(HAVE_MALLOC_H)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/dstring.h"
|
||||
#include "QF/sound.h"
|
||||
|
@ -51,6 +48,85 @@
|
|||
|
||||
#define SAMPLE_GAP 4
|
||||
|
||||
static uint32_t snd_mem_size;
|
||||
static cvar_t snd_mem_size_cvar = {
|
||||
.name = "snd_mem_size",
|
||||
.description =
|
||||
"Amount of LOCKED memory to allocate to the sound system in MB. "
|
||||
"Defaults to 32MB.",
|
||||
.default_value = "32",
|
||||
.flags = CVAR_ROM,
|
||||
.value = { .type = &cexpr_uint, .value = &snd_mem_size },
|
||||
};
|
||||
|
||||
static memzone_t *snd_zone;
|
||||
|
||||
void
|
||||
SND_Memory_Init_Cvars (void)
|
||||
{
|
||||
Cvar_Register (&snd_mem_size_cvar, 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
snd_zone_error (void *data, const char *msg)
|
||||
{
|
||||
Sys_Error ("Sound: %s", msg);
|
||||
}
|
||||
|
||||
static void
|
||||
snd_memory_shutdown (void *data)
|
||||
{
|
||||
if (snd_zone) {
|
||||
size_t size = snd_mem_size * 1024 * 1024;
|
||||
Sys_Free (snd_zone, size);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
SND_Memory_Init (void)
|
||||
{
|
||||
size_t size = snd_mem_size * 1024 * 1024;
|
||||
|
||||
snd_zone = Sys_Alloc (size);
|
||||
if (!snd_zone) {
|
||||
Sys_Printf ("Sound: Unable to allocate %uMB buffer\n", snd_mem_size);
|
||||
return 0;
|
||||
}
|
||||
if (!Sys_LockMemory (snd_zone, size)) {
|
||||
Sys_Printf ("Sound: Unable to lock %uMB buffer\n", snd_mem_size);
|
||||
Sys_Free (snd_zone, size);
|
||||
return 0;
|
||||
}
|
||||
Z_ClearZone (snd_zone, size, 0, 1);
|
||||
Z_SetError (snd_zone, snd_zone_error, 0);
|
||||
|
||||
Sys_MaskPrintf (SYS_snd, "Sound: Initialized %uMB buffer\n", snd_mem_size);
|
||||
|
||||
Sys_RegisterShutdown (snd_memory_shutdown, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
sfxbuffer_t *
|
||||
SND_Memory_AllocBuffer (unsigned samples)
|
||||
{
|
||||
size_t size = field_offset (sfxbuffer_t, data[samples]);
|
||||
// Z_Malloc (currently) clears memory, don't need that for the whole
|
||||
// buffer (just the header), but Z_TagMalloc // does not
|
||||
// +4 for sentinel
|
||||
sfxbuffer_t *buffer = Z_TagMalloc (snd_zone, size + 4, 1);
|
||||
// place a sentinel at the end of the buffer for added safety
|
||||
memcpy ((byte *) buffer->data + size, "\xde\xad\xbe\xef", 4);
|
||||
// clear buffer header
|
||||
memset (buffer, 0, sizeof (sfxbuffer_t));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void
|
||||
SND_Memory_FreeBuffer (sfxbuffer_t *buffer)
|
||||
{
|
||||
Z_Free (snd_zone, buffer);
|
||||
}
|
||||
|
||||
static sfxbuffer_t *
|
||||
snd_fail (sfx_t *sfx)
|
||||
{
|
||||
|
@ -117,13 +193,13 @@ SND_CacheRelease (sfx_t *sfx)
|
|||
sfxbuffer_t *
|
||||
SND_StreamGetBuffer (sfx_t *sfx)
|
||||
{
|
||||
return &sfx->data.stream->buffer;
|
||||
return sfx->data.stream->buffer;
|
||||
}
|
||||
|
||||
sfxbuffer_t *
|
||||
SND_StreamRetain (sfx_t *sfx)
|
||||
{
|
||||
return &sfx->data.stream->buffer;
|
||||
return sfx->data.stream->buffer;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -92,7 +92,7 @@ static int
|
|||
snd_read (sfxstream_t *stream, float *data, int frames)
|
||||
{
|
||||
snd_null_state_t *state = (snd_null_state_t *) stream->state;
|
||||
int channels = stream->buffer.channels;
|
||||
int channels = stream->buffer->channels;
|
||||
int framesize = channels * sizeof (float);
|
||||
int count;
|
||||
int read = 0;
|
||||
|
|
|
@ -124,7 +124,6 @@ SND_SFX_StreamOpen (sfx_t *sfx, void *file,
|
|||
sfxstream_t *stream = sfx->data.stream;
|
||||
wavinfo_t *info = &stream->wavinfo;
|
||||
int frames;
|
||||
int size;
|
||||
|
||||
// if the speed is 0, there is no sound driver (probably failed to connect
|
||||
// to jackd)
|
||||
|
@ -144,11 +143,10 @@ SND_SFX_StreamOpen (sfx_t *sfx, void *file,
|
|||
|
||||
frames = snd->speed * 0.3;
|
||||
frames = (frames + 255) & ~255;
|
||||
size = frames * info->channels * sizeof (float);
|
||||
|
||||
stream = calloc (1, sizeof (sfxstream_t) + size);
|
||||
stream = calloc (1, sizeof (sfxstream_t));
|
||||
new_sfx->data.stream = stream;
|
||||
memcpy ((byte *) stream->buffer.data + size, "\xde\xad\xbe\xef", 4);
|
||||
stream->buffer = SND_Memory_AllocBuffer (frames * info->channels);
|
||||
stream->file = file;
|
||||
stream->sfx = new_sfx;
|
||||
stream->ll_read = read;
|
||||
|
@ -156,14 +154,14 @@ SND_SFX_StreamOpen (sfx_t *sfx, void *file,
|
|||
|
||||
stream->wavinfo = *sfx->wavinfo (sfx);
|
||||
|
||||
stream->buffer.size = frames;
|
||||
stream->buffer.advance = SND_StreamAdvance;
|
||||
stream->buffer.setpos = SND_StreamSetPos;
|
||||
stream->buffer.sfx = new_sfx;
|
||||
SND_SetPaint (&stream->buffer);
|
||||
stream->buffer->size = frames;
|
||||
stream->buffer->advance = SND_StreamAdvance;
|
||||
stream->buffer->setpos = SND_StreamSetPos;
|
||||
stream->buffer->sfx = new_sfx;
|
||||
SND_SetPaint (stream->buffer);
|
||||
|
||||
SND_SetupResampler (&stream->buffer, 1); // get sfx setup properly
|
||||
stream->buffer.setpos (&stream->buffer, 0); // pre-fill the buffer
|
||||
SND_SetupResampler (stream->buffer, 1); // get sfx setup properly
|
||||
stream->buffer->setpos (stream->buffer, 0); // pre-fill the buffer
|
||||
|
||||
return new_sfx;
|
||||
}
|
||||
|
@ -173,6 +171,7 @@ SND_SFX_StreamClose (sfx_t *sfx)
|
|||
{
|
||||
sfxstream_t *stream = sfx->data.stream;
|
||||
SND_PulldownResampler (stream);
|
||||
SND_Memory_FreeBuffer (stream->buffer);
|
||||
free (stream);
|
||||
free (sfx);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue