#!/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()