2个版本
0.1.1 | 2020年10月23日 |
---|---|
0.1.0 | 2020年3月27日 |
#13 在 #lv2
在 lv2 中使用
1MB
15K SLoC
Rust-LV2的库,用于实现LV2 Worker扩展。
一个工作调度库,允许具有实时能力的LV2插件执行非实时操作。这是 rust-lv2
的一部分,一个用于创建LV2插件的 Rust 编写的安全、快速和易于使用的框架,用于音频处理。
文档
原始LV2 API(用C语言编程)由"LV2书籍"进行文档编制。这本书正在与rust-lv2
的开发一起翻译成Rust(链接)(链接),并描述了如何正确使用rust-lv2
。
许可证
根据您选择以下任一许可证进行许可
- Apache许可证,版本2.0(LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT许可证(LICENSE-MIT 或 http://opensource.org/licenses/MIT)
任选。
lib.rs
:
一个工作调度库,允许实时能力的LV2插件执行非实时操作。
此crate允许插件在另一个线程中安排必须执行的工作。插件可以使用此接口安全地执行非实时安全的工作,并在运行上下文中接收结果。一个典型用例是从磁盘读取和缓存数据的采样器。有关详细信息,请参阅LV2 Worker规范。
示例
use std::any::Any;
use lv2_core::feature::*;
use lv2_core::prelude::*;
use urid::*;
use lv2_worker::*;
#[derive(PortCollection)]
struct Ports {}
/// Requested features
#[derive(FeatureCollection)]
struct AudioFeatures<'a> {
///host feature allowing to schedule some work
schedule: Schedule<'a, EgWorker>,
}
//custom datatype
struct WorkMessage {
cycle: usize,
task: usize,
}
/// A plugin that do some work in another thread
struct EgWorker {
// The schedule handler needs to know the plugin type in order to access the `WorkData` type.
cycle: usize,
end_cycle: usize,
}
/// URI identifier
unsafe impl UriBound for EgWorker {
const URI: &'static [u8] = b"urn:rust-lv2-more-examples:eg-worker-rs\0";
}
impl Plugin for EgWorker {
type Ports = Ports;
type InitFeatures = ();
type AudioFeatures = AudioFeatures<'static>;
fn new(_plugin_info: &PluginInfo, _features: &mut Self::InitFeatures) -> Option<Self> {
Some(Self {
cycle: 0,
end_cycle: 1,
})
}
fn run(&mut self, _ports: &mut Ports, features: &mut Self::AudioFeatures, _: u32) {
self.cycle += 1;
let cycle = self.cycle;
println!("cycle {} started", cycle);
for task in 0..10 {
let work = WorkMessage { cycle, task };
// schedule some work, passing some data and check for error
if let Err(e) = features.schedule.schedule_work(work) {
eprintln!("Can't schedule work: {}", e);
}
}
}
fn extension_data(uri: &Uri) -> Option<&'static dyn Any> {
match_extensions![uri, WorkerDescriptor<Self>]
}
}
/// Implementing the extension.
impl Worker for EgWorker {
// data type sent by the schedule handler and received by the `work` method.
type WorkData = WorkMessage;
// data type sent by the response handler and received by the `work_response` method.
type ResponseData = String;
fn work(
//response handler need to know the plugin type.
response_handler: &ResponseHandler<Self>,
data: Self::WorkData,
) -> Result<(), WorkerError> {
println!("work received: cycle {}, task {}", data.cycle, data.task);
if data.task >= 5 {
if let Err(e) = response_handler.respond(format!(
"response to cycle {}, task {}",
data.cycle, data.task
)) {
eprintln!("Can't respond: {}", e);
}
};
Ok(())
}
fn work_response(
&mut self,
data: Self::ResponseData,
_features: &mut Self::AudioFeatures,
) -> Result<(), WorkerError> {
println!("work_response received: {}", data);
Ok(())
}
fn end_run(&mut self, _features: &mut Self::AudioFeatures) -> Result<(), WorkerError> {
println!("cycle {} ended", self.end_cycle);
self.end_cycle += 1;
Ok(())
}
}
依赖项
~1.5MB
~34K SLoC