Assembly 音频合成的数据结构

Posted

技术标签:

【中文标题】Assembly 音频合成的数据结构【英文标题】:Data structure for Assembly audio synthesis 【发布时间】:2012-11-03 18:35:52 【问题描述】:

我正在编写一个简单的汇编合成器作为一个学习项目,我想实现现代合成器上的一些更高级的功能,即 ADSR 包络和使用正弦波的脉冲宽度调制。目前,我基本上是手动生成样本并将它们推送到音频输出,它有一个样本缓冲区,当缓冲区接近空时它会产生一个中断。

我坚持的是如何生成“连续”波形。目前,我为单个波实例(无论是锯齿波还是脉冲波)生成样本,然后简单地循环该波以生成连续输出。正如您可以想象的那样,这不能很好地扩展到 PWM 和 ADSR 包络。因此,我需要按需生成波,并对其进行动态调整,例如调制脉冲宽度或音高(例如,用于连奏),但我不知道如何在内存中有效地表示它,以及如何在缓冲区已满时“暂停”波形生成,并在中断出现时“恢复”。

我不是在寻求解决方案,而是在推动正确的思考方向:-)

谢谢!

【问题讨论】:

【参考方案1】:

按需生成 wave 将适用于简单的 wave,但如果您以后想要添加额外的功能/dsps,您仍然需要某种缓冲区。

幅度的ADSR相当简单,因为你只是缩放波形,对于频率调制它有点复杂,这是一篇解释它的文章link

你也可以查看farbraushgithub,应该会有一些不错的灵感给你。

【讨论】:

【参考方案2】:

看来您生成波的方式是减法合成的合适方法。如果要调整波形的 PWM,则必须重新生成样本(或检索存储在内存中的预先计算的波形)。

在大多数情况下,如果音高发生变化,您还需要重建波表。您可以通过计算读取指针相对于波基的增量来以更快的速度读取波,但这需要在波表中的值之间进行插值,并且可能会在更复杂的波中引入混叠。

当然,在大多数情况下,生成的波不太可能恰好是 2^n 个样本。因此,在处理例程开始时,首先从前一个波形中复制样本,然后再将当前波形复制到输出缓冲区。

您不希望再生过程中断您的 DSP 处理例程,因此我会在单独的内存位置构建更新后的波形,并在准备好时将其复制。

ADSR 包络(减法)应在波生成后作为移动增益系数应用,而不是影响波本身。

希望有帮助:)

【讨论】:

所以您的意思是,在 RAM 中的某处生成波形,然后直接输入,而不是为即时渲染而烦恼?但目前我只有一波。将更复杂的波存储在内存中的某个位置,我将如何处理任意长度的延音之类的事情?我考虑在预渲染样本中设置“循环点”,但如果我正在调制频率或脉冲宽度,则循环必须具有潜在的巨大长度。我想我错过了一块拼图…… 我需要了解更多关于你的合成器是如何被驱动的。在大多数插件效果/合成器(我熟悉)的情况下,客户端通过调用“处理”函数定期请求 2 个样本块的功率。对 DSP 的更新是通过进程请求之间的参数更改事件回调完成的。你的实现类似吗? 类似,是的。我的问题主要是关于如何生成这样的 2^ 块,特别是考虑到音高和脉冲宽度调制。

以上是关于Assembly 音频合成的数据结构的主要内容,如果未能解决你的问题,请参考以下文章

《CLR Via C#》使用CSC.exe将module组合成assembly

文本转音频(百度语音合成api)(python)

在音频合成方面使用 vDSP(加速框架)

使用软件合成器制作实时音频应用程序

使用软件合成器将 MIDI 文件转换为原始音频

格式工厂 音频合成问题