fix: Update Piper TTS to support voice preview and improve setup
- Fixed preview endpoint to work with both Kokoro and Piper engines - Improved voice model download with curl fallback and SSL handling - Added better error messages when models are missing - Created PIPER_SETUP.md with manual download instructions - Added test_piper_direct.py for testing Piper installation - Updated README with voice model download requirements Note: Piper voice models require manual download from GitHub releases due to HuggingFace URL structure. See PIPER_SETUP.md for instructions.
This commit is contained in:
@@ -385,26 +385,42 @@ async def preview_voice(request: VoicePreviewRequest):
|
||||
preview_text = request.text or "Hello! This is a preview of this voice. How does it sound?"
|
||||
|
||||
try:
|
||||
# Get pipeline for language
|
||||
pipeline = tts_service.get_pipeline(request.lang)
|
||||
|
||||
# Generate preview audio
|
||||
audio = tts_service.synthesize_segment(
|
||||
pipeline=pipeline,
|
||||
text=preview_text,
|
||||
voice=request.voice,
|
||||
speed=request.speed
|
||||
)
|
||||
|
||||
# Convert to WAV bytes
|
||||
import io
|
||||
import soundfile as sf
|
||||
import numpy as np
|
||||
|
||||
# Check which engine is active
|
||||
if tts_service.engine_name == 'kokoro':
|
||||
# Use Kokoro service
|
||||
pipeline = tts_service.kokoro_service.get_pipeline(request.lang)
|
||||
audio = tts_service.kokoro_service.synthesize_segment(
|
||||
pipeline=pipeline,
|
||||
text=preview_text,
|
||||
voice=request.voice,
|
||||
speed=request.speed
|
||||
)
|
||||
sample_rate = tts_service.kokoro_service.SAMPLE_RATE
|
||||
|
||||
elif tts_service.engine_name == 'piper':
|
||||
# Use Piper service with pitch control
|
||||
audio = tts_service.piper_service.synthesize_with_pitch(
|
||||
text=preview_text,
|
||||
voice=request.voice,
|
||||
speed=request.speed,
|
||||
pitch_shift=0 # No pitch shift for preview
|
||||
)
|
||||
sample_rate = tts_service.piper_service.SAMPLE_RATE
|
||||
|
||||
else:
|
||||
raise ValueError(f"Unknown engine: {tts_service.engine_name}")
|
||||
|
||||
# Convert to WAV bytes
|
||||
buffer = io.BytesIO()
|
||||
sf.write(buffer, audio, tts_service.SAMPLE_RATE, format='WAV')
|
||||
sf.write(buffer, audio, sample_rate, format='WAV')
|
||||
buffer.seek(0)
|
||||
audio_bytes = buffer.read()
|
||||
|
||||
logger.info(f"Generated voice preview: {len(audio_bytes)} bytes")
|
||||
logger.info(f"Generated voice preview ({tts_service.engine_name}): {len(audio_bytes)} bytes")
|
||||
|
||||
return StreamingResponse(
|
||||
iter([audio_bytes]),
|
||||
|
||||
Reference in New Issue
Block a user