mirror of
https://github.com/id-Software/DOOM-3.git
synced 2026-03-20 00:49:31 +01:00
hello world
This commit is contained in:
924
neo/sound/snd_local.h
Normal file
924
neo/sound/snd_local.h
Normal file
@@ -0,0 +1,924 @@
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Doom 3 GPL Source Code
|
||||
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
|
||||
|
||||
Doom 3 Source Code 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Doom 3 Source Code is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||
|
||||
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#ifndef __SND_LOCAL_H__
|
||||
#define __SND_LOCAL_H__
|
||||
|
||||
// you need the OpenAL headers for build, even if AL is not enabled - http://www.openal.org/
|
||||
#ifdef _WIN32
|
||||
#include "../openal/include/al.h"
|
||||
#include "../openal/include/alc.h"
|
||||
#include "../openal/idal.h"
|
||||
// broken OpenAL SDK ?
|
||||
#define ID_ALCHAR (ALubyte *)
|
||||
#elif defined( MACOS_X )
|
||||
#include <OpenAL/al.h>
|
||||
#include <OpenAL/alc.h>
|
||||
#define ID_ALCHAR
|
||||
#else
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#define ID_ALCHAR
|
||||
#endif
|
||||
#include "../openal/include/efxlib.h"
|
||||
|
||||
// demo sound commands
|
||||
typedef enum {
|
||||
SCMD_STATE, // followed by a load game state
|
||||
SCMD_PLACE_LISTENER,
|
||||
SCMD_ALLOC_EMITTER,
|
||||
|
||||
SCMD_FREE,
|
||||
SCMD_UPDATE,
|
||||
SCMD_START,
|
||||
SCMD_MODIFY,
|
||||
SCMD_STOP,
|
||||
SCMD_FADE
|
||||
} soundDemoCommand_t;
|
||||
|
||||
const int SOUND_MAX_CHANNELS = 8;
|
||||
const int SOUND_DECODER_FREE_DELAY = 1000 * MIXBUFFER_SAMPLES / USERCMD_MSEC; // four seconds
|
||||
|
||||
const int PRIMARYFREQ = 44100; // samples per second
|
||||
const float SND_EPSILON = 1.0f / 32768.0f; // if volume is below this, it will always multiply to zero
|
||||
|
||||
const int ROOM_SLICES_IN_BUFFER = 10;
|
||||
|
||||
class idAudioHardware;
|
||||
class idAudioBuffer;
|
||||
class idWaveFile;
|
||||
class idSoundCache;
|
||||
class idSoundSample;
|
||||
class idSampleDecoder;
|
||||
class idSoundWorldLocal;
|
||||
|
||||
|
||||
/*
|
||||
===================================================================================
|
||||
|
||||
General extended waveform format structure.
|
||||
Use this for all NON PCM formats.
|
||||
|
||||
===================================================================================
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
#ifdef __MWERKS__
|
||||
#pragma pack (push, 1)
|
||||
#endif
|
||||
struct waveformatex_s {
|
||||
word wFormatTag; /* format type */
|
||||
word nChannels; /* number of channels (i.e. mono, stereo...) */
|
||||
dword nSamplesPerSec; /* sample rate */
|
||||
dword nAvgBytesPerSec; /* for buffer estimation */
|
||||
word nBlockAlign; /* block size of data */
|
||||
word wBitsPerSample; /* Number of bits per sample of mono data */
|
||||
word cbSize; /* The count in bytes of the size of
|
||||
extra information (after cbSize) */
|
||||
} PACKED;
|
||||
|
||||
typedef waveformatex_s waveformatex_t;
|
||||
|
||||
/* OLD general waveform format structure (information common to all formats) */
|
||||
struct waveformat_s {
|
||||
word wFormatTag; /* format type */
|
||||
word nChannels; /* number of channels (i.e. mono, stereo, etc.) */
|
||||
dword nSamplesPerSec; /* sample rate */
|
||||
dword nAvgBytesPerSec; /* for buffer estimation */
|
||||
word nBlockAlign; /* block size of data */
|
||||
} PACKED;
|
||||
|
||||
typedef waveformat_s waveformat_t;
|
||||
|
||||
/* flags for wFormatTag field of WAVEFORMAT */
|
||||
enum {
|
||||
WAVE_FORMAT_TAG_PCM = 1,
|
||||
WAVE_FORMAT_TAG_OGG = 2
|
||||
};
|
||||
|
||||
/* specific waveform format structure for PCM data */
|
||||
struct pcmwaveformat_s {
|
||||
waveformat_t wf;
|
||||
word wBitsPerSample;
|
||||
} PACKED;
|
||||
|
||||
typedef pcmwaveformat_s pcmwaveformat_t;
|
||||
|
||||
#ifndef mmioFOURCC
|
||||
#define mmioFOURCC( ch0, ch1, ch2, ch3 ) \
|
||||
( (dword)(byte)(ch0) | ( (dword)(byte)(ch1) << 8 ) | \
|
||||
( (dword)(byte)(ch2) << 16 ) | ( (dword)(byte)(ch3) << 24 ) )
|
||||
#endif
|
||||
|
||||
#define fourcc_riff mmioFOURCC('R', 'I', 'F', 'F')
|
||||
|
||||
struct waveformatextensible_s {
|
||||
waveformatex_t Format;
|
||||
union {
|
||||
word wValidBitsPerSample; /* bits of precision */
|
||||
word wSamplesPerBlock; /* valid if wBitsPerSample==0*/
|
||||
word wReserved; /* If neither applies, set to zero*/
|
||||
} Samples;
|
||||
dword dwChannelMask; /* which channels are */
|
||||
/* present in stream */
|
||||
int SubFormat;
|
||||
} PACKED;
|
||||
|
||||
typedef waveformatextensible_s waveformatextensible_t;
|
||||
|
||||
typedef dword fourcc;
|
||||
|
||||
/* RIFF chunk information data structure */
|
||||
struct mminfo_s {
|
||||
fourcc ckid; /* chunk ID */
|
||||
dword cksize; /* chunk size */
|
||||
fourcc fccType; /* form type or list type */
|
||||
dword dwDataOffset; /* offset of data portion of chunk */
|
||||
} PACKED;
|
||||
|
||||
typedef mminfo_s mminfo_t;
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma pack()
|
||||
#endif
|
||||
#ifdef __MWERKS__
|
||||
#pragma pack (pop)
|
||||
#endif
|
||||
|
||||
/*
|
||||
===================================================================================
|
||||
|
||||
idWaveFile
|
||||
|
||||
===================================================================================
|
||||
*/
|
||||
|
||||
class idWaveFile {
|
||||
public:
|
||||
idWaveFile( void );
|
||||
~idWaveFile( void );
|
||||
|
||||
int Open( const char* strFileName, waveformatex_t* pwfx = NULL );
|
||||
int OpenFromMemory( short* pbData, int ulDataSize, waveformatextensible_t* pwfx );
|
||||
int Read( byte* pBuffer, int dwSizeToRead, int *pdwSizeRead );
|
||||
int Seek( int offset );
|
||||
int Close( void );
|
||||
int ResetFile( void );
|
||||
|
||||
int GetOutputSize( void ) { return mdwSize; }
|
||||
int GetMemorySize( void ) { return mMemSize; }
|
||||
|
||||
waveformatextensible_t mpwfx; // Pointer to waveformatex structure
|
||||
|
||||
private:
|
||||
idFile * mhmmio; // I/O handle for the WAVE
|
||||
mminfo_t mck; // Multimedia RIFF chunk
|
||||
mminfo_t mckRiff; // used when opening a WAVE file
|
||||
dword mdwSize; // size in samples
|
||||
dword mMemSize; // size of the wave data in memory
|
||||
dword mseekBase;
|
||||
ID_TIME_T mfileTime;
|
||||
|
||||
bool mbIsReadingFromMemory;
|
||||
short * mpbData;
|
||||
short * mpbDataCur;
|
||||
dword mulDataSize;
|
||||
|
||||
void * ogg; // only !NULL when !s_realTimeDecoding
|
||||
bool isOgg;
|
||||
|
||||
private:
|
||||
int ReadMMIO( void );
|
||||
|
||||
int OpenOGG( const char* strFileName, waveformatex_t* pwfx = NULL );
|
||||
int ReadOGG( byte* pBuffer, int dwSizeToRead, int *pdwSizeRead );
|
||||
int CloseOGG( void );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===================================================================================
|
||||
|
||||
idAudioHardware
|
||||
|
||||
===================================================================================
|
||||
*/
|
||||
|
||||
class idAudioHardware {
|
||||
public:
|
||||
static idAudioHardware *Alloc();
|
||||
|
||||
virtual ~idAudioHardware();
|
||||
|
||||
virtual bool Initialize( ) = 0;
|
||||
|
||||
virtual bool Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize ) = 0;
|
||||
virtual bool Unlock( void *pDSLockedBuffer, dword dwDSLockedBufferSize ) = 0;
|
||||
virtual bool GetCurrentPosition( ulong *pdwCurrentWriteCursor ) = 0;
|
||||
|
||||
// try to write as many sound samples to the device as possible without blocking and prepare for a possible new mixing call
|
||||
// returns wether there is *some* space for writing available
|
||||
virtual bool Flush( void ) = 0;
|
||||
|
||||
virtual void Write( bool flushing ) = 0;
|
||||
|
||||
virtual int GetNumberOfSpeakers( void )= 0;
|
||||
virtual int GetMixBufferSize( void ) = 0;
|
||||
virtual short* GetMixBuffer( void ) = 0;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===================================================================================
|
||||
|
||||
Encapsulates functionality of a DirectSound buffer.
|
||||
|
||||
===================================================================================
|
||||
*/
|
||||
|
||||
class idAudioBuffer {
|
||||
public:
|
||||
virtual int Play( dword dwPriority=0, dword dwFlags=0 ) = 0;
|
||||
virtual int Stop( void ) = 0;
|
||||
virtual int Reset( void ) = 0;
|
||||
virtual bool IsSoundPlaying( void ) = 0;
|
||||
virtual void SetVolume( float x ) = 0;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===================================================================================
|
||||
|
||||
idSoundEmitterLocal
|
||||
|
||||
===================================================================================
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
REMOVE_STATUS_INVALID = -1,
|
||||
REMOVE_STATUS_ALIVE = 0,
|
||||
REMOVE_STATUS_WAITSAMPLEFINISHED = 1,
|
||||
REMOVE_STATUS_SAMPLEFINISHED = 2
|
||||
} removeStatus_t;
|
||||
|
||||
class idSoundFade {
|
||||
public:
|
||||
int fadeStart44kHz;
|
||||
int fadeEnd44kHz;
|
||||
float fadeStartVolume; // in dB
|
||||
float fadeEndVolume; // in dB
|
||||
|
||||
void Clear();
|
||||
float FadeDbAt44kHz( int current44kHz );
|
||||
};
|
||||
|
||||
class SoundFX {
|
||||
protected:
|
||||
bool initialized;
|
||||
|
||||
int channel;
|
||||
int maxlen;
|
||||
|
||||
float* buffer;
|
||||
float continuitySamples[4];
|
||||
|
||||
float param;
|
||||
|
||||
public:
|
||||
SoundFX() { channel = 0; buffer = NULL; initialized = false; maxlen = 0; memset( continuitySamples, 0, sizeof( float ) * 4 ); };
|
||||
virtual ~SoundFX() { if ( buffer ) delete buffer; };
|
||||
|
||||
virtual void Initialize() { };
|
||||
virtual void ProcessSample( float* in, float* out ) = 0;
|
||||
|
||||
void SetChannel( int chan ) { channel = chan; };
|
||||
int GetChannel() { return channel; };
|
||||
|
||||
void SetContinuitySamples( float in1, float in2, float out1, float out2 ) { continuitySamples[0] = in1; continuitySamples[1] = in2; continuitySamples[2] = out1; continuitySamples[3] = out2; }; // FIXME?
|
||||
void GetContinuitySamples( float& in1, float& in2, float& out1, float& out2 ) { in1 = continuitySamples[0]; in2 = continuitySamples[1]; out1 = continuitySamples[2]; out2 = continuitySamples[3]; };
|
||||
|
||||
void SetParameter( float val ) { param = val; };
|
||||
};
|
||||
|
||||
class SoundFX_Lowpass : public SoundFX {
|
||||
public:
|
||||
virtual void ProcessSample( float* in, float* out );
|
||||
};
|
||||
|
||||
class SoundFX_LowpassFast : public SoundFX {
|
||||
float freq;
|
||||
float res;
|
||||
float a1, a2, a3;
|
||||
float b1, b2;
|
||||
|
||||
public:
|
||||
virtual void ProcessSample( float* in, float* out );
|
||||
void SetParms( float p1 = 0, float p2 = 0, float p3 = 0 );
|
||||
};
|
||||
|
||||
class SoundFX_Comb : public SoundFX {
|
||||
int currentTime;
|
||||
|
||||
public:
|
||||
virtual void Initialize();
|
||||
virtual void ProcessSample( float* in, float* out );
|
||||
};
|
||||
|
||||
class FracTime {
|
||||
public:
|
||||
int time;
|
||||
float frac;
|
||||
|
||||
void Set( int val ) { time = val; frac = 0; };
|
||||
void Increment( float val ) { frac += val; while ( frac >= 1.f ) { time++; frac--; } };
|
||||
};
|
||||
|
||||
enum {
|
||||
PLAYBACK_RESET,
|
||||
PLAYBACK_ADVANCING
|
||||
};
|
||||
|
||||
class idSoundChannel;
|
||||
|
||||
class idSlowChannel {
|
||||
bool active;
|
||||
const idSoundChannel* chan;
|
||||
|
||||
int playbackState;
|
||||
int triggerOffset;
|
||||
|
||||
FracTime newPosition;
|
||||
int newSampleOffset;
|
||||
|
||||
FracTime curPosition;
|
||||
int curSampleOffset;
|
||||
|
||||
SoundFX_LowpassFast lowpass;
|
||||
|
||||
// functions
|
||||
void GenerateSlowChannel( FracTime& playPos, int sampleCount44k, float* finalBuffer );
|
||||
|
||||
float GetSlowmoSpeed();
|
||||
|
||||
public:
|
||||
|
||||
void AttachSoundChannel( const idSoundChannel *chan );
|
||||
void Reset();
|
||||
|
||||
void GatherChannelSamples( int sampleOffset44k, int sampleCount44k, float *dest );
|
||||
|
||||
bool IsActive() { return active; };
|
||||
FracTime GetCurrentPosition() { return curPosition; };
|
||||
};
|
||||
|
||||
class idSoundChannel {
|
||||
public:
|
||||
idSoundChannel( void );
|
||||
~idSoundChannel( void );
|
||||
|
||||
void Clear( void );
|
||||
void Start( void );
|
||||
void Stop( void );
|
||||
void GatherChannelSamples( int sampleOffset44k, int sampleCount44k, float *dest ) const;
|
||||
void ALStop( void ); // free OpenAL resources if any
|
||||
|
||||
bool triggerState;
|
||||
int trigger44kHzTime; // hardware time sample the channel started
|
||||
int triggerGame44kHzTime; // game time sample time the channel started
|
||||
soundShaderParms_t parms; // combines the shader parms and the per-channel overrides
|
||||
idSoundSample * leadinSample; // if not looped, this is the only sample
|
||||
s_channelType triggerChannel;
|
||||
const idSoundShader *soundShader;
|
||||
idSampleDecoder * decoder;
|
||||
float diversity;
|
||||
float lastVolume; // last calculated volume based on distance
|
||||
float lastV[6]; // last calculated volume for each speaker, so we can smoothly fade
|
||||
idSoundFade channelFade;
|
||||
bool triggered;
|
||||
ALuint openalSource;
|
||||
ALuint openalStreamingOffset;
|
||||
ALuint openalStreamingBuffer[3];
|
||||
ALuint lastopenalStreamingBuffer[3];
|
||||
|
||||
bool disallowSlow;
|
||||
|
||||
};
|
||||
|
||||
class idSoundEmitterLocal : public idSoundEmitter {
|
||||
public:
|
||||
|
||||
idSoundEmitterLocal( void );
|
||||
virtual ~idSoundEmitterLocal( void );
|
||||
|
||||
//----------------------------------------------
|
||||
|
||||
// the "time" parameters should be game time in msec, which is used to make queries
|
||||
// return deterministic values regardless of async buffer scheduling
|
||||
|
||||
// a non-immediate free will let all currently playing sounds complete
|
||||
virtual void Free( bool immediate );
|
||||
|
||||
// the parms specified will be the default overrides for all sounds started on this emitter.
|
||||
// NULL is acceptable for parms
|
||||
virtual void UpdateEmitter( const idVec3 &origin, int listenerId, const soundShaderParms_t *parms );
|
||||
|
||||
// returns the length of the started sound in msec
|
||||
virtual int StartSound( const idSoundShader *shader, const s_channelType channel, float diversity = 0, int shaderFlags = 0, bool allowSlow = true /* D3XP */ );
|
||||
|
||||
// can pass SCHANNEL_ANY
|
||||
virtual void ModifySound( const s_channelType channel, const soundShaderParms_t *parms );
|
||||
virtual void StopSound( const s_channelType channel );
|
||||
virtual void FadeSound( const s_channelType channel, float to, float over );
|
||||
|
||||
virtual bool CurrentlyPlaying( void ) const;
|
||||
|
||||
// can pass SCHANNEL_ANY
|
||||
virtual float CurrentAmplitude( void );
|
||||
|
||||
// used for save games
|
||||
virtual int Index( void ) const;
|
||||
|
||||
//----------------------------------------------
|
||||
|
||||
void Clear( void );
|
||||
|
||||
void OverrideParms( const soundShaderParms_t *base, const soundShaderParms_t *over, soundShaderParms_t *out );
|
||||
void CheckForCompletion( int current44kHzTime );
|
||||
void Spatialize( idVec3 listenerPos, int listenerArea, idRenderWorld *rw );
|
||||
|
||||
idSoundWorldLocal * soundWorld; // the world that holds this emitter
|
||||
|
||||
int index; // in world emitter list
|
||||
removeStatus_t removeStatus;
|
||||
|
||||
idVec3 origin;
|
||||
int listenerId;
|
||||
soundShaderParms_t parms; // default overrides for all channels
|
||||
|
||||
|
||||
// the following are calculated in UpdateEmitter, and don't need to be archived
|
||||
float maxDistance; // greatest of all playing channel distances
|
||||
int lastValidPortalArea; // so an emitter that slides out of the world continues playing
|
||||
bool playing; // if false, no channel is active
|
||||
bool hasShakes;
|
||||
idVec3 spatializedOrigin; // the virtual sound origin, either the real sound origin,
|
||||
// or a point through a portal chain
|
||||
float realDistance; // in meters
|
||||
float distance; // in meters, this may be the straight-line distance, or
|
||||
// it may go through a chain of portals. If there
|
||||
// is not an open-portal path, distance will be > maxDistance
|
||||
|
||||
// a single soundEmitter can have many channels playing from the same point
|
||||
idSoundChannel channels[SOUND_MAX_CHANNELS];
|
||||
|
||||
idSlowChannel slowChannels[SOUND_MAX_CHANNELS];
|
||||
|
||||
idSlowChannel GetSlowChannel( const idSoundChannel *chan );
|
||||
void SetSlowChannel( const idSoundChannel *chan, idSlowChannel slow );
|
||||
void ResetSlowChannel( const idSoundChannel *chan );
|
||||
|
||||
// this is just used for feedback to the game or rendering system:
|
||||
// flashing lights and screen shakes. Because the material expression
|
||||
// evaluation doesn't do common subexpression removal, we cache the
|
||||
// last generated value
|
||||
int ampTime;
|
||||
float amplitude;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===================================================================================
|
||||
|
||||
idSoundWorldLocal
|
||||
|
||||
===================================================================================
|
||||
*/
|
||||
|
||||
class s_stats {
|
||||
public:
|
||||
s_stats( void ) {
|
||||
rinuse = 0;
|
||||
runs = 1;
|
||||
timeinprocess = 0;
|
||||
missedWindow = 0;
|
||||
missedUpdateWindow = 0;
|
||||
activeSounds = 0;
|
||||
}
|
||||
int rinuse;
|
||||
int runs;
|
||||
int timeinprocess;
|
||||
int missedWindow;
|
||||
int missedUpdateWindow;
|
||||
int activeSounds;
|
||||
};
|
||||
|
||||
typedef struct soundPortalTrace_s {
|
||||
int portalArea;
|
||||
const struct soundPortalTrace_s *prevStack;
|
||||
} soundPortalTrace_t;
|
||||
|
||||
class idSoundWorldLocal : public idSoundWorld {
|
||||
public:
|
||||
virtual ~idSoundWorldLocal( void );
|
||||
|
||||
// call at each map start
|
||||
virtual void ClearAllSoundEmitters( void );
|
||||
virtual void StopAllSounds( void );
|
||||
|
||||
// get a new emitter that can play sounds in this world
|
||||
virtual idSoundEmitter *AllocSoundEmitter( void );
|
||||
|
||||
// for load games
|
||||
virtual idSoundEmitter *EmitterForIndex( int index );
|
||||
|
||||
// query data from all emitters in the world
|
||||
virtual float CurrentShakeAmplitudeForPosition( const int time, const idVec3 &listererPosition );
|
||||
|
||||
// where is the camera/microphone
|
||||
// listenerId allows listener-private sounds to be added
|
||||
virtual void PlaceListener( const idVec3 &origin, const idMat3 &axis, const int listenerId, const int gameTime, const idStr& areaName );
|
||||
|
||||
// fade all sounds in the world with a given shader soundClass
|
||||
// to is in Db (sigh), over is in seconds
|
||||
virtual void FadeSoundClasses( const int soundClass, const float to, const float over );
|
||||
|
||||
// dumps the current state and begins archiving commands
|
||||
virtual void StartWritingDemo( idDemoFile *demo );
|
||||
virtual void StopWritingDemo( void );
|
||||
|
||||
// read a sound command from a demo file
|
||||
virtual void ProcessDemoCommand( idDemoFile *readDemo );
|
||||
|
||||
// background music
|
||||
virtual void PlayShaderDirectly( const char *name, int channel = -1 );
|
||||
|
||||
// pause and unpause the sound world
|
||||
virtual void Pause( void );
|
||||
virtual void UnPause( void );
|
||||
virtual bool IsPaused( void );
|
||||
|
||||
// avidump
|
||||
virtual void AVIOpen( const char *path, const char *name );
|
||||
virtual void AVIClose( void );
|
||||
|
||||
// SaveGame Support
|
||||
virtual void WriteToSaveGame( idFile *savefile );
|
||||
virtual void ReadFromSaveGame( idFile *savefile );
|
||||
|
||||
virtual void ReadFromSaveGameSoundChannel( idFile *saveGame, idSoundChannel *ch );
|
||||
virtual void ReadFromSaveGameSoundShaderParams( idFile *saveGame, soundShaderParms_t *params );
|
||||
virtual void WriteToSaveGameSoundChannel( idFile *saveGame, idSoundChannel *ch );
|
||||
virtual void WriteToSaveGameSoundShaderParams( idFile *saveGame, soundShaderParms_t *params );
|
||||
|
||||
virtual void SetSlowmo( bool active );
|
||||
virtual void SetSlowmoSpeed( float speed );
|
||||
virtual void SetEnviroSuit( bool active );
|
||||
|
||||
//=======================================
|
||||
|
||||
idSoundWorldLocal( void );
|
||||
|
||||
void Shutdown( void );
|
||||
void Init( idRenderWorld *rw );
|
||||
void ClearBuffer( void );
|
||||
|
||||
// update
|
||||
void ForegroundUpdate( int currentTime );
|
||||
void OffsetSoundTime( int offset44kHz );
|
||||
|
||||
idSoundEmitterLocal * AllocLocalSoundEmitter();
|
||||
void CalcEars( int numSpeakers, idVec3 realOrigin, idVec3 listenerPos, idMat3 listenerAxis, float ears[6], float spatialize );
|
||||
void AddChannelContribution( idSoundEmitterLocal *sound, idSoundChannel *chan,
|
||||
int current44kHz, int numSpeakers, float *finalMixBuffer );
|
||||
void MixLoop( int current44kHz, int numSpeakers, float *finalMixBuffer );
|
||||
void AVIUpdate( void );
|
||||
void ResolveOrigin( const int stackDepth, const soundPortalTrace_t *prevStack, const int soundArea, const float dist, const idVec3& soundOrigin, idSoundEmitterLocal *def );
|
||||
float FindAmplitude( idSoundEmitterLocal *sound, const int localTime, const idVec3 *listenerPosition, const s_channelType channel, bool shakesOnly );
|
||||
|
||||
//============================================
|
||||
|
||||
idRenderWorld * rw; // for portals and debug drawing
|
||||
idDemoFile * writeDemo; // if not NULL, archive commands here
|
||||
|
||||
idMat3 listenerAxis;
|
||||
idVec3 listenerPos; // position in meters
|
||||
int listenerPrivateId;
|
||||
idVec3 listenerQU; // position in "quake units"
|
||||
int listenerArea;
|
||||
idStr listenerAreaName;
|
||||
int listenerEnvironmentID;
|
||||
|
||||
int gameMsec;
|
||||
int game44kHz;
|
||||
int pause44kHz;
|
||||
int lastAVI44kHz; // determine when we need to mix and write another block
|
||||
|
||||
idList<idSoundEmitterLocal *>emitters;
|
||||
|
||||
idSoundFade soundClassFade[SOUND_MAX_CLASSES]; // for global sound fading
|
||||
|
||||
// avi stuff
|
||||
idFile * fpa[6];
|
||||
idStr aviDemoPath;
|
||||
idStr aviDemoName;
|
||||
|
||||
idSoundEmitterLocal * localSound; // just for playShaderDirectly()
|
||||
|
||||
bool slowmoActive;
|
||||
float slowmoSpeed;
|
||||
bool enviroSuitActive;
|
||||
};
|
||||
|
||||
/*
|
||||
===================================================================================
|
||||
|
||||
idSoundSystemLocal
|
||||
|
||||
===================================================================================
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
ALuint handle;
|
||||
int startTime;
|
||||
idSoundChannel *chan;
|
||||
bool inUse;
|
||||
bool looping;
|
||||
bool stereo;
|
||||
} openalSource_t;
|
||||
|
||||
class idSoundSystemLocal : public idSoundSystem {
|
||||
public:
|
||||
idSoundSystemLocal( ) {
|
||||
isInitialized = false;
|
||||
}
|
||||
|
||||
// all non-hardware initialization
|
||||
virtual void Init( void );
|
||||
|
||||
// shutdown routine
|
||||
virtual void Shutdown( void );
|
||||
virtual void ClearBuffer( void );
|
||||
|
||||
// sound is attached to the window, and must be recreated when the window is changed
|
||||
virtual bool ShutdownHW( void );
|
||||
virtual bool InitHW( void );
|
||||
|
||||
// async loop, called at 60Hz
|
||||
virtual int AsyncUpdate( int time );
|
||||
// async loop, when the sound driver uses a write strategy
|
||||
virtual int AsyncUpdateWrite( int time );
|
||||
// direct mixing called from the sound driver thread for OSes that support it
|
||||
virtual int AsyncMix( int soundTime, float *mixBuffer );
|
||||
|
||||
virtual void SetMute( bool mute );
|
||||
|
||||
virtual cinData_t ImageForTime( const int milliseconds, const bool waveform );
|
||||
|
||||
int GetSoundDecoderInfo( int index, soundDecoderInfo_t &decoderInfo );
|
||||
|
||||
// if rw == NULL, no portal occlusion or rendered debugging is available
|
||||
virtual idSoundWorld *AllocSoundWorld( idRenderWorld *rw );
|
||||
|
||||
// specifying NULL will cause silence to be played
|
||||
virtual void SetPlayingSoundWorld( idSoundWorld *soundWorld );
|
||||
|
||||
// some tools, like the sound dialog, may be used in both the game and the editor
|
||||
// This can return NULL, so check!
|
||||
virtual idSoundWorld *GetPlayingSoundWorld( void );
|
||||
|
||||
virtual void BeginLevelLoad( void );
|
||||
virtual void EndLevelLoad( const char *mapString );
|
||||
|
||||
virtual void PrintMemInfo( MemInfo_t *mi );
|
||||
|
||||
virtual int IsEAXAvailable( void );
|
||||
|
||||
//-------------------------
|
||||
|
||||
int GetCurrent44kHzTime( void ) const;
|
||||
float dB2Scale( const float val ) const;
|
||||
int SamplesToMilliseconds( int samples ) const;
|
||||
int MillisecondsToSamples( int ms ) const;
|
||||
|
||||
void DoEnviroSuit( float* samples, int numSamples, int numSpeakers );
|
||||
|
||||
ALuint AllocOpenALSource( idSoundChannel *chan, bool looping, bool stereo );
|
||||
void FreeOpenALSource( ALuint handle );
|
||||
|
||||
idAudioHardware * snd_audio_hw;
|
||||
idSoundCache * soundCache;
|
||||
|
||||
idSoundWorldLocal * currentSoundWorld; // the one to mix each async tic
|
||||
|
||||
int olddwCurrentWritePos; // statistics
|
||||
int buffers; // statistics
|
||||
int CurrentSoundTime; // set by the async thread and only used by the main thread
|
||||
|
||||
unsigned int nextWriteBlock;
|
||||
|
||||
float realAccum[6*MIXBUFFER_SAMPLES+16];
|
||||
float * finalMixBuffer; // points inside realAccum at a 16 byte aligned boundary
|
||||
|
||||
bool isInitialized;
|
||||
bool muted;
|
||||
bool shutdown;
|
||||
|
||||
s_stats soundStats; // NOTE: updated throughout the code, not displayed anywhere
|
||||
|
||||
int meterTops[256];
|
||||
int meterTopsTime[256];
|
||||
|
||||
dword * graph;
|
||||
|
||||
float volumesDB[1200]; // dB to float volume conversion
|
||||
|
||||
idList<SoundFX*> fxList;
|
||||
|
||||
ALCdevice *openalDevice;
|
||||
ALCcontext *openalContext;
|
||||
ALsizei openalSourceCount;
|
||||
openalSource_t openalSources[256];
|
||||
EAXSet alEAXSet;
|
||||
EAXGet alEAXGet;
|
||||
EAXSetBufferMode alEAXSetBufferMode;
|
||||
EAXGetBufferMode alEAXGetBufferMode;
|
||||
idEFXFile EFXDatabase;
|
||||
bool efxloaded;
|
||||
// latches
|
||||
static bool useOpenAL;
|
||||
static bool useEAXReverb;
|
||||
// mark available during initialization, or through an explicit test
|
||||
static int EAXAvailable;
|
||||
|
||||
|
||||
static idCVar s_noSound;
|
||||
static idCVar s_quadraticFalloff;
|
||||
static idCVar s_drawSounds;
|
||||
static idCVar s_minVolume6;
|
||||
static idCVar s_dotbias6;
|
||||
static idCVar s_minVolume2;
|
||||
static idCVar s_dotbias2;
|
||||
static idCVar s_spatializationDecay;
|
||||
static idCVar s_showStartSound;
|
||||
static idCVar s_maxSoundsPerShader;
|
||||
static idCVar s_reverse;
|
||||
static idCVar s_showLevelMeter;
|
||||
static idCVar s_meterTopTime;
|
||||
static idCVar s_volume;
|
||||
static idCVar s_constantAmplitude;
|
||||
static idCVar s_playDefaultSound;
|
||||
static idCVar s_useOcclusion;
|
||||
static idCVar s_subFraction;
|
||||
static idCVar s_globalFraction;
|
||||
static idCVar s_doorDistanceAdd;
|
||||
static idCVar s_singleEmitter;
|
||||
static idCVar s_numberOfSpeakers;
|
||||
static idCVar s_force22kHz;
|
||||
static idCVar s_clipVolumes;
|
||||
static idCVar s_realTimeDecoding;
|
||||
static idCVar s_libOpenAL;
|
||||
static idCVar s_useOpenAL;
|
||||
static idCVar s_useEAXReverb;
|
||||
static idCVar s_muteEAXReverb;
|
||||
static idCVar s_decompressionLimit;
|
||||
|
||||
static idCVar s_slowAttenuate;
|
||||
|
||||
static idCVar s_enviroSuitCutoffFreq;
|
||||
static idCVar s_enviroSuitCutoffQ;
|
||||
static idCVar s_enviroSuitSkipLowpass;
|
||||
static idCVar s_enviroSuitSkipReverb;
|
||||
|
||||
static idCVar s_reverbTime;
|
||||
static idCVar s_reverbFeedback;
|
||||
static idCVar s_enviroSuitVolumeScale;
|
||||
static idCVar s_skipHelltimeFX;
|
||||
};
|
||||
|
||||
extern idSoundSystemLocal soundSystemLocal;
|
||||
|
||||
|
||||
/*
|
||||
===================================================================================
|
||||
|
||||
This class holds the actual wavefile bitmap, size, and info.
|
||||
|
||||
===================================================================================
|
||||
*/
|
||||
|
||||
const int SCACHE_SIZE = MIXBUFFER_SAMPLES*20; // 1/2 of a second (aroundabout)
|
||||
|
||||
class idSoundSample {
|
||||
public:
|
||||
idSoundSample();
|
||||
~idSoundSample();
|
||||
|
||||
idStr name; // name of the sample file
|
||||
ID_TIME_T timestamp; // the most recent of all images used in creation, for reloadImages command
|
||||
|
||||
waveformatex_t objectInfo; // what are we caching
|
||||
int objectSize; // size of waveform in samples, excludes the header
|
||||
int objectMemSize; // object size in memory
|
||||
byte * nonCacheData; // if it's not cached
|
||||
byte * amplitudeData; // precomputed min,max amplitude pairs
|
||||
ALuint openalBuffer; // openal buffer
|
||||
bool hardwareBuffer;
|
||||
bool defaultSound;
|
||||
bool onDemand;
|
||||
bool purged;
|
||||
bool levelLoadReferenced; // so we can tell which samples aren't needed any more
|
||||
|
||||
int LengthIn44kHzSamples() const;
|
||||
ID_TIME_T GetNewTimeStamp( void ) const;
|
||||
void MakeDefault(); // turns it into a beep
|
||||
void Load(); // loads the current sound based on name
|
||||
void Reload( bool force ); // reloads if timestamp has changed, or always if force
|
||||
void PurgeSoundSample(); // frees all data
|
||||
void CheckForDownSample(); // down sample if required
|
||||
bool FetchFromCache( int offset, const byte **output, int *position, int *size, const bool allowIO );
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===================================================================================
|
||||
|
||||
Sound sample decoder.
|
||||
|
||||
===================================================================================
|
||||
*/
|
||||
|
||||
class idSampleDecoder {
|
||||
public:
|
||||
static void Init( void );
|
||||
static void Shutdown( void );
|
||||
static idSampleDecoder *Alloc( void );
|
||||
static void Free( idSampleDecoder *decoder );
|
||||
static int GetNumUsedBlocks( void );
|
||||
static int GetUsedBlockMemory( void );
|
||||
|
||||
virtual ~idSampleDecoder( void ) {}
|
||||
virtual void Decode( idSoundSample *sample, int sampleOffset44k, int sampleCount44k, float *dest ) = 0;
|
||||
virtual void ClearDecoder( void ) = 0;
|
||||
virtual idSoundSample * GetSample( void ) const = 0;
|
||||
virtual int GetLastDecodeTime( void ) const = 0;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===================================================================================
|
||||
|
||||
The actual sound cache.
|
||||
|
||||
===================================================================================
|
||||
*/
|
||||
|
||||
class idSoundCache {
|
||||
public:
|
||||
idSoundCache();
|
||||
~idSoundCache();
|
||||
|
||||
idSoundSample * FindSound( const idStr &fname, bool loadOnDemandOnly );
|
||||
|
||||
const int GetNumObjects( void ) { return listCache.Num(); }
|
||||
const idSoundSample * GetObject( const int index ) const;
|
||||
|
||||
void ReloadSounds( bool force );
|
||||
|
||||
void BeginLevelLoad();
|
||||
void EndLevelLoad();
|
||||
|
||||
void PrintMemInfo( MemInfo_t *mi );
|
||||
|
||||
private:
|
||||
bool insideLevelLoad;
|
||||
idList<idSoundSample*> listCache;
|
||||
};
|
||||
|
||||
#endif /* !__SND_LOCAL_H__ */
|
||||
Reference in New Issue
Block a user