From d4e9116b0f5708b7d142e37479945d9abaec1ee4 Mon Sep 17 00:00:00 2001 From: Regalis Date: Sun, 9 Oct 2016 19:25:14 +0300 Subject: [PATCH] Audio channel states visible in debug view + some sound fixes: - a short "cooldown" after each footstep sound (prevents the sound playing multiple times during one footstep) - water flow sounds are only played by one of the hulls a gap is between - flow rate affects the range of the flow sound --- .../Source/Characters/Animation/Ragdoll.cs | 6 +- Subsurface/Source/GUI/GUI.cs | 27 ++++ Subsurface/Source/Map/Hull.cs | 23 ++- Subsurface/Source/Sounds/SoundManager.cs | 153 ++++-------------- 4 files changed, 77 insertions(+), 132 deletions(-) diff --git a/Subsurface/Source/Characters/Animation/Ragdoll.cs b/Subsurface/Source/Characters/Animation/Ragdoll.cs index 75b26d98f..d46ace6d9 100644 --- a/Subsurface/Source/Characters/Animation/Ragdoll.cs +++ b/Subsurface/Source/Characters/Animation/Ragdoll.cs @@ -422,7 +422,11 @@ namespace Barotrauma float volume = stairs == null ? impact / 5.0f : impact; volume = Math.Min(impact, 1.0f); - if (impact > 0.8f && l.HitSound != null && l.soundTimer <= 0.0f) l.HitSound.Play(volume, impact * 100.0f, l.WorldPosition); + if (impact > 0.5f && l.HitSound != null && l.soundTimer <= 0.0f) + { + l.soundTimer = Limb.SoundInterval; + l.HitSound.Play(volume, impact * 250.0f, l.WorldPosition); + } if (impact > l.impactTolerance) { diff --git a/Subsurface/Source/GUI/GUI.cs b/Subsurface/Source/GUI/GUI.cs index 5ec7a82d4..d2392e6e7 100644 --- a/Subsurface/Source/GUI/GUI.cs +++ b/Subsurface/Source/GUI/GUI.cs @@ -449,6 +449,33 @@ namespace Barotrauma "Sub pos: " + Submarine.MainSub.Position.ToPoint(), new Vector2(10, 50), Color.White); } + + for (int i = 1; i < Sounds.SoundManager.DefaultSourceCount; i++) + { + Color clr = Color.White; + + string soundStr = i+": "; + + var playingSound = Sounds.SoundManager.GetPlayingSound(i); + + if (playingSound == null) + { + soundStr+= "none"; + clr *= 0.5f; + } + else + { + soundStr += System.IO.Path.GetFileNameWithoutExtension(playingSound.FilePath); + + if (Sounds.SoundManager.IsLooping(i)) + { + soundStr += " (looping)"; + clr = Color.Yellow; + } + } + + GUI.DrawString(spriteBatch, new Vector2(200, i * 15), soundStr, clr, Color.Black * 0.5f, 0, GUI.SmallFont); + } } if (GameMain.NetworkMember != null) GameMain.NetworkMember.Draw(spriteBatch); diff --git a/Subsurface/Source/Map/Hull.cs b/Subsurface/Source/Map/Hull.cs index ff306401f..83693d7da 100644 --- a/Subsurface/Source/Map/Hull.cs +++ b/Subsurface/Source/Map/Hull.cs @@ -102,6 +102,7 @@ namespace Barotrauma } surface = rect.Y - rect.Height + Volume / rect.Width; + Pressure = surface; } } @@ -259,7 +260,7 @@ namespace Barotrauma return rect; } - + public static EntityGrid GenerateEntityGrid(Submarine submarine) { var newGrid = new EntityGrid(submarine, 200.0f); @@ -318,6 +319,9 @@ namespace Barotrauma Item.UpdateHulls(); Gap.UpdateHulls(); } + + surface = rect.Y - rect.Height + Volume / rect.Width; + Pressure = surface; } public override void Remove() @@ -404,6 +408,12 @@ namespace Barotrauma float strongestFlow = 0.0f; foreach (Gap gap in ConnectedGaps) { + if (gap.IsRoomToRoom) + { + //only the first linked hull plays the flow sound + if (gap.linkedTo[1] == this) continue; + } + float gapFlow = gap.LerpedFlowForce.Length(); if (gapFlow > strongestFlow) @@ -411,9 +421,8 @@ namespace Barotrauma strongestFlow = gapFlow; } } - - - if (strongestFlow>0.1f) + + if (strongestFlow > 1.0f) { soundVolume = soundVolume + ((strongestFlow < 100.0f) ? -deltaTime * 0.5f : deltaTime * 0.5f); soundVolume = MathHelper.Clamp(soundVolume, 0.0f, 1.0f); @@ -430,8 +439,7 @@ namespace Barotrauma } currentFlowSound = flowSound; - - soundIndex = currentFlowSound.Loop(soundIndex, soundVolume, WorldPosition, 2000.0f); + soundIndex = currentFlowSound.Loop(soundIndex, soundVolume, WorldPosition, Math.Min(strongestFlow*5.0f, 2000.0f)); } else { @@ -515,10 +523,13 @@ namespace Barotrauma LethalPressure -= 10.0f * deltaTime; if (Volume == 0.0f) { + //wait for the surface to be lerped back to bottom and the waves to settle until disabling update + if (surface > rect.Y - rect.Height + 1) return; for (int i = 1; i < waveY.Length - 1; i++) { if (waveY[i] > 0.1f) return; } + update = false; } } diff --git a/Subsurface/Source/Sounds/SoundManager.cs b/Subsurface/Source/Sounds/SoundManager.cs index 80a073bc9..3c28bc280 100644 --- a/Subsurface/Source/Sounds/SoundManager.cs +++ b/Subsurface/Source/Sounds/SoundManager.cs @@ -14,6 +14,8 @@ namespace Barotrauma.Sounds private static readonly List alSources = new List(); private static readonly int[] alBuffers = new int[DefaultSourceCount]; private static int lowpassFilterId; + + private static readonly Sound[] soundsPlaying = new Sound[DefaultSourceCount]; private static AudioContext AC; @@ -47,112 +49,33 @@ namespace Barotrauma.Sounds LowPassHFGain = 1.0f; } - - } - - //public SoundManager(int bufferCount = DefaultSourceCount) - //{ - // Stopwatch sw = new Stopwatch(); - // sw.Start(); - - // alSourceId = AL.GenSource(); - // //AL.Source(alSourceId, ALSourcei.Buffer, alBufferId); - - // Volume = 1; - - // if (ALHelper.Efx.IsInitialized) - // { - // alFilterId = ALHelper.Efx.GenFilter(); - // ALHelper.Efx.Filter(alFilterId, EfxFilteri.FilterType, (int)EfxFilterType.Lowpass); - // ALHelper.Efx.Filter(alFilterId, EfxFilterf.LowpassGain, 1); - // LowPassHFGain = 1; - // } - - // sw.Stop(); - // System.Diagnostics.Debug.WriteLine("oggsource: "+sw.ElapsedMilliseconds); - - //} - - // public static int Play(Sound sound, float volume = 1.0f) - // { - // return Play(sound, volume, new Vector2(0.0f, 0.0f)); - //} public static int Play(Sound sound, float volume = 1.0f) { return Play(sound, Vector2.Zero, volume, 0.0f); - //for (int i = 2; i < DefaultSourceCount; i++) - //{ - // AL.SourceStop(alSources[i]); - // AL.Source(alSources[i], ALSourceb.Looping, false); - // System.Diagnostics.Debug.WriteLine(i + ": " + AL.GetSourceState(alSources[i])); - // System.Diagnostics.Debug.WriteLine(AL.GetSourceType(alSources[i])); - //} - - //for (int i = 1; i < DefaultSourceCount; i++) - //{ - // //find a source that's free to use (not playing or paused) - // if (AL.GetSourceState(alSources[i]) == ALSourceState.Playing - // || AL.GetSourceState(alSources[i]) == ALSourceState.Paused) continue; - - // //if (position!=Vector2.Zero) - // // position /= 1000.0f; - - // alBuffers[i]=sound.AlBufferId; - // AL.Source(alSources[i], ALSourceb.Looping, false); - // AL.Source(alSources[i], ALSource3f.Position, 0.0f, 0.0f, 0.0f); - // AL.Source(alSources[i], ALSourcei.Buffer, sound.AlBufferId); - // AL.Source(alSources[i], ALSourcef.Gain, volume); - // //AL.Source(alSources[i], ALSource3f.Position, position.X, position.Y, 0.0f); - // AL.SourcePlay(alSources[i]); - - // //sound.sourceIndex = i; - - // return i; - //} - - //return -1; } public static int Play(Sound sound, Vector2 position, float volume = 1.0f, float lowPassGain = 0.0f, bool loop=false) { - //for (int i = 2; i < DefaultSourceCount; i++) - //{ - // AL.SourceStop(alSources[i]); - // AL.Source(alSources[i], ALSourceb.Looping, false); - // System.Diagnostics.Debug.WriteLine(i + ": " + AL.GetSourceState(alSources[i])); - // System.Diagnostics.Debug.WriteLine(AL.GetSourceType(alSources[i])); - //} - - - for (int i = 1; i < DefaultSourceCount; i++) { //find a source that's free to use (not playing or paused) if (OpenTK.Audio.OpenAL.AL.GetSourceState(alSources[i]) == OpenTK.Audio.OpenAL.ALSourceState.Playing || OpenTK.Audio.OpenAL.AL.GetSourceState(alSources[i]) == OpenTK.Audio.OpenAL.ALSourceState.Paused) continue; - //if (position!=Vector2.Zero) - // position /= 1000.0f; + soundsPlaying[i] = sound; alBuffers[i] = sound.AlBufferId; OpenTK.Audio.OpenAL.AL.Source(alSources[i], OpenTK.Audio.OpenAL.ALSourceb.Looping, loop); OpenTK.Audio.OpenAL.AL.Source(alSources[i], OpenTK.Audio.OpenAL.ALSourcei.Buffer, sound.AlBufferId); - - + UpdateSoundPosition(i, position, volume); - //AL.Source(alSources[i], ALSource3f.Position, position.X, position.Y, 0.0f); OpenTK.Audio.OpenAL.AL.SourcePlay(alSources[i]); - - - - //sound.sourceIndex = i; - return i; } @@ -174,44 +97,17 @@ namespace Barotrauma.Sounds if (sourceIndex<1) { sourceIndex = Play(sound, position, volume, 0.0f, true); - //if (sourceIndex>0) - //{ - // AL.Source(alSources[sourceIndex], ALSourceb.Looping, true); - // AL.Source(alSources[sourceIndex], ALSourcef.Gain, volume); - //} } else { UpdateSoundPosition(sourceIndex, position, volume); - - //position /= 1000.0f; - - //OpenTK.Audio.OpenAL.AL.Source(alSources[sourceIndex], OpenTK.Audio.OpenAL.ALSource3f.Position, position.X, position.Y, 0.0f); AL.Source(alSources[sourceIndex], ALSourceb.Looping, true); - //AL.Source(alSources[sourceIndex], ALSourcef.Gain, volume); - } ALHelper.Check(); return sourceIndex; } - //public static int Loop(int sourceIndex, float volume = 1.0f) - //{ - - // if (sourceIndex > 0 && alSources[sourceIndex]>0) - // { - // ALSourceState state = AL.GetSourceState(alSources[sourceIndex]); - // ALHelper.Check(); - // if (state == ALSourceState.Playing) return sourceIndex; - // } - - // int newSourceIndex = Play(sound, volume); - // AL.Source(alSources[sourceIndex], ALSourceb.Looping, true); - - // return sourceIndex; - //} - public static void Pause(int sourceIndex) { if (AL.GetSourceState(alSources[sourceIndex]) != ALSourceState.Playing) @@ -239,9 +135,21 @@ namespace Barotrauma.Sounds { AL.SourceStop(alSources[sourceIndex]); AL.Source(alSources[sourceIndex], ALSourceb.Looping, false); + + soundsPlaying[sourceIndex] = null; } } + public static Sound GetPlayingSound(int sourceIndex) + { + if (sourceIndex < 1 || sourceIndex>alSources.Count-1) return null; + + if (AL.GetSourceState(alSources[sourceIndex]) != ALSourceState.Playing) return null; + + return soundsPlaying[sourceIndex]; + } + + public static bool IsPlaying(int sourceIndex) { if (sourceIndex < 1 || sourceIndex>alSources.Count-1) return false; @@ -249,14 +157,23 @@ namespace Barotrauma.Sounds return (state == ALSourceState.Playing); } + public static bool IsLooping(int sourceIndex) + { + if (sourceIndex < 1 || sourceIndex > alSources.Count - 1) return false; + + bool isLooping; + + OpenTK.Audio.OpenAL.AL.GetSource(alSources[sourceIndex], OpenTK.Audio.OpenAL.ALSourceb.Looping, out isLooping); + + return isLooping; + } + public static void Volume(int sourceIndex, float volume) { AL.Source(alSources[sourceIndex], ALSourcef.Gain, volume * MasterVolume); ALHelper.Check(); } - //int alFilterId; - static float lowPassHfGain; public static float LowPassHFGain { @@ -281,16 +198,6 @@ namespace Barotrauma.Sounds } } - //float volume; - //public float Volume - //{ - // get { return volume; } - // set - // { - // AL.Source(alSourceId, ALSourcef.Gain, volume = value); - // ALHelper.Check(); - // } - //} public static void UpdateSoundPosition(int sourceIndex, Vector2 position, float baseVolume = 1.0f) { @@ -301,9 +208,7 @@ namespace Barotrauma.Sounds position = Vector2.Zero; } - //Resume(sourceIndex); - - position/= 1000.0f; + position /= 1000.0f; OpenTK.Audio.OpenAL.AL.Source(alSources[sourceIndex], OpenTK.Audio.OpenAL.ALSourcef.Gain, baseVolume * MasterVolume); OpenTK.Audio.OpenAL.AL.Source(alSources[sourceIndex], OpenTK.Audio.OpenAL.ALSource3f.Position, position.X, position.Y, 0.0f); @@ -313,8 +218,6 @@ namespace Barotrauma.Sounds ALHelper.Efx.Filter(lowpassFilterId, OpenTK.Audio.OpenAL.EfxFilterf.LowpassGainHF, lowPassGain); ALHelper.Efx.BindFilterToSource(alSources[sourceIndex], lowpassFilterId); ALHelper.Check(); - - } public static OggStream StartStream(string file, float volume = 1.0f)