Carlexxx commited on
Commit
af382fb
·
1 Parent(s): c0e5fc7
audio_specialist.py CHANGED
@@ -1,5 +1,6 @@
1
- # audio_specialist.py (Versão final para áudio dinâmico por fragmento)
2
  # Especialista ADUC para geração de áudio, com gerenciamento de memória GPU.
 
3
 
4
  import torch
5
  import logging
@@ -24,6 +25,10 @@ except ImportError:
24
  logger = logging.getLogger(__name__)
25
 
26
  class AudioSpecialist:
 
 
 
 
27
  def __init__(self, workspace_dir):
28
  self.device = "cuda" if torch.cuda.is_available() else "cpu"
29
  self.cpu_device = torch.device("cpu")
@@ -38,6 +43,7 @@ class AudioSpecialist:
38
  self._load_models_to_cpu()
39
 
40
  def _load_models_to_cpu(self):
 
41
  try:
42
  logger.info("Verificando e baixando modelos MMAudio, se necessário...")
43
  self.model_config.download_if_needed()
@@ -66,12 +72,14 @@ class AudioSpecialist:
66
  self.net = None
67
 
68
  def to_gpu(self):
 
69
  if self.device == 'cpu': return
70
  logger.info(f"Movendo especialista de áudio para a GPU ({self.device})...")
71
  self.net.to(self.device, self.dtype)
72
  self.feature_utils.to(self.device, self.dtype)
73
 
74
  def to_cpu(self):
 
75
  if self.device == 'cpu': return
76
  logger.info("Descarregando especialista de áudio da GPU...")
77
  self.net.to(self.cpu_device)
@@ -79,7 +87,18 @@ class AudioSpecialist:
79
  gc.collect()
80
  if torch.cuda.is_available(): torch.cuda.empty_cache()
81
 
82
- def generate_audio_for_video(self, video_path: str, prompt: str, negative_prompt: str, duration_seconds: float) -> str:
 
 
 
 
 
 
 
 
 
 
 
83
  if self.net is None:
84
  raise gr.Error("Modelo MMAudio não está carregado. Não é possível gerar áudio.")
85
 
@@ -89,6 +108,9 @@ class AudioSpecialist:
89
  logger.info(f"--- Duração: {duration_seconds:.2f}s")
90
  logger.info(f"--- Prompt (Descrição da Cena): '{prompt}'")
91
 
 
 
 
92
  if duration_seconds < 1:
93
  logger.warning("Fragmento muito curto (<1s). Retornando vídeo silencioso.")
94
  logger.info("------------------------------------------------------")
@@ -137,5 +159,5 @@ try:
137
  WORKSPACE_DIR = config['application']['workspace_dir']
138
  audio_specialist_singleton = AudioSpecialist(workspace_dir=WORKSPACE_DIR)
139
  except Exception as e:
140
- logger.error(f"Não foi possível inicializar o AudioSpecialist: {e}")
141
  audio_specialist_singleton = None
 
1
+ # audio_specialist.py
2
  # Especialista ADUC para geração de áudio, com gerenciamento de memória GPU.
3
+ # Copyright (C) 4 de Agosto de 2025 Carlos Rodrigues dos Santos
4
 
5
  import torch
6
  import logging
 
25
  logger = logging.getLogger(__name__)
26
 
27
  class AudioSpecialist:
28
+ """
29
+ Especialista responsável por gerar áudio para fragmentos de vídeo.
30
+ Gerencia o carregamento e descarregamento de modelos de áudio da VRAM.
31
+ """
32
  def __init__(self, workspace_dir):
33
  self.device = "cuda" if torch.cuda.is_available() else "cpu"
34
  self.cpu_device = torch.device("cpu")
 
43
  self._load_models_to_cpu()
44
 
45
  def _load_models_to_cpu(self):
46
+ """Carrega os modelos MMAudio para a memória da CPU na inicialização."""
47
  try:
48
  logger.info("Verificando e baixando modelos MMAudio, se necessário...")
49
  self.model_config.download_if_needed()
 
72
  self.net = None
73
 
74
  def to_gpu(self):
75
+ """Move os modelos e utilitários para a GPU antes da inferência."""
76
  if self.device == 'cpu': return
77
  logger.info(f"Movendo especialista de áudio para a GPU ({self.device})...")
78
  self.net.to(self.device, self.dtype)
79
  self.feature_utils.to(self.device, self.dtype)
80
 
81
  def to_cpu(self):
