gzdoom-gles/src/s_sound.h
Randy Heit 99a2014ead - Added support for custom loop points for songs. This does not work with MP3 because of the
way MP3 obfuscates custom tags. Vorbis and FLAC are fine. (I could make it work with MP3,
  but you should be using Vorbis instead.) They are:
  * LOOP_START: Start time for the loop. If omitted, the song repeats from the beginning.
  * LOOP_END: End time for the loop. If omitted, the song loops at the end. (If you need to specify this, why aren't you using a shorter song.)
  You only need to specify one of these tags to set the custom loop. Naturally, you can set
  them both, as well. The format for each tag is the same:
  * If it contains a colon (:), it specifies by time. This may be of the form 00:00:00.00
    (HH:MM:SS.ss) to specify by play. Various parts may be left off. e.g. To start the loop
    at 20 seconds in, you can use ":20", 0:20", "00:00:20", ":20.0", etc. Values after the
    decimal are fractions of a second and accurate to one millisecond.
  * If you don't include a colon but just have a raw number, then it's the number of PCM
    samples at which to loop.
  * Any characters other than digits (0-9), colons (:), or a single decimal point for the
    seconds portion will result in the tag being ignored.

SVN r2424 (trunk)
2010-07-10 02:59:34 +00:00

387 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
// unsigned int frequency; // [RH] Preferred playback rate
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 bForce11025:1;
WORD bForce22050:1;
WORD bLoadRAW:1;
WORD bPlayerCompat:1;
WORD b16bit:1;
WORD bUsed:1;
WORD bSingular:1;
WORD bTentative:1;
int LoopStart; // -1 means no specific loop defined
unsigned int link;
enum { NO_LINK = 0xffffffff };
FRolloffInfo Rolloff;
};
// 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;
}
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);
// 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 ();
int S_GetMusic (char **name);
// Stops the music for sure.
void S_StopMusic (bool force);
// 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 ();
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_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_FMOD = 2,
MDEV_TIMIDITY = 3,
};
typedef TMap<FName, int> MidiDeviceMap;
extern MidiDeviceMap MidiDevices;
#endif