本システムは、歌詞や対話ログなどの「構造化・半構造化テキスト」から不要なメタ情報を排出し、コンパイラ理論(EBNF・スタック・SSA形式)を用いて、人間の発話の「余韻や文脈(コンテキスト)」を時間軸(ミリ秒)へ論理的かつ爆速で静的代入する、AITuber/音声合成システム向けのフロントエンド・バックエンド共通統合仕様である。
1. 全体アーキテクチャ・パイプライン
システムは、入力から最終出力(IR)までを完全な1方向のパイプラインとしてストリーム処理する。各フェーズは結合度を極限まで下げた単一責任原則(SRP)に基づき実装される。
[入力: 歌詞・テキスト]
│
▼
1. InputGate (前処理層) ─── [ノイズ(タグ・コード)の完全除去]
│
▼
2. Lexical Analysis (字句解析) ─── [MeCabによる形態素・助詞の分解]
│
▼
3. TanukiParser2 (構文解析) ─── [ContextStack(LIFO)による主述AST構築]
│ └─ 述語駆動による暗黙主語(Speaker/Listener)バインド
│
▼
4. TanukiBackend1 (最適化パス) ─── [TargetEnvによるペルソナ具象化]
│ └─ 構文駆動型プロソディ(150ms/300msポーズ)の静的代入
│
▼
5. Emitter Layer (最終出力) ─── [ゴースト・トークン(Control)をVocalへ完全吸着]
│
▼
[最終出力: FinalVocalToken (JSON)] ─── [音声合成エンジン(ACE-Step等)へノーレイテンシ結合]
2. 各コンポーネント詳細仕様
2.1. InputGate(前処理層)
- 責任: テキストストリームに含まれる非言語的な演出タグ・演奏指示を完全遮断し、構文解析のノイズを排除する。
-
フィルタリング制約(静的置換):
- メタタグ(セクション定義): \[.*?\](例: [Chorus], [Verse 1]) $\rightarrow$ 除去
- 演奏・演出指示(括弧メタ): \(.*?\)(例: (Gt. Solo), (Am7-D7)) $\rightarrow$ 除去
- 特性: 除去後、文字列の前後を trim() 処理し、文脈の連続性を破壊せずに形態素解析へ引き渡す。
2.2. TanukiParser2 Core(構文解析・記憶AST生成層)
-
責任: 助詞の連続性と述語の性質から、日本語特有の「主語の省略(ゼロ代名詞)」を論理的に解決し、抽象構文木(AST)を構築する。
-
データ構造:
Rustpub enum Subject { Text(String), // 明示的、またはスタックから継承された主語 Speaker, // [暗黙主語型] 発話者(わたし、僕、システム) Listener, // [暗黙主語型] 聞き手(あなた、君、ユーザー) } pub struct NodeSP { pub subject: Option<Subject>, pub predicate: String } -
文脈スタック制御(LIFO)アルゴリズム:
- 主語の検知: 特定助詞(「は」「が」「も」)を伴う名詞を検知した場合、それを最新主語として ContextStack に PUSH する。
- 通常述語の処理: 一般動詞・形容詞のパース時、主語が省略されている場合は ContextStack.pop()(または last() の参照)を行い、直前の物理主語(Subject::Text)を継承する。
-
述語駆動型・例外ルール(★最重要バグ回避):
述語が対人定型句・挨拶・感嘆詞(「またね」「ありがとう」「こんにちは」等)であるとマクロ判定(matches!)された場合、スタックを消費(POP)せず、かつ物理主語を継承せず、強制的に Subject::Speaker を割り当てる。 これにより、背後にある有効な物理主語(例:「空」)のコンテキストを次節へ破壊せず温存する。
2.3. TanukiBackend1(環境バインディング&ポーズ静的代入層)
- 責任: 抽象的な Subject 型を具象ペルソナへ展開し、フロントエンドの解析軌跡(KEEP/POP)を時間軸(韻律)の仕様へ翻訳する。
-
ペルソナ割当(TargetEnv):
- システム起動時に与えられる TargetEnv(例: speaker_pronoun = "わたし")に基づき、Subject::Speaker などのメタ型を物理音素文字列へ動的展開(バインド)する。
-
構文駆動型ポーズ挿入ルール(SSA形式代入):
- Rule A(通常主述完了): 一般述語の完了ノード直後 $\rightarrow$ post_pause_ms = 150
- Rule B(感情余韻): 挨拶・定型句(スタックKEEP)の完了ノード直後 $\rightarrow$ post_pause_ms = 300
- Rule C(主語ノード): 主語単体トークンの直後 $\rightarrow$ post_pause_ms = 0
2.4. Emitter Layer(最外周・ゴーストトークン吸着層)
- 責任: タイムライン(時間軸)の汚染や音声エンジンの同期エラーを根本的に防ぐため、非発話トークン(Control)を消滅させ、データ構造を完全一本化する。
-
吸着(Context Injection)アルゴリズム:
- 1パス($O(N)$)走査において、自動補完された主語(Control)に遭遇した際、その話者状態(speaker_identity や speaker_weight)を内部ステートに退避し、ストリームからノードを削除する。
- 直後に現れる発話トークン(Vocal)の context 属性フィールドに対し、退避していた状態変数をインジェクション(代入)し、FinalVocalToken として出力する。
- 終端セーフティ: ストリーム末尾が Control で終了する例外ケースでは、自動的にダミーの無音ノード(スペース)を生成して文脈を吸着させ、データの脱落を防ぐ。
3. 最終出力データフォーマット(仕様定義JSON)
音声合成エンジン(リンカー層)が最終的に受け取る、完全に最適化されたデータ構造のスキーマ例。
JSON
[
{
"phoneme": "そらが",
"accent_curve": [],
"post_pause_ms": 0,
"context": { "speaker_identity": "Default", "speaker_weight": 1.0 }
},
{
"phoneme": "あおい",
"accent_curve": [],
"post_pause_ms": 150,
"context": { "speaker_identity": "Default", "speaker_weight": 1.0 }
},
{
"phoneme": "またね",
"accent_curve": [],
"post_pause_ms": 300,
"context": { "speaker_identity": "Speaker(わたし)", "speaker_weight": 1.0 }
}
]
4. 本システムの論理的優位性(総括)
- 低レイヤーにおける表現力の固定化: LLMなどの重い推論を一切挟むことなく、コンパイラの静的パース($O(N)$)のみで「感情の余韻(300ms)」を論理的かつ決定論的に時間軸へ代入することに成功している。
- 完全なポータビリティ: キャラクターの名前("Rin" など)は一切コアコードにハードコーディングされておらず、すべての文脈は「型(Enum)」と「外部環境(TargetEnv)」として抽象化されているため、あらゆる音声合成エンジン、あらゆるキャラクターへ即座にリターゲット可能である。