public void Should_correctly_process_multiple_channels()
        {
            var buffers = new float[][] { new float[4], new float[4] };

            var expected = new float[]
            {
                5f, 6f, 7f, 8f
            };

            transformProvider.FFT(Arg.Any<bool>(), Arg.Any<int>(), Arg.Do<Complex[]>(x =>
            {
                x[0] = new Complex { X = expected[0], Y = 0f };
                x[1] = new Complex { X = expected[1], Y = 0f };
                x[2] = new Complex { X = expected[2], Y = 0f };
                x[3] = new Complex { X = expected[3], Y = 0f };
            }));

            target = new FourierTransform(transformProvider, windowFunction, 4);

            float[][] actual = new float[2][];
            target.DataReady += (s, e) => actual[e.Channel] = e.Real;

            target.Format = new WaveFormat(44100, 2);

            target.Process(buffers, 4);

            CollectionAssert.AreEqual(expected, actual[0], new FloatComparer());
            CollectionAssert.AreEqual(expected, actual[1], new FloatComparer());
        }
        public void FourierTransform_16384_length_2000000_iterations()
        {
            var transformProvider = new ProviderFake();
            var windowFunction = new BlackmanHarrisWindowFunction();

            var target = new FourierTransform(
                transformProvider,
                windowFunction,
                4096 * 4);

            target.Format = new WaveFormat(44100, 1);

            var buffers = new float[][] { new float[64] };

            for (int i = 0; i < 2000000; i++)
            {
                target.Process(buffers, 64);
            }
        }
        public void Should_apply_window_function_to_FFT_inputs()
        {
            var buffers = new float[][]{ new []
            {
                1f, 2f, 3f, 4f
            }};

            windowFunction.CalculateCoefficients(Arg.Is(4))
                .Returns(new[] { 5f, 6f, 7f, 8f });

            target = new FourierTransform(transformProvider, windowFunction, 4);
            target.Format = new WaveFormat(44100, 1);

            target.Process(buffers, 4);

            transformProvider.Received(1).FFT(
                Arg.Any<bool>(),
                Arg.Any<int>(),
                Arg.Is<Complex[]>(x => x.Length == 4
                    && x[0].X == 5f
                    && x[1].X == 12f
                    && x[2].X == 21f
                    && x[3].X == 32f));
        }
        public void Should_pass_samples_to_FFT_implementation_as_real_component()
        {
            var buffers = new float[][]{ new []
            {
                1f, 2f, 3f, 4f
            }};

            target = new FourierTransform(transformProvider, windowFunction, 4);
            target.Format = new WaveFormat(44100, 1);

            target.Process(buffers, 4);

            transformProvider.Received(1).FFT(
                Arg.Any<bool>(),
                Arg.Any<int>(),
                Arg.Is<Complex[]>(x => x.Length == 4
                    && x[0].X == 1f
                    && x[1].X == 2f
                    && x[2].X == 3f
                    && x[3].X == 4f));
        }
        public void Should_provide_the_power_of_two_for_the_transform_length()
        {
            var buffers = new float[][] { new float[16] };

            target = new FourierTransform(transformProvider, windowFunction, 16);
            target.Format = new WaveFormat(44100, 1);

            target.Process(buffers, 16);

            transformProvider.Received(1).FFT(
                Arg.Any<bool>(),
                Arg.Is<int>(4),
                Arg.Any<Complex[]>());
        }
        public void Should_provide_the_FFT_provider_result_via_the_DataReady_event()
        {
            var buffers = new float[][] { new float[4] };

            var expected = new float[]
            {
                5f, 6f, 7f, 8f
            };

            transformProvider.FFT(Arg.Any<bool>(), Arg.Any<int>(), Arg.Do<Complex[]>(x =>
            {
                x[0] = new Complex { X = expected[0], Y = 0f };
                x[1] = new Complex { X = expected[1], Y = 0f };
                x[2] = new Complex { X = expected[2], Y = 0f };
                x[3] = new Complex { X = expected[3], Y = 0f };
            }));

            target = new FourierTransform(transformProvider, windowFunction, 4);

            float[] actual = null;
            target.DataReady += (s, e) => actual = e.Real;

            target.Format = new WaveFormat(44100, 1);

            target.Process(buffers, 4);

            CollectionAssert.AreEqual(expected, actual, new FloatComparer());
        }
        public void Should_perform_forwards_FFT()
        {
            var buffers = new float[][] { new float[4] };

            target = new FourierTransform(transformProvider, windowFunction, 4);
            target.Format = new WaveFormat(44100, 1);

            target.Process(buffers, 4);

            transformProvider.Received(1).FFT(
                Arg.Is<bool>(true),
                Arg.Any<int>(),
                Arg.Any<Complex[]>());
        }