studing-audio / pieces.py
diegosouzacdv's picture
Add optional LFM3-Audio-2B engine (off unless LFM3_ENABLED=1)
845ded6 verified
Raw History Blame Contribute Delete
2.04 kB
"""Pure helpers of the LFM3 Space (no model, no network): text pieces and voices.
Kept apart from app.py so they can be unit-tested without torch or transformers.
"""
import re
FIRST_PIECE_MAX = 60 # first sentence longer than this is cut at its first clause
_SENTENCE = re.compile(r"(?<=[.!?…])\s+")
_CLAUSE = re.compile(r"(?<=[,;:])\s+")
# The Kokoro voice ids the app already sends (af_heart, bm_george, ...) are
# accepted, so the same client can be pointed at either Space. LFM3 has no
# named voices: only a language/locale and a female or male voice.
_KOKORO_LANG = {"a": "American English", "b": "British English"}
_GENDER = {"f": "female", "m": "male"}
_KOKORO_VOICE = re.compile(r"^([ab])([fm])_[a-z]+$")
def split_for_streaming(text: str) -> list:
"""Sentences, with the first one cut at its first clause when long, so
the first audio arrives after synthesizing only a few words."""
sentences = [s.strip() for s in _SENTENCE.split(text) if s.strip()]
if not sentences:
return []
first = sentences[0]
if len(first) > FIRST_PIECE_MAX:
parts = _CLAUSE.split(first, maxsplit=1)
if len(parts) == 2 and len(parts[0]) >= 12 and len(parts[1]) >= 12:
return [parts[0], parts[1]] + sentences[1:]
return sentences
def parse_voice(voice: str):
"""(language, gender) for a voice id, or None when it is not supported.
"female" / "male" mean American English; "af_heart"-style ids map the
first letter to American (a) or British (b) English and the second to the
gender. Portuguese Kokoro voices (pf_, pm_) are not mapped on purpose:
this Space is for comparing English."""
voice = (voice or "").strip().lower()
if voice in ("female", "male"):
return "American English", voice
match = _KOKORO_VOICE.match(voice)
if match:
return _KOKORO_LANG[match.group(1)], _GENDER[match.group(2)]
return None
def system_prompt(language: str, gender: str) -> str:
return f"Perform TTS in {language} using a {gender} voice."