예제 #1
0
        public static void ComputePSD(List <List <double> > data, int fs, int N, double Nw, double Nover, int Nzp, DetectorWindowType windowtype, out List <List <double> > dataInFreqDomain, out List <double> freqAll)
        {
            double[] win;

            switch (windowtype)
            {
            case Core.Models.DetectorWindowType.hann:
                win = Window.Hann((int)Nw);
                break;

            case Core.Models.DetectorWindowType.rectwin:
                win = _rectwin((int)Nw);
                break;

            case Core.Models.DetectorWindowType.bartlett:
                win = Window.Bartlett((int)Nw);
                break;

            case Core.Models.DetectorWindowType.hamming:
                win = Window.Hamming((int)Nw);
                break;

            case Core.Models.DetectorWindowType.blackman:
                win = Window.Blackman((int)Nw);
                break;

            default:
                throw new Exception(windowtype.ToString() + " is not an acceptable window type.");
            }
            var U = win.Sum(x => Math.Pow(x, 2));

            dataInFreqDomain = new List <List <double> >();

            //find the frequency vector which should be the x axis of the spectrum
            freqAll = new List <double>();
            for (int i = 0; i < Nzp; i++)
            {
                freqAll.Add((double)fs * i / Nzp);
            }

            //comput the number of segments: (signalLength - overlap)/(windowLength - overlap)
            //round towards zero
            var M = Math.Floor((N - Nover) / (Nw - Nover));

            foreach (var sig in data)
            {
                var newSig = new List <double>();
                var dat    = sig.GetRange(0, N);
                var mean   = dat.Average();
                foreach (var p in dat)
                {
                    var pp = p - mean;
                    newSig.Add(pp);
                }
                double[] Pxx = null;
                for (int i = 0; i < M; i++)
                {
                    var start = (int)(i * (Nw - Nover));
                    var end   = (int)(i * (Nw - Nover) + Nw);
                    //Console.WriteLine("start from " + start.ToString() + ", end at " + end.ToString());
                    //to match InspectionSpectral where mean is removed before calling pwelch
                    var frag = newSig.GetRange(start, (int)Nw);
                    //to match CalcPSD_OmegaB.m where mean is not removed from the data before calling fft
                    //var frag = dat.GetRange(start, (int)Nw);
                    //Console.WriteLine("number of point " + frag.Count());

                    //double[] real = null;
                    var fragcount = frag.Count;

                    //if (fragcount % 2 == 0)
                    //{
                    //    real = new double[fragcount + 2];
                    //    real[fragcount] = 0d;
                    //    real[fragcount + 1] = 0d;
                    //}
                    //else
                    //{
                    //    real = new double[fragcount + 1];
                    //    real[fragcount] = 0d;
                    //}
                    var complex = new Complex[Nzp];
                    //multiply with filter win first
                    for (int ii = 0; ii < frag.Count; ii++)
                    {
                        //real[ii] = frag[ii] * win[ii];
                        complex[ii] = new Complex(frag[ii] * win[ii], 0);
                    }
                    //might need an empty vector to hold results, or pass by ref?
                    //Console.WriteLine(frag[0]);
                    //var fragarray = frag.ToArray();
                    //Console.WriteLine("[{0}]", string.Join(", ", real));
                    //Fourier.ForwardReal(real, fragcount, FourierOptions.Matlab);
                    //Console.WriteLine("[{0}]", string.Join(", ", real));
                    //Console.WriteLine("[{0}]", string.Join(", ", complex));
                    Fourier.Forward(complex, FourierOptions.Matlab);
                    //Console.WriteLine("[{0}]", string.Join(", ", complex));
                    //Console.WriteLine("real: {0}, imaginary: {1}, magnitude: {2}", complex[0].Real, complex[0].Imaginary, complex[0].Magnitude);

                    if (Pxx == null)
                    {
                        Pxx = new double[complex.Length];
                    }

                    for (int ii = 0; ii < complex.Length; ii++)
                    {
                        Pxx[ii] = Pxx[ii] + (Math.Pow(complex[ii].Magnitude, 2) / (U * M));
                    }
                }
                //Pxx[0] = Pxx[0] / 2;
                dataInFreqDomain.Add(Pxx.ToList());
            }
        }
예제 #2
0
 public void Transform()
 {
     Fourier.Forward(_data, FourierOptions.Default);
     Fourier.Inverse(_data, FourierOptions.Default);
 }
예제 #3
0
        public static SpectralDecomp Decompose(
            IBGCStream stream,
            int windowCount   = 400,
            int windowOrder   = 12,
            int targetChannel = 0,
            double minFreq    = 0.0,
            double maxFreq    = double.PositiveInfinity)
        {
            //WindowSize is 2 ^ windowOrder
            int windowSize = 1 << windowOrder;

            if (stream.Channels <= targetChannel)
            {
                throw new ArgumentException(
                          $"TargetChannel ({targetChannel}) exceeded stream channels ({stream.Channels})",
                          nameof(targetChannel));
            }

            float[] samples = stream.IsolateChannel(targetChannel).Cache().Samples;

            int sampleOffset = (int)((samples.Length - windowSize) / (double)(windowCount - 1));

            //Adjust windowSize to conform to sample size and requirements
            while (sampleOffset <= 0 && windowOrder > 4)
            {
                --windowOrder;
                windowSize   = 1 << windowOrder;
                windowCount /= 2;
                sampleOffset = (int)((samples.Length - windowSize) / (double)(windowCount - 1));
            }

            if (windowOrder == 4)
            {
                throw new ArgumentException("Clip too short to evaluate");
            }

            if (maxFreq == double.PositiveInfinity)
            {
                //Default MaxFrequency to be determined by the size of the window
                maxFreq = FrequencyDomain.GetComplexSampleFrequency(windowSize, windowSize / 2);
            }

            //Limit Max Frquency by the size of the window
            maxFreq = Math.Min(maxFreq, FrequencyDomain.GetComplexSampleFrequency(windowSize, windowSize / 2));

            //Limit Min Frequency by the
            minFreq = Math.Max(minFreq, FrequencyDomain.GetComplexSampleFrequency(windowSize, 1));

            //Our output will be just the real-valued amplitudes
            SpectralDecomp decomp = new SpectralDecomp(minFreq, maxFreq, windowSize, windowCount);

            Complex64[] fftBuffer = new Complex64[windowSize];

            IBGCEnvelopeStream hammingWindow = new EnvelopeConcatenator(
                CosineEnvelope.HammingWindow(windowSize / 2, true),
                CosineEnvelope.HammingWindow(windowSize / 2, false));

            for (int window = 0; window < windowCount; window++)
            {
                int specificOffset = sampleOffset * window;
                hammingWindow.Reset();

                //Copy samples into buffer
                for (int i = 0; i < windowSize; i++)
                {
                    //Set real value
                    fftBuffer[i] = samples[specificOffset + i] * hammingWindow.ReadNextSample();
                }

                Fourier.Forward(fftBuffer);

                decomp.Add(window, fftBuffer);
            }

            return(decomp);
        }
