Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaClient/Source/Sounds/OggSound.cs
T
Joonas Rikkonen 63eb4d64e5 f8b0295...0671290
2019-03-18 23:30:58 +02:00

101 lines
3.4 KiB
C#

using System;
using OpenTK.Audio.OpenAL;
using NVorbis;
using System.Collections.Generic;
namespace Barotrauma.Sounds
{
public class OggSound : Sound
{
private VorbisReader reader;
//key = sample rate, value = filter
private static Dictionary<int, BiQuad> muffleFilters = new Dictionary<int, BiQuad>();
public OggSound(SoundManager owner, string filename, bool stream) : base(owner, filename, stream, true)
{
if (!ToolBox.IsProperFilenameCase(filename))
{
DebugConsole.ThrowError("Sound file \"" + filename + "\" has incorrect case!");
}
reader = new VorbisReader(filename);
ALFormat = reader.Channels == 1 ? ALFormat.Mono16 : ALFormat.Stereo16;
SampleRate = reader.SampleRate;
if (!stream)
{
int bufferSize = (int)reader.TotalSamples * reader.Channels;
float[] floatBuffer = new float[bufferSize];
short[] shortBuffer = new short[bufferSize];
int readSamples = reader.ReadSamples(floatBuffer, 0, bufferSize);
CastBuffer(floatBuffer, shortBuffer, readSamples);
AL.BufferData((int)ALBuffer, ALFormat, shortBuffer,
readSamples * sizeof(short), SampleRate);
ALError alError = AL.GetError();
if (alError != ALError.NoError)
{
throw new Exception("Failed to set buffer data for non-streamed audio! "+AL.GetErrorString(alError));
}
MuffleBuffer(floatBuffer, SampleRate, reader.Channels);
CastBuffer(floatBuffer, shortBuffer, readSamples);
AL.BufferData((int)ALMuffledBuffer, ALFormat, shortBuffer,
readSamples * sizeof(short), SampleRate);
alError = AL.GetError();
if (alError != ALError.NoError)
{
throw new Exception("Failed to set buffer data for non-streamed audio! " + AL.GetErrorString(alError));
}
reader.Dispose();
}
}
public override int FillStreamBuffer(int samplePos, short[] buffer)
{
if (!Stream) throw new Exception("Called FillStreamBuffer on a non-streamed sound!");
if (samplePos >= reader.TotalSamples * reader.Channels * 2) return 0;
samplePos /= reader.Channels * 2;
reader.DecodedPosition = samplePos;
float[] floatBuffer = new float[buffer.Length];
int readSamples = reader.ReadSamples(floatBuffer, 0, buffer.Length / 2);
//MuffleBuffer(floatBuffer, reader.Channels);
CastBuffer(floatBuffer, buffer, readSamples);
return readSamples * 2;
}
static void MuffleBuffer(float[] buffer, int sampleRate, int channelCount)
{
if (!muffleFilters.TryGetValue(sampleRate, out BiQuad filter))
{
filter = new LowpassFilter(sampleRate, 800);
muffleFilters.Add(sampleRate, filter);
}
filter.Process(buffer);
}
public override void Dispose()
{
if (Stream)
{
reader.Dispose();
}
base.Dispose();
}
}
}