]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/sound/sound.h
Various Mac OS X tweaks to get this to build. Probably breaking things.
[icculus/iodoom3.git] / neo / sound / sound.h
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
67 } soundShaderParms_t;
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
119         int                                             speakerMask;
120         const idSoundShader *   altSound;
121         idStr                                   desc;                                           // description
122         bool                                    errorDuringParse;
123         float                                   leadinVolume;                           // allows light breaking leadin sounds to be much louder than the broken loop
124
125         idSoundSample * leadins[SOUND_MAX_LIST_WAVS];
126         int                                             numLeadins;
127         idSoundSample * entries[SOUND_MAX_LIST_WAVS];
128         int                                             numEntries;
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
150 class idSoundEmitter {
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
197 class idSoundWorld {
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 {
270         idStr                                   name;
271         idStr                                   format;
272         int                                             numChannels;
273         int                                             numSamplesPerSecond;
274         int                                             num44kHzSamples;
275         int                                             numBytes;
276         bool                                    looping;
277         float                                   lastVolume;
278         int                                             start44kHzTime;
279         int                                             current44kHzTime;
280 } soundDecoderInfo_t;
281
282
283 class idSoundSystem {
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__ */