예제 #4
0
        private void button1_Click(object sender, EventArgs e)  // Refresh
        {
            // Init Graphs
            double  intervals = 315; // "samples"
            double  mag       = 0;
            double  phase     = 0;
            double  w         = 0;
            double  scale     = 11;
            Complex i1        = new Complex(1, 0);
            Complex i2        = new Complex(0, 0);

            GlobalVar.refresh = 1;

            //Analog Plottage

            GAMag.Series[0].Points.Clear();
            GAPhase.Series[0].Points.Clear();

            // Analog Magnitude
            GAMag.ChartAreas[0].AxisX.Title = "Frequency (kHz)";
            GAMag.ChartAreas[0].AxisY.Title = "Magnitude (dB)";
            //GAMag.ChartAreas[0].AxisX.IsLogarithmic = true;
            GAMag.Series[0].LegendText        = "Magnitude";
            GAMag.Series[0].IsVisibleInLegend = false;

            // Analog Phase
            GAPhase.ChartAreas[0].AxisX.Title   = "Frequency (kHz)";
            GAPhase.ChartAreas[0].AxisY.Title   = "Phase";
            GAPhase.Series[0].IsVisibleInLegend = false;

            for (double n = 0; n < intervals; n = ++n)
            {
                w  = (2 * Math.PI * GlobalVar.samplef / intervals) * n;
                i2 = new Complex(0, w);  // i2 = 0 + jw
                // Mag = 20log(|Bandalog|)
                // Phase = Atan(Im(bandalog)/Re(bandalog)
                i1 = Bandalog(i2);                                                                 // s = jw

                mag = 20 * Math.Log10(Complex.Abs(i1));                                            // Log10!!!
                //Vector2 magpoints = [n / 2 * Math.PI, mag];
                GAMag.Series[0].Points.AddXY(Math.Round((n / (2 * Math.PI)) / scale, 2) + 1, mag); //Add x,y to chart
                //GAMag.ChartAreas[0].RecalculateAxesScale();

                phase = Math.Atan(i1.Imaginary / i1.Real);
                GAPhase.Series[0].Points.AddXY(Math.Round((n / (2 * Math.PI)) / scale, 2) + 1, phase); //Add x,y to chart
            }



            // Digital Plottage

            GDMag.Series[0].Points.Clear();
            GDPhase.Series[0].Points.Clear();

            // Init Graphs
            double  intervalz = 1000; // "samples"
            double  magz      = 0;
            double  phasez    = 0;
            Complex i3        = new Complex(1, 0);
            Complex i4        = new Complex(0, 0);

            // Digital Magnitude
            GDMag.ChartAreas[0].AxisX.Title   = "Frequency (kHz)";
            GDMag.ChartAreas[0].AxisY.Title   = "Magnitude (dB)";
            GDMag.Series[0].LegendText        = "Magnitude";
            GDMag.Series[0].IsVisibleInLegend = false; // Saves space

            // Digital Phase
            GDPhase.ChartAreas[0].AxisX.Title   = "Frequency (kHz)";
            GDPhase.ChartAreas[0].AxisY.Title   = "Phase";
            GDPhase.Series[0].IsVisibleInLegend = false; // Saves space

            Complex i5 = new Complex(0, 0);

            for (double j = 1; j < intervalz; ++j)  //  j = w from 0 -> pi
            {
                double dw = (Math.PI / (intervalz)) * j;
                i4 = new Complex(0, dw); // i4 = 0 + jw
                i5 = Complex.Exp(i4);    // i5 = e^jw = s
                // Mag = 20log(|Bandigital|)
                // Phase = Atan(Im(bandigital)/Re(bandigital)
                i3 = Bandigital(i5);

                magz = 20 * Math.Log10(Complex.Abs(i3));                                                                       // Log10!!!
                GDMag.Series[0].Points.Add(new DataPoint(Math.Round(GlobalVar.samplef * dw / (2 * Math.PI) / 1000, 3), magz)); // add x,y values

                phasez = Math.Atan(i3.Imaginary / i3.Real);
                GDPhase.Series[0].Points.Add(new DataPoint(Math.Round(GlobalVar.samplef * dw / (2 * Math.PI) / 1000, 3), phasez)); // add x,y values
            }


            // Realisations

            GIn1.Series[0].Points.Clear();
            GIn2.Series[0].Points.Clear();
            GOut1.Series[0].Points.Clear();
            GOut2.Series[0].Points.Clear();
            GFFT1.Series[0].Points.Clear();
            GFFT2.Series[0].Points.Clear();

            // Direct Realisation

            int    dintervals = 1000;
            double sineinputA = 0;

            //double[] inputA;
            //double[] outputA1;
            //double[] outputA2;
            double[] num = { 0.298534, 0.348534, 0.952554, 0.68258, 0.952554, 0.348534, 0.298534 };
            double[] den = { 1, 0.748427, 0.876976, 0.544886, 0.690464, 0.086335, -0.065264 };



            GIn1.ChartAreas[0].AxisX.Title   = "Time (s)";
            GIn1.ChartAreas[0].AxisY.Title   = "Amplitude";
            GIn1.Series[0].IsVisibleInLegend = false; // Saves space

            GOut1.ChartAreas[0].AxisX.Title   = "Time (s)";
            GOut1.ChartAreas[0].AxisY.Title   = "Amplitude";
            GOut1.Series[0].IsVisibleInLegend = false; // Saves space

            GIn2.ChartAreas[0].AxisX.Title   = "Time (s)";
            GIn2.ChartAreas[0].AxisY.Title   = "Amplitude";
            GIn2.Series[0].IsVisibleInLegend = false; // Saves space

            for (int oloop = 1; oloop < dintervals; oloop++)
            {
                GlobalVar.outputA1[oloop] = 0;
                sineinputA = findinputA(oloop);
                GlobalVar.inputA[oloop] = sineinputA;

                for (int iloop = 1; oloop - iloop > 1 && iloop <= 7; iloop++) //Realisation 1
                {
                    GlobalVar.outputA1[oloop] += num[iloop - 1] * GlobalVar.inputA[oloop - iloop] - den[iloop - 1] * GlobalVar.inputA[oloop];
                }

                GlobalVar.compinputA1[oloop]  = new Complex(GlobalVar.inputA[oloop], 0);
                GlobalVar.compoutputA1[oloop] = new Complex(GlobalVar.outputA1[oloop], 0);

                GIn1.Series[0].Points.Add(new DataPoint(oloop, GlobalVar.inputA[oloop]));
                GOut1.Series[0].Points.Add(new DataPoint(oloop, GlobalVar.outputA1[oloop]));
                GIn2.Series[0].Points.Add(new DataPoint(oloop, GlobalVar.inputA[oloop]));
                GOut2.Series[0].Points.Add(new DataPoint(oloop, GlobalVar.outputA1[oloop]));
            }

            GFFT1.Series[0].Points.Clear();

            Fourier.Forward(GlobalVar.compinputA1);
            for (int q = 0; q < dintervals; q++)
            {
                GFFT1.ChartAreas[0].AxisX.Title   = "Frequency (Hz)";
                GFFT1.ChartAreas[0].AxisY.Title   = "Amplitude";
                GFFT1.Series[0].IsVisibleInLegend = false; // Saves space
                GFFT1.ChartAreas[0].AxisY.Minimum = 0;
                GFFT1.ChartAreas[0].AxisX.Minimum = 0;
                GFFT1.ChartAreas[0].AxisX.Maximum = 5500;

                GFFT2.ChartAreas[0].AxisX.Title   = "Frequency (Hz)";
                GFFT2.ChartAreas[0].AxisY.Title   = "Amplitude";
                GFFT2.Series[0].IsVisibleInLegend = false; // Saves space
                GFFT2.ChartAreas[0].AxisY.Minimum = 0;
                GFFT2.ChartAreas[0].AxisX.Minimum = 0;
                GFFT2.ChartAreas[0].AxisX.Maximum = 5500;

                if (20 * Math.Log10(GlobalVar.compoutputA1[q].Magnitude) > 0)
                {
                    GFFT1.Series[0].Points.Add(new DataPoint(GlobalVar.samplef / dintervals * q, 20 * Math.Log10(GlobalVar.compinputA1[q].Magnitude)));
                    GFFT2.Series[0].Points.Add(new DataPoint(GlobalVar.samplef / dintervals * q, 20 * Math.Log10(GlobalVar.compinputA1[q].Magnitude)));
                }
                else
                {
                    GFFT1.Series[0].Points.Add(new DataPoint(GlobalVar.samplef / dintervals * q, 0));
                    GFFT2.Series[0].Points.Add(new DataPoint(GlobalVar.samplef / dintervals * q, 0));
                }
            }

            // Cascade Realisation


            GOut2.ChartAreas[0].AxisX.Title   = "Time (s)";
            GOut2.ChartAreas[0].AxisY.Title   = "Amplitude";
            GOut2.Series[0].IsVisibleInLegend = false; // Saves space

            double[] cnum1 = { -0.133277, 1 };
            double[] cden1 = { 0.184704, -0.0944 };
            double[] cnum2 = { 0.407766, 1 };
            double[] cden2 = { 1.217628, 0.848231 };
            double[] cnum3 = { 0.893, 1 };
            double[] cden3 = { -0.653845, 0.815172 };
            double   nmult = 2.629;
            double   temp  = 0;
            double   temp1 = 0;
            double   temp2 = 0;
            double   temp3 = 0;

            for (int jloop = 1; jloop < dintervals; jloop++)
            {
                GlobalVar.outputA1[jloop] = 0;
                sineinputA = findinputA(jloop);
                GlobalVar.inputA[jloop] = sineinputA;
                temp = 0;

                for (int kloop = 2; jloop - kloop > 1 && kloop >= 0; kloop--)
                {
                    //temp1 += cnum1[kloop] * GlobalVar.inputA[jloop - kloop] - cden1[kloop] * GlobalVar.inputA[jloop];
                }

                temp = temp1;

                for (int lloop = 2; jloop - lloop > 1 && lloop >= 0; lloop--)
                {
                    //temp3 += cnum2[lloop] * GlobalVar.inputA[jloop] - cden2[jloop-lloop] * GlobalVar.inputA[jloop-1];
                }

                temp += temp2;

                for (int mloop = 2; jloop - mloop > 1 && mloop >= 0; mloop--)
                {
                    //temp3 += cnum3[mloop] * GlobalVar.inputA[jloop] - cden3[jloop - mloop] * GlobalVar.inputA[jloop-1];
                    GlobalVar.outputA2[jloop] += 0 * temp3;
                    temp = temp3;
                }

                temp += temp3;

                GlobalVar.outputA2[jloop] += nmult * temp;
                GOut1.Series[0].Points.Add(new DataPoint(jloop, GlobalVar.outputA2[jloop]));
            }
        }
        public override int Read(float[] data, int offset, int count)
        {
            if (!initialized)
            {
                Initialize();
            }

            int samplesWritten = ReadBody(data, offset, count);

            while (samplesWritten < count)
            {
                int read = stream.Read(inputBuffer, 0, inputBuffer.Length);

                if (read <= 0)
                {
                    //Done, No samples left to work with
                    break;
                }

                //Slide output samples over to accumulate on the remainder
                Array.Copy(
                    sourceArray: outputAccumulation,
                    sourceIndex: bufferCount,
                    destinationArray: outputAccumulation,
                    destinationIndex: 0,
                    length: outputAccumulation.Length - bufferCount);

                Array.Clear(
                    array: outputAccumulation,
                    index: outputAccumulation.Length - bufferCount,
                    length: bufferCount);

                bufferIndex = 0;
                bufferCount = Channels * samplesPerOverlap;


                if (read < inputBuffer.Length)
                {
                    //Copy all the remaining samples
                    //We are guaranteed to have enough room because the output buffer's
                    //length is Channels * (inputBuffer.Length + fftLength)
                    bufferCount = Channels * (read + filterLength - 1);
                    //Set rest of inputBuffer to zero
                    Array.Clear(inputBuffer, read, inputBuffer.Length - read);
                }

                for (int i = 0; i < samplesPerOverlap; i++)
                {
                    fftBuffer[i] = inputBuffer[i];
                }

                Array.Clear(fftBuffer, samplesPerOverlap, fftLength - samplesPerOverlap);

                //FFT
                Fourier.Forward(fftBuffer);

                for (int channel = 0; channel < Channels; channel++)
                {
                    for (int i = 0; i < fftLength; i++)
                    {
                        ifftBuffer[i] = fftBuffer[i] * filterFD[channel][i];
                    }

                    //IFFT
                    Fourier.Inverse(ifftBuffer);

                    //Accumualte the window samples
                    for (int i = 0; i < fftLength; i++)
                    {
                        outputAccumulation[Channels * i + channel] += (float)ifftBuffer[i].Real;
                    }
                }

                samplesWritten += ReadBody(data, offset + samplesWritten, count - samplesWritten);
            }

            return(samplesWritten);
        }
        private void showChart(object sender, EventArgs e)
        {
            var complexData = new Complex[N];

            try
            {
                string[] strArrayData = message.Split(',');// カンマで分割

                if (strArrayData.Length == 5)
                {
                    //ゼロ点調整
                    if (checkBox_zeroset.Checked && flag_zeroset == true)
                    {
                        for (int i = 1; i < strArrayData.Length; i++)
                        {
                            ZeroData[i] = Math.Round(Convert.ToDouble(strArrayData[i]), order);
                        }
                        //label_Free.Text = "Zero pos.: " + ZeroData[1] + ", " + ZeroData[2] + ", " + ZeroData[3] + ", " + ZeroData[4];

                        if (ZeroData[4] < 20)// ゼロ点調整を終わらせる条件
                        {
                            flag_zeroset = false;
                        }
                    }

                    for (int i = 1; i < strArrayData.Length; i++)
                    {
                        originalData[i] = Math.Round(Convert.ToDouble(strArrayData[i]), order); // 小数第5位までに四捨五入
                        data[i]         = originalData[i] - ZeroData[i];                        // ゼロ点からの差分をデータとする

                        // 複素数データに変換し、追加
                        complexData[dataPointNum] = new Complex(Convert.ToDouble(strArrayData[1]), 0);
                    }

                    // データの個数カウント
                    dataPointNum++;
                    label_Free.Text = "point num:" + dataPointNum;

                    z_old = z;//自動ゼロ点更新用

                    //4次元データを三次元データに変換
                    x_raw = data[3] + data[4] - data[1] - data[2];
                    y_raw = data[1] + data[4] - data[2] - data[3];
                    z_raw = data[1] + data[2] + data[3] + data[4];// 押下度合いの計算

                    x = (int)(x_raw * amp);
                    y = (int)(y_raw * amp);
                    z = (int)(z_raw * amp);// 押下度合いの計算

                    //解像度設定に合わせる
                    x = (int)(Convert.ToDouble(x_reso - 1 - x_origin) * x / (x_max * amp));
                    y = (int)(Convert.ToDouble(y_reso - 1 - y_origin) * y / (y_max * amp));
                    z = (int)(Convert.ToDouble(z_reso - 1 - z_origin) * z / (z_max * amp));

                    //overflow check
                    if (x < 0 - x_origin)
                    {
                        x = 0 - x_origin;
                    }
                    if (x > x_reso - 1)
                    {
                        x = x_reso - 1;
                    }
                    if (y < 0 - y_origin)
                    {
                        y = 0 - y_origin;
                    }
                    if (y > y_reso - 1)
                    {
                        y = y_reso - 1;
                    }
                    if (z < 0 - z_origin)
                    {
                        z = 0 - z_origin;
                    }
                    if (z > z_reso - 1)
                    {
                        z = z_reso - 1;
                    }

                    /***
                     * //自動ゼロ点更新
                     * if (checkBox_zeroset.Checked)
                     * {
                     *  if (Math.Abs(z_old - z) < reset_diff)// 前回差分が規定値未満の状況が…
                     *  {
                     *      resetcounter++;
                     *  }
                     *  else
                     *  {
                     *      resetcounter = 0;
                     *  }
                     *
                     *  if (resetcounter > reset_count)// 規定ステップ連続すればゼロ点調整のフラグをオンにする
                     *  {
                     *      flag_zeroset = true;
                     *      resetcounter = 0;
                     *  }
                     * }***/

                    double CH0 = Convert.ToDouble(data[1]);
                    //double y = Convert.ToDouble(strArrayData[1]);// CH0のインダクタンス値
                    double time = Convert.ToDouble(strArrayData[0]);// 時間
                    chart1.Series[legend1].Points.AddXY(time, CH0);

                    // グラフの横軸の表示範囲設定
                    chart1.ChartAreas[0].AxisX.Maximum = time;
                    chart1.ChartAreas[0].AxisX.Minimum = time - displayTime;// 何秒前のデータまで表示するか

                    // logの作成
                    if (flag_log)
                    {
                        string logmsg = strArrayData[1] + "," + strArrayData[2] + "," + strArrayData[3] + "," + strArrayData[4];// CSVファイルに書き込み
                        logging.write(logmsg);
                    }
                }

                //if (dataPointNum+1 == Math.Pow(Math.Floor(Math.Sqrt(dataPointNum+1)), 2))// 平方数になっているかどうかの確認
                if (dataPointNum == N)                                    // データ数がNならFFT実行
                {
                    Fourier.Forward(complexData, FourierOptions.Default); // FFT実行
                    dataPointNum = 0;                                     // データの個数のカウントのリセット
                }



                // グラフの描画設定
                chart1.Series[legend1].IsVisibleInLegend   = false;                // 凡例表示設定
                chart1.Series[legend1].IsValueShownAsLabel = false;                // データラベル表示設定
                chart1.Series[legend1].ChartType           = SeriesChartType.Line; // 折れ線グラフを指定
                chart1.Series[legend1].BorderWidth         = 2;                    // 折れ線グラフの幅を指定
                chart1.Series[legend1].Color       = Color.FromArgb(243, 152, 0);  // RGBでグラフの色を指定
                chart1.ChartAreas[0].AxisY.Maximum = 0.1;                          // Y軸の最大値指定
                chart1.ChartAreas[0].AxisY.Minimum = -0.05;                        // Y軸の最小値指定
            }
            catch { }
        }
