Add automatable volume and pan control to default instruments

This commit is contained in:
Skyler Lehmkuhl 2026-03-23 23:27:05 -04:00
parent 434b488a4c
commit fa40173562
36 changed files with 4854 additions and 225 deletions

367
daw-backend/Cargo.lock generated
View File

@ -2,6 +2,23 @@
# It is not intended for manual editing.
version = 4
[[package]]
name = "adler2"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
[[package]]
name = "aes"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
dependencies = [
"cfg-if",
"cipher",
"cpufeatures",
]
[[package]]
name = "aho-corasick"
version = "1.1.3"
@ -69,6 +86,12 @@ version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "base64ct"
version = "1.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
[[package]]
name = "beamdsp"
version = "0.1.0"
@ -106,6 +129,15 @@ version = "2.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394"
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "block2"
version = "0.6.2"
@ -127,12 +159,38 @@ version = "1.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
[[package]]
name = "bzip2"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8"
dependencies = [
"bzip2-sys",
"libc",
]
[[package]]
name = "bzip2-sys"
version = "0.1.13+1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14"
dependencies = [
"cc",
"pkg-config",
]
[[package]]
name = "cassowary"
version = "0.3.0"
@ -155,6 +213,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7"
dependencies = [
"find-msvc-tools",
"jobserver",
"libc",
"shlex",
]
@ -179,6 +239,16 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "cipher"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
dependencies = [
"crypto-common",
"inout",
]
[[package]]
name = "clang-sys"
version = "1.8.1"
@ -222,6 +292,12 @@ dependencies = [
"static_assertions",
]
[[package]]
name = "constant_time_eq"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]]
name = "core-foundation"
version = "0.9.4"
@ -302,6 +378,24 @@ dependencies = [
"windows 0.62.2",
]
[[package]]
name = "cpufeatures"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
[[package]]
name = "crc32fast"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
dependencies = [
"cfg-if",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.6"
@ -352,6 +446,16 @@ dependencies = [
"winapi",
]
[[package]]
name = "crypto-common"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "dasp_envelope"
version = "0.11.0"
@ -497,6 +601,27 @@ dependencies = [
"serde",
"serde_json",
"symphonia",
"zip",
]
[[package]]
name = "deranged"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c"
dependencies = [
"powerfmt",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
"subtle",
]
[[package]]
@ -579,12 +704,32 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
[[package]]
name = "flate2"
version = "1.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
name = "foldhash"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getrandom"
version = "0.2.16"
@ -596,6 +741,18 @@ dependencies = [
"wasi",
]
[[package]]
name = "getrandom"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"wasip2",
]
[[package]]
name = "glob"
version = "0.3.3"
@ -637,6 +794,15 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
[[package]]
name = "hmac"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
dependencies = [
"digest",
]
[[package]]
name = "hound"
version = "3.5.1"
@ -663,6 +829,15 @@ dependencies = [
"hashbrown 0.16.0",
]
[[package]]
name = "inout"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01"
dependencies = [
"generic-array",
]
[[package]]
name = "itertools"
version = "0.12.1"
@ -709,6 +884,16 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
[[package]]
name = "jobserver"
version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
dependencies = [
"getrandom 0.3.4",
"libc",
]
[[package]]
name = "js-sys"
version = "0.3.81"
@ -820,6 +1005,16 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
dependencies = [
"adler2",
"simd-adler32",
]
[[package]]
name = "mio"
version = "0.8.11"
@ -889,6 +1084,12 @@ dependencies = [
"minimal-lexical",
]
[[package]]
name = "num-conv"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050"
[[package]]
name = "num-derive"
version = "0.4.2"
@ -1059,6 +1260,17 @@ dependencies = [
"windows-link",
]
[[package]]
name = "password-hash"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700"
dependencies = [
"base64ct",
"rand_core",
"subtle",
]
[[package]]
name = "paste"
version = "1.0.15"
@ -1071,6 +1283,18 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
[[package]]
name = "pbkdf2"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917"
dependencies = [
"digest",
"hmac",
"password-hash",
"sha2",
]
[[package]]
name = "petgraph"
version = "0.5.1"
@ -1097,6 +1321,12 @@ version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
[[package]]
name = "powerfmt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "ppv-lite86"
version = "0.2.21"
@ -1133,6 +1363,12 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "r-efi"
version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "rand"
version = "0.8.5"
@ -1160,7 +1396,7 @@ version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
"getrandom 0.2.16",
]
[[package]]
@ -1323,6 +1559,28 @@ dependencies = [
"serde_core",
]
[[package]]
name = "sha1"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "sha2"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "shlex"
version = "1.3.0"
@ -1359,6 +1617,12 @@ dependencies = [
"libc",
]
[[package]]
name = "simd-adler32"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2"
[[package]]
name = "smallvec"
version = "1.15.1"
@ -1403,6 +1667,12 @@ dependencies = [
"syn",
]
[[package]]
name = "subtle"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "symphonia"
version = "0.5.5"
@ -1629,6 +1899,25 @@ dependencies = [
"syn",
]
[[package]]
name = "time"
version = "0.3.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
dependencies = [
"deranged",
"num-conv",
"powerfmt",
"serde_core",
"time-core",
]
[[package]]
name = "time-core"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
[[package]]
name = "toml_datetime"
version = "0.7.3"
@ -1659,6 +1948,12 @@ dependencies = [
"winnow",
]
[[package]]
name = "typenum"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
[[package]]
name = "unicode-ident"
version = "1.0.19"
@ -1694,6 +1989,12 @@ version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "walkdir"
version = "2.5.0"
@ -1710,6 +2011,15 @@ version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "wasip2"
version = "1.0.2+wasi-0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
dependencies = [
"wit-bindgen",
]
[[package]]
name = "wasm-bindgen"
version = "0.2.104"
@ -2098,6 +2408,12 @@ dependencies = [
"memchr",
]
[[package]]
name = "wit-bindgen"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
[[package]]
name = "zerocopy"
version = "0.8.27"
@ -2117,3 +2433,52 @@ dependencies = [
"quote",
"syn",
]
[[package]]
name = "zip"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261"
dependencies = [
"aes",
"byteorder",
"bzip2",
"constant_time_eq",
"crc32fast",
"crossbeam-utils",
"flate2",
"hmac",
"pbkdf2",
"sha1",
"time",
"zstd",
]
[[package]]
name = "zstd"
version = "0.11.2+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4"
dependencies = [
"zstd-safe",
]
[[package]]
name = "zstd-safe"
version = "5.0.2+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db"
dependencies = [
"libc",
"zstd-sys",
]
[[package]]
name = "zstd-sys"
version = "2.0.16+zstd.1.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748"
dependencies = [
"cc",
"pkg-config",
]

View File

@ -1009,6 +1009,29 @@ impl AudioGraph {
}
}
// For AutomationInput nodes, serialize display name and keyframes
if node.node_type() == "AutomationInput" {
use crate::audio::node_graph::nodes::{AutomationInputNode, InterpolationType};
use crate::audio::node_graph::preset::SerializedKeyframe;
if let Some(auto_node) = node.as_any().downcast_ref::<AutomationInputNode>() {
serialized.automation_display_name = Some(auto_node.display_name().to_string());
serialized.automation_keyframes = auto_node.keyframes().iter().map(|kf| {
SerializedKeyframe {
time: kf.time,
value: kf.value,
interpolation: match kf.interpolation {
InterpolationType::Linear => "linear",
InterpolationType::Bezier => "bezier",
InterpolationType::Step => "step",
InterpolationType::Hold => "hold",
}.to_string(),
ease_out: kf.ease_out,
ease_in: kf.ease_in,
}
}).collect();
}
}
// For AmpSim nodes, serialize the model path
if node.node_type() == "AmpSim" {
use crate::audio::node_graph::nodes::AmpSimNode;
@ -1322,6 +1345,35 @@ impl AudioGraph {
}
}
// Restore AutomationInput display name and keyframes
if serialized_node.node_type == "AutomationInput" {
use crate::audio::node_graph::nodes::{AutomationInputNode, AutomationKeyframe, InterpolationType};
if let Some(graph_node) = graph.graph.node_weight_mut(node_idx) {
if let Some(auto_node) = graph_node.node.as_any_mut().downcast_mut::<AutomationInputNode>() {
if let Some(ref name) = serialized_node.automation_display_name {
auto_node.set_display_name(name.clone());
}
if !serialized_node.automation_keyframes.is_empty() {
auto_node.clear_keyframes();
for kf in &serialized_node.automation_keyframes {
auto_node.add_keyframe(AutomationKeyframe {
time: kf.time,
value: kf.value,
interpolation: match kf.interpolation.as_str() {
"bezier" => InterpolationType::Bezier,
"step" => InterpolationType::Step,
"hold" => InterpolationType::Hold,
_ => InterpolationType::Linear,
},
ease_out: kf.ease_out,
ease_in: kf.ease_in,
});
}
}
}
}
}
// Restore position
graph.set_node_position(node_idx, serialized_node.position.0, serialized_node.position.1);
}

