生成 100 个相互叠加的正弦波的计算效率最高的方法是什么?

信息处理 采样 调制 软件实现 表现
2022-01-28 00:57:18

现在我只是这样做(伪代码)

for freq in freqs:
    for i in len(samples):
        samples[i] += sin(...)

有没有更好的办法?这用于在 ARM7 设备上使用 C 输出到 16 位 WAV 文件。频率实际上是特定 bin 大小的 FFT bin 的中心。

3个回答

计算效率最高的方法是在频域中设置您想要的数据,方法是将音调作为“尖峰”放入适当的频率区间,然后对其进行逆 FFT 处理以获得时域音调。这种方法可能会比您的方法快几个数量级左右。

这样做有一些缺点。对于频率是样本频率的整数倍除以样本数量的音调,这很容易——只需在适当的频率仓中放入一个尖峰。但是,对于所有其他频率,您也需要将一些能量放入相邻的箱中。我将不得不考虑如何确切地弄清楚如何做到这一点。我确信它可以做到,但这并不是一件容易的事。

此外,如果您只需要生成带有音调的样本块,这种方法是理想的。但是,如果您需要创建一个连续的流,则必须注意从一个块到另一个块的正确相位。再一次,不是一个明智的选择。

尽管如此,我很确定这是计算效率最高的方法。

加法合成在 CPU 上总是相当繁重。如果您还没有,我会考虑使用波表振荡器来生成您的正弦波。展开你的循环也可能是值得的(一定要进行分析,这样你就可以看到它是否有所作为)。

您确实需要分析您的代码并确定程序特有的瓶颈。

麦克风

您可以做两件事来加快速度:

  1. 进行基于帧的处理,即在将它们写入波形文件之前一次计算 1000 个左右的样本
  2. 最小化对超越函数(例如正弦和余弦)的调用

这个问题的第二个答案如何创建可以在频率之间平滑转换的正弦波发生器显示了一种算法,该算法仅在初始化期间使用超越函数,并且每个样本和正弦波仅使用 4 次乘法。