11 个版本

0.1.10 2023 年 10 月 4 日
0.1.9 2022 年 4 月 24 日

#15 in 多媒体

每月 23 次下载

BSD-3-Clause

490KB
1.5K SLoC

libpd-rs

Build and Test Status Code Coverage

libpd-sys 之上的安全 Rust 抽象。

Pure Data (Pd) 是由 Miller Puckette 在 1990 年代开发的一种视觉编程语言,用于创建交互式计算机音乐和多媒体作品。虽然 Puckette 是该程序的主要作者,但 Pd 是一个 开源项目,拥有一个 庞大的开发者群体,致力于开发新的扩展。该项目采用 BSD-3-Clause 许可。

尽管 pd 设计为桌面应用程序,但 libpd 是一个开源项目,它将其作为 C 库公开,从而为 C 可以编译到的任何平台嵌入 pd 的功能提供了可能性。

libpd-rs 致力于将 libpd 带到 Rust 生态系统。它旨在通过添加一些额外的功能(例如捆绑常用外部库和增加易用性)来全面公开 libpd 的功能。

它经过详细的 文档,经过良好的 测试,并提供了各种 示例,以帮助您快速入门。

现在让我们来制作一些声音! 🔔


将以下依赖项添加到您的 Cargo.toml

[dependencies]
libpd-rs = "0.1"
cpal = "0.15"

将代码粘贴到您的 main.rs

⚠️ 警告 ⚠️:此示例将产生音频,所以请保持音量在合理水平以确保安全。

use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use libpd_rs::convenience::PdGlobal;

fn main() -> Result<(), Box<dyn std::error::Error>> {

    // Initialize cpal
    // This could have been another cross platform audio library
    // basically anything which gets you the audio callback of the os.
    let host = cpal::default_host();

    // Currently we're only going to output to the default device
    let device = host.default_output_device().unwrap();

    // Using the default config
    let config = device.default_output_config()?;

    // Let's get the default configuration from the audio driver.
    let sample_rate = config.sample_rate().0 as i32;
    let output_channels = config.channels() as i32;

    // Initialize libpd with that configuration,
    // with no input channels since we're not going to use them.
    let mut pd = PdGlobal::init_and_configure(0, output_channels, sample_rate)?;

    // Let's evaluate a pd patch.
    // We could have opened a `.pd` file also.
    // This patch would play a sine wave at 440hz.
    pd.eval_patch(
        r#"
    #N canvas 577 549 158 168 12;
    #X obj 23 116 dac~;
    #X obj 23 17 osc~ 440;
    #X obj 23 66 *~ 0.1;
    #X obj 81 67 *~ 0.1;
    #X connect 1 0 2 0;
    #X connect 1 0 3 0;
    #X connect 2 0 0 0;
    #X connect 3 0 0 1;
        "#,
    )?;

    // Build the audio stream.
    let output_stream = device.build_output_stream(
        &config.into(),
        move |data: &mut [f32], _: &cpal::OutputCallbackInfo| {
            // Provide the ticks to advance per iteration for the internal scheduler.
            let ticks = libpd_rs::convenience::calculate_ticks(output_channels, data.len() as i32);

            // Here if we had an input buffer we could have modified it to do pre-processing.

            // Process audio, advance internal scheduler.
            libpd_rs::process::process_float(ticks, &[], data);

            // Here we could have done post processing after pd processed our output buffer in place.
        },
        |err| eprintln!("an error occurred on stream: {}", err),
        None,
    )?;

    // Turn audio processing on
    pd.activate_audio(true)?;

    // Run the stream
    output_stream.play()?;

    // Wait a bit for listening..
    std::thread::sleep(std::time::Duration::from_secs(5));

    // Turn audio processing off
    pd.activate_audio(false)?;

    // Pause the stream
    output_stream.pause()?;

    // Close the patch
    pd.close_patch()?;

    // Leave
    Ok(())
}

这只是关于您可以使用 libpd 做的事情的一小部分。

我们刚才评估的补丁在 pd 桌面应用程序中的样子如下

运行示例和测试

在克隆了存储库后,在存储库根目录中运行

cargo run --example <name of the example>

例如。

cargo run --example with_nannou

请查看README以获取更多示例信息。

对于测试,您可以直接运行cargo test

下一步

如果您喜欢通过阅读代码来学习,请检查示例测试目录。

或者,如果您想深入了解文档,请继续。

资源

路线图

支持

  • 桌面

    • macOS
      • x86_64
      • aarch64
    • linux
      • x86_64
      • aarch64
    • windows
      • msvc
        • x86_64
        • aarch64 (未测试但应能工作)
      • gnu
        • x86_64 (未测试但应能工作)
        • aarch64 (未测试但应能工作)
  • 移动

    • iOS (尚未但将予以解决)
    • Android (尚未但将予以解决)
  • Web (尚未但将予以解决)

捆绑外部的列表

将外部添加到libpd的方法是编译并静态链接它们。

libpd-rs将捆绑一些纯数据中基本和常用外部组件。随着我们添加更多外部组件,此列表将不断增长。

如果您有想法,请考虑回答这个帖子

  • moog~
  • freeverb~

贡献

  • 友好并富有成效
  • 遵循常见的开源贡献文化实践
  • Rust 行为准则适用

谢谢 🙏

类似项目

结语

生成式或算法音乐是探索的有力工具,激发创造力,并且与传统音乐制作方法非常搭配。

制作产生有意义声音的应用程序很困难,我希望这个crate能够使您更容易地完成这项任务,并使复杂音频想法在应用程序中更容易被更多人访问。

依赖项

~15–26MB
~370K SLoC