# Vocal10n — Pipeline Configuration
# For RTX 3060 12GB — All components on single GPU
#
# VRAM Budget (12GB total):
#   Whisper large-v3-turbo:  ~2.5GB
#   Qwen3-4B Q4_K_M:        ~4.0GB
#   GPT-SoVITS (fp16):      ~3.0GB
#   Total:                   ~9.5GB (leaves ~2.5GB headroom)

pipeline:
  name: "Vocal10n"
  target_latency_ms: 2500

  # Component enable switches (all off by default)
  enable_stt: false
  enable_translation: false
  enable_tts: false

  # Translation modes
  enable_pending_translation: true      # Translate pending text for display only
  enable_confirmed_translation: true    # Translate confirmed text for TTS

  # TTS source: "confirmed" | "pending" | "both"
  tts_source: "confirmed"

  # Batching / debounce
  translation_debounce_ms: 150
  confirmed_batch_delay_ms: 400
  tts_queue_max_size: 10
  tts_queue_max_pending: 3       # Drop oldest when queue exceeds this depth
  max_buffer_age_s: 2.0          # Max seconds to buffer confirmed text before flushing
  min_clause_chars: 8            # Min chars before clause-end triggers translation

# --- STT (FasterWhisper) ---------------------------------------------------
stt:
  model_size: "large-v3-turbo"
  device: "cuda"
  compute_type: "int8_float16"

  # Latency tuning
  window_seconds: 6.5
  confirm_threshold: 0.3
  min_transcribe_duration: 0.3
  max_segment_age: 4.0

  # Audio capture
  sample_rate: 16000
  channels: 1
  chunk_duration: 0.2

  # Language: null = auto-detect, "zh", "en"
  language: null
  use_simplified_chinese: true

  # Recognition context / term files
  initial_prompt_capacity: 200   # Max terms to include in Whisper's initial_prompt
  beam_size: 1

# --- Translation (Qwen3-4B via llama-cpp) -----------------------------------
translation:
  backend: "local"           # "local" (GGUF via llama-cpp) or "api" (OpenAI-compatible)
  model_path: "models/llm/Qwen3-4B-Instruct-2507.Q4_K_M.gguf"

  # llama-cpp settings (local backend only)
  n_gpu_layers: -1          # All layers on GPU
  n_ctx: 512
  n_batch: 8
  n_threads: 4

  # OpenAI-compatible API settings (api backend only)
  api_url: "http://localhost:1234/v1"
  api_model: ""              # Empty = auto-detect from server
  api_key: ""                # Optional, for cloud APIs
  api_timeout: 10

  # Generation
  temperature: 0.0
  top_k: 1
  top_p: 1.0
  max_tokens: 64

  target_latency_ms: 200
  target_language: "English"
  auto_detect_source: true
  context_window_size: 2         # Number of previous translations for context
  rag_threshold: 100             # Use vector retrieval when glossary exceeds this many terms

# --- TTS (GPT-SoVITS) ------------------------------------------------------
tts:
  api_host: "127.0.0.1"
  api_port: 9880
  api_timeout: 60

  # Reference audio for voice cloning (mixed Chinese-English)
  ref_audio_path: "vendor/GPT-SoVITS/reference_audio/default_reference.wav"
  ref_audio_text: "在那个Beautiful的清晨，这群Engineer正在迅速地Catch机遇。他们不仅用Alpha系统Fix了Bug，还通过创新，让梦想在现实中绽放。"
  ref_audio_lang: "auto"

  output_lang: "en"

  # Streaming / speed
  streaming_mode: 3
  speed_factor: 1.3

  # Sampling
  top_k: 5
  top_p: 0.7
  temperature: 0.5

  text_split_method: "cut0"
  batch_size: 1

