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()); } }
public void Transform() { Fourier.Forward(_data, FourierOptions.Default); Fourier.Inverse(_data, FourierOptions.Default); }
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); }
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 { } }
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]; }
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); }
/// <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); }
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); }
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 }
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); }
public void Transform() { Fourier.Forward(_data, FourierOptions.NoScaling); Fourier.Inverse(_data, FourierOptions.NoScaling); }
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); }
/// <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(); }
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); } }
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; } }