mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-13 14:10:42 +00:00
dccd35ef29
UpdateSounds will not be called during screen wipes and the entire setup of this function suggests that this is not advisable at all. The OpenAL stream updates were done deep inside this function implicitly. This caused music to stop while a wipe was in progress. So in order to allow uninterrupted music playback during screen wipes the music updates need to be handled separately from sound updates and be called both in the main loop and the wipe loop. I think that the OpenAL music updating should be offloaded to a separate thread but at least it's working now without causing interruptions during wipes.
405 lines
12 KiB
C++
405 lines
12 KiB
C++
// Emacs style mode select -*- C++ -*-
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
|
//
|
|
// This source is available for distribution and/or modification
|
|
// only under the terms of the DOOM Source Code License as
|
|
// published by id Software. All rights reserved.
|
|
//
|
|
// The source is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
|
// for more details.
|
|
//
|
|
// DESCRIPTION:
|
|
// The not so system specific sound interface.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
#ifndef __S_SOUND__
|
|
#define __S_SOUND__
|
|
|
|
#include "doomtype.h"
|
|
#include "i_soundinternal.h"
|
|
#include "dobject.h"
|
|
|
|
class AActor;
|
|
class FScanner;
|
|
|
|
//
|
|
// SoundFX struct.
|
|
//
|
|
struct sfxinfo_t
|
|
{
|
|
// Next field is for use by the system sound interface.
|
|
// A non-null data means the sound has been loaded.
|
|
SoundHandle data;
|
|
|
|
FString name; // [RH] Sound name defined in SNDINFO
|
|
int lumpnum; // lump number of sfx
|
|
|
|
unsigned int next, index; // [RH] For hashing
|
|
float Volume;
|
|
|
|
BYTE PitchMask;
|
|
SWORD NearLimit; // 0 means unlimited
|
|
float LimitRange; // Range for sound limiting (squared for faster computations)
|
|
|
|
WORD bRandomHeader:1;
|
|
WORD bPlayerReserve:1;
|
|
WORD bLoadRAW:1;
|
|
WORD bPlayerCompat:1;
|
|
WORD b16bit:1;
|
|
WORD bUsed:1;
|
|
WORD bSingular:1;
|
|
WORD bTentative:1;
|
|
WORD bPlayerSilent:1; // This player sound is intentionally silent.
|
|
|
|
WORD RawRate; // Sample rate to use when bLoadRAW is true
|
|
|
|
int LoopStart; // -1 means no specific loop defined
|
|
|
|
unsigned int link;
|
|
enum { NO_LINK = 0xffffffff };
|
|
|
|
FRolloffInfo Rolloff;
|
|
float Attenuation; // Multiplies the attenuation passed to S_Sound.
|
|
|
|
void MarkUsed(); // Marks this sound as used.
|
|
};
|
|
|
|
// Rolloff types
|
|
enum
|
|
{
|
|
ROLLOFF_Doom, // Linear rolloff with a logarithmic volume scale
|
|
ROLLOFF_Linear, // Linear rolloff with a linear volume scale
|
|
ROLLOFF_Log, // Logarithmic rolloff (standard hardware type)
|
|
ROLLOFF_Custom // Lookup volume from SNDCURVE
|
|
};
|
|
|
|
int S_FindSound (const char *logicalname);
|
|
|
|
// the complete set of sound effects
|
|
extern TArray<sfxinfo_t> S_sfx;
|
|
|
|
// An index into the S_sfx[] array.
|
|
class FSoundID
|
|
{
|
|
public:
|
|
FSoundID()
|
|
{
|
|
ID = 0;
|
|
}
|
|
FSoundID(int id)
|
|
{
|
|
ID = id;
|
|
}
|
|
FSoundID(const char *name)
|
|
{
|
|
ID = S_FindSound(name);
|
|
}
|
|
FSoundID(const FString &name)
|
|
{
|
|
ID = S_FindSound(name);
|
|
}
|
|
FSoundID(const FSoundID &other)
|
|
{
|
|
ID = other.ID;
|
|
}
|
|
FSoundID &operator=(const FSoundID &other)
|
|
{
|
|
ID = other.ID;
|
|
return *this;
|
|
}
|
|
FSoundID &operator=(const char *name)
|
|
{
|
|
ID = S_FindSound(name);
|
|
return *this;
|
|
}
|
|
FSoundID &operator=(const FString &name)
|
|
{
|
|
ID = S_FindSound(name);
|
|
return *this;
|
|
}
|
|
operator int() const
|
|
{
|
|
return ID;
|
|
}
|
|
operator FString() const
|
|
{
|
|
return ID ? S_sfx[ID].name : "";
|
|
}
|
|
operator const char *() const
|
|
{
|
|
return ID ? S_sfx[ID].name.GetChars() : NULL;
|
|
}
|
|
void MarkUsed() const
|
|
{
|
|
S_sfx[ID].MarkUsed();
|
|
}
|
|
private:
|
|
int ID;
|
|
protected:
|
|
enum EDummy { NoInit };
|
|
FSoundID(EDummy) {}
|
|
};
|
|
|
|
class FSoundIDNoInit : public FSoundID
|
|
{
|
|
public:
|
|
FSoundIDNoInit() : FSoundID(NoInit) {}
|
|
|
|
FSoundID &operator=(const FSoundID &other)
|
|
{
|
|
return FSoundID::operator=(other);
|
|
}
|
|
FSoundID &operator=(const char *name)
|
|
{
|
|
return FSoundID::operator=(name);
|
|
}
|
|
FSoundID &operator=(const FString &name)
|
|
{
|
|
return FSoundID::operator=(name);
|
|
}
|
|
};
|
|
|
|
FArchive &operator<<(FArchive &arc, FSoundID &sid);
|
|
|
|
extern FRolloffInfo S_Rolloff;
|
|
extern BYTE *S_SoundCurve;
|
|
extern int S_SoundCurveSize;
|
|
|
|
// Information about one playing sound.
|
|
struct sector_t;
|
|
struct FPolyObj;
|
|
struct FSoundChan : public FISoundChannel
|
|
{
|
|
FSoundChan *NextChan; // Next channel in this list.
|
|
FSoundChan **PrevChan; // Previous channel in this list.
|
|
FSoundID SoundID; // Sound ID of playing sound.
|
|
FSoundID OrgID; // Sound ID of sound used to start this channel.
|
|
float Volume;
|
|
int ChanFlags;
|
|
SWORD Pitch; // Pitch variation.
|
|
BYTE EntChannel; // Actor's sound channel.
|
|
SBYTE Priority;
|
|
SWORD NearLimit;
|
|
BYTE SourceType;
|
|
float LimitRange;
|
|
union
|
|
{
|
|
AActor *Actor; // Used for position and velocity.
|
|
const sector_t *Sector; // Sector for area sounds.
|
|
const FPolyObj *Poly; // Polyobject sound source.
|
|
float Point[3]; // Sound is not attached to any source.
|
|
};
|
|
};
|
|
extern FSoundChan *Channels;
|
|
|
|
void S_ReturnChannel(FSoundChan *chan);
|
|
void S_EvictAllChannels();
|
|
|
|
void S_StopChannel(FSoundChan *chan);
|
|
void S_LinkChannel(FSoundChan *chan, FSoundChan **head);
|
|
void S_UnlinkChannel(FSoundChan *chan);
|
|
|
|
// Initializes sound stuff, including volume
|
|
// Sets channels, SFX and music volume,
|
|
// allocates channel buffer, sets S_sfx lookup.
|
|
//
|
|
void S_Init ();
|
|
void S_InitData ();
|
|
void S_Shutdown ();
|
|
|
|
// Per level startup code.
|
|
// Kills playing sounds at start of level and starts new music.
|
|
//
|
|
void S_Start ();
|
|
|
|
// Called after a level is loaded. Ensures that most sounds are loaded.
|
|
void S_PrecacheLevel ();
|
|
|
|
// Loads a sound, including any random sounds it might reference.
|
|
void S_CacheSound (sfxinfo_t *sfx);
|
|
|
|
// Start sound for thing at <ent>
|
|
void S_Sound (int channel, FSoundID sfxid, float volume, float attenuation);
|
|
void S_Sound (AActor *ent, int channel, FSoundID sfxid, float volume, float attenuation);
|
|
void S_SoundMinMaxDist (AActor *ent, int channel, FSoundID sfxid, float volume, float mindist, float maxdist);
|
|
void S_Sound (const FPolyObj *poly, int channel, FSoundID sfxid, float volume, float attenuation);
|
|
void S_Sound (const sector_t *sec, int channel, FSoundID sfxid, float volume, float attenuation);
|
|
void S_Sound (fixed_t x, fixed_t y, fixed_t z, int channel, FSoundID sfxid, float volume, float attenuation);
|
|
|
|
// sound channels
|
|
// channel 0 never willingly overrides
|
|
// other channels (1-7) always override a playing sound on that channel
|
|
//
|
|
// CHAN_AUTO searches down from channel 7 until it finds a channel not in use
|
|
// CHAN_WEAPON is for weapons
|
|
// CHAN_VOICE is for oof, sight, or other voice sounds
|
|
// CHAN_ITEM is for small things and item pickup
|
|
// CHAN_BODY is for generic body sounds
|
|
// CHAN_PICKUP can optionally be set as a local sound only for "compatibility"
|
|
|
|
#define CHAN_AUTO 0
|
|
#define CHAN_WEAPON 1
|
|
#define CHAN_VOICE 2
|
|
#define CHAN_ITEM 3
|
|
#define CHAN_BODY 4
|
|
|
|
// Channel alias for sector sounds. These define how listener height is
|
|
// used when calculating 3D sound volume.
|
|
#define CHAN_FLOOR 1 // Sound comes from the floor.
|
|
#define CHAN_CEILING 2 // Sound comes from the ceiling.
|
|
#define CHAN_FULLHEIGHT 3 // Sound comes entire height of the sector.
|
|
#define CHAN_INTERIOR 4 // Sound comes height between floor and ceiling.
|
|
|
|
// modifier flags
|
|
#define CHAN_LISTENERZ 8
|
|
#define CHAN_MAYBE_LOCAL 16
|
|
#define CHAN_UI 32 // Do not record sound in savegames.
|
|
#define CHAN_NOPAUSE 64 // Do not pause this sound in menus.
|
|
#define CHAN_AREA 128 // Sound plays from all around. Only valid with sector sounds.
|
|
#define CHAN_LOOP 256
|
|
|
|
#define CHAN_PICKUP (CHAN_ITEM|CHAN_MAYBE_LOCAL)
|
|
|
|
#define CHAN_IS3D 1 // internal: Sound is 3D.
|
|
#define CHAN_EVICTED 2 // internal: Sound was evicted.
|
|
#define CHAN_FORGETTABLE 4 // internal: Forget channel data when sound stops.
|
|
#define CHAN_JUSTSTARTED 512 // internal: Sound has not been updated yet.
|
|
#define CHAN_ABSTIME 1024// internal: Start time is absolute and does not depend on current time.
|
|
#define CHAN_VIRTUAL 2048// internal: Channel is currently virtual
|
|
|
|
// sound attenuation values
|
|
#define ATTN_NONE 0.f // full volume the entire level
|
|
#define ATTN_NORM 1.f
|
|
#define ATTN_IDLE 1.001f
|
|
#define ATTN_STATIC 3.f // diminish very rapidly with distance
|
|
|
|
int S_PickReplacement (int refid);
|
|
void S_CacheRandomSound (sfxinfo_t *sfx);
|
|
|
|
// Checks if a copy of this sound is already playing.
|
|
bool S_CheckSingular (int sound_id);
|
|
|
|
// Stops a sound emanating from one of an emitter's channels.
|
|
void S_StopSound (AActor *ent, int channel);
|
|
void S_StopSound (const sector_t *sec, int channel);
|
|
void S_StopSound (const FPolyObj *poly, int channel);
|
|
|
|
// Stops an origin-less sound from playing from this channel.
|
|
void S_StopSound (int channel);
|
|
|
|
// Stop sound for all channels
|
|
void S_StopAllChannels (void);
|
|
|
|
// Is the sound playing on one of the emitter's channels?
|
|
bool S_GetSoundPlayingInfo (const AActor *actor, int sound_id);
|
|
bool S_GetSoundPlayingInfo (const sector_t *sector, int sound_id);
|
|
bool S_GetSoundPlayingInfo (const FPolyObj *poly, int sound_id);
|
|
|
|
bool S_IsActorPlayingSomething (AActor *actor, int channel, int sound_id);
|
|
|
|
// Change a playing sound's volume
|
|
bool S_ChangeSoundVolume(AActor *actor, int channel, float volume);
|
|
|
|
// Moves all sounds from one mobj to another
|
|
void S_RelinkSound (AActor *from, AActor *to);
|
|
|
|
// Stores/retrieves playing channel information in an archive.
|
|
void S_SerializeSounds(FArchive &arc);
|
|
|
|
// Start music using <music_name>
|
|
bool S_StartMusic (const char *music_name);
|
|
|
|
// Start music using <music_name>, and set whether looping
|
|
bool S_ChangeMusic (const char *music_name, int order=0, bool looping=true, bool force=false);
|
|
|
|
// Start playing a cd track as music
|
|
bool S_ChangeCDMusic (int track, unsigned int id=0, bool looping=true);
|
|
|
|
void S_RestartMusic ();
|
|
|
|
void S_MIDIDeviceChanged();
|
|
|
|
int S_GetMusic (char **name);
|
|
|
|
// Stops the music for sure.
|
|
void S_StopMusic (bool force);
|
|
void S_UpdateMusic();
|
|
|
|
// Stop and resume music, during game PAUSE.
|
|
void S_PauseSound (bool notmusic, bool notsfx);
|
|
void S_ResumeSound (bool notsfx);
|
|
void S_SetSoundPaused (int state);
|
|
|
|
//
|
|
// Updates music & sounds
|
|
//
|
|
void S_UpdateSounds (AActor *listener);
|
|
|
|
void S_RestoreEvictedChannels();
|
|
|
|
// [RH] S_sfx "maintenance" routines
|
|
void S_ParseSndInfo (bool redefine);
|
|
void S_ParseReverbDef ();
|
|
void S_UnloadReverbDef ();
|
|
|
|
void S_HashSounds ();
|
|
int S_FindSoundNoHash (const char *logicalname);
|
|
bool S_AreSoundsEquivalent (AActor *actor, int id1, int id2);
|
|
bool S_AreSoundsEquivalent (AActor *actor, const char *name1, const char *name2);
|
|
int S_LookupPlayerSound (const char *playerclass, int gender, const char *logicalname);
|
|
int S_LookupPlayerSound (const char *playerclass, int gender, FSoundID refid);
|
|
int S_FindSkinnedSound (AActor *actor, FSoundID refid);
|
|
int S_FindSkinnedSoundEx (AActor *actor, const char *logicalname, const char *extendedname);
|
|
int S_FindSoundByLump (int lump);
|
|
int S_AddSound (const char *logicalname, const char *lumpname, FScanner *sc=NULL); // Add sound by lumpname
|
|
int S_AddSoundLump (const char *logicalname, int lump); // Add sound by lump index
|
|
int S_AddPlayerSound (const char *playerclass, const int gender, int refid, const char *lumpname);
|
|
int S_AddPlayerSound (const char *playerclass, const int gender, int refid, int lumpnum, bool fromskin=false);
|
|
int S_AddPlayerSoundExisting (const char *playerclass, const int gender, int refid, int aliasto, bool fromskin=false);
|
|
void S_MarkPlayerSounds (const char *playerclass);
|
|
void S_ShrinkPlayerSoundLists ();
|
|
void S_UnloadSound (sfxinfo_t *sfx);
|
|
sfxinfo_t *S_LoadSound(sfxinfo_t *sfx);
|
|
unsigned int S_GetMSLength(FSoundID sound);
|
|
void S_ParseMusInfo();
|
|
bool S_ParseTimeTag(const char *tag, bool *as_samples, unsigned int *time);
|
|
|
|
// [RH] Prints sound debug info to the screen.
|
|
// Modelled after Hexen's noise cheat.
|
|
void S_NoiseDebug ();
|
|
|
|
extern ReverbContainer *Environments;
|
|
extern ReverbContainer *DefaultEnvironments[26];
|
|
|
|
class FArchive;
|
|
FArchive &operator<< (FArchive &arc, ReverbContainer *&env);
|
|
|
|
void S_SetEnvironment (const ReverbContainer *settings);
|
|
ReverbContainer *S_FindEnvironment (const char *name);
|
|
ReverbContainer *S_FindEnvironment (int id);
|
|
void S_AddEnvironment (ReverbContainer *settings);
|
|
|
|
enum EMidiDevice
|
|
{
|
|
MDEV_DEFAULT = -1,
|
|
MDEV_MMAPI = 0,
|
|
MDEV_OPL = 1,
|
|
MDEV_SNDSYS = 2,
|
|
MDEV_TIMIDITY = 3,
|
|
MDEV_FLUIDSYNTH = 4,
|
|
MDEV_GUS = 5,
|
|
};
|
|
|
|
typedef TMap<FName, FName> MusicAliasMap;
|
|
typedef TMap<FName, int> MidiDeviceMap;
|
|
|
|
extern MusicAliasMap MusicAliases;
|
|
extern MidiDeviceMap MidiDevices;
|
|
|
|
#endif
|