DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

snd_local.h (14936B)


      1 /*
      2 ===========================================================================
      3 
      4 Doom 3 BFG Edition GPL Source Code
      5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 
      6 
      7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").  
      8 
      9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
     10 it under the terms of the GNU General Public License as published by
     11 the Free Software Foundation, either version 3 of the License, or
     12 (at your option) any later version.
     13 
     14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
     15 but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 GNU General Public License for more details.
     18 
     19 You should have received a copy of the GNU General Public License
     20 along with Doom 3 BFG Edition Source Code.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 In addition, the Doom 3 BFG Edition 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 BFG Edition Source Code.  If not, please request a copy in writing from id Software at the address below.
     23 
     24 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.
     25 
     26 ===========================================================================
     27 */
     28 
     29 #ifndef __SND_LOCAL_H__
     30 #define __SND_LOCAL_H__
     31 
     32 #include "WaveFile.h"
     33 
     34 // Maximum number of voices we can have allocated
     35 #define MAX_HARDWARE_VOICES 48
     36 
     37 // A single voice can play multiple channels (up to 5.1, but most commonly stereo)
     38 // This is the maximum number of channels which can play simultaneously
     39 // This is limited primarily by seeking on the optical drive, secondarily by memory consumption, and tertiarily by CPU time spent mixing
     40 #define MAX_HARDWARE_CHANNELS 64
     41 
     42 // We may need up to 3 buffers for each hardware voice if they are all long sounds
     43 #define MAX_SOUND_BUFFERS ( MAX_HARDWARE_VOICES * 3 )
     44 
     45 // Maximum number of channels in a sound sample
     46 #define MAX_CHANNELS_PER_VOICE	8
     47 
     48 /*
     49 ========================
     50 MsecToSamples
     51 SamplesToMsec
     52 ========================
     53 */
     54 ID_INLINE_EXTERN uint32 MsecToSamples( uint32 msec, uint32 sampleRate ) { return ( msec * ( sampleRate / 100 ) ) / 10; }
     55 ID_INLINE_EXTERN uint32 SamplesToMsec( uint32 samples, uint32 sampleRate ) { return sampleRate < 100 ? 0 : ( samples * 10 ) / ( sampleRate / 100 ); }
     56 
     57 /*
     58 ========================
     59 DBtoLinear
     60 LinearToDB
     61 ========================
     62 */
     63 ID_INLINE_EXTERN float DBtoLinear( float db ) { return idMath::Pow( 2.0f, db * ( 1.0f / 6.0f ) ); }
     64 ID_INLINE_EXTERN float LinearToDB( float linear ) { return ( linear > 0.0f ) ? ( idMath::Log( linear ) * ( 6.0f / 0.693147181f ) ) : -999.0f; }
     65 
     66 // demo sound commands
     67 typedef enum {
     68 	SCMD_STATE,				// followed by a load game state
     69 	SCMD_PLACE_LISTENER,
     70 	SCMD_ALLOC_EMITTER,
     71 
     72 	SCMD_FREE,
     73 	SCMD_UPDATE,
     74 	SCMD_START,
     75 	SCMD_MODIFY,
     76 	SCMD_STOP,
     77 	SCMD_FADE
     78 } soundDemoCommand_t;
     79 
     80 #include "SoundVoice.h"
     81 
     82 
     83 #define OPERATION_SET 1
     84 
     85 #include <dxsdkver.h>
     86 
     87 #include <xaudio2.h>
     88 #include <xaudio2fx.h>
     89 #include <X3DAudio.h>
     90 #include <xma2defs.h>
     91 #include "XAudio2/XA2_SoundSample.h"
     92 #include "XAudio2/XA2_SoundVoice.h"
     93 #include "XAudio2/XA2_SoundHardware.h"
     94 
     95 
     96 
     97 //------------------------
     98 // Listener data
     99 //------------------------
    100 struct listener_t {
    101 	idMat3	axis;		// orientation of the listener
    102 	idVec3	pos;		// position in meters
    103 	int		id;			// the entity number, used to detect when a sound is local
    104 	int		area;		// area number the listener is in
    105 };
    106 
    107 class idSoundFade {
    108 public:
    109 	int		fadeStartTime;
    110 	int		fadeEndTime;
    111 	float	fadeStartVolume;
    112 	float	fadeEndVolume;
    113 
    114 
    115 public:
    116 	idSoundFade() { Clear(); }
    117 
    118 	void	Clear();
    119 	void	SetVolume( float to );
    120 	void	Fade( float to, int length, int soundTime );
    121 
    122 	float	GetVolume( int soundTime ) const;
    123 };
    124 
    125 /*
    126 ================================================
    127 idSoundChannel
    128 ================================================
    129 */
    130 class idSoundChannel {
    131 public:
    132 	bool	CanMute() const;
    133 
    134 	void	Mute();
    135 	bool	CheckForCompletion( int currentTime );
    136 
    137 	void	UpdateVolume( int currentTime );
    138 	void	UpdateHardware( float volumeAdd, int currentTime );
    139 
    140 	// returns true if this channel is marked as looping
    141 	bool	IsLooping() const;
    142 
    143 	class idSoundEmitterLocal *	emitter;
    144 
    145 	int						startTime;
    146 	int						endTime;
    147 	int						logicalChannel;
    148 	bool					allowSlow;
    149 
    150 	soundShaderParms_t		parms;				// combines shader parms and per-channel overrides
    151 	const idSoundShader *	soundShader;
    152 	idSoundSample *			leadinSample;
    153 	idSoundSample *			loopingSample;
    154 	idSoundFade				volumeFade;
    155 
    156 	float					volumeDB;			// last volume at which this channel will play (calculated in UpdateVolume)
    157 	float					currentAmplitude;	// current amplitude on the hardware voice
    158 
    159 	// hardwareVoice will be freed and NULL'd when a sound is out of range, 
    160 	// and reallocated when it comes back in range
    161 	idSoundVoice *			hardwareVoice;
    162 
    163 	// only allocated by the soundWorld block allocator
    164 	idSoundChannel();
    165 	~idSoundChannel();
    166 };
    167 
    168 // Maximum number of SoundChannels for a single SoundEmitter.
    169 // This is probably excessive...
    170 const int MAX_CHANNELS_PER_EMITTER = 16;
    171 
    172 /*
    173 ===================================================================================
    174 
    175 idSoundWorldLocal
    176 
    177 ===================================================================================
    178 */
    179 
    180 class idSoundWorldLocal : public idSoundWorld {
    181 public:
    182 							idSoundWorldLocal();
    183 	virtual					~idSoundWorldLocal();
    184 
    185 	//------------------------
    186 	// Functions from idSoundWorld, implemented in SoundWorld.cpp
    187 	//------------------------
    188 
    189 	// Called at map start
    190 	virtual void			ClearAllSoundEmitters();
    191 
    192 	// stop all playing sounds
    193 	virtual void			StopAllSounds();
    194 
    195 	// get a new emitter that can play sounds in this world
    196 	virtual idSoundEmitter *AllocSoundEmitter();
    197 
    198 	// for load games
    199 	virtual idSoundEmitter *EmitterForIndex( int index );
    200 
    201 	// query data from all emitters in the world
    202 	virtual float			CurrentShakeAmplitude();
    203 
    204 	// where is the camera
    205 	virtual void			PlaceListener( const idVec3 &origin, const idMat3 &axis, const int listenerId );
    206 
    207 	// fade all sounds in the world with a given shader soundClass
    208 	// to is in Db, over is in seconds
    209 	virtual void			FadeSoundClasses( const int soundClass, const float to, const float over );
    210 
    211 	// dumps the current state and begins archiving commands
    212 	virtual void			StartWritingDemo( idDemoFile *demo );
    213 	virtual void			StopWritingDemo();
    214 
    215 	// read a sound command from a demo file
    216 	virtual void			ProcessDemoCommand( idDemoFile *readDemo );
    217 
    218 	// menu sounds
    219 	virtual int				PlayShaderDirectly( const char *name, int channel = -1 );
    220 
    221 	virtual void			Skip( int time );
    222 
    223 	virtual void			Pause();
    224 	virtual void			UnPause();
    225 	virtual bool			IsPaused() { return isPaused; }
    226 
    227 	virtual int				GetSoundTime();
    228 
    229 	// avidump
    230 	virtual void			AVIOpen( const char *path, const char *name );
    231 	virtual void			AVIClose();
    232 
    233 	// SaveGame Support
    234 	virtual void			WriteToSaveGame( idFile *savefile );
    235 	virtual void			ReadFromSaveGame( idFile *savefile );
    236 
    237 	virtual void			SetSlowmoSpeed( float speed );
    238 	virtual void			SetEnviroSuit( bool active );
    239 
    240 	//=======================================
    241 
    242 	//------------------------
    243 	// Random stuff that's not exposed outside the sound system
    244 	//------------------------
    245 	void			Update();
    246 	void			OnReloadSound( const idDecl *decl );
    247 
    248 	idSoundChannel *	AllocSoundChannel();
    249 	void				FreeSoundChannel( idSoundChannel * );
    250 
    251 public:
    252 	// even though all these variables are public, nobody outside the sound system includes SoundWorld_local.h
    253 	// so this is equivalent to making it private and friending all the other classes in the sound system
    254 
    255 	idSoundFade			volumeFade;						// master volume knob for the entire world
    256 	idSoundFade			soundClassFade[SOUND_MAX_CLASSES];
    257 
    258 	idRenderWorld *		renderWorld;	// for debug visualization and light amplitude sampling
    259 	idDemoFile *		writeDemo;		// if not NULL, archive commands here
    260 
    261 	float				currentCushionDB;	// channels at or below this level will be faded to 0
    262 	float				shakeAmp;			// last calculated shake amplitude
    263 
    264 	listener_t			listener;
    265 	idList<idSoundEmitterLocal *, TAG_AUDIO>	emitters;
    266 
    267 	idSoundEmitter *	localSound;			// for PlayShaderDirectly()
    268 
    269 	idBlockAlloc<idSoundEmitterLocal, 16>	emitterAllocator;
    270 	idBlockAlloc<idSoundChannel, 16>		channelAllocator;
    271 
    272 	idSoundFade				pauseFade;
    273 	int						pausedTime;
    274 	int						accumulatedPauseTime;
    275 	bool					isPaused;
    276 
    277 	float					slowmoSpeed;
    278 	bool					enviroSuitActive;
    279 
    280 public: 
    281 	struct soundPortalTrace_t {
    282 		int		portalArea;
    283 		const soundPortalTrace_t * prevStack;
    284 	};
    285 
    286 	void			ResolveOrigin( const int stackDepth, const soundPortalTrace_t * prevStack, const int soundArea, const float dist, const idVec3 & soundOrigin, idSoundEmitterLocal * def );
    287 };
    288 
    289 
    290 /*
    291 ================================================
    292 idSoundEmitterLocal 
    293 ================================================
    294 */
    295 class idSoundEmitterLocal : public idSoundEmitter {
    296 public:
    297 	virtual void	Free( bool immediate );
    298 
    299 	virtual void	Reset();
    300 
    301 	virtual void	UpdateEmitter( const idVec3 &origin, int listenerId, const soundShaderParms_t *parms );
    302 
    303 	virtual int		StartSound( const idSoundShader *shader, const s_channelType channel, float diversity = 0, int shaderFlags = 0, bool allowSlow = true );
    304 
    305 	virtual void	ModifySound( const s_channelType channel, const soundShaderParms_t *parms );
    306 	virtual void	StopSound( const s_channelType channel );
    307 
    308 	virtual void	FadeSound( const s_channelType channel, float to, float over );
    309 
    310 	virtual bool	CurrentlyPlaying( const s_channelType channel = SCHANNEL_ANY ) const;
    311 
    312 	virtual	float	CurrentAmplitude();
    313 
    314 	virtual	int		Index() const;
    315 
    316 	//----------------------------------------------
    317 
    318 	void			Init( int i, idSoundWorldLocal * sw );
    319 
    320 	// Returns true if the emitter should be freed.
    321 	bool			CheckForCompletion( int currentTime );
    322 
    323 	void			OverrideParms( const soundShaderParms_t * base, const soundShaderParms_t * over, soundShaderParms_t * out );
    324 
    325 	void			Update( int currentTime );
    326 	void			OnReloadSound( const idDecl *decl );
    327 
    328 	//----------------------------------------------
    329 
    330 	idSoundWorldLocal *		soundWorld;						// the world that holds this emitter
    331 
    332 	int			index;							// in world emitter list
    333 	bool		canFree;						// if true, this emitter can be canFree (once channels.Num() == 0)
    334 
    335 	// a single soundEmitter can have many channels playing from the same point
    336 	idStaticList<idSoundChannel *, MAX_CHANNELS_PER_EMITTER> channels;
    337 
    338 	//----- set by UpdateEmitter -----
    339 	idVec3				origin;
    340 	soundShaderParms_t	parms;
    341 	int					emitterId;						// sounds will be full volume when emitterId == listenerId
    342 
    343 	//----- set by Update -----
    344 	int			lastValidPortalArea;
    345 	float		directDistance;
    346 	float		spatializedDistance;
    347 	idVec3		spatializedOrigin;
    348 
    349 	// sound emitters are only allocated by the soundWorld block allocator
    350 					idSoundEmitterLocal();
    351 	virtual			~idSoundEmitterLocal();
    352 };
    353 
    354 
    355 /*
    356 ===================================================================================
    357 
    358 idSoundSystemLocal
    359 
    360 ===================================================================================
    361 */
    362 class idSoundSystemLocal : public idSoundSystem {
    363 public:
    364 	// all non-hardware initialization
    365 	virtual void			Init();
    366 
    367 	// shutdown routine
    368 	virtual	void			Shutdown();
    369 
    370 	virtual idSoundWorld *	AllocSoundWorld( idRenderWorld *rw );
    371 	virtual void			FreeSoundWorld( idSoundWorld *sw );
    372 
    373 	// specifying NULL will cause silence to be played
    374 	virtual void			SetPlayingSoundWorld( idSoundWorld *soundWorld );
    375 
    376 	// some tools, like the sound dialog, may be used in both the game and the editor
    377 	// This can return NULL, so check!
    378 	virtual idSoundWorld *	GetPlayingSoundWorld();
    379 
    380 	// sends the current playing sound world information to the sound hardware
    381 	virtual void			Render();
    382 
    383 	// Mutes the SSG_MUSIC group
    384 	virtual void			MuteBackgroundMusic( bool mute ) { musicMuted = mute; }
    385 
    386 	// sets the final output volume to 0
    387 	// This should only be used when the app is deactivated
    388 	// Since otherwise there will be problems with different subsystems muting and unmuting at different times
    389 	virtual void			SetMute( bool mute ) { muted = mute; }
    390 	virtual bool			IsMuted() { return muted; }
    391 
    392 	virtual void			OnReloadSound( const idDecl * sound );
    393 
    394 	virtual void			StopAllSounds();
    395 
    396 	virtual void			InitStreamBuffers();
    397 	virtual void			FreeStreamBuffers();
    398 
    399 	virtual void *			GetIXAudio2() const;
    400 
    401 	// for the sound level meter window
    402 	virtual cinData_t		ImageForTime( const int milliseconds, const bool waveform );
    403 
    404 	// Free all sounds loaded during the last map load
    405 	virtual	void			BeginLevelLoad();
    406 
    407 	// We might want to defer the loading of new sounds to this point
    408 	virtual	void			EndLevelLoad();
    409 
    410 	// prints memory info
    411 	virtual void			PrintMemInfo( MemInfo_t *mi );
    412 
    413 	//-------------------------
    414 
    415 	// Before a sound is reloaded, any active voices using it must
    416 	// be stopped.  Returns true if any were playing, and should be
    417 	// restarted after the sound is reloaded.
    418 	void					StopVoicesWithSample( const idSoundSample * const sample );
    419 
    420 	void					Restart();
    421 	void					SetNeedsRestart() { needsRestart = true; }
    422 
    423 	int						SoundTime() const;
    424 
    425 	// may return NULL if there are no more voices left
    426 	idSoundVoice *			AllocateVoice( const idSoundSample * leadinSample, const idSoundSample * loopingSample );
    427 	void					FreeVoice( idSoundVoice * );
    428 
    429 	idSoundSample *			LoadSample( const char * name );
    430 
    431 	virtual void			Preload( idPreloadManifest & preload );
    432 
    433 	struct bufferContext_t {
    434 		bufferContext_t() :
    435 			voice( NULL ),
    436 			sample( NULL ),
    437 			bufferNumber( 0 )
    438 		{ }
    439 		idSoundVoice_XAudio2 *	voice;
    440 		idSoundSample_XAudio2 * sample;
    441 		int bufferNumber;
    442 	};
    443 
    444 	// Get a stream buffer from the free pool, returns NULL if none are available
    445 	bufferContext_t *			ObtainStreamBufferContext();
    446 	void						ReleaseStreamBufferContext( bufferContext_t * p );
    447 
    448 	idSysMutex					streamBufferMutex;
    449 	idStaticList< bufferContext_t *, MAX_SOUND_BUFFERS > freeStreamBufferContexts;
    450 	idStaticList< bufferContext_t *, MAX_SOUND_BUFFERS > activeStreamBufferContexts;
    451 	idStaticList< bufferContext_t, MAX_SOUND_BUFFERS > bufferContexts;
    452 
    453 	idSoundWorldLocal *			currentSoundWorld;
    454 	idStaticList<idSoundWorldLocal *, 32>	soundWorlds;
    455 
    456 	idList<idSoundSample *, TAG_AUDIO>		samples;
    457 	idHashIndex					sampleHash;
    458 
    459 	idSoundHardware				hardware;
    460 
    461 	idRandom2					random;
    462 	
    463 	int							soundTime;
    464 	bool						muted;
    465 	bool						musicMuted;
    466 	bool						needsRestart;
    467 
    468 	bool						insideLevelLoad;
    469 
    470 	//-------------------------
    471 
    472 	idSoundSystemLocal() :
    473 		soundTime( 0 ),
    474 		currentSoundWorld( NULL ),
    475 		muted( false ),
    476 		musicMuted( false ),
    477 		needsRestart( false )
    478 		{}
    479 };
    480 
    481 extern	idSoundSystemLocal	soundSystemLocal;
    482 
    483 #endif /* !__SND_LOCAL_H__ */