Spaces:
Running
Running
| """Voice = Simlish babble + emoticon + browser-TTS params. No model, no GPU, | |
| no server cost — the frontend speaks `simlish` via the Web Speech API and shows | |
| `emoticon` in the bubble. Rage register uses a harsher syllable pool + lower, | |
| faster voice.""" | |
| from __future__ import annotations | |
| import random | |
| from app.appearance import _face | |
| _WORD = { | |
| "content": "cheerful", "excited": "excited", "sad": "sad", | |
| "angry": "angry", "neutral": "calm", | |
| } | |
| _EMOTICON = { | |
| "content": "(◕‿◕)", "excited": "(★▽★)", | |
| "sad": "(╥﹏╥)", "angry": "(╬ಠ益ಠ)", | |
| "neutral": "(・_・)", | |
| } | |
| _SOFT = ["ba", "bo", "doo", "la", "lee", "mee", "na", "no", "wa", "yu", "pi", "to"] | |
| _RAGE = ["grr", "kah", "ztt", "brk", "gnak", "rrg", "tzk", "drr", "skuh", "vrr"] | |
| # region -> (syllable pool, word count, exclaim, pitch, rate) | |
| _VOICE = { | |
| "content": (_SOFT, 3, False, 1.4, 1.0), | |
| "excited": (_SOFT, 4, True, 1.7, 1.25), | |
| "sad": (_SOFT, 2, False, 1.1, 0.8), | |
| "angry": (_RAGE, 4, True, 0.7, 1.35), | |
| "neutral": (_SOFT, 3, False, 1.3, 1.0), | |
| } | |
| def _region(mood: list[int]) -> str: | |
| return _face(mood[0], mood[1]) | |
| def mood_word(mood: list[int]) -> str: | |
| return _WORD[_region(mood)] | |
| def emoticon(mood: list[int]) -> str: | |
| return _EMOTICON[_region(mood)] | |
| def simlish(mood: list[int], *, rng: random.Random | None = None) -> str: | |
| pool, nwords, exclaim, _pitch, _rate = _VOICE[_region(mood)] | |
| rng = rng or random.Random() | |
| words = ["".join(rng.choice(pool) for _ in range(rng.randint(1, 3))) | |
| for _ in range(nwords)] | |
| return " ".join(words) + ("!" if exclaim else "") | |
| def voice_params(mood: list[int]) -> dict: | |
| _pool, _n, _ex, pitch, rate = _VOICE[_region(mood)] | |
| return {"pitch": pitch, "rate": rate} | |