Exemple #1
0
        /// <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);
        }
Exemple #5
0
        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);
        }