Compare commits
5
Commits
f10b44acab
...
d01c64200d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d01c64200d | ||
|
|
b427c2b6dc | ||
|
|
b45885b5f7 | ||
|
|
c14ba5d2a8 | ||
|
|
47b6ee0139 |
No files matched your search
@@ -84,13 +84,21 @@ $: n("0 2 4 6").sound("piano") // samples
|
||||
$: n("0 2 4 6").sound("gm_acoustic_bass") // GM sounds
|
||||
```
|
||||
|
||||
##### Built-in Synths
|
||||
brown bytebeat crackle gm_accordion(7) gm_acoustic_bass(4) gm_acoustic_guitar_nylon(9) gm_acoustic_guitar_steel(10) gm_agogo(6) gm_alto_sax(6) gm_applause(15) gm_bagpipe(1) gm_bandoneon(10) gm_banjo(6) gm_baritone_sax(6) gm_bassoon(4) gm_bird_tweet(7) gm_blown_bottle(5) gm_brass_section(5) gm_breath_noise(8) gm_celesta(6) gm_cello(6) gm_choir_aahs(9) gm_church_organ(5) gm_clarinet(6) gm_clavinet(4) gm_contrabass(3) gm_distortion_guitar(7) gm_drawbar_organ(7) gm_dulcimer(5) gm_electric_bass_finger(4) gm_electric_bass_pick(5) gm_electric_guitar_clean(9) gm_electric_guitar_jazz(9) gm_electric_guitar_muted(10) gm_english_horn(4) gm_epiano1(11) gm_epiano2(9) gm_fiddle(9) gm_flute(5) gm_french_horn(5) gm_fretless_bass(2) gm_fx_atmosphere(13) gm_fx_brightness(12) gm_fx_crystal(10) gm_fx_echoes(10) gm_fx_goblins(9) gm_fx_rain(6) gm_fx_sci_fi(9) gm_fx_soundtrack(5) gm_glockenspiel(5) gm_guitar_fret_noise(8) gm_guitar_harmonics(3) gm_gunshot(12) gm_harmonica(6) gm_harpsichord(8) gm_helicopter(16) gm_kalimba(5) gm_koto(9) gm_lead_1_square(3) gm_lead_2_sawtooth(7) gm_lead_3_calliope(7) gm_lead_4_chiff(6) gm_lead_5_charang(10) gm_lead_6_voice(6) gm_lead_7_fifths(5) gm_lead_8_bass_lead(5) gm_marimba(7) gm_melodic_tom(9) gm_music_box(5) gm_muted_trumpet(5) gm_oboe(5) gm_ocarina(4) gm_orchestra_hit(5) gm_orchestral_harp(5) gm_overdriven_guitar(10) gm_pad_bowed(5) gm_pad_choir(6) gm_pad_halo(8) gm_pad_metallic(7) gm_pad_new_age(12) gm_pad_poly(7) gm_pad_sweep(7) gm_pad_warm(7) gm_pan_flute(8) gm_percussive_organ(6) gm_piano(32) gm_piccolo(5) gm_pizzicato_strings(6) gm_recorder(5) gm_reed_organ(8) gm_reverse_cymbal(9) gm_rock_organ(5) gm_seashore(16) gm_shakuhachi(5) gm_shamisen(7) gm_shanai(5) gm_sitar(7) gm_slap_bass_1(4) gm_slap_bass_2(4) gm_soprano_sax(5) gm_steel_drums(6) gm_string_ensemble_1(11) gm_string_ensemble_2(7) gm_synth_bass_1(9) gm_synth_bass_2(7) gm_synth_brass_1(4) gm_synth_brass_2(7) gm_synth_choir(5) gm_synth_drum(7) gm_synth_strings_1(7) gm_synth_strings_2(4) gm_taiko_drum(10) gm_telephone(10) gm_tenor_sax(4) gm_timpani(6) gm_tinkle_bell(1) gm_tremolo_strings(6) gm_trombone(5) gm_trumpet(4) gm_tuba(4) gm_tubular_bells(6) gm_vibraphone(6) gm_viola(5) gm_violin(9) gm_voice_oohs(6) gm_whistle(4) gm_woodblock(9) gm_xylophone(6) pink pulse saw sawtooth sbd sin sine sqr square supersaw tri triangle white z_noise z_sawtooth z_sine z_square z_tan z_triangle zzfx
|
||||
|
||||
##### Built-in Drum Machines
|
||||
9000_bd(1) 9000_cb(2) 9000_cr(2) 9000_hh(1) 9000_ht(2) 9000_lt(2) 9000_mt(1) 9000_oh(1) 9000_perc(3) 9000_rd(2) 9000_rim(1) 9000_sd(1) 9000_tb(1) ace_bd(3) ace_hh(1) ace_ht(1) ace_lt(1) ace_oh(1) ace_perc(6) ace_sd(3) ajkpercusyn_bd(1) ajkpercusyn_cb(2) ajkpercusyn_ht(1) ajkpercusyn_sd(1) akailinn_bd(1) akailinn_cb(1) akailinn_cp(1) akailinn_cr(1) akailinn_hh(1) akailinn_ht(1) akailinn_lt(1) akailinn_mt(1) akailinn_oh(1) akailinn_rd(1) akailinn_sd(1) akailinn_sh(1) akailinn_tb(1) akaimpc60_bd(2) akaimpc60_cp(1) akaimpc60_cr(1) akaimpc60_hh(1) akaimpc60_ht(1) akaimpc60_lt(1) akaimpc60_misc(2) akaimpc60_mt(1) akaimpc60_oh(1) akaimpc60_perc(5) akaimpc60_rd(1) akaimpc60_rim(1) akaimpc60_sd(3) akaixr10_bd(10) akaixr10_cb(1) akaixr10_cp(1) akaixr10_cr(3) akaixr10_hh(2) akaixr10_ht(1) akaixr10_lt(2) akaixr10_misc(4) akaixr10_mt(2) akaixr10_oh(1) akaixr10_perc(15) akaixr10_rd(1) akaixr10_rim(2) akaixr10_sd(10) akaixr10_sh(1) akaixr10_tb(1) alesishr16_bd(1) alesishr16_cp(1) alesishr16_hh(1) alesishr16_ht(1) alesishr16_lt(1) alesishr16_oh(1) alesishr16_perc(8) alesishr16_rim(1) alesishr16_sd(1) alesishr16_sh(3) alesissr16_bd(13) alesissr16_cb(1) alesissr16_cp(1) alesissr16_cr(2) alesissr16_hh(3) alesissr16_misc(3) alesissr16_oh(4) alesissr16_perc(7) alesissr16_rd(3) alesissr16_rim(1) alesissr16_sd(12) alesissr16_sh(1) alesissr16_tb(1) bd(8) bossdr110_bd(1) bossdr110_cp(1) bossdr110_cr(1) bossdr110_hh(1) bossdr110_oh(1) bossdr110_rd(1) bossdr110_sd(1) bossdr220_bd(1) bossdr220_cp(1) bossdr220_cr(1) bossdr220_hh(1) bossdr220_ht(1) bossdr220_lt(1) bossdr220_mt(1) bossdr220_oh(1) bossdr220_perc(1) bossdr220_rd(1) bossdr220_sd(1) bossdr55_bd(2) bossdr55_hh(2) bossdr55_rim(1) bossdr55_sd(8) bossdr550_bd(5) bossdr550_cb(2) bossdr550_cp(1) bossdr550_cr(1) bossdr550_hh(2) bossdr550_ht(3) bossdr550_lt(3) bossdr550_misc(3) bossdr550_mt(2) bossdr550_oh(2) bossdr550_perc(11) bossdr550_rd(2) bossdr550_rim(1) bossdr550_sd(6) bossdr550_sh(2) bossdr550_tb(1) brk(1) casiorz1_bd(1) casiorz1_cb(1) casiorz1_cp(1) casiorz1_cr(1) casiorz1_hh(1) casiorz1_ht(1) casiorz1_lt(1) casiorz1_mt(1) casiorz1_rd(2) casiorz1_rim(1) casiorz1_sd(1) casiosk1_bd(1) casiosk1_hh(1) casiosk1_ht(1) casiosk1_mt(1) casiosk1_oh(1) casiosk1_sd(1) casiovl1_bd(1) casiovl1_hh(1) casiovl1_sd(1) cb(1) circuitsdrumtracks_bd(1) circuitsdrumtracks_cb(1) circuitsdrumtracks_cp(1) circuitsdrumtracks_cr(1) circuitsdrumtracks_hh(1) circuitsdrumtracks_ht(1) circuitsdrumtracks_oh(1) circuitsdrumtracks_rd(1) circuitsdrumtracks_rim(1) circuitsdrumtracks_sd(1) circuitsdrumtracks_sh(1) circuitsdrumtracks_tb(1) circuitstom_bd(1) circuitstom_cp(1) circuitstom_cr(1) circuitstom_hh(1) circuitstom_ht(2) circuitstom_oh(1) circuitstom_sd(1) compurhythm1000_bd(1) compurhythm1000_cb(1) compurhythm1000_cp(1) compurhythm1000_cr(1) compurhythm1000_hh(1) compurhythm1000_ht(1) compurhythm1000_lt(1) compurhythm1000_mt(1) compurhythm1000_oh(1) compurhythm1000_perc(3) compurhythm1000_rd(1) compurhythm1000_rim(1) compurhythm1000_sd(1) compurhythm78_bd(1) compurhythm78_cb(1) compurhythm78_hh(2) compurhythm78_misc(4) compurhythm78_oh(2) compurhythm78_perc(8) compurhythm78_sd(1) compurhythm78_tb(1) compurhythm8000_bd(1) compurhythm8000_cb(1) compurhythm8000_cp(1) compurhythm8000_cr(1) compurhythm8000_hh(1) compurhythm8000_ht(1) compurhythm8000_lt(1) compurhythm8000_mt(1) compurhythm8000_oh(1) compurhythm8000_perc(2) compurhythm8000_rim(1) compurhythm8000_sd(1) concertmatemg1_bd(3) concertmatemg1_sd(2) cp(2) cr(2) d110_bd(1) d110_cb(2) d110_cr(1) d110_hh(1) d110_lt(1) d110_oh(2) d110_perc(3) d110_rd(1) d110_rim(1) d110_sd(3) d110_sh(1) d110_tb(1) d70_bd(4) d70_cb(1) d70_cp(1) d70_cr(1) d70_hh(1) d70_lt(1) d70_mt(1) d70_oh(1) d70_perc(1) d70_rd(1) d70_rim(1) d70_sd(5) d70_sh(1) ddm110_bd(1) ddm110_cp(1) ddm110_cr(1) ddm110_hh(1) ddm110_ht(2) ddm110_lt(2) ddm110_oh(1) ddm110_rim(1) ddm110_sd(1) ddr30_bd(8) ddr30_ht(4) ddr30_lt(4) ddr30_sd(8) dmx_bd(3) dmx_cp(1) dmx_cr(1) dmx_hh(1) dmx_ht(1) dmx_lt(1) dmx_mt(1) dmx_oh(1) dmx_rd(1) dmx_rim(1) dmx_sd(3) dmx_sh(1) dmx_tb(1) doepferms404_bd(2) doepferms404_hh(1) doepferms404_lt(1) doepferms404_oh(1) doepferms404_sd(1) dpm48_bd(3) dpm48_cp(1) dpm48_cr(1) dpm48_hh(2) dpm48_ht(1) dpm48_lt(2) dpm48_mt(1) dpm48_oh(1) dpm48_perc(2) dpm48_rd(1) dpm48_rim(1) dpm48_sd(2) dpm48_sh(2) dr110_bd(1) dr110_cp(1) dr110_cr(1) dr110_hh(1) dr110_oh(1) dr110_rd(1) dr110_sd(1) dr220_bd(1) dr220_cp(1) dr220_cr(1) dr220_hh(1) dr220_ht(1) dr220_lt(1) dr220_mt(1) dr220_oh(1) dr220_perc(1) dr220_rd(1) dr220_sd(1) dr55_bd(2) dr55_hh(2) dr55_rim(1) dr55_sd(8) dr550_bd(5) dr550_cb(2) dr550_cp(1) dr550_cr(1) dr550_hh(2) dr550_ht(3) dr550_lt(3) dr550_misc(3) dr550_mt(2) dr550_oh(2) dr550_perc(11) dr550_rd(2) dr550_rim(1) dr550_sd(6) dr550_sh(2) dr550_tb(1) drumulator_bd(1) drumulator_cb(1) drumulator_cp(1) drumulator_cr(1) drumulator_hh(1) drumulator_ht(1) drumulator_lt(1) drumulator_mt(1) drumulator_oh(1) drumulator_perc(1) drumulator_rim(1) drumulator_sd(1) emudrumulator_bd(1) emudrumulatLine truncated
|
||||
|
||||
##### Built-in Samples
|
||||
agogo(5) anvil(9) balafon(6) balafon_hard(6) balafon_soft(6) ballwhistle(2) bassdrum1(8) bassdrum2(30) belltree(6) bongo(28) brakedrum(17) cabasa(6) cajon(18) casio(3) clap(10) clash(10) clash2(5) clave(6) clavisynth(19) conga(34) cowbell(13) crow(4) dantranh(17) dantranh_tremolo(16) dantranh_vibrato(16) darbuka(20) didgeridoo(12) east(9) fingercymbal(1) flexatone(8) fmpiano(22) folkharp(29) framedrum(18) glockenspiel(7) gong(7) gong2(6) guiro(5) handbells(3) handchimes(19) harmonica(9) harmonica_soft(10) harmonica_vib(10) harp(23) hihat(15) insect(3) jazz(8) kalimba(11) kalimba2(25) kalimba3(22) kalimba4(22) kalimba5(14) kawai(37) marimba(10) marktrees(6) metal(10) num(21) numbers(9) ocarina(11) ocarina_small(10) ocarina_small_stacc(13) ocarina_vib(10) oceandrum(3) organ_4inch(27) organ_8inch(27) organ_full(27) piano(29) piano1(22) pipeorgan_loud(21) pipeorgan_loud_pedal(11) pipeorgan_quiet(21) pipeorgan_quiet_pedal(11) psaltery_bow(11) psaltery_pluck(11) psaltery_spiccato(11) ratchet(8) recorder_alto_stacc(12) recorder_alto_sus(12) recorder_alto_vib(12) recorder_bass_stacc(15) recorder_bass_sus(12) recorder_bass_vib(14) recorder_soprano_stacc(12) recorder_soprano_sus(13) recorder_tenor_stacc(12) recorder_tenor_sus(13) recorder_tenor_vib(14) sax(23) sax_stacc(23) sax_vib(19) saxello(8) saxello_stacc(8) saxello_vib(8) shaker_large(6) shaker_small(16) siren(5) slapstick(5) sleighbells(6) slitdrum(6) snare_hi(8) snare_low(20) snare_modern(72) snare_rim(4) space(18) steinway(42) strumstick(19) super64(13) super64_acc(13) super64_vib(13) sus_cymbal(25) sus_cymbal2(23) tambourine(7) tambourine2(7) timpani(30) timpani_roll(10) timpani2(204) tom_mallet(8) tom_rim(6) tom_stick(8) tom2_mallet(8) tom2_rim(6) tom2_stick(8) trainwhistle(6) triangles(37) tubularbells(9) tubularbells2(11) vibraphone(11) vibraphone_bowed(6) vibraphone_soft(11) vibraslap(4) wind(10) wineglass(4) wineglass_slow(4) woodblock(10) xylophone_hard_ff(8) xylophone_hard_pp(8) xylophone_medium_ff(8) xylophone_medium_pp(8) xylophone_soft_ff(8) xylophone_soft_pp(8)
|
||||
|
||||
#### 8. Effects and Modulation
|
||||
```javascript
|
||||
// Audio effects
|
||||
.gain(0.8) // volume
|
||||
.lpf(800) // low-pass filter
|
||||
.hpf(2000) // high-pass filter
|
||||
.reverb(0.4) // reverb amount
|
||||
.room(0.6) // room reverb
|
||||
.delay(0.25) // delay time
|
||||
.pan(-0.3) // stereo pan (-1 to 1)
|
||||
@@ -101,6 +109,10 @@ $: n("0 2 4 6").sound("gm_acoustic_bass") // GM sounds
|
||||
.pan(sine.range(-0.5, 0.5).slow(6)) // auto-pan
|
||||
```
|
||||
|
||||
## Effect Method Names
|
||||
|
||||
Strudel uses specific method names for effects that differ from some other audio frameworks. Use `.room()` for reverb (not `.reverb()`), `.gain()` for volume, `.delay()` for delay, `.lpf()`/`.hpf()` for filters, and `.pan()` for stereo positioning. If you encounter "is not a function" errors, verify you're using the correct Strudel effect method names from the official documentation.
|
||||
|
||||
#### 9. Time Manipulation
|
||||
```javascript
|
||||
.slow(2) // half speed (2x longer cycles)
|
||||
@@ -117,6 +129,24 @@ $: n("0 2 4 6").sound("gm_acoustic_bass") // GM sounds
|
||||
.mask("1 0 1 1") // rhythmic gating
|
||||
```
|
||||
|
||||
## Advanced Pattern Features
|
||||
|
||||
Strudel supports several advanced features for complex live coding:
|
||||
|
||||
**Named Patterns**: Use `$name:` syntax to create referenceable patterns (e.g., `$bass: n("0 2 4").sound("sawtooth")`), enabling pattern manipulation and live control.
|
||||
|
||||
**Precise Tempo Control**: `setCps(bpm/60/4)` provides more accurate tempo setting than basic BPM values, essential for precise synchronization.
|
||||
|
||||
**Pattern Visualization**: `._scope()` method enables visual feedback for patterns, useful for live performance monitoring.
|
||||
|
||||
**Mathematical Operations**: `.sub(n)` subtracts semitones, `.seg(n)` creates segmented phrases, `irand(n)` generates random integers for algorithmic composition.
|
||||
|
||||
**Orbit Management**: Explicit `.orbit(n)` assignment routes patterns to specific effect chains, enabling complex audio routing and independent processing.
|
||||
|
||||
**Interactive Elements**: Strudel supports embedding interactive controls directly in code, allowing real-time parameter manipulation during performance.
|
||||
|
||||
These features enable sophisticated composition techniques beyond basic sequencing, supporting professional live coding performance.
|
||||
|
||||
### Documentation Sources
|
||||
|
||||
Before providing Strudel code, agents should:
|
||||
|
||||
@@ -0,0 +1,277 @@
|
||||
---
|
||||
title: "Mastering Strudel: A Reproducible Development Environment with Nix"
|
||||
date: 2025-09-27T12:00:00+02:00
|
||||
draft: false
|
||||
tags: ["strudel", "nix", "development", "live-coding"]
|
||||
categories: ["Development"]
|
||||
build:
|
||||
render: never
|
||||
list: never
|
||||
publishResources: false
|
||||
---
|
||||
|
||||
# Mastering Strudel: A Reproducible Development Environment with Nix
|
||||
|
||||
Strudel is a fascinating JavaScript-based live coding environment that brings the power of TidalCycles to the web. As developers and musicians exploring algorithmic music composition, we've discovered that setting up a proper development environment is crucial for productive work. In this post, we'll dive deep into our Nix-based setup that makes Strudel development reproducible, reliable, and collaborative.
|
||||
|
||||
## Why Nix for Strudel Development?
|
||||
|
||||
Traditional development environments often suffer from the "works on my machine" syndrome. Dependencies drift, versions conflict, and onboarding new contributors becomes a chore. Nix solves these problems by providing declarative, reproducible environments.
|
||||
|
||||
Our Strudel development setup uses:
|
||||
|
||||
- **Nix Flakes** for pinned, reproducible dependencies
|
||||
- **Git submodules** to track the official Strudel repository
|
||||
- **Makefile** for convenient command shortcuts
|
||||
- **Comprehensive guidelines** for AI-assisted development
|
||||
|
||||
## Getting Started: The Complete Setup
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Before diving in, ensure you have:
|
||||
- [Nix](https://nixos.org/download.html) package manager (version 2.4+)
|
||||
- Git for version control
|
||||
|
||||
### Step-by-Step Setup
|
||||
|
||||
1. **Clone the repository**:
|
||||
```bash
|
||||
git clone <your-strudel-dev-repo-url>
|
||||
cd strudel
|
||||
```
|
||||
|
||||
2. **Initialize git submodules**:
|
||||
```bash
|
||||
make submodules-init submodules-update
|
||||
```
|
||||
This pulls in the official Strudel codebase as a submodule in the `src/` directory.
|
||||
|
||||
3. **Enter the development environment**:
|
||||
```bash
|
||||
make shell
|
||||
```
|
||||
This launches a Nix shell with Node.js 20, pnpm, and git pre-configured.
|
||||
|
||||
4. **Install dependencies**:
|
||||
```bash
|
||||
make install
|
||||
```
|
||||
This runs `pnpm install` within the Nix environment, ensuring consistent package versions.
|
||||
|
||||
5. **Start the development server**:
|
||||
```bash
|
||||
make dev
|
||||
```
|
||||
The Strudel REPL will be available at `http://localhost:5173`.
|
||||
|
||||
## Understanding the Project Structure
|
||||
|
||||
```
|
||||
strudel/
|
||||
├── src/ # Strudel codebase (git submodule)
|
||||
├── AGENTS.md # Guidelines for AI assistants
|
||||
├── Makefile # Development shortcuts
|
||||
├── flake.nix # Nix development environment
|
||||
├── flake.lock # Nix flake lockfile
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
The `src/` directory contains the actual Strudel monorepo as a git submodule. This approach ensures we always work with a specific, tested version of Strudel while keeping our development environment separate.
|
||||
|
||||
## Workflow Mastery with Makefile
|
||||
|
||||
Our Makefile provides a clean interface for all development tasks:
|
||||
|
||||
```bash
|
||||
make help # Show all available targets
|
||||
make update # Initialize and update git submodules
|
||||
make install # Install dependencies
|
||||
make dev # Start development server
|
||||
make build # Build the project
|
||||
make test # Run tests
|
||||
make lint # Run linter
|
||||
make format # Format code
|
||||
make check # Run all checks
|
||||
make clean # Clean build artifacts
|
||||
make shell # Enter Nix development shell
|
||||
```
|
||||
|
||||
Every command automatically runs within the Nix environment, ensuring consistency across different machines and operating systems.
|
||||
|
||||
## Git Submodules: The Right Way
|
||||
|
||||
Working with git submodules can be tricky, but we've established best practices:
|
||||
|
||||
### Common Pitfalls and Solutions
|
||||
|
||||
**Problem**: `git status` shows submodule changes after installing dependencies.
|
||||
|
||||
**Solution**: Dependencies like `node_modules/` are properly ignored in the submodule's `.gitignore`. However, some files may have permission changes during installation (like executable scripts). To handle this:
|
||||
|
||||
```bash
|
||||
# Check what changed
|
||||
cd src && git status
|
||||
|
||||
# Discard unintended changes
|
||||
git submodule foreach git checkout -- .
|
||||
|
||||
# Reset submodule to clean state
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
**Key Principle**: Treat submodules as read-only for local changes. If you need to modify Strudel itself, commit changes to the upstream repository first.
|
||||
|
||||
## AI-Assisted Development: Guidelines for Success
|
||||
|
||||
Our `AGENTS.md` document provides comprehensive guidelines for AI assistants working with Strudel. Here are the critical points:
|
||||
|
||||
### Strudel is NOT JavaScript
|
||||
|
||||
Despite being built with JavaScript, Strudel uses its own pattern-based syntax:
|
||||
|
||||
```javascript
|
||||
// ✅ CORRECT - Direct pattern composition
|
||||
$: sound("bd*4")
|
||||
$: sound("~ sd ~ sd")
|
||||
$: sound("hh*8").gain(0.3)
|
||||
|
||||
// ❌ WRONG - JavaScript-style approach
|
||||
const kick = sound("bd*4");
|
||||
const snare = sound("~ sd ~ sd");
|
||||
```
|
||||
|
||||
### Essential Syntax Patterns
|
||||
|
||||
**Parallel Patterns**: Use multiple `$:` lines for simultaneous playback
|
||||
**Muting**: Prefix with `_` to silence patterns during live performance
|
||||
**Mini-notation**: `"bd ~ sd ~"` for rhythmic patterns
|
||||
**Scale-based Composition**: Use `n("0 2 4 6").scale("C:minor")` instead of manual note names
|
||||
|
||||
### Sound Sources and Effects
|
||||
|
||||
```javascript
|
||||
// Drum samples
|
||||
$: sound("bd sd hh oh")
|
||||
|
||||
// Synthesizers with scales
|
||||
$: n("0 2 4 6").scale("C:minor").sound("sawtooth")
|
||||
|
||||
// Live effects
|
||||
$: sound("bd*4").lpf(sine.range(200, 2000).slow(8))
|
||||
```
|
||||
|
||||
### Live Performance Best Practices
|
||||
|
||||
- Each `$:` line is independently controllable
|
||||
- Use `_$:` to mute sections during performance
|
||||
- Include modulation for evolving sounds
|
||||
- Keep patterns readable for live modification
|
||||
|
||||
## Nix Flake Configuration Deep Dive
|
||||
|
||||
Our `flake.nix` provides a robust development environment:
|
||||
|
||||
```nix
|
||||
{
|
||||
description = "Strudel development environment";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils }:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
in
|
||||
{
|
||||
devShells.default = pkgs.mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
nodejs_20
|
||||
pnpm
|
||||
git
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
echo "Strudel development environment loaded"
|
||||
echo "Node.js: $(node --version)"
|
||||
echo "pnpm: $(pnpm --version)"
|
||||
'';
|
||||
};
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
This configuration:
|
||||
- Pins Nixpkgs to version 25.05 for reproducibility
|
||||
- Provides Node.js 20 and pnpm for package management
|
||||
- Includes git for version control operations
|
||||
- Shows version information on shell entry
|
||||
|
||||
## Contributing and Best Practices
|
||||
|
||||
When contributing to Strudel development:
|
||||
|
||||
- Follow the guidelines in `AGENTS.md` for AI-assisted work
|
||||
- Use lowercase commit messages
|
||||
- Ensure all changes pass `make check`
|
||||
- Test thoroughly before submitting
|
||||
|
||||
## Troubleshooting Common Issues
|
||||
|
||||
### Submodule Problems
|
||||
```bash
|
||||
make update # Reinitialize submodules
|
||||
```
|
||||
|
||||
### Dependency Issues
|
||||
```bash
|
||||
make clean && make install # Fresh dependency installation
|
||||
```
|
||||
|
||||
### Nix Issues
|
||||
Ensure Nix is installed and up-to-date. On Linux:
|
||||
```bash
|
||||
sh <(curl -L https://nixos.org/nix/install) --daemon
|
||||
```
|
||||
|
||||
## The Power of Reproducible Environments
|
||||
|
||||
This Nix-based setup eliminates common development headaches:
|
||||
|
||||
- **Zero configuration drift**: Everyone gets identical environments
|
||||
- **Easy onboarding**: New contributors can start coding immediately
|
||||
- **Version pinning**: Dependencies are locked to specific versions
|
||||
- **Cross-platform compatibility**: Works on Linux, macOS, and Windows (via WSL)
|
||||
|
||||
## Live Coding with Strudel: A Glimpse
|
||||
|
||||
Once set up, you can start creating algorithmic music immediately:
|
||||
|
||||
```javascript
|
||||
// Basic beat
|
||||
$: sound("bd*4").gain(0.8)
|
||||
$: sound("~ sd ~ sd").gain(0.7)
|
||||
$: sound("hh*8").gain(0.3)
|
||||
|
||||
// Melodic elements
|
||||
$: n("0 ~ 2 ~ 4 ~ 6 ~").scale("C2:minor").sound("sawtooth").lpf(1200)
|
||||
$: n("~ 0 ~ 2 ~ 4 ~ 6").scale("C4:minor").sound("piano").room(0.6)
|
||||
|
||||
// Live effects
|
||||
_$: sound("bd*4").lpf(sine.range(200, 2000).slow(8)) // muted filter sweep
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
|
||||
Setting up a proper development environment for Strudel isn't just about getting code to run—it's about creating a sustainable, collaborative workflow that scales. Our Nix-based approach, combined with careful submodule management and comprehensive guidelines, provides a solid foundation for both individual exploration and team development.
|
||||
|
||||
Whether you're a seasoned live coder or just starting your algorithmic music journey, this environment ensures you can focus on what matters most: creating amazing sounds.
|
||||
|
||||
The Strudel community welcomes contributors at all levels. Check out the [official Strudel website](https://strudel.cc/) and [workshop](https://strudel.cc/workshop/) to learn more, and join us in pushing the boundaries of live coding music!
|
||||
|
||||
---
|
||||
|
||||
*This post is part of our series on reproducible development environments. Stay tuned for more insights into modern software development practices.*
|
||||
@@ -0,0 +1,15 @@
|
||||
// Switch Angel's tempo setup - 140 BPM
|
||||
setCps(140/60/4)
|
||||
|
||||
// ACID bassline with sidechain ducking
|
||||
$: s("sbd*4")._scope()
|
||||
.duck("2:3:4").duckattack(.2).duckdepth(.8)
|
||||
|
||||
// Complex bass pattern - removing the unknown .rtb() method
|
||||
$bass: n(irand(10).sub(7).seg(16)).scale("D:minor")
|
||||
.distort("2.2") // simplified distortion syntax
|
||||
.s("sawtooth").lpf(200).lpenv(2.28) // filter envelope modulation
|
||||
.lpq(12).orbit(2) // high resonance, orbit 2
|
||||
|
||||
// Supersaw pad with detuning and beat sync
|
||||
$: s("supersaw").detune(1).rel(5).beat(2, 32).slow(2)
|
||||
Reference in new issue
Block a user