View File

@ -1,4 +1,4 @@
use crate::audio::node_graph::{AudioNode, NodeCategory, NodePort, Parameter, SignalType};
use crate::audio::node_graph::{AudioNode, NodeCategory, NodePort, Parameter, ParameterUnit, SignalType};
use crate::audio::midi::MidiEvent;
use serde::{Deserialize, Serialize};
use std::sync::{Arc, RwLock};
@ -63,12 +63,17 @@ impl AutomationInputNode {
NodePort::new("CV Out", SignalType::CV, 0),
];
let parameters = vec![
Parameter::new(0, "Min", f32::NEG_INFINITY, f32::INFINITY, -1.0, ParameterUnit::Generic),
Parameter::new(1, "Max", f32::NEG_INFINITY, f32::INFINITY, 1.0, ParameterUnit::Generic),
];
Self {
name: name.clone(),
display_name: "Automation".to_string(),
keyframes: vec![AutomationKeyframe::new(0.0, 0.0)],
outputs,
parameters: Vec::new(),
parameters,
playback_time: Arc::new(RwLock::new(0.0)),
value_min: -1.0,
value_max: 1.0,
@ -221,12 +226,20 @@ impl AudioNode for AutomationInputNode {
&self.parameters
}
fn set_parameter(&mut self, _id: u32, _value: f32) {
// No parameters
fn set_parameter(&mut self, id: u32, value: f32) {
match id {
0 => self.value_min = value,
1 => self.value_max = value,
_ => {}
}
}
fn get_parameter(&self, _id: u32) -> f32 {
0.0
fn get_parameter(&self, id: u32) -> f32 {
match id {
0 => self.value_min,
1 => self.value_max,
_ => 0.0,
}
}
fn process(

View File

@ -113,10 +113,8 @@ impl AudioNode for PanNode {
let frames_to_process = frames.min(output_frames);
for frame in 0..frames_to_process {
// Pan CV input: when connected, replaces parameter; when unconnected, uses parameter
// CV is in 0-1 range, mapped to -1 to +1 pan range
let cv_raw = cv_input_or_default(inputs, 1, frame, (self.pan + 1.0) * 0.5);
let pan = (cv_raw * 2.0 - 1.0).clamp(-1.0, 1.0);
// Pan CV input: -1..+1 directly (0 = center), defaults to parameter value when unconnected
let pan = cv_input_or_default(inputs, 1, frame, self.pan).clamp(-1.0, 1.0);
// Calculate gains using constant-power panning law
let angle = (pan + 1.0) * 0.5 * PI / 2.0;

View File

@ -100,6 +100,16 @@ fn default_version() -> u32 {
1
}
/// Serialized keyframe for AutomationInput nodes
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SerializedKeyframe {
pub time: f64,
pub value: f32,
pub interpolation: String,
pub ease_out: (f32, f32),
pub ease_in: (f32, f32),
}
/// Serialized node representation
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SerializedNode {
@ -141,6 +151,14 @@ pub struct SerializedNode {
/// Allows the UI to display actual track names on the node's output ports.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub port_names: Vec<String>,
/// For AutomationInput nodes: user-visible display name
#[serde(skip_serializing_if = "Option::is_none")]
pub automation_display_name: Option<String>,
/// For AutomationInput nodes: saved keyframes
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub automation_keyframes: Vec<SerializedKeyframe>,
}
/// Serialized group definition (frontend-only visual grouping, stored opaquely by backend)
@ -239,6 +257,8 @@ impl SerializedNode {
nam_model_path: None,
num_ports: None,
port_names: Vec::new(),
automation_display_name: None,
automation_keyframes: Vec::new(),
}
}

View File

@ -1697,6 +1697,7 @@ dependencies = [
"serde",
"serde_json",
"symphonia",
"zip",
]
[[package]]

View File

@ -1449,7 +1449,7 @@ fn render_vector_graph_cpu(
}
// Image fill — decode to Pixmap and use as a Pattern shader
if let Some(image_asset_id) = face.image_fill {
if let Some(image_asset_id) = fill.image_fill {
if let Some(asset) = document.get_image_asset(&image_asset_id) {
if let Some(img_pixmap) = image_cache.get_or_decode_cpu(asset) {
let pattern = tiny_skia::Pattern::new(

View File

@ -777,7 +777,7 @@ impl NodeTemplateTrait for NodeTemplate {
NodeTemplate::Pan => {
graph.add_input_param(node_id, "Audio In".into(), DataType::Audio, ValueType::float(0.0), InputParamKind::ConnectionOnly, true);
graph.add_input_param(node_id, "Pan".into(), DataType::CV,
ValueType::float_param(0.0, -1.0, 1.0, "", 0, None), InputParamKind::ConstantOnly, true);
ValueType::float_param(0.0, -1.0, 1.0, "", 0, None), InputParamKind::ConnectionOrConstant, true);
graph.add_output_param(node_id, "Audio Out".into(), DataType::Audio);
}
NodeTemplate::RingModulator => {

View File

@ -2000,7 +2000,22 @@ impl TimelinePane {
);
// Get layer ID and current property values from the layer we already have
let current_volume = layer_for_controls.volume();
// Check if there's a Volume automation lane; use it to drive the slider
let volume_auto_info = self.automation_cache.get(&layer_id)
.and_then(|lanes| lanes.iter().find(|l| l.name == "Volume"))
.map(|l| (l.node_id, l.keyframes.clone()));
// Classify the volume automation state
let (volume_auto_node_id, volume_auto_value, volume_is_automated) =
match &volume_auto_info {
None => (None, None, false),
Some((nid, kfs)) if kfs.len() == 1 && (kfs[0].time - 0.0).abs() < 0.001 => {
(Some(*nid), Some(kfs[0].value as f64), false)
}
Some((nid, _)) => (Some(*nid), None, true),
};
let current_volume = volume_auto_value.unwrap_or_else(|| layer_for_controls.volume());
let is_muted = layer_for_controls.muted();
let is_soloed = layer_for_controls.soloed();
let is_locked = layer_for_controls.locked();
@ -2106,6 +2121,7 @@ impl TimelinePane {
}
// Volume slider (nonlinear: 0-70% slider = 0-100% volume, 70-100% slider = 100-200% volume)
// Disabled when the user has edited the Volume automation curve beyond the default single keyframe
let volume_response = ui.scope_builder(egui::UiBuilder::new().max_rect(volume_slider_rect), |ui| {
// Map volume (0.0-2.0) to slider position (0.0-1.0)
let slider_value = if current_volume <= 1.0 {
@ -2116,11 +2132,11 @@ impl TimelinePane {
0.7 + (current_volume - 1.0) * 0.3
};
let mut temp_slider_value = slider_value;
let mut temp_slider_value = slider_value as f32;
let slider = egui::Slider::new(&mut temp_slider_value, 0.0..=1.0)
.show_value(false);
let response = ui.add(slider);
let response = ui.add_enabled(!volume_is_automated, slider);
(response, temp_slider_value)
}).inner;
@ -2128,7 +2144,7 @@ impl TimelinePane {
if volume_response.0.dragged() || volume_response.0.has_focus() {
self.layer_control_clicked = true;
}
if volume_response.0.changed() {
if volume_response.0.changed() && !volume_is_automated {
self.layer_control_clicked = true;
// Map slider position (0.0-1.0) back to volume (0.0-2.0)
let new_volume = if volume_response.1 <= 0.7 {
@ -2139,12 +2155,30 @@ impl TimelinePane {
1.0 + (volume_response.1 - 0.7) / 0.3
};
pending_actions.push(Box::new(
lightningbeam_core::actions::SetLayerPropertiesAction::new(
if let Some(node_id) = volume_auto_node_id {
// Route through automation: update the t=0 keyframe
self.pending_automation_actions.push(AutomationLaneAction::AddKeyframe {
layer_id,
lightningbeam_core::actions::LayerProperty::Volume(new_volume),
)
));
node_id,
time: 0.0,
value: new_volume,
});
// Optimistic cache update so slider feels immediate
if let Some(lanes) = self.automation_cache.get_mut(&layer_id) {
if let Some(lane) = lanes.iter_mut().find(|l| l.node_id == node_id) {
if let Some(kf) = lane.keyframes.iter_mut().find(|k| k.time < 0.001) {
kf.value = new_volume;
}
}
}
} else {
pending_actions.push(Box::new(
lightningbeam_core::actions::SetLayerPropertiesAction::new(
layer_id,
lightningbeam_core::actions::LayerProperty::Volume(new_volume as f64),
)
));
}
}
// Input gain slider for sampled audio layers (below volume slider)
@ -5161,15 +5195,19 @@ impl PaneRenderer for TimelinePane {
// Optimistic cache update
if let Some(lanes) = self.automation_cache.get_mut(&layer_id) {
if let Some(lane) = lanes.iter_mut().find(|l| l.node_id == node_id) {
let new_kf = crate::curve_editor::CurvePoint {
time,
value,
interpolation: crate::curve_editor::CurveInterpolation::Linear,
ease_out: (0.0, 0.0),
ease_in: (0.0, 0.0),
};
lane.keyframes.push(new_kf);
lane.keyframes.sort_by(|a, b| a.time.partial_cmp(&b.time).unwrap_or(std::cmp::Ordering::Equal));
// Replace existing keyframe at same time, or insert new one
if let Some(existing) = lane.keyframes.iter_mut().find(|k| (k.time - time).abs() < 0.001) {
existing.value = value;
} else {
lane.keyframes.push(crate::curve_editor::CurvePoint {
time,
value,
interpolation: crate::curve_editor::CurveInterpolation::Linear,
ease_out: (0.0, 0.0),
ease_in: (0.0, 0.0),
});
lane.keyframes.sort_by(|a, b| a.time.partial_cmp(&b.time).unwrap_or(std::cmp::Ordering::Equal));
}
}
}
}

165
scripts/add_output_chain.py Normal file
View File

@ -0,0 +1,165 @@
#!/usr/bin/env python3
"""
Transform all instrument preset JSON files to add a Compressor Pan Gain
output chain, plus Volume and Pan AutomationInput nodes wired via CV.
Only modifies presets that have a MidiInput node (i.e., MIDI instrument presets).
"""
import json
import sys
from pathlib import Path
def transform_preset(data: dict) -> dict | None:
"""Transform a preset. Returns modified dict or None if no change needed."""
nodes = data.get("nodes", [])
connections = data.get("connections", [])
# Only modify presets with a MidiInput node
if not any(n["node_type"] == "MidiInput" for n in nodes):
return None
# Skip if already transformed (has a Compressor node)
if any(n["node_type"] == "Compressor" for n in nodes):
print(" Already transformed, skipping.")
return None
output_node_id = data.get("output_node")
if output_node_id is None:
print(" No output_node, skipping.")
return None
# Find the connection going into the output node
incoming = [c for c in connections if c["to_node"] == output_node_id]
if len(incoming) != 1:
print(f" Expected 1 incoming connection to output_node, found {len(incoming)}, skipping.")
return None
conn = incoming[0]
source_node = conn["from_node"]
source_port = conn["from_port"]
# Get AudioOutput node position — new chain starts where it was
output_node_data = next((n for n in nodes if n["id"] == output_node_id), None)
out_pos = output_node_data.get("position", [700.0, 150.0]) if output_node_data else [700.0, 150.0]
if isinstance(out_pos, list):
ox, oy = float(out_pos[0]), float(out_pos[1])
else:
ox, oy = 700.0, 150.0
step = 230.0 # horizontal spacing between nodes
# Compute new node IDs
max_id = max(n["id"] for n in nodes)
comp_id = max_id + 1 # Compressor
pan_id = max_id + 2 # Pan
gain_id = max_id + 3 # Gain (volume)
vol_id = max_id + 4 # Volume AutomationInput
pan_auto_id = max_id + 5 # Pan AutomationInput
# Move the AudioOutput node to the right of the new chain
if output_node_data is not None:
output_node_data["position"] = [ox + step * 3, oy]
# Remove the existing connection to output
connections = [c for c in connections if not (c["to_node"] == output_node_id and c["from_node"] == source_node)]
# New nodes — Compressor starts where AudioOutput was
new_nodes = [
{
"id": comp_id,
"node_type": "Compressor",
"parameters": {"0": -18.0, "1": 4.0, "2": 5.0, "3": 50.0, "4": 3.0, "5": 3.0},
"position": [ox, oy]
},
{
"id": pan_id,
"node_type": "Pan",
"parameters": {"0": 0.0},
"position": [ox + step, oy]
},
{
"id": gain_id,
"node_type": "Gain",
"parameters": {"0": 1.0},
"position": [ox + step * 2, oy]
},
{
"id": vol_id,
"node_type": "AutomationInput",
"parameters": {"0": 0.0, "1": 2.0},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [0.58, 1.0],
"ease_in": [0.42, 0.0]
}
],
"position": [ox + step, oy + 230.0]
},
{
"id": pan_auto_id,
"node_type": "AutomationInput",
"parameters": {"0": -1.0, "1": 1.0},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [0.58, 1.0],
"ease_in": [0.42, 0.0]
}
],
"position": [ox, oy + 230.0]
},
]
# New connections
new_connections = [
{"from_node": source_node, "from_port": source_port, "to_node": comp_id, "to_port": 0},
{"from_node": comp_id, "from_port": 0, "to_node": pan_id, "to_port": 0},
{"from_node": pan_id, "from_port": 0, "to_node": gain_id, "to_port": 0},
{"from_node": gain_id, "from_port": 0, "to_node": output_node_id, "to_port": 0},
{"from_node": vol_id, "from_port": 0, "to_node": gain_id, "to_port": 1},
{"from_node": pan_auto_id, "from_port": 0, "to_node": pan_id, "to_port": 1},
]
data["nodes"] = nodes + new_nodes
data["connections"] = connections + new_connections
return data
def main():
instruments_dir = Path(__file__).parent.parent / "src" / "assets" / "instruments"
if not instruments_dir.exists():
print(f"Instruments directory not found: {instruments_dir}", file=sys.stderr)
sys.exit(1)
json_files = sorted(instruments_dir.rglob("*.json"))
print(f"Found {len(json_files)} preset files")
modified = 0
for path in json_files:
print(f"Processing: {path.relative_to(instruments_dir)}")
with open(path) as f:
data = json.load(f)
result = transform_preset(data)
if result is not None:
with open(path, "w") as f:
json.dump(result, f, indent=2)
print(f" -> Modified")
modified += 1
else:
print(f" -> Skipped")
print(f"\nDone. Modified {modified}/{len(json_files)} presets.")
if __name__ == "__main__":
main()

View File

@ -735,10 +735,104 @@
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
1390.0,
100.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
100.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
100.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
100.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
330.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
330.0
]
}
],
"connections": [
@ -751,8 +845,38 @@
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}

View File

@ -286,10 +286,104 @@
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
1390.0,
100.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
100.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
100.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
100.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
330.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
330.0
]
}
],
"connections": [
@ -302,8 +396,38 @@
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}

View File

@ -213,10 +213,104 @@
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
1390.0,
100.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
100.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
100.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
100.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
330.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
330.0
]
}
],
"connections": [
@ -229,8 +323,38 @@
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}

View File

@ -258,10 +258,104 @@
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
1390.0,
100.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
100.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
100.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
100.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
330.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
330.0
]
}
],
"connections": [
@ -274,8 +368,38 @@
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}

