2003-02-02 03:43:49 +00:00
|
|
|
/*
|
2011-07-23 06:56:22 +00:00
|
|
|
snd_internal.h
|
2003-02-02 03:43:49 +00:00
|
|
|
|
|
|
|
Sound renderer plugin stuff
|
|
|
|
|
|
|
|
Copyright (C) 2002 Bill Currie
|
|
|
|
|
|
|
|
Author: Bill Currie <bill@taniwha.org>
|
|
|
|
Date: Jan 31 2003
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to:
|
|
|
|
|
|
|
|
Free Software Foundation, Inc.
|
|
|
|
59 Temple Place - Suite 330
|
|
|
|
Boston, MA 02111-1307, USA
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2011-07-23 06:56:22 +00:00
|
|
|
#ifndef __snd_internal_h
|
|
|
|
#define __snd_internal_h
|
2003-01-31 20:51:04 +00:00
|
|
|
|
2022-06-06 02:33:22 +00:00
|
|
|
#include <stdatomic.h>
|
2003-04-11 01:17:48 +00:00
|
|
|
|
2007-03-10 06:01:28 +00:00
|
|
|
/** \defgroup sound_render Sound rendering sub-system.
|
2007-03-10 04:21:32 +00:00
|
|
|
\ingroup sound
|
|
|
|
*/
|
2020-02-11 06:20:49 +00:00
|
|
|
///@{
|
2007-03-10 04:21:32 +00:00
|
|
|
|
2012-02-13 12:58:34 +00:00
|
|
|
#include "QF/plugin/general.h"
|
2007-03-17 03:10:45 +00:00
|
|
|
#include "QF/plugin/snd_render.h"
|
2012-02-13 12:58:34 +00:00
|
|
|
#include "QF/plugin/snd_output.h"
|
2007-03-17 03:10:45 +00:00
|
|
|
#include "QF/quakeio.h"
|
2007-03-10 04:21:32 +00:00
|
|
|
#include "QF/sound.h"
|
|
|
|
#include "QF/zone.h"
|
2003-04-11 21:14:38 +00:00
|
|
|
|
2022-02-28 07:59:38 +00:00
|
|
|
struct transform_s;
|
2007-03-10 04:21:32 +00:00
|
|
|
typedef struct portable_samplepair_s portable_samplepair_t;
|
2021-06-23 15:04:02 +00:00
|
|
|
typedef struct snd_s snd_t;
|
2007-03-10 04:21:32 +00:00
|
|
|
typedef struct wavinfo_s wavinfo_t;
|
2003-04-11 01:17:48 +00:00
|
|
|
typedef struct sfxbuffer_s sfxbuffer_t;
|
2007-03-10 04:21:32 +00:00
|
|
|
typedef struct sfxblock_s sfxblock_t;
|
|
|
|
typedef struct sfxstream_s sfxstream_t;
|
2022-06-03 02:54:53 +00:00
|
|
|
|
|
|
|
struct sfx_s
|
|
|
|
{
|
|
|
|
struct snd_s *snd; //!< ownding snd_t instance
|
|
|
|
const char *name;
|
|
|
|
|
2022-06-05 07:57:13 +00:00
|
|
|
unsigned length;
|
|
|
|
unsigned loopstart;
|
2022-06-03 02:54:53 +00:00
|
|
|
|
|
|
|
union {
|
2022-06-04 09:45:11 +00:00
|
|
|
sfxstream_t *stream;
|
|
|
|
sfxblock_t *block;
|
2022-06-05 07:57:13 +00:00
|
|
|
};
|
2022-06-03 02:54:53 +00:00
|
|
|
|
2022-06-05 07:57:13 +00:00
|
|
|
struct wavinfo_s *(*wavinfo) (const sfx_t *sfx);
|
2022-06-03 02:54:53 +00:00
|
|
|
|
2022-06-05 07:57:13 +00:00
|
|
|
sfxbuffer_t *(*open) (sfx_t *sfx);
|
2022-06-03 02:54:53 +00:00
|
|
|
};
|
|
|
|
|
2010-08-12 02:28:27 +00:00
|
|
|
/** paint samples into the mix buffer
|
2022-06-05 07:57:13 +00:00
|
|
|
|
|
|
|
This is currently used for channel-count specific mixing
|
|
|
|
|
2010-08-12 02:28:27 +00:00
|
|
|
\param offset offset into the mix buffer at which to start mixing
|
|
|
|
the channel
|
|
|
|
\param ch sound channel
|
|
|
|
\param buffer sound data
|
|
|
|
\param count number of frames to paint
|
|
|
|
*/
|
2021-01-22 06:23:04 +00:00
|
|
|
typedef void sfxpaint_t (int offset, channel_t *ch, float *buffer,
|
|
|
|
unsigned count);
|
2007-03-10 04:21:32 +00:00
|
|
|
|
2022-06-05 07:57:13 +00:00
|
|
|
/** Represent a single output frame in the mixer.
|
2007-03-10 04:21:32 +00:00
|
|
|
*/
|
|
|
|
struct portable_samplepair_s {
|
2022-06-05 09:25:14 +00:00
|
|
|
float left; //!< left sample
|
|
|
|
float right; //!< right sample
|
2007-03-10 04:21:32 +00:00
|
|
|
};
|
|
|
|
|
2021-12-25 02:17:33 +00:00
|
|
|
/** Sound system state
|
2007-03-10 04:21:32 +00:00
|
|
|
*/
|
2021-06-23 15:04:02 +00:00
|
|
|
struct snd_s {
|
2022-06-05 09:25:14 +00:00
|
|
|
int speed; //!< sample rate
|
|
|
|
int samplebits; //!< bits per sample
|
|
|
|
int channels; //!< number of output channels
|
|
|
|
int frames; //!< frames in buffer
|
|
|
|
//!< 1 frame = channels samples
|
|
|
|
int submission_chunk; //!< don't mix less than this #
|
|
|
|
unsigned paintedtime; //!< sound clock in samples
|
|
|
|
int framepos; //!< position of dma cursor
|
|
|
|
int threaded; //!< output+mixer run asynchronously
|
|
|
|
byte *buffer; //!< destination for mixed sound
|
2007-03-17 07:05:24 +00:00
|
|
|
/** Transfer mixed samples to the output.
|
2011-09-08 09:10:09 +00:00
|
|
|
\param paintbuffer The buffer of mixed samples to be transferred.
|
|
|
|
\param count The number of sample to transfer.
|
|
|
|
\param volume The gain for the samples.
|
2007-03-17 07:05:24 +00:00
|
|
|
*/
|
2022-06-05 09:25:14 +00:00
|
|
|
void (*xfer) (struct snd_s *snd, portable_samplepair_t *paintbuffer,
|
|
|
|
int count, float volume);
|
2011-09-07 08:00:18 +00:00
|
|
|
/** Optional data for the xfer function.
|
|
|
|
*/
|
2022-06-05 09:25:14 +00:00
|
|
|
void *xfer_data;
|
2021-06-26 07:18:18 +00:00
|
|
|
|
|
|
|
void (*finish_channels) (void);
|
|
|
|
void (*paint_channels) (struct snd_s *snd, unsigned endtime);
|
2007-03-10 04:21:32 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/** Describes the sound data.
|
|
|
|
For looped data (loopstart >= 0), play starts at sample 0, goes to the end,
|
|
|
|
then loops back to loopstart. This allows an optional lead in section
|
|
|
|
followed by a continuously looped (until the sound is stopped) section.
|
|
|
|
*/
|
|
|
|
struct wavinfo_s {
|
|
|
|
unsigned rate; //!< sample rate
|
2010-08-11 23:44:34 +00:00
|
|
|
unsigned width; //!< bytes per sample
|
2007-03-10 04:21:32 +00:00
|
|
|
unsigned channels; //!< number of channels
|
2010-08-11 23:44:34 +00:00
|
|
|
unsigned loopstart; //!< start frame of loop. -1 = no loop
|
|
|
|
unsigned frames; //!< size of sound in frames
|
2007-03-10 04:21:32 +00:00
|
|
|
unsigned dataofs; //!< chunk starts this many bytes from BOF
|
|
|
|
unsigned datalen; //!< chunk bytes
|
|
|
|
};
|
|
|
|
|
2022-06-06 03:05:44 +00:00
|
|
|
/** Buffer for storing sound samples in memory. For block-loaded sounds, acts
|
|
|
|
as an ordinary buffer. For streamed sounds, acts as a ring buffer.
|
2007-03-10 04:21:32 +00:00
|
|
|
*/
|
2003-04-11 01:17:48 +00:00
|
|
|
struct sfxbuffer_s {
|
2022-06-06 02:33:22 +00:00
|
|
|
_Atomic unsigned head; //!< ring buffer head position in sampels
|
|
|
|
_Atomic unsigned tail; //!< ring buffer tail position in sampels
|
|
|
|
// FIXME should pos be atomic? it's primary use is in the mixer but can
|
|
|
|
// be used for checking the channel's "time"
|
2007-03-10 04:21:32 +00:00
|
|
|
unsigned pos; //!< position of tail within full stream
|
2022-06-06 02:33:22 +00:00
|
|
|
unsigned size; //!< size of buffer in frames
|
2010-08-11 23:44:34 +00:00
|
|
|
unsigned channels; //!< number of channels per frame
|
2022-06-05 07:57:13 +00:00
|
|
|
unsigned sfx_length; //!< total length of sfx
|
|
|
|
union { // owning instance
|
|
|
|
// the first field of both sfxstream_t and sfxblock_t is a pointer
|
|
|
|
// to sfx_t
|
|
|
|
sfx_t const * const * const sfx;
|
|
|
|
sfxstream_t *stream;
|
|
|
|
sfxblock_t *block;
|
|
|
|
};
|
2010-08-12 02:28:27 +00:00
|
|
|
sfxpaint_t *paint; //!< channel count specific paint function
|
2007-03-10 04:21:32 +00:00
|
|
|
/** Advance the position with the stream, updating the ring buffer as
|
|
|
|
necessary. Null for chached sounds.
|
|
|
|
\param buffer "this"
|
2010-08-11 23:44:34 +00:00
|
|
|
\param count number of frames to advance
|
2010-08-13 01:48:20 +00:00
|
|
|
\return true for success, false if an error occured
|
2007-03-10 04:21:32 +00:00
|
|
|
*/
|
2022-06-05 09:25:14 +00:00
|
|
|
int (*advance) (sfxbuffer_t *buffer, unsigned int count);
|
2007-03-10 04:21:32 +00:00
|
|
|
/** Seek to an absolute position within the stream, resetting the ring
|
|
|
|
buffer.
|
|
|
|
\param buffer "this"
|
2010-08-11 23:44:34 +00:00
|
|
|
\param pos frame position with the stream
|
2007-03-10 04:21:32 +00:00
|
|
|
*/
|
2022-06-05 09:25:14 +00:00
|
|
|
void (*setpos) (sfxbuffer_t *buffer, unsigned int pos);
|
|
|
|
void (*close) (sfxbuffer_t *buffer);
|
2009-01-08 07:48:08 +00:00
|
|
|
/** Sample data. The block at the beginning of the buffer (size depends on
|
2010-08-11 23:45:09 +00:00
|
|
|
sample size)
|
2009-01-08 07:48:08 +00:00
|
|
|
*/
|
2022-06-04 14:55:31 +00:00
|
|
|
float data[];
|
2003-04-11 01:17:48 +00:00
|
|
|
};
|
|
|
|
|
2007-03-10 04:21:32 +00:00
|
|
|
/** Representation of sound loaded that is streamed in as needed.
|
|
|
|
*/
|
|
|
|
struct sfxstream_s {
|
2022-06-05 07:57:13 +00:00
|
|
|
const sfx_t *sfx; //!< owning sfx_t instance
|
2007-03-10 04:21:32 +00:00
|
|
|
void *file; //!< handle for "file" representing the stream
|
|
|
|
wavinfo_t wavinfo; //!< description of sound data
|
2010-08-11 23:44:34 +00:00
|
|
|
unsigned pos; //!< position of next frame full stream
|
2010-08-13 01:48:20 +00:00
|
|
|
int error; //!< an error occured while reading
|
2010-08-11 23:47:03 +00:00
|
|
|
|
|
|
|
void *state; //!< resampler state information
|
|
|
|
/** Read data from the stream.
|
|
|
|
This is a low-level function used by sfxstream_t::read. The read
|
|
|
|
samples will be at the sample rate of the underlying stream.
|
|
|
|
\param cb_data stream relevant infomation (actually ::sfxstream_t
|
|
|
|
("this"), but this signature is used for compatibility
|
|
|
|
with libsamplerate
|
|
|
|
\param data address of pointer to be set to point to the buffer
|
|
|
|
holding the samples
|
2007-03-10 04:21:32 +00:00
|
|
|
*/
|
2022-06-05 09:25:14 +00:00
|
|
|
long (*ll_read)(void *cb_data, float **data);
|
2010-08-11 23:47:31 +00:00
|
|
|
/** Seek to an absolute position within the stream (low level).
|
|
|
|
\param stream "this"
|
|
|
|
\param pos frame position with the stream
|
|
|
|
*/
|
2022-06-05 09:25:14 +00:00
|
|
|
int (*ll_seek)(sfxstream_t *stream, int pos);
|
2007-03-18 01:44:46 +00:00
|
|
|
/** Read data from the stream.
|
2010-08-11 23:47:03 +00:00
|
|
|
This is a high-level function for use in the mixer. The read samples
|
|
|
|
will always at be the correct sample rate for the mixer, reguardless
|
|
|
|
of the sample rate in the underlying stream.
|
|
|
|
\param stream "this"
|
2007-03-10 04:21:32 +00:00
|
|
|
\param data destination of read data
|
2010-08-11 23:47:03 +00:00
|
|
|
\param frames maximum number of frames to read from stream
|
2010-08-11 23:44:34 +00:00
|
|
|
\return number of frames read from stream
|
2007-03-10 04:21:32 +00:00
|
|
|
*/
|
2022-06-05 09:25:14 +00:00
|
|
|
int (*read)(sfxstream_t *stream, float *data, int frames);
|
2007-03-10 04:21:32 +00:00
|
|
|
/** Seek to an absolute position within the stream.
|
2010-08-11 23:47:03 +00:00
|
|
|
\param stream "this"
|
2010-08-11 23:44:34 +00:00
|
|
|
\param pos frame position with the stream
|
2007-03-10 04:21:32 +00:00
|
|
|
*/
|
2022-06-05 09:25:14 +00:00
|
|
|
int (*seek)(sfxstream_t *stream, int pos);
|
2022-06-04 09:45:11 +00:00
|
|
|
sfxbuffer_t *buffer; //<! stream's ring buffer
|
2007-03-10 04:21:32 +00:00
|
|
|
};
|
2003-04-11 01:17:48 +00:00
|
|
|
|
2007-03-10 04:21:32 +00:00
|
|
|
/** Representation of sound loaded into memory as a full block.
|
|
|
|
*/
|
|
|
|
struct sfxblock_s {
|
2022-06-05 07:57:13 +00:00
|
|
|
const sfx_t *sfx; //!< owning sfx_t instance
|
2007-03-10 04:21:32 +00:00
|
|
|
void *file; //!< handle for "file" representing the block
|
|
|
|
wavinfo_t wavinfo; //!< description of sound data
|
2022-06-06 03:05:44 +00:00
|
|
|
sfxbuffer_t *buffer; //!< pointer to block-loaded buffer
|
2007-03-10 04:21:32 +00:00
|
|
|
};
|
2003-01-31 20:51:04 +00:00
|
|
|
|
2007-03-18 01:44:46 +00:00
|
|
|
/** Representation of a sound being played.
|
2007-03-10 04:21:32 +00:00
|
|
|
*/
|
2003-04-11 01:17:48 +00:00
|
|
|
struct channel_s {
|
2022-06-06 02:33:22 +00:00
|
|
|
sfxbuffer_t *_Atomic buffer;//!< sound played by this channel
|
2022-06-03 07:54:57 +00:00
|
|
|
float leftvol; //!< 0-1 volume
|
|
|
|
float rightvol; //!< 0-1 volume
|
2007-03-10 04:21:32 +00:00
|
|
|
unsigned end; //!< end time in global paintsamples
|
|
|
|
unsigned pos; //!< sample position in sfx
|
2022-06-05 07:57:13 +00:00
|
|
|
unsigned loopstart; //!< where to loop, -1 = no looping
|
2007-03-10 04:21:32 +00:00
|
|
|
int phase; //!< phase shift between l-r in samples
|
|
|
|
int oldphase; //!< phase shift between l-r in samples
|
2022-06-06 02:33:22 +00:00
|
|
|
_Atomic byte pause; //!< don't update the channel at all
|
2007-03-18 01:44:46 +00:00
|
|
|
/** signal between main program and mixer thread that the channel is to be
|
|
|
|
stopped.
|
2007-03-18 10:32:01 +00:00
|
|
|
- both \c stop and \c done are zero: normal operation
|
|
|
|
- \c stop is non-zero: main program is done with channel. must wait
|
|
|
|
for mixer to finish with channel before re-using.
|
|
|
|
- \c done is non-zero: mixer is done with channel. can be reused at
|
|
|
|
any time.
|
|
|
|
- both \c stop and \c done are non-zero: both are done with channel.
|
|
|
|
can be reused at any time.
|
2007-03-18 01:44:46 +00:00
|
|
|
*/
|
2007-03-18 10:32:01 +00:00
|
|
|
//@{
|
2022-06-06 02:33:22 +00:00
|
|
|
_Atomic byte stop;
|
|
|
|
_Atomic byte done;
|
2007-03-18 10:32:01 +00:00
|
|
|
//@}
|
2003-04-11 01:17:48 +00:00
|
|
|
};
|
2003-01-31 20:51:04 +00:00
|
|
|
|
[cvar] Make cvars properly typed
This is an extremely extensive patch as it hits every cvar, and every
usage of the cvars. Cvars no longer store the value they control,
instead, they use a cexpr value object to reference the value and
specify the value's type (currently, a null type is used for strings).
Non-string cvars are passed through cexpr, allowing expressions in the
cvars' settings. Also, cvars have returned to an enhanced version of the
original (id quake) registration scheme.
As a minor benefit, relevant code having direct access to the
cvar-controlled variables is probably a slight optimization as it
removed a pointer dereference, and the variables can be located for data
locality.
The static cvar descriptors are made private as an additional safety
layer, though there's nothing stopping external modification via
Cvar_FindVar (which is needed for adding listeners).
While not used yet (partly due to working out the design), cvars can
have a validation function.
Registering a cvar allows a primary listener (and its data) to be
specified: it will always be called first when the cvar is modified. The
combination of proper listeners and direct access to the controlled
variable greatly simplifies the more complex cvar interactions as much
less null checking is required, and there's no need for one cvar's
callback to call another's.
nq-x11 is known to work at least well enough for the demos. More testing
will come.
2022-04-23 03:22:45 +00:00
|
|
|
extern float snd_volume;
|
2007-03-10 05:54:27 +00:00
|
|
|
|
2007-03-17 03:10:45 +00:00
|
|
|
extern snd_render_data_t snd_render_data;
|
2007-03-17 07:05:24 +00:00
|
|
|
#define PAINTBUFFER_SIZE 512
|
|
|
|
extern portable_samplepair_t snd_paintbuffer[PAINTBUFFER_SIZE * 2];
|
2007-03-17 03:10:45 +00:00
|
|
|
|
2020-02-11 06:20:49 +00:00
|
|
|
///@}
|
2007-03-17 03:10:45 +00:00
|
|
|
|
2022-06-04 09:45:11 +00:00
|
|
|
void SND_Memory_Init_Cvars (void);
|
|
|
|
int SND_Memory_Init (void);
|
|
|
|
sfxbuffer_t *SND_Memory_AllocBuffer (unsigned samples);
|
2022-06-05 07:57:13 +00:00
|
|
|
void SND_Memory_Free (void *ptr);
|
|
|
|
void SND_Memory_SetTag (void *ptr, int tag);
|
|
|
|
int SND_Memory_Retain (void *ptr);
|
|
|
|
int SND_Memory_Release (void *ptr);
|
|
|
|
int SND_Memory_GetRetainCount (void *ptr) __attribute__((pure));
|
2022-06-04 09:45:11 +00:00
|
|
|
|
2007-03-17 03:10:45 +00:00
|
|
|
/** \defgroup sound_render_sfx Sound sfx
|
|
|
|
\ingroup sound_render_mix
|
|
|
|
*/
|
2020-02-11 06:20:49 +00:00
|
|
|
///@{
|
2022-06-06 03:05:44 +00:00
|
|
|
/** Block sound data. Initializes block fields of sfx.
|
2007-03-18 01:44:46 +00:00
|
|
|
\param sfx
|
|
|
|
\param realname
|
|
|
|
\param info
|
2022-06-08 07:14:12 +00:00
|
|
|
\param load
|
2007-03-18 01:44:46 +00:00
|
|
|
*/
|
2022-06-04 14:55:31 +00:00
|
|
|
void SND_SFX_Block (sfx_t *sfx, char *realname, wavinfo_t info,
|
|
|
|
sfxbuffer_t *(*load) (sfxblock_t *block));
|
2007-03-18 01:44:46 +00:00
|
|
|
|
|
|
|
/** Stream sound data. Initializes streaming fields of sfx.
|
|
|
|
\param sfx
|
|
|
|
\param realname
|
|
|
|
\param info
|
|
|
|
\param open
|
|
|
|
*/
|
2012-05-21 23:23:22 +00:00
|
|
|
void SND_SFX_Stream (sfx_t *sfx, char *realname, wavinfo_t info,
|
2022-06-05 07:57:13 +00:00
|
|
|
sfxbuffer_t *(*open) (sfx_t *sfx));
|
2007-03-18 01:44:46 +00:00
|
|
|
|
|
|
|
/** Open a stream for playback.
|
|
|
|
\param sfx
|
2007-04-04 12:11:41 +00:00
|
|
|
\param file
|
2007-03-18 01:44:46 +00:00
|
|
|
\param read
|
|
|
|
\param seek
|
|
|
|
\param close
|
|
|
|
*/
|
2022-06-05 07:57:13 +00:00
|
|
|
sfxbuffer_t *SND_SFX_StreamOpen (sfx_t *sfx, void *file,
|
|
|
|
long (*read)(void *, float **),
|
|
|
|
int (*seek)(sfxstream_t *, int),
|
|
|
|
void (*close) (sfxbuffer_t *));
|
2007-03-18 01:44:46 +00:00
|
|
|
|
2010-08-11 23:47:03 +00:00
|
|
|
/** Close a stream.
|
2022-06-08 07:14:12 +00:00
|
|
|
\param stream
|
2010-08-11 23:47:03 +00:00
|
|
|
*/
|
2022-06-05 07:57:13 +00:00
|
|
|
void SND_SFX_StreamClose (sfxstream_t *stream);
|
2010-08-11 23:47:03 +00:00
|
|
|
|
2022-06-06 03:05:44 +00:00
|
|
|
/** Load a sound into the system.
|
2021-12-25 02:17:33 +00:00
|
|
|
\param snd sound system state
|
2022-06-06 03:05:44 +00:00
|
|
|
\param sample name of sound to load
|
2007-03-17 03:10:45 +00:00
|
|
|
*/
|
2021-06-23 15:04:02 +00:00
|
|
|
sfx_t *SND_PrecacheSound (snd_t *snd, const char *sample);
|
2007-03-17 03:10:45 +00:00
|
|
|
|
|
|
|
/** Pre-load a sound.
|
2021-12-25 02:17:33 +00:00
|
|
|
\param snd sound system state
|
2007-03-17 03:10:45 +00:00
|
|
|
\param name name of sound to load
|
|
|
|
*/
|
2021-06-23 15:04:02 +00:00
|
|
|
sfx_t *SND_LoadSound (snd_t *snd, const char *name);
|
2007-03-17 03:10:45 +00:00
|
|
|
|
|
|
|
/** Initialize the sfx sub-subsystem
|
2021-12-25 02:17:33 +00:00
|
|
|
\param snd sound system state
|
2007-03-17 03:10:45 +00:00
|
|
|
*/
|
2021-06-23 15:04:02 +00:00
|
|
|
void SND_SFX_Init (snd_t *snd);
|
2023-03-05 08:15:49 +00:00
|
|
|
void SND_SFX_Shutdown (snd_t *snd);
|
2007-03-17 03:10:45 +00:00
|
|
|
|
2020-02-11 06:20:49 +00:00
|
|
|
///@}
|
2007-03-10 05:54:27 +00:00
|
|
|
|
|
|
|
/** \defgroup sound_render_mix_channels Sound channels
|
|
|
|
\ingroup sound_render_mix
|
|
|
|
Output sound is mixed from an number of active sound channels.
|
|
|
|
|
|
|
|
- 0 to MAX_DYNAMIC_CHANNELS-1 <br>
|
|
|
|
normal entity sounds
|
|
|
|
- MAX_DYNAMIC_CHANNELS to MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS -1 <br>
|
|
|
|
water, etc
|
|
|
|
- MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS to total_channels - 1 <br>
|
|
|
|
static sounds
|
|
|
|
*/
|
2020-02-11 06:20:49 +00:00
|
|
|
///@{
|
2007-03-18 10:32:01 +00:00
|
|
|
#define MAX_CHANNELS 512 //!< number of available mixing channels
|
2010-08-24 00:53:54 +00:00
|
|
|
#define MAX_DYNAMIC_CHANNELS 128 //!< number of dynamic channels
|
2007-03-18 10:32:01 +00:00
|
|
|
#define MAX_STATIC_CHANNELS 256 //!< number of static channels
|
2007-03-10 05:54:27 +00:00
|
|
|
extern channel_t snd_channels[MAX_CHANNELS]; //!< pool of available channels
|
|
|
|
extern int snd_total_channels; //!< number of active channels
|
2007-03-17 03:10:45 +00:00
|
|
|
|
|
|
|
/** Allocate a sound channel that can be used for playing sounds.
|
2021-12-25 02:17:33 +00:00
|
|
|
\param snd sound system state
|
2007-03-17 03:10:45 +00:00
|
|
|
*/
|
2022-06-03 06:20:41 +00:00
|
|
|
channel_t *SND_AllocChannel (snd_t *snd);
|
2007-03-17 03:10:45 +00:00
|
|
|
|
2022-06-04 07:17:43 +00:00
|
|
|
void SND_ChannelSetVolume (channel_t *chan, float volume);
|
|
|
|
|
2007-03-17 03:10:45 +00:00
|
|
|
/** Stop a channel from playing.
|
2021-12-25 02:17:33 +00:00
|
|
|
\param snd sound system state
|
2007-03-17 03:10:45 +00:00
|
|
|
\param chan the channel to stop
|
|
|
|
*/
|
2021-06-23 15:04:02 +00:00
|
|
|
void SND_ChannelStop (snd_t *snd, channel_t *chan);
|
2007-03-17 03:10:45 +00:00
|
|
|
|
2021-06-26 07:18:18 +00:00
|
|
|
/** Mark all channels as no longer in use.
|
|
|
|
|
|
|
|
For use by asynchronous output drivers.
|
|
|
|
*/
|
|
|
|
void SND_FinishChannels (void);
|
|
|
|
|
2007-03-18 11:20:47 +00:00
|
|
|
/** Scan channels looking for stopped channels.
|
2021-12-25 02:17:33 +00:00
|
|
|
\param snd sound system state
|
2007-04-07 07:44:07 +00:00
|
|
|
\param wait if true, wait for the channels to be done. if false, force the
|
|
|
|
channels to be done. true is for threaded, false for
|
|
|
|
non-threaded.
|
2007-03-18 11:20:47 +00:00
|
|
|
*/
|
2021-06-23 15:04:02 +00:00
|
|
|
void SND_ScanChannels (snd_t *snd, int wait);
|
2007-03-18 11:20:47 +00:00
|
|
|
|
2007-03-17 03:10:45 +00:00
|
|
|
/** Disable ambient sounds.
|
2021-12-25 02:17:33 +00:00
|
|
|
\param snd sound system state
|
2007-03-17 03:10:45 +00:00
|
|
|
\todo not used, remove?
|
|
|
|
*/
|
2021-06-23 15:04:02 +00:00
|
|
|
void SND_AmbientOff (snd_t *snd);
|
2007-03-17 03:10:45 +00:00
|
|
|
|
|
|
|
/** Enable ambient sounds.
|
2021-12-25 02:17:33 +00:00
|
|
|
\param snd sound system state
|
2007-03-17 03:10:45 +00:00
|
|
|
\todo not used, remove?
|
|
|
|
*/
|
2021-06-23 15:04:02 +00:00
|
|
|
void SND_AmbientOn (snd_t *snd);
|
2007-03-17 03:10:45 +00:00
|
|
|
|
2022-06-06 05:29:14 +00:00
|
|
|
void SND_SetAmbient (snd_t *snd, int amb_channel, sfx_t *sfx);
|
|
|
|
|
2007-03-17 03:10:45 +00:00
|
|
|
/** Update the sound engine with the client's position and orientation and
|
|
|
|
render some sound.
|
2021-12-25 02:17:33 +00:00
|
|
|
\param snd sound system state
|
2022-04-12 12:01:41 +00:00
|
|
|
\param ear Transform for the position and orientation of the stereo
|
|
|
|
sound pickup.
|
2012-04-22 13:20:45 +00:00
|
|
|
\param ambient_sound_level Pointer to 4 bytes indicating the levels at
|
|
|
|
which to play the ambient sounds.
|
2007-03-17 03:10:45 +00:00
|
|
|
*/
|
[scene] Make entity_t just an entity id for ECS
This puts the hierarchy (transform) reference, animation, visibility,
renderer, active, and old_origin data in separate components. There are
a few bugs (crashes on grenade explosions in gl/glsl/vulkan, immediately
in sw, reasons known, missing brush models in vulkan).
While quake doesn't really need an ECS, the direction I want to take QF
does, and it does seem to have improved memory bandwidth a little
(uncertain). However, there's a lot more work to go (especially fixing
the above bugs), but this seems to be a good start.
2022-10-23 01:32:09 +00:00
|
|
|
void SND_SetListener (snd_t *snd, struct transform_s ear,
|
2012-02-13 04:44:29 +00:00
|
|
|
const byte *ambient_sound_level);
|
2007-03-17 03:10:45 +00:00
|
|
|
|
|
|
|
/** Stop all sounds from playing.
|
2021-12-25 02:17:33 +00:00
|
|
|
\param snd sound system state
|
2007-03-17 03:10:45 +00:00
|
|
|
*/
|
2021-06-23 15:04:02 +00:00
|
|
|
void SND_StopAllSounds (snd_t *snd);
|
2007-03-17 03:10:45 +00:00
|
|
|
|
|
|
|
/** Initialize the channels sub-subsystem
|
2021-12-25 02:17:33 +00:00
|
|
|
\param snd sound system state
|
2007-03-17 03:10:45 +00:00
|
|
|
*/
|
2021-06-23 15:04:02 +00:00
|
|
|
void SND_Channels_Init (snd_t *snd);
|
2007-03-17 03:10:45 +00:00
|
|
|
|
|
|
|
/** Start a sound playing.
|
2021-12-25 02:17:33 +00:00
|
|
|
\param snd sound system state
|
2007-03-17 03:10:45 +00:00
|
|
|
\param entnum index of entity the sound is associated with.
|
|
|
|
\param entchannel 0-7
|
|
|
|
- 0 auto (never willingly overrides)
|
|
|
|
- 1 weapon
|
|
|
|
- 2 voice
|
|
|
|
- 3 item
|
|
|
|
- 4 body
|
|
|
|
\param sfx sound to play
|
|
|
|
\param origin 3d coords of where the sound originates
|
|
|
|
\param fvol absolute volume of the sound
|
|
|
|
\param attenuation rate of volume dropoff vs distance
|
|
|
|
*/
|
2021-06-23 15:04:02 +00:00
|
|
|
void SND_StartSound (snd_t *snd, int entnum, int entchannel, sfx_t *sfx,
|
2022-03-30 14:38:01 +00:00
|
|
|
vec4f_t origin, float fvol, float attenuation);
|
2007-03-17 03:10:45 +00:00
|
|
|
|
|
|
|
/** Create a sound generated by the world.
|
2021-12-25 02:17:33 +00:00
|
|
|
\param snd sound system state
|
2007-03-17 03:10:45 +00:00
|
|
|
\param sfx sound to play
|
|
|
|
\param origin 3d coords of where the sound originates
|
|
|
|
\param vol absolute volume of the sound
|
|
|
|
\param attenuation rate of volume dropoff vs distance
|
|
|
|
*/
|
2022-03-30 14:38:01 +00:00
|
|
|
void SND_StaticSound (snd_t *snd, sfx_t *sfx, vec4f_t origin, float vol,
|
2021-06-23 15:04:02 +00:00
|
|
|
float attenuation);
|
2007-03-17 03:10:45 +00:00
|
|
|
/** Stop an entity's sound.
|
2021-12-25 02:17:33 +00:00
|
|
|
\param snd sound system state
|
2007-03-17 03:10:45 +00:00
|
|
|
\param entnum index of entity the sound is associated with.
|
|
|
|
\param entchannel channel to silence
|
|
|
|
*/
|
2021-06-23 15:04:02 +00:00
|
|
|
void SND_StopSound (snd_t *snd, int entnum, int entchannel);
|
2007-03-17 03:10:45 +00:00
|
|
|
|
|
|
|
/** Start a sound local to the client view.
|
2021-12-25 02:17:33 +00:00
|
|
|
\param snd sound system state
|
2007-03-17 03:10:45 +00:00
|
|
|
\param s name of sound to play
|
|
|
|
*/
|
2021-06-23 15:04:02 +00:00
|
|
|
void SND_LocalSound (snd_t *snd, const char *s);
|
2020-02-11 06:20:49 +00:00
|
|
|
///@}
|
2007-03-10 05:54:27 +00:00
|
|
|
|
|
|
|
|
|
|
|
/** \defgroup sound_render_mix Mixer engine.
|
|
|
|
\ingroup sound_render
|
|
|
|
*/
|
2020-02-11 06:20:49 +00:00
|
|
|
///@{
|
2007-03-10 05:54:27 +00:00
|
|
|
|
|
|
|
/** Mix all active channels into the output buffer.
|
2021-12-25 02:17:33 +00:00
|
|
|
\param snd sound system state
|
2007-03-10 05:54:27 +00:00
|
|
|
\param endtime sample time until when to mix
|
|
|
|
*/
|
2021-06-23 15:04:02 +00:00
|
|
|
void SND_PaintChannels(snd_t *snd, unsigned int endtime);
|
2003-01-31 20:51:04 +00:00
|
|
|
|
2007-03-10 05:54:27 +00:00
|
|
|
/** Initialize the scale table for painting of 8 bit samples.
|
2021-12-25 02:17:33 +00:00
|
|
|
\param snd sound system state
|
2007-03-10 05:54:27 +00:00
|
|
|
*/
|
2021-06-23 15:04:02 +00:00
|
|
|
void SND_InitScaletable (snd_t *snd);
|
2007-03-26 11:44:52 +00:00
|
|
|
|
|
|
|
/** Set the paint function of the sfxbuffer
|
2022-06-04 14:55:31 +00:00
|
|
|
\param sb sfxbuffer to set.
|
2007-03-26 11:44:52 +00:00
|
|
|
*/
|
2022-06-04 14:55:31 +00:00
|
|
|
void SND_SetPaint (sfxbuffer_t *sb);
|
2020-02-11 06:20:49 +00:00
|
|
|
///@}
|
2007-03-10 05:54:27 +00:00
|
|
|
|
|
|
|
|
2007-05-07 05:20:24 +00:00
|
|
|
/** \defgroup sound_render_resample Resampling functions
|
2007-03-10 05:54:27 +00:00
|
|
|
\ingroup sound_render
|
|
|
|
*/
|
2020-02-11 06:20:49 +00:00
|
|
|
///@{
|
2022-06-04 14:55:31 +00:00
|
|
|
|
2022-06-05 07:57:13 +00:00
|
|
|
unsigned SND_ResamplerFrames (const sfx_t *sfx, unsigned frames);
|
2022-06-04 14:55:31 +00:00
|
|
|
|
2010-08-11 23:45:09 +00:00
|
|
|
/** Set up the various parameters that depend on the actual sample rate.
|
2022-06-04 14:55:31 +00:00
|
|
|
\param sb buffer to setup
|
2010-08-11 23:45:09 +00:00
|
|
|
\param streamed non-zero if this is for a stream.
|
|
|
|
*/
|
2022-06-04 14:55:31 +00:00
|
|
|
void SND_SetupResampler (sfxbuffer_t *sb, int streamed);
|
2010-08-11 23:45:09 +00:00
|
|
|
|
2010-08-11 23:47:03 +00:00
|
|
|
/** Free memory allocated for the resampler.
|
|
|
|
\param stream stream to pulldown
|
|
|
|
*/
|
|
|
|
void SND_PulldownResampler (sfxstream_t *stream);
|
|
|
|
|
2010-08-11 23:44:34 +00:00
|
|
|
/** Copy/resample data into buffer, resampling as necessary.
|
2022-06-04 14:55:31 +00:00
|
|
|
\param sb buffer to write resampled sound
|
2007-03-10 05:54:27 +00:00
|
|
|
\param data raw sample data
|
2010-08-11 23:44:34 +00:00
|
|
|
\param length number of frames to resample
|
2007-03-10 05:54:27 +00:00
|
|
|
*/
|
2022-06-04 14:55:31 +00:00
|
|
|
void SND_Resample (sfxbuffer_t *sb, float *data, int length);
|
2007-03-10 05:54:27 +00:00
|
|
|
|
2010-08-11 23:44:34 +00:00
|
|
|
/** Convert integer sample data to float sample data.
|
|
|
|
\param idata integer data buffer
|
|
|
|
\param fdata float data buffer
|
|
|
|
\param frames number of frames
|
|
|
|
\param channels number of channels per frame
|
|
|
|
\param width bytes per channel
|
2007-03-10 05:54:27 +00:00
|
|
|
*/
|
2021-06-23 15:04:02 +00:00
|
|
|
void SND_Convert (byte *idata, float *fdata, int frames,
|
|
|
|
int channels, int width);
|
2020-02-11 06:20:49 +00:00
|
|
|
///@}
|
2003-01-31 20:51:04 +00:00
|
|
|
|
|
|
|
|
2007-03-10 05:54:27 +00:00
|
|
|
/** \defgroup sound_render_load Sound loading functions
|
|
|
|
\ingroup sound_render
|
|
|
|
*/
|
2020-02-11 06:20:49 +00:00
|
|
|
///@{
|
2007-03-10 05:54:27 +00:00
|
|
|
/** Load the referenced sound.
|
|
|
|
\param sfx sound reference
|
2010-08-08 03:02:55 +00:00
|
|
|
\return 0 if ok, -1 on error
|
2007-03-10 05:54:27 +00:00
|
|
|
*/
|
2010-08-08 03:02:55 +00:00
|
|
|
int SND_Load (sfx_t *sfx);
|
2007-03-10 05:54:27 +00:00
|
|
|
|
|
|
|
/** Load the referenced sound from the specified Ogg file.
|
|
|
|
\param file pre-opened Ogg file
|
|
|
|
\param sfx sound reference
|
|
|
|
\param realname path of sound file should it need to be re-opened
|
2010-08-08 03:02:55 +00:00
|
|
|
\return 0 if ok, -1 on error
|
2007-03-10 05:54:27 +00:00
|
|
|
*/
|
2010-08-08 03:02:55 +00:00
|
|
|
int SND_LoadOgg (QFile *file, sfx_t *sfx, char *realname);
|
2007-03-10 05:54:27 +00:00
|
|
|
|
|
|
|
/** Load the referenced sound from the specified FLAC file.
|
|
|
|
\param file pre-opened FLAC file
|
|
|
|
\param sfx sound reference
|
|
|
|
\param realname path of sound file should it need to be re-opened
|
2010-08-08 03:02:55 +00:00
|
|
|
\return 0 if ok, -1 on error
|
2007-03-10 05:54:27 +00:00
|
|
|
*/
|
2010-08-08 03:02:55 +00:00
|
|
|
int SND_LoadFLAC (QFile *file, sfx_t *sfx, char *realname);
|
2007-03-10 05:54:27 +00:00
|
|
|
|
|
|
|
/** Load the referenced sound from the specified WAV file.
|
|
|
|
\param file pre-opened WAV file
|
|
|
|
\param sfx sound reference
|
|
|
|
\param realname path of sound file should it need to be re-opened
|
2010-08-08 03:02:55 +00:00
|
|
|
\return 0 if ok, -1 on error
|
2007-03-10 05:54:27 +00:00
|
|
|
*/
|
2010-08-08 03:02:55 +00:00
|
|
|
int SND_LoadWav (QFile *file, sfx_t *sfx, char *realname);
|
2007-03-10 05:54:27 +00:00
|
|
|
|
|
|
|
/** Load the referenced sound from the specified MIDI file.
|
|
|
|
\param file pre-opened MIDI file
|
|
|
|
\param sfx sound reference
|
|
|
|
\param realname path of sound file should it need to be re-opened
|
2010-08-08 03:02:55 +00:00
|
|
|
\return 0 if ok, -1 on error
|
2007-03-10 05:54:27 +00:00
|
|
|
*/
|
2021-06-23 15:14:33 +00:00
|
|
|
int SND_LoadMidi (QFile *file, sfx_t *sfx, char *realname);
|
2020-02-11 06:20:49 +00:00
|
|
|
///@}
|
2003-04-11 01:17:48 +00:00
|
|
|
|
2022-06-06 03:05:44 +00:00
|
|
|
/** \defgroup sound_render_block_stream Block/Stream Functions.
|
2007-03-10 05:54:27 +00:00
|
|
|
\ingroup sound_render
|
|
|
|
*/
|
2020-02-11 06:20:49 +00:00
|
|
|
///@{
|
2022-06-06 03:05:44 +00:00
|
|
|
/** Retrieve wavinfo from a block-loaded sound.
|
2007-03-10 05:54:27 +00:00
|
|
|
\param sfx sound reference
|
|
|
|
\return pointer to sound's wavinfo
|
|
|
|
*/
|
2022-06-06 03:05:44 +00:00
|
|
|
wavinfo_t *SND_BlockWavinfo (const sfx_t *sfx) __attribute__((pure));
|
2007-03-10 05:54:27 +00:00
|
|
|
|
|
|
|
/** Retrieve wavinfo from a streamed sound.
|
|
|
|
\param sfx sound reference
|
|
|
|
\return pointer to sound's wavinfo
|
|
|
|
*/
|
2022-06-05 07:57:13 +00:00
|
|
|
wavinfo_t *SND_StreamWavinfo (const sfx_t *sfx) __attribute__((pure));
|
2007-03-10 05:54:27 +00:00
|
|
|
|
|
|
|
/** Advance the position with the stream, updating the ring buffer as
|
|
|
|
necessary. Null for chached sounds.
|
|
|
|
\param buffer "this"
|
|
|
|
\param count number of samples to advance
|
|
|
|
*/
|
2010-08-13 01:48:20 +00:00
|
|
|
int SND_StreamAdvance (sfxbuffer_t *buffer, unsigned int count);
|
2003-01-31 20:51:04 +00:00
|
|
|
|
2007-03-10 05:54:27 +00:00
|
|
|
/** Seek to an absolute position within the stream, resetting the ring
|
|
|
|
buffer.
|
|
|
|
\param buffer "this"
|
|
|
|
\param pos sample position with the stream
|
|
|
|
*/
|
|
|
|
void SND_StreamSetPos (sfxbuffer_t *buffer, unsigned int pos);
|
2020-02-11 06:20:49 +00:00
|
|
|
///@}
|
2007-03-10 01:06:00 +00:00
|
|
|
|
2011-07-23 06:56:22 +00:00
|
|
|
#endif//__snd_internal_h
|