public void Base_Read_OneChannelToTwo()
        {
            var inputFormat   = new AudioFormat();
            var outputFormat  = new AudioFormat(channels: 2);
            var resampler     = new ResampleFilter(inputFormat, outputFormat);
            var inboundFrame  = new short[inputFormat.SamplesPerFrame];
            var outboundFrame = new short[outputFormat.SamplesPerFrame];

            // Populate one channel
            for (short i = 0; i < inputFormat.SamplesPerFrame; i++)
            {
                inboundFrame[i] = i;
            }
            var temp = new byte[Buffer.ByteLength(inboundFrame)];

            Buffer.BlockCopy(inboundFrame, 0, temp, 0, temp.Length);
            resampler.Write(temp);

            bool moreFrames;
            bool successful = resampler.Read(outboundFrame, out moreFrames);

            Assert.IsTrue(successful);
            Assert.IsFalse(moreFrames);

            // We should have two channels worth of data back. Because we interpolate and smooth, it isn't a simple
            // doubling of the original data, but some patterns can still be tested.
            for (int i = 0; i < (inputFormat.SamplesPerFrame * 2) - 4; i++)
            {
                Assert.IsTrue(outboundFrame[i] <= outboundFrame[i + 4]);
            }
        }
        public void Base_Read_TwoChannelsToOne()
        {
            var inputFormat   = new AudioFormat(channels: 2);
            var outputFormat  = new AudioFormat();
            var resampler     = new ResampleFilter(inputFormat, outputFormat);
            var inboundFrame  = new short[inputFormat.SamplesPerFrame];
            var outboundFrame = new short[outputFormat.SamplesPerFrame];

            // Give both channels the same values.
            int index = 0;

            for (short i = 0; i < outputFormat.SamplesPerFrame; i++)
            {
                inboundFrame[index++] = i;
                inboundFrame[index++] = i;
            }
            var temp = new byte[Buffer.ByteLength(inboundFrame)];

            Buffer.BlockCopy(inboundFrame, 0, temp, 0, temp.Length);
            resampler.Write(temp);

            bool moreFrames;
            bool successful = resampler.Read(outboundFrame, out moreFrames);

            Assert.IsTrue(successful);
            Assert.IsFalse(moreFrames);

            // We should get just one channel's values back.
            for (int i = 0; i < outputFormat.SamplesPerFrame; i++)
            {
                Assert.AreEqual(i, outboundFrame[i]);
            }
        }
        public void Base_Read_96KhzTo16Khz_And_TwoChannelsToOne()
        {
            var inputFormat   = new AudioFormat(96000, channels: 2);
            var outputFormat  = new AudioFormat();
            var resampler     = new ResampleFilter(inputFormat, outputFormat);
            var inboundFrame  = new short[inputFormat.SamplesPerFrame];
            var outboundFrame = new short[outputFormat.SamplesPerFrame];

            int index = 0;

            for (short i = 0; i < inputFormat.SamplesPerFrame / inputFormat.Channels; i++)
            {
                inboundFrame[index++] = i;
                inboundFrame[index++] = i;
            }
            var temp = new byte[Buffer.ByteLength(inboundFrame)];

            Buffer.BlockCopy(inboundFrame, 0, temp, 0, temp.Length);
            resampler.Write(temp);

            bool moreFrames;
            bool successful = resampler.Read(outboundFrame, out moreFrames);

            Assert.IsTrue(successful);
            Assert.IsFalse(moreFrames);

            for (int i = 0; i < outputFormat.SamplesPerFrame; i++)
            {
                Assert.AreEqual(i * 6, outboundFrame[i]);
            }
        }
        public void Base_Read_32KhzTo8Khz()
        {
            var inputFormat   = new AudioFormat(32000);
            var outputFormat  = new AudioFormat(8000);
            var resampler     = new ResampleFilter(inputFormat, outputFormat);
            var inboundFrame  = new short[inputFormat.SamplesPerFrame];
            var outboundFrame = new short[outputFormat.SamplesPerFrame];

            for (short i = 0; i < inputFormat.SamplesPerFrame; i++)
            {
                inboundFrame[i] = i;
            }
            var temp = new byte[Buffer.ByteLength(inboundFrame)];

            Buffer.BlockCopy(inboundFrame, 0, temp, 0, temp.Length);
            resampler.Write(temp);

            bool moreFrames;
            bool successful = resampler.Read(outboundFrame, out moreFrames);

            Assert.IsTrue(successful);
            Assert.IsFalse(moreFrames);

            for (int i = 0; i < outputFormat.SamplesPerFrame; i++)
            {
                Assert.AreEqual(i * 4, outboundFrame[i]);
            }
        }
        public void Base_Read_44KhzTo16Khz_And_2048To640()
        {
            // This tests the scenario we run into on some Macs, where the amount of data submitted is always on 2048 byte boundaries.

            // 44100 / 16000 = 2.75625
            const int writeFrameSize   = 1024;                           // in shorts
            const int readFrameSize    = 320;                            // in shorts
            const int inboundFrameSize = (int)(readFrameSize * 2.75625); //  = 882
            const int frameCount       = 100;
            var       inputFormat      = new AudioFormat(44100);
            var       outputFormat     = new AudioFormat();
            var       resampler        = new ResampleFilter(inputFormat, outputFormat);
            var       inboundFrames    = new short[inboundFrameSize * frameCount];
            var       outboundFrame    = new byte[readFrameSize * sizeof(short)];

            // Fill the inbound buffer.
            for (short frame = 0; frame < frameCount; frame++)
            {
                for (int i = 0; i < inboundFrameSize; i++)
                {
                    inboundFrames[frame * inboundFrameSize + i] = frame;
                }
            }

            int   index     = 0;
            short readFrame = 0;

            while (index + writeFrameSize < inboundFrames.Length)
            {
                // Write data to the frame in 1024 sample/2048 byte chunks (we'll be reading from it in 320 sample chunks).
                var tmpWrite = new byte[writeFrameSize * sizeof(short)];
                Buffer.BlockCopy(inboundFrames, index * sizeof(short), tmpWrite, 0, writeFrameSize * sizeof(short));
                resampler.Write(tmpWrite);
                index += writeFrameSize;

                bool moreFrames;
                do
                {
                    if (resampler.Read(outboundFrame, out moreFrames))
                    {
                        // Copy the byte array to a short array so we can check the values.
                        var tmpRead = new short[readFrameSize];
                        Buffer.BlockCopy(outboundFrame, 0, tmpRead, 0, readFrameSize * sizeof(short));

                        // There's some expected leakage around the ends of the buffers,
                        // so ignore the values there.
                        for (int i = 0; i < tmpRead.Length - (readFrame / 2); i++)
                        {
                            Assert.AreEqual(readFrame, tmpRead[i]);
                        }
                        readFrame++;
                    }
                } while (moreFrames);
            }
        }
        public void Base_Read_NoChanges()
        {
            var resampler     = new ResampleFilter(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.Write(inboundFrame);
            bool moreFrames;
            bool successful = resampler.Read(outboundFrame, out moreFrames);

            Assert.IsTrue(successful);
            Assert.IsFalse(moreFrames);
            for (int i = 0; i < AudioFormat.Default.BytesPerFrame; i++)
            {
                Assert.AreEqual(inboundFrame[i], outboundFrame[i]);
            }
        }