Artificial-superintelligence commited on
Commit
4851afd
·
verified ·
1 Parent(s): 6a86f73

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +50 -84
app.py CHANGED
@@ -2,112 +2,78 @@ import streamlit as st
2
  import librosa
3
  import soundfile as sf
4
  import numpy as np
5
- from scipy import signal
6
  import tempfile
7
- import os
8
 
9
- def convert_to_female_voice(audio_path, settings):
10
  # Load the audio file
11
- y, sr = librosa.load(audio_path, sr=None)
12
 
13
- # Step 1: Pitch shifting (female voice is typically higher)
14
- y_pitched = librosa.effects.pitch_shift(
15
- y=y,
16
- sr=sr,
17
- n_steps=settings['pitch_steps']
18
- )
19
 
20
- # Step 2: Simple formant shifting using resampling
21
- alpha = 1.2 # Formant scaling factor
22
- y_formant = librosa.effects.time_stretch(y_pitched, rate=alpha)
23
 
24
- # Step 3: Add slight breathiness
25
- noise = np.random.normal(0, 0.005, len(y_formant))
26
- noise_filtered = signal.filtfilt([1], [1, -0.99], noise)
27
- y_breathy = y_formant + settings['breathiness'] * noise_filtered
28
-
29
- # Final normalization
30
- y_normalized = librosa.util.normalize(y_breathy)
31
 
32
  return y_normalized, sr
33
 
34
- # Streamlit interface
35
- st.title("Simple Female Voice Converter")
 
 
 
 
 
36
 
37
- # File upload
38
- audio_file = st.file_uploader("Upload your audio file (WAV or MP3)", type=['wav', 'mp3'])
39
 
40
- if audio_file is not None:
41
  # Save uploaded file temporarily
42
- with tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(audio_file.name)[1]) as tmp_file:
43
- tmp_file.write(audio_file.getvalue())
44
- temp_path = tmp_file.name
45
-
46
- # Voice type selection
47
- voice_type = st.selectbox(
48
- "Select voice type",
49
- ["Young Female", "Mature Female", "Custom"]
50
- )
51
-
52
- # Settings based on voice type
53
- if voice_type == "Young Female":
54
- settings = {
55
- 'pitch_steps': 4.0,
56
- 'breathiness': 0.1
57
- }
58
- elif voice_type == "Mature Female":
59
- settings = {
60
- 'pitch_steps': 3.0,
61
- 'breathiness': 0.08
62
- }
63
- else: # Custom
64
- settings = {
65
- 'pitch_steps': st.slider("Pitch (Higher = More Female)", 0.0, 6.0, 4.0, 0.5),
66
- 'breathiness': st.slider("Breathiness", 0.0, 0.2, 0.1, 0.01)
67
- }
68
 
69
- # Convert button
70
  if st.button("Convert to Female Voice"):
 
71
  try:
72
- # Process the audio
73
- st.write("Converting... Please wait...")
74
- converted_audio, sr = convert_to_female_voice(temp_path, settings)
75
-
76
- # Save the processed audio
77
- output_path = "temp_output.wav"
78
- sf.write(output_path, converted_audio, sr)
79
 
80
- # Play the audio
81
- st.audio(output_path)
82
 
83
- # Provide download button
84
- with open(output_path, 'rb') as audio_file:
85
- st.download_button(
86
- label="Download converted audio",
87
- data=audio_file,
88
- file_name="female_voice.wav",
89
- mime="audio/wav"
90
- )
91
 
92
- # Clean up
93
- os.remove(temp_path)
94
- os.remove(output_path)
 
 
 
 
95
 
96
  except Exception as e:
97
- st.error(f"An error occurred: {str(e)}")
98
 
 
99
  st.markdown("""
100
- ### How to use:
101
- 1. Upload an audio file (WAV or MP3)
102
- 2. Choose a preset or custom settings
103
  3. Click 'Convert to Female Voice'
104
- 4. Listen to the result
105
- 5. Download if you like it
106
 
107
- ### Tips for best results:
108
- - Use clear audio with minimal background noise
109
- - Speak in a neutral tone
110
- - Try different settings to find the best match
111
- - Young female voice works best with pitch 4-5
112
- - Mature female voice works best with pitch 3-4
113
  """)
 
2
  import librosa
3
  import soundfile as sf
4
  import numpy as np
5
+ from io import BytesIO
6
  import tempfile
 
7
 
8
+ def process_audio(audio_file, pitch_factor=8):
9
  # Load the audio file
10
+ y, sr = librosa.load(audio_file)
11
 
12
+ # Pitch shift using librosa (female voice typically higher pitch)
13
+ y_shifted = librosa.effects.pitch_shift(y, sr=sr, n_steps=pitch_factor)
 
 
 
 
14
 
15
+ # Apply some feminine characteristics
16
+ # Smooth the audio slightly
17
+ y_smooth = librosa.effects.preemphasis(y_shifted)
18
 
19
+ # Normalize audio
20
+ y_normalized = librosa.util.normalize(y_smooth)
 
 
 
 
 
21
 
22
  return y_normalized, sr
23
 
24
+ def save_audio(audio_data, sr):
25
+ # Save processed audio to BytesIO object
26
+ buffer = BytesIO()
27
+ sf.write(buffer, audio_data, sr, format='WAV')
28
+ return buffer
29
+
30
+ st.title("Voice Changer - Female Voice Conversion")
31
 
32
+ # File uploader
33
+ uploaded_file = st.file_uploader("Upload an audio file", type=['wav', 'mp3'])
34
 
35
+ if uploaded_file is not None:
36
  # Save uploaded file temporarily
37
+ with tempfile.NamedTemporaryFile(delete=False, suffix='.wav') as tmp_file:
38
+ tmp_file.write(uploaded_file.getvalue())
39
+ tmp_path = tmp_file.name
40
+
41
+ # Pitch adjustment slider
42
+ pitch_factor = st.slider("Pitch Adjustment", 0.0, 12.0, 8.0, 0.5)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
 
44
  if st.button("Convert to Female Voice"):
45
+ # Process the audio
46
  try:
47
+ processed_audio, sr = process_audio(tmp_path, pitch_factor)
 
 
 
 
 
 
48
 
49
+ # Save processed audio
50
+ audio_buffer = save_audio(processed_audio, sr)
51
 
52
+ # Create download button
53
+ st.audio(audio_buffer, format='audio/wav')
 
 
 
 
 
 
54
 
55
+ # Add download button
56
+ st.download_button(
57
+ label="Download Converted Audio",
58
+ data=audio_buffer,
59
+ file_name="female_voice.wav",
60
+ mime="audio/wav"
61
+ )
62
 
63
  except Exception as e:
64
+ st.error(f"Error processing audio: {str(e)}")
65
 
66
+ # Add instructions
67
  st.markdown("""
68
+ ### Instructions:
69
+ 1. Upload a WAV or MP3 audio file
70
+ 2. Adjust the pitch slider (higher values = more feminine voice)
71
  3. Click 'Convert to Female Voice'
72
+ 4. Play the converted audio
73
+ 5. Download the result if satisfied
74
 
75
+ ### Notes:
76
+ - Best results with clear audio input
77
+ - Recommended pitch adjustment: 6-8 for natural-sounding results
78
+ - Larger files may take longer to process
 
 
79
  """)