예제 #7
0
        private void GetRMS()
        {
            int len1 = _sample.Length; //获取数据个数,默认应为3个

            _rms = new double[len1];   //每个位置的加权加速度均方根值
            //double _ratio = _sampleFreq / Nfft;//频域分辨率
            for (int i = 0; i < len1; i++)
            {
                _rms[i] = 0;
                double[] aj         = new double[23];
                double[] aw         = new double[23];
                double[] sampleCopy = _sample[i];
                int      len        = _sample[i].Length;
                double   _ratio     = (double)len / Nfft;

                if (len > 0)
                {
                    double[] data;
                    double[] imag;
                    data = _sample[i];
                    imag = new double[len];
                    Fourier.Forward(data, imag, FourierOptions.Default);//FFT结果也保存在data里
                    double[] wj = new double[23];

                    if (_rank == 1)
                    {
                        switch (i)
                        {
                        case 1:
                        case 2:
                            wj = wd;
                            break;

                        case 3:
                            wj = wk;
                            break;

                        default:
                            wj = wd;
                            break;
                        }
                    }
                    else if (_rank == 2)
                    {
                        switch (i)
                        {
                        case 4:
                            wj = wc;
                            break;

                        case 5:
                        case 6:
                            wj = wd;
                            break;

                        default:
                            wj = wd;
                            break;
                        }
                    }
                    else
                    {
                        wj = wk;
                    }

                    for (int j = 0; j < aj.Length; j++)
                    {
                        aj[j] = 0;
                        aw[j] = 0;
                        int _freqDown = (int)Math.Floor(freqlimit[j] / _ratio);
                        int _freqUp   = (int)Math.Floor(freqlimit[j + 1] / _ratio);
                        if (_freqDown < data.Length && _freqDown < _freqUp)
                        {
                            if (_freqUp > data.Length)
                            {
                                _freqUp = data.Length;
                            }
                            for (int k = _freqDown; k < _freqUp; k++)
                            {
                                aj[j] += Math.Pow(data[k], 2);       //周期法自功率谱计算包括在内
                            }
                            aj[j] = Math.Pow((aj[j] * _ratio), 0.5); //计算中心频率为fj的1/3倍频程加速度均方根值
                        }
                        aw[j] = Math.Pow(wj[j] * aj[j] / 1000, 2);
                    }
                    _rms[i] = Math.Pow(aw.Sum(), 0.5);//单轴向加权加速度均方根值
                }
            }
            _rmsN = _rms;
            _xRms = _rms[0];
            _yRms = _rms[1];
            _zRms = _rms[2];
        }
