Пример #1
0
        /// <summary>
        /// 複素数がインターリーブされたデータを離散フーリエ変換します。
        /// </summary>
        /// <param name="invert">逆離散フーリエ変換を行うかの真偽値。</param>
        /// <param name="data">複素数がインターリーブされた配列。</param>
        public void TransformComplex(bool invert, double[] data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            if (data.Length != this.n)
            {
                throw new ArgumentOutOfRangeException("data");
            }

            FastFourier.cdft(this.n, invert, data, this.ip, this.w);

            if (invert)
            {
                double f = 2.0 / this.n;

                for (int j = 0; j < this.n; j++)
                {
                    data[j] *= f;
                }
            }
        }
Пример #2
0
        public override void Draw(float[] data)
        {
            float dx = (float)this.size.Width / (float)(data.Length / 8);
            float y_offset = +20.0f;

            int fftSize = data.Length / 2;
            int height = this.size.Height / 2;

            if (this.buffer.Length != fftSize)
            {
                this.buffer = new PointF[fftSize / 4];
                this.lchannel = new double[fftSize];
                this.rchannel = new double[fftSize];
                this.fft_buffer = new double[fftSize * 2];
                this.fft = new FastFourier(fftSize);
            }

            this.graphics.Clear(this.backgroundColor);

            for (int i = 0, j = 0, k = 1; i < fftSize; i++, j += 2, k += 2)
            {
                this.lchannel[i] = data[j];
                this.rchannel[i] = data[k];
            }

            // L channel
            {
                Window.Hanning(lchannel);
                Channel.Interleave(lchannel, this.fft_buffer, fftSize);
                this.fft.TransformComplex(false, this.fft_buffer);

                for (int i = 0, j = 0, k = 1; i < fftSize / 4; i++, j += 2, k += 2)
                {
                    double d = 20.0 * Math.Log10(Math.Sqrt(this.fft_buffer[j] * this.fft_buffer[j] + this.fft_buffer[k] * this.fft_buffer[k]) / fftSize) + y_offset;

                    if (d <= -height)
                        d = -height;
                    else if (d > 0.0)
                        d = 0.0;

                    this.buffer[i] = new PointF(i * dx, -(float)d);
                }

                this.graphics.DrawLines(this.p, this.buffer);
            }

            // R channel
            {
                Window.Hanning(rchannel);
                Channel.Interleave(rchannel, this.fft_buffer, fftSize);
                this.fft.TransformComplex(false, this.fft_buffer);

                for (int i = 0, j = 0, k = 1; i < fftSize / 4; i++, j += 2, k += 2)
                {
                    double d = 20.0 * Math.Log10(Math.Sqrt(this.fft_buffer[j] * this.fft_buffer[j] + this.fft_buffer[k] * this.fft_buffer[k]) / fftSize) + y_offset;

                    if (d <= -height)
                        d = -height;
                    else if (d > 0.0)
                        d = 0.0;

                    this.buffer[i] = new PointF(i * dx, this.size.Height / 2 - (float)d);
                }

                this.graphics.DrawLines(this.p, this.buffer);
            }

            this.graphics.DrawLine(this.p, 0, height, this.size.Width, height);

            this.graphics.Flush();
        }
Пример #3
0
        public unsafe override void Draw(float[] data)
        {
            float dx = (float)this.size.Width / (float)(data.Length / 4);
            const float y_offset = +210.0f;
            const float y_amplifier = 100.0f;

            int fftSize = data.Length;

            if (fftSize != this.fft_buffer.Length)
            {
                this.fft = new FastFourier(fftSize);
                this.re = new double[fftSize];
                this.fft_buffer = new double[fftSize * 2];
                this.spectrum = new Bitmap(1, fftSize / 8);
            }

            data.CopyTo(re, 0);
            Window.Hanning(this.re);
            Channel.Interleave(this.re, this.fft_buffer, fftSize);
            this.fft.TransformComplex(false, this.fft_buffer);

            for (int i = 0, j = 0, k = 1; i < fftSize / 8; i++, j += 2, k += 2)
            {
                re[i] = y_amplifier * Math.Log10(Math.Sqrt(this.fft_buffer[j] * this.fft_buffer[j] + this.fft_buffer[k] * this.fft_buffer[k]) / (fftSize * 4)) + y_offset;

                if (re[i] < -255.0)
                    re[i] = -255.0;
                else if (re[i] > 0.0)
                    re[i] = 0.0;
            }

            var bdata = this.bitmap.LockBits(new Rectangle(0, 0, this.bitmap.Width, this.bitmap.Height),
                                             ImageLockMode.ReadWrite,
                                             PixelFormat.Format32bppArgb);
            {
                for (byte* i = (byte*)bdata.Scan0, j = i + 4, l = i + bdata.Width * bdata.Height * 4; j < l; i++, j++)
                    *i = *j;
            }
            this.bitmap.UnlockBits(bdata);

            bdata = this.spectrum.LockBits(new Rectangle(0, 0, 1, fftSize / 8),
                                           ImageLockMode.ReadWrite,
                                           PixelFormat.Format32bppArgb);
            {
                int j = 0;
                for (byte* i = (byte*)bdata.Scan0, l = i + bdata.Height * 4; i < l; j++)
                {
                    byte b = (byte)(255.0 + re[j]);
                    *i++ = b;
                    *i++ = b;
                    *i++ = b;
                    *i++ = 255;
                }
            }
            this.spectrum.UnlockBits(bdata);

            this.graphics.DrawImage(this.spectrum, this.size.Width - 1, this.size.Height - 1, 1, -this.size.Height);
            this.graphics.Flush();
        }