From 79d8da74ac98166ec9e9dae7eff820cd9842edb3 Mon Sep 17 00:00:00 2001 From: bonmas14 Date: Sun, 29 Oct 2023 21:03:26 +0300 Subject: basic functionality + compute bound --- RayRoom.NAudio/AudioOut.cs | 95 ++++++++++++++++++++++++++++++ RayRoom.NAudio/AudioSampler.cs | 46 +++++++++++++++ RayRoom.NAudio/RayRoom.NAudioEngine.csproj | 17 ++++++ 3 files changed, 158 insertions(+) create mode 100644 RayRoom.NAudio/AudioOut.cs create mode 100644 RayRoom.NAudio/AudioSampler.cs create mode 100644 RayRoom.NAudio/RayRoom.NAudioEngine.csproj (limited to 'RayRoom.NAudio') diff --git a/RayRoom.NAudio/AudioOut.cs b/RayRoom.NAudio/AudioOut.cs new file mode 100644 index 0000000..79a3288 --- /dev/null +++ b/RayRoom.NAudio/AudioOut.cs @@ -0,0 +1,95 @@ +using NAudio.Wave; +using RayRoom.Core; +using RayRoom.Structures; + +namespace RayRoom.NAudioEngine +{ + public class AudioOut : ISampleProvider + { + public WaveFormat WaveFormat { get; } + + public ResultContainer Container + { + get => container; + + set + { + updatedPosition = value; + } + } + + private ResultContainer updatedPosition; + + private ShiftArray leftBuffer; + private ShiftArray rightBuffer; + private Settings settings; + + private Dictionary> sources; + private ResultContainer container; + + public AudioOut(Settings settings) + { + this.settings = settings; + sources = new Dictionary>(); + WaveFormat = WaveFormat.CreateIeeeFloatWaveFormat(settings.frequency, 2); + + leftBuffer = new ShiftArray((int)(settings.frequency * (settings.maxDistanceMeters / settings.speedOfSound + 1))); + rightBuffer = new ShiftArray((int)(settings.frequency * (settings.maxDistanceMeters / settings.speedOfSound + 1))); + } + + public int Read(float[] buffer, int offset, int count) + { + container = updatedPosition; + + float velocity = 1f / container.countOfRays; + + sources.Clear(); + + foreach (var collision in container.distances) + if (sources.ContainsKey(collision.source.Handler)) + sources[collision.source.Handler].Add(collision); + else + sources.Add(collision.source.Handler, new List(10) { collision }); + + foreach (var source in sources) + { + float[] samples = new float[count / 2]; + + int read = source.Key.WriteTo(samples, 0, count / 2); + + foreach (var collision in source.Value) + { + int offsetSamples = settings.GetSamplesDelay(collision.distance) * 4; + Parallel.For(0, count / 2, i => + { + if (collision.channel == 0) + leftBuffer[i + offsetSamples] += samples[i] * velocity * (collision.source.Loudness / MathF.Pow(collision.distance, 2)); + else + rightBuffer[i + offsetSamples] += samples[i] * velocity * (collision.source.Loudness / MathF.Pow(collision.distance, 2)); + + }); + } + } + + Parallel.For(0, count, i => + { + if (i % 2 == 0) + { + buffer[i] = leftBuffer[i / 2]; + leftBuffer[i / 2] = 0; + } + else + { + buffer[i] = rightBuffer[(i - 1) / 2]; + rightBuffer[(i - 1) / 2] = 0; + } + + }); + + leftBuffer.Offset += count / 2; + rightBuffer.Offset += count / 2; + + return count; + } + } +} diff --git a/RayRoom.NAudio/AudioSampler.cs b/RayRoom.NAudio/AudioSampler.cs new file mode 100644 index 0000000..2aebcce --- /dev/null +++ b/RayRoom.NAudio/AudioSampler.cs @@ -0,0 +1,46 @@ +using NAudio.Wave; +using RayRoom.Core; + +namespace RayRoom.NAudioEngine +{ + public class AudioSampler : ISampleHandler, IDisposable + { + public bool Loop { get; set; } + + private bool disposed; + + private AudioFileReader reader; + private ISampleProvider provider; + + public AudioSampler(string file, bool looping = false) + { + disposed = false; + reader = new AudioFileReader(file); + Loop = looping; + + provider = reader.ToSampleProvider(); + provider = provider.ToMono(); + } + + public int WriteTo(float[] buffer, int offset, int count) + { + if (disposed) throw new ObjectDisposedException("AudioSampler is disposed"); + + int length = provider.Read(buffer, offset, count); + + if (Loop && length < count) + { + reader.Position = 0; + length += provider.Read(buffer, length, count - length); + } + + return length; + } + + public void Dispose() + { + reader.Close(); + reader.Dispose(); + } + } +} \ No newline at end of file diff --git a/RayRoom.NAudio/RayRoom.NAudioEngine.csproj b/RayRoom.NAudio/RayRoom.NAudioEngine.csproj new file mode 100644 index 0000000..471fb68 --- /dev/null +++ b/RayRoom.NAudio/RayRoom.NAudioEngine.csproj @@ -0,0 +1,17 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + -- cgit v1.2.3-70-g09d2