2009-10-02 22:00:00 +02:00
|
|
|
|
//=======================================================================
|
|
|
|
|
// Copyright XashXT Group 2009 <20>
|
|
|
|
|
// sound.h - sndlib main header
|
|
|
|
|
//=======================================================================
|
|
|
|
|
|
|
|
|
|
#ifndef SOUND_H
|
|
|
|
|
#define SOUND_H
|
|
|
|
|
|
|
|
|
|
#include <windows.h>
|
|
|
|
|
#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;
|
|
|
|
|
|
2009-10-10 22:00:00 +02:00
|
|
|
|
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
|
|
|
|
|
|
2009-10-02 22:00:00 +02:00
|
|
|
|
#include "mathlib.h"
|
|
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
|
{
|
|
|
|
|
int left;
|
|
|
|
|
int right;
|
2009-10-10 22:00:00 +02:00
|
|
|
|
} 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 );
|
2009-10-02 22:00:00 +02:00
|
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
|
{
|
|
|
|
|
int length;
|
|
|
|
|
int loopstart;
|
|
|
|
|
int speed; // not needed, because converted on load?
|
|
|
|
|
int width;
|
|
|
|
|
int stereo;
|
2009-10-10 22:00:00 +02:00
|
|
|
|
bool sentence; // set to true if it's a sentence
|
2009-10-02 22:00:00 +02:00
|
|
|
|
byte data[1]; // variable sized
|
|
|
|
|
} sfxcache_t;
|
|
|
|
|
|
2009-10-10 22:00:00 +02:00
|
|
|
|
typedef struct mixer_s
|
|
|
|
|
{
|
|
|
|
|
double m_sample;
|
|
|
|
|
|
|
|
|
|
sfxcache_t *m_pData;
|
|
|
|
|
double m_forcedEndSample;
|
|
|
|
|
bool m_finished;
|
|
|
|
|
int m_delaySamples;
|
|
|
|
|
|
|
|
|
|
MixFn MixFunc;
|
|
|
|
|
} mixer_t;
|
|
|
|
|
|
2009-10-02 22:00:00 +02:00
|
|
|
|
typedef struct sfx_s
|
|
|
|
|
{
|
|
|
|
|
string name;
|
|
|
|
|
sfxcache_t *cache;
|
2009-10-10 22:00:00 +02:00
|
|
|
|
mixer_t *mixer;
|
2009-10-02 22:00:00 +02:00
|
|
|
|
|
|
|
|
|
int registration_sequence;
|
|
|
|
|
bool default_sound;
|
|
|
|
|
} sfx_t;
|
|
|
|
|
|
2009-10-10 22:00:00 +02:00
|
|
|
|
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;
|
|
|
|
|
|
2009-10-02 22:00:00 +02:00
|
|
|
|
// 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;
|
|
|
|
|
|
2009-10-10 22:00:00 +02:00
|
|
|
|
typedef enum
|
|
|
|
|
{
|
|
|
|
|
src_sound = 0,
|
|
|
|
|
src_sentence
|
|
|
|
|
} srctype_t;
|
|
|
|
|
|
|
|
|
|
typedef struct channel_s
|
2009-10-02 22:00:00 +02:00
|
|
|
|
{
|
2009-10-10 22:00:00 +02:00
|
|
|
|
srctype_t type;
|
2009-10-02 22:00:00 +02:00
|
|
|
|
sfx_t *sfx; // sfx number
|
2009-10-10 22:00:00 +02:00
|
|
|
|
mixer_t *pMixer; // sound mixer data
|
|
|
|
|
|
2009-10-02 22:00:00 +02:00
|
|
|
|
int leftvol; // 0-255 volume
|
|
|
|
|
int rightvol; // 0-255 volume
|
2009-10-10 22:00:00 +02:00
|
|
|
|
int dleftvol; // 0-255 front left volume - doppler outgoing wav
|
|
|
|
|
int drightvol; // 0-255 front right volume - doppler outgoing wav
|
|
|
|
|
|
2009-10-02 22:00:00 +02:00
|
|
|
|
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
|
2009-10-10 22:00:00 +02:00
|
|
|
|
vec3_t direction; // direction of the sound
|
2009-10-02 22:00:00 +02:00
|
|
|
|
vec_t dist_mult; // distance multiplier (attenuation/clipK)
|
|
|
|
|
int master_vol; // 0-255 master volume
|
2009-10-10 22:00:00 +02:00
|
|
|
|
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
|
2009-10-02 22:00:00 +02:00
|
|
|
|
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 )
|
|
|
|
|
|
2009-10-10 22:00:00 +02:00
|
|
|
|
// 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<<SND_SCALE_BITS)
|
|
|
|
|
|
|
|
|
|
// global paintbuffer flags
|
|
|
|
|
#define SOUND_BUSS_ROOM BIT( 0 ) // mix samples using channel dspmix value (based on distance from player)
|
|
|
|
|
#define SOUND_BUSS_FACING BIT( 1 ) // mix samples using channel dspface value (source facing)
|
|
|
|
|
#define SOUND_BUSS_FACINGAWAY BIT( 2 ) // mix samples using 1-dspface
|
|
|
|
|
|
|
|
|
|
// hard clip input value to -32767 <= y <= 32767
|
|
|
|
|
#define CLIP( x ) bound( -32767, (x), 32767 )
|
|
|
|
|
|
2009-10-02 22:00:00 +02:00
|
|
|
|
// initializes cycling through a DMA buffer and returns information on it
|
|
|
|
|
bool SNDDMA_Init( void *hInst );
|
|
|
|
|
int SNDDMA_GetDMAPos( void );
|
|
|
|
|
void SNDDMA_Shutdown( void );
|
|
|
|
|
void SNDDMA_BeginPainting( void );
|
|
|
|
|
void SNDDMA_Submit( void );
|
|
|
|
|
|
|
|
|
|
//====================================================================
|
|
|
|
|
|
|
|
|
|
#define MAX_CHANNELS 64
|
|
|
|
|
#define MAX_RAW_SAMPLES 8192
|
|
|
|
|
|
|
|
|
|
extern channel_t channels[MAX_CHANNELS];
|
|
|
|
|
extern int paintedtime;
|
|
|
|
|
extern int s_rawend;
|
2009-10-10 22:00:00 +02:00
|
|
|
|
extern int listener_waterlevel;
|
2009-10-02 22:00:00 +02:00
|
|
|
|
extern vec3_t listener_origin;
|
|
|
|
|
extern vec3_t listener_forward;
|
|
|
|
|
extern vec3_t listener_right;
|
|
|
|
|
extern vec3_t listener_up;
|
|
|
|
|
extern dma_t dma;
|
|
|
|
|
extern playsound_t s_pendingplays;
|
|
|
|
|
extern bool sound_started;
|
2009-10-10 22:00:00 +02:00
|
|
|
|
extern bool dsound_init;
|
|
|
|
|
extern bool wavout_init;
|
|
|
|
|
extern bool g_bDspOff;
|
|
|
|
|
extern bool g_bdirectionalfx;
|
|
|
|
|
extern int snd_scaletable[SND_SCALE_LEVELS][256];
|
2009-10-02 22:00:00 +02:00
|
|
|
|
|
|
|
|
|
extern cvar_t *s_check_errors;
|
|
|
|
|
extern cvar_t *s_volume;
|
|
|
|
|
extern cvar_t *s_nosound;
|
|
|
|
|
extern cvar_t *s_loadas8bit;
|
|
|
|
|
extern cvar_t *s_khz;
|
|
|
|
|
extern cvar_t *s_show;
|
|
|
|
|
extern cvar_t *s_mixahead;
|
|
|
|
|
extern cvar_t *s_testsound;
|
|
|
|
|
extern cvar_t *s_primary;
|
|
|
|
|
|
2009-10-10 22:00:00 +02:00
|
|
|
|
extern samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
|
|
|
|
|
extern samplepair_t paintbuffer[];
|
2009-10-02 22:00:00 +02:00
|
|
|
|
|
2009-10-10 22:00:00 +02:00
|
|
|
|
float S_GetMasterVolume( void );
|
2009-10-02 22:00:00 +02:00
|
|
|
|
void S_InitScaletable( void );
|
2009-10-10 22:00:00 +02:00
|
|
|
|
sfxcache_t *S_LoadSound( sfx_t *sfx, channel_t *ch );
|
2009-10-02 22:00:00 +02:00
|
|
|
|
void S_IssuePlaysound( playsound_t *ps );
|
|
|
|
|
void S_PaintChannels( int endtime );
|
|
|
|
|
|
2009-10-10 22:00:00 +02:00
|
|
|
|
// s_mix.c
|
|
|
|
|
void MIX_ClearAllPaintBuffers( int SampleCount, bool clearFilters );
|
|
|
|
|
extern _inline void MIX_SetCurrentPaintbuffer( int ipaintbuffer );
|
|
|
|
|
extern _inline int MIX_GetCurrentPaintbufferIndex( void );
|
|
|
|
|
extern _inline paintbuffer_t *MIX_GetCurrentPaintbufferPtr( void );
|
|
|
|
|
void MIX_ScaleChannelVolume( paintbuffer_t *ppaint, channel_t *pChannel, int volume[CCHANVOLUMES], int mixchans );
|
|
|
|
|
void Mix8Mono(channel_t *pChannel, char *pData, int outputOffset, int inputOffset, uint rateScaleFix, int outCount);
|
|
|
|
|
void Mix16Mono(channel_t *pChannel, char *pData, int outputOffset, int inputOffset, uint rateScaleFix, int outCount);
|
|
|
|
|
void Mix8Stereo(channel_t *pChannel, char *pData, int outputOffset, int inputOffset, uint rateScaleFix, int outCount);
|
|
|
|
|
void Mix16Stereo(channel_t *pChannel, char *pData, int outputOffset, int inputOffset, uint rateScaleFix, int outCount);
|
|
|
|
|
int MIX_GetCurrentPaintbufferIndex( void );
|
|
|
|
|
bool MIX_InitAllPaintbuffers( void );
|
|
|
|
|
void MIX_FreeAllPaintbuffers( void );
|
|
|
|
|
void SND_MoveMouth8( channel_t *ch, int count );
|
|
|
|
|
void SND_CloseMouth( channel_t *ch );
|
|
|
|
|
void SND_InitMouth( int entnum, int entchannel );
|
|
|
|
|
void SND_UpdateMouth( channel_t *pChannel );
|
|
|
|
|
void SND_ClearMouth( channel_t *pChannel );
|
|
|
|
|
bool SND_IsMouth( channel_t *pChannel );
|
|
|
|
|
|
|
|
|
|
// s_dsp.c
|
|
|
|
|
extern cvar_t *dsp_off;
|
|
|
|
|
extern cvar_t *dsp_room;
|
|
|
|
|
extern cvar_t *dsp_water;
|
|
|
|
|
extern cvar_t *dsp_player;
|
|
|
|
|
extern cvar_t *dsp_facingaway;
|
|
|
|
|
extern int idsp_room;
|
|
|
|
|
extern int idsp_water;
|
|
|
|
|
extern int idsp_player;
|
|
|
|
|
extern int idsp_facingaway;
|
|
|
|
|
|
|
|
|
|
bool AllocDsps( void );
|
|
|
|
|
void FreeDsps( void );
|
|
|
|
|
void CheckNewDspPresets( void );
|
|
|
|
|
float DSP_GetGain( int idsp );
|
|
|
|
|
void DSP_Process( int idsp, samplepair_t *pbfront, int sampleCount );
|
|
|
|
|
void DSP_ClearState();
|
|
|
|
|
|
|
|
|
|
// legacy DSP Routines
|
|
|
|
|
void SX_Init( void );
|
|
|
|
|
void SX_Free( void );
|
|
|
|
|
void SX_RoomFX( int endtime, int fFilter, int fTimefx );
|
|
|
|
|
|
2009-10-02 22:00:00 +02:00
|
|
|
|
bool S_Init( void *hInst );
|
|
|
|
|
void S_Shutdown( void );
|
|
|
|
|
void S_Activate( bool active );
|
|
|
|
|
void S_SoundList_f( void );
|
|
|
|
|
void S_SoundInfo_f( void );
|
|
|
|
|
|
|
|
|
|
// if origin is NULL, the sound will be dynamically sourced from the entity
|
|
|
|
|
void S_StartSound( const vec3_t pos, int ent, int chan, sound_t sfx, float vol, float attn, float pitch, bool use_loop);
|
|
|
|
|
void S_StreamRawSamples( int samples, int rate, int width, int channels, const byte *data );
|
|
|
|
|
bool S_AddLoopingSound( int entnum, sound_t handle, float volume, float attn );
|
|
|
|
|
void S_StartBackgroundTrack( const char *intro, const char *loop );
|
|
|
|
|
channel_t *S_PickChannel( int entNum, int entChannel );
|
|
|
|
|
int S_StartLocalSound( const char *name, float volume, float pitch, const float *org );
|
|
|
|
|
sfx_t *S_GetSfxByHandle( sound_t handle );
|
|
|
|
|
void S_StopBackgroundTrack( void );
|
2009-10-06 22:00:00 +02:00
|
|
|
|
void S_Update( ref_params_t *fd );
|
2009-10-02 22:00:00 +02:00
|
|
|
|
void S_StartStreaming( void );
|
|
|
|
|
void S_StopStreaming( void );
|
|
|
|
|
void S_StopAllSounds( void );
|
|
|
|
|
void S_FreeSounds( void );
|
|
|
|
|
|
|
|
|
|
void S_BeginRegistration( void );
|
|
|
|
|
sound_t S_RegisterSound( const char *sample );
|
|
|
|
|
void S_EndRegistration( void );
|
|
|
|
|
|
|
|
|
|
#endif//SOUND_H
|