diff --git a/.cargo/config b/.cargo/config
new file mode 100644
index 00000000..2d727e1e
--- /dev/null
+++ b/.cargo/config
@@ -0,0 +1,2 @@
+[alias]
+systool = "run -p systool --"
diff --git a/.github/workflows/book.yml b/.github/workflows/book.yml
new file mode 100644
index 00000000..b59ea413
--- /dev/null
+++ b/.github/workflows/book.yml
@@ -0,0 +1,34 @@
+name: Book
+
+on:
+  push:
+    branches: 
+    - master
+    - develop
+
+jobs:
+  book:
+    runs-on: ubuntu-latest
+      
+    steps:
+    - uses: actions/checkout@v2
+    - uses: actions/setup-python@v1.2.0
+      with:
+        python-version: 3.8
+    - name: Install Sphinx
+      run: |
+        python -m pip install --upgrade pip
+        pip install -r docs/requirements.txt
+    - name: Build Book
+      run: |
+        cd docs
+        make html
+        touch _build/html/.nojekyll
+    - name: Deploy
+      if: success()
+      uses: crazy-max/ghaction-github-pages@v1
+      with:
+        target_branch: gh-pages
+        build_dir: docs/_build/html
+      env:
+        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
new file mode 100644
index 00000000..e0e48a5f
--- /dev/null
+++ b/.github/workflows/rust.yml
@@ -0,0 +1,72 @@
+name: Rust
+
+on:
+  push:
+    branches: 
+    - master
+    - develop
+  pull_request:
+    branches: 
+    - master
+    - develop
+
+jobs:
+  build:
+    strategy:
+      matrix:
+        os: [ubuntu-latest, windows-latest]
+        toolchain: [stable, beta, nightly]
+
+    runs-on: ${{ matrix.os }}
+    
+    steps:
+    - uses: actions/checkout@v2
+    - uses: actions-rs/toolchain@v1
+      with:
+        toolchain: ${{ matrix.toolchain }}
+        override: true
+    - name: Build
+      run: cargo build --all --all-features --verbose
+    - name: Run tests
+      run: cargo test --all --all-features --verbose
+  
+  check:
+    runs-on: ubuntu-latest
+    
+    steps:
+    - uses: actions/checkout@v2
+    - uses: actions-rs/toolchain@v1
+      with:
+        toolchain: stable
+        override: true
+        components: rustfmt, clippy
+    - name: Format
+      run: cargo fmt --all -- --check
+    - uses: actions-rs/clippy-check@v1
+      with:
+        token: ${{ secrets.GITHUB_TOKEN }}
+        args: --all --all-features -- -D warnings
+
+  linux-bindings:
+    runs-on: ubuntu-latest
+
+    steps:
+    - uses: actions/checkout@v2
+    - uses: actions-rs/toolchain@v1
+      with:
+        toolchain: stable
+        override: true
+        target: i686-unknown-linux-gnu
+    - name: Install 32-bit libc
+      run: |
+        sudo apt-get update
+        sudo apt-get install libc6-dev-i386
+    - name: Generate
+      run: |
+        mkdir bindings
+        cargo run -p systool -- -I ./sys/lv2/ -o bindings/x86_64.rs -- -target x86_64-unknown-linux-gnu
+        cargo run -p systool -- -I ./sys/lv2/ -o bindings/x86.rs -- -target i686-unknown-linux-gnu
+    - uses: actions/upload-artifact@v1
+      with:
+        name: linux-bindings
+        path: bindings
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 48190c26..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-language: rust
-
-branches:
-  only:
-  - master
-  - develop
-
-rust:
-  - stable
-  - beta
-  - nightly
-
-os:
-  - linux
-  - osx
-  - windows
-
-matrix:
-  allow_failures:
-    - os: windows
-    - rust: nightly
-
-before_script:
-  - rustup component add rustfmt
-  - rustup component add clippy
-
-script:
-  - cargo fmt --all -- --check
-  - cargo clippy --all --all-features -- -D warnings
-  - cargo test --all --all-features --verbose
-
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 6bb64e5c..bac6acd1 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,12 +1,12 @@
-# Contributing to rust-lv2
+# Contributing to Rust-LV2
 
 *Inspired by [Rust's contribution guide](https://github.com/rust-lang/rust/blob/d9051341a1c142542a3f7dab509266606c775382/CONTRIBUTING.md).*
 
-Thank you for your interest in contributing to rust-lv2! There are many ways to contribute, and we appreciate all of them.
+Thank you for your interest in contributing to Rust-LV2! There are many ways to contribute, and we appreciate all of them.
 
 ## General or Usage questions, Feature Ideas or Discussions
 
-Our main discussion panel is the [Rust Audio Discourse](https://rust-audio.discourse.group/). Most of our design decisions are taken there and it's the perfect place to post any question or idea. rust-lv2 isn't the only project there, so you may post anything that is somehow related to Rust and Audio Processing.
+Our main discussion panel is the [Rust Audio Discourse](https://rust-audio.discourse.group/). Most of our design decisions are taken there and it's the perfect place to post any question or idea. Rust-LV2 isn't the only project there, so you may post anything that is somehow related to Rust and Audio Processing.
 
 ## Bug Reports
 
@@ -39,7 +39,7 @@ Instead, this happened: <explanation>
 ### Backtrace:
 ```
 
-All three components are important: what you did, what you expected, what happened instead. Please include the dependencies to rust-lv2 in your `Cargo.toml` so we can track down where to find the bug.
+All three components are important: what you did, what you expected, what happened instead. Please include the dependencies to Rust-LV2 in your `Cargo.toml` so we can track down where to find the bug.
 
 Sometimes, a backtrace is helpful, and so including that is nice. To get a backtrace, set the `RUST_BACKTRACE` environment variable to a value other than `0`. The easiest way to do this is to invoke `cargo` like this:
 
@@ -47,7 +47,7 @@ Sometimes, a backtrace is helpful, and so including that is nice. To get a backt
 
 ## Pull Requests
 
-Pull requests are the primary mechanism we use to change rust-lv2. GitHub itself has some [great documentation](https://help.github.com/articles/about-pull-requests/) on using the Pull Request feature. We use the "fork and pull" model [described here](https://help.github.com/articles/about-collaborative-development-models/), where contributors push changes to their personal fork and create pull requests to bring those changes into the source repository.
+Pull requests are the primary mechanism we use to change Rust-LV2. GitHub itself has some [great documentation](https://help.github.com/articles/about-pull-requests/) on using the Pull Request feature. We use the "fork and pull" model [described here](https://help.github.com/articles/about-collaborative-development-models/), where contributors push changes to their personal fork and create pull requests to bring those changes into the source repository.
 
 Please make pull requests against the `develop` branch.
 
@@ -59,6 +59,6 @@ Another useful feature are [draft Pull Requests](https://github.blog/2019-02-14-
 
 ## Writing Documentation
 
-Documentation improvements are very welcome. The API documentation is generated from the source code itself. However, the [rust-lv2 book](https://github.com/Janonard/rust-lv2-book), which explains how to use rust-lv2 in general, is a separate project. Documentation pull requests function in the same way as other pull requests.
+Documentation improvements are very welcome. The API documentation is generated from the source code itself. Documentation pull requests function in the same way as other pull requests.
 
 To find documentation-related issues, sort by the [documentation](https://github.com/RustAudio/rust-lv2/labels/documentation) label.
\ No newline at end of file
diff --git a/Cargo.toml b/Cargo.toml
index 441b30e1..01abe7d6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "lv2"
-version = "0.5.1"
+version = "0.6.0"
 authors = ["Jan-Oliver 'Janonard' Opdenhövel <jan.opdenhoevel@protonmail.com>", "Adrien Prokopowicz <adrien.prokopowicz@gmail.com>",
  "Yruama_Lairba <yruama_lairba@hotmail.com>"]
 edition = "2018"
@@ -16,23 +16,23 @@ travis-ci = { repository = "RustAudio/rust-lv2", branch = "master" }
 maintenance = { status = "actively-developed" }
 
 [dependencies.lv2-atom]
-version = "1.0.0"
+version = "2.0.0"
 optional = true
 
 [dependencies.lv2-core]
-version = "2.0.0"
+version = "3.0.0"
 optional = true
 
 [dependencies.lv2-midi]
-version = "1.0.0"
+version = "1.2.0"
 optional = true
 
 [dependencies.lv2-time]
-version = "0.1.0"
+version = "0.1.3"
 optional = true
 
 [dependencies.lv2-units]
-version = "0.1.0"
+version = "0.1.3"
 optional = true
 
 [dependencies.urid]
@@ -40,15 +40,19 @@ version = "0.1.0"
 optional = true
 
 [dependencies.lv2-urid]
-version = "2.0.0"
+version = "2.1.0"
 optional = true
 
 [dependencies.lv2-state]
-version = "1.0.0"
+version = "2.0.0"
+optional = true
+
+[dependencies.lv2-sys]
+version = "2.0.0"
 optional = true
 
 [dependencies.lv2-worker]
-version = "0.1.0"
+version = "0.1.1"
 optional = true
 
 [features]
@@ -74,6 +78,7 @@ full = [
     "urid",
     "lv2-urid",
     "lv2-state",
+    "lv2-sys",
     "lv2-worker",
 ]
 wmidi = ["lv2-midi", "lv2-midi/wmidi"]
@@ -86,10 +91,33 @@ members = [
     "midi",
     "state",
     "sys",
+    "sys/tool",
     "time",
     "units",
     "urid",
     "urid/derive",
     "urid/lv2-urid",
     "worker",
+    "docs/amp",
+    "docs/fifths",
+    "docs/metro",
+    "docs/midigate",
 ]
+
+[profile.release]
+lto = true
+
+[patch.crates-io]
+lv2 = { path = "." }
+lv2-atom = { path = "atom" }
+lv2-core = { path = "core" }
+lv2-core-derive = { path = "core/derive" }
+lv2-midi = { path = "midi" }
+lv2-state = { path = "state" }
+lv2-sys = { path = "sys" }
+lv2-time = { path = "time" }
+lv2-units = { path = "units" }
+urid = { path = "urid" }
+urid-derive = { path = "urid/derive" }
+lv2-urid = { path = "urid/lv2-urid" }
+lv2-worker = { path = "worker" }
diff --git a/README.md b/README.md
index 610f37ea..af719ca0 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# rust-lv2
+# Rust-LV2
 
 [![Build Status][travis-badge]][travis-url] [![Current Crates.io Version][crates-badge]][crates-url]
 
@@ -92,12 +92,26 @@ impl Plugin for Amp {
 lv2_descriptors!(Amp);
 ```
 
-## Using this framework
+## About this framework
+
+### Q&A
+
+#### Does my host program support it?
+
+Plugins created with `rust-lv2` are compatible to all LV2 hosts that comply to the specifications. If your application uses [`lilv`](https://drobilla.net/software/lilv), it's a good sign that it will support your plugin. Some prime examples are [Carla](https://kx.studio/Applications:Carla) and [Ardour](https://ardour.org/).
+
+#### Can I host plugins with `rust-lv2`?
+
+Currently, hosting plugins is not supported. This project was initialy started to create plugins using safe Rust and therefore, it is very plugin-centric. There are plans for integrated plugin hosting or a spin-off project, but those won't start in the near future.
+
+However, there is a lot of code that can be re-used for a hosting framework. If you want to create such a framework, you should take a look at `lv2-sys`, `urid`, and `lv2-atom`.
+
+A bare hosting framework would require an RDF triple store which can load Turtle files, an internal store for plugin interfaces and their extensions, a centralized URID map store, and a graph based work scheduling system to execute `run` functions in order.
 
 ### Documentation
 
 There are multiple valuable sources of documentation:
-* ["The rust-lv2 book"](https://janonard.github.io/rust-lv2-book/) describes how to use rust-lv2 in general, broad terms. It's the ideal point to get started and is updated with every new version of rust-lv2.
+* ["The Rust-LV2 book"](https://rustaudio.github.io/rust-lv2/) describes how to use Rust-LV2 in general, broad terms. It's the ideal point to get started and is updated with every new version of Rust-LV2.
 * [The API documentation](https://docs.rs/lv2).
 * [The LV2 specification reference](https://lv2plug.in/ns/).
 
@@ -122,37 +136,35 @@ There are also feature sets that account for common scenarios:
 * `plugin`: Usual crates for standard plugins. Includes `lv2-core`, `lv2-atom`, `lv2-midi`, `lv2-urid`, and `urid`. **This is the default.**
 * `full`: All sub-crates.
 
-### Building
+## Supported targets
 
-Since the bindings to the raw C headers are generated with bindgen, you need to have [Clang](https://clang.llvm.org/) installed on your system and, if it isn't in your system's standard path, set the environment variable `LIBCLANG_PATH` to the path of `libClang`.
+Rust-LV2 uses pregenerated C API bindings for different targets in order to increase usability and building speed. Rust has a lot of [supported targets](https://forge.rust-lang.org/release/platform-support.html), but our maintaining power is limited and therefore, only certain targets can be supported. We've ranked different targets in Tiers, [just like rustc does](https://doc.rust-lang.org/nightly/rustc/platform-support.html), which gives you a general understanding of what to expect of a target. The tables below list the supported targets, the used binding in the [`lv2-sys`](sys/) crate, and, if applicable, the maintainer and the last verification of that target.
 
-## Q&A
+The bindings itself are generated with the [LV2 systool](sys/tool/) and verified by building the [example plugins of the book](docs) and testing them with a host of that target.
 
-### Does my host program support it?
+### Tier 1
 
-Plugins created with `rust-lv2` are compatible to all LV2 hosts that comply to the specifications. If your application uses [`lilv`](https://drobilla.net/software/lilv), it's a good sign that it will support your plugin. Some prime examples are [Carla](https://kx.studio/Applications:Carla) and [Ardour](https://ardour.org/).
-
-### What targets are supported?
-
-We currently support stable and beta Rust running on macOS and Linux. Windows will probably work too, but the Windows build environment of Travis CI is currently broken and we therefore can not support it.
-
-We would like to also support Windows as well as ARM-based embedded devices like Raspberry Pis. If you can help us with these targets, please do so!
-
-### Can I host plugins with `rust-lv2`?
-
-Currently, hosting plugins is not supported. This project was initialy started to create plugins using safe Rust and therefore, it is very plugin-centric. There are plans for integrated plugin hosting or a spin-off project, but those won't start in the near future.
-
-However, there is a lot of code that can be re-used for a hosting framework. If you want to create such a framework, you should take a look at `lv2-sys`, `urid`, and `lv2-atom`.
-
-A bare hosting framework would require an RDF triple store which can load Turtle files, an internal store for plugin interfaces and their extensions, a centralized URID map store, and a graph based work scheduling system to execute `run` functions in order.
+A Tier 1 target for `rust-lv2` also has to be a Tier 1 target of rustc. You can check the [platform support page](https://doc.rust-lang.org/nightly/rustc/platform-support.html) to see which targets are included and what they provide. Additionally, there has to be a [maintainer](https://github.com/orgs/RustAudio/teams/lv2-maintainers) of `rust-lv2` who has access to a machine that runs this target and who can generate and verify bindings on this machine. This means that if you have a problem running your code on a Tier 1 target, there will be a maintainer who can help you.
 
-### Why `bindgen`?
+| Target                     | Binding           | Maintainer | Last Verification                                                                                        |
+|----------------------------|-------------------|------------|----------------------------------------------------------------------------------------------------------|
+| `x86_64-unknown-linux-gnu` | `linux/x86_64.rs` | @Janonard  | 10. of May 2020, using [Carla](https://github.com/falkTX/Carla) v2.1, running on Arch Linux              |
+| `x86-unknown-linux-gnu`    | `linux/x86.rs`    | @Janonard  | 16th of May 2020, using [Carla](https://github.com/falkTX/Carla) v2.1, running on Linux Mint 19.3 32-bit |
 
-`lv2-sys` uses `bindgen` to generate the Rust representation of the LV2 C API. Rust can not handle verbatim C code, but is able to define type and function definitions that exactly match those from the C headers. However, since serveral importants details in C aren't properly defined, these bindings need to be different for every platform. One example: While Rust's `u32` is always an unsigned, 32-bit wide integer, C's `int` may be 16 to 64 bits wide and may be signed or unsigned; It depends on the platform.
+### Tier 2
 
-One solution would be to generate bindings for every supported target, but if we would only support stable, beta and nightly Rust on [tier 1 platforms](https://forge.rust-lang.org/release/platform-support.html#tier-1), we would still have to maintain 21 different versions of the same crate. If we would add [tier 2 platforms](https://forge.rust-lang.org/release/platform-support.html#tier-2) too (which would include e.g. the Raspberry Pis), there would be 216(!) different versions.
+A Tier 2 target is a target that is at least in Tier 2 of rustc and has a generated binding. However, it might not work (well) and there might not be a maintainer who has access to a machine that runs this target and who can generate and verify bindings on this machine. This means that if you have a problem running your code on a Tier 2 target, you're stepping into uncharted territory.
 
-I guess it's obvious that this isn't a maintainable situation. Therefore, the bindings need to be generated every time they are build, which requires the build dependency to `bindgen`.
+| Target                                | Binding      |
+|---------------------------------------|--------------|
+| `aarch64-unknown-linux-gnu`           | `aarch64.rs` |
+| `arm-unknown-linux-gnueabi`           | `arm.rs`     |
+| `arm-unknown-linux-gnueabihf`         | `arm.rs`     |
+| `armv5te-unknown-linux-gnueabi`       | `arm.rs`     |
+| `armv7-unknown-linux-gnueabi`         | `arm.rs`     |
+| `armv7-unknown-linux-gnueabihf`       | `arm.rs`     |
+| `thumbv7neon-unknown-linux-gnueabihf` | `arm.rs`     |
+| `x86_64-pc-windows-msvc`              | `windows.rs` |
 
 ## License
 
diff --git a/atom/Cargo.toml b/atom/Cargo.toml
index e9b2bae8..e23194cb 100644
--- a/atom/Cargo.toml
+++ b/atom/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "lv2-atom"
-version = "1.1.0"
+version = "2.0.0"
 authors = ["Jan-Oliver 'Janonard' Opdenhövel <jan.opdenhoevel@protonmail.com>"]
 edition = "2018"
 license = "MIT OR Apache-2.0"
@@ -14,16 +14,16 @@ travis-ci = { repository = "RustAudio/rust-lv2", branch = "master" }
 maintenance = { status = "passively-maintained" }
 
 [dependencies]
-lv2-sys = "1.0.0"
-lv2-units = "0.1.0"
+lv2-sys = "2.0.0"
+lv2-units = "0.1.3"
 urid = "0.1.0"
 
 [dependencies.lv2-core]
-version = "2.0.0"
+version = "3.0.0"
 optional = true
 
 [dev-dependencies]
-lv2-urid = "2.0.0"
+lv2-urid = "2.1.0"
 
 [features]
 default = ["lv2-core"]
\ No newline at end of file
diff --git a/atom/README.md b/atom/README.md
index e24314ed..23183225 100644
--- a/atom/README.md
+++ b/atom/README.md
@@ -1,4 +1,4 @@
-# rust-lv2's Atom handling library.
+# Rust-LV2's Atom handling library.
 
 A library for reading and writing [LV2's](https://lv2plug.in/) Atom type system, used by [`rust-lv2`](https://crates.io/crates/lv2), a safe, fast, and ergonomic framework to create [LV2 plugins](http://lv2plug.in/) for audio processing, written in Rust.
 
@@ -8,10 +8,6 @@ LV2 has it's own type system to make data exchange between plugins as versatile
 
 The original LV2 API (in the `C` programming language) is documented by ["the LV2 book"](https://lv2plug.in/book/). This book is in the process of being translated to Rust along with the development of `rust-lv2` [(link)](https://janonard.github.io/rust-lv2-book/) and describes how to properly use `rust-lv2`.
 
-## Building
-
-Since the bindings to the raw C headers are generated with bindgen, you need to have [Clang](https://clang.llvm.org/) installed on your system and, if it isn't in your system's standard path, set the environment variable `LIBCLANG_PATH` to the path of `libClang`.
-
 ## Features
 
 Like any other crate of `rust-lv2`, this crate has the optional `host` feature. Some of the types defined by some crates are only useful for testing or LV2 hosts. Since the goal of this framework is to provide an easy way to create plugins, these aren't necessary and therefore gated behind that feature.
diff --git a/atom/src/lib.rs b/atom/src/lib.rs
index e851dc42..a091671d 100644
--- a/atom/src/lib.rs
+++ b/atom/src/lib.rs
@@ -61,11 +61,6 @@
 //! # Internals
 //!
 //! Internally, all atoms are powered by the structs in the [`space`](space/index.html) 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.
-//!
-//! # Non-Rust requirements
-//!
-//! Since this crate depends on `-sys` crates that use `bindgen` to create the C API bindings,
-//! you need to have clang installed on your machine.
 extern crate lv2_sys as sys;
 extern crate lv2_units as units;
 
@@ -103,6 +98,7 @@ use urid::*;
 #[derive(Clone, URIDCollection)]
 /// Collection with the URIDs of all `UriBound`s in this crate.
 pub struct AtomURIDCollection {
+    pub blank: URID<object::Blank>,
     pub double: URID<scalar::Double>,
     pub float: URID<scalar::Float>,
     pub int: URID<scalar::Int>,
@@ -204,4 +200,13 @@ impl<'a> UnidentifiedAtom<'a> {
             .map(|(body, _)| body)
             .and_then(|body| A::read(body, parameter))
     }
+
+    /// Retrieve the type URID of the atom.
+    ///
+    /// This can be used to identify atoms without actually reading them.
+    pub fn type_urid(self) -> Option<URID> {
+        self.space
+            .split_type::<sys::LV2_Atom>()
+            .and_then(|(header, _)| URID::new(header.type_))
+    }
 }
diff --git a/atom/src/object.rs b/atom/src/object.rs
index 08ecc160..1a94d0e1 100644
--- a/atom/src/object.rs
+++ b/atom/src/object.rs
@@ -61,7 +61,7 @@
 //!     ).unwrap();
 //!
 //!     // Write a property to the object.
-//!     object_writer.init(urids.property_a, None, urids.atom.int, 42).unwrap();
+//!     object_writer.init(urids.property_a, urids.atom.int, 42).unwrap();
 //! }
 //! ```
 //!
@@ -132,18 +132,17 @@ where
     }
 }
 
-/// Deprecated alias of `Object`
+/// Alias of `Object`, used by older hosts.
 ///
 /// A blank object is an object that isn't an instance of a class. The [specification recommends](https://lv2plug.in/ns/ext/atom/atom.html#Blank) to use an [`Object`](struct.Object.html) with an id of `None`, but some hosts still use it and therefore, it's included in this library.
-#[deprecated]
+///
+/// If you want to read an object, you should also support `Blank`s, but if you want to write an object, you should always use `Object`.
 pub struct Blank;
 
-#[allow(deprecated)]
 unsafe impl UriBound for Blank {
     const URI: &'static [u8] = sys::LV2_ATOM__Blank;
 }
 
-#[allow(deprecated)]
 impl<'a, 'b> Atom<'a, 'b> for Blank
 where
     'a: 'b,
@@ -191,17 +190,32 @@ pub struct ObjectWriter<'a, 'b> {
 }
 
 impl<'a, 'b> ObjectWriter<'a, 'b> {
+    /// Initialize a new property with a context.
+    ///
+    /// This method does the same as [`init`](#method.init), but also sets the context URID.
+    pub fn init_with_context<'c, K: ?Sized, T: ?Sized, A: Atom<'a, 'c>>(
+        &'c mut self,
+        key: URID<K>,
+        context: URID<T>,
+        child_urid: URID<A>,
+        parameter: A::WriteParameter,
+    ) -> Option<A::WriteHandle> {
+        Property::write_header(&mut self.frame, key.into_general(), Some(context))?;
+        (&mut self.frame as &mut dyn MutSpace).init(child_urid, parameter)
+    }
+
     /// Initialize a new property.
     ///
     /// This method writes out the header of a property and returns a reference to the space, so the property values can be written.
-    pub fn init<'c, G: ?Sized, A: Atom<'a, 'c>>(
+    ///
+    /// Properties also have a context URID internally, which is rarely used. If you want to add one, use [`init_with_context`](#method.init_with_context).
+    pub fn init<'c, K: ?Sized, A: Atom<'a, 'c>>(
         &'c mut self,
-        key: URID<G>,
-        context: Option<URID>,
+        key: URID<K>,
         child_urid: URID<A>,
         parameter: A::WriteParameter,
     ) -> Option<A::WriteHandle> {
-        Property::write_header(&mut self.frame, key.into_general(), context)?;
+        Property::write_header::<K, ()>(&mut self.frame, key, None)?;
         (&mut self.frame as &mut dyn MutSpace).init(child_urid, parameter)
     }
 }
@@ -255,7 +269,11 @@ impl Property {
     /// Write out the header of a property atom.
     ///
     /// This method simply writes out the content of the header to the space and returns `Some(())` if it's successful.
-    fn write_header(space: &mut dyn MutSpace, key: URID, context: Option<URID>) -> Option<()> {
+    fn write_header<K: ?Sized, C: ?Sized>(
+        space: &mut dyn MutSpace,
+        key: URID<K>,
+        context: Option<URID<C>>,
+    ) -> Option<()> {
         space.write(&key.get(), true)?;
         space.write(&context.map(|urid| urid.get()).unwrap_or(0), false)?;
         Some(())
@@ -303,14 +321,10 @@ mod tests {
             )
             .unwrap();
             {
-                writer
-                    .init(first_key, None, urids.int, first_value)
-                    .unwrap();
+                writer.init(first_key, urids.int, first_value).unwrap();
             }
             {
-                writer
-                    .init(second_key, None, urids.float, second_value)
-                    .unwrap();
+                writer.init(second_key, urids.float, second_value).unwrap();
             }
         }
 
diff --git a/atom/tests/atom_integration.rs b/atom/tests/atom_integration.rs
index dc5b21aa..1b47fbb0 100644
--- a/atom/tests/atom_integration.rs
+++ b/atom/tests/atom_integration.rs
@@ -42,7 +42,7 @@ impl Plugin for AtomPlugin {
         })
     }
 
-    fn run(&mut self, ports: &mut Ports, _: &mut ()) {
+    fn run(&mut self, ports: &mut Ports, _: &mut (), _: u32) {
         let sequence_reader = ports
             .input
             .read::<Sequence>(self.urids.atom.sequence, self.urids.units.beat)
diff --git a/core/Cargo.toml b/core/Cargo.toml
index 00aa411c..9f733552 100644
--- a/core/Cargo.toml
+++ b/core/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "lv2-core"
-version = "2.0.0"
+version = "3.0.0"
 authors = ["Janonard <jan.opdenhoevel@protonmail.com>", "Adrien Prokopowicz <adrien.prokopowicz@gmail.com>"]
 edition = "2018"
 license = "MIT OR Apache-2.0"
@@ -15,5 +15,5 @@ maintenance = { status = "passively-maintained" }
 
 [dependencies]
 urid = "0.1.0"
-lv2-sys = "1.0.0"
-lv2-core-derive = "2.0.0"
+lv2-sys = "2.0.0"
+lv2-core-derive = "2.1.0"
diff --git a/core/README.md b/core/README.md
index 7ede514d..06c02cd8 100644
--- a/core/README.md
+++ b/core/README.md
@@ -1,4 +1,4 @@
-# rust-lv2's core library.
+# Rust-LV2's core library.
 
 The foundation of [`rust-lv2`](https://crates.io/crates/lv2), a safe, fast, and ergonomic framework to create [LV2 plugins](http://lv2plug.in/) for audio processing, written in Rust.
 
@@ -68,10 +68,6 @@ lv2_descriptors!(Amp);
 
 The original LV2 API (in the `C` programming language) is documented by ["the LV2 book"](https://lv2plug.in/book/). This book is in the process of being translated to Rust along with the development of `rust-lv2` [(link)](https://janonard.github.io/rust-lv2-book/) and describes how to properly use `rust-lv2`.
 
-## Building
-
-Since the bindings to the raw C headers are generated with bindgen, you need to have [Clang](https://clang.llvm.org/) installed on your system and, if it isn't in your system's standard path, set the environment variable `LIBCLANG_PATH` to the path of `libClang`.
-
 ## Features
 
 Like any other crate of `rust-lv2`, this crate has the optional `host` feature. Some of the types defined by some crates are only useful for testing or LV2 hosts. Since the goal of this framework is to provide an easy way to create plugins, these aren't necessary and therefore gated behind that feature.
diff --git a/core/derive/Cargo.toml b/core/derive/Cargo.toml
index f28c6344..9c6f03ea 100644
--- a/core/derive/Cargo.toml
+++ b/core/derive/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "lv2-core-derive"
-version = "2.0.0"
+version = "2.1.0"
 authors = ["Jan-Oliver 'Janonard' Opdenhövel <jan.opdenhoevel@protonmail.com>", "Adrien Prokopowicz <adrien.prokopowicz@gmail.com>"]
 license = "MIT OR Apache-2.0"
 
diff --git a/core/derive/src/port_collection_derive.rs b/core/derive/src/port_collection_derive.rs
index c67d7e02..ac824285 100644
--- a/core/derive/src/port_collection_derive.rs
+++ b/core/derive/src/port_collection_derive.rs
@@ -24,14 +24,7 @@ impl<'a> PortCollectionField<'a> {
         let identifier = self.identifier;
         let port_type = self.port_type;
         quote! {
-            #identifier: {
-                let connection = <#port_type as PortHandle>::from_raw(connections.#identifier, sample_count);
-                if let Some(connection) = connection {
-                    connection
-                } else {
-                    return None;
-                }
-            },
+            #identifier: <#port_type as PortHandle>::from_raw(connections.#identifier, sample_count)?,
         }
     }
 
diff --git a/core/src/extension.rs b/core/src/extension.rs
index 3f062879..f93f25ce 100644
--- a/core/src/extension.rs
+++ b/core/src/extension.rs
@@ -79,7 +79,7 @@
 //!         Some(Self { internal: 0 })
 //!     }
 //!
-//!     fn run(&mut self, _: &mut (), _: &mut ()) {
+//!     fn run(&mut self, _: &mut (), _: &mut (), _: u32) {
 //!         self.internal += 1;
 //!     }
 //!
diff --git a/core/src/feature/cache.rs b/core/src/feature/cache.rs
index 2c548e44..2eb1c588 100644
--- a/core/src/feature/cache.rs
+++ b/core/src/feature/cache.rs
@@ -8,6 +8,7 @@ use std::iter::Map;
 /// At initialization time, a raw LV2 plugin receives a null-terminated array containing all requested host features. Obviously, this is not suited for safe Rust code and therefore, it needs an abstraction layer.
 ///
 /// Internally, this struct contains a hash map which is filled the raw LV2 feature descriptors. Using this map, methods are defined to identify and retrieve features.
+#[derive(Clone)]
 pub struct FeatureCache<'a> {
     internal: HashMap<&'a CStr, *const c_void>,
 }
diff --git a/core/src/feature/mod.rs b/core/src/feature/mod.rs
index fb9baf0a..cbdcbc64 100644
--- a/core/src/feature/mod.rs
+++ b/core/src/feature/mod.rs
@@ -30,7 +30,7 @@ pub enum ThreadingClass {
 ///
 /// In Rust, most of this behaviour is done internally and instead of simply casting a pointer, a safe feature descriptor, which implements this trait, is constructed using the [`from_raw_data`](#tymethod.from_raw_data) method.
 ///
-/// Some host features may only be used in certain threading classes. This is guarded by rust-lv2 by passing the threading class in which the plugin will be used to the feature, which then may take different actions.
+/// Some host features may only be used in certain threading classes. This is guarded by Rust-LV2 by passing the threading class in which the plugin will be used to the feature, which then may take different actions.
 pub unsafe trait Feature: UriBound + Sized {
     /// Create an instance of the featurer.
     ///
diff --git a/core/src/lib.rs b/core/src/lib.rs
index b6e58bc0..369b2245 100644
--- a/core/src/lib.rs
+++ b/core/src/lib.rs
@@ -2,9 +2,6 @@
 //!
 //! This crate forms the foundation of the LV2 experience for Rust: It contains the plugin trait and ports, as well as means to retrieve features from the host and to extend the interface of the plugin.
 //!
-//! Since this crate depends on `-sys` crates that use `bindgen` to create the C API bindings,
-//! you need to have clang installed on your machine.
-//!
 //! # Example
 //!
 //! ```
@@ -46,7 +43,7 @@
 //!
 //!     // Process a chunk of audio. The audio ports are dereferenced to slices, which the plugin
 //!     // iterates over.
-//!     fn run(&mut self, ports: &mut Ports, _features: &mut ()) {
+//!     fn run(&mut self, ports: &mut Ports, _features: &mut (), _: u32) {
 //!         let coef = if *(ports.gain) > -90.0 {
 //!             10.0_f32.powf(*(ports.gain) * 0.05)
 //!         } else {
diff --git a/core/src/plugin/mod.rs b/core/src/plugin/mod.rs
index e6c1d7c7..a1509cec 100644
--- a/core/src/plugin/mod.rs
+++ b/core/src/plugin/mod.rs
@@ -45,7 +45,14 @@ pub trait Plugin: UriBound + Sized + Send + Sync + 'static {
     /// Run a processing step.
     ///
     /// The host will always call this method after `active` has been called and before `deactivate` has been called.
-    fn run(&mut self, ports: &mut Self::Ports, features: &mut Self::AudioFeatures);
+    ///
+    /// The sample count is the number of frames covered by this `run` call. Audio and CV ports will contain exactly `sample_count` frames. Please note that `sample_count` may be differ between calls.
+    fn run(
+        &mut self,
+        ports: &mut Self::Ports,
+        features: &mut Self::AudioFeatures,
+        sample_count: u32,
+    );
 
     /// Reset and initialize the complete internal state of the plugin.
     ///
@@ -77,13 +84,13 @@ pub trait Plugin: UriBound + Sized + Send + Sync + 'static {
 #[repr(C)]
 pub struct PluginInstance<T: Plugin> {
     /// The plugin instance.
-    pub instance: T,
+    instance: T,
     /// A temporary storage for all ports of the plugin.
-    pub connections: <T::Ports as PortCollection>::Cache,
+    connections: <T::Ports as PortCollection>::Cache,
     /// All features that may be used in the initialization threading class.
-    pub init_features: T::InitFeatures,
+    init_features: T::InitFeatures,
     /// All features that may be used in the audio threading class.
-    pub audio_features: T::AudioFeatures,
+    audio_features: T::AudioFeatures,
 }
 
 impl<T: Plugin> PluginInstance<T> {
@@ -131,17 +138,21 @@ impl<T: Plugin> PluginInstance<T> {
         };
 
         // Collect the supported features.
-        let mut feature_cache = FeatureCache::from_raw(features);
-        let mut init_features =
-            match T::InitFeatures::from_cache(&mut feature_cache, ThreadingClass::Instantiation) {
-                Ok(f) => f,
-                Err(e) => {
-                    eprintln!("{}", e);
-                    return std::ptr::null_mut();
-                }
-            };
+        let mut init_features_cache = FeatureCache::from_raw(features);
+        let mut audio_features_cache = init_features_cache.clone();
+
+        let mut init_features = match T::InitFeatures::from_cache(
+            &mut init_features_cache,
+            ThreadingClass::Instantiation,
+        ) {
+            Ok(f) => f,
+            Err(e) => {
+                eprintln!("{}", e);
+                return std::ptr::null_mut();
+            }
+        };
         let audio_features =
-            match T::AudioFeatures::from_cache(&mut feature_cache, ThreadingClass::Audio) {
+            match T::AudioFeatures::from_cache(&mut audio_features_cache, ThreadingClass::Audio) {
                 Ok(f) => f,
                 Err(e) => {
                     eprintln!("{}", e);
@@ -224,7 +235,7 @@ impl<T: Plugin> PluginInstance<T> {
         if let Some(mut ports) = instance.ports(sample_count) {
             instance
                 .instance
-                .run(&mut ports, &mut instance.audio_features);
+                .run(&mut ports, &mut instance.audio_features, sample_count);
         }
     }
 
@@ -243,6 +254,25 @@ impl<T: Plugin> PluginInstance<T> {
             std::ptr::null()
         }
     }
+
+    /// Retrieve the internal plugin.
+    pub fn plugin_handle(&mut self) -> &mut T {
+        &mut self.instance
+    }
+
+    /// Retrieve the required handles to execute an Initialization class method.
+    ///
+    /// This method can be used by extensions to call an extension method in the Initialization threading class and provide it the host features for that class.
+    pub fn init_class_handle(&mut self) -> (&mut T, &mut T::InitFeatures) {
+        (&mut self.instance, &mut self.init_features)
+    }
+
+    /// Retrieve the required handles to execute an Audio class method.
+    ///
+    /// This method can be used by extensions to call an extension method in the Audio threading class and provide it the host features for that class.
+    pub fn audio_class_handle(&mut self) -> (&mut T, &mut T::AudioFeatures) {
+        (&mut self.instance, &mut self.audio_features)
+    }
 }
 
 #[doc(hidden)]
diff --git a/core/tests/amp.rs b/core/tests/amp.rs
index b5ec5f18..25c9e94d 100644
--- a/core/tests/amp.rs
+++ b/core/tests/amp.rs
@@ -53,7 +53,7 @@ impl Plugin for Amp {
     }
 
     #[inline]
-    fn run(&mut self, ports: &mut AmpPorts, _: &mut ()) {
+    fn run(&mut self, ports: &mut AmpPorts, _: &mut (), _: u32) {
         assert!(self.activated);
 
         let coef = *(ports.gain);
diff --git a/docs/.gitignore b/docs/.gitignore
new file mode 100644
index 00000000..acf7e422
--- /dev/null
+++ b/docs/.gitignore
@@ -0,0 +1,7 @@
+
+target
+_build
+chapter
+Cargo.lock
+__pycache__
+.vscode
\ No newline at end of file
diff --git a/docs/LICENSE.md b/docs/LICENSE.md
new file mode 100644
index 00000000..b01e14b4
--- /dev/null
+++ b/docs/LICENSE.md
@@ -0,0 +1,15 @@
+Copyright 2019 Jan-Oliver "Janonard" Opdenhövel.
+
+Based on LV2, Copyright 2006-2012 Steve Harris, David Robillard.
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
\ No newline at end of file
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 00000000..382e743b
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,22 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line, and also
+# from the environment for the first two.
+SPHINXOPTS    ?=
+SPHINXBUILD   ?= sphinx-build
+SOURCEDIR     = .
+BUILDDIR      = _build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+	mkdir -p export
+	./make_chapters.py
+	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 00000000..ae732131
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,25 @@
+# Programming LV2 Plugins - Rust Edition
+
+[![Build Status](https://travis-ci.org/Janonard/rust-lv2-book.svg?branch=master)](https://travis-ci.org/Janonard/rust-lv2-book)
+
+This repository contains the sample plugins of the "Programming LV2 Plugins - Rust edition" book, as well as means to build both the plugins and the book.
+
+## Building the book
+
+The book is generated from the source files of the samples. In order to build the book, you need to have Python 3 installed. Simply type
+
+```bash
+python3 make_book.py
+```
+
+and the book will be written to `export/README.md`.
+
+## Building and installing the sample plugins
+
+Every sample is a self-contained Rust crate; You can simply build it with cargo. If you want to install the samples on your machine, you can run `install_examples.sh`. This will build the crates, bundle them and copy them to `~/.lv2`.
+
+The compiler might complain that "profiles for the non root package will be ignored", which you can safely ignore. Some examples have a profile section to show how to enable link-time optimizations, but these profile section don't have an effect.
+
+## Licensing
+
+Just like the original, the book and the code is published under the `ISC` license. See the [LICENSE file](LICENSE.md) for more info.
\ No newline at end of file
diff --git a/docs/amp/Cargo.toml b/docs/amp/Cargo.toml
new file mode 100644
index 00000000..9a716f0b
--- /dev/null
+++ b/docs/amp/Cargo.toml
@@ -0,0 +1,22 @@
+# The host does not really care in which language the code of the plugin is written, as long as the
+# built library complies to the headers of the specifications. Therefore, every plugin is a standard
+# Cargo crate.
+[package]
+name = "amp"
+version = "0.2.0"
+authors = ["Jan-Oliver 'Janonard' Opdenhövel <jan.opdenhoevel@protonmail.com>"]
+license = "ISC"
+edition = "2018"
+
+# Plugins are dynamic libraries. This setting tells cargo to export it this way.
+[lib]
+crate-type = ["cdylib"]
+
+# Rust-LV2 is a network of individual sub-crates with different version numbers and histories.
+# However, most plugins don't need to deal with them directly. Instead, they use the re-export crate
+# simply called `lv2`. It has an optional dependency to every sub-crate, which can be enabled via crate features.
+# 
+# The default feature set includes everything to create a simple plugin for audio and MIDI processing.
+# Therefore, we don't need to enable extra features here.
+[dependencies]
+lv2 = "0.6.0"
\ No newline at end of file
diff --git a/docs/amp/eg-amp-rs.lv2/amp.ttl b/docs/amp/eg-amp-rs.lv2/amp.ttl
new file mode 100644
index 00000000..af6fdb60
--- /dev/null
+++ b/docs/amp/eg-amp-rs.lv2/amp.ttl
@@ -0,0 +1,80 @@
+# The full description of the plugin is in this file, which is linked to from
+# `manifest.ttl`.  This is done so the host only needs to scan the relatively
+# small `manifest.ttl` files to quickly discover all plugins.
+@prefix doap:  <http://usefulinc.com/ns/doap#> .
+@prefix lv2:   <http://lv2plug.in/ns/lv2core#> .
+@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix units: <http://lv2plug.in/ns/extensions/units#> .
+# First the type of the plugin is described.  All plugins must explicitly list
+# `lv2:Plugin` as a type.  A more specific type should also be given, where
+# applicable, so hosts can present a nicer UI for loading plugins.  Note that
+# this URI is the identifier of the plugin, so if it does not match the one in
+# `manifest.ttl`, the host will not discover the plugin data at all.
+<https://github.com/RustAudio/rust-lv2/tree/master/docs/amp>
+        a lv2:Plugin ,
+                lv2:AmplifierPlugin ;
+# Plugins are associated with a project, where common information like
+# developers, home page, and so on are described.  This plugin is part of the
+# Rust-LV2 project, which has URI <https://github.com/RustAudio/rust-lv2>, and is described
+# elsewhere.  Typical plugin collections will describe the project in
+# manifest.ttl
+        lv2:project <https://github.com/RustAudio/rust-lv2> ;
+# Every plugin must have a name, described with the doap:name property.
+        doap:name "Simple Amplifier (Rust Version)" ;
+        doap:license <http://opensource.org/licenses/isc> ;
+# This tells the host that this plugin can not work "in-place"; The input and output buffers may not be the same. This plugin could technically work "in-place", but it would mean that the plugin would receive a mutable and an immutable reference to the same place in memory, which obviously isn't allowed in Rust.
+        lv2:requiredFeature lv2:inPlaceBroken ;
+        lv2:optionalFeature lv2:hardRTCapable ;
+        lv2:port [
+# Every port must have at least two types, one that specifies direction
+# (lv2:InputPort or lv2:OutputPort), and another to describe the data type.
+# This port is a lv2:ControlPort, which means it contains a single float.
+                a lv2:InputPort ,
+                        lv2:ControlPort ;
+                lv2:index 0 ;
+                lv2:symbol "gain" ;
+                lv2:name "Gain" ,
+                        "收益"@ch ,
+                        "Gewinn"@de ,
+                        "Gain"@en-gb ,
+                        "Aumento"@es ,
+                        "Gain"@fr ,
+                        "Guadagno"@it ,
+                        "ゲイン"@jp ,
+                        "Увеличение"@ru ;
+# An lv2:ControlPort should always describe its default value, and usually a
+# minimum and maximum value.  Defining a range is not strictly required, but
+# should be done wherever possible to aid host support, particularly for UIs.
+                lv2:default 0.0 ;
+                lv2:minimum -90.0 ;
+                lv2:maximum 24.0 ;
+# Ports can describe units and control detents to allow better UI generation
+# and host automation.
+                units:unit units:db ;
+                lv2:scalePoint [
+                        rdfs:label "+5" ;
+                        rdf:value 5.0
+                ] , [
+                        rdfs:label "0" ;
+                        rdf:value 0.0
+                ] , [
+                        rdfs:label "-5" ;
+                        rdf:value -5.0
+                ] , [
+                        rdfs:label "-10" ;
+                        rdf:value -10.0
+                ]
+        ] , [
+                a lv2:AudioPort ,
+                        lv2:InputPort ;
+                lv2:index 1 ;
+                lv2:symbol "in" ;
+                lv2:name "In"
+        ] , [
+                a lv2:AudioPort ,
+                        lv2:OutputPort ;
+                lv2:index 2 ;
+                lv2:symbol "out" ;
+                lv2:name "Out"
+        ] .
diff --git a/docs/amp/eg-amp-rs.lv2/manifest.ttl b/docs/amp/eg-amp-rs.lv2/manifest.ttl
new file mode 100644
index 00000000..888184ee
--- /dev/null
+++ b/docs/amp/eg-amp-rs.lv2/manifest.ttl
@@ -0,0 +1,46 @@
+# LV2 plugins are installed in a "bundle", a directory with a standard structure. Each bundle has a
+# Turtle file named `manifest.ttl` which lists the contents of the bundle.
+#
+# Hosts typically read the manifest of every installed bundle to discover plugins on start-up, so it
+# should be as small as possible for performance reasons. Details that are only useful if the host
+# chooses to load the plugin are stored in other files and linked to from `manifest.ttl`.
+#
+# In a crate, this should be a special folder that contains the Turtle files. After the crate was
+# build, the resulting shared object should also be copied into this folder.
+# 
+# #### URIs
+#
+# LV2 makes use of URIs as globally-unique identifiers for resources. For example, the ID of the
+# plugin described here is `<https://github.com/RustAudio/rust-lv2/tree/master/docs/amp>`. Note that URIs are only used as identifiers
+# and don't necessarily imply that something can be accessed at that address on the web (though that
+# may be the case).
+# 
+# #### Namespace Prefixes
+#
+# Turtle files contain many URIs, but prefixes can be defined to improve readability. For example,
+# with the `lv2:` prefix below, `lv2:Plugin` can be written instead of 
+# `<http://lv2plug.in/ns/lv2core#Plugin>`.
+
+@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+# #### Describing a Plugin
+#
+# Turtle files contain a set of subject-predicate-object statements which describe resources. 
+# 
+# Firstly, `<https://github.com/RustAudio/rust-lv2/tree/master/docs/amp>` is an LV2 plugin:
+
+<https://github.com/RustAudio/rust-lv2/tree/master/docs/amp> a lv2:Plugin .
+
+# The predicate `a` is a Turtle shorthand for `rdf:type`.
+#
+# The binary of that plugin can be found at `<amp.ext>`:
+<https://github.com/RustAudio/rust-lv2/tree/master/docs/amp> lv2:binary <libamp.so> .
+
+# This line is platform-dependent since it assumes that shared objects have the `.so` ending. On
+# Windows, it should be ending with `.dll`. Relative URIs in manifests are relative to the bundle 
+# directory, so this refers to a binary with the given name in the same directory as this manifest.
+# 
+# Finally, more information about this plugin can be found in `<amp.ttl>`:
+
+<https://github.com/RustAudio/rust-lv2/tree/master/docs/amp> rdfs:seeAlso <amp.ttl> .
diff --git a/docs/amp/src/lib.rs b/docs/amp/src/lib.rs
new file mode 100644
index 00000000..1e58657c
--- /dev/null
+++ b/docs/amp/src/lib.rs
@@ -0,0 +1,39 @@
+// Include the prelude of `lv2`. This includes the preludes of every sub-crate and you are strongly encouraged to use it, since many macros depend on it.
+use lv2::prelude::*;
+// Most useful plugins will have ports for input and output data. In code, these ports are represented by a struct implementing the `PortCollection` trait. Internally, ports are referred to by index. These indices are assigned in ascending order, starting with 0 for the first port. The indices in `amp.ttl` have to match them.
+#[derive(PortCollection)]
+struct Ports {
+    gain: InputPort<Control>,
+    input: InputPort<Audio>,
+    output: OutputPort<Audio>,
+}
+// Every plugin defines a struct for the plugin instance. All persistent data associated with a plugin instance is stored here, and is available to every instance method. In this simple plugin, there is no additional instance data and therefore, this struct is empty.
+//
+// The URI is the identifier for a plugin, and how the host associates this implementation in code with its description in data. If this URI does not match that used in the data files, the host will fail to load the plugin. This attribute internally implements the `UriBound` trait for `Amp`, which is also used to identify many other things in the Rust-LV2 ecosystem.
+#[uri("https://github.com/RustAudio/rust-lv2/tree/master/docs/amp")]
+struct Amp;
+// Every plugin struct implements the `Plugin` trait. This trait contains both the methods that are called by the hosting application and the collection types for the ports and the used host features. This plugin does not use additional host features and therefore, we set both feature collection types to `()`. Other plugins may define separate structs with their required and optional features and set it here.
+impl Plugin for Amp {
+    type Ports = Ports;
+
+    type InitFeatures = ();
+    type AudioFeatures = ();
+    // The `new` method is called by the plugin backend when it creates a new plugin instance. The host passes the plugin URI, sample rate, and bundle path for plugins that need to load additional resources (e.g. waveforms). The features parameter contains host-provided features defined in LV2 extensions, but this simple plugin does not use any. This method is in the “instantiation” threading class, so no other methods on this instance will be called concurrently with it.
+    fn new(_plugin_info: &PluginInfo, _features: &mut ()) -> Option<Self> {
+        Some(Self)
+    }
+    // The `run()` method is the main process function of the plugin. It processes a block of audio in the audio context. Since this plugin is `lv2:hardRTCapable`, `run()` must be real-time safe, so blocking (e.g. with a mutex) or memory allocation are not allowed.
+    fn run(&mut self, ports: &mut Ports, _features: &mut (), _: u32) {
+        let coef = if *(ports.gain) > -90.0 {
+            10.0_f32.powf(*(ports.gain) * 0.05)
+        } else {
+            0.0
+        };
+
+        for (in_frame, out_frame) in Iterator::zip(ports.input.iter(), ports.output.iter_mut()) {
+            *out_frame = in_frame * coef;
+        }
+    }
+}
+// The `lv2_descriptors` macro creates the entry point to the plugin library. It takes structs that implement `Plugin` and exposes them. The host will load the library and call a generated function to find all the plugins defined in the library.
+lv2_descriptors!(Amp);
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 00000000..4aee9e38
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,55 @@
+import sphinx_rtd_theme
+
+# Configuration file for the Sphinx documentation builder.
+#
+# This file only contains a selection of the most common options. For a full
+# list see the documentation:
+# https://www.sphinx-doc.org/en/master/usage/configuration.html
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+import os
+import sys
+sys.path.insert(0, os.path.abspath('.'))
+import make_chapters
+make_chapters.make()
+
+# -- Project information -----------------------------------------------------
+
+project = 'Rust-LV2'
+copyright = "2020, Jan-Oliver 'Janonard' Opdenhövel, Adrien Prokopowicz, Amaury 'Yruama_Lairba' Abrial"
+author = "Jan-Oliver 'Janonard' Opdenhövel, Adrien Prokopowicz, Amaury 'Yruama_Lairba' Abrial"
+
+# The full version, including alpha/beta/rc tags
+release = '0.5.1'
+
+
+# -- General configuration ---------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+    'recommonmark',
+    "sphinx_rtd_theme"
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
+exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'introductions', 'README.md', 'LICENSE.md']
+
+
+# -- Options for HTML output -------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'sphinx_rtd_theme'
\ No newline at end of file
diff --git a/docs/fifths/Cargo.toml b/docs/fifths/Cargo.toml
new file mode 100644
index 00000000..b0cdba76
--- /dev/null
+++ b/docs/fifths/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "fifths"
+version = "0.1.0"
+authors = ["Jan-Oliver 'Janonard' Opdenhövel <jan.opdenhoevel@protonmail.com>"]
+edition = "2018"
+
+[lib]
+crate-type = ["cdylib"]
+
+[dependencies]
+wmidi = "3.1.0"
+lv2 = "0.6.0"
\ No newline at end of file
diff --git a/docs/fifths/eg-fifths-rs.lv2/fifths.ttl b/docs/fifths/eg-fifths-rs.lv2/fifths.ttl
new file mode 100644
index 00000000..f1fc9e13
--- /dev/null
+++ b/docs/fifths/eg-fifths-rs.lv2/fifths.ttl
@@ -0,0 +1,30 @@
+@prefix atom:  <http://lv2plug.in/ns/ext/atom#> .
+@prefix doap:  <http://usefulinc.com/ns/doap#> .
+@prefix lv2:   <http://lv2plug.in/ns/lv2core#> .
+@prefix urid:  <http://lv2plug.in/ns/ext/urid#> .
+@prefix midi:  <http://lv2plug.in/ns/ext/midi#> .
+
+<https://github.com/RustAudio/rust-lv2/tree/master/docs/fifths>
+	a lv2:Plugin ;
+	doap:name "Example Fifths (Rust Edition)" ;
+	doap:license <http://opensource.org/licenses/isc> ;
+    lv2:project <https://github.com/RustAudio/rust-lv2> ;
+	lv2:requiredFeature urid:map , lv2:inPlaceBroken ;
+	lv2:optionalFeature lv2:hardRTCapable ;
+	lv2:port [
+		a lv2:InputPort ,
+			atom:AtomPort ;
+		atom:bufferType atom:Sequence ;
+		atom:supports midi:MidiEvent ;
+		lv2:index 0 ;
+		lv2:symbol "in" ;
+		lv2:name "In"
+	] , [
+		a lv2:OutputPort ,
+			atom:AtomPort ;
+		atom:bufferType atom:Sequence ;
+		atom:supports midi:MidiEvent ;
+		lv2:index 1 ;
+		lv2:symbol "out" ;
+		lv2:name "Out"
+	] .
diff --git a/docs/fifths/eg-fifths-rs.lv2/manifest.ttl b/docs/fifths/eg-fifths-rs.lv2/manifest.ttl
new file mode 100644
index 00000000..a5ae0c30
--- /dev/null
+++ b/docs/fifths/eg-fifths-rs.lv2/manifest.ttl
@@ -0,0 +1,9 @@
+# You should be familiar with these Turtle files by know!
+@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix ui:   <http://lv2plug.in/ns/extensions/ui#> .
+
+<https://github.com/RustAudio/rust-lv2/tree/master/docs/fifths>
+	a lv2:Plugin ;
+	lv2:binary <libfifths.so> ;
+	rdfs:seeAlso <fifths.ttl> .
diff --git a/docs/fifths/src/lib.rs b/docs/fifths/src/lib.rs
new file mode 100644
index 00000000..7e963c5d
--- /dev/null
+++ b/docs/fifths/src/lib.rs
@@ -0,0 +1,100 @@
+// The same as before...
+use lv2::prelude::*;
+use wmidi::*;
+
+#[derive(PortCollection)]
+pub struct Ports {
+    input: InputPort<AtomPort>,
+    output: OutputPort<AtomPort>,
+}
+
+#[derive(FeatureCollection)]
+pub struct Features<'a> {
+    map: LV2Map<'a>,
+}
+
+#[derive(URIDCollection)]
+pub struct URIDs {
+    atom: AtomURIDCollection,
+    midi: MidiURIDCollection,
+    unit: UnitURIDCollection,
+}
+
+#[uri("https://github.com/RustAudio/rust-lv2/tree/master/docs/fifths")]
+pub struct Fifths {
+    urids: URIDs,
+}
+
+impl Plugin for Fifths {
+    type Ports = Ports;
+
+    type InitFeatures = Features<'static>;
+    type AudioFeatures = ();
+
+    fn new(_plugin_info: &PluginInfo, features: &mut Features<'static>) -> Option<Self> {
+        Some(Self {
+            urids: features.map.populate_collection()?,
+        })
+    }
+
+    // This plugin works similar to the previous one: It iterates over the events in the input port. However, it only needs to write one or two messages instead of blocks of audio.
+    fn run(&mut self, ports: &mut Ports, _: &mut (), _: u32) {
+        // Get the reading handle of the input sequence.
+        let input_sequence = ports
+            .input
+            .read(self.urids.atom.sequence, self.urids.unit.beat)
+            .unwrap();
+
+        // Initialise the output sequence and get the writing handle.
+        let mut output_sequence = ports
+            .output
+            .init(
+                self.urids.atom.sequence,
+                TimeStampURID::Frames(self.urids.unit.frame),
+            )
+            .unwrap();
+
+        for (timestamp, atom) in input_sequence {
+            // Every message is forwarded, regardless of it's content.
+            output_sequence.forward(timestamp, atom);
+
+            // Retrieve the message.
+            let message = if let Some(message) = atom.read(self.urids.midi.wmidi, ()) {
+                message
+            } else {
+                continue;
+            };
+
+            match message {
+                MidiMessage::NoteOn(channel, note, velocity) => {
+                    // Create a note 5th (7 semitones) higher than the input.
+                    if let Ok(note) = note.step(7) {
+                        // Write the fifth. Writing is done after initialization.
+                        output_sequence
+                            .init(
+                                timestamp,
+                                self.urids.midi.wmidi,
+                                MidiMessage::NoteOn(channel, note, velocity),
+                            )
+                            .unwrap();
+                    }
+                }
+                MidiMessage::NoteOff(channel, note, velocity) => {
+                    // Do the same thing for `NoteOff`.
+                    if let Ok(note) = note.step(7) {
+                        output_sequence
+                            .init(
+                                timestamp,
+                                self.urids.midi.wmidi,
+                                MidiMessage::NoteOff(channel, note, velocity),
+                            )
+                            .unwrap();
+                    }
+                }
+                _ => (),
+            }
+        }
+    }
+}
+
+lv2_descriptors!(Fifths);
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 00000000..3c77ac85
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,26 @@
+Programming LV2 Plugins - Rust Edition
+======================================
+
+This is a series of well-documented example plugins that demonstrate the various features of `LV2`_ and how they translate to `rust-lv2`_. Starting with the most basic plugin possible, each adds new functionality and explains the features used from a high level perspective.
+
+API and vocabulary reference documentation explains details, but not the "big picture". This book is intended to complement the reference documentation by providing good reference implementations of plugins, while also conveying a higher-level understanding of LV2.
+
+The chapters/plugins are arranged so that each builds incrementally on its predecessor. Reading this book front to back is a good way to become familiar with modern LV2 programming. The reader is expected to be familiar with Rust, but otherwise no special knowledge is required; the first plugin describes the basics in detail.
+
+Each chapter corresponds to executable plugin code which can be found in the  `project's doc folder`_. If you prefer to read actual source code, all the content here is also available in the source code as comments.
+
+This book is a "translation" of `the original LV2 Book by David Robillard`_. Most of the examples as well as the README's and comments are copied from the original and have been altered to adapt for the differences between C and Rust.
+
+.. toctree::
+   :maxdepth: 2
+   :caption: Chapters:
+
+   chapter/amp
+   chapter/midigate
+   chapter/fifths
+   chapter/metro
+
+.. _LV2: https://lv2plug.in/
+.. _rust-lv2: https://github.com/RustAudio/rust-lv2
+.. _project's doc folder: https://github.com/RustAudio/rust-lv2/tree/master/docs
+.. _the original LV2 Book by David Robillard: http://lv2plug.in/book/
\ No newline at end of file
diff --git a/docs/introductions/amp.md b/docs/introductions/amp.md
new file mode 100644
index 00000000..3ade5624
--- /dev/null
+++ b/docs/introductions/amp.md
@@ -0,0 +1,13 @@
+## Simple Amplifier
+
+This plugin is a simple example of a basic LV2 plugin with no additional features. It has audio ports which contain an array of float, and a control port which contains a single float.
+
+LV2 plugins are defined in two parts: code and data. The code provides an interface to the host written in C, but it can be written in any C-compatible language. Static data is described separately in the human and machine friendly Turtle syntax.
+
+Generally, the goal is to keep code minimal, and describe as much as possible in the static data. There are several advantages to this approach:
+
+* Hosts can discover and inspect plugins without loading or executing any plugin code.
+* Plugin data can be used from a wide range of generic tools like scripting languages and command line utilities.
+* The standard data model allows the use of existing vocabularies to describe plugins and related information.
+* The language is extensible, so authors may describe any data without requiring changes to the LV2 specification.
+* Labels and documentation are translatable, and available to hosts for display in user interfaces.
diff --git a/docs/introductions/fifths.md b/docs/introductions/fifths.md
new file mode 100644
index 00000000..5f13f0bc
--- /dev/null
+++ b/docs/introductions/fifths.md
@@ -0,0 +1,5 @@
+## Fifths
+
+This plugin demonstrates simple MIDI event reading and writing.
+
+For every note-on and note-off event it reads, it writes the original note and it's fifth. Therefore, you can play a power-chords by pressing only one key!
\ No newline at end of file
diff --git a/docs/introductions/metro.md b/docs/introductions/metro.md
new file mode 100644
index 00000000..a5e486fc
--- /dev/null
+++ b/docs/introductions/metro.md
@@ -0,0 +1,11 @@
+# Metro
+
+This plugin showcases several interesting topics: First of all, it shows how to synthesize notes using a sampled sine wave and an envelope. These notes are also synchronized to the host's transport via the "time" extension and lastly, it uses the [pipes library](https://github.com/Janonard/pipes) to express the internal processing pipeline.
+
+A pipe is similar to an iterator as it has a `next` method that produces the next item of the pipeline. However, it also takes an input item to create this output item. Therefore, individual pipes can be chained into larger pipes and even complete pipelines.
+
+Using pipes has multiple advantages over writing the processing algorithm "manually": First of all, it slices the pipeline into well-defined pieces that can easily be understood on their own. Then, they also provide a testable interface to the individual parts of the algorithm, which is very useful since you can't properly test your code online, and lastly, they also improve the reusability of your code.
+
+However, they also have some downsides: First of all, they require more code than a "manual" implementation, since every pipe is a type on its own. Also, since the algorithm is split into many small methods, there is an overhead from the function calls and it might be hard for the compiler to use [SIMD instructions](https://en.wikipedia.org/wiki/SIMD).
+
+We don't tell you which approach to use, but we would like to show you both so you can decide!
\ No newline at end of file
diff --git a/docs/introductions/midigate.md b/docs/introductions/midigate.md
new file mode 100644
index 00000000..5a296d43
--- /dev/null
+++ b/docs/introductions/midigate.md
@@ -0,0 +1,8 @@
+## MIDI Gate
+
+This plugin demonstrates:
+* Receiving MIDI input
+* Processing audio based on MIDI events with sample accuracy
+* Supporting MIDI programs which the host can control/automate, or present a user interface for with human readable labels
+
+A key concept of LV2 that is introduced with this plugin is URID. As you've learned before, many things in the LV2 ecosystem are identified by URIs. However, comparing URIs isn't nescessarily fast and the time it takes to compare URIs rises with their length. Therefore, every known URI is mapped to number, a so-called URID, which is used instead of the full URI when time and space is valuable. This mapping is done by the host, which also assures that the mappings are consistent across plugins. Therefore, URIDs are also used for host-plugin or plugin-plugin communication.
\ No newline at end of file
diff --git a/docs/make_chapters.py b/docs/make_chapters.py
new file mode 100755
index 00000000..b7d82904
--- /dev/null
+++ b/docs/make_chapters.py
@@ -0,0 +1,189 @@
+#!/usr/bin/env python3
+from pathlib import Path
+import os
+import re
+import itertools
+import argparse
+
+class Line(object):
+    """
+    Base class for a document line.
+    """
+
+    def __init__(self, content):
+        self.content = content
+
+    def __str__(self):
+        return self.content
+
+
+class CommentLine(Line):
+    """
+    A line that was a comment in the source document.
+    It will be outputed as normal text.
+    """
+
+    pass
+
+
+class CodeLine(Line):
+    """
+    A line that was source code in the source document.
+    It will be outputed as quoted code.
+    """
+
+    pass
+
+
+class Block(object):
+    """
+    Base class for a block of lines. This class represents normal, unmodified text.
+    """
+
+    def __init__(self):
+        self.lines = list()
+
+    def add_line(self, line):
+        """
+        Add another line to the block.
+        `line` is supposed to be a `Line` object and has to be of the same type as the other lines
+        in this block.
+        """
+        self.lines.append(line)
+
+    def __str__(self):
+        return "\n".join(map(str, self.lines))
+
+
+class CodeBlock(Block):
+    """
+    A block of code lines. It has additional features to export the lines as quoted code.
+    """
+
+    def __init__(self, language):
+        self.language = language
+        self.lines = list()
+
+    def __str__(self):
+        return "\n```{}\n".format(self.language) + "\n".join(map(str, self.lines)) + "\n```\n"
+
+class File(object):
+
+    def __init__(self, path, language=None):
+        self.path = path
+
+        # Determine the language of the source.
+        if language is None:
+            language = re.match(r".([^\n]*)", path.suffix).group(1)
+
+        # Read the raw lines fromt the input file.
+        with path.open("r") as input:
+            raw_lines = input.readlines()
+
+        # Retrieve an iterator over all line object.
+        lines = make_lines(raw_lines, language)
+        # Retrieve an iterator over all blocks.
+        self.blocks = list(lines_to_blocks(lines, language))
+
+    def __str__(self):
+        return "### {}\n\n".format(str(self.path)) + "\n".join(map(str, self.blocks))
+
+class Chapter(object):
+
+    def __init__(self, intro_path, paths):
+        self.intro = "".join(open(intro_path, "r").readlines())
+        self.files = list()
+        for path in paths:
+            self.files.append(File(Path(path)))
+
+    def __str__(self):
+        return self.intro + "\n" + "\n".join(map(str, self.files))
+
+def make_lines(raw_lines, language):
+    """
+    Iterate through the raw lines and yield either a `CommentLine` or a `CodeLine`.
+    """
+    # Depending on the language, other comment indicators are used.
+    if language == "rs":
+        comment_indicator_re = re.compile(r"\s*//\s*([^\n]*)")
+    else:
+        comment_indicator_re = re.compile(r"\s*#\s*([^\n]*)")
+    # A RE to clean a code line of the new-line character and to remove empty code lines.
+    clean_line_re = re.compile(r"([^\n]*)")
+
+    for line in raw_lines:
+        is_comment = comment_indicator_re.match(line)
+        if is_comment:
+            yield CommentLine(is_comment.group(1))
+        else:
+            cleaned_line = clean_line_re.match(line)
+            if cleaned_line is not None:
+                yield CodeLine(cleaned_line.group(1))
+
+
+def lines_to_blocks(lines, language):
+    """
+    Iterate through the lines and group them in blocks.
+    """
+    last_block = None
+    for line in lines:
+        if last_block is None:
+            new_block = True
+        elif type(last_block.lines[-1]) != type(line):
+            yield last_block
+            new_block = True
+        else:
+            new_block = False
+
+        if new_block:
+            if type(line) == CodeLine:
+                last_block = CodeBlock(language)
+            else:
+                last_block = Block()
+
+        last_block.add_line(line)
+    yield last_block
+
+def make():
+    try:
+        os.mkdir("chapter")
+    except FileExistsError:
+        pass
+
+    amp = Chapter("introductions/amp.md", [
+        "amp/eg-amp-rs.lv2/manifest.ttl",
+        "amp/eg-amp-rs.lv2/amp.ttl",
+        "amp/Cargo.toml",
+        "amp/src/lib.rs",
+    ])
+
+    open("chapter/amp.md", "w").write(str(amp))
+
+    midigate = Chapter("introductions/midigate.md", [
+        "midigate/eg-midigate-rs.lv2/manifest.ttl",
+        "midigate/eg-midigate-rs.lv2/midigate.ttl",
+        "midigate/Cargo.toml",
+        "midigate/src/lib.rs"
+    ])
+
+    open("chapter/midigate.md", "w").write(str(midigate))
+
+    fifths = Chapter("introductions/fifths.md", [
+        "fifths/eg-fifths-rs.lv2/manifest.ttl",
+        "fifths/eg-fifths-rs.lv2/fifths.ttl",
+        "fifths/Cargo.toml",
+        "fifths/src/lib.rs"
+    ])
+
+    open("chapter/fifths.md", "w").write(str(fifths))
+
+    metro = Chapter("introductions/metro.md", [
+        "metro/eg-metro-rs.lv2/manifest.ttl",
+        "metro/eg-metro-rs.lv2/metro.ttl",
+        "metro/Cargo.toml",
+        "metro/src/pipes.rs",
+        "metro/src/lib.rs"
+    ])
+
+    open("chapter/metro.md", "w").write(str(metro))
+
diff --git a/docs/metro/Cargo.toml b/docs/metro/Cargo.toml
new file mode 100644
index 00000000..42863c7a
--- /dev/null
+++ b/docs/metro/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "metro"
+version = "0.1.0"
+authors = ["Jan-Oliver 'Janonard' Opdenhövel <jan.opdenhoevel@protonmail.com>"]
+license = "ISC"
+edition = "2018"
+
+[lib]
+crate-type = ["cdylib"]
+
+# This is the first time we need a non-default LV2 feature. In this case, this is the `lv2-time` crate.
+[dependencies]
+lv2 = { version = "0.6.0", features = ["lv2-time"] }
+iterpipes = "0.2.0"
\ No newline at end of file
diff --git a/docs/metro/eg-metro-rs.lv2/manifest.ttl b/docs/metro/eg-metro-rs.lv2/manifest.ttl
new file mode 100644
index 00000000..6d7ebd38
--- /dev/null
+++ b/docs/metro/eg-metro-rs.lv2/manifest.ttl
@@ -0,0 +1,8 @@
+@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix ui:   <http://lv2plug.in/ns/extensions/ui#> .
+
+<https://github.com/RustAudio/rust-lv2/tree/master/docs/metro>
+	a lv2:Plugin ;
+	lv2:binary <libmetro.so> ;
+	rdfs:seeAlso <metro.ttl> .
diff --git a/docs/metro/eg-metro-rs.lv2/metro.ttl b/docs/metro/eg-metro-rs.lv2/metro.ttl
new file mode 100644
index 00000000..b375feba
--- /dev/null
+++ b/docs/metro/eg-metro-rs.lv2/metro.ttl
@@ -0,0 +1,29 @@
+@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix time: <http://lv2plug.in/ns/ext/time#> .
+@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+
+<https://github.com/RustAudio/rust-lv2/tree/master/docs/metro>
+a lv2:Plugin ;
+    doap:name "Example Metronome" ;
+    doap:license <http://opensource.org/licenses/isc> ;
+    lv2:project <https://github.com/RustAudio/rust-lv2> ;
+    lv2:requiredFeature urid:map , lv2:inPlaceBroken ;
+    lv2:optionalFeature lv2:hardRTCapable ;
+    lv2:port [
+# There are atom objects, which are semantically similar to Turtle files, but only use URIDs and atom types as properties. `time:Position` is a class of such objects and this input port accepts it as an event. Therefore, the host knows to deliver time and tempo information here.
+        a lv2:InputPort ,
+                atom:AtomPort ;
+            atom:bufferType atom:Sequence ;
+            atom:supports time:Position ;
+            lv2:index 0 ;
+            lv2:symbol "control" ;
+            lv2:name "Control" ;
+    ] , [
+        a lv2:AudioPort ,
+            lv2:OutputPort ;
+            lv2:index 1 ;
+            lv2:symbol "out" ;
+            lv2:name "Out" ;
+    ] .
\ No newline at end of file
diff --git a/docs/metro/src/lib.rs b/docs/metro/src/lib.rs
new file mode 100644
index 00000000..582bed0e
--- /dev/null
+++ b/docs/metro/src/lib.rs
@@ -0,0 +1,104 @@
+// Now, we put it all together:
+use iterpipes::*;
+use lv2::prelude::*;
+
+mod pipes;
+use pipes::*;
+
+// In future iterations of the plugin, these values could be parameters, but for now, the're constants:
+const ATTACK_DURATION: f64 = 0.005;
+const DECAY_DURATION: f64 = 0.075;
+const NOTE_FREQUENCY: f64 = 440.0 * 2.0;
+
+#[derive(URIDCollection)]
+struct URIDs {
+    atom: AtomURIDCollection,
+    unit: UnitURIDCollection,
+    time: TimeURIDCollection,
+}
+
+#[derive(PortCollection)]
+pub struct Ports {
+    control: InputPort<AtomPort>,
+    output: OutputPort<Audio>,
+}
+
+#[derive(FeatureCollection)]
+pub struct Features<'a> {
+    map: LV2Map<'a>,
+}
+
+// This plugin struct contains the URID collection and two pre-constructed pipes. These are later used to construct the complete pipeline.
+#[uri("https://github.com/RustAudio/rust-lv2/tree/master/docs/metro")]
+pub struct Metro {
+    urids: URIDs,
+    envelope: Connector<Enumerate<PulseGenerator>, Envelope>,
+    sampler: Connector<Counter<usize>, Sampler<f32>>,
+}
+
+impl Plugin for Metro {
+    type Ports = Ports;
+
+    type InitFeatures = Features<'static>;
+    type AudioFeatures = ();
+
+    fn new(plugin_info: &PluginInfo, features: &mut Features<'static>) -> Option<Self> {
+        let attack_len = (ATTACK_DURATION * plugin_info.sample_rate()) as usize;
+        let decay_len = (DECAY_DURATION * plugin_info.sample_rate()) as usize;
+
+        // Pre-construct the envelope pipe. Pipes can be enumerated, just like iterators, and connected.
+        let envelope = PulseGenerator::new(plugin_info.sample_rate() as f32)
+            .enumerate()
+            .connect(Envelope::new(attack_len, decay_len));
+
+        // Calculate the sample and pre-construct the sampler pipe.
+        let sample_len = (plugin_info.sample_rate() / NOTE_FREQUENCY) as usize;
+        let mut sample: Vec<f32> = Vec::with_capacity(sample_len);
+        for i in 0..sample_len {
+            sample.push(
+                (i as f64 * 2.0 * std::f64::consts::PI * NOTE_FREQUENCY / plugin_info.sample_rate())
+                    .sin() as f32,
+            );
+        }
+        let sampler = Counter::<usize>::new(0, 1).connect(Sampler::new(sample));
+
+        Some(Self {
+            urids: features.map.populate_collection()?,
+            envelope,
+            sampler,
+        })
+    }
+
+    fn activate(&mut self, _: &mut Features<'static>) {
+        self.envelope.reset();
+        self.sampler.reset();
+    }
+
+    fn run(&mut self, ports: &mut Ports, _: &mut (), _: u32) {
+        if let Some(control) = ports
+            .control
+            .read(self.urids.atom.sequence, self.urids.unit.beat)
+        {
+            // Here, the final assembly of the pipeline is done. First, the event iterator is pre-processed to only emit an index and an `UnidentifiedAtom`. Then, the event iterator is wrapped into an `EventAtomizer`, which is then connected to an `EventReader` and the envelope. The resulting pipe consumes a `()` and emits the next frame of the envelope; It's already a compact pipeline.
+            //
+            // Then, the final pipeline is constructed using some lazy pipes: The first one splits a `()` to a tuple of `()`, which is then connected to a tuple of the envelope and the pre-constructed sampler. A tuple of two pipes is also a pipe; The two pipes are processed in parallel. Then, the emitted envelope and sample frame are multiplied to one frame.
+            let control =
+                control.map(|(timestamp, event)| (timestamp.as_frames().unwrap() as usize, event));
+
+            let complete_envelope = EventAtomizer::new(control).compose()
+                >> EventReader::new(&self.urids.atom, &self.urids.time)
+                >> &mut self.envelope;
+
+            let mut pipeline = Lazy::new(|_: ()| ((), ())).compose()
+                >> (complete_envelope, &mut self.sampler)
+                >> Lazy::new(|(env, sample)| env * sample);
+
+            // Generate a frame for every frame in the output buffer. All of the processing is done by the single call to `next`!
+            for frame in ports.output.iter_mut() {
+                *frame = pipeline.next(());
+            }
+        }
+    }
+}
+
+lv2_descriptors!(Metro);
diff --git a/docs/metro/src/pipes.rs b/docs/metro/src/pipes.rs
new file mode 100644
index 00000000..f9597b40
--- /dev/null
+++ b/docs/metro/src/pipes.rs
@@ -0,0 +1,350 @@
+// We cover the individual pipes of the plugin before putting it all together:
+use iterpipes::*;
+use lv2::prelude::*;
+
+// `Sampler` is a simple sampler that plays back the contents of a pre-recorded sample. It simply returns a frame for every index it receives as an input, which means that it can also be played backward or at a different speed. The actual type of frames isn't important and therefore, this sampler is generic.
+
+pub struct Sampler<T> {
+    sample: Box<[T]>,
+}
+
+impl<T> Sampler<T> {
+    pub fn new<S>(sample: S) -> Self
+    where
+        S: Into<Box<[T]>>,
+    {
+        Self {
+            sample: sample.into(),
+        }
+    }
+}
+
+impl<T> Pipe for Sampler<T>
+where
+    T: Copy,
+{
+    type InputItem = usize;
+    type OutputItem = T;
+
+    fn next(&mut self, index: usize) -> T {
+        self.sample[index % self.sample.len()]
+    }
+}
+
+impl<T> ResetablePipe for Sampler<T>
+where
+    T: Copy,
+{
+    fn reset(&mut self) {}
+}
+
+// We try to test as much of the individual parts as possible to reduce the error cases.
+#[test]
+fn test_sampler() {
+    let sample: Vec<u8> = vec![1, 2, 3, 4];
+    let mut sampler = Sampler::new(sample);
+    for i in (0..32).chain(32..0) {
+        assert_eq!((i % 4 + 1) as u8, sampler.next(i));
+    }
+}
+
+// `Envelope` receives a pulse and an index and creates an envelope after every pulse. This envelope is multiplied with the sample output to generate the sound signal.
+
+pub struct Envelope {
+    attack_len: usize,
+    decay_len: usize,
+    impulse_index: usize,
+}
+
+impl Envelope {
+    pub fn new(attack_len: usize, decay_len: usize) -> Self {
+        Self {
+            attack_len,
+            decay_len,
+            impulse_index: std::usize::MAX,
+        }
+    }
+}
+
+impl Pipe for Envelope {
+    type InputItem = (usize, bool);
+    type OutputItem = f32;
+
+    fn next(&mut self, (index, impulse): (usize, bool)) -> f32 {
+        if impulse {
+            self.impulse_index = index;
+        }
+
+        if index < self.impulse_index {
+            0.0
+        } else if index < self.impulse_index + self.attack_len {
+            (index - self.impulse_index) as f32 / (self.attack_len) as f32
+        } else if index < self.impulse_index + self.attack_len + self.decay_len {
+            1.0 - ((index - self.impulse_index - self.attack_len) as f32 / (self.decay_len) as f32)
+        } else {
+            0.0
+        }
+    }
+}
+
+impl ResetablePipe for Envelope {
+    fn reset(&mut self) {
+        self.impulse_index = std::usize::MAX;
+    }
+}
+
+#[test]
+fn test_envelope() {
+    let mut pipe =
+        Envelope::new(4, 4).compose() >> Lazy::new(|frame: f32| (frame * 4.0).round() as u8);
+    for i in 0..32 {
+        assert_eq!(0, pipe.next((i, false)));
+    }
+    assert_eq!(0, pipe.next((32, true)));
+    assert_eq!(1, pipe.next((33, false)));
+    assert_eq!(2, pipe.next((34, false)));
+    assert_eq!(3, pipe.next((35, false)));
+    assert_eq!(4, pipe.next((36, false)));
+    assert_eq!(3, pipe.next((37, false)));
+    assert_eq!(2, pipe.next((38, false)));
+    assert_eq!(1, pipe.next((39, false)));
+    assert_eq!(0, pipe.next((40, false)));
+    for i in 41..64 {
+        assert_eq!(0, pipe.next((i, false)));
+    }
+}
+
+// The `PulseGenerator` interprets the settings of the host and creates a pulse every time a new note should be played. This pulse is a `bool` that flips from `false` to `true`.
+//
+// The host settings are updated via `PulseInput` objects, which contain new BPM and speed measures as well as the number of the current beat in the current bar for synchronization.
+//
+// Note that the `elapsed_frames` counter is only used internally to generate pulses. The index counters for the envelope and the samples are separate, which means that the audio won't stutter after a hard update.
+pub struct PulseGenerator {
+    sample_rate: f32,
+
+    beats_per_minute: f32,
+    speed_coefficient: f32,
+    frames_per_beat: usize,
+
+    elapsed_frames: usize,
+}
+
+impl PulseGenerator {
+    pub fn new(sample_rate: f32) -> Self {
+        Self {
+            sample_rate,
+
+            beats_per_minute: 120.0,
+            speed_coefficient: 0.0,
+            frames_per_beat: 0,
+
+            elapsed_frames: 0,
+        }
+    }
+}
+
+impl Pipe for PulseGenerator {
+    type InputItem = PulseInput;
+    type OutputItem = bool;
+
+    fn next(&mut self, input: PulseInput) -> bool {
+        self.elapsed_frames += 1;
+
+        let mut parameters_changed = false;
+        if let Some(new_bpm) = input.bpm_update {
+            self.beats_per_minute = new_bpm;
+            parameters_changed = true;
+        }
+        if let Some(new_speed) = input.speed_update {
+            self.speed_coefficient = new_speed;
+            parameters_changed = true;
+        }
+
+        if parameters_changed {
+            self.frames_per_beat =
+                (self.speed_coefficient * (60.0 / self.beats_per_minute) * self.sample_rate).abs()
+                    as usize;
+        }
+
+        if let Some(new_beat) = input.beat_update {
+            self.elapsed_frames = (new_beat * self.frames_per_beat as f64) as usize;
+        }
+
+        self.frames_per_beat != 0 && self.elapsed_frames % self.frames_per_beat == 0
+    }
+}
+
+impl ResetablePipe for PulseGenerator {
+    fn reset(&mut self) {
+        self.beats_per_minute = 120.0;
+        self.speed_coefficient = 0.0;
+        self.frames_per_beat = 0;
+        self.elapsed_frames = 0;
+    }
+}
+
+#[test]
+fn test_pulse_generator() {
+    let mut pipe = PulseGenerator::new(44100.0);
+    assert!(pipe.next(PulseInput {
+        beat_update: Some(0.0),
+        bpm_update: Some(120.0),
+        speed_update: Some(1.0)
+    }));
+
+    for i in 1..88100 {
+        let input = PulseInput {
+            beat_update: None,
+            bpm_update: None,
+            speed_update: None,
+        };
+        if i % 22050 == 0 {
+            assert!(pipe.next(input));
+        } else {
+            assert!(!pipe.next(input));
+        }
+    }
+}
+
+// This is the input type for the pulse generator. The `bpm_update` and `speed_update` fields tell the pulse generator of the new number of beats per second and playback speed. The `beat_update` contains the number of the current beat in the current bar and is used to synchronize the plugin with the host.
+
+#[derive(Clone, Copy, Debug)]
+pub struct PulseInput {
+    pub beat_update: Option<f64>,
+    pub bpm_update: Option<f32>,
+    pub speed_update: Option<f32>,
+}
+
+// The `EventAtomizer` wraps an iterator over events and transforms them into frames, which either contain an event or don't. This iterator will be the atom event iterator later, but for now, it's good to be generic.
+//
+// Internally, it stores the next event of the event sequence. Every time `next` is called, this counter is increased and once it hits this next event, it is yielded and the next "next event" is retrieved. This is continued as long as the sequence contains events. Once it is depleted, this pipe only emits `None`s.
+//
+// Since every frame can only contain one event and frames must be emitted chronologically, it drops every event that has the same or an earlier timestamp than a previous event.
+pub struct EventAtomizer<T, I>
+where
+    I: Iterator<Item = (usize, T)>,
+{
+    sequence: I,
+    next_event: Option<(usize, T)>,
+    index: usize,
+}
+
+impl<T, I> EventAtomizer<T, I>
+where
+    I: Iterator<Item = (usize, T)>,
+{
+    pub fn new(sequence: I) -> Self {
+        let mut instance = Self {
+            sequence,
+            next_event: None,
+            index: 0,
+        };
+        instance.retrieve_next_event();
+        instance
+    }
+
+    fn retrieve_next_event(&mut self) {
+        self.next_event = None;
+        if let Some((index, item)) = self.sequence.next() {
+            if index >= self.index {
+                self.next_event = Some((index, item));
+            }
+        }
+    }
+}
+
+impl<T, I> Pipe for EventAtomizer<T, I>
+where
+    I: Iterator<Item = (usize, T)>,
+{
+    type InputItem = ();
+    type OutputItem = Option<T>;
+
+    fn next(&mut self, _: ()) -> Option<T> {
+        match self.next_event.take() {
+            Some((event_index, event_atom)) => {
+                let event_is_due = event_index == self.index;
+                self.index += 1;
+                if event_is_due {
+                    self.retrieve_next_event();
+                    Some(event_atom)
+                } else {
+                    self.next_event = Some((event_index, event_atom));
+                    None
+                }
+            }
+            None => None,
+        }
+    }
+}
+
+#[test]
+fn test_atomizer() {
+    let events: Box<[(usize, u32)]> = Box::new([(4, 1), (10, 5)]);
+    let mut pipe = EventAtomizer::new(events.iter().cloned());
+
+    for i in 0..15 {
+        let output = pipe.next(());
+        match i {
+            4 => assert_eq!(Some(1), output),
+            10 => assert_eq!(Some(5), output),
+            _ => assert_eq!(None, output),
+        }
+    }
+}
+
+// In the final plugin, the `EventAtomizer` emits `Option<UnidentifiedAtom>`s, which might be any atom at all, and the `PulseGenerator` consumes `PulseInput`s. The `EventReader` bridges the gap between these two pipes by identifying the atom, reading it and emitting an appropriate `PulseInput`.
+//
+// This is the only pipe that isn't tested since creating a testbed for it would require too much code for this book.
+
+pub struct EventReader<'a> {
+    atom_urids: &'a AtomURIDCollection,
+    time_urids: &'a TimeURIDCollection,
+}
+
+impl<'a> EventReader<'a> {
+    pub fn new(atom_urids: &'a AtomURIDCollection, time_urids: &'a TimeURIDCollection) -> Self {
+        Self {
+            atom_urids,
+            time_urids,
+        }
+    }
+}
+
+impl<'a> Pipe for EventReader<'a> {
+    type InputItem = Option<UnidentifiedAtom<'a>>;
+    type OutputItem = PulseInput;
+
+    fn next(&mut self, atom: Option<UnidentifiedAtom>) -> PulseInput {
+        let mut updates = PulseInput {
+            beat_update: None,
+            bpm_update: None,
+            speed_update: None,
+        };
+
+        if let Some(atom) = atom {
+            if let Some((object_header, object_reader)) = atom
+                .read(self.atom_urids.object, ())
+                .or_else(|| atom.read(self.atom_urids.blank, ()))
+            {
+                if object_header.otype == self.time_urids.position_class {
+                    for (property_header, property) in object_reader {
+                        if property_header.key == self.time_urids.bar_beat {
+                            updates.beat_update = property
+                                .read(self.atom_urids.float, ())
+                                .map(|float| float as f64);
+                        }
+                        if property_header.key == self.time_urids.beats_per_minute {
+                            updates.bpm_update = property.read(self.atom_urids.float, ());
+                        }
+                        if property_header.key == self.time_urids.speed {
+                            updates.speed_update = property.read(self.atom_urids.float, ());
+                        }
+                    }
+                }
+            }
+        }
+
+        updates
+    }
+}
diff --git a/docs/midigate/Cargo.toml b/docs/midigate/Cargo.toml
new file mode 100644
index 00000000..715ee428
--- /dev/null
+++ b/docs/midigate/Cargo.toml
@@ -0,0 +1,14 @@
+# The `Cargo.toml` file is pretty similiar too. This plugin needs no extra features, but it needs
+# the `wmidi` crate, which provides the enums to handle MIDI messages. 
+[package]
+name = "midigate"
+version = "0.1.0"
+authors = ["Jan-Oliver 'Janonard' Opdenhövel <jan.opdenhoevel@protonmail.com>"]
+edition = "2018"
+
+[lib]
+crate-type = ["cdylib"]
+
+[dependencies]
+wmidi = "3.1.0"
+lv2 = "0.6.0"
\ No newline at end of file
diff --git a/docs/midigate/eg-midigate-rs.lv2/manifest.ttl b/docs/midigate/eg-midigate-rs.lv2/manifest.ttl
new file mode 100644
index 00000000..d5a2240a
--- /dev/null
+++ b/docs/midigate/eg-midigate-rs.lv2/manifest.ttl
@@ -0,0 +1,9 @@
+# The manifest.ttl file follows the same template as the previous example.
+@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix ui:   <http://lv2plug.in/ns/extensions/ui#> .
+
+<https://github.com/RustAudio/rust-lv2/tree/master/docs/midigate>
+	a lv2:Plugin ;
+	lv2:binary <libmidigate.so> ;
+	rdfs:seeAlso <midigate.ttl> .
diff --git a/docs/midigate/eg-midigate-rs.lv2/midigate.ttl b/docs/midigate/eg-midigate-rs.lv2/midigate.ttl
new file mode 100644
index 00000000..21494d31
--- /dev/null
+++ b/docs/midigate/eg-midigate-rs.lv2/midigate.ttl
@@ -0,0 +1,55 @@
+# The same set of namespace prefixes with two additions for LV2 extensions this
+# plugin uses: atom and urid.
+@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix midi: <http://lv2plug.in/ns/ext/midi#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+
+<https://github.com/RustAudio/rust-lv2/tree/master/docs/midigate>
+	a lv2:Plugin ;
+	doap:name "Example MIDI Gate (Rust Version)" ;
+	doap:license <http://opensource.org/licenses/isc> ;
+    lv2:project <https://github.com/RustAudio/rust-lv2> ;
+	lv2:requiredFeature urid:map , lv2:inPlaceBroken ;
+	lv2:optionalFeature lv2:hardRTCapable ;
+# This plugin has three ports.  There is an audio input and output as before,
+# as well as a new `AtomPort`.  An `AtomPort` buffer contains an `Atom`, which is a
+# generic container for any type of data.  In this case, we want to receive
+# MIDI events, so the (mandatory) `atom:bufferType` is `atom:Sequence`, which is
+# a series of events with time stamps.
+#
+# Events themselves are also generic and can contain any type of data, but in
+# this case we are only interested in MIDI events.  The (optional)
+# `atom:supports` property describes which event types are supported.  Though
+# not required, this information should always be given so the host knows what
+# types of event it can expect the plugin to understand.
+#
+# The (optional) `lv2:designation` of this port is `lv2:control`, which
+# indicates that this is the "main" control port where the host should send
+# events it expects to configure the plugin, in this case changing the MIDI
+# program.  This is necessary since it is possible to have several MIDI input
+# ports, though typically it is best to have one.
+	lv2:port [
+		a lv2:InputPort ,
+			atom:AtomPort ;
+		atom:bufferType atom:Sequence ;
+		atom:supports midi:MidiEvent ;
+		lv2:designation lv2:control ;
+		lv2:index 0 ;
+		lv2:symbol "control" ;
+		lv2:name "Control"
+	] , [
+		a lv2:AudioPort ,
+			lv2:InputPort ;
+		lv2:index 1 ;
+		lv2:symbol "in" ;
+		lv2:name "In"
+	] , [
+		a lv2:AudioPort ,
+			lv2:OutputPort ;
+		lv2:index 2 ;
+		lv2:symbol "out" ;
+		lv2:name "Out"
+	] .
diff --git a/docs/midigate/src/lib.rs b/docs/midigate/src/lib.rs
new file mode 100644
index 00000000..feb33897
--- /dev/null
+++ b/docs/midigate/src/lib.rs
@@ -0,0 +1,127 @@
+// Use the prelude and the `wmidi` crate.
+use lv2::prelude::*;
+use wmidi::*;
+
+#[derive(PortCollection)]
+pub struct Ports {
+    control: InputPort<AtomPort>,
+    input: InputPort<Audio>,
+    output: OutputPort<Audio>,
+}
+// Now, an additional host feature is needed. A feature is something that implements the `Feature` trait and usually wraps a certain functionality of the host; In this case mapping URIs to URIDs. The discovery and validation of features is done by the framework.
+#[derive(FeatureCollection)]
+pub struct Features<'a> {
+    map: LV2Map<'a>,
+}
+// Retrieving URIDs from the host isn't guaranteed to be real-time safe or even fast. Therefore, all URIDs that may be needed should be retrieved when the plugin is instantiated. The `URIDCollection` trait makes this easy: It provides a single method that creates an instance of itself from the mapping feature, which can also be generated using this `derive` macro.
+#[derive(URIDCollection)]
+pub struct URIDs {
+    atom: AtomURIDCollection,
+    midi: MidiURIDCollection,
+    unit: UnitURIDCollection,
+}
+
+#[uri("https://github.com/RustAudio/rust-lv2/tree/master/docs/midigate")]
+pub struct Midigate {
+    n_active_notes: u64,
+    program: u8,
+    urids: URIDs,
+}
+
+impl Midigate {
+    // A function to write a chunk of output, to be called from `run()`. If the gate is high, then the input will be passed through for this chunk, otherwise silence is written.
+    fn write_output(&mut self, ports: &mut Ports, offset: usize, mut len: usize) {
+        if ports.input.len() < offset + len {
+            len = ports.input.len() - offset;
+        }
+
+        let active = if self.program == 0 {
+            self.n_active_notes > 0
+        } else {
+            self.n_active_notes == 0
+        };
+
+        let input = &ports.input[offset..offset + len];
+        let output = &mut ports.output[offset..offset + len];
+
+        if active {
+            output.copy_from_slice(input);
+        } else {
+            for frame in output.iter_mut() {
+                *frame = 0.0;
+            }
+        }
+    }
+}
+
+impl Plugin for Midigate {
+    type Ports = Ports;
+
+    type InitFeatures = Features<'static>;
+    type AudioFeatures = ();
+
+    fn new(_plugin_info: &PluginInfo, features: &mut Features<'static>) -> Option<Self> {
+        Some(Self {
+            n_active_notes: 0,
+            program: 0,
+            urids: features.map.populate_collection()?,
+        })
+    }
+
+    // This plugin works through the cycle in chunks starting at offset zero. The `offset` represents the current time within this this cycle, so the output from 0 to `offset` has already been written.
+    //
+    // MIDI events are read in a loop. In each iteration, the number of active notes (on note on and note off) or the program (on program change) is updated, then the output is written up until the current event time. Then `offset` is updated and the next event is processed. After the loop the final chunk from the last event to the end of the cycle is emitted.
+    //
+    // There is currently no standard way to describe MIDI programs in LV2, so the host has no way of knowing that these programs exist and should be presented to the user. A future version of LV2 will address this shortcoming.
+    //
+    // This pattern of iterating over input events and writing output along the way is a common idiom for writing sample accurate output based on event input.
+    //
+    // Note that this simple example simply writes input or zero for each sample based on the gate. A serious implementation would need to envelope the transition to avoid aliasing.
+    fn run(&mut self, ports: &mut Ports, _: &mut (), _: u32) {
+        let mut offset: usize = 0;
+
+        let control_sequence = ports
+            .control
+            .read(self.urids.atom.sequence, self.urids.unit.beat)
+            .unwrap();
+
+        for (timestamp, message) in control_sequence {
+            let timestamp: usize = if let Some(timestamp) = timestamp.as_frames() {
+                timestamp as usize
+            } else {
+                continue;
+            };
+
+            let message = if let Some(message) = message.read(self.urids.midi.wmidi, ()) {
+                message
+            } else {
+                continue;
+            };
+
+            match message {
+                MidiMessage::NoteOn(_, _, _) => self.n_active_notes += 1,
+                MidiMessage::NoteOff(_, _, _) => self.n_active_notes -= 1,
+                MidiMessage::ProgramChange(_, program) => {
+                    let program: u8 = program.into();
+                    if program == 0 || program == 1 {
+                        self.program = program;
+                    }
+                }
+                _ => (),
+            }
+
+            self.write_output(ports, offset, timestamp + offset);
+            offset += timestamp;
+        }
+
+        self.write_output(ports, offset, ports.input.len() - offset);
+    }
+
+    // During it's runtime, the host might decide to deactivate the plugin. When the plugin is reactivated, the host calls this method which gives the plugin an opportunity to reset it's internal state.
+    fn activate(&mut self, _features: &mut Features<'static>) {
+        self.n_active_notes = 0;
+        self.program = 0;
+    }
+}
+
+lv2_descriptors!(Midigate);
diff --git a/docs/requirements.txt b/docs/requirements.txt
new file mode 100644
index 00000000..8143b0e3
--- /dev/null
+++ b/docs/requirements.txt
@@ -0,0 +1,3 @@
+recommonmark
+sphinx
+sphinx_rtd_theme
\ No newline at end of file
diff --git a/docs/shell.nix b/docs/shell.nix
new file mode 100644
index 00000000..c107f492
--- /dev/null
+++ b/docs/shell.nix
@@ -0,0 +1,4 @@
+{ pkgs ? import <nixpkgs> {} }:
+pkgs.mkShell {
+    buildInputs = with pkgs.python3Packages; [sphinx recommonmark sphinx_rtd_theme];
+}
\ No newline at end of file
diff --git a/install_examples.sh b/install_examples.sh
new file mode 100755
index 00000000..bde3cc70
--- /dev/null
+++ b/install_examples.sh
@@ -0,0 +1,33 @@
+#!/usr/bin/env sh
+#
+# Installation script for the example plugins.
+#
+# This script builds every plugin and installs it into `~/.lv2`, which is the standard path for user
+# plugins for Linux. The first argument of the script is interpreted as the target to build the
+# plugins for. If you leave it out, the default target of your Rust installation is used.
+export TARGET_PATH="target"
+test ! -z "$1" && export TARGET_OPT="--target $1" TARGET_PATH="target/$1"
+
+set -e -x
+
+rm -rf target/lv2
+mkdir -p target/lv2
+
+cargo build -p amp --release $TARGET_OPT
+cp -r docs/amp/eg-amp-rs.lv2 target/lv2/eg-amp-rs.lv2
+cp $TARGET_PATH/release/libamp.so target/lv2/eg-amp-rs.lv2
+
+cargo build -p midigate --release $TARGET_OPT
+cp -r docs/midigate/eg-midigate-rs.lv2 target/lv2/eg-midigate-rs.lv2
+cp $TARGET_PATH/release/libmidigate.so target/lv2/eg-midigate-rs.lv2
+
+cargo build -p fifths --release $TARGET_OPT
+cp -r docs/fifths/eg-fifths-rs.lv2 target/lv2/eg-fifths-rs.lv2
+cp $TARGET_PATH/release/libfifths.so target/lv2/eg-fifths-rs.lv2
+
+cargo build -p metro --release $TARGET_OPT
+cp -r docs/metro/eg-metro-rs.lv2 target/lv2/eg-metro-rs.lv2
+cp $TARGET_PATH/release/libmetro.so target/lv2/eg-metro-rs.lv2
+
+mkdir -p ~/.lv2
+cp -r target/lv2/* ~/.lv2
diff --git a/midi/Cargo.toml b/midi/Cargo.toml
index 9641ee93..6dd533b4 100644
--- a/midi/Cargo.toml
+++ b/midi/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "lv2-midi"
-version = "1.1.0"
+version = "1.2.0"
 authors = ["Jan-Oliver 'Janonard' Opdenhövel <jan.opdenhoevel@protonmail.com>"]
 edition = "2018"
 license = "MIT OR Apache-2.0"
@@ -14,13 +14,13 @@ travis-ci = { repository = "RustAudio/rust-lv2", branch = "master" }
 maintenance = { status = "passively-maintained" }
 
 [dependencies]
-lv2-atom = "1.0.0"
-lv2-sys = "1.0.0"
+lv2-atom = "2.0.0"
+lv2-sys = "2.0.0"
 urid = "0.1.0"
 
 [dev-dependencies]
-lv2-units = "0.1.0"
-lv2-core = "2.0.0"
+lv2-units = "0.1.3"
+lv2-core = "3.0.0"
 
 [dependencies.wmidi]
 version = "3.1.0"
diff --git a/midi/README.md b/midi/README.md
index 7793708f..76f2a24f 100644
--- a/midi/README.md
+++ b/midi/README.md
@@ -1,4 +1,4 @@
-## rust-lv2's MIDI processing library.
+## Rust-LV2's MIDI processing library.
 
 The MIDI processing library of [`rust-lv2`](https://crates.io/crates/lv2), a safe, fast, and ergonomic framework to create [LV2 plugins](http://lv2plug.in/) for audio processing, written in Rust.
 
@@ -8,10 +8,6 @@ This is a addon to [`lv2-atom`](https://crates.io/crates/lv2-atom) that adds the
 
 The original LV2 API (in the `C` programming language) is documented by ["the LV2 book"](https://lv2plug.in/book/). This book is in the process of being translated to Rust along with the development of `rust-lv2` [(link)](https://janonard.github.io/rust-lv2-book/) and describes how to properly use `rust-lv2`.
 
-## Building
-
-Since the bindings to the raw C headers are generated with bindgen, you need to have [Clang](https://clang.llvm.org/) installed on your system and, if it isn't in your system's standard path, set the environment variable `LIBCLANG_PATH` to the path of `libClang`.
-
 ## Features
 
 There are two optional features:
diff --git a/src/lib.rs b/src/lib.rs
index 91807dfa..262baae5 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -68,7 +68,7 @@
 //!
 //!     // Process a chunk of audio. The audio ports are dereferenced to slices, which the plugin
 //!     // iterates over.
-//!     fn run(&mut self, ports: &mut Ports, _features: &mut ()) {
+//!     fn run(&mut self, ports: &mut Ports, _features: &mut (), _: u32) {
 //!         let coef = if *(ports.gain) > -90.0 {
 //!             10.0_f32.powf(*(ports.gain) * 0.05)
 //!         } else {
@@ -87,7 +87,7 @@
 //! ## Documentation
 //!
 //! There are multiple valuable sources of documentation:
-//! * ["The rust-lv2 book"](https://janonard.github.io/rust-lv2-book/) describes how to use rust-lv2 in general, broad terms. It's the ideal point to get started and is updated with every new version of rust-lv2.
+//! * ["The Rust-LV2 book"](https://rustaudio.github.io/rust-lv2/) describes how to use Rust-LV2 in general, broad terms. It's the ideal point to get started and is updated with every new version of Rust-LV2.
 //! * [The API documentation](https://docs.rs/lv2).
 //! * [The LV2 specification reference](https://lv2plug.in/ns/).
 //!
@@ -150,6 +150,9 @@ pub extern crate lv2_midi;
 #[cfg(feature = "lv2-state")]
 pub extern crate lv2_state;
 
+#[cfg(feature = "lv2-sys")]
+pub extern crate lv2_sys;
+
 #[cfg(feature = "lv2-time")]
 pub extern crate lv2_time;
 
diff --git a/state/Cargo.toml b/state/Cargo.toml
index d8c5466f..7adb0f2c 100644
--- a/state/Cargo.toml
+++ b/state/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "lv2-state"
-version = "1.1.0"
+version = "2.0.0"
 authors = ["Jan-Oliver 'Janonard' Opdenhövel <jan.opdenhoevel@protonmail.com>"]
 edition = "2018"
 license = "MIT OR Apache-2.0"
@@ -14,10 +14,11 @@ travis-ci = { repository = "RustAudio/rust-lv2", branch = "master" }
 maintenance = { status = "passively-maintained" }
 
 [dependencies]
-lv2-sys = "1.0.0"
-lv2-core = "2.0.0"
-lv2-atom = "1.0.0"
+lv2-sys = "2.0.0"
+lv2-core = "3.0.0"
+lv2-atom = "2.0.0"
 urid = "0.1.0"
 
 [dev-dependencies]
-lv2-urid = "2.0.0"
\ No newline at end of file
+lv2-urid = "2.1.0"
+mktemp = "0.4.0"
\ No newline at end of file
diff --git a/state/README.md b/state/README.md
index a0bd15c2..36518968 100644
--- a/state/README.md
+++ b/state/README.md
@@ -1,14 +1,10 @@
-# rust-lv2's state handling library.
+# Rust-LV2's state handling library.
 
 A wrapper of LV2's State API which allows plugins to save and restore their state. This is a part of [`rust-lv2`](https://crates.io/crates/lv2), a safe, fast, and ergonomic framework to create [LV2 plugins](http://lv2plug.in/) for audio processing, written in Rust.
 ## Documentation
 
 The original LV2 API (in the `C` programming language) is documented by ["the LV2 book"](https://lv2plug.in/book/). This book is in the process of being translated to Rust along with the development of `rust-lv2` [(link)](https://janonard.github.io/rust-lv2-book/) and describes how to properly use `rust-lv2`.
 
-## Building
-
-Since the bindings to the raw C headers are generated with bindgen, you need to have [Clang](https://clang.llvm.org/) installed on your system and, if it isn't in your system's standard path, set the environment variable `LIBCLANG_PATH` to the path of `libClang`.
-
 ## Features
 
 There are two optional features:
diff --git a/state/src/interface.rs b/state/src/interface.rs
index f405a7a0..88e6e790 100644
--- a/state/src/interface.rs
+++ b/state/src/interface.rs
@@ -152,7 +152,7 @@ mod tests {
         }
 
         #[cfg_attr(tarpaulin, skip)]
-        fn run(&mut self, _: &mut (), _: &mut ()) {}
+        fn run(&mut self, _: &mut (), _: &mut (), _: u32) {}
     }
 
     #[derive(FeatureCollection)]
diff --git a/state/src/lib.rs b/state/src/lib.rs
index b7313cd9..a5a8db63 100644
--- a/state/src/lib.rs
+++ b/state/src/lib.rs
@@ -2,6 +2,10 @@
 //!
 //! This is a rather classic extension to LV2 plugins: There is a trait called [`State`](trait.State.html) which requires the methods [`save`](trait.State.html#tymethod.save) and [`restore`](trait.State.html#tymethiod.restore) to be implemented. These methods will be called by the host to save and restore the state of the plugin.
 //!
+//! ## Refering to files
+//!
+//! This crate also includes features to create files in a unique namespace for the plugin instance. However, these files will not persist across `save`/`restore` calls and therefore need to be safed together with the state as well. For more information, see the documentation of the [`path` module](path/index.html).
+//!
 //! ## Example usage
 //!
 //! ```
@@ -55,7 +59,7 @@
 //!         })
 //!     }
 //!
-//!     fn run(&mut self, _: &mut (), _: &mut ()) {
+//!     fn run(&mut self, _: &mut (), _: &mut (), _: u32) {
 //!         // Set the float to a different value than the previous one.
 //!         self.internal += 1.0;
 //!     }
@@ -88,6 +92,8 @@ pub use raw::*;
 mod storage;
 pub use storage::Storage;
 
+pub mod path;
+
 /// Kinds of errors that may occur in the crate.
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub enum StateErr {
@@ -107,6 +113,10 @@ pub enum StateErr {
     NoProperty,
     /// There isn't enough memory available to execute the task.
     NoSpace,
+    /// A path that's been used as a parameter is not encoded in UTF-8.
+    PathNotUTF8,
+    /// The host does not comply to the specification.
+    HostError,
 }
 
 impl StateErr {
diff --git a/state/src/path.rs b/state/src/path.rs
new file mode 100644
index 00000000..66523a02
--- /dev/null
+++ b/state/src/path.rs
@@ -0,0 +1,545 @@
+//! Host features for file path managment.
+//!
+//! There are cases where a plugin needs to store a complete file in it's state. For example, a sampler might want to store the recorded sample in a .wav file. However, chosing a valid path for this file is a delicate problem: First of all, different operating systems have different naming schemes for file paths. This means that the system has to be independent of naming schemes. Secondly, there might be multiple instances of the same plugin, other plugins, or even different hosts competing for a file path. Therefore, the system has to avoid collisions with other programs. Lastly, a path that was available when the state was saved might not be available when the state has to be restored. Therefore, the new absolute path to the file has to be retrievable.
+//!
+//! LV2 handles this problem by leaving it to the host implementors and specifying an interface for it. There are three distinct host features which are necessary to fulfill the tasks from above: [`MakePath`](struct.MakePath.html), which "makes" an absolute file path from a relative path, [`MapPath`](struct.MapPath), which maps an absolute path to/from an abstract string that can be stored as a property, and [`FreePath`](struct.FreePath.html), which frees the strings/paths created by the features above.
+//!
+//! Since all of these features need each other in order to be safe and sound, none of them can be used on their own. Instead, you use them to construct a [`PathManager`](struct.PathManager.html), which exposes all of their interfaces.
+//!
+//! The best way to understand this system is to have an example:
+//!
+//! ```
+//! use lv2_core::prelude::*;
+//! use lv2_state::*;
+//! use lv2_state::path::*;
+//! use lv2_atom::prelude::*;
+//! use lv2_urid::*;
+//! use urid::*;
+//! use std::fs::File;
+//! use std::path::Path;
+//! use std::io::{Read, Write};
+//!
+//! // First, we need to write out some boilerplate code
+//! // to define a proper plugin. There's no way around it. 😕
+//!
+//! /// The plugin we're outlining.
+//! #[uri("urn:my-plugin")]
+//! struct Sampler {
+//!     // A vector of bytes, for simplicity's sake.
+//!     // In a proper sampler, this would be a vector of floats.
+//!     sample: Vec<u8>,
+//!     urids: URIDs,
+//! }
+//!
+//! /// The features we need.
+//! #[derive(FeatureCollection)]
+//! struct Features<'a> {
+//!     makePath: MakePath<'a>,
+//!     mapPath: MapPath<'a>,
+//!     freePath: FreePath<'a>,
+//!     uridMap: LV2Map<'a>,
+//! }
+//!
+//! // A quick definition to identify the sample
+//! // path in the state property store.
+//! #[uri("urn:my-plugin:sample")]
+//! struct Sample;
+//!
+//! /// Some URIDs we need.
+//! #[derive(URIDCollection)]
+//! struct URIDs {
+//!     atom: AtomURIDCollection,
+//!     sample: URID<Sample>,
+//! }
+//!
+//! // Plugin implementation omitted...
+//! # impl Plugin for Sampler {
+//! #     type Ports = ();
+//! #     type InitFeatures = Features<'static>;
+//! #     type AudioFeatures = ();
+//! #
+//! #     fn new(_: &PluginInfo, features: &mut Features<'static>) -> Option<Self> {
+//! #         Some(Self {
+//! #             sample: Vec::new(),
+//! #             urids: features.uridMap.populate_collection()?,
+//! #         })
+//! #     }
+//! #
+//! #     fn run(&mut self, _: &mut (), _: &mut (), _: u32) {}
+//! # }
+//!
+//! impl State for Sampler {
+//!     type StateFeatures = Features<'static>;
+//!
+//!     fn save(&self, mut store: StoreHandle, features: Features) -> Result<(), StateErr> {
+//!         // Create a path manager, it manages all paths!
+//!         let mut manager = PathManager::new(
+//!             features.makePath,
+//!             features.mapPath,
+//!             features.freePath
+//!         );
+//!
+//!         // Allocate a path to store the sample to.
+//!         // The absolute path is the "real" path of the file we may write to
+//!         // and the abstract path is the path we may store in a property.
+//!         let (absolute_path, abstract_path) = manager
+//!             .allocate_path(Path::new("sample.wav"))?;
+//!
+//!         // Store the sample. This isn't the correct way to save WAVs!
+//!         let mut file = File::create(absolute_path).map_err(|_| StateErr::Unknown)?;
+//!         file.write_all(self.sample.as_ref()).map_err(|_| StateErr::Unknown)?;
+//!
+//!         // Draft a new property to store the abstract path of the sample.
+//!         {
+//!             let mut path_writer = store.draft(self.urids.sample);
+//!             let mut path_writer = path_writer
+//!                 .init(self.urids.atom.string, ())
+//!                 .map_err(|_| StateErr::Unknown)?;
+//!             path_writer.append(&*abstract_path);
+//!         }
+//!
+//!         // Commit everything!
+//!         store.commit_all()
+//!     }
+//!
+//!     fn restore(&mut self, store: RetrieveHandle, features: Features) -> Result<(), StateErr> {
+//!         // Again, create a path a path manager.
+//!         let mut manager = PathManager::new(
+//!             features.makePath,
+//!             features.mapPath,
+//!             features.freePath
+//!         );
+//!
+//!         // Retrieve the abstract path from the property store.
+//!         let abstract_path = store
+//!             .retrieve(self.urids.sample)?
+//!             .read(self.urids.atom.string, ())
+//!             .map_err(|_| StateErr::Unknown)?;
+//!
+//!         // Get the absolute path to the referenced file.
+//!         let absolute_path = manager
+//!             .deabstract_path(abstract_path)?;
+//!
+//!         // Open the file.
+//!         let mut file = File::open(absolute_path)
+//!             .map_err(|_| StateErr::Unknown)?;
+//!
+//!         // Write it to the sample.
+//!         self.sample.clear();
+//!         file.read_to_end(&mut self.sample)
+//!             .map(|_| ())
+//!             .map_err(|_| StateErr::Unknown)
+//!     }
+//! }
+//! ```
+//!
+//! # A note on availability
+//!
+//! Originally, these path handling features are also meant to be usable outside of the context of `save` and `restore`, for example to create a temporary audio file. However, the specification does not define whether the `FreePath` feature only deallocates the path string or if it deallocates the files pointed by the path too. Therefore, we can not guarantee that files and strings live outside of the scope of a trait function call and had to restrict the usage to `save` and `restore`.
+use crate::StateErr;
+use lv2_core::feature::Feature;
+use lv2_core::prelude::*;
+use lv2_sys as sys;
+use std::ffi::*;
+use std::iter::once;
+use std::marker::PhantomData;
+use std::os::raw::c_char;
+use std::path::*;
+use std::rc::Rc;
+use std::sync::Mutex;
+use urid::*;
+
+/// A host feature that allocates absolute file paths.
+///
+/// This is only useful in conjunction with the [`FreePath`](struct.FreePath.html) and [`MapPath`](struct.MapPath.html) features. Therefore, the interface of this feature is private and only exposed by a [`PathManager`](struct.PathManager.html), which is constructed from these three host features.
+///
+/// Please take a look at the [module documentation](index.html) for a usage example.
+pub struct MakePath<'a> {
+    handle: sys::LV2_State_Make_Path_Handle,
+    function: unsafe extern "C" fn(sys::LV2_State_Make_Path_Handle, *const c_char) -> *mut c_char,
+    lifetime: PhantomData<&'a mut c_void>,
+}
+
+unsafe impl<'a> UriBound for MakePath<'a> {
+    const URI: &'static [u8] = sys::LV2_STATE__makePath;
+}
+
+unsafe impl<'a> Feature for MakePath<'a> {
+    unsafe fn from_feature_ptr(feature: *const c_void, _: ThreadingClass) -> Option<Self> {
+        (feature as *const sys::LV2_State_Make_Path)
+            .as_ref()
+            .and_then(|internal| {
+                Some(Self {
+                    handle: internal.handle,
+                    function: internal.path?,
+                    lifetime: PhantomData,
+                })
+            })
+    }
+}
+
+impl<'a> MakePath<'a> {
+    fn relative_to_absolute_path(&mut self, relative_path: &Path) -> Result<&'a Path, StateErr> {
+        let relative_path: Vec<c_char> = relative_path
+            .to_str()
+            .ok_or(StateErr::PathNotUTF8)?
+            .bytes()
+            .chain(once(0))
+            .map(|b| b as c_char)
+            .collect();
+
+        let absolute_path = unsafe { (self.function)(self.handle, relative_path.as_ptr()) };
+
+        if absolute_path.is_null() {
+            return Err(StateErr::HostError);
+        }
+
+        unsafe { CStr::from_ptr(absolute_path) }
+            .to_str()
+            .map(Path::new)
+            .map_err(|_| StateErr::HostError)
+    }
+}
+
+/// A host feature that maps absolute file paths to and from abstract file paths.
+///
+/// This is only useful in conjunction with the [`FreePath`](struct.FreePath.html) and [`MakePath`](struct.MakePath.html) features. Therefore, the interface of this feature is private and only exposed by a [`PathManager`](struct.PathManager.html), which is constructed from these three host features.
+///
+/// Please take a look at the [module documentation](index.html) for a usage example.
+pub struct MapPath<'a> {
+    handle: sys::LV2_State_Map_Path_Handle,
+    abstract_path: unsafe extern "C" fn(
+        sys::LV2_State_Map_Path_Handle,
+        absolute_path: *const c_char,
+    ) -> *mut c_char,
+    absolute_path: unsafe extern "C" fn(
+        sys::LV2_State_Map_Path_Handle,
+        abstract_path: *const c_char,
+    ) -> *mut c_char,
+    lifetime: PhantomData<&'a mut c_void>,
+}
+
+unsafe impl<'a> UriBound for MapPath<'a> {
+    const URI: &'static [u8] = sys::LV2_STATE__mapPath;
+}
+
+unsafe impl<'a> Feature for MapPath<'a> {
+    unsafe fn from_feature_ptr(feature: *const c_void, _: ThreadingClass) -> Option<Self> {
+        (feature as *const sys::LV2_State_Map_Path)
+            .as_ref()
+            .and_then(|internal| {
+                Some(Self {
+                    handle: internal.handle,
+                    abstract_path: internal.abstract_path?,
+                    absolute_path: internal.absolute_path?,
+                    lifetime: PhantomData,
+                })
+            })
+    }
+}
+
+impl<'a> MapPath<'a> {
+    fn absolute_to_abstract_path(&mut self, path: &Path) -> Result<&'a str, StateErr> {
+        let path: Vec<c_char> = path
+            .to_str()
+            .ok_or(StateErr::PathNotUTF8)?
+            .bytes()
+            .chain(once(0))
+            .map(|b| b as c_char)
+            .collect();
+
+        let path = unsafe { (self.abstract_path)(self.handle, path.as_ptr()) };
+
+        if path.is_null() {
+            return Err(StateErr::HostError);
+        }
+
+        unsafe { CStr::from_ptr(path) }
+            .to_str()
+            .map_err(|_| StateErr::HostError)
+    }
+
+    fn abstract_to_absolute_path(&mut self, path: &str) -> Result<&'a Path, StateErr> {
+        let path: Vec<c_char> = path.bytes().chain(once(0)).map(|b| b as c_char).collect();
+
+        let path = unsafe { (self.absolute_path)(self.handle, path.as_ptr()) };
+
+        if path.is_null() {
+            return Err(StateErr::HostError);
+        }
+
+        unsafe { CStr::from_ptr(path) }
+            .to_str()
+            .map(Path::new)
+            .map_err(|_| StateErr::HostError)
+    }
+}
+
+/// A host feature that deallocates absolute and abstract file paths.
+///
+/// This is only useful in conjunction with the [`MapPath`](struct.MapPath.html) and [`MakePath`](struct.MakePath.html) features. Therefore, the interface of this feature is private and only exposed by a [`PathManager`](struct.PathManager.html), which is constructed from these three host features.
+///
+/// Please take a look at the [module documentation](index.html) for a usage example.
+pub struct FreePath<'a> {
+    handle: sys::LV2_State_Free_Path_Handle,
+    free_path: unsafe extern "C" fn(sys::LV2_State_Free_Path_Handle, *mut c_char),
+    lifetime: PhantomData<&'a mut c_void>,
+}
+
+unsafe impl<'a> UriBound for FreePath<'a> {
+    const URI: &'static [u8] = sys::LV2_STATE__freePath;
+}
+
+unsafe impl<'a> Feature for FreePath<'a> {
+    unsafe fn from_feature_ptr(feature: *const c_void, _: ThreadingClass) -> Option<Self> {
+        (feature as *const sys::LV2_State_Free_Path)
+            .as_ref()
+            .and_then(|internal| {
+                Some(Self {
+                    handle: internal.handle,
+                    free_path: internal.free_path?,
+                    lifetime: PhantomData,
+                })
+            })
+    }
+}
+
+impl<'a> FreePath<'a> {
+    fn free_path(&self, path: &str) {
+        unsafe { (self.free_path)(self.handle, path.as_ptr() as *mut c_char) }
+    }
+}
+
+/// A path that has been allocated by the host.
+///
+/// An instance of this struct can be used just like a [`Path`](https://doc.rust-lang.org/stable/std/path/struct.Path.html) instance.
+///
+/// This path has been allocated by the host via a [`PathManager`](struct.PathManager.html) and will be deallocated by the host when dropped. Since it contains an `Rc<Mutex<>>`, it is neither `Send` nor `Sync` and shouldn't be used outside of the scope of a [`save`](../trait.State.html#tymethod.save) or [`restore`](../trait.State.html#tymethod.restore) call.
+pub struct ManagedPath<'a> {
+    path: &'a Path,
+    free_path: Rc<Mutex<FreePath<'a>>>,
+}
+
+impl<'a> std::ops::Deref for ManagedPath<'a> {
+    type Target = Path;
+
+    fn deref(&self) -> &Path {
+        self.path
+    }
+}
+
+impl<'a> AsRef<Path> for ManagedPath<'a> {
+    fn as_ref(&self) -> &Path {
+        self.path
+    }
+}
+
+impl<'a> Drop for ManagedPath<'a> {
+    fn drop(&mut self) {
+        self.free_path
+            .lock()
+            .unwrap()
+            .free_path(self.path.to_str().unwrap())
+    }
+}
+
+/// A string that has been allocated by the host.
+///
+/// An instance of this struct can be used just like a [`str`](https://doc.rust-lang.org/stable/std/primitive.str.html) reference.
+///
+/// This string has been allocated by the host via a [`PathManager`](struct.PathManager.html) and will be deallocated by the host when dropped. Since it contains an `Rc<Mutex<>>`, it is neither `Send` nor `Sync` and shouldn't be used outside of the scope of a [`save`](../trait.State.html#tymethod.save) or [`restore`](../trait.State.html#tymethod.restore) call.
+pub struct ManagedStr<'a> {
+    str: &'a str,
+    free_path: Rc<Mutex<FreePath<'a>>>,
+}
+
+impl<'a> std::ops::Deref for ManagedStr<'a> {
+    type Target = str;
+
+    fn deref(&self) -> &str {
+        self.str
+    }
+}
+
+impl<'a> Drop for ManagedStr<'a> {
+    fn drop(&mut self) {
+        self.free_path.lock().unwrap().free_path(self.str)
+    }
+}
+
+impl<'a> AsRef<str> for ManagedStr<'a> {
+    fn as_ref(&self) -> &str {
+        self.str
+    }
+}
+
+/// A safe interface to the path handling features.
+///
+/// This struct is constructed from the three path handling features, [`MakePath`](struct.MakePath.html), [`MapPath`](struct.MapPath.html), and [`FreePath`](struct.FreePath.html), and exposes them as one safe interface.
+///
+/// Please take a look at the [module documentation](index.html) for a usage example.
+pub struct PathManager<'a> {
+    make: MakePath<'a>,
+    map: MapPath<'a>,
+    free: Rc<Mutex<FreePath<'a>>>,
+}
+
+impl<'a> PathManager<'a> {
+    /// Create a new path manager from the three path handling features.
+    pub fn new(make: MakePath<'a>, map: MapPath<'a>, free: FreePath<'a>) -> Self {
+        Self {
+            make,
+            map,
+            free: Rc::new(Mutex::new(free)),
+        }
+    }
+
+    /// Allocate a new path.
+    ///
+    /// This function maps the given relative file path to an absolute file path as well as an abstract file path. The absolute file path can be used to access the new file and the abstract file path is used to reference it in the state of the plugin. Storing the absolute file path in the plugin state will not work since it might have changed when the state is restored.
+    ///
+    /// The relative file path will be the suffix of the absolute file path and will be contained in a namespace unique to the plugin instance. This means that allocations of the same relative path by different plugin instances will not collide. Apart from that, you can not make any other assumptions about the absolute and abstract file paths.
+    ///
+    /// An abstract file path that has been read from the plugin state can be mapped back to an absolute file path with the [`deabstract_path`](#method.deabstract_path) method.
+    pub fn allocate_path(
+        &mut self,
+        relative_path: &Path,
+    ) -> Result<(ManagedPath<'a>, ManagedStr<'a>), StateErr> {
+        let absolute_path = self
+            .make
+            .relative_to_absolute_path(relative_path)
+            .map(|path| ManagedPath {
+                path,
+                free_path: self.free.clone(),
+            })?;
+
+        let abstract_path = self
+            .map
+            .absolute_to_abstract_path(absolute_path.as_ref())
+            .map(|str| ManagedStr {
+                str,
+                free_path: self.free.clone(),
+            })?;
+
+        Ok((absolute_path, abstract_path))
+    }
+
+    /// Map an abstract file path back to an absolute one.
+    ///
+    /// After reading an abstract file path from the state, you have to map it back to an absolute file path in order to read the file. This is what this method does.
+    pub fn deabstract_path(&mut self, path: &str) -> Result<ManagedPath<'a>, StateErr> {
+        self.map
+            .abstract_to_absolute_path(path)
+            .map(|path| ManagedPath {
+                path,
+                free_path: self.free.clone(),
+            })
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::path::*;
+
+    unsafe extern "C" fn make_path_impl(
+        temp_dir: sys::LV2_State_Make_Path_Handle,
+        relative_path: *const c_char,
+    ) -> *mut c_char {
+        let relative_path = match CStr::from_ptr(relative_path).to_str() {
+            Ok(path) => path,
+            _ => return std::ptr::null_mut(),
+        };
+
+        let temp_dir = temp_dir as *const mktemp::Temp;
+        let mut absolute_path = (*temp_dir).as_path().to_path_buf();
+        absolute_path.push(relative_path);
+
+        CString::new(absolute_path.to_str().unwrap())
+            .map(CString::into_raw)
+            .unwrap_or(std::ptr::null_mut())
+    }
+
+    unsafe extern "C" fn abstract_path_impl(
+        temp_dir: sys::LV2_State_Map_Path_Handle,
+        absolute_path: *const c_char,
+    ) -> *mut c_char {
+        let absolute_path = match CStr::from_ptr(absolute_path).to_str() {
+            Ok(path) => Path::new(path),
+            _ => return std::ptr::null_mut(),
+        };
+
+        let temp_dir = temp_dir as *const mktemp::Temp;
+        let temp_dir = (*temp_dir).as_path();
+        let abstract_path = absolute_path.strip_prefix(temp_dir).unwrap();
+
+        CString::new(abstract_path.to_str().unwrap())
+            .map(CString::into_raw)
+            .unwrap_or(std::ptr::null_mut())
+    }
+
+    unsafe extern "C" fn free_path_impl(
+        free_counter: sys::LV2_State_Free_Path_Handle,
+        path: *mut c_char,
+    ) {
+        *(free_counter as *mut u32).as_mut().unwrap() += 1;
+        CString::from_raw(path);
+    }
+
+    #[test]
+    fn test_path() {
+        let temp_dir = mktemp::Temp::new_dir().unwrap();
+
+        let make_path_feature = sys::LV2_State_Make_Path {
+            handle: &temp_dir as *const _ as *mut c_void,
+            path: Some(make_path_impl),
+        };
+        let make_path = unsafe {
+            MakePath::from_feature_ptr(
+                &make_path_feature as *const _ as *const c_void,
+                ThreadingClass::Other,
+            )
+        }
+        .unwrap();
+
+        let map_path_feature = sys::LV2_State_Map_Path {
+            handle: &temp_dir as *const _ as *mut c_void,
+            abstract_path: Some(abstract_path_impl),
+            absolute_path: Some(make_path_impl),
+        };
+        let map_path = unsafe {
+            MapPath::from_feature_ptr(
+                &map_path_feature as *const _ as *const c_void,
+                ThreadingClass::Other,
+            )
+        }
+        .unwrap();
+
+        let mut free_counter: u32 = 0;
+        let free_path_feature = sys::LV2_State_Free_Path {
+            handle: &mut free_counter as *mut _ as *mut c_void,
+            free_path: Some(free_path_impl),
+        };
+        let free_path = unsafe {
+            FreePath::from_feature_ptr(
+                &free_path_feature as *const _ as *const c_void,
+                ThreadingClass::Other,
+            )
+        }
+        .unwrap();
+
+        let mut manager = PathManager::new(make_path, map_path, free_path);
+        let relative_path = Path::new("sample.wav");
+        let ref_absolute_path: PathBuf = [temp_dir.as_path(), relative_path].iter().collect();
+
+        {
+            let (absolute_path, abstract_path) = manager.allocate_path(relative_path).unwrap();
+            assert_eq!(ref_absolute_path, &*absolute_path);
+            assert_eq!(relative_path.to_str().unwrap(), &*abstract_path);
+
+            let absolute_path = manager.deabstract_path(&abstract_path).unwrap();
+            assert_eq!(ref_absolute_path, &*absolute_path);
+        }
+
+        assert_eq!(free_counter, 3);
+    }
+}
diff --git a/state/src/raw.rs b/state/src/raw.rs
index 4ea63118..ea0abc56 100644
--- a/state/src/raw.rs
+++ b/state/src/raw.rs
@@ -34,19 +34,22 @@ impl<'a> StoreHandle<'a> {
     /// This will return a new handle to create a property. Once the property is completely written, you can commit it by calling [`commit`](#method.commit) or [`commit_all`](#method.commit_all). Then, and only then, it will be saved by the host.
     ///
     /// If you began to write a property and don't want the written things to be stored, you can discard it with [`discard`](#method.discard) or [`discard_all`](#method.discard_all).
-    pub fn draft(&mut self, property_key: URID) -> StatePropertyWriter {
+    pub fn draft<K: ?Sized>(&mut self, property_key: URID<K>) -> StatePropertyWriter {
+        let property_key = property_key.into_general();
         self.properties
-            .insert(property_key, SpaceElement::default());
+            .insert(property_key.into_general(), SpaceElement::default());
         StatePropertyWriter::new(SpaceHead::new(
-            self.properties.get_mut(&property_key).unwrap(),
+            self.properties
+                .get_mut(&property_key.into_general())
+                .unwrap(),
         ))
     }
 
     /// Internal helper function to store a property.
-    pub fn commit_pair(
+    pub fn commit_pair<K: ?Sized>(
         store_fn: sys::LV2_State_Store_Function,
         handle: sys::LV2_State_Handle,
-        key: URID,
+        key: URID<K>,
         space: SpaceElement,
     ) -> Result<(), StateErr> {
         let store_fn = store_fn.ok_or(StateErr::BadCallback)?;
@@ -83,7 +86,8 @@ impl<'a> StoreHandle<'a> {
     /// Commit one specific property.
     ///
     /// This method returns `None` if the requested property was not marked for commit, `Some(Ok(()))` if the property was stored and `Some(Err(_))` if an error occured while storing the property.
-    pub fn commit(&mut self, key: URID) -> Option<Result<(), StateErr>> {
+    pub fn commit<K: ?Sized>(&mut self, key: URID<K>) -> Option<Result<(), StateErr>> {
+        let key = key.into_general();
         let space = self.properties.remove(&key)?;
         Some(Self::commit_pair(self.store_fn, self.handle, key, space))
     }
@@ -96,8 +100,8 @@ impl<'a> StoreHandle<'a> {
     /// Discard a drafted property.
     ///
     /// If no property with the given key was drafted before, this is a no-op.
-    pub fn discard(&mut self, key: URID) {
-        self.properties.remove(&key);
+    pub fn discard<K: ?Sized>(&mut self, key: URID<K>) {
+        self.properties.remove(&key.into_general());
     }
 }
 
@@ -158,7 +162,7 @@ impl<'a> RetrieveHandle<'a> {
     /// Try to retrieve a property from the host.
     ///
     /// This method calls the internal retrieve callback with the given URID. If there's no property with the given URID, `Err(StateErr::NoProperty)` is returned. Otherwise, a reading handle is returned that contains the type and the data of the property and can interpret it as an atom.
-    pub fn retrieve(&self, key: URID) -> Result<StatePropertyReader, StateErr> {
+    pub fn retrieve<K: ?Sized>(&self, key: URID<K>) -> Result<StatePropertyReader, StateErr> {
         let mut size: usize = 0;
         let mut type_: u32 = 0;
         let property_ptr: *const std::ffi::c_void = unsafe {
@@ -192,8 +196,11 @@ pub struct StatePropertyReader<'a> {
 
 impl<'a> StatePropertyReader<'a> {
     /// Create a new reading handle with the given type and data.
-    pub fn new(type_: URID, body: Space<'a>) -> Self {
-        Self { type_, body }
+    pub fn new<T: ?Sized>(type_: URID<T>, body: Space<'a>) -> Self {
+        Self {
+            type_: type_.into_general(),
+            body,
+        }
     }
 
     /// Return the type of the property.
diff --git a/state/src/storage.rs b/state/src/storage.rs
index f7c82426..b96e1781 100644
--- a/state/src/storage.rs
+++ b/state/src/storage.rs
@@ -23,8 +23,9 @@ impl Default for Storage {
 
 impl Storage {
     /// Store a property.
-    pub fn store(&mut self, key: URID, type_: URID, value: &[u8]) {
-        self.items.insert(key, (type_, value.to_owned()));
+    pub fn store<K: ?Sized, T: ?Sized>(&mut self, key: URID<K>, type_: URID<T>, value: &[u8]) {
+        self.items
+            .insert(key.into_general(), (type_.into_general(), value.to_owned()));
     }
 
     /// External version of [`store`](#method.store).
@@ -60,9 +61,9 @@ impl Storage {
     /// Try to retrieve a property.
     ///
     /// If the property doesn't exist, `None` is returned.
-    pub fn retrieve(&self, key: URID) -> Option<(URID, &[u8])> {
+    pub fn retrieve<K: ?Sized>(&self, key: URID<K>) -> Option<(URID, &[u8])> {
         self.items
-            .get(&key)
+            .get(&key.into_general())
             .map(|(urid, data)| (*urid, data.as_ref()))
     }
 
diff --git a/state/tests/integration.rs b/state/tests/integration.rs
index 1effbea8..b34f11dc 100644
--- a/state/tests/integration.rs
+++ b/state/tests/integration.rs
@@ -36,7 +36,7 @@ impl Plugin for Stateful {
         })
     }
 
-    fn run(&mut self, _: &mut (), _: &mut ()) {
+    fn run(&mut self, _: &mut (), _: &mut (), _: u32) {
         self.internal = 17.0;
         self.audio.extend((0..32).map(|f| f as f32));
     }
@@ -118,7 +118,7 @@ fn test_save_n_restore() {
 
     let mut first_plugin = create_plugin(mapper.as_mut());
 
-    first_plugin.run(&mut (), &mut ());
+    first_plugin.run(&mut (), &mut (), 32);
 
     assert_eq!(17.0, first_plugin.internal);
     assert_eq!(32, first_plugin.audio.len());
diff --git a/sys/Cargo.toml b/sys/Cargo.toml
index 32a2eee0..6aa3bfb7 100644
--- a/sys/Cargo.toml
+++ b/sys/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "lv2-sys"
-version = "1.1.0"
+version = "2.0.0"
 authors = ["Jan-Oliver 'Janonard' Opdenhövel <jan.opdenhoevel@protonmail.com>"]
 edition = "2018"
 license = "MIT OR Apache-2.0"
@@ -9,9 +9,8 @@ description = "rust-lv2's C header bindings"
 readme = "README.md"
 repository = "https://github.com/RustAudio/rust-lv2"
 
+exclude = ["lv2", "tool"]
+
 [badges]
 travis-ci = { repository = "RustAudio/rust-lv2", branch = "master" }
-maintenance = { status = "passively-maintained" }
-
-[build-dependencies]
-bindgen = "0.53.1"
+maintenance = { status = "passively-maintained" }
\ No newline at end of file
diff --git a/sys/README.md b/sys/README.md
index 04d99bde..9a8c9de8 100644
--- a/sys/README.md
+++ b/sys/README.md
@@ -1,10 +1,6 @@
-# rust-lv2's C header bindings.
+# Rust-LV2's C header bindings.
 
-Bindings to the official [LV2](https://lv2plug.in/) API headers, used by [`rust-lv2`](https://crates.io/crates/lv2), a safe, fast, and ergonomic framework to create [LV2 plugins](http://lv2plug.in/) for audio processing, written in Rust.
-
-## Building
-
-Since the bindings to the raw C headers are generated with bindgen, you need to have [Clang](https://clang.llvm.org/) installed on your system and, if it isn't in your system's standard path, set the environment variable `LIBCLANG_PATH` to the path of `libClang`.
+Bindings to the official [LV2](https://lv2plug.in/) API headers, used by [`rust-lv2`](https://crates.io/crates/lv2), a safe, fast, and ergonomic framework to create [LV2 plugins](http://lv2plug.in/) for audio processing, written in Rust. The crate uses the version 1.18.0 of the specification, as pulled from the [project's website](https://lv2plug.in/lv2-1-18-0.html).
 
 ## License
 
diff --git a/sys/build.rs b/sys/build.rs
deleted file mode 100644
index d19fa6ec..00000000
--- a/sys/build.rs
+++ /dev/null
@@ -1,53 +0,0 @@
-extern crate bindgen;
-
-use std::env;
-use std::fs;
-use std::path::PathBuf;
-
-fn main() {
-    let mut bindings = bindgen::Builder::default().size_t_is_usize(true);
-
-    let mut source_dir = PathBuf::new();
-    source_dir.push(env::var("CARGO_MANIFEST_DIR").unwrap());
-
-    // Adding the crate to the include path of clang.
-    // Otherwise, included headers can not be found.
-    bindings = bindings.clang_arg(format!("-I{}", source_dir.to_str().unwrap()));
-
-    source_dir.push("lv2");
-
-    for entry in fs::read_dir(source_dir).unwrap() {
-        let spec_dir = if let Ok(spec_dir) = entry {
-            spec_dir.path()
-        } else {
-            continue;
-        };
-
-        for entry in fs::read_dir(spec_dir).unwrap() {
-            let entry = match entry {
-                Ok(entry) => entry.path(),
-                _ => continue,
-            };
-
-            let extension = match entry.extension() {
-                Some(extension) => extension,
-                None => continue,
-            };
-
-            if extension == "h" {
-                bindings = bindings.header(entry.to_str().unwrap());
-            }
-        }
-    }
-
-    bindings = bindings.bitfield_enum("LV2_State_Flags");
-
-    // Generating the bindings.
-    let bindings = bindings.generate().expect("Unable to generate bindings");
-
-    // Writing the bindings to a file.
-    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
-    bindings
-        .write_to_file(out_path.join("bindings.rs"))
-        .expect("Couldn't write bindings!");
-}
diff --git a/sys/lv2/atom/NEWS b/sys/lv2/atom/NEWS
deleted file mode 100644
index 65ca9316..00000000
--- a/sys/lv2/atom/NEWS
+++ /dev/null
@@ -1,55 +0,0 @@
-atom (2.2) stable;
-
-  * Add lv2_atom_object_get_typed() for easy type-safe access to object properties.
-
- -- None <None>  Sun, 03 Feb 2019 00:00:00 +0000
-
-atom (2.0) stable;
-
-  * Deprecate Blank and Resource in favour of just Object.
-  * Add lv2_atom_forge_key() for terser object writing.
-  * Add lv2_atom_sequence_clear() and lv2_atom_sequence_append_event() helper
-    functions.
-  * Add lv2_atom_forge_is_object_type() and lv2_atom_forge_is_blank() to ease
-    backwards compatibility.
-
- -- None <None>  Fri, 08 Aug 2014 00:00:00 +0000
-
-atom (1.8) stable;
-
-  * Make lv2_atom_*_is_end() arguments const.
-
- -- None <None>  Sat, 04 Jan 2014 00:00:00 +0000
-
-atom (1.6) stable;
-
-  * Fix crash in forge.h when pushing atoms to a full buffer.
-
- -- None <None>  Sun, 26 May 2013 00:00:00 +0000
-
-atom (1.4) stable;
-
-  * Improve atom documentation.
-  * Fix lv2_atom_sequence_end().
-  * Remove atom:stringType in favour of owl:onDatatype so generic tools can
-    understand and validate atom literals.
-
- -- None <None>  Sun, 27 Jan 2013 00:00:00 +0000
-
-atom (1.2) stable;
-
-  * Use consistent label style.
-  * Fix lv2_atom_object_next() on 32-bit platforms.
-  * Add lv2_atom_object_body_get().
-  * Add LV2_ATOM_CONTENTS_CONST and LV2_ATOM_BODY_CONST.
-  * Fix outdated documentation in forge.h.
-  * Fix implicit conversions in forge.h that are invalid in C++11.
-
- -- None <None>  Sun, 14 Oct 2012 00:00:00 +0000
-
-atom (1.0) stable;
-
-  * Initial release.
-
- -- None <None>  Tue, 17 Apr 2012 00:00:00 +0000
-
diff --git a/sys/lv2/atom/atom-test-utils.c b/sys/lv2/atom/atom-test-utils.c
new file mode 100644
index 00000000..057dada9
--- /dev/null
+++ b/sys/lv2/atom/atom-test-utils.c
@@ -0,0 +1,71 @@
+/*
+  Copyright 2012-2018 David Robillard <http://drobilla.net>
+
+  Permission to use, copy, modify, and/or distribute this software for any
+  purpose with or without fee is hereby granted, provided that the above
+  copyright notice and this permission notice appear in all copies.
+
+  THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#include "lv2/atom/atom.h"
+#include "lv2/atom/forge.h"
+#include "lv2/atom/util.h"
+#include "lv2/urid/urid.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+char**   uris   = NULL;
+uint32_t n_uris = 0;
+
+static char*
+copy_string(const char* str)
+{
+	const size_t len = strlen(str);
+	char*        dup = (char*)malloc(len + 1);
+	memcpy(dup, str, len + 1);
+	return dup;
+}
+
+static LV2_URID
+urid_map(LV2_URID_Map_Handle handle, const char* uri)
+{
+	for (uint32_t i = 0; i < n_uris; ++i) {
+		if (!strcmp(uris[i], uri)) {
+			return i + 1;
+		}
+	}
+
+	uris = (char**)realloc(uris, ++n_uris * sizeof(char*));
+	uris[n_uris - 1] = copy_string(uri);
+	return n_uris;
+}
+
+static void
+free_urid_map(void)
+{
+	for (uint32_t i = 0; i < n_uris; ++i) {
+		free(uris[i]);
+	}
+
+	free(uris);
+}
+
+static int
+test_fail(const char* fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+	fprintf(stderr, "error: ");
+	vfprintf(stderr, fmt, args);
+	va_end(args);
+	return 1;
+}
diff --git a/sys/lv2/atom/atom-test.c b/sys/lv2/atom/atom-test.c
index 63a2bfec..5189d9dc 100644
--- a/sys/lv2/atom/atom-test.c
+++ b/sys/lv2/atom/atom-test.c
@@ -14,54 +14,14 @@
   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
 
+#include "lv2/atom/atom-test-utils.c"
 #include "lv2/atom/atom.h"
 #include "lv2/atom/forge.h"
 #include "lv2/atom/util.h"
 #include "lv2/urid/urid.h"
 
-#include <stdarg.h>
-#include <stdbool.h>
 #include <stdint.h>
-#include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
-
-char**   uris   = NULL;
-uint32_t n_uris = 0;
-
-static char*
-copy_string(const char* str)
-{
-	const size_t len = strlen(str);
-	char*        dup = (char*)malloc(len + 1);
-	memcpy(dup, str, len + 1);
-	return dup;
-}
-
-static LV2_URID
-urid_map(LV2_URID_Map_Handle handle, const char* uri)
-{
-	for (uint32_t i = 0; i < n_uris; ++i) {
-		if (!strcmp(uris[i], uri)) {
-			return i + 1;
-		}
-	}
-
-	uris = (char**)realloc(uris, ++n_uris * sizeof(char*));
-	uris[n_uris - 1] = copy_string(uri);
-	return n_uris;
-}
-
-static int
-test_fail(const char* fmt, ...)
-{
-	va_list args;
-	va_start(args, fmt);
-	fprintf(stderr, "error: ");
-	vfprintf(stderr, fmt, args);
-	va_end(args);
-	return 1;
-}
 
 int
 main(void)
@@ -397,5 +357,7 @@ main(void)
 		                                0);
 	}
 
+	free_urid_map();
+
 	return 0;
 }
diff --git a/sys/lv2/atom/atom.h b/sys/lv2/atom/atom.h
index dd332ce3..8c0f30af 100644
--- a/sys/lv2/atom/atom.h
+++ b/sys/lv2/atom/atom.h
@@ -16,6 +16,7 @@
 
 /**
    @defgroup atom Atom
+   @ingroup lv2
 
    A generic value container and several data types, see
    <http://lv2plug.in/ns/ext/atom> for details.
@@ -79,7 +80,7 @@ typedef char lv2_atom_assert_double_fits_in_64_bits[
 /**
    Return a pointer to the contents of an Atom.  The "contents" of an atom
    is the data past the complete type-specific header.
-   @param type The type of the atom, e.g. LV2_Atom_String.
+   @param type The type of the atom, for example LV2_Atom_String.
    @param atom A variable-sized atom.
 */
 #define LV2_ATOM_CONTENTS(type, atom) \
@@ -179,7 +180,7 @@ typedef struct {
 	LV2_Atom_Vector_Body body;  /**< Body. */
 } LV2_Atom_Vector;
 
-/** The body of an atom:Property (e.g. in an atom:Object). */
+/** The body of an atom:Property (typically in an atom:Object). */
 typedef struct {
 	uint32_t key;      /**< Key (predicate) (mapped URI). */
 	uint32_t context;  /**< Context URID (may be, and generally is, 0). */
@@ -225,7 +226,7 @@ typedef struct {
    LV2_Descriptor::run(), the default stamp type is audio frames.
 
    The contents of a sequence is a series of LV2_Atom_Event, each aligned
-   to 64-bits, e.g.:
+   to 64-bits, for example:
    <pre>
    | Event 1 (size 6)                              | Event 2
    |       |       |       |       |       |       |       |       |
diff --git a/sys/lv2/atom/atom.meta.ttl b/sys/lv2/atom/atom.meta.ttl
new file mode 100644
index 00000000..7b04180b
--- /dev/null
+++ b/sys/lv2/atom/atom.meta.ttl
@@ -0,0 +1,542 @@
+@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/atom>
+	a doap:Project ;
+	doap:name "LV2 Atom" ;
+	doap:shortdesc "A generic value container and several data types." ;
+	doap:license <http://opensource.org/licenses/isc> ;
+	doap:created "2007-00-00" ;
+	doap:developer <http://drobilla.net/drobilla#me> ;
+	doap:release [
+		doap:revision "2.2" ;
+		doap:created "2019-02-03" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.16.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add lv2_atom_object_get_typed() for easy type-safe access to object properties."
+			]
+		]
+	] , [
+		doap:revision "2.0" ;
+		doap:created "2014-08-08" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.10.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Deprecate Blank and Resource in favour of just Object."
+			] , [
+				rdfs:label "Add lv2_atom_forge_is_object_type() and lv2_atom_forge_is_blank() to ease backwards compatibility."
+			] , [
+				rdfs:label "Add lv2_atom_forge_key() for terser object writing."
+			] , [
+				rdfs:label "Add lv2_atom_sequence_clear() and lv2_atom_sequence_append_event() helper functions."
+			]
+		]
+	] , [
+		doap:revision "1.8" ;
+		doap:created "2014-01-04" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.8.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Make lv2_atom_*_is_end() arguments const."
+			]
+		]
+	] , [
+		doap:revision "1.6" ;
+		doap:created "2013-05-26" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.6.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Fix crash in forge.h when pushing atoms to a full buffer."
+			]
+		]
+	] , [
+		doap:revision "1.4" ;
+		doap:created "2013-01-27" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.4.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Fix lv2_atom_sequence_end()."
+			] , [
+				rdfs:label "Remove atom:stringType in favour of owl:onDatatype so generic tools can understand and validate atom literals."
+			] , [
+				rdfs:label "Improve atom documentation."
+			]
+		]
+	] , [
+		doap:revision "1.2" ;
+		doap:created "2012-10-14" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Fix implicit conversions in forge.h that are invalid in C++11."
+			] , [
+				rdfs:label "Fix lv2_atom_object_next() on 32-bit platforms."
+			] , [
+				rdfs:label "Add lv2_atom_object_body_get()."
+			] , [
+				rdfs:label "Fix outdated documentation in forge.h."
+			] , [
+				rdfs:label "Use consistent label style."
+			] , [
+				rdfs:label "Add LV2_ATOM_CONTENTS_CONST and LV2_ATOM_BODY_CONST."
+			]
+		]
+	] , [
+		doap:revision "1.0" ;
+		doap:created "2012-04-17" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Initial release."
+			]
+		]
+	] ;
+	lv2:documentation """
+
+An atom:Atom is a simple generic data container for holding any type of Plain
+Old Data (POD).  An Atom can contain simple primitive types like integers,
+floating point numbers, and strings; as well as structured data like lists and
+dictionary-like <q>Objects</q>.  Since Atoms are POD, they can be easily copied
+(for example, with `memcpy()`) anywhere and are suitable for use in real-time
+code.
+
+Every atom starts with an LV2_Atom header, followed by the contents.  This
+allows code to process atoms without requiring special code for every type of
+data.  For example, plugins that mutually understand a type can be used
+together in a host that does not understand that type, because the host is only
+required to copy atoms, not interpret their contents.  Similarly, plugins (such
+as routers, delays, or data structures) can meaningfully process atoms of a
+type unknown to them.
+
+Atoms should be used anywhere values of various types must be stored or
+transmitted.  An atom:AtomPort can be used to transmit atoms via ports.  An
+atom:AtomPort that contains a atom:Sequence can be used for sample accurate
+communication of events, such as MIDI.
+
+### Serialisation
+
+Each Atom type defines a binary format for use at runtime, but also a
+serialisation that is natural to express in Turtle format.  Thus, this
+specification defines a powerful real-time appropriate data model, as well as a
+portable way to serialise any data in that model.  This is particularly useful
+for inter-process communication, saving/restoring state, and describing values
+in plugin data files.
+
+### Custom Atom Types
+
+While it is possible to define new Atom types for any binary format, the
+standard types defined here are powerful enough to describe almost anything.
+Implementations SHOULD build structures out of the types provided here, rather
+than define new binary formats (for example, using atom:Object rather than a
+new C `struct` type).  Host and tool implementations have support for
+serialising all standard types, so new binary formats are an implementation
+burden which harms interoperabilty.  In particular, plugins SHOULD NOT expect
+UI communication or state saving with custom binary types to work.  In general,
+new Atom types should only be defined where absolutely necessary due to
+performance reasons and serialisation is not a concern.
+
+"""^^lv2:Markdown .
+
+atom:Atom
+	lv2:documentation """
+
+An LV2_Atom has a 32-bit `size` and `type`, followed by a body of `size` bytes.
+Atoms MUST be 64-bit aligned.
+
+All concrete Atom types (subclasses of this class) MUST define a precise binary
+layout for their body.
+
+The `type` field is the URI of an Atom type mapped to an integer.
+Implementations SHOULD gracefully pass through, or ignore, atoms with unknown
+types.
+
+All atoms are POD by definition except references, which as a special case have
+`type` 0.  An Atom MUST NOT contain a Reference.  It is safe to copy any
+non-reference Atom with a simple `memcpy`, even if the implementation does not
+understand `type`.  Though this extension reserves the type 0 for references,
+the details of reference handling are currently unspecified.  A future revision
+of this extension, or a different extension, may define how to use non-POD data
+and references.  Implementations MUST NOT send references to another
+implementation unless the receiver is explicitly known to support references
+(e.g. by supporting a feature).
+
+The special case of a null atom with both `type` and `size` 0 is not considered
+a reference.
+
+"""^^lv2:Markdown .
+
+atom:Chunk
+	lv2:documentation """
+
+This type is used to indicate a certain amount of space is available.  For
+example, output ports with a variably sized type are connected to a Chunk so
+the plugin knows the size of the buffer available for writing.
+
+The use of a Chunk should be constrained to a local scope, since
+interpreting it is impossible without context.  However, if serialised to RDF,
+a Chunk may be represented directly as an xsd:base64Binary string, for example:
+
+    :::turtle
+    [] eg:someChunk "vu/erQ=="^^xsd:base64Binary .
+
+"""^^lv2:Markdown .
+
+atom:String
+	lv2:documentation """
+
+The body of an LV2_Atom_String is a C string in UTF-8 encoding, i.e. an array
+of bytes (`uint8_t`) terminated with a NULL byte (`'\\0'`).
+
+This type is for free-form strings, but SHOULD NOT be used for typed data or
+text in any language.  Use atom:Literal unless translating the string does not
+make sense and the string has no meaningful datatype.
+
+"""^^lv2:Markdown .
+
+atom:Literal
+	lv2:documentation """
+
+This type is compatible with rdfs:Literal and is capable of expressing a
+string in any language or a value of any type.  A Literal has a
+`datatype` and `lang` followed by string data in UTF-8
+encoding.  The length of the string data in bytes is `size -
+sizeof(LV2_Atom_Literal)`, including the terminating NULL character.  The
+`lang` field SHOULD be a URI of the form
+&lt;http://lexvo.org/id/iso639-3/LANG&gt; or
+&lt;http://lexvo.org/id/iso639-1/LANG&gt; where LANG is a 3-character ISO 693-3
+language code, or a 2-character ISO 693-1 language code, respectively.
+
+A Literal may have a `datatype` or a `lang`, but never both.
+
+For example, a Literal can be <q>Hello</q> in English:
+
+    :::c
+    void set_to_hello_in_english(LV2_Atom_Literal* lit) {
+         lit->atom.type     = map(expand("atom:Literal"));
+         lit->atom.size     = 14;
+         lit->body.datatype = 0;
+         lit->body.lang     = map("http://lexvo.org/id/iso639-1/en");
+         memcpy(LV2_ATOM_CONTENTS(LV2_Atom_Literal, lit),
+                "Hello",
+                sizeof("Hello"));  // Assumes enough space
+    }
+
+or a Turtle string:
+
+    :::c
+    void set_to_turtle_string(LV2_Atom_Literal* lit, const char* ttl) {
+         lit->atom.type     = map(expand("atom:Literal"));
+         lit->atom.size     = 64;
+         lit->body.datatype = map("http://www.w3.org/2008/turtle#turtle");
+         lit->body.lang     = 0;
+         memcpy(LV2_ATOM_CONTENTS(LV2_Atom_Literal, lit),
+                ttl,
+                strlen(ttl) + 1);  // Assumes enough space
+    }
+
+"""^^lv2:Markdown .
+
+atom:Path
+	lv2:documentation """
+
+A Path is a URI reference with only a path component: no scheme, authority,
+query, or fragment.  In particular, paths to files in the same bundle may be
+cleanly written in Turtle files as a relative URI.  However, implementations
+may assume any binary Path (e.g. in an event payload) is a valid file path
+which can passed to system functions like fopen() directly, without any
+character encoding or escape expansion required.
+
+Any implemenation that creates a Path atom to transmit to another is
+responsible for ensuring it is valid.  A Path SHOULD always be absolute, unless
+there is some mechanism in place that defines a base path.  Since this is not
+the case for plugin instances, effectively any Path sent to or received from a
+plugin instance MUST be absolute.
+
+"""^^lv2:Markdown .
+
+atom:URI
+	lv2:documentation """
+
+This is useful when a URI is needed but mapping is inappropriate, for example
+with temporary or relative URIs.  Since the ability to distinguish URIs from
+plain strings is often necessary, URIs MUST NOT be transmitted as atom:String.
+
+This is not strictly a URI, since UTF-8 is allowed.  Escaping and related
+issues are the host's responsibility.
+
+"""^^lv2:Markdown .
+
+atom:URID
+	lv2:documentation """
+
+A URID is typically generated with the LV2_URID_Map provided by the host .
+
+"""^^lv2:Markdown .
+
+atom:Vector
+	lv2:documentation """
+
+A homogeneous series of atom bodies with equivalent type and size.
+
+An LV2_Atom_Vector is a 32-bit `child_size` and `child_type` followed by `size
+/ child_size` atom bodies.
+
+For example, an atom:Vector containing 42 elements of type atom:Float:
+
+    :::c
+    struct VectorOf42Floats {
+        uint32_t size;        // sizeof(LV2_Atom_Vector_Body) + (42 * sizeof(float);
+        uint32_t type;        // map(expand("atom:Vector"))
+        uint32_t child_size;  // sizeof(float)
+        uint32_t child_type;  // map(expand("atom:Float"))
+        float    elems[42];
+    };
+
+Note that it is possible to construct a valid Atom for each element of the
+vector, even by an implementation which does not understand `child_type`.
+
+If serialised to RDF, a Vector SHOULD have the form:
+
+    :::turtle
+    eg:someVector
+         a atom:Vector ;
+         atom:childType atom:Int ;
+         rdf:value (
+             "1"^^xsd:int
+             "2"^^xsd:int
+             "3"^^xsd:int
+             "4"^^xsd:int
+         ) .
+
+"""^^lv2:Markdown .
+
+atom:Tuple
+	lv2:documentation """
+
+The body of a Tuple is simply a series of complete atoms, each aligned to
+64 bits.
+
+If serialised to RDF, a Tuple SHOULD have the form:
+
+    :::turtle
+    eg:someVector
+         a atom:Tuple ;
+         rdf:value (
+             "1"^^xsd:int
+             "3.5"^^xsd:float
+             "etc"
+         ) .
+
+"""^^lv2:Markdown .
+
+atom:Property
+	lv2:documentation """
+
+An LV2_Atom_Property has a URID `key` and `context`, and an Atom `value`.  This
+corresponds to an RDF Property, where the <q>key</q> is the <q>predicate</q>
+and the <q>value</q> is the object.
+
+The `context` field can be used to specify a different context for each
+property, where this is useful.  Otherwise, it may be 0.
+
+Properties generally only exist as part of an atom:Object.  Accordingly,
+they will typically be represented directly as properties in RDF (see
+atom:Object).  If this is not possible, they may be expressed as partial
+reified statements, for example:
+
+    :::turtle
+    eg:someProperty
+        rdf:predicate eg:theKey ;
+        rdf:object eg:theValue .
+
+"""^^lv2:Markdown .
+
+atom:Object
+	lv2:documentation """
+
+An <q>Object</q> is an atom with a set of properties.  This corresponds to an
+RDF Resource, and can be thought of as a dictionary with URID keys.
+
+An LV2_Atom_Object body has a uint32_t `id` and `type`, followed by a series of
+atom:Property bodies (LV2_Atom_Property_Body).  The LV2_Atom_Object_Body::otype
+field is equivalent to a property with key rdf:type, but is included in the
+structure to allow for fast dispatching.
+
+Code SHOULD check for objects using lv2_atom_forge_is_object() or
+lv2_atom_forge_is_blank() if a forge is available, rather than checking the
+atom type directly.  This will correctly handle the deprecated atom:Resource
+and atom:Blank types.
+
+When serialised to RDF, an Object is represented as a resource, for example:
+
+    :::turtle
+    eg:someObject
+        eg:firstPropertyKey "first property value" ;
+        eg:secondPropertyKey "first loser" ;
+        eg:andSoOn "and so on" .
+
+"""^^lv2:Markdown .
+
+atom:Resource
+	lv2:documentation """
+
+This class is deprecated.  Use atom:Object directly instead.
+
+An atom:Object where the <code>id</code> field is a URID, that is, an Object
+with a URI.
+
+"""^^lv2:Markdown .
+
+atom:Blank
+	lv2:documentation """
+
+This class is deprecated.  Use atom:Object with ID 0 instead.
+
+An atom:Object where the LV2_Atom_Object::id is a blank node ID (NOT a URI).
+The ID of a Blank is valid only within the context the Blank appears in.  For
+ports this is the context of the associated run() call, i.e. all ports share
+the same context so outputs can contain IDs that correspond to IDs of blanks in
+the input.
+
+"""^^lv2:Markdown .
+
+atom:Sound
+	lv2:documentation """
+
+The format of a atom:Sound is the same as the buffer format for lv2:AudioPort
+(except the size may be arbitrary).  An atom:Sound inherently depends on the
+sample rate, which is assumed to be known from context.  Because of this,
+directly serialising an atom:Sound is probably a bad idea, use a standard
+format like WAV instead.
+
+"""^^lv2:Markdown .
+
+atom:Event
+	lv2:documentation """
+
+An Event is typically an element of an atom:Sequence.  Note that this is not an Atom type since it begins with a timestamp, not an atom header.
+
+"""^^lv2:Markdown .
+
+atom:Sequence
+	lv2:documentation """
+
+A flat sequence of atom:Event, that is, a series of time-stamped Atoms.
+
+LV2_Atom_Sequence_Body.unit describes the time unit for the contained atoms.
+If the unit is known from context (e.g. run() stamps are always audio frames),
+this field may be zero.  Otherwise, it SHOULD be either units:frame or
+units:beat, in which case ev.time.frames or ev.time.beats is valid,
+respectively.
+
+If serialised to RDF, a Sequence has a similar form to atom:Vector, but for
+brevity the elements may be assumed to be atom:Event, for example:
+
+    :::turtle
+    eg:someSequence
+        a atom:Sequence ;
+        rdf:value (
+            [
+                atom:frameTime 1 ;
+                rdf:value "901A01"^^midi:MidiEvent
+            ] [
+                atom:frameTime 3 ;
+                rdf:value "902B02"^^midi:MidiEvent
+            ]
+        ) .
+
+"""^^lv2:Markdown .
+
+atom:AtomPort
+	lv2:documentation """
+
+Ports of this type are connected to an LV2_Atom with a type specified by
+atom:bufferType.
+
+Output ports with a variably sized type MUST be initialised by the host before
+every run() to an atom:Chunk with size set to the available space.  The plugin
+reads this size to know how much space is available for writing.  In all cases,
+the plugin MUST write a complete atom (including header) to outputs.  However,
+to be robust, hosts SHOULD initialise output ports to a safe sentinel (e.g. the
+null Atom) before calling run().
+
+"""^^lv2:Markdown .
+
+atom:bufferType
+	lv2:documentation """
+
+Indicates that an AtomPort may be connected to a certain Atom type.  A port MAY
+support several buffer types.  The host MUST NOT connect a port to an Atom with
+a type not explicitly listed with this property.  The value of this property
+MUST be a sub-class of atom:Atom.  For example, an input port that is connected
+directly to an LV2_Atom_Double value is described like so:
+
+    :::turtle
+    &lt;plugin&gt;
+        lv2:port [
+            a lv2:InputPort , atom:AtomPort ;
+            atom:bufferType atom:Double ;
+        ] .
+
+This property only describes the types a port may be directly connected to.  It
+says nothing about the expected contents of containers.  For that, use
+atom:supports.
+
+"""^^lv2:Markdown .
+
+atom:supports
+	lv2:documentation """
+
+This property is defined loosely, it may be used to indicate that anything
+<q>supports</q> an Atom type, wherever that may be useful.  It applies
+<q>recursively</q> where collections are involved.
+
+In particular, this property can be used to describe which event types are
+expected by a port.  For example, a port that receives MIDI events is described
+like so:
+
+    :::turtle
+    &lt;plugin&gt;
+        lv2:port [
+            a lv2:InputPort , atom:AtomPort ;
+            atom:bufferType atom:Sequence ;
+            atom:supports midi:MidiEvent ;
+        ] .
+
+"""^^lv2:Markdown .
+
+atom:eventTransfer
+	lv2:documentation """
+
+Transfer of individual events in a port buffer.  Useful as the `format` for a
+LV2UI_Write_Function.
+
+This protocol applies to ports which contain events, usually in an
+atom:Sequence.  The host must transfer each individual event to the recipient.
+The format of the received data is an LV2_Atom, there is no timestamp header.
+
+"""^^lv2:Markdown .
+
+atom:atomTransfer
+	lv2:documentation """
+
+Transfer of the complete atom in a port buffer.  Useful as the `format` for a
+LV2UI_Write_Function.
+
+This protocol applies to atom ports.  The host must transfer the complete atom
+contained in the port, including header.
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/atom/atom.ttl b/sys/lv2/atom/atom.ttl
index 891cd1fb..ddfb430d 100644
--- a/sys/lv2/atom/atom.ttl
+++ b/sys/lv2/atom/atom.ttl
@@ -1,133 +1,56 @@
-@prefix atom:  <http://lv2plug.in/ns/ext/atom#> .
-@prefix lv2:   <http://lv2plug.in/ns/lv2core#> .
-@prefix owl:   <http://www.w3.org/2002/07/owl#> .
-@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
-@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
-@prefix ui:    <http://lv2plug.in/ns/extensions/ui#> .
+@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
 @prefix units: <http://lv2plug.in/ns/extensions/units#> .
-@prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
 
 <http://lv2plug.in/ns/ext/atom>
 	a owl:Ontology ;
 	rdfs:seeAlso <atom.h> ,
 		<util.h> ,
 		<forge.h> ,
-		<lv2-atom.doap.ttl> ;
-	lv2:documentation """
-
-<p>An #Atom is a simple generic data container for holding any type of Plain
-Old Data (POD).  An #Atom can contain simple primitive types like integers,
-floating point numbers, and strings; as well as structured data like lists and
-dictionary-like <q>Objects</q>.  Since Atoms are POD, they can be easily copied
-(e.g. using <code>memcpy</code>) anywhere and are suitable for use in real-time
-code.</p>
-
-<p>Every atom starts with an LV2_Atom header, followed by the contents.  This
-allows code to process atoms without requiring special code for every type of
-data.  For example, plugins that mutually understand a type can be used
-together in a host that does not understand that type, because the host is only
-required to copy atoms, not interpret their contents.  Similarly, plugins (such
-as routers, delays, or data structures) can meaningfully process atoms of a
-type unknown to them.</p>
-
-<p>Atoms should be used anywhere values of various types must be stored or
-transmitted.  The port type #AtomPort can be used to transmit atoms via ports.
-An #AtomPort that contains an #Sequence can be used for sample accurate event
-communication, such as MIDI, and replaces the earlier event extension.</p>
-
-<h3>Serialisation</h3>
-
-<p>Each Atom type defines a binary format for use at runtime, but also a
-serialisation that is natural to express in Turtle format.  Thus, this
-specification defines a powerful real-time appropriate data model, as well as a
-portable way to serialise any data in that model.  This is particularly useful
-for inter-process communication, saving/restoring state, and describing values
-in plugin data files.</p>
-
-<h3>Custom Atom Types</h3>
-
-<p>While it is possible to define new Atom types for any binary format, the
-standard types defined here are powerful enough to describe almost anything.
-Implementations SHOULD build structures out of the types provided here, rather
-than define new binary formats (e.g. use #Tuple or #Object rather than
-a new C <code>struct</code> type).  Current implementations have support for
-serialising all standard types, so new binary formats are an implementation
-burden which harms interoperabilty.  In particular, plugins SHOULD NOT expect
-UI communication or state saving with custom Atom types to work.  In general,
-new Atom types should only be defined where absolutely necessary due to
-performance reasons and serialisation is not a concern.</p>
-""" .
+		<atom.meta.ttl> ;
+	rdfs:label "LV2 Atom" ;
+	rdfs:comment "A generic value container and several data types." .
 
 atom:cType
 	a rdf:Property ,
 		owl:DatatypeProperty ,
 		owl:FunctionalProperty ;
 	rdfs:label "C type" ;
+	rdfs:comment "The C type that describes the binary representation of an Atom type." ;
 	rdfs:domain rdfs:Class ;
-	rdfs:range lv2:Symbol ;
-	rdfs:comment """The identifier for a C type describing the binary representation of an Atom of this type.""" .
+	rdfs:range lv2:Symbol .
 
 atom:Atom
 	a rdfs:Class ;
 	rdfs:label "Atom" ;
-	atom:cType "LV2_Atom" ;
-	lv2:documentation """
-<p>Abstract base class for all atoms.  An LV2_Atom has a 32-bit
-<code>size</code> and <code>type</code> followed by a body of <code>size</code>
-bytes.  Atoms MUST be 64-bit aligned.</p>
-
-<p>All concrete Atom types (subclasses of this class) MUST define a precise
-binary layout for their body.</p>
-
-<p>The <code>type</code> field is the URI of an Atom type mapped to an integer.
-Implementations SHOULD gracefully pass through, or ignore, atoms with unknown
-types.</p>
-
-<p>All atoms are POD by definition except references, which as a special case
-have <code>type = 0</code>.  An Atom MUST NOT contain a Reference.  It is safe
-to copy any non-reference Atom with a simple <code>memcpy</code>, even if the
-implementation does not understand <code>type</code>.  Though this extension
-reserves the type 0 for references, the details of reference handling are
-currently unspecified.  A future revision of this extension, or a different
-extension, may define how to use non-POD data and references.  Implementations
-MUST NOT send references to another implementation unless the receiver is
-explicitly known to support references (e.g. by supporting a feature).</p>
-
-<p>The atom with both <code>type</code> <em>and</em> <code>size</code> 0 is
-<q>null</q>, which is not considered a Reference.</p>
-""" .
+	rdfs:comment "Abstract base class for all atoms." ;
+	atom:cType "LV2_Atom" .
 
 atom:Chunk
 	a rdfs:Class ,
 		rdfs:Datatype ;
 	rdfs:subClassOf atom:Atom ;
-	rdfs:label "Chunk of memory" ;
-	owl:onDatatype xsd:base64Binary ;
-	lv2:documentation """
-<p>A chunk of memory with undefined contents.  This type is used to indicate a
-certain amount of space is available.  For example, output ports with a
-variably sized type are connected to a Chunk so the plugin knows the size of
-the buffer available for writing.</p>
-
-<p>The use of a Chunk should be constrained to a local scope, since
-interpreting it is impossible without context.  However, if serialised to RDF,
-a Chunk may be represented directly as an xsd:base64Binary string, e.g.:</p>
-
-<pre class="turtle-code">
-[] eg:someChunk "vu/erQ=="^^xsd:base64Binary .
-</pre>
-""" .
+	rdfs:label "Chunk" ;
+	rdfs:comment "A chunk of memory with undefined contents." ;
+	owl:onDatatype xsd:base64Binary .
 
 atom:Number
 	a rdfs:Class ;
 	rdfs:subClassOf atom:Atom ;
-	rdfs:label "Number" .
+	rdfs:label "Number" ;
+	rdfs:comment "Base class for numeric types." .
 
 atom:Int
 	a rdfs:Class ,
 		rdfs:Datatype ;
 	rdfs:subClassOf atom:Number ;
-	rdfs:label "Signed 32-bit integer" ;
+	rdfs:label "Int" ;
+	rdfs:comment "A native `int32_t`." ;
 	atom:cType "LV2_Atom_Int" ;
 	owl:onDatatype xsd:int .
 
@@ -135,7 +58,8 @@ atom:Long
 	a rdfs:Class ,
 		rdfs:Datatype ;
 	rdfs:subClassOf atom:Number ;
-	rdfs:label "Signed 64-bit integer" ;
+	rdfs:label "Long" ;
+	rdfs:comment "A native `int64_t`." ;
 	atom:cType "LV2_Atom_Long" ;
 	owl:onDatatype xsd:long .
 
@@ -143,7 +67,8 @@ atom:Float
 	a rdfs:Class ,
 		rdfs:Datatype ;
 	rdfs:subClassOf atom:Number ;
-	rdfs:label "32-bit floating point number" ;
+	rdfs:label "Float" ;
+	rdfs:comment "A native `float`." ;
 	atom:cType "LV2_Atom_Float" ;
 	owl:onDatatype xsd:float .
 
@@ -151,7 +76,8 @@ atom:Double
 	a rdfs:Class ,
 		rdfs:Datatype ;
 	rdfs:subClassOf atom:Number ;
-	rdfs:label "64-bit floating point number" ;
+	rdfs:label "Double" ;
+	rdfs:comment "A native `double`." ;
 	atom:cType "LV2_Atom_Double" ;
 	owl:onDatatype xsd:double .
 
@@ -159,289 +85,99 @@ atom:Bool
 	a rdfs:Class ,
 		rdfs:Datatype ;
 	rdfs:subClassOf atom:Atom ;
-	rdfs:label "Boolean" ;
+	rdfs:label "Bool" ;
+	rdfs:comment "An atom:Int where 0 is false and any other value is true." ;
 	atom:cType "LV2_Atom_Bool" ;
-	owl:onDatatype xsd:boolean ;
-	rdfs:comment "An Int where 0 is false and any other value is true." .
+	owl:onDatatype xsd:boolean .
 
 atom:String
 	a rdfs:Class ,
 		rdfs:Datatype ;
 	rdfs:subClassOf atom:Atom ;
 	rdfs:label "String" ;
+	rdfs:comment "A UTF-8 string." ;
 	atom:cType "LV2_Atom_String" ;
-	owl:onDatatype xsd:string ;
-	lv2:documentation """
-<p>A UTF-8 encoded string.</p>
-
-<p>The body of an LV2_Atom_String is a C string in UTF-8 encoding, i.e. an
-array of bytes (<code>uint8_t</code>) terminated with a NULL byte
-(<code>'\\0'</code>).</p>
-
-<p>This type is for free-form strings, but SHOULD NOT be used for typed data or
-text in any language.  Use atom:Literal unless translating the string does not
-make sense and the string has no meaningful datatype.</p>
-""" .
+	owl:onDatatype xsd:string .
 
 atom:Literal
 	a rdfs:Class ;
 	rdfs:subClassOf atom:Atom ;
-	rdfs:label "String Literal" ;
-	atom:cType "LV2_Atom_Literal" ;
-	lv2:documentation """
-<p>A UTF-8 encoded string literal, with an optional datatype or language.</p>
-
-<p>This type is compatible with rdfs:Literal and is capable of expressing a
-string in any language or a value of any type.  A Literal has a
-<code>datatype</code> and <code>lang</code> followed by string data in UTF-8
-encoding.  The length of the string data in bytes is <code>size -
-sizeof(LV2_Atom_Literal)</code>, including the terminating NULL character.  The
-<code>lang</code> field SHOULD be a URI of the form
-&lt;http://lexvo.org/id/iso639-3/LANG&gt; or
-&lt;http://lexvo.org/id/iso639-1/LANG&gt; where LANG is a 3-character ISO 693-3
-language code, or a 2-character ISO 693-1 language code, respectively.</p>
-
-<p>A Literal may have a <code>datatype</code> OR a <code>lang</code>, but never
-both.</p>
-
-<p>For example, a Literal can be "Hello" in English:</p>
-<pre class="c-code">
-void set_to_hello_in_english(LV2_Atom_Literal* lit) {
-     lit->atom.type     = map(expand("atom:Literal"));
-     lit->atom.size     = 14;
-     lit->body.datatype = 0;
-     lit->body.lang     = map("http://lexvo.org/id/iso639-1/en");
-     memcpy(LV2_ATOM_CONTENTS(LV2_Atom_Literal, lit),
-            "Hello",
-            sizeof("Hello"));  // Assumes enough space
-}
-</pre>
-
-<p>or a Turtle string:</p>
-<pre class="c-code">
-void set_to_turtle_string(LV2_Atom_Literal* lit, const char* ttl) {
-     lit->atom.type     = map(expand("atom:Literal"));
-     lit->atom.size     = 64;
-     lit->body.datatype = map("http://www.w3.org/2008/turtle#turtle");
-     lit->body.lang     = 0;
-     memcpy(LV2_ATOM_CONTENTS(LV2_Atom_Literal, lit),
-            ttl,
-            strlen(ttl) + 1);  // Assumes enough space
-}
-</pre>
-""" .
+	rdfs:label "Literal" ;
+	rdfs:comment "A UTF-8 string literal with optional datatype or language." ;
+	atom:cType "LV2_Atom_Literal" .
 
 atom:Path
 	a rdfs:Class ,
 		rdfs:Datatype ;
 	rdfs:subClassOf atom:URI ;
 	owl:onDatatype atom:URI ;
-	rdfs:label "File path string" ;
-	lv2:documentation """
-<p>A local file path.</p>
-
-<p>A Path is a URI reference with only a path component: no scheme, authority,
-query, or fragment.  In particular, paths to files in the same bundle may be
-cleanly written in Turtle files as a relative URI.  However, implementations
-may assume any binary Path (e.g. in an event payload) is a valid file path
-which can passed to system functions like fopen() directly, without any
-character encoding or escape expansion required.</p>
-
-<p>Any implemenation that creates a Path atom to transmit to another is
-responsible for ensuring it is valid.  A Path SHOULD always be absolute, unless
-there is some mechanism in place that defines a base path.  Since this is not
-the case for plugin instances, effectively any Path sent to or received from a
-plugin instance MUST be absolute.</p>
-""" .
+	rdfs:label "Path" ;
+	rdfs:comment "A local file path." .
 
 atom:URI
 	a rdfs:Class ,
 		rdfs:Datatype ;
 	rdfs:subClassOf atom:String ;
 	owl:onDatatype xsd:anyURI ;
-	rdfs:label "URI string" ;
-	lv2:documentation """
-<p>A URI string.  This is useful when a URI is needed but mapping is
-inappropriate, for example with temporary or relative URIs.  Since the ability
-to distinguish URIs from plain strings is often necessary, URIs MUST NOT be
-transmitted as atom:String.</p>
-
-<p>This is not strictly a URI, since UTF-8 is allowed.  Escaping and related
-issues are the host's responsibility.</p>
-""" .
+	rdfs:label "URI" ;
+	rdfs:comment "A URI string." .
 
 atom:URID
 	a rdfs:Class ;
 	rdfs:subClassOf atom:Atom ;
-	rdfs:label "Integer URID" ;
-	atom:cType "LV2_Atom_URID" ;
-	lv2:documentation """
-<p>An unsigned 32-bit integer mapped from a URI (e.g. with LV2_URID_Map).</p>
-""" .
+	rdfs:label "URID" ;
+	rdfs:comment "An unsigned 32-bit integer ID for a URI." ;
+	atom:cType "LV2_Atom_URID" .
 
 atom:Vector
 	a rdfs:Class ;
 	rdfs:subClassOf atom:Atom ;
 	rdfs:label "Vector" ;
-	atom:cType "LV2_Atom_Vector" ;
-	lv2:documentation """
-<p>A homogeneous series of atom bodies with equivalent type and size.</p>
-
-<p>An LV2_Atom_Vector is a 32-bit <code>child_size</code> and
-<code>child_type</code> followed by <code>size / child_size</code> atom
-bodies.</p>
-
-<p>For example, an atom:Vector containing 42 elements of type atom:Float:</p>
-<pre class="c-code">
-struct VectorOf42Floats {
-    uint32_t size;        // sizeof(LV2_Atom_Vector_Body) + (42 * sizeof(float);
-    uint32_t type;        // map(expand("atom:Vector"))
-    uint32_t child_size;  // sizeof(float)
-    uint32_t child_type;  // map(expand("atom:Float"))
-    float    elems[42];
-};
-</pre>
-
-<p>Note that it is possible to construct a valid Atom for each element
-of the vector, even by an implementation which does not understand
-<code>child_type</code>.</p>
-
-<p>If serialised to RDF, a Vector SHOULD have the form:</p>
-
-<pre class="turtle-code">
-eg:someVector
-     a atom:Vector ;
-     atom:childType atom:Int ;
-     rdf:value (
-         "1"^^xsd:int
-         "2"^^xsd:int
-         "3"^^xsd:int
-         "4"^^xsd:int
-     ) .
-</pre>
-""" .
+	rdfs:comment "A homogeneous sequence of atom bodies with equivalent type and size." ;
+	atom:cType "LV2_Atom_Vector" .
 
 atom:Tuple
 	a rdfs:Class ;
 	rdfs:subClassOf atom:Atom ;
 	rdfs:label "Tuple" ;
-	lv2:documentation """
-<p>A series of Atoms with varying <code>type</code> and <code>size</code>.</p>
-
-<p>The body of a Tuple is simply a series of complete atoms, each aligned to
-64 bits.</p>
-
-<p>If serialised to RDF, a Tuple SHOULD have the form:</p>
-
-<pre class="turtle-code">
-eg:someVector
-     a atom:Tuple ;
-     rdf:value (
-         "1"^^xsd:int
-         "3.5"^^xsd:float
-         "etc"
-     ) .
-</pre>
-
-""" .
+	rdfs:comment "A sequence of atoms with varying type and size." .
 
 atom:Property
 	a rdfs:Class ;
 	rdfs:subClassOf atom:Atom ;
 	rdfs:label "Property" ;
-	atom:cType "LV2_Atom_Property" ;
-	lv2:documentation """
-<p>A property of an atom:Object.  An LV2_Atom_Property has a URID
-<code>key</code> and <code>context</code>, and an Atom <code>value</code>.
-This corresponds to an RDF Property, where the <q>key</q> is the <q>predicate</q>
-and the <q>value</q> is the object.</p>
-
-<p>The <code>context</code> field can be used to specify a different context
-for each property, where this is useful.  Otherwise, it may be 0.</p>
-
-<p>Properties generally only exist as part of an atom:Object.  Accordingly,
-they will typically be represented directly as properties in RDF (see
-atom:Object).  If this is not possible, they may be expressed as partial
-reified statements, e.g.:</p>
-
-<pre class="turtle-code">
-eg:someProperty
-    rdf:predicate eg:theKey ;
-    rdf:object eg:theValue .
-</pre>
-""" .
+	rdfs:comment "A property of an atom:Object." ;
+	atom:cType "LV2_Atom_Property" .
 
 atom:Object
 	a rdfs:Class ;
 	rdfs:subClassOf atom:Atom ;
 	rdfs:label "Object" ;
-	atom:cType "LV2_Atom_Object" ;
-	lv2:documentation """
-<p>An <q>Object</q> is an atom with a set of properties.  This corresponds to
-an RDF Resource, and can be thought of as a dictionary with URID keys.</p>
-
-<p>An LV2_Atom_Object body has a uint32_t <code>id</code> and
-<code>type</code>, followed by a series of atom:Property bodies
-(LV2_Atom_Property_Body).  The LV2_Atom_Object_Body::otype field is equivalent
-to a property with key rdf:type, but is included in the structure to allow for
-fast dispatching.</p>
-
-<p>Code SHOULD check for objects using lv2_atom_forge_is_object() or
-lv2_atom_forge_is_blank() if a forge is available, rather than checking the
-atom type directly.  This will correctly handle the deprecated atom:Resource
-and atom:Blank types.</p>
-
-<p>When serialised to RDF, an Object is represented as a resource, e.g.:</p>
-
-<pre class="turtle-code">
-eg:someObject
-    eg:firstPropertyKey "first property value" ;
-    eg:secondPropertyKey "first loser" ;
-    eg:andSoOn "and so on" .
-</pre>
-""" .
+	rdfs:comment "A collection of properties." ;
+	atom:cType "LV2_Atom_Object" .
 
 atom:Resource
 	a rdfs:Class ;
 	rdfs:subClassOf atom:Object ;
 	rdfs:label "Resource" ;
+	rdfs:comment "A named collection of properties with a URI." ;
 	owl:deprecated "true"^^xsd:boolean ;
-	atom:cType "LV2_Atom_Object" ;
-	lv2:documentation """
-<p>This class is deprecated.  Use atom:Object instead.</p>
-
-<p>An atom:Object where the <code>id</code> field is a URID, i.e. an Object
-with a URI.</p>
-""" .
+	atom:cType "LV2_Atom_Object" .
 
 atom:Blank
 	a rdfs:Class ;
 	rdfs:subClassOf atom:Object ;
 	rdfs:label "Blank" ;
+	rdfs:comment "An anonymous collection of properties without a URI." ;
 	owl:deprecated "true"^^xsd:boolean ;
-	atom:cType "LV2_Atom_Object" ;
-	lv2:documentation """
-<p>This class is deprecated.  Use atom:Object with ID 0 instead.</p>
-
-<p>An atom:Object where the LV2_Atom_Object::id is a blank node ID (NOT a URI).
-The ID of a Blank is valid only within the context the Blank appears in.  For
-ports this is the context of the associated run() call, i.e. all ports share
-the same context so outputs can contain IDs that correspond to IDs of blanks in
-the input.</p>
-""" .
+	atom:cType "LV2_Atom_Object" .
 
 atom:Sound
 	a rdfs:Class ;
 	rdfs:subClassOf atom:Vector ;
 	rdfs:label "Sound" ;
-	atom:cType "LV2_Atom_Sound" ;
-	lv2:documentation """
-<p>An atom:Vector of atom:Float which represents an audio waveform.  The format
-is the same as the buffer format for lv2:AudioPort (except the size may be
-arbitrary).  An atom:Sound inherently depends on the sample rate, which is
-assumed to be known from context.  Because of this, directly serialising an
-atom:Sound is probably a bad idea, use a standard format like WAV instead.</p>
-""" .
+	rdfs:comment "A atom:Vector of atom:Float which represents an audio waveform." ;
+	atom:cType "LV2_Atom_Vector" .
 
 atom:frameTime
 	a rdf:Property ,
@@ -449,9 +185,7 @@ atom:frameTime
 		owl:FunctionalProperty ;
 	rdfs:range xsd:decimal ;
 	rdfs:label "frame time" ;
-	lv2:documentation """
-<p>Time stamp in audio frames.  Typically used for events.</p>
-""" .
+	rdfs:comment "A time stamp in audio frames." .
 
 atom:beatTime
 	a rdf:Property ,
@@ -459,66 +193,26 @@ atom:beatTime
 		owl:FunctionalProperty ;
 	rdfs:range xsd:decimal ;
 	rdfs:label "beat time" ;
-	lv2:documentation """
-<p>Time stamp in beats.  Typically used for events.</p>
-""" .
+	rdfs:comment "A time stamp in beats." .
 
 atom:Event
 	a rdfs:Class ;
 	rdfs:label "Event" ;
 	atom:cType "LV2_Atom_Event" ;
-	lv2:documentation """
-<p>An atom with a time stamp prefix, typically an element of an atom:Sequence.
-Note this is not an Atom type.</p>
-""" .
+	rdfs:comment "An atom with a time stamp prefix in a sequence." .
 
 atom:Sequence
 	a rdfs:Class ;
 	rdfs:subClassOf atom:Atom ;
 	rdfs:label "Sequence" ;
 	atom:cType "LV2_Atom_Sequence" ;
-	lv2:documentation """
-<p>A sequence of atom:Event, i.e. a series of time-stamped Atoms.</p>
-
-<p>LV2_Atom_Sequence_Body.unit describes the time unit for the contained atoms.
-If the unit is known from context (e.g. run() stamps are always audio frames),
-this field may be zero.  Otherwise, it SHOULD be either units:frame or
-units:beat, in which case ev.time.frames or ev.time.beats is valid,
-respectively.</p>
-
-<p>If serialised to RDF, a Sequence has a similar form to atom:Vector, but for
-brevity the elements may be assumed to be atom:Event, e.g.:</p>
-
-<pre class="turtle-code">
-eg:someSequence
-    a atom:Sequence ;
-    rdf:value (
-        [
-            atom:frameTime 1 ;
-            rdf:value "901A01"^^midi:MidiEvent
-        ] [
-            atom:frameTime 3 ;
-            rdf:value "902B02"^^midi:MidiEvent
-        ]
-    ) .
-</pre>
-""" .
+	rdfs:comment "A sequence of events." .
 
 atom:AtomPort
 	a rdfs:Class ;
 	rdfs:subClassOf lv2:Port ;
 	rdfs:label "Atom Port" ;
-	lv2:documentation """
-<p>A port which contains an atom:Atom.  Ports of this type are connected to an
-LV2_Atom with a type specified by atom:bufferType.</p>
-
-<p>Output ports with a variably sized type MUST be initialised by the host
-before every run() to an atom:Chunk with size set to the available space.  The
-plugin reads this size to know how much space is available for writing.  In all
-cases, the plugin MUST write a complete atom (including header) to outputs.
-However, to be robust, hosts SHOULD initialise output ports to a safe sentinel
-(e.g. the null Atom) before calling run().</p>
-""" .
+	rdfs:comment "A port which contains an atom:Atom." .
 
 atom:bufferType
 	a rdf:Property ,
@@ -526,77 +220,28 @@ atom:bufferType
 	rdfs:domain atom:AtomPort ;
 	rdfs:range rdfs:Class ;
 	rdfs:label "buffer type" ;
-	lv2:documentation """
-<p>Indicates that an AtomPort may be connected to a certain Atom type.  A port
-MAY support several buffer types.  The host MUST NOT connect a port to an Atom
-with a type not explicitly listed with this property.  The value of this
-property MUST be a sub-class of atom:Atom.  For example, an input port that is
-connected directly to an LV2_Atom_Double value is described like so:</p>
-
-<pre class="turtle-code">
-&lt;plugin&gt;
-    lv2:port [
-        a lv2:InputPort , atom:AtomPort ;
-        atom:bufferType atom:Double ;
-    ] .
-</pre>
-
-<p>This property only describes the types a port may be <em>directly</em>
-connected to.  It says nothing about the expected contents of containers.  For
-that, use atom:supports.</p>
-""" .
+	rdfs:comment "An atom type that a port may be connected to." .
 
 atom:childType
 	a rdf:Property ,
 		owl:ObjectProperty ;
 	rdfs:label "child type" ;
-	rdfs:comment "The type of a container's children." .
+	rdfs:comment "The type of children in a container." .
 
 atom:supports
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:ObjectProperty ;
 	rdfs:label "supports" ;
-	rdfs:range rdfs:Class ;
-	lv2:documentation """
-<p>Indicates that a particular Atom type is supported.</p>
-
-<p>This property is defined loosely, it may be used to indicate that anything
-<q>supports</q> an Atom type, wherever that may be useful.  It applies
-<q>recursively</q> where collections are involved.</p>
-
-<p>In particular, this property can be used to describe which event types are
-expected by a port.  For example, a port that receives MIDI events is described
-like so:</p>
-
-<pre class="turtle-code">
-&lt;plugin&gt;
-    lv2:port [
-        a lv2:InputPort , atom:AtomPort ;
-        atom:bufferType atom:Sequence ;
-        atom:supports midi:MidiEvent ;
-    ] .
-</pre>
-""" .
+	rdfs:comment "A supported atom type." ;
+	rdfs:range rdfs:Class .
 
 atom:eventTransfer
 	a ui:PortProtocol ;
 	rdfs:label "event transfer" ;
-	lv2:documentation """
-<p>Transfer of individual events in a port buffer.  Useful as the
-<code>format</code> for a LV2UI_Write_Function.</p>
-
-<p>This protocol applies to ports which contain events, usually in an
-atom:Sequence.  The host must transfer each individual event to the recipient.
-The format of the received data is an LV2_Atom, there is no timestamp
-header.</p>
-""" .
+	rdfs:comment "A port protocol for transferring events." .
 
 atom:atomTransfer
 	a ui:PortProtocol ;
 	rdfs:label "atom transfer" ;
-	lv2:documentation """
-<p>Transfer of the complete atom in a port buffer.  Useful as the
-<code>format</code> for a LV2UI_Write_Function.</p>
+	rdfs:comment "A port protocol for transferring atoms." .
 
-<p>This protocol applies to atom ports.  The host must transfer the complete
-atom contained in the port, including header.</p>
-""" .
diff --git a/sys/lv2/atom/forge-overflow-test.c b/sys/lv2/atom/forge-overflow-test.c
new file mode 100644
index 00000000..a580d698
--- /dev/null
+++ b/sys/lv2/atom/forge-overflow-test.c
@@ -0,0 +1,237 @@
+/*
+  Copyright 2019 David Robillard <http://drobilla.net>
+
+  Permission to use, copy, modify, and/or distribute this software for any
+  purpose with or without fee is hereby granted, provided that the above
+  copyright notice and this permission notice appear in all copies.
+
+  THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#include "lv2/atom/atom-test-utils.c"
+#include "lv2/atom/atom.h"
+#include "lv2/atom/forge.h"
+#include "lv2/atom/util.h"
+#include "lv2/urid/urid.h"
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+static int
+test_string_overflow(void)
+{
+#define MAX_CHARS 15
+
+	static const size_t capacity = sizeof(LV2_Atom_String) + MAX_CHARS + 1;
+	static const char*  str      = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+	uint8_t*       buf = (uint8_t*)malloc(capacity);
+	LV2_URID_Map   map = { NULL, urid_map };
+	LV2_Atom_Forge forge;
+	lv2_atom_forge_init(&forge, &map);
+
+	// Check that writing increasingly long strings fails at the right point
+	for (size_t count = 0; count < MAX_CHARS; ++count) {
+		lv2_atom_forge_set_buffer(&forge, buf, capacity);
+
+		const LV2_Atom_Forge_Ref ref =
+		        lv2_atom_forge_string(&forge, str, count);
+		if (!ref) {
+			return test_fail("Failed to write %zu byte string\n", count);
+		}
+	}
+
+	// Failure writing to an exactly full forge
+	LV2_Atom_Forge_Ref ref = 0;
+	if ((ref = lv2_atom_forge_string(&forge, str, MAX_CHARS + 1))) {
+		return test_fail("Successfully wrote past end of buffer\n");
+	}
+
+	// Failure writing body after successfully writing header
+	lv2_atom_forge_set_buffer(&forge, buf, sizeof(LV2_Atom) + 1);
+	if ((ref = lv2_atom_forge_string(&forge, "AB", 2))) {
+		return test_fail("Successfully wrote atom header past end\n");
+	}
+
+	free(buf);
+	return 0;
+}
+
+static int
+test_literal_overflow(void)
+{
+	static const size_t capacity = sizeof(LV2_Atom_Literal) + 2;
+
+	uint8_t*           buf = (uint8_t*)malloc(capacity);
+	LV2_URID_Map       map = { NULL, urid_map };
+	LV2_Atom_Forge_Ref ref = 0;
+	LV2_Atom_Forge     forge;
+	lv2_atom_forge_init(&forge, &map);
+
+	// Failure in atom header
+	lv2_atom_forge_set_buffer(&forge, buf, 1);
+	if ((ref = lv2_atom_forge_literal(&forge, "A", 1, 0, 0))) {
+		return test_fail("Successfully wrote atom header past end\n");
+	}
+
+	// Failure in literal header
+	lv2_atom_forge_set_buffer(&forge, buf, sizeof(LV2_Atom) + 1);
+	if ((ref = lv2_atom_forge_literal(&forge, "A", 1, 0, 0))) {
+		return test_fail("Successfully wrote literal header past end\n");
+	}
+
+	// Success (only room for one character + null terminator)
+	lv2_atom_forge_set_buffer(&forge, buf, capacity);
+	if (!(ref = lv2_atom_forge_literal(&forge, "A", 1, 0, 0))) {
+		return test_fail("Failed to write small enough literal\n");
+	}
+
+	// Failure in body
+	lv2_atom_forge_set_buffer(&forge, buf, capacity);
+	if ((ref = lv2_atom_forge_literal(&forge, "AB", 2, 0, 0))) {
+		return test_fail("Successfully wrote literal body past end\n");
+	}
+
+	free(buf);
+	return 0;
+}
+
+static int
+test_sequence_overflow(void)
+{
+	static const size_t size = sizeof(LV2_Atom_Sequence) + 6 * sizeof(LV2_Atom);
+	LV2_URID_Map        map  = { NULL, urid_map };
+
+	// Test over a range that fails in the sequence header and event components
+	for (size_t capacity = 1; capacity < size; ++capacity) {
+		uint8_t* buf = (uint8_t*)malloc(capacity);
+
+		LV2_Atom_Forge forge;
+		lv2_atom_forge_init(&forge, &map);
+		lv2_atom_forge_set_buffer(&forge, buf, capacity);
+
+		LV2_Atom_Forge_Frame frame;
+		LV2_Atom_Forge_Ref   ref =
+		        lv2_atom_forge_sequence_head(&forge, &frame, 0);
+
+		assert(capacity >= sizeof(LV2_Atom_Sequence) || !frame.ref);
+		assert(capacity >= sizeof(LV2_Atom_Sequence) || !ref);
+
+		lv2_atom_forge_frame_time(&forge, 0);
+		lv2_atom_forge_int(&forge, 42);
+		lv2_atom_forge_pop(&forge, &frame);
+
+		free(buf);
+	}
+
+	return 0;
+}
+
+static int
+test_vector_head_overflow(void)
+{
+	static const size_t size = sizeof(LV2_Atom_Vector) + 3 * sizeof(LV2_Atom);
+	LV2_URID_Map        map  = { NULL, urid_map };
+
+	// Test over a range that fails in the vector header and elements
+	for (size_t capacity = 1; capacity < size; ++capacity) {
+		uint8_t* buf = (uint8_t*)malloc(capacity);
+
+		LV2_Atom_Forge forge;
+		lv2_atom_forge_init(&forge, &map);
+		lv2_atom_forge_set_buffer(&forge, buf, capacity);
+
+		LV2_Atom_Forge_Frame frame;
+		LV2_Atom_Forge_Ref   ref = lv2_atom_forge_vector_head(
+                &forge, &frame, sizeof(int32_t), forge.Int);
+
+		assert(capacity >= sizeof(LV2_Atom_Vector) || !frame.ref);
+		assert(capacity >= sizeof(LV2_Atom_Vector) || !ref);
+
+		lv2_atom_forge_int(&forge, 1);
+		lv2_atom_forge_int(&forge, 2);
+		lv2_atom_forge_int(&forge, 3);
+		lv2_atom_forge_pop(&forge, &frame);
+
+		free(buf);
+	}
+
+	return 0;
+}
+
+static int
+test_vector_overflow(void)
+{
+	static const size_t  size  = sizeof(LV2_Atom_Vector) + 3 * sizeof(LV2_Atom);
+	static const int32_t vec[] = { 1, 2, 3 };
+	LV2_URID_Map         map   = { NULL, urid_map };
+
+	// Test over a range that fails in the vector header and elements
+	for (size_t capacity = 1; capacity < size; ++capacity) {
+		uint8_t* buf = (uint8_t*)malloc(capacity);
+
+		LV2_Atom_Forge forge;
+		lv2_atom_forge_init(&forge, &map);
+		lv2_atom_forge_set_buffer(&forge, buf, capacity);
+
+		LV2_Atom_Forge_Ref ref = lv2_atom_forge_vector(
+		        &forge, sizeof(int32_t), forge.Int, 3, vec);
+
+		assert(capacity >= sizeof(LV2_Atom_Vector) || !ref);
+
+		free(buf);
+	}
+
+	return 0;
+}
+
+static int
+test_tuple_overflow(void)
+{
+	static const size_t size = sizeof(LV2_Atom_Tuple) + 3 * sizeof(LV2_Atom);
+	LV2_URID_Map        map  = { NULL, urid_map };
+
+	// Test over a range that fails in the tuple header and elements
+	for (size_t capacity = 1; capacity < size; ++capacity) {
+		uint8_t* buf = (uint8_t*)malloc(capacity);
+
+		LV2_Atom_Forge forge;
+		lv2_atom_forge_init(&forge, &map);
+		lv2_atom_forge_set_buffer(&forge, buf, capacity);
+
+		LV2_Atom_Forge_Frame frame;
+		LV2_Atom_Forge_Ref   ref = lv2_atom_forge_tuple(&forge, &frame);
+
+		assert(capacity >= sizeof(LV2_Atom_Tuple) || !frame.ref);
+		assert(capacity >= sizeof(LV2_Atom_Tuple) || !ref);
+
+		lv2_atom_forge_int(&forge, 1);
+		lv2_atom_forge_float(&forge, 2.0f);
+		lv2_atom_forge_string(&forge, "three", 5);
+		lv2_atom_forge_pop(&forge, &frame);
+
+		free(buf);
+	}
+
+	return 0;
+}
+
+int
+main(void)
+{
+	const int ret = test_string_overflow() || test_literal_overflow() ||
+	                test_sequence_overflow() || test_vector_head_overflow() ||
+	                test_vector_overflow() || test_tuple_overflow();
+
+	free_urid_map();
+
+	return ret;
+}
diff --git a/sys/lv2/atom/forge.h b/sys/lv2/atom/forge.h
index e866b389..e992ff21 100644
--- a/sys/lv2/atom/forge.h
+++ b/sys/lv2/atom/forge.h
@@ -81,9 +81,9 @@ typedef LV2_Atom*
                              LV2_Atom_Forge_Ref         ref);
 
 /** A stack frame used for keeping track of nested Atom containers. */
-typedef struct _LV2_Atom_Forge_Frame {
-	struct _LV2_Atom_Forge_Frame* parent;
-	LV2_Atom_Forge_Ref            ref;
+typedef struct LV2_Atom_Forge_Frame {
+	struct LV2_Atom_Forge_Frame* parent;
+	LV2_Atom_Forge_Ref           ref;
 } LV2_Atom_Forge_Frame;
 
 /** A "forge" for creating atoms by appending to a buffer. */
@@ -176,7 +176,11 @@ lv2_atom_forge_push(LV2_Atom_Forge*       forge,
 {
 	frame->parent = forge->stack;
 	frame->ref    = ref;
-	forge->stack  = frame;
+
+	if (ref) {
+		forge->stack = frame; // Don't push, so walking the stack is always safe
+	}
+
 	return ref;
 }
 
@@ -184,8 +188,12 @@ lv2_atom_forge_push(LV2_Atom_Forge*       forge,
 static inline void
 lv2_atom_forge_pop(LV2_Atom_Forge* forge, LV2_Atom_Forge_Frame* frame)
 {
-	assert(frame == forge->stack);
-	forge->stack = frame->parent;
+	if (frame->ref) {
+		// If frame has a valid ref, it must be the top of the stack
+		assert(frame == forge->stack);
+		forge->stack = frame->parent;
+	}
+	// Otherwise, frame was not pushed because of overflow, do nothing
 }
 
 /** Return true iff the top of the stack has the given type. */
diff --git a/sys/lv2/atom/lv2-atom.doap.ttl b/sys/lv2/atom/lv2-atom.doap.ttl
deleted file mode 100644
index 1613c649..00000000
--- a/sys/lv2/atom/lv2-atom.doap.ttl
+++ /dev/null
@@ -1,103 +0,0 @@
-@prefix dcs: <http://ontologi.es/doap-changeset#> .
-@prefix doap: <http://usefulinc.com/ns/doap#> .
-@prefix foaf: <http://xmlns.com/foaf/0.1/> .
-@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-
-<http://lv2plug.in/ns/ext/atom>
-	a doap:Project ;
-	doap:name "LV2 Atom" ;
-	doap:shortdesc "A generic value container and several data types." ;
-	doap:license <http://opensource.org/licenses/isc> ;
-	doap:created "2007-00-00" ;
-	doap:developer <http://drobilla.net/drobilla#me> ;
-	doap:release [
-		doap:revision "2.2" ;
-		doap:created "2019-02-03" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.16.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Add lv2_atom_object_get_typed() for easy type-safe access to object properties."
-			]
-		]
-	] , [
-		doap:revision "2.0" ;
-		doap:created "2014-08-08" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.10.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Deprecate Blank and Resource in favour of just Object."
-			] , [
-				rdfs:label "Add lv2_atom_forge_is_object_type() and lv2_atom_forge_is_blank() to ease backwards compatibility."
-			] , [
-				rdfs:label "Add lv2_atom_forge_key() for terser object writing."
-			] , [
-				rdfs:label "Add lv2_atom_sequence_clear() and lv2_atom_sequence_append_event() helper functions."
-			]
-		]
-	] , [
-		doap:revision "1.8" ;
-		doap:created "2014-01-04" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.8.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Make lv2_atom_*_is_end() arguments const."
-			]
-		]
-	] , [
-		doap:revision "1.6" ;
-		doap:created "2013-05-26" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.6.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Fix crash in forge.h when pushing atoms to a full buffer."
-			]
-		]
-	] , [
-		doap:revision "1.4" ;
-		doap:created "2013-01-27" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.4.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Fix lv2_atom_sequence_end()."
-			] , [
-				rdfs:label "Remove atom:stringType in favour of owl:onDatatype so generic tools can understand and validate atom literals."
-			] , [
-				rdfs:label "Improve atom documentation."
-			]
-		]
-	] , [
-		doap:revision "1.2" ;
-		doap:created "2012-10-14" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Fix implicit conversions in forge.h that are invalid in C++11."
-			] , [
-				rdfs:label "Fix lv2_atom_object_next() on 32-bit platforms."
-			] , [
-				rdfs:label "Add lv2_atom_object_body_get()."
-			] , [
-				rdfs:label "Fix outdated documentation in forge.h."
-			] , [
-				rdfs:label "Use consistent label style."
-			] , [
-				rdfs:label "Add LV2_ATOM_CONTENTS_CONST and LV2_ATOM_BODY_CONST."
-			]
-		]
-	] , [
-		doap:revision "1.0" ;
-		doap:created "2012-04-17" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Initial release."
-			]
-		]
-	] .
diff --git a/sys/lv2/atom/manifest.ttl b/sys/lv2/atom/manifest.ttl
index ae6195bc..46d6de5a 100644
--- a/sys/lv2/atom/manifest.ttl
+++ b/sys/lv2/atom/manifest.ttl
@@ -1,4 +1,4 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/atom>
@@ -6,3 +6,4 @@
 	lv2:minorVersion 2 ;
 	lv2:microVersion 2 ;
 	rdfs:seeAlso <atom.ttl> .
+
diff --git a/sys/lv2/atom/util.h b/sys/lv2/atom/util.h
index cf24a533..383d3043 100644
--- a/sys/lv2/atom/util.h
+++ b/sys/lv2/atom/util.h
@@ -114,7 +114,9 @@ lv2_atom_sequence_next(const LV2_Atom_Event* i)
    @param seq  The sequence to iterate over
    @param iter The name of the iterator
 
-   This macro is used similarly to a for loop (which it expands to), e.g.:
+   This macro is used similarly to a for loop (which it expands to), for
+   example:
+
    @code
    LV2_ATOM_SEQUENCE_FOREACH(sequence, ev) {
        // Do something with ev (an LV2_Atom_Event*) here...
@@ -154,7 +156,7 @@ lv2_atom_sequence_clear(LV2_Atom_Sequence* seq)
 
    @param seq Sequence to append to.
    @param capacity Total capacity of the sequence atom
-   (e.g. as set by the host for sequence output ports).
+   (as set by the host for sequence output ports).
    @param event Event to write.
 
    @return A pointer to the newly written event in `seq`,
@@ -211,7 +213,9 @@ lv2_atom_tuple_next(const LV2_Atom* i)
    @param tuple The tuple to iterate over
    @param iter The name of the iterator
 
-   This macro is used similarly to a for loop (which it expands to), e.g.:
+   This macro is used similarly to a for loop (which it expands to), for
+   example:
+
    @code
    LV2_ATOM_TUPLE_FOREACH(tuple, elem) {
        // Do something with elem (an LV2_Atom*) here...
@@ -267,10 +271,12 @@ lv2_atom_object_next(const LV2_Atom_Property_Body* i)
    @param obj The object to iterate over
    @param iter The name of the iterator
 
-   This macro is used similarly to a for loop (which it expands to), e.g.:
+   This macro is used similarly to a for loop (which it expands to), for
+   example:
+
    @code
    LV2_ATOM_OBJECT_FOREACH(object, i) {
-       // Do something with prop (an LV2_Atom_Property_Body*) here...
+       // Do something with i (an LV2_Atom_Property_Body*) here...
    }
    @endcode
 */
@@ -297,6 +303,7 @@ typedef struct {
 	const LV2_Atom** value;  /**< Found value (output set by query function) */
 } LV2_Atom_Object_Query;
 
+/** Sentinel for lv2_atom_object_query(). */
 static const LV2_Atom_Object_Query LV2_ATOM_OBJECT_QUERY_END = { 0, NULL };
 
 /**
diff --git a/sys/lv2/buf-size/NEWS b/sys/lv2/buf-size/NEWS
deleted file mode 100644
index f025596c..00000000
--- a/sys/lv2/buf-size/NEWS
+++ /dev/null
@@ -1,19 +0,0 @@
-buf-size (1.4) stable;
-
-  * Add bufsz:coarseBlockLength feature.
-  * Add bufsz:nominalBlockLength option.
-
- -- None <None>  Fri, 18 Sep 2015 00:00:00 +0000
-
-buf-size (1.2) stable;
-
-  * Fix typo in bufsz:sequenceSize label.
-
- -- None <None>  Fri, 21 Dec 2012 00:00:00 +0000
-
-buf-size (1.0) stable;
-
-  * Initial release.
-
- -- None <None>  Sun, 14 Oct 2012 00:00:00 +0000
-
diff --git a/sys/lv2/buf-size/buf-size.h b/sys/lv2/buf-size/buf-size.h
index 900f8fa2..7655c773 100644
--- a/sys/lv2/buf-size/buf-size.h
+++ b/sys/lv2/buf-size/buf-size.h
@@ -19,6 +19,7 @@
 
 /**
    @defgroup buf-size Buffer Size
+   @ingroup lv2
 
    Access to, and restrictions on, buffer sizes; see
    <http://lv2plug.in/ns/ext/buf-size> for details.
diff --git a/sys/lv2/buf-size/buf-size.meta.ttl b/sys/lv2/buf-size/buf-size.meta.ttl
new file mode 100644
index 00000000..b1d8011c
--- /dev/null
+++ b/sys/lv2/buf-size/buf-size.meta.ttl
@@ -0,0 +1,157 @@
+@prefix bufsz: <http://lv2plug.in/ns/ext/buf-size#> .
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/buf-size>
+	a doap:Project ;
+	doap:name "LV2 Buf Size" ;
+	doap:shortdesc "Access to, and restrictions on, buffer sizes." ;
+	doap:created "2012-08-07" ;
+	doap:developer <http://drobilla.net/drobilla#me> ;
+	doap:release [
+		doap:revision "1.4" ;
+		doap:created "2015-09-18" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.14.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add bufsz:nominalBlockLength option."
+			] , [
+				rdfs:label "Add bufsz:coarseBlockLength feature."
+			]
+		]
+	] , [
+		doap:revision "1.2" ;
+		doap:created "2012-12-21" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.4.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Fix typo in bufsz:sequenceSize label."
+			]
+		]
+	] , [
+		doap:revision "1.0" ;
+		doap:created "2012-10-14" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Initial release."
+			]
+		]
+	] ;
+	lv2:documentation """
+
+This extension defines a facility for plugins to get information about the
+block length (the sample_count parameter of LV2_Descriptor::run) and port
+buffer sizes, as well as several features which can be used to restrict the
+block length.
+
+This extension defines features and properties but has no special purpose
+API of its own.  The host provides all the relevant information to the plugin
+as [options](options.html).
+
+To require restrictions on the block length, plugins can require additional
+features: bufsz:boundedBlockLength, bufsz:powerOf2BlockLength, and
+bufsz:fixedBlockLength.  These features are data-only, that is they merely
+indicate a restriction and do not carry any data or API.
+
+"""^^lv2:Markdown .
+
+bufsz:boundedBlockLength
+	lv2:documentation """
+
+A feature that indicates the host will provide both the bufsz:minBlockLength
+and bufsz:maxBlockLength options to the plugin.  Plugins that copy data from
+audio inputs can require this feature to ensure they know how much space is
+required for auxiliary buffers.  Note the minimum may be zero, this feature is
+mainly useful to ensure a maximum is available.
+
+All hosts SHOULD support this feature, since it is simple to support and
+necessary for any plugins that may need to copy the input.
+
+"""^^lv2:Markdown .
+
+bufsz:fixedBlockLength
+	lv2:documentation """
+
+A feature that indicates the host will always call LV2_Descriptor::run() with
+the same value for sample_count.  This length MUST be provided as the value of
+both the bufsz:minBlockLength and bufsz:maxBlockLength options.
+
+Note that requiring this feature may severely limit the number of hosts capable
+of running the plugin.
+
+"""^^lv2:Markdown .
+
+bufsz:powerOf2BlockLength
+	lv2:documentation """
+
+A feature that indicates the host will always call LV2_Descriptor::run() with a
+power of two sample_count.  Note that this feature does not guarantee the value
+is the same each call, to guarantee a fixed power of two block length plugins
+must require both this feature and bufsz:fixedBlockLength.
+
+Note that requiring this feature may severely limit the number of hosts capable
+of running the plugin.
+
+"""^^lv2:Markdown .
+
+bufsz:coarseBlockLength
+	lv2:documentation """
+
+A feature that indicates the plugin prefers coarse, regular block lengths.  For
+example, plugins that do not implement sample-accurate control use this feature
+to indicate that the host should not split the run cycle because controls have
+changed.
+
+Note that this feature is merely a hint, and does not guarantee a fixed block
+length.  The run cycle may be split for other reasons, and the blocksize itself
+may change anytime.
+
+"""^^lv2:Markdown .
+
+bufsz:maxBlockLength
+	lv2:documentation """
+
+The maximum block length the host will ever request the plugin to process at
+once, that is, the maximum `sample_count` parameter that will ever be passed to
+LV2_Descriptor::run().
+
+"""^^lv2:Markdown .
+
+bufsz:minBlockLength
+	lv2:documentation """
+
+The minimum block length the host will ever request the plugin to process at
+once, that is, the minimum `sample_count` parameter that will ever be passed to
+LV2_Descriptor::run().
+
+"""^^lv2:Markdown .
+
+bufsz:nominalBlockLength
+	lv2:documentation """
+
+The typical block length the host will request the plugin to process at once,
+that is, the typical `sample_count` parameter that will be passed to
+LV2_Descriptor::run().  This will usually be equivalent, or close to, the
+maximum block length, but there are no strong guarantees about this value
+whatsoever.  Plugins may use this length for optimization purposes, but MUST
+NOT assume the host will always process blocks of this length.  In particular,
+the host MAY process longer blocks.
+
+"""^^lv2:Markdown .
+
+bufsz:sequenceSize
+	lv2:documentation """
+
+This should be provided as an option by hosts that support event ports
+(including but not limited to MIDI), so plugins have the ability to allocate
+auxiliary buffers large enough to copy the input.
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/buf-size/buf-size.ttl b/sys/lv2/buf-size/buf-size.ttl
index f8a9d601..88631982 100644
--- a/sys/lv2/buf-size/buf-size.ttl
+++ b/sys/lv2/buf-size/buf-size.ttl
@@ -1,129 +1,67 @@
 @prefix bufsz: <http://lv2plug.in/ns/ext/buf-size#> .
-@prefix lv2:   <http://lv2plug.in/ns/lv2core#> .
-@prefix opts:  <http://lv2plug.in/ns/ext/options#> .
-@prefix owl:   <http://www.w3.org/2002/07/owl#> .
-@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
-@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
-@prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix opts: <http://lv2plug.in/ns/ext/options#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
 
 <http://lv2plug.in/ns/ext/buf-size>
-	a lv2:Specification ;
+	a owl:Ontology ;
+	rdfs:label "LV2 Buf Size" ;
+	rdfs:comment "Access to, and restrictions on, buffer sizes." ;
 	rdfs:seeAlso <buf-size.h> ,
-		<lv2-buf-size.doap.ttl> ;
-	lv2:documentation """
-<p>This extension defines a facility for plugins to get information about the
-block length (the sample_count parameter of LV2_Descriptor::run) and
-port buffer sizes, as well as several features which can be used to restrict
-the block length.</p>
-
-<p>This extension defines features and properties but has no special purpose
-API of its own.  The host provides all the relevant information to the plugin
-as <a href="../options/options.html#options">options</a>.</p>
-
-<p>To require restrictions on the block length, plugins can require additional
-features: bufsz:boundedBlockLength, bufsz:powerOf2BlockLength, and
-bufsz:fixedBlockLength.  These features are data-only, that is they merely
-indicate a restriction and do not carry any data or API.</p>
-""" .
+		<buf-size.meta.ttl> .
 
 bufsz:boundedBlockLength
 	a lv2:Feature ;
-	lv2:documentation """
-<p>A feature that indicates the host will provide both the bufsz:minBlockLength
-and bufsz:maxBlockLength options to the plugin.  Plugins that copy data from
-audio inputs can require this feature to ensure they know how much space is
-required for auxiliary buffers.  Note the minimum may be zero, this feature is
-mainly useful to ensure a maximum is available.</p>
-
-<p>All hosts SHOULD support this feature, since it is simple to support and
-necessary for any plugins that may need to copy the input.</p>
-""" .
+	rdfs:label "bounded block length" ;
+	rdfs:comment "Block length has lower and upper bounds." .
 
 bufsz:fixedBlockLength
 	a lv2:Feature ;
-	lv2:documentation """
-<p>A feature that indicates the host will always call LV2_Descriptor::run()
-with the same value for sample_count.  This length MUST be provided as the
-value of both the bufsz:minBlockLength and bufsz:maxBlockLength options.</p>
-
-<p>Note that requiring this feature may severely limit the number of hosts
-capable of running the plugin.</p>
-""" .
+	rdfs:label "fixed block length" ;
+	rdfs:comment "Block length never changes." .
 
 bufsz:powerOf2BlockLength
 	a lv2:Feature ;
-	lv2:documentation """
-<p>A feature that indicates the host will always call LV2_Descriptor::run()
-with a power of two sample_count.  Note that this feature does not guarantee
-the value is the same each call, to guarantee a fixed power of two block length
-plugins must require both this feature and bufsz:fixedBlockLength.</p>
-
-<p>Note that requiring this feature may severely limit the number of hosts
-capable of running the plugin.</p>
-""" .
+	rdfs:label "power of 2 block length" ;
+	rdfs:comment "Block length is a power of 2." .
 
 bufsz:coarseBlockLength
 	a lv2:Feature ;
 	rdfs:label "coarse block length" ;
-	lv2:documentation """
-<p>A feature that indicates the plugin prefers coarse, regular block lengths.
-For example, plugins that do not implement sample-accurate control use this
-feature to indicate that the host should not split the run cycle because
-controls have changed.</p>
-
-<p>Note that this feature is merely a hint, and does not guarantee a fixed
-block length.  The run cycle may be split for other reasons, and the blocksize
-itself may change anytime.</p>
-""" .
+	rdfs:comment "Plugin prefers coarse block length without buffer splitting." .
 
 bufsz:maxBlockLength
 	a rdf:Property ,
 		owl:DatatypeProperty ,
 		opts:Option ;
 	rdfs:label "maximum block length" ;
-	rdfs:range xsd:nonNegativeInteger ;
-	lv2:documentation """
-<p>The maximum block length the host will ever request the plugin to process at
-once, that is, the maximum <code>sample_count</code> parameter that will ever
-be passed to LV2_Descriptor::run().</p>
-""" .
+	rdfs:comment "Block length has an upper bound." ;
+	rdfs:range xsd:nonNegativeInteger .
 
 bufsz:minBlockLength
 	a rdf:Property ,
 		owl:DatatypeProperty ,
 		opts:Option ;
 	rdfs:label "minimum block length" ;
-	rdfs:range xsd:nonNegativeInteger ;
-	lv2:documentation """
-<p>The minimum block length the host will ever request the plugin to process at
-once, that is, the minimum <code>sample_count</code> parameter that will ever
-be passed to LV2_Descriptor::run().</p>
-""" .
+	rdfs:comment "Block length has a lower bound." ;
+	rdfs:range xsd:nonNegativeInteger .
 
 bufsz:nominalBlockLength
 	a rdf:Property ,
 		owl:DatatypeProperty ,
 		opts:Option ;
 	rdfs:label "nominal block length" ;
-	rdfs:range xsd:nonNegativeInteger ;
-	lv2:documentation """
-<p>The typical block length the host will request the plugin to process at
-once, that is, the typical <code>sample_count</code> parameter that will
-be passed to LV2_Descriptor::run().  This will usually be equivalent, or close
-to, the maximum block length, but there are no strong guarantees about this
-value whatsoever.  Plugins may use this length for optimization purposes, but
-MUST NOT assume the host will always process blocks of this length.  In
-particular, the host MAY process longer blocks.</p>
-""" .
+	rdfs:comment "Typical block length that will most often be processed." ;
+	rdfs:range xsd:nonNegativeInteger .
 
 bufsz:sequenceSize
 	a rdf:Property ,
 		owl:DatatypeProperty ,
 		opts:Option ;
 	rdfs:label "sequence size" ;
-	rdfs:range xsd:nonNegativeInteger ;
-	lv2:documentation """
-<p>The maximum size of a sequence, in bytes.  This should be provided as an
-option by hosts that support event ports (including but not limited to MIDI),
-so plugins have the ability to allocate auxiliary buffers large enough to copy
-the input.</p> """ .
+	rdfs:comment "The maximum size of a sequence, in bytes." ;
+	rdfs:range xsd:nonNegativeInteger .
+
diff --git a/sys/lv2/buf-size/lv2-buf-size.doap.ttl b/sys/lv2/buf-size/lv2-buf-size.doap.ttl
deleted file mode 100644
index bc6ffe96..00000000
--- a/sys/lv2/buf-size/lv2-buf-size.doap.ttl
+++ /dev/null
@@ -1,44 +0,0 @@
-@prefix dcs: <http://ontologi.es/doap-changeset#> .
-@prefix doap: <http://usefulinc.com/ns/doap#> .
-@prefix foaf: <http://xmlns.com/foaf/0.1/> .
-@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-
-<http://lv2plug.in/ns/ext/buf-size>
-	a doap:Project ;
-	doap:name "LV2 Buf Size" ;
-	doap:shortdesc "Access to, and restrictions on, buffer sizes." ;
-	doap:created "2012-08-07" ;
-	doap:developer <http://drobilla.net/drobilla#me> ;
-	doap:release [
-		doap:revision "1.4" ;
-		doap:created "2015-09-18" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.14.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Add bufsz:nominalBlockLength option."
-			] , [
-				rdfs:label "Add bufsz:coarseBlockLength feature."
-			]
-		]
-	] , [
-		doap:revision "1.2" ;
-		doap:created "2012-12-21" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.4.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Fix typo in bufsz:sequenceSize label."
-			]
-		]
-	] , [
-		doap:revision "1.0" ;
-		doap:created "2012-10-14" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Initial release."
-			]
-		]
-	] .
diff --git a/sys/lv2/buf-size/manifest.ttl b/sys/lv2/buf-size/manifest.ttl
index aeccc995..d242f97b 100644
--- a/sys/lv2/buf-size/manifest.ttl
+++ b/sys/lv2/buf-size/manifest.ttl
@@ -1,4 +1,4 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/buf-size>
diff --git a/sys/lv2/core/NEWS b/sys/lv2/core/NEWS
deleted file mode 100644
index 6f1db6d9..00000000
--- a/sys/lv2/core/NEWS
+++ /dev/null
@@ -1,80 +0,0 @@
-core (1.16.0) stable;
-
-  * Add lv2_validate utility.
-  * Add core/attributes.h utility header.
-  * Upgrade build system and fix building with Python 3.7.
-  * eg-sampler: Add waveform display to UI.
-  * eg-midigate: Respond to "all notes off" MIDI message.
-  * Aggressively deprecate uri-map and event extensions.
-  * Simplify use of lv2specgen.
-  * Install headers to simpler paths.
-
- -- David Robillard <d@drobilla.net>  Sun, 03 Feb 2019 00:00:00 +0000
-
-core (1.14.0) stable;
-
-  * eg-sampler: Fix handling of state file paths.
-  * eg-sampler: Support thread-safe state restoration.
-  * eg-scope: Don't feed back UI state updates.
-
- -- David Robillard <d@drobilla.net>  Mon, 19 Sep 2016 00:00:00 +0000
-
-core (1.12.0) stable;
-
-  * eg-sampler: Support patch:Get, and request initial state from UI.
-  * eg-sampler: Add gain parameter.
-  * Improve API documentation.
-  * Simplify property restrictions by removing redundancy.
-  * Fix merging of version histories in specification documentation.
-
- -- David Robillard <d@drobilla.net>  Tue, 07 Apr 2015 00:00:00 +0000
-
-core (1.10.0) stable;
-
-  * lv2specgen: Display deprecated warning on classes marked owl:deprecated.
-  * Fix -Wconversion warnings in headers.
-  * Upgrade to waf 1.7.16.
-
- -- David Robillard <d@drobilla.net>  Fri, 08 Aug 2014 00:00:00 +0000
-
-core (1.8.0) stable;
-
-  * lv2specgen: Fix links to externally defined terms.
-  * Add scope example plugin from Robin Gareus.
-  * Install lv2specgen for use by other projects.
-
- -- David Robillard <d@drobilla.net>  Sat, 04 Jan 2014 00:00:00 +0000
-
-core (1.6.0) stable;
-
-  * Fix lv2specgen usage from command line.
-  * Fix port indices of metronome example.
-  * Upgrade to waf 1.7.11.
-
- -- David Robillard <d@drobilla.net>  Fri, 09 Aug 2013 00:00:00 +0000
-
-core (1.4.0) stable;
-
-  * Add metronome example plugin to demonstrate sample accurate tempo sync.
-  * Generate book-style HTML documentation from example plugins.
-
- -- David Robillard <d@drobilla.net>  Sun, 17 Feb 2013 00:00:00 +0000
-
-core (1.2.0) stable;
-
-  * Use stricter datatype definitions conformant with the XSD and OWL
-    specifications for better validation.
-  * Move all project metadata for extensions (e.g. change log) to separate files to
-    spare hosts from loading them during discovery.
-
- -- David Robillard <d@drobilla.net>  Sun, 14 Oct 2012 00:00:00 +0000
-
-core (1.0.0) stable;
-
-  * Initial release as a unified project.  Projects can now simply depend on the
-    pkg-config package 'lv2' for all official LV2 APIs.
-  * New extensions: atom, log, parameters, patch, port-groups, port-props, resize-
-    port, state, time, worker.
-
- -- David Robillard <d@drobilla.net>  Mon, 16 Apr 2012 00:00:00 +0000
-
diff --git a/sys/lv2/core/attributes.h b/sys/lv2/core/attributes.h
index c054ae17..7465c22a 100644
--- a/sys/lv2/core/attributes.h
+++ b/sys/lv2/core/attributes.h
@@ -19,6 +19,7 @@
 
 /**
    @defgroup attributes Attributes
+   @ingroup lv2
 
    Macros for source code attributes.
 
diff --git a/sys/lv2/core/lv2.h b/sys/lv2/core/lv2.h
index 3bfdd025..9b2de6fe 100644
--- a/sys/lv2/core/lv2.h
+++ b/sys/lv2/core/lv2.h
@@ -19,7 +19,15 @@
 */
 
 /**
-   @defgroup core LV2 Core
+   @defgroup lv2 LV2
+
+   The LV2 specification.
+
+   @{
+*/
+
+/**
+   @defgroup lv2core LV2 Core
 
    Core LV2 specification, see <http://lv2plug.in/ns/lv2core> for details.
 
@@ -140,7 +148,7 @@ typedef void * LV2_Handle;
    features and specify the `URI` and `data` to be used if necessary.
    Some features, such as lv2:isLive, do not require the host to pass data.
 */
-typedef struct _LV2_Feature {
+typedef struct {
 	/**
 	   A globally unique, case-sensitive identifier (URI) for this feature.
 
@@ -163,7 +171,7 @@ typedef struct _LV2_Feature {
    This structure provides the core functions necessary to instantiate and use
    a plugin.
 */
-typedef struct _LV2_Descriptor {
+typedef struct LV2_Descriptor {
 	/**
 	   A globally unique, case-sensitive identifier for this plugin.
 
@@ -185,9 +193,8 @@ typedef struct _LV2_Descriptor {
 	   @param sample_rate Sample rate, in Hz, for the new plugin instance.
 
 	   @param bundle_path Path to the LV2 bundle which contains this plugin
-	   binary. It MUST include the trailing directory separator (e.g. '/') so
-	   that simply appending a filename will yield the path to that file in the
-	   bundle.
+	   binary. It MUST include the trailing directory separator so that simply
+	   appending a filename will yield the path to that file in the bundle.
 
 	   @param features A NULL terminated array of LV2_Feature structs which
 	   represent the features the host supports. Plugins may refuse to
@@ -201,10 +208,10 @@ typedef struct _LV2_Descriptor {
 	   @return A handle for the new plugin instance, or NULL if instantiation
 	   has failed.
 	*/
-	LV2_Handle (*instantiate)(const struct _LV2_Descriptor * descriptor,
-	                          double                         sample_rate,
-	                          const char *                   bundle_path,
-	                          const LV2_Feature *const *     features);
+	LV2_Handle (*instantiate)(const struct LV2_Descriptor * descriptor,
+	                          double                        sample_rate,
+	                          const char *                  bundle_path,
+	                          const LV2_Feature *const *    features);
 
 	/**
 	   Connect a port on a plugin instance to a memory location.
@@ -235,7 +242,7 @@ typedef struct _LV2_Descriptor {
 	   it does, the plugin's behaviour is undefined (a crash is likely).
 
 	   @param data_location Pointer to data of the type defined by the port
-	   type in the plugin's RDF data (e.g. an array of float for an
+	   type in the plugin's RDF data (for example, an array of float for an
 	   lv2:AudioPort). This pointer must be stored by the plugin instance and
 	   used to read/write data when run() is called. Data present at the time
 	   of the connect_port() call MUST NOT be considered meaningful.
@@ -279,10 +286,10 @@ typedef struct _LV2_Descriptor {
 	   lv2core.ttl for details).
 
 	   As a special case, when `sample_count` is 0, the plugin should update
-	   any output ports that represent a single instant in time (e.g. control
-	   ports, but not audio ports). This is particularly useful for latent
-	   plugins, which should update their latency output port so hosts can
-	   pre-roll plugins to compute latency. Plugins MUST NOT crash when
+	   any output ports that represent a single instant in time (for example,
+	   control ports, but not audio ports). This is particularly useful for
+	   latent plugins, which should update their latency output port so hosts
+	   can pre-roll plugins to compute latency. Plugins MUST NOT crash when
 	   `sample_count` is 0.
 
 	   @param instance Instance to be run.
@@ -471,4 +478,5 @@ typedef const LV2_Lib_Descriptor *
 
 /**
    @}
+   @}
 */
diff --git a/sys/lv2/core/lv2_util.h b/sys/lv2/core/lv2_util.h
index 06174eec..0792941d 100644
--- a/sys/lv2/core/lv2_util.h
+++ b/sys/lv2/core/lv2_util.h
@@ -99,5 +99,4 @@ lv2_features_query(const LV2_Feature* const* features, ...)
 
 /**
    @}
-   @}
 */
diff --git a/sys/lv2/core/lv2core.doap.ttl b/sys/lv2/core/lv2core.doap.ttl
deleted file mode 100644
index aace5bae..00000000
--- a/sys/lv2/core/lv2core.doap.ttl
+++ /dev/null
@@ -1,204 +0,0 @@
-@prefix dcs: <http://ontologi.es/doap-changeset#> .
-@prefix doap: <http://usefulinc.com/ns/doap#> .
-@prefix foaf: <http://xmlns.com/foaf/0.1/> .
-@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-
-<http://lv2plug.in/ns/lv2core>
-	a doap:Project ;
-	rdfs:seeAlso <meta.ttl> ;
-	doap:license <http://opensource.org/licenses/isc> ;
-	doap:name "LV2" ;
-	doap:homepage <http://lv2plug.in> ;
-	doap:created "2004-04-21" ;
-	doap:shortdesc "An audio plugin interface specification." ;
-	doap:programming-language "C" ;
-	doap:developer <http://plugin.org.uk/swh.xrdf#me> ,
-		<http://drobilla.net/drobilla#me> ;
-	doap:maintainer <http://drobilla.net/drobilla#me> ;
-	doap:release [
-		doap:revision "16.0" ;
-		doap:created "2019-02-03" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.16.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Add lv2:MIDIPlugin class."
-			] , [
-				rdfs:label "Rework port restrictions so that presets can be validated."
-			]
-		]
-	] , [
-		doap:revision "14.0" ;
-		doap:created "2016-09-18" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.14.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Add lv2_util.h with lv2_features_data() and lv2_features_query()."
-			] , [
-				rdfs:label "Add lv2:enabled designation."
-			]
-		]
-	] , [
-		doap:revision "12.4" ;
-		doap:created "2015-04-07" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.12.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Relax domain of lv2:minimum lv2:maximum and lv2:default so they can be used to describe properties/parameters as well."
-			] , [
-				rdfs:label "Add extern C and visibility attribute to LV2_SYMBOL_EXPORT."
-			] , [
-				rdfs:label "Add lv2:isSideChain port property."
-			]
-		]
-	] , [
-		doap:revision "12.2" ;
-		doap:created "2014-08-08" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.10.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Clarify lv2_descriptor() and lv2_lib_descriptor() documentation."
-			]
-		]
-	] , [
-		doap:revision "12.0" ;
-		doap:created "2014-01-04" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.8.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Add lv2:prototype for property inheritance."
-			]
-		]
-	] , [
-		doap:revision "10.0" ;
-		doap:created "2013-02-17" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.4.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Add lv2:EnvelopePlugin class."
-			] , [
-				rdfs:label "Add lv2:control for designating primary event-based control ports."
-			] , [
-				rdfs:label "Set range of lv2:designation to lv2:Designation."
-			] , [
-				rdfs:label "Make lv2:Parameter rdfs:subClassOf rdf:Property."
-			] , [
-				rdfs:label "Reserve minor version 0 for unstable development plugins."
-			]
-		]
-	] , [
-		doap:revision "8.2" ;
-		doap:created "2012-10-14" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Use consistent label style."
-			]
-		]
-	] , [
-		doap:revision "8.0" ;
-		doap:created "2012-04-17" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Fix LV2_SYMBOL_EXPORT and lv2_descriptor prototype for Windows."
-			] , [
-				rdfs:label "Add metadata concept of a designation, a channel or parameter description which can be assigned to ports for more intelligent use by hosts."
-			] , [
-				rdfs:label "Add new discovery API which allows libraries to read bundle files during discovery, makes library construction/destruction explicit, and adds extensibility to prevent future breakage."
-			] , [
-				rdfs:label "Relax the range of lv2:index so it can be used for things other than ports."
-			] , [
-				rdfs:label "Remove lv2:Resource, which turned out to be meaningless."
-			] , [
-				rdfs:label "Add lv2:CVPort."
-			] , [
-				rdfs:label "Merge with unified LV2 package."
-			]
-		]
-	] , [
-		doap:revision "6.0" ;
-		doap:created "2011-11-21" ;
-		doap:file-release <http://lv2plug.in/spec/lv2core-6.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Rename core.lv2 and lv2.ttl to lv2core.lv2 and lv2core.ttl to adhere to modern conventions."
-			] , [
-				rdfs:label "Add lv2:extensionData and lv2:ExtensionData for plugins to indicate that they support some URI for extension_data()."
-			] , [
-				rdfs:label "Remove lv2config in favour of the simple convention that specifications install headers to standard URI-based paths."
-			] , [
-				rdfs:label "Switch to the ISC license, a simple BSD-style license (with permission of all contributors to lv2.h and its ancestor, ladspa.h)."
-			] , [
-				rdfs:label "Make lv2core.ttl a valid OWL 2 DL ontology."
-			] , [
-				rdfs:label "Improve documentation."
-			]
-		]
-	] , [
-		doap:revision "4.0" ;
-		doap:created "2011-03-18" ;
-		doap:file-release <http://lv2plug.in/spec/lv2core-4.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Make doap:license suggested, but not required (for wrappers)."
-			] , [
-				rdfs:label "Define lv2:binary (MUST be in manifest.ttl)."
-			] , [
-				rdfs:label "Define lv2:minorVersion and lv2:microVersion (MUST be in manifest.ttl)."
-			] , [
-				rdfs:label "Define lv2:documentation and use it to document lv2core."
-			] , [
-				rdfs:label "Add lv2:FunctionPlugin and lv2:ConstantPlugin classes."
-			] , [
-				rdfs:label "Move lv2:AmplifierPlugin under lv2:DynamicsPlugin."
-			] , [
-				rdfs:label "Loosen domain of lv2:optionalFeature and lv2:requiredFeature (to allow re-use in extensions)."
-			] , [
-				rdfs:label "Add generic lv2:Resource and lv2:PluginBase classes."
-			] , [
-				rdfs:label "Fix definition of lv2:minimum etc. (used for values, not scale points)."
-			] , [
-				rdfs:label "More precisely define properties with OWL."
-			] , [
-				rdfs:label "Move project metadata to manifest."
-			] , [
-				rdfs:label "Add lv2:enumeration port property."
-			] , [
-				rdfs:label "Define run() pre-roll special case (sample_count == 0)."
-			]
-		]
-	] , [
-		doap:revision "3.0" ;
-		doap:created "2008-11-08" ;
-		doap:file-release <http://lv2plug.in/spec/lv2core-3.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Require that serialisations refer to ports by symbol rather than index."
-			] , [
-				rdfs:label "Minor stylistic changes to lv2.ttl."
-			] , [
-				rdfs:label "No header changes."
-			]
-		]
-	] , [
-		doap:revision "2.0" ;
-		doap:created "2008-02-10" ;
-		doap:file-release <http://lv2plug.in/spec/lv2core-2.0.tar.gz> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Initial release."
-			]
-		]
-	] .
diff --git a/sys/lv2/core/lv2core.meta.ttl b/sys/lv2/core/lv2core.meta.ttl
new file mode 100644
index 00000000..1dca8557
--- /dev/null
+++ b/sys/lv2/core/lv2core.meta.ttl
@@ -0,0 +1,906 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/lv2core>
+	a doap:Project ;
+	doap:license <http://opensource.org/licenses/isc> ;
+	doap:name "LV2" ;
+	doap:homepage <http://lv2plug.in> ;
+	doap:created "2004-04-21" ;
+	doap:shortdesc "An extensible open standard for audio plugins" ;
+	doap:programming-language "C" ;
+	doap:developer <http://plugin.org.uk/swh.xrdf#me> ,
+		<http://drobilla.net/drobilla#me> ;
+	doap:maintainer <http://drobilla.net/drobilla#me> ;
+	doap:release [
+		doap:revision "18.0" ;
+		doap:created "2020-04-26" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.18.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add lv2:Markdown datatype."
+			] , [
+				rdfs:label "Deprecate lv2:reportsLatency."
+			]
+		]
+	] , [
+		doap:revision "16.0" ;
+		doap:created "2019-02-03" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.16.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add lv2:MIDIPlugin class."
+			] , [
+				rdfs:label "Rework port restrictions so that presets can be validated."
+			]
+		]
+	] , [
+		doap:revision "14.0" ;
+		doap:created "2016-09-18" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.14.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add lv2_util.h with lv2_features_data() and lv2_features_query()."
+			] , [
+				rdfs:label "Add lv2:enabled designation."
+			]
+		]
+	] , [
+		doap:revision "12.4" ;
+		doap:created "2015-04-07" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.12.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Relax domain of lv2:minimum lv2:maximum and lv2:default so they can be used to describe properties/parameters as well."
+			] , [
+				rdfs:label "Add extern C and visibility attribute to LV2_SYMBOL_EXPORT."
+			] , [
+				rdfs:label "Add lv2:isSideChain port property."
+			]
+		]
+	] , [
+		doap:revision "12.2" ;
+		doap:created "2014-08-08" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.10.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Clarify lv2_descriptor() and lv2_lib_descriptor() documentation."
+			]
+		]
+	] , [
+		doap:revision "12.0" ;
+		doap:created "2014-01-04" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.8.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add lv2:prototype for property inheritance."
+			]
+		]
+	] , [
+		doap:revision "10.0" ;
+		doap:created "2013-02-17" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.4.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add lv2:EnvelopePlugin class."
+			] , [
+				rdfs:label "Add lv2:control for designating primary event-based control ports."
+			] , [
+				rdfs:label "Set range of lv2:designation to lv2:Designation."
+			] , [
+				rdfs:label "Make lv2:Parameter rdfs:subClassOf rdf:Property."
+			] , [
+				rdfs:label "Reserve minor version 0 for unstable development plugins."
+			]
+		]
+	] , [
+		doap:revision "8.2" ;
+		doap:created "2012-10-14" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Use consistent label style."
+			]
+		]
+	] , [
+		doap:revision "8.0" ;
+		doap:created "2012-04-17" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Fix LV2_SYMBOL_EXPORT and lv2_descriptor prototype for Windows."
+			] , [
+				rdfs:label "Add metadata concept of a designation, a channel or parameter description which can be assigned to ports for more intelligent use by hosts."
+			] , [
+				rdfs:label "Add new discovery API which allows libraries to read bundle files during discovery, makes library construction/destruction explicit, and adds extensibility to prevent future breakage."
+			] , [
+				rdfs:label "Relax the range of lv2:index so it can be used for things other than ports."
+			] , [
+				rdfs:label "Remove lv2:Resource, which turned out to be meaningless."
+			] , [
+				rdfs:label "Add lv2:CVPort."
+			] , [
+				rdfs:label "Merge with unified LV2 package."
+			]
+		]
+	] , [
+		doap:revision "6.0" ;
+		doap:created "2011-11-21" ;
+		doap:file-release <http://lv2plug.in/spec/lv2core-6.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Rename core.lv2 and lv2.ttl to lv2core.lv2 and lv2core.ttl to adhere to modern conventions."
+			] , [
+				rdfs:label "Add lv2:extensionData and lv2:ExtensionData for plugins to indicate that they support some URI for extension_data()."
+			] , [
+				rdfs:label "Remove lv2config in favour of the simple convention that specifications install headers to standard URI-based paths."
+			] , [
+				rdfs:label "Switch to the ISC license, a simple BSD-style license (with permission of all contributors to lv2.h and its ancestor, ladspa.h)."
+			] , [
+				rdfs:label "Make lv2core.ttl a valid OWL 2 DL ontology."
+			] , [
+				rdfs:label "Improve documentation."
+			]
+		]
+	] , [
+		doap:revision "4.0" ;
+		doap:created "2011-03-18" ;
+		doap:file-release <http://lv2plug.in/spec/lv2core-4.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Make doap:license suggested, but not required (for wrappers)."
+			] , [
+				rdfs:label "Define lv2:binary (MUST be in manifest.ttl)."
+			] , [
+				rdfs:label "Define lv2:minorVersion and lv2:microVersion (MUST be in manifest.ttl)."
+			] , [
+				rdfs:label "Define lv2:documentation and use it to document lv2core."
+			] , [
+				rdfs:label "Add lv2:FunctionPlugin and lv2:ConstantPlugin classes."
+			] , [
+				rdfs:label "Move lv2:AmplifierPlugin under lv2:DynamicsPlugin."
+			] , [
+				rdfs:label "Loosen domain of lv2:optionalFeature and lv2:requiredFeature (to allow re-use in extensions)."
+			] , [
+				rdfs:label "Add generic lv2:Resource and lv2:PluginBase classes."
+			] , [
+				rdfs:label "Fix definition of lv2:minimum etc. (used for values, not scale points)."
+			] , [
+				rdfs:label "More precisely define properties with OWL."
+			] , [
+				rdfs:label "Move project metadata to manifest."
+			] , [
+				rdfs:label "Add lv2:enumeration port property."
+			] , [
+				rdfs:label "Define run() pre-roll special case (sample_count == 0)."
+			]
+		]
+	] , [
+		doap:revision "3.0" ;
+		doap:created "2008-11-08" ;
+		doap:file-release <http://lv2plug.in/spec/lv2core-3.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Require that serialisations refer to ports by symbol rather than index."
+			] , [
+				rdfs:label "Minor stylistic changes to lv2.ttl."
+			] , [
+				rdfs:label "No header changes."
+			]
+		]
+	] , [
+		doap:revision "2.0" ;
+		doap:created "2008-02-10" ;
+		doap:file-release <http://lv2plug.in/spec/lv2core-2.0.tar.gz> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Initial release."
+			]
+		]
+	] ;
+	lv2:documentation """
+
+LV2 is an interface for writing audio plugins in C or compatible languages,
+which can be dynamically loaded into many _host_ applications.  This core
+specification is simple and minimal, but is designed so that _extensions_ can
+be defined to add more advanced features, making it possible to implement
+nearly any feature.
+
+LV2 maintains a strong distinction between code and data.  Plugin code is in a
+shared library, while data is in a companion data file written in
+[Turtle](https://www.w3.org/TR/turtle/).  Code, data, and any other resources
+(such as waveforms) are shipped together in a bundle directory.  The code
+contains only the executable portions of the plugin.  All other data is
+provided in the data file(s).  This makes plugin data flexible and extensible,
+and allows the host to do everything but run the plugin without loading or
+executing any code.  Among other advantages, this makes hosts more robust
+(broken plugins can't crash a host during discovery) and allows generic tools
+written in any language to work with LV2 data.  The LV2 specification itself is
+distributed in a similar way.
+
+An LV2 plugin library is suitable for dynamic loading (for example with
+`dlopen()`) and provides one or more plugin descriptors via `lv2_descriptor()`
+or `lv2_lib_descriptor()`.  These can be instantiated to create plugin
+instances, which can be run directly on data or connected together to perform
+advanced signal processing tasks.
+
+Plugins communicate via _ports_, which can transmit any type of data.  Data is
+processed by first connecting each port to a buffer, then repeatedly calling
+the `run()` method to process blocks of data.
+
+This core specification defines two types of port, equivalent to those in
+[LADSPA](http://www.ladspa.org/), lv2:ControlPort and lv2:AudioPort, as well as
+lv2:CVPort which has the same format as an audio port but is interpreted as
+non-audible control data.  Audio ports contain arrays with one `float` element
+per sample, allowing a block of audio to be processed in a single call to
+`run()`.  Control ports contain single `float` values, which are fixed and
+valid for the duration of the call to `run()`.  Thus the _control rate_ is
+determined by the block size, which is controlled by the host (and not
+necessarily constant).
+
+### Threading Rules
+
+To faciliate use in multi-threaded programs, LV2 functions are partitioned into
+several threading classes:
+
+| Discovery Class                  | Instantiation Class           | Audio Class                    |
+|----------------------------------|-------------------------------|------------------------------- |
+| lv2_descriptor()                 | LV2_Descriptor::instantiate() | LV2_Descriptor::run()          |
+| lv2_lib_descriptor()             | LV2_Descriptor::cleanup()     | LV2_Descriptor::connect_port() |
+| LV2_Descriptor::extension_data() | LV2_Descriptor::activate()    |                                |
+|                                  | LV2_Descriptor::deactivate()  |                                |
+
+Hosts MUST guarantee that:
+
+ * A function in any class is never called concurrently with another function
+   in that class.
+
+ * A _Discovery_ function is never called concurrently with any other fuction
+   in the same shared object file.
+
+ * An _Instantiation_ function for an instance is never called concurrently
+   with any other function for that instance.
+
+Any simultaneous calls that are not explicitly forbidden by these rules are
+allowed. For example, a host may call `run()` for two different plugin
+instances simultaneously.
+
+Plugin functions in any class MUST NOT manipulate any state which might affect
+other plugins or the host (beyond the contract of that function), for example
+by using non-reentrant global functions.
+
+Extensions to this specification which add new functions MUST declare in which
+of these classes the functions belong, define new classes for them, or
+otherwise precisely describe their threading rules.
+
+"""^^lv2:Markdown .
+
+lv2:Specification
+	lv2:documentation """
+
+An LV2 specification typically contains a vocabulary description, C headers to
+define an API, and any other resources that may be useful.  Specifications,
+like plugins, are distributed and installed as bundles so that hosts may
+discover them.
+
+"""^^lv2:Markdown .
+
+lv2:Markdown
+	lv2:documentation """
+
+This datatype is typically used for documentation in
+[Markdown](https://daringfireball.net/projects/markdown/syntax) syntax.
+
+Generally, documentation with this datatype should stay as close to readable
+plain text as possible, but may use core Markdown syntax for nicer
+presentation.  Documentation can assume that basic extensions like codehilite
+and tables are available.
+
+"""^^lv2:Markdown .
+
+lv2:documentation
+	lv2:documentation """
+
+Relates a Resource to extended documentation.
+
+LV2 specifications are documented using this property with an lv2:Markdown
+datatype.
+
+If the value has no explicit datatype, it is assumed to be a valid XHTML Basic
+1.1 fragment suitable for use as the content of the <code>&lt;body&gt;</code>
+element of a page.
+
+XHTML Basic is a W3C Recommendation which defines a simplified subset of XHTML
+intended to be reasonable to implement with limited resources, for exampe on
+embedded devices. See [XHTML Basic, Section
+3](http://www.w3.org/TR/xhtml-basic/#s_xhtmlmodules) for a list of valid tags.
+
+"""^^lv2:Markdown .
+
+lv2:PluginBase
+	lv2:documentation """
+
+An abstract plugin-like resource that may not actually be an LV2 plugin, for
+example that may not have a lv2:binary.  This is useful for describing things
+that share common structure with a plugin, but are not themselves an actul
+plugin, such as presets.
+
+"""^^lv2:Markdown .
+
+lv2:Plugin
+	lv2:documentation """
+
+To be discovered by hosts, plugins MUST explicitly have an rdf:type of lv2:Plugin
+in their bundle's manifest, for example:
+
+    :::turtle
+    &lt;http://example.org/my-plugin&gt; a lv2:Plugin .
+
+Plugins should have a doap:name property that is at most a few words in length
+using title capitalization, for example <q>Tape Delay Unit</q>.
+
+"""^^lv2:Markdown .
+
+lv2:PortBase
+	lv2:documentation """
+
+Similar to lv2:PluginBase, this is an abstract port-like resource that may not
+be a fully specified LV2 port.  For example, this is used for preset "ports"
+which do not specify an index.
+
+"""^^lv2:Markdown .
+
+lv2:Port
+	lv2:documentation """
+
+All LV2 port descriptions MUST have a rdf:type that is one of lv2:Port,
+lv2:InputPort or lv2:OutputPort.  Additionally, there MUST be at least one
+other rdf:type which more precisely describes type of the port, for example
+lv2:AudioPort.
+
+Hosts that do not support a specific port class MUST NOT instantiate the
+plugin, unless that port has the lv2:connectionOptional property set.
+
+A port has two identifiers: a (numeric) index, and a (textual) symbol.  The
+index can be used as an identifier at run-time, but persistent references to
+ports (for example in presets or save files) MUST use the symbol.  Only the
+symbol is guaranteed to refer to the same port on all plugins with a given URI,
+that is the index for a port may differ between plugin binaries.
+
+"""^^lv2:Markdown .
+
+lv2:AudioPort
+	lv2:documentation """
+
+Ports of this type are connected to a buffer of `float` audio samples, which
+the host guarantees have `sample_count` elements in any call to
+LV2_Descriptor::run().
+
+Audio samples are normalized between -1.0 and 1.0, though there is no
+requirement for samples to be strictly within this range.
+
+"""^^lv2:Markdown .
+
+lv2:CVPort
+	lv2:documentation """
+
+Ports of this type have the same buffer format as an lv2:AudioPort, except the
+buffer represents audio-rate control data rather than audio.  Like a
+lv2:ControlPort, a CV port SHOULD have properties describing its value, in
+particular lv2:minimum, lv2:maximum, and lv2:default.
+
+Hosts may present CV ports to users as controls in the same way as control
+ports.  Conceptually, aside from the buffer format, a CV port is the same as a
+control port, so hosts can use all the same properties and expectations.
+
+In particular, this port type does not imply any range, unit, or meaning for
+its values.  However, if there is no inherent unit to the values, for example
+if the port is used to modulate some other value, then plugins SHOULD use a
+normalized range, either from -1.0 to 1.0, or from 0.0 to 1.0.
+
+It is generally safe to connect an audio output to a CV input, but not
+vice-versa.  Hosts must take care to prevent data from a CVPort port from being
+used as audio.
+
+"""^^lv2:Markdown .
+
+lv2:project
+	lv2:documentation """
+
+This property provides a way to group plugins and/or related resources.  A
+project may have useful metadata common to all plugins (such as homepage,
+author, version history) which would be wasteful to list separately for each
+plugin.
+
+Grouping via projects also allows users to find plugins in hosts by project,
+which is often how they are remembered.  For this reason, a project that
+contains plugins SHOULD always have a doap:name.  It is also a good idea for
+each plugin and the project itself to have an lv2:symbol property, which allows
+nice quasi-global identifiers for plugins, for example `myproj.superamp` which
+can be useful for display or fast user entry.
+
+"""^^lv2:Markdown .
+
+lv2:prototype
+	lv2:documentation """
+
+This property can be used to <q>include</q> common properties in several
+descriptions, serving as a sort of template mechanism.  If a plugin has a
+prototype, then the host must load all the properties for the prototype as if
+they were properties of the plugin.  That is, if `:plug lv2:prototype :prot`,
+then for each triple `:prot p o`, the triple `:plug p o` should be loaded.
+
+This facility is useful for distributing data-only plugins that rely on a
+common binary, for example those where the internal state is loaded from some
+other file.  Such plugins can refer to a prototype in a template LV2 bundle
+which is installed by the corresponding software.
+
+"""^^lv2:Markdown .
+
+lv2:minorVersion
+	lv2:documentation """
+
+This, along with lv2:microVersion, is used to distinguish between different
+versions of the <q>same</q> resource, for example to load only the bundle with
+the most recent version of a plugin.  An LV2 version has a minor and micro
+number with the usual semantics:
+
+  * The minor version MUST be incremented when backwards (but not forwards)
+    compatible additions are made, for example the addition of a port to a
+    plugin.
+
+  * The micro version is incremented for changes which do not affect
+    compatibility at all, for example bug fixes or documentation updates.
+
+Note that there is deliberately no major version: all versions with the same
+URI are compatible by definition.  Replacing a resource with a newer version of
+that resource MUST NOT break anything.  If a change violates this rule, then
+the URI of the resource (which serves as the major version) MUST be changed.
+
+Plugins and extensions MUST adhere to at least the following rules:
+
+  * All versions of a plugin with a given URI MUST have the <q>same</q> set of
+    mandatory (not lv2:connectionOptional) ports with respect to lv2:symbol and
+    rdf:type.  In other words, every port on a particular version is guaranteed
+    to exist on a future version with same lv2:symbol and at least those
+    rdf:types.
+
+  * New ports MAY be added without changing the plugin URI if and only if they
+    are lv2:connectionOptional and the minor version is incremented.
+
+  * The minor version MUST be incremented if the index of any port (identified
+    by its symbol) is changed.
+
+  * All versions of a specification MUST be compatible in the sense that an
+    implementation of the new version can interoperate with an implementation
+    of any previous version.
+
+Anything that depends on a specific version of a plugin (including referencing
+ports by index) MUST refer to the plugin by both URI and version.  However,
+implementations should be tolerant where possible.
+
+When hosts discover several installed versions of a resource, they SHOULD warn
+the user and load only the most recent version.
+
+An odd minor _or_ micro version, or minor version zero, indicates that the
+resource is a development version.  Hosts and tools SHOULD clearly indicate
+this wherever appropriate.  Minor version zero is a special case for
+pre-release development of plugins, or experimental plugins that are not
+intended for stable use at all.  Hosts SHOULD NOT expect such a plugin to
+remain compatible with any future version.  Where feasible, hosts SHOULD NOT
+expose such plugins to users by default, but may provide an option to display
+them.
+
+"""^^lv2:Markdown .
+
+lv2:microVersion
+	lv2:documentation """
+
+Releases of plugins and extensions MUST be explicitly versioned.  Correct
+version numbers MUST always be maintained for any versioned resource that is
+published. For example, after a release, if a change is made in the development
+version in source control, the micro version MUST be incremented (to an odd
+number) to distinguish this modified version from the previous release.
+
+This property describes half of a resource version. For detailed documentation
+on LV2 resource versioning, see lv2:minorVersion.
+
+"""^^lv2:Markdown .
+
+lv2:binary
+	lv2:documentation """
+
+The value of this property must be the URI of a shared library object,
+typically in the same bundle as the data file which contains this property.
+The actual type of the library is platform specific.
+
+This is a required property of a lv2:Plugin which MUST be included in the
+bundle's `manifest.ttl` file.  The lv2:binary of a lv2:Plugin is the shared
+object containing the lv2_descriptor() or lv2_lib_descriptor() function.  This
+probably may also be used similarly by extensions to relate other resources to
+their implementations (it is not implied that a lv2:binary on an arbitrary
+resource is an LV2 plugin library).
+
+"""^^lv2:Markdown .
+
+lv2:appliesTo
+	lv2:documentation """
+
+This is primarily intended for discovery purposes: bundles that describe
+resources that work with particular plugins (like presets or user interfaces)
+SHOULD specify this in their `manifest.ttl` so the host can associate them with
+the correct plugin.  For example:
+
+    :::turtle
+    &lt;thing&gt;
+        a             ext:Thing ;
+        lv2:appliesTo &lt;plugin&gt; ;
+        rdfs:seeAlso  &lt;thing.ttl&gt; .
+
+Using this pattern is preferable for large amounts of data, since the host may
+choose whether/when to load the data.
+
+"""^^lv2:Markdown .
+
+lv2:Symbol
+	lv2:documentation """
+
+The first character of a symbol must be one of `_`, `a-z` or `A-Z`, and
+subsequent characters may additionally be `0-9`.  This is, among other things,
+a valid C identifier, and generally compatible in most contexts which have
+restrictions on string identifiers, such as file paths.
+
+"""^^lv2:Markdown .
+
+lv2:symbol
+	lv2:documentation """
+
+The value of this property MUST be a valid lv2:Symbol, and MUST NOT have a
+language tag.
+
+A symbol is a unique identifier with respect to the parent, for example a
+port's symbol is a unique identifiers with respect to its plugin.  The plugin
+author MUST change the plugin URI if any port symbol is changed or removed.
+
+"""^^lv2:Markdown .
+
+lv2:name
+	lv2:documentation """
+
+Unlike lv2:symbol, this is unrestricted, may be translated, and is not relevant
+for compatibility.  The name is not necessarily unique and MUST NOT be used as
+an identifier.
+
+"""^^lv2:Markdown .
+
+lv2:shortName
+	lv2:documentation """
+
+This is the same as lv2:name, with the additional requirement that the value is
+shorter than 16 characters.
+
+"""^^lv2:Markdown .
+
+lv2:Designation
+	lv2:documentation """
+
+A designation is metadata that describes the meaning or role of something.  By
+assigning a designation to a port using lv2:designation, the port's content
+becomes meaningful and can be used more intelligently by the host.
+
+"""^^lv2:Markdown .
+
+lv2:Channel
+	lv2:documentation """
+
+A specific channel, for example the <q>left</q> channel of a stereo stream.  A
+channel may be audio, or another type such as a MIDI control stream.
+
+"""^^lv2:Markdown .
+
+lv2:Parameter
+	lv2:documentation """
+
+A parameter is a designation for a control.
+
+A parameter defines the meaning of a control, not the method of conveying its
+value.  For example, a parameter could be controlled via a lv2:ControlPort,
+messages, or both.
+
+A lv2:ControlPort can be associated with a parameter using lv2:designation.
+
+"""^^lv2:Markdown .
+
+lv2:designation
+	lv2:documentation """
+
+This property is used to give a port's contents a well-defined meaning.  For
+example, if a port has the designation `eg:gain`, then the value of that port
+represents the `eg:gain` of the plugin instance.
+
+Ports should be given designations whenever possible, particularly if a
+suitable designation is already defined.  This allows the host to act more
+intelligently and provide a more effective user interface.  For example, if the
+plugin has a BPM parameter, the host may automatically set that parameter to
+the current tempo.
+
+"""^^lv2:Markdown .
+
+lv2:freeWheeling
+	lv2:documentation """
+
+If true, this means that all processing is happening as quickly as possible,
+not in real-time.  When free-wheeling there is no relationship between the
+passage of real wall-clock time and the passage of time in the data being
+processed.
+
+"""^^lv2:Markdown .
+
+lv2:enabled
+	lv2:documentation """
+
+If this value is greater than zero, the plugin processes normally.  If this
+value is zero, the plugin is expected to bypass all signals unmodified.  The
+plugin must provide a click-free transition between the enabled and disabled
+(bypassed) states.
+
+Values less than zero are reserved for future use (such as click-free
+insertion/removal of latent plugins), and should be treated like zero
+(bypassed) by current implementations.
+
+"""^^lv2:Markdown .
+
+lv2:control
+	lv2:documentation """
+
+This should be used as the lv2:designation of ports that are used to send
+commands and receive responses.  Typically this will be an event port that
+supports some protocol, for example MIDI or LV2 Atoms.
+
+"""^^lv2:Markdown .
+
+lv2:Point
+	lv2:documentation """
+
+  * A Point MUST have at least one rdfs:label which is a string.
+
+  * A Point MUST have exactly one rdf:value with a type that is compatible with
+    the type of the corresponding Port.
+
+"""^^lv2:Markdown .
+
+lv2:default
+	lv2:documentation """
+
+The host SHOULD set the port to this value initially, and in any situation
+where the port value should be cleared or reset.
+
+"""^^lv2:Markdown .
+
+lv2:minimum
+	lv2:documentation """
+
+This is a soft limit: the plugin is required to gracefully accept all values in
+the range of a port's data type.
+
+"""^^lv2:Markdown .
+
+lv2:maximum
+	lv2:documentation """
+
+This is a soft limit: the plugin is required to gracefully accept all values in
+the range of a port's data type.
+
+"""^^lv2:Markdown .
+
+lv2:optionalFeature
+	lv2:documentation """
+
+To support this feature, the host MUST pass its URI and any additional data to
+the plugin in LV2_Descriptor::instantiate().
+
+The plugin MUST NOT fail to instantiate if an optional feature is not supported
+by the host.
+
+"""^^lv2:Markdown .
+
+lv2:requiredFeature
+	lv2:documentation """
+
+To support this feature, the host MUST pass its URI and any additional data to
+the plugin in LV2_Descriptor::instantiate().
+
+The host MUST check this property before attempting to instantiate a plugin,
+and not attempt to instantiate plugins which require features it does not
+support.  The plugin MUST fail to instantiate if a required feature is not
+supported by the host.  Note that these rules are intentionally redundant for
+resilience: neither host nor plugin should assume that the other does not
+violate them.
+
+"""^^lv2:Markdown .
+
+lv2:ExtensionData
+	lv2:documentation """
+
+This is additional data that a plugin may return from
+LV2_Descriptor::extension_data().  This is generally used to add APIs to extend
+that defined by LV2_Descriptor.
+
+"""^^lv2:Markdown .
+
+lv2:extensionData
+	lv2:documentation """
+
+If a plugin has a value for this property, it must be a URI that defines the
+extension data.  The plugin should return the appropriate data when
+LV2_Descriptor::extension_data() is called with that URI as a parameter.
+
+"""^^lv2:Markdown .
+
+lv2:isLive
+	lv2:documentation """
+
+This feature is for plugins that have time-sensitive internals, for example
+communicating in real time over a socket.  It indicates to the host that its
+input and output must not be cached or subject to significant latency, and that
+calls to LV2_Descriptor::run() should be made at a rate that roughly
+corresponds to wall clock time (according to the `sample_count` parameter).
+
+Note that this feature is not related to <q>hard real-time</q> execution
+requirements (see lv2:hardRTCapable).
+
+"""^^lv2:Markdown .
+
+lv2:inPlaceBroken
+	lv2:documentation """
+
+This feature indicates that the plugin may not work correctly if the host
+elects to use the same data location for both input and output.  Plugins that
+will fail to work correctly if ANY input port is connected to the same location
+as ANY output port MUST require this feature.  Doing so should be avoided
+whenever possible since it prevents hosts from running the plugin on data
+<q>in-place</q>.
+
+"""^^lv2:Markdown .
+
+lv2:hardRTCapable
+	lv2:documentation """
+
+This feature indicates that the plugin is capable of running in a <q>hard
+real-time</q> environment.  This should be the case for most audio processors,
+so most plugins are expected to have this feature.
+
+To support this feature, plugins MUST adhere to the following in all of their
+audio class functions (LV2_Descriptor::run() and
+LV2_Descriptor::connect_port()):
+
+  * There is no use of `malloc()`, `free()` or any other heap memory management
+    functions.
+
+  * There is no use of any library functions which do not adhere to these
+    rules.  The plugin may assume that the standard C math library functions
+    are safe.
+
+  * There is no access to files, devices, pipes, sockets, system calls, or any
+    other mechanism that might result in the process or thread blocking.
+
+  * The maximum amount of time for a `run()` call is bounded by some expression
+    of the form `A + B * sample_count`, where `A` and `B` are platform specific
+    constants.  Note that this bound does not depend on input signals or plugin
+    state.
+
+"""^^lv2:Markdown .
+
+lv2:portProperty
+	lv2:documentation """
+
+States that a port has a particular lv2:PortProperty.  This may be ignored
+without catastrophic effects, though it may be useful, for example to provide a
+sensible user interface for the port.
+
+"""^^lv2:Markdown .
+
+lv2:connectionOptional
+	lv2:documentation """
+
+This property means that the port does not have to be connected to valid data
+by the host.  To leave a port <q>unconnected</q>, the host MUST explicitly
+connect the port to `NULL`.
+
+"""^^lv2:Markdown .
+
+lv2:reportsLatency
+	lv2:documentation """
+
+This property indicates that the port is used to express the processing latency
+incurred by the plugin, expressed in samples.  The latency may be affected by
+the current sample rate, plugin settings, or other factors, and may be changed
+by the plugin at any time.  Where the latency is frequency dependent the plugin
+may choose any appropriate value.  If a plugin introduces latency it MUST
+provide EXACTLY ONE port with this property set.  In <q>fuzzy</q> cases the
+value should be the most reasonable one based on user expectation of
+input/output alignment.  For example, musical delay plugins should not report
+their delay as latency, since it is an intentional effect that the host should
+not compensate for.
+
+This property is deprecated, use a lv2:designation of lv2:latency instead,
+following the same rules as above:
+
+    :::turtle
+	<http://example.org/plugin>
+		lv2:port [
+			a lv2:OutputPort , lv2:ControlPort ;
+			lv2:designation lv2:latency ;
+			lv2:symbol "latency" ;
+        ]
+
+"""^^lv2:Markdown .
+
+lv2:toggled
+	lv2:documentation """
+
+Indicates that the data item should be considered a boolean toggle.  Data less
+than or equal to zero should be considered <q>off</q> or <q>false</q>, and data
+above zero should be considered <q>on</q> or <q>true</q>.
+
+"""^^lv2:Markdown .
+
+lv2:sampleRate
+	lv2:documentation """
+
+Indicates that any specified bounds should be interpreted as multiples of the
+sample rate.  For example, a frequency range from 0 Hz to the Nyquist frequency
+(half the sample rate) can be specified by using this property with lv2:minimum
+0.0 and lv2:maximum 0.5.  Hosts that support bounds at all MUST support this
+property.
+
+"""^^lv2:Markdown .
+
+lv2:integer
+	lv2:documentation """
+
+Indicates that all the reasonable values for a port are integers.  For such
+ports, a user interface should provide a stepped control that only allows
+choosing integer values.
+
+Note that this is only a hint, and that the plugin MUST operate reasonably even
+if such a port has a non-integer value.
+
+"""^^lv2:Markdown .
+
+lv2:enumeration
+	lv2:documentation """
+
+Indicates that all the rasonable values for a port are defined by
+lv2:scalePoint properties.  For such ports, a user interface should provide a selector that allows the user to choose any of the scale point values by name.  It is recommended to show the value as well if possible.
+
+Note that this is only a hint, and that the plugin MUST operate reasonably even
+if such a port has a value that does not correspond to a scale point.
+
+"""^^lv2:Markdown .
+
+lv2:isSideChain
+	lv2:documentation """
+
+Indicates that a port is a <q>sidechain</q>, which affects the output somehow
+but should not be considered a part of the main signal chain.  Sidechain ports
+SHOULD be lv2:connectionOptional, and may be ignored by hosts.
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/core/lv2core.ttl b/sys/lv2/core/lv2core.ttl
index b6e5a7ce..f5836c6e 100644
--- a/sys/lv2/core/lv2core.ttl
+++ b/sys/lv2/core/lv2core.ttl
@@ -1,274 +1,122 @@
 @prefix doap: <http://usefulinc.com/ns/doap#> .
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
-@prefix owl:  <http://www.w3.org/2002/07/owl#> .
-@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+
+<http://lv2plug.in/ns/lv2core>
+	a owl:Ontology ;
+	rdfs:label "LV2" ;
+	rdfs:comment "An extensible open standard for audio plugins." ;
+	rdfs:seeAlso <lv2.h> ,
+		<lv2_util.h> ,
+		<lv2core.meta.ttl> .
 
 lv2:Specification
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf doap:Project ;
-	lv2:documentation """
-<p>An LV2 specification (i.e. this specification, or an LV2 extension).</p>
+	rdfs:label "Specification" ;
+	rdfs:comment "An LV2 specifiation." .
 
-<p>Specification data, like plugin data, is distributed in bundles
-so hosts may discover <em>all</em> present LV2 data.</p>
-""" .
+lv2:Markdown
+	a rdfs:Datatype ;
+	owl:onDatatype xsd:string ;
+	rdfs:label "Markdown" ;
+	rdfs:comment "A string in Markdown syntax." .
 
 lv2:documentation
 	a rdf:Property ,
 		owl:AnnotationProperty ;
 	rdfs:range rdfs:Literal ;
 	rdfs:label "documentation" ;
-	rdfs:seeAlso <http://www.w3.org/TR/xhtml-basic/> ;
-	lv2:documentation """
-<p>Relates a Resource to documentation markup. The value of this property
-MUST be a string literal which is a valid XHTML Basic 1.1 fragment suitable
-for use as the content of the &lt;body&gt; element. This can be used by
-hosts to provide rich online documentation or by tools to generate external
-documentation pages. The standard language tagging facility of RDF can be
-used to provide multi-lingual documentation.</p>
-<p>XHTML Basic is a W3C Recommendation which defines a basic subset of XHTML
-intended to be reasonable to implement with limited resources (e.g. on embedded
-devices). See <a href="http://www.w3.org/TR/xhtml-basic/#s_xhtmlmodules"
->XHTML Basic, Section 3</a> for a list of legal tags.</p>
-""" .
-
-<http://lv2plug.in/ns/lv2core>
-	a owl:Ontology ;
-	rdfs:seeAlso <lv2.h> ,
-		<lv2_util.h> ,
-		<lv2core.doap.ttl> ;
-	lv2:documentation """
-<p>LV2 is an interface for writing audio processors, or <q>plugins</q>, in
-C/C++ which can be dynamically loaded into many applications, or <q>hosts</q>.
-This <q>core</q> specification is simple and minimal, but is designed so that
-<q>extensions</q> can be defined to add more advanced features, making it
-possibly to implement nearly any feature imaginable.</p>
-
-<p>LV2 maintains a strong distinction between <q>code</q> and <q>data</q>.
-Plugin code is in a shared library, while data is in a companion data file
-written in <a href="http://www.w3.org/TeamSubmission/turtle/">Turtle</a>.
-Code, data, and any other resources (e.g. waveforms) are shipped together in a
-<q>bundle</q> directory.  The code contains only the executable portions of the
-plugin which inherently <em>must</em> be written in code.  All other data is
-provided in the data file(s).  This makes plugin data flexible and extensible,
-and allows the host to do everything but run the plugin without loading or
-executing any code.  Among other advantages, this makes hosts more robust
-(broken plugins can't crash a host during discovery) and allows generic tools
-and non-C programs to work with LV2 data.  LV2 itself and extensions are
-distributed in a similar way.</p>
-
-<p>An LV2 plugin library is suitable for dynamic loading (e.g. via
-<code>dlopen()</code>) and provides one or more plugin descriptors via
-<code>lv2_descriptor()</code> or <code>lv2_lib_descriptor()</code>.  These can
-be instantiated to create plugin <q>instances</q>, which can be run directly on
-data or connected together to perform advanced signal processing tasks.</p>
-
-<p>Plugins communicate via <q>ports</q>, which can transmit any type of data.
-Data is processed by first <q>connecting</q> each port to a buffer, then
-repeatedly calling a plugin's <code>run()</code> method to process blocks of
-data.</p>
-
-<p>This core specification defines two types of port, equivalent to those in <a
-href="http://www.ladspa.org/">LADSPA</a>: lv2:ControlPort and lv2:AudioPort.
-Audio ports contain arrays with one <code>float</code> element per sample,
-allowing a block of audio to be processed in a single call to
-<code>run()</code>.  Control ports contain single <code>float</code> values,
-which are fixed and valid for the duration of the call to <code>run()</code>.
-Thus the <q>control rate</q> is determined by the block size, which is
-controlled by the host (and not necessarily constant).</p>
-
-<h3>Threading Rules</h3>
-
-<p>To faciliate use in multi-threaded programs, LV2 functions are partitioned
-into several threading classes:</p>
-
-<table>
-<tr><th>Discovery Class</th>
-    <th>Instantiation Class</th>
-    <th>Audio Class</th></tr>
-<tr><td>lv2_descriptor()</td>
-    <td>LV2_Descriptor::instantiate()</td>
-    <td>LV2_Descriptor::run()</td></tr>
-<tr><td>lv2_lib_descriptor()</td>
-    <td>LV2_Descriptor::cleanup()</td>
-    <td>LV2_Descriptor::connect_port()</td></tr>
-<tr><td>LV2_Descriptor::extension_data()</td>
-    <td>LV2_Descriptor::activate()</td><td></td></tr>
-<tr><td></td><td>LV2_Descriptor::deactivate()</td><td></td></tr>
-</table>
-
-<p>The rules that hosts MUST follow are:</p>
-<ul>
-<li>When any function is running for a plugin instance,
-no other function in the same class may run for that instance.</li>
-<li>When a <em>Discovery</em> function is running,
-no other functions in the same shared object file may run.</li>
-<li>When an <em>Instantiation</em> function is running for a plugin instance,
-no other functions for that instance may run.</li>
-</ul>
-
-<p>Any simultaneous calls that are not explicitly forbidden by these rules are
-allowed. For example, a host may call <code>run()</code> for two different
-plugin instances simultaneously.</p>
-
-<p>Plugin functions in any class MUST NOT manipulate any state which might
-affect other plugin or host code, e.g. by using non-reentrant global
-functions.</p>
-
-<p>Extensions to this specification which add new functions MUST declare in
-which of these classes the functions belong, define new classes for them, or
-otherwise precisely describe their threading rules.</p>
-""" .
+	rdfs:comment "Extended documentation." ;
+	rdfs:seeAlso <http://www.w3.org/TR/xhtml-basic/> .
 
 lv2:PluginBase
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:label "Plugin Base" ;
-	lv2:documentation """
-<p>An abstract plugin-like resource that MAY not actually be an LV2 plugin
-(e.g. may not actually have a plugin binary).</p>
-
-<p>PluginBase SHOULD be used as a base type for any resource that may have
-ports or otherwise mimic the structure of a Plugin (e.g. a preset), since
-hosts and other tools already <q>understand</q> this structure.</p>
-""" .
+	rdfs:comment "Base class for a plugin-like resource." .
 
 lv2:Plugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:PluginBase ;
 	rdfs:label "Plugin" ;
+	rdfs:comment "An LV2 plugin." ;
 	rdfs:subClassOf [
 		a owl:Restriction ;
 		owl:onProperty doap:name ;
 		owl:someValuesFrom rdf:PlainLiteral ;
-		rdfs:comment "A plugin MUST have at least one untranslated doap:name." ;
+		rdfs:comment "A plugin MUST have at least one untranslated doap:name."
 	] , [
 		a owl:Restriction ;
 		owl:onProperty lv2:port ;
 		owl:allValuesFrom lv2:Port ;
-		rdfs:comment "All ports on a plugin MUST be fully specified lv2:Port instances." ;
-	] ;
-	lv2:documentation """
-<p>The class which represents an LV2 plugin.</p>
-
-<p>To be discovered by hosts, plugins MUST explicitly have rdf:type lv2:Plugin
-listed in their bundle's manifest, e.g.:</p>
-<pre class="turtle-code">
-&lt;http://example.org/my-plugin&gt; a lv2:Plugin .
-</pre>
-
-<p>Plugins SHOULD have a doap:license property whenever possible. The doap:name
-property should be at most a few words in length using title capitalization,
-e.g. <q>Tape Delay Unit</q>. Use doap:shortdesc or doap:description for more
-detailed descriptions.</p>
-""" .
+		rdfs:comment "All ports on a plugin MUST be fully specified lv2:Port instances."
+	] .
 
 lv2:PortBase
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:label "Port Base" ;
+	rdfs:comment "Base class for a port-like resource." ;
 	rdfs:subClassOf [
 		a owl:Restriction ;
 		owl:onProperty lv2:symbol ;
 		owl:cardinality 1 ;
-		rdfs:comment "A port MUST have exactly one lv2:symbol." ;
-	] ;
-	lv2:documentation """
-<p>Similar to lv2:PluginBase, an abstract port-like resource that MAY not
-actually be a fully specified LV2 port.  For example, this is used for preset
-"ports" which do not specify an index.</p>
-""" .
+		rdfs:comment "A port MUST have exactly one lv2:symbol."
+	] .
 
 lv2:Port
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:label "Port" ;
-	rdfs:subClassOf lv2:PortBase ;
-	rdfs:subClassOf [
+	rdfs:comment "An LV2 plugin port." ;
+	rdfs:subClassOf lv2:PortBase ,
+	[
 		a owl:Restriction ;
 		owl:onProperty lv2:name ;
 		owl:minCardinality 1 ;
 		rdfs:comment "A port MUST have at least one lv2:name."
-	] ;
-	lv2:documentation """
-<p>The class which represents an LV2 port.</p>
-
-<p>All LV2 port descriptions MUST have a rdf:type that is one of lv2:Port
-lv2:InputPort or lv2:OutputPort. Additionally there MUST be at least one other
-rdf:type which more precisely describes type of the port
-(e.g. lv2:AudioPort).</p>
-
-<p>Hosts that do not support a specific port class MUST NOT instantiate the
-plugin, unless that port has the connectionOptional property set (in which case
-the host can simply <q>connect</q> that port to NULL). If a host is interested
-in plugins to insert in a certain signal path (e.g. stereo audio), it SHOULD
-consider all the classes of a port to determine which ports are most suitable
-for connection (e.g. by ignoring ports with additional classes the host does
-not recognize).</p>
-
-<p>A port has two identifiers: a (numeric) index, and a (textual) symbol.
-The index can be used as an identifier at run-time, but persistent references
-to ports (e.g. in a saved preset) MUST use the symbol. A symbol is guaranteed
-to refer to the same port on all plugins with a given URI. An index does NOT
-necessarily refer to the same port on all plugins with a given URI (i.e. the
-index for a port may differ between plugin binaries).</p>
-""" .
+	] .
 
 lv2:InputPort
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:Port ;
 	rdfs:label "Input Port" ;
-	rdfs:comment """Ports of this type will be connected to a pointer to some value, which will be read by the plugin during their run method.""" .
+	rdfs:comment "A port connected to constant data which is read during `run()`." .
 
 lv2:OutputPort
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:Port ;
 	rdfs:label "Output Port" ;
-	rdfs:comment """Ports of this type will be connected to a pointer to some value, which will be written to by the plugin during their run method.""" .
+	rdfs:comment "A port connected to data which is written during `run()`." .
 
 lv2:ControlPort
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:Port ;
 	rdfs:label "Control Port" ;
-	lv2:documentation """
-<p>Ports of this type will be connected to a pointer to a single value of C
-type <code>float</code>.</p>
-
-""" .
+	rdfs:comment "A port connected to a single `float`." .
 
 lv2:AudioPort
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:Port ;
 	rdfs:label "Audio Port" ;
-	lv2:documentation """
-<p>Ports of this type will be connected to an array of length sample_count
-with elements of C type <code>float</code>.</p>
-""" .
+	rdfs:comment "A port connected to an array of float audio samples." .
 
 lv2:CVPort
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:Port ;
 	rdfs:label "CV Port" ;
-	lv2:documentation """
-<p>Ports of this type have the same buffer format as an lv2:AudioPort, except
-the buffer represents audio-rate control data rather than audio.  Like an
-lv2:ControlPort, a CVPort SHOULD have properties describing its value
-(e.g. lv2:minimum, lv2:maximum, and lv2:default), and may be presented to the
-user as a control.</p>
-
-<p>It is generally safe to connect an audio output to a CV input, but not vice
-versa.  Hosts SHOULD take care to prevent data from a CVPort port from being
-used as audio.</p>
-""" .
+	rdfs:comment "A port connected to an array of float control values." .
 
 lv2:port
 	a rdf:Property ,
@@ -283,162 +131,41 @@ lv2:project
 		owl:ObjectProperty ;
 	rdfs:range doap:Project ;
 	rdfs:label "project" ;
-	lv2:documentation """
-<p>The project this is a component of.</p>
-
-<p>This property provides a way to group plugins and/or related resources.  A
-project may have useful metadata common to all plugins (such as homepage,
-author, version history) which would be wasteful to list separately for each
-plugin.</p>
-
-<p>Grouping via projects also allows users to find plugins in hosts by project,
-which is often how they are remembered.  For this reason, a project that
-contains plugins SHOULD always have a doap:name.  It is also a good idea for
-each plugin and the project itself to have an lv2:symbol property, which allows
-nice quasi-global identifiers for plugins, e.g. <q>myproj.superamp</q> which
-can be useful for display or fast user entry.</p>
-""" .
+	rdfs:comment "The project this is a part of." .
 
 lv2:prototype
 	a rdf:Property ,
 		owl:ObjectProperty ;
 	rdfs:label "prototype" ;
-	lv2:documentation """
-<p>The prototype to inherit properties from.</p>
-
-<p>This property can be used to <q>include</q> common properties in several
-descriptions.  If a plugin has a prototype, then the host must load all the
-properties for the prototype as if they were properties of the plugin.  That
-is, if <code>:plug lv2:prototype :prot</code>, then for each triple <code>:prot
-p o</code>, the triple <code>:plug p o</code> should be loaded.</p>
-
-<p>This facility is useful for distributing text-only plugins that rely on a
-common binary, by referring to a prototype which is installed by the
-corresponding software, along with the plugin binary.</p>
-""" .
+	rdfs:comment "The prototype to inherit properties from." .
 
 lv2:minorVersion
 	a rdf:Property ,
 		owl:DatatypeProperty ;
 	rdfs:range xsd:nonNegativeInteger ;
 	rdfs:label "minor version" ;
-	lv2:documentation """
-<p>The minor version of an LV2 Resource.  This, along with lv2:microVersion, is
-used to distinguish between different versions of the <q>same</q> resource,
-e.g. to load only the bundle with the most recent version of a plugin.  An LV2
-version has a minor and micro number with the usual semantics:</p>
-
-<ul>
-<li>The minor version MUST be incremented when backwards (but not
-forwards) compatible additions are made, e.g. the addition of a port to a
-plugin.</li>
-
-<li>The micro version is incremented for changes which do not affect
-compatibility at all, e.g. bug fixes or documentation updates.</li>
-</ul>
-
-<p>Note there is deliberately no major version; all versions with the same URI
-are compatible by definition.  Replacing a resource with a newer version of
-that resource MUST NOT break anything.  If a change violates this rule, then
-the URI of the resource (which serves as the major version) MUST be
-changed.</p>
-
-<p>Plugins and extensions MUST adhere to at least the following rules:</p>
-<ul>
-<li>All versions of a plugin with a given URI MUST have the <q>same</q> set of
-mandatory (i.e. not lv2:connectionOptional) ports with respect to lv2:symbol
-and rdf:type.  In other words, every port on a particular version is guaranteed
-to exist on a future version with same lv2:symbol and at least those
-rdf:types.</li>
-
-<li>New ports MAY be added without changing the plugin URI if and only if they
-are lv2:connectionOptional and the minor version is incremented.</li>
-
-<li>The minor version MUST be incremented if the index of any port (identified
-by its symbol) is changed.</li>
-
-<li>All versions of a specification MUST be compatible in the sense that an
-implementation of the new version can interoperate with an implementation of
-any previous version.</li>
-</ul>
-
-<p>Anything that depends on a specific version of a plugin (e.g. a
-serialisation that references ports by index) MUST refer to the plugin by both
-URI and version.  However, implementations should be tolerant and extensions
-should be designed such that there is no need to do this (e.g. indices should
-only be meaningful for a particular plugin <em>instance</em> at run-time).</p>
-
-<p>When hosts discover several installed versions of a resource, they SHOULD
-warn the user and load only the most recent version.</p>
-
-<p>An odd minor <em>or</em> micro version, or minor version zero, indicates
-that the resource is a development version.  Hosts and tools SHOULD clearly
-indicate this wherever appropriate.  Minor version zero is a special case for
-pre-release development of plugins, or experimental plugins that are not
-intended for stable use at all.  Hosts SHOULD NOT expect such a plugin to
-remain compatible with any future version.  If possible, hosts SHOULD hide such
-plugins from users unless an <q>experimental</q> option is enabled.</p>
-""" .
+	rdfs:comment "The minor version of this resource." .
 
 lv2:microVersion
 	a rdf:Property ,
 		owl:DatatypeProperty ;
 	rdfs:range xsd:nonNegativeInteger ;
 	rdfs:label "micro version" ;
-	lv2:documentation """
-<p>The micro component of a Resource's version.</p>
-
-<p>Releases of plugins and extensions MUST be explicitly versioned. Correct
-version numbers MUST always be maintained for any versioned resource that is
-published. For example, after a release, if a change is made in the development
-version in source control, the micro version MUST be incremented (to an odd
-number) to distinguish this modified version from the previous release.</p>
-
-<p>This property describes half of a resource version. For detailed
-documentation on LV2 resource versioning, see lv2:minorVersion.</p>
-""" .
+	rdfs:comment "The micro version of this resource." .
 
 lv2:binary
 	a rdf:Property ,
 		owl:ObjectProperty ;
 	rdfs:range owl:Thing ;
 	rdfs:label "binary" ;
-	lv2:documentation """
-<p>The binary of an LV2 resource. The value of this property must be a URI that
-resolves to a shared library object (the actual type of this library is system
-specific).</p>
-
-<p>This is a required property of a Plugin which MUST be included in the
-bundle's manifest.ttl file. The lv2:binary of an lv2:Plugin is the shared
-object containing the <code>lv2_descriptor()</code> or
-<code>lv2_lib_descriptor()</code> function which can be used to access the
-descriptor for that plugin. This property may be used similarly by extensions
-to relate other resources to their implementations.</p>
-""" .
+	rdfs:comment "The binary of this resource." .
 
 lv2:appliesTo
 	a rdf:Property ,
 		owl:ObjectProperty ;
 	rdfs:range lv2:Plugin ;
 	rdfs:label "applies to" ;
-	lv2:documentation """
-<p>Specifies that a resource is related to a plugin. This is primarily intended
-for discovery purposes: bundles that describe resources that work with
-particular plugins (e.g. presets or user interfaces) SHOULD use this predicate
-in manifest.ttl to relate the resource to the applicable
-plugin(s), e.g.:</p>
-<pre class="turtle-code">
-&lt;thing&gt;
-    a             ext:Thing ;
-    lv2:appliesTo &lt;plugin&gt; ;
-    rdfs:seeAlso  &lt;thing.ttl&gt; .
-</pre>
-
-<p>Particularly for large amounts of data, this is preferable to
-extending the plugin description with rdfs:seeAlso since the host may choose
-if/when to load the data, knowing that it describes an additional resource and
-not the plugin itself.</p>
-""" .
+	rdfs:comment "The plugin this resource is related to." .
 
 lv2:index
 	a rdf:Property ,
@@ -456,9 +183,8 @@ lv2:Symbol
 			xsd:pattern "[_a-zA-Z][_a-zA-Z0-9]*"
 		]
 	) ;
-	rdfs:comment """A short restricted name used as a machine and human readable identifier.
-
-The first character must be one of _, a-z or A-Z and subsequent characters can be from _, a-z, A-Z and 0-9.  This is a valid C identifier, and compatible in most other contexts with restricted string identifiers (e.g. file paths).""" .
+	rdfs:label "Symbol" ;
+	rdfs:comment "A short restricted name used as a strong identifier." .
 
 lv2:symbol
 	a rdf:Property ,
@@ -467,54 +193,35 @@ lv2:symbol
 	rdfs:label "symbol" ;
 	rdfs:range lv2:Symbol ,
 		rdf:PlainLiteral ;
-	lv2:documentation """
-<p>The value of this property MUST conform to the rules for lv2:Symbol, and
-MUST NOT have a language tag.</p>
-
-<p>A symbol is a unique identifier with respect to the parent (e.g. a port's
-symbol is a unique identifier with respect to its plugin).  The plugin author
-MUST change the plugin URI if a port symbol is changed or removed.</p>
-""" .
+	rdfs:comment "The symbol that identifies this resource in the context of its parent." .
 
 lv2:name
 	a rdf:Property ,
 		owl:DatatypeProperty ;
 	rdfs:label "name" ;
 	rdfs:range xsd:string ;
-	rdfs:comment """A display name for labeling in a user interface.  Unlike lv2:symbol this is unrestricted and may be translated.  The lv2:name MUST NOT be used as an identifier.
-
-This property is required for Ports, but MUST NOT be used by the host for port identification. The plugin author may change the values of this property without changing the Plugin URI.""" .
+	rdfs:comment "A display name for labeling in a user interface." .
 
 lv2:shortName
 	a rdf:Property ,
 		owl:DatatypeProperty ;
 	rdfs:label "short name" ;
 	rdfs:range xsd:string ;
-	rdfs:comment """A short display name for labeling in a user interface.
-
-The same rules for port names apply here, with the exception that short names should not be longer than 16 characters.""" .
+	rdfs:comment "A short display name for labeling in a user interface." .
 
 lv2:Designation
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf rdf:Property ;
 	rdfs:label "Designation" ;
-	lv2:documentation """
-<p>The designation (or <q>assignment</q>) of an input or output.  A designation
-is metadata that describes the meaning or role of data.  By assigning a
-designation to a port using lv2:designation, the port's content becomes
-meaningful and can be used more intelligently by the host.</p>
-""" .
+	rdfs:comment "A designation which defines the meaning of some data." .
 
 lv2:Channel
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:Designation ;
 	rdfs:label "Channel" ;
-	lv2:documentation """
-<p>A specific channel, e.g. <q>left</q> or <q>right</q>.  A channel may be
-audio, or another type such as a MIDI control stream.</p>
-""" .
+	rdfs:comment "An individual channel, such as left or right." .
 
 lv2:Parameter
 	a rdfs:Class ,
@@ -522,16 +229,7 @@ lv2:Parameter
 	rdfs:subClassOf lv2:Designation ,
 		rdf:Property ;
 	rdfs:label "Parameter" ;
-	lv2:documentation """
-<p>A parameter, i.e. a recognized property.  A parameter is a designation for a
-control.</p>
-
-<p>A parameter defines the <em>meaning</em> of a control (not the
-<em>method</em> of conveying its value).  The standard way of exposing a plugin
-parameter is via an lv2:ControlPort, which can be given a parameter designation
-with lv2:designation.  Other methods, such as setting dynamic parameters via
-messages, are possible but not defined here.</p>
-""" .
+	rdfs:comment "A property that is a plugin parameter." .
 
 lv2:designation
 	a rdf:Property ,
@@ -539,18 +237,7 @@ lv2:designation
 		owl:FunctionalProperty ;
 	rdfs:range rdf:Property ;
 	rdfs:label "designation" ;
-	lv2:documentation """
-<p>Indicates a channel or parameter designation.</p>
-
-<p>This property is used to give the port's contents a well-defined meaning.
-For example, if a port has lv2:designation eg:gain, then the value of that port
-represents the eg:gain of the plugin instance.</p>
-
-<p>Ports should be given designations whenever a well-defined designation
-exists.  This allows the host to act more intelligently and/or provide a more
-effective user interface.  For example, if the plugin has a BPM parameter, the
-host may automatically set that parameter to the current tempo.</p>
-""" .
+	rdfs:comment "The designation that defines the meaning of this input or output." .
 
 lv2:latency
 	a rdf:Property ,
@@ -564,61 +251,32 @@ lv2:freeWheeling
 		owl:DatatypeProperty ;
 	rdfs:label "free-wheeling" ;
 	rdfs:range xsd:boolean ;
-	lv2:documentation """
-<p>Whether or not processing is currently free-wheeling.  If true, this means
-that all processing is happening as quickly as possible, not in real-time.
-When free-wheeling there is no relationship between the passage of real
-wall-clock time and the passage of time in the data being processed (e.g. audio
-frames).</p>
-""" .
+	rdfs:comment "Whether processing is currently free-wheeling." .
 
 lv2:enabled
 	a rdf:Property ,
 		owl:DatatypeProperty ;
 	rdfs:label "enabled" ;
 	rdfs:range xsd:int ;
-	lv2:documentation """
-<p>Whether or not processing is currently enabled, that is, not bypassed.</p>
-
-<p>If this value is greater than zero, the plugin processes normally.  If this
-value is zero, the plugin is expected to bypass all signals unmodified.  The
-plugin must provide a click-free transition between the enabled and disabled
-(bypassed) states.</p>
-
-<p>Values less than zero are reserved for future use (such as click-free
-insertion/removal of latent plugins), and should be treated like zero
-(bypassed) by current implementations.</p>
-""" .
+	rdfs:comment "Whether processing is currently enabled (not bypassed)." .
 
 lv2:control
 	a lv2:Channel ;
 	rdfs:label "control" ;
-	lv2:documentation """
-<p>The primary control channel.  This should be used as the lv2:designation of
-ports that are used to send commands and receive responses.  Typically this
-will be an event port that supports some protocol, e.g. MIDI or LV2 Atoms.</p>
-""" .
+	rdfs:comment "The primary control channel." .
 
 lv2:Point
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:label "Point" ;
-	lv2:documentation """
-<p>A Point describes an interesting value in a Port's range (much like a labeled
-<q>notch</q> on a physical knob).</p>
-<ul>
-  <li>A Point MUST have at least one rdfs:label which is a string.</li>
-  <li>A Point MUST have exactly one rdf:value with a type that is compatible
-  with the type of the corresponding Port.</li>
-</ul>
-""" .
+	rdfs:comment "An interesting point in a value range." .
 
 lv2:ScalePoint
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:Point ;
 	rdfs:label "Scale Point" ;
-	rdfs:comment "A single float Point (for control inputs)." .
+	rdfs:comment "A single `float` Point for control inputs." .
 
 lv2:scalePoint
 	a rdf:Property ,
@@ -632,137 +290,75 @@ lv2:default
 		owl:DatatypeProperty ,
 		owl:FunctionalProperty ;
 	rdfs:label "default" ;
-	rdfs:comment """The default value that the host SHOULD set this port to when there is no other information available.""" .
+	rdfs:comment "The default value for this control." .
 
 lv2:minimum
 	a rdf:Property ,
 		owl:DatatypeProperty ,
 		owl:FunctionalProperty ;
 	rdfs:label "minimum" ;
-	lv2:documentation """
-<p>A hint to the host for the minimum useful value that the port will use. This
-is a <q>soft</q> limit; the plugin is required to gracefully accept all values
-in the range of a port's data type.</p>
-""" .
+	rdfs:comment "The minimum value for this control." .
 
 lv2:maximum
 	a rdf:Property ,
 		owl:DatatypeProperty ,
 		owl:FunctionalProperty ;
 	rdfs:label "maximum" ;
-	lv2:documentation """
-<p>A hint to the host for the maximum useful value that the port will use.
-This is a <q>soft</q> limit; the plugin is required to gracefully accept all
-values in the range of a port's data type.</p>
-""" .
+	rdfs:comment "The maximum value for this control." .
 
 lv2:Feature
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:label "Feature" ;
-	rdfs:comment """An additional feature which a plugin or other resource may use or require.""" .
+	rdfs:comment "An additional feature which may be used or required." .
 
 lv2:optionalFeature
 	a rdf:Property ,
 		owl:ObjectProperty ;
 	rdfs:range lv2:Feature ;
 	rdfs:label "optional feature" ;
-	lv2:documentation """
-<p>Signifies that a plugin or other resource supports a certain feature. If
-the host supports this feature, it MUST pass its URI and any additional data to
-the plugin in LV2_Descriptor::instantiate(). The plugin MUST NOT fail to
-instantiate if an optional feature is not supported by the host.</p>
-""" .
+	rdfs:comment "An optional feature that is supported if available." .
 
 lv2:requiredFeature
 	a rdf:Property ,
 		owl:ObjectProperty ;
 	rdfs:range lv2:Feature ;
 	rdfs:label "required feature" ;
-	lv2:documentation """
-<p>Signifies that a plugin or other resource requires a certain feature. If
-the host supports this feature, it MUST pass its URI and any additional data to
-the plugin in LV2_Descriptor::instantiate(). The plugin MUST fail to
-instantiate if a required feature is not present; hosts SHOULD always check
-this before attempting to instantiate a plugin (i.e. discovery by attempting to
-instantiate is strongly discouraged).</p>
-""" .
+	rdfs:comment "A required feature that must be available to run." .
 
 lv2:ExtensionData
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:label "Extension Data" ;
-	lv2:documentation """
-<p>Additional data and/or functions a plugin may return from
-LV2_Descriptor::extension_data() which can be used to add additional API beyond
-that defined by LV2_Descriptor.</p>
-""" .
+	rdfs:comment "Additional data defined by an extension." .
 
 lv2:extensionData
 	a rdf:Property ,
 		owl:ObjectProperty ;
 	rdfs:range lv2:ExtensionData ;
 	rdfs:label "extension data" ;
-	lv2:documentation """
-<p>Signifies that a plugin provides additional data or functions (as defined by
-some extension) via LV2_Descriptor::instantiate().</p>
-""" .
+	rdfs:comment "Extension data provided by a plugin or other binary." .
 
 lv2:isLive
 	a lv2:Feature ;
 	rdfs:label "is live" ;
-	lv2:documentation """
-<p>Indicates that the plugin has a real-time dependency (e.g. queues data from
-a socket) and so its output must not be cached or subject to significant
-latency, and calls to the run method should be done in rapid succession. This
-property is not related to <q>hard real-time</q> execution requirements (see
-lv2:hardRTCapable).</p>
-""" .
+	rdfs:comment "Plugin has a real-time dependency." .
 
 lv2:inPlaceBroken
 	a lv2:Feature ;
 	rdfs:label "in-place broken" ;
-	lv2:documentation """
-<p>Indicates that the plugin may cease to work correctly if the host elects to
-use the same data location for both input and output. Plugins that will fail
-to work correctly if ANY input port is connected to the same location as ANY
-output port MUST require this Feature. Doing so should be avoided as it makes
-it impossible for hosts to use the plugin to process data <q>in-place</q>.</p>
-""" .
+	rdfs:comment "Plugin requires separate locations for input and output." .
 
 lv2:hardRTCapable
 	a lv2:Feature ;
 	rdfs:label "hard real-time capable" ;
-	lv2:documentation """
-<p>Indicates that the plugin is capable of running not only in a conventional
-host but also in a <q>hard real-time</q> environment. To qualify for this the
-plugin MUST satisfy all of the following:</p>
-<ol>
-<li>The plugin MUST NOT use malloc(), free() or other heap memory management
-    functions within its Audio class functions.</li>
-
-<li>The plugin MUST NOT attempt to make use of any library functions in its
-    Audio class functions, unless those functions themselves adhere to these
-    rules (i.e. are hard realtime safe). The plugin MAY assume the standard C
-    and C math library functions are safe.</li>
-
-<li>The plugin will not access files, devices, pipes, sockets, IPC or any other
-    mechanism that might result in process or thread blocking within its Audio
-    class functions.</li>
-
-<li>The plugin will take an amount of time to execute a run() call
-    approximately of form <code>A + B * sample_count</code> where <code>A</code>
-    and <code>B</code> depend on the machine and host in use. This amount of
-    time MUST NOT depend on input signals or plugin state.</li>
-</ol>
-<p>Note these rules apply to the connect_port() function as well as run().</p>
-""" .
+	rdfs:comment "Plugin is capable of running in a hard real-time environment." .
 
 lv2:PortProperty
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:label "Port Property" ;
-	rdfs:comment """A property of this port that allows a host to make more sensible decisions (e.g. to provide a better interface).""" .
+	rdfs:comment "A particular property that a port has." .
 
 lv2:portProperty
 	a rdf:Property ,
@@ -770,125 +366,113 @@ lv2:portProperty
 	rdfs:domain lv2:Port ;
 	rdfs:range lv2:PortProperty ;
 	rdfs:label "port property" ;
-	rdfs:comment """Relates Ports to PortProperties. The PortProperty may be ignored without catastrophic effects, though it may be useful e.g. for providing a sensible interface for the port.""" .
+	rdfs:comment "A property of this port hosts may find useful." .
 
 lv2:connectionOptional
 	a lv2:PortProperty ;
 	rdfs:label "connection optional" ;
-	rdfs:comment """Indicates that this port does not have to be connected to valid data by the host. If it is to be disconnected then the port MUST set to NULL with a call to the connectPort method.""" .
+	rdfs:comment "The property that this port may be connected to NULL." .
 
 lv2:reportsLatency
 	a lv2:PortProperty ;
+	owl:deprecated "true"^^xsd:boolean ;
 	rdfs:label "reports latency" ;
-	lv2:documentation """
-<p>Indicates that the port is used to express the processing latency incurred
-by the plugin, expressed in samples. The latency may be affected by the current
-sample rate, plugin settings, or other factors, and may be changed by the
-plugin at any time. Where the latency is frequency dependent the plugin may
-choose any appropriate value. If a plugin introduces latency it MUST provide
-EXACTLY ONE port with this property set which informs the host of the
-<q>correct</q> latency. In <q>fuzzy</q> cases the value output should be the
-most reasonable based on user expectation of input/output alignment
-(eg. musical delay/echo plugins should not report their delay as latency, as it
-is an intentional effect).</p>
-""" .
+	rdfs:comment "Control port value is the plugin latency in frames." .
 
 lv2:toggled
 	a lv2:PortProperty ;
 	rdfs:label "toggled" ;
-	lv2:documentation """
-<p>Indicates that the data item should be considered a Boolean toggle. Data
-less than or equal to zero should be considered <q>off</q> or <q>false</q>, and
-data above zero should be considered <q>on</q> or <q>true</q>.</p>
-""" .
+	rdfs:comment "Control port value is considered a boolean toggle." .
 
 lv2:sampleRate
 	a lv2:PortProperty ;
 	rdfs:label "sample rate" ;
-	rdfs:comment """Indicates that any bounds specified should be interpreted as multiples of the sample rate. For instance, a frequency range from 0Hz to the Nyquist frequency (half the sample rate) could be requested by this property in conjunction with lv2:minimum 0.0 and lv2:maximum 0.5. Hosts that support bounds at all MUST support this property.""" .
+	rdfs:comment "Control port bounds are interpreted as multiples of the sample rate." .
 
 lv2:integer
 	a lv2:PortProperty ;
 	rdfs:label "integer" ;
-	rdfs:comment """Indicates that a port's reasonable values are integers (eg. a user interface would likely wish to provide a stepped control allowing only integer input). A plugin MUST operate reasonably even if such a port has a non-integer input.""" .
+	rdfs:comment "Control port values are treated as integers." .
 
 lv2:enumeration
 	a lv2:PortProperty ;
 	rdfs:label "enumeration" ;
-	rdfs:comment """Indicates that a port's only reasonable values are the scale points defined for that port. A host SHOULD NOT allow a user to set the value of such a port to anything other than a scale point. However, a plugin MUST operate reasonably even if such a port has an input that is not a scale point, preferably by simply choosing the largest enumeration value less than or equal to the actual input value (i.e. round the input value down).""" .
+	rdfs:comment "Control port scale points represent all useful values." .
 
 lv2:isSideChain
 	a lv2:PortProperty ;
 	rdfs:label "is side-chain" ;
-	rdfs:comment """Indicates that a port is a "sidechain", which affects the output somehow but should not be considered a main input.  Sidechain ports should be connectionOptional, and may be ignored by hosts.""" .
+	rdfs:comment "Signal for port should not be considered a main input or output." .
 
 lv2:GeneratorPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:Plugin ;
-	rdfs:label "Generator" ;
-	rdfs:comment """Any plugin that generates sound internally, rather than processing its input.""" .
+	rdfs:label "Generator Plugin" ;
+	rdfs:comment "A plugin that generates new sound internally." .
 
 lv2:InstrumentPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:GeneratorPlugin ;
-	rdfs:label "Instrument" ;
-	rdfs:comment """Any plugin that is intended to be played as a musical instrument.""" .
+	rdfs:label "Instrument Plugin" ;
+	rdfs:comment "A plugin intended to be played as a musical instrument." .
 
 lv2:OscillatorPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:GeneratorPlugin ;
-	rdfs:label "Oscillator" .
+	rdfs:label "Oscillator Plugin" ;
+	rdfs:comment "A plugin that generates output with an oscillator." .
 
 lv2:UtilityPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:Plugin ;
-	rdfs:label "Utility" ;
-	rdfs:comment """Includes things like mathematical functions and non-musical delays.""" .
+	rdfs:label "Utility Plugin" ;
+	rdfs:comment "A utility plugin that is not a typical audio effect or generator." .
 
 lv2:ConverterPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:UtilityPlugin ;
-	rdfs:label "Converter" ;
-	rdfs:comment """Any plugin that converts some form of input into a different form of output.""" .
+	rdfs:label "Converter Plugin" ;
+	rdfs:comment "A plugin that converts its input into a different form." .
 
 lv2:AnalyserPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:UtilityPlugin ;
-	rdfs:label "Analyser" ;
-	rdfs:comment """Any plugin that analyses input to output some useful information.""" .
+	rdfs:label "Analyser Plugin" ;
+	rdfs:comment "A plugin that analyses its input and emits some useful information." .
 
 lv2:MixerPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:UtilityPlugin ;
-	rdfs:label "Mixer" ;
-	rdfs:comment """A plugin which mixes some number of inputs into some number of outputs.""" .
+	rdfs:label "Mixer Plugin" ;
+	rdfs:comment "A plugin that mixes some number of inputs into some number of outputs." .
 
 lv2:SimulatorPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:Plugin ;
-	rdfs:label "Simulator" ;
-	rdfs:comment """Plugins that aim to duplicate the effect of some environmental effect or musical equipment.""" .
+	rdfs:label "Simulator Plugin" ;
+	rdfs:comment "A plugin that aims to emulate some environmental effect or musical equipment." .
 
 lv2:DelayPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:Plugin ;
-	rdfs:label "Delay" ;
-	rdfs:comment """Plugins that intentionally delay their input signal as an effect.""" .
+	rdfs:label "Delay Plugin" ;
+	rdfs:comment "An effect that intentionally delays its input as an effect." .
 
 lv2:ModulatorPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:Plugin ;
-	rdfs:label "Modulator" .
+	rdfs:label "Modulator Plugin" ;
+	rdfs:comment "An effect that modulats its input as an effect." .
 
 lv2:ReverbPlugin
 	a rdfs:Class ,
@@ -896,170 +480,195 @@ lv2:ReverbPlugin
 	rdfs:subClassOf lv2:Plugin ,
 		lv2:SimulatorPlugin ,
 		lv2:DelayPlugin ;
-	rdfs:label "Reverb" .
+	rdfs:label "Reverb Plugin" ;
+	rdfs:comment "An effect that adds reverberation to its input." .
 
 lv2:PhaserPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:ModulatorPlugin ;
-	rdfs:label "Phaser" .
+	rdfs:label "Phaser Plugin" ;
+	rdfs:comment "An effect that periodically sweeps a filter over its input." .
 
 lv2:FlangerPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:ModulatorPlugin ;
-	rdfs:label "Flanger" .
+	rdfs:label "Flanger Plugin" ;
+	rdfs:comment "An effect that mixes slightly delayed copies of its input." .
 
 lv2:ChorusPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:ModulatorPlugin ;
-	rdfs:label "Chorus" .
+	rdfs:label "Chorus Plugin" ;
+	rdfs:comment "An effect that mixes significantly delayed copies of its input." .
 
 lv2:FilterPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:Plugin ;
-	rdfs:label "Filter" .
+	rdfs:label "Filter Plugin" ;
+	rdfs:comment "An effect that manipulates the frequency spectrum of its input." .
 
 lv2:LowpassPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:FilterPlugin ;
-	rdfs:label "Lowpass" .
+	rdfs:label "Lowpass Filter Plugin" ;
+	rdfs:comment "A filter that attenuates frequencies above some cutoff." .
 
 lv2:BandpassPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:FilterPlugin ;
-	rdfs:label "Bandpass" .
+	rdfs:label "Bandpass Filter Plugin" ;
+	rdfs:comment "A filter that attenuates frequencies outside of some band." .
 
 lv2:HighpassPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:FilterPlugin ;
-	rdfs:label "Highpass" .
+	rdfs:label "Highpass Filter Plugin" ;
+	rdfs:comment "A filter that attenuates frequencies below some cutoff." .
 
 lv2:CombPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:FilterPlugin ;
-	rdfs:label "Comb" .
+	rdfs:label "Comb FilterPlugin" ;
+	rdfs:comment "A filter that adds a delayed version of its input to itself." .
 
 lv2:AllpassPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:FilterPlugin ;
-	rdfs:label "Allpass" .
+	rdfs:label "Allpass Plugin" ;
+	rdfs:comment "A filter that changes the phase relationship between frequency components." .
 
 lv2:EQPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:FilterPlugin ;
-	rdfs:label "Equaliser" .
+	rdfs:label "Equaliser Plugin" ;
+	rdfs:comment "A plugin that adjusts the balance between frequency components." .
 
 lv2:ParaEQPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:EQPlugin ;
-	rdfs:label "Parametric" .
+	rdfs:label "Parametric EQ Plugin" ;
+	rdfs:comment "A plugin that adjusts the balance between configurable frequency components." .
 
 lv2:MultiEQPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:EQPlugin ;
-	rdfs:label "Multiband" .
+	rdfs:label "Multiband EQ Plugin" ;
+	rdfs:comment "A plugin that adjusts the balance between a fixed set of frequency components." .
 
 lv2:SpatialPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:Plugin ;
-	rdfs:label "Spatial" ;
-	rdfs:comment """Plugins that manipulate the position of audio in space (e.g. panning,
-stereo width, surround encoding, etc.).""" .
+	rdfs:label "Spatial Plugin" ;
+	rdfs:comment "A plugin that manipulates the position of audio in space." .
 
 lv2:SpectralPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:Plugin ;
-	rdfs:label "Spectral" ;
-	rdfs:comment """Plugins that alter the spectral properties (e.g. frequency) of audio.""" .
+	rdfs:label "Spectral Plugin" ;
+	rdfs:comment "A plugin that alters the spectral properties of audio." .
 
 lv2:PitchPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:SpectralPlugin ;
-	rdfs:label "Pitch Shifter" .
+	rdfs:label "Pitch Shifter Plugin" ;
+	rdfs:comment "A plugin that shifts the pitch of its input." .
 
 lv2:AmplifierPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:DynamicsPlugin ;
-	rdfs:label "Amplifier" .
+	rdfs:label "Amplifier Plugin" ;
+	rdfs:comment "A plugin that primarily changes the volume of its input." .
 
 lv2:EnvelopePlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:DynamicsPlugin ;
-	rdfs:label "Envelope" .
+	rdfs:label "Envelope Plugin" ;
+	rdfs:comment "A plugin that applies an envelope to its input." .
 
 lv2:DistortionPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:Plugin ;
-	rdfs:label "Distortion" .
+	rdfs:label "Distortion Plugin" ;
+	rdfs:comment "A plugin that adds distortion to its input." .
 
 lv2:WaveshaperPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:DistortionPlugin ;
-	rdfs:label "Waveshaper" .
+	rdfs:label "Waveshaper Plugin" ;
+	rdfs:comment "An effect that alters the shape of input waveforms." .
 
 lv2:DynamicsPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:Plugin ;
-	rdfs:label "Dynamics" ;
-	rdfs:comment """Plugins that alter the envelope or dynamic range of audio.""" .
+	rdfs:label "Dynamics Plugin" ;
+	rdfs:comment "A plugin that alters the envelope or dynamic range of its input." .
 
 lv2:CompressorPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:DynamicsPlugin ;
-	rdfs:label "Compressor" .
+	rdfs:label "Compressor Plugin" ;
+	rdfs:comment "A plugin that reduces the dynamic range of its input." .
 
 lv2:ExpanderPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:DynamicsPlugin ;
-	rdfs:label "Expander" .
+	rdfs:label "Expander Plugin" ;
+	rdfs:comment "A plugin that expands the dynamic range of its input." .
 
 lv2:LimiterPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:DynamicsPlugin ;
-	rdfs:label "Limiter" .
+	rdfs:label "Limiter Plugin" ;
+	rdfs:comment "A plugin that limits its input to some maximum level." .
 
 lv2:GatePlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:DynamicsPlugin ;
-	rdfs:label "Gate" .
+	rdfs:label "Gate Plugin" ;
+	rdfs:comment "A plugin that attenuates signals below some threshold." .
 
 lv2:FunctionPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:UtilityPlugin ;
-	rdfs:label "Function" .
+	rdfs:label "Function Plugin" ;
+	rdfs:comment "A plugin whose output is a mathmatical function of its input." .
 
 lv2:ConstantPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:GeneratorPlugin ;
-	rdfs:label "Constant" .
+	rdfs:label "Constant Plugin" ;
+	rdfs:comment "A plugin that emits constant values." .
 
 lv2:MIDIPlugin
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:Plugin ;
-	rdfs:label "MIDI" .
+	rdfs:label "MIDI Plugin" ;
+	rdfs:comment "A plugin that primarily processes MIDI messages." .
+
diff --git a/sys/lv2/core/manifest.ttl b/sys/lv2/core/manifest.ttl
index 7abddcee..7f1512bf 100644
--- a/sys/lv2/core/manifest.ttl
+++ b/sys/lv2/core/manifest.ttl
@@ -1,14 +1,15 @@
 @prefix doap: <http://usefulinc.com/ns/doap#> .
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
-@prefix owl:  <http://www.w3.org/2002/07/owl#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/lv2core>
 	a lv2:Specification ;
-	lv2:minorVersion 16 ;
+	lv2:minorVersion 18 ;
 	lv2:microVersion 0 ;
 	rdfs:seeAlso <lv2core.ttl> .
 
 <http://lv2plug.in/ns/lv2>
 	a doap:Project ;
-	rdfs:seeAlso <meta.ttl> .
+	rdfs:seeAlso <meta.ttl> ,
+		<people.ttl> .
+
diff --git a/sys/lv2/core/meta.ttl b/sys/lv2/core/meta.ttl
index 4752dcb7..721fba85 100644
--- a/sys/lv2/core/meta.ttl
+++ b/sys/lv2/core/meta.ttl
@@ -1,10 +1,8 @@
-@prefix dcs:  <http://ontologi.es/doap-changeset#> .
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
 @prefix doap: <http://usefulinc.com/ns/doap#> .
-@prefix foaf: <http://xmlns.com/foaf/0.1/> .
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix meta: <http://lv2plug.in/ns/meta#> .
-@prefix owl:  <http://www.w3.org/2002/07/owl#> .
-@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://opensource.org/licenses/isc>
@@ -17,9 +15,11 @@ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH R
 <http://lv2plug.in/ns/lv2>
 	a doap:Project ;
 	lv2:symbol "lv2" ;
+	rdfs:label "LV2" ;
+	rdfs:comment "The LV2 Plugin Interface Project." ;
 	doap:name "LV2" ;
 	doap:license <http://opensource.org/licenses/isc> ;
-	doap:shortdesc "The LV2 Plugin Interface Project" ;
+	doap:shortdesc "The LV2 Plugin Interface Project." ;
 	doap:description "LV2 is a plugin standard for audio systems. It defines a minimal yet extensible C API for plugin code and a format for plugin bundles" ;
 	doap:created "2006-05-10" ;
 	doap:homepage <http://lv2plug.in/> ;
@@ -38,6 +38,18 @@ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH R
 		meta:kfoltman ,
 		meta:paniq ;
 	doap:release [
+		doap:revision "1.18.0" ;
+		doap:created "2020-04-26" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.18.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Improve documentation."
+			] , [
+				rdfs:label "Separate extended documentation from primary data."
+			]
+		]
+	] , [
 		doap:revision "1.16.0" ;
 		doap:created "2019-02-03" ;
 		doap:file-release <http://lv2plug.in/spec/lv2-1.16.0.tar.bz2> ;
@@ -68,7 +80,7 @@ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH R
 		dcs:blame <http://drobilla.net/drobilla#me> ;
 		dcs:changeset [
 			dcs:item [
-				rdfs:label "eg-scope: Don't feed back UI state updates."
+				rdfs:label """eg-scope: Don't feed back UI state updates."""
 			] , [
 				rdfs:label "eg-sampler: Fix handling of state file paths."
 			] , [
@@ -166,57 +178,10 @@ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH R
 		dcs:blame <http://drobilla.net/drobilla#me> ;
 		dcs:changeset [
 			dcs:item [
-				rdfs:label "Initial release as a unified project.  Projects can now simply depend on the pkg-config package 'lv2' for all official LV2 APIs."
+				rdfs:label """Initial release as a unified project.  Projects can now simply depend on the pkg-config package 'lv2' for all official LV2 APIs."""
 			] , [
 				rdfs:label "New extensions: atom, log, parameters, patch, port-groups, port-props, resize-port, state, time, worker."
 			]
 		]
 	] .
 
-<http://drobilla.net/drobilla#me>
-	a foaf:Person ;
-	foaf:name "David Robillard" ;
-	foaf:mbox <mailto:d@drobilla.net> ;
-	rdfs:seeAlso <http://drobilla.net/drobilla> .
-
-<http://plugin.org.uk/swh.xrdf#me>
-	a foaf:Person ;
-	foaf:name "Steve Harris" ;
-	foaf:mbox <mailto:steve@plugin.org.uk> ;
-	rdfs:seeAlso <http://plugin.org.uk/swh.xrdf> .
-
-meta:larsl
-	a foaf:Person ;
-	foaf:name "Lars Luthman" ;
-	foaf:mbox <mailto:lars.luthman@gmail.com> .
-
-meta:gabrbedd
-	a foaf:Person ;
-	foaf:name "Gabriel M. Beddingfield" ;
-	foaf:mbox <mailto:gabrbedd@gmail.com> .
-
-meta:daste
-	a foaf:Person ;
-	foaf:name "Stefano D'Angelo" ;
-	foaf:mbox <mailto:zanga.mail@gmail.com> .
-
-meta:kfoltman
-	a foaf:Person ;
-	foaf:name "Krzysztof Foltman" ;
-	foaf:mbox <mailto:wdev@foltman.com> .
-
-meta:paniq
-	a foaf:Person ;
-	foaf:name "Leonard Ritter" ;
-	foaf:mbox <mailto:paniq@paniq.org> .
-
-meta:harry
-	a foaf:Person ;
-	foaf:name "Harry van Haaren" ;
-	foaf:mbox <harryhaaren@gmail.com> .
-
-meta:bmwiedemann
-	a foaf:Person ;
-	foaf:name "Bernhard M. Wiedemann" ;
-	foaf:mbox <bwiedemann@suse.de> .
-
diff --git a/sys/lv2/core/people.ttl b/sys/lv2/core/people.ttl
new file mode 100644
index 00000000..52d0384e
--- /dev/null
+++ b/sys/lv2/core/people.ttl
@@ -0,0 +1,51 @@
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix meta: <http://lv2plug.in/ns/meta#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://drobilla.net/drobilla#me>
+	a foaf:Person ;
+	foaf:name "David Robillard" ;
+	foaf:mbox <mailto:d@drobilla.net> ;
+	rdfs:seeAlso <http://drobilla.net/drobilla> .
+
+<http://plugin.org.uk/swh.xrdf#me>
+	a foaf:Person ;
+	foaf:name "Steve Harris" ;
+	foaf:mbox <mailto:steve@plugin.org.uk> ;
+	rdfs:seeAlso <http://plugin.org.uk/swh.xrdf> .
+
+meta:larsl
+	a foaf:Person ;
+	foaf:name "Lars Luthman" ;
+	foaf:mbox <mailto:lars.luthman@gmail.com> .
+
+meta:gabrbedd
+	a foaf:Person ;
+	foaf:name "Gabriel M. Beddingfield" ;
+	foaf:mbox <mailto:gabrbedd@gmail.com> .
+
+meta:daste
+	a foaf:Person ;
+	foaf:name """Stefano D'Angelo""" ;
+	foaf:mbox <mailto:zanga.mail@gmail.com> .
+
+meta:kfoltman
+	a foaf:Person ;
+	foaf:name "Krzysztof Foltman" ;
+	foaf:mbox <mailto:wdev@foltman.com> .
+
+meta:paniq
+	a foaf:Person ;
+	foaf:name "Leonard Ritter" ;
+	foaf:mbox <mailto:paniq@paniq.org> .
+
+meta:harry
+	a foaf:Person ;
+	foaf:name "Harry van Haaren" ;
+	foaf:mbox <harryhaaren@gmail.com> .
+
+meta:bmwiedemann
+	a foaf:Person ;
+	foaf:name "Bernhard M. Wiedemann" ;
+	foaf:mbox <bwiedemann@suse.de> .
+
diff --git a/sys/lv2/data-access/NEWS b/sys/lv2/data-access/NEWS
deleted file mode 100644
index 1e35cea5..00000000
--- a/sys/lv2/data-access/NEWS
+++ /dev/null
@@ -1,26 +0,0 @@
-data-access (1.6) stable;
-
-  * Merge with unified LV2 package.
-
- -- None <None>  Tue, 17 Apr 2012 00:00:00 +0000
-
-data-access (1.4) stable;
-
-  * Improve documentation.
-  * Update packaging.
-
- -- None <None>  Mon, 21 Nov 2011 00:00:00 +0000
-
-data-access (1.2) stable;
-
-  * Add build system for installation.
-  * Switch to ISC license.
-
- -- None <None>  Thu, 26 May 2011 00:00:00 +0000
-
-data-access (1.0) stable;
-
-  * Initial release.
-
- -- None <None>  Mon, 04 Oct 2010 00:00:00 +0000
-
diff --git a/sys/lv2/data-access/data-access.h b/sys/lv2/data-access/data-access.h
index 2f4fd28d..f57b1e26 100644
--- a/sys/lv2/data-access/data-access.h
+++ b/sys/lv2/data-access/data-access.h
@@ -17,9 +17,10 @@
 
 /**
    @defgroup data-access Data Access
+   @ingroup lv2
 
    Access to plugin extension_data() for UIs, see
-   <http://lv2plug.in/ns/ext/data-acess> for details.
+   <http://lv2plug.in/ns/ext/data-access> for details.
 
    @{
 */
diff --git a/sys/lv2/data-access/lv2-data-access.doap.ttl b/sys/lv2/data-access/data-access.meta.ttl
similarity index 64%
rename from sys/lv2/data-access/lv2-data-access.doap.ttl
rename to sys/lv2/data-access/data-access.meta.ttl
index d577e633..3184110c 100644
--- a/sys/lv2/data-access/lv2-data-access.doap.ttl
+++ b/sys/lv2/data-access/data-access.meta.ttl
@@ -1,6 +1,8 @@
+@prefix da: <http://lv2plug.in/ns/ext/data-access#> .
 @prefix dcs: <http://ontologi.es/doap-changeset#> .
 @prefix doap: <http://usefulinc.com/ns/doap#> .
 @prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/data-access>
@@ -8,7 +10,7 @@
 	rdfs:seeAlso <data-access.h> ;
 	doap:license <http://opensource.org/licenses/isc> ;
 	doap:name "LV2 Data Access" ;
-	doap:shortdesc "Provides access to LV2_Descriptor::extension_data()." ;
+	doap:shortdesc "Provides access to plugin extension data." ;
 	doap:created "2008-00-00" ;
 	doap:developer <http://drobilla.net/drobilla#me> ;
 	doap:release [
@@ -55,4 +57,21 @@
 				rdfs:label "Initial release."
 			]
 		]
-	] .
+	] ;
+	lv2:documentation """
+
+This extension defines a feature, LV2_Extension_Data_Feature, which provides
+access to LV2_Descriptor::extension_data() for plugin UIs or other potentially
+remote users of a plugin.
+
+Note that the use of this extension by UIs violates the important principle of
+UI/plugin separation, and is potentially a source of many problems.
+Accordingly, **use of this extension is highly discouraged**, and plugins
+should not expect hosts to support it, since it is often impossible to do so.
+
+To support this feature the host must pass an LV2_Feature struct to
+LV2_Descriptor::extension_data() with URI LV2_DATA_ACCESS_URI and data pointed
+to an instance of LV2_Extension_Data_Feature.
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/data-access/data-access.ttl b/sys/lv2/data-access/data-access.ttl
index 654b7140..0185cd0d 100644
--- a/sys/lv2/data-access/data-access.ttl
+++ b/sys/lv2/data-access/data-access.ttl
@@ -1,23 +1,11 @@
-@prefix da:   <http://lv2plug.in/ns/ext/data-access#> .
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix da: <http://lv2plug.in/ns/ext/data-access#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/data-access>
 	a lv2:Feature ;
+	rdfs:label "data access" ;
+	rdfs:comment "A feature that provides access to plugin extension data." ;
 	rdfs:seeAlso <data-access.h> ,
-		<lv2-data-access.doap.ttl> ;
-	lv2:documentation """
-<p>This extension defines a feature, LV2_Extension_Data_Feature, which provides
-access to LV2_Descriptor::extension_data() for plugin UIs or other potentially
-remote users of a plugin.</p>
+		<data-access.meta.ttl> .
 
-<p>Note that the use of this extension by UIs violates the important principle
-of UI/plugin separation, and is potentially a source of many problems.
-Accordingly, <strong>use of this extension is highly discouraged</strong>, and
-plugins should not expect hosts to support it, since it is often impossible to
-do so.</p>
-
-<p>To support this feature the host must pass an LV2_Feature struct to the
-instantiate method with URI LV2_DATA_ACCESS_URI and data pointed to an instance
-of LV2_Extension_Data_Feature.</p>
-""" .
diff --git a/sys/lv2/data-access/manifest.ttl b/sys/lv2/data-access/manifest.ttl
index 85e50fc3..9585a5e4 100644
--- a/sys/lv2/data-access/manifest.ttl
+++ b/sys/lv2/data-access/manifest.ttl
@@ -1,4 +1,4 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/data-access>
diff --git a/sys/lv2/dynmanifest/NEWS b/sys/lv2/dynmanifest/NEWS
deleted file mode 100644
index 20502402..00000000
--- a/sys/lv2/dynmanifest/NEWS
+++ /dev/null
@@ -1,24 +0,0 @@
-dynmanifest (1.6) stable;
-
-  * Use consistent label style.
-
- -- None <None>  Sun, 14 Oct 2012 00:00:00 +0000
-
-dynmanifest (1.4) stable;
-
-  * Merge with unified LV2 package.
-
- -- None <None>  Tue, 17 Apr 2012 00:00:00 +0000
-
-dynmanifest (1.2) stable;
-
-  * Improve documentation.
-
- -- None <None>  Mon, 21 Nov 2011 00:00:00 +0000
-
-dynmanifest (1.0) stable;
-
-  * Initial release.
-
- -- None <None>  Sat, 10 Apr 2010 00:00:00 +0000
-
diff --git a/sys/lv2/dynmanifest/dynmanifest.h b/sys/lv2/dynmanifest/dynmanifest.h
index a15eaf47..16274e46 100644
--- a/sys/lv2/dynmanifest/dynmanifest.h
+++ b/sys/lv2/dynmanifest/dynmanifest.h
@@ -17,6 +17,7 @@
 
 /**
    @defgroup dynmanifest Dynamic Manifest
+   @ingroup lv2
 
    Support for dynamic data generation, see
    <http://lv2plug.in/ns/ext/dynmanifest> for details.
@@ -75,7 +76,7 @@ int lv2_dyn_manifest_open(LV2_Dyn_Manifest_Handle *  handle,
    example, if the plugin library exposes a regular LV2 plugin, it should
    output only a triple like the following:
 
-   <http://www.example.com/plugin/uri> a lv2:Plugin .
+   <http://example.org/plugin> a lv2:Plugin .
 
    The objects that are elegible for exposure are those that would need to be
    represented by a subject node in a static manifest.
@@ -85,8 +86,8 @@ int lv2_dyn_manifest_open(LV2_Dyn_Manifest_Handle *  handle,
    @param fp FILE * identifying the resource the host has to set up for the
    dynamic manifest generator. The host MUST pass a writable, empty resource to
    this function, and the dynamic manifest generator MUST ONLY perform write
-   operations on it at the end of the stream (e.g., using only fprintf(),
-   fwrite() and similar).
+   operations on it at the end of the stream (for example, using only
+   fprintf(), fwrite() and similar).
 
    @return 0 on success, otherwise a non-zero error code.
 */
@@ -99,11 +100,11 @@ int lv2_dyn_manifest_get_subjects(LV2_Dyn_Manifest_Handle handle,
    The dynamic manifest generator has to fill the resource with data related to
    object represented by the given URI. For example, if the library exposes a
    regular LV2 plugin whose URI, as retrieved by the host using
-   lv2_dyn_manifest_get_subjects() is http://www.example.com/plugin/uri, it
+   lv2_dyn_manifest_get_subjects() is http://example.org/plugin then it
    should output something like:
 
    <pre>
-   <http://www.example.com/plugin/uri>
+   <http://example.org/plugin>
        a lv2:Plugin ;
        doap:name "My Plugin" ;
        lv2:binary <mylib.so> ;
@@ -115,8 +116,8 @@ int lv2_dyn_manifest_get_subjects(LV2_Dyn_Manifest_Handle handle,
    @param fp FILE * identifying the resource the host has to set up for the
    dynamic manifest generator. The host MUST pass a writable resource to this
    function, and the dynamic manifest generator MUST ONLY perform write
-   operations on it at the current position of the stream (e.g. using only
-   fprintf(), fwrite() and similar).
+   operations on it at the current position of the stream (for example, using
+   only fprintf(), fwrite() and similar).
 
    @param uri URI to get data about (in the "plain" form, i.e., absolute URI
    without Turtle prefixes).
diff --git a/sys/lv2/dynmanifest/dynmanifest.meta.ttl b/sys/lv2/dynmanifest/dynmanifest.meta.ttl
new file mode 100644
index 00000000..4e66d98a
--- /dev/null
+++ b/sys/lv2/dynmanifest/dynmanifest.meta.ttl
@@ -0,0 +1,131 @@
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix dman: <http://lv2plug.in/ns/ext/dynmanifest#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/dynmanifest>
+	a doap:Project ;
+	doap:license <http://opensource.org/licenses/isc> ;
+	doap:name "LV2 Dynamic Manifest" ;
+	doap:homepage <http://naspro.atheme.org> ;
+	doap:created "2009-06-13" ;
+	doap:shortdesc "Support for dynamic manifest data generation." ;
+	doap:programming-language "C" ;
+	doap:developer <http://lv2plug.in/ns/meta#daste> ;
+	doap:release [
+		doap:revision "1.6" ;
+		doap:created "2012-10-14" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Use consistent label style."
+			]
+		]
+	] , [
+		doap:revision "1.4" ;
+		doap:created "2012-04-17" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Merge with unified LV2 package."
+			]
+		]
+	] , [
+		doap:revision "1.2" ;
+		doap:created "2011-11-21" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-dynmanifest-1.2.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Improve documentation."
+			]
+		]
+	] , [
+		doap:revision "1.0" ;
+		doap:created "2010-04-10" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-dyn-manifest-1.0.tar.gz> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Initial release."
+			]
+		]
+	] ;
+	lv2:documentation """
+
+The LV2 API, on its own, cannot be used to write plugin libraries where data is
+dynamically generated at runtime, since LV2 requires needed information to be
+provided in one or more static data (RDF) files. This API addresses this
+limitation by extending the LV2 API.
+
+To detect that a plugin library implements a dynamic manifest generator, the
+host checks its static manifest for a description like:
+
+    :::turtle
+    <http://example.org/my-dynamic-manifest>
+        a dman:DynManifest ;
+        lv2:binary <mydynmanifest.so> .
+
+To load the data, the host loads the library (`mydynmanifest.so` in this
+example) as usual and fetches the dynamic Turtle data from it using this API.
+
+The host is allowed to request regeneration of the dynamic manifest multiple
+times, and the plugin library is expected to provide updated data if/when
+possible. All data and references provided via this API before the last
+regeneration of the dynamic manifest is to be considered invalid by the host,
+including plugin descriptors whose URIs were discovered using this API.
+
+### Accessing Data
+
+To access data using this API, the host must:
+
+  1. Call lv2_dyn_manifest_open().
+
+  2. Create a `FILE` for functions to write data to (for example with `tmpfile()`).
+
+  3. Get a list of exposed subject URIs using lv2_dyn_manifest_get_subjects().
+
+  4. Call lv2_dyn_manifest_get_data() for each URI of interest to write the
+  related data to the file.
+
+  5. Call lv2_dyn_manifest_close().
+
+  6. Parse the content of the file(s).
+
+  7. Remove the file(s).
+
+Each call to the above mentioned dynamic manifest functions MUST write a
+complete, valid Turtle document (including all needed prefix definitions) to
+the output FILE.
+
+Each call to lv2_dyn_manifest_open() causes the (re)generation of the dynamic
+manifest data, and invalidates all data fetched before the call.
+
+In case the plugin library uses this same API to access other dynamic
+manifests, it MUST implement some mechanism to avoid potentially endless loops
+(such as A loads B, B loads A, etc.) and, in case such a loop is detected, the
+operation MUST fail.  For this purpose, use of a static boolean flag is
+suggested.
+
+### Threading Rules
+
+All of the functions defined by this specification belong to the Discovery
+class.
+
+
+"""^^lv2:Markdown .
+
+dman:DynManifest
+	lv2:documentation """
+
+There MUST NOT be any instances of dman:DynManifest in the generated manifest.
+
+All relative URIs in the generated data MUST be relative to the base path that
+would be used to parse a normal LV2 manifest (the bundle path).
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/dynmanifest/dynmanifest.ttl b/sys/lv2/dynmanifest/dynmanifest.ttl
index 63e0730f..4e2e8309 100644
--- a/sys/lv2/dynmanifest/dynmanifest.ttl
+++ b/sys/lv2/dynmanifest/dynmanifest.ttl
@@ -1,73 +1,16 @@
 @prefix dman: <http://lv2plug.in/ns/ext/dynmanifest#> .
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
-@prefix owl:  <http://www.w3.org/2002/07/owl#> .
-@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
 
 <http://lv2plug.in/ns/ext/dynmanifest>
-	a lv2:Specification ;
+	a owl:Ontology ;
+	rdfs:label "LV2 Dyn Manifest" ;
+	rdfs:comment "Support for dynamic manifest data generation." ;
 	rdfs:seeAlso <dynmanifest.h> ,
-		<lv2-dynmanifest.doap.ttl> ;
-    lv2:documentation """
-<p>The LV2 API, on its own, cannot be used to write plugin libraries where data
-is dynamically generated at runtime (e.g. API wrappers), since LV2 requires
-needed information to be provided in one or more static data (RDF) files. This
-API addresses this limitation by extending the LV2 API.</p>
-
-<p>To detect that a plugin library implements a dynamic manifest generator,
-the host checks its static manifest for a description like:</p>
-
-<pre class="turtle-code">
-&lt;http://example.org/my-dynamic-manifest&gt;
-    a dman:DynManifest ;
-    lv2:binary &lt;mydynmanifest.so&gt; .
-</pre>
-
-<p>To load the data, the host loads the library
-(e.g. <code>mydynmanifest.so</code>) as usual and fetches the dynamic Turtle
-data from it using this API.</p>
-
-<p>The host is allowed to request regeneration of the dynamic manifest multiple
-times, and the plugin library is expected to provide updated data if/when
-possible.  All data and references provided via this API before the last
-regeneration of the dynamic manifest is to be considered invalid by the host,
-including plugin descriptors whose URIs were discovered using this API.</p>
-
-<h3>Accessing Data</h3>
-
-<p>Whenever a host wants to access data using this API, it could:</p>
-
-<ol>
-<li>Call lv2_dyn_manifest_open().</li>
-<li>Create a FILE for functions to write data to (e.g. using tmpfile()).</li>
-<li>Get a <q>list</q> of exposed subject URIs using
-    lv2_dyn_manifest_get_subjects().</li>
-<li>Call lv2_dyn_manifest_get_data() for each URI of interest to
-    get the data related to that URI (which can be written to any FILE).</li>
-<li>Call lv2_dyn_manifest_close().</li>
-<li>Parse the content of the FILE(s).</li>
-<li>Free/delete/unlink the FILE(s).</li>
-</ol>
-
-<p>Each call to the above mentioned dynamic manifest functions MUST write a
-complete, valid Turtle document (including all needed prefix definitions) to
-the output FILE.</p>
-
-<p>Each call to lv2_dyn_manifest_open() causes the (re)generation of the
-dynamic manifest data, and invalidates all data fetched before the call.</p>
-
-<p>In case the plugin library uses this same API to access other dynamic
-manifests, it MUST implement some mechanism to avoid potentially endless loops
-(such as A loads B, B loads A, etc.) and, in case such a loop is detected, the
-operation MUST fail.  For this purpose, use of a static boolean flag is
-suggested.</p>
-
-<h3>Threading Rules</h3>
-
-<p>All of the functions defined by this specification belong to the Discovery
-class.</p>
-""" .
+		<dynmanifest.meta.ttl> .
 
 dman:DynManifest
 	a rdfs:Class ;
@@ -76,10 +19,7 @@ dman:DynManifest
 		a owl:Restriction ;
 		owl:onProperty lv2:binary ;
 		owl:minCardinality 1 ;
-		rdfs:comment "A DynManifest MUST have at least 1 lv2:binary, which MUST implement all the functions defined in dynmanifest.h."
+		rdfs:comment "A DynManifest MUST have at least one lv2:binary."
 	] ;
-	rdfs:comment """The class which represents a dynamic manifest generator.
-
-There MUST NOT be any instances of dman:DynManifest in the generated manifest.
+	rdfs:comment "Dynamic manifest for an LV2 binary." .
 
-All relative URIs in the generated data MUST be relative to the base path that would be used to parse a normal LV2 manifest (the bundle path).""" .
diff --git a/sys/lv2/dynmanifest/lv2-dynmanifest.doap.ttl b/sys/lv2/dynmanifest/lv2-dynmanifest.doap.ttl
deleted file mode 100644
index 9dd6c817..00000000
--- a/sys/lv2/dynmanifest/lv2-dynmanifest.doap.ttl
+++ /dev/null
@@ -1,55 +0,0 @@
-@prefix dcs: <http://ontologi.es/doap-changeset#> .
-@prefix doap: <http://usefulinc.com/ns/doap#> .
-@prefix foaf: <http://xmlns.com/foaf/0.1/> .
-@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-
-<http://lv2plug.in/ns/ext/dynmanifest>
-	a doap:Project ;
-	doap:license <http://opensource.org/licenses/isc> ;
-	doap:name "LV2 Dynamic Manifest" ;
-	doap:homepage <http://naspro.atheme.org> ;
-	doap:created "2009-06-13" ;
-	doap:shortdesc "Support for dynamic data generation." ;
-	doap:programming-language "C" ;
-	doap:developer <http://lv2plug.in/ns/meta#daste> ;
-	doap:release [
-		doap:revision "1.6" ;
-		doap:created "2012-10-14" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Use consistent label style."
-			]
-		]
-	] , [
-		doap:revision "1.4" ;
-		doap:created "2012-04-17" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Merge with unified LV2 package."
-			]
-		]
-	] , [
-		doap:revision "1.2" ;
-		doap:created "2011-11-21" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-dynmanifest-1.2.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Improve documentation."
-			]
-		]
-	] , [
-		doap:revision "1.0" ;
-		doap:created "2010-04-10" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-dyn-manifest-1.0.tar.gz> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Initial release."
-			]
-		]
-	] .
diff --git a/sys/lv2/dynmanifest/manifest.ttl b/sys/lv2/dynmanifest/manifest.ttl
index 784fb308..db27a731 100644
--- a/sys/lv2/dynmanifest/manifest.ttl
+++ b/sys/lv2/dynmanifest/manifest.ttl
@@ -1,4 +1,4 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/dynmanifest>
@@ -6,3 +6,4 @@
 	lv2:minorVersion 1 ;
 	lv2:microVersion 6 ;
 	rdfs:seeAlso <dynmanifest.ttl> .
+
diff --git a/sys/lv2/event/NEWS b/sys/lv2/event/NEWS
deleted file mode 100644
index 20a7d955..00000000
--- a/sys/lv2/event/NEWS
+++ /dev/null
@@ -1,49 +0,0 @@
-event (1.12) stable;
-
-  * Minor documentation improvements.
-
- -- None <None>  Fri, 08 Aug 2014 00:00:00 +0000
-
-event (1.10) stable;
-
-  * Fix incorrect return type in lv2_event_get().
-
- -- None <None>  Sun, 13 Jan 2013 00:00:00 +0000
-
-event (1.8) stable;
-
-  * Make event iterator gracefully handle optional ports.
-  * Use consistent label style.
-  * Remove asserts from event-helper.h.
-  * Use more precise domain and range for EventPort properties.
-
- -- None <None>  Sun, 14 Oct 2012 00:00:00 +0000
-
-event (1.6) stable;
-
-  * Fix bug in lv2_event_reserve().
-  * Fix incorrect ranges of some properties.
-  * Merge with unified LV2 package.
-
- -- None <None>  Tue, 17 Apr 2012 00:00:00 +0000
-
-event (1.4) stable;
-
-  * Update packaging.
-
- -- None <None>  Mon, 21 Nov 2011 00:00:00 +0000
-
-event (1.2) stable;
-
-  * Add build system (for installation).
-  * Convert documentation to HTML and use lv2:documentation.
-  * Use lv2:Specification to be discovered as an extension.
-
- -- None <None>  Thu, 26 May 2011 00:00:00 +0000
-
-event (1.0) stable;
-
-  * Initial release.
-
- -- None <None>  Wed, 24 Nov 2010 00:00:00 +0000
-
diff --git a/sys/lv2/event/event-helpers.h b/sys/lv2/event/event-helpers.h
index af72d763..ca3abec7 100644
--- a/sys/lv2/event/event-helpers.h
+++ b/sys/lv2/event/event-helpers.h
@@ -90,7 +90,7 @@ lv2_event_buffer_new(uint32_t capacity, uint16_t stamp_type)
 /** An iterator over an LV2_Event_Buffer.
  *
  * Multiple simultaneous read iterators over a single buffer is fine,
- * but changing the buffer invalidates all iterators (e.g. RW Lock). */
+ * but changing the buffer invalidates all iterators. */
 typedef struct {
 	LV2_Event_Buffer* buf;
 	uint32_t          offset;
diff --git a/sys/lv2/event/event.h b/sys/lv2/event/event.h
index 70cae6a3..aa673909 100644
--- a/sys/lv2/event/event.h
+++ b/sys/lv2/event/event.h
@@ -17,6 +17,7 @@
 
 /**
    @defgroup event Event
+   @ingroup lv2
 
    Generic time-stamped events, see <http://lv2plug.in/ns/ext/event> for
    details.
@@ -80,7 +81,7 @@ typedef struct {
 	   The frames portion of timestamp. The units used here can optionally be
 	   set for a port (with the lv2ev:timeUnits property), otherwise this is
 	   audio frames, corresponding to the sample_count parameter of the LV2 run
-	   method (e.g. frame 0 is the first frame for that call to run).
+	   method (frame 0 is the first frame for that call to run).
 	*/
 	uint32_t frames;
 
diff --git a/sys/lv2/event/event.meta.ttl b/sys/lv2/event/event.meta.ttl
new file mode 100644
index 00000000..80593cef
--- /dev/null
+++ b/sys/lv2/event/event.meta.ttl
@@ -0,0 +1,246 @@
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix ev: <http://lv2plug.in/ns/ext/event#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/event>
+	a doap:Project ;
+	doap:license <http://opensource.org/licenses/isc> ;
+	doap:name "LV2 Event" ;
+	doap:shortdesc "A port-based real-time generic event interface." ;
+	doap:created "2008-00-00" ;
+	doap:developer <http://drobilla.net/drobilla#me> ,
+		<http://lv2plug.in/ns/meta#larsl> ;
+	doap:release [
+		doap:revision "1.12" ;
+		doap:created "2014-08-08" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.10.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Minor documentation improvements."
+			]
+		]
+	] , [
+		doap:revision "1.10" ;
+		doap:created "2013-01-13" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.4.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Fix incorrect return type in lv2_event_get()."
+			]
+		]
+	] , [
+		doap:revision "1.8" ;
+		doap:created "2012-10-14" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Make event iterator gracefully handle optional ports."
+			] , [
+				rdfs:label "Remove asserts from event-helper.h."
+			] , [
+				rdfs:label "Use more precise domain and range for EventPort properties."
+			] , [
+				rdfs:label "Use consistent label style."
+			]
+		]
+	] , [
+		doap:revision "1.6" ;
+		doap:created "2012-04-17" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Fix bug in lv2_event_reserve()."
+			] , [
+				rdfs:label "Fix incorrect ranges of some properties."
+			] , [
+				rdfs:label "Merge with unified LV2 package."
+			]
+		]
+	] , [
+		doap:revision "1.4" ;
+		doap:created "2011-11-21" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-event-1.4.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Update packaging."
+			]
+		]
+	] , [
+		doap:revision "1.2" ;
+		doap:created "2011-05-26" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-event-1.2.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add build system (for installation)."
+			] , [
+				rdfs:label "Convert documentation to HTML and use lv2:documentation."
+			] , [
+				rdfs:label "Use lv2:Specification to be discovered as an extension."
+			]
+		]
+	] , [
+		doap:revision "1.0" ;
+		doap:created "2010-11-24" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-event-1.0.tar.gz> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Initial release."
+			]
+		]
+	] ;
+	lv2:documentation """
+
+<span class="warning">This extension is deprecated.</span> New implementations
+should use <a href="atom.html">LV2 Atom</a> instead.
+
+This extension defines a generic time-stamped event port type, which can be
+used to create plugins that read and write real-time events, such as MIDI,
+OSC, or any other type of event payload.  The type(s) of event supported by
+a port is defined in the data file for a plugin, for example:
+
+    :::turtle
+    &lt;http://example.org/some-plugin&gt;
+        lv2:port [
+            a ev:EventPort, lv2:InputPort ;
+            lv2:index 0 ;
+            ev:supportsEvent &lt;http://lv2plug.in/ns/ext/midi#MidiEvent&gt; ;
+            lv2:symbol "midi_input" ;
+            lv2:name "MIDI input" ;
+        ] .
+
+"""^^lv2:Markdown .
+
+ev:EventPort
+	lv2:documentation """
+
+Ports of this type will be connected to a struct of type LV2_Event_Buffer,
+defined in event.h.  These ports contain a sequence of generic events (possibly
+several types mixed in a single stream), the specific types of which are
+defined by some URI in another LV2 extension.
+
+"""^^lv2:Markdown .
+
+ev:Event
+	a rdfs:Class ;
+	rdfs:label "Event" ;
+	lv2:documentation """
+
+An ev:EventPort contains an LV2_Event_Buffer which contains a sequence of these
+events.  The binary format of LV2 events is defined by the LV2_Event struct in
+event.h.
+
+Specific event types (such as MIDI or OSC) are defined by extensions, and
+should be rdfs:subClassOf this class.
+
+"""^^lv2:Markdown .
+
+ev:TimeStamp
+	lv2:documentation """
+
+This defines the meaning of the 'frames' and 'subframes' fields of an LV2_Event
+(both unsigned 32-bit integers).
+
+"""^^lv2:Markdown .
+
+ev:FrameStamp
+	lv2:documentation """
+
+The default time stamp unit for an LV2 event: the frames field represents audio
+frames (in the sample rate passed to intantiate), and the subframes field is
+1/UINT32_MAX of a frame.
+
+"""^^lv2:Markdown .
+
+ev:generic
+	lv2:documentation """
+
+Indicates that this port does something meaningful for any event type.  This is
+useful for things like event mixers, delays, serialisers, and so on.
+
+If this property is set, hosts should consider the port suitable for any type
+of event.  Otherwise, hosts should consider the port 'appropriate' only for the
+specific event types listed with :supportsEvent.  Note that plugins must
+gracefully handle unknown event types whether or not this property is present.
+
+"""^^lv2:Markdown .
+
+ev:supportsEvent
+	lv2:documentation """
+
+Indicates that this port supports or "understands" a certain event type.
+
+For input ports, this means the plugin understands and does something useful
+with events of this type.  For output ports, this means the plugin may generate
+events of this type.  If the plugin never actually generates events of this
+type, but might pass them through from an input, this property should not be
+set (use ev:inheritsEvent for that).
+
+Plugins with event input ports must always gracefully handle any type of event,
+even if it does not 'support' it.  This property should always be set for event
+types the plugin understands/generates so hosts can discover plugins
+appropriate for a given scenario (for example, plugins with a MIDI input).
+Hosts are not expected to consider event ports suitable for some type of event
+if the relevant :supportsEvent property is not set, unless the ev:generic
+property for that port is also set.
+
+
+"""^^lv2:Markdown .
+
+ev:inheritsEvent
+	lv2:documentation """
+
+Indicates that this output port might pass through events that arrived at some
+other input port (or generate an event of the same type as events arriving at
+that input).  The host must always check the stamp type of all outputs when
+connecting an input, but this property should be set whenever it applies.
+
+
+"""^^lv2:Markdown .
+
+ev:supportsTimeStamp
+	lv2:documentation """
+
+Indicates that this port supports or "understands" a certain time stamp type.
+Meaningful only for input ports, the host must never connect a port to an event
+buffer with a time stamp type that isn't supported by the port.
+
+"""^^lv2:Markdown .
+
+ev:generatesTimeStamp
+	lv2:documentation """
+
+Indicates that this port may output a certain time stamp type, regardless of
+the time stamp type of any input ports.
+
+If the port outputs stamps based on what type inputs are connected to, this
+property should not be set (use the ev:inheritsTimeStamp property for that).
+Hosts MUST check the time_stamp value of any output port buffers after a call
+to connect_port on ANY event input port on the plugin.
+
+If the plugin changes the stamp_type field of an output event buffer during a
+call to run(), the plugin must call the stamp_type_changed function provided by
+the host in the LV2_Event_Feature struct, if it is non-NULL.
+
+"""^^lv2:Markdown .
+
+ev:inheritsTimeStamp
+	lv2:documentation """
+
+Indicates that this port follows the time stamp type of an input port.
+
+This property is not necessary, but it should be set for outputs that base
+their output type on an input port so the host can make more sense of the
+plugin and provide a more sensible interface.
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/event/event.ttl b/sys/lv2/event/event.ttl
index 94e429fd..de400d43 100644
--- a/sys/lv2/event/event.ttl
+++ b/sys/lv2/event/event.ttl
@@ -1,114 +1,86 @@
-@prefix ev:   <http://lv2plug.in/ns/ext/event#> .
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
-@prefix owl:  <http://www.w3.org/2002/07/owl#> .
-@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix ev: <http://lv2plug.in/ns/ext/event#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/event>
 	a owl:Ontology ;
 	owl:deprecated true ;
+	rdfs:label "LV2 Event" ;
+	rdfs:comment "A port-based real-time generic event interface." ;
 	rdfs:seeAlso <event.h> ,
 		<event-helpers.h> ,
-		<lv2-event.doap.ttl> ;
-	lv2:documentation """
-<p>This extension defines a generic time-stamped event port type, which can be
-used to create plugins that read and write real-time events, such as MIDI,
-OSC, or any other type of event payload.  The type(s) of event supported by
-a port is defined in the data file for a plugin, for example:</p>
-<pre class="turtle-code">
-&lt;http://example.org/some-plugin&gt;
-    lv2:port [
-        a ev:EventPort, lv2:InputPort ;
-        lv2:index 0 ;
-        ev:supportsEvent &lt;http://lv2plug.in/ns/ext/midi#MidiEvent&gt; ;
-        lv2:symbol "midi_input" ;
-        lv2:name "MIDI input" ;
-    ] .
-</pre>
-""" .
+		<event.meta.ttl> .
 
 ev:EventPort
 	a rdfs:Class ;
 	rdfs:label "Event Port" ;
 	rdfs:subClassOf lv2:Port ;
-	rdfs:comment """Ports of this type will be connected to a struct of type LV2_Event_Buffer, defined in event.h.  These ports contain a sequence of generic events (possibly several types mixed in a single stream), the specific types of which are defined by some URI in another LV2 extension.""" .
+	rdfs:comment "An LV2 event port." .
 
 ev:Event
 	a rdfs:Class ;
 	rdfs:label "Event" ;
-	rdfs:comment """A single generic time-stamped event.
-
-An ev:EventPort contains an LV2_Event_Buffer which contains a sequence of these events.  The binary format of LV2 events is defined by the LV2_Event struct in event.h.
-
-Specific event types (e.g. MIDI, OSC) are defined by extensions, and should be rdfs:subClassOf this class.""" .
+	rdfs:comment "A single generic time-stamped event." .
 
 ev:TimeStamp
 	a rdfs:Class ;
 	rdfs:label "Event Time Stamp" ;
-	rdfs:comment """The time stamp of an Event.
-
-This defines the meaning of the 'frames' and 'subframes' fields of an LV2_Event (both unsigned 32-bit integers).""" .
+	rdfs:comment "The time stamp of an Event." .
 
 ev:FrameStamp
 	a rdfs:Class ;
 	rdfs:subClassOf ev:TimeStamp ;
 	rdfs:label "Audio Frame Time Stamp" ;
-	rdfs:comment """The default time stamp unit for an LV2 event: the frames field represents
-audio frames (in the sample rate passed to intantiate), and the subframes
-field is 1/UINT32_MAX of a frame.""" .
+	rdfs:comment "The default time stamp unit for an event." .
 
 ev:generic
 	a lv2:PortProperty ;
 	rdfs:label "generic event port" ;
-	rdfs:comment """Indicates that this port does something meaningful for any event type (e.g. event mixers, delays, serialisers, etc).
-
-If this property is set, hosts should consider the port suitable for any type of event.  Otherwise, hosts should consider the port 'appropriate' only for the specific event types listed with :supportsEvent.  Note that plugins must gracefully handle unknown event types whether or not this property is present.""" .
+	rdfs:comment "Port works with generic events." .
 
 ev:supportsEvent
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:ObjectProperty ;
 	rdfs:domain ev:EventPort ;
 	rdfs:range rdfs:Class ;
 	rdfs:label "supports event type" ;
-	rdfs:comment """Indicates that this port supports or "understands" a certain event type.
-
-For input ports, this means the plugin understands and does something useful with events of this type.  For output ports, this means the plugin may generate events of this type.  If the plugin never actually generates events of this type, but might pass them through from an input, this property should not be set (use ev:inheritsEvent for that).
-
-Plugins with event input ports must always gracefully handle any type of event, even if it does not 'support' it.  This property should always be set for event types the plugin understands/generates so hosts can discover plugins appropriate for a given scenario (e.g. plugins with a MIDI input). Hosts are not expected to consider event ports suitable for some type of event if the relevant :supportsEvent property is not set, unless the ev:generic property for that port is also set.""" .
+	rdfs:comment "An event type supported by this port." .
 
 ev:inheritsEvent
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:ObjectProperty ;
 	rdfs:domain ev:EventPort ,
 		lv2:OutputPort ;
 	rdfs:range lv2:Port ;
 	rdfs:label "inherits event type" ;
-	rdfs:comment """Indicates that this output port might pass through events that arrived at some other input port (or generate an event of the same type as events arriving at that input).  The host must always check the stamp type of all outputs when connecting an input, but this property should be set whenever it applies.""" .
+	rdfs:comment "Output port inherits event types from an input port." .
 
 ev:supportsTimeStamp
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:ObjectProperty ;
 	rdfs:domain ev:EventPort ,
 		lv2:InputPort ;
 	rdfs:range rdfs:Class ;
 	rdfs:label "supports time stamp type" ;
-	rdfs:comment """Indicates that this port supports or "understands" a certain time stamp type.  Meaningful only for input ports, the host must never connect a port to an event buffer with a time stamp type that isn't supported by the port.""" .
+	rdfs:comment "A time stamp type suported by this input port." .
 
 ev:generatesTimeStamp
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:ObjectProperty ;
 	rdfs:domain ev:EventPort ,
 		lv2:OutputPort ;
 	rdfs:range rdfs:Class ;
 	rdfs:label "generates time stamp type" ;
-	rdfs:comment """Indicates that this port may output a certain time stamp type, regardless of the time stamp type of any input ports.
-
-If the port outputs stamps based on what type inputs are connected to, this property should not be set (use the ev:inheritsTimeStamp property for that).  Hosts MUST check the time_stamp value of any output port buffers after a call to connect_port on ANY event input port on the plugin.
-
-If the plugin changes the stamp_type field of an output event buffer during a call to run(), the plugin must call the stamp_type_changed function provided by the host in the LV2_Event_Feature struct, if it is non-NULL.""" .
+	rdfs:comment "A time stamp type generated by this input port." .
 
 ev:inheritsTimeStamp
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:ObjectProperty ;
 	rdfs:domain ev:EventPort ,
 		lv2:OutputPort ;
 	rdfs:range lv2:Port ;
 	rdfs:label "inherits time stamp type" ;
-	rdfs:comment """Indicates that this port follows the time stamp type of an input port.
+	rdfs:comment "Output port inherits time stamp types from an input port." .
 
-This property is not necessary, but it should be set for outputs that base their output type on an input port so the host can make more sense of the plugin and provide a more sensible interface.""" .
diff --git a/sys/lv2/event/lv2-event.doap.ttl b/sys/lv2/event/lv2-event.doap.ttl
deleted file mode 100644
index 5051237b..00000000
--- a/sys/lv2/event/lv2-event.doap.ttl
+++ /dev/null
@@ -1,98 +0,0 @@
-@prefix dcs: <http://ontologi.es/doap-changeset#> .
-@prefix doap: <http://usefulinc.com/ns/doap#> .
-@prefix foaf: <http://xmlns.com/foaf/0.1/> .
-@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-
-<http://lv2plug.in/ns/ext/event>
-	a doap:Project ;
-	doap:license <http://opensource.org/licenses/isc> ;
-	doap:name "LV2 Event" ;
-	doap:shortdesc "A port-based real-time generic event interface." ;
-	doap:created "2008-00-00" ;
-	doap:developer <http://drobilla.net/drobilla#me> ,
-		<http://lv2plug.in/ns/meta#larsl> ;
-	doap:release [
-		doap:revision "1.12" ;
-		doap:created "2014-08-08" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.10.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Minor documentation improvements."
-			]
-		]
-	] , [
-		doap:revision "1.10" ;
-		doap:created "2013-01-13" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.4.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Fix incorrect return type in lv2_event_get()."
-			]
-		]
-	] , [
-		doap:revision "1.8" ;
-		doap:created "2012-10-14" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Make event iterator gracefully handle optional ports."
-			] , [
-				rdfs:label "Remove asserts from event-helper.h."
-			] , [
-				rdfs:label "Use more precise domain and range for EventPort properties."
-			] , [
-				rdfs:label "Use consistent label style."
-			]
-		]
-	] , [
-		doap:revision "1.6" ;
-		doap:created "2012-04-17" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Fix bug in lv2_event_reserve()."
-			] , [
-				rdfs:label "Fix incorrect ranges of some properties."
-			] , [
-				rdfs:label "Merge with unified LV2 package."
-			]
-		]
-	] , [
-		doap:revision "1.4" ;
-		doap:created "2011-11-21" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-event-1.4.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Update packaging."
-			]
-		]
-	] , [
-		doap:revision "1.2" ;
-		doap:created "2011-05-26" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-event-1.2.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Add build system (for installation)."
-			] , [
-				rdfs:label "Convert documentation to HTML and use lv2:documentation."
-			] , [
-				rdfs:label "Use lv2:Specification to be discovered as an extension."
-			]
-		]
-	] , [
-		doap:revision "1.0" ;
-		doap:created "2010-11-24" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-event-1.0.tar.gz> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Initial release."
-			]
-		]
-	] .
diff --git a/sys/lv2/event/manifest.ttl b/sys/lv2/event/manifest.ttl
index 0b454e25..0194d717 100644
--- a/sys/lv2/event/manifest.ttl
+++ b/sys/lv2/event/manifest.ttl
@@ -1,4 +1,4 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/event>
diff --git a/sys/lv2/instance-access/NEWS b/sys/lv2/instance-access/NEWS
deleted file mode 100644
index 287916ad..00000000
--- a/sys/lv2/instance-access/NEWS
+++ /dev/null
@@ -1,26 +0,0 @@
-instance-access (1.6) stable;
-
-  * Merge with unified LV2 package.
-
- -- None <None>  Tue, 17 Apr 2012 00:00:00 +0000
-
-instance-access (1.4) stable;
-
-  * Update packaging.
-  * Improve documentation.
-
- -- None <None>  Mon, 21 Nov 2011 00:00:00 +0000
-
-instance-access (1.2) stable;
-
-  * Add build system for installation.
-  * Switch to ISC license.
-
- -- None <None>  Thu, 26 May 2011 00:00:00 +0000
-
-instance-access (1.0) stable;
-
-  * Initial release.
-
- -- None <None>  Mon, 04 Oct 2010 00:00:00 +0000
-
diff --git a/sys/lv2/instance-access/instance-access.h b/sys/lv2/instance-access/instance-access.h
index 7e328fd8..6a585417 100644
--- a/sys/lv2/instance-access/instance-access.h
+++ b/sys/lv2/instance-access/instance-access.h
@@ -17,6 +17,7 @@
 
 /**
    @defgroup instance-access Instance Access
+   @ingroup lv2
 
    Access to the LV2_Handle of a plugin for UIs; see
    <http://lv2plug.in/ns/ext/instance-access> for details.
diff --git a/sys/lv2/instance-access/lv2-instance-access.doap.ttl b/sys/lv2/instance-access/instance-access.meta.ttl
similarity index 68%
rename from sys/lv2/instance-access/lv2-instance-access.doap.ttl
rename to sys/lv2/instance-access/instance-access.meta.ttl
index 5aa70d8c..875e2f84 100644
--- a/sys/lv2/instance-access/lv2-instance-access.doap.ttl
+++ b/sys/lv2/instance-access/instance-access.meta.ttl
@@ -1,6 +1,8 @@
 @prefix dcs: <http://ontologi.es/doap-changeset#> .
 @prefix doap: <http://usefulinc.com/ns/doap#> .
 @prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix ia: <http://lv2plug.in/ns/ext/instance-access#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/instance-access>
@@ -54,4 +56,20 @@
 				rdfs:label "Initial release."
 			]
 		]
-	] .
+	] ;
+	lv2:documentation """
+
+This extension defines a feature which allows plugin UIs to get a direct handle
+to an LV2 plugin instance (LV2_Handle), if possible.
+
+Note that the use of this extension by UIs violates the important principle of
+UI/plugin separation, and is potentially a source of many problems.
+Accordingly, **use of this extension is highly discouraged**, and plugins
+should not expect hosts to support it, since it is often impossible to do so.
+
+To support this feature the host must pass an LV2_Feature struct to the UI
+instantiate method with URI LV2_INSTANCE_ACCESS_URI and data pointed directly
+to the LV2_Handle of the plugin instance.
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/instance-access/instance-access.ttl b/sys/lv2/instance-access/instance-access.ttl
index 5656345c..085ae37d 100644
--- a/sys/lv2/instance-access/instance-access.ttl
+++ b/sys/lv2/instance-access/instance-access.ttl
@@ -1,22 +1,11 @@
-@prefix ia:   <http://lv2plug.in/ns/ext/instance-access#> .
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix ia: <http://lv2plug.in/ns/ext/instance-access#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/instance-access>
 	a lv2:Feature ;
+	rdfs:label "instance access" ;
+	rdfs:comment "A feature that provides access to a plugin instance." ;
 	rdfs:seeAlso <instance-access.h> ,
-		<lv2-instance-access.doap.ttl> ;
-	lv2:documentation """
-<p>This extension defines a feature which allows plugin UIs to get a direct
-handle to an LV2 plugin instance (LV2_Handle), if possible.</p>
+		<instance-access.meta.ttl> .
 
-<p>Note that the use of this extension by UIs violates the important principle
-of UI/plugin separation, and is potentially a source of many problems.
-Accordingly, <strong>use of this extension is highly discouraged</strong>, and
-plugins should not expect hosts to support it, since it is often impossible to
-do so.</p>
-
-<p>To support this feature the host must pass an LV2_Feature struct to the UI
-instantiate method with URI LV2_INSTANCE_ACCESS_URI and data pointed directly
-to the LV2_Handle of the plugin instance.</p>
-""" .
diff --git a/sys/lv2/instance-access/manifest.ttl b/sys/lv2/instance-access/manifest.ttl
index cee5dbfe..e6c88107 100644
--- a/sys/lv2/instance-access/manifest.ttl
+++ b/sys/lv2/instance-access/manifest.ttl
@@ -1,4 +1,4 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/instance-access>
diff --git a/sys/lv2/log/NEWS b/sys/lv2/log/NEWS
deleted file mode 100644
index 6091f187..00000000
--- a/sys/lv2/log/NEWS
+++ /dev/null
@@ -1,24 +0,0 @@
-log (2.4) stable;
-
-  * Add lv2_log_logger_set_map() for changing the URI map of an existing logger.
-
- -- None <None>  Sat, 30 Jul 2016 00:00:00 +0000
-
-log (2.2) stable;
-
-  * Add missing include string.h to logger.h for memset.
-
- -- None <None>  Sat, 04 Jan 2014 00:00:00 +0000
-
-log (2.0) stable;
-
-  * Add logger convenience API.
-
- -- None <None>  Tue, 08 Jan 2013 00:00:00 +0000
-
-log (1.0) stable;
-
-  * Initial release.
-
- -- None <None>  Tue, 17 Apr 2012 00:00:00 +0000
-
diff --git a/sys/lv2/log/log.h b/sys/lv2/log/log.h
index 7175339d..8930fac1 100644
--- a/sys/lv2/log/log.h
+++ b/sys/lv2/log/log.h
@@ -16,6 +16,7 @@
 
 /**
    @defgroup log Log
+   @ingroup lv2
 
    Interface for plugins to log via the host; see
    <http://lv2plug.in/ns/ext/log> for details.
@@ -61,7 +62,7 @@ typedef void* LV2_Log_Handle;
 /**
    Log feature (LV2_LOG__log)
 */
-typedef struct _LV2_Log {
+typedef struct {
 	/**
 	   Opaque pointer to host data.
 
diff --git a/sys/lv2/log/log.meta.ttl b/sys/lv2/log/log.meta.ttl
new file mode 100644
index 00000000..87cff438
--- /dev/null
+++ b/sys/lv2/log/log.meta.ttl
@@ -0,0 +1,126 @@
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix log: <http://lv2plug.in/ns/ext/log#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/log>
+	a doap:Project ;
+	doap:name "LV2 Log" ;
+	doap:shortdesc "A feature for writing log messages." ;
+	doap:created "2012-01-12" ;
+	doap:developer <http://drobilla.net/drobilla#me> ;
+	doap:release [
+		doap:revision "2.4" ;
+		doap:created "2016-07-30" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.14.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add lv2_log_logger_set_map() for changing the URI map of an existing logger."
+			]
+		]
+	] , [
+		doap:revision "2.2" ;
+		doap:created "2014-01-04" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.8.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add missing include string.h to logger.h for memset."
+			]
+		]
+	] , [
+		doap:revision "2.0" ;
+		doap:created "2013-01-08" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.4.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add logger convenience API."
+			]
+		]
+	] , [
+		doap:revision "1.0" ;
+		doap:created "2012-04-17" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Initial release."
+			]
+		]
+	] ;
+	lv2:documentation """
+
+This extension defines a feature, log:log, which allows plugins to print log
+messages with an API similar to the standard C `printf` function.  This allows,
+for example, plugin logs to be nicely presented to the user in a graphical user
+interface.
+
+Different log levels are defined by URI and passed as an LV2_URID.  This
+extensions defines standard levels which are expected to be understood by all
+implementations and should be sufficient in most cases, but advanced
+implementations may define and use additional levels to suit their needs.
+
+"""^^lv2:Markdown .
+
+log:Entry
+	a rdfs:Class ;
+	rdfs:label "Log Entry" ;
+	lv2:documentation """
+
+Subclasses of this are passed as the `type` parameter to LV2_Log_Log methods to
+describe the nature of the log entry.
+
+"""^^lv2:Markdown .
+
+log:Error
+	lv2:documentation """
+
+An error should only be posted when a serious unexpected error occurs, and
+should be actively shown to the user by the host.
+
+"""^^lv2:Markdown .
+
+log:Note
+	lv2:documentation """
+
+A note records some useful piece of information, but may be ignored.  The host
+should provide passive access to note entries to the user.
+
+"""^^lv2:Markdown .
+
+log:Warning
+	lv2:documentation """
+
+A warning should be posted when an unexpected, but non-critical, error occurs.
+The host should provide passive access to warnings entries to the user, but may
+also choose to actively show them.
+
+"""^^lv2:Markdown .
+
+log:Trace
+	lv2:documentation """
+
+A trace should not be displayed during normal operation, but the host may
+implement an option to display them for debugging purposes.
+
+This entry type is special in that one may be posted in a real-time thread.  It
+is assumed that if debug tracing is enabled, real-time performance is not a
+concern.  However, the host MUST guarantee that posting a trace _is_ real-time
+safe if debug tracing is not enabled (for example, by simply ignoring the call
+as early as possible).
+
+"""^^lv2:Markdown .
+
+log:log
+	lv2:documentation """
+
+A feature which plugins may use to log messages.  To support this feature,
+the host must pass an LV2_Feature to LV2_Descriptor::instantiate() with URI
+LV2_LOG__log and data pointed to an instance of LV2_Log_Log.
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/log/log.ttl b/sys/lv2/log/log.ttl
index 60e1d3fc..46cba45e 100644
--- a/sys/lv2/log/log.ttl
+++ b/sys/lv2/log/log.ttl
@@ -1,31 +1,21 @@
-@prefix log:  <http://lv2plug.in/ns/ext/log#> .
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
-@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix log: <http://lv2plug.in/ns/ext/log#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
 
 <http://lv2plug.in/ns/ext/log>
-	a lv2:Specification ;
+	a owl:Ontology ;
+	rdfs:label "LV2 Log" ;
+	rdfs:comment "A feature for writing log messages." ;
 	rdfs:seeAlso <log.h> ,
-		<lv2-log.doap.ttl> ;
-	lv2:documentation """
-<p>This extension defines a feature, log:log, which allows plugins to print log
-messages with an API much like the standard C printf functions.  This allows,
-for example, plugin logs to be nicely presented to the user in a graphical user
-interface.</p>
-
-<p>Different log levels (e.g. <q>error</q> or <q>information</q>) are defined
-by URI and passed as an LV2_URID.  This document defines the typical levels
-which should be sufficient, but implementations may define and use additional
-levels to suit their needs.</p>
-""" .
+		<log.meta.ttl> .
 
 log:Entry
 	a rdfs:Class ;
-	rdfs:label "Log Entry" ;
-	lv2:documentation """
-<p>A log entry.  Subclasses of this class can be passed to LV2_Log_Log methods
-to describe the nature of the log message.</p>""" .
+	rdfs:label "Entry" ;
+	rdfs:comment "A log entry." .
 
 log:Error
 	a rdfs:Class ;
@@ -49,20 +39,10 @@ log:Trace
 	a rdfs:Class ;
 	rdfs:label "Trace" ;
 	rdfs:subClassOf log:Entry ;
-	lv2:documentation """
-<p>A debugging trace.  These entries should not be displayed during normal
-operation, but the host may implement an option to display them for debugging
-purposes.</p>
-
-<p>This entry type is special in that it may be written to in a real-time
-thread.  It is assumed that if debug tracing is enabled, real-time
-considerations are not a concern.</p>
-""" .
+	rdfs:comment "A debugging trace message." .
 
 log:log
 	a lv2:Feature ;
-	lv2:documentation """
-<p>A feature which plugins may use to log messages.  To support this feature,
-the host must pass an LV2_Feature to LV2_Descriptor::instantiate() with URI
-LV2_LOG__log and data pointed to an instance of LV2_Log_Log.</p>
-""" .
+	rdfs:label "log" ;
+	rdfs:comment "Logging feature." .
+
diff --git a/sys/lv2/log/lv2-log.doap.ttl b/sys/lv2/log/lv2-log.doap.ttl
deleted file mode 100644
index d109809e..00000000
--- a/sys/lv2/log/lv2-log.doap.ttl
+++ /dev/null
@@ -1,52 +0,0 @@
-@prefix dcs: <http://ontologi.es/doap-changeset#> .
-@prefix doap: <http://usefulinc.com/ns/doap#> .
-@prefix foaf: <http://xmlns.com/foaf/0.1/> .
-@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-
-<http://lv2plug.in/ns/ext/log>
-	a doap:Project ;
-	doap:name "LV2 Log" ;
-	doap:shortdesc "A feature for writing log messages." ;
-	doap:created "2012-01-12" ;
-	doap:developer <http://drobilla.net/drobilla#me> ;
-	doap:release [
-		doap:revision "2.4" ;
-		doap:created "2016-07-30" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.14.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Add lv2_log_logger_set_map() for changing the URI map of an existing logger."
-			]
-		]
-	] , [
-		doap:revision "2.2" ;
-		doap:created "2014-01-04" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.8.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Add missing include string.h to logger.h for memset."
-			]
-		]
-	] , [
-		doap:revision "2.0" ;
-		doap:created "2013-01-08" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.4.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Add logger convenience API."
-			]
-		]
-	] , [
-		doap:revision "1.0" ;
-		doap:created "2012-04-17" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Initial release."
-			]
-		]
-	] .
diff --git a/sys/lv2/log/manifest.ttl b/sys/lv2/log/manifest.ttl
index afe74491..bcaeff3d 100644
--- a/sys/lv2/log/manifest.ttl
+++ b/sys/lv2/log/manifest.ttl
@@ -1,4 +1,4 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/log>
diff --git a/sys/lv2/midi/NEWS b/sys/lv2/midi/NEWS
deleted file mode 100644
index 80bad059..00000000
--- a/sys/lv2/midi/NEWS
+++ /dev/null
@@ -1,45 +0,0 @@
-midi (1.10) stable;
-
-  * Fix incorrect range of midi:chunk.
-
- -- None <None>  Sun, 03 Feb 2019 00:00:00 +0000
-
-midi (1.8) stable;
-
-  * Add midi:HexByte datatype for status bytes and masks.
-  * Add midi:binding and midi:channel predicates.
-  * Remove non-standard midi:Tick message type.
-  * Use consistent label style.
-  * Add C definitions for message types and standard controllers.
-  * Fix definition of SystemExclusive status byte.
-
- -- None <None>  Sun, 14 Oct 2012 00:00:00 +0000
-
-midi (1.6) stable;
-
-  * Document how to serialise a MidiEvent to a string.
-  * Merge with unified LV2 package.
-  * Add class definitions for various message types.
-
- -- None <None>  Tue, 17 Apr 2012 00:00:00 +0000
-
-midi (1.4) stable;
-
-  * Improve documentation.
-  * Update packaging.
-
- -- None <None>  Mon, 21 Nov 2011 00:00:00 +0000
-
-midi (1.2) stable;
-
-  * Switch to ISC license.
-  * Add build system for installation.
-
- -- None <None>  Thu, 26 May 2011 00:00:00 +0000
-
-midi (1.0) stable;
-
-  * Initial release.
-
- -- None <None>  Mon, 04 Oct 2010 00:00:00 +0000
-
diff --git a/sys/lv2/midi/manifest.ttl b/sys/lv2/midi/manifest.ttl
index 6dd7db67..f1419367 100644
--- a/sys/lv2/midi/manifest.ttl
+++ b/sys/lv2/midi/manifest.ttl
@@ -1,4 +1,4 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/midi>
diff --git a/sys/lv2/midi/midi.h b/sys/lv2/midi/midi.h
index 52e99563..0abfba14 100644
--- a/sys/lv2/midi/midi.h
+++ b/sys/lv2/midi/midi.h
@@ -16,6 +16,7 @@
 
 /**
    @defgroup midi MIDI
+   @ingroup lv2
 
    Definitions of standard MIDI messages, see <http://lv2plug.in/ns/ext/midi>
    for details.
diff --git a/sys/lv2/midi/lv2-midi.doap.ttl b/sys/lv2/midi/midi.meta.ttl
similarity index 56%
rename from sys/lv2/midi/lv2-midi.doap.ttl
rename to sys/lv2/midi/midi.meta.ttl
index 8a9315af..7efdb017 100644
--- a/sys/lv2/midi/lv2-midi.doap.ttl
+++ b/sys/lv2/midi/midi.meta.ttl
@@ -1,6 +1,8 @@
 @prefix dcs: <http://ontologi.es/doap-changeset#> .
 @prefix doap: <http://usefulinc.com/ns/doap#> .
 @prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix midi: <http://lv2plug.in/ns/ext/midi#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/midi>
@@ -90,4 +92,62 @@
 				rdfs:label "Initial release."
 			]
 		]
-	] .
+	] ;
+	lv2:documentation """
+
+This specification defines a data type for a MIDI message, midi:MidiEvent,
+which is normalised for fast and convenient real-time processing.  MIDI is the
+<q>Musical Instrument Digital Interface</q>, a ubiquitous binary standard for
+controlling digital music devices.
+
+For plugins that process MIDI (or other situations where MIDI is sent via a
+generic transport) the main type defined here, midi:MidiEvent, can be mapped to
+an integer and used as the type of an LV2 [Atom](atom.html#Atom) or
+[Event](event.html#Event).
+
+This specification also defines a complete vocabulary for the MIDI standard,
+except for standard controller numbers.  These descriptions are detailed enough
+to express any MIDI message as properties.
+
+"""^^lv2:Markdown .
+
+midi:MidiEvent
+	lv2:documentation """
+
+A single raw MIDI message (a sequence of bytes).
+
+This is equivalent to a standard MIDI messages, except with the following
+restrictions to simplify handling:
+
+  * Running status is not allowed, every message must have its own status byte.
+
+  * Note On messages with velocity 0 are not allowed.  These messages are
+    equivalent to Note Off in standard MIDI streams, but here only proper Note
+    Off messages are allowed.
+
+  * "Realtime messages" (status bytes 0xF8 to 0xFF) are allowed, but may not
+     occur inside other messages like they can in standard MIDI streams.
+
+  * All messages are complete valid MIDI messages.  This means, for example,
+    that only the first byte in each event (the status byte) may have the
+    eighth bit set, that Note On and Note Off events are always 3 bytes long,
+    etc.
+
+Where messages are communicated, the writer is responsible for writing valid
+messages, and the reader may assume that all events are valid.
+
+If a midi:MidiEvent is serialised to a string, the format should be
+xsd:hexBinary, for example:
+
+    :::turtle
+    [] eg:someEvent "901A01"^^midi:MidiEvent .
+
+"""^^lv2:Markdown .
+
+midi:statusMask
+	lv2:documentation """
+
+This is a status byte with the lower nibble set to zero.
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/midi/midi.ttl b/sys/lv2/midi/midi.ttl
index 23e41b3a..81f34959 100644
--- a/sys/lv2/midi/midi.ttl
+++ b/sys/lv2/midi/midi.ttl
@@ -1,44 +1,31 @@
 @prefix atom: <http://lv2plug.in/ns/ext/atom#> .
-@prefix ev:   <http://lv2plug.in/ns/ext/event#> .
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix ev: <http://lv2plug.in/ns/ext/event#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix midi: <http://lv2plug.in/ns/ext/midi#> .
-@prefix owl:  <http://www.w3.org/2002/07/owl#> .
-@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
 
 <http://lv2plug.in/ns/ext/midi>
 	a owl:Ontology ;
+	rdfs:label "LV2 MIDI" ;
+	rdfs:comment "A normalised definition of raw MIDI." ;
 	rdfs:seeAlso <midi.h> ,
-		<lv2-midi.doap.ttl> ;
-	lv2:documentation """
-<p>This specification defines a data type for a MIDI message, midi:MidiEvent,
-which is normalised for fast and convenient real-time processing.  MIDI is the
-<q>Musical Instrument Digital Interface</q>, a ubiquitous binary standard for
-controlling digital music devices.</p>
-
-<p>For plugins that process MIDI (or other situations where MIDI is sent via a
-generic transport) the main type defined here, midi:MidiEvent, can be mapped to
-an integer and used as the type of an LV2 <a
-href="../atom/atom.html#Atom">Atom</a> or <a
-href="../event/event.html#Event">Event</a>.</p>
-
-<p>This specification also defines a complete human and machine readable
-description of the MIDI standard (except for standard controller numbers).
-These descriptions are detailed enough to express any MIDI message as
-properties.</p>
-""" .
+		<midi.meta.ttl> .
 
 midi:ActiveSense
 	a rdfs:Class ;
 	rdfs:subClassOf midi:SystemRealtime ;
-	rdfs:label "Active Sense Message" ;
+	rdfs:label "Active Sense" ;
+	rdfs:comment "MIDI active sense message." ;
 	midi:status "FE"^^xsd:hexBinary .
 
 midi:Aftertouch
 	a rdfs:Class ;
 	rdfs:subClassOf midi:VoiceMessage ;
-	rdfs:label "Aftertouch Message" ;
+	rdfs:label "Aftertouch" ;
+	rdfs:comment "MIDI aftertouch message." ;
 	midi:statusMask "A0"^^xsd:hexBinary ;
 	midi:chunk [
 		midi:byteNumber 0 ;
@@ -51,7 +38,8 @@ midi:Aftertouch
 midi:Bender
 	a rdfs:Class ;
 	rdfs:subClassOf midi:VoiceMessage ;
-	rdfs:label "Bender Message" ;
+	rdfs:label "Bender" ;
+	rdfs:comment "MIDI bender message." ;
 	midi:statusMask "E0"^^xsd:hexBinary ;
 	midi:chunk [
 		midi:byteNumber 0 ,
@@ -62,7 +50,8 @@ midi:Bender
 midi:ChannelPressure
 	a rdfs:Class ;
 	rdfs:subClassOf midi:VoiceMessage ;
-	rdfs:label "Channel Pressure Message" ;
+	rdfs:label "Channel Pressure" ;
+	rdfs:comment "MIDI channel pressure message." ;
 	midi:statusMask "D0"^^xsd:hexBinary ;
 	midi:chunk [
 		midi:byteNumber 0 ;
@@ -71,25 +60,28 @@ midi:ChannelPressure
 
 midi:Chunk
 	a rdfs:Class ;
-	rdfs:label "MIDI Chunk" ;
-	rdfs:comment "A series of contiguous bytes (usually one) in a message." .
+	rdfs:label "Chunk" ;
+	rdfs:comment "A sequence of contiguous bytes in a MIDI message." .
 
 midi:Clock
 	a rdfs:Class ;
 	rdfs:subClassOf midi:SystemRealtime ;
-	rdfs:label "Clock Message" ;
+	rdfs:label "Clock" ;
+	rdfs:comment "MIDI clock message." ;
 	midi:status "F8"^^xsd:hexBinary .
 
 midi:Continue
 	a rdfs:Class ;
 	rdfs:subClassOf midi:SystemRealtime ;
-	rdfs:label "Continue Message" ;
+	rdfs:label "Continue" ;
+	rdfs:comment "MIDI continue message." ;
 	midi:status "FB"^^xsd:hexBinary .
 
 midi:Controller
 	a rdfs:Class ;
 	rdfs:subClassOf midi:VoiceMessage ;
-	rdfs:label "Controller Change Message" ;
+	rdfs:label "Controller" ;
+	rdfs:comment "MIDI controller change message." ;
 	midi:statusMask "B0"^^xsd:hexBinary ;
 	midi:chunk [
 		midi:byteNumber 0 ;
@@ -107,50 +99,23 @@ midi:HexByte
 			xsd:maxInclusive "FF"
 		]
 	) ;
-	rdfs:comment "A hexadecimal byte, which is a xsd:hexBinary value <= FF" .
+	rdfs:label "Hex Byte" ;
+	rdfs:comment "A hexadecimal byte, which has a value <= FF." .
 
 midi:MidiEvent
 	a rdfs:Class ,
 		rdfs:Datatype ;
-	rdfs:label "MIDI Message" ;
 	rdfs:subClassOf ev:Event ,
 		atom:Atom ;
 	owl:onDatatype xsd:hexBinary ;
-	lv2:documentation """
-<p>A single raw MIDI message (i.e. a sequence of bytes).</p>
-
-<p>This is equivalent to a standard MIDI messages, except with the following
-restrictions to simplify handling:</p>
-<ul>
-  <li>Running status is not allowed, every message must have its own status
-  byte.</li>
-
-  <li>Note On messages with velocity 0 are not allowed.  These messages are
-  equivalent to Note Off in standard MIDI streams, but here only proper Note
-  Off messages are allowed.</li>
-
-  <li>"Realtime messages" (status bytes 0xF8 to 0xFF) are allowed, but may
-  not occur inside other messages like they can in standard MIDI streams.</li>
-
-  <li>All messages are complete valid MIDI messages.  This means, for example,
-  that only the first byte in each event (the status byte) may have the eighth
-  bit set, that Note On and Note Off events are always 3 bytes long, etc.
-  Where messages are communicated, the writer is responsible for writing valid
-  messages, and the reader may assume that all events are valid.</li>
-</ul>
-
-<p>If a midi:MidiEvent is serialised to a string, the format should be
-xsd:hexBinary, e.g. (in Turtle notation):</p>
-
-<pre class="turtle-code">
-[] eg:someEvent "901A01"^^midi:MidiEvent .
-</pre>
-""" .
+	rdfs:label "MIDI Message" ;
+	rdfs:comment "A single raw MIDI message." .
 
 midi:NoteOff
 	a rdfs:Class ;
 	rdfs:subClassOf midi:VoiceMessage ;
-	rdfs:label "Note Off Message" ;
+	rdfs:label "Note Off" ;
+	rdfs:comment "MIDI note off message." ;
 	midi:statusMask "80"^^xsd:hexBinary ;
 	midi:chunk [
 		midi:byteNumber 0 ;
@@ -163,7 +128,8 @@ midi:NoteOff
 midi:NoteOn
 	a rdfs:Class ;
 	rdfs:subClassOf midi:VoiceMessage ;
-	rdfs:label "Note On Message" ;
+	rdfs:label "Note On" ;
+	rdfs:comment "MIDI note on message." ;
 	midi:statusMask "90"^^xsd:hexBinary ;
 	midi:chunk [
 		midi:byteNumber 0 ;
@@ -176,7 +142,8 @@ midi:NoteOn
 midi:ProgramChange
 	a rdfs:Class ;
 	rdfs:subClassOf midi:VoiceMessage ;
-	rdfs:label "Program Change Message" ;
+	rdfs:label "Program Change" ;
+	rdfs:comment "MIDI program change message." ;
 	midi:statusMask "C0"^^xsd:hexBinary ;
 	midi:chunk [
 		midi:byteNumber 0 ;
@@ -186,19 +153,22 @@ midi:ProgramChange
 midi:QuarterFrame
 	a rdfs:Class ;
 	rdfs:subClassOf midi:SystemCommon ;
-	rdfs:label "Quarter Frame Message" ;
+	rdfs:label "Quarter Frame" ;
+	rdfs:comment "MIDI quarter frame message." ;
 	midi:status "F1"^^xsd:hexBinary .
 
 midi:Reset
 	a rdfs:Class ;
 	rdfs:subClassOf midi:SystemRealtime ;
-	rdfs:label "Reset Message" ;
+	rdfs:label "Reset" ;
+	rdfs:comment "MIDI reset message." ;
 	midi:status "FF"^^xsd:hexBinary .
 
 midi:SongPosition
 	a rdfs:Class ;
 	rdfs:subClassOf midi:SystemCommon ;
-	rdfs:label "Song Position Pointer Message" ;
+	rdfs:label "Song Position" ;
+	rdfs:comment "MIDI song position pointer message." ;
 	midi:status "F2"^^xsd:hexBinary ;
 	midi:chunk [
 		midi:byteNumber 0 ,
@@ -209,53 +179,62 @@ midi:SongPosition
 midi:SongSelect
 	a rdfs:Class ;
 	rdfs:subClassOf midi:SystemCommon ;
-	rdfs:label "Song Select Message" ;
+	rdfs:label "Song Select" ;
+	rdfs:comment "MIDI song select message." ;
 	midi:status "F3"^^xsd:hexBinary .
 
 midi:Start
 	a rdfs:Class ;
 	rdfs:subClassOf midi:SystemRealtime ;
-	rdfs:label "Start Message" ;
+	rdfs:label "Start" ;
+	rdfs:comment "MIDI start message." ;
 	midi:status "FA"^^xsd:hexBinary .
 
 midi:Stop
 	a rdfs:Class ;
 	rdfs:subClassOf midi:SystemRealtime ;
-	rdfs:label "Stop Message" ;
+	rdfs:label "Stop" ;
+	rdfs:comment "MIDI stop message." ;
 	midi:status "FC"^^xsd:hexBinary .
 
 midi:SystemCommon
 	a rdfs:Class ;
 	rdfs:subClassOf midi:SystemMessage ;
-	rdfs:label "System Common Message" .
+	rdfs:label "System Common" ;
+	rdfs:comment "MIDI system common message." .
 
 midi:SystemExclusive
 	a rdfs:Class ;
 	rdfs:subClassOf midi:SystemMessage ;
-	rdfs:label "System Exclusive Message" ;
+	rdfs:label "System Exclusive" ;
+	rdfs:comment "MIDI system exclusive message." ;
 	midi:status "F0"^^xsd:hexBinary .
 
 midi:SystemMessage
 	a rdfs:Class ;
 	rdfs:subClassOf midi:MidiEvent ;
 	rdfs:label "System Message" ;
+	rdfs:comment "MIDI system message." ;
 	midi:statusMask "F0"^^xsd:hexBinary .
 
 midi:SystemRealtime
 	a rdfs:Class ;
 	rdfs:subClassOf midi:SystemMessage ;
-	rdfs:label "System Realtime Message" .
+	rdfs:label "System Realtime" ;
+	rdfs:comment "MIDI system realtime message." .
 
 midi:TuneRequest
 	a rdfs:Class ;
 	rdfs:subClassOf midi:SystemCommon ;
-	rdfs:label "Tune Request Message" ;
+	rdfs:label "Tune Request" ;
+	rdfs:comment "MIDI tune request message." ;
 	midi:status "F6"^^xsd:hexBinary .
 
 midi:VoiceMessage
 	a rdfs:Class ;
 	rdfs:subClassOf midi:MidiEvent ;
 	rdfs:label "Voice Message" ;
+	rdfs:comment "MIDI voice message." ;
 	midi:statusMask "F0"^^xsd:hexBinary .
 
 midi:benderValue
@@ -264,26 +243,14 @@ midi:benderValue
 		owl:FunctionalProperty ;
 	rdfs:label "bender value" ;
 	rdfs:range xsd:short ;
-	rdfs:comment "The value of a pitch bender (-8192 to 8192)." .
+	rdfs:comment "MIDI pitch bender message (-8192 to 8192)." .
 
 midi:binding
 	a rdf:Property ,
 		owl:ObjectProperty ;
 	rdfs:range midi:MidiEvent ;
 	rdfs:label "binding" ;
-	lv2:documentation """
-<p>The MIDI event to bind a parameter to.  This describes which MIDI events
-should be used to control a port, parameter, or other object.  The binding
-should be a midi:MidiEvent but the property that represents the control value may
-be omitted.  For example, to bind to the value of controller 17:</p>
-
-<pre class="turtle-code">
-port midi:binding [
-    a midi:Controller ;
-    midi:controllerNumber 17
-] .
-</pre>
-""" .
+	rdfs:comment "The MIDI event to bind a parameter to." .
 
 midi:byteNumber
 	a rdf:Property ,
@@ -302,7 +269,8 @@ midi:channel
 	rdfs:comment "The channel number of a MIDI message." .
 
 midi:chunk
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:ObjectProperty ;
 	rdfs:range midi:Chunk ;
 	rdfs:label "MIDI chunk" ;
 	rdfs:comment "A chunk of a MIDI message." .
@@ -386,7 +354,7 @@ midi:statusMask
 		owl:FunctionalProperty ;
 	rdfs:label "status mask" ;
 	rdfs:range midi:HexByte ;
-	rdfs:comment """The status byte for a message of this type on channel 1, i.e. a status byte with the lower nibble set to zero.""" .
+	rdfs:comment "The status byte for a message of this type on channel 1." .
 
 midi:velocity
 	a rdf:Property ,
@@ -395,3 +363,4 @@ midi:velocity
 	rdfs:label "velocity" ;
 	rdfs:range midi:HexByte ;
 	rdfs:comment "The velocity of a note message (0 to 127)." .
+
diff --git a/sys/lv2/morph/NEWS b/sys/lv2/morph/NEWS
deleted file mode 100644
index 99a8712f..00000000
--- a/sys/lv2/morph/NEWS
+++ /dev/null
@@ -1,6 +0,0 @@
-morph (1.0) stable;
-
-  * Initial release.
-
- -- None <None>  Sun, 14 Oct 2012 00:00:00 +0000
-
diff --git a/sys/lv2/morph/lv2-morph.doap.ttl b/sys/lv2/morph/lv2-morph.doap.ttl
deleted file mode 100644
index 533cf10f..00000000
--- a/sys/lv2/morph/lv2-morph.doap.ttl
+++ /dev/null
@@ -1,22 +0,0 @@
-@prefix dcs: <http://ontologi.es/doap-changeset#> .
-@prefix doap: <http://usefulinc.com/ns/doap#> .
-@prefix foaf: <http://xmlns.com/foaf/0.1/> .
-@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-
-<http://lv2plug.in/ns/ext/morph>
-	a doap:Project ;
-	doap:name "LV2 Morph" ;
-	doap:shortdesc "Ports that can dynamically change type." ;
-	doap:created "2012-05-22" ;
-	doap:developer <http://drobilla.net/drobilla#me> ;
-	doap:release [
-		doap:revision "1.0" ;
-		doap:created "2012-10-14" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Initial release."
-			]
-		]
-	] .
diff --git a/sys/lv2/morph/manifest.ttl b/sys/lv2/morph/manifest.ttl
index 40b0f2b1..7c85cfd6 100644
--- a/sys/lv2/morph/manifest.ttl
+++ b/sys/lv2/morph/manifest.ttl
@@ -1,4 +1,4 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/morph>
diff --git a/sys/lv2/morph/morph.h b/sys/lv2/morph/morph.h
index 884af741..101df8e4 100644
--- a/sys/lv2/morph/morph.h
+++ b/sys/lv2/morph/morph.h
@@ -16,6 +16,7 @@
 
 /**
    @defgroup morph Morph
+   @ingroup lv2
 
    Ports that can dynamically change type, see <http://lv2plug.in/ns/ext/morph>
    for details.
diff --git a/sys/lv2/morph/morph.meta.ttl b/sys/lv2/morph/morph.meta.ttl
new file mode 100644
index 00000000..c2477831
--- /dev/null
+++ b/sys/lv2/morph/morph.meta.ttl
@@ -0,0 +1,90 @@
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix morph: <http://lv2plug.in/ns/ext/morph#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/morph>
+	a doap:Project ;
+	doap:name "LV2 Morph" ;
+	doap:shortdesc "Ports that can dynamically change type." ;
+	doap:created "2012-05-22" ;
+	doap:developer <http://drobilla.net/drobilla#me> ;
+	doap:release [
+		doap:revision "1.0" ;
+		doap:created "2012-10-14" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Initial release."
+			]
+		]
+	] ;
+	lv2:documentation """
+
+This extension defines two port types: morph:MorphPort, which has a
+host-configurable type, and morph:AutoMorphPort, which may automatically change
+type when a MorphPort's type is changed.  These ports always have a default
+type and work normally work in hosts that are unaware of this extension.  Thus,
+this extension provides a backwards compatibility mechanism which allows
+plugins to use new port types but gracefully fall back to a default type in
+hosts that do not support them.
+
+This extension only defines port types and properties for describing morph
+ports.  The actual run-time switching is done via the opts:interface API.
+
+"""^^lv2:Markdown .
+
+morph:MorphPort
+	lv2:documentation """
+
+Ports of this type MUST have another type which defines the default buffer
+format (for example lv2:ControlPort) but can be dynamically changed to a
+different type in hosts that support opts:interface.
+
+The host may change the type of a MorphPort by setting its morph:currentType
+with LV2_Options_Interface::set().  If the plugin has any morph:AutoMorphPort
+ports, the host MUST check their types after changing any port type since they
+may have changed.
+
+"""^^lv2:Markdown .
+
+morph:AutoMorphPort
+	lv2:documentation """
+
+Ports of this type MUST have another type which defines the default buffer
+format (for example, lv2:ControlPort) but may dynamically change types based on
+the configured types of any morph:MorphPort ports on the same plugin instance.
+
+The type of a port may only change in response to a host call to
+LV2_Options_Interface::set().  Whenever any port type on the instance changes,
+the host MUST check the type of all morph:AutoMorphPort ports with
+LV2_Options_Interface::get() before calling run() again, since they may have
+changed.  If the type of any port is zero, it means the current configuration
+is invalid and the plugin may not be run (unless that port is
+lv2:connectionOptional and connected to NULL).
+
+This is mainly useful for outputs whose type depends on the type of
+corresponding inputs.
+
+"""^^lv2:Markdown .
+
+morph:supportsType
+	lv2:documentation """
+
+Indicates that a port supports being switched to a certain type.  A MorphPort
+MUST list each type it supports being switched to in the plugin data using this
+property.
+
+"""^^lv2:Markdown .
+
+morph:currentType
+	lv2:documentation """
+
+The currently active type of the port.  This is for dynamic use as an option
+and SHOULD NOT be listed in the static plugin data.
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/morph/morph.ttl b/sys/lv2/morph/morph.ttl
index 2a2e9fc4..303293da 100644
--- a/sys/lv2/morph/morph.ttl
+++ b/sys/lv2/morph/morph.ttl
@@ -1,77 +1,40 @@
-@prefix doap:  <http://usefulinc.com/ns/doap#> .
-@prefix foaf:  <http://xmlns.com/foaf/0.1/> .
-@prefix lv2:   <http://lv2plug.in/ns/lv2core#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix morph: <http://lv2plug.in/ns/ext/morph#> .
 @prefix opts: <http://lv2plug.in/ns/ext/options#> .
-@prefix owl:   <http://www.w3.org/2002/07/owl#> .
-@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
-@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
-@prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
 
 <http://lv2plug.in/ns/ext/morph>
 	a owl:Ontology ;
+	rdfs:label "LV2 Morph" ;
+	rdfs:comment "Ports that can dynamically change type." ;
 	rdfs:seeAlso <morph.h> ,
-		<lv2-morph.doap.ttl> ;
-	lv2:documentation """
-<p>This extension defines two port types: morph:MorphPort, which has a
-host-configurable type, and morph:AutoMorphPort, which may automatically change
-type when a MorphPort's type is changed.  These ports always have a default
-type and work normally work in hosts that are unaware of this extension.  Thus,
-this extension provides a backwards compatibility mechanism which allows
-plugins to use new port types but gracefully fall back to a default type in
-hosts that do not support them.</p>
-
-<p>This extension only defines port types and properties for describing morph
-ports.  The actual run-time switching is done via the opts:interface API.</p>
-""" .
+		<morph.meta.ttl> .
 
 morph:MorphPort
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:Port ;
 	rdfs:label "Morph Port" ;
-	lv2:documentation """
-<p>Ports of this type MUST have another type which defines the default buffer
-format (e.g. lv2:ControlPort) but can be dynamically changed to a different
-type in hosts that support opts:interface.</p>
-
-<p>The host may change the type of a MorphPort by setting its morph:currentType
-with LV2_Options_Interface::set().  If the plugin has any morph:AutoMorphPort
-ports, the host MUST check their types after changing any port type since they
-may have changed.</p> """ .
+	rdfs:comment "A port which can be switched to another type." .
 
 morph:AutoMorphPort
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf lv2:Port ;
 	rdfs:label "Auto Morph Port" ;
-	lv2:documentation """
-<p>Ports of this type MUST have another type which defines the default buffer
-format (e.g. lv2:ControlPort) but may dynamically change types based on the
-configured types of any morph:MorphPort ports on the same plugin instance.</p>
-
-<p>The type of a port may only change in response to a host call to
-LV2_Options_Interface::set().  Whenever any port type on the instance changes,
-the host MUST check the type of all morph:AutoMorphPort ports with
-LV2_Options_Interface::get() before calling run() again, since they may have
-changed.  If the type of any port is zero, it means the current configuration
-is invalid and the plugin may not be run (unless that port is
-lv2:connectionOptional and connected to NULL).</p>
-
-<p>This is mainly useful for outputs whose type depends on the type of
-corresponding inputs.</p>
-""" .
+	rdfs:comment "A port that can change its type based on that of another." .
 
 morph:supportsType
 	a rdf:Property ,
 		owl:ObjectProperty ;
 	rdfs:domain morph:MorphPort ;
 	rdfs:label "supports type" ;
-	lv2:documentation """
-<p>Indicates that a port supports being switched to a certain type.  A
-MorphPort MUST list each type it supports being switched to in the plugin data
-using this property.</p>
-""" .
+	rdfs:comment "A type that a port supports being switched to." .
 
 morph:currentType
 	a rdf:Property ,
@@ -79,7 +42,5 @@ morph:currentType
 		owl:ObjectProperty ;
 	rdfs:domain morph:MorphPort ;
 	rdfs:label "current type" ;
-	lv2:documentation """
-<p>The currently active type of the port.  This is for dynamic use as an option
-and SHOULD NOT be listed in the static plugin data.</p>
-""" .
+	rdfs:comment "The currently active type of the port." .
+
diff --git a/sys/lv2/options/NEWS b/sys/lv2/options/NEWS
deleted file mode 100644
index 4da8879f..00000000
--- a/sys/lv2/options/NEWS
+++ /dev/null
@@ -1,18 +0,0 @@
-options (1.4) stable;
-
-  * Relax range of opts:requiredOption and opts:supportedOption
-
- -- None <None>  Sun, 03 Feb 2019 00:00:00 +0000
-
-options (1.2) stable;
-
-  * Set the range of opts:requiredOption and opts:supportedOption to opts:Option.
-
- -- None <None>  Thu, 10 Jan 2013 00:00:00 +0000
-
-options (1.0) stable;
-
-  * Initial release.
-
- -- None <None>  Sun, 14 Oct 2012 00:00:00 +0000
-
diff --git a/sys/lv2/options/lv2-options.doap.ttl b/sys/lv2/options/lv2-options.doap.ttl
deleted file mode 100644
index 22efbfce..00000000
--- a/sys/lv2/options/lv2-options.doap.ttl
+++ /dev/null
@@ -1,42 +0,0 @@
-@prefix dcs: <http://ontologi.es/doap-changeset#> .
-@prefix doap: <http://usefulinc.com/ns/doap#> .
-@prefix foaf: <http://xmlns.com/foaf/0.1/> .
-@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-
-<http://lv2plug.in/ns/ext/options>
-	a doap:Project ;
-	doap:name "LV2 Options" ;
-	doap:shortdesc "Instantiation time options." ;
-	doap:created "2012-08-20" ;
-	doap:developer <http://drobilla.net/drobilla#me> ;
-	doap:release [
-		doap:revision "1.4" ;
-		doap:created "2019-02-03" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.16.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Relax range of opts:requiredOption and opts:supportedOption"
-			]
-		]
-	] , [
-		doap:revision "1.2" ;
-		doap:created "2013-01-10" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.4.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Set the range of opts:requiredOption and opts:supportedOption to opts:Option."
-			]
-		]
-	] , [
-		doap:revision "1.0" ;
-		doap:created "2012-10-14" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Initial release."
-			]
-		]
-	] .
diff --git a/sys/lv2/options/manifest.ttl b/sys/lv2/options/manifest.ttl
index bab8984c..18db4483 100644
--- a/sys/lv2/options/manifest.ttl
+++ b/sys/lv2/options/manifest.ttl
@@ -1,4 +1,4 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/options>
@@ -6,3 +6,4 @@
 	lv2:minorVersion 1 ;
 	lv2:microVersion 4 ;
 	rdfs:seeAlso <options.ttl> .
+
diff --git a/sys/lv2/options/options.h b/sys/lv2/options/options.h
index 7878c583..2ed9f8a4 100644
--- a/sys/lv2/options/options.h
+++ b/sys/lv2/options/options.h
@@ -16,6 +16,7 @@
 
 /**
    @defgroup options Options
+   @ingroup lv2
 
    Instantiation time options, see <http://lv2plug.in/ns/ext/options> for
    details.
@@ -85,7 +86,7 @@ typedef enum {
    with data pointed to an array of options terminated by a zeroed option, or
    accessed/manipulated using LV2_Options_Interface.
 */
-typedef struct _LV2_Options_Option {
+typedef struct {
 	LV2_Options_Context context;  /**< Context (type of subject). */
 	uint32_t            subject;  /**< Subject. */
 	LV2_URID            key;      /**< Key (property). */
@@ -106,7 +107,7 @@ typedef enum {
 /**
    Interface for dynamically setting options (LV2_OPTIONS__interface).
 */
-typedef struct _LV2_Options_Interface {
+typedef struct {
 	/**
 	   Get the given options.
 
diff --git a/sys/lv2/options/options.meta.ttl b/sys/lv2/options/options.meta.ttl
new file mode 100644
index 00000000..d545f954
--- /dev/null
+++ b/sys/lv2/options/options.meta.ttl
@@ -0,0 +1,129 @@
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix opts: <http://lv2plug.in/ns/ext/options#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/options>
+	a doap:Project ;
+	doap:name "LV2 Options" ;
+	doap:shortdesc "Runtime options for LV2 plugins and UIs." ;
+	doap:created "2012-08-20" ;
+	doap:developer <http://drobilla.net/drobilla#me> ;
+	doap:release [
+		doap:revision "1.4" ;
+		doap:created "2019-02-03" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.16.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Relax range of opts:requiredOption and opts:supportedOption"
+			]
+		]
+	] , [
+		doap:revision "1.2" ;
+		doap:created "2013-01-10" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.4.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Set the range of opts:requiredOption and opts:supportedOption to opts:Option."
+			]
+		]
+	] , [
+		doap:revision "1.0" ;
+		doap:created "2012-10-14" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Initial release."
+			]
+		]
+	] ;
+	lv2:documentation """
+
+This extension defines a facility for <q>options</q>, which are values the host
+passes to a plugin or UI at run time.
+
+There are two facilities for passing options to an instance: opts:options
+allows passing options at instantiation time, and the opts:interface interface
+allows options to be dynamically set and retrieved after instantiation.
+
+Note that this extension is only for allowing hosts to configure plugins, and
+is not a <q>live</q> control mechanism.  For real-time control, use event-based
+control via an atom:AtomPort with an atom:Sequence buffer.
+
+Instances may indicate they require an option with the opts:requiredOption
+property, or that they optionally support an option with the
+opts:supportedOption property.
+
+"""^^lv2:Markdown .
+
+opts:Option
+	lv2:documentation """
+
+It is not required for a property to explicitly be an Option in order to be
+used as such.  However, properties which are primarily intended for use as
+options, or are at least particularly useful as options, should be explicitly
+given this type for documentation purposes, and to assist hosts in discovering
+option definitions.
+
+"""^^lv2:Markdown .
+
+opts:interface
+	lv2:documentation """
+
+An interface (LV2_Options_Interface) for dynamically setting and getting
+options.  Note that this is intended for use by the host for configuring
+plugins only, and is not a <q>live</q> plugin control mechanism.
+
+The plugin data file should advertise this interface like so:
+
+    :::turtle
+    @prefix opts: &lt;http://lv2plug.in/ns/ext/options#&gt; .
+
+    &lt;plugin&gt;
+        a lv2:Plugin ;
+        lv2:extensionData opts:interface .
+
+"""^^lv2:Markdown .
+
+opts:options
+	lv2:documentation """
+
+To implement this feature, hosts MUST pass an LV2_Feature to the appropriate
+instantiate method with this URI and data pointed to an array of
+LV2_Options_Option terminated by an element with both key and value set to
+zero.  The instance should cast this data pointer to `const
+LV2_Options_Option*` and scan the array for any options of interest.  The
+instance MUST NOT modify the options array in any way.
+
+Note that requiring this feature may reduce the number of compatible hosts.
+Unless some options are strictly required by the instance, this feature SHOULD
+be listed as an lv2:optionalFeature.
+
+"""^^lv2:Markdown .
+
+opts:requiredOption
+	lv2:documentation """
+
+The host MUST pass a value for the specified option via opts:options during
+instantiation.
+
+Note that use of this property may reduce the number of compatible hosts.
+Wherever possible, it is better to list options with opts:supportedOption and
+fall back to a reasonable default value if it is not provided.
+
+"""^^lv2:Markdown .
+
+opts:supportedOption
+	lv2:documentation """
+
+The host SHOULD provide a value for the specified option if one is known, or
+provide the user an opportunity to specify one if possible.
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/options/options.ttl b/sys/lv2/options/options.ttl
index 5c5860ac..f8388da8 100644
--- a/sys/lv2/options/options.ttl
+++ b/sys/lv2/options/options.ttl
@@ -1,103 +1,44 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix opts: <http://lv2plug.in/ns/ext/options#> .
-@prefix owl:  <http://www.w3.org/2002/07/owl#> .
-@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
 
 <http://lv2plug.in/ns/ext/options>
 	a owl:Ontology ;
+	rdfs:label "LV2 Options" ;
+	rdfs:comment "Runtime options for LV2 plugins and UIs." ;
 	rdfs:seeAlso <options.h> ,
-		<lv2-options.doap.ttl> ;
-	lv2:documentation """
-<p>This extension defines a facility for <q>options</q>, which are dynamic
-properties that may be changed at run time.</p>
-
-<p>There are two facilities for passing options to an instance: opts:options
-allows passing options at instantiation time, and the opts:interface interface
-allows options to be dynamically set and retrieved after instantiation.</p>
-
-<p>Note that this extension is only for allowing hosts to configure plugins,
-and is not a <q>live</q> control mechanism.  For real-time control, use
-event-based control via an atom:AtomPort with an atom:Sequence buffer.</p>
-
-<p>Instances may indicate they <q>require</q> an option with the
-opts:requiredOption property, or that they optionally <q>support</q> an option
-with the opts:supportedOption property.</p>
-""" .
+		<options.meta.ttl> .
 
 opts:Option
 	a rdfs:Class ;
 	rdfs:label "Option" ;
 	rdfs:subClassOf rdf:Property ;
-	lv2:documentation """
-<p>A property intended to be used as a static option for an instance.</p>
-
-<p>It is not required for a property to explicitly be an Option in order to be
-used as such.  However, properties which are primarily intended for use as
-options, or are at least particularly useful as options, should be explicitly
-given this type for documentation purposes, and to assist hosts in discovering
-option definitions.</p>
-""" .
+	rdfs:comment "A value for a static option passed to an instance." .
 
 opts:interface
 	a lv2:ExtensionData ;
-	lv2:documentation """
-<p>An interface (LV2_Options_Interface) for dynamically setting and getting
-options.  Note this is intended for use by the host for configuring plugins
-only, and and is <em>not</em> a <q>live</q> plugin control mechanism.</p>
-
-<p>The plugin data file should describe this like so:</p>
-<pre class="turtle-code">
-@prefix opts: &lt;http://lv2plug.in/ns/ext/options#&gt; .
-
-&lt;plugin&gt;
-    a lv2:Plugin ;
-    lv2:extensionData opts:interface .
-</pre>
-""" .
+	rdfs:label "interface" ;
+	rdfs:comment "An interface for dynamically setting and getting options." .
 
 opts:options
 	a lv2:Feature ;
 	rdfs:label "options" ;
-	lv2:documentation """
-<p>The feature used to provide options to an instance.</p>
-
-<p>To implement this feature, hosts MUST pass an LV2_Feature to the appropriate
-instantiate method with this URI and data pointed to an array of
-LV2_Options_Option terminated by an element with both key and value set to
-zero.  The instance should cast this data pointer to <code>const
-LV2_Options_Option*</code> and scan the array for any options of interest.  The
-instance MUST NOT modify the options array in any way.</p>
-
-<p>Note that requiring this feature may reduce the number of compatible hosts.
-Unless some options are strictly required by the instance, this feature SHOULD
-be listed as a lv2:optionalFeature.</p>
-""" .
+	rdfs:comment "The feature used to provide options to an instance." .
 
 opts:requiredOption
 	a rdf:Property ,
 		owl:ObjectProperty ;
 	rdfs:range rdf:Property ;
 	rdfs:label "required option" ;
-	lv2:documentation """
-<p>An option required by the instance to function at all.  The host MUST pass a
-value for the specified option via opts:options in order to create an
-instance.</p>
-
-<p>Note that use of this property may reduce the number of compatible hosts.
-Wherever possible, it is better to list options with opts:supportedOption and
-fall back to a reasonable default value if it is not provided.</p>
-""" .
+	rdfs:comment "An option required by the instance to function at all." .
 
 opts:supportedOption
 	a rdf:Property ,
 		owl:ObjectProperty ;
 	rdfs:range rdf:Property ;
 	rdfs:label "supported option" ;
-	lv2:documentation """
-<p>An option supported or <q>understood</q> by the instance.  The host SHOULD
-provide a value for the specified option if one is known, or provide the user
-an opportunity to specify one if one is Indicates that the instance host MUST
-pass a value for the specified option in order to instantiate the instance.</p>
-""" .
+	rdfs:comment "An option supported or by the instance." .
+
diff --git a/sys/lv2/parameters/NEWS b/sys/lv2/parameters/NEWS
deleted file mode 100644
index 7b6e7ebc..00000000
--- a/sys/lv2/parameters/NEWS
+++ /dev/null
@@ -1,20 +0,0 @@
-parameters (1.4) stable;
-
-  * Add range to parameters so hosts know how to control them.
-
- -- None <None>  Tue, 07 Apr 2015 00:00:00 +0000
-
-parameters (1.2) stable;
-
-  * Use consistent label style.
-  * Add parameters.h of URI defines for convenience.
-  * Add param:sampleRate.
-
- -- None <None>  Sun, 14 Oct 2012 00:00:00 +0000
-
-parameters (1.0) stable;
-
-  * Initial release.
-
- -- None <None>  Tue, 17 Apr 2012 00:00:00 +0000
-
diff --git a/sys/lv2/parameters/manifest.ttl b/sys/lv2/parameters/manifest.ttl
index d2ba8faa..57f5d2e1 100644
--- a/sys/lv2/parameters/manifest.ttl
+++ b/sys/lv2/parameters/manifest.ttl
@@ -1,4 +1,4 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/parameters>
@@ -6,3 +6,4 @@
 	lv2:minorVersion 1 ;
 	lv2:microVersion 4 ;
 	rdfs:seeAlso <parameters.ttl> .
+
diff --git a/sys/lv2/parameters/parameters.h b/sys/lv2/parameters/parameters.h
index f81e78ba..01c6ddea 100644
--- a/sys/lv2/parameters/parameters.h
+++ b/sys/lv2/parameters/parameters.h
@@ -16,6 +16,7 @@
 
 /**
    @defgroup parameters Parameters
+   @ingroup lv2
 
    Common parameters for audio processing, see
    <http://lv2plug.in/ns/ext/parameters>.
diff --git a/sys/lv2/parameters/lv2-parameters.doap.ttl b/sys/lv2/parameters/parameters.meta.ttl
similarity index 57%
rename from sys/lv2/parameters/lv2-parameters.doap.ttl
rename to sys/lv2/parameters/parameters.meta.ttl
index 3ff707c6..9d7c623f 100644
--- a/sys/lv2/parameters/lv2-parameters.doap.ttl
+++ b/sys/lv2/parameters/parameters.meta.ttl
@@ -1,6 +1,8 @@
 @prefix dcs: <http://ontologi.es/doap-changeset#> .
 @prefix doap: <http://usefulinc.com/ns/doap#> .
 @prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix param: <http://lv2plug.in/ns/ext/parameters#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/parameters>
@@ -44,4 +46,30 @@
 	doap:created "2009-00-00" ;
 	doap:shortdesc "Common parameters for audio processing." ;
 	doap:maintainer <http://drobilla.net/drobilla#me> ;
-	doap:developer <http://lv2plug.in/ns/meta#larsl> .
+	doap:developer <http://lv2plug.in/ns/meta#larsl> ;
+	lv2:documentation """
+
+This is a vocabulary for parameters that are common in audio processing
+software.  A <q>parameter</q> is purely a metadata concept, unrelated to any
+particular code mechanism.  Parameters are used to assign meaning to controls
+(for example, using lv2:designation for ports) so they can be used more
+intelligently or presented to the user more efficiently.
+
+"""^^lv2:Markdown .
+
+param:wetDryRatio
+	a lv2:Parameter ;
+	rdfs:label "wet/dry ratio" ;
+	lv2:documentation """
+
+The ratio between processed and bypass components in output signal.  The dry
+and wet percentages can be calculated from the following equations:
+
+    :::c
+    dry = (wetDryRatio.maximum - wetDryRatio.value) / wetDryRatio.maximum
+    wet = wetDryRatio.value / wetDryRatio.maximum
+
+Typically, maximum value of 1 or 100 and minimum value of 0 should be used.
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/parameters/parameters.ttl b/sys/lv2/parameters/parameters.ttl
index f8ad2ab9..5c3dadf9 100644
--- a/sys/lv2/parameters/parameters.ttl
+++ b/sys/lv2/parameters/parameters.ttl
@@ -1,64 +1,65 @@
-@prefix lv2:   <http://lv2plug.in/ns/lv2core#> .
+@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
 @prefix param: <http://lv2plug.in/ns/ext/parameters#> .
-@prefix atom:  <http://lv2plug.in/ns/ext/atom#> .
-@prefix pg:    <http://lv2plug.in/ns/ext/port-groups#> .
-@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
-@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix pg: <http://lv2plug.in/ns/ext/port-groups#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 @prefix units: <http://lv2plug.in/ns/extensions/units#> .
 
 <http://lv2plug.in/ns/ext/parameters>
-	a lv2:Specification ;
-	rdfs:seeAlso <lv2-parameters.doap.ttl> ;
-	lv2:documentation """
-<p>This vocabulary describes parameters common in audio processing software.  A
-<q>parameter</q> is purely a metadata concept, unrelated to any particular code
-mechanism.  Parameters are used to assign meaning to controls (e.g. using
-lv2:designation for ports) so they can be used more intelligently or presented
-to the user more efficiently.</p> """ .
+	a owl:Ontology ;
+	rdfs:label "LV2 Parameters" ;
+	rdfs:comment "Common parameters for audio processing." ;
+	rdfs:seeAlso <parameters.meta.ttl> .
 
 param:ControlGroup
 	a rdfs:Class ;
 	rdfs:subClassOf pg:Group ;
+	rdfs:label "Control Group" ;
 	rdfs:comment "A group representing a set of associated controls." .
 
 param:amplitude
 	a lv2:Parameter ;
 	rdfs:range atom:Float ;
-	rdfs:label "amplitude" .
+	rdfs:label "amplitude" ;
+	rdfs:comment "An amplitude as a factor, where 0 is silent and 1 is unity." .
 
 param:attack
 	a lv2:Parameter ;
 	rdfs:range atom:Float ;
 	rdfs:label "attack" ;
-	rdfs:comment "The duration of an envelope's attack stage." .
+	rdfs:comment "The duration of an envelope attack stage." .
 
 param:cutoffFrequency
 	a lv2:Parameter ;
 	rdfs:range atom:Float ;
-	rdfs:label "cutoff frequency" .
+	rdfs:label "cutoff frequency" ;
+	rdfs:comment "The cutoff frequency, typically in Hz, for a filter." .
 
 param:decay
 	a lv2:Parameter ;
 	rdfs:range atom:Float ;
 	rdfs:label "decay" ;
-	rdfs:comment "The duration of an envelope's decay stage." .
+	rdfs:comment "The duration of an envelope decay stage." .
 
 param:delay
 	a lv2:Parameter ;
 	rdfs:range atom:Float ;
 	rdfs:label "delay" ;
-	rdfs:comment "The duration of an envelope's delay stage." .
+	rdfs:comment "The duration of an envelope delay stage." .
 
 param:frequency
 	a lv2:Parameter ;
 	rdfs:range atom:Float ;
-	rdfs:label "frequency" .
+	rdfs:label "frequency" ;
+	rdfs:comment "A frequency, typically in Hz." .
 
 param:hold
 	a lv2:Parameter ;
 	rdfs:range atom:Float ;
 	rdfs:label "hold" ;
-	rdfs:comment "The duration of an envelope's hold stage." .
+	rdfs:comment "The duration of an envelope hold stage." .
 
 param:pulseWidth
 	a lv2:Parameter ;
@@ -76,7 +77,7 @@ param:release
 	a lv2:Parameter ;
 	rdfs:range atom:Float ;
 	rdfs:label "release" ;
-	rdfs:comment "The duration of an envelope's release stage." .
+	rdfs:comment "The duration of an envelope release stage." .
 
 param:resonance
 	a lv2:Parameter ;
@@ -88,7 +89,7 @@ param:sustain
 	a lv2:Parameter ;
 	rdfs:label "sustain" ;
 	rdfs:range atom:Float ;
-	rdfs:comment "The level (not duration) of an envelope's sustain stage." .
+	rdfs:comment "The level of an envelope sustain stage as a factor." .
 
 param:threshold
 	a lv2:Parameter ;
@@ -99,7 +100,8 @@ param:threshold
 param:waveform
 	a lv2:Parameter ;
 	rdfs:range atom:Float ;
-	rdfs:label "waveform" .
+	rdfs:label "waveform" ;
+	rdfs:comment """The waveform "fader" for oscillators or modulators that have several.""" .
 
 param:gain
 	a lv2:Parameter ;
@@ -114,18 +116,7 @@ param:gain
 param:wetDryRatio
 	a lv2:Parameter ;
 	rdfs:label "wet/dry ratio" ;
-	lv2:documentation """
-<p>The ratio between processed and bypass components in output signal.  The dry
-and wet percentages can be calculated from the following equations:</p>
-
-<pre class="c-code">
-    dry = (wetDryRatio.maximum - wetDryRatio.value) / wetDryRatio.maximum
-    wet = wetDryRatio.value / wetDryRatio.maximum
-</pre>
-
-<p>Typically, maximum value of 1 or 100 and minimum value of 0 should be
-used.</p>
-""" .
+	rdfs:comment "The ratio between processed and bypassed levels in the output." .
 
 param:wetLevel
 	a lv2:Parameter ;
@@ -140,7 +131,7 @@ param:dryLevel
 param:bypass
 	a lv2:Parameter ;
 	rdfs:label "bypass" ;
-	rdfs:comment "A boolean parameter that disabled processing if true." .
+	rdfs:comment "A boolean parameter that disables processing if true." .
 
 param:sampleRate
 	a lv2:Parameter ;
@@ -150,7 +141,8 @@ param:sampleRate
 param:EnvelopeControls
 	a rdfs:Class ;
 	rdfs:subClassOf param:ControlGroup ;
-	rdfs:label "DAHDSR Envelope Controls" ;
+	rdfs:label "Envelope Controls" ;
+	rdfs:comment "Typical controls for a DAHDSR envelope." ;
 	pg:element [
 		lv2:index 0 ;
 		lv2:designation param:delay
@@ -175,6 +167,7 @@ param:OscillatorControls
 	a rdfs:Class ;
 	rdfs:subClassOf param:ControlGroup ;
 	rdfs:label "Oscillator Controls" ;
+	rdfs:comment "Typical controls for an oscillator." ;
 	pg:element [
 		lv2:designation param:frequency
 	] , [
@@ -189,6 +182,7 @@ param:FilterControls
 	a rdfs:Class ;
 	rdfs:subClassOf param:ControlGroup ;
 	rdfs:label "Filter Controls" ;
+	rdfs:comment "Typical controls for a filter." ;
 	pg:element [
 		lv2:designation param:cutoffFrequency
 	] , [
@@ -199,8 +193,10 @@ param:CompressorControls
 	a rdfs:Class ;
 	rdfs:subClassOf param:ControlGroup ;
 	rdfs:label "Compressor Controls" ;
+	rdfs:comment "Typical controls for a compressor." ;
 	pg:element [
 		lv2:designation param:threshold
 	] , [
 		lv2:designation param:ratio
 	] .
+
diff --git a/sys/lv2/patch/NEWS b/sys/lv2/patch/NEWS
deleted file mode 100644
index cdf4fa6a..00000000
--- a/sys/lv2/patch/NEWS
+++ /dev/null
@@ -1,34 +0,0 @@
-patch (2.6) stable;
-
-  * Add patch:context property.
-  * Add patch:accept property.
-
- -- None <None>  Sun, 03 Feb 2019 00:00:00 +0000
-
-patch (2.4) stable;
-
-  * Add patch:Copy method.
-  * Define patch:Get with no subject to implicitly apply to reciever.  This can be
-    used by UIs to get an initial description of a plugin.
-
- -- None <None>  Tue, 07 Apr 2015 00:00:00 +0000
-
-patch (2.2) stable;
-
-  * Add patch:sequenceNumber for associating replies with requests.
-
- -- None <None>  Fri, 08 Aug 2014 00:00:00 +0000
-
-patch (2.0) stable;
-
-  * Add patch:readable and patch:writable for describing available properties.
-  * Make patch:Set a compact message for setting one property.
-
- -- None <None>  Thu, 10 Jan 2013 00:00:00 +0000
-
-patch (1.0) stable;
-
-  * Initial release.
-
- -- None <None>  Tue, 17 Apr 2012 00:00:00 +0000
-
diff --git a/sys/lv2/patch/lv2-patch.doap.ttl b/sys/lv2/patch/lv2-patch.doap.ttl
deleted file mode 100644
index 2a76d9ba..00000000
--- a/sys/lv2/patch/lv2-patch.doap.ttl
+++ /dev/null
@@ -1,69 +0,0 @@
-@prefix dcs: <http://ontologi.es/doap-changeset#> .
-@prefix doap: <http://usefulinc.com/ns/doap#> .
-@prefix foaf: <http://xmlns.com/foaf/0.1/> .
-@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-
-<http://lv2plug.in/ns/ext/patch>
-	a doap:Project ;
-	doap:created "2012-02-09" ;
-	doap:license <http://opensource.org/licenses/isc> ;
-	doap:developer <http://drobilla.net/drobilla#me> ;
-	doap:name "LV2 Patch" ;
-	doap:shortdesc "Messages for accessing and manipulating properties." ;
-	doap:release [
-		doap:revision "2.6" ;
-		doap:created "2019-02-03" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.16.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Add patch:accept property."
-			] , [
-				rdfs:label "Add patch:context property."
-			]
-		]
-	] , [
-		doap:revision "2.4" ;
-		doap:created "2015-04-07" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.12.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Define patch:Get with no subject to implicitly apply to reciever.  This can be used by UIs to get an initial description of a plugin."
-			] , [
-				rdfs:label "Add patch:Copy method."
-			]
-		]
-	] , [
-		doap:revision "2.2" ;
-		doap:created "2014-08-08" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.10.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Add patch:sequenceNumber for associating replies with requests."
-			]
-		]
-	] , [
-		doap:revision "2.0" ;
-		doap:created "2013-01-10" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.4.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Make patch:Set a compact message for setting one property."
-			] , [
-				rdfs:label "Add patch:readable and patch:writable for describing available properties."
-			]
-		]
-	] , [
-		doap:revision "1.0" ;
-		doap:created "2012-04-17" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Initial release."
-			]
-		]
-	] .
diff --git a/sys/lv2/patch/manifest.ttl b/sys/lv2/patch/manifest.ttl
index 598bf297..25150bdd 100644
--- a/sys/lv2/patch/manifest.ttl
+++ b/sys/lv2/patch/manifest.ttl
@@ -1,8 +1,9 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/patch>
 	a lv2:Specification ;
 	lv2:minorVersion 2 ;
-	lv2:microVersion 6 ;
+	lv2:microVersion 8 ;
 	rdfs:seeAlso <patch.ttl> .
+
diff --git a/sys/lv2/patch/patch.h b/sys/lv2/patch/patch.h
index fed6a872..a721c5eb 100644
--- a/sys/lv2/patch/patch.h
+++ b/sys/lv2/patch/patch.h
@@ -16,6 +16,7 @@
 
 /**
    @defgroup patch Patch
+   @ingroup lv2
 
    Messages for accessing and manipulating properties, see
    <http://lv2plug.in/ns/ext/patch> for details.
diff --git a/sys/lv2/patch/patch.meta.ttl b/sys/lv2/patch/patch.meta.ttl
new file mode 100644
index 00000000..549757a6
--- /dev/null
+++ b/sys/lv2/patch/patch.meta.ttl
@@ -0,0 +1,374 @@
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix patch: <http://lv2plug.in/ns/ext/patch#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/patch>
+	a doap:Project ;
+	doap:created "2012-02-09" ;
+	doap:license <http://opensource.org/licenses/isc> ;
+	doap:developer <http://drobilla.net/drobilla#me> ;
+	doap:name "LV2 Patch" ;
+	doap:shortdesc "A protocol for accessing and manipulating properties." ;
+	doap:release [
+		doap:revision "2.8" ;
+		doap:created "2020-04-26" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.18.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Fix incorrect type of patch:sequenceNumber."
+			]
+		]
+	] , [
+		doap:revision "2.6" ;
+		doap:created "2019-02-03" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.16.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add patch:accept property."
+			] , [
+				rdfs:label "Add patch:context property."
+			]
+		]
+	] , [
+		doap:revision "2.4" ;
+		doap:created "2015-04-07" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.12.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Define patch:Get with no subject to implicitly apply to reciever.  This can be used by UIs to get an initial description of a plugin."
+			] , [
+				rdfs:label "Add patch:Copy method."
+			]
+		]
+	] , [
+		doap:revision "2.2" ;
+		doap:created "2014-08-08" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.10.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add patch:sequenceNumber for associating replies with requests."
+			]
+		]
+	] , [
+		doap:revision "2.0" ;
+		doap:created "2013-01-10" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.4.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Make patch:Set a compact message for setting one property."
+			] , [
+				rdfs:label "Add patch:readable and patch:writable for describing available properties."
+			]
+		]
+	] , [
+		doap:revision "1.0" ;
+		doap:created "2012-04-17" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Initial release."
+			]
+		]
+	] ;
+	lv2:documentation """
+
+This is a vocabulary for messages that access and manipulate properties.
+It can be used as a dynamic control interface for plugins,
+or anything else with a property-based model.
+
+The key underlying concept here is to control things by manipulating arbitrary properties,
+rather than by calling application-specific methods.
+This allows implementations to understand what messages do
+(at least in a mechanical sense),
+which makes things like caching, proxying, or undo relatively straightforward to implement.
+Note, however, that this is only conceptual:
+there is no requirement to implement a general property store.
+Typically, a plugin will understand a fixed set of properties that represent its parameters or other internal state, and ignore everything else.
+
+This protocol is syntax-agnostic,
+and [homoiconic](https://en.wikipedia.org/wiki/Homoiconicity)
+in the sense that the messages use the same format as the data they manipulate.
+In particular, messages can be serialised as a binary [Object](atom.html#Object) for realtime plugin control,
+or as Turtle for saving to a file,
+sending over a network,
+printing for debugging purposes,
+and so on.
+
+This specification only defines a semantic protocol,
+there is no corresponding API.
+It can be used with the [Atom](atom.html) extension to control plugins which support message-based parameters as defined by the [Parameters](parameters.html) extension.
+
+For example, if a plugin defines a `eg:volume` parameter, it can be controlled by the host by sending a patch:Set message to the plugin instance:
+
+    :::turtle
+    [
+        a patch:Set ;
+        patch:property eg:volume ;
+        patch:value 11.0 ;
+    ]
+
+Similarly, the host could get the current value for this parameter by sending a patch:Get message:
+
+    :::turtle
+    [
+        a patch:Get ;
+        patch:property eg:volume ;
+    ]
+
+The plugin would then respond with the same patch:Set message as above.
+In this case, the plugin instance is implicitly the patch:subject,
+but a specific subject can also be given for deeper control.
+
+"""^^lv2:Markdown .
+
+patch:Copy
+	lv2:documentation """
+
+After this, the destination has the same description as the subject,
+and the subject is unchanged.
+
+It is an error if the subject does not exist,
+or if the destination already exists.
+
+Multiple subjects may be given if the destination is a container,
+but the semantics of this case are application-defined.
+
+"""^^lv2:Markdown .
+
+patch:Get
+	lv2:documentation """
+
+If a patch:property is given,
+then the receiver should respond with a patch:Set message that gives only that property.
+
+Otherwise, it should respond with a [concise bounded description](http://www.w3.org/Submission/CBD/) in a patch:Put message,
+that is, a description that recursively includes any blank node values.
+
+If a patch:subject is given, then the response should have the same subject.
+If no subject is given, then the receiver is implicitly the subject.
+
+If a patch:request node or a patch:sequenceNumber is given,
+then the response should be a patch:Response and have the same property.
+If neither is given, then the receiver can respond with a simple patch:Put message.
+For example:
+
+    :::turtle
+    []
+        a patch:Get ;
+        patch:subject eg:something .
+
+Could result in:
+
+    :::turtle
+    []
+        a patch:Put ;
+        patch:subject eg:something ;
+        patch:body [
+            eg:name "Something" ;
+            eg:ratio 1.6180339887 ;
+        ] .
+
+"""^^lv2:Markdown .
+
+patch:Insert
+	lv2:documentation """
+
+If the subject does not exist, it is created.  If the subject does already
+exist, it is added to.
+
+This request only adds properties, it never removes them.  The user must take
+care that multiple values are not set for properties which should only have
+one.
+
+"""^^lv2:Markdown .
+
+patch:Message
+	lv2:documentation """
+
+This is an abstract base class for all patch messages.  Concrete messages are
+either a patch:Request or a patch:Response.
+
+"""^^lv2:Markdown .
+
+patch:Move
+	lv2:documentation """
+
+After this, the destination has the description that the subject had, and the
+subject no longer exists.
+
+It is an error if the subject does not exist, or if the destination already
+exists.
+
+"""^^lv2:Markdown .
+
+patch:Patch
+	lv2:documentation """
+
+This method always has at least one subject, and exactly one patch:add and
+patch:remove property.  The value of patch:add and patch:remove are nodes which
+have the properties to add or remove from the subject(s), respectively.  The
+special value patch:wildcard may be used as the value of a remove property to
+remove all properties with the given predicate.  For example:
+
+    :::turtle
+    []
+        a patch:Patch ;
+        patch:subject &lt;something&gt; ;
+        patch:add [
+            eg:name "New name" ;
+            eg:age 42 ;
+        ] ;
+        patch:remove [
+            eg:name "Old name" ;
+            eg:age patch:wildcard ;  # Remove all old eg:age properties
+        ] .
+
+"""^^lv2:Markdown .
+
+patch:Put
+	lv2:documentation """
+
+If the subject does not already exist, it is created.  If the subject does
+already exist, the patch:body is considered an updated version of it, and the
+previous version is replaced.
+
+    :::turtle
+    []
+        a patch:Put ;
+        patch:subject &lt;something&gt; ;
+        patch:body [
+            eg:name "New name" ;
+            eg:age 42 ;
+        ] .
+
+"""^^lv2:Markdown .
+
+patch:Request
+	a rdfs:Class ;
+	rdfs:label "Request" ;
+	rdfs:subClassOf patch:Message ;
+	lv2:documentation """
+
+A request may have a patch:subject property, which specifies the resource that
+the request applies to.  The subject may be omitted in contexts where it is
+implicit, for example if the recipient is the subject.
+
+"""^^lv2:Markdown .
+
+patch:Set
+	lv2:documentation """
+
+This is equivalent to a patch:Patch which removes _all_ pre-existing values for
+the property before setting the new value.  For example:
+
+    :::turtle
+    []
+        a patch:Set ;
+        patch:subject &lt;something&gt; ;
+        patch:property eg:name ;
+        patch:value "New name" .
+
+Which is equivalent to:
+
+    :::turtle
+    []
+        a patch:Patch ;
+        patch:subject &lt;something&gt; ;
+        patch:add [
+            eg:name "New name" ;
+        ] ;
+        patch:remove [
+            eg:name patch:wildcard ;
+        ] .
+
+"""^^lv2:Markdown .
+
+patch:body
+	lv2:documentation """
+
+The details of this property's value depend on the type of message it is a part
+of.
+
+"""^^lv2:Markdown .
+
+patch:context
+	lv2:documentation """
+
+For example, a plugin may have a special context for ephemeral properties which
+are only relevant during the lifetime of the instance and should not be saved
+in state.
+
+The specific uses for contexts are application specific.  However, the context
+MUST be a URI, and can be interpreted as the ID of a data model where
+properties should be stored.  Implementations MAY have special support for
+contexts, for example by storing in a quad store or serializing to a format
+that supports multiple RDF graphs such as TriG.
+
+"""^^lv2:Markdown .
+
+patch:readable
+	lv2:documentation """
+
+See the similar patch:writable property for details.
+
+"""^^lv2:Markdown .
+
+patch:request
+	lv2:documentation """
+
+This can be used if referring directly to the URI or blank node ID of the
+request is possible.  Otherwise, use patch:sequenceNumber.
+
+"""^^lv2:Markdown .
+
+patch:sequenceNumber
+	lv2:documentation """
+
+This property is used to associate replies with requests when it is not
+feasible to refer to request URIs with patch:request.  A patch:Response with a
+given sequence number is the reply to the previously send patch:Request with
+the same sequence number.
+
+The special sequence number 0 means that no reply is desired.
+
+"""^^lv2:Markdown .
+
+patch:wildcard
+	lv2:documentation """
+
+This makes it possible to describe the removal of all values for a given
+property.
+
+"""^^lv2:Markdown .
+
+patch:writable
+	lv2:documentation """
+
+This is used to list properties that can be changed, for example to allow user
+interfaces to present appropriate controls.  For example:
+
+    :::turtle
+    @prefix eg:   &lt;http://example.org/&gt; .
+    @prefix rdf:  &lt;http://www.w3.org/1999/02/22-rdf-syntax-ns#&gt; .
+    @prefix rdfs: &lt;http://www.w3.org/2000/01/rdf-schema#&gt; .
+    @prefix xsd:  &lt;http://www.w3.org/2001/XMLSchema#&gt; .
+
+    eg:title
+        a rdf:Property ;
+        rdfs:label "title" ;
+        rdfs:range xsd:string .
+
+    eg:plugin
+        patch:writable eg:title .
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/patch/patch.ttl b/sys/lv2/patch/patch.ttl
index 71c51a33..78040094 100644
--- a/sys/lv2/patch/patch.ttl
+++ b/sys/lv2/patch/patch.ttl
@@ -1,52 +1,22 @@
-@prefix foaf:  <http://xmlns.com/foaf/0.1/> .
-@prefix lv2:   <http://lv2plug.in/ns/lv2core#> .
-@prefix owl:   <http://www.w3.org/2002/07/owl#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
 @prefix patch: <http://lv2plug.in/ns/ext/patch#> .
-@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
-@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
-@prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
 
 <http://lv2plug.in/ns/ext/patch>
 	a owl:Ontology ;
 	rdfs:seeAlso <patch.h> ,
-		<lv2-patch.doap.ttl> ;
-	lv2:documentation """
-<p>This vocabulary defines messages which can be used to access and manipulate
-properties.  It is designed to provide a dynamic control interface for LV2
-plugins, but is useful in many contexts.</p>
-
-<p>The main feature of this design is that the messages themselves are
-described in the same format as the data they work with.  In particular,
-messages can be serialised as a binary <a
-href="../atom/atom.html#Object">Object</a> or in Turtle (or any other RDF
-serialisation).</p>
-
-<p>The idea behind using a property-based interface for control is to prevent
-an an explosion of message types.  Instead of a custom message for each action,
-control is achieved via manipulating properties (which are likely already
-defined for other reasons).  Note, however, that this is purely conceptual;
-there is no requirement that the receiver actually implement a store of
-resources with properties.</p>
-
-<p>For example, consider an object that can blink.  Rather than define a
-specific interface to control this (e.g. <code>obj.start_blinking();
-obj.stop_blinking()</code>), set a <q>blinking</q> property to true or false
-(e.g. <code>obj.set(blinking, true)</code>) to achieve the desired behaviour.
-One benefit of this approach is that a persistent state model is available
-<q>for free</q>: simply serialise the <q>blinking</q> property.</p>
-
-<p>This specification is strictly metadata and does not define any binary
-mechanism, though it can be completely expressed by standard types in the <a
-href="../atom/atom.html">LV2 Atom</a> extension.  Thus, hosts can be expected
-to be capable of transmitting it between plugins, or between a plugin and its
-UI, making it a good choice for advanced plugin control.</p>
-""" .
+		<patch.meta.ttl> ;
+	rdfs:label "LV2 Patch" ;
+	rdfs:comment "A protocol for accessing and manipulating properties." .
 
 patch:Ack
 	a rdfs:Class ;
 	rdfs:subClassOf patch:Response ;
 	rdfs:label "Ack" ;
-	rdfs:comment """An acknowledgement that a request has been successfully processed.  This is returned as a reply when a specific reply type is not necessary or appropriate. """ .
+	rdfs:comment "An acknowledgement that a request was successful." .
 
 patch:Copy
 	a rdfs:Class ;
@@ -61,15 +31,13 @@ patch:Copy
 		owl:cardinality 1 ;
 		owl:onProperty patch:destination
 	] ;
-	rdfs:comment """Copy the patch:subject to patch:destination.  After this, patch:destination has the description patch:subject had prior to this request's execution, and patch:subject is unchanged.  It is an error if the subject does not exist or the destination already exists.
-
-Multiple patch:subject properties may be given if the patch:destination is a container, the semantics of this use case are application defined.""" .
+	rdfs:comment "A request to copy the patch:subject to the patch:destination." .
 
 patch:Delete
 	a rdfs:Class ;
 	rdfs:subClassOf patch:Request ;
 	rdfs:label "Delete" ;
-	rdfs:comment "Request the subject(s) be deleted." .
+	rdfs:comment "Request that the patch:subject or subjects be deleted." .
 
 patch:Error
 	a rdfs:Class ;
@@ -81,56 +49,7 @@ patch:Get
 	a rdfs:Class ;
 	rdfs:subClassOf patch:Request ;
 	rdfs:label "Get" ;
-	rdfs:comment "Request a description of the subject." ;
-	lv2:documentation """
-<p>Request a description of the subject.</p>
-
-<p>The detail of the response is not specified, it may be a flat description of
-all the properties of the subject, or a more expressive description with
-several subjects.  A good choice is a <q><a
-href="http://www.w3.org/Submission/CBD/">concise bounded description</a></q>,
-i.e. a description which recursively includes all properties with blank node
-values.</p>
-
-<p>The response should have the same patch:subject property as the request, and
-a patch:body that is a description of that subject.  For example:</p>
-<pre class="turtle-code">
-&lt;get-request&gt;
-    a patch:Get ;
-    patch:subject &lt;something&gt; .
-</pre>
-
-<p>Could result in:</p>
-<pre class="turtle-code">
-[]
-    a patch:Response ;
-    patch:request &lt;get-request&gt; ;
-    patch:subject &lt;something&gt; ;
-    patch:body [
-        eg:name "Something" ;
-        eg:ratio 1.6180339887 ;
-    ] .
-</pre>
-
-<p>Note the use of blank nodes is not required; the value of patch:body may be
-the actual resource node.  Depending on the transport and syntax used this may
-be preferable.  For example, the same response could be written:</p>
-
-<pre class="turtle-code">
-&lt;something&gt;
-    eg:name "Something" ;
-    eg:ratio 1.6180339887 .
-
-[]
-    a patch:Response ;
-    patch:request &lt;get-request&gt; ;
-    patch:subject &lt;something&gt; ;
-    patch:body &lt;something&gt; .
-</pre>
-
-<p>If the patch:subject property is absent, then the Get implicitly applies to
-the receiver.</p>
-""" .
+	rdfs:comment "A request for a description of the patch:subject." .
 
 patch:Insert
 	a rdfs:Class ;
@@ -141,11 +60,12 @@ patch:Insert
 		owl:cardinality 1 ;
 		owl:onProperty patch:subject
 	] ;
-	rdfs:comment """Insert the patch:body at patch:subject.  If the subject does not exist, it is created.  If the subject does already exist, it is added to.  This request only adds properties, it never removes them.  The user must take care that multiple values are not set for properties which should only have one value.""" .
+	rdfs:comment "A request to insert a patch:body into the patch:subject." .
 
 patch:Message
 	a rdfs:Class ;
-	rdfs:label "Patch Message" .
+	rdfs:label "Patch Message" ;
+	rdfs:comment "A patch message." .
 
 patch:Move
 	a rdfs:Class ;
@@ -160,7 +80,7 @@ patch:Move
 		owl:cardinality 1 ;
 		owl:onProperty patch:destination
 	] ;
-	rdfs:comment "Move the patch:subject to patch:destination.  After this, patch:destination has the description patch:subject had prior to this request's execution, and patch:subject no longer exists.  It is an error if the subject does not exist or the destination already exists." .
+	rdfs:comment "A request to move the patch:subject to the patch:destination." .
 
 patch:Patch
 	a rdfs:Class ;
@@ -169,32 +89,17 @@ patch:Patch
 		a owl:Restriction ;
 		owl:minCardinality 1 ;
 		owl:onProperty patch:subject
+	] , [
+		a owl:Restriction ;
+		owl:cardinality 1 ;
+		owl:onProperty patch:add
+	] , [
+		a owl:Restriction ;
+		owl:cardinality 1 ;
+		owl:onProperty patch:remove
 	] ;
 	rdfs:label "Patch" ;
-	rdfs:comment "Add and/or remove properties of the subject." ;
-	lv2:documentation """
-<p>Add and/or remove properties of the subject.</p>
-
-<p>This method always has at least one patch:subject, and exactly one patch:add
-and patch:remove property.  The value of patch:add and patch:remove are nodes
-which have the properties to add or remove from the subject(s), respectively.
-The special value patch:wildcard may be used as the value of a remove property
-to remove all properties with the given predicate.  For example:</p>
-
-<pre class="turtle-code">
-[]
-    a patch:Patch ;
-    patch:subject &lt;something&gt; ;
-    patch:add [
-        eg:name "New name" ;
-        eg:age 42 ;
-    ] ;
-    patch:remove [
-        eg:name "Old name" ;
-        eg:age patch:wildcard ;  # Remove all old eg:age properties
-    ] .
-</pre>
-""" .
+	rdfs:comment "A request to add and/or remove properties of the patch:subject." .
 
 patch:Put
 	a rdfs:Class ;
@@ -205,30 +110,19 @@ patch:Put
 		owl:cardinality 1 ;
 		owl:onProperty patch:subject
 	] ;
-	lv2:documentation """<p>Put the patch:body as the patch:subject.  If the subject does not already exist, it is created.  If the subject does already exist, the patch:body is considered an updated version of it, and the previous version is replaced.</p>
-
-<pre class="turtle-code">
-[]
-    a patch:Put ;
-    patch:subject &lt;something&gt; ;
-    patch:body [
-        eg:name "New name" ;
-        eg:age 42 ;
-    ] .
-</pre>
-""" .
+	rdfs:comment "A request to put the patch:body as the patch:subject." .
 
 patch:Request
 	a rdfs:Class ;
 	rdfs:label "Request" ;
 	rdfs:subClassOf patch:Message ;
-	rdfs:comment """A request.  A request may have a patch:subject property, which indicates which resource the request applies to.  The subject may be omitted in contexts where it is implicit (e.g. the recipient is the subject).""" .
+	rdfs:comment "A patch request message." .
 
 patch:Response
 	a rdfs:Class ;
 	rdfs:subClassOf patch:Message ;
 	rdfs:label "Response" ;
-	rdfs:comment "A response to a message." .
+	rdfs:comment "A response to a patch:Request." .
 
 patch:Set
 	a rdfs:Class ;
@@ -243,37 +137,11 @@ patch:Set
 		owl:cardinality 1 ;
 		owl:onProperty patch:value
 	] ;
-	rdfs:comment "Set one property to a specific value." ;
-	lv2:documentation """
-<p>A compact message for setting one property to a specific value.</p>
-
-<p>This is equivalent to a patch:Patch which removes <em>all</em> pre-existing
-values for the property before setting the new value.  For example:</p>
-
-<pre class="turtle-code">
-[]
-    a patch:Set ;
-    patch:subject &lt;something&gt; ;
-    patch:property eg:name ;
-    patch:value "New name" .
-</pre>
-
-<p>Which is equivalent to:</p>
-<pre class="turtle-code">
-[]
-    a patch:Patch ;
-    patch:subject &lt;something&gt; ;
-    patch:add [
-        eg:name "New name" ;
-    ] ;
-    patch:remove [
-        eg:name patch:wildcard ;
-    ] .
-</pre>
-""" .
+	rdfs:comment "A compact request to set a property to a value." .
 
 patch:accept
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:ObjectProperty ;
 	rdfs:label "accept" ;
 	rdfs:domain patch:Request ;
 	rdfs:range rdfs:Class ;
@@ -283,61 +151,57 @@ patch:add
 	a rdf:Property ,
 		owl:ObjectProperty ,
 		owl:FunctionalProperty ;
-	rdfs:domain patch:Message .
+	rdfs:domain patch:Patch ;
+	rdfs:range rdfs:Resource ;
+	rdfs:label "add" ;
+	rdfs:comment "The properties to add to the subject." .
 
 patch:body
 	a rdf:Property ,
 		owl:ObjectProperty ,
 		owl:FunctionalProperty ;
 	rdfs:domain patch:Message ;
-	rdfs:comment """The body of a message.
-
-The details of this property's value depend on the type of message it is a
-part of.""" .
+	rdfs:label "body" ;
+	rdfs:comment "The body of a message." .
 
 patch:context
 	a rdf:Property ,
 		owl:ObjectProperty ;
 	rdfs:domain patch:Message ;
-	rdfs:comment """The context of properties in this message.
-
-For example, a plugin may have a special context for ephemeral properties which
-are only relevant during the lifetime of the instance and should not be saved
-in state.
-
-The specific uses for contexts are application specific.  However, the context
-MUST be a URI, and can be interpreted as the ID of a data model where
-properties should be stored.  Implementations MAY have special support for
-contexts, for example by storing in a quad store or serializing to a format
-that supports multiple RDF graphs such as TriG.
-""" .
+	rdfs:label "context" ;
+	rdfs:comment "The context of properties in this message." .
 
 patch:destination
 	a rdf:Property ,
 		owl:ObjectProperty ,
 		owl:FunctionalProperty ;
-	rdfs:domain patch:Message .
+	rdfs:domain patch:Message ;
+	rdfs:label "destination" ;
+	rdfs:comment "The destination to move the patch:subject to." .
 
 patch:property
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:ObjectProperty ;
 	rdfs:label "property" ;
-	rdfs:domain patch:Set ;
+	rdfs:domain patch:Message ;
 	rdfs:range rdf:Property ;
-	rdfs:comment "The property for a Set message." .
+	rdfs:comment "The property for a patch:Set or patch:Get message." .
 
 patch:readable
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:ObjectProperty ;
 	rdfs:label "readable" ;
 	rdfs:range rdf:Property ;
-	rdfs:comment """Indicates that the subject may have a property that can be read via a
-patch:Get message.  See the similar property patch:writable for details.""" .
+	rdfs:comment "A property that can be read with a patch:Get message." .
 
 patch:remove
 	a rdf:Property ,
 		owl:ObjectProperty ,
 		owl:FunctionalProperty ;
 	rdfs:label "remove" ;
-	rdfs:domain patch:Message .
+	rdfs:domain patch:Patch ;
+	rdfs:range rdfs:Resource ;
+	rdfs:comment "The properties to remove from the subject." .
 
 patch:request
 	a rdf:Property ,
@@ -346,28 +210,28 @@ patch:request
 	rdfs:label "request" ;
 	rdfs:domain patch:Response ;
 	rdfs:range patch:Request ;
-	rdfs:comment """The request this is a response to.  This can be used if referring directly to the URI or blank node ID of the request is possible.  Otherwise, use patch:sequenceNumber.""" .
+	rdfs:comment "The request this is a response to." .
 
 patch:sequenceNumber
 	a rdf:Property ,
-		owl:ObjectProperty ,
+		owl:DatatypeProperty ,
 		owl:FunctionalProperty ;
 	rdfs:label "sequence number" ;
 	rdfs:domain patch:Message ;
 	rdfs:range xsd:int ;
-	rdfs:comment """The sequence number of a request or response.  This property is used to associate replies with requests when it is not feasible to refer to request URIs with patch:request.  A patch:Response with a given sequence number is the reply to the previously send patch:Request with the same sequence number.
-
-The special sequence number 0 means no reply is desired. """ .
+	rdfs:comment "The sequence number of a request or response." .
 
 patch:subject
 	a rdf:Property ,
 		owl:ObjectProperty ,
 		owl:FunctionalProperty ;
 	rdfs:domain patch:Message ;
+	rdfs:label "subject" ;
 	rdfs:comment "The subject this message applies to." .
 
 patch:value
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:DatatypeProperty ;
 	rdfs:label "value" ;
 	rdfs:domain patch:Set ;
 	rdfs:range rdf:Property ;
@@ -375,28 +239,13 @@ patch:value
 
 patch:wildcard
 	a rdfs:Resource ;
-	rdfs:comment """A wildcard which matches any resource.  This makes it possible to describe the removal of all values for a given property.""" .
+	rdfs:label "wildcard" ;
+	rdfs:comment "A wildcard that matches any resource." .
 
 patch:writable
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:ObjectProperty ;
 	rdfs:label "writable" ;
 	rdfs:range rdf:Property ;
-	lv2:documentation """
-<p>Indicates that subject may have a property that can be written via a patch
-message.  This is used to list supported properties, e.g. so user interfaces
-can present appropriate controls.  For example:</p>
-
-<pre class="turtle-code">
-@prefix eg:   &lt;http://example.org/&gt; .
-@prefix rdf:  &lt;http://www.w3.org/1999/02/22-rdf-syntax-ns#&gt; .
-@prefix rdfs: &lt;http://www.w3.org/2000/01/rdf-schema#&gt; .
-
-eg:title
-    a rdf:Property ;
-    rdfs:label "title" ;
-    rdfs:range xsd:string .
+	rdfs:comment "A property that can be set with a patch:Set or patch:Patch message." .
 
-eg:plugin
-    patch:writable eg:title .
-</pre>
-""" .
diff --git a/sys/lv2/port-groups/NEWS b/sys/lv2/port-groups/NEWS
deleted file mode 100644
index e242f5af..00000000
--- a/sys/lv2/port-groups/NEWS
+++ /dev/null
@@ -1,12 +0,0 @@
-port-groups (1.2) stable;
-
-  * Use consistent label style.
-
- -- None <None>  Sun, 14 Oct 2012 00:00:00 +0000
-
-port-groups (1.0) stable;
-
-  * Initial release.
-
- -- None <None>  Tue, 17 Apr 2012 00:00:00 +0000
-
diff --git a/sys/lv2/port-groups/lv2-port-groups.doap.ttl b/sys/lv2/port-groups/lv2-port-groups.doap.ttl
deleted file mode 100644
index 90848d25..00000000
--- a/sys/lv2/port-groups/lv2-port-groups.doap.ttl
+++ /dev/null
@@ -1,34 +0,0 @@
-@prefix dcs: <http://ontologi.es/doap-changeset#> .
-@prefix doap: <http://usefulinc.com/ns/doap#> .
-@prefix foaf: <http://xmlns.com/foaf/0.1/> .
-@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-
-<http://lv2plug.in/ns/ext/port-groups>
-	a doap:Project ;
-	doap:license <http://opensource.org/licenses/isc> ;
-	doap:name "LV2 Port Groups" ;
-	doap:shortdesc "Multi-channel groups of LV2 ports." ;
-	doap:created "2008-00-00" ;
-	doap:developer <http://lv2plug.in/ns/meta#larsl> ,
-		<http://drobilla.net/drobilla#me> ;
-	doap:release [
-		doap:revision "1.2" ;
-		doap:created "2012-10-14" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Use consistent label style."
-			]
-		]
-	] , [
-		doap:revision "1.0" ;
-		doap:created "2012-04-17" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Initial release."
-			]
-		]
-	] .
diff --git a/sys/lv2/port-groups/manifest.ttl b/sys/lv2/port-groups/manifest.ttl
index fa893c66..a887cb0f 100644
--- a/sys/lv2/port-groups/manifest.ttl
+++ b/sys/lv2/port-groups/manifest.ttl
@@ -1,9 +1,9 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/port-groups>
 	a lv2:Specification ;
 	lv2:minorVersion 1 ;
-	lv2:microVersion 2 ;
+	lv2:microVersion 4 ;
 	rdfs:seeAlso <port-groups.ttl> .
 
diff --git a/sys/lv2/port-groups/port-groups.h b/sys/lv2/port-groups/port-groups.h
index a1bcd122..4c5699f1 100644
--- a/sys/lv2/port-groups/port-groups.h
+++ b/sys/lv2/port-groups/port-groups.h
@@ -16,6 +16,7 @@
 
 /**
    @defgroup port-groups Port Groups
+   @ingroup lv2
 
    Multi-channel groups of LV2 ports, see
    <http://lv2plug.in/ns/ext/port-groups> for details.
diff --git a/sys/lv2/port-groups/port-groups.meta.ttl b/sys/lv2/port-groups/port-groups.meta.ttl
new file mode 100644
index 00000000..67408ec2
--- /dev/null
+++ b/sys/lv2/port-groups/port-groups.meta.ttl
@@ -0,0 +1,144 @@
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix pg: <http://lv2plug.in/ns/ext/port-groups#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/port-groups>
+	a doap:Project ;
+	doap:license <http://opensource.org/licenses/isc> ;
+	doap:name "LV2 Port Groups" ;
+	doap:shortdesc "Multi-channel groups of LV2 ports." ;
+	doap:created "2008-00-00" ;
+	doap:developer <http://lv2plug.in/ns/meta#larsl> ,
+		<http://drobilla.net/drobilla#me> ;
+	doap:release [
+		doap:revision "1.4" ;
+		doap:created "2020-04-26" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.18.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Replace broken links with detailed Ambisonic channel descriptions."
+			] , [
+				rdfs:label "Remove incorrect type of pg:letterCode."
+			]
+		]
+	] , [
+		doap:revision "1.2" ;
+		doap:created "2012-10-14" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Use consistent label style."
+			]
+		]
+	] , [
+		doap:revision "1.0" ;
+		doap:created "2012-04-17" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Initial release."
+			]
+		]
+	] .
+
+pg:Group
+	lv2:documentation """
+
+A group logically combines ports which should be considered part of the same
+stream.  For example, two audio ports in a group may form a stereo stream.
+
+Like ports, groups have a lv2:symbol that is unique within the context of the
+plugin, where group symbols and port symbols reside in the same namespace.  In
+other words, a group on a plugin MUST NOT have the same symbol as any other
+group or port on that plugin.  This makes it possible to uniquely reference a
+port or group on a plugin with a single identifier and no context.
+
+Group definitions may be shared across plugins for brevity.  For example, a
+plugin collection may define a single URI for a pg:StereoGroup with the symbol
+"input" and use it in many plugins.
+
+"""^^lv2:Markdown .
+
+pg:sideChainOf
+	lv2:documentation """
+
+Indicates that this port or group should be considered a "side chain" of some
+other port or group.  The precise definition of "side chain" depends on the
+plugin, but in general this group should be considered a modifier to some other
+group, rather than an independent input itself.
+
+"""^^lv2:Markdown .
+
+pg:subGroupOf
+	lv2:documentation """
+
+Indicates that this group is a child of another group.  This property has no
+meaning with respect to plugin execution, but the host may find this
+information useful to provide a better user interface.  Note that being a
+sub-group does not relax the restriction that the group MUST have a unique
+symbol with respect to the plugin.
+
+"""^^lv2:Markdown .
+
+pg:source
+	lv2:documentation """
+
+Indicates that this port or group should be considered the "result" of some
+other port or group.  This property only makes sense on groups with outputs
+when the source is a group with inputs.  This can be used to convey a
+relationship between corresponding input and output groups with different
+types, for example in a mono to stereo plugin.
+
+"""^^lv2:Markdown .
+
+pg:mainInput
+	lv2:documentation """
+
+Indicates that this group should be considered the "main" input, i.e. the
+primary task is processing the signal in this group.  A plugin MUST NOT have
+more than one pg:mainInput property.
+
+"""^^lv2:Markdown .
+
+pg:mainOutput
+	lv2:documentation """
+
+Indicates that this group should be considered the "main" output.  The main
+output group SHOULD have the main input group as a pg:source.
+
+"""^^lv2:Markdown .
+
+pg:group
+	lv2:documentation """
+
+Indicates that this port is a part of a group of ports on the plugin.  The port
+should also have an lv2:designation property to define its designation within
+that group.
+
+"""^^lv2:Markdown .
+
+pg:DiscreteGroup
+	lv2:documentation """
+
+These groups are divided into channels where each represents a particular
+speaker location.  The position of sound in one of these groups depends on a
+particular speaker configuration.
+
+"""^^lv2:Markdown .
+
+pg:AmbisonicGroup
+	lv2:documentation """
+
+These groups are divided into channels which together represent a position in
+an abstract n-dimensional space. The position of sound in one of these groups
+does not depend on a particular speaker configuration; a decoder can be used to
+convert an ambisonic stream for any speaker configuration.
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/port-groups/port-groups.ttl b/sys/lv2/port-groups/port-groups.ttl
index 0681e420..aefe8f8e 100644
--- a/sys/lv2/port-groups/port-groups.ttl
+++ b/sys/lv2/port-groups/port-groups.ttl
@@ -1,13 +1,15 @@
-@prefix amb:  <http://ambisonics.ch/standards/channels/> .
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
-@prefix owl:  <http://www.w3.org/2002/07/owl#> .
-@prefix pg:   <http://lv2plug.in/ns/ext/port-groups#> .
-@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix pg: <http://lv2plug.in/ns/ext/port-groups#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
 
 <http://lv2plug.in/ns/ext/port-groups>
 	a owl:Ontology ;
-	rdfs:seeAlso <lv2-port-groups.doap.ttl> .
+	rdfs:label "LV2 Port Groups" ;
+	rdfs:comment "Multi-channel groups of LV2 ports." ;
+	rdfs:seeAlso <port-groups.meta.ttl> .
 
 pg:Group
 	a rdfs:Class ;
@@ -16,14 +18,9 @@ pg:Group
 		a owl:Restriction ;
 		owl:onProperty lv2:symbol ;
 		owl:cardinality 1 ;
-		rdfs:comment """A pg:Group MUST have exactly one string lv2:symbol.
-
-This symbol must be unique according to the same rules as the lv2:symbol for an lv2:Port, where group symbols and port symbols reside in the same namespace.  In other words, a group on a plugin MUST NOT have the same symbol as another group or a port on that plugin.  This makes it possible to uniquely reference a port or group on a plugin with a single identifier and no context."""
+		rdfs:comment "A Group MUST have exactly one string lv2:symbol."
 	] ;
-	rdfs:comment """A set of ports/channels/controls/etc that are are logically grouped together,
-e.g. two audio ports in a group may form a stereo stream.
-
-In order to avoid the need to define large numbers of identical group definitions, a group definition may be shared.  For example, a plugin collection may define a single URI for a pg:StereoGroup with the symbol "input" and use it in many plugins.""" .
+	rdfs:comment "A set of ports that are logicaly grouped together." .
 
 pg:InputGroup
 	a rdfs:Class ;
@@ -47,20 +44,20 @@ pg:Element
 		owl:cardinality 1 ;
 		rdfs:comment "An element MUST have exactly one lv2:designation."
 	] ;
-	rdfs:comment "An element of a group, which has a designation and an optional index." .
+	rdfs:comment "An element of a group, with a designation and optional index." .
 
 pg:element
 	a rdf:Property ,
 		owl:ObjectProperty ;
 	rdfs:range pg:Element ;
 	rdfs:label "element" ;
-	rdfs:comment """Indicates that a group has a certain element (a parameter or channel designation with a possible index).""" .
+	rdfs:comment "An element within a port group." .
 
 pg:sideChainOf
 	a rdf:Property ,
 		owl:ObjectProperty ;
 	rdfs:label "side-chain of" ;
-	rdfs:comment """Indicates that this port or group should be considered a "side chain" of some other port or group.  The precise definition of "side chain" depends on the plugin, but in general this group should be considered a modifier to some other group, rather than an independent input itself.""" .
+	rdfs:comment "Port or grou is a side chain of another." .
 
 pg:subGroupOf
 	a rdf:Property ,
@@ -69,7 +66,7 @@ pg:subGroupOf
 	rdfs:domain pg:Group ;
 	rdfs:range pg:Group ;
 	rdfs:label "sub-group of" ;
-	rdfs:comment """Indicates that this group is a child of another group.  This property has no meaning with respect to plugin execution, but the host may find this information useful (e.g. to provide a compact user interface).  Note that being a sub-group does not relax the restriction that the group MUST have a unique symbol with respect to the plugin.""" .
+	rdfs:comment "Group is a child of another group." .
 
 pg:source
 	a rdf:Property ,
@@ -77,7 +74,7 @@ pg:source
 	rdfs:domain pg:OutputGroup ;
 	rdfs:range pg:InputGroup ;
 	rdfs:label "source" ;
-	rdfs:comment """Indicates that this port or group should be considered the "result" of some other port or group.  This property only makes sense on groups with outputs when the source is a group with inputs.  This can be used to convey a relationship between corresponding input and output groups with different types, e.g. a mono->stereo plugin.""" .
+	rdfs:comment "Port or group that this group is the output of." .
 
 pg:mainInput
 	a rdf:Property ,
@@ -86,7 +83,7 @@ pg:mainInput
 	rdfs:domain lv2:Plugin ;
 	rdfs:range pg:InputGroup ;
 	rdfs:label "main input" ;
-	rdfs:comment """Indicates that this group should be considered the "main" input, i.e. the primary task is processing the signal in this group.  A plugin MUST NOT have more than one pg:mainInput property.""" .
+	rdfs:comment "Input group that is the primary input of the plugin." .
 
 pg:mainOutput
 	a rdf:Property ,
@@ -95,7 +92,7 @@ pg:mainOutput
 	rdfs:domain lv2:Plugin ;
 	rdfs:range pg:OutputGroup ;
 	rdfs:label "main output" ;
-	rdfs:comment """Indicates that this group should be considered the "main" output.  The main output group SHOULD have the main input group as a pg:source.""" .
+	rdfs:comment "Output group that is the primary output of the plugin." .
 
 pg:group
 	a rdf:Property ,
@@ -104,65 +101,79 @@ pg:group
 	rdfs:domain lv2:Port ;
 	rdfs:range pg:Group ;
 	rdfs:label "group" ;
-	rdfs:comment """Indicates that this port is a part of a group of ports on the plugin.  The port should also have an lv2:designation property to define its designation within that group.""" .
+	rdfs:comment "Group that this port is a part of." .
 
 pg:DiscreteGroup
 	a rdfs:Class ;
 	rdfs:subClassOf pg:Group ;
-	rdfs:comment """Discrete channel configurations.  These groups are divided into channels where each represents a particular speaker location.  The position of sound in one of these groups depends on a particular speaker configuration.""" .
+	rdfs:label "Discrete Group" ;
+	rdfs:comment "A group of discrete channels." .
 
 pg:left
 	a lv2:Channel ;
-	rdfs:label "left" .
+	rdfs:label "left" ;
+	rdfs:comment "The left channel of a stereo audio group." .
 
 pg:right
 	a lv2:Channel ;
-	rdfs:label "right" .
+	rdfs:label "right" ;
+	rdfs:comment "The right channel of a stereo audio group." .
 
 pg:center
 	a lv2:Channel ;
-	rdfs:label "center" .
+	rdfs:label "center" ;
+	rdfs:comment "The center channel of a discrete audio group." .
 
 pg:side
 	a lv2:Channel ;
-	rdfs:label "side" .
+	rdfs:label "side" ;
+	rdfs:comment "The side channel of a mid-side audio group." .
 
 pg:centerLeft
 	a lv2:Channel ;
-	rdfs:label "center left" .
+	rdfs:label "center left" ;
+	rdfs:comment "The center-left channel of a 7.1 wide surround sound group." .
 
 pg:centerRight
 	a lv2:Channel ;
-	rdfs:label "center right" .
+	rdfs:label "center right" ;
+	rdfs:comment "The center-right channel of a 7.1 wide surround sound group." .
 
 pg:sideLeft
 	a lv2:Channel ;
-	rdfs:label "side left" .
+	rdfs:label "side left" ;
+	rdfs:comment "The side-left channel of a 6.1 or 7.1 surround sound group." .
 
 pg:sideRight
 	a lv2:Channel ;
-	rdfs:label "side right" .
+	rdfs:label "side right" ;
+	rdfs:comment "The side-right channel of a 6.1 or 7.1 surround sound group." .
 
 pg:rearLeft
 	a lv2:Channel ;
-	rdfs:label "rear left" .
+	rdfs:label "rear left" ;
+	rdfs:comment "The rear-left channel of a surround sound group." .
 
 pg:rearRight
 	a lv2:Channel ;
-	rdfs:label "rear right" .
+	rdfs:label "rear right" ;
+	rdfs:comment "The rear-right channel of a surround sound group." .
 
 pg:rearCenter
 	a lv2:Channel ;
-	rdfs:label "rear center" .
+	rdfs:label "rear center" ;
+	rdfs:comment "The rear-center channel of a surround sound group." .
 
 pg:lowFrequencyEffects
 	a lv2:Channel ;
-	rdfs:label "low-frequency effects" .
+	rdfs:label "low-frequency effects" ;
+	rdfs:comment "The LFE channel of a *.1 surround sound group." .
 
 pg:MonoGroup
 	a rdfs:Class ;
 	rdfs:subClassOf pg:DiscreteGroup ;
 	rdfs:label "Mono" ;
+	rdfs:comment "A single channel audio group." ;
 	pg:element [
 		lv2:index 0 ;
 		lv2:designation pg:center
@@ -172,6 +183,7 @@ pg:StereoGroup
 	a rdfs:Class ;
 	rdfs:subClassOf pg:DiscreteGroup ;
 	rdfs:label "Stereo" ;
+	rdfs:comment "A 2-channel discrete stereo audio group." ;
 	pg:element [
 		lv2:index 0 ;
 		lv2:designation pg:left
@@ -184,6 +196,7 @@ pg:MidSideGroup
 	a rdfs:Class ;
 	rdfs:subClassOf pg:DiscreteGroup ;
 	rdfs:label "Mid-Side Stereo" ;
+	rdfs:comment "A 2-channel mid-side stereo audio group." ;
 	pg:element [
 		lv2:index 0 ;
 		lv2:designation pg:center
@@ -196,6 +209,7 @@ pg:ThreePointZeroGroup
 	a rdfs:Class ;
 	rdfs:subClassOf pg:DiscreteGroup ;
 	rdfs:label "3.0 Surround" ;
+	rdfs:comment "A 3.0 discrete surround sound group." ;
 	pg:element [
 		lv2:index 0 ;
 		lv2:designation pg:left
@@ -210,7 +224,8 @@ pg:ThreePointZeroGroup
 pg:FourPointZeroGroup
 	a rdfs:Class ;
 	rdfs:subClassOf pg:DiscreteGroup ;
-	rdfs:label "4.0 Surround (Quadraphonic)" ;
+	rdfs:label "4.0 Surround" ;
+	rdfs:comment "A 4.0 (Quadraphonic) discrete surround sound group." ;
 	pg:element [
 		lv2:index 0 ;
 		lv2:designation pg:left
@@ -228,7 +243,8 @@ pg:FourPointZeroGroup
 pg:FivePointZeroGroup
 	a rdfs:Class ;
 	rdfs:subClassOf pg:DiscreteGroup ;
-	rdfs:label "5.0 Surround (3-2 stereo)" ;
+	rdfs:label "5.0 Surround" ;
+	rdfs:comment "A 5.0 (3-2 stereo) discrete surround sound group." ;
 	pg:element [
 		lv2:index 0 ;
 		lv2:designation pg:left
@@ -249,7 +265,8 @@ pg:FivePointZeroGroup
 pg:FivePointOneGroup
 	a rdfs:Class ;
 	rdfs:subClassOf pg:DiscreteGroup ;
-	rdfs:label "5.1 Surround (3-2 stereo)" ;
+	rdfs:label "5.1 Surround" ;
+	rdfs:comment "A 5.1 (3-2 stereo with sub) discrete surround sound group." ;
 	pg:element [
 		lv2:index 0 ;
 		lv2:designation pg:left
@@ -274,6 +291,7 @@ pg:SixPointOneGroup
 	a rdfs:Class ;
 	rdfs:subClassOf pg:DiscreteGroup ;
 	rdfs:label "6.1 Surround" ;
+	rdfs:comment "A 6.1 discrete surround sound group." ;
 	pg:element [
 		lv2:index 0 ;
 		lv2:designation pg:left
@@ -301,6 +319,7 @@ pg:SevenPointOneGroup
 	a rdfs:Class ;
 	rdfs:subClassOf pg:DiscreteGroup ;
 	rdfs:label "7.1 Surround" ;
+	rdfs:comment "A 7.1 discrete surround sound group." ;
 	pg:element [
 		lv2:index 0 ;
 		lv2:designation pg:left
@@ -331,6 +350,7 @@ pg:SevenPointOneWideGroup
 	a rdfs:Class ;
 	rdfs:subClassOf pg:DiscreteGroup ;
 	rdfs:label "7.1 Surround (Wide)" ;
+	rdfs:comment "A 7.1 wide discrete surround sound group." ;
 	pg:element [
 		lv2:index 0 ;
 		lv2:designation pg:left
@@ -357,316 +377,431 @@ pg:SevenPointOneWideGroup
 		lv2:designation pg:lowFrequencyEffects
 	] .
 
-amb:ACN0
-	a lv2:Channel .
+pg:letterCode
+	a rdf:Property ,
+		owl:DatatypeProperty ;
+	rdfs:domain lv2:Channel ;
+	rdfs:range rdf:PlainLiteral ;
+	rdfs:label "ambisonic letter code" ;
+	rdfs:comment "The YuMa letter code for an Ambisonic channel." .
 
-amb:ACN1
-	a lv2:Channel .
+pg:harmonicDegree
+	a rdf:Property ,
+		owl:DatatypeProperty ;
+	rdfs:domain lv2:Channel ;
+	rdfs:range xsd:integer ;
+	rdfs:label "harmonic degree" ;
+	rdfs:comment "The degree coefficient (l) of the spherical harmonic for an Ambisonic channel." .
 
-amb:ACN2
-	a lv2:Channel .
+pg:harmonicIndex
+	a rdf:Property ,
+		owl:DatatypeProperty ;
+	rdfs:domain lv2:Channel ;
+	rdfs:range xsd:integer ;
+	rdfs:label "harmonic index" ;
+	rdfs:comment "The index coefficient (m) of the spherical harmonic for an Ambisonic channel." .
 
-amb:ACN3
-	a lv2:Channel .
+pg:ACN0
+	a lv2:Channel ;
+	pg:letterCode "W" ;
+	pg:harmonicDegree 0 ;
+	pg:harmonicIndex 0 ;
+	rdfs:label "ACN0" ;
+	rdfs:comment "Ambisonic channel 0 (W): degree 0, index 0." .
 
-amb:ACN4
-	a lv2:Channel .
+pg:ACN1
+	a lv2:Channel ;
+	pg:letterCode "Y" ;
+	pg:harmonicDegree 1 ;
+	pg:harmonicIndex -1 ;
+	rdfs:label "ACN1" ;
+	rdfs:comment "Ambisonic channel 1 (Y): degree 1, index -1." .
 
-amb:ACN5
-	a lv2:Channel .
+pg:ACN2
+	a lv2:Channel ;
+	pg:letterCode "Z" ;
+	pg:harmonicDegree 1 ;
+	pg:harmonicIndex 0 ;
+	rdfs:label "ACN2" ;
+	rdfs:comment "Ambisonic channel 2 (Z): degree 1, index 0." .
 
-amb:ACN6
-	a lv2:Channel .
+pg:ACN3
+	a lv2:Channel ;
+	pg:letterCode "X" ;
+	pg:harmonicDegree 1 ;
+	pg:harmonicIndex 1 ;
+	rdfs:label "ACN3" ;
+	rdfs:comment "Ambisonic channel 3 (X): degree 1, index 1." .
 
-amb:ACN7
-	a lv2:Channel .
+pg:ACN4
+	a lv2:Channel ;
+	pg:letterCode "V" ;
+	pg:harmonicDegree 2 ;
+	pg:harmonicIndex -2 ;
+	rdfs:label "ACN4" ;
+	rdfs:comment "Ambisonic channel 4 (V): degree 2, index -2." .
 
-amb:ACN8
-	a lv2:Channel .
+pg:ACN5
+	a lv2:Channel ;
+	pg:letterCode "T" ;
+	pg:harmonicDegree 2 ;
+	pg:harmonicIndex -1 ;
+	rdfs:label "ACN5" ;
+	rdfs:comment "Ambisonic channel 5 (T): degree 2, index -1." .
 
-amb:ACN9
-	a lv2:Channel .
+pg:ACN6
+	a lv2:Channel ;
+	pg:letterCode "R" ;
+	pg:harmonicDegree 2 ;
+	pg:harmonicIndex 0 ;
+	rdfs:label "ACN6" ;
+	rdfs:comment "Ambisonic channel 6 (R): degree 2, index 0." .
 
-amb:ACN10
-	a lv2:Channel .
+pg:ACN7
+	a lv2:Channel ;
+	pg:letterCode "S" ;
+	pg:harmonicDegree 2 ;
+	pg:harmonicIndex 1 ;
+	rdfs:label "ACN7" ;
+	rdfs:comment "Ambisonic channel 7 (S): degree 2, index 1." .
 
-amb:ACN11
-	a lv2:Channel .
+pg:ACN8
+	a lv2:Channel ;
+	pg:letterCode "U" ;
+	pg:harmonicDegree 2 ;
+	pg:harmonicIndex 2 ;
+	rdfs:label "ACN8" ;
+	rdfs:comment "Ambisonic channel 8 (U): degree 2, index 2." .
+
+pg:ACN9
+	a lv2:Channel ;
+	pg:letterCode "Q" ;
+	pg:harmonicDegree 3 ;
+	pg:harmonicIndex -3 ;
+	rdfs:label "ACN9" ;
+	rdfs:comment "Ambisonic channel 9 (Q): degree 3, index -3." .
+
+pg:ACN10
+	a lv2:Channel ;
+	pg:letterCode "O" ;
+	pg:harmonicDegree 3 ;
+	pg:harmonicIndex -2 ;
+	rdfs:label "ACN10" ;
+	rdfs:comment "Ambisonic channel 10 (O): degree 3, index -2." .
+
+pg:ACN11
+	a lv2:Channel ;
+	pg:letterCode "M" ;
+	pg:harmonicDegree 3 ;
+	pg:harmonicIndex -1 ;
+	rdfs:label "ACN11" ;
+	rdfs:comment "Ambisonic channel 11 (M): degree 3, index -1." .
 
-amb:ACN12
-	a lv2:Channel .
+pg:ACN12
+	a lv2:Channel ;
+	pg:letterCode "K" ;
+	pg:harmonicDegree 3 ;
+	pg:harmonicIndex 0 ;
+	rdfs:label "ACN12" ;
+	rdfs:comment "Ambisonic channel 12 (K): degree 3, index 0." .
 
-amb:ACN13
-	a lv2:Channel .
+pg:ACN13
+	a lv2:Channel ;
+	pg:letterCode "L" ;
+	pg:harmonicDegree 3 ;
+	pg:harmonicIndex 1 ;
+	rdfs:label "ACN13" ;
+	rdfs:comment "Ambisonic channel 13 (L): degree 3, index 1." .
 
-amb:ACN14
-	a lv2:Channel .
+pg:ACN14
+	a lv2:Channel ;
+	pg:letterCode "N" ;
+	pg:harmonicDegree 3 ;
+	pg:harmonicIndex 2 ;
+	rdfs:label "ACN14" ;
+	rdfs:comment "Ambisonic channel 14 (N): degree 3, index 2." .
 
-amb:ACN15
-	a lv2:Channel .
+pg:ACN15
+	a lv2:Channel ;
+	pg:letterCode "P" ;
+	pg:harmonicDegree 3 ;
+	pg:harmonicIndex 3 ;
+	rdfs:label "ACN15" ;
+	rdfs:comment "Ambisonic channel 15 (P): degree 3, index 3." .
 
 pg:AmbisonicGroup
 	a rdfs:Class ;
 	rdfs:subClassOf pg:Group ;
-	rdfs:comment """Ambisonic channel configurations.  These groups are divided into channels which together represent a position in an abstract n-dimensional space. The position of sound in one of these groups does not depend on a particular speaker configuration; a decoder can be used to convert an ambisonic stream for any speaker configuration.""" .
+	rdfs:label "Ambisonic Group" ;
+	rdfs:comment "A group of Ambisonic channels." .
 
 pg:AmbisonicBH1P0Group
 	a rdfs:Class ;
 	rdfs:subClassOf pg:AmbisonicGroup ;
-	rdfs:label "Ambisonic B stream of horizontal order 1 and peripheral order 0." ;
+	rdfs:label "Ambisonic BH1P0" ;
+	rdfs:comment "Ambisonic B stream of horizontal order 1 and peripheral order 0." ;
 	pg:element [
 		lv2:index 0 ;
-		lv2:designation amb:ACN0
+		lv2:designation pg:ACN0
 	] , [
 		lv2:index 1 ;
-		lv2:designation amb:ACN1
+		lv2:designation pg:ACN1
 	] , [
 		lv2:index 2 ;
-		lv2:designation amb:ACN3
+		lv2:designation pg:ACN3
 	] .
 
 pg:AmbisonicBH1P1Group
 	a rdfs:Class ;
 	rdfs:subClassOf pg:AmbisonicGroup ;
-	rdfs:label "Ambisonic B stream of horizontal order 1 and peripheral order 1." ;
+	rdfs:label "Ambisonic BH1P1" ;
+	rdfs:comment "Ambisonic B stream of horizontal order 1 and peripheral order 1." ;
 	pg:element [
 		lv2:index 0 ;
-		lv2:designation amb:ACN0
+		lv2:designation pg:ACN0
 	] , [
 		lv2:index 1 ;
-		lv2:designation amb:ACN1
+		lv2:designation pg:ACN1
 	] , [
 		lv2:index 2 ;
-		lv2:designation amb:ACN2
+		lv2:designation pg:ACN2
 	] , [
 		lv2:index 3 ;
-		lv2:designation amb:ACN3
+		lv2:designation pg:ACN3
 	] .
 
 pg:AmbisonicBH2P0Group
 	a rdfs:Class ;
 	rdfs:subClassOf pg:AmbisonicGroup ;
-	rdfs:label "Ambisonic B stream of horizontal order 2 and peripheral order 0." ;
+	rdfs:label "Ambisonic BH2P0" ;
+	rdfs:comment "Ambisonic B stream of horizontal order 2 and peripheral order 0." ;
 	pg:element [
 		lv2:index 0 ;
-		lv2:designation amb:ACN0
+		lv2:designation pg:ACN0
 	] , [
 		lv2:index 1 ;
-		lv2:designation amb:ACN1
+		lv2:designation pg:ACN1
 	] , [
 		lv2:index 2 ;
-		lv2:designation amb:ACN3
+		lv2:designation pg:ACN3
 	] , [
 		lv2:index 3 ;
-		lv2:designation amb:ACN4
+		lv2:designation pg:ACN4
 	] , [
 		lv2:index 4 ;
-		lv2:designation amb:ACN8
+		lv2:designation pg:ACN8
 	] .
 
 pg:AmbisonicBH2P1Group
 	a rdfs:Class ;
 	rdfs:subClassOf pg:AmbisonicGroup ;
-	rdfs:label "Ambisonic B stream of horizontal order 2 and peripheral order 1." ;
+	rdfs:label "Ambisonic BH2P1" ;
+	rdfs:comment "Ambisonic B stream of horizontal order 2 and peripheral order 1." ;
 	pg:element [
 		lv2:index 0 ;
-		lv2:designation amb:ACN0
+		lv2:designation pg:ACN0
 	] , [
 		lv2:index 1 ;
-		lv2:designation amb:ACN1
+		lv2:designation pg:ACN1
 	] , [
 		lv2:index 2 ;
-		lv2:designation amb:ACN2
+		lv2:designation pg:ACN2
 	] , [
 		lv2:index 3 ;
-		lv2:designation amb:ACN3
+		lv2:designation pg:ACN3
 	] , [
 		lv2:index 4 ;
-		lv2:designation amb:ACN4
+		lv2:designation pg:ACN4
 	] , [
 		lv2:index 5 ;
-		lv2:designation amb:ACN8
+		lv2:designation pg:ACN8
 	] .
 
 pg:AmbisonicBH2P2Group
 	a rdfs:Class ;
 	rdfs:subClassOf pg:AmbisonicGroup ;
-	rdfs:label "Ambisonic B stream of horizontal order 2 and peripheral order 2." ;
+	rdfs:label "Ambisonic BH2P2" ;
+	rdfs:comment "Ambisonic B stream of horizontal order 2 and peripheral order 2." ;
 	pg:element [
 		lv2:index 0 ;
-		lv2:designation amb:ACN0
+		lv2:designation pg:ACN0
 	] , [
 		lv2:index 1 ;
-		lv2:designation amb:ACN1
+		lv2:designation pg:ACN1
 	] , [
 		lv2:index 2 ;
-		lv2:designation amb:ACN2
+		lv2:designation pg:ACN2
 	] , [
 		lv2:index 3 ;
-		lv2:designation amb:ACN3
+		lv2:designation pg:ACN3
 	] , [
 		lv2:index 4 ;
-		lv2:designation amb:ACN4
+		lv2:designation pg:ACN4
 	] , [
 		lv2:index 5 ;
-		lv2:designation amb:ACN5
+		lv2:designation pg:ACN5
 	] , [
 		lv2:index 6 ;
-		lv2:designation amb:ACN6
+		lv2:designation pg:ACN6
 	] , [
 		lv2:index 7 ;
-		lv2:designation amb:ACN7
+		lv2:designation pg:ACN7
 	] , [
 		lv2:index 8 ;
-		lv2:designation amb:ACN8
+		lv2:designation pg:ACN8
 	] .
 
 pg:AmbisonicBH3P0Group
 	a rdfs:Class ;
 	rdfs:subClassOf pg:AmbisonicGroup ;
-	rdfs:label "Ambisonic B stream of horizontal order 3 and peripheral order 0." ;
+	rdfs:label "Ambisonic BH3P0" ;
+	rdfs:comment "Ambisonic B stream of horizontal order 3 and peripheral order 0." ;
 	pg:element [
 		lv2:index 0 ;
-		lv2:designation amb:ACN0
+		lv2:designation pg:ACN0
 	] , [
 		lv2:index 1 ;
-		lv2:designation amb:ACN1
+		lv2:designation pg:ACN1
 	] , [
 		lv2:index 2 ;
-		lv2:designation amb:ACN3
+		lv2:designation pg:ACN3
 	] , [
 		lv2:index 3 ;
-		lv2:designation amb:ACN4
+		lv2:designation pg:ACN4
 	] , [
 		lv2:index 4 ;
-		lv2:designation amb:ACN8
+		lv2:designation pg:ACN8
 	] , [
 		lv2:index 5 ;
-		lv2:designation amb:ACN9
+		lv2:designation pg:ACN9
 	] , [
 		lv2:index 6 ;
-		lv2:designation amb:ACN15
+		lv2:designation pg:ACN15
 	] .
 
 pg:AmbisonicBH3P1Group
 	a rdfs:Class ;
 	rdfs:subClassOf pg:AmbisonicGroup ;
-	rdfs:label "Ambisonic B stream of horizontal order 3 and peripheral order 1." ;
+	rdfs:label "Ambisonic BH3P1" ;
+	rdfs:comment "Ambisonic B stream of horizontal order 3 and peripheral order 1." ;
 	pg:element [
 		lv2:index 0 ;
-		lv2:designation amb:ACN0
+		lv2:designation pg:ACN0
 	] , [
 		lv2:index 1 ;
-		lv2:designation amb:ACN1
+		lv2:designation pg:ACN1
 	] , [
 		lv2:index 2 ;
-		lv2:designation amb:ACN2
+		lv2:designation pg:ACN2
 	] , [
 		lv2:index 3 ;
-		lv2:designation amb:ACN3
+		lv2:designation pg:ACN3
 	] , [
 		lv2:index 4 ;
-		lv2:designation amb:ACN4
+		lv2:designation pg:ACN4
 	] , [
 		lv2:index 5 ;
-		lv2:designation amb:ACN8
+		lv2:designation pg:ACN8
 	] , [
 		lv2:index 6 ;
-		lv2:designation amb:ACN9
+		lv2:designation pg:ACN9
 	] , [
 		lv2:index 7 ;
-		lv2:designation amb:ACN15
+		lv2:designation pg:ACN15
 	] .
 
 pg:AmbisonicBH3P2Group
 	a rdfs:Class ;
 	rdfs:subClassOf pg:AmbisonicGroup ;
-	rdfs:label "Ambisonic B stream of horizontal order 3 and peripheral order 2." ;
+	rdfs:label "Ambisonic BH3P2" ;
+	rdfs:comment "Ambisonic B stream of horizontal order 3 and peripheral order 2." ;
 	pg:element [
 		lv2:index 0 ;
-		lv2:designation amb:ACN0
+		lv2:designation pg:ACN0
 	] , [
 		lv2:index 1 ;
-		lv2:designation amb:ACN1
+		lv2:designation pg:ACN1
 	] , [
 		lv2:index 2 ;
-		lv2:designation amb:ACN2
+		lv2:designation pg:ACN2
 	] , [
 		lv2:index 3 ;
-		lv2:designation amb:ACN3
+		lv2:designation pg:ACN3
 	] , [
 		lv2:index 4 ;
-		lv2:designation amb:ACN4
+		lv2:designation pg:ACN4
 	] , [
 		lv2:index 5 ;
-		lv2:designation amb:ACN5
+		lv2:designation pg:ACN5
 	] , [
 		lv2:index 6 ;
-		lv2:designation amb:ACN6
+		lv2:designation pg:ACN6
 	] , [
 		lv2:index 7 ;
-		lv2:designation amb:ACN7
+		lv2:designation pg:ACN7
 	] , [
 		lv2:index 8 ;
-		lv2:designation amb:ACN8
+		lv2:designation pg:ACN8
 	] , [
 		lv2:index 9 ;
-		lv2:designation amb:ACN9
+		lv2:designation pg:ACN9
 	] , [
 		lv2:index 10 ;
-		lv2:designation amb:ACN15
+		lv2:designation pg:ACN15
 	] .
 
 pg:AmbisonicBH3P3Group
 	a rdfs:Class ;
 	rdfs:subClassOf pg:AmbisonicGroup ;
-	rdfs:label "Ambisonic B stream of horizontal order 3 and peripheral order 3." ;
+	rdfs:label "Ambisonic BH3P3" ;
+	rdfs:comment "Ambisonic B stream of horizontal order 3 and peripheral order 3." ;
 	pg:element [
 		lv2:index 0 ;
-		lv2:designation amb:ACN0
+		lv2:designation pg:ACN0
 	] , [
 		lv2:index 1 ;
-		lv2:designation amb:ACN1
+		lv2:designation pg:ACN1
 	] , [
 		lv2:index 2 ;
-		lv2:designation amb:ACN2
+		lv2:designation pg:ACN2
 	] , [
 		lv2:index 3 ;
-		lv2:designation amb:ACN3
+		lv2:designation pg:ACN3
 	] , [
 		lv2:index 4 ;
-		lv2:designation amb:ACN4
+		lv2:designation pg:ACN4
 	] , [
 		lv2:index 5 ;
-		lv2:designation amb:ACN5
+		lv2:designation pg:ACN5
 	] , [
 		lv2:index 6 ;
-		lv2:designation amb:ACN6
+		lv2:designation pg:ACN6
 	] , [
 		lv2:index 7 ;
-		lv2:designation amb:ACN7
+		lv2:designation pg:ACN7
 	] , [
 		lv2:index 8 ;
-		lv2:designation amb:ACN8
+		lv2:designation pg:ACN8
 	] , [
 		lv2:index 9 ;
-		lv2:designation amb:ACN9
+		lv2:designation pg:ACN9
 	] , [
 		lv2:index 10 ;
-		lv2:designation amb:ACN10
+		lv2:designation pg:ACN10
 	] , [
 		lv2:index 11 ;
-		lv2:designation amb:ACN11
+		lv2:designation pg:ACN11
 	] , [
 		lv2:index 12 ;
-		lv2:designation amb:ACN12
+		lv2:designation pg:ACN12
 	] , [
 		lv2:index 13 ;
-		lv2:designation amb:ACN13
+		lv2:designation pg:ACN13
 	] , [
 		lv2:index 14 ;
-		lv2:designation amb:ACN14
+		lv2:designation pg:ACN14
 	] , [
 		lv2:index 15 ;
-		lv2:designation amb:ACN15
+		lv2:designation pg:ACN15
 	] .
+
diff --git a/sys/lv2/port-props/NEWS b/sys/lv2/port-props/NEWS
deleted file mode 100644
index d1ae2432..00000000
--- a/sys/lv2/port-props/NEWS
+++ /dev/null
@@ -1,12 +0,0 @@
-port-props (1.2) stable;
-
-  * Use consistent label style.
-
- -- None <None>  Sun, 14 Oct 2012 00:00:00 +0000
-
-port-props (1.0) stable;
-
-  * Initial release.
-
- -- None <None>  Tue, 17 Apr 2012 00:00:00 +0000
-
diff --git a/sys/lv2/port-props/lv2-port-props.doap.ttl b/sys/lv2/port-props/lv2-port-props.doap.ttl
deleted file mode 100644
index b199d36e..00000000
--- a/sys/lv2/port-props/lv2-port-props.doap.ttl
+++ /dev/null
@@ -1,33 +0,0 @@
-@prefix dcs: <http://ontologi.es/doap-changeset#> .
-@prefix doap: <http://usefulinc.com/ns/doap#> .
-@prefix foaf: <http://xmlns.com/foaf/0.1/> .
-@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-
-<http://lv2plug.in/ns/ext/port-props>
-	a doap:Project ;
-	doap:name "LV2 Port Properties" ;
-	doap:created "2009-01-01" ;
-	doap:shortdesc "Various port properties." ;
-	doap:maintainer <http://drobilla.net/drobilla#me> ;
-	doap:developer <http://lv2plug.in/ns/meta#kfoltman> ;
-	doap:release [
-		doap:revision "1.2" ;
-		doap:created "2012-10-14" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Use consistent label style."
-			]
-		]
-	] , [
-		doap:revision "1.0" ;
-		doap:created "2012-04-17" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Initial release."
-			]
-		]
-	] .
diff --git a/sys/lv2/port-props/manifest.ttl b/sys/lv2/port-props/manifest.ttl
index 27f15c99..45f598d7 100644
--- a/sys/lv2/port-props/manifest.ttl
+++ b/sys/lv2/port-props/manifest.ttl
@@ -1,4 +1,4 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/port-props>
@@ -6,3 +6,4 @@
 	lv2:minorVersion 1 ;
 	lv2:microVersion 2 ;
 	rdfs:seeAlso <port-props.ttl> .
+
diff --git a/sys/lv2/port-props/port-props.h b/sys/lv2/port-props/port-props.h
index ef2b64d3..eb551308 100644
--- a/sys/lv2/port-props/port-props.h
+++ b/sys/lv2/port-props/port-props.h
@@ -16,6 +16,7 @@
 
 /**
    @defgroup port-props Port Properties
+   @ingroup lv2
 
    Various port properties.
 
diff --git a/sys/lv2/port-props/port-props.meta.ttl b/sys/lv2/port-props/port-props.meta.ttl
new file mode 100644
index 00000000..7077e4b5
--- /dev/null
+++ b/sys/lv2/port-props/port-props.meta.ttl
@@ -0,0 +1,202 @@
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix pprops: <http://lv2plug.in/ns/ext/port-props#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/port-props>
+	a doap:Project ;
+	doap:name "LV2 Port Properties" ;
+	doap:created "2009-01-01" ;
+	doap:shortdesc "Various properties for LV2 plugin ports." ;
+	doap:maintainer <http://drobilla.net/drobilla#me> ;
+	doap:developer <http://lv2plug.in/ns/meta#kfoltman> ;
+	doap:release [
+		doap:revision "1.2" ;
+		doap:created "2012-10-14" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Use consistent label style."
+			]
+		]
+	] , [
+		doap:revision "1.0" ;
+		doap:created "2012-04-17" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Initial release."
+			]
+		]
+	] ;
+	lv2:documentation """
+
+This vocabulary defines various properties for plugin ports, which can be used
+to better describe how a plugin can be controlled.  Using this metadata, hosts
+can build better UIs for plugins, and provide more advanced automatic
+functionality.
+
+"""^^lv2:Markdown .
+
+pprops:trigger
+	lv2:documentation """
+
+Indicates that the data item corresponds to a momentary event that has been
+detected (control output ports) or is to be triggered (control input ports).
+For input ports, the port needs to be reset to lv2:default value after run()
+function of the plugin has returned.  If the control port is assigned a GUI
+widget by the host, the widget should be of auto-off (momentary, one-shot) type
+- for example, a push button if the port is also declared as lv2:toggled, or a
+series of push button or auto-clear input box with a "Send" button if the port
+is also lv2:integer.
+
+"""^^lv2:Markdown .
+
+pprops:supportsStrictBounds
+	lv2:documentation """
+
+Indicates use of host support for pprops:hasStrictBounds port property.  A
+plugin that specifies it as optional feature can omit value clamping for
+hasStrictBounds ports, if the feature is supported by the host.  When specified
+as required feature, it indicates that the plugin does not do any clamping for
+input ports that have a pprops:hasStrictBounds property.
+
+"""^^lv2:Markdown .
+
+pprops:hasStrictBounds
+	lv2:documentation """
+
+For hosts that support pprops:supportsStrictBounds, this indicates that the
+value of the port should never exceed the port's minimum and maximum control
+points.  For input ports, it moves the responsibility for limiting the range of
+values to host, if it supports pprops:supportsStrictBounds.  For output ports,
+it indicates that values within specified range are to be expected, and
+breaking that should be considered by the host as error in plugin
+implementation.
+
+"""^^lv2:Markdown .
+
+pprops:expensive
+	lv2:documentation """
+
+Input ports only.  Indicates that any changes to the port value may trigger
+expensive background calculation (for example, regeneration of lookup tables in
+a background thread).  Any value changes may have not have immediate effect, or
+may cause silence or diminished-quality version of the output until background
+processing is finished.  Ports having this property are typically not well
+suited for connection to outputs of other plugins, and should not be offered as
+connection targets or for automation by default.
+
+"""^^lv2:Markdown .
+
+pprops:causesArtifacts
+	lv2:documentation """
+
+Input ports only.  Indicates that any changes to the port value may produce
+slight artifacts to produced audio signals (zipper noise and other results of
+signal discontinuities).  Connecting ports of this type to continuous signals
+is not recommended, and when presenting a list of automation targets, those
+ports may be marked as artifact-producing.
+
+"""^^lv2:Markdown .
+
+pprops:continuousCV
+	lv2:documentation """
+
+Indicates that the port carries a "smooth" modulation signal.  Control input
+ports of this type are well-suited for being connected to sources of smooth
+signals (knobs with smoothing, modulation rate oscillators, output ports with
+continuousCV type, etc.).  Typically, the plugin with ports which have this
+property will implement appropriate smoothing to avoid audio artifacts.  For
+output ports, this property suggests the value of the port is likely to change
+frequently, and describes a smooth signal (so successive values may be
+considered points along a curve).
+
+"""^^lv2:Markdown .
+
+pprops:discreteCV
+	lv2:documentation """
+
+Indicates that the port carries a "discrete" modulation signal.  Input ports of
+this type are well-suited for being connected to sources of discrete signals
+(switches, buttons, classifiers, event detectors, etc.).  May be combined with
+pprops:trigger property.  For output ports, this property suggests the value of
+the port describe discrete values that should be interpreted as steps (and not
+points along a curve).
+
+"""^^lv2:Markdown .
+
+pprops:logarithmic
+	lv2:documentation """
+
+Indicates that port value behaviour within specified range (bounds) is a value
+using logarithmic scale.  The lower and upper bounds must be specified, and
+must be of the same sign.
+
+"""^^lv2:Markdown .
+
+pprops:notAutomatic
+	lv2:documentation """
+
+Indicates that the port is not primarily intended to be fed with modulation
+signals from external sources (other plugins, etc.).  It is merely a UI hint
+and hosts may allow the user to override it.
+
+"""^^lv2:Markdown .
+
+pprops:notOnGUI
+	lv2:documentation """
+
+Indicates that the port is not primarily intended to be represented by a
+separate control in the user interface window (or any similar mechanism used
+for direct, immediate control of control ports).  It is merely a UI hint and
+hosts may allow the user to override it.
+
+"""^^lv2:Markdown .
+
+pprops:displayPriority
+	lv2:documentation """
+
+Indicates how important a port is to controlling the plugin.  If a host can
+only display some ports of a plugin, it should prefer ports with a higher
+display priority.  Priorities do not need to be unique, and are only meaningful
+when compared to each other.
+
+"""^^lv2:Markdown .
+
+pprops:rangeSteps
+	lv2:documentation """
+
+This value indicates into how many evenly-divided points the (control) port
+range should be divided for step-wise control.  This may be used for changing
+the value with step-based controllers like arrow keys, mouse wheel, rotary
+encoders, and so on.
+
+Note that when used with a pprops:logarithmic port, the steps are logarithmic
+too, and port value can be calculated as:
+
+    :::c
+    value = lower * pow(upper / lower, step / (steps - 1))
+
+and the step from value is:
+
+    :::c
+    step = (steps - 1) * log(value / lower) / log(upper / lower)
+
+where:
+
+  * `value` is the port value.
+
+  * `step` is the step number (0..steps).
+
+  * `steps` is the number of steps (= value of :rangeSteps property).
+
+  * `lower` and <code>upper</code> are the bounds.
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/port-props/port-props.ttl b/sys/lv2/port-props/port-props.ttl
index f27f51e1..1ddeed07 100644
--- a/sys/lv2/port-props/port-props.ttl
+++ b/sys/lv2/port-props/port-props.ttl
@@ -1,105 +1,79 @@
-@prefix lv2:    <http://lv2plug.in/ns/lv2core#> .
-@prefix owl:    <http://www.w3.org/2002/07/owl#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
 @prefix pprops: <http://lv2plug.in/ns/ext/port-props#> .
-@prefix rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
-@prefix rdfs:   <http://www.w3.org/2000/01/rdf-schema#> .
-@prefix xsd:    <http://www.w3.org/2001/XMLSchema#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
 
 <http://lv2plug.in/ns/ext/port-props>
 	a owl:Ontology ;
-	rdfs:seeAlso <lv2-port-props.doap.ttl> ;
-	lv2:documentation """
-<p>This vocabulary defines various properties for plugin ports, which can be
-used to better describe how a plugin can be controlled.  Using this metadata,
-hosts can build better UIs for plugins, and provide more advanced automatic
-functionality.</p>""" .
+	rdfs:label "LV2 Port Properties" ;
+	rdfs:comment "Various properties for LV2 plugin ports." ;
+	rdfs:seeAlso <port-props.meta.ttl> .
 
 pprops:trigger
 	a lv2:PortProperty ;
 	rdfs:label "trigger" ;
-	rdfs:comment """Indicates that the data item corresponds to a momentary event that has been detected (control output ports) or is to be triggered (control input ports). For input ports, the port needs to be reset to lv2:default value after run() function of the plugin has returned. If the control port is assigned a GUI widget by the host, the widget should be of auto-off (momentary, one-shot) type - for example, a push button if the port is also declared as lv2:toggled, or a series of push button or auto-clear input box with a "Send" button if the port is also lv2:integer.""" .
+	rdfs:comment "Port is a momentary trigger." .
 
 pprops:supportsStrictBounds
 	a lv2:Feature ;
 	rdfs:label "supports strict bounds" ;
-	rdfs:comment """Indicates use of host support for pprops:hasStrictBounds port property.  A plugin that specifies it as optional feature can omit value clamping for hasStrictBounds ports, if the feature is supported by the host.  When specified as required feature, it indicates that the plugin does not do any clamping for input ports that have a pprops:hasStrictBounds property.""" .
+	rdfs:comment "A feature indicating plugin support for strict port bounds." .
 
 pprops:hasStrictBounds
 	a lv2:PortProperty ;
 	rdfs:label "has strict bounds" ;
-	rdfs:comment """For hosts that support pprops:supportsStrictBounds, this indicates that the value of the port should never exceed the port's minimum and maximum control points.  For input ports, it moves the responsibility for limiting the range of values to host, if it supports pprops:supportsStrictBounds.  For output ports, it indicates that values within specified range are to be expected, and breaking that should be considered by the host as error in plugin implementation.""" .
+	rdfs:comment "Port has strict bounds which are not internally clamped." .
 
 pprops:expensive
 	a lv2:PortProperty ;
 	rdfs:label "changes are expensive" ;
-	rdfs:comment """Input ports only.  Indicates that any changes to the port value may trigger expensive background calculation (e.g. regenerate some lookup tables in a background thread).  Any value changes may have not have immediate effect, or may cause silence or diminished-quality version of the output until background processing is finished.  Ports having this property are typically not well suited for connection to outputs of other plugins, and should not be offered as connection targets or for automation by default.""" .
+	rdfs:comment "Input port is expensive to change." .
 
 pprops:causesArtifacts
 	a lv2:PortProperty ;
 	rdfs:label "changes cause artifacts" ;
-	rdfs:comment """Input ports only.  Indicates that any changes to the port value may produce slight artifacts to produced audio signals (zipper noise and other results of signal discontinuities).  Connecting ports of this type to continuous signals is not recommended, and when presenting a list of automation targets, those ports may be marked as artifact-producing.""" .
+	rdfs:comment "Input port causes audible artifacts when changed." .
 
 pprops:continuousCV
 	a lv2:PortProperty ;
 	rdfs:label "smooth modulation signal" ;
-	rdfs:comment """Indicates that the port carries a "smooth" modulation signal.  Control input ports of this type are well-suited for being connected to sources of smooth signals (knobs with smoothing, modulation rate oscillators, output ports with continuousCV type, etc.).  Typically, the plugin with ports which have this property will implement appropriate smoothing to avoid audio artifacts.  For output ports, this property suggests the value of the port is likely to change frequently, and describes a smooth signal (e.g. successive values may be considered points along a curve).""" .
+	rdfs:comment "Port carries a smooth modulation signal." .
 
 pprops:discreteCV
 	a lv2:PortProperty ;
 	rdfs:label "discrete modulation signal" ;
-	rdfs:comment """Indicates that the port carries a "discrete" modulation signal.  Input ports of this type are well-suited for being connected to sources of discrete signals (switches, buttons, classifiers, event detectors, etc.).  May be combined with pprops:trigger property.  For output ports, this property suggests the value of the port describe discrete values that should be interpreted as steps (and not points along a curve).""" .
+	rdfs:comment "Port carries a discrete modulation signal." .
 
 pprops:logarithmic
 	a lv2:PortProperty ;
-	rdfs:label "logarithmic scale" ;
-	rdfs:comment """Indicates that port value behaviour within specified range (bounds) is a value using logarithmic scale.  The lower and upper bounds must be specified, and must be of the same sign.""" .
+	rdfs:label "logarithmic" ;
+	rdfs:comment "Port value is logarithmic." .
 
 pprops:notAutomatic
 	a lv2:PortProperty ;
-	rdfs:label "not intended as a CV input" ;
-	rdfs:comment """Indicates that the port is not primarily intended to be fed with modulation signals from external sources (other plugins, etc.).  It is merely a UI hint and hosts may allow the user to override it.""" .
+	rdfs:label "not automatic" ;
+	rdfs:comment "Port that is not intended to be fed with a modulation signal." .
 
 pprops:notOnGUI
 	a lv2:PortProperty ;
 	rdfs:label "not on GUI" ;
-	rdfs:comment """Indicates that the port is not primarily intended to be represented by a separate control in the user interface window (or any similar mechanism used for direct, immediate control of control ports).  It is merely a UI hint and hosts may allow the user to override it.""" .
+	rdfs:comment "Port that should not be displayed on a GUI." .
 
 pprops:displayPriority
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:DatatypeProperty ;
 	rdfs:domain lv2:Port ;
 	rdfs:range xsd:nonNegativeInteger ;
 	rdfs:label "display priority" ;
-	rdfs:comment """Indicates how important a port is to controlling the plugin.  If a host can only display some ports of a plugin, it should prefer ports with a higher display priority.  Priorities do not need to be unique, and are only meaningful when compared to each other.""" .
+	rdfs:comment "A priority ranking this port in importance to its plugin." .
 
 pprops:rangeSteps
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:DatatypeProperty ;
 	rdfs:domain lv2:Port ;
 	rdfs:range xsd:nonNegativeInteger ;
-	rdfs:label "number of value steps" ;
-	lv2:documentation """
-<p>This value indicates into how many evenly-divided points the (control) port
-range should be divided for step-wise control. This may be used for changing
-the value with step-based controllers like arrow keys, mouse wheel, rotary
-encoders, etc.</p>
+	rdfs:label "range steps" ;
+	rdfs:comment "The number of even steps the range should be divided into." .
 
-<p>Note that when used with a pprops:logarithmic port, the steps are
-logarithmic too, and port value can be calculated as:</p>
-
-<pre class="c-code">
-value = lower * pow(upper / lower, step / (steps - 1))
-</pre>
-
-<p>and the step from value is:</p>
-
-<pre class="c-code">
-step = (steps - 1) * log(value / lower) / log(upper / lower)
-</pre>
-
-<p>where:</p>
-<ul>
-<li><code>value</code> is the port value</li>
-<li><code>step</code> is the step number (0..steps)</li>
-<li><code>steps</code> is the number of steps (= value of :rangeSteps property)</li>
-<li><code>lower</code> and <code>upper</code> are the bounds</li>
-</ul>
-""" .
diff --git a/sys/lv2/presets/NEWS b/sys/lv2/presets/NEWS
deleted file mode 100644
index 859a3fad..00000000
--- a/sys/lv2/presets/NEWS
+++ /dev/null
@@ -1,29 +0,0 @@
-presets (2.8) stable;
-
-  * Use consistent label style.
-  * Add preset banks.
-
- -- None <None>  Sun, 14 Oct 2012 00:00:00 +0000
-
-presets (2.6) stable;
-
-  * Remove pset:appliesTo property, use lv2:appliesTo instead.
-  * Add pset:preset property for describing the preset currently applied to a
-    plugin instance.
-  * Merge with unified LV2 package.
-
- -- None <None>  Tue, 17 Apr 2012 00:00:00 +0000
-
-presets (2.2) stable;
-
-  * Update packaging.
-  * Improve documentation.
-
- -- None <None>  Mon, 21 Nov 2011 00:00:00 +0000
-
-presets (2.0) stable;
-
-  * Initial release.
-
- -- None <None>  Mon, 04 Oct 2010 00:00:00 +0000
-
diff --git a/sys/lv2/presets/lv2-presets.doap.ttl b/sys/lv2/presets/lv2-presets.doap.ttl
deleted file mode 100644
index 5ba88675..00000000
--- a/sys/lv2/presets/lv2-presets.doap.ttl
+++ /dev/null
@@ -1,61 +0,0 @@
-@prefix dcs: <http://ontologi.es/doap-changeset#> .
-@prefix doap: <http://usefulinc.com/ns/doap#> .
-@prefix foaf: <http://xmlns.com/foaf/0.1/> .
-@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-
-<http://lv2plug.in/ns/ext/presets>
-	a doap:Project ;
-	doap:license <http://opensource.org/licenses/isc> ;
-	doap:name "LV2 Presets" ;
-	doap:shortdesc "Presets for LV2 plugins." ;
-	doap:created "2009-00-00" ;
-	doap:developer <http://drobilla.net/drobilla#me> ;
-	doap:release [
-		doap:revision "2.8" ;
-		doap:created "2012-10-14" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Use consistent label style."
-			] , [
-				rdfs:label "Add preset banks."
-			]
-		]
-	] , [
-		doap:revision "2.6" ;
-		doap:created "2012-04-17" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Add pset:preset property for describing the preset currently applied to a plugin instance."
-			] , [
-				rdfs:label "Remove pset:appliesTo property, use lv2:appliesTo instead."
-			] , [
-				rdfs:label "Merge with unified LV2 package."
-			]
-		]
-	] , [
-		doap:revision "2.2" ;
-		doap:created "2011-11-21" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-presets-2.2.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Update packaging."
-			] , [
-				rdfs:label "Improve documentation."
-			]
-		]
-	] , [
-		doap:revision "2.0" ;
-		doap:created "2010-10-04" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-presets-2.0.tar.gz> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Initial release."
-			]
-		]
-	] .
diff --git a/sys/lv2/presets/manifest.ttl b/sys/lv2/presets/manifest.ttl
index d1fc482a..b9cacf57 100644
--- a/sys/lv2/presets/manifest.ttl
+++ b/sys/lv2/presets/manifest.ttl
@@ -1,4 +1,4 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/presets>
diff --git a/sys/lv2/presets/presets.h b/sys/lv2/presets/presets.h
index 7c51b1c6..8264a9c5 100644
--- a/sys/lv2/presets/presets.h
+++ b/sys/lv2/presets/presets.h
@@ -16,6 +16,7 @@
 
 /**
    @defgroup presets Presets
+   @ingroup lv2
 
    Presets for plugins, see <http://lv2plug.in/ns/ext/presets> for details.
 
diff --git a/sys/lv2/presets/presets.meta.ttl b/sys/lv2/presets/presets.meta.ttl
new file mode 100644
index 00000000..cc6d33ad
--- /dev/null
+++ b/sys/lv2/presets/presets.meta.ttl
@@ -0,0 +1,133 @@
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix pset: <http://lv2plug.in/ns/ext/presets#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+
+<http://lv2plug.in/ns/ext/presets>
+	a doap:Project ;
+	doap:license <http://opensource.org/licenses/isc> ;
+	doap:name "LV2 Presets" ;
+	doap:shortdesc "Presets for LV2 plugins." ;
+	doap:created "2009-00-00" ;
+	doap:developer <http://drobilla.net/drobilla#me> ;
+	doap:release [
+		doap:revision "2.8" ;
+		doap:created "2012-10-14" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Use consistent label style."
+			] , [
+				rdfs:label "Add preset banks."
+			]
+		]
+	] , [
+		doap:revision "2.6" ;
+		doap:created "2012-04-17" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add pset:preset property for describing the preset currently applied to a plugin instance."
+			] , [
+				rdfs:label "Remove pset:appliesTo property, use lv2:appliesTo instead."
+			] , [
+				rdfs:label "Merge with unified LV2 package."
+			]
+		]
+	] , [
+		doap:revision "2.2" ;
+		doap:created "2011-11-21" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-presets-2.2.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Update packaging."
+			] , [
+				rdfs:label "Improve documentation."
+			]
+		]
+	] , [
+		doap:revision "2.0" ;
+		doap:created "2010-10-04" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-presets-2.0.tar.gz> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Initial release."
+			]
+		]
+	] ;
+	lv2:documentation """
+
+This is a vocabulary for LV2 plugin presets, that is, named sets of control
+values and possibly other state.  The structure of a pset:Preset is
+deliberately identical to that of an lv2:Plugin, and can be thought of as a
+plugin template or overlay.
+
+Presets may be defined in any bundle, including the plugin's bundle, separate
+third party preset bundles, or user preset bundles saved by hosts.  Since
+preset data tends to be large, it is recommended that plugins describe presets
+in a separate file(s) to avoid slowing down hosts.  The `manifest.ttl` of a
+bundle containing presets should list them like so:
+
+    :::turtle
+    eg:mypreset
+        a             pset:Preset ;
+        lv2:appliesTo eg:myplugin ;
+        rdfs:seeAlso  &lt;mypreset.ttl&gt; .
+
+"""^^lv2:Markdown .
+
+pset:Preset
+	lv2:documentation """
+
+The structure of a Preset deliberately mirrors that of a plugin, so existing
+predicates can be used to describe any data associated with the preset.  For
+example:
+
+    :::turtle
+    @prefix eg: &lt;http://example.org/&gt; .
+
+    eg:mypreset
+        a pset:Preset ;
+        rdfs:label "One louder" ;
+        lv2:appliesTo eg:myplugin ;
+        lv2:port [
+            lv2:symbol "volume1" ;
+            pset:value 11.0
+        ] , [
+            lv2:symbol "volume2" ;
+            pset:value 11.0
+        ] .
+
+A Preset SHOULD have at least one lv2:appliesTo property.  Each Port on a
+Preset MUST have at least a lv2:symbol property and a pset:value property.
+
+Hosts SHOULD save user presets to a bundle in the user-local LV2 directory (for
+example `~/.lv2`) with a name like
+`&lt;Plugin_Name&gt;_&lt;Preset_Name&gt;.preset.lv2` (for example
+`LV2_Amp_At_Eleven.preset.lv2`), where names are transformed to be valid LV2
+symbols for maximum compatibility.
+
+"""^^lv2:Markdown .
+
+pset:value
+	lv2:documentation """
+
+This property is used in a similar way to lv2:default.
+
+"""^^lv2:Markdown .
+
+pset:preset
+	lv2:documentation """
+
+Specifies the preset currently applied to a plugin instance.  This property may
+be useful for saving state, or notifying a plugin instance at run-time about a
+preset change.
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/presets/presets.ttl b/sys/lv2/presets/presets.ttl
index a32347bc..c1caf43c 100644
--- a/sys/lv2/presets/presets.ttl
+++ b/sys/lv2/presets/presets.ttl
@@ -1,32 +1,15 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
-@prefix owl:  <http://www.w3.org/2002/07/owl#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
 @prefix pset: <http://lv2plug.in/ns/ext/presets#> .
-@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
 
 <http://lv2plug.in/ns/ext/presets>
 	a owl:Ontology ;
-	rdfs:seeAlso <lv2-presets.doap.ttl> ;
-	lv2:documentation """
-<p>This vocabulary describes a format for presets (i.e. named sets of control
-values and possibly other state) for LV2 plugins.  The structure of a
-pset:Preset is deliberately identical to that of an lv2:Plugin, and can be
-thought of as a plugin template or overlay.</p>
-
-<p>Presets may be defined in any bundle, including the plugin's bundle,
-separate third party preset bundles, or user preset bundles saved by hosts.
-Since preset data tends to be large, it is recommended that plugins describe
-presets in a separate file(s) to avoid slowing down hosts.  The manifest.ttl of
-a bundle containing presets should list the presets like so:</p>
-
-<pre class="turtle-code">
-eg:mypreset
-    a             pset:Preset ;
-    lv2:appliesTo eg:myplugin ;
-    rdfs:seeAlso  &lt;mypreset.ttl&gt; .
-</pre>
-""" .
+	rdfs:label "LV2 Presets" ;
+	rdfs:comment "Presets for LV2 plugins." ;
+	rdfs:seeAlso <presets.meta.ttl> .
 
 pset:Bank
 	a rdfs:Class ;
@@ -43,63 +26,35 @@ pset:Preset
 	a rdfs:Class ;
 	rdfs:subClassOf lv2:PluginBase ;
 	rdfs:label "Preset" ;
+	rdfs:comment "A preset for an LV2 plugin." ;
 	rdfs:subClassOf [
 		a owl:Restriction ;
 		owl:onProperty rdfs:label ;
 		owl:someValuesFrom xsd:string ;
 		rdfs:comment "A Preset MUST have at least one string rdfs:label."
-	] ;
-	lv2:documentation """
-<p>A Preset for an LV2 Plugin.  The structure of a Preset deliberately mirrors that
-of a plugin, so existing predicates can be used to describe any data associated with
-the preset.  For example:</p>
-
-<pre class="turtle-code">
-@prefix eg: &lt;http://example.org/&gt; .
-
-eg:mypreset
-    a pset:Preset ;
-    rdfs:label "One louder" ;
-    lv2:appliesTo eg:myplugin ;
-    lv2:port [
-        lv2:symbol "volume1" ;
-        pset:value 11.0
-    ] , [
-        lv2:symbol "volume2" ;
-        pset:value 11.0
-    ] .
-</pre>
-
-<p>A Preset SHOULD have at least one lv2:appliesTo property.  Each Port on a
-Preset MUST have at least a lv2:symbol property and a pset:value property.</p>
-
-<p>Hosts SHOULD save user presets to a bundle in the user-local LV2 directory
-(e.g. ~/.lv2) with a name like
-<code>&lt;Plugin_Name&gt;_&lt;Preset_Name&gt;.preset.lv2</code>
-(e.g. <code>LV2_Amp_At_Eleven.preset.lv2</code>), where names are transformed
-to be valid LV2 symbols for maximum compatibility.</p>
-""" .
+	] .
 
 pset:bank
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:ObjectProperty ;
 	rdfs:domain pset:Preset ;
 	rdfs:range pset:Bank ;
 	rdfs:label "bank" ;
 	rdfs:comment "The bank this preset belongs to." .
 
 pset:value
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:DatatypeProperty ,
+		owl:FunctionalProperty ;
 	rdfs:domain lv2:PortBase ;
 	rdfs:label "value" ;
-	rdfs:comment """Specifies the value of a Port on some Preset.  This property is used in a similar way to e.g. lv2:default.""" .
+	rdfs:comment "The value of a port in a preset." .
 
 pset:preset
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:ObjectProperty ;
 	rdfs:domain lv2:PluginBase ;
 	rdfs:range pset:Preset ;
 	rdfs:label "preset" ;
-	lv2:documentation """
-<p>Specifies the preset currently applied to a plugin instance.  This property
-may be useful for saving state, or notifying a plugin instance at run-time
-about a preset change.</p>
-""" .
+	rdfs:comment "The preset currently applied to a plugin instance." .
+
diff --git a/sys/lv2/resize-port/NEWS b/sys/lv2/resize-port/NEWS
deleted file mode 100644
index 6ebc1b5c..00000000
--- a/sys/lv2/resize-port/NEWS
+++ /dev/null
@@ -1,6 +0,0 @@
-resize-port (1.0) stable;
-
-  * Initial release.
-
- -- None <None>  Tue, 17 Apr 2012 00:00:00 +0000
-
diff --git a/sys/lv2/resize-port/lv2-resize-port.doap.ttl b/sys/lv2/resize-port/lv2-resize-port.doap.ttl
deleted file mode 100644
index 49ab3cb8..00000000
--- a/sys/lv2/resize-port/lv2-resize-port.doap.ttl
+++ /dev/null
@@ -1,22 +0,0 @@
-@prefix dcs: <http://ontologi.es/doap-changeset#> .
-@prefix doap: <http://usefulinc.com/ns/doap#> .
-@prefix foaf: <http://xmlns.com/foaf/0.1/> .
-@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-
-<http://lv2plug.in/ns/ext/resize-port>
-	a doap:Project ;
-	doap:name "LV2 Resize Port" ;
-	doap:shortdesc "Dynamically sized LV2 port buffers." ;
-	doap:created "2007-00-00" ;
-	doap:developer <http://drobilla.net/drobilla#me> ;
-	doap:release [
-		doap:revision "1.0" ;
-		doap:created "2012-04-17" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Initial release."
-			]
-		]
-	] .
diff --git a/sys/lv2/resize-port/manifest.ttl b/sys/lv2/resize-port/manifest.ttl
index 21569ae2..9fae8b85 100644
--- a/sys/lv2/resize-port/manifest.ttl
+++ b/sys/lv2/resize-port/manifest.ttl
@@ -1,4 +1,4 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/resize-port>
diff --git a/sys/lv2/resize-port/resize-port.h b/sys/lv2/resize-port/resize-port.h
index 34bfe61a..a60626d8 100644
--- a/sys/lv2/resize-port/resize-port.h
+++ b/sys/lv2/resize-port/resize-port.h
@@ -16,6 +16,7 @@
 
 /**
    @defgroup resize-port Resize Port
+   @ingroup lv2
 
    Dynamically sized LV2 port buffers.
 
@@ -32,9 +33,9 @@
 #define LV2_RESIZE_PORT_URI    "http://lv2plug.in/ns/ext/resize-port"  ///< http://lv2plug.in/ns/ext/resize-port
 #define LV2_RESIZE_PORT_PREFIX LV2_RESIZE_PORT_URI "#"                 ///< http://lv2plug.in/ns/ext/resize-port#
 
-#define LV2_RESIZE_PORT__asLargeAs   LV2_RESIZE_PORT_PREFIX "asLargeAs"    ///< http://lv2plug.in/ns/ext/port#asLargeAs
-#define LV2_RESIZE_PORT__minimumSize LV2_RESIZE_PORT_PREFIX "minimumSize"  ///< http://lv2plug.in/ns/ext/port#minimumSize
-#define LV2_RESIZE_PORT__resize      LV2_RESIZE_PORT_PREFIX "resize"       ///< http://lv2plug.in/ns/ext/port#resize
+#define LV2_RESIZE_PORT__asLargeAs   LV2_RESIZE_PORT_PREFIX "asLargeAs"    ///< http://lv2plug.in/ns/ext/resize-port#asLargeAs
+#define LV2_RESIZE_PORT__minimumSize LV2_RESIZE_PORT_PREFIX "minimumSize"  ///< http://lv2plug.in/ns/ext/resize-port#minimumSize
+#define LV2_RESIZE_PORT__resize      LV2_RESIZE_PORT_PREFIX "resize"       ///< http://lv2plug.in/ns/ext/resize-port#resize
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/sys/lv2/resize-port/resize-port.meta.ttl b/sys/lv2/resize-port/resize-port.meta.ttl
new file mode 100644
index 00000000..d44620cc
--- /dev/null
+++ b/sys/lv2/resize-port/resize-port.meta.ttl
@@ -0,0 +1,74 @@
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix rsz: <http://lv2plug.in/ns/ext/resize-port#> .
+
+<http://lv2plug.in/ns/ext/resize-port>
+	a doap:Project ;
+	doap:name "LV2 Resize Port" ;
+	doap:shortdesc "Dynamically sized LV2 port buffers." ;
+	doap:created "2007-00-00" ;
+	doap:developer <http://drobilla.net/drobilla#me> ;
+	doap:release [
+		doap:revision "1.0" ;
+		doap:created "2012-04-17" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Initial release."
+			]
+		]
+	] ;
+	lv2:documentation """
+
+This extension defines a feature, rsz:resize, which allows plugins to
+dynamically resize their output port buffers.
+
+In addition to the dynamic feature, there are properties which describe the
+space required for a particular port buffer which can be used statically in
+data files.
+
+"""^^lv2:Markdown .
+
+rsz:resize
+	lv2:documentation """
+
+A feature to resize output port buffers in LV2_Plugin_Descriptor::run().
+
+To support this feature, the host must pass an LV2_Feature to the plugin's
+instantiate method with URI LV2_RESIZE_PORT__resize and a pointer to a
+LV2_Resize_Port_Resize structure.  This structure provides a resize_port
+function which plugins may use to resize output port buffers as necessary.
+
+"""^^lv2:Markdown .
+
+rsz:asLargeAs
+	lv2:documentation """
+
+Indicates that a port requires at least as much buffer space as the port with
+the given symbol on the same plugin instance.  This may be used for any ports,
+but is generally most useful to indicate an output port must be at least as
+large as some input port (because it will copy from it).  If a port is
+asLargeAs several ports, it is asLargeAs the largest such port (not the sum of
+those ports' sizes).
+
+The host guarantees that whenever an ObjectPort's run method is called, any
+output `O` that is rsz:asLargeAs an input `I` is connected to a buffer large
+enough to copy `I`, or `NULL` if the port is lv2:connectionOptional.
+
+"""^^lv2:Markdown .
+
+rsz:minimumSize
+	lv2:documentation """
+
+Indicates that a port requires a buffer at least this large, in bytes.  Any
+host that supports the resize-port feature MUST connect any port with a
+minimumSize specified to a buffer at least as large as the value given for this
+property.  Any host, especially those that do NOT support dynamic port
+resizing, SHOULD do so or reduced functionality may result.
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/resize-port/resize-port.ttl b/sys/lv2/resize-port/resize-port.ttl
index 6688f900..29cd18b3 100644
--- a/sys/lv2/resize-port/resize-port.ttl
+++ b/sys/lv2/resize-port/resize-port.ttl
@@ -1,33 +1,21 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
-@prefix owl:  <http://www.w3.org/2002/07/owl#> .
-@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-@prefix rsz:  <http://lv2plug.in/ns/ext/resize-port#> .
-@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> .
+@prefix rsz: <http://lv2plug.in/ns/ext/resize-port#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
 
 <http://lv2plug.in/ns/ext/resize-port>
-	a lv2:Specification ;
+	a owl:Ontology ;
+	rdfs:label "LV2 Resize Port" ;
+	rdfs:comment "Dynamically sized LV2 port buffers." ;
 	rdfs:seeAlso <resize-port.h> ,
-		<lv2-resize-port.doap.ttl> ;
-	lv2:documentation """
-<p>This extension defines a feature, rsz:resize, which allows plugins to
-dynamically resize their output port buffers.</p>
-
-<p>In addition to the dynamic feature, there are properties which describe the
-space required for a particular port buffer which can be used statically in
-data files.</p>
-""" .
+		<resize-port.meta.ttl> .
 
 rsz:resize
 	a lv2:Feature ;
-	lv2:documentation """
-<p>A feature to resize output port buffers in LV2_Plugin_Descriptor::run().</p>
-
-<p>To support this feature, the host must pass an LV2_Feature to the plugin's
-instantiate method with URI LV2_RESIZE_PORT__resize and a pointer to a
-LV2_Resize_Port_Resize structure.  This structure provides a resize_port
-function which plugins may use to resize output port buffers as necessary.</p>
-""" .
+	rdfs:label "resize" ;
+	rdfs:comment "A feature for resizing output port buffers." .
 
 rsz:asLargeAs
 	a rdf:Property ,
@@ -35,18 +23,7 @@ rsz:asLargeAs
 	rdfs:domain lv2:Port ;
 	rdfs:range lv2:Symbol ;
 	rdfs:label "as large as" ;
-	lv2:documentation """
-<p>Indicates that a port requires at least as much buffer space as the port
-with the given symbol on the same plugin instance.  This may be used for any
-ports, but is generally most useful to indicate an output port must be at least
-as large as some input port (because it will copy from it).  If a port is
-asLargeAs several ports, it is asLargeAs the largest such port (not the sum of
-those ports' sizes).</p>
-
-<p>The host guarantees that whenever an ObjectPort's run method is called, any
-output O that is obj:asLargeAs an input I is connected to a buffer large enough
-to copy I, or NULL if the port is lv2:connectionOptional.</p>
-""" .
+	rdfs:comment "Port that this port must have at least as much buffer space as." .
 
 rsz:minimumSize
 	a rdf:Property ,
@@ -55,10 +32,5 @@ rsz:minimumSize
 	rdfs:domain lv2:Port ;
 	rdfs:range xsd:nonNegativeInteger ;
 	rdfs:label "minimum size" ;
-	rdfs:comment """
-Indicates that a port requires a buffer at least this large, in bytes.  Any
-host that supports the resize-port feature MUST connect any port with a
-minimumSize specified to a buffer at least as large as the value given for this
-property.  Any host, especially those that do NOT support dynamic port
-resizing, SHOULD do so or reduced functionality may result.
-""" .
+	rdfs:comment "Minimum buffer size required by a port, in bytes." .
+
diff --git a/sys/lv2/state/NEWS b/sys/lv2/state/NEWS
deleted file mode 100644
index 4e50b3f5..00000000
--- a/sys/lv2/state/NEWS
+++ /dev/null
@@ -1,32 +0,0 @@
-state (2.4) stable;
-
-  * Add state:StateChanged for notification events.
-
- -- None <None>  Sun, 03 Feb 2019 00:00:00 +0000
-
-state (2.2) stable;
-
-  * Add state:threadSafeRestore feature for dropout-free state restoration.
-  * Add LV2_STATE_ERR_NO_SPACE status flag.
-
- -- None <None>  Sun, 31 Jul 2016 00:00:00 +0000
-
-state (2.0) stable;
-
-  * Add state:loadDefaultState feature so plugins can have their default state
-    loaded without hard-coding default state as a special case.
-
- -- None <None>  Wed, 16 Jan 2013 00:00:00 +0000
-
-state (1.2) stable;
-
-  * Use consistent label style.
-
- -- None <None>  Sun, 14 Oct 2012 00:00:00 +0000
-
-state (1.0) stable;
-
-  * Initial release.
-
- -- None <None>  Tue, 17 Apr 2012 00:00:00 +0000
-
diff --git a/sys/lv2/state/lv2-state.doap.ttl b/sys/lv2/state/lv2-state.doap.ttl
deleted file mode 100644
index 4ad60899..00000000
--- a/sys/lv2/state/lv2-state.doap.ttl
+++ /dev/null
@@ -1,67 +0,0 @@
-@prefix dcs: <http://ontologi.es/doap-changeset#> .
-@prefix doap: <http://usefulinc.com/ns/doap#> .
-@prefix foaf: <http://xmlns.com/foaf/0.1/> .
-@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-
-<http://lv2plug.in/ns/ext/state>
-	a doap:Project ;
-	doap:created "2010-11-09" ;
-	doap:name "LV2 State" ;
-	doap:shortdesc "An interface for LV2 plugins to save and restore state." ;
-	doap:license <http://opensource.org/licenses/isc> ;
-	doap:developer <http://lv2plug.in/ns/meta#paniq> ,
-		<http://drobilla.net/drobilla#me> ;
-	doap:maintainer <http://drobilla.net/drobilla#me> ;
-	doap:release [
-		doap:revision "2.4" ;
-		doap:created "2019-02-03" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.16.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Add state:StateChanged for notification events."
-			]
-		]
-	] , [
-		doap:revision "2.2" ;
-		doap:created "2016-07-31" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.14.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Add LV2_STATE_ERR_NO_SPACE status flag."
-			] , [
-				rdfs:label "Add state:threadSafeRestore feature for dropout-free state restoration."
-			]
-		]
-	] , [
-		doap:revision "2.0" ;
-		doap:created "2013-01-16" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.4.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Add state:loadDefaultState feature so plugins can have their default state loaded without hard-coding default state as a special case."
-			]
-		]
-	] , [
-		doap:revision "1.2" ;
-		doap:created "2012-10-14" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Use consistent label style."
-			]
-		]
-	] , [
-		doap:revision "1.0" ;
-		doap:created "2012-04-17" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Initial release."
-			]
-		]
-	] .
diff --git a/sys/lv2/state/manifest.ttl b/sys/lv2/state/manifest.ttl
index e2d4d30b..6d123580 100644
--- a/sys/lv2/state/manifest.ttl
+++ b/sys/lv2/state/manifest.ttl
@@ -1,8 +1,9 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/state>
 	a lv2:Specification ;
 	lv2:minorVersion 2 ;
-	lv2:microVersion 4 ;
+	lv2:microVersion 6 ;
 	rdfs:seeAlso <state.ttl> .
+
diff --git a/sys/lv2/state/state.h b/sys/lv2/state/state.h
index 1005d501..2823989a 100644
--- a/sys/lv2/state/state.h
+++ b/sys/lv2/state/state.h
@@ -17,6 +17,7 @@
 
 /**
    @defgroup state State
+   @ingroup lv2
 
    An interface for LV2 plugins to save and restore state, see
    <http://lv2plug.in/ns/ext/state> for details.
@@ -39,6 +40,7 @@
 #define LV2_STATE__State             LV2_STATE_PREFIX "State"              ///< http://lv2plug.in/ns/ext/state#State
 #define LV2_STATE__interface         LV2_STATE_PREFIX "interface"          ///< http://lv2plug.in/ns/ext/state#interface
 #define LV2_STATE__loadDefaultState  LV2_STATE_PREFIX "loadDefaultState"   ///< http://lv2plug.in/ns/ext/state#loadDefaultState
+#define LV2_STATE__freePath          LV2_STATE_PREFIX "freePath"           ///< http://lv2plug.in/ns/ext/state#freePath
 #define LV2_STATE__makePath          LV2_STATE_PREFIX "makePath"           ///< http://lv2plug.in/ns/ext/state#makePath
 #define LV2_STATE__mapPath           LV2_STATE_PREFIX "mapPath"            ///< http://lv2plug.in/ns/ext/state#mapPath
 #define LV2_STATE__state             LV2_STATE_PREFIX "state"              ///< http://lv2plug.in/ns/ext/state#state
@@ -50,6 +52,7 @@ extern "C" {
 #endif
 
 typedef void* LV2_State_Handle;            ///< Opaque handle for state save/restore
+typedef void* LV2_State_Free_Path_Handle;  ///< Opaque handle for state:freePath feature
 typedef void* LV2_State_Map_Path_Handle;   ///< Opaque handle for state:mapPath feature
 typedef void* LV2_State_Make_Path_Handle;  ///< Opaque handle for state:makePath feature
 
@@ -66,8 +69,8 @@ typedef enum {
 	   Values with this flag contain no pointers or references to other areas
 	   of memory.  It is safe to copy POD values with a simple memcpy and store
 	   them for the duration of the process.  A POD value is not necessarily
-	   safe to trasmit between processes or machines (e.g. filenames are POD),
-	   see LV2_STATE_IS_PORTABLE for details.
+	   safe to trasmit between processes or machines (for example, filenames
+	   are POD), see LV2_STATE_IS_PORTABLE for details.
 
 	   Implementations MUST NOT attempt to copy or serialise a non-POD value if
 	   they do not understand its type (and thus know how to correctly do so).
@@ -89,9 +92,9 @@ typedef enum {
 	   Native data.
 
 	   This flag is used by the host to indicate that the saved data is only
-	   going to be used locally in the currently running process (e.g. for
-	   instance duplication or snapshots), so the plugin should use the most
-	   efficient representation possible and not worry about serialisation
+	   going to be used locally in the currently running process (for things
+	   like instance duplication or snapshots), so the plugin should use the
+	   most efficient representation possible and not worry about serialisation
 	   and portability.
 	*/
 	LV2_STATE_IS_NATIVE = 1 << 2
@@ -125,7 +128,7 @@ typedef enum {
    DO NOT INVENT NONSENSE URI SCHEMES FOR THE KEY.  Best is to use keys from
    existing vocabularies.  If nothing appropriate is available, use http URIs
    that point to somewhere you can host documents so documentation can be made
-   resolvable (e.g. a child of the plugin or project URI).  If this is not
+   resolvable (typically a child of the plugin or project URI).  If this is not
    possible, invent a URN scheme, e.g. urn:myproj:whatever.  The plugin MUST
    NOT pass an invalid URI key.
 
@@ -192,7 +195,7 @@ typedef const void* (*LV2_State_Retrieve_Function)(
    authors should consider this possibility, and always store sensible data
    with meaningful types to avoid such problems in the future.
 */
-typedef struct _LV2_State_Interface {
+typedef struct {
 	/**
 	   Save plugin state using a host-provided `store` callback.
 
@@ -216,10 +219,10 @@ typedef struct _LV2_State_Interface {
 	   This function has its own special threading class: it may not be called
 	   concurrently with any "Instantiation" function, but it may be called
 	   concurrently with functions in any other class, unless the definition of
-	   that class prohibits it (e.g. it may not be called concurrently with a
-	   "Discovery" function, but it may be called concurrently with an "Audio"
-	   function.  The plugin is responsible for any locking or lock-free
-	   techniques necessary to make this possible.
+	   that class prohibits it (for example, it may not be called concurrently
+	   with a "Discovery" function, but it may be called concurrently with an
+	   "Audio" function.  The plugin is responsible for any locking or
+	   lock-free techniques necessary to make this possible.
 
 	   Note that in the simple case where state is only modified by restore(),
 	   there are no synchronization issues since save() is never called
@@ -292,8 +295,8 @@ typedef struct {
 	   not necessarily the same original path) using absolute_path().
 
 	   This function may only be called within the context of
-	   LV2_State_Interface methods.  The caller is responsible for freeing the
-	   returned value with free().
+	   LV2_State_Interface methods.  The caller must free the returned value
+	   with LV2_State_Free_Path.free_path().
 	*/
 	char* (*abstract_path)(LV2_State_Map_Path_Handle handle,
 	                       const char*               absolute_path);
@@ -301,15 +304,15 @@ typedef struct {
 	/**
 	   Map an abstract path from plugin state to an absolute path.
 	   @param handle MUST be the `handle` member of this struct.
-	   @param abstract_path An abstract path (e.g. a path from plugin state).
+	   @param abstract_path An abstract path (typically from plugin state).
 	   @return An absolute file system path.
 
 	   The plugin MUST use this function in order to actually open or otherwise
 	   use any paths loaded from plugin state.
 
 	   This function may only be called within the context of
-	   LV2_State_Interface methods.  The caller is responsible for freeing the
-	   returned value with free().
+	   LV2_State_Interface methods.  The caller must free the returned value
+	   with LV2_State_Free_Path.free_path().
 	*/
 	char* (*absolute_path)(LV2_State_Map_Path_Handle handle,
 	                       const char*               abstract_path);
@@ -337,20 +340,44 @@ typedef struct {
 	   LV2_Descriptor.instantiate()).
 
 	   The host MUST do whatever is necessary for the plugin to be able to
-	   create a file at the returned path (e.g. using fopen), including
-	   creating any leading directories.
+	   create a file at the returned path (for example, using fopen()),
+	   including creating any leading directories.
 
 	   If this function is passed to LV2_Descriptor.instantiate(), it may be
 	   called from any non-realtime context.  If it is passed to
 	   LV2_State_Interface.save(), it may only be called within the dynamic
 	   scope of that function call.
 
-	   The caller is responsible for freeing the returned value with free().
+	   The caller must free the returned value with
+	   LV2_State_Free_Path.free_path().
 	*/
 	char* (*path)(LV2_State_Make_Path_Handle handle,
 	              const char*                path);
 } LV2_State_Make_Path;
 
+/**
+   Feature data for state:freePath (@ref LV2_STATE__freePath).
+*/
+typedef struct {
+	/**
+	   Opaque host data.
+	*/
+	LV2_State_Free_Path_Handle handle;
+
+	/**
+	   Free a path returned by a state feature.
+
+	   @param handle MUST be the `handle` member of this struct.
+	   @param path The path previously returned by a state feature.
+
+	   This function can be used by plugins to free paths allocated by the host
+	   and returned by state features (LV2_State_Map_Path.abstract_path(),
+	   LV2_State_Map_Path.absolute_path(), and LV2_State_Make_Path.path()).
+	*/
+	void (*free_path)(LV2_State_Free_Path_Handle handle,
+	                  char*                      path);
+} LV2_State_Free_Path;
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
diff --git a/sys/lv2/state/state.meta.ttl b/sys/lv2/state/state.meta.ttl
new file mode 100644
index 00000000..766ac570
--- /dev/null
+++ b/sys/lv2/state/state.meta.ttl
@@ -0,0 +1,457 @@
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix state: <http://lv2plug.in/ns/ext/state#> .
+
+<http://lv2plug.in/ns/ext/state>
+	a doap:Project ;
+	doap:created "2010-11-09" ;
+	doap:name "LV2 State" ;
+	doap:shortdesc "An interface for LV2 plugins to save and restore state." ;
+	doap:license <http://opensource.org/licenses/isc> ;
+	doap:developer <http://lv2plug.in/ns/meta#paniq> ,
+		<http://drobilla.net/drobilla#me> ;
+	doap:maintainer <http://drobilla.net/drobilla#me> ;
+	doap:release [
+		doap:revision "2.6" ;
+		doap:created "2020-04-26" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.18.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add state:freePath feature."
+			]
+		]
+	] , [
+		doap:revision "2.4" ;
+		doap:created "2019-02-03" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.16.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add state:StateChanged for notification events."
+			]
+		]
+	] , [
+		doap:revision "2.2" ;
+		doap:created "2016-07-31" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.14.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add LV2_STATE_ERR_NO_SPACE status flag."
+			] , [
+				rdfs:label "Add state:threadSafeRestore feature for dropout-free state restoration."
+			]
+		]
+	] , [
+		doap:revision "2.0" ;
+		doap:created "2013-01-16" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.4.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add state:loadDefaultState feature so plugins can have their default state loaded without hard-coding default state as a special case."
+			]
+		]
+	] , [
+		doap:revision "1.2" ;
+		doap:created "2012-10-14" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Use consistent label style."
+			]
+		]
+	] , [
+		doap:revision "1.0" ;
+		doap:created "2012-04-17" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Initial release."
+			]
+		]
+	] ;
+	lv2:documentation """
+
+This extension defines a simple mechanism that allows hosts to save and restore
+a plugin instance's state.  The goal is for an instance's state to be
+completely described by port values and a simple dictionary.
+
+The <q>state</q> defined here is conceptually a key:value dictionary, with URI keys
+and values of any type. For performance reasons the key and value type are
+actually a "URID", a URI mapped to an integer. A single key:value pair is
+called a "property".
+
+This state model is simple yet has many benefits:
+
+  * Both fast and extensible thanks to URID keys.
+
+  * No limitations on possible value types.
+
+  * Easy to serialise in almost any format.
+
+  * Easy to store in a typical "map" or "dictionary" data structure.
+
+  * Elegantly described in Turtle, so state can be described in LV2 data files
+    (including presets).
+
+  * Does not impose any file formats, data structures, or file system
+    requirements.
+
+  * Suitable for portable persistent state as well as fast in-memory snapshots.
+
+  * Keys _may_ be well-defined and used meaningfully across several
+    implementations.
+
+  * State _may_ be dynamic, but plugins are not required to have a dynamic
+    dictionary data structure available.
+
+To implement state, the plugin provides a state:interface to the host. To save
+or restore, the host calls LV2_State_Interface::save() or
+LV2_State_Interface::restore(), passing a callback to be used for handling a
+single property. The host is free to implement property storage and retrieval
+in any way.
+
+Since value types are defined by URI, any type is possible. However, a set of
+standard types is defined by the [LV2 Atom](atom.html) extension. Use of these
+types is recommended. Hosts MUST implement at least
+[atom:String](atom.html#String), which is simply a C string.
+
+### Referring to Files
+
+Plugins may need to refer to existing files (such as loaded samples) in their
+state. This is done by storing the file's path as a property just like any
+other value. However, there are some rules which MUST be followed when storing
+paths, see state:mapPath for details. Plugins MUST use the type
+[atom:Path](atom.html#Path) for all paths in their state.
+
+Plugins are strongly encouraged to avoid creating files, instead storing all
+state as properties. However, occasionally the ability to create files is
+necessary. To make this possible, the host can provide the feature
+state:makePath which allocates paths for plugin-created files. Plugins MUST
+NOT create files in any other locations.
+
+### Plugin Code Example
+
+    :::c
+
+    /* Namespace for this plugin's keys.  This SHOULD be something that could be
+       published as a document, even if that document does not exist right now.
+    */
+    #define NS_MY "http://example.org/myplugin/schema#"
+
+    #define DEFAULT_GREETING "Hello"
+
+    LV2_Handle
+    my_instantiate(...)
+    {
+        MyPlugin* plugin = ...;
+        plugin->uris.atom_String = map_uri(LV2_ATOM__String);
+        plugin->uris.my_greeting = map_uri(NS_MY "greeting");
+        plugin->state.greeting   = strdup(DEFAULT_GREETING);
+        return plugin;
+    }
+
+    LV2_State_Status
+    my_save(LV2_Handle                 instance,
+            LV2_State_Store_Function   store,
+            LV2_State_Handle           handle,
+            uint32_t                   flags,
+            const LV2_Feature *const * features)
+    {
+        MyPlugin*   plugin   = (MyPlugin*)instance;
+        const char* greeting = plugin->state.greeting;
+
+        store(handle,
+              plugin->uris.my_greeting,
+              greeting,
+              strlen(greeting) + 1,  // Careful!  Need space for terminator
+              plugin->uris.atom_String,
+              LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
+
+        return LV2_STATE_SUCCESS;
+    }
+
+    LV2_State_Status
+    my_restore(LV2_Handle                  instance,
+               LV2_State_Retrieve_Function retrieve,
+               LV2_State_Handle            handle,
+               uint32_t                    flags,
+               const LV2_Feature *const *  features)
+    {
+        MyPlugin* plugin = (MyPlugin*)instance;
+
+        size_t      size;
+        uint32_t    type;
+        uint32_t    flags;
+        const char* greeting = retrieve(
+            handle, plugin->uris.my_greeting, &size, &type, &flags);
+
+        if (greeting) {
+            free(plugin->state->greeting);
+            plugin->state->greeting = strdup(greeting);
+        } else {
+            plugin->state->greeting = strdup(DEFAULT_GREETING);
+        }
+
+        return LV2_STATE_SUCCESS;
+    }
+
+    const void*
+    my_extension_data(const char* uri)
+    {
+        static const LV2_State_Interface state_iface = { my_save, my_restore };
+        if (!strcmp(uri, LV2_STATE__interface)) {
+            return &state_iface;
+        }
+    }
+
+### Host Code Example
+
+    :::c
+    LV2_State_Status
+    store_callback(LV2_State_Handle handle,
+                   uint32_t         key,
+                   const void*      value,
+                   size_t           size,
+                   uint32_t         type,
+                   uint32_t         flags)
+    {
+        if ((flags & LV2_STATE_IS_POD)) {
+            // We only care about POD since we're keeping state in memory only.
+            // Disk or network use would also require LV2_STATE_IS_PORTABLE.
+            Map* state_map = (Map*)handle;
+            state_map->insert(key, Value(copy(value), size, type));
+            return LV2_STATE_SUCCESS;;
+        } else {
+            return LV2_STATE_ERR_BAD_FLAGS; // Non-POD events are unsupported
+        }
+    }
+
+    Map
+    get_plugin_state(LV2_Handle instance)
+    {
+        LV2_State* state = instance.extension_data(LV2_STATE__interface);
+
+        // Request a fast/native/POD save, since we're just copying in memory
+        Map state_map;
+        state.save(instance, store_callback, &state_map,
+                   LV2_STATE_IS_POD|LV2_STATE_IS_NATIVE);
+
+        return state_map;
+    }
+
+### Extensions to this Specification
+
+It is likely that other interfaces for working with plugin state will be
+developed as needed. This is encouraged, however everything SHOULD work within
+the state _model_ defined here. That is, **do not complicate the state
+model**. Implementations can assume the following:
+
+  * The current port values and state dictionary completely describe a plugin
+    instance, at least well enough that saving and restoring will yield an
+    "identical" instance from the user's perspective.
+
+  * Hosts are not expected to save and/or restore any other attributes of a
+    plugin instance.
+
+### The "Property Principle"
+
+The main benefit of this meaningful state model is that it can double as a
+plugin control/query mechanism. For plugins that require more advanced control
+than simple control ports, instead of defining a set of commands, define
+properties whose values can be set appropriately. This provides both a way to
+control and save that state "for free", since there is no need to define
+commands _and_ a set of properties for storing their effects. In particular,
+this is a good way for UIs to achieve more advanced control of plugins.
+
+This "property principle" is summed up in the phrase: "Don't stop; set playing
+to false".
+
+This extension does not define a dynamic mechanism for state access and
+manipulation. The [LV2 Patch](patch.html) extension defines a generic set of
+messages which can be used to access or manipulate properties, and the [LV2
+Atom](atom.html) extension defines a port type and data container capable of
+transmitting those messages.
+
+"""^^lv2:Markdown .
+
+state:interface
+	lv2:documentation """
+
+A structure (LV2_State_Interface) which contains functions to be called by the
+host to save and restore state.  In order to support this extension, the plugin
+must return a valid LV2_State_Interface from LV2_Descriptor::extension_data()
+when it is called with URI LV2_STATE__interface.
+
+The plugin data file should describe this like so:
+
+    :::turtle
+    @prefix state: &lt;http://lv2plug.in/ns/ext/state#&gt; .
+
+    &lt;plugin&gt;
+        a lv2:Plugin ;
+        lv2:extensionData state:interface .
+
+"""^^lv2:Markdown .
+
+state:State
+	lv2:documentation """
+
+This type should be used wherever instance state is described.  The properties
+of a resource with this type correspond directly to the properties of the state
+dictionary (except the property that states it has this type).
+
+"""^^lv2:Markdown .
+
+state:loadDefaultState
+	lv2:documentation """
+
+This feature indicates that the plugin has default state listed with the
+state:state property which should be loaded by the host before running the
+plugin.  Requiring this feature allows plugins to implement a single state
+loading mechanism which works for initialisation as well as restoration,
+without having to hard-code default state.
+
+To support this feature, the host MUST restore the default state after
+instantiating the plugin but before calling run().
+
+"""^^lv2:Markdown .
+
+state:state
+	lv2:documentation """
+
+This property may be used anywhere a state needs to be described, for example:
+
+    :::turtle
+    @prefix eg: &lt;http://example.org/&gt; .
+
+    &lt;plugin-instance&gt;
+        state:state [
+            eg:somekey "some value" ;
+            eg:someotherkey "some other value" ;
+            eg:favourite-number 2
+        ] .
+
+"""^^lv2:Markdown .
+
+state:mapPath
+	lv2:documentation """
+
+This feature maps absolute paths to/from <q>abstract paths</q> which are stored
+in state.  To support this feature a host must pass an LV2_Feature with URI
+LV2_STATE__mapPath and data pointed to an LV2_State_Map_Path to the plugin's
+LV2_State_Interface methods.
+
+The plugin MUST map _all_ paths stored in its state (including those inside any
+files).  This is necessary so that hosts can handle file system references
+correctly, for example to share common files, or bundle state for distribution
+or archival.
+
+For example, a plugin may write a path to a state file like so:
+
+    :::c
+    void write_path(LV2_State_Map_Path* map_path, FILE* myfile, const char* path)
+    {
+        char* abstract_path = map_path->abstract_path(map_path->handle, path);
+        fprintf(myfile, "%s", abstract_path);
+        free(abstract_path);
+    }
+
+Then, later reload the path like so:
+
+    :::c
+    char* read_path(LV2_State_Map_Path* map_path, FILE* myfile)
+    {
+        /* Obviously this is not production quality code! */
+        char abstract_path[1024];
+        fscanf(myfile, "%s", abstract_path);
+        return map_path->absolute_path(map_path->handle, abstract_path);
+    }
+
+"""^^lv2:Markdown .
+
+state:makePath
+	lv2:documentation """
+
+This feature allows plugins to create new files and/or directories.  To support
+this feature the host passes an LV2_Feature with URI LV2_STATE__makePath and
+data pointed to an LV2_State_Make_Path to the plugin.  The host may make this
+feature available only during save by passing it to
+LV2_State_Interface::save(), or available any time by passing it to
+LV2_Descriptor::instantiate().  If passed to LV2_State_Interface::save(), the
+feature MUST NOT be used beyond the scope of that call.
+
+The plugin is guaranteed a hierarchical namespace unique to that plugin
+instance, and may expect the returned path to have the requested path as a
+suffix.  There is one such namespace, even if the feature is passed to both
+LV2_Descriptor::instantiate() and LV2_State_Interface::save().  Beyond this,
+the plugin MUST NOT make any assumptions about the returned paths.
+
+Like any other paths, the plugin MUST map these paths using state:mapPath
+before storing them in state.  The plugin MUST NOT assume these paths will be
+available across a save/restore otherwise, that is, only mapped paths saved to
+state are persistent, any other created paths are temporary.
+
+For example, a plugin may create a file in a subdirectory like so:
+
+    :::c
+    char* save_myfile(LV2_State_Make_Path* make_path)
+    {
+        char* path   = make_path->path(make_path->handle, "foo/bar/myfile.txt");
+        FILE* myfile = fopen(path, 'w');
+        fprintf(myfile, "I am some data");
+        fclose(myfile);
+        return path;
+    }
+
+"""^^lv2:Markdown .
+
+state:threadSafeRestore
+	lv2:documentation """
+
+If a plugin supports this feature, its LV2_State_Interface::restore method is
+thread-safe and may be called concurrently with audio class functions.
+
+To support this feature, the host MUST pass a
+[work:schedule](worker.html#schedule) feature to the restore method, which will
+be used to complete the state restoration.  The usual mechanics of the worker
+apply: the host will call the plugin's work method, which emits a response
+which is later applied in the audio thread.
+
+The host is not required to block audio processing while restore() and work()
+load the state, so this feature allows state to be restored without dropouts.
+
+"""^^lv2:Markdown .
+
+state:freePath
+	lv2:documentation """
+
+This feature provides a function that can be used by plugins to free paths that
+were allocated by the host via other state features (state:mapPath and
+state:makePath).
+
+"""^^lv2:Markdown .
+
+state:Changed
+	lv2:documentation """
+
+A notification that the internal state of the plugin has been changed in a way
+that the host can not otherwise know about.
+
+This is a one-way notification, intended to be used as the type of an
+[Object](atom.html#Object) sent from plugins when necessary.
+
+Plugins SHOULD emit such an event whenever a change has occurred that would
+result in a different state being saved, but not when the host explicity makes
+a change which it knows is likely to have that effect, such as changing a
+parameter.
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/state/state.ttl b/sys/lv2/state/state.ttl
index c86fea76..704b312c 100644
--- a/sys/lv2/state/state.ttl
+++ b/sys/lv2/state/state.ttl
@@ -1,382 +1,60 @@
-@prefix lv2:   <http://lv2plug.in/ns/lv2core#> .
-@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
-@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 @prefix state: <http://lv2plug.in/ns/ext/state#> .
 
 <http://lv2plug.in/ns/ext/state>
-	a lv2:Specification ;
+	a owl:Ontology ;
+	rdfs:label "LV2 State" ;
+	rdfs:comment "An interface for LV2 plugins to save and restore state." ;
 	rdfs:seeAlso <state.h> ,
-		<lv2-state.doap.ttl> ;
-	lv2:documentation """
-<p>This extension defines a simple mechanism which allows hosts to save and
-restore a plugin instance's state.  The goal is for an instance's state to be
-<em>completely</em> described by port values (as with all LV2 plugins) and a
-simple dictionary.</p>
-
-<p>The <q>state</q> defined here is conceptually a key:value dictionary, with
-URI keys and values of any type.  For performance reasons the key and value
-type are actually a <q>URID</q>, a URI mapped to an integer.  A single
-key:value pair is called a <q>property</q>.</p>
-
-<p>This state model is simple yet has many benefits:</p>
-<ul>
-  <li>Both fast and extensible thanks to URID keys.</li>
-  <li>No limitations on possible value types.</li>
-  <li>Easy to serialise in almost any format.</li>
-  <li>Easy to store in a typical <q>map</q> or <q>dictionary</q> data
-  structure.</li>
-  <li>Elegantly described in Turtle, so state can be described in LV2 data
-  files (including presets).</li>
-  <li>Does not impose any file formats, data structures, or file system
-  requirements.</li>
-  <li>Suitable for portable persistent state as well as fast in-memory
-  snapshots.</li>
-  <li>Keys <em>may</em> be well-defined and used meaningfully across several
-  implementations.</li>
-  <li>State <em>may</em> be dynamic, but plugins are not required to have a
-  dynamic dictionary data structure available.</li>
-</ul>
-
-<p>To implement state, the plugin provides a state:interface to the host.  To
-save or restore, the host calls LV2_State_Interface::save() or
-LV2_State_Interface::restore(), passing a callback to be used for handling a
-single property.  The host is free to implement property storage and retrieval
-in any way.</p>
-
-<p>Since value types are defined by URI, any type is possible.  However, a set
-of standard types is defined by the <a href="../atom/atom.html">LV2 Atom</a>
-extension.  Use of these types is recommended.  Hosts MUST implement at least
-<a href="../atom/atom.html#String">atom:String</a>, which is simply a C
-string.</p>
-
-<h3>Referring to Files</h3>
-
-<p>Plugins may need to refer to existing files (e.g. loaded samples) in their
-state.  This is done by storing the file's path as a property just like any
-other value.  However, there are some rules which MUST be followed when storing
-paths, see state:mapPath for details.  Plugins MUST use the type <a
-href="../atom/atom.html#Path">atom:Path</a> for all paths in their state.</p>
-
-<p>Plugins are strongly encouraged to avoid creating files, instead storing all
-state as properties.  However, occasionally the ability to create files is
-necessary.  To make this possible, the host can provide the feature
-state:makePath which allocates paths for plugin-created files.  Plugins MUST
-NOT create files in any other locations.</p>
-
-<h3>Plugin Code Example</h3>
-
-<pre class="c-code">
-
-/* Namespace for this plugin's keys.  This SHOULD be something that could be
-   published as a document, even if that document does not exist right now.
-*/
-#define NS_MY "http://example.org/myplugin/schema#"
-
-#define DEFAULT_GREETING "Hello"
-
-LV2_Handle
-my_instantiate(...)
-{
-    MyPlugin* plugin = ...;
-    plugin->uris.atom_String = map_uri(LV2_ATOM__String);
-    plugin->uris.my_greeting = map_uri(NS_MY "greeting");
-    plugin->state.greeting   = strdup(DEFAULT_GREETING);
-    return plugin;
-}
-
-LV2_State_Status
-my_save(LV2_Handle                 instance,
-        LV2_State_Store_Function   store,
-        LV2_State_Handle           handle,
-        uint32_t                   flags,
-        const LV2_Feature *const * features)
-{
-    MyPlugin*   plugin   = (MyPlugin*)instance;
-    const char* greeting = plugin->state.greeting;
-
-    store(handle,
-          plugin->uris.my_greeting,
-          greeting,
-          strlen(greeting) + 1,  // Careful!  Need space for terminator
-          plugin->uris.atom_String,
-          LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
-
-    return LV2_STATE_SUCCESS;
-}
-
-LV2_State_Status
-my_restore(LV2_Handle                  instance,
-           LV2_State_Retrieve_Function retrieve,
-           LV2_State_Handle            handle,
-           uint32_t                    flags,
-           const LV2_Feature *const *  features)
-{
-    MyPlugin* plugin = (MyPlugin*)instance;
-
-    size_t      size;
-    uint32_t    type;
-    uint32_t    flags;
-    const char* greeting = retrieve(
-        handle, plugin->uris.my_greeting, &amp;size, &amp;type, &amp;flags);
-
-    if (greeting) {
-        free(plugin->state->greeting);
-        plugin->state->greeting = strdup(greeting);
-    } else {
-        plugin->state->greeting = strdup(DEFAULT_GREETING);
-    }
-
-    return LV2_STATE_SUCCESS;
-}
-
-const void*
-my_extension_data(const char* uri)
-{
-    static const LV2_State_Interface state_iface = { my_save, my_restore };
-    if (!strcmp(uri, LV2_STATE__interface)) {
-        return &amp;state_iface;
-    }
-}
-</pre>
-
-<h3>Host Code Example</h3>
-
-<pre class="c-code">
-LV2_State_Status
-store_callback(LV2_State_Handle handle,
-               uint32_t         key,
-               const void*      value,
-               size_t           size,
-               uint32_t         type,
-               uint32_t         flags)
-{
-    if ((flags &amp; LV2_STATE_IS_POD)) {
-        /* We only care about POD since we're keeping state in memory only.
-           For disk or network use, LV2_STATE_IS_PORTABLE must also be checked.
-        */
-        Map* state_map = (Map*)handle;
-        state_map->insert(key, Value(copy(value), size, type));
-        return 0;
-    } else {
-        return 1; /* Non-POD events are unsupported. */
-    }
-}
-
-Map
-get_plugin_state(LV2_Handle instance)
-{
-    LV2_State* state = instance.extension_data(LV2_STATE__interface);
-    Map state_map;
-    /** Request a fast/native/POD save, since we're just copying in memory */
-    state.save(instance, store_callback, &amp;state_map,
-               LV2_STATE_IS_POD|LV2_STATE_IS_NATIVE);
-    return state_map;
-}
-</pre>
-
-<h3>Extensions to this Specification</h3>
-
-<p>It is likely that other interfaces for working with plugin state will be
-developed as needed.  This is encouraged, however everything SHOULD work within
-the state <em>model</em> defined here.  That is, <strong>do not complicate the
-state model</strong>.  Implementations can assume the following:</p>
-
-<ul>
-<li>The current port values and state dictionary completely describe a plugin
-instance, at least well enough that saving and restoring will yield an
-<q>identical</q> instance from the user's perspective.</li>
-<li>Hosts are not expected to save and/or restore any other attributes of a
-plugin instance.</li>
-</ul>
-
-<h3>The <q>Property Principle</q></h3>
-
-<p>The main benefit of this meaningful state model is that it can double as a
-plugin control/query mechanism.  For plugins that require more advanced control
-than simple control ports, instead of defining a set of commands, define
-properties whose values can be set appropriately.  This provides both a way to
-control and save that state <q>for free</q>, since there is no need to define
-commands <em>and</em> a set of properties for storing their effects.  In
-particular, this is a good way for UIs to achieve more advanced control of
-plugins.</p>
-
-<p>This <q>property principle</q> is summed up in the phrase:
-<q>Don't stop; set playing to false</q>.</p>
-
-<p>This extension does not define a dynamic mechanism for state access and
-manipulation.  The <a href="../patch/patch.html">LV2 Patch</a> extension
-defines a generic set of messages which can be used to access or manipulate
-properties, and the <a href="../atom/atom.html">LV2 Atom</a> extension defines
-a port type and data container capable of transmitting those messages.</p>
-""" .
+		<state.meta.ttl> .
 
 state:interface
 	a lv2:ExtensionData ;
-	lv2:documentation """
-<p>A structure (LV2_State_Interface) which contains functions to be called by
-the host to save and restore state.  In order to support this extension, the
-plugin must return a valid LV2_State_Interface from
-LV2_Descriptor::extension_data() when it is called with URI
-LV2_STATE__interface.</p>
-
-<p>The plugin data file should describe this like so:</p>
-<pre class="turtle-code">
-@prefix state: &lt;http://lv2plug.in/ns/ext/state#&gt; .
-
-&lt;plugin&gt;
-    a lv2:Plugin ;
-    lv2:extensionData state:interface .
-</pre>
-""" .
+	rdfs:label "interface" ;
+	rdfs:comment "A plugin interface for saving and restoring state." .
 
 state:State
 	a rdfs:Class ;
 	rdfs:label "State" ;
-	lv2:documentation """
-<p>A state dictionary.  This type should be used wherever instance state is
-described.  The properties of a resource with this type correspond directly to
-the properties of the state dictionary (except the property that states it has
-this type).</p>
-""" .
+	rdfs:comment "LV2 plugin state." .
 
 state:loadDefaultState
 	a lv2:Feature ;
-	lv2:documentation """
-<p>This feature indicates that the plugin has default state listed with the
-state:state property which should be loaded by the host before running the
-plugin.  Requiring this feature allows plugins to implement a single state
-loading mechanism which works for initialisation as well as restoration,
-without having to hard-code default state.</p>
-
-<p>To support this feature, the host MUST <q>restore</q> the default state
-after instantiating the plugin but before calling run().</p>
-""" .
+	rdfs:label "load default state" ;
+	rdfs:comment "A feature indicating that the plugin has default state." .
 
 state:state
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:ObjectProperty ;
 	rdfs:label "state" ;
 	rdfs:range state:State ;
-	lv2:documentation """
-<p>The state of this instance.  This property may be used anywhere a state
-needs to be described, for example:</p>
-
-<pre class="turtle-code">
-@prefix eg: &lt;http://example.org/&gt; .
-
-&lt;plugin-instance&gt;
-    state:state [
-        eg:somekey "some value" ;
-        eg:someotherkey "some other value" ;
-        eg:favourite-number 2
-    ] .
-</pre>
-""" .
+	rdfs:comment "The state of an LV2 plugin instance." .
 
 state:mapPath
 	a lv2:Feature ;
-	rdfs:label "map file paths" ;
-	lv2:documentation """
-<p>This feature maps absolute paths to/from <q>abstract paths</q> which are
-stored in state.  To support this feature a host must pass an LV2_Feature with
-URI LV2_STATE__mapPath and data pointed to an LV2_State_Map_Path to the
-plugin's LV2_State_Interface methods.</p>
-
-<p>The plugin MUST map <em>all</em> paths stored in its state (including those
-inside any files in its state).  This is necessary to enable host to handle
-file system references correctly, e.g. for distribution or archival.</p>
-
-<p>For example, a plugin may write a path to a state file like so:</p>
-
-<pre class="c-code">
-void write_path(LV2_State_Map_Path* map_path, FILE* myfile, const char* path)
-{
-    char* abstract_path = map_path->abstract_path(map_path->handle, path);
-    fprintf(myfile, "%s", abstract_path);
-    free(abstract_path);
-}
-</pre>
-
-<p>Then, later reload the path like so:</p>
-
-<pre class="c-code">
-char* read_path(LV2_State_Map_Path* map_path, FILE* myfile)
-{
-    /* Obviously this is not production quality code! */
-    char abstract_path[1024];
-    fscanf(myfile, "%s", abstract_path);
-    return map_path->absolute_path(map_path->handle, abstract_path);
-}
-</pre>
-""" .
+	rdfs:label "map path" ;
+	rdfs:comment "A feature for mapping between absolute and abstract file paths." .
 
 state:makePath
 	a lv2:Feature ;
-	rdfs:label "create new file paths" ;
-	lv2:documentation """
-<p>This feature allows plugins to create new files and/or directories.  To
-support this feature the host passes an LV2_Feature with URI
-LV2_STATE__makePath and data pointed to an LV2_State_Make_Path to the plugin.
-The host may make this feature available only during save by passing it to
-LV2_State_Interface::save(), or available any time by passing it to
-LV2_Descriptor::instantiate().  If passed to LV2_State_Interface::save(), the
-feature MUST NOT be used beyond the scope of that call.</p>
-
-<p>The plugin is guaranteed a hierarchical namespace unique to that plugin
-instance, and may expect the returned path to have the requested path as a
-suffix.  There is <em>one</em> such namespace, even if the feature is passed to
-both LV2_Descriptor::instantiate() <em>and</em> LV2_State_Interface::save().
-Beyond this, the plugin MUST NOT make any assumptions about the returned
-paths.</p>
-
-<p>Like any other paths, the plugin MUST map these paths using state:mapPath
-before storing them in state.  The plugin MUST NOT assume these paths will be
-available across a save/restore otherwise, i.e.  only mapped paths saved to
-state are persistent, any other created paths are temporary.</p>
-
-<p>For example, a plugin may create a file in a subdirectory like so:</p>
-
-<pre class="c-code">
-char* save_myfile(LV2_State_Make_Path* make_path)
-{
-    char* path   = make_path->path(make_path->handle, "foo/bar/myfile.txt");
-    FILE* myfile = fopen(path, 'w');
-    fprintf(myfile, "I am some data");
-    fclose(myfile);
-    return path;
-}
-</pre>
-""" .
+	rdfs:label "make path" ;
+	rdfs:comment "A feature for creating new files and directories." .
 
 state:threadSafeRestore
 	a lv2:Feature ;
 	rdfs:label "thread-safe restore" ;
-	lv2:documentation """
-<p>If a plugin supports this feature, its LV2_State_Interface::restore method
-is thread-safe and may be called concurrently with audio class functions.</p>
-
-<p>To support this feature, the host MUST pass a <a
-href="../worker/worker.html#schedule">work:schedule</a> feature to the restore
-method, which will be used to complete the state restoration.  The usual
-mechanics of the worker apply: the host will call the plugin's work method,
-which emits a response which is later applied in the audio thread.</p>
+	rdfs:comment "A feature indicating support for thread-safe state restoration." .
 
-<p>The host is not required to block run() while restore() and work() load the
-state, so this feature allows state to be restored without dropouts.</p>
-""" .
+state:freePath
+	a lv2:Feature ;
+	rdfs:label "free path" ;
+	rdfs:comment "A feature for freeing paths allocated by the host." .
 
 state:Changed
 	a rdfs:Class ;
-	rdfs:label "State changed" ;
-	lv2:documentation """
-<p>A notification that the internal state of the plugin has been changed in a
-way that the host can not otherwise know about.</p>
-
-<p>This is a one-way notification, intended to be used as the type of an <a
-href="../atom/atom.html#Object">Object</a> sent from plugins when
-necessary.</p>
+	rdfs:label "Changed" ;
+	rdfs:comment "A notification that the internal state of the plugin has changed." .
 
-<p>Plugins SHOULD emit such an event whenever a change has occurred that would
-result in a different state being saved, but not when the host explicity makes
-a change which it knows is likely to have that effect, such as changing a
-parameter.</p>
-""" .
diff --git a/sys/lv2/time/NEWS b/sys/lv2/time/NEWS
deleted file mode 100644
index a7c29b44..00000000
--- a/sys/lv2/time/NEWS
+++ /dev/null
@@ -1,24 +0,0 @@
-time (1.6) stable;
-
-  * Clarify time:beat origin.
-
- -- None <None>  Sun, 03 Feb 2019 00:00:00 +0000
-
-time (1.4) stable;
-
-  * Define LV2_TIME_PREFIX.
-
- -- None <None>  Sun, 31 Jul 2016 00:00:00 +0000
-
-time (1.2) stable;
-
-  * Use consistent label style.
-
- -- None <None>  Sun, 14 Oct 2012 00:00:00 +0000
-
-time (1.0) stable;
-
-  * Initial release.
-
- -- None <None>  Tue, 17 Apr 2012 00:00:00 +0000
-
diff --git a/sys/lv2/time/lv2-time.doap.ttl b/sys/lv2/time/lv2-time.doap.ttl
deleted file mode 100644
index a46b9f65..00000000
--- a/sys/lv2/time/lv2-time.doap.ttl
+++ /dev/null
@@ -1,52 +0,0 @@
-@prefix dcs: <http://ontologi.es/doap-changeset#> .
-@prefix doap: <http://usefulinc.com/ns/doap#> .
-@prefix foaf: <http://xmlns.com/foaf/0.1/> .
-@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-
-<http://lv2plug.in/ns/ext/time>
-	a doap:Project ;
-	doap:name "LV2 Time" ;
-	doap:shortdesc "Properties for describing time." ;
-	doap:created "2011-10-05" ;
-	doap:developer <http://drobilla.net/drobilla#me> ;
-	doap:release [
-		doap:revision "1.6" ;
-		doap:created "2019-02-03" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.16.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Clarify time:beat origin."
-			]
-		]
-	] , [
-		doap:revision "1.4" ;
-		doap:created "2016-07-31" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.14.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Define LV2_TIME_PREFIX."
-			]
-		]
-	] , [
-		doap:revision "1.2" ;
-		doap:created "2012-10-14" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Use consistent label style."
-			]
-		]
-	] , [
-		doap:revision "1.0" ;
-		doap:created "2012-04-17" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Initial release."
-			]
-		]
-	] .
diff --git a/sys/lv2/time/manifest.ttl b/sys/lv2/time/manifest.ttl
index 55a82f13..d80aa752 100644
--- a/sys/lv2/time/manifest.ttl
+++ b/sys/lv2/time/manifest.ttl
@@ -1,4 +1,4 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/time>
diff --git a/sys/lv2/time/time.h b/sys/lv2/time/time.h
index ec5007c3..912d7321 100644
--- a/sys/lv2/time/time.h
+++ b/sys/lv2/time/time.h
@@ -16,6 +16,7 @@
 
 /**
    @defgroup time Time
+   @ingroup lv2
 
    Properties for describing time, see <http://lv2plug.in/ns/ext/time> for
    details.
diff --git a/sys/lv2/time/time.meta.ttl b/sys/lv2/time/time.meta.ttl
new file mode 100644
index 00000000..2b99cb77
--- /dev/null
+++ b/sys/lv2/time/time.meta.ttl
@@ -0,0 +1,112 @@
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix time: <http://lv2plug.in/ns/ext/time#> .
+
+<http://lv2plug.in/ns/ext/time>
+	a doap:Project ;
+	doap:name "LV2 Time" ;
+	doap:shortdesc "A vocabulary for describing musical time." ;
+	doap:created "2011-10-05" ;
+	doap:developer <http://drobilla.net/drobilla#me> ;
+	doap:release [
+		doap:revision "1.6" ;
+		doap:created "2019-02-03" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.16.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Clarify time:beat origin."
+			]
+		]
+	] , [
+		doap:revision "1.4" ;
+		doap:created "2016-07-31" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.14.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Define LV2_TIME_PREFIX."
+			]
+		]
+	] , [
+		doap:revision "1.2" ;
+		doap:created "2012-10-14" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Use consistent label style."
+			]
+		]
+	] , [
+		doap:revision "1.0" ;
+		doap:created "2012-04-17" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Initial release."
+			]
+		]
+	] ;
+	lv2:documentation """
+
+This is a vocabulary for describing a position in time and the speed of time
+passage, in both real and musical terms.
+
+In addition to real time (based on seconds), two units of time are used:
+_frames_ and _beats_.  A frame is a numbered quantum of time.  Frame time is
+related to real-time by the _frame rate_ or _sample rate_,
+time:framesPerSecond.  A beat is a single pulse of musical time.  Beat time is
+related to real-time by the _tempo_, time:beatsPerMinute.
+
+Musical time additionally has a _meter_ which describes passage of time in
+terms of musical _bars_.  A bar is a higher level grouping of beats.  The meter
+describes how many beats are in one bar.
+
+"""^^lv2:Markdown .
+
+time:Position
+	lv2:documentation """
+
+A point in time and/or the speed at which time is passing.  A position is both
+a point and a speed, which precisely defines a time within a timeline.
+
+"""^^lv2:Markdown .
+
+time:Rate
+	lv2:documentation """
+
+The rate of passage of time in terms of one unit with respect to another.
+
+"""^^lv2:Markdown .
+
+time:beat
+	lv2:documentation """
+
+This is not the beat within a bar like time:barBeat, but relative to the same
+origin as time:bar and monotonically increases unless the transport is
+repositioned.
+
+"""^^lv2:Markdown .
+
+time:beatUnit
+	lv2:documentation """
+
+Beat unit, the note value that counts as one beat.  This is the bottom number
+in a time signature: 2 for half note, 4 for quarter note, and so on.
+
+"""^^lv2:Markdown .
+
+time:speed
+	lv2:documentation """
+
+The rate of the progress of time as a fraction of normal speed.  For example, a
+rate of 0.0 is stopped, 1.0 is rolling at normal speed, 0.5 is rolling at half
+speed, -1.0 is reverse, and so on.
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/time/time.ttl b/sys/lv2/time/time.ttl
index 13137aff..a4085c60 100644
--- a/sys/lv2/time/time.ttl
+++ b/sys/lv2/time/time.ttl
@@ -1,57 +1,43 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
-@prefix owl:  <http://www.w3.org/2002/07/owl#> .
-@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 @prefix time: <http://lv2plug.in/ns/ext/time#> .
-@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
 
 <http://lv2plug.in/ns/ext/time>
 	a owl:Ontology ;
+	rdfs:label "LV2 Time" ;
+	rdfs:comment "A vocabulary for describing musical time." ;
 	rdfs:seeAlso <time.h> ,
-		<lv2-time.doap.ttl> ;
-	lv2:documentation """
-<p>This is a vocabulary for precisely describing a position in time and the
-passage of time itself, in both real and musical terms.</p>
-
-<p>In addition to real time (e.g. seconds), two units of time are used:
-<q>frames</q> and <q>beats</q>.  A frame is a numbered quantum of time.  Frame
-time is related to real-time by the <q>frame rate</q> or <q>sample rate</q>,
-time:framesPerSecond.  A beat is a single pulse of musical time.  Beat time is
-related to real-time by the <q>tempo</q>, time:beatsPerMinute.</p>
-
-<p>Musical time additionally has a <q>meter</q> which describes passage of time
-in terms of musical <q>bars</q>.  A bar is a higher level grouping of beats.
-The meter describes how many beats are in one bar.</p>
-""" .
+		<time.meta.ttl> .
 
 time:Time
-	a rdfs:Class ;
+	a rdfs:Class ,
+		owl:Class ;
 	rdfs:subClassOf time:Position ;
 	rdfs:label "Time" ;
 	rdfs:comment "A point in time in some unit/dimension." .
 
 time:Position
-	a rdfs:Class ;
+	a rdfs:Class ,
+		owl:Class ;
 	rdfs:label "Position" ;
-	lv2:documentation """
-<p>A point in time and/or the speed at which time is passing.  A position is
-both a point and a speed, which precisely defines a time within a timeline.</p>
-""" .
+	rdfs:comment "A point in time and/or the speed at which time is passing." .
 
 time:Rate
-	a rdfs:Class ;
+	a rdfs:Class ,
+		owl:Class ;
 	rdfs:subClassOf time:Position ;
 	rdfs:label "Rate" ;
-	lv2:documentation """
-<p>The rate of passage of time in terms of one unit with respect to
-another.</p> """ .
+	rdfs:comment "The rate of passage of time." .
 
 time:position
 	a rdf:Property ,
 		owl:ObjectProperty ,
 		owl:FunctionalProperty ;
 	rdfs:range time:Position ;
-	rdfs:label "position" .
+	rdfs:label "position" ;
+	rdfs:comment "A musical position." .
 
 time:barBeat
 	a rdf:Property ,
@@ -60,7 +46,7 @@ time:barBeat
 	rdfs:domain time:Time ;
 	rdfs:range xsd:float ;
 	rdfs:label "beat within bar" ;
-	rdfs:comment "The beat number within the bar, from 0 to beatsPerBar." .
+	rdfs:comment "The beat number within the bar, from 0 to time:beatsPerBar." .
 
 time:bar
 	a rdf:Property ,
@@ -68,7 +54,8 @@ time:bar
 		owl:FunctionalProperty ;
 	rdfs:domain time:Time ;
 	rdfs:range xsd:long ;
-	rdfs:label "bar" .
+	rdfs:label "bar" ;
+	rdfs:comment "A musical bar or measure." .
 
 time:beat
 	a rdf:Property ,
@@ -77,11 +64,7 @@ time:beat
 	rdfs:domain time:Time ;
 	rdfs:range xsd:double ;
 	rdfs:label "beat" ;
-	rdfs:comment """
-The global running beat number.  This is not the beat within a bar like barBeat,
-but relative to the same origin as time:bar and monotonically increases unless
-the transport is repositioned.
-""" .
+	rdfs:comment "The global running beat number." .
 
 time:beatUnit
 	a rdf:Property ,
@@ -89,10 +72,8 @@ time:beatUnit
 		owl:FunctionalProperty ;
 	rdfs:domain time:Rate ;
 	rdfs:range xsd:nonNegativeInteger ;
-	lv2:documentation """
-<p>Beat unit, the note value that counts as one beat.  This is the bottom number
-in a time signature: 2 for half note, 4 for quarter note, and so on.</p>
-""" .
+	rdfs:label "beat unit" ;
+	rdfs:comment "The note value that counts as one beat." .
 
 time:beatsPerBar
 	a rdf:Property ,
@@ -100,7 +81,8 @@ time:beatsPerBar
 		owl:FunctionalProperty ;
 	rdfs:domain time:Rate ;
 	rdfs:range xsd:float ;
-	rdfs:label "beats per bar" .
+	rdfs:label "beats per bar" ;
+	rdfs:comment "The number of beats in one bar." .
 
 time:beatsPerMinute
 	a rdf:Property ,
@@ -117,7 +99,8 @@ time:frame
 		owl:FunctionalProperty ;
 	rdfs:domain time:Time ;
 	rdfs:range xsd:long ;
-	rdfs:label "frame" .
+	rdfs:label "frame" ;
+	rdfs:comment "A time stamp in audio frames." .
 
 time:framesPerSecond
 	a rdf:Property ,
@@ -135,9 +118,5 @@ time:speed
 	rdfs:domain time:Rate ;
 	rdfs:range xsd:float ;
 	rdfs:label "speed" ;
-	lv2:documentation """
-<p>The rate of the progress of time as a fraction of normal speed.  For
-example, a rate of 0.0 is stopped, 1.0 is rolling at normal speed, 0.5 is
-rolling at half speed, -1.0 is reverse, and so on.
-</p>
-""" .
+	rdfs:comment "The rate of the progress of time as a fraction of normal speed." .
+
diff --git a/sys/lv2/ui/NEWS b/sys/lv2/ui/NEWS
deleted file mode 100644
index 82f3c9cb..00000000
--- a/sys/lv2/ui/NEWS
+++ /dev/null
@@ -1,80 +0,0 @@
-ui (2.20) stable;
-
-  * Improve documentation.
-  * Add missing property labels.
-
- -- None <None>  Sat, 25 Jul 2015 00:00:00 +0000
-
-ui (2.18) stable;
-
-  * Add show interface so UIs can gracefully degrade to separate windows if hosts
-    can not use their widget directly.
-  * Fix identifier typos in documentation.
-
- -- None <None>  Fri, 08 Aug 2014 00:00:00 +0000
-
-ui (2.16) stable;
-
-  * Fix LV2_UI_INVALID_PORT_INDEX identifier in documentation.
-
- -- None <None>  Sat, 04 Jan 2014 00:00:00 +0000
-
-ui (2.14) stable;
-
-  * Add idle interface so native UIs and foreign toolkits can drive their event
-    loops.
-  * Add ui:updateRate property.
-
- -- None <None>  Mon, 18 Mar 2013 00:00:00 +0000
-
-ui (2.12) stable;
-
-  * Fix incorrect linker flag in ui:makeSONameResident documentation.
-
- -- None <None>  Sat, 01 Dec 2012 00:00:00 +0000
-
-ui (2.10) stable;
-
-  * Add types for WindowsUI, CocoaUI, and Gtk3UI.
-  * Add missing LV2_SYMBOL_EXPORT declaration for lv2ui_descriptor prototype.
-  * Use consistent label style.
-
- -- None <None>  Sun, 14 Oct 2012 00:00:00 +0000
-
-ui (2.8) stable;
-
-  * Add port protocols and a dynamic notification subscription mechanism, for more
-    flexible communication, and audio port metering without control port kludges.
-  * Add ui:parent and ui:resize.
-  * Add ui:portMap for accessing ports by symbol, allowing for UIs to be
-    distributed separately from plugins.
-  * Add support for referring to ports by symbol.
-  * Merge with unified LV2 package.
-  * Add touch feature to notify the host that the user has grabbed a control.
-
- -- None <None>  Tue, 17 Apr 2012 00:00:00 +0000
-
-ui (2.4) stable;
-
-  * Install header to URI-based system path.
-  * Deprecate ui:makeSONameResident.
-  * Add Qt4 and X11 widget types.
-  * Make ui.ttl a valid OWL 2 DL ontology.
-  * Add pkg-config file.
-
- -- None <None>  Mon, 21 Nov 2011 00:00:00 +0000
-
-ui (2.2) stable;
-
-  * Add build system (for installation).
-  * Use lv2:Specification to be discovered as an extension.
-  * Convert documentation to HTML and use lv2:documentation.
-
- -- None <None>  Thu, 26 May 2011 00:00:00 +0000
-
-ui (2.0) stable;
-
-  * Initial release.
-
- -- None <None>  Wed, 06 Oct 2010 00:00:00 +0000
-
diff --git a/sys/lv2/ui/lv2-ui.doap.ttl b/sys/lv2/ui/lv2-ui.doap.ttl
deleted file mode 100644
index 8b804b15..00000000
--- a/sys/lv2/ui/lv2-ui.doap.ttl
+++ /dev/null
@@ -1,146 +0,0 @@
-@prefix dcs:  <http://ontologi.es/doap-changeset#> .
-@prefix doap: <http://usefulinc.com/ns/doap#> .
-@prefix foaf: <http://xmlns.com/foaf/0.1/> .
-@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-
-<http://lv2plug.in/ns/extensions/ui>
-	a doap:Project ;
-	doap:license <http://opensource.org/licenses/isc> ;
-	doap:name "LV2 UI" ;
-	doap:shortdesc "LV2 plugin UIs of any type." ;
-	doap:created "2006-00-00" ;
-	doap:developer <http://lv2plug.in/ns/meta#larsl> ;
-	doap:maintainer <http://drobilla.net/drobilla#me> ;
-	doap:release [
-		doap:revision "2.20" ;
-		doap:created "2015-07-25" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.14.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Improve documentation."
-			] , [
-				rdfs:label "Add missing property labels."
-			]
-		]
-	] , [
-		doap:revision "2.18" ;
-		doap:created "2014-08-08" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.10.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Add show interface so UIs can gracefully degrade to separate windows if hosts can not use their widget directly."
-			] , [
-				rdfs:label "Fix identifier typos in documentation."
-			]
-		]
-	] , [
-		doap:revision "2.16" ;
-		doap:created "2014-01-04" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.8.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Fix LV2_UI_INVALID_PORT_INDEX identifier in documentation."
-			]
-		]
-	] , [
-		doap:revision "2.14" ;
-		doap:created "2013-03-18" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.6.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Add idle interface so native UIs and foreign toolkits can drive their event loops."
-			] , [
-				rdfs:label "Add ui:updateRate property."
-			]
-		]
-	] , [
-		doap:revision "2.12" ;
-		doap:created "2012-12-01" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.4.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Fix incorrect linker flag in ui:makeSONameResident documentation."
-			]
-		]
-	] , [
-		doap:revision "2.10" ;
-		doap:created "2012-10-14" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Add types for WindowsUI, CocoaUI, and Gtk3UI."
-			] , [
-				rdfs:label "Use consistent label style."
-			] , [
-				rdfs:label "Add missing LV2_SYMBOL_EXPORT declaration for lv2ui_descriptor prototype."
-			]
-		]
-	] , [
-		doap:revision "2.8" ;
-		doap:created "2012-04-17" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Add ui:parent and ui:resize."
-			] , [
-				rdfs:label "Add support for referring to ports by symbol."
-			] , [
-				rdfs:label "Add ui:portMap for accessing ports by symbol, allowing for UIs to be distributed separately from plugins."
-			] , [
-				rdfs:label "Add port protocols and a dynamic notification subscription mechanism, for more flexible communication, and audio port metering without control port kludges."
-			] , [
-				rdfs:label "Add touch feature to notify the host that the user has grabbed a control."
-			] , [
-				rdfs:label "Merge with unified LV2 package."
-			]
-		]
-	] , [
-		doap:revision "2.4" ;
-		doap:created "2011-11-21" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-ui-2.4.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Deprecate ui:makeSONameResident."
-			] , [
-				rdfs:label "Add Qt4 and X11 widget types."
-			] , [
-				rdfs:label "Install header to URI-based system path."
-			] , [
-				rdfs:label "Add pkg-config file."
-			] , [
-				rdfs:label "Make ui.ttl a valid OWL 2 DL ontology."
-			]
-		]
-	] , [
-		doap:revision "2.2" ;
-		doap:created "2011-05-26" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-ui-2.2.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Add build system (for installation)."
-			] , [
-				rdfs:label "Convert documentation to HTML and use lv2:documentation."
-			] , [
-				rdfs:label "Use lv2:Specification to be discovered as an extension."
-			]
-		]
-	] , [
-		doap:revision "2.0" ;
-		doap:created "2010-10-06" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-ui-2.0.tar.gz> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Initial release."
-			]
-		]
-	] .
diff --git a/sys/lv2/ui/manifest.ttl b/sys/lv2/ui/manifest.ttl
index 384bf2e1..9f259adf 100644
--- a/sys/lv2/ui/manifest.ttl
+++ b/sys/lv2/ui/manifest.ttl
@@ -1,8 +1,9 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/extensions/ui>
 	a lv2:Specification ;
 	lv2:minorVersion 2 ;
-	lv2:microVersion 20 ;
-	rdfs:seeAlso <ui.ttl> .
\ No newline at end of file
+	lv2:microVersion 22 ;
+	rdfs:seeAlso <ui.ttl> .
+
diff --git a/sys/lv2/ui/ui.h b/sys/lv2/ui/ui.h
index 450a41e6..ce6aa4fc 100644
--- a/sys/lv2/ui/ui.h
+++ b/sys/lv2/ui/ui.h
@@ -18,6 +18,7 @@
 
 /**
    @defgroup ui User Interfaces
+   @ingroup lv2
 
    User interfaces of any type for plugins,
    <http://lv2plug.in/ns/extensions/ui> for details.
@@ -29,6 +30,7 @@
 #define LV2_UI_H
 
 #include "lv2/core/lv2.h"
+#include "lv2/urid/urid.h"
 
 #include <stdbool.h>
 #include <stdint.h>
@@ -58,6 +60,7 @@
 #define LV2_UI__portNotification LV2_UI_PREFIX "portNotification"  ///< http://lv2plug.in/ns/extensions/ui#portNotification
 #define LV2_UI__portSubscribe    LV2_UI_PREFIX "portSubscribe"     ///< http://lv2plug.in/ns/extensions/ui#portSubscribe
 #define LV2_UI__protocol         LV2_UI_PREFIX "protocol"          ///< http://lv2plug.in/ns/extensions/ui#protocol
+#define LV2_UI__requestValue     LV2_UI_PREFIX "requestValue"      ///< http://lv2plug.in/ns/extensions/ui#requestValue
 #define LV2_UI__floatProtocol    LV2_UI_PREFIX "floatProtocol"     ///< http://lv2plug.in/ns/extensions/ui#floatProtocol
 #define LV2_UI__peakProtocol     LV2_UI_PREFIX "peakProtocol"      ///< http://lv2plug.in/ns/extensions/ui#peakProtocol
 #define LV2_UI__resize           LV2_UI_PREFIX "resize"            ///< http://lv2plug.in/ns/extensions/ui#resize
@@ -66,6 +69,9 @@
 #define LV2_UI__ui               LV2_UI_PREFIX "ui"                ///< http://lv2plug.in/ns/extensions/ui#ui
 #define LV2_UI__updateRate       LV2_UI_PREFIX "updateRate"        ///< http://lv2plug.in/ns/extensions/ui#updateRate
 #define LV2_UI__windowTitle      LV2_UI_PREFIX "windowTitle"       ///< http://lv2plug.in/ns/extensions/ui#windowTitle
+#define LV2_UI__scaleFactor      LV2_UI_PREFIX "scaleFactor"       ///< http://lv2plug.in/ns/extensions/ui#scaleFactor
+#define LV2_UI__foregroundColor  LV2_UI_PREFIX "foregroundColor"   ///< http://lv2plug.in/ns/extensions/ui#foregroundColor
+#define LV2_UI__backgroundColor  LV2_UI_PREFIX "backgroundColor"   ///< http://lv2plug.in/ns/extensions/ui#backgroundColor
 
 /**
    The index returned by LV2UI_Port_Map::port_index() for unknown ports.
@@ -133,7 +139,7 @@ typedef void (*LV2UI_Write_Function)(LV2UI_Controller controller,
    A pointer to an object of this type is returned by the lv2ui_descriptor()
    function.
 */
-typedef struct _LV2UI_Descriptor {
+typedef struct LV2UI_Descriptor {
 	/**
 	   The URI for this UI (not for the plugin it controls).
 	*/
@@ -165,13 +171,13 @@ typedef struct _LV2UI_Descriptor {
 	   features are not necessarily the same.
 
 	*/
-	LV2UI_Handle (*instantiate)(const struct _LV2UI_Descriptor* descriptor,
-	                            const char*                     plugin_uri,
-	                            const char*                     bundle_path,
-	                            LV2UI_Write_Function            write_function,
-	                            LV2UI_Controller                controller,
-	                            LV2UI_Widget*                   widget,
-	                            const LV2_Feature* const*       features);
+	LV2UI_Handle (*instantiate)(const struct LV2UI_Descriptor* descriptor,
+	                            const char*                    plugin_uri,
+	                            const char*                    bundle_path,
+	                            LV2UI_Write_Function           write_function,
+	                            LV2UI_Controller               controller,
+	                            LV2UI_Widget*                  widget,
+	                            const LV2_Feature* const*      features);
 
 
 	/**
@@ -223,7 +229,7 @@ typedef struct _LV2UI_Descriptor {
    LV2UI_Descriptor::instantiate(), or as an interface provided by a UI via
    LV2UI_Descriptor::extension_data()).
 */
-typedef struct _LV2UI_Resize {
+typedef struct {
 	/**
 	   Pointer to opaque data which must be passed to ui_resize().
 	*/
@@ -251,7 +257,7 @@ typedef struct _LV2UI_Resize {
    symbol.  This makes it possible to implement and distribute a UI separately
    from the plugin (since symbol, unlike index, is a stable port identifier).
 */
-typedef struct _LV2UI_Port_Map {
+typedef struct {
 	/**
 	   Pointer to opaque data which must be passed to port_index().
 	*/
@@ -269,7 +275,7 @@ typedef struct _LV2UI_Port_Map {
 /**
    Feature to subscribe to port updates (LV2_UI__portSubscribe).
 */
-typedef struct _LV2UI_Port_Subscribe {
+typedef struct {
 	/**
 	   Pointer to opaque data which must be passed to subscribe() and
 	   unsubscribe().
@@ -320,7 +326,7 @@ typedef struct _LV2UI_Port_Subscribe {
 /**
    A feature to notify the host that the user has grabbed a UI control.
 */
-typedef struct _LV2UI_Touch {
+typedef struct {
 	/**
 	   Pointer to opaque data which must be passed to ui_resize().
 	*/
@@ -342,13 +348,101 @@ typedef struct _LV2UI_Touch {
 	              bool                 grabbed);
 } LV2UI_Touch;
 
+/**
+   A status code for LV2UI_Request_Value::request().
+*/
+typedef enum {
+	/**
+	   Completed successfully.
+
+	   The host will set the parameter later if the user choses a new value.
+	*/
+	LV2UI_REQUEST_VALUE_SUCCESS,
+
+	/**
+	   Parameter already being requested.
+
+	   The host is already requesting a parameter from the user (for example, a
+	   dialog is visible), or the UI is otherwise busy and can not make this
+	   request.
+	*/
+	LV2UI_REQUEST_VALUE_BUSY,
+
+	/**
+	   Unknown parameter.
+
+	   The host is not aware of this parameter, and is not able to set a new
+	   value for it.
+	*/
+	LV2UI_REQUEST_VALUE_ERR_UNKNOWN,
+
+	/**
+	   Unsupported parameter.
+
+	   The host knows about this parameter, but does not support requesting a
+	   new value for it from the user.  This is likely because the host does
+	   not have UI support for choosing a value with the appropriate type.
+	*/
+	LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED
+} LV2UI_Request_Value_Status;
+
+/**
+   A feature to request a new parameter value from the host.
+*/
+typedef struct {
+	/**
+	   Pointer to opaque data which must be passed to request().
+	*/
+	LV2UI_Feature_Handle handle;
+
+	/**
+	   Request a value for a parameter from the host.
+
+	   This is mainly used by UIs to request values for complex parameters that
+	   don't change often, such as file paths, but it may be used to request
+	   any parameter value.
+
+	   This function returns immediately, and the return value indicates
+	   whether the host can fulfill the request.  The host may notify the
+	   plugin about the new parameter value, for example when a file is
+	   selected by the user, via the usual mechanism.  Typically, the host will
+	   send a message to the plugin that sets the new parameter value, and the
+	   plugin will notify the UI via a message as usual for any other parameter
+	   change.
+
+	   To provide an appropriate UI, the host can determine details about the
+	   parameter from the plugin data as usual.  The additional parameters of
+	   this function provide support for more advanced use cases, but in the
+	   simple common case, the plugin will simply pass the key of the desired
+	   parameter and zero for everything else.
+
+	   @param handle The handle field of this struct.
+
+	   @param key The URID of the parameter.
+
+	   @param type The optional type of the value to request.  This can be used
+	   to request a specific value type for parameters that support several.
+	   If non-zero, it must be the URID of an instance of rdfs:Class or
+	   rdfs:Datatype.
+
+	   @param features Additional features for this request, or NULL.
+
+	   @return A status code which is 0 on success.
+	*/
+	LV2UI_Request_Value_Status (*request)(LV2UI_Feature_Handle      handle,
+	                                      LV2_URID                  key,
+	                                      LV2_URID                  type,
+	                                      const LV2_Feature* const* features);
+
+} LV2UI_Request_Value;
+
 /**
    UI Idle Interface (LV2_UI__idleInterface)
 
    UIs can provide this interface to have an idle() callback called by the host
    rapidly to update the UI.
 */
-typedef struct _LV2UI_Idle_Interface {
+typedef struct {
 	/**
 	   Run a single iteration of the UI's idle loop.
 
@@ -377,7 +471,7 @@ typedef struct _LV2UI_Idle_Interface {
    - If idle() returns non-zero, the host MUST call hide() and stop calling
      idle().  It MAY later call show() then resume calling idle().
 */
-typedef struct _LV2UI_Show_Interface {
+typedef struct {
 	/**
 	   Show a window for this UI.
 
@@ -400,7 +494,7 @@ typedef struct _LV2UI_Show_Interface {
 /**
    Peak data for a slice of time, the update format for ui:peakProtocol.
 */
-typedef struct _LV2UI_Peak_Data {
+typedef struct {
 	/**
 	   The start of the measurement period.  This is just a running counter
 	   that is only meaningful in comparison to previous values and must not be
diff --git a/sys/lv2/ui/ui.meta.ttl b/sys/lv2/ui/ui.meta.ttl
new file mode 100644
index 00000000..cb92a865
--- /dev/null
+++ b/sys/lv2/ui/ui.meta.ttl
@@ -0,0 +1,627 @@
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
+
+<http://lv2plug.in/ns/extensions/ui>
+	a doap:Project ;
+	doap:license <http://opensource.org/licenses/isc> ;
+	doap:name "LV2 UI" ;
+	doap:shortdesc "User interfaces for LV2 plugins." ;
+	doap:created "2006-00-00" ;
+	doap:developer <http://lv2plug.in/ns/meta#larsl> ;
+	doap:maintainer <http://drobilla.net/drobilla#me> ;
+	doap:release [
+		doap:revision "2.22" ;
+		doap:created "2020-04-26" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.18.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add ui:requestValue feature."
+			] , [
+				rdfs:label "Add ui:scaleFactor, ui:foregroundColor, and ui:backgroundColor properties."
+			] , [
+				rdfs:label "Deprecate ui:binary."
+			]
+		]
+	] , [
+		doap:revision "2.20" ;
+		doap:created "2015-07-25" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.14.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Improve documentation."
+			] , [
+				rdfs:label "Add missing property labels."
+			]
+		]
+	] , [
+		doap:revision "2.18" ;
+		doap:created "2014-08-08" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.10.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add show interface so UIs can gracefully degrade to separate windows if hosts can not use their widget directly."
+			] , [
+				rdfs:label "Fix identifier typos in documentation."
+			]
+		]
+	] , [
+		doap:revision "2.16" ;
+		doap:created "2014-01-04" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.8.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Fix LV2_UI_INVALID_PORT_INDEX identifier in documentation."
+			]
+		]
+	] , [
+		doap:revision "2.14" ;
+		doap:created "2013-03-18" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.6.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add idle interface so native UIs and foreign toolkits can drive their event loops."
+			] , [
+				rdfs:label "Add ui:updateRate property."
+			]
+		]
+	] , [
+		doap:revision "2.12" ;
+		doap:created "2012-12-01" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.4.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Fix incorrect linker flag in ui:makeSONameResident documentation."
+			]
+		]
+	] , [
+		doap:revision "2.10" ;
+		doap:created "2012-10-14" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add types for WindowsUI, CocoaUI, and Gtk3UI."
+			] , [
+				rdfs:label "Use consistent label style."
+			] , [
+				rdfs:label "Add missing LV2_SYMBOL_EXPORT declaration for lv2ui_descriptor prototype."
+			]
+		]
+	] , [
+		doap:revision "2.8" ;
+		doap:created "2012-04-17" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add ui:parent and ui:resize."
+			] , [
+				rdfs:label "Add support for referring to ports by symbol."
+			] , [
+				rdfs:label "Add ui:portMap for accessing ports by symbol, allowing for UIs to be distributed separately from plugins."
+			] , [
+				rdfs:label "Add port protocols and a dynamic notification subscription mechanism, for more flexible communication, and audio port metering without control port kludges."
+			] , [
+				rdfs:label "Add touch feature to notify the host that the user has grabbed a control."
+			] , [
+				rdfs:label "Merge with unified LV2 package."
+			]
+		]
+	] , [
+		doap:revision "2.4" ;
+		doap:created "2011-11-21" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-ui-2.4.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Deprecate ui:makeSONameResident."
+			] , [
+				rdfs:label "Add Qt4 and X11 widget types."
+			] , [
+				rdfs:label "Install header to URI-based system path."
+			] , [
+				rdfs:label "Add pkg-config file."
+			] , [
+				rdfs:label "Make ui.ttl a valid OWL 2 DL ontology."
+			]
+		]
+	] , [
+		doap:revision "2.2" ;
+		doap:created "2011-05-26" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-ui-2.2.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add build system (for installation)."
+			] , [
+				rdfs:label "Convert documentation to HTML and use lv2:documentation."
+			] , [
+				rdfs:label "Use lv2:Specification to be discovered as an extension."
+			]
+		]
+	] , [
+		doap:revision "2.0" ;
+		doap:created "2010-10-06" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-ui-2.0.tar.gz> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Initial release."
+			]
+		]
+	] ;
+	lv2:documentation """
+
+This extension makes it possible to create user interfaces for LV2 plugins.
+
+UIs are implemented as an LV2UI_Descriptor loaded via lv2ui_descriptor() in a
+shared library, and are distributed in bundles just like plugins.
+
+UIs are associated with plugins in data:
+
+    :::turtle
+    @prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
+
+    <http://my.plugin>   ui:ui      <http://my.pluginui> .
+    <http://my.pluginui> a          ui:X11UI ;
+                         lv2:binary <myui.so> .
+
+where `http://my.plugin` is the URI of the plugin, `http://my.pluginui` is the
+URI of the plugin UI and `myui.so` is the relative URI to the shared object
+file.
+
+While it is possible to have the plugin UI and the plugin in the same shared
+object file, it is a good idea to keep them separate so that hosts can avoid
+loading the UI code if they do not need it.  A UI MUST specify its class in the
+RDF data (`ui:X11UI` in the above example).  The class defines what type the UI
+is, for example what graphics toolkit it uses.  Any type of UI class can be
+defined separately from this extension.
+
+It is possible to have multiple UIs for the same plugin, or to have the UI for
+a plugin in a different bundle from the actual plugin.  This allows plugin UIs
+to be written independently.
+
+Note that the process that loads the shared object file containing the UI code
+and the process that loads the shared object file containing the actual plugin
+implementation are not necessarily the same process (and not even necessarily
+on the same machine).  This means that plugin and UI code MUST NOT use
+singletons and global variables and expect them to refer to the same objects in
+the UI and the actual plugin. The function callback interface defined in this
+header is the only method of communication between UIs and plugin instances
+(extensions may define more, though this is discouraged unless absolutely
+necessary since the significant benefits of network transparency and
+serialisability are lost).
+
+UI functionality may be extended via features, much like plugins:
+
+    :::turtle
+    <http://my.pluginui> lv2:requiredFeature <http://my.feature> .
+    <http://my.pluginui> lv2:optionalFeature <http://my.feature> .
+
+The rules for a UI with a required or optional feature are identical to those
+of lv2:Plugin instances: if a UI declares a feature as required, the host is
+NOT allowed to load it unless it supports that feature; and if it does support
+a feature, it MUST pass an appropriate LV2_Feature struct to the UI's
+instantiate() method.  This extension defines several standard features for
+common functionality.
+
+UIs written to this specification do not need to be thread-safe.  All functions
+may only be called in the <q>UI thread</q>.  There is only one UI thread (for
+toolkits, the one the UI main loop runs in).  There is no requirement that a
+<q>UI</q> actually be a graphical widget.
+
+Note that UIs are completely separate from plugins.  From the plugin's
+perspective, control from a UI is indistinguishable from any other control, as
+it all occcurs via ports.
+
+"""^^lv2:Markdown .
+
+ui:GtkUI
+	lv2:documentation """
+
+The host must guarantee that the Gtk+ 2 library has been initialised and the
+Glib main loop is running before the UI is instantiated.  Note that this UI
+type is not suitable for binary distribution since multiple versions of Gtk can
+not be used in the same process.
+
+"""^^lv2:Markdown .
+
+ui:Gtk3UI
+	lv2:documentation """
+
+The host must guarantee that the Gtk+ 3 library has been initialised and the
+Glib main loop is running before the UI is instantiated.  Note that this UI
+type is not suitable for binary distribution since multiple versions of Gtk can
+not be used in the same process.
+
+"""^^lv2:Markdown .
+
+ui:Qt4UI
+	lv2:documentation """
+
+The host must guarantee that the Qt4 library has been initialised and the Qt4
+main loop is running before the UI is instantiated.  Note that this UI type is
+not suitable for binary distribution since multiple versions of Qt can not be
+used in the same process.
+
+"""^^lv2:Markdown .
+
+ui:Qt5UI
+	lv2:documentation """
+
+The host must guarantee that the Qt5 library has been initialised and the Qt5
+main loop is running before the UI is instantiated.  Note that this UI type is
+not suitable for binary distribution since multiple versions of Qt can not be
+used in the same process.
+
+"""^^lv2:Markdown .
+
+ui:X11UI
+	lv2:documentation """
+
+Note that the LV2UI_Widget for this type of UI is not a pointer, but should be
+interpreted directly as an X11 `Window` ID.  This is the native UI type on most
+POSIX systems.
+
+"""^^lv2:Markdown .
+
+ui:WindowsUI
+	lv2:documentation """
+
+Note that the LV2UI_Widget for this type of UI is not a pointer, but should be
+interpreted directly as a `HWND`.  This is the native UI type on Microsoft
+Windows.
+
+"""^^lv2:Markdown .
+
+ui:CocoaUI
+	lv2:documentation """
+
+This is the native UI type on Mac OS X.
+
+"""^^lv2:Markdown .
+
+ui:binary
+	lv2:documentation """
+
+This property is redundant and deprecated: new UIs should use lv2:binary
+instead, however hosts must still support ui:binary.
+
+"""^^lv2:Markdown .
+
+ui:makeSONameResident
+	lv2:documentation """
+
+This feature was intended to support UIs that link against toolkit libraries
+which may not be unloaded during the lifetime of the host.  This is better
+achieved by using the appropriate flags when linking the UI, for example `gcc
+-Wl,-z,nodelete`.
+
+"""^^lv2:Markdown .
+
+ui:noUserResize
+	lv2:documentation """
+
+If a UI has this feature, it indicates that it does not make sense to let the
+user resize the main widget, and the host should prevent that.  This feature
+may not make sense for all UI types.  The data pointer for this feature should
+always be set to NULL.
+
+"""^^lv2:Markdown .
+
+ui:fixedSize
+	lv2:documentation """
+
+If a UI has this feature, it indicates the same thing as ui:noUserResize, and
+additionally that the UI will not resize itself on its own.  That is, the UI
+will always remain the same size.  This feature may not make sense for all UI
+types.  The data pointer for this feature should always be set to NULL.
+
+"""^^lv2:Markdown .
+
+ui:scaleFactor
+	lv2:documentation """
+
+HiDPI (High Dots Per Inch) displays have a high resolution on a relatively
+small form factor.  Many systems use a scale factor to compensate for this, so
+for example, a scale factor of 2 means things are drawn twice as large as
+normal.
+
+Hosts can pass this as an option to UIs to communicate this information, so
+that the UI can draw at an appropriate scale.
+
+"""^^lv2:Markdown .
+
+ui:backgroundColor
+	lv2:documentation """
+
+The background color of the host's UI.  The host can pass this as an option so
+that UIs can integrate nicely with the host window around it.
+
+Hosts should pass this as an option to UIs with an integer RGBA32 color value.
+If the value is a 32-bit integer, it is guaranteed to be in RGBA32 format, but
+the UI must check the value type and not assume this, to allow for other types
+of color in the future.
+
+"""^^lv2:Markdown .
+
+ui:foregroundColor
+	lv2:documentation """
+
+The foreground color of the host's UI.  The host can pass this as an option so
+that UIs can integrate nicely with the host window around it.
+
+Hosts should pass this as an option to UIs with an integer RGBA32 color value.
+If the value is a 32-bit integer, it is guaranteed to be in RGBA32 format, but
+the UI must check the value type and not assume this, to allow for other types
+of color in the future.
+
+"""^^lv2:Markdown .
+
+ui:parent
+	lv2:documentation """
+
+This feature can be used to pass a parent that the UI should be a child of.
+The format of data pointer of this feature is determined by the UI type, and is
+generally the same type as the LV2UI_Widget that the UI would return.  For
+example, for a ui:X11UI, the parent should be a `Window`.  This is particularly
+useful for embedding, where the parent often must be known at construction time
+for embedding to work correctly.
+
+UIs should not _require_ this feature unless it is necessary for them to work
+at all, but hosts should provide it whenever possible.
+
+"""^^lv2:Markdown .
+
+ui:PortNotification
+	lv2:documentation """
+
+This describes which ports the host must send notifications to the UI about.
+The port must be specific either by index, using the ui:portIndex property, or
+symbol, using the lv2:symbol property.  Since port indices are not guaranteed
+to be stable, using the symbol is recommended, and the inde MUST NOT be used
+except by UIs that are shipped in the same bundle as the corresponding plugin.
+
+"""^^lv2:Markdown .
+
+ui:portNotification
+	lv2:documentation """
+
+Specifies that a UI should receive notifications about changes to a particular
+port's value via LV2UI_Descriptor::port_event().
+
+For example:
+
+    :::turtle
+    eg:ui
+        a ui:X11UI ;
+        ui:portNotification [
+            ui:plugin eg:plugin ;
+            lv2:symbol "gain" ;
+            ui:protocol ui:floatProtocol
+        ] .
+
+"""^^lv2:Markdown .
+
+ui:notifyType
+	lv2:documentation """
+
+Specifies a particular type that the UI should be notified of.
+
+This is useful for message-based ports where several types of data can be
+present, but only some are interesting to the UI.  For example, if UI control
+is multiplexed in the same port as MIDI, this property can be used to ensure
+that only the relevant events are forwarded to the UI, and not potentially high
+frequency MIDI data.
+
+"""^^lv2:Markdown .
+
+ui:resize
+	lv2:documentation """
+
+This feature corresponds to the LV2UI_Resize struct, which should be passed
+with the URI LV2_UI__resize.  This struct may also be provided by the UI as
+extension data using the same URI, in which case it is used by the host to
+request that the UI change its size.
+
+"""^^lv2:Markdown .
+
+ui:portMap
+	lv2:documentation """
+
+This makes it possible to implement and distribute UIs separately from the
+plugin binaries they control.
+
+This feature corresponds to the LV2UI_Port_Index struct, which should be passed
+with the URI LV2_UI__portIndex.
+
+"""^^lv2:Markdown .
+
+ui:portSubscribe
+	lv2:documentation """
+
+This makes it possible for a UI to explicitly request a particular style of
+update from a port at run-time, in a more flexible and powerful way than
+listing subscriptions statically allows.
+
+This feature corresponds to the LV2UI_Port_Subscribe struct, which should be
+passed with the URI LV2_UI__portSubscribe.
+
+"""^^lv2:Markdown .
+
+ui:touch
+	lv2:documentation """
+
+This is useful for automation, so the host can allow the user to take control
+of a port, even if that port would otherwise be automated (much like grabbing a
+physical motorised fader).
+
+It can also be used for MIDI learn or in any other situation where the host
+needs to do something with a particular control and it would be convenient for
+the user to select it directly from the plugin UI.
+
+This feature corresponds to the LV2UI_Touch struct, which should be passed with
+the URI LV2_UI__touch.
+
+"""^^lv2:Markdown .
+
+ui:requestValue
+	lv2:documentation """
+
+This allows a plugin UI to request a new parameter value using the host's UI,
+for example by showing a dialog or integrating with the host's built-in content
+browser.  This should only be used for complex parameter types where the plugin
+UI is not capable of showing the expected native platform or host interface to
+choose a value, such as file path parameters.
+
+This feature corresponds to the LV2UI_Request_Value struct, which should be
+passed with the URI LV2_UI__requestValue.
+
+"""^^lv2:Markdown .
+
+ui:idleInterface
+	lv2:documentation """
+
+To support this feature, the UI should list it as a lv2:optionalFeature or
+lv2:requiredFeature in its data, and also as lv2:extensionData.  When the UI's
+extension_data() is called with this URI (LV2_UI__idleInterface), it should
+return a pointer to an LV2UI_Idle_Interface.
+
+To indicate support, the host should pass a feature to instantiate() with this
+URI, with NULL for data.
+
+"""^^lv2:Markdown .
+
+ui:showInterface
+	lv2:documentation """
+
+This allows UIs to gracefully degrade to separate windows when the host is
+unable to embed the UI widget for whatever reason.  When the UI's
+extension_data() is called with this URI (LV2_UI__showInterface), it should
+return a pointer to an LV2UI_Show_Interface.
+
+"""^^lv2:Markdown .
+
+ui:PortProtocol
+	lv2:documentation """
+
+A PortProtocol MUST define:
+
+Port Type
+:   Which plugin port types the buffer type is valid for.
+
+Feature Data
+:   What data (if any) should be passed in the LV2_Feature.
+
+A PortProtocol for an output port MUST define:
+
+Update Frequency
+:   When the host should call port_event().
+
+Update Format
+:   The format of the data in the buffer passed to port_event().
+
+Options
+:   The format of the options passed to subscribe() and unsubscribe().
+
+A PortProtocol for an input port MUST define:
+
+Write Format
+:   The format of the data in the buffer passed to write_port().
+
+Write Effect
+:   What happens when the UI calls write_port().
+
+For an example, see ui:floatProtocol or ui:peakProtocol.
+
+PortProtocol is a subclass of lv2:Feature, so UIs use lv2:optionalFeature and
+lv2:requiredFeature to specify which PortProtocols they want to use.
+
+"""^^lv2:Markdown .
+
+ui:floatProtocol
+	lv2:documentation """
+
+A protocol for transferring single floating point values.  The rules for this
+protocol are:
+
+Port Type
+:   lv2:ControlPort
+
+Feature Data
+:   None.
+
+Update Frequency
+:   The host SHOULD call port_event() as soon as possible when the port value has
+    changed, but there are no timing guarantees.
+
+Update Format
+:   A single <code>float</code>.
+
+Options
+:   None.
+
+Write Format
+:   A single <code>float</code>.
+
+Write Effect
+:   The host SHOULD set the port to the received value as soon as possible, but
+    there is no guarantee that run() actually sees this value.
+
+"""^^lv2:Markdown .
+
+ui:peakProtocol
+	lv2:documentation """
+
+This port protocol defines a way for the host to send continuous peak
+measurements of the audio signal at a certain port to the UI.  The intended use
+is visualisation, for example an animated meter widget that shows the level of
+the audio input or output.
+
+A contiguous sequence of audio samples for which a peak value has been computed
+is called a _measurement period_.
+
+The rules for this protocol are:
+
+Port Type
+:   lv2:AudioPort
+
+Feature Data
+:   None.
+
+Update Frequency
+:   The host SHOULD call port_event() at regular intervals.  The measurement
+    periods used for calls to port_event() for the same port SHOULD be
+    contiguous (i.e. the measurement period for one call should begin right
+    after the end of the measurement period for the previous call ends) unless
+    the UI has removed and re-added the port subscription between those calls.
+    However, UIs MUST NOT depend on either the regularity of the calls or the
+    contiguity of the measurement periods; hosts may change the call rate or
+    skip calls for performance or other reasons.  Measurement periods for
+    different calls to port_event() for the same port MUST NOT overlap.
+
+Update Format
+:   A single LV2UI_Peak_Data object.
+
+Options
+:   None.
+
+Write Format
+:   None.
+
+Write Effect
+:   None.
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/ui/ui.ttl b/sys/lv2/ui/ui.ttl
index f0444b5a..61f8bcac 100644
--- a/sys/lv2/ui/ui.ttl
+++ b/sys/lv2/ui/ui.ttl
@@ -1,199 +1,132 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
-@prefix owl:  <http://www.w3.org/2002/07/owl#> .
-@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix opts: <http://lv2plug.in/ns/ext/options#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-@prefix ui:   <http://lv2plug.in/ns/extensions/ui#> .
-@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> .
+@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
 
 <http://lv2plug.in/ns/extensions/ui>
 	a owl:Ontology ;
+	rdfs:label "LV2 UI" ;
+	rdfs:comment "User interfaces for LV2 plugins." ;
 	owl:imports <http://lv2plug.in/ns/lv2core> ;
 	rdfs:seeAlso <ui.h> ,
-		<lv2-ui.doap.ttl> ;
-	lv2:documentation """
-<p>This extension is used to create User Interfaces (UIs) for LV2 plugins.</p>
-
-<p>UIs are implemented as an LV2UI_Descriptor loaded via lv2ui_descriptor() in
-a shared library, and are distributed in bundles just like plugins.  See the <a
-href="../../../doc/html/ui_8h.html">API reference</a> for details on the C
-API.</p>
-
-<p>UIs are associated with plugins in data:</p>
-
-<pre class="turtle-code">
-@prefix ui: &lt;http://lv2plug.in/ns/extensions/ui#&gt; .
-
-&lt;http://my.plugin&gt;   ui:ui     &lt;http://my.pluginui&gt; .
-&lt;http://my.pluginui&gt; a         ui:GtkUI ;
-                     ui:binary &lt;myui.so&gt; .
-</pre>
-
-<p>where &lt;http://my.plugin&gt; is the URI of the plugin,
-&lt;http://my.pluginui&gt; is the URI of the plugin UI and &lt;myui.so&gt; is
-the relative URI to the shared object file.</p>
-
-<p>While it is possible to have the plugin UI and the plugin in the same shared
-object file it is probably a good idea to keep them separate so that hosts that
-don't want UIs don't have to load the UI code.  A UI MUST specify its class in
-the RDF data (ui:GtkUI in the above example). The class defines what type the
-UI is, e.g. what graphics toolkit it uses.  Any type of UI class can be defined
-separately from this extension.</p>
-
-<p>It is possible to have multiple UIs for the same plugin, or to have the UI
-for a plugin in a different bundle from the actual plugin - this way people
-other than the plugin author can write plugin UIs independently without editing
-the original plugin bundle.</p>
-
-<p>Note that the process that loads the shared object file containing the UI
-code and the process that loads the shared object file containing the actual
-plugin implementation are not necessarily the same process (and not even
-necessarily on the same machine).  This means that plugin and UI code MUST NOT
-use singletons and global variables and expect them to refer to the same
-objects in the UI and the actual plugin. The function callback interface
-defined in this header is the only method of communication between UIs and
-plugin instances (extensions may define more, though this is discouraged unless
-absolutely necessary since the significant benefits of network transparency and
-serialisability are lost).</p>
-
-<p>UI functionality may be extended via features, much like plugins:</p>
-
-<pre class="turtle-code">
-&lt;http://my.pluginui&gt; lv2:requiredFeature &lt;http://my.feature&gt; .
-&lt;http://my.pluginui&gt; lv2:optionalFeature &lt;http://my.feature&gt; .
-</pre>
-
-<p>The rules for a UI with a required or optional feature are identical to
-those of lv2:Plugin instances: if a UI declares a feature as required, the host
-is NOT allowed to load it unless it supports that feature; and if it does
-support a feature, it MUST pass an appropriate LV2_Feature struct to the UI's
-instantiate() method.  This extension defines several standard features for
-common functionality.</p>
-
-<p>UIs written to this specification do not need to be thread-safe.  All
-functions may only be called in the <q>UI thread</q>.  There is only one UI
-thread (for toolkits, the one the UI main loop runs in).  There is no
-requirement that a <q>UI</q> actually be a graphical widget.</p>
-
-<p>Note that UIs are completely separate from plugins.  From the plugin's
-perspective, control from a UI is indistinguishable from any other control, as
-it all occcurs via ports.</p>
-""" .
+		<ui.meta.ttl> .
 
 ui:UI
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:label "User Interface" ;
-	rdfs:comment "A UI for an LV2 plugin" .
+	rdfs:comment "A UI for an LV2 plugin." .
 
 ui:GtkUI
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf ui:UI ;
 	rdfs:label "GTK2 UI" ;
-	rdfs:comment """A UI where the LV2_Widget is a pointer to a Gtk+ 2.0 compatible GtkWidget, and the host guarantees that the Gtk+ library has been initialised and the Glib main loop is running before a UI of this type is instantiated.""" .
+	rdfs:comment "A UI where the widget is a pointer to a Gtk+ 2.0 GtkWidget." .
 
 ui:Gtk3UI
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf ui:UI ;
 	rdfs:label "GTK3 UI" ;
-	rdfs:comment """A UI where the LV2_Widget is a pointer to a Gtk+ 3.0 compatible GtkWidget, and the host guarantees that the Gtk+ library has been initialised and the Glib main loop is running before a UI of this type is instantiated.""" .
+	rdfs:comment "A UI where the widget is a pointer to a Gtk+ 3.0 GtkWidget." .
 
 ui:Qt4UI
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf ui:UI ;
 	rdfs:label "Qt4 UI" ;
-	rdfs:comment """A UI where the LV2_Widget is a pointer to a Qt4 compatible QWidget, and the host guarantees that the Qt4 library has been initialised and the Qt4 main loop is running before a UI of this type is instantiated.""" .
+	rdfs:comment "A UI where the widget is a pointer to a Qt4 QWidget." .
 
 ui:Qt5UI
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf ui:UI ;
 	rdfs:label "Qt5 UI" ;
-	rdfs:comment """A UI where the LV2_Widget is a pointer to a Qt5 compatible QWidget, and the host guarantees that the Qt5 library has been initialised and the Qt5 main loop is running before a UI of this type is instantiated.""" .
+	rdfs:comment "A UI where the widget is a pointer to a Qt5 QWidget." .
 
 ui:X11UI
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf ui:UI ;
 	rdfs:label "X11 UI" ;
-	rdfs:comment """A UI where the LV2_Widget is an X11 window ID.  Note this is actually an integer, i.e. the LV2_Widget is not a pointer to an X11 window ID, but should be itself taken as an integer value.  This is the native UI type on most POSIX systems.""" .
+	rdfs:comment "A UI where the widget is an X11 Window window ID." .
 
 ui:WindowsUI
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf ui:UI ;
 	rdfs:label "Windows UI" ;
-	rdfs:comment """A UI where the LV2_Widget is a Windows HWND window ID.  Note this is actually an unsigned 32-bit integer, i.e. the LV2_Widget is not a pointer to a HWND but should be interpreted as an HWND itself.  This is the native UI type on Microsoft Windows.""" .
+	rdfs:comment "A UI where the widget is a Windows HWND window ID." .
 
 ui:CocoaUI
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:subClassOf ui:UI ;
 	rdfs:label "Cocoa UI" ;
-	rdfs:comment """A UI where the LV2_Widget is a pointer to a NSView, the basic view type for the Cocoa API (formerly OpenStep).  This is the native UI type on Mac OS X.""" .
+	rdfs:comment "A UI where the widget is a pointer to a NSView." .
 
 ui:ui
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:ObjectProperty ;
 	rdfs:domain lv2:Plugin ;
 	rdfs:range ui:UI ;
 	rdfs:label "user interface" ;
-	rdfs:comment """Relates a plugin to a UI that applies to it.""" .
+	rdfs:comment "Relates a plugin to a UI that applies to it." .
 
 ui:binary
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:ObjectProperty ;
 	owl:sameAs lv2:binary ;
 	owl:deprecated "true"^^xsd:boolean ;
 	rdfs:label "binary" ;
-	rdfs:comment """The shared library a UI resides in.  This property is redundant, new UIs SHOULD use lv2:binary, however hosts MUST still support ui:binary at this time.""" .
+	rdfs:comment "The shared library that a UI resides in." .
 
 ui:makeSONameResident
 	a lv2:Feature ;
 	owl:deprecated "true"^^xsd:boolean ;
-	lv2:documentation """
-<p>DEPRECATED</p>
-
-<p>This feature was intended to support UIs that link against toolkit
-libraries which may not be unloaded during the lifetime of the host.
-This is better achieved by using the appropriate flags when linking the
-UI, e.g. <code>gcc -Wl,-z,nodelete</code>.</p>
-""" .
+	rdfs:label "make SO name resident" ;
+	rdfs:comment "UI binary must not be unloaded." .
 
 ui:noUserResize
 	a lv2:Feature ;
-	lv2:documentation """
-<p>If a UI requires this feature it indicates that it does not make sense
-to let the user resize the main widget, and the host should prevent that.
-This feature may not make sense for all UI types. The data pointer for the
-LV2_Feature for this feature should always be set to NULL.</p>
-""" .
+	rdfs:label "no user resize" ;
+	rdfs:comment "Non-resizable UI." .
 
 ui:fixedSize
 	a lv2:Feature ;
-	lv2:documentation """
-<p>If a UI requires this feature it indicates the same thing as
-ui:noUserResize, and additionally it means that the UI will not resize
-the main widget on its own - it will always remain the same size (e.g. a
-pixmap based GUI). This feature may not make sense for all UI types.
-The data pointer for the LV2_Feature for this feature should always be set
-to NULL.</p>
-""" .
+	rdfs:label "fixed size" ;
+	rdfs:comment "Non-resizable UI that will never resize itself." .
+
+ui:scaleFactor
+	a rdf:Property ,
+		owl:DatatypeProperty ,
+		opts:Option ;
+	rdfs:range xsd:float ;
+	rdfs:label "scale factor" ;
+	rdfs:comment "Scale factor for high resolution screens." .
+
+ui:backgroundColor
+	a rdf:Property ,
+		owl:DatatypeProperty ,
+		opts:Option ;
+	rdfs:label "background color" ;
+	rdfs:comment """The background color of the host's UI.""" .
+
+ui:foregroundColor
+	a rdf:Property ,
+		owl:DatatypeProperty ,
+		opts:Option ;
+	rdfs:label "foreground color" ;
+	rdfs:comment """The foreground color of the host's UI.""" .
 
 ui:parent
 	a lv2:Feature ;
-	lv2:documentation """
-<p>The parent for the UI.</p>
-
-<p>This feature can be used to pass a parent (e.g. a widget, container, canvas,
-etc.) the UI should be a child of.  The format of data pointer of this feature
-is determined by the UI type, and is generally the same type as the LV2_Widget
-the UI would return (e.g. for a GtkUI the data would be a pointer to a
-GtkWidget which is a GtkContainer).  This is particularly useful for
-cross-toolkit embedding, where the parent often must be known at construction
-time for embedding to work correctly.  UIs should not require this feature
-unless it is absolutely necessary for them to work at all.</p>
-""" .
+	rdfs:label "parent" ;
+	rdfs:comment "The parent for a UI." .
 
 ui:PortNotification
 	a rdfs:Class ,
@@ -202,19 +135,10 @@ ui:PortNotification
 		a owl:Restriction ;
 		owl:onProperty ui:plugin ;
 		owl:cardinality 1 ;
-		rdfs:comment "A PortNotification MUST have exactly one ui:plugin." ;
+		rdfs:comment "A PortNotification MUST have exactly one ui:plugin."
 	] ;
-	lv2:documentation """
-<p>A port notification.  This describes which ports the host must send
-notifications to the UI about.  The port can be specific by index, using the
-ui:portIndex property, or symbol, using the lv2:symbol property.  Since port
-indices are not guaranteed to be stable between different revisions (or even
-instantiations) of a plugin, symbol is recommended, and index may only be used
-by UIs shipped in the same bundle as the plugin.</p>
-
-<p>A ui:PortNotification MUST have either a ui:portIndex or a lv2:symbol to
-indicate which port it refers to.</p>
-""" .
+	rdfs:label "Port Notification" ;
+	rdfs:comment "A description of port updates that a host must send a UI." .
 
 ui:portNotification
 	a rdf:Property ,
@@ -222,21 +146,7 @@ ui:portNotification
 	rdfs:domain ui:UI ;
 	rdfs:range ui:PortNotification ;
 	rdfs:label "port notification" ;
-	lv2:documentation """
-<p>Indicates that a UI should receive notification (via
-LV2UI_Descriptor::port_event()) when a particular port's value changes.</p>
-
-<p>For example:</p>
-<pre class="turtle-code">
-eg:ui
-    a ui:GtkUI ;
-    ui:portNotification [
-        ui:plugin eg:plugin ;
-        lv2:symbol "gain" ;
-        ui:protocol ui:floatProtocol
-    ] .
-</pre>
-""" .
+	rdfs:comment "Specifies a port notification that is required by a UI." .
 
 ui:plugin
 	a rdf:Property ,
@@ -255,99 +165,66 @@ ui:portIndex
 	rdfs:comment "The index of the port a portNotification applies to." .
 
 ui:notifyType
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:ObjectProperty ;
 	rdfs:domain ui:PortNotification ;
 	rdfs:label "notify type" ;
-	lv2:documentation """
-<p>Indicates a particular type that the UI should be notified of.  In the case
-of ports where several types of data can be present (e.g. event ports), this
-can be used to indicate that only a particular type of data should cause
-notification.  This is useful where port traffic is very dense, but only a
-certain small number of events are actually of interest to the UI.</p>
-""" .
+	rdfs:comment "A particular type that the UI should be notified of." .
 
 ui:resize
 	a lv2:Feature ,
 		lv2:ExtensionData ;
-	lv2:documentation """
-<p>A feature that allows the UI to notify the host about its current size, or
-request a size change.  This feature corresponds to the LV2UI_Resize struct,
-which should be passed with the URI LV2_UI__resize.  This struct may also be
-provided by the UI as extension data using the same URI, in which case it is
-used by the host to request that the UI change its size.</p>
-""" .
+	rdfs:label "resize" ;
+	rdfs:comment """A feature that control of, and notifications about, a UI's size.""" .
 
 ui:portMap
 	a lv2:Feature ;
-	lv2:documentation """
-<p>A feature for accessing the index of a port by symbol.  This makes it
-possible to implement and distribute UIs separately from the plugin binaries
-they control.  This feature corresponds to the LV2UI_Port_Index struct, which
-should be passed with the URI LV2_UI__portIndex.</p>
-""" .
+	rdfs:label "port map" ;
+	rdfs:comment "A feature for accessing the index of a port by symbol." .
 
 ui:portSubscribe
 	a lv2:Feature ;
-	lv2:documentation """
-<p>A feature for dynamically subscribing to updates from a port.  This makes it
-possible for a UI to explicitly request a particular style of update from a
-port at run-time, in a more flexible and powerful way than listing
-subscriptions statically allows.  This feature corresponds to the
-LV2UI_Port_Subscribe struct, which should be passed with the URI
-LV2_UI__portSubscribe.</p>
-""" .
+	rdfs:label "port subscribe" ;
+	rdfs:comment "A feature for dynamically subscribing to updates from a port." .
 
 ui:touch
 	a lv2:Feature ;
-	lv2:documentation """
-<p>A feature to notify the host that the user has grabbed a particular port
-control.  This is useful for automation, so the host can allow the user to take
-control of a port, even if that port would otherwise be automated (much like
-grabbing a physical morotised fader).  It can also be used for MIDI learn or in
-any other situation where the host needs to do something with a particular
-control and it would be convenient for the user to select it directly from the
-plugin UI.  This feature corresponds to the LV2UI_Touch struct, which
-should be passed with the URI LV2_UI__touch.</p>
-""" .
+	rdfs:label "touch" ;
+	rdfs:comment "A feature to notify that the user has grabbed a port control." .
+
+ui:requestValue
+	a lv2:Feature ;
+	rdfs:label "request value" ;
+	rdfs:comment "A feature to request a parameter value from the user via the host." .
 
 ui:idleInterface
 	a lv2:Feature ,
 		lv2:ExtensionData ;
-	lv2:documentation """
-<p>A feature that provides a callback for the host to call rapidly to drive the
-UI.  To support this feature, the UI should list it as a lv2:optionalFeature or
-lv2:requiredFeature in its data, and also as lv2:extensionData.  When the UI's
-extension_data() is called with this URI (LV2_UI__idleInterface), it should
-return a pointer to an LV2UI_Idle_Interface.</p>
-
-<p>To indicate support, the host should pass a feature to instantiate() with
-this URI, with NULL for data.</p>
-""" .
+	rdfs:label "idle interface" ;
+	rdfs:comment "A feature that provides a callback for the host to drive the UI." .
 
 ui:showInterface
 	a lv2:ExtensionData ;
-	lv2:documentation """
-<p>An interface for showing and hiding a window for a UI.  This allows UIs to
-gracefully degrade to separate windows when the host is unable to embed the UI
-widget for whatever reason.  When the UI's extension_data() is called with this
-URI (LV2_UI__showInterface), it should return a pointer to an
-LV2UI_Show_Interface.</p>
-""" .
+	rdfs:label "show interface" ;
+	rdfs:comment "An interface for showing and hiding a window for a UI." .
 
 ui:windowTitle
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:DatatypeProperty ;
 	rdfs:range xsd:string ;
 	rdfs:label "window title" ;
 	rdfs:comment "The title for the window shown by LV2UI_Show_Interface." .
 
 ui:updateRate
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:DatatypeProperty ;
 	rdfs:range xsd:float ;
 	rdfs:label "update rate" ;
 	rdfs:comment "The target rate, in Hz, to send updates to the UI." .
 
 ui:protocol
-	a rdf:Property ;
+	a rdf:Property ,
+		owl:ObjectProperty ;
 	rdfs:domain ui:PortNotification ;
 	rdfs:range ui:PortProtocol ;
 	rdfs:label "protocol" ;
@@ -357,107 +234,15 @@ ui:PortProtocol
 	a rdfs:Class ;
 	rdfs:subClassOf lv2:Feature ;
 	rdfs:label "Port Protocol" ;
-	lv2:documentation """
-<p>A PortProtocol defines a method to communicate port data between a UI and
-plugin.</p>
-
-<p>Any PortProtocol MUST define:</p>
-<table>
-<tr><th>Port Type</th>
-    <td>Which plugin port types the buffer type is valid for.</td></tr>
-<tr><th>Feature Data</th>
-    <td>What data (if any) should be passed in the LV2_Feature.</td></tr>
-</table>
-
-<p>Any PortProtocol for an output port MUST define:</p>
-<table>
-<tr><th>Update Frequency</th>
-    <td>When the host should call port_event().</td></tr>
-<tr><th>Update Format</th>
-    <td>The format of the data in the buffer passed to port_event().</td></tr>
-<tr><th>Options</th>
-    <td>The format of the options passed to subscribe() and unsubscribe().</td>
-</tr></table>
-
-<p>Any PortProtocol for an input port MUST define:</p>
-<table>
-<tr><th>Write Format</th>
-    <td>The format of the data in the buffer passed to write_port().</td></tr>
-<tr><th>Write Effect</th>
-    <td>What happens when the UI calls write_port().</td></tr>
-</table>
-
-<p>For an example, see ui:floatProtocol or ui:peakProtocol.
-</p>
-
-<p>PortProtocol is a subclass of lv2:Feature, so UIs use lv2:optionalFeature and
-lv2:requiredFeature to specify which PortProtocols they want to use.
-</p>
-""" .
+	rdfs:comment "A method to communicate port data between a UI and plugin." .
 
 ui:floatProtocol
 	a ui:PortProtocol ;
-	rdfs:label "floating point value" ;
-	lv2:documentation """
-
-<p>A protocol for transferring single floating point values.  The rules for
-this protocol are:</p>
-<table>
-<tr><th>Port Type</th>
-    <td>lv2:ControlPort</td></tr>
-<tr><th>Feature Data</th>
-    <td>None.</td></tr>
-<tr><th>Update Frequency</th>
-    <td>The host SHOULD call port_event() as soon as possible when the port
-    value has changed, but there are no timing guarantees.</td></tr>
-<tr><th>Update Format</th>
-    <td>A single <code>float</code>.</td></tr>
-<tr><th>Options</th>
-    <td>None.</td></tr>
-<tr><th>Write Format</th>
-    <td>A single <code>float</code>.</td></tr>
-<tr><th>Write Effect</th>
-    <td>The host SHOULD set the port to the received value as soon as possible,
-    but there is no guarantee that run() actually sees this value.</td></tr>
-</table>
-""" .
+	rdfs:label "float protocol" ;
+	rdfs:comment "A protocol for transferring single floating point values." .
 
 ui:peakProtocol
 	a ui:PortProtocol ;
-	rdfs:label "peak measurement for a period of audio" ;
-	lv2:documentation """
-<p>This port protocol defines a way for the host to send continuous peak
-measurements of the audio signal at a certain port to the UI.  The
-intended use is visualisation, e.g. an animated meter widget that shows
-the level of the audio input or output.</p>
-
-<p>A contiguous sequence of audio samples for which a peak value has been
-computed is called a <em>measurement period</em>.</p>
-
-<p>The rules for this protocol are:</p>
-<table>
-<tr><th>Port Type</th>
-    <td>lv2:AudioPort</td></tr>
-<tr><th>Feature Data</th>
-    <td>None.</td></tr>
-<tr><th>Update Frequency</th>
-    <td>The host SHOULD call port_event() at regular intervals.  The
-    measurement periods used for calls to port_event() for the same port SHOULD
-    be contiguous (i.e. the measurement period for one call should begin right
-    after the end of the measurement period for the previous call ends) unless
-    the UI has removed and re-added the port subscription between those calls.
-    However, UIs MUST NOT depend on either the regularity of the calls or the
-    contiguity of the measurement periods; hosts may change the call rate or
-    skip calls for performance or other reasons.  Measurement periods for
-    different calls to port_event() for the same port MUST NOT
-    overlap.</td></tr>
-<tr><th>Update Format</th>
-    <td>A single LV2UI_Peak_Data object.</td></tr>
-<tr><th>Options</th>
-    <td>None.</td></tr>
-<tr><th>Write Format</th>
-    <td>None.</td></tr>
-<tr><th>Write Effect</th>
-    <td>None.</td></tr>
-</table>
-""" .
+	rdfs:label "peak protocol" ;
+	rdfs:comment "A protocol for sending continuous peak measurements of an audio signal." .
+
diff --git a/sys/lv2/units/NEWS b/sys/lv2/units/NEWS
deleted file mode 100644
index 4780e3f8..00000000
--- a/sys/lv2/units/NEWS
+++ /dev/null
@@ -1,58 +0,0 @@
-units (5.12) stable;
-
-  * Remove overly restrictive domain from units:unit.
-  * Fix outdated port description in documentation.
-
- -- None <None>  Sun, 03 Feb 2019 00:00:00 +0000
-
-units (5.10) stable;
-
-  * Add lv2:Parameter to domain of units:unit.
-  * Fix non-existent port type in examples.
-
- -- None <None>  Tue, 07 Apr 2015 00:00:00 +0000
-
-units (5.8) stable;
-
-  * Remove units:name in favour of rdfs:label.
-  * Use consistent label style.
-
- -- None <None>  Sun, 14 Oct 2012 00:00:00 +0000
-
-units (5.6) stable;
-
-  * Add header of URI defines.
-  * Add unit for audio frames.
-  * Merge with unified LV2 package.
-
- -- None <None>  Tue, 17 Apr 2012 00:00:00 +0000
-
-units (5.4) stable;
-
-  * Define used but undefined resources (units:name, units:render, units:symbol,
-    units:Conversion, units:conversion, units:prefixConversion, units:to, and
-    units:factor).
-  * Update packaging.
-  * Make units.ttl a valid OWL 2 DL ontology.
-  * Improve documentation.
-
- -- None <None>  Mon, 21 Nov 2011 00:00:00 +0000
-
-units (5.2) stable;
-
-  * Add build system (for installation).
-  * Convert documentation to HTML and use lv2:documentation.
-
- -- None <None>  Tue, 05 Oct 2010 00:00:00 +0000
-
-units (5.0) stable;
-
-  * Improve documentation.
-  * Initial release.
-  * Define used but undefined resources (units:name, units:render, units:symbol,
-    units:Conversion, units:conversion, units:prefixConversion, units:to, and
-    units:factor).
-  * Update packaging.
-
- -- None <None>  Tue, 05 Oct 2010 00:00:00 +0000
-
diff --git a/sys/lv2/units/manifest.ttl b/sys/lv2/units/manifest.ttl
index ada802a2..c6c9286b 100644
--- a/sys/lv2/units/manifest.ttl
+++ b/sys/lv2/units/manifest.ttl
@@ -1,4 +1,4 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/extensions/units>
diff --git a/sys/lv2/units/units.h b/sys/lv2/units/units.h
index 1debf60b..caea38df 100644
--- a/sys/lv2/units/units.h
+++ b/sys/lv2/units/units.h
@@ -16,6 +16,7 @@
 
 /**
    @defgroup units Units
+   @ingroup lv2
 
    Units for LV2 values, see <http://lv2plug.in/ns/extensions/units> for
    details.
@@ -29,38 +30,38 @@
 #define LV2_UNITS_URI    "http://lv2plug.in/ns/extensions/units"  ///< http://lv2plug.in/ns/extensions/units
 #define LV2_UNITS_PREFIX LV2_UNITS_URI "#"                        ///< http://lv2plug.in/ns/extensions/units#
 
-#define LV2_UNITS__Conversion       LV2_UNITS_PREFIX "Conversion"        ///< http://lv2plug.in/ns/ext/units#Conversion
-#define LV2_UNITS__Unit             LV2_UNITS_PREFIX "Unit"              ///< http://lv2plug.in/ns/ext/units#Unit
-#define LV2_UNITS__bar              LV2_UNITS_PREFIX "bar"               ///< http://lv2plug.in/ns/ext/units#bar
-#define LV2_UNITS__beat             LV2_UNITS_PREFIX "beat"              ///< http://lv2plug.in/ns/ext/units#beat
-#define LV2_UNITS__bpm              LV2_UNITS_PREFIX "bpm"               ///< http://lv2plug.in/ns/ext/units#bpm
-#define LV2_UNITS__cent             LV2_UNITS_PREFIX "cent"              ///< http://lv2plug.in/ns/ext/units#cent
-#define LV2_UNITS__cm               LV2_UNITS_PREFIX "cm"                ///< http://lv2plug.in/ns/ext/units#cm
-#define LV2_UNITS__coef             LV2_UNITS_PREFIX "coef"              ///< http://lv2plug.in/ns/ext/units#coef
-#define LV2_UNITS__conversion       LV2_UNITS_PREFIX "conversion"        ///< http://lv2plug.in/ns/ext/units#conversion
-#define LV2_UNITS__db               LV2_UNITS_PREFIX "db"                ///< http://lv2plug.in/ns/ext/units#db
-#define LV2_UNITS__degree           LV2_UNITS_PREFIX "degree"            ///< http://lv2plug.in/ns/ext/units#degree
-#define LV2_UNITS__frame            LV2_UNITS_PREFIX "frame"             ///< http://lv2plug.in/ns/ext/units#frame
-#define LV2_UNITS__hz               LV2_UNITS_PREFIX "hz"                ///< http://lv2plug.in/ns/ext/units#hz
-#define LV2_UNITS__inch             LV2_UNITS_PREFIX "inch"              ///< http://lv2plug.in/ns/ext/units#inch
-#define LV2_UNITS__khz              LV2_UNITS_PREFIX "khz"               ///< http://lv2plug.in/ns/ext/units#khz
-#define LV2_UNITS__km               LV2_UNITS_PREFIX "km"                ///< http://lv2plug.in/ns/ext/units#km
-#define LV2_UNITS__m                LV2_UNITS_PREFIX "m"                 ///< http://lv2plug.in/ns/ext/units#m
-#define LV2_UNITS__mhz              LV2_UNITS_PREFIX "mhz"               ///< http://lv2plug.in/ns/ext/units#mhz
-#define LV2_UNITS__midiNote         LV2_UNITS_PREFIX "midiNote"          ///< http://lv2plug.in/ns/ext/units#midiNote
-#define LV2_UNITS__mile             LV2_UNITS_PREFIX "mile"              ///< http://lv2plug.in/ns/ext/units#mile
-#define LV2_UNITS__min              LV2_UNITS_PREFIX "min"               ///< http://lv2plug.in/ns/ext/units#min
-#define LV2_UNITS__mm               LV2_UNITS_PREFIX "mm"                ///< http://lv2plug.in/ns/ext/units#mm
-#define LV2_UNITS__ms               LV2_UNITS_PREFIX "ms"                ///< http://lv2plug.in/ns/ext/units#ms
-#define LV2_UNITS__name             LV2_UNITS_PREFIX "name"              ///< http://lv2plug.in/ns/ext/units#name
-#define LV2_UNITS__oct              LV2_UNITS_PREFIX "oct"               ///< http://lv2plug.in/ns/ext/units#oct
-#define LV2_UNITS__pc               LV2_UNITS_PREFIX "pc"                ///< http://lv2plug.in/ns/ext/units#pc
-#define LV2_UNITS__prefixConversion LV2_UNITS_PREFIX "prefixConversion"  ///< http://lv2plug.in/ns/ext/units#prefixConversion
-#define LV2_UNITS__render           LV2_UNITS_PREFIX "render"            ///< http://lv2plug.in/ns/ext/units#render
-#define LV2_UNITS__s                LV2_UNITS_PREFIX "s"                 ///< http://lv2plug.in/ns/ext/units#s
-#define LV2_UNITS__semitone12TET    LV2_UNITS_PREFIX "semitone12TET"     ///< http://lv2plug.in/ns/ext/units#semitone12TET
-#define LV2_UNITS__symbol           LV2_UNITS_PREFIX "symbol"            ///< http://lv2plug.in/ns/ext/units#symbol
-#define LV2_UNITS__unit             LV2_UNITS_PREFIX "unit"              ///< http://lv2plug.in/ns/ext/units#unit
+#define LV2_UNITS__Conversion       LV2_UNITS_PREFIX "Conversion"        ///< http://lv2plug.in/ns/extensions/units#Conversion
+#define LV2_UNITS__Unit             LV2_UNITS_PREFIX "Unit"              ///< http://lv2plug.in/ns/extensions/units#Unit
+#define LV2_UNITS__bar              LV2_UNITS_PREFIX "bar"               ///< http://lv2plug.in/ns/extensions/units#bar
+#define LV2_UNITS__beat             LV2_UNITS_PREFIX "beat"              ///< http://lv2plug.in/ns/extensions/units#beat
+#define LV2_UNITS__bpm              LV2_UNITS_PREFIX "bpm"               ///< http://lv2plug.in/ns/extensions/units#bpm
+#define LV2_UNITS__cent             LV2_UNITS_PREFIX "cent"              ///< http://lv2plug.in/ns/extensions/units#cent
+#define LV2_UNITS__cm               LV2_UNITS_PREFIX "cm"                ///< http://lv2plug.in/ns/extensions/units#cm
+#define LV2_UNITS__coef             LV2_UNITS_PREFIX "coef"              ///< http://lv2plug.in/ns/extensions/units#coef
+#define LV2_UNITS__conversion       LV2_UNITS_PREFIX "conversion"        ///< http://lv2plug.in/ns/extensions/units#conversion
+#define LV2_UNITS__db               LV2_UNITS_PREFIX "db"                ///< http://lv2plug.in/ns/extensions/units#db
+#define LV2_UNITS__degree           LV2_UNITS_PREFIX "degree"            ///< http://lv2plug.in/ns/extensions/units#degree
+#define LV2_UNITS__frame            LV2_UNITS_PREFIX "frame"             ///< http://lv2plug.in/ns/extensions/units#frame
+#define LV2_UNITS__hz               LV2_UNITS_PREFIX "hz"                ///< http://lv2plug.in/ns/extensions/units#hz
+#define LV2_UNITS__inch             LV2_UNITS_PREFIX "inch"              ///< http://lv2plug.in/ns/extensions/units#inch
+#define LV2_UNITS__khz              LV2_UNITS_PREFIX "khz"               ///< http://lv2plug.in/ns/extensions/units#khz
+#define LV2_UNITS__km               LV2_UNITS_PREFIX "km"                ///< http://lv2plug.in/ns/extensions/units#km
+#define LV2_UNITS__m                LV2_UNITS_PREFIX "m"                 ///< http://lv2plug.in/ns/extensions/units#m
+#define LV2_UNITS__mhz              LV2_UNITS_PREFIX "mhz"               ///< http://lv2plug.in/ns/extensions/units#mhz
+#define LV2_UNITS__midiNote         LV2_UNITS_PREFIX "midiNote"          ///< http://lv2plug.in/ns/extensions/units#midiNote
+#define LV2_UNITS__mile             LV2_UNITS_PREFIX "mile"              ///< http://lv2plug.in/ns/extensions/units#mile
+#define LV2_UNITS__min              LV2_UNITS_PREFIX "min"               ///< http://lv2plug.in/ns/extensions/units#min
+#define LV2_UNITS__mm               LV2_UNITS_PREFIX "mm"                ///< http://lv2plug.in/ns/extensions/units#mm
+#define LV2_UNITS__ms               LV2_UNITS_PREFIX "ms"                ///< http://lv2plug.in/ns/extensions/units#ms
+#define LV2_UNITS__name             LV2_UNITS_PREFIX "name"              ///< http://lv2plug.in/ns/extensions/units#name
+#define LV2_UNITS__oct              LV2_UNITS_PREFIX "oct"               ///< http://lv2plug.in/ns/extensions/units#oct
+#define LV2_UNITS__pc               LV2_UNITS_PREFIX "pc"                ///< http://lv2plug.in/ns/extensions/units#pc
+#define LV2_UNITS__prefixConversion LV2_UNITS_PREFIX "prefixConversion"  ///< http://lv2plug.in/ns/extensions/units#prefixConversion
+#define LV2_UNITS__render           LV2_UNITS_PREFIX "render"            ///< http://lv2plug.in/ns/extensions/units#render
+#define LV2_UNITS__s                LV2_UNITS_PREFIX "s"                 ///< http://lv2plug.in/ns/extensions/units#s
+#define LV2_UNITS__semitone12TET    LV2_UNITS_PREFIX "semitone12TET"     ///< http://lv2plug.in/ns/extensions/units#semitone12TET
+#define LV2_UNITS__symbol           LV2_UNITS_PREFIX "symbol"            ///< http://lv2plug.in/ns/extensions/units#symbol
+#define LV2_UNITS__unit             LV2_UNITS_PREFIX "unit"              ///< http://lv2plug.in/ns/extensions/units#unit
 
 #endif  /* LV2_UNITS_H */
 
diff --git a/sys/lv2/units/lv2-units.doap.ttl b/sys/lv2/units/units.meta.ttl
similarity index 70%
rename from sys/lv2/units/lv2-units.doap.ttl
rename to sys/lv2/units/units.meta.ttl
index 076fef66..bb40547b 100644
--- a/sys/lv2/units/lv2-units.doap.ttl
+++ b/sys/lv2/units/units.meta.ttl
@@ -1,7 +1,9 @@
 @prefix dcs: <http://ontologi.es/doap-changeset#> .
 @prefix doap: <http://usefulinc.com/ns/doap#> .
 @prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix units: <http://lv2plug.in/ns/extensions/units#> .
 
 <http://lv2plug.in/ns/extensions/units>
 	a doap:Project ;
@@ -106,4 +108,47 @@
 		]
 	] ;
 	doap:developer <http://plugin.org.uk/swh.xrdf#me> ;
-	doap:maintainer <http://drobilla.net/drobilla#me> .
+	doap:maintainer <http://drobilla.net/drobilla#me> ;
+	lv2:documentation """
+
+This is a vocabulary for units typically used for control values in audio
+processing.
+
+For example, to say that a gain control is in decibels:
+
+    :::turtle
+    @prefix units: &lt;http://lv2plug.in/ns/extensions/units#&gt; .
+    @prefix eg:    &lt;http://example.org/&gt; .
+
+    eg:plugin lv2:port [
+        a            lv2:ControlPort , lv2:InputPort ;
+        lv2:index    0 ;
+        lv2:symbol   "gain" ;
+        lv2:name     "Gain" ;
+        units:unit   units:db
+    ] .
+
+Using the same form, plugins may also specify one-off units inline, to give
+better display hints to hosts:
+
+    :::turtle
+    eg:plugin lv2:port [
+        a            lv2:ControlPort , lv2:InputPort ;
+        lv2:index    0 ;
+        lv2:symbol   "frob" ;
+        lv2:name     "frob level" ;
+        units:unit [
+            a            units:Unit ;
+            rdfs:label   "frobnication" ;
+            units:symbol "fr" ;
+            units:render "%f f"
+        ]
+    ] .
+
+It is also possible to define conversions between various units, which makes it
+possible for hosts to automatically convert between units where possible.  The
+units defined in this extension include conversion definitions where it makes
+sense to do so.
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/units/units.ttl b/sys/lv2/units/units.ttl
index aaae520c..959c0639 100644
--- a/sys/lv2/units/units.ttl
+++ b/sys/lv2/units/units.ttl
@@ -1,60 +1,21 @@
-@prefix lv2:   <http://lv2plug.in/ns/lv2core#> .
-@prefix owl:   <http://www.w3.org/2002/07/owl#> .
-@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
-@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 @prefix units: <http://lv2plug.in/ns/extensions/units#> .
-@prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
 
 <http://lv2plug.in/ns/extensions/units>
 	a owl:Ontology ;
-	owl:imports <http://lv2plug.in/ns/lv2core> ;
+	rdfs:label "LV2 Units" ;
+	rdfs:comment "Units for LV2 values." ;
 	rdfs:seeAlso <units.h> ,
-		<lv2-units.doap.ttl> ;
-	lv2:documentation """
-<p>This vocabulary defines a number of units for use in audio processing.</p>
-
-<p>For example, to say that a gain port's value is in decibels (units:db)</p>
-<pre class="turtle-code">
-@prefix units: &lt;http://lv2plug.in/ns/extensions/units#&gt; .
-@prefix eg:    &lt;http://example.org/&gt; .
-
-eg:plugin lv2:port [
-    a            lv2:ControlPort , lv2:InputPort ;
-    lv2:index    0 ;
-    lv2:symbol   "gain" ;
-    lv2:name     "gain" ;
-    units:unit   units:db
-] .
-</pre>
-
-<p>Using the same form, plugins may also specify one-off units inline, to give
-better display hints to hosts:</p>
-<pre class="turtle-code">
-eg:plugin lv2:port [
-    a            lv2:ControlPort , lv2:InputPort ;
-    lv2:index    0 ;
-    lv2:symbol   "frob" ;
-    lv2:name     "frob level" ;
-    units:unit [
-        a            units:Unit ;
-        rdfs:label   "frobnication" ;
-        units:symbol "fr" ;
-        units:render "%f f"
-    ]
-] .
-</pre>
-
-<p>It is also possible to define conversions between various units, which makes
-it possible for hosts to automatically and generically convert from a given
-unit to a desired unit.  The units defined in this extension include conversion
-definitions where it makes sense to do so.</p>
-""" .
+		<units.meta.ttl> .
 
 units:Unit
 	a rdfs:Class ,
 		owl:Class ;
 	rdfs:label "Unit" ;
-	rdfs:comment "A unit for LV2 port data" .
+	rdfs:comment "A unit for a control value." .
 
 units:unit
 	a rdf:Property ,
@@ -69,7 +30,7 @@ units:render
 	rdfs:label "unit format string" ;
 	rdfs:domain units:Unit ;
 	rdfs:range xsd:string ;
-	rdfs:comment """A printf format string for rendering a value (eg. "%f dB").""" .
+	rdfs:comment """A printf format string for rendering a value (e.g., "%f dB").""" .
 
 units:symbol
 	a rdf:Property ,
@@ -77,7 +38,7 @@ units:symbol
 	rdfs:label "unit symbol" ;
 	rdfs:domain units:Unit ;
 	rdfs:range xsd:string ;
-	rdfs:comment "The abbreviated symbol for the unit (e.g. dB)." .
+	rdfs:comment """The abbreviated symbol for this unit (e.g., "dB").""" .
 
 units:Conversion
 	a rdfs:Class ,
@@ -106,7 +67,7 @@ units:prefixConversion
 	rdfs:domain units:Unit ;
 	rdfs:range units:Conversion ;
 	rdfs:label "prefix conversion" ;
-	rdfs:comment """A conversion from this unit to the same unit but with a different SI prefix (e.g. Hz to kHz).""" .
+	rdfs:comment "A conversion from this unit to another with the same base but a different prefix." .
 
 units:to
 	a rdf:Property ,
@@ -121,7 +82,7 @@ units:factor
 		owl:DatatypeProperty ;
 	rdfs:domain units:Conversion ;
 	rdfs:label "conversion factor" ;
-	rdfs:comment """The factor to multiply the source value by in order to convert to the target unit.""" .
+	rdfs:comment "The factor to multiply the source value by in order to convert to the target unit." .
 
 units:s
 	a units:Unit ;
@@ -130,6 +91,7 @@ units:s
 		units:to units:min
 	] ;
 	rdfs:label "seconds" ;
+	rdfs:comment "Seconds, the SI base unit for time." ;
 	units:prefixConversion [
 		units:factor 1000 ;
 		units:to units:ms
@@ -140,6 +102,7 @@ units:s
 units:ms
 	a units:Unit ;
 	rdfs:label "milliseconds" ;
+	rdfs:comment "Milliseconds (thousandths of seconds)." ;
 	units:prefixConversion [
 		units:factor 0.001 ;
 		units:to units:s
@@ -154,24 +117,28 @@ units:min
 		units:to units:s
 	] ;
 	rdfs:label "minutes" ;
+	rdfs:comment "Minutes (60s of seconds and 60ths of an hour)." ;
 	units:render "%f mins" ;
 	units:symbol "min" .
 
 units:bar
 	a units:Unit ;
 	rdfs:label "bars" ;
+	rdfs:comment "Musical bars or measures." ;
 	units:render "%f bars" ;
 	units:symbol "bars" .
 
 units:beat
 	a units:Unit ;
 	rdfs:label "beats" ;
+	rdfs:comment "Musical beats." ;
 	units:render "%f beats" ;
 	units:symbol "beats" .
 
 units:frame
 	a units:Unit ;
 	rdfs:label "audio frames" ;
+	rdfs:comment "Audio frames or samples." ;
 	units:render "%f frames" ;
 	units:symbol "frames" .
 
@@ -182,6 +149,7 @@ units:m
 		units:to units:inch
 	] ;
 	rdfs:label "metres" ;
+	rdfs:comment "Metres, the SI base unit for length." ;
 	units:prefixConversion [
 		units:factor 100 ;
 		units:to units:cm
@@ -202,6 +170,7 @@ units:cm
 		units:to units:inch
 	] ;
 	rdfs:label "centimetres" ;
+	rdfs:comment "Centimetres (hundredths of metres)." ;
 	units:prefixConversion [
 		units:factor 0.01 ;
 		units:to units:m
@@ -222,6 +191,7 @@ units:mm
 		units:to units:inch
 	] ;
 	rdfs:label "millimetres" ;
+	rdfs:comment "Millimetres (thousandths of metres)." ;
 	units:prefixConversion [
 		units:factor 0.001 ;
 		units:to units:m
@@ -242,6 +212,7 @@ units:km
 		units:to units:mile
 	] ;
 	rdfs:label "kilometres" ;
+	rdfs:comment "Kilometres (thousands of metres)." ;
 	units:prefixConversion [
 		units:factor 1000 ;
 		units:to units:m
@@ -258,26 +229,29 @@ units:km
 units:inch
 	a units:Unit ;
 	units:conversion [
-		units:factor 2.54 ;
-		units:to units:cm
+		units:factor 0.0254 ;
+		units:to units:m
 	] ;
 	rdfs:label "inches" ;
-	units:render """%f\"""" ;
+	rdfs:comment "An inch, defined as exactly 0.0254 metres." ;
+	units:render "%f\"" ;
 	units:symbol "in" .
 
 units:mile
 	a units:Unit ;
 	units:conversion [
-		units:factor 1.6093 ;
-		units:to units:km
+		units:factor 1609.344 ;
+		units:to units:m
 	] ;
 	rdfs:label "miles" ;
+	rdfs:comment "A mile, defined as exactly 1609.344 metres." ;
 	units:render "%f mi" ;
 	units:symbol "mi" .
 
 units:db
 	a units:Unit ;
 	rdfs:label "decibels" ;
+	rdfs:comment "Decibels, a logarithmic relative unit where 0 is unity." ;
 	units:render "%f dB" ;
 	units:symbol "dB" .
 
@@ -288,6 +262,7 @@ units:pc
 		units:to units:coef
 	] ;
 	rdfs:label "percent" ;
+	rdfs:comment "Percentage, a ratio as a fraction of 100." ;
 	units:render "%f%%" ;
 	units:symbol "%" .
 
@@ -298,12 +273,14 @@ units:coef
 		units:to units:pc
 	] ;
 	rdfs:label "coefficient" ;
+	rdfs:comment "A scale coefficient where 1 is unity, or 100 percent." ;
 	units:render "* %f" ;
 	units:symbol "" .
 
 units:hz
 	a units:Unit ;
 	rdfs:label "hertz" ;
+	rdfs:comment "Hertz, or inverse seconds, the SI derived unit for frequency." ;
 	units:prefixConversion [
 		units:factor 0.001 ;
 		units:to units:khz
@@ -317,6 +294,7 @@ units:hz
 units:khz
 	a units:Unit ;
 	rdfs:label "kilohertz" ;
+	rdfs:comment "Kilohertz (thousands of Hertz)." ;
 	units:prefixConversion [
 		units:factor 1000 ;
 		units:to units:hz
@@ -330,6 +308,7 @@ units:khz
 units:mhz
 	a units:Unit ;
 	rdfs:label "megahertz" ;
+	rdfs:comment "Megahertz (millions of Hertz)." ;
 	units:prefixConversion [
 		units:factor 1000000 ;
 		units:to units:hz
@@ -343,6 +322,7 @@ units:mhz
 units:bpm
 	a units:Unit ;
 	rdfs:label "beats per minute" ;
+	rdfs:comment "Beats Per Minute (BPM), the standard unit for musical tempo." ;
 	units:prefixConversion [
 		units:factor 0.0166666666 ;
 		units:to units:hz
@@ -357,6 +337,7 @@ units:oct
 		units:to units:semitone12TET
 	] ;
 	rdfs:label "octaves" ;
+	rdfs:comment "Octaves, relative musical pitch where +1 octave doubles the frequency." ;
 	units:render "%f octaves" ;
 	units:symbol "oct" .
 
@@ -367,6 +348,7 @@ units:cent
 		units:to units:semitone12TET
 	] ;
 	rdfs:label "cents" ;
+	rdfs:comment "Cents (hundredths of semitones)." ;
 	units:render "%f ct" ;
 	units:symbol "ct" .
 
@@ -377,17 +359,21 @@ units:semitone12TET
 		units:to units:oct
 	] ;
 	rdfs:label "semitones" ;
+	rdfs:comment "A semitone in the 12-tone equal temperament scale." ;
 	units:render "%f semi" ;
 	units:symbol "semi" .
 
 units:degree
 	a units:Unit ;
 	rdfs:label "degrees" ;
+	rdfs:comment "An angle where 360 degrees is one full rotation." ;
 	units:render "%f deg" ;
 	units:symbol "deg" .
 
 units:midiNote
 	a units:Unit ;
 	rdfs:label "MIDI note" ;
+	rdfs:comment "A MIDI note number." ;
 	units:render "MIDI note %d" ;
 	units:symbol "note" .
+
diff --git a/sys/lv2/uri-map/NEWS b/sys/lv2/uri-map/NEWS
deleted file mode 100644
index fe73504c..00000000
--- a/sys/lv2/uri-map/NEWS
+++ /dev/null
@@ -1,26 +0,0 @@
-uri-map (1.6) stable;
-
-  * Merge with unified LV2 package.
-
- -- None <None>  Tue, 17 Apr 2012 00:00:00 +0000
-
-uri-map (1.4) stable;
-
-  * Update packaging.
-  * Deprecate uri-map in favour of urid.
-
- -- None <None>  Mon, 21 Nov 2011 00:00:00 +0000
-
-uri-map (1.2) stable;
-
-  * Mark up documentation in HTML using lv2:documentation.
-  * Add build system (for installation).
-
- -- None <None>  Thu, 26 May 2011 00:00:00 +0000
-
-uri-map (1.0) stable;
-
-  * Initial release.
-
- -- None <None>  Mon, 18 Oct 2010 00:00:00 +0000
-
diff --git a/sys/lv2/uri-map/manifest.ttl b/sys/lv2/uri-map/manifest.ttl
index 87087b61..a64e4fbd 100644
--- a/sys/lv2/uri-map/manifest.ttl
+++ b/sys/lv2/uri-map/manifest.ttl
@@ -1,4 +1,4 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/uri-map>
@@ -6,3 +6,4 @@
 	lv2:minorVersion 1 ;
 	lv2:microVersion 6 ;
 	rdfs:seeAlso <uri-map.ttl> .
+
diff --git a/sys/lv2/uri-map/uri-map.h b/sys/lv2/uri-map/uri-map.h
index 7bd2724d..651c3a8e 100644
--- a/sys/lv2/uri-map/uri-map.h
+++ b/sys/lv2/uri-map/uri-map.h
@@ -16,6 +16,7 @@
 
 /**
    @defgroup uri-map URI Map
+   @ingroup lv2
 
    C API for the LV2 URI Map extension <http://lv2plug.in/ns/ext/uri-map>.
 
diff --git a/sys/lv2/uri-map/lv2-uri-map.doap.ttl b/sys/lv2/uri-map/uri-map.meta.ttl
similarity index 69%
rename from sys/lv2/uri-map/lv2-uri-map.doap.ttl
rename to sys/lv2/uri-map/uri-map.meta.ttl
index df0feb72..acd1c267 100644
--- a/sys/lv2/uri-map/lv2-uri-map.doap.ttl
+++ b/sys/lv2/uri-map/uri-map.meta.ttl
@@ -1,3 +1,4 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix dcs: <http://ontologi.es/doap-changeset#> .
 @prefix doap: <http://usefulinc.com/ns/doap#> .
 @prefix foaf: <http://xmlns.com/foaf/0.1/> .
@@ -26,7 +27,6 @@
 		doap:revision "1.4" ;
 		doap:created "2011-11-21" ;
 		dcs:blame <http://drobilla.net/drobilla#me> ;
-		doap:file-release <http://lv2plug.in/spec/lv2-uri-map-1.4.tar.bz2> ;
 		dcs:changeset [
 			dcs:item [
 				rdfs:label "Update packaging."
@@ -38,7 +38,6 @@
 		doap:revision "1.2" ;
 		doap:created "2011-05-26" ;
 		dcs:blame <http://drobilla.net/drobilla#me> ;
-		doap:file-release <http://lv2plug.in/spec/lv2-uri-map-1.2.tar.bz2> ;
 		dcs:changeset [
 			dcs:item [
 				rdfs:label "Add build system (for installation)."
@@ -49,11 +48,25 @@
 	] , [
 		doap:revision "1.0" ;
 		doap:created "2010-10-18" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-uri-map-1.0.tar.gz> ;
 		dcs:blame <http://drobilla.net/drobilla#me> ;
 		dcs:changeset [
 			dcs:item [
 				rdfs:label "Initial release."
 			]
 		]
-	] .
+	] ;
+	lv2:documentation """
+
+<span class="warning">This extension is deprecated.</span> New implementations
+should use [LV2 URID](urid.html) instead.
+
+This extension defines a simple mechanism for plugins to map URIs to integers,
+usually for performance reasons (e.g. processing events typed by URIs in real
+time).  The expected use case is for plugins to map URIs to integers for things
+they 'understand' at instantiation time, and store those values for use in the
+audio thread without doing any string comparison.  This allows the
+extensibility of RDF with the performance of integers (or centrally defined
+enumerations).
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/uri-map/uri-map.ttl b/sys/lv2/uri-map/uri-map.ttl
index 7f6b0e77..bfb0d0b6 100644
--- a/sys/lv2/uri-map/uri-map.ttl
+++ b/sys/lv2/uri-map/uri-map.ttl
@@ -1,24 +1,14 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
-@prefix owl:  <http://www.w3.org/2002/07/owl#> .
-@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 @prefix umap: <http://lv2plug.in/ns/ext/uri-map#> .
 
 <http://lv2plug.in/ns/ext/uri-map>
 	a lv2:Feature ;
 	owl:deprecated true ;
+	rdfs:label "LV2 URI Map" ;
+	rdfs:comment "A feature for mapping URIs to integers." ;
 	rdfs:seeAlso <uri-map.h> ,
-		<lv2-uri-map.doap.ttl> ;
-	lv2:documentation """
-<p><span class="warning">This extension is deprecated.</span> New
-implementations should use <a href="../urid/urid.html">LV2 URID</a>
-instead.</p>
+		<uri-map.meta.ttl> .
 
-<p>This extension defines a simple mechanism for plugins to map URIs to
-integers, usually for performance reasons (e.g. processing events typed by URIs
-in real time).  The expected use case is for plugins to map URIs to integers
-for things they 'understand' at instantiation time, and store those values for
-use in the audio thread without doing any string comparison.  This allows the
-extensibility of RDF with the performance of integers (or centrally defined
-enumerations).</p>
-""" .
diff --git a/sys/lv2/urid/NEWS b/sys/lv2/urid/NEWS
deleted file mode 100644
index 2e7b4fc8..00000000
--- a/sys/lv2/urid/NEWS
+++ /dev/null
@@ -1,19 +0,0 @@
-urid (1.4) stable;
-
-  * Fix typo in urid:unmap documentation.
-
- -- None <None>  Sun, 14 Oct 2012 00:00:00 +0000
-
-urid (1.2) stable;
-
-  * Merge with unified LV2 package.
-  * Add feature struct names.
-
- -- None <None>  Tue, 17 Apr 2012 00:00:00 +0000
-
-urid (1.0) stable;
-
-  * Initial release.
-
- -- None <None>  Mon, 21 Nov 2011 00:00:00 +0000
-
diff --git a/sys/lv2/urid/lv2-urid.doap.ttl b/sys/lv2/urid/lv2-urid.doap.ttl
deleted file mode 100644
index b79545c2..00000000
--- a/sys/lv2/urid/lv2-urid.doap.ttl
+++ /dev/null
@@ -1,46 +0,0 @@
-@prefix dcs: <http://ontologi.es/doap-changeset#> .
-@prefix doap: <http://usefulinc.com/ns/doap#> .
-@prefix foaf: <http://xmlns.com/foaf/0.1/> .
-@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-
-<http://lv2plug.in/ns/ext/urid>
-	a doap:Project ;
-	doap:license <http://opensource.org/licenses/isc> ;
-	doap:name "LV2 URID" ;
-	doap:shortdesc "Features for mapping URIs to and from integers." ;
-	doap:created "2011-07-22" ;
-	doap:developer <http://lv2plug.in/ns/meta#gabrbedd> ;
-	doap:maintainer <http://drobilla.net/drobilla#me> ;
-	doap:release [
-		doap:revision "1.4" ;
-		doap:created "2012-10-14" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Fix typo in urid:unmap documentation."
-			]
-		]
-	] , [
-		doap:revision "1.2" ;
-		doap:created "2012-04-17" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Add feature struct names."
-			] , [
-				rdfs:label "Merge with unified LV2 package."
-			]
-		]
-	] , [
-		doap:revision "1.0" ;
-		doap:created "2011-11-21" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-urid-1.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Initial release."
-			]
-		]
-	] .
diff --git a/sys/lv2/urid/manifest.ttl b/sys/lv2/urid/manifest.ttl
index 19b58323..772e2b6c 100644
--- a/sys/lv2/urid/manifest.ttl
+++ b/sys/lv2/urid/manifest.ttl
@@ -1,4 +1,4 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/urid>
@@ -6,3 +6,4 @@
 	lv2:minorVersion 1 ;
 	lv2:microVersion 4 ;
 	rdfs:seeAlso <urid.ttl> .
+
diff --git a/sys/lv2/urid/urid.h b/sys/lv2/urid/urid.h
index c9ee2e0e..a68bc128 100644
--- a/sys/lv2/urid/urid.h
+++ b/sys/lv2/urid/urid.h
@@ -17,6 +17,7 @@
 
 /**
    @defgroup urid URID
+   @ingroup lv2
 
    Features for mapping URIs to and from integers, see
    <http://lv2plug.in/ns/ext/urid> for details.
@@ -60,7 +61,7 @@ typedef uint32_t LV2_URID;
 /**
    URID Map Feature (LV2_URID__map)
 */
-typedef struct _LV2_URID_Map {
+typedef struct {
 	/**
 	   Opaque pointer to host data.
 
@@ -97,7 +98,7 @@ typedef struct _LV2_URID_Map {
 /**
    URI Unmap Feature (LV2_URID__unmap)
 */
-typedef struct _LV2_URID_Unmap {
+typedef struct {
 	/**
 	   Opaque pointer to host data.
 
diff --git a/sys/lv2/urid/urid.meta.ttl b/sys/lv2/urid/urid.meta.ttl
new file mode 100644
index 00000000..b2a74fa0
--- /dev/null
+++ b/sys/lv2/urid/urid.meta.ttl
@@ -0,0 +1,84 @@
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
+
+<http://lv2plug.in/ns/ext/urid>
+	a doap:Project ;
+	doap:license <http://opensource.org/licenses/isc> ;
+	doap:name "LV2 URID" ;
+	doap:shortdesc "Features for mapping URIs to and from integers." ;
+	doap:created "2011-07-22" ;
+	doap:developer <http://lv2plug.in/ns/meta#gabrbedd> ;
+	doap:maintainer <http://drobilla.net/drobilla#me> ;
+	doap:release [
+		doap:revision "1.4" ;
+		doap:created "2012-10-14" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.2.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Fix typo in urid:unmap documentation."
+			]
+		]
+	] , [
+		doap:revision "1.2" ;
+		doap:created "2012-04-17" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Add feature struct names."
+			] , [
+				rdfs:label "Merge with unified LV2 package."
+			]
+		]
+	] , [
+		doap:revision "1.0" ;
+		doap:created "2011-11-21" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-urid-1.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Initial release."
+			]
+		]
+	] ;
+	lv2:documentation """
+
+This extension defines a simple mechanism for plugins to map URIs to and from
+integers.  This is usually used for performance reasons, for example for
+processing events with URI types in real-time audio code).  Typically, plugins
+map URIs to integers for things they "understand" at instantiation time, and
+store those values for use in the audio thread without doing any string
+comparison.  This allows for the extensibility of RDF but with the performance
+of integers.
+
+This extension is intended as an improved and simplified replacement for the
+[uri-map](uri-map.html) extension, since the `map` context parameter there has
+proven problematic.  This extension is functionally equivalent to the uri-map
+extension with a NULL context.  New implementations are encouraged to use this
+extension for URI mapping.
+
+"""^^lv2:Markdown .
+
+urid:map
+	lv2:documentation """
+
+To support this feature, the host must pass an LV2_Feature to
+LV2_Descriptor::instantiate() with URI LV2_URID__map and data pointed to an
+instance of LV2_URID_Map.
+
+"""^^lv2:Markdown .
+
+urid:unmap
+	lv2:documentation """
+
+To support this feature, the host must pass an LV2_Feature to
+LV2_Descriptor::instantiate() with URI LV2_URID__unmap and data pointed to an
+instance of LV2_URID_Unmap.
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/urid/urid.ttl b/sys/lv2/urid/urid.ttl
index 29b196aa..2c44b561 100644
--- a/sys/lv2/urid/urid.ttl
+++ b/sys/lv2/urid/urid.ttl
@@ -1,39 +1,22 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 @prefix urid: <http://lv2plug.in/ns/ext/urid#> .
 
 <http://lv2plug.in/ns/ext/urid>
-	a lv2:Specification ;
+	a owl:Ontology ;
+	rdfs:label "LV2 URID" ;
+	rdfs:comment "Features for mapping URIs to and from integers." ;
 	rdfs:seeAlso <urid.h> ,
-		<lv2-urid.doap.ttl> ;
-	lv2:documentation """
-<p>This extension defines a simple mechanism for plugins to map URIs to and
-from integers, usually for performance reasons (e.g. processing events typed by
-URIs in real time).  Typically, plugins map URIs to integers for things they
-"understand" at instantiation time, and store those values for use in the audio
-thread without doing any string comparison.  This allows for the extensibility
-of RDF but with the performance of integers.</p>
-
-<p>This extension is intended as an improved and simplified replacement for the
-<a href="../uri-map/uri-map.html">uri-map</a> extension, since the <q>map</q>
-context parameter has been found problematic.  This extension is functionally
-equivalent to the uri-map extension with a NULL context.  New implementations
-are encouraged to use this extension for URI mapping.</p>
-""" .
+		<urid.meta.ttl> .
 
 urid:map
 	a lv2:Feature ;
-	lv2:documentation """
-<p>A feature which is used to map URIs to integers.  To support this feature,
-the host must pass an LV2_Feature to LV2_Descriptor::instantiate() with URI
-LV2_URID__map and data pointed to an instance of LV2_URID_Map.</p>
-""" .
+	rdfs:label "map" ;
+	rdfs:comment "A feature to map URI strings to integer URIDs." .
 
 urid:unmap
 	a lv2:Feature ;
-	lv2:documentation """
-<p>A feature which is used to unmap URIs previously mapped to integers by
-urid:map.  To support this feature, the host must pass an LV2_Feature to
-LV2_Descriptor::instantiate() with URI LV2_URID__unmap and data pointed to
-an instance of LV2_URID_Unmap.</p>
-""" .
+	rdfs:label "unmap" ;
+	rdfs:comment "A feature to unmap URIDs back to strings." .
+
diff --git a/sys/lv2/worker/NEWS b/sys/lv2/worker/NEWS
deleted file mode 100644
index 2eaa7717..00000000
--- a/sys/lv2/worker/NEWS
+++ /dev/null
@@ -1,12 +0,0 @@
-worker (1.2) stable;
-
-  * Improve documentation.
-
- -- None <None>  Sun, 31 Jul 2016 00:00:00 +0000
-
-worker (1.0) stable;
-
-  * Initial release.
-
- -- None <None>  Tue, 17 Apr 2012 00:00:00 +0000
-
diff --git a/sys/lv2/worker/lv2-worker.doap.ttl b/sys/lv2/worker/lv2-worker.doap.ttl
deleted file mode 100644
index b01159ba..00000000
--- a/sys/lv2/worker/lv2-worker.doap.ttl
+++ /dev/null
@@ -1,32 +0,0 @@
-@prefix dcs: <http://ontologi.es/doap-changeset#> .
-@prefix doap: <http://usefulinc.com/ns/doap#> .
-@prefix foaf: <http://xmlns.com/foaf/0.1/> .
-@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-
-<http://lv2plug.in/ns/ext/worker>
-	a doap:Project ;
-	doap:name "LV2 Worker" ;
-	doap:shortdesc "Support for a non-realtime plugin worker method." ;
-	doap:created "2012-03-22" ;
-	doap:developer <http://drobilla.net/drobilla#me> ;
-	doap:release [
-		doap:revision "1.2" ;
-		doap:created "2016-07-31" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.14.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Improve documentation."
-			]
-		]
-	] , [
-		doap:revision "1.0" ;
-		doap:created "2012-04-17" ;
-		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
-		dcs:blame <http://drobilla.net/drobilla#me> ;
-		dcs:changeset [
-			dcs:item [
-				rdfs:label "Initial release."
-			]
-		]
-	] .
diff --git a/sys/lv2/worker/manifest.ttl b/sys/lv2/worker/manifest.ttl
index 28c21293..692720db 100644
--- a/sys/lv2/worker/manifest.ttl
+++ b/sys/lv2/worker/manifest.ttl
@@ -1,4 +1,4 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 
 <http://lv2plug.in/ns/ext/worker>
@@ -6,3 +6,4 @@
 	lv2:minorVersion 1 ;
 	lv2:microVersion 2 ;
 	rdfs:seeAlso <worker.ttl> .
+
diff --git a/sys/lv2/worker/worker.h b/sys/lv2/worker/worker.h
index f874d841..69cc1d3b 100644
--- a/sys/lv2/worker/worker.h
+++ b/sys/lv2/worker/worker.h
@@ -16,6 +16,7 @@
 
 /**
    @defgroup worker Worker
+   @ingroup lv2
 
    Support for non-realtime plugin operations, see
    <http://lv2plug.in/ns/ext/worker> for details.
@@ -71,7 +72,7 @@ typedef LV2_Worker_Status (*LV2_Worker_Respond_Function)(
    The plugin's extension_data() method should return an LV2_Worker_Interface
    when called with LV2_WORKER__interface as its argument.
 */
-typedef struct _LV2_Worker_Interface {
+typedef struct {
 	/**
 	   The worker method.  This is called by the host in a non-realtime context
 	   as requested, possibly with an arbitrary message to handle.
@@ -129,7 +130,7 @@ typedef void* LV2_Worker_Schedule_Handle;
    The host passes this feature to provide a schedule_work() function, which
    the plugin can use to schedule a worker call from run().
 */
-typedef struct _LV2_Worker_Schedule {
+typedef struct {
 	/**
 	   Opaque host data.
 	*/
@@ -144,10 +145,10 @@ typedef struct _LV2_Worker_Schedule {
 
 	   This function is always safe to call from run(), but it is not
 	   guaranteed that the worker is actually called from a different thread.
-	   In particular, when free-wheeling (e.g. for offline rendering), the
-	   worker may be executed immediately.  This allows single-threaded
-	   processing with sample accuracy and avoids timing problems when run() is
-	   executing much faster or slower than real-time.
+	   In particular, when free-wheeling (for example, during offline
+	   rendering), the worker may be executed immediately.  This allows
+	   single-threaded processing with sample accuracy and avoids timing
+	   problems when run() is executing much faster or slower than real-time.
 
 	   Plugins SHOULD be written in such a way that if the worker runs
 	   immediately, and responses from the worker are delivered immediately,
diff --git a/sys/lv2/worker/worker.meta.ttl b/sys/lv2/worker/worker.meta.ttl
new file mode 100644
index 00000000..f696d61a
--- /dev/null
+++ b/sys/lv2/worker/worker.meta.ttl
@@ -0,0 +1,82 @@
+@prefix dcs: <http://ontologi.es/doap-changeset#> .
+@prefix doap: <http://usefulinc.com/ns/doap#> .
+@prefix foaf: <http://xmlns.com/foaf/0.1/> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix work: <http://lv2plug.in/ns/ext/worker#> .
+
+<http://lv2plug.in/ns/ext/worker>
+	a doap:Project ;
+	doap:name "LV2 Worker" ;
+	doap:shortdesc "Support for doing non-realtime work in plugins." ;
+	doap:created "2012-03-22" ;
+	doap:developer <http://drobilla.net/drobilla#me> ;
+	doap:release [
+		doap:revision "1.2" ;
+		doap:created "2020-04-26" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.18.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Improve documentation."
+			]
+		]
+	] , [
+		doap:revision "1.0" ;
+		doap:created "2012-04-17" ;
+		doap:file-release <http://lv2plug.in/spec/lv2-1.0.0.tar.bz2> ;
+		dcs:blame <http://drobilla.net/drobilla#me> ;
+		dcs:changeset [
+			dcs:item [
+				rdfs:label "Initial release."
+			]
+		]
+	] ;
+	lv2:documentation """
+
+This extension allows plugins to schedule work that must be performed in
+another thread.  Plugins can use this interface to safely perform work that is
+not real-time safe, and receive the result in the run context.  The details of
+threading are managed by the host, allowing plugins to be simple and portable
+while using resources more efficiently.
+
+This interface is designed to gracefully support single-threaded synchronous
+execution, which allows the same code to work with sample accuracy for offline
+rendering.  For example, a sampler plugin may schedule a sample to be loaded
+from disk in another thread.  During live execution, the host will call the
+plugin's work method from another thread, and deliver the result to the audio
+thread when it is finished.  However, during offline export, the
+<q>scheduled</q> load would be executed immediately in the same thread.  This
+enables reproducible offline rendering, where any changes affect the output
+immediately regardless of how long the work takes to execute.
+
+"""^^lv2:Markdown .
+
+work:interface
+	lv2:documentation """
+
+The work interface provided by a plugin, LV2_Worker_Interface.
+
+    :::turtle
+
+    @prefix work: &lt;http://lv2plug.in/ns/ext/worker#&gt; .
+
+    &lt;plugin&gt;
+        a lv2:Plugin ;
+        lv2:extensionData work:interface .
+
+"""^^lv2:Markdown .
+
+work:schedule
+	lv2:documentation """
+
+The work scheduling feature provided by a host, LV2_Worker_Schedule.
+
+If the host passes this feature to LV2_Descriptor::instantiate, the plugin MAY
+use it to schedule work in the audio thread, and MUST NOT call it in any other
+context.  Hosts MAY pass this feature to other functions as well, in which case
+the plugin MAY use it to schedule work in the calling context.  The plugin MUST
+NOT assume any relationship between different schedule features.
+
+"""^^lv2:Markdown .
+
diff --git a/sys/lv2/worker/worker.ttl b/sys/lv2/worker/worker.ttl
index 6b327425..cb8a81a7 100644
--- a/sys/lv2/worker/worker.ttl
+++ b/sys/lv2/worker/worker.ttl
@@ -1,53 +1,25 @@
-@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .
-@prefix owl:  <http://www.w3.org/2002/07/owl#> .
-@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
+@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
 @prefix work: <http://lv2plug.in/ns/ext/worker#> .
-@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
 
 <http://lv2plug.in/ns/ext/worker>
 	a owl:Ontology ;
+	rdfs:label "LV2 Worker" ;
+	rdfs:comment "Support for doing non-realtime work in plugins." ;
+	owl:imports <http://lv2plug.in/ns/lv2core> ;
 	rdfs:seeAlso <worker.h> ,
-		<lv2-worker.doap.ttl> ;
-	lv2:documentation """
-<p>This extension allows plugins to schedule work that must be performed in
-another thread.  Plugins can use this interface to safely perform work that is
-not real-time safe, and receive the result in the run context.  The details of
-threading are managed by the host, allowing plugins to be simple and portable
-while using resources more efficiently.</p>
-
-<p>This interface is designed to gracefully support single-threaded synchronous
-execution, which allows the same code to work with sample accuracy for offline
-rendering.  For example, a sampler plugin may schedule a sample to be loaded
-from disk in another thread.  During live execution, the host will call the
-plugin's work method from another thread, and deliver the result to the audio
-thread when it is finished. However, during offline export, the
-<q>scheduled</q> load would be executed immediately in the same thread.  This
-enables reproducible offline rendering, where any changes affect the output
-immediately regardless of how long the work takes to execute.</p>
-""" .
+		<worker.meta.ttl> .
 
 work:interface
 	a lv2:ExtensionData ;
-	lv2:documentation """
-<p>The work interface provided by a plugin, LV2_Worker_Interface.</p>
-<pre class="turtle-code">
-@prefix work: &lt;http://lv2plug.in/ns/ext/worker#&gt; .
-
-&lt;plugin&gt;
-    a lv2:Plugin ;
-    lv2:extensionData work:interface .
-</pre>
-""" .
+	rdfs:label "work interface" ;
+	rdfs:comment "The work interface provided by a plugin." .
 
 work:schedule
 	a lv2:Feature ;
-	lv2:documentation """
-<p>The work scheduling feature provided by a host, LV2_Worker_Schedule.</p>
+	rdfs:label "work schedule" ;
+	rdfs:comment "The work scheduling feature provided by a host." .
 
-<p>If the host passes this feature to LV2_Descriptor::instantiate, the plugin
-MAY use it to schedule work in the audio thread, and MUST NOT call it in any
-other context.  Hosts MAY pass this feature to other functions as well, in
-which case the plugin MAY use it to schedule work in the calling context.  The
-plugin MUST NOT assume any relationship between different schedule
-features.</p> """ .
diff --git a/sys/src/lib.rs b/sys/src/lib.rs
index 94ea4abe..d9851981 100644
--- a/sys/src/lib.rs
+++ b/sys/src/lib.rs
@@ -1,40 +1,24 @@
 //! Raw bindings of all LV2 specification headers.
 //!
-//! This crate contains all C headers of the LV2 specification. Please note that utility headers are not included. If you want to use utilities, you should use the "nice" LV2 crates or create your own.
-//!
-//! The bindings are generated at build time using [bindgen](https://crates.io/crates/bindgen), which requires clang to be installed. The installation process is described [here](https://rust-lang.github.io/rust-bindgen/requirements.html).
+//! Bindings to the official [LV2](https://lv2plug.in/) API headers, used by [`rust-lv2`](https://crates.io/crates/lv2), a safe, fast, and ergonomic framework to create [LV2 plugins](http://lv2plug.in/) for audio processing, written in Rust. The crate uses the version 1.18.0 of the specification, as pulled from the [project's website](https://lv2plug.in/lv2-1-18-0.html).
 #![allow(non_upper_case_globals)]
 #![allow(non_camel_case_types)]
 #![allow(non_snake_case)]
-#![allow(dead_code)]
 #![allow(clippy::all)]
-#![allow(improper_ctypes)]
-include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
 
-#[cfg(windows)]
-impl From<u32> for LV2_State_Flags {
-    fn from(flags: u32) -> Self {
-        Self(flags as i32)
-    }
-}
+#[cfg_attr(target_os = "linux", path = "linux/mod.rs")]
+#[cfg_attr(target_os = "windows", path = "windows.rs")]
+mod unsupported;
+pub use unsupported::*;
 
-#[cfg(not(windows))]
 impl From<u32> for LV2_State_Flags {
     fn from(flags: u32) -> Self {
-        Self(flags)
+        Self(flags as _)
     }
 }
 
-#[cfg(windows)]
 impl From<LV2_State_Flags> for u32 {
     fn from(flags: LV2_State_Flags) -> u32 {
         flags.0 as u32
     }
 }
-
-#[cfg(not(windows))]
-impl From<LV2_State_Flags> for u32 {
-    fn from(flags: LV2_State_Flags) -> u32 {
-        flags.0
-    }
-}
diff --git a/sys/src/linux/aarch64.rs b/sys/src/linux/aarch64.rs
new file mode 100644
index 00000000..22581d71
--- /dev/null
+++ b/sys/src/linux/aarch64.rs
@@ -0,0 +1,2731 @@
+/* automatically generated by rust-bindgen */
+
+pub const LV2_ATOM_URI: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/atom\0";
+pub const LV2_ATOM_PREFIX: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/atom#\0";
+pub const LV2_ATOM__Atom: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#Atom\0";
+pub const LV2_ATOM__AtomPort: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#AtomPort\0";
+pub const LV2_ATOM__Blank: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Blank\0";
+pub const LV2_ATOM__Bool: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#Bool\0";
+pub const LV2_ATOM__Chunk: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Chunk\0";
+pub const LV2_ATOM__Double: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#Double\0";
+pub const LV2_ATOM__Event: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Event\0";
+pub const LV2_ATOM__Float: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Float\0";
+pub const LV2_ATOM__Int: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/atom#Int\0";
+pub const LV2_ATOM__Literal: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/atom#Literal\0";
+pub const LV2_ATOM__Long: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#Long\0";
+pub const LV2_ATOM__Number: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#Number\0";
+pub const LV2_ATOM__Object: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#Object\0";
+pub const LV2_ATOM__Path: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#Path\0";
+pub const LV2_ATOM__Property: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#Property\0";
+pub const LV2_ATOM__Resource: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#Resource\0";
+pub const LV2_ATOM__Sequence: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#Sequence\0";
+pub const LV2_ATOM__Sound: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Sound\0";
+pub const LV2_ATOM__String: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#String\0";
+pub const LV2_ATOM__Tuple: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Tuple\0";
+pub const LV2_ATOM__URI: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/atom#URI\0";
+pub const LV2_ATOM__URID: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#URID\0";
+pub const LV2_ATOM__Vector: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#Vector\0";
+pub const LV2_ATOM__atomTransfer: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/atom#atomTransfer\0";
+pub const LV2_ATOM__beatTime: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#beatTime\0";
+pub const LV2_ATOM__bufferType: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/atom#bufferType\0";
+pub const LV2_ATOM__childType: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/atom#childType\0";
+pub const LV2_ATOM__eventTransfer: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/atom#eventTransfer\0";
+pub const LV2_ATOM__frameTime: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/atom#frameTime\0";
+pub const LV2_ATOM__supports: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#supports\0";
+pub const LV2_ATOM__timeUnit: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#timeUnit\0";
+pub const LV2_ATOM_REFERENCE_TYPE: u32 = 0;
+pub const LV2_URID_URI: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/urid\0";
+pub const LV2_URID_PREFIX: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/urid#\0";
+pub const LV2_URID__map: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/urid#map\0";
+pub const LV2_URID__unmap: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/urid#unmap\0";
+pub const LV2_URID_MAP_URI: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/urid#map\0";
+pub const LV2_URID_UNMAP_URI: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/urid#unmap\0";
+pub const LV2_BUF_SIZE_URI: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/buf-size\0";
+pub const LV2_BUF_SIZE_PREFIX: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/buf-size#\0";
+pub const LV2_BUF_SIZE__boundedBlockLength: &'static [u8; 53usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#boundedBlockLength\0";
+pub const LV2_BUF_SIZE__fixedBlockLength: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#fixedBlockLength\0";
+pub const LV2_BUF_SIZE__maxBlockLength: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#maxBlockLength\0";
+pub const LV2_BUF_SIZE__minBlockLength: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#minBlockLength\0";
+pub const LV2_BUF_SIZE__nominalBlockLength: &'static [u8; 53usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#nominalBlockLength\0";
+pub const LV2_BUF_SIZE__powerOf2BlockLength: &'static [u8; 54usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#powerOf2BlockLength\0";
+pub const LV2_BUF_SIZE__sequenceSize: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#sequenceSize\0";
+pub const LV2_CORE_URI: &'static [u8; 29usize] = b"http://lv2plug.in/ns/lv2core\0";
+pub const LV2_CORE_PREFIX: &'static [u8; 30usize] = b"http://lv2plug.in/ns/lv2core#\0";
+pub const LV2_CORE__AllpassPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#AllpassPlugin\0";
+pub const LV2_CORE__AmplifierPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#AmplifierPlugin\0";
+pub const LV2_CORE__AnalyserPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#AnalyserPlugin\0";
+pub const LV2_CORE__AudioPort: &'static [u8; 39usize] = b"http://lv2plug.in/ns/lv2core#AudioPort\0";
+pub const LV2_CORE__BandpassPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#BandpassPlugin\0";
+pub const LV2_CORE__CVPort: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#CVPort\0";
+pub const LV2_CORE__ChorusPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#ChorusPlugin\0";
+pub const LV2_CORE__CombPlugin: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#CombPlugin\0";
+pub const LV2_CORE__CompressorPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#CompressorPlugin\0";
+pub const LV2_CORE__ConstantPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#ConstantPlugin\0";
+pub const LV2_CORE__ControlPort: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#ControlPort\0";
+pub const LV2_CORE__ConverterPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#ConverterPlugin\0";
+pub const LV2_CORE__DelayPlugin: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#DelayPlugin\0";
+pub const LV2_CORE__DistortionPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#DistortionPlugin\0";
+pub const LV2_CORE__DynamicsPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#DynamicsPlugin\0";
+pub const LV2_CORE__EQPlugin: &'static [u8; 38usize] = b"http://lv2plug.in/ns/lv2core#EQPlugin\0";
+pub const LV2_CORE__EnvelopePlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#EnvelopePlugin\0";
+pub const LV2_CORE__ExpanderPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#ExpanderPlugin\0";
+pub const LV2_CORE__ExtensionData: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#ExtensionData\0";
+pub const LV2_CORE__Feature: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#Feature\0";
+pub const LV2_CORE__FilterPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#FilterPlugin\0";
+pub const LV2_CORE__FlangerPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#FlangerPlugin\0";
+pub const LV2_CORE__FunctionPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#FunctionPlugin\0";
+pub const LV2_CORE__GatePlugin: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#GatePlugin\0";
+pub const LV2_CORE__GeneratorPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#GeneratorPlugin\0";
+pub const LV2_CORE__HighpassPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#HighpassPlugin\0";
+pub const LV2_CORE__InputPort: &'static [u8; 39usize] = b"http://lv2plug.in/ns/lv2core#InputPort\0";
+pub const LV2_CORE__InstrumentPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#InstrumentPlugin\0";
+pub const LV2_CORE__LimiterPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#LimiterPlugin\0";
+pub const LV2_CORE__LowpassPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#LowpassPlugin\0";
+pub const LV2_CORE__MixerPlugin: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#MixerPlugin\0";
+pub const LV2_CORE__ModulatorPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#ModulatorPlugin\0";
+pub const LV2_CORE__MultiEQPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#MultiEQPlugin\0";
+pub const LV2_CORE__OscillatorPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#OscillatorPlugin\0";
+pub const LV2_CORE__OutputPort: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#OutputPort\0";
+pub const LV2_CORE__ParaEQPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#ParaEQPlugin\0";
+pub const LV2_CORE__PhaserPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#PhaserPlugin\0";
+pub const LV2_CORE__PitchPlugin: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#PitchPlugin\0";
+pub const LV2_CORE__Plugin: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#Plugin\0";
+pub const LV2_CORE__PluginBase: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#PluginBase\0";
+pub const LV2_CORE__Point: &'static [u8; 35usize] = b"http://lv2plug.in/ns/lv2core#Point\0";
+pub const LV2_CORE__Port: &'static [u8; 34usize] = b"http://lv2plug.in/ns/lv2core#Port\0";
+pub const LV2_CORE__PortProperty: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#PortProperty\0";
+pub const LV2_CORE__Resource: &'static [u8; 38usize] = b"http://lv2plug.in/ns/lv2core#Resource\0";
+pub const LV2_CORE__ReverbPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#ReverbPlugin\0";
+pub const LV2_CORE__ScalePoint: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#ScalePoint\0";
+pub const LV2_CORE__SimulatorPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#SimulatorPlugin\0";
+pub const LV2_CORE__SpatialPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#SpatialPlugin\0";
+pub const LV2_CORE__Specification: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#Specification\0";
+pub const LV2_CORE__SpectralPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#SpectralPlugin\0";
+pub const LV2_CORE__UtilityPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#UtilityPlugin\0";
+pub const LV2_CORE__WaveshaperPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#WaveshaperPlugin\0";
+pub const LV2_CORE__appliesTo: &'static [u8; 39usize] = b"http://lv2plug.in/ns/lv2core#appliesTo\0";
+pub const LV2_CORE__binary: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#binary\0";
+pub const LV2_CORE__connectionOptional: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/lv2core#connectionOptional\0";
+pub const LV2_CORE__control: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#control\0";
+pub const LV2_CORE__default: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#default\0";
+pub const LV2_CORE__designation: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#designation\0";
+pub const LV2_CORE__documentation: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#documentation\0";
+pub const LV2_CORE__enumeration: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#enumeration\0";
+pub const LV2_CORE__extensionData: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#extensionData\0";
+pub const LV2_CORE__freeWheeling: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#freeWheeling\0";
+pub const LV2_CORE__hardRTCapable: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#hardRTCapable\0";
+pub const LV2_CORE__inPlaceBroken: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#inPlaceBroken\0";
+pub const LV2_CORE__index: &'static [u8; 35usize] = b"http://lv2plug.in/ns/lv2core#index\0";
+pub const LV2_CORE__integer: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#integer\0";
+pub const LV2_CORE__isLive: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#isLive\0";
+pub const LV2_CORE__latency: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#latency\0";
+pub const LV2_CORE__maximum: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#maximum\0";
+pub const LV2_CORE__microVersion: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#microVersion\0";
+pub const LV2_CORE__minimum: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#minimum\0";
+pub const LV2_CORE__minorVersion: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#minorVersion\0";
+pub const LV2_CORE__name: &'static [u8; 34usize] = b"http://lv2plug.in/ns/lv2core#name\0";
+pub const LV2_CORE__optionalFeature: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#optionalFeature\0";
+pub const LV2_CORE__port: &'static [u8; 34usize] = b"http://lv2plug.in/ns/lv2core#port\0";
+pub const LV2_CORE__portProperty: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#portProperty\0";
+pub const LV2_CORE__project: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#project\0";
+pub const LV2_CORE__prototype: &'static [u8; 39usize] = b"http://lv2plug.in/ns/lv2core#prototype\0";
+pub const LV2_CORE__reportsLatency: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#reportsLatency\0";
+pub const LV2_CORE__requiredFeature: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#requiredFeature\0";
+pub const LV2_CORE__sampleRate: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#sampleRate\0";
+pub const LV2_CORE__scalePoint: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#scalePoint\0";
+pub const LV2_CORE__symbol: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#symbol\0";
+pub const LV2_CORE__toggled: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#toggled\0";
+pub const LV2_DATA_ACCESS_URI: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/data-access\0";
+pub const LV2_DATA_ACCESS_PREFIX: &'static [u8; 38usize] =
+    b"http://lv2plug.in/ns/ext/data-access#\0";
+pub const LV2_DYN_MANIFEST_URI: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/dynmanifest\0";
+pub const LV2_DYN_MANIFEST_PREFIX: &'static [u8; 38usize] =
+    b"http://lv2plug.in/ns/ext/dynmanifest#\0";
+pub const LV2_EVENT_URI: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/event\0";
+pub const LV2_EVENT_PREFIX: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/event#\0";
+pub const LV2_EVENT__Event: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/event#Event\0";
+pub const LV2_EVENT__EventPort: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/event#EventPort\0";
+pub const LV2_EVENT__FrameStamp: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/event#FrameStamp\0";
+pub const LV2_EVENT__TimeStamp: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/event#TimeStamp\0";
+pub const LV2_EVENT__generatesTimeStamp: &'static [u8; 50usize] =
+    b"http://lv2plug.in/ns/ext/event#generatesTimeStamp\0";
+pub const LV2_EVENT__generic: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/event#generic\0";
+pub const LV2_EVENT__inheritsEvent: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/event#inheritsEvent\0";
+pub const LV2_EVENT__inheritsTimeStamp: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/event#inheritsTimeStamp\0";
+pub const LV2_EVENT__supportsEvent: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/event#supportsEvent\0";
+pub const LV2_EVENT__supportsTimeStamp: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/event#supportsTimeStamp\0";
+pub const LV2_EVENT_AUDIO_STAMP: u32 = 0;
+pub const LV2_INSTANCE_ACCESS_URI: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/instance-access\0";
+pub const LV2_LOG_URI: &'static [u8; 29usize] = b"http://lv2plug.in/ns/ext/log\0";
+pub const LV2_LOG_PREFIX: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/log#\0";
+pub const LV2_LOG__Entry: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/log#Entry\0";
+pub const LV2_LOG__Error: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/log#Error\0";
+pub const LV2_LOG__Note: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/log#Note\0";
+pub const LV2_LOG__Trace: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/log#Trace\0";
+pub const LV2_LOG__Warning: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/log#Warning\0";
+pub const LV2_LOG__log: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/log#log\0";
+pub const LV2_MIDI_URI: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/midi\0";
+pub const LV2_MIDI_PREFIX: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/midi#\0";
+pub const LV2_MIDI__ActiveSense: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/midi#ActiveSense\0";
+pub const LV2_MIDI__Aftertouch: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#Aftertouch\0";
+pub const LV2_MIDI__Bender: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/midi#Bender\0";
+pub const LV2_MIDI__ChannelPressure: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/midi#ChannelPressure\0";
+pub const LV2_MIDI__Chunk: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#Chunk\0";
+pub const LV2_MIDI__Clock: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#Clock\0";
+pub const LV2_MIDI__Continue: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/midi#Continue\0";
+pub const LV2_MIDI__Controller: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#Controller\0";
+pub const LV2_MIDI__MidiEvent: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/midi#MidiEvent\0";
+pub const LV2_MIDI__NoteOff: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/midi#NoteOff\0";
+pub const LV2_MIDI__NoteOn: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/midi#NoteOn\0";
+pub const LV2_MIDI__ProgramChange: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/midi#ProgramChange\0";
+pub const LV2_MIDI__QuarterFrame: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#QuarterFrame\0";
+pub const LV2_MIDI__Reset: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#Reset\0";
+pub const LV2_MIDI__SongPosition: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#SongPosition\0";
+pub const LV2_MIDI__SongSelect: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#SongSelect\0";
+pub const LV2_MIDI__Start: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#Start\0";
+pub const LV2_MIDI__Stop: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/midi#Stop\0";
+pub const LV2_MIDI__SystemCommon: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#SystemCommon\0";
+pub const LV2_MIDI__SystemExclusive: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/midi#SystemExclusive\0";
+pub const LV2_MIDI__SystemMessage: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/midi#SystemMessage\0";
+pub const LV2_MIDI__SystemRealtime: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/midi#SystemRealtime\0";
+pub const LV2_MIDI__Tick: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/midi#Tick\0";
+pub const LV2_MIDI__TuneRequest: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/midi#TuneRequest\0";
+pub const LV2_MIDI__VoiceMessage: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#VoiceMessage\0";
+pub const LV2_MIDI__benderValue: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/midi#benderValue\0";
+pub const LV2_MIDI__binding: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/midi#binding\0";
+pub const LV2_MIDI__byteNumber: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#byteNumber\0";
+pub const LV2_MIDI__channel: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/midi#channel\0";
+pub const LV2_MIDI__chunk: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#chunk\0";
+pub const LV2_MIDI__controllerNumber: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/midi#controllerNumber\0";
+pub const LV2_MIDI__controllerValue: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/midi#controllerValue\0";
+pub const LV2_MIDI__noteNumber: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#noteNumber\0";
+pub const LV2_MIDI__pressure: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/midi#pressure\0";
+pub const LV2_MIDI__programNumber: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/midi#programNumber\0";
+pub const LV2_MIDI__property: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/midi#property\0";
+pub const LV2_MIDI__songNumber: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#songNumber\0";
+pub const LV2_MIDI__songPosition: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#songPosition\0";
+pub const LV2_MIDI__status: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/midi#status\0";
+pub const LV2_MIDI__statusMask: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#statusMask\0";
+pub const LV2_MIDI__velocity: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/midi#velocity\0";
+pub const LV2_MORPH_URI: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/morph\0";
+pub const LV2_MORPH_PREFIX: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/morph#\0";
+pub const LV2_MORPH__AutoMorphPort: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/morph#AutoMorphPort\0";
+pub const LV2_MORPH__MorphPort: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/morph#MorphPort\0";
+pub const LV2_MORPH__interface: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/morph#interface\0";
+pub const LV2_MORPH__supportsType: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/morph#supportsType\0";
+pub const LV2_MORPH__currentType: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/morph#currentType\0";
+pub const LV2_OPTIONS_URI: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/options\0";
+pub const LV2_OPTIONS_PREFIX: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/options#\0";
+pub const LV2_OPTIONS__Option: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/options#Option\0";
+pub const LV2_OPTIONS__interface: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/options#interface\0";
+pub const LV2_OPTIONS__options: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/options#options\0";
+pub const LV2_OPTIONS__requiredOption: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/options#requiredOption\0";
+pub const LV2_OPTIONS__supportedOption: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/options#supportedOption\0";
+pub const LV2_PARAMETERS_URI: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/parameters\0";
+pub const LV2_PARAMETERS_PREFIX: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/parameters#\0";
+pub const LV2_PARAMETERS__CompressorControls: &'static [u8; 55usize] =
+    b"http://lv2plug.in/ns/ext/parameters#CompressorControls\0";
+pub const LV2_PARAMETERS__ControlGroup: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/parameters#ControlGroup\0";
+pub const LV2_PARAMETERS__EnvelopeControls: &'static [u8; 53usize] =
+    b"http://lv2plug.in/ns/ext/parameters#EnvelopeControls\0";
+pub const LV2_PARAMETERS__FilterControls: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/ext/parameters#FilterControls\0";
+pub const LV2_PARAMETERS__OscillatorControls: &'static [u8; 55usize] =
+    b"http://lv2plug.in/ns/ext/parameters#OscillatorControls\0";
+pub const LV2_PARAMETERS__amplitude: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/parameters#amplitude\0";
+pub const LV2_PARAMETERS__attack: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/parameters#attack\0";
+pub const LV2_PARAMETERS__bypass: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/parameters#bypass\0";
+pub const LV2_PARAMETERS__cutoffFrequency: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/ext/parameters#cutoffFrequency\0";
+pub const LV2_PARAMETERS__decay: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/parameters#decay\0";
+pub const LV2_PARAMETERS__delay: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/parameters#delay\0";
+pub const LV2_PARAMETERS__dryLevel: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/parameters#dryLevel\0";
+pub const LV2_PARAMETERS__frequency: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/parameters#frequency\0";
+pub const LV2_PARAMETERS__gain: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/parameters#gain\0";
+pub const LV2_PARAMETERS__hold: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/parameters#hold\0";
+pub const LV2_PARAMETERS__pulseWidth: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/parameters#pulseWidth\0";
+pub const LV2_PARAMETERS__ratio: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/parameters#ratio\0";
+pub const LV2_PARAMETERS__release: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/parameters#release\0";
+pub const LV2_PARAMETERS__resonance: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/parameters#resonance\0";
+pub const LV2_PARAMETERS__sampleRate: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/parameters#sampleRate\0";
+pub const LV2_PARAMETERS__sustain: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/parameters#sustain\0";
+pub const LV2_PARAMETERS__threshold: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/parameters#threshold\0";
+pub const LV2_PARAMETERS__waveform: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/parameters#waveform\0";
+pub const LV2_PARAMETERS__wetDryRatio: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/parameters#wetDryRatio\0";
+pub const LV2_PARAMETERS__wetLevel: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/parameters#wetLevel\0";
+pub const LV2_PATCH_URI: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/patch\0";
+pub const LV2_PATCH_PREFIX: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/patch#\0";
+pub const LV2_PATCH__Ack: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#Ack\0";
+pub const LV2_PATCH__Delete: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/patch#Delete\0";
+pub const LV2_PATCH__Copy: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/patch#Copy\0";
+pub const LV2_PATCH__Error: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/patch#Error\0";
+pub const LV2_PATCH__Get: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#Get\0";
+pub const LV2_PATCH__Message: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#Message\0";
+pub const LV2_PATCH__Move: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/patch#Move\0";
+pub const LV2_PATCH__Patch: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/patch#Patch\0";
+pub const LV2_PATCH__Post: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/patch#Post\0";
+pub const LV2_PATCH__Put: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#Put\0";
+pub const LV2_PATCH__Request: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#Request\0";
+pub const LV2_PATCH__Response: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#Response\0";
+pub const LV2_PATCH__Set: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#Set\0";
+pub const LV2_PATCH__accept: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/patch#accept\0";
+pub const LV2_PATCH__add: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#add\0";
+pub const LV2_PATCH__body: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/patch#body\0";
+pub const LV2_PATCH__context: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#context\0";
+pub const LV2_PATCH__destination: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/patch#destination\0";
+pub const LV2_PATCH__property: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#property\0";
+pub const LV2_PATCH__readable: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#readable\0";
+pub const LV2_PATCH__remove: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/patch#remove\0";
+pub const LV2_PATCH__request: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#request\0";
+pub const LV2_PATCH__subject: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#subject\0";
+pub const LV2_PATCH__sequenceNumber: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/patch#sequenceNumber\0";
+pub const LV2_PATCH__value: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/patch#value\0";
+pub const LV2_PATCH__wildcard: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#wildcard\0";
+pub const LV2_PATCH__writable: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#writable\0";
+pub const LV2_PORT_GROUPS_URI: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/port-groups\0";
+pub const LV2_PORT_GROUPS_PREFIX: &'static [u8; 38usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#\0";
+pub const LV2_PORT_GROUPS__DiscreteGroup: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#DiscreteGroup\0";
+pub const LV2_PORT_GROUPS__Element: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#Element\0";
+pub const LV2_PORT_GROUPS__FivePointOneGroup: &'static [u8; 55usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#FivePointOneGroup\0";
+pub const LV2_PORT_GROUPS__FivePointZeroGroup: &'static [u8; 56usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#FivePointZeroGroup\0";
+pub const LV2_PORT_GROUPS__FourPointZeroGroup: &'static [u8; 56usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#FourPointZeroGroup\0";
+pub const LV2_PORT_GROUPS__Group: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#Group\0";
+pub const LV2_PORT_GROUPS__InputGroup: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#InputGroup\0";
+pub const LV2_PORT_GROUPS__MidSideGroup: &'static [u8; 50usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#MidSideGroup\0";
+pub const LV2_PORT_GROUPS__MonoGroup: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#MonoGroup\0";
+pub const LV2_PORT_GROUPS__OutputGroup: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#OutputGroup\0";
+pub const LV2_PORT_GROUPS__SevenPointOneGroup: &'static [u8; 56usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#SevenPointOneGroup\0";
+pub const LV2_PORT_GROUPS__SevenPointOneWideGroup: &'static [u8; 60usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#SevenPointOneWideGroup\0";
+pub const LV2_PORT_GROUPS__SixPointOneGroup: &'static [u8; 54usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#SixPointOneGroup\0";
+pub const LV2_PORT_GROUPS__StereoGroup: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#StereoGroup\0";
+pub const LV2_PORT_GROUPS__ThreePointZeroGroup: &'static [u8; 57usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#ThreePointZeroGroup\0";
+pub const LV2_PORT_GROUPS__center: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#center\0";
+pub const LV2_PORT_GROUPS__centerLeft: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#centerLeft\0";
+pub const LV2_PORT_GROUPS__centerRight: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#centerRight\0";
+pub const LV2_PORT_GROUPS__element: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#element\0";
+pub const LV2_PORT_GROUPS__group: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#group\0";
+pub const LV2_PORT_GROUPS__left: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#left\0";
+pub const LV2_PORT_GROUPS__lowFrequencyEffects: &'static [u8; 57usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#lowFrequencyEffects\0";
+pub const LV2_PORT_GROUPS__mainInput: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#mainInput\0";
+pub const LV2_PORT_GROUPS__mainOutput: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#mainOutput\0";
+pub const LV2_PORT_GROUPS__rearCenter: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#rearCenter\0";
+pub const LV2_PORT_GROUPS__rearLeft: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#rearLeft\0";
+pub const LV2_PORT_GROUPS__rearRight: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#rearRight\0";
+pub const LV2_PORT_GROUPS__right: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#right\0";
+pub const LV2_PORT_GROUPS__side: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#side\0";
+pub const LV2_PORT_GROUPS__sideChainOf: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#sideChainOf\0";
+pub const LV2_PORT_GROUPS__sideLeft: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#sideLeft\0";
+pub const LV2_PORT_GROUPS__sideRight: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#sideRight\0";
+pub const LV2_PORT_GROUPS__source: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#source\0";
+pub const LV2_PORT_GROUPS__subGroupOf: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#subGroupOf\0";
+pub const LV2_PORT_PROPS_URI: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/port-props\0";
+pub const LV2_PORT_PROPS_PREFIX: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/port-props#\0";
+pub const LV2_PORT_PROPS__causesArtifacts: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/ext/port-props#causesArtifacts\0";
+pub const LV2_PORT_PROPS__continuousCV: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-props#continuousCV\0";
+pub const LV2_PORT_PROPS__discreteCV: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-props#discreteCV\0";
+pub const LV2_PORT_PROPS__displayPriority: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/ext/port-props#displayPriority\0";
+pub const LV2_PORT_PROPS__expensive: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/port-props#expensive\0";
+pub const LV2_PORT_PROPS__hasStrictBounds: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/ext/port-props#hasStrictBounds\0";
+pub const LV2_PORT_PROPS__logarithmic: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-props#logarithmic\0";
+pub const LV2_PORT_PROPS__notAutomatic: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-props#notAutomatic\0";
+pub const LV2_PORT_PROPS__notOnGUI: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/port-props#notOnGUI\0";
+pub const LV2_PORT_PROPS__rangeSteps: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-props#rangeSteps\0";
+pub const LV2_PORT_PROPS__supportsStrictBounds: &'static [u8; 57usize] =
+    b"http://lv2plug.in/ns/ext/port-props#supportsStrictBounds\0";
+pub const LV2_PORT_PROPS__trigger: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/port-props#trigger\0";
+pub const LV2_PRESETS_URI: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/presets\0";
+pub const LV2_PRESETS_PREFIX: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/presets#\0";
+pub const LV2_PRESETS__Bank: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/presets#Bank\0";
+pub const LV2_PRESETS__Preset: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/presets#Preset\0";
+pub const LV2_PRESETS__bank: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/presets#bank\0";
+pub const LV2_PRESETS__preset: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/presets#preset\0";
+pub const LV2_PRESETS__value: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/presets#value\0";
+pub const LV2_RESIZE_PORT_URI: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/resize-port\0";
+pub const LV2_RESIZE_PORT_PREFIX: &'static [u8; 38usize] =
+    b"http://lv2plug.in/ns/ext/resize-port#\0";
+pub const LV2_RESIZE_PORT__asLargeAs: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/resize-port#asLargeAs\0";
+pub const LV2_RESIZE_PORT__minimumSize: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/resize-port#minimumSize\0";
+pub const LV2_RESIZE_PORT__resize: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/resize-port#resize\0";
+pub const LV2_STATE_URI: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/state\0";
+pub const LV2_STATE_PREFIX: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/state#\0";
+pub const LV2_STATE__State: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/state#State\0";
+pub const LV2_STATE__interface: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/state#interface\0";
+pub const LV2_STATE__loadDefaultState: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/state#loadDefaultState\0";
+pub const LV2_STATE__freePath: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/state#freePath\0";
+pub const LV2_STATE__makePath: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/state#makePath\0";
+pub const LV2_STATE__mapPath: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/state#mapPath\0";
+pub const LV2_STATE__state: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/state#state\0";
+pub const LV2_STATE__threadSafeRestore: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/state#threadSafeRestore\0";
+pub const LV2_STATE__StateChanged: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/state#StateChanged\0";
+pub const LV2_TIME_URI: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/time\0";
+pub const LV2_TIME_PREFIX: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/time#\0";
+pub const LV2_TIME__Time: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/time#Time\0";
+pub const LV2_TIME__Position: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/time#Position\0";
+pub const LV2_TIME__Rate: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/time#Rate\0";
+pub const LV2_TIME__position: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/time#position\0";
+pub const LV2_TIME__barBeat: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/time#barBeat\0";
+pub const LV2_TIME__bar: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/time#bar\0";
+pub const LV2_TIME__beat: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/time#beat\0";
+pub const LV2_TIME__beatUnit: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/time#beatUnit\0";
+pub const LV2_TIME__beatsPerBar: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/time#beatsPerBar\0";
+pub const LV2_TIME__beatsPerMinute: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/time#beatsPerMinute\0";
+pub const LV2_TIME__frame: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/time#frame\0";
+pub const LV2_TIME__framesPerSecond: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/time#framesPerSecond\0";
+pub const LV2_TIME__speed: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/time#speed\0";
+pub const LV2_UI_URI: &'static [u8; 35usize] = b"http://lv2plug.in/ns/extensions/ui\0";
+pub const LV2_UI_PREFIX: &'static [u8; 36usize] = b"http://lv2plug.in/ns/extensions/ui#\0";
+pub const LV2_UI__CocoaUI: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/ui#CocoaUI\0";
+pub const LV2_UI__Gtk3UI: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#Gtk3UI\0";
+pub const LV2_UI__GtkUI: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#GtkUI\0";
+pub const LV2_UI__PortNotification: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/extensions/ui#PortNotification\0";
+pub const LV2_UI__PortProtocol: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/extensions/ui#PortProtocol\0";
+pub const LV2_UI__Qt4UI: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#Qt4UI\0";
+pub const LV2_UI__Qt5UI: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#Qt5UI\0";
+pub const LV2_UI__UI: &'static [u8; 38usize] = b"http://lv2plug.in/ns/extensions/ui#UI\0";
+pub const LV2_UI__WindowsUI: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/ui#WindowsUI\0";
+pub const LV2_UI__X11UI: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#X11UI\0";
+pub const LV2_UI__binary: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#binary\0";
+pub const LV2_UI__fixedSize: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/ui#fixedSize\0";
+pub const LV2_UI__idleInterface: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/ui#idleInterface\0";
+pub const LV2_UI__noUserResize: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/extensions/ui#noUserResize\0";
+pub const LV2_UI__notifyType: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/extensions/ui#notifyType\0";
+pub const LV2_UI__parent: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#parent\0";
+pub const LV2_UI__plugin: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#plugin\0";
+pub const LV2_UI__portIndex: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/ui#portIndex\0";
+pub const LV2_UI__portMap: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/ui#portMap\0";
+pub const LV2_UI__portNotification: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/extensions/ui#portNotification\0";
+pub const LV2_UI__portSubscribe: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/ui#portSubscribe\0";
+pub const LV2_UI__protocol: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/extensions/ui#protocol\0";
+pub const LV2_UI__requestValue: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/extensions/ui#requestValue\0";
+pub const LV2_UI__floatProtocol: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/ui#floatProtocol\0";
+pub const LV2_UI__peakProtocol: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/extensions/ui#peakProtocol\0";
+pub const LV2_UI__resize: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#resize\0";
+pub const LV2_UI__showInterface: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/ui#showInterface\0";
+pub const LV2_UI__touch: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#touch\0";
+pub const LV2_UI__ui: &'static [u8; 38usize] = b"http://lv2plug.in/ns/extensions/ui#ui\0";
+pub const LV2_UI__updateRate: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/extensions/ui#updateRate\0";
+pub const LV2_UI__windowTitle: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/extensions/ui#windowTitle\0";
+pub const LV2_UI__scaleFactor: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/extensions/ui#scaleFactor\0";
+pub const LV2_UI__foregroundColor: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/extensions/ui#foregroundColor\0";
+pub const LV2_UI__backgroundColor: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/extensions/ui#backgroundColor\0";
+pub const LV2_UNITS_URI: &'static [u8; 38usize] = b"http://lv2plug.in/ns/extensions/units\0";
+pub const LV2_UNITS_PREFIX: &'static [u8; 39usize] = b"http://lv2plug.in/ns/extensions/units#\0";
+pub const LV2_UNITS__Conversion: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/units#Conversion\0";
+pub const LV2_UNITS__Unit: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#Unit\0";
+pub const LV2_UNITS__bar: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#bar\0";
+pub const LV2_UNITS__beat: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#beat\0";
+pub const LV2_UNITS__bpm: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#bpm\0";
+pub const LV2_UNITS__cent: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#cent\0";
+pub const LV2_UNITS__cm: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#cm\0";
+pub const LV2_UNITS__coef: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#coef\0";
+pub const LV2_UNITS__conversion: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/units#conversion\0";
+pub const LV2_UNITS__db: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#db\0";
+pub const LV2_UNITS__degree: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/units#degree\0";
+pub const LV2_UNITS__frame: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/extensions/units#frame\0";
+pub const LV2_UNITS__hz: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#hz\0";
+pub const LV2_UNITS__inch: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#inch\0";
+pub const LV2_UNITS__khz: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#khz\0";
+pub const LV2_UNITS__km: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#km\0";
+pub const LV2_UNITS__m: &'static [u8; 40usize] = b"http://lv2plug.in/ns/extensions/units#m\0";
+pub const LV2_UNITS__mhz: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#mhz\0";
+pub const LV2_UNITS__midiNote: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/extensions/units#midiNote\0";
+pub const LV2_UNITS__mile: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#mile\0";
+pub const LV2_UNITS__min: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#min\0";
+pub const LV2_UNITS__mm: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#mm\0";
+pub const LV2_UNITS__ms: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#ms\0";
+pub const LV2_UNITS__name: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#name\0";
+pub const LV2_UNITS__oct: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#oct\0";
+pub const LV2_UNITS__pc: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#pc\0";
+pub const LV2_UNITS__prefixConversion: &'static [u8; 55usize] =
+    b"http://lv2plug.in/ns/extensions/units#prefixConversion\0";
+pub const LV2_UNITS__render: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/units#render\0";
+pub const LV2_UNITS__s: &'static [u8; 40usize] = b"http://lv2plug.in/ns/extensions/units#s\0";
+pub const LV2_UNITS__semitone12TET: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/extensions/units#semitone12TET\0";
+pub const LV2_UNITS__symbol: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/units#symbol\0";
+pub const LV2_UNITS__unit: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#unit\0";
+pub const LV2_URI_MAP_URI: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/uri-map\0";
+pub const LV2_URI_MAP_PREFIX: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/uri-map#\0";
+pub const LV2_WORKER_URI: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/worker\0";
+pub const LV2_WORKER_PREFIX: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/worker#\0";
+pub const LV2_WORKER__interface: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/worker#interface\0";
+pub const LV2_WORKER__schedule: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/worker#schedule\0";
+pub type __uint8_t = ::std::os::raw::c_uchar;
+pub type __uint16_t = ::std::os::raw::c_ushort;
+pub type __int32_t = ::std::os::raw::c_int;
+pub type __uint32_t = ::std::os::raw::c_uint;
+pub type __int64_t = ::std::os::raw::c_long;
+#[doc = " The header of an atom:Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom {
+    #[doc = "< Size in bytes, not including type and size."]
+    pub size: u32,
+    #[doc = "< Type of this atom (mapped URI)."]
+    pub type_: u32,
+}
+#[doc = " An atom:Int or atom:Bool.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Int {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Integer value."]
+    pub body: i32,
+}
+#[doc = " An atom:Long.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Long {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Integer value."]
+    pub body: i64,
+}
+#[doc = " An atom:Float.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Float {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Floating point value."]
+    pub body: f32,
+}
+#[doc = " An atom:Double.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Double {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Floating point value."]
+    pub body: f64,
+}
+#[doc = " An atom:Bool.  May be cast to LV2_Atom."]
+pub type LV2_Atom_Bool = LV2_Atom_Int;
+#[doc = " An atom:URID.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_URID {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< URID."]
+    pub body: u32,
+}
+#[doc = " An atom:String.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_String {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+}
+#[doc = " The body of an atom:Literal."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Literal_Body {
+    #[doc = "< Datatype URID."]
+    pub datatype: u32,
+    #[doc = "< Language URID."]
+    pub lang: u32,
+}
+#[doc = " An atom:Literal.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Literal {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Literal_Body,
+}
+#[doc = " An atom:Tuple.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Tuple {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+}
+#[doc = " The body of an atom:Vector."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Vector_Body {
+    #[doc = "< The size of each element in the vector."]
+    pub child_size: u32,
+    #[doc = "< The type of each element in the vector."]
+    pub child_type: u32,
+}
+#[doc = " An atom:Vector.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Vector {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Vector_Body,
+}
+#[doc = " The body of an atom:Property (typically in an atom:Object)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Property_Body {
+    #[doc = "< Key (predicate) (mapped URI)."]
+    pub key: u32,
+    #[doc = "< Context URID (may be, and generally is, 0)."]
+    pub context: u32,
+    #[doc = "< Value atom header."]
+    pub value: LV2_Atom,
+}
+#[doc = " An atom:Property.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Property {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Property_Body,
+}
+#[doc = " The body of an atom:Object. May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Object_Body {
+    #[doc = "< URID, or 0 for blank."]
+    pub id: u32,
+    #[doc = "< Type URID (same as rdf:type, for fast dispatch)."]
+    pub otype: u32,
+}
+#[doc = " An atom:Object.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Object {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Object_Body,
+}
+#[doc = " The header of an atom:Event.  Note this type is NOT an LV2_Atom."]
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct LV2_Atom_Event {
+    pub time: LV2_Atom_Event__bindgen_ty_1,
+    #[doc = "< Event body atom header."]
+    pub body: LV2_Atom,
+}
+#[doc = " Time stamp.  Which type is valid is determined by context."]
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union LV2_Atom_Event__bindgen_ty_1 {
+    #[doc = "< Time in audio frames."]
+    pub frames: i64,
+    #[doc = "< Time in beats."]
+    pub beats: f64,
+    _bindgen_union_align: u64,
+}
+#[doc = "The body of an atom:Sequence (a sequence of events)."]
+#[doc = ""]
+#[doc = "The unit field is either a URID that described an appropriate time stamp"]
+#[doc = "type, or may be 0 where a default stamp type is known.  For"]
+#[doc = "LV2_Descriptor::run(), the default stamp type is audio frames."]
+#[doc = ""]
+#[doc = "The contents of a sequence is a series of LV2_Atom_Event, each aligned"]
+#[doc = "to 64-bits, for example:"]
+#[doc = "<pre>"]
+#[doc = "| Event 1 (size 6)                              | Event 2"]
+#[doc = "|       |       |       |       |       |       |       |       |"]
+#[doc = "| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |"]
+#[doc = "|FRAMES |SUBFRMS|TYPE   |SIZE   |DATADATADATAPAD|FRAMES |SUBFRMS|..."]
+#[doc = "</pre>"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Sequence_Body {
+    #[doc = "< URID of unit of event time stamps."]
+    pub unit: u32,
+    #[doc = "< Currently unused."]
+    pub pad: u32,
+}
+#[doc = " An atom:Sequence."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Sequence {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Sequence_Body,
+}
+pub type va_list = __builtin_va_list;
+#[doc = " A single entry in an Object query."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Object_Query {
+    #[doc = "< Key to query (input set by user)"]
+    pub key: u32,
+    #[doc = "< Found value (output set by query function)"]
+    pub value: *mut *const LV2_Atom,
+}
+extern "C" {
+    pub static LV2_ATOM_OBJECT_QUERY_END: LV2_Atom_Object_Query;
+}
+#[doc = "Opaque pointer to host data for LV2_URID_Map."]
+pub type LV2_URID_Map_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Opaque pointer to host data for LV2_URID_Unmap."]
+pub type LV2_URID_Unmap_Handle = *mut ::std::os::raw::c_void;
+#[doc = "URI mapped to an integer."]
+pub type LV2_URID = u32;
+#[doc = "URID Map Feature (LV2_URID__map)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_URID_Map {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "This MUST be passed to map_uri() whenever it is called."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub handle: LV2_URID_Map_Handle,
+    #[doc = "Get the numeric ID of a URI."]
+    #[doc = ""]
+    #[doc = "If the ID does not already exist, it will be created."]
+    #[doc = ""]
+    #[doc = "This function is referentially transparent; any number of calls with the"]
+    #[doc = "same arguments is guaranteed to return the same value over the life of a"]
+    #[doc = "plugin instance.  Note, however, that several URIs MAY resolve to the"]
+    #[doc = "same ID if the host considers those URIs equivalent."]
+    #[doc = ""]
+    #[doc = "This function is not necessarily very fast or RT-safe: plugins SHOULD"]
+    #[doc = "cache any IDs they might need in performance critical situations."]
+    #[doc = ""]
+    #[doc = "The return value 0 is reserved and indicates that an ID for that URI"]
+    #[doc = "could not be created for whatever reason.  However, hosts SHOULD NOT"]
+    #[doc = "return 0 from this function in non-exceptional circumstances (i.e. the"]
+    #[doc = "URI map SHOULD be dynamic)."]
+    #[doc = ""]
+    #[doc = "@param handle Must be the callback_data member of this struct."]
+    #[doc = "@param uri The URI to be mapped to an integer ID."]
+    pub map: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_URID_Map_Handle,
+            uri: *const ::std::os::raw::c_char,
+        ) -> LV2_URID,
+    >,
+}
+#[doc = "URI Unmap Feature (LV2_URID__unmap)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_URID_Unmap {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "This MUST be passed to unmap() whenever it is called."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub handle: LV2_URID_Unmap_Handle,
+    #[doc = "Get the URI for a previously mapped numeric ID."]
+    #[doc = ""]
+    #[doc = "Returns NULL if `urid` is not yet mapped.  Otherwise, the corresponding"]
+    #[doc = "URI is returned in a canonical form.  This MAY not be the exact same"]
+    #[doc = "string that was originally passed to LV2_URID_Map::map(), but it MUST be"]
+    #[doc = "an identical URI according to the URI syntax specification (RFC3986).  A"]
+    #[doc = "non-NULL return for a given `urid` will always be the same for the life"]
+    #[doc = "of the plugin.  Plugins that intend to perform string comparison on"]
+    #[doc = "unmapped URIs SHOULD first canonicalise URI strings with a call to"]
+    #[doc = "map_uri() followed by a call to unmap_uri()."]
+    #[doc = ""]
+    #[doc = "@param handle Must be the callback_data member of this struct."]
+    #[doc = "@param urid The ID to be mapped back to the URI string."]
+    pub unmap: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_URID_Unmap_Handle,
+            urid: LV2_URID,
+        ) -> *const ::std::os::raw::c_char,
+    >,
+}
+#[doc = " Handle for LV2_Atom_Forge_Sink."]
+pub type LV2_Atom_Forge_Sink_Handle = *mut ::std::os::raw::c_void;
+#[doc = " A reference to a chunk of written output."]
+pub type LV2_Atom_Forge_Ref = isize;
+#[doc = " Sink function for writing output.  See lv2_atom_forge_set_sink()."]
+pub type LV2_Atom_Forge_Sink = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_Atom_Forge_Sink_Handle,
+        buf: *const ::std::os::raw::c_void,
+        size: u32,
+    ) -> LV2_Atom_Forge_Ref,
+>;
+#[doc = " Function for resolving a reference.  See lv2_atom_forge_set_sink()."]
+pub type LV2_Atom_Forge_Deref_Func = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_Atom_Forge_Sink_Handle,
+        ref_: LV2_Atom_Forge_Ref,
+    ) -> *mut LV2_Atom,
+>;
+#[doc = " A stack frame used for keeping track of nested Atom containers."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Forge_Frame {
+    pub parent: *mut LV2_Atom_Forge_Frame,
+    pub ref_: LV2_Atom_Forge_Ref,
+}
+#[doc = " A \"forge\" for creating atoms by appending to a buffer."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Forge {
+    pub buf: *mut u8,
+    pub offset: u32,
+    pub size: u32,
+    pub sink: LV2_Atom_Forge_Sink,
+    pub deref: LV2_Atom_Forge_Deref_Func,
+    pub handle: LV2_Atom_Forge_Sink_Handle,
+    pub stack: *mut LV2_Atom_Forge_Frame,
+    pub Blank: LV2_URID,
+    pub Bool: LV2_URID,
+    pub Chunk: LV2_URID,
+    pub Double: LV2_URID,
+    pub Float: LV2_URID,
+    pub Int: LV2_URID,
+    pub Long: LV2_URID,
+    pub Literal: LV2_URID,
+    pub Object: LV2_URID,
+    pub Path: LV2_URID,
+    pub Property: LV2_URID,
+    pub Resource: LV2_URID,
+    pub Sequence: LV2_URID,
+    pub String: LV2_URID,
+    pub Tuple: LV2_URID,
+    pub URI: LV2_URID,
+    pub URID: LV2_URID,
+    pub Vector: LV2_URID,
+}
+#[doc = "Plugin Instance Handle."]
+#[doc = ""]
+#[doc = "This is a handle for one particular instance of a plugin.  It is valid to"]
+#[doc = "compare to NULL (or 0 for C++) but otherwise the host MUST NOT attempt to"]
+#[doc = "interpret it."]
+pub type LV2_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Feature."]
+#[doc = ""]
+#[doc = "Features allow hosts to make additional functionality available to plugins"]
+#[doc = "without requiring modification to the LV2 API.  Extensions may define new"]
+#[doc = "features and specify the `URI` and `data` to be used if necessary."]
+#[doc = "Some features, such as lv2:isLive, do not require the host to pass data."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Feature {
+    #[doc = "A globally unique, case-sensitive identifier (URI) for this feature."]
+    #[doc = ""]
+    #[doc = "This MUST be a valid URI string as defined by RFC 3986."]
+    pub URI: *const ::std::os::raw::c_char,
+    #[doc = "Pointer to arbitrary data."]
+    #[doc = ""]
+    #[doc = "The format of this data is defined by the extension which describes the"]
+    #[doc = "feature with the given `URI`."]
+    pub data: *mut ::std::os::raw::c_void,
+}
+#[doc = "Plugin Descriptor."]
+#[doc = ""]
+#[doc = "This structure provides the core functions necessary to instantiate and use"]
+#[doc = "a plugin."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Descriptor {
+    #[doc = "A globally unique, case-sensitive identifier for this plugin."]
+    #[doc = ""]
+    #[doc = "This MUST be a valid URI string as defined by RFC 3986.  All plugins with"]
+    #[doc = "the same URI MUST be compatible to some degree, see"]
+    #[doc = "http://lv2plug.in/ns/lv2core for details."]
+    pub URI: *const ::std::os::raw::c_char,
+    #[doc = "Instantiate the plugin."]
+    #[doc = ""]
+    #[doc = "Note that instance initialisation should generally occur in activate()"]
+    #[doc = "rather than here. If a host calls instantiate(), it MUST call cleanup()"]
+    #[doc = "at some point in the future."]
+    #[doc = ""]
+    #[doc = "@param descriptor Descriptor of the plugin to instantiate."]
+    #[doc = ""]
+    #[doc = "@param sample_rate Sample rate, in Hz, for the new plugin instance."]
+    #[doc = ""]
+    #[doc = "@param bundle_path Path to the LV2 bundle which contains this plugin"]
+    #[doc = "binary. It MUST include the trailing directory separator so that simply"]
+    #[doc = "appending a filename will yield the path to that file in the bundle."]
+    #[doc = ""]
+    #[doc = "@param features A NULL terminated array of LV2_Feature structs which"]
+    #[doc = "represent the features the host supports. Plugins may refuse to"]
+    #[doc = "instantiate if required features are not found here. However, hosts MUST"]
+    #[doc = "NOT use this as a discovery mechanism: instead, use the RDF data to"]
+    #[doc = "determine which features are required and do not attempt to instantiate"]
+    #[doc = "unsupported plugins at all. This parameter MUST NOT be NULL, i.e. a host"]
+    #[doc = "that supports no features MUST pass a single element array containing"]
+    #[doc = "NULL."]
+    #[doc = ""]
+    #[doc = "@return A handle for the new plugin instance, or NULL if instantiation"]
+    #[doc = "has failed."]
+    pub instantiate: ::std::option::Option<
+        unsafe extern "C" fn(
+            descriptor: *const LV2_Descriptor,
+            sample_rate: f64,
+            bundle_path: *const ::std::os::raw::c_char,
+            features: *const *const LV2_Feature,
+        ) -> LV2_Handle,
+    >,
+    #[doc = "Connect a port on a plugin instance to a memory location."]
+    #[doc = ""]
+    #[doc = "Plugin writers should be aware that the host may elect to use the same"]
+    #[doc = "buffer for more than one port and even use the same buffer for both"]
+    #[doc = "input and output (see lv2:inPlaceBroken in lv2.ttl)."]
+    #[doc = ""]
+    #[doc = "If the plugin has the feature lv2:hardRTCapable then there are various"]
+    #[doc = "things that the plugin MUST NOT do within the connect_port() function;"]
+    #[doc = "see lv2core.ttl for details."]
+    #[doc = ""]
+    #[doc = "connect_port() MUST be called at least once for each port before run()"]
+    #[doc = "is called, unless that port is lv2:connectionOptional. The plugin must"]
+    #[doc = "pay careful attention to the block size passed to run() since the block"]
+    #[doc = "allocated may only just be large enough to contain the data, and is not"]
+    #[doc = "guaranteed to remain constant between run() calls."]
+    #[doc = ""]
+    #[doc = "connect_port() may be called more than once for a plugin instance to"]
+    #[doc = "allow the host to change the buffers that the plugin is reading or"]
+    #[doc = "writing. These calls may be made before or after activate() or"]
+    #[doc = "deactivate() calls."]
+    #[doc = ""]
+    #[doc = "@param instance Plugin instance containing the port."]
+    #[doc = ""]
+    #[doc = "@param port Index of the port to connect. The host MUST NOT try to"]
+    #[doc = "connect a port index that is not defined in the plugin's RDF data. If"]
+    #[doc = "it does, the plugin's behaviour is undefined (a crash is likely)."]
+    #[doc = ""]
+    #[doc = "@param data_location Pointer to data of the type defined by the port"]
+    #[doc = "type in the plugin's RDF data (for example, an array of float for an"]
+    #[doc = "lv2:AudioPort). This pointer must be stored by the plugin instance and"]
+    #[doc = "used to read/write data when run() is called. Data present at the time"]
+    #[doc = "of the connect_port() call MUST NOT be considered meaningful."]
+    pub connect_port: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            port: u32,
+            data_location: *mut ::std::os::raw::c_void,
+        ),
+    >,
+    #[doc = "Initialise a plugin instance and activate it for use."]
+    #[doc = ""]
+    #[doc = "This is separated from instantiate() to aid real-time support and so"]
+    #[doc = "that hosts can reinitialise a plugin instance by calling deactivate()"]
+    #[doc = "and then activate(). In this case the plugin instance MUST reset all"]
+    #[doc = "state information dependent on the history of the plugin instance except"]
+    #[doc = "for any data locations provided by connect_port(). If there is nothing"]
+    #[doc = "for activate() to do then this field may be NULL."]
+    #[doc = ""]
+    #[doc = "When present, hosts MUST call this function once before run() is called"]
+    #[doc = "for the first time. This call SHOULD be made as close to the run() call"]
+    #[doc = "as possible and indicates to real-time plugins that they are now live,"]
+    #[doc = "however plugins MUST NOT rely on a prompt call to run() after"]
+    #[doc = "activate()."]
+    #[doc = ""]
+    #[doc = "The host MUST NOT call activate() again until deactivate() has been"]
+    #[doc = "called first. If a host calls activate(), it MUST call deactivate() at"]
+    #[doc = "some point in the future. Note that connect_port() may be called before"]
+    #[doc = "or after activate()."]
+    pub activate: ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle)>,
+    #[doc = "Run a plugin instance for a block."]
+    #[doc = ""]
+    #[doc = "Note that if an activate() function exists then it must be called before"]
+    #[doc = "run(). If deactivate() is called for a plugin instance then run() may"]
+    #[doc = "not be called until activate() has been called again."]
+    #[doc = ""]
+    #[doc = "If the plugin has the feature lv2:hardRTCapable then there are various"]
+    #[doc = "things that the plugin MUST NOT do within the run() function (see"]
+    #[doc = "lv2core.ttl for details)."]
+    #[doc = ""]
+    #[doc = "As a special case, when `sample_count` is 0, the plugin should update"]
+    #[doc = "any output ports that represent a single instant in time (for example,"]
+    #[doc = "control ports, but not audio ports). This is particularly useful for"]
+    #[doc = "latent plugins, which should update their latency output port so hosts"]
+    #[doc = "can pre-roll plugins to compute latency. Plugins MUST NOT crash when"]
+    #[doc = "`sample_count` is 0."]
+    #[doc = ""]
+    #[doc = "@param instance Instance to be run."]
+    #[doc = ""]
+    #[doc = "@param sample_count The block size (in samples) for which the plugin"]
+    #[doc = "instance must run."]
+    pub run: ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle, sample_count: u32)>,
+    #[doc = "Deactivate a plugin instance (counterpart to activate())."]
+    #[doc = ""]
+    #[doc = "Hosts MUST deactivate all activated instances after they have been run()"]
+    #[doc = "for the last time. This call SHOULD be made as close to the last run()"]
+    #[doc = "call as possible and indicates to real-time plugins that they are no"]
+    #[doc = "longer live, however plugins MUST NOT rely on prompt deactivation. If"]
+    #[doc = "there is nothing for deactivate() to do then this field may be NULL"]
+    #[doc = ""]
+    #[doc = "Deactivation is not similar to pausing since the plugin instance will be"]
+    #[doc = "reinitialised by activate(). However, deactivate() itself MUST NOT fully"]
+    #[doc = "reset plugin state. For example, the host may deactivate a plugin, then"]
+    #[doc = "store its state (using some extension to do so)."]
+    #[doc = ""]
+    #[doc = "Hosts MUST NOT call deactivate() unless activate() was previously"]
+    #[doc = "called. Note that connect_port() may be called before or after"]
+    #[doc = "deactivate()."]
+    pub deactivate: ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle)>,
+    #[doc = "Clean up a plugin instance (counterpart to instantiate())."]
+    #[doc = ""]
+    #[doc = "Once an instance of a plugin has been finished with it must be deleted"]
+    #[doc = "using this function. The instance handle passed ceases to be valid after"]
+    #[doc = "this call."]
+    #[doc = ""]
+    #[doc = "If activate() was called for a plugin instance then a corresponding call"]
+    #[doc = "to deactivate() MUST be made before cleanup() is called. Hosts MUST NOT"]
+    #[doc = "call cleanup() unless instantiate() was previously called."]
+    pub cleanup: ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle)>,
+    #[doc = "Return additional plugin data defined by some extenion."]
+    #[doc = ""]
+    #[doc = "A typical use of this facility is to return a struct containing function"]
+    #[doc = "pointers to extend the LV2_Descriptor API."]
+    #[doc = ""]
+    #[doc = "The actual type and meaning of the returned object MUST be specified"]
+    #[doc = "precisely by the extension. This function MUST return NULL for any"]
+    #[doc = "unsupported URI. If a plugin does not support any extension data, this"]
+    #[doc = "field may be NULL."]
+    #[doc = ""]
+    #[doc = "The host is never responsible for freeing the returned value."]
+    pub extension_data: ::std::option::Option<
+        unsafe extern "C" fn(uri: *const ::std::os::raw::c_char) -> *const ::std::os::raw::c_void,
+    >,
+}
+#[doc = "Type of the lv2_descriptor() function in a library (old discovery API)."]
+pub type LV2_Descriptor_Function =
+    ::std::option::Option<unsafe extern "C" fn(index: u32) -> *const LV2_Descriptor>;
+#[doc = "Handle for a library descriptor."]
+pub type LV2_Lib_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Descriptor for a plugin library."]
+#[doc = ""]
+#[doc = "To access a plugin library, the host creates an LV2_Lib_Descriptor via the"]
+#[doc = "lv2_lib_descriptor() function in the shared object."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Lib_Descriptor {
+    #[doc = "Opaque library data which must be passed as the first parameter to all"]
+    #[doc = "the methods of this struct."]
+    pub handle: LV2_Lib_Handle,
+    #[doc = "The total size of this struct.  This allows for this struct to be"]
+    #[doc = "expanded in the future if necessary.  This MUST be set by the library to"]
+    #[doc = "sizeof(LV2_Lib_Descriptor).  The host MUST NOT access any fields of this"]
+    #[doc = "struct beyond get_plugin() unless this field indicates they are present."]
+    pub size: u32,
+    #[doc = "Destroy this library descriptor and free all related resources."]
+    pub cleanup: ::std::option::Option<unsafe extern "C" fn(handle: LV2_Lib_Handle)>,
+    #[doc = "Plugin accessor."]
+    #[doc = ""]
+    #[doc = "Plugins are accessed by index using values from 0 upwards.  Out of range"]
+    #[doc = "indices MUST result in this function returning NULL, so the host can"]
+    #[doc = "enumerate plugins by increasing `index` until NULL is returned."]
+    pub get_plugin: ::std::option::Option<
+        unsafe extern "C" fn(handle: LV2_Lib_Handle, index: u32) -> *const LV2_Descriptor,
+    >,
+}
+#[doc = "Type of the lv2_lib_descriptor() function in an LV2 library."]
+pub type LV2_Lib_Descriptor_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        bundle_path: *const ::std::os::raw::c_char,
+        features: *const *const LV2_Feature,
+    ) -> *const LV2_Lib_Descriptor,
+>;
+#[doc = "The data field of the LV2_Feature for this extension."]
+#[doc = ""]
+#[doc = "To support this feature the host must pass an LV2_Feature struct to the"]
+#[doc = "instantiate method with URI \"http://lv2plug.in/ns/ext/data-access\""]
+#[doc = "and data pointed to an instance of this struct."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Extension_Data_Feature {
+    #[doc = "A pointer to a method the UI can call to get data (of a type specified"]
+    #[doc = "by some other extension) from the plugin."]
+    #[doc = ""]
+    #[doc = "This call never is never guaranteed to return anything, UIs should"]
+    #[doc = "degrade gracefully if direct access to the plugin data is not possible"]
+    #[doc = "(in which case this function will return NULL)."]
+    #[doc = ""]
+    #[doc = "This is for access to large data that can only possibly work if the UI"]
+    #[doc = "and plugin are running in the same process.  For all other things, use"]
+    #[doc = "the normal LV2 UI communication system."]
+    pub data_access: ::std::option::Option<
+        unsafe extern "C" fn(uri: *const ::std::os::raw::c_char) -> *const ::std::os::raw::c_void,
+    >,
+}
+#[doc = "Dynamic manifest generator handle."]
+#[doc = ""]
+#[doc = "This handle indicates a particular status of a dynamic manifest generator."]
+#[doc = "The host MUST NOT attempt to interpret it and, unlikely LV2_Handle, it is"]
+#[doc = "NOT even valid to compare this to NULL. The dynamic manifest generator MAY"]
+#[doc = "use it to reference internal data."]
+pub type LV2_Dyn_Manifest_Handle = *mut ::std::os::raw::c_void;
+pub const LV2_EVENT_PPQN: u32 = 3136573440;
+#[doc = "An LV2 event (header only)."]
+#[doc = ""]
+#[doc = "LV2 events are generic time-stamped containers for any type of event."]
+#[doc = "The type field defines the format of a given event's contents."]
+#[doc = ""]
+#[doc = "This struct defines the header of an LV2 event. An LV2 event is a single"]
+#[doc = "chunk of POD (plain old data), usually contained in a flat buffer (see"]
+#[doc = "LV2_EventBuffer below). Unless a required feature says otherwise, hosts may"]
+#[doc = "assume a deep copy of an LV2 event can be created safely using a simple:"]
+#[doc = ""]
+#[doc = "memcpy(ev_copy, ev, sizeof(LV2_Event) + ev->size);  (or equivalent)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Event {
+    #[doc = "The frames portion of timestamp. The units used here can optionally be"]
+    #[doc = "set for a port (with the lv2ev:timeUnits property), otherwise this is"]
+    #[doc = "audio frames, corresponding to the sample_count parameter of the LV2 run"]
+    #[doc = "method (frame 0 is the first frame for that call to run)."]
+    pub frames: u32,
+    #[doc = "The sub-frames portion of timestamp. The units used here can optionally"]
+    #[doc = "be set for a port (with the lv2ev:timeUnits property), otherwise this is"]
+    #[doc = "1/(2^32) of an audio frame."]
+    pub subframes: u32,
+    #[doc = "The type of this event, as a number which represents some URI"]
+    #[doc = "defining an event type. This value MUST be some value previously"]
+    #[doc = "returned from a call to the uri_to_id function defined in the LV2"]
+    #[doc = "URI map extension (see lv2_uri_map.h)."]
+    #[doc = "There are special rules which must be followed depending on the type"]
+    #[doc = "of an event. If the plugin recognizes an event type, the definition"]
+    #[doc = "of that event type will describe how to interpret the event, and"]
+    #[doc = "any required behaviour. Otherwise, if the type is 0, this event is a"]
+    #[doc = "non-POD event and lv2_event_unref MUST be called if the event is"]
+    #[doc = "'dropped' (see above). Even if the plugin does not understand an event,"]
+    #[doc = "it may pass the event through to an output by simply copying (and NOT"]
+    #[doc = "calling lv2_event_unref). These rules are designed to allow for generic"]
+    #[doc = "event handling plugins and large non-POD events, but with minimal hassle"]
+    #[doc = "on simple plugins that \"don't care\" about these more advanced features."]
+    pub type_: u16,
+    #[doc = "The size of the data portion of this event in bytes, which immediately"]
+    #[doc = "follows. The header size (12 bytes) is not included in this value."]
+    pub size: u16,
+}
+#[doc = "A buffer of LV2 events (header only)."]
+#[doc = ""]
+#[doc = "Like events (which this contains) an event buffer is a single chunk of POD:"]
+#[doc = "the entire buffer (including contents) can be copied with a single memcpy."]
+#[doc = "The first contained event begins sizeof(LV2_EventBuffer) bytes after the"]
+#[doc = "start of this struct."]
+#[doc = ""]
+#[doc = "After this header, the buffer contains an event header (defined by struct"]
+#[doc = "LV2_Event), followed by that event's contents (padded to 64 bits), followed"]
+#[doc = "by another header, etc:"]
+#[doc = ""]
+#[doc = "|       |       |       |       |       |       |"]
+#[doc = "| | | | | | | | | | | | | | | | | | | | | | | | |"]
+#[doc = "|FRAMES |SUBFRMS|TYP|LEN|DATA..DATA..PAD|FRAMES | ..."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Event_Buffer {
+    #[doc = "The contents of the event buffer. This may or may not reside in the"]
+    #[doc = "same block of memory as this header, plugins must not assume either."]
+    #[doc = "The host guarantees this points to at least capacity bytes of allocated"]
+    #[doc = "memory (though only size bytes of that are valid events)."]
+    pub data: *mut u8,
+    #[doc = "The size of this event header in bytes (including everything)."]
+    #[doc = ""]
+    #[doc = "This is to allow for extending this header in the future without"]
+    #[doc = "breaking binary compatibility. Whenever this header is copied,"]
+    #[doc = "it MUST be done using this field (and NOT the sizeof this struct)."]
+    pub header_size: u16,
+    #[doc = "The type of the time stamps for events in this buffer."]
+    #[doc = "As a special exception, '0' always means audio frames and subframes"]
+    #[doc = "(1/UINT32_MAX'th of a frame) in the sample rate passed to instantiate."]
+    #[doc = ""]
+    #[doc = "INPUTS: The host must set this field to the numeric ID of some URI"]
+    #[doc = "defining the meaning of the frames/subframes fields of contained events"]
+    #[doc = "(obtained by the LV2 URI Map uri_to_id function with the URI of this"]
+    #[doc = "extension as the 'map' argument, see lv2_uri_map.h).  The host must"]
+    #[doc = "never pass a plugin a buffer which uses a stamp type the plugin does not"]
+    #[doc = "'understand'. The value of this field must never change, except when"]
+    #[doc = "connect_port is called on the input port, at which time the host MUST"]
+    #[doc = "have set the stamp_type field to the value that will be used for all"]
+    #[doc = "subsequent run calls."]
+    #[doc = ""]
+    #[doc = "OUTPUTS: The plugin may set this to any value that has been returned"]
+    #[doc = "from uri_to_id with the URI of this extension for a 'map' argument."]
+    #[doc = "When connected to a buffer with connect_port, output ports MUST set this"]
+    #[doc = "field to the type of time stamp they will be writing. On any call to"]
+    #[doc = "connect_port on an event input port, the plugin may change this field on"]
+    #[doc = "any output port, it is the responsibility of the host to check if any of"]
+    #[doc = "these values have changed and act accordingly."]
+    pub stamp_type: u16,
+    #[doc = "The number of events in this buffer."]
+    #[doc = ""]
+    #[doc = "INPUTS: The host must set this field to the number of events contained"]
+    #[doc = "in the data buffer before calling run(). The plugin must not change"]
+    #[doc = "this field."]
+    #[doc = ""]
+    #[doc = "OUTPUTS: The plugin must set this field to the number of events it has"]
+    #[doc = "written to the buffer before returning from run(). Any initial value"]
+    #[doc = "should be ignored by the plugin."]
+    pub event_count: u32,
+    #[doc = "The size of the data buffer in bytes."]
+    #[doc = "This is set by the host and must not be changed by the plugin."]
+    #[doc = "The host is allowed to change this between run() calls."]
+    pub capacity: u32,
+    #[doc = "The size of the initial portion of the data buffer containing data."]
+    #[doc = ""]
+    #[doc = "INPUTS: The host must set this field to the number of bytes used"]
+    #[doc = "by all events it has written to the buffer (including headers)"]
+    #[doc = "before calling the plugin's run()."]
+    #[doc = "The plugin must not change this field."]
+    #[doc = ""]
+    #[doc = "OUTPUTS: The plugin must set this field to the number of bytes"]
+    #[doc = "used by all events it has written to the buffer (including headers)"]
+    #[doc = "before returning from run()."]
+    #[doc = "Any initial value should be ignored by the plugin."]
+    pub size: u32,
+}
+#[doc = "Opaque pointer to host data."]
+pub type LV2_Event_Callback_Data = *mut ::std::os::raw::c_void;
+#[doc = "Non-POD events feature."]
+#[doc = ""]
+#[doc = "To support this feature the host must pass an LV2_Feature struct to the"]
+#[doc = "plugin's instantiate method with URI \"http://lv2plug.in/ns/ext/event\""]
+#[doc = "and data pointed to an instance of this struct.  Note this feature"]
+#[doc = "is not mandatory to support the event extension."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Event_Feature {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "The plugin MUST pass this to any call to functions in this struct."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub callback_data: LV2_Event_Callback_Data,
+    #[doc = "Take a reference to a non-POD event."]
+    #[doc = ""]
+    #[doc = "If a plugin receives an event with type 0, it means the event is a"]
+    #[doc = "pointer to some object in memory and not a flat sequence of bytes"]
+    #[doc = "in the buffer. When receiving a non-POD event, the plugin already"]
+    #[doc = "has an implicit reference to the event. If the event is stored AND"]
+    #[doc = "passed to an output, lv2_event_ref MUST be called on that event."]
+    #[doc = "If the event is only stored OR passed through, this is not necessary"]
+    #[doc = "(as the plugin already has 1 implicit reference)."]
+    #[doc = ""]
+    #[doc = "@param event An event received at an input that will not be copied to"]
+    #[doc = "an output or stored in any way."]
+    #[doc = ""]
+    #[doc = "@param context The calling context. Like event types, this is a mapped"]
+    #[doc = "URI, see lv2_context.h. Simple plugin with just a run() method should"]
+    #[doc = "pass 0 here (the ID of the 'standard' LV2 run context). The host"]
+    #[doc = "guarantees that this function is realtime safe iff the context is"]
+    #[doc = "realtime safe."]
+    #[doc = ""]
+    #[doc = "PLUGINS THAT VIOLATE THESE RULES MAY CAUSE CRASHES AND MEMORY LEAKS."]
+    pub lv2_event_ref: ::std::option::Option<
+        unsafe extern "C" fn(callback_data: LV2_Event_Callback_Data, event: *mut LV2_Event) -> u32,
+    >,
+    #[doc = "Drop a reference to a non-POD event."]
+    #[doc = ""]
+    #[doc = "If a plugin receives an event with type 0, it means the event is a"]
+    #[doc = "pointer to some object in memory and not a flat sequence of bytes"]
+    #[doc = "in the buffer. If the plugin does not pass the event through to"]
+    #[doc = "an output or store it internally somehow, it MUST call this function"]
+    #[doc = "on the event (more information on using non-POD events below)."]
+    #[doc = ""]
+    #[doc = "@param event An event received at an input that will not be copied to an"]
+    #[doc = "output or stored in any way."]
+    #[doc = ""]
+    #[doc = "@param context The calling context. Like event types, this is a mapped"]
+    #[doc = "URI, see lv2_context.h. Simple plugin with just a run() method should"]
+    #[doc = "pass 0 here (the ID of the 'standard' LV2 run context). The host"]
+    #[doc = "guarantees that this function is realtime safe iff the context is"]
+    #[doc = "realtime safe."]
+    #[doc = ""]
+    #[doc = "PLUGINS THAT VIOLATE THESE RULES MAY CAUSE CRASHES AND MEMORY LEAKS."]
+    pub lv2_event_unref: ::std::option::Option<
+        unsafe extern "C" fn(callback_data: LV2_Event_Callback_Data, event: *mut LV2_Event) -> u32,
+    >,
+}
+#[doc = " An iterator over an LV2_Event_Buffer."]
+#[doc = ""]
+#[doc = " Multiple simultaneous read iterators over a single buffer is fine,"]
+#[doc = " but changing the buffer invalidates all iterators."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Event_Iterator {
+    pub buf: *mut LV2_Event_Buffer,
+    pub offset: u32,
+}
+#[doc = "Opaque data to host data for LV2_Log_Log."]
+pub type LV2_Log_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Log feature (LV2_LOG__log)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Log_Log {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "This MUST be passed to methods in this struct whenever they are called."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub handle: LV2_Log_Handle,
+    #[doc = "Log a message, passing format parameters directly."]
+    #[doc = ""]
+    #[doc = "The API of this function matches that of the standard C printf function,"]
+    #[doc = "except for the addition of the first two parameters.  This function may"]
+    #[doc = "be called from any non-realtime context, or from any context if `type`"]
+    #[doc = "is @ref LV2_LOG__Trace."]
+    pub printf: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_Log_Handle,
+            type_: LV2_URID,
+            fmt: *const ::std::os::raw::c_char,
+            ...
+        ) -> ::std::os::raw::c_int,
+    >,
+    #[doc = "Log a message, passing format parameters in a va_list."]
+    #[doc = ""]
+    #[doc = "The API of this function matches that of the standard C vprintf"]
+    #[doc = "function, except for the addition of the first two parameters.  This"]
+    #[doc = "function may be called from any non-realtime context, or from any"]
+    #[doc = "context if `type` is @ref LV2_LOG__Trace."]
+    pub vprintf: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_Log_Handle,
+            type_: LV2_URID,
+            fmt: *const ::std::os::raw::c_char,
+            ap: va_list,
+        ) -> ::std::os::raw::c_int,
+    >,
+}
+#[doc = "Logger convenience API state."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Log_Logger {
+    pub log: *mut LV2_Log_Log,
+    pub Error: LV2_URID,
+    pub Note: LV2_URID,
+    pub Trace: LV2_URID,
+    pub Warning: LV2_URID,
+}
+#[doc = "< Invalid Message"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_INVALID: LV2_Midi_Message_Type = 0;
+#[doc = "< Note Off"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_NOTE_OFF: LV2_Midi_Message_Type = 128;
+#[doc = "< Note On"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_NOTE_ON: LV2_Midi_Message_Type = 144;
+#[doc = "< Note Pressure"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_NOTE_PRESSURE: LV2_Midi_Message_Type = 160;
+#[doc = "< Controller"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_CONTROLLER: LV2_Midi_Message_Type = 176;
+#[doc = "< Program Change"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_PGM_CHANGE: LV2_Midi_Message_Type = 192;
+#[doc = "< Channel Pressure"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_CHANNEL_PRESSURE: LV2_Midi_Message_Type = 208;
+#[doc = "< Pitch Bender"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_BENDER: LV2_Midi_Message_Type = 224;
+#[doc = "< System Exclusive Begin"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_SYSTEM_EXCLUSIVE: LV2_Midi_Message_Type = 240;
+#[doc = "< MTC Quarter Frame"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_MTC_QUARTER: LV2_Midi_Message_Type = 241;
+#[doc = "< Song Position"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_SONG_POS: LV2_Midi_Message_Type = 242;
+#[doc = "< Song Select"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_SONG_SELECT: LV2_Midi_Message_Type = 243;
+#[doc = "< Tune Request"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_TUNE_REQUEST: LV2_Midi_Message_Type = 246;
+#[doc = "< Clock"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_CLOCK: LV2_Midi_Message_Type = 248;
+#[doc = "< Start"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_START: LV2_Midi_Message_Type = 250;
+#[doc = "< Continue"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_CONTINUE: LV2_Midi_Message_Type = 251;
+#[doc = "< Stop"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_STOP: LV2_Midi_Message_Type = 252;
+#[doc = "< Active Sensing"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_ACTIVE_SENSE: LV2_Midi_Message_Type = 254;
+#[doc = "< Reset"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_RESET: LV2_Midi_Message_Type = 255;
+#[doc = "MIDI Message Type."]
+#[doc = ""]
+#[doc = "This includes both voice messages (which have a channel) and system messages"]
+#[doc = "(which do not), as well as a sentinel value for invalid messages.  To get"]
+#[doc = "the type of a message suitable for use in a switch statement, use"]
+#[doc = "lv2_midi_get_type() on the status byte."]
+pub type LV2_Midi_Message_Type = u32;
+#[doc = "< Bank Selection"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_BANK: LV2_Midi_Controller = 0;
+#[doc = "< Modulation"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_MODWHEEL: LV2_Midi_Controller = 1;
+#[doc = "< Breath"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_BREATH: LV2_Midi_Controller = 2;
+#[doc = "< Foot"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_FOOT: LV2_Midi_Controller = 4;
+#[doc = "< Portamento Time"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_PORTAMENTO_TIME: LV2_Midi_Controller = 5;
+#[doc = "< Data Entry"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_DATA_ENTRY: LV2_Midi_Controller = 6;
+#[doc = "< Main Volume"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_MAIN_VOLUME: LV2_Midi_Controller = 7;
+#[doc = "< Balance"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_BALANCE: LV2_Midi_Controller = 8;
+#[doc = "< Panpot"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_PAN: LV2_Midi_Controller = 10;
+#[doc = "< Expression"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_EXPRESSION: LV2_Midi_Controller = 11;
+#[doc = "< Effect1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_EFFECT1: LV2_Midi_Controller = 12;
+#[doc = "< Effect2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_EFFECT2: LV2_Midi_Controller = 13;
+#[doc = "< General Purpose 1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_GENERAL_PURPOSE1: LV2_Midi_Controller = 16;
+#[doc = "< General Purpose 2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_GENERAL_PURPOSE2: LV2_Midi_Controller = 17;
+#[doc = "< General Purpose 3"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_GENERAL_PURPOSE3: LV2_Midi_Controller = 18;
+#[doc = "< General Purpose 4"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_GENERAL_PURPOSE4: LV2_Midi_Controller = 19;
+#[doc = "< Bank Selection"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_BANK: LV2_Midi_Controller = 32;
+#[doc = "< Modulation"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_MODWHEEL: LV2_Midi_Controller = 33;
+#[doc = "< Breath"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_BREATH: LV2_Midi_Controller = 34;
+#[doc = "< Foot"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_FOOT: LV2_Midi_Controller = 36;
+#[doc = "< Portamento Time"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_PORTAMENTO_TIME: LV2_Midi_Controller = 37;
+#[doc = "< Data Entry"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_DATA_ENTRY: LV2_Midi_Controller = 38;
+#[doc = "< Main Volume"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_MAIN_VOLUME: LV2_Midi_Controller = 39;
+#[doc = "< Balance"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_BALANCE: LV2_Midi_Controller = 40;
+#[doc = "< Panpot"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_PAN: LV2_Midi_Controller = 42;
+#[doc = "< Expression"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_EXPRESSION: LV2_Midi_Controller = 43;
+#[doc = "< Effect1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_EFFECT1: LV2_Midi_Controller = 44;
+#[doc = "< Effect2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_EFFECT2: LV2_Midi_Controller = 45;
+#[doc = "< General Purpose 1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_GENERAL_PURPOSE1: LV2_Midi_Controller = 48;
+#[doc = "< General Purpose 2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_GENERAL_PURPOSE2: LV2_Midi_Controller = 49;
+#[doc = "< General Purpose 3"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_GENERAL_PURPOSE3: LV2_Midi_Controller = 50;
+#[doc = "< General Purpose 4"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_GENERAL_PURPOSE4: LV2_Midi_Controller = 51;
+#[doc = "< Sustain Pedal"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SUSTAIN: LV2_Midi_Controller = 64;
+#[doc = "< Portamento"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_PORTAMENTO: LV2_Midi_Controller = 65;
+#[doc = "< Sostenuto"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SOSTENUTO: LV2_Midi_Controller = 66;
+#[doc = "< Soft Pedal"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SOFT_PEDAL: LV2_Midi_Controller = 67;
+#[doc = "< Legato Foot Switch"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LEGATO_FOOTSWITCH: LV2_Midi_Controller = 68;
+#[doc = "< Hold2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_HOLD2: LV2_Midi_Controller = 69;
+#[doc = "< SC1 Sound Variation"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC1_SOUND_VARIATION: LV2_Midi_Controller = 70;
+#[doc = "< SC2 Timbre"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC2_TIMBRE: LV2_Midi_Controller = 71;
+#[doc = "< SC3 Release Time"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC3_RELEASE_TIME: LV2_Midi_Controller = 72;
+#[doc = "< SC4 Attack Time"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC4_ATTACK_TIME: LV2_Midi_Controller = 73;
+#[doc = "< SC5 Brightness"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC5_BRIGHTNESS: LV2_Midi_Controller = 74;
+#[doc = "< SC6"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC6: LV2_Midi_Controller = 75;
+#[doc = "< SC7"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC7: LV2_Midi_Controller = 76;
+#[doc = "< SC8"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC8: LV2_Midi_Controller = 77;
+#[doc = "< SC9"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC9: LV2_Midi_Controller = 78;
+#[doc = "< SC10"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC10: LV2_Midi_Controller = 79;
+#[doc = "< General Purpose 5"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_GENERAL_PURPOSE5: LV2_Midi_Controller = 80;
+#[doc = "< General Purpose 6"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_GENERAL_PURPOSE6: LV2_Midi_Controller = 81;
+#[doc = "< General Purpose 7"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_GENERAL_PURPOSE7: LV2_Midi_Controller = 82;
+#[doc = "< General Purpose 8"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_GENERAL_PURPOSE8: LV2_Midi_Controller = 83;
+#[doc = "< Portamento Control"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_PORTAMENTO_CONTROL: LV2_Midi_Controller = 84;
+#[doc = "< E1 Reverb Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E1_REVERB_DEPTH: LV2_Midi_Controller = 91;
+#[doc = "< E2 Tremolo Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E2_TREMOLO_DEPTH: LV2_Midi_Controller = 92;
+#[doc = "< E3 Chorus Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E3_CHORUS_DEPTH: LV2_Midi_Controller = 93;
+#[doc = "< E4 Detune Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E4_DETUNE_DEPTH: LV2_Midi_Controller = 94;
+#[doc = "< E5 Phaser Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E5_PHASER_DEPTH: LV2_Midi_Controller = 95;
+#[doc = "< Data Increment"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_DATA_INCREMENT: LV2_Midi_Controller = 96;
+#[doc = "< Data Decrement"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_DATA_DECREMENT: LV2_Midi_Controller = 97;
+#[doc = "< Non-registered Parameter Number"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_NRPN_LSB: LV2_Midi_Controller = 98;
+#[doc = "< Non-registered Parameter Number"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_NRPN_MSB: LV2_Midi_Controller = 99;
+#[doc = "< Registered Parameter Number"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_RPN_LSB: LV2_Midi_Controller = 100;
+#[doc = "< Registered Parameter Number"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_RPN_MSB: LV2_Midi_Controller = 101;
+#[doc = "< All Sounds Off"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_ALL_SOUNDS_OFF: LV2_Midi_Controller = 120;
+#[doc = "< Reset Controllers"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_RESET_CONTROLLERS: LV2_Midi_Controller = 121;
+#[doc = "< Local Control Switch"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LOCAL_CONTROL_SWITCH: LV2_Midi_Controller = 122;
+#[doc = "< All Notes Off"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_ALL_NOTES_OFF: LV2_Midi_Controller = 123;
+#[doc = "< Omni Off"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_OMNI_OFF: LV2_Midi_Controller = 124;
+#[doc = "< Omni On"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_OMNI_ON: LV2_Midi_Controller = 125;
+#[doc = "< Mono1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MONO1: LV2_Midi_Controller = 126;
+#[doc = "< Mono2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MONO2: LV2_Midi_Controller = 127;
+#[doc = "Standard MIDI Controller Numbers."]
+pub type LV2_Midi_Controller = u32;
+#[doc = "This option applies to the instance itself.  The subject must be"]
+#[doc = "ignored."]
+pub const LV2_Options_Context_LV2_OPTIONS_INSTANCE: LV2_Options_Context = 0;
+#[doc = "This option applies to some named resource.  The subject is a URI mapped"]
+#[doc = "to an integer (a LV2_URID, like the key)"]
+pub const LV2_Options_Context_LV2_OPTIONS_RESOURCE: LV2_Options_Context = 1;
+#[doc = "This option applies to some blank node.  The subject is a blank node"]
+#[doc = "identifier, which is valid only within the current local scope."]
+pub const LV2_Options_Context_LV2_OPTIONS_BLANK: LV2_Options_Context = 2;
+#[doc = "This option applies to a port on the instance.  The subject is the"]
+#[doc = "port's index."]
+pub const LV2_Options_Context_LV2_OPTIONS_PORT: LV2_Options_Context = 3;
+#[doc = "The context of an Option, which defines the subject it applies to."]
+pub type LV2_Options_Context = u32;
+#[doc = "An option."]
+#[doc = ""]
+#[doc = "This is a property with a subject, also known as a triple or statement."]
+#[doc = ""]
+#[doc = "This struct is useful anywhere a statement needs to be passed where no"]
+#[doc = "memory ownership issues are present (since the value is a const pointer)."]
+#[doc = ""]
+#[doc = "Options can be passed to an instance via the feature LV2_OPTIONS__options"]
+#[doc = "with data pointed to an array of options terminated by a zeroed option, or"]
+#[doc = "accessed/manipulated using LV2_Options_Interface."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Options_Option {
+    #[doc = "< Context (type of subject)."]
+    pub context: LV2_Options_Context,
+    #[doc = "< Subject."]
+    pub subject: u32,
+    #[doc = "< Key (property)."]
+    pub key: LV2_URID,
+    #[doc = "< Size of value in bytes."]
+    pub size: u32,
+    #[doc = "< Type of value (datatype)."]
+    pub type_: LV2_URID,
+    #[doc = "< Pointer to value (object)."]
+    pub value: *const ::std::os::raw::c_void,
+}
+#[doc = "< Completed successfully."]
+pub const LV2_Options_Status_LV2_OPTIONS_SUCCESS: LV2_Options_Status = 0;
+#[doc = "< Unknown error."]
+pub const LV2_Options_Status_LV2_OPTIONS_ERR_UNKNOWN: LV2_Options_Status = 1;
+#[doc = "< Invalid/unsupported subject."]
+pub const LV2_Options_Status_LV2_OPTIONS_ERR_BAD_SUBJECT: LV2_Options_Status = 2;
+#[doc = "< Invalid/unsupported key."]
+pub const LV2_Options_Status_LV2_OPTIONS_ERR_BAD_KEY: LV2_Options_Status = 4;
+#[doc = "< Invalid/unsupported value."]
+pub const LV2_Options_Status_LV2_OPTIONS_ERR_BAD_VALUE: LV2_Options_Status = 8;
+#[doc = " A status code for option functions."]
+pub type LV2_Options_Status = u32;
+#[doc = "Interface for dynamically setting options (LV2_OPTIONS__interface)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Options_Interface {
+    #[doc = "Get the given options."]
+    #[doc = ""]
+    #[doc = "Each element of the passed options array MUST have type, subject, and"]
+    #[doc = "key set.  All other fields (size, type, value) MUST be initialised to"]
+    #[doc = "zero, and are set to the option value if such an option is found."]
+    #[doc = ""]
+    #[doc = "This function is in the \"instantiation\" LV2 threading class, so no other"]
+    #[doc = "instance functions may be called concurrently."]
+    #[doc = ""]
+    #[doc = "@return Bitwise OR of LV2_Options_Status values."]
+    pub get: ::std::option::Option<
+        unsafe extern "C" fn(instance: LV2_Handle, options: *mut LV2_Options_Option) -> u32,
+    >,
+    #[doc = "Set the given options."]
+    #[doc = ""]
+    #[doc = "This function is in the \"instantiation\" LV2 threading class, so no other"]
+    #[doc = "instance functions may be called concurrently."]
+    #[doc = ""]
+    #[doc = "@return Bitwise OR of LV2_Options_Status values."]
+    pub set: ::std::option::Option<
+        unsafe extern "C" fn(instance: LV2_Handle, options: *const LV2_Options_Option) -> u32,
+    >,
+}
+#[doc = "< Completed successfully."]
+pub const LV2_Resize_Port_Status_LV2_RESIZE_PORT_SUCCESS: LV2_Resize_Port_Status = 0;
+#[doc = "< Unknown error."]
+pub const LV2_Resize_Port_Status_LV2_RESIZE_PORT_ERR_UNKNOWN: LV2_Resize_Port_Status = 1;
+#[doc = "< Insufficient space."]
+pub const LV2_Resize_Port_Status_LV2_RESIZE_PORT_ERR_NO_SPACE: LV2_Resize_Port_Status = 2;
+#[doc = " A status code for state functions."]
+pub type LV2_Resize_Port_Status = u32;
+#[doc = " Opaque data for resize method."]
+pub type LV2_Resize_Port_Feature_Data = *mut ::std::os::raw::c_void;
+#[doc = " Host feature to allow plugins to resize their port buffers."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Resize_Port_Resize {
+    #[doc = " Opaque data for resize method."]
+    pub data: LV2_Resize_Port_Feature_Data,
+    #[doc = "Resize a port buffer to at least `size` bytes."]
+    #[doc = ""]
+    #[doc = "This function MAY return an error, in which case the port buffer was not"]
+    #[doc = "resized and the port is still connected to the same location.  Plugins"]
+    #[doc = "MUST gracefully handle this situation."]
+    #[doc = ""]
+    #[doc = "This function is in the audio threading class."]
+    #[doc = ""]
+    #[doc = "The host MUST preserve the contents of the port buffer when resizing."]
+    #[doc = ""]
+    #[doc = "Plugins MAY resize a port many times in a single run callback.  Hosts"]
+    #[doc = "SHOULD make this as inexpensive as possible."]
+    pub resize: ::std::option::Option<
+        unsafe extern "C" fn(
+            data: LV2_Resize_Port_Feature_Data,
+            index: u32,
+            size: usize,
+        ) -> LV2_Resize_Port_Status,
+    >,
+}
+pub type LV2_State_Handle = *mut ::std::os::raw::c_void;
+pub type LV2_State_Free_Path_Handle = *mut ::std::os::raw::c_void;
+pub type LV2_State_Map_Path_Handle = *mut ::std::os::raw::c_void;
+pub type LV2_State_Make_Path_Handle = *mut ::std::os::raw::c_void;
+impl LV2_State_Flags {
+    #[doc = "Plain Old Data."]
+    #[doc = ""]
+    #[doc = "Values with this flag contain no pointers or references to other areas"]
+    #[doc = "of memory.  It is safe to copy POD values with a simple memcpy and store"]
+    #[doc = "them for the duration of the process.  A POD value is not necessarily"]
+    #[doc = "safe to trasmit between processes or machines (for example, filenames"]
+    #[doc = "are POD), see LV2_STATE_IS_PORTABLE for details."]
+    #[doc = ""]
+    #[doc = "Implementations MUST NOT attempt to copy or serialise a non-POD value if"]
+    #[doc = "they do not understand its type (and thus know how to correctly do so)."]
+    pub const LV2_STATE_IS_POD: LV2_State_Flags = LV2_State_Flags(1);
+}
+impl LV2_State_Flags {
+    #[doc = "Portable (architecture independent) data."]
+    #[doc = ""]
+    #[doc = "Values with this flag are in a format that is usable on any"]
+    #[doc = "architecture.  A portable value saved on one machine can be restored on"]
+    #[doc = "another machine regardless of architecture.  The format of portable"]
+    #[doc = "values MUST NOT depend on architecture-specific properties like"]
+    #[doc = "endianness or alignment.  Portable values MUST NOT contain filenames."]
+    pub const LV2_STATE_IS_PORTABLE: LV2_State_Flags = LV2_State_Flags(2);
+}
+impl LV2_State_Flags {
+    #[doc = "Native data."]
+    #[doc = ""]
+    #[doc = "This flag is used by the host to indicate that the saved data is only"]
+    #[doc = "going to be used locally in the currently running process (for things"]
+    #[doc = "like instance duplication or snapshots), so the plugin should use the"]
+    #[doc = "most efficient representation possible and not worry about serialisation"]
+    #[doc = "and portability."]
+    pub const LV2_STATE_IS_NATIVE: LV2_State_Flags = LV2_State_Flags(4);
+}
+impl ::std::ops::BitOr<LV2_State_Flags> for LV2_State_Flags {
+    type Output = Self;
+    #[inline]
+    fn bitor(self, other: Self) -> Self {
+        LV2_State_Flags(self.0 | other.0)
+    }
+}
+impl ::std::ops::BitOrAssign for LV2_State_Flags {
+    #[inline]
+    fn bitor_assign(&mut self, rhs: LV2_State_Flags) {
+        self.0 |= rhs.0;
+    }
+}
+impl ::std::ops::BitAnd<LV2_State_Flags> for LV2_State_Flags {
+    type Output = Self;
+    #[inline]
+    fn bitand(self, other: Self) -> Self {
+        LV2_State_Flags(self.0 & other.0)
+    }
+}
+impl ::std::ops::BitAndAssign for LV2_State_Flags {
+    #[inline]
+    fn bitand_assign(&mut self, rhs: LV2_State_Flags) {
+        self.0 &= rhs.0;
+    }
+}
+#[repr(transparent)]
+#[doc = "Flags describing value characteristics."]
+#[doc = ""]
+#[doc = "These flags are used along with the value's type URI to determine how to"]
+#[doc = "(de-)serialise the value data, or whether it is even possible to do so."]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct LV2_State_Flags(pub u32);
+#[doc = "< Completed successfully."]
+pub const LV2_State_Status_LV2_STATE_SUCCESS: LV2_State_Status = 0;
+#[doc = "< Unknown error."]
+pub const LV2_State_Status_LV2_STATE_ERR_UNKNOWN: LV2_State_Status = 1;
+#[doc = "< Failed due to unsupported type."]
+pub const LV2_State_Status_LV2_STATE_ERR_BAD_TYPE: LV2_State_Status = 2;
+#[doc = "< Failed due to unsupported flags."]
+pub const LV2_State_Status_LV2_STATE_ERR_BAD_FLAGS: LV2_State_Status = 3;
+#[doc = "< Failed due to missing features."]
+pub const LV2_State_Status_LV2_STATE_ERR_NO_FEATURE: LV2_State_Status = 4;
+#[doc = "< Failed due to missing property."]
+pub const LV2_State_Status_LV2_STATE_ERR_NO_PROPERTY: LV2_State_Status = 5;
+#[doc = "< Failed due to insufficient space."]
+pub const LV2_State_Status_LV2_STATE_ERR_NO_SPACE: LV2_State_Status = 6;
+#[doc = " A status code for state functions."]
+pub type LV2_State_Status = u32;
+#[doc = "A host-provided function to store a property."]
+#[doc = "@param handle Must be the handle passed to LV2_State_Interface.save()."]
+#[doc = "@param key The key to store `value` under (URID)."]
+#[doc = "@param value Pointer to the value to be stored."]
+#[doc = "@param size The size of `value` in bytes."]
+#[doc = "@param type The type of `value` (URID)."]
+#[doc = "@param flags LV2_State_Flags for `value`."]
+#[doc = "@return 0 on success, otherwise a non-zero error code."]
+#[doc = ""]
+#[doc = "The host passes a callback of this type to LV2_State_Interface.save(). This"]
+#[doc = "callback is called repeatedly by the plugin to store all the properties that"]
+#[doc = "describe its current state."]
+#[doc = ""]
+#[doc = "DO NOT INVENT NONSENSE URI SCHEMES FOR THE KEY.  Best is to use keys from"]
+#[doc = "existing vocabularies.  If nothing appropriate is available, use http URIs"]
+#[doc = "that point to somewhere you can host documents so documentation can be made"]
+#[doc = "resolvable (typically a child of the plugin or project URI).  If this is not"]
+#[doc = "possible, invent a URN scheme, e.g. urn:myproj:whatever.  The plugin MUST"]
+#[doc = "NOT pass an invalid URI key."]
+#[doc = ""]
+#[doc = "The host MAY fail to store a property for whatever reason, but SHOULD"]
+#[doc = "store any property that is LV2_STATE_IS_POD and LV2_STATE_IS_PORTABLE."]
+#[doc = "Implementations SHOULD use the types from the LV2 Atom extension"]
+#[doc = "(http://lv2plug.in/ns/ext/atom) wherever possible.  The plugin SHOULD"]
+#[doc = "attempt to fall-back and avoid the error if possible."]
+#[doc = ""]
+#[doc = "Note that `size` MUST be > 0, and `value` MUST point to a valid region of"]
+#[doc = "memory `size` bytes long (this is required to make restore unambiguous)."]
+#[doc = ""]
+#[doc = "The plugin MUST NOT attempt to use this function outside of the"]
+#[doc = "LV2_State_Interface.restore() context."]
+pub type LV2_State_Store_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_State_Handle,
+        key: u32,
+        value: *const ::std::os::raw::c_void,
+        size: usize,
+        type_: u32,
+        flags: u32,
+    ) -> LV2_State_Status,
+>;
+#[doc = "A host-provided function to retrieve a property."]
+#[doc = "@param handle Must be the handle passed to LV2_State_Interface.restore()."]
+#[doc = "@param key The key of the property to retrieve (URID)."]
+#[doc = "@param size (Output) If non-NULL, set to the size of the restored value."]
+#[doc = "@param type (Output) If non-NULL, set to the type of the restored value."]
+#[doc = "@param flags (Output) If non-NULL, set to the flags for the restored value."]
+#[doc = "@return A pointer to the restored value (object), or NULL if no value"]
+#[doc = "has been stored under `key`."]
+#[doc = ""]
+#[doc = "A callback of this type is passed by the host to"]
+#[doc = "LV2_State_Interface.restore().  This callback is called repeatedly by the"]
+#[doc = "plugin to retrieve any properties it requires to restore its state."]
+#[doc = ""]
+#[doc = "The returned value MUST remain valid until LV2_State_Interface.restore()"]
+#[doc = "returns.  The plugin MUST NOT attempt to use this function, or any value"]
+#[doc = "returned from it, outside of the LV2_State_Interface.restore() context."]
+pub type LV2_State_Retrieve_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_State_Handle,
+        key: u32,
+        size: *mut usize,
+        type_: *mut u32,
+        flags: *mut u32,
+    ) -> *const ::std::os::raw::c_void,
+>;
+#[doc = "LV2 Plugin State Interface."]
+#[doc = ""]
+#[doc = "When the plugin's extension_data is called with argument"]
+#[doc = "LV2_STATE__interface, the plugin MUST return an LV2_State_Interface"]
+#[doc = "structure, which remains valid for the lifetime of the plugin."]
+#[doc = ""]
+#[doc = "The host can use the contained function pointers to save and restore the"]
+#[doc = "state of a plugin instance at any time, provided the threading restrictions"]
+#[doc = "of the functions are met."]
+#[doc = ""]
+#[doc = "Stored data is only guaranteed to be compatible between instances of plugins"]
+#[doc = "with the same URI (i.e. if a change to a plugin would cause a fatal error"]
+#[doc = "when restoring state saved by a previous version of that plugin, the plugin"]
+#[doc = "URI MUST change just as it must when ports change incompatibly).  Plugin"]
+#[doc = "authors should consider this possibility, and always store sensible data"]
+#[doc = "with meaningful types to avoid such problems in the future."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_State_Interface {
+    #[doc = "Save plugin state using a host-provided `store` callback."]
+    #[doc = ""]
+    #[doc = "@param instance The instance handle of the plugin."]
+    #[doc = "@param store The host-provided store callback."]
+    #[doc = "@param handle An opaque pointer to host data which MUST be passed as the"]
+    #[doc = "handle parameter to `store` if it is called."]
+    #[doc = "@param flags Flags describing desired properties of this save.  These"]
+    #[doc = "flags may be used to determine the most appropriate values to store."]
+    #[doc = "@param features Extensible parameter for passing any additional"]
+    #[doc = "features to be used for this save."]
+    #[doc = ""]
+    #[doc = "The plugin is expected to store everything necessary to completely"]
+    #[doc = "restore its state later.  Plugins SHOULD store simple POD data whenever"]
+    #[doc = "possible, and consider the possibility of state being restored much"]
+    #[doc = "later on a different machine."]
+    #[doc = ""]
+    #[doc = "The `handle` pointer and `store` function MUST NOT be used"]
+    #[doc = "beyond the scope of save()."]
+    #[doc = ""]
+    #[doc = "This function has its own special threading class: it may not be called"]
+    #[doc = "concurrently with any \"Instantiation\" function, but it may be called"]
+    #[doc = "concurrently with functions in any other class, unless the definition of"]
+    #[doc = "that class prohibits it (for example, it may not be called concurrently"]
+    #[doc = "with a \"Discovery\" function, but it may be called concurrently with an"]
+    #[doc = "\"Audio\" function.  The plugin is responsible for any locking or"]
+    #[doc = "lock-free techniques necessary to make this possible."]
+    #[doc = ""]
+    #[doc = "Note that in the simple case where state is only modified by restore(),"]
+    #[doc = "there are no synchronization issues since save() is never called"]
+    #[doc = "concurrently with restore() (though run() may read it during a save)."]
+    #[doc = ""]
+    #[doc = "Plugins that dynamically modify state while running, however, must take"]
+    #[doc = "care to do so in such a way that a concurrent call to save() will save a"]
+    #[doc = "consistent representation of plugin state for a single instant in time."]
+    pub save: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            store: LV2_State_Store_Function,
+            handle: LV2_State_Handle,
+            flags: u32,
+            features: *const *const LV2_Feature,
+        ) -> LV2_State_Status,
+    >,
+    #[doc = "Restore plugin state using a host-provided `retrieve` callback."]
+    #[doc = ""]
+    #[doc = "@param instance The instance handle of the plugin."]
+    #[doc = "@param retrieve The host-provided retrieve callback."]
+    #[doc = "@param handle An opaque pointer to host data which MUST be passed as the"]
+    #[doc = "handle parameter to `retrieve` if it is called."]
+    #[doc = "@param flags Currently unused."]
+    #[doc = "@param features Extensible parameter for passing any additional"]
+    #[doc = "features to be used for this restore."]
+    #[doc = ""]
+    #[doc = "The plugin MAY assume a restored value was set by a previous call to"]
+    #[doc = "LV2_State_Interface.save() by a plugin with the same URI."]
+    #[doc = ""]
+    #[doc = "The plugin MUST gracefully fall back to a default value when a value can"]
+    #[doc = "not be retrieved.  This allows the host to reset the plugin state with"]
+    #[doc = "an empty map."]
+    #[doc = ""]
+    #[doc = "The `handle` pointer and `store` function MUST NOT be used"]
+    #[doc = "beyond the scope of restore()."]
+    #[doc = ""]
+    #[doc = "This function is in the \"Instantiation\" threading class as defined by"]
+    #[doc = "LV2. This means it MUST NOT be called concurrently with any other"]
+    #[doc = "function on the same plugin instance."]
+    pub restore: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            retrieve: LV2_State_Retrieve_Function,
+            handle: LV2_State_Handle,
+            flags: u32,
+            features: *const *const LV2_Feature,
+        ) -> LV2_State_Status,
+    >,
+}
+#[doc = "Feature data for state:mapPath (@ref LV2_STATE__mapPath)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_State_Map_Path {
+    #[doc = "Opaque host data."]
+    pub handle: LV2_State_Map_Path_Handle,
+    #[doc = "Map an absolute path to an abstract path for use in plugin state."]
+    #[doc = "@param handle MUST be the `handle` member of this struct."]
+    #[doc = "@param absolute_path The absolute path of a file."]
+    #[doc = "@return An abstract path suitable for use in plugin state."]
+    #[doc = ""]
+    #[doc = "The plugin MUST use this function to map any paths that will be stored"]
+    #[doc = "in plugin state.  The returned value is an abstract path which MAY not"]
+    #[doc = "be an actual file system path; absolute_path() MUST be used to map"]
+    #[doc = "it to an actual path in order to use the file."]
+    #[doc = ""]
+    #[doc = "Plugins MUST NOT make any assumptions about abstract paths except that"]
+    #[doc = "they can be mapped back to the absolute path of the \"same\" file (though"]
+    #[doc = "not necessarily the same original path) using absolute_path()."]
+    #[doc = ""]
+    #[doc = "This function may only be called within the context of"]
+    #[doc = "LV2_State_Interface methods.  The caller must free the returned value"]
+    #[doc = "with LV2_State_Free_Path.free_path()."]
+    pub abstract_path: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_State_Map_Path_Handle,
+            absolute_path: *const ::std::os::raw::c_char,
+        ) -> *mut ::std::os::raw::c_char,
+    >,
+    #[doc = "Map an abstract path from plugin state to an absolute path."]
+    #[doc = "@param handle MUST be the `handle` member of this struct."]
+    #[doc = "@param abstract_path An abstract path (typically from plugin state)."]
+    #[doc = "@return An absolute file system path."]
+    #[doc = ""]
+    #[doc = "The plugin MUST use this function in order to actually open or otherwise"]
+    #[doc = "use any paths loaded from plugin state."]
+    #[doc = ""]
+    #[doc = "This function may only be called within the context of"]
+    #[doc = "LV2_State_Interface methods.  The caller must free the returned value"]
+    #[doc = "with LV2_State_Free_Path.free_path()."]
+    pub absolute_path: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_State_Map_Path_Handle,
+            abstract_path: *const ::std::os::raw::c_char,
+        ) -> *mut ::std::os::raw::c_char,
+    >,
+}
+#[doc = "Feature data for state:makePath (@ref LV2_STATE__makePath)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_State_Make_Path {
+    #[doc = "Opaque host data."]
+    pub handle: LV2_State_Make_Path_Handle,
+    #[doc = "Return a path the plugin may use to create a new file."]
+    #[doc = "@param handle MUST be the `handle` member of this struct."]
+    #[doc = "@param path The path of the new file within a namespace unique to this"]
+    #[doc = "plugin instance."]
+    #[doc = "@return The absolute path to use for the new file."]
+    #[doc = ""]
+    #[doc = "This function can be used by plugins to create files and directories,"]
+    #[doc = "either at state saving time (if this feature is passed to"]
+    #[doc = "LV2_State_Interface.save()) or any time (if this feature is passed to"]
+    #[doc = "LV2_Descriptor.instantiate())."]
+    #[doc = ""]
+    #[doc = "The host MUST do whatever is necessary for the plugin to be able to"]
+    #[doc = "create a file at the returned path (for example, using fopen()),"]
+    #[doc = "including creating any leading directories."]
+    #[doc = ""]
+    #[doc = "If this function is passed to LV2_Descriptor.instantiate(), it may be"]
+    #[doc = "called from any non-realtime context.  If it is passed to"]
+    #[doc = "LV2_State_Interface.save(), it may only be called within the dynamic"]
+    #[doc = "scope of that function call."]
+    #[doc = ""]
+    #[doc = "The caller must free the returned value with"]
+    #[doc = "LV2_State_Free_Path.free_path()."]
+    pub path: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_State_Make_Path_Handle,
+            path: *const ::std::os::raw::c_char,
+        ) -> *mut ::std::os::raw::c_char,
+    >,
+}
+#[doc = "Feature data for state:freePath (@ref LV2_STATE__freePath)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_State_Free_Path {
+    #[doc = "Opaque host data."]
+    pub handle: LV2_State_Free_Path_Handle,
+    #[doc = "Free a path returned by a state feature."]
+    #[doc = ""]
+    #[doc = "@param handle MUST be the `handle` member of this struct."]
+    #[doc = "@param path The path previously returned by a state feature."]
+    #[doc = ""]
+    #[doc = "This function can be used by plugins to free paths allocated by the host"]
+    #[doc = "and returned by state features (LV2_State_Map_Path.abstract_path(),"]
+    #[doc = "LV2_State_Map_Path.absolute_path(), and LV2_State_Make_Path.path())."]
+    pub free_path: ::std::option::Option<
+        unsafe extern "C" fn(handle: LV2_State_Free_Path_Handle, path: *mut ::std::os::raw::c_char),
+    >,
+}
+#[doc = "A pointer to some widget or other type of UI handle."]
+#[doc = ""]
+#[doc = "The actual type is defined by the type of the UI."]
+pub type LV2UI_Widget = *mut ::std::os::raw::c_void;
+#[doc = "A pointer to UI instance internals."]
+#[doc = ""]
+#[doc = "The host may compare this to NULL, but otherwise MUST NOT interpret it."]
+pub type LV2UI_Handle = *mut ::std::os::raw::c_void;
+#[doc = "A pointer to a controller provided by the host."]
+#[doc = ""]
+#[doc = "The UI may compare this to NULL, but otherwise MUST NOT interpret it."]
+pub type LV2UI_Controller = *mut ::std::os::raw::c_void;
+#[doc = "A pointer to opaque data for a feature."]
+pub type LV2UI_Feature_Handle = *mut ::std::os::raw::c_void;
+#[doc = "A host-provided function that sends data to a plugin's input ports."]
+#[doc = ""]
+#[doc = "@param controller The opaque controller pointer passed to"]
+#[doc = "LV2UI_Descriptor::instantiate()."]
+#[doc = ""]
+#[doc = "@param port_index Index of the port to update."]
+#[doc = ""]
+#[doc = "@param buffer Buffer containing `buffer_size` bytes of data."]
+#[doc = ""]
+#[doc = "@param buffer_size Size of `buffer` in bytes."]
+#[doc = ""]
+#[doc = "@param port_protocol Either 0 or the URID for a ui:PortProtocol.  If 0, the"]
+#[doc = "protocol is implicitly ui:floatProtocol, the port MUST be an lv2:ControlPort"]
+#[doc = "input, `buffer` MUST point to a single float value, and `buffer_size` MUST"]
+#[doc = "be sizeof(float).  The UI SHOULD NOT use a protocol not supported by the"]
+#[doc = "host, but the host MUST gracefully ignore any protocol it does not"]
+#[doc = "understand."]
+pub type LV2UI_Write_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        controller: LV2UI_Controller,
+        port_index: u32,
+        buffer_size: u32,
+        port_protocol: u32,
+        buffer: *const ::std::os::raw::c_void,
+    ),
+>;
+#[doc = "A plugin UI."]
+#[doc = ""]
+#[doc = "A pointer to an object of this type is returned by the lv2ui_descriptor()"]
+#[doc = "function."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Descriptor {
+    #[doc = "The URI for this UI (not for the plugin it controls)."]
+    pub URI: *const ::std::os::raw::c_char,
+    #[doc = "Create a new UI and return a handle to it.  This function works"]
+    #[doc = "similarly to LV2_Descriptor::instantiate()."]
+    #[doc = ""]
+    #[doc = "@param descriptor The descriptor for the UI to instantiate."]
+    #[doc = ""]
+    #[doc = "@param plugin_uri The URI of the plugin that this UI will control."]
+    #[doc = ""]
+    #[doc = "@param bundle_path The path to the bundle containing this UI, including"]
+    #[doc = "the trailing directory separator."]
+    #[doc = ""]
+    #[doc = "@param write_function A function that the UI can use to send data to the"]
+    #[doc = "plugin's input ports."]
+    #[doc = ""]
+    #[doc = "@param controller A handle for the UI instance to be passed as the"]
+    #[doc = "first parameter of UI methods."]
+    #[doc = ""]
+    #[doc = "@param widget (output) widget pointer.  The UI points this at its main"]
+    #[doc = "widget, which has the type defined by the UI type in the data file."]
+    #[doc = ""]
+    #[doc = "@param features An array of LV2_Feature pointers.  The host must pass"]
+    #[doc = "all feature URIs that it and the UI supports and any additional data, as"]
+    #[doc = "in LV2_Descriptor::instantiate().  Note that UI features and plugin"]
+    #[doc = "features are not necessarily the same."]
+    #[doc = ""]
+    pub instantiate: ::std::option::Option<
+        unsafe extern "C" fn(
+            descriptor: *const LV2UI_Descriptor,
+            plugin_uri: *const ::std::os::raw::c_char,
+            bundle_path: *const ::std::os::raw::c_char,
+            write_function: LV2UI_Write_Function,
+            controller: LV2UI_Controller,
+            widget: *mut LV2UI_Widget,
+            features: *const *const LV2_Feature,
+        ) -> LV2UI_Handle,
+    >,
+    #[doc = "Destroy the UI.  The host must not try to access the widget after"]
+    #[doc = "calling this function."]
+    pub cleanup: ::std::option::Option<unsafe extern "C" fn(ui: LV2UI_Handle)>,
+    #[doc = "Tell the UI that something interesting has happened at a plugin port."]
+    #[doc = ""]
+    #[doc = "What is \"interesting\" and how it is written to `buffer` is defined by"]
+    #[doc = "`format`, which has the same meaning as in LV2UI_Write_Function()."]
+    #[doc = "Format 0 is a special case for lv2:ControlPort, where this function"]
+    #[doc = "should be called when the port value changes (but not necessarily for"]
+    #[doc = "every change), `buffer_size` must be sizeof(float), and `buffer`"]
+    #[doc = "points to a single IEEE-754 float."]
+    #[doc = ""]
+    #[doc = "By default, the host should only call this function for lv2:ControlPort"]
+    #[doc = "inputs.  However, the UI can request updates for other ports statically"]
+    #[doc = "with ui:portNotification or dynamicaly with ui:portSubscribe."]
+    #[doc = ""]
+    #[doc = "The UI MUST NOT retain any reference to `buffer` after this function"]
+    #[doc = "returns, it is only valid for the duration of the call."]
+    #[doc = ""]
+    #[doc = "This member may be NULL if the UI is not interested in any port events."]
+    pub port_event: ::std::option::Option<
+        unsafe extern "C" fn(
+            ui: LV2UI_Handle,
+            port_index: u32,
+            buffer_size: u32,
+            format: u32,
+            buffer: *const ::std::os::raw::c_void,
+        ),
+    >,
+    #[doc = "Return a data structure associated with an extension URI, typically an"]
+    #[doc = "interface struct with additional function pointers"]
+    #[doc = ""]
+    #[doc = "This member may be set to NULL if the UI is not interested in supporting"]
+    #[doc = "any extensions. This is similar to LV2_Descriptor::extension_data()."]
+    #[doc = ""]
+    pub extension_data: ::std::option::Option<
+        unsafe extern "C" fn(uri: *const ::std::os::raw::c_char) -> *const ::std::os::raw::c_void,
+    >,
+}
+#[doc = "Feature/interface for resizable UIs (LV2_UI__resize)."]
+#[doc = ""]
+#[doc = "This structure is used in two ways: as a feature passed by the host via"]
+#[doc = "LV2UI_Descriptor::instantiate(), or as an interface provided by a UI via"]
+#[doc = "LV2UI_Descriptor::extension_data())."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Resize {
+    #[doc = "Pointer to opaque data which must be passed to ui_resize()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Request/advertise a size change."]
+    #[doc = ""]
+    #[doc = "When provided by the host, the UI may call this function to inform the"]
+    #[doc = "host about the size of the UI."]
+    #[doc = ""]
+    #[doc = "When provided by the UI, the host may call this function to notify the"]
+    #[doc = "UI that it should change its size accordingly.  In this case, the host"]
+    #[doc = "must pass the LV2UI_Handle to provide access to the UI instance."]
+    #[doc = ""]
+    #[doc = "@return 0 on success."]
+    pub ui_resize: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            width: ::std::os::raw::c_int,
+            height: ::std::os::raw::c_int,
+        ) -> ::std::os::raw::c_int,
+    >,
+}
+#[doc = "Feature to map port symbols to UIs."]
+#[doc = ""]
+#[doc = "This can be used by the UI to get the index for a port with the given"]
+#[doc = "symbol.  This makes it possible to implement and distribute a UI separately"]
+#[doc = "from the plugin (since symbol, unlike index, is a stable port identifier)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Port_Map {
+    #[doc = "Pointer to opaque data which must be passed to port_index()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Get the index for the port with the given `symbol`."]
+    #[doc = ""]
+    #[doc = "@return The index of the port, or LV2UI_INVALID_PORT_INDEX if no such"]
+    #[doc = "port is found."]
+    pub port_index: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            symbol: *const ::std::os::raw::c_char,
+        ) -> u32,
+    >,
+}
+#[doc = "Feature to subscribe to port updates (LV2_UI__portSubscribe)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Port_Subscribe {
+    #[doc = "Pointer to opaque data which must be passed to subscribe() and"]
+    #[doc = "unsubscribe()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Subscribe to updates for a port."]
+    #[doc = ""]
+    #[doc = "This means that the host will call the UI's port_event() function when"]
+    #[doc = "the port value changes (as defined by protocol)."]
+    #[doc = ""]
+    #[doc = "Calling this function with the same `port_index` and `port_protocol`"]
+    #[doc = "as an already active subscription has no effect."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = "@param port_index The index of the port."]
+    #[doc = "@param port_protocol The URID of the ui:PortProtocol."]
+    #[doc = "@param features Features for this subscription."]
+    #[doc = "@return 0 on success."]
+    pub subscribe: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            port_index: u32,
+            port_protocol: u32,
+            features: *const *const LV2_Feature,
+        ) -> u32,
+    >,
+    #[doc = "Unsubscribe from updates for a port."]
+    #[doc = ""]
+    #[doc = "This means that the host will cease calling calling port_event() when"]
+    #[doc = "the port value changes."]
+    #[doc = ""]
+    #[doc = "Calling this function with a `port_index` and `port_protocol` that"]
+    #[doc = "does not refer to an active port subscription has no effect."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = "@param port_index The index of the port."]
+    #[doc = "@param port_protocol The URID of the ui:PortProtocol."]
+    #[doc = "@param features Features for this subscription."]
+    #[doc = "@return 0 on success."]
+    pub unsubscribe: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            port_index: u32,
+            port_protocol: u32,
+            features: *const *const LV2_Feature,
+        ) -> u32,
+    >,
+}
+#[doc = "A feature to notify the host that the user has grabbed a UI control."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Touch {
+    #[doc = "Pointer to opaque data which must be passed to ui_resize()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Notify the host that a control has been grabbed or released."]
+    #[doc = ""]
+    #[doc = "The host should cease automating the port or otherwise manipulating the"]
+    #[doc = "port value until the control has been ungrabbed."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = "@param port_index The index of the port associated with the control."]
+    #[doc = "@param grabbed If true, the control has been grabbed, otherwise the"]
+    #[doc = "control has been released."]
+    pub touch: ::std::option::Option<
+        unsafe extern "C" fn(handle: LV2UI_Feature_Handle, port_index: u32, grabbed: bool),
+    >,
+}
+#[doc = "Completed successfully."]
+#[doc = ""]
+#[doc = "The host will set the parameter later if the user choses a new value."]
+pub const LV2UI_Request_Value_Status_LV2UI_REQUEST_VALUE_SUCCESS: LV2UI_Request_Value_Status = 0;
+#[doc = "Parameter already being requested."]
+#[doc = ""]
+#[doc = "The host is already requesting a parameter from the user (for example, a"]
+#[doc = "dialog is visible), or the UI is otherwise busy and can not make this"]
+#[doc = "request."]
+pub const LV2UI_Request_Value_Status_LV2UI_REQUEST_VALUE_BUSY: LV2UI_Request_Value_Status = 1;
+#[doc = "Unknown parameter."]
+#[doc = ""]
+#[doc = "The host is not aware of this parameter, and is not able to set a new"]
+#[doc = "value for it."]
+pub const LV2UI_Request_Value_Status_LV2UI_REQUEST_VALUE_ERR_UNKNOWN: LV2UI_Request_Value_Status =
+    2;
+#[doc = "Unsupported parameter."]
+#[doc = ""]
+#[doc = "The host knows about this parameter, but does not support requesting a"]
+#[doc = "new value for it from the user.  This is likely because the host does"]
+#[doc = "not have UI support for choosing a value with the appropriate type."]
+pub const LV2UI_Request_Value_Status_LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED:
+    LV2UI_Request_Value_Status = 3;
+#[doc = "A status code for LV2UI_Request_Value::request()."]
+pub type LV2UI_Request_Value_Status = u32;
+#[doc = "A feature to request a new parameter value from the host."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Request_Value {
+    #[doc = "Pointer to opaque data which must be passed to request()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Request a value for a parameter from the host."]
+    #[doc = ""]
+    #[doc = "This is mainly used by UIs to request values for complex parameters that"]
+    #[doc = "don't change often, such as file paths, but it may be used to request"]
+    #[doc = "any parameter value."]
+    #[doc = ""]
+    #[doc = "This function returns immediately, and the return value indicates"]
+    #[doc = "whether the host can fulfill the request.  The host may notify the"]
+    #[doc = "plugin about the new parameter value, for example when a file is"]
+    #[doc = "selected by the user, via the usual mechanism.  Typically, the host will"]
+    #[doc = "send a message to the plugin that sets the new parameter value, and the"]
+    #[doc = "plugin will notify the UI via a message as usual for any other parameter"]
+    #[doc = "change."]
+    #[doc = ""]
+    #[doc = "To provide an appropriate UI, the host can determine details about the"]
+    #[doc = "parameter from the plugin data as usual.  The additional parameters of"]
+    #[doc = "this function provide support for more advanced use cases, but in the"]
+    #[doc = "simple common case, the plugin will simply pass the key of the desired"]
+    #[doc = "parameter and zero for everything else."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = ""]
+    #[doc = "@param key The URID of the parameter."]
+    #[doc = ""]
+    #[doc = "@param type The optional type of the value to request.  This can be used"]
+    #[doc = "to request a specific value type for parameters that support several."]
+    #[doc = "If non-zero, it must be the URID of an instance of rdfs:Class or"]
+    #[doc = "rdfs:Datatype."]
+    #[doc = ""]
+    #[doc = "@param features Additional features for this request, or NULL."]
+    #[doc = ""]
+    #[doc = "@return A status code which is 0 on success."]
+    pub request: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            key: LV2_URID,
+            type_: LV2_URID,
+            features: *const *const LV2_Feature,
+        ) -> LV2UI_Request_Value_Status,
+    >,
+}
+#[doc = "UI Idle Interface (LV2_UI__idleInterface)"]
+#[doc = ""]
+#[doc = "UIs can provide this interface to have an idle() callback called by the host"]
+#[doc = "rapidly to update the UI."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Idle_Interface {
+    #[doc = "Run a single iteration of the UI's idle loop."]
+    #[doc = ""]
+    #[doc = "This will be called rapidly in the UI thread at a rate appropriate"]
+    #[doc = "for a toolkit main loop.  There are no precise timing guarantees, but"]
+    #[doc = "the host should attempt to call idle() at a high enough rate for smooth"]
+    #[doc = "animation, at least 30Hz."]
+    #[doc = ""]
+    #[doc = "@return non-zero if the UI has been closed, in which case the host"]
+    #[doc = "should stop calling idle(), and can either completely destroy the UI, or"]
+    #[doc = "re-show it and resume calling idle()."]
+    pub idle:
+        ::std::option::Option<unsafe extern "C" fn(ui: LV2UI_Handle) -> ::std::os::raw::c_int>,
+}
+#[doc = "UI Show Interface (LV2_UI__showInterface)"]
+#[doc = ""]
+#[doc = "UIs can provide this interface to show and hide a window, which allows them"]
+#[doc = "to function in hosts unable to embed their widget.  This allows any UI to"]
+#[doc = "provide a fallback for embedding that works in any host."]
+#[doc = ""]
+#[doc = "If used:"]
+#[doc = "- The host MUST use LV2UI_Idle_Interface to drive the UI."]
+#[doc = "- The UI MUST return non-zero from LV2UI_Idle_Interface::idle() when it has been closed."]
+#[doc = "- If idle() returns non-zero, the host MUST call hide() and stop calling"]
+#[doc = "idle().  It MAY later call show() then resume calling idle()."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Show_Interface {
+    #[doc = "Show a window for this UI."]
+    #[doc = ""]
+    #[doc = "The window title MAY have been passed by the host to"]
+    #[doc = "LV2UI_Descriptor::instantiate() as an LV2_Options_Option with key"]
+    #[doc = "LV2_UI__windowTitle."]
+    #[doc = ""]
+    #[doc = "@return 0 on success, or anything else to stop being called."]
+    pub show:
+        ::std::option::Option<unsafe extern "C" fn(ui: LV2UI_Handle) -> ::std::os::raw::c_int>,
+    #[doc = "Hide the window for this UI."]
+    #[doc = ""]
+    #[doc = "@return 0 on success, or anything else to stop being called."]
+    pub hide:
+        ::std::option::Option<unsafe extern "C" fn(ui: LV2UI_Handle) -> ::std::os::raw::c_int>,
+}
+#[doc = "Peak data for a slice of time, the update format for ui:peakProtocol."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Peak_Data {
+    #[doc = "The start of the measurement period.  This is just a running counter"]
+    #[doc = "that is only meaningful in comparison to previous values and must not be"]
+    #[doc = "interpreted as an absolute time."]
+    pub period_start: u32,
+    #[doc = "The size of the measurement period, in the same units as period_start."]
+    pub period_size: u32,
+    #[doc = "The peak value for the measurement period. This should be the maximal"]
+    #[doc = "value for abs(sample) over all the samples in the period."]
+    pub peak: f32,
+}
+#[doc = "The type of the lv2ui_descriptor() function."]
+pub type LV2UI_DescriptorFunction =
+    ::std::option::Option<unsafe extern "C" fn(index: u32) -> *const LV2UI_Descriptor>;
+#[doc = "Opaque pointer to host data."]
+pub type LV2_URI_Map_Callback_Data = *mut ::std::os::raw::c_void;
+#[doc = "URI Map Feature."]
+#[doc = ""]
+#[doc = "To support this feature the host must pass an LV2_Feature struct to the"]
+#[doc = "plugin's instantiate method with URI \"http://lv2plug.in/ns/ext/uri-map\""]
+#[doc = "and data pointed to an instance of this struct."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_URI_Map_Feature {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "The plugin MUST pass this to any call to functions in this struct."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub callback_data: LV2_URI_Map_Callback_Data,
+    #[doc = "Get the numeric ID of a URI from the host."]
+    #[doc = ""]
+    #[doc = "@param callback_data Must be the callback_data member of this struct."]
+    #[doc = "@param map The 'context' of this URI. Certain extensions may define a"]
+    #[doc = "URI that must be passed here with certain restrictions on the return"]
+    #[doc = "value (e.g. limited range). This value may be NULL if the plugin needs"]
+    #[doc = "an ID for a URI in general. Extensions SHOULD NOT define a context"]
+    #[doc = "unless there is a specific need to do so, e.g. to restrict the range of"]
+    #[doc = "the returned value."]
+    #[doc = "@param uri The URI to be mapped to an integer ID."]
+    #[doc = ""]
+    #[doc = "This function is referentially transparent; any number of calls with the"]
+    #[doc = "same arguments is guaranteed to return the same value over the life of a"]
+    #[doc = "plugin instance (though the same URI may return different values with a"]
+    #[doc = "different map parameter). However, this function is not necessarily very"]
+    #[doc = "fast: plugins SHOULD cache any IDs they might need in performance"]
+    #[doc = "critical situations."]
+    #[doc = ""]
+    #[doc = "The return value 0 is reserved and indicates that an ID for that URI"]
+    #[doc = "could not be created for whatever reason. Extensions MAY define more"]
+    #[doc = "precisely what this means in a certain context, but in general plugins"]
+    #[doc = "SHOULD handle this situation as gracefully as possible. However, hosts"]
+    #[doc = "SHOULD NOT return 0 from this function in non-exceptional circumstances"]
+    #[doc = "(e.g. the URI map SHOULD be dynamic). Hosts that statically support only"]
+    #[doc = "a fixed set of URIs should not expect plugins to function correctly."]
+    pub uri_to_id: ::std::option::Option<
+        unsafe extern "C" fn(
+            callback_data: LV2_URI_Map_Callback_Data,
+            map: *const ::std::os::raw::c_char,
+            uri: *const ::std::os::raw::c_char,
+        ) -> u32,
+    >,
+}
+#[doc = "< Completed successfully."]
+pub const LV2_Worker_Status_LV2_WORKER_SUCCESS: LV2_Worker_Status = 0;
+#[doc = "< Unknown error."]
+pub const LV2_Worker_Status_LV2_WORKER_ERR_UNKNOWN: LV2_Worker_Status = 1;
+#[doc = "< Failed due to lack of space."]
+pub const LV2_Worker_Status_LV2_WORKER_ERR_NO_SPACE: LV2_Worker_Status = 2;
+#[doc = "Status code for worker functions."]
+pub type LV2_Worker_Status = u32;
+#[doc = " Opaque handle for LV2_Worker_Interface::work()."]
+pub type LV2_Worker_Respond_Handle = *mut ::std::os::raw::c_void;
+#[doc = "A function to respond to run() from the worker method."]
+#[doc = ""]
+#[doc = "The `data` MUST be safe for the host to copy and later pass to"]
+#[doc = "work_response(), and the host MUST guarantee that it will be eventually"]
+#[doc = "passed to work_response() if this function returns LV2_WORKER_SUCCESS."]
+pub type LV2_Worker_Respond_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_Worker_Respond_Handle,
+        size: u32,
+        data: *const ::std::os::raw::c_void,
+    ) -> LV2_Worker_Status,
+>;
+#[doc = "Plugin Worker Interface."]
+#[doc = ""]
+#[doc = "This is the interface provided by the plugin to implement a worker method."]
+#[doc = "The plugin's extension_data() method should return an LV2_Worker_Interface"]
+#[doc = "when called with LV2_WORKER__interface as its argument."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Worker_Interface {
+    #[doc = "The worker method.  This is called by the host in a non-realtime context"]
+    #[doc = "as requested, possibly with an arbitrary message to handle."]
+    #[doc = ""]
+    #[doc = "A response can be sent to run() using `respond`.  The plugin MUST NOT"]
+    #[doc = "make any assumptions about which thread calls this method, except that"]
+    #[doc = "there are no real-time requirements and only one call may be executed at"]
+    #[doc = "a time.  That is, the host MAY call this method from any non-real-time"]
+    #[doc = "thread, but MUST NOT make concurrent calls to this method from several"]
+    #[doc = "threads."]
+    #[doc = ""]
+    #[doc = "@param instance The LV2 instance this is a method on."]
+    #[doc = "@param respond  A function for sending a response to run()."]
+    #[doc = "@param handle   Must be passed to `respond` if it is called."]
+    #[doc = "@param size     The size of `data`."]
+    #[doc = "@param data     Data from run(), or NULL."]
+    pub work: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            respond: LV2_Worker_Respond_Function,
+            handle: LV2_Worker_Respond_Handle,
+            size: u32,
+            data: *const ::std::os::raw::c_void,
+        ) -> LV2_Worker_Status,
+    >,
+    #[doc = "Handle a response from the worker.  This is called by the host in the"]
+    #[doc = "run() context when a response from the worker is ready."]
+    #[doc = ""]
+    #[doc = "@param instance The LV2 instance this is a method on."]
+    #[doc = "@param size     The size of `body`."]
+    #[doc = "@param body     Message body, or NULL."]
+    pub work_response: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            size: u32,
+            body: *const ::std::os::raw::c_void,
+        ) -> LV2_Worker_Status,
+    >,
+    #[doc = "Called when all responses for this cycle have been delivered."]
+    #[doc = ""]
+    #[doc = "Since work_response() may be called after run() finished, this provides"]
+    #[doc = "a hook for code that must run after the cycle is completed."]
+    #[doc = ""]
+    #[doc = "This field may be NULL if the plugin has no use for it.  Otherwise, the"]
+    #[doc = "host MUST call it after every run(), regardless of whether or not any"]
+    #[doc = "responses were sent that cycle."]
+    pub end_run:
+        ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle) -> LV2_Worker_Status>,
+}
+#[doc = " Opaque handle for LV2_Worker_Schedule."]
+pub type LV2_Worker_Schedule_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Schedule Worker Host Feature."]
+#[doc = ""]
+#[doc = "The host passes this feature to provide a schedule_work() function, which"]
+#[doc = "the plugin can use to schedule a worker call from run()."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Worker_Schedule {
+    #[doc = "Opaque host data."]
+    pub handle: LV2_Worker_Schedule_Handle,
+    #[doc = "Request from run() that the host call the worker."]
+    #[doc = ""]
+    #[doc = "This function is in the audio threading class.  It should be called from"]
+    #[doc = "run() to request that the host call the work() method in a non-realtime"]
+    #[doc = "context with the given arguments."]
+    #[doc = ""]
+    #[doc = "This function is always safe to call from run(), but it is not"]
+    #[doc = "guaranteed that the worker is actually called from a different thread."]
+    #[doc = "In particular, when free-wheeling (for example, during offline"]
+    #[doc = "rendering), the worker may be executed immediately.  This allows"]
+    #[doc = "single-threaded processing with sample accuracy and avoids timing"]
+    #[doc = "problems when run() is executing much faster or slower than real-time."]
+    #[doc = ""]
+    #[doc = "Plugins SHOULD be written in such a way that if the worker runs"]
+    #[doc = "immediately, and responses from the worker are delivered immediately,"]
+    #[doc = "the effect of the work takes place immediately with sample accuracy."]
+    #[doc = ""]
+    #[doc = "The `data` MUST be safe for the host to copy and later pass to work(),"]
+    #[doc = "and the host MUST guarantee that it will be eventually passed to work()"]
+    #[doc = "if this function returns LV2_WORKER_SUCCESS."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = "@param size   The size of `data`."]
+    #[doc = "@param data   Message to pass to work(), or NULL."]
+    pub schedule_work: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_Worker_Schedule_Handle,
+            size: u32,
+            data: *const ::std::os::raw::c_void,
+        ) -> LV2_Worker_Status,
+    >,
+}
+pub type __builtin_va_list = __va_list;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct __va_list {
+    pub __stack: *mut ::std::os::raw::c_void,
+    pub __gr_top: *mut ::std::os::raw::c_void,
+    pub __vr_top: *mut ::std::os::raw::c_void,
+    pub __gr_offs: ::std::os::raw::c_int,
+    pub __vr_offs: ::std::os::raw::c_int,
+}
diff --git a/sys/src/linux/arm.rs b/sys/src/linux/arm.rs
new file mode 100644
index 00000000..8d6d0966
--- /dev/null
+++ b/sys/src/linux/arm.rs
@@ -0,0 +1,2727 @@
+/* automatically generated by rust-bindgen */
+
+pub const LV2_ATOM_URI: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/atom\0";
+pub const LV2_ATOM_PREFIX: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/atom#\0";
+pub const LV2_ATOM__Atom: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#Atom\0";
+pub const LV2_ATOM__AtomPort: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#AtomPort\0";
+pub const LV2_ATOM__Blank: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Blank\0";
+pub const LV2_ATOM__Bool: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#Bool\0";
+pub const LV2_ATOM__Chunk: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Chunk\0";
+pub const LV2_ATOM__Double: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#Double\0";
+pub const LV2_ATOM__Event: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Event\0";
+pub const LV2_ATOM__Float: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Float\0";
+pub const LV2_ATOM__Int: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/atom#Int\0";
+pub const LV2_ATOM__Literal: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/atom#Literal\0";
+pub const LV2_ATOM__Long: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#Long\0";
+pub const LV2_ATOM__Number: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#Number\0";
+pub const LV2_ATOM__Object: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#Object\0";
+pub const LV2_ATOM__Path: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#Path\0";
+pub const LV2_ATOM__Property: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#Property\0";
+pub const LV2_ATOM__Resource: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#Resource\0";
+pub const LV2_ATOM__Sequence: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#Sequence\0";
+pub const LV2_ATOM__Sound: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Sound\0";
+pub const LV2_ATOM__String: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#String\0";
+pub const LV2_ATOM__Tuple: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Tuple\0";
+pub const LV2_ATOM__URI: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/atom#URI\0";
+pub const LV2_ATOM__URID: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#URID\0";
+pub const LV2_ATOM__Vector: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#Vector\0";
+pub const LV2_ATOM__atomTransfer: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/atom#atomTransfer\0";
+pub const LV2_ATOM__beatTime: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#beatTime\0";
+pub const LV2_ATOM__bufferType: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/atom#bufferType\0";
+pub const LV2_ATOM__childType: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/atom#childType\0";
+pub const LV2_ATOM__eventTransfer: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/atom#eventTransfer\0";
+pub const LV2_ATOM__frameTime: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/atom#frameTime\0";
+pub const LV2_ATOM__supports: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#supports\0";
+pub const LV2_ATOM__timeUnit: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#timeUnit\0";
+pub const LV2_ATOM_REFERENCE_TYPE: u32 = 0;
+pub const LV2_URID_URI: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/urid\0";
+pub const LV2_URID_PREFIX: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/urid#\0";
+pub const LV2_URID__map: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/urid#map\0";
+pub const LV2_URID__unmap: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/urid#unmap\0";
+pub const LV2_URID_MAP_URI: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/urid#map\0";
+pub const LV2_URID_UNMAP_URI: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/urid#unmap\0";
+pub const LV2_BUF_SIZE_URI: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/buf-size\0";
+pub const LV2_BUF_SIZE_PREFIX: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/buf-size#\0";
+pub const LV2_BUF_SIZE__boundedBlockLength: &'static [u8; 53usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#boundedBlockLength\0";
+pub const LV2_BUF_SIZE__fixedBlockLength: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#fixedBlockLength\0";
+pub const LV2_BUF_SIZE__maxBlockLength: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#maxBlockLength\0";
+pub const LV2_BUF_SIZE__minBlockLength: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#minBlockLength\0";
+pub const LV2_BUF_SIZE__nominalBlockLength: &'static [u8; 53usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#nominalBlockLength\0";
+pub const LV2_BUF_SIZE__powerOf2BlockLength: &'static [u8; 54usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#powerOf2BlockLength\0";
+pub const LV2_BUF_SIZE__sequenceSize: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#sequenceSize\0";
+pub const LV2_CORE_URI: &'static [u8; 29usize] = b"http://lv2plug.in/ns/lv2core\0";
+pub const LV2_CORE_PREFIX: &'static [u8; 30usize] = b"http://lv2plug.in/ns/lv2core#\0";
+pub const LV2_CORE__AllpassPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#AllpassPlugin\0";
+pub const LV2_CORE__AmplifierPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#AmplifierPlugin\0";
+pub const LV2_CORE__AnalyserPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#AnalyserPlugin\0";
+pub const LV2_CORE__AudioPort: &'static [u8; 39usize] = b"http://lv2plug.in/ns/lv2core#AudioPort\0";
+pub const LV2_CORE__BandpassPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#BandpassPlugin\0";
+pub const LV2_CORE__CVPort: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#CVPort\0";
+pub const LV2_CORE__ChorusPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#ChorusPlugin\0";
+pub const LV2_CORE__CombPlugin: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#CombPlugin\0";
+pub const LV2_CORE__CompressorPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#CompressorPlugin\0";
+pub const LV2_CORE__ConstantPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#ConstantPlugin\0";
+pub const LV2_CORE__ControlPort: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#ControlPort\0";
+pub const LV2_CORE__ConverterPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#ConverterPlugin\0";
+pub const LV2_CORE__DelayPlugin: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#DelayPlugin\0";
+pub const LV2_CORE__DistortionPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#DistortionPlugin\0";
+pub const LV2_CORE__DynamicsPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#DynamicsPlugin\0";
+pub const LV2_CORE__EQPlugin: &'static [u8; 38usize] = b"http://lv2plug.in/ns/lv2core#EQPlugin\0";
+pub const LV2_CORE__EnvelopePlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#EnvelopePlugin\0";
+pub const LV2_CORE__ExpanderPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#ExpanderPlugin\0";
+pub const LV2_CORE__ExtensionData: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#ExtensionData\0";
+pub const LV2_CORE__Feature: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#Feature\0";
+pub const LV2_CORE__FilterPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#FilterPlugin\0";
+pub const LV2_CORE__FlangerPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#FlangerPlugin\0";
+pub const LV2_CORE__FunctionPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#FunctionPlugin\0";
+pub const LV2_CORE__GatePlugin: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#GatePlugin\0";
+pub const LV2_CORE__GeneratorPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#GeneratorPlugin\0";
+pub const LV2_CORE__HighpassPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#HighpassPlugin\0";
+pub const LV2_CORE__InputPort: &'static [u8; 39usize] = b"http://lv2plug.in/ns/lv2core#InputPort\0";
+pub const LV2_CORE__InstrumentPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#InstrumentPlugin\0";
+pub const LV2_CORE__LimiterPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#LimiterPlugin\0";
+pub const LV2_CORE__LowpassPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#LowpassPlugin\0";
+pub const LV2_CORE__MixerPlugin: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#MixerPlugin\0";
+pub const LV2_CORE__ModulatorPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#ModulatorPlugin\0";
+pub const LV2_CORE__MultiEQPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#MultiEQPlugin\0";
+pub const LV2_CORE__OscillatorPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#OscillatorPlugin\0";
+pub const LV2_CORE__OutputPort: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#OutputPort\0";
+pub const LV2_CORE__ParaEQPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#ParaEQPlugin\0";
+pub const LV2_CORE__PhaserPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#PhaserPlugin\0";
+pub const LV2_CORE__PitchPlugin: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#PitchPlugin\0";
+pub const LV2_CORE__Plugin: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#Plugin\0";
+pub const LV2_CORE__PluginBase: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#PluginBase\0";
+pub const LV2_CORE__Point: &'static [u8; 35usize] = b"http://lv2plug.in/ns/lv2core#Point\0";
+pub const LV2_CORE__Port: &'static [u8; 34usize] = b"http://lv2plug.in/ns/lv2core#Port\0";
+pub const LV2_CORE__PortProperty: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#PortProperty\0";
+pub const LV2_CORE__Resource: &'static [u8; 38usize] = b"http://lv2plug.in/ns/lv2core#Resource\0";
+pub const LV2_CORE__ReverbPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#ReverbPlugin\0";
+pub const LV2_CORE__ScalePoint: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#ScalePoint\0";
+pub const LV2_CORE__SimulatorPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#SimulatorPlugin\0";
+pub const LV2_CORE__SpatialPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#SpatialPlugin\0";
+pub const LV2_CORE__Specification: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#Specification\0";
+pub const LV2_CORE__SpectralPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#SpectralPlugin\0";
+pub const LV2_CORE__UtilityPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#UtilityPlugin\0";
+pub const LV2_CORE__WaveshaperPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#WaveshaperPlugin\0";
+pub const LV2_CORE__appliesTo: &'static [u8; 39usize] = b"http://lv2plug.in/ns/lv2core#appliesTo\0";
+pub const LV2_CORE__binary: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#binary\0";
+pub const LV2_CORE__connectionOptional: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/lv2core#connectionOptional\0";
+pub const LV2_CORE__control: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#control\0";
+pub const LV2_CORE__default: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#default\0";
+pub const LV2_CORE__designation: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#designation\0";
+pub const LV2_CORE__documentation: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#documentation\0";
+pub const LV2_CORE__enumeration: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#enumeration\0";
+pub const LV2_CORE__extensionData: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#extensionData\0";
+pub const LV2_CORE__freeWheeling: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#freeWheeling\0";
+pub const LV2_CORE__hardRTCapable: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#hardRTCapable\0";
+pub const LV2_CORE__inPlaceBroken: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#inPlaceBroken\0";
+pub const LV2_CORE__index: &'static [u8; 35usize] = b"http://lv2plug.in/ns/lv2core#index\0";
+pub const LV2_CORE__integer: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#integer\0";
+pub const LV2_CORE__isLive: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#isLive\0";
+pub const LV2_CORE__latency: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#latency\0";
+pub const LV2_CORE__maximum: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#maximum\0";
+pub const LV2_CORE__microVersion: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#microVersion\0";
+pub const LV2_CORE__minimum: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#minimum\0";
+pub const LV2_CORE__minorVersion: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#minorVersion\0";
+pub const LV2_CORE__name: &'static [u8; 34usize] = b"http://lv2plug.in/ns/lv2core#name\0";
+pub const LV2_CORE__optionalFeature: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#optionalFeature\0";
+pub const LV2_CORE__port: &'static [u8; 34usize] = b"http://lv2plug.in/ns/lv2core#port\0";
+pub const LV2_CORE__portProperty: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#portProperty\0";
+pub const LV2_CORE__project: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#project\0";
+pub const LV2_CORE__prototype: &'static [u8; 39usize] = b"http://lv2plug.in/ns/lv2core#prototype\0";
+pub const LV2_CORE__reportsLatency: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#reportsLatency\0";
+pub const LV2_CORE__requiredFeature: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#requiredFeature\0";
+pub const LV2_CORE__sampleRate: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#sampleRate\0";
+pub const LV2_CORE__scalePoint: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#scalePoint\0";
+pub const LV2_CORE__symbol: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#symbol\0";
+pub const LV2_CORE__toggled: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#toggled\0";
+pub const LV2_DATA_ACCESS_URI: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/data-access\0";
+pub const LV2_DATA_ACCESS_PREFIX: &'static [u8; 38usize] =
+    b"http://lv2plug.in/ns/ext/data-access#\0";
+pub const LV2_DYN_MANIFEST_URI: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/dynmanifest\0";
+pub const LV2_DYN_MANIFEST_PREFIX: &'static [u8; 38usize] =
+    b"http://lv2plug.in/ns/ext/dynmanifest#\0";
+pub const LV2_EVENT_URI: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/event\0";
+pub const LV2_EVENT_PREFIX: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/event#\0";
+pub const LV2_EVENT__Event: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/event#Event\0";
+pub const LV2_EVENT__EventPort: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/event#EventPort\0";
+pub const LV2_EVENT__FrameStamp: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/event#FrameStamp\0";
+pub const LV2_EVENT__TimeStamp: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/event#TimeStamp\0";
+pub const LV2_EVENT__generatesTimeStamp: &'static [u8; 50usize] =
+    b"http://lv2plug.in/ns/ext/event#generatesTimeStamp\0";
+pub const LV2_EVENT__generic: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/event#generic\0";
+pub const LV2_EVENT__inheritsEvent: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/event#inheritsEvent\0";
+pub const LV2_EVENT__inheritsTimeStamp: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/event#inheritsTimeStamp\0";
+pub const LV2_EVENT__supportsEvent: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/event#supportsEvent\0";
+pub const LV2_EVENT__supportsTimeStamp: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/event#supportsTimeStamp\0";
+pub const LV2_EVENT_AUDIO_STAMP: u32 = 0;
+pub const LV2_INSTANCE_ACCESS_URI: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/instance-access\0";
+pub const LV2_LOG_URI: &'static [u8; 29usize] = b"http://lv2plug.in/ns/ext/log\0";
+pub const LV2_LOG_PREFIX: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/log#\0";
+pub const LV2_LOG__Entry: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/log#Entry\0";
+pub const LV2_LOG__Error: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/log#Error\0";
+pub const LV2_LOG__Note: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/log#Note\0";
+pub const LV2_LOG__Trace: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/log#Trace\0";
+pub const LV2_LOG__Warning: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/log#Warning\0";
+pub const LV2_LOG__log: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/log#log\0";
+pub const LV2_MIDI_URI: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/midi\0";
+pub const LV2_MIDI_PREFIX: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/midi#\0";
+pub const LV2_MIDI__ActiveSense: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/midi#ActiveSense\0";
+pub const LV2_MIDI__Aftertouch: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#Aftertouch\0";
+pub const LV2_MIDI__Bender: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/midi#Bender\0";
+pub const LV2_MIDI__ChannelPressure: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/midi#ChannelPressure\0";
+pub const LV2_MIDI__Chunk: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#Chunk\0";
+pub const LV2_MIDI__Clock: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#Clock\0";
+pub const LV2_MIDI__Continue: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/midi#Continue\0";
+pub const LV2_MIDI__Controller: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#Controller\0";
+pub const LV2_MIDI__MidiEvent: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/midi#MidiEvent\0";
+pub const LV2_MIDI__NoteOff: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/midi#NoteOff\0";
+pub const LV2_MIDI__NoteOn: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/midi#NoteOn\0";
+pub const LV2_MIDI__ProgramChange: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/midi#ProgramChange\0";
+pub const LV2_MIDI__QuarterFrame: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#QuarterFrame\0";
+pub const LV2_MIDI__Reset: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#Reset\0";
+pub const LV2_MIDI__SongPosition: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#SongPosition\0";
+pub const LV2_MIDI__SongSelect: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#SongSelect\0";
+pub const LV2_MIDI__Start: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#Start\0";
+pub const LV2_MIDI__Stop: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/midi#Stop\0";
+pub const LV2_MIDI__SystemCommon: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#SystemCommon\0";
+pub const LV2_MIDI__SystemExclusive: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/midi#SystemExclusive\0";
+pub const LV2_MIDI__SystemMessage: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/midi#SystemMessage\0";
+pub const LV2_MIDI__SystemRealtime: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/midi#SystemRealtime\0";
+pub const LV2_MIDI__Tick: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/midi#Tick\0";
+pub const LV2_MIDI__TuneRequest: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/midi#TuneRequest\0";
+pub const LV2_MIDI__VoiceMessage: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#VoiceMessage\0";
+pub const LV2_MIDI__benderValue: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/midi#benderValue\0";
+pub const LV2_MIDI__binding: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/midi#binding\0";
+pub const LV2_MIDI__byteNumber: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#byteNumber\0";
+pub const LV2_MIDI__channel: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/midi#channel\0";
+pub const LV2_MIDI__chunk: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#chunk\0";
+pub const LV2_MIDI__controllerNumber: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/midi#controllerNumber\0";
+pub const LV2_MIDI__controllerValue: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/midi#controllerValue\0";
+pub const LV2_MIDI__noteNumber: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#noteNumber\0";
+pub const LV2_MIDI__pressure: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/midi#pressure\0";
+pub const LV2_MIDI__programNumber: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/midi#programNumber\0";
+pub const LV2_MIDI__property: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/midi#property\0";
+pub const LV2_MIDI__songNumber: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#songNumber\0";
+pub const LV2_MIDI__songPosition: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#songPosition\0";
+pub const LV2_MIDI__status: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/midi#status\0";
+pub const LV2_MIDI__statusMask: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#statusMask\0";
+pub const LV2_MIDI__velocity: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/midi#velocity\0";
+pub const LV2_MORPH_URI: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/morph\0";
+pub const LV2_MORPH_PREFIX: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/morph#\0";
+pub const LV2_MORPH__AutoMorphPort: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/morph#AutoMorphPort\0";
+pub const LV2_MORPH__MorphPort: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/morph#MorphPort\0";
+pub const LV2_MORPH__interface: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/morph#interface\0";
+pub const LV2_MORPH__supportsType: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/morph#supportsType\0";
+pub const LV2_MORPH__currentType: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/morph#currentType\0";
+pub const LV2_OPTIONS_URI: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/options\0";
+pub const LV2_OPTIONS_PREFIX: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/options#\0";
+pub const LV2_OPTIONS__Option: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/options#Option\0";
+pub const LV2_OPTIONS__interface: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/options#interface\0";
+pub const LV2_OPTIONS__options: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/options#options\0";
+pub const LV2_OPTIONS__requiredOption: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/options#requiredOption\0";
+pub const LV2_OPTIONS__supportedOption: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/options#supportedOption\0";
+pub const LV2_PARAMETERS_URI: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/parameters\0";
+pub const LV2_PARAMETERS_PREFIX: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/parameters#\0";
+pub const LV2_PARAMETERS__CompressorControls: &'static [u8; 55usize] =
+    b"http://lv2plug.in/ns/ext/parameters#CompressorControls\0";
+pub const LV2_PARAMETERS__ControlGroup: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/parameters#ControlGroup\0";
+pub const LV2_PARAMETERS__EnvelopeControls: &'static [u8; 53usize] =
+    b"http://lv2plug.in/ns/ext/parameters#EnvelopeControls\0";
+pub const LV2_PARAMETERS__FilterControls: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/ext/parameters#FilterControls\0";
+pub const LV2_PARAMETERS__OscillatorControls: &'static [u8; 55usize] =
+    b"http://lv2plug.in/ns/ext/parameters#OscillatorControls\0";
+pub const LV2_PARAMETERS__amplitude: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/parameters#amplitude\0";
+pub const LV2_PARAMETERS__attack: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/parameters#attack\0";
+pub const LV2_PARAMETERS__bypass: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/parameters#bypass\0";
+pub const LV2_PARAMETERS__cutoffFrequency: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/ext/parameters#cutoffFrequency\0";
+pub const LV2_PARAMETERS__decay: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/parameters#decay\0";
+pub const LV2_PARAMETERS__delay: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/parameters#delay\0";
+pub const LV2_PARAMETERS__dryLevel: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/parameters#dryLevel\0";
+pub const LV2_PARAMETERS__frequency: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/parameters#frequency\0";
+pub const LV2_PARAMETERS__gain: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/parameters#gain\0";
+pub const LV2_PARAMETERS__hold: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/parameters#hold\0";
+pub const LV2_PARAMETERS__pulseWidth: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/parameters#pulseWidth\0";
+pub const LV2_PARAMETERS__ratio: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/parameters#ratio\0";
+pub const LV2_PARAMETERS__release: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/parameters#release\0";
+pub const LV2_PARAMETERS__resonance: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/parameters#resonance\0";
+pub const LV2_PARAMETERS__sampleRate: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/parameters#sampleRate\0";
+pub const LV2_PARAMETERS__sustain: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/parameters#sustain\0";
+pub const LV2_PARAMETERS__threshold: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/parameters#threshold\0";
+pub const LV2_PARAMETERS__waveform: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/parameters#waveform\0";
+pub const LV2_PARAMETERS__wetDryRatio: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/parameters#wetDryRatio\0";
+pub const LV2_PARAMETERS__wetLevel: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/parameters#wetLevel\0";
+pub const LV2_PATCH_URI: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/patch\0";
+pub const LV2_PATCH_PREFIX: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/patch#\0";
+pub const LV2_PATCH__Ack: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#Ack\0";
+pub const LV2_PATCH__Delete: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/patch#Delete\0";
+pub const LV2_PATCH__Copy: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/patch#Copy\0";
+pub const LV2_PATCH__Error: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/patch#Error\0";
+pub const LV2_PATCH__Get: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#Get\0";
+pub const LV2_PATCH__Message: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#Message\0";
+pub const LV2_PATCH__Move: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/patch#Move\0";
+pub const LV2_PATCH__Patch: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/patch#Patch\0";
+pub const LV2_PATCH__Post: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/patch#Post\0";
+pub const LV2_PATCH__Put: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#Put\0";
+pub const LV2_PATCH__Request: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#Request\0";
+pub const LV2_PATCH__Response: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#Response\0";
+pub const LV2_PATCH__Set: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#Set\0";
+pub const LV2_PATCH__accept: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/patch#accept\0";
+pub const LV2_PATCH__add: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#add\0";
+pub const LV2_PATCH__body: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/patch#body\0";
+pub const LV2_PATCH__context: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#context\0";
+pub const LV2_PATCH__destination: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/patch#destination\0";
+pub const LV2_PATCH__property: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#property\0";
+pub const LV2_PATCH__readable: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#readable\0";
+pub const LV2_PATCH__remove: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/patch#remove\0";
+pub const LV2_PATCH__request: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#request\0";
+pub const LV2_PATCH__subject: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#subject\0";
+pub const LV2_PATCH__sequenceNumber: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/patch#sequenceNumber\0";
+pub const LV2_PATCH__value: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/patch#value\0";
+pub const LV2_PATCH__wildcard: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#wildcard\0";
+pub const LV2_PATCH__writable: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#writable\0";
+pub const LV2_PORT_GROUPS_URI: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/port-groups\0";
+pub const LV2_PORT_GROUPS_PREFIX: &'static [u8; 38usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#\0";
+pub const LV2_PORT_GROUPS__DiscreteGroup: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#DiscreteGroup\0";
+pub const LV2_PORT_GROUPS__Element: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#Element\0";
+pub const LV2_PORT_GROUPS__FivePointOneGroup: &'static [u8; 55usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#FivePointOneGroup\0";
+pub const LV2_PORT_GROUPS__FivePointZeroGroup: &'static [u8; 56usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#FivePointZeroGroup\0";
+pub const LV2_PORT_GROUPS__FourPointZeroGroup: &'static [u8; 56usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#FourPointZeroGroup\0";
+pub const LV2_PORT_GROUPS__Group: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#Group\0";
+pub const LV2_PORT_GROUPS__InputGroup: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#InputGroup\0";
+pub const LV2_PORT_GROUPS__MidSideGroup: &'static [u8; 50usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#MidSideGroup\0";
+pub const LV2_PORT_GROUPS__MonoGroup: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#MonoGroup\0";
+pub const LV2_PORT_GROUPS__OutputGroup: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#OutputGroup\0";
+pub const LV2_PORT_GROUPS__SevenPointOneGroup: &'static [u8; 56usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#SevenPointOneGroup\0";
+pub const LV2_PORT_GROUPS__SevenPointOneWideGroup: &'static [u8; 60usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#SevenPointOneWideGroup\0";
+pub const LV2_PORT_GROUPS__SixPointOneGroup: &'static [u8; 54usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#SixPointOneGroup\0";
+pub const LV2_PORT_GROUPS__StereoGroup: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#StereoGroup\0";
+pub const LV2_PORT_GROUPS__ThreePointZeroGroup: &'static [u8; 57usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#ThreePointZeroGroup\0";
+pub const LV2_PORT_GROUPS__center: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#center\0";
+pub const LV2_PORT_GROUPS__centerLeft: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#centerLeft\0";
+pub const LV2_PORT_GROUPS__centerRight: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#centerRight\0";
+pub const LV2_PORT_GROUPS__element: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#element\0";
+pub const LV2_PORT_GROUPS__group: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#group\0";
+pub const LV2_PORT_GROUPS__left: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#left\0";
+pub const LV2_PORT_GROUPS__lowFrequencyEffects: &'static [u8; 57usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#lowFrequencyEffects\0";
+pub const LV2_PORT_GROUPS__mainInput: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#mainInput\0";
+pub const LV2_PORT_GROUPS__mainOutput: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#mainOutput\0";
+pub const LV2_PORT_GROUPS__rearCenter: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#rearCenter\0";
+pub const LV2_PORT_GROUPS__rearLeft: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#rearLeft\0";
+pub const LV2_PORT_GROUPS__rearRight: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#rearRight\0";
+pub const LV2_PORT_GROUPS__right: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#right\0";
+pub const LV2_PORT_GROUPS__side: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#side\0";
+pub const LV2_PORT_GROUPS__sideChainOf: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#sideChainOf\0";
+pub const LV2_PORT_GROUPS__sideLeft: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#sideLeft\0";
+pub const LV2_PORT_GROUPS__sideRight: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#sideRight\0";
+pub const LV2_PORT_GROUPS__source: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#source\0";
+pub const LV2_PORT_GROUPS__subGroupOf: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#subGroupOf\0";
+pub const LV2_PORT_PROPS_URI: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/port-props\0";
+pub const LV2_PORT_PROPS_PREFIX: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/port-props#\0";
+pub const LV2_PORT_PROPS__causesArtifacts: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/ext/port-props#causesArtifacts\0";
+pub const LV2_PORT_PROPS__continuousCV: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-props#continuousCV\0";
+pub const LV2_PORT_PROPS__discreteCV: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-props#discreteCV\0";
+pub const LV2_PORT_PROPS__displayPriority: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/ext/port-props#displayPriority\0";
+pub const LV2_PORT_PROPS__expensive: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/port-props#expensive\0";
+pub const LV2_PORT_PROPS__hasStrictBounds: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/ext/port-props#hasStrictBounds\0";
+pub const LV2_PORT_PROPS__logarithmic: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-props#logarithmic\0";
+pub const LV2_PORT_PROPS__notAutomatic: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-props#notAutomatic\0";
+pub const LV2_PORT_PROPS__notOnGUI: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/port-props#notOnGUI\0";
+pub const LV2_PORT_PROPS__rangeSteps: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-props#rangeSteps\0";
+pub const LV2_PORT_PROPS__supportsStrictBounds: &'static [u8; 57usize] =
+    b"http://lv2plug.in/ns/ext/port-props#supportsStrictBounds\0";
+pub const LV2_PORT_PROPS__trigger: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/port-props#trigger\0";
+pub const LV2_PRESETS_URI: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/presets\0";
+pub const LV2_PRESETS_PREFIX: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/presets#\0";
+pub const LV2_PRESETS__Bank: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/presets#Bank\0";
+pub const LV2_PRESETS__Preset: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/presets#Preset\0";
+pub const LV2_PRESETS__bank: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/presets#bank\0";
+pub const LV2_PRESETS__preset: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/presets#preset\0";
+pub const LV2_PRESETS__value: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/presets#value\0";
+pub const LV2_RESIZE_PORT_URI: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/resize-port\0";
+pub const LV2_RESIZE_PORT_PREFIX: &'static [u8; 38usize] =
+    b"http://lv2plug.in/ns/ext/resize-port#\0";
+pub const LV2_RESIZE_PORT__asLargeAs: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/resize-port#asLargeAs\0";
+pub const LV2_RESIZE_PORT__minimumSize: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/resize-port#minimumSize\0";
+pub const LV2_RESIZE_PORT__resize: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/resize-port#resize\0";
+pub const LV2_STATE_URI: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/state\0";
+pub const LV2_STATE_PREFIX: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/state#\0";
+pub const LV2_STATE__State: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/state#State\0";
+pub const LV2_STATE__interface: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/state#interface\0";
+pub const LV2_STATE__loadDefaultState: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/state#loadDefaultState\0";
+pub const LV2_STATE__freePath: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/state#freePath\0";
+pub const LV2_STATE__makePath: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/state#makePath\0";
+pub const LV2_STATE__mapPath: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/state#mapPath\0";
+pub const LV2_STATE__state: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/state#state\0";
+pub const LV2_STATE__threadSafeRestore: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/state#threadSafeRestore\0";
+pub const LV2_STATE__StateChanged: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/state#StateChanged\0";
+pub const LV2_TIME_URI: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/time\0";
+pub const LV2_TIME_PREFIX: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/time#\0";
+pub const LV2_TIME__Time: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/time#Time\0";
+pub const LV2_TIME__Position: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/time#Position\0";
+pub const LV2_TIME__Rate: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/time#Rate\0";
+pub const LV2_TIME__position: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/time#position\0";
+pub const LV2_TIME__barBeat: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/time#barBeat\0";
+pub const LV2_TIME__bar: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/time#bar\0";
+pub const LV2_TIME__beat: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/time#beat\0";
+pub const LV2_TIME__beatUnit: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/time#beatUnit\0";
+pub const LV2_TIME__beatsPerBar: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/time#beatsPerBar\0";
+pub const LV2_TIME__beatsPerMinute: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/time#beatsPerMinute\0";
+pub const LV2_TIME__frame: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/time#frame\0";
+pub const LV2_TIME__framesPerSecond: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/time#framesPerSecond\0";
+pub const LV2_TIME__speed: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/time#speed\0";
+pub const LV2_UI_URI: &'static [u8; 35usize] = b"http://lv2plug.in/ns/extensions/ui\0";
+pub const LV2_UI_PREFIX: &'static [u8; 36usize] = b"http://lv2plug.in/ns/extensions/ui#\0";
+pub const LV2_UI__CocoaUI: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/ui#CocoaUI\0";
+pub const LV2_UI__Gtk3UI: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#Gtk3UI\0";
+pub const LV2_UI__GtkUI: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#GtkUI\0";
+pub const LV2_UI__PortNotification: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/extensions/ui#PortNotification\0";
+pub const LV2_UI__PortProtocol: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/extensions/ui#PortProtocol\0";
+pub const LV2_UI__Qt4UI: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#Qt4UI\0";
+pub const LV2_UI__Qt5UI: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#Qt5UI\0";
+pub const LV2_UI__UI: &'static [u8; 38usize] = b"http://lv2plug.in/ns/extensions/ui#UI\0";
+pub const LV2_UI__WindowsUI: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/ui#WindowsUI\0";
+pub const LV2_UI__X11UI: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#X11UI\0";
+pub const LV2_UI__binary: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#binary\0";
+pub const LV2_UI__fixedSize: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/ui#fixedSize\0";
+pub const LV2_UI__idleInterface: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/ui#idleInterface\0";
+pub const LV2_UI__noUserResize: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/extensions/ui#noUserResize\0";
+pub const LV2_UI__notifyType: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/extensions/ui#notifyType\0";
+pub const LV2_UI__parent: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#parent\0";
+pub const LV2_UI__plugin: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#plugin\0";
+pub const LV2_UI__portIndex: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/ui#portIndex\0";
+pub const LV2_UI__portMap: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/ui#portMap\0";
+pub const LV2_UI__portNotification: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/extensions/ui#portNotification\0";
+pub const LV2_UI__portSubscribe: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/ui#portSubscribe\0";
+pub const LV2_UI__protocol: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/extensions/ui#protocol\0";
+pub const LV2_UI__requestValue: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/extensions/ui#requestValue\0";
+pub const LV2_UI__floatProtocol: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/ui#floatProtocol\0";
+pub const LV2_UI__peakProtocol: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/extensions/ui#peakProtocol\0";
+pub const LV2_UI__resize: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#resize\0";
+pub const LV2_UI__showInterface: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/ui#showInterface\0";
+pub const LV2_UI__touch: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#touch\0";
+pub const LV2_UI__ui: &'static [u8; 38usize] = b"http://lv2plug.in/ns/extensions/ui#ui\0";
+pub const LV2_UI__updateRate: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/extensions/ui#updateRate\0";
+pub const LV2_UI__windowTitle: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/extensions/ui#windowTitle\0";
+pub const LV2_UI__scaleFactor: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/extensions/ui#scaleFactor\0";
+pub const LV2_UI__foregroundColor: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/extensions/ui#foregroundColor\0";
+pub const LV2_UI__backgroundColor: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/extensions/ui#backgroundColor\0";
+pub const LV2_UNITS_URI: &'static [u8; 38usize] = b"http://lv2plug.in/ns/extensions/units\0";
+pub const LV2_UNITS_PREFIX: &'static [u8; 39usize] = b"http://lv2plug.in/ns/extensions/units#\0";
+pub const LV2_UNITS__Conversion: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/units#Conversion\0";
+pub const LV2_UNITS__Unit: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#Unit\0";
+pub const LV2_UNITS__bar: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#bar\0";
+pub const LV2_UNITS__beat: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#beat\0";
+pub const LV2_UNITS__bpm: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#bpm\0";
+pub const LV2_UNITS__cent: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#cent\0";
+pub const LV2_UNITS__cm: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#cm\0";
+pub const LV2_UNITS__coef: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#coef\0";
+pub const LV2_UNITS__conversion: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/units#conversion\0";
+pub const LV2_UNITS__db: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#db\0";
+pub const LV2_UNITS__degree: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/units#degree\0";
+pub const LV2_UNITS__frame: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/extensions/units#frame\0";
+pub const LV2_UNITS__hz: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#hz\0";
+pub const LV2_UNITS__inch: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#inch\0";
+pub const LV2_UNITS__khz: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#khz\0";
+pub const LV2_UNITS__km: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#km\0";
+pub const LV2_UNITS__m: &'static [u8; 40usize] = b"http://lv2plug.in/ns/extensions/units#m\0";
+pub const LV2_UNITS__mhz: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#mhz\0";
+pub const LV2_UNITS__midiNote: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/extensions/units#midiNote\0";
+pub const LV2_UNITS__mile: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#mile\0";
+pub const LV2_UNITS__min: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#min\0";
+pub const LV2_UNITS__mm: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#mm\0";
+pub const LV2_UNITS__ms: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#ms\0";
+pub const LV2_UNITS__name: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#name\0";
+pub const LV2_UNITS__oct: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#oct\0";
+pub const LV2_UNITS__pc: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#pc\0";
+pub const LV2_UNITS__prefixConversion: &'static [u8; 55usize] =
+    b"http://lv2plug.in/ns/extensions/units#prefixConversion\0";
+pub const LV2_UNITS__render: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/units#render\0";
+pub const LV2_UNITS__s: &'static [u8; 40usize] = b"http://lv2plug.in/ns/extensions/units#s\0";
+pub const LV2_UNITS__semitone12TET: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/extensions/units#semitone12TET\0";
+pub const LV2_UNITS__symbol: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/units#symbol\0";
+pub const LV2_UNITS__unit: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#unit\0";
+pub const LV2_URI_MAP_URI: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/uri-map\0";
+pub const LV2_URI_MAP_PREFIX: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/uri-map#\0";
+pub const LV2_WORKER_URI: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/worker\0";
+pub const LV2_WORKER_PREFIX: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/worker#\0";
+pub const LV2_WORKER__interface: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/worker#interface\0";
+pub const LV2_WORKER__schedule: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/worker#schedule\0";
+pub type __uint8_t = ::std::os::raw::c_uchar;
+pub type __uint16_t = ::std::os::raw::c_ushort;
+pub type __int32_t = ::std::os::raw::c_int;
+pub type __uint32_t = ::std::os::raw::c_uint;
+pub type __int64_t = ::std::os::raw::c_longlong;
+#[doc = " The header of an atom:Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom {
+    #[doc = "< Size in bytes, not including type and size."]
+    pub size: u32,
+    #[doc = "< Type of this atom (mapped URI)."]
+    pub type_: u32,
+}
+#[doc = " An atom:Int or atom:Bool.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Int {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Integer value."]
+    pub body: i32,
+}
+#[doc = " An atom:Long.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Long {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Integer value."]
+    pub body: i64,
+}
+#[doc = " An atom:Float.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Float {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Floating point value."]
+    pub body: f32,
+}
+#[doc = " An atom:Double.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Double {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Floating point value."]
+    pub body: f64,
+}
+#[doc = " An atom:Bool.  May be cast to LV2_Atom."]
+pub type LV2_Atom_Bool = LV2_Atom_Int;
+#[doc = " An atom:URID.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_URID {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< URID."]
+    pub body: u32,
+}
+#[doc = " An atom:String.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_String {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+}
+#[doc = " The body of an atom:Literal."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Literal_Body {
+    #[doc = "< Datatype URID."]
+    pub datatype: u32,
+    #[doc = "< Language URID."]
+    pub lang: u32,
+}
+#[doc = " An atom:Literal.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Literal {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Literal_Body,
+}
+#[doc = " An atom:Tuple.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Tuple {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+}
+#[doc = " The body of an atom:Vector."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Vector_Body {
+    #[doc = "< The size of each element in the vector."]
+    pub child_size: u32,
+    #[doc = "< The type of each element in the vector."]
+    pub child_type: u32,
+}
+#[doc = " An atom:Vector.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Vector {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Vector_Body,
+}
+#[doc = " The body of an atom:Property (typically in an atom:Object)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Property_Body {
+    #[doc = "< Key (predicate) (mapped URI)."]
+    pub key: u32,
+    #[doc = "< Context URID (may be, and generally is, 0)."]
+    pub context: u32,
+    #[doc = "< Value atom header."]
+    pub value: LV2_Atom,
+}
+#[doc = " An atom:Property.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Property {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Property_Body,
+}
+#[doc = " The body of an atom:Object. May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Object_Body {
+    #[doc = "< URID, or 0 for blank."]
+    pub id: u32,
+    #[doc = "< Type URID (same as rdf:type, for fast dispatch)."]
+    pub otype: u32,
+}
+#[doc = " An atom:Object.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Object {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Object_Body,
+}
+#[doc = " The header of an atom:Event.  Note this type is NOT an LV2_Atom."]
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct LV2_Atom_Event {
+    pub time: LV2_Atom_Event__bindgen_ty_1,
+    #[doc = "< Event body atom header."]
+    pub body: LV2_Atom,
+}
+#[doc = " Time stamp.  Which type is valid is determined by context."]
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union LV2_Atom_Event__bindgen_ty_1 {
+    #[doc = "< Time in audio frames."]
+    pub frames: i64,
+    #[doc = "< Time in beats."]
+    pub beats: f64,
+    _bindgen_union_align: u64,
+}
+#[doc = "The body of an atom:Sequence (a sequence of events)."]
+#[doc = ""]
+#[doc = "The unit field is either a URID that described an appropriate time stamp"]
+#[doc = "type, or may be 0 where a default stamp type is known.  For"]
+#[doc = "LV2_Descriptor::run(), the default stamp type is audio frames."]
+#[doc = ""]
+#[doc = "The contents of a sequence is a series of LV2_Atom_Event, each aligned"]
+#[doc = "to 64-bits, for example:"]
+#[doc = "<pre>"]
+#[doc = "| Event 1 (size 6)                              | Event 2"]
+#[doc = "|       |       |       |       |       |       |       |       |"]
+#[doc = "| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |"]
+#[doc = "|FRAMES |SUBFRMS|TYPE   |SIZE   |DATADATADATAPAD|FRAMES |SUBFRMS|..."]
+#[doc = "</pre>"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Sequence_Body {
+    #[doc = "< URID of unit of event time stamps."]
+    pub unit: u32,
+    #[doc = "< Currently unused."]
+    pub pad: u32,
+}
+#[doc = " An atom:Sequence."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Sequence {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Sequence_Body,
+}
+pub type va_list = __builtin_va_list;
+#[doc = " A single entry in an Object query."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Object_Query {
+    #[doc = "< Key to query (input set by user)"]
+    pub key: u32,
+    #[doc = "< Found value (output set by query function)"]
+    pub value: *mut *const LV2_Atom,
+}
+extern "C" {
+    pub static LV2_ATOM_OBJECT_QUERY_END: LV2_Atom_Object_Query;
+}
+#[doc = "Opaque pointer to host data for LV2_URID_Map."]
+pub type LV2_URID_Map_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Opaque pointer to host data for LV2_URID_Unmap."]
+pub type LV2_URID_Unmap_Handle = *mut ::std::os::raw::c_void;
+#[doc = "URI mapped to an integer."]
+pub type LV2_URID = u32;
+#[doc = "URID Map Feature (LV2_URID__map)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_URID_Map {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "This MUST be passed to map_uri() whenever it is called."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub handle: LV2_URID_Map_Handle,
+    #[doc = "Get the numeric ID of a URI."]
+    #[doc = ""]
+    #[doc = "If the ID does not already exist, it will be created."]
+    #[doc = ""]
+    #[doc = "This function is referentially transparent; any number of calls with the"]
+    #[doc = "same arguments is guaranteed to return the same value over the life of a"]
+    #[doc = "plugin instance.  Note, however, that several URIs MAY resolve to the"]
+    #[doc = "same ID if the host considers those URIs equivalent."]
+    #[doc = ""]
+    #[doc = "This function is not necessarily very fast or RT-safe: plugins SHOULD"]
+    #[doc = "cache any IDs they might need in performance critical situations."]
+    #[doc = ""]
+    #[doc = "The return value 0 is reserved and indicates that an ID for that URI"]
+    #[doc = "could not be created for whatever reason.  However, hosts SHOULD NOT"]
+    #[doc = "return 0 from this function in non-exceptional circumstances (i.e. the"]
+    #[doc = "URI map SHOULD be dynamic)."]
+    #[doc = ""]
+    #[doc = "@param handle Must be the callback_data member of this struct."]
+    #[doc = "@param uri The URI to be mapped to an integer ID."]
+    pub map: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_URID_Map_Handle,
+            uri: *const ::std::os::raw::c_char,
+        ) -> LV2_URID,
+    >,
+}
+#[doc = "URI Unmap Feature (LV2_URID__unmap)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_URID_Unmap {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "This MUST be passed to unmap() whenever it is called."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub handle: LV2_URID_Unmap_Handle,
+    #[doc = "Get the URI for a previously mapped numeric ID."]
+    #[doc = ""]
+    #[doc = "Returns NULL if `urid` is not yet mapped.  Otherwise, the corresponding"]
+    #[doc = "URI is returned in a canonical form.  This MAY not be the exact same"]
+    #[doc = "string that was originally passed to LV2_URID_Map::map(), but it MUST be"]
+    #[doc = "an identical URI according to the URI syntax specification (RFC3986).  A"]
+    #[doc = "non-NULL return for a given `urid` will always be the same for the life"]
+    #[doc = "of the plugin.  Plugins that intend to perform string comparison on"]
+    #[doc = "unmapped URIs SHOULD first canonicalise URI strings with a call to"]
+    #[doc = "map_uri() followed by a call to unmap_uri()."]
+    #[doc = ""]
+    #[doc = "@param handle Must be the callback_data member of this struct."]
+    #[doc = "@param urid The ID to be mapped back to the URI string."]
+    pub unmap: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_URID_Unmap_Handle,
+            urid: LV2_URID,
+        ) -> *const ::std::os::raw::c_char,
+    >,
+}
+#[doc = " Handle for LV2_Atom_Forge_Sink."]
+pub type LV2_Atom_Forge_Sink_Handle = *mut ::std::os::raw::c_void;
+#[doc = " A reference to a chunk of written output."]
+pub type LV2_Atom_Forge_Ref = isize;
+#[doc = " Sink function for writing output.  See lv2_atom_forge_set_sink()."]
+pub type LV2_Atom_Forge_Sink = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_Atom_Forge_Sink_Handle,
+        buf: *const ::std::os::raw::c_void,
+        size: u32,
+    ) -> LV2_Atom_Forge_Ref,
+>;
+#[doc = " Function for resolving a reference.  See lv2_atom_forge_set_sink()."]
+pub type LV2_Atom_Forge_Deref_Func = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_Atom_Forge_Sink_Handle,
+        ref_: LV2_Atom_Forge_Ref,
+    ) -> *mut LV2_Atom,
+>;
+#[doc = " A stack frame used for keeping track of nested Atom containers."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Forge_Frame {
+    pub parent: *mut LV2_Atom_Forge_Frame,
+    pub ref_: LV2_Atom_Forge_Ref,
+}
+#[doc = " A \"forge\" for creating atoms by appending to a buffer."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Forge {
+    pub buf: *mut u8,
+    pub offset: u32,
+    pub size: u32,
+    pub sink: LV2_Atom_Forge_Sink,
+    pub deref: LV2_Atom_Forge_Deref_Func,
+    pub handle: LV2_Atom_Forge_Sink_Handle,
+    pub stack: *mut LV2_Atom_Forge_Frame,
+    pub Blank: LV2_URID,
+    pub Bool: LV2_URID,
+    pub Chunk: LV2_URID,
+    pub Double: LV2_URID,
+    pub Float: LV2_URID,
+    pub Int: LV2_URID,
+    pub Long: LV2_URID,
+    pub Literal: LV2_URID,
+    pub Object: LV2_URID,
+    pub Path: LV2_URID,
+    pub Property: LV2_URID,
+    pub Resource: LV2_URID,
+    pub Sequence: LV2_URID,
+    pub String: LV2_URID,
+    pub Tuple: LV2_URID,
+    pub URI: LV2_URID,
+    pub URID: LV2_URID,
+    pub Vector: LV2_URID,
+}
+#[doc = "Plugin Instance Handle."]
+#[doc = ""]
+#[doc = "This is a handle for one particular instance of a plugin.  It is valid to"]
+#[doc = "compare to NULL (or 0 for C++) but otherwise the host MUST NOT attempt to"]
+#[doc = "interpret it."]
+pub type LV2_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Feature."]
+#[doc = ""]
+#[doc = "Features allow hosts to make additional functionality available to plugins"]
+#[doc = "without requiring modification to the LV2 API.  Extensions may define new"]
+#[doc = "features and specify the `URI` and `data` to be used if necessary."]
+#[doc = "Some features, such as lv2:isLive, do not require the host to pass data."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Feature {
+    #[doc = "A globally unique, case-sensitive identifier (URI) for this feature."]
+    #[doc = ""]
+    #[doc = "This MUST be a valid URI string as defined by RFC 3986."]
+    pub URI: *const ::std::os::raw::c_char,
+    #[doc = "Pointer to arbitrary data."]
+    #[doc = ""]
+    #[doc = "The format of this data is defined by the extension which describes the"]
+    #[doc = "feature with the given `URI`."]
+    pub data: *mut ::std::os::raw::c_void,
+}
+#[doc = "Plugin Descriptor."]
+#[doc = ""]
+#[doc = "This structure provides the core functions necessary to instantiate and use"]
+#[doc = "a plugin."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Descriptor {
+    #[doc = "A globally unique, case-sensitive identifier for this plugin."]
+    #[doc = ""]
+    #[doc = "This MUST be a valid URI string as defined by RFC 3986.  All plugins with"]
+    #[doc = "the same URI MUST be compatible to some degree, see"]
+    #[doc = "http://lv2plug.in/ns/lv2core for details."]
+    pub URI: *const ::std::os::raw::c_char,
+    #[doc = "Instantiate the plugin."]
+    #[doc = ""]
+    #[doc = "Note that instance initialisation should generally occur in activate()"]
+    #[doc = "rather than here. If a host calls instantiate(), it MUST call cleanup()"]
+    #[doc = "at some point in the future."]
+    #[doc = ""]
+    #[doc = "@param descriptor Descriptor of the plugin to instantiate."]
+    #[doc = ""]
+    #[doc = "@param sample_rate Sample rate, in Hz, for the new plugin instance."]
+    #[doc = ""]
+    #[doc = "@param bundle_path Path to the LV2 bundle which contains this plugin"]
+    #[doc = "binary. It MUST include the trailing directory separator so that simply"]
+    #[doc = "appending a filename will yield the path to that file in the bundle."]
+    #[doc = ""]
+    #[doc = "@param features A NULL terminated array of LV2_Feature structs which"]
+    #[doc = "represent the features the host supports. Plugins may refuse to"]
+    #[doc = "instantiate if required features are not found here. However, hosts MUST"]
+    #[doc = "NOT use this as a discovery mechanism: instead, use the RDF data to"]
+    #[doc = "determine which features are required and do not attempt to instantiate"]
+    #[doc = "unsupported plugins at all. This parameter MUST NOT be NULL, i.e. a host"]
+    #[doc = "that supports no features MUST pass a single element array containing"]
+    #[doc = "NULL."]
+    #[doc = ""]
+    #[doc = "@return A handle for the new plugin instance, or NULL if instantiation"]
+    #[doc = "has failed."]
+    pub instantiate: ::std::option::Option<
+        unsafe extern "C" fn(
+            descriptor: *const LV2_Descriptor,
+            sample_rate: f64,
+            bundle_path: *const ::std::os::raw::c_char,
+            features: *const *const LV2_Feature,
+        ) -> LV2_Handle,
+    >,
+    #[doc = "Connect a port on a plugin instance to a memory location."]
+    #[doc = ""]
+    #[doc = "Plugin writers should be aware that the host may elect to use the same"]
+    #[doc = "buffer for more than one port and even use the same buffer for both"]
+    #[doc = "input and output (see lv2:inPlaceBroken in lv2.ttl)."]
+    #[doc = ""]
+    #[doc = "If the plugin has the feature lv2:hardRTCapable then there are various"]
+    #[doc = "things that the plugin MUST NOT do within the connect_port() function;"]
+    #[doc = "see lv2core.ttl for details."]
+    #[doc = ""]
+    #[doc = "connect_port() MUST be called at least once for each port before run()"]
+    #[doc = "is called, unless that port is lv2:connectionOptional. The plugin must"]
+    #[doc = "pay careful attention to the block size passed to run() since the block"]
+    #[doc = "allocated may only just be large enough to contain the data, and is not"]
+    #[doc = "guaranteed to remain constant between run() calls."]
+    #[doc = ""]
+    #[doc = "connect_port() may be called more than once for a plugin instance to"]
+    #[doc = "allow the host to change the buffers that the plugin is reading or"]
+    #[doc = "writing. These calls may be made before or after activate() or"]
+    #[doc = "deactivate() calls."]
+    #[doc = ""]
+    #[doc = "@param instance Plugin instance containing the port."]
+    #[doc = ""]
+    #[doc = "@param port Index of the port to connect. The host MUST NOT try to"]
+    #[doc = "connect a port index that is not defined in the plugin's RDF data. If"]
+    #[doc = "it does, the plugin's behaviour is undefined (a crash is likely)."]
+    #[doc = ""]
+    #[doc = "@param data_location Pointer to data of the type defined by the port"]
+    #[doc = "type in the plugin's RDF data (for example, an array of float for an"]
+    #[doc = "lv2:AudioPort). This pointer must be stored by the plugin instance and"]
+    #[doc = "used to read/write data when run() is called. Data present at the time"]
+    #[doc = "of the connect_port() call MUST NOT be considered meaningful."]
+    pub connect_port: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            port: u32,
+            data_location: *mut ::std::os::raw::c_void,
+        ),
+    >,
+    #[doc = "Initialise a plugin instance and activate it for use."]
+    #[doc = ""]
+    #[doc = "This is separated from instantiate() to aid real-time support and so"]
+    #[doc = "that hosts can reinitialise a plugin instance by calling deactivate()"]
+    #[doc = "and then activate(). In this case the plugin instance MUST reset all"]
+    #[doc = "state information dependent on the history of the plugin instance except"]
+    #[doc = "for any data locations provided by connect_port(). If there is nothing"]
+    #[doc = "for activate() to do then this field may be NULL."]
+    #[doc = ""]
+    #[doc = "When present, hosts MUST call this function once before run() is called"]
+    #[doc = "for the first time. This call SHOULD be made as close to the run() call"]
+    #[doc = "as possible and indicates to real-time plugins that they are now live,"]
+    #[doc = "however plugins MUST NOT rely on a prompt call to run() after"]
+    #[doc = "activate()."]
+    #[doc = ""]
+    #[doc = "The host MUST NOT call activate() again until deactivate() has been"]
+    #[doc = "called first. If a host calls activate(), it MUST call deactivate() at"]
+    #[doc = "some point in the future. Note that connect_port() may be called before"]
+    #[doc = "or after activate()."]
+    pub activate: ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle)>,
+    #[doc = "Run a plugin instance for a block."]
+    #[doc = ""]
+    #[doc = "Note that if an activate() function exists then it must be called before"]
+    #[doc = "run(). If deactivate() is called for a plugin instance then run() may"]
+    #[doc = "not be called until activate() has been called again."]
+    #[doc = ""]
+    #[doc = "If the plugin has the feature lv2:hardRTCapable then there are various"]
+    #[doc = "things that the plugin MUST NOT do within the run() function (see"]
+    #[doc = "lv2core.ttl for details)."]
+    #[doc = ""]
+    #[doc = "As a special case, when `sample_count` is 0, the plugin should update"]
+    #[doc = "any output ports that represent a single instant in time (for example,"]
+    #[doc = "control ports, but not audio ports). This is particularly useful for"]
+    #[doc = "latent plugins, which should update their latency output port so hosts"]
+    #[doc = "can pre-roll plugins to compute latency. Plugins MUST NOT crash when"]
+    #[doc = "`sample_count` is 0."]
+    #[doc = ""]
+    #[doc = "@param instance Instance to be run."]
+    #[doc = ""]
+    #[doc = "@param sample_count The block size (in samples) for which the plugin"]
+    #[doc = "instance must run."]
+    pub run: ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle, sample_count: u32)>,
+    #[doc = "Deactivate a plugin instance (counterpart to activate())."]
+    #[doc = ""]
+    #[doc = "Hosts MUST deactivate all activated instances after they have been run()"]
+    #[doc = "for the last time. This call SHOULD be made as close to the last run()"]
+    #[doc = "call as possible and indicates to real-time plugins that they are no"]
+    #[doc = "longer live, however plugins MUST NOT rely on prompt deactivation. If"]
+    #[doc = "there is nothing for deactivate() to do then this field may be NULL"]
+    #[doc = ""]
+    #[doc = "Deactivation is not similar to pausing since the plugin instance will be"]
+    #[doc = "reinitialised by activate(). However, deactivate() itself MUST NOT fully"]
+    #[doc = "reset plugin state. For example, the host may deactivate a plugin, then"]
+    #[doc = "store its state (using some extension to do so)."]
+    #[doc = ""]
+    #[doc = "Hosts MUST NOT call deactivate() unless activate() was previously"]
+    #[doc = "called. Note that connect_port() may be called before or after"]
+    #[doc = "deactivate()."]
+    pub deactivate: ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle)>,
+    #[doc = "Clean up a plugin instance (counterpart to instantiate())."]
+    #[doc = ""]
+    #[doc = "Once an instance of a plugin has been finished with it must be deleted"]
+    #[doc = "using this function. The instance handle passed ceases to be valid after"]
+    #[doc = "this call."]
+    #[doc = ""]
+    #[doc = "If activate() was called for a plugin instance then a corresponding call"]
+    #[doc = "to deactivate() MUST be made before cleanup() is called. Hosts MUST NOT"]
+    #[doc = "call cleanup() unless instantiate() was previously called."]
+    pub cleanup: ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle)>,
+    #[doc = "Return additional plugin data defined by some extenion."]
+    #[doc = ""]
+    #[doc = "A typical use of this facility is to return a struct containing function"]
+    #[doc = "pointers to extend the LV2_Descriptor API."]
+    #[doc = ""]
+    #[doc = "The actual type and meaning of the returned object MUST be specified"]
+    #[doc = "precisely by the extension. This function MUST return NULL for any"]
+    #[doc = "unsupported URI. If a plugin does not support any extension data, this"]
+    #[doc = "field may be NULL."]
+    #[doc = ""]
+    #[doc = "The host is never responsible for freeing the returned value."]
+    pub extension_data: ::std::option::Option<
+        unsafe extern "C" fn(uri: *const ::std::os::raw::c_char) -> *const ::std::os::raw::c_void,
+    >,
+}
+#[doc = "Type of the lv2_descriptor() function in a library (old discovery API)."]
+pub type LV2_Descriptor_Function =
+    ::std::option::Option<unsafe extern "C" fn(index: u32) -> *const LV2_Descriptor>;
+#[doc = "Handle for a library descriptor."]
+pub type LV2_Lib_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Descriptor for a plugin library."]
+#[doc = ""]
+#[doc = "To access a plugin library, the host creates an LV2_Lib_Descriptor via the"]
+#[doc = "lv2_lib_descriptor() function in the shared object."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Lib_Descriptor {
+    #[doc = "Opaque library data which must be passed as the first parameter to all"]
+    #[doc = "the methods of this struct."]
+    pub handle: LV2_Lib_Handle,
+    #[doc = "The total size of this struct.  This allows for this struct to be"]
+    #[doc = "expanded in the future if necessary.  This MUST be set by the library to"]
+    #[doc = "sizeof(LV2_Lib_Descriptor).  The host MUST NOT access any fields of this"]
+    #[doc = "struct beyond get_plugin() unless this field indicates they are present."]
+    pub size: u32,
+    #[doc = "Destroy this library descriptor and free all related resources."]
+    pub cleanup: ::std::option::Option<unsafe extern "C" fn(handle: LV2_Lib_Handle)>,
+    #[doc = "Plugin accessor."]
+    #[doc = ""]
+    #[doc = "Plugins are accessed by index using values from 0 upwards.  Out of range"]
+    #[doc = "indices MUST result in this function returning NULL, so the host can"]
+    #[doc = "enumerate plugins by increasing `index` until NULL is returned."]
+    pub get_plugin: ::std::option::Option<
+        unsafe extern "C" fn(handle: LV2_Lib_Handle, index: u32) -> *const LV2_Descriptor,
+    >,
+}
+#[doc = "Type of the lv2_lib_descriptor() function in an LV2 library."]
+pub type LV2_Lib_Descriptor_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        bundle_path: *const ::std::os::raw::c_char,
+        features: *const *const LV2_Feature,
+    ) -> *const LV2_Lib_Descriptor,
+>;
+#[doc = "The data field of the LV2_Feature for this extension."]
+#[doc = ""]
+#[doc = "To support this feature the host must pass an LV2_Feature struct to the"]
+#[doc = "instantiate method with URI \"http://lv2plug.in/ns/ext/data-access\""]
+#[doc = "and data pointed to an instance of this struct."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Extension_Data_Feature {
+    #[doc = "A pointer to a method the UI can call to get data (of a type specified"]
+    #[doc = "by some other extension) from the plugin."]
+    #[doc = ""]
+    #[doc = "This call never is never guaranteed to return anything, UIs should"]
+    #[doc = "degrade gracefully if direct access to the plugin data is not possible"]
+    #[doc = "(in which case this function will return NULL)."]
+    #[doc = ""]
+    #[doc = "This is for access to large data that can only possibly work if the UI"]
+    #[doc = "and plugin are running in the same process.  For all other things, use"]
+    #[doc = "the normal LV2 UI communication system."]
+    pub data_access: ::std::option::Option<
+        unsafe extern "C" fn(uri: *const ::std::os::raw::c_char) -> *const ::std::os::raw::c_void,
+    >,
+}
+#[doc = "Dynamic manifest generator handle."]
+#[doc = ""]
+#[doc = "This handle indicates a particular status of a dynamic manifest generator."]
+#[doc = "The host MUST NOT attempt to interpret it and, unlikely LV2_Handle, it is"]
+#[doc = "NOT even valid to compare this to NULL. The dynamic manifest generator MAY"]
+#[doc = "use it to reference internal data."]
+pub type LV2_Dyn_Manifest_Handle = *mut ::std::os::raw::c_void;
+pub const LV2_EVENT_PPQN: u32 = 3136573440;
+#[doc = "An LV2 event (header only)."]
+#[doc = ""]
+#[doc = "LV2 events are generic time-stamped containers for any type of event."]
+#[doc = "The type field defines the format of a given event's contents."]
+#[doc = ""]
+#[doc = "This struct defines the header of an LV2 event. An LV2 event is a single"]
+#[doc = "chunk of POD (plain old data), usually contained in a flat buffer (see"]
+#[doc = "LV2_EventBuffer below). Unless a required feature says otherwise, hosts may"]
+#[doc = "assume a deep copy of an LV2 event can be created safely using a simple:"]
+#[doc = ""]
+#[doc = "memcpy(ev_copy, ev, sizeof(LV2_Event) + ev->size);  (or equivalent)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Event {
+    #[doc = "The frames portion of timestamp. The units used here can optionally be"]
+    #[doc = "set for a port (with the lv2ev:timeUnits property), otherwise this is"]
+    #[doc = "audio frames, corresponding to the sample_count parameter of the LV2 run"]
+    #[doc = "method (frame 0 is the first frame for that call to run)."]
+    pub frames: u32,
+    #[doc = "The sub-frames portion of timestamp. The units used here can optionally"]
+    #[doc = "be set for a port (with the lv2ev:timeUnits property), otherwise this is"]
+    #[doc = "1/(2^32) of an audio frame."]
+    pub subframes: u32,
+    #[doc = "The type of this event, as a number which represents some URI"]
+    #[doc = "defining an event type. This value MUST be some value previously"]
+    #[doc = "returned from a call to the uri_to_id function defined in the LV2"]
+    #[doc = "URI map extension (see lv2_uri_map.h)."]
+    #[doc = "There are special rules which must be followed depending on the type"]
+    #[doc = "of an event. If the plugin recognizes an event type, the definition"]
+    #[doc = "of that event type will describe how to interpret the event, and"]
+    #[doc = "any required behaviour. Otherwise, if the type is 0, this event is a"]
+    #[doc = "non-POD event and lv2_event_unref MUST be called if the event is"]
+    #[doc = "'dropped' (see above). Even if the plugin does not understand an event,"]
+    #[doc = "it may pass the event through to an output by simply copying (and NOT"]
+    #[doc = "calling lv2_event_unref). These rules are designed to allow for generic"]
+    #[doc = "event handling plugins and large non-POD events, but with minimal hassle"]
+    #[doc = "on simple plugins that \"don't care\" about these more advanced features."]
+    pub type_: u16,
+    #[doc = "The size of the data portion of this event in bytes, which immediately"]
+    #[doc = "follows. The header size (12 bytes) is not included in this value."]
+    pub size: u16,
+}
+#[doc = "A buffer of LV2 events (header only)."]
+#[doc = ""]
+#[doc = "Like events (which this contains) an event buffer is a single chunk of POD:"]
+#[doc = "the entire buffer (including contents) can be copied with a single memcpy."]
+#[doc = "The first contained event begins sizeof(LV2_EventBuffer) bytes after the"]
+#[doc = "start of this struct."]
+#[doc = ""]
+#[doc = "After this header, the buffer contains an event header (defined by struct"]
+#[doc = "LV2_Event), followed by that event's contents (padded to 64 bits), followed"]
+#[doc = "by another header, etc:"]
+#[doc = ""]
+#[doc = "|       |       |       |       |       |       |"]
+#[doc = "| | | | | | | | | | | | | | | | | | | | | | | | |"]
+#[doc = "|FRAMES |SUBFRMS|TYP|LEN|DATA..DATA..PAD|FRAMES | ..."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Event_Buffer {
+    #[doc = "The contents of the event buffer. This may or may not reside in the"]
+    #[doc = "same block of memory as this header, plugins must not assume either."]
+    #[doc = "The host guarantees this points to at least capacity bytes of allocated"]
+    #[doc = "memory (though only size bytes of that are valid events)."]
+    pub data: *mut u8,
+    #[doc = "The size of this event header in bytes (including everything)."]
+    #[doc = ""]
+    #[doc = "This is to allow for extending this header in the future without"]
+    #[doc = "breaking binary compatibility. Whenever this header is copied,"]
+    #[doc = "it MUST be done using this field (and NOT the sizeof this struct)."]
+    pub header_size: u16,
+    #[doc = "The type of the time stamps for events in this buffer."]
+    #[doc = "As a special exception, '0' always means audio frames and subframes"]
+    #[doc = "(1/UINT32_MAX'th of a frame) in the sample rate passed to instantiate."]
+    #[doc = ""]
+    #[doc = "INPUTS: The host must set this field to the numeric ID of some URI"]
+    #[doc = "defining the meaning of the frames/subframes fields of contained events"]
+    #[doc = "(obtained by the LV2 URI Map uri_to_id function with the URI of this"]
+    #[doc = "extension as the 'map' argument, see lv2_uri_map.h).  The host must"]
+    #[doc = "never pass a plugin a buffer which uses a stamp type the plugin does not"]
+    #[doc = "'understand'. The value of this field must never change, except when"]
+    #[doc = "connect_port is called on the input port, at which time the host MUST"]
+    #[doc = "have set the stamp_type field to the value that will be used for all"]
+    #[doc = "subsequent run calls."]
+    #[doc = ""]
+    #[doc = "OUTPUTS: The plugin may set this to any value that has been returned"]
+    #[doc = "from uri_to_id with the URI of this extension for a 'map' argument."]
+    #[doc = "When connected to a buffer with connect_port, output ports MUST set this"]
+    #[doc = "field to the type of time stamp they will be writing. On any call to"]
+    #[doc = "connect_port on an event input port, the plugin may change this field on"]
+    #[doc = "any output port, it is the responsibility of the host to check if any of"]
+    #[doc = "these values have changed and act accordingly."]
+    pub stamp_type: u16,
+    #[doc = "The number of events in this buffer."]
+    #[doc = ""]
+    #[doc = "INPUTS: The host must set this field to the number of events contained"]
+    #[doc = "in the data buffer before calling run(). The plugin must not change"]
+    #[doc = "this field."]
+    #[doc = ""]
+    #[doc = "OUTPUTS: The plugin must set this field to the number of events it has"]
+    #[doc = "written to the buffer before returning from run(). Any initial value"]
+    #[doc = "should be ignored by the plugin."]
+    pub event_count: u32,
+    #[doc = "The size of the data buffer in bytes."]
+    #[doc = "This is set by the host and must not be changed by the plugin."]
+    #[doc = "The host is allowed to change this between run() calls."]
+    pub capacity: u32,
+    #[doc = "The size of the initial portion of the data buffer containing data."]
+    #[doc = ""]
+    #[doc = "INPUTS: The host must set this field to the number of bytes used"]
+    #[doc = "by all events it has written to the buffer (including headers)"]
+    #[doc = "before calling the plugin's run()."]
+    #[doc = "The plugin must not change this field."]
+    #[doc = ""]
+    #[doc = "OUTPUTS: The plugin must set this field to the number of bytes"]
+    #[doc = "used by all events it has written to the buffer (including headers)"]
+    #[doc = "before returning from run()."]
+    #[doc = "Any initial value should be ignored by the plugin."]
+    pub size: u32,
+}
+#[doc = "Opaque pointer to host data."]
+pub type LV2_Event_Callback_Data = *mut ::std::os::raw::c_void;
+#[doc = "Non-POD events feature."]
+#[doc = ""]
+#[doc = "To support this feature the host must pass an LV2_Feature struct to the"]
+#[doc = "plugin's instantiate method with URI \"http://lv2plug.in/ns/ext/event\""]
+#[doc = "and data pointed to an instance of this struct.  Note this feature"]
+#[doc = "is not mandatory to support the event extension."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Event_Feature {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "The plugin MUST pass this to any call to functions in this struct."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub callback_data: LV2_Event_Callback_Data,
+    #[doc = "Take a reference to a non-POD event."]
+    #[doc = ""]
+    #[doc = "If a plugin receives an event with type 0, it means the event is a"]
+    #[doc = "pointer to some object in memory and not a flat sequence of bytes"]
+    #[doc = "in the buffer. When receiving a non-POD event, the plugin already"]
+    #[doc = "has an implicit reference to the event. If the event is stored AND"]
+    #[doc = "passed to an output, lv2_event_ref MUST be called on that event."]
+    #[doc = "If the event is only stored OR passed through, this is not necessary"]
+    #[doc = "(as the plugin already has 1 implicit reference)."]
+    #[doc = ""]
+    #[doc = "@param event An event received at an input that will not be copied to"]
+    #[doc = "an output or stored in any way."]
+    #[doc = ""]
+    #[doc = "@param context The calling context. Like event types, this is a mapped"]
+    #[doc = "URI, see lv2_context.h. Simple plugin with just a run() method should"]
+    #[doc = "pass 0 here (the ID of the 'standard' LV2 run context). The host"]
+    #[doc = "guarantees that this function is realtime safe iff the context is"]
+    #[doc = "realtime safe."]
+    #[doc = ""]
+    #[doc = "PLUGINS THAT VIOLATE THESE RULES MAY CAUSE CRASHES AND MEMORY LEAKS."]
+    pub lv2_event_ref: ::std::option::Option<
+        unsafe extern "C" fn(callback_data: LV2_Event_Callback_Data, event: *mut LV2_Event) -> u32,
+    >,
+    #[doc = "Drop a reference to a non-POD event."]
+    #[doc = ""]
+    #[doc = "If a plugin receives an event with type 0, it means the event is a"]
+    #[doc = "pointer to some object in memory and not a flat sequence of bytes"]
+    #[doc = "in the buffer. If the plugin does not pass the event through to"]
+    #[doc = "an output or store it internally somehow, it MUST call this function"]
+    #[doc = "on the event (more information on using non-POD events below)."]
+    #[doc = ""]
+    #[doc = "@param event An event received at an input that will not be copied to an"]
+    #[doc = "output or stored in any way."]
+    #[doc = ""]
+    #[doc = "@param context The calling context. Like event types, this is a mapped"]
+    #[doc = "URI, see lv2_context.h. Simple plugin with just a run() method should"]
+    #[doc = "pass 0 here (the ID of the 'standard' LV2 run context). The host"]
+    #[doc = "guarantees that this function is realtime safe iff the context is"]
+    #[doc = "realtime safe."]
+    #[doc = ""]
+    #[doc = "PLUGINS THAT VIOLATE THESE RULES MAY CAUSE CRASHES AND MEMORY LEAKS."]
+    pub lv2_event_unref: ::std::option::Option<
+        unsafe extern "C" fn(callback_data: LV2_Event_Callback_Data, event: *mut LV2_Event) -> u32,
+    >,
+}
+#[doc = " An iterator over an LV2_Event_Buffer."]
+#[doc = ""]
+#[doc = " Multiple simultaneous read iterators over a single buffer is fine,"]
+#[doc = " but changing the buffer invalidates all iterators."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Event_Iterator {
+    pub buf: *mut LV2_Event_Buffer,
+    pub offset: u32,
+}
+#[doc = "Opaque data to host data for LV2_Log_Log."]
+pub type LV2_Log_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Log feature (LV2_LOG__log)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Log_Log {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "This MUST be passed to methods in this struct whenever they are called."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub handle: LV2_Log_Handle,
+    #[doc = "Log a message, passing format parameters directly."]
+    #[doc = ""]
+    #[doc = "The API of this function matches that of the standard C printf function,"]
+    #[doc = "except for the addition of the first two parameters.  This function may"]
+    #[doc = "be called from any non-realtime context, or from any context if `type`"]
+    #[doc = "is @ref LV2_LOG__Trace."]
+    pub printf: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_Log_Handle,
+            type_: LV2_URID,
+            fmt: *const ::std::os::raw::c_char,
+            ...
+        ) -> ::std::os::raw::c_int,
+    >,
+    #[doc = "Log a message, passing format parameters in a va_list."]
+    #[doc = ""]
+    #[doc = "The API of this function matches that of the standard C vprintf"]
+    #[doc = "function, except for the addition of the first two parameters.  This"]
+    #[doc = "function may be called from any non-realtime context, or from any"]
+    #[doc = "context if `type` is @ref LV2_LOG__Trace."]
+    pub vprintf: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_Log_Handle,
+            type_: LV2_URID,
+            fmt: *const ::std::os::raw::c_char,
+            ap: va_list,
+        ) -> ::std::os::raw::c_int,
+    >,
+}
+#[doc = "Logger convenience API state."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Log_Logger {
+    pub log: *mut LV2_Log_Log,
+    pub Error: LV2_URID,
+    pub Note: LV2_URID,
+    pub Trace: LV2_URID,
+    pub Warning: LV2_URID,
+}
+#[doc = "< Invalid Message"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_INVALID: LV2_Midi_Message_Type = 0;
+#[doc = "< Note Off"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_NOTE_OFF: LV2_Midi_Message_Type = 128;
+#[doc = "< Note On"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_NOTE_ON: LV2_Midi_Message_Type = 144;
+#[doc = "< Note Pressure"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_NOTE_PRESSURE: LV2_Midi_Message_Type = 160;
+#[doc = "< Controller"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_CONTROLLER: LV2_Midi_Message_Type = 176;
+#[doc = "< Program Change"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_PGM_CHANGE: LV2_Midi_Message_Type = 192;
+#[doc = "< Channel Pressure"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_CHANNEL_PRESSURE: LV2_Midi_Message_Type = 208;
+#[doc = "< Pitch Bender"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_BENDER: LV2_Midi_Message_Type = 224;
+#[doc = "< System Exclusive Begin"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_SYSTEM_EXCLUSIVE: LV2_Midi_Message_Type = 240;
+#[doc = "< MTC Quarter Frame"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_MTC_QUARTER: LV2_Midi_Message_Type = 241;
+#[doc = "< Song Position"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_SONG_POS: LV2_Midi_Message_Type = 242;
+#[doc = "< Song Select"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_SONG_SELECT: LV2_Midi_Message_Type = 243;
+#[doc = "< Tune Request"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_TUNE_REQUEST: LV2_Midi_Message_Type = 246;
+#[doc = "< Clock"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_CLOCK: LV2_Midi_Message_Type = 248;
+#[doc = "< Start"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_START: LV2_Midi_Message_Type = 250;
+#[doc = "< Continue"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_CONTINUE: LV2_Midi_Message_Type = 251;
+#[doc = "< Stop"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_STOP: LV2_Midi_Message_Type = 252;
+#[doc = "< Active Sensing"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_ACTIVE_SENSE: LV2_Midi_Message_Type = 254;
+#[doc = "< Reset"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_RESET: LV2_Midi_Message_Type = 255;
+#[doc = "MIDI Message Type."]
+#[doc = ""]
+#[doc = "This includes both voice messages (which have a channel) and system messages"]
+#[doc = "(which do not), as well as a sentinel value for invalid messages.  To get"]
+#[doc = "the type of a message suitable for use in a switch statement, use"]
+#[doc = "lv2_midi_get_type() on the status byte."]
+pub type LV2_Midi_Message_Type = u32;
+#[doc = "< Bank Selection"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_BANK: LV2_Midi_Controller = 0;
+#[doc = "< Modulation"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_MODWHEEL: LV2_Midi_Controller = 1;
+#[doc = "< Breath"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_BREATH: LV2_Midi_Controller = 2;
+#[doc = "< Foot"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_FOOT: LV2_Midi_Controller = 4;
+#[doc = "< Portamento Time"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_PORTAMENTO_TIME: LV2_Midi_Controller = 5;
+#[doc = "< Data Entry"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_DATA_ENTRY: LV2_Midi_Controller = 6;
+#[doc = "< Main Volume"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_MAIN_VOLUME: LV2_Midi_Controller = 7;
+#[doc = "< Balance"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_BALANCE: LV2_Midi_Controller = 8;
+#[doc = "< Panpot"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_PAN: LV2_Midi_Controller = 10;
+#[doc = "< Expression"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_EXPRESSION: LV2_Midi_Controller = 11;
+#[doc = "< Effect1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_EFFECT1: LV2_Midi_Controller = 12;
+#[doc = "< Effect2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_EFFECT2: LV2_Midi_Controller = 13;
+#[doc = "< General Purpose 1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_GENERAL_PURPOSE1: LV2_Midi_Controller = 16;
+#[doc = "< General Purpose 2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_GENERAL_PURPOSE2: LV2_Midi_Controller = 17;
+#[doc = "< General Purpose 3"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_GENERAL_PURPOSE3: LV2_Midi_Controller = 18;
+#[doc = "< General Purpose 4"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_GENERAL_PURPOSE4: LV2_Midi_Controller = 19;
+#[doc = "< Bank Selection"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_BANK: LV2_Midi_Controller = 32;
+#[doc = "< Modulation"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_MODWHEEL: LV2_Midi_Controller = 33;
+#[doc = "< Breath"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_BREATH: LV2_Midi_Controller = 34;
+#[doc = "< Foot"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_FOOT: LV2_Midi_Controller = 36;
+#[doc = "< Portamento Time"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_PORTAMENTO_TIME: LV2_Midi_Controller = 37;
+#[doc = "< Data Entry"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_DATA_ENTRY: LV2_Midi_Controller = 38;
+#[doc = "< Main Volume"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_MAIN_VOLUME: LV2_Midi_Controller = 39;
+#[doc = "< Balance"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_BALANCE: LV2_Midi_Controller = 40;
+#[doc = "< Panpot"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_PAN: LV2_Midi_Controller = 42;
+#[doc = "< Expression"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_EXPRESSION: LV2_Midi_Controller = 43;
+#[doc = "< Effect1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_EFFECT1: LV2_Midi_Controller = 44;
+#[doc = "< Effect2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_EFFECT2: LV2_Midi_Controller = 45;
+#[doc = "< General Purpose 1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_GENERAL_PURPOSE1: LV2_Midi_Controller = 48;
+#[doc = "< General Purpose 2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_GENERAL_PURPOSE2: LV2_Midi_Controller = 49;
+#[doc = "< General Purpose 3"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_GENERAL_PURPOSE3: LV2_Midi_Controller = 50;
+#[doc = "< General Purpose 4"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_GENERAL_PURPOSE4: LV2_Midi_Controller = 51;
+#[doc = "< Sustain Pedal"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SUSTAIN: LV2_Midi_Controller = 64;
+#[doc = "< Portamento"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_PORTAMENTO: LV2_Midi_Controller = 65;
+#[doc = "< Sostenuto"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SOSTENUTO: LV2_Midi_Controller = 66;
+#[doc = "< Soft Pedal"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SOFT_PEDAL: LV2_Midi_Controller = 67;
+#[doc = "< Legato Foot Switch"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LEGATO_FOOTSWITCH: LV2_Midi_Controller = 68;
+#[doc = "< Hold2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_HOLD2: LV2_Midi_Controller = 69;
+#[doc = "< SC1 Sound Variation"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC1_SOUND_VARIATION: LV2_Midi_Controller = 70;
+#[doc = "< SC2 Timbre"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC2_TIMBRE: LV2_Midi_Controller = 71;
+#[doc = "< SC3 Release Time"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC3_RELEASE_TIME: LV2_Midi_Controller = 72;
+#[doc = "< SC4 Attack Time"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC4_ATTACK_TIME: LV2_Midi_Controller = 73;
+#[doc = "< SC5 Brightness"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC5_BRIGHTNESS: LV2_Midi_Controller = 74;
+#[doc = "< SC6"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC6: LV2_Midi_Controller = 75;
+#[doc = "< SC7"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC7: LV2_Midi_Controller = 76;
+#[doc = "< SC8"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC8: LV2_Midi_Controller = 77;
+#[doc = "< SC9"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC9: LV2_Midi_Controller = 78;
+#[doc = "< SC10"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC10: LV2_Midi_Controller = 79;
+#[doc = "< General Purpose 5"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_GENERAL_PURPOSE5: LV2_Midi_Controller = 80;
+#[doc = "< General Purpose 6"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_GENERAL_PURPOSE6: LV2_Midi_Controller = 81;
+#[doc = "< General Purpose 7"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_GENERAL_PURPOSE7: LV2_Midi_Controller = 82;
+#[doc = "< General Purpose 8"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_GENERAL_PURPOSE8: LV2_Midi_Controller = 83;
+#[doc = "< Portamento Control"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_PORTAMENTO_CONTROL: LV2_Midi_Controller = 84;
+#[doc = "< E1 Reverb Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E1_REVERB_DEPTH: LV2_Midi_Controller = 91;
+#[doc = "< E2 Tremolo Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E2_TREMOLO_DEPTH: LV2_Midi_Controller = 92;
+#[doc = "< E3 Chorus Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E3_CHORUS_DEPTH: LV2_Midi_Controller = 93;
+#[doc = "< E4 Detune Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E4_DETUNE_DEPTH: LV2_Midi_Controller = 94;
+#[doc = "< E5 Phaser Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E5_PHASER_DEPTH: LV2_Midi_Controller = 95;
+#[doc = "< Data Increment"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_DATA_INCREMENT: LV2_Midi_Controller = 96;
+#[doc = "< Data Decrement"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_DATA_DECREMENT: LV2_Midi_Controller = 97;
+#[doc = "< Non-registered Parameter Number"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_NRPN_LSB: LV2_Midi_Controller = 98;
+#[doc = "< Non-registered Parameter Number"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_NRPN_MSB: LV2_Midi_Controller = 99;
+#[doc = "< Registered Parameter Number"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_RPN_LSB: LV2_Midi_Controller = 100;
+#[doc = "< Registered Parameter Number"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_RPN_MSB: LV2_Midi_Controller = 101;
+#[doc = "< All Sounds Off"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_ALL_SOUNDS_OFF: LV2_Midi_Controller = 120;
+#[doc = "< Reset Controllers"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_RESET_CONTROLLERS: LV2_Midi_Controller = 121;
+#[doc = "< Local Control Switch"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LOCAL_CONTROL_SWITCH: LV2_Midi_Controller = 122;
+#[doc = "< All Notes Off"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_ALL_NOTES_OFF: LV2_Midi_Controller = 123;
+#[doc = "< Omni Off"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_OMNI_OFF: LV2_Midi_Controller = 124;
+#[doc = "< Omni On"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_OMNI_ON: LV2_Midi_Controller = 125;
+#[doc = "< Mono1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MONO1: LV2_Midi_Controller = 126;
+#[doc = "< Mono2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MONO2: LV2_Midi_Controller = 127;
+#[doc = "Standard MIDI Controller Numbers."]
+pub type LV2_Midi_Controller = u32;
+#[doc = "This option applies to the instance itself.  The subject must be"]
+#[doc = "ignored."]
+pub const LV2_Options_Context_LV2_OPTIONS_INSTANCE: LV2_Options_Context = 0;
+#[doc = "This option applies to some named resource.  The subject is a URI mapped"]
+#[doc = "to an integer (a LV2_URID, like the key)"]
+pub const LV2_Options_Context_LV2_OPTIONS_RESOURCE: LV2_Options_Context = 1;
+#[doc = "This option applies to some blank node.  The subject is a blank node"]
+#[doc = "identifier, which is valid only within the current local scope."]
+pub const LV2_Options_Context_LV2_OPTIONS_BLANK: LV2_Options_Context = 2;
+#[doc = "This option applies to a port on the instance.  The subject is the"]
+#[doc = "port's index."]
+pub const LV2_Options_Context_LV2_OPTIONS_PORT: LV2_Options_Context = 3;
+#[doc = "The context of an Option, which defines the subject it applies to."]
+pub type LV2_Options_Context = u32;
+#[doc = "An option."]
+#[doc = ""]
+#[doc = "This is a property with a subject, also known as a triple or statement."]
+#[doc = ""]
+#[doc = "This struct is useful anywhere a statement needs to be passed where no"]
+#[doc = "memory ownership issues are present (since the value is a const pointer)."]
+#[doc = ""]
+#[doc = "Options can be passed to an instance via the feature LV2_OPTIONS__options"]
+#[doc = "with data pointed to an array of options terminated by a zeroed option, or"]
+#[doc = "accessed/manipulated using LV2_Options_Interface."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Options_Option {
+    #[doc = "< Context (type of subject)."]
+    pub context: LV2_Options_Context,
+    #[doc = "< Subject."]
+    pub subject: u32,
+    #[doc = "< Key (property)."]
+    pub key: LV2_URID,
+    #[doc = "< Size of value in bytes."]
+    pub size: u32,
+    #[doc = "< Type of value (datatype)."]
+    pub type_: LV2_URID,
+    #[doc = "< Pointer to value (object)."]
+    pub value: *const ::std::os::raw::c_void,
+}
+#[doc = "< Completed successfully."]
+pub const LV2_Options_Status_LV2_OPTIONS_SUCCESS: LV2_Options_Status = 0;
+#[doc = "< Unknown error."]
+pub const LV2_Options_Status_LV2_OPTIONS_ERR_UNKNOWN: LV2_Options_Status = 1;
+#[doc = "< Invalid/unsupported subject."]
+pub const LV2_Options_Status_LV2_OPTIONS_ERR_BAD_SUBJECT: LV2_Options_Status = 2;
+#[doc = "< Invalid/unsupported key."]
+pub const LV2_Options_Status_LV2_OPTIONS_ERR_BAD_KEY: LV2_Options_Status = 4;
+#[doc = "< Invalid/unsupported value."]
+pub const LV2_Options_Status_LV2_OPTIONS_ERR_BAD_VALUE: LV2_Options_Status = 8;
+#[doc = " A status code for option functions."]
+pub type LV2_Options_Status = u32;
+#[doc = "Interface for dynamically setting options (LV2_OPTIONS__interface)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Options_Interface {
+    #[doc = "Get the given options."]
+    #[doc = ""]
+    #[doc = "Each element of the passed options array MUST have type, subject, and"]
+    #[doc = "key set.  All other fields (size, type, value) MUST be initialised to"]
+    #[doc = "zero, and are set to the option value if such an option is found."]
+    #[doc = ""]
+    #[doc = "This function is in the \"instantiation\" LV2 threading class, so no other"]
+    #[doc = "instance functions may be called concurrently."]
+    #[doc = ""]
+    #[doc = "@return Bitwise OR of LV2_Options_Status values."]
+    pub get: ::std::option::Option<
+        unsafe extern "C" fn(instance: LV2_Handle, options: *mut LV2_Options_Option) -> u32,
+    >,
+    #[doc = "Set the given options."]
+    #[doc = ""]
+    #[doc = "This function is in the \"instantiation\" LV2 threading class, so no other"]
+    #[doc = "instance functions may be called concurrently."]
+    #[doc = ""]
+    #[doc = "@return Bitwise OR of LV2_Options_Status values."]
+    pub set: ::std::option::Option<
+        unsafe extern "C" fn(instance: LV2_Handle, options: *const LV2_Options_Option) -> u32,
+    >,
+}
+#[doc = "< Completed successfully."]
+pub const LV2_Resize_Port_Status_LV2_RESIZE_PORT_SUCCESS: LV2_Resize_Port_Status = 0;
+#[doc = "< Unknown error."]
+pub const LV2_Resize_Port_Status_LV2_RESIZE_PORT_ERR_UNKNOWN: LV2_Resize_Port_Status = 1;
+#[doc = "< Insufficient space."]
+pub const LV2_Resize_Port_Status_LV2_RESIZE_PORT_ERR_NO_SPACE: LV2_Resize_Port_Status = 2;
+#[doc = " A status code for state functions."]
+pub type LV2_Resize_Port_Status = u32;
+#[doc = " Opaque data for resize method."]
+pub type LV2_Resize_Port_Feature_Data = *mut ::std::os::raw::c_void;
+#[doc = " Host feature to allow plugins to resize their port buffers."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Resize_Port_Resize {
+    #[doc = " Opaque data for resize method."]
+    pub data: LV2_Resize_Port_Feature_Data,
+    #[doc = "Resize a port buffer to at least `size` bytes."]
+    #[doc = ""]
+    #[doc = "This function MAY return an error, in which case the port buffer was not"]
+    #[doc = "resized and the port is still connected to the same location.  Plugins"]
+    #[doc = "MUST gracefully handle this situation."]
+    #[doc = ""]
+    #[doc = "This function is in the audio threading class."]
+    #[doc = ""]
+    #[doc = "The host MUST preserve the contents of the port buffer when resizing."]
+    #[doc = ""]
+    #[doc = "Plugins MAY resize a port many times in a single run callback.  Hosts"]
+    #[doc = "SHOULD make this as inexpensive as possible."]
+    pub resize: ::std::option::Option<
+        unsafe extern "C" fn(
+            data: LV2_Resize_Port_Feature_Data,
+            index: u32,
+            size: usize,
+        ) -> LV2_Resize_Port_Status,
+    >,
+}
+pub type LV2_State_Handle = *mut ::std::os::raw::c_void;
+pub type LV2_State_Free_Path_Handle = *mut ::std::os::raw::c_void;
+pub type LV2_State_Map_Path_Handle = *mut ::std::os::raw::c_void;
+pub type LV2_State_Make_Path_Handle = *mut ::std::os::raw::c_void;
+impl LV2_State_Flags {
+    #[doc = "Plain Old Data."]
+    #[doc = ""]
+    #[doc = "Values with this flag contain no pointers or references to other areas"]
+    #[doc = "of memory.  It is safe to copy POD values with a simple memcpy and store"]
+    #[doc = "them for the duration of the process.  A POD value is not necessarily"]
+    #[doc = "safe to trasmit between processes or machines (for example, filenames"]
+    #[doc = "are POD), see LV2_STATE_IS_PORTABLE for details."]
+    #[doc = ""]
+    #[doc = "Implementations MUST NOT attempt to copy or serialise a non-POD value if"]
+    #[doc = "they do not understand its type (and thus know how to correctly do so)."]
+    pub const LV2_STATE_IS_POD: LV2_State_Flags = LV2_State_Flags(1);
+}
+impl LV2_State_Flags {
+    #[doc = "Portable (architecture independent) data."]
+    #[doc = ""]
+    #[doc = "Values with this flag are in a format that is usable on any"]
+    #[doc = "architecture.  A portable value saved on one machine can be restored on"]
+    #[doc = "another machine regardless of architecture.  The format of portable"]
+    #[doc = "values MUST NOT depend on architecture-specific properties like"]
+    #[doc = "endianness or alignment.  Portable values MUST NOT contain filenames."]
+    pub const LV2_STATE_IS_PORTABLE: LV2_State_Flags = LV2_State_Flags(2);
+}
+impl LV2_State_Flags {
+    #[doc = "Native data."]
+    #[doc = ""]
+    #[doc = "This flag is used by the host to indicate that the saved data is only"]
+    #[doc = "going to be used locally in the currently running process (for things"]
+    #[doc = "like instance duplication or snapshots), so the plugin should use the"]
+    #[doc = "most efficient representation possible and not worry about serialisation"]
+    #[doc = "and portability."]
+    pub const LV2_STATE_IS_NATIVE: LV2_State_Flags = LV2_State_Flags(4);
+}
+impl ::std::ops::BitOr<LV2_State_Flags> for LV2_State_Flags {
+    type Output = Self;
+    #[inline]
+    fn bitor(self, other: Self) -> Self {
+        LV2_State_Flags(self.0 | other.0)
+    }
+}
+impl ::std::ops::BitOrAssign for LV2_State_Flags {
+    #[inline]
+    fn bitor_assign(&mut self, rhs: LV2_State_Flags) {
+        self.0 |= rhs.0;
+    }
+}
+impl ::std::ops::BitAnd<LV2_State_Flags> for LV2_State_Flags {
+    type Output = Self;
+    #[inline]
+    fn bitand(self, other: Self) -> Self {
+        LV2_State_Flags(self.0 & other.0)
+    }
+}
+impl ::std::ops::BitAndAssign for LV2_State_Flags {
+    #[inline]
+    fn bitand_assign(&mut self, rhs: LV2_State_Flags) {
+        self.0 &= rhs.0;
+    }
+}
+#[repr(transparent)]
+#[doc = "Flags describing value characteristics."]
+#[doc = ""]
+#[doc = "These flags are used along with the value's type URI to determine how to"]
+#[doc = "(de-)serialise the value data, or whether it is even possible to do so."]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct LV2_State_Flags(pub u32);
+#[doc = "< Completed successfully."]
+pub const LV2_State_Status_LV2_STATE_SUCCESS: LV2_State_Status = 0;
+#[doc = "< Unknown error."]
+pub const LV2_State_Status_LV2_STATE_ERR_UNKNOWN: LV2_State_Status = 1;
+#[doc = "< Failed due to unsupported type."]
+pub const LV2_State_Status_LV2_STATE_ERR_BAD_TYPE: LV2_State_Status = 2;
+#[doc = "< Failed due to unsupported flags."]
+pub const LV2_State_Status_LV2_STATE_ERR_BAD_FLAGS: LV2_State_Status = 3;
+#[doc = "< Failed due to missing features."]
+pub const LV2_State_Status_LV2_STATE_ERR_NO_FEATURE: LV2_State_Status = 4;
+#[doc = "< Failed due to missing property."]
+pub const LV2_State_Status_LV2_STATE_ERR_NO_PROPERTY: LV2_State_Status = 5;
+#[doc = "< Failed due to insufficient space."]
+pub const LV2_State_Status_LV2_STATE_ERR_NO_SPACE: LV2_State_Status = 6;
+#[doc = " A status code for state functions."]
+pub type LV2_State_Status = u32;
+#[doc = "A host-provided function to store a property."]
+#[doc = "@param handle Must be the handle passed to LV2_State_Interface.save()."]
+#[doc = "@param key The key to store `value` under (URID)."]
+#[doc = "@param value Pointer to the value to be stored."]
+#[doc = "@param size The size of `value` in bytes."]
+#[doc = "@param type The type of `value` (URID)."]
+#[doc = "@param flags LV2_State_Flags for `value`."]
+#[doc = "@return 0 on success, otherwise a non-zero error code."]
+#[doc = ""]
+#[doc = "The host passes a callback of this type to LV2_State_Interface.save(). This"]
+#[doc = "callback is called repeatedly by the plugin to store all the properties that"]
+#[doc = "describe its current state."]
+#[doc = ""]
+#[doc = "DO NOT INVENT NONSENSE URI SCHEMES FOR THE KEY.  Best is to use keys from"]
+#[doc = "existing vocabularies.  If nothing appropriate is available, use http URIs"]
+#[doc = "that point to somewhere you can host documents so documentation can be made"]
+#[doc = "resolvable (typically a child of the plugin or project URI).  If this is not"]
+#[doc = "possible, invent a URN scheme, e.g. urn:myproj:whatever.  The plugin MUST"]
+#[doc = "NOT pass an invalid URI key."]
+#[doc = ""]
+#[doc = "The host MAY fail to store a property for whatever reason, but SHOULD"]
+#[doc = "store any property that is LV2_STATE_IS_POD and LV2_STATE_IS_PORTABLE."]
+#[doc = "Implementations SHOULD use the types from the LV2 Atom extension"]
+#[doc = "(http://lv2plug.in/ns/ext/atom) wherever possible.  The plugin SHOULD"]
+#[doc = "attempt to fall-back and avoid the error if possible."]
+#[doc = ""]
+#[doc = "Note that `size` MUST be > 0, and `value` MUST point to a valid region of"]
+#[doc = "memory `size` bytes long (this is required to make restore unambiguous)."]
+#[doc = ""]
+#[doc = "The plugin MUST NOT attempt to use this function outside of the"]
+#[doc = "LV2_State_Interface.restore() context."]
+pub type LV2_State_Store_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_State_Handle,
+        key: u32,
+        value: *const ::std::os::raw::c_void,
+        size: usize,
+        type_: u32,
+        flags: u32,
+    ) -> LV2_State_Status,
+>;
+#[doc = "A host-provided function to retrieve a property."]
+#[doc = "@param handle Must be the handle passed to LV2_State_Interface.restore()."]
+#[doc = "@param key The key of the property to retrieve (URID)."]
+#[doc = "@param size (Output) If non-NULL, set to the size of the restored value."]
+#[doc = "@param type (Output) If non-NULL, set to the type of the restored value."]
+#[doc = "@param flags (Output) If non-NULL, set to the flags for the restored value."]
+#[doc = "@return A pointer to the restored value (object), or NULL if no value"]
+#[doc = "has been stored under `key`."]
+#[doc = ""]
+#[doc = "A callback of this type is passed by the host to"]
+#[doc = "LV2_State_Interface.restore().  This callback is called repeatedly by the"]
+#[doc = "plugin to retrieve any properties it requires to restore its state."]
+#[doc = ""]
+#[doc = "The returned value MUST remain valid until LV2_State_Interface.restore()"]
+#[doc = "returns.  The plugin MUST NOT attempt to use this function, or any value"]
+#[doc = "returned from it, outside of the LV2_State_Interface.restore() context."]
+pub type LV2_State_Retrieve_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_State_Handle,
+        key: u32,
+        size: *mut usize,
+        type_: *mut u32,
+        flags: *mut u32,
+    ) -> *const ::std::os::raw::c_void,
+>;
+#[doc = "LV2 Plugin State Interface."]
+#[doc = ""]
+#[doc = "When the plugin's extension_data is called with argument"]
+#[doc = "LV2_STATE__interface, the plugin MUST return an LV2_State_Interface"]
+#[doc = "structure, which remains valid for the lifetime of the plugin."]
+#[doc = ""]
+#[doc = "The host can use the contained function pointers to save and restore the"]
+#[doc = "state of a plugin instance at any time, provided the threading restrictions"]
+#[doc = "of the functions are met."]
+#[doc = ""]
+#[doc = "Stored data is only guaranteed to be compatible between instances of plugins"]
+#[doc = "with the same URI (i.e. if a change to a plugin would cause a fatal error"]
+#[doc = "when restoring state saved by a previous version of that plugin, the plugin"]
+#[doc = "URI MUST change just as it must when ports change incompatibly).  Plugin"]
+#[doc = "authors should consider this possibility, and always store sensible data"]
+#[doc = "with meaningful types to avoid such problems in the future."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_State_Interface {
+    #[doc = "Save plugin state using a host-provided `store` callback."]
+    #[doc = ""]
+    #[doc = "@param instance The instance handle of the plugin."]
+    #[doc = "@param store The host-provided store callback."]
+    #[doc = "@param handle An opaque pointer to host data which MUST be passed as the"]
+    #[doc = "handle parameter to `store` if it is called."]
+    #[doc = "@param flags Flags describing desired properties of this save.  These"]
+    #[doc = "flags may be used to determine the most appropriate values to store."]
+    #[doc = "@param features Extensible parameter for passing any additional"]
+    #[doc = "features to be used for this save."]
+    #[doc = ""]
+    #[doc = "The plugin is expected to store everything necessary to completely"]
+    #[doc = "restore its state later.  Plugins SHOULD store simple POD data whenever"]
+    #[doc = "possible, and consider the possibility of state being restored much"]
+    #[doc = "later on a different machine."]
+    #[doc = ""]
+    #[doc = "The `handle` pointer and `store` function MUST NOT be used"]
+    #[doc = "beyond the scope of save()."]
+    #[doc = ""]
+    #[doc = "This function has its own special threading class: it may not be called"]
+    #[doc = "concurrently with any \"Instantiation\" function, but it may be called"]
+    #[doc = "concurrently with functions in any other class, unless the definition of"]
+    #[doc = "that class prohibits it (for example, it may not be called concurrently"]
+    #[doc = "with a \"Discovery\" function, but it may be called concurrently with an"]
+    #[doc = "\"Audio\" function.  The plugin is responsible for any locking or"]
+    #[doc = "lock-free techniques necessary to make this possible."]
+    #[doc = ""]
+    #[doc = "Note that in the simple case where state is only modified by restore(),"]
+    #[doc = "there are no synchronization issues since save() is never called"]
+    #[doc = "concurrently with restore() (though run() may read it during a save)."]
+    #[doc = ""]
+    #[doc = "Plugins that dynamically modify state while running, however, must take"]
+    #[doc = "care to do so in such a way that a concurrent call to save() will save a"]
+    #[doc = "consistent representation of plugin state for a single instant in time."]
+    pub save: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            store: LV2_State_Store_Function,
+            handle: LV2_State_Handle,
+            flags: u32,
+            features: *const *const LV2_Feature,
+        ) -> LV2_State_Status,
+    >,
+    #[doc = "Restore plugin state using a host-provided `retrieve` callback."]
+    #[doc = ""]
+    #[doc = "@param instance The instance handle of the plugin."]
+    #[doc = "@param retrieve The host-provided retrieve callback."]
+    #[doc = "@param handle An opaque pointer to host data which MUST be passed as the"]
+    #[doc = "handle parameter to `retrieve` if it is called."]
+    #[doc = "@param flags Currently unused."]
+    #[doc = "@param features Extensible parameter for passing any additional"]
+    #[doc = "features to be used for this restore."]
+    #[doc = ""]
+    #[doc = "The plugin MAY assume a restored value was set by a previous call to"]
+    #[doc = "LV2_State_Interface.save() by a plugin with the same URI."]
+    #[doc = ""]
+    #[doc = "The plugin MUST gracefully fall back to a default value when a value can"]
+    #[doc = "not be retrieved.  This allows the host to reset the plugin state with"]
+    #[doc = "an empty map."]
+    #[doc = ""]
+    #[doc = "The `handle` pointer and `store` function MUST NOT be used"]
+    #[doc = "beyond the scope of restore()."]
+    #[doc = ""]
+    #[doc = "This function is in the \"Instantiation\" threading class as defined by"]
+    #[doc = "LV2. This means it MUST NOT be called concurrently with any other"]
+    #[doc = "function on the same plugin instance."]
+    pub restore: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            retrieve: LV2_State_Retrieve_Function,
+            handle: LV2_State_Handle,
+            flags: u32,
+            features: *const *const LV2_Feature,
+        ) -> LV2_State_Status,
+    >,
+}
+#[doc = "Feature data for state:mapPath (@ref LV2_STATE__mapPath)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_State_Map_Path {
+    #[doc = "Opaque host data."]
+    pub handle: LV2_State_Map_Path_Handle,
+    #[doc = "Map an absolute path to an abstract path for use in plugin state."]
+    #[doc = "@param handle MUST be the `handle` member of this struct."]
+    #[doc = "@param absolute_path The absolute path of a file."]
+    #[doc = "@return An abstract path suitable for use in plugin state."]
+    #[doc = ""]
+    #[doc = "The plugin MUST use this function to map any paths that will be stored"]
+    #[doc = "in plugin state.  The returned value is an abstract path which MAY not"]
+    #[doc = "be an actual file system path; absolute_path() MUST be used to map"]
+    #[doc = "it to an actual path in order to use the file."]
+    #[doc = ""]
+    #[doc = "Plugins MUST NOT make any assumptions about abstract paths except that"]
+    #[doc = "they can be mapped back to the absolute path of the \"same\" file (though"]
+    #[doc = "not necessarily the same original path) using absolute_path()."]
+    #[doc = ""]
+    #[doc = "This function may only be called within the context of"]
+    #[doc = "LV2_State_Interface methods.  The caller must free the returned value"]
+    #[doc = "with LV2_State_Free_Path.free_path()."]
+    pub abstract_path: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_State_Map_Path_Handle,
+            absolute_path: *const ::std::os::raw::c_char,
+        ) -> *mut ::std::os::raw::c_char,
+    >,
+    #[doc = "Map an abstract path from plugin state to an absolute path."]
+    #[doc = "@param handle MUST be the `handle` member of this struct."]
+    #[doc = "@param abstract_path An abstract path (typically from plugin state)."]
+    #[doc = "@return An absolute file system path."]
+    #[doc = ""]
+    #[doc = "The plugin MUST use this function in order to actually open or otherwise"]
+    #[doc = "use any paths loaded from plugin state."]
+    #[doc = ""]
+    #[doc = "This function may only be called within the context of"]
+    #[doc = "LV2_State_Interface methods.  The caller must free the returned value"]
+    #[doc = "with LV2_State_Free_Path.free_path()."]
+    pub absolute_path: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_State_Map_Path_Handle,
+            abstract_path: *const ::std::os::raw::c_char,
+        ) -> *mut ::std::os::raw::c_char,
+    >,
+}
+#[doc = "Feature data for state:makePath (@ref LV2_STATE__makePath)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_State_Make_Path {
+    #[doc = "Opaque host data."]
+    pub handle: LV2_State_Make_Path_Handle,
+    #[doc = "Return a path the plugin may use to create a new file."]
+    #[doc = "@param handle MUST be the `handle` member of this struct."]
+    #[doc = "@param path The path of the new file within a namespace unique to this"]
+    #[doc = "plugin instance."]
+    #[doc = "@return The absolute path to use for the new file."]
+    #[doc = ""]
+    #[doc = "This function can be used by plugins to create files and directories,"]
+    #[doc = "either at state saving time (if this feature is passed to"]
+    #[doc = "LV2_State_Interface.save()) or any time (if this feature is passed to"]
+    #[doc = "LV2_Descriptor.instantiate())."]
+    #[doc = ""]
+    #[doc = "The host MUST do whatever is necessary for the plugin to be able to"]
+    #[doc = "create a file at the returned path (for example, using fopen()),"]
+    #[doc = "including creating any leading directories."]
+    #[doc = ""]
+    #[doc = "If this function is passed to LV2_Descriptor.instantiate(), it may be"]
+    #[doc = "called from any non-realtime context.  If it is passed to"]
+    #[doc = "LV2_State_Interface.save(), it may only be called within the dynamic"]
+    #[doc = "scope of that function call."]
+    #[doc = ""]
+    #[doc = "The caller must free the returned value with"]
+    #[doc = "LV2_State_Free_Path.free_path()."]
+    pub path: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_State_Make_Path_Handle,
+            path: *const ::std::os::raw::c_char,
+        ) -> *mut ::std::os::raw::c_char,
+    >,
+}
+#[doc = "Feature data for state:freePath (@ref LV2_STATE__freePath)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_State_Free_Path {
+    #[doc = "Opaque host data."]
+    pub handle: LV2_State_Free_Path_Handle,
+    #[doc = "Free a path returned by a state feature."]
+    #[doc = ""]
+    #[doc = "@param handle MUST be the `handle` member of this struct."]
+    #[doc = "@param path The path previously returned by a state feature."]
+    #[doc = ""]
+    #[doc = "This function can be used by plugins to free paths allocated by the host"]
+    #[doc = "and returned by state features (LV2_State_Map_Path.abstract_path(),"]
+    #[doc = "LV2_State_Map_Path.absolute_path(), and LV2_State_Make_Path.path())."]
+    pub free_path: ::std::option::Option<
+        unsafe extern "C" fn(handle: LV2_State_Free_Path_Handle, path: *mut ::std::os::raw::c_char),
+    >,
+}
+#[doc = "A pointer to some widget or other type of UI handle."]
+#[doc = ""]
+#[doc = "The actual type is defined by the type of the UI."]
+pub type LV2UI_Widget = *mut ::std::os::raw::c_void;
+#[doc = "A pointer to UI instance internals."]
+#[doc = ""]
+#[doc = "The host may compare this to NULL, but otherwise MUST NOT interpret it."]
+pub type LV2UI_Handle = *mut ::std::os::raw::c_void;
+#[doc = "A pointer to a controller provided by the host."]
+#[doc = ""]
+#[doc = "The UI may compare this to NULL, but otherwise MUST NOT interpret it."]
+pub type LV2UI_Controller = *mut ::std::os::raw::c_void;
+#[doc = "A pointer to opaque data for a feature."]
+pub type LV2UI_Feature_Handle = *mut ::std::os::raw::c_void;
+#[doc = "A host-provided function that sends data to a plugin's input ports."]
+#[doc = ""]
+#[doc = "@param controller The opaque controller pointer passed to"]
+#[doc = "LV2UI_Descriptor::instantiate()."]
+#[doc = ""]
+#[doc = "@param port_index Index of the port to update."]
+#[doc = ""]
+#[doc = "@param buffer Buffer containing `buffer_size` bytes of data."]
+#[doc = ""]
+#[doc = "@param buffer_size Size of `buffer` in bytes."]
+#[doc = ""]
+#[doc = "@param port_protocol Either 0 or the URID for a ui:PortProtocol.  If 0, the"]
+#[doc = "protocol is implicitly ui:floatProtocol, the port MUST be an lv2:ControlPort"]
+#[doc = "input, `buffer` MUST point to a single float value, and `buffer_size` MUST"]
+#[doc = "be sizeof(float).  The UI SHOULD NOT use a protocol not supported by the"]
+#[doc = "host, but the host MUST gracefully ignore any protocol it does not"]
+#[doc = "understand."]
+pub type LV2UI_Write_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        controller: LV2UI_Controller,
+        port_index: u32,
+        buffer_size: u32,
+        port_protocol: u32,
+        buffer: *const ::std::os::raw::c_void,
+    ),
+>;
+#[doc = "A plugin UI."]
+#[doc = ""]
+#[doc = "A pointer to an object of this type is returned by the lv2ui_descriptor()"]
+#[doc = "function."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Descriptor {
+    #[doc = "The URI for this UI (not for the plugin it controls)."]
+    pub URI: *const ::std::os::raw::c_char,
+    #[doc = "Create a new UI and return a handle to it.  This function works"]
+    #[doc = "similarly to LV2_Descriptor::instantiate()."]
+    #[doc = ""]
+    #[doc = "@param descriptor The descriptor for the UI to instantiate."]
+    #[doc = ""]
+    #[doc = "@param plugin_uri The URI of the plugin that this UI will control."]
+    #[doc = ""]
+    #[doc = "@param bundle_path The path to the bundle containing this UI, including"]
+    #[doc = "the trailing directory separator."]
+    #[doc = ""]
+    #[doc = "@param write_function A function that the UI can use to send data to the"]
+    #[doc = "plugin's input ports."]
+    #[doc = ""]
+    #[doc = "@param controller A handle for the UI instance to be passed as the"]
+    #[doc = "first parameter of UI methods."]
+    #[doc = ""]
+    #[doc = "@param widget (output) widget pointer.  The UI points this at its main"]
+    #[doc = "widget, which has the type defined by the UI type in the data file."]
+    #[doc = ""]
+    #[doc = "@param features An array of LV2_Feature pointers.  The host must pass"]
+    #[doc = "all feature URIs that it and the UI supports and any additional data, as"]
+    #[doc = "in LV2_Descriptor::instantiate().  Note that UI features and plugin"]
+    #[doc = "features are not necessarily the same."]
+    #[doc = ""]
+    pub instantiate: ::std::option::Option<
+        unsafe extern "C" fn(
+            descriptor: *const LV2UI_Descriptor,
+            plugin_uri: *const ::std::os::raw::c_char,
+            bundle_path: *const ::std::os::raw::c_char,
+            write_function: LV2UI_Write_Function,
+            controller: LV2UI_Controller,
+            widget: *mut LV2UI_Widget,
+            features: *const *const LV2_Feature,
+        ) -> LV2UI_Handle,
+    >,
+    #[doc = "Destroy the UI.  The host must not try to access the widget after"]
+    #[doc = "calling this function."]
+    pub cleanup: ::std::option::Option<unsafe extern "C" fn(ui: LV2UI_Handle)>,
+    #[doc = "Tell the UI that something interesting has happened at a plugin port."]
+    #[doc = ""]
+    #[doc = "What is \"interesting\" and how it is written to `buffer` is defined by"]
+    #[doc = "`format`, which has the same meaning as in LV2UI_Write_Function()."]
+    #[doc = "Format 0 is a special case for lv2:ControlPort, where this function"]
+    #[doc = "should be called when the port value changes (but not necessarily for"]
+    #[doc = "every change), `buffer_size` must be sizeof(float), and `buffer`"]
+    #[doc = "points to a single IEEE-754 float."]
+    #[doc = ""]
+    #[doc = "By default, the host should only call this function for lv2:ControlPort"]
+    #[doc = "inputs.  However, the UI can request updates for other ports statically"]
+    #[doc = "with ui:portNotification or dynamicaly with ui:portSubscribe."]
+    #[doc = ""]
+    #[doc = "The UI MUST NOT retain any reference to `buffer` after this function"]
+    #[doc = "returns, it is only valid for the duration of the call."]
+    #[doc = ""]
+    #[doc = "This member may be NULL if the UI is not interested in any port events."]
+    pub port_event: ::std::option::Option<
+        unsafe extern "C" fn(
+            ui: LV2UI_Handle,
+            port_index: u32,
+            buffer_size: u32,
+            format: u32,
+            buffer: *const ::std::os::raw::c_void,
+        ),
+    >,
+    #[doc = "Return a data structure associated with an extension URI, typically an"]
+    #[doc = "interface struct with additional function pointers"]
+    #[doc = ""]
+    #[doc = "This member may be set to NULL if the UI is not interested in supporting"]
+    #[doc = "any extensions. This is similar to LV2_Descriptor::extension_data()."]
+    #[doc = ""]
+    pub extension_data: ::std::option::Option<
+        unsafe extern "C" fn(uri: *const ::std::os::raw::c_char) -> *const ::std::os::raw::c_void,
+    >,
+}
+#[doc = "Feature/interface for resizable UIs (LV2_UI__resize)."]
+#[doc = ""]
+#[doc = "This structure is used in two ways: as a feature passed by the host via"]
+#[doc = "LV2UI_Descriptor::instantiate(), or as an interface provided by a UI via"]
+#[doc = "LV2UI_Descriptor::extension_data())."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Resize {
+    #[doc = "Pointer to opaque data which must be passed to ui_resize()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Request/advertise a size change."]
+    #[doc = ""]
+    #[doc = "When provided by the host, the UI may call this function to inform the"]
+    #[doc = "host about the size of the UI."]
+    #[doc = ""]
+    #[doc = "When provided by the UI, the host may call this function to notify the"]
+    #[doc = "UI that it should change its size accordingly.  In this case, the host"]
+    #[doc = "must pass the LV2UI_Handle to provide access to the UI instance."]
+    #[doc = ""]
+    #[doc = "@return 0 on success."]
+    pub ui_resize: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            width: ::std::os::raw::c_int,
+            height: ::std::os::raw::c_int,
+        ) -> ::std::os::raw::c_int,
+    >,
+}
+#[doc = "Feature to map port symbols to UIs."]
+#[doc = ""]
+#[doc = "This can be used by the UI to get the index for a port with the given"]
+#[doc = "symbol.  This makes it possible to implement and distribute a UI separately"]
+#[doc = "from the plugin (since symbol, unlike index, is a stable port identifier)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Port_Map {
+    #[doc = "Pointer to opaque data which must be passed to port_index()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Get the index for the port with the given `symbol`."]
+    #[doc = ""]
+    #[doc = "@return The index of the port, or LV2UI_INVALID_PORT_INDEX if no such"]
+    #[doc = "port is found."]
+    pub port_index: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            symbol: *const ::std::os::raw::c_char,
+        ) -> u32,
+    >,
+}
+#[doc = "Feature to subscribe to port updates (LV2_UI__portSubscribe)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Port_Subscribe {
+    #[doc = "Pointer to opaque data which must be passed to subscribe() and"]
+    #[doc = "unsubscribe()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Subscribe to updates for a port."]
+    #[doc = ""]
+    #[doc = "This means that the host will call the UI's port_event() function when"]
+    #[doc = "the port value changes (as defined by protocol)."]
+    #[doc = ""]
+    #[doc = "Calling this function with the same `port_index` and `port_protocol`"]
+    #[doc = "as an already active subscription has no effect."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = "@param port_index The index of the port."]
+    #[doc = "@param port_protocol The URID of the ui:PortProtocol."]
+    #[doc = "@param features Features for this subscription."]
+    #[doc = "@return 0 on success."]
+    pub subscribe: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            port_index: u32,
+            port_protocol: u32,
+            features: *const *const LV2_Feature,
+        ) -> u32,
+    >,
+    #[doc = "Unsubscribe from updates for a port."]
+    #[doc = ""]
+    #[doc = "This means that the host will cease calling calling port_event() when"]
+    #[doc = "the port value changes."]
+    #[doc = ""]
+    #[doc = "Calling this function with a `port_index` and `port_protocol` that"]
+    #[doc = "does not refer to an active port subscription has no effect."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = "@param port_index The index of the port."]
+    #[doc = "@param port_protocol The URID of the ui:PortProtocol."]
+    #[doc = "@param features Features for this subscription."]
+    #[doc = "@return 0 on success."]
+    pub unsubscribe: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            port_index: u32,
+            port_protocol: u32,
+            features: *const *const LV2_Feature,
+        ) -> u32,
+    >,
+}
+#[doc = "A feature to notify the host that the user has grabbed a UI control."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Touch {
+    #[doc = "Pointer to opaque data which must be passed to ui_resize()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Notify the host that a control has been grabbed or released."]
+    #[doc = ""]
+    #[doc = "The host should cease automating the port or otherwise manipulating the"]
+    #[doc = "port value until the control has been ungrabbed."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = "@param port_index The index of the port associated with the control."]
+    #[doc = "@param grabbed If true, the control has been grabbed, otherwise the"]
+    #[doc = "control has been released."]
+    pub touch: ::std::option::Option<
+        unsafe extern "C" fn(handle: LV2UI_Feature_Handle, port_index: u32, grabbed: bool),
+    >,
+}
+#[doc = "Completed successfully."]
+#[doc = ""]
+#[doc = "The host will set the parameter later if the user choses a new value."]
+pub const LV2UI_Request_Value_Status_LV2UI_REQUEST_VALUE_SUCCESS: LV2UI_Request_Value_Status = 0;
+#[doc = "Parameter already being requested."]
+#[doc = ""]
+#[doc = "The host is already requesting a parameter from the user (for example, a"]
+#[doc = "dialog is visible), or the UI is otherwise busy and can not make this"]
+#[doc = "request."]
+pub const LV2UI_Request_Value_Status_LV2UI_REQUEST_VALUE_BUSY: LV2UI_Request_Value_Status = 1;
+#[doc = "Unknown parameter."]
+#[doc = ""]
+#[doc = "The host is not aware of this parameter, and is not able to set a new"]
+#[doc = "value for it."]
+pub const LV2UI_Request_Value_Status_LV2UI_REQUEST_VALUE_ERR_UNKNOWN: LV2UI_Request_Value_Status =
+    2;
+#[doc = "Unsupported parameter."]
+#[doc = ""]
+#[doc = "The host knows about this parameter, but does not support requesting a"]
+#[doc = "new value for it from the user.  This is likely because the host does"]
+#[doc = "not have UI support for choosing a value with the appropriate type."]
+pub const LV2UI_Request_Value_Status_LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED:
+    LV2UI_Request_Value_Status = 3;
+#[doc = "A status code for LV2UI_Request_Value::request()."]
+pub type LV2UI_Request_Value_Status = u32;
+#[doc = "A feature to request a new parameter value from the host."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Request_Value {
+    #[doc = "Pointer to opaque data which must be passed to request()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Request a value for a parameter from the host."]
+    #[doc = ""]
+    #[doc = "This is mainly used by UIs to request values for complex parameters that"]
+    #[doc = "don't change often, such as file paths, but it may be used to request"]
+    #[doc = "any parameter value."]
+    #[doc = ""]
+    #[doc = "This function returns immediately, and the return value indicates"]
+    #[doc = "whether the host can fulfill the request.  The host may notify the"]
+    #[doc = "plugin about the new parameter value, for example when a file is"]
+    #[doc = "selected by the user, via the usual mechanism.  Typically, the host will"]
+    #[doc = "send a message to the plugin that sets the new parameter value, and the"]
+    #[doc = "plugin will notify the UI via a message as usual for any other parameter"]
+    #[doc = "change."]
+    #[doc = ""]
+    #[doc = "To provide an appropriate UI, the host can determine details about the"]
+    #[doc = "parameter from the plugin data as usual.  The additional parameters of"]
+    #[doc = "this function provide support for more advanced use cases, but in the"]
+    #[doc = "simple common case, the plugin will simply pass the key of the desired"]
+    #[doc = "parameter and zero for everything else."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = ""]
+    #[doc = "@param key The URID of the parameter."]
+    #[doc = ""]
+    #[doc = "@param type The optional type of the value to request.  This can be used"]
+    #[doc = "to request a specific value type for parameters that support several."]
+    #[doc = "If non-zero, it must be the URID of an instance of rdfs:Class or"]
+    #[doc = "rdfs:Datatype."]
+    #[doc = ""]
+    #[doc = "@param features Additional features for this request, or NULL."]
+    #[doc = ""]
+    #[doc = "@return A status code which is 0 on success."]
+    pub request: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            key: LV2_URID,
+            type_: LV2_URID,
+            features: *const *const LV2_Feature,
+        ) -> LV2UI_Request_Value_Status,
+    >,
+}
+#[doc = "UI Idle Interface (LV2_UI__idleInterface)"]
+#[doc = ""]
+#[doc = "UIs can provide this interface to have an idle() callback called by the host"]
+#[doc = "rapidly to update the UI."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Idle_Interface {
+    #[doc = "Run a single iteration of the UI's idle loop."]
+    #[doc = ""]
+    #[doc = "This will be called rapidly in the UI thread at a rate appropriate"]
+    #[doc = "for a toolkit main loop.  There are no precise timing guarantees, but"]
+    #[doc = "the host should attempt to call idle() at a high enough rate for smooth"]
+    #[doc = "animation, at least 30Hz."]
+    #[doc = ""]
+    #[doc = "@return non-zero if the UI has been closed, in which case the host"]
+    #[doc = "should stop calling idle(), and can either completely destroy the UI, or"]
+    #[doc = "re-show it and resume calling idle()."]
+    pub idle:
+        ::std::option::Option<unsafe extern "C" fn(ui: LV2UI_Handle) -> ::std::os::raw::c_int>,
+}
+#[doc = "UI Show Interface (LV2_UI__showInterface)"]
+#[doc = ""]
+#[doc = "UIs can provide this interface to show and hide a window, which allows them"]
+#[doc = "to function in hosts unable to embed their widget.  This allows any UI to"]
+#[doc = "provide a fallback for embedding that works in any host."]
+#[doc = ""]
+#[doc = "If used:"]
+#[doc = "- The host MUST use LV2UI_Idle_Interface to drive the UI."]
+#[doc = "- The UI MUST return non-zero from LV2UI_Idle_Interface::idle() when it has been closed."]
+#[doc = "- If idle() returns non-zero, the host MUST call hide() and stop calling"]
+#[doc = "idle().  It MAY later call show() then resume calling idle()."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Show_Interface {
+    #[doc = "Show a window for this UI."]
+    #[doc = ""]
+    #[doc = "The window title MAY have been passed by the host to"]
+    #[doc = "LV2UI_Descriptor::instantiate() as an LV2_Options_Option with key"]
+    #[doc = "LV2_UI__windowTitle."]
+    #[doc = ""]
+    #[doc = "@return 0 on success, or anything else to stop being called."]
+    pub show:
+        ::std::option::Option<unsafe extern "C" fn(ui: LV2UI_Handle) -> ::std::os::raw::c_int>,
+    #[doc = "Hide the window for this UI."]
+    #[doc = ""]
+    #[doc = "@return 0 on success, or anything else to stop being called."]
+    pub hide:
+        ::std::option::Option<unsafe extern "C" fn(ui: LV2UI_Handle) -> ::std::os::raw::c_int>,
+}
+#[doc = "Peak data for a slice of time, the update format for ui:peakProtocol."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Peak_Data {
+    #[doc = "The start of the measurement period.  This is just a running counter"]
+    #[doc = "that is only meaningful in comparison to previous values and must not be"]
+    #[doc = "interpreted as an absolute time."]
+    pub period_start: u32,
+    #[doc = "The size of the measurement period, in the same units as period_start."]
+    pub period_size: u32,
+    #[doc = "The peak value for the measurement period. This should be the maximal"]
+    #[doc = "value for abs(sample) over all the samples in the period."]
+    pub peak: f32,
+}
+#[doc = "The type of the lv2ui_descriptor() function."]
+pub type LV2UI_DescriptorFunction =
+    ::std::option::Option<unsafe extern "C" fn(index: u32) -> *const LV2UI_Descriptor>;
+#[doc = "Opaque pointer to host data."]
+pub type LV2_URI_Map_Callback_Data = *mut ::std::os::raw::c_void;
+#[doc = "URI Map Feature."]
+#[doc = ""]
+#[doc = "To support this feature the host must pass an LV2_Feature struct to the"]
+#[doc = "plugin's instantiate method with URI \"http://lv2plug.in/ns/ext/uri-map\""]
+#[doc = "and data pointed to an instance of this struct."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_URI_Map_Feature {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "The plugin MUST pass this to any call to functions in this struct."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub callback_data: LV2_URI_Map_Callback_Data,
+    #[doc = "Get the numeric ID of a URI from the host."]
+    #[doc = ""]
+    #[doc = "@param callback_data Must be the callback_data member of this struct."]
+    #[doc = "@param map The 'context' of this URI. Certain extensions may define a"]
+    #[doc = "URI that must be passed here with certain restrictions on the return"]
+    #[doc = "value (e.g. limited range). This value may be NULL if the plugin needs"]
+    #[doc = "an ID for a URI in general. Extensions SHOULD NOT define a context"]
+    #[doc = "unless there is a specific need to do so, e.g. to restrict the range of"]
+    #[doc = "the returned value."]
+    #[doc = "@param uri The URI to be mapped to an integer ID."]
+    #[doc = ""]
+    #[doc = "This function is referentially transparent; any number of calls with the"]
+    #[doc = "same arguments is guaranteed to return the same value over the life of a"]
+    #[doc = "plugin instance (though the same URI may return different values with a"]
+    #[doc = "different map parameter). However, this function is not necessarily very"]
+    #[doc = "fast: plugins SHOULD cache any IDs they might need in performance"]
+    #[doc = "critical situations."]
+    #[doc = ""]
+    #[doc = "The return value 0 is reserved and indicates that an ID for that URI"]
+    #[doc = "could not be created for whatever reason. Extensions MAY define more"]
+    #[doc = "precisely what this means in a certain context, but in general plugins"]
+    #[doc = "SHOULD handle this situation as gracefully as possible. However, hosts"]
+    #[doc = "SHOULD NOT return 0 from this function in non-exceptional circumstances"]
+    #[doc = "(e.g. the URI map SHOULD be dynamic). Hosts that statically support only"]
+    #[doc = "a fixed set of URIs should not expect plugins to function correctly."]
+    pub uri_to_id: ::std::option::Option<
+        unsafe extern "C" fn(
+            callback_data: LV2_URI_Map_Callback_Data,
+            map: *const ::std::os::raw::c_char,
+            uri: *const ::std::os::raw::c_char,
+        ) -> u32,
+    >,
+}
+#[doc = "< Completed successfully."]
+pub const LV2_Worker_Status_LV2_WORKER_SUCCESS: LV2_Worker_Status = 0;
+#[doc = "< Unknown error."]
+pub const LV2_Worker_Status_LV2_WORKER_ERR_UNKNOWN: LV2_Worker_Status = 1;
+#[doc = "< Failed due to lack of space."]
+pub const LV2_Worker_Status_LV2_WORKER_ERR_NO_SPACE: LV2_Worker_Status = 2;
+#[doc = "Status code for worker functions."]
+pub type LV2_Worker_Status = u32;
+#[doc = " Opaque handle for LV2_Worker_Interface::work()."]
+pub type LV2_Worker_Respond_Handle = *mut ::std::os::raw::c_void;
+#[doc = "A function to respond to run() from the worker method."]
+#[doc = ""]
+#[doc = "The `data` MUST be safe for the host to copy and later pass to"]
+#[doc = "work_response(), and the host MUST guarantee that it will be eventually"]
+#[doc = "passed to work_response() if this function returns LV2_WORKER_SUCCESS."]
+pub type LV2_Worker_Respond_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_Worker_Respond_Handle,
+        size: u32,
+        data: *const ::std::os::raw::c_void,
+    ) -> LV2_Worker_Status,
+>;
+#[doc = "Plugin Worker Interface."]
+#[doc = ""]
+#[doc = "This is the interface provided by the plugin to implement a worker method."]
+#[doc = "The plugin's extension_data() method should return an LV2_Worker_Interface"]
+#[doc = "when called with LV2_WORKER__interface as its argument."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Worker_Interface {
+    #[doc = "The worker method.  This is called by the host in a non-realtime context"]
+    #[doc = "as requested, possibly with an arbitrary message to handle."]
+    #[doc = ""]
+    #[doc = "A response can be sent to run() using `respond`.  The plugin MUST NOT"]
+    #[doc = "make any assumptions about which thread calls this method, except that"]
+    #[doc = "there are no real-time requirements and only one call may be executed at"]
+    #[doc = "a time.  That is, the host MAY call this method from any non-real-time"]
+    #[doc = "thread, but MUST NOT make concurrent calls to this method from several"]
+    #[doc = "threads."]
+    #[doc = ""]
+    #[doc = "@param instance The LV2 instance this is a method on."]
+    #[doc = "@param respond  A function for sending a response to run()."]
+    #[doc = "@param handle   Must be passed to `respond` if it is called."]
+    #[doc = "@param size     The size of `data`."]
+    #[doc = "@param data     Data from run(), or NULL."]
+    pub work: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            respond: LV2_Worker_Respond_Function,
+            handle: LV2_Worker_Respond_Handle,
+            size: u32,
+            data: *const ::std::os::raw::c_void,
+        ) -> LV2_Worker_Status,
+    >,
+    #[doc = "Handle a response from the worker.  This is called by the host in the"]
+    #[doc = "run() context when a response from the worker is ready."]
+    #[doc = ""]
+    #[doc = "@param instance The LV2 instance this is a method on."]
+    #[doc = "@param size     The size of `body`."]
+    #[doc = "@param body     Message body, or NULL."]
+    pub work_response: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            size: u32,
+            body: *const ::std::os::raw::c_void,
+        ) -> LV2_Worker_Status,
+    >,
+    #[doc = "Called when all responses for this cycle have been delivered."]
+    #[doc = ""]
+    #[doc = "Since work_response() may be called after run() finished, this provides"]
+    #[doc = "a hook for code that must run after the cycle is completed."]
+    #[doc = ""]
+    #[doc = "This field may be NULL if the plugin has no use for it.  Otherwise, the"]
+    #[doc = "host MUST call it after every run(), regardless of whether or not any"]
+    #[doc = "responses were sent that cycle."]
+    pub end_run:
+        ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle) -> LV2_Worker_Status>,
+}
+#[doc = " Opaque handle for LV2_Worker_Schedule."]
+pub type LV2_Worker_Schedule_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Schedule Worker Host Feature."]
+#[doc = ""]
+#[doc = "The host passes this feature to provide a schedule_work() function, which"]
+#[doc = "the plugin can use to schedule a worker call from run()."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Worker_Schedule {
+    #[doc = "Opaque host data."]
+    pub handle: LV2_Worker_Schedule_Handle,
+    #[doc = "Request from run() that the host call the worker."]
+    #[doc = ""]
+    #[doc = "This function is in the audio threading class.  It should be called from"]
+    #[doc = "run() to request that the host call the work() method in a non-realtime"]
+    #[doc = "context with the given arguments."]
+    #[doc = ""]
+    #[doc = "This function is always safe to call from run(), but it is not"]
+    #[doc = "guaranteed that the worker is actually called from a different thread."]
+    #[doc = "In particular, when free-wheeling (for example, during offline"]
+    #[doc = "rendering), the worker may be executed immediately.  This allows"]
+    #[doc = "single-threaded processing with sample accuracy and avoids timing"]
+    #[doc = "problems when run() is executing much faster or slower than real-time."]
+    #[doc = ""]
+    #[doc = "Plugins SHOULD be written in such a way that if the worker runs"]
+    #[doc = "immediately, and responses from the worker are delivered immediately,"]
+    #[doc = "the effect of the work takes place immediately with sample accuracy."]
+    #[doc = ""]
+    #[doc = "The `data` MUST be safe for the host to copy and later pass to work(),"]
+    #[doc = "and the host MUST guarantee that it will be eventually passed to work()"]
+    #[doc = "if this function returns LV2_WORKER_SUCCESS."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = "@param size   The size of `data`."]
+    #[doc = "@param data   Message to pass to work(), or NULL."]
+    pub schedule_work: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_Worker_Schedule_Handle,
+            size: u32,
+            data: *const ::std::os::raw::c_void,
+        ) -> LV2_Worker_Status,
+    >,
+}
+pub type __builtin_va_list = __va_list;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct __va_list {
+    pub __ap: *mut ::std::os::raw::c_void,
+}
diff --git a/sys/src/linux/mod.rs b/sys/src/linux/mod.rs
new file mode 100644
index 00000000..d2d0f80a
--- /dev/null
+++ b/sys/src/linux/mod.rs
@@ -0,0 +1,6 @@
+#[cfg_attr(target_arch = "x86", path = "x86.rs")]
+#[cfg_attr(target_arch = "x86_64", path = "x86_64.rs")]
+#[cfg_attr(target_arch = "arm", path = "arm.rs")]
+#[cfg_attr(target_arch = "aarch64", path = "aarch64.rs")]
+mod unsupported;
+pub use unsupported::*;
diff --git a/sys/src/linux/unsupported.rs b/sys/src/linux/unsupported.rs
new file mode 100644
index 00000000..baa1ff78
--- /dev/null
+++ b/sys/src/linux/unsupported.rs
@@ -0,0 +1 @@
+compile_error!("The targeted computer architecture is not supported by rust-lv2!");
diff --git a/sys/src/linux/x86.rs b/sys/src/linux/x86.rs
new file mode 100644
index 00000000..ca89369b
--- /dev/null
+++ b/sys/src/linux/x86.rs
@@ -0,0 +1,2720 @@
+/* automatically generated by rust-bindgen */
+
+pub const LV2_ATOM_URI: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/atom\0";
+pub const LV2_ATOM_PREFIX: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/atom#\0";
+pub const LV2_ATOM__Atom: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#Atom\0";
+pub const LV2_ATOM__AtomPort: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#AtomPort\0";
+pub const LV2_ATOM__Blank: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Blank\0";
+pub const LV2_ATOM__Bool: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#Bool\0";
+pub const LV2_ATOM__Chunk: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Chunk\0";
+pub const LV2_ATOM__Double: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#Double\0";
+pub const LV2_ATOM__Event: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Event\0";
+pub const LV2_ATOM__Float: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Float\0";
+pub const LV2_ATOM__Int: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/atom#Int\0";
+pub const LV2_ATOM__Literal: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/atom#Literal\0";
+pub const LV2_ATOM__Long: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#Long\0";
+pub const LV2_ATOM__Number: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#Number\0";
+pub const LV2_ATOM__Object: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#Object\0";
+pub const LV2_ATOM__Path: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#Path\0";
+pub const LV2_ATOM__Property: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#Property\0";
+pub const LV2_ATOM__Resource: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#Resource\0";
+pub const LV2_ATOM__Sequence: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#Sequence\0";
+pub const LV2_ATOM__Sound: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Sound\0";
+pub const LV2_ATOM__String: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#String\0";
+pub const LV2_ATOM__Tuple: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Tuple\0";
+pub const LV2_ATOM__URI: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/atom#URI\0";
+pub const LV2_ATOM__URID: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#URID\0";
+pub const LV2_ATOM__Vector: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#Vector\0";
+pub const LV2_ATOM__atomTransfer: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/atom#atomTransfer\0";
+pub const LV2_ATOM__beatTime: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#beatTime\0";
+pub const LV2_ATOM__bufferType: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/atom#bufferType\0";
+pub const LV2_ATOM__childType: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/atom#childType\0";
+pub const LV2_ATOM__eventTransfer: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/atom#eventTransfer\0";
+pub const LV2_ATOM__frameTime: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/atom#frameTime\0";
+pub const LV2_ATOM__supports: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#supports\0";
+pub const LV2_ATOM__timeUnit: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#timeUnit\0";
+pub const LV2_ATOM_REFERENCE_TYPE: u32 = 0;
+pub const LV2_URID_URI: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/urid\0";
+pub const LV2_URID_PREFIX: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/urid#\0";
+pub const LV2_URID__map: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/urid#map\0";
+pub const LV2_URID__unmap: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/urid#unmap\0";
+pub const LV2_URID_MAP_URI: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/urid#map\0";
+pub const LV2_URID_UNMAP_URI: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/urid#unmap\0";
+pub const LV2_BUF_SIZE_URI: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/buf-size\0";
+pub const LV2_BUF_SIZE_PREFIX: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/buf-size#\0";
+pub const LV2_BUF_SIZE__boundedBlockLength: &'static [u8; 53usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#boundedBlockLength\0";
+pub const LV2_BUF_SIZE__fixedBlockLength: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#fixedBlockLength\0";
+pub const LV2_BUF_SIZE__maxBlockLength: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#maxBlockLength\0";
+pub const LV2_BUF_SIZE__minBlockLength: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#minBlockLength\0";
+pub const LV2_BUF_SIZE__nominalBlockLength: &'static [u8; 53usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#nominalBlockLength\0";
+pub const LV2_BUF_SIZE__powerOf2BlockLength: &'static [u8; 54usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#powerOf2BlockLength\0";
+pub const LV2_BUF_SIZE__sequenceSize: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#sequenceSize\0";
+pub const LV2_CORE_URI: &'static [u8; 29usize] = b"http://lv2plug.in/ns/lv2core\0";
+pub const LV2_CORE_PREFIX: &'static [u8; 30usize] = b"http://lv2plug.in/ns/lv2core#\0";
+pub const LV2_CORE__AllpassPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#AllpassPlugin\0";
+pub const LV2_CORE__AmplifierPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#AmplifierPlugin\0";
+pub const LV2_CORE__AnalyserPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#AnalyserPlugin\0";
+pub const LV2_CORE__AudioPort: &'static [u8; 39usize] = b"http://lv2plug.in/ns/lv2core#AudioPort\0";
+pub const LV2_CORE__BandpassPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#BandpassPlugin\0";
+pub const LV2_CORE__CVPort: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#CVPort\0";
+pub const LV2_CORE__ChorusPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#ChorusPlugin\0";
+pub const LV2_CORE__CombPlugin: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#CombPlugin\0";
+pub const LV2_CORE__CompressorPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#CompressorPlugin\0";
+pub const LV2_CORE__ConstantPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#ConstantPlugin\0";
+pub const LV2_CORE__ControlPort: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#ControlPort\0";
+pub const LV2_CORE__ConverterPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#ConverterPlugin\0";
+pub const LV2_CORE__DelayPlugin: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#DelayPlugin\0";
+pub const LV2_CORE__DistortionPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#DistortionPlugin\0";
+pub const LV2_CORE__DynamicsPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#DynamicsPlugin\0";
+pub const LV2_CORE__EQPlugin: &'static [u8; 38usize] = b"http://lv2plug.in/ns/lv2core#EQPlugin\0";
+pub const LV2_CORE__EnvelopePlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#EnvelopePlugin\0";
+pub const LV2_CORE__ExpanderPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#ExpanderPlugin\0";
+pub const LV2_CORE__ExtensionData: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#ExtensionData\0";
+pub const LV2_CORE__Feature: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#Feature\0";
+pub const LV2_CORE__FilterPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#FilterPlugin\0";
+pub const LV2_CORE__FlangerPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#FlangerPlugin\0";
+pub const LV2_CORE__FunctionPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#FunctionPlugin\0";
+pub const LV2_CORE__GatePlugin: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#GatePlugin\0";
+pub const LV2_CORE__GeneratorPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#GeneratorPlugin\0";
+pub const LV2_CORE__HighpassPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#HighpassPlugin\0";
+pub const LV2_CORE__InputPort: &'static [u8; 39usize] = b"http://lv2plug.in/ns/lv2core#InputPort\0";
+pub const LV2_CORE__InstrumentPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#InstrumentPlugin\0";
+pub const LV2_CORE__LimiterPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#LimiterPlugin\0";
+pub const LV2_CORE__LowpassPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#LowpassPlugin\0";
+pub const LV2_CORE__MixerPlugin: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#MixerPlugin\0";
+pub const LV2_CORE__ModulatorPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#ModulatorPlugin\0";
+pub const LV2_CORE__MultiEQPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#MultiEQPlugin\0";
+pub const LV2_CORE__OscillatorPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#OscillatorPlugin\0";
+pub const LV2_CORE__OutputPort: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#OutputPort\0";
+pub const LV2_CORE__ParaEQPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#ParaEQPlugin\0";
+pub const LV2_CORE__PhaserPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#PhaserPlugin\0";
+pub const LV2_CORE__PitchPlugin: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#PitchPlugin\0";
+pub const LV2_CORE__Plugin: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#Plugin\0";
+pub const LV2_CORE__PluginBase: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#PluginBase\0";
+pub const LV2_CORE__Point: &'static [u8; 35usize] = b"http://lv2plug.in/ns/lv2core#Point\0";
+pub const LV2_CORE__Port: &'static [u8; 34usize] = b"http://lv2plug.in/ns/lv2core#Port\0";
+pub const LV2_CORE__PortProperty: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#PortProperty\0";
+pub const LV2_CORE__Resource: &'static [u8; 38usize] = b"http://lv2plug.in/ns/lv2core#Resource\0";
+pub const LV2_CORE__ReverbPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#ReverbPlugin\0";
+pub const LV2_CORE__ScalePoint: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#ScalePoint\0";
+pub const LV2_CORE__SimulatorPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#SimulatorPlugin\0";
+pub const LV2_CORE__SpatialPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#SpatialPlugin\0";
+pub const LV2_CORE__Specification: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#Specification\0";
+pub const LV2_CORE__SpectralPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#SpectralPlugin\0";
+pub const LV2_CORE__UtilityPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#UtilityPlugin\0";
+pub const LV2_CORE__WaveshaperPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#WaveshaperPlugin\0";
+pub const LV2_CORE__appliesTo: &'static [u8; 39usize] = b"http://lv2plug.in/ns/lv2core#appliesTo\0";
+pub const LV2_CORE__binary: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#binary\0";
+pub const LV2_CORE__connectionOptional: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/lv2core#connectionOptional\0";
+pub const LV2_CORE__control: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#control\0";
+pub const LV2_CORE__default: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#default\0";
+pub const LV2_CORE__designation: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#designation\0";
+pub const LV2_CORE__documentation: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#documentation\0";
+pub const LV2_CORE__enumeration: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#enumeration\0";
+pub const LV2_CORE__extensionData: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#extensionData\0";
+pub const LV2_CORE__freeWheeling: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#freeWheeling\0";
+pub const LV2_CORE__hardRTCapable: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#hardRTCapable\0";
+pub const LV2_CORE__inPlaceBroken: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#inPlaceBroken\0";
+pub const LV2_CORE__index: &'static [u8; 35usize] = b"http://lv2plug.in/ns/lv2core#index\0";
+pub const LV2_CORE__integer: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#integer\0";
+pub const LV2_CORE__isLive: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#isLive\0";
+pub const LV2_CORE__latency: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#latency\0";
+pub const LV2_CORE__maximum: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#maximum\0";
+pub const LV2_CORE__microVersion: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#microVersion\0";
+pub const LV2_CORE__minimum: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#minimum\0";
+pub const LV2_CORE__minorVersion: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#minorVersion\0";
+pub const LV2_CORE__name: &'static [u8; 34usize] = b"http://lv2plug.in/ns/lv2core#name\0";
+pub const LV2_CORE__optionalFeature: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#optionalFeature\0";
+pub const LV2_CORE__port: &'static [u8; 34usize] = b"http://lv2plug.in/ns/lv2core#port\0";
+pub const LV2_CORE__portProperty: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#portProperty\0";
+pub const LV2_CORE__project: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#project\0";
+pub const LV2_CORE__prototype: &'static [u8; 39usize] = b"http://lv2plug.in/ns/lv2core#prototype\0";
+pub const LV2_CORE__reportsLatency: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#reportsLatency\0";
+pub const LV2_CORE__requiredFeature: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#requiredFeature\0";
+pub const LV2_CORE__sampleRate: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#sampleRate\0";
+pub const LV2_CORE__scalePoint: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#scalePoint\0";
+pub const LV2_CORE__symbol: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#symbol\0";
+pub const LV2_CORE__toggled: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#toggled\0";
+pub const LV2_DATA_ACCESS_URI: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/data-access\0";
+pub const LV2_DATA_ACCESS_PREFIX: &'static [u8; 38usize] =
+    b"http://lv2plug.in/ns/ext/data-access#\0";
+pub const LV2_DYN_MANIFEST_URI: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/dynmanifest\0";
+pub const LV2_DYN_MANIFEST_PREFIX: &'static [u8; 38usize] =
+    b"http://lv2plug.in/ns/ext/dynmanifest#\0";
+pub const LV2_EVENT_URI: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/event\0";
+pub const LV2_EVENT_PREFIX: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/event#\0";
+pub const LV2_EVENT__Event: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/event#Event\0";
+pub const LV2_EVENT__EventPort: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/event#EventPort\0";
+pub const LV2_EVENT__FrameStamp: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/event#FrameStamp\0";
+pub const LV2_EVENT__TimeStamp: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/event#TimeStamp\0";
+pub const LV2_EVENT__generatesTimeStamp: &'static [u8; 50usize] =
+    b"http://lv2plug.in/ns/ext/event#generatesTimeStamp\0";
+pub const LV2_EVENT__generic: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/event#generic\0";
+pub const LV2_EVENT__inheritsEvent: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/event#inheritsEvent\0";
+pub const LV2_EVENT__inheritsTimeStamp: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/event#inheritsTimeStamp\0";
+pub const LV2_EVENT__supportsEvent: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/event#supportsEvent\0";
+pub const LV2_EVENT__supportsTimeStamp: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/event#supportsTimeStamp\0";
+pub const LV2_EVENT_AUDIO_STAMP: u32 = 0;
+pub const LV2_INSTANCE_ACCESS_URI: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/instance-access\0";
+pub const LV2_LOG_URI: &'static [u8; 29usize] = b"http://lv2plug.in/ns/ext/log\0";
+pub const LV2_LOG_PREFIX: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/log#\0";
+pub const LV2_LOG__Entry: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/log#Entry\0";
+pub const LV2_LOG__Error: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/log#Error\0";
+pub const LV2_LOG__Note: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/log#Note\0";
+pub const LV2_LOG__Trace: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/log#Trace\0";
+pub const LV2_LOG__Warning: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/log#Warning\0";
+pub const LV2_LOG__log: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/log#log\0";
+pub const LV2_MIDI_URI: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/midi\0";
+pub const LV2_MIDI_PREFIX: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/midi#\0";
+pub const LV2_MIDI__ActiveSense: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/midi#ActiveSense\0";
+pub const LV2_MIDI__Aftertouch: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#Aftertouch\0";
+pub const LV2_MIDI__Bender: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/midi#Bender\0";
+pub const LV2_MIDI__ChannelPressure: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/midi#ChannelPressure\0";
+pub const LV2_MIDI__Chunk: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#Chunk\0";
+pub const LV2_MIDI__Clock: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#Clock\0";
+pub const LV2_MIDI__Continue: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/midi#Continue\0";
+pub const LV2_MIDI__Controller: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#Controller\0";
+pub const LV2_MIDI__MidiEvent: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/midi#MidiEvent\0";
+pub const LV2_MIDI__NoteOff: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/midi#NoteOff\0";
+pub const LV2_MIDI__NoteOn: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/midi#NoteOn\0";
+pub const LV2_MIDI__ProgramChange: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/midi#ProgramChange\0";
+pub const LV2_MIDI__QuarterFrame: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#QuarterFrame\0";
+pub const LV2_MIDI__Reset: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#Reset\0";
+pub const LV2_MIDI__SongPosition: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#SongPosition\0";
+pub const LV2_MIDI__SongSelect: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#SongSelect\0";
+pub const LV2_MIDI__Start: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#Start\0";
+pub const LV2_MIDI__Stop: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/midi#Stop\0";
+pub const LV2_MIDI__SystemCommon: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#SystemCommon\0";
+pub const LV2_MIDI__SystemExclusive: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/midi#SystemExclusive\0";
+pub const LV2_MIDI__SystemMessage: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/midi#SystemMessage\0";
+pub const LV2_MIDI__SystemRealtime: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/midi#SystemRealtime\0";
+pub const LV2_MIDI__Tick: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/midi#Tick\0";
+pub const LV2_MIDI__TuneRequest: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/midi#TuneRequest\0";
+pub const LV2_MIDI__VoiceMessage: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#VoiceMessage\0";
+pub const LV2_MIDI__benderValue: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/midi#benderValue\0";
+pub const LV2_MIDI__binding: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/midi#binding\0";
+pub const LV2_MIDI__byteNumber: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#byteNumber\0";
+pub const LV2_MIDI__channel: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/midi#channel\0";
+pub const LV2_MIDI__chunk: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#chunk\0";
+pub const LV2_MIDI__controllerNumber: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/midi#controllerNumber\0";
+pub const LV2_MIDI__controllerValue: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/midi#controllerValue\0";
+pub const LV2_MIDI__noteNumber: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#noteNumber\0";
+pub const LV2_MIDI__pressure: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/midi#pressure\0";
+pub const LV2_MIDI__programNumber: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/midi#programNumber\0";
+pub const LV2_MIDI__property: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/midi#property\0";
+pub const LV2_MIDI__songNumber: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#songNumber\0";
+pub const LV2_MIDI__songPosition: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#songPosition\0";
+pub const LV2_MIDI__status: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/midi#status\0";
+pub const LV2_MIDI__statusMask: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#statusMask\0";
+pub const LV2_MIDI__velocity: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/midi#velocity\0";
+pub const LV2_MORPH_URI: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/morph\0";
+pub const LV2_MORPH_PREFIX: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/morph#\0";
+pub const LV2_MORPH__AutoMorphPort: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/morph#AutoMorphPort\0";
+pub const LV2_MORPH__MorphPort: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/morph#MorphPort\0";
+pub const LV2_MORPH__interface: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/morph#interface\0";
+pub const LV2_MORPH__supportsType: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/morph#supportsType\0";
+pub const LV2_MORPH__currentType: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/morph#currentType\0";
+pub const LV2_OPTIONS_URI: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/options\0";
+pub const LV2_OPTIONS_PREFIX: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/options#\0";
+pub const LV2_OPTIONS__Option: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/options#Option\0";
+pub const LV2_OPTIONS__interface: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/options#interface\0";
+pub const LV2_OPTIONS__options: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/options#options\0";
+pub const LV2_OPTIONS__requiredOption: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/options#requiredOption\0";
+pub const LV2_OPTIONS__supportedOption: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/options#supportedOption\0";
+pub const LV2_PARAMETERS_URI: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/parameters\0";
+pub const LV2_PARAMETERS_PREFIX: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/parameters#\0";
+pub const LV2_PARAMETERS__CompressorControls: &'static [u8; 55usize] =
+    b"http://lv2plug.in/ns/ext/parameters#CompressorControls\0";
+pub const LV2_PARAMETERS__ControlGroup: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/parameters#ControlGroup\0";
+pub const LV2_PARAMETERS__EnvelopeControls: &'static [u8; 53usize] =
+    b"http://lv2plug.in/ns/ext/parameters#EnvelopeControls\0";
+pub const LV2_PARAMETERS__FilterControls: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/ext/parameters#FilterControls\0";
+pub const LV2_PARAMETERS__OscillatorControls: &'static [u8; 55usize] =
+    b"http://lv2plug.in/ns/ext/parameters#OscillatorControls\0";
+pub const LV2_PARAMETERS__amplitude: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/parameters#amplitude\0";
+pub const LV2_PARAMETERS__attack: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/parameters#attack\0";
+pub const LV2_PARAMETERS__bypass: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/parameters#bypass\0";
+pub const LV2_PARAMETERS__cutoffFrequency: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/ext/parameters#cutoffFrequency\0";
+pub const LV2_PARAMETERS__decay: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/parameters#decay\0";
+pub const LV2_PARAMETERS__delay: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/parameters#delay\0";
+pub const LV2_PARAMETERS__dryLevel: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/parameters#dryLevel\0";
+pub const LV2_PARAMETERS__frequency: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/parameters#frequency\0";
+pub const LV2_PARAMETERS__gain: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/parameters#gain\0";
+pub const LV2_PARAMETERS__hold: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/parameters#hold\0";
+pub const LV2_PARAMETERS__pulseWidth: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/parameters#pulseWidth\0";
+pub const LV2_PARAMETERS__ratio: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/parameters#ratio\0";
+pub const LV2_PARAMETERS__release: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/parameters#release\0";
+pub const LV2_PARAMETERS__resonance: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/parameters#resonance\0";
+pub const LV2_PARAMETERS__sampleRate: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/parameters#sampleRate\0";
+pub const LV2_PARAMETERS__sustain: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/parameters#sustain\0";
+pub const LV2_PARAMETERS__threshold: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/parameters#threshold\0";
+pub const LV2_PARAMETERS__waveform: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/parameters#waveform\0";
+pub const LV2_PARAMETERS__wetDryRatio: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/parameters#wetDryRatio\0";
+pub const LV2_PARAMETERS__wetLevel: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/parameters#wetLevel\0";
+pub const LV2_PATCH_URI: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/patch\0";
+pub const LV2_PATCH_PREFIX: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/patch#\0";
+pub const LV2_PATCH__Ack: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#Ack\0";
+pub const LV2_PATCH__Delete: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/patch#Delete\0";
+pub const LV2_PATCH__Copy: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/patch#Copy\0";
+pub const LV2_PATCH__Error: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/patch#Error\0";
+pub const LV2_PATCH__Get: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#Get\0";
+pub const LV2_PATCH__Message: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#Message\0";
+pub const LV2_PATCH__Move: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/patch#Move\0";
+pub const LV2_PATCH__Patch: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/patch#Patch\0";
+pub const LV2_PATCH__Post: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/patch#Post\0";
+pub const LV2_PATCH__Put: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#Put\0";
+pub const LV2_PATCH__Request: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#Request\0";
+pub const LV2_PATCH__Response: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#Response\0";
+pub const LV2_PATCH__Set: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#Set\0";
+pub const LV2_PATCH__accept: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/patch#accept\0";
+pub const LV2_PATCH__add: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#add\0";
+pub const LV2_PATCH__body: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/patch#body\0";
+pub const LV2_PATCH__context: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#context\0";
+pub const LV2_PATCH__destination: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/patch#destination\0";
+pub const LV2_PATCH__property: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#property\0";
+pub const LV2_PATCH__readable: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#readable\0";
+pub const LV2_PATCH__remove: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/patch#remove\0";
+pub const LV2_PATCH__request: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#request\0";
+pub const LV2_PATCH__subject: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#subject\0";
+pub const LV2_PATCH__sequenceNumber: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/patch#sequenceNumber\0";
+pub const LV2_PATCH__value: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/patch#value\0";
+pub const LV2_PATCH__wildcard: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#wildcard\0";
+pub const LV2_PATCH__writable: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#writable\0";
+pub const LV2_PORT_GROUPS_URI: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/port-groups\0";
+pub const LV2_PORT_GROUPS_PREFIX: &'static [u8; 38usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#\0";
+pub const LV2_PORT_GROUPS__DiscreteGroup: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#DiscreteGroup\0";
+pub const LV2_PORT_GROUPS__Element: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#Element\0";
+pub const LV2_PORT_GROUPS__FivePointOneGroup: &'static [u8; 55usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#FivePointOneGroup\0";
+pub const LV2_PORT_GROUPS__FivePointZeroGroup: &'static [u8; 56usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#FivePointZeroGroup\0";
+pub const LV2_PORT_GROUPS__FourPointZeroGroup: &'static [u8; 56usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#FourPointZeroGroup\0";
+pub const LV2_PORT_GROUPS__Group: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#Group\0";
+pub const LV2_PORT_GROUPS__InputGroup: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#InputGroup\0";
+pub const LV2_PORT_GROUPS__MidSideGroup: &'static [u8; 50usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#MidSideGroup\0";
+pub const LV2_PORT_GROUPS__MonoGroup: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#MonoGroup\0";
+pub const LV2_PORT_GROUPS__OutputGroup: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#OutputGroup\0";
+pub const LV2_PORT_GROUPS__SevenPointOneGroup: &'static [u8; 56usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#SevenPointOneGroup\0";
+pub const LV2_PORT_GROUPS__SevenPointOneWideGroup: &'static [u8; 60usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#SevenPointOneWideGroup\0";
+pub const LV2_PORT_GROUPS__SixPointOneGroup: &'static [u8; 54usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#SixPointOneGroup\0";
+pub const LV2_PORT_GROUPS__StereoGroup: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#StereoGroup\0";
+pub const LV2_PORT_GROUPS__ThreePointZeroGroup: &'static [u8; 57usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#ThreePointZeroGroup\0";
+pub const LV2_PORT_GROUPS__center: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#center\0";
+pub const LV2_PORT_GROUPS__centerLeft: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#centerLeft\0";
+pub const LV2_PORT_GROUPS__centerRight: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#centerRight\0";
+pub const LV2_PORT_GROUPS__element: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#element\0";
+pub const LV2_PORT_GROUPS__group: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#group\0";
+pub const LV2_PORT_GROUPS__left: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#left\0";
+pub const LV2_PORT_GROUPS__lowFrequencyEffects: &'static [u8; 57usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#lowFrequencyEffects\0";
+pub const LV2_PORT_GROUPS__mainInput: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#mainInput\0";
+pub const LV2_PORT_GROUPS__mainOutput: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#mainOutput\0";
+pub const LV2_PORT_GROUPS__rearCenter: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#rearCenter\0";
+pub const LV2_PORT_GROUPS__rearLeft: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#rearLeft\0";
+pub const LV2_PORT_GROUPS__rearRight: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#rearRight\0";
+pub const LV2_PORT_GROUPS__right: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#right\0";
+pub const LV2_PORT_GROUPS__side: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#side\0";
+pub const LV2_PORT_GROUPS__sideChainOf: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#sideChainOf\0";
+pub const LV2_PORT_GROUPS__sideLeft: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#sideLeft\0";
+pub const LV2_PORT_GROUPS__sideRight: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#sideRight\0";
+pub const LV2_PORT_GROUPS__source: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#source\0";
+pub const LV2_PORT_GROUPS__subGroupOf: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#subGroupOf\0";
+pub const LV2_PORT_PROPS_URI: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/port-props\0";
+pub const LV2_PORT_PROPS_PREFIX: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/port-props#\0";
+pub const LV2_PORT_PROPS__causesArtifacts: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/ext/port-props#causesArtifacts\0";
+pub const LV2_PORT_PROPS__continuousCV: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-props#continuousCV\0";
+pub const LV2_PORT_PROPS__discreteCV: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-props#discreteCV\0";
+pub const LV2_PORT_PROPS__displayPriority: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/ext/port-props#displayPriority\0";
+pub const LV2_PORT_PROPS__expensive: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/port-props#expensive\0";
+pub const LV2_PORT_PROPS__hasStrictBounds: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/ext/port-props#hasStrictBounds\0";
+pub const LV2_PORT_PROPS__logarithmic: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-props#logarithmic\0";
+pub const LV2_PORT_PROPS__notAutomatic: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-props#notAutomatic\0";
+pub const LV2_PORT_PROPS__notOnGUI: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/port-props#notOnGUI\0";
+pub const LV2_PORT_PROPS__rangeSteps: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-props#rangeSteps\0";
+pub const LV2_PORT_PROPS__supportsStrictBounds: &'static [u8; 57usize] =
+    b"http://lv2plug.in/ns/ext/port-props#supportsStrictBounds\0";
+pub const LV2_PORT_PROPS__trigger: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/port-props#trigger\0";
+pub const LV2_PRESETS_URI: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/presets\0";
+pub const LV2_PRESETS_PREFIX: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/presets#\0";
+pub const LV2_PRESETS__Bank: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/presets#Bank\0";
+pub const LV2_PRESETS__Preset: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/presets#Preset\0";
+pub const LV2_PRESETS__bank: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/presets#bank\0";
+pub const LV2_PRESETS__preset: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/presets#preset\0";
+pub const LV2_PRESETS__value: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/presets#value\0";
+pub const LV2_RESIZE_PORT_URI: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/resize-port\0";
+pub const LV2_RESIZE_PORT_PREFIX: &'static [u8; 38usize] =
+    b"http://lv2plug.in/ns/ext/resize-port#\0";
+pub const LV2_RESIZE_PORT__asLargeAs: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/resize-port#asLargeAs\0";
+pub const LV2_RESIZE_PORT__minimumSize: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/resize-port#minimumSize\0";
+pub const LV2_RESIZE_PORT__resize: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/resize-port#resize\0";
+pub const LV2_STATE_URI: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/state\0";
+pub const LV2_STATE_PREFIX: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/state#\0";
+pub const LV2_STATE__State: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/state#State\0";
+pub const LV2_STATE__interface: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/state#interface\0";
+pub const LV2_STATE__loadDefaultState: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/state#loadDefaultState\0";
+pub const LV2_STATE__freePath: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/state#freePath\0";
+pub const LV2_STATE__makePath: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/state#makePath\0";
+pub const LV2_STATE__mapPath: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/state#mapPath\0";
+pub const LV2_STATE__state: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/state#state\0";
+pub const LV2_STATE__threadSafeRestore: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/state#threadSafeRestore\0";
+pub const LV2_STATE__StateChanged: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/state#StateChanged\0";
+pub const LV2_TIME_URI: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/time\0";
+pub const LV2_TIME_PREFIX: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/time#\0";
+pub const LV2_TIME__Time: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/time#Time\0";
+pub const LV2_TIME__Position: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/time#Position\0";
+pub const LV2_TIME__Rate: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/time#Rate\0";
+pub const LV2_TIME__position: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/time#position\0";
+pub const LV2_TIME__barBeat: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/time#barBeat\0";
+pub const LV2_TIME__bar: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/time#bar\0";
+pub const LV2_TIME__beat: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/time#beat\0";
+pub const LV2_TIME__beatUnit: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/time#beatUnit\0";
+pub const LV2_TIME__beatsPerBar: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/time#beatsPerBar\0";
+pub const LV2_TIME__beatsPerMinute: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/time#beatsPerMinute\0";
+pub const LV2_TIME__frame: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/time#frame\0";
+pub const LV2_TIME__framesPerSecond: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/time#framesPerSecond\0";
+pub const LV2_TIME__speed: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/time#speed\0";
+pub const LV2_UI_URI: &'static [u8; 35usize] = b"http://lv2plug.in/ns/extensions/ui\0";
+pub const LV2_UI_PREFIX: &'static [u8; 36usize] = b"http://lv2plug.in/ns/extensions/ui#\0";
+pub const LV2_UI__CocoaUI: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/ui#CocoaUI\0";
+pub const LV2_UI__Gtk3UI: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#Gtk3UI\0";
+pub const LV2_UI__GtkUI: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#GtkUI\0";
+pub const LV2_UI__PortNotification: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/extensions/ui#PortNotification\0";
+pub const LV2_UI__PortProtocol: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/extensions/ui#PortProtocol\0";
+pub const LV2_UI__Qt4UI: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#Qt4UI\0";
+pub const LV2_UI__Qt5UI: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#Qt5UI\0";
+pub const LV2_UI__UI: &'static [u8; 38usize] = b"http://lv2plug.in/ns/extensions/ui#UI\0";
+pub const LV2_UI__WindowsUI: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/ui#WindowsUI\0";
+pub const LV2_UI__X11UI: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#X11UI\0";
+pub const LV2_UI__binary: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#binary\0";
+pub const LV2_UI__fixedSize: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/ui#fixedSize\0";
+pub const LV2_UI__idleInterface: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/ui#idleInterface\0";
+pub const LV2_UI__noUserResize: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/extensions/ui#noUserResize\0";
+pub const LV2_UI__notifyType: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/extensions/ui#notifyType\0";
+pub const LV2_UI__parent: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#parent\0";
+pub const LV2_UI__plugin: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#plugin\0";
+pub const LV2_UI__portIndex: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/ui#portIndex\0";
+pub const LV2_UI__portMap: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/ui#portMap\0";
+pub const LV2_UI__portNotification: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/extensions/ui#portNotification\0";
+pub const LV2_UI__portSubscribe: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/ui#portSubscribe\0";
+pub const LV2_UI__protocol: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/extensions/ui#protocol\0";
+pub const LV2_UI__requestValue: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/extensions/ui#requestValue\0";
+pub const LV2_UI__floatProtocol: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/ui#floatProtocol\0";
+pub const LV2_UI__peakProtocol: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/extensions/ui#peakProtocol\0";
+pub const LV2_UI__resize: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#resize\0";
+pub const LV2_UI__showInterface: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/ui#showInterface\0";
+pub const LV2_UI__touch: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#touch\0";
+pub const LV2_UI__ui: &'static [u8; 38usize] = b"http://lv2plug.in/ns/extensions/ui#ui\0";
+pub const LV2_UI__updateRate: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/extensions/ui#updateRate\0";
+pub const LV2_UI__windowTitle: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/extensions/ui#windowTitle\0";
+pub const LV2_UI__scaleFactor: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/extensions/ui#scaleFactor\0";
+pub const LV2_UI__foregroundColor: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/extensions/ui#foregroundColor\0";
+pub const LV2_UI__backgroundColor: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/extensions/ui#backgroundColor\0";
+pub const LV2_UNITS_URI: &'static [u8; 38usize] = b"http://lv2plug.in/ns/extensions/units\0";
+pub const LV2_UNITS_PREFIX: &'static [u8; 39usize] = b"http://lv2plug.in/ns/extensions/units#\0";
+pub const LV2_UNITS__Conversion: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/units#Conversion\0";
+pub const LV2_UNITS__Unit: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#Unit\0";
+pub const LV2_UNITS__bar: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#bar\0";
+pub const LV2_UNITS__beat: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#beat\0";
+pub const LV2_UNITS__bpm: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#bpm\0";
+pub const LV2_UNITS__cent: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#cent\0";
+pub const LV2_UNITS__cm: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#cm\0";
+pub const LV2_UNITS__coef: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#coef\0";
+pub const LV2_UNITS__conversion: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/units#conversion\0";
+pub const LV2_UNITS__db: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#db\0";
+pub const LV2_UNITS__degree: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/units#degree\0";
+pub const LV2_UNITS__frame: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/extensions/units#frame\0";
+pub const LV2_UNITS__hz: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#hz\0";
+pub const LV2_UNITS__inch: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#inch\0";
+pub const LV2_UNITS__khz: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#khz\0";
+pub const LV2_UNITS__km: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#km\0";
+pub const LV2_UNITS__m: &'static [u8; 40usize] = b"http://lv2plug.in/ns/extensions/units#m\0";
+pub const LV2_UNITS__mhz: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#mhz\0";
+pub const LV2_UNITS__midiNote: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/extensions/units#midiNote\0";
+pub const LV2_UNITS__mile: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#mile\0";
+pub const LV2_UNITS__min: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#min\0";
+pub const LV2_UNITS__mm: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#mm\0";
+pub const LV2_UNITS__ms: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#ms\0";
+pub const LV2_UNITS__name: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#name\0";
+pub const LV2_UNITS__oct: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#oct\0";
+pub const LV2_UNITS__pc: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#pc\0";
+pub const LV2_UNITS__prefixConversion: &'static [u8; 55usize] =
+    b"http://lv2plug.in/ns/extensions/units#prefixConversion\0";
+pub const LV2_UNITS__render: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/units#render\0";
+pub const LV2_UNITS__s: &'static [u8; 40usize] = b"http://lv2plug.in/ns/extensions/units#s\0";
+pub const LV2_UNITS__semitone12TET: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/extensions/units#semitone12TET\0";
+pub const LV2_UNITS__symbol: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/units#symbol\0";
+pub const LV2_UNITS__unit: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#unit\0";
+pub const LV2_URI_MAP_URI: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/uri-map\0";
+pub const LV2_URI_MAP_PREFIX: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/uri-map#\0";
+pub const LV2_WORKER_URI: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/worker\0";
+pub const LV2_WORKER_PREFIX: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/worker#\0";
+pub const LV2_WORKER__interface: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/worker#interface\0";
+pub const LV2_WORKER__schedule: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/worker#schedule\0";
+pub type __uint8_t = ::std::os::raw::c_uchar;
+pub type __uint16_t = ::std::os::raw::c_ushort;
+pub type __int32_t = ::std::os::raw::c_int;
+pub type __uint32_t = ::std::os::raw::c_uint;
+pub type __int64_t = ::std::os::raw::c_longlong;
+#[doc = " The header of an atom:Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom {
+    #[doc = "< Size in bytes, not including type and size."]
+    pub size: u32,
+    #[doc = "< Type of this atom (mapped URI)."]
+    pub type_: u32,
+}
+#[doc = " An atom:Int or atom:Bool.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Int {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Integer value."]
+    pub body: i32,
+}
+#[doc = " An atom:Long.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Long {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Integer value."]
+    pub body: i64,
+}
+#[doc = " An atom:Float.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Float {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Floating point value."]
+    pub body: f32,
+}
+#[doc = " An atom:Double.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Double {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Floating point value."]
+    pub body: f64,
+}
+#[doc = " An atom:Bool.  May be cast to LV2_Atom."]
+pub type LV2_Atom_Bool = LV2_Atom_Int;
+#[doc = " An atom:URID.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_URID {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< URID."]
+    pub body: u32,
+}
+#[doc = " An atom:String.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_String {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+}
+#[doc = " The body of an atom:Literal."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Literal_Body {
+    #[doc = "< Datatype URID."]
+    pub datatype: u32,
+    #[doc = "< Language URID."]
+    pub lang: u32,
+}
+#[doc = " An atom:Literal.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Literal {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Literal_Body,
+}
+#[doc = " An atom:Tuple.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Tuple {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+}
+#[doc = " The body of an atom:Vector."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Vector_Body {
+    #[doc = "< The size of each element in the vector."]
+    pub child_size: u32,
+    #[doc = "< The type of each element in the vector."]
+    pub child_type: u32,
+}
+#[doc = " An atom:Vector.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Vector {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Vector_Body,
+}
+#[doc = " The body of an atom:Property (typically in an atom:Object)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Property_Body {
+    #[doc = "< Key (predicate) (mapped URI)."]
+    pub key: u32,
+    #[doc = "< Context URID (may be, and generally is, 0)."]
+    pub context: u32,
+    #[doc = "< Value atom header."]
+    pub value: LV2_Atom,
+}
+#[doc = " An atom:Property.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Property {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Property_Body,
+}
+#[doc = " The body of an atom:Object. May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Object_Body {
+    #[doc = "< URID, or 0 for blank."]
+    pub id: u32,
+    #[doc = "< Type URID (same as rdf:type, for fast dispatch)."]
+    pub otype: u32,
+}
+#[doc = " An atom:Object.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Object {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Object_Body,
+}
+#[doc = " The header of an atom:Event.  Note this type is NOT an LV2_Atom."]
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct LV2_Atom_Event {
+    pub time: LV2_Atom_Event__bindgen_ty_1,
+    #[doc = "< Event body atom header."]
+    pub body: LV2_Atom,
+}
+#[doc = " Time stamp.  Which type is valid is determined by context."]
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union LV2_Atom_Event__bindgen_ty_1 {
+    #[doc = "< Time in audio frames."]
+    pub frames: i64,
+    #[doc = "< Time in beats."]
+    pub beats: f64,
+    _bindgen_union_align: [u32; 2usize],
+}
+#[doc = "The body of an atom:Sequence (a sequence of events)."]
+#[doc = ""]
+#[doc = "The unit field is either a URID that described an appropriate time stamp"]
+#[doc = "type, or may be 0 where a default stamp type is known.  For"]
+#[doc = "LV2_Descriptor::run(), the default stamp type is audio frames."]
+#[doc = ""]
+#[doc = "The contents of a sequence is a series of LV2_Atom_Event, each aligned"]
+#[doc = "to 64-bits, for example:"]
+#[doc = "<pre>"]
+#[doc = "| Event 1 (size 6)                              | Event 2"]
+#[doc = "|       |       |       |       |       |       |       |       |"]
+#[doc = "| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |"]
+#[doc = "|FRAMES |SUBFRMS|TYPE   |SIZE   |DATADATADATAPAD|FRAMES |SUBFRMS|..."]
+#[doc = "</pre>"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Sequence_Body {
+    #[doc = "< URID of unit of event time stamps."]
+    pub unit: u32,
+    #[doc = "< Currently unused."]
+    pub pad: u32,
+}
+#[doc = " An atom:Sequence."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Sequence {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Sequence_Body,
+}
+pub type va_list = __builtin_va_list;
+#[doc = " A single entry in an Object query."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Object_Query {
+    #[doc = "< Key to query (input set by user)"]
+    pub key: u32,
+    #[doc = "< Found value (output set by query function)"]
+    pub value: *mut *const LV2_Atom,
+}
+extern "C" {
+    pub static LV2_ATOM_OBJECT_QUERY_END: LV2_Atom_Object_Query;
+}
+#[doc = "Opaque pointer to host data for LV2_URID_Map."]
+pub type LV2_URID_Map_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Opaque pointer to host data for LV2_URID_Unmap."]
+pub type LV2_URID_Unmap_Handle = *mut ::std::os::raw::c_void;
+#[doc = "URI mapped to an integer."]
+pub type LV2_URID = u32;
+#[doc = "URID Map Feature (LV2_URID__map)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_URID_Map {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "This MUST be passed to map_uri() whenever it is called."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub handle: LV2_URID_Map_Handle,
+    #[doc = "Get the numeric ID of a URI."]
+    #[doc = ""]
+    #[doc = "If the ID does not already exist, it will be created."]
+    #[doc = ""]
+    #[doc = "This function is referentially transparent; any number of calls with the"]
+    #[doc = "same arguments is guaranteed to return the same value over the life of a"]
+    #[doc = "plugin instance.  Note, however, that several URIs MAY resolve to the"]
+    #[doc = "same ID if the host considers those URIs equivalent."]
+    #[doc = ""]
+    #[doc = "This function is not necessarily very fast or RT-safe: plugins SHOULD"]
+    #[doc = "cache any IDs they might need in performance critical situations."]
+    #[doc = ""]
+    #[doc = "The return value 0 is reserved and indicates that an ID for that URI"]
+    #[doc = "could not be created for whatever reason.  However, hosts SHOULD NOT"]
+    #[doc = "return 0 from this function in non-exceptional circumstances (i.e. the"]
+    #[doc = "URI map SHOULD be dynamic)."]
+    #[doc = ""]
+    #[doc = "@param handle Must be the callback_data member of this struct."]
+    #[doc = "@param uri The URI to be mapped to an integer ID."]
+    pub map: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_URID_Map_Handle,
+            uri: *const ::std::os::raw::c_char,
+        ) -> LV2_URID,
+    >,
+}
+#[doc = "URI Unmap Feature (LV2_URID__unmap)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_URID_Unmap {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "This MUST be passed to unmap() whenever it is called."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub handle: LV2_URID_Unmap_Handle,
+    #[doc = "Get the URI for a previously mapped numeric ID."]
+    #[doc = ""]
+    #[doc = "Returns NULL if `urid` is not yet mapped.  Otherwise, the corresponding"]
+    #[doc = "URI is returned in a canonical form.  This MAY not be the exact same"]
+    #[doc = "string that was originally passed to LV2_URID_Map::map(), but it MUST be"]
+    #[doc = "an identical URI according to the URI syntax specification (RFC3986).  A"]
+    #[doc = "non-NULL return for a given `urid` will always be the same for the life"]
+    #[doc = "of the plugin.  Plugins that intend to perform string comparison on"]
+    #[doc = "unmapped URIs SHOULD first canonicalise URI strings with a call to"]
+    #[doc = "map_uri() followed by a call to unmap_uri()."]
+    #[doc = ""]
+    #[doc = "@param handle Must be the callback_data member of this struct."]
+    #[doc = "@param urid The ID to be mapped back to the URI string."]
+    pub unmap: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_URID_Unmap_Handle,
+            urid: LV2_URID,
+        ) -> *const ::std::os::raw::c_char,
+    >,
+}
+#[doc = " Handle for LV2_Atom_Forge_Sink."]
+pub type LV2_Atom_Forge_Sink_Handle = *mut ::std::os::raw::c_void;
+#[doc = " A reference to a chunk of written output."]
+pub type LV2_Atom_Forge_Ref = isize;
+#[doc = " Sink function for writing output.  See lv2_atom_forge_set_sink()."]
+pub type LV2_Atom_Forge_Sink = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_Atom_Forge_Sink_Handle,
+        buf: *const ::std::os::raw::c_void,
+        size: u32,
+    ) -> LV2_Atom_Forge_Ref,
+>;
+#[doc = " Function for resolving a reference.  See lv2_atom_forge_set_sink()."]
+pub type LV2_Atom_Forge_Deref_Func = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_Atom_Forge_Sink_Handle,
+        ref_: LV2_Atom_Forge_Ref,
+    ) -> *mut LV2_Atom,
+>;
+#[doc = " A stack frame used for keeping track of nested Atom containers."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Forge_Frame {
+    pub parent: *mut LV2_Atom_Forge_Frame,
+    pub ref_: LV2_Atom_Forge_Ref,
+}
+#[doc = " A \"forge\" for creating atoms by appending to a buffer."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Forge {
+    pub buf: *mut u8,
+    pub offset: u32,
+    pub size: u32,
+    pub sink: LV2_Atom_Forge_Sink,
+    pub deref: LV2_Atom_Forge_Deref_Func,
+    pub handle: LV2_Atom_Forge_Sink_Handle,
+    pub stack: *mut LV2_Atom_Forge_Frame,
+    pub Blank: LV2_URID,
+    pub Bool: LV2_URID,
+    pub Chunk: LV2_URID,
+    pub Double: LV2_URID,
+    pub Float: LV2_URID,
+    pub Int: LV2_URID,
+    pub Long: LV2_URID,
+    pub Literal: LV2_URID,
+    pub Object: LV2_URID,
+    pub Path: LV2_URID,
+    pub Property: LV2_URID,
+    pub Resource: LV2_URID,
+    pub Sequence: LV2_URID,
+    pub String: LV2_URID,
+    pub Tuple: LV2_URID,
+    pub URI: LV2_URID,
+    pub URID: LV2_URID,
+    pub Vector: LV2_URID,
+}
+#[doc = "Plugin Instance Handle."]
+#[doc = ""]
+#[doc = "This is a handle for one particular instance of a plugin.  It is valid to"]
+#[doc = "compare to NULL (or 0 for C++) but otherwise the host MUST NOT attempt to"]
+#[doc = "interpret it."]
+pub type LV2_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Feature."]
+#[doc = ""]
+#[doc = "Features allow hosts to make additional functionality available to plugins"]
+#[doc = "without requiring modification to the LV2 API.  Extensions may define new"]
+#[doc = "features and specify the `URI` and `data` to be used if necessary."]
+#[doc = "Some features, such as lv2:isLive, do not require the host to pass data."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Feature {
+    #[doc = "A globally unique, case-sensitive identifier (URI) for this feature."]
+    #[doc = ""]
+    #[doc = "This MUST be a valid URI string as defined by RFC 3986."]
+    pub URI: *const ::std::os::raw::c_char,
+    #[doc = "Pointer to arbitrary data."]
+    #[doc = ""]
+    #[doc = "The format of this data is defined by the extension which describes the"]
+    #[doc = "feature with the given `URI`."]
+    pub data: *mut ::std::os::raw::c_void,
+}
+#[doc = "Plugin Descriptor."]
+#[doc = ""]
+#[doc = "This structure provides the core functions necessary to instantiate and use"]
+#[doc = "a plugin."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Descriptor {
+    #[doc = "A globally unique, case-sensitive identifier for this plugin."]
+    #[doc = ""]
+    #[doc = "This MUST be a valid URI string as defined by RFC 3986.  All plugins with"]
+    #[doc = "the same URI MUST be compatible to some degree, see"]
+    #[doc = "http://lv2plug.in/ns/lv2core for details."]
+    pub URI: *const ::std::os::raw::c_char,
+    #[doc = "Instantiate the plugin."]
+    #[doc = ""]
+    #[doc = "Note that instance initialisation should generally occur in activate()"]
+    #[doc = "rather than here. If a host calls instantiate(), it MUST call cleanup()"]
+    #[doc = "at some point in the future."]
+    #[doc = ""]
+    #[doc = "@param descriptor Descriptor of the plugin to instantiate."]
+    #[doc = ""]
+    #[doc = "@param sample_rate Sample rate, in Hz, for the new plugin instance."]
+    #[doc = ""]
+    #[doc = "@param bundle_path Path to the LV2 bundle which contains this plugin"]
+    #[doc = "binary. It MUST include the trailing directory separator so that simply"]
+    #[doc = "appending a filename will yield the path to that file in the bundle."]
+    #[doc = ""]
+    #[doc = "@param features A NULL terminated array of LV2_Feature structs which"]
+    #[doc = "represent the features the host supports. Plugins may refuse to"]
+    #[doc = "instantiate if required features are not found here. However, hosts MUST"]
+    #[doc = "NOT use this as a discovery mechanism: instead, use the RDF data to"]
+    #[doc = "determine which features are required and do not attempt to instantiate"]
+    #[doc = "unsupported plugins at all. This parameter MUST NOT be NULL, i.e. a host"]
+    #[doc = "that supports no features MUST pass a single element array containing"]
+    #[doc = "NULL."]
+    #[doc = ""]
+    #[doc = "@return A handle for the new plugin instance, or NULL if instantiation"]
+    #[doc = "has failed."]
+    pub instantiate: ::std::option::Option<
+        unsafe extern "C" fn(
+            descriptor: *const LV2_Descriptor,
+            sample_rate: f64,
+            bundle_path: *const ::std::os::raw::c_char,
+            features: *const *const LV2_Feature,
+        ) -> LV2_Handle,
+    >,
+    #[doc = "Connect a port on a plugin instance to a memory location."]
+    #[doc = ""]
+    #[doc = "Plugin writers should be aware that the host may elect to use the same"]
+    #[doc = "buffer for more than one port and even use the same buffer for both"]
+    #[doc = "input and output (see lv2:inPlaceBroken in lv2.ttl)."]
+    #[doc = ""]
+    #[doc = "If the plugin has the feature lv2:hardRTCapable then there are various"]
+    #[doc = "things that the plugin MUST NOT do within the connect_port() function;"]
+    #[doc = "see lv2core.ttl for details."]
+    #[doc = ""]
+    #[doc = "connect_port() MUST be called at least once for each port before run()"]
+    #[doc = "is called, unless that port is lv2:connectionOptional. The plugin must"]
+    #[doc = "pay careful attention to the block size passed to run() since the block"]
+    #[doc = "allocated may only just be large enough to contain the data, and is not"]
+    #[doc = "guaranteed to remain constant between run() calls."]
+    #[doc = ""]
+    #[doc = "connect_port() may be called more than once for a plugin instance to"]
+    #[doc = "allow the host to change the buffers that the plugin is reading or"]
+    #[doc = "writing. These calls may be made before or after activate() or"]
+    #[doc = "deactivate() calls."]
+    #[doc = ""]
+    #[doc = "@param instance Plugin instance containing the port."]
+    #[doc = ""]
+    #[doc = "@param port Index of the port to connect. The host MUST NOT try to"]
+    #[doc = "connect a port index that is not defined in the plugin's RDF data. If"]
+    #[doc = "it does, the plugin's behaviour is undefined (a crash is likely)."]
+    #[doc = ""]
+    #[doc = "@param data_location Pointer to data of the type defined by the port"]
+    #[doc = "type in the plugin's RDF data (for example, an array of float for an"]
+    #[doc = "lv2:AudioPort). This pointer must be stored by the plugin instance and"]
+    #[doc = "used to read/write data when run() is called. Data present at the time"]
+    #[doc = "of the connect_port() call MUST NOT be considered meaningful."]
+    pub connect_port: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            port: u32,
+            data_location: *mut ::std::os::raw::c_void,
+        ),
+    >,
+    #[doc = "Initialise a plugin instance and activate it for use."]
+    #[doc = ""]
+    #[doc = "This is separated from instantiate() to aid real-time support and so"]
+    #[doc = "that hosts can reinitialise a plugin instance by calling deactivate()"]
+    #[doc = "and then activate(). In this case the plugin instance MUST reset all"]
+    #[doc = "state information dependent on the history of the plugin instance except"]
+    #[doc = "for any data locations provided by connect_port(). If there is nothing"]
+    #[doc = "for activate() to do then this field may be NULL."]
+    #[doc = ""]
+    #[doc = "When present, hosts MUST call this function once before run() is called"]
+    #[doc = "for the first time. This call SHOULD be made as close to the run() call"]
+    #[doc = "as possible and indicates to real-time plugins that they are now live,"]
+    #[doc = "however plugins MUST NOT rely on a prompt call to run() after"]
+    #[doc = "activate()."]
+    #[doc = ""]
+    #[doc = "The host MUST NOT call activate() again until deactivate() has been"]
+    #[doc = "called first. If a host calls activate(), it MUST call deactivate() at"]
+    #[doc = "some point in the future. Note that connect_port() may be called before"]
+    #[doc = "or after activate()."]
+    pub activate: ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle)>,
+    #[doc = "Run a plugin instance for a block."]
+    #[doc = ""]
+    #[doc = "Note that if an activate() function exists then it must be called before"]
+    #[doc = "run(). If deactivate() is called for a plugin instance then run() may"]
+    #[doc = "not be called until activate() has been called again."]
+    #[doc = ""]
+    #[doc = "If the plugin has the feature lv2:hardRTCapable then there are various"]
+    #[doc = "things that the plugin MUST NOT do within the run() function (see"]
+    #[doc = "lv2core.ttl for details)."]
+    #[doc = ""]
+    #[doc = "As a special case, when `sample_count` is 0, the plugin should update"]
+    #[doc = "any output ports that represent a single instant in time (for example,"]
+    #[doc = "control ports, but not audio ports). This is particularly useful for"]
+    #[doc = "latent plugins, which should update their latency output port so hosts"]
+    #[doc = "can pre-roll plugins to compute latency. Plugins MUST NOT crash when"]
+    #[doc = "`sample_count` is 0."]
+    #[doc = ""]
+    #[doc = "@param instance Instance to be run."]
+    #[doc = ""]
+    #[doc = "@param sample_count The block size (in samples) for which the plugin"]
+    #[doc = "instance must run."]
+    pub run: ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle, sample_count: u32)>,
+    #[doc = "Deactivate a plugin instance (counterpart to activate())."]
+    #[doc = ""]
+    #[doc = "Hosts MUST deactivate all activated instances after they have been run()"]
+    #[doc = "for the last time. This call SHOULD be made as close to the last run()"]
+    #[doc = "call as possible and indicates to real-time plugins that they are no"]
+    #[doc = "longer live, however plugins MUST NOT rely on prompt deactivation. If"]
+    #[doc = "there is nothing for deactivate() to do then this field may be NULL"]
+    #[doc = ""]
+    #[doc = "Deactivation is not similar to pausing since the plugin instance will be"]
+    #[doc = "reinitialised by activate(). However, deactivate() itself MUST NOT fully"]
+    #[doc = "reset plugin state. For example, the host may deactivate a plugin, then"]
+    #[doc = "store its state (using some extension to do so)."]
+    #[doc = ""]
+    #[doc = "Hosts MUST NOT call deactivate() unless activate() was previously"]
+    #[doc = "called. Note that connect_port() may be called before or after"]
+    #[doc = "deactivate()."]
+    pub deactivate: ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle)>,
+    #[doc = "Clean up a plugin instance (counterpart to instantiate())."]
+    #[doc = ""]
+    #[doc = "Once an instance of a plugin has been finished with it must be deleted"]
+    #[doc = "using this function. The instance handle passed ceases to be valid after"]
+    #[doc = "this call."]
+    #[doc = ""]
+    #[doc = "If activate() was called for a plugin instance then a corresponding call"]
+    #[doc = "to deactivate() MUST be made before cleanup() is called. Hosts MUST NOT"]
+    #[doc = "call cleanup() unless instantiate() was previously called."]
+    pub cleanup: ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle)>,
+    #[doc = "Return additional plugin data defined by some extenion."]
+    #[doc = ""]
+    #[doc = "A typical use of this facility is to return a struct containing function"]
+    #[doc = "pointers to extend the LV2_Descriptor API."]
+    #[doc = ""]
+    #[doc = "The actual type and meaning of the returned object MUST be specified"]
+    #[doc = "precisely by the extension. This function MUST return NULL for any"]
+    #[doc = "unsupported URI. If a plugin does not support any extension data, this"]
+    #[doc = "field may be NULL."]
+    #[doc = ""]
+    #[doc = "The host is never responsible for freeing the returned value."]
+    pub extension_data: ::std::option::Option<
+        unsafe extern "C" fn(uri: *const ::std::os::raw::c_char) -> *const ::std::os::raw::c_void,
+    >,
+}
+#[doc = "Type of the lv2_descriptor() function in a library (old discovery API)."]
+pub type LV2_Descriptor_Function =
+    ::std::option::Option<unsafe extern "C" fn(index: u32) -> *const LV2_Descriptor>;
+#[doc = "Handle for a library descriptor."]
+pub type LV2_Lib_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Descriptor for a plugin library."]
+#[doc = ""]
+#[doc = "To access a plugin library, the host creates an LV2_Lib_Descriptor via the"]
+#[doc = "lv2_lib_descriptor() function in the shared object."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Lib_Descriptor {
+    #[doc = "Opaque library data which must be passed as the first parameter to all"]
+    #[doc = "the methods of this struct."]
+    pub handle: LV2_Lib_Handle,
+    #[doc = "The total size of this struct.  This allows for this struct to be"]
+    #[doc = "expanded in the future if necessary.  This MUST be set by the library to"]
+    #[doc = "sizeof(LV2_Lib_Descriptor).  The host MUST NOT access any fields of this"]
+    #[doc = "struct beyond get_plugin() unless this field indicates they are present."]
+    pub size: u32,
+    #[doc = "Destroy this library descriptor and free all related resources."]
+    pub cleanup: ::std::option::Option<unsafe extern "C" fn(handle: LV2_Lib_Handle)>,
+    #[doc = "Plugin accessor."]
+    #[doc = ""]
+    #[doc = "Plugins are accessed by index using values from 0 upwards.  Out of range"]
+    #[doc = "indices MUST result in this function returning NULL, so the host can"]
+    #[doc = "enumerate plugins by increasing `index` until NULL is returned."]
+    pub get_plugin: ::std::option::Option<
+        unsafe extern "C" fn(handle: LV2_Lib_Handle, index: u32) -> *const LV2_Descriptor,
+    >,
+}
+#[doc = "Type of the lv2_lib_descriptor() function in an LV2 library."]
+pub type LV2_Lib_Descriptor_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        bundle_path: *const ::std::os::raw::c_char,
+        features: *const *const LV2_Feature,
+    ) -> *const LV2_Lib_Descriptor,
+>;
+#[doc = "The data field of the LV2_Feature for this extension."]
+#[doc = ""]
+#[doc = "To support this feature the host must pass an LV2_Feature struct to the"]
+#[doc = "instantiate method with URI \"http://lv2plug.in/ns/ext/data-access\""]
+#[doc = "and data pointed to an instance of this struct."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Extension_Data_Feature {
+    #[doc = "A pointer to a method the UI can call to get data (of a type specified"]
+    #[doc = "by some other extension) from the plugin."]
+    #[doc = ""]
+    #[doc = "This call never is never guaranteed to return anything, UIs should"]
+    #[doc = "degrade gracefully if direct access to the plugin data is not possible"]
+    #[doc = "(in which case this function will return NULL)."]
+    #[doc = ""]
+    #[doc = "This is for access to large data that can only possibly work if the UI"]
+    #[doc = "and plugin are running in the same process.  For all other things, use"]
+    #[doc = "the normal LV2 UI communication system."]
+    pub data_access: ::std::option::Option<
+        unsafe extern "C" fn(uri: *const ::std::os::raw::c_char) -> *const ::std::os::raw::c_void,
+    >,
+}
+#[doc = "Dynamic manifest generator handle."]
+#[doc = ""]
+#[doc = "This handle indicates a particular status of a dynamic manifest generator."]
+#[doc = "The host MUST NOT attempt to interpret it and, unlikely LV2_Handle, it is"]
+#[doc = "NOT even valid to compare this to NULL. The dynamic manifest generator MAY"]
+#[doc = "use it to reference internal data."]
+pub type LV2_Dyn_Manifest_Handle = *mut ::std::os::raw::c_void;
+pub const LV2_EVENT_PPQN: u32 = 3136573440;
+#[doc = "An LV2 event (header only)."]
+#[doc = ""]
+#[doc = "LV2 events are generic time-stamped containers for any type of event."]
+#[doc = "The type field defines the format of a given event's contents."]
+#[doc = ""]
+#[doc = "This struct defines the header of an LV2 event. An LV2 event is a single"]
+#[doc = "chunk of POD (plain old data), usually contained in a flat buffer (see"]
+#[doc = "LV2_EventBuffer below). Unless a required feature says otherwise, hosts may"]
+#[doc = "assume a deep copy of an LV2 event can be created safely using a simple:"]
+#[doc = ""]
+#[doc = "memcpy(ev_copy, ev, sizeof(LV2_Event) + ev->size);  (or equivalent)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Event {
+    #[doc = "The frames portion of timestamp. The units used here can optionally be"]
+    #[doc = "set for a port (with the lv2ev:timeUnits property), otherwise this is"]
+    #[doc = "audio frames, corresponding to the sample_count parameter of the LV2 run"]
+    #[doc = "method (frame 0 is the first frame for that call to run)."]
+    pub frames: u32,
+    #[doc = "The sub-frames portion of timestamp. The units used here can optionally"]
+    #[doc = "be set for a port (with the lv2ev:timeUnits property), otherwise this is"]
+    #[doc = "1/(2^32) of an audio frame."]
+    pub subframes: u32,
+    #[doc = "The type of this event, as a number which represents some URI"]
+    #[doc = "defining an event type. This value MUST be some value previously"]
+    #[doc = "returned from a call to the uri_to_id function defined in the LV2"]
+    #[doc = "URI map extension (see lv2_uri_map.h)."]
+    #[doc = "There are special rules which must be followed depending on the type"]
+    #[doc = "of an event. If the plugin recognizes an event type, the definition"]
+    #[doc = "of that event type will describe how to interpret the event, and"]
+    #[doc = "any required behaviour. Otherwise, if the type is 0, this event is a"]
+    #[doc = "non-POD event and lv2_event_unref MUST be called if the event is"]
+    #[doc = "'dropped' (see above). Even if the plugin does not understand an event,"]
+    #[doc = "it may pass the event through to an output by simply copying (and NOT"]
+    #[doc = "calling lv2_event_unref). These rules are designed to allow for generic"]
+    #[doc = "event handling plugins and large non-POD events, but with minimal hassle"]
+    #[doc = "on simple plugins that \"don't care\" about these more advanced features."]
+    pub type_: u16,
+    #[doc = "The size of the data portion of this event in bytes, which immediately"]
+    #[doc = "follows. The header size (12 bytes) is not included in this value."]
+    pub size: u16,
+}
+#[doc = "A buffer of LV2 events (header only)."]
+#[doc = ""]
+#[doc = "Like events (which this contains) an event buffer is a single chunk of POD:"]
+#[doc = "the entire buffer (including contents) can be copied with a single memcpy."]
+#[doc = "The first contained event begins sizeof(LV2_EventBuffer) bytes after the"]
+#[doc = "start of this struct."]
+#[doc = ""]
+#[doc = "After this header, the buffer contains an event header (defined by struct"]
+#[doc = "LV2_Event), followed by that event's contents (padded to 64 bits), followed"]
+#[doc = "by another header, etc:"]
+#[doc = ""]
+#[doc = "|       |       |       |       |       |       |"]
+#[doc = "| | | | | | | | | | | | | | | | | | | | | | | | |"]
+#[doc = "|FRAMES |SUBFRMS|TYP|LEN|DATA..DATA..PAD|FRAMES | ..."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Event_Buffer {
+    #[doc = "The contents of the event buffer. This may or may not reside in the"]
+    #[doc = "same block of memory as this header, plugins must not assume either."]
+    #[doc = "The host guarantees this points to at least capacity bytes of allocated"]
+    #[doc = "memory (though only size bytes of that are valid events)."]
+    pub data: *mut u8,
+    #[doc = "The size of this event header in bytes (including everything)."]
+    #[doc = ""]
+    #[doc = "This is to allow for extending this header in the future without"]
+    #[doc = "breaking binary compatibility. Whenever this header is copied,"]
+    #[doc = "it MUST be done using this field (and NOT the sizeof this struct)."]
+    pub header_size: u16,
+    #[doc = "The type of the time stamps for events in this buffer."]
+    #[doc = "As a special exception, '0' always means audio frames and subframes"]
+    #[doc = "(1/UINT32_MAX'th of a frame) in the sample rate passed to instantiate."]
+    #[doc = ""]
+    #[doc = "INPUTS: The host must set this field to the numeric ID of some URI"]
+    #[doc = "defining the meaning of the frames/subframes fields of contained events"]
+    #[doc = "(obtained by the LV2 URI Map uri_to_id function with the URI of this"]
+    #[doc = "extension as the 'map' argument, see lv2_uri_map.h).  The host must"]
+    #[doc = "never pass a plugin a buffer which uses a stamp type the plugin does not"]
+    #[doc = "'understand'. The value of this field must never change, except when"]
+    #[doc = "connect_port is called on the input port, at which time the host MUST"]
+    #[doc = "have set the stamp_type field to the value that will be used for all"]
+    #[doc = "subsequent run calls."]
+    #[doc = ""]
+    #[doc = "OUTPUTS: The plugin may set this to any value that has been returned"]
+    #[doc = "from uri_to_id with the URI of this extension for a 'map' argument."]
+    #[doc = "When connected to a buffer with connect_port, output ports MUST set this"]
+    #[doc = "field to the type of time stamp they will be writing. On any call to"]
+    #[doc = "connect_port on an event input port, the plugin may change this field on"]
+    #[doc = "any output port, it is the responsibility of the host to check if any of"]
+    #[doc = "these values have changed and act accordingly."]
+    pub stamp_type: u16,
+    #[doc = "The number of events in this buffer."]
+    #[doc = ""]
+    #[doc = "INPUTS: The host must set this field to the number of events contained"]
+    #[doc = "in the data buffer before calling run(). The plugin must not change"]
+    #[doc = "this field."]
+    #[doc = ""]
+    #[doc = "OUTPUTS: The plugin must set this field to the number of events it has"]
+    #[doc = "written to the buffer before returning from run(). Any initial value"]
+    #[doc = "should be ignored by the plugin."]
+    pub event_count: u32,
+    #[doc = "The size of the data buffer in bytes."]
+    #[doc = "This is set by the host and must not be changed by the plugin."]
+    #[doc = "The host is allowed to change this between run() calls."]
+    pub capacity: u32,
+    #[doc = "The size of the initial portion of the data buffer containing data."]
+    #[doc = ""]
+    #[doc = "INPUTS: The host must set this field to the number of bytes used"]
+    #[doc = "by all events it has written to the buffer (including headers)"]
+    #[doc = "before calling the plugin's run()."]
+    #[doc = "The plugin must not change this field."]
+    #[doc = ""]
+    #[doc = "OUTPUTS: The plugin must set this field to the number of bytes"]
+    #[doc = "used by all events it has written to the buffer (including headers)"]
+    #[doc = "before returning from run()."]
+    #[doc = "Any initial value should be ignored by the plugin."]
+    pub size: u32,
+}
+pub type LV2_Event_Callback_Data = *mut ::std::os::raw::c_void;
+#[doc = "Non-POD events feature."]
+#[doc = ""]
+#[doc = "To support this feature the host must pass an LV2_Feature struct to the"]
+#[doc = "plugin's instantiate method with URI \"http://lv2plug.in/ns/ext/event\""]
+#[doc = "and data pointed to an instance of this struct.  Note this feature"]
+#[doc = "is not mandatory to support the event extension."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Event_Feature {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "The plugin MUST pass this to any call to functions in this struct."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub callback_data: LV2_Event_Callback_Data,
+    #[doc = "Take a reference to a non-POD event."]
+    #[doc = ""]
+    #[doc = "If a plugin receives an event with type 0, it means the event is a"]
+    #[doc = "pointer to some object in memory and not a flat sequence of bytes"]
+    #[doc = "in the buffer. When receiving a non-POD event, the plugin already"]
+    #[doc = "has an implicit reference to the event. If the event is stored AND"]
+    #[doc = "passed to an output, lv2_event_ref MUST be called on that event."]
+    #[doc = "If the event is only stored OR passed through, this is not necessary"]
+    #[doc = "(as the plugin already has 1 implicit reference)."]
+    #[doc = ""]
+    #[doc = "@param event An event received at an input that will not be copied to"]
+    #[doc = "an output or stored in any way."]
+    #[doc = ""]
+    #[doc = "@param context The calling context. Like event types, this is a mapped"]
+    #[doc = "URI, see lv2_context.h. Simple plugin with just a run() method should"]
+    #[doc = "pass 0 here (the ID of the 'standard' LV2 run context). The host"]
+    #[doc = "guarantees that this function is realtime safe iff the context is"]
+    #[doc = "realtime safe."]
+    #[doc = ""]
+    #[doc = "PLUGINS THAT VIOLATE THESE RULES MAY CAUSE CRASHES AND MEMORY LEAKS."]
+    pub lv2_event_ref: ::std::option::Option<
+        unsafe extern "C" fn(callback_data: LV2_Event_Callback_Data, event: *mut LV2_Event) -> u32,
+    >,
+    #[doc = "Drop a reference to a non-POD event."]
+    #[doc = ""]
+    #[doc = "If a plugin receives an event with type 0, it means the event is a"]
+    #[doc = "pointer to some object in memory and not a flat sequence of bytes"]
+    #[doc = "in the buffer. If the plugin does not pass the event through to"]
+    #[doc = "an output or store it internally somehow, it MUST call this function"]
+    #[doc = "on the event (more information on using non-POD events below)."]
+    #[doc = ""]
+    #[doc = "@param event An event received at an input that will not be copied to an"]
+    #[doc = "output or stored in any way."]
+    #[doc = ""]
+    #[doc = "@param context The calling context. Like event types, this is a mapped"]
+    #[doc = "URI, see lv2_context.h. Simple plugin with just a run() method should"]
+    #[doc = "pass 0 here (the ID of the 'standard' LV2 run context). The host"]
+    #[doc = "guarantees that this function is realtime safe iff the context is"]
+    #[doc = "realtime safe."]
+    #[doc = ""]
+    #[doc = "PLUGINS THAT VIOLATE THESE RULES MAY CAUSE CRASHES AND MEMORY LEAKS."]
+    pub lv2_event_unref: ::std::option::Option<
+        unsafe extern "C" fn(callback_data: LV2_Event_Callback_Data, event: *mut LV2_Event) -> u32,
+    >,
+}
+#[doc = " An iterator over an LV2_Event_Buffer."]
+#[doc = ""]
+#[doc = " Multiple simultaneous read iterators over a single buffer is fine,"]
+#[doc = " but changing the buffer invalidates all iterators."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Event_Iterator {
+    pub buf: *mut LV2_Event_Buffer,
+    pub offset: u32,
+}
+#[doc = "Opaque data to host data for LV2_Log_Log."]
+pub type LV2_Log_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Log feature (LV2_LOG__log)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Log_Log {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "This MUST be passed to methods in this struct whenever they are called."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub handle: LV2_Log_Handle,
+    #[doc = "Log a message, passing format parameters directly."]
+    #[doc = ""]
+    #[doc = "The API of this function matches that of the standard C printf function,"]
+    #[doc = "except for the addition of the first two parameters.  This function may"]
+    #[doc = "be called from any non-realtime context, or from any context if `type`"]
+    #[doc = "is @ref LV2_LOG__Trace."]
+    pub printf: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_Log_Handle,
+            type_: LV2_URID,
+            fmt: *const ::std::os::raw::c_char,
+            ...
+        ) -> ::std::os::raw::c_int,
+    >,
+    #[doc = "Log a message, passing format parameters in a va_list."]
+    #[doc = ""]
+    #[doc = "The API of this function matches that of the standard C vprintf"]
+    #[doc = "function, except for the addition of the first two parameters.  This"]
+    #[doc = "function may be called from any non-realtime context, or from any"]
+    #[doc = "context if `type` is @ref LV2_LOG__Trace."]
+    pub vprintf: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_Log_Handle,
+            type_: LV2_URID,
+            fmt: *const ::std::os::raw::c_char,
+            ap: va_list,
+        ) -> ::std::os::raw::c_int,
+    >,
+}
+#[doc = "Logger convenience API state."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Log_Logger {
+    pub log: *mut LV2_Log_Log,
+    pub Error: LV2_URID,
+    pub Note: LV2_URID,
+    pub Trace: LV2_URID,
+    pub Warning: LV2_URID,
+}
+#[doc = "< Invalid Message"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_INVALID: LV2_Midi_Message_Type = 0;
+#[doc = "< Note Off"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_NOTE_OFF: LV2_Midi_Message_Type = 128;
+#[doc = "< Note On"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_NOTE_ON: LV2_Midi_Message_Type = 144;
+#[doc = "< Note Pressure"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_NOTE_PRESSURE: LV2_Midi_Message_Type = 160;
+#[doc = "< Controller"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_CONTROLLER: LV2_Midi_Message_Type = 176;
+#[doc = "< Program Change"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_PGM_CHANGE: LV2_Midi_Message_Type = 192;
+#[doc = "< Channel Pressure"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_CHANNEL_PRESSURE: LV2_Midi_Message_Type = 208;
+#[doc = "< Pitch Bender"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_BENDER: LV2_Midi_Message_Type = 224;
+#[doc = "< System Exclusive Begin"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_SYSTEM_EXCLUSIVE: LV2_Midi_Message_Type = 240;
+#[doc = "< MTC Quarter Frame"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_MTC_QUARTER: LV2_Midi_Message_Type = 241;
+#[doc = "< Song Position"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_SONG_POS: LV2_Midi_Message_Type = 242;
+#[doc = "< Song Select"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_SONG_SELECT: LV2_Midi_Message_Type = 243;
+#[doc = "< Tune Request"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_TUNE_REQUEST: LV2_Midi_Message_Type = 246;
+#[doc = "< Clock"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_CLOCK: LV2_Midi_Message_Type = 248;
+#[doc = "< Start"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_START: LV2_Midi_Message_Type = 250;
+#[doc = "< Continue"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_CONTINUE: LV2_Midi_Message_Type = 251;
+#[doc = "< Stop"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_STOP: LV2_Midi_Message_Type = 252;
+#[doc = "< Active Sensing"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_ACTIVE_SENSE: LV2_Midi_Message_Type = 254;
+#[doc = "< Reset"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_RESET: LV2_Midi_Message_Type = 255;
+#[doc = "MIDI Message Type."]
+#[doc = ""]
+#[doc = "This includes both voice messages (which have a channel) and system messages"]
+#[doc = "(which do not), as well as a sentinel value for invalid messages.  To get"]
+#[doc = "the type of a message suitable for use in a switch statement, use"]
+#[doc = "lv2_midi_get_type() on the status byte."]
+pub type LV2_Midi_Message_Type = u32;
+#[doc = "< Bank Selection"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_BANK: LV2_Midi_Controller = 0;
+#[doc = "< Modulation"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_MODWHEEL: LV2_Midi_Controller = 1;
+#[doc = "< Breath"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_BREATH: LV2_Midi_Controller = 2;
+#[doc = "< Foot"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_FOOT: LV2_Midi_Controller = 4;
+#[doc = "< Portamento Time"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_PORTAMENTO_TIME: LV2_Midi_Controller = 5;
+#[doc = "< Data Entry"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_DATA_ENTRY: LV2_Midi_Controller = 6;
+#[doc = "< Main Volume"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_MAIN_VOLUME: LV2_Midi_Controller = 7;
+#[doc = "< Balance"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_BALANCE: LV2_Midi_Controller = 8;
+#[doc = "< Panpot"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_PAN: LV2_Midi_Controller = 10;
+#[doc = "< Expression"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_EXPRESSION: LV2_Midi_Controller = 11;
+#[doc = "< Effect1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_EFFECT1: LV2_Midi_Controller = 12;
+#[doc = "< Effect2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_EFFECT2: LV2_Midi_Controller = 13;
+#[doc = "< General Purpose 1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_GENERAL_PURPOSE1: LV2_Midi_Controller = 16;
+#[doc = "< General Purpose 2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_GENERAL_PURPOSE2: LV2_Midi_Controller = 17;
+#[doc = "< General Purpose 3"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_GENERAL_PURPOSE3: LV2_Midi_Controller = 18;
+#[doc = "< General Purpose 4"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_GENERAL_PURPOSE4: LV2_Midi_Controller = 19;
+#[doc = "< Bank Selection"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_BANK: LV2_Midi_Controller = 32;
+#[doc = "< Modulation"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_MODWHEEL: LV2_Midi_Controller = 33;
+#[doc = "< Breath"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_BREATH: LV2_Midi_Controller = 34;
+#[doc = "< Foot"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_FOOT: LV2_Midi_Controller = 36;
+#[doc = "< Portamento Time"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_PORTAMENTO_TIME: LV2_Midi_Controller = 37;
+#[doc = "< Data Entry"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_DATA_ENTRY: LV2_Midi_Controller = 38;
+#[doc = "< Main Volume"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_MAIN_VOLUME: LV2_Midi_Controller = 39;
+#[doc = "< Balance"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_BALANCE: LV2_Midi_Controller = 40;
+#[doc = "< Panpot"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_PAN: LV2_Midi_Controller = 42;
+#[doc = "< Expression"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_EXPRESSION: LV2_Midi_Controller = 43;
+#[doc = "< Effect1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_EFFECT1: LV2_Midi_Controller = 44;
+#[doc = "< Effect2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_EFFECT2: LV2_Midi_Controller = 45;
+#[doc = "< General Purpose 1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_GENERAL_PURPOSE1: LV2_Midi_Controller = 48;
+#[doc = "< General Purpose 2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_GENERAL_PURPOSE2: LV2_Midi_Controller = 49;
+#[doc = "< General Purpose 3"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_GENERAL_PURPOSE3: LV2_Midi_Controller = 50;
+#[doc = "< General Purpose 4"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_GENERAL_PURPOSE4: LV2_Midi_Controller = 51;
+#[doc = "< Sustain Pedal"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SUSTAIN: LV2_Midi_Controller = 64;
+#[doc = "< Portamento"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_PORTAMENTO: LV2_Midi_Controller = 65;
+#[doc = "< Sostenuto"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SOSTENUTO: LV2_Midi_Controller = 66;
+#[doc = "< Soft Pedal"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SOFT_PEDAL: LV2_Midi_Controller = 67;
+#[doc = "< Legato Foot Switch"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LEGATO_FOOTSWITCH: LV2_Midi_Controller = 68;
+#[doc = "< Hold2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_HOLD2: LV2_Midi_Controller = 69;
+#[doc = "< SC1 Sound Variation"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC1_SOUND_VARIATION: LV2_Midi_Controller = 70;
+#[doc = "< SC2 Timbre"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC2_TIMBRE: LV2_Midi_Controller = 71;
+#[doc = "< SC3 Release Time"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC3_RELEASE_TIME: LV2_Midi_Controller = 72;
+#[doc = "< SC4 Attack Time"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC4_ATTACK_TIME: LV2_Midi_Controller = 73;
+#[doc = "< SC5 Brightness"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC5_BRIGHTNESS: LV2_Midi_Controller = 74;
+#[doc = "< SC6"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC6: LV2_Midi_Controller = 75;
+#[doc = "< SC7"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC7: LV2_Midi_Controller = 76;
+#[doc = "< SC8"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC8: LV2_Midi_Controller = 77;
+#[doc = "< SC9"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC9: LV2_Midi_Controller = 78;
+#[doc = "< SC10"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC10: LV2_Midi_Controller = 79;
+#[doc = "< General Purpose 5"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_GENERAL_PURPOSE5: LV2_Midi_Controller = 80;
+#[doc = "< General Purpose 6"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_GENERAL_PURPOSE6: LV2_Midi_Controller = 81;
+#[doc = "< General Purpose 7"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_GENERAL_PURPOSE7: LV2_Midi_Controller = 82;
+#[doc = "< General Purpose 8"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_GENERAL_PURPOSE8: LV2_Midi_Controller = 83;
+#[doc = "< Portamento Control"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_PORTAMENTO_CONTROL: LV2_Midi_Controller = 84;
+#[doc = "< E1 Reverb Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E1_REVERB_DEPTH: LV2_Midi_Controller = 91;
+#[doc = "< E2 Tremolo Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E2_TREMOLO_DEPTH: LV2_Midi_Controller = 92;
+#[doc = "< E3 Chorus Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E3_CHORUS_DEPTH: LV2_Midi_Controller = 93;
+#[doc = "< E4 Detune Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E4_DETUNE_DEPTH: LV2_Midi_Controller = 94;
+#[doc = "< E5 Phaser Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E5_PHASER_DEPTH: LV2_Midi_Controller = 95;
+#[doc = "< Data Increment"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_DATA_INCREMENT: LV2_Midi_Controller = 96;
+#[doc = "< Data Decrement"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_DATA_DECREMENT: LV2_Midi_Controller = 97;
+#[doc = "< Non-registered Parameter Number"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_NRPN_LSB: LV2_Midi_Controller = 98;
+#[doc = "< Non-registered Parameter Number"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_NRPN_MSB: LV2_Midi_Controller = 99;
+#[doc = "< Registered Parameter Number"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_RPN_LSB: LV2_Midi_Controller = 100;
+#[doc = "< Registered Parameter Number"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_RPN_MSB: LV2_Midi_Controller = 101;
+#[doc = "< All Sounds Off"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_ALL_SOUNDS_OFF: LV2_Midi_Controller = 120;
+#[doc = "< Reset Controllers"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_RESET_CONTROLLERS: LV2_Midi_Controller = 121;
+#[doc = "< Local Control Switch"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LOCAL_CONTROL_SWITCH: LV2_Midi_Controller = 122;
+#[doc = "< All Notes Off"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_ALL_NOTES_OFF: LV2_Midi_Controller = 123;
+#[doc = "< Omni Off"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_OMNI_OFF: LV2_Midi_Controller = 124;
+#[doc = "< Omni On"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_OMNI_ON: LV2_Midi_Controller = 125;
+#[doc = "< Mono1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MONO1: LV2_Midi_Controller = 126;
+#[doc = "< Mono2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MONO2: LV2_Midi_Controller = 127;
+#[doc = "Standard MIDI Controller Numbers."]
+pub type LV2_Midi_Controller = u32;
+#[doc = "This option applies to the instance itself.  The subject must be"]
+#[doc = "ignored."]
+pub const LV2_Options_Context_LV2_OPTIONS_INSTANCE: LV2_Options_Context = 0;
+#[doc = "This option applies to some named resource.  The subject is a URI mapped"]
+#[doc = "to an integer (a LV2_URID, like the key)"]
+pub const LV2_Options_Context_LV2_OPTIONS_RESOURCE: LV2_Options_Context = 1;
+#[doc = "This option applies to some blank node.  The subject is a blank node"]
+#[doc = "identifier, which is valid only within the current local scope."]
+pub const LV2_Options_Context_LV2_OPTIONS_BLANK: LV2_Options_Context = 2;
+#[doc = "This option applies to a port on the instance.  The subject is the"]
+#[doc = "port's index."]
+pub const LV2_Options_Context_LV2_OPTIONS_PORT: LV2_Options_Context = 3;
+#[doc = "The context of an Option, which defines the subject it applies to."]
+pub type LV2_Options_Context = u32;
+#[doc = "An option."]
+#[doc = ""]
+#[doc = "This is a property with a subject, also known as a triple or statement."]
+#[doc = ""]
+#[doc = "This struct is useful anywhere a statement needs to be passed where no"]
+#[doc = "memory ownership issues are present (since the value is a const pointer)."]
+#[doc = ""]
+#[doc = "Options can be passed to an instance via the feature LV2_OPTIONS__options"]
+#[doc = "with data pointed to an array of options terminated by a zeroed option, or"]
+#[doc = "accessed/manipulated using LV2_Options_Interface."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Options_Option {
+    #[doc = "< Context (type of subject)."]
+    pub context: LV2_Options_Context,
+    #[doc = "< Subject."]
+    pub subject: u32,
+    #[doc = "< Key (property)."]
+    pub key: LV2_URID,
+    #[doc = "< Size of value in bytes."]
+    pub size: u32,
+    #[doc = "< Type of value (datatype)."]
+    pub type_: LV2_URID,
+    #[doc = "< Pointer to value (object)."]
+    pub value: *const ::std::os::raw::c_void,
+}
+#[doc = "< Completed successfully."]
+pub const LV2_Options_Status_LV2_OPTIONS_SUCCESS: LV2_Options_Status = 0;
+#[doc = "< Unknown error."]
+pub const LV2_Options_Status_LV2_OPTIONS_ERR_UNKNOWN: LV2_Options_Status = 1;
+#[doc = "< Invalid/unsupported subject."]
+pub const LV2_Options_Status_LV2_OPTIONS_ERR_BAD_SUBJECT: LV2_Options_Status = 2;
+#[doc = "< Invalid/unsupported key."]
+pub const LV2_Options_Status_LV2_OPTIONS_ERR_BAD_KEY: LV2_Options_Status = 4;
+#[doc = "< Invalid/unsupported value."]
+pub const LV2_Options_Status_LV2_OPTIONS_ERR_BAD_VALUE: LV2_Options_Status = 8;
+#[doc = " A status code for option functions."]
+pub type LV2_Options_Status = u32;
+#[doc = "Interface for dynamically setting options (LV2_OPTIONS__interface)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Options_Interface {
+    #[doc = "Get the given options."]
+    #[doc = ""]
+    #[doc = "Each element of the passed options array MUST have type, subject, and"]
+    #[doc = "key set.  All other fields (size, type, value) MUST be initialised to"]
+    #[doc = "zero, and are set to the option value if such an option is found."]
+    #[doc = ""]
+    #[doc = "This function is in the \"instantiation\" LV2 threading class, so no other"]
+    #[doc = "instance functions may be called concurrently."]
+    #[doc = ""]
+    #[doc = "@return Bitwise OR of LV2_Options_Status values."]
+    pub get: ::std::option::Option<
+        unsafe extern "C" fn(instance: LV2_Handle, options: *mut LV2_Options_Option) -> u32,
+    >,
+    #[doc = "Set the given options."]
+    #[doc = ""]
+    #[doc = "This function is in the \"instantiation\" LV2 threading class, so no other"]
+    #[doc = "instance functions may be called concurrently."]
+    #[doc = ""]
+    #[doc = "@return Bitwise OR of LV2_Options_Status values."]
+    pub set: ::std::option::Option<
+        unsafe extern "C" fn(instance: LV2_Handle, options: *const LV2_Options_Option) -> u32,
+    >,
+}
+#[doc = "< Completed successfully."]
+pub const LV2_Resize_Port_Status_LV2_RESIZE_PORT_SUCCESS: LV2_Resize_Port_Status = 0;
+#[doc = "< Unknown error."]
+pub const LV2_Resize_Port_Status_LV2_RESIZE_PORT_ERR_UNKNOWN: LV2_Resize_Port_Status = 1;
+#[doc = "< Insufficient space."]
+pub const LV2_Resize_Port_Status_LV2_RESIZE_PORT_ERR_NO_SPACE: LV2_Resize_Port_Status = 2;
+#[doc = " A status code for state functions."]
+pub type LV2_Resize_Port_Status = u32;
+#[doc = " Opaque data for resize method."]
+pub type LV2_Resize_Port_Feature_Data = *mut ::std::os::raw::c_void;
+#[doc = " Host feature to allow plugins to resize their port buffers."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Resize_Port_Resize {
+    #[doc = " Opaque data for resize method."]
+    pub data: LV2_Resize_Port_Feature_Data,
+    #[doc = "Resize a port buffer to at least `size` bytes."]
+    #[doc = ""]
+    #[doc = "This function MAY return an error, in which case the port buffer was not"]
+    #[doc = "resized and the port is still connected to the same location.  Plugins"]
+    #[doc = "MUST gracefully handle this situation."]
+    #[doc = ""]
+    #[doc = "This function is in the audio threading class."]
+    #[doc = ""]
+    #[doc = "The host MUST preserve the contents of the port buffer when resizing."]
+    #[doc = ""]
+    #[doc = "Plugins MAY resize a port many times in a single run callback.  Hosts"]
+    #[doc = "SHOULD make this as inexpensive as possible."]
+    pub resize: ::std::option::Option<
+        unsafe extern "C" fn(
+            data: LV2_Resize_Port_Feature_Data,
+            index: u32,
+            size: usize,
+        ) -> LV2_Resize_Port_Status,
+    >,
+}
+pub type LV2_State_Handle = *mut ::std::os::raw::c_void;
+pub type LV2_State_Free_Path_Handle = *mut ::std::os::raw::c_void;
+pub type LV2_State_Map_Path_Handle = *mut ::std::os::raw::c_void;
+pub type LV2_State_Make_Path_Handle = *mut ::std::os::raw::c_void;
+impl LV2_State_Flags {
+    #[doc = "Plain Old Data."]
+    #[doc = ""]
+    #[doc = "Values with this flag contain no pointers or references to other areas"]
+    #[doc = "of memory.  It is safe to copy POD values with a simple memcpy and store"]
+    #[doc = "them for the duration of the process.  A POD value is not necessarily"]
+    #[doc = "safe to trasmit between processes or machines (for example, filenames"]
+    #[doc = "are POD), see LV2_STATE_IS_PORTABLE for details."]
+    #[doc = ""]
+    #[doc = "Implementations MUST NOT attempt to copy or serialise a non-POD value if"]
+    #[doc = "they do not understand its type (and thus know how to correctly do so)."]
+    pub const LV2_STATE_IS_POD: LV2_State_Flags = LV2_State_Flags(1);
+}
+impl LV2_State_Flags {
+    #[doc = "Portable (architecture independent) data."]
+    #[doc = ""]
+    #[doc = "Values with this flag are in a format that is usable on any"]
+    #[doc = "architecture.  A portable value saved on one machine can be restored on"]
+    #[doc = "another machine regardless of architecture.  The format of portable"]
+    #[doc = "values MUST NOT depend on architecture-specific properties like"]
+    #[doc = "endianness or alignment.  Portable values MUST NOT contain filenames."]
+    pub const LV2_STATE_IS_PORTABLE: LV2_State_Flags = LV2_State_Flags(2);
+}
+impl LV2_State_Flags {
+    #[doc = "Native data."]
+    #[doc = ""]
+    #[doc = "This flag is used by the host to indicate that the saved data is only"]
+    #[doc = "going to be used locally in the currently running process (for things"]
+    #[doc = "like instance duplication or snapshots), so the plugin should use the"]
+    #[doc = "most efficient representation possible and not worry about serialisation"]
+    #[doc = "and portability."]
+    pub const LV2_STATE_IS_NATIVE: LV2_State_Flags = LV2_State_Flags(4);
+}
+impl ::std::ops::BitOr<LV2_State_Flags> for LV2_State_Flags {
+    type Output = Self;
+    #[inline]
+    fn bitor(self, other: Self) -> Self {
+        LV2_State_Flags(self.0 | other.0)
+    }
+}
+impl ::std::ops::BitOrAssign for LV2_State_Flags {
+    #[inline]
+    fn bitor_assign(&mut self, rhs: LV2_State_Flags) {
+        self.0 |= rhs.0;
+    }
+}
+impl ::std::ops::BitAnd<LV2_State_Flags> for LV2_State_Flags {
+    type Output = Self;
+    #[inline]
+    fn bitand(self, other: Self) -> Self {
+        LV2_State_Flags(self.0 & other.0)
+    }
+}
+impl ::std::ops::BitAndAssign for LV2_State_Flags {
+    #[inline]
+    fn bitand_assign(&mut self, rhs: LV2_State_Flags) {
+        self.0 &= rhs.0;
+    }
+}
+#[repr(transparent)]
+#[doc = "Flags describing value characteristics."]
+#[doc = ""]
+#[doc = "These flags are used along with the value's type URI to determine how to"]
+#[doc = "(de-)serialise the value data, or whether it is even possible to do so."]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct LV2_State_Flags(pub u32);
+#[doc = "< Completed successfully."]
+pub const LV2_State_Status_LV2_STATE_SUCCESS: LV2_State_Status = 0;
+#[doc = "< Unknown error."]
+pub const LV2_State_Status_LV2_STATE_ERR_UNKNOWN: LV2_State_Status = 1;
+#[doc = "< Failed due to unsupported type."]
+pub const LV2_State_Status_LV2_STATE_ERR_BAD_TYPE: LV2_State_Status = 2;
+#[doc = "< Failed due to unsupported flags."]
+pub const LV2_State_Status_LV2_STATE_ERR_BAD_FLAGS: LV2_State_Status = 3;
+#[doc = "< Failed due to missing features."]
+pub const LV2_State_Status_LV2_STATE_ERR_NO_FEATURE: LV2_State_Status = 4;
+#[doc = "< Failed due to missing property."]
+pub const LV2_State_Status_LV2_STATE_ERR_NO_PROPERTY: LV2_State_Status = 5;
+#[doc = "< Failed due to insufficient space."]
+pub const LV2_State_Status_LV2_STATE_ERR_NO_SPACE: LV2_State_Status = 6;
+#[doc = " A status code for state functions."]
+pub type LV2_State_Status = u32;
+#[doc = "A host-provided function to store a property."]
+#[doc = "@param handle Must be the handle passed to LV2_State_Interface.save()."]
+#[doc = "@param key The key to store `value` under (URID)."]
+#[doc = "@param value Pointer to the value to be stored."]
+#[doc = "@param size The size of `value` in bytes."]
+#[doc = "@param type The type of `value` (URID)."]
+#[doc = "@param flags LV2_State_Flags for `value`."]
+#[doc = "@return 0 on success, otherwise a non-zero error code."]
+#[doc = ""]
+#[doc = "The host passes a callback of this type to LV2_State_Interface.save(). This"]
+#[doc = "callback is called repeatedly by the plugin to store all the properties that"]
+#[doc = "describe its current state."]
+#[doc = ""]
+#[doc = "DO NOT INVENT NONSENSE URI SCHEMES FOR THE KEY.  Best is to use keys from"]
+#[doc = "existing vocabularies.  If nothing appropriate is available, use http URIs"]
+#[doc = "that point to somewhere you can host documents so documentation can be made"]
+#[doc = "resolvable (typically a child of the plugin or project URI).  If this is not"]
+#[doc = "possible, invent a URN scheme, e.g. urn:myproj:whatever.  The plugin MUST"]
+#[doc = "NOT pass an invalid URI key."]
+#[doc = ""]
+#[doc = "The host MAY fail to store a property for whatever reason, but SHOULD"]
+#[doc = "store any property that is LV2_STATE_IS_POD and LV2_STATE_IS_PORTABLE."]
+#[doc = "Implementations SHOULD use the types from the LV2 Atom extension"]
+#[doc = "(http://lv2plug.in/ns/ext/atom) wherever possible.  The plugin SHOULD"]
+#[doc = "attempt to fall-back and avoid the error if possible."]
+#[doc = ""]
+#[doc = "Note that `size` MUST be > 0, and `value` MUST point to a valid region of"]
+#[doc = "memory `size` bytes long (this is required to make restore unambiguous)."]
+#[doc = ""]
+#[doc = "The plugin MUST NOT attempt to use this function outside of the"]
+#[doc = "LV2_State_Interface.restore() context."]
+pub type LV2_State_Store_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_State_Handle,
+        key: u32,
+        value: *const ::std::os::raw::c_void,
+        size: usize,
+        type_: u32,
+        flags: u32,
+    ) -> LV2_State_Status,
+>;
+#[doc = "A host-provided function to retrieve a property."]
+#[doc = "@param handle Must be the handle passed to LV2_State_Interface.restore()."]
+#[doc = "@param key The key of the property to retrieve (URID)."]
+#[doc = "@param size (Output) If non-NULL, set to the size of the restored value."]
+#[doc = "@param type (Output) If non-NULL, set to the type of the restored value."]
+#[doc = "@param flags (Output) If non-NULL, set to the flags for the restored value."]
+#[doc = "@return A pointer to the restored value (object), or NULL if no value"]
+#[doc = "has been stored under `key`."]
+#[doc = ""]
+#[doc = "A callback of this type is passed by the host to"]
+#[doc = "LV2_State_Interface.restore().  This callback is called repeatedly by the"]
+#[doc = "plugin to retrieve any properties it requires to restore its state."]
+#[doc = ""]
+#[doc = "The returned value MUST remain valid until LV2_State_Interface.restore()"]
+#[doc = "returns.  The plugin MUST NOT attempt to use this function, or any value"]
+#[doc = "returned from it, outside of the LV2_State_Interface.restore() context."]
+pub type LV2_State_Retrieve_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_State_Handle,
+        key: u32,
+        size: *mut usize,
+        type_: *mut u32,
+        flags: *mut u32,
+    ) -> *const ::std::os::raw::c_void,
+>;
+#[doc = "LV2 Plugin State Interface."]
+#[doc = ""]
+#[doc = "When the plugin's extension_data is called with argument"]
+#[doc = "LV2_STATE__interface, the plugin MUST return an LV2_State_Interface"]
+#[doc = "structure, which remains valid for the lifetime of the plugin."]
+#[doc = ""]
+#[doc = "The host can use the contained function pointers to save and restore the"]
+#[doc = "state of a plugin instance at any time, provided the threading restrictions"]
+#[doc = "of the functions are met."]
+#[doc = ""]
+#[doc = "Stored data is only guaranteed to be compatible between instances of plugins"]
+#[doc = "with the same URI (i.e. if a change to a plugin would cause a fatal error"]
+#[doc = "when restoring state saved by a previous version of that plugin, the plugin"]
+#[doc = "URI MUST change just as it must when ports change incompatibly).  Plugin"]
+#[doc = "authors should consider this possibility, and always store sensible data"]
+#[doc = "with meaningful types to avoid such problems in the future."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_State_Interface {
+    #[doc = "Save plugin state using a host-provided `store` callback."]
+    #[doc = ""]
+    #[doc = "@param instance The instance handle of the plugin."]
+    #[doc = "@param store The host-provided store callback."]
+    #[doc = "@param handle An opaque pointer to host data which MUST be passed as the"]
+    #[doc = "handle parameter to `store` if it is called."]
+    #[doc = "@param flags Flags describing desired properties of this save.  These"]
+    #[doc = "flags may be used to determine the most appropriate values to store."]
+    #[doc = "@param features Extensible parameter for passing any additional"]
+    #[doc = "features to be used for this save."]
+    #[doc = ""]
+    #[doc = "The plugin is expected to store everything necessary to completely"]
+    #[doc = "restore its state later.  Plugins SHOULD store simple POD data whenever"]
+    #[doc = "possible, and consider the possibility of state being restored much"]
+    #[doc = "later on a different machine."]
+    #[doc = ""]
+    #[doc = "The `handle` pointer and `store` function MUST NOT be used"]
+    #[doc = "beyond the scope of save()."]
+    #[doc = ""]
+    #[doc = "This function has its own special threading class: it may not be called"]
+    #[doc = "concurrently with any \"Instantiation\" function, but it may be called"]
+    #[doc = "concurrently with functions in any other class, unless the definition of"]
+    #[doc = "that class prohibits it (for example, it may not be called concurrently"]
+    #[doc = "with a \"Discovery\" function, but it may be called concurrently with an"]
+    #[doc = "\"Audio\" function.  The plugin is responsible for any locking or"]
+    #[doc = "lock-free techniques necessary to make this possible."]
+    #[doc = ""]
+    #[doc = "Note that in the simple case where state is only modified by restore(),"]
+    #[doc = "there are no synchronization issues since save() is never called"]
+    #[doc = "concurrently with restore() (though run() may read it during a save)."]
+    #[doc = ""]
+    #[doc = "Plugins that dynamically modify state while running, however, must take"]
+    #[doc = "care to do so in such a way that a concurrent call to save() will save a"]
+    #[doc = "consistent representation of plugin state for a single instant in time."]
+    pub save: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            store: LV2_State_Store_Function,
+            handle: LV2_State_Handle,
+            flags: u32,
+            features: *const *const LV2_Feature,
+        ) -> LV2_State_Status,
+    >,
+    #[doc = "Restore plugin state using a host-provided `retrieve` callback."]
+    #[doc = ""]
+    #[doc = "@param instance The instance handle of the plugin."]
+    #[doc = "@param retrieve The host-provided retrieve callback."]
+    #[doc = "@param handle An opaque pointer to host data which MUST be passed as the"]
+    #[doc = "handle parameter to `retrieve` if it is called."]
+    #[doc = "@param flags Currently unused."]
+    #[doc = "@param features Extensible parameter for passing any additional"]
+    #[doc = "features to be used for this restore."]
+    #[doc = ""]
+    #[doc = "The plugin MAY assume a restored value was set by a previous call to"]
+    #[doc = "LV2_State_Interface.save() by a plugin with the same URI."]
+    #[doc = ""]
+    #[doc = "The plugin MUST gracefully fall back to a default value when a value can"]
+    #[doc = "not be retrieved.  This allows the host to reset the plugin state with"]
+    #[doc = "an empty map."]
+    #[doc = ""]
+    #[doc = "The `handle` pointer and `store` function MUST NOT be used"]
+    #[doc = "beyond the scope of restore()."]
+    #[doc = ""]
+    #[doc = "This function is in the \"Instantiation\" threading class as defined by"]
+    #[doc = "LV2. This means it MUST NOT be called concurrently with any other"]
+    #[doc = "function on the same plugin instance."]
+    pub restore: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            retrieve: LV2_State_Retrieve_Function,
+            handle: LV2_State_Handle,
+            flags: u32,
+            features: *const *const LV2_Feature,
+        ) -> LV2_State_Status,
+    >,
+}
+#[doc = "Feature data for state:mapPath (@ref LV2_STATE__mapPath)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_State_Map_Path {
+    #[doc = "Opaque host data."]
+    pub handle: LV2_State_Map_Path_Handle,
+    #[doc = "Map an absolute path to an abstract path for use in plugin state."]
+    #[doc = "@param handle MUST be the `handle` member of this struct."]
+    #[doc = "@param absolute_path The absolute path of a file."]
+    #[doc = "@return An abstract path suitable for use in plugin state."]
+    #[doc = ""]
+    #[doc = "The plugin MUST use this function to map any paths that will be stored"]
+    #[doc = "in plugin state.  The returned value is an abstract path which MAY not"]
+    #[doc = "be an actual file system path; absolute_path() MUST be used to map"]
+    #[doc = "it to an actual path in order to use the file."]
+    #[doc = ""]
+    #[doc = "Plugins MUST NOT make any assumptions about abstract paths except that"]
+    #[doc = "they can be mapped back to the absolute path of the \"same\" file (though"]
+    #[doc = "not necessarily the same original path) using absolute_path()."]
+    #[doc = ""]
+    #[doc = "This function may only be called within the context of"]
+    #[doc = "LV2_State_Interface methods.  The caller must free the returned value"]
+    #[doc = "with LV2_State_Free_Path.free_path()."]
+    pub abstract_path: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_State_Map_Path_Handle,
+            absolute_path: *const ::std::os::raw::c_char,
+        ) -> *mut ::std::os::raw::c_char,
+    >,
+    #[doc = "Map an abstract path from plugin state to an absolute path."]
+    #[doc = "@param handle MUST be the `handle` member of this struct."]
+    #[doc = "@param abstract_path An abstract path (typically from plugin state)."]
+    #[doc = "@return An absolute file system path."]
+    #[doc = ""]
+    #[doc = "The plugin MUST use this function in order to actually open or otherwise"]
+    #[doc = "use any paths loaded from plugin state."]
+    #[doc = ""]
+    #[doc = "This function may only be called within the context of"]
+    #[doc = "LV2_State_Interface methods.  The caller must free the returned value"]
+    #[doc = "with LV2_State_Free_Path.free_path()."]
+    pub absolute_path: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_State_Map_Path_Handle,
+            abstract_path: *const ::std::os::raw::c_char,
+        ) -> *mut ::std::os::raw::c_char,
+    >,
+}
+#[doc = "Feature data for state:makePath (@ref LV2_STATE__makePath)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_State_Make_Path {
+    #[doc = "Opaque host data."]
+    pub handle: LV2_State_Make_Path_Handle,
+    #[doc = "Return a path the plugin may use to create a new file."]
+    #[doc = "@param handle MUST be the `handle` member of this struct."]
+    #[doc = "@param path The path of the new file within a namespace unique to this"]
+    #[doc = "plugin instance."]
+    #[doc = "@return The absolute path to use for the new file."]
+    #[doc = ""]
+    #[doc = "This function can be used by plugins to create files and directories,"]
+    #[doc = "either at state saving time (if this feature is passed to"]
+    #[doc = "LV2_State_Interface.save()) or any time (if this feature is passed to"]
+    #[doc = "LV2_Descriptor.instantiate())."]
+    #[doc = ""]
+    #[doc = "The host MUST do whatever is necessary for the plugin to be able to"]
+    #[doc = "create a file at the returned path (for example, using fopen()),"]
+    #[doc = "including creating any leading directories."]
+    #[doc = ""]
+    #[doc = "If this function is passed to LV2_Descriptor.instantiate(), it may be"]
+    #[doc = "called from any non-realtime context.  If it is passed to"]
+    #[doc = "LV2_State_Interface.save(), it may only be called within the dynamic"]
+    #[doc = "scope of that function call."]
+    #[doc = ""]
+    #[doc = "The caller must free the returned value with"]
+    #[doc = "LV2_State_Free_Path.free_path()."]
+    pub path: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_State_Make_Path_Handle,
+            path: *const ::std::os::raw::c_char,
+        ) -> *mut ::std::os::raw::c_char,
+    >,
+}
+#[doc = "Feature data for state:freePath (@ref LV2_STATE__freePath)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_State_Free_Path {
+    #[doc = "Opaque host data."]
+    pub handle: LV2_State_Free_Path_Handle,
+    #[doc = "Free a path returned by a state feature."]
+    #[doc = ""]
+    #[doc = "@param handle MUST be the `handle` member of this struct."]
+    #[doc = "@param path The path previously returned by a state feature."]
+    #[doc = ""]
+    #[doc = "This function can be used by plugins to free paths allocated by the host"]
+    #[doc = "and returned by state features (LV2_State_Map_Path.abstract_path(),"]
+    #[doc = "LV2_State_Map_Path.absolute_path(), and LV2_State_Make_Path.path())."]
+    pub free_path: ::std::option::Option<
+        unsafe extern "C" fn(handle: LV2_State_Free_Path_Handle, path: *mut ::std::os::raw::c_char),
+    >,
+}
+#[doc = "A pointer to some widget or other type of UI handle."]
+#[doc = ""]
+#[doc = "The actual type is defined by the type of the UI."]
+pub type LV2UI_Widget = *mut ::std::os::raw::c_void;
+#[doc = "A pointer to UI instance internals."]
+#[doc = ""]
+#[doc = "The host may compare this to NULL, but otherwise MUST NOT interpret it."]
+pub type LV2UI_Handle = *mut ::std::os::raw::c_void;
+#[doc = "A pointer to a controller provided by the host."]
+#[doc = ""]
+#[doc = "The UI may compare this to NULL, but otherwise MUST NOT interpret it."]
+pub type LV2UI_Controller = *mut ::std::os::raw::c_void;
+#[doc = "A pointer to opaque data for a feature."]
+pub type LV2UI_Feature_Handle = *mut ::std::os::raw::c_void;
+#[doc = "A host-provided function that sends data to a plugin's input ports."]
+#[doc = ""]
+#[doc = "@param controller The opaque controller pointer passed to"]
+#[doc = "LV2UI_Descriptor::instantiate()."]
+#[doc = ""]
+#[doc = "@param port_index Index of the port to update."]
+#[doc = ""]
+#[doc = "@param buffer Buffer containing `buffer_size` bytes of data."]
+#[doc = ""]
+#[doc = "@param buffer_size Size of `buffer` in bytes."]
+#[doc = ""]
+#[doc = "@param port_protocol Either 0 or the URID for a ui:PortProtocol.  If 0, the"]
+#[doc = "protocol is implicitly ui:floatProtocol, the port MUST be an lv2:ControlPort"]
+#[doc = "input, `buffer` MUST point to a single float value, and `buffer_size` MUST"]
+#[doc = "be sizeof(float).  The UI SHOULD NOT use a protocol not supported by the"]
+#[doc = "host, but the host MUST gracefully ignore any protocol it does not"]
+#[doc = "understand."]
+pub type LV2UI_Write_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        controller: LV2UI_Controller,
+        port_index: u32,
+        buffer_size: u32,
+        port_protocol: u32,
+        buffer: *const ::std::os::raw::c_void,
+    ),
+>;
+#[doc = "A plugin UI."]
+#[doc = ""]
+#[doc = "A pointer to an object of this type is returned by the lv2ui_descriptor()"]
+#[doc = "function."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Descriptor {
+    #[doc = "The URI for this UI (not for the plugin it controls)."]
+    pub URI: *const ::std::os::raw::c_char,
+    #[doc = "Create a new UI and return a handle to it.  This function works"]
+    #[doc = "similarly to LV2_Descriptor::instantiate()."]
+    #[doc = ""]
+    #[doc = "@param descriptor The descriptor for the UI to instantiate."]
+    #[doc = ""]
+    #[doc = "@param plugin_uri The URI of the plugin that this UI will control."]
+    #[doc = ""]
+    #[doc = "@param bundle_path The path to the bundle containing this UI, including"]
+    #[doc = "the trailing directory separator."]
+    #[doc = ""]
+    #[doc = "@param write_function A function that the UI can use to send data to the"]
+    #[doc = "plugin's input ports."]
+    #[doc = ""]
+    #[doc = "@param controller A handle for the UI instance to be passed as the"]
+    #[doc = "first parameter of UI methods."]
+    #[doc = ""]
+    #[doc = "@param widget (output) widget pointer.  The UI points this at its main"]
+    #[doc = "widget, which has the type defined by the UI type in the data file."]
+    #[doc = ""]
+    #[doc = "@param features An array of LV2_Feature pointers.  The host must pass"]
+    #[doc = "all feature URIs that it and the UI supports and any additional data, as"]
+    #[doc = "in LV2_Descriptor::instantiate().  Note that UI features and plugin"]
+    #[doc = "features are not necessarily the same."]
+    #[doc = ""]
+    pub instantiate: ::std::option::Option<
+        unsafe extern "C" fn(
+            descriptor: *const LV2UI_Descriptor,
+            plugin_uri: *const ::std::os::raw::c_char,
+            bundle_path: *const ::std::os::raw::c_char,
+            write_function: LV2UI_Write_Function,
+            controller: LV2UI_Controller,
+            widget: *mut LV2UI_Widget,
+            features: *const *const LV2_Feature,
+        ) -> LV2UI_Handle,
+    >,
+    #[doc = "Destroy the UI.  The host must not try to access the widget after"]
+    #[doc = "calling this function."]
+    pub cleanup: ::std::option::Option<unsafe extern "C" fn(ui: LV2UI_Handle)>,
+    #[doc = "Tell the UI that something interesting has happened at a plugin port."]
+    #[doc = ""]
+    #[doc = "What is \"interesting\" and how it is written to `buffer` is defined by"]
+    #[doc = "`format`, which has the same meaning as in LV2UI_Write_Function()."]
+    #[doc = "Format 0 is a special case for lv2:ControlPort, where this function"]
+    #[doc = "should be called when the port value changes (but not necessarily for"]
+    #[doc = "every change), `buffer_size` must be sizeof(float), and `buffer`"]
+    #[doc = "points to a single IEEE-754 float."]
+    #[doc = ""]
+    #[doc = "By default, the host should only call this function for lv2:ControlPort"]
+    #[doc = "inputs.  However, the UI can request updates for other ports statically"]
+    #[doc = "with ui:portNotification or dynamicaly with ui:portSubscribe."]
+    #[doc = ""]
+    #[doc = "The UI MUST NOT retain any reference to `buffer` after this function"]
+    #[doc = "returns, it is only valid for the duration of the call."]
+    #[doc = ""]
+    #[doc = "This member may be NULL if the UI is not interested in any port events."]
+    pub port_event: ::std::option::Option<
+        unsafe extern "C" fn(
+            ui: LV2UI_Handle,
+            port_index: u32,
+            buffer_size: u32,
+            format: u32,
+            buffer: *const ::std::os::raw::c_void,
+        ),
+    >,
+    #[doc = "Return a data structure associated with an extension URI, typically an"]
+    #[doc = "interface struct with additional function pointers"]
+    #[doc = ""]
+    #[doc = "This member may be set to NULL if the UI is not interested in supporting"]
+    #[doc = "any extensions. This is similar to LV2_Descriptor::extension_data()."]
+    #[doc = ""]
+    pub extension_data: ::std::option::Option<
+        unsafe extern "C" fn(uri: *const ::std::os::raw::c_char) -> *const ::std::os::raw::c_void,
+    >,
+}
+#[doc = "Feature/interface for resizable UIs (LV2_UI__resize)."]
+#[doc = ""]
+#[doc = "This structure is used in two ways: as a feature passed by the host via"]
+#[doc = "LV2UI_Descriptor::instantiate(), or as an interface provided by a UI via"]
+#[doc = "LV2UI_Descriptor::extension_data())."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Resize {
+    #[doc = "Pointer to opaque data which must be passed to ui_resize()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Request/advertise a size change."]
+    #[doc = ""]
+    #[doc = "When provided by the host, the UI may call this function to inform the"]
+    #[doc = "host about the size of the UI."]
+    #[doc = ""]
+    #[doc = "When provided by the UI, the host may call this function to notify the"]
+    #[doc = "UI that it should change its size accordingly.  In this case, the host"]
+    #[doc = "must pass the LV2UI_Handle to provide access to the UI instance."]
+    #[doc = ""]
+    #[doc = "@return 0 on success."]
+    pub ui_resize: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            width: ::std::os::raw::c_int,
+            height: ::std::os::raw::c_int,
+        ) -> ::std::os::raw::c_int,
+    >,
+}
+#[doc = "Feature to map port symbols to UIs."]
+#[doc = ""]
+#[doc = "This can be used by the UI to get the index for a port with the given"]
+#[doc = "symbol.  This makes it possible to implement and distribute a UI separately"]
+#[doc = "from the plugin (since symbol, unlike index, is a stable port identifier)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Port_Map {
+    #[doc = "Pointer to opaque data which must be passed to port_index()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Get the index for the port with the given `symbol`."]
+    #[doc = ""]
+    #[doc = "@return The index of the port, or LV2UI_INVALID_PORT_INDEX if no such"]
+    #[doc = "port is found."]
+    pub port_index: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            symbol: *const ::std::os::raw::c_char,
+        ) -> u32,
+    >,
+}
+#[doc = "Feature to subscribe to port updates (LV2_UI__portSubscribe)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Port_Subscribe {
+    #[doc = "Pointer to opaque data which must be passed to subscribe() and"]
+    #[doc = "unsubscribe()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Subscribe to updates for a port."]
+    #[doc = ""]
+    #[doc = "This means that the host will call the UI's port_event() function when"]
+    #[doc = "the port value changes (as defined by protocol)."]
+    #[doc = ""]
+    #[doc = "Calling this function with the same `port_index` and `port_protocol`"]
+    #[doc = "as an already active subscription has no effect."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = "@param port_index The index of the port."]
+    #[doc = "@param port_protocol The URID of the ui:PortProtocol."]
+    #[doc = "@param features Features for this subscription."]
+    #[doc = "@return 0 on success."]
+    pub subscribe: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            port_index: u32,
+            port_protocol: u32,
+            features: *const *const LV2_Feature,
+        ) -> u32,
+    >,
+    #[doc = "Unsubscribe from updates for a port."]
+    #[doc = ""]
+    #[doc = "This means that the host will cease calling calling port_event() when"]
+    #[doc = "the port value changes."]
+    #[doc = ""]
+    #[doc = "Calling this function with a `port_index` and `port_protocol` that"]
+    #[doc = "does not refer to an active port subscription has no effect."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = "@param port_index The index of the port."]
+    #[doc = "@param port_protocol The URID of the ui:PortProtocol."]
+    #[doc = "@param features Features for this subscription."]
+    #[doc = "@return 0 on success."]
+    pub unsubscribe: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            port_index: u32,
+            port_protocol: u32,
+            features: *const *const LV2_Feature,
+        ) -> u32,
+    >,
+}
+#[doc = "A feature to notify the host that the user has grabbed a UI control."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Touch {
+    #[doc = "Pointer to opaque data which must be passed to ui_resize()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Notify the host that a control has been grabbed or released."]
+    #[doc = ""]
+    #[doc = "The host should cease automating the port or otherwise manipulating the"]
+    #[doc = "port value until the control has been ungrabbed."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = "@param port_index The index of the port associated with the control."]
+    #[doc = "@param grabbed If true, the control has been grabbed, otherwise the"]
+    #[doc = "control has been released."]
+    pub touch: ::std::option::Option<
+        unsafe extern "C" fn(handle: LV2UI_Feature_Handle, port_index: u32, grabbed: bool),
+    >,
+}
+#[doc = "Completed successfully."]
+#[doc = ""]
+#[doc = "The host will set the parameter later if the user choses a new value."]
+pub const LV2UI_Request_Value_Status_LV2UI_REQUEST_VALUE_SUCCESS: LV2UI_Request_Value_Status = 0;
+#[doc = "Parameter already being requested."]
+#[doc = ""]
+#[doc = "The host is already requesting a parameter from the user (for example, a"]
+#[doc = "dialog is visible), or the UI is otherwise busy and can not make this"]
+#[doc = "request."]
+pub const LV2UI_Request_Value_Status_LV2UI_REQUEST_VALUE_BUSY: LV2UI_Request_Value_Status = 1;
+#[doc = "Unknown parameter."]
+#[doc = ""]
+#[doc = "The host is not aware of this parameter, and is not able to set a new"]
+#[doc = "value for it."]
+pub const LV2UI_Request_Value_Status_LV2UI_REQUEST_VALUE_ERR_UNKNOWN: LV2UI_Request_Value_Status =
+    2;
+#[doc = "Unsupported parameter."]
+#[doc = ""]
+#[doc = "The host knows about this parameter, but does not support requesting a"]
+#[doc = "new value for it from the user.  This is likely because the host does"]
+#[doc = "not have UI support for choosing a value with the appropriate type."]
+pub const LV2UI_Request_Value_Status_LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED:
+    LV2UI_Request_Value_Status = 3;
+#[doc = "A status code for LV2UI_Request_Value::request()."]
+pub type LV2UI_Request_Value_Status = u32;
+#[doc = "A feature to request a new parameter value from the host."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Request_Value {
+    #[doc = "Pointer to opaque data which must be passed to request()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Request a value for a parameter from the host."]
+    #[doc = ""]
+    #[doc = "This is mainly used by UIs to request values for complex parameters that"]
+    #[doc = "don't change often, such as file paths, but it may be used to request"]
+    #[doc = "any parameter value."]
+    #[doc = ""]
+    #[doc = "This function returns immediately, and the return value indicates"]
+    #[doc = "whether the host can fulfill the request.  The host may notify the"]
+    #[doc = "plugin about the new parameter value, for example when a file is"]
+    #[doc = "selected by the user, via the usual mechanism.  Typically, the host will"]
+    #[doc = "send a message to the plugin that sets the new parameter value, and the"]
+    #[doc = "plugin will notify the UI via a message as usual for any other parameter"]
+    #[doc = "change."]
+    #[doc = ""]
+    #[doc = "To provide an appropriate UI, the host can determine details about the"]
+    #[doc = "parameter from the plugin data as usual.  The additional parameters of"]
+    #[doc = "this function provide support for more advanced use cases, but in the"]
+    #[doc = "simple common case, the plugin will simply pass the key of the desired"]
+    #[doc = "parameter and zero for everything else."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = ""]
+    #[doc = "@param key The URID of the parameter."]
+    #[doc = ""]
+    #[doc = "@param type The optional type of the value to request.  This can be used"]
+    #[doc = "to request a specific value type for parameters that support several."]
+    #[doc = "If non-zero, it must be the URID of an instance of rdfs:Class or"]
+    #[doc = "rdfs:Datatype."]
+    #[doc = ""]
+    #[doc = "@param features Additional features for this request, or NULL."]
+    #[doc = ""]
+    #[doc = "@return A status code which is 0 on success."]
+    pub request: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            key: LV2_URID,
+            type_: LV2_URID,
+            features: *const *const LV2_Feature,
+        ) -> LV2UI_Request_Value_Status,
+    >,
+}
+#[doc = "UI Idle Interface (LV2_UI__idleInterface)"]
+#[doc = ""]
+#[doc = "UIs can provide this interface to have an idle() callback called by the host"]
+#[doc = "rapidly to update the UI."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Idle_Interface {
+    #[doc = "Run a single iteration of the UI's idle loop."]
+    #[doc = ""]
+    #[doc = "This will be called rapidly in the UI thread at a rate appropriate"]
+    #[doc = "for a toolkit main loop.  There are no precise timing guarantees, but"]
+    #[doc = "the host should attempt to call idle() at a high enough rate for smooth"]
+    #[doc = "animation, at least 30Hz."]
+    #[doc = ""]
+    #[doc = "@return non-zero if the UI has been closed, in which case the host"]
+    #[doc = "should stop calling idle(), and can either completely destroy the UI, or"]
+    #[doc = "re-show it and resume calling idle()."]
+    pub idle:
+        ::std::option::Option<unsafe extern "C" fn(ui: LV2UI_Handle) -> ::std::os::raw::c_int>,
+}
+#[doc = "UI Show Interface (LV2_UI__showInterface)"]
+#[doc = ""]
+#[doc = "UIs can provide this interface to show and hide a window, which allows them"]
+#[doc = "to function in hosts unable to embed their widget.  This allows any UI to"]
+#[doc = "provide a fallback for embedding that works in any host."]
+#[doc = ""]
+#[doc = "If used:"]
+#[doc = "- The host MUST use LV2UI_Idle_Interface to drive the UI."]
+#[doc = "- The UI MUST return non-zero from LV2UI_Idle_Interface::idle() when it has been closed."]
+#[doc = "- If idle() returns non-zero, the host MUST call hide() and stop calling"]
+#[doc = "idle().  It MAY later call show() then resume calling idle()."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Show_Interface {
+    #[doc = "Show a window for this UI."]
+    #[doc = ""]
+    #[doc = "The window title MAY have been passed by the host to"]
+    #[doc = "LV2UI_Descriptor::instantiate() as an LV2_Options_Option with key"]
+    #[doc = "LV2_UI__windowTitle."]
+    #[doc = ""]
+    #[doc = "@return 0 on success, or anything else to stop being called."]
+    pub show:
+        ::std::option::Option<unsafe extern "C" fn(ui: LV2UI_Handle) -> ::std::os::raw::c_int>,
+    #[doc = "Hide the window for this UI."]
+    #[doc = ""]
+    #[doc = "@return 0 on success, or anything else to stop being called."]
+    pub hide:
+        ::std::option::Option<unsafe extern "C" fn(ui: LV2UI_Handle) -> ::std::os::raw::c_int>,
+}
+#[doc = "Peak data for a slice of time, the update format for ui:peakProtocol."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Peak_Data {
+    #[doc = "The start of the measurement period.  This is just a running counter"]
+    #[doc = "that is only meaningful in comparison to previous values and must not be"]
+    #[doc = "interpreted as an absolute time."]
+    pub period_start: u32,
+    #[doc = "The size of the measurement period, in the same units as period_start."]
+    pub period_size: u32,
+    #[doc = "The peak value for the measurement period. This should be the maximal"]
+    #[doc = "value for abs(sample) over all the samples in the period."]
+    pub peak: f32,
+}
+#[doc = "The type of the lv2ui_descriptor() function."]
+pub type LV2UI_DescriptorFunction =
+    ::std::option::Option<unsafe extern "C" fn(index: u32) -> *const LV2UI_Descriptor>;
+pub type LV2_URI_Map_Callback_Data = *mut ::std::os::raw::c_void;
+#[doc = "URI Map Feature."]
+#[doc = ""]
+#[doc = "To support this feature the host must pass an LV2_Feature struct to the"]
+#[doc = "plugin's instantiate method with URI \"http://lv2plug.in/ns/ext/uri-map\""]
+#[doc = "and data pointed to an instance of this struct."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_URI_Map_Feature {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "The plugin MUST pass this to any call to functions in this struct."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub callback_data: LV2_URI_Map_Callback_Data,
+    #[doc = "Get the numeric ID of a URI from the host."]
+    #[doc = ""]
+    #[doc = "@param callback_data Must be the callback_data member of this struct."]
+    #[doc = "@param map The 'context' of this URI. Certain extensions may define a"]
+    #[doc = "URI that must be passed here with certain restrictions on the return"]
+    #[doc = "value (e.g. limited range). This value may be NULL if the plugin needs"]
+    #[doc = "an ID for a URI in general. Extensions SHOULD NOT define a context"]
+    #[doc = "unless there is a specific need to do so, e.g. to restrict the range of"]
+    #[doc = "the returned value."]
+    #[doc = "@param uri The URI to be mapped to an integer ID."]
+    #[doc = ""]
+    #[doc = "This function is referentially transparent; any number of calls with the"]
+    #[doc = "same arguments is guaranteed to return the same value over the life of a"]
+    #[doc = "plugin instance (though the same URI may return different values with a"]
+    #[doc = "different map parameter). However, this function is not necessarily very"]
+    #[doc = "fast: plugins SHOULD cache any IDs they might need in performance"]
+    #[doc = "critical situations."]
+    #[doc = ""]
+    #[doc = "The return value 0 is reserved and indicates that an ID for that URI"]
+    #[doc = "could not be created for whatever reason. Extensions MAY define more"]
+    #[doc = "precisely what this means in a certain context, but in general plugins"]
+    #[doc = "SHOULD handle this situation as gracefully as possible. However, hosts"]
+    #[doc = "SHOULD NOT return 0 from this function in non-exceptional circumstances"]
+    #[doc = "(e.g. the URI map SHOULD be dynamic). Hosts that statically support only"]
+    #[doc = "a fixed set of URIs should not expect plugins to function correctly."]
+    pub uri_to_id: ::std::option::Option<
+        unsafe extern "C" fn(
+            callback_data: LV2_URI_Map_Callback_Data,
+            map: *const ::std::os::raw::c_char,
+            uri: *const ::std::os::raw::c_char,
+        ) -> u32,
+    >,
+}
+#[doc = "< Completed successfully."]
+pub const LV2_Worker_Status_LV2_WORKER_SUCCESS: LV2_Worker_Status = 0;
+#[doc = "< Unknown error."]
+pub const LV2_Worker_Status_LV2_WORKER_ERR_UNKNOWN: LV2_Worker_Status = 1;
+#[doc = "< Failed due to lack of space."]
+pub const LV2_Worker_Status_LV2_WORKER_ERR_NO_SPACE: LV2_Worker_Status = 2;
+#[doc = "Status code for worker functions."]
+pub type LV2_Worker_Status = u32;
+#[doc = " Opaque handle for LV2_Worker_Interface::work()."]
+pub type LV2_Worker_Respond_Handle = *mut ::std::os::raw::c_void;
+#[doc = "A function to respond to run() from the worker method."]
+#[doc = ""]
+#[doc = "The `data` MUST be safe for the host to copy and later pass to"]
+#[doc = "work_response(), and the host MUST guarantee that it will be eventually"]
+#[doc = "passed to work_response() if this function returns LV2_WORKER_SUCCESS."]
+pub type LV2_Worker_Respond_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_Worker_Respond_Handle,
+        size: u32,
+        data: *const ::std::os::raw::c_void,
+    ) -> LV2_Worker_Status,
+>;
+#[doc = "Plugin Worker Interface."]
+#[doc = ""]
+#[doc = "This is the interface provided by the plugin to implement a worker method."]
+#[doc = "The plugin's extension_data() method should return an LV2_Worker_Interface"]
+#[doc = "when called with LV2_WORKER__interface as its argument."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Worker_Interface {
+    #[doc = "The worker method.  This is called by the host in a non-realtime context"]
+    #[doc = "as requested, possibly with an arbitrary message to handle."]
+    #[doc = ""]
+    #[doc = "A response can be sent to run() using `respond`.  The plugin MUST NOT"]
+    #[doc = "make any assumptions about which thread calls this method, except that"]
+    #[doc = "there are no real-time requirements and only one call may be executed at"]
+    #[doc = "a time.  That is, the host MAY call this method from any non-real-time"]
+    #[doc = "thread, but MUST NOT make concurrent calls to this method from several"]
+    #[doc = "threads."]
+    #[doc = ""]
+    #[doc = "@param instance The LV2 instance this is a method on."]
+    #[doc = "@param respond  A function for sending a response to run()."]
+    #[doc = "@param handle   Must be passed to `respond` if it is called."]
+    #[doc = "@param size     The size of `data`."]
+    #[doc = "@param data     Data from run(), or NULL."]
+    pub work: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            respond: LV2_Worker_Respond_Function,
+            handle: LV2_Worker_Respond_Handle,
+            size: u32,
+            data: *const ::std::os::raw::c_void,
+        ) -> LV2_Worker_Status,
+    >,
+    #[doc = "Handle a response from the worker.  This is called by the host in the"]
+    #[doc = "run() context when a response from the worker is ready."]
+    #[doc = ""]
+    #[doc = "@param instance The LV2 instance this is a method on."]
+    #[doc = "@param size     The size of `body`."]
+    #[doc = "@param body     Message body, or NULL."]
+    pub work_response: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            size: u32,
+            body: *const ::std::os::raw::c_void,
+        ) -> LV2_Worker_Status,
+    >,
+    #[doc = "Called when all responses for this cycle have been delivered."]
+    #[doc = ""]
+    #[doc = "Since work_response() may be called after run() finished, this provides"]
+    #[doc = "a hook for code that must run after the cycle is completed."]
+    #[doc = ""]
+    #[doc = "This field may be NULL if the plugin has no use for it.  Otherwise, the"]
+    #[doc = "host MUST call it after every run(), regardless of whether or not any"]
+    #[doc = "responses were sent that cycle."]
+    pub end_run:
+        ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle) -> LV2_Worker_Status>,
+}
+#[doc = " Opaque handle for LV2_Worker_Schedule."]
+pub type LV2_Worker_Schedule_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Schedule Worker Host Feature."]
+#[doc = ""]
+#[doc = "The host passes this feature to provide a schedule_work() function, which"]
+#[doc = "the plugin can use to schedule a worker call from run()."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Worker_Schedule {
+    #[doc = "Opaque host data."]
+    pub handle: LV2_Worker_Schedule_Handle,
+    #[doc = "Request from run() that the host call the worker."]
+    #[doc = ""]
+    #[doc = "This function is in the audio threading class.  It should be called from"]
+    #[doc = "run() to request that the host call the work() method in a non-realtime"]
+    #[doc = "context with the given arguments."]
+    #[doc = ""]
+    #[doc = "This function is always safe to call from run(), but it is not"]
+    #[doc = "guaranteed that the worker is actually called from a different thread."]
+    #[doc = "In particular, when free-wheeling (for example, during offline"]
+    #[doc = "rendering), the worker may be executed immediately.  This allows"]
+    #[doc = "single-threaded processing with sample accuracy and avoids timing"]
+    #[doc = "problems when run() is executing much faster or slower than real-time."]
+    #[doc = ""]
+    #[doc = "Plugins SHOULD be written in such a way that if the worker runs"]
+    #[doc = "immediately, and responses from the worker are delivered immediately,"]
+    #[doc = "the effect of the work takes place immediately with sample accuracy."]
+    #[doc = ""]
+    #[doc = "The `data` MUST be safe for the host to copy and later pass to work(),"]
+    #[doc = "and the host MUST guarantee that it will be eventually passed to work()"]
+    #[doc = "if this function returns LV2_WORKER_SUCCESS."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = "@param size   The size of `data`."]
+    #[doc = "@param data   Message to pass to work(), or NULL."]
+    pub schedule_work: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_Worker_Schedule_Handle,
+            size: u32,
+            data: *const ::std::os::raw::c_void,
+        ) -> LV2_Worker_Status,
+    >,
+}
+pub type __builtin_va_list = *mut ::std::os::raw::c_char;
diff --git a/sys/src/linux/x86_64.rs b/sys/src/linux/x86_64.rs
new file mode 100644
index 00000000..438ccff2
--- /dev/null
+++ b/sys/src/linux/x86_64.rs
@@ -0,0 +1,2728 @@
+/* automatically generated by rust-bindgen */
+
+pub const LV2_ATOM_URI: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/atom\0";
+pub const LV2_ATOM_PREFIX: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/atom#\0";
+pub const LV2_ATOM__Atom: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#Atom\0";
+pub const LV2_ATOM__AtomPort: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#AtomPort\0";
+pub const LV2_ATOM__Blank: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Blank\0";
+pub const LV2_ATOM__Bool: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#Bool\0";
+pub const LV2_ATOM__Chunk: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Chunk\0";
+pub const LV2_ATOM__Double: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#Double\0";
+pub const LV2_ATOM__Event: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Event\0";
+pub const LV2_ATOM__Float: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Float\0";
+pub const LV2_ATOM__Int: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/atom#Int\0";
+pub const LV2_ATOM__Literal: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/atom#Literal\0";
+pub const LV2_ATOM__Long: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#Long\0";
+pub const LV2_ATOM__Number: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#Number\0";
+pub const LV2_ATOM__Object: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#Object\0";
+pub const LV2_ATOM__Path: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#Path\0";
+pub const LV2_ATOM__Property: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#Property\0";
+pub const LV2_ATOM__Resource: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#Resource\0";
+pub const LV2_ATOM__Sequence: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#Sequence\0";
+pub const LV2_ATOM__Sound: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Sound\0";
+pub const LV2_ATOM__String: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#String\0";
+pub const LV2_ATOM__Tuple: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Tuple\0";
+pub const LV2_ATOM__URI: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/atom#URI\0";
+pub const LV2_ATOM__URID: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#URID\0";
+pub const LV2_ATOM__Vector: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#Vector\0";
+pub const LV2_ATOM__atomTransfer: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/atom#atomTransfer\0";
+pub const LV2_ATOM__beatTime: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#beatTime\0";
+pub const LV2_ATOM__bufferType: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/atom#bufferType\0";
+pub const LV2_ATOM__childType: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/atom#childType\0";
+pub const LV2_ATOM__eventTransfer: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/atom#eventTransfer\0";
+pub const LV2_ATOM__frameTime: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/atom#frameTime\0";
+pub const LV2_ATOM__supports: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#supports\0";
+pub const LV2_ATOM__timeUnit: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#timeUnit\0";
+pub const LV2_ATOM_REFERENCE_TYPE: u32 = 0;
+pub const LV2_URID_URI: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/urid\0";
+pub const LV2_URID_PREFIX: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/urid#\0";
+pub const LV2_URID__map: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/urid#map\0";
+pub const LV2_URID__unmap: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/urid#unmap\0";
+pub const LV2_URID_MAP_URI: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/urid#map\0";
+pub const LV2_URID_UNMAP_URI: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/urid#unmap\0";
+pub const LV2_BUF_SIZE_URI: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/buf-size\0";
+pub const LV2_BUF_SIZE_PREFIX: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/buf-size#\0";
+pub const LV2_BUF_SIZE__boundedBlockLength: &'static [u8; 53usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#boundedBlockLength\0";
+pub const LV2_BUF_SIZE__fixedBlockLength: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#fixedBlockLength\0";
+pub const LV2_BUF_SIZE__maxBlockLength: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#maxBlockLength\0";
+pub const LV2_BUF_SIZE__minBlockLength: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#minBlockLength\0";
+pub const LV2_BUF_SIZE__nominalBlockLength: &'static [u8; 53usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#nominalBlockLength\0";
+pub const LV2_BUF_SIZE__powerOf2BlockLength: &'static [u8; 54usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#powerOf2BlockLength\0";
+pub const LV2_BUF_SIZE__sequenceSize: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#sequenceSize\0";
+pub const LV2_CORE_URI: &'static [u8; 29usize] = b"http://lv2plug.in/ns/lv2core\0";
+pub const LV2_CORE_PREFIX: &'static [u8; 30usize] = b"http://lv2plug.in/ns/lv2core#\0";
+pub const LV2_CORE__AllpassPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#AllpassPlugin\0";
+pub const LV2_CORE__AmplifierPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#AmplifierPlugin\0";
+pub const LV2_CORE__AnalyserPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#AnalyserPlugin\0";
+pub const LV2_CORE__AudioPort: &'static [u8; 39usize] = b"http://lv2plug.in/ns/lv2core#AudioPort\0";
+pub const LV2_CORE__BandpassPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#BandpassPlugin\0";
+pub const LV2_CORE__CVPort: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#CVPort\0";
+pub const LV2_CORE__ChorusPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#ChorusPlugin\0";
+pub const LV2_CORE__CombPlugin: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#CombPlugin\0";
+pub const LV2_CORE__CompressorPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#CompressorPlugin\0";
+pub const LV2_CORE__ConstantPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#ConstantPlugin\0";
+pub const LV2_CORE__ControlPort: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#ControlPort\0";
+pub const LV2_CORE__ConverterPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#ConverterPlugin\0";
+pub const LV2_CORE__DelayPlugin: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#DelayPlugin\0";
+pub const LV2_CORE__DistortionPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#DistortionPlugin\0";
+pub const LV2_CORE__DynamicsPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#DynamicsPlugin\0";
+pub const LV2_CORE__EQPlugin: &'static [u8; 38usize] = b"http://lv2plug.in/ns/lv2core#EQPlugin\0";
+pub const LV2_CORE__EnvelopePlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#EnvelopePlugin\0";
+pub const LV2_CORE__ExpanderPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#ExpanderPlugin\0";
+pub const LV2_CORE__ExtensionData: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#ExtensionData\0";
+pub const LV2_CORE__Feature: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#Feature\0";
+pub const LV2_CORE__FilterPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#FilterPlugin\0";
+pub const LV2_CORE__FlangerPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#FlangerPlugin\0";
+pub const LV2_CORE__FunctionPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#FunctionPlugin\0";
+pub const LV2_CORE__GatePlugin: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#GatePlugin\0";
+pub const LV2_CORE__GeneratorPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#GeneratorPlugin\0";
+pub const LV2_CORE__HighpassPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#HighpassPlugin\0";
+pub const LV2_CORE__InputPort: &'static [u8; 39usize] = b"http://lv2plug.in/ns/lv2core#InputPort\0";
+pub const LV2_CORE__InstrumentPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#InstrumentPlugin\0";
+pub const LV2_CORE__LimiterPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#LimiterPlugin\0";
+pub const LV2_CORE__LowpassPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#LowpassPlugin\0";
+pub const LV2_CORE__MixerPlugin: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#MixerPlugin\0";
+pub const LV2_CORE__ModulatorPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#ModulatorPlugin\0";
+pub const LV2_CORE__MultiEQPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#MultiEQPlugin\0";
+pub const LV2_CORE__OscillatorPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#OscillatorPlugin\0";
+pub const LV2_CORE__OutputPort: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#OutputPort\0";
+pub const LV2_CORE__ParaEQPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#ParaEQPlugin\0";
+pub const LV2_CORE__PhaserPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#PhaserPlugin\0";
+pub const LV2_CORE__PitchPlugin: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#PitchPlugin\0";
+pub const LV2_CORE__Plugin: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#Plugin\0";
+pub const LV2_CORE__PluginBase: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#PluginBase\0";
+pub const LV2_CORE__Point: &'static [u8; 35usize] = b"http://lv2plug.in/ns/lv2core#Point\0";
+pub const LV2_CORE__Port: &'static [u8; 34usize] = b"http://lv2plug.in/ns/lv2core#Port\0";
+pub const LV2_CORE__PortProperty: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#PortProperty\0";
+pub const LV2_CORE__Resource: &'static [u8; 38usize] = b"http://lv2plug.in/ns/lv2core#Resource\0";
+pub const LV2_CORE__ReverbPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#ReverbPlugin\0";
+pub const LV2_CORE__ScalePoint: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#ScalePoint\0";
+pub const LV2_CORE__SimulatorPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#SimulatorPlugin\0";
+pub const LV2_CORE__SpatialPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#SpatialPlugin\0";
+pub const LV2_CORE__Specification: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#Specification\0";
+pub const LV2_CORE__SpectralPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#SpectralPlugin\0";
+pub const LV2_CORE__UtilityPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#UtilityPlugin\0";
+pub const LV2_CORE__WaveshaperPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#WaveshaperPlugin\0";
+pub const LV2_CORE__appliesTo: &'static [u8; 39usize] = b"http://lv2plug.in/ns/lv2core#appliesTo\0";
+pub const LV2_CORE__binary: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#binary\0";
+pub const LV2_CORE__connectionOptional: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/lv2core#connectionOptional\0";
+pub const LV2_CORE__control: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#control\0";
+pub const LV2_CORE__default: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#default\0";
+pub const LV2_CORE__designation: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#designation\0";
+pub const LV2_CORE__documentation: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#documentation\0";
+pub const LV2_CORE__enumeration: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#enumeration\0";
+pub const LV2_CORE__extensionData: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#extensionData\0";
+pub const LV2_CORE__freeWheeling: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#freeWheeling\0";
+pub const LV2_CORE__hardRTCapable: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#hardRTCapable\0";
+pub const LV2_CORE__inPlaceBroken: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#inPlaceBroken\0";
+pub const LV2_CORE__index: &'static [u8; 35usize] = b"http://lv2plug.in/ns/lv2core#index\0";
+pub const LV2_CORE__integer: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#integer\0";
+pub const LV2_CORE__isLive: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#isLive\0";
+pub const LV2_CORE__latency: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#latency\0";
+pub const LV2_CORE__maximum: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#maximum\0";
+pub const LV2_CORE__microVersion: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#microVersion\0";
+pub const LV2_CORE__minimum: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#minimum\0";
+pub const LV2_CORE__minorVersion: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#minorVersion\0";
+pub const LV2_CORE__name: &'static [u8; 34usize] = b"http://lv2plug.in/ns/lv2core#name\0";
+pub const LV2_CORE__optionalFeature: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#optionalFeature\0";
+pub const LV2_CORE__port: &'static [u8; 34usize] = b"http://lv2plug.in/ns/lv2core#port\0";
+pub const LV2_CORE__portProperty: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#portProperty\0";
+pub const LV2_CORE__project: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#project\0";
+pub const LV2_CORE__prototype: &'static [u8; 39usize] = b"http://lv2plug.in/ns/lv2core#prototype\0";
+pub const LV2_CORE__reportsLatency: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#reportsLatency\0";
+pub const LV2_CORE__requiredFeature: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#requiredFeature\0";
+pub const LV2_CORE__sampleRate: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#sampleRate\0";
+pub const LV2_CORE__scalePoint: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#scalePoint\0";
+pub const LV2_CORE__symbol: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#symbol\0";
+pub const LV2_CORE__toggled: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#toggled\0";
+pub const LV2_DATA_ACCESS_URI: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/data-access\0";
+pub const LV2_DATA_ACCESS_PREFIX: &'static [u8; 38usize] =
+    b"http://lv2plug.in/ns/ext/data-access#\0";
+pub const LV2_DYN_MANIFEST_URI: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/dynmanifest\0";
+pub const LV2_DYN_MANIFEST_PREFIX: &'static [u8; 38usize] =
+    b"http://lv2plug.in/ns/ext/dynmanifest#\0";
+pub const LV2_EVENT_URI: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/event\0";
+pub const LV2_EVENT_PREFIX: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/event#\0";
+pub const LV2_EVENT__Event: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/event#Event\0";
+pub const LV2_EVENT__EventPort: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/event#EventPort\0";
+pub const LV2_EVENT__FrameStamp: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/event#FrameStamp\0";
+pub const LV2_EVENT__TimeStamp: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/event#TimeStamp\0";
+pub const LV2_EVENT__generatesTimeStamp: &'static [u8; 50usize] =
+    b"http://lv2plug.in/ns/ext/event#generatesTimeStamp\0";
+pub const LV2_EVENT__generic: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/event#generic\0";
+pub const LV2_EVENT__inheritsEvent: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/event#inheritsEvent\0";
+pub const LV2_EVENT__inheritsTimeStamp: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/event#inheritsTimeStamp\0";
+pub const LV2_EVENT__supportsEvent: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/event#supportsEvent\0";
+pub const LV2_EVENT__supportsTimeStamp: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/event#supportsTimeStamp\0";
+pub const LV2_EVENT_AUDIO_STAMP: u32 = 0;
+pub const LV2_INSTANCE_ACCESS_URI: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/instance-access\0";
+pub const LV2_LOG_URI: &'static [u8; 29usize] = b"http://lv2plug.in/ns/ext/log\0";
+pub const LV2_LOG_PREFIX: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/log#\0";
+pub const LV2_LOG__Entry: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/log#Entry\0";
+pub const LV2_LOG__Error: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/log#Error\0";
+pub const LV2_LOG__Note: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/log#Note\0";
+pub const LV2_LOG__Trace: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/log#Trace\0";
+pub const LV2_LOG__Warning: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/log#Warning\0";
+pub const LV2_LOG__log: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/log#log\0";
+pub const LV2_MIDI_URI: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/midi\0";
+pub const LV2_MIDI_PREFIX: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/midi#\0";
+pub const LV2_MIDI__ActiveSense: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/midi#ActiveSense\0";
+pub const LV2_MIDI__Aftertouch: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#Aftertouch\0";
+pub const LV2_MIDI__Bender: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/midi#Bender\0";
+pub const LV2_MIDI__ChannelPressure: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/midi#ChannelPressure\0";
+pub const LV2_MIDI__Chunk: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#Chunk\0";
+pub const LV2_MIDI__Clock: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#Clock\0";
+pub const LV2_MIDI__Continue: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/midi#Continue\0";
+pub const LV2_MIDI__Controller: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#Controller\0";
+pub const LV2_MIDI__MidiEvent: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/midi#MidiEvent\0";
+pub const LV2_MIDI__NoteOff: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/midi#NoteOff\0";
+pub const LV2_MIDI__NoteOn: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/midi#NoteOn\0";
+pub const LV2_MIDI__ProgramChange: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/midi#ProgramChange\0";
+pub const LV2_MIDI__QuarterFrame: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#QuarterFrame\0";
+pub const LV2_MIDI__Reset: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#Reset\0";
+pub const LV2_MIDI__SongPosition: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#SongPosition\0";
+pub const LV2_MIDI__SongSelect: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#SongSelect\0";
+pub const LV2_MIDI__Start: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#Start\0";
+pub const LV2_MIDI__Stop: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/midi#Stop\0";
+pub const LV2_MIDI__SystemCommon: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#SystemCommon\0";
+pub const LV2_MIDI__SystemExclusive: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/midi#SystemExclusive\0";
+pub const LV2_MIDI__SystemMessage: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/midi#SystemMessage\0";
+pub const LV2_MIDI__SystemRealtime: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/midi#SystemRealtime\0";
+pub const LV2_MIDI__Tick: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/midi#Tick\0";
+pub const LV2_MIDI__TuneRequest: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/midi#TuneRequest\0";
+pub const LV2_MIDI__VoiceMessage: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#VoiceMessage\0";
+pub const LV2_MIDI__benderValue: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/midi#benderValue\0";
+pub const LV2_MIDI__binding: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/midi#binding\0";
+pub const LV2_MIDI__byteNumber: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#byteNumber\0";
+pub const LV2_MIDI__channel: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/midi#channel\0";
+pub const LV2_MIDI__chunk: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#chunk\0";
+pub const LV2_MIDI__controllerNumber: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/midi#controllerNumber\0";
+pub const LV2_MIDI__controllerValue: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/midi#controllerValue\0";
+pub const LV2_MIDI__noteNumber: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#noteNumber\0";
+pub const LV2_MIDI__pressure: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/midi#pressure\0";
+pub const LV2_MIDI__programNumber: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/midi#programNumber\0";
+pub const LV2_MIDI__property: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/midi#property\0";
+pub const LV2_MIDI__songNumber: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#songNumber\0";
+pub const LV2_MIDI__songPosition: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#songPosition\0";
+pub const LV2_MIDI__status: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/midi#status\0";
+pub const LV2_MIDI__statusMask: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#statusMask\0";
+pub const LV2_MIDI__velocity: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/midi#velocity\0";
+pub const LV2_MORPH_URI: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/morph\0";
+pub const LV2_MORPH_PREFIX: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/morph#\0";
+pub const LV2_MORPH__AutoMorphPort: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/morph#AutoMorphPort\0";
+pub const LV2_MORPH__MorphPort: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/morph#MorphPort\0";
+pub const LV2_MORPH__interface: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/morph#interface\0";
+pub const LV2_MORPH__supportsType: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/morph#supportsType\0";
+pub const LV2_MORPH__currentType: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/morph#currentType\0";
+pub const LV2_OPTIONS_URI: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/options\0";
+pub const LV2_OPTIONS_PREFIX: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/options#\0";
+pub const LV2_OPTIONS__Option: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/options#Option\0";
+pub const LV2_OPTIONS__interface: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/options#interface\0";
+pub const LV2_OPTIONS__options: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/options#options\0";
+pub const LV2_OPTIONS__requiredOption: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/options#requiredOption\0";
+pub const LV2_OPTIONS__supportedOption: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/options#supportedOption\0";
+pub const LV2_PARAMETERS_URI: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/parameters\0";
+pub const LV2_PARAMETERS_PREFIX: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/parameters#\0";
+pub const LV2_PARAMETERS__CompressorControls: &'static [u8; 55usize] =
+    b"http://lv2plug.in/ns/ext/parameters#CompressorControls\0";
+pub const LV2_PARAMETERS__ControlGroup: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/parameters#ControlGroup\0";
+pub const LV2_PARAMETERS__EnvelopeControls: &'static [u8; 53usize] =
+    b"http://lv2plug.in/ns/ext/parameters#EnvelopeControls\0";
+pub const LV2_PARAMETERS__FilterControls: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/ext/parameters#FilterControls\0";
+pub const LV2_PARAMETERS__OscillatorControls: &'static [u8; 55usize] =
+    b"http://lv2plug.in/ns/ext/parameters#OscillatorControls\0";
+pub const LV2_PARAMETERS__amplitude: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/parameters#amplitude\0";
+pub const LV2_PARAMETERS__attack: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/parameters#attack\0";
+pub const LV2_PARAMETERS__bypass: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/parameters#bypass\0";
+pub const LV2_PARAMETERS__cutoffFrequency: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/ext/parameters#cutoffFrequency\0";
+pub const LV2_PARAMETERS__decay: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/parameters#decay\0";
+pub const LV2_PARAMETERS__delay: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/parameters#delay\0";
+pub const LV2_PARAMETERS__dryLevel: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/parameters#dryLevel\0";
+pub const LV2_PARAMETERS__frequency: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/parameters#frequency\0";
+pub const LV2_PARAMETERS__gain: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/parameters#gain\0";
+pub const LV2_PARAMETERS__hold: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/parameters#hold\0";
+pub const LV2_PARAMETERS__pulseWidth: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/parameters#pulseWidth\0";
+pub const LV2_PARAMETERS__ratio: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/parameters#ratio\0";
+pub const LV2_PARAMETERS__release: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/parameters#release\0";
+pub const LV2_PARAMETERS__resonance: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/parameters#resonance\0";
+pub const LV2_PARAMETERS__sampleRate: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/parameters#sampleRate\0";
+pub const LV2_PARAMETERS__sustain: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/parameters#sustain\0";
+pub const LV2_PARAMETERS__threshold: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/parameters#threshold\0";
+pub const LV2_PARAMETERS__waveform: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/parameters#waveform\0";
+pub const LV2_PARAMETERS__wetDryRatio: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/parameters#wetDryRatio\0";
+pub const LV2_PARAMETERS__wetLevel: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/parameters#wetLevel\0";
+pub const LV2_PATCH_URI: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/patch\0";
+pub const LV2_PATCH_PREFIX: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/patch#\0";
+pub const LV2_PATCH__Ack: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#Ack\0";
+pub const LV2_PATCH__Delete: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/patch#Delete\0";
+pub const LV2_PATCH__Copy: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/patch#Copy\0";
+pub const LV2_PATCH__Error: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/patch#Error\0";
+pub const LV2_PATCH__Get: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#Get\0";
+pub const LV2_PATCH__Message: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#Message\0";
+pub const LV2_PATCH__Move: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/patch#Move\0";
+pub const LV2_PATCH__Patch: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/patch#Patch\0";
+pub const LV2_PATCH__Post: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/patch#Post\0";
+pub const LV2_PATCH__Put: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#Put\0";
+pub const LV2_PATCH__Request: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#Request\0";
+pub const LV2_PATCH__Response: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#Response\0";
+pub const LV2_PATCH__Set: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#Set\0";
+pub const LV2_PATCH__accept: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/patch#accept\0";
+pub const LV2_PATCH__add: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#add\0";
+pub const LV2_PATCH__body: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/patch#body\0";
+pub const LV2_PATCH__context: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#context\0";
+pub const LV2_PATCH__destination: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/patch#destination\0";
+pub const LV2_PATCH__property: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#property\0";
+pub const LV2_PATCH__readable: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#readable\0";
+pub const LV2_PATCH__remove: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/patch#remove\0";
+pub const LV2_PATCH__request: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#request\0";
+pub const LV2_PATCH__subject: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#subject\0";
+pub const LV2_PATCH__sequenceNumber: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/patch#sequenceNumber\0";
+pub const LV2_PATCH__value: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/patch#value\0";
+pub const LV2_PATCH__wildcard: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#wildcard\0";
+pub const LV2_PATCH__writable: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#writable\0";
+pub const LV2_PORT_GROUPS_URI: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/port-groups\0";
+pub const LV2_PORT_GROUPS_PREFIX: &'static [u8; 38usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#\0";
+pub const LV2_PORT_GROUPS__DiscreteGroup: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#DiscreteGroup\0";
+pub const LV2_PORT_GROUPS__Element: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#Element\0";
+pub const LV2_PORT_GROUPS__FivePointOneGroup: &'static [u8; 55usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#FivePointOneGroup\0";
+pub const LV2_PORT_GROUPS__FivePointZeroGroup: &'static [u8; 56usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#FivePointZeroGroup\0";
+pub const LV2_PORT_GROUPS__FourPointZeroGroup: &'static [u8; 56usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#FourPointZeroGroup\0";
+pub const LV2_PORT_GROUPS__Group: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#Group\0";
+pub const LV2_PORT_GROUPS__InputGroup: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#InputGroup\0";
+pub const LV2_PORT_GROUPS__MidSideGroup: &'static [u8; 50usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#MidSideGroup\0";
+pub const LV2_PORT_GROUPS__MonoGroup: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#MonoGroup\0";
+pub const LV2_PORT_GROUPS__OutputGroup: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#OutputGroup\0";
+pub const LV2_PORT_GROUPS__SevenPointOneGroup: &'static [u8; 56usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#SevenPointOneGroup\0";
+pub const LV2_PORT_GROUPS__SevenPointOneWideGroup: &'static [u8; 60usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#SevenPointOneWideGroup\0";
+pub const LV2_PORT_GROUPS__SixPointOneGroup: &'static [u8; 54usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#SixPointOneGroup\0";
+pub const LV2_PORT_GROUPS__StereoGroup: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#StereoGroup\0";
+pub const LV2_PORT_GROUPS__ThreePointZeroGroup: &'static [u8; 57usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#ThreePointZeroGroup\0";
+pub const LV2_PORT_GROUPS__center: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#center\0";
+pub const LV2_PORT_GROUPS__centerLeft: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#centerLeft\0";
+pub const LV2_PORT_GROUPS__centerRight: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#centerRight\0";
+pub const LV2_PORT_GROUPS__element: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#element\0";
+pub const LV2_PORT_GROUPS__group: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#group\0";
+pub const LV2_PORT_GROUPS__left: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#left\0";
+pub const LV2_PORT_GROUPS__lowFrequencyEffects: &'static [u8; 57usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#lowFrequencyEffects\0";
+pub const LV2_PORT_GROUPS__mainInput: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#mainInput\0";
+pub const LV2_PORT_GROUPS__mainOutput: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#mainOutput\0";
+pub const LV2_PORT_GROUPS__rearCenter: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#rearCenter\0";
+pub const LV2_PORT_GROUPS__rearLeft: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#rearLeft\0";
+pub const LV2_PORT_GROUPS__rearRight: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#rearRight\0";
+pub const LV2_PORT_GROUPS__right: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#right\0";
+pub const LV2_PORT_GROUPS__side: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#side\0";
+pub const LV2_PORT_GROUPS__sideChainOf: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#sideChainOf\0";
+pub const LV2_PORT_GROUPS__sideLeft: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#sideLeft\0";
+pub const LV2_PORT_GROUPS__sideRight: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#sideRight\0";
+pub const LV2_PORT_GROUPS__source: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#source\0";
+pub const LV2_PORT_GROUPS__subGroupOf: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#subGroupOf\0";
+pub const LV2_PORT_PROPS_URI: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/port-props\0";
+pub const LV2_PORT_PROPS_PREFIX: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/port-props#\0";
+pub const LV2_PORT_PROPS__causesArtifacts: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/ext/port-props#causesArtifacts\0";
+pub const LV2_PORT_PROPS__continuousCV: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-props#continuousCV\0";
+pub const LV2_PORT_PROPS__discreteCV: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-props#discreteCV\0";
+pub const LV2_PORT_PROPS__displayPriority: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/ext/port-props#displayPriority\0";
+pub const LV2_PORT_PROPS__expensive: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/port-props#expensive\0";
+pub const LV2_PORT_PROPS__hasStrictBounds: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/ext/port-props#hasStrictBounds\0";
+pub const LV2_PORT_PROPS__logarithmic: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-props#logarithmic\0";
+pub const LV2_PORT_PROPS__notAutomatic: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-props#notAutomatic\0";
+pub const LV2_PORT_PROPS__notOnGUI: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/port-props#notOnGUI\0";
+pub const LV2_PORT_PROPS__rangeSteps: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-props#rangeSteps\0";
+pub const LV2_PORT_PROPS__supportsStrictBounds: &'static [u8; 57usize] =
+    b"http://lv2plug.in/ns/ext/port-props#supportsStrictBounds\0";
+pub const LV2_PORT_PROPS__trigger: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/port-props#trigger\0";
+pub const LV2_PRESETS_URI: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/presets\0";
+pub const LV2_PRESETS_PREFIX: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/presets#\0";
+pub const LV2_PRESETS__Bank: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/presets#Bank\0";
+pub const LV2_PRESETS__Preset: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/presets#Preset\0";
+pub const LV2_PRESETS__bank: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/presets#bank\0";
+pub const LV2_PRESETS__preset: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/presets#preset\0";
+pub const LV2_PRESETS__value: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/presets#value\0";
+pub const LV2_RESIZE_PORT_URI: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/resize-port\0";
+pub const LV2_RESIZE_PORT_PREFIX: &'static [u8; 38usize] =
+    b"http://lv2plug.in/ns/ext/resize-port#\0";
+pub const LV2_RESIZE_PORT__asLargeAs: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/resize-port#asLargeAs\0";
+pub const LV2_RESIZE_PORT__minimumSize: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/resize-port#minimumSize\0";
+pub const LV2_RESIZE_PORT__resize: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/resize-port#resize\0";
+pub const LV2_STATE_URI: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/state\0";
+pub const LV2_STATE_PREFIX: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/state#\0";
+pub const LV2_STATE__State: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/state#State\0";
+pub const LV2_STATE__interface: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/state#interface\0";
+pub const LV2_STATE__loadDefaultState: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/state#loadDefaultState\0";
+pub const LV2_STATE__freePath: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/state#freePath\0";
+pub const LV2_STATE__makePath: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/state#makePath\0";
+pub const LV2_STATE__mapPath: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/state#mapPath\0";
+pub const LV2_STATE__state: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/state#state\0";
+pub const LV2_STATE__threadSafeRestore: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/state#threadSafeRestore\0";
+pub const LV2_STATE__StateChanged: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/state#StateChanged\0";
+pub const LV2_TIME_URI: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/time\0";
+pub const LV2_TIME_PREFIX: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/time#\0";
+pub const LV2_TIME__Time: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/time#Time\0";
+pub const LV2_TIME__Position: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/time#Position\0";
+pub const LV2_TIME__Rate: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/time#Rate\0";
+pub const LV2_TIME__position: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/time#position\0";
+pub const LV2_TIME__barBeat: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/time#barBeat\0";
+pub const LV2_TIME__bar: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/time#bar\0";
+pub const LV2_TIME__beat: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/time#beat\0";
+pub const LV2_TIME__beatUnit: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/time#beatUnit\0";
+pub const LV2_TIME__beatsPerBar: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/time#beatsPerBar\0";
+pub const LV2_TIME__beatsPerMinute: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/time#beatsPerMinute\0";
+pub const LV2_TIME__frame: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/time#frame\0";
+pub const LV2_TIME__framesPerSecond: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/time#framesPerSecond\0";
+pub const LV2_TIME__speed: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/time#speed\0";
+pub const LV2_UI_URI: &'static [u8; 35usize] = b"http://lv2plug.in/ns/extensions/ui\0";
+pub const LV2_UI_PREFIX: &'static [u8; 36usize] = b"http://lv2plug.in/ns/extensions/ui#\0";
+pub const LV2_UI__CocoaUI: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/ui#CocoaUI\0";
+pub const LV2_UI__Gtk3UI: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#Gtk3UI\0";
+pub const LV2_UI__GtkUI: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#GtkUI\0";
+pub const LV2_UI__PortNotification: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/extensions/ui#PortNotification\0";
+pub const LV2_UI__PortProtocol: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/extensions/ui#PortProtocol\0";
+pub const LV2_UI__Qt4UI: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#Qt4UI\0";
+pub const LV2_UI__Qt5UI: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#Qt5UI\0";
+pub const LV2_UI__UI: &'static [u8; 38usize] = b"http://lv2plug.in/ns/extensions/ui#UI\0";
+pub const LV2_UI__WindowsUI: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/ui#WindowsUI\0";
+pub const LV2_UI__X11UI: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#X11UI\0";
+pub const LV2_UI__binary: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#binary\0";
+pub const LV2_UI__fixedSize: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/ui#fixedSize\0";
+pub const LV2_UI__idleInterface: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/ui#idleInterface\0";
+pub const LV2_UI__noUserResize: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/extensions/ui#noUserResize\0";
+pub const LV2_UI__notifyType: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/extensions/ui#notifyType\0";
+pub const LV2_UI__parent: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#parent\0";
+pub const LV2_UI__plugin: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#plugin\0";
+pub const LV2_UI__portIndex: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/ui#portIndex\0";
+pub const LV2_UI__portMap: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/ui#portMap\0";
+pub const LV2_UI__portNotification: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/extensions/ui#portNotification\0";
+pub const LV2_UI__portSubscribe: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/ui#portSubscribe\0";
+pub const LV2_UI__protocol: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/extensions/ui#protocol\0";
+pub const LV2_UI__requestValue: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/extensions/ui#requestValue\0";
+pub const LV2_UI__floatProtocol: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/ui#floatProtocol\0";
+pub const LV2_UI__peakProtocol: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/extensions/ui#peakProtocol\0";
+pub const LV2_UI__resize: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#resize\0";
+pub const LV2_UI__showInterface: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/ui#showInterface\0";
+pub const LV2_UI__touch: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#touch\0";
+pub const LV2_UI__ui: &'static [u8; 38usize] = b"http://lv2plug.in/ns/extensions/ui#ui\0";
+pub const LV2_UI__updateRate: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/extensions/ui#updateRate\0";
+pub const LV2_UI__windowTitle: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/extensions/ui#windowTitle\0";
+pub const LV2_UI__scaleFactor: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/extensions/ui#scaleFactor\0";
+pub const LV2_UI__foregroundColor: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/extensions/ui#foregroundColor\0";
+pub const LV2_UI__backgroundColor: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/extensions/ui#backgroundColor\0";
+pub const LV2_UNITS_URI: &'static [u8; 38usize] = b"http://lv2plug.in/ns/extensions/units\0";
+pub const LV2_UNITS_PREFIX: &'static [u8; 39usize] = b"http://lv2plug.in/ns/extensions/units#\0";
+pub const LV2_UNITS__Conversion: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/units#Conversion\0";
+pub const LV2_UNITS__Unit: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#Unit\0";
+pub const LV2_UNITS__bar: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#bar\0";
+pub const LV2_UNITS__beat: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#beat\0";
+pub const LV2_UNITS__bpm: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#bpm\0";
+pub const LV2_UNITS__cent: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#cent\0";
+pub const LV2_UNITS__cm: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#cm\0";
+pub const LV2_UNITS__coef: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#coef\0";
+pub const LV2_UNITS__conversion: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/units#conversion\0";
+pub const LV2_UNITS__db: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#db\0";
+pub const LV2_UNITS__degree: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/units#degree\0";
+pub const LV2_UNITS__frame: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/extensions/units#frame\0";
+pub const LV2_UNITS__hz: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#hz\0";
+pub const LV2_UNITS__inch: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#inch\0";
+pub const LV2_UNITS__khz: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#khz\0";
+pub const LV2_UNITS__km: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#km\0";
+pub const LV2_UNITS__m: &'static [u8; 40usize] = b"http://lv2plug.in/ns/extensions/units#m\0";
+pub const LV2_UNITS__mhz: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#mhz\0";
+pub const LV2_UNITS__midiNote: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/extensions/units#midiNote\0";
+pub const LV2_UNITS__mile: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#mile\0";
+pub const LV2_UNITS__min: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#min\0";
+pub const LV2_UNITS__mm: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#mm\0";
+pub const LV2_UNITS__ms: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#ms\0";
+pub const LV2_UNITS__name: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#name\0";
+pub const LV2_UNITS__oct: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#oct\0";
+pub const LV2_UNITS__pc: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#pc\0";
+pub const LV2_UNITS__prefixConversion: &'static [u8; 55usize] =
+    b"http://lv2plug.in/ns/extensions/units#prefixConversion\0";
+pub const LV2_UNITS__render: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/units#render\0";
+pub const LV2_UNITS__s: &'static [u8; 40usize] = b"http://lv2plug.in/ns/extensions/units#s\0";
+pub const LV2_UNITS__semitone12TET: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/extensions/units#semitone12TET\0";
+pub const LV2_UNITS__symbol: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/units#symbol\0";
+pub const LV2_UNITS__unit: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#unit\0";
+pub const LV2_URI_MAP_URI: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/uri-map\0";
+pub const LV2_URI_MAP_PREFIX: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/uri-map#\0";
+pub const LV2_WORKER_URI: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/worker\0";
+pub const LV2_WORKER_PREFIX: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/worker#\0";
+pub const LV2_WORKER__interface: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/worker#interface\0";
+pub const LV2_WORKER__schedule: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/worker#schedule\0";
+pub type __uint8_t = ::std::os::raw::c_uchar;
+pub type __uint16_t = ::std::os::raw::c_ushort;
+pub type __int32_t = ::std::os::raw::c_int;
+pub type __uint32_t = ::std::os::raw::c_uint;
+pub type __int64_t = ::std::os::raw::c_long;
+#[doc = " The header of an atom:Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom {
+    #[doc = "< Size in bytes, not including type and size."]
+    pub size: u32,
+    #[doc = "< Type of this atom (mapped URI)."]
+    pub type_: u32,
+}
+#[doc = " An atom:Int or atom:Bool.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Int {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Integer value."]
+    pub body: i32,
+}
+#[doc = " An atom:Long.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Long {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Integer value."]
+    pub body: i64,
+}
+#[doc = " An atom:Float.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Float {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Floating point value."]
+    pub body: f32,
+}
+#[doc = " An atom:Double.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Double {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Floating point value."]
+    pub body: f64,
+}
+#[doc = " An atom:Bool.  May be cast to LV2_Atom."]
+pub type LV2_Atom_Bool = LV2_Atom_Int;
+#[doc = " An atom:URID.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_URID {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< URID."]
+    pub body: u32,
+}
+#[doc = " An atom:String.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_String {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+}
+#[doc = " The body of an atom:Literal."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Literal_Body {
+    #[doc = "< Datatype URID."]
+    pub datatype: u32,
+    #[doc = "< Language URID."]
+    pub lang: u32,
+}
+#[doc = " An atom:Literal.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Literal {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Literal_Body,
+}
+#[doc = " An atom:Tuple.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Tuple {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+}
+#[doc = " The body of an atom:Vector."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Vector_Body {
+    #[doc = "< The size of each element in the vector."]
+    pub child_size: u32,
+    #[doc = "< The type of each element in the vector."]
+    pub child_type: u32,
+}
+#[doc = " An atom:Vector.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Vector {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Vector_Body,
+}
+#[doc = " The body of an atom:Property (typically in an atom:Object)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Property_Body {
+    #[doc = "< Key (predicate) (mapped URI)."]
+    pub key: u32,
+    #[doc = "< Context URID (may be, and generally is, 0)."]
+    pub context: u32,
+    #[doc = "< Value atom header."]
+    pub value: LV2_Atom,
+}
+#[doc = " An atom:Property.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Property {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Property_Body,
+}
+#[doc = " The body of an atom:Object. May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Object_Body {
+    #[doc = "< URID, or 0 for blank."]
+    pub id: u32,
+    #[doc = "< Type URID (same as rdf:type, for fast dispatch)."]
+    pub otype: u32,
+}
+#[doc = " An atom:Object.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Object {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Object_Body,
+}
+#[doc = " The header of an atom:Event.  Note this type is NOT an LV2_Atom."]
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct LV2_Atom_Event {
+    pub time: LV2_Atom_Event__bindgen_ty_1,
+    #[doc = "< Event body atom header."]
+    pub body: LV2_Atom,
+}
+#[doc = " Time stamp.  Which type is valid is determined by context."]
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union LV2_Atom_Event__bindgen_ty_1 {
+    #[doc = "< Time in audio frames."]
+    pub frames: i64,
+    #[doc = "< Time in beats."]
+    pub beats: f64,
+    _bindgen_union_align: u64,
+}
+#[doc = "The body of an atom:Sequence (a sequence of events)."]
+#[doc = ""]
+#[doc = "The unit field is either a URID that described an appropriate time stamp"]
+#[doc = "type, or may be 0 where a default stamp type is known.  For"]
+#[doc = "LV2_Descriptor::run(), the default stamp type is audio frames."]
+#[doc = ""]
+#[doc = "The contents of a sequence is a series of LV2_Atom_Event, each aligned"]
+#[doc = "to 64-bits, for example:"]
+#[doc = "<pre>"]
+#[doc = "| Event 1 (size 6)                              | Event 2"]
+#[doc = "|       |       |       |       |       |       |       |       |"]
+#[doc = "| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |"]
+#[doc = "|FRAMES |SUBFRMS|TYPE   |SIZE   |DATADATADATAPAD|FRAMES |SUBFRMS|..."]
+#[doc = "</pre>"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Sequence_Body {
+    #[doc = "< URID of unit of event time stamps."]
+    pub unit: u32,
+    #[doc = "< Currently unused."]
+    pub pad: u32,
+}
+#[doc = " An atom:Sequence."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Sequence {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Sequence_Body,
+}
+pub type va_list = __builtin_va_list;
+#[doc = " A single entry in an Object query."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Object_Query {
+    #[doc = "< Key to query (input set by user)"]
+    pub key: u32,
+    #[doc = "< Found value (output set by query function)"]
+    pub value: *mut *const LV2_Atom,
+}
+extern "C" {
+    pub static LV2_ATOM_OBJECT_QUERY_END: LV2_Atom_Object_Query;
+}
+#[doc = "Opaque pointer to host data for LV2_URID_Map."]
+pub type LV2_URID_Map_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Opaque pointer to host data for LV2_URID_Unmap."]
+pub type LV2_URID_Unmap_Handle = *mut ::std::os::raw::c_void;
+#[doc = "URI mapped to an integer."]
+pub type LV2_URID = u32;
+#[doc = "URID Map Feature (LV2_URID__map)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_URID_Map {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "This MUST be passed to map_uri() whenever it is called."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub handle: LV2_URID_Map_Handle,
+    #[doc = "Get the numeric ID of a URI."]
+    #[doc = ""]
+    #[doc = "If the ID does not already exist, it will be created."]
+    #[doc = ""]
+    #[doc = "This function is referentially transparent; any number of calls with the"]
+    #[doc = "same arguments is guaranteed to return the same value over the life of a"]
+    #[doc = "plugin instance.  Note, however, that several URIs MAY resolve to the"]
+    #[doc = "same ID if the host considers those URIs equivalent."]
+    #[doc = ""]
+    #[doc = "This function is not necessarily very fast or RT-safe: plugins SHOULD"]
+    #[doc = "cache any IDs they might need in performance critical situations."]
+    #[doc = ""]
+    #[doc = "The return value 0 is reserved and indicates that an ID for that URI"]
+    #[doc = "could not be created for whatever reason.  However, hosts SHOULD NOT"]
+    #[doc = "return 0 from this function in non-exceptional circumstances (i.e. the"]
+    #[doc = "URI map SHOULD be dynamic)."]
+    #[doc = ""]
+    #[doc = "@param handle Must be the callback_data member of this struct."]
+    #[doc = "@param uri The URI to be mapped to an integer ID."]
+    pub map: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_URID_Map_Handle,
+            uri: *const ::std::os::raw::c_char,
+        ) -> LV2_URID,
+    >,
+}
+#[doc = "URI Unmap Feature (LV2_URID__unmap)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_URID_Unmap {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "This MUST be passed to unmap() whenever it is called."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub handle: LV2_URID_Unmap_Handle,
+    #[doc = "Get the URI for a previously mapped numeric ID."]
+    #[doc = ""]
+    #[doc = "Returns NULL if `urid` is not yet mapped.  Otherwise, the corresponding"]
+    #[doc = "URI is returned in a canonical form.  This MAY not be the exact same"]
+    #[doc = "string that was originally passed to LV2_URID_Map::map(), but it MUST be"]
+    #[doc = "an identical URI according to the URI syntax specification (RFC3986).  A"]
+    #[doc = "non-NULL return for a given `urid` will always be the same for the life"]
+    #[doc = "of the plugin.  Plugins that intend to perform string comparison on"]
+    #[doc = "unmapped URIs SHOULD first canonicalise URI strings with a call to"]
+    #[doc = "map_uri() followed by a call to unmap_uri()."]
+    #[doc = ""]
+    #[doc = "@param handle Must be the callback_data member of this struct."]
+    #[doc = "@param urid The ID to be mapped back to the URI string."]
+    pub unmap: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_URID_Unmap_Handle,
+            urid: LV2_URID,
+        ) -> *const ::std::os::raw::c_char,
+    >,
+}
+#[doc = " Handle for LV2_Atom_Forge_Sink."]
+pub type LV2_Atom_Forge_Sink_Handle = *mut ::std::os::raw::c_void;
+#[doc = " A reference to a chunk of written output."]
+pub type LV2_Atom_Forge_Ref = isize;
+#[doc = " Sink function for writing output.  See lv2_atom_forge_set_sink()."]
+pub type LV2_Atom_Forge_Sink = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_Atom_Forge_Sink_Handle,
+        buf: *const ::std::os::raw::c_void,
+        size: u32,
+    ) -> LV2_Atom_Forge_Ref,
+>;
+#[doc = " Function for resolving a reference.  See lv2_atom_forge_set_sink()."]
+pub type LV2_Atom_Forge_Deref_Func = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_Atom_Forge_Sink_Handle,
+        ref_: LV2_Atom_Forge_Ref,
+    ) -> *mut LV2_Atom,
+>;
+#[doc = " A stack frame used for keeping track of nested Atom containers."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Forge_Frame {
+    pub parent: *mut LV2_Atom_Forge_Frame,
+    pub ref_: LV2_Atom_Forge_Ref,
+}
+#[doc = " A \"forge\" for creating atoms by appending to a buffer."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Forge {
+    pub buf: *mut u8,
+    pub offset: u32,
+    pub size: u32,
+    pub sink: LV2_Atom_Forge_Sink,
+    pub deref: LV2_Atom_Forge_Deref_Func,
+    pub handle: LV2_Atom_Forge_Sink_Handle,
+    pub stack: *mut LV2_Atom_Forge_Frame,
+    pub Blank: LV2_URID,
+    pub Bool: LV2_URID,
+    pub Chunk: LV2_URID,
+    pub Double: LV2_URID,
+    pub Float: LV2_URID,
+    pub Int: LV2_URID,
+    pub Long: LV2_URID,
+    pub Literal: LV2_URID,
+    pub Object: LV2_URID,
+    pub Path: LV2_URID,
+    pub Property: LV2_URID,
+    pub Resource: LV2_URID,
+    pub Sequence: LV2_URID,
+    pub String: LV2_URID,
+    pub Tuple: LV2_URID,
+    pub URI: LV2_URID,
+    pub URID: LV2_URID,
+    pub Vector: LV2_URID,
+}
+#[doc = "Plugin Instance Handle."]
+#[doc = ""]
+#[doc = "This is a handle for one particular instance of a plugin.  It is valid to"]
+#[doc = "compare to NULL (or 0 for C++) but otherwise the host MUST NOT attempt to"]
+#[doc = "interpret it."]
+pub type LV2_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Feature."]
+#[doc = ""]
+#[doc = "Features allow hosts to make additional functionality available to plugins"]
+#[doc = "without requiring modification to the LV2 API.  Extensions may define new"]
+#[doc = "features and specify the `URI` and `data` to be used if necessary."]
+#[doc = "Some features, such as lv2:isLive, do not require the host to pass data."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Feature {
+    #[doc = "A globally unique, case-sensitive identifier (URI) for this feature."]
+    #[doc = ""]
+    #[doc = "This MUST be a valid URI string as defined by RFC 3986."]
+    pub URI: *const ::std::os::raw::c_char,
+    #[doc = "Pointer to arbitrary data."]
+    #[doc = ""]
+    #[doc = "The format of this data is defined by the extension which describes the"]
+    #[doc = "feature with the given `URI`."]
+    pub data: *mut ::std::os::raw::c_void,
+}
+#[doc = "Plugin Descriptor."]
+#[doc = ""]
+#[doc = "This structure provides the core functions necessary to instantiate and use"]
+#[doc = "a plugin."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Descriptor {
+    #[doc = "A globally unique, case-sensitive identifier for this plugin."]
+    #[doc = ""]
+    #[doc = "This MUST be a valid URI string as defined by RFC 3986.  All plugins with"]
+    #[doc = "the same URI MUST be compatible to some degree, see"]
+    #[doc = "http://lv2plug.in/ns/lv2core for details."]
+    pub URI: *const ::std::os::raw::c_char,
+    #[doc = "Instantiate the plugin."]
+    #[doc = ""]
+    #[doc = "Note that instance initialisation should generally occur in activate()"]
+    #[doc = "rather than here. If a host calls instantiate(), it MUST call cleanup()"]
+    #[doc = "at some point in the future."]
+    #[doc = ""]
+    #[doc = "@param descriptor Descriptor of the plugin to instantiate."]
+    #[doc = ""]
+    #[doc = "@param sample_rate Sample rate, in Hz, for the new plugin instance."]
+    #[doc = ""]
+    #[doc = "@param bundle_path Path to the LV2 bundle which contains this plugin"]
+    #[doc = "binary. It MUST include the trailing directory separator so that simply"]
+    #[doc = "appending a filename will yield the path to that file in the bundle."]
+    #[doc = ""]
+    #[doc = "@param features A NULL terminated array of LV2_Feature structs which"]
+    #[doc = "represent the features the host supports. Plugins may refuse to"]
+    #[doc = "instantiate if required features are not found here. However, hosts MUST"]
+    #[doc = "NOT use this as a discovery mechanism: instead, use the RDF data to"]
+    #[doc = "determine which features are required and do not attempt to instantiate"]
+    #[doc = "unsupported plugins at all. This parameter MUST NOT be NULL, i.e. a host"]
+    #[doc = "that supports no features MUST pass a single element array containing"]
+    #[doc = "NULL."]
+    #[doc = ""]
+    #[doc = "@return A handle for the new plugin instance, or NULL if instantiation"]
+    #[doc = "has failed."]
+    pub instantiate: ::std::option::Option<
+        unsafe extern "C" fn(
+            descriptor: *const LV2_Descriptor,
+            sample_rate: f64,
+            bundle_path: *const ::std::os::raw::c_char,
+            features: *const *const LV2_Feature,
+        ) -> LV2_Handle,
+    >,
+    #[doc = "Connect a port on a plugin instance to a memory location."]
+    #[doc = ""]
+    #[doc = "Plugin writers should be aware that the host may elect to use the same"]
+    #[doc = "buffer for more than one port and even use the same buffer for both"]
+    #[doc = "input and output (see lv2:inPlaceBroken in lv2.ttl)."]
+    #[doc = ""]
+    #[doc = "If the plugin has the feature lv2:hardRTCapable then there are various"]
+    #[doc = "things that the plugin MUST NOT do within the connect_port() function;"]
+    #[doc = "see lv2core.ttl for details."]
+    #[doc = ""]
+    #[doc = "connect_port() MUST be called at least once for each port before run()"]
+    #[doc = "is called, unless that port is lv2:connectionOptional. The plugin must"]
+    #[doc = "pay careful attention to the block size passed to run() since the block"]
+    #[doc = "allocated may only just be large enough to contain the data, and is not"]
+    #[doc = "guaranteed to remain constant between run() calls."]
+    #[doc = ""]
+    #[doc = "connect_port() may be called more than once for a plugin instance to"]
+    #[doc = "allow the host to change the buffers that the plugin is reading or"]
+    #[doc = "writing. These calls may be made before or after activate() or"]
+    #[doc = "deactivate() calls."]
+    #[doc = ""]
+    #[doc = "@param instance Plugin instance containing the port."]
+    #[doc = ""]
+    #[doc = "@param port Index of the port to connect. The host MUST NOT try to"]
+    #[doc = "connect a port index that is not defined in the plugin's RDF data. If"]
+    #[doc = "it does, the plugin's behaviour is undefined (a crash is likely)."]
+    #[doc = ""]
+    #[doc = "@param data_location Pointer to data of the type defined by the port"]
+    #[doc = "type in the plugin's RDF data (for example, an array of float for an"]
+    #[doc = "lv2:AudioPort). This pointer must be stored by the plugin instance and"]
+    #[doc = "used to read/write data when run() is called. Data present at the time"]
+    #[doc = "of the connect_port() call MUST NOT be considered meaningful."]
+    pub connect_port: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            port: u32,
+            data_location: *mut ::std::os::raw::c_void,
+        ),
+    >,
+    #[doc = "Initialise a plugin instance and activate it for use."]
+    #[doc = ""]
+    #[doc = "This is separated from instantiate() to aid real-time support and so"]
+    #[doc = "that hosts can reinitialise a plugin instance by calling deactivate()"]
+    #[doc = "and then activate(). In this case the plugin instance MUST reset all"]
+    #[doc = "state information dependent on the history of the plugin instance except"]
+    #[doc = "for any data locations provided by connect_port(). If there is nothing"]
+    #[doc = "for activate() to do then this field may be NULL."]
+    #[doc = ""]
+    #[doc = "When present, hosts MUST call this function once before run() is called"]
+    #[doc = "for the first time. This call SHOULD be made as close to the run() call"]
+    #[doc = "as possible and indicates to real-time plugins that they are now live,"]
+    #[doc = "however plugins MUST NOT rely on a prompt call to run() after"]
+    #[doc = "activate()."]
+    #[doc = ""]
+    #[doc = "The host MUST NOT call activate() again until deactivate() has been"]
+    #[doc = "called first. If a host calls activate(), it MUST call deactivate() at"]
+    #[doc = "some point in the future. Note that connect_port() may be called before"]
+    #[doc = "or after activate()."]
+    pub activate: ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle)>,
+    #[doc = "Run a plugin instance for a block."]
+    #[doc = ""]
+    #[doc = "Note that if an activate() function exists then it must be called before"]
+    #[doc = "run(). If deactivate() is called for a plugin instance then run() may"]
+    #[doc = "not be called until activate() has been called again."]
+    #[doc = ""]
+    #[doc = "If the plugin has the feature lv2:hardRTCapable then there are various"]
+    #[doc = "things that the plugin MUST NOT do within the run() function (see"]
+    #[doc = "lv2core.ttl for details)."]
+    #[doc = ""]
+    #[doc = "As a special case, when `sample_count` is 0, the plugin should update"]
+    #[doc = "any output ports that represent a single instant in time (for example,"]
+    #[doc = "control ports, but not audio ports). This is particularly useful for"]
+    #[doc = "latent plugins, which should update their latency output port so hosts"]
+    #[doc = "can pre-roll plugins to compute latency. Plugins MUST NOT crash when"]
+    #[doc = "`sample_count` is 0."]
+    #[doc = ""]
+    #[doc = "@param instance Instance to be run."]
+    #[doc = ""]
+    #[doc = "@param sample_count The block size (in samples) for which the plugin"]
+    #[doc = "instance must run."]
+    pub run: ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle, sample_count: u32)>,
+    #[doc = "Deactivate a plugin instance (counterpart to activate())."]
+    #[doc = ""]
+    #[doc = "Hosts MUST deactivate all activated instances after they have been run()"]
+    #[doc = "for the last time. This call SHOULD be made as close to the last run()"]
+    #[doc = "call as possible and indicates to real-time plugins that they are no"]
+    #[doc = "longer live, however plugins MUST NOT rely on prompt deactivation. If"]
+    #[doc = "there is nothing for deactivate() to do then this field may be NULL"]
+    #[doc = ""]
+    #[doc = "Deactivation is not similar to pausing since the plugin instance will be"]
+    #[doc = "reinitialised by activate(). However, deactivate() itself MUST NOT fully"]
+    #[doc = "reset plugin state. For example, the host may deactivate a plugin, then"]
+    #[doc = "store its state (using some extension to do so)."]
+    #[doc = ""]
+    #[doc = "Hosts MUST NOT call deactivate() unless activate() was previously"]
+    #[doc = "called. Note that connect_port() may be called before or after"]
+    #[doc = "deactivate()."]
+    pub deactivate: ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle)>,
+    #[doc = "Clean up a plugin instance (counterpart to instantiate())."]
+    #[doc = ""]
+    #[doc = "Once an instance of a plugin has been finished with it must be deleted"]
+    #[doc = "using this function. The instance handle passed ceases to be valid after"]
+    #[doc = "this call."]
+    #[doc = ""]
+    #[doc = "If activate() was called for a plugin instance then a corresponding call"]
+    #[doc = "to deactivate() MUST be made before cleanup() is called. Hosts MUST NOT"]
+    #[doc = "call cleanup() unless instantiate() was previously called."]
+    pub cleanup: ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle)>,
+    #[doc = "Return additional plugin data defined by some extenion."]
+    #[doc = ""]
+    #[doc = "A typical use of this facility is to return a struct containing function"]
+    #[doc = "pointers to extend the LV2_Descriptor API."]
+    #[doc = ""]
+    #[doc = "The actual type and meaning of the returned object MUST be specified"]
+    #[doc = "precisely by the extension. This function MUST return NULL for any"]
+    #[doc = "unsupported URI. If a plugin does not support any extension data, this"]
+    #[doc = "field may be NULL."]
+    #[doc = ""]
+    #[doc = "The host is never responsible for freeing the returned value."]
+    pub extension_data: ::std::option::Option<
+        unsafe extern "C" fn(uri: *const ::std::os::raw::c_char) -> *const ::std::os::raw::c_void,
+    >,
+}
+#[doc = "Type of the lv2_descriptor() function in a library (old discovery API)."]
+pub type LV2_Descriptor_Function =
+    ::std::option::Option<unsafe extern "C" fn(index: u32) -> *const LV2_Descriptor>;
+#[doc = "Handle for a library descriptor."]
+pub type LV2_Lib_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Descriptor for a plugin library."]
+#[doc = ""]
+#[doc = "To access a plugin library, the host creates an LV2_Lib_Descriptor via the"]
+#[doc = "lv2_lib_descriptor() function in the shared object."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Lib_Descriptor {
+    #[doc = "Opaque library data which must be passed as the first parameter to all"]
+    #[doc = "the methods of this struct."]
+    pub handle: LV2_Lib_Handle,
+    #[doc = "The total size of this struct.  This allows for this struct to be"]
+    #[doc = "expanded in the future if necessary.  This MUST be set by the library to"]
+    #[doc = "sizeof(LV2_Lib_Descriptor).  The host MUST NOT access any fields of this"]
+    #[doc = "struct beyond get_plugin() unless this field indicates they are present."]
+    pub size: u32,
+    #[doc = "Destroy this library descriptor and free all related resources."]
+    pub cleanup: ::std::option::Option<unsafe extern "C" fn(handle: LV2_Lib_Handle)>,
+    #[doc = "Plugin accessor."]
+    #[doc = ""]
+    #[doc = "Plugins are accessed by index using values from 0 upwards.  Out of range"]
+    #[doc = "indices MUST result in this function returning NULL, so the host can"]
+    #[doc = "enumerate plugins by increasing `index` until NULL is returned."]
+    pub get_plugin: ::std::option::Option<
+        unsafe extern "C" fn(handle: LV2_Lib_Handle, index: u32) -> *const LV2_Descriptor,
+    >,
+}
+#[doc = "Type of the lv2_lib_descriptor() function in an LV2 library."]
+pub type LV2_Lib_Descriptor_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        bundle_path: *const ::std::os::raw::c_char,
+        features: *const *const LV2_Feature,
+    ) -> *const LV2_Lib_Descriptor,
+>;
+#[doc = "The data field of the LV2_Feature for this extension."]
+#[doc = ""]
+#[doc = "To support this feature the host must pass an LV2_Feature struct to the"]
+#[doc = "instantiate method with URI \"http://lv2plug.in/ns/ext/data-access\""]
+#[doc = "and data pointed to an instance of this struct."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Extension_Data_Feature {
+    #[doc = "A pointer to a method the UI can call to get data (of a type specified"]
+    #[doc = "by some other extension) from the plugin."]
+    #[doc = ""]
+    #[doc = "This call never is never guaranteed to return anything, UIs should"]
+    #[doc = "degrade gracefully if direct access to the plugin data is not possible"]
+    #[doc = "(in which case this function will return NULL)."]
+    #[doc = ""]
+    #[doc = "This is for access to large data that can only possibly work if the UI"]
+    #[doc = "and plugin are running in the same process.  For all other things, use"]
+    #[doc = "the normal LV2 UI communication system."]
+    pub data_access: ::std::option::Option<
+        unsafe extern "C" fn(uri: *const ::std::os::raw::c_char) -> *const ::std::os::raw::c_void,
+    >,
+}
+#[doc = "Dynamic manifest generator handle."]
+#[doc = ""]
+#[doc = "This handle indicates a particular status of a dynamic manifest generator."]
+#[doc = "The host MUST NOT attempt to interpret it and, unlikely LV2_Handle, it is"]
+#[doc = "NOT even valid to compare this to NULL. The dynamic manifest generator MAY"]
+#[doc = "use it to reference internal data."]
+pub type LV2_Dyn_Manifest_Handle = *mut ::std::os::raw::c_void;
+pub const LV2_EVENT_PPQN: u32 = 3136573440;
+#[doc = "An LV2 event (header only)."]
+#[doc = ""]
+#[doc = "LV2 events are generic time-stamped containers for any type of event."]
+#[doc = "The type field defines the format of a given event's contents."]
+#[doc = ""]
+#[doc = "This struct defines the header of an LV2 event. An LV2 event is a single"]
+#[doc = "chunk of POD (plain old data), usually contained in a flat buffer (see"]
+#[doc = "LV2_EventBuffer below). Unless a required feature says otherwise, hosts may"]
+#[doc = "assume a deep copy of an LV2 event can be created safely using a simple:"]
+#[doc = ""]
+#[doc = "memcpy(ev_copy, ev, sizeof(LV2_Event) + ev->size);  (or equivalent)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Event {
+    #[doc = "The frames portion of timestamp. The units used here can optionally be"]
+    #[doc = "set for a port (with the lv2ev:timeUnits property), otherwise this is"]
+    #[doc = "audio frames, corresponding to the sample_count parameter of the LV2 run"]
+    #[doc = "method (frame 0 is the first frame for that call to run)."]
+    pub frames: u32,
+    #[doc = "The sub-frames portion of timestamp. The units used here can optionally"]
+    #[doc = "be set for a port (with the lv2ev:timeUnits property), otherwise this is"]
+    #[doc = "1/(2^32) of an audio frame."]
+    pub subframes: u32,
+    #[doc = "The type of this event, as a number which represents some URI"]
+    #[doc = "defining an event type. This value MUST be some value previously"]
+    #[doc = "returned from a call to the uri_to_id function defined in the LV2"]
+    #[doc = "URI map extension (see lv2_uri_map.h)."]
+    #[doc = "There are special rules which must be followed depending on the type"]
+    #[doc = "of an event. If the plugin recognizes an event type, the definition"]
+    #[doc = "of that event type will describe how to interpret the event, and"]
+    #[doc = "any required behaviour. Otherwise, if the type is 0, this event is a"]
+    #[doc = "non-POD event and lv2_event_unref MUST be called if the event is"]
+    #[doc = "'dropped' (see above). Even if the plugin does not understand an event,"]
+    #[doc = "it may pass the event through to an output by simply copying (and NOT"]
+    #[doc = "calling lv2_event_unref). These rules are designed to allow for generic"]
+    #[doc = "event handling plugins and large non-POD events, but with minimal hassle"]
+    #[doc = "on simple plugins that \"don't care\" about these more advanced features."]
+    pub type_: u16,
+    #[doc = "The size of the data portion of this event in bytes, which immediately"]
+    #[doc = "follows. The header size (12 bytes) is not included in this value."]
+    pub size: u16,
+}
+#[doc = "A buffer of LV2 events (header only)."]
+#[doc = ""]
+#[doc = "Like events (which this contains) an event buffer is a single chunk of POD:"]
+#[doc = "the entire buffer (including contents) can be copied with a single memcpy."]
+#[doc = "The first contained event begins sizeof(LV2_EventBuffer) bytes after the"]
+#[doc = "start of this struct."]
+#[doc = ""]
+#[doc = "After this header, the buffer contains an event header (defined by struct"]
+#[doc = "LV2_Event), followed by that event's contents (padded to 64 bits), followed"]
+#[doc = "by another header, etc:"]
+#[doc = ""]
+#[doc = "|       |       |       |       |       |       |"]
+#[doc = "| | | | | | | | | | | | | | | | | | | | | | | | |"]
+#[doc = "|FRAMES |SUBFRMS|TYP|LEN|DATA..DATA..PAD|FRAMES | ..."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Event_Buffer {
+    #[doc = "The contents of the event buffer. This may or may not reside in the"]
+    #[doc = "same block of memory as this header, plugins must not assume either."]
+    #[doc = "The host guarantees this points to at least capacity bytes of allocated"]
+    #[doc = "memory (though only size bytes of that are valid events)."]
+    pub data: *mut u8,
+    #[doc = "The size of this event header in bytes (including everything)."]
+    #[doc = ""]
+    #[doc = "This is to allow for extending this header in the future without"]
+    #[doc = "breaking binary compatibility. Whenever this header is copied,"]
+    #[doc = "it MUST be done using this field (and NOT the sizeof this struct)."]
+    pub header_size: u16,
+    #[doc = "The type of the time stamps for events in this buffer."]
+    #[doc = "As a special exception, '0' always means audio frames and subframes"]
+    #[doc = "(1/UINT32_MAX'th of a frame) in the sample rate passed to instantiate."]
+    #[doc = ""]
+    #[doc = "INPUTS: The host must set this field to the numeric ID of some URI"]
+    #[doc = "defining the meaning of the frames/subframes fields of contained events"]
+    #[doc = "(obtained by the LV2 URI Map uri_to_id function with the URI of this"]
+    #[doc = "extension as the 'map' argument, see lv2_uri_map.h).  The host must"]
+    #[doc = "never pass a plugin a buffer which uses a stamp type the plugin does not"]
+    #[doc = "'understand'. The value of this field must never change, except when"]
+    #[doc = "connect_port is called on the input port, at which time the host MUST"]
+    #[doc = "have set the stamp_type field to the value that will be used for all"]
+    #[doc = "subsequent run calls."]
+    #[doc = ""]
+    #[doc = "OUTPUTS: The plugin may set this to any value that has been returned"]
+    #[doc = "from uri_to_id with the URI of this extension for a 'map' argument."]
+    #[doc = "When connected to a buffer with connect_port, output ports MUST set this"]
+    #[doc = "field to the type of time stamp they will be writing. On any call to"]
+    #[doc = "connect_port on an event input port, the plugin may change this field on"]
+    #[doc = "any output port, it is the responsibility of the host to check if any of"]
+    #[doc = "these values have changed and act accordingly."]
+    pub stamp_type: u16,
+    #[doc = "The number of events in this buffer."]
+    #[doc = ""]
+    #[doc = "INPUTS: The host must set this field to the number of events contained"]
+    #[doc = "in the data buffer before calling run(). The plugin must not change"]
+    #[doc = "this field."]
+    #[doc = ""]
+    #[doc = "OUTPUTS: The plugin must set this field to the number of events it has"]
+    #[doc = "written to the buffer before returning from run(). Any initial value"]
+    #[doc = "should be ignored by the plugin."]
+    pub event_count: u32,
+    #[doc = "The size of the data buffer in bytes."]
+    #[doc = "This is set by the host and must not be changed by the plugin."]
+    #[doc = "The host is allowed to change this between run() calls."]
+    pub capacity: u32,
+    #[doc = "The size of the initial portion of the data buffer containing data."]
+    #[doc = ""]
+    #[doc = "INPUTS: The host must set this field to the number of bytes used"]
+    #[doc = "by all events it has written to the buffer (including headers)"]
+    #[doc = "before calling the plugin's run()."]
+    #[doc = "The plugin must not change this field."]
+    #[doc = ""]
+    #[doc = "OUTPUTS: The plugin must set this field to the number of bytes"]
+    #[doc = "used by all events it has written to the buffer (including headers)"]
+    #[doc = "before returning from run()."]
+    #[doc = "Any initial value should be ignored by the plugin."]
+    pub size: u32,
+}
+pub type LV2_Event_Callback_Data = *mut ::std::os::raw::c_void;
+#[doc = "Non-POD events feature."]
+#[doc = ""]
+#[doc = "To support this feature the host must pass an LV2_Feature struct to the"]
+#[doc = "plugin's instantiate method with URI \"http://lv2plug.in/ns/ext/event\""]
+#[doc = "and data pointed to an instance of this struct.  Note this feature"]
+#[doc = "is not mandatory to support the event extension."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Event_Feature {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "The plugin MUST pass this to any call to functions in this struct."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub callback_data: LV2_Event_Callback_Data,
+    #[doc = "Take a reference to a non-POD event."]
+    #[doc = ""]
+    #[doc = "If a plugin receives an event with type 0, it means the event is a"]
+    #[doc = "pointer to some object in memory and not a flat sequence of bytes"]
+    #[doc = "in the buffer. When receiving a non-POD event, the plugin already"]
+    #[doc = "has an implicit reference to the event. If the event is stored AND"]
+    #[doc = "passed to an output, lv2_event_ref MUST be called on that event."]
+    #[doc = "If the event is only stored OR passed through, this is not necessary"]
+    #[doc = "(as the plugin already has 1 implicit reference)."]
+    #[doc = ""]
+    #[doc = "@param event An event received at an input that will not be copied to"]
+    #[doc = "an output or stored in any way."]
+    #[doc = ""]
+    #[doc = "@param context The calling context. Like event types, this is a mapped"]
+    #[doc = "URI, see lv2_context.h. Simple plugin with just a run() method should"]
+    #[doc = "pass 0 here (the ID of the 'standard' LV2 run context). The host"]
+    #[doc = "guarantees that this function is realtime safe iff the context is"]
+    #[doc = "realtime safe."]
+    #[doc = ""]
+    #[doc = "PLUGINS THAT VIOLATE THESE RULES MAY CAUSE CRASHES AND MEMORY LEAKS."]
+    pub lv2_event_ref: ::std::option::Option<
+        unsafe extern "C" fn(callback_data: LV2_Event_Callback_Data, event: *mut LV2_Event) -> u32,
+    >,
+    #[doc = "Drop a reference to a non-POD event."]
+    #[doc = ""]
+    #[doc = "If a plugin receives an event with type 0, it means the event is a"]
+    #[doc = "pointer to some object in memory and not a flat sequence of bytes"]
+    #[doc = "in the buffer. If the plugin does not pass the event through to"]
+    #[doc = "an output or store it internally somehow, it MUST call this function"]
+    #[doc = "on the event (more information on using non-POD events below)."]
+    #[doc = ""]
+    #[doc = "@param event An event received at an input that will not be copied to an"]
+    #[doc = "output or stored in any way."]
+    #[doc = ""]
+    #[doc = "@param context The calling context. Like event types, this is a mapped"]
+    #[doc = "URI, see lv2_context.h. Simple plugin with just a run() method should"]
+    #[doc = "pass 0 here (the ID of the 'standard' LV2 run context). The host"]
+    #[doc = "guarantees that this function is realtime safe iff the context is"]
+    #[doc = "realtime safe."]
+    #[doc = ""]
+    #[doc = "PLUGINS THAT VIOLATE THESE RULES MAY CAUSE CRASHES AND MEMORY LEAKS."]
+    pub lv2_event_unref: ::std::option::Option<
+        unsafe extern "C" fn(callback_data: LV2_Event_Callback_Data, event: *mut LV2_Event) -> u32,
+    >,
+}
+#[doc = " An iterator over an LV2_Event_Buffer."]
+#[doc = ""]
+#[doc = " Multiple simultaneous read iterators over a single buffer is fine,"]
+#[doc = " but changing the buffer invalidates all iterators."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Event_Iterator {
+    pub buf: *mut LV2_Event_Buffer,
+    pub offset: u32,
+}
+#[doc = "Opaque data to host data for LV2_Log_Log."]
+pub type LV2_Log_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Log feature (LV2_LOG__log)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Log_Log {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "This MUST be passed to methods in this struct whenever they are called."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub handle: LV2_Log_Handle,
+    #[doc = "Log a message, passing format parameters directly."]
+    #[doc = ""]
+    #[doc = "The API of this function matches that of the standard C printf function,"]
+    #[doc = "except for the addition of the first two parameters.  This function may"]
+    #[doc = "be called from any non-realtime context, or from any context if `type`"]
+    #[doc = "is @ref LV2_LOG__Trace."]
+    pub printf: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_Log_Handle,
+            type_: LV2_URID,
+            fmt: *const ::std::os::raw::c_char,
+            ...
+        ) -> ::std::os::raw::c_int,
+    >,
+    #[doc = "Log a message, passing format parameters in a va_list."]
+    #[doc = ""]
+    #[doc = "The API of this function matches that of the standard C vprintf"]
+    #[doc = "function, except for the addition of the first two parameters.  This"]
+    #[doc = "function may be called from any non-realtime context, or from any"]
+    #[doc = "context if `type` is @ref LV2_LOG__Trace."]
+    pub vprintf: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_Log_Handle,
+            type_: LV2_URID,
+            fmt: *const ::std::os::raw::c_char,
+            ap: *mut __va_list_tag,
+        ) -> ::std::os::raw::c_int,
+    >,
+}
+#[doc = "Logger convenience API state."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Log_Logger {
+    pub log: *mut LV2_Log_Log,
+    pub Error: LV2_URID,
+    pub Note: LV2_URID,
+    pub Trace: LV2_URID,
+    pub Warning: LV2_URID,
+}
+#[doc = "< Invalid Message"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_INVALID: LV2_Midi_Message_Type = 0;
+#[doc = "< Note Off"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_NOTE_OFF: LV2_Midi_Message_Type = 128;
+#[doc = "< Note On"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_NOTE_ON: LV2_Midi_Message_Type = 144;
+#[doc = "< Note Pressure"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_NOTE_PRESSURE: LV2_Midi_Message_Type = 160;
+#[doc = "< Controller"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_CONTROLLER: LV2_Midi_Message_Type = 176;
+#[doc = "< Program Change"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_PGM_CHANGE: LV2_Midi_Message_Type = 192;
+#[doc = "< Channel Pressure"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_CHANNEL_PRESSURE: LV2_Midi_Message_Type = 208;
+#[doc = "< Pitch Bender"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_BENDER: LV2_Midi_Message_Type = 224;
+#[doc = "< System Exclusive Begin"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_SYSTEM_EXCLUSIVE: LV2_Midi_Message_Type = 240;
+#[doc = "< MTC Quarter Frame"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_MTC_QUARTER: LV2_Midi_Message_Type = 241;
+#[doc = "< Song Position"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_SONG_POS: LV2_Midi_Message_Type = 242;
+#[doc = "< Song Select"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_SONG_SELECT: LV2_Midi_Message_Type = 243;
+#[doc = "< Tune Request"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_TUNE_REQUEST: LV2_Midi_Message_Type = 246;
+#[doc = "< Clock"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_CLOCK: LV2_Midi_Message_Type = 248;
+#[doc = "< Start"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_START: LV2_Midi_Message_Type = 250;
+#[doc = "< Continue"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_CONTINUE: LV2_Midi_Message_Type = 251;
+#[doc = "< Stop"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_STOP: LV2_Midi_Message_Type = 252;
+#[doc = "< Active Sensing"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_ACTIVE_SENSE: LV2_Midi_Message_Type = 254;
+#[doc = "< Reset"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_RESET: LV2_Midi_Message_Type = 255;
+#[doc = "MIDI Message Type."]
+#[doc = ""]
+#[doc = "This includes both voice messages (which have a channel) and system messages"]
+#[doc = "(which do not), as well as a sentinel value for invalid messages.  To get"]
+#[doc = "the type of a message suitable for use in a switch statement, use"]
+#[doc = "lv2_midi_get_type() on the status byte."]
+pub type LV2_Midi_Message_Type = u32;
+#[doc = "< Bank Selection"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_BANK: LV2_Midi_Controller = 0;
+#[doc = "< Modulation"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_MODWHEEL: LV2_Midi_Controller = 1;
+#[doc = "< Breath"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_BREATH: LV2_Midi_Controller = 2;
+#[doc = "< Foot"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_FOOT: LV2_Midi_Controller = 4;
+#[doc = "< Portamento Time"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_PORTAMENTO_TIME: LV2_Midi_Controller = 5;
+#[doc = "< Data Entry"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_DATA_ENTRY: LV2_Midi_Controller = 6;
+#[doc = "< Main Volume"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_MAIN_VOLUME: LV2_Midi_Controller = 7;
+#[doc = "< Balance"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_BALANCE: LV2_Midi_Controller = 8;
+#[doc = "< Panpot"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_PAN: LV2_Midi_Controller = 10;
+#[doc = "< Expression"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_EXPRESSION: LV2_Midi_Controller = 11;
+#[doc = "< Effect1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_EFFECT1: LV2_Midi_Controller = 12;
+#[doc = "< Effect2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_EFFECT2: LV2_Midi_Controller = 13;
+#[doc = "< General Purpose 1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_GENERAL_PURPOSE1: LV2_Midi_Controller = 16;
+#[doc = "< General Purpose 2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_GENERAL_PURPOSE2: LV2_Midi_Controller = 17;
+#[doc = "< General Purpose 3"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_GENERAL_PURPOSE3: LV2_Midi_Controller = 18;
+#[doc = "< General Purpose 4"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_GENERAL_PURPOSE4: LV2_Midi_Controller = 19;
+#[doc = "< Bank Selection"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_BANK: LV2_Midi_Controller = 32;
+#[doc = "< Modulation"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_MODWHEEL: LV2_Midi_Controller = 33;
+#[doc = "< Breath"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_BREATH: LV2_Midi_Controller = 34;
+#[doc = "< Foot"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_FOOT: LV2_Midi_Controller = 36;
+#[doc = "< Portamento Time"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_PORTAMENTO_TIME: LV2_Midi_Controller = 37;
+#[doc = "< Data Entry"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_DATA_ENTRY: LV2_Midi_Controller = 38;
+#[doc = "< Main Volume"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_MAIN_VOLUME: LV2_Midi_Controller = 39;
+#[doc = "< Balance"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_BALANCE: LV2_Midi_Controller = 40;
+#[doc = "< Panpot"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_PAN: LV2_Midi_Controller = 42;
+#[doc = "< Expression"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_EXPRESSION: LV2_Midi_Controller = 43;
+#[doc = "< Effect1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_EFFECT1: LV2_Midi_Controller = 44;
+#[doc = "< Effect2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_EFFECT2: LV2_Midi_Controller = 45;
+#[doc = "< General Purpose 1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_GENERAL_PURPOSE1: LV2_Midi_Controller = 48;
+#[doc = "< General Purpose 2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_GENERAL_PURPOSE2: LV2_Midi_Controller = 49;
+#[doc = "< General Purpose 3"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_GENERAL_PURPOSE3: LV2_Midi_Controller = 50;
+#[doc = "< General Purpose 4"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_GENERAL_PURPOSE4: LV2_Midi_Controller = 51;
+#[doc = "< Sustain Pedal"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SUSTAIN: LV2_Midi_Controller = 64;
+#[doc = "< Portamento"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_PORTAMENTO: LV2_Midi_Controller = 65;
+#[doc = "< Sostenuto"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SOSTENUTO: LV2_Midi_Controller = 66;
+#[doc = "< Soft Pedal"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SOFT_PEDAL: LV2_Midi_Controller = 67;
+#[doc = "< Legato Foot Switch"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LEGATO_FOOTSWITCH: LV2_Midi_Controller = 68;
+#[doc = "< Hold2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_HOLD2: LV2_Midi_Controller = 69;
+#[doc = "< SC1 Sound Variation"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC1_SOUND_VARIATION: LV2_Midi_Controller = 70;
+#[doc = "< SC2 Timbre"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC2_TIMBRE: LV2_Midi_Controller = 71;
+#[doc = "< SC3 Release Time"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC3_RELEASE_TIME: LV2_Midi_Controller = 72;
+#[doc = "< SC4 Attack Time"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC4_ATTACK_TIME: LV2_Midi_Controller = 73;
+#[doc = "< SC5 Brightness"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC5_BRIGHTNESS: LV2_Midi_Controller = 74;
+#[doc = "< SC6"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC6: LV2_Midi_Controller = 75;
+#[doc = "< SC7"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC7: LV2_Midi_Controller = 76;
+#[doc = "< SC8"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC8: LV2_Midi_Controller = 77;
+#[doc = "< SC9"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC9: LV2_Midi_Controller = 78;
+#[doc = "< SC10"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC10: LV2_Midi_Controller = 79;
+#[doc = "< General Purpose 5"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_GENERAL_PURPOSE5: LV2_Midi_Controller = 80;
+#[doc = "< General Purpose 6"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_GENERAL_PURPOSE6: LV2_Midi_Controller = 81;
+#[doc = "< General Purpose 7"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_GENERAL_PURPOSE7: LV2_Midi_Controller = 82;
+#[doc = "< General Purpose 8"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_GENERAL_PURPOSE8: LV2_Midi_Controller = 83;
+#[doc = "< Portamento Control"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_PORTAMENTO_CONTROL: LV2_Midi_Controller = 84;
+#[doc = "< E1 Reverb Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E1_REVERB_DEPTH: LV2_Midi_Controller = 91;
+#[doc = "< E2 Tremolo Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E2_TREMOLO_DEPTH: LV2_Midi_Controller = 92;
+#[doc = "< E3 Chorus Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E3_CHORUS_DEPTH: LV2_Midi_Controller = 93;
+#[doc = "< E4 Detune Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E4_DETUNE_DEPTH: LV2_Midi_Controller = 94;
+#[doc = "< E5 Phaser Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E5_PHASER_DEPTH: LV2_Midi_Controller = 95;
+#[doc = "< Data Increment"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_DATA_INCREMENT: LV2_Midi_Controller = 96;
+#[doc = "< Data Decrement"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_DATA_DECREMENT: LV2_Midi_Controller = 97;
+#[doc = "< Non-registered Parameter Number"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_NRPN_LSB: LV2_Midi_Controller = 98;
+#[doc = "< Non-registered Parameter Number"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_NRPN_MSB: LV2_Midi_Controller = 99;
+#[doc = "< Registered Parameter Number"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_RPN_LSB: LV2_Midi_Controller = 100;
+#[doc = "< Registered Parameter Number"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_RPN_MSB: LV2_Midi_Controller = 101;
+#[doc = "< All Sounds Off"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_ALL_SOUNDS_OFF: LV2_Midi_Controller = 120;
+#[doc = "< Reset Controllers"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_RESET_CONTROLLERS: LV2_Midi_Controller = 121;
+#[doc = "< Local Control Switch"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LOCAL_CONTROL_SWITCH: LV2_Midi_Controller = 122;
+#[doc = "< All Notes Off"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_ALL_NOTES_OFF: LV2_Midi_Controller = 123;
+#[doc = "< Omni Off"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_OMNI_OFF: LV2_Midi_Controller = 124;
+#[doc = "< Omni On"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_OMNI_ON: LV2_Midi_Controller = 125;
+#[doc = "< Mono1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MONO1: LV2_Midi_Controller = 126;
+#[doc = "< Mono2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MONO2: LV2_Midi_Controller = 127;
+#[doc = "Standard MIDI Controller Numbers."]
+pub type LV2_Midi_Controller = u32;
+#[doc = "This option applies to the instance itself.  The subject must be"]
+#[doc = "ignored."]
+pub const LV2_Options_Context_LV2_OPTIONS_INSTANCE: LV2_Options_Context = 0;
+#[doc = "This option applies to some named resource.  The subject is a URI mapped"]
+#[doc = "to an integer (a LV2_URID, like the key)"]
+pub const LV2_Options_Context_LV2_OPTIONS_RESOURCE: LV2_Options_Context = 1;
+#[doc = "This option applies to some blank node.  The subject is a blank node"]
+#[doc = "identifier, which is valid only within the current local scope."]
+pub const LV2_Options_Context_LV2_OPTIONS_BLANK: LV2_Options_Context = 2;
+#[doc = "This option applies to a port on the instance.  The subject is the"]
+#[doc = "port's index."]
+pub const LV2_Options_Context_LV2_OPTIONS_PORT: LV2_Options_Context = 3;
+#[doc = "The context of an Option, which defines the subject it applies to."]
+pub type LV2_Options_Context = u32;
+#[doc = "An option."]
+#[doc = ""]
+#[doc = "This is a property with a subject, also known as a triple or statement."]
+#[doc = ""]
+#[doc = "This struct is useful anywhere a statement needs to be passed where no"]
+#[doc = "memory ownership issues are present (since the value is a const pointer)."]
+#[doc = ""]
+#[doc = "Options can be passed to an instance via the feature LV2_OPTIONS__options"]
+#[doc = "with data pointed to an array of options terminated by a zeroed option, or"]
+#[doc = "accessed/manipulated using LV2_Options_Interface."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Options_Option {
+    #[doc = "< Context (type of subject)."]
+    pub context: LV2_Options_Context,
+    #[doc = "< Subject."]
+    pub subject: u32,
+    #[doc = "< Key (property)."]
+    pub key: LV2_URID,
+    #[doc = "< Size of value in bytes."]
+    pub size: u32,
+    #[doc = "< Type of value (datatype)."]
+    pub type_: LV2_URID,
+    #[doc = "< Pointer to value (object)."]
+    pub value: *const ::std::os::raw::c_void,
+}
+#[doc = "< Completed successfully."]
+pub const LV2_Options_Status_LV2_OPTIONS_SUCCESS: LV2_Options_Status = 0;
+#[doc = "< Unknown error."]
+pub const LV2_Options_Status_LV2_OPTIONS_ERR_UNKNOWN: LV2_Options_Status = 1;
+#[doc = "< Invalid/unsupported subject."]
+pub const LV2_Options_Status_LV2_OPTIONS_ERR_BAD_SUBJECT: LV2_Options_Status = 2;
+#[doc = "< Invalid/unsupported key."]
+pub const LV2_Options_Status_LV2_OPTIONS_ERR_BAD_KEY: LV2_Options_Status = 4;
+#[doc = "< Invalid/unsupported value."]
+pub const LV2_Options_Status_LV2_OPTIONS_ERR_BAD_VALUE: LV2_Options_Status = 8;
+#[doc = " A status code for option functions."]
+pub type LV2_Options_Status = u32;
+#[doc = "Interface for dynamically setting options (LV2_OPTIONS__interface)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Options_Interface {
+    #[doc = "Get the given options."]
+    #[doc = ""]
+    #[doc = "Each element of the passed options array MUST have type, subject, and"]
+    #[doc = "key set.  All other fields (size, type, value) MUST be initialised to"]
+    #[doc = "zero, and are set to the option value if such an option is found."]
+    #[doc = ""]
+    #[doc = "This function is in the \"instantiation\" LV2 threading class, so no other"]
+    #[doc = "instance functions may be called concurrently."]
+    #[doc = ""]
+    #[doc = "@return Bitwise OR of LV2_Options_Status values."]
+    pub get: ::std::option::Option<
+        unsafe extern "C" fn(instance: LV2_Handle, options: *mut LV2_Options_Option) -> u32,
+    >,
+    #[doc = "Set the given options."]
+    #[doc = ""]
+    #[doc = "This function is in the \"instantiation\" LV2 threading class, so no other"]
+    #[doc = "instance functions may be called concurrently."]
+    #[doc = ""]
+    #[doc = "@return Bitwise OR of LV2_Options_Status values."]
+    pub set: ::std::option::Option<
+        unsafe extern "C" fn(instance: LV2_Handle, options: *const LV2_Options_Option) -> u32,
+    >,
+}
+#[doc = "< Completed successfully."]
+pub const LV2_Resize_Port_Status_LV2_RESIZE_PORT_SUCCESS: LV2_Resize_Port_Status = 0;
+#[doc = "< Unknown error."]
+pub const LV2_Resize_Port_Status_LV2_RESIZE_PORT_ERR_UNKNOWN: LV2_Resize_Port_Status = 1;
+#[doc = "< Insufficient space."]
+pub const LV2_Resize_Port_Status_LV2_RESIZE_PORT_ERR_NO_SPACE: LV2_Resize_Port_Status = 2;
+#[doc = " A status code for state functions."]
+pub type LV2_Resize_Port_Status = u32;
+#[doc = " Opaque data for resize method."]
+pub type LV2_Resize_Port_Feature_Data = *mut ::std::os::raw::c_void;
+#[doc = " Host feature to allow plugins to resize their port buffers."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Resize_Port_Resize {
+    #[doc = " Opaque data for resize method."]
+    pub data: LV2_Resize_Port_Feature_Data,
+    #[doc = "Resize a port buffer to at least `size` bytes."]
+    #[doc = ""]
+    #[doc = "This function MAY return an error, in which case the port buffer was not"]
+    #[doc = "resized and the port is still connected to the same location.  Plugins"]
+    #[doc = "MUST gracefully handle this situation."]
+    #[doc = ""]
+    #[doc = "This function is in the audio threading class."]
+    #[doc = ""]
+    #[doc = "The host MUST preserve the contents of the port buffer when resizing."]
+    #[doc = ""]
+    #[doc = "Plugins MAY resize a port many times in a single run callback.  Hosts"]
+    #[doc = "SHOULD make this as inexpensive as possible."]
+    pub resize: ::std::option::Option<
+        unsafe extern "C" fn(
+            data: LV2_Resize_Port_Feature_Data,
+            index: u32,
+            size: usize,
+        ) -> LV2_Resize_Port_Status,
+    >,
+}
+pub type LV2_State_Handle = *mut ::std::os::raw::c_void;
+pub type LV2_State_Free_Path_Handle = *mut ::std::os::raw::c_void;
+pub type LV2_State_Map_Path_Handle = *mut ::std::os::raw::c_void;
+pub type LV2_State_Make_Path_Handle = *mut ::std::os::raw::c_void;
+impl LV2_State_Flags {
+    #[doc = "Plain Old Data."]
+    #[doc = ""]
+    #[doc = "Values with this flag contain no pointers or references to other areas"]
+    #[doc = "of memory.  It is safe to copy POD values with a simple memcpy and store"]
+    #[doc = "them for the duration of the process.  A POD value is not necessarily"]
+    #[doc = "safe to trasmit between processes or machines (for example, filenames"]
+    #[doc = "are POD), see LV2_STATE_IS_PORTABLE for details."]
+    #[doc = ""]
+    #[doc = "Implementations MUST NOT attempt to copy or serialise a non-POD value if"]
+    #[doc = "they do not understand its type (and thus know how to correctly do so)."]
+    pub const LV2_STATE_IS_POD: LV2_State_Flags = LV2_State_Flags(1);
+}
+impl LV2_State_Flags {
+    #[doc = "Portable (architecture independent) data."]
+    #[doc = ""]
+    #[doc = "Values with this flag are in a format that is usable on any"]
+    #[doc = "architecture.  A portable value saved on one machine can be restored on"]
+    #[doc = "another machine regardless of architecture.  The format of portable"]
+    #[doc = "values MUST NOT depend on architecture-specific properties like"]
+    #[doc = "endianness or alignment.  Portable values MUST NOT contain filenames."]
+    pub const LV2_STATE_IS_PORTABLE: LV2_State_Flags = LV2_State_Flags(2);
+}
+impl LV2_State_Flags {
+    #[doc = "Native data."]
+    #[doc = ""]
+    #[doc = "This flag is used by the host to indicate that the saved data is only"]
+    #[doc = "going to be used locally in the currently running process (for things"]
+    #[doc = "like instance duplication or snapshots), so the plugin should use the"]
+    #[doc = "most efficient representation possible and not worry about serialisation"]
+    #[doc = "and portability."]
+    pub const LV2_STATE_IS_NATIVE: LV2_State_Flags = LV2_State_Flags(4);
+}
+impl ::std::ops::BitOr<LV2_State_Flags> for LV2_State_Flags {
+    type Output = Self;
+    #[inline]
+    fn bitor(self, other: Self) -> Self {
+        LV2_State_Flags(self.0 | other.0)
+    }
+}
+impl ::std::ops::BitOrAssign for LV2_State_Flags {
+    #[inline]
+    fn bitor_assign(&mut self, rhs: LV2_State_Flags) {
+        self.0 |= rhs.0;
+    }
+}
+impl ::std::ops::BitAnd<LV2_State_Flags> for LV2_State_Flags {
+    type Output = Self;
+    #[inline]
+    fn bitand(self, other: Self) -> Self {
+        LV2_State_Flags(self.0 & other.0)
+    }
+}
+impl ::std::ops::BitAndAssign for LV2_State_Flags {
+    #[inline]
+    fn bitand_assign(&mut self, rhs: LV2_State_Flags) {
+        self.0 &= rhs.0;
+    }
+}
+#[repr(transparent)]
+#[doc = "Flags describing value characteristics."]
+#[doc = ""]
+#[doc = "These flags are used along with the value's type URI to determine how to"]
+#[doc = "(de-)serialise the value data, or whether it is even possible to do so."]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct LV2_State_Flags(pub u32);
+#[doc = "< Completed successfully."]
+pub const LV2_State_Status_LV2_STATE_SUCCESS: LV2_State_Status = 0;
+#[doc = "< Unknown error."]
+pub const LV2_State_Status_LV2_STATE_ERR_UNKNOWN: LV2_State_Status = 1;
+#[doc = "< Failed due to unsupported type."]
+pub const LV2_State_Status_LV2_STATE_ERR_BAD_TYPE: LV2_State_Status = 2;
+#[doc = "< Failed due to unsupported flags."]
+pub const LV2_State_Status_LV2_STATE_ERR_BAD_FLAGS: LV2_State_Status = 3;
+#[doc = "< Failed due to missing features."]
+pub const LV2_State_Status_LV2_STATE_ERR_NO_FEATURE: LV2_State_Status = 4;
+#[doc = "< Failed due to missing property."]
+pub const LV2_State_Status_LV2_STATE_ERR_NO_PROPERTY: LV2_State_Status = 5;
+#[doc = "< Failed due to insufficient space."]
+pub const LV2_State_Status_LV2_STATE_ERR_NO_SPACE: LV2_State_Status = 6;
+#[doc = " A status code for state functions."]
+pub type LV2_State_Status = u32;
+#[doc = "A host-provided function to store a property."]
+#[doc = "@param handle Must be the handle passed to LV2_State_Interface.save()."]
+#[doc = "@param key The key to store `value` under (URID)."]
+#[doc = "@param value Pointer to the value to be stored."]
+#[doc = "@param size The size of `value` in bytes."]
+#[doc = "@param type The type of `value` (URID)."]
+#[doc = "@param flags LV2_State_Flags for `value`."]
+#[doc = "@return 0 on success, otherwise a non-zero error code."]
+#[doc = ""]
+#[doc = "The host passes a callback of this type to LV2_State_Interface.save(). This"]
+#[doc = "callback is called repeatedly by the plugin to store all the properties that"]
+#[doc = "describe its current state."]
+#[doc = ""]
+#[doc = "DO NOT INVENT NONSENSE URI SCHEMES FOR THE KEY.  Best is to use keys from"]
+#[doc = "existing vocabularies.  If nothing appropriate is available, use http URIs"]
+#[doc = "that point to somewhere you can host documents so documentation can be made"]
+#[doc = "resolvable (typically a child of the plugin or project URI).  If this is not"]
+#[doc = "possible, invent a URN scheme, e.g. urn:myproj:whatever.  The plugin MUST"]
+#[doc = "NOT pass an invalid URI key."]
+#[doc = ""]
+#[doc = "The host MAY fail to store a property for whatever reason, but SHOULD"]
+#[doc = "store any property that is LV2_STATE_IS_POD and LV2_STATE_IS_PORTABLE."]
+#[doc = "Implementations SHOULD use the types from the LV2 Atom extension"]
+#[doc = "(http://lv2plug.in/ns/ext/atom) wherever possible.  The plugin SHOULD"]
+#[doc = "attempt to fall-back and avoid the error if possible."]
+#[doc = ""]
+#[doc = "Note that `size` MUST be > 0, and `value` MUST point to a valid region of"]
+#[doc = "memory `size` bytes long (this is required to make restore unambiguous)."]
+#[doc = ""]
+#[doc = "The plugin MUST NOT attempt to use this function outside of the"]
+#[doc = "LV2_State_Interface.restore() context."]
+pub type LV2_State_Store_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_State_Handle,
+        key: u32,
+        value: *const ::std::os::raw::c_void,
+        size: usize,
+        type_: u32,
+        flags: u32,
+    ) -> LV2_State_Status,
+>;
+#[doc = "A host-provided function to retrieve a property."]
+#[doc = "@param handle Must be the handle passed to LV2_State_Interface.restore()."]
+#[doc = "@param key The key of the property to retrieve (URID)."]
+#[doc = "@param size (Output) If non-NULL, set to the size of the restored value."]
+#[doc = "@param type (Output) If non-NULL, set to the type of the restored value."]
+#[doc = "@param flags (Output) If non-NULL, set to the flags for the restored value."]
+#[doc = "@return A pointer to the restored value (object), or NULL if no value"]
+#[doc = "has been stored under `key`."]
+#[doc = ""]
+#[doc = "A callback of this type is passed by the host to"]
+#[doc = "LV2_State_Interface.restore().  This callback is called repeatedly by the"]
+#[doc = "plugin to retrieve any properties it requires to restore its state."]
+#[doc = ""]
+#[doc = "The returned value MUST remain valid until LV2_State_Interface.restore()"]
+#[doc = "returns.  The plugin MUST NOT attempt to use this function, or any value"]
+#[doc = "returned from it, outside of the LV2_State_Interface.restore() context."]
+pub type LV2_State_Retrieve_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_State_Handle,
+        key: u32,
+        size: *mut usize,
+        type_: *mut u32,
+        flags: *mut u32,
+    ) -> *const ::std::os::raw::c_void,
+>;
+#[doc = "LV2 Plugin State Interface."]
+#[doc = ""]
+#[doc = "When the plugin's extension_data is called with argument"]
+#[doc = "LV2_STATE__interface, the plugin MUST return an LV2_State_Interface"]
+#[doc = "structure, which remains valid for the lifetime of the plugin."]
+#[doc = ""]
+#[doc = "The host can use the contained function pointers to save and restore the"]
+#[doc = "state of a plugin instance at any time, provided the threading restrictions"]
+#[doc = "of the functions are met."]
+#[doc = ""]
+#[doc = "Stored data is only guaranteed to be compatible between instances of plugins"]
+#[doc = "with the same URI (i.e. if a change to a plugin would cause a fatal error"]
+#[doc = "when restoring state saved by a previous version of that plugin, the plugin"]
+#[doc = "URI MUST change just as it must when ports change incompatibly).  Plugin"]
+#[doc = "authors should consider this possibility, and always store sensible data"]
+#[doc = "with meaningful types to avoid such problems in the future."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_State_Interface {
+    #[doc = "Save plugin state using a host-provided `store` callback."]
+    #[doc = ""]
+    #[doc = "@param instance The instance handle of the plugin."]
+    #[doc = "@param store The host-provided store callback."]
+    #[doc = "@param handle An opaque pointer to host data which MUST be passed as the"]
+    #[doc = "handle parameter to `store` if it is called."]
+    #[doc = "@param flags Flags describing desired properties of this save.  These"]
+    #[doc = "flags may be used to determine the most appropriate values to store."]
+    #[doc = "@param features Extensible parameter for passing any additional"]
+    #[doc = "features to be used for this save."]
+    #[doc = ""]
+    #[doc = "The plugin is expected to store everything necessary to completely"]
+    #[doc = "restore its state later.  Plugins SHOULD store simple POD data whenever"]
+    #[doc = "possible, and consider the possibility of state being restored much"]
+    #[doc = "later on a different machine."]
+    #[doc = ""]
+    #[doc = "The `handle` pointer and `store` function MUST NOT be used"]
+    #[doc = "beyond the scope of save()."]
+    #[doc = ""]
+    #[doc = "This function has its own special threading class: it may not be called"]
+    #[doc = "concurrently with any \"Instantiation\" function, but it may be called"]
+    #[doc = "concurrently with functions in any other class, unless the definition of"]
+    #[doc = "that class prohibits it (for example, it may not be called concurrently"]
+    #[doc = "with a \"Discovery\" function, but it may be called concurrently with an"]
+    #[doc = "\"Audio\" function.  The plugin is responsible for any locking or"]
+    #[doc = "lock-free techniques necessary to make this possible."]
+    #[doc = ""]
+    #[doc = "Note that in the simple case where state is only modified by restore(),"]
+    #[doc = "there are no synchronization issues since save() is never called"]
+    #[doc = "concurrently with restore() (though run() may read it during a save)."]
+    #[doc = ""]
+    #[doc = "Plugins that dynamically modify state while running, however, must take"]
+    #[doc = "care to do so in such a way that a concurrent call to save() will save a"]
+    #[doc = "consistent representation of plugin state for a single instant in time."]
+    pub save: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            store: LV2_State_Store_Function,
+            handle: LV2_State_Handle,
+            flags: u32,
+            features: *const *const LV2_Feature,
+        ) -> LV2_State_Status,
+    >,
+    #[doc = "Restore plugin state using a host-provided `retrieve` callback."]
+    #[doc = ""]
+    #[doc = "@param instance The instance handle of the plugin."]
+    #[doc = "@param retrieve The host-provided retrieve callback."]
+    #[doc = "@param handle An opaque pointer to host data which MUST be passed as the"]
+    #[doc = "handle parameter to `retrieve` if it is called."]
+    #[doc = "@param flags Currently unused."]
+    #[doc = "@param features Extensible parameter for passing any additional"]
+    #[doc = "features to be used for this restore."]
+    #[doc = ""]
+    #[doc = "The plugin MAY assume a restored value was set by a previous call to"]
+    #[doc = "LV2_State_Interface.save() by a plugin with the same URI."]
+    #[doc = ""]
+    #[doc = "The plugin MUST gracefully fall back to a default value when a value can"]
+    #[doc = "not be retrieved.  This allows the host to reset the plugin state with"]
+    #[doc = "an empty map."]
+    #[doc = ""]
+    #[doc = "The `handle` pointer and `store` function MUST NOT be used"]
+    #[doc = "beyond the scope of restore()."]
+    #[doc = ""]
+    #[doc = "This function is in the \"Instantiation\" threading class as defined by"]
+    #[doc = "LV2. This means it MUST NOT be called concurrently with any other"]
+    #[doc = "function on the same plugin instance."]
+    pub restore: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            retrieve: LV2_State_Retrieve_Function,
+            handle: LV2_State_Handle,
+            flags: u32,
+            features: *const *const LV2_Feature,
+        ) -> LV2_State_Status,
+    >,
+}
+#[doc = "Feature data for state:mapPath (@ref LV2_STATE__mapPath)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_State_Map_Path {
+    #[doc = "Opaque host data."]
+    pub handle: LV2_State_Map_Path_Handle,
+    #[doc = "Map an absolute path to an abstract path for use in plugin state."]
+    #[doc = "@param handle MUST be the `handle` member of this struct."]
+    #[doc = "@param absolute_path The absolute path of a file."]
+    #[doc = "@return An abstract path suitable for use in plugin state."]
+    #[doc = ""]
+    #[doc = "The plugin MUST use this function to map any paths that will be stored"]
+    #[doc = "in plugin state.  The returned value is an abstract path which MAY not"]
+    #[doc = "be an actual file system path; absolute_path() MUST be used to map"]
+    #[doc = "it to an actual path in order to use the file."]
+    #[doc = ""]
+    #[doc = "Plugins MUST NOT make any assumptions about abstract paths except that"]
+    #[doc = "they can be mapped back to the absolute path of the \"same\" file (though"]
+    #[doc = "not necessarily the same original path) using absolute_path()."]
+    #[doc = ""]
+    #[doc = "This function may only be called within the context of"]
+    #[doc = "LV2_State_Interface methods.  The caller must free the returned value"]
+    #[doc = "with LV2_State_Free_Path.free_path()."]
+    pub abstract_path: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_State_Map_Path_Handle,
+            absolute_path: *const ::std::os::raw::c_char,
+        ) -> *mut ::std::os::raw::c_char,
+    >,
+    #[doc = "Map an abstract path from plugin state to an absolute path."]
+    #[doc = "@param handle MUST be the `handle` member of this struct."]
+    #[doc = "@param abstract_path An abstract path (typically from plugin state)."]
+    #[doc = "@return An absolute file system path."]
+    #[doc = ""]
+    #[doc = "The plugin MUST use this function in order to actually open or otherwise"]
+    #[doc = "use any paths loaded from plugin state."]
+    #[doc = ""]
+    #[doc = "This function may only be called within the context of"]
+    #[doc = "LV2_State_Interface methods.  The caller must free the returned value"]
+    #[doc = "with LV2_State_Free_Path.free_path()."]
+    pub absolute_path: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_State_Map_Path_Handle,
+            abstract_path: *const ::std::os::raw::c_char,
+        ) -> *mut ::std::os::raw::c_char,
+    >,
+}
+#[doc = "Feature data for state:makePath (@ref LV2_STATE__makePath)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_State_Make_Path {
+    #[doc = "Opaque host data."]
+    pub handle: LV2_State_Make_Path_Handle,
+    #[doc = "Return a path the plugin may use to create a new file."]
+    #[doc = "@param handle MUST be the `handle` member of this struct."]
+    #[doc = "@param path The path of the new file within a namespace unique to this"]
+    #[doc = "plugin instance."]
+    #[doc = "@return The absolute path to use for the new file."]
+    #[doc = ""]
+    #[doc = "This function can be used by plugins to create files and directories,"]
+    #[doc = "either at state saving time (if this feature is passed to"]
+    #[doc = "LV2_State_Interface.save()) or any time (if this feature is passed to"]
+    #[doc = "LV2_Descriptor.instantiate())."]
+    #[doc = ""]
+    #[doc = "The host MUST do whatever is necessary for the plugin to be able to"]
+    #[doc = "create a file at the returned path (for example, using fopen()),"]
+    #[doc = "including creating any leading directories."]
+    #[doc = ""]
+    #[doc = "If this function is passed to LV2_Descriptor.instantiate(), it may be"]
+    #[doc = "called from any non-realtime context.  If it is passed to"]
+    #[doc = "LV2_State_Interface.save(), it may only be called within the dynamic"]
+    #[doc = "scope of that function call."]
+    #[doc = ""]
+    #[doc = "The caller must free the returned value with"]
+    #[doc = "LV2_State_Free_Path.free_path()."]
+    pub path: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_State_Make_Path_Handle,
+            path: *const ::std::os::raw::c_char,
+        ) -> *mut ::std::os::raw::c_char,
+    >,
+}
+#[doc = "Feature data for state:freePath (@ref LV2_STATE__freePath)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_State_Free_Path {
+    #[doc = "Opaque host data."]
+    pub handle: LV2_State_Free_Path_Handle,
+    #[doc = "Free a path returned by a state feature."]
+    #[doc = ""]
+    #[doc = "@param handle MUST be the `handle` member of this struct."]
+    #[doc = "@param path The path previously returned by a state feature."]
+    #[doc = ""]
+    #[doc = "This function can be used by plugins to free paths allocated by the host"]
+    #[doc = "and returned by state features (LV2_State_Map_Path.abstract_path(),"]
+    #[doc = "LV2_State_Map_Path.absolute_path(), and LV2_State_Make_Path.path())."]
+    pub free_path: ::std::option::Option<
+        unsafe extern "C" fn(handle: LV2_State_Free_Path_Handle, path: *mut ::std::os::raw::c_char),
+    >,
+}
+#[doc = "A pointer to some widget or other type of UI handle."]
+#[doc = ""]
+#[doc = "The actual type is defined by the type of the UI."]
+pub type LV2UI_Widget = *mut ::std::os::raw::c_void;
+#[doc = "A pointer to UI instance internals."]
+#[doc = ""]
+#[doc = "The host may compare this to NULL, but otherwise MUST NOT interpret it."]
+pub type LV2UI_Handle = *mut ::std::os::raw::c_void;
+#[doc = "A pointer to a controller provided by the host."]
+#[doc = ""]
+#[doc = "The UI may compare this to NULL, but otherwise MUST NOT interpret it."]
+pub type LV2UI_Controller = *mut ::std::os::raw::c_void;
+#[doc = "A pointer to opaque data for a feature."]
+pub type LV2UI_Feature_Handle = *mut ::std::os::raw::c_void;
+#[doc = "A host-provided function that sends data to a plugin's input ports."]
+#[doc = ""]
+#[doc = "@param controller The opaque controller pointer passed to"]
+#[doc = "LV2UI_Descriptor::instantiate()."]
+#[doc = ""]
+#[doc = "@param port_index Index of the port to update."]
+#[doc = ""]
+#[doc = "@param buffer Buffer containing `buffer_size` bytes of data."]
+#[doc = ""]
+#[doc = "@param buffer_size Size of `buffer` in bytes."]
+#[doc = ""]
+#[doc = "@param port_protocol Either 0 or the URID for a ui:PortProtocol.  If 0, the"]
+#[doc = "protocol is implicitly ui:floatProtocol, the port MUST be an lv2:ControlPort"]
+#[doc = "input, `buffer` MUST point to a single float value, and `buffer_size` MUST"]
+#[doc = "be sizeof(float).  The UI SHOULD NOT use a protocol not supported by the"]
+#[doc = "host, but the host MUST gracefully ignore any protocol it does not"]
+#[doc = "understand."]
+pub type LV2UI_Write_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        controller: LV2UI_Controller,
+        port_index: u32,
+        buffer_size: u32,
+        port_protocol: u32,
+        buffer: *const ::std::os::raw::c_void,
+    ),
+>;
+#[doc = "A plugin UI."]
+#[doc = ""]
+#[doc = "A pointer to an object of this type is returned by the lv2ui_descriptor()"]
+#[doc = "function."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Descriptor {
+    #[doc = "The URI for this UI (not for the plugin it controls)."]
+    pub URI: *const ::std::os::raw::c_char,
+    #[doc = "Create a new UI and return a handle to it.  This function works"]
+    #[doc = "similarly to LV2_Descriptor::instantiate()."]
+    #[doc = ""]
+    #[doc = "@param descriptor The descriptor for the UI to instantiate."]
+    #[doc = ""]
+    #[doc = "@param plugin_uri The URI of the plugin that this UI will control."]
+    #[doc = ""]
+    #[doc = "@param bundle_path The path to the bundle containing this UI, including"]
+    #[doc = "the trailing directory separator."]
+    #[doc = ""]
+    #[doc = "@param write_function A function that the UI can use to send data to the"]
+    #[doc = "plugin's input ports."]
+    #[doc = ""]
+    #[doc = "@param controller A handle for the UI instance to be passed as the"]
+    #[doc = "first parameter of UI methods."]
+    #[doc = ""]
+    #[doc = "@param widget (output) widget pointer.  The UI points this at its main"]
+    #[doc = "widget, which has the type defined by the UI type in the data file."]
+    #[doc = ""]
+    #[doc = "@param features An array of LV2_Feature pointers.  The host must pass"]
+    #[doc = "all feature URIs that it and the UI supports and any additional data, as"]
+    #[doc = "in LV2_Descriptor::instantiate().  Note that UI features and plugin"]
+    #[doc = "features are not necessarily the same."]
+    #[doc = ""]
+    pub instantiate: ::std::option::Option<
+        unsafe extern "C" fn(
+            descriptor: *const LV2UI_Descriptor,
+            plugin_uri: *const ::std::os::raw::c_char,
+            bundle_path: *const ::std::os::raw::c_char,
+            write_function: LV2UI_Write_Function,
+            controller: LV2UI_Controller,
+            widget: *mut LV2UI_Widget,
+            features: *const *const LV2_Feature,
+        ) -> LV2UI_Handle,
+    >,
+    #[doc = "Destroy the UI.  The host must not try to access the widget after"]
+    #[doc = "calling this function."]
+    pub cleanup: ::std::option::Option<unsafe extern "C" fn(ui: LV2UI_Handle)>,
+    #[doc = "Tell the UI that something interesting has happened at a plugin port."]
+    #[doc = ""]
+    #[doc = "What is \"interesting\" and how it is written to `buffer` is defined by"]
+    #[doc = "`format`, which has the same meaning as in LV2UI_Write_Function()."]
+    #[doc = "Format 0 is a special case for lv2:ControlPort, where this function"]
+    #[doc = "should be called when the port value changes (but not necessarily for"]
+    #[doc = "every change), `buffer_size` must be sizeof(float), and `buffer`"]
+    #[doc = "points to a single IEEE-754 float."]
+    #[doc = ""]
+    #[doc = "By default, the host should only call this function for lv2:ControlPort"]
+    #[doc = "inputs.  However, the UI can request updates for other ports statically"]
+    #[doc = "with ui:portNotification or dynamicaly with ui:portSubscribe."]
+    #[doc = ""]
+    #[doc = "The UI MUST NOT retain any reference to `buffer` after this function"]
+    #[doc = "returns, it is only valid for the duration of the call."]
+    #[doc = ""]
+    #[doc = "This member may be NULL if the UI is not interested in any port events."]
+    pub port_event: ::std::option::Option<
+        unsafe extern "C" fn(
+            ui: LV2UI_Handle,
+            port_index: u32,
+            buffer_size: u32,
+            format: u32,
+            buffer: *const ::std::os::raw::c_void,
+        ),
+    >,
+    #[doc = "Return a data structure associated with an extension URI, typically an"]
+    #[doc = "interface struct with additional function pointers"]
+    #[doc = ""]
+    #[doc = "This member may be set to NULL if the UI is not interested in supporting"]
+    #[doc = "any extensions. This is similar to LV2_Descriptor::extension_data()."]
+    #[doc = ""]
+    pub extension_data: ::std::option::Option<
+        unsafe extern "C" fn(uri: *const ::std::os::raw::c_char) -> *const ::std::os::raw::c_void,
+    >,
+}
+#[doc = "Feature/interface for resizable UIs (LV2_UI__resize)."]
+#[doc = ""]
+#[doc = "This structure is used in two ways: as a feature passed by the host via"]
+#[doc = "LV2UI_Descriptor::instantiate(), or as an interface provided by a UI via"]
+#[doc = "LV2UI_Descriptor::extension_data())."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Resize {
+    #[doc = "Pointer to opaque data which must be passed to ui_resize()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Request/advertise a size change."]
+    #[doc = ""]
+    #[doc = "When provided by the host, the UI may call this function to inform the"]
+    #[doc = "host about the size of the UI."]
+    #[doc = ""]
+    #[doc = "When provided by the UI, the host may call this function to notify the"]
+    #[doc = "UI that it should change its size accordingly.  In this case, the host"]
+    #[doc = "must pass the LV2UI_Handle to provide access to the UI instance."]
+    #[doc = ""]
+    #[doc = "@return 0 on success."]
+    pub ui_resize: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            width: ::std::os::raw::c_int,
+            height: ::std::os::raw::c_int,
+        ) -> ::std::os::raw::c_int,
+    >,
+}
+#[doc = "Feature to map port symbols to UIs."]
+#[doc = ""]
+#[doc = "This can be used by the UI to get the index for a port with the given"]
+#[doc = "symbol.  This makes it possible to implement and distribute a UI separately"]
+#[doc = "from the plugin (since symbol, unlike index, is a stable port identifier)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Port_Map {
+    #[doc = "Pointer to opaque data which must be passed to port_index()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Get the index for the port with the given `symbol`."]
+    #[doc = ""]
+    #[doc = "@return The index of the port, or LV2UI_INVALID_PORT_INDEX if no such"]
+    #[doc = "port is found."]
+    pub port_index: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            symbol: *const ::std::os::raw::c_char,
+        ) -> u32,
+    >,
+}
+#[doc = "Feature to subscribe to port updates (LV2_UI__portSubscribe)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Port_Subscribe {
+    #[doc = "Pointer to opaque data which must be passed to subscribe() and"]
+    #[doc = "unsubscribe()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Subscribe to updates for a port."]
+    #[doc = ""]
+    #[doc = "This means that the host will call the UI's port_event() function when"]
+    #[doc = "the port value changes (as defined by protocol)."]
+    #[doc = ""]
+    #[doc = "Calling this function with the same `port_index` and `port_protocol`"]
+    #[doc = "as an already active subscription has no effect."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = "@param port_index The index of the port."]
+    #[doc = "@param port_protocol The URID of the ui:PortProtocol."]
+    #[doc = "@param features Features for this subscription."]
+    #[doc = "@return 0 on success."]
+    pub subscribe: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            port_index: u32,
+            port_protocol: u32,
+            features: *const *const LV2_Feature,
+        ) -> u32,
+    >,
+    #[doc = "Unsubscribe from updates for a port."]
+    #[doc = ""]
+    #[doc = "This means that the host will cease calling calling port_event() when"]
+    #[doc = "the port value changes."]
+    #[doc = ""]
+    #[doc = "Calling this function with a `port_index` and `port_protocol` that"]
+    #[doc = "does not refer to an active port subscription has no effect."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = "@param port_index The index of the port."]
+    #[doc = "@param port_protocol The URID of the ui:PortProtocol."]
+    #[doc = "@param features Features for this subscription."]
+    #[doc = "@return 0 on success."]
+    pub unsubscribe: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            port_index: u32,
+            port_protocol: u32,
+            features: *const *const LV2_Feature,
+        ) -> u32,
+    >,
+}
+#[doc = "A feature to notify the host that the user has grabbed a UI control."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Touch {
+    #[doc = "Pointer to opaque data which must be passed to ui_resize()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Notify the host that a control has been grabbed or released."]
+    #[doc = ""]
+    #[doc = "The host should cease automating the port or otherwise manipulating the"]
+    #[doc = "port value until the control has been ungrabbed."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = "@param port_index The index of the port associated with the control."]
+    #[doc = "@param grabbed If true, the control has been grabbed, otherwise the"]
+    #[doc = "control has been released."]
+    pub touch: ::std::option::Option<
+        unsafe extern "C" fn(handle: LV2UI_Feature_Handle, port_index: u32, grabbed: bool),
+    >,
+}
+#[doc = "Completed successfully."]
+#[doc = ""]
+#[doc = "The host will set the parameter later if the user choses a new value."]
+pub const LV2UI_Request_Value_Status_LV2UI_REQUEST_VALUE_SUCCESS: LV2UI_Request_Value_Status = 0;
+#[doc = "Parameter already being requested."]
+#[doc = ""]
+#[doc = "The host is already requesting a parameter from the user (for example, a"]
+#[doc = "dialog is visible), or the UI is otherwise busy and can not make this"]
+#[doc = "request."]
+pub const LV2UI_Request_Value_Status_LV2UI_REQUEST_VALUE_BUSY: LV2UI_Request_Value_Status = 1;
+#[doc = "Unknown parameter."]
+#[doc = ""]
+#[doc = "The host is not aware of this parameter, and is not able to set a new"]
+#[doc = "value for it."]
+pub const LV2UI_Request_Value_Status_LV2UI_REQUEST_VALUE_ERR_UNKNOWN: LV2UI_Request_Value_Status =
+    2;
+#[doc = "Unsupported parameter."]
+#[doc = ""]
+#[doc = "The host knows about this parameter, but does not support requesting a"]
+#[doc = "new value for it from the user.  This is likely because the host does"]
+#[doc = "not have UI support for choosing a value with the appropriate type."]
+pub const LV2UI_Request_Value_Status_LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED:
+    LV2UI_Request_Value_Status = 3;
+#[doc = "A status code for LV2UI_Request_Value::request()."]
+pub type LV2UI_Request_Value_Status = u32;
+#[doc = "A feature to request a new parameter value from the host."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Request_Value {
+    #[doc = "Pointer to opaque data which must be passed to request()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Request a value for a parameter from the host."]
+    #[doc = ""]
+    #[doc = "This is mainly used by UIs to request values for complex parameters that"]
+    #[doc = "don't change often, such as file paths, but it may be used to request"]
+    #[doc = "any parameter value."]
+    #[doc = ""]
+    #[doc = "This function returns immediately, and the return value indicates"]
+    #[doc = "whether the host can fulfill the request.  The host may notify the"]
+    #[doc = "plugin about the new parameter value, for example when a file is"]
+    #[doc = "selected by the user, via the usual mechanism.  Typically, the host will"]
+    #[doc = "send a message to the plugin that sets the new parameter value, and the"]
+    #[doc = "plugin will notify the UI via a message as usual for any other parameter"]
+    #[doc = "change."]
+    #[doc = ""]
+    #[doc = "To provide an appropriate UI, the host can determine details about the"]
+    #[doc = "parameter from the plugin data as usual.  The additional parameters of"]
+    #[doc = "this function provide support for more advanced use cases, but in the"]
+    #[doc = "simple common case, the plugin will simply pass the key of the desired"]
+    #[doc = "parameter and zero for everything else."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = ""]
+    #[doc = "@param key The URID of the parameter."]
+    #[doc = ""]
+    #[doc = "@param type The optional type of the value to request.  This can be used"]
+    #[doc = "to request a specific value type for parameters that support several."]
+    #[doc = "If non-zero, it must be the URID of an instance of rdfs:Class or"]
+    #[doc = "rdfs:Datatype."]
+    #[doc = ""]
+    #[doc = "@param features Additional features for this request, or NULL."]
+    #[doc = ""]
+    #[doc = "@return A status code which is 0 on success."]
+    pub request: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            key: LV2_URID,
+            type_: LV2_URID,
+            features: *const *const LV2_Feature,
+        ) -> LV2UI_Request_Value_Status,
+    >,
+}
+#[doc = "UI Idle Interface (LV2_UI__idleInterface)"]
+#[doc = ""]
+#[doc = "UIs can provide this interface to have an idle() callback called by the host"]
+#[doc = "rapidly to update the UI."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Idle_Interface {
+    #[doc = "Run a single iteration of the UI's idle loop."]
+    #[doc = ""]
+    #[doc = "This will be called rapidly in the UI thread at a rate appropriate"]
+    #[doc = "for a toolkit main loop.  There are no precise timing guarantees, but"]
+    #[doc = "the host should attempt to call idle() at a high enough rate for smooth"]
+    #[doc = "animation, at least 30Hz."]
+    #[doc = ""]
+    #[doc = "@return non-zero if the UI has been closed, in which case the host"]
+    #[doc = "should stop calling idle(), and can either completely destroy the UI, or"]
+    #[doc = "re-show it and resume calling idle()."]
+    pub idle:
+        ::std::option::Option<unsafe extern "C" fn(ui: LV2UI_Handle) -> ::std::os::raw::c_int>,
+}
+#[doc = "UI Show Interface (LV2_UI__showInterface)"]
+#[doc = ""]
+#[doc = "UIs can provide this interface to show and hide a window, which allows them"]
+#[doc = "to function in hosts unable to embed their widget.  This allows any UI to"]
+#[doc = "provide a fallback for embedding that works in any host."]
+#[doc = ""]
+#[doc = "If used:"]
+#[doc = "- The host MUST use LV2UI_Idle_Interface to drive the UI."]
+#[doc = "- The UI MUST return non-zero from LV2UI_Idle_Interface::idle() when it has been closed."]
+#[doc = "- If idle() returns non-zero, the host MUST call hide() and stop calling"]
+#[doc = "idle().  It MAY later call show() then resume calling idle()."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Show_Interface {
+    #[doc = "Show a window for this UI."]
+    #[doc = ""]
+    #[doc = "The window title MAY have been passed by the host to"]
+    #[doc = "LV2UI_Descriptor::instantiate() as an LV2_Options_Option with key"]
+    #[doc = "LV2_UI__windowTitle."]
+    #[doc = ""]
+    #[doc = "@return 0 on success, or anything else to stop being called."]
+    pub show:
+        ::std::option::Option<unsafe extern "C" fn(ui: LV2UI_Handle) -> ::std::os::raw::c_int>,
+    #[doc = "Hide the window for this UI."]
+    #[doc = ""]
+    #[doc = "@return 0 on success, or anything else to stop being called."]
+    pub hide:
+        ::std::option::Option<unsafe extern "C" fn(ui: LV2UI_Handle) -> ::std::os::raw::c_int>,
+}
+#[doc = "Peak data for a slice of time, the update format for ui:peakProtocol."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Peak_Data {
+    #[doc = "The start of the measurement period.  This is just a running counter"]
+    #[doc = "that is only meaningful in comparison to previous values and must not be"]
+    #[doc = "interpreted as an absolute time."]
+    pub period_start: u32,
+    #[doc = "The size of the measurement period, in the same units as period_start."]
+    pub period_size: u32,
+    #[doc = "The peak value for the measurement period. This should be the maximal"]
+    #[doc = "value for abs(sample) over all the samples in the period."]
+    pub peak: f32,
+}
+#[doc = "The type of the lv2ui_descriptor() function."]
+pub type LV2UI_DescriptorFunction =
+    ::std::option::Option<unsafe extern "C" fn(index: u32) -> *const LV2UI_Descriptor>;
+pub type LV2_URI_Map_Callback_Data = *mut ::std::os::raw::c_void;
+#[doc = "URI Map Feature."]
+#[doc = ""]
+#[doc = "To support this feature the host must pass an LV2_Feature struct to the"]
+#[doc = "plugin's instantiate method with URI \"http://lv2plug.in/ns/ext/uri-map\""]
+#[doc = "and data pointed to an instance of this struct."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_URI_Map_Feature {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "The plugin MUST pass this to any call to functions in this struct."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub callback_data: LV2_URI_Map_Callback_Data,
+    #[doc = "Get the numeric ID of a URI from the host."]
+    #[doc = ""]
+    #[doc = "@param callback_data Must be the callback_data member of this struct."]
+    #[doc = "@param map The 'context' of this URI. Certain extensions may define a"]
+    #[doc = "URI that must be passed here with certain restrictions on the return"]
+    #[doc = "value (e.g. limited range). This value may be NULL if the plugin needs"]
+    #[doc = "an ID for a URI in general. Extensions SHOULD NOT define a context"]
+    #[doc = "unless there is a specific need to do so, e.g. to restrict the range of"]
+    #[doc = "the returned value."]
+    #[doc = "@param uri The URI to be mapped to an integer ID."]
+    #[doc = ""]
+    #[doc = "This function is referentially transparent; any number of calls with the"]
+    #[doc = "same arguments is guaranteed to return the same value over the life of a"]
+    #[doc = "plugin instance (though the same URI may return different values with a"]
+    #[doc = "different map parameter). However, this function is not necessarily very"]
+    #[doc = "fast: plugins SHOULD cache any IDs they might need in performance"]
+    #[doc = "critical situations."]
+    #[doc = ""]
+    #[doc = "The return value 0 is reserved and indicates that an ID for that URI"]
+    #[doc = "could not be created for whatever reason. Extensions MAY define more"]
+    #[doc = "precisely what this means in a certain context, but in general plugins"]
+    #[doc = "SHOULD handle this situation as gracefully as possible. However, hosts"]
+    #[doc = "SHOULD NOT return 0 from this function in non-exceptional circumstances"]
+    #[doc = "(e.g. the URI map SHOULD be dynamic). Hosts that statically support only"]
+    #[doc = "a fixed set of URIs should not expect plugins to function correctly."]
+    pub uri_to_id: ::std::option::Option<
+        unsafe extern "C" fn(
+            callback_data: LV2_URI_Map_Callback_Data,
+            map: *const ::std::os::raw::c_char,
+            uri: *const ::std::os::raw::c_char,
+        ) -> u32,
+    >,
+}
+#[doc = "< Completed successfully."]
+pub const LV2_Worker_Status_LV2_WORKER_SUCCESS: LV2_Worker_Status = 0;
+#[doc = "< Unknown error."]
+pub const LV2_Worker_Status_LV2_WORKER_ERR_UNKNOWN: LV2_Worker_Status = 1;
+#[doc = "< Failed due to lack of space."]
+pub const LV2_Worker_Status_LV2_WORKER_ERR_NO_SPACE: LV2_Worker_Status = 2;
+#[doc = "Status code for worker functions."]
+pub type LV2_Worker_Status = u32;
+#[doc = " Opaque handle for LV2_Worker_Interface::work()."]
+pub type LV2_Worker_Respond_Handle = *mut ::std::os::raw::c_void;
+#[doc = "A function to respond to run() from the worker method."]
+#[doc = ""]
+#[doc = "The `data` MUST be safe for the host to copy and later pass to"]
+#[doc = "work_response(), and the host MUST guarantee that it will be eventually"]
+#[doc = "passed to work_response() if this function returns LV2_WORKER_SUCCESS."]
+pub type LV2_Worker_Respond_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_Worker_Respond_Handle,
+        size: u32,
+        data: *const ::std::os::raw::c_void,
+    ) -> LV2_Worker_Status,
+>;
+#[doc = "Plugin Worker Interface."]
+#[doc = ""]
+#[doc = "This is the interface provided by the plugin to implement a worker method."]
+#[doc = "The plugin's extension_data() method should return an LV2_Worker_Interface"]
+#[doc = "when called with LV2_WORKER__interface as its argument."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Worker_Interface {
+    #[doc = "The worker method.  This is called by the host in a non-realtime context"]
+    #[doc = "as requested, possibly with an arbitrary message to handle."]
+    #[doc = ""]
+    #[doc = "A response can be sent to run() using `respond`.  The plugin MUST NOT"]
+    #[doc = "make any assumptions about which thread calls this method, except that"]
+    #[doc = "there are no real-time requirements and only one call may be executed at"]
+    #[doc = "a time.  That is, the host MAY call this method from any non-real-time"]
+    #[doc = "thread, but MUST NOT make concurrent calls to this method from several"]
+    #[doc = "threads."]
+    #[doc = ""]
+    #[doc = "@param instance The LV2 instance this is a method on."]
+    #[doc = "@param respond  A function for sending a response to run()."]
+    #[doc = "@param handle   Must be passed to `respond` if it is called."]
+    #[doc = "@param size     The size of `data`."]
+    #[doc = "@param data     Data from run(), or NULL."]
+    pub work: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            respond: LV2_Worker_Respond_Function,
+            handle: LV2_Worker_Respond_Handle,
+            size: u32,
+            data: *const ::std::os::raw::c_void,
+        ) -> LV2_Worker_Status,
+    >,
+    #[doc = "Handle a response from the worker.  This is called by the host in the"]
+    #[doc = "run() context when a response from the worker is ready."]
+    #[doc = ""]
+    #[doc = "@param instance The LV2 instance this is a method on."]
+    #[doc = "@param size     The size of `body`."]
+    #[doc = "@param body     Message body, or NULL."]
+    pub work_response: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            size: u32,
+            body: *const ::std::os::raw::c_void,
+        ) -> LV2_Worker_Status,
+    >,
+    #[doc = "Called when all responses for this cycle have been delivered."]
+    #[doc = ""]
+    #[doc = "Since work_response() may be called after run() finished, this provides"]
+    #[doc = "a hook for code that must run after the cycle is completed."]
+    #[doc = ""]
+    #[doc = "This field may be NULL if the plugin has no use for it.  Otherwise, the"]
+    #[doc = "host MUST call it after every run(), regardless of whether or not any"]
+    #[doc = "responses were sent that cycle."]
+    pub end_run:
+        ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle) -> LV2_Worker_Status>,
+}
+#[doc = " Opaque handle for LV2_Worker_Schedule."]
+pub type LV2_Worker_Schedule_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Schedule Worker Host Feature."]
+#[doc = ""]
+#[doc = "The host passes this feature to provide a schedule_work() function, which"]
+#[doc = "the plugin can use to schedule a worker call from run()."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Worker_Schedule {
+    #[doc = "Opaque host data."]
+    pub handle: LV2_Worker_Schedule_Handle,
+    #[doc = "Request from run() that the host call the worker."]
+    #[doc = ""]
+    #[doc = "This function is in the audio threading class.  It should be called from"]
+    #[doc = "run() to request that the host call the work() method in a non-realtime"]
+    #[doc = "context with the given arguments."]
+    #[doc = ""]
+    #[doc = "This function is always safe to call from run(), but it is not"]
+    #[doc = "guaranteed that the worker is actually called from a different thread."]
+    #[doc = "In particular, when free-wheeling (for example, during offline"]
+    #[doc = "rendering), the worker may be executed immediately.  This allows"]
+    #[doc = "single-threaded processing with sample accuracy and avoids timing"]
+    #[doc = "problems when run() is executing much faster or slower than real-time."]
+    #[doc = ""]
+    #[doc = "Plugins SHOULD be written in such a way that if the worker runs"]
+    #[doc = "immediately, and responses from the worker are delivered immediately,"]
+    #[doc = "the effect of the work takes place immediately with sample accuracy."]
+    #[doc = ""]
+    #[doc = "The `data` MUST be safe for the host to copy and later pass to work(),"]
+    #[doc = "and the host MUST guarantee that it will be eventually passed to work()"]
+    #[doc = "if this function returns LV2_WORKER_SUCCESS."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = "@param size   The size of `data`."]
+    #[doc = "@param data   Message to pass to work(), or NULL."]
+    pub schedule_work: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_Worker_Schedule_Handle,
+            size: u32,
+            data: *const ::std::os::raw::c_void,
+        ) -> LV2_Worker_Status,
+    >,
+}
+pub type __builtin_va_list = [__va_list_tag; 1usize];
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct __va_list_tag {
+    pub gp_offset: ::std::os::raw::c_uint,
+    pub fp_offset: ::std::os::raw::c_uint,
+    pub overflow_arg_area: *mut ::std::os::raw::c_void,
+    pub reg_save_area: *mut ::std::os::raw::c_void,
+}
diff --git a/sys/src/unsupported.rs b/sys/src/unsupported.rs
new file mode 100644
index 00000000..e0a4d8fd
--- /dev/null
+++ b/sys/src/unsupported.rs
@@ -0,0 +1 @@
+compile_error!("The targeted operation system is not supported by rust-lv2!");
diff --git a/sys/src/windows.rs b/sys/src/windows.rs
new file mode 100644
index 00000000..0b76865a
--- /dev/null
+++ b/sys/src/windows.rs
@@ -0,0 +1,2716 @@
+/* automatically generated by rust-bindgen */
+
+pub const LV2_ATOM_URI: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/atom\0";
+pub const LV2_ATOM_PREFIX: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/atom#\0";
+pub const LV2_ATOM__Atom: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#Atom\0";
+pub const LV2_ATOM__AtomPort: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#AtomPort\0";
+pub const LV2_ATOM__Blank: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Blank\0";
+pub const LV2_ATOM__Bool: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#Bool\0";
+pub const LV2_ATOM__Chunk: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Chunk\0";
+pub const LV2_ATOM__Double: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#Double\0";
+pub const LV2_ATOM__Event: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Event\0";
+pub const LV2_ATOM__Float: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Float\0";
+pub const LV2_ATOM__Int: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/atom#Int\0";
+pub const LV2_ATOM__Literal: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/atom#Literal\0";
+pub const LV2_ATOM__Long: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#Long\0";
+pub const LV2_ATOM__Number: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#Number\0";
+pub const LV2_ATOM__Object: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#Object\0";
+pub const LV2_ATOM__Path: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#Path\0";
+pub const LV2_ATOM__Property: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#Property\0";
+pub const LV2_ATOM__Resource: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#Resource\0";
+pub const LV2_ATOM__Sequence: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#Sequence\0";
+pub const LV2_ATOM__Sound: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Sound\0";
+pub const LV2_ATOM__String: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#String\0";
+pub const LV2_ATOM__Tuple: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/atom#Tuple\0";
+pub const LV2_ATOM__URI: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/atom#URI\0";
+pub const LV2_ATOM__URID: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/atom#URID\0";
+pub const LV2_ATOM__Vector: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/atom#Vector\0";
+pub const LV2_ATOM__atomTransfer: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/atom#atomTransfer\0";
+pub const LV2_ATOM__beatTime: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#beatTime\0";
+pub const LV2_ATOM__bufferType: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/atom#bufferType\0";
+pub const LV2_ATOM__childType: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/atom#childType\0";
+pub const LV2_ATOM__eventTransfer: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/atom#eventTransfer\0";
+pub const LV2_ATOM__frameTime: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/atom#frameTime\0";
+pub const LV2_ATOM__supports: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#supports\0";
+pub const LV2_ATOM__timeUnit: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/atom#timeUnit\0";
+pub const LV2_ATOM_REFERENCE_TYPE: u32 = 0;
+pub const LV2_URID_URI: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/urid\0";
+pub const LV2_URID_PREFIX: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/urid#\0";
+pub const LV2_URID__map: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/urid#map\0";
+pub const LV2_URID__unmap: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/urid#unmap\0";
+pub const LV2_URID_MAP_URI: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/urid#map\0";
+pub const LV2_URID_UNMAP_URI: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/urid#unmap\0";
+pub const LV2_BUF_SIZE_URI: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/buf-size\0";
+pub const LV2_BUF_SIZE_PREFIX: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/buf-size#\0";
+pub const LV2_BUF_SIZE__boundedBlockLength: &'static [u8; 53usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#boundedBlockLength\0";
+pub const LV2_BUF_SIZE__fixedBlockLength: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#fixedBlockLength\0";
+pub const LV2_BUF_SIZE__maxBlockLength: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#maxBlockLength\0";
+pub const LV2_BUF_SIZE__minBlockLength: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#minBlockLength\0";
+pub const LV2_BUF_SIZE__nominalBlockLength: &'static [u8; 53usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#nominalBlockLength\0";
+pub const LV2_BUF_SIZE__powerOf2BlockLength: &'static [u8; 54usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#powerOf2BlockLength\0";
+pub const LV2_BUF_SIZE__sequenceSize: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/buf-size#sequenceSize\0";
+pub const LV2_CORE_URI: &'static [u8; 29usize] = b"http://lv2plug.in/ns/lv2core\0";
+pub const LV2_CORE_PREFIX: &'static [u8; 30usize] = b"http://lv2plug.in/ns/lv2core#\0";
+pub const LV2_CORE__AllpassPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#AllpassPlugin\0";
+pub const LV2_CORE__AmplifierPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#AmplifierPlugin\0";
+pub const LV2_CORE__AnalyserPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#AnalyserPlugin\0";
+pub const LV2_CORE__AudioPort: &'static [u8; 39usize] = b"http://lv2plug.in/ns/lv2core#AudioPort\0";
+pub const LV2_CORE__BandpassPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#BandpassPlugin\0";
+pub const LV2_CORE__CVPort: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#CVPort\0";
+pub const LV2_CORE__ChorusPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#ChorusPlugin\0";
+pub const LV2_CORE__CombPlugin: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#CombPlugin\0";
+pub const LV2_CORE__CompressorPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#CompressorPlugin\0";
+pub const LV2_CORE__ConstantPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#ConstantPlugin\0";
+pub const LV2_CORE__ControlPort: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#ControlPort\0";
+pub const LV2_CORE__ConverterPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#ConverterPlugin\0";
+pub const LV2_CORE__DelayPlugin: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#DelayPlugin\0";
+pub const LV2_CORE__DistortionPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#DistortionPlugin\0";
+pub const LV2_CORE__DynamicsPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#DynamicsPlugin\0";
+pub const LV2_CORE__EQPlugin: &'static [u8; 38usize] = b"http://lv2plug.in/ns/lv2core#EQPlugin\0";
+pub const LV2_CORE__EnvelopePlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#EnvelopePlugin\0";
+pub const LV2_CORE__ExpanderPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#ExpanderPlugin\0";
+pub const LV2_CORE__ExtensionData: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#ExtensionData\0";
+pub const LV2_CORE__Feature: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#Feature\0";
+pub const LV2_CORE__FilterPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#FilterPlugin\0";
+pub const LV2_CORE__FlangerPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#FlangerPlugin\0";
+pub const LV2_CORE__FunctionPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#FunctionPlugin\0";
+pub const LV2_CORE__GatePlugin: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#GatePlugin\0";
+pub const LV2_CORE__GeneratorPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#GeneratorPlugin\0";
+pub const LV2_CORE__HighpassPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#HighpassPlugin\0";
+pub const LV2_CORE__InputPort: &'static [u8; 39usize] = b"http://lv2plug.in/ns/lv2core#InputPort\0";
+pub const LV2_CORE__InstrumentPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#InstrumentPlugin\0";
+pub const LV2_CORE__LimiterPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#LimiterPlugin\0";
+pub const LV2_CORE__LowpassPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#LowpassPlugin\0";
+pub const LV2_CORE__MixerPlugin: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#MixerPlugin\0";
+pub const LV2_CORE__ModulatorPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#ModulatorPlugin\0";
+pub const LV2_CORE__MultiEQPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#MultiEQPlugin\0";
+pub const LV2_CORE__OscillatorPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#OscillatorPlugin\0";
+pub const LV2_CORE__OutputPort: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#OutputPort\0";
+pub const LV2_CORE__ParaEQPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#ParaEQPlugin\0";
+pub const LV2_CORE__PhaserPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#PhaserPlugin\0";
+pub const LV2_CORE__PitchPlugin: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#PitchPlugin\0";
+pub const LV2_CORE__Plugin: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#Plugin\0";
+pub const LV2_CORE__PluginBase: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#PluginBase\0";
+pub const LV2_CORE__Point: &'static [u8; 35usize] = b"http://lv2plug.in/ns/lv2core#Point\0";
+pub const LV2_CORE__Port: &'static [u8; 34usize] = b"http://lv2plug.in/ns/lv2core#Port\0";
+pub const LV2_CORE__PortProperty: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#PortProperty\0";
+pub const LV2_CORE__Resource: &'static [u8; 38usize] = b"http://lv2plug.in/ns/lv2core#Resource\0";
+pub const LV2_CORE__ReverbPlugin: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#ReverbPlugin\0";
+pub const LV2_CORE__ScalePoint: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#ScalePoint\0";
+pub const LV2_CORE__SimulatorPlugin: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#SimulatorPlugin\0";
+pub const LV2_CORE__SpatialPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#SpatialPlugin\0";
+pub const LV2_CORE__Specification: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#Specification\0";
+pub const LV2_CORE__SpectralPlugin: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#SpectralPlugin\0";
+pub const LV2_CORE__UtilityPlugin: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#UtilityPlugin\0";
+pub const LV2_CORE__WaveshaperPlugin: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/lv2core#WaveshaperPlugin\0";
+pub const LV2_CORE__appliesTo: &'static [u8; 39usize] = b"http://lv2plug.in/ns/lv2core#appliesTo\0";
+pub const LV2_CORE__binary: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#binary\0";
+pub const LV2_CORE__connectionOptional: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/lv2core#connectionOptional\0";
+pub const LV2_CORE__control: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#control\0";
+pub const LV2_CORE__default: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#default\0";
+pub const LV2_CORE__designation: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#designation\0";
+pub const LV2_CORE__documentation: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#documentation\0";
+pub const LV2_CORE__enumeration: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/lv2core#enumeration\0";
+pub const LV2_CORE__extensionData: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#extensionData\0";
+pub const LV2_CORE__freeWheeling: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#freeWheeling\0";
+pub const LV2_CORE__hardRTCapable: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#hardRTCapable\0";
+pub const LV2_CORE__inPlaceBroken: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/lv2core#inPlaceBroken\0";
+pub const LV2_CORE__index: &'static [u8; 35usize] = b"http://lv2plug.in/ns/lv2core#index\0";
+pub const LV2_CORE__integer: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#integer\0";
+pub const LV2_CORE__isLive: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#isLive\0";
+pub const LV2_CORE__latency: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#latency\0";
+pub const LV2_CORE__maximum: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#maximum\0";
+pub const LV2_CORE__microVersion: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#microVersion\0";
+pub const LV2_CORE__minimum: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#minimum\0";
+pub const LV2_CORE__minorVersion: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#minorVersion\0";
+pub const LV2_CORE__name: &'static [u8; 34usize] = b"http://lv2plug.in/ns/lv2core#name\0";
+pub const LV2_CORE__optionalFeature: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#optionalFeature\0";
+pub const LV2_CORE__port: &'static [u8; 34usize] = b"http://lv2plug.in/ns/lv2core#port\0";
+pub const LV2_CORE__portProperty: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/lv2core#portProperty\0";
+pub const LV2_CORE__project: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#project\0";
+pub const LV2_CORE__prototype: &'static [u8; 39usize] = b"http://lv2plug.in/ns/lv2core#prototype\0";
+pub const LV2_CORE__reportsLatency: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/lv2core#reportsLatency\0";
+pub const LV2_CORE__requiredFeature: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/lv2core#requiredFeature\0";
+pub const LV2_CORE__sampleRate: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#sampleRate\0";
+pub const LV2_CORE__scalePoint: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/lv2core#scalePoint\0";
+pub const LV2_CORE__symbol: &'static [u8; 36usize] = b"http://lv2plug.in/ns/lv2core#symbol\0";
+pub const LV2_CORE__toggled: &'static [u8; 37usize] = b"http://lv2plug.in/ns/lv2core#toggled\0";
+pub const LV2_DATA_ACCESS_URI: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/data-access\0";
+pub const LV2_DATA_ACCESS_PREFIX: &'static [u8; 38usize] =
+    b"http://lv2plug.in/ns/ext/data-access#\0";
+pub const LV2_DYN_MANIFEST_URI: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/dynmanifest\0";
+pub const LV2_DYN_MANIFEST_PREFIX: &'static [u8; 38usize] =
+    b"http://lv2plug.in/ns/ext/dynmanifest#\0";
+pub const LV2_EVENT_URI: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/event\0";
+pub const LV2_EVENT_PREFIX: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/event#\0";
+pub const LV2_EVENT__Event: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/event#Event\0";
+pub const LV2_EVENT__EventPort: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/event#EventPort\0";
+pub const LV2_EVENT__FrameStamp: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/event#FrameStamp\0";
+pub const LV2_EVENT__TimeStamp: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/event#TimeStamp\0";
+pub const LV2_EVENT__generatesTimeStamp: &'static [u8; 50usize] =
+    b"http://lv2plug.in/ns/ext/event#generatesTimeStamp\0";
+pub const LV2_EVENT__generic: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/event#generic\0";
+pub const LV2_EVENT__inheritsEvent: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/event#inheritsEvent\0";
+pub const LV2_EVENT__inheritsTimeStamp: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/event#inheritsTimeStamp\0";
+pub const LV2_EVENT__supportsEvent: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/event#supportsEvent\0";
+pub const LV2_EVENT__supportsTimeStamp: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/event#supportsTimeStamp\0";
+pub const LV2_EVENT_AUDIO_STAMP: u32 = 0;
+pub const LV2_INSTANCE_ACCESS_URI: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/instance-access\0";
+pub const LV2_LOG_URI: &'static [u8; 29usize] = b"http://lv2plug.in/ns/ext/log\0";
+pub const LV2_LOG_PREFIX: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/log#\0";
+pub const LV2_LOG__Entry: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/log#Entry\0";
+pub const LV2_LOG__Error: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/log#Error\0";
+pub const LV2_LOG__Note: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/log#Note\0";
+pub const LV2_LOG__Trace: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/log#Trace\0";
+pub const LV2_LOG__Warning: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/log#Warning\0";
+pub const LV2_LOG__log: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/log#log\0";
+pub const LV2_MIDI_URI: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/midi\0";
+pub const LV2_MIDI_PREFIX: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/midi#\0";
+pub const LV2_MIDI__ActiveSense: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/midi#ActiveSense\0";
+pub const LV2_MIDI__Aftertouch: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#Aftertouch\0";
+pub const LV2_MIDI__Bender: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/midi#Bender\0";
+pub const LV2_MIDI__ChannelPressure: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/midi#ChannelPressure\0";
+pub const LV2_MIDI__Chunk: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#Chunk\0";
+pub const LV2_MIDI__Clock: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#Clock\0";
+pub const LV2_MIDI__Continue: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/midi#Continue\0";
+pub const LV2_MIDI__Controller: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#Controller\0";
+pub const LV2_MIDI__MidiEvent: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/midi#MidiEvent\0";
+pub const LV2_MIDI__NoteOff: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/midi#NoteOff\0";
+pub const LV2_MIDI__NoteOn: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/midi#NoteOn\0";
+pub const LV2_MIDI__ProgramChange: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/midi#ProgramChange\0";
+pub const LV2_MIDI__QuarterFrame: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#QuarterFrame\0";
+pub const LV2_MIDI__Reset: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#Reset\0";
+pub const LV2_MIDI__SongPosition: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#SongPosition\0";
+pub const LV2_MIDI__SongSelect: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#SongSelect\0";
+pub const LV2_MIDI__Start: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#Start\0";
+pub const LV2_MIDI__Stop: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/midi#Stop\0";
+pub const LV2_MIDI__SystemCommon: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#SystemCommon\0";
+pub const LV2_MIDI__SystemExclusive: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/midi#SystemExclusive\0";
+pub const LV2_MIDI__SystemMessage: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/midi#SystemMessage\0";
+pub const LV2_MIDI__SystemRealtime: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/midi#SystemRealtime\0";
+pub const LV2_MIDI__Tick: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/midi#Tick\0";
+pub const LV2_MIDI__TuneRequest: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/midi#TuneRequest\0";
+pub const LV2_MIDI__VoiceMessage: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#VoiceMessage\0";
+pub const LV2_MIDI__benderValue: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/midi#benderValue\0";
+pub const LV2_MIDI__binding: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/midi#binding\0";
+pub const LV2_MIDI__byteNumber: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#byteNumber\0";
+pub const LV2_MIDI__channel: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/midi#channel\0";
+pub const LV2_MIDI__chunk: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/midi#chunk\0";
+pub const LV2_MIDI__controllerNumber: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/midi#controllerNumber\0";
+pub const LV2_MIDI__controllerValue: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/midi#controllerValue\0";
+pub const LV2_MIDI__noteNumber: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#noteNumber\0";
+pub const LV2_MIDI__pressure: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/midi#pressure\0";
+pub const LV2_MIDI__programNumber: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/midi#programNumber\0";
+pub const LV2_MIDI__property: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/midi#property\0";
+pub const LV2_MIDI__songNumber: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#songNumber\0";
+pub const LV2_MIDI__songPosition: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/midi#songPosition\0";
+pub const LV2_MIDI__status: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/midi#status\0";
+pub const LV2_MIDI__statusMask: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/midi#statusMask\0";
+pub const LV2_MIDI__velocity: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/midi#velocity\0";
+pub const LV2_MORPH_URI: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/morph\0";
+pub const LV2_MORPH_PREFIX: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/morph#\0";
+pub const LV2_MORPH__AutoMorphPort: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/morph#AutoMorphPort\0";
+pub const LV2_MORPH__MorphPort: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/morph#MorphPort\0";
+pub const LV2_MORPH__interface: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/morph#interface\0";
+pub const LV2_MORPH__supportsType: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/morph#supportsType\0";
+pub const LV2_MORPH__currentType: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/morph#currentType\0";
+pub const LV2_OPTIONS_URI: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/options\0";
+pub const LV2_OPTIONS_PREFIX: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/options#\0";
+pub const LV2_OPTIONS__Option: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/options#Option\0";
+pub const LV2_OPTIONS__interface: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/options#interface\0";
+pub const LV2_OPTIONS__options: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/options#options\0";
+pub const LV2_OPTIONS__requiredOption: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/options#requiredOption\0";
+pub const LV2_OPTIONS__supportedOption: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/options#supportedOption\0";
+pub const LV2_PARAMETERS_URI: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/parameters\0";
+pub const LV2_PARAMETERS_PREFIX: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/parameters#\0";
+pub const LV2_PARAMETERS__CompressorControls: &'static [u8; 55usize] =
+    b"http://lv2plug.in/ns/ext/parameters#CompressorControls\0";
+pub const LV2_PARAMETERS__ControlGroup: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/parameters#ControlGroup\0";
+pub const LV2_PARAMETERS__EnvelopeControls: &'static [u8; 53usize] =
+    b"http://lv2plug.in/ns/ext/parameters#EnvelopeControls\0";
+pub const LV2_PARAMETERS__FilterControls: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/ext/parameters#FilterControls\0";
+pub const LV2_PARAMETERS__OscillatorControls: &'static [u8; 55usize] =
+    b"http://lv2plug.in/ns/ext/parameters#OscillatorControls\0";
+pub const LV2_PARAMETERS__amplitude: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/parameters#amplitude\0";
+pub const LV2_PARAMETERS__attack: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/parameters#attack\0";
+pub const LV2_PARAMETERS__bypass: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/parameters#bypass\0";
+pub const LV2_PARAMETERS__cutoffFrequency: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/ext/parameters#cutoffFrequency\0";
+pub const LV2_PARAMETERS__decay: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/parameters#decay\0";
+pub const LV2_PARAMETERS__delay: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/parameters#delay\0";
+pub const LV2_PARAMETERS__dryLevel: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/parameters#dryLevel\0";
+pub const LV2_PARAMETERS__frequency: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/parameters#frequency\0";
+pub const LV2_PARAMETERS__gain: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/parameters#gain\0";
+pub const LV2_PARAMETERS__hold: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/parameters#hold\0";
+pub const LV2_PARAMETERS__pulseWidth: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/parameters#pulseWidth\0";
+pub const LV2_PARAMETERS__ratio: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/parameters#ratio\0";
+pub const LV2_PARAMETERS__release: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/parameters#release\0";
+pub const LV2_PARAMETERS__resonance: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/parameters#resonance\0";
+pub const LV2_PARAMETERS__sampleRate: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/parameters#sampleRate\0";
+pub const LV2_PARAMETERS__sustain: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/parameters#sustain\0";
+pub const LV2_PARAMETERS__threshold: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/parameters#threshold\0";
+pub const LV2_PARAMETERS__waveform: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/parameters#waveform\0";
+pub const LV2_PARAMETERS__wetDryRatio: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/parameters#wetDryRatio\0";
+pub const LV2_PARAMETERS__wetLevel: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/parameters#wetLevel\0";
+pub const LV2_PATCH_URI: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/patch\0";
+pub const LV2_PATCH_PREFIX: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/patch#\0";
+pub const LV2_PATCH__Ack: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#Ack\0";
+pub const LV2_PATCH__Delete: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/patch#Delete\0";
+pub const LV2_PATCH__Copy: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/patch#Copy\0";
+pub const LV2_PATCH__Error: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/patch#Error\0";
+pub const LV2_PATCH__Get: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#Get\0";
+pub const LV2_PATCH__Message: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#Message\0";
+pub const LV2_PATCH__Move: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/patch#Move\0";
+pub const LV2_PATCH__Patch: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/patch#Patch\0";
+pub const LV2_PATCH__Post: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/patch#Post\0";
+pub const LV2_PATCH__Put: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#Put\0";
+pub const LV2_PATCH__Request: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#Request\0";
+pub const LV2_PATCH__Response: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#Response\0";
+pub const LV2_PATCH__Set: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#Set\0";
+pub const LV2_PATCH__accept: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/patch#accept\0";
+pub const LV2_PATCH__add: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/patch#add\0";
+pub const LV2_PATCH__body: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/patch#body\0";
+pub const LV2_PATCH__context: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#context\0";
+pub const LV2_PATCH__destination: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/patch#destination\0";
+pub const LV2_PATCH__property: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#property\0";
+pub const LV2_PATCH__readable: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#readable\0";
+pub const LV2_PATCH__remove: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/patch#remove\0";
+pub const LV2_PATCH__request: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#request\0";
+pub const LV2_PATCH__subject: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/patch#subject\0";
+pub const LV2_PATCH__sequenceNumber: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/patch#sequenceNumber\0";
+pub const LV2_PATCH__value: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/patch#value\0";
+pub const LV2_PATCH__wildcard: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#wildcard\0";
+pub const LV2_PATCH__writable: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/patch#writable\0";
+pub const LV2_PORT_GROUPS_URI: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/port-groups\0";
+pub const LV2_PORT_GROUPS_PREFIX: &'static [u8; 38usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#\0";
+pub const LV2_PORT_GROUPS__DiscreteGroup: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#DiscreteGroup\0";
+pub const LV2_PORT_GROUPS__Element: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#Element\0";
+pub const LV2_PORT_GROUPS__FivePointOneGroup: &'static [u8; 55usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#FivePointOneGroup\0";
+pub const LV2_PORT_GROUPS__FivePointZeroGroup: &'static [u8; 56usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#FivePointZeroGroup\0";
+pub const LV2_PORT_GROUPS__FourPointZeroGroup: &'static [u8; 56usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#FourPointZeroGroup\0";
+pub const LV2_PORT_GROUPS__Group: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#Group\0";
+pub const LV2_PORT_GROUPS__InputGroup: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#InputGroup\0";
+pub const LV2_PORT_GROUPS__MidSideGroup: &'static [u8; 50usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#MidSideGroup\0";
+pub const LV2_PORT_GROUPS__MonoGroup: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#MonoGroup\0";
+pub const LV2_PORT_GROUPS__OutputGroup: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#OutputGroup\0";
+pub const LV2_PORT_GROUPS__SevenPointOneGroup: &'static [u8; 56usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#SevenPointOneGroup\0";
+pub const LV2_PORT_GROUPS__SevenPointOneWideGroup: &'static [u8; 60usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#SevenPointOneWideGroup\0";
+pub const LV2_PORT_GROUPS__SixPointOneGroup: &'static [u8; 54usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#SixPointOneGroup\0";
+pub const LV2_PORT_GROUPS__StereoGroup: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#StereoGroup\0";
+pub const LV2_PORT_GROUPS__ThreePointZeroGroup: &'static [u8; 57usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#ThreePointZeroGroup\0";
+pub const LV2_PORT_GROUPS__center: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#center\0";
+pub const LV2_PORT_GROUPS__centerLeft: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#centerLeft\0";
+pub const LV2_PORT_GROUPS__centerRight: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#centerRight\0";
+pub const LV2_PORT_GROUPS__element: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#element\0";
+pub const LV2_PORT_GROUPS__group: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#group\0";
+pub const LV2_PORT_GROUPS__left: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#left\0";
+pub const LV2_PORT_GROUPS__lowFrequencyEffects: &'static [u8; 57usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#lowFrequencyEffects\0";
+pub const LV2_PORT_GROUPS__mainInput: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#mainInput\0";
+pub const LV2_PORT_GROUPS__mainOutput: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#mainOutput\0";
+pub const LV2_PORT_GROUPS__rearCenter: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#rearCenter\0";
+pub const LV2_PORT_GROUPS__rearLeft: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#rearLeft\0";
+pub const LV2_PORT_GROUPS__rearRight: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#rearRight\0";
+pub const LV2_PORT_GROUPS__right: &'static [u8; 43usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#right\0";
+pub const LV2_PORT_GROUPS__side: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#side\0";
+pub const LV2_PORT_GROUPS__sideChainOf: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#sideChainOf\0";
+pub const LV2_PORT_GROUPS__sideLeft: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#sideLeft\0";
+pub const LV2_PORT_GROUPS__sideRight: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#sideRight\0";
+pub const LV2_PORT_GROUPS__source: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#source\0";
+pub const LV2_PORT_GROUPS__subGroupOf: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-groups#subGroupOf\0";
+pub const LV2_PORT_PROPS_URI: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/port-props\0";
+pub const LV2_PORT_PROPS_PREFIX: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/port-props#\0";
+pub const LV2_PORT_PROPS__causesArtifacts: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/ext/port-props#causesArtifacts\0";
+pub const LV2_PORT_PROPS__continuousCV: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-props#continuousCV\0";
+pub const LV2_PORT_PROPS__discreteCV: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-props#discreteCV\0";
+pub const LV2_PORT_PROPS__displayPriority: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/ext/port-props#displayPriority\0";
+pub const LV2_PORT_PROPS__expensive: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/port-props#expensive\0";
+pub const LV2_PORT_PROPS__hasStrictBounds: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/ext/port-props#hasStrictBounds\0";
+pub const LV2_PORT_PROPS__logarithmic: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/port-props#logarithmic\0";
+pub const LV2_PORT_PROPS__notAutomatic: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/port-props#notAutomatic\0";
+pub const LV2_PORT_PROPS__notOnGUI: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/port-props#notOnGUI\0";
+pub const LV2_PORT_PROPS__rangeSteps: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/port-props#rangeSteps\0";
+pub const LV2_PORT_PROPS__supportsStrictBounds: &'static [u8; 57usize] =
+    b"http://lv2plug.in/ns/ext/port-props#supportsStrictBounds\0";
+pub const LV2_PORT_PROPS__trigger: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/port-props#trigger\0";
+pub const LV2_PRESETS_URI: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/presets\0";
+pub const LV2_PRESETS_PREFIX: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/presets#\0";
+pub const LV2_PRESETS__Bank: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/presets#Bank\0";
+pub const LV2_PRESETS__Preset: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/presets#Preset\0";
+pub const LV2_PRESETS__bank: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/presets#bank\0";
+pub const LV2_PRESETS__preset: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/presets#preset\0";
+pub const LV2_PRESETS__value: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/presets#value\0";
+pub const LV2_RESIZE_PORT_URI: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/resize-port\0";
+pub const LV2_RESIZE_PORT_PREFIX: &'static [u8; 38usize] =
+    b"http://lv2plug.in/ns/ext/resize-port#\0";
+pub const LV2_RESIZE_PORT__asLargeAs: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/ext/resize-port#asLargeAs\0";
+pub const LV2_RESIZE_PORT__minimumSize: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/resize-port#minimumSize\0";
+pub const LV2_RESIZE_PORT__resize: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/resize-port#resize\0";
+pub const LV2_STATE_URI: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/state\0";
+pub const LV2_STATE_PREFIX: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/state#\0";
+pub const LV2_STATE__State: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/state#State\0";
+pub const LV2_STATE__interface: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/state#interface\0";
+pub const LV2_STATE__loadDefaultState: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/ext/state#loadDefaultState\0";
+pub const LV2_STATE__freePath: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/state#freePath\0";
+pub const LV2_STATE__makePath: &'static [u8; 40usize] =
+    b"http://lv2plug.in/ns/ext/state#makePath\0";
+pub const LV2_STATE__mapPath: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/state#mapPath\0";
+pub const LV2_STATE__state: &'static [u8; 37usize] = b"http://lv2plug.in/ns/ext/state#state\0";
+pub const LV2_STATE__threadSafeRestore: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/ext/state#threadSafeRestore\0";
+pub const LV2_STATE__StateChanged: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/ext/state#StateChanged\0";
+pub const LV2_TIME_URI: &'static [u8; 30usize] = b"http://lv2plug.in/ns/ext/time\0";
+pub const LV2_TIME_PREFIX: &'static [u8; 31usize] = b"http://lv2plug.in/ns/ext/time#\0";
+pub const LV2_TIME__Time: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/time#Time\0";
+pub const LV2_TIME__Position: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/time#Position\0";
+pub const LV2_TIME__Rate: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/time#Rate\0";
+pub const LV2_TIME__position: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/time#position\0";
+pub const LV2_TIME__barBeat: &'static [u8; 38usize] = b"http://lv2plug.in/ns/ext/time#barBeat\0";
+pub const LV2_TIME__bar: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/time#bar\0";
+pub const LV2_TIME__beat: &'static [u8; 35usize] = b"http://lv2plug.in/ns/ext/time#beat\0";
+pub const LV2_TIME__beatUnit: &'static [u8; 39usize] = b"http://lv2plug.in/ns/ext/time#beatUnit\0";
+pub const LV2_TIME__beatsPerBar: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/time#beatsPerBar\0";
+pub const LV2_TIME__beatsPerMinute: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/ext/time#beatsPerMinute\0";
+pub const LV2_TIME__frame: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/time#frame\0";
+pub const LV2_TIME__framesPerSecond: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/ext/time#framesPerSecond\0";
+pub const LV2_TIME__speed: &'static [u8; 36usize] = b"http://lv2plug.in/ns/ext/time#speed\0";
+pub const LV2_UI_URI: &'static [u8; 35usize] = b"http://lv2plug.in/ns/extensions/ui\0";
+pub const LV2_UI_PREFIX: &'static [u8; 36usize] = b"http://lv2plug.in/ns/extensions/ui#\0";
+pub const LV2_UI__CocoaUI: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/ui#CocoaUI\0";
+pub const LV2_UI__Gtk3UI: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#Gtk3UI\0";
+pub const LV2_UI__GtkUI: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#GtkUI\0";
+pub const LV2_UI__PortNotification: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/extensions/ui#PortNotification\0";
+pub const LV2_UI__PortProtocol: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/extensions/ui#PortProtocol\0";
+pub const LV2_UI__Qt4UI: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#Qt4UI\0";
+pub const LV2_UI__Qt5UI: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#Qt5UI\0";
+pub const LV2_UI__UI: &'static [u8; 38usize] = b"http://lv2plug.in/ns/extensions/ui#UI\0";
+pub const LV2_UI__WindowsUI: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/ui#WindowsUI\0";
+pub const LV2_UI__X11UI: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#X11UI\0";
+pub const LV2_UI__binary: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#binary\0";
+pub const LV2_UI__fixedSize: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/ui#fixedSize\0";
+pub const LV2_UI__idleInterface: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/ui#idleInterface\0";
+pub const LV2_UI__noUserResize: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/extensions/ui#noUserResize\0";
+pub const LV2_UI__notifyType: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/extensions/ui#notifyType\0";
+pub const LV2_UI__parent: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#parent\0";
+pub const LV2_UI__plugin: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#plugin\0";
+pub const LV2_UI__portIndex: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/ui#portIndex\0";
+pub const LV2_UI__portMap: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/ui#portMap\0";
+pub const LV2_UI__portNotification: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/extensions/ui#portNotification\0";
+pub const LV2_UI__portSubscribe: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/ui#portSubscribe\0";
+pub const LV2_UI__protocol: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/extensions/ui#protocol\0";
+pub const LV2_UI__requestValue: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/extensions/ui#requestValue\0";
+pub const LV2_UI__floatProtocol: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/ui#floatProtocol\0";
+pub const LV2_UI__peakProtocol: &'static [u8; 48usize] =
+    b"http://lv2plug.in/ns/extensions/ui#peakProtocol\0";
+pub const LV2_UI__resize: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/ui#resize\0";
+pub const LV2_UI__showInterface: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/ui#showInterface\0";
+pub const LV2_UI__touch: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/ui#touch\0";
+pub const LV2_UI__ui: &'static [u8; 38usize] = b"http://lv2plug.in/ns/extensions/ui#ui\0";
+pub const LV2_UI__updateRate: &'static [u8; 46usize] =
+    b"http://lv2plug.in/ns/extensions/ui#updateRate\0";
+pub const LV2_UI__windowTitle: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/extensions/ui#windowTitle\0";
+pub const LV2_UI__scaleFactor: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/extensions/ui#scaleFactor\0";
+pub const LV2_UI__foregroundColor: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/extensions/ui#foregroundColor\0";
+pub const LV2_UI__backgroundColor: &'static [u8; 51usize] =
+    b"http://lv2plug.in/ns/extensions/ui#backgroundColor\0";
+pub const LV2_UNITS_URI: &'static [u8; 38usize] = b"http://lv2plug.in/ns/extensions/units\0";
+pub const LV2_UNITS_PREFIX: &'static [u8; 39usize] = b"http://lv2plug.in/ns/extensions/units#\0";
+pub const LV2_UNITS__Conversion: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/units#Conversion\0";
+pub const LV2_UNITS__Unit: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#Unit\0";
+pub const LV2_UNITS__bar: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#bar\0";
+pub const LV2_UNITS__beat: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#beat\0";
+pub const LV2_UNITS__bpm: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#bpm\0";
+pub const LV2_UNITS__cent: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#cent\0";
+pub const LV2_UNITS__cm: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#cm\0";
+pub const LV2_UNITS__coef: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#coef\0";
+pub const LV2_UNITS__conversion: &'static [u8; 49usize] =
+    b"http://lv2plug.in/ns/extensions/units#conversion\0";
+pub const LV2_UNITS__db: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#db\0";
+pub const LV2_UNITS__degree: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/units#degree\0";
+pub const LV2_UNITS__frame: &'static [u8; 44usize] =
+    b"http://lv2plug.in/ns/extensions/units#frame\0";
+pub const LV2_UNITS__hz: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#hz\0";
+pub const LV2_UNITS__inch: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#inch\0";
+pub const LV2_UNITS__khz: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#khz\0";
+pub const LV2_UNITS__km: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#km\0";
+pub const LV2_UNITS__m: &'static [u8; 40usize] = b"http://lv2plug.in/ns/extensions/units#m\0";
+pub const LV2_UNITS__mhz: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#mhz\0";
+pub const LV2_UNITS__midiNote: &'static [u8; 47usize] =
+    b"http://lv2plug.in/ns/extensions/units#midiNote\0";
+pub const LV2_UNITS__mile: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#mile\0";
+pub const LV2_UNITS__min: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#min\0";
+pub const LV2_UNITS__mm: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#mm\0";
+pub const LV2_UNITS__ms: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#ms\0";
+pub const LV2_UNITS__name: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#name\0";
+pub const LV2_UNITS__oct: &'static [u8; 42usize] = b"http://lv2plug.in/ns/extensions/units#oct\0";
+pub const LV2_UNITS__pc: &'static [u8; 41usize] = b"http://lv2plug.in/ns/extensions/units#pc\0";
+pub const LV2_UNITS__prefixConversion: &'static [u8; 55usize] =
+    b"http://lv2plug.in/ns/extensions/units#prefixConversion\0";
+pub const LV2_UNITS__render: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/units#render\0";
+pub const LV2_UNITS__s: &'static [u8; 40usize] = b"http://lv2plug.in/ns/extensions/units#s\0";
+pub const LV2_UNITS__semitone12TET: &'static [u8; 52usize] =
+    b"http://lv2plug.in/ns/extensions/units#semitone12TET\0";
+pub const LV2_UNITS__symbol: &'static [u8; 45usize] =
+    b"http://lv2plug.in/ns/extensions/units#symbol\0";
+pub const LV2_UNITS__unit: &'static [u8; 43usize] = b"http://lv2plug.in/ns/extensions/units#unit\0";
+pub const LV2_URI_MAP_URI: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/uri-map\0";
+pub const LV2_URI_MAP_PREFIX: &'static [u8; 34usize] = b"http://lv2plug.in/ns/ext/uri-map#\0";
+pub const LV2_WORKER_URI: &'static [u8; 32usize] = b"http://lv2plug.in/ns/ext/worker\0";
+pub const LV2_WORKER_PREFIX: &'static [u8; 33usize] = b"http://lv2plug.in/ns/ext/worker#\0";
+pub const LV2_WORKER__interface: &'static [u8; 42usize] =
+    b"http://lv2plug.in/ns/ext/worker#interface\0";
+pub const LV2_WORKER__schedule: &'static [u8; 41usize] =
+    b"http://lv2plug.in/ns/ext/worker#schedule\0";
+pub type va_list = *mut ::std::os::raw::c_char;
+#[doc = " The header of an atom:Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom {
+    #[doc = "< Size in bytes, not including type and size."]
+    pub size: u32,
+    #[doc = "< Type of this atom (mapped URI)."]
+    pub type_: u32,
+}
+#[doc = " An atom:Int or atom:Bool.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Int {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Integer value."]
+    pub body: i32,
+}
+#[doc = " An atom:Long.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Long {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Integer value."]
+    pub body: i64,
+}
+#[doc = " An atom:Float.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Float {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Floating point value."]
+    pub body: f32,
+}
+#[doc = " An atom:Double.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Double {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Floating point value."]
+    pub body: f64,
+}
+#[doc = " An atom:Bool.  May be cast to LV2_Atom."]
+pub type LV2_Atom_Bool = LV2_Atom_Int;
+#[doc = " An atom:URID.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_URID {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< URID."]
+    pub body: u32,
+}
+#[doc = " An atom:String.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_String {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+}
+#[doc = " The body of an atom:Literal."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Literal_Body {
+    #[doc = "< Datatype URID."]
+    pub datatype: u32,
+    #[doc = "< Language URID."]
+    pub lang: u32,
+}
+#[doc = " An atom:Literal.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Literal {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Literal_Body,
+}
+#[doc = " An atom:Tuple.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Tuple {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+}
+#[doc = " The body of an atom:Vector."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Vector_Body {
+    #[doc = "< The size of each element in the vector."]
+    pub child_size: u32,
+    #[doc = "< The type of each element in the vector."]
+    pub child_type: u32,
+}
+#[doc = " An atom:Vector.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Vector {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Vector_Body,
+}
+#[doc = " The body of an atom:Property (typically in an atom:Object)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Property_Body {
+    #[doc = "< Key (predicate) (mapped URI)."]
+    pub key: u32,
+    #[doc = "< Context URID (may be, and generally is, 0)."]
+    pub context: u32,
+    #[doc = "< Value atom header."]
+    pub value: LV2_Atom,
+}
+#[doc = " An atom:Property.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Property {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Property_Body,
+}
+#[doc = " The body of an atom:Object. May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Object_Body {
+    #[doc = "< URID, or 0 for blank."]
+    pub id: u32,
+    #[doc = "< Type URID (same as rdf:type, for fast dispatch)."]
+    pub otype: u32,
+}
+#[doc = " An atom:Object.  May be cast to LV2_Atom."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Object {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Object_Body,
+}
+#[doc = " The header of an atom:Event.  Note this type is NOT an LV2_Atom."]
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct LV2_Atom_Event {
+    pub time: LV2_Atom_Event__bindgen_ty_1,
+    #[doc = "< Event body atom header."]
+    pub body: LV2_Atom,
+}
+#[doc = " Time stamp.  Which type is valid is determined by context."]
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union LV2_Atom_Event__bindgen_ty_1 {
+    #[doc = "< Time in audio frames."]
+    pub frames: i64,
+    #[doc = "< Time in beats."]
+    pub beats: f64,
+    _bindgen_union_align: u64,
+}
+#[doc = "The body of an atom:Sequence (a sequence of events)."]
+#[doc = ""]
+#[doc = "The unit field is either a URID that described an appropriate time stamp"]
+#[doc = "type, or may be 0 where a default stamp type is known.  For"]
+#[doc = "LV2_Descriptor::run(), the default stamp type is audio frames."]
+#[doc = ""]
+#[doc = "The contents of a sequence is a series of LV2_Atom_Event, each aligned"]
+#[doc = "to 64-bits, for example:"]
+#[doc = "<pre>"]
+#[doc = "| Event 1 (size 6)                              | Event 2"]
+#[doc = "|       |       |       |       |       |       |       |       |"]
+#[doc = "| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |"]
+#[doc = "|FRAMES |SUBFRMS|TYPE   |SIZE   |DATADATADATAPAD|FRAMES |SUBFRMS|..."]
+#[doc = "</pre>"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Sequence_Body {
+    #[doc = "< URID of unit of event time stamps."]
+    pub unit: u32,
+    #[doc = "< Currently unused."]
+    pub pad: u32,
+}
+#[doc = " An atom:Sequence."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Sequence {
+    #[doc = "< Atom header."]
+    pub atom: LV2_Atom,
+    #[doc = "< Body."]
+    pub body: LV2_Atom_Sequence_Body,
+}
+#[doc = " A single entry in an Object query."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Object_Query {
+    #[doc = "< Key to query (input set by user)"]
+    pub key: u32,
+    #[doc = "< Found value (output set by query function)"]
+    pub value: *mut *const LV2_Atom,
+}
+extern "C" {
+    pub static LV2_ATOM_OBJECT_QUERY_END: LV2_Atom_Object_Query;
+}
+#[doc = "Opaque pointer to host data for LV2_URID_Map."]
+pub type LV2_URID_Map_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Opaque pointer to host data for LV2_URID_Unmap."]
+pub type LV2_URID_Unmap_Handle = *mut ::std::os::raw::c_void;
+#[doc = "URI mapped to an integer."]
+pub type LV2_URID = u32;
+#[doc = "URID Map Feature (LV2_URID__map)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_URID_Map {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "This MUST be passed to map_uri() whenever it is called."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub handle: LV2_URID_Map_Handle,
+    #[doc = "Get the numeric ID of a URI."]
+    #[doc = ""]
+    #[doc = "If the ID does not already exist, it will be created."]
+    #[doc = ""]
+    #[doc = "This function is referentially transparent; any number of calls with the"]
+    #[doc = "same arguments is guaranteed to return the same value over the life of a"]
+    #[doc = "plugin instance.  Note, however, that several URIs MAY resolve to the"]
+    #[doc = "same ID if the host considers those URIs equivalent."]
+    #[doc = ""]
+    #[doc = "This function is not necessarily very fast or RT-safe: plugins SHOULD"]
+    #[doc = "cache any IDs they might need in performance critical situations."]
+    #[doc = ""]
+    #[doc = "The return value 0 is reserved and indicates that an ID for that URI"]
+    #[doc = "could not be created for whatever reason.  However, hosts SHOULD NOT"]
+    #[doc = "return 0 from this function in non-exceptional circumstances (i.e. the"]
+    #[doc = "URI map SHOULD be dynamic)."]
+    #[doc = ""]
+    #[doc = "@param handle Must be the callback_data member of this struct."]
+    #[doc = "@param uri The URI to be mapped to an integer ID."]
+    pub map: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_URID_Map_Handle,
+            uri: *const ::std::os::raw::c_char,
+        ) -> LV2_URID,
+    >,
+}
+#[doc = "URI Unmap Feature (LV2_URID__unmap)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_URID_Unmap {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "This MUST be passed to unmap() whenever it is called."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub handle: LV2_URID_Unmap_Handle,
+    #[doc = "Get the URI for a previously mapped numeric ID."]
+    #[doc = ""]
+    #[doc = "Returns NULL if `urid` is not yet mapped.  Otherwise, the corresponding"]
+    #[doc = "URI is returned in a canonical form.  This MAY not be the exact same"]
+    #[doc = "string that was originally passed to LV2_URID_Map::map(), but it MUST be"]
+    #[doc = "an identical URI according to the URI syntax specification (RFC3986).  A"]
+    #[doc = "non-NULL return for a given `urid` will always be the same for the life"]
+    #[doc = "of the plugin.  Plugins that intend to perform string comparison on"]
+    #[doc = "unmapped URIs SHOULD first canonicalise URI strings with a call to"]
+    #[doc = "map_uri() followed by a call to unmap_uri()."]
+    #[doc = ""]
+    #[doc = "@param handle Must be the callback_data member of this struct."]
+    #[doc = "@param urid The ID to be mapped back to the URI string."]
+    pub unmap: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_URID_Unmap_Handle,
+            urid: LV2_URID,
+        ) -> *const ::std::os::raw::c_char,
+    >,
+}
+#[doc = " Handle for LV2_Atom_Forge_Sink."]
+pub type LV2_Atom_Forge_Sink_Handle = *mut ::std::os::raw::c_void;
+#[doc = " A reference to a chunk of written output."]
+pub type LV2_Atom_Forge_Ref = isize;
+#[doc = " Sink function for writing output.  See lv2_atom_forge_set_sink()."]
+pub type LV2_Atom_Forge_Sink = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_Atom_Forge_Sink_Handle,
+        buf: *const ::std::os::raw::c_void,
+        size: u32,
+    ) -> LV2_Atom_Forge_Ref,
+>;
+#[doc = " Function for resolving a reference.  See lv2_atom_forge_set_sink()."]
+pub type LV2_Atom_Forge_Deref_Func = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_Atom_Forge_Sink_Handle,
+        ref_: LV2_Atom_Forge_Ref,
+    ) -> *mut LV2_Atom,
+>;
+#[doc = " A stack frame used for keeping track of nested Atom containers."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Forge_Frame {
+    pub parent: *mut LV2_Atom_Forge_Frame,
+    pub ref_: LV2_Atom_Forge_Ref,
+}
+#[doc = " A \"forge\" for creating atoms by appending to a buffer."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Atom_Forge {
+    pub buf: *mut u8,
+    pub offset: u32,
+    pub size: u32,
+    pub sink: LV2_Atom_Forge_Sink,
+    pub deref: LV2_Atom_Forge_Deref_Func,
+    pub handle: LV2_Atom_Forge_Sink_Handle,
+    pub stack: *mut LV2_Atom_Forge_Frame,
+    pub Blank: LV2_URID,
+    pub Bool: LV2_URID,
+    pub Chunk: LV2_URID,
+    pub Double: LV2_URID,
+    pub Float: LV2_URID,
+    pub Int: LV2_URID,
+    pub Long: LV2_URID,
+    pub Literal: LV2_URID,
+    pub Object: LV2_URID,
+    pub Path: LV2_URID,
+    pub Property: LV2_URID,
+    pub Resource: LV2_URID,
+    pub Sequence: LV2_URID,
+    pub String: LV2_URID,
+    pub Tuple: LV2_URID,
+    pub URI: LV2_URID,
+    pub URID: LV2_URID,
+    pub Vector: LV2_URID,
+}
+#[doc = "Plugin Instance Handle."]
+#[doc = ""]
+#[doc = "This is a handle for one particular instance of a plugin.  It is valid to"]
+#[doc = "compare to NULL (or 0 for C++) but otherwise the host MUST NOT attempt to"]
+#[doc = "interpret it."]
+pub type LV2_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Feature."]
+#[doc = ""]
+#[doc = "Features allow hosts to make additional functionality available to plugins"]
+#[doc = "without requiring modification to the LV2 API.  Extensions may define new"]
+#[doc = "features and specify the `URI` and `data` to be used if necessary."]
+#[doc = "Some features, such as lv2:isLive, do not require the host to pass data."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Feature {
+    #[doc = "A globally unique, case-sensitive identifier (URI) for this feature."]
+    #[doc = ""]
+    #[doc = "This MUST be a valid URI string as defined by RFC 3986."]
+    pub URI: *const ::std::os::raw::c_char,
+    #[doc = "Pointer to arbitrary data."]
+    #[doc = ""]
+    #[doc = "The format of this data is defined by the extension which describes the"]
+    #[doc = "feature with the given `URI`."]
+    pub data: *mut ::std::os::raw::c_void,
+}
+#[doc = "Plugin Descriptor."]
+#[doc = ""]
+#[doc = "This structure provides the core functions necessary to instantiate and use"]
+#[doc = "a plugin."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Descriptor {
+    #[doc = "A globally unique, case-sensitive identifier for this plugin."]
+    #[doc = ""]
+    #[doc = "This MUST be a valid URI string as defined by RFC 3986.  All plugins with"]
+    #[doc = "the same URI MUST be compatible to some degree, see"]
+    #[doc = "http://lv2plug.in/ns/lv2core for details."]
+    pub URI: *const ::std::os::raw::c_char,
+    #[doc = "Instantiate the plugin."]
+    #[doc = ""]
+    #[doc = "Note that instance initialisation should generally occur in activate()"]
+    #[doc = "rather than here. If a host calls instantiate(), it MUST call cleanup()"]
+    #[doc = "at some point in the future."]
+    #[doc = ""]
+    #[doc = "@param descriptor Descriptor of the plugin to instantiate."]
+    #[doc = ""]
+    #[doc = "@param sample_rate Sample rate, in Hz, for the new plugin instance."]
+    #[doc = ""]
+    #[doc = "@param bundle_path Path to the LV2 bundle which contains this plugin"]
+    #[doc = "binary. It MUST include the trailing directory separator so that simply"]
+    #[doc = "appending a filename will yield the path to that file in the bundle."]
+    #[doc = ""]
+    #[doc = "@param features A NULL terminated array of LV2_Feature structs which"]
+    #[doc = "represent the features the host supports. Plugins may refuse to"]
+    #[doc = "instantiate if required features are not found here. However, hosts MUST"]
+    #[doc = "NOT use this as a discovery mechanism: instead, use the RDF data to"]
+    #[doc = "determine which features are required and do not attempt to instantiate"]
+    #[doc = "unsupported plugins at all. This parameter MUST NOT be NULL, i.e. a host"]
+    #[doc = "that supports no features MUST pass a single element array containing"]
+    #[doc = "NULL."]
+    #[doc = ""]
+    #[doc = "@return A handle for the new plugin instance, or NULL if instantiation"]
+    #[doc = "has failed."]
+    pub instantiate: ::std::option::Option<
+        unsafe extern "C" fn(
+            descriptor: *const LV2_Descriptor,
+            sample_rate: f64,
+            bundle_path: *const ::std::os::raw::c_char,
+            features: *const *const LV2_Feature,
+        ) -> LV2_Handle,
+    >,
+    #[doc = "Connect a port on a plugin instance to a memory location."]
+    #[doc = ""]
+    #[doc = "Plugin writers should be aware that the host may elect to use the same"]
+    #[doc = "buffer for more than one port and even use the same buffer for both"]
+    #[doc = "input and output (see lv2:inPlaceBroken in lv2.ttl)."]
+    #[doc = ""]
+    #[doc = "If the plugin has the feature lv2:hardRTCapable then there are various"]
+    #[doc = "things that the plugin MUST NOT do within the connect_port() function;"]
+    #[doc = "see lv2core.ttl for details."]
+    #[doc = ""]
+    #[doc = "connect_port() MUST be called at least once for each port before run()"]
+    #[doc = "is called, unless that port is lv2:connectionOptional. The plugin must"]
+    #[doc = "pay careful attention to the block size passed to run() since the block"]
+    #[doc = "allocated may only just be large enough to contain the data, and is not"]
+    #[doc = "guaranteed to remain constant between run() calls."]
+    #[doc = ""]
+    #[doc = "connect_port() may be called more than once for a plugin instance to"]
+    #[doc = "allow the host to change the buffers that the plugin is reading or"]
+    #[doc = "writing. These calls may be made before or after activate() or"]
+    #[doc = "deactivate() calls."]
+    #[doc = ""]
+    #[doc = "@param instance Plugin instance containing the port."]
+    #[doc = ""]
+    #[doc = "@param port Index of the port to connect. The host MUST NOT try to"]
+    #[doc = "connect a port index that is not defined in the plugin's RDF data. If"]
+    #[doc = "it does, the plugin's behaviour is undefined (a crash is likely)."]
+    #[doc = ""]
+    #[doc = "@param data_location Pointer to data of the type defined by the port"]
+    #[doc = "type in the plugin's RDF data (for example, an array of float for an"]
+    #[doc = "lv2:AudioPort). This pointer must be stored by the plugin instance and"]
+    #[doc = "used to read/write data when run() is called. Data present at the time"]
+    #[doc = "of the connect_port() call MUST NOT be considered meaningful."]
+    pub connect_port: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            port: u32,
+            data_location: *mut ::std::os::raw::c_void,
+        ),
+    >,
+    #[doc = "Initialise a plugin instance and activate it for use."]
+    #[doc = ""]
+    #[doc = "This is separated from instantiate() to aid real-time support and so"]
+    #[doc = "that hosts can reinitialise a plugin instance by calling deactivate()"]
+    #[doc = "and then activate(). In this case the plugin instance MUST reset all"]
+    #[doc = "state information dependent on the history of the plugin instance except"]
+    #[doc = "for any data locations provided by connect_port(). If there is nothing"]
+    #[doc = "for activate() to do then this field may be NULL."]
+    #[doc = ""]
+    #[doc = "When present, hosts MUST call this function once before run() is called"]
+    #[doc = "for the first time. This call SHOULD be made as close to the run() call"]
+    #[doc = "as possible and indicates to real-time plugins that they are now live,"]
+    #[doc = "however plugins MUST NOT rely on a prompt call to run() after"]
+    #[doc = "activate()."]
+    #[doc = ""]
+    #[doc = "The host MUST NOT call activate() again until deactivate() has been"]
+    #[doc = "called first. If a host calls activate(), it MUST call deactivate() at"]
+    #[doc = "some point in the future. Note that connect_port() may be called before"]
+    #[doc = "or after activate()."]
+    pub activate: ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle)>,
+    #[doc = "Run a plugin instance for a block."]
+    #[doc = ""]
+    #[doc = "Note that if an activate() function exists then it must be called before"]
+    #[doc = "run(). If deactivate() is called for a plugin instance then run() may"]
+    #[doc = "not be called until activate() has been called again."]
+    #[doc = ""]
+    #[doc = "If the plugin has the feature lv2:hardRTCapable then there are various"]
+    #[doc = "things that the plugin MUST NOT do within the run() function (see"]
+    #[doc = "lv2core.ttl for details)."]
+    #[doc = ""]
+    #[doc = "As a special case, when `sample_count` is 0, the plugin should update"]
+    #[doc = "any output ports that represent a single instant in time (for example,"]
+    #[doc = "control ports, but not audio ports). This is particularly useful for"]
+    #[doc = "latent plugins, which should update their latency output port so hosts"]
+    #[doc = "can pre-roll plugins to compute latency. Plugins MUST NOT crash when"]
+    #[doc = "`sample_count` is 0."]
+    #[doc = ""]
+    #[doc = "@param instance Instance to be run."]
+    #[doc = ""]
+    #[doc = "@param sample_count The block size (in samples) for which the plugin"]
+    #[doc = "instance must run."]
+    pub run: ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle, sample_count: u32)>,
+    #[doc = "Deactivate a plugin instance (counterpart to activate())."]
+    #[doc = ""]
+    #[doc = "Hosts MUST deactivate all activated instances after they have been run()"]
+    #[doc = "for the last time. This call SHOULD be made as close to the last run()"]
+    #[doc = "call as possible and indicates to real-time plugins that they are no"]
+    #[doc = "longer live, however plugins MUST NOT rely on prompt deactivation. If"]
+    #[doc = "there is nothing for deactivate() to do then this field may be NULL"]
+    #[doc = ""]
+    #[doc = "Deactivation is not similar to pausing since the plugin instance will be"]
+    #[doc = "reinitialised by activate(). However, deactivate() itself MUST NOT fully"]
+    #[doc = "reset plugin state. For example, the host may deactivate a plugin, then"]
+    #[doc = "store its state (using some extension to do so)."]
+    #[doc = ""]
+    #[doc = "Hosts MUST NOT call deactivate() unless activate() was previously"]
+    #[doc = "called. Note that connect_port() may be called before or after"]
+    #[doc = "deactivate()."]
+    pub deactivate: ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle)>,
+    #[doc = "Clean up a plugin instance (counterpart to instantiate())."]
+    #[doc = ""]
+    #[doc = "Once an instance of a plugin has been finished with it must be deleted"]
+    #[doc = "using this function. The instance handle passed ceases to be valid after"]
+    #[doc = "this call."]
+    #[doc = ""]
+    #[doc = "If activate() was called for a plugin instance then a corresponding call"]
+    #[doc = "to deactivate() MUST be made before cleanup() is called. Hosts MUST NOT"]
+    #[doc = "call cleanup() unless instantiate() was previously called."]
+    pub cleanup: ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle)>,
+    #[doc = "Return additional plugin data defined by some extenion."]
+    #[doc = ""]
+    #[doc = "A typical use of this facility is to return a struct containing function"]
+    #[doc = "pointers to extend the LV2_Descriptor API."]
+    #[doc = ""]
+    #[doc = "The actual type and meaning of the returned object MUST be specified"]
+    #[doc = "precisely by the extension. This function MUST return NULL for any"]
+    #[doc = "unsupported URI. If a plugin does not support any extension data, this"]
+    #[doc = "field may be NULL."]
+    #[doc = ""]
+    #[doc = "The host is never responsible for freeing the returned value."]
+    pub extension_data: ::std::option::Option<
+        unsafe extern "C" fn(uri: *const ::std::os::raw::c_char) -> *const ::std::os::raw::c_void,
+    >,
+}
+#[doc = "Type of the lv2_descriptor() function in a library (old discovery API)."]
+pub type LV2_Descriptor_Function =
+    ::std::option::Option<unsafe extern "C" fn(index: u32) -> *const LV2_Descriptor>;
+#[doc = "Handle for a library descriptor."]
+pub type LV2_Lib_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Descriptor for a plugin library."]
+#[doc = ""]
+#[doc = "To access a plugin library, the host creates an LV2_Lib_Descriptor via the"]
+#[doc = "lv2_lib_descriptor() function in the shared object."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Lib_Descriptor {
+    #[doc = "Opaque library data which must be passed as the first parameter to all"]
+    #[doc = "the methods of this struct."]
+    pub handle: LV2_Lib_Handle,
+    #[doc = "The total size of this struct.  This allows for this struct to be"]
+    #[doc = "expanded in the future if necessary.  This MUST be set by the library to"]
+    #[doc = "sizeof(LV2_Lib_Descriptor).  The host MUST NOT access any fields of this"]
+    #[doc = "struct beyond get_plugin() unless this field indicates they are present."]
+    pub size: u32,
+    #[doc = "Destroy this library descriptor and free all related resources."]
+    pub cleanup: ::std::option::Option<unsafe extern "C" fn(handle: LV2_Lib_Handle)>,
+    #[doc = "Plugin accessor."]
+    #[doc = ""]
+    #[doc = "Plugins are accessed by index using values from 0 upwards.  Out of range"]
+    #[doc = "indices MUST result in this function returning NULL, so the host can"]
+    #[doc = "enumerate plugins by increasing `index` until NULL is returned."]
+    pub get_plugin: ::std::option::Option<
+        unsafe extern "C" fn(handle: LV2_Lib_Handle, index: u32) -> *const LV2_Descriptor,
+    >,
+}
+#[doc = "Type of the lv2_lib_descriptor() function in an LV2 library."]
+pub type LV2_Lib_Descriptor_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        bundle_path: *const ::std::os::raw::c_char,
+        features: *const *const LV2_Feature,
+    ) -> *const LV2_Lib_Descriptor,
+>;
+#[doc = "The data field of the LV2_Feature for this extension."]
+#[doc = ""]
+#[doc = "To support this feature the host must pass an LV2_Feature struct to the"]
+#[doc = "instantiate method with URI \"http://lv2plug.in/ns/ext/data-access\""]
+#[doc = "and data pointed to an instance of this struct."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Extension_Data_Feature {
+    #[doc = "A pointer to a method the UI can call to get data (of a type specified"]
+    #[doc = "by some other extension) from the plugin."]
+    #[doc = ""]
+    #[doc = "This call never is never guaranteed to return anything, UIs should"]
+    #[doc = "degrade gracefully if direct access to the plugin data is not possible"]
+    #[doc = "(in which case this function will return NULL)."]
+    #[doc = ""]
+    #[doc = "This is for access to large data that can only possibly work if the UI"]
+    #[doc = "and plugin are running in the same process.  For all other things, use"]
+    #[doc = "the normal LV2 UI communication system."]
+    pub data_access: ::std::option::Option<
+        unsafe extern "C" fn(uri: *const ::std::os::raw::c_char) -> *const ::std::os::raw::c_void,
+    >,
+}
+#[doc = "Dynamic manifest generator handle."]
+#[doc = ""]
+#[doc = "This handle indicates a particular status of a dynamic manifest generator."]
+#[doc = "The host MUST NOT attempt to interpret it and, unlikely LV2_Handle, it is"]
+#[doc = "NOT even valid to compare this to NULL. The dynamic manifest generator MAY"]
+#[doc = "use it to reference internal data."]
+pub type LV2_Dyn_Manifest_Handle = *mut ::std::os::raw::c_void;
+pub const LV2_EVENT_PPQN: u32 = 3136573440;
+#[doc = "An LV2 event (header only)."]
+#[doc = ""]
+#[doc = "LV2 events are generic time-stamped containers for any type of event."]
+#[doc = "The type field defines the format of a given event's contents."]
+#[doc = ""]
+#[doc = "This struct defines the header of an LV2 event. An LV2 event is a single"]
+#[doc = "chunk of POD (plain old data), usually contained in a flat buffer (see"]
+#[doc = "LV2_EventBuffer below). Unless a required feature says otherwise, hosts may"]
+#[doc = "assume a deep copy of an LV2 event can be created safely using a simple:"]
+#[doc = ""]
+#[doc = "memcpy(ev_copy, ev, sizeof(LV2_Event) + ev->size);  (or equivalent)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Event {
+    #[doc = "The frames portion of timestamp. The units used here can optionally be"]
+    #[doc = "set for a port (with the lv2ev:timeUnits property), otherwise this is"]
+    #[doc = "audio frames, corresponding to the sample_count parameter of the LV2 run"]
+    #[doc = "method (frame 0 is the first frame for that call to run)."]
+    pub frames: u32,
+    #[doc = "The sub-frames portion of timestamp. The units used here can optionally"]
+    #[doc = "be set for a port (with the lv2ev:timeUnits property), otherwise this is"]
+    #[doc = "1/(2^32) of an audio frame."]
+    pub subframes: u32,
+    #[doc = "The type of this event, as a number which represents some URI"]
+    #[doc = "defining an event type. This value MUST be some value previously"]
+    #[doc = "returned from a call to the uri_to_id function defined in the LV2"]
+    #[doc = "URI map extension (see lv2_uri_map.h)."]
+    #[doc = "There are special rules which must be followed depending on the type"]
+    #[doc = "of an event. If the plugin recognizes an event type, the definition"]
+    #[doc = "of that event type will describe how to interpret the event, and"]
+    #[doc = "any required behaviour. Otherwise, if the type is 0, this event is a"]
+    #[doc = "non-POD event and lv2_event_unref MUST be called if the event is"]
+    #[doc = "'dropped' (see above). Even if the plugin does not understand an event,"]
+    #[doc = "it may pass the event through to an output by simply copying (and NOT"]
+    #[doc = "calling lv2_event_unref). These rules are designed to allow for generic"]
+    #[doc = "event handling plugins and large non-POD events, but with minimal hassle"]
+    #[doc = "on simple plugins that \"don't care\" about these more advanced features."]
+    pub type_: u16,
+    #[doc = "The size of the data portion of this event in bytes, which immediately"]
+    #[doc = "follows. The header size (12 bytes) is not included in this value."]
+    pub size: u16,
+}
+#[doc = "A buffer of LV2 events (header only)."]
+#[doc = ""]
+#[doc = "Like events (which this contains) an event buffer is a single chunk of POD:"]
+#[doc = "the entire buffer (including contents) can be copied with a single memcpy."]
+#[doc = "The first contained event begins sizeof(LV2_EventBuffer) bytes after the"]
+#[doc = "start of this struct."]
+#[doc = ""]
+#[doc = "After this header, the buffer contains an event header (defined by struct"]
+#[doc = "LV2_Event), followed by that event's contents (padded to 64 bits), followed"]
+#[doc = "by another header, etc:"]
+#[doc = ""]
+#[doc = "|       |       |       |       |       |       |"]
+#[doc = "| | | | | | | | | | | | | | | | | | | | | | | | |"]
+#[doc = "|FRAMES |SUBFRMS|TYP|LEN|DATA..DATA..PAD|FRAMES | ..."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Event_Buffer {
+    #[doc = "The contents of the event buffer. This may or may not reside in the"]
+    #[doc = "same block of memory as this header, plugins must not assume either."]
+    #[doc = "The host guarantees this points to at least capacity bytes of allocated"]
+    #[doc = "memory (though only size bytes of that are valid events)."]
+    pub data: *mut u8,
+    #[doc = "The size of this event header in bytes (including everything)."]
+    #[doc = ""]
+    #[doc = "This is to allow for extending this header in the future without"]
+    #[doc = "breaking binary compatibility. Whenever this header is copied,"]
+    #[doc = "it MUST be done using this field (and NOT the sizeof this struct)."]
+    pub header_size: u16,
+    #[doc = "The type of the time stamps for events in this buffer."]
+    #[doc = "As a special exception, '0' always means audio frames and subframes"]
+    #[doc = "(1/UINT32_MAX'th of a frame) in the sample rate passed to instantiate."]
+    #[doc = ""]
+    #[doc = "INPUTS: The host must set this field to the numeric ID of some URI"]
+    #[doc = "defining the meaning of the frames/subframes fields of contained events"]
+    #[doc = "(obtained by the LV2 URI Map uri_to_id function with the URI of this"]
+    #[doc = "extension as the 'map' argument, see lv2_uri_map.h).  The host must"]
+    #[doc = "never pass a plugin a buffer which uses a stamp type the plugin does not"]
+    #[doc = "'understand'. The value of this field must never change, except when"]
+    #[doc = "connect_port is called on the input port, at which time the host MUST"]
+    #[doc = "have set the stamp_type field to the value that will be used for all"]
+    #[doc = "subsequent run calls."]
+    #[doc = ""]
+    #[doc = "OUTPUTS: The plugin may set this to any value that has been returned"]
+    #[doc = "from uri_to_id with the URI of this extension for a 'map' argument."]
+    #[doc = "When connected to a buffer with connect_port, output ports MUST set this"]
+    #[doc = "field to the type of time stamp they will be writing. On any call to"]
+    #[doc = "connect_port on an event input port, the plugin may change this field on"]
+    #[doc = "any output port, it is the responsibility of the host to check if any of"]
+    #[doc = "these values have changed and act accordingly."]
+    pub stamp_type: u16,
+    #[doc = "The number of events in this buffer."]
+    #[doc = ""]
+    #[doc = "INPUTS: The host must set this field to the number of events contained"]
+    #[doc = "in the data buffer before calling run(). The plugin must not change"]
+    #[doc = "this field."]
+    #[doc = ""]
+    #[doc = "OUTPUTS: The plugin must set this field to the number of events it has"]
+    #[doc = "written to the buffer before returning from run(). Any initial value"]
+    #[doc = "should be ignored by the plugin."]
+    pub event_count: u32,
+    #[doc = "The size of the data buffer in bytes."]
+    #[doc = "This is set by the host and must not be changed by the plugin."]
+    #[doc = "The host is allowed to change this between run() calls."]
+    pub capacity: u32,
+    #[doc = "The size of the initial portion of the data buffer containing data."]
+    #[doc = ""]
+    #[doc = "INPUTS: The host must set this field to the number of bytes used"]
+    #[doc = "by all events it has written to the buffer (including headers)"]
+    #[doc = "before calling the plugin's run()."]
+    #[doc = "The plugin must not change this field."]
+    #[doc = ""]
+    #[doc = "OUTPUTS: The plugin must set this field to the number of bytes"]
+    #[doc = "used by all events it has written to the buffer (including headers)"]
+    #[doc = "before returning from run()."]
+    #[doc = "Any initial value should be ignored by the plugin."]
+    pub size: u32,
+}
+#[doc = "Opaque pointer to host data."]
+pub type LV2_Event_Callback_Data = *mut ::std::os::raw::c_void;
+#[doc = "Non-POD events feature."]
+#[doc = ""]
+#[doc = "To support this feature the host must pass an LV2_Feature struct to the"]
+#[doc = "plugin's instantiate method with URI \"http://lv2plug.in/ns/ext/event\""]
+#[doc = "and data pointed to an instance of this struct.  Note this feature"]
+#[doc = "is not mandatory to support the event extension."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Event_Feature {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "The plugin MUST pass this to any call to functions in this struct."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub callback_data: LV2_Event_Callback_Data,
+    #[doc = "Take a reference to a non-POD event."]
+    #[doc = ""]
+    #[doc = "If a plugin receives an event with type 0, it means the event is a"]
+    #[doc = "pointer to some object in memory and not a flat sequence of bytes"]
+    #[doc = "in the buffer. When receiving a non-POD event, the plugin already"]
+    #[doc = "has an implicit reference to the event. If the event is stored AND"]
+    #[doc = "passed to an output, lv2_event_ref MUST be called on that event."]
+    #[doc = "If the event is only stored OR passed through, this is not necessary"]
+    #[doc = "(as the plugin already has 1 implicit reference)."]
+    #[doc = ""]
+    #[doc = "@param event An event received at an input that will not be copied to"]
+    #[doc = "an output or stored in any way."]
+    #[doc = ""]
+    #[doc = "@param context The calling context. Like event types, this is a mapped"]
+    #[doc = "URI, see lv2_context.h. Simple plugin with just a run() method should"]
+    #[doc = "pass 0 here (the ID of the 'standard' LV2 run context). The host"]
+    #[doc = "guarantees that this function is realtime safe iff the context is"]
+    #[doc = "realtime safe."]
+    #[doc = ""]
+    #[doc = "PLUGINS THAT VIOLATE THESE RULES MAY CAUSE CRASHES AND MEMORY LEAKS."]
+    pub lv2_event_ref: ::std::option::Option<
+        unsafe extern "C" fn(callback_data: LV2_Event_Callback_Data, event: *mut LV2_Event) -> u32,
+    >,
+    #[doc = "Drop a reference to a non-POD event."]
+    #[doc = ""]
+    #[doc = "If a plugin receives an event with type 0, it means the event is a"]
+    #[doc = "pointer to some object in memory and not a flat sequence of bytes"]
+    #[doc = "in the buffer. If the plugin does not pass the event through to"]
+    #[doc = "an output or store it internally somehow, it MUST call this function"]
+    #[doc = "on the event (more information on using non-POD events below)."]
+    #[doc = ""]
+    #[doc = "@param event An event received at an input that will not be copied to an"]
+    #[doc = "output or stored in any way."]
+    #[doc = ""]
+    #[doc = "@param context The calling context. Like event types, this is a mapped"]
+    #[doc = "URI, see lv2_context.h. Simple plugin with just a run() method should"]
+    #[doc = "pass 0 here (the ID of the 'standard' LV2 run context). The host"]
+    #[doc = "guarantees that this function is realtime safe iff the context is"]
+    #[doc = "realtime safe."]
+    #[doc = ""]
+    #[doc = "PLUGINS THAT VIOLATE THESE RULES MAY CAUSE CRASHES AND MEMORY LEAKS."]
+    pub lv2_event_unref: ::std::option::Option<
+        unsafe extern "C" fn(callback_data: LV2_Event_Callback_Data, event: *mut LV2_Event) -> u32,
+    >,
+}
+#[doc = " An iterator over an LV2_Event_Buffer."]
+#[doc = ""]
+#[doc = " Multiple simultaneous read iterators over a single buffer is fine,"]
+#[doc = " but changing the buffer invalidates all iterators."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Event_Iterator {
+    pub buf: *mut LV2_Event_Buffer,
+    pub offset: u32,
+}
+#[doc = "Opaque data to host data for LV2_Log_Log."]
+pub type LV2_Log_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Log feature (LV2_LOG__log)"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Log_Log {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "This MUST be passed to methods in this struct whenever they are called."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub handle: LV2_Log_Handle,
+    #[doc = "Log a message, passing format parameters directly."]
+    #[doc = ""]
+    #[doc = "The API of this function matches that of the standard C printf function,"]
+    #[doc = "except for the addition of the first two parameters.  This function may"]
+    #[doc = "be called from any non-realtime context, or from any context if `type`"]
+    #[doc = "is @ref LV2_LOG__Trace."]
+    pub printf: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_Log_Handle,
+            type_: LV2_URID,
+            fmt: *const ::std::os::raw::c_char,
+            ...
+        ) -> ::std::os::raw::c_int,
+    >,
+    #[doc = "Log a message, passing format parameters in a va_list."]
+    #[doc = ""]
+    #[doc = "The API of this function matches that of the standard C vprintf"]
+    #[doc = "function, except for the addition of the first two parameters.  This"]
+    #[doc = "function may be called from any non-realtime context, or from any"]
+    #[doc = "context if `type` is @ref LV2_LOG__Trace."]
+    pub vprintf: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_Log_Handle,
+            type_: LV2_URID,
+            fmt: *const ::std::os::raw::c_char,
+            ap: va_list,
+        ) -> ::std::os::raw::c_int,
+    >,
+}
+#[doc = "Logger convenience API state."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Log_Logger {
+    pub log: *mut LV2_Log_Log,
+    pub Error: LV2_URID,
+    pub Note: LV2_URID,
+    pub Trace: LV2_URID,
+    pub Warning: LV2_URID,
+}
+#[doc = "< Invalid Message"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_INVALID: LV2_Midi_Message_Type = 0;
+#[doc = "< Note Off"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_NOTE_OFF: LV2_Midi_Message_Type = 128;
+#[doc = "< Note On"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_NOTE_ON: LV2_Midi_Message_Type = 144;
+#[doc = "< Note Pressure"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_NOTE_PRESSURE: LV2_Midi_Message_Type = 160;
+#[doc = "< Controller"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_CONTROLLER: LV2_Midi_Message_Type = 176;
+#[doc = "< Program Change"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_PGM_CHANGE: LV2_Midi_Message_Type = 192;
+#[doc = "< Channel Pressure"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_CHANNEL_PRESSURE: LV2_Midi_Message_Type = 208;
+#[doc = "< Pitch Bender"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_BENDER: LV2_Midi_Message_Type = 224;
+#[doc = "< System Exclusive Begin"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_SYSTEM_EXCLUSIVE: LV2_Midi_Message_Type = 240;
+#[doc = "< MTC Quarter Frame"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_MTC_QUARTER: LV2_Midi_Message_Type = 241;
+#[doc = "< Song Position"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_SONG_POS: LV2_Midi_Message_Type = 242;
+#[doc = "< Song Select"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_SONG_SELECT: LV2_Midi_Message_Type = 243;
+#[doc = "< Tune Request"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_TUNE_REQUEST: LV2_Midi_Message_Type = 246;
+#[doc = "< Clock"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_CLOCK: LV2_Midi_Message_Type = 248;
+#[doc = "< Start"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_START: LV2_Midi_Message_Type = 250;
+#[doc = "< Continue"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_CONTINUE: LV2_Midi_Message_Type = 251;
+#[doc = "< Stop"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_STOP: LV2_Midi_Message_Type = 252;
+#[doc = "< Active Sensing"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_ACTIVE_SENSE: LV2_Midi_Message_Type = 254;
+#[doc = "< Reset"]
+pub const LV2_Midi_Message_Type_LV2_MIDI_MSG_RESET: LV2_Midi_Message_Type = 255;
+#[doc = "MIDI Message Type."]
+#[doc = ""]
+#[doc = "This includes both voice messages (which have a channel) and system messages"]
+#[doc = "(which do not), as well as a sentinel value for invalid messages.  To get"]
+#[doc = "the type of a message suitable for use in a switch statement, use"]
+#[doc = "lv2_midi_get_type() on the status byte."]
+pub type LV2_Midi_Message_Type = i32;
+#[doc = "< Bank Selection"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_BANK: LV2_Midi_Controller = 0;
+#[doc = "< Modulation"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_MODWHEEL: LV2_Midi_Controller = 1;
+#[doc = "< Breath"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_BREATH: LV2_Midi_Controller = 2;
+#[doc = "< Foot"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_FOOT: LV2_Midi_Controller = 4;
+#[doc = "< Portamento Time"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_PORTAMENTO_TIME: LV2_Midi_Controller = 5;
+#[doc = "< Data Entry"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_DATA_ENTRY: LV2_Midi_Controller = 6;
+#[doc = "< Main Volume"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_MAIN_VOLUME: LV2_Midi_Controller = 7;
+#[doc = "< Balance"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_BALANCE: LV2_Midi_Controller = 8;
+#[doc = "< Panpot"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_PAN: LV2_Midi_Controller = 10;
+#[doc = "< Expression"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_EXPRESSION: LV2_Midi_Controller = 11;
+#[doc = "< Effect1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_EFFECT1: LV2_Midi_Controller = 12;
+#[doc = "< Effect2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_EFFECT2: LV2_Midi_Controller = 13;
+#[doc = "< General Purpose 1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_GENERAL_PURPOSE1: LV2_Midi_Controller = 16;
+#[doc = "< General Purpose 2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_GENERAL_PURPOSE2: LV2_Midi_Controller = 17;
+#[doc = "< General Purpose 3"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_GENERAL_PURPOSE3: LV2_Midi_Controller = 18;
+#[doc = "< General Purpose 4"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MSB_GENERAL_PURPOSE4: LV2_Midi_Controller = 19;
+#[doc = "< Bank Selection"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_BANK: LV2_Midi_Controller = 32;
+#[doc = "< Modulation"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_MODWHEEL: LV2_Midi_Controller = 33;
+#[doc = "< Breath"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_BREATH: LV2_Midi_Controller = 34;
+#[doc = "< Foot"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_FOOT: LV2_Midi_Controller = 36;
+#[doc = "< Portamento Time"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_PORTAMENTO_TIME: LV2_Midi_Controller = 37;
+#[doc = "< Data Entry"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_DATA_ENTRY: LV2_Midi_Controller = 38;
+#[doc = "< Main Volume"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_MAIN_VOLUME: LV2_Midi_Controller = 39;
+#[doc = "< Balance"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_BALANCE: LV2_Midi_Controller = 40;
+#[doc = "< Panpot"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_PAN: LV2_Midi_Controller = 42;
+#[doc = "< Expression"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_EXPRESSION: LV2_Midi_Controller = 43;
+#[doc = "< Effect1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_EFFECT1: LV2_Midi_Controller = 44;
+#[doc = "< Effect2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_EFFECT2: LV2_Midi_Controller = 45;
+#[doc = "< General Purpose 1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_GENERAL_PURPOSE1: LV2_Midi_Controller = 48;
+#[doc = "< General Purpose 2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_GENERAL_PURPOSE2: LV2_Midi_Controller = 49;
+#[doc = "< General Purpose 3"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_GENERAL_PURPOSE3: LV2_Midi_Controller = 50;
+#[doc = "< General Purpose 4"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LSB_GENERAL_PURPOSE4: LV2_Midi_Controller = 51;
+#[doc = "< Sustain Pedal"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SUSTAIN: LV2_Midi_Controller = 64;
+#[doc = "< Portamento"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_PORTAMENTO: LV2_Midi_Controller = 65;
+#[doc = "< Sostenuto"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SOSTENUTO: LV2_Midi_Controller = 66;
+#[doc = "< Soft Pedal"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SOFT_PEDAL: LV2_Midi_Controller = 67;
+#[doc = "< Legato Foot Switch"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LEGATO_FOOTSWITCH: LV2_Midi_Controller = 68;
+#[doc = "< Hold2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_HOLD2: LV2_Midi_Controller = 69;
+#[doc = "< SC1 Sound Variation"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC1_SOUND_VARIATION: LV2_Midi_Controller = 70;
+#[doc = "< SC2 Timbre"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC2_TIMBRE: LV2_Midi_Controller = 71;
+#[doc = "< SC3 Release Time"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC3_RELEASE_TIME: LV2_Midi_Controller = 72;
+#[doc = "< SC4 Attack Time"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC4_ATTACK_TIME: LV2_Midi_Controller = 73;
+#[doc = "< SC5 Brightness"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC5_BRIGHTNESS: LV2_Midi_Controller = 74;
+#[doc = "< SC6"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC6: LV2_Midi_Controller = 75;
+#[doc = "< SC7"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC7: LV2_Midi_Controller = 76;
+#[doc = "< SC8"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC8: LV2_Midi_Controller = 77;
+#[doc = "< SC9"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC9: LV2_Midi_Controller = 78;
+#[doc = "< SC10"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_SC10: LV2_Midi_Controller = 79;
+#[doc = "< General Purpose 5"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_GENERAL_PURPOSE5: LV2_Midi_Controller = 80;
+#[doc = "< General Purpose 6"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_GENERAL_PURPOSE6: LV2_Midi_Controller = 81;
+#[doc = "< General Purpose 7"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_GENERAL_PURPOSE7: LV2_Midi_Controller = 82;
+#[doc = "< General Purpose 8"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_GENERAL_PURPOSE8: LV2_Midi_Controller = 83;
+#[doc = "< Portamento Control"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_PORTAMENTO_CONTROL: LV2_Midi_Controller = 84;
+#[doc = "< E1 Reverb Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E1_REVERB_DEPTH: LV2_Midi_Controller = 91;
+#[doc = "< E2 Tremolo Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E2_TREMOLO_DEPTH: LV2_Midi_Controller = 92;
+#[doc = "< E3 Chorus Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E3_CHORUS_DEPTH: LV2_Midi_Controller = 93;
+#[doc = "< E4 Detune Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E4_DETUNE_DEPTH: LV2_Midi_Controller = 94;
+#[doc = "< E5 Phaser Depth"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_E5_PHASER_DEPTH: LV2_Midi_Controller = 95;
+#[doc = "< Data Increment"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_DATA_INCREMENT: LV2_Midi_Controller = 96;
+#[doc = "< Data Decrement"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_DATA_DECREMENT: LV2_Midi_Controller = 97;
+#[doc = "< Non-registered Parameter Number"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_NRPN_LSB: LV2_Midi_Controller = 98;
+#[doc = "< Non-registered Parameter Number"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_NRPN_MSB: LV2_Midi_Controller = 99;
+#[doc = "< Registered Parameter Number"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_RPN_LSB: LV2_Midi_Controller = 100;
+#[doc = "< Registered Parameter Number"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_RPN_MSB: LV2_Midi_Controller = 101;
+#[doc = "< All Sounds Off"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_ALL_SOUNDS_OFF: LV2_Midi_Controller = 120;
+#[doc = "< Reset Controllers"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_RESET_CONTROLLERS: LV2_Midi_Controller = 121;
+#[doc = "< Local Control Switch"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_LOCAL_CONTROL_SWITCH: LV2_Midi_Controller = 122;
+#[doc = "< All Notes Off"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_ALL_NOTES_OFF: LV2_Midi_Controller = 123;
+#[doc = "< Omni Off"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_OMNI_OFF: LV2_Midi_Controller = 124;
+#[doc = "< Omni On"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_OMNI_ON: LV2_Midi_Controller = 125;
+#[doc = "< Mono1"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MONO1: LV2_Midi_Controller = 126;
+#[doc = "< Mono2"]
+pub const LV2_Midi_Controller_LV2_MIDI_CTL_MONO2: LV2_Midi_Controller = 127;
+#[doc = "Standard MIDI Controller Numbers."]
+pub type LV2_Midi_Controller = i32;
+#[doc = "This option applies to the instance itself.  The subject must be"]
+#[doc = "ignored."]
+pub const LV2_Options_Context_LV2_OPTIONS_INSTANCE: LV2_Options_Context = 0;
+#[doc = "This option applies to some named resource.  The subject is a URI mapped"]
+#[doc = "to an integer (a LV2_URID, like the key)"]
+pub const LV2_Options_Context_LV2_OPTIONS_RESOURCE: LV2_Options_Context = 1;
+#[doc = "This option applies to some blank node.  The subject is a blank node"]
+#[doc = "identifier, which is valid only within the current local scope."]
+pub const LV2_Options_Context_LV2_OPTIONS_BLANK: LV2_Options_Context = 2;
+#[doc = "This option applies to a port on the instance.  The subject is the"]
+#[doc = "port's index."]
+pub const LV2_Options_Context_LV2_OPTIONS_PORT: LV2_Options_Context = 3;
+#[doc = "The context of an Option, which defines the subject it applies to."]
+pub type LV2_Options_Context = i32;
+#[doc = "An option."]
+#[doc = ""]
+#[doc = "This is a property with a subject, also known as a triple or statement."]
+#[doc = ""]
+#[doc = "This struct is useful anywhere a statement needs to be passed where no"]
+#[doc = "memory ownership issues are present (since the value is a const pointer)."]
+#[doc = ""]
+#[doc = "Options can be passed to an instance via the feature LV2_OPTIONS__options"]
+#[doc = "with data pointed to an array of options terminated by a zeroed option, or"]
+#[doc = "accessed/manipulated using LV2_Options_Interface."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Options_Option {
+    #[doc = "< Context (type of subject)."]
+    pub context: LV2_Options_Context,
+    #[doc = "< Subject."]
+    pub subject: u32,
+    #[doc = "< Key (property)."]
+    pub key: LV2_URID,
+    #[doc = "< Size of value in bytes."]
+    pub size: u32,
+    #[doc = "< Type of value (datatype)."]
+    pub type_: LV2_URID,
+    #[doc = "< Pointer to value (object)."]
+    pub value: *const ::std::os::raw::c_void,
+}
+#[doc = "< Completed successfully."]
+pub const LV2_Options_Status_LV2_OPTIONS_SUCCESS: LV2_Options_Status = 0;
+#[doc = "< Unknown error."]
+pub const LV2_Options_Status_LV2_OPTIONS_ERR_UNKNOWN: LV2_Options_Status = 1;
+#[doc = "< Invalid/unsupported subject."]
+pub const LV2_Options_Status_LV2_OPTIONS_ERR_BAD_SUBJECT: LV2_Options_Status = 2;
+#[doc = "< Invalid/unsupported key."]
+pub const LV2_Options_Status_LV2_OPTIONS_ERR_BAD_KEY: LV2_Options_Status = 4;
+#[doc = "< Invalid/unsupported value."]
+pub const LV2_Options_Status_LV2_OPTIONS_ERR_BAD_VALUE: LV2_Options_Status = 8;
+#[doc = " A status code for option functions."]
+pub type LV2_Options_Status = i32;
+#[doc = "Interface for dynamically setting options (LV2_OPTIONS__interface)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Options_Interface {
+    #[doc = "Get the given options."]
+    #[doc = ""]
+    #[doc = "Each element of the passed options array MUST have type, subject, and"]
+    #[doc = "key set.  All other fields (size, type, value) MUST be initialised to"]
+    #[doc = "zero, and are set to the option value if such an option is found."]
+    #[doc = ""]
+    #[doc = "This function is in the \"instantiation\" LV2 threading class, so no other"]
+    #[doc = "instance functions may be called concurrently."]
+    #[doc = ""]
+    #[doc = "@return Bitwise OR of LV2_Options_Status values."]
+    pub get: ::std::option::Option<
+        unsafe extern "C" fn(instance: LV2_Handle, options: *mut LV2_Options_Option) -> u32,
+    >,
+    #[doc = "Set the given options."]
+    #[doc = ""]
+    #[doc = "This function is in the \"instantiation\" LV2 threading class, so no other"]
+    #[doc = "instance functions may be called concurrently."]
+    #[doc = ""]
+    #[doc = "@return Bitwise OR of LV2_Options_Status values."]
+    pub set: ::std::option::Option<
+        unsafe extern "C" fn(instance: LV2_Handle, options: *const LV2_Options_Option) -> u32,
+    >,
+}
+#[doc = "< Completed successfully."]
+pub const LV2_Resize_Port_Status_LV2_RESIZE_PORT_SUCCESS: LV2_Resize_Port_Status = 0;
+#[doc = "< Unknown error."]
+pub const LV2_Resize_Port_Status_LV2_RESIZE_PORT_ERR_UNKNOWN: LV2_Resize_Port_Status = 1;
+#[doc = "< Insufficient space."]
+pub const LV2_Resize_Port_Status_LV2_RESIZE_PORT_ERR_NO_SPACE: LV2_Resize_Port_Status = 2;
+#[doc = " A status code for state functions."]
+pub type LV2_Resize_Port_Status = i32;
+#[doc = " Opaque data for resize method."]
+pub type LV2_Resize_Port_Feature_Data = *mut ::std::os::raw::c_void;
+#[doc = " Host feature to allow plugins to resize their port buffers."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Resize_Port_Resize {
+    #[doc = " Opaque data for resize method."]
+    pub data: LV2_Resize_Port_Feature_Data,
+    #[doc = "Resize a port buffer to at least `size` bytes."]
+    #[doc = ""]
+    #[doc = "This function MAY return an error, in which case the port buffer was not"]
+    #[doc = "resized and the port is still connected to the same location.  Plugins"]
+    #[doc = "MUST gracefully handle this situation."]
+    #[doc = ""]
+    #[doc = "This function is in the audio threading class."]
+    #[doc = ""]
+    #[doc = "The host MUST preserve the contents of the port buffer when resizing."]
+    #[doc = ""]
+    #[doc = "Plugins MAY resize a port many times in a single run callback.  Hosts"]
+    #[doc = "SHOULD make this as inexpensive as possible."]
+    pub resize: ::std::option::Option<
+        unsafe extern "C" fn(
+            data: LV2_Resize_Port_Feature_Data,
+            index: u32,
+            size: usize,
+        ) -> LV2_Resize_Port_Status,
+    >,
+}
+pub type LV2_State_Handle = *mut ::std::os::raw::c_void;
+pub type LV2_State_Free_Path_Handle = *mut ::std::os::raw::c_void;
+pub type LV2_State_Map_Path_Handle = *mut ::std::os::raw::c_void;
+pub type LV2_State_Make_Path_Handle = *mut ::std::os::raw::c_void;
+impl LV2_State_Flags {
+    #[doc = "Plain Old Data."]
+    #[doc = ""]
+    #[doc = "Values with this flag contain no pointers or references to other areas"]
+    #[doc = "of memory.  It is safe to copy POD values with a simple memcpy and store"]
+    #[doc = "them for the duration of the process.  A POD value is not necessarily"]
+    #[doc = "safe to trasmit between processes or machines (for example, filenames"]
+    #[doc = "are POD), see LV2_STATE_IS_PORTABLE for details."]
+    #[doc = ""]
+    #[doc = "Implementations MUST NOT attempt to copy or serialise a non-POD value if"]
+    #[doc = "they do not understand its type (and thus know how to correctly do so)."]
+    pub const LV2_STATE_IS_POD: LV2_State_Flags = LV2_State_Flags(1);
+}
+impl LV2_State_Flags {
+    #[doc = "Portable (architecture independent) data."]
+    #[doc = ""]
+    #[doc = "Values with this flag are in a format that is usable on any"]
+    #[doc = "architecture.  A portable value saved on one machine can be restored on"]
+    #[doc = "another machine regardless of architecture.  The format of portable"]
+    #[doc = "values MUST NOT depend on architecture-specific properties like"]
+    #[doc = "endianness or alignment.  Portable values MUST NOT contain filenames."]
+    pub const LV2_STATE_IS_PORTABLE: LV2_State_Flags = LV2_State_Flags(2);
+}
+impl LV2_State_Flags {
+    #[doc = "Native data."]
+    #[doc = ""]
+    #[doc = "This flag is used by the host to indicate that the saved data is only"]
+    #[doc = "going to be used locally in the currently running process (for things"]
+    #[doc = "like instance duplication or snapshots), so the plugin should use the"]
+    #[doc = "most efficient representation possible and not worry about serialisation"]
+    #[doc = "and portability."]
+    pub const LV2_STATE_IS_NATIVE: LV2_State_Flags = LV2_State_Flags(4);
+}
+impl ::std::ops::BitOr<LV2_State_Flags> for LV2_State_Flags {
+    type Output = Self;
+    #[inline]
+    fn bitor(self, other: Self) -> Self {
+        LV2_State_Flags(self.0 | other.0)
+    }
+}
+impl ::std::ops::BitOrAssign for LV2_State_Flags {
+    #[inline]
+    fn bitor_assign(&mut self, rhs: LV2_State_Flags) {
+        self.0 |= rhs.0;
+    }
+}
+impl ::std::ops::BitAnd<LV2_State_Flags> for LV2_State_Flags {
+    type Output = Self;
+    #[inline]
+    fn bitand(self, other: Self) -> Self {
+        LV2_State_Flags(self.0 & other.0)
+    }
+}
+impl ::std::ops::BitAndAssign for LV2_State_Flags {
+    #[inline]
+    fn bitand_assign(&mut self, rhs: LV2_State_Flags) {
+        self.0 &= rhs.0;
+    }
+}
+#[repr(transparent)]
+#[doc = "Flags describing value characteristics."]
+#[doc = ""]
+#[doc = "These flags are used along with the value's type URI to determine how to"]
+#[doc = "(de-)serialise the value data, or whether it is even possible to do so."]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct LV2_State_Flags(pub i32);
+#[doc = "< Completed successfully."]
+pub const LV2_State_Status_LV2_STATE_SUCCESS: LV2_State_Status = 0;
+#[doc = "< Unknown error."]
+pub const LV2_State_Status_LV2_STATE_ERR_UNKNOWN: LV2_State_Status = 1;
+#[doc = "< Failed due to unsupported type."]
+pub const LV2_State_Status_LV2_STATE_ERR_BAD_TYPE: LV2_State_Status = 2;
+#[doc = "< Failed due to unsupported flags."]
+pub const LV2_State_Status_LV2_STATE_ERR_BAD_FLAGS: LV2_State_Status = 3;
+#[doc = "< Failed due to missing features."]
+pub const LV2_State_Status_LV2_STATE_ERR_NO_FEATURE: LV2_State_Status = 4;
+#[doc = "< Failed due to missing property."]
+pub const LV2_State_Status_LV2_STATE_ERR_NO_PROPERTY: LV2_State_Status = 5;
+#[doc = "< Failed due to insufficient space."]
+pub const LV2_State_Status_LV2_STATE_ERR_NO_SPACE: LV2_State_Status = 6;
+#[doc = " A status code for state functions."]
+pub type LV2_State_Status = i32;
+#[doc = "A host-provided function to store a property."]
+#[doc = "@param handle Must be the handle passed to LV2_State_Interface.save()."]
+#[doc = "@param key The key to store `value` under (URID)."]
+#[doc = "@param value Pointer to the value to be stored."]
+#[doc = "@param size The size of `value` in bytes."]
+#[doc = "@param type The type of `value` (URID)."]
+#[doc = "@param flags LV2_State_Flags for `value`."]
+#[doc = "@return 0 on success, otherwise a non-zero error code."]
+#[doc = ""]
+#[doc = "The host passes a callback of this type to LV2_State_Interface.save(). This"]
+#[doc = "callback is called repeatedly by the plugin to store all the properties that"]
+#[doc = "describe its current state."]
+#[doc = ""]
+#[doc = "DO NOT INVENT NONSENSE URI SCHEMES FOR THE KEY.  Best is to use keys from"]
+#[doc = "existing vocabularies.  If nothing appropriate is available, use http URIs"]
+#[doc = "that point to somewhere you can host documents so documentation can be made"]
+#[doc = "resolvable (typically a child of the plugin or project URI).  If this is not"]
+#[doc = "possible, invent a URN scheme, e.g. urn:myproj:whatever.  The plugin MUST"]
+#[doc = "NOT pass an invalid URI key."]
+#[doc = ""]
+#[doc = "The host MAY fail to store a property for whatever reason, but SHOULD"]
+#[doc = "store any property that is LV2_STATE_IS_POD and LV2_STATE_IS_PORTABLE."]
+#[doc = "Implementations SHOULD use the types from the LV2 Atom extension"]
+#[doc = "(http://lv2plug.in/ns/ext/atom) wherever possible.  The plugin SHOULD"]
+#[doc = "attempt to fall-back and avoid the error if possible."]
+#[doc = ""]
+#[doc = "Note that `size` MUST be > 0, and `value` MUST point to a valid region of"]
+#[doc = "memory `size` bytes long (this is required to make restore unambiguous)."]
+#[doc = ""]
+#[doc = "The plugin MUST NOT attempt to use this function outside of the"]
+#[doc = "LV2_State_Interface.restore() context."]
+pub type LV2_State_Store_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_State_Handle,
+        key: u32,
+        value: *const ::std::os::raw::c_void,
+        size: usize,
+        type_: u32,
+        flags: u32,
+    ) -> LV2_State_Status,
+>;
+#[doc = "A host-provided function to retrieve a property."]
+#[doc = "@param handle Must be the handle passed to LV2_State_Interface.restore()."]
+#[doc = "@param key The key of the property to retrieve (URID)."]
+#[doc = "@param size (Output) If non-NULL, set to the size of the restored value."]
+#[doc = "@param type (Output) If non-NULL, set to the type of the restored value."]
+#[doc = "@param flags (Output) If non-NULL, set to the flags for the restored value."]
+#[doc = "@return A pointer to the restored value (object), or NULL if no value"]
+#[doc = "has been stored under `key`."]
+#[doc = ""]
+#[doc = "A callback of this type is passed by the host to"]
+#[doc = "LV2_State_Interface.restore().  This callback is called repeatedly by the"]
+#[doc = "plugin to retrieve any properties it requires to restore its state."]
+#[doc = ""]
+#[doc = "The returned value MUST remain valid until LV2_State_Interface.restore()"]
+#[doc = "returns.  The plugin MUST NOT attempt to use this function, or any value"]
+#[doc = "returned from it, outside of the LV2_State_Interface.restore() context."]
+pub type LV2_State_Retrieve_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_State_Handle,
+        key: u32,
+        size: *mut usize,
+        type_: *mut u32,
+        flags: *mut u32,
+    ) -> *const ::std::os::raw::c_void,
+>;
+#[doc = "LV2 Plugin State Interface."]
+#[doc = ""]
+#[doc = "When the plugin's extension_data is called with argument"]
+#[doc = "LV2_STATE__interface, the plugin MUST return an LV2_State_Interface"]
+#[doc = "structure, which remains valid for the lifetime of the plugin."]
+#[doc = ""]
+#[doc = "The host can use the contained function pointers to save and restore the"]
+#[doc = "state of a plugin instance at any time, provided the threading restrictions"]
+#[doc = "of the functions are met."]
+#[doc = ""]
+#[doc = "Stored data is only guaranteed to be compatible between instances of plugins"]
+#[doc = "with the same URI (i.e. if a change to a plugin would cause a fatal error"]
+#[doc = "when restoring state saved by a previous version of that plugin, the plugin"]
+#[doc = "URI MUST change just as it must when ports change incompatibly).  Plugin"]
+#[doc = "authors should consider this possibility, and always store sensible data"]
+#[doc = "with meaningful types to avoid such problems in the future."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_State_Interface {
+    #[doc = "Save plugin state using a host-provided `store` callback."]
+    #[doc = ""]
+    #[doc = "@param instance The instance handle of the plugin."]
+    #[doc = "@param store The host-provided store callback."]
+    #[doc = "@param handle An opaque pointer to host data which MUST be passed as the"]
+    #[doc = "handle parameter to `store` if it is called."]
+    #[doc = "@param flags Flags describing desired properties of this save.  These"]
+    #[doc = "flags may be used to determine the most appropriate values to store."]
+    #[doc = "@param features Extensible parameter for passing any additional"]
+    #[doc = "features to be used for this save."]
+    #[doc = ""]
+    #[doc = "The plugin is expected to store everything necessary to completely"]
+    #[doc = "restore its state later.  Plugins SHOULD store simple POD data whenever"]
+    #[doc = "possible, and consider the possibility of state being restored much"]
+    #[doc = "later on a different machine."]
+    #[doc = ""]
+    #[doc = "The `handle` pointer and `store` function MUST NOT be used"]
+    #[doc = "beyond the scope of save()."]
+    #[doc = ""]
+    #[doc = "This function has its own special threading class: it may not be called"]
+    #[doc = "concurrently with any \"Instantiation\" function, but it may be called"]
+    #[doc = "concurrently with functions in any other class, unless the definition of"]
+    #[doc = "that class prohibits it (for example, it may not be called concurrently"]
+    #[doc = "with a \"Discovery\" function, but it may be called concurrently with an"]
+    #[doc = "\"Audio\" function.  The plugin is responsible for any locking or"]
+    #[doc = "lock-free techniques necessary to make this possible."]
+    #[doc = ""]
+    #[doc = "Note that in the simple case where state is only modified by restore(),"]
+    #[doc = "there are no synchronization issues since save() is never called"]
+    #[doc = "concurrently with restore() (though run() may read it during a save)."]
+    #[doc = ""]
+    #[doc = "Plugins that dynamically modify state while running, however, must take"]
+    #[doc = "care to do so in such a way that a concurrent call to save() will save a"]
+    #[doc = "consistent representation of plugin state for a single instant in time."]
+    pub save: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            store: LV2_State_Store_Function,
+            handle: LV2_State_Handle,
+            flags: u32,
+            features: *const *const LV2_Feature,
+        ) -> LV2_State_Status,
+    >,
+    #[doc = "Restore plugin state using a host-provided `retrieve` callback."]
+    #[doc = ""]
+    #[doc = "@param instance The instance handle of the plugin."]
+    #[doc = "@param retrieve The host-provided retrieve callback."]
+    #[doc = "@param handle An opaque pointer to host data which MUST be passed as the"]
+    #[doc = "handle parameter to `retrieve` if it is called."]
+    #[doc = "@param flags Currently unused."]
+    #[doc = "@param features Extensible parameter for passing any additional"]
+    #[doc = "features to be used for this restore."]
+    #[doc = ""]
+    #[doc = "The plugin MAY assume a restored value was set by a previous call to"]
+    #[doc = "LV2_State_Interface.save() by a plugin with the same URI."]
+    #[doc = ""]
+    #[doc = "The plugin MUST gracefully fall back to a default value when a value can"]
+    #[doc = "not be retrieved.  This allows the host to reset the plugin state with"]
+    #[doc = "an empty map."]
+    #[doc = ""]
+    #[doc = "The `handle` pointer and `store` function MUST NOT be used"]
+    #[doc = "beyond the scope of restore()."]
+    #[doc = ""]
+    #[doc = "This function is in the \"Instantiation\" threading class as defined by"]
+    #[doc = "LV2. This means it MUST NOT be called concurrently with any other"]
+    #[doc = "function on the same plugin instance."]
+    pub restore: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            retrieve: LV2_State_Retrieve_Function,
+            handle: LV2_State_Handle,
+            flags: u32,
+            features: *const *const LV2_Feature,
+        ) -> LV2_State_Status,
+    >,
+}
+#[doc = "Feature data for state:mapPath (@ref LV2_STATE__mapPath)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_State_Map_Path {
+    #[doc = "Opaque host data."]
+    pub handle: LV2_State_Map_Path_Handle,
+    #[doc = "Map an absolute path to an abstract path for use in plugin state."]
+    #[doc = "@param handle MUST be the `handle` member of this struct."]
+    #[doc = "@param absolute_path The absolute path of a file."]
+    #[doc = "@return An abstract path suitable for use in plugin state."]
+    #[doc = ""]
+    #[doc = "The plugin MUST use this function to map any paths that will be stored"]
+    #[doc = "in plugin state.  The returned value is an abstract path which MAY not"]
+    #[doc = "be an actual file system path; absolute_path() MUST be used to map"]
+    #[doc = "it to an actual path in order to use the file."]
+    #[doc = ""]
+    #[doc = "Plugins MUST NOT make any assumptions about abstract paths except that"]
+    #[doc = "they can be mapped back to the absolute path of the \"same\" file (though"]
+    #[doc = "not necessarily the same original path) using absolute_path()."]
+    #[doc = ""]
+    #[doc = "This function may only be called within the context of"]
+    #[doc = "LV2_State_Interface methods.  The caller must free the returned value"]
+    #[doc = "with LV2_State_Free_Path.free_path()."]
+    pub abstract_path: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_State_Map_Path_Handle,
+            absolute_path: *const ::std::os::raw::c_char,
+        ) -> *mut ::std::os::raw::c_char,
+    >,
+    #[doc = "Map an abstract path from plugin state to an absolute path."]
+    #[doc = "@param handle MUST be the `handle` member of this struct."]
+    #[doc = "@param abstract_path An abstract path (typically from plugin state)."]
+    #[doc = "@return An absolute file system path."]
+    #[doc = ""]
+    #[doc = "The plugin MUST use this function in order to actually open or otherwise"]
+    #[doc = "use any paths loaded from plugin state."]
+    #[doc = ""]
+    #[doc = "This function may only be called within the context of"]
+    #[doc = "LV2_State_Interface methods.  The caller must free the returned value"]
+    #[doc = "with LV2_State_Free_Path.free_path()."]
+    pub absolute_path: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_State_Map_Path_Handle,
+            abstract_path: *const ::std::os::raw::c_char,
+        ) -> *mut ::std::os::raw::c_char,
+    >,
+}
+#[doc = "Feature data for state:makePath (@ref LV2_STATE__makePath)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_State_Make_Path {
+    #[doc = "Opaque host data."]
+    pub handle: LV2_State_Make_Path_Handle,
+    #[doc = "Return a path the plugin may use to create a new file."]
+    #[doc = "@param handle MUST be the `handle` member of this struct."]
+    #[doc = "@param path The path of the new file within a namespace unique to this"]
+    #[doc = "plugin instance."]
+    #[doc = "@return The absolute path to use for the new file."]
+    #[doc = ""]
+    #[doc = "This function can be used by plugins to create files and directories,"]
+    #[doc = "either at state saving time (if this feature is passed to"]
+    #[doc = "LV2_State_Interface.save()) or any time (if this feature is passed to"]
+    #[doc = "LV2_Descriptor.instantiate())."]
+    #[doc = ""]
+    #[doc = "The host MUST do whatever is necessary for the plugin to be able to"]
+    #[doc = "create a file at the returned path (for example, using fopen()),"]
+    #[doc = "including creating any leading directories."]
+    #[doc = ""]
+    #[doc = "If this function is passed to LV2_Descriptor.instantiate(), it may be"]
+    #[doc = "called from any non-realtime context.  If it is passed to"]
+    #[doc = "LV2_State_Interface.save(), it may only be called within the dynamic"]
+    #[doc = "scope of that function call."]
+    #[doc = ""]
+    #[doc = "The caller must free the returned value with"]
+    #[doc = "LV2_State_Free_Path.free_path()."]
+    pub path: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_State_Make_Path_Handle,
+            path: *const ::std::os::raw::c_char,
+        ) -> *mut ::std::os::raw::c_char,
+    >,
+}
+#[doc = "Feature data for state:freePath (@ref LV2_STATE__freePath)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_State_Free_Path {
+    #[doc = "Opaque host data."]
+    pub handle: LV2_State_Free_Path_Handle,
+    #[doc = "Free a path returned by a state feature."]
+    #[doc = ""]
+    #[doc = "@param handle MUST be the `handle` member of this struct."]
+    #[doc = "@param path The path previously returned by a state feature."]
+    #[doc = ""]
+    #[doc = "This function can be used by plugins to free paths allocated by the host"]
+    #[doc = "and returned by state features (LV2_State_Map_Path.abstract_path(),"]
+    #[doc = "LV2_State_Map_Path.absolute_path(), and LV2_State_Make_Path.path())."]
+    pub free_path: ::std::option::Option<
+        unsafe extern "C" fn(handle: LV2_State_Free_Path_Handle, path: *mut ::std::os::raw::c_char),
+    >,
+}
+#[doc = "A pointer to some widget or other type of UI handle."]
+#[doc = ""]
+#[doc = "The actual type is defined by the type of the UI."]
+pub type LV2UI_Widget = *mut ::std::os::raw::c_void;
+#[doc = "A pointer to UI instance internals."]
+#[doc = ""]
+#[doc = "The host may compare this to NULL, but otherwise MUST NOT interpret it."]
+pub type LV2UI_Handle = *mut ::std::os::raw::c_void;
+#[doc = "A pointer to a controller provided by the host."]
+#[doc = ""]
+#[doc = "The UI may compare this to NULL, but otherwise MUST NOT interpret it."]
+pub type LV2UI_Controller = *mut ::std::os::raw::c_void;
+#[doc = "A pointer to opaque data for a feature."]
+pub type LV2UI_Feature_Handle = *mut ::std::os::raw::c_void;
+#[doc = "A host-provided function that sends data to a plugin's input ports."]
+#[doc = ""]
+#[doc = "@param controller The opaque controller pointer passed to"]
+#[doc = "LV2UI_Descriptor::instantiate()."]
+#[doc = ""]
+#[doc = "@param port_index Index of the port to update."]
+#[doc = ""]
+#[doc = "@param buffer Buffer containing `buffer_size` bytes of data."]
+#[doc = ""]
+#[doc = "@param buffer_size Size of `buffer` in bytes."]
+#[doc = ""]
+#[doc = "@param port_protocol Either 0 or the URID for a ui:PortProtocol.  If 0, the"]
+#[doc = "protocol is implicitly ui:floatProtocol, the port MUST be an lv2:ControlPort"]
+#[doc = "input, `buffer` MUST point to a single float value, and `buffer_size` MUST"]
+#[doc = "be sizeof(float).  The UI SHOULD NOT use a protocol not supported by the"]
+#[doc = "host, but the host MUST gracefully ignore any protocol it does not"]
+#[doc = "understand."]
+pub type LV2UI_Write_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        controller: LV2UI_Controller,
+        port_index: u32,
+        buffer_size: u32,
+        port_protocol: u32,
+        buffer: *const ::std::os::raw::c_void,
+    ),
+>;
+#[doc = "A plugin UI."]
+#[doc = ""]
+#[doc = "A pointer to an object of this type is returned by the lv2ui_descriptor()"]
+#[doc = "function."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Descriptor {
+    #[doc = "The URI for this UI (not for the plugin it controls)."]
+    pub URI: *const ::std::os::raw::c_char,
+    #[doc = "Create a new UI and return a handle to it.  This function works"]
+    #[doc = "similarly to LV2_Descriptor::instantiate()."]
+    #[doc = ""]
+    #[doc = "@param descriptor The descriptor for the UI to instantiate."]
+    #[doc = ""]
+    #[doc = "@param plugin_uri The URI of the plugin that this UI will control."]
+    #[doc = ""]
+    #[doc = "@param bundle_path The path to the bundle containing this UI, including"]
+    #[doc = "the trailing directory separator."]
+    #[doc = ""]
+    #[doc = "@param write_function A function that the UI can use to send data to the"]
+    #[doc = "plugin's input ports."]
+    #[doc = ""]
+    #[doc = "@param controller A handle for the UI instance to be passed as the"]
+    #[doc = "first parameter of UI methods."]
+    #[doc = ""]
+    #[doc = "@param widget (output) widget pointer.  The UI points this at its main"]
+    #[doc = "widget, which has the type defined by the UI type in the data file."]
+    #[doc = ""]
+    #[doc = "@param features An array of LV2_Feature pointers.  The host must pass"]
+    #[doc = "all feature URIs that it and the UI supports and any additional data, as"]
+    #[doc = "in LV2_Descriptor::instantiate().  Note that UI features and plugin"]
+    #[doc = "features are not necessarily the same."]
+    #[doc = ""]
+    pub instantiate: ::std::option::Option<
+        unsafe extern "C" fn(
+            descriptor: *const LV2UI_Descriptor,
+            plugin_uri: *const ::std::os::raw::c_char,
+            bundle_path: *const ::std::os::raw::c_char,
+            write_function: LV2UI_Write_Function,
+            controller: LV2UI_Controller,
+            widget: *mut LV2UI_Widget,
+            features: *const *const LV2_Feature,
+        ) -> LV2UI_Handle,
+    >,
+    #[doc = "Destroy the UI.  The host must not try to access the widget after"]
+    #[doc = "calling this function."]
+    pub cleanup: ::std::option::Option<unsafe extern "C" fn(ui: LV2UI_Handle)>,
+    #[doc = "Tell the UI that something interesting has happened at a plugin port."]
+    #[doc = ""]
+    #[doc = "What is \"interesting\" and how it is written to `buffer` is defined by"]
+    #[doc = "`format`, which has the same meaning as in LV2UI_Write_Function()."]
+    #[doc = "Format 0 is a special case for lv2:ControlPort, where this function"]
+    #[doc = "should be called when the port value changes (but not necessarily for"]
+    #[doc = "every change), `buffer_size` must be sizeof(float), and `buffer`"]
+    #[doc = "points to a single IEEE-754 float."]
+    #[doc = ""]
+    #[doc = "By default, the host should only call this function for lv2:ControlPort"]
+    #[doc = "inputs.  However, the UI can request updates for other ports statically"]
+    #[doc = "with ui:portNotification or dynamicaly with ui:portSubscribe."]
+    #[doc = ""]
+    #[doc = "The UI MUST NOT retain any reference to `buffer` after this function"]
+    #[doc = "returns, it is only valid for the duration of the call."]
+    #[doc = ""]
+    #[doc = "This member may be NULL if the UI is not interested in any port events."]
+    pub port_event: ::std::option::Option<
+        unsafe extern "C" fn(
+            ui: LV2UI_Handle,
+            port_index: u32,
+            buffer_size: u32,
+            format: u32,
+            buffer: *const ::std::os::raw::c_void,
+        ),
+    >,
+    #[doc = "Return a data structure associated with an extension URI, typically an"]
+    #[doc = "interface struct with additional function pointers"]
+    #[doc = ""]
+    #[doc = "This member may be set to NULL if the UI is not interested in supporting"]
+    #[doc = "any extensions. This is similar to LV2_Descriptor::extension_data()."]
+    #[doc = ""]
+    pub extension_data: ::std::option::Option<
+        unsafe extern "C" fn(uri: *const ::std::os::raw::c_char) -> *const ::std::os::raw::c_void,
+    >,
+}
+#[doc = "Feature/interface for resizable UIs (LV2_UI__resize)."]
+#[doc = ""]
+#[doc = "This structure is used in two ways: as a feature passed by the host via"]
+#[doc = "LV2UI_Descriptor::instantiate(), or as an interface provided by a UI via"]
+#[doc = "LV2UI_Descriptor::extension_data())."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Resize {
+    #[doc = "Pointer to opaque data which must be passed to ui_resize()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Request/advertise a size change."]
+    #[doc = ""]
+    #[doc = "When provided by the host, the UI may call this function to inform the"]
+    #[doc = "host about the size of the UI."]
+    #[doc = ""]
+    #[doc = "When provided by the UI, the host may call this function to notify the"]
+    #[doc = "UI that it should change its size accordingly.  In this case, the host"]
+    #[doc = "must pass the LV2UI_Handle to provide access to the UI instance."]
+    #[doc = ""]
+    #[doc = "@return 0 on success."]
+    pub ui_resize: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            width: ::std::os::raw::c_int,
+            height: ::std::os::raw::c_int,
+        ) -> ::std::os::raw::c_int,
+    >,
+}
+#[doc = "Feature to map port symbols to UIs."]
+#[doc = ""]
+#[doc = "This can be used by the UI to get the index for a port with the given"]
+#[doc = "symbol.  This makes it possible to implement and distribute a UI separately"]
+#[doc = "from the plugin (since symbol, unlike index, is a stable port identifier)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Port_Map {
+    #[doc = "Pointer to opaque data which must be passed to port_index()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Get the index for the port with the given `symbol`."]
+    #[doc = ""]
+    #[doc = "@return The index of the port, or LV2UI_INVALID_PORT_INDEX if no such"]
+    #[doc = "port is found."]
+    pub port_index: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            symbol: *const ::std::os::raw::c_char,
+        ) -> u32,
+    >,
+}
+#[doc = "Feature to subscribe to port updates (LV2_UI__portSubscribe)."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Port_Subscribe {
+    #[doc = "Pointer to opaque data which must be passed to subscribe() and"]
+    #[doc = "unsubscribe()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Subscribe to updates for a port."]
+    #[doc = ""]
+    #[doc = "This means that the host will call the UI's port_event() function when"]
+    #[doc = "the port value changes (as defined by protocol)."]
+    #[doc = ""]
+    #[doc = "Calling this function with the same `port_index` and `port_protocol`"]
+    #[doc = "as an already active subscription has no effect."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = "@param port_index The index of the port."]
+    #[doc = "@param port_protocol The URID of the ui:PortProtocol."]
+    #[doc = "@param features Features for this subscription."]
+    #[doc = "@return 0 on success."]
+    pub subscribe: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            port_index: u32,
+            port_protocol: u32,
+            features: *const *const LV2_Feature,
+        ) -> u32,
+    >,
+    #[doc = "Unsubscribe from updates for a port."]
+    #[doc = ""]
+    #[doc = "This means that the host will cease calling calling port_event() when"]
+    #[doc = "the port value changes."]
+    #[doc = ""]
+    #[doc = "Calling this function with a `port_index` and `port_protocol` that"]
+    #[doc = "does not refer to an active port subscription has no effect."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = "@param port_index The index of the port."]
+    #[doc = "@param port_protocol The URID of the ui:PortProtocol."]
+    #[doc = "@param features Features for this subscription."]
+    #[doc = "@return 0 on success."]
+    pub unsubscribe: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            port_index: u32,
+            port_protocol: u32,
+            features: *const *const LV2_Feature,
+        ) -> u32,
+    >,
+}
+#[doc = "A feature to notify the host that the user has grabbed a UI control."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Touch {
+    #[doc = "Pointer to opaque data which must be passed to ui_resize()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Notify the host that a control has been grabbed or released."]
+    #[doc = ""]
+    #[doc = "The host should cease automating the port or otherwise manipulating the"]
+    #[doc = "port value until the control has been ungrabbed."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = "@param port_index The index of the port associated with the control."]
+    #[doc = "@param grabbed If true, the control has been grabbed, otherwise the"]
+    #[doc = "control has been released."]
+    pub touch: ::std::option::Option<
+        unsafe extern "C" fn(handle: LV2UI_Feature_Handle, port_index: u32, grabbed: bool),
+    >,
+}
+#[doc = "Completed successfully."]
+#[doc = ""]
+#[doc = "The host will set the parameter later if the user choses a new value."]
+pub const LV2UI_Request_Value_Status_LV2UI_REQUEST_VALUE_SUCCESS: LV2UI_Request_Value_Status = 0;
+#[doc = "Parameter already being requested."]
+#[doc = ""]
+#[doc = "The host is already requesting a parameter from the user (for example, a"]
+#[doc = "dialog is visible), or the UI is otherwise busy and can not make this"]
+#[doc = "request."]
+pub const LV2UI_Request_Value_Status_LV2UI_REQUEST_VALUE_BUSY: LV2UI_Request_Value_Status = 1;
+#[doc = "Unknown parameter."]
+#[doc = ""]
+#[doc = "The host is not aware of this parameter, and is not able to set a new"]
+#[doc = "value for it."]
+pub const LV2UI_Request_Value_Status_LV2UI_REQUEST_VALUE_ERR_UNKNOWN: LV2UI_Request_Value_Status =
+    2;
+#[doc = "Unsupported parameter."]
+#[doc = ""]
+#[doc = "The host knows about this parameter, but does not support requesting a"]
+#[doc = "new value for it from the user.  This is likely because the host does"]
+#[doc = "not have UI support for choosing a value with the appropriate type."]
+pub const LV2UI_Request_Value_Status_LV2UI_REQUEST_VALUE_ERR_UNSUPPORTED:
+    LV2UI_Request_Value_Status = 3;
+#[doc = "A status code for LV2UI_Request_Value::request()."]
+pub type LV2UI_Request_Value_Status = i32;
+#[doc = "A feature to request a new parameter value from the host."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Request_Value {
+    #[doc = "Pointer to opaque data which must be passed to request()."]
+    pub handle: LV2UI_Feature_Handle,
+    #[doc = "Request a value for a parameter from the host."]
+    #[doc = ""]
+    #[doc = "This is mainly used by UIs to request values for complex parameters that"]
+    #[doc = "don't change often, such as file paths, but it may be used to request"]
+    #[doc = "any parameter value."]
+    #[doc = ""]
+    #[doc = "This function returns immediately, and the return value indicates"]
+    #[doc = "whether the host can fulfill the request.  The host may notify the"]
+    #[doc = "plugin about the new parameter value, for example when a file is"]
+    #[doc = "selected by the user, via the usual mechanism.  Typically, the host will"]
+    #[doc = "send a message to the plugin that sets the new parameter value, and the"]
+    #[doc = "plugin will notify the UI via a message as usual for any other parameter"]
+    #[doc = "change."]
+    #[doc = ""]
+    #[doc = "To provide an appropriate UI, the host can determine details about the"]
+    #[doc = "parameter from the plugin data as usual.  The additional parameters of"]
+    #[doc = "this function provide support for more advanced use cases, but in the"]
+    #[doc = "simple common case, the plugin will simply pass the key of the desired"]
+    #[doc = "parameter and zero for everything else."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = ""]
+    #[doc = "@param key The URID of the parameter."]
+    #[doc = ""]
+    #[doc = "@param type The optional type of the value to request.  This can be used"]
+    #[doc = "to request a specific value type for parameters that support several."]
+    #[doc = "If non-zero, it must be the URID of an instance of rdfs:Class or"]
+    #[doc = "rdfs:Datatype."]
+    #[doc = ""]
+    #[doc = "@param features Additional features for this request, or NULL."]
+    #[doc = ""]
+    #[doc = "@return A status code which is 0 on success."]
+    pub request: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2UI_Feature_Handle,
+            key: LV2_URID,
+            type_: LV2_URID,
+            features: *const *const LV2_Feature,
+        ) -> LV2UI_Request_Value_Status,
+    >,
+}
+#[doc = "UI Idle Interface (LV2_UI__idleInterface)"]
+#[doc = ""]
+#[doc = "UIs can provide this interface to have an idle() callback called by the host"]
+#[doc = "rapidly to update the UI."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Idle_Interface {
+    #[doc = "Run a single iteration of the UI's idle loop."]
+    #[doc = ""]
+    #[doc = "This will be called rapidly in the UI thread at a rate appropriate"]
+    #[doc = "for a toolkit main loop.  There are no precise timing guarantees, but"]
+    #[doc = "the host should attempt to call idle() at a high enough rate for smooth"]
+    #[doc = "animation, at least 30Hz."]
+    #[doc = ""]
+    #[doc = "@return non-zero if the UI has been closed, in which case the host"]
+    #[doc = "should stop calling idle(), and can either completely destroy the UI, or"]
+    #[doc = "re-show it and resume calling idle()."]
+    pub idle:
+        ::std::option::Option<unsafe extern "C" fn(ui: LV2UI_Handle) -> ::std::os::raw::c_int>,
+}
+#[doc = "UI Show Interface (LV2_UI__showInterface)"]
+#[doc = ""]
+#[doc = "UIs can provide this interface to show and hide a window, which allows them"]
+#[doc = "to function in hosts unable to embed their widget.  This allows any UI to"]
+#[doc = "provide a fallback for embedding that works in any host."]
+#[doc = ""]
+#[doc = "If used:"]
+#[doc = "- The host MUST use LV2UI_Idle_Interface to drive the UI."]
+#[doc = "- The UI MUST return non-zero from LV2UI_Idle_Interface::idle() when it has been closed."]
+#[doc = "- If idle() returns non-zero, the host MUST call hide() and stop calling"]
+#[doc = "idle().  It MAY later call show() then resume calling idle()."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Show_Interface {
+    #[doc = "Show a window for this UI."]
+    #[doc = ""]
+    #[doc = "The window title MAY have been passed by the host to"]
+    #[doc = "LV2UI_Descriptor::instantiate() as an LV2_Options_Option with key"]
+    #[doc = "LV2_UI__windowTitle."]
+    #[doc = ""]
+    #[doc = "@return 0 on success, or anything else to stop being called."]
+    pub show:
+        ::std::option::Option<unsafe extern "C" fn(ui: LV2UI_Handle) -> ::std::os::raw::c_int>,
+    #[doc = "Hide the window for this UI."]
+    #[doc = ""]
+    #[doc = "@return 0 on success, or anything else to stop being called."]
+    pub hide:
+        ::std::option::Option<unsafe extern "C" fn(ui: LV2UI_Handle) -> ::std::os::raw::c_int>,
+}
+#[doc = "Peak data for a slice of time, the update format for ui:peakProtocol."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2UI_Peak_Data {
+    #[doc = "The start of the measurement period.  This is just a running counter"]
+    #[doc = "that is only meaningful in comparison to previous values and must not be"]
+    #[doc = "interpreted as an absolute time."]
+    pub period_start: u32,
+    #[doc = "The size of the measurement period, in the same units as period_start."]
+    pub period_size: u32,
+    #[doc = "The peak value for the measurement period. This should be the maximal"]
+    #[doc = "value for abs(sample) over all the samples in the period."]
+    pub peak: f32,
+}
+#[doc = "The type of the lv2ui_descriptor() function."]
+pub type LV2UI_DescriptorFunction =
+    ::std::option::Option<unsafe extern "C" fn(index: u32) -> *const LV2UI_Descriptor>;
+#[doc = "Opaque pointer to host data."]
+pub type LV2_URI_Map_Callback_Data = *mut ::std::os::raw::c_void;
+#[doc = "URI Map Feature."]
+#[doc = ""]
+#[doc = "To support this feature the host must pass an LV2_Feature struct to the"]
+#[doc = "plugin's instantiate method with URI \"http://lv2plug.in/ns/ext/uri-map\""]
+#[doc = "and data pointed to an instance of this struct."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_URI_Map_Feature {
+    #[doc = "Opaque pointer to host data."]
+    #[doc = ""]
+    #[doc = "The plugin MUST pass this to any call to functions in this struct."]
+    #[doc = "Otherwise, it must not be interpreted in any way."]
+    pub callback_data: LV2_URI_Map_Callback_Data,
+    #[doc = "Get the numeric ID of a URI from the host."]
+    #[doc = ""]
+    #[doc = "@param callback_data Must be the callback_data member of this struct."]
+    #[doc = "@param map The 'context' of this URI. Certain extensions may define a"]
+    #[doc = "URI that must be passed here with certain restrictions on the return"]
+    #[doc = "value (e.g. limited range). This value may be NULL if the plugin needs"]
+    #[doc = "an ID for a URI in general. Extensions SHOULD NOT define a context"]
+    #[doc = "unless there is a specific need to do so, e.g. to restrict the range of"]
+    #[doc = "the returned value."]
+    #[doc = "@param uri The URI to be mapped to an integer ID."]
+    #[doc = ""]
+    #[doc = "This function is referentially transparent; any number of calls with the"]
+    #[doc = "same arguments is guaranteed to return the same value over the life of a"]
+    #[doc = "plugin instance (though the same URI may return different values with a"]
+    #[doc = "different map parameter). However, this function is not necessarily very"]
+    #[doc = "fast: plugins SHOULD cache any IDs they might need in performance"]
+    #[doc = "critical situations."]
+    #[doc = ""]
+    #[doc = "The return value 0 is reserved and indicates that an ID for that URI"]
+    #[doc = "could not be created for whatever reason. Extensions MAY define more"]
+    #[doc = "precisely what this means in a certain context, but in general plugins"]
+    #[doc = "SHOULD handle this situation as gracefully as possible. However, hosts"]
+    #[doc = "SHOULD NOT return 0 from this function in non-exceptional circumstances"]
+    #[doc = "(e.g. the URI map SHOULD be dynamic). Hosts that statically support only"]
+    #[doc = "a fixed set of URIs should not expect plugins to function correctly."]
+    pub uri_to_id: ::std::option::Option<
+        unsafe extern "C" fn(
+            callback_data: LV2_URI_Map_Callback_Data,
+            map: *const ::std::os::raw::c_char,
+            uri: *const ::std::os::raw::c_char,
+        ) -> u32,
+    >,
+}
+#[doc = "< Completed successfully."]
+pub const LV2_Worker_Status_LV2_WORKER_SUCCESS: LV2_Worker_Status = 0;
+#[doc = "< Unknown error."]
+pub const LV2_Worker_Status_LV2_WORKER_ERR_UNKNOWN: LV2_Worker_Status = 1;
+#[doc = "< Failed due to lack of space."]
+pub const LV2_Worker_Status_LV2_WORKER_ERR_NO_SPACE: LV2_Worker_Status = 2;
+#[doc = "Status code for worker functions."]
+pub type LV2_Worker_Status = i32;
+#[doc = " Opaque handle for LV2_Worker_Interface::work()."]
+pub type LV2_Worker_Respond_Handle = *mut ::std::os::raw::c_void;
+#[doc = "A function to respond to run() from the worker method."]
+#[doc = ""]
+#[doc = "The `data` MUST be safe for the host to copy and later pass to"]
+#[doc = "work_response(), and the host MUST guarantee that it will be eventually"]
+#[doc = "passed to work_response() if this function returns LV2_WORKER_SUCCESS."]
+pub type LV2_Worker_Respond_Function = ::std::option::Option<
+    unsafe extern "C" fn(
+        handle: LV2_Worker_Respond_Handle,
+        size: u32,
+        data: *const ::std::os::raw::c_void,
+    ) -> LV2_Worker_Status,
+>;
+#[doc = "Plugin Worker Interface."]
+#[doc = ""]
+#[doc = "This is the interface provided by the plugin to implement a worker method."]
+#[doc = "The plugin's extension_data() method should return an LV2_Worker_Interface"]
+#[doc = "when called with LV2_WORKER__interface as its argument."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Worker_Interface {
+    #[doc = "The worker method.  This is called by the host in a non-realtime context"]
+    #[doc = "as requested, possibly with an arbitrary message to handle."]
+    #[doc = ""]
+    #[doc = "A response can be sent to run() using `respond`.  The plugin MUST NOT"]
+    #[doc = "make any assumptions about which thread calls this method, except that"]
+    #[doc = "there are no real-time requirements and only one call may be executed at"]
+    #[doc = "a time.  That is, the host MAY call this method from any non-real-time"]
+    #[doc = "thread, but MUST NOT make concurrent calls to this method from several"]
+    #[doc = "threads."]
+    #[doc = ""]
+    #[doc = "@param instance The LV2 instance this is a method on."]
+    #[doc = "@param respond  A function for sending a response to run()."]
+    #[doc = "@param handle   Must be passed to `respond` if it is called."]
+    #[doc = "@param size     The size of `data`."]
+    #[doc = "@param data     Data from run(), or NULL."]
+    pub work: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            respond: LV2_Worker_Respond_Function,
+            handle: LV2_Worker_Respond_Handle,
+            size: u32,
+            data: *const ::std::os::raw::c_void,
+        ) -> LV2_Worker_Status,
+    >,
+    #[doc = "Handle a response from the worker.  This is called by the host in the"]
+    #[doc = "run() context when a response from the worker is ready."]
+    #[doc = ""]
+    #[doc = "@param instance The LV2 instance this is a method on."]
+    #[doc = "@param size     The size of `body`."]
+    #[doc = "@param body     Message body, or NULL."]
+    pub work_response: ::std::option::Option<
+        unsafe extern "C" fn(
+            instance: LV2_Handle,
+            size: u32,
+            body: *const ::std::os::raw::c_void,
+        ) -> LV2_Worker_Status,
+    >,
+    #[doc = "Called when all responses for this cycle have been delivered."]
+    #[doc = ""]
+    #[doc = "Since work_response() may be called after run() finished, this provides"]
+    #[doc = "a hook for code that must run after the cycle is completed."]
+    #[doc = ""]
+    #[doc = "This field may be NULL if the plugin has no use for it.  Otherwise, the"]
+    #[doc = "host MUST call it after every run(), regardless of whether or not any"]
+    #[doc = "responses were sent that cycle."]
+    pub end_run:
+        ::std::option::Option<unsafe extern "C" fn(instance: LV2_Handle) -> LV2_Worker_Status>,
+}
+#[doc = " Opaque handle for LV2_Worker_Schedule."]
+pub type LV2_Worker_Schedule_Handle = *mut ::std::os::raw::c_void;
+#[doc = "Schedule Worker Host Feature."]
+#[doc = ""]
+#[doc = "The host passes this feature to provide a schedule_work() function, which"]
+#[doc = "the plugin can use to schedule a worker call from run()."]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct LV2_Worker_Schedule {
+    #[doc = "Opaque host data."]
+    pub handle: LV2_Worker_Schedule_Handle,
+    #[doc = "Request from run() that the host call the worker."]
+    #[doc = ""]
+    #[doc = "This function is in the audio threading class.  It should be called from"]
+    #[doc = "run() to request that the host call the work() method in a non-realtime"]
+    #[doc = "context with the given arguments."]
+    #[doc = ""]
+    #[doc = "This function is always safe to call from run(), but it is not"]
+    #[doc = "guaranteed that the worker is actually called from a different thread."]
+    #[doc = "In particular, when free-wheeling (for example, during offline"]
+    #[doc = "rendering), the worker may be executed immediately.  This allows"]
+    #[doc = "single-threaded processing with sample accuracy and avoids timing"]
+    #[doc = "problems when run() is executing much faster or slower than real-time."]
+    #[doc = ""]
+    #[doc = "Plugins SHOULD be written in such a way that if the worker runs"]
+    #[doc = "immediately, and responses from the worker are delivered immediately,"]
+    #[doc = "the effect of the work takes place immediately with sample accuracy."]
+    #[doc = ""]
+    #[doc = "The `data` MUST be safe for the host to copy and later pass to work(),"]
+    #[doc = "and the host MUST guarantee that it will be eventually passed to work()"]
+    #[doc = "if this function returns LV2_WORKER_SUCCESS."]
+    #[doc = ""]
+    #[doc = "@param handle The handle field of this struct."]
+    #[doc = "@param size   The size of `data`."]
+    #[doc = "@param data   Message to pass to work(), or NULL."]
+    pub schedule_work: ::std::option::Option<
+        unsafe extern "C" fn(
+            handle: LV2_Worker_Schedule_Handle,
+            size: u32,
+            data: *const ::std::os::raw::c_void,
+        ) -> LV2_Worker_Status,
+    >,
+}
diff --git a/sys/tool/Cargo.toml b/sys/tool/Cargo.toml
new file mode 100644
index 00000000..3f5ec9cc
--- /dev/null
+++ b/sys/tool/Cargo.toml
@@ -0,0 +1,15 @@
+[package]
+name = "systool"
+version = "0.1.0"
+authors = ["Yruama_Lairba <yruama_lairba@hotmail.com>", "Jan-Oliver 'Janonard' Opdenhövel <jan.opdenhoevel@protonmail.com>"]
+edition = "2018"
+license = "MIT OR Apache-2.0"
+publish = false
+
+description = "Generate Rust bindings of the LV2 C API"
+readme = "README.md"
+repository = "https://github.com/RustAudio/rust-lv2"
+
+[dependencies]
+bindgen = "0.53.1"
+clap = "2.33.0"
diff --git a/sys/tool/LICENSE-APACHE b/sys/tool/LICENSE-APACHE
new file mode 100644
index 00000000..16fe87b0
--- /dev/null
+++ b/sys/tool/LICENSE-APACHE
@@ -0,0 +1,201 @@
+                              Apache License
+                        Version 2.0, January 2004
+                     http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+   "License" shall mean the terms and conditions for use, reproduction,
+   and distribution as defined by Sections 1 through 9 of this document.
+
+   "Licensor" shall mean the copyright owner or entity authorized by
+   the copyright owner that is granting the License.
+
+   "Legal Entity" shall mean the union of the acting entity and all
+   other entities that control, are controlled by, or are under common
+   control with that entity. For the purposes of this definition,
+   "control" means (i) the power, direct or indirect, to cause the
+   direction or management of such entity, whether by contract or
+   otherwise, or (ii) ownership of fifty percent (50%) or more of the
+   outstanding shares, or (iii) beneficial ownership of such entity.
+
+   "You" (or "Your") shall mean an individual or Legal Entity
+   exercising permissions granted by this License.
+
+   "Source" form shall mean the preferred form for making modifications,
+   including but not limited to software source code, documentation
+   source, and configuration files.
+
+   "Object" form shall mean any form resulting from mechanical
+   transformation or translation of a Source form, including but
+   not limited to compiled object code, generated documentation,
+   and conversions to other media types.
+
+   "Work" shall mean the work of authorship, whether in Source or
+   Object form, made available under the License, as indicated by a
+   copyright notice that is included in or attached to the work
+   (an example is provided in the Appendix below).
+
+   "Derivative Works" shall mean any work, whether in Source or Object
+   form, that is based on (or derived from) the Work and for which the
+   editorial revisions, annotations, elaborations, or other modifications
+   represent, as a whole, an original work of authorship. For the purposes
+   of this License, Derivative Works shall not include works that remain
+   separable from, or merely link (or bind by name) to the interfaces of,
+   the Work and Derivative Works thereof.
+
+   "Contribution" shall mean any work of authorship, including
+   the original version of the Work and any modifications or additions
+   to that Work or Derivative Works thereof, that is intentionally
+   submitted to Licensor for inclusion in the Work by the copyright owner
+   or by an individual or Legal Entity authorized to submit on behalf of
+   the copyright owner. For the purposes of this definition, "submitted"
+   means any form of electronic, verbal, or written communication sent
+   to the Licensor or its representatives, including but not limited to
+   communication on electronic mailing lists, source code control systems,
+   and issue tracking systems that are managed by, or on behalf of, the
+   Licensor for the purpose of discussing and improving the Work, but
+   excluding communication that is conspicuously marked or otherwise
+   designated in writing by the copyright owner as "Not a Contribution."
+
+   "Contributor" shall mean Licensor and any individual or Legal Entity
+   on behalf of whom a Contribution has been received by Licensor and
+   subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   copyright license to reproduce, prepare Derivative Works of,
+   publicly display, publicly perform, sublicense, and distribute the
+   Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   (except as stated in this section) patent license to make, have made,
+   use, offer to sell, sell, import, and otherwise transfer the Work,
+   where such license applies only to those patent claims licensable
+   by such Contributor that are necessarily infringed by their
+   Contribution(s) alone or by combination of their Contribution(s)
+   with the Work to which such Contribution(s) was submitted. If You
+   institute patent litigation against any entity (including a
+   cross-claim or counterclaim in a lawsuit) alleging that the Work
+   or a Contribution incorporated within the Work constitutes direct
+   or contributory patent infringement, then any patent licenses
+   granted to You under this License for that Work shall terminate
+   as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+   Work or Derivative Works thereof in any medium, with or without
+   modifications, and in Source or Object form, provided that You
+   meet the following conditions:
+
+   (a) You must give any other recipients of the Work or
+       Derivative Works a copy of this License; and
+
+   (b) You must cause any modified files to carry prominent notices
+       stating that You changed the files; and
+
+   (c) You must retain, in the Source form of any Derivative Works
+       that You distribute, all copyright, patent, trademark, and
+       attribution notices from the Source form of the Work,
+       excluding those notices that do not pertain to any part of
+       the Derivative Works; and
+
+   (d) If the Work includes a "NOTICE" text file as part of its
+       distribution, then any Derivative Works that You distribute must
+       include a readable copy of the attribution notices contained
+       within such NOTICE file, excluding those notices that do not
+       pertain to any part of the Derivative Works, in at least one
+       of the following places: within a NOTICE text file distributed
+       as part of the Derivative Works; within the Source form or
+       documentation, if provided along with the Derivative Works; or,
+       within a display generated by the Derivative Works, if and
+       wherever such third-party notices normally appear. The contents
+       of the NOTICE file are for informational purposes only and
+       do not modify the License. You may add Your own attribution
+       notices within Derivative Works that You distribute, alongside
+       or as an addendum to the NOTICE text from the Work, provided
+       that such additional attribution notices cannot be construed
+       as modifying the License.
+
+   You may add Your own copyright statement to Your modifications and
+   may provide additional or different license terms and conditions
+   for use, reproduction, or distribution of Your modifications, or
+   for any such Derivative Works as a whole, provided Your use,
+   reproduction, and distribution of the Work otherwise complies with
+   the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+   any Contribution intentionally submitted for inclusion in the Work
+   by You to the Licensor shall be under the terms and conditions of
+   this License, without any additional terms or conditions.
+   Notwithstanding the above, nothing herein shall supersede or modify
+   the terms of any separate license agreement you may have executed
+   with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+   names, trademarks, service marks, or product names of the Licensor,
+   except as required for reasonable and customary use in describing the
+   origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+   agreed to in writing, Licensor provides the Work (and each
+   Contributor provides its Contributions) on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+   implied, including, without limitation, any warranties or conditions
+   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+   PARTICULAR PURPOSE. You are solely responsible for determining the
+   appropriateness of using or redistributing the Work and assume any
+   risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+   whether in tort (including negligence), contract, or otherwise,
+   unless required by applicable law (such as deliberate and grossly
+   negligent acts) or agreed to in writing, shall any Contributor be
+   liable to You for damages, including any direct, indirect, special,
+   incidental, or consequential damages of any character arising as a
+   result of this License or out of the use or inability to use the
+   Work (including but not limited to damages for loss of goodwill,
+   work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses), even if such Contributor
+   has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+   the Work or Derivative Works thereof, You may choose to offer,
+   and charge a fee for, acceptance of support, warranty, indemnity,
+   or other liability obligations and/or rights consistent with this
+   License. However, in accepting such obligations, You may act only
+   on Your own behalf and on Your sole responsibility, not on behalf
+   of any other Contributor, and only if You agree to indemnify,
+   defend, and hold each Contributor harmless for any liability
+   incurred by, or claims asserted against, such Contributor by reason
+   of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+   To apply the Apache License to your work, attach the following
+   boilerplate notice, with the fields enclosed by brackets "[]"
+   replaced with your own identifying information. (Don't include
+   the brackets!)  The text should be enclosed in the appropriate
+   comment syntax for the file format. We also recommend that a
+   file or class name and description of purpose be included on the
+   same "printed page" as the copyright notice for easier
+   identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+	http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/sys/tool/LICENSE-MIT b/sys/tool/LICENSE-MIT
new file mode 100644
index 00000000..468cd79a
--- /dev/null
+++ b/sys/tool/LICENSE-MIT
@@ -0,0 +1,23 @@
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/sys/tool/README.md b/sys/tool/README.md
new file mode 100644
index 00000000..84a4351f
--- /dev/null
+++ b/sys/tool/README.md
@@ -0,0 +1,39 @@
+# Generate Rust bindings of the LV2 C API
+
+## Requirements
+
+Since the bindings to the raw C headers are generated with bindgen, you need to
+have [Clang](https://clang.llvm.org/) installed on your system and, if it isn't
+in your system's standard path, set the environment variable `LIBCLANG_PATH` to
+the path of `libClang`.
+
+## Usage
+
+Usage (anywhere is rust-lv2 workspace):
+* `cargo run -p systool -- --lv2 <DIR> --out <OUT> [-- <CLANG-ARGS>...]`
+* `cargo systool --lv2 <DIR> --out <OUT> [-- <CLANG-ARGS>...]` (alias of the
+  first)
+
+Options:
+* `-I, --lv2 <DIR>`: The path to the LV2 C API
+* `-o, --out <OUT>`: The file to write the bindings to
+
+Args:
+* `<CLANG-ARGS>...`:   Arguments passed to clang
+
+## Cross-platform bindings
+
+Cross-platform bindings generation require C headers of the target
+platform. The easiest way to obtain them is installing a C cross-compiler for
+that target platform. Then, you provide the cross-compiler root path as a clang
+arguments. Example with `arm-linux-gnueabi`:
+
+`cargo run -p systool -- --lv2 lv2 --out arm-linux-gnueabi.rs --
+--target=arm-linux-gnueabi --sysroot /usr/arm-linux-gnueabi`
+
+Sometimes, clang can't find some headers, you need to manually provide their
+path using `-I`. Example with `aarch64-unknown-linux-gnu`:
+
+`cargo run -p systool -- --lv2 lv2 --out aarch64-unknown-linux-gnu.rs --
+--target=aarch64-unknown-linux-gnu --sysroot /usr/aarch64-unknown-linux-gnu
+-I/usr/aarch64-linux-gnu/include/`
diff --git a/sys/tool/src/main.rs b/sys/tool/src/main.rs
new file mode 100644
index 00000000..01b0b0e4
--- /dev/null
+++ b/sys/tool/src/main.rs
@@ -0,0 +1,99 @@
+extern crate bindgen;
+use std::fs;
+use std::path::Path;
+use std::path::PathBuf;
+
+/// Generate lv2-sys bindings and write them to out.
+pub fn generate_bindings<I>(source_dir: &Path, out: &Path, clang_args: I)
+where
+    I: IntoIterator,
+    I::Item: AsRef<str>,
+{
+    let mut bindings = bindgen::Builder::default()
+        .size_t_is_usize(true)
+        .whitelist_type("LV2.*")
+        .whitelist_function("LV2.*")
+        .whitelist_var("LV2.*")
+        .layout_tests(false)
+        .bitfield_enum("LV2_State_Flags");
+    bindings = bindings.clang_args(clang_args);
+
+    // Adding the headers to the include path of clang.
+    // Otherwise, included headers can not be found.
+    let mut include_path = PathBuf::from(source_dir);
+    include_path.pop();
+    bindings = bindings.clang_arg(format!("-I{}", include_path.to_str().unwrap()));
+
+    // Iterate over every folder and header file in the source dir and add them to the bindings.
+    let mut dirs: Vec<PathBuf> = fs::read_dir(source_dir)
+        .unwrap()
+        .map(|entry| entry.unwrap().path())
+        .collect();
+    dirs.sort_unstable();
+    for spec_dir in dirs.iter() {
+        let mut files: Vec<PathBuf> = fs::read_dir(spec_dir)
+            .unwrap()
+            .map(|entry| entry.unwrap().path())
+            .collect();
+        files.sort_unstable();
+
+        for file in files {
+            let extension = match file.extension() {
+                Some(extension) => extension,
+                None => continue,
+            };
+
+            if extension == "h" {
+                bindings = bindings.header(file.to_str().unwrap());
+            }
+        }
+    }
+
+    // Generating the bindings.
+    let bindings = bindings.generate().expect("Unable to generate bindings");
+
+    // Writing the bindings to the file.
+    bindings
+        .write_to_file(out)
+        .expect("Couldn't write bindings!");
+}
+
+fn main() {
+    let matches = clap::App::new("systool")
+        .author("© 2020 Amaury 'Yruama_Lairba' Abrial, Jan-Oliver 'Janonard' Opdenhövel")
+        .about("Generate Rust bindings of the LV2 C API")
+        .version("0.1.0")
+        .arg(
+            clap::Arg::with_name("LV2")
+                .help("The path to the LV2 C API")
+                .required(true)
+                .short("I")
+                .long("lv2")
+                .value_name("DIR")
+                .takes_value(true),
+        )
+        .arg(
+            clap::Arg::with_name("out")
+                .help("The file to write the bindings to")
+                .required(true)
+                .short("o")
+                .long("out")
+                .value_name("OUT")
+                .takes_value(true),
+        )
+        .arg(
+            clap::Arg::with_name("clang args")
+                .help("Arguments passed to clang")
+                .required(false)
+                .value_name("CLANG-ARGS")
+                .multiple(true)
+                .last(true),
+        )
+        .get_matches();
+
+    let headers = PathBuf::from(".").join(matches.value_of("LV2").unwrap());
+    let out = PathBuf::from(".").join(matches.value_of("out").unwrap());
+    let clang_args = matches.values_of("clang args").unwrap();
+
+    generate_bindings(&headers, &out, clang_args);
+}
diff --git a/time/Cargo.toml b/time/Cargo.toml
index 3b566da3..38816f10 100644
--- a/time/Cargo.toml
+++ b/time/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "lv2-time"
-version = "0.1.2"
+version = "0.1.3"
 authors = ["Yruama_Lairba <yruama_lairba@hotmail.com>"]
 edition = "2018"
 license = "MIT OR Apache-2.0"
@@ -15,4 +15,4 @@ maintenance = { status = "actively-developed" }
 
 [dependencies]
 urid = "0.1.0"
-lv2-sys = "1.0.0"
+lv2-sys = "2.0.0"
diff --git a/time/README.md b/time/README.md
index 144ff107..76b22c12 100644
--- a/time/README.md
+++ b/time/README.md
@@ -1,4 +1,4 @@
-# rust-lv2's wrapper of LV2's time types.
+# Rust-LV2's wrapper of LV2's time types.
 
 This crate binds some of the time-related URIs from [the `sys`-crate](https://crates.io/crates/lv2-sys) to types and is a part of [`rust-lv2`](https://crates.io/crates/lv2), a safe, fast, and ergonomic framework to create [LV2 plugins](http://lv2plug.in/) for audio processing, written in Rust.
 
@@ -6,10 +6,6 @@ This crate binds some of the time-related URIs from [the `sys`-crate](https://cr
 
 The original LV2 API (in the `C` programming language) is documented by ["the LV2 book"](https://lv2plug.in/book/). This book is in the process of being translated to Rust along with the development of `rust-lv2` [(link)](https://janonard.github.io/rust-lv2-book/) and describes how to properly use `rust-lv2`.
 
-## Building
-
-Since the bindings to the raw C headers are generated with bindgen, you need to have [Clang](https://clang.llvm.org/) installed on your system and, if it isn't in your system's standard path, set the environment variable `LIBCLANG_PATH` to the path of `libClang`.
-
 ## Features
 
 There are two optional features:
diff --git a/units/Cargo.toml b/units/Cargo.toml
index a8fcce17..2e88b52e 100644
--- a/units/Cargo.toml
+++ b/units/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "lv2-units"
-version = "0.1.2"
+version = "0.1.3"
 authors = ["Jan-Oliver 'Janonard' Opdenhövel <jan.opdenhoevel@protonmail.com>"]
 edition = "2018"
 license = "MIT OR Apache-2.0"
@@ -14,5 +14,5 @@ travis-ci = { repository = "RustAudio/rust-lv2", branch = "master" }
 maintenance = { status = "actively-developed" }
 
 [dependencies]
-lv2-sys = "1.0.0"
+lv2-sys = "2.0.0"
 urid = "0.1.0"
diff --git a/units/README.md b/units/README.md
index 38c0996f..cd777640 100644
--- a/units/README.md
+++ b/units/README.md
@@ -1,4 +1,4 @@
-# rust-lv2's wrapper of LV2's unit types.
+# Rust-LV2's wrapper of LV2's unit types.
 
 This crate binds some of the unit-related URIs from [the `sys`-crate](https://crates.io/crates/lv2-sys) to types and is a part of [`rust-lv2`](https://crates.io/crates/lv2), a safe, fast, and ergonomic framework to create [LV2 plugins](http://lv2plug.in/) for audio processing, written in Rust.
 
@@ -6,10 +6,6 @@ This crate binds some of the unit-related URIs from [the `sys`-crate](https://cr
 
 The original LV2 API (in the `C` programming language) is documented by ["the LV2 book"](https://lv2plug.in/book/). This book is in the process of being translated to Rust along with the development of `rust-lv2` [(link)](https://janonard.github.io/rust-lv2-book/) and describes how to properly use `rust-lv2`.
 
-## Building
-
-Since the bindings to the raw C headers are generated with bindgen, you need to have [Clang](https://clang.llvm.org/) installed on your system and, if it isn't in your system's standard path, set the environment variable `LIBCLANG_PATH` to the path of `libClang`.
-
 ## Features
 
 There are two optional features:
diff --git a/urid/derive/Cargo.toml b/urid/derive/Cargo.toml
index 8e653ad7..fe18e72e 100644
--- a/urid/derive/Cargo.toml
+++ b/urid/derive/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "urid-derive"
-version = "0.1.0"
+version = "0.1.1"
 authors = ["Jan-Oliver 'Janonard' Opdenhövel <jan.opdenhoevel@protonmail.com>", "Adrien Prokopowicz <adrien.prokopowicz@gmail.com>"]
 edition = "2018"
 license = "MIT OR Apache-2.0"
@@ -20,5 +20,3 @@ proc-macro = true
 syn = {version = "1.0.5", features = ["full"]}
 quote = "1.0.2"
 proc-macro2 = "1.0.9"
-regex = "1.3.5"
-lazy_static = "1.4.0"
\ No newline at end of file
diff --git a/urid/derive/src/lib.rs b/urid/derive/src/lib.rs
index 28a31ead..5b9af285 100644
--- a/urid/derive/src/lib.rs
+++ b/urid/derive/src/lib.rs
@@ -1,5 +1,6 @@
 //! Procedural macros for `urid`.
 #![recursion_limit = "128"]
+extern crate proc_macro;
 
 mod uri_bound;
 mod urid_collection_derive;
diff --git a/urid/derive/src/uri_bound.rs b/urid/derive/src/uri_bound.rs
index 7e9f2bb4..a90696f6 100644
--- a/urid/derive/src/uri_bound.rs
+++ b/urid/derive/src/uri_bound.rs
@@ -1,8 +1,6 @@
-use lazy_static::lazy_static;
 use proc_macro::TokenStream;
 use proc_macro2::Literal;
 use quote::quote;
-use regex::Regex;
 use syn::{parse, Ident, Item};
 
 /// Get the identity of the item we have to implement `UriBound` for.
@@ -30,21 +28,20 @@ fn get_type_ident(item: TokenStream) -> Ident {
 ///
 /// This includes multiple checks to assure that the literal is formatted correctly.
 fn get_uri(attr: TokenStream) -> Literal {
-    lazy_static! {
-        static ref GET_STRING_RE: Regex = Regex::new(r#"^"(.*)"$"#).unwrap();
-    }
-
     const PARSING_ERROR: &str = "A URI has to be a string literal";
 
     if parse::<Literal>(attr.clone()).is_err() {
         panic!(PARSING_ERROR);
     }
-
+    //check if it's a litteral string
     let attr = attr.to_string();
-    let captures = GET_STRING_RE.captures(attr.as_str()).expect(PARSING_ERROR);
-    let uri = captures.get(1).expect(PARSING_ERROR).as_str();
-    if !uri.is_ascii() {
-        panic!("A URI has to be an ASCII string");
+    if !attr.starts_with('"') || !attr.ends_with('"') {
+        panic!(PARSING_ERROR);
+    }
+    //Remove the enclosing "" to get the uri
+    let uri = String::from(attr.get(1..attr.len() - 1).expect(PARSING_ERROR));
+    if uri.contains("\\0") {
+        panic!("Unexpected Null terminator");
     }
 
     let mut uri_vec: Vec<u8> = Vec::with_capacity(uri.len() + 1);
diff --git a/urid/lv2-urid/Cargo.toml b/urid/lv2-urid/Cargo.toml
index dc67f44b..60c5947a 100644
--- a/urid/lv2-urid/Cargo.toml
+++ b/urid/lv2-urid/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "lv2-urid"
-version = "2.0.0"
+version = "2.1.0"
 authors = ["Jan-Oliver 'Janonard' Opdenhövel <jan.opdenhoevel@protonmail.com>", "Adrien Prokopowicz <adrien.prokopowicz@gmail.com>"]
 edition = "2018"
 license = "MIT OR Apache-2.0"
@@ -14,6 +14,6 @@ travis-ci = { repository = "RustAudio/rust-lv2", branch = "master" }
 maintenance = { status = "passively-maintained" }
 
 [dependencies]
-lv2-core = "2.0.0"
-lv2-sys = "1.0.0"
+lv2-core = "3.0.0"
+lv2-sys = "2.0.0"
 urid = "0.1.0"
diff --git a/urid/lv2-urid/README.md b/urid/lv2-urid/README.md
index e3566622..2b4e9cad 100644
--- a/urid/lv2-urid/README.md
+++ b/urid/lv2-urid/README.md
@@ -1,4 +1,4 @@
-# rust-lv2's URID handling library.
+# Rust-LV2's URID handling library.
 
 URI <-> URID mapping utilities used by [`rust-lv2`](https://crates.io/crates/lv2), a safe, fast, and ergonomic framework to create [LV2 plugins](http://lv2plug.in/) for audio processing, written in Rust.
 
@@ -8,10 +8,6 @@ LV2 often uses URIs to identify types. However, comparing strings isn't particul
 
 The original LV2 API (in the `C` programming language) is documented by ["the LV2 book"](https://lv2plug.in/book/). This book is in the process of being translated to Rust along with the development of `rust-lv2` [(link)](https://janonard.github.io/rust-lv2-book/) and describes how to properly use `rust-lv2`.
 
-## Building
-
-Since the bindings to the raw C headers are generated with bindgen, you need to have [Clang](https://clang.llvm.org/) installed on your system and, if it isn't in your system's standard path, set the environment variable `LIBCLANG_PATH` to the path of `libClang`.
-
 ## Features
 
 Like any other crate of `rust-lv2`, this crate has the optional `host` feature. Some of the types defined by some crates are only useful for testing or LV2 hosts. Since the goal of this framework is to provide an easy way to create plugins, these aren't necessary and therefore gated behind that feature.
diff --git a/urid/lv2-urid/src/lib.rs b/urid/lv2-urid/src/lib.rs
index 48d56900..0a8d2dd1 100644
--- a/urid/lv2-urid/src/lib.rs
+++ b/urid/lv2-urid/src/lib.rs
@@ -1,9 +1,6 @@
 //! LV2 integration of the URID concept.
 //!
 //! The URID specification provides a host feature that can be used by plugins to map URIs to integers, so-called URIDs. These URIDs are used by many other specifications to identify other URI bounds and combine the flexibility of URIs with the comparison speed of integers.
-//!
-//! Since this crate depends on `-sys` crates that use `bindgen` to create the C API bindings,
-//! you need to have clang installed on your machine.
 extern crate lv2_core as core;
 extern crate lv2_sys as sys;
 
diff --git a/worker/Cargo.toml b/worker/Cargo.toml
index 4c345115..cfe0a10f 100644
--- a/worker/Cargo.toml
+++ b/worker/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "lv2-worker"
-version = "0.1.0"
+version = "0.1.1"
 authors = ["Amaury ABRIAL aka Yruama_Lairba <yruama_lairba@hotmail.com>"]
 edition = "2018"
 license = "MIT OR Apache-2.0"
@@ -10,6 +10,6 @@ readme = "README.md"
 repository = "https://github.com/RustAudio/rust-lv2"
 
 [dependencies]
-lv2-sys = "1.0.0"
-lv2-core = "2.0.0"
+lv2-sys = "2.0.0"
+lv2-core = "3.0.0"
 urid = "0.1.0"
diff --git a/worker/README.md b/worker/README.md
index 9348e740..6444b471 100644
--- a/worker/README.md
+++ b/worker/README.md
@@ -1,4 +1,4 @@
-# rust-lv2's library to implement LV2 Worker extension.
+# Rust-LV2's library to implement LV2 Worker extension.
 
 Work scheduling library that allows real-time capable LV2 plugins to execute
 non-real-time actions. This is a part of
@@ -14,13 +14,6 @@ being translated to Rust along with the development of `rust-lv2`
 [(link)](https://janonard.github.io/rust-lv2-book/) and describes how to
 properly use `rust-lv2`.
 
-## Building
-
-Since the bindings to the raw C headers are generated with bindgen, you need to
-have [Clang](https://clang.llvm.org/) installed on your system and, if it isn't
-in your system's standard path, set the environment variable `LIBCLANG_PATH` to
-the path of `libClang`.
-
 ## License
 
 Licensed under either of
diff --git a/worker/src/lib.rs b/worker/src/lib.rs
index e293a302..7b2ef1d3 100644
--- a/worker/src/lib.rs
+++ b/worker/src/lib.rs
@@ -54,7 +54,7 @@
 //!        })
 //!    }
 //!
-//!    fn run(&mut self, _ports: &mut Ports, features: &mut Self::AudioFeatures) {
+//!    fn run(&mut self, _ports: &mut Ports, features: &mut Self::AudioFeatures, _: u32) {
 //!        self.cycle += 1;
 //!        let cycle = self.cycle;
 //!        println!("cycle {} started", cycle);
@@ -437,10 +437,8 @@ impl<P: Worker> WorkerDescriptor<P> {
             return lv2_sys::LV2_Worker_Status_LV2_WORKER_ERR_UNKNOWN;
         }
 
-        match plugin_instance
-            .instance
-            .work_response(response_data, &mut plugin_instance.audio_features)
-        {
+        let (instance, features) = plugin_instance.audio_class_handle();
+        match instance.work_response(response_data, features) {
             Ok(()) => lv2_sys::LV2_Worker_Status_LV2_WORKER_SUCCESS,
             Err(WorkerError::Unknown) => lv2_sys::LV2_Worker_Status_LV2_WORKER_ERR_UNKNOWN,
             Err(WorkerError::NoSpace) => lv2_sys::LV2_Worker_Status_LV2_WORKER_ERR_NO_SPACE,
@@ -450,10 +448,8 @@ impl<P: Worker> WorkerDescriptor<P> {
     /// Extern unsafe version of `end_run` method actually called by the host
     unsafe extern "C" fn extern_end_run(handle: lv2_sys::LV2_Handle) -> lv2_sys::LV2_Worker_Status {
         if let Some(plugin_instance) = (handle as *mut PluginInstance<P>).as_mut() {
-            match plugin_instance
-                .instance
-                .end_run(&mut plugin_instance.audio_features)
-            {
+            let (instance, features) = plugin_instance.audio_class_handle();
+            match instance.end_run(features) {
                 Ok(()) => lv2_sys::LV2_Worker_Status_LV2_WORKER_SUCCESS,
                 Err(WorkerError::Unknown) => lv2_sys::LV2_Worker_Status_LV2_WORKER_ERR_UNKNOWN,
                 Err(WorkerError::NoSpace) => lv2_sys::LV2_Worker_Status_LV2_WORKER_ERR_NO_SPACE,
@@ -535,7 +531,7 @@ mod tests {
             Some(Self {})
         }
 
-        fn run(&mut self, _ports: &mut Ports, _features: &mut Self::InitFeatures) {}
+        fn run(&mut self, _ports: &mut Ports, _features: &mut Self::InitFeatures, _: u32) {}
     }
 
     impl Worker for TestDropWorker {