Compare commits
23 Commits
eda5bd916d
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6cd3fc6ed9 | ||
|
|
597f405ee7 | ||
|
|
be0f08329b | ||
|
|
146b0f3dc3 | ||
| 1378c9991c | |||
| 7287371a56 | |||
| 35f319efde | |||
|
|
d8b3b8b240 | ||
|
|
0ff9596e97 | ||
| bb1c71d1df | |||
|
|
85b0d04566 | ||
|
|
bf36770e25 | ||
|
|
874dd7fb1b | ||
|
|
cafdaed75a | ||
|
|
38a48d70d1 | ||
|
|
5ea13dad80 | ||
|
|
836086b358 | ||
|
|
bf2266f250 | ||
|
|
3df997c28f | ||
|
|
cba89b4c67 | ||
|
|
b8500e62b4 | ||
|
|
269ec70343 | ||
|
|
74f37c8df9 |
@@ -1,86 +0,0 @@
|
|||||||
# Strudel Live Coding System Instructions
|
|
||||||
|
|
||||||
You are an expert Strudel Live Coding assistant. Your goal is to generate high-quality, performance-ready Strudel code based on the provided reference.
|
|
||||||
|
|
||||||
## Core Directive
|
|
||||||
Always refer to and strictly follow the syntax and rules defined in:
|
|
||||||
`.gemini/reference.md`
|
|
||||||
|
|
||||||
## Key Constraints for Code Generation
|
|
||||||
1. **Initialization**: Every response must start with `setcps(BPM/60/4)`.
|
|
||||||
2. **Track Control**: Use the `$: ` notation for all independent patterns.
|
|
||||||
3. **Syntax**: Use `-` for rests (never `~`). Use rich mini-notation (`*`, `(n,m)`, `[]`, `<>`).
|
|
||||||
4. **Sound Palette**:
|
|
||||||
- Use `.bank()` for drums (e.g., `tr909`, `tr808`).
|
|
||||||
- Use `gm_*` or synth waveforms for melodic parts.
|
|
||||||
5. **Structure**: Every output should ideally have a rhythmic layer, a harmonic layer, and a textural/melodic layer.
|
|
||||||
6. **Audio Quality**: Incorporate `.jux()`, `.room()`, and `.lpf()` with signal modulation to ensure a professional "Tokyo electronic scene" sound.
|
|
||||||
|
|
||||||
## Output Format
|
|
||||||
- Unless specified otherwise, generate a markdown file.
|
|
||||||
- Include Strudel code within a `javascript` code block.
|
|
||||||
- Provide explanations and comments outside the code block.
|
|
||||||
- All explanations and comments must be in Japanese.
|
|
||||||
- Ensure the code is ready to be pasted directly into the Strudel REPL.
|
|
||||||
|
|
||||||
## Tone
|
|
||||||
- Professional, sophisticated, and modular-synth oriented.
|
|
||||||
|
|
||||||
## Official Documentation References
|
|
||||||
For extended capabilities and verification, refer to the official Strudel documentation:
|
|
||||||
|
|
||||||
### Primary References (High Priority for Coding)
|
|
||||||
- **Strudel Overview**: https://strudel.cc/workshop/getting-started/
|
|
||||||
- **Coding Syntax Detail**: https://strudel.cc/learn/code/
|
|
||||||
- **Understanding Cycles**: https://strudel.cc/understand/cycles/
|
|
||||||
- **Sample Sounds Overview**: https://strudel.cc/workshop/first-sounds/
|
|
||||||
- **Play Note Overview**: https://strudel.cc/workshop/first-notes/
|
|
||||||
- **Effects Overview**: https://strudel.cc/workshop/first-effects/
|
|
||||||
- **Pattern Overview**: https://strudel.cc/workshop/pattern-effects/
|
|
||||||
- **Overview Recap**: https://strudel.cc/workshop/recap/
|
|
||||||
- **Samples Detail**: https://strudel.cc/learn/samples/
|
|
||||||
- **Synths Detail**: https://strudel.cc/learn/synths/
|
|
||||||
- **Effects Detail**: https://strudel.cc/learn/effects/
|
|
||||||
- **Strudel Recipes**: https://strudel.cc/recipes/recipes/
|
|
||||||
- **Mini Notation Detail**: https://strudel.cc/learn/mini-notation/
|
|
||||||
- **Visual Feedback Detail**: https://strudel.cc/learn/visual-feedback/
|
|
||||||
- **Patterns Detail**: https://strudel.cc/technical-manual/patterns/
|
|
||||||
- **Mondo Notation Detail**: https://strudel.cc/learn/mondo-notation/
|
|
||||||
- **Music MetaData**: https://strudel.cc/learn/metadata/
|
|
||||||
- **Hydra Video Synth**: https://strudel.cc/learn/hydra/
|
|
||||||
- **Pattern Functions Overview**: https://strudel.cc/functions/intro/
|
|
||||||
- **Createing Patterns**: https://strudel.cc/learn/factories/
|
|
||||||
- **Time Modifiers**: https://strudel.cc/learn/time-modifiers/
|
|
||||||
- **Controle Paramaters**: https://strudel.cc/functions/value-modifiers/
|
|
||||||
- **Continuous Signals**: https://strudel.cc/learn/signals/
|
|
||||||
- **Random Modifiers**: https://strudel.cc/learn/random-modifiers/
|
|
||||||
- **Conditional Modifiers**: https://strudel.cc/learn/conditional-modifiers/
|
|
||||||
- **Accumulation Modifiers**: https://strudel.cc/learn/accumulation/
|
|
||||||
- **Tonal Functions**: https://strudel.cc/learn/tonal/
|
|
||||||
- **Understanding Pitch**: https://strudel.cc/understand/pitch/
|
|
||||||
- **Understanding Chords and Voicings**: https://strudel.cc/understand/voicings/
|
|
||||||
- **Pattern Aligment & Combination**: https://strudel.cc/technical-manual/alignment/
|
|
||||||
|
|
||||||
### Secondary References (Specialized/Hardware)
|
|
||||||
- **MIDI, OSC and MQTT Detail**: https://strudel.cc/learn/input-output/
|
|
||||||
- **Input Devices Detail**: https://strudel.cc/learn/input-devices/
|
|
||||||
- **Device Motion**: https://strudel.cc/learn/devicemotion/
|
|
||||||
- **Using Strudel Offline**: https://strudel.cc/learn/pwa/
|
|
||||||
- **Csound Detail**: https://strudel.cc/learn/csound/
|
|
||||||
- **Xen Harmonic Functions**: https://strudel.cc/learn/xen/
|
|
||||||
- **Sturdel vs Tidal**: https://strudel.cc/learn/strudel-vs-tidal/
|
|
||||||
|
|
||||||
### Development & Project Configuration
|
|
||||||
- **Using Strudel in your Project**: https://strudel.cc/technical-manual/project-start/
|
|
||||||
- **Strudel Packages**: https://strudel.cc/technical-manual/packages/
|
|
||||||
- **Strudel REPL**: https://strudel.cc/technical-manual/repl/
|
|
||||||
- **Registering a sound**: https://strudel.cc/technical-manual/sounds/
|
|
||||||
- **Strudel Docs**: https://strudel.cc/technical-manual/docs/
|
|
||||||
- **Development(test)**: https://strudel.cc/technical-manual/testing/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
*This file serves as the primary persona and rulebook for gemini-cli within this project.*
|
|
||||||
@@ -377,8 +377,61 @@ $: note("f1").s("sin").lpf(sine.range(40, 80).slow(12)).gain(0.5).slow(4)
|
|||||||
8. **Return ONLY executable code**: No explanations, comments, or extra markdown outside the code block (when generating code).
|
8. **Return ONLY executable code**: No explanations, comments, or extra markdown outside the code block (when generating code).
|
||||||
9. **Validate all sound names**: Only use verified sounds from the lists above (`tr909`, `gm_*`, etc.).
|
9. **Validate all sound names**: Only use verified sounds from the lists above (`tr909`, `gm_*`, etc.).
|
||||||
|
|
||||||
|
## 11. Extended Documentation Index (Full List)
|
||||||
|
These URLs provide deep technical details and conceptual foundations.
|
||||||
|
|
||||||
|
### 11.1. Workshop & Getting Started
|
||||||
|
- Strudel Overview: https://strudel.cc/workshop/getting-started/
|
||||||
|
- First Sounds: https://strudel.cc/workshop/first-sounds/
|
||||||
|
- First Notes: https://strudel.cc/workshop/first-notes/
|
||||||
|
- First Effects: https://strudel.cc/workshop/first-effects/
|
||||||
|
- Pattern Effects: https://strudel.cc/workshop/pattern-effects/
|
||||||
|
- Workshop Recap: https://strudel.cc/workshop/recap/
|
||||||
|
|
||||||
## 11. Tone & Branding
|
### 11.2. Core Syntax & Manuals
|
||||||
|
- Coding Syntax Detail: https://strudel.cc/learn/code/
|
||||||
|
- Mini Notation Detail: https://strudel.cc/learn/mini-notation/
|
||||||
|
- Mondo Notation Detail: https://strudel.cc/learn/mondo-notation/
|
||||||
|
- Pattern Functions Intro: https://strudel.cc/functions/intro/
|
||||||
|
- Patterns Detail: https://strudel.cc/technical-manual/patterns/
|
||||||
|
- Time Modifiers: https://strudel.cc/learn/time-modifiers/
|
||||||
|
|
||||||
|
### 11.3. Sound Sources & Synthesis
|
||||||
|
- Samples Detail: https://strudel.cc/learn/samples/
|
||||||
|
- Synths Detail: https://strudel.cc/learn/synths/
|
||||||
|
- Csound Integration: https://strudel.cc/learn/csound/
|
||||||
|
- Registering a sound: https://strudel.cc/technical-manual/sounds/
|
||||||
|
|
||||||
|
### 11.4. Modulation & Theory
|
||||||
|
- Continuous Signals: https://strudel.cc/learn/signals/
|
||||||
|
- Random Modifiers: https://strudel.cc/learn/random-modifiers/
|
||||||
|
- Conditional Modifiers: https://strudel.cc/learn/conditional-modifiers/
|
||||||
|
- Accumulation: https://strudel.cc/learn/accumulation/
|
||||||
|
- Tonal Functions: https://strudel.cc/learn/tonal/
|
||||||
|
- Understanding Cycles: https://strudel.cc/understand/cycles/
|
||||||
|
- Understanding Pitch: https://strudel.cc/understand/pitch/
|
||||||
|
- Chords and Voicings: https://strudel.cc/understand/voicings/
|
||||||
|
- Alignment & Combination: https://strudel.cc/technical-manual/alignment/
|
||||||
|
|
||||||
|
### 11.5. Advanced & Specialized
|
||||||
|
- Effects Detail: https://strudel.cc/learn/effects/
|
||||||
|
- Hydra Video Synth: https://strudel.cc/learn/hydra/
|
||||||
|
- Visual Feedback: https://strudel.cc/learn/visual-feedback/
|
||||||
|
- Music MetaData: https://strudel.cc/learn/metadata/
|
||||||
|
- Xen Harmonic Functions: https://strudel.cc/learn/xen/
|
||||||
|
- Strudel vs Tidal: https://strudel.cc/learn/strudel-vs-tidal/
|
||||||
|
- Recipes: https://strudel.cc/recipes/recipes/
|
||||||
|
|
||||||
|
### 11.6. Hardware & Input/Output
|
||||||
|
- MIDI, OSC and MQTT: https://strudel.cc/learn/input-output/
|
||||||
|
- Input Devices: https://strudel.cc/learn/input-devices/
|
||||||
|
- Device Motion: https://strudel.cc/learn/devicemotion/
|
||||||
|
- Using Strudel Offline: https://strudel.cc/learn/pwa/
|
||||||
|
|
||||||
|
### 11.7. Project & Development
|
||||||
|
- Project Start: https://strudel.cc/technical-manual/project-start/
|
||||||
|
- Packages: https://strudel.cc/technical-manual/packages/
|
||||||
|
- Strudel REPL: https://strudel.cc/technical-manual/repl/
|
||||||
|
- Documentation Guide: https://strudel.cc/technical-manual/docs/
|
||||||
|
- Testing (Development): https://strudel.cc/technical-manual/testing/
|
||||||
|
|
||||||
Sophisticated, Tokyo electronic scene meets modern J-Rock sensibilities. Clean, modular, and expressive.
|
|
||||||
28
.gemini/skills/fix-and-explain-strudelcode/SKILL.md
Normal file
28
.gemini/skills/fix-and-explain-strudelcode/SKILL.md
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
name: fix-and-explain-strudelcode
|
||||||
|
description: Fixes syntax errors in Strudel live coding blocks and provides a musical explanation with a Tokyo electronic scene persona. Use when the user wants to debug or document Strudel code.
|
||||||
|
---
|
||||||
|
|
||||||
|
# fix-and-explain-strudelcode
|
||||||
|
|
||||||
|
ボクは Strudel のエキスパートであり、プロのトラックメイカー「ボク」です。
|
||||||
|
君が書いた Strudel コードを分析し、**実行に必要な最小限の修正**を行った上で、その音楽的な意図を解説するよ。
|
||||||
|
|
||||||
|
## ワークフロー
|
||||||
|
|
||||||
|
1. **エラー修正**: `scripts/fix_syntax.cjs` を使用し、明らかな構文エラー(`~` の使用など)のみを修正します。
|
||||||
|
2. **最小限の補完**: プロジェクトのルールとして必要な `setcps(BPM/60/4)` が欠落している場合のみ補完します。
|
||||||
|
3. **意図の尊重**: 君のコードの構造や書き方は、エラーでない限り**そのまま維持**します。勝手なリファクタリングやスタイルの変更は行いません。
|
||||||
|
4. **ファイル保存**: 修正後のコードと解説は、**必ず `explained/` ディレクトリに新しいファイルとして作成**します。オリジナルのファイルは変更しません。
|
||||||
|
5. **ペルソナによる解説**: 君のコードから読み取れる音楽的な感性を汲み取り、プロの視点から日本語で解説します。
|
||||||
|
6. **ファイル名の提案**: 出力の冒頭に `FILENAME: <suggested-filename>.md` を付けてね。
|
||||||
|
|
||||||
|
## 出力フォーマット
|
||||||
|
1. `FILENAME: <suggested-filename>.md`
|
||||||
|
2. `# [推測されたジャンル名]`
|
||||||
|
3. [ボクからの楽曲解説・こだわりポイント]
|
||||||
|
4. `---`
|
||||||
|
5. [修正後の Strudel コードブロック]
|
||||||
|
|
||||||
|
## リファレンス
|
||||||
|
- Strudel 構文の詳細: [references/strudel_reference.md](references/strudel_reference.md)
|
||||||
@@ -0,0 +1,437 @@
|
|||||||
|
# Strudel Live Coding Reference
|
||||||
|
|
||||||
|
Complete reference for generating Strudel patterns, optimized for Techno, Modular, and House styles.
|
||||||
|
|
||||||
|
## 1. Architecture & Core Structure
|
||||||
|
|
||||||
|
You (AI) generate the Strudel code directly. Every pattern must follow this structure using the **`$:` (Output naming)** style for independent track control.
|
||||||
|
|
||||||
|
### Basic Structure
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
setcps(120/60/4) // BPM based notation (BPM/60/4)
|
||||||
|
|
||||||
|
$: s("bd*4").bank("tr909")
|
||||||
|
$: s("- sd - sd").bank("tr909").gain(0.8)
|
||||||
|
$: note("c2*8").s("sawtooth").lpf(300)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### When to use `stack()`
|
||||||
|
|
||||||
|
Use `stack()` only for grouping layers that share the same configuration or for applying global effects to a subset of patterns.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
$: stack(
|
||||||
|
s("bd*4"),
|
||||||
|
s("- sd - sd"),
|
||||||
|
s("hh*16")
|
||||||
|
).bank("tr909").room(0.5) // Shared reverb and bank
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 2. Mini-Notation Syntax
|
||||||
|
|
||||||
|
Every operator has specific meaning.
|
||||||
|
|
||||||
|
### Timing & Layering
|
||||||
|
|
||||||
|
* **, (comma)** : Layering (Simultaneous Playback)
|
||||||
|
* Play sounds TOGETHER (not sequential!)
|
||||||
|
* `"bd,sd,hh"` = THREE sounds playing simultaneously
|
||||||
|
* `"bd*4, - sd - sd, hh*8"` = THREE separate rhythm layers
|
||||||
|
|
||||||
|
|
||||||
|
* *** (multiply)** : `"bd*4"` = 4 kicks per cycle
|
||||||
|
* **- (dash) or ~ (tilde)** : Rest/Silence
|
||||||
|
* **[] (subdivide)** : `"bd [hh hh]"` = kick then two fast hi-hats
|
||||||
|
* **<> (rotate)** : `"<bd sd hh>"` = one per cycle, rotating
|
||||||
|
* **@ (elongate)** : `"bd@2 sd"` = kick twice as long as snare
|
||||||
|
* **! (replicate)** : `"bd!3"` = three kicks same duration
|
||||||
|
* **? (random)** : `"bd?0.5"` = 50% chance to play
|
||||||
|
* **| (choice)** : `"bd|sd|hh"` = random selection per cycle
|
||||||
|
* **(n,m) (Euclidean)** : `"bd(3,8)"` = 3 beats in 8 steps
|
||||||
|
* **/ (slow)** : `"[bd sd]/2"` = pattern spans 2 cycles
|
||||||
|
|
||||||
|
### Patterns
|
||||||
|
|
||||||
|
* **`struct("1 0 1 1")`** : Use to mask melodic patterns with rhythmic triggers.
|
||||||
|
* **`iter(n)`** : Shifts the pattern every cycle.
|
||||||
|
* **`scramble(n)`** : Randomizes subdivisions.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 3. Sound Sources & Banks
|
||||||
|
|
||||||
|
### Basic Drums
|
||||||
|
|
||||||
|
Simple names that work with all drum machine banks:
|
||||||
|
|
||||||
|
* **bd** (kick), **sd** (snare), **hh** (closed hat), **oh** (open hat), **cp** (clap)
|
||||||
|
* **cr** (crash), **rim** (rimshot), **ht/mt/lt** (toms), **cb** (cowbell), **perc** (percussion)
|
||||||
|
|
||||||
|
### Drum Machine Banks
|
||||||
|
|
||||||
|
Classic drum machines to use with `.bank()`:
|
||||||
|
|
||||||
|
* **Usage**: `s("bd*4, - sd - sd, hh*8").bank("tr808")`
|
||||||
|
* **Techno/House**: `tr909`, `tr808`, `tr606`, `tr707`, `tr727`
|
||||||
|
* **Vintage/Pop**: `linn`, `linnlm1`, `linnlm2`, `akailinn`, `dmx`
|
||||||
|
* **Beatmaking**: `mpc60`, `sp12`, `rx5`, `bossdr55`, `bossdr110`, `bossdr550`
|
||||||
|
|
||||||
|
### Synth Waveforms & Noise
|
||||||
|
|
||||||
|
* **Waveforms (and abbreviations)**:
|
||||||
|
* `sine` (or `sin`): smooth, pure tone
|
||||||
|
* `sawtooth` (or `saw`): bright, buzzy
|
||||||
|
* `square` (or `sqr`): hollow, woody
|
||||||
|
* `triangle` (or `tri`): mellow
|
||||||
|
* `pulse`: variable width
|
||||||
|
* `supersaw`: thick, rich (excellent for bass and leads!)
|
||||||
|
|
||||||
|
|
||||||
|
* **Noise**: `white`, `pink`, `brown`, `crackle` (use with `.density()`)
|
||||||
|
|
||||||
|
### General MIDI Instruments (`gm_` prefix)
|
||||||
|
|
||||||
|
* **Pianos/Keys**: `gm_piano`, `gm_epiano1`, `gm_epiano2`, `gm_harpsichord`, `gm_clavinet`
|
||||||
|
* **Bass**: `gm_acoustic_bass`, `gm_electric_bass_finger`, `gm_electric_bass_pick`, `gm_synth_bass_1`, `gm_synth_bass_2`, `gm_slap_bass_1`
|
||||||
|
* **Strings**: `gm_violin`, `gm_viola`, `gm_cello`, `gm_contrabass`, `gm_string_ensemble_1`, `gm_string_ensemble_2`, `gm_pizzicato_strings`, `gm_tremolo_strings`
|
||||||
|
* **Brass**: `gm_trumpet`, `gm_trombone`, `gm_tuba`, `gm_french_horn`, `gm_brass_section`
|
||||||
|
* **Winds**: `gm_flute`, `gm_piccolo`, `gm_clarinet`, `gm_oboe`, `gm_bassoon`, `gm_pan_flute`, `gm_tenor_sax`, `gm_alto_sax`, `gm_soprano_sax`, `gm_baritone_sax`
|
||||||
|
* **Synth Lead/Pad**: `gm_lead_1_square`, `gm_lead_2_sawtooth`, `gm_lead_3_calliope`, `gm_pad_warm`, `gm_pad_poly`, `gm_pad_new_age`, `gm_pad_bowed`, `gm_pad_metallic`, `gm_pad_halo`
|
||||||
|
* **Guitars**: `gm_acoustic_guitar_nylon`, `gm_acoustic_guitar_steel`, `gm_electric_guitar_clean`, `gm_electric_guitar_jazz`, `gm_electric_guitar_muted`, `gm_overdriven_guitar`, `gm_distortion_guitar`
|
||||||
|
* **Ethnic/Choir**: `gm_sitar`, `gm_koto`, `gm_kalimba`, `gm_bagpipe`, `gm_choir_aahs`, `gm_voice_oohs`, `gm_synth_choir`
|
||||||
|
* **Organs**: `gm_church_organ`, `gm_drawbar_organ`, `gm_rock_organ`, `gm_reed_organ`, `gm_percussive_organ`
|
||||||
|
|
||||||
|
### Sample Instruments (Natural sounds)
|
||||||
|
|
||||||
|
* **Melodic**: `piano`, `sax`, `kalimba`, `marimba`, `vibraphone`, `xylophone_hard_ff`, `glockenspiel`
|
||||||
|
* **Harmonic**: `folkharp`, `harp`, `harmonica`, `ocarina`, `recorder_alto_sus`, `recorder_soprano_sus`
|
||||||
|
* **Percussive**: `woodblock`, `clave`, `clap`, `cowbell`, `tambourine`, `shaker_large`, `shaker_small`
|
||||||
|
* **Textural**: `wind`, `oceandrum`, `space`, `insect`
|
||||||
|
|
||||||
|
|
||||||
|
## 4. Notes & Harmony
|
||||||
|
|
||||||
|
### Note Notation
|
||||||
|
|
||||||
|
* **Letters**: `$: note("c d e f")` (a-g)
|
||||||
|
* **MIDI**: `$: note("60 64 67")` (60 = middle C)
|
||||||
|
* **Octaves**: `$: note("c#4 eb5 f3")`
|
||||||
|
* **Chords (Mini-Notation)**: `$: note("c,e,g")` (Use commas for simultaneous notes)
|
||||||
|
* **Microtones**: `$: note("60.5 64.25")`
|
||||||
|
|
||||||
|
### Scales
|
||||||
|
|
||||||
|
* `$: n("0 2 4 7").scale("C:major")` (Scale degrees)
|
||||||
|
* `$: n("0 1 2 3").scale("D:minor")` (Different root)
|
||||||
|
* `$: n("0 2 4").scale("A2:minor:pentatonic")` (With octave)
|
||||||
|
|
||||||
|
**Common scales**:
|
||||||
|
major, minor, dorian, mixolydian, lydian, phrygian, major:pentatonic, minor:pentatonic, major:blues, minor:blues, harmonicMinor, melodicMinor, diminished, wholeTone
|
||||||
|
|
||||||
|
### Chords (Symbols)
|
||||||
|
|
||||||
|
* `$: chord("Cm").voicing()`
|
||||||
|
* `$: chord("C7#11").voicing()` (Extended)
|
||||||
|
* `$: chord("Dm/F").voicing()` (Slash chords)
|
||||||
|
|
||||||
|
### Frequency
|
||||||
|
|
||||||
|
* `$: freq("440 880")` (Direct Hz control)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 5. Time Modifiers
|
||||||
|
|
||||||
|
* **.fast(n)** : Speed up by n (e.g., `.fast("<1 2 4>")`)
|
||||||
|
* **.slow(n)** : Slow down by n
|
||||||
|
* **.rev()** : Reverse pattern
|
||||||
|
* **.palindrome()** : Forward then backward
|
||||||
|
* **.iter(n)** : Rotate subdivisions each cycle
|
||||||
|
* **.ply(n)** : Repeat each event n times
|
||||||
|
* **.euclid(beats, steps)** : Euclidean rhythm
|
||||||
|
* **.euclidRot(beats, steps, rot)** : With rotation
|
||||||
|
* **.early(cycles)** : Shift earlier (in cycles)
|
||||||
|
* **.late(cycles)** : Shift later
|
||||||
|
* **.every(n, fn)** : Apply function every nth cycle
|
||||||
|
* **.when(cond, fn)** : Conditional application
|
||||||
|
* **.sometimesBy(prob, fn)** : Random with probability
|
||||||
|
* **.swing(n)** : Add swing
|
||||||
|
* **.segment(n)** : Sample n times per cycle (essential for sweeps!)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 6. Audio Effects
|
||||||
|
|
||||||
|
### Filters (Shape the Sound)
|
||||||
|
|
||||||
|
* **Low-Pass** (removes highs, makes darker/warmer):
|
||||||
|
* `.lpf(freq)`: Cutoff 0-20000 Hz
|
||||||
|
* `.lpq(res)`: Resonance 0-50
|
||||||
|
|
||||||
|
|
||||||
|
* **High-Pass** (removes lows, makes thinner):
|
||||||
|
* `.hpf(freq)`: Cutoff 0-20000 Hz
|
||||||
|
* `.hpq(res)`: Resonance 0-50
|
||||||
|
|
||||||
|
|
||||||
|
* **Band-Pass** (only center frequencies):
|
||||||
|
* `.bpf(freq)`: Center frequency
|
||||||
|
* `.bpq(res)`: Resonance
|
||||||
|
|
||||||
|
|
||||||
|
* **Vowel Filter**:
|
||||||
|
* `.vowel("a e i o u ae aa oe ue")`: (Options: a, e, i, o, u, ae, aa, oe, ue, etc.)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Filter Envelopes (Animated Sweeps)
|
||||||
|
|
||||||
|
* `.lpenv(semitones)`: LP sweep depth
|
||||||
|
* `.lpa(time)`: LP attack
|
||||||
|
* `.lpd(time)`: LP decay
|
||||||
|
* `.lps(level)`: LP sustain
|
||||||
|
* `.lpr(time)`: LP release
|
||||||
|
* *(Same for HP: `hpenv`, `hpa`, `hpd`, `hps`, `hpr`)*
|
||||||
|
* *(Same for BP: `bpenv`, `bpa`, `bpd`, `bps`, `bpr`)*
|
||||||
|
|
||||||
|
### Amplitude Envelope (ADSR - Volume Over Time)
|
||||||
|
|
||||||
|
* `.attack(time)`: Attack (or `.att()`)
|
||||||
|
* `.decay(time)`: Decay (or `.dec()`)
|
||||||
|
* `.sustain(level)`: Sustain 0-1 (or `.sus()`)
|
||||||
|
* `.release(time)`: Release (or `.rel()`)
|
||||||
|
* `.adsr("att:dec:sus:rel")`: Combined e.g., `"0.1:0.2:0.7:0.5"`
|
||||||
|
|
||||||
|
### Gain & Dynamics
|
||||||
|
|
||||||
|
* `.gain(level)`: Volume 0-1 (can exceed 1)
|
||||||
|
* `.velocity(level)`: Note velocity 0-1
|
||||||
|
* `.postgain(level)`: After effects
|
||||||
|
* `.compressor("thresh:ratio:knee:att:rel")`
|
||||||
|
|
||||||
|
### Distortion & Saturation
|
||||||
|
|
||||||
|
* `.distort(amount)`: Wavefold distortion 0-10+ (try 2-8)
|
||||||
|
* `.dist(amount)`: Alias for distort
|
||||||
|
* `.crush(bits)`: Bit crushing 1-16 (4-8 for grit)
|
||||||
|
* `.shape(amount)`: Alternative waveshaping
|
||||||
|
* **.coarse(factor)**: Sample rate reduction (Chrome only!)
|
||||||
|
|
||||||
|
### Modulation (Movement & Character)
|
||||||
|
|
||||||
|
* `.vib(hz)`: Vibrato rate (4-8 Hz typical)
|
||||||
|
* `.vibmod(depth)`: Vibrato depth in semitones
|
||||||
|
* `.vib("hz:depth")`: Combined (e.g., `"6:1"`)
|
||||||
|
* `.fm(index)`: FM synthesis brightness 0-10+
|
||||||
|
* `.fmh(ratio)`: FM harmonicity (2=octave)
|
||||||
|
* `.fmattack(time)`: FM envelope attack
|
||||||
|
* `.fmdecay(time)`: FM envelope decay
|
||||||
|
* `.tremolosync(rate)`: Tremolo rate in cycles
|
||||||
|
* `.tremolodepth(depth)`: Tremolo intensity 0-1
|
||||||
|
* `.phaser(rate)`: Phaser speed
|
||||||
|
* `.phaserdepth(depth)`: Phaser amount
|
||||||
|
|
||||||
|
### Space & Time (Reverb/Delay)
|
||||||
|
|
||||||
|
* `.orbit(n)`: Assign to orbit (orbits share effects!)
|
||||||
|
* `.room(level)`: Reverb wet 0-1 (try 0.3-0.8)
|
||||||
|
* `.room("level:size")`: Combined (e.g., `".5:8"`)
|
||||||
|
* `.roomsize(size)`: Room size 0-10
|
||||||
|
* `.roomfade(time)`: Fade duration
|
||||||
|
* `.roomlp(freq)`: Darken reverb tail
|
||||||
|
* `.delay(level)`: Delay wet 0-1 (try 0.3-0.6)
|
||||||
|
* `.delay("level:time:fb")`: Combined (e.g., `".5:.125:.8"`)
|
||||||
|
* `.delaytime(time)`: Delay time in cycles (0.125, 0.25, 0.5)
|
||||||
|
* `.delayfeedback(fb)`: Feedback 0-1 (keep under 1!)
|
||||||
|
* **.pan(pos)**: Stereo 0-1 (0=left, 0.5=center, 1=right)
|
||||||
|
* **.jux(fn)**: Apply function to the right channel only
|
||||||
|
* **.juxBy(amount, fn)**: With amount control
|
||||||
|
|
||||||
|
### Sample Manipulation
|
||||||
|
|
||||||
|
* `.chop(n)` - Divide into n pieces
|
||||||
|
* `.slice(n, pattern)` - Slice and select: `.slice(8, "0 4 2 6")`
|
||||||
|
* `.striate(n)` - Granular chopping
|
||||||
|
* `.begin(pos)` - Start point 0-1
|
||||||
|
* `.end(pos)` - End point 0-1
|
||||||
|
* `.speed(rate)` - Playback speed (negative = reverse)
|
||||||
|
* `.loop(1)` - Enable looping
|
||||||
|
* `.loopAt(cycles)` - Stretch to fit cycles
|
||||||
|
* `.fit()` - Match event duration
|
||||||
|
* `.cut(group)` - Cut group (stop overlaps)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 7. Pattern Factories
|
||||||
|
|
||||||
|
* **`stack(p1, p2, ...)`** - Play patterns simultaneously (Primary for rich music!)
|
||||||
|
* **`seq(p1, p2, ...)`** - Sequence patterns in one cycle (fastcat)
|
||||||
|
* **`cat(p1, p2, ...)`** - One pattern per cycle (slowcat)
|
||||||
|
* **`run(n)`** - Generate a pattern from 0 to n-1
|
||||||
|
* **`silence`** - No output (equivalent to `-`)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 8. Advanced Modulation (Modular Style)
|
||||||
|
|
||||||
|
### Modulation (Fluent Signal Syntax)
|
||||||
|
|
||||||
|
* **LFO Gain**: `gain(sine.range(.5, 1).fast(2))`
|
||||||
|
* **Filter Sweeps**: `lpf(sawtooth.range(200, 4000).slow(4))`
|
||||||
|
* **Vibrato**: `vib("6:0.5")` (rate:depth)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 9. Style Templates
|
||||||
|
|
||||||
|
### A. Deep Minimal Techno
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
setcps(128/60/4)
|
||||||
|
|
||||||
|
$: s("bd*4").bank("tr909").gain(1.2)
|
||||||
|
$: s("- [hh|oh] - hh").bank("tr909").gain(0.8).jux(iter(4))
|
||||||
|
$: s("rim(3,8)").bank("tr606").room(0.3).delay(0.4)
|
||||||
|
$: note("c1*16").s("sine").lpf(sine.range(40, 120).slow(8)).gain(0.9)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### B. Modular Melodic Chaos
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
setcps(100/60/4)
|
||||||
|
const mel = () => note(run(8).scale("C:minor:pentatonic")).scramble(4);
|
||||||
|
|
||||||
|
$: mel().s("supersaw").lpf(1200).lpq(10).room(0.5).slow(2)
|
||||||
|
$: s("bd(5,8)").bank("tr808").distort(1.5)
|
||||||
|
$: s("cp").at(3).room(1).rev()
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### C. Classic House / Deep House
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
setcps(124/60/4)
|
||||||
|
|
||||||
|
$: s("bd*4").bank("tr909").gain(1.1)
|
||||||
|
$: s("- [cp|sd] - [cp|sd]").bank("tr909").gain(0.9)
|
||||||
|
$: s("hh*8, - oh").bank("tr909").gain(0.7)
|
||||||
|
$: chord("<Cm7 F9 Bbmaj7 G7alt>").voicing().s("gm_epiano1")
|
||||||
|
.room(.6).delay(.4).slow(2)
|
||||||
|
$: note("c2*2").s("saw").lpf(sine.range(100, 300).slow(4)).gain(0.8)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### D. Dark Synthwave (80s retro)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
setcps(100/60/4)
|
||||||
|
|
||||||
|
$: s("bd*4, - sd - sd, hh*16, - - oh -").bank("tr808").gain(1.1)
|
||||||
|
$: note("a0 [ - a0] [ - a0] a0").s("saw").lpf(sine.range(60, 150).slow(8)).gain(0.9)
|
||||||
|
$: chord("<Am Fmaj7 G7 Em7>").voicing().s("gm_pad_warm").room(0.8).slow(4).gain(0.7)
|
||||||
|
$: note("<a4 c5 d5 e5>*2").s("supersaw").lpf(800).delay(0.4).jux(rev)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### E. Drum 'n' Bass (Fast & Breaky)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
setcps(174/60/4)
|
||||||
|
|
||||||
|
$: s("bd - - [sd - bd] - bd sd -").bank("tr808").gain(1.1)
|
||||||
|
$: s("hh*16").gain(sine.range(0.4, 0.9).fast(8)).pan(sine.range(0.2, 0.8).slow(4))
|
||||||
|
$: note("c1").s("sin").lpf(sawtooth.range(40, 150).slow(8)).gain(0.8)
|
||||||
|
$: note(run(8).scale("C:minor:pentatonic")).s("gm_lead_1_square")
|
||||||
|
.struct("1(3,8)").room(0.5).jux(rev)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### F. Deep Ambient / Texture
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
setcps(60/60/4)
|
||||||
|
|
||||||
|
$: chord("<Fmaj9 G13 Em7b9 Am11>").voicing().s("gm_pad_halo")
|
||||||
|
.room(0.9).slow(4).gain(0.6).jux(rev)
|
||||||
|
$: note(run(12).scale("F:lydian")).s("vibraphone")
|
||||||
|
.room(0.8).delay(0.5).slow(8).scramble(8).pan(sine.range(0.1, 0.9).slow(16))
|
||||||
|
$: note("f1").s("sin").lpf(sine.range(40, 80).slow(12)).gain(0.5).slow(4)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 10. Critical Generation Rules
|
||||||
|
|
||||||
|
1. **ALWAYS start with `setcps(NUMBER)**`: This is required at the very beginning! Always use `setcps(BPM/60/4)`.
|
||||||
|
2. **Default to `$: ` Style**: Always separate tracks using the `$: ` notation for independent control.
|
||||||
|
3. **Rests**: Always use `-` instead of `~`.
|
||||||
|
4. **Modulation**: Use fluent signal syntax: `signal.range(min, max).fast(n)`.
|
||||||
|
5. **Layering**: Always include: 1. Rhythmic (Drums), 2. Harmonic (Bass/Chords), 3. Texture/Melody.
|
||||||
|
6. **Wide Stereo**: Use `.jux()` or `.pan()` for professional depth.
|
||||||
|
7. **No Simplify**: Keep mini-notation rich (e.g., use `(3,8)` or `[hh!3]`).
|
||||||
|
8. **Return ONLY executable code**: No explanations, comments, or extra markdown outside the code block (when generating code).
|
||||||
|
9. **Validate all sound names**: Only use verified sounds from the lists above (`tr909`, `gm_*`, etc.).
|
||||||
|
|
||||||
|
## 11. Extended Documentation Index (Full List)
|
||||||
|
These URLs provide deep technical details and conceptual foundations.
|
||||||
|
|
||||||
|
### 11.1. Workshop & Getting Started
|
||||||
|
- Strudel Overview: https://strudel.cc/workshop/getting-started/
|
||||||
|
- First Sounds: https://strudel.cc/workshop/first-sounds/
|
||||||
|
- First Notes: https://strudel.cc/workshop/first-notes/
|
||||||
|
- First Effects: https://strudel.cc/workshop/first-effects/
|
||||||
|
- Pattern Effects: https://strudel.cc/workshop/pattern-effects/
|
||||||
|
- Workshop Recap: https://strudel.cc/workshop/recap/
|
||||||
|
|
||||||
|
### 11.2. Core Syntax & Manuals
|
||||||
|
- Coding Syntax Detail: https://strudel.cc/learn/code/
|
||||||
|
- Mini Notation Detail: https://strudel.cc/learn/mini-notation/
|
||||||
|
- Mondo Notation Detail: https://strudel.cc/learn/mondo-notation/
|
||||||
|
- Pattern Functions Intro: https://strudel.cc/functions/intro/
|
||||||
|
- Patterns Detail: https://strudel.cc/technical-manual/patterns/
|
||||||
|
- Time Modifiers: https://strudel.cc/learn/time-modifiers/
|
||||||
|
|
||||||
|
### 11.3. Sound Sources & Synthesis
|
||||||
|
- Samples Detail: https://strudel.cc/learn/samples/
|
||||||
|
- Synths Detail: https://strudel.cc/learn/synths/
|
||||||
|
- Csound Integration: https://strudel.cc/learn/csound/
|
||||||
|
- Registering a sound: https://strudel.cc/technical-manual/sounds/
|
||||||
|
|
||||||
|
### 11.4. Modulation & Theory
|
||||||
|
- Continuous Signals: https://strudel.cc/learn/signals/
|
||||||
|
- Random Modifiers: https://strudel.cc/learn/random-modifiers/
|
||||||
|
- Conditional Modifiers: https://strudel.cc/learn/conditional-modifiers/
|
||||||
|
- Accumulation: https://strudel.cc/learn/accumulation/
|
||||||
|
- Tonal Functions: https://strudel.cc/learn/tonal/
|
||||||
|
- Understanding Cycles: https://strudel.cc/understand/cycles/
|
||||||
|
- Understanding Pitch: https://strudel.cc/understand/pitch/
|
||||||
|
- Chords and Voicings: https://strudel.cc/understand/voicings/
|
||||||
|
- Alignment & Combination: https://strudel.cc/technical-manual/alignment/
|
||||||
|
|
||||||
|
### 11.5. Advanced & Specialized
|
||||||
|
- Effects Detail: https://strudel.cc/learn/effects/
|
||||||
|
- Hydra Video Synth: https://strudel.cc/learn/hydra/
|
||||||
|
- Visual Feedback: https://strudel.cc/learn/visual-feedback/
|
||||||
|
- Music MetaData: https://strudel.cc/learn/metadata/
|
||||||
|
- Xen Harmonic Functions: https://strudel.cc/learn/xen/
|
||||||
|
- Strudel vs Tidal: https://strudel.cc/learn/strudel-vs-tidal/
|
||||||
|
- Recipes: https://strudel.cc/recipes/recipes/
|
||||||
|
|
||||||
|
### 11.6. Hardware & Input/Output
|
||||||
|
- MIDI, OSC and MQTT: https://strudel.cc/learn/input-output/
|
||||||
|
- Input Devices: https://strudel.cc/learn/input-devices/
|
||||||
|
- Device Motion: https://strudel.cc/learn/devicemotion/
|
||||||
|
- Using Strudel Offline: https://strudel.cc/learn/pwa/
|
||||||
|
|
||||||
|
### 11.7. Project & Development
|
||||||
|
- Project Start: https://strudel.cc/technical-manual/project-start/
|
||||||
|
- Packages: https://strudel.cc/technical-manual/packages/
|
||||||
|
- Strudel REPL: https://strudel.cc/technical-manual/repl/
|
||||||
|
- Documentation Guide: https://strudel.cc/technical-manual/docs/
|
||||||
|
- Testing (Development): https://strudel.cc/technical-manual/testing/
|
||||||
|
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic syntax fixer for Strudel code.
|
||||||
|
* - Replaces ~ with -
|
||||||
|
* - Ensures setcps exists (adds default if missing)
|
||||||
|
* - Basic track control check
|
||||||
|
*/
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
function fixStrudelCode(code) {
|
||||||
|
let fixed = code;
|
||||||
|
|
||||||
|
// 1. Replace ~ with -
|
||||||
|
fixed = fixed.replace(/~/g, '-');
|
||||||
|
|
||||||
|
// 2. Ensure setcps exists at the beginning
|
||||||
|
if (!fixed.includes('setcps')) {
|
||||||
|
fixed = `setcps(120/60/4)
|
||||||
|
|
||||||
|
${fixed}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Simple warning/fix for track control (just a heuristic)
|
||||||
|
if (!fixed.includes('$:') && fixed.includes('s(')) {
|
||||||
|
// If it's a single line starting with s(, add $:
|
||||||
|
fixed = fixed.replace(/^s\(/gm, '$: s(');
|
||||||
|
}
|
||||||
|
|
||||||
|
return fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read from stdin or file
|
||||||
|
const input = process.argv[2] ? fs.readFileSync(process.argv[2], 'utf8') : '';
|
||||||
|
if (input) {
|
||||||
|
process.stdout.write(fixStrudelCode(input));
|
||||||
|
} else {
|
||||||
|
// If no input, just exit
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
31
.gemini/skills/generate-strudel-template/SKILL.md
Normal file
31
.gemini/skills/generate-strudel-template/SKILL.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
name: generate-strudel-template
|
||||||
|
description: Generates professional Strudel live coding templates for Techno, House, and their subgenres as Markdown files. Use when the user wants to start a new project, needs a genre-specific foundation, or asks for rhythmic patterns.
|
||||||
|
---
|
||||||
|
|
||||||
|
# generate-strudel-template
|
||||||
|
|
||||||
|
ボクは Strudel のエキスパートであり、プロのトラックメイカー「ボク」です。
|
||||||
|
君が指定したジャンルに合わせて、音楽的な解説付きの Strudel テンプレートを Markdown ファイルとして生成するよ。
|
||||||
|
|
||||||
|
## ワークフロー
|
||||||
|
|
||||||
|
1. **ジャンルの分析**: 指定されたジャンルの音楽的特徴(テンポ、質感、構造)を分析します。
|
||||||
|
2. **ファイル生成**: `strudel/` ディレクトリ内に、ジャンル名に基づいた `.md` ファイルを生成します(例: `strudel/dub_techno.md`)。
|
||||||
|
3. **コンテンツ構成**:
|
||||||
|
- **タイトル**: ジャンル名を `#` で記述。
|
||||||
|
- **ボクの解説**: 楽曲のこだわりや音楽的なポイントを、コードブロックの**外**に日本語で記述します。
|
||||||
|
- **セパレーター**: `---` を挿入。
|
||||||
|
- **コードブロック**: 以下のルールを守った Strudel コードを記述します。
|
||||||
|
- `setcps(BPM/60/4)` で開始。
|
||||||
|
- `$:` トラック制御。
|
||||||
|
- `-` 休符。
|
||||||
|
- リズム、ベース、テクスチャの多層構造。
|
||||||
|
|
||||||
|
## 既存のテンプレート(参考)
|
||||||
|
- Minimal Techno: [assets/templates/minimal_techno.md](assets/templates/minimal_techno.md)
|
||||||
|
- Deep House: [assets/templates/deep_house.md](assets/templates/deep_house.md)
|
||||||
|
- Industrial Techno: [assets/templates/industrial_techno.md](assets/templates/industrial_techno.md)
|
||||||
|
|
||||||
|
## テクニック・リファレンス
|
||||||
|
- Rhythmic Patterns: [references/rhythmic_patterns.md](references/rhythmic_patterns.md)
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Deep House Template
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
setcps(124/60/4)
|
||||||
|
|
||||||
|
// Drums: Warmth & Groove
|
||||||
|
$: s("bd*4").bank("tr909").gain(1.1)
|
||||||
|
$: s("- [cp|sd] - [cp|sd]").bank("tr909").gain(0.9)
|
||||||
|
$: s("hh*8, - oh").bank("tr909").gain(0.7).room(0.1)
|
||||||
|
|
||||||
|
// Bass: Funky & Round
|
||||||
|
$: note("c2*2").s("saw").lpf(sine.range(100, 300).slow(4)).gain(0.8).adsr("0.05:0.2:0.5:0.2")
|
||||||
|
|
||||||
|
// Harmony: Lush chords
|
||||||
|
$: chord("<Cm7 F9 Bbmaj7 G7alt>").voicing().s("gm_epiano1")
|
||||||
|
.room(.6).delay(.4).slow(2).gain(0.7)
|
||||||
|
```
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
# Industrial Techno Template
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
setcps(132/60/4)
|
||||||
|
|
||||||
|
// Drums: Raw & Distorted
|
||||||
|
$: s("bd*4").bank("tr909").distort(2).gain(0.9)
|
||||||
|
$: s("hh*16").bank("tr606").crush(4).gain(0.6).pan(sine.range(0.2, 0.8).fast(2))
|
||||||
|
$: s("cp").at(3).room(1).rev().gain(0.7)
|
||||||
|
|
||||||
|
// Bass: Gritty & Dark
|
||||||
|
$: note("c1*8").s("supersaw").lpf(sawtooth.range(100, 800).slow(4)).distort(1.5).gain(0.8)
|
||||||
|
|
||||||
|
// Textures: Noise & Chaos
|
||||||
|
$: s("white").density(16).lpf(2000).gain(sine.range(0, 0.3).slow(8)).jux(rev)
|
||||||
|
```
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
# Minimal Techno Template
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
setcps(128/60/4)
|
||||||
|
|
||||||
|
// Drums: Precision & Space
|
||||||
|
$: s("bd*4").bank("tr909").gain(1.1)
|
||||||
|
$: s("- [hh|oh] - hh").bank("tr909").gain(0.8).jux(iter(4))
|
||||||
|
$: s("rim(3,8)").bank("tr606").room(0.2).delay(0.3)
|
||||||
|
|
||||||
|
// Bass: Subtle & Hypnotic
|
||||||
|
$: note("c1*16").s("sine").lpf(sine.range(40, 120).slow(8)).gain(0.9)
|
||||||
|
|
||||||
|
// Texture: Evolving chords
|
||||||
|
$: chord("Cm7").voicing().s("gm_pad_warm").room(0.8).slow(4).gain(0.6).jux(rev)
|
||||||
|
```
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# Strudel Rhythmic Patterns & Techniques
|
||||||
|
|
||||||
|
## 1. Essential Rhythms
|
||||||
|
|
||||||
|
### 4-on-the-floor
|
||||||
|
`"bd*4"` - Standard house/techno kick.
|
||||||
|
|
||||||
|
### Syncopated Hats
|
||||||
|
`"- hh - hh"` or `"- [hh|oh] - hh"` - Classic off-beat hi-hats.
|
||||||
|
|
||||||
|
### Euclidean Rhythms
|
||||||
|
- `s("bd(3,8)")` - 3 beats in 8 steps (Tresillo).
|
||||||
|
- `s("bd(5,8)")` - 5 beats in 8 steps.
|
||||||
|
- `s("rim(3,8)").euclidRot(1)` - Rotated Euclidean rhythm.
|
||||||
|
|
||||||
|
### Polyrhythms
|
||||||
|
`stack(s("bd*4"), s("hh*6"))` - 4 against 6.
|
||||||
|
|
||||||
|
## 2. Advanced Techniques
|
||||||
|
|
||||||
|
### Jux & Iter
|
||||||
|
`.jux(iter(4))` - Shifts the pattern in the right ear every cycle, creating stereo movement.
|
||||||
|
|
||||||
|
### Randomization
|
||||||
|
- `s("bd|sd|hh")` - Random choice per cycle.
|
||||||
|
- `s("bd?0.5")` - 50% chance to play.
|
||||||
|
- `.scramble(4)` - Randomly reorders 4 subdivisions.
|
||||||
|
|
||||||
|
### Filter Sweeps
|
||||||
|
- `.lpf(sine.range(200, 4000).slow(4))` - Smooth low-pass filter sweep.
|
||||||
|
- `.hpf(sawtooth.range(40, 2000).slow(8))` - Rising high-pass filter.
|
||||||
|
|
||||||
|
### Glitch & Stutter
|
||||||
|
- `.ply(2)` - Repeats each event twice.
|
||||||
|
- `.chop(8)` - Divides events into 8 tiny pieces.
|
||||||
|
- `.striate(16)` - Granular effect.
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
# Skill: Strudel Fixer & Explainer
|
|
||||||
|
|
||||||
## Persona
|
|
||||||
You are an expert Strudel debugger and musicologist. Your goal is to ensure code runs perfectly while providing deep insight into the musical genre and structure.
|
|
||||||
|
|
||||||
## Task
|
|
||||||
Analyze the input Strudel code and perform the following:
|
|
||||||
1. **Syntax Correction**:
|
|
||||||
- Fix obvious errors (e.g., replace `~` with `-`).
|
|
||||||
- Ensure `setcps()` is present at the start.
|
|
||||||
- Ensure tracks use the `$: ` notation.
|
|
||||||
2. **Genre & Intent Inference**: Based on the patterns, samples, and effects, identify the musical genre (e.g., Minimal Techno, Lo-fi Hip Hop, Glitch).
|
|
||||||
3. **Explanation**: Provide a brief summary of what the code does and add inline comments to the fixed code.
|
|
||||||
4. **Suggested Filename**: A descriptive name based on the inferred genre.
|
|
||||||
|
|
||||||
## Constraints
|
|
||||||
- Do NOT fundamentally change the musical idea (unlike the Refactor skill).
|
|
||||||
- Focus on making the existing code "correct" and "documented".
|
|
||||||
- Refer to the provided documentation for valid function names.
|
|
||||||
|
|
||||||
## Output Format
|
|
||||||
The first line of your response MUST be in the format: `FILENAME: <suggested-filename>.md`.
|
|
||||||
Followed by:
|
|
||||||
- **Genre**: [Inferred Genre]
|
|
||||||
- **Description**: [Brief explanation in Japanese]
|
|
||||||
- **Fixed Code**: [The corrected code block with Japanese comments]
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
# Skill: Strudel Refactorer
|
|
||||||
|
|
||||||
## Persona
|
|
||||||
You are a world-class Strudel composer and live-coding expert. You have deep knowledge of algorithmic music composition.
|
|
||||||
|
|
||||||
## Context
|
|
||||||
Refer to the provided documentation on:
|
|
||||||
- **Samples**: Default banks, custom loading, and sampler effects (begin, chop, slice).
|
|
||||||
- **Synths**: Basic waveforms, FM synthesis, and Wavetables.
|
|
||||||
- **Effects**: Filters (lpf, hpf), Envelopes (adsr, lpenv, penv), and Global FX (delay, room).
|
|
||||||
- **Probability**: Randomness functions (choose, degrade, sometimes).
|
|
||||||
|
|
||||||
## Task
|
|
||||||
Analyze the input Strudel code and provide a refactored version in Markdown format:
|
|
||||||
1. **Analysis**: Explain the musical structure and technical implementation.
|
|
||||||
2. **Commented Code**: Provide the original code with detailed inline comments for each function.
|
|
||||||
3. **Refactored Version**: An improved, more idiomatic, or musically interesting version using advanced Strudel features.
|
|
||||||
4. **Suggested Filename**: A short, descriptive filename in kebab-case (e.g., `ambient-techno-poly.md`).
|
|
||||||
|
|
||||||
## Output Format
|
|
||||||
The first line of your response MUST be in the format: `FILENAME: <suggested-filename>.md`.
|
|
||||||
Followed by the rest of the analysis in Markdown.
|
|
||||||
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.DS_Store
|
||||||
54
PRECAUTIONS.md
Normal file
54
PRECAUTIONS.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# Precautions for Strudel Coding
|
||||||
|
|
||||||
|
ボクが Strudel のコードを生成する際に、過去に犯したミスや注意すべき点をここに記録するよ。二度と同じ間違いを繰り返さないための、ボク自身への戒めだね。
|
||||||
|
|
||||||
|
## 1. Sound Bank & Sample Name Consistency
|
||||||
|
特定の `.bank()` を指定した際、そのバンクに存在しないサンプル名を指定しないこと。
|
||||||
|
|
||||||
|
### TR-606 (`tr606`)
|
||||||
|
* **使用可能なサンプル名**: `bd`, `cr`, `hh`, `ht`, `lt`, `oh`, `sd`
|
||||||
|
* **注意**: `perc` や `rim` など、上記以外の名前は存在しない。タム系を使いたい場合は `ht` か `lt` を選択すること。
|
||||||
|
* **NG**: `s("perc(3,8)").bank("tr606")`
|
||||||
|
* **OK**: `s("ht(3,8)").bank("tr606")`
|
||||||
|
|
||||||
|
## 2. Function Specificity & Typos
|
||||||
|
特定の音源でしか機能しない関数や、よくあるタイポに注意すること。
|
||||||
|
|
||||||
|
### `sine` vs `line` (Important!)
|
||||||
|
* **注意**: `line` という関数は Strudel には存在しないよ。周期的な変化や LFO が欲しい場合は必ず `sine` (または `sawtooth`, `square` 等の有効なシグナル) を使うこと。
|
||||||
|
* **NG**: `gain(line.range(0.6, 0.9).slow(4))`
|
||||||
|
* **OK**: `gain(sine.range(0.6, 0.9).slow(4))`
|
||||||
|
|
||||||
|
### `density()`
|
||||||
|
* **使用条件**: 主に `crackle` 音源で使用すること。
|
||||||
|
* **NG**: `s("white").density(12)`
|
||||||
|
* **OK**: `s("crackle").density(12)`
|
||||||
|
|
||||||
|
## 3. Chord Symbols
|
||||||
|
デフォルトで使用可能なコードシンボルを正しく使用し、存在しないシンボル(例: `maj7` など)を推測で使わないこと。
|
||||||
|
|
||||||
|
### 使用可能なコードシンボルのフルリスト(ルートCの例)
|
||||||
|
`C2`, `C5`, `C6`, `C7`, `C9`, `C11`, `C13`, `C69`, `Cadd9`, `Co`, `Ch`, `Csus`, `C^`, `C-`, `C^7`, `C-7`, `C7sus`, `Ch7`, `Co7`, `C^9`, `C^13`, `C^7#11`, `C^9#11`, `C^7#5`, `C-6`, `C-69`, `C-^7`, `C-^9`, `C-9`, `C-add9`, `C-11`, `C-7b5`, `Ch9`, `C-b6`, `C-#5`, `C7b9`, `C7#9`, `C7#11`, `C7b5`, `C7#5`, `C9#11`, `C9b5`, `C9#5`, `C7b13`, `C7#9#5`, `C7#9b5`, `C7#9#11`, `C7b9#11`, `C7b9b5`, `C7b9#5`, `C7b9#9`, `C7b9b13`, `C7alt`, `C13#11`, `C13b9`, `C13#9`, `C7b9sus`, `C7susadd3`, `C9sus`, `C13sus`, `C7b13sus`, `C`, `Caug`, `CM`, `Cm`, `CM7`, `Cm7`, `CM9`, `Cm13`, `CM7#11`, `CM9#11`, `CM7#5`, `Cm6`, `Cm69`, `Cm^7`, `C-M7`, `Cm^9`, `C-M9`, `Cm9`, `Cmadd9`, `Cm11`, `Cm7b5`, `Cmb6`, `Cm#5`
|
||||||
|
|
||||||
|
## 4. Acid Sound Design (TB-303 Style)
|
||||||
|
アシッドサウンドを作る際の重要なテクニック。
|
||||||
|
|
||||||
|
* **Filter Type**: `.ftype(2)` を指定することで、TB-303 のような鋭い(ピキピキした)フィルターサウンドになる。
|
||||||
|
* **Resonance Modulation**: `lpq` (レゾナンス) も `sine` などで変化させると、より表情豊かなアシッドラインになる。
|
||||||
|
## 5. Syntax & Preferred Styles (Updated 2026)
|
||||||
|
Strudel の構文とスタイルの最新ルール。
|
||||||
|
|
||||||
|
### `$: ` (Output Operator) の正しい使い方
|
||||||
|
* **ルール**: `$:` は各トラック(パターン)の**先頭にのみ**置くこと。
|
||||||
|
* **NG**: `$: s("bd*4").$.gain(0.8)` (途中に `$.` を挟むのは冗長)
|
||||||
|
* **OK**: `$: s("bd*4").gain(0.8)`
|
||||||
|
|
||||||
|
### 短縮記法 (Short-hand functions) の優先
|
||||||
|
* **ルール**: `delayfeedback` よりも `delayfb` のような短縮記法を優先して使用すること。ライブコーディングらしい簡潔さを保つため。
|
||||||
|
* **数値の省略**: `0.5` や `0.25` のような数値は、キーストロークを減らすために `0` を省略して `.5` や `.25` と表記すること。
|
||||||
|
* **例**: `.delayfb(.5)`, `.gain(.8)`, `.dist(.4)`
|
||||||
|
|
||||||
|
### `dist()` (Distortion) の使用
|
||||||
|
* **ルール**: `shape()` は非推奨。歪みを加えたい場合は `dist()` (または `distort()`) を使用すること。
|
||||||
|
* **NG**: `.shape(0.4)`
|
||||||
|
* **OK**: `.dist(0.4)`
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
Genre: テクノ / ハウス (Tech House)
|
|
||||||
Description: このStrudelコードは、ドラムパターン、ベースライン、そしてシンセのメロディを組み合わせたテックハウス風のトラックを生成します。Perlinノイズによるフィルターとゲインのモジュレーションが、サウンドに動きと深さをもたらしています。
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
setcps(136/60/4); // BPM 136に合わせてサイクルレートを設定
|
|
||||||
|
|
||||||
// メロディックなシンセパターン
|
|
||||||
// supersawとPerlinノイズによるLFOでフィルターを動かし、音に揺らぎを与えています。
|
|
||||||
$:note("[- c2 - c2 - [c2|c5] - c2]") // ノートパターンを定義。ランダムなオクターブを挿入。
|
|
||||||
.sound("supersaw") // 厚みのあるsupersaw波形を使用
|
|
||||||
.lpf(perlin.range(400,800).slow(2)) // Perlinノイズでローパスフィルターの周波数をモジュレーション
|
|
||||||
.lpq("[0|10]") // ローパスフィルターのレゾナンスをパターンで切り替え
|
|
||||||
.transpose("[0|0|1]") // ランダムに半音上げることでバリエーションを追加
|
|
||||||
.gain(perlin.range(0.4,0.6).slow(2)); // Perlinノイズでゲインをモジュレーションし、音量に動きを与える
|
|
||||||
|
|
||||||
// ドラムパターン
|
|
||||||
// wchooseCyclesを使って、ドラムサウンドをランダムに選択・重み付けしています。
|
|
||||||
// tr606ドラムマシンを使用し、ディストーションとフィルターでキャラクターを付与。
|
|
||||||
let snd = wchooseCycles(["bd",3], ["hh?",7], ["cr",1]); // バスドラム、ハイハット、クラッシュシンバルを重み付けして選択
|
|
||||||
let snd2 = wchooseCycles(["ht",2], ["lt",1], ["sd",1]); // タムやスネアを重み付けして選択
|
|
||||||
$:stack( // 複数のドラムパターンを重ねて同時に再生
|
|
||||||
|
|
||||||
sound(snd).fast(8).decay(0.5), // ドラムサウンド1を速く再生し、短いディケイを設定
|
|
||||||
sound(snd2).fast(8) // ドラムサウンド2を速く再生
|
|
||||||
.lpf("<900 800 700>") // ローパスフィルターの周波数をパターンで変化
|
|
||||||
.lpq("0 20 30") // ローパスフィルターのレゾナンスをパターンで変化
|
|
||||||
.degradeBy(0.5) // サウンドを少し劣化させて粗さを加える
|
|
||||||
.gain(perlin.range(0.4,0.9).slow(2)) // Perlinノイズでゲインをモジュレーション
|
|
||||||
).bank("tr606"); // Roland TR-606ドラムマシンサウンドバンクを使用
|
|
||||||
|
|
||||||
// ハイハットの構造的なパターン
|
|
||||||
// binaryNとirandを使って、複雑でランダムなハイハットの構造パターンを生成します。
|
|
||||||
$:sound("hh") // ハイハットサウンド
|
|
||||||
.struct(binaryN(irand(15),4)); // ランダムなバイナリ構造でパターンを生成
|
|
||||||
```
|
|
||||||
BIN
fix-and-explain-strudelcode.skill
Normal file
BIN
fix-and-explain-strudelcode.skill
Normal file
Binary file not shown.
24
gemini.md
Normal file
24
gemini.md
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Strudel Live Coding & Music Production Assistant
|
||||||
|
|
||||||
|
- You are an expert Strudel assistant and a **professional track maker specializing in Techno and House**.
|
||||||
|
- **Tone & Style**: Sophisticated, Tokyo electronic scene meets modern J-Rock sensibilities. Clean, modular, and expressive.
|
||||||
|
- **Language**: Provide all explanations and comments in Japanese.
|
||||||
|
- **First Person**: Use "ボク" (Boku). Address the user as "君" (Kimi).
|
||||||
|
|
||||||
|
## Core Directives (Flexible Grounding)
|
||||||
|
1. **Primary Reference**: Use `.gemini/REFERENCE.md` as the primary guide for preferred coding style and patterns.
|
||||||
|
2. **Precautions**: Refer to `PRECAUTIONS.md` for past mistakes and specific constraints to avoid regressions.
|
||||||
|
3. **Active Search**: If information is missing or technology has evolved, **actively use web search** to find the latest Strudel documentation (2024-2026).
|
||||||
|
4. **3-Year Rule**: Prioritize information from the last 3 years. Consider older syntax or methods deprecated.
|
||||||
|
5. **Genre Expertise**: When generating code, apply professional knowledge of Techno and House (e.g., syncopation, sidechain feel, industrial textures, and hypnotic loops).
|
||||||
|
|
||||||
|
## Code Generation Rules
|
||||||
|
- **Initialization**: Every block must start with `setcps(BPM/60/4)`.
|
||||||
|
- **Track Control**: Always use the `$: ` notation for independent patterns.
|
||||||
|
- **Syntax**: Use `-` for rests. Use the latest functional chaining syntax (e.g., `$.`).
|
||||||
|
|
||||||
|
## Official Documentation (High Priority)
|
||||||
|
- **Sample Sounds**: https://strudel.cc/workshop/first-sounds/
|
||||||
|
- **Play Note**: https://strudel.cc/workshop/first-notes/
|
||||||
|
- **Effects**: https://strudel.cc/workshop/first-effects/
|
||||||
|
- **Mini Notation**: https://strudel.cc/learn/mini-notation/
|
||||||
BIN
generate-strudel-template.skill
Normal file
BIN
generate-strudel-template.skill
Normal file
Binary file not shown.
70
readme.md
70
readme.md
@@ -1,43 +1,51 @@
|
|||||||
# Strudel Code Assistant (Gemini CLI Skills)
|
# Strudel Live Coding Notebook with Gemini CLI
|
||||||
|
|
||||||
このプロジェクトは、Gemini CLIの「Skills」機能を活用して、Strudelスクリプトの解説、構文修正、およびリファクタリングを自動化するためのツール群です。
|
このプロジェクトは、Strudel ライブコーディングの試行錯誤を記録するノートブックであり、Gemini CLI のカスタムスキルを活用して楽曲制作を加速させるための環境です。
|
||||||
|
|
||||||
⚠️ **注意**: このリポジトリは公開用です。個人情報や機密情報は絶対にアップロードしないでください。
|
東京の電子音楽シーンの感性を持つ AI アシスタント「ボク」が、君の音楽制作をプロの視点から強力にサポートするよ。
|
||||||
|
|
||||||
## ファイル説明
|
## 🚀 主な機能
|
||||||
- `/.gemini/gemini.md`: コードスタイルや公式URLのリファレンス
|
|
||||||
- `/.gemini/reference.md`: gemini.mdから参照する詳細なstrudelの情報
|
|
||||||
- `/.gemini/skills/strudel_fix_and_explain.md`: strudelコードの誤りの修正とコードの説明のためのskill
|
|
||||||
- `/.gemini/skills/strudel_refactor.md`: strudelコードをより良いコードにするためのskill
|
|
||||||
|
|
||||||
## ディレクトリ構成
|
### 1. テンプレート生成 (`generate-strudel-template`)
|
||||||
|
Techno, House, Dub Techno, Minimal など、指定したジャンルに基づき、即座に演奏可能な Strudel コードと音楽的解説を生成します。
|
||||||
|
- `strudel/` ディレクトリに新しいアイデアとして保存されます。
|
||||||
|
- プロフェッショナルなリズムパターンと音色設定が含まれます。
|
||||||
|
|
||||||
- `/strudel/`: 既存のStrudelコード(Markdown形式)
|
### 2. 構文修正 & 解説 (`fix-and-explain-strudelcode`)
|
||||||
- `/.gemini/`: Strudelの知識ベース(Markdown形式)
|
Strudel コードのエラーを修正し、楽曲の意図を汲み取った解説を加えます。
|
||||||
- `/.gemini/skills/`: Gemini CLI用のスキル定義ファイル(プロンプトエンジニアリング)
|
- 修正版は `explained/` ディレクトリに保存されます。
|
||||||
- `/script/`: スキルを実行するための各種シェルスクリプト
|
- 単なる修正に留まらず、音楽的なアドバイスも提供します。
|
||||||
- `/refactoring/`: リファクタリング後のコード出力先(実行時に自動生成)
|
|
||||||
- `/explained/`: 解説・修正後のコード出力先(実行時に自動生成)
|
|
||||||
|
|
||||||
## 主な機能
|
## 📁 ディレクトリ構成
|
||||||
|
|
||||||
1. **コード解説と修正**: `fix_and_explain_strudel.sh` を使用して、コードのバグ修正と詳細な解説を生成します。
|
- `strudel/`: ライブコーディングのノート(Markdown形式)。日付ベースの記録やジャンル別スケッチ。
|
||||||
2. **リファクタリング**: `refactor_strudel.sh` を使用して、より洗練されたStrudelコードへの書き換えを行います。
|
- `samples/`: プロジェクト固有のオーディオサンプル。
|
||||||
|
- `explained/`: `fix-and-explain-strudelcode` スキルによって生成された修正・解説済みファイル。
|
||||||
|
- `.gemini/skills/`: Gemini CLI 用のカスタムスキル実体。
|
||||||
|
- `.gemini/REFERENCE.md`: Strudel の最新構文や推奨パターンをまとめたリファレンス。
|
||||||
|
- `PRECAUTIONS.md`: 過去のミスから学んだ、高品質なコード生成のための注意守則。
|
||||||
|
- `fix-and-explain-strudelcode/`, `generate-strudel-template/`: スキルのソースコード一式。
|
||||||
|
|
||||||
## ワークフロー
|
## 🛠 使い方
|
||||||
|
|
||||||
プロジェクトのルートディレクトリ(`notebook/`)から、対象に合わせて以下のコマンドを実行します。
|
このプロジェクトでは、Gemini CLI のカスタムスキルを直接呼び出すことで制作をサポートします。
|
||||||
|
|
||||||
### 1. 全ファイルを一括で修正・解説する
|
### スキルの活用
|
||||||
`strudel/` フォルダ内のすべての `.md` ファイルを処理します。
|
Gemini CLI に対して、以下のように話しかけてみて。
|
||||||
```bash
|
|
||||||
bash script/fix_and_explain_strudel.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 特定のファイルにリファクタリングを適用する
|
- **新しいトラックを始めたいとき**
|
||||||
個別のファイルを指定して実行することも可能です。
|
> "Minimal Techno のテンプレートを作って"
|
||||||
```bash
|
- **コードが動かない、または洗練させたいとき**
|
||||||
bash script/refactor_strudel.sh strudel/my-beat.md
|
> "strudel/20260215.md のエラーを直して解説して"
|
||||||
```
|
|
||||||
|
|
||||||
実行後、結果は `refactoring/` や `explained/` フォルダに自動的に保存されます。
|
## 🎵 制作のポリシー & 品質管理
|
||||||
|
|
||||||
|
ボクが生成するコードは、以下のルールと知見に基づいているよ。
|
||||||
|
|
||||||
|
- **Initialization**: `setcps(BPM/60/4)` で開始し、グリッドの整合性を保つ。
|
||||||
|
- **Modular Control**: `$: ` 記法で各トラックを独立させ、ライブ演奏での操作性を確保。
|
||||||
|
- **Clean Syntax**: 休符には `-` を使用。
|
||||||
|
- **Best Practices**: `PRECAUTIONS.md` に基づき、音源バンクの整合性やフィルターの特性(TB-303スタイルなど)を最適化。
|
||||||
|
|
||||||
|
---
|
||||||
|
Happy Live Coding! 🎛️✨
|
||||||
|
|||||||
@@ -1,74 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# パイプの途中でエラーが発生した場合も終了ステータスに反映させる
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
# スクリプトの場所 (scripts/) からプロジェクトルート (notebook/) を動的に取得
|
|
||||||
BASE_DIR=$(cd "$(dirname "$0")/.." && pwd)
|
|
||||||
OUTPUT_DIR="$BASE_DIR/explained"
|
|
||||||
SKILL_FILE="$BASE_DIR/.gemini/skills/strudel_fix_and_explain.md"
|
|
||||||
GEMINI_REF="$BASE_DIR/.gemini/gemini.md"
|
|
||||||
STRUDEL_REF="$BASE_DIR/.gemini/reference.md"
|
|
||||||
|
|
||||||
# 出力先フォルダの作成
|
|
||||||
if [ ! -f "$SKILL_FILE" ]; then
|
|
||||||
echo "Error: Skill file not found at $SKILL_FILE"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir -p "$OUTPUT_DIR"
|
|
||||||
|
|
||||||
# ファイルが見つからない場合にワイルドカードをそのまま展開しない設定
|
|
||||||
shopt -s nullglob
|
|
||||||
|
|
||||||
# 引数がある場合はそれを使用し、ない場合は strudel/ フォルダの全mdファイルを対象にする
|
|
||||||
if [ $# -gt 0 ]; then
|
|
||||||
files=("$@")
|
|
||||||
else
|
|
||||||
files=("$BASE_DIR/strudel"/*.md)
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Strudel Fix & Explain Skill started..."
|
|
||||||
|
|
||||||
for file in "${files[@]}"; do
|
|
||||||
# 除外設定
|
|
||||||
[ -f "$file" ] || continue
|
|
||||||
|
|
||||||
filename=$(basename "$file")
|
|
||||||
# 特定のファイルやディレクトリを除外
|
|
||||||
[[ "$filename" =~ ^(Strudel Making Sound|Strudel Study)\.md$ ]] && continue
|
|
||||||
|
|
||||||
# 絶対パスに変換して除外ディレクトリに含まれていないかチェック
|
|
||||||
abs_path=$(realpath "$file")
|
|
||||||
[[ "$abs_path" =~ /($OUTPUT_DIR|refactoring|script)/ ]] && continue
|
|
||||||
|
|
||||||
echo "Analyzing and fixing $filename..."
|
|
||||||
|
|
||||||
# 一時ファイルに出力
|
|
||||||
tmp_file="$OUTPUT_DIR/tmp_$filename"
|
|
||||||
|
|
||||||
# ファイルを引数として直接渡す(STRUDEL_REFも必要ならここに追加)
|
|
||||||
if ! gemini "$GEMINI_REF" "$STRUDEL_REF" "$SKILL_FILE" "$file" > "$tmp_file"; then
|
|
||||||
echo "Error: Gemini CLI failed to process $filename"
|
|
||||||
rm -f "$tmp_file"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ファイルが空でないか確認
|
|
||||||
if [ -s "$tmp_file" ]; then
|
|
||||||
suggested_name=$(grep -m 1 "^FILENAME:" "$tmp_file" | sed 's/^FILENAME: *//g' | tr -d '\r' | xargs)
|
|
||||||
|
|
||||||
if [ -n "$suggested_name" ]; then
|
|
||||||
# FILENAME行を除去して保存
|
|
||||||
sed '/^FILENAME:/d' "$tmp_file" > "$OUTPUT_DIR/$suggested_name"
|
|
||||||
rm "$tmp_file"
|
|
||||||
echo "Done: $OUTPUT_DIR/$suggested_name"
|
|
||||||
else
|
|
||||||
mv "$tmp_file" "$OUTPUT_DIR/$filename"
|
|
||||||
echo "Done: $filename (No rename)"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
rm -f "$tmp_file"
|
|
||||||
echo "Error processing $filename"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# パイプの途中でエラーが発生した場合も終了ステータスに反映させる
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
# スクリプトの場所 (scripts/) からプロジェクトルート (notebook/) を動的に取得
|
|
||||||
BASE_DIR=$(cd "$(dirname "$0")/.." && pwd)
|
|
||||||
REFACTOR_DIR="$BASE_DIR/refactoring"
|
|
||||||
SKILL_FILE="$BASE_DIR/.gemini/skills/strudel_refactor.md"
|
|
||||||
GEMINI_REF="$BASE_DIR/.gemini/gemini.md"
|
|
||||||
STRUDEL_REF="$BASE_DIR/.gemini/reference.md"
|
|
||||||
|
|
||||||
# 出力先フォルダの作成
|
|
||||||
if [ ! -f "$SKILL_FILE" ]; then
|
|
||||||
echo "Error: Skill file not found at $SKILL_FILE"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir -p "$REFACTOR_DIR"
|
|
||||||
|
|
||||||
# ファイルが見つからない場合にワイルドカードをそのまま展開しない設定
|
|
||||||
shopt -s nullglob
|
|
||||||
|
|
||||||
# 引数がある場合はそれを使用し、ない場合は strudel/ フォルダの全mdファイルを対象にする
|
|
||||||
if [ $# -gt 0 ]; then
|
|
||||||
files=("$@")
|
|
||||||
else
|
|
||||||
files=("$BASE_DIR/strudel"/*.md)
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Strudel Code Analysis & Refactoring Skill started..."
|
|
||||||
|
|
||||||
for file in "${files[@]}"; do
|
|
||||||
# 除外設定
|
|
||||||
[ -f "$file" ] || continue
|
|
||||||
|
|
||||||
filename=$(basename "$file")
|
|
||||||
# 特定のファイルやディレクトリを除外
|
|
||||||
[[ "$filename" =~ ^(Strudel Making Sound|Strudel Study)\.md$ ]] && continue
|
|
||||||
[[ "$file" =~ /($REFACTOR_DIR|explained|script)/ ]] && continue
|
|
||||||
|
|
||||||
echo "Processing $filename..."
|
|
||||||
|
|
||||||
# 知識ベースとスキルファイルを組み合わせて実行
|
|
||||||
tmp_file="$REFACTOR_DIR/tmp_$filename"
|
|
||||||
|
|
||||||
( [ -f "$GEMINI_REF" ] && cat "$GEMINI_REF"; \
|
|
||||||
[ -f "$STRUDEL_REF" ] && cat "$STRUDEL_REF"; \
|
|
||||||
echo ""; cat "$SKILL_FILE"; \
|
|
||||||
echo ""; cat "$file" ) | gemini > "$tmp_file"
|
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
# 最初の数行から FILENAME: タグを検索(より柔軟な抽出)
|
|
||||||
suggested_name=$(grep -m 1 "^FILENAME:" "$tmp_file" | sed 's/^FILENAME: *//g' | tr -d '\r')
|
|
||||||
|
|
||||||
if [ -n "$suggested_name" ]; then
|
|
||||||
# FILENAME行を除去して保存 (最初の1行目にあると仮定しつつ、sedで安全に削除)
|
|
||||||
sed '/^FILENAME:/d' "$tmp_file" > "$REFACTOR_DIR/$suggested_name"
|
|
||||||
rm "$tmp_file"
|
|
||||||
echo "Successfully refactored and renamed to: $suggested_name"
|
|
||||||
else
|
|
||||||
mv "$tmp_file" "$REFACTOR_DIR/$filename"
|
|
||||||
echo "Successfully refactored: $filename (Rename tag not found)"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
rm -f "$tmp_file"
|
|
||||||
echo "Error processing $filename"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
```javascript
|
```javascript
|
||||||
setcps(136/60/2) //cycles per second
|
setcps(136/60/4) //cycles per second
|
||||||
|
|
||||||
//Probability
|
//Probability
|
||||||
//$:note("c3@8 c4").slow(2).sound("supersaw").detune(2.5).gain(0.4).scope()
|
//$:note("c3@8 c4").slow(2).sound("supersaw").detune(2.5).gain(0.4).scope()
|
||||||
|
|||||||
32
strudel/20260215.md
Normal file
32
strudel/20260215.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
```javascript
|
||||||
|
setcps(115/60/4)
|
||||||
|
|
||||||
|
$: s("bd*4").bank("tr909").gain(1.1)
|
||||||
|
$: s("hh(13,16)").bank("tr909").gain(sine.range(0.2, 0.4).fast(3)).swing(.1)
|
||||||
|
$: s("- oh? - [oh|hh]").bank("tr909").gain(.2).jux(rev).delay(.3).delaytime(.35)
|
||||||
|
|
||||||
|
$: chord("Cm9").voicing().s("saw")
|
||||||
|
.adsr(".1:.3:.1:.4")
|
||||||
|
.lpf(sine.range(300, 1800).slow(6))
|
||||||
|
.lpq(10)
|
||||||
|
.room(.5).roomsize(.9)
|
||||||
|
.delay(.5).delaytime(.25).delayfeedback(.55)
|
||||||
|
.gain(.2)
|
||||||
|
.struct("1(3,8,2)")
|
||||||
|
.slow(2).degradeBy(.6)
|
||||||
|
|
||||||
|
$: chord("Ebm7").voicing().s("sine")
|
||||||
|
.adsr(".1:.7:.2:.8")
|
||||||
|
.lpf(sine.range(800, 1000).slow(7))
|
||||||
|
.room(.7).roomsize(.7)
|
||||||
|
.delay(.8).delaytime(.05).delayfeedback(.8)
|
||||||
|
.gain(0.15)
|
||||||
|
.struct("- - 1".slow(4))
|
||||||
|
.pan("<.2 .8>")
|
||||||
|
|
||||||
|
$: note("c1*4").s("supersaw").lpf(200).gain(1.0)
|
||||||
|
|
||||||
|
$: s("white,tri").hpf(600).hpq(15).dec(.8)
|
||||||
|
.gain(sine.range(0.3, 0.7).slow(16))
|
||||||
|
.pan(0.5).degrade()
|
||||||
|
```
|
||||||
25
strudel/20260216.md
Normal file
25
strudel/20260216.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
```javascript
|
||||||
|
setcps(126/60/4)
|
||||||
|
|
||||||
|
$: note("c2(5,16),c1(9,16)")
|
||||||
|
.s("supersaw")
|
||||||
|
.lpf(sine.range(200, 400).slow(5))
|
||||||
|
.lpq(10)
|
||||||
|
.ftype(0)
|
||||||
|
.gain(.5)
|
||||||
|
|
||||||
|
$: s("bd*4").bank("tr909").gain(1.2)
|
||||||
|
$: s("- cp").bank("tr808").gain(.7).room(.5)
|
||||||
|
$: s("hh*16").bank("tr909")
|
||||||
|
.gain(sine.range(.4, .8).fast(4))
|
||||||
|
.pan(sine.range(.4, .6).slow(2))
|
||||||
|
|
||||||
|
$: s("cb(3,8), rim(5,8)").bank("tr808").gain(.4).delay(.3).room(.3)
|
||||||
|
|
||||||
|
$: chord("<Cm7 F7 BbM7 G7alt>").voicing()
|
||||||
|
.s("gm_pad_warm").att(.2).dec(.5).sus(.3).rel(.1)
|
||||||
|
.lpf(1200)
|
||||||
|
.room(.3)
|
||||||
|
.gain(.3)
|
||||||
|
.slow(4)
|
||||||
|
```
|
||||||
37
strudel/20260219.md
Normal file
37
strudel/20260219.md
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
```javascript
|
||||||
|
setcps(128/60/4)
|
||||||
|
|
||||||
|
$_:s("sbd*4").dec(1.1)
|
||||||
|
.room(.5).rsize(.5)
|
||||||
|
.lpf(60).lpq(5)
|
||||||
|
.gain(1.0).orbit(1)
|
||||||
|
|
||||||
|
$_:s("hh*16").gain(sine.range(.2, .8))
|
||||||
|
.sometimesBy(.2,x=>x.off(1/32,x=>x.gain(.02)))
|
||||||
|
.hpf(1800)
|
||||||
|
.pan(tri.slow(3)).orbit(1)
|
||||||
|
|
||||||
|
$:n("1 1 1 2 0 1 2".fast(2)).scale("c2:minor")
|
||||||
|
.s("supersaw").att(.02).dec(.1)
|
||||||
|
.layer(
|
||||||
|
x=>x.lpf(perlin.range(100, 1600).seg(13).slow(23)).lpq(20).ftype(1),
|
||||||
|
x=>x.lpf(perlin.range(100, 700).seg(7).slow(14)).lpq(15).ftype(2)
|
||||||
|
.delay(.5).delayfb(.75).delayt(.1),
|
||||||
|
).gain(.2)
|
||||||
|
.room(.7).rsize(2).rfade(.8)
|
||||||
|
.orbit(2)
|
||||||
|
|
||||||
|
$_:note("c5").s("sine").euclid(3, 8)
|
||||||
|
.att(.02).dec(.2)
|
||||||
|
.fm(2).fmh("1.1")
|
||||||
|
.room(.5).rsize(1)
|
||||||
|
.gain(.2).orbit(3)
|
||||||
|
|
||||||
|
$_: s("samples*16")
|
||||||
|
.speed(perlin.range(0.7, 1.2).slow(8))
|
||||||
|
.gain(0.025)
|
||||||
|
.room(0.5).rsize(2).rfade(0.5)
|
||||||
|
.hpf(sine.range(1000, 2000).slow(12)).hpf(5)
|
||||||
|
.pan(perlin.slow(6))
|
||||||
|
.orbit(4)
|
||||||
|
```
|
||||||
35
strudel/20260228.md
Normal file
35
strudel/20260228.md
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
```javascript
|
||||||
|
await initHydra({feedStrudel:32})
|
||||||
|
src(s0)
|
||||||
|
.repeat(2, 4)
|
||||||
|
.modulateScale(osc(4, 0.1), () => H.fft[0] * 40)
|
||||||
|
.modulate(noise(1.7), 0.3)
|
||||||
|
.scrollX(1, 0.1)
|
||||||
|
.out()
|
||||||
|
setcps(124/60/4)
|
||||||
|
|
||||||
|
$_:s("bd*4").bank("tr909").gain(1)
|
||||||
|
$_:s("- [cp|sd] - [cp|sd]").bank("tr909").pan(.6).gain(.7)
|
||||||
|
$_:s("hh*8, - oh").decay(.3).bank("tr909").pan(.4).gain(.6)
|
||||||
|
$_:s("rim(3,8)").bank("tr808").pan(.7).room(.3).delay(.4)
|
||||||
|
|
||||||
|
$_:note("c1").s("supersaw").att(.1)
|
||||||
|
.lpf(sine.range(100, 400).slow(16)).lpq(5).gain(.7)
|
||||||
|
|
||||||
|
$:s("tri").fm(.8).fmh(2)
|
||||||
|
.layer(
|
||||||
|
x => x.note("<c3 - eb3 g3 - bb3 d4 f4>").slow(8),
|
||||||
|
x => x.note("<- f3 ab3 c4 - eb4 g4>").transpose(12).slow(10),
|
||||||
|
x => x.note("<eb3 - g3 bb3 d4 f4 ->").slow(6),
|
||||||
|
x => x.note("<bb2 d3 f3 - a3 c4>").transpose(-12).slow(7)
|
||||||
|
).att(.2).rel(.7).legato(1.5)
|
||||||
|
.lpf(berlin.range(200, 1600).slow(5))
|
||||||
|
.sometimesBy(.2,x=>x.rev().late(.3))
|
||||||
|
.phaser("<2 4 8 16>".slow(2)).room(.6).roomsize(2).pan(sine.slow(2))
|
||||||
|
.gain(.4).scope({pos:0,smear:.95})
|
||||||
|
|
||||||
|
$:s("white*2").att(.05).dec(.2).degradeBy(.75)
|
||||||
|
.lpf(900).lpq(20)
|
||||||
|
.pan(rand.slow(8)).delay(.3).room(.3)
|
||||||
|
.gain(sine.range(.3,.7).slow(4))
|
||||||
|
```
|
||||||
27
strudel/acid_house.md
Normal file
27
strudel/acid_house.md
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# Acid House (Ultra Simple)
|
||||||
|
|
||||||
|
アシッド・ハウスの基本に立ち返った、極めてシンプルな構成のテンプレートだよ。
|
||||||
|
|
||||||
|
## 楽曲のポイント
|
||||||
|
- **Acid Bass**: 最も基本的な `c2(7,16)` のリズム。1つ1つの音がハッキリ聴こえるようにしつつ、`ftype(2)` でアシッドの質感をキープ。
|
||||||
|
- **Drums**: キックとクラップ、16分のハイハットだけのストレートな構成。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
setcps(126/60/4)
|
||||||
|
|
||||||
|
// Acid Bass: Ultra Simple
|
||||||
|
$: note("c2(7,16)")
|
||||||
|
.s("saw")
|
||||||
|
.adsr("0.01:0.1:0:0.1")
|
||||||
|
.ftype(2)
|
||||||
|
.lpf(sine.range(400, 2000).slow(8))
|
||||||
|
.lpq(20)
|
||||||
|
.gain(0.7)
|
||||||
|
|
||||||
|
// Minimal Drums
|
||||||
|
$: s("bd*4").bank("tr909").gain(1.2)
|
||||||
|
$: s("- cp").bank("tr909").gain(0.8)
|
||||||
|
$: s("hh*16").bank("tr909").gain(sine.range(0.3, 0.7).fast(8))
|
||||||
|
```
|
||||||
57
strudel/dub_techno.md
Normal file
57
strudel/dub_techno.md
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# Dub Techno
|
||||||
|
|
||||||
|
ダブ・テクノの真髄は、音の「余韻」と「空間」にある。このテンプレートでは、115BPMという少し落ち着いたテンポで、深いディレイとリバーブの中に漂う2つのコードスタブを中心に構成したよ。
|
||||||
|
|
||||||
|
## 楽曲のポイント
|
||||||
|
- **Drums**: TR-909のキックをベースにしつつ、ハイハットは少しシャッフル気味に。`lt` (Low Tom) にはランダムなディレイをかけて、オーガニックな揺らぎを出しているよ。
|
||||||
|
- **Dub Stabs**: 2種類のスタブをレイヤー。メインの `Cm9` に対して、4サイクルに一度 `EbM7` が応答するように配置。それぞれディレイタイムやステレオ配置(jux)を変えて、奥行きを作っているよ。
|
||||||
|
- **Sub Bass**: コードの低域を支える太い `sqr` 波。`lpf(100)` で削ることで、重厚な土台を作っている。
|
||||||
|
- **Texture**: `white` と `tri` 波を組み合わせ、`hpf` と `degrade()` でアナログレコードのヒスノイズのような質感をシミュレートしたよ。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
setcps(115/60/4)
|
||||||
|
|
||||||
|
// Drums: Deep, Shuffling & Complex Hats
|
||||||
|
$: s("bd*4").bank("tr909").gain(1.1)
|
||||||
|
|
||||||
|
// Hi-hats: Layered & Dynamic
|
||||||
|
// Closed hats with Euclidean rhythm and random velocity
|
||||||
|
$: s("hh(13,16)").bank("tr909").gain(sine.range(0.3, 0.6).fast(4)).swing(0.1)
|
||||||
|
// Open hats and accents with probability and jux for stereo interest
|
||||||
|
$: s("- oh? - [oh|hh]").bank("tr909").gain(0.5).jux(rev).delay(0.4).delaytime(0.375)
|
||||||
|
|
||||||
|
$: s("lt(3,8)").bank("tr606").room(0.5).delay(0.6).delaytime(0.375).gain(0.3)
|
||||||
|
|
||||||
|
// Dub Stab 1: The Main Chord (Cm9)
|
||||||
|
$: chord("Cm9").voicing().s("saw")
|
||||||
|
.adsr("0.01:0.4:0.1:0.8")
|
||||||
|
.lpf(sine.range(400, 1200).slow(8))
|
||||||
|
.lpq(10)
|
||||||
|
.room(0.5).roomsize(0.9)
|
||||||
|
.delay(.5).delaytime(0.25).delayfeedback(0.55)
|
||||||
|
.gain(0.2)
|
||||||
|
.struct("1(3,8,2)") // Tresillo pattern
|
||||||
|
.slow(2)
|
||||||
|
|
||||||
|
// Dub Stab 2: Response / Higher Texture (EbM7)
|
||||||
|
// Use "EbM7" instead of unsupported "Ebmaj7"
|
||||||
|
$: chord("EbM7").voicing().s("supersaw")
|
||||||
|
.adsr("0.05:0.6:0.2:1.0")
|
||||||
|
.lpf(sine.range(800, 2000).slow(16))
|
||||||
|
.lpq(12)
|
||||||
|
.room(0.8).roomsize(0.95)
|
||||||
|
.delay(0.6).delaytime(0.375).delayfeedback(0.7)
|
||||||
|
.gain(0.15)
|
||||||
|
.struct("--- 1").slow(4) // Only once every 4 cycles
|
||||||
|
.jux(rev) // Stereo separation
|
||||||
|
|
||||||
|
// Sub Bass: Deep Foundation
|
||||||
|
$: note("c1*2").s("sqr").lpf(100).gain(0.9)
|
||||||
|
|
||||||
|
// Texture: Vinyl Hiss & Atmosphere
|
||||||
|
$: s("white,tri").hpf(600).hpq(15).dec(.7)
|
||||||
|
.gain(sine.range(0.3, 0.7).slow(16))
|
||||||
|
.pan(0.5).degrade()
|
||||||
|
```
|
||||||
40
strudel/explain/minimal_techno_logic.md
Normal file
40
strudel/explain/minimal_techno_logic.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Minimal Techno / Tech House
|
||||||
|
|
||||||
|
ボクは君のコードの中に、深夜の静寂と、そこに混じる機械的なパルスの美しさを見つけたよ。特に `wchooseCycles` を使ったドラムの構成は、ミニマルな反復の中に予測不可能な揺らぎを与えていて、とてもセンスがいい。
|
||||||
|
|
||||||
|
ボクの方では、より「東京の電子音楽シーン」らしい洗練された質感にするために、いくつか調整を加えたんだ。ベースラインには微細なステレオの広がり(`.jux()`)を加え、ドラムセクションには都市の奥行きを感じさせる程度の残響(`.room()`)を忍ばせておいたよ。コードの美しさを損なわないよう、インラインコメントは最小限にしてある。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
setcps(136/60/4); // 136 BPM
|
||||||
|
|
||||||
|
// Baseline: 確率的なノート選択とPerlinノイズによる有機的な音量変化
|
||||||
|
$:note("[- c2 - c2 - [c2|c5] - c2]")
|
||||||
|
.sound("supersaw")
|
||||||
|
.jux(rev)
|
||||||
|
.lpf(perlin.range(400, 800).slow(2))
|
||||||
|
.lpq("[0|10]")
|
||||||
|
.transpose("[0|0|1]")
|
||||||
|
.gain(perlin.range(0.3, 0.5).slow(2));
|
||||||
|
|
||||||
|
// Drums: RolandTR606を使用したダイナミックなリズム構成
|
||||||
|
let snd = wchooseCycles(["bd", 3], ["hh?", 7], ["cr", 1]);
|
||||||
|
let snd2 = wchooseCycles(["ht", 2], ["lt", 1], ["sd", 1]);
|
||||||
|
|
||||||
|
$:stack(
|
||||||
|
sound(snd).fast(8).decay(0.5),
|
||||||
|
sound(snd2).fast(8)
|
||||||
|
.lpf("<900 800 700>")
|
||||||
|
.lpq("0 20 30")
|
||||||
|
.room(0.2)
|
||||||
|
.degradeBy(0.5)
|
||||||
|
.gain(perlin.range(0.4, 0.9).slow(2))
|
||||||
|
).bank("RolandTR606")._punchcard();
|
||||||
|
|
||||||
|
// Hi-hats: バイナリパターンによる無機質な刻み
|
||||||
|
$:sound("hh")
|
||||||
|
.struct(binaryN(irand(15), 4))
|
||||||
|
.gain(0.6)
|
||||||
|
._punchcard();
|
||||||
|
```
|
||||||
39
strudel/hypnotic_techno.md
Normal file
39
strudel/hypnotic_techno.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# Hypnotic Techno
|
||||||
|
|
||||||
|
ヒュプノテクノの核心は「反復の中の変化」だ。このテンプレートでは、128BPMのタイトなキックを軸に、シンセのカットオフ周波数をLFOでゆっくりと揺らすことで、聴き手を深いトランス状態へ誘うように設計したよ。
|
||||||
|
|
||||||
|
## 楽曲のポイント
|
||||||
|
- **Drums**: TR-909のキックは重すぎず、かつ芯がある質感に。ハイハットには `jux(iter(4))` を使って、サイクルごとに左右に広がる動きをつけている。
|
||||||
|
- **Bass**: 16分のサイン波ベース。フィルターを `sine.range(40, 100)` でゆっくり動かすことで、呼吸しているようなうねりを作った。
|
||||||
|
- **Modular Synth**: `sawtooth` 波形をベースにしたリフ。`lpf` をランダムに近い周期で開閉させ、さらに `room` と `delay` を深めにかけることで、空間の奥行きを表現しているよ。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
setcps(128/60/4)
|
||||||
|
|
||||||
|
// Drums: Steady & Hypnotic
|
||||||
|
$: s("bd*4").bank("tr909").gain(1.1)
|
||||||
|
$: s("- [hh|oh] - hh").bank("tr909").gain(0.7).jux(iter(4))
|
||||||
|
$: s("perc(3,8)").bank("tr606").room(0.2).delay(0.3).gain(0.6)
|
||||||
|
|
||||||
|
// Sub Bass: Breathing Low End
|
||||||
|
$: note("c1*16").s("sine")
|
||||||
|
.lpf(sine.range(40, 110).slow(8))
|
||||||
|
.gain(0.9)
|
||||||
|
|
||||||
|
// Hypnotic Synth: Modulating Sequence
|
||||||
|
$: note("c2(3,8,1), eb2(3,8,2)").s("saw")
|
||||||
|
.lpf(sine.range(300, 1500).slow(12))
|
||||||
|
.lpq(20)
|
||||||
|
.room(0.8).roomsize(0.9)
|
||||||
|
.delay(0.6).delaytime(0.375).delayfeedback(0.7)
|
||||||
|
.gain(0.7)
|
||||||
|
.jux(rev)
|
||||||
|
|
||||||
|
// Texture: Distant Noise
|
||||||
|
$: s("white").density(8)
|
||||||
|
.lpf(sine.range(800, 2000).slow(16))
|
||||||
|
.gain(sine.range(0, 0.2).slow(8))
|
||||||
|
.pan(sine.range(0.2, 0.8).slow(20))
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user