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次下载

MIT/Apache

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