lv2rs_core/lib.rs
1//! This crate contains the complete contents of the
2//! [LV2 core library](http://lv2plug.in/ns/lv2core/lv2core.html) with additional constructions
3//! to make the use of LV2 as idiomatic and safe as possible.
4//!
5//! This is a frozen prototype and therefore, development of this crate will not continue here. Further
6//! development continues as [rust-lv2](https://github.com/rust-dsp/rust-lv2).
7mod feature;
8mod plugin;
9pub mod ports;
10pub mod uris;
11
12pub use feature::{Feature, FeaturesList};
13pub use plugin::*;
14
15/// Create lv2 export functions.
16///
17/// This macro takes a struct that implements [`Plugin`](trait.Plugin.html) and creates the required
18/// functions a plugin needs to export in order to be found and used by plugin hosts.
19///
20/// In order to properly work, it needs three arguments:
21/// * The namespace of the `lv2rs-core` crate: You may use this crate via re-exports and
22/// therefore, the name of the namespace is needed in order to call the appropiate functions.
23/// * The struct type that should be used as the Plugin implementation.
24/// * The URI of the plugin. Please note that the URI needs to be a bytes-array and null-terminated,
25/// since the C world has to interact with it.
26///
27/// extern crate lv2rs_core as lv2core;
28/// use std::ffi::CStr;
29/// use lv2core::ports::*;
30///
31/// struct MyPlugin {}
32///
33/// impl lv2core::Plugin for MyPlugin {
34/// fn instantiate(
35/// _descriptor: &lv2core::Descriptor,
36/// _rate: f64,
37/// _bundle_path: &CStr,
38/// _features: Option<&lv2core::FeaturesList>
39/// ) -> Option<Self> {
40/// Some(Self {})
41/// }
42///
43/// fn connect_port(&mut self, _port: u32, _data: *mut ()) {}
44///
45/// fn run(&mut self, _n_samples: u32) {}
46/// }
47///
48/// lv2core::lv2_main!(lv2core, MyPlugin, b"http://example.org/Dummy\0");
49///
50#[macro_export]
51macro_rules! lv2_main {
52 ($c:ident, $s:ty, $u:expr) => {
53 const PLUGIN_URI: &'static [u8] = $u;
54 const PLUGIN_DESCRIPTOR: $c::Descriptor = $c::Descriptor {
55 uri: PLUGIN_URI.as_ptr() as *const std::os::raw::c_char,
56 instantiate: instantiate,
57 connect_port: connect_port,
58 activate: activate,
59 run: run,
60 deactivate: deactivate,
61 cleanup: cleanup,
62 extension_data: extension_data,
63 };
64
65 unsafe extern "C" fn instantiate(
66 descriptor: *const $c::Descriptor,
67 rate: f64,
68 bundle_path: *const std::os::raw::c_char,
69 features: *const *const $c::Feature,
70 ) -> $c::Handle {
71 $c::instantiate::<$s>(descriptor, rate, bundle_path, features)
72 }
73
74 unsafe extern "C" fn connect_port(
75 instance: $c::Handle,
76 port: u32,
77 data: *mut std::os::raw::c_void,
78 ) {
79 $c::connect_port::<$s>(instance, port, data);
80 }
81
82 unsafe extern "C" fn activate(instance: $c::Handle) {
83 $c::activate::<$s>(instance);
84 }
85
86 unsafe extern "C" fn run(instance: $c::Handle, n_samples: u32) {
87 $c::run::<$s>(instance, n_samples);
88 }
89
90 unsafe extern "C" fn deactivate(instance: $c::Handle) {
91 $c::deactivate::<$s>(instance);
92 }
93
94 unsafe extern "C" fn cleanup(instance: $c::Handle) {
95 $c::cleanup::<$s>(instance);
96 }
97
98 unsafe extern "C" fn extension_data(
99 uri: *const std::os::raw::c_char,
100 ) -> *const std::os::raw::c_void {
101 $c::extension_data::<$s>(uri)
102 }
103
104 #[no_mangle]
105 pub unsafe extern "C" fn lv2_descriptor(index: u32) -> *const $c::Descriptor {
106 if index == 0 {
107 &PLUGIN_DESCRIPTOR
108 } else {
109 std::ptr::null()
110 }
111 }
112 };
113}