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 #include "idlib/math/Vector.h"
33 #include "framework/DeclManager.h"
34 #include "framework/DemoFile.h"
35 #include "renderer/Cinematic.h"
36 
37 /*
38 ===============================================================================
39 
40 	SOUND SHADER DECL
41 
42 ===============================================================================
43 */
44 
45 // unfortunately, our minDistance / maxDistance is specified in meters, and
46 // we have far too many of them to change at this time.
47 const float DOOM_TO_METERS = 0.0254f;					// doom to meters
48 const float METERS_TO_DOOM = (1.0f/DOOM_TO_METERS);	// meters to doom
49 
50 class idSoundSample;
51 
52 // sound shader flags
53 static const int	SSF_PRIVATE_SOUND =		BIT(0);	// only plays for the current listenerId
54 static const int	SSF_ANTI_PRIVATE_SOUND =BIT(1);	// plays for everyone but the current listenerId
55 static const int	SSF_NO_OCCLUSION =		BIT(2);	// don't flow through portals, only use straight line
56 static const int	SSF_GLOBAL =			BIT(3);	// play full volume to all speakers and all listeners
57 static const int	SSF_OMNIDIRECTIONAL =	BIT(4);	// fall off with distance, but play same volume in all speakers
58 static const int	SSF_LOOPING =			BIT(5);	// repeat the sound continuously
59 static const int	SSF_PLAY_ONCE =			BIT(6);	// never restart if already playing on any channel of a given emitter
60 static const int	SSF_UNCLAMPED =			BIT(7);	// don't clamp calculated volumes at 1.0
61 static const int	SSF_NO_FLICKER =		BIT(8);	// always return 1.0 for volume queries
62 static const int	SSF_NO_DUPS =			BIT(9);	// try not to play the same sound twice in a row
63 
64 // these options can be overriden from sound shader defaults on a per-emitter and per-channel basis
65 typedef struct {
66 	float					minDistance;
67 	float					maxDistance;
68 	float					volume;					// in dB, unfortunately.  Negative values get quieter
69 	float					shakes;
70 	int						soundShaderFlags;		// SSF_* bit flags
71 	int						soundClass;				// for global fading of sounds
72 } soundShaderParms_t;
73 
74 
75 const int		SOUND_MAX_LIST_WAVS		= 32;
76 
77 // sound classes are used to fade most sounds down inside cinematics, leaving dialog
78 // flagged with a non-zero class full volume
79 const int		SOUND_MAX_CLASSES		= 4;
80 
81 // it is somewhat tempting to make this a virtual class to hide the private
82 // details here, but that doesn't fit easily with the decl manager at the moment.
83 class idSoundShader : public idDecl {
84 public:
85 							idSoundShader( void );
86 	virtual					~idSoundShader( void );
87 
88 	virtual size_t			Size( void ) const;
89 	virtual bool			SetDefaultText( void );
90 	virtual const char *	DefaultDefinition( void ) const;
91 	virtual bool			Parse( const char *text, const int textLength );
92 	virtual void			FreeData( void );
93 	virtual void			List( void ) const;
94 
95 	virtual const char *	GetDescription() const;
96 
97 	// so the editor can draw correct default sound spheres
98 	// this is currently defined as meters, which sucks, IMHO.
99 	virtual float			GetMinDistance() const;		// FIXME: replace this with a GetSoundShaderParms()
100 	virtual float			GetMaxDistance() const;
101 
102 	// returns NULL if an AltSound isn't defined in the shader.
103 	// we use this for pairing a specific broken light sound with a normal light sound
104 	virtual const idSoundShader *GetAltSound() const;
105 
106 	virtual bool			HasDefaultSound() const;
107 
108 	virtual const soundShaderParms_t *GetParms() const;
109 	virtual int				GetNumSounds() const;
110 	virtual const char *	GetSound( int index ) const;
111 
112 	virtual bool			CheckShakesAndOgg( void ) const;
113 
114 private:
115 	friend class idSoundWorldLocal;
116 	friend class idSoundEmitterLocal;
117 	friend class idSoundChannel;
118 	friend class idSoundCache;
119 
120 	// options from sound shader text
121 	soundShaderParms_t		parms;						// can be overriden on a per-channel basis
122 
123 	bool					onDemand;					// only load when played, and free when finished
124 	int						speakerMask;
125 	const idSoundShader *	altSound;
126 	idStr					desc;						// description
127 	bool					errorDuringParse;
128 	float					leadinVolume;				// allows light breaking leadin sounds to be much louder than the broken loop
129 
130 	idSoundSample *	leadins[SOUND_MAX_LIST_WAVS];
131 	int						numLeadins;
132 	idSoundSample *	entries[SOUND_MAX_LIST_WAVS];
133 	int						numEntries;
134 
135 private:
136 	void					Init( void );
137 	bool					ParseShader( idLexer &src );
138 };
139 
140 /*
141 ===============================================================================
142 
143 	SOUND EMITTER
144 
145 ===============================================================================
146 */
147 
148 // sound channels
149 static const int SCHANNEL_ANY = 0;	// used in queries and commands to effect every channel at once, in
150 									// startSound to have it not override any other channel
151 static const int SCHANNEL_ONE = 1;	// any following integer can be used as a channel number
152 typedef int s_channelType;	// the game uses its own series of enums, and we don't want to require casts
153 
154 
155 class idSoundEmitter {
156 public:
~idSoundEmitter(void)157 	virtual					~idSoundEmitter( void ) {}
158 
159 	// a non-immediate free will let all currently playing sounds complete
160 	// soundEmitters are not actually deleted, they are just marked as
161 	// reusable by the soundWorld
162 	virtual void			Free( bool immediate ) = 0;
163 
164 	// the parms specified will be the default overrides for all sounds started on this emitter.
165 	// NULL is acceptable for parms
166 	virtual void			UpdateEmitter( const idVec3 &origin, int listenerId, const soundShaderParms_t *parms ) = 0;
167 
168 	// returns the length of the started sound in msec
169 	virtual int				StartSound( const idSoundShader *shader, const s_channelType channel, float diversity = 0, int shaderFlags = 0, bool allowSlow = true ) = 0;
170 
171 	// pass SCHANNEL_ANY to effect all channels
172 	virtual void			ModifySound( const s_channelType channel, const soundShaderParms_t *parms ) = 0;
173 	virtual void			StopSound( const s_channelType channel ) = 0;
174 	// to is in Db (sigh), over is in seconds
175 	virtual void			FadeSound( const s_channelType channel, float to, float over ) = 0;
176 
177 	// returns true if there are any sounds playing from this emitter.  There is some conservative
178 	// slop at the end to remove inconsistent race conditions with the sound thread updates.
179 	// FIXME: network game: on a dedicated server, this will always be false
180 	virtual bool			CurrentlyPlaying( void ) const = 0;
181 
182 	// returns a 0.0 to 1.0 value based on the current sound amplitude, allowing
183 	// graphic effects to be modified in time with the audio.
184 	// just samples the raw wav file, it doesn't account for volume overrides in the
185 	virtual	float			CurrentAmplitude( void ) = 0;
186 
187 	// for save games.  Index will always be > 0
188 	virtual	int				Index( void ) const = 0;
189 };
190 
191 /*
192 ===============================================================================
193 
194 	SOUND WORLD
195 
196 There can be multiple independent sound worlds, just as there can be multiple
197 independent render worlds.  The prime example is the editor sound preview
198 option existing simultaniously with a live game.
199 ===============================================================================
200 */
201 
202 class idSoundWorld {
203 public:
~idSoundWorld(void)204 	virtual					~idSoundWorld( void ) {}
205 
206 	// call at each map start
207 	virtual void			ClearAllSoundEmitters( void ) = 0;
208 	virtual void			StopAllSounds( void ) = 0;
209 
210 	// get a new emitter that can play sounds in this world
211 	virtual idSoundEmitter *AllocSoundEmitter( void ) = 0;
212 
213 	// for load games, index 0 will return NULL
214 	virtual idSoundEmitter *EmitterForIndex( int index ) = 0;
215 
216 	// query sound samples from all emitters reaching a given position
217 	virtual	float			CurrentShakeAmplitudeForPosition( const int time, const idVec3 &listenerPosition ) = 0;
218 
219 	// where is the camera/microphone
220 	// listenerId allows listener-private and antiPrivate sounds to be filtered
221 	// gameTime is in msec, and is used to time sound queries and removals so that they are independent
222 	// of any race conditions with the async update
223 	virtual	void			PlaceListener( const idVec3 &origin, const idMat3 &axis, const int listenerId, const int gameTime, const idStr& areaName ) = 0;
224 
225 	// fade all sounds in the world with a given shader soundClass
226 	// to is in Db (sigh), over is in seconds
227 	virtual void			FadeSoundClasses( const int soundClass, const float to, const float over ) = 0;
228 
229 	// background music
230 	virtual	void			PlayShaderDirectly( const char *name, int channel = -1 ) = 0;
231 
232 	// dumps the current state and begins archiving commands
233 	virtual void			StartWritingDemo( idDemoFile *demo ) = 0;
234 	virtual void			StopWritingDemo() = 0;
235 
236 	// read a sound command from a demo file
237 	virtual void			ProcessDemoCommand( idDemoFile *demo ) = 0;
238 
239 	// pause and unpause the sound world
240 	virtual void			Pause( void ) = 0;
241 	virtual void			UnPause( void ) = 0;
242 	virtual bool			IsPaused( void ) = 0;
243 
244 	// Write the sound output to multiple wav files.  Note that this does not use the
245 	// work done by AsyncUpdate, it mixes explicitly in the foreground every PlaceOrigin(),
246 	// under the assumption that we are rendering out screenshots and the gameTime is going
247 	// much slower than real time.
248 	// path should not include an extension, and the generated filenames will be:
249 	// <path>_left.raw, <path>_right.raw, or <path>_51left.raw, <path>_51right.raw,
250 	// <path>_51center.raw, <path>_51lfe.raw, <path>_51backleft.raw, <path>_51backright.raw,
251 	// If only two channel mixing is enabled, the left and right .raw files will also be
252 	// combined into a stereo .wav file.
253 	virtual void			AVIOpen( const char *path, const char *name ) = 0;
254 	virtual void			AVIClose( void ) = 0;
255 
256 	// SaveGame / demo Support
257 	virtual void			WriteToSaveGame( idFile *savefile ) = 0;
258 	virtual void			ReadFromSaveGame( idFile *savefile ) = 0;
259 
260 	virtual void			SetSlowmo( bool active ) = 0;
261 	virtual void			SetSlowmoSpeed( float speed ) = 0;
262 	virtual void			SetEnviroSuit( bool active ) = 0;
263 };
264 
265 
266 /*
267 ===============================================================================
268 
269 	SOUND SYSTEM
270 
271 ===============================================================================
272 */
273 
274 typedef struct {
275 	idStr					name;
276 	idStr					format;
277 	int						numChannels;
278 	int						numSamplesPerSecond;
279 	int						num44kHzSamples;
280 	int						numBytes;
281 	bool					looping;
282 	float					lastVolume;
283 	int						start44kHzTime;
284 	int						current44kHzTime;
285 } soundDecoderInfo_t;
286 
287 
288 class idSoundSystem {
289 public:
~idSoundSystem(void)290 	virtual					~idSoundSystem( void ) {}
291 
292 	// all non-hardware initialization
293 	virtual void			Init( void ) = 0;
294 
295 	// shutdown routine
296 	virtual	void			Shutdown( 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 EFX support present - -1: disabled at compile time, 0: no suitable hardware, 1: ok
345 	virtual int				IsEFXAvailable( void ) = 0;
346 };
347 
348 extern idSoundSystem	*soundSystem;
349 
350 #endif /* !__SOUND__ */
351