private void AnalyzeFFT(AudioSampleData[] data) { if (data.Length == _fftWindowSize) { double[] dataIn = new double[data.Length]; double[] dataOut = new double[data.Length]; for (int i = 0; i < data.Length; i++) { dataIn[i] = data[i].LVOL; } FFT.Forward(dataIn, dataOut); lock (_spectrogramLock) { var linearData = dataOut .Skip(1 /* First band represents the 'total energy' of the signal */) .Take(_fftWindowSize / 2 /* The spectrum is 'mirrored' horizontally around the sample rate / 2 according to Nyquist theorem */) .ToArray(); _spectrogramData = FFTHelper.TranslateFFTIntoBands(linearData, _actualAudioFormat.nSamplesPerSec / 2, MAX_SPECTROGRAM_BANDS); } } }
private void ProcessFFT() { double width = RectangleUI.X1 - RectangleUI.X0; SelectedData.Clear(); double[] func = FFTHelper.WindowFunc(SelectedWindowFunc, (int)width); int px = -1; int i = 0; Line.Points.Where(point => point.X >= RectangleUI.X0 && point.X <= RectangleUI.X1).ToList().ForEach(p => { if (px == -1) { px = (int)p.X; } double pY = !IsMagnitude ? p.Y * func[i] : p.Y; SelectedData.Add(new Complex(pY, 0)); if (i < width - 1) { i++; } }); // Process((int)RectangleUI.X0, (int)RectangleUI.X1); }
private Vector3 getFFT(int x, int z, out Vector3 normal) { if (!hasDoneFFT) { hasDoneFFT = true; FFT_H = new Vector2[edgelen, edgelen]; FFT_Dx = new Vector2[edgelen, edgelen]; FFT_Dz = new Vector2[edgelen, edgelen]; FFT_Nx = new Vector2[edgelen, edgelen]; FFT_Nz = new Vector2[edgelen, edgelen]; int halfedgelen = edgelen / 2; float kx, kz; Vector2 k; Vector2 ht; int uaddh; int vaddh; for (int u = -halfedgelen; u < halfedgelen; u++) { kx = 2 * Mathf.PI * u / edgelen; for (int v = -halfedgelen; v < halfedgelen; v++) { kz = 2 * Mathf.PI * v / edgelen; k = new Vector2(kx, kz); uaddh = u + halfedgelen; vaddh = v + halfedgelen; ht = Htildes[uaddh, vaddh]; FFT_H[uaddh, vaddh] = new Vector2(ht.x, ht.y); if (k.magnitude < Min) { FFT_Nx[uaddh, vaddh] = new Vector2(0, 0); FFT_Nz[uaddh, vaddh] = new Vector2(0, 0); FFT_Dx[uaddh, vaddh] = new Vector2(0, 0); FFT_Dz[uaddh, vaddh] = new Vector2(0, 0); } else { FFT_Nx[uaddh, vaddh] = new Vector2(-ht.y * kx, ht.x * kx); FFT_Nz[uaddh, vaddh] = new Vector2(-ht.y * kz, ht.x * kz); FFT_Dx[uaddh, vaddh] = new Vector2(ht.y * kx / k.magnitude, -ht.x * kx / k.magnitude); FFT_Dz[uaddh, vaddh] = new Vector2(ht.y * kz / k.magnitude, -ht.x * kz / k.magnitude); } FFT_H[uaddh, vaddh].y *= -1; FFT_Nx[uaddh, vaddh].y *= -1; FFT_Nz[uaddh, vaddh].y *= -1; FFT_Dx[uaddh, vaddh].y *= -1; FFT_Dz[uaddh, vaddh].y *= -1; } } FFTHelper.FFT(FFT_H, edgelen); FFTHelper.FFT(FFT_Nx, edgelen); FFTHelper.FFT(FFT_Nz, edgelen); FFTHelper.FFT(FFT_Dx, edgelen); FFTHelper.FFT(FFT_Dz, edgelen); } normal = new Vector3(0, 1, 0) - new Vector3(FFT_Nx[x, z].x, 0, FFT_Nz[x, z].x); return(new Vector3(FFT_Dx[x, z].x * -Q, FFT_H[x, z].x, FFT_Dz[x, z].x * -Q)); }
private void IFFT(Complex[] source, int start) { int i = start; foreach (var p in FFTHelper.IFFT(source)) { Line.Points[i] = new DataPoint(i, p); i++; } Model.InvalidatePlot(true); }
private void Model_MouseUp(object sender, OxyMouseEventArgs e) { isPanBar = false; if (RectangleUI != null && isSelected) { if (Math.Abs(RectangleUI.X1 - RectangleUI.X0) < 10) { ClearBar(); SelectedData.Clear(); } else { double[] func = FFTHelper.WindowFunc(SelectedWindowFunc, 512); double min = RectangleUI.X0 < RectangleUI.X1 ? RectangleUI.X0 : RectangleUI.X1; double max = RectangleUI.X0 > RectangleUI.X1 ? RectangleUI.X0 : RectangleUI.X1; RectangleUI = new RectangleBarItem(min, Int16.MinValue, max, Int16.MaxValue); RectangleUI.Color = OxyColor.FromArgb(100, 0, 0, 250); Bar.Items.Add(RectangleUI); Bar.Items.RemoveAt(0); int func_i = 0; Line.Points.Where(point => point.X > min && point.X < max).ToList().ForEach(p => { SelectedData.Add(new Complex(p.Y * func[func_i], 0)); if (func_i == 511) { func_i = 0; } else { func_i++; } }); LastX = (int)min; if (!IsMagnitude) { Process2((int)RectangleUI.X0, (int)RectangleUI.X1); // Process((int)RectangleUI.X0, (int)RectangleUI.X1); } else { Morphing(); } } } isSelected = false; }
protected override void DrawDecadicLines(Graphics g, Rectangle rc) { using (Pen p = new Pen(ThemeManager.ForeColor)) using (Brush b = new SolidBrush(ThemeManager.ForeColor)) { for (int i = 0; i < DecadeLinesRelativePositions.Length; i++) { double decadeLinePos = DecadeLinesRelativePositions[i]; string decadeLineText = DecadeLinesText[i]; if (i == DecadeLinesRelativePositions.Length - 1) { try { int maxFq = FFTHelper.GetMaxDisplayableFreq(MediaRenderer.DefaultInstance.ActualAudioFormat.nSamplesPerSec / 2, DsRendererBase.MAX_SPECTROGRAM_BANDS); decadeLineText = string.Format("{0}K", (int)(maxFq / 1000)); } catch { decadeLineText = string.Empty; } } int x = rc.Left + (int)(decadeLinePos * rc.Width); Point pt1 = new Point(x, rc.Top); Point pt2 = new Point(x, rc.Bottom); Point pt3 = new Point(x, rc.Bottom + 5); p.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDotDot; if (i > 0 && i < DecadeLinesRelativePositions.Length - 1) { g.DrawLine(p, pt1, pt2); } SizeF sz = g.MeasureString(decadeLineText, ThemeManager.SmallestFont); if (pt3.X + sz.Width > rc.Right) { pt3.X = (int)(rc.Right - sz.Width); } g.DrawString(decadeLineText, ThemeManager.SmallestFont, b, pt3); } } }
private void Process2(int start, int end) { //Сдвиг окна (shift 500 - width 512) int shift = 256; int width = 1024; //Диапазон частот (256 - до 22100Hz, 128 - до 11050Hz) int freq_range = 256; double[] func = FFTHelper.WindowFunc(SelectedWindowFunc, width); Bitmap btm = new Bitmap((end - start) / shift, 256); System.Drawing.Color[] freq = new System.Drawing.Color[freq_range]; int btm_i = 0; FFTLine.Points.Clear(); double[] result = new double[width]; for (int x = 0; x < SelectedData.Count() - width; x += shift) { int i = 0; int ii = 0; if (x + width < SelectedData.Count() - 1) { FFT2Helper.fft(SelectedData.GetRange(x, width).ToArray()).ToList().ForEach(p => { p = p.Magnitude * func[ii]; int Db = (int)(GetYPosLog(p) + 5) * 8; int intense1 = Db <= 0 ? 0 : Db; intense1 = intense1 > 255 ? 255 : intense1; // intense1 = Math.Abs(intense1 - 255) ; if (i < freq.Count()) { freq[i] = System.Drawing.Color.FromArgb(255, intense1, intense1, 50); } i++; ii++; }); for (int yi = freq.Count() - 1; yi > 0; yi--) { btm.SetPixel(btm_i, yi, freq[Math.Abs(yi - (freq.Count() - 1))]); } } btm_i++; } Spectrogramm = BitmapToImage(btm); //for (int i = 0; i < 2048; i++) //{ // temp[i].Magnitude = (temp[i].Magnitude / 2048); // // temp[i].Magnitude = temp[i].Rep > cons ? (temp[i].Magnitude / temp[i].Rep) : 0; // FFTLine.Points.Add(new DataPoint(i, temp[i].Magnitude)); //} //FFTModel.InvalidatePlot(true); }
/// <summary> /// 加速频谱 转化 disp频谱 /// </summary> /// <param name="accSpectrum"></param> /// <param name="sampleFre"></param> /// <param name="point"></param> /// <returns></returns> private float[] GetDispSpectrum(float[] accSpectrum, int sampleFre, int point) { float[] dispSpectrum = new float[point / 2]; FFTHelper.IntegrateFromSpectrum1(accSpectrum, sampleFre, point, 2, ref dispSpectrum); return(dispSpectrum); }
/// <summary> /// 加速频谱 转化 vel频谱 /// </summary> /// <param name="accSpectrum"></param> /// <param name="sampleFre"></param> /// <param name="point"></param> /// <returns></returns> private float[] GetVelSpectrum(float[] accSpectrum, int sampleFre, int point) { float[] velSpectrum = new float[point / 2]; FFTHelper.IntegrateFromSpectrum1(accSpectrum, sampleFre, point, 1, ref velSpectrum); return(velSpectrum); }
/// <summary> /// 加速度波形 转化 acc频谱 /// </summary> /// <param name="accTw"></param> /// <param name="line"></param> /// <returns></returns> private float[] GetAccSpectrum(float[] accTw, int line) { float[] spectrum = FFTHelper.TwToFFT(accTw, line); return(spectrum); }
public void GetDataTw(SiteModel site, SocketMiddleware socket) { Dictionary <string, bool> stopDic = RedisHelper.Get <Dictionary <string, bool> >($"{CallContext.GetData<ClientInfo>("clientInfo").Database}IsStop"); Console.WriteLine("开始采集波形数据!"); //存储集合 List <int> workStatuesList = null; List <MeterageSamplerate> list = null; int type, frequency, line; byte[] cmd = null; byte[] recData = new byte[20]; for (int i = 0; i < site.ChannelStructList.Count; i++) { //是否停机状态 string key = $"A{site.ChannelStructList[i].AreaID}M{site.ChannelStructList[i].MachineID}"; if (stopDic.GetValueOrDefault(key)) { continue; } list = _meterageSamplerateService.Query(s => s.AreaId == site.ChannelStructList[i].AreaID && s.McId == site.ChannelStructList[i].MachineID && s.ParId == site.ChannelStructList[i].MonitorID && s.DirId == site.ChannelStructList[i].Position_HVA && s.IsSamplerate == 1); workStatuesList = site.ChannelStructList[i].StateStatus.Where(w => w != -1).ToList(); foreach (MeterageSamplerate item in list) { line = item.MsrLine; frequency = item.MsrRateMax; type = item.MsrParameter.ToLower().Contains("env") ? 2 : 0; char typeName = item.MsrName.ToUpper()[0]; //类型的首字母 如:Disp 'D' cmd = OrderHelper.TwDataByChannel(site.ChannelStructList[i].ChannelID, typeName, frequency, line, 0); //获取每个通道取数据命令 if (socket.Send(cmd)) { if (!socket.Receive(recData)) //接收失败 { continue; } int len = BitConverter.ToInt32(recData, 15); //获取要接收的数据长度 if (len <= 0) //是否有数据 { continue; } //获取波形数据 cmd = OrderHelper.TwDataByChannel(site.ChannelStructList[i].ChannelID, typeName, frequency, line, 1); if (!socket.Send(cmd)) { continue; } byte[] data = new byte[len]; if (!socket.Receive(data)) //接收波形数据,最后4个字节是工况 { Console.WriteLine(string.Format("{0}站点{1}通道号接收波形异常!", site.Sn, i)); continue; } DataTw tw = new DataTw() //数据转化波形对象 { AreaId = item.AreaId, McId = item.McId, ParId = item.ParId, DirId = item.DirId, DataLines = GetLineByType(item.MsrLine, type), DataPoints = (int)(GetLineByType(item.MsrLine, type) * 2.56), DataHz = (int)(GetFrequencyByType(item.MsrRateMax, type) * 2.56), DataIsFFT = 0, DataType = type + 1, DataFormat = 2, Data = new byte[len - 7 * 4], DataWorkStatus = Convert.ToInt32(BitConverter.ToSingle(data, 24)), Time = ConvertTime(data) }; //是否是要取的工况 if (!workStatuesList.Exists(w => w == tw.DataWorkStatus)) { continue; } Array.Copy(data, 7 * 4, tw.Data, 0, len - 7 * 4); //把波形数据copy到 tw.data中 if (item.MsrParameter.ToLower().Contains("env")) //包络,直接存 { tw.DataIsFFT = 1; tw.Data = SplitMinFFT(tw.Data, item); //截取最小Fmin _dataTwService.InsertDataTw(tw, string.Format("tb_data_tw_{0}", item.MsrName)); //存入数据库 } else if (item.MsrParameter.ToLower().Contains("acc")) { //存储波形 _dataTwService.InsertDataTw(tw, string.Format("tb_data_tw_{0}", item.MsrName)); //频谱存储 float[] accSpectrum = GetAccSpectrum(ToFloatArray(tw.Data), tw.DataLines); for (int z = 0; z < accSpectrum.Length; z++) { accSpectrum[z] = accSpectrum[z] / 1.414f;//峰值转有效值 } tw.Data = ToByteArray(accSpectrum); tw.DataIsFFT = 1; tw.Data = SplitMinFFT(tw.Data, item); //截取最小Fmin _dataTwService.InsertDataTw(tw, string.Format("tb_data_tw_{0}", item.MsrName)); } else if (item.MsrParameter.ToLower().Contains("disp")) { float[] accSpectrum = GetAccSpectrum(ToFloatArray(tw.Data) /*原始波形*/, tw.DataLines); //位移频谱 float[] dispSpectrum = GetDispSpectrum(accSpectrum, tw.DataHz, tw.DataPoints); for (int k = 0; k < dispSpectrum.Length; k++) { //位移有效值 dispSpectrum[k] = dispSpectrum[k] * 9800 * 1000 / 1.414f; } //位移波形 float[] dispTw = new float[tw.DataPoints]; FFTHelper.IntegrateFromSpectrum(ToFloatArray(tw.Data) /*原始波形*/, tw.DataHz, tw.DataPoints, item.MsrRateMin, GetFrequencyByType(item.MsrRateMax, type), 2, ref dispTw); for (int k = 0; k < dispTw.Length; k++) { dispTw[k] = dispTw[k] * 9800 * 1000; } //存储波形 //tw.data = ToByteArray(dispTw); _dataTwService.InsertDataTw(tw, string.Format("tb_data_tw_{0}", item.MsrName)); //频谱存储 tw.DataIsFFT = 1; tw.Data = ToByteArray(dispSpectrum); tw.Data = SplitMinFFT(tw.Data, item); //截取最小Fmin _dataTwService.InsertDataTw(tw, string.Format("tb_data_tw_{0}", item.MsrName)); } else if (item.MsrParameter.ToLower().Contains("vel")) { float[] accSpectrum = GetAccSpectrum(ToFloatArray(tw.Data) /*原始波形*/, tw.DataLines); //速度波形 float[] velTw = new float[tw.DataPoints]; FFTHelper.IntegrateFromSpectrum(ToFloatArray(tw.Data) /*原始波形*/, tw.DataHz, tw.DataPoints, item.MsrRateMin, GetFrequencyByType(item.MsrRateMax, type), 1, ref velTw); for (int k = 0; k < velTw.Length; k++) { velTw[k] = velTw[k] * 9800; } //速度频谱 float[] velSpectrum = GetVelSpectrum(accSpectrum, tw.DataHz, tw.DataPoints); for (int k = 0; k < velSpectrum.Length; k++) { velSpectrum[k] = velSpectrum[k] * 9800 / 1.414f; } //波形存储 //tw.data = ToByteArray(velTw); _dataTwService.InsertDataTw(tw, string.Format("tb_data_tw_{0}", item.MsrName)); //频谱存储 tw.DataIsFFT = 1; tw.Data = ToByteArray(velSpectrum); //获取频谱 tw.Data = SplitMinFFT(tw.Data, item); //截取最小Fmin _dataTwService.InsertDataTw(tw, string.Format("tb_data_tw_{0}", item.MsrName)); } } } } Console.WriteLine("波形数据采集完成!"); }
/// <summary> /// 从下位机获取波形或频谱数据,波形数据直接存储,频谱数据返回供提取转速 /// </summary> /// <param name="meterageSamplerate">获取波形或频谱参数</param> /// <returns></returns> private DataTwModel GetTwFFTData(MeterageSamplerate ms) { //是否停机状态 string key = $"A{ms.AreaId}M{ms.McId}"; if (_stopMachineOa.GetValueOrDefault(key)) { return(null); } byte[] recData = new byte[20]; int line = ms.MsrLine; int frequency = ms.MsrRateMax; int type = ms.MsrParameter.ToLower().Contains("env") ? 2 : 0; char typeName = ms.MsrName.ToUpper()[0]; //类型的首字母 如:Disp 'D' ChannelStruct channelStruct = _site.ChannelStructList.FirstOrDefault(cs => cs.AreaID == ms.AreaId && cs.MachineID == ms.McId && cs.MonitorID == ms.ParId && cs.Position_HVA == ms.DirId); //获取通道号 List <int> workStatuesList = channelStruct.StateStatus.Where(w => w != -1).ToList(); byte[] cmd = OrderHelper.TwDataByChannel(channelStruct.ChannelID, typeName, frequency, line, 0); //获取每个通道取数据命令 if (_socket.Send(cmd)) { if (!_socket.Receive(recData)) //接收失败 { return(null); } int len = BitConverter.ToInt32(recData, 15); //获取要接收的数据长度 if (len <= 0) //是否有数据 { return(null); } //获取波形数据 cmd = OrderHelper.TwDataByChannel(channelStruct.ChannelID, typeName, frequency, line, 1); if (!_socket.Send(cmd)) { return(null); } byte[] data = new byte[len]; if (!_socket.Receive(data)) //接收波形数据,最后4个字节是工况 { Console.WriteLine(string.Format("{0}站点{1}通道号接收波形异常!", _site.Sn, channelStruct.ChannelID)); return(null); } DataTw tw = new DataTw() //数据转化波形对象 { AreaId = ms.AreaId, McId = ms.McId, ParId = ms.ParId, DirId = ms.DirId, DataLines = GetLineByType(ms.MsrLine, type), DataPoints = (int)(GetLineByType(ms.MsrLine, type) * 2.56), DataHz = (int)(GetFrequencyByType(ms.MsrRateMax, type) * 2.56), DataIsFFT = 0, DataType = type + 1, DataFormat = 2, Data = new byte[len - 7 * 4], DataWorkStatus = Convert.ToInt32(BitConverter.ToSingle(data, 24)), Time = ConvertTime(data) }; //是否是要取的工况 if (!workStatuesList.Exists(w => w == tw.DataWorkStatus)) { return(null); } Array.Copy(data, 7 * 4, tw.Data, 0, len - 7 * 4); //把波形数据copy到 tw.data中 if (ms.MsrParameter.ToLower().Contains("env")) //包络,直接存 { tw.DataIsFFT = 1; tw.Data = SplitMinFFT(tw.Data, ms); //截取最小Fmin _dataTwService.InsertDataTw(tw, string.Format("tb_data_tw_{0}", ms.MsrName)); //存入数据库 } else if (ms.MsrParameter.ToLower().Contains("acc")) { //存储波形 _dataTwService.InsertDataTw(tw, string.Format("tb_data_tw_{0}", ms.MsrName)); //频谱存储 float[] accSpectrum = GetAccSpectrum(ToFloatArray(tw.Data), tw.DataLines); for (int z = 0; z < accSpectrum.Length; z++) { accSpectrum[z] = accSpectrum[z] / 1.414f;//峰值转有效值 } tw.Data = ToByteArray(accSpectrum); tw.DataIsFFT = 1; tw.Data = SplitMinFFT(tw.Data, ms); //截取最小Fmin _dataTwService.InsertDataTw(tw, string.Format("tb_data_tw_{0}", ms.MsrName)); } else if (ms.MsrParameter.ToLower().Contains("disp")) { float[] accSpectrum = GetAccSpectrum(ToFloatArray(tw.Data) /*原始波形*/, tw.DataLines); //位移频谱 float[] dispSpectrum = GetDispSpectrum(accSpectrum, tw.DataHz, tw.DataPoints); for (int k = 0; k < dispSpectrum.Length; k++) { //位移有效值 dispSpectrum[k] = dispSpectrum[k] * 9800 * 1000 / 1.414f; } //位移波形 float[] dispTw = new float[tw.DataPoints]; FFTHelper.IntegrateFromSpectrum(ToFloatArray(tw.Data) /*原始波形*/, tw.DataHz, tw.DataPoints, ms.MsrRateMin, GetFrequencyByType(ms.MsrRateMax, type), 2, ref dispTw); for (int k = 0; k < dispTw.Length; k++) { dispTw[k] = dispTw[k] * 9800 * 1000; } //存储波形 //tw.data = ToByteArray(dispTw); _dataTwService.InsertDataTw(tw, string.Format("tb_data_tw_{0}", ms.MsrName)); //频谱存储 tw.DataIsFFT = 1; tw.Data = ToByteArray(dispSpectrum); tw.Data = SplitMinFFT(tw.Data, ms); //截取最小Fmin _dataTwService.InsertDataTw(tw, string.Format("tb_data_tw_{0}", ms.MsrName)); } else if (ms.MsrParameter.ToLower().Contains("vel")) { float[] accSpectrum = GetAccSpectrum(ToFloatArray(tw.Data) /*原始波形*/, tw.DataLines); //速度波形 float[] velTw = new float[tw.DataPoints]; FFTHelper.IntegrateFromSpectrum(ToFloatArray(tw.Data) /*原始波形*/, tw.DataHz, tw.DataPoints, ms.MsrRateMin, GetFrequencyByType(ms.MsrRateMax, type), 1, ref velTw); for (int k = 0; k < velTw.Length; k++) { velTw[k] = velTw[k] * 9800; } //速度频谱 float[] velSpectrum = GetVelSpectrum(accSpectrum, tw.DataHz, tw.DataPoints); for (int k = 0; k < velSpectrum.Length; k++) { velSpectrum[k] = velSpectrum[k] * 9800 / 1.414f; } //波形存储 //tw.data = ToByteArray(velTw); _dataTwService.InsertDataTw(tw, string.Format("tb_data_tw_{0}", ms.MsrName)); //频谱存储 tw.DataIsFFT = 1; tw.Data = ToByteArray(velSpectrum); //获取频谱 tw.Data = SplitMinFFT(tw.Data, ms); //截取最小Fmin _dataTwService.InsertDataTw(tw, string.Format("tb_data_tw_{0}", ms.MsrName)); } return(_mapper.Map <DataTwModel>(tw)); } return(null); }