使用 GLSL 进行频率调制?

Posted

技术标签:

【中文标题】使用 GLSL 进行频率调制?【英文标题】:Frequency Modulation using GLSL? 【发布时间】:2012-07-31 15:32:34 【问题描述】:

1。上下文

我正在使用GLSL 来绘制给定频率下的波形幅度,如下所示:

显示像上面这样的简单波形是一项微不足道的任务,只需使用正确的方程即可(GLSL 摘录代码可用here)。我现在要做的是在两个波形之间显示频率调制的结果。


2。研究

经过一些研究,我发现了两种可能的方法来实现这一点:

    使用类似 dsp 的方法,据我所知,使用 相位累加器(请参阅 first answer here)结合查找表是建议的方法在使用信号处理时。作为一个 GLSL 初学者,我明白这对于 GLSL 着色器来说是不可能的,因为它们不能跨多个 GPU 周期存储和增加变量。

    使用纯数学方法,这涉及到像 Chowning 的 simple fm formula 这样的方程。 FM formula http://img577.imageshack.us/img577/4820/fmformula.png 该公式在某些情况下非常有效(cosine wave modulating another cosinecosine modulating a sawtooth),但我无法找到适用于所有情况的通用方程(当 锯齿波 调制 余弦我期待the carrier frequency to be modulated by sawtooth amplitude,但我得到的只是显然未调制的载波)。


3。问题

解决此问题的最佳方法是什么? GLSL 是否可以使用类似 dsp 的方法? 如果没有,是否有足够灵活的通用 FM 方程来完成所有工作?

考虑到我在这里所涉及的所有学科(音频 dsp、计算机科学、gpu 编程、数学)方面都缺乏技能,如果我在这里遗漏了一些非常简单的东西,我不会感到惊讶。请耐心等待。

【问题讨论】:

我建议从 CPU 实现开始。实现 CPU 后,将其移植到 GPU 应该相当简单。使用 CUDA、ATIStream 或 OpenCL 而不是 GLSL 可能会更好,除非你只是想看看波形是什么样子的。 GLSL 在设计时并没有真正考虑到 GPGPU 任务。 【参考方案1】:

您说得对,相位累加器的通常类似 dsp 的方法不太适合在 GPU 上进行并行计算。因此,“纯数学”方法可能是最好的选择。

Wikipedia page for Frequency Modulation(该页面上的第一个方程)给出了将 Chowing 的简单 FM 公式推广到更通用的频率调制函数。关键是 cos 函数的参数是 phase,正如 Wikipedia 上的等式所示,它是频率的时间积分。在 FM 中,频率通常是一个载波加上一个调制:例如,对于简单的正弦 FM,使用 Chowing 的公式,频率作为时间的函数t

f(t) = f_c - M * f_m * sin(f_m * t)

其中f_c是载波频率,M是调制量,f_m是调制频率。这融入了相位

p(t) = f_c * t + M * cos(f_m * t)

对应于您问题等式中的阶段。

要使用锯齿调制余弦,f(t) 将是锯齿波(加上载波频率),因此要找到 p(t),您需要找到锯齿波的时间积分。这相对简单(它应该是一个分段二次函数),但如果您遇到困难,math.stackexchange 的人应该能够提供帮助。

(注意:我在这里用时间来表达所有内容t,但这也可以是空间x。)

【讨论】:

以上是关于使用 GLSL 进行频率调制?的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 中计算频率调制

计算机网络--物理层

射频信号发生器的使用以及相关中心频率,载波,调制波术语解释

[Matlab]在信号调幅过程中用方波进行调幅还是正弦波?为啥?

载波(带通)调制

GLSL 问题:一个程序中有多个着色器