예제 #8
0
        protected override void _Initialize()
        {
            int fftBufferSize = _channelSamples.CeilingToPowerOfTwo();

            fftBuffer = new Complex64[fftBufferSize];

            double effectiveDuration = fftBufferSize / SamplingRate;

            double t_step     = effectiveDuration / (2.0 * Math.Round(maxTemporalVelocity * effectiveDuration));
            int    t_env_size = 2 * (int)Math.Round(effectiveDuration / (2.0 * t_step));

            double[] carrierFrequencies;

            switch (componentSpacing)
            {
            case ComponentSpacing.Harmonic:
            {
                int componentLB = (int)Math.Round(lowestFrequency / frequencySpacing);
                int componentUB = (int)Math.Round(lowestFrequency * Math.Pow(2, componentBandwidth) / frequencySpacing) + 1;

                int componentCount = componentUB - componentLB;
                carrierFrequencies = new double[componentCount];

                for (int n = 0; n < componentCount; n++)
                {
                    carrierFrequencies[n] = frequencySpacing * (n + componentLB);
                }
            }
            break;

            case ComponentSpacing.Log:
            {
                int componentUB = (int)(Math.Round(2 * componentBandwidth / frequencySpacing) / 2);

                carrierFrequencies = new double[componentUB];

                for (int n = 0; n < componentUB; n++)
                {
                    carrierFrequencies[n] = lowestFrequency * Math.Pow(2.0, n * frequencySpacing);
                }
            }
            break;

            default:
                UnityEngine.Debug.LogError($"Unexpected ComponentSpacing: {componentSpacing}");
                goto case ComponentSpacing.Log;
            }

            int f_env_size = carrierFrequencies.Length;

            double[] t_env_phases_sin = new double[t_env_size];
            double[] t_env_phases_cos = new double[t_env_size];

            double t_env_phase;
            double t_env_phase_factor = 2.0 * Math.PI * temporalModulationRate;

            for (int t = 0; t < t_env_size; t++)
            {
                t_env_phase         = t * t_env_phase_factor * t_step;
                t_env_phases_sin[t] = Math.Sin(t_env_phase);
                t_env_phases_cos[t] = Math.Cos(t_env_phase);
            }

            double value;
            double f_env_phase;
            double f_env_phase_factor = 2.0 * Math.PI * spectralModulationRate;
            double f_env_phase_offset = 0.5 * Math.PI;
            double f_env_phase_sin;
            double f_env_phase_cos;

            Complex64[] complexProfile = new Complex64[t_env_size];
            for (int c = 0; c < f_env_size; c++)
            {
                int f_index = (int)Math.Round(carrierFrequencies[c] * effectiveDuration);
                f_env_phase     = Math.Log(carrierFrequencies[c] / lowestFrequency, 2.0) * f_env_phase_factor + f_env_phase_offset;
                f_env_phase_sin = Math.Sin(f_env_phase);
                f_env_phase_cos = Math.Cos(f_env_phase);

                for (int t = 0; t < t_env_size; t++)
                {
                    value             = f_env_phase_sin * t_env_phases_cos[t] + f_env_phase_cos * t_env_phases_sin[t];
                    complexProfile[t] = Math.Pow(10.0, modulationDepth * value / 20.0);
                }

                Fourier.Forward(complexProfile);
                FFTShift(complexProfile);

                double componentPhase = 2.0 * Math.PI * randomizer.NextDouble();
                for (int t = 0; t < t_env_size; t++)
                {
                    complexProfile[t] *= Complex64.FromPolarCoordinates(
                        magnitude: fftBufferSize / (2.0 * t_env_size),
                        phase: componentPhase);
                }

                int leftPad  = f_index - (t_env_size / 2) - 1;
                int rightPad = (fftBufferSize / 2) - f_index - (t_env_size / 2);

                if (leftPad >= 0 && rightPad >= 0)
                {
                    for (int i = 0; i < t_env_size; i++)
                    {
                        int index = i + leftPad + 1;
                        fftBuffer[index] += complexProfile[i];
                        fftBuffer[fftBufferSize - index] += complexProfile[i].Conjugate();
                    }
                }
                else if (leftPad < 0 && rightPad > 0)
                {
                    for (int i = -leftPad; i < t_env_size; i++)
                    {
                        int index = i + leftPad + 1;
                        fftBuffer[index] += complexProfile[i];
                        fftBuffer[fftBufferSize - index] += complexProfile[i].Conjugate();
                    }
                }
                else if (leftPad > 0 && rightPad < 0)
                {
                    for (int i = 0; i < t_env_size + rightPad; i++)
                    {
                        int index = i + leftPad + 1;
                        fftBuffer[index] += complexProfile[i];
                        fftBuffer[fftBufferSize - index] += complexProfile[i].Conjugate();
                    }
                }
            }

            Fourier.Inverse(fftBuffer);
        }
예제 #9
0
        /// <summary>
        /// The internal core method for calculating the autocorrelation.
        /// </summary>
        /// <param name="x">The data array to calculate auto correlation for</param>
        /// <param name="k_low">Min lag to calculate ACF for (0 = no shift with acf=1) must be zero or positive and smaller than x.Length</param>
        /// <param name="k_high">Max lag (EXCLUSIVE) to calculate ACF for must be positive and smaller than x.Length</param>
        /// <returns>An array with the ACF as a function of the lags k.</returns>
        private static double[] AutoCorrelationFft(IEnumerable <double> x, int k_low, int k_high)
        {
            if (x == null)
            {
                throw new ArgumentNullException(nameof(x));
            }

            int N = x.Count();    // Sample size

            if (k_low < 0 || k_low >= N)
            {
                throw new ArgumentOutOfRangeException(nameof(k_low), "kMin must be zero or positive and smaller than x.Length");
            }
            if (k_high < 0 || k_high >= N)
            {
                throw new ArgumentOutOfRangeException(nameof(k_high), "kMax must be positive and smaller than x.Length");
            }

            if (N < 1)
            {
                return(new double[0]);
            }

            int nFFT = Euclid.CeilingToPowerOfTwo(N) * 2;

            Complex[] x_fft  = new Complex[nFFT];
            Complex[] x_fft2 = new Complex[nFFT];

            double x_dash  = Statistics.Mean(x);
            double xArrNow = 0.0d;

            using (IEnumerator <double> iex = x.GetEnumerator())
            {
                for (int ii = 0; ii < nFFT; ii++)
                {
                    if (ii < N)
                    {
                        if (!iex.MoveNext())
                        {
                            throw new ArgumentOutOfRangeException(nameof(x));
                        }
                        xArrNow   = iex.Current;
                        x_fft[ii] = new Complex(xArrNow - x_dash, 0.0);    // copy values in range and substract mean
                    }
                    else
                    {
                        x_fft[ii] = new Complex(0.0, 0.0);      // pad all remaining points
                    }
                }
            }

            Fourier.Forward(x_fft, FourierOptions.Matlab);

            // maybe a Vector<Complex> implementation here would be faster
            for (int ii = 0; ii < x_fft.Length; ii++)
            {
                x_fft2[ii] = Complex.Multiply(x_fft[ii], Complex.Conjugate(x_fft[ii]));
            }

            Fourier.Inverse(x_fft2, FourierOptions.Matlab);

            double acf_Val1 = x_fft2[0].Real;

            double[] acf_Vec = new double[k_high - k_low + 1];

            // normalize such that acf[0] would be 1.0
            for (int ii = 0; ii < (k_high - k_low + 1); ii++)
            {
                acf_Vec[ii] = x_fft2[k_low + ii].Real / acf_Val1;
            }

            return(acf_Vec);
        }
