Example #1
0
        public void WavReaderMakeMultiChannelWav()
        {
            const double Tau = 2 * Math.PI;

            var a = new double[22050].Select((v, i) => Math.Sin(Tau * i * 500 / 22050)).ToArray();
            var b = new double[22050].Select((v, i) => Math.Sin(Tau * i * 1500 / 22050)).ToArray();
            var c = new double[22050].Select((v, i) => Math.Sin(Tau * i * 2500 / 22050)).ToArray();
            var d = new double[22050].Select((v, i) => Math.Sin(Tau * i * 3500 / 22050)).ToArray();

            var multiplexed = new double[22050 * 4].Select(
                (v, i) =>
            {
                switch (i % 4)
                {
                case 0: return(a[i / 4]);

                case 1: return(b[i / 4]);

                case 2: return(c[i / 4]);

                case 3: return(d[i / 4]);
                }

                return(double.NaN);
            });

            var reader = new WavReader(multiplexed.ToArray(), 4, 16, 22050);

            CollectionAssert.AreEqual(a, reader.GetChannel(0));
            CollectionAssert.AreEqual(b, reader.GetChannel(1));
            CollectionAssert.AreEqual(c, reader.GetChannel(2));
            CollectionAssert.AreEqual(d, reader.GetChannel(3));
        }
Example #2
0
        public void WavReaderChannelOutOfBoundsFails()
        {
            var source = PathHelper.GetTestAudioFile("different_channels_tone.wav");

            var reader = new WavReader(source);

            Assert.ThrowsException <IndexOutOfRangeException>(() => { reader.GetChannel(-1); });
            Assert.ThrowsException <IndexOutOfRangeException>(() => { reader.GetChannel(5); });
            Assert.ThrowsException <IndexOutOfRangeException>(() => { reader[0, -1].ToString(); });
            Assert.ThrowsException <IndexOutOfRangeException>(() => { reader[0, 5].ToString(); });
        }
Example #3
0
        public void WavReaderReadsSamplesAccurately24bit()
        {
            // 11025Hz fake array
            var a = new double[44100 * 5].Select((v, i) => i % 4 == 3 ? -1 : i % 2).ToArray();

            var source = PathHelper.GetTestAudioFile("11025Hz-24bit.wav");
            var info   = this.audioUtility.Info(source);

            var reader = new WavReader(source);

            TestHelper.WavReaderAssertions(reader, info);

            Assert.AreEqual(5.0M, reader.ExactDurationSeconds);

            var mono = reader.GetChannel(0);

            Assert.AreEqual(a.Length, reader.Samples.Length);
            Assert.AreEqual(a.Length, mono.Length);

            for (int i = 0; i < a.Length; i++)
            {
                Assert.AreEqual(a[i], reader.Samples[i], double.Epsilon);
                Assert.AreEqual(a[i], mono[i], double.Epsilon);
            }
        }
        private static void DoFrequencyAnalysis(
            AudioUtilityInfo expected,
            int[][] expectedFrequencies)
        {
            var reader = new WavReader(expected.SourceFile);

            TestHelper.WavReaderAssertions(reader, expected);

            for (var channel = 0; channel < expectedFrequencies.Length; channel++)
            {
                var samples = reader.GetChannel(channel);

                TestHelper.AssertFrequencyInSignal(reader, samples, expectedFrequencies[channel]);
            }
        }
Example #5
0
        public void WavReaderGetChannel()
        {
            var source = PathHelper.GetTestAudioFile("4channelsPureTones.wav");
            var info   = this.audioUtility.Info(source);

            var reader = new WavReader(source);

            TestHelper.WavReaderAssertions(reader, info);

            var channels            = new double[4][];
            var expectedFrequencies = new int[] { 4000, 3000, 2000, 1000 };

            for (int c = 0; c < channels.Length; c++)
            {
                channels[c] = reader.GetChannel(c);

                TestHelper.AssertFrequencyInSignal(reader, channels[c], new[] { expectedFrequencies[c] });
            }
        }
Example #6
0
        public void WavReaderReadsSamplesAccuratelytMultiChannelRandom(int bitDepth, int sampleRate, int channels)
        {
            const int testSampleCount = 500;

            // generate some fake data
            // generates a repeating saw wave of 0, 1, 0 -1
            var a = new double[testSampleCount].Select((v, i) => i % 4 == 3 ? -1.0 : i % 2).ToArray();

            // random data
            var random = TestHelpers.Random.GetRandom();

            double Clamp(double value)
            {
                return(Math.Max(Math.Min(value, 1.0), -1.0));
            }

            var b = new double[testSampleCount].Select(v => Clamp(random.NextDouble() * 2.0 - 1.0)).ToArray();

            // now write the file
            var temp    = PathHelper.GetTempFile("wav");
            var signals = new double[channels][];

            switch (channels)
            {
            case 4:
                signals[0] = a;
                signals[1] = b;
                signals[2] = b;
                signals[3] = a;
                break;

            case 2:
                signals[0] = a;
                signals[1] = b;
                break;

            case 1:
                var c = new double[a.Length + b.Length];
                a.CopyTo(c, 0);
                b.CopyTo(c, a.Length);
                signals[0] = c;
                break;

            default:
                throw new InvalidOperationException();
            }

            WavWriter.WriteWavFileViaFfmpeg(temp, signals, bitDepth, sampleRate);

            // verify file written correctly
            var info = this.audioUtility.Info(temp);

            var reader = new WavReader(temp);

            // verify the writer wrote (the header) correctly
            TestHelper.WavReaderAssertions(reader, new AudioUtilityInfo()
            {
                BitsPerSample = bitDepth,
                BitsPerSecond = channels * bitDepth * sampleRate,
                ChannelCount  = channels,
                Duration      = TimeSpan.FromSeconds(testSampleCount * (channels == 1 ? 2 : 1) / (double)sampleRate),
                MediaType     = MediaTypes.MediaTypeWav1,
                SampleRate    = sampleRate,
            });

            // verify the wav reader read correctly
            TestHelper.WavReaderAssertions(reader, info);

            // our ability to faithfully convert numbers depends on the bit depth of the signal
            double epilson = reader.Epsilon;

            for (int c = 0; c < channels; c++)
            {
                double[] expected;
                double   e;
                switch (c)
                {
                case 0 when channels == 1:
                    var ex = new double[a.Length + b.Length];
                    a.CopyTo(ex, 0);
                    b.CopyTo(ex, a.Length);
                    expected = ex;

                    e = epilson;
                    break;

                case 0:
                    expected = a;
                    e        = 0.0;
                    break;

                case 1:
                    expected = b;
                    e        = epilson;
                    break;

                case 2:
                    expected = b;
                    e        = epilson;
                    break;

                case 3:
                    expected = a;
                    e        = 0.0;
                    break;

                default:
                    throw new InvalidOperationException();
                }

                var mono = reader.GetChannel(c);
                Assert.AreEqual(expected.Length, mono.Length);

                for (int i = 0; i < a.Length; i++)
                {
                    Assert.AreEqual(expected[i], mono[i], epilson, $"failed at index {i} channel {c}");
                }
            }
        }