A library for hosting LV2 plugins.
Note: This is a work in progress and has not yet been full tested.
LV2 has a simple core interface but is accompanied by extensions that can add lots of functionality. This library aims to support as many features as possible out of the box.
http://lv2plug.in/ns/ext/urid#map
http://lv2plug.in/ns/ext/urid#unmap
http://lv2plug.in/ns/ext/options#options
http://lv2plug.in/ns/ext/buf-size#boundedBlockLength
http://lv2plug.in/ns/ext/worker#schedule
Below is an example on how to run the mda EPiano plugin.
``rust
let world = livi::World::new();
const SAMPLE_RATE: f64 = 44100.0;
let worker_manager = std::sync::Arc::new(livi::WorkerManager::default());
let features = world.build_features(livi::FeaturesBuilder {
min_block_length: 1,
max_block_length: 4096,
worker_manager: worker_manager.clone(),
});
let plugin = world
// This is the URI for mda EPiano. You can use the
lv2ls` command line
// utility to see all available LV2 plugins.
.pluginbyuri("http://drobilla.net/plugins/mda/EPiano")
.expect("Plugin not found.");
let mut instance = unsafe {
plugin
.instantiate(features.clone(), SAMPLE_RATE)
.expect("Could not instantiate plugin.")
};
// Where midi events will be read from. let input = { let mut s = livi::event::LV2AtomSequence::new(&features, 1024); let playnotedata = [0x90, 0x40, 0x7f]; s.pushmidievent::<3>(1, features.midiurid(), &playnote_data) .unwrap(); s };
// This is where the audio data will be stored. let mut outputs = [ vec![0.0; features.maxblocklength()], // For mda EPiano, this is the left channel. vec![0.0; features.maxblocklength()], // For mda EPiano, this is the right channel. ];
// Set up the port configuration and run the plugin!
// The results will be stored in outputs
.
let ports = livi::EmptyPortConnections::new()
.withatomsequenceinputs(std::iter::once(&input))
.withaudiooutputs(outputs.itermut().map(|output| output.asmutslice()));
unsafe { instance.run(features.maxblocklength(), ports).unwrap() };
// Plugins may push asynchronous works to the worker. When operating in
// Realtime, run_workers
should be run in a separate thread.
std::thread::spawn(move || {
workermanager.runworkers();
std::thread::sleep(std::time::Duration::from_millis(100));
});
std::thread::park(); ```
cargo build
cargo test
, requires mda LV2 plugins.cargo run --example livi-jack --release -- --plugin-uri=http://drobilla.net/plugins/mda/EPiano
.