Files
explorer-monorepo/virtual-banker/avatar/animation/visemes.go

114 lines
2.4 KiB
Go

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
}