Skip to content

Instantly share code, notes, and snippets.

@Ludo6431
Created December 4, 2011 22:29
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save Ludo6431/1431500 to your computer and use it in GitHub Desktop.
Save Ludo6431/1431500 to your computer and use it in GitHub Desktop.
KORG Monotribe AFSK firmware decoder
# -*- coding: utf-8 -*-
# KORG monotribe firmware decoder by:
# Ludovic Lacoste (aka Ludo6431) -- http://ludolacoste.com
#
# thanks to :
# Th0mas @ http://gravitronic.blogspot.com/2011/12/decoding-korg-monotribe-firmware.html
# nitro2k01 @ http://blog.gg8.se/wordpress/2011/12/04/korg-monotribe-firmware-20-analysis/
# decoder.py <input ascii bits file> <output file prefix>
import sys
from struct import pack
# input bits file (list of '0' and '1' in ascii (for example, produced by reader.py))
f = open(sys.argv[1], "r")
bits=iter(f.read())
f.close()
def readbyte(bits):
byte=''
for i in range(0,8):
byte=bits.next()+byte
return pack('B', int(byte, 2))
def waitsync(bits):
i=0
while bits.next()!='0':
i=i+1
# print 'wait: '+str(i)
def readpaquet(bits):
paquet=''
chk=0
# read paquet header
if readbyte(bits)!='\xA9':
print 'problem, bad packet start'
# read paquet data
for i in range(0,256):
by=readbyte(bits)
paquet+=by
chk+=ord(by)
# read paquet footer
paquet_type = readbyte(bits)
paquet_type += readbyte(bits)
paquet_type += readbyte(bits)
if paquet_type!='\x55\x55\x55' and paquet_type!='\xff\xff\xff':
print 'problem, bad paquet identifier'
# read paquet checksum
chk=chk%256
if paquet_type[0]!='\xff' and chk!=ord(readbyte(bits)):
print 'problem, bad checksum'
return (paquet, paquet_type[0])
f=open(sys.argv[2]+'_header.bin', "wb") # 256B
waitsync(bits)
f.write(readpaquet(bits)[0])
f.close()
f=open(sys.argv[2]+'_fw.bin', "wb") # 32kiB
for i in range(0,128):
waitsync(bits)
f.write(readpaquet(bits)[0])
f.close()
f=open(sys.argv[2]+'_footer.bin', "wb") # 256B
waitsync(bits)
f.write(readpaquet(bits)[0])
f.close()
# -*- coding: utf-8 -*-
# KORG monotribe wave firmware bit extractor by:
# Ludovic Lacoste (aka Ludo6431) -- http://ludolacoste.com
#
# thanks to :
# Th0mas @ http://gravitronic.blogspot.com/2011/12/decoding-korg-monotribe-firmware.html
# nitro2k01 @ http://blog.gg8.se/wordpress/2011/12/04/korg-monotribe-firmware-20-analysis/
#
# f1: ~4400Hz (227µs)
# f0: ~2200Hz (450µs)
# reader.py <input wav file> <output ascii bits file>
import sys, wave
from struct import unpack
# input .wav file
fd=wave.open(sys.argv[1], 'rb')
print 'nchannels:'+str(fd.getnchannels())
print 'sampwidth:'+str(fd.getsampwidth())
print 'framerate:'+str(fd.getframerate())
# thresholds of the software schmidt trigger
low=-3*32768/4
high=3*32767/4
# output ascii file (list of '0' and '1' in ascii)
f = open(sys.argv[2], "w")
st=0
pst=0
cmpt=0
fr=fd.readframes(1) # read one stereo frame (4 bytes)
while fr!='':
v=unpack('h', fr[0:2])[0] # get value of the first channel of the frame
# get current state (schmidt trigger)
if v>high:
st=1 # high
elif v<low:
st=-1 # low
if st>pst: # raising edge
if 5<cmpt and cmpt<15: # high frequency
f.write('1')
elif 15<cmpt and cmpt<25: # low frequency
f.write('0')
else:
print 'Unknown cmpt: '+str(cmpt)
cmpt=0
else:
cmpt=cmpt+1
pst=st # store previous state
fr=fd.readframes(1) # read one stereo frame (4 bytes)
f.close()
fd.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment