Add orchestral sampled instruments

This commit is contained in:
Skyler Lehmkuhl 2026-02-21 07:28:19 -05:00
parent 2222e68a3e
commit 84f1f8e7d7
225 changed files with 5241 additions and 1 deletions

View File

@ -231,7 +231,7 @@ impl Voice {
envelope_phase: EnvelopePhase::Attack,
envelope_value: 0.0,
crossfade_buffer: Vec::new(),
crossfade_length: 1000, // ~20ms at 48kHz (longer for smoother loops)
crossfade_length: 4800, // ~100ms at 48kHz — hides loop seams in sustained instruments
}
}
}

View File

@ -79,6 +79,8 @@ assets = [
["assets/icons/32x32.png", "usr/share/icons/hicolor/32x32/apps/lightningbeam-editor.png", "644"],
["assets/icons/128x128.png", "usr/share/icons/hicolor/128x128/apps/lightningbeam-editor.png", "644"],
["assets/icons/256x256.png", "usr/share/icons/hicolor/256x256/apps/lightningbeam-editor.png", "644"],
# Factory instrument presets and samples — copied to share dir, preserving directory tree
["target/release/presets/**/*", "usr/share/lightningbeam-editor/presets/", "644"],
]
[package.metadata.generate-rpm]
@ -121,3 +123,10 @@ mode = "644"
source = "assets/icons/256x256.png"
dest = "/usr/share/icons/hicolor/256x256/apps/lightningbeam-editor.png"
mode = "644"
# Factory instrument presets and samples (built by build.rs into target dir)
[[package.metadata.generate-rpm.assets]]
source = "target/release/presets/"
dest = "/usr/share/lightningbeam-editor/presets/"
mode = "644"
doc = false

View File