# --- TTS Qwen3 (Qwen3-TTS) -------------------------------------------------
tts_qwen3:
  model_name: "Qwen/Qwen3-TTS-12Hz-0.6B-Base"
  local_model_path: ""           # Set to local directory to skip download
  local_tokenizer_path: ""
  device: "cuda:0"
  dtype: "bfloat16"
  use_flash_attn: true

  # Voice mode: "clone" (use reference audio), "speaker" (built-in voices), "design" (describe voice)
  voice_mode: "clone"

  # Reference audio for voice cloning (used when voice_mode: "clone")
  ref_audio_path: "vendor/GPT-SoVITS/reference_audio/default_reference.wav"
  ref_audio_text: "在那个Beautiful的清晨，这群Engineer正在迅速地Catch机遇。他们不仅用Alpha系统Fix了Bug，还通过创新，让梦想在现实中绽放。"
  ref_audio_lang: "auto"

  # Built-in speaker (used when voice_mode: "speaker")
  # Options: Ryan, Aiden, Vivian, Serena, Uncle_Fu, Dylan, Eric, Ono_Anna, Sohee
  speaker: "Ryan"
  speaker_instruct: ""           # Optional style: e.g., "Speak happily" or "用愤怒的语气说"

  # Voice design (used when voice_mode: "design")
  # Natural language description of desired voice
  design_instruct: ""            # e.g., "Young female voice, high pitch, cheerful"

  output_lang: "en"
  speed_factor: 1.2

  # Generation
  top_k: 50
  top_p: 0.9
  temperature: 1.0
  max_new_tokens: 2048

# --- Audio Output -----------------------------------------------------------
audio_output:
  device: null              # null = system default
  sample_rate: 32000
  buffer_size: 1024
  crossfade_ms: 50

# --- Acoustic Echo Cancellation (AEC) ---------------------------------------
# Prevents TTS playback from being re-transcribed by the STT engine.
# Uses a block-NLMS adaptive filter that continuously models the room
# impulse response, plus a double-talk detector to preserve user voice.
aec:
  enabled: true
  filter_taps: 2048        # NLMS filter length; filter_taps / sample_rate covers the echo tail
                           # 2048 @ 16 kHz = 128 ms — enough for most desktop rooms
  step_size: 0.01          # NLMS adaptation step μ (0.005–0.05 recommended)
  dt_threshold: 3.0        # Double-talk gate: freeze adaptation when
                           # mic_energy > dt_threshold × echo_estimate_energy
  max_delay_ms: 300.0      # Max acoustic delay to search via cross-correlation (ms)

# --- Languages --------------------------------------------------------------
languages:
  English: "en"
  Chinese: "zh"
  Japanese: "ja"
  Korean: "ko"
  Spanish: "es"
  French: "fr"
  German: "de"

# --- OBS Overlay ------------------------------------------------------------
obs:
  host: "127.0.0.1"
  port: 5124
  enable_source_subtitle: true
  enable_target_subtitle: true
  font_family_source: "Noto Sans SC"
  font_family_target: "Noto Sans"
  font_size_source: 28
  font_size_target: 28
  color_source: "#FFFFFF"
  color_target: "#FFE066"

  # Stroke (text outline via -webkit-text-stroke)
  stroke_width_source: 2        # px
  stroke_color_source: "#000000"
  stroke_width_target: 2
  stroke_color_target: "#000000"

  # Shadow (CSS text-shadow)
  shadow_color_source: "#000000"
  shadow_x_source: 0            # px offset
  shadow_y_source: 2
  shadow_blur_source: 4         # px blur radius
  shadow_opacity_source: 80     # 0-100 %
  shadow_color_target: "#000000"
  shadow_x_target: 0
  shadow_y_target: 2
  shadow_blur_target: 4
  shadow_opacity_target: 80

# --- Output Files -----------------------------------------------------------
output:
  save_source_txt: false    # Corrected source transcript with punctuation
  save_source_srt: false    # Corrected source SRT (no punctuation, space-separated)
  save_target_txt: false    # Translated text with punctuation
  save_target_srt: false    # Translated SRT (no punctuation, space-separated)
  save_wav: false           # Raw microphone audio (16 kHz mono WAV)
  directory: "output"

# --- Logging ----------------------------------------------------------------
logging:
  level: "INFO"
  show_latency: true
  show_vram: true
