【问题标题】:plotting real time Data on (qwt )Oscillocope在 (qwt) 示波器上绘制实时数据
【发布时间】:2014-02-09 07:11:11
【问题描述】:

我正在尝试使用 Qt (c++) 创建一个程序,该程序可以使用 QAudioinput 和 QIODevice 从我的麦克风录制音频。 现在,我想可视化我的信号

任何帮助将不胜感激。谢谢

[Edit1] - 复制自您的评论(由 Spektre 提供)

  • 我只有一个缓冲区用于两个通道
  • 我用的是Qt,channel的值在buffer上是交错的
  • 这就是我分离值的方式

    for ( int i = 0, j = 0; i < countSamples ; ++j) 
     {
     YVectorRight[j]=Samples[i++];
     YVectorLeft[j] =Samples[i++];
     }
    
  • 在绘制 YvectorRight 和 YvectorLeft 之后。我看不到如何只触发一个频道

【问题讨论】:

  • +1 用于不常见的硬件相关问题。看看我的回答。稍微编辑您的问题,添加您已经尝试过的内容以及需要解决的内容。任何带有可见文本的编辑标志(我会这样做 [edit1],[edit2]),并添加您已编辑内容的评论,以便评论列表中的任何人获得通知
  • 我没有使用 QT/QWT 但你可以使用定时器或线程函数(定时器是一个组件,将它添加到窗口设置间隔,并在它的 ontimer 事件中进行绘图)线程只需使用 CreateThread .. . (在 Windows 和 linux 中我认为是一样的)

标签: c++ plot qwt real-time-data


【解决方案1】:

呵呵,几年前在课堂上为学生做了这个。我希望你知道示波器是如何工作的,所以这里只是基础知识:

  1. 时基

    • fsmpl 为输入信号采样频率[Hz]

    尝试使用尽可能大的(44100,48000, ???),以便检测到的最大频率为fsmpl/2,这为您提供了时基轴的顶部。下限由您的缓冲区长度给出

  2. 创建将从指定起始地址(缓冲区内)呈现采样缓冲区的函数:

    • Y-scale ...幅度设置
    • Y 偏移 ... 垂直光束位置
    • X-offset ... 时移或水平位置

    这可以通过修改起始地址或仅通过 X 偏移曲线来完成

  3. 等级

    创建将模拟 Level 功能的函数。所以从起始地址搜索缓冲区,如果幅度超过电平则停止。你可以有更多的模式,但这些是你应该实现的基础:

    • 幅度:( &lt; lvl ) -&gt; ( &gt; lvl )
    • 幅度:( &gt; lvl ) -&gt; ( &lt; lvl )

    关卡还有许多其他可能性,例如故障、相对边缘、...

  4. 预览

    您可以将所有这些放在一起,例如:您有start address 变量,因此将数据连续采样到某个缓冲区,并在计时器调用levelstart address(并更新它)。然后用新的start address 调用draw 并将timebase period 添加到start address(当然就您的样本而言)

  5. 多渠道

    我使用 Line IN 所以我有立体声输入(A,B = 左,右),因此我可以添加一些其他内容,例如:

    • 关卡源 (A,B,none)
    • 渲染模式(时基,切比雪夫(Lissajous 曲线,如果闭合))
    • Chebyshev = x 轴是Ay 轴是B 这将创建著名的切比雪夫图像,这些图像对相关的正弦信号非常有用。通常形成圆形、椭圆、扭曲的循环......
  6. 杂项

    您可以为模拟电容或输入接地等通道添加滤波器

  7. 图形界面

    你需要很多设置我更喜欢模拟旋钮而不是按钮/滚动条/滑块,就像在真正的示波器上一样

    • (半)模拟值:幅度、时基、电平、X-offset、Y-offset
    • 离散值:电平模式(/,),电平源(A,B,-),每个通道(直接开启,接地,关闭,容量开启)

这是我的示波器的一些截图:

这是我的生成器的屏幕截图:

最后在添加一些 FFT 之后还有频谱分析仪

附言。

  • 我从 DirectSound 开始,但由于有错误/无功能的缓冲区回调,它很糟糕
  • 我现在使用 WinAPI WaveIn/Out 来处理我的应用程序中的所有声音。经过几次怪癖后,它是最适合我的需求并且具有最佳延迟(Directsound 太慢了 10 倍以上)但对于示波器它没有任何优点(我需要低延迟主要用于模拟器)

顺便说一句。我将这三个应用程序作为可链接的 C++ 子窗口类 (Borland)

  • 最后一次与我的 ATMega168 仿真器一起用于我的无传感器 BLDC 驱动程序调试
  • 在这里你可以试试我的Oscilloscope,generator and Spectrum analyser 如果你对下载感到困惑,请阅读这篇文章下面的 cmets 顺便说一句密码是:“oscill”

如果您需要任何帮助,请评论我,希望对您有所帮助

[Edit1] 触发器

您一次触发所有通道,但通常只从一个通道检查触发条件 现在实现很简单,例如让 触发条件 成为 A(left) 通道上升到水平以上 所以:

  1. 先不触发你写的连续播放是这样的:

    for ( int i = 0, j = 0; i < countSamples ; ++j) 
     {
     YVectorRight[j]=Samples[i++];
     YVectorLeft[j] =Samples[i++];
     }
    // here draw or FFT,draw  buffers YVectorRight,YVectorLeft
    
  2. 添加触发器

    要添加触发条件,您只需找到满足它的样本并开始从中绘制,然后将其更改为类似的东西

    // static or global variables
    static int i0=0; // actual start for drawing
    static bool _copy_data=true; // flag that new samples need to be copied
    static int level=35; // trigger level value datatype should be the same as your samples...
    
    int i,j;
    for (;;)
     {
     // copy new samples to buffer if needed
     if (_copy_data)
      for (_copy_data=false,i=0,j=0;i<countSamples;++j) 
      {
      YVectorRight[j]=Samples[i++];
      YVectorLeft[j] =Samples[i++];
      }
     // now search for new start
     for (i=i0+1;i<countSamples>>1;i++) 
      if (YVectorLeft[i-1]<level) // lower then level before i
       if (YVectorLeft[i]>=level) // higher then level after i
        {
        i0=i;
        break;
        }
     if (i0>=(countSamples>>1)-view_samples) { i0=0; _copy_data=true; continue; }
     break;
     }
    // here draw or FFT,draw  buffers YVectorRight,YVectorLeft from i0 position
    
    • view_samples 是查看/处理的数据大小(对于一个或多个屏幕),它应该比(countSamples&gt;&gt;1) 小几倍
    • 此代码可以在边框区域松动一屏以避免您需要实现循环缓冲区(环),但对于初学者来说甚至可以这样做
    • 只需通过一些 if 或 switch 语句对所有触发条件进行编码

【讨论】:

  • 您可以在您的问题中发布您的代码,以便其他人也可以看到并提供帮助(只是不要忘记选择它并单击代码格式按钮,以便在该灰色区域中使用语法查看它突出显示和代码行格式)如果您在项目符号下添加代码,则在每行中添加 n*4 个空格,直到它变为灰色。对于子问题,也将它们添加到您的问题中(例如 Q1、Q2、...),我们将尝试回答它们(我相信其他人会添加到此)。顺便说一句,我主要在 bds2006 C++ win32 中编写代码,因此与 Qwt 或不同平台相关的问题无论如何都必须回答其他人。
  • 附言。下载这个:ulozto.sk/xFASrEPv/soundio-exe-rar 密码是“oscil”,它使用 Windows 声音设置中的首选声音输入和输出
  • 您好 Spektre,您如何生成三角波和方波?
  • @user2932518 很容易使用 for 循环或预先计算的表 ... for 循环三角形形状是 for (i=0;iratio) out[i] = 0 else out[i] = Amplitude;
  • 两个通道只有一个缓冲区,我使用 Qt ,通道的值在缓冲区上交错。这就是我如何分离 (int i = 0, j = 0; i
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多