Metadata-Version: 2.4
Name: jaketts
Version: 1.0.6
Summary: Jake's local CLI text-to-speech tool powered by Kokoro-82M
Home-page: https://github.com/ofalltrades/jaketts
Author: Jake
License: MIT
Project-URL: Source, https://github.com/ofalltrades/jaketts
Project-URL: Issues, https://github.com/ofalltrades/jaketts/issues
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Environment :: MacOS X
Classifier: Intended Audience :: End Users/Desktop
Classifier: Operating System :: MacOS
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
Requires-Python: >=3.10,<3.13
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: kokoro>=0.7.0
Requires-Dist: misaki[ja,zh]>=0.9.4
Requires-Dist: sounddevice>=0.4.0
Requires-Dist: soundfile>=0.4.0
Requires-Dist: numpy<2.0.0,>=1.20.0
Requires-Dist: torch>=2.0.0
Requires-Dist: tqdm>=4.65.0
Dynamic: author
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license
Dynamic: license-file
Dynamic: project-url
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# 🔊 jaketts

`jaketts` — also available as the shorter `jtts` command — is a local text-to-speech utility for macOS powered by the open-weight **Kokoro-82M** model.

It can play synthesized speech directly through your speakers, save WAV files, read plain-text files, switch between Kokoro voices, adjust playback speed, and launch a small Tkinter desktop interface when run with no arguments.

The default voice is `bm_george`.

## Features

- 🔊 Direct speaker playback
- 💾 WAV file export
- 📖 Plain-text file input
- 🗣️ Optionless voice selection
- ⏩ Adjustable speech speed
- 🌍 Multiple Kokoro language/voice families
- 🖥️ Native Tkinter GUI with voice, speed, and volume controls
- 🔒 Local synthesis with no API key required
- ⚡ `jaketts` and `jtts` command aliases
- 🇯🇵 Automatic one-time Japanese dictionary setup when a Japanese voice is first used

## Requirements

`jaketts` currently supports Python 3.10 through Python 3.12.

On Apple Silicon, `jaketts` automatically allows PyTorch to use the MPS backend when available, with CPU fallback for unsupported operations. Heavy Kokoro/PyTorch imports are deferred until synthesis actually starts, so lightweight CLI operations and GUI launch remain responsive.

## Installation from PyPI

Install the published package into your preferred Python environment:

```bash
python -m pip install jaketts
```

That installs both commands:

```bash
jaketts --version
jtts --version
```

Japanese support uses the full UniDic dictionary. The required Python packages are installed by pip, and the first time you select a Japanese voice, `jaketts` automatically downloads the UniDic dictionary into the same Python environment. This is a one-time download of roughly 526 MB.

## Installation from GitHub

Clone the repository, enter it, and install it in editable mode:

```bash
git clone https://github.com/ofalltrades/jaketts.git
cd jaketts
python -m pip install -e .
```

Editable mode means changes to `jaketts.py` are used immediately without reinstalling the package. Re-run `python -m pip install -e .` after changing package metadata or dependencies.

If you prefer an isolated virtual environment:

```bash
python3.12 -m venv .venv
source .venv/bin/activate
python -m pip install -e .
```

To update a source checkout later:

```bash
git pull --ff-only origin main
```

If the update changed dependencies or package metadata, follow it with:

```bash
python -m pip install -e .
```

## Usage

### Launch the desktop GUI

Run either command with no arguments:

```bash
jaketts
```

or:

```bash
jtts
```

The GUI launches in its own process, so the terminal prompt is returned immediately while the desktop window remains open.

### Speak text using the default voice

```bash
jtts "Three Rings for the Elven-kings under the sky."
```

### Choose a voice

Voice IDs are passed directly without a `--voice` flag:

```bash
jtts af_sarah "Hello from an American female voice."
```

```bash
jtts am_adam "Hello from an American male voice."
```

The voice can appear before or after the text:

```bash
jtts "This also uses Adam." am_adam
```

If no recognized voice ID is supplied, `bm_george` is used.

### Japanese voices

Japanese voices work without a separate setup command:

```bash
jtts jf_alpha "こんにちは世界"
```

On the first Japanese invocation only, `jaketts` downloads the full UniDic dictionary automatically. Later Japanese invocations reuse the downloaded dictionary.

### Read a text file

```bash
jtts story.txt
```

With an explicit voice:

```bash
jtts am_adam story.txt
```

### Save to the default output file

A bare `-o` or `--output` saves to `output.wav`:

```bash
jtts -o "Save this narration."
```

This also works when a voice immediately follows `-o`:

```bash
jtts -o am_adam "Save this using Adam."
```

### Save to a custom WAV file

```bash
jtts -o narration.wav "Save this narration."
```

or:

```bash
jtts --output narration.wav am_adam "Save this narration."
```

Equals syntax is also supported:

```bash
jtts --output=narration.wav "Save this narration."
```

### Change speech speed

```bash
jtts -s 1.25 "Speak this a little faster."
```

```bash
jtts --speed 0.9 am_adam "Speak this a little slower."
```

Equals syntax is supported as well:

```bash
jtts --speed=1.1 "Slightly faster speech."
```

### Flexible argument ordering

The CLI normalizes recognized options and voice IDs before handing them to `argparse`, so these layouts are valid:

```bash
jtts am_adam "Hello" -o hello.wav
jtts -o hello.wav "Hello" am_adam
jtts "Hello" -s 1.1 am_adam -o hello.wav
jtts am_adam "Hello" -o
```

### Show the installed version

`-v` is the version flag:

```bash
jtts -v
```

or:

```bash
jtts --version
```

## Voice reference

Some commonly useful Kokoro voices include:

| Voice ID | Family | Description |
| --- | --- | --- |
| `bm_george` | British English | Default narrator |
| `bm_lewis` | British English | Male British voice |
| `bf_emma` | British English | Female British voice |
| `af_heart` | American English | Expressive female voice |
| `af_sarah` | American English | Female American voice |
| `am_adam` | American English | Male American voice |
| `ff_sixtine` | French | Female French voice |
| `jf_alpha` | Japanese | Female Japanese voice |
| `pf_doris` | Portuguese | Female Portuguese voice |
| `zf_xiaobei` | Chinese | Female Chinese voice |

The complete supported voice list is defined in `VOICE_WHITELIST` inside `jaketts.py` and is also available in the desktop GUI.

## Testing

The repository includes an integration test matrix covering output routing, flexible argument ordering, speed options, version flags, text-file input, default voice behavior, and multilingual voice routing.

Run it with:

```bash
./test_app.sh
```

The test script creates temporary WAV/text artifacts and removes them automatically when the test run exits.

## Development

Install the clone in editable mode:

```bash
python -m pip install -e .
```

The package version is defined in `setup.py`. `jaketts.py` reads the installed package metadata using `importlib.metadata`, so the runtime version output does not need a second hardcoded version string.

Before building a release:

```bash
./test_app.sh
rm -rf dist build *.egg-info
python -m build
python -m twine check dist/*
```

## License

See `LICENSE` for the project's license terms.