View File

@ -131,10 +131,104 @@
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
1390.0,
100.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
100.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
100.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
100.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
330.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
330.0
]
}
],
"connections": [
@ -147,8 +241,38 @@
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}

View File

@ -323,10 +323,104 @@
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
1390.0,
100.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
100.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
100.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
100.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
330.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
330.0
]
}
],
"connections": [
@ -339,8 +433,38 @@
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}

View File

@ -1099,10 +1099,104 @@
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
1390.0,
100.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
100.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
100.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
100.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
330.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
330.0
]
}
],
"connections": [
@ -1115,8 +1209,38 @@
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}

View File

@ -498,10 +498,104 @@
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
1390.0,
100.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
100.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
100.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
100.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
330.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
330.0
]
}
],
"connections": [
@ -514,8 +608,38 @@
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}

View File

@ -4,9 +4,16 @@
"description": "Synthesized electric guitar with exponential pluck envelope through a tube amp sim",
"author": "Lightningbeam",
"version": 2,
"tags": ["guitar", "electric", "amp", "pluck"]
"tags": [
"guitar",
"electric",
"amp",
"pluck"
]
},
"midi_targets": [0],
"midi_targets": [
0
],
"output_node": 4,
"nodes": [
{
@ -14,7 +21,10 @@
"node_type": "MidiInput",
"name": "MIDI In",
"parameters": {},
"position": [100.0, 150.0]
"position": [
100.0,
150.0
]
},
{
"id": 1,
@ -23,7 +33,10 @@
"parameters": {
"0": 6.0
},
"position": [400.0, 150.0],
"position": [
400.0,
150.0
],
"template_graph": {
"metadata": {
"name": "Voice Template",
@ -32,7 +45,9 @@
"version": 3,
"tags": []
},
"midi_targets": [0],
"midi_targets": [
0
],
"output_node": 11,
"nodes": [
{
@ -40,14 +55,20 @@
"node_type": "TemplateInput",
"name": "Template Input",
"parameters": {},
"position": [-200.0, 0.0]
"position": [
-200.0,
0.0
]
},
{
"id": 1,
"node_type": "MidiToCV",
"name": "MIDICV",
"name": "MIDI\u2192CV",
"parameters": {},
"position": [100.0, 0.0]
"position": [
100.0,
0.0
]
},
{
"id": 2,
@ -56,7 +77,10 @@
"parameters": {
"0": 1.0
},
"position": [100.0, 350.0]
"position": [
100.0,
350.0
]
},
{
"id": 3,
@ -65,7 +89,10 @@
"parameters": {
"0": 1.0
},
"position": [300.0, 300.0]
"position": [
300.0,
300.0
]
},
{
"id": 4,
@ -76,7 +103,10 @@
"1": 0.4,
"2": 3.0
},
"position": [500.0, -200.0]
"position": [
500.0,
-200.0
]
},
{
"id": 5,
@ -87,7 +117,10 @@
"1": 0.18,
"2": 1.0
},
"position": [500.0, 0.0]
"position": [
500.0,
0.0
]
},
{
"id": 6,
@ -98,7 +131,10 @@
"1": 0.35,
"2": 0.0
},
"position": [500.0, 200.0]
"position": [
500.0,
200.0
]
},
{
"id": 7,
@ -109,7 +145,10 @@
"1": 1.0,
"2": 1.0
},
"position": [800.0, 0.0]
"position": [
800.0,
0.0
]
},
{
"id": 8,
@ -122,7 +161,10 @@
"3": 0.3,
"4": 1.0
},
"position": [500.0, 450.0]
"position": [
500.0,
450.0
]
},
{
"id": 9,
@ -131,7 +173,10 @@
"parameters": {
"0": 1.0
},
"position": [1100.0, 0.0]
"position": [
1100.0,
0.0
]
},
{
"id": 10,
@ -140,31 +185,107 @@
"parameters": {
"0": 1.4
},
"position": [1100.0, 200.0]
"position": [
1100.0,
200.0
]
},
{
"id": 11,
"node_type": "TemplateOutput",
"name": "Template Output",
"parameters": {},
"position": [1400.0, 0.0]
"position": [
1400.0,
0.0
]
}
],
"connections": [
{ "from_node": 0, "from_port": 0, "to_node": 1, "to_port": 0 },
{ "from_node": 1, "from_port": 0, "to_node": 4, "to_port": 0 },
{ "from_node": 1, "from_port": 0, "to_node": 5, "to_port": 0 },
{ "from_node": 1, "from_port": 0, "to_node": 3, "to_port": 0 },
{ "from_node": 2, "from_port": 0, "to_node": 3, "to_port": 1 },
{ "from_node": 3, "from_port": 0, "to_node": 6, "to_port": 0 },
{ "from_node": 1, "from_port": 1, "to_node": 8, "to_port": 0 },
{ "from_node": 4, "from_port": 0, "to_node": 7, "to_port": 0 },
{ "from_node": 5, "from_port": 0, "to_node": 7, "to_port": 1 },
{ "from_node": 6, "from_port": 0, "to_node": 7, "to_port": 2 },
{ "from_node": 7, "from_port": 0, "to_node": 9, "to_port": 0 },
{ "from_node": 8, "from_port": 0, "to_node": 9, "to_port": 1 },
{ "from_node": 9, "from_port": 0, "to_node": 10, "to_port": 0 },
{ "from_node": 10, "from_port": 0, "to_node": 11, "to_port": 0 }
{
"from_node": 0,
"from_port": 0,
"to_node": 1,
"to_port": 0
},
{
"from_node": 1,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 1,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 2,
"from_port": 0,
"to_node": 3,
"to_port": 1
},
{
"from_node": 3,
"from_port": 0,
"to_node": 6,
"to_port": 0
},
{
"from_node": 1,
"from_port": 1,
"to_node": 8,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 7,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 7,
"to_port": 1
},
{
"from_node": 6,
"from_port": 0,
"to_node": 7,
"to_port": 2
},
{
"from_node": 7,
"from_port": 0,
"to_node": 9,
"to_port": 0
},
{
"from_node": 8,
"from_port": 0,
"to_node": 9,
"to_port": 1
},
{
"from_node": 9,
"from_port": 0,
"to_node": 10,
"to_port": 0
},
{
"from_node": 10,
"from_port": 0,
"to_node": 11,
"to_port": 0
}
]
}
},
@ -173,7 +294,10 @@
"node_type": "AmpSim",
"name": "Tube Amp",
"parameters": {},
"position": [700.0, 150.0],
"position": [
700.0,
150.0
],
"nam_model_path": "bundled:BossSD1"
},
{
@ -185,20 +309,170 @@
"1": 0.4,
"2": 0.5
},
"position": [1000.0, 150.0]
"position": [
1000.0,
150.0
]
},
{
"id": 4,
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [1300.0, 150.0]
"position": [
1990.0,
150.0
]
},
{
"id": 5,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
1300.0,
150.0
]
},
{
"id": 6,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
1530.0,
150.0
]
},
{
"id": 7,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1760.0,
150.0
]
},
{
"id": 8,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
1530.0,
380.0
]
},
{
"id": 9,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
1300.0,
380.0
]
}
],
"connections": [
{ "from_node": 0, "from_port": 0, "to_node": 1, "to_port": 0 },
{ "from_node": 1, "from_port": 0, "to_node": 2, "to_port": 0 },
{ "from_node": 2, "from_port": 0, "to_node": 3, "to_port": 0 },
{ "from_node": 3, "from_port": 0, "to_node": 4, "to_port": 0 }
{
"from_node": 0,
"from_port": 0,
"to_node": 1,
"to_port": 0
},
{
"from_node": 1,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 2,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 6,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 7,
"to_port": 0
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 8,
"from_port": 0,
"to_node": 7,
"to_port": 1
},
{
"from_node": 9,
"from_port": 0,
"to_node": 6,
"to_port": 1
}
]
}
}

