Files
diodiogod-TTS-Audio-Suite/utils/system/subprocess.py
T
diodiogod b21d0212fb Major refactoring: Reorganize project structure for better maintainability
🔧 ENGINES SEPARATION:
- Move chatterbox/ → engines/chatterbox/ (TTS/VC engine + models)
- Move chatterbox/f5tts/ → engines/f5tts/ (F5-TTS engine)
- Move adapters/ → engines/adapters/ (engine adapters for multilingual system)

📁 NODES ORGANIZATION:
- Create nodes/chatterbox/ for ChatterBox nodes (TTS, VC, SRT)
- Create nodes/f5tts/ for F5-TTS nodes (TTS, SRT, Edit, Options)
- Create nodes/audio/ for audio processing nodes (analyzer, recorder)
- Create nodes/base/ for base classes
- Rename node files for clarity (tts_node.py → chatterbox_tts_node.py)

🗂️ UTILITIES RESTRUCTURE:
- Replace core/ with organized utils/ structure
- utils/audio/ - Audio processing, analysis, caching
- utils/text/ - Text processing, character parsing, chunking
- utils/voice/ - Voice discovery, multilingual engine
- utils/timing/ - SRT timing logic (from chatterbox_srt/)
- utils/models/ - Model management (ChatterBox + F5-TTS)
- utils/system/ - System utilities, import management

🔄 IMPORT PATH UPDATES:
- Update all import paths to use new organized structure
- Fix lazy imports in nodes for runtime compatibility
- Restore missing F5-TTS edit engine from git history
- Fix path resolution for voice discovery and character aliases

🎯 KEY IMPROVEMENTS:
- Engine-centric organization with clear separation
- Purpose-driven folder grouping for better navigation
- Self-documenting file names indicating ownership
- Scalable structure for future engine additions
- Maintains backward compatibility for existing workflows

All 10 nodes loading successfully with complete functionality preserved.
2025-08-02 18:50:26 -03:00

114 lines
4.0 KiB
Python

#!/usr/bin/env python3
"""
ChatterBox TTS Subprocess Wrapper
This script runs ChatterBox TTS generation in an isolated subprocess to prevent
CUDA crashes from affecting the main ComfyUI process.
Usage:
python chatterbox_subprocess.py --text "Hello world" --reference_audio "path/to/ref.wav" --output "output.wav"
"""
import sys
import os
import argparse
import json
import traceback
import tempfile
import torch
import numpy as np
from pathlib import Path
# Add the project root to Python path
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))
def main():
parser = argparse.ArgumentParser(description='ChatterBox TTS Subprocess')
parser.add_argument('--text', required=True, help='Text to synthesize')
parser.add_argument('--reference_audio', required=True, help='Path to reference audio')
parser.add_argument('--output', required=True, help='Output audio file path')
parser.add_argument('--device', default='auto', help='Device to use (auto/cuda/cpu)')
parser.add_argument('--exaggeration', type=float, default=0.5, help='Exaggeration factor')
parser.add_argument('--temperature', type=float, default=0.8, help='Temperature')
parser.add_argument('--cfg_weight', type=float, default=0.5, help='CFG weight')
parser.add_argument('--seed', type=int, default=0, help='Random seed')
args = parser.parse_args()
try:
# Import ChatterBox TTS modules
from engines.chatterbox.tts import ChatterboxTTS
import torchaudio
print(f"🔄 Subprocess: Loading ChatterBox TTS on {args.device}...")
# Initialize ChatterBox TTS
if args.device == 'auto':
device = 'cuda' if torch.cuda.is_available() else 'cpu'
else:
device = args.device
chatterbox = ChatterboxTTS.from_pretrained(device=device)
print(f"🔄 Subprocess: Loading reference audio from {args.reference_audio}...")
# Load reference audio
ref_audio, sample_rate = torchaudio.load(args.reference_audio)
# Ensure mono audio
if ref_audio.shape[0] > 1:
ref_audio = ref_audio.mean(dim=0, keepdim=True)
# Resample if necessary
if sample_rate != chatterbox.sr:
resampler = torchaudio.transforms.Resample(sample_rate, chatterbox.sr)
ref_audio = resampler(ref_audio)
print(f"🔄 Subprocess: Generating speech for text: '{args.text[:50]}...'")
# Set seed for reproducibility
if args.seed != 0:
torch.manual_seed(args.seed)
if torch.cuda.is_available():
torch.cuda.manual_seed(args.seed)
# Generate audio
generated_audio = chatterbox.generate(
text=args.text,
reference_audio=ref_audio,
exaggeration=args.exaggeration,
temperature=args.temperature,
cfg_weight=args.cfg_weight
)
print(f"🔄 Subprocess: Saving audio to {args.output}...")
# Save output audio
torchaudio.save(args.output, generated_audio.cpu(), chatterbox.sr)
# Return success info
duration = generated_audio.size(-1) / chatterbox.sr
result = {
'success': True,
'output_path': args.output,
'duration': duration,
'sample_rate': chatterbox.sr,
'audio_shape': list(generated_audio.shape)
}
print(f"✅ Subprocess: Generation completed successfully ({duration:.2f}s)")
print(json.dumps(result))
except Exception as e:
error_result = {
'success': False,
'error': str(e),
'traceback': traceback.format_exc()
}
print(f"❌ Subprocess: Generation failed: {e}")
print(json.dumps(error_result))
sys.exit(1)
if __name__ == "__main__":
main()