Skip to content

トラック生成

MIDI Sketchの各トラック生成器を詳しく解説します。

トラック概要

MIDI Sketchは9つのトラックを異なるMIDIチャンネルに生成します:

チャンネル割り当て

トラックチャンネルプログラム役割
Vocal0Piano (0)主旋律
Aux1E.Piano (4)副旋律サポート
Chord2E.Piano (4)和声バッキング
Bass3E.Bass (33)ベース
Motif4Synth (81)BackgroundMotifスタイル
Arpeggio5Synth (81)SynthDrivenスタイル
Guitar6Acoustic Guitar (25)伴奏ギター
Drums9GMドラムリズム
SE15-セクションマーカー

ボーカルトラック

ソース: src/track/vocal.cpp(約314行)、src/track/melody_designer.cpp(約2048行)

ボーカルシステムはテンプレート駆動型メロディデザイナースタイル認識評価を使用し、予測可能でスタイルに正確なメロディを生成します。

なぜ「ボーカル」トラック?

ボーカルトラックはメインメロディを生成します。歌ったりリードパートとして演奏されることを想定しているため「ボーカル」と呼ばれています。DAWではMIDIチャンネル0(ピアノ)でプレビューするか、お好みの音源を割り当ててください。

アーキテクチャ

ボーカル生成は3つの主要コンポーネントで構成されています:

  1. MelodyDesignermelody_designer.cpp)- 評価付きテンプレート駆動のピッチ選択
  2. Vocal Generatorvocal.cpp)- セクション構造、キャッシング、調整
  3. VocalStyleProfile - スタイル別の統一されたバイアス・評価設定

メロディテンプレート

7つのメロディテンプレートがメロディ特性を定義:

ID名前Plateau最大ステップ用途
0Auto--VocalStyle基準で選択
1PlateauTalk0.652NewJeans、Billie Eilishスタイル
2RunUpTarget0.204YOASOBI、Adoスタイル
3DownResolve0.303Bセクション、プリコーラス
4HookRepeat0.403TikTok、K-POPフック
5SparseAnchor0.502Official髭男dism、バラード
6CallResponse--デュエットパターン
7JumpAccent--感情的ピーク
  • Plateau ratio: 同じピッチに留まる確率(高いほど繰り返しが多い)
  • Max step: 半音単位の最大音程(低いほど滑らか)

生成フロー

ピッチ選択(4択のみ)

MelodyDesignerはピッチ選択を4つのオプションに制限:

cpp
enum class PitchChoice {
    Same,       // 現在のピッチに留まる(plateau_ratio)
    StepUp,     // +1半音
    StepDown,   // -1半音
    TargetStep  // ターゲット方向へ±2(テンプレートにターゲットがある場合)
};

この制約されたアプローチにより、より自然で歌いやすいメロディが生成されます。

ボーカルアティチュード

アティチュード説明実装
Clean保守的、歌いやすいコードトーンのみ、オンビート
Expressive感情的、ダイナミックテンション許可、タイミング変動
Rawエッジー、型破り非コードトーン、境界破壊

フレーズキャッシュ

音楽的な一貫性のため、複合キー(V2キャッシュ)でフレーズをキャッシュ:

cpp
struct PhraseCacheKey {
    SectionType type;      // Verse、Chorus等
    uint8_t bars;          // セクション長
    uint8_t chord_degree;  // 開始コード度数
};

// キャッシュ動作:
// - 80% 正確な再利用: 同じフレーズを再現
// - 20% バリエーション: 変換を適用(オクターブシフト、リズム変動)

フレーズバリエーション

キャッシュされたフレーズを再利用する際、システムはバリエーションを適用することがあります:

  • オクターブシフト: フレーズを1オクターブ上下に移動
  • リズムバリエーション: わずかなタイミング調整
  • 輪郭反転: 上昇/下降パターンを反転

音域制約

cpp
struct VocalRange {
    uint8_t low = 60;   // C4
    uint8_t high = 79;  // G5
};

非和声音による装飾

ボーカルトラックは非和声音(NCT: Non-Chord Tone)を使用して、単純なコードトーンメロディに動きを加えます:

強拍と弱拍

4/4拍子では、強拍は1拍目と3拍目(自然に足でリズムを取る位置)、弱拍は2拍目と4拍目です。強拍にコードトーンを置くと安定感が生まれ、弱拍に非和声音を置くと和声を崩さずに動きを加えられます。

