diff --git a/abogen/web/routes.py b/abogen/web/routes.py index cd55f69..35eaa2b 100644 --- a/abogen/web/routes.py +++ b/abogen/web/routes.py @@ -44,7 +44,7 @@ from abogen.constants import ( SUPPORTED_SOUND_FORMATS, VOICES_INTERNAL, ) -from abogen.kokoro_text_normalization import normalize_roman_numeral_titles +from abogen.kokoro_text_normalization import normalize_for_pipeline, normalize_roman_numeral_titles from abogen.utils import ( calculate_text_length, get_user_output_path, @@ -2488,6 +2488,11 @@ def api_preview_voice_mix() -> ResponseReturnValue: if voice_choice is None: abort(400, "Unable to resolve voice selection") + try: + text = normalize_for_pipeline(text) + except Exception: + current_app.logger.exception("Voice preview normalization failed; using raw text") + segments = pipeline( text, voice=voice_choice, @@ -2584,6 +2589,11 @@ def api_speaker_preview() -> ResponseReturnValue: except ValueError as exc: abort(400, str(exc)) + try: + text = normalize_for_pipeline(text) + except Exception: + current_app.logger.exception("Preview normalization failed; using raw text") + segments = pipeline( text, voice=voice_choice, diff --git a/abogen/web/static/prepare.js b/abogen/web/static/prepare.js index ff18a01..b35b530 100644 --- a/abogen/web/static/prepare.js +++ b/abogen/web/static/prepare.js @@ -1855,8 +1855,14 @@ const initPrepare = (root = document) => { }; const resolveOverrideVoice = (data) => { - if (data.voice) { - return data.voice; + const hasVoiceProp = Boolean(data && Object.prototype.hasOwnProperty.call(data, "voice")); + const voiceValueRaw = typeof data?.voice === "string" ? data.voice : ""; + const voiceValue = voiceValueRaw.trim(); + if (voiceValue) { + return voiceValue; + } + if (hasVoiceProp) { + return ""; } const normalizedKey = canonicalizeEntityKey(data.normalized || data.token || ""); let genderHint = (data.gender || "").toLowerCase(); @@ -1878,6 +1884,9 @@ const initPrepare = (root = document) => { genderHint = ""; } } + if (baseVoice) { + return ""; + } return pickRandomVoiceForOverride(genderHint); }; diff --git a/abogen/web/static/styles.css b/abogen/web/static/styles.css index 6eaa37e..a92a4f7 100644 --- a/abogen/web/static/styles.css +++ b/abogen/web/static/styles.css @@ -1625,6 +1625,9 @@ button.step-indicator__item:focus-visible { border: 1px solid rgba(148, 163, 184, 0.2); box-shadow: 0 18px 38px rgba(15, 23, 42, 0.35); backdrop-filter: blur(4px); + position: sticky; + top: max(env(safe-area-inset-top), 0.5rem); + z-index: 25; } .entity-tabs__tab {