mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-07 12:50:38 +08:00
Merge branch 'theevolk-feature-soundapi' of github.com:ShadowOfEVolk/xash3d-fwgs
This commit is contained in:
185
common/sound_api.h
Normal file
185
common/sound_api.h
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
sound_api.h - Xash3D extension for client sound interface
|
||||
Copyright (C) 2026 Xash3D FWGS Developers
|
||||
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
#ifndef SOUND_API_H
|
||||
#define SOUND_API_H
|
||||
|
||||
#include "xash3d_types.h"
|
||||
|
||||
// Experimental implementation, backward compatibility is not guaranteed.
|
||||
#define CL_SOUND_INTERFACE_VERSION 1
|
||||
|
||||
#define FL_VOXWORD_IN_CACHE BIT( 0 ) // if set, it was loaded prior and shouldn't be freed
|
||||
|
||||
#define FL_CHAN_USE_LOOP BIT( 0 ) // don't loop default and local sounds
|
||||
#define FL_CHAN_STATIC_SOUND BIT( 1 ) // use origin instead of fetching entnum's origin
|
||||
#define FL_CHAN_LOCAL_SOUND BIT( 2 ) // it's a local menu sound (not looped, not paused)
|
||||
#define FL_CHAN_SENTENCE_FINISHED BIT( 4 ) // if set, finished playing sentence
|
||||
#define FL_CHAN_FINISHED BIT( 5 ) // if set, finished playing single word
|
||||
|
||||
typedef int sound_t;
|
||||
|
||||
typedef struct portable_samplepair_s
|
||||
{
|
||||
int left;
|
||||
int right;
|
||||
} portable_samplepair_t;
|
||||
|
||||
typedef struct sfx_s
|
||||
{
|
||||
char name[MAX_QPATH];
|
||||
wavdata_t *cache;
|
||||
|
||||
int servercount;
|
||||
uint hashValue;
|
||||
struct sfx_s *hashNext;
|
||||
} sfx_t;
|
||||
|
||||
typedef struct voxword_s
|
||||
{
|
||||
sfx_t *sfx;
|
||||
uint16_t volume; // volume percent
|
||||
uint16_t pitch; // pitch shift percent (keep large for extra chipmunk fun)
|
||||
uint8_t timecompress; // percent of skipped data (speeds up playback without pitch shift)
|
||||
uint8_t start; // percent at which playback starts
|
||||
uint8_t end; // percent at which playback ends
|
||||
uint8_t flags;
|
||||
} voxword_t;
|
||||
|
||||
typedef struct channel_s
|
||||
{
|
||||
char name[16]; // keep sentence name
|
||||
sfx_t *sfx; // sfx number
|
||||
|
||||
vec3_t origin; // only use if fixed_origin is set
|
||||
float dist_mult; // distance multiplier (attenuation/clipK)
|
||||
|
||||
int entchannel; // sound channel (CHAN_STREAM, CHAN_VOICE, etc.)
|
||||
uint flags;
|
||||
short entnum; // entity soundsource
|
||||
short master_vol; // 0-255 master volume
|
||||
short leftvol; // 0-255 left volume
|
||||
short rightvol; // 0-255 right volume
|
||||
short basePitch; // base pitch percent (100% is normal pitch playback)
|
||||
byte word_index;
|
||||
|
||||
// HACKHACK: count when this channel became inaudible
|
||||
// to not free it when it could be respatialized soon
|
||||
#define MAX_CHANNEL_INAUDIBLE_TIME 0.1f
|
||||
float inauduble_free_time;
|
||||
|
||||
double sample;
|
||||
double forced_end;
|
||||
wavdata_t *data;
|
||||
voxword_t *words; // dynamically allocated, (num_words + 1) entries, null sfx terminates
|
||||
|
||||
uintptr_t engine_reserved[8]; // only for engine developers
|
||||
uintptr_t game_reserved[8]; // free space for game developers
|
||||
} channel_t;
|
||||
|
||||
typedef struct rawchan_s
|
||||
{
|
||||
short entnum;
|
||||
short master_vol;
|
||||
short leftvol; // 0-255 left volume
|
||||
short rightvol; // 0-255 right volume
|
||||
float dist_mult; // distance multiplier (attenuation/clipK)
|
||||
vec3_t origin; // only use if fixed_origin is set
|
||||
volatile uint s_rawend;
|
||||
float oldtime; // catch time jumps
|
||||
|
||||
uintptr_t engine_reserved[8]; // only for engine developers
|
||||
uintptr_t game_reserved[8]; // free space for game developers
|
||||
|
||||
size_t max_samples; // buffer length
|
||||
portable_samplepair_t rawsamples[]; // variable sized
|
||||
} rawchan_t;
|
||||
|
||||
typedef struct snd_format_s
|
||||
{
|
||||
uint speed;
|
||||
byte width;
|
||||
byte channels;
|
||||
} snd_format_t;
|
||||
|
||||
typedef struct snd_globals_s
|
||||
{
|
||||
// dma
|
||||
const char *backend_name;
|
||||
byte *buffer;
|
||||
snd_format_t format;
|
||||
qboolean initialized; // sound engine is active
|
||||
int samples; // mono samples in buffer
|
||||
int samplepos; // in mono samples
|
||||
|
||||
int paintedtime; // total samples that have been mixed at speed
|
||||
int soundtime; // total samples that have been played out to hardware at dma speed
|
||||
|
||||
// listener (client, camera, etc)
|
||||
vec3_t origin;
|
||||
vec3_t forward, right, up;
|
||||
int entnum;
|
||||
qboolean streaming; // playing AVI-file
|
||||
qboolean stream_paused; // pause only background track
|
||||
|
||||
// SoundAPI shared pointers
|
||||
channel_t *const channels;
|
||||
int max_channels;
|
||||
int total_channels;
|
||||
rawchan_t **const raw_channels;
|
||||
int max_raw_channels;
|
||||
sound_t ambient_sfx[NUM_AMBIENTS];
|
||||
qboolean have_ambient_sfx;
|
||||
} snd_globals_t;
|
||||
|
||||
// API from engine to client (client calls these)
|
||||
typedef struct sound_api_s
|
||||
{
|
||||
qboolean (*CL_GetEntitySpatialization)( channel_t *ch );
|
||||
sfx_t* (*S_GetSfxByHandle)( sound_t handle );
|
||||
} sound_api_t;
|
||||
|
||||
// Callbacks from client to engine (engine calls these when custom sound is active)
|
||||
typedef struct sound_interface_s
|
||||
{
|
||||
int version;
|
||||
|
||||
qboolean (*pfnS_Init)( snd_globals_t *globals );
|
||||
void (*pfnS_Shutdown)( void );
|
||||
void (*pfnS_UpdateSound)( void );
|
||||
/* Full paint: endtime (sample pairs), dma buffer, paintedtime in/out. Client does mix + transfer to dma.buffer. */
|
||||
void (*pfnS_PaintChannels)( int endtime );
|
||||
void (*pfnS_UpdateChannel)( int ch_idx, const channel_t *ch, sound_t handle ); // ch=NULL -> channel freed
|
||||
void (*pfnS_UpdateRawChannel)( int raw_idx, rawchan_t *ch ); // ch=NULL -> channel freed
|
||||
void (*pfnS_Spatialize)( channel_t *ch );
|
||||
void (*pfnS_FreeSound)( sfx_t *sfx, sound_t handle );
|
||||
} sound_interface_t;
|
||||
|
||||
#endif // SOUND_API_H
|
||||
@@ -23,6 +23,12 @@ struct mstudioevent_s;
|
||||
struct engine_studio_api_s;
|
||||
struct r_studio_interface_s;
|
||||
|
||||
struct sound_api_s;
|
||||
struct sound_interface_s;
|
||||
|
||||
typedef struct sound_api_s sound_api_t;
|
||||
typedef struct sound_interface_s sound_interface_t;
|
||||
|
||||
// NOTE: ordering is important!
|
||||
typedef struct cldll_func_s
|
||||
{
|
||||
@@ -74,6 +80,8 @@ typedef struct cldll_func_s
|
||||
int (*pfnTouchEvent)( int type, int fingerID, float x, float y, float dx, float dy );
|
||||
void (*pfnMoveEvent)( float forwardmove, float sidemove );
|
||||
void (*pfnLookEvent)( float relyaw, float relpitch );
|
||||
// Sound API
|
||||
int (*pfnGetSoundInterface)( int version, const sound_api_t *api, sound_interface_t *callback );
|
||||
} cldll_func_t;
|
||||
|
||||
#endif//CDLL_EXP_H
|
||||
|
||||
@@ -105,6 +105,7 @@ static const dllfunc_t cdll_new_exports[] = // allowed only in SDK 2.3 and high
|
||||
{ "IN_ClientTouchEvent", (void **)&clgame.dllFuncs.pfnTouchEvent}, // Xash3D FWGS ext
|
||||
{ "IN_ClientMoveEvent", (void **)&clgame.dllFuncs.pfnMoveEvent}, // Xash3D FWGS ext
|
||||
{ "IN_ClientLookEvent", (void **)&clgame.dllFuncs.pfnLookEvent}, // Xash3D FWGS ext
|
||||
{ "HUD_GetSoundInterface", (void **)&clgame.dllFuncs.pfnGetSoundInterface }, // Xash3D ext
|
||||
};
|
||||
|
||||
static void pfnSPR_DrawHoles( int frame, int x, int y, const wrect_t *prc );
|
||||
|
||||
@@ -3678,8 +3678,6 @@ void CL_Init( void )
|
||||
CL_InitLocal();
|
||||
|
||||
VID_Init(); // init video
|
||||
S_Init(); // init sound
|
||||
Voice_Init( VOICE_DEFAULT_CODEC, 3, true ); // init voice (do not open the device)
|
||||
|
||||
// unreliable buffer. unsed for unreliable commands and voice stream
|
||||
MSG_Init( &cls.datagram, "cls.datagram", cls.datagram_buf, sizeof( cls.datagram_buf ));
|
||||
@@ -3689,6 +3687,9 @@ void CL_Init( void )
|
||||
if( !CL_LoadProgs( libpath ))
|
||||
Host_Error( "can't initialize %s: %s\n", libpath, COM_GetLibraryError( ));
|
||||
|
||||
S_Init(); // init sound
|
||||
Voice_Init( VOICE_DEFAULT_CODEC, 3, true ); // init voice (do not open the device)
|
||||
|
||||
ID_Init();
|
||||
SteamBroker_Init();
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ GNU General Public License for more details.
|
||||
#include "pm_defs.h"
|
||||
#include "ref_params.h"
|
||||
#include "render_api.h"
|
||||
#include "sound_api.h"
|
||||
#include "cdll_exp.h"
|
||||
#include "screenfade.h"
|
||||
#include "protocol.h"
|
||||
@@ -454,6 +455,7 @@ typedef struct
|
||||
void *hInstance; // pointer to client.dll
|
||||
cldll_func_t dllFuncs; // dll exported funcs
|
||||
render_interface_t drawFuncs; // custom renderer support
|
||||
sound_interface_t soundFuncs; // custom sound support
|
||||
poolhandle_t mempool; // client edicts pool
|
||||
string mapname; // map name
|
||||
string maptitle; // display map title
|
||||
|
||||
@@ -232,6 +232,12 @@ void S_FreeSound( sfx_t *sfx )
|
||||
prev = &hashSfx->hashNext;
|
||||
}
|
||||
|
||||
if( clgame.soundFuncs.pfnS_FreeSound )
|
||||
{
|
||||
clgame.soundFuncs.pfnS_FreeSound( sfx, sfx - s_knownSfx );
|
||||
return;
|
||||
}
|
||||
|
||||
if( sfx->cache )
|
||||
FS_FreeSound( sfx->cache );
|
||||
memset( sfx, 0, sizeof( *sfx ));
|
||||
|
||||
@@ -159,6 +159,18 @@ static qboolean S_IsClient( int entnum )
|
||||
return entnum == snd.entnum;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_NotifyChannelUpdate
|
||||
=================
|
||||
*/
|
||||
static void S_NotifyChannelUpdate( int ch_idx, const channel_t *ch, sound_t handle )
|
||||
{
|
||||
if( !clgame.soundFuncs.pfnS_UpdateChannel )
|
||||
return;
|
||||
|
||||
clgame.soundFuncs.pfnS_UpdateChannel( ch_idx, ch, handle );
|
||||
}
|
||||
|
||||
// free channel so that it may be allocated by the
|
||||
// next request to play a sound. If sound is a
|
||||
@@ -171,6 +183,8 @@ S_FreeChannel
|
||||
*/
|
||||
void S_FreeChannel( channel_t *ch )
|
||||
{
|
||||
S_NotifyChannelUpdate( ch - snd.channels, NULL, -1 );
|
||||
|
||||
// free the currently loaded word's audio cache before nuking the channel
|
||||
if( ch->words )
|
||||
VOX_FreeWord( ch );
|
||||
@@ -185,6 +199,19 @@ void S_FreeChannel( channel_t *ch )
|
||||
SND_CloseMouth( ch );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_NotifyRawChannelUpdate
|
||||
=================
|
||||
*/
|
||||
static void S_NotifyRawChannelUpdate( int raw_idx, rawchan_t *ch )
|
||||
{
|
||||
if( !clgame.soundFuncs.pfnS_UpdateRawChannel )
|
||||
return;
|
||||
|
||||
clgame.soundFuncs.pfnS_UpdateRawChannel( raw_idx, ch );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_UpdateSoundFade
|
||||
@@ -531,6 +558,12 @@ SND_Spatialize
|
||||
*/
|
||||
static void SND_Spatialize( channel_t *ch )
|
||||
{
|
||||
if( clgame.soundFuncs.pfnS_Spatialize )
|
||||
{
|
||||
clgame.soundFuncs.pfnS_Spatialize( ch );
|
||||
return;
|
||||
}
|
||||
|
||||
// anything coming from the view entity will allways be full volume
|
||||
if( S_IsClient( ch->entnum ))
|
||||
{
|
||||
@@ -700,6 +733,8 @@ void S_StartSound( const vec3_t pos, int ent, int chan, sound_t handle, float fv
|
||||
}
|
||||
}
|
||||
|
||||
S_NotifyChannelUpdate( target_chan - snd.channels, target_chan, handle );
|
||||
|
||||
// Init client entity mouth movement vars
|
||||
SND_InitMouth( ent, chan );
|
||||
}
|
||||
@@ -814,6 +849,8 @@ void S_RestoreSound( const vec3_t pos, int ent, int chan, sound_t handle, float
|
||||
target_chan->sample = sample;
|
||||
target_chan->forced_end = end;
|
||||
|
||||
S_NotifyChannelUpdate( target_chan - snd.channels, target_chan, handle );
|
||||
|
||||
// Init client entity mouth movement vars
|
||||
SND_InitMouth( ent, chan );
|
||||
}
|
||||
@@ -907,6 +944,7 @@ void S_AmbientSound( const vec3_t pos, int ent, sound_t handle, float fvol, floa
|
||||
ch->entchannel = CHAN_STATIC;
|
||||
ch->basePitch = pitch;
|
||||
|
||||
S_NotifyChannelUpdate( ch - snd.channels, ch, handle );
|
||||
SND_Spatialize( ch );
|
||||
}
|
||||
|
||||
@@ -1173,6 +1211,8 @@ rawchan_t *S_FindRawChannel( int entnum, qboolean create )
|
||||
ch->entnum = entnum;
|
||||
ch->s_rawend = 0;
|
||||
|
||||
S_NotifyRawChannelUpdate( best, ch );
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
@@ -1522,7 +1562,10 @@ static void S_UpdateChannels( void )
|
||||
endtime -= ( endtime - snd.paintedtime ) & 0x3;
|
||||
}
|
||||
|
||||
S_PaintChannels( endtime );
|
||||
if( clgame.soundFuncs.pfnS_PaintChannels )
|
||||
clgame.soundFuncs.pfnS_PaintChannels( endtime );
|
||||
else
|
||||
S_PaintChannels( endtime );
|
||||
|
||||
SNDDMA_Submit();
|
||||
}
|
||||
@@ -1568,6 +1611,9 @@ void SND_UpdateSound( void )
|
||||
{
|
||||
if( !snd.initialized ) return;
|
||||
|
||||
if( clgame.soundFuncs.pfnS_UpdateSound )
|
||||
clgame.soundFuncs.pfnS_UpdateSound();
|
||||
|
||||
// if the loading plaque is up, clear everything
|
||||
// out to make sure we aren't looping a dirty
|
||||
// dma buffer while loading
|
||||
@@ -1889,6 +1935,38 @@ static void S_VoiceRecordStop_f( void )
|
||||
Voice_RecordStop();
|
||||
}
|
||||
|
||||
static const sound_api_t gSoundAPI = {
|
||||
CL_GetEntitySpatialization,
|
||||
S_GetSfxByHandle,
|
||||
};
|
||||
|
||||
/*
|
||||
================
|
||||
S_InitSoundAPI
|
||||
================
|
||||
*/
|
||||
static qboolean S_InitSoundAPI( void )
|
||||
{
|
||||
// make sure what sound functions is cleared
|
||||
memset( &clgame.soundFuncs, 0, sizeof( clgame.soundFuncs ));
|
||||
|
||||
if( clgame.dllFuncs.pfnGetSoundInterface )
|
||||
{
|
||||
if( clgame.dllFuncs.pfnGetSoundInterface( CL_SOUND_INTERFACE_VERSION, &gSoundAPI, &clgame.soundFuncs ))
|
||||
{
|
||||
Con_Reportf( "%s: ^2initailized extended SoundAPI ^7ver. %i\n", __func__, CL_SOUND_INTERFACE_VERSION );
|
||||
return true;
|
||||
}
|
||||
|
||||
Con_Reportf( "%s: ^1failed to initialize extended SoundAPI ^7ver. %i\n", __func__, CL_SOUND_INTERFACE_VERSION );
|
||||
|
||||
// make sure what sound functions is cleared
|
||||
memset( &clgame.soundFuncs, 0, sizeof( clgame.soundFuncs ));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
S_Init
|
||||
@@ -1949,6 +2027,11 @@ qboolean S_Init( void )
|
||||
S_InitSounds ();
|
||||
VOX_Init ();
|
||||
|
||||
S_InitSoundAPI();
|
||||
|
||||
if( clgame.soundFuncs.pfnS_Init )
|
||||
clgame.soundFuncs.pfnS_Init( &snd );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1973,6 +2056,9 @@ void S_Shutdown( void )
|
||||
Cmd_RemoveCommand( "speak" );
|
||||
Cmd_RemoveCommand( "spk" );
|
||||
|
||||
if( clgame.soundFuncs.pfnS_Shutdown )
|
||||
clgame.soundFuncs.pfnS_Shutdown();
|
||||
|
||||
S_StopAllSounds (false);
|
||||
S_FreeRawChannels ();
|
||||
S_FreeSounds ();
|
||||
|
||||
@@ -19,6 +19,7 @@ GNU General Public License for more details.
|
||||
extern poolhandle_t sndpool;
|
||||
|
||||
#include "xash3d_mathlib.h"
|
||||
#include "sound_api.h"
|
||||
|
||||
// sound engine rate defines
|
||||
#define SOUND_11k 11025 // 11khz sample rate
|
||||
@@ -38,129 +39,6 @@ extern poolhandle_t sndpool;
|
||||
|
||||
#define CLIP16( x ) bound( SHRT_MIN + 8, x, SHRT_MAX - 8 )
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int left;
|
||||
int right;
|
||||
} portable_samplepair_t;
|
||||
|
||||
typedef struct sfx_s
|
||||
{
|
||||
char name[MAX_QPATH];
|
||||
wavdata_t *cache;
|
||||
|
||||
int servercount;
|
||||
uint hashValue;
|
||||
struct sfx_s *hashNext;
|
||||
} sfx_t;
|
||||
|
||||
#define FL_VOXWORD_IN_CACHE BIT( 0 ) // if set, it was loaded prior and shouldn't be freed
|
||||
|
||||
typedef struct voxword_s
|
||||
{
|
||||
sfx_t *sfx;
|
||||
uint16_t volume; // volume percent
|
||||
uint16_t pitch; // pitch shift percent (keep large for extra chipmunk fun)
|
||||
uint8_t timecompress; // percent of skipped data (speeds up playback without pitch shift)
|
||||
uint8_t start; // percent at which playback starts
|
||||
uint8_t end; // percent at which playback ends
|
||||
uint8_t flags;
|
||||
} voxword_t;
|
||||
|
||||
typedef struct snd_format_s
|
||||
{
|
||||
uint speed;
|
||||
byte width;
|
||||
byte channels;
|
||||
} snd_format_t;
|
||||
|
||||
typedef struct rawchan_s
|
||||
{
|
||||
short entnum;
|
||||
short master_vol;
|
||||
short leftvol; // 0-255 left volume
|
||||
short rightvol; // 0-255 right volume
|
||||
float dist_mult; // distance multiplier (attenuation/clipK)
|
||||
vec3_t origin; // only use if fixed_origin is set
|
||||
volatile uint s_rawend;
|
||||
float oldtime; // catch time jumps
|
||||
|
||||
uintptr_t engine_reserved[8]; // only for engine developers
|
||||
uintptr_t game_reserved[8]; // free space for game developers
|
||||
|
||||
size_t max_samples; // buffer length
|
||||
portable_samplepair_t rawsamples[]; // variable sized
|
||||
} rawchan_t;
|
||||
|
||||
#define FL_CHAN_USE_LOOP BIT( 0 ) // don't loop default and local sounds
|
||||
#define FL_CHAN_STATIC_SOUND BIT( 1 ) // use origin instead of fetching entnum's origin
|
||||
#define FL_CHAN_LOCAL_SOUND BIT( 2 ) // it's a local menu sound (not looped, not paused)
|
||||
#define FL_CHAN_SENTENCE_FINISHED BIT( 4 ) // if set, finished playing sentence
|
||||
#define FL_CHAN_FINISHED BIT( 5 ) // if set, finished playing single word
|
||||
|
||||
typedef struct channel_s
|
||||
{
|
||||
char name[16]; // keep sentence name
|
||||
sfx_t *sfx; // sfx number
|
||||
|
||||
vec3_t origin; // only use if fixed_origin is set
|
||||
float dist_mult; // distance multiplier (attenuation/clipK)
|
||||
|
||||
int entchannel; // sound channel (CHAN_STREAM, CHAN_VOICE, etc.)
|
||||
uint flags;
|
||||
short entnum; // entity soundsource
|
||||
short master_vol; // 0-255 master volume
|
||||
short leftvol; // 0-255 left volume
|
||||
short rightvol; // 0-255 right volume
|
||||
short basePitch; // base pitch percent (100% is normal pitch playback)
|
||||
byte word_index;
|
||||
|
||||
// HACKHACK: count when this channel became inaudible
|
||||
// to not free it when it could be respatialized soon
|
||||
#define MAX_CHANNEL_INAUDIBLE_TIME 0.1f
|
||||
float inauduble_free_time;
|
||||
|
||||
double sample;
|
||||
double forced_end;
|
||||
wavdata_t *data;
|
||||
voxword_t *words; // dynamically allocated, (num_words + 1) entries, null sfx terminates
|
||||
|
||||
uintptr_t engine_reserved[8]; // only for engine developers
|
||||
uintptr_t game_reserved[8]; // free space for game developers
|
||||
} channel_t;
|
||||
|
||||
typedef int sound_t;
|
||||
|
||||
typedef struct snd_globals_s
|
||||
{
|
||||
// dma
|
||||
const char *backend_name;
|
||||
byte *buffer;
|
||||
snd_format_t format;
|
||||
qboolean initialized; // sound engine is active
|
||||
int samples; // mono samples in buffer
|
||||
int samplepos; // in mono samples
|
||||
|
||||
int paintedtime; // total samples that have been mixed at speed
|
||||
int soundtime; // total samples that have been played out to hardware at dma speed
|
||||
|
||||
// listener (client, camera, etc)
|
||||
vec3_t origin;
|
||||
vec3_t forward, right, up;
|
||||
int entnum;
|
||||
qboolean streaming; // playing AVI-file
|
||||
qboolean stream_paused; // pause only background track
|
||||
|
||||
// SoundAPI shared pointers
|
||||
channel_t *const channels;
|
||||
int max_channels;
|
||||
int total_channels;
|
||||
rawchan_t **const raw_channels;
|
||||
int max_raw_channels;
|
||||
sound_t ambient_sfx[NUM_AMBIENTS];
|
||||
qboolean have_ambient_sfx;
|
||||
} snd_globals_t;
|
||||
|
||||
//====================================================================
|
||||
|
||||
#define MAX_DYNAMIC_CHANNELS (60 + NUM_AMBIENTS)
|
||||
|
||||
Reference in New Issue
Block a user