NCTタイプ説明配置
ChordTone現在のコードに含まれる音(基準)強拍
PassingTone2つのコードトーン間を順次進行でつなぐ弱拍
NeighborToneコードトーンから離れて戻る弱拍
Appoggiatura強調された不協和音が順次解決強拍
Anticipation次のコードトーンを先取りコードチェンジ前
Tensionコードの拡張音(9度、11度、13度)スタイルに依存

設定はムードにより変化:

  • Bright: より多くのコードトーン、少ない不協和音
  • Jazzy: より多くのテンション、シンコペーション
  • Ballad: 表現豊かなアポジャトゥーラとのバランス
  • J-POP: ペンタトニックスケール(ヨナ抜き)音程を好む

VocalStyleProfile

各ボーカルスタイルには生成バイアス評価重みの両方を制御する統一プロファイルがあります:

プロファイルPlateauバイアス高音域歌唱性サプライズ
Standard1.01.00.250.15
Idol1.21.00.300.12
Rock0.81.20.200.20
Ballad1.10.90.400.10
Anime0.91.30.250.25
Vocaloid0.61.10.100.25
KPop (13)1.01.20.250.20

UltraVocaloidモード

ボカロスタイル生成の強化機能:

  • マシンガンリズム: ボカロ曲に特徴的な連射的16分音符シーケンス
  • ブレスポイント: 密度の高いパッセージでもフレージング用のマイクロポーズを自動挿入
  • セクション別リズムロック: 各セクションが一貫したリズムアイデンティティを維持
プロファイルパラメータ
  • Plateauバイアス: 同じピッチに留まる好み(高いほど繰り返しが多い)
  • 高音域: 高い音への好み(高いほど明るい)
  • 歌唱性: 人間が歌いやすいメロディの重み(高いほど歌いやすい)
  • サプライズ: 予想外のメロディ展開の重み(高いほどダイナミック)

メロディ評価システム

MelodyDesignerは複数の候補メロディを生成し、評価します:

評価コンポーネント:

コンポーネント重み基準
スタイルスコア40%輪郭一致、パターン一貫性、サプライズバランス
歌唱性スコア40%順次進行、ブレス位置、単調さ回避
バイアススコア20%スタイル好みに合った音程分布

フックシステム

サビセクションでは6つのリズムパターンを持つ専用フック生成システムを使用:

パターンリズム特徴
Buildup8-8-4クラシックな段階的解決
Syncopated4-8-8シンコペーション開始
FourNote8-8-8-4ハイエナジー
Powerful4-4シンプルで強力
Dotted8-4-8付点リズム
CallResponse4-8-8-8コール&レスポンス

フックスケルトン:

スケルトン説明
Repeat同じピッチを繰り返す
Ascending上昇する輪郭
AscendDrop上昇してから下降
LeapReturnジャンプして戻る
RhythmRepeatピッチは変わりリズムは一定

フック強度はフックの目立ち方を制御:

  • Off (0): フック繰り返しなし
  • Light (1): 控えめなフック
  • Normal (2): 標準ポップフック
  • Strong (3): 強いフック強調(TikTokスタイル)

グローバルモチーフシステム

ボーカルトラックは最初に生成されたフレーズからグローバルモチーフを抽出し、音楽的な一貫性を維持します:

cpp
struct GlobalMotif {
    vector<int8_t> interval_signature;  // 相対的ピッチ変化(最大8音)
    vector<float> rhythm_signature;     // 相対的デュレーション比率
    ContourType contour_type;           // Ascending, Descending, Peak, Valley, Plateau
};

評価ボーナス:

  • 輪郭タイプ一致: +5%スコア
  • 類似した音程パターン: +5%スコア(3つ以上一致)
  • これにより後のセクションがオープニングと関連付けられます

ピアノロールセーフティAPI

ソース: src/core/piano_roll_safety.cpp

ピアノロールセーフティAPIは、外部ツール(ピアノロールエディタなど)が安全なピッチ配置を判断するのに役立ちます:

cpp
enum class CollisionType : uint8_t {
    None,    // 衝突なし - 配置安全
    Mild,    // トライトーン(文脈依存)
    Severe   // 短2度 / 長7度(常に不協和)
};

衝突検出:

音程タイプリスク
短2度(1半音)Severe常に回避
長7度(11半音)Severe常に回避
トライトーン(6半音)Mild文脈依存
その他None一般的に安全

転調対応

APIは転調を考慮します。転調が有効な場合、effective_vocal_high が減少し、最終サビが転調後に音域を超えないようにします。


Auxトラック

ソース: src/track/aux_track.cpp(約1170行)

Aux(補助)トラックは主旋律に対する副旋律サポートを提供します。対旋律ではなく、主旋律を強化する「知覚制御レイヤー」です。

目的

