void UpdateChannel() { int i, j; _mplayer.Close(); _throughputGraph.BeginUpdate(); _throughputSeries.SamplesSingle = _throughputdata[_selectChannelIndex]; _rmsSeries.SamplesSingle = _rmsData[_selectChannelIndex]; _throughputGraph.ViewXY.ZoomToFit(); _throughputGraph.EndUpdate(); _tfGraph.BeginUpdate(); _tfdata = new double[_dataFileNode.NFrame][]; float[] curdata = new float[_dataFileNode.Nfft]; float[] fdata = null; int curind = 0; for (i = 0; i < _dataFileNode.NFrame; i++) { Array.Copy(_throughputdata[_selectChannelIndex], curind, curdata, 0, _dataFileNode.Nfft); curind += _dataFileNode.FrameDN; spectrumCalculator.PowerSpectrum(curdata, out fdata); _tfdata[i] = new double[flen]; for (j = 0; j < flen; j++) { _tfdata[i][j] = 20 * Math.Log10(fdata[j + fstarti]) + _aweightdb[j]; } } _tfSeries.SetValuesData(_tfdata, IntensityGridValuesDataOrder.ColumnsRows); _tfGraph.ViewXY.ZoomToFit(); _tfGraph.EndUpdate(); oldiColIndex = -1; verticalCursor_PositionChanged(null, new PositionChangedEventArgs() { NewValue = _tfgraph_verticalCursor.ValueAtXAxis }); }
private void OnDataSampled(short[][] intdata) { Parallel.For(0, ChannelNum, i => { Array.Copy(_oldtimeData[i], FrameDN, _oldtimeData[i], 0, Nfft - FrameDN); Array.Copy(intdata[i], 0, _oldtimeData[i], Nfft - FrameDN, FrameDN); }); _sampledLen += (UInt64)FrameDN; if (_sampledLen < (UInt64)Nfft) { return; } float[][] timeData = new float[ChannelNum][]; float[][] frfData = new float[ChannelNum][]; float[] rms = new float[ChannelNum]; bool bMaxFrfChanged = false; Parallel.For(0, ChannelNum, i => { double crms = 0; timeData[i] = new float[Nfft]; float[] dataf = new float[Nfft]; frfData[i] = new float[_flen]; int j = 0; int mean = 0; Array.Copy(_oldtimeData[i], FrameDN, _oldtimeData[i], 0, Nfft - FrameDN); Array.Copy(intdata[i], 0, _oldtimeData[i], Nfft - FrameDN, FrameDN); for (j = 0; j < Nfft; j++) { mean += _oldtimeData[i][j]; } mean /= Nfft; for (j = 0; j < Nfft; j++) { timeData[i][j] = (float)((_oldtimeData[i][j] - mean) * Sens[i]); } _spectrumCalculator.PowerSpectrum(timeData[i], out dataf); for (j = 0; j < _flen; j++) { crms += dataf[j + _fstarti] * dataf[j + _fstarti] * _aweight[j]; //frfData[i][j] = (float)(dataf[j + _fstarti]/_Nfft*Math.Sqrt(2));//有效值谱 frfData[i][j] = (float)(20 * Math.Log10(dataf[j + _fstarti]) + _aweightdb[j]); if (bRecording) { if (frfData[i][j] > _maxFrfData[j]) { bMaxFrfChanged = true; _maxFrfData[j] = frfData[i][j]; } } } rms[i] = (float)(10 * Math.Log10(crms) + _overallFix); }); if (_bRecording && binaryFormatter != null) { lock (binaryFS) RecordedFrames++; if (_bRecordFisrt) { _bRecordFisrt = false; binaryFormatter.Serialize(binaryFS, _oldtimeData); } else { binaryFormatter.Serialize(binaryFS, intdata); } } _eventAggregator.GetEvent <RecordServiceDataEvent>().Publish( new RecordServiceDataEventData { TimeData = timeData, FrfData = frfData, RMS = rms, MaxFrfData = (bRecording && bMaxFrfChanged)?_maxFrfData:null }); }
/// <summary> /// 从多频道数据流中计算FFT /// </summary> /// <param name="data">样例数据</param> /// <param name="xValues"></param> /// <param name="yValues"></param> /// <returns>如果成功计算出FFT返回true</returns> public bool FeedDataAndCalculate(double[][] data, out double[][][] xValues, out double[][][] yValues) { xValues = null; yValues = null; if (data == null) { return(false); } int channelCounter = m_iChannelCount; if (data.Length < channelCounter) { channelCounter = data.Length; } long ticksNow = DateTime.Now.Ticks; bool giveDataOut = false; //每次更新的样例数 int samplesPerUpdate = (int)(_intervalMs * (double)_samplingFrequency / 1000.0); int repeatFFT; if (_FFTEntryIndex == 0) { repeatFFT = 1; } else { repeatFFT = (int)Math.Ceiling((double)data[0].Length / samplesPerUpdate); } double[][][] valuesX = new double[repeatFFT][][]; //dimensions: repeatFFTcalc, channelCounter, fftResult.Length double[][][] valuesY = new double[repeatFFT][][]; for (int i = 0; i < repeatFFT; i++) { //for FFT calculus copy only less or samplesPerUpdate points from DATA int samplesCopiesAmount = Math.Min(samplesPerUpdate, data[0].Length - i * samplesPerUpdate); if (_FFTEntryIndex == 0) { samplesCopiesAmount = data[0].Length; //for 1st m_iFFTWindowLen number of points } valuesX[i] = new double[channelCounter][]; valuesY[i] = new double[channelCounter][]; int samplesInCombinedData = 0; //多频道并行计算 System.Threading.Tasks.Parallel.For(0, channelCounter, iChannel => { //拼接前次处理过的数据与新数据形成要处理的数据 double[] combinedData = new double[_oldData[iChannel].Length + samplesCopiesAmount]; Array.Copy(_oldData[iChannel], 0, combinedData, 0, _oldData[iChannel].Length); Array.Copy(data[iChannel], i * samplesPerUpdate, combinedData, _oldData[iChannel].Length, samplesCopiesAmount); samplesInCombinedData = combinedData.Length; // initiate FFTcalculus at fixed interval from Time-reference if (samplesInCombinedData >= m_iFFTWindowLen && ticksNow >= (m_lRefTicks + _updateInterval * (_FFTEntryIndex + 1))) { double[] dataCombined = new double[m_iFFTWindowLen]; int index = 0; for (int j = samplesInCombinedData - m_iFFTWindowLen; j < samplesInCombinedData; j++) { dataCombined[index++] = combinedData[j]; } //调用内建方法计算频谱 double[] fftResult; if (_spectrumCalculator.PowerSpectrum(dataCombined, out fftResult)) { int length = fftResult.Length; valuesX[i][iChannel] = new double[length]; valuesY[i][iChannel] = new double[length]; double stepX = (double)_samplingFrequency / 2.0 / ((double)length - 1.0); //accurate estimate of DC (0 HZ) component is difficult, therefore, maybe a good idea to skip it for (int point = 1; point < length; point++) { valuesX[i][iChannel][point] = (double)point * stepX; valuesY[i][iChannel][point] = fftResult[point]; } int samplesAmountNew = samplesPerUpdate; if (m_iFFTWindowLen > samplesAmountNew) { samplesAmountNew = m_iFFTWindowLen; } if (samplesInCombinedData > samplesAmountNew) { //Drop oldest samples out _oldData[iChannel] = new double[samplesAmountNew]; Array.Copy(combinedData, samplesInCombinedData - samplesAmountNew, _oldData[iChannel], 0, samplesAmountNew); } giveDataOut = true; } } else { _oldData[iChannel] = combinedData; } }); //repeat IF block to avoid some uncertainties of Parallel loop if (samplesInCombinedData >= m_iFFTWindowLen && ticksNow >= (m_lRefTicks + _updateInterval * (_FFTEntryIndex + 1))) { if (_FFTEntryIndex == 0) { m_lRefTicks = ticksNow; } _FFTEntryIndex++; } } if (giveDataOut) { while (repeatFFT > 0 && valuesX[repeatFFT - 1][0] == null) { repeatFFT--; //reduce 1st dimension if it was not enough points to Calculate FFT } if (repeatFFT == 0) { giveDataOut = false; return(giveDataOut); } xValues = new double[repeatFFT][][]; yValues = new double[repeatFFT][][]; for (int i = 0; i < repeatFFT; i++) { xValues[i] = new double[channelCounter][]; yValues[i] = new double[channelCounter][]; for (int iChannel = 0; iChannel < channelCounter; iChannel++) { // copy FFT results to output xValues[i][iChannel] = valuesX[i][iChannel]; yValues[i][iChannel] = valuesY[i][iChannel]; } } } if (giveDataOut) { _lastTicks = ticksNow; } return(giveDataOut); }