File size: 3,786 Bytes
416096f
463cfd6
416096f
 
463cfd6
 
ae54d9a
416096f
2d54a75
416096f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
463cfd6
 
 
 
 
 
 
 
 
 
 
a5e228d
463cfd6
 
 
a5e228d
ae54d9a
 
 
 
 
416096f
ae54d9a
463cfd6
ae54d9a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
416096f
 
a5e228d
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
import numpy as np
import soundfile as sf
from scipy import signal
import gradio as gr
import shutil
import tempfile
import IPython.display as ipd

def generate_vinyl_sound(noise_ratio, lowcut, highcut, duration, pop_rate):
    # Parameters
    sample_rate = 44100  # sample rate in Hz
    num_samples = int(duration * sample_rate)

    # Generate pink noise
    pink_noise = np.random.normal(0, 1, num_samples)
    b, a = signal.butter(2, [0.002, 0.4], btype='band')
    pink_noise = signal.lfilter(b, a, pink_noise)

    # Apply band-pass filter to pink noise
    nyquist_rate = 0.5 * sample_rate
    low = lowcut / nyquist_rate
    high = highcut / nyquist_rate
    b, a = signal.butter(1, [low, high], btype='band')
    pink_noise = signal.lfilter(b, a, pink_noise)

    # Generate low-frequency rumble
    rumble_noise = np.random.normal(0, 1, num_samples)
    b, a = signal.butter(2, 0.002, btype='low')
    rumble_noise = signal.lfilter(b, a, rumble_noise)

    # Generate high-frequency hiss
    hiss_noise = np.random.normal(0, 1, num_samples)
    b, a = signal.butter(2, 0.4, btype='high')
    hiss_noise = signal.lfilter(b, a, hiss_noise)

    # Generate pops
    num_pops = int(duration * pop_rate)
    pop_times = np.random.randint(0, num_samples, num_pops)
    pop_data = np.zeros(num_samples)
    pop_data[pop_times] = np.random.normal(0, 1, num_pops) * 0.2  # random loudness

    # Create a simple low-pass filter to make the pops sound more like clicks
    b, a = signal.butter(4, 0.1)
    pop_data = signal.lfilter(b, a, pop_data)

    # Combine the noises and pops
    vinyl_sound = noise_ratio * (pink_noise + 0.05 * rumble_noise + 0.05 * hiss_noise) + (1 - noise_ratio) * pop_data

    # Normalize to between -1 and 1
    vinyl_sound /= np.max(np.abs(vinyl_sound))

    return vinyl_sound.astype(np.float32), sample_rate

def convert_to_wav(data, sample_rate):
    # Normalize to between -1 and 1
    data /= np.max(np.abs(data))

    # Save to a temporary .wav file
    temp_file = tempfile.mktemp(suffix=".wav")
    sf.write(temp_file, data, sample_rate)

    return temp_file

def download_wav(noise_ratio, lowcut, highcut, duration, pop_rate):
    data, sample_rate = generate_vinyl_sound(noise_ratio, lowcut, highcut, duration, pop_rate)
    temp_file = convert_to_wav(data, sample_rate)
    shutil.move(temp_file, "download.wav")
    return "download.wav"

def play_wav(noise_ratio, lowcut, highcut, duration, pop_rate):
    data, sample_rate = generate_vinyl_sound(noise_ratio, lowcut, highcut, duration, pop_rate)
    ipd.display(ipd.Audio(data, rate=sample_rate))
    return None

iface = gr.Interface(
    fn=None,  # We don't need a main function
    inputs=[
        gr.inputs.Slider(minimum=0, maximum=1, default=0.001, step=0.001, label="Noise Ratio"),
        gr.inputs.Slider(minimum=20, maximum=20000, default=300, step=10, label="Lowcut Frequency (Hz)"),
        gr.inputs.Slider(minimum=20, maximum=20000, default=5000, step=10, label="Highcut Frequency (Hz)"),
        gr.inputs.Slider(minimum=1, maximum=60, default=10, step=1, label="Duration (seconds)"),
        gr.inputs.Slider(minimum=1, maximum=100, default=10, step=1, label="Pop Rate (pops per second)")
    ],
    outputs=[
        gr.outputs.File(label="Download Vinyl Sound", type="auto", convert=download_wav),
        gr.outputs.Button(label="Play Vinyl Sound", type="auto", callback=play_wav)
    ],
    title="Vinyl Sound Generator",
    description="Generate a synthetic vinyl sound using pink noise, rumble, hiss, and pops. Adjust the noise ratio, bandpass frequencies, duration, and pop rate to modify the sound.",
    examples=[
        [0.001, 300, 5000, 10, 10],
        [0.002, 500, 4000, 15, 20],
        [0.005, 200, 6000, 20, 30]
    ]
)

iface.launch(inbrowser=True)