diff options
author | bonmas14 <bonmas14@gmail.com> | 2023-10-29 21:03:26 +0300 |
---|---|---|
committer | bonmas14 <bonmas14@gmail.com> | 2023-10-29 21:03:26 +0300 |
commit | 79d8da74ac98166ec9e9dae7eff820cd9842edb3 (patch) | |
tree | bc359f214122236968f853e6aed7236a9e4905f9 /RayRoom.NAudio | |
parent | 0ee008ae77fb76cbe9fe151cc6c4bc9f89cb98a5 (diff) | |
download | RayRoom-79d8da74ac98166ec9e9dae7eff820cd9842edb3.tar.gz RayRoom-79d8da74ac98166ec9e9dae7eff820cd9842edb3.zip |
basic functionality
+ compute bound
Diffstat (limited to 'RayRoom.NAudio')
-rw-r--r-- | RayRoom.NAudio/AudioOut.cs | 95 | ||||
-rw-r--r-- | RayRoom.NAudio/AudioSampler.cs | 46 | ||||
-rw-r--r-- | RayRoom.NAudio/RayRoom.NAudioEngine.csproj | 17 |
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> |