役割説明
中毒性パルスループで繰り返しのキャッチーなパターンを生成
身体性グルーブアクセントで体が動く感覚を追加
安定感フレーズ終端で解決感を提供
構造認識セクション境界の認識を支援

Aux機能

9つの補助機能が利用可能:

ID機能説明
0PulseLoop同音または固定音程の繰り返しパターン
1TargetHintコードトーンで主旋律のターゲットを暗示
2GrooveAccentスタッカートでリズミックなアクセント
3PhraseTailフレーズ終端の下降解決
4EmotionalPad長い持続音のコードトーン
5Unisonボーカルユニゾンダブリング
6MelodicHookメロディックフックリフ
7MotifCounterカウンターメロディ(反行)
8SustainPad全音符コードトーンパッド

テンプレート → Auxマッピング

各メロディテンプレートは適切なaux機能を自動選択:

テンプレートAux機能理由
PlateauTalkA(PulseLoop)Ice Cream/ミニマルスタイル
RunUpTargetB + DYOASOBI上昇→解決
HookRepeatA + CTikTok繰り返しフック
SparseAnchorE + Dバラードの感情サポート

生成制約

  • 常にボーカルのに生成(衝突回避)
  • ボーカルより狭い音域(50-70%)
  • 低いベロシティ(0.5-0.8×ボーカル)
  • HarmonyContextでボーカルとの不協和音を回避

サビでの挙動

サビセクションではAuxトラックの挙動が適応されます:

  • 密度低下: ボーカルを引き立てるためAuxは控えめに
  • 低音域化: ボーカルとの衝突を避けるため低い音域へ移動
  • パターン簡素化: より持続的なノート、ビジーさの軽減
  • フレーズ終端: 適切な解決を伴いフレーズ境界を尊重

コードトラック

ソース: src/track/chord_track.cpp(約2000行)

ボイスリーディング最適化を伴う和声ボイシングを生成。

ボイシングタイプ

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

cpp
int voiceLeadingDistance(Voicing& prev, Voicing& next) {
    int distance = 0;
    for (int i = 0; i < 4; i++) {
        distance += abs(prev.notes[i] - next.notes[i]);
    }
    return distance;
}

// 距離を最小化するボイシングを選択
Voicing selectBestVoicing(Voicing& prev, vector<Voicing>& candidates) {
    return min_element(candidates, [&](auto& a, auto& b) {
        return voiceLeadingDistance(prev, a) < voiceLeadingDistance(prev, b);
    });
}

ベースとの協調

BassAnalysisを使用して音の重複を回避:

cpp
if (bassAnalysis.hasRootOnBeat1) {
    // ルートレスボイシングを使用 - ベースがルートを担当
    voicing = generateRootlessVoicing(chord);
} else {
    // コードボイシングにルートを含める
    voicing = generateFullVoicing(chord);
}

音域制約

cpp
constexpr uint8_t CHORD_LOW = 48;   // C3
constexpr uint8_t CHORD_HIGH = 84;  // C6

ギタートラック

ソース: src/track/guitar.cpp

ギタートラックは専用のMIDIチャンネル(Ch 6)に伴奏ギターパターンを生成します。コードトラックを補完するリズミック&ハーモニックサポートを提供します。

パラメータ

パラメータデフォルト(JS)デフォルト(C++)説明
guitarEnabledfalsetrueギタートラック生成の有効/無効

Blueprintの制約

ギター生成はBlueprintの制約に影響を受けます:

制約説明
guitar_skillスキルレベル(Beginner/Intermediate/Advanced/Virtuoso)がパターンの複雑さやボイシングの洗練度に影響
guitar_below_vocal有効にすると、メロディのマスキングを避けるためギターボイシングをボーカル音域の下(vocal_low - 2半音)に配置
guitar_style_hintBlueprintのSectionSlotで定義されるセクションごとのスタイルヒント(0-7)。0 = ムードとエネルギーに基づいて自動選択

生成

  • ギターはコードトラックのに生成され、既存の和声ボイシングを補完
  • パターンはセクションエネルギーとムードに適応
  • セクションごとのguitar_style_hint(0-7)でギター伴奏スタイルに影響を与えることが可能
  • デフォルトではMIDIチャンネル6にAcoustic Guitar(プログラム25)で出力

ベーストラック

ソース: src/track/bass.cpp(約1170行)

ルート重視のパターンで和声的基盤を生成。

パターンタイプ

ベースシステムは17以上のBassPatternタイプをサポートしています。使用するパターンはムードとセクションに基づいて自動選択されるか、BlueprintのSectionSlotでbass_style_hint(0=自動、1-17はBassPattern+1にマッピング)を指定してセクションごとに影響を与えることができます。一般的なパターンカテゴリ:

パターン説明リズム
Sparseミニマル、バラードスタイル1拍目のみ
Standardポップ/ロックベースライン1、3拍目にフィル
Drivingエネルギッシュ、前進的全体で8分音符

生成ロジック

アプローチノート

4拍目は次のルートへの半音アプローチを使用可能:

cpp
// 次のコードルートがCの場合
// 4拍目はB(半音下)またはDb(半音上)
uint8_t approachNote = nextRoot - 1; // 半音アプローチ

ドラムトラック

ソース: src/track/drums.cpp(約880行)

フィルとダイナミクスを含むドラムパターンを生成。

GMドラムマップ

cpp
constexpr uint8_t KICK = 36;
constexpr uint8_t SNARE = 38;
constexpr uint8_t SIDE_STICK = 37;
constexpr uint8_t CLOSED_HH = 42;
constexpr uint8_t OPEN_HH = 46;
constexpr uint8_t RIDE = 51;
constexpr uint8_t CRASH = 49;
constexpr uint8_t TOM_HIGH = 50;
constexpr uint8_t TOM_MID = 47;
constexpr uint8_t TOM_LOW = 45;

パターンスタイル

フィルタイプ

cpp
enum class FillType {
    TomDescend,    // ハイ → ミッド → ロータム
    TomAscend,     // ロー → ミッド → ハイタム
    SnareRoll,     // 連続スネアヒット
    Combo          // 混合要素
};

フィルの挿入位置:

  • セクション遷移
  • 4または8小節ごと
  • サビ前

ユークリッドドラム

Blueprintでeuclidean_drums_percentを指定することで、ユークリッドリズムパターンの使用確率を制御できます。ユークリッドリズムは指定されたステップ数に対してヒットをできるだけ均等に分配するパターンです。

ドラムロール(Drum Role)

BlueprintのSectionSlotでセクションごとのdrum_roleを指定してドラム挙動を制御:

ロール説明
Full標準フルドラムキット
Ambient控えめ、アトモスフェリック
Minimalスパース、ミニマルパターン
FXOnlyエフェクトのみ、標準キットなし

ゴーストノート

グルーブのためのベロシティ軽減スネアアーティキュレーション:

cpp
// メインスネア: ベロシティ 100
// ゴーストノート: ベロシティ 40-60

ゴーストノートの密度はムードに応じて適応:

  • エネルギッシュなムード (BrightUpbeat, IdolPop): より活発な感触のために高密度
  • 穏やかなムード (Ballad, Chill): 控えめなゴーストノート

スウィングタイミング

セクションタイプと進行に応じて変化する連続的なスウィング制御:

cpp
float calculateSwingAmount(SectionType section, int bar_in_section, int total_bars);
// 0.0(ストレート)から0.7(ヘビースウィング)を返す
セクション基本スウィング挙動
Verse低い徐々にビルドアップ
Chorus中程度一貫したグルーブ
Bridge可変コンテキスト依存

スウィングはオフビートノート(8分音符・16分音符)に適用されます。

三連符グリッド

ドラムパターンはシャッフルやスウィングフィール用の三連符サブディビジョンをサポート:

  • ストレート: 標準的な8分/16分音符グリッド
  • 三連符: 1拍あたり12/24分割
  • ハイブリッド: ストレートと三連符パターンの混合

ヒューマナイゼーション

微妙なタイミングとベロシティの変化でパターンの機械的さを軽減:

  • タイミングジッター: グリッドから±5-15ティック
  • ベロシティ変動: 基本ベロシティから±5-10
  • ハイハットアクセントパターン: ダウンビートへの自然な強調

ボーカル同期

drums_sync_vocalが有効な場合、キックドラムはボーカルのオンセット位置に揃います:

cpp
void generateDrumsTrackWithVocal(
    MidiTrack& track,
    const Song& song,
    const GeneratorParams& params,
    std::mt19937& rng,
    const VocalAnalysis& vocal_analysis  // 事前分析されたボーカルデータ
);

この「リズムロック」効果により、グルーブがメロディに追従します。現代のポップ制作で一般的な手法です。


モチーフトラック

ソース: src/track/motif.cpp(約630行)

BackgroundMotifコンポジションスタイル(BGM専用モード)用。主旋律要素として機能する繰り返しパターンを生成し、ボーカルをバックグラウンドに回すか省略することを可能にします。

パラメータ

