Skip to main content

🎙️ VoiSona Talk Proxy

A tiny proxy that makes local VoiSona Talk speech synthesis available over the network.

NOTE: This is an unofficial project and is not affiliated with, endorsed by, or supported by the maker of VoiSona Talk. Please do not contact them for support about this package.

💎 Features

  • 🌐 Access VoiSona Talk speech synthesis from other machines over the network
  • ⚡️ Respond faster by reusing cached audio for repeated requests
  • 🐍 Provide Python client for direct local use

📦 Installation

Requirements:

  • Python 3.11+
  • VoiSona Talk running locally
  • Local VoiSona Talk API available at http://127.0.0.1:32766/api/talk/v1

Install:

pip install voisona-talk-proxy

🚀 Quick Start

Start the proxy server:

voisona-talk-proxy --host 0.0.0.0 --port 32777

Underscore command and Python module forms are also available:

voisona_talk_proxy --host 0.0.0.0 --port 32777
python -m voisona_talk_proxy --host 0.0.0.0 --port 32777

Synthesize speech:

curl -u your-voisona-talk-user:your-voisona-talk-password \
  -X POST http://127.0.0.1:32777/speech-syntheses \
  -H "Content-Type: application/json" \
  -o output.wav \
  -d '{
    "text": "こんにちは",
    "language": "ja_JP",
    "voice_name": "tanaka-san_ja_JP"
  }'

Or open the browser playground: http://127.0.0.1:32777/playground/

The playground can load installed voices, synthesize text, preview the generated audio, and download the WAV file.

You can also mount the proxy inside your own FastAPI app:

from fastapi import FastAPI
from voisona_talk_proxy.proxy import VoisonaProxy

app = FastAPI()
proxy = VoisonaProxy(
    # username="your-voisona-talk-user",
    # password="your-voisona-talk-password",
)
app.include_router(proxy.get_api_router())

🧩 API Usage

Routes:

  • GET /voices
  • POST /speech-syntheses
  • DELETE /cache
  • DELETE /cache/{voice_name}
  • GET /health
  • GET /playground/
  • compatible /api/talk/v1/... paths for API routes above, except /playground/

NOTE: See the official VoiSona Talk API manual for request payload details.

GET /playground/

Opens a small browser page for testing speech synthesis, previewing audio, and downloading WAV files.

GET /voices

Returns installed voice libraries from the local VoiSona Talk API.

curl http://127.0.0.1:32777/voices

Example shape:

{
  "items": [
    {
      "voice_name": "tanaka-san_ja_JP",
      "voice_version": "2.0.1",
      "languages": ["ja_JP"]
    }
  ]
}

POST /speech-syntheses

Synthesizes speech and returns audio/wav.

Minimal request:

curl -X POST http://127.0.0.1:32777/speech-syntheses \
  -H "Content-Type: application/json" \
  -o output.wav \
  -d '{
    "text": "Hello!",
    "language": "ja_JP",
    "voice_name": "tanaka-san_ja_JP"
  }'

Credentials can be sent with HTTP Basic auth. In Swagger UI, use Authorize and enter your VoiSona username and password.

curl -u your-voisona-talk-user:your-voisona-talk-password \
  -X POST http://127.0.0.1:32777/speech-syntheses \
  -H "Content-Type: application/json" \
  -o output.wav \
  -d '{
    "text": "Hello!",
    "language": "ja_JP",
    "voice_name": "tanaka-san_ja_JP"
  }'

If HTTP Basic auth is omitted, the proxy falls back to credentials configured at startup with --username / --password or VOISONA_USERNAME / VOISONA_PASSWORD.

Request schema:

Field Type Required Notes
language string Yes Language code from the selected voice library, for example ja_JP.
text string Conditional Text to synthesize. Required unless non-empty analyzed_text is set. Max length: 500.
analyzed_text string Conditional Analyzed text generated by text analysis. If non-empty, text is ignored for synthesis. Max length: 50000.
voice_name string No Voice library name.
voice_version string No Voice library version.
global_parameters object No Global voice parameters such as speed, pitch, intonation, volume, huskiness, alp, and style_weights.
phoneme_durations number[] No Requested phoneme durations in seconds. Negative values mean automatic.

The proxy also accepts additional VoiSona request fields for compatibility. destination, output_file_path, force_enqueue, and can_overwrite_file are ignored by the proxy and sent upstream as proxy-managed values: destination="file", output_file_path=<cache path>, force_enqueue=true, and can_overwrite_file=true.

Full request example with /voices values and global_parameters:

import httpx

base_url = "http://127.0.0.1:32777"

voices = httpx.get(f"{base_url}/voices").json()
voice = voices["items"][0]

payload = {
    "text": "こんにちは",
    "language": voice["languages"][0],
    "voice_name": voice["voice_name"],
    "voice_version": voice["voice_version"],
    "global_parameters": {
        "alp": 0.0,
        "huskiness": 0.0,
        "intonation": 1.0,
        "pitch": 0.0,
        "speed": 2.0,
        "style_weights": [],
        "volume": 0.0,
    },
}

audio = httpx.post(f"{base_url}/speech-syntheses", json=payload).content

with open("output.wav", "wb") as f:
    f.write(audio)

GET /health

Returns a simple health check response.

