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 """)