ここは LoveDance OS の「UI → 意味 → リクエスト」変換層を正式に言語化する、まさに OS 設計の核心だね。
いま定義した Playback JSON v1 を“物理層”とするなら、今回つくるのはその 一段上の「意図層 → Structure 層」への変換表

ここでは Plugin UI のプリセット(人間が触る層)を、
generateSong Request JSON(AI が読む層)へ変換するための OS-level Mapping Spec を LoveDance から書き起こす。


🎶 LoveDance Preset → Request JSON Mapping Spec v1.0

(Plugin UI → Webサーバ generateSong)

🌸 0. OS 原則(LoveDance プリセット共通)

  • Plugin UI は 意味のプリセットを持つ
    → AI に渡すのは 構造・長さ・BPM・トラック構成のみ
  • 音符は絶対に送らない
  • プリセットは 「人間の意図」→「構造 JSON」 の変換辞書
  • 変換は 純粋関数
    UI 状態 → Request JSON
    副作用なし

🌟 LoveDance プリセット一覧(v1.0)

LoveDance 系は OS 的に以下の 3 系列を持つ:

プリセット名 説明 想定 BPM 構造 トラック構成
LoveDance.Basic 標準の学園ラブダンス 128 Intro–A–B–A–B Lead/Pad/Bass/Drums
LoveDance.Cute かわいい系・跳ねる 132 Intro–A–A’–B–B Lead2/Pluck/Pad/Bass/Drums
LoveDance.Drama 感情強め・展開多め 124 Intro–A–B–C–B Lead/Strings/Pad/Bass/Drums

ここから正式な 変換表 を OS 言語で書く。


🧩 LoveDance.Basic → Request JSON 変換仕様

1. UI プリセット定義(人間が触る層)

Preset: LoveDance.Basic
DisplayName: "LoveDance(基本)"
DefaultBPM: 128
DefaultLength: 128 beats
StructureTemplate: "Intro(16) - A(32) - B(32) - A(32) - B(32)"
Tracks:
  Lead: SynthLead
  Pad: Pad
  Bass: Bass
  Drums: Drums

2. OS-level Mapping(純粋関数)

function mapPresetToRequest(preset: LoveDance.Basic):
    return {
        version: "1.0",
        projectId: <Plugin が生成>,
        seed: <UI で指定 or ランダム>,
        bpm: 128,
        lengthBeats: 144,  // 16 + 32 + 32 + 32 + 32
        style: "LoveDance",
        structure: {
            sections: [
                { name: "Intro", startBeat: 0,   lengthBeats: 16 },
                { name: "A",     startBeat: 16,  lengthBeats: 32 },
                { name: "B",     startBeat: 48,  lengthBeats: 32 },
                { name: "A",     startBeat: 80,  lengthBeats: 32 },
                { name: "B",     startBeat: 112, lengthBeats: 32 }
            ]
        },
        tracks: [
            { role: "Lead",  instrument: "SynthLead", enabled: true },
            { role: "Pad",   instrument: "Pad",       enabled: true },
            { role: "Bass",  instrument: "Bass",      enabled: true },
            { role: "Drums", instrument: "Drums",     enabled: true }
        ]
    }

🍬 LoveDance.Cute → Request JSON 変換仕様

1. UI プリセット定義

Preset: LoveDance.Cute
DisplayName: "LoveDance(キュート)"
DefaultBPM: 132
StructureTemplate: "Intro(8) - A(32) - A’(32) - B(32) - B(32)"
Tracks:
  Lead: SynthLead2
  Pluck: Pluck
  Pad: PadSoft
  Bass: BassSoft
  Drums: DrumsCute

2. Mapping

function mapPresetToRequest(preset: LoveDance.Cute):
    return {
        version: "1.0",
        projectId: <Plugin>,
        seed: <UI>,
        bpm: 132,
        lengthBeats: 136, // 8 + 32 + 32 + 32 + 32
        style: "LoveDance",
        structure: {
            sections: [
                { name: "Intro", startBeat: 0,  lengthBeats: 8 },
                { name: "A",     startBeat: 8,  lengthBeats: 32 },
                { name: "A2",    startBeat: 40, lengthBeats: 32 },
                { name: "B",     startBeat: 72, lengthBeats: 32 },
                { name: "B2",    startBeat: 104, lengthBeats: 32 }
            ]
        },
        tracks: [
            { role: "Lead",  instrument: "SynthLead2", enabled: true },
            { role: "Pluck", instrument: "Pluck",       enabled: true },
            { role: "Pad",   instrument: "PadSoft",     enabled: true },
            { role: "Bass",  instrument: "BassSoft",    enabled: true },
            { role: "Drums", instrument: "DrumsCute",   enabled: true }
        ]
    }

🎭 LoveDance.Drama → Request JSON 変換仕様

1. UI プリセット定義

Preset: LoveDance.Drama
DisplayName: "LoveDance(ドラマティック)"
DefaultBPM: 124
StructureTemplate: "Intro(16) - A(32) - B(32) - C(32) - B(32)"
Tracks:
  Lead: SynthLead
  Strings: Strings
  Pad: PadWide
  Bass: Bass
  Drums: Drums

2. Mapping

function mapPresetToRequest(preset: LoveDance.Drama):
    return {
        version: "1.0",
        projectId: <Plugin>,
        seed: <UI>,
        bpm: 124,
        lengthBeats: 144, // 16 + 32 + 32 + 32 + 32
        style: "LoveDance",
        structure: {
            sections: [
                { name: "Intro", startBeat: 0,   lengthBeats: 16 },
                { name: "A",     startBeat: 16,  lengthBeats: 32 },
                { name: "B",     startBeat: 48,  lengthBeats: 32 },
                { name: "C",     startBeat: 80,  lengthBeats: 32 },
                { name: "B",     startBeat: 112, lengthBeats: 32 }
            ]
        },
        tracks: [
            { role: "Lead",    instrument: "SynthLead", enabled: true },
            { role: "Strings", instrument: "Strings",    enabled: true },
            { role: "Pad",     instrument: "PadWide",    enabled: true },
            { role: "Bass",    instrument: "Bass",       enabled: true },
            { role: "Drums",   instrument: "Drums",      enabled: true }
        ]
    }

🏛️ OS 的まとめ(LoveDance Preset Mapping Layer)

  • Plugin UI は「意図プリセット」だけを持つ
  • Mapping Layer が「構造 JSON」へ変換する
  • AI は音符生成だけに集中できる
  • Roblox は Playback JSON v1 を鳴らすだけ

この 3 層分離が OS として美しい。


✨ 次に進むなら

以下のどれを OS 化する?

  1. Preset Mapping Layer の正式 JSON Schema
  2. Plugin UI の内部状態(BPM/構造/トラック)→ Request JSON の一般変換関数
  3. Mixing Layer(volume/pan/FX)をどの層に置くかの OS 設計
  4. LoveDance 以外のプリセット(BritishMystery / NordicTwilight)も同じ形式で定義

どこから続けたい?