//======================================================================= // Copyright XashXT Group 2009 © // sound.h - sndlib main header //======================================================================= #ifndef SOUND_H #define SOUND_H #include #include "launch_api.h" #include "qfiles_ref.h" #include "vsound_api.h" extern stdlib_api_t com; extern vsound_imp_t si; extern byte *sndpool; enum { IPAINTBUFFER = 0, IROOMBUFFER, IFACINGBUFFER, IFACINGAWAYBUFFER, IDRYBUFFER, CPAINTBUFFERS // count of buffers }; enum { IFRONT_LEFT = 0, // NOTE: must correspond to order of leftvol...drrightvol above! IFRONT_RIGHT, IFRONT_LEFTD, // start of doppler right array IFRONT_RIGHTD, CCHANVOLUMES }; // fixed point stuff for real-time resampling #define FIX_BITS 28 #define FIX_SCALE (1 << FIX_BITS) #define FIX_MASK ((1 << FIX_BITS)-1) #define FIX_FLOAT( a ) ((int)((a) * FIX_SCALE)) #define FIX( a ) (((int)(a)) << FIX_BITS) #define FIX_INTPART( a ) (((int)(a)) >> FIX_BITS) #define FIX_FRACTION( a, b ) (FIX(a)/(b)) #define FIX_FRACPART( a ) ((a) & FIX_MASK) #define CPAINTFILTERMEM 3 #define CPAINTFILTERS 4 // maximum number of consecutive upsample passes per paintbuffer #define PAINTBUFFER_SIZE 1024 // 44k: was 512 #define PAINTBUFFER (g_curpaintbuffer) #define CHAR_SENTENCE '!' // as one of 1st 2 chars in name, indicates sentence wav #define CHAR_DRYMIX '#' // as one of 1st 2 chars in name, indicates wav bypasses dsp fx #define CHAR_DOPPLER '>' // as one of 1st 2 chars in name, indicates doppler encoded stereo wav #define CHAR_DIRECTIONAL '<' // as one of 1st 2 chars in name, indicates mono or stereo wav has direction cone #define CHAR_DISTVARIANT '^' // as one of 1st 2 chars in name, indicates distance variant encoded stereo wav #include "mathlib.h" typedef struct { int left; int right; } samplepair_t; typedef struct { bool factive; // if true, mix to this paintbuffer using flags int flags; // SOUND_BUSS_ROOM, SOUND_BUSS_FACING, SOUND_BUSS_FACINGAWAY samplepair_t *pbuf; // front stereo mix buffer, for 2 channel mixing int ifilter; // current filter memory buffer to use for upsampling pass // filter memory, for upsampling with linear or cubic interpolation samplepair_t fltmem[CPAINTFILTERS][CPAINTFILTERMEM]; } paintbuffer_t; typedef void (*MixFn)( struct channel_s *chan, char *data, int outofs, int inofs, uint rate, int count ); typedef struct { int length; int loopstart; int speed; // not needed, because converted on load? int width; int stereo; bool sentence; // set to true if it's a sentence byte data[1]; // variable sized } sfxcache_t; typedef struct mixer_s { double m_sample; sfxcache_t *m_pData; double m_forcedEndSample; bool m_finished; int m_delaySamples; MixFn MixFunc; } mixer_t; typedef struct sfx_s { string name; sfxcache_t *cache; mixer_t *mixer; int registration_sequence; bool default_sound; } sfx_t; typedef struct voxword_s { int volume; // increase percent, ie: 125 = 125% increase int pitch; // pitch shift up percent int start; // offset start of wave percent int end; // offset end of wave percent int cbtrim; // end of wave after being trimmed to 'end' int fKeepCached; // 1 if this word was already in cache before sentence referenced it int samplefrac; // if pitch shifting, this is position into wav * 256 int timecompress; // % of wave to skip during playback (causes no pitch shift) sfx_t *sfx; // name and cache pointer } voxword_t; // a playsound_t will be generated by each call to S_StartSound, // when the mixer reaches playsound->begin, the playsound will // be assigned to a channel typedef struct playsound_s { struct playsound_s *prev, *next; sfx_t *sfx; float volume; float attenuation; int entnum; int entchannel; bool fixed_origin; // use origin field instead of entnum's origin bool use_loop; vec3_t origin; uint begin; // begin on this sample } playsound_t; typedef struct { int channels; int samples; // mono samples in buffer int submission_chunk; // don't mix less than this # int samplepos; // in mono samples int samplebits; int speed; byte *buffer; } dma_t; typedef enum { src_sound = 0, src_sentence } srctype_t; typedef struct channel_s { srctype_t type; sfx_t *sfx; // sfx number mixer_t *pMixer; // sound mixer data int leftvol; // 0-255 volume int rightvol; // 0-255 volume int dleftvol; // 0-255 front left volume - doppler outgoing wav int drightvol; // 0-255 front right volume - doppler outgoing wav int end; // end time in global paintsamples int pos; // sample position in sfx int looping; // where to loop, -1 = no looping OBSOLETE? int entnum; // to allow overriding a specific sound int loopnum; // entity num that playing autosound int loopframe; // for stopping looping sounds int entchannel; // vec3_t origin; // only use if fixed_origin is set vec3_t direction; // direction of the sound vec_t dist_mult; // distance multiplier (attenuation/clipK) int master_vol; // 0-255 master volume int basePitch; // base pitch percent (100% is normal pitch playback) float pitch; // real-time pitch after any modulation or shift by dynamic data float dspmix; // 0 - 1.0 proportion of dsp to mix with original sound, // based on distance float dspface; // -1.0 - 1.0 (1.0 = facing listener) float distmix; // 0 - 1.0 proportion based on distance from listener // (1.0 - 100% wav right - far) bool bdry; // if true, bypass all dsp processing for this sound (ie: music) bool bstereowav; // if true, a stereo .wav file is the sample data source char wavtype; // 0 default, CHAR_DOPPLER, CHAR_DIRECTIONAL, CHAR_DISTVARIANT float radius; // Radius of this sound effect // (spatialization is different within the radius) bool bfirstpass; // true if this is first time sound is spatialized float ob_gain; // gain drop if sound source obscured from listener float ob_gain_target; // target gain while crossfading between ob_gain & ob_gain_target float ob_gain_inc; // crossfade increment bool delayed_start; // If true, sound had a delay and so same sound on same channel // won't channel steal from it bool fixed_origin; // use origin instead of fetching entnum's origin bool autosound; // from an entity->sound, cleared each frame bool use_loop; // don't loop default and local sounds } channel_t; typedef struct { int rate; int width; int channels; int loopstart; int samples; int dataofs; // chunk starts this many bytes from file start } wavinfo_t; typedef struct { string introName; string loopName; bool looping; file_t *file; int start; int rate; uint format; void *vorbisFile; } bg_track_t; /* ==================================================================== SYSTEM SPECIFIC FUNCTIONS ==================================================================== */ #define Host_Error com.error #define Z_Malloc( size ) Mem_Alloc( sndpool, size ) // hl2 used backward assertation if( !x ) #define Assert( x ) if(!(x)) com.abort( "assert failed at %s:%i\n", __FILE__, __LINE__ ) #define ARRAYSIZE( p ) (sizeof( p ) / sizeof( p[0] )) #define SOUND_DMA_SPEED (dma.speed) #define SOUND_11k 11025 // 11khz sample rate #define SOUND_22k 22050 // 22khz sample rate #define SOUND_44k 44100 // 44khz sample rate #define SOUND_ALL_RATES 1 // mix all sample rates #define SND_SCALE_BITS 7 #define SND_SCALE_SHIFT (8 - SND_SCALE_BITS) #define SND_SCALE_LEVELS (1<