[][src]Crate lv2_atom

General data IO for LV2 plugins.

This crate empowers LV2 plugins to communicate using a common type system, which is defined in the LV2 Atom Specification. Many plugin standards only provide audio and MIDI IO, but LV2 plugins can read and write anything from simple integers over vectors and strings to event sequences using this specification.

How to use atoms

The foundation of this crate is the Atom trait. This trait provides type definitions and methods to read and write atoms. However, you will never handle these types directly, only via handles and generics.

Your entry point to the atom system are the PortReader and PortWriter structs provided by your plugin's ports. If you provide them the URID of the desired atom type as a atom-specific parameter, they will try to retrieve a handle that either lets you access the contents of an atom or write additional data to it. This is a general pattern in this crate; you will encounter it several times. From there, you use the handles as documented.

Example

use lv2_atom::prelude::*;
use lv2_core::prelude::*;
use lv2_units::prelude::*;
use urid::*;

#[derive(PortCollection)]
struct MyPorts {
    input: InputPort<AtomPort>,
    output: OutputPort<AtomPort>,
}

#[derive(URIDCollection)]
struct MyURIDs {
    atom: AtomURIDCollection,
    units: UnitURIDCollection,
}

/// Something like a plugin's run method.
fn run(ports: &mut MyPorts, urids: &MyURIDs) {
    // Get the read handle to the sequence.
    let input_sequence = ports.input.read(
        urids.atom.sequence,
        urids.units.beat
    ).unwrap();

    // Get the write handle to the sequence.
    let mut output_sequence = ports.output.init(
        urids.atom.sequence,
        TimeStampURID::Frames(urids.units.frame)
    ).unwrap();

    // Iterate through all events in the input sequence.
    for event in input_sequence {
        // An event contains a timestamp and an atom.
        let (timestamp, atom) = event;
        // If the read atom is a 32-bit integer...
        if let Some(integer) = atom.read(urids.atom.int, ()) {
            // Multiply it by two and write it to the sequence.
            output_sequence.init(timestamp, urids.atom.int, integer * 2).unwrap();
        } else {
            // Forward the atom to the sequence without a change.
            output_sequence.forward(timestamp, atom).unwrap();
        }
    }
}

Internals

Internally, all atoms are powered by the structs in the space module. They safely abstract the reading and writing process and assure that no memory is improperly accessed or leaked and that alignments are upheld. If you simply want to use the atoms in this crate, you don't need to deal with. They are only interesting if you want to create your own atom types.

Modules

chunk

An atom containing memory of undefined type.

object

An atom containing multiple key-value pairs.

port

Integration for plugin ports.

prelude

Prelude of lv2_atom for wildcard usage.

scalar

Scalar, single-value atoms.

sequence

An atom containing a sequence of time-stamped events.

space

Smart pointers with safe atom reading and writing methods.

string

String handling atoms.

tuple

An atom containg a series of other atoms.

vector

An atom containg an array of scalar atom bodies.

Structs

AtomURIDCollection

Collection with the URIDs of all UriBounds in this crate.

UnidentifiedAtom

An atom of yet unknown type.

Traits

Atom

Atom type.