9个不稳定版本
0.5.0 | 2024年1月18日 |
---|---|
0.4.3 | 2023年10月25日 |
0.4.2 | 2023年4月18日 |
0.4.1 | 2023年3月27日 |
0.1.0 | 2022年10月7日 |
#73 in 音频
每月39次下载
685KB
14K SLoC
Knyst
Knyst是一个实时音频合成框架,侧重于灵活性和性能。其主要目标使用场景是桌面多线程环境,但它也可以进行单线程和非实时合成。目前不支持嵌入式平台,但已在路线图上。
[!重要]
Knyst不稳定。Knyst的API仍在开发中,版本之间可能差异很大。
名称
"Knyst"是瑞典语中的一个单词,意思是非常微弱的声音。它通常几乎只在否定意义上使用,例如“Det hörs inte ett knyst”(英文“你听不到任何声音”),但我认为它值得一些积极的用途。
示例
播放正弦波
// Set up knyst
let mut backend = CpalBackend::new(CpalBackendOptions::default())?;
let _sphere = KnystSphere::start(
&mut backend,
SphereSettings {
num_inputs: 1,
num_outputs: 2,
..Default::default()
},
print_error_handler,
);
// Add a sine wave to the top level graph
let sine_osc_handle = oscillator(WavetableId::cos()).freq(200.);
// Output it to the graph output, which for the top level graph is the
// application output.
graph_output(0, sine_osc_handle);
实现自己的 Gen
使用impl_gen
宏可以处理大部分样板代码。但是,如果您需要可变数量的输入或输出,您必须自己实现Gen
特质。
struct DummyGen {
counter: Sample,
}
#[impl_gen]
impl DummyGen {
// Having a `new` method enabled generation of a function `dummy_gen() -> Handle<DummyGenHandle>`
pub fn new() -> Self {
Self {
counter: 0.,
}
}
/// The process method, or any method with the `#[process]` attribute is what will be run every block
/// when processing audio. It must not allocate or wait (unless you are doing non-realtime stuff).
///
/// Inputs are extracted from any argument with the type &[Sample]
/// Outputs are extracted from any argument with the type &mut [Sample]
///
/// Additionally, &[Trig] is an input channel of triggers and enables the `inputname_trig()` method on the handle
/// to conveniently schedule a trigger. `SampleRate` gives you the current sample rate and `BlockSize` gives you
/// the block size.
#[process]
fn process(&mut self, counter: &[Sample], output: &mut [Sample]) -> GenState {
for (count, out) in counter.iter().zip(output.iter_mut()) {
self.counter += 1.;
*out = count + self.counter;
}
GenState::Continue
}
/// The init method will be called before adding the `Gen` to a running graph. Here is where you can
/// allocate buffers and initialise state based on sample rate and block size.
fn init(&mut self, _sample_rate: SampleRate, _block_size: BlockSize, _node_id: NodeId) {
self.counter = 0.;
}
}
特性
- 良好的运行时性能
- 通过异步兼容接口实时更改音频图
- 对图中的节点和参数更改进行样本精确调度
- 与静态Rust DSP库(如dasp和fundsp)的互操作性(它们可以封装在节点中并添加到图中)
- 图可以作为节点,可以在任何深度对图中的图应用更改
- 反馈连接,将一个节点的1块延迟输出连接到链中的早期节点
- 节点可以有任意数量的输入/输出
- 允许使用自动缓冲区对内部图进行不同块大小的选择
- 选择您所需的灵活性和优化级别:创建一个具有大量相互连接节点的图,或当需要更多性能时将所有内容硬编码到一个节点中
安全性
Knyst在底层使用一些不安全的功能来提高库中最敏感部分的性能,就像它的某些依赖项一样。但是,用户不需要编写任何不安全的代码。
路线图
对未来的愿景
- 自动参数更改插值
- 自动从图形生成GUI,包括交互式更改连接和参数
- 音乐时间调度工具,包括节奏选项,例如rubato,加速/减速和不规则拍号
- 并行处理大型图形
- 自动采样率转换
- 支持嵌入式平台使用no_std
许可
根据您选择的Apache License,Version 2.0或MIT许可证授权。
除非您明确说明,否则您有意提交给Knyst的任何贡献,根据Apache-2.0许可证定义,将以上双许可,没有任何附加条款或条件。
依赖项
~7–37MB
~639K SLoC