doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
sound.h
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 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.
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 __SOUND__
30 #define __SOUND__
31 
32 /*
33 ===============================================================================
34 
35  SOUND SHADER DECL
36 
37 ===============================================================================
38 */
39 
40 // unfortunately, our minDistance / maxDistance is specified in meters, and
41 // we have far too many of them to change at this time.
42 const float DOOM_TO_METERS = 0.0254f; // doom to meters
43 const float METERS_TO_DOOM = (1.0f/DOOM_TO_METERS); // meters to doom
44 
45 class idSoundSample;
46 
47 // sound shader flags
48 static const int SSF_PRIVATE_SOUND = BIT(0); // only plays for the current listenerId
49 static const int SSF_ANTI_PRIVATE_SOUND =BIT(1); // plays for everyone but the current listenerId
50 static const int SSF_NO_OCCLUSION = BIT(2); // don't flow through portals, only use straight line
51 static const int SSF_GLOBAL = BIT(3); // play full volume to all speakers and all listeners
52 static const int SSF_OMNIDIRECTIONAL = BIT(4); // fall off with distance, but play same volume in all speakers
53 static const int SSF_LOOPING = BIT(5); // repeat the sound continuously
54 static const int SSF_PLAY_ONCE = BIT(6); // never restart if already playing on any channel of a given emitter
55 static const int SSF_UNCLAMPED = BIT(7); // don't clamp calculated volumes at 1.0
56 static const int SSF_NO_FLICKER = BIT(8); // always return 1.0 for volume queries
57 static const int SSF_NO_DUPS = BIT(9); // try not to play the same sound twice in a row
58 
59 // these options can be overriden from sound shader defaults on a per-emitter and per-channel basis
60 typedef struct {
61  float minDistance;
62  float maxDistance;
63  float volume; // in dB, unfortunately. Negative values get quieter
64  float shakes;
65  int soundShaderFlags; // SSF_* bit flags
66  int soundClass; // for global fading of sounds
68 
69 
70 const int SOUND_MAX_LIST_WAVS = 32;
71 
72 // sound classes are used to fade most sounds down inside cinematics, leaving dialog
73 // flagged with a non-zero class full volume
74 const int SOUND_MAX_CLASSES = 4;
75 
76 // it is somewhat tempting to make this a virtual class to hide the private
77 // details here, but that doesn't fit easily with the decl manager at the moment.
78 class idSoundShader : public idDecl {
79 public:
80  idSoundShader( void );
81  virtual ~idSoundShader( void );
82 
83  virtual size_t Size( void ) const;
84  virtual bool SetDefaultText( void );
85  virtual const char * DefaultDefinition( void ) const;
86  virtual bool Parse( const char *text, const int textLength );
87  virtual void FreeData( void );
88  virtual void List( void ) const;
89 
90  virtual const char * GetDescription() const;
91 
92  // so the editor can draw correct default sound spheres
93  // this is currently defined as meters, which sucks, IMHO.
94  virtual float GetMinDistance() const; // FIXME: replace this with a GetSoundShaderParms()
95  virtual float GetMaxDistance() const;
96 
97  // returns NULL if an AltSound isn't defined in the shader.
98  // we use this for pairing a specific broken light sound with a normal light sound
99  virtual const idSoundShader *GetAltSound() const;
100 
101  virtual bool HasDefaultSound() const;
102 
103  virtual const soundShaderParms_t *GetParms() const;
104  virtual int GetNumSounds() const;
105  virtual const char * GetSound( int index ) const;
106 
107  virtual bool CheckShakesAndOgg( void ) const;
108 
109 private:
110  friend class idSoundWorldLocal;
111  friend class idSoundEmitterLocal;
112  friend class idSoundChannel;
113  friend class idSoundCache;
114 
115  // options from sound shader text
116  soundShaderParms_t parms; // can be overriden on a per-channel basis
117 
118  bool onDemand; // only load when played, and free when finished
121  idStr desc; // description
123  float leadinVolume; // allows light breaking leadin sounds to be much louder than the broken loop
124 
129 
130 private:
131  void Init( void );
132  bool ParseShader( idLexer &src );
133 };
134 
135 /*
136 ===============================================================================
137 
138  SOUND EMITTER
139 
140 ===============================================================================
141 */
142 
143 // sound channels
144 static const int SCHANNEL_ANY = 0; // used in queries and commands to effect every channel at once, in
145  // startSound to have it not override any other channel
146 static const int SCHANNEL_ONE = 1; // any following integer can be used as a channel number
147 typedef int s_channelType; // the game uses its own series of enums, and we don't want to require casts
148 
149 
151 public:
152  virtual ~idSoundEmitter( void ) {}
153 
154  // a non-immediate free will let all currently playing sounds complete
155  // soundEmitters are not actually deleted, they are just marked as
156  // reusable by the soundWorld
157  virtual void Free( bool immediate ) = 0;
158 
159  // the parms specified will be the default overrides for all sounds started on this emitter.
160  // NULL is acceptable for parms
161  virtual void UpdateEmitter( const idVec3 &origin, int listenerId, const soundShaderParms_t *parms ) = 0;
162 
163  // returns the length of the started sound in msec
164  virtual int StartSound( const idSoundShader *shader, const s_channelType channel, float diversity = 0, int shaderFlags = 0, bool allowSlow = true ) = 0;
165 
166  // pass SCHANNEL_ANY to effect all channels
167  virtual void ModifySound( const s_channelType channel, const soundShaderParms_t *parms ) = 0;
168  virtual void StopSound( const s_channelType channel ) = 0;
169  // to is in Db (sigh), over is in seconds
170  virtual void FadeSound( const s_channelType channel, float to, float over ) = 0;
171 
172  // returns true if there are any sounds playing from this emitter. There is some conservative
173  // slop at the end to remove inconsistent race conditions with the sound thread updates.
174  // FIXME: network game: on a dedicated server, this will always be false
175  virtual bool CurrentlyPlaying( void ) const = 0;
176 
177  // returns a 0.0 to 1.0 value based on the current sound amplitude, allowing
178  // graphic effects to be modified in time with the audio.
179  // just samples the raw wav file, it doesn't account for volume overrides in the
180  virtual float CurrentAmplitude( void ) = 0;
181 
182  // for save games. Index will always be > 0
183  virtual int Index( void ) const = 0;
184 };
185 
186 /*
187 ===============================================================================
188 
189  SOUND WORLD
190 
191 There can be multiple independent sound worlds, just as there can be multiple
192 independent render worlds. The prime example is the editor sound preview
193 option existing simultaniously with a live game.
194 ===============================================================================
195 */
196 
198 public:
199  virtual ~idSoundWorld( void ) {}
200 
201  // call at each map start
202  virtual void ClearAllSoundEmitters( void ) = 0;
203  virtual void StopAllSounds( void ) = 0;
204 
205  // get a new emitter that can play sounds in this world
206  virtual idSoundEmitter *AllocSoundEmitter( void ) = 0;
207 
208  // for load games, index 0 will return NULL
209  virtual idSoundEmitter *EmitterForIndex( int index ) = 0;
210 
211  // query sound samples from all emitters reaching a given position
212  virtual float CurrentShakeAmplitudeForPosition( const int time, const idVec3 &listenerPosition ) = 0;
213 
214  // where is the camera/microphone
215  // listenerId allows listener-private and antiPrivate sounds to be filtered
216  // gameTime is in msec, and is used to time sound queries and removals so that they are independent
217  // of any race conditions with the async update
218  virtual void PlaceListener( const idVec3 &origin, const idMat3 &axis, const int listenerId, const int gameTime, const idStr& areaName ) = 0;
219 
220  // fade all sounds in the world with a given shader soundClass
221  // to is in Db (sigh), over is in seconds
222  virtual void FadeSoundClasses( const int soundClass, const float to, const float over ) = 0;
223 
224  // background music
225  virtual void PlayShaderDirectly( const char *name, int channel = -1 ) = 0;
226 
227  // dumps the current state and begins archiving commands
228  virtual void StartWritingDemo( idDemoFile *demo ) = 0;
229  virtual void StopWritingDemo() = 0;
230 
231  // read a sound command from a demo file
232  virtual void ProcessDemoCommand( idDemoFile *demo ) = 0;
233 
234  // pause and unpause the sound world
235  virtual void Pause( void ) = 0;
236  virtual void UnPause( void ) = 0;
237  virtual bool IsPaused( void ) = 0;
238 
239  // Write the sound output to multiple wav files. Note that this does not use the
240  // work done by AsyncUpdate, it mixes explicitly in the foreground every PlaceOrigin(),
241  // under the assumption that we are rendering out screenshots and the gameTime is going
242  // much slower than real time.
243  // path should not include an extension, and the generated filenames will be:
244  // <path>_left.raw, <path>_right.raw, or <path>_51left.raw, <path>_51right.raw,
245  // <path>_51center.raw, <path>_51lfe.raw, <path>_51backleft.raw, <path>_51backright.raw,
246  // If only two channel mixing is enabled, the left and right .raw files will also be
247  // combined into a stereo .wav file.
248  virtual void AVIOpen( const char *path, const char *name ) = 0;
249  virtual void AVIClose( void ) = 0;
250 
251  // SaveGame / demo Support
252  virtual void WriteToSaveGame( idFile *savefile ) = 0;
253  virtual void ReadFromSaveGame( idFile *savefile ) = 0;
254 
255  virtual void SetSlowmo( bool active ) = 0;
256  virtual void SetSlowmoSpeed( float speed ) = 0;
257  virtual void SetEnviroSuit( bool active ) = 0;
258 };
259 
260 
261 /*
262 ===============================================================================
263 
264  SOUND SYSTEM
265 
266 ===============================================================================
267 */
268 
269 typedef struct {
275  int numBytes;
276  bool looping;
277  float lastVolume;
281 
282 
284 public:
285  virtual ~idSoundSystem( void ) {}
286 
287  // all non-hardware initialization
288  virtual void Init( void ) = 0;
289 
290  // shutdown routine
291  virtual void Shutdown( void ) = 0;
292 
293  // call ClearBuffer if there is a chance that the AsyncUpdate won't get called
294  // for 20+ msec, which would cause a stuttering repeat of the current
295  // buffer contents
296  virtual void ClearBuffer( void ) = 0;
297 
298  // sound is attached to the window, and must be recreated when the window is changed
299  virtual bool InitHW( void ) = 0;
300  virtual bool ShutdownHW( void ) = 0;
301 
302  // asyn loop, called at 60Hz
303  virtual int AsyncUpdate( int time ) = 0;
304 
305  // async loop, when the sound driver uses a write strategy
306  virtual int AsyncUpdateWrite( int time ) = 0;
307 
308  // it is a good idea to mute everything when starting a new level,
309  // because sounds may be started before a valid listener origin
310  // is specified
311  virtual void SetMute( bool mute ) = 0;
312 
313  // for the sound level meter window
314  virtual cinData_t ImageForTime( const int milliseconds, const bool waveform ) = 0;
315 
316  // get sound decoder info
317  virtual int GetSoundDecoderInfo( int index, soundDecoderInfo_t &decoderInfo ) = 0;
318 
319  // if rw == NULL, no portal occlusion or rendered debugging is available
320  virtual idSoundWorld * AllocSoundWorld( idRenderWorld *rw ) = 0;
321 
322  // specifying NULL will cause silence to be played
323  virtual void SetPlayingSoundWorld( idSoundWorld *soundWorld ) = 0;
324 
325  // some tools, like the sound dialog, may be used in both the game and the editor
326  // This can return NULL, so check!
327  virtual idSoundWorld * GetPlayingSoundWorld( void ) = 0;
328 
329  // Mark all soundSamples as currently unused,
330  // but don't free anything.
331  virtual void BeginLevelLoad( void ) = 0;
332 
333  // Free all soundSamples marked as unused
334  // We might want to defer the loading of new sounds to this point,
335  // as we do with images, to avoid having a union in memory at one time.
336  virtual void EndLevelLoad( const char *mapString ) = 0;
337 
338  // direct mixing for OSes that support it
339  virtual int AsyncMix( int soundTime, float *mixBuffer ) = 0;
340 
341  // prints memory info
342  virtual void PrintMemInfo( MemInfo_t *mi ) = 0;
343 
344  // is EAX support present - -1: disabled at compile time, 0: no suitable hardware, 1: ok, 2: failed to load OpenAL DLL
345  virtual int IsEAXAvailable( void ) = 0;
346 };
347 
348 extern idSoundSystem *soundSystem;
349 
350 #endif /* !__SOUND__ */
virtual void SetSlowmoSpeed(float speed)=0
virtual cinData_t ImageForTime(const int milliseconds, const bool waveform)=0
virtual void SetEnviroSuit(bool active)=0
virtual bool HasDefaultSound() const
Definition: snd_shader.cpp:467
float maxDistance
Definition: sound.h:62
virtual bool CurrentlyPlaying(void) const =0
virtual size_t Size(void) const
Definition: snd_shader.cpp:72
const float METERS_TO_DOOM
Definition: sound.h:43
virtual void ClearBuffer(void)=0
virtual void StopWritingDemo()=0
virtual const char * DefaultDefinition(void) const
Definition: snd_shader.cpp:117
virtual idSoundWorld * AllocSoundWorld(idRenderWorld *rw)=0
virtual float GetMaxDistance() const
Definition: snd_shader.cpp:449
virtual bool Parse(const char *text, const int textLength)
Definition: snd_shader.cpp:131
virtual const soundShaderParms_t * GetParms() const
Definition: snd_shader.cpp:481
virtual void ProcessDemoCommand(idDemoFile *demo)=0
virtual bool InitHW(void)=0
virtual void PlayShaderDirectly(const char *name, int channel=-1)=0
virtual int AsyncUpdate(int time)=0
#define BIT(num)
Definition: Lib.h:92
virtual int GetSoundDecoderInfo(int index, soundDecoderInfo_t &decoderInfo)=0
Definition: Vector.h:316
virtual void FadeSound(const s_channelType channel, float to, float over)=0
virtual int IsEAXAvailable(void)=0
bool ParseShader(idLexer &src)
Definition: snd_shader.cpp:153
virtual float GetMinDistance() const
Definition: snd_shader.cpp:440
virtual int Index(void) const =0
int s_channelType
Definition: sound.h:147
GLuint src
Definition: glext.h:5390
virtual void Free(bool immediate)=0
int current44kHzTime
Definition: sound.h:279
bool onDemand
Definition: sound.h:118
virtual ~idSoundWorld(void)
Definition: sound.h:199
virtual void Pause(void)=0
idSoundSample * leadins[SOUND_MAX_LIST_WAVS]
Definition: sound.h:125
virtual void WriteToSaveGame(idFile *savefile)=0
Definition: File.h:50
int numLeadins
Definition: sound.h:126
virtual idSoundWorld * GetPlayingSoundWorld(void)=0
int start44kHzTime
Definition: sound.h:278
Definition: Lexer.h:137
soundShaderParms_t parms
Definition: sound.h:116
virtual float CurrentShakeAmplitudeForPosition(const int time, const idVec3 &listenerPosition)=0
int num44kHzSamples
Definition: sound.h:274
GLuint index
Definition: glext.h:3476
virtual bool CheckShakesAndOgg(void) const
Definition: snd_shader.cpp:377
int numSamplesPerSecond
Definition: sound.h:273
virtual void ClearAllSoundEmitters(void)=0
virtual void SetPlayingSoundWorld(idSoundWorld *soundWorld)=0
virtual int GetNumSounds() const
Definition: snd_shader.cpp:490
virtual void BeginLevelLoad(void)=0
virtual void Init(void)=0
virtual void List(void) const
Definition: snd_shader.cpp:403
virtual void Shutdown(void)=0
virtual void FadeSoundClasses(const int soundClass, const float to, const float over)=0
virtual int AsyncUpdateWrite(int time)=0
float leadinVolume
Definition: sound.h:123
const char * path
Definition: sws.c:117
virtual idSoundEmitter * AllocSoundEmitter(void)=0
virtual const idSoundShader * GetAltSound() const
Definition: snd_shader.cpp:431
float lastVolume
Definition: sound.h:277
virtual void UnPause(void)=0
virtual void ModifySound(const s_channelType channel, const soundShaderParms_t *parms)=0
const float DOOM_TO_METERS
Definition: sound.h:42
virtual const char * GetSound(int index) const
Definition: snd_shader.cpp:499
float shakes
Definition: sound.h:64
virtual bool SetDefaultText(void)
Definition: snd_shader.cpp:91
int numEntries
Definition: sound.h:128
virtual bool IsPaused(void)=0
virtual int StartSound(const idSoundShader *shader, const s_channelType channel, float diversity=0, int shaderFlags=0, bool allowSlow=true)=0
virtual ~idSoundSystem(void)
Definition: sound.h:285
virtual ~idSoundShader(void)
Definition: snd_shader.cpp:64
virtual const char * GetDescription() const
Definition: snd_shader.cpp:458
idSoundSystem * soundSystem
Definition: snd_system.cpp:92
virtual void AVIOpen(const char *path, const char *name)=0
idSoundSample * entries[SOUND_MAX_LIST_WAVS]
Definition: sound.h:127
virtual void SetMute(bool mute)=0
virtual void EndLevelLoad(const char *mapString)=0
Definition: Matrix.h:333
int speakerMask
Definition: sound.h:119
virtual void StopSound(const s_channelType channel)=0
virtual ~idSoundEmitter(void)
Definition: sound.h:152
virtual void SetSlowmo(bool active)=0
const GLcharARB * name
Definition: glext.h:3629
virtual void UpdateEmitter(const idVec3 &origin, int listenerId, const soundShaderParms_t *parms)=0
Definition: Str.h:116
virtual idSoundEmitter * EmitterForIndex(int index)=0
virtual void PlaceListener(const idVec3 &origin, const idMat3 &axis, const int listenerId, const int gameTime, const idStr &areaName)=0
virtual void AVIClose(void)=0
virtual bool ShutdownHW(void)=0
const idSoundShader * altSound
Definition: sound.h:120
virtual void PrintMemInfo(MemInfo_t *mi)=0
idSoundShader(void)
Definition: snd_shader.cpp:55
virtual void StartWritingDemo(idDemoFile *demo)=0
virtual void ReadFromSaveGame(idFile *savefile)=0
const int SOUND_MAX_LIST_WAVS
Definition: sound.h:70
const int SOUND_MAX_CLASSES
Definition: sound.h:74
virtual int AsyncMix(int soundTime, float *mixBuffer)=0
int soundShaderFlags
Definition: sound.h:65
void Init(void)
Definition: snd_shader.cpp:40
virtual void FreeData(void)
Definition: snd_shader.cpp:81
bool errorDuringParse
Definition: sound.h:122
float volume
Definition: sound.h:63
idStr desc
Definition: sound.h:121
float minDistance
Definition: sound.h:61
virtual float CurrentAmplitude(void)=0
virtual void StopAllSounds(void)=0