3个版本
0.1.31 | 2024年3月31日 |
---|---|
0.1.2 | 2022年12月26日 |
0.1.1 | 2022年12月26日 |
在音频中排名285
每月下载40次
在4个crate中使用
8MB
174K SLoC
包含(Mach-o exe,7KB)lib/WDL/WDL/eel2/asm-nseel-x64-macho.o
rea-rs
易于使用的ReaScript API。虽然reaper-rs在低级上完全实现,在中级上部分实现,在其之上(主要是在低级上)这个crate构建了一个易于使用的API。实际上,目前它是Reapy项目的更好版本。
此API的主要框架是从Reapy克隆的,但以更“Rusty”的方式重新实现。此外,还添加了一些新的函数到Track、Item和Take中,以及为ExtState和midi做出了良好的新实现。可以说,目前包装了约95%的Track、Take、Item、AudioAccessor和FX原始函数;约70%的Envelope和Source。其余部分可能不到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::low
、Reaper::medium
和Reaper::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包含顶级函数,可以返回Project、Item等。而Project可以通过Track、Item、Take进行操作。层次结构的关键点——尽可能保证安全性。由于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
创建。享受编码吧!