curl http://127.0.0.1:32777/health
{"status": "ok"}

DELETE /cache

Clears cached audio for the default voice cache.

curl -X DELETE http://127.0.0.1:32777/cache
{"cleared": true, "voice_name": "default"}

You can also clear one voice cache by path or query parameter:

curl -X DELETE http://127.0.0.1:32777/cache/tanaka-san_ja_JP
curl -X DELETE "http://127.0.0.1:32777/cache?voice_name=tanaka-san_ja_JP"

🍪 Cache

The proxy caches generated audio under voisona_talk_cache/<voice_name>/<cache_key>.wav.

If voice_name is missing, the cache goes under default.

Set the proxy cache directory with --cache-dir:

voisona-talk-proxy --host 0.0.0.0 --port 32777 --cache-dir /path/to/cache

Or use VOISONA_CACHE_DIR:

export VOISONA_CACHE_DIR=/path/to/cache
voisona-talk-proxy --host 0.0.0.0 --port 32777

When mounting the proxy in your own FastAPI app, pass cache_dir to VoisonaProxy:

from fastapi import FastAPI
from voisona_talk_proxy.proxy import VoisonaProxy

app = FastAPI()
proxy = VoisonaProxy(
    # username="your-voisona-talk-user",
    # password="your-voisona-talk-password",
    cache_dir="/path/to/cache",
)
app.include_router(proxy.get_api_router())

⚙️ Configurations

CLI arguments take precedence over environment variables.

Setting CLI argument Environment variable Default
Listen host --host - 127.0.0.1
Listen port --port - 32777
VoiSona Talk API URL --voisona-url VOISONA_BASE_URL http://127.0.0.1:32766/api/talk/v1
Username --username VOISONA_USERNAME -
Password --password VOISONA_PASSWORD -
Cache directory --cache-dir VOISONA_CACHE_DIR voisona_talk_cache
Log level --log-level VOISONA_LOG_LEVEL info

Example:

export VOISONA_BASE_URL=http://127.0.0.1:32766/api/talk/v1
export VOISONA_USERNAME=your-voisona-talk-user
export VOISONA_PASSWORD=your-voisona-talk-password
export VOISONA_CACHE_DIR=/path/to/cache
export VOISONA_LOG_LEVEL=debug

voisona-talk-proxy --host 0.0.0.0 --port 32777

If VOISONA_USERNAME and VOISONA_PASSWORD are set, or --username and --password are passed, the proxy uses those credentials for requests that do not include HTTP Basic auth. In that mode, clients do not need to send credentials on every request.

NOTE: For more advanced FastAPI or Uvicorn settings, create your own main program and mount VoisonaProxy there.

🐍 Python Local Mode

from voisona_talk_proxy.client import VoisonaTalkClient

client = VoisonaTalkClient(
    base_url="http://127.0.0.1:32766/api/talk/v1",
)

audio = await client.synthesize({
    "text": "Hello!",
    "language": "ja_JP",
    "voice_name": "tanaka-san_ja_JP",
})

with open("output.wav", "wb") as f:
    f.write(audio)

await client.close()

You can also use get_voices() and pass values from an installed voice library. This is useful when you want to choose voices dynamically.

voices = await client.get_voices()
voice = voices["items"][0]

audio = await client.synthesize({
    "text": "Hello!",
    "language": voice["languages"][0],
    "voice_name": voice["voice_name"],
    "voice_version": voice["voice_version"],
})

Per-request credentials can also be passed as method arguments:

voices = await client.get_voices(username="user", password="pass")
audio = await client.synthesize(payload, username="user", password="pass")

🧪 Tests

The tests use the real local VoiSona Talk API, not mocks. Put your local API URL and credentials in pytest.ini, then run:

python -m pytest tests/

🌧️ Thanks

We built this repository to make 🌧️ 雨衣 / Ui's voice easier to use in all kinds of scenes. Thank you for the wonderful voice! ✨🙏✨

⚖️ License

MIT. Use it freely, and please share what you create with it on SNS!

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

voisona_talk_proxy-0.2.0.tar.gz (18.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

voisona_talk_proxy-0.2.0-py3-none-any.whl (17.2 kB view details)

Uploaded Python 3

File details

Details for the file voisona_talk_proxy-0.2.0.tar.gz.

File metadata

  • Download URL: voisona_talk_proxy-0.2.0.tar.gz
  • Upload date:
  • Size: 18.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for voisona_talk_proxy-0.2.0.tar.gz
Algorithm Hash digest
SHA256 994f6d496f2a374996b0163cfae0a59bcbb43c1465aa9a294b3fefd54bdc4bfd
MD5 b92c15c67537d0d30da02cdb1f50c144
BLAKE2b-256 24a9a7611618f78b650ee8d481f19f785b37f3949e6a894d8f83c81f19da7b37

See more details on using hashes here.

File details

Details for the file voisona_talk_proxy-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for voisona_talk_proxy-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4d4ecc06f7ed000b885346db12b4d923cf1d6c85b7eb52abc2c19d77d3b16dac
MD5 5dd29af24cc987bd5ba3d4e71eb0f642
BLAKE2b-256 e10271305bd29415ae8a282eed3a0452073c84fe6417c2a6af9e7081a186aa69

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page