/// <summary> /// Create a room to be simulated. /// </summary> /// <param name="size">The size of the room as a 3-dimensional vector.</param> /// <param name="distanceAttenuation">The distance attenuation characteristics of the room.</param> /// <param name="reflectionAttenuation">The reflection attenuation characteristics of the room.</param> /// <param name="maxReflectionCount">The number of reflections to be simulated.</param> public Room(Vector <double> size, DistanceAttenuation distanceAttenuation, ReflectionAttenuation reflectionAttenuation, int maxReflectionCount) { if (size == null) { throw new ArgumentNullException(nameof(size)); } if (size.Count != 3) { throw new ArgumentException(nameof(size), "The length of the size vector must be 3."); } if (size.Any(value => value <= 0)) { throw new ArgumentException(nameof(size), "All the values of the size vector must be positive."); } if (distanceAttenuation == null) { throw new ArgumentNullException(nameof(distanceAttenuation)); } if (reflectionAttenuation == null) { throw new ArgumentNullException(nameof(reflectionAttenuation)); } if (maxReflectionCount < 0) { throw new ArgumentException(nameof(maxReflectionCount), "The max reflection count must be greater than or equal to zero."); } this.size = size.Clone(); this.distanceAttenuation = distanceAttenuation; this.reflectionAttenuation = reflectionAttenuation; this.maxReflectionCount = maxReflectionCount; }
public void GenerateImpulseResponse_CheckSignal() { var sampleRate = 16000; var dftLength = 1024; var delaySampleCount = 30; var time = (double)delaySampleCount / sampleRate; var distance = AcousticConstants.SoundSpeed * time; var roomSize = DenseVector.OfArray(new double[] { distance, distance, distance }); var distanceAttenuation = new DistanceAttenuation(distance => 0.9); var reflectionAttenuation = new ReflectionAttenuation(frequency => 0.7); var room = new Room(roomSize, distanceAttenuation, reflectionAttenuation, 1); var soundSource = new SoundSource(distance / 2, distance / 2, distance / 2); var microphone = new Microphone(distance / 2, distance / 2, distance / 2); var response = MirrorMethod.GenerateImpulseResponse(room, soundSource, microphone, sampleRate, dftLength); Assert.AreEqual(dftLength / 2, response.Length); for (var t = 0; t < response.Length; t++) { if (t == 0) { Assert.AreEqual(0.9, response[t], 1.0E-6); } else if (t == delaySampleCount) { Assert.AreEqual(6 * 0.9 * 0.7, response[t], 1.0E-6); } } }
public void GenerateSoundRays_CheckRayProperties() { var roomSize = DenseVector.OfArray(new double[] { 2.0, 2.0, 2.0 }); var distanceAttenuation = new DistanceAttenuation(distance => 0.9); var reflectionAttenuation = new ReflectionAttenuation(frequency => 0.7); var room = new Room(roomSize, distanceAttenuation, reflectionAttenuation, 1); var soundSource = new SoundSource(1.0, 1.0, 1.0); var microphone = new Microphone(1.0, 1.0, 1.0); var rays = MirrorMethod.GenerateSoundRays(room, soundSource, microphone).ToArray(); Assert.AreEqual(7, rays.Length); foreach (var ray in rays) { if (ray.Distance < 1.0E-6) { Assert.AreEqual(0, ray.ReflectionCount); } else { Assert.AreEqual(2.0, ray.Distance, 1.0E-6); Assert.AreEqual(1, ray.ReflectionCount); } } }
public void GetMirroredPosition_Case3() { var roomSize = DenseVector.OfArray(new double[] { 3.0, 4.0, 2.0 }); var distanceAttenuation = new DistanceAttenuation(distance => 0.9); var reflectionAttenuation = new ReflectionAttenuation(frequency => 0.7); var room = new Room(roomSize, distanceAttenuation, reflectionAttenuation, 1); var microphone = new Microphone(0.5, 1.0, 1.5); var index = new MirroredRoomIndex(5, -2, -3); var mirrored = MirrorMethod.GetMirroredPosition(room, microphone, index); Assert.AreEqual(15.0 + 2.5, mirrored[0], 1.0E-9); Assert.AreEqual(-8.0 + 1.0, mirrored[1], 1.0E-9); Assert.AreEqual(-6.0 + 0.5, mirrored[2], 1.0E-9); }
public void Constructor() { var roomSize = DenseVector.OfArray(new double[] { 3.0, 4.0, 2.0 }); var distanceAttenuation = new DistanceAttenuation(distance => 0.9); var reflectionAttenuation = new ReflectionAttenuation(frequency => 0.7); var room = new Room(roomSize, distanceAttenuation, reflectionAttenuation, 1); Assert.IsTrue((roomSize - room.Size).L2Norm() < 1.0E-6); Assert.AreEqual(distanceAttenuation(1), room.DistanceAttenuation(1)); Assert.AreEqual(distanceAttenuation(3), room.DistanceAttenuation(3)); Assert.AreEqual(reflectionAttenuation(0), room.ReflectionAttenuation(0)); Assert.AreEqual(reflectionAttenuation(1), room.ReflectionAttenuation(1)); Assert.AreEqual(reflectionAttenuation(3), room.ReflectionAttenuation(3)); Assert.AreEqual(1, room.MaxReflectionCount); }
public void GenerateFrequencyDomainImpulseResponse_CheckDistanceAttenuation() { var sampleRate = 16000; var dftLength = 1024; var delaySampleCount = 30; var time = (double)delaySampleCount / sampleRate; var distance = AcousticConstants.SoundSpeed * time; var roomSize = DenseVector.OfArray(new double[] { distance, distance, distance }); var distanceAttenuation = new DistanceAttenuation(distance => distance < 0.1 ? 3.1 : 2.3); var reflectionAttenuation = new ReflectionAttenuation(frequency => 0.7); var room = new Room(roomSize, distanceAttenuation, reflectionAttenuation, 1); var soundSource = new SoundSource(distance / 2, distance / 2, distance / 2); var microphone = new Microphone(distance / 2, distance / 2, distance / 2); var response = MirrorMethod.GenerateFrequencyDomainImpulseResponse(room, soundSource, microphone, sampleRate, dftLength); var timeDomainSignal = new Complex[dftLength]; timeDomainSignal[0] = response[0]; for (var w = 1; w < dftLength / 2; w++) { timeDomainSignal[w] = response[w]; timeDomainSignal[dftLength - w] = response[w].Conjugate(); } timeDomainSignal[dftLength / 2] = response[dftLength / 2]; Fourier.Inverse(timeDomainSignal, FourierOptions.AsymmetricScaling); for (var t = 0; t < dftLength; t++) { if (t == 0) { Assert.AreEqual(3.1, timeDomainSignal[t].Real, 1.0E-6); Assert.AreEqual(0.0, timeDomainSignal[t].Imaginary, 1.0E-6); } else if (t == delaySampleCount) { Assert.AreEqual(6 * 2.3 * 0.7, timeDomainSignal[t].Real, 1.0E-6); Assert.AreEqual(0.0, timeDomainSignal[t].Imaginary, 1.0E-6); } else { Assert.AreEqual(0.0, timeDomainSignal[t].Real, 1.0E-6); Assert.AreEqual(0.0, timeDomainSignal[t].Imaginary, 1.0E-6); } } }
public override string GetStepParameters() { var parameters = new List <string>(); parameters.Add(Name != null ? Name.ToStepValue() : "$"); parameters.Add(LightColour != null ? LightColour.ToStepValue() : "$"); parameters.Add(AmbientIntensity != null ? AmbientIntensity.ToStepValue() : "$"); parameters.Add(Intensity != null ? Intensity.ToStepValue() : "$"); parameters.Add(Position != null ? Position.ToStepValue() : "$"); parameters.Add(Radius != null ? Radius.ToStepValue() : "$"); parameters.Add(ConstantAttenuation != null ? ConstantAttenuation.ToStepValue() : "$"); parameters.Add(DistanceAttenuation != null ? DistanceAttenuation.ToStepValue() : "$"); parameters.Add(QuadricAttenuation != null ? QuadricAttenuation.ToStepValue() : "$"); return(string.Join(", ", parameters.ToArray())); }
public void GenerateFrequencyDomainImpulseResponse_CheckReflectionAttenuation() { var sampleRate = 16000; var dftLength = 1024; var delaySampleCount = 30; var time = (double)delaySampleCount / sampleRate; var distance = AcousticConstants.SoundSpeed * time; var cutOff = 4000; var roomSize = DenseVector.OfArray(new double[] { distance, distance, distance }); var distanceAttenuation = new DistanceAttenuation(distance => distance < 1.0E-3 ? 0.0 : 0.9); var reflectionAttenuation = new ReflectionAttenuation(frequency => frequency < cutOff ? 0.7 : 0.0); var room = new Room(roomSize, distanceAttenuation, reflectionAttenuation, 1); var soundSource = new SoundSource(distance / 2, distance / 2, distance / 2); var microphone = new Microphone(distance / 2, distance / 2, distance / 2); var response = MirrorMethod.GenerateFrequencyDomainImpulseResponse(room, soundSource, microphone, sampleRate, dftLength); var validCount = 0; for (var w = 0; w < response.Length; w++) { var frequency = (double)w / dftLength * sampleRate; if (Math.Abs(frequency - cutOff) > 1) { if (frequency < cutOff) { Assert.IsTrue(response[w].Magnitude > 1.0E-3); } else { Assert.IsTrue(response[w].Magnitude < 1.0E-3); } validCount++; } } Assert.IsTrue(validCount >= response.Length - 3); }