Skip to content

生成パイプライン

MIDI Sketchのステップバイステップの音楽生成プロセスを解説します。

パイプライン概要

フェーズ1: 構造構築

StructurePatternに基づいて楽曲構造を作成:

cpp
void Generator::buildStructure() {
    arrangement_ = StructureBuilder::build(params_.structure);
}

構造パターン

パターン小節数セクション
StandardPop24A(8)-B(8)-Chorus(8)
BuildUp28Intro(4)-A(8)-B(8)-Chorus(8)
DirectChorus16A(8)-Chorus(8)
RepeatChorus32A(8)-B(8)-Chorus(8)-Chorus(8)
FullPop56Intro-A-B-Chorus-A-B-Chorus-Outro
FullWithBridge52Intro-A-B-Chorus-Bridge-Chorus-Outro
Ballad56Intro(8)-A-B-Chorus-Interlude-B-Chorus-Outro
ExtendedFull90拡張セクション付きフル形式

セクションタイプ

各セクションは生成に影響するプロパティを持つ:

cpp
struct Section {
    SectionType type;         // Intro, A, B, Chorus, Bridge, Interlude, Outro
    uint8_t bars;             // 小節数
    VocalDensity vocal_density;    // Full, Sparse, None
    BackingDensity backing_density; // Normal, Thin, Thick
};

フェーズ2: リズムセクション

ベース生成

ベースは和声の基礎として最初に生成:

ベースパターン:

  • Sparse: 1拍目と3拍目に4分音符(バラード、チル)
  • Standard: 時々8分音符を含む4分音符リズム
  • Driving: アプローチノート付き8分音符パターン

コード生成

コードボイシングはベース分析を使用して協調:

cpp
void Generator::generateChord() {
    BassAnalysis bassAnalysis = analyzeBass(song_.bass);
    // ベースがルートを持つ場合はルートレスボイシング
    if (bassAnalysis.hasRootOnBeat1) {
        useRootlessVoicing();
    }
}

ボイスリーディングアルゴリズム:

  1. 連続するボイシング間の距離を計算
  2. 動きを最小化(半音距離の合計)
  3. 共通音を最大限保持
  4. 遷移を最適化するために転回形を適用

ドラム生成

ドラムパターンはムードに基づいて選択:

スタイル特徴使用ムード
Sparseハーフタイム、ミニマルBallad, Chill
Standard8分ハイハット、2&4スネアStraightPop
FourOnFloor4つ打ちキックElectroPop, IdolPop
Upbeatシンコペーション、16分ハイハットBrightUpbeat
Rockライドシンバル、クラッシュアクセントLightRock
Synthタイトな16分ハイハットYoasobi, Synthwave

フィル生成:

  • タムの下降/上昇パターン
  • スネアロール
  • セクション遷移でのコンビネーションフィル

フェーズ3: メロディ生成

ボーカルトラック

フレーズキャッシュを持つ最も複雑な生成器:

ボーカルアティチュード:

アティチュード特徴
Cleanコードトーンのみ、オンビートリズム
Expressive遅延解決のテンション、微妙なタイミング変動
Raw非コードトーン、フレーズ境界の破壊

非コードトーン:

  • 4-3サスペンション
  • アンティシペーション
  • パッシングトーン
  • ネイバートーン

モチーフトラック(BackgroundMotifスタイル)

繰り返しパターンを生成:

cpp
MotifParams params {
    .length = MotifLength::TwoBars,    // 2または4小節
    .rhythm_density = RhythmDensity::Medium,
    .motion = MotifMotion::Stepwise,
    .repeat_scope = RepeatScope::FullSong
};

アルペジオトラック(SynthDrivenスタイル)

アルペジオパターンを生成:

cpp
ArpeggioParams params {
    .pattern = ArpeggioPattern::UpDown,
    .speed = ArpeggioSpeed::Sixteenth,
    .octave_range = 2,
    .gate = 0.5f  // ノート長比率
};

フェーズ4: 仕上げ

トランジション・ダイナミクス

エネルギー遷移を自動適用:

セクションエネルギー倍率:

セクション倍率
Intro0.75
A0.85
B1.00
Chorus1.20
Bridge0.90
Outro0.80

ヒューマナイズ

タイミングとベロシティに自然な揺らぎを追加:

cpp
void applyHumanization(Song& song, float intensity) {
    // タイミング: ランダムオフセット ±ms
    // ベロシティ: ランダム ±値
    // ドラムには適用しない
}

MIDI出力

最後に、SongをSMF Type 1に変換:

トラックマッピング:

トラックチャンネルプログラム
Vocal00(ピアノ)
Chord14(エレピ)
Bass233(エレベ)
Motif381(シンセリード)
Arpeggio481(ソウリード)
Drums9GMドラム
SE15テキストイベント

キー移調

全ての生成はCメジャーで行われ、出力時に移調が適用:

cpp
uint8_t MidiWriter::transposePitch(uint8_t pitch, Key key) {
    return pitch + static_cast<uint8_t>(key);
}

Released under the MIT License.