A. 我读过技术 1 是处理器密集型的,而且不是真正可行的。这是否适用于 ARM 处理器,例如 iPad 上的处理器?
这使得一个简单的问题变得复杂(双关语)。Accelerate.framework 提供了这些函数的优化变体(fwiw),但它仍然使一个简单的问题复杂化。作为一般说明:设备上的浮点计算很慢。浮点实现可能会大大损害您的程序。它可能会显着影响功能、复音或质量。在不知道要求的情况下,很难说您是否可以使用浮点计算。
B. 无论我最终选择何种技术,是否可以简单地通过将低通滤波器连接到振荡器的输出端来解决混叠问题?
除非您过采样,否则这不适用于时域中生成的信号。
C. 关于如何实现这种振荡器的任何其他建议?
见下文
D. 关于使用哪个 C++ 工具包有什么建议吗?我一直在看 CCRMA 的 STK,但我不知道是否还有其他更合适的库。
STK 更像是一种教学工具,而不是为嵌入式合成器设计的工具包。存在更合适的实现方式。
选项 1. 提出一个函数,该函数获取旋钮位置并计算实际信号的频谱(幅度和频率的数组),然后使用一堆正弦函数和一个求和块来实现输出信号。
选项 2。类似于 1。但应用反向傅立叶变换而不是正弦和求和(好的,此时我不确定它们是否实际上是同一件事。)
这在台式机上相对较慢。
选项 4. 从 2 个锯齿波开始(它们包含偶次和奇次谐波),将其中一个反转并求和,并用旋钮控制每个锯齿波的幅度。波形不会是
对于无别名生成,您可以非常有效地执行此操作(例如,使用 BLIT)。但是,BLIT 仅限于少数波形(您可以将其用于 Saw 和 Square)。您可以回顾历史并询问“他们是如何在 2000 年左右的硬件和软件合成器中解决这个问题的”。这是一种解决方案。另一个是:
选项 3. 为每个可能的旋钮位置生成波形表,并使用波形表合成技术生成输出信号。
考虑到设备的功能,我推荐这个或 BLIT 的 int 实现。
该表易于理解和实施,并提供良好的声音和 CPU 结果。它对于 CPU/内存/质量权衡也是高度可配置的。
如果您想要免费(或关闭)别名,请选择 BLIT(或亲属)。原因是您需要大量的内存和大量的过采样,以最大限度地减少波表的可听混叠。
执行:
在线有许多 BLIT(和系列)实现。
这是一张桌子上的餐巾纸:
enum { WF_Sine, WF_Saw, WF_Square, WF_COUNT };
enum { TableSize = SomePowerOfTwo };
struct sc_waveform {
uint32_t at[TableSize];
};
enum { NPitches = Something };
sc_waveform oscs[WF_COUNT][NPitches];
初始化后,使用加法合成来填充oscs
.
在播放期间,使用以下任一:
- 从表格中读取的插值和过采样
- 或者对信号进行大量过采样,然后进行下采样(这是 CPU 高效的)。
供参考:我会估计一个表格的线性插值,它消耗了不负责任的内存量(考虑到可用的数量)而没有过采样,如果你不想听到最高分音,你的混叠频率应该保持在 -40 dB 或以下以 44.1kHz 渲染。这是一种天真的蛮力方法!你可以通过一些额外的工作做得更好。
最后,如果您搜索“矢量合成”,您还应该找到相关信息——您所描述的是它的原始形式。