Metadata-Version: 2.4
Name: inflectsynth
Version: 0.1.2
Summary: Inflect v2 ONNX synthesis frontend backed by inflectg2p
Author: inflectsynth contributors
License: Apache-2.0
Project-URL: Repository, https://github.com/buchwandler/inflectsynth
Project-URL: Homepage, https://github.com/buchwandler/inflectsynth
Keywords: tts,inflect,onnx,onnxruntime,speech
Classifier: Development Status :: 3 - Alpha
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: numpy<3,>=1.26
Requires-Dist: inflectg2p<0.2,>=0.1.0
Requires-Dist: onnxvoice[huggingface]<0.3,>=0.2.10
Requires-Dist: audiosig<0.2,>=0.1.4
Provides-Extra: cpu
Requires-Dist: onnxvoice[cpu]<0.3,>=0.2.10; extra == "cpu"
Provides-Extra: gpu
Requires-Dist: onnxvoice[gpu]<0.3,>=0.2.10; extra == "gpu"
Provides-Extra: directml
Requires-Dist: onnxvoice[directml]<0.3,>=0.2.10; extra == "directml"
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: ruff<0.17,>=0.16; extra == "dev"
Requires-Dist: mypy>=1.11; extra == "dev"
Requires-Dist: build>=1; extra == "dev"
Requires-Dist: setuptools>=80; extra == "dev"
Requires-Dist: setuptools-scm[simple]>=9.2; extra == "dev"
Requires-Dist: wheel; extra == "dev"
Requires-Dist: twine>=5; extra == "dev"
Requires-Dist: packaging>=24; extra == "dev"
Dynamic: license-file

# inflectsynth

InflectSynth is the text/frontend layer for Inflect v2 synthesis: `inflectg2p` produces model-ready token IDs, while ONNXVoice owns the split ONNX Runtime sessions for Inflect Nano v2 and Inflect Micro v2.

The package has a flat layout (no `src/`) and dynamic Git-tag versioning through
`setuptools-scm`.

## Install

CPU:

```bash
python -m pip install "inflectsynth[cpu]"
```

CUDA or DirectML:

```bash
python -m pip install "inflectsynth[gpu]"
python -m pip install "inflectsynth[directml]"
```

## Python

```python
from inflectsynth import DEFAULT_MODEL, InflectVoice

with InflectVoice.from_pretrained(DEFAULT_MODEL, providers="cpu") as tts:
    result = tts.synthesize(
        "A small voice can still have something meaningful to say.",
        speed=1.0,
        variation=0.667,
        seed=7,
    )
    result.save_wav("sample.wav")
```

Use `micro-v2` (or alias `micro`) for the larger v2 model.

The first managed run downloads exactly two revision-pinned upstream artifacts,
`duration.onnx` and `decode.onnx`, and verifies both byte size and SHA-256 before opening.

## Voice contract

The upstream Inflect v2 base releases each contain **one fixed synthetic English voice**.
Accordingly:

```python
tts.available_voices == ("default",)
```

`voice="default"` is the only supported runtime voice. There are no hidden style rows,
speaker embeddings, or reference-audio voice cloning inputs in the published v2 ONNX ABI.

## Controls

The public upstream ranges are preserved:

- `speed`: `0.5` to `2.0`, default `1.0`
- `variation`: `0.0` to `1.0`, default `0.667`
- `seed`: integer, default `0`

A call processes one input through one frontend/runtime request. InflectSynth does not currently implement the official runner's long-text wrapper behavior: punctuation-aware chunking, per-chunk pauses/noise, concatenation, or edge fades.

## Atomic request ownership

One `InflectVoice.synthesize_prepared()` call processes one exact prepared-text request. The caller owns text boundaries, subdivision, and any composition of child requests. InflectSynth does not split or concatenate long text, add pauses, or perform sentence segmentation.

## Request capacity and token measurement

`InflectVoice.measure_prepared()` runs the same InflectG2P prepared-text frontend used by synthesis and reports the actual model-token count without acoustic inference:

```python
from inflectsynth import DEFAULT_MODEL, InflectVoice

with InflectVoice.from_pretrained(DEFAULT_MODEL, providers="cpu") as tts:
    measure = tts.measure_prepared("The exact prepared text to send.")
    print(measure.amount, measure.unit, measure.maximum, measure.fits)
```

