From ab7fe51bb2f4155421dba184fdff79fceacbc811 Mon Sep 17 00:00:00 2001 From: Denis Tokarev Date: Tue, 20 Oct 2026 12:17:19 +1100 Subject: [PATCH] feat(packs): eight more default packs and 21 more instruments: Sonic Pi's samples, a solo cello, an erhu, a steel pan, synth drums, body percussion, glitch kits and sound effects --- CHANGELOG.md | 4 + README.md | 2 +- crates/claudius-cli/src/args.rs | 2 +- crates/claudius-packs/src/catalog.rs | 8 +- crates/claudius-packs/src/install.rs | 41 +++ .../claudius-packs/src/install/from_names.rs | 19 +- crates/claudius-packs/src/install/from_sfz.rs | 15 +- crates/claudius-packs/src/registry.json | 237 +++++++++++++++++- crates/claudius-packs/src/resolve.rs | 65 ++++- crates/claudius/src/script/sounds.rs | 2 +- docs/src/contributing/setup.md | 2 +- docs/src/getting-started/first-song.md | 4 +- docs/src/getting-started/install.md | 4 +- docs/src/getting-started/studio.md | 2 +- docs/src/guide/cli.md | 4 +- docs/src/guide/packs.md | 37 ++- docs/src/language/limits.md | 2 +- docs/src/language/quick-reference.md | 2 +- docs/src/language/sounds.md | 27 +- docs/src/learn/producers/sounds.md | 12 +- site/index.html | 4 +- skills/claudius-setup/SKILL.md | 2 +- skills/claudius-songs/references/script.md | 9 +- 23 files changed, 439 insertions(+), 67 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aba15f7..5f846b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ can't, so install this one the way you installed the last. Sample packs installed by 0.2 can hold damaged FLAC files: two notes of VCSL's harmonica take hundreds of MB and play as noise. `claudius-packs install --defaults` converts such files again and downloads nothing else. +Eight more default packs, and 21 more instruments in VCSL and FreePats: Sonic Pi's samples, a solo cello, an erhu, a +steel pan, synth drums, body percussion, glitch kits and sound effects, among them a hang, wine glasses and a TX81Z. +`claudius setup` downloads them, about 0.9 GB more ([Sample packs](https://github.com/devlato/claudius/blob/main/docs/src/guide/packs.md)). + ## [0.2.0] - 2026-10-19 ### Added diff --git a/README.md b/README.md index eed6d0b..19adb8f 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ terminal instead: ```sh curl -fsSL https://github.com/devlato/claudius/releases/latest/download/install.sh | sh # macOS (the app too), Linux irm https://github.com/devlato/claudius/releases/latest/download/install.ps1 | iex # Windows (PowerShell) -claudius setup # sample packs and listening models, about 3 GB to download +claudius setup # sample packs and listening models, about 4 GB to download ``` You can also build it from source; see [install](docs/src/getting-started/install.md). diff --git a/crates/claudius-cli/src/args.rs b/crates/claudius-cli/src/args.rs index 434869b..0b09202 100644 --- a/crates/claudius-cli/src/args.rs +++ b/crates/claudius-cli/src/args.rs @@ -201,7 +201,7 @@ pub(crate) enum Cmd { }, /// Print the script language reference Reference, - /// Download the default sample packs (about 1.1 GB) and earshot's listening models (about 0.8 GB) + /// Download the default sample packs (about 3.1 GB) and earshot's listening models (about 0.8 GB) Setup { /// do not ask before downloading #[arg(short, long)] diff --git a/crates/claudius-packs/src/catalog.rs b/crates/claudius-packs/src/catalog.rs index 48bc43f..677dfb1 100644 --- a/crates/claudius-packs/src/catalog.rs +++ b/crates/claudius-packs/src/catalog.rs @@ -91,6 +91,10 @@ pub struct InstSpec { // --- SFZ source #[serde(default)] pub sfz: Option, + /// the folder the SFZ's sample and include paths start from, when it is not the SFZ's own: a mapping file that + /// a program in another folder includes (the erhu's maps, used without the program's unison voices) + #[serde(default)] + pub base: Option, /// keep this many velocity layers (evenly spread) and widen them to cover the full range #[serde(default)] pub keep_layers: Option, @@ -103,7 +107,7 @@ pub struct InstSpec { /// one variant per distinct key range of the SFZ (unpitched percussion with several hits) #[serde(default)] pub kit_auto: bool, - /// regex on sample paths to leave out + /// regex on sample paths to leave out (SFZ regions and file-name sources) #[serde(default)] pub exclude: Option, /// shift roots and key ranges by octaves (mappings at written pitch, e.g. bass guitars one octave up) @@ -227,7 +231,7 @@ mod tests { } } } - assert!(default_mb < 3000.0, "default packs are {default_mb} MB"); + assert!(default_mb < 3300.0, "default packs are {default_mb} MB"); } #[test] diff --git a/crates/claudius-packs/src/install.rs b/crates/claudius-packs/src/install.rs index ea7f573..1ba7544 100644 --- a/crates/claudius-packs/src/install.rs +++ b/crates/claudius-packs/src/install.rs @@ -652,6 +652,47 @@ mod tests { assert!(glob_regex("**/*.wav").unwrap().is_match("a/b/c.wav")); } + #[test] + fn file_globs_leave_out_what_is_excluded() { + let listing: Vec<(String, u64)> = [ + "etc/samples/loop_amen.flac", + "etc/samples/loop_amen_full.flac", + "etc/samples/loop_breakbeat.flac", + "etc/samples/loop_garzul.flac", + "etc/samples/loop_tabla.flac", + "etc/samples/README.md", + "etc/samples/ambi_drone.flac", + ] + .iter() + .map(|p| (p.to_string(), 1)) + .collect(); + let got = matching(&listing, "etc/samples/loop_*.flac", Some("loop_(amen|breakbeat)")).unwrap(); + assert_eq!(got, ["etc/samples/loop_garzul.flac", "etc/samples/loop_tabla.flac"]); + assert_eq!(matching(&listing, "etc/samples/loop_*.flac", None).unwrap().len(), 5); + } + + #[test] + fn sfz_envelope_and_pan_follow_the_controller_defaults() { + // Karoryfer's style: knobs with defaults open the sustain and centre the pan + let src = r#" + set_cc10=64 set_cc103=127 + pan=-100 pan_oncc10=200 ampeg_sustain=0 ampeg_sustain_oncc103=100 ampeg_hold=0.5 +ampeg_decay=0.001 ampeg_decay_oncc102=6 + sample=a.wav key=60 +"#; + let file = sfz::parse(src, &mut |_| Ok(String::new())).unwrap(); + let z = sfz_zone(&file.regions[0], &file, 0, false); + assert!(z.pan.abs() < 1.0, "pan {}", z.pan); + assert_eq!(z.sustain, 1.0); + assert!((z.hold - 0.5).abs() < 1e-6); + assert!((z.decay - 0.001).abs() < 1e-6, "cc102 has no default, so it adds nothing: {}", z.decay); + // sfzinstruments' style: a bipolar curve centres the same knob + let file = + sfz::parse(" pan_oncc10=100 pan_curvecc10=1 sample=a.wav", &mut |_| Ok(String::new())) + .unwrap(); + assert_eq!(sfz_zone(&file.regions[0], &file, 0, false).pan, 0.0); + } + #[test] fn velocity_layer_reduction() { // 16 Salamander-style layers on one key diff --git a/crates/claudius-packs/src/install/from_names.rs b/crates/claudius-packs/src/install/from_names.rs index c6870e0..5b30b1f 100644 --- a/crates/claudius-packs/src/install/from_names.rs +++ b/crates/claudius-packs/src/install/from_names.rs @@ -120,6 +120,20 @@ pub(super) fn zones_from_names(paths: &[(u32, String)], vel_re: Option<&Regex>, zones } +/// the audio files of a listing that the glob matches and `exclude` (a regex) does not, sorted +pub(super) fn matching(listing: &[(String, u64)], glob: &str, exclude: Option<&str>) -> Result> { + let re = glob_regex(glob)?; + let exclude = exclude.map(Regex::new).transpose()?; + let mut matched: Vec = listing + .iter() + .map(|(p, _)| p.clone()) + .filter(|p| re.is_match(p) && !junk(p) && is_audio(p)) + .filter(|p| !exclude.as_ref().is_some_and(|x| x.is_match(p))) + .collect(); + matched.sort(); + Ok(matched) +} + pub(super) fn build_files(ctx: &mut Ctx, src_key: &str, spec: &InstSpec) -> Result { let kind = spec_kind(spec); let listing = ctx.sources.get_mut(src_key).expect("source").list()?; @@ -130,10 +144,7 @@ pub(super) fn build_files(ctx: &mut Ctx, src_key: &str, spec: &InstSpec) -> Resu let mut variants: Vec = Vec::new(); for part in parts { let glob = part.files.as_deref().ok_or_else(|| anyhow!("{}: variant without files", spec.name))?; - let re = glob_regex(glob)?; - let mut matched: Vec = - listing.iter().map(|(p, _)| p.clone()).filter(|p| re.is_match(p) && !junk(p) && is_audio(p)).collect(); - matched.sort(); + let mut matched = matching(&listing, glob, part.exclude.as_deref().or(spec.exclude.as_deref()))?; if matched.is_empty() { bail!("{}: no files match {glob}", spec.name); } diff --git a/crates/claudius-packs/src/install/from_sfz.rs b/crates/claudius-packs/src/install/from_sfz.rs index a62b892..37275db 100644 --- a/crates/claudius-packs/src/install/from_sfz.rs +++ b/crates/claudius-packs/src/install/from_sfz.rs @@ -124,7 +124,7 @@ pub(super) fn sfz_zone(r: &SfzRegion, file: &SfzFile, file_id: u32, keep_release lorand: r.f32("lorand").unwrap_or(0.0), hirand: r.f32("hirand").unwrap_or(1.0), gain_db, - pan: r.f32("pan").unwrap_or(0.0).clamp(-100.0, 100.0), + pan: modded(r, file, "pan", 0.0).clamp(-100.0, 100.0), offset: modded(r, file, "offset", 0.0).max(0.0) as u32, end: r.f32("end").unwrap_or(0.0).max(0.0) as u32, loop_mode, @@ -133,9 +133,9 @@ pub(super) fn sfz_zone(r: &SfzRegion, file: &SfzFile, file_id: u32, keep_release keytrack: r.f32("pitch_keytrack").unwrap_or(100.0) / 100.0, release, attack, - hold: r.f32("ampeg_hold").unwrap_or(0.0).max(0.0), - decay: r.f32("ampeg_decay").unwrap_or(0.0).max(0.0), - sustain: (r.f32("ampeg_sustain").unwrap_or(100.0) / 100.0).clamp(0.0, 1.0), + hold: modded(r, file, "ampeg_hold", 0.0).max(0.0), + decay: modded(r, file, "ampeg_decay", 0.0).max(0.0), + sustain: (modded(r, file, "ampeg_sustain", 100.0) / 100.0).clamp(0.0, 1.0), } } @@ -177,9 +177,10 @@ pub(super) fn drumify(z: &mut Zone, center: f32) { pub(super) fn build_sfz(ctx: &mut Ctx, src_key: &str, spec: &InstSpec) -> Result> { let sfz_path = spec.sfz.as_deref().expect("sfz"); - let base_dir = match sfz_path.rfind('/') { - Some(i) => sfz_path[..i].to_string(), - None => String::new(), + let base_dir = match (&spec.base, sfz_path.rfind('/')) { + (Some(b), _) => b.trim_end_matches('/').to_string(), + (None, Some(i)) => sfz_path[..i].to_string(), + (None, None) => String::new(), }; let text = ctx.sources[src_key].read_text(sfz_path).with_context(|| format!("reading {sfz_path}"))?; let file = { diff --git a/crates/claudius-packs/src/registry.json b/crates/claudius-packs/src/registry.json index 7472abd..6752f65 100644 --- a/crates/claudius-packs/src/registry.json +++ b/crates/claudius-packs/src/registry.json @@ -118,8 +118,8 @@ { "name": "vcsl", "title": "Versilian Community Sample Library (selection)", - "description": "Selection from VCSL: mallets (marimba, vibraphone, xylophone, glockenspiel, tubular bells, kalimba), pipe organ, tenor saxophone, harmonica, world and orchestral percussion (bongos, congas, cajon, darbuka, frame drum, tambourine, shakers, cabasa, claves, cowbells, woodblock, agogo, guiro, triangle, sleigh bells, vibraslap, slapstick, claps, suspended cymbal, gong, mark tree, concert bass drum). Downloaded as WAV, stored as lossless FLAC. Pianos, harpsichords, recorders and the rest of VCSL are left out for size. The release's SFZ maps xylophone and glockenspiel an octave below sounding pitch; corrected here.", - "categories": ["mallets", "percussion", "world percussion", "organ", "woodwinds"], + "description": "Selection from VCSL: mallets (marimba, vibraphone, bowed vibraphone, xylophone, glockenspiel, tubular bells, hand chimes, kalimba, balafon), rubbed wine glasses, pipe organ, ocarina, tenor saxophone, harmonica, didgeridoo, a Yamaha TX81Z FM synthesizer (Clavisynth), zithers (Dan Tranh plucked and in tremolo, bowed psaltery), world and orchestral percussion (bongos, congas, cajon, darbuka, frame drum, slit drum, tambourine, shakers, cabasa, claves, cowbells, woodblock, agogo, guiro, triangle, sleigh bells, vibraslap, slapstick, claps, suspended cymbal, gong, mark tree, concert bass drum, anvil, brake drum, finger cymbals, bell tree) and effects (ocean drum, flexatone, ratchet, siren whistles). Downloaded as WAV, stored as lossless FLAC. Pianos, harpsichords, recorders and the rest of VCSL are left out for size. The release's SFZ maps xylophone and glockenspiel an octave below sounding pitch; corrected here.", + "categories": ["mallets", "percussion", "world percussion", "organ", "woodwinds", "synth", "fx"], "licence": "CC0-1.0", "licence_url": "https://creativecommons.org/publicdomain/zero/1.0/", "attribution": "Versilian Community Sample Library by Versilian Studios (CC0)", @@ -127,7 +127,7 @@ "licence_note": "LICENSE of sgossner/VCSL: CC0 1.0 Universal. README: 'Essentially it's Public Domain- you can do whatever you want with these sounds (even make commercial software), no royalties, no credit, no special terms.' SFZ mappings from release v1.2.2-RC (generated by Peter Eastman's tool, also CC0).", "source": "https://github.com/sgossner/VCSL", "default": true, - "size_mb": 469, + "size_mb": 764, "version": "v1.2.2-RC (b6e6ac8)", "flac": true, "fetch": {"github": "sgossner/VCSL", "rev": "b6e6ac82d22248edee98a0bde185eb9ef6d439ad"}, @@ -163,7 +163,26 @@ {"name": "suspended_cymbal", "kind": "drum", "category": "orchestral percussion", "sfz": "Idiophones/Struck Idiophones/Suspended Cymbal 1.sfz", "kit_auto": true, "veltrack": 0.6, "aliases": ["cymbal_swell", "orchestral_cymbal"]}, {"name": "gong", "kind": "drum", "category": "orchestral percussion", "sfz": "Idiophones/Struck Idiophones/Gong 1.sfz", "kit_auto": true, "veltrack": 0.6, "aliases": ["tam_tam"]}, {"name": "mark_tree", "kind": "drum", "category": "percussion", "sfz": "Idiophones/Struck Idiophones/Mark Trees.sfz", "kit_auto": true, "veltrack": 0.6, "aliases": ["mark_trees", "wind_chimes", "chimes_tree"]}, - {"name": "bass_drum", "kind": "drum", "category": "orchestral percussion", "description": "concert bass drum", "sfz": "Membranophones/Struck Membranophones/Bass Drum 1.sfz", "kit_auto": true, "veltrack": 0.6, "aliases": ["concert_bass_drum", "gran_cassa"]} + {"name": "bass_drum", "kind": "drum", "category": "orchestral percussion", "description": "concert bass drum", "sfz": "Membranophones/Struck Membranophones/Bass Drum 1.sfz", "kit_auto": true, "veltrack": 0.6, "aliases": ["concert_bass_drum", "gran_cassa"]}, + {"name": "bowed_vibraphone", "category": "mallets", "description": "vibraphone bars bowed: long, pure tones", "sfz": "Idiophones/Struck Idiophones/Vibraphone - Bowed.sfz", "gain_db": -9.0, "release": 1.5, "veltrack": 0.5, "aliases": ["bowed_vibes"]}, + {"name": "hand_chimes", "category": "mallets", "description": "hand chimes, left to ring", "sfz": "Idiophones/Struck Idiophones/Hand Chimes.sfz", "one_shot": true, "release": 1.0, "veltrack": 0.6, "aliases": ["handchimes"]}, + {"name": "balafon", "category": "mallets", "description": "balafon (West African xylophone), traditional mallets", "sfz": "Idiophones/Struck Idiophones/Balafon - Traditional Mallet.sfz", "one_shot": true, "release": 0.3, "veltrack": 0.7}, + {"name": "wine_glasses", "category": "mallets", "description": "wine glasses rubbed until they sing, slow swells", "sfz": "Idiophones/Friction Idiophones/Wine Glasses - Slow.sfz", "release": 1.0, "veltrack": 0.4, "aliases": ["glass_harp", "singing_glasses"]}, + {"name": "ocarina", "category": "woodwinds", "description": "ocarina, sustained", "sfz": "Aerophones/Edge-blown Aerophones/Ocarina, Typical - Sus.sfz", "release": 0.15, "veltrack": 0.5}, + {"name": "clavisynth", "category": "synth", "description": "Yamaha TX81Z FM synthesizer, Clavisynth patch, 3 velocity layers (the patch sounds an octave above the keys it was recorded from; corrected)", "sfz": "Electrophones/TX81Z - Clavisynth.sfz", "octave": 1, "release": 0.2, "veltrack": 0.7, "aliases": ["tx81z", "fm_clav"]}, + {"name": "dan_tranh", "category": "world", "description": "Dan Tranh, Vietnamese plucked zither", "sfz": "Chordophones/Zithers/Dan Tranh - Normal.sfz", "one_shot": true, "release": 0.5, "veltrack": 0.7, "aliases": ["dantranh"]}, + {"name": "dan_tranh_tremolo", "category": "world", "description": "Dan Tranh in tremolo", "sfz": "Chordophones/Zithers/Dan Tranh - Tremolo.sfz", "release": 0.5, "veltrack": 0.6}, + {"name": "bowed_psaltery", "category": "strings", "description": "bowed psaltery, long bows: airy, glassy sustains", "sfz": "Chordophones/Zithers/Psaltery, Bowed and Plucked - LongBow.sfz", "release": 0.8, "veltrack": 0.5, "aliases": ["psaltery"]}, + {"name": "didgeridoo", "kind": "drum", "category": "world", "description": "didgeridoo barks and phrases", "sfz": "Aerophones/Lip Aerophones/Didgeridoo.sfz", "kit_auto": true, "veltrack": 0.4, "aliases": ["didge"]}, + {"name": "slit_drum", "kind": "drum", "category": "world percussion", "description": "wooden slit drum, high and low", "sfz": "Idiophones/Struck Idiophones/Slit Drum.sfz", "kit_auto": true, "veltrack": 0.6, "aliases": ["log_drum"]}, + {"name": "anvil", "kind": "drum", "category": "percussion", "sfz": "Idiophones/Struck Idiophones/Anvil.sfz", "kit_auto": true, "veltrack": 0.6}, + {"name": "brake_drum", "kind": "drum", "category": "percussion", "sfz": "Idiophones/Struck Idiophones/Brake Drum.sfz", "kit_auto": true, "veltrack": 0.6}, + {"name": "finger_cymbals", "kind": "drum", "category": "percussion", "sfz": "Idiophones/Struck Idiophones/Finger Cymbals.sfz", "kit_auto": true, "veltrack": 0.6, "aliases": ["zills"]}, + {"name": "bell_tree", "kind": "drum", "category": "percussion", "description": "bell tree strokes", "sfz": "Idiophones/Struck Idiophones/Bell Tree - Stroke.sfz", "kit_auto": true, "veltrack": 0.5}, + {"name": "ocean_drum", "kind": "drum", "category": "fx", "description": "ocean drum: waves rolling", "sfz": "Membranophones/Other Membranophones/Ocean Drum.sfz", "kit_auto": true, "veltrack": 0.4, "aliases": ["waves"]}, + {"name": "flexatone", "kind": "drum", "category": "fx", "sfz": "Idiophones/Struck Idiophones/Flexatone.sfz", "kit_auto": true, "veltrack": 0.5}, + {"name": "ratchet", "kind": "drum", "category": "fx", "sfz": "Idiophones/Struck Idiophones/Ratchet.sfz", "kit_auto": true, "veltrack": 0.5}, + {"name": "siren", "kind": "drum", "category": "fx", "description": "siren whistles", "sfz": "Aerophones/Free Aerophones/Siren.sfz", "kit_auto": true, "veltrack": 0.4, "aliases": ["siren_whistle"]} ] }, { @@ -306,8 +325,8 @@ { "name": "freepats", "title": "FreePats selection", - "description": "CC0 instruments from the FreePats project: Upright Piano KW (Kawai upright, 2 layers, looped bass), FM electric piano, drawbar organ (setBfree), finger and picked bass guitar (Yamaha RBX), Spanish classical guitar, Fender electric guitar (clean and jazz, small editions), and synths: strings, brass, basses, square lead, sweep / new-age / bowed / choir pads.", - "categories": ["piano", "organ", "bass", "guitar", "synth"], + "description": "CC0 instruments from the FreePats project: Upright Piano KW (Kawai upright, 2 layers, looped bass), FM electric piano, drawbar organ (setBfree), finger and picked bass guitar (Yamaha RBX), Spanish classical guitar, Fender electric guitar (clean and jazz, small editions), synths (strings, brass, basses, square lead, sweep / new-age / bowed / choir pads), glasses of water tuned from A4 to G6, and a hang in D minor.", + "categories": ["piano", "organ", "bass", "guitar", "synth", "mallets"], "licence": "CC0-1.0", "licence_url": "https://creativecommons.org/publicdomain/zero/1.0/", "attribution": "FreePats project (freepats.zenvoid.org), CC0", @@ -315,7 +334,7 @@ "licence_note": "Each FreePats page: 'Published under the terms of the Creative Commons CC0 1.0 public domain dedication.'; every freepats/* repository used here has a CC0-1.0 LICENSE. Bass Guitar YR: 'sent for inclusion in FreePats on September 2019, under the terms of the Creative Commons CC0 1.0 public domain dedication.'", "source": "https://freepats.zenvoid.org/", "default": true, - "size_mb": 136, + "size_mb": 162, "version": "2026-10", "instruments": [ {"name": "upright_piano", "category": "piano", "description": "Kawai upright piano, 2 velocity layers", "fetch": {"github": "freepats/upright-piano-KW", "rev": "570f6c60ed2eff67accad3b85d5b452e57a3ad28"}, "sfz": "UprightPianoKW-20220221.sfz", "release": 0.35, "veltrack": 0.8, "retrigger": true, "aliases": ["upright", "honky_piano"]}, @@ -336,7 +355,9 @@ {"name": "sweep_pad", "category": "pad", "fetch": {"github": "freepats/sweep-pad", "rev": "ed3e294fcec8c3ea3ec84471f8c7a75bc09eba04"}, "sfz": "SweepPad 20190813.sfz", "release": 1.0, "veltrack": 0.3, "aliases": ["pad", "synth_pad"]}, {"name": "new_age_pad", "category": "pad", "fetch": {"github": "freepats/new-age", "rev": "f277fa2463180f2aee6f481c3d08644533f3ce98"}, "sfz": "NewAge 20190730.sfz", "release": 1.0, "veltrack": 0.3, "aliases": ["new_age", "warm_pad"]}, {"name": "bowed_pad", "category": "pad", "fetch": {"github": "freepats/synth-pad-bowed", "rev": "1646e448ff4cfa966496af3e07a68d7778c85d58"}, "sfz": "SynthPadBowed 20190719.sfz", "release": 1.0, "veltrack": 0.3}, - {"name": "choir_pad", "category": "pad", "fetch": {"github": "freepats/synth-pad-choir", "rev": "b801f7fc3eee44f575cd480750aea4f6a16a07a9"}, "sfz": "SynthPadChoir 20200516.sfz", "release": 1.0, "veltrack": 0.3, "aliases": ["synth_choir", "pad_choir"]} + {"name": "choir_pad", "category": "pad", "fetch": {"github": "freepats/synth-pad-choir", "rev": "b801f7fc3eee44f575cd480750aea4f6a16a07a9"}, "sfz": "SynthPadChoir 20200516.sfz", "release": 1.0, "veltrack": 0.3, "aliases": ["synth_choir", "pad_choir"]}, + {"name": "water_glasses", "category": "mallets", "description": "glasses of water tuned chromatically, A4 to G6, with round robins", "fetch": {"github": "freepats/glass", "rev": "8b2fd2c0dfc334b6c16eaac418c8e73020be1105"}, "sfz": "Glass-20191227.sfz", "one_shot": true, "release": 0.6, "veltrack": 0.7, "aliases": ["glasses", "glass"]}, + {"name": "hang", "category": "mallets", "description": "hang in D minor: only its own notes sound (A3 C4 D4 E4 F4 G4 A4 Bb4 C5 D5), because its other notes ring along with each one and would move to another scale if pitched", "fetch": {"github": "freepats/hang-D-minor", "rev": "fdeca2ec981ab374607f250bccb1452b531ac13a"}, "sfz": "Hang-D-minor 20220330.sfz", "one_shot": true, "release": 0.8, "veltrack": 0.7, "aliases": ["hang_drum", "handpan"]} ] }, { @@ -400,6 +421,206 @@ {"name": "choir", "category": "choir", "description": "5-voice ensemble rendered from the solo 'ah'", "compose": [{"from": "voice_ah"}], "release": 0.6, "attack": 0.08, "veltrack": 0.5, "unison": {"voices": 5, "detune_cents": 14.0, "spread": 0.8, "delay_ms": 35.0}, "aliases": ["choir_aah", "voices", "choir_ah", "ensemble_voices"]} ] }, + { + "name": "sonicpi", + "title": "Sonic Pi samples", + "description": "The samples Sonic Pi ships with, under its names: kicks (bd), snares (sn), hi-hats (hat), rides, an acoustic kit (drum), electronic one-shots (elec), glitches, Mehackit's phones and robots, percussion and impacts (perc), bass hits, ambient drones and textures (ambi), guitar phrases (guit), vinyl hiss, scratches and spins, tabla strokes, loops, Arovane's beats and The Black Dog's pads (tbd). Each group's sounds are its variants, and each sound also answers to its own name (vinyl_scratch, bd_haus). The Amen and breakbeat loops are left out: they are cut from commercial records.", + "categories": ["drums", "electronic drums", "fx", "texture", "loops"], + "licence": "CC0-1.0", + "licence_url": "https://creativecommons.org/publicdomain/zero/1.0/", + "attribution": "Sonic Pi samples (sonic-pi.net): Freesound contributors, Arovane (Uwe Zahn) and The Black Dog, CC0", + "attribution_required": false, + "licence_note": "etc/samples/README.md of sonic-pi-net/sonic-pi: the arovane_ samples 'kindly donated by Uwe Zahn (Arovane) under a Creative Commons 0 license'; 'All other samples in this directory are from http://freesound.org and have also been placed in the public domain via the Creative Commons 0 License'; each tbd_ sample 'Donated by The Black Dog under a CC0 license'.", + "source": "https://github.com/sonic-pi-net/sonic-pi/tree/main/etc/samples", + "default": true, + "size_mb": 34, + "version": "e543d54", + "aliases": ["sonic_pi", "sonic-pi"], + "fetch": {"github": "sonic-pi-net/sonic-pi", "rev": "e543d5415bec4d25cdacc5b9ef87e1d4c1e5292a"}, + "instruments": [ + {"name": "bd", "kind": "drum", "category": "drums", "description": "15 kicks: 808, ada, boom, chip, fat, gas, haus, jazz, klub, mehackit, pure, sone, tek, zome, zum", "files": "etc/samples/bd_*.flac", "each": true}, + {"name": "sn", "kind": "drum", "category": "drums", "description": "snares: dolf, dub, generic, zome", "files": "etc/samples/sn_*.flac", "each": true}, + {"name": "hat", "kind": "drum", "category": "drums", "description": "21 hi-hats", "files": "etc/samples/hat_*.flac", "each": true}, + {"name": "ride", "kind": "drum", "category": "drums", "files": "etc/samples/ride_*.flac", "each": true}, + {"name": "drum", "kind": "drum", "category": "acoustic drums", "description": "an acoustic kit, soft and hard: bass drum, snare, toms, cymbals, splash, cowbell, a roll", "files": "etc/samples/drum_*.flac", "each": true}, + {"name": "elec", "kind": "drum", "category": "electronic drums", "description": "25 electronic one-shots: blips, bleeps, bells, pings, pops, snares, kicks, toms", "files": "etc/samples/elec_*.flac", "each": true}, + {"name": "glitch", "kind": "drum", "category": "electronic drums", "description": "glitch percussion, a glitch bass and robot voices", "files": "etc/samples/glitch_*.flac", "each": true}, + {"name": "mehackit", "kind": "drum", "category": "fx", "description": "phone and robot sounds", "files": "etc/samples/mehackit_*.flac", "each": true}, + {"name": "perc", "kind": "drum", "category": "percussion", "description": "bells, a door, impacts, snaps, a swash, a swoosh, a till", "files": "etc/samples/perc_*.flac", "each": true}, + {"name": "misc", "kind": "drum", "category": "fx", "description": "a burp, a cinematic boom, a crow", "files": "etc/samples/misc_*.flac", "each": true}, + {"name": "vinyl", "kind": "drum", "category": "fx", "description": "vinyl backspin, hiss, rewind, scratch", "files": "etc/samples/vinyl_*.flac", "each": true}, + {"name": "bass", "kind": "drum", "category": "bass", "description": "bass hits in C (dnb in F): drop, hard, hit, thick, trance, voxy, woodsy", "files": "etc/samples/bass_*.flac", "each": true}, + {"name": "ambi", "kind": "drum", "category": "texture", "description": "ambient textures and drones: choir, dark woosh, drone, glass hum and rub, haunted hum, lunar landing, piano wash, sauna, soft buzz, swoosh", "files": "etc/samples/ambi_*.flac", "each": true}, + {"name": "tbd", "kind": "drum", "category": "texture", "description": "The Black Dog's pads, an effects bed, a high key in C4, percussion and a vocal tone", "files": "etc/samples/tbd_*.flac", "each": true}, + {"name": "guit", "kind": "drum", "category": "guitar", "description": "electric guitar phrases: E fifths, slide, Em9, harmonics", "files": "etc/samples/guit_*.flac", "each": true}, + {"name": "tabla", "kind": "drum", "category": "world percussion", "description": "26 tabla strokes", "files": "etc/samples/tabla_*.flac", "each": true}, + {"name": "loop", "kind": "drum", "category": "loops", "description": "loops at their own tempo: 3D printer, compus, drone in G, electric, garzul, industrial, mehackit, mika, percussion, safari, tabla, weirdo", "files": "etc/samples/loop_*.flac", "exclude": "loop_(amen|breakbeat)", "each": true}, + {"name": "arovane", "kind": "drum", "category": "loops", "description": "five beats by Arovane", "files": "etc/samples/arovane_*.flac", "each": true} + ] + }, + { + "name": "solocello", + "title": "Karoryfer x Bigcat cello", + "description": "A solo cello played by Kamila Borowiak: bowed, with velocity choosing soft to loud, and plucked. The SFZ maps the cello an octave below where it sounds, corrected here, and its harmonics and noises are left out. Downloaded as WAV, stored as lossless FLAC.", + "categories": ["strings"], + "licence": "CC0-1.0", + "licence_url": "https://creativecommons.org/publicdomain/zero/1.0/", + "attribution": "Karoryfer x Bigcat cello by Karoryfer Samples and Bigcat Instruments, performed by Kamila Borowiak (CC0)", + "attribution_required": false, + "licence_note": "LICENSE of sfzinstruments/karoryfer-bigcat.cello: CC0 1.0 Universal; README: 'This sample library is royalty-free for all commercial and non-commercial use.'", + "source": "https://github.com/sfzinstruments/karoryfer-bigcat.cello", + "default": true, + "size_mb": 112, + "version": "6fd75fb", + "flac": true, + "fetch": {"github": "sfzinstruments/karoryfer-bigcat.cello", "rev": "6fd75fbfc1dbb3109bf26220ba1adea46188a18b"}, + "instruments": [ + {"name": "solo_cello", "category": "strings", "description": "solo cello, bowed", "sfz": "Programs/01- Bowed (velocity layer).sfz", "keys": [0, 83], "octave": 1, "release": 0.4, "veltrack": 0.5, "aliases": ["cello_solo", "bowed_cello"]}, + {"name": "solo_cello_pizz", "category": "strings", "description": "solo cello, plucked", "sfz": "Programs/03- Plucked.sfz", "keys": [0, 71], "octave": 1, "one_shot": true, "release": 0.3, "veltrack": 0.6, "aliases": ["cello_solo_pizz"]} + ] + }, + { + "name": "erhu", + "title": "Erhu (D. Smolken)", + "description": "An inexpensive erhu (the two-stringed Chinese fiddle) played by a violinist and close-miked in stereo: long bows, short bows and sul tasto, as one voice (the programs' unison voices are left out). The mappings sit an octave below where the erhu sounds; corrected here. Downloaded as WAV, stored as lossless FLAC.", + "categories": ["strings", "world"], + "licence": "CC0-1.0", + "licence_url": "https://creativecommons.org/publicdomain/zero/1.0/", + "attribution": "Erhu samples by D. Smolken (CC0)", + "attribution_required": false, + "licence_note": "LICENSE of sfzinstruments/aliexpress-erhu: CC0 1.0 Universal.", + "source": "https://github.com/sfzinstruments/aliexpress-erhu", + "default": true, + "size_mb": 86, + "version": "6615047", + "flac": true, + "fetch": {"github": "sfzinstruments/aliexpress-erhu", "rev": "6615047b2fd06126877483e97b8bb4af9d00b080"}, + "instruments": [ + {"name": "erhu", "category": "world", "description": "erhu, long bows", "sfz": "Programs/modules/maps/erhu_sus_map.sfz", "base": "Programs", "octave": 1, "attack": 0.01, "release": 0.25, "veltrack": 0.5}, + {"name": "erhu_short", "category": "world", "description": "erhu, short bows", "sfz": "Programs/modules/maps/erhu_stac_map.sfz", "base": "Programs", "octave": 1, "one_shot": true, "release": 0.25, "veltrack": 0.6}, + {"name": "erhu_sul_tasto", "category": "world", "description": "erhu bowed over the fingerboard: soft and airy", "sfz": "Programs/modules/maps/erhu_st_map.sfz", "base": "Programs", "octave": 1, "gain_db": -16.0, "attack": 0.01, "release": 0.25, "veltrack": 0.5} + ] + }, + { + "name": "steelpan", + "title": "jSteelDrum", + "description": "Hand-made tenor steel pan by Jeff Learman: 24 notes from C4 to B5, 5 crossfaded velocity layers, 3 or 4 alternates on each, FLAC.", + "categories": ["mallets", "world percussion"], + "licence": "Unlicense", + "licence_url": "https://unlicense.org/", + "attribution": "jSteelDrum by Jeff Learman", + "attribution_required": false, + "licence_note": "LICENSE of sfzinstruments/jlearman.SteelDrum: The Unlicense ('This is free and unencumbered software released into the public domain.').", + "source": "https://github.com/sfzinstruments/jlearman.SteelDrum", + "default": true, + "size_mb": 38, + "version": "dc15a36", + "fetch": {"github": "sfzinstruments/jlearman.SteelDrum", "rev": "dc15a36ad69a43b0d240fcbd0cc78fbc61b2b47e"}, + "instruments": [ + {"name": "steel_pan", "category": "mallets", "description": "tenor steel pan, 5 velocity layers", "sfz": "jSteelDrum.sfz", "one_shot": true, "release": 0.5, "veltrack": 0.7, "aliases": ["steelpan", "steel_drum", "steeldrum", "steel_drums"]} + ] + }, + { + "name": "synthdrums", + "title": "FreePats synthesizer percussion", + "description": "Drums Roberto made with the Yoshimi and Geonkick synthesizers after the kits of vintage analog electronic music: 2 kicks, 2 snares, closed and open hi-hats, 2 cymbals, 6 toms, a clap, shakers and claves, FLAC.", + "categories": ["drums", "electronic drums"], + "licence": "CC0-1.0", + "licence_url": "https://creativecommons.org/publicdomain/zero/1.0/", + "attribution": "FreePats synthesizer percussion by Roberto (freepats.zenvoid.org), CC0", + "attribution_required": false, + "licence_note": "README of freepats/synthesizer-percussion: 'Published under the terms of Creative Commons CC0 public domain dedication'; LICENSE: CC0 1.0 Universal.", + "source": "https://github.com/freepats/synthesizer-percussion", + "default": true, + "size_mb": 1.5, + "version": "2022-07-18 (39bbabc)", + "aliases": ["synth_drums", "synth_percussion"], + "fetch": {"github": "freepats/synthesizer-percussion", "rev": "39bbabce8e0e10aa259d5d94fca329f668733185"}, + "instruments": [ + {"name": "kit", "kind": "drum", "category": "drums", "sfz": "SynthesizerPercussion-20220718.sfz", "kit": {"bd": [48, 49], "sd": [50, 51], "hh": [52, 53], "oh": [54], "cr": [55, 56], "lt": [57, 58], "mt": [59, 60], "ht": [61, 62], "cp": [63], "sh": [64, 65], "cl": [66]}, "veltrack": 0.5} + ] + }, + { + "name": "body", + "title": "Body percussion", + "description": "Claps, snaps, stomps, heels and hits on the chest, belly, cheeks, head and shoulders, with 4 to 6 round robins and sometimes 2 velocity layers; the left and right hand or foot are variants. Downloaded as WAV, stored as lossless FLAC.", + "categories": ["percussion"], + "licence": "CC0-1.0", + "licence_url": "https://creativecommons.org/publicdomain/zero/1.0/", + "attribution": "Body percussion (sfzinstruments/body_percussion), CC0", + "attribution_required": false, + "licence_note": "readme.txt of sfzinstruments/body_percussion: 'CC 0 license.'; LICENSE: CC0 1.0 Universal.", + "source": "https://github.com/sfzinstruments/body_percussion", + "default": true, + "size_mb": 62, + "version": "4ac9d89", + "flac": true, + "aliases": ["body_percussion", "bodypercussion"], + "fetch": {"github": "sfzinstruments/body_percussion", "rev": "4ac9d8966679c648b62fa10a188179e186b97f24"}, + "instruments": [ + {"name": "kit", "kind": "drum", "category": "percussion", "sfz": "Programs/body.sfz", "kit": {"heel": [36, 37], "half_stomp": [38, 39], "stomp": [40, 41], "belly_side": [42, 43], "belly": [44, 45], "chest": [46], "chest_side": [47, 48], "shoulder": [49, 50], "head": [51], "cheek": [52, 53, 54, 55], "snap": [56, 57], "pinky_snap": [58, 59], "finger_clap": [60], "clap": [61]}, "veltrack": 0.6} + ] + }, + { + "name": "zamenhof", + "title": "Zamenhof Stickmusterstuch Error (Karoryfer)", + "description": "Two kits of electronic glitches, one-shots and loops: clicks and noises from digital recordings, time-stretched, pitch-shifted, distorted and put through a Kaoss Pad, for ambient, industrial and glitch music and micro-beats. Each key of the original mapping is a variant. Downloaded as WAV, stored as lossless FLAC.", + "categories": ["electronic drums", "fx"], + "licence": "CC0-1.0", + "licence_url": "https://creativecommons.org/publicdomain/zero/1.0/", + "attribution": "Zamenhof Stickmusterstuch Error by Karoryfer Samples (CC0)", + "attribution_required": false, + "licence_note": "LICENSE of sfzinstruments/zamenhof_stickmusterstuch_error: CC0 1.0 Universal; karoryfer.com free samples page: 'All our free sample libraries are under a Creative Commons Zero license.'", + "source": "https://github.com/sfzinstruments/zamenhof_stickmusterstuch_error", + "default": true, + "size_mb": 121, + "version": "338133e", + "flac": true, + "fetch": {"github": "sfzinstruments/zamenhof_stickmusterstuch_error", "rev": "338133ee7fe6a429576c0dea3edfa1b9270201b6"}, + "instruments": [ + {"name": "glitch_kit", "kind": "drum", "category": "electronic drums", "description": "glitch kit Eins", "sfz": "Zamenhof Stickmusterstuch Error Eins.sfz", "kit_auto": true, "veltrack": 0.5, "aliases": ["error_kit"]}, + {"name": "glitch_kit_2", "kind": "drum", "category": "electronic drums", "description": "glitch kit Zwei", "sfz": "Zamenhof Stickmusterstuch Error Zwei.sfz", "kit_auto": true, "veltrack": 0.5, "aliases": ["error_kit_2"]} + ] + }, + { + "name": "miscellania", + "title": "Versilian Miscellania I and II", + "description": "Sound effects recorded by Versilian Studios, from the raw folder of VSCO 2 CE: aliens, zaps, sirens, metal hits, breaking glass, cymbals played as gongs, chains, bubbles, ringing vibraphone bars, timpani with snares, scrapes; frame-drum toms, sleigh bells and tambourines hit and rolled, spoons, tuba effects; Nepalese bells; glockenspiel glissandi up and down. Downloaded as WAV, stored as lossless FLAC.", + "categories": ["fx", "percussion"], + "licence": "CC0-1.0", + "licence_url": "https://creativecommons.org/publicdomain/zero/1.0/", + "attribution": "Miscellania by Versilian Studios (CC0), from VS Chamber Orchestra 2: Community Edition", + "attribution_required": false, + "licence_note": "LICENSE of sgossner/VSCO-2-CE: CC0 1.0 Universal; versilian-studios.com/legacy: 'Sounds under CC0 license via the VSCO 2 CE project. You'll find them there, in the raw WAV version.'", + "source": "https://github.com/sgossner/VSCO-2-CE/tree/master/Miscellania%20Raw", + "default": true, + "size_mb": 125, + "version": "6dd651d", + "flac": true, + "aliases": ["misc_fx", "versilian_fx"], + "fetch": {"github": "sgossner/VSCO-2-CE", "rev": "6dd651d55dde97fd4028699be9d4481f26917891"}, + "instruments": [ + {"name": "aliens", "kind": "drum", "category": "fx", "files": "Miscellania Raw/Misc 1/alien*.wav", "each": true}, + {"name": "zaps", "kind": "drum", "category": "fx", "files": "Miscellania Raw/Misc 1/zap*.wav", "each": true}, + {"name": "sirens", "kind": "drum", "category": "fx", "files": "Miscellania Raw/Misc 1/siren*.wav", "each": true}, + {"name": "metal_hits", "kind": "drum", "category": "fx", "files": "Miscellania Raw/Misc 1/metal_hit*.wav", "each": true}, + {"name": "glass_breaks", "kind": "drum", "category": "fx", "files": "Miscellania Raw/Misc 1/glass_break*.wav", "each": true, "aliases": ["glass_break", "breaking_glass"]}, + {"name": "cymbal_gongs", "kind": "drum", "category": "fx", "description": "cymbals played as gongs and on a timpani", "files": "Miscellania Raw/Misc 1/cymb*.wav", "each": true}, + {"name": "chains", "kind": "drum", "category": "fx", "description": "chains rattled and ground", "files": "Miscellania Raw/Misc 1/chain*.wav", "each": true}, + {"name": "bubbles", "kind": "drum", "category": "fx", "files": "Miscellania Raw/Misc 1/bubbles*.wav", "each": true}, + {"name": "scrapes", "kind": "drum", "category": "fx", "description": "bricks scraped", "files": "Miscellania Raw/Misc 1/brick_scrape*.wav", "each": true}, + {"name": "vibra_rings", "kind": "drum", "category": "fx", "description": "vibraphone bars ringing", "files": "Miscellania Raw/Misc 1/vibraring*.wav", "each": true}, + {"name": "timp_snares", "kind": "drum", "category": "percussion", "description": "timpani with snares on, very soft to very loud, and a tenor drum", "files": "Miscellania Raw/Misc 1/timp*snare*.wav", "each": true}, + {"name": "ambience", "kind": "drum", "category": "texture", "files": "Miscellania Raw/Misc 1/ambience*.wav", "each": true}, + {"name": "frame_toms", "kind": "drum", "category": "percussion", "description": "frame-drum toms and a roll", "files": "Miscellania Raw/Misc 2/rtomtom*.wav", "each": true}, + {"name": "sleigh_bell_hits", "kind": "drum", "category": "percussion", "description": "two sets of sleigh bells, hit and shaken", "files": "Miscellania Raw/Misc 2/sleighbell*.wav", "each": true}, + {"name": "tambourine_hits", "kind": "drum", "category": "percussion", "description": "two tambourines, hit and rolled", "files": "Miscellania Raw/Misc 2/tamb*.wav", "each": true}, + {"name": "spoons", "kind": "drum", "category": "percussion", "files": "Miscellania Raw/Misc 2/spoons*.wav", "each": true}, + {"name": "tuba_fx", "kind": "drum", "category": "fx", "files": "Miscellania Raw/Misc 2/tuba*.wav", "each": true}, + {"name": "nepalese_bells", "kind": "drum", "category": "percussion", "description": "Nepalese bells, short and long", "files": "Miscellania Raw/Misc 2/NepaleseBells/*.wav", "each": true}, + {"name": "glock_gliss", "kind": "drum", "category": "fx", "description": "glockenspiel glissandi, up and down, chromatic and pentatonic, slow to fast", "files": "Miscellania Raw/Misc 2/glock_glisses/*.wav", "each": true, "aliases": ["glock_glissando", "glissando"]} + ] + }, { "name": "splendid", "title": "Splendid Grand Piano", diff --git a/crates/claudius-packs/src/resolve.rs b/crates/claudius-packs/src/resolve.rs index 76dc66a..dfcc3b9 100644 --- a/crates/claudius-packs/src/resolve.rs +++ b/crates/claudius-packs/src/resolve.rs @@ -165,6 +165,18 @@ fn find_inst(p: &PackIndex, name: &str, bank: Option<&str>) -> Option { p.instruments.iter().position(|d| drum_canonical(&d.name) == Some(c)) } +/// a variant called by its own name, which starts with its instrument's: `vinyl_scratch` is a variant of `vinyl` +/// (Sonic Pi's names). Other variant names (`BD5075`, `C4`) are not names of their own. +fn find_named_variant(p: &PackIndex, name: &str) -> Option { + let n = norm(name); + p.instruments.iter().enumerate().find_map(|(i, d)| { + if !n.starts_with(&format!("{}_", norm(&d.name))) { + return None; + } + d.variants.iter().position(|v| norm(&v.name) == n).and_then(|k| make(p, i, k)) + }) +} + fn make(p: &PackIndex, i: usize, variant: usize) -> Option { let d = &p.instruments[i]; (variant < d.variants.len()).then(|| InstrumentRef { pack: p.name.clone(), instrument: d.name.clone(), variant }) @@ -194,10 +206,15 @@ pub fn resolve_in(indexes: &[Arc], name: &str, bank: Option<&str>) -> // explicit bank: `s("bd").bank("tr909")` if let Some(b) = bank { let sound = parts.last().copied().unwrap_or_default(); - if let Some(p) = find_pack(indexes, b) - && let Some(i) = find_inst(p, sound, None) - { - return make(p, i, variant); + if let Some(p) = find_pack(indexes, b) { + if let Some(i) = find_inst(p, sound, None) { + return make(p, i, variant); + } + if variant == 0 + && let Some(r) = find_named_variant(p, sound) + { + return Some(r); + } } // Strudel bank naming inside map packs: RolandTR909_bd for p in indexes { @@ -216,7 +233,11 @@ pub fn resolve_in(indexes: &[Arc], name: &str, bank: Option<&str>) -> if parts.len() >= 2 { let (pk, sound) = (parts[0], parts[1..].join(":")); if let Some(p) = find_pack(indexes, pk) { - return find_inst(p, &sound, None).and_then(|i| make(p, i, variant)); + return match find_inst(p, &sound, None) { + Some(i) => make(p, i, variant), + None if variant == 0 => find_named_variant(p, &sound), + None => None, + }; } // `bank:sound` where the bank is a Strudel bank name return resolve_in(indexes, &format!("{sound}:{variant}"), Some(pk)); @@ -257,6 +278,11 @@ pub fn resolve_in(indexes: &[Arc], name: &str, bank: Option<&str>) -> return make(p, i, variant); } } + if variant == 0 + && let Some(r) = order.iter().find_map(|p| find_named_variant(p, &n)) + { + return Some(r); + } // a drum synonym in any other kit (user-added maps): `kick` -> some pack's `bd` if let Some(c) = drum_canonical(&n) { for p in &order { @@ -374,4 +400,33 @@ mod tests { assert_eq!(resolve_in(&idx, "bd", Some("nonexistent")), None); assert_eq!(resolve_in(&idx, "grand_piano", None), r("salamander", "piano", 0)); } + + fn named(name: &str, variants: &[&str]) -> InstrumentDef { + let mut d = def(name, 0, &[]); + d.variants = variants.iter().map(|n| Variant { name: n.to_string(), zones: vec![Zone::default()] }).collect(); + d + } + + #[test] + fn variants_answer_to_their_own_names() { + let idx = vec![ + pack("tr808", &["808"], vec![named("bd", &["BD0010", "BD5075"])], true), + pack( + "sonicpi", + &[], + vec![named("vinyl", &["vinyl_backspin", "vinyl_hiss", "vinyl_scratch"]), def("bd", 2, &[])], + true, + ), + ]; + assert_eq!(resolve_in(&idx, "vinyl_scratch", None), r("sonicpi", "vinyl", 2)); + assert_eq!(resolve_in(&idx, "sonicpi:vinyl_hiss", None), r("sonicpi", "vinyl", 1)); + assert_eq!(resolve_in(&idx, "vinyl_backspin", Some("sonicpi")), r("sonicpi", "vinyl", 0)); + // the group and its numbered variants, Strudel's way + assert_eq!(resolve_in(&idx, "vinyl:1", None), r("sonicpi", "vinyl", 1)); + // a variant name that does not start with its instrument's is not a name of its own + assert_eq!(resolve_in(&idx, "BD5075", None), None); + assert_eq!(resolve_in(&idx, "vinyl_nothing", None), None); + // bare drum names still go to the preferred kits + assert_eq!(resolve_in(&idx, "bd", None), r("tr808", "bd", 0)); + } } diff --git a/crates/claudius/src/script/sounds.rs b/crates/claudius/src/script/sounds.rs index 7143348..14d7a53 100644 --- a/crates/claudius/src/script/sounds.rs +++ b/crates/claudius/src/script/sounds.rs @@ -153,7 +153,7 @@ pub fn resolve_sound( } else if packs.is_empty() { format!("no sample packs are installed for bank '{b}' (install them with: claudius-packs install --defaults)") } else { - format!("no '{label}' in bank '{b}' (installed packs: {}; kits: tr909 tr808 tr707 acoustic uzu)", packs.join(" ")) + format!("no '{label}' in bank '{b}' (installed packs: {}; kits: tr909 tr808 tr707 acoustic uzu synthdrums sonicpi body)", packs.join(" ")) } }); } diff --git a/docs/src/contributing/setup.md b/docs/src/contributing/setup.md index 2cda868..243fed8 100644 --- a/docs/src/contributing/setup.md +++ b/docs/src/contributing/setup.md @@ -118,7 +118,7 @@ redirects, the 404 page) at `http://127.0.0.1:4321`. ```sh cargo xtask web # the web studio, once and after changes to the UI -cargo run --release -p claudius-cli -- setup # the sample packs and the listening models, once (about 3 GB) +cargo run --release -p claudius-cli -- setup # the sample packs and the listening models, once (about 4 GB) cargo run --release -p claudius-cli -- studio # the native window, with the engine inside cargo run --release -p claudius-cli -- serve # or the studio in the browser at http://127.0.0.1:7878 ``` diff --git a/docs/src/getting-started/first-song.md b/docs/src/getting-started/first-song.md index 29b19ee..a477521 100644 --- a/docs/src/getting-started/first-song.md +++ b/docs/src/getting-started/first-song.md @@ -12,7 +12,7 @@ claudius doctor ```text claudius 0.1.0 (macos aarch64) ok web studio ~/.local/share/claudius/web - ok sample packs 14 default packs (1.2 GB) in ~/Library/Application Support/claudius/packs + ok sample packs 22 default packs (1.5 GB) in ~/Library/Application Support/claudius/packs ok ears models in ~/.cache/earshot-rs ok Apple Loops 14096 loops and samples ok ffmpeg 9.0.2 (writes song.mp3) @@ -25,7 +25,7 @@ Everything claudius needs is here. ``` Two things matter for this page: the **sample packs** (recorded instruments and drum machines) and the **ears** (the -listening models the critic uses). If either is missing, `claudius setup` downloads them: about 2.2 GB of packs (1.2 GB +listening models the critic uses). If either is missing, `claudius setup` downloads them: about 3.1 GB of packs (1.5 GB once unpacked) and 0.8 GB of models, once. Apple Loops are optional (claudius uses them when GarageBand or Logic content is installed), and without ffmpeg you get `song.wav` but no `song.mp3`. diff --git a/docs/src/getting-started/install.md b/docs/src/getting-started/install.md index 0975e4d..b0a0cc8 100644 --- a/docs/src/getting-started/install.md +++ b/docs/src/getting-started/install.md @@ -97,7 +97,7 @@ claudius setup | what | size | where | |---|---|---| -| 14 sample packs: pianos, electric pianos, strings, brass, woodwinds, mallets, basses, guitars, voice, real drum machines | 2.2 GB to download, 1.2 GB on disk | `~/Library/Application Support/claudius/packs` on macOS, `~/.local/share/claudius/packs` on Linux | +| 22 sample packs: pianos, electric pianos, strings, brass, woodwinds, mallets, basses, guitars, voice, real drum machines, electronic one-shots, effects | 3.1 GB to download, 1.5 GB on disk | `~/Library/Application Support/claudius/packs` on macOS, `~/.local/share/claudius/packs` on Linux | | earshot's listening models (CLAP) | about 0.8 GB | `~/.cache/earshot-rs` | The studio offers the same download of the packs when they are missing, and downloads the models by itself the @@ -117,7 +117,7 @@ claudius doctor ```text claudius 0.1.0 (macos aarch64) ok web studio ~/.local/share/claudius/web - ok sample packs 14 default packs (1.2 GB) in ~/Library/Application Support/claudius/packs + ok sample packs 22 default packs (1.5 GB) in ~/Library/Application Support/claudius/packs ok ears models in ~/.cache/earshot-rs ok Apple Loops 14096 loops and samples ok ffmpeg 9.0.2 (writes song.mp3) diff --git a/docs/src/getting-started/studio.md b/docs/src/getting-started/studio.md index 75f933c..24b65e1 100644 --- a/docs/src/getting-started/studio.md +++ b/docs/src/getting-started/studio.md @@ -21,7 +21,7 @@ The tour never blocks the studio. **Skip the tour** or Esc ends it for good, and The first time it starts, claudius downloads its listening models (about 0.8 GB) in the background; the verdict judges with meters and music theory until they are ready, and the log says when they are. If the default sample -packs are not installed, the studio says so and offers **Download the packs** (a 2.2 GB download): until then, the +packs are not installed, the studio says so and offers **Download the packs** (a 3.1 GB download): until then, the sampled instruments are synthesized. The **Sounds** tab lists every pack, with a button for each one that is not installed. diff --git a/docs/src/guide/cli.md b/docs/src/guide/cli.md index 11fd767..9a21b0f 100644 --- a/docs/src/guide/cli.md +++ b/docs/src/guide/cli.md @@ -431,7 +431,7 @@ terminal it asks before each download; elsewhere (and with `--yes`) it does not | `--no-models` | skips the models | | `--tags` | also downloads the AudioSet tagger, 347 MB more, used by `--tags` | -The prompt shows what is missing and how much it downloads: about 2.2 GB for the default packs, which take 1.2 GB on +The prompt shows what is missing and how much it downloads: about 3.1 GB for the default packs, which take 1.5 GB on disk because several arrive as WAV and are converted to FLAC, and 785 MB for the models (the prompt says about 0.8 GB, or 1.1 GB with `--tags`). An interrupted pack download resumes where it stopped; a model file that was cut off downloads again from its start, and the files that finished are kept. After the models arrive, the first load spends @@ -445,7 +445,7 @@ Checks the installation and says what is missing. $ claudius doctor claudius 0.1.0 (macos aarch64) ok web studio ~/.local/share/claudius/web - ok sample packs 14 default packs (1.2 GB) in ~/Library/Application Support/claudius/packs + ok sample packs 22 default packs (1.5 GB) in ~/Library/Application Support/claudius/packs ok ears models in ~/.cache/earshot-rs ok Apple Loops 14096 loops and samples ok ffmpeg 9.0.2 (writes song.mp3) diff --git a/docs/src/guide/packs.md b/docs/src/guide/packs.md index 4902213..8fb4e1d 100644 --- a/docs/src/guide/packs.md +++ b/docs/src/guide/packs.md @@ -11,7 +11,7 @@ instrument maps onto them) and a `files/` folder. ## The packs -`claudius-packs list` shows every pack with its state and licence. The 14 default packs hold 162 instruments: +`claudius-packs list` shows every pack with its state and licence. The 22 default packs hold 253 instruments: | pack | what | instruments | licence | credit required | on disk | |---|---|---|---|---|---| @@ -19,21 +19,30 @@ instrument maps onto them) and a `files/` folder. | `epianos` | Wurlitzer EP200, Yamaha CP80, Hohner Pianet T | 3 | CC BY 3.0 | yes | 21 MB | | `jrhodes` | 1977 Rhodes Mark I, 5 crossfaded layers | 1 | free for making music; no redistribution of the samples | no | 38 MB | | `vsco2` | VS Chamber Orchestra 2: strings, brass, woodwinds, harp, timpani, key-split sections | 36 | CC0 | no | 284 MB | -| `vcsl` | mallets, pipe organ, tenor sax, harmonica, world and orchestral percussion | 32 | CC0 | no | 150 MB | +| `vcsl` | mallets, bowed vibraphone, wine glasses, pipe organ, ocarina, tenor sax, harmonica, didgeridoo, a TX81Z FM synth, zithers, world and orchestral percussion, effects | 51 | CC0 | no | 238 MB | | `tr808` | Roland TR-808 by Michael Fischer, every knob at five positions | 16 | CC0 | no | 13 MB | | `tr909` | Roland TR-909 by Audio Realism, accent layers and knob sweeps | 11 | free for personal and commercial use, no redistribution | no | 26 MB | | `tr707` | Roland TR-707, all 15 sounds | 13 | public domain | no | 0.5 MB | | `uzu` | the uzu drum kit made for Strudel | 15 | Unlicense | no | 2.4 MB | | `muldjord` | MuldjordKit, an acoustic rock kit (bank `acoustic`) | 11 | CC BY 4.0 | yes | 135 MB | -| `freepats` | upright piano, FM piano, drawbar organ, basses, guitars, synth pads, strings and leads | 19 | CC0 | no | 137 MB | +| `freepats` | upright piano, FM piano, drawbar organ, basses, guitars, synth pads, strings and leads, glasses of water, a hang | 21 | CC0 | no | 157 MB | | `doublebass` | double bass pizzicato with round robins | 1 | CC0 | no | 30 MB | | `growlybass` | Squier Jazz Bass, fingered | 1 | CC0 | no | 67 MB | | `voice` | a low male "ah", and a 5-voice choir made from it | 2 | CC0 | no | 27 MB | - -The download is about 2.2 GB, larger than the 1.2 GB on disk, because `vsco2`, `vcsl`, `tr909`, `doublebass`, -`growlybass` and `voice` arrive as WAV and are converted to lossless FLAC as they install. Where a pack was cut for -size (the piano keeps 5 of its 16 velocity layers, VSCO leaves out the tremolo and muted brass), the pack's -description in `claudius-packs list` says what was left out. +| `sonicpi` | Sonic Pi's samples: kicks, snares, hats, electronic one-shots, glitches, bass hits, drones, vinyl, tabla, loops | 18 | CC0 | no | 33 MB | +| `solocello` | a solo cello, bowed and plucked | 2 | CC0 | no | 60 MB | +| `erhu` | an erhu: long and short bows, sul tasto | 3 | CC0 | no | 43 MB | +| `steelpan` | a tenor steel pan, 5 velocity layers | 1 | Unlicense | no | 38 MB | +| `synthdrums` | drums made on synthesizers after vintage analog kits | 11 | CC0 | no | 2 MB | +| `body` | body percussion: claps, snaps, stomps, chest and belly hits | 14 | CC0 | no | 20 MB | +| `zamenhof` | two kits of electronic glitches | 2 | CC0 | no | 56 MB | +| `miscellania` | sound effects: aliens, zaps, sirens, metal, breaking glass, chains, bells, glockenspiel glissandi | 19 | CC0 | no | 41 MB | + +The download is about 3.1 GB, larger than the 1.5 GB on disk, because `vsco2`, `vcsl`, `tr909`, `doublebass`, +`growlybass`, `voice`, `solocello`, `erhu`, `body`, `zamenhof` and `miscellania` arrive as WAV and are converted to +lossless FLAC as they install; each conversion is read back and compared with the WAV. Where a pack was cut for size +(the piano keeps 5 of its 16 velocity layers, VSCO leaves out the tremolo and muted brass), the pack's description in +`claudius-packs list` says what was left out. Two more packs install only when you name them: @@ -107,12 +116,13 @@ A script or a genre asks for an instrument by name, and the installed packs deci | `piano` | a friendly alias: the first installed of `salamander:piano`, `splendid:piano`, `freepats:upright_piano`, `piano-lite:piano` | | `vsco2:violins` | that pack's instrument, by name or by one of its aliases (`vsco2:violin_ensemble`) | | `tr808:sd:3` | variation 3 of that instrument | +| `vinyl_scratch` | a variation by its own name, when it starts with its instrument's (Sonic Pi's names): `sonicpi:vinyl:3` | | `kick`, `bd`, `hh` | a bare drum name: the first installed kit of `tr909`, `tr808`, `muldjord`, `tr707`, `uzu` that has it | | `RolandTR909_bd` | a Strudel bank name: bank `RolandTR909`, sound `bd` | | `bd` with bank `tr909` | that kit's kick | `claudius-packs resolve` answers what a name plays on your machine, and `claudius-packs aliases` lists every friendly -name with what it resolves to now (262 of them with the default packs): +name with what it resolves to now (264 of them with the default packs): ```text $ claudius-packs resolve piano @@ -141,16 +151,21 @@ answer to the pack's name and its aliases: | `tr707` | `707`, `rolandtr707`, `tr-707` | Roland TR-707 | | `muldjord` | `acoustic`, `acoustic_kit`, `rock_kit` | MuldjordKit | | `uzu` | `uzu-drumkit` | uzu drum kit | +| `synthdrums` | `synth_drums`, `synth_percussion` | FreePats synthesizer percussion | +| `sonicpi` | `sonic_pi`, `sonic-pi` | Sonic Pi's kicks, snares, hats and rides, and its other groups | +| `body` | `body_percussion` | body percussion: `stomp`, `clap`, `snap`, `chest`, `belly`, `heel` ... | Drum names have synonyms (`kick`, `kd`, `bassdrum` for `bd`; `snare` for `sd`; `rimshot`, `sidestick` for `rim`; and -so on), so `s("kick").bank("808")` works. A variation picks another recording of the same drum: `bd:2` in the pattern, +so on), so `s("kick").bank("808")` works, and `s("bd sd hh").bank("sonicpi")` plays Sonic Pi's `bd`, `sn` and `hat`. A variation picks another recording of the same drum: `bd:2` in the pattern, or `.n("0 1 2")`. The drum machines have many: - `tr808`: every knob at five positions, 25 variations of `bd`, `sd` and the cymbal (tone by decay, or tone by snappy), 5 of the toms, congas and open hat; - `tr909`: variation 0 of every drum plays its 11 accent levels as velocity layers; the others are the knob sweeps (125 for `bd` and `sd`, 121 for the toms, the decay of the hats, the tuning of the cymbals); -- `tr707`: one recording per sound. +- `tr707`: one recording per sound; +- `sonicpi`: each group's sounds, in the order of their names, which they also answer to: `vinyl:3` is + `vinyl_scratch`, `bd:6` is `bd_haus`. `claudius-packs instruments` shows how many variations each instrument has. diff --git a/docs/src/language/limits.md b/docs/src/language/limits.md index 70d9b65..29d49f6 100644 --- a/docs/src/language/limits.md +++ b/docs/src/language/limits.md @@ -52,7 +52,7 @@ The messages, as printed after `Runtime error:`. | `master()` | `master() has no option 'loudness' (options: lufs ceiling)` | | `track()` | `track 'x': unknown sound 'bdd' (drums: ...; synths: ...; sampled: ...)` | | `track()`, unreadable words | `track 'x': cannot read 'h3' as a note (...)`; `track 'x': cannot read 'Xyz' as a chord (...)`; `track 'x': n() takes scale degrees (0 1 2 -1 ...), not 'e'` | -| `track()` with `.bank()` | `track 'x': no 'bongo' in bank 'tr909' (installed packs: ...; kits: tr909 tr808 tr707 acoustic uzu)` | +| `track()` with `.bank()` | `track 'x': no 'bongo' in bank 'tr909' (installed packs: ...; kits: tr909 tr808 tr707 acoustic uzu synthdrums sonicpi body)` | | `track()` without packs | `track 'x': no sample packs are installed for bank 'tr909' (install them with: claudius-packs install --defaults)`; a sampled name: `unknown sound 'rhodes' (...; sampled instruments need packs: claudius-packs install --defaults)` | | `track()` under `--synth-only` | `track 'x': bank 'tr909' plays sample packs, which are off in this session (--synth-only)`; a sampled name: `unknown sound 'rhodes' (...; sampled instruments are off in this session (--synth-only))` | | `track()` with a file | `track 'x': /path/vox.wav does not exist`; `track 'x': /path/vox.wav is outside the folders this claudius may read` | diff --git a/docs/src/language/quick-reference.md b/docs/src/language/quick-reference.md index 531bd57..835c8e4 100644 --- a/docs/src/language/quick-reference.md +++ b/docs/src/language/quick-reference.md @@ -91,7 +91,7 @@ Everything on one page. Each name links to its full entry. | | | |---|---| | `.s(name)`, `.sound(name)` | instrument for note / degree / chord patterns | -| `.bank("tr909")` | `tr909 tr808 tr707 acoustic uzu apple` | +| `.bank("tr909")` | `tr909 tr808 tr707 acoustic uzu synthdrums sonicpi body apple` | | `.scale("A:minor")` | also `dorian phrygian lydian mixolydian harmonic_minor minor_pentatonic pentatonic blues chromatic` | | `.octave(4)` | octave of degree 0 and of note names without one | | `.voicing()`, `.voicing(48, 72)` | chord range, default 52..74 | diff --git a/docs/src/language/sounds.md b/docs/src/language/sounds.md index 9d466f4..483694d 100644 --- a/docs/src/language/sounds.md +++ b/docs/src/language/sounds.md @@ -112,16 +112,24 @@ with velocity layers and round robins. Most have several aliases; `claudius-pack |---|---| | pianos and keys | `piano` (Salamander grand), `upright`, `rhodes`, `wurlitzer`, `cp80`, `pianet`, `fm_piano` | | organs | `hammond`, `church_organ` | -| strings | `string_ensemble`, `violins`, `violas`, `cellos`, `contrabass`, `pizzicato`, `spiccato` | -| brass and winds | `brass`, `brass_stabs`, `trumpet`, `horn`, `trombone`, `tuba`, `woodwinds`, `flute`, `oboe`, `clarinet`, `bassoon`, `piccolo`, `sax`, `harmonica` | -| mallets and bells | `harp`, `marimba`, `vibes`, `xylophone`, `glock`, `bells`, `kalimba`, `timpani` | -| bass and guitar | `upright_bass`, `bass` (electric), `pick_bass`, `synth_bass`, `guitar` (nylon), `electric_guitar`, `jazz_guitar` | +| strings | `string_ensemble`, `violins`, `violas`, `cellos`, `contrabass`, `pizzicato`, `spiccato`, `solo_cello`, `solo_cello_pizz`, `erhu`, `erhu_short`, `erhu_sul_tasto`, `bowed_psaltery` | +| brass and winds | `brass`, `brass_stabs`, `trumpet`, `horn`, `trombone`, `tuba`, `woodwinds`, `flute`, `oboe`, `clarinet`, `bassoon`, `piccolo`, `sax`, `harmonica`, `ocarina` | +| mallets and bells | `harp`, `marimba`, `vibes`, `bowed_vibraphone`, `xylophone`, `glock`, `bells`, `hand_chimes`, `kalimba`, `balafon`, `steel_pan`, `hang`, `water_glasses`, `wine_glasses`, `timpani` | +| bass and guitar | `upright_bass`, `bass` (electric), `pick_bass`, `synth_bass`, `guitar` (nylon), `electric_guitar`, `jazz_guitar`, `dan_tranh`, `dan_tranh_tremolo` | | voices | `choir`, `voice` | -| synths, recorded | `synth_pad`, `new_age_pad`, `bowed_pad`, `choir_pad`, `synth_strings`, `synth_brass`, `lead` | -| percussion | `bongo`, `conga`, `cajon`, `darbuka`, `frame_drum`, `tambourine`, `cabasa`, `claves`, `woodblock`, `agogo`, `guiro`, `triangle`, `sleigh_bells`, `vibraslap`, `mark_tree`, `claps`, `gong`, `suspended_cymbal` | +| synths, recorded | `synth_pad`, `new_age_pad`, `bowed_pad`, `choir_pad`, `synth_strings`, `synth_brass`, `lead`, `clavisynth` (Yamaha TX81Z) | +| percussion | `bongo`, `conga`, `cajon`, `darbuka`, `frame_drum`, `slit_drum`, `tambourine`, `cabasa`, `claves`, `woodblock`, `agogo`, `guiro`, `triangle`, `sleigh_bells`, `vibraslap`, `mark_tree`, `claps`, `gong`, `suspended_cymbal`, `anvil`, `brake_drum`, `finger_cymbals`, `bell_tree`, `didgeridoo`, `tabla`, `stomp`, `chest`, `belly`, `heel` | +| electronic one-shots | `elec`, `glitch`, `mehackit`, `glitch_kit`, `glitch_kit_2`, Sonic Pi's names (`elec_blip`, `bd_haus`, `hat_snap`) | +| effects and textures | `ambi` (drones), `vinyl`, `loop`, `tbd` (pads), `ocean_drum`, `flexatone`, `ratchet`, `siren`, `aliens`, `zaps`, `sirens`, `metal_hits`, `glass_breaks`, `cymbal_gongs`, `chains`, `bubbles`, `vibra_rings`, `nepalese_bells`, `glock_gliss` | `pack:instrument` names one exactly, in `.s()` or in an `s()` pattern: `note("c4 e4").s("vsco2:violins")`, -`s("vcsl:shaker*8")`. +`s("vcsl:shaker*8")`. A name that is also a drum name plays the synthesized drum; name the pack for the recording: +`s("snap clap").bank("body")`, or `s("body:snap")`. + +The groups of one-shots (`elec`, `zaps`, `glitch_kit` ...) hold their sounds as [variations](#variations): +`s("zaps:3")`, `s("glitch_kit").n("<0 5 12>")`. Sonic Pi's sounds also answer to their own names, `s("vinyl_scratch")` +being `s("vinyl:3")`. The hang plays only its own notes (A3 C4 D4 E4 F4 G4 A4 Bb4 C5 D5): the others ring along with +each one, so pitching it would put them in another scale. Every recorded instrument has a playable range; notes outside it are pitched from the nearest sample, which sounds stretched far from home. Songs that play instruments from packs whose licences ask for credit get a `credits.txt` in @@ -154,6 +162,9 @@ Sampled percussion from the packs gets the `perc` [role](mixing.md#roles) by its | `tr707` | `707` | Roland TR-707 | | `muldjord` | `acoustic`, `acoustic_kit`, `rock_kit` | a recorded acoustic kit | | `uzu` | | the uzu drum kit | +| `synthdrums` | `synth_drums` | drums made on synthesizers after vintage analog kits | +| `sonicpi` | `sonic_pi` | Sonic Pi's kicks (`bd`), snares (`sn`), hats (`hat`) and rides, and its other groups | +| `body` | `body_percussion` | body percussion: `stomp`, `clap`, `snap`, `chest`, `belly`, `heel`, `cheek` ... | Each kit has a subset of `bd sd cp hh oh rd cr lt mt ht rim cb sh` (the 909 has no shaker, the acoustic kit no clap); names like `kick` and `snare` map to them. A name the bank does not have is an error: @@ -164,7 +175,7 @@ track("drums", s("bd*4, bongo*2").bank("tr909")); ``` ```text -Error: Runtime error: track 'drums': no 'bongo' in bank 'tr909' (installed packs: salamander epianos jrhodes vsco2 vcsl tr808 tr909 tr707 uzu muldjord freepats doublebass growlybass voice; kits: tr909 tr808 tr707 acoustic uzu) (line 2, position 1) +Error: Runtime error: track 'drums': no 'bongo' in bank 'tr909' (installed packs: salamander epianos jrhodes vsco2 vcsl tr808 tr909 tr707 uzu muldjord freepats doublebass growlybass voice sonicpi solocello erhu steelpan synthdrums body zamenhof miscellania; kits: tr909 tr808 tr707 acoustic uzu synthdrums sonicpi body) (line 2, position 1) ``` The bank applies to every word of the pattern. To mix kits, or a kit and a sampled instrument, in one pattern, name diff --git a/docs/src/learn/producers/sounds.md b/docs/src/learn/producers/sounds.md index c314306..95e832f 100644 --- a/docs/src/learn/producers/sounds.md +++ b/docs/src/learn/producers/sounds.md @@ -29,7 +29,7 @@ arrangement asks for, with the riser pitched to the key. The crash is a drum voi ## Recorded **Sample packs.** Multi-sampled instruments and drum machines under licences that allow making and publishing music -with them. `claudius-packs install --defaults` installs fourteen packs (a 2.2 GB download, 1.2 GB on disk): +with them. `claudius-packs install --defaults` installs 22 packs (a 3.1 GB download, 1.5 GB on disk): | pack | what | licence | |---|---|---| @@ -37,13 +37,17 @@ with them. `claudius-packs install --defaults` installs fourteen packs (a 2.2 GB | `epianos` | Wurlitzer, CP80, Pianet | CC BY 3.0 | | `jrhodes` | Rhodes Mark I | free for music | | `vsco2` | chamber orchestra: strings, brass, woodwinds, harp, timpani | CC0 | -| `vcsl` | mallets, pipe organ, sax, harmonica, world percussion | CC0 | +| `vcsl` | mallets, bowed vibraphone, wine glasses, pipe organ, sax, harmonica, a TX81Z FM synth, zithers, world percussion, effects | CC0 | | `tr808`, `tr909`, `tr707` | Roland drum machines | CC0; free use; public domain | -| `uzu` | a drum kit | Unlicense | +| `uzu`, `synthdrums` | electronic drum kits | Unlicense; CC0 | | `muldjord` | an acoustic drum kit | CC BY 4.0 | -| `freepats` | upright piano, organ, guitars, basses, synth pads and leads | CC0 | +| `freepats` | upright piano, organ, guitars, basses, synth pads and leads, glasses of water, a hang | CC0 | | `doublebass`, `growlybass` | upright and electric bass | CC0 | | `voice` | a sung vowel and a choir | CC0 | +| `solocello`, `erhu`, `steelpan` | a solo cello, an erhu, a steel pan | CC0; Unlicense | +| `sonicpi` | Sonic Pi's one-shots, drones, vinyl, tabla and loops | CC0 | +| `body`, `zamenhof` | body percussion; electronic glitch kits | CC0 | +| `miscellania` | sound effects: sci-fi, metal, glass, chains, bells, glissandi | CC0 | The instruments have velocity layers and round robins (the Salamander piano has five layers; the 909 kick eleven layers and 126 variations). A song that plays a pack whose licence asks for attribution gets a `credits.txt` in its diff --git a/site/index.html b/site/index.html index 30929d6..1201f79 100644 --- a/site/index.html +++ b/site/index.html @@ -727,7 +727,7 @@

Synthesized

Recorded

-

14 sample packs with 162 instruments, multi-sampled with velocity layers and round robins, all under licences that allow making and publishing music with them. claudius-packs install --defaults downloads them, about 1.1 GB. Songs that use CC BY packs get a credits.txt.

+

22 sample packs with 253 instruments, multi-sampled with velocity layers and round robins, all under licences that allow making and publishing music with them. claudius-packs install --defaults downloads them, about 3.1 GB. Songs that use CC BY packs get a credits.txt.

@@ -830,7 +830,7 @@

From source

Then

-
claudius setup                  # the sample packs (about 1.1 GB) and the listening models (about 0.8 GB)
+      
claudius setup                  # the sample packs (about 3.1 GB) and the listening models (about 0.8 GB)
 claudius doctor                 # checks the installation: studio, packs, models, ffmpeg, the port
 claudius make --genre house     # a full song in out/house-<title>-<seed>/
 claudius studio                 # the studio window, with the engine inside
diff --git a/skills/claudius-setup/SKILL.md b/skills/claudius-setup/SKILL.md index bb629ff..e2bde04 100644 --- a/skills/claudius-setup/SKILL.md +++ b/skills/claudius-setup/SKILL.md @@ -27,7 +27,7 @@ build, which serves the studio to a browser instead of opening a window. Then: ```sh -claudius setup # the default sample packs (a 2.2 GB download) and the listening models (0.8 GB); asks first +claudius setup # the default sample packs (a 3.1 GB download) and the listening models (0.8 GB); asks first claudius doctor # what is installed and what is missing, with the fix for each ``` diff --git a/skills/claudius-songs/references/script.md b/skills/claudius-songs/references/script.md index f9ff617..3b5f139 100644 --- a/skills/claudius-songs/references/script.md +++ b/skills/claudius-songs/references/script.md @@ -81,12 +81,17 @@ Methods on patterns: - Drum words, synthesized: `bd kick sd snare cp clap hh ch hat oh ohat rd ride cr crash lt mt ht tom rim rs sh shaker cb cowbell snap perc`. -- Real drum machines from the sample packs: `.bank("tr909")`, `"tr808"`, `"tr707"`, `"acoustic"`, `"uzu"`. +- Real drum machines and kits from the sample packs: `.bank("tr909")`, `"tr808"`, `"tr707"`, `"acoustic"`, `"uzu"`, + `"synthdrums"`, `"sonicpi"` (Sonic Pi's `bd`, `sn`, `hat`), `"body"` (`stomp clap snap chest`). - Synth presets: `sub_bass 808 reese acid saw_bass pluck_bass organ_bass wobble pluck supersaw pad warm_pad stab epiano keys bell organ strings square_lead chip`. - Sampled instruments when their packs are installed: `piano upright rhodes wurlitzer hammond string_ensemble violins cellos pizzicato brass trumpet flute harp marimba vibes kalimba upright_bass electric_bass guitar choir - voice sax` and more; `catalog` (or `claudius-packs instruments`) lists what is installed. + voice sax solo_cello erhu steel_pan hang water_glasses wine_glasses bowed_vibraphone dan_tranh clavisynth` and more; + `catalog` (or `claudius-packs instruments`) lists what is installed. +- One-shots and effects in groups, picked with a variation (`s("zaps:3")`, `.n()`): `elec glitch glitch_kit ambi + vinyl loop tabla aliens zaps sirens metal_hits glass_breaks chains glock_gliss ocean_drum`; Sonic Pi's sounds also + by their own names (`s("vinyl_scratch")`, `s("bd_haus")`). - A file plays as a sampler: `note("c4 ~ c4 [c4 c4]").s("/path/to/vox.wav")`; `c4` is the pitch it was recorded at. ## Recipes