File size: 4,002 Bytes
1b2f7fd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import gradio as gr
import torch
import torchaudio
from torchaudio.transforms import Resample
import numpy as np
import os
from datetime import datetime
import soundfile as sf

# بررسی وجود GPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

def load_audio(file_path, target_sr=16000):
    """بارگذاری فایل صوتی و تبدیل به تنسور"""
    try:
        waveform, sample_rate = torchaudio.load(file_path)
        
        # تغییر نرخ نمونه‌برداری در صورت نیاز
        if sample_rate != target_sr:
            resampler = Resample(sample_rate, target_sr)
            waveform = resampler(waveform)
            
        return waveform.to(device), target_sr
    except Exception as e:
        raise gr.Error(f"خطا در بارگذاری فایل صوتی: {str(e)}")

def preprocess_audio(waveform, sr):
    """پیش‌پردازش سیگنال صوتی"""
    # نرمالایز کردن سیگنال
    waveform = waveform / torch.max(torch.abs(waveform))
    
    # تبدیل به مونو اگر استریو باشد
    if waveform.shape[0] > 1:
        waveform = torch.mean(waveform, dim=0, keepdim=True)
        
    return waveform

def clone_voice(source_audio, target_audio, output_format="wav"):
    """عمل کلون کردن صدا"""
    try:
        # بارگذاری فایل‌های صوتی
        source_waveform, source_sr = load_audio(source_audio)
        target_waveform, target_sr = load_audio(target_audio)
        
        # پیش‌پردازش
        source_waveform = preprocess_audio(source_waveform, source_sr)
        target_waveform = preprocess_audio(target_waveform, target_sr)
        
        # در اینجا باید مدل تبدیل صدا اعمال شود
        # این قسمت ساده‌سازی شده و نیاز به پیاده‌سازی واقعی دارد
        # برای نمونه، فقط طول موج هدف را با طول موج منبع هماهنگ می‌کنیم
        min_len = min(source_waveform.shape[1], target_waveform.shape[1])
        converted_waveform = target_waveform[:, :min_len]
        
        # ذخیره فایل نتیجه
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        output_filename = f"output_{timestamp}.{output_format.lower()}"
        
        # ذخیره با soundfile که با فرمت‌های مختلف کار می‌کند
        sf.write(output_filename, converted_waveform.cpu().numpy().T, target_sr)
        
        return output_filename
    except Exception as e:
        raise gr.Error(f"خطا در پردازش صدا: {str(e)}")

# رابط Gradio
with gr.Blocks(title="Voice Cloner") as demo:
    gr.Markdown("# 🎤 Voice Cloner")
    gr.Markdown("بارگذاری فایل صوتی منبع و فایل صوتی هدف برای کلون کردن صدا")
    
    with gr.Row():
        with gr.Column():
            source_audio = gr.Audio(label="فایل صوتی منبع (صدا برای کپی کردن)", type="filepath")
            target_audio = gr.Audio(label="فایل صوتی هدف (محتوا برای تبدیل)", type="filepath")
            output_format = gr.Dropdown(
                choices=["wav", "mp3"],
                value="wav",
                label="فرمت فایل خروجی",
                interactive=True
            )
            submit_btn = gr.Button("شروع تبدیل صدا")
        
        with gr.Column():
            output_audio = gr.Audio(label="فایل صوتی نتیجه", interactive=False)
            download_link = gr.File(label="دانلود فایل نتیجه")
    
    submit_btn.click(
        fn=clone_voice,
        inputs=[source_audio, target_audio, output_format],
        outputs=[output_audio]
    )
    
    output_audio.change(
        lambda x: gr.File(value=x),
        inputs=[output_audio],
        outputs=[download_link]
    )

if __name__ == "__main__":
    demo.launch()