82
+ """Move os modelos de volta para a CPU e limpa a VRAM após a inferência."""
83
  if self.device == 'cpu': return
84
  logger.info("Descarregando especialista de áudio da GPU...")
85
  self.net.to(self.cpu_device)
 
87
  gc.collect()
88
  if torch.cuda.is_available(): torch.cuda.empty_cache()
89
 
90
+ def generate_audio_for_video(self, video_path: str, prompt: str, duration_seconds: float) -> str:
91
+ """
92
+ Gera áudio para um arquivo de vídeo, aplicando um prompt negativo para evitar fala.
93
+
94
+ Args:
95
+ video_path (str): Caminho para o vídeo silencioso.
96
+ prompt (str): Descrição da cena para guiar a geração de SFX.
97
+ duration_seconds (float): Duração do áudio a ser gerado.
98
+
99
+ Returns:
100
+ str: Caminho para o novo arquivo de vídeo com áudio.
101
+ """
102
  if self.net is None:
103
  raise gr.Error("Modelo MMAudio não está carregado. Não é possível gerar áudio.")
104
 
 
108
  logger.info(f"--- Duração: {duration_seconds:.2f}s")
109
  logger.info(f"--- Prompt (Descrição da Cena): '{prompt}'")
110
 
111
+ negative_prompt = "speech, human voice, talking, vocals, music, singing, dialogue"
112
+ logger.info(f"--- Negative Prompt: '{negative_prompt}'")
113
+
114
  if duration_seconds < 1:
115
  logger.warning("Fragmento muito curto (<1s). Retornando vídeo silencioso.")
116
  logger.info("------------------------------------------------------")
 
159
  WORKSPACE_DIR = config['application']['workspace_dir']
160
  audio_specialist_singleton = AudioSpecialist(workspace_dir=WORKSPACE_DIR)
161
  except Exception as e:
162
+ logger.error(f"Não foi possível inicializar o AudioSpecialist: {e}", exc_info=True)
163
  audio_specialist_singleton = None
prompts/sound_director_prompt.txt.txt ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ROLE: AI Sound Director & Foley Artist
2
+
3
+ # GOAL:
4
+ You are the sound director for a film. Your task is to create a single, rich, and descriptive prompt for an audio generation model (like MMAudio). This prompt must describe the complete soundscape for the CURRENT scene, considering what happened before and what will happen next to ensure audio continuity.
5
+
6
+ # CRITICAL RULES (MUST FOLLOW):
7
+ 1. **NO SPEECH OR VOICES:** The final prompt must NOT include any terms related to human speech, dialogue, talking, voices, singing, or narration. The goal is to create a world of ambient sounds and specific sound effects (SFX).
8
+ 2. **FOCUS ON THE PRESENT:** The audio must primarily match the CURRENT visual scene (Keyframe Kn) and its textual description (Ato_n).
9
+ 3. **USE THE PAST FOR CONTINUITY:** Analyze the "Previous Audio Prompt" to understand the established soundscape. If a sound should logically continue from the previous scene, include it (e.g., "the continued sound of a gentle breeze...").
10
+ 4. **USE THE FUTURE FOR FORESHADOWING:** Analyze the FUTURE keyframe and scene description. If appropriate, introduce subtle sounds that hint at what's to come. (e.g., if the next scene is a storm, you could add "...with the faint, distant rumble of thunder in the background.").
11
+ 5. **BE DESCRIPTIVE:** Use evocative language. Instead of "dog bark", use "the sharp, excited yapping of a small dog". Combine multiple elements into a cohesive soundscape.
12
+
13
+ # CONTEXT FOR YOUR DECISION:
14
+
15
+ - **Previous Audio Prompt (what was just heard):**
16
+ {audio_history}
17
+
18
+ - **VISUAL PAST (Keyframe Kn-1):** [PAST_IMAGE]
19
+ - **VISUAL PRESENT (Keyframe Kn):** [PRESENT_IMAGE]
20
+ - **VISUAL FUTURE (Keyframe Kn+1):** [FUTURE_IMAGE]
21
+
22
+ - **CURRENT Scene Description (Ato_n):** "{present_scene_desc}"
23
+ - **CURRENT Motion Prompt (what the camera is doing):** "{motion_prompt}"
24
+ - **FUTURE Scene Description (Ato_n+1):** "{future_scene_desc}"
25
+
26
+ # RESPONSE FORMAT:
27
+ Respond with ONLY the final, single-line prompt string for the audio generator.