File size: 5,301 Bytes
8517a17
 
ac8753d
8517a17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ac8753d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8517a17
ac8753d
 
 
 
 
 
 
 
8517a17
 
 
 
 
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import os
import numpy as np
import zipfile
from pydub import AudioSegment
import streamlit as st
from io import BytesIO

# Noise generation functions
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,  # 16-bit audio
        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,  # 16-bit audio
        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)

    # Check for specific duration
    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

    # Generate noise
    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

    # Normalize noise
    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
    )

    # Overlay noise for the specified segment
    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

# Streamlit App
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.
    """)

    # Upload files
    uploaded_files = st.file_uploader("Upload Audio Files", type=["wav", "mp3"], accept_multiple_files=True)

    # Noise type selection
    noise_type = st.selectbox("Select Noise Type", ["gaussian", "impulse"])

    # Noise level
    noise_level = st.slider("Select Noise Level", 0.01, 1.0, 0.1, 0.01)

    # Duration selection
    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

    # Process and save files
    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:
                        # Rename file based on noise type
                        base_name, ext = os.path.splitext(uploaded_file.name)
                        output_name = f"{noise_type}_{base_name}.wav"

                        # Save to in-memory buffer
                        buffer = BytesIO()
                        noisy_audio.export(buffer, format="wav")
                        buffer.seek(0)

                        # Add to zip archive
                        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()