Spaces:
Running
Running
File size: 9,644 Bytes
7c3b38c fa2737f 7c3b38c fa2737f 7c3b38c fa2737f 7c3b38c fa2737f 7c3b38c fa2737f 7c3b38c fa2737f 7c3b38c fa2737f 7c3b38c fa2737f 7c3b38c fa2737f 7c3b38c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 | #!/usr/bin/env python3
"""
setup_examples.py - Gerador completo de arquivos de exemplo para o RVC Full Suite.
Executa: python setup_examples.py
Cria:
- examples/sample_inputs/ (arquivos de entrada: sample_audio.wav, sample_video.mp4)
- examples/sample_outputs/ (5 arquivos: entrada_acapella.mp3, entrada.mp3,
entrada_instrumental.mp3, saida.mp3, saida_acapella.mp3)
Os arquivos são sintéticos (senoides + ruído) e podem ser usados para testar a interface
sem depender de conversões reais. Se quiser exemplos reais, descomente a seção de pipeline.
"""
import os
import subprocess
import sys
import tempfile
from pathlib import Path
# Tenta importar bibliotecas necessárias; se faltarem, instala automaticamente
try:
import numpy as np
from scipy.io.wavfile import write as write_wav
except ImportError:
print("Instalando dependências necessárias...")
subprocess.check_call([sys.executable, "-m", "pip", "install", "numpy", "scipy"])
import numpy as np
from scipy.io.wavfile import write as write_wav
try:
from moviepy.video.io.VideoFileClip import VideoFileClip
from moviepy.audio.io.AudioFileClip import AudioFileClip
except ImportError:
print("Instalando moviepy para geração de vídeo...")
subprocess.check_call([sys.executable, "-m", "pip", "install", "moviepy"])
from moviepy.video.io.VideoFileClip import VideoFileClip
from moviepy.audio.io.AudioFileClip import AudioFileClip
# ============================================================================
# CONFIGURAÇÕES
# ============================================================================
SAMPLE_RATE = 22050
DURATION_SEC = 8 # 8 segundos de exemplo
BASE_DIR = Path(__file__).parent
EXAMPLES_DIR = BASE_DIR / "examples"
INPUTS_DIR = EXAMPLES_DIR / "sample_inputs"
OUTPUTS_DIR = EXAMPLES_DIR / "sample_outputs"
# ============================================================================
# FUNÇÕES DE GERAÇÃO DE ÁUDIO SINTÉTICO
# ============================================================================
def generate_sine_tone(freq_hz, duration_sec, sample_rate):
"""Gera um tom senoidal puro."""
t = np.linspace(0, duration_sec, int(sample_rate * duration_sec), endpoint=False)
return 0.5 * np.sin(2 * np.pi * freq_hz * t)
def generate_voice_like(duration_sec, sample_rate):
"""
Simula uma voz humana com tons modulados (formantes simples).
Combina duas senoides com vibrato.
"""
t = np.linspace(0, duration_sec, int(sample_rate * duration_sec), endpoint=False)
# Frequência fundamental (voz masculina ~110 Hz, feminina ~220 Hz)
f0 = 180.0
# Vibrato: modulação de frequência
vibrato = 5.0 # Hz
freq_mod = f0 + 10 * np.sin(2 * np.pi * vibrato * t)
# Gera a onda com fase acumulada
phase = 2 * np.pi * np.cumsum(freq_mod) / sample_rate
voice = 0.7 * np.sin(phase)
# Adiciona um harmônico (formante)
voice += 0.3 * np.sin(2 * np.pi * 2 * f0 * t)
# Envelope para suavizar início/fim
envelope = np.ones_like(t)
attack = int(0.1 * sample_rate)
decay = int(0.2 * sample_rate)
envelope[:attack] = np.linspace(0, 1, attack)
envelope[-decay:] = np.linspace(1, 0, decay)
voice *= envelope
return voice.astype(np.float32)
def generate_instrumental(duration_sec, sample_rate):
"""Gera um fundo instrumental simples (acorde + percussão leve)."""
t = np.linspace(0, duration_sec, int(sample_rate * duration_sec), endpoint=False)
# Acorde: C maior (262, 330, 392 Hz)
chord = (0.2 * np.sin(2 * np.pi * 262 * t) +
0.2 * np.sin(2 * np.pi * 330 * t) +
0.2 * np.sin(2 * np.pi * 392 * t))
# Percussão: ruído branco filtrado
noise = np.random.normal(0, 0.05, len(t))
# Envelope
envelope = np.ones_like(t)
attack = int(0.05 * sample_rate)
envelope[:attack] = np.linspace(0, 1, attack)
chord *= envelope
noise *= envelope
instrumental = chord + noise
return instrumental.astype(np.float32)
def save_audio(file_path, audio_array, sample_rate=SAMPLE_RATE):
"""Salva array como arquivo WAV e depois converte para MP3 usando ffmpeg."""
# Salva WAV temporário
with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as tmp_wav:
tmp_wav_path = tmp_wav.name
write_wav(tmp_wav_path, sample_rate, audio_array)
# Converte para MP3
subprocess.run([
"ffmpeg", "-y", "-i", tmp_wav_path,
"-acodec", "libmp3lame", "-b:a", "192k",
str(file_path)
], check=True, capture_output=True)
os.unlink(tmp_wav_path)
print(f" ✅ Gerado: {file_path.name}")
# ============================================================================
# GERAÇÃO DOS ARQUIVOS DE EXEMPLO
# ============================================================================
def setup_examples():
print("=" * 60)
print("🎵 Setting up RVC Full Suite Examples")
print("=" * 60)
# Criar diretórios
INPUTS_DIR.mkdir(parents=True, exist_ok=True)
OUTPUTS_DIR.mkdir(parents=True, exist_ok=True)
print(f"📁 Criado: {INPUTS_DIR}")
print(f"📁 Criado: {OUTPUTS_DIR}")
# 1. Gerar áudio de entrada (voz simulada)
print("\n🎤 Gerando áudio de entrada (sample_audio.wav)...")
voice_audio = generate_voice_like(DURATION_SEC, SAMPLE_RATE)
input_wav = INPUTS_DIR / "sample_audio.wav"
write_wav(str(input_wav), SAMPLE_RATE, voice_audio)
print(f" ✅ Criado: {input_wav.name}")
# 2. Gerar vídeo de exemplo com este áudio
print("\n🎬 Gerando vídeo de exemplo (sample_video.mp4)...")
video_path = INPUTS_DIR / "sample_video.mp4"
# Cria um clipe de vídeo com cor sólida e o áudio gerado
from moviepy.video.VideoClip import ColorClip
from moviepy.audio.AudioClip import AudioArrayClip
audio_clip = AudioArrayClip(voice_audio, fps=SAMPLE_RATE)
video_clip = ColorClip(size=(640, 480), color=(50, 100, 150), duration=DURATION_SEC)
video_clip = video_clip.with_audio(audio_clip)
video_clip.write_videofile(str(video_path), fps=24, logger=None, verbose=False)
print(f" ✅ Criado: {video_path.name}")
# 3. Gerar os 5 arquivos de saída sintéticos (simulam resultado do pipeline)
print("\n📦 Gerando 5 arquivos de saída sintéticos (placeholders)...")
# a) entrada.mp3 - o mesmo áudio original
entrada_mp3 = OUTPUTS_DIR / "entrada.mp3"
save_audio(entrada_mp3, voice_audio)
# b) entrada_acapella.mp3 - versão filtrada (voz mais isolada)
# Simula um acapella (apenas a voz, sem instrumental)
save_audio(OUTPUTS_DIR / "entrada_acapella.mp3", voice_audio)
# c) entrada_instrumental.mp3 - instrumental sintético
instrumental = generate_instrumental(DURATION_SEC, SAMPLE_RATE)
save_audio(OUTPUTS_DIR / "entrada_instrumental.mp3", instrumental)
# d) saida.mp3 - RVC sobre original (simula conversão com pitch shift)
# Aplica um pitch shift simples: estica o sinal (exemplo)
from scipy import signal
stretched = signal.resample(voice_audio, int(len(voice_audio) * 1.2)) # +3 semitons aprox
save_audio(OUTPUTS_DIR / "saida.mp3", stretched[:len(voice_audio)])
# e) saida_acapella.mp3 - RVC sobre acapella
# Mesmo tratamento
stretched_acap = signal.resample(voice_audio, int(len(voice_audio) * 1.2))
save_audio(OUTPUTS_DIR / "saida_acapella.mp3", stretched_acap[:len(voice_audio)])
# 4. (Opcional) Executar pipeline real se houver modelos RVC disponíveis
print("\n⚠️ Nota: Os arquivos gerados são SINTÉTICOS (placeholders).")
print(" Para gerar exemplos REAIS com RVC, descomente a seção abaixo")
print(" e certifique-se de ter um modelo carregado e o ffmpeg instalado.\n")
# Exemplo de como chamar o pipeline real (comentado):
"""
from lib.jobs import submit_full_pipeline
from lib.config import MODELS_DIR
# Verifica se há pelo menos um modelo
models = list_models()
if models:
print("🎛️ Executando pipeline real com o primeiro modelo disponível...")
status, acap, orig, instr, saida, saida_acap = submit_full_pipeline(
video_file=None,
audio_mic=None,
audio_file=str(input_wav),
model=models[0],
pitch=0,
f0_method="rmvpe",
index_rate=0.75,
protect=0.5,
vol_env=0.25,
clean_cb=False,
clean_strength=0.5,
split_cb=False,
autotune_cb=False,
autotune_strength=1.0,
filter_radius=3,
output_format="MP3",
reverb_cb=False,
reverb_room=0.15,
reverb_damp=0.7,
reverb_wet=0.15,
)
# Copia os resultados para OUTPUTS_DIR
import shutil
for src, dst_name in [(orig, "entrada.mp3"), (acap, "entrada_acapella.mp3"),
(instr, "entrada_instrumental.mp3"), (saida, "saida.mp3"),
(saida_acap, "saida_acapella.mp3")]:
if src and Path(src).exists():
shutil.copy2(src, OUTPUTS_DIR / dst_name)
print("✅ Exemplos reais gerados com sucesso!")
else:
print("⚠️ Nenhum modelo RVC encontrado. Pulando geração real.")
"""
print("=" * 60)
print("✅ Setup concluído!")
print(f"📁 Arquivos de exemplo disponíveis em: {EXAMPLES_DIR}")
print(" - sample_inputs/ (áudio e vídeo de entrada)")
print(" - sample_outputs/ (5 arquivos de saída sintéticos)")
print("=" * 60)
return True
if __name__ == "__main__":
setup_examples() |