Strudelとは
Strudelは、Webブラウザ上で動作するライブコーディング音楽環境(REPL)であり、JavaScriptを用いて音楽の「パターン」を記述するためのパターン言語です。
1. 音符が無い(五線譜からの解放)
Strudelには従来の五線譜や音符の長さ(4分音符など)という概念がありません。
「1小節を何等分するか」という時間分割のルール(パターン・ストラクチャー)で音楽を作ります。
- 「音符」ではなく文字列でリズムを分割する
setcpm(30)
s("~ ~ cp ~ ~ ~ cp ~")
- 記号で空間を作る:
~ は休符を表します。1小節の中に文字を並べるだけで自動的に等分割されます。 - 文字が音になる:
cp(ハンドクラップ)などの文字を並べるだけで、直感的にリズムの配置が可能です。
- スケール(音階)と数値でメロディを制御する
setcpm(30)
n("<[4@2 4] [5@2 5] [6@2 6] [5@2 5]>*2")
.sound("gm_acoustic_bass")
- 数値による指定:
4 や 5 といった数値(度数)で音階を指定します。 - 時間の伸縮:
4@2(4の音を2倍の長さに引き伸ばす)や *2(スピードを2倍にする)といった記号を使い、五線譜を使わずに複雑なリズムを構築します。
2. 並列である(同時に複数の音を重ねる)
Strudelは、異なるリズムやメロディを並列に走らせて、重ね合わせるのが非常に得意です。
- カンマ(,)を使った並列処理
$: sound("bd*4, [~ <sd cp>]*2, [~ hh]*4").bank("RolandTR909")
- 一行でマルチトラック:
カンマ , で区切るだけで、バスドラム(bd)、スネア/クラップ(sd cp)、ハイハット(hh)という3つの独立したリズムを完全に並列で同時に鳴らすことができます。
- 「$」によるトラックの並列化
$: n(`< [~ 0] 2 [0 2] [~ 2] ... >*4`).scale("C4:minor").sound("saw")
$: sound("bd*4, [~ <sd cp>]*2, [~ hh]*4").bank("RolandTR909")
- 独立したループ:
$ 記号を使うことで、上の「シンセのメロディライン」と下の「ドラムパターン」をそれぞれ別々のレイヤーとして同時にループ再生させます。
3. ギターは難しい(プログラミングの壁)
ドラムやベースに比べ、Strudelでギターのリアルな演奏(コードの響きやカッティングなど)を表現しようとすると、コードが圧倒的に複雑になります。
- 複雑なギター演奏を再現するためのコード
setcpm(200)"<0@5 1 0 1 0@3 ~@2 0 ~ 0@4 ~@2 >/48"
.pickRestart([
stack(
"<c3@9 c#3 c3@2>",
"<g3 f3@2 g3@4 f3 g3 g#3 g3 f3>".add("<0,5>")
).struct("<x!4 ~!2 x!9 x@3 x!6>")
])
.note()
.transpose("<0@9 -5 -7 0@4 ~ 0@2 -5 -7 ~@2>/48")
.s("gm_acoustic_guitar_steel:2")
- 和音とピッチの微調整:
ギター特有のボイシング(弦の組み合わせ)を作るため、[c3,g3,c4] という和音の指定に加え、.add(-3) や .transpose(...) で複雑に音程をズラしていく必要があります。 - 複雑な制御関数のコンボ:
カッティングのリズムを制御するために stack や struct を組み合わせ、さらに長大な周期(/48)の中でパターンを切り替える(pickRestart)など、ベースやドラムのコードとは比較にならないほどの高度な記述が要求されます。
4. ピアノは万能(シンプルで美しい響き)
難しいギターとは対照的に、ピアノ音源はStrudelにおいて「最も万能な楽器」です。複雑な関数を使わなくても、シンプルにコード(和音)を書くだけで完璧に機能します。
- ピアノなら、シンプルな和音指定だけで綺麗に響く
setcpm(30)
$: n(`<
[~ 0] 2 [0 2] [~ 2]
[~ 0] 1 [0 1] [~ 1]
[~ 0] 3 [0 3] [~ 3]
[~ 0] 2 [0 2] [~ 2]
>*4`).scale("C4:minor").sound("piano")
$: sound("bd*4, [~ <sd cp>]*2, [~ hh]*4")
※ピアノ音源(gm_piano等)でも同様の構造
- 一発で鳴る和音:
[c4,e4,g4] のようにカンマで音名を囲むだけで、ピアノらしい美しい三和音が瞬時に鳴らせます。 - どんな役割にも化ける:
ベースライン、メロディ、バッキング、コード進行の確認など、ピアノ音源に変えるだけでどんなジャンルの音楽にも一瞬で馴染む万能さを持っています。
5. Pianoroll(視覚的な確認と操作)
Strudelの最大の特徴の一つが、エディタに組み込まれた「Pianoroll(ピアノロール)」ビューです。コードで書いた音楽が、リアルタイムにピアノロールへと視覚化されます。
- スケールやノートがそのままPianorollに視覚化される
setcpm(30)
n("<[4@2 4] [5@2 5] [6@2 6] [5@2 5]>*2")
.sound("gm_acoustic_bass")
.pianoroll()
- テキストからグリッドへの変換:
コードを実行すると、画面のピアノロール上に「どの音階(n)が」「どのスケール(scale)で」「いつ鳴っているか」がグラフィカルなブロックとして表示されます。 - コードと視覚の連動:
文字だけでは把握しづらい複雑なリズムの密度や音の重なり(並列処理の結果)を、一般的なDTM(DAW)ソフトのピアノロールと同じように目で見て直感的に確認できます。
6. Function(関数によるコードの共通化)
StrudelのベースはJavaScript(TidalCyclesベース)です。そのため、自分で関数(Function)を作って複雑な処理を型化し、コードを劇的にすっきりさせることができます。
- 複雑なエフェクトや音作りのセットを「関数」として定義する
const myGuitarFX = (pattern) => pattern
.note()
.transpose("<0@9 -5 -7 0@4 ~ 0@2 -5 -7 ~@2>/48")
.s("gm_acoustic_guitar_steel:2");
// 定義した関数を呼び出すだけで、スッキリ記述できる
setcpm(200)
myGuitarFX(
"<0@5 1 0 1 0@3 ~@2 0 ~ 0@4 ~@2 >/48"
.pickRestart([
stack("<c3@9 c#3 c3@2>","<g3 f3@2 g3@4 f3 g3 g#3 g3 f3>".add("<0,5>")).struct("<x!4 ~!2 x!9 x@3 x!6>")
])
)
- ロジックの分離:
さきほどの「難しいギター」のコードも、音程移動(transpose)や音色指定(s)の部分を myGuitarFX という関数に分離することで、メインラインの可読性が上がります。 - プログラマブルな音楽制作:
共通のリズムパターンや、お気に入りの音響効果(ディレイやリバーブの組み合わせなど)を関数化して使い回す、プログラミングならではの効率的な作曲が可能です。
7.主な関数の一覧です。
音源・サンプルの指定 (Sources)
音を鳴らすための基本となる関数です。
- s() / sound(): サンプル音源(ドラム、楽器など)の名前を指定する(例: s("bd sd"))。
- n(): 音程やノート番号、サンプル内のインデックスを指定する(例: n("c3 e3 g3"))。
- note(): n() と同様に、文字列や数値で音高(ノート)を指定する。
- pitch(): 再生ピッチ(倍率)を直接指定する。
メロディ・和音の制御 (Pitch & Scale)
音階やコード(和音)を扱うための関数です。
- scale(): 特定の音階(マイナー、メジャーなど)を適用する(例: .scale("C4:minor"))。
- transpose(): パターンの音程を半音単位で移調(ずらす)する。
- add(): ノート番号や数値パターンに、指定した数値を足す。
時間・リズムの変形 (Time & Rhythm)
パターンの再生速度やタイミングを操作する関数です。
- slow(): パターンの再生スピードを遅くする(例: .slow(2) で2倍の長さに延ばす)。
- fast(): パターンの再生スピードを速くする(例: .fast(2) で2倍速にする)。
- hurry(): スピードを速くすると同時に、ピッチ(音高)も上げる。
- rev(): パターンを後ろから前に逆再生する。
- ply(): 1つのステップを、指定した回数だけ細かく分割して連打する(例: .ply(3))。
エフェクト・音響効果 (Effects)
音の響きやステレオ感をコントロールする関数です。
- room() / reverb(): リバーブ(残響)の深さを調整する(0 〜 1)。
- delay() / delaytime(): ディレイ(やまびこ効果)の量とディレイタイムを設定する。
- cutoff() / lp(): ローパスフィルターの遮断周波数を指定する(音をこもらせる)。
- pan(): 音の左右の定位(パンニング)を設定する(0が左、0.5が中央、1が右)。
- gain(): 個々のパターンの音量を調節する。
構造・スタック (Structure)
複数のパターンを重ねたり、組み合わせたりする関数です。
- stack(): 複数の異なるパターンを同時に並列で重ねて再生する。
- struct(): 別のパターンの「リズムの形(構造)」だけを抽出して適用する。
- jux(): ステレオの片チャンネル(右耳など)にだけ、指定したエフェクトや変形を適用する。
視覚化・ビジュアル (Visualization)
作成したパターンを画面上に表示するための関数です。
- pianoroll(): パターンの音階やタイミングを、DAWのようなピアノロール形式で画面に描画する。
- punchcard(): パターンをドット状のパンチカード形式でビジュアル表示する。
- scope(): 波形を表示する。
8.サンプルコード (曲を書いてみよう。)
以上。