1

我想在 Qt 中创建一个准确的信号发生器。

例如,10us(微秒)生成 255 和 10ms(毫秒)生成 0 的方波信号。

我在我的线程中使用了 usleep() 但它睡了大约 1 毫秒!当搜索它时,我发现它是用于 CPU 上下文切换的。

//fp:frequency of signal //t:time of generate high (amp) // n:generate n time

void Thread::rectGenerator(double fp, double t, double amp, double n)
{
    double result;
    double T=1000000/fp; //(us)
    for (double i=0,ii=0; i<n*T; i+=_Interval,ii+=_Interval)
    {
        if (ii>=T)
            ii=0;
        if (ii<=t)
            result=amp;
        else
            result=0;
        th.usleep(1);
        qDebug() << i << "\t" <<result;
    }
}

结果:rectGenerator(200, 20, 255, 12) 在 12 秒内执行,但它应该在 60(ms) 内执行!!!

那么产生准确信号的最佳方法是什么?

4

3 回答 3

2

通常你会做的是分配一个代表一定时间量的缓冲区,用你生成的信号填充这个缓冲区,然后安排它播放、保存或流式传输。(你没有指定你对信号做了什么,但由于你是用线程做的,我假设它是近似实时的)。

假设您的目标采样率为 48kHz(专业音频的标准)。然后,您将分配一个包含 48000 个浮点样本的缓冲区来存储 1 秒的音频。(使用 double 几乎可以肯定是矫枉过正;高质量的音频是 16 位或可能是 24 位,如果您掌握顶级系统,则为 32 位,因此 float 精度绰绰有余; double 浪费位)。

然后,您将使用与您在上面粘贴的内容非常相似的循环函数,用您的信号填充此缓冲区。但是你不使用 sleep 或类似的东西;目前,您只是准备稍后播放的数据。

因此,一旦准备好音频缓冲区,就需要安排播放它。这通常涉及您将缓冲区发送到系统以在特定时间播放。根据 API 或设备,当达到低水位标记时,您将收到一个回调来填充缓冲区,等等。

如果您的信号永远不会改变,您可以只生成一个缓冲区并通过重新安排播放来继续重用它。根据信号的周期,您可能需要调整缓冲区大小以保持正确的频率。

(请注意,您所描述的纯方波理论上需要无限带宽才能再现,其砖墙边缘;您可能应该应用低通滤波器来限制信号,这取决于您的输出设备。)

于 2013-07-16T12:33:16.150 回答
0

对于 10 uS 范围内的精度,您最好将信号生成卸载到专用硬件(FPGA 或具有实时或无操作系统的微控制器)。

于 2013-07-16T16:10:06.023 回答
0

由于您需要 100 Khz 信号,到目前为止,最简单的解决方案是使用旨在创建该范围内信号的设备。一个好的声卡可以实现这一点,并且很容易编程。只需加载您的样本并告诉它播放。它的内部硬件将完成所有计时。

于 2013-07-16T19:29:48.670 回答