@ -5,6 +5,9 @@ use std::path::PathBuf;
fn main() {
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
// Copy factory instrument presets next to the binary (works on all platforms)
bundle_factory_presets();
if target_os == "windows" {
bundle_windows_dlls();
}
@ -128,6 +131,56 @@ fn bundle_windows_dlls() {
println!("cargo:warning=Bundled FFmpeg DLLs to {}", target_dir.display());
}
/// Copy factory instrument presets into target dir so they're next to the binary.
/// This makes them available for:
/// - Portable/AppImage builds (preset browser checks <exe>/presets/)
/// - Windows builds (same)
/// - cargo-deb/rpm packaging (assets reference target/release/presets/)
fn bundle_factory_presets() {
let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
let instruments_src = manifest_dir.join("../../src/assets/instruments");
let out_dir = env::var("OUT_DIR").unwrap();
let target_dir = PathBuf::from(&out_dir)
.parent().unwrap()
.parent().unwrap()
.parent().unwrap()
.to_path_buf();
let presets_dst = target_dir.join("presets");
if !instruments_src.exists() {
println!("cargo:warning=Factory instruments not found at {:?}, skipping", instruments_src);
return;
}
// Re-run if instruments change
println!("cargo:rerun-if-changed={}", instruments_src.display());
if let Err(e) = copy_dir_recursive(&instruments_src, &presets_dst) {
println!("cargo:warning=Failed to copy factory presets: {}", e);
}
}
/// Recursively copy a directory tree, preserving structure.
/// Only copies .json and .mp3 files (skips README.md, etc.)
fn copy_dir_recursive(src: &std::path::Path, dst: &std::path::Path) -> std::io::Result<()> {
fs::create_dir_all(dst)?;
for entry in fs::read_dir(src)? {
let entry = entry?;
let src_path = entry.path();
let dst_path = dst.join(entry.file_name());
if src_path.is_dir() {
copy_dir_recursive(&src_path, &dst_path)?;
} else if let Some(ext) = src_path.extension() {
let ext = ext.to_string_lossy().to_lowercase();
if ext == "json" || ext == "mp3" {
fs::copy(&src_path, &dst_path)?;
}
}
}
Ok(())
}
fn copy_library(lib_name: &str, search_paths: &[&str], lib_dir: &PathBuf) {
let mut copied = false;

View File

@ -0,0 +1,569 @@
#!/usr/bin/env python3
"""Build factory instrument presets from Virtual Playing Orchestra 3 samples.
Usage:
python3 scripts/build_instruments.py
Converts WAV samples to MP3 and generates MultiSampler JSON presets.
"""
import json
import os
import re
import subprocess
import sys
from pathlib import Path
VPO = Path.home() / "Downloads" / "Virtual-Playing-Orchestra3" / "libs"
INSTRUMENTS_DIR = Path(__file__).parent.parent / "src" / "assets" / "instruments"
# Note name to semitone offset (within octave)
NOTE_MAP = {
'c': 0, 'c#': 1, 'db': 1, 'd': 2, 'd#': 3, 'eb': 3,
'e': 4, 'f': 5, 'f#': 6, 'gb': 6, 'g': 7, 'g#': 8, 'ab': 8,
'a': 9, 'a#': 10, 'bb': 10, 'b': 11,
}
def note_to_midi(note_name: str, octave: int) -> int:
"""Convert note name + octave to MIDI number. C4 = 60."""
semitone = NOTE_MAP[note_name.lower()]
return (octave + 1) * 12 + semitone
def parse_sso_filename(filename: str) -> dict | None:
"""Parse SSO-style: instrument-sus-note-PB-loop.wav (e.g. 1st-violins-sus-a#3.wav)
Also handles flats: oboe-a#3, basses-sus-d#2, etc.
"""
m = re.search(r'([a-g][#b]?)(\d+)', filename.lower())
if not m:
return None
note, octave = m.group(1), int(m.group(2))
midi = note_to_midi(note, octave)
return {'midi': midi, 'note': f"{note.upper()}{octave}"}
def parse_nbo_filename(filename: str) -> dict | None:
"""Parse NBO-style: octave_note.wav (e.g. 3_Bb-PB-loop.wav)"""
m = re.match(r'(\d+)_([A-Ga-g][b#]?)', filename)
if not m:
return None
octave, note = int(m.group(1)), m.group(2)
midi = note_to_midi(note, octave)
return {'midi': midi, 'note': f"{note}{octave}"}
def parse_nbo_with_dynamics(filename: str) -> dict | None:
"""Parse NBO2-style with dynamics: octave_note_p.wav or octave_note.wav"""
m = re.match(r'(\d+)_([A-Ga-g][b#]?)(?:_(p|f|mf|ff))?', filename)
if not m:
return None
octave, note = int(m.group(1)), m.group(2)
dynamic = m.group(3)
midi = note_to_midi(note, octave)
return {'midi': midi, 'note': f"{note}{octave}", 'dynamic': dynamic}
def parse_mw_viola_filename(filename: str) -> dict | None:
"""Parse MW-style: Violas_note.wav (e.g. Violas_c4.wav, Violas_d#3.wav)"""
m = re.search(r'_([a-g][#b]?)(\d+)\.wav', filename.lower())
if not m:
return None
note, octave = m.group(1), int(m.group(2))
midi = note_to_midi(note, octave)
return {'midi': midi, 'note': f"{note.upper()}{octave}"}
def parse_mw_horn_filename(filename: str) -> dict | None:
"""Parse MW horn: horns-sus-ff-note-PB-loop.wav or horns-sus-mp-note-PB-loop.wav"""
# Extract dynamics marker (ff, mp) from filename
dyn_match = re.search(r'-(ff|mp|mf|p|pp)-', filename.lower())
dynamic = dyn_match.group(1) if dyn_match else None
# Extract note
m = re.search(r'([a-g][#b]?)(\d+)', filename.lower())
if not m:
return None
note, octave = m.group(1), int(m.group(2))
midi = note_to_midi(note, octave)
return {'midi': midi, 'note': f"{note.upper()}{octave}", 'dynamic': dynamic}
def parse_vsco_harp_filename(filename: str) -> dict | None:
"""Parse VSCO harp: KSHarp_Note_dyn.wav (e.g. KSHarp_A4_mf.wav)"""
m = re.search(r'KSHarp_([A-G][b#]?)(\d+)', filename)
if not m:
return None
note, octave = m.group(1), int(m.group(2))
midi = note_to_midi(note, octave)
return {'midi': midi, 'note': f"{note}{octave}"}
def convert_wav_to_mp3(wav_path: Path, mp3_path: Path, bitrate: str = '192k'):
"""Convert WAV to MP3 using ffmpeg with peak normalization."""
mp3_path.parent.mkdir(parents=True, exist_ok=True)
if mp3_path.exists():
return # Skip if already converted
# Peak-normalize to -1dBFS so all samples have consistent max level.
# Using dynaudnorm with very gentle settings to avoid changing the
# character of the sound — just brings everything to the same peak level.
subprocess.run([
'ffmpeg', '-i', str(wav_path),
'-af', 'loudnorm=I=-16:TP=-1:LRA=11',
'-ar', '44100', '-ab', bitrate,
'-y', '-loglevel', 'error',
str(mp3_path)
], check=True)
def compute_key_ranges(layers: list[dict]) -> list[dict]:
"""Compute key_min/key_max for each layer by splitting at midpoints between adjacent root notes."""
if not layers:
return layers
layers.sort(key=lambda l: l['root_key'])
for i, layer in enumerate(layers):
if i == 0:
layer['key_min'] = 0
else:
midpoint = (layers[i-1]['root_key'] + layer['root_key']) // 2 + 1
layer['key_min'] = midpoint
layers[i-1]['key_max'] = midpoint - 1
if i == len(layers) - 1:
layer['key_max'] = 127
return layers
def make_preset(name: str, description: str, tags: list[str], layers: list[dict],
attack: float = 0.01, release: float = 0.3) -> dict:
"""Generate a complete instrument preset JSON."""
return {
"metadata": {
"name": name,
"description": description,
"author": "Virtual Playing Orchestra 3",
"version": 1,
"tags": tags
},
"midi_targets": [0],
"output_node": 2,
"nodes": [
{
"id": 0,
"node_type": "MidiInput",
"name": "MIDI In",
"parameters": {},
"position": [100.0, 100.0]
},
{
"id": 1,
"node_type": "MultiSampler",
"name": f"{name} Sampler",
"parameters": {
"0": 1.0, # gain
"1": attack, # attack
"2": release, # release
"3": 0.0 # transpose
},
"sample_data": {
"type": "multi_sampler",
"layers": layers
},
"position": [350.0, 0.0]
},
{
"id": 2,
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [700.0, 100.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}
]
}
def build_simple_instrument(name: str, description: str, tags: list[str],
source_dir: Path, output_subdir: str,
filename_filter=None, parser=parse_sso_filename,
attack: float = 0.01, release: float = 0.3,
loop: bool = False):
"""Build a single-velocity instrument from a directory of WAV files."""
out_dir = INSTRUMENTS_DIR / output_subdir
samples_dir = out_dir / "samples"
samples_dir.mkdir(parents=True, exist_ok=True)
layers = []
wav_files = sorted(source_dir.glob("*.wav"))
for wav in wav_files:
if filename_filter and not filename_filter(wav.name):
continue
parsed = parser(wav.name)
if not parsed:
print(f" WARNING: Could not parse {wav.name}, skipping")
continue
mp3_name = f"{parsed['note']}.mp3"
mp3_path = samples_dir / mp3_name
print(f" Converting {wav.name} -> {mp3_name} (MIDI {parsed['midi']})")
convert_wav_to_mp3(wav, mp3_path)
layer = {
"file_path": f"samples/{mp3_name}",
"root_key": parsed['midi'],
"velocity_min": 0,
"velocity_max": 127,
}
if loop:
layer["loop_mode"] = "continuous"
layers.append(layer)
layers = compute_key_ranges(layers)
preset = make_preset(name, description, tags, layers, attack, release)
preset_path = out_dir / f"{output_subdir.split('/')[-1]}.json"
with open(preset_path, 'w') as f:
json.dump(preset, f, indent=2)
print(f" -> Wrote {preset_path} ({len(layers)} layers)")
return layers
def build_dynamics_instrument(name: str, description: str, tags: list[str],
source_dir: Path, output_subdir: str,
filename_filter=None, parser=parse_nbo_with_dynamics,
attack: float = 0.01, release: float = 0.3,
loop: bool = False):
"""Build an instrument with velocity layers from dynamics markings."""
out_dir = INSTRUMENTS_DIR / output_subdir
samples_dir = out_dir / "samples"
samples_dir.mkdir(parents=True, exist_ok=True)
# Group samples by dynamics level
# Map dynamics markings to velocity ranges (soft to loud)
DYNAMICS_ORDER = ['pp', 'p', 'mp', 'mf', 'f', 'ff']
dynamics_groups: dict[str | None, list[dict]] = {}
wav_files = sorted(source_dir.glob("*.wav"))
for wav in wav_files:
if filename_filter and not filename_filter(wav.name):
continue
parsed = parser(wav.name)
if not parsed:
print(f" WARNING: Could not parse {wav.name}, skipping")
continue
dyn = parsed.get('dynamic')
suffix = f"_{dyn}" if dyn else ""
mp3_name = f"{parsed['note']}{suffix}.mp3"
mp3_path = samples_dir / mp3_name
print(f" Converting {wav.name} -> {mp3_name} (MIDI {parsed['midi']}, dyn={dyn})")
convert_wav_to_mp3(wav, mp3_path)
layer = {
"file_path": f"samples/{mp3_name}",
"root_key": parsed['midi'],
}
if loop:
layer["loop_mode"] = "continuous"
dynamics_groups.setdefault(dyn, []).append(layer)
# Determine velocity ranges based on how many dynamics levels exist
# Treat None (unmarked) as forte — it's the "normal" dynamic
dyn_keys = sorted(dynamics_groups.keys(),
key=lambda d: DYNAMICS_ORDER.index(d) if d and d in DYNAMICS_ORDER else
(DYNAMICS_ORDER.index('f') if d is None else 3))
if len(dyn_keys) == 1:
# Only one dynamics level — full velocity
for layer in dynamics_groups[dyn_keys[0]]:
layer["velocity_min"] = 0
layer["velocity_max"] = 127
else:
num_levels = len(dyn_keys)
vel_step = 128 // num_levels
for i, dyn in enumerate(dyn_keys):
vel_min = i * vel_step
vel_max = (i + 1) * vel_step - 1 if i < num_levels - 1 else 127
for layer in dynamics_groups[dyn]:
layer["velocity_min"] = vel_min
layer["velocity_max"] = vel_max
# Compute key ranges separately for each velocity group
all_layers = []
for dyn, group in dynamics_groups.items():
group = compute_key_ranges(group)
all_layers.extend(group)
preset = make_preset(name, description, tags, all_layers, attack, release)
preset_path = out_dir / f"{output_subdir.split('/')[-1]}.json"
with open(preset_path, 'w') as f:
json.dump(preset, f, indent=2)
dyn_summary = ", ".join(f"{k or 'default'}: {len(v)}" for k, v in dynamics_groups.items())
print(f" -> Wrote {preset_path} ({len(all_layers)} layers: {dyn_summary})")
return all_layers
def build_combined_instrument(name: str, description: str, tags: list[str],
component_dirs: list[str], output_subdir: str,
attack: float = 0.01, release: float = 0.3):
"""Build a combined instrument that references samples from component instruments.
component_dirs: list of output_subdir paths for component instruments, ordered low to high pitch.
Splits the keyboard range across them.
"""
out_dir = INSTRUMENTS_DIR / output_subdir
out_dir.mkdir(parents=True, exist_ok=True)
# Load each component's preset to get its layers
all_component_layers = []
for comp_dir in component_dirs:
comp_path = INSTRUMENTS_DIR / comp_dir
json_files = list(comp_path.glob("*.json"))
if not json_files:
print(f" WARNING: No preset found in {comp_dir}")
continue
with open(json_files[0]) as f:
comp_preset = json.load(f)
comp_layers = comp_preset["nodes"][1]["sample_data"]["layers"]
# Adjust file paths to be relative from the combined instrument dir
rel_prefix = os.path.relpath(comp_path, out_dir)
for layer in comp_layers:
layer["file_path"] = f"{rel_prefix}/{layer['file_path']}"
all_component_layers.extend(comp_layers)
# Re-sort by root key and recompute ranges across all layers
# Group by velocity range to handle dynamics separately
vel_groups = {}
for layer in all_component_layers:
vel_key = (layer["velocity_min"], layer["velocity_max"])
vel_groups.setdefault(vel_key, []).append(layer)
final_layers = []
for vel_key, group in vel_groups.items():
group = compute_key_ranges(group)
# Preserve the original velocity range
for layer in group:
layer["velocity_min"] = vel_key[0]
layer["velocity_max"] = vel_key[1]
final_layers.extend(group)
preset = make_preset(name, description, tags, final_layers, attack, release)
preset_path = out_dir / f"{output_subdir.split('/')[-1]}.json"
with open(preset_path, 'w') as f:
json.dump(preset, f, indent=2)
print(f" -> Wrote {preset_path} ({len(final_layers)} layers from {len(component_dirs)} components)")
def main():
print("=== Building Lightningbeam Factory Instruments from VPO3 ===\n")
if not VPO.exists():
print(f"ERROR: VPO3 not found at {VPO}")
sys.exit(1)
# --- STRINGS ---
print("\n[1/14] Violin Section (SSO 1st Violins sustain)")
build_simple_instrument(
"Violin Section", "Orchestral violin section with sustained bowing",
["strings", "violin", "section", "orchestral"],
VPO / "SSO" / "Samples" / "1st Violins",
"strings/violin-section",
filename_filter=lambda f: 'sus' in f.lower(),
parser=parse_sso_filename,
attack=0.05, release=0.4,
loop=True,
)
print("\n[2/14] Viola Section (Mattias-Westlund)")
build_simple_instrument(
"Viola Section", "Orchestral viola section with sustained bowing",
["strings", "viola", "section", "orchestral"],
VPO / "Mattias-Westlund" / "ViolaSect" / "Samples",
"strings/viola-section",
parser=parse_mw_viola_filename,
attack=0.05, release=0.4,
loop=True,
)
print("\n[3/14] Cello Section (NBO sustain)")
build_simple_instrument(
"Cello Section", "Orchestral cello section with sustained bowing",
["strings", "cello", "section", "orchestral"],
VPO / "NoBudgetOrch" / "CelloSect" / "Sustain",
"strings/cello-section",
parser=parse_nbo_filename,
attack=0.05, release=0.4,
loop=True,
)
print("\n[4/14] Bass Section (SSO sustain)")
build_simple_instrument(
"Bass Section", "Orchestral double bass section with sustained bowing",
["strings", "bass", "contrabass", "section", "orchestral"],
VPO / "SSO" / "Samples" / "Basses",
"strings/bass-section",
filename_filter=lambda f: 'sus' in f.lower(),
parser=parse_sso_filename,
attack=0.08, release=0.5,
loop=True,
)
print("\n[5/14] Harp (VSCO2-CE)")
build_simple_instrument(
"Harp", "Concert harp",
["strings", "harp", "orchestral"],
VPO / "VSCO2-CE" / "Strings" / "Harp",
"strings/harp",
parser=parse_vsco_harp_filename,
attack=0.001, release=0.8,
)
# --- WOODWINDS ---
print("\n[6/14] Flute Section (NBO)")
build_simple_instrument(
"Flute", "Orchestral flute section",
["woodwinds", "flute", "section", "orchestral"],
VPO / "NoBudgetOrch" / "FluteSect",
"woodwinds/flute",
parser=parse_nbo_filename,
attack=0.03, release=0.3,
loop=True,
)
print("\n[7/14] Oboe (SSO solo)")
build_simple_instrument(
"Oboe", "Solo oboe",
["woodwinds", "oboe", "solo", "orchestral"],
VPO / "SSO" / "Samples" / "Oboe",
"woodwinds/oboe",
filename_filter=lambda f: f.endswith('.wav') and 'readme' not in f.lower(),
parser=parse_sso_filename,
attack=0.02, release=0.25,
loop=True,
)
print("\n[8/14] Clarinet Section (NBO)")
build_simple_instrument(
"Clarinet", "Orchestral clarinet section",
["woodwinds", "clarinet", "section", "orchestral"],
VPO / "NoBudgetOrch" / "ClarinetSect" / "Sustain",
"woodwinds/clarinet",
parser=parse_nbo_filename,
attack=0.02, release=0.25,
loop=True,
)
print("\n[9/14] Bassoon (SSO)")
build_simple_instrument(
"Bassoon", "Solo bassoon",
["woodwinds", "bassoon", "solo", "orchestral"],
VPO / "SSO" / "Samples" / "Bassoon",
"woodwinds/bassoon",
parser=parse_sso_filename,
attack=0.03, release=0.3,
loop=True,
)
# --- BRASS ---
print("\n[10/14] Horn Section (Mattias-Westlund, ff + mp dynamics)")
build_dynamics_instrument(
"Horn Section", "French horn section with forte and mezzo-piano dynamics",
["brass", "horn", "french horn", "section", "orchestral"],
VPO / "Mattias-Westlund" / "Horns" / "Samples",
"brass/horn-section",
parser=parse_mw_horn_filename,
attack=0.04, release=0.4,
loop=True,
)
print("\n[11/14] Trumpet Section (NBO2 with dynamics)")
build_dynamics_instrument(
"Trumpet Section", "Orchestral trumpet section with piano and forte dynamics",
["brass", "trumpet", "section", "orchestral"],
VPO / "NoBudgetOrch2" / "Trumpet" / "TrumpetSect" / "Sustain",
"brass/trumpet-section",
attack=0.02, release=0.3,
loop=True,
)
print("\n[12/14] Trombone Section (NBO2 with dynamics)")
build_dynamics_instrument(
"Trombone Section", "Orchestral trombone section with piano and forte dynamics",
["brass", "trombone", "section", "orchestral"],
VPO / "NoBudgetOrch2" / "Trombone" / "TromboneSect" / "Sustain",
"brass/trombone-section",
attack=0.03, release=0.35,
loop=True,
)
print("\n[13/14] Tuba (SSO sustain)")
build_simple_instrument(
"Tuba", "Orchestral tuba",
["brass", "tuba", "orchestral"],
VPO / "SSO" / "Samples" / "Tuba",
"brass/tuba",
filename_filter=lambda f: 'sus' in f.lower(),
parser=parse_sso_filename,
attack=0.04, release=0.4,
loop=True,
)
# --- PERCUSSION ---
print("\n[14/14] Timpani (NBO)")
build_simple_instrument(
"Timpani", "Orchestral timpani",
["percussion", "timpani", "orchestral"],
VPO / "NoBudgetOrch" / "Timpani",
"orchestral/timpani",
parser=lambda f: parse_sso_filename(f), # Note-octave format like A2-PB.wav
attack=0.001, release=1.5,
)
# --- COMBINED INSTRUMENTS ---
print("\n[Combined] Strings")
build_combined_instrument(
"Strings", "Full string section — auto-selects violin, viola, cello, or bass by pitch range",
["strings", "section", "orchestral", "combined"],
[
"strings/bass-section",
"strings/cello-section",
"strings/viola-section",
"strings/violin-section",
],
"strings/strings-combined",
attack=0.05, release=0.4,
)
print("\n[Combined] Woodwinds")
build_combined_instrument(
"Woodwinds", "Full woodwind section — auto-selects bassoon, clarinet, oboe, or flute by pitch range",
["woodwinds", "section", "orchestral", "combined"],
[
"woodwinds/bassoon",
"woodwinds/clarinet",
"woodwinds/oboe",
"woodwinds/flute",
],
"woodwinds/woodwinds-combined",
attack=0.03, release=0.3,
)
print("\n[Combined] Brass")
build_combined_instrument(
"Brass", "Full brass section — auto-selects tuba, trombone, horn, or trumpet by pitch range",
["brass", "section", "orchestral", "combined"],
[
"brass/tuba",
"brass/trombone-section",
"brass/horn-section",
"brass/trumpet-section",
],
"brass/brass-combined",
attack=0.03, release=0.35,
)
print("\n=== Done! ===")
if __name__ == '__main__':
main()

View File

@ -0,0 +1,758 @@
{
"metadata": {
"name": "Brass",
"description": "Full brass section \u2014 auto-selects tuba, trombone, horn, or trumpet by pitch range",
"author": "Virtual Playing Orchestra 3",
"version": 1,
"tags": [
"brass",
"section",
"orchestral",
"combined"
]
},
"midi_targets": [
0
],
"output_node": 2,
"nodes": [
{
"id": 0,
"node_type": "MidiInput",
"name": "MIDI In",
"parameters": {},
"position": [
100.0,
100.0
]
},
{
"id": 1,
"node_type": "MultiSampler",
"name": "Brass Sampler",
"parameters": {
"0": 1.0,
"1": 0.03,
"2": 0.35,
"3": 0.0
},
"sample_data": {
"type": "multi_sampler",
"layers": [
{
"file_path": "../tuba/samples/E1.mp3",
"root_key": 28,
"velocity_min": 0,
"velocity_max": 127,
"loop_mode": "continuous",
"key_min": 0,
"key_max": 29
},
{
"file_path": "../tuba/samples/G1.mp3",
"root_key": 31,
"velocity_min": 0,
"velocity_max": 127,
"loop_mode": "continuous",
"key_min": 30,
"key_max": 32
},
{
"file_path": "../tuba/samples/A#1.mp3",
"root_key": 34,
"velocity_min": 0,
"velocity_max": 127,
"loop_mode": "continuous",
"key_min": 33,
"key_max": 35
},
{
"file_path": "../tuba/samples/C#2.mp3",
"root_key": 37,
"velocity_min": 0,
"velocity_max": 127,
"loop_mode": "continuous",
"key_min": 36,
"key_max": 38
},
{
"file_path": "../tuba/samples/E2.mp3",
"root_key": 40,
"velocity_min": 0,
"velocity_max": 127,
"loop_mode": "continuous",
"key_min": 39,
"key_max": 41
},
{
"file_path": "../tuba/samples/G2.mp3",
"root_key": 43,
"velocity_min": 0,
"velocity_max": 127,
"loop_mode": "continuous",
"key_min": 42,
"key_max": 44
},
{
"file_path": "../tuba/samples/A#2.mp3",
"root_key": 46,
"velocity_min": 0,
"velocity_max": 127,
"loop_mode": "continuous",
"key_min": 45,
"key_max": 47
},
{
"file_path": "../tuba/samples/C#3.mp3",
"root_key": 49,
"velocity_min": 0,
"velocity_max": 127,
"loop_mode": "continuous",
"key_min": 48,
"key_max": 50
},
{
"file_path": "../tuba/samples/E3.mp3",
"root_key": 52,
"velocity_min": 0,
"velocity_max": 127,
"loop_mode": "continuous",
"key_min": 51,
"key_max": 127
},
{
"file_path": "../horn-section/samples/E2_ff.mp3",
"root_key": 40,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 0,
"key_max": 40
},
{
"file_path": "../trombone-section/samples/F2.mp3",
"root_key": 41,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 41,
"key_max": 42
},
{
"file_path": "../horn-section/samples/G2_ff.mp3",
"root_key": 43,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 43,
"key_max": 44
},
{
"file_path": "../trombone-section/samples/A2.mp3",
"root_key": 45,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 45,
"key_max": 45
},
{
"file_path": "../horn-section/samples/A#2_ff.mp3",
"root_key": 46,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 46,
"key_max": 47
},
{
"file_path": "../trombone-section/samples/C3.mp3",
"root_key": 48,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 48,
"key_max": 48
},
{
"file_path": "../horn-section/samples/C#3_ff.mp3",
"root_key": 49,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 49,
"key_max": 50
},
{
"file_path": "../trombone-section/samples/Eb3.mp3",
"root_key": 51,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 51,
"key_max": 51
},
{
"file_path": "../horn-section/samples/E3_ff.mp3",
"root_key": 52,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 52,
"key_max": 53
},
{
"file_path": "../trombone-section/samples/Gb3.mp3",
"root_key": 54,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 54,
"key_max": 54
},
{
"file_path": "../horn-section/samples/G3_ff.mp3",
"root_key": 55,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 55,
"key_max": 55
},
{
"file_path": "../trumpet-section/samples/G3.mp3",
"root_key": 55,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 56,
"key_max": 55
},
{
"file_path": "../trumpet-section/samples/Ab3.mp3",
"root_key": 56,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 56,
"key_max": 56
},
{
"file_path": "../trombone-section/samples/A3.mp3",
"root_key": 57,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 57,
"key_max": 57
},
{
"file_path": "../horn-section/samples/A#3_ff.mp3",
"root_key": 58,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 58,
"key_max": 58
},
{
"file_path": "../trumpet-section/samples/Bb3.mp3",
"root_key": 58,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 59,
"key_max": 59
},
{
"file_path": "../trombone-section/samples/C4.mp3",
"root_key": 60,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 60,
"key_max": 60
},
{
"file_path": "../trumpet-section/samples/C4.mp3",
"root_key": 60,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 61,
"key_max": 60
},
{
"file_path": "../horn-section/samples/C#4_ff.mp3",
"root_key": 61,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 61,
"key_max": 61
},
{
"file_path": "../trumpet-section/samples/D4.mp3",
"root_key": 62,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 62,
"key_max": 62
},
{
"file_path": "../trombone-section/samples/Eb4.mp3",
"root_key": 63,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 63,
"key_max": 63
},
{
"file_path": "../horn-section/samples/E4_ff.mp3",
"root_key": 64,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 64,
"key_max": 64
},
{
"file_path": "../trumpet-section/samples/E4.mp3",
"root_key": 64,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 65,
"key_max": 64
},
{
"file_path": "../trumpet-section/samples/F4.mp3",
"root_key": 65,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 65,
"key_max": 65
},
{
"file_path": "../trombone-section/samples/Gb4.mp3",
"root_key": 66,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 66,
"key_max": 66
},
{
"file_path": "../horn-section/samples/G4_ff.mp3",
"root_key": 67,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 67,
"key_max": 67
},
{
"file_path": "../trumpet-section/samples/G4.mp3",
"root_key": 67,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 68,
"key_max": 68
},
{
"file_path": "../trombone-section/samples/A4.mp3",
"root_key": 69,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 69,
"key_max": 69
},
{
"file_path": "../trumpet-section/samples/A4.mp3",
"root_key": 69,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 70,
"key_max": 69
},
{
"file_path": "../horn-section/samples/A#4_ff.mp3",
"root_key": 70,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 70,
"key_max": 70
},
{
"file_path": "../trumpet-section/samples/Bb4.mp3",
"root_key": 70,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 71,
"key_max": 71
},
{
"file_path": "../trombone-section/samples/C5.mp3",
"root_key": 72,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 72,
"key_max": 72
},
{
"file_path": "../trumpet-section/samples/C5.mp3",
"root_key": 72,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 73,
"key_max": 72
},
{
"file_path": "../horn-section/samples/C#5_ff.mp3",
"root_key": 73,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 73,
"key_max": 73
},
{
"file_path": "../trumpet-section/samples/D5.mp3",
"root_key": 74,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 74,
"key_max": 74
},
{
"file_path": "../trumpet-section/samples/Eb5.mp3",
"root_key": 75,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 75,
"key_max": 75
},
{
"file_path": "../horn-section/samples/E5_ff.mp3",
"root_key": 76,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 76,
"key_max": 76
},
{
"file_path": "../trumpet-section/samples/F5.mp3",
"root_key": 77,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 77,
"key_max": 78
},
{
"file_path": "../trumpet-section/samples/G5.mp3",
"root_key": 79,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 79,
"key_max": 80
},
{
"file_path": "../trumpet-section/samples/A5.mp3",
"root_key": 81,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 81,
"key_max": 82
},
{
"file_path": "../trumpet-section/samples/B5.mp3",
"root_key": 83,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 83,
"key_max": 84
},
{
"file_path": "../trumpet-section/samples/Db6.mp3",
"root_key": 85,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 85,
"key_max": 127
},
{
"file_path": "../horn-section/samples/E2_mp.mp3",
"root_key": 40,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 0,
"key_max": 40
},
{
"file_path": "../trombone-section/samples/F2_p.mp3",
"root_key": 41,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 41,
"key_max": 42
},
{
"file_path": "../horn-section/samples/G2_mp.mp3",
"root_key": 43,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 43,
"key_max": 44
},
{
"file_path": "../trombone-section/samples/Bb2_p.mp3",
"root_key": 46,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 45,
"key_max": 46
},
{
"file_path": "../horn-section/samples/A#2_mp.mp3",
"root_key": 46,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 47,
"key_max": 47
},
{
"file_path": "../horn-section/samples/C#3_mp.mp3",
"root_key": 49,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 48,
"key_max": 50
},
{
"file_path": "../trombone-section/samples/Eb3_p.mp3",
"root_key": 51,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 51,
"key_max": 51
},
{
"file_path": "../horn-section/samples/E3_mp.mp3",
"root_key": 52,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 52,
"key_max": 53
},
{
"file_path": "../horn-section/samples/G3_mp.mp3",
"root_key": 55,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 54,
"key_max": 55
},
{
"file_path": "../trombone-section/samples/Ab3_p.mp3",
"root_key": 56,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 56,
"key_max": 57
},
{
"file_path": "../horn-section/samples/A#3_mp.mp3",
"root_key": 58,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 58,
"key_max": 58
},
{
"file_path": "../trumpet-section/samples/Bb3_p.mp3",
"root_key": 58,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 59,
"key_max": 59
},
{
"file_path": "../trombone-section/samples/Db4_p.mp3",
"root_key": 61,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 60,
"key_max": 61
},
{
"file_path": "../horn-section/samples/C#4_mp.mp3",
"root_key": 61,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 62,
"key_max": 62
},
{
"file_path": "../trumpet-section/samples/Eb4_p.mp3",
"root_key": 63,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 63,
"key_max": 63
},
{
"file_path": "../horn-section/samples/E4_mp.mp3",
"root_key": 64,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 64,
"key_max": 65
},
{
"file_path": "../trombone-section/samples/Gb4_p.mp3",
"root_key": 66,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 66,
"key_max": 66
},
{
"file_path": "../horn-section/samples/G4_mp.mp3",
"root_key": 67,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 67,
"key_max": 67
},
{
"file_path": "../trumpet-section/samples/Ab4_p.mp3",
"root_key": 68,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 68,
"key_max": 69
},
{
"file_path": "../horn-section/samples/A#4_mp.mp3",
"root_key": 70,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 70,
"key_max": 70
},
{
"file_path": "../trombone-section/samples/B4_p.mp3",
"root_key": 71,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 71,
"key_max": 72
},
{
"file_path": "../horn-section/samples/C#5_mp.mp3",
"root_key": 73,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 73,
"key_max": 73
},
{
"file_path": "../trumpet-section/samples/Db5_p.mp3",
"root_key": 73,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 74,
"key_max": 74
},
{
"file_path": "../horn-section/samples/E5_mp.mp3",
"root_key": 76,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 75,
"key_max": 78
},
{
"file_path": "../trumpet-section/samples/Ab5_p.mp3",
"root_key": 80,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 79,
"key_max": 127
}
]
},
"position": [
350.0,
0.0
]
},
{
"id": 2,
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
700.0,
100.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
}
]
}

View File

@ -0,0 +1,309 @@
{
"metadata": {
"name": "Horn Section",
"description": "French horn section with forte and mezzo-piano dynamics",
"author": "Virtual Playing Orchestra 3",
"version": 1,
"tags": [
"brass",
"horn",
"french horn",
"section",
"orchestral"
]
},
"midi_targets": [
0
],
"output_node": 2,
"nodes": [
{
"id": 0,
"node_type": "MidiInput",
"name": "MIDI In",
"parameters": {},
"position": [
100.0,
100.0
]
},
{
"id": 1,
"node_type": "MultiSampler",
"name": "Horn Section Sampler",
"parameters": {
"0": 1.0,
"1": 0.04,
"2": 0.4,
"3": 0.0
},
"sample_data": {
"type": "multi_sampler",
"layers": [
{
"file_path": "samples/E2_ff.mp3",
"root_key": 40,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 0,
"key_max": 41
},
{
"file_path": "samples/G2_ff.mp3",
"root_key": 43,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 42,
"key_max": 44
},
{
"file_path": "samples/A#2_ff.mp3",
"root_key": 46,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 45,
"key_max": 47
},
{
"file_path": "samples/C#3_ff.mp3",
"root_key": 49,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 48,
"key_max": 50
},
{
"file_path": "samples/E3_ff.mp3",
"root_key": 52,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 51,
"key_max": 53
},
{
"file_path": "samples/G3_ff.mp3",
"root_key": 55,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 54,
"key_max": 56
},
{
"file_path": "samples/A#3_ff.mp3",
"root_key": 58,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 57,
"key_max": 59
},
{
"file_path": "samples/C#4_ff.mp3",
"root_key": 61,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 60,
"key_max": 62
},
{
"file_path": "samples/E4_ff.mp3",
"root_key": 64,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 63,
"key_max": 65
},
{
"file_path": "samples/G4_ff.mp3",
"root_key": 67,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 66,
"key_max": 68
},
{
"file_path": "samples/A#4_ff.mp3",
"root_key": 70,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 69,
"key_max": 71
},
{
"file_path": "samples/C#5_ff.mp3",
"root_key": 73,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 72,
"key_max": 74
},
{
"file_path": "samples/E5_ff.mp3",
"root_key": 76,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 75,
"key_max": 127
},
{
"file_path": "samples/E2_mp.mp3",
"root_key": 40,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 0,
"key_max": 41
},
{
"file_path": "samples/G2_mp.mp3",
"root_key": 43,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 42,
"key_max": 44
},
{
"file_path": "samples/A#2_mp.mp3",
"root_key": 46,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 45,
"key_max": 47
},
{
"file_path": "samples/C#3_mp.mp3",
"root_key": 49,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 48,
"key_max": 50
},
{
"file_path": "samples/E3_mp.mp3",
"root_key": 52,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 51,
"key_max": 53
},
{
"file_path": "samples/G3_mp.mp3",
"root_key": 55,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 54,
"key_max": 56
},
{
"file_path": "samples/A#3_mp.mp3",
"root_key": 58,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 57,
"key_max": 59
},
{
"file_path": "samples/C#4_mp.mp3",
"root_key": 61,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 60,
"key_max": 62
},
{
"file_path": "samples/E4_mp.mp3",
"root_key": 64,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 63,
"key_max": 65
},
{
"file_path": "samples/G4_mp.mp3",
"root_key": 67,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 66,
"key_max": 68
},
{
"file_path": "samples/A#4_mp.mp3",
"root_key": 70,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 69,
"key_max": 71
},
{
"file_path": "samples/C#5_mp.mp3",
"root_key": 73,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 72,
"key_max": 74
},
{
"file_path": "samples/E5_mp.mp3",
"root_key": 76,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 75,
"key_max": 127
}
]
},
"position": [
350.0,
0.0
]
},
{
"id": 2,
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
700.0,
100.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
}
]
}

View File

@ -0,0 +1,236 @@
{
"metadata": {
"name": "Trombone Section",
"description": "Orchestral trombone section with piano and forte dynamics",
"author": "Virtual Playing Orchestra 3",
"version": 1,
"tags": [
"brass",
"trombone",
"section",
"orchestral"
]
},
"midi_targets": [
0
],
"output_node": 2,
"nodes": [
{
"id": 0,
"node_type": "MidiInput",
"name": "MIDI In",
"parameters": {},
"position": [
100.0,
100.0
]
},
{
"id": 1,
"node_type": "MultiSampler",
"name": "Trombone Section Sampler",
"parameters": {
"0": 1.0,
"1": 0.03,
"2": 0.35,
"3": 0.0
},
"sample_data": {
"type": "multi_sampler",
"layers": [
{
"file_path": "samples/F2.mp3",
"root_key": 41,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 0,
"key_max": 43
},
{
"file_path": "samples/A2.mp3",
"root_key": 45,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 44,
"key_max": 46
},
{
"file_path": "samples/C3.mp3",
"root_key": 48,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 47,
"key_max": 49
},
{
"file_path": "samples/Eb3.mp3",
"root_key": 51,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 50,
"key_max": 52
},
{
"file_path": "samples/Gb3.mp3",
"root_key": 54,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 53,
"key_max": 55
},
{
"file_path": "samples/A3.mp3",
"root_key": 57,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 56,
"key_max": 58
},
{
"file_path": "samples/C4.mp3",
"root_key": 60,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 59,
"key_max": 61
},
{
"file_path": "samples/Eb4.mp3",
"root_key": 63,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 62,
"key_max": 64
},
{
"file_path": "samples/Gb4.mp3",
"root_key": 66,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 65,
"key_max": 67
},
{
"file_path": "samples/A4.mp3",
"root_key": 69,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 68,
"key_max": 70
},
{
"file_path": "samples/C5.mp3",
"root_key": 72,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 71,
"key_max": 127
},
{
"file_path": "samples/F2_p.mp3",
"root_key": 41,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 0,
"key_max": 43
},
{
"file_path": "samples/Bb2_p.mp3",
"root_key": 46,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 44,
"key_max": 48
},
{
"file_path": "samples/Eb3_p.mp3",
"root_key": 51,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 49,
"key_max": 53
},
{
"file_path": "samples/Ab3_p.mp3",
"root_key": 56,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 54,
"key_max": 58
},
{
"file_path": "samples/Db4_p.mp3",
"root_key": 61,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 59,
"key_max": 63
},
{
"file_path": "samples/Gb4_p.mp3",
"root_key": 66,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 64,
"key_max": 68
},
{
"file_path": "samples/B4_p.mp3",
"root_key": 71,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 69,
"key_max": 127
}
]
},
"position": [
350.0,
0.0
]
},
{
"id": 2,
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
700.0,
100.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
}
]
}

View File

@ -0,0 +1,281 @@
{
"metadata": {
"name": "Trumpet Section",
"description": "Orchestral trumpet section with piano and forte dynamics",
"author": "Virtual Playing Orchestra 3",
"version": 1,
"tags": [
"brass",
"trumpet",
"section",
"orchestral"
]
},
"midi_targets": [
0
],
"output_node": 2,
"nodes": [
{
"id": 0,
"node_type": "MidiInput",
"name": "MIDI In",
"parameters": {},
"position": [
100.0,
100.0
]
},
{
"id": 1,
"node_type": "MultiSampler",
"name": "Trumpet Section Sampler",
"parameters": {
"0": 1.0,
"1": 0.02,
"2": 0.3,
"3": 0.0
},
"sample_data": {
"type": "multi_sampler",
"layers": [
{
"file_path": "samples/G3.mp3",
"root_key": 55,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 0,
"key_max": 55
},
{
"file_path": "samples/Ab3.mp3",
"root_key": 56,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 56,
"key_max": 57
},
{
"file_path": "samples/Bb3.mp3",
"root_key": 58,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 58,
"key_max": 59
},
{
"file_path": "samples/C4.mp3",
"root_key": 60,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 60,
"key_max": 61
},
{
"file_path": "samples/D4.mp3",
"root_key": 62,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 62,
"key_max": 63
},
{
"file_path": "samples/E4.mp3",
"root_key": 64,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 64,
"key_max": 64
},
{
"file_path": "samples/F4.mp3",
"root_key": 65,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 65,
"key_max": 66
},
{
"file_path": "samples/G4.mp3",
"root_key": 67,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 67,
"key_max": 68
},
{
"file_path": "samples/A4.mp3",
"root_key": 69,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 69,
"key_max": 69
},
{
"file_path": "samples/Bb4.mp3",
"root_key": 70,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 70,
"key_max": 71
},
{
"file_path": "samples/C5.mp3",
"root_key": 72,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 72,
"key_max": 73
},
{
"file_path": "samples/D5.mp3",
"root_key": 74,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 74,
"key_max": 74
},
{
"file_path": "samples/Eb5.mp3",
"root_key": 75,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 75,
"key_max": 76
},
{
"file_path": "samples/F5.mp3",
"root_key": 77,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 77,
"key_max": 78
},
{
"file_path": "samples/G5.mp3",
"root_key": 79,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 79,
"key_max": 80
},
{
"file_path": "samples/A5.mp3",
"root_key": 81,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 81,
"key_max": 82
},
{
"file_path": "samples/B5.mp3",
"root_key": 83,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 83,
"key_max": 84
},
{
"file_path": "samples/Db6.mp3",
"root_key": 85,
"loop_mode": "continuous",
"velocity_min": 64,
"velocity_max": 127,
"key_min": 85,
"key_max": 127
},
{
"file_path": "samples/Bb3_p.mp3",
"root_key": 58,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 0,
"key_max": 60
},
{
"file_path": "samples/Eb4_p.mp3",
"root_key": 63,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 61,
"key_max": 65
},
{
"file_path": "samples/Ab4_p.mp3",
"root_key": 68,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 66,
"key_max": 70
},
{
"file_path": "samples/Db5_p.mp3",
"root_key": 73,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 71,
"key_max": 76
},
{
"file_path": "samples/Ab5_p.mp3",
"root_key": 80,
"loop_mode": "continuous",
"velocity_min": 0,
"velocity_max": 63,
"key_min": 77,
"key_max": 127
}
]
},
"position": [
350.0,
0.0
]
},
{
"id": 2,
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
700.0,
100.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
}
]
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,154 @@
{
"metadata": {
"name": "Tuba",
"description": "Orchestral tuba",
"author": "Virtual Playing Orchestra 3",
"version": 1,
"tags": [
"brass",
"tuba",
"orchestral"
]
},
"midi_targets": [
0
],
"output_node": 2,
"nodes": [
{
"id": 0,
"node_type": "MidiInput",
"name": "MIDI In",
"parameters": {},
"position": [
100.0,
100.0
]
},
{
"id": 1,
"node_type": "MultiSampler",
"name": "Tuba Sampler",
"parameters": {
"0": 1.0,
"1": 0.04,
"2": 0.4,
"3": 0.0
},
"sample_data": {
"type": "multi_sampler",
"layers": [
{
"file_path": "samples/E1.mp3",
"root_key": 28,
"velocity_min": 0,
"velocity_max": 127,
"loop_mode": "continuous",
"key_min": 0,
"key_max": 29
},
{
"file_path": "samples/G1.mp3",
"root_key": 31,
"velocity_min": 0,
"velocity_max": 127,
"loop_mode": "continuous",
"key_min": 30,
"key_max": 32
},
{
"file_path": "samples/A#1.mp3",
"root_key": 34,
"velocity_min": 0,
"velocity_max": 127,
"loop_mode": "continuous",
"key_min": 33,
"key_max": 35
},
{
"file_path": "samples/C#2.mp3",
"root_key": 37,
"velocity_min": 0,
"velocity_max": 127,
"loop_mode": "continuous",
"key_min": 36,
"key_max": 38
},
{
"file_path": "samples/E2.mp3",
"root_key": 40,
"velocity_min": 0,
"velocity_max": 127,
"loop_mode": "continuous",
"key_min": 39,
"key_max": 41
},
{
"file_path": "samples/G2.mp3",
"root_key": 43,
"velocity_min": 0,
"velocity_max": 127,
"loop_mode": "continuous",
"key_min": 42,
"key_max": 44
},
{
"file_path": "samples/A#2.mp3",
"root_key": 46,
"velocity_min": 0,
"velocity_max": 127,
"loop_mode": "continuous",
"key_min": 45,
"key_max": 47
},
{
"file_path": "samples/C#3.mp3",
"root_key": 49,
"velocity_min": 0,
"velocity_max": 127,
"loop_mode": "continuous",
"key_min": 48,
"key_max": 50
},
{
"file_path": "samples/E3.mp3",
"root_key": 52,
"velocity_min": 0,
"velocity_max": 127,
"loop_mode": "continuous",
"key_min": 51,
"key_max": 127
}
]
},
"position": [
350.0,
0.0
]
},
{
"id": 2,
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
700.0,
100.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
}
]
}

View File

@ -0,0 +1,185 @@
{
"metadata": {
"name": "Timpani",
"description": "Orchestral timpani",
"author": "Virtual Playing Orchestra 3",
"version": 1,
"tags": [
"percussion",
"timpani",
"orchestral"
]
},
"midi_targets": [
0
],
"output_node": 2,
"nodes": [
{
"id": 0,
"node_type": "MidiInput",
"name": "MIDI In",
"parameters": {},
"position": [
100.0,
100.0
]
},
{
"id": 1,
"node_type": "MultiSampler",
"name": "Timpani Sampler",
"parameters": {
"0": 1.0,
"1": 0.001,
"2": 1.5,
"3": 0.0
},
"sample_data": {
"type": "multi_sampler",
"layers": [
{
"file_path": "samples/C2.mp3",
"root_key": 36,
"velocity_min": 0,
"velocity_max": 127,
"key_min": 0,
"key_max": 37
},
{
"file_path": "samples/D2.mp3",
"root_key": 38,
"velocity_min": 0,
"velocity_max": 127,
"key_min": 38,
"key_max": 39
},
{
"file_path": "samples/E2.mp3",
"root_key": 40,
"velocity_min": 0,
"velocity_max": 127,
"key_min": 40,
"key_max": 40
},
{
"file_path": "samples/F2.mp3",
"root_key": 41,
"velocity_min": 0,
"velocity_max": 127,
"key_min": 41,
"key_max": 42
},
{
"file_path": "samples/AB2.mp3",
"root_key": 44,
"velocity_min": 0,
"velocity_max": 127,
"key_min": 43,
"key_max": 44
},
{
"file_path": "samples/A2.mp3",
"root_key": 45,
"velocity_min": 0,
"velocity_max": 127,
"key_min": 45,
"key_max": 45
},
{
"file_path": "samples/BB2.mp3",
"root_key": 46,
"velocity_min": 0,
"velocity_max": 127,
"key_min": 46,
"key_max": 47
},
{
"file_path": "samples/C3.mp3",
"root_key": 48,
"velocity_min": 0,
"velocity_max": 127,
"key_min": 48,
"key_max": 49
},
{
"file_path": "samples/D3.mp3",
"root_key": 50,
"velocity_min": 0,
"velocity_max": 127,
"key_min": 50,
"key_max": 52
},
{
"file_path": "samples/GB3.mp3",
"root_key": 54,
"velocity_min": 0,
"velocity_max": 127,
"key_min": 53,
"key_max": 54
},
{
"file_path": "samples/G3.mp3",
"root_key": 55,
"velocity_min": 0,
"velocity_max": 127,
"key_min": 55,
"key_max": 55
},
{
"file_path": "samples/AB3.mp3",
"root_key": 56,
"velocity_min": 0,
"velocity_max": 127,
"key_min": 56,
"key_max": 56
},
{
"file_path": "samples/A3.mp3",
"root_key": 57,
"velocity_min": 0,
"velocity_max": 127,
"key_min": 57,
"key_max": 57
},
{
"file_path": "samples/BB3.mp3",
"root_key": 58,
"velocity_min": 0,
"velocity_max": 127,
"key_min": 58,
"key_max": 127
}
]
},
"position": [
350.0,
0.0
]
},
{
"id": 2,
"node_type": "AudioOutput",
"name": "Out",
"parameters": {},
"position": [
700.0,
100.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
}
]
}

Some files were not shown because too many files have changed in this diff Show More