1个稳定版本
1.0.0 | 2024年2月10日 |
---|
#413 in 音频
115KB
3K SLoC
heron-sound
是一个用于Heron Sounds音频插件的DSP工具库。
目前支持以下DSP组件
- 包络发生器(ADSR,指数ADSR,DA)
- 包络跟随器
- 滤波器(状态变量)
- 基本波形(锯齿波,正弦波,脉冲波,三角形)
- 基于基本波形的振荡器
- 低频振荡器
- 参数调制的工具
- 音高操纵工具
- 位掩码实现
- 样本率操纵工具
以及支持上述功能的各种实用工具。
实现
为了帮助开发DSP组件,我们提供了两个基本特性,Gen和Proc。 Gen
用于不需要任何明确输入即可从其内部状态生成一些值的组件,而 Proc
用于接收某些输入值并产生输出的处理器。输入和输出可以是样本、增益或更复杂的数据类型,但不应该是用户可修改的参数。
为了传递用户可修改的参数,这两个特性都有一个 Spec
关联类型,它在处理时通过共享引用传递并评估,并与处理器的内部状态一起产生输出。
例如,包络跟随器可以作为Proc实现,它接收一个输入样本并返回一个bool值,指示包络是否激活
struct EnvFollower {
engaged: bool,
counter: u32,
}
struct EnvFollowerSpec {
threshold: f64,
hold_time: u32,
}
impl Proc<f64, bool> for EnvFollower {
type Spec = EnvFollowerSpec;
fn proc(&mut self, spec: &Self::Spec, sample: f64) -> bool {
// implementation omitted
}
}
它的内部状态跟踪它当前是否激活以及持续时间,它的相关 Spec
类型跟踪幅度阈值和保持时间,这两个都可以由用户设置。在处理时间,它检查输入样本的幅度是否高于阈值,增加其内部计数器并检查它与用户设置的保持时间,然后计算一个布尔值返回。要了解如何在实践中实现,请查看EnvFollower和EnvFollowerSpec。
此库中的大部分代码都是 Gen
和 Proc
的实现,但我们还在util模块中包含了一些杂项工具。
方法
此库中的组件实现遵循以下约束
- 保持内存使用率低
- 但优先考虑缓存值而不是重新计算
- 在处理过程中避免分配
- 在处理过程中尽可能少进行操作
- 在用户可修改的参数和内部可变状态之间保持严格的界限
- 最小化依赖关系
- 避免不安全代码
以及一些更宽松的约束条件
- 避免使用newtypes,但在有助于可读性的地方使用类型别名
- 使用
f64
作为默认的浮点类型 - 优先使用相位偏移而不是赫兹数中的音高,以最小化计算(参见音高)
- 在简单代码中,在发布构建中可以跳过边界检查以提高性能
- 如果内存使用量小且代码更清晰,则允许一些不必要的内存使用
- 尽可能使组件通用,但允许一些有见解的决定(参见ExpAdsrSpec)
未来
一般来说,只要我们能找到一种方法使代码足够通用,可以用于多种类型的插件(并为它编写足够的测试),我们就会尽快将代码放入这个库中。期待功能会随着我们清理应用程序特定的代码并使其更加模块化而扩展。
以下功能正在开发中,但尚未完全测试或整理
- 对插件参数的一等支持
- 环形缓冲区、延迟线和音高转换
- 失真算法
- 额外的滤波器类型