RVC-CH / setup_examples.py
LosCaquitos's picture
Update setup_examples.py
fa2737f verified
raw
history blame
9.64 kB
#!/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()