v0.13.0.11
This commit is contained in:
@@ -30,6 +30,7 @@ namespace Barotrauma.Sounds
|
||||
public override int FillStreamBuffer(int samplePos, short[] buffer)
|
||||
{
|
||||
if (!Stream) throw new Exception("Called FillStreamBuffer on a non-streamed sound!");
|
||||
if (reader == null) throw new Exception("Called FillStreamBuffer when the reader is null!");
|
||||
|
||||
if (samplePos >= reader.TotalSamples * reader.Channels * 2) return 0;
|
||||
|
||||
@@ -41,7 +42,7 @@ namespace Barotrauma.Sounds
|
||||
//MuffleBuffer(floatBuffer, reader.Channels);
|
||||
CastBuffer(floatBuffer, buffer, readSamples);
|
||||
|
||||
return readSamples * 2;
|
||||
return readSamples;
|
||||
}
|
||||
|
||||
static void MuffleBuffer(float[] buffer, int sampleRate, int channelCount)
|
||||
@@ -63,8 +64,20 @@ namespace Barotrauma.Sounds
|
||||
ALFormat = reader.Channels == 1 ? Al.FormatMono16 : Al.FormatStereo16;
|
||||
SampleRate = reader.SampleRate;
|
||||
|
||||
if (Buffers != null && SoundBuffers.BuffersGenerated < SoundBuffers.MaxBuffers)
|
||||
{
|
||||
Buffers.RequestAlBuffers(); FillBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
public override void FillBuffers()
|
||||
{
|
||||
if (!Stream)
|
||||
{
|
||||
reader ??= new VorbisReader(Filename);
|
||||
|
||||
reader.DecodedPosition = 0;
|
||||
|
||||
int bufferSize = (int)reader.TotalSamples * reader.Channels;
|
||||
|
||||
float[] floatBuffer = new float[bufferSize];
|
||||
@@ -86,26 +99,26 @@ namespace Barotrauma.Sounds
|
||||
|
||||
CastBuffer(floatBuffer, shortBuffer, readSamples);
|
||||
|
||||
Al.BufferData(ALBuffer, ALFormat, shortBuffer,
|
||||
Al.BufferData(Buffers.AlBuffer, ALFormat, shortBuffer,
|
||||
readSamples * sizeof(short), SampleRate);
|
||||
|
||||
int alError = Al.GetError();
|
||||
if (alError != Al.NoError)
|
||||
{
|
||||
throw new Exception("Failed to set buffer data for non-streamed audio! " + Al.GetErrorString(alError));
|
||||
throw new Exception("Failed to set regular buffer data for non-streamed audio! " + Al.GetErrorString(alError));
|
||||
}
|
||||
|
||||
MuffleBuffer(floatBuffer, SampleRate, reader.Channels);
|
||||
|
||||
CastBuffer(floatBuffer, shortBuffer, readSamples);
|
||||
|
||||
Al.BufferData(ALMuffledBuffer, ALFormat, shortBuffer,
|
||||
Al.BufferData(Buffers.AlMuffledBuffer, ALFormat, shortBuffer,
|
||||
readSamples * sizeof(short), SampleRate);
|
||||
|
||||
alError = Al.GetError();
|
||||
if (alError != Al.NoError)
|
||||
{
|
||||
throw new Exception("Failed to set buffer data for non-streamed audio! " + Al.GetErrorString(alError));
|
||||
throw new Exception("Failed to set muffled buffer data for non-streamed audio! " + Al.GetErrorString(alError));
|
||||
}
|
||||
|
||||
reader.Dispose(); reader = null;
|
||||
@@ -116,7 +129,7 @@ namespace Barotrauma.Sounds
|
||||
{
|
||||
if (Stream)
|
||||
{
|
||||
reader.Dispose();
|
||||
reader?.Dispose();
|
||||
}
|
||||
|
||||
base.Dispose();
|
||||
|
||||
@@ -14,35 +14,15 @@ namespace Barotrauma.Sounds
|
||||
get { return disposed; }
|
||||
}
|
||||
|
||||
public SoundManager Owner
|
||||
{
|
||||
get;
|
||||
protected set;
|
||||
}
|
||||
public readonly SoundManager Owner;
|
||||
|
||||
public string Filename
|
||||
{
|
||||
get;
|
||||
protected set;
|
||||
}
|
||||
public readonly string Filename;
|
||||
|
||||
public XElement XElement
|
||||
{
|
||||
get;
|
||||
protected set;
|
||||
}
|
||||
public readonly XElement XElement;
|
||||
|
||||
public bool Stream
|
||||
{
|
||||
get;
|
||||
protected set;
|
||||
}
|
||||
public readonly bool Stream;
|
||||
|
||||
public bool StreamsReliably
|
||||
{
|
||||
get;
|
||||
protected set;
|
||||
}
|
||||
public readonly bool StreamsReliably;
|
||||
|
||||
public virtual SoundManager.SourcePoolIndex SourcePoolIndex
|
||||
{
|
||||
@@ -52,16 +32,10 @@ namespace Barotrauma.Sounds
|
||||
}
|
||||
}
|
||||
|
||||
private uint alBuffer;
|
||||
public uint ALBuffer
|
||||
private SoundBuffers buffers;
|
||||
public SoundBuffers Buffers
|
||||
{
|
||||
get { return !Stream ? alBuffer : 0; }
|
||||
}
|
||||
|
||||
private uint alMuffledBuffer;
|
||||
public uint ALMuffledBuffer
|
||||
{
|
||||
get { return !Stream ? alMuffledBuffer : 0; }
|
||||
get { return !Stream ? buffers : null; }
|
||||
}
|
||||
|
||||
public int ALFormat
|
||||
@@ -85,10 +59,10 @@ namespace Barotrauma.Sounds
|
||||
public float BaseNear;
|
||||
public float BaseFar;
|
||||
|
||||
public Sound(SoundManager owner, string filename, bool stream, bool streamsReliably, XElement xElement=null)
|
||||
public Sound(SoundManager owner, string filename, bool stream, bool streamsReliably, XElement xElement=null, bool getFullPath=true)
|
||||
{
|
||||
Owner = owner;
|
||||
Filename = Path.GetFullPath(filename.CleanUpPath()).CleanUpPath();
|
||||
Filename = getFullPath ? Path.GetFullPath(filename.CleanUpPath()).CleanUpPath() : filename;
|
||||
Stream = stream;
|
||||
StreamsReliably = streamsReliably;
|
||||
XElement = xElement;
|
||||
@@ -169,69 +143,20 @@ namespace Barotrauma.Sounds
|
||||
{
|
||||
if (!Stream)
|
||||
{
|
||||
Al.GenBuffer(out alBuffer);
|
||||
int alError = Al.GetError();
|
||||
if (alError != Al.NoError)
|
||||
{
|
||||
throw new Exception("Failed to create OpenAL buffer for non-streamed sound: " + Al.GetErrorString(alError));
|
||||
}
|
||||
|
||||
if (!Al.IsBuffer(alBuffer))
|
||||
{
|
||||
throw new Exception("Generated OpenAL buffer is invalid!");
|
||||
}
|
||||
|
||||
Al.GenBuffer(out alMuffledBuffer);
|
||||
alError = Al.GetError();
|
||||
if (alError != Al.NoError)
|
||||
{
|
||||
throw new Exception("Failed to create OpenAL buffer for non-streamed sound: " + Al.GetErrorString(alError));
|
||||
}
|
||||
|
||||
if (!Al.IsBuffer(alMuffledBuffer))
|
||||
{
|
||||
throw new Exception("Generated OpenAL buffer is invalid!");
|
||||
}
|
||||
buffers = new SoundBuffers(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
alBuffer = 0;
|
||||
buffers = null;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void FillBuffers() { }
|
||||
|
||||
public virtual void DeleteALBuffers()
|
||||
{
|
||||
Owner.KillChannels(this);
|
||||
if (alBuffer != 0)
|
||||
{
|
||||
if (!Al.IsBuffer(alBuffer))
|
||||
{
|
||||
throw new Exception("Buffer to delete is invalid!");
|
||||
}
|
||||
|
||||
Al.DeleteBuffer(alBuffer); alBuffer = 0;
|
||||
|
||||
int alError = Al.GetError();
|
||||
if (alError != Al.NoError)
|
||||
{
|
||||
throw new Exception("Failed to delete OpenAL buffer for non-streamed sound: " + Al.GetErrorString(alError));
|
||||
}
|
||||
}
|
||||
if (alMuffledBuffer != 0)
|
||||
{
|
||||
if (!Al.IsBuffer(alMuffledBuffer))
|
||||
{
|
||||
throw new Exception("Buffer to delete is invalid!");
|
||||
}
|
||||
|
||||
Al.DeleteBuffer(alMuffledBuffer); alMuffledBuffer = 0;
|
||||
|
||||
int alError = Al.GetError();
|
||||
if (alError != Al.NoError)
|
||||
{
|
||||
throw new Exception("Failed to delete OpenAL buffer for non-streamed sound: " + Al.GetErrorString(alError));
|
||||
}
|
||||
}
|
||||
buffers?.Dispose();
|
||||
}
|
||||
|
||||
public virtual void Dispose()
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
using Barotrauma.Extensions;
|
||||
using OpenAL;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Barotrauma.Sounds
|
||||
{
|
||||
public class SoundBuffers : IDisposable
|
||||
{
|
||||
private static HashSet<uint> bufferPool = new HashSet<uint>();
|
||||
#if OSX
|
||||
public const int MaxBuffers = 400; //TODO: check that this value works for macOS
|
||||
#else
|
||||
public const int MaxBuffers = 32000;
|
||||
#endif
|
||||
public static int BuffersGenerated { get; private set; } = 0;
|
||||
private Sound sound;
|
||||
|
||||
public uint AlBuffer { get; private set; } = 0;
|
||||
public uint AlMuffledBuffer { get; private set; } = 0;
|
||||
|
||||
public SoundBuffers(Sound sound) { this.sound = sound; }
|
||||
public void Dispose()
|
||||
{
|
||||
if (AlBuffer != 0) { bufferPool.Add(AlBuffer); }
|
||||
if (AlMuffledBuffer != 0) { bufferPool.Add(AlMuffledBuffer); }
|
||||
AlBuffer = 0;
|
||||
AlMuffledBuffer = 0;
|
||||
}
|
||||
|
||||
public static void ClearPool()
|
||||
{
|
||||
bufferPool.ForEach(b => Al.DeleteBuffer(b));
|
||||
bufferPool.Clear();
|
||||
BuffersGenerated = 0;
|
||||
}
|
||||
|
||||
public bool RequestAlBuffers()
|
||||
{
|
||||
if (AlBuffer != 0) { return false; }
|
||||
int alError = 0;
|
||||
while (bufferPool.Count < 2 && BuffersGenerated < MaxBuffers)
|
||||
{
|
||||
Al.GenBuffer(out uint newBuffer);
|
||||
alError = Al.GetError();
|
||||
if (alError != Al.NoError)
|
||||
{
|
||||
DebugConsole.AddWarning($"Error when generating sound buffer: {Al.GetErrorString(alError)}. {BuffersGenerated} buffer(s) were generated. No more sound buffers will be generated.");
|
||||
BuffersGenerated = MaxBuffers;
|
||||
}
|
||||
else if (!Al.IsBuffer(newBuffer))
|
||||
{
|
||||
DebugConsole.AddWarning($"Error when generating sound buffer: result is not a valid buffer. {BuffersGenerated} buffer(s) were generated. No more sound buffers will be generated.");
|
||||
BuffersGenerated = MaxBuffers;
|
||||
}
|
||||
else
|
||||
{
|
||||
bufferPool.Add(newBuffer);
|
||||
BuffersGenerated++;
|
||||
if (BuffersGenerated >= MaxBuffers)
|
||||
{
|
||||
DebugConsole.AddWarning($"{BuffersGenerated} buffer(s) were generated. No more sound buffers will be generated.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bufferPool.Count >= 2)
|
||||
{
|
||||
AlBuffer = bufferPool.First();
|
||||
bufferPool.Remove(AlBuffer);
|
||||
AlMuffledBuffer = bufferPool.First();
|
||||
bufferPool.Remove(AlMuffledBuffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
//can't generate any more OpenAL buffers! we'll have to steal a buffer from someone...
|
||||
foreach (var otherSound in sound.Owner.LoadedSounds)
|
||||
{
|
||||
if (otherSound == sound) { continue; }
|
||||
if (otherSound.IsPlaying()) { continue; }
|
||||
if (otherSound.Buffers == null) { continue; }
|
||||
if (otherSound.Buffers.AlBuffer == 0) { continue; }
|
||||
|
||||
// Dispose all channels that are holding
|
||||
// a reference to these buffers, otherwise
|
||||
// an INVALID_OPERATION error will be thrown
|
||||
// when attempting to set the buffer data later.
|
||||
// Having the sources not play is not enough,
|
||||
// as OpenAL assumes that you may want to call
|
||||
// alSourcePlay without reassigning the buffer.
|
||||
otherSound.Owner.KillChannels(otherSound);
|
||||
|
||||
AlBuffer = otherSound.Buffers.AlBuffer;
|
||||
AlMuffledBuffer = otherSound.Buffers.AlMuffledBuffer;
|
||||
otherSound.Buffers.AlBuffer = 0;
|
||||
otherSound.Buffers.AlMuffledBuffer = 0;
|
||||
|
||||
// For performance reasons, sift the current sound to
|
||||
// the end of the loadedSounds list, that way it'll
|
||||
// be less likely to have its buffers stolen, which
|
||||
// means less reuploads for frequently played sounds.
|
||||
sound.Owner.MoveSoundToPosition(sound, sound.Owner.LoadedSoundCount-1);
|
||||
|
||||
if (!Al.IsBuffer(AlBuffer))
|
||||
{
|
||||
throw new Exception(sound.Filename + " has an invalid buffer!");
|
||||
}
|
||||
if (!Al.IsBuffer(AlMuffledBuffer))
|
||||
{
|
||||
throw new Exception(sound.Filename + " has an invalid muffled buffer!");
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -334,7 +334,11 @@ namespace Barotrauma.Sounds
|
||||
return;
|
||||
}
|
||||
|
||||
Al.Sourcei(alSource, Al.Buffer, muffled ? (int)Sound.ALMuffledBuffer : (int)Sound.ALBuffer);
|
||||
if (Sound.Buffers.RequestAlBuffers())
|
||||
{
|
||||
Sound.FillBuffers();
|
||||
}
|
||||
Al.Sourcei(alSource, Al.Buffer, muffled ? (int)Sound.Buffers.AlMuffledBuffer : (int)Sound.Buffers.AlBuffer);
|
||||
|
||||
alError = Al.GetError();
|
||||
if (alError != Al.NoError)
|
||||
@@ -487,8 +491,10 @@ namespace Barotrauma.Sounds
|
||||
mutex = new object();
|
||||
}
|
||||
|
||||
#if !DEBUG
|
||||
try
|
||||
{
|
||||
#endif
|
||||
if (mutex != null) { Monitor.Enter(mutex); }
|
||||
if (sound.Owner.CountPlayingInstances(sound) < sound.MaxSimultaneousInstances)
|
||||
{
|
||||
@@ -506,17 +512,17 @@ namespace Barotrauma.Sounds
|
||||
throw new Exception("Failed to reset source buffer: " + debugName + ", " + Al.GetErrorString(alError));
|
||||
}
|
||||
|
||||
if (!Al.IsBuffer(sound.ALBuffer))
|
||||
if (Sound.Buffers.RequestAlBuffers())
|
||||
{
|
||||
throw new Exception(sound.Filename + " has an invalid buffer!");
|
||||
Sound.FillBuffers();
|
||||
}
|
||||
|
||||
uint alBuffer = sound.Owner.GetCategoryMuffle(category) || muffle ? sound.ALMuffledBuffer : sound.ALBuffer;
|
||||
uint alBuffer = sound.Owner.GetCategoryMuffle(category) || muffled ? Sound.Buffers.AlMuffledBuffer : Sound.Buffers.AlBuffer;
|
||||
Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Buffer, (int)alBuffer);
|
||||
alError = Al.GetError();
|
||||
if (alError != Al.NoError)
|
||||
{
|
||||
throw new Exception("Failed to bind buffer to source (" + ALSourceIndex.ToString() + ":" + sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex) + "," + sound.ALBuffer.ToString() + "): " + debugName + ", " + Al.GetErrorString(alError));
|
||||
throw new Exception("Failed to bind buffer to source (" + ALSourceIndex.ToString() + ":" + sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex) + "," + alBuffer.ToString() + "): " + debugName + ", " + Al.GetErrorString(alError));
|
||||
}
|
||||
|
||||
Al.SourcePlay(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex));
|
||||
@@ -528,7 +534,7 @@ namespace Barotrauma.Sounds
|
||||
}
|
||||
else
|
||||
{
|
||||
uint alBuffer = sound.Owner.GetCategoryMuffle(category) || muffle ? sound.ALMuffledBuffer : sound.ALBuffer;
|
||||
uint alBuffer = 0;
|
||||
Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Buffer, (int)alBuffer);
|
||||
int alError = Al.GetError();
|
||||
if (alError != Al.NoError)
|
||||
@@ -574,6 +580,7 @@ namespace Barotrauma.Sounds
|
||||
this.Near = near;
|
||||
this.Far = far;
|
||||
this.Category = category;
|
||||
#if !DEBUG
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -581,8 +588,11 @@ namespace Barotrauma.Sounds
|
||||
}
|
||||
finally
|
||||
{
|
||||
#endif
|
||||
if (mutex != null) { Monitor.Exit(mutex); }
|
||||
#if !DEBUG
|
||||
}
|
||||
#endif
|
||||
|
||||
Sound.Owner.Update();
|
||||
}
|
||||
@@ -736,11 +746,6 @@ namespace Barotrauma.Sounds
|
||||
|
||||
if (FilledByNetwork)
|
||||
{
|
||||
if (Sound is VoipSound voipSound)
|
||||
{
|
||||
voipSound.ApplyFilters(buffer, readSamples);
|
||||
}
|
||||
|
||||
if (readSamples <= 0)
|
||||
{
|
||||
streamAmplitude *= 0.5f;
|
||||
@@ -752,13 +757,18 @@ namespace Barotrauma.Sounds
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Sound is VoipSound voipSound)
|
||||
{
|
||||
voipSound.ApplyFilters(buffer, readSamples);
|
||||
}
|
||||
|
||||
decayTimer = 0;
|
||||
}
|
||||
}
|
||||
else if (Sound.StreamsReliably)
|
||||
{
|
||||
streamSeekPos += readSamples;
|
||||
if (readSamples < STREAM_BUFFER_SIZE)
|
||||
streamSeekPos += readSamples * 2;
|
||||
if (readSamples * 2 < STREAM_BUFFER_SIZE)
|
||||
{
|
||||
if (looping)
|
||||
{
|
||||
@@ -775,7 +785,7 @@ namespace Barotrauma.Sounds
|
||||
{
|
||||
streamBufferAmplitudes[index] = readAmplitude;
|
||||
|
||||
Al.BufferData<short>(streamBuffers[index], Sound.ALFormat, buffer, readSamples, Sound.SampleRate);
|
||||
Al.BufferData<short>(streamBuffers[index], Sound.ALFormat, buffer, readSamples * 2, Sound.SampleRate);
|
||||
|
||||
alError = Al.GetError();
|
||||
if (alError != Al.NoError)
|
||||
|
||||
@@ -30,6 +30,8 @@ namespace Barotrauma.Sounds
|
||||
private readonly SoundSourcePool[] sourcePools;
|
||||
|
||||
private readonly List<Sound> loadedSounds;
|
||||
public IReadOnlyList<Sound> LoadedSounds => loadedSounds;
|
||||
|
||||
private readonly SoundChannel[][] playingChannels = new SoundChannel[2][];
|
||||
private readonly object threadDeathMutex = new object();
|
||||
|
||||
@@ -512,6 +514,18 @@ namespace Barotrauma.Sounds
|
||||
}
|
||||
}
|
||||
|
||||
public void MoveSoundToPosition(Sound sound, int pos)
|
||||
{
|
||||
lock (loadedSounds)
|
||||
{
|
||||
int index = loadedSounds.IndexOf(sound);
|
||||
if (index >= 0)
|
||||
{
|
||||
loadedSounds.SiftElement(index, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetCategoryGainMultiplier(string category, float gain, int index=0)
|
||||
{
|
||||
if (Disabled) { return; }
|
||||
@@ -706,9 +720,11 @@ namespace Barotrauma.Sounds
|
||||
}
|
||||
|
||||
bool areStreamsPlaying = false;
|
||||
ManualResetEvent streamMre = null;
|
||||
|
||||
void UpdateStreaming()
|
||||
{
|
||||
streamMre = new ManualResetEvent(false);
|
||||
bool killThread = false;
|
||||
while (!killThread)
|
||||
{
|
||||
@@ -745,14 +761,20 @@ namespace Barotrauma.Sounds
|
||||
}
|
||||
}
|
||||
}
|
||||
streamMre.WaitOne(10);
|
||||
streamMre.Reset();
|
||||
lock (threadDeathMutex)
|
||||
{
|
||||
areStreamsPlaying = !killThread;
|
||||
}
|
||||
Thread.Sleep(10); //TODO: use a separate thread for network audio?
|
||||
}
|
||||
}
|
||||
|
||||
public void ForceStreamUpdate()
|
||||
{
|
||||
streamMre?.Set();
|
||||
}
|
||||
|
||||
private void ReloadSounds()
|
||||
{
|
||||
for (int i = loadedSounds.Count - 1; i >= 0; i--)
|
||||
@@ -788,6 +810,8 @@ namespace Barotrauma.Sounds
|
||||
}
|
||||
sourcePools[(int)SourcePoolIndex.Default]?.Dispose();
|
||||
sourcePools[(int)SourcePoolIndex.Voice]?.Dispose();
|
||||
|
||||
SoundBuffers.ClearPool();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -21,12 +21,14 @@ namespace Barotrauma
|
||||
|
||||
public readonly string requiredTag;
|
||||
|
||||
public DamageSound(Sound sound, Vector2 damageRange, string damageType, string requiredTag = "")
|
||||
public bool ignoreMuffling;
|
||||
|
||||
public DamageSound(Sound sound, Vector2 damageRange, string damageType, bool ignoreMuffling, string requiredTag = "")
|
||||
{
|
||||
this.sound = sound;
|
||||
this.damageRange = damageRange;
|
||||
this.damageType = damageType;
|
||||
|
||||
this.ignoreMuffling = ignoreMuffling;
|
||||
this.requiredTag = requiredTag;
|
||||
}
|
||||
}
|
||||
@@ -195,14 +197,21 @@ namespace Barotrauma
|
||||
{
|
||||
case "music":
|
||||
var newMusicClip = new BackgroundMusic(soundElement);
|
||||
musicClips.AddIfNotNull(newMusicClip);
|
||||
if (loadedSoundElements != null)
|
||||
if (File.Exists(newMusicClip.File))
|
||||
{
|
||||
if (newMusicClip.Type.Equals("menu", StringComparison.OrdinalIgnoreCase))
|
||||
musicClips.AddIfNotNull(newMusicClip);
|
||||
if (loadedSoundElements != null)
|
||||
{
|
||||
targetMusic[0] = newMusicClip;
|
||||
if (newMusicClip.Type.Equals("menu", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
targetMusic[0] = newMusicClip;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.NewMessage($"Music file \"{newMusicClip.File}\" not found.");
|
||||
}
|
||||
break;
|
||||
case "splash":
|
||||
SplashSounds.AddIfNotNull(GameMain.SoundManager.LoadSound(soundElement, false));
|
||||
@@ -262,6 +271,7 @@ namespace Barotrauma
|
||||
damageSound,
|
||||
soundElement.GetAttributeVector2("damagerange", Vector2.Zero),
|
||||
damageSoundType,
|
||||
soundElement.GetAttributeBool("ignoremuffling", false),
|
||||
soundElement.GetAttributeString("requiredtag", "")));
|
||||
|
||||
break;
|
||||
@@ -524,7 +534,7 @@ namespace Barotrauma
|
||||
Vector2 diff = gap.WorldPosition - listenerPos;
|
||||
if (Math.Abs(diff.X) < FlowSoundRange && Math.Abs(diff.Y) < FlowSoundRange)
|
||||
{
|
||||
if (gap.Open < 0.01f) { continue; }
|
||||
if (gap.Open < 0.01f || gap.LerpedFlowForce.LengthSquared() < 100.0f) { continue; }
|
||||
float gapFlow = Math.Abs(gap.LerpedFlowForce.X) + Math.Abs(gap.LerpedFlowForce.Y) * 2.5f;
|
||||
if (!gap.IsRoomToRoom) { gapFlow *= 2.0f; }
|
||||
if (gapFlow < 10.0f) { continue; }
|
||||
@@ -887,7 +897,17 @@ namespace Barotrauma
|
||||
if (currentMusic[i] == null || (musicChannel[i] == null || !musicChannel[i].IsPlaying))
|
||||
{
|
||||
DisposeMusicChannel(i);
|
||||
currentMusic[i] = GameMain.SoundManager.LoadSound(targetMusic[i].File, true);
|
||||
try
|
||||
{
|
||||
currentMusic[i] = GameMain.SoundManager.LoadSound(targetMusic[i].File, true);
|
||||
}
|
||||
catch (System.IO.InvalidDataException e)
|
||||
{
|
||||
DebugConsole.ThrowError($"Failed to load the music clip \"{targetMusic[i].File}\".", e);
|
||||
musicClips.Remove(targetMusic[i]);
|
||||
targetMusic[i] = null;
|
||||
break;
|
||||
}
|
||||
musicChannel[i] = currentMusic[i].Play(0.0f, "music");
|
||||
if (targetMusic[i].ContinueFromPreviousTime)
|
||||
{
|
||||
@@ -983,13 +1003,17 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
Submarine targetSubmarine = Character.Controlled?.Submarine;
|
||||
if ((targetSubmarine != null && targetSubmarine.AtDamageDepth) ||
|
||||
(GameMain.GameScreen != null && Screen.Selected == GameMain.GameScreen && Level.Loaded != null && Level.Loaded.GetRealWorldDepth(GameMain.GameScreen.Cam.Position.Y) > Level.Loaded.RealWorldCrushDepth))
|
||||
if (targetSubmarine != null && targetSubmarine.AtDamageDepth)
|
||||
{
|
||||
return "deep";
|
||||
}
|
||||
if (GameMain.GameScreen != null && Screen.Selected == GameMain.GameScreen && Submarine.MainSub != null &&
|
||||
Level.Loaded != null && Level.Loaded.GetRealWorldDepth(GameMain.GameScreen.Cam.Position.Y) > Submarine.MainSub.RealWorldCrushDepth)
|
||||
{
|
||||
return "deep";
|
||||
}
|
||||
|
||||
if (targetSubmarine != null)
|
||||
if (targetSubmarine != null)
|
||||
{
|
||||
float floodedArea = 0.0f;
|
||||
float totalArea = 0.0f;
|
||||
@@ -1033,7 +1057,7 @@ namespace Barotrauma
|
||||
|
||||
if (GameMain.GameSession != null)
|
||||
{
|
||||
if (Submarine.Loaded != null && Level.Loaded != null && Submarine.MainSub != null && Submarine.MainSub.AtEndPosition)
|
||||
if (Submarine.Loaded != null && Level.Loaded != null && Submarine.MainSub != null && Submarine.MainSub.AtEndExit)
|
||||
{
|
||||
return "levelend";
|
||||
}
|
||||
@@ -1102,7 +1126,11 @@ namespace Barotrauma
|
||||
tempList.Add(s);
|
||||
}
|
||||
}
|
||||
tempList.GetRandom().sound?.Play(1.0f, range, position, muffle: ShouldMuffleSound(Character.Controlled, position, range, null));
|
||||
var damageSound = tempList.GetRandom();
|
||||
if (damageSound.sound != null)
|
||||
{
|
||||
damageSound.sound.Play(1.0f, range, position, muffle: !damageSound.ignoreMuffling && ShouldMuffleSound(Character.Controlled, position, range, null));
|
||||
}
|
||||
}
|
||||
|
||||
public static void PlayUISound(GUISoundType soundType)
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace Barotrauma.Sounds
|
||||
readAmount += buf.Length;
|
||||
}
|
||||
}
|
||||
return readAmount*2;
|
||||
return readAmount;
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Barotrauma.Networking;
|
||||
using Barotrauma.IO;
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using OpenAL;
|
||||
using System;
|
||||
@@ -35,14 +36,15 @@ namespace Barotrauma.Sounds
|
||||
public float Near { get; private set; }
|
||||
public float Far { get; private set; }
|
||||
|
||||
private static BiQuad[] muffleFilters = new BiQuad[]
|
||||
private BiQuad[] muffleFilters = new BiQuad[]
|
||||
{
|
||||
new LowpassFilter(VoipConfig.FREQUENCY, 800)
|
||||
};
|
||||
private static BiQuad[] radioFilters = new BiQuad[]
|
||||
private BiQuad[] radioFilters = new BiQuad[]
|
||||
{
|
||||
new BandpassFilter(VoipConfig.FREQUENCY, 2000)
|
||||
};
|
||||
private const float PostRadioFilterBoost = 1.2f;
|
||||
|
||||
private float gain;
|
||||
public float Gain
|
||||
@@ -61,10 +63,8 @@ namespace Barotrauma.Sounds
|
||||
get { return soundChannel?.CurrentAmplitude ?? 0.0f; }
|
||||
}
|
||||
|
||||
public VoipSound(string name, SoundManager owner, VoipQueue q) : base(owner, "voip", true, true)
|
||||
public VoipSound(string name, SoundManager owner, VoipQueue q) : base(owner, $"VoIP ({name})", true, true, getFullPath: false)
|
||||
{
|
||||
Filename = $"VoIP ({name})";
|
||||
|
||||
VoipConfig.SetupEncoding();
|
||||
|
||||
ALFormat = Al.FormatMono16;
|
||||
@@ -104,7 +104,7 @@ namespace Barotrauma.Sounds
|
||||
|
||||
if (gain * GameMain.Config.VoiceChatVolume > 1.0f) //TODO: take distance into account?
|
||||
{
|
||||
fVal = Math.Clamp(fVal * gain * GameMain.Config.VoiceChatVolume, -1.0f, 1.0f);
|
||||
fVal = Math.Clamp(fVal * gain * GameMain.Config.VoiceChatVolume, -1f, 1f);
|
||||
}
|
||||
|
||||
if (UseMuffleFilter)
|
||||
@@ -118,7 +118,7 @@ namespace Barotrauma.Sounds
|
||||
{
|
||||
foreach (var filter in radioFilters)
|
||||
{
|
||||
fVal = filter.Process(fVal);
|
||||
fVal = Math.Clamp(filter.Process(fVal) * PostRadioFilterBoost, -1f, 1f);
|
||||
}
|
||||
}
|
||||
buffer[i] = FloatToShort(fVal);
|
||||
@@ -154,7 +154,7 @@ namespace Barotrauma.Sounds
|
||||
{
|
||||
VoipConfig.Decoder.Decode(compressedBuffer, 0, compressedSize, buffer, 0, VoipConfig.BUFFER_SIZE);
|
||||
bufferID++;
|
||||
return VoipConfig.BUFFER_SIZE * 2;
|
||||
return VoipConfig.BUFFER_SIZE;
|
||||
}
|
||||
if (bufferID < queue.LatestBufferID - (VoipQueue.BUFFER_COUNT - 1)) bufferID = queue.LatestBufferID - (VoipQueue.BUFFER_COUNT - 1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user