View File

@ -4,9 +4,15 @@
"description": "Classic drawbar organ with vibrato and reverb (polyphonic)",
"author": "Lightningbeam",
"version": 1,
"tags": ["organ", "keyboard", "drawbar"]
"tags": [
"organ",
"keyboard",
"drawbar"
]
},
"midi_targets": [0],
"midi_targets": [
0
],
"output_node": 4,
"nodes": [
{
@ -14,7 +20,10 @@
"node_type": "MidiInput",
"name": "MIDI In",
"parameters": {},
"position": [100.0, 200.0]
"position": [
100.0,
200.0
]
},
{
"id": 1,
@ -23,7 +32,10 @@
"parameters": {
"0": 8.0
},
"position": [400.0, 200.0],
"position": [
400.0,
200.0
],
"template_graph": {
"metadata": {
"name": "Voice Template",
@ -32,7 +44,9 @@
"version": 1,
"tags": []
},
"midi_targets": [0],
"midi_targets": [
0
],
"output_node": 15,
"nodes": [
{
@ -40,14 +54,20 @@
"node_type": "TemplateInput",
"name": "Template Input",
"parameters": {},
"position": [-200.0, 0.0]
"position": [
-200.0,
0.0
]
},
{
"id": 1,
"node_type": "MidiToCV",
"name": "MIDICV",
"name": "MIDI\u2192CV",
"parameters": {},
"position": [100.0, 0.0]
"position": [
100.0,
0.0
]
},
{
"id": 2,
@ -56,7 +76,10 @@
"parameters": {
"0": -1.0
},
"position": [250.0, -300.0]
"position": [
250.0,
-300.0
]
},
{
"id": 3,
@ -65,7 +88,10 @@
"parameters": {
"0": 1.0
},
"position": [250.0, 200.0]
"position": [
250.0,
200.0
]
},
{
"id": 4,
@ -76,7 +102,10 @@
"1": 0.8,
"2": 0.0
},
"position": [700.0, -300.0]
"position": [
700.0,
-300.0
]
},
{
"id": 5,
@ -87,7 +116,10 @@
"1": 0.65,
"2": 0.0
},
"position": [700.0, -100.0]
"position": [
700.0,
-100.0
]
},
{
"id": 6,
@ -96,7 +128,10 @@
"parameters": {
"0": 0.0
},
"position": [450.0, -300.0]
"position": [
450.0,
-300.0
]
},
{
"id": 7,
@ -105,7 +140,10 @@
"parameters": {
"0": 0.0
},
"position": [450.0, 200.0]
"position": [
450.0,
200.0
]
},
{
"id": 8,
@ -116,7 +154,10 @@
"1": 0.4,
"2": 0.0
},
"position": [700.0, 100.0]
"position": [
700.0,
100.0
]
},
{
"id": 9,
@ -125,7 +166,10 @@
"parameters": {
"0": 1.585
},
"position": [250.0, 400.0]
"position": [
250.0,
400.0
]
},
{
"id": 10,
@ -134,7 +178,10 @@
"parameters": {
"0": 0.0
},
"position": [450.0, 400.0]
"position": [
450.0,
400.0
]
},
{
"id": 11,
@ -145,7 +192,10 @@
"1": 0.3,
"2": 0.0
},
"position": [700.0, 300.0]
"position": [
700.0,
300.0
]
},
{
"id": 12,
@ -157,7 +207,10 @@
"2": 0.9,
"3": 0.08
},
"position": [700.0, 500.0]
"position": [
700.0,
500.0
]
},
{
"id": 13,
@ -169,7 +222,10 @@
"2": 0.6,
"3": 0.4
},
"position": [1000.0, 0.0]
"position": [
1000.0,
0.0
]
},
{
"id": 14,
@ -178,36 +234,137 @@
"parameters": {
"0": 1.0
},
"position": [1250.0, 0.0]
"position": [
1250.0,
0.0
]
},
{
"id": 15,
"node_type": "TemplateOutput",
"name": "Template Output",
"parameters": {},
"position": [1500.0, 0.0]
"position": [
1500.0,
0.0
]
}
],
"connections": [
{ "from_node": 0, "from_port": 0, "to_node": 1, "to_port": 0 },
{ "from_node": 1, "from_port": 0, "to_node": 5, "to_port": 0 },
{ "from_node": 1, "from_port": 0, "to_node": 6, "to_port": 0 },
{ "from_node": 2, "from_port": 0, "to_node": 6, "to_port": 1 },
{ "from_node": 6, "from_port": 0, "to_node": 4, "to_port": 0 },
{ "from_node": 1, "from_port": 0, "to_node": 7, "to_port": 0 },
{ "from_node": 3, "from_port": 0, "to_node": 7, "to_port": 1 },
{ "from_node": 7, "from_port": 0, "to_node": 8, "to_port": 0 },
{ "from_node": 1, "from_port": 0, "to_node": 10, "to_port": 0 },
{ "from_node": 9, "from_port": 0, "to_node": 10, "to_port": 1 },
{ "from_node": 10, "from_port": 0, "to_node": 11, "to_port": 0 },
{ "from_node": 1, "from_port": 1, "to_node": 12, "to_port": 0 },
{ "from_node": 4, "from_port": 0, "to_node": 13, "to_port": 0 },
{ "from_node": 5, "from_port": 0, "to_node": 13, "to_port": 1 },
{ "from_node": 8, "from_port": 0, "to_node": 13, "to_port": 2 },
{ "from_node": 11, "from_port": 0, "to_node": 13, "to_port": 3 },
{ "from_node": 13, "from_port": 0, "to_node": 14, "to_port": 0 },
{ "from_node": 12, "from_port": 0, "to_node": 14, "to_port": 1 },
{ "from_node": 14, "from_port": 0, "to_node": 15, "to_port": 0 }
{
"from_node": 0,
"from_port": 0,
"to_node": 1,
"to_port": 0
},
{
"from_node": 1,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 1,
"from_port": 0,
"to_node": 6,
"to_port": 0
},
{
"from_node": 2,
"from_port": 0,
"to_node": 6,
"to_port": 1
},
{
"from_node": 6,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 1,
"from_port": 0,
"to_node": 7,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 7,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 8,
"to_port": 0
},
{
"from_node": 1,
"from_port": 0,
"to_node": 10,
"to_port": 0
},
{
"from_node": 9,
"from_port": 0,
"to_node": 10,
"to_port": 1
},
{
"from_node": 10,
"from_port": 0,
"to_node": 11,
"to_port": 0
},
{
"from_node": 1,
"from_port": 1,
"to_node": 12,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 13,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 13,
"to_port": 1
},
{
"from_node": 8,
"from_port": 0,
"to_node": 13,
"to_port": 2
},
{
"from_node": 11,
"from_port": 0,
"to_node": 13,
"to_port": 3
},
{
"from_node": 13,
"from_port": 0,
"to_node": 14,
"to_port": 0
},
{
"from_node": 12,
"from_port": 0,
"to_node": 14,
"to_port": 1
},
{
"from_node": 14,
"from_port": 0,
"to_node": 15,
"to_port": 0
}
]
}
},
@ -219,7 +376,10 @@
"0": 6.0,
"1": 0.15
},
"position": [700.0, 200.0]
"position": [
700.0,
200.0
]
},
{
"id": 3,
@ -230,20 +390,170 @@
"1": 0.5,
"2": 0.3
},
"position": [1000.0, 200.0]
"position": [
1000.0,
200.0
]
},
{
"id": 4,
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [1300.0, 200.0]
"position": [
1990.0,
200.0
]
},
{
"id": 5,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
1300.0,
200.0
]
},
{
"id": 6,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
1530.0,
200.0
]
},
{
"id": 7,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1760.0,
200.0
]
},
{
"id": 8,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
1530.0,
430.0
]
},
{
"id": 9,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
1300.0,
430.0
]
}
],
"connections": [
{ "from_node": 0, "from_port": 0, "to_node": 1, "to_port": 0 },
{ "from_node": 1, "from_port": 0, "to_node": 2, "to_port": 0 },
{ "from_node": 2, "from_port": 0, "to_node": 3, "to_port": 0 },
{ "from_node": 3, "from_port": 0, "to_node": 4, "to_port": 0 }
{
"from_node": 0,
"from_port": 0,
"to_node": 1,
"to_port": 0
},
{
"from_node": 1,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 2,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 6,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 7,
"to_port": 0
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 8,
"from_port": 0,
"to_node": 7,
"to_port": 1
},
{
"from_node": 9,
"from_port": 0,
"to_node": 6,
"to_port": 1
}
]
}
}