예제 #10
0
        public DigitalAudio Embed(DigitalAudio cover, byte[] message)
        {
            BitArray embeddingMessage = CreateEmbeddedMessage(message);
            var      msgLength        = embeddingMessage.Length;
            // Create embeddingMessage
            var value = (float)(Math.PI / 2.0);

            float[] embeddingData = new float[msgLength];
            for (int i = 0; i < msgLength; i++)
            {
                if (embeddingMessage[i])
                {
                    embeddingData[i] = -value;
                }
                else
                {
                    embeddingData[i] = value;
                }
            }

            // Signal
            var coverSignal   = cover.GetSignal();
            var ComplexSignal = coverSignal.Select(x => new Complex32(x, 0)).ToArray();

            double ratio = cover.SamplesInChannel / segmentLength;
            int    N     = (int)Math.Floor(ratio); //Segmnets count
            //---------------------------------------------
            List <Complex32[]> signalSegments = new List <Complex32[]>(N);
            List <float[]>     phases         = new List <float[]>(N);
            List <float[]>     magnitude      = new List <float[]>(N);
            List <float[]>     deltaPhases    = new List <float[]>(N);

            for (int seg = 0; seg < N; seg++)
            {
                //----------Create-----
                signalSegments.Add(new Complex32[segmentLength]);
                phases.Add(new float[segmentLength]);
                magnitude.Add(new float[segmentLength]);
                deltaPhases.Add(new float[segmentLength]);
                //---------------------
                //---Segments init---
                Array.Copy(ComplexSignal, seg * segmentLength, signalSegments[seg], 0, segmentLength); // Signal copy
                //---------------------
                //-------FFT----------
                Fourier.Forward(signalSegments[seg], FourierOptions.Matlab); // Signal transform for each segment
                //--------------------
                for (int j = 0; j < segmentLength; j++)
                {
                    phases[seg][j]    = signalSegments[seg][j].Phase;     //Phases for each segment
                    magnitude[seg][j] = signalSegments[seg][j].Magnitude; //Magnitude for each segment
                }
            }

            var spectrumMiddle = segmentLength / 2;

            // Delta phases
            for (int seg = 1; seg < N; seg++)
            {
                for (int j = 0; j < segmentLength; j++)
                {
                    deltaPhases[seg][j] = phases[seg][j] - phases[seg - 1][j];
                }
            }

            int startIndex         = spectrumMiddle - 1;
            int startSymmetryIndex = spectrumMiddle + 1;

            for (int i = 0; i < msgLength; i++)
            {
                phases[0][startIndex - i]         = embeddingData[i];
                phases[0][startSymmetryIndex + i] = -embeddingData[i]; // symmetry
            }
            // New phases
            for (int seg = 1; seg < N; seg++)
            {
                for (int j = 0; j < segmentLength; j++)
                {
                    phases[seg][j] = phases[seg - 1][j] + deltaPhases[seg][j];
                }
            }

            //Restore signal
            for (int seg = 0; seg < N; seg++)
            {
                for (int j = 0; j < segmentLength; j++)
                {
                    var A     = magnitude[seg][j];
                    var phase = phases[seg][j];
                    signalSegments[seg][j] = Complex32.FromPolarCoordinates(A, phase);
                }
                Fourier.Inverse(signalSegments[seg], FourierOptions.Matlab);
            }

            for (int i = 0; i < N; i++)
            {
                for (int j = 0; j < segmentLength; j++)
                {
                    coverSignal[segmentLength * i + j] = (int)signalSegments[i][j].Real;
                }
            }

            return(cover);
        }
예제 #11
0
 public static double[] FFT(double[] data)
 {
     Complex[] samples = (from x in data select new Complex(x, 0)).ToArray();
     Fourier.Forward(samples);
     return((from x in samples select x.Magnitude).ToArray());
 }
        public static Complex[] Transform(Complex[] functionPoints, string transformate)
        {
            var copyofFunctionsPoints = functionPoints;


            var copyofFunctionsPoints2 = new Complex[functionPoints.Length];
            var multidimensialArray    = new double[functionPoints.Length, 2];

            var jaggedArray = new double[functionPoints.Length][];

            for (var i = 0; i < functionPoints.Length; i++)
            {
                jaggedArray[i] = new double[2];
            }


            for (var i = 0; i < functionPoints.Length; i++)
            {
                jaggedArray[i][0]             = multidimensialArray[i, 0] = functionPoints[i].Real;
                jaggedArray[i][1]             =
                    multidimensialArray[i, 1] = functionPoints[i].Imaginary;
                copyofFunctionsPoints2[i]     = new Complex(functionPoints[i].Real,
                                                            copyofFunctionsPoints2[i].Imaginary);
            }


            switch (transformate)
            {
            case "FFT":
                Fourier.Forward(copyofFunctionsPoints);
                break;


            case "IFFT":
                Fourier.Inverse(copyofFunctionsPoints);
                break;

            case "DST":
                SineTransform.DST(jaggedArray);
                copyofFunctionsPoints = jaggedToComplex(jaggedArray);
                break;

            case "IDST":
                SineTransform.IDST(jaggedArray);
                copyofFunctionsPoints = jaggedToComplex(jaggedArray);
                break;

            case "DCT":
                CosineTransform.DCT(multidimensialArray);
                copyofFunctionsPoints = multidimensialToComplex(multidimensialArray);
                break;

            case "IDCT":
                CosineTransform.IDCT(multidimensialArray);
                copyofFunctionsPoints = multidimensialToComplex(multidimensialArray);
                break;

            case "DHT":
                HartleyTransform.DHT(multidimensialArray);
                copyofFunctionsPoints = multidimensialToComplex(multidimensialArray);
                break;

            case "FHT":
                HilbertTransform.FHT(copyofFunctionsPoints2,
                                     FourierTransform.Direction.Forward);
                copyofFunctionsPoints = copyofFunctionsPoints2;
                break;

            case "IFHT":
                HilbertTransform.FHT(copyofFunctionsPoints2,
                                     FourierTransform.Direction.Backward);
                copyofFunctionsPoints = copyofFunctionsPoints2;
                break;

            default:
                throw new ArgumentException("Unknown transformation!");
            }
            return(copyofFunctionsPoints); //athenia programuje//dididididi//di/kocham PaciA// JJKAKAKK  K
        }
