3个版本

0.1.31 2024年3月31日
0.1.2 2022年12月26日
0.1.1 2022年12月26日

音频中排名285

每月下载40
4个crate中使用

MIT许可证

8MB
174K SLoC

C 81K SLoC // 0.2% comments C++ 59K SLoC // 0.0% comments Rust 16K SLoC // 0.0% comments Objective-C++ 15K SLoC // 0.0% comments Assembly 892 SLoC // 0.0% comments PHP 750 SLoC // 0.0% comments Visual Studio Project 484 SLoC Happy 341 SLoC Vim Script 332 SLoC // 0.1% comments Visual Studio Solution 56 SLoC Shell 13 SLoC // 0.1% comments Objective-C 10 SLoC // 0.6% comments

包含(Mach-o exe,7KB)lib/WDL/WDL/eel2/asm-nseel-x64-macho.o

rea-rs

linux windows macos

易于使用的ReaScript API。虽然reaper-rs在低级上完全实现,在中级上部分实现,在其之上(主要是在低级上)这个crate构建了一个易于使用的API。实际上,目前它是Reapy项目的更好版本。

查看文档

此API的主要框架是从Reapy克隆的,但以更“Rusty”的方式重新实现。此外,还添加了一些新的函数到TrackItemTake中,以及为ExtStatemidi做出了良好的新实现。可以说,目前包装了约95%的Track、Take、Item、AudioAccessorFX原始函数;约70%的EnvelopeSource。其余部分可能不到50%。也应该能够从VST插件中使用,但这尚未进行任何测试。

在没有与当前master分支有很大不同的新版本reaper-rs之前,这是我强烈推荐的依赖列表

这些是依赖项

[dependencies]
rea-rs = "0.1.3"
rea-rs-low = "0.1.3" # optional
rea-rs-macros = "0.1.3"

但实际上,所有中低级功能仍然存在于Reaper对象中。只需使用Reaper::lowReaper::mediumReaper::medium_session。公共入口点应如下所示

use rea_rs::{errors::ReaperResult, ActionKind, Reaper, PluginContext};
use rea_rs_macros::reaper_extension_plugin;
use std::error::Error;

#[reaper_extension_plugin]
fn plugin_main(context: PluginContext) -> Result<(), Box<dyn Error>> {
    Reaper::init_global(context);
    let reaper = Reaper::get_mut();
    let message = "Hello from small extension";
    reaper.show_console_msg(message);
    Ok(())
}

由于Reaper启动时没有太多事情要做,因此有两种常见的方法来调用代码:操作和Timer

use rea_rs::{PluginContext, Reaper, RegisteredAccel, Timer};
use rea_rs_macros::reaper_extension_plugin;
use std::error::Error;

#[derive(Debug)]
struct Listener {
    action: RegisteredAccel,
}

// Full list of function larger.
impl Timer for Listener {
    fn run(&mut self) -> Result<(), Box<dyn Error>> {
        Reaper::get().perform_action(self.action.command_id, 0, None);
        Ok(())
    }
    fn id_string(&self) -> String {"test listener".to_string()}
}

fn my_action_func(_flag: i32) -> Result<(), Box<dyn Error>> {
    Reaper::get().show_console_msg("running");
    Ok(())
}

#[reaper_extension_plugin]
fn plugin_main(context: PluginContext) -> Result<(), Box<dyn Error>> {
    Reaper::init_global(context);
    let reaper = Reaper::get_mut();

    let action = reaper.register_action(
        // This will be capitalized and used as action ID in action window
        "command_name",
        // This is the line user searches action for
        "description",
        my_action_func,
        // Only type currently supported
        None
    )?;

    reaper.register_timer(Box::new(Listener{action}));
    Ok(())
}

API中有浮点值。我建议使用float_eq包。

API结构

大多数情况下,API以层次结构使用:Reaper包含顶级函数,可以返回ProjectItem等。而Project可以通过TrackItemTake进行操作。层次结构的关键点——尽可能保证安全性。由于Project是活动的,从track到它的引用是安全的。其他子对象也是如此。由于同样的原因,同时修改两个对象几乎是不可能的。如果一个track是可变的,它就负责整个底层对象。我们可以几乎肯定,剩下的tracks由我们之前留下的对象组成。API的大部分内容都由测试覆盖,它们是一组很好的使用示例。

use rea_rs::Reaper;
use std::collections::HashMap;
let rpr = Reaper::get();
let captions =
vec!["age(18)", "name(user)", "leave blank", "fate(atheist)"];
let mut answers = HashMap::new();
answers.insert(String::from("age(18)"), String::from("18"));
answers.insert(String::from("name(user)"), String::from("user"));
answers.insert(String::from("leave blank"), String::from(""));
answers.insert(String::from("fate(atheist)"), String::from("atheist"));
let result = rpr.get_user_inputs(
    "Fill values as asked in fields",
    captions,
    None,
).unwrap();
assert_eq!(result, answers);

了解以下内容更有帮助

目前,API的缺点是

  • 顶级功能:我不确定至少一半的小Reaper函数是否被包装。比如所有窗口和主题相关的内容。
  • GUI。与reapy一样,GUI是一个问题。我已经开始了一个名为reaper-imgui的crate,它可以使用Rust的ReaImGui扩展。但它等待由rea-rs正确包装。
  • 线程安全。重要的是要知道,几乎没有什么Reaper应该留在主线程。有一些函数是为音频线程设计的,还有一些可以从任何线程安全执行。但,基本上,这里有一条规则:如果你创建了一个监听器、GUI或套接字通信——Reaper生活在主线程中,否则由std::sync::mpsc创建。享受编码吧!

依赖项