aboutsummaryrefslogtreecommitdiff
path: root/RayRoom.NAudio
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
parent0ee008ae77fb76cbe9fe151cc6c4bc9f89cb98a5 (diff)
downloadRayRoom-79d8da74ac98166ec9e9dae7eff820cd9842edb3.tar.gz
RayRoom-79d8da74ac98166ec9e9dae7eff820cd9842edb3.zip
basic functionality
+ compute bound
Diffstat (limited to 'RayRoom.NAudio')
-rw-r--r--RayRoom.NAudio/AudioOut.cs95
-rw-r--r--RayRoom.NAudio/AudioSampler.cs46
-rw-r--r--RayRoom.NAudio/RayRoom.NAudioEngine.csproj17
3 files changed, 158 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;
+ }
+ }
+}
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 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>net6.0</TargetFramework>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <Nullable>enable</Nullable>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="NAudio" Version="2.2.1" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\RayRoom\RayRoom.csproj" />
+ </ItemGroup>
+
+</Project>