| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346 |
- 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();
- }
- /// <summary>
- /// 重写 DesignMode
- /// </summary>
- 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;
- }
- }
- /// <summary>
- /// 频谱窗口大小发生改变
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void spePanel_Resize(object sender, EventArgs e)
- {
- if (DesignMode)
- return;
- if (speView != IntPtr.Zero)
- {
- IfeQTSpect.ResizeView(speView, this.spePanel.Width, this.spePanel.Height);
- }
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="fun"></param>
- public void RegisterSelectIndexChanged(IfeQTSpect.SelectIndexChanged fun)
- {
- if (speView != IntPtr.Zero)
- {
- IfeQTSpect.RegisterSelectIndexChanged(speView, fun);
- }
- }
- /// <summary>
- /// 清空信号展示页面
- /// </summary>
- public void Clear()
- {
- if (speView != IntPtr.Zero)
- {
- IfeQTSpect.Clear(speView);
- }
- }
- /// <summary>
- /// 选中指定频率
- /// </summary>
- /// <param name="freq"></param>
- public void HitFrequence(double freq)
- {
- if (speView != IntPtr.Zero)
- {
- IfeQTSpect.SelectFrequence(speView, freq);
- }
- }
- /// <summary>
- /// 空间初始化
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- 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;
- }
- /// <summary>
- /// 设置数据源
- /// </summary>
- /// <param name="fileName">原始文件</param>
- /// <param name="fsample">采样率 Hz</param>
- /// <param name="beIQ">是否IQ数据</param>
- /// <param name="minFreq">显示的最小频率</param>
- /// <param name="fftOrder">fft阶数</param>
- /// <param name="smoothCount">平滑次数</param>
- /// <param name="autodoor"></param>
- /// <param name="doorline"></param>
- /// <param name="detectBw"></param>
- /// <param name="detectSnr"></param>
- 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);
- /// <summary>
- /// 界面当前选择改变
- /// </summary>
- /// <param name="index"></param>
- public delegate void SelectIndexChanged(int index);
- /// <summary>
- /// 初始化 必须在Main函数中提前调用
- /// </summary>
- [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
- public static extern void Init();
- /// <summary>
- /// 创建一个频谱展示控件
- /// </summary>
- /// <param name="parent"></param>
- /// <returns></returns>
- [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
- public static extern IntPtr CreateView(IntPtr parent, int w, int h);
- /// <summary>
- /// 销毁控件
- /// </summary>
- /// <param name="view"></param>
- [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
- public static extern void DestoryView(IntPtr view);
- /// <summary>
- /// 计算频谱
- /// </summary>
- /// <param name="fileName"></param>
- /// <param name="beIQ"></param>
- /// <param name="fftOrder"></param>
- /// <param name="smoothCount"></param>
- [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
- public static extern IntPtr CalcFFT(String fileName, bool beIQ, int fftOrder, int smoothCount);
- /// <summary>
- /// 释放C++申请的内存空间
- /// </summary>
- /// <param name="ptr"></param>
- [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
- public static extern void freeBuffer(IntPtr ptr);
- /// <summary>
- /// 显示频谱数据
- /// </summary>
- /// <param name="ptr"></param>
- /// <param name="buffer"></param>
- /// <param name="len"></param>
- /// <param name="beIQ"></param>
- /// <param name="fsample"></param>
- /// <param name="minFreq"></param>
- [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);
- /// <summary>
- /// 输入频谱检测信号
- /// </summary>
- /// <param name="fftbuffer"></param>
- /// <param name="len"></param>
- /// <param name="reslen"></param>
- /// <param name="sf"></param>
- /// <param name="ef"></param>
- /// <param name="bw"></param>
- /// <param name="autodoor"></param>
- /// <param name="doorline"></param>
- /// <param name="detectBw"></param>
- /// <param name="detectSnr"></param>
- /// <returns></returns>
- [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);
- /// <summary>
- /// 注册界面信号变动
- /// </summary>
- /// <param name="ptr"></param>
- /// <param name="fun"></param>
- [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
- public static extern void RegisterSelectIndexChanged(IntPtr ptr, SelectIndexChanged fun);
- /// <summary>
- /// 创建一个频谱展示控件
- /// </summary>
- /// <param name="parent"></param>
- /// <returns></returns>
- [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
- public static extern void ResizeView(IntPtr ptr, int w, int h);
- /// <summary>
- /// 清空页面展示
- /// </summary>
- /// <param name="parent"></param>
- /// <returns></returns>
- [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
- public static extern void Clear(IntPtr ptr);
- /// <summary>
- /// 设置显示范围
- /// </summary>
- [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
- public static extern void SetShowRangeX(IntPtr ptr, double vMin, double vMax);
- /// <summary>
- /// 选中一个信号
- /// </summary>
- /// <param name="freq">信号中心频率</param>
- [DllImport(dllName, CallingConvention = CallingConvention.Cdecl)]
- public static extern void SelectFrequence(IntPtr ptr, double freq);
- }
- }
|