---
name: eapil-voice
description: Guide agents to call the hosted Eapil-Voice/Qwen3 Voice Design FastAPI service by domain for audio generation workflows. Use when a task asks to synthesize speech, design a voice from an instruction, clone a voice from reference audio, use VoxCPM2 or Qwen providers, enhance or denoise audio, transcribe audio through this service, batch-ASR/clone alert sounds, export generated speech as WAV/MP3, check model health, or produce curl/Python calls for the Eapil-Voice API.
---

# Eapil-Voice

## Purpose

Use this skill to call the hosted Eapil-Voice API by domain. Prefer the existing API surface over inventing client contracts.

Default base URL is `https://ades.playones.com`. Override it only when the user gives another domain or `QWEN3_VOICE_API_BASE_URL`.

Use `OPENAI_API_KEY` as the API key environment variable. If it is not set and the user did not provide a key directly, tell the user to get their key from `https://kinfo.playones.com`. Direct key use is allowed with `--token` or an `Authorization: Bearer <key>` header.

## Call Workflow

1. Resolve the base URL first. Use `https://ades.playones.com` unless the user gives another domain.
2. Check `GET /health` before expensive generation.
3. Add `Authorization: Bearer <key>` from an explicit user-provided key or `OPENAI_API_KEY`.
4. Choose the endpoint by desired output:
   - Voice from style instruction: `POST /v1/voice/design`.
   - Base TTS by speaker name: `POST /v1/voice/synthesize`.
   - Voice clone from reference audio: `POST /v1/voice/clone`.
   - Speech enhancement or denoise: `POST /v1/audio/enhance` or `POST /v1/audio/denoise`.
   - Transcription: `POST /v1/asr/transcribe` returns JSON, not audio.
5. Save audio-output responses as `.wav`; these endpoints return `audio/wav`.
6. Read `/openapi.json` from the active base URL when exact current form fields matter.
7. Read `references/api.md` before writing detailed client code, exposing all services, troubleshooting errors, or selecting Qwen vs VoxCPM2 parameters.
8. Read `references/batch-audio.md` before batch ASR/clone/export work, especially game filter alert sounds.

## Provider Rules

Use `provider=qwen` by default. Only `/v1/voice/design` and `/v1/voice/clone` accept `provider=voxcpm2`.

For VoxCPM2:
- Pass `provider=voxcpm2`.
- Use `cfg_value`, `inference_timesteps`, `normalize`, `denoise`, and `retry_badcase` for generation controls.
- Set `denoise=true` only when the server is configured with `VOXCPM2_LOAD_DENOISER=true`.
- For clone with `ref_text`, expect Hi-Fi transcript-guided cloning.
- For clone without `ref_text`, use `instruct` for controllable cloning.

For Qwen clone, always provide both `text` and `ref_text`.

## Batch Audio Rules

- For many short alert sounds, ask only if the output mode is genuinely ambiguous: generated-only files, full replacement files, or overlay/mix.
- Do not assume ASR segment timestamps are source-separation masks. ASR can locate/transcribe speech; it cannot remove an old voice from mixed music/SFX by itself.
- If the user wants clean replacement assets for another tool, export generated speech only, named after the source files. Use `scripts/batch_clone_generated_audio.py`.
- If the user wants to preserve music/SFX while replacing embedded speech, state that source separation or stems are required for clean removal. Do not mix the original voice under the generated voice unless the user explicitly asks for overlay.
- Normalize generated text before clone: add expressive punctuation when useful; if the final character is not `。！？.!?~～`, append `。` for Chinese alert text.
- For final MP3 delivery, convert the generated WAVs with `ffmpeg` and explicit gain such as `volume=4dB` only when requested.

## Quick Examples

Use JSON for voice design and synthesis:

```bash
BASE_URL="${QWEN3_VOICE_API_BASE_URL:-https://ades.playones.com}"

curl -X POST "$BASE_URL/v1/voice/design" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"provider":"qwen","text":"Hello world","instruct":"Warm, calm, natural narration","language":"auto","temperature":0.9,"max_tokens":4096,"top_k":50,"top_p":1.0,"repetition_penalty":1.05}' \
  --output voice_design.wav
```

Use multipart form data for clone, enhancement, denoise, and ASR:

```bash
BASE_URL="${QWEN3_VOICE_API_BASE_URL:-https://ades.playones.com}"

curl -X POST "$BASE_URL/v1/voice/clone" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -F 'file=@reference.wav' \
  -F 'provider=qwen' \
  -F 'text=This is the cloned sentence.' \
  -F 'ref_text=Transcript of the reference audio.' \
  -F 'language=auto' \
  -F 'temperature=0.9' \
  -F 'max_tokens=4096' \
  -F 'top_k=50' \
  -F 'top_p=1.0' \
  -F 'repetition_penalty=1.05' \
  --output voice_clone.wav
```

Use the bundled dependency-free client when convenient:

```bash
python ~/.codex/skills/eapil-voice/scripts/call_voice_api.py design \
  --text "Hello world" \
  --instruct "Warm, calm, natural narration" \
  --out voice_design.wav
```

Batch clone generated speech only, preserving source names:

```bash
python ~/.codex/skills/eapil-voice/scripts/batch_clone_generated_audio.py \
  --base-url https://ades.playones.com \
  --token "$OPENAI_API_KEY" \
  --input-dir "/path/to/filter-sounds" \
  --reference-audio reference.wav \
  --output-dir "/path/to/generated-mp3" \
  --format mp3 \
  --gain-db 4
```

On Windows, prefer direct command execution or a single quoted `Start-Process -ArgumentList` string for paths containing spaces or CJK characters.

## Source Anchors

When a local source checkout is available and the task depends on implementation details, use it only as source reference. Do not prefer local service startup over the hosted domain:

- `/Users/eapil/git/QWEN3-Voice-Design/app/api/routes/voice.py`
- `/Users/eapil/git/QWEN3-Voice-Design/app/api/routes/audio.py`
- `/Users/eapil/git/QWEN3-Voice-Design/app/api/routes/asr.py`
- `/Users/eapil/git/QWEN3-Voice-Design/app/schemas/voice.py`
- `/Users/eapil/git/QWEN3-Voice-Design/README.md`
