Files
vtt_work/sound.py
T
2025-09-16 14:29:35 +02:00

94 lines
3.1 KiB
Python

import numpy as np
import soundfile as sf
from scipy.signal import lfilter, fftconvolve
# Global Parameters
sample_rate = 44100
duration_seconds = 30
samples = duration_seconds * sample_rate
t = np.linspace(0, duration_seconds, samples, endpoint=False)
# === 1. Aggressive White Noise + Reverb ===
def aggressive_white_noise():
noise = np.random.normal(0, 0.07, samples)
# High-pass filter
b = [0.95, -0.95]
a = [1, -0.85]
filtered_noise = lfilter(b, a, noise)
# Reverb via impulse response (short decaying tail)
impulse_response = np.exp(-np.linspace(0, 1.5, int(0.3 * sample_rate)))
impulse_response = impulse_response * np.random.uniform(0.8, 1.2, impulse_response.shape)
reverb_noise = fftconvolve(filtered_noise, impulse_response, mode='full')[:samples]
return reverb_noise
white_noise = aggressive_white_noise()
# === 3. Metallic Sonar Ping with Echo ===
def generate_sonar_ping(start_time, freq=5000, ping_duration=0.82):
ping_t = np.linspace(0, ping_duration, int(sample_rate * ping_duration), endpoint=False)
# FM modulation for metallic texture
mod_freq = 1000 # Modulating frequency
fm_wave = np.sin(2 * np.pi * freq * ping_t + 5 * np.sin(2 * np.pi * mod_freq * ping_t))
envelope = np.exp(-8 * ping_t)
ping = fm_wave * envelope * 0.6
mod_freq = 4000 # Modulating frequency
fm_wave = np.sin(2 * np.pi * freq * ping_t + 5 * np.sin(2 * np.pi * mod_freq * ping_t))
envelope = np.exp(-8 * ping_t)
ping = fm_wave * envelope * 0.9
mod_freq = 7000 # Modulating frequency
fm_wave = np.sin(2 * np.pi * freq * ping_t + 5 * np.sin(2 * np.pi * mod_freq * ping_t))
envelope = np.exp(-8 * ping_t)
ping = fm_wave * envelope * 0.5
# Add echo (delay)
echo_delay = int(0.01 * sample_rate)
echo = np.pad(ping * 0.1, (echo_delay, 0), 'constant')[:len(ping)]
ping = ping + echo
echo_delay = int(0.06 * sample_rate)
echo = np.pad(ping * 0.1, (echo_delay, 0), 'constant')[:len(ping)]
ping = ping + echo
echo_delay = int(0.06 * sample_rate)
echo = np.pad(ping * 0.1, (echo_delay, 0), 'constant')[:len(ping)]
ping = ping + echo
echo_delay = int(0.1 * sample_rate)
echo = np.pad(ping * 0.1, (echo_delay, 0), 'constant')[:len(ping)]
ping = ping + echo
echo_delay = int(0.2 * sample_rate)
echo = np.pad(ping * 0.1, (echo_delay, 0), 'constant')[:len(ping)]
ping = ping + echo
sonar = np.zeros(samples)
start_sample = int(start_time * sample_rate)
end_sample = start_sample + len(ping)
if end_sample <= samples:
sonar[start_sample:end_sample] = ping
return sonar
sonar_total = np.zeros(samples)
np.random.seed(42)
ping_times = np.cumsum(np.random.uniform(0.5, 3.0, size=12))
ping_times = ping_times[ping_times < duration_seconds]
for pt in ping_times:
sonar_total += generate_sonar_ping(pt)
# === 4. Combine & Normalize ===
final_mix = 0.2*white_noise + 3.0*sonar_total
final_mix = final_mix / np.max(np.abs(final_mix))
# === 5. Export ===
file_path = 'test.wav'
sf.write(file_path, final_mix, sample_rate)
print(f"✅ Saved to: {file_path}")