예제 #13
0
        private void btnProcessAccelerationTimeSeries_Click(object sender, EventArgs e)
        {
            if ((bgwCalculate != null) && (bgwCalculate.IsBusy))
            {
                bgwCalculate.CancelAsync();
                return;
            }

            //simpleMultipleImagesShow imagesRepresentingForm = new simpleMultipleImagesShow();
            //imagesRepresentingForm.Show();



            DoWorkEventHandler bgwCalculate_DoWorkHandler = delegate(object currBGWsender, DoWorkEventArgs args)
            {
                BackgroundWorker selfWorker = currBGWsender as BackgroundWorker;

                //simpleMultipleImagesShow multImagesRepresentingForm = (simpleMultipleImagesShow)((args.Argument as object[])[0]);
                //Type theShowImagesType = multImagesRepresentingForm.GetType();
                //MethodInfo thePicturePlacingMethodInfo = theShowImagesType.GetMethod("PlaceAPicture");

                int imageRepresentingCounter = 0;

                DateTime dbgDT = new DateTime(2014, 7, 9, 9, 0, 0);
                dbgDT = dbgDT.AddMinutes(33);
                DateTime dtSeriesStart = accSubseries[0].StartTime;
                double   tsOverallSeriesDurationMillisec = (accSubseries[accSubseries.Count - 1].EndTime - accSubseries[0].StartTime).TotalMilliseconds;

                string strToWrite = " fileName ; lat ; lon ; date ; time ; time(s) since start ; period(s) ; spectrum amplitude";
                ServiceTools.logToTextFile(strOutputDirectory + "\\100sData-spectra-maximums.dat", strToWrite + Environment.NewLine, true);

                foreach (TimeSeries <double> accSubseria in accSubseries)
                {
                    if (selfWorker.CancellationPending)
                    {
                        break;
                    }

                    int startindex = 0;
                    while (true)
                    {
                        int endIndex;

                        if (selfWorker.CancellationPending)
                        {
                            break;
                        }

                        TimeSeries <double> currTimeSeria = accSubseria.SubSeria(startindex, new TimeSpan(1000000000),
                                                                                 out endIndex); //100s
                        currTimeSeria = currTimeSeria.InterpolateSeria(new TimeSpan(500000));
                        currTimeSeria = currTimeSeria.ExtractDataDeviationValues();

                        //обработать и оценить наличие выраженных периодов
                        Complex[] sourceSignalArray = currTimeSeria.DataRealValuesComplexArray();
                        Fourier.Forward(sourceSignalArray);
                        //Transform.FourierForward(sourceSignalArray);
                        List <Complex> FourierTransformedSignal           = new List <Complex>(sourceSignalArray);
                        List <double>  FourierTransformedSignalAmplitudes =
                            FourierTransformedSignal.ConvertAll <double>(
                                cVal =>
                                ((double.IsNaN(cVal.Magnitude)) || (double.IsInfinity(cVal.Magnitude)))
                                        ? (0.0d)
                                        : (cVal.Magnitude));
                        List <double> FourierTransformedSignalPeriods = new List <double>();
                        for (int ind = 0; ind < FourierTransformedSignalAmplitudes.Count; ind++)
                        {
                            FourierTransformedSignalPeriods.Add(currTimeSeria.TotalSeriaDuration.TotalSeconds /
                                                                (double)ind);
                        }

                        FourierTransformedSignalAmplitudes =
                            new List <double>(
                                FourierTransformedSignalAmplitudes.Zip <double, double, double>(
                                    FourierTransformedSignalPeriods,
                                    (amp, periodSec) =>
                                    ((double.IsNaN(periodSec)) || (double.IsInfinity(periodSec))) ? (0.0d) : (amp)));
                        FourierTransformedSignalPeriods =
                            FourierTransformedSignalPeriods.ConvertAll <double>(
                                dval => ((double.IsNaN(dval)) || (double.IsInfinity(dval))) ? (0.0d) : (dval));


                        //проанализируем этот участок - есть ли выраженные пики по амплитуде конкретных частот

                        //найти максимум в спектре и выдать данные об этом максимуме в файл

                        // сначала отфильтруем периоды меньше 1с - для данных по динамике судна они несущественны
                        FourierTransformedSignalAmplitudes =
                            new List <double>(
                                FourierTransformedSignalAmplitudes.Zip <double, double, double>(
                                    FourierTransformedSignalPeriods,
                                    (amp, periodSec) => (periodSec <= 1.0d) ? (0.0d) : (amp)));
                        FourierTransformedSignalPeriods =
                            FourierTransformedSignalPeriods.ConvertAll <double>(dVal => (dVal <= 1.0d) ? (0.0d) : (dVal));


                        DescriptiveStatistics currAmpsStat =
                            new DescriptiveStatistics(FourierTransformedSignalAmplitudes);
                        List <double> lAmpsOutstanding = FourierTransformedSignalAmplitudes.ConvertAll <double>(dVal =>
                        {
                            if (dVal / currAmpsStat.Mean >= 100.0d)
                            {
                                return(dVal);
                            }
                            return(0.0d);
                        });
                        List <double> lPeriodsOutstanding =
                            new List <double>(FourierTransformedSignalPeriods.Zip <double, double, double>(lAmpsOutstanding,
                                                                                                           (per, amp) => (amp == 0.0d) ? (0.0d) : (per)));


                        if (lAmpsOutstanding.Sum() > 0.0d)
                        {
                            MultipleScatterAndFunctionsRepresentation renderer =
                                new MultipleScatterAndFunctionsRepresentation(2048, 1536);

                            renderer.dvScatterXSpace.Add(currTimeSeria.TimeStampsValuesSeconds);
                            renderer.dvScatterFuncValues.Add(currTimeSeria.dvDoubleDataValues);
                            renderer.scatterLineColors.Add(new Bgr(255, 50, 50));
                            renderer.scatterDrawingVariants.Add(SequencesDrawingVariants.polyline);

                            renderer.dvScatterXSpace.Add(DenseVector.OfEnumerable(FourierTransformedSignalPeriods));
                            renderer.dvScatterFuncValues.Add(DenseVector.OfEnumerable(FourierTransformedSignalAmplitudes));
                            renderer.scatterLineColors.Add(new Bgr(50, 255, 50));
                            renderer.scatterDrawingVariants.Add(SequencesDrawingVariants.squares);

                            renderer.dvScatterXSpace.Add(DenseVector.OfEnumerable(lPeriodsOutstanding));
                            renderer.dvScatterFuncValues.Add(DenseVector.OfEnumerable(lAmpsOutstanding));
                            renderer.scatterLineColors.Add(new Bgr(50, 50, 255));
                            renderer.scatterDrawingVariants.Add(SequencesDrawingVariants.circles);

                            renderer.Represent();

                            if (strOutputDirectory != "")
                            {
                                double maxAmp       = lAmpsOutstanding.Max();
                                int    idx          = lAmpsOutstanding.FindIndex(dval => dval == maxAmp);
                                double maxAmpPeriod = lPeriodsOutstanding[idx];

                                GPSdata gpsMark = gpsSeriaData.GetMostClose(currTimeSeria.StartTime).Item2;

                                string fName = currTimeSeria.StartTime.ToString("s").Replace(":", "-") +
                                               "-100sData-spectrum.jpg";
                                renderer.SaveToImage(strOutputDirectory + "\\" + fName, true);

                                strToWrite  = "" + fName + " ; ";
                                strToWrite += gpsMark.LatDec + " ; ";
                                strToWrite += gpsMark.LonDec + " ; ";
                                strToWrite += currTimeSeria.StartTime.Date.ToString("yyyy-MM-dd") + " ; ";
                                strToWrite += currTimeSeria.StartTime.ToString("HH-mm-ss") + " ; ";
                                strToWrite += (currTimeSeria.StartTime - dtSeriesStart).TotalSeconds + " ; ";
                                strToWrite += maxAmpPeriod.ToString() + " ; ";
                                strToWrite += maxAmp.ToString() + " ; ";
                                ServiceTools.logToTextFile(strOutputDirectory + "\\100sData-spectra-maximums.dat", strToWrite + Environment.NewLine, true);

                                ThreadSafeOperations.SetText(lblStatusString, "processing: " + currTimeSeria.StartTime.ToString("s"), false);
                            }
                        }

                        if ((currTimeSeria.StartTime >= dbgDT) || (currTimeSeria.EndTime >= dbgDT))
                        {
                            startindex++;
                            startindex--;
                        }

                        if (endIndex == accSubseria.Count - 1)
                        {
                            break;
                        }

                        Application.DoEvents();

                        selfWorker.ReportProgress(Convert.ToInt32(100.0d * (currTimeSeria.EndTime - dtSeriesStart).TotalMilliseconds / tsOverallSeriesDurationMillisec));

                        startindex += Convert.ToInt32((endIndex - startindex) / 2.0d);
                    }
                }
            };

            RunWorkerCompletedEventHandler bgwCalculate_CompletedHandler = delegate(object currBGWCompletedSender, RunWorkerCompletedEventArgs args)
            {
                ThreadSafeOperations.ToggleButtonState(btnProcessAccelerationTimeSeries, true, "Process acceleration timeseries", false);
            };

            ProgressChangedEventHandler bgwCalculate_ProgressChanged = delegate(object bgwDataReaderSender, ProgressChangedEventArgs args)
            {
                ThreadSafeOperations.UpdateProgressBar(prbReadingProcessingData, args.ProgressPercentage);
            };



            ThreadSafeOperations.ToggleButtonState(btnProcessAccelerationTimeSeries, true, "STOP", true);

            bgwCalculate = new BackgroundWorker();
            bgwCalculate.WorkerSupportsCancellation = true;
            bgwCalculate.WorkerReportsProgress      = true;
            bgwCalculate.DoWork             += bgwCalculate_DoWorkHandler;
            bgwCalculate.RunWorkerCompleted += bgwCalculate_CompletedHandler;
            bgwCalculate.ProgressChanged    += bgwCalculate_ProgressChanged;
            //object[] bgwCalculateArgs = new object[] { imagesRepresentingForm };
            object[] bgwCalculateArgs = new object[] {  };

            bgwCalculate.RunWorkerAsync(bgwCalculateArgs);
        }
        public override int Read(float[] data, int offset, int count)
        {
            if (!initialized)
            {
                Initialize();
            }

            int samplesWritten = ReadBody(data, offset, count);

            while (samplesWritten < count)
            {
                //Slide over noise samples
                Array.Copy(
                    sourceArray: noiseBuffer,
                    sourceIndex: stepSize,
                    destinationArray: noiseBuffer,
                    destinationIndex: 0,
                    length: overlapSize);

                int read = stream.Read(inputBuffer, overlapSize, stepSize);

                if (read <= 0 && samplesHandled <= 0)
                {
                    //Done, No samples left to work with
                    break;
                }
                else if (read <= 0)
                {
                    //We are in buffer-dumping window
                    //Set rest of inputBuffer to zero
                    Array.Clear(inputBuffer, overlapSize, stepSize);
                }
                else if (read < stepSize)
                {
                    //Near or at the end
                    //Set rest of inputBuffer to zero
                    Array.Clear(inputBuffer, overlapSize + read, inputBuffer.Length - overlapSize - read);
                }

                //Generate new noise
                for (int i = 0; i < stepSize; i++)
                {
                    noiseBuffer[overlapSize + i] = noiseScalarA - noiseScalarB * randomizer.NextDouble();
                }

                //Copy in the input data
                for (int i = 0; i < fftSize; i++)
                {
                    signalFFTBuffer[i] = inputBuffer[i] * window[i];
                    noiseFFTBuffer[i]  = noiseBuffer[i];
                }

                //FFT
                Task.WaitAll(
                    Task.Run(() => Fourier.Forward(signalFFTBuffer)),
                    Task.Run(() => Fourier.Forward(noiseFFTBuffer)));

                //For each band...

                Parallel.For(
                    fromInclusive: 0,
                    toExclusive: bandFrequencies.Length - 1,
                    body: (int band) =>
                {
                    int lowerBound = FrequencyDomain.GetComplexFrequencyBin(fftSize, bandFrequencies[band], SamplingRate);
                    int upperBound = FrequencyDomain.GetComplexFrequencyBin(fftSize, bandFrequencies[band + 1], SamplingRate);

                    Complex64[] amplitudeBuffer = amplitudeBuffers[band];
                    Complex64[] noiseBandBuffer = noiseBandBuffers[band];

                    //Copy over band just the relevant frequency band
                    for (int i = lowerBound; i < upperBound; i++)
                    {
                        amplitudeBuffer[i] = 2.0 * signalFFTBuffer[i];
                        noiseBandBuffer[i] = 2.0 * noiseFFTBuffer[i];
                    }

                    Complex64 zero = Complex64.Zero;


                    //Clear rest of buffers
                    for (int i = 0; i < lowerBound; i++)
                    {
                        amplitudeBuffer[i] = zero;
                        noiseBandBuffer[i] = zero;
                    }

                    for (int i = upperBound; i < amplitudeBuffer.Length; i++)
                    {
                        amplitudeBuffer[i] = zero;
                        noiseBandBuffer[i] = zero;
                    }

                    //IFFT
                    Task.WaitAll(
                        Task.Run(() => Fourier.Inverse(amplitudeBuffer)),
                        Task.Run(() => Fourier.Inverse(noiseBandBuffer)));

                    for (int i = 0; i < amplitudeBuffer.Length; i++)
                    {
                        outputAccumulation[i] += outputFactor * window[i] * noiseBandBuffer[i].Real * amplitudeBuffer[i].Magnitude;
                    }
                });


                samplesHandled += read;

                if (--frameLag <= 0)
                {
                    bufferIndex     = 0;
                    bufferCount     = Math.Min(stepSize, samplesHandled);
                    samplesHandled -= bufferCount;

                    //Copy output samples to output buffer
                    for (int sample = 0; sample < bufferCount; sample++)
                    {
                        cachedSampleBuffer[sample] = (float)outputAccumulation[sample];
                    }
                }

                //Slide over input samples
                Array.Copy(
                    sourceArray: inputBuffer,
                    sourceIndex: stepSize,
                    destinationArray: inputBuffer,
                    destinationIndex: 0,
                    length: overlapSize);

                //Slide output samples
                Array.Copy(
                    sourceArray: outputAccumulation,
                    sourceIndex: stepSize,
                    destinationArray: outputAccumulation,
                    destinationIndex: 0,
                    length: overlapSize);

                //Clear empty output accumulation region
                Array.Clear(outputAccumulation, overlapSize, stepSize);

                samplesWritten += ReadBody(data, offset + samplesWritten, count - samplesWritten);
            }

            return(samplesWritten);
        }
