Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaClient/Source/Sounds/Sound.cs
T
2019-03-18 20:39:27 +02:00

158 lines
4.2 KiB
C#

using System;
using OpenTK.Audio.OpenAL;
using Microsoft.Xna.Framework;
using System.IO;
namespace Barotrauma.Sounds
{
public abstract class Sound : IDisposable
{
public SoundManager Owner
{
get;
protected set;
}
public string Filename
{
get;
protected set;
}
public bool Stream
{
get;
protected set;
}
private uint alBuffer;
public uint ALBuffer
{
get { return !Stream ? alBuffer : 0; }
}
private uint alMuffledBuffer;
public uint ALMuffledBuffer
{
get { return !Stream ? alMuffledBuffer : 0; }
}
public ALFormat ALFormat
{
get;
protected set;
}
public int SampleRate
{
get;
protected set;
}
public float BaseGain;
public float BaseNear;
public float BaseFar;
public Sound(SoundManager owner,string filename,bool stream)
{
Owner = owner;
Filename = Path.GetFullPath(filename);
Stream = stream;
BaseGain = 1.0f;
BaseNear = 100.0f;
BaseFar = 200.0f;
if (!stream)
{
AL.GenBuffer(out alBuffer);
ALError alError = AL.GetError();
if (alError != ALError.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 != ALError.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!");
}
}
else
{
alBuffer = 0;
}
}
public override string ToString()
{
return GetType().ToString() + " (" + Filename + ")";
}
public bool IsPlaying()
{
return Owner.IsPlaying(this);
}
public SoundChannel Play(float gain, float range, Vector2 position, bool muffle = false)
{
return new SoundChannel(this, gain, new Vector3(position.X, position.Y, 0.0f), range * 0.4f, range, "default", muffle);
}
public SoundChannel Play(Vector3? position, float gain, bool muffle = false)
{
return new SoundChannel(this, gain, position, BaseNear, BaseFar, "default", muffle);
}
public SoundChannel Play(float gain)
{
return Play(null, gain);
}
public SoundChannel Play()
{
return Play(BaseGain);
}
public SoundChannel Play(float? gain, string category)
{
return new SoundChannel(this, gain ?? BaseGain, null, BaseNear, BaseFar, category);
}
public abstract int FillStreamBuffer(int samplePos, short[] buffer);
public virtual void Dispose()
{
Owner.KillChannels(this);
if (alBuffer != 0)
{
if (!AL.IsBuffer(alBuffer))
{
throw new Exception("Buffer to delete is invalid!");
}
AL.DeleteBuffer(ref alBuffer); alBuffer = 0;
ALError alError = AL.GetError();
if (alError != ALError.NoError)
{
throw new Exception("Failed to delete OpenAL buffer for non-streamed sound: " + AL.GetErrorString(alError));
}
}
Owner.RemoveSound(this);
}
}
}