View File

@ -4,9 +4,15 @@
"description": "Acoustic grand piano with multi-octave sampling",
"author": "Lightningbeam",
"version": 1,
"tags": ["piano", "keyboard", "acoustic"]
"tags": [
"piano",
"keyboard",
"acoustic"
]
},
"midi_targets": [0],
"midi_targets": [
0
],
"output_node": 2,
"nodes": [
{
@ -14,7 +20,10 @@
"node_type": "MidiInput",
"name": "MIDI In",
"parameters": {},
"position": [100.0, 100.0]
"position": [
100.0,
100.0
]
},
{
"id": 1,
@ -29,34 +38,272 @@
"sample_data": {
"type": "multi_sampler",
"layers": [
{ "file_path": "samples/C1.mp3", "key_min": 0, "key_max": 28, "root_key": 24, "velocity_min": 0, "velocity_max": 127 },
{ "file_path": "samples/A1.mp3", "key_min": 29, "key_max": 34, "root_key": 33, "velocity_min": 0, "velocity_max": 127 },
{ "file_path": "samples/C2.mp3", "key_min": 35, "key_max": 40, "root_key": 36, "velocity_min": 0, "velocity_max": 127 },
{ "file_path": "samples/A2.mp3", "key_min": 41, "key_max": 46, "root_key": 45, "velocity_min": 0, "velocity_max": 127 },
{ "file_path": "samples/C3.mp3", "key_min": 47, "key_max": 52, "root_key": 48, "velocity_min": 0, "velocity_max": 127 },
{ "file_path": "samples/A3.mp3", "key_min": 53, "key_max": 58, "root_key": 57, "velocity_min": 0, "velocity_max": 127 },
{ "file_path": "samples/C4.mp3", "key_min": 59, "key_max": 64, "root_key": 60, "velocity_min": 0, "velocity_max": 127 },
{ "file_path": "samples/A4.mp3", "key_min": 65, "key_max": 70, "root_key": 69, "velocity_min": 0, "velocity_max": 127 },
{ "file_path": "samples/C5.mp3", "key_min": 71, "key_max": 76, "root_key": 72, "velocity_min": 0, "velocity_max": 127 },
{ "file_path": "samples/A5.mp3", "key_min": 77, "key_max": 82, "root_key": 81, "velocity_min": 0, "velocity_max": 127 },
{ "file_path": "samples/C6.mp3", "key_min": 83, "key_max": 88, "root_key": 84, "velocity_min": 0, "velocity_max": 127 },
{ "file_path": "samples/A6.mp3", "key_min": 89, "key_max": 94, "root_key": 93, "velocity_min": 0, "velocity_max": 127 },
{ "file_path": "samples/C7.mp3", "key_min": 95, "key_max": 100, "root_key": 96, "velocity_min": 0, "velocity_max": 127 },
{ "file_path": "samples/A7.mp3", "key_min": 101, "key_max": 127, "root_key": 105, "velocity_min": 0, "velocity_max": 127 }
{
"file_path": "samples/C1.mp3",
"key_min": 0,
"key_max": 28,
"root_key": 24,
"velocity_min": 0,
"velocity_max": 127
},
{
"file_path": "samples/A1.mp3",
"key_min": 29,
"key_max": 34,
"root_key": 33,
"velocity_min": 0,
"velocity_max": 127
},
{
"file_path": "samples/C2.mp3",
"key_min": 35,
"key_max": 40,
"root_key": 36,
"velocity_min": 0,
"velocity_max": 127
},
{
"file_path": "samples/A2.mp3",
"key_min": 41,
"key_max": 46,
"root_key": 45,
"velocity_min": 0,
"velocity_max": 127
},
{
"file_path": "samples/C3.mp3",
"key_min": 47,
"key_max": 52,
"root_key": 48,
"velocity_min": 0,
"velocity_max": 127
},
{
"file_path": "samples/A3.mp3",
"key_min": 53,
"key_max": 58,
"root_key": 57,
"velocity_min": 0,
"velocity_max": 127
},
{
"file_path": "samples/C4.mp3",
"key_min": 59,
"key_max": 64,
"root_key": 60,
"velocity_min": 0,
"velocity_max": 127
},
{
"file_path": "samples/A4.mp3",
"key_min": 65,
"key_max": 70,
"root_key": 69,
"velocity_min": 0,
"velocity_max": 127
},
{
"file_path": "samples/C5.mp3",
"key_min": 71,
"key_max": 76,
"root_key": 72,
"velocity_min": 0,
"velocity_max": 127
},
{
"file_path": "samples/A5.mp3",
"key_min": 77,
"key_max": 82,
"root_key": 81,
"velocity_min": 0,
"velocity_max": 127
},
{
"file_path": "samples/C6.mp3",
"key_min": 83,
"key_max": 88,
"root_key": 84,
"velocity_min": 0,
"velocity_max": 127
},
{
"file_path": "samples/A6.mp3",
"key_min": 89,
"key_max": 94,
"root_key": 93,
"velocity_min": 0,
"velocity_max": 127
},
{
"file_path": "samples/C7.mp3",
"key_min": 95,
"key_max": 100,
"root_key": 96,
"velocity_min": 0,
"velocity_max": 127
},
{
"file_path": "samples/A7.mp3",
"key_min": 101,
"key_max": 127,
"root_key": 105,
"velocity_min": 0,
"velocity_max": 127
}
]
},
"position": [350.0, 0.0]
"position": [
350.0,
0.0
]
},
{
"id": 2,
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [700.0, 100.0]
"position": [
1390.0,
100.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
100.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
100.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
100.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
330.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
330.0
]
}
],
"connections": [
{ "from_node": 0, "from_port": 0, "to_node": 1, "to_port": 0 },
{ "from_node": 1, "from_port": 0, "to_node": 2, "to_port": 0 }
{
"from_node": 0,
"from_port": 0,
"to_node": 1,
"to_port": 0
},
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}
}

