From 8bd5f12b42c69ccab08e36788c694214956b5e38 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 12 Apr 2020 08:09:38 +0200 Subject: [PATCH] - matching sound backend code with GZDoom. # Conflicts: # source/core/sound/s_soundinternal.h --- source/CMakeLists.txt | 1 + source/blood/src/aiunicult.cpp | 2 +- source/blood/src/asound.cpp | 2 +- source/blood/src/blood.cpp | 2 +- source/blood/src/credits.cpp | 2 +- source/blood/src/endgame.cpp | 2 +- source/blood/src/seq.cpp | 2 +- source/blood/src/sfx.cpp | 15 +- source/blood/src/sound.cpp | 2 +- source/core/console/c_console.cpp | 1 + source/core/gamecontrol.cpp | 2 +- source/core/gamecontrol.h | 12 +- source/core/menu/menu.cpp | 2 +- source/core/raze_sound.cpp | 250 +++++++++++++++++ source/core/raze_sound.h | 37 +++ source/core/rts.cpp | 2 +- source/core/savegamehelp.cpp | 2 +- source/core/serializer.cpp | 2 +- source/core/sound/backend/i_sound.cpp | 38 +-- source/core/sound/backend/i_sound.h | 16 +- source/core/sound/backend/i_soundinternal.h | 3 +- source/core/sound/backend/oalsound.cpp | 32 ++- source/core/sound/backend/oalsound.h | 6 +- source/core/sound/s_sound.cpp | 285 ++++---------------- source/core/sound/s_soundinternal.h | 56 +--- source/duke3d/src/demo.cpp | 20 +- source/duke3d/src/sounds.cpp | 13 +- source/duke3d/src/sounds.h | 2 +- source/exhumed/src/d_menu.cpp | 2 +- source/exhumed/src/exhumed.cpp | 2 +- source/exhumed/src/menu.cpp | 2 +- source/exhumed/src/sound.cpp | 13 +- source/exhumed/src/sound.h | 2 +- source/rr/src/demo.cpp | 20 +- source/rr/src/sounds.cpp | 13 +- source/rr/src/sounds.h | 2 +- source/sw/src/d_menu.cpp | 2 +- source/sw/src/game.cpp | 2 +- source/sw/src/game.h | 2 +- source/sw/src/panel.cpp | 2 +- source/sw/src/sounds.cpp | 12 +- 41 files changed, 522 insertions(+), 365 deletions(-) create mode 100644 source/core/raze_sound.cpp create mode 100644 source/core/raze_sound.h diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 7a1e5fcbf..1c1d9ada2 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -701,6 +701,7 @@ set (PCH_SOURCES core/screenshot.cpp core/serializer.cpp core/raze_music.cpp + core/raze_sound.cpp core/2d/v_2ddrawer.cpp core/2d/v_draw.cpp diff --git a/source/blood/src/aiunicult.cpp b/source/blood/src/aiunicult.cpp index 5d0804478..b55b3102b 100644 --- a/source/blood/src/aiunicult.cpp +++ b/source/blood/src/aiunicult.cpp @@ -51,7 +51,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "endgame.h" #include "view.h" #include "tile.h" -#include "sound/s_soundinternal.h" +#include "raze_sound.h" #include "gib.h" #include "aiburn.h" diff --git a/source/blood/src/asound.cpp b/source/blood/src/asound.cpp index 12334c2e0..472328c9b 100644 --- a/source/blood/src/asound.cpp +++ b/source/blood/src/asound.cpp @@ -33,7 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "resource.h" #include "sound.h" #include "loadsave.h" -#include "sound/s_soundinternal.h" +#include "raze_sound.h" BEGIN_BLD_NS diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index e67a0bb93..180c04048 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -71,7 +71,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "m_argv.h" #include "statistics.h" #include "menu/menu.h" -#include "sound/s_soundinternal.h" +#include "raze_sound.h" #include "nnexts.h" #include"secrets.h" diff --git a/source/blood/src/credits.cpp b/source/blood/src/credits.cpp index 9ff031ada..4ab0d012a 100644 --- a/source/blood/src/credits.cpp +++ b/source/blood/src/credits.cpp @@ -37,7 +37,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "view.h" #include "animtexture.h" #include "../glbackend/glbackend.h" -#include "sound/s_soundinternal.h" +#include "raze_sound.h" BEGIN_BLD_NS diff --git a/source/blood/src/endgame.cpp b/source/blood/src/endgame.cpp index d75a05f05..bfac65063 100644 --- a/source/blood/src/endgame.cpp +++ b/source/blood/src/endgame.cpp @@ -41,7 +41,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "statistics.h" #include "gamemenu.h" #include "gstrings.h" -#include "sound/s_soundinternal.h" +#include "raze_sound.h" BEGIN_BLD_NS diff --git a/source/blood/src/seq.cpp b/source/blood/src/seq.cpp index 11b069827..c852a039f 100644 --- a/source/blood/src/seq.cpp +++ b/source/blood/src/seq.cpp @@ -39,7 +39,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "actor.h" #include "tile.h" #include "view.h" -#include "sound/s_soundinternal.h" +#include "raze_sound.h" BEGIN_BLD_NS diff --git a/source/blood/src/sfx.cpp b/source/blood/src/sfx.cpp index c82ea6189..eda0be731 100644 --- a/source/blood/src/sfx.cpp +++ b/source/blood/src/sfx.cpp @@ -34,7 +34,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "sfx.h" #include "sound.h" #include "trig.h" -#include "sound/s_soundinternal.h" +#include "raze_sound.h" BEGIN_BLD_NS @@ -51,6 +51,19 @@ public: S_Rolloff.MinDistance = 170; // these are the numbers I got when uncrunching the original sound code. S_Rolloff.MaxDistance = 850; } + + void StopChannel(FSoundChan* chan) override + { + if (chan && chan->SysChannel != NULL && !(chan->ChanFlags & CHANF_EVICTED) && chan->SourceType == SOURCE_Actor) + { + chan->Source = NULL; + chan->SourceType = SOURCE_Unattached; + } + SoundEngine::StopChannel(chan); + } + + + }; void sfxInit(void) diff --git a/source/blood/src/sound.cpp b/source/blood/src/sound.cpp index 9b491d525..c327475c0 100644 --- a/source/blood/src/sound.cpp +++ b/source/blood/src/sound.cpp @@ -32,7 +32,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "baselayer.h" #include "raze_music.h" #include "sfx.h" -#include "sound/s_soundinternal.h" +#include "raze_sound.h" BEGIN_BLD_NS diff --git a/source/core/console/c_console.cpp b/source/core/console/c_console.cpp index 20afb3297..17141589e 100644 --- a/source/core/console/c_console.cpp +++ b/source/core/console/c_console.cpp @@ -59,6 +59,7 @@ #include "i_system.h" #include "s_soundinternal.h" #include "engineerrors.h" +#include "gamecontrol.h" #define LEFTMARGIN 8 #define RIGHTMARGIN 8 diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 0fba34a41..ed18eca52 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -45,7 +45,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "gstrings.h" #include "quotemgr.h" #include "mapinfo.h" -#include "s_soundinternal.h" +#include "raze_sound.h" #include "i_system.h" #include "inputstate.h" #include "v_video.h" diff --git a/source/core/gamecontrol.h b/source/core/gamecontrol.h index 85ab1a24e..71af02387 100644 --- a/source/core/gamecontrol.h +++ b/source/core/gamecontrol.h @@ -78,6 +78,7 @@ struct UserConfig extern UserConfig userConfig; extern int nomusic; +extern bool nosound; inline bool MusicEnabled() { return !nomusic; @@ -85,7 +86,7 @@ inline bool MusicEnabled() inline bool SoundEnabled() { - return snd_enabled && !userConfig.nosound; + return snd_enabled && !nosound; } @@ -173,4 +174,11 @@ struct FStartupInfo //int LoadBrightmaps = -1; }; -extern FStartupInfo RazeStartupInfo; \ No newline at end of file +extern FStartupInfo RazeStartupInfo; + +enum +{ + PAUSESFX_MENU = 1, + PAUSESFX_CONSOLE = 2 +}; + diff --git a/source/core/menu/menu.cpp b/source/core/menu/menu.cpp index d4563291e..011c1fcd5 100644 --- a/source/core/menu/menu.cpp +++ b/source/core/menu/menu.cpp @@ -53,7 +53,7 @@ #include "baselayer.h" #include "statistics.h" #include "input/m_joy.h" -#include "sound/s_soundinternal.h" +#include "raze_sound.h" void RegisterDukeMenus(); void RegisterRedneckMenus(); diff --git a/source/core/raze_sound.cpp b/source/core/raze_sound.cpp new file mode 100644 index 000000000..589919fc5 --- /dev/null +++ b/source/core/raze_sound.cpp @@ -0,0 +1,250 @@ +/* +** s_sound.cpp +** Main sound engine +** +**--------------------------------------------------------------------------- +** Copyright 1998-2016 Randy Heit +** Copyright 2002-2019 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include "raze_sound.h" +#include "c_cvars.h" +#include "basics.h" +#include "stats.h" +#include "v_text.h" +#include "filesystem.h" +#include "serializer.h" +#include "name.h" +#include "cmdlib.h" +#include "gamecontrol.h" +#include "build.h" + +extern ReverbContainer* ForcedEnvironment; +static int LastReverb; + +CUSTOM_CVAR(Bool, snd_reverb, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +{ + FX_SetReverb(-1); +} + +// This is for testing reverb settings. +CUSTOM_CVAR(Int, snd_reverbtype, -1, 0) +{ + FX_SetReverb(-1); +} + +void FX_SetReverb(int strength) +{ + if (strength == -1) strength = LastReverb; + if (snd_reverbtype > -1) + { + strength = snd_reverbtype; + ForcedEnvironment = S_FindEnvironment(strength); + } + else if (snd_reverb && strength > 0) + { + // todo: optimize environments. The original "reverb" was garbage and not usable as reference. + if (strength < 64) strength = 0x1400; + else if (strength < 192) strength = 0x1503; + else strength = 0x1900; + LastReverb = strength; + ForcedEnvironment = S_FindEnvironment(strength); + } + else ForcedEnvironment = nullptr; +} + + +//========================================================================== +// +// S_NoiseDebug +// +// [RH] Print sound debug info. Called by status bar. +//========================================================================== + +FString NoiseDebug(SoundEngine *engine) +{ + FVector3 listener; + FVector3 origin; + + listener = engine->GetListener().position; + int ch = 0; + + FString out; + + out.Format("*** SOUND DEBUG INFO ***\nListener: %3.2f %2.3f %2.3f\n" + "x y z vol dist chan pri flags aud pos name\n", listener.X, listener.Y, listener.Z); + + for (auto chan = engine->GetChannels(); chan; chan = chan->NextChan) + { + if (!(chan->ChanFlags & CHANF_IS3D)) + { + out += "--- --- --- --- "; + } + else + { + engine->CalcPosVel(chan, &origin, nullptr); + out.AppendFormat(TEXTCOLOR_GOLD "%5.0f | %5.0f | %5.0f | %5.0f ", origin.X, origin.Z, origin.Y, (origin - listener).Length()); + } + out.AppendFormat("%-.2g %-4d %-4d %sF%s3%sZ%sU%sM%sN%sA%sL%sE%sV" TEXTCOLOR_GOLD " %-5.4f %-4u %d: %s %p\n", chan->Volume, chan->EntChannel, chan->Priority, + (chan->ChanFlags & CHANF_FORGETTABLE) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, + (chan->ChanFlags & CHANF_IS3D) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, + (chan->ChanFlags & CHANF_LISTENERZ) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, + (chan->ChanFlags & CHANF_UI) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, + (chan->ChanFlags & CHANF_MAYBE_LOCAL) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, + (chan->ChanFlags & CHANF_NOPAUSE) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, + (chan->ChanFlags & CHANF_AREA) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, + (chan->ChanFlags & CHANF_LOOP) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, + (chan->ChanFlags & CHANF_EVICTED) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, + (chan->ChanFlags & CHANF_VIRTUAL) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, + GSnd->GetAudibility(chan), GSnd->GetPosition(chan), ((int)chan->OrgID)-1, engine->GetSounds()[chan->SoundID].name.GetChars(), chan->Source); + ch++; + } + out.AppendFormat("%d channels\n", ch); + return out; +} + +ADD_STAT(sounddebug) +{ + return NoiseDebug(soundEngine); +} + +CVAR(Bool, snd_extendedlookup, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) + +int S_LookupSound(const char* fn) +{ + static const char * const sndformats[] = { "OGG", "FLAC", "WAV" }; + if (snd_extendedlookup) + { + int lump = fileSystem.FindFileWithExtensions(StripExtension(fn), sndformats, countof(sndformats)); + if (lump >= 0) return lump; + } + return fileSystem.FindFile(fn); +} + +//========================================================================== +// +// Although saving the sound system's state is supposed to be an engine +// feature, the specifics cannot be set up there, this needs to be on the client side. +// +//========================================================================== + +static FSerializer& Serialize(FSerializer& arc, const char* key, FSoundChan& chan, FSoundChan* def) +{ + if (arc.BeginObject(key)) + { + arc("sourcetype", chan.SourceType) + ("soundid", chan.SoundID) + ("orgid", chan.OrgID) + ("volume", chan.Volume) + ("distancescale", chan.DistanceScale) + ("pitch", chan.Pitch) + ("chanflags", chan.ChanFlags) + ("entchannel", chan.EntChannel) + ("priority", chan.Priority) + ("nearlimit", chan.NearLimit) + ("starttime", chan.StartTime) + ("rolloftype", chan.Rolloff.RolloffType) + ("rolloffmin", chan.Rolloff.MinDistance) + ("rolloffmax", chan.Rolloff.MaxDistance) + ("limitrange", chan.LimitRange) + .Array("point", chan.Point, 3); + + int SourceIndex = 0; + if (arc.isWriting()) + { + if (chan.SourceType == SOURCE_Actor) SourceIndex = int((spritetype*)(chan.Source) - sprite); + else SourceIndex = soundEngine->SoundSourceIndex(&chan); + } + arc("Source", SourceIndex); + if (arc.isReading()) + { + if (chan.SourceType == SOURCE_Actor) chan.Source = &sprite[SourceIndex]; + else soundEngine->SetSource(&chan, SourceIndex); + } + arc.EndObject(); + } + return arc; +} + +//========================================================================== +// +// S_SerializeSounds +// +//========================================================================== + +void S_SerializeSounds(FSerializer& arc) +{ + FSoundChan* chan; + + GSnd->Sync(true); + + if (arc.isWriting()) + { + // Count channels and accumulate them so we can store them in + // reverse order. That way, they will be in the same order when + // reloaded later as they are now. + TArray chans = soundEngine->AllActiveChannels(); + + if (chans.Size() > 0 && arc.BeginArray("sounds")) + { + for (unsigned int i = chans.Size(); i-- != 0; ) + { + // Replace start time with sample position. + uint64_t start = chans[i]->StartTime; + chans[i]->StartTime = GSnd ? GSnd->GetPosition(chans[i]) : 0; + arc(nullptr, *chans[i]); + chans[i]->StartTime = start; + } + arc.EndArray(); + } + } + else + { + unsigned int count; + + soundEngine->StopAllChannels(); + if (arc.BeginArray("sounds")) + { + count = arc.ArraySize(); + for (unsigned int i = 0; i < count; ++i) + { + chan = (FSoundChan*)soundEngine->GetChannel(nullptr); + arc(nullptr, *chan); + // Sounds always start out evicted when restored from a save. + chan->ChanFlags |= CHANF_EVICTED | CHANF_ABSTIME; + } + arc.EndArray(); + } + // totalclock runs on 120 fps, we need to allow a small delay here. + soundEngine->SetRestartTime((int)totalclock + 6); + } + GSnd->Sync(false); + GSnd->UpdateSounds(); +} + diff --git a/source/core/raze_sound.h b/source/core/raze_sound.h new file mode 100644 index 000000000..4ee5ec22c --- /dev/null +++ b/source/core/raze_sound.h @@ -0,0 +1,37 @@ +#pragma once +#include "s_soundinternal.h" + +enum +{ + SOURCE_Actor = SOURCE_None+1, // Sound is coming from an actor. + SOURCE_Ambient, // Sound is coming from a blood ambient definition. + SOURCE_Player, // SW player sound (player in SW maintains its own position separately from the sprite so needs to be special.) + SOURCE_Swirly, // Special stuff for Exhumed. (local sound with custom panning) + SOURCE_EXBoss, // Another special case for Exhumed. +}; + + +inline void FX_StopAllSounds(void) +{ + soundEngine->StopAllChannels(); +} + +void FX_SetReverb(int strength); + +inline void FX_SetReverbDelay(int delay) +{ +} + +inline int S_FindSoundByResID(int ndx) +{ + return soundEngine->FindSoundByResID(ndx); +} + +inline int S_FindSound(const char* name) +{ + return soundEngine->FindSound(name); +} + +int S_LookupSound(const char* fn); +class FSerializer; +void S_SerializeSounds(FSerializer& arc); diff --git a/source/core/rts.cpp b/source/core/rts.cpp index 938ae157b..ac892f2e0 100644 --- a/source/core/rts.cpp +++ b/source/core/rts.cpp @@ -38,7 +38,7 @@ #include "filesystem.h" #include "rts.h" #include "m_swap.h" -#include "s_soundinternal.h" +#include "raze_sound.h" struct WadInfo diff --git a/source/core/savegamehelp.cpp b/source/core/savegamehelp.cpp index 048000002..bb63302bb 100644 --- a/source/core/savegamehelp.cpp +++ b/source/core/savegamehelp.cpp @@ -50,7 +50,7 @@ #include "serializer.h" #include "version.h" #include "raze_music.h" -#include "s_soundinternal.h" +#include "raze_sound.h" static CompositeSavegameWriter savewriter; static FResourceFile *savereader; diff --git a/source/core/serializer.cpp b/source/core/serializer.cpp index 36be5f203..2c0f11811 100644 --- a/source/core/serializer.cpp +++ b/source/core/serializer.cpp @@ -49,7 +49,7 @@ #include "cmdlib.h" #include "utf8.h" #include "printf.h" -#include "s_soundinternal.h" +#include "raze_sound.h" bool save_full = false; diff --git a/source/core/sound/backend/i_sound.cpp b/source/core/sound/backend/i_sound.cpp index c0d6c8c9c..74290c4ab 100644 --- a/source/core/sound/backend/i_sound.cpp +++ b/source/core/sound/backend/i_sound.cpp @@ -36,10 +36,9 @@ #include #include "oalsound.h" -#include "printf.h" + #include "i_module.h" #include "cmdlib.h" -#include #include "c_dispatch.h" #include "i_music.h" @@ -47,12 +46,9 @@ #include "v_text.h" #include "c_cvars.h" #include "stats.h" -#include "s_music.h" -#include "raze_music.h" -#include "gamecvars.h" -#include "gamecontrol.h" #include + EXTERN_CVAR (Float, snd_sfxvolume) EXTERN_CVAR(Float, snd_musicvolume) CVAR (Int, snd_samplerate, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) @@ -71,6 +67,8 @@ CVAR(String, snd_backend, DEF_BACKEND, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR (Bool, snd_pitched, false, CVAR_ARCHIVE) SoundRenderer *GSnd; +bool nosound; +bool nosfx; void I_CloseSound (); @@ -173,17 +171,17 @@ public: } // Starts a sound. - FISoundChannel *StartSound (SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan) + FISoundChannel *StartSound (SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan, float startTime) { return NULL; } - FISoundChannel *StartSound3D (SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan) + FISoundChannel *StartSound3D (SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime) { return NULL; } // Marks a channel's start time without actually playing it. - void MarkStartTime (FISoundChannel *chan) + void MarkStartTime (FISoundChannel *chan, float startTime) { } @@ -247,21 +245,31 @@ public: void I_InitSound () { FModule_SetProgDir(progdir); + /* Get command line options: */ + nosound = !!Args->CheckParm ("-nosound"); + nosfx = !!Args->CheckParm ("-nosfx"); GSnd = NULL; - if (userConfig.nosound) + if (nosound) { GSnd = new NullSoundRenderer; return; } -#ifndef NO_OPENAL - if (IsOpenALPresent()) + // Keep it simple: let everything except "null" init the sound. + if (stricmp(snd_backend, "null") == 0) { - GSnd = new OpenALSoundRenderer; + GSnd = new NullSoundRenderer; + } + else + { + #ifndef NO_OPENAL + if (IsOpenALPresent()) + { + GSnd = new OpenALSoundRenderer; + } + #endif } -#endif // !NO_OPENAL - if (!GSnd || !GSnd->IsValid ()) { I_CloseSound(); diff --git a/source/core/sound/backend/i_sound.h b/source/core/sound/backend/i_sound.h index 7eaac6d04..060838edf 100644 --- a/source/core/sound/backend/i_sound.h +++ b/source/core/sound/backend/i_sound.h @@ -35,6 +35,7 @@ #ifndef __I_SOUND__ #define __I_SOUND__ +#include #include "i_soundinternal.h" #include "zstring.h" #include @@ -108,8 +109,8 @@ public: virtual SoundStream *CreateStream (SoundStreamCallback callback, int buffbytes, int flags, int samplerate, void *userdata) = 0; // Starts a sound. - virtual FISoundChannel *StartSound (SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan) = 0; - virtual FISoundChannel *StartSound3D (SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan) = 0; + virtual FISoundChannel *StartSound (SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan, float startTime = 0.f) = 0; + virtual FISoundChannel *StartSound3D (SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime = 0.f) = 0; // Stops a sound channel. virtual void StopChannel (FISoundChannel *chan) = 0; @@ -121,7 +122,7 @@ public: virtual void ChannelPitch(FISoundChannel *chan, float volume) = 0; // Marks a channel's start time without actually playing it. - virtual void MarkStartTime (FISoundChannel *chan) = 0; + virtual void MarkStartTime (FISoundChannel *chan, float startTime = 0.f) = 0; // Returns position of sound on this channel, in samples. virtual unsigned int GetPosition(FISoundChannel *chan) = 0; @@ -159,6 +160,8 @@ public: }; extern SoundRenderer *GSnd; +extern bool nosfx; +extern bool nosound; void I_InitSound (); void I_CloseSound(); @@ -166,11 +169,6 @@ void I_CloseSound(); extern ReverbContainer *DefaultEnvironments[26]; bool IsOpenALPresent(); - -enum -{ - PAUSESFX_MENU = 1, - PAUSESFX_CONSOLE = 2 -}; +void S_SoundReset(); #endif diff --git a/source/core/sound/backend/i_soundinternal.h b/source/core/sound/backend/i_soundinternal.h index f5631b4f5..039e308d7 100644 --- a/source/core/sound/backend/i_soundinternal.h +++ b/source/core/sound/backend/i_soundinternal.h @@ -6,7 +6,6 @@ #include "vectors.h" #include "tarray.h" -#include #include "tflags.h" enum EChanFlag @@ -30,7 +29,7 @@ enum EChanFlag CHANF_VIRTUAL = 2048, // internal: Channel is currently virtual CHANF_NOSTOP = 4096, // only for A_PlaySound. Does not start if channel is playing something. CHANF_OVERLAP = 8192, // [MK] Does not stop any sounds in the channel and instead plays over them. - CHANF_ENDED = 16384, // Helper to detect broken ChannelEnded implementations. + CHANF_LOCAL = 16384, // only plays locally for the calling actor CHANF_TRANSIENT = 32768, // Do not record in savegames - used for sounds that get restarted outside the sound system (e.g. ambients in SW and Blood) }; diff --git a/source/core/sound/backend/oalsound.cpp b/source/core/sound/backend/oalsound.cpp index b2ad03535..86fbc303a 100644 --- a/source/core/sound/backend/oalsound.cpp +++ b/source/core/sound/backend/oalsound.cpp @@ -35,16 +35,15 @@ #include #include +#include "c_cvars.h" #include "templates.h" #include "oalsound.h" #include "c_dispatch.h" #include "v_text.h" #include "i_module.h" #include "cmdlib.h" -#include "c_cvars.h" -#include "printf.h" -#include -#include "filereadermusicinterface.h" +#include "m_fixed.h" + const char *GetSampleTypeName(SampleType type); const char *GetChannelConfigName(ChannelConfig chan); @@ -108,7 +107,9 @@ ReverbContainer *ForcedEnvironment; #ifndef NO_OPENAL +EXTERN_CVAR (Int, snd_channels) EXTERN_CVAR (Int, snd_samplerate) +EXTERN_CVAR (Bool, snd_waterreverb) EXTERN_CVAR (Bool, snd_pitched) EXTERN_CVAR (Int, snd_hrtf) @@ -1171,7 +1172,7 @@ SoundStream *OpenALSoundRenderer::CreateStream(SoundStreamCallback callback, int return stream; } -FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan) +FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan, float startTime) { if(FreeSfx.Size() == 0) { @@ -1222,7 +1223,10 @@ FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int alSourcef(source, AL_PITCH, PITCH(pitch)); if(!reuse_chan || reuse_chan->StartTime == 0) - alSourcef(source, AL_SEC_OFFSET, 0.f); + { + float st = (chanflags&SNDF_LOOP) ? fmod(startTime, (float)GetMSLength(sfx) / 1000.f) : clamp(startTime, 0.f, (float)GetMSLength(sfx) / 1000.f); + alSourcef(source, AL_SEC_OFFSET, st); + } else { if((chanflags&SNDF_ABSTIME)) @@ -1271,7 +1275,7 @@ FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, - int channum, int chanflags, FISoundChannel *reuse_chan) + int channum, int chanflags, FISoundChannel *reuse_chan, float startTime) { float dist_sqr = (float)(pos - listener->position).LengthSquared(); @@ -1415,7 +1419,10 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener alSourcef(source, AL_PITCH, PITCH(pitch)); if(!reuse_chan || reuse_chan->StartTime == 0) - alSourcef(source, AL_SEC_OFFSET, 0.f); + { + float st = (chanflags & SNDF_LOOP) ? fmod(startTime, (float)GetMSLength(sfx) / 1000.f) : clamp(startTime, 0.f, (float)GetMSLength(sfx) / 1000.f); + alSourcef(source, AL_SEC_OFFSET, st); + } else { if((chanflags&SNDF_ABSTIME)) @@ -1782,7 +1789,7 @@ void OpenALSoundRenderer::UpdateSounds() if(connected == ALC_FALSE) { Printf("Sound device disconnected; restarting...\n"); - soundEngine->Reset(); + S_SoundReset(); return; } } @@ -1795,11 +1802,14 @@ bool OpenALSoundRenderer::IsValid() return Device != NULL; } -void OpenALSoundRenderer::MarkStartTime(FISoundChannel *chan) +void OpenALSoundRenderer::MarkStartTime(FISoundChannel *chan, float startTime) { // FIXME: Get current time (preferably from the audio clock, but the system // time will have to do) - chan->StartTime = std::chrono::steady_clock::now().time_since_epoch().count(); + using namespace std::chrono; + auto startTimeDuration = duration(startTime); + auto diff = steady_clock::now().time_since_epoch() - startTimeDuration; + chan->StartTime = static_cast(duration_cast(diff).count()); } float OpenALSoundRenderer::GetAudibility(FISoundChannel *chan) diff --git a/source/core/sound/backend/oalsound.h b/source/core/sound/backend/oalsound.h index a3ed09c57..a333d772d 100644 --- a/source/core/sound/backend/oalsound.h +++ b/source/core/sound/backend/oalsound.h @@ -136,8 +136,8 @@ public: virtual SoundStream *CreateStream(SoundStreamCallback callback, int buffbytes, int flags, int samplerate, void *userdata); // Starts a sound. - virtual FISoundChannel *StartSound(SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan); - virtual FISoundChannel *StartSound3D(SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan); + virtual FISoundChannel *StartSound(SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan, float startTime); + virtual FISoundChannel *StartSound3D(SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime); // Changes a channel's volume. virtual void ChannelVolume(FISoundChannel *chan, float volume); @@ -166,7 +166,7 @@ public: virtual void UpdateListener(SoundListener *); virtual void UpdateSounds(); - virtual void MarkStartTime(FISoundChannel*); + virtual void MarkStartTime(FISoundChannel*, float startTime); virtual float GetAudibility(FISoundChannel*); diff --git a/source/core/sound/s_sound.cpp b/source/core/sound/s_sound.cpp index b67900d8a..b6d6bb242 100644 --- a/source/core/sound/s_sound.cpp +++ b/source/core/sound/s_sound.cpp @@ -36,16 +36,11 @@ #include #include +#include "templates.h" #include "s_soundinternal.h" #include "m_swap.h" #include "superfasthash.h" -#include "c_cvars.h" -#include "name.h" -#include "filesystem.h" -#include "cmdlib.h" -#include "gamecontrol.h" -#include "serializer.h" -#include "build.h" +#include "s_music.h" enum @@ -62,7 +57,7 @@ int sfx_empty = -1; // //========================================================================== -void SoundEngine::Init(TArray &curve, int factor) +void SoundEngine::Init(TArray &curve) { StopAllChannels(); // Free all channels for use. @@ -71,7 +66,6 @@ void SoundEngine::Init(TArray &curve, int factor) ReturnChannel(Channels); } S_SoundCurve = std::move(curve); - SndCurveFactor = (uint8_t)factor; } //========================================================================== @@ -173,7 +167,6 @@ void SoundEngine::CacheSound (sfxinfo_t *sfx) } else { - // Since we do not know in what format the sound will be used, we have to cache both. LoadSound(sfx); sfx->bUsed = true; } @@ -374,7 +367,7 @@ FSoundID SoundEngine::ResolveSound(const void *, int, FSoundID soundid, float &a FSoundChan *SoundEngine::StartSound(int type, const void *source, const FVector3 *pt, int channel, EChanFlags flags, FSoundID sound_id, float volume, float attenuation, - FRolloffInfo *forcedrolloff, float spitch) + FRolloffInfo *forcedrolloff, float spitch, float startTime) { sfxinfo_t *sfx; EChanFlags chanflags = flags; @@ -385,7 +378,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, FVector3 pos, vel; FRolloffInfo *rolloff; - if (sound_id <= 0 || volume <= 0 || userConfig.nosound ) + if (sound_id <= 0 || volume <= 0 || nosfx || nosound ) return NULL; // prevent crashes. @@ -465,9 +458,8 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, near_limit = 0; } - // If this sound doesn't like playing near itself, don't play it if - // that's what would happen. (Does this really need the SOURCE_Actor restriction?) - if (near_limit > 0 && CheckSoundLimit(sfx, pos, near_limit, limit_range, type, type == SOURCE_Actor? source : nullptr, channel)) + // If this sound doesn't like playing near itself, don't play it if that's what would happen. + if (near_limit > 0 && CheckSoundLimit(sfx, pos, near_limit, limit_range, type, source, channel)) { chanflags |= CHANF_EVICTED; } @@ -555,13 +547,17 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, if (chanflags & (CHANF_UI|CHANF_NOPAUSE)) startflags |= SNDF_NOPAUSE; if (chanflags & CHANF_UI) startflags |= SNDF_NOREVERB; + startTime = (startflags & SNDF_LOOP) + ? fmod(startTime, (float)GSnd->GetMSLength(sfx->data) / 1000.f) + : clamp(startTime, 0.f, (float)GSnd->GetMSLength(sfx->data) / 1000.f); + if (attenuation > 0 && type != SOURCE_None) { - chan = (FSoundChan*)GSnd->StartSound3D (sfx->data, &listener, float(volume), rolloff, float(attenuation), pitch, basepriority, pos, vel, channel, startflags, NULL); + chan = (FSoundChan*)GSnd->StartSound3D (sfx->data, &listener, float(volume), rolloff, float(attenuation), pitch, basepriority, pos, vel, channel, startflags, NULL, startTime); } else { - chan = (FSoundChan*)GSnd->StartSound (sfx->data, float(volume), pitch, startflags, NULL); + chan = (FSoundChan*)GSnd->StartSound (sfx->data, float(volume), pitch, startflags, NULL, startTime); } } if (chan == NULL && (chanflags & CHANF_LOOP)) @@ -893,6 +889,38 @@ void SoundEngine::StopSound(int sourcetype, const void* actor, int channel, int } } +//========================================================================== +// +// S_StopAllActorSounds +// +// Stops all sounds on an actor. +// +//========================================================================== + +void SoundEngine::StopActorSounds(int sourcetype, const void* actor, int chanmin, int chanmax) +{ + const bool all = (chanmin == 0 && chanmax == 0); + if (!all && chanmax > chanmin) + { + const int temp = chanmax; + chanmax = chanmin; + chanmin = temp; + } + + FSoundChan* chan = Channels; + while (chan != nullptr) + { + FSoundChan* next = chan->NextChan; + if (chan->SourceType == sourcetype && + chan->Source == actor && + (all || (chan->EntChannel >= chanmin && chan->EntChannel <= chanmax))) + { + StopChannel(chan); + } + chan = next; + } +} + //========================================================================== // // S_StopAllChannels @@ -1249,7 +1277,7 @@ float SoundEngine::GetRolloff(const FRolloffInfo* rolloff, float distance) if (rolloff->RolloffType == ROLLOFF_Custom && S_SoundCurve.Size() > 0) { - return S_SoundCurve[int(S_SoundCurve.Size() * (1.f - volume))] / (float)SndCurveFactor; + return S_SoundCurve[int(S_SoundCurve.Size() * (1.f - volume))] / 127.f; } return (powf(10.f, volume) - 1.f) / 9.f; } @@ -1264,7 +1292,7 @@ void SoundEngine::ChannelEnded(FISoundChannel *ichan) { FSoundChan *schan = static_cast(ichan); bool evicted; - schan->ChanFlags &= ~CHANF_ENDED; + if (schan != NULL) { // If the sound was stopped with GSnd->StopSound(), then we know @@ -1341,11 +1369,6 @@ void SoundEngine::StopChannel(FSoundChan *chan) if (!(chan->ChanFlags & CHANF_EVICTED)) { chan->ChanFlags |= CHANF_FORGETTABLE; - if (chan->SourceType == SOURCE_Actor) - { - chan->Source = NULL; - chan->SourceType = SOURCE_Unattached; - } } if (GSnd) GSnd->StopChannel(chan); } @@ -1486,13 +1509,6 @@ int SoundEngine::AddSoundLump(const char* logicalname, int lump, int CurrentPitc return (int)S_sfx.Size()-1; } -int SoundEngine::AddSfx(sfxinfo_t &sfx) -{ - S_sfx.Push(sfx); - if (sfx.ResourceId >= 0) ResIdMap[sfx.ResourceId] = S_sfx.Size() - 1; - return (int)S_sfx.Size() - 1; -} - //========================================================================== // @@ -1645,209 +1661,10 @@ void SoundEngine::AddRandomSound(int Owner, TArray list) S_sfx[Owner].NearLimit = -1; } -extern ReverbContainer* ForcedEnvironment; -static int LastReverb; - -CUSTOM_CVAR(Bool, snd_reverb, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +void S_SoundReset() { - FX_SetReverb(-1); -} - -// This is for testing reverb settings. -CUSTOM_CVAR(Int, snd_reverbtype, -1, 0) -{ - FX_SetReverb(-1); -} - -void FX_SetReverb(int strength) -{ - if (strength == -1) strength = LastReverb; - if (snd_reverbtype > -1) - { - strength = snd_reverbtype; - ForcedEnvironment = S_FindEnvironment(strength); - } - else if (snd_reverb && strength > 0) - { - // todo: optimize environments. The original "reverb" was garbage and not usable as reference. - if (strength < 64) strength = 0x1400; - else if (strength < 192) strength = 0x1503; - else strength = 0x1900; - LastReverb = strength; - ForcedEnvironment = S_FindEnvironment(strength); - } - else ForcedEnvironment = nullptr; -} - - -#include "basics.h" -#include "stats.h" -#include "v_text.h" -//========================================================================== -// -// S_NoiseDebug -// -// [RH] Print sound debug info. Called by status bar. -//========================================================================== - -FString SoundEngine::NoiseDebug() -{ - FVector3 listener; - FVector3 origin; - - listener = this->listener.position; - int ch = 0; - - FString out; - - out.Format("*** SOUND DEBUG INFO ***\nListener: %3.2f %2.3f %2.3f\n" - "x y z vol dist chan pri flags aud pos name\n", listener.X, listener.Y, listener.Z); - - for (auto chan = Channels; chan; chan = chan->NextChan) - { - if (!(chan->ChanFlags & CHANF_IS3D)) - { - out += "--- --- --- --- "; - } - else - { - CalcPosVel(chan, &origin, nullptr); - out.AppendFormat(TEXTCOLOR_GOLD "%5.0f | %5.0f | %5.0f | %5.0f ", origin.X, origin.Z, origin.Y, (origin - listener).Length()); - } - out.AppendFormat("%-.2g %-4d %-4d %sF%s3%sZ%sU%sM%sN%sA%sL%sE%sV" TEXTCOLOR_GOLD " %-5.4f %-4u %d: %s %p\n", chan->Volume, chan->EntChannel, chan->Priority, - (chan->ChanFlags & CHANF_FORGETTABLE) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, - (chan->ChanFlags & CHANF_IS3D) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, - (chan->ChanFlags & CHANF_LISTENERZ) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, - (chan->ChanFlags & CHANF_UI) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, - (chan->ChanFlags & CHANF_MAYBE_LOCAL) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, - (chan->ChanFlags & CHANF_NOPAUSE) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, - (chan->ChanFlags & CHANF_AREA) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, - (chan->ChanFlags & CHANF_LOOP) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, - (chan->ChanFlags & CHANF_EVICTED) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, - (chan->ChanFlags & CHANF_VIRTUAL) ? TEXTCOLOR_GREEN : TEXTCOLOR_DARKRED, - GSnd->GetAudibility(chan), GSnd->GetPosition(chan), ((int)chan->OrgID)-1, S_sfx[chan->SoundID].name.GetChars(), chan->Source); - ch++; - } - out.AppendFormat("%d channels\n", ch); - return out; -} - -ADD_STAT(sounddebug) -{ - return soundEngine->NoiseDebug(); -} - -CVAR(Bool, snd_extendedlookup, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - -int S_LookupSound(const char* fn) -{ - static const char * const sndformats[] = { "OGG", "FLAC", "WAV" }; - if (snd_extendedlookup) - { - int lump = fileSystem.FindFileWithExtensions(StripExtension(fn), sndformats, countof(sndformats)); - if (lump >= 0) return lump; - } - return fileSystem.FindFile(fn); -} - -//========================================================================== -// -// Although saving the sound system's state is supposed to be an engine -// feature, the specifics cannot be set up there, this needs to be on the client side. -// -//========================================================================== - -static FSerializer& Serialize(FSerializer& arc, const char* key, FSoundChan& chan, FSoundChan* def) -{ - if (arc.BeginObject(key)) - { - arc("sourcetype", chan.SourceType) - ("soundid", chan.SoundID) - ("orgid", chan.OrgID) - ("volume", chan.Volume) - ("distancescale", chan.DistanceScale) - ("pitch", chan.Pitch) - ("chanflags", chan.ChanFlags) - ("entchannel", chan.EntChannel) - ("priority", chan.Priority) - ("nearlimit", chan.NearLimit) - ("starttime", chan.StartTime) - ("rolloftype", chan.Rolloff.RolloffType) - ("rolloffmin", chan.Rolloff.MinDistance) - ("rolloffmax", chan.Rolloff.MaxDistance) - ("limitrange", chan.LimitRange) - .Array("point", chan.Point, 3); - - int SourceIndex = 0; - if (arc.isWriting()) - { - if (chan.SourceType == SOURCE_Actor) SourceIndex = int((spritetype*)(chan.Source) - sprite); - else SourceIndex = soundEngine->SoundSourceIndex(&chan); - } - arc("Source", SourceIndex); - if (arc.isReading()) - { - if (chan.SourceType == SOURCE_Actor) chan.Source = &sprite[SourceIndex]; - else soundEngine->SetSource(&chan, SourceIndex); - } - arc.EndObject(); - } - return arc; -} - -//========================================================================== -// -// S_SerializeSounds -// -//========================================================================== - -void S_SerializeSounds(FSerializer& arc) -{ - FSoundChan* chan; - - GSnd->Sync(true); - - if (arc.isWriting()) - { - // Count channels and accumulate them so we can store them in - // reverse order. That way, they will be in the same order when - // reloaded later as they are now. - TArray chans = soundEngine->AllActiveChannels(); - - if (chans.Size() > 0 && arc.BeginArray("sounds")) - { - for (unsigned int i = chans.Size(); i-- != 0; ) - { - // Replace start time with sample position. - uint64_t start = chans[i]->StartTime; - chans[i]->StartTime = GSnd ? GSnd->GetPosition(chans[i]) : 0; - arc(nullptr, *chans[i]); - chans[i]->StartTime = start; - } - arc.EndArray(); - } - } - else - { - unsigned int count; - - soundEngine->StopAllChannels(); - if (arc.BeginArray("sounds")) - { - count = arc.ArraySize(); - for (unsigned int i = 0; i < count; ++i) - { - chan = (FSoundChan*)soundEngine->GetChannel(nullptr); - arc(nullptr, *chan); - // Sounds always start out evicted when restored from a save. - chan->ChanFlags |= CHANF_EVICTED | CHANF_ABSTIME; - } - arc.EndArray(); - } - // totalclock runs on 120 fps, we need to allow a small delay here. - soundEngine->SetRestartTime((int)totalclock + 6); - } - GSnd->Sync(false); - GSnd->UpdateSounds(); + S_StopMusic(true); + soundEngine->Reset(); + S_RestartMusic(); } diff --git a/source/core/sound/s_soundinternal.h b/source/core/sound/s_soundinternal.h index 112fb8d31..0d0060e9f 100644 --- a/source/core/sound/s_soundinternal.h +++ b/source/core/sound/s_soundinternal.h @@ -1,6 +1,6 @@ #pragma once -#include "backend/i_sound.h" +#include "i_sound.h" struct FRandomSoundList { @@ -183,7 +183,6 @@ struct FSoundChan : public FISoundChannel // 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" // Channels below 0 are reserved for CHAN_AUTO. enum EChannel @@ -206,16 +205,11 @@ enum EChannel #define ATTN_IDLE 1.001f #define ATTN_STATIC 3.f // diminish very rapidly with distance -enum // This cannot be remain as this, but for now it has to suffice. +enum // The core source types, implementations may extend this list as they see fit. { SOURCE_Any = -1, // Input for check functions meaning 'any source' - SOURCE_None, // Sound is always on top of the listener. - SOURCE_Actor, // Sound is coming from an actor. - SOURCE_Ambient, // Sound is coming from a blood ambient definition. SOURCE_Unattached, // Sound is not attached to any particular emitter. - SOURCE_Player, // SW player sound (player in SW maintains its own position separately from the sprite so needs to be special.) - SOURCE_Swirly, // Special stuff for Exhumed. (local sound with custom panning) - SOURCE_EXBoss, // Another special case for Exhumed. + SOURCE_None, // Sound is always on top of the listener. }; @@ -233,7 +227,6 @@ class SoundEngine { protected: bool SoundPaused = false; // whether sound is paused - uint8_t SndCurveFactor = 127; int RestartEvictionsAt = 0; // do not restart evicted channels before this time SoundListener listener{}; @@ -264,9 +257,9 @@ private: // Checks if a copy of this sound is already playing. bool CheckSingular(int sound_id); - bool CheckSoundLimit(sfxinfo_t* sfx, const FVector3& pos, int near_limit, float limit_range, int sourcetype, const void* actor, int channel); virtual TArray ReadSound(int lumpnum) = 0; protected: + virtual bool CheckSoundLimit(sfxinfo_t* sfx, const FVector3& pos, int near_limit, float limit_range, int sourcetype, const void* actor, int channel); virtual FSoundID ResolveSound(const void *ent, int srctype, FSoundID soundid, float &attenuation); public: @@ -276,18 +269,17 @@ public: } void EvictAllChannels(); - // For handling special sound types. Source types None, Unattached and Actor never get here. virtual int SoundSourceIndex(FSoundChan* chan) { return 0; } virtual void SetSource(FSoundChan* chan, int index) {} - void StopChannel(FSoundChan* chan); + virtual void StopChannel(FSoundChan* chan); sfxinfo_t* LoadSound(sfxinfo_t* sfx); // Initializes sound stuff, including volume // Sets channels, SFX and music volume, // allocates channel buffer, sets S_sfx lookup. // - void Init(TArray &sndcurve, int factor = 127); + void Init(TArray &sndcurve); void InitData(); void Clear(); void Shutdown(); @@ -301,19 +293,20 @@ public: void CalcPosVel(FSoundChan* chan, FVector3* pos, FVector3* vel); // Loads a sound, including any random sounds it might reference. - void CacheSound(sfxinfo_t* sfx); + virtual void CacheSound(sfxinfo_t* sfx); void CacheSound(int sfx) { CacheSound(&S_sfx[sfx]); } void UnloadSound(sfxinfo_t* sfx); void UpdateSounds(int time); FSoundChan* StartSound(int sourcetype, const void* source, - const FVector3* pt, int channel, EChanFlags flags, FSoundID sound_id, float volume, float attenuation, FRolloffInfo* rolloff = nullptr, float spitch = 0.0f); + const FVector3* pt, int channel, EChanFlags flags, FSoundID sound_id, float volume, float attenuation, FRolloffInfo* rolloff = nullptr, float spitch = 0.0f, float startTime = 0.0f); // Stops an origin-less sound from playing from this channel. void StopSoundID(int sound_id); void StopSound(int channel, int sound_id = -1); void StopSound(int sourcetype, const void* actor, int channel, int sound_id = -1); + void StopActorSounds(int sourcetype, const void* actor, int chanmin, int chanmax); void RelinkSound(int sourcetype, const void* from, const void* to, const FVector3* optpos); void ChangeSoundVolume(int sourcetype, const void* source, int channel, double dvolume); @@ -326,7 +319,6 @@ public: void Reset(); void MarkUsed(int num); void CacheMarkedSounds(); - FString NoiseDebug(); TArray AllActiveChannels(); void MarkAllUnused() @@ -342,6 +334,10 @@ public: { listener = l; } + const SoundListener& GetListener() const + { + return listener; + } void SetRestartTime(int time) { RestartEvictionsAt = time; @@ -413,8 +409,7 @@ public: int FindSoundByResID(int rid); int FindSoundNoHash(const char* logicalname); int FindSoundByLump(int lump); - int AddSoundLump(const char* logicalname, int lump, int CurrentPitchMask, int resid = -1, int nearlimit = 2); - int AddSfx(sfxinfo_t &sfx); + virtual int AddSoundLump(const char* logicalname, int lump, int CurrentPitchMask, int resid = -1, int nearlimit = 2); int FindSoundTentative(const char* name); void CacheRandomSound(sfxinfo_t* sfx); unsigned int GetMSLength(FSoundID sound); @@ -434,27 +429,4 @@ struct FReverbField unsigned int Flag; }; -inline void FX_StopAllSounds(void) -{ - soundEngine->StopAllChannels(); -} -void FX_SetReverb(int strength); - -inline void FX_SetReverbDelay(int delay) -{ -} - -inline int S_FindSoundByResID(int ndx) -{ - return soundEngine->FindSoundByResID(ndx); -} - -inline int S_FindSound(const char* name) -{ - return soundEngine->FindSound(name); -} - -int S_LookupSound(const char* fn); -class FSerializer; -void S_SerializeSounds(FSerializer& arc); diff --git a/source/duke3d/src/demo.cpp b/source/duke3d/src/demo.cpp index 1e8744073..785271fd7 100644 --- a/source/duke3d/src/demo.cpp +++ b/source/duke3d/src/demo.cpp @@ -67,8 +67,8 @@ void Demo_PrepareWarp(void) { if (!g_demo_paused) { - g_demo_soundToggle = userConfig.nosound; - userConfig.nosound = true; + g_demo_soundToggle = nosound; + nosound = true; } FX_StopAllSounds(); @@ -384,8 +384,8 @@ static void Demo_SetupProfile(void) { g_demo_profile *= -1; // now >0: profile for real - g_demo_soundToggle = userConfig.nosound; - userConfig.nosound = true; // restored by Demo_FinishProfile() + g_demo_soundToggle = nosound; + nosound = true; // restored by Demo_FinishProfile() Bmemset(&g_prof, 0, sizeof(g_prof)); @@ -401,7 +401,7 @@ static void Demo_FinishProfile(void) double gms=g_prof.totalgamems; double dms1=g_prof.totalroomsdrawms, dms2=g_prof.totalrestdrawms; - userConfig.nosound = g_demo_soundToggle; + nosound = g_demo_soundToggle; if (nt > 0) { @@ -667,7 +667,7 @@ nextdemo_nomenu: if (g_demo_goalCnt>0) { g_demo_goalCnt=0; - userConfig.nosound = g_demo_soundToggle; + nosound = g_demo_soundToggle; } if (Demo_IsProfiling()) // don't reset g_demo_profile if it's < 0 @@ -709,10 +709,10 @@ nextdemo_nomenu: } else { - int32_t k = userConfig.nosound; - userConfig.nosound = true; + int32_t k = nosound; + nosound = true; G_DoMoveThings(); - userConfig.nosound = k; + nosound = k; } ototalclock += TICSPERFRAME; @@ -727,7 +727,7 @@ nextdemo_nomenu: if (g_demo_cnt>=g_demo_goalCnt) { g_demo_goalCnt = 0; - userConfig.nosound = g_demo_soundToggle; + nosound = g_demo_soundToggle; } } } diff --git a/source/duke3d/src/sounds.cpp b/source/duke3d/src/sounds.cpp index 594fc7a13..c436f7e47 100644 --- a/source/duke3d/src/sounds.cpp +++ b/source/duke3d/src/sounds.cpp @@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "duke3d.h" #include "raze_music.h" #include "mapinfo.h" -#include "sound/s_soundinternal.h" +#include "raze_sound.h" BEGIN_DUKE_NS @@ -44,6 +44,17 @@ public: S_Rolloff.MinDistance = 144; // was originally 576 which looks like a bug and sounds like crap. S_Rolloff.MaxDistance = 1088; } + + void StopChannel(FSoundChan* chan) override + { + if (chan && chan->SysChannel != NULL && !(chan->ChanFlags & CHANF_EVICTED) && chan->SourceType == SOURCE_Actor) + { + chan->Source = NULL; + chan->SourceType = SOURCE_Unattached; + } + SoundEngine::StopChannel(chan); + } + }; void S_InitSound() diff --git a/source/duke3d/src/sounds.h b/source/duke3d/src/sounds.h index 33c93f0cc..030e537a0 100644 --- a/source/duke3d/src/sounds.h +++ b/source/duke3d/src/sounds.h @@ -30,7 +30,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define sounds_public_h_ #include "sounds_common.h" -#include "sound/s_soundinternal.h" +#include "raze_sound.h" #include "raze_music.h" BEGIN_DUKE_NS diff --git a/source/exhumed/src/d_menu.cpp b/source/exhumed/src/d_menu.cpp index f8ad58c0e..f225ed168 100644 --- a/source/exhumed/src/d_menu.cpp +++ b/source/exhumed/src/d_menu.cpp @@ -28,7 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "sound.h" #include "names.h" #include "version.h" -#include "s_soundinternal.h" +#include "raze_sound.h" #include "menu/menu.h" diff --git a/source/exhumed/src/exhumed.cpp b/source/exhumed/src/exhumed.cpp index 3f3f55005..36189cb98 100644 --- a/source/exhumed/src/exhumed.cpp +++ b/source/exhumed/src/exhumed.cpp @@ -74,7 +74,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "gamecvars.h" #include "savegamehelp.h" #include "c_dispatch.h" -#include "s_soundinternal.h" +#include "raze_sound.h" #include "core/menu/menu.h" BEGIN_PS_NS diff --git a/source/exhumed/src/menu.cpp b/source/exhumed/src/menu.cpp index 05de2deb8..981811f1e 100644 --- a/source/exhumed/src/menu.cpp +++ b/source/exhumed/src/menu.cpp @@ -37,7 +37,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "object.h" #include "light.h" #include "cd.h" -#include "s_soundinternal.h" +#include "raze_sound.h" #include "menu/menu.h" #include "v_2ddrawer.h" #include diff --git a/source/exhumed/src/sound.cpp b/source/exhumed/src/sound.cpp index 74e8c6ee0..86512fd38 100644 --- a/source/exhumed/src/sound.cpp +++ b/source/exhumed/src/sound.cpp @@ -30,7 +30,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "trigdat.h" #include "sequence.h" #include "cd.h" -#include "sound/s_soundinternal.h" +#include "raze_sound.h" BEGIN_PS_NS @@ -153,6 +153,17 @@ public: S_Rolloff.MinDistance = 0; S_Rolloff.MaxDistance = 1536; } + + void StopChannel(FSoundChan* chan) override + { + if (chan && chan->SysChannel != NULL && !(chan->ChanFlags & CHANF_EVICTED) && chan->SourceType == SOURCE_Actor) + { + chan->Source = NULL; + chan->SourceType = SOURCE_Unattached; + } + SoundEngine::StopChannel(chan); + } + }; //========================================================================== diff --git a/source/exhumed/src/sound.h b/source/exhumed/src/sound.h index ef47a9ed5..6bbedfd2e 100644 --- a/source/exhumed/src/sound.h +++ b/source/exhumed/src/sound.h @@ -19,7 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #ifndef __sound_h__ #define __sound_h__ -#include "s_soundinternal.h" +#include "raze_sound.h" BEGIN_PS_NS diff --git a/source/rr/src/demo.cpp b/source/rr/src/demo.cpp index b79544de1..8f52b4bef 100644 --- a/source/rr/src/demo.cpp +++ b/source/rr/src/demo.cpp @@ -66,8 +66,8 @@ void Demo_PrepareWarp(void) { if (!g_demo_paused) { - g_demo_soundToggle = userConfig.nosound; - userConfig.nosound = true; + g_demo_soundToggle = nosound; + nosound = true; } FX_StopAllSounds(); @@ -387,8 +387,8 @@ static void Demo_SetupProfile(void) { g_demo_profile *= -1; // now >0: profile for real - g_demo_soundToggle = userConfig.nosound; - userConfig.nosound = true; // restored by Demo_FinishProfile() + g_demo_soundToggle = nosound; + nosound = true; // restored by Demo_FinishProfile() Bmemset(&g_prof, 0, sizeof(g_prof)); @@ -404,7 +404,7 @@ static void Demo_FinishProfile(void) double gms=g_prof.totalgamems; double dms1=g_prof.totalroomsdrawms, dms2=g_prof.totalrestdrawms; - userConfig.nosound = g_demo_soundToggle; + nosound = g_demo_soundToggle; if (nt > 0) { @@ -670,7 +670,7 @@ nextdemo_nomenu: if (g_demo_goalCnt>0) { g_demo_goalCnt=0; - userConfig.nosound = g_demo_soundToggle; + nosound = g_demo_soundToggle; } if (Demo_IsProfiling()) // don't reset g_demo_profile if it's < 0 @@ -714,10 +714,10 @@ nextdemo_nomenu: } else { - int32_t k = userConfig.nosound; - userConfig.nosound = true; + int32_t k = nosound; + nosound = true; G_DoMoveThings(); - userConfig.nosound = k; + nosound = k; } ototalclock += TICSPERFRAME; @@ -732,7 +732,7 @@ nextdemo_nomenu: if (g_demo_cnt>=g_demo_goalCnt) { g_demo_goalCnt = 0; - userConfig.nosound = g_demo_soundToggle; + nosound = g_demo_soundToggle; } } } diff --git a/source/rr/src/sounds.cpp b/source/rr/src/sounds.cpp index 827b2077b..562e18f3a 100644 --- a/source/rr/src/sounds.cpp +++ b/source/rr/src/sounds.cpp @@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "duke3d.h" #include "raze_music.h" #include "mapinfo.h" -#include "sound/s_soundinternal.h" +#include "raze_sound.h" BEGIN_RR_NS @@ -43,6 +43,17 @@ public: S_Rolloff.MinDistance = 144; // was originally 576 which looks like a bug and sounds like crap. S_Rolloff.MaxDistance = 1088; } + + void StopChannel(FSoundChan* chan) override + { + if (chan && chan->SysChannel != NULL && !(chan->ChanFlags & CHANF_EVICTED) && chan->SourceType == SOURCE_Actor) + { + chan->Source = NULL; + chan->SourceType = SOURCE_Unattached; + } + SoundEngine::StopChannel(chan); + } + }; void S_InitSound() diff --git a/source/rr/src/sounds.h b/source/rr/src/sounds.h index 963b14b07..04d672b87 100644 --- a/source/rr/src/sounds.h +++ b/source/rr/src/sounds.h @@ -30,7 +30,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define sounds_public_h_ #include "sounds_common.h" -#include "sound/s_soundinternal.h" +#include "raze_sound.h" #include "raze_music.h" BEGIN_RR_NS diff --git a/source/sw/src/d_menu.cpp b/source/sw/src/d_menu.cpp index 481552d67..eb0ca4f07 100644 --- a/source/sw/src/d_menu.cpp +++ b/source/sw/src/d_menu.cpp @@ -50,7 +50,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "colormap.h" #include "config.h" #include "menu/menu.h" -#include "sound/s_soundinternal.h" +#include "raze_sound.h" #include "sounds.h" #include "../../glbackend/glbackend.h" diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index ce2fa0687..fb9c7ec87 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -99,7 +99,7 @@ Things required to make savegames work: #include "gstrings.h" #include "mapinfo.h" #include "rendering/v_video.h" -#include "sound/s_soundinternal.h" +#include "raze_sound.h" #include "secrets.h" #include "osdcmds.h" diff --git a/source/sw/src/game.h b/source/sw/src/game.h index c51639079..d59c06032 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -46,7 +46,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "settings.h" #include "pragmas.h" #include "gamecvars.h" -#include "s_soundinternal.h" +#include "raze_sound.h" BEGIN_SW_NS diff --git a/source/sw/src/panel.cpp b/source/sw/src/panel.cpp index bfb77a860..c2ef56e02 100644 --- a/source/sw/src/panel.cpp +++ b/source/sw/src/panel.cpp @@ -46,7 +46,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "weapon.h" #include "menu/menu.h" #include "swcvar.h" -#include "sound/s_soundinternal.h" +#include "raze_sound.h" BEGIN_SW_NS diff --git a/source/sw/src/sounds.cpp b/source/sw/src/sounds.cpp index ff1c1a653..0fbf17dce 100644 --- a/source/sw/src/sounds.cpp +++ b/source/sw/src/sounds.cpp @@ -50,7 +50,7 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #include "config.h" #include "menu/menu.h" #include "raze_music.h" -#include "sound/s_soundinternal.h" +#include "raze_sound.h" #include "filesystem.h" #include "serializer.h" @@ -450,6 +450,16 @@ public: else chan->Source = nullptr; } + void StopChannel(FSoundChan* chan) override + { + if (chan && chan->SysChannel != NULL && !(chan->ChanFlags & CHANF_EVICTED) && chan->SourceType == SOURCE_Actor) + { + chan->Source = NULL; + chan->SourceType = SOURCE_Unattached; + } + SoundEngine::StopChannel(chan); + } + }; //==========================================================================