[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:
Bill Currie 2022-06-04 18:45:11 +09:00
parent 855b9dccc0
commit deab21cb4b
5 changed files with 110 additions and 32 deletions

View file

@ -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
*/

View file

@ -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.

View file

@ -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

View file

@ -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;

View file

@ -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);
}