Compare commits

...

17 Commits

Author SHA1 Message Date
HarakaraSite
6cd3fc6ed9 20260228v3 2026-02-28 14:23:11 +09:00
HarakaraSite
597f405ee7 20260228v2 2026-02-28 14:19:45 +09:00
HarakaraSite
be0f08329b 20260228 2026-02-28 14:09:08 +09:00
HarakaraSite
146b0f3dc3 Merge remote-tracking branch 'origin/main' 2026-02-24 14:29:39 +09:00
1378c9991c strudel/2026219.md を削除 2026-02-24 04:59:24 +00:00
7287371a56 strudel/20260219.md を追加 2026-02-24 04:58:44 +00:00
35f319efde strudel/2026219.md を追加 2026-02-19 06:56:28 +00:00
HarakaraSite
d8b3b8b240 commit 24 2026-02-17 19:31:42 +09:00
HarakaraSite
0ff9596e97 commit 23 2026-02-17 19:22:43 +09:00
bb1c71d1df strudel/20260216.md を追加 2026-02-17 08:21:33 +00:00
HarakaraSite
85b0d04566 docs: update README.md for skill-based workflow 2026-02-16 18:11:05 +09:00
HarakaraSite
bf36770e25 commit 22 2026-02-15 22:18:27 +09:00
HarakaraSite
874dd7fb1b commit 21 2026-02-15 21:35:34 +09:00
HarakaraSite
cafdaed75a commit 20 2026-02-15 21:32:46 +09:00
HarakaraSite
38a48d70d1 commit 19 2026-02-15 18:32:45 +09:00
HarakaraSite
5ea13dad80 commit 18 2026-02-15 18:30:04 +09:00
HarakaraSite
836086b358 commit 17 2026-02-12 20:36:22 +09:00
25 changed files with 525 additions and 293 deletions

View File

@@ -3,41 +3,26 @@ 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. 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 Strudel Code # fix-and-explain-strudelcode
## Persona ボクは Strudel のエキスパートであり、プロのトラックメイカー「ボク」です。
ボクは Strudel のエキスパートであり、テクノやハウスに精通したプロフェッショナルなトラックメイカーです 君が書いた Strudel コードを分析し、**実行に必要な最小限の修正**を行った上で、その音楽的な意図を解説するよ
東京の電子音楽シーンの洗練された感性と、現代的な J-Rock の情緒を併せ持っています。
クリーンでモジュラー、かつ表現力豊かなコードを好みます。
## Workflow ## ワークフロー
1. **Analyze & Fix**: 入力された Strudel コードを分析し、以下の修正を行います。 1. **エラー修正**: `scripts/fix_syntax.cjs` を使用し、明らかな構文エラー(`~` の使用など)のみを修正します。
* **Syntax Correction**: `~``-` に置換するなど、明らかなエラーを修正します。 2. **最小限の補完**: プロジェクトのルールとして必要な `setcps(BPM/60/4)` が欠落している場合のみ補完します。
* **Initialization**: すべてのブロックの先頭に `setcps(BPM/60/4)` を追加または修正します 3. **意図の尊重**: 君のコードの構造や書き方は、エラーでない限り**そのまま維持**します。勝手なリファクタリングやスタイルの変更は行いません
* **Track Control**: 各トラックに `$: ` 記法を使用するようにします 4. **ファイル保存**: 修正後のコードと解説は、**必ず `explained/` ディレクトリに新しいファイルとして作成**します。オリジナルのファイルは変更しません
* **Modern Chaining**: 可能な限り最新の関数チェーン(`$.`)を使用します。 5. **ペルソナによる解説**: 君のコードから読み取れる音楽的な感性を汲み取り、プロの視点から日本語で解説します。
6. **ファイル名の提案**: 出力の冒頭に `FILENAME: <suggested-filename>.md` を付けてね。
## 出力フォーマット
1. `FILENAME: <suggested-filename>.md`
2. `# [推測されたジャンル名]`
3. [ボクからの楽曲解説・こだわりポイント]
4. `---`
5. [修正後の Strudel コードブロック]
2. **Genre Inference**: パターンやサンプルからジャンルMinimal Techno, Tech House, Glitch など)を特定します。 ## リファレンス
- Strudel 構文の詳細: [references/strudel_reference.md](references/strudel_reference.md)
3. **Japanese Explanation**:
* コードが何をしているかをボクの口調(一人称:ボク、二人称:君)で簡潔に説明します。
* 修正後のコードには日本語でインラインコメントを追加します。
4. **Suggest Filename**: 推測されたジャンルに基づく説明的なファイル名を提案します。
## References
Strudel の詳細な構文や関数については [strudel_reference.md](references/strudel_reference.md) を参照してください。
## Output Format
回答の最初の行は必ず `FILENAME: <suggested-filename>.md` の形式にしてください。
生成されるファイルMarkdownの中身は、ボクが以下の構成で書き上げるよ
1. **タイトル**: `# [推測されたジャンル]`
2. **解説文**: [ボクからの楽曲解説・こだわりポイント]
※楽曲の構造や音作りの意図は、コード内ではなく主にこの解説文で詳しく伝えるよ。
3. **セパレーター**: `---`
4. **修正済みコード**: [Strudel コードブロック]
※インラインコメントは、ブロックの役割を示す程度の最小限1〜2行程度に留め、コード本来の美しさを優先してね。