View File

@ -162,10 +162,104 @@
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
1390.0,
100.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
100.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
100.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
100.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
330.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
330.0
]
}
],
"connections": [
@ -178,8 +272,38 @@
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}

View File

@ -160,10 +160,104 @@
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
1390.0,
100.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
100.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
100.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
100.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
330.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
330.0
]
}
],
"connections": [
@ -176,8 +270,38 @@
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}

View File

@ -159,10 +159,104 @@
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
1390.0,
100.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
100.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
100.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
100.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
330.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
330.0
]
}
],
"connections": [
@ -175,8 +269,38 @@
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}

View File

@ -194,10 +194,104 @@
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
1390.0,
100.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
100.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
100.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
100.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
330.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
330.0
]
}
],
"connections": [
@ -210,8 +304,38 @@
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}

View File

@ -528,10 +528,104 @@
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
1390.0,
100.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
100.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
100.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
100.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
330.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
330.0
]
}
],
"connections": [
@ -544,8 +638,38 @@
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}

View File

@ -186,10 +186,104 @@
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
1390.0,
100.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
100.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
100.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
100.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
330.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
330.0
]
}
],
"connections": [
@ -202,8 +296,38 @@
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}

View File

@ -177,10 +177,104 @@
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
1390.0,
100.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
100.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
100.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
100.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
330.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
330.0
]
}
],
"connections": [
@ -193,8 +287,38 @@
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}

View File

