aboutsummaryrefslogtreecommitdiff
path: root/RayRoom.NAudio/AudioOut.cs
diff options
context:
space:
mode:
authorbonmas14 <bonmas14@gmail.com>2023-10-29 21:03:26 +0300
committerbonmas14 <bonmas14@gmail.com>2023-10-29 21:03:26 +0300
commit79d8da74ac98166ec9e9dae7eff820cd9842edb3 (patch)
treebc359f214122236968f853e6aed7236a9e4905f9 /RayRoom.NAudio/AudioOut.cs
parent0ee008ae77fb76cbe9fe151cc6c4bc9f89cb98a5 (diff)
downloadRayRoom-79d8da74ac98166ec9e9dae7eff820cd9842edb3.tar.gz
RayRoom-79d8da74ac98166ec9e9dae7eff820cd9842edb3.zip
basic functionality
+ compute bound
Diffstat (limited to 'RayRoom.NAudio/AudioOut.cs')
-rw-r--r--RayRoom.NAudio/AudioOut.cs95
1 files changed, 95 insertions, 0 deletions
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<float> leftBuffer;
+ private ShiftArray<float> rightBuffer;
+ private Settings settings;
+
+ private Dictionary<ISampleHandler, List<AudioSourceCollision>> sources;
+ private ResultContainer container;
+
+ public AudioOut(Settings settings)
+ {
+ this.settings = settings;
+ sources = new Dictionary<ISampleHandler, List<AudioSourceCollision>>();
+ WaveFormat = WaveFormat.CreateIeeeFloatWaveFormat(settings.frequency, 2);
+
+ leftBuffer = new ShiftArray<float>((int)(settings.frequency * (settings.maxDistanceMeters / settings.speedOfSound + 1)));
+ rightBuffer = new ShiftArray<float>((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<AudioSourceCollision>(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;
+ }
+ }
+}