This repository has been archived on 2022-06-27. You can view files and clone it, but cannot push or open issues or pull requests.
Xash3DArchive/snd_dx/sound.h

374 lines
12 KiB
C
Raw Normal View History

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