| import os |
| import numpy as np |
| import zipfile |
| from pydub import AudioSegment |
| import streamlit as st |
| from io import BytesIO |
|
|
| |
| def generate_gaussian_noise(duration, sample_rate=44100, std_dev=0.1): |
| """Generate Gaussian noise.""" |
| samples = np.random.normal(0, std_dev, size=(duration * sample_rate,)) |
| audio_segment = AudioSegment( |
| samples.tobytes(), |
| frame_rate=sample_rate, |
| sample_width=2, |
| channels=1 |
| ) |
| return audio_segment |
|
|
| def generate_impulse_noise(duration, sample_rate=44100, impulse_rate=0.05): |
| """Generate impulse noise.""" |
| samples = np.zeros(int(duration * sample_rate)) |
| num_impulses = int(sample_rate * duration * impulse_rate) |
| impulse_indices = np.random.randint(0, len(samples), num_impulses) |
| samples[impulse_indices] = np.random.uniform(-1, 1, size=num_impulses) |
| |
| audio_segment = AudioSegment( |
| samples.tobytes(), |
| frame_rate=sample_rate, |
| sample_width=2, |
| channels=1 |
| ) |
| return audio_segment |
|
|
| def add_noise(audio_file, noise_type='gaussian', noise_level=0.1, start_time=None, end_time=None): |
| """Add noise to a clean audio file.""" |
| audio = AudioSegment.from_file(audio_file) |
| duration = len(audio) |
|
|
| |
| if start_time is not None and end_time is not None: |
| start_time = int(start_time * 1000) |
| end_time = int(end_time * 1000) |
| if start_time < 0 or end_time > duration or start_time >= end_time: |
| st.error("Invalid start or end time.") |
| return None |
| noise_duration = (end_time - start_time) // 1000 |
| else: |
| start_time = 0 |
| end_time = duration |
| noise_duration = duration // 1000 |
|
|
| |
| if noise_type == 'gaussian': |
| noise = generate_gaussian_noise(noise_duration) |
| elif noise_type == 'impulse': |
| noise = generate_impulse_noise(noise_duration) |
| else: |
| st.error("Invalid noise type.") |
| return None |
|
|
| |
| noise_array = np.array(noise.get_array_of_samples()) |
| noise_array = noise_array * noise_level / np.max(np.abs(noise_array)) |
| noise_array = np.clip(noise_array, -1.0, 1.0) |
|
|
| noise = AudioSegment( |
| noise_array.tobytes(), |
| frame_rate=noise.frame_rate, |
| sample_width=noise.sample_width, |
| channels=noise.channels |
| ) |
|
|
| |
| silence = AudioSegment.silent(duration=end_time - start_time) |
| noisy_segment = silence.overlay(noise) |
| |
| noisy_audio = audio[:start_time] + noisy_segment + audio[end_time:] |
| return noisy_audio |
|
|
| |
| def main(): |
| st.title("🎵 Audio Noise Generator") |
| st.sidebar.title("Instructions") |
| st.sidebar.write(""" |
| - Upload one or more audio files (.wav or .mp3). |
| - Choose noise type (Gaussian or Impulse). |
| - Add noise to the full audio or a specific time duration. |
| - Save the processed audio files. |
| """) |
|
|
| |
| uploaded_files = st.file_uploader("Upload Audio Files", type=["wav", "mp3"], accept_multiple_files=True) |
|
|
| |
| noise_type = st.selectbox("Select Noise Type", ["gaussian", "impulse"]) |
|
|
| |
| noise_level = st.slider("Select Noise Level", 0.01, 1.0, 0.1, 0.01) |
|
|
| |
| add_to_specific_duration = st.checkbox("Add noise to specific duration") |
| if add_to_specific_duration: |
| start_time = st.number_input("Start Time (in seconds)", min_value=0.0, value=0.0, step=0.1) |
| end_time = st.number_input("End Time (in seconds)", min_value=0.1, value=1.0, step=0.1) |
| else: |
| start_time, end_time = None, None |
|
|
| |
| if st.button("Process Audio"): |
| if uploaded_files: |
| zip_buffer = BytesIO() |
| with zipfile.ZipFile(zip_buffer, "w") as zf: |
| for uploaded_file in uploaded_files: |
| st.write(f"Processing {uploaded_file.name}...") |
| audio_data = BytesIO(uploaded_file.read()) |
| |
| noisy_audio = add_noise(audio_data, noise_type, noise_level, start_time, end_time) |
| if noisy_audio: |
| |
| base_name, ext = os.path.splitext(uploaded_file.name) |
| output_name = f"{noise_type}_{base_name}.wav" |
|
|
| |
| buffer = BytesIO() |
| noisy_audio.export(buffer, format="wav") |
| buffer.seek(0) |
|
|
| |
| zf.writestr(output_name, buffer.read()) |
| st.success(f"Added {noise_type} noise to {uploaded_file.name}.") |
| |
| zip_buffer.seek(0) |
| st.write("### Download All Processed Files") |
| st.download_button( |
| label="Download All as ZIP", |
| data=zip_buffer, |
| file_name="processed_audio_files.zip", |
| mime="application/zip" |
| ) |
| else: |
| st.warning("Please upload at least one audio file.") |
|
|
| if __name__ == "__main__": |
| main() |
|
|