FILMITO commited on
Commit
bef0e2d
Β·
verified Β·
1 Parent(s): 5e60fe8

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +118 -0
app.py ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import numpy as np
3
+ import librosa
4
+ import soundfile as sf
5
+ from scipy import signal
6
+ import io
7
+
8
+ def change_voice(audio, voice_preset, custom_pitch, custom_speed):
9
+ """
10
+ Transform voice with selected preset or custom settings
11
+ """
12
+ if audio is None:
13
+ return None, "Please record or upload audio first!"
14
+
15
+ presets = {
16
+ "Sophia (Soft)": {"pitch": 1.5, "speed": 1.0},
17
+ "Emma (Professional)": {"pitch": 1.4, "speed": 1.1},
18
+ "Olivia (Young)": {"pitch": 1.7, "speed": 1.15},
19
+ "Ava (Mature)": {"pitch": 1.3, "speed": 0.95},
20
+ "Isabella (Sweet)": {"pitch": 1.6, "speed": 1.05},
21
+ "Mia (Dramatic)": {"pitch": 1.55, "speed": 0.9},
22
+ "Custom": {"pitch": custom_pitch, "speed": custom_speed}
23
+ }
24
+
25
+ settings = presets[voice_preset]
26
+ pitch_factor = settings["pitch"]
27
+ speed_factor = settings["speed"]
28
+
29
+ try:
30
+ sr, y = audio
31
+
32
+ if y.dtype == np.int16:
33
+ y = y.astype(np.float32) / 32768.0
34
+ elif y.dtype == np.int32:
35
+ y = y.astype(np.float32) / 2147483648.0
36
+
37
+ if len(y.shape) > 1:
38
+ y = np.mean(y, axis=1)
39
+
40
+ y_shifted = librosa.effects.pitch_shift(y, sr=sr, n_steps=12 * np.log2(pitch_factor))
41
+
42
+ if speed_factor != 1.0:
43
+ y_shifted = librosa.effects.time_stretch(y_shifted, rate=speed_factor)
44
+
45
+ if pitch_factor > 1.2:
46
+ nyquist = sr / 2
47
+ formant_freqs = [800, 1150, 2900, 3900]
48
+ for freq in formant_freqs:
49
+ if freq < nyquist:
50
+ b, a = signal.butter(2, [max(freq-100, 20)/nyquist, min(freq+100, nyquist-1)/nyquist], btype='band')
51
+ filtered = signal.filtfilt(b, a, y_shifted)
52
+ y_shifted = y_shifted + filtered * 0.1
53
+
54
+ y_shifted = y_shifted / np.max(np.abs(y_shifted)) * 0.9
55
+ y_shifted = (y_shifted * 32768).astype(np.int16)
56
+
57
+ message = f"βœ… Voice transformed to {voice_preset}!\nPitch: {pitch_factor:.2f}x | Speed: {speed_factor:.2f}x"
58
+ return (sr, y_shifted), message
59
+
60
+ except Exception as e:
61
+ return None, f"❌ Error processing audio: {str(e)}"
62
+
63
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="pink")) as demo:
64
+
65
+ gr.Markdown("""
66
+ # 🎀 Professional Voice Changer
67
+ ### Transform your voice with AI-powered female voice presets
68
+ """)
69
+
70
+ with gr.Row():
71
+ with gr.Column(scale=1):
72
+ gr.Markdown("### πŸŽ™οΈ Input Audio")
73
+ audio_input = gr.Audio(sources=["microphone", "upload"], type="numpy", label="Record or Upload Audio")
74
+
75
+ gr.Markdown("### 🎡 Voice Settings")
76
+ voice_preset = gr.Radio(
77
+ choices=["Sophia (Soft)", "Emma (Professional)", "Olivia (Young)", "Ava (Mature)", "Isabella (Sweet)", "Mia (Dramatic)", "Custom"],
78
+ value="Sophia (Soft)",
79
+ label="Choose Voice Profile",
80
+ info="Select a preset or use Custom for manual control"
81
+ )
82
+
83
+ with gr.Accordion("πŸŽ›οΈ Custom Settings", open=False):
84
+ custom_pitch = gr.Slider(minimum=1.0, maximum=2.0, value=1.5, step=0.1, label="Pitch Multiplier", info="Higher = More feminine")
85
+ custom_speed = gr.Slider(minimum=0.5, maximum=1.5, value=1.0, step=0.05, label="Speed Multiplier", info="Adjust speaking speed")
86
+
87
+ transform_btn = gr.Button("✨ Transform Voice", variant="primary", size="lg")
88
+
89
+ with gr.Column(scale=1):
90
+ gr.Markdown("### πŸ”Š Output Audio")
91
+ audio_output = gr.Audio(label="Transformed Voice", type="numpy")
92
+ status_output = gr.Textbox(label="Status", lines=3, interactive=False)
93
+
94
+ gr.Markdown("""
95
+ ### πŸ“ Voice Profile Details
96
+ - **Sophia (Soft)**: Gentle and warm tone
97
+ - **Emma (Professional)**: Clear and confident
98
+ - **Olivia (Young)**: Energetic and bright
99
+ - **Ava (Mature)**: Deep and authoritative
100
+ - **Isabella (Sweet)**: Friendly and cheerful
101
+ - **Mia (Dramatic)**: Expressive and bold
102
+ - **Custom**: Set your own pitch and speed
103
+ """)
104
+
105
+ transform_btn.click(fn=change_voice, inputs=[audio_input, voice_preset, custom_pitch, custom_speed], outputs=[audio_output, status_output])
106
+
107
+ gr.Markdown("""
108
+ ---
109
+ ### πŸ’‘ Tips:
110
+ - 🎀 **Recording**: Speak clearly and at normal volume
111
+ - πŸ“ **Upload**: Supports WAV, MP3, and other audio formats
112
+ - 🎚️ **Pitch**: Range 1.0-2.0 (higher = more feminine)
113
+ - ⚑ **Speed**: Range 0.5-1.5 (adjust speaking pace)
114
+ - πŸ’Ύ **Download**: Click the download button on the output audio player
115
+ """)
116
+
117
+ if __name__ == "__main__":
118
+ demo.launch()