"""OpenAI-compatible TTS Server for AX650 NPU3. Start: python -m inflect_tts_sdk.server --port 8000 API: POST /v1/audio/speech """ from __future__ import annotations import io, sys, argparse from pathlib import Path try: from fastapi import FastAPI from fastapi.responses import Response import uvicorn except ImportError: sys.exit("pip install fastapi uvicorn") def create_app(model_dir: str | None = None): app = FastAPI(title="Inflect-Micro-v2 TTS", version="1.0.0") engine = None def get_engine(): nonlocal engine if engine is None: sys.path.insert(0, str(Path(__file__).resolve().parent)) from tts_engine import InflectTTSEngine engine = InflectTTSEngine(model_dir=model_dir) return engine @app.get("/health") async def health(): return {"status": "ok", "model": "inflect-micro-v2", "hw": "AX650-NPU3"} @app.get("/v1/models") async def models(): return {"object": "list", "data": [ {"id": "inflect-micro-v2", "object": "model", "owned_by": "owensong"} ]} @app.post("/v1/audio/speech") async def speech(request: dict): text = request.get("input", "") if not text: return Response(status_code=400) eng = get_engine() sr, wav = eng.synthesize( text, speed=float(request.get("speed", 1.0)), variation=float(request.get("variation", 0.667)), ) buf = io.BytesIO() import soundfile as sf sf.write(buf, wav, sr, format="WAV") return Response(content=buf.getvalue(), media_type="audio/wav") return app def main(): ap = argparse.ArgumentParser() ap.add_argument("--host", default="0.0.0.0") ap.add_argument("--port", type=int, default=8000) ap.add_argument("--model-dir", default=None) args = ap.parse_args() app = create_app(args.model_dir) print(f"🎤 Inflect-Micro-v2 TTS Server → http://{args.host}:{args.port}") uvicorn.run(app, host=args.host, port=args.port) if __name__ == "__main__": main()