194 lines
5.0 KiB
Python

import numpy as np
from scipy.io import wavfile
import random
import sys
import subprocess # to play the resulting wave file
import datetime # EAS alerts are heavily dependent on timestamps so this makes it easy to send a thing now
import argparse
# NicksMadScience same eas encoder was modified by iRaven @ iravenhome.net (github.com/iraven4522)
# version 0.2? to add a custom outfile path. :D
# parse command-line arguments
parser = argparse.ArgumentParser()
parser.add_argument("--playaudiolive", "-pal", nargs='?', default=-1)
parser.add_argument("--code", "-c", nargs='?', default="none")
parser.add_argument("--outfile","-o", nargs='?', default="same.wav")
args = parser.parse_args()
######## CONFIG / constants ########
markBitFrequency = 2083 + (1/3)
spaceBitFrequency = 1562.5
print (args)
fs = 43750
# t = 1.0 / (520 + (5/6))
# f = 2083.33333
samples = np.zeros(0)
def markBit():
global markBitFrequency
# f = 2083.33333
f = markBitFrequency
t = 1.0 / (520 + (5/6))
samples = np.arange(t * fs) / fs
roffle = np.sin(2 * np.pi * f * samples)
return roffle * 0.8
def spaceBit():
global spaceBitFrequency
# f = 1562.5
f = spaceBitFrequency
t = 1.0 / (520 + (5/6))
samples = np.arange(t * fs) / fs
return np.sin(2 * np.pi * f * samples)
signal = np.zeros(20000)
def byte(the_byte):
sys.stdout.write(the_byte)
sys.stdout.write(" ")
byte_data = np.zeros(0)
for i in range(0, 8):
if ord(the_byte) >> i & 1:
sys.stdout.write("1")
byte_data = np.append(byte_data, markBit())
else:
sys.stdout.write("0")
byte_data = np.append(byte_data, spaceBit())
sys.stdout.write("\n")
sys.stdout.flush()
return byte_data
def extramarks(numberOfMarks):
"""SAGE encoders seem to add a few mark bits at the beginning and end"""
byte_data = np.zeros(0)
for i in range(0, numberOfMarks):
byte_data = np.append(byte_data, markBit())
return byte_data
def preamble():
byte_data = np.zeros(0)
for i in range(0, 16):
byte_data = np.append(byte_data, markBit())
byte_data = np.append(byte_data, markBit())
byte_data = np.append(byte_data, spaceBit())
byte_data = np.append(byte_data, markBit())
byte_data = np.append(byte_data, spaceBit())
byte_data = np.append(byte_data, markBit())
byte_data = np.append(byte_data, spaceBit())
byte_data = np.append(byte_data, markBit())
return byte_data
# ZCZC-WXR-RWT-020103-020209-020091-020121-029047-029165-029095-029037+0030-1051700-KEAX/NWS
# code = "ZCZC-EAS-RMT-011000+0100-2141800-SCIENCE-"
# code = "ZCZC-WXR-TOR-000000+0030-2142200-SCIENCE -"
# code = "ZCZC-PEP-EAN-000000+0400-2142350-SCIENCE -"
# control string
# code = "ZCZC-EAS-RMT-011000+0100-2142200-KMMS FM -"
# useful FIPS codes
# 000000 - the whole fucking united states
# 024031 - silver spring, md / montgomery county
# 011001 - district of columbia
# EAS alerts are heavily dependent on timestamps so this makes it easy/fun to send a thing now
sameCompatibleTimestamp = datetime.datetime.now().strftime("%j%H%M")
# known good
# OH SHIT it's all time-dependent
# which i can now do since the time works on the box
#code = "ZCZC-PEP-EAN-000000+0400-" + sameCompatibleTimestamp + "-SCIENCE -" # nuclear armageddon (or some other form of "we are all likely to die")
# code = "ZCZC-PEP-EAT-000000+0400-" + sameCompatibleTimestamp + "-SCIENCE -" # nuclear armageddon (or some other form of "we are all likely to die")
# code = "ZCZC-PEP-EAT-000000+0400-2142350-SCIENCE -" # lol jk no nuclear armageddon
code = "ZCZC-WXR-TOR-024031+0030-" + sameCompatibleTimestamp + "-SCIENCE -" # tornado warning, silver spring, md
# code = "ZCZC-WXR-SVR-024031+0030-2142200-SCIENCE -" # severe thunderstorm warning, silver spring, md
# code = "ZCZC-WXR-EVI-024031+0030-" + sameCompatibleTimestamp + "-SCIENCE -" # evacuation immediate!!, silver spring, md
# code = "ZCZC-WXR-FFW-024031+0030-2150021-SCIENCE -"
# testing
# code = "ZCZC-CIV-LAE-024031+0030-2150022-SCIENCE -"
# code = "ZCZC-CIV-CDW-024031+0400-" + sameCompatibleTimestamp + "-SCIENCE -"
# code = "ZCZC-PEP-EAN-024031+0030-" + sameCompatibleTimestamp + "-SCIENCE -"
# code = "ZCZC-ROFL-WTF-012345+0000-YO WADDUP MOTHAFUCKAZ="
code = args.code
for i in range(0, 3):
# signal = np.append(signal, extramarks(10))
signal = np.append(signal, preamble())
# turn each character into a sequence of sine waves
for char in code:
signal = np.append(signal, byte(char))
# signal = np.append(signal, extramarks(6)) # ENDEC might not be as picky about this as I once thought
signal = np.append(signal, np.zeros(43750)) # wait the requisite one second
# EOM (3x)
for i in range(0, 3):
# signal = np.append(signal, extramarks(10))
signal = np.append(signal, preamble())
for char in "NNNN": # NNNN = End Of Message
signal = np.append(signal, byte(char))
# signal = np.append(signal, extramarks(6))
signal = np.append(signal, np.zeros(43750)) # wait the requisite one second
signal *= 32767
signal = np.int16(signal)
wavfile.write(f'{args.outfile}', fs, signal)
if args.playaudiolive == "1":
subprocess.call("afplay same.wav", shell=True)