-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstaticbyte.py
More file actions
executable file
·145 lines (115 loc) · 3.2 KB
/
staticbyte.py
File metadata and controls
executable file
·145 lines (115 loc) · 3.2 KB
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/usr/bin/env python -u
"""staticbyte.py - encode a stream of bytes as static noise
Usage:
python -u staticbyte.py (-e | -d) <FILE> [-s <N>]
python -u staticbyte.py -h
Options:
-s Set the chip size (default: 4096)
-h Print this help
"""
from __future__ import print_function
import numpy
import os
import sys
import wave
__author__ = 'Mansour Moufid'
__email__ = 'mansourmoufid@gmail.com'
__license__ = 'ISC'
__status__ = 'Development'
__version__ = '0.1'
PCM_DTYPE = numpy.int16
PCM_MAX = 2.0 ** (16 - 1) - 1.0
def readbytes(f):
while True:
char = f.read(1)
if char == '':
break
byte = ord(char)
yield byte
def xcor(x, y):
x = numpy.copy(x)
y = numpy.copy(y[::-1])
n = x.size + y.size
x.resize(n)
y.resize(n)
X = numpy.fft.rfft(x)
Y = numpy.fft.rfft(y)
Z = X * Y
z = numpy.fft.irfft(Z, n=n)
return z
def modxcor(x, y):
z = xcor(x, y)
n = y.size
return z[(n // 2):-(n // 2)]
class Chip(object):
def __init__(self, size, seed=None):
self.size = size
numpy.random.seed(seed)
def codes(self, n):
return numpy.float32(numpy.random.normal(0.0, 0.2, self.size * n))
if __name__ == '__main__':
if len(sys.argv) == 2 and sys.argv[1] == '-h':
print(__doc__)
sys.exit(0)
try:
encode = '-e' in sys.argv
i = sys.argv.index('-e' if encode else '-d')
filename = sys.argv[i + 1]
if '-s' in sys.argv:
i = sys.argv.index('-s')
size = int(sys.argv[i + 1])
else:
size = 2 ** 12
except:
print(__doc__)
sys.exit(os.EX_USAGE)
tty = os.ctermid()
prompt = '\xF0\x9F\x94\x91 '
with open(tty, 'w') as f:
f.write(prompt)
with open(tty, 'r') as f:
line = f.readline()
key = line.rstrip('\n')
key = int(key)
chip = Chip(size, seed=key)
FS = 44100
SAMPWIDTH = 2
NCHANNELS = 1
if encode:
wav = wave.open(filename, 'wb')
wav.setframerate(FS)
wav.setsampwidth(SAMPWIDTH)
wav.setnchannels(NCHANNELS)
else:
wav = wave.open(filename, 'rb')
sampwidth = wav.getsampwidth()
nchannels = wav.getnchannels()
nframes = wav.getnframes()
fs = wav.getframerate()
assert fs == FS
assert sampwidth == SAMPWIDTH
assert nchannels == NCHANNELS
if encode:
for byte in readbytes(sys.stdin):
codes = chip.codes(2 ** 8)
i = byte * chip.size
j = i + chip.size
pcm = PCM_DTYPE(codes[i:j] * PCM_MAX)
frames = pcm.tostring()
wav.writeframes(frames)
else:
while True:
frames = wav.readframes(chip.size)
if len(frames) == 0:
break
pcm = numpy.fromstring(frames, dtype=PCM_DTYPE)
data = numpy.float32(pcm)
data = data / (PCM_MAX + 1.0)
codes = chip.codes(2 ** 8)
xc = modxcor(codes, data)
i = numpy.argmax(xc ** 2)
byte = i / chip.size
if sys.stdout.isatty():
byte &= 127
sys.stdout.write(chr(byte))
wav.close()