File size: 4,101 Bytes
416096f 463cfd6 416096f 1bb307a c0b1f61 b56f897 416096f 2d54a75 c0b1f61 7b88a57 c0b1f61 7b88a57 c0b1f61 416096f 463cfd6 c0b1f61 463cfd6 c0b1f61 42e062f c0b1f61 1bb307a 11d3126 c0b1f61 1bb307a 9e479ab e1bc836 416096f c0b1f61 5c3bbd4 c0b1f61 5c3bbd4 9cf73ca c0b1f61 cae93e7 ef5f4d0 c0b1f61 ae54d9a 9cf73ca 5c3bbd4 42e062f 416096f 7b88a57 |
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 |
import numpy as np
import soundfile as sf
from scipy import signal
import gradio as gr
import shutil
import tempfile
from IPython.display import Audio, display
from typing import Tuple
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 with varying loudness and frequency
num_pops = int(duration * pop_rate)
pop_times = np.random.randint(0, num_samples, num_pops)
pop_data = np.zeros(num_samples)
pop_amplitudes = np.random.uniform(0.05, 0.2, num_pops) # Vary pop amplitudes
pop_data[pop_times] = pop_amplitudes # Apply random loudness
# Create a low-pass filter for clicks, with varying filter frequencies for more realistic pops
for i in range(num_pops):
pop_filter_freq = np.random.uniform(0.05, 0.2) # Vary filter frequency
b, a = signal.butter(4, pop_filter_freq)
pop_data[pop_times[i]] = signal.lfilter(b, a, pop_data[pop_times[i]])
# 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 play_and_download_sound(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)
return temp_file, temp_file
iface = gr.Interface(
fn=play_and_download_sound,
inputs=[
gr.inputs.Slider(minimum=0, maximum=0.005, default=0.0005, step=0.0001, 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=600, default=30, step=1, label="Duration (seconds)"),
gr.inputs.Slider(minimum=1, maximum=180, default=10, step=1, label="Pop Rate (pops per second)")
],
outputs=[
gr.outputs.Audio(type="numpy", label="Vinyl Sound"),
gr.outputs.HTML("<button onclick='downloadSound()'>Download Vinyl Sound</button>"
"<script>function downloadSound(){"
"var link = document.createElement('a');"
"link.href = '/download';"
"link.download = 'vinyl_sound.wav';"
"link.click();}</script>")
],
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.0005, 300, 5000, 30, 10],
[0.001, 500, 4000, 30, 50],
[0.002, 200, 6000, 30, 100]
]
)
iface.launch() |