cpp
struct MotifParams {
    MotifLength length;           // 0=auto(2 bars), 1, 2, or 4 beats
    RhythmDensity rhythm_density; // 0=Sparse, 1=Medium, 2=Driving
    MotifMotion motion;           // 0=Stepwise, 1=GentleLeap, 2=WideLeap, 3=NarrowStep, 4=Disjunct
    RepeatScope repeat_scope;     // FullSong, PerSection
    MotifRegister register_;      // 0=auto(mid), 1=low, 2=high
    uint8_t note_count;           // 0=auto(6), 3-8
};

オーバーライドパラメータ

設定でモチーフオーバーライドが指定されている場合、以下のパラメータがスタイルのデフォルトより優先されます:

パラメータ説明
motifLengthint (0=auto, 1/2/4)モチーフ長のオーバーライド(拍単位、0はデフォルトで2小節)
motifNoteCountint (0=auto, 3-8)モチーフの音数をオーバーライド(0はデフォルトで6)
motifMotionint (0xFF=preset, 0-4)モーションタイプのオーバーライド(0=Stepwise, 1=GentleLeap, 2=WideLeap, 3=NarrowStep, 4=Disjunct; 内部5=OstinatoはBlueprint専用)
motifRegisterHighint (0=auto, 1=low, 2=high)レジスター範囲のオーバーライド
motifRhythmDensityint (0xFF=preset, 0-2)リズム密度のオーバーライド(0=Sparse, 1=Medium, 2=Driving)

パターン生成

MotifMotionの値(API: 0-4、内部: 0-5):

名前説明
0Stepwiseスケールステップのみ(2度)
1GentleLeap3度まで
2WideLeap5度まで
3NarrowStep狭いスケール度数(ジャジー)
4Disjunct不規則な跳躍(実験的)
5Ostinato同一ピッチクラスの繰り返し(内部Blueprint専用

音域レンジ

レジスター範囲
MidC3 (48) - C5 (72)
HighC4 (60) - C6 (84)

アルペジオトラック

ソース: src/track/arpeggio.cpp(約275行)

SynthDrivenコンポジションスタイル(BGM専用モード)用。エレクトロニックスタイルのトラックで主要なハーモニック/メロディック要素として機能するアルペジオパターンを生成します。

パラメータ

cpp
struct ArpeggioParams {
    ArpeggioPattern pattern;  // Up, Down, UpDown, Random, Pinwheel, PedalRoot, Alberti, BrokenChord
    ArpeggioSpeed speed;      // Eighth, Sixteenth, Triplet
    uint8_t octave_range;     // 1-3オクターブ
    float gate;               // ノート長比率 (0.0-1.0)
    bool sync_chord;          // コードチェンジに追従
};

パターンタイプ(全8種類)

IDパターン説明
0Upコードトーンを上昇
1Downコードトーンを下降
2UpDown上昇後に下降
3Randomランダムなコードトーン選択
4Pinwheel方向が交互に変わるパターン
5PedalRoot各音の間にルートに戻る
6Albertiクラシック的な分散和音(低-高-中-高)
7BrokenChord不規則なコードトーン配列

スピード変換

cpp
Tick getNoteDuration(ArpeggioSpeed speed) {
    switch (speed) {
        case Eighth:    return TICKS_PER_BEAT / 2;    // 240
        case Sixteenth: return TICKS_PER_BEAT / 4;    // 120
        case Triplet:   return TICKS_PER_BEAT / 3;    // 160
    }
}

SEトラック

ソース: src/track/se.cpp(約15行)

セクションマーカー用の最小トラック(テキストイベントのみ)。

cpp
void generateSE(Song& song) {
    for (auto& section : song.arrangement.sections) {
        MidiEvent marker;
        marker.tick = section.start_tick;
        marker.type = MidiEventType::Text;
        marker.text = section.name;
        song.se.addEvent(marker);
    }
}

ベロシティ計算

全トラック共通のベロシティ計算式:

cpp
uint8_t calculateVelocity(
    uint8_t baseVelocity,
    int beat,
    SectionType section,
    float trackBalance
) {
    float beatAdjust = getBeatAccent(beat);      // 強拍: +10
    float sectionMult = getSectionEnergy(section); // Chorus: 1.2

    return clamp(
        baseVelocity * beatAdjust * sectionMult * trackBalance,
        1, 127
    );
}

トラックバランス

トラックバランス備考
Vocal1.00リード楽器
Aux0.50-0.80副旋律サポート
Chord0.75サポート
Bass0.85ベース
Guitar0.70伴奏
Drums0.90タイミングドライバー
Motif0.70バックグラウンド
Arpeggio0.85中レベル

Released under the MIT License.