Managed canonical models `nano-v2` and `micro-v2` have an evidence-backed supported safe request budget of 400 model tokens each. For these managed models, `maximum` is 400 and `fits` is true exactly when the measured request uses at most that many tokens. This is a conservative request budget, not a claim about the ONNX graph's hard maximum or a guarantee of perceptual quality. The packaged policy revision is available from `capacity_api_contract()` and managed discovery metadata; it records the benchmark evidence digest, runtime/package versions, model source revisions, and ONNX artifact hashes.

Local and unmanaged models always report `maximum=None` and `fits=None`; they do not inherit managed capacity by model ID or file name. No text splitting, retry chunking, or sentence segmentation is performed. Discovery publishes the same policy maximum and revision as `metadata["max_input_tokens"]` and `metadata["capacity_policy_revision"]` when its managed source revision matches the policy.

For debugging, the optional CLI measurement command prints the same fields as JSON and does not synthesize audio:

```bash
python -m inflectsynth --measure "The exact prepared text to send."
```

## Local graphs

```python
from inflectsynth import InflectVoice

with InflectVoice.from_local(
    duration_path="duration.onnx",
    decode_path="decode.onnx",
    providers="cpu",
) as tts:
    result = tts.synthesize("Local inference.")
```

## Voice-level calibration

InflectSynth ships measured BS.1770 static-gain calibration for both managed v2 models. Calibration is **opt-in**; the default mode remains `off`, so existing synthesis returns the raw model level.

```python
from inflectsynth import DEFAULT_MODEL, InflectVoice, SynthesisConfig, VoiceLevelConfig

config = SynthesisConfig(
    voice_level=VoiceLevelConfig(mode="calibrated"),
)

with InflectVoice.from_pretrained(DEFAULT_MODEL, providers="cpu") as tts:
    result = tts.synthesize(
        "Use the packaged voice-level calibration.",
        config=config,
    )
```

The v0.1.0 calibration catalog contains:

- `inflect:nano-v2:default`: `-0.0423775698 dB`
- `inflect:micro-v2:default`: `-0.3353773193 dB`

Both records target `-24.0 LUFS` using the `inflectsynth-prepared-speech-v1` corpus and nine measurements per model (three prepared-speech stimuli × three seeds). The applied gain and catalog revision are reported under `result.metadata["voice_level"]`. Local/unmanaged graphs do not receive a managed calibration identity automatically.

## Catalog

Catalog discovery is delegated to ONNXVoice. Its Inflect adapter uses the authoritative `inflect-onnx-bundles` catalog source and cache; InflectSynth does not package a second model catalog. For sibling-repository testing or a separately updated catalog, pass `catalog_url="../inflect-onnx-bundles/catalog/models.json"` to `InflectVoice.from_pretrained()` or the corresponding discovery API. The authoritative catalog repo is intentionally not a Python package.

## Runtime ownership

InflectSynth owns text preparation and calls `inflectg2p` to produce the model-ready token IDs. It passes those IDs and the speed, variation, and seed controls to ONNXVoice's registered Inflect adapter. ONNXVoice owns catalog resolution, pinned artifact integrity checks, provider/session configuration, and ONNX graph execution; InflectSynth does not open ONNX Runtime sessions directly.

## Real-model release smoke

The real CPU integration smoke is excluded from normal unit runs and downloads model files only when explicitly enabled. Install the candidate ONNXVoice checkout/wheel and InflectSynth's CPU test dependencies, then run from this repository root:

```bash
python -m pip install -e "../onnxvoice[cpu]" -e ".[cpu,dev]"
env INFLECTSYNTH_RUN_REAL_MODEL_TESTS=1 python -m pytest -s -m "integration and network" tests/integration/test_inflect_real_models.py
```

The test runs both `nano-v2` and `micro-v2` through real InflectG2P and ONNXVoice CPU inference, checks output/seed behavior, and prints the resolved revision, artifact sizes and SHA-256 digests, and runtime/package versions. Run this gate against the candidate ONNXVoice build before release.

## Dynamic versioning

Versions come from Git tags through `setuptools-scm`; source archives without Git metadata use
`0.1.dev0`. `inflectsynth.__version__` reports the installed distribution version.

## License

Apache-2.0. Inflect code and weights referenced by this project are published by Owen Song under
Apache-2.0; model weights are downloaded from their official Hugging Face repositories and are not
included in this source package.