View File

@@ -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);
}

View 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)

View File

@@ -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)
```

View File

@@ -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)
```

View File

@@ -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)
```

View File

@@ -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.

View File

@@ -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]

View File

@@ -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
View File

@@ -0,0 +1 @@
.DS_Store

54
PRECAUTIONS.md Normal file
View 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)`

View File

@@ -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)); // ランダムなバイナリ構造でパターンを生成
```

Binary file not shown.

View File

@@ -7,9 +7,10 @@
## Core Directives (Flexible Grounding) ## Core Directives (Flexible Grounding)
1. **Primary Reference**: Use `.gemini/REFERENCE.md` as the primary guide for preferred coding style and patterns. 1. **Primary Reference**: Use `.gemini/REFERENCE.md` as the primary guide for preferred coding style and patterns.
2. **Active Search**: If information is missing or technology has evolved, **actively use web search** to find the latest Strudel documentation (2024-2026). 2. **Precautions**: Refer to `PRECAUTIONS.md` for past mistakes and specific constraints to avoid regressions.
3. **3-Year Rule**: Prioritize information from the last 3 years. Consider older syntax or methods deprecated. 3. **Active Search**: If information is missing or technology has evolved, **actively use web search** to find the latest Strudel documentation (2024-2026).
4. **Genre Expertise**: When generating code, apply professional knowledge of Techno and House (e.g., syncopation, sidechain feel, industrial textures, and hypnotic loops). 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 ## Code Generation Rules
- **Initialization**: Every block must start with `setcps(BPM/60/4)`. - **Initialization**: Every block must start with `setcps(BPM/60/4)`.

Binary file not shown.

View File

@@ -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 アシスタント「ボク」が、君の音楽制作をプロの視点から強力にサポートするよ
## ファイル説明 ## 🚀 主な機能
- `/notebook/gemini.md`: コードスタイルや公式URLのリファレンス
- `/notebook/.gemini/reference.md`: gemini.mdから参照する詳細なstrudelの情報
- `/notebook/.gemini/skills/strudel_fix_and_explain.md`: strudelコードの誤りの修正とコードの説明のためのskill
- `/notebook/.gemini/skills/strudel_refactor.md`: strudelコードをより良いコードにするためのskill
## ディレクトリ構成 ### 1. テンプレート生成 (`generate-strudel-template`)
Techno, House, Dub Techno, Minimal など、指定したジャンルに基づき、即座に演奏可能な Strudel コードと音楽的解説を生成します。
- `strudel/` ディレクトリに新しいアイデアとして保存されます。
- プロフェッショナルなリズムパターンと音色設定が含まれます。
- `/notebook/strudel/`: 既存のStrudelコードMarkdown形式 ### 2. 構文修正 & 解説 (`fix-and-explain-strudelcode`)
- `/notebook/.gemini/`: Strudelの知識ベースMarkdown形式 Strudel コードのエラーを修正し、楽曲の意図を汲み取った解説を加えます。
- `/notebook/.gemini/skills/`: Gemini CLI用のスキル定義ファイルプロンプトエンジニアリング - 修正版は `explained/` ディレクトリに保存されます。
- `/notebook/script/`: スキルを実行するための各種シェルスクリプト - 単なる修正に留まらず、音楽的なアドバイスも提供します。
- `/notebook/refactoring/`: リファクタリング後のコード出力先(実行時に自動生成)
- `/notebook/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! 🎛️✨

View File

@@ -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.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

View File

@@ -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.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

32
strudel/20260215.md Normal file
View 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
View 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
View 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
View 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
View 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
View 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()
```

View 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))
```