File size: 3,509 Bytes
aaed37a
2158d6f
 
f034b93
6a86f73
aaed37a
6a86f73
2158d6f
6a86f73
 
 
20d8ce9
6a86f73
 
20d8ce9
 
6a86f73
20d8ce9
 
6a86f73
 
 
20d8ce9
6a86f73
 
 
 
20d8ce9
6a86f73
 
f034b93
6a86f73
20d8ce9
6a86f73
 
20d8ce9
6a86f73
 
f034b93
6a86f73
 
 
 
 
 
 
 
 
 
f034b93
 
6a86f73
 
 
 
20d8ce9
f034b93
6a86f73
f034b93
6a86f73
 
f034b93
6a86f73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8d24163
6a86f73
 
 
8d24163
 
6a86f73
 
 
 
 
 
 
aaed37a
 
6a86f73
 
 
 
 
 
20d8ce9
6a86f73
 
 
 
 
 
f034b93
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
102
103
104
105
106
107
108
109
110
111
112
113
import streamlit as st
import librosa
import soundfile as sf
import numpy as np
from scipy import signal
import tempfile
import os

def convert_to_female_voice(audio_path, settings):
    # Load the audio file
    y, sr = librosa.load(audio_path, sr=None)
    
    # Step 1: Pitch shifting (female voice is typically higher)
    y_pitched = librosa.effects.pitch_shift(
        y=y,
        sr=sr,
        n_steps=settings['pitch_steps']
    )
    
    # Step 2: Simple formant shifting using resampling
    alpha = 1.2  # Formant scaling factor
    y_formant = librosa.effects.time_stretch(y_pitched, rate=alpha)
    
    # Step 3: Add slight breathiness
    noise = np.random.normal(0, 0.005, len(y_formant))
    noise_filtered = signal.filtfilt([1], [1, -0.99], noise)
    y_breathy = y_formant + settings['breathiness'] * noise_filtered
    
    # Final normalization
    y_normalized = librosa.util.normalize(y_breathy)
    
    return y_normalized, sr

# Streamlit interface
st.title("Simple Female Voice Converter")

# File upload
audio_file = st.file_uploader("Upload your audio file (WAV or MP3)", type=['wav', 'mp3'])

if audio_file is not None:
    # Save uploaded file temporarily
    with tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(audio_file.name)[1]) as tmp_file:
        tmp_file.write(audio_file.getvalue())
        temp_path = tmp_file.name
    
    # Voice type selection
    voice_type = st.selectbox(
        "Select voice type",
        ["Young Female", "Mature Female", "Custom"]
    )
    
    # Settings based on voice type
    if voice_type == "Young Female":
        settings = {
            'pitch_steps': 4.0,
            'breathiness': 0.1
        }
    elif voice_type == "Mature Female":
        settings = {
            'pitch_steps': 3.0,
            'breathiness': 0.08
        }
    else:  # Custom
        settings = {
            'pitch_steps': st.slider("Pitch (Higher = More Female)", 0.0, 6.0, 4.0, 0.5),
            'breathiness': st.slider("Breathiness", 0.0, 0.2, 0.1, 0.01)
        }
    
    # Convert button
    if st.button("Convert to Female Voice"):
        try:
            # Process the audio
            st.write("Converting... Please wait...")
            converted_audio, sr = convert_to_female_voice(temp_path, settings)
            
            # Save the processed audio
            output_path = "temp_output.wav"
            sf.write(output_path, converted_audio, sr)
            
            # Play the audio
            st.audio(output_path)
            
            # Provide download button
            with open(output_path, 'rb') as audio_file:
                st.download_button(
                    label="Download converted audio",
                    data=audio_file,
                    file_name="female_voice.wav",
                    mime="audio/wav"
                )
            
            # Clean up
            os.remove(temp_path)
            os.remove(output_path)
            
        except Exception as e:
            st.error(f"An error occurred: {str(e)}")

st.markdown("""
### How to use:
1. Upload an audio file (WAV or MP3)
2. Choose a preset or custom settings
3. Click 'Convert to Female Voice'
4. Listen to the result
5. Download if you like it

### Tips for best results:
- Use clear audio with minimal background noise
- Speak in a neutral tone
- Try different settings to find the best match
- Young female voice works best with pitch 4-5
- Mature female voice works best with pitch 3-4
""")