2004-08-23 00:15:46 +00:00
/*
Copyright ( C ) 1996 - 1997 Id Software , Inc .
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
2005-06-14 04:52:10 +00:00
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
2004-08-23 00:15:46 +00:00
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 the Free Software
Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
// sound.h -- client sound i/o functions
# ifndef __SOUND__
# define __SOUND__
// !!! if this is changed, it much be changed in asm_i386.h too !!!
2011-07-06 01:40:40 +00:00
# define MAXSOUNDCHANNELS 8 //on a per device basis
2004-08-23 00:15:46 +00:00
// !!! if this is changed, it much be changed in asm_i386.h too !!!
struct sfx_s ;
/*typedef struct
{
int left ;
int right ;
} portable_samplepair_t ;
*/
typedef struct
{
int s [ MAXSOUNDCHANNELS ] ;
} portable_samplegroup_t ;
typedef struct {
2012-02-27 12:23:15 +00:00
struct sfxcache_s * ( * decodedata ) ( struct sfx_s * sfx , struct sfxcache_s * buf , int start , int length ) ; //retrurn true when done.
2004-08-23 00:15:46 +00:00
void ( * abort ) ( struct sfx_s * sfx ) ; //it's not playing elsewhere. free entirly
void * buf ;
} sfxdecode_t ;
typedef struct sfx_s
{
char name [ MAX_OSPATH ] ;
2010-03-14 14:35:56 +00:00
# ifdef AVAIL_OPENAL
unsigned int openal_buffer ;
# endif
2012-02-27 12:23:15 +00:00
qboolean failedload : 1 ; //no more super-spammy
qboolean touched : 1 ; //if the sound is still relevent
sfxdecode_t decoder ;
2004-08-23 00:15:46 +00:00
} sfx_t ;
// !!! if this is changed, it much be changed in asm_i386.h too !!!
typedef struct sfxcache_s
{
2012-09-30 05:52:03 +00:00
unsigned int length ; //sample count
unsigned int loopstart ; //-1 or sample index to begin looping at once the sample ends
2012-02-27 12:23:15 +00:00
unsigned int speed ;
unsigned int width ;
unsigned int numchannels ;
unsigned int soundoffset ; //byte index into the sound
qbyte * data ; // variable sized
2004-08-23 00:15:46 +00:00
} sfxcache_t ;
typedef struct
{
2006-09-17 00:59:22 +00:00
// qboolean gamealive;
// qboolean soundalive;
// qboolean splitbuffer;
2012-02-27 12:23:15 +00:00
int numchannels ; // this many samples per frame
2006-09-17 00:59:22 +00:00
int samples ; // mono samples in buffer (individual, non grouped)
// int submission_chunk; // don't mix less than this #
2004-08-23 00:15:46 +00:00
int samplepos ; // in mono samples
int samplebits ;
2012-02-27 12:23:15 +00:00
int speed ; // this many frames per second
unsigned char * buffer ; // pointer to mixed pcm buffer (not directly used by mixer)
2004-08-23 00:15:46 +00:00
} dma_t ;
2012-02-27 12:23:15 +00:00
# define PITCHSHIFT 6 /*max audio file length = (1<<32>>PITCHSHIFT)/KHZ*/
2010-11-06 23:05:29 +00:00
2013-05-31 01:16:07 +00:00
# define CF_ABSVOLUME 1 // ignores volume cvar.
2004-08-23 00:15:46 +00:00
typedef struct
{
sfx_t * sfx ; // sfx number
2013-05-31 01:16:07 +00:00
int vol [ MAXSOUNDCHANNELS ] ; // volume, .8 fixed point.
2012-02-27 12:23:15 +00:00
int start ; // start time in global paintsamples
2010-11-06 23:05:29 +00:00
int pos ; // sample position in sfx, <0 means delay sound start (shifted up by 8)
int rate ; // 24.8 fixed point rate scaling
2013-05-31 01:16:07 +00:00
int flags ; // cf_ flags
2004-08-23 00:15:46 +00:00
int looping ; // where to loop, -1 = no looping
int entnum ; // to allow overriding a specific sound
int entchannel ; //int audio_fd
vec3_t origin ; // origin of sound effect
vec_t dist_mult ; // distance multiplier (attenuation/clipK)
int master_vol ; // 0-255 master volume
} channel_t ;
typedef struct
{
int rate ;
int width ;
int numchannels ;
int loopstart ;
int samples ;
int dataofs ; // chunk starts this many bytes from file start
} wavinfo_t ;
struct soundcardinfo_s ;
typedef struct soundcardinfo_s soundcardinfo_t ;
void S_Init ( void ) ;
void S_Startup ( void ) ;
2013-08-21 07:14:39 +00:00
void S_Shutdown ( qboolean final ) ;
2012-02-27 12:23:15 +00:00
void S_StartSound ( int entnum , int entchannel , sfx_t * sfx , vec3_t origin , float fvol , float attenuation , float timeofs , float pitchadj ) ;
2004-08-23 00:15:46 +00:00
void S_StaticSound ( sfx_t * sfx , vec3_t origin , float vol , float attenuation ) ;
void S_StopSound ( int entnum , int entchannel ) ;
void S_StopAllSounds ( qboolean clear ) ;
2010-11-06 23:05:29 +00:00
void S_UpdateListener ( vec3_t origin , vec3_t forward , vec3_t right , vec3_t up ) ;
2009-11-04 21:16:50 +00:00
void S_GetListenerInfo ( float * origin , float * forward , float * right , float * up ) ;
2010-11-06 23:05:29 +00:00
void S_Update ( void ) ;
2004-08-23 00:15:46 +00:00
void S_ExtraUpdate ( void ) ;
2012-02-27 12:23:15 +00:00
void S_MixerThread ( soundcardinfo_t * sc ) ;
void S_Purge ( qboolean retaintouched ) ;
2004-08-23 00:15:46 +00:00
2009-04-06 00:34:32 +00:00
qboolean S_HaveOutput ( void ) ;
void S_Music_Clear ( sfx_t * onlyifsample ) ;
void S_Music_Seek ( float time ) ;
2014-03-30 08:55:06 +00:00
sfx_t * S_PrecacheSound ( const char * sample ) ;
2004-08-23 00:15:46 +00:00
void S_TouchSound ( char * sample ) ;
2012-02-27 12:23:15 +00:00
void S_UntouchAll ( void ) ;
2004-08-23 00:15:46 +00:00
void S_ClearPrecache ( void ) ;
void S_BeginPrecaching ( void ) ;
void S_EndPrecaching ( void ) ;
void S_PaintChannels ( soundcardinfo_t * sc , int endtime ) ;
void S_InitPaintChannels ( soundcardinfo_t * sc ) ;
void S_ShutdownCard ( soundcardinfo_t * sc ) ;
2007-08-06 21:13:15 +00:00
void S_DefaultSpeakerConfiguration ( soundcardinfo_t * sc ) ;
void S_ResetFailedLoad ( void ) ;
2011-12-05 15:23:40 +00:00
# ifdef PEXT2_VOICECHAT
void S_Voip_Parse ( void ) ;
# endif
2010-11-15 02:40:31 +00:00
# ifdef VOICECHAT
2013-09-06 22:57:44 +00:00
extern cvar_t snd_voip_showmeter ;
2010-11-20 22:01:16 +00:00
void S_Voip_Transmit ( unsigned char clc , sizebuf_t * buf ) ;
2010-11-16 02:03:47 +00:00
void S_Voip_MapChange ( void ) ;
2010-11-20 22:01:16 +00:00
int S_Voip_Loudness ( qboolean ignorevad ) ; //-1 for not capturing, otherwise between 0 and 100
qboolean S_Voip_Speaking ( unsigned int plno ) ;
2010-12-05 02:46:07 +00:00
void S_Voip_Ignore ( unsigned int plno , qboolean ignore ) ;
2010-11-20 22:01:16 +00:00
# else
# define S_Voip_Loudness() -1
# define S_Voip_Speaking(p) false
2010-12-05 02:56:31 +00:00
# define S_Voip_Ignore(p,s)
2010-11-15 02:40:31 +00:00
# endif
2004-08-23 00:15:46 +00:00
qboolean S_IsPlayingSomewhere ( sfx_t * s ) ;
2012-02-27 12:23:15 +00:00
qboolean ResampleSfx ( sfx_t * sfx , int inrate , int inchannels , int inwidth , int insamps , int inloopstart , qbyte * data ) ;
2004-08-23 00:15:46 +00:00
// picks a channel based on priorities, empty slots, number of channels
channel_t * SND_PickChannel ( soundcardinfo_t * sc , int entnum , int entchannel ) ;
// spatializes a channel
void SND_Spatialize ( soundcardinfo_t * sc , channel_t * ch ) ;
2006-06-04 01:43:52 +00:00
void SND_ResampleStream ( void * in , int inrate , int inwidth , int inchannels , int insamps , void * out , int outrate , int outwidth , int outchannels , int resampstyle ) ;
2005-06-18 23:52:42 +00:00
// restart entire sound subsystem (doesn't flush old sounds, so make sure that happens)
void S_DoRestart ( void ) ;
2012-07-05 19:42:36 +00:00
void S_SetUnderWater ( qboolean underwater ) ;
2004-08-23 00:15:46 +00:00
2005-10-07 02:05:22 +00:00
void S_Restart_f ( void ) ;
2004-08-23 00:15:46 +00:00
//plays streaming audio
2013-05-31 01:16:07 +00:00
void S_RawAudio ( int sourceid , qbyte * data , int speed , int samples , int channels , int width , float volume ) ;
2004-08-23 00:15:46 +00:00
void CLVC_Poll ( void ) ;
void SNDVC_MicInput ( qbyte * buffer , int samples , int freq , int width ) ;
2010-03-14 14:35:56 +00:00
# ifdef AVAIL_OPENAL
void OpenAL_CvarInit ( void ) ;
# endif
2004-08-23 00:15:46 +00:00
// ====================================================================
// User-setable variables
// ====================================================================
2010-11-13 17:22:46 +00:00
# define MAX_CHANNELS 1024 /*tracked sounds (including statics)*/
2011-07-22 20:49:15 +00:00
# define MAX_DYNAMIC_CHANNELS 64 /*playing sounds (identical ones merge)*/
2010-11-06 23:05:29 +00:00
2004-08-23 00:15:46 +00:00
2010-11-06 23:05:29 +00:00
# define NUM_MUSICS 1
# define AMBIENT_FIRST 0
# define AMBIENT_STOP NUM_AMBIENTS
# define MUSIC_FIRST AMBIENT_STOP
# define MUSIC_STOP (MUSIC_FIRST + NUM_MUSICS)
# define DYNAMIC_FIRST MUSIC_STOP
# define DYNAMIC_STOP (DYNAMIC_FIRST + MAX_DYNAMIC_CHANNELS)
2004-08-23 00:15:46 +00:00
//
// Fake dma is a synchronous faking of the DMA progress used for
// isolating performance in the renderer. The fakedma_updates is
// number of times S_Update() is called per second.
//
extern int snd_speed ;
extern vec3_t listener_origin ;
extern vec3_t listener_forward ;
extern vec3_t listener_right ;
extern vec3_t listener_up ;
extern vec_t sound_nominal_clip_dist ;
extern cvar_t loadas8bit ;
extern cvar_t bgmvolume ;
extern cvar_t volume ;
extern cvar_t snd_capture ;
2010-11-20 22:01:16 +00:00
extern float voicevolumemod ;
2004-08-23 00:15:46 +00:00
extern qboolean snd_initialized ;
2013-04-07 08:59:05 +00:00
extern cvar_t snd_mixerthread ;
2004-08-23 00:15:46 +00:00
extern int snd_blocked ;
2014-03-30 08:55:06 +00:00
void S_LocalSound ( const char * s ) ;
2012-02-27 12:23:15 +00:00
qboolean S_LoadSound ( sfx_t * s ) ;
2004-08-23 00:15:46 +00:00
2012-02-27 12:23:15 +00:00
typedef qboolean ( * S_LoadSound_t ) ( sfx_t * s , qbyte * data , int datalen , int sndspeed ) ;
2006-02-11 14:51:36 +00:00
qboolean S_RegisterSoundInputPlugin ( S_LoadSound_t loadfnc ) ; //called to register additional sound input plugins
2004-08-23 00:15:46 +00:00
wavinfo_t GetWavinfo ( char * name , qbyte * wav , int wavlength ) ;
void S_AmbientOff ( void ) ;
void S_AmbientOn ( void ) ;
2005-06-14 04:52:10 +00:00
//inititalisation functions.
2013-07-26 17:19:06 +00:00
typedef struct
{
const char * name ; //must be a single token, with no :
qboolean ( QDECL * InitCard ) ( soundcardinfo_t * sc , const char * cardname ) ; //NULL for default device.
qboolean ( QDECL * Enumerate ) ( void ( QDECL * callback ) ( const char * drivername , const char * devicecode , const char * readablename ) ) ;
} sounddriver_t ;
2005-06-14 04:52:10 +00:00
typedef int ( * sounddriver ) ( soundcardinfo_t * sc , int cardnum ) ;
2010-03-14 14:35:56 +00:00
extern sounddriver pOPENAL_InitCard ;
2005-06-14 04:52:10 +00:00
extern sounddriver pDSOUND_InitCard ;
extern sounddriver pALSA_InitCard ;
2012-09-30 05:52:03 +00:00
extern sounddriver pSNDIO_InitCard ;
2005-06-14 04:52:10 +00:00
extern sounddriver pOSS_InitCard ;
extern sounddriver pSDL_InitCard ;
extern sounddriver pWAV_InitCard ;
2005-11-26 03:02:55 +00:00
extern sounddriver pAHI_InitCard ;
2004-08-23 00:15:46 +00:00
struct soundcardinfo_s { //windows has one defined AFTER directsound
2005-06-14 04:52:10 +00:00
char name [ 256 ] ; //a description of the card.
struct soundcardinfo_s * next ;
//speaker orientations for spacialisation.
2010-11-06 23:05:29 +00:00
float dist [ MAXSOUNDCHANNELS ] ;
vec3_t speakerdir [ MAXSOUNDCHANNELS ] ;
2004-08-23 00:15:46 +00:00
2005-06-14 04:52:10 +00:00
//info on which sound effects are playing
channel_t channel [ MAX_CHANNELS ] ;
int total_chans ;
//mixer
volatile dma_t sn ; //why is this volatile?
qboolean inactive_sound ; //continue mixing for this card even when the window isn't active.
qboolean selfpainting ; //allow the sound code to call the right functions when it feels the need (not properly supported).
2012-02-27 12:23:15 +00:00
int paintedtime ; //used in the mixer as last-written pos (in frames)
2006-09-17 00:59:22 +00:00
int oldsamplepos ; //this is used to track buffer wraps
int buffers ; //used to keep track of how many buffer wraps for consistant sound
2011-01-29 19:53:38 +00:00
int samplequeue ; //this is the number of samples the device can enqueue. if set, DMAPos returns the write point (rather than hardware read point) (in samplepairs).
2005-06-14 04:52:10 +00:00
//callbacks
2012-09-30 05:52:03 +00:00
void * ( * Lock ) ( soundcardinfo_t * sc , unsigned int * startoffset ) ; //grab a pointer to the hardware ringbuffer or whatever. startoffset is the starting offset. you can set it to 0 and bump the start offset if you need.
void ( * Unlock ) ( soundcardinfo_t * sc , void * buffer ) ; //release the hardware ringbuffer memory
void ( * Submit ) ( soundcardinfo_t * sc , int start , int end ) ; //if the ringbuffer is emulated, this is where you should push it to the device.
void ( * Shutdown ) ( soundcardinfo_t * sc ) ; //kill the device
unsigned int ( * GetDMAPos ) ( soundcardinfo_t * sc ) ; //get the current point that the hardware is reading from (the return value should not wrap, at least not very often)
void ( * SetWaterDistortion ) ( soundcardinfo_t * sc , qboolean underwater ) ; //if you have eax enabled, change the environment. fixme. generally this is a stub. optional.
void ( * Restore ) ( soundcardinfo_t * sc ) ; //called before lock/unlock/lock/unlock/submit. optional
void ( * ChannelUpdate ) ( soundcardinfo_t * sc , channel_t * channel , unsigned int schanged ) ; //properties of a sound effect changed. this is to notify hardware mixers. optional.
2013-07-26 17:19:06 +00:00
void ( * ListenerUpdate ) ( soundcardinfo_t * sc , vec3_t origin , vec3_t forward , vec3_t right , vec3_t up , vec3_t velocity ) ; //player moved or something. this is to notify hardware mixers. optional.
2012-09-30 05:52:03 +00:00
//driver-specific - if you need more stuff, you should just shove it in the handle pointer
2012-02-27 12:23:15 +00:00
void * thread ;
2005-06-14 04:52:10 +00:00
void * handle ;
2004-08-23 00:15:46 +00:00
int snd_sent ;
int snd_completed ;
int audio_fd ;
} ;
extern soundcardinfo_t * sndcardinfo ;
2010-11-20 22:01:16 +00:00
typedef struct
{
2013-09-06 22:57:44 +00:00
int apiver ;
char * drivername ;
qboolean ( QDECL * Enumerate ) ( void ( QDECL * callback ) ( const char * drivername , const char * devicecode , const char * readablename ) ) ;
2013-10-26 02:50:24 +00:00
void * ( QDECL * Init ) ( int samplerate , const char * device ) ; /*create a new context*/
2013-09-06 22:57:44 +00:00
void ( QDECL * Start ) ( void * ctx ) ; /*begin grabbing new data, old data is potentially flushed*/
unsigned int ( QDECL * Update ) ( void * ctx , unsigned char * buffer , unsigned int minbytes , unsigned int maxbytes ) ; /*grab the data into a different buffer*/
void ( QDECL * Stop ) ( void * ctx ) ; /*stop grabbing new data, old data may remain*/
void ( QDECL * Shutdown ) ( void * ctx ) ; /*destroy everything*/
2010-11-20 22:01:16 +00:00
} snd_capture_driver_t ;
2004-08-23 00:15:46 +00:00
# endif