예제 #15
0
 public void Transform()
 {
     Fourier.Forward(_data, FourierOptions.NoScaling);
     Fourier.Inverse(_data, FourierOptions.NoScaling);
 }
예제 #16
0
        private void Capture(AudioCapturedEventArgs e)
        {
            DataUtils.Normalize(e.Left.Buffer);
            DataUtils.Normalize(e.Right.Buffer);

            var a      = new Complex32[e.Left.Buffer.Length];
            var b      = new Complex32[e.Right.Buffer.Length];
            var sp1    = new Complex32[a.Length];
            var sp2    = new Complex32[b.Length];
            var window = Window.Hamming(a.Length);


            // Составляем комплексный массив и умножаем на окно Хэмминга
            for (int i = 0; i < a.Length; i++)
            {
                a[i] = new Complex32(e.Left.Buffer[i] * (float)window[i], 0);
                b[i] = new Complex32(e.Left.Buffer[i] * (float)window[i], 0);
            }

            // Преобразование фурье
            Fourier.Forward(a);
            Fourier.Forward(b);
            Array.Copy(a, sp1, a.Length);
            Array.Copy(b, sp2, b.Length);

            // Поэлементно умножаем первое на сопряженное ко второму
            for (int i = 0; i < a.Length; i++)
            {
                a[i] = a[i] * b[i].Conjugate();
            }


            // Поэлементно делим на модуль самого себя
            //for (int i = 0; i < a.Length; i++)
            //    a[i] = Complex32.Divide(a[i], a[i].Magnitude);

            //Fourier.Inverse(a);

            // Поиск максимума

            /*int maxI = 0;
             * float max = a[0].Imaginary;
             * for (int i = 0; i < a.Length; i++)
             * {
             *  if (Math.Abs(a[i].Imaginary) > max)
             *  {
             *      maxI = i;
             *      max = Math.Abs(a[i].Imaginary);
             *  }
             * }*/

            sgraphWave.Clear();
            sgraphSpectrum.Clear();

            for (int i = 0; i < e.Left.Buffer.Length; i++)
            {
                sgraphWave.AddData(i, e.Left.Buffer[i], e.Right.Buffer[i]);
            }

            for (int i = 0; i < a.Length / 10; i++)
            {
                float hz = i * e.Left.Source.WaveFormat.SampleRate / (float)a.Length;
                //sgraphSpectrum.AddData(hz, sp1[i].Magnitude, sp2[i].Magnitude);
                sgraphSpectrum.AddData(hz, 0, a[i].Imaginary);
            }


            sgraphWave.UpdateGraph();
            sgraphSpectrum.UpdateGraph();
        }
        public override int Read(float[] data, int offset, int count)
        {
            int samplesWritten = ReadBody(data, offset, count);

            while (samplesWritten < count)
            {
                int read = stream.Read(localSampleBuffer, 0, localSampleBuffer.Length);

                if (read <= 0)
                {
                    //Done
                    break;
                }
                else if (read < localSampleBuffer.Length)
                {
                    //Set rest to zero
                    Array.Clear(localSampleBuffer, read, localSampleBuffer.Length - read);
                }

                bufferIndex = 0;
                bufferCount = Channels * stepSize;

                for (int channel = 0; channel < Channels; channel++)
                {
                    //Slide input samples over
                    Array.Copy(
                        sourceArray: inputBuffers[channel],
                        sourceIndex: stepSize,
                        destinationArray: inputBuffers[channel],
                        destinationIndex: 0,
                        length: overlap);

                    //Copy new samples into buffer
                    for (int i = 0; i < stepSize; i++)
                    {
                        inputBuffers[channel][overlap + i] = localSampleBuffer[Channels * i + channel];
                    }

                    //Copy and Window into fftbuffer
                    for (int i = 0; i < frameSize; i++)
                    {
                        fftBuffer[i] = inputBuffers[channel][i] * windowInput[i];
                    }

                    //FFT
                    Fourier.Forward(fftBuffer);

                    //Copy values into IFFT Buffer
                    for (int i = 0; i < halfFrameSize; i++)
                    {
                        fftBuffer[i] *= phasors[channel][i];
                    }

                    Array.Clear(
                        array: fftBuffer,
                        index: halfFrameSize + 1,
                        length: halfFrameSize - 1);

                    //IFFT
                    Fourier.Inverse(fftBuffer);

                    //Accumualte the window samples
                    for (int i = 0; i < frameSize; i++)
                    {
                        outputAccumulation[Channels * i + channel] += (float)(outputScalar * fftBuffer[i].Real);
                    }
                }

                //Copy output samples to output buffer
                Array.Copy(
                    sourceArray: outputAccumulation,
                    destinationArray: cachedSampleBuffer,
                    length: bufferCount);

                //Slide down output accumulation
                Array.Copy(
                    sourceArray: outputAccumulation,
                    sourceIndex: bufferCount,
                    destinationArray: outputAccumulation,
                    destinationIndex: 0,
                    length: outputAccumulation.Length - bufferCount);

                //Clear empty output accumulation region
                Array.Clear(outputAccumulation, outputAccumulation.Length - bufferCount, bufferCount);

                samplesWritten += ReadBody(data, offset + samplesWritten, count - samplesWritten);
            }

            return(samplesWritten);
        }
