Skip to content

Instantly share code, notes, and snippets.

@qubodup
Created May 2, 2026 09:22
Show Gist options
  • Select an option

  • Save qubodup/4014e12186a88bd282748e180ca59ebd to your computer and use it in GitHub Desktop.

Select an option

Save qubodup/4014e12186a88bd282748e180ca59ebd to your computer and use it in GitHub Desktop.
Super duper serious SCP broadcast message audio generator
# genAI did this
# cc0 or wtfpl
import numpy as np
from scipy.signal import butter, lfilter
import wave, tempfile, os, asyncio, subprocess, sys
import edge_tts
SR = 44100
# ---------- basic ----------
def write_wav(path, x):
m = np.max(np.abs(x))
if m > 0:
x = x / m
x = np.int16(x * 32767)
with wave.open(path, "w") as f:
f.setnchannels(1)
f.setsampwidth(2)
f.setframerate(SR)
f.writeframes(x.tobytes())
def tone(f, d):
t = np.linspace(0, d, int(SR*d), False)
return np.sin(2*np.pi*f*t)
def silence(d):
return np.zeros(int(SR*d))
def gain(x, g):
return x * g
# ---------- EAS ----------
def afsk(text):
mark, space = 2083.3, 1562.5
bd = 1/520.83
bits = "".join(format(ord(c), "08b") for c in text)
return np.concatenate([tone(mark if b=="1" else space, bd) for b in bits])
def attention(d=8):
t = np.linspace(0, d, int(SR*d), False)
sig = 0.5*np.sin(2*np.pi*853*t) + 0.5*np.sin(2*np.pi*960*t)
return np.tanh(sig * 1.3)
# ---------- DSP ----------
def bandpass(x):
b,a = butter(4, [300/(SR/2), 3000/(SR/2)], btype="band")
return lfilter(b,a,x)
def process_voice(x):
x = bandpass(x)
x += np.random.normal(0, 0.008, len(x))
return np.tanh(x * 1.6)
# ---------- TTS ----------
async def tts_async(text, voice):
mp3 = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name
t = edge_tts.Communicate(text, voice=voice, rate="-12%")
await t.save(mp3)
proc = subprocess.run([
"ffmpeg",
"-i", mp3,
"-f", "s16le",
"-acodec", "pcm_s16le",
"-ac", "1",
"-ar", str(SR),
"-"
], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
os.unlink(mp3)
if proc.returncode != 0:
raise RuntimeError("ffmpeg failed")
x = np.frombuffer(proc.stdout, dtype=np.int16).astype(np.float32)
return x / 32767.0
# ---------- build ----------
def build(voice_audio, header3, attn):
voice_audio = process_voice(voice_audio)
return np.concatenate([
silence(0.5),
header3,
silence(0.5),
attn,
silence(0.5),
gain(voice_audio, 2.0),
silence(0.5),
header3
])
# ---------- voices ----------
async def get_voices():
voices = await edge_tts.list_voices()
return sorted([v["ShortName"] for v in voices])
def select_voices(all_voices):
while True:
print("\nAvailable voices:\n")
for i, v in enumerate(all_voices):
print(f"{i:3d}: {v}")
print("\nOptions:")
print(" a -> all voices")
print(" <number> -> single voice")
print(" <text> -> filter (e.g. en-US)")
print(" q -> quit\n")
choice = input("> ").strip()
if not choice or choice.lower() == "q":
print("Exit")
sys.exit(0)
if choice.lower() == "a":
return all_voices
if choice.isdigit():
idx = int(choice)
if 0 <= idx < len(all_voices):
return [all_voices[idx]]
else:
print("Invalid index -> exit")
sys.exit(1)
filtered = [v for v in all_voices if choice.lower() in v.lower()]
if not filtered:
print("No matches -> exit")
sys.exit(1)
print("\nFiltered voices:\n")
for i, v in enumerate(filtered):
print(f"{i:3d}: {v}")
confirm = input("\nUse these? (y/n/q): ").strip().lower()
if confirm == "y":
return filtered
elif confirm == "n":
continue # go back to main selection
elif confirm == "q":
print("Exit")
sys.exit(0)
else:
print("Invalid input -> exit")
sys.exit(1)
# ---------- main ----------
async def main():
voices = await get_voices()
selected = select_voices(voices)
print(f"\nSelected {len(selected)} voice(s)\n")
# precompute static audio
header = afsk("ZCZC-EAS-DMO-XXX+0030-1234567-KXXX/NWS-")
header3 = gain(np.concatenate([header, silence(1), header, silence(1), header]), 0.5)
attn = gain(attention(), 0.5)
message = (
"This is an emergency action notification. "
"A containment breach involving SCP YADDA YADDA BLAH BLAH WHATEVER has been confirmed. "
"All civilians must remain indoors. "
"Avoid all contact with unidentified biological entities. "
"This is not a test. "
"Or is it! "
)
for v in selected:
try:
print(f"[+] {v}", flush=True)
voice_audio = await tts_async(message, v)
audio = build(voice_audio, header3, attn)
safe = v.replace(":", "").replace("/", "_")
write_wav(f"eas_{safe}.wav", audio)
print(f"[OK] {v}", flush=True)
except Exception as e:
print(f"[FAIL] {v} -> {e}", flush=True)
# ---------- run ----------
if __name__ == "__main__":
asyncio.run(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment