import math import random import struct import wave import os os.makedirs('assets/sounds', exist_ok=True) def write_wav(filename, samples, sample_rate=44100): with wave.open(filename, 'w') as wav_file: wav_file.setnchannels(1) wav_file.setsampwidth(2) wav_file.setframerate(sample_rate) for s in samples: # Clamp and convert to 16-bit val = int(max(-1.0, min(1.0, s)) * 32767) data = struct.pack(' 0.15: seat_env = math.exp(-(t2 - 0.15) * 40.0) seat_click = noise * seat_env * 0.4 sample += seat_click sample += slide # Phase 3: Snap shut (t=0.7) if t >= 0.7: t3 = t - 0.7 snap_env = math.exp(-t3 * 40.0) snap = noise * snap_env * 0.8 ring_env = math.exp(-t3 * 10.0) ring1 = math.sin(t3 * 3500.0 * 2 * math.pi) ring2 = math.sin(t3 * 4200.0 * 2 * math.pi) ring = (ring1 + ring2) * ring_env * 0.1 thud = math.sin(t3 * 80.0 * 2 * math.pi) * math.exp(-t3 * 15.0) * 0.5 sample += snap + ring + thud reload_samples.append(sample) # Global low-pass to smooth out the harsh digital noise prev = 0.0 for i in range(len(reload_samples)): prev = prev + 0.5 * (reload_samples[i] - prev) reload_samples[i] = max(-1.0, min(1.0, prev * 1.5)) write_wav('assets/sounds/shotgun_reload.wav', reload_samples) # 3. Footstep Sound (Quiet Thud + Scrape) footstep_duration = 0.15 footstep_samples = [] for i in range(int(sample_rate * footstep_duration)): t = i / sample_rate noise = random.uniform(-1.0, 1.0) # Dull Thud (lower frequency, less metallic) thud_env = math.exp(-t * 25.0) thud = math.sin(t * 50.0 * 2 * math.pi) * thud_env * 0.15 # Scrape (very quiet, low-passed) scrape_env = math.exp(-t * 50.0) scrape = noise * scrape_env * 0.03 footstep_samples.append(thud + scrape) # Filter footstep to ensure no tin-can high frequencies prev = 0.0 for i in range(len(footstep_samples)): prev = prev + 0.3 * (footstep_samples[i] - prev) footstep_samples[i] = prev write_wav('assets/sounds/footstep.wav', footstep_samples) # 4. Dash Sound (Whoosh) dash_duration = 0.5 dash_samples = [] prev_dash = 0.0 for i in range(int(sample_rate * dash_duration)): t = i / sample_rate noise = random.uniform(-1.0, 1.0) env = math.sin(t * math.pi / dash_duration) ** 2 # Smooth bell curve alpha = 0.1 filtered = prev_dash + alpha * (noise - prev_dash) prev_dash = filtered dash_samples.append(filtered * env * 0.8) write_wav('assets/sounds/dash.wav', dash_samples) # 5. Hit Confirm (Tink/Chirp) hit_duration = 0.2 hit_samples = [] for i in range(int(sample_rate * hit_duration)): t = i / sample_rate env = math.exp(-t * 30.0) # High pitch chirp sweeping slightly freq = 2000.0 + math.exp(-t * 20.0) * 1000.0 tink = math.sin(t * freq * 2 * math.pi) * env * 0.3 hit_samples.append(tink) write_wav('assets/sounds/hit_confirm.wav', hit_samples) # 6. Wallrun (Continuous scrape) # We want this to seamlessly loop wallrun_duration = 1.0 wallrun_samples = [] for i in range(int(sample_rate * wallrun_duration)): t = i / sample_rate noise = random.uniform(-1.0, 1.0) # Give it a slight 4/4 rhythm rhythm = 0.8 + 0.2 * math.sin(t * 8.0 * math.pi) # Low pass to keep it as a dull scrape alpha = 0.05 sample = noise * alpha * rhythm * 0.4 wallrun_samples.append(sample) write_wav('assets/sounds/wallrun.wav', wallrun_samples) # 7. Slide (Continuous deep friction) slide_duration = 1.0 slide_samples = [] for i in range(int(sample_rate * slide_duration)): noise = random.uniform(-1.0, 1.0) # Deeper, steadier scrape than wallrun alpha = 0.02 sample = noise * alpha * 0.5 slide_samples.append(sample) write_wav('assets/sounds/slide.wav', slide_samples) # 8. Wind (Subtle rushing air) wind_duration = 2.0 # Generate 2 seconds sample_count = int(sample_rate * wind_duration) raw_wind = [] prev_wind = 0.0 # Generate extra long to stabilize filter for i in range(sample_count + int(sample_rate * 0.5)): noise = random.uniform(-1.0, 1.0) alpha = 0.015 filtered = prev_wind + alpha * (noise - prev_wind) prev_wind = filtered if i >= int(sample_rate * 0.5): raw_wind.append(filtered * 0.5) # Crossfade the last 0.1s into the first 0.1s to make it perfectly loop crossfade_samples = int(sample_rate * 0.1) loop_wind = raw_wind[:-crossfade_samples] # remove the tail for i in range(crossfade_samples): # Blend the tail into the start tail_sample = raw_wind[-(crossfade_samples - i)] start_sample = loop_wind[i] t = i / float(crossfade_samples) loop_wind[i] = start_sample * t + tail_sample * (1.0 - t) write_wav('assets/sounds/wind.wav', loop_wind) # 9. Jump Sound (Quick exertion / push) jump_duration = 0.2 jump_samples = [] for i in range(int(sample_rate * jump_duration)): t = i / sample_rate noise = random.uniform(-1.0, 1.0) # Lower frequency push (less tin can) push_env = math.exp(-t * 25.0) push = math.sin(t * 60.0 * 2 * math.pi) * push_env * 0.3 # High frequency clothing ruffle (quieter) ruffle_env = math.exp(-t * 30.0) ruffle = noise * ruffle_env * 0.05 jump_samples.append(push + ruffle) # Filter jump to ensure no tin-can high frequencies prev = 0.0 for i in range(len(jump_samples)): prev = prev + 0.4 * (jump_samples[i] - prev) jump_samples[i] = prev write_wav('assets/sounds/jump.wav', jump_samples) # 10. Double Jump Sound (Airy, cloudy whoosh) dj_duration = 0.4 dj_samples = [] prev_dj = 0.0 for i in range(int(sample_rate * dj_duration)): t = i / sample_rate noise = random.uniform(-1.0, 1.0) # Airy filter alpha = 0.05 filtered = prev_dj + alpha * (noise - prev_dj) prev_dj = filtered # Envelope: soft attack, long decay env = (math.exp(-t * 8.0) - math.exp(-t * 40.0)) * 1.5 # Slight pitch movement to give it a "lifting" feel lift = math.sin(t * 150.0 * 2 * math.pi * (1.0 + t)) * env * 0.1 dj_samples.append((filtered * 0.4 + lift) * env) write_wav('assets/sounds/double_jump.wav', dj_samples) # ========================================== # NEW WEAPONS (AK47, M4, MP7, DMR, Plasma, Nail) # ========================================== # 11. AK47 (Heavy punch, low thud, sharp crack) ak_duration = 0.2 ak_samples = [] for i in range(int(sample_rate * ak_duration)): t = i / sample_rate noise = random.uniform(-1.0, 1.0) # Sharp metallic crack crack_env = math.exp(-t * 100.0) crack = noise * crack_env * 0.4 # Deep heavy punch (70Hz sweep down to 40Hz) punch_freq = max(40.0, 70.0 - t * 300.0) punch_env = math.exp(-t * 20.0) punch = math.sin(t * punch_freq * 2 * math.pi) * punch_env * 0.6 # Mechanism ring ring_env = math.exp(-t * 15.0) ring = math.sin(t * 800.0 * 2 * math.pi) * ring_env * 0.05 ak_samples.append(crack + punch + ring) write_wav('assets/sounds/ak47_fire.wav', ak_samples) # 12. M4 (Moderate punch, sharper crack, tighter burst) m4_duration = 0.15 m4_samples = [] for i in range(int(sample_rate * m4_duration)): t = i / sample_rate noise = random.uniform(-1.0, 1.0) crack_env = math.exp(-t * 120.0) crack = noise * crack_env * 0.5 punch_freq = 90.0 punch_env = math.exp(-t * 25.0) punch = math.sin(t * punch_freq * 2 * math.pi) * punch_env * 0.4 m4_samples.append(crack + punch) write_wav('assets/sounds/m4_fire.wav', m4_samples) # 13. MP7 (Very fast, light pop, high pitched) mp7_duration = 0.1 mp7_samples = [] for i in range(int(sample_rate * mp7_duration)): t = i / sample_rate noise = random.uniform(-1.0, 1.0) pop_env = math.exp(-t * 80.0) pop = noise * pop_env * 0.3 punch_freq = 150.0 punch_env = math.exp(-t * 35.0) punch = math.sin(t * punch_freq * 2 * math.pi) * punch_env * 0.2 mp7_samples.append(pop + punch) write_wav('assets/sounds/mp7_fire.wav', mp7_samples) # 14. DMR (Extremely loud, echoing boom, very sharp) dmr_duration = 0.4 dmr_samples = [] for i in range(int(sample_rate * dmr_duration)): t = i / sample_rate noise = random.uniform(-1.0, 1.0) crack_env = math.exp(-t * 50.0) crack = noise * crack_env * 0.6 boom_freq = max(30.0, 60.0 - t * 100.0) boom_env = math.exp(-t * 8.0) boom = math.sin(t * boom_freq * 2 * math.pi) * boom_env * 0.7 tail_env = math.exp(-t * 5.0) tail = noise * tail_env * 0.1 # outdoor echo reflection dmr_samples.append(crack + boom + tail) write_wav('assets/sounds/dmr_fire.wav', dmr_samples) # 15. Plasma Gun (Sci-Fi pew, tonal sweep) plasma_duration = 0.2 plasma_samples = [] for i in range(int(sample_rate * plasma_duration)): t = i / sample_rate # Sweep from 1200 Hz down to 300 Hz rapidly freq = max(300.0, 1200.0 * math.exp(-t * 30.0)) pew_env = math.exp(-t * 15.0) pew = math.sin(t * freq * 2 * math.pi) * pew_env * 0.6 plasma_samples.append(pew) write_wav('assets/sounds/plasma_fire.wav', plasma_samples) # 16. Nail Gun (Clack clack clack, metallic hit) nail_duration = 0.1 nail_samples = [] for i in range(int(sample_rate * nail_duration)): t = i / sample_rate noise = random.uniform(-1.0, 1.0) # Sharp metallic impact hit_env = math.exp(-t * 150.0) hit = noise * hit_env * 0.4 # Ringing metal (two tones) ring_env = math.exp(-t * 40.0) ring = (math.sin(t * 3500.0 * 2 * math.pi) + math.sin(t * 4100.0 * 2 * math.pi)) * ring_env * 0.15 # Mechanism chunk chunk_env = math.exp(-t * 30.0) chunk = math.sin(t * 200.0 * 2 * math.pi) * chunk_env * 0.2 nail_samples.append(hit + ring + chunk) write_wav('assets/sounds/nailgun_fire.wav', nail_samples) # 17. AWP (Thunderous crack, massive bass, slow echo) awp_duration = 0.6 awp_samples = [] for i in range(int(sample_rate * awp_duration)): t = i / sample_rate noise = random.uniform(-1.0, 1.0) crack = noise * math.exp(-t * 80.0) * 0.8 boom = math.sin(t * max(30.0, 80.0 - t * 150.0) * 2 * math.pi) * math.exp(-t * 10.0) * 0.9 awp_samples.append(crack + boom) write_wav('assets/sounds/awp_fire.wav', awp_samples) # 18. Rocket Launcher (Deep thud, whoosh) rocket_duration = 0.4 rocket_samples = [] prev_r = 0.0 for i in range(int(sample_rate * rocket_duration)): t = i / sample_rate noise = random.uniform(-1.0, 1.0) thud = math.sin(t * 50.0 * 2 * math.pi) * math.exp(-t * 20.0) * 0.7 alpha = 0.05 filtered = prev_r + alpha * (noise - prev_r) prev_r = filtered whoosh = filtered * math.exp(-t * 15.0) * 0.5 rocket_samples.append(thud + whoosh) write_wav('assets/sounds/rocket_fire.wav', rocket_samples) # 19. Swarm Launcher (High-pitched whistling zip) swarm_duration = 0.2 swarm_samples = [] for i in range(int(sample_rate * swarm_duration)): t = i / sample_rate noise = random.uniform(-1.0, 1.0) zip_freq = 600.0 + t * 2000.0 pew = math.sin(t * zip_freq * 2 * math.pi) * math.exp(-t * 25.0) * 0.4 swarm_samples.append(pew + noise * math.exp(-t * 50.0) * 0.2) write_wav('assets/sounds/swarm_fire.wav', swarm_samples) # 20. Mortar (Heavy hollow thunk) mortar_duration = 0.3 mortar_samples = [] for i in range(int(sample_rate * mortar_duration)): t = i / sample_rate noise = random.uniform(-1.0, 1.0) thunk_freq = 60.0 thunk = math.sin(t * thunk_freq * 2 * math.pi) * math.exp(-t * 15.0) * 0.7 ring = math.sin(t * 200.0 * 2 * math.pi) * math.exp(-t * 30.0) * 0.2 mortar_samples.append(thunk + ring) write_wav('assets/sounds/mortar_fire.wav', mortar_samples) # 21. Rocket Flight (Deep continuous looping whoosh/rumble) flight_duration = 1.0 # 1 second loop flight_samples = [] prev_f = 0.0 for i in range(int(sample_rate * flight_duration)): t = i / sample_rate noise = random.uniform(-1.0, 1.0) alpha = 0.15 # Higher cutoff for more whoosh filtered = prev_f + alpha * (noise - prev_f) prev_f = filtered rumble = math.sin(t * 70.0 * 2 * math.pi) * 1.5 raw = (filtered * 2.5 + rumble) # Heavy soft clipping to make it sound intensely loud flight_samples.append(math.tanh(raw * 2.0)) write_wav('assets/sounds/rocket_flight.wav', flight_samples) # 22. Swarm Flight (Higher pitched continuous hiss) swarm_flight_samples = [] prev_sf = 0.0 for i in range(int(sample_rate * flight_duration)): t = i / sample_rate noise = random.uniform(-1.0, 1.0) alpha = 0.4 # Higher cutoff for hiss filtered = prev_sf + alpha * (noise - prev_sf) prev_sf = filtered # Aggressive screaming tone whine = math.sin(t * 800.0 * 2 * math.pi) * 1.5 raw = (filtered * 2.0 + whine) # Heavy soft clipping swarm_flight_samples.append(math.tanh(raw * 2.0)) write_wav('assets/sounds/swarm_flight.wav', swarm_flight_samples) # 23. Vault Sound (Quick airy whoosh + clothing ruffle) vault_duration = 0.3 vault_samples = [] prev_v = 0.0 for i in range(int(sample_rate * vault_duration)): t = i / sample_rate noise = random.uniform(-1.0, 1.0) # Airy whoosh alpha = 0.08 filtered = prev_v + alpha * (noise - prev_v) prev_v = filtered whoosh_env = math.sin(t * math.pi / vault_duration) whoosh = filtered * whoosh_env * 0.6 # Ruffle/grab sound ruffle_env = math.exp(-t * 30.0) ruffle = noise * ruffle_env * 0.2 vault_samples.append(whoosh + ruffle) write_wav('assets/sounds/vault.wav', vault_samples) print("Generated all sounds!")