@ -4,9 +4,15 @@
"description": "Thick sub bass with sawtooth oscillator (polyphonic)",
"author": "Lightningbeam",
"version": 2,
"tags": ["bass", "sub", "synth"]
"tags": [
"bass",
"sub",
"synth"
]
},
"midi_targets": [0],
"midi_targets": [
0
],
"output_node": 2,
"nodes": [
{
@ -14,7 +20,10 @@
"node_type": "MidiInput",
"name": "MIDI In",
"parameters": {},
"position": [100.0, 150.0]
"position": [
100.0,
150.0
]
},
{
"id": 1,
@ -23,7 +32,10 @@
"parameters": {
"0": 8.0
},
"position": [400.0, 150.0],
"position": [
400.0,
150.0
],
"template_graph": {
"metadata": {
"name": "Voice Template",
@ -32,7 +44,9 @@
"version": 1,
"tags": []
},
"midi_targets": [0],
"midi_targets": [
0
],
"output_node": 6,
"nodes": [
{
@ -40,14 +54,20 @@
"node_type": "TemplateInput",
"name": "Template Input",
"parameters": {},
"position": [-200.0, 0.0]
"position": [
-200.0,
0.0
]
},
{
"id": 1,
"node_type": "MidiToCV",
"name": "MIDICV",
"name": "MIDI\u2192CV",
"parameters": {},
"position": [100.0, 0.0]
"position": [
100.0,
0.0
]
},
{
"id": 2,
@ -58,7 +78,10 @@
"1": 0.7,
"2": 1.0
},
"position": [400.0, -100.0]
"position": [
400.0,
-100.0
]
},
{
"id": 3,
@ -70,7 +93,10 @@
"2": 0.8,
"3": 0.3
},
"position": [400.0, 200.0]
"position": [
400.0,
200.0
]
},
{
"id": 4,
@ -79,7 +105,10 @@
"parameters": {
"0": 1.0
},
"position": [700.0, 0.0]
"position": [
700.0,
0.0
]
},
{
"id": 5,
@ -90,24 +119,65 @@
"1": 1.5,
"2": 0.0
},
"position": [900.0, 0.0]
"position": [
900.0,
0.0
]
},
{
"id": 6,
"node_type": "TemplateOutput",
"name": "Template Output",
"parameters": {},
"position": [1100.0, 0.0]
"position": [
1100.0,
0.0
]
}
],
"connections": [
{ "from_node": 0, "from_port": 0, "to_node": 1, "to_port": 0 },
{ "from_node": 1, "from_port": 0, "to_node": 2, "to_port": 0 },
{ "from_node": 1, "from_port": 1, "to_node": 3, "to_port": 0 },
{ "from_node": 2, "from_port": 0, "to_node": 4, "to_port": 0 },
{ "from_node": 3, "from_port": 0, "to_node": 4, "to_port": 1 },
{ "from_node": 4, "from_port": 0, "to_node": 5, "to_port": 0 },
{ "from_node": 5, "from_port": 0, "to_node": 6, "to_port": 0 }
{
"from_node": 0,
"from_port": 0,
"to_node": 1,
"to_port": 0
},
{
"from_node": 1,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 1,
"from_port": 1,
"to_node": 3,
"to_port": 0
},
{
"from_node": 2,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 1
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 6,
"to_port": 0
}
]
}
},
@ -116,11 +186,148 @@
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [700.0, 150.0]
"position": [
1390.0,
150.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
150.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
150.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
150.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
380.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
380.0
]
}
],
"connections": [
{ "from_node": 0, "from_port": 0, "to_node": 1, "to_port": 0 },
{ "from_node": 1, "from_port": 0, "to_node": 2, "to_port": 0 }
{
"from_node": 0,
"from_port": 0,
"to_node": 1,
"to_port": 0
},
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}
}

View File

@ -4,9 +4,15 @@
"description": "Piercing lead synth with filter modulation (polyphonic)",
"author": "Lightningbeam",
"version": 2,
"tags": ["lead", "synth", "solo"]
"tags": [
"lead",
"synth",
"solo"
]
},
"midi_targets": [0],
"midi_targets": [
0
],
"output_node": 2,
"nodes": [
{
@ -14,7 +20,10 @@
"node_type": "MidiInput",
"name": "MIDI In",
"parameters": {},
"position": [100.0, 150.0]
"position": [
100.0,
150.0
]
},
{
"id": 1,
@ -23,7 +32,10 @@
"parameters": {
"0": 8.0
},
"position": [400.0, 150.0],
"position": [
400.0,
150.0
],
"template_graph": {
"metadata": {
"name": "Voice Template",
@ -32,7 +44,9 @@
"version": 1,
"tags": []
},
"midi_targets": [0],
"midi_targets": [
0
],
"output_node": 7,
"nodes": [
{
@ -40,14 +54,20 @@
"node_type": "TemplateInput",
"name": "Template Input",
"parameters": {},
"position": [-200.0, 0.0]
"position": [
-200.0,
0.0
]
},
{
"id": 1,
"node_type": "MidiToCV",
"name": "MIDICV",
"name": "MIDI\u2192CV",
"parameters": {},
"position": [100.0, 0.0]
"position": [
100.0,
0.0
]
},
{
"id": 2,
@ -58,7 +78,10 @@
"1": 0.6,
"2": 2.0
},
"position": [400.0, -100.0]
"position": [
400.0,
-100.0
]
},
{
"id": 3,
@ -70,7 +93,10 @@
"2": 0.0,
"3": 0.0
},
"position": [400.0, 200.0]
"position": [
400.0,
200.0
]
},
{
"id": 4,
@ -81,7 +107,10 @@
"1": 2.0,
"2": 0.0
},
"position": [700.0, -80.0]
"position": [
700.0,
-80.0
]
},
{
"id": 5,
@ -93,7 +122,10 @@
"2": 0.6,
"3": 0.2
},
"position": [700.0, 200.0]
"position": [
700.0,
200.0
]
},
{
"id": 6,
@ -102,25 +134,71 @@
"parameters": {
"0": 1.0
},
"position": [1000.0, 50.0]
"position": [
1000.0,
50.0
]
},
{
"id": 7,
"node_type": "TemplateOutput",
"name": "Template Output",
"parameters": {},
"position": [1200.0, 50.0]
"position": [
1200.0,
50.0
]
}
],
"connections": [
{ "from_node": 0, "from_port": 0, "to_node": 1, "to_port": 0 },
{ "from_node": 1, "from_port": 0, "to_node": 2, "to_port": 0 },
{ "from_node": 1, "from_port": 1, "to_node": 5, "to_port": 0 },
{ "from_node": 2, "from_port": 0, "to_node": 4, "to_port": 0 },
{ "from_node": 3, "from_port": 0, "to_node": 4, "to_port": 1 },
{ "from_node": 4, "from_port": 0, "to_node": 6, "to_port": 0 },
{ "from_node": 5, "from_port": 0, "to_node": 6, "to_port": 1 },
{ "from_node": 6, "from_port": 0, "to_node": 7, "to_port": 0 }
{
"from_node": 0,
"from_port": 0,
"to_node": 1,
"to_port": 0
},
{
"from_node": 1,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 1,
"from_port": 1,
"to_node": 5,
"to_port": 0
},
{
"from_node": 2,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 1
},
{
"from_node": 4,
"from_port": 0,
"to_node": 6,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 6,
"to_port": 1
},
{
"from_node": 6,
"from_port": 0,
"to_node": 7,
"to_port": 0
}
]
}
},
@ -129,11 +207,148 @@
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [700.0, 150.0]
"position": [
1390.0,
150.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
150.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
150.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
150.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
380.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
380.0
]
}
],
"connections": [
{ "from_node": 0, "from_port": 0, "to_node": 1, "to_port": 0 },
{ "from_node": 1, "from_port": 0, "to_node": 2, "to_port": 0 }
{
"from_node": 0,
"from_port": 0,
"to_node": 1,
"to_port": 0
},
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}
}

View File

