feat: 完成 P 群組 — 語音子系統
新增 apps/api/src/voice/:Voice Sheet(基礎音色/預設語速/音域幅度/口頭 聲響庫/禁則,依性格原型推導預設值,1:1 掛在 Character,同 EmotionState 的關聯模式);情緒→韻律對照(六狀態語速/音高/音量/句尾走向),音高變化 依角色音域幅度縮放(三無角色近乎單音),設計原則同 O-4 表情外顯度縮放; 非語言發聲與節奏(依情緒插入聲響、重大情緒延長停頓、禁則過濾候選、 低親密度不打斷、talkative 特徵+親密度門檻才可插話);TTSProvider 抽象 完全比照 F-1 LLMProvider(MockTTSProvider 輸出韻律標記+佔位音檔, RealTTSProvider 待人工確認供應商後再接,TTS_PROVIDER=mock|real 切換); 語音輸入副語言分析(EmotionService 新增 paralinguisticSignal,優先序 排在作息基線之前,讓「文字說沒事但聲音在抖」判為負向)。 修正一個真實 bug:非語言發聲的停頓時長原本直接拿目前主導情緒的數值 當強度訊號,但平靜狀態下 calm 預設就是 100,導致「什麼事都沒發生」被 誤判成「強度最強的重大情緒事件」而觸發不該有的長停頓——修正為 CALM 一律視為強度 0(平靜是情緒事件的缺席,不是訊號)。 刻意簡化:副語言特徵(語速/音量/顫抖/停頓)採結構化輸入,不做真實音訊 分析,比照 M/N 群組「先用結構化輸入代替真實訊號處理」的一貫取捨。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
0f3d16059c
commit
0e9401b891
@@ -58,6 +58,9 @@ export interface ProcessInputOptions extends TransitionContext {
|
||||
now?: Date;
|
||||
// I-5:本輪對話沒有明確情緒訊號時,套用作息驅動的基線情緒(不覆蓋文字本身觸發的訊號)。
|
||||
baselineSignal?: { tag: EmotionTag; intensity: number };
|
||||
// P-5:語音輸入的副語言特徵(語速/音量/顫抖/停頓)分析出的訊號——文字說「沒事」但聲音在抖,
|
||||
// 優先於作息基線(副語言是這一輪輸入本身的訊號,比時段基線更直接),但仍不覆蓋文字本身觸發的訊號。
|
||||
paralinguisticSignal?: { tag: EmotionTag; intensity: number };
|
||||
}
|
||||
|
||||
function toDomain(characterId: string, dims: Dimensions, updatedAt: Date): EmotionState {
|
||||
@@ -108,7 +111,9 @@ export class EmotionService {
|
||||
const rawSignal = this.tagger.tag({ text, triggerThreshold });
|
||||
// 情緒觸發閾值除了縮放強度,也要能讓「難觸發」原型對弱刺激完全不觸發(而不只是觸發得比較小力)。
|
||||
let signal = rawSignal.intensity < MIN_TRIGGER_INTENSITY ? { tag: "CALM" as const, intensity: 0 } : rawSignal;
|
||||
if (signal.tag === "CALM" && options.baselineSignal) {
|
||||
if (signal.tag === "CALM" && options.paralinguisticSignal) {
|
||||
signal = options.paralinguisticSignal;
|
||||
} else if (signal.tag === "CALM" && options.baselineSignal) {
|
||||
signal = options.baselineSignal;
|
||||
}
|
||||
const next = nextEmotionState(currentDominant, signal, options);
|
||||
|
||||
Reference in New Issue
Block a user