public void Timing_EverythingOnTime()
        {
            var resampler     = new ResampleFilterTiming(AudioFormat.Default, AudioFormat.Default);
            var inboundFrame  = new byte[AudioFormat.Default.BytesPerFrame];
            var outboundFrame = new byte[AudioFormat.Default.BytesPerFrame];

            for (int i = 0; i < inboundFrame.Length; i++)
            {
                inboundFrame[i] = (byte)i;
            }
            resampler.Now = DateTime.Now;
            for (int i = 0; i < ResampleFilterTiming.InitialFramesToIgnore + ResampleFilterTiming.MaxFramesBetweenResets * 2; i++)
            {
                resampler.Write(inboundFrame);
                bool moreFrames;
                bool successful = resampler.Read(outboundFrame, out moreFrames);
                Assert.IsTrue(successful);
                Assert.IsFalse(moreFrames);
                for (int j = 0; j < AudioFormat.Default.BytesPerFrame; j++)
                {
                    Assert.AreEqual(inboundFrame[j], outboundFrame[j]);
                }
                Assert.AreEqual(1.0f, resampler.CorrectionFactor);
                Assert.AreEqual(0, resampler.UnreadBytes);
                resampler.Now += TimeSpan.FromMilliseconds(resampler.OutputMillisecondsPerFrame);
            }
        }
        public void Timing_TooSlow()
        {
            var resampler     = new ResampleFilterTiming(AudioFormat.Default, AudioFormat.Default);
            var inboundFrame  = new byte[AudioFormat.Default.BytesPerFrame];
            var outboundFrame = new byte[AudioFormat.Default.BytesPerFrame];

            for (int i = 0; i < inboundFrame.Length; i++)
            {
                inboundFrame[i] = (byte)i;
            }
            resampler.Now = DateTime.Now;

            bool successful;
            bool moreFrames = false;

            // Read normally until we get through the warmup period.
            for (int i = 0; i < ResampleFilterTiming.InitialFramesToIgnore; i++)
            {
                resampler.Write(inboundFrame);
                successful = resampler.Read(outboundFrame, out moreFrames);
                Assert.IsTrue(successful);
                Assert.IsFalse(moreFrames);
                Assert.IsTrue(resampler.UnreadBytes == 0);
                resampler.Now += TimeSpan.FromMilliseconds(resampler.OutputMillisecondsPerFrame);
            }

            // Read/write every 21 milliseconds
            for (int i = 0; i < ResampleFilterTiming.MaxFramesBetweenResets; i++)
            {
                resampler.Write(inboundFrame);
                successful = resampler.Read(outboundFrame, out moreFrames);
                Assert.IsTrue(successful);
                Assert.IsFalse(moreFrames);
                resampler.Now += TimeSpan.FromMilliseconds(21);
            }

            // Confirm that the correction factor has been set correctly.
            Assert.AreEqual(21.0 / resampler.OutputMillisecondsPerFrame, resampler.CorrectionFactor);

            // Read another 19 frames
            for (int i = 0; i < 19; i++)
            {
                resampler.Write(inboundFrame);
                successful = resampler.Read(outboundFrame, out moreFrames);
                Assert.IsTrue(successful);
                Assert.IsTrue(resampler.UnreadBytes > 0);
                resampler.Now += TimeSpan.FromMilliseconds(21);
            }

            // After 19 reads, there should be one more frame waiting to be read.
            Assert.IsTrue(moreFrames);
            successful = resampler.Read(outboundFrame, out moreFrames);
            Assert.IsTrue(successful);
            Assert.IsFalse(moreFrames);
            Assert.IsTrue(resampler.UnreadBytes == 0);
        }
        public void Timing_TooFast()
        {
            var resampler     = new ResampleFilterTiming(AudioFormat.Default, AudioFormat.Default);
            var inboundFrame  = new byte[AudioFormat.Default.BytesPerFrame];
            var outboundFrame = new byte[AudioFormat.Default.BytesPerFrame];

            for (int i = 0; i < inboundFrame.Length; i++)
            {
                inboundFrame[i] = (byte)i;
            }
            resampler.Now = DateTime.Now;

            bool successful;
            bool moreFrames;

            // Read normally until we get through the warmup period.
            for (int i = 0; i < ResampleFilterTiming.InitialFramesToIgnore; i++)
            {
                resampler.Write(inboundFrame);
                successful = resampler.Read(outboundFrame, out moreFrames);
                Assert.IsTrue(successful);
                Assert.IsFalse(moreFrames);
                Assert.IsTrue(resampler.UnreadBytes == 0);
                resampler.Now += TimeSpan.FromMilliseconds(resampler.OutputMillisecondsPerFrame);
            }

            // Read/write every 19 milliseconds
            for (int i = 0; i < ResampleFilterTiming.MaxFramesBetweenResets - 1; i++)
            {
                resampler.Write(inboundFrame);
                successful = resampler.Read(outboundFrame, out moreFrames);
                Assert.IsTrue(successful);
                Assert.IsFalse(moreFrames);
                resampler.Now += TimeSpan.FromMilliseconds(19);
            }

            // Write and try to read another frame. It should have been downsampled, and hence shouldn't be ready for reading yet.
            resampler.Write(inboundFrame);
            Assert.AreEqual((int)(19.0 / resampler.OutputMillisecondsPerFrame) * 1000, (int)resampler.CorrectionFactor * 1000);
            successful = resampler.Read(outboundFrame, out moreFrames);
            Assert.IsFalse(successful);
            Assert.IsFalse(moreFrames);
            resampler.Now += TimeSpan.FromMilliseconds(19);

            // The next 18 read/writes should succeed, but leave data.
            for (int i = 0; i < 18; i++)
            {
                resampler.Write(inboundFrame);
                successful = resampler.Read(outboundFrame, out moreFrames);
                Assert.IsTrue(successful);
                Assert.IsTrue(resampler.UnreadBytes > 0);
                Assert.IsFalse(moreFrames);
                resampler.Now += TimeSpan.FromMilliseconds(19);
            }

            // The 19th read/write should drain the buffer.
            resampler.Write(inboundFrame);
            successful = resampler.Read(outboundFrame, out moreFrames);
            Assert.IsTrue(successful);
            Assert.IsFalse(moreFrames);
            Assert.IsTrue(resampler.UnreadBytes == 0);

            // The 20th read/write should fail.
            resampler.Write(inboundFrame);
            Assert.AreEqual((int)(19.0 / resampler.OutputMillisecondsPerFrame) * 1000, (int)resampler.CorrectionFactor * 1000);
            successful = resampler.Read(outboundFrame, out moreFrames);
            Assert.IsFalse(successful);
            Assert.IsFalse(moreFrames);
        }