@ -4,9 +4,15 @@
"description": "Ambient pad with reverb and chorus (polyphonic)",
"author": "Lightningbeam",
"version": 2,
"tags": ["pad", "ambient", "synth"]
"tags": [
"pad",
"ambient",
"synth"
]
},
"midi_targets": [0],
"midi_targets": [
0
],
"output_node": 4,
"nodes": [
{
@ -14,7 +20,10 @@
"node_type": "MidiInput",
"name": "MIDI In",
"parameters": {},
"position": [100.0, 150.0]
"position": [
100.0,
150.0
]
},
{
"id": 1,
@ -23,7 +32,10 @@
"parameters": {
"0": 8.0
},
"position": [400.0, 150.0],
"position": [
400.0,
150.0
],
"template_graph": {
"metadata": {
"name": "Voice Template",
@ -32,7 +44,9 @@
"version": 1,
"tags": []
},
"midi_targets": [0],
"midi_targets": [
0
],
"output_node": 8,
"nodes": [
{
@ -40,14 +54,20 @@
"node_type": "TemplateInput",
"name": "Template Input",
"parameters": {},
"position": [-200.0, 0.0]
"position": [
-200.0,
0.0
]
},
{
"id": 1,
"node_type": "MidiToCV",
"name": "MIDICV",
"name": "MIDI\u2192CV",
"parameters": {},
"position": [100.0, 0.0]
"position": [
100.0,
0.0
]
},
{
"id": 2,
@ -58,7 +78,10 @@
"1": 0.4,
"2": 0.0
},
"position": [400.0, -100.0]
"position": [
400.0,
-100.0
]
},
{
"id": 3,
@ -69,7 +92,10 @@
"1": 0.4,
"2": 0.0
},
"position": [400.0, 200.0]
"position": [
400.0,
200.0
]
},
{
"id": 4,
@ -81,7 +107,10 @@
"2": 0.0,
"3": 0.0
},
"position": [700.0, 50.0]
"position": [
700.0,
50.0
]
},
{
"id": 5,
@ -92,7 +121,10 @@
"1": 0.707,
"2": 0.0
},
"position": [900.0, -50.0]
"position": [
900.0,
-50.0
]
},
{
"id": 6,
@ -104,7 +136,10 @@
"2": 0.7,
"3": 1.0
},
"position": [900.0, 200.0]
"position": [
900.0,
200.0
]
},
{
"id": 7,
@ -113,27 +148,83 @@
"parameters": {
"0": 1.0
},
"position": [1100.0, 50.0]
"position": [
1100.0,
50.0
]
},
{
"id": 8,
"node_type": "TemplateOutput",
"name": "Template Output",
"parameters": {},
"position": [1300.0, 50.0]
"position": [
1300.0,
50.0
]
}
],
"connections": [
{ "from_node": 0, "from_port": 0, "to_node": 1, "to_port": 0 },
{ "from_node": 1, "from_port": 0, "to_node": 2, "to_port": 0 },
{ "from_node": 1, "from_port": 0, "to_node": 3, "to_port": 0 },
{ "from_node": 1, "from_port": 1, "to_node": 6, "to_port": 0 },
{ "from_node": 2, "from_port": 0, "to_node": 4, "to_port": 0 },
{ "from_node": 3, "from_port": 0, "to_node": 4, "to_port": 1 },
{ "from_node": 4, "from_port": 0, "to_node": 5, "to_port": 0 },
{ "from_node": 5, "from_port": 0, "to_node": 7, "to_port": 0 },
{ "from_node": 6, "from_port": 0, "to_node": 7, "to_port": 1 },
{ "from_node": 7, "from_port": 0, "to_node": 8, "to_port": 0 }
{
"from_node": 0,
"from_port": 0,
"to_node": 1,
"to_port": 0
},
{
"from_node": 1,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 1,
"from_port": 1,
"to_node": 6,
"to_port": 0
},
{
"from_node": 2,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 1
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 7,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 7,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 8,
"to_port": 0
}
]
}
},
@ -146,7 +237,10 @@
"1": 0.6,
"2": 0.4
},
"position": [700.0, 150.0]
"position": [
700.0,
150.0
]
},
{
"id": 3,
@ -157,20 +251,170 @@
"1": 0.5,
"2": 0.5
},
"position": [1000.0, 150.0]
"position": [
1000.0,
150.0
]
},
{
"id": 4,
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [1300.0, 150.0]
"position": [
1990.0,
150.0
]
},
{
"id": 5,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
1300.0,
150.0
]
},
{
"id": 6,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
1530.0,
150.0
]
},
{
"id": 7,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1760.0,
150.0
]
},
{
"id": 8,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
1530.0,
380.0
]
},
{
"id": 9,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
1300.0,
380.0
]
}
],
"connections": [
{ "from_node": 0, "from_port": 0, "to_node": 1, "to_port": 0 },
{ "from_node": 1, "from_port": 0, "to_node": 2, "to_port": 0 },
{ "from_node": 2, "from_port": 0, "to_node": 3, "to_port": 0 },
{ "from_node": 3, "from_port": 0, "to_node": 4, "to_port": 0 }
{
"from_node": 0,
"from_port": 0,
"to_node": 1,
"to_port": 0
},
{
"from_node": 1,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 2,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 6,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 7,
"to_port": 0
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 8,
"from_port": 0,
"to_node": 7,
"to_port": 1
},
{
"from_node": 9,
"from_port": 0,
"to_node": 6,
"to_port": 1
}
]
}
}

View File

@ -168,10 +168,104 @@
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
1390.0,
100.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
100.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
100.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
100.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
330.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
330.0
]
}
],
"connections": [
@ -184,8 +278,38 @@
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}

View File

@ -150,10 +150,104 @@
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
1390.0,
100.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
100.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
100.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
100.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
330.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
330.0
]
}
],
"connections": [
@ -166,8 +260,38 @@
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}

View File

@ -141,10 +141,104 @@
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
1390.0,
100.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
100.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
100.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
100.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
330.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
330.0
]
}
],
"connections": [
@ -157,8 +251,38 @@
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}

View File

@ -132,10 +132,104 @@
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
1390.0,
100.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
100.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
100.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
100.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
330.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
330.0
]
}
],
"connections": [
@ -148,8 +242,38 @@
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}

View File

@ -438,10 +438,104 @@
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
1390.0,
100.0
]
},
{
"id": 3,
"node_type": "Compressor",
"parameters": {
"0": -18.0,
"1": 4.0,
"2": 5.0,
"3": 50.0,
"4": 3.0,
"5": 3.0
},
"position": [
700.0,
100.0
]
},
{
"id": 4,
"node_type": "Pan",
"parameters": {
"0": 0.0
},
"position": [
930.0,
100.0
]
},
{
"id": 5,
"node_type": "Gain",
"parameters": {
"0": 1.0
},
"position": [
1160.0,
100.0
]
},
{
"id": 6,
"node_type": "AutomationInput",
"parameters": {
"0": 0.0,
"1": 2.0
},
"automation_display_name": "Volume",
"automation_keyframes": [
{
"time": 0.0,
"value": 1.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
930.0,
330.0
]
},
{
"id": 7,
"node_type": "AutomationInput",
"parameters": {
"0": -1.0,
"1": 1.0
},
"automation_display_name": "Pan",
"automation_keyframes": [
{
"time": 0.0,
"value": 0.0,
"interpolation": "linear",
"ease_out": [
0.58,
1.0
],
"ease_in": [
0.42,
0.0
]
}
],
"position": [
700.0,
330.0
]
}
],
"connections": [
@ -454,8 +548,38 @@
{
"from_node": 1,
"from_port": 0,
"to_node": 3,
"to_port": 0
},
{
"from_node": 3,
"from_port": 0,
"to_node": 4,
"to_port": 0
},
{
"from_node": 4,
"from_port": 0,
"to_node": 5,
"to_port": 0
},
{
"from_node": 5,
"from_port": 0,
"to_node": 2,
"to_port": 0
},
{
"from_node": 6,
"from_port": 0,
"to_node": 5,
"to_port": 1
},
{
"from_node": 7,
"from_port": 0,
"to_node": 4,
"to_port": 1
}
]
}