Skip to content

Instantly share code, notes, and snippets.

@insom insom/decode-wav.py
Last active Aug 29, 2015

Embed
What would you like to do?
Decode a VirtualWire encoded thingy
import wave, struct, sys
sixtofour = [ 0xd, 0xe, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c, 0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x32, 0x34 ]
data = []
states = ['START', 'PREAMBLE', 'GOTMAGIC', 'GOTLENGTH']
state = states[0]
bits = []
lengthbits = []
radiodata = []
total_length = 0
def hexify(listofnibs):
byte = 0
o = []
while len(listofnibs) > 1:
hi, lo = listofnibs.pop(0), listofnibs.pop(0)
o.append( (hi << 4) | lo )
return o
def bitstobin(bits):
bits.reverse()
x = 0
for bit in bits:
x <<= 1
x |= bit
return x
w = wave.open('16wut.wav', 'r')
w = wave.open('wut3.wav', 'r')
while True:
f = w.readframes(48000 / 1000)
if not len(f): break
body = f[-2:]
data.append(struct.unpack('h', body)[0] > 0 and 1 or 0)
for i in range(len(data)):
if state == 'START':
if ''.join([str(x) for x in data[i-8:i]]) == '01010101':
print 'GOT PREAMBLE AT %d' % i
state = states[1]
continue
if state == 'PREAMBLE':
if ''.join([str(x) for x in data[i-12:i]]) == '000111001101':
print 'GOT MAGIC AT %d' % i
state = states[2]
bits = []
continue
if state == 'GOTMAGIC':
bits.append(data[i-1:i][0])
if len(bits) == 6:
try:
lengthbits.append(sixtofour.index(bitstobin(bits)))
except:
print "FAILED TO READ A HEX"
bits = []
state = 'START'
continue
print bits
bits = []
if len(lengthbits) == 2:
total_length = (lengthbits[0] << 4) + lengthbits[1]
state = 'GOTLENGTH'
print 'GOTLENGTH AT %d - IT IS %d' % (i, total_length)
continue
if state == 'GOTLENGTH':
bits.append(data[i-1:i][0])
if len(bits) == 6:
try:
radiodata.append(sixtofour.index(bitstobin(bits)))
except:
print "FAILED TO READ A HEX"
bits = []
state = 'START'
continue
bits = []
if len(radiodata) == (total_length * 2) - 4: #screw the checksum
dater = hexify(radiodata)
daters = ['%.2X' % (x) for x in dater]
mac = daters[:6]
temp = '%d.%d' % (dater[7], dater[6])
bat = '%d.%d' % (dater[9], dater[8])
ldr = 1024 - ((dater[11] << 8) + dater[10])
print
print "READING FROM %s - temp:%s bat:%s ldr:%s" % (':'.join(mac), temp, bat, ldr)
print
radiodata = []
state = 'START'
continue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.