1 // Emacs style mode select -*- C++ -*- 2 //----------------------------------------------------------------------------- 3 // 4 // Copyright (C) 1993-1996 by id Software, Inc. 5 // 6 // This source is available for distribution and/or modification 7 // only under the terms of the DOOM Source Code License as 8 // published by id Software. All rights reserved. 9 // 10 // The source is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License 13 // for more details. 14 // 15 // DESCRIPTION: 16 // The not so system specific sound interface. 17 // 18 //----------------------------------------------------------------------------- 19 20 21 #ifndef __S_SOUND__ 22 #define __S_SOUND__ 23 24 #include "doomtype.h" 25 #include "i_soundinternal.h" 26 #include "dobject.h" 27 28 class AActor; 29 class FScanner; 30 31 // 32 // SoundFX struct. 33 // 34 struct sfxinfo_t 35 { 36 // Next field is for use by the system sound interface. 37 // A non-null data means the sound has been loaded. 38 SoundHandle data; 39 40 FString name; // [RH] Sound name defined in SNDINFO 41 int lumpnum; // lump number of sfx 42 43 unsigned int next, index; // [RH] For hashing 44 float Volume; 45 46 BYTE PitchMask; 47 SWORD NearLimit; // 0 means unlimited 48 float LimitRange; // Range for sound limiting (squared for faster computations) 49 50 WORD bRandomHeader:1; 51 WORD bPlayerReserve:1; 52 WORD bLoadRAW:1; 53 WORD bPlayerCompat:1; 54 WORD b16bit:1; 55 WORD bUsed:1; 56 WORD bSingular:1; 57 WORD bTentative:1; 58 WORD bPlayerSilent:1; // This player sound is intentionally silent. 59 60 WORD RawRate; // Sample rate to use when bLoadRAW is true 61 62 int LoopStart; // -1 means no specific loop defined 63 64 unsigned int link; 65 enum { NO_LINK = 0xffffffff }; 66 67 FRolloffInfo Rolloff; 68 float Attenuation; // Multiplies the attenuation passed to S_Sound. 69 70 void MarkUsed(); // Marks this sound as used. 71 }; 72 73 // Rolloff types 74 enum 75 { 76 ROLLOFF_Doom, // Linear rolloff with a logarithmic volume scale 77 ROLLOFF_Linear, // Linear rolloff with a linear volume scale 78 ROLLOFF_Log, // Logarithmic rolloff (standard hardware type) 79 ROLLOFF_Custom // Lookup volume from SNDCURVE 80 }; 81 82 int S_FindSound (const char *logicalname); 83 84 // the complete set of sound effects 85 extern TArray<sfxinfo_t> S_sfx; 86 87 // An index into the S_sfx[] array. 88 class FSoundID 89 { 90 public: FSoundID()91 FSoundID() 92 { 93 ID = 0; 94 } FSoundID(int id)95 FSoundID(int id) 96 { 97 ID = id; 98 } FSoundID(const char * name)99 FSoundID(const char *name) 100 { 101 ID = S_FindSound(name); 102 } FSoundID(const FString & name)103 FSoundID(const FString &name) 104 { 105 ID = S_FindSound(name); 106 } FSoundID(const FSoundID & other)107 FSoundID(const FSoundID &other) 108 { 109 ID = other.ID; 110 } 111 FSoundID &operator=(const FSoundID &other) 112 { 113 ID = other.ID; 114 return *this; 115 } 116 FSoundID &operator=(const char *name) 117 { 118 ID = S_FindSound(name); 119 return *this; 120 } 121 FSoundID &operator=(const FString &name) 122 { 123 ID = S_FindSound(name); 124 return *this; 125 } 126 operator int() const 127 { 128 return ID; 129 } FString()130 operator FString() const 131 { 132 return ID ? S_sfx[ID].name : ""; 133 } 134 operator const char *() const 135 { 136 return ID ? S_sfx[ID].name.GetChars() : NULL; 137 } MarkUsed()138 void MarkUsed() const 139 { 140 S_sfx[ID].MarkUsed(); 141 } 142 private: 143 int ID; 144 protected: 145 enum EDummy { NoInit }; FSoundID(EDummy)146 FSoundID(EDummy) {} 147 }; 148 149 class FSoundIDNoInit : public FSoundID 150 { 151 public: FSoundIDNoInit()152 FSoundIDNoInit() : FSoundID(NoInit) {} 153 154 FSoundID &operator=(const FSoundID &other) 155 { 156 return FSoundID::operator=(other); 157 } 158 FSoundID &operator=(const char *name) 159 { 160 return FSoundID::operator=(name); 161 } 162 FSoundID &operator=(const FString &name) 163 { 164 return FSoundID::operator=(name); 165 } 166 }; 167 168 FArchive &operator<<(FArchive &arc, FSoundID &sid); 169 170 extern FRolloffInfo S_Rolloff; 171 extern BYTE *S_SoundCurve; 172 extern int S_SoundCurveSize; 173 174 // Information about one playing sound. 175 struct sector_t; 176 struct FPolyObj; 177 struct FSoundChan : public FISoundChannel 178 { 179 FSoundChan *NextChan; // Next channel in this list. 180 FSoundChan **PrevChan; // Previous channel in this list. 181 FSoundID SoundID; // Sound ID of playing sound. 182 FSoundID OrgID; // Sound ID of sound used to start this channel. 183 float Volume; 184 int ChanFlags; 185 SWORD Pitch; // Pitch variation. 186 BYTE EntChannel; // Actor's sound channel. 187 SBYTE Priority; 188 SWORD NearLimit; 189 BYTE SourceType; 190 float LimitRange; 191 union 192 { 193 AActor *Actor; // Used for position and velocity. 194 const sector_t *Sector; // Sector for area sounds. 195 const FPolyObj *Poly; // Polyobject sound source. 196 float Point[3]; // Sound is not attached to any source. 197 }; 198 }; 199 extern FSoundChan *Channels; 200 201 void S_ReturnChannel(FSoundChan *chan); 202 void S_EvictAllChannels(); 203 204 void S_StopChannel(FSoundChan *chan); 205 void S_LinkChannel(FSoundChan *chan, FSoundChan **head); 206 void S_UnlinkChannel(FSoundChan *chan); 207 208 // Initializes sound stuff, including volume 209 // Sets channels, SFX and music volume, 210 // allocates channel buffer, sets S_sfx lookup. 211 // 212 void S_Init (); 213 void S_InitData (); 214 void S_Shutdown (); 215 216 // Per level startup code. 217 // Kills playing sounds at start of level and starts new music. 218 // 219 void S_Start (); 220 221 // Called after a level is loaded. Ensures that most sounds are loaded. 222 void S_PrecacheLevel (); 223 224 // Loads a sound, including any random sounds it might reference. 225 void S_CacheSound (sfxinfo_t *sfx); 226 227 // Start sound for thing at <ent> 228 void S_Sound (int channel, FSoundID sfxid, float volume, float attenuation); 229 void S_Sound (AActor *ent, int channel, FSoundID sfxid, float volume, float attenuation); 230 void S_SoundMinMaxDist (AActor *ent, int channel, FSoundID sfxid, float volume, float mindist, float maxdist); 231 void S_Sound (const FPolyObj *poly, int channel, FSoundID sfxid, float volume, float attenuation); 232 void S_Sound (const sector_t *sec, int channel, FSoundID sfxid, float volume, float attenuation); 233 void S_Sound (fixed_t x, fixed_t y, fixed_t z, int channel, FSoundID sfxid, float volume, float attenuation); 234 235 // sound channels 236 // channel 0 never willingly overrides 237 // other channels (1-7) always override a playing sound on that channel 238 // 239 // CHAN_AUTO searches down from channel 7 until it finds a channel not in use 240 // CHAN_WEAPON is for weapons 241 // CHAN_VOICE is for oof, sight, or other voice sounds 242 // CHAN_ITEM is for small things and item pickup 243 // CHAN_BODY is for generic body sounds 244 // CHAN_PICKUP can optionally be set as a local sound only for "compatibility" 245 246 #define CHAN_AUTO 0 247 #define CHAN_WEAPON 1 248 #define CHAN_VOICE 2 249 #define CHAN_ITEM 3 250 #define CHAN_BODY 4 251 252 // Channel alias for sector sounds. These define how listener height is 253 // used when calculating 3D sound volume. 254 #define CHAN_FLOOR 1 // Sound comes from the floor. 255 #define CHAN_CEILING 2 // Sound comes from the ceiling. 256 #define CHAN_FULLHEIGHT 3 // Sound comes entire height of the sector. 257 #define CHAN_INTERIOR 4 // Sound comes height between floor and ceiling. 258 259 // modifier flags 260 #define CHAN_LISTENERZ 8 261 #define CHAN_MAYBE_LOCAL 16 262 #define CHAN_UI 32 // Do not record sound in savegames. 263 #define CHAN_NOPAUSE 64 // Do not pause this sound in menus. 264 #define CHAN_AREA 128 // Sound plays from all around. Only valid with sector sounds. 265 #define CHAN_LOOP 256 266 267 #define CHAN_PICKUP (CHAN_ITEM|CHAN_MAYBE_LOCAL) 268 269 #define CHAN_IS3D 1 // internal: Sound is 3D. 270 #define CHAN_EVICTED 2 // internal: Sound was evicted. 271 #define CHAN_FORGETTABLE 4 // internal: Forget channel data when sound stops. 272 #define CHAN_JUSTSTARTED 512 // internal: Sound has not been updated yet. 273 #define CHAN_ABSTIME 1024// internal: Start time is absolute and does not depend on current time. 274 #define CHAN_VIRTUAL 2048// internal: Channel is currently virtual 275 276 // sound attenuation values 277 #define ATTN_NONE 0.f // full volume the entire level 278 #define ATTN_NORM 1.f 279 #define ATTN_IDLE 1.001f 280 #define ATTN_STATIC 3.f // diminish very rapidly with distance 281 282 int S_PickReplacement (int refid); 283 void S_CacheRandomSound (sfxinfo_t *sfx); 284 285 // Checks if a copy of this sound is already playing. 286 bool S_CheckSingular (int sound_id); 287 288 // Stops a sound emanating from one of an emitter's channels. 289 void S_StopSound (AActor *ent, int channel); 290 void S_StopSound (const sector_t *sec, int channel); 291 void S_StopSound (const FPolyObj *poly, int channel); 292 293 // Stops an origin-less sound from playing from this channel. 294 void S_StopSound (int channel); 295 296 // Stop sound for all channels 297 void S_StopAllChannels (void); 298 299 // Is the sound playing on one of the emitter's channels? 300 bool S_GetSoundPlayingInfo (const AActor *actor, int sound_id); 301 bool S_GetSoundPlayingInfo (const sector_t *sector, int sound_id); 302 bool S_GetSoundPlayingInfo (const FPolyObj *poly, int sound_id); 303 304 bool S_IsActorPlayingSomething (AActor *actor, int channel, int sound_id); 305 306 // Change a playing sound's volume 307 bool S_ChangeSoundVolume(AActor *actor, int channel, float volume); 308 309 // Moves all sounds from one mobj to another 310 void S_RelinkSound (AActor *from, AActor *to); 311 312 // Stores/retrieves playing channel information in an archive. 313 void S_SerializeSounds(FArchive &arc); 314 315 // Start music using <music_name> 316 bool S_StartMusic (const char *music_name); 317 318 // Start music using <music_name>, and set whether looping 319 bool S_ChangeMusic (const char *music_name, int order=0, bool looping=true, bool force=false); 320 321 // Start playing a cd track as music 322 bool S_ChangeCDMusic (int track, unsigned int id=0, bool looping=true); 323 324 void S_RestartMusic (); 325 326 void S_MIDIDeviceChanged(); 327 328 int S_GetMusic (char **name); 329 330 // Stops the music for sure. 331 void S_StopMusic (bool force); 332 void S_UpdateMusic(); 333 334 // Stop and resume music, during game PAUSE. 335 void S_PauseSound (bool notmusic, bool notsfx); 336 void S_ResumeSound (bool notsfx); 337 void S_SetSoundPaused (int state); 338 339 // 340 // Updates music & sounds 341 // 342 void S_UpdateSounds (AActor *listener); 343 344 void S_RestoreEvictedChannels(); 345 346 // [RH] S_sfx "maintenance" routines 347 void S_ParseSndInfo (bool redefine); 348 void S_ParseReverbDef (); 349 void S_UnloadReverbDef (); 350 351 void S_HashSounds (); 352 int S_FindSoundNoHash (const char *logicalname); 353 bool S_AreSoundsEquivalent (AActor *actor, int id1, int id2); 354 bool S_AreSoundsEquivalent (AActor *actor, const char *name1, const char *name2); 355 int S_LookupPlayerSound (const char *playerclass, int gender, const char *logicalname); 356 int S_LookupPlayerSound (const char *playerclass, int gender, FSoundID refid); 357 int S_FindSkinnedSound (AActor *actor, FSoundID refid); 358 int S_FindSkinnedSoundEx (AActor *actor, const char *logicalname, const char *extendedname); 359 int S_FindSoundByLump (int lump); 360 int S_AddSound (const char *logicalname, const char *lumpname, FScanner *sc=NULL); // Add sound by lumpname 361 int S_AddSoundLump (const char *logicalname, int lump); // Add sound by lump index 362 int S_AddPlayerSound (const char *playerclass, const int gender, int refid, const char *lumpname); 363 int S_AddPlayerSound (const char *playerclass, const int gender, int refid, int lumpnum, bool fromskin=false); 364 int S_AddPlayerSoundExisting (const char *playerclass, const int gender, int refid, int aliasto, bool fromskin=false); 365 void S_MarkPlayerSounds (const char *playerclass); 366 void S_ShrinkPlayerSoundLists (); 367 void S_UnloadSound (sfxinfo_t *sfx); 368 sfxinfo_t *S_LoadSound(sfxinfo_t *sfx); 369 unsigned int S_GetMSLength(FSoundID sound); 370 void S_ParseMusInfo(); 371 bool S_ParseTimeTag(const char *tag, bool *as_samples, unsigned int *time); 372 373 // [RH] Prints sound debug info to the screen. 374 // Modelled after Hexen's noise cheat. 375 void S_NoiseDebug (); 376 377 extern ReverbContainer *Environments; 378 extern ReverbContainer *DefaultEnvironments[26]; 379 380 class FArchive; 381 FArchive &operator<< (FArchive &arc, ReverbContainer *&env); 382 383 void S_SetEnvironment (const ReverbContainer *settings); 384 ReverbContainer *S_FindEnvironment (const char *name); 385 ReverbContainer *S_FindEnvironment (int id); 386 void S_AddEnvironment (ReverbContainer *settings); 387 388 enum EMidiDevice 389 { 390 MDEV_DEFAULT = -1, 391 MDEV_MMAPI = 0, 392 MDEV_OPL = 1, 393 MDEV_SNDSYS = 2, 394 MDEV_TIMIDITY = 3, 395 MDEV_FLUIDSYNTH = 4, 396 MDEV_GUS = 5, 397 MDEV_WILDMIDI = 6, 398 }; 399 400 struct MidiDeviceSetting 401 { 402 int device; 403 FString args; 404 MidiDeviceSettingMidiDeviceSetting405 MidiDeviceSetting() 406 { 407 device = MDEV_DEFAULT; 408 } 409 }; 410 411 typedef TMap<FName, FName> MusicAliasMap; 412 typedef TMap<FName, MidiDeviceSetting> MidiDeviceMap; 413 414 extern MusicAliasMap MusicAliases; 415 extern MidiDeviceMap MidiDevices; 416 417 #endif 418