パターン集(レシピ)
すぐ使える実用パターン集です。コピペして元ノート / クリップ長を変えるだけで動きます。前提は 既定の stepsPerBeat = 4(16 分グリッド)。
各レシピには使うヘルパー (🛠)、目的 (🎯) を 1 行で付記しています。詳しいヘルパーの仕様は 音楽ヘルパー / 数値ヘルパー / ホスト API を参照。
やりたいことから探す
Section titled “やりたいことから探す”| やりたいこと | レシピ |
|---|---|
| 入力ノートを加工する | オクターブダブリング ・ 5 度ハモリ ・ スケールスナップ ・ 2 倍速 |
| ドラムパターンを作る | 4 つ打ち + スネア + HH ・ ユークリッド |
| アルペジオを作る | chord で和音を分散 ・ 元ノートを基音にしたアルペジエータ |
| コード進行を書く | I-IV-V-I |
| メロディを生成する | drunk() ・ urn() |
| LFO / オートメーション | velocity LFO ・ CC1 三角波 LFO ・ CC11 ADSR |
| 確率的に変化させる | HOF チェイン ・ 確率的ハーモナイズ ・ 再現可能な乱数 |
| 解像度を変える | 三連符 ・ シャッフル |
入力ノートを加工する
Section titled “入力ノートを加工する”オクターブダブリング・エコー
Section titled “オクターブダブリング・エコー”🛠
onNote,setNote・ 🎯 元ノートに 1 オクターブ上の遅れたコピーを追加(厚み + ステレオ感)
onNote((n) => { setNote({ ...n }); // 元ノート保持 setNote({ pitch: n.pitch + 12, // オクターブ上 velocity: Math.round(n.velocity * 0.7), // 70% velocity startBeat: n.startBeat + 0.5, // 半拍遅らせる lengthBeats: n.lengthBeats, });});5 度上のハモリを足す
Section titled “5 度上のハモリを足す”🛠
onNote,setNote・ 🎯 各ノートに 5 度(+7 半音)のハモリを重ねる
onNote((n) => { setNote({ ...n }); setNote({ ...n, pitch: n.pitch + 7, velocity: Math.round(n.velocity * 0.8) });});スケールスナップ(フィルター)
Section titled “スケールスナップ(フィルター)”入力ノートをスケール内の音に丸める。
🛠
scale,onNote,setNote・ 🎯 外れた音を半音下げてスケール内に収める
const sc = scale("minor", 60);const allowed = new Set(sc.map((p) => p % 12));onNote((n) => { if (allowed.has(n.pitch % 12)) { setNote({ ...n }); } else { setNote({ ...n, pitch: n.pitch - 1 }); // 半音下げてスケールへ }});元ノートを 2 倍速で再生
Section titled “元ノートを 2 倍速で再生”startBeat と lengthBeats を半分にする。クリップ長を超えるノートは自動で切り詰められません — 必要なら自前でクリップ。
🛠
onNote,setNote・ 🎯 入力フレーズを 2 倍速で詰めて再生
onNote((n) => { setNote({ ...n, startBeat: n.startBeat / 2, lengthBeats: n.lengthBeats / 2, });});ジェネレータ(元ノート不要)
Section titled “ジェネレータ(元ノート不要)”ユークリッド + マイナースケールでアルペジオ
Section titled “ユークリッド + マイナースケールでアルペジオ”🛠
euclid,scale,degree,onBeat,setNote・ 🎯 5/16 ユークリッドリズムにスケール音を当てたアルペジオ
const pat = euclid(5, 16);const sc = scale("minor", 60);onBeat((b) => { const i = Math.floor(b * 4); // 16 分の通し番号 if (pat[i % pat.length]) { setNote({ pitch: degree(sc, i % sc.length), startBeat: b, lengthBeats: 0.25, }); }});4 つ打ちキック + 裏拍スネア + 8 分ハイハット
Section titled “4 つ打ちキック + 裏拍スネア + 8 分ハイハット”🛠
onBeat,noteOn・ 🎯 ハウス/4 つ打ちの基本ドラムパターン
onBeat((b) => { if (Number.isInteger(b)) noteOn(36, 0.1, 100, b); // キック if (Math.abs((b % 1) - 0.5) < 1e-6 && b >= 1) noteOn(38, 0.1, 90, b); // スネア(2,4 拍) if (Math.abs((b * 2) % 1) < 1e-6) noteOn(42, 0.05, 70, b); // 8 分ハットHH});chord で和音を分散(アルペジオ)
Section titled “chord で和音を分散(アルペジオ)”🛠
chord,onInit,setNote・ 🎯 maj7 の和音を 16 分音符で 1 音ずつ分散
const ch = chord("maj7", 60);onInit(() => { ch.forEach((p, i) => { setNote({ pitch: p, startBeat: i * 0.25, lengthBeats: 1 }); });});コード進行 I-IV-V-I
Section titled “コード進行 I-IV-V-I”🛠
chord,transpose,onInit,setNote・ 🎯 1 小節 = 1 コードで 4 小節分の進行を全音発音
const I = chord("maj", 60);const IV = transpose(I, 5);const V = transpose(I, 7);const prog = [I, IV, V, I];
onInit(() => { prog.forEach((ch, bar) => { ch.forEach((p) => setNote({ pitch: p, startBeat: bar, lengthBeats: 1 })); });});drunk() でランダムウォークメロディ
Section titled “drunk() でランダムウォークメロディ”🛠
drunk,onBeat,setNote・ 🎯 中心 60、最大歩幅 3 半音、48〜84 範囲のランダムウォーク
const d = drunk(60, 3, 48, 84);onBeat((b) => { if (Math.abs(b % 0.5) < 1e-6) { setNote({ pitch: d(), startBeat: b, lengthBeats: 0.5 }); }});urn() で 7 音を一様にランダム配列
Section titled “urn() で 7 音を一様にランダム配列”🛠
scale,urn,onBeat,setNote・ 🎯 マイナースケール 7 音をランダムに(重複なし)配置
const sc = scale("minor", 60);const u = urn(sc.length);onBeat((b) => { if (Math.abs((b * 2) % 1) < 1e-6) { // 8 分ごと setNote({ pitch: sc[u()], startBeat: b, lengthBeats: 0.5 }); }});元ノートと混ぜる
Section titled “元ノートと混ぜる”既存ノートを保持しつつレイヤーを追加
Section titled “既存ノートを保持しつつレイヤーを追加”🛠
onNote,onBeat,noteOn・ 🎯 元ノートをそのまま残しつつ HH を上から重ねる
onNote((n) => setNote({ ...n })); // 元ノート保持onBeat((b) => { // ハイハットを上から重ねる if (Math.abs((b * 2) % 1) < 1e-6) noteOn(42, 0.05, 70, b);});元ノートのリズムだけ使ってピッチを置き換え
Section titled “元ノートのリズムだけ使ってピッチを置き換え”🛠
scale,degree,onNote,setNote・ 🎯 タイミングは入力のまま、ピッチをドリアン上に再割当
const sc = scale("dorian", 60);let i = 0;onNote((n) => { setNote({ ...n, pitch: degree(sc, i), }); i += 1;});モジュレーション(LFO・エンベロープ・CC)
Section titled “モジュレーション(LFO・エンベロープ・CC)”LFO で velocity を揺らす
Section titled “LFO で velocity を揺らす”🛠
lfo,onNote,setNote・ 🎯 サイン LFO で velocity を 70〜110 の間で揺らす
onNote((n) => { const phase = n.startBeat / CLIP_LENGTH; setNote({ ...n, velocity: 90 + 20 * lfo(phase, "sin") });});CC1(modulation)に三角波 LFO
Section titled “CC1(modulation)に三角波 LFO”🛠
lfo,onBeat,setCc・ 🎯 クリップ全体で 2 周期の三角波で CC1 を 14〜114 に揺らす
onBeat((b) => { const phase = b / CLIP_LENGTH; setCc({ ccNumber: 1, beat: b, value: 64 + 50 * lfo(phase * 2, "tri") });});envelope で CC11(expression)の ADSR
Section titled “envelope で CC11(expression)の ADSR”🛠
envelope,onBeat,setCc・ 🎯 ブレークポイント指定で CC11 にアタック→サステイン→リリース
const adsr = [ [0, 0], [0.25, 110], [0.5, 80], [3.5, 80], [4, 0],];onBeat((b) => { setCc({ ccNumber: 11, beat: b, value: envelope(adsr, b) });});velocity → CC11 への変換
Section titled “velocity → CC11 への変換”🛠
onNote,setCc・ 🎯 各ノートの velocity を同じ beat の CC11 として書き出す
onNote((n) => { setNote({ ...n }); setCc({ ccNumber: 11, beat: n.startBeat, value: n.velocity });});既存 CC を半分に
Section titled “既存 CC を半分に”🛠
onCc,sampleCc,setCc・ 🎯 入力 CC7 を一定グリッドでサンプル → 半分の値で書き戻し
// 入力 CC7 を半分の値で書き戻す。固定グリッドで掃引されるので、// 元のブレークポイント数に関係なく滑らかに出力される。onCc(({ beat }) => { const base = sampleCc(7, beat); setCc({ ccNumber: 7, value: Math.round(base * 0.5) });});CC1 にサイン LFO
Section titled “CC1 にサイン LFO”🛠
setCcResolution,onCc,setCc・ 🎯 高解像度(32 / beat)でクリップ全体に 1 周期のサイン LFO
// クリップ全体で 1 周期。解像度を上げるほど滑らか。onInit(() => setCcResolution(32));onCc(({ phase }) => { setCc({ ccNumber: 1, value: 64 + 32 * Math.sin(phase * 2 * Math.PI) });});modCc で「読んで → 加工して → 書き戻す」を 1 行
Section titled “modCc で「読んで → 加工して → 書き戻す」を 1 行”🛠
modCc,lfo,onCc・ 🎯 入力 CC7 に LFO を加算(factory.js のラッパ関数)
// factory.js の modCc は sampleCc + clamp + setCc のラッパ。onCc(modCc(7, (v, phase) => v + 10 * lfo(phase, "sin")));確率・パターン操作
Section titled “確率・パターン操作”HOF をチェイン
Section titled “HOF をチェイン”🛠
every,sometimes,onBeat,setNote・ 🎯 4 ステップに 1 度かつ 50% で発火(期待値 1/8)
// 4 ステップに 1 度かつ 50% 確率で発火(期待値 1/8)onBeat( every( 4, sometimes(0.5, (b) => { setNote({ pitch: 60, startBeat: b, lengthBeats: 0.25 }); }), ),);確率的ハーモナイズ
Section titled “確率的ハーモナイズ”🛠
chance,weighted,onNote,setNote・ 🎯 60% 確率でハモリ追加、ハモリ間隔は重み付き分布で選ぶ
const intervals = [0, 7, 12]; // ユニゾン / 5 度 / オクターブconst w = [3, 5, 2]; // 5 度を多めに
onNote((n) => { setNote({ ...n }); // 元ノート保持 if (chance(0.6)) { // 60% の確率でハモリ追加 const semi = weighted(intervals, w); setNote({ ...n, pitch: n.pitch + semi, velocity: Math.round(n.velocity * 0.7), }); }});再現可能な乱数
Section titled “再現可能な乱数”🛠
seed,seededRandom,onNote,setNote・ 🎯 文字列シードで毎回同じピッチオフセットを出す
seed("variation-A"); // 文字列で固定onNote((n) => { const offset = Math.floor(seededRandom() * 12) - 6; // -6..+5 setNote({ ...n, pitch: n.pitch + offset });});解像度を変える
Section titled “解像度を変える”三連符(1 拍を 3 分割)
Section titled “三連符(1 拍を 3 分割)”🛠
onBeat,setNote・ 🎯 1 拍を 3 分割した 3 連符
onBeat((b) => { if (Math.abs((b * 3) % 1) < 1e-6) { setNote({ pitch: 67, startBeat: b, lengthBeats: 1 / 3 }); }});8 分シャッフル
Section titled “8 分シャッフル”🛠
onBeat,setNote・ 🎯 8 分グリッドの裏拍を 0.05 beat 後ろにずらすシャッフル感
onBeat((b) => { // 8 分グリッドで、裏は少し遅らせる if (Math.abs((b * 2) % 1) < 1e-6) { const isOff = Math.abs((b % 1) - 0.5) < 1e-6; setNote({ pitch: 60, startBeat: b + (isOff ? 0.05 : 0), lengthBeats: 0.25, }); }});スタッター(同じピッチを連打)
Section titled “スタッター(同じピッチを連打)”🛠
onNote,setNote・ 🎯 1 ノートを 4 分割し、velocity を徐々に減衰させて連打
onNote((n) => { const reps = 4; for (let i = 0; i < reps; i++) { setNote({ ...n, startBeat: n.startBeat + (i / reps) * n.lengthBeats, lengthBeats: n.lengthBeats / reps, velocity: Math.round(n.velocity * (1 - i * 0.15)), // 徐々に減衰 }); }});元ノートを基音にしたアルペジエータ
Section titled “元ノートを基音にしたアルペジエータ”🛠
onNote,setNote・ 🎯 入力ピッチをルートとして 1度→5度→8度→5度を分散
const pattern = [0, 7, 12, 7]; // 1度・5度・オクターブ・5度onNote((n) => { pattern.forEach((semi, i) => { setNote({ ...n, pitch: n.pitch + semi, startBeat: n.startBeat + i * (n.lengthBeats / pattern.length), lengthBeats: n.lengthBeats / pattern.length, }); });});確率分布を時間で変える(左から右へ密度が上がる)
Section titled “確率分布を時間で変える(左から右へ密度が上がる)”🛠
chance,pick,scale,onBeat,setNote・ 🎯 クリップの後半ほど発音密度が上がるビルドアップ
onBeat((b) => { const density = b / CLIP_LENGTH; // 0..1 if (chance(density)) { setNote({ pitch: pick(scale("pentaMinor", 60)), startBeat: b, lengthBeats: 0.25, }); }});元ノートをコードに展開
Section titled “元ノートをコードに展開”各元ノートを「そのピッチをルートとするコード」として鳴らす。
🛠
chord,onNote,setNote・ 🎯 入力 1 音を min7 コードに展開(同タイミング・同長)
onNote((n) => { chord("min7", n.pitch).forEach((p) => { setNote({ pitch: p, velocity: n.velocity, startBeat: n.startBeat, lengthBeats: n.lengthBeats, }); });});