using System; using System.ComponentModel; using System.Windows.Forms; using System.Runtime.InteropServices; using System.IO; using DevExpress.XtraEditors; namespace Ips.Sps.IfeSpects { public partial class IfeSpectCtrl : XtraUserControl { IntPtr speView = IntPtr.Zero; public IfeSpectCtrl() { InitializeComponent(); } static IfeSpectCtrl() { IfeQTSpect.Init(); } /// /// 重写 DesignMode /// protected new bool DesignMode { get { bool flag = false; if (LicenseManager.UsageMode == LicenseUsageMode.Designtime) { flag = true; } else if (System.Diagnostics.Process.GetCurrentProcess().ProcessName.ToUpper().Equals("DEVENV")) { flag = true; } return flag; } } /// /// 频谱窗口大小发生改变 /// /// /// private void spePanel_Resize(object sender, EventArgs e) { if (DesignMode) return; if (speView != IntPtr.Zero) { IfeQTSpect.ResizeView(speView, this.spePanel.Width, this.spePanel.Height); } } /// /// /// /// public void RegisterSelectIndexChanged(IfeQTSpect.SelectIndexChanged fun) { if (speView != IntPtr.Zero) { IfeQTSpect.RegisterSelectIndexChanged(speView, fun); } } /// /// 清空信号展示页面 /// public void Clear() { if (speView != IntPtr.Zero) { IfeQTSpect.Clear(speView); } } /// /// 选中指定频率 /// /// public void HitFrequence(double freq) { if (speView != IntPtr.Zero) { IfeQTSpect.SelectFrequence(speView, freq); } } /// /// 空间初始化 /// /// /// private void ItcSpectrum_Load(object sender, EventArgs e) { if (DesignMode) return; //频谱绘制 speView = IfeQTSpect.CreateView(this.spePanel.Handle, this.spePanel.Width, this.spePanel.Height); //test //SetSource(@"E:\1.dat", 100000000, false, 1031000000, 13, 40, false, 100, 1500000, 5); } private double[] SetRealSource(String fileName, int fsample, UInt64 midFreq, int fftOrder, int smoothCount , bool autodoor, double doorline, int detectBw, double detectSnr) { double[] ret = null; if (speView != IntPtr.Zero) { IntPtr fft = IfeQTSpect.CalcFFT(fileName, false, fftOrder, smoothCount); int len = (int)Math.Pow(2, fftOrder - 1); float[] ckfft = new float[len]; Marshal.Copy(fft, ckfft, 0, len); int sigCount = 1000; double[] tmp = new double[sigCount * 3]; float fFreqReso = (float)(fsample / 2.0 / len); //IfeQTSpect.SignalDetecting(ckfft, len, fFreqReso, 1.0f, tmp, ref sigCount); IfeQTSpect.SignalDetecting(ckfft, len, fFreqReso, detectSnr, tmp, ref sigCount); double[] sigs = null; if (sigCount > 0) { ret = new double[sigCount * 3]; sigs = new double[sigCount * 3]; for (int idx = 0; idx < sigCount; ++idx) { sigs[3 * idx] = tmp[3 * idx]; sigs[3 * idx + 1] = tmp[3 * idx + 1]; sigs[3 * idx + 2] = tmp[3 * idx + 2]; ret[3 * idx] = tmp[3 * idx] + midFreq - 20000000; ret[3 * idx + 1] = tmp[3 * idx + 1]; ret[3 * idx + 2] = tmp[3 * idx + 2]; } } IfeQTSpect.ShowFFT(speView, fft, len, false, fsample, midFreq - 20000000, sigs, sigCount); IfeQTSpect.freeBuffer(fft); } return ret; } private double[] SetIQSource(String fileName, int fsample, UInt64 midFreq, int fftOrder, int smoothCount , bool autodoor, double doorline, int detectBw, double detectSnr) { double[] ret = null; if (speView != IntPtr.Zero) { IntPtr fft = IfeQTSpect.CalcFFT(fileName, true, fftOrder, smoothCount); int len = (int)Math.Pow(2, fftOrder); IntPtr tmpFFT = IntPtr.Add(fft, (int)(len * 0.1) * sizeof(float)); float[] ckfft = new float[(int)(len * 0.8)]; Marshal.Copy(tmpFFT, ckfft, 0, (int)(len * 0.8)); int sigCount = 1000; double[] tmp = new double[sigCount * 3]; float fFreqReso = (float)(fsample * 1.0 / len); //IfeQTSpect.SignalDetecting(ckfft, (int)(len * 0.8), fFreqReso, 1.0f, tmp, ref sigCount); IfeQTSpect.SignalDetecting(ckfft, (int)(len * 0.8), fFreqReso, detectSnr, tmp, ref sigCount); double[] sigs = null; if (sigCount > 0) { ret = new double[sigCount * 3]; sigs = new double[sigCount * 3]; for (int idx = 0; idx < sigCount; ++idx) { sigs[3 * idx] = tmp[3 * idx] + fsample * 0.1 /*+ (midFreq - (UInt64)fsample / 2)*/; sigs[3 * idx + 1] = tmp[3 * idx + 1]; sigs[3 * idx + 2] = tmp[3 * idx + 2]; ret[3 * idx] = tmp[3 * idx] + fsample * 0.1 + (midFreq - (UInt64)fsample / 2); ret[3 * idx + 1] = tmp[3 * idx + 1]; ret[3 * idx + 2] = tmp[3 * idx + 2]; } } IfeQTSpect.ShowFFT(speView, fft, len, true, fsample, (midFreq - (UInt64)fsample / 2), sigs, sigCount); IfeQTSpect.freeBuffer(fft); } return ret; } /// /// 设置数据源 /// /// 原始文件 /// 采样率 Hz /// 是否IQ数据 /// 显示的最小频率 /// fft阶数 /// 平滑次数 /// /// /// /// public double[] SetSource(String fileName, int fsample, bool beIQ, UInt64 midFreq, int fftOrder, int smoothCount , bool autodoor, double doorline, int detectBw, double detectSnr) { double[] ret = null; if (!beIQ) { ret = SetRealSource(fileName, fsample, midFreq, fftOrder, smoothCount, autodoor, doorline, detectBw, detectSnr); } else { ret = SetIQSource(fileName, fsample, midFreq, fftOrder, smoothCount, autodoor, doorline, detectBw, detectSnr); } return ret; } } public class IfeQTSpect { //动态库位置 public const string dllName = @"IfeSpect\IfeSpect.dll"; [DllImport(dllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, SetLastError = true)] public static extern bool SignalDetecting(float[] Spectrum, int SpecLen, double freqReso, double snrThreshold, double[] Sig, ref int SigNum); /// /// 界面当前选择改变 /// /// public delegate void SelectIndexChanged(int index); /// /// 初始化 必须在Main函数中提前调用 /// [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] public static extern void Init(); /// /// 创建一个频谱展示控件 /// /// /// [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr CreateView(IntPtr parent, int w, int h); /// /// 销毁控件 /// /// [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] public static extern void DestoryView(IntPtr view); /// /// 计算频谱 /// /// /// /// /// [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr CalcFFT(String fileName, bool beIQ, int fftOrder, int smoothCount); /// /// 释放C++申请的内存空间 /// /// [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] public static extern void freeBuffer(IntPtr ptr); /// /// 显示频谱数据 /// /// /// /// /// /// /// [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] public static extern void ShowFFT(IntPtr ptr, IntPtr buffer, int len, bool beIQ , int fsample, UInt64 minFreq , double[] sig, int siglen); /// /// 输入频谱检测信号 /// /// /// /// /// /// /// /// /// /// /// /// [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr fftCheck(IntPtr fftbuffer, int len, ref int reslen , double sf, double ef, double bw , bool autodoor, double doorline, int detectBw, double detectSnr); /// /// 注册界面信号变动 /// /// /// [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] public static extern void RegisterSelectIndexChanged(IntPtr ptr, SelectIndexChanged fun); /// /// 创建一个频谱展示控件 /// /// /// [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] public static extern void ResizeView(IntPtr ptr, int w, int h); /// /// 清空页面展示 /// /// /// [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] public static extern void Clear(IntPtr ptr); /// /// 设置显示范围 /// [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] public static extern void SetShowRangeX(IntPtr ptr, double vMin, double vMax); /// /// 选中一个信号 /// /// 信号中心频率 [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)] public static extern void SelectFrequence(IntPtr ptr, double freq); } }