/// <summary>
        /// 频率滤波。传入要保留的起止频率
        /// </summary>
        /// <param name="data"></param>
        /// <param name="beginf"></param>
        /// <param name="endf"></param>
        /// <returns></returns>
        public static int[] FrequencyFilter(int[] data, double beginf, double endf)
        {
            int    k  = data.Length;
            int    dx = getmin2x(k);
            double dl = (double)NNLink.NBankManager.samplingRate / dx;

            double[] data1     = new double[dx];
            double[] dataimag1 = new double[dx];
            Array.Copy(data, data1, k);
            TWFFT.FFT(data1, dataimag1);

            //double[] data1t = new double[dx];
            //for (int i = 0; i < dx; i++) data1t[i] = Math.Sqrt(data1[i] * data1[i] + dataimag1[i] * dataimag1[i]);
            int beginx = (int)(beginf / dl);
            int endx   = (int)(endf / dl);

            for (int i = 0; i < dx; i++)
            {
                if (i < beginx || i > dx - beginx || (i > endx && i < dx - endx))
                {
                    data1[i] = 0;
                    //dataimag1[i] = 0;
                }
            }

            TWFFT.IFFT(data1, dataimag1);
            int[] res = new int[k];
            for (int i = 0; i < k; i++)
            {
                res[i] = (int)data1[i];
            }
            return(res);
        }
        /// <summary>
        /// 频域修正
        /// </summary>
        /// <param name="data1"></param>
        /// <param name="begin1"></param>
        /// <param name="end1"></param>
        /// <param name="data2"></param>
        /// <param name="begin2"></param>
        /// <param name="end2"></param>
        /// <returns></returns>
        public static int[] MiddleFilterCorrection(int[] data1, int begin1, int end1, int[] data2, int begin2, int end2)
        {
            int[] res = new int[end1 - begin1];

            int k  = Math.Max(end1 - begin1, end2 - begin2);
            int dx = FToneAnalysis.getmin2x(k);

            //double dl = (double)NNAnalysis.samplingRate / dx;

            double[] fftdata1     = new double[dx];
            double[] fftdataimag1 = new double[dx];
            Array.Copy(data1, begin1, fftdata1, 0, Math.Min(k, end1 - begin1));
            TWFFT.FFT(fftdata1, fftdataimag1);

            double[] fftdata2     = new double[dx];
            double[] fftdataimag2 = new double[dx];
            Array.Copy(data2, begin2, fftdata2, 0, Math.Min(k, end2 - begin2));
            TWFFT.FFT(fftdata2, fftdataimag2);

            int num = 15;

            double[] lineori1 = new double[dx];
            double[] lineori2 = new double[dx];
            for (int i = 0; i < dx; i++)
            {
                lineori1[i] = Math.Abs(fftdata1[i]);
                lineori2[i] = Math.Abs(fftdata2[i]);
                //lineori1[i] = Math.Sqrt(Math.Pow(fftdata1[i], 2) + Math.Pow(fftdataimag1[i], 2));
                //lineori2[i] = Math.Sqrt(Math.Pow(fftdata2[i], 2) + Math.Pow(fftdataimag2[i], 2));
            }
            double[] line1 = FToneAnalysis.MiddleFilter(lineori1, num);
            //double[] linei1 = FToneAnalysis.MiddleFilter(fftdataimag1, num);
            double[] line2 = FToneAnalysis.MiddleFilter(lineori2, num);
            //double[] linei2 = FToneAnalysis.MiddleFilter(fftdataimag2, num);
            for (int i = 0; i < line1.Length; i++)
            {
                //Complex c1 = new Complex(fftdata1[i], fftdataimag1[i]);
                //Complex cl1 = new Complex(line1[i], linei1[i]);
                //Complex cl2 = new Complex(line2[i], linei2[i]);
                //c1 = c1.Multiply(cl1.Division(cl2));
                fftdata1[i] = (int)((double)fftdata1[i] * (line2[i] / line1[i]));
                //fftdataimag1[i] += (int)(linei2[i]-linei1[i]);
            }
            for (int i = dx / 4; i < dx / 2; i++)
            {
                if (line2[i] < line1[i])
                {
                    fftdata1[i]      = fftdata2[i];
                    fftdata1[dx - i] = fftdata2[dx - i];
                }
            }

            TWFFT.IFFT(fftdata1, fftdataimag1);
            for (int i = 0; i < res.Length; i++)
            {
                res[i] = (int)fftdata1[i];
            }

            return(res);
        }
        /// <summary>
        /// 用倒谱获得频谱包络
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private static double[] GetEnvelopeFD(double[] data)
        {
            int n = data.Length;

            double[] data1  = new double[n];
            double[] data1i = new double[n];
            for (int i = 0; i < n; i++)
            {
                data1[i] = Math.Log(data[i]);
            }
            for (int i = 0; i < n; i++)
            {
                data1i[i] = 0;
            }
            TWFFT.FFT(data1, data1i);
            double therehold = 100;

            double[] data2  = new double[n];
            double[] data2i = new double[n];
            // 低通滤波
            for (int i = 0; i < n; i++)
            {
                if (i < therehold || i > n - therehold)
                {
                    data2[i]  = data1[i];
                    data2i[i] = data1i[i];
                }
                else
                {
                    data2[i]  = 0;
                    data2i[i] = 0;
                }
            }
            //for (int i = 0; i < n; i++) data2i[i] = 0;
            TWFFT.IFFT(data2, data2i);
            var res = FToneAnalysis.MiddleFilter(data2, 5);

            for (int i = 0; i < n; i++)
            {
                res[i] = Math.Pow(Math.E, res[i]);
            }
            return(res);
        }
        private static void repairWaveShape(int[] oridata, int[] tardata)
        {
            int n = FToneAnalysis.getmin2x(oridata.Length);

            double[] odata  = new double[n];
            double[] odatai = new double[n];
            for (int i = 0; i < n; i++)
            {
                if (i < oridata.Length)
                {
                    odata[i] = oridata[i];
                }
                else
                {
                    odata[i] = 0;
                }
                odatai[i] = 0;
            }
            TWFFT.FFT(odata, odatai);
            double[] odatamod = new double[n];
            for (int i = 0; i < n; i++)
            {
                odatamod[i] = Math.Sqrt(odata[i] * odata[i] + odatai[i] * odatai[i]);
            }
            var odataenv = GetEnvelopeFD(odatamod);

            double[] tdata  = new double[n];
            double[] tdatai = new double[n];
            for (int i = 0; i < n; i++)
            {
                if (i < tardata.Length)
                {
                    tdata[i] = tardata[i];
                }
                else
                {
                    tdata[i] = 0;
                }
                tdatai[i] = 0;
            }
            TWFFT.FFT(tdata, tdatai);
            double[] tdatamod = new double[n];
            for (int i = 0; i < n; i++)
            {
                tdatamod[i] = Math.Sqrt(tdata[i] * tdata[i] + tdatai[i] * tdatai[i]);
            }
            var tdataenv = GetEnvelopeFD(tdatamod);

            for (int i = 1; i < n / 2; i++)
            {
                //if (odataenv[i] >= tdataenv[i]) continue;
                tdata[i]      = tdata[i] * (odataenv[i] / tdataenv[i]);
                tdatai[i]     = tdatai[i] * (odataenv[i] / tdataenv[i]);
                tdata[n - i]  = tdata[i];
                tdatai[n - i] = tdatai[i];
            }
            TWFFT.IFFT(tdata, tdatai);
            for (int i = 0; i < tardata.Length; i++)
            {
                tardata[i] = (int)tdata[i];
            }
        }
        private static int[] ChangePitResutltFD(int[] data, double dpit)
        {
            // 傅里叶点数必须2的倍数
            int n = FToneAnalysis.getmin2x(data.Length * 2);

            n = 4096;
            double[] ddata = new double[n];
            for (int i = 0; i < n; i++)
            {
                if (i < data.Length)
                {
                    ddata[i] = data[i];
                }
                else
                {
                    ddata[i] = 0;
                }
            }
            double[] ddatai = new double[n];
            for (int i = 0; i < n; i++)
            {
                ddatai[i] = 0;
            }
            TWFFT.FFT(ddata, ddatai);
            // ln(|X(n)|)
            double[] ddatalnmod = new double[n];
            for (int i = 0; i < n; i++)
            {
                ddatalnmod[i] = Math.Sqrt(ddata[i] * ddata[i] + ddatai[i] * ddatai[i]);
            }
            // 根据倒谱获取频谱包络,即声道滤波器
            var ddataenv = GetEnvelopeFD(ddatalnmod);

            // double[] ddataenv = new double[n];
            //for (int i = 0; i < n; i++) ddataenv[i] = Math.Pow(Math.E, ddatalnenv[i]);
            // 除以包络,得到激励谱
            double[] ddatabase  = new double[n];
            double[] ddataibase = new double[n];
            for (int i = 0; i < n; i++)
            {
                ddatabase[i] = ddata[i];                        /// ddataenv[i];
            }
            for (int i = 0; i < n; i++)
            {
                ddataibase[i] = ddatai[i];                        /// ddataenv[i];
            }
            // 拉伸激励谱,得到新基频下的激励谱
            double[] ddatabaser  = new double[n];
            double[] ddataibaser = new double[n];
            // 对称共轭,所以分两半分别压缩
            ddatabaser[0]  = ddatabase[0];
            ddataibaser[0] = ddataibase[0];
            //dpit = 1.4;
            for (int i = 1; i < n / 2; i++)
            {
                int j = (int)(i - 3000 * (dpit - 1));
                if (j < 1 || j >= n / 2)
                {
                    ddatabaser[i]  = 0;
                    ddataibaser[i] = 0;
                }
                else
                {
                    ddatabaser[i]  = ddatabase[j];
                    ddataibaser[i] = ddataibase[j];
                }
                ddatabaser[n - i]  = ddatabaser[i];
                ddataibaser[n - i] = -ddataibaser[i];
            }
            //for(int i = 1; i <= n/2; i++)
            //{
            //    ddatabaser[i] = getResampleValue(ddatabase, (double)i / dpit);
            //    ddatabaser[n - i] = ddatabaser[i];
            //    ddataibaser[i] = getResampleValue(ddataibase, (double)i / dpit);
            //    ddataibaser[n - i] = -ddataibaser[i];
            //}
            // 激励谱与包络相乘,重建频谱
            double[] ddatar  = new double[n];
            double[] ddatair = new double[n];
            for (int i = 0; i < n; i++)
            {
                ddatar[i] = ddatabaser[i];                        //* ddataenv[i];
            }
            for (int i = 0; i < n; i++)
            {
                ddatair[i] = ddataibaser[i];                         //* ddataenv[i];
            }
            TWFFT.IFFT(ddatar, ddatair);
            // int结果
            int[] datar = new int[data.Length];
            for (int i = 0; i < data.Length; i++)
            {
                datar[i] = (int)ddatar[i];
            }
            return(datar);
        }