예제 #18
0
        /// <summary>
        /// Called to process the audio input once the required number of samples are available.
        /// </summary>
        public void ProcessSample(Complex[] samples)
        {
            //Console.WriteLine($"process sample {samples[0]},{samples[1]},{samples[2]},{samples[3]},{samples[4]},{samples[5]},{samples[6]},{samples[7]}");

            //for (int i = 0; i < samples.Length; i++)
            //{
            //    Complex mono = new Complex(GAIN * samples[i], 0.0f);
            //    _timeRingBuffer[_timeIndex + i] = mono;       // Left.
            //    _timeRingBuffer[_timeIndex + FFT_SIZE + i] = mono; // right
            //}

            //Array.Copy(samples, 0, _timeRingBuffer, _timeIndex, samples.Length);
            //Array.Copy(samples, 0, _timeRingBuffer, _timeIndex + FFT_SIZE, samples.Length);
            Array.Copy(samples, 0, _timeRingBuffer, _timeIndex, samples.Length > FFT_SIZE ? FFT_SIZE : samples.Length);
            Array.Copy(samples, 0, _timeRingBuffer, _timeIndex + FFT_SIZE, samples.Length > (_timeRingBuffer.Length / 2 - _timeIndex) ? _timeRingBuffer.Length / 2 - _timeIndex : samples.Length);

            _timeIndex = (_timeIndex + samples.Length) % FFT_SIZE;

            var freqBuffer = _timeRingBuffer.Skip(_timeIndex).Take(FFT_SIZE).ToArray();

            Fourier.Forward(freqBuffer, FourierOptions.NoScaling);

            for (int j = 0; j < freqBuffer.Length; j++)
            {
                freqBuffer[j] = freqBuffer[j] * _analytic[j];
            }

            Fourier.Inverse(freqBuffer, FourierOptions.NoScaling);

            float scale = (float)FFT_SIZE;

            var complexAnalyticBuffer = freqBuffer.Skip(FFT_SIZE - BUFFER_SIZE).Take(BUFFER_SIZE).ToArray();
            var data = new float[BUFFER_SIZE * DISPLAY_ARRAY_STRIDE + PREVIOUS_SAMPLES_LENGTH];

            //Complex prevInput = new Complex(_previousResults[_previousResults.Length - DISPLAY_ARRAY_STRIDE], _previousResults[_previousResults.Length - DISPLAY_ARRAY_STRIDE + 1]);
            //Complex secondPrevInput = new Complex(_previousResults[_previousResults.Length - DISPLAY_ARRAY_STRIDE * 2], _previousResults[_previousResults.Length - DISPLAY_ARRAY_STRIDE * 2 + 1]);
            //Complex prevDiff = prevInput - secondPrevInput;

            Console.WriteLine($"Output sample {_outputSampleCount}:");

            for (int k = 0; k < complexAnalyticBuffer.Length; k++)
            {
                var diff = complexAnalyticBuffer[k] - _prevInput;
                _prevInput = complexAnalyticBuffer[k];

                var angle = (float)Math.Max(Math.Log(Math.Abs(GetAngle(diff, _prevDiff)), 2.0f), -1.0e12);
                _prevDiff = diff;
                var output = _angleLowPass.Apply(angle);

                //Console.WriteLine($"angle {angle}.");

                data[k * DISPLAY_ARRAY_STRIDE]     = (float)(complexAnalyticBuffer[k].Real / scale);
                data[k * DISPLAY_ARRAY_STRIDE + 1] = (float)(complexAnalyticBuffer[k].Imaginary / scale);
                data[k * DISPLAY_ARRAY_STRIDE + 2] = (float)Math.Pow(2, output);                           // Smoothed angular velocity.
                data[k * DISPLAY_ARRAY_STRIDE + 3] = _noiseLowPass.Apply((float)Math.Abs(angle - output)); // Average angular noise.

                //Console.WriteLine($"{ data[k * DISPLAY_ARRAY_STRIDE]},{data[k * DISPLAY_ARRAY_STRIDE + 1] },angle={angle},{data[k * DISPLAY_ARRAY_STRIDE + 2] },{data[k * DISPLAY_ARRAY_STRIDE + 3] }");
            }

            Array.Copy(_previousResults, 0, data, 0, PREVIOUS_SAMPLES_LENGTH);
            _lastSample = data;
            _outputSampleCount++;

            _previousResults = data.Skip(data.Length - PREVIOUS_SAMPLES_LENGTH).ToArray();
        }
예제 #19
0
        private void CreateFreqGraph(ZedGraphControl zgc, double[] sectionBuffers)
        {
            try
            {
                int FreqMin = int.Parse(FreqMintextBox.Text);
                int FreqMax = int.Parse(FreqMaxtextBox.Text);
                convertClkRate = int.Parse(SamplingTextbox.Text);
                sectionLength  = int.Parse(DataLengthtextBox.Text);
                Freqrange      = int.Parse(FreqrangetextBox.Text);
                Complex[] fftsamples = new Complex[sectionLength];

                for (int i = 0; i < sectionLength; i++)
                {
                    fftsamples[i] = sectionBuffers[i];
                }
                Fourier.Forward(fftsamples, FourierOptions.NoScaling);
                double[] hzsample = new double[sectionBuffers.Length / Freqrange];
                double[] mag      = new double[sectionBuffers.Length / Freqrange];
                for (int i = 0; i < fftsamples.Length / Freqrange; i++)
                {
                    mag[i]      = 2000 * (2.0 / sectionLength) * (Math.Abs(Math.Sqrt(Math.Pow(fftsamples[i].Real, 2) + Math.Pow(fftsamples[i].Imaginary, 2))));
                    hzsample[i] = convertClkRate / sectionLength * i;
                }
                int      Minxlength = int.Parse(FreqMintextBox.Text);
                int      Maxxlength = int.Parse(FreqMaxtextBox.Text);
                double[] x          = new double[Minxlength];
                double[] y          = new double[Minxlength];
                double[] x1         = new double[Maxxlength];
                double[] y1         = new double[Maxxlength];

                for (int i = 0; i < x.Length; i++)
                {
                    x[i] = i;
                }
                for (int i = 0; i < x1.Length; i++)
                {
                    x1[i] = i;
                }
                y[Minxlength - 1]  = 10;
                y1[Maxxlength - 1] = 10;
                zgc.GraphPane.CurveList.Clear();
                GraphPane myPane = zgc.GraphPane;
                // Set the titles and axis labels
                // Make up some data points from the Sine function
                LineItem      myCurve;
                LineItem      Mincurve;
                LineItem      Maxcurve;
                PointPairList list = new PointPairList();
                list.Add(hzsample, mag);
                // Generate a blue curve with circle symbols, and "My Curve 2" in the legend
                myCurve = zedGraphControl2.GraphPane.AddCurve("Channel 0", list, Color.Red, SymbolType.None);
                //myCurve = zedGraphControl2.GraphPane.AddCurve("Channel 0", hzsample, mag, Color.Red, SymbolType.None);
                Mincurve              = zedGraphControl2.GraphPane.AddCurve("FreqMin", x, y, Color.DarkBlue, SymbolType.None);
                Maxcurve              = zedGraphControl2.GraphPane.AddCurve("FreqMax", x1, y1, Color.DarkOrange, SymbolType.None);
                Mincurve.Line.Style   = DashStyle.Custom;
                Mincurve.Line.Width   = 2;
                Mincurve.Line.DashOn  = 5;
                Mincurve.Line.DashOff = 5;
                Maxcurve.Line.Style   = DashStyle.Custom;
                Maxcurve.Line.Width   = 2;
                Maxcurve.Line.DashOn  = 5;
                Maxcurve.Line.DashOff = 5;
                // Make the symbols opaque by filling them with white
                myCurve.Line.Fill   = new Fill(Color.White, Color.Red, 45F);
                myCurve.Symbol.Fill = new Fill(Color.White);
                // Fill the axis background with a color gradient
                zgc.AxisChange();
                zgc.Refresh();
            }
            catch (Exception err)
            {
                _log.Error("Frequency domain calculate or drawing Error message is---" + err.Message);
                MessageBox.Show(err.Message);
            }
        }
예제 #20
0
        public void RecalcSpectrum()
        {
            if (_buffer.Count > BUFFER_SIZE)
            {
                _buffer.RemoveRange(0, _buffer.Count - BUFFER_SIZE);
            }
            UNIT_TIME = (_buffer.Count * 1.0f / SAMPLE_RATE);
            int _buffer_len = _buffer.Count;
            var windowfunc  = Window.Hann(_buffer_len);

            float ScaleFactor = 1.0f;

            var fourier_v = new Complex32[_buffer_len];

            for (int i = 0; i < _buffer_len; i++)
            {
                fourier_v[i] = new Complex32(ScaleFactor * _buffer[i].Real * (float)windowfunc[i], 0);
            }

            Fourier.Forward(fourier_v);
            spectrum = fourier_v.Take(fourier_v.Length / 2).Select(x => (float)x.Norm()).ToArray();

            /*
             * Complex32[] cepstrum = fourier_v.Take(fourier_v.Length / 2).Select(x => Complex32.Log(x) ).ToArray();
             * Fourier.Inverse(cepstrum);
             * for (int i = 120; i < cepstrum.Length; i++) {
             *      cepstrum[i] = 0;
             * }
             * Fourier.Forward(cepstrum);
             * test_graph = cepstrum.Take(cepstrum.Length / 2).Select(x => (float) x.Norm() ).ToArray(); //cepstrum.Select(x => (float)x.Norm()).ToArray();
             */
            float prev    = -1.0f;
            bool  prev_up = true;
            float max_fq  = 0.0f;
            float max_v   = 0.0f;

            peaks.Clear();
            for (int i = 0; i < spectrum.Length; i++)
            {
                float v  = spectrum[i];
                float fq = i / UNIT_TIME;
                if (fq < CUTOFF)
                {
                    continue;
                }
                bool up = false;
                if (v > prev)
                {
                    up = true;
                }
                if ((!up) && prev_up && prev > THRESHOLD)
                {
                    peaks.Add(new KeyValuePair <int, float>(i - 1, prev));
                }
                if (max_v < v)
                {
                    max_fq = fq;
                    max_v  = v;
                }
                prev    = v;
                prev_up = up;
            }
            float freq = float.NaN;

            if (peaks.Count > 0)
            {
                freq = peaks.Select(x => x.Key).Min() / UNIT_TIME;
            }
            freq_graph[freq_graph_pos++] = freq;

            //Console.WriteLine(String.Format("{0,12:F4},{1,12:F4}", max_fq, max_v));

/*			if (max_v > THRESHOLD) {
 *                              freq_graph[freq_graph_pos++] = max_fq;
 *                      } else {
 *                              freq_graph[freq_graph_pos++] = float.NaN;
 *                      } */



            if (freq_graph_pos >= FREQ_GRAPH_SIZE)
            {
                freq_graph_pos = 0;
            }
        }