トラック生成
MIDI Sketchの各トラック生成器を詳しく解説します。
トラック概要
MIDI Sketchは8つのトラックを異なるMIDIチャンネルに生成します:
チャンネル割り当て
| トラック | チャンネル | プログラム | 役割 |
|---|---|---|---|
| Vocal | 0 | Piano (0) | 主旋律 |
| Aux | 5 | Pad (89) | 副旋律サポート |
| Chord | 2 | E.Piano (4) | 和声バッキング |
| Bass | 3 | E.Bass (33) | ベース |
| Motif | 4 | Synth (81) | BackgroundMotifスタイル |
| Arpeggio | 5 | Synth (81) | SynthDrivenスタイル |
| Drums | 9 | GMドラム | リズム |
| SE | 15 | - | セクションマーカー |
ボーカルトラック
ソース: src/track/vocal.cpp(約470行)、src/track/melody_designer.cpp(約520行)
ボーカルシステムはテンプレート駆動型メロディデザイナーを使用し、予測可能でスタイルに正確なメロディを生成します。
アーキテクチャ
ボーカル生成は2つのコンポーネントに分割されています:
- MelodyDesigner(
melody_designer.cpp)- テンプレート駆動のピッチ選択 - Vocal Generator(
vocal.cpp)- セクション構造と調整
メロディテンプレート
7つのメロディテンプレートがメロディ特性を定義:
| ID | 名前 | Plateau | 最大ステップ | 用途 |
|---|---|---|---|---|
| 0 | Auto | - | - | VocalStyle基準で選択 |
| 1 | PlateauTalk | 0.65 | 2 | NewJeans、Billie Eilishスタイル |
| 2 | RunUpTarget | 0.20 | 4 | YOASOBI、Adoスタイル |
| 3 | DownResolve | 0.30 | 3 | Bセクション、プリコーラス |
| 4 | HookRepeat | 0.40 | 3 | TikTok、K-POPフック |
| 5 | SparseAnchor | 0.50 | 2 | Official髭男dism、バラード |
| 6 | CallResponse | - | - | デュエットパターン |
| 7 | JumpAccent | - | - | 感情的ピーク |
- Plateau ratio: 同じピッチに留まる確率(高いほど繰り返しが多い)
- Max step: 半音単位の最大音程(低いほど滑らか)
生成フロー
ピッチ選択(4択のみ)
MelodyDesignerはピッチ選択を4つのオプションに制限:
enum class PitchChoice {
Same, // 現在のピッチに留まる(plateau_ratio)
StepUp, // +1半音
StepDown, // -1半音
TargetStep // ターゲット方向へ±2(テンプレートにターゲットがある場合)
};この制約されたアプローチにより、より自然で歌いやすいメロディが生成されます。
ボーカルアティチュード
| アティチュード | 説明 | 実装 |
|---|---|---|
| Clean | 保守的、歌いやすい | コードトーンのみ、オンビート |
| Expressive | 感情的、ダイナミック | テンション許可、タイミング変動 |
| Raw | エッジー、型破り | 非コードトーン、境界破壊 |
フレーズキャッシュ
音楽的な一貫性のためセクションタイプ別にフレーズをキャッシュ:
std::map<SectionType, std::vector<Phrase>> phraseCache_;
// Aセクションは繰り返し時に同じ/類似フレーズを使用
// サビはメロディのアイデンティティを維持音域制約
struct VocalRange {
uint8_t low = 60; // C4
uint8_t high = 79; // G5
};Auxトラック
ソース: src/track/aux_track.cpp(約440行)
Aux(補助)トラックは主旋律に対する副旋律サポートを提供します。対旋律ではなく、主旋律を強化する「知覚制御レイヤー」です。
目的
| 役割 | 説明 |
|---|---|
| 中毒性 | パルスループで繰り返しのキャッチーなパターンを生成 |
| 身体性 | グルーブアクセントで体が動く感覚を追加 |
| 安定感 | フレーズ終端で解決感を提供 |
| 構造認識 | セクション境界の認識を支援 |
Aux機能
5つの補助機能が利用可能:
| ID | 機能 | 説明 |
|---|---|---|
| A | PulseLoop | 同音または固定音程の繰り返しパターン |
| B | TargetHint | コードトーンで主旋律のターゲットを暗示 |
| C | GrooveAccent | スタッカートでリズミックなアクセント |
| D | PhraseTail | フレーズ終端の下降解決 |
| E | EmotionalPad | 長い持続音のコードトーン |
テンプレート → Auxマッピング
各メロディテンプレートは適切なaux機能を自動選択:
| テンプレート | Aux機能 | 理由 |
|---|---|---|
| PlateauTalk | A(PulseLoop) | Ice Cream/ミニマルスタイル |
| RunUpTarget | B + D | YOASOBI上昇→解決 |
| HookRepeat | A + C | TikTok繰り返しフック |
| SparseAnchor | E + D | バラードの感情サポート |
生成制約
- 常にボーカルの後に生成(衝突回避)
- ボーカルより狭い音域(50-70%)
- 低いベロシティ(0.5-0.8×ボーカル)
- HarmonyContextでボーカルとの不協和音を回避
コードトラック
ソース: src/track/chord_track.cpp(約820行)
ボイスリーディング最適化を伴う和声ボイシングを生成。
ボイシングタイプ
ボイスリーディングアルゴリズム
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を使用して音の重複を回避:
if (bassAnalysis.hasRootOnBeat1) {
// ルートレスボイシングを使用 - ベースがルートを担当
voicing = generateRootlessVoicing(chord);
} else {
// コードボイシングにルートを含める
voicing = generateFullVoicing(chord);
}音域制約
constexpr uint8_t CHORD_LOW = 48; // C3
constexpr uint8_t CHORD_HIGH = 84; // C6ベーストラック
ソース: src/track/bass.cpp(約450行)
ルート重視のパターンで和声的基盤を生成。
パターンタイプ
| パターン | 説明 | リズム |
|---|---|---|
| Sparse | ミニマル、バラードスタイル | 1拍目のみ |
| Standard | ポップ/ロックベースライン | 1、3拍目にフィル |
| Driving | エネルギッシュ、前進的 | 全体で8分音符 |
生成ロジック
アプローチノート
4拍目は次のルートへの半音アプローチを使用可能:
// 次のコードルートがCの場合
// 4拍目はB(半音下)またはDb(半音上)
uint8_t approachNote = nextRoot - 1; // 半音アプローチドラムトラック
ソース: src/track/drums.cpp(約680行)
フィルとダイナミクスを含むドラムパターンを生成。
GMドラムマップ
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;パターンスタイル
フィルタイプ
enum class FillType {
TomDescend, // ハイ → ミッド → ロータム
TomAscend, // ロー → ミッド → ハイタム
SnareRoll, // 連続スネアヒット
Combo // 混合要素
};フィルの挿入位置:
- セクション遷移
- 4または8小節ごと
- サビ前
ゴーストノート
グルーブのためのベロシティ軽減スネアアーティキュレーション:
// メインスネア: ベロシティ 100
// ゴーストノート: ベロシティ 40-60モチーフトラック
ソース: src/track/motif.cpp(約470行)
BackgroundMotifコンポジションスタイル用。繰り返しパターンを生成。
パラメータ
struct MotifParams {
MotifLength length; // TwoBars, FourBars
RhythmDensity rhythm_density; // Sparse, Medium, Driving
MotifMotion motion; // Stepwise, GentleLeap
RepeatScope repeat_scope; // FullSong, PerSection
MotifRegister register_; // Mid, High
};パターン生成
音域レンジ
| レジスター | 範囲 |
|---|---|
| Mid | C3 (48) - C5 (72) |
| High | C4 (60) - C6 (84) |
アルペジオトラック
ソース: src/track/arpeggio.cpp(約200行)
SynthDrivenコンポジションスタイル用。アルペジオパターンを生成。
パラメータ
struct ArpeggioParams {
ArpeggioPattern pattern; // Up, Down, UpDown, Random
ArpeggioSpeed speed; // Eighth, Sixteenth, Triplet
uint8_t octave_range; // 1-3オクターブ
float gate; // ノート長比率 (0.0-1.0)
bool sync_chord; // コードチェンジに追従
};パターンタイプ
スピード変換
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行)
セクションマーカー用の最小トラック(テキストイベントのみ)。
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);
}
}ベロシティ計算
全トラック共通のベロシティ計算式:
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
);
}トラックバランス
| トラック | バランス | 備考 |
|---|---|---|
| Vocal | 1.00 | リード楽器 |
| Aux | 0.50-0.80 | 副旋律サポート |
| Chord | 0.75 | サポート |
| Bass | 0.85 | ベース |
| Drums | 0.90 | タイミングドライバー |
| Motif | 0.70 | バックグラウンド |
| Arpeggio | 0.85 | 中レベル |