| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
chore: flatten project by moving all contents from submodule to root | 6 个月前 | |
fix(clone): long references clone on OmniVoice; engines report the reference length they use (#2286) * fix(clone): let long references clone and say what each engine uses OmniVoice rejects a transcript paired with a clip over 20 s, and every automatic path produced exactly that pair: Voice Clone and /generate transcribed the whole clip, and saved profiles kept that transcript. A 25 s saved voice was permanently unusable on the default engine even though the model can pick its best 15 s passage from clips up to 75 s. - Drop whole-clip transcripts on over-long OmniVoice references at the engine boundary (prompt cache, inline fallback, sidecar) and skip the wasted whole-clip ASR; a transcript typed on /generate still gets the actionable [clone_ref_too_long] error. - VoxCPM2 ignores a whole-clip transcript once its 30 s cap cuts the clip. - Engines advertise max_ref_seconds/ref_strategy via list_backends(). - Electron Voice Clone shows an engine-aware note instead of the 15 s trim toast and leaves the transcript to engines that pick a passage. Refs #2281 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(clone): patch the sidecar backend's own base class Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(clone): review fixes for long references (#2281) - A transcript sent with a saved voice over the limit gets the same [clone_ref_too_long] 400 as an upload instead of being dropped. - omnivoice_ref_text treats blank text as no transcript. - The VoxCPM2 sidecar advertises its 30 s head limit; a parity test pins every sidecar's reference metadata to its in-process engine. - The Voice Clone transcript hook withdraws its own whole-clip transcript when the engine starts picking the passage itself, keeping user edits. - Changelog credits use the standard form. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(generate): probe reference length off the event loop Non-WAV clips decode through ffmpeg to measure length; doing it inline on the async route stalled every other request. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> | 29 天前 | |
chore: flatten project by moving all contents from submodule to root | 6 个月前 | |
chore: flatten project by moving all contents from submodule to root | 6 个月前 | |
fix: address PR #2500 review findings CPU preset leads with Whisper small; CLIs and loaders share omnivoice.utils.dtype (honours OMNIVOICE_CPU_DTYPE, no import cycle); the Windows-on-ARM notice and the disk-space message are localized (setup_space takes {{gib}}: 5 for CPU installs, 9 otherwise); ARM64 payloads without a manifest fail the release check; Windows on ARM is labelled experimental; test imports resolve at run time. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> | 20 天前 | |
fix(lang): propagate profile/request language into generation + longform (#533/#505/#502) (#565) Non-English voices drifted to English/wrong-language because the request's or profile's language wasn't reaching the model: - #533: generate_speech() read instruct/ref_text/seed from a resolved profile row but never row['language'] (and collapsed Auto→None), so a German archetype previewed in German yet generated in English on the user's own call (and via Docker/API). Fall back to the profile's stored language when the request didn't pin one; an explicit non-Auto request language still wins. (Frontend already sets the dropdown on profile-select; this is the authoritative backend fix.) - #505 (B2): the audiobook/longform synth hardcoded language=None, so the engine re-autodetected per chunk and a non-English clone flipped language mid-render. Add _resolve_default_language (request → profile → autodetect) and thread the resolved language through _build_synth/_prepare_synth/_render_longform_sse, the three longform request models, the preview path, and the resume manifest. Genuine Auto/unset behavior is unchanged. - #502 (partial): the duration estimator weights combining marks (U+0300–036F) at 0.0, so NFD/decomposed text under-allocated frames → rushed audio. NFC- normalize text at the estimator entry — fixes the whole diacritic-script class (no-op for precomposed text). (The residual "distorted" core still needs the reporter's sample; tracked separately.) Tests (fail-before/pass-after): profile language reaches the engine (German→de; explicit/Auto override semantics); longform synth gets the resolved language (→ja), not None; NFD vs NFC duration parity (Korean Hangul diverges ~3x pre-fix). Full suite: tests/ 1740 passed, backend/tests/ 114 passed. Co-authored-by: mergetest <test@local> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> | 4 个月前 | |
chore: flatten project by moving all contents from submodule to root | 6 个月前 | |
feat(audiobook): chapterized audiobook core + plan preview (Wave 5) (#402) * feat(audiobook): chapterized audiobook core + plan preview (Wave 5) First cut of the long-form vertical (parity §R3). Engine-agnostic core in services/audiobook.py: - parse_audiobook_script: pure parser. Markdown '# H1' headings → chapters; inline [voice:NAME] switches the narrator; [pause …] is delegated to the shared omnivoice.utils.text.parse_pause_markers so audiobooks and single-shot synthesis keep one pause dialect. Returns a chapter/span plan. - synthesize_chapter: orchestration via an injected synth(text, voice) callable (reuses chunked_tts split + crossfade, stitches inter-span silence) — so it's unit-testable with a stub backend, no model/GPU. - build_chapter_ffmetadata + build_m4b_cmd: pure FFMETADATA1 [CHAPTER] builder and faststart-m4b concat-demux argv (bitrate-validated, no injection). POST /audiobook/plan returns the parsed plan (no TTS/ffmpeg, no side effects). Deferred (follow-ups): the streaming synth job + chapterized-m4b run, epub/pdf ingest (new dep), ACX loudnorm mastering, crash-resume, UI. 14 tests: parser (chapters/voice/pause/intro/empties/to_dict), FFMETADATA offsets+escaping, m4b argv + bitrate guard, and stub-synth orchestration (span+silence stitching, voice threading). docs §R3 status updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(audiobook): linear-time regexes (CodeQL ReDoS) CodeQL flagged polynomial backtracking on user-provided input in three regexes reachable from the new POST /audiobook/plan endpoint: - _VOICE_RE: \s*(...)\s* → single [^\]]* class, stripped in code. - _HEADING_RE: trailing [ \t]* removed; title captured greedily + stripped. - _PAUSE_RE (omnivoice/utils/text.py): the numeric spec is now an atomic group (?>…) so its leading \s+ can't backtrack against the trailing \s*. Behavior-preserving (Python >=3.11 already required); 14 pause tests + 14 audiobook tests green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(audiobook): require non-space heading title start (CodeQL ReDoS) The previous _HEADING_RE '[ \t]+(.+)' still let the leading whitespace class and the title '.+' both match the same tab run (overlap → polynomial). Anchor the title capture with \S so the two can't overlap. 14 audiobook tests green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(audiobook): exclude '[' from voice-tag content (CodeQL ReDoS) [^\]]* still matched '[', so a run of nested [voice: prefixes produced overlapping finditer match attempts → O(n^2). Excluding both brackets ([^\]\[]) makes matches non-overlapping and linear. A voice name never contains a bracket. 14 audiobook tests green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> | 4 个月前 | |
fix(security): bound model and voice validators | 2 个月前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 6 个月前 | ||
| 29 天前 | ||
| 6 个月前 | ||
| 6 个月前 | ||
| 20 天前 | ||
| 4 个月前 | ||
| 6 个月前 | ||
| 4 个月前 | ||
| 2 个月前 |