Metadata-Version: 2.4
Name: piperg2p
Version: 0.1.1
Summary: Independent Piper-compatible text/phoneme/id frontend for Piper ONNX voice configs
Author: piperg2p contributors
License: Apache-2.0
Project-URL: Repository, https://github.com/buchwandler/piperg2p
Project-URL: Homepage, https://github.com/buchwandler/piperg2p
Keywords: tts,piper,g2p,phonemizer,onnx,espeak
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
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: pytest-cov>=4; extra == "dev"
Requires-Dist: ruff>=0.6; extra == "dev"
Requires-Dist: mypy>=1.10; extra == "dev"
Requires-Dist: build>=1; extra == "dev"
Requires-Dist: twine>=5; extra == "dev"
Requires-Dist: packaging>=24; extra == "dev"
Provides-Extra: g2lex
Requires-Dist: g2lex<0.2,>=0.1.8; extra == "g2lex"
Provides-Extra: lexphon
Requires-Dist: lexphon<0.3,>=0.2.3; extra == "lexphon"
Provides-Extra: espeak-direct
Requires-Dist: espeakng-loader>=0.1.0; extra == "espeak-direct"
Requires-Dist: dlinfo>=1.2.1; (sys_platform != "win32" and sys_platform != "android") and extra == "espeak-direct"
Provides-Extra: lexicons
Requires-Dist: lexphon<0.3,>=0.2.3; extra == "lexicons"
Dynamic: license-file

[![PyPI - Version](https://img.shields.io/pypi/v/piperg2p)](https://pypi.org/project/piperg2p/)
![PyPI - Python Version](https://img.shields.io/pypi/pyversions/piperg2p)
![PyPI - Downloads](https://img.shields.io/pypi/dm/piperg2p)
[![codecov](https://codecov.io/gh/buchwandler/piperg2p/graph/badge.svg?token=eMF0pdgARs)](https://codecov.io/gh/buchwandler/piperg2p)

# piperg2p

`piperg2p` is an independent, voice-config-driven Piper-compatible frontend. It produces phoneme sequences and model IDs from Piper ONNX voice configurations. It does not synthesize audio, require Piper, or include Piper source or model data.

## Delivered scope

- `text` phoneme voices with no eSpeak dependency.
- `espeak` voices through a native eSpeak NG public API binding or an explicit CLI fallback.
- Unicode NFD normalization and voice-specific ID maps.
- Sentence-grouped results and raw `[[ ... ]]` phoneme blocks in eSpeak mode.
- Immutable diagnostics, typed configuration, errors, and missing-phoneme reporting.

The native clause API is labeled `exact` only when it is available. The CLI path is always labeled `best-effort`. This release supports the named Piper Python `text` and ordinary `espeak` profile only. Pinyin, Hebrew, Japanese, and Thai are recognized configuration values but unavailable. Arabic eSpeak voices are rejected until Piper-compatible preprocessing is implemented.

## Install

```bash
pip install .
```

PiperG2P consumes **prepared, speakable text**. It does not verbalize numbers, abbreviations, units, currencies, dates, times, URLs, versions, or other written semantics. Prepare those forms in the calling application, then pass the result to `phonemize_prepared()`.

PiperG2P has no runtime dependency on Spokenform or Numeralform. Installing either package does not change core PiperG2P behavior.

This boundary does not change eSpeak compatibility: PiperG2P passes prepared text to the selected backend, and backend-specific pronunciation behavior remains unchanged.

Install eSpeak NG separately for eSpeak voices. Text voices need no optional runtime package.

## Semantic preparation composition

Use a separate preparation package only when written semantics need expansion:

```python
from spokenform import prepare_for_piperg2p
from piperg2p import phonemize_prepared

prepared = prepare_for_piperg2p(
    "Pay $12.50 for 2 kg.",
    language="en",
).spoken_text

result = phonemize_prepared(
    prepared,
    language="en-us",
    config="voice.onnx.json",
)

print(result.phonemes)
print(result.token_ids)
```

Install Spokenform separately. It is not required for PiperG2P core installation or core tests.

## Usage

```python
from piperg2p import PiperFrontend

frontend = PiperFrontend.from_config("voice.onnx.json")
result = frontend.phonemize("Hello, world.")
for sentence in result.sentences:
    print(sentence.phoneme_string)
    print(sentence.ids)
    print(sentence.missing_phonemes)
```

The configured `phoneme_id_map` is authoritative. `result.ids` is a convenience flattening of sentence IDs. Model inference should normally consume each `sentence.ids` separately.

## Lexicon-first mode

Lexicon support is an opt-in overlay on the existing eSpeak frontend. Install `piperg2p[lexphon]` for managed Lexphon identifiers or `piperg2p[g2lex]` for explicit local `.g2lex` files. Raw `[[...]]` blocks have precedence, lexicon misses use PiperG2P's eSpeak backend, and no dictionary downloads occur implicitly. See [docs/lexicons.md](docs/lexicons.md).

Use `*:espeak` assets for generic IPA pronunciation overrides. Use `*:espeak-piper` assets for Piper raw phoneme behavior with `phoneme_encoding="espeak-ipa3"`. Lexphon installs and verifies data externally, while PiperG2P owns interpretation, precedence, and voice-map ID encoding.

## Compatibility

Compatibility is measured against pinned reference profiles, not a moving upstream branch. See [docs/compatibility.md](docs/compatibility.md), [docs/espeak.md](docs/espeak.md), and [docs/provenance.md](docs/provenance.md).

## Independence

The runtime package has no Piper dependency, does not import Piper, and does not bundle Piper GPL assets. Reference corpus metadata is development evidence only.

## Sibling-style API

The high-level API keeps Piper voice configuration explicit while matching the shared development vocabulary used by sibling frontends:

```python
from piperg2p import phonemize_prepared

result = phonemize_prepared(
    "Hello world", language="en-us", config="voice.onnx.json"
)
print(result.phonemes)
print(result.token_ids)
```

Use `get_g2p(language, config=...)` for reuse. `tokenize`, `OverrideSpan`, `TokenAnnotation`, marker helpers, bounded `cache_info`, and `ids_to_phonemes` are also exported. The API never downloads models or lexicons. See `examples/README.md` for the twelve executable examples.
