package animation // VisemeMapping maps phonemes to visemes var VisemeMapping = map[string]string{ // Silence "sil": "sil", "sp": "sil", // Vowels "aa": "aa", // "father" "ae": "aa", // "cat" "ah": "aa", // "but" "ao": "oh", // "law" "aw": "ou", // "cow" "ay": "aa", // "hide" "eh": "ee", // "red" "er": "er", // "her" "ey": "ee", // "ate" "ih": "ee", // "it" "iy": "ee", // "eat" "ow": "ou", // "show" "oy": "ou", // "toy" "uh": "ou", // "book" "uw": "ou", // "blue" // Consonants "b": "mbp", // "bat" "ch": "ch", // "chair" "d": "td", // "dog" "dh": "th", // "the" "f": "fv", // "fish" "g": "gk", // "go" "hh": "aa", // "hat" "jh": "ch", // "joy" "k": "gk", // "cat" "l": "aa", // "let" "m": "mbp", // "mat" "n": "aa", // "not" "ng": "gk", // "sing" "p": "mbp", // "pat" "r": "aa", // "red" "s": "s", // "sat" "sh": "ch", // "ship" "t": "td", // "top" "th": "th", // "think" "v": "fv", // "vat" "w": "ou", // "wet" "y": "ee", // "yet" "z": "s", // "zoo" "zh": "ch", // "measure" } // GetVisemeForPhoneme returns the viseme for a phoneme func GetVisemeForPhoneme(phoneme string) string { if viseme, ok := VisemeMapping[phoneme]; ok { return viseme } return "aa" // Default } // PhonemeToVisemeTimeline converts phoneme timings to viseme timeline func PhonemeToVisemeTimeline(phonemes []PhonemeTiming) []VisemeEvent { if len(phonemes) == 0 { return []VisemeEvent{} } var visemes []VisemeEvent currentViseme := GetVisemeForPhoneme(phonemes[0].Phoneme) startTime := phonemes[0].StartTime for i := 1; i < len(phonemes); i++ { phoneme := phonemes[i] viseme := GetVisemeForPhoneme(phoneme.Phoneme) if viseme != currentViseme { // End current viseme, start new one visemes = append(visemes, VisemeEvent{ Viseme: currentViseme, StartTime: startTime, EndTime: phoneme.StartTime, }) currentViseme = viseme startTime = phoneme.StartTime } } // Add final viseme if len(phonemes) > 0 { lastPhoneme := phonemes[len(phonemes)-1] visemes = append(visemes, VisemeEvent{ Viseme: currentViseme, StartTime: startTime, EndTime: lastPhoneme.EndTime, }) } return visemes } // PhonemeTiming represents a phoneme with timing type PhonemeTiming struct { Phoneme string StartTime float64 EndTime float64 } // VisemeEvent represents a viseme event type VisemeEvent struct { Viseme string StartTime float64 EndTime float64 }