soft-packet-finder.py
· 11 KiB · Python
Неформатований
#!/usr/bin/env python
# WARNING: Work-in-progress
import os, math
import collections
ifile = "2016_08_17_LRPT_09-06-31.s" #"sample.s"
ofile = "sample.s.out"#"sample.s.out"
skipi = 0 #4800
'''
Sync Words Phased
0 = 00011010 11001111 11111100 00011101 = 0x1ACFFC1D
1 = 10001111 01100101 01010110 10000100 = 0x8F655684
2 = 11100101 00110000 00000011 11100010 = 0xE53003E2
3 = 01110000 10011010 10101001 01111011 = 0x709AA97B
10001111 01100101 01010110 10000100
01110000 10011010 10101001 01111011
'''
'''
Sync Word in 1/2 k=7 FEC:
1111 1100 1010 0010 1011 0110 0011 1101 1011 0000 0000 1101 1001 0111 1001 0100 0xfca2b63db00d9794
0101 0110 1111 1011 1101 0011 1001 0100 1101 1010 1010 0100 1100 0001 1100 0010 0x56fbd394daa4c1c2
0000 0011 0101 1101 0100 1001 1100 0010 0100 1111 1111 0010 0110 1000 0110 1011 0x035d49c24ff2686b
1010 1001 0000 0100 0010 1100 0110 1011 0010 0101 0101 1011 0011 1110 0011 1101 0xa9042c6b255b3e3d
also for IQ reversal, we reverse each pair of bits. Since I'm lazy, this script does the bit reversal over binary string:
x = "1010 1001 0000 0100 0010 1100 0110 1011 0010 0101 0101 1011 0011 1110 0011 1101".replace(" ", "")
o = ""
for i in range(0, len(x), 2):
o += x[i+1]
o += x[i]
print o
print hex(int(o, 2))
So for bit reversal we have this sync words:
1111 1100 0101 0001 0111 1001 0011 1110 0111 0000 0000 1110 0110 1011 0110 1000 0xfc51793e700e6b68
1010 1001 1111 0111 1110 0011 0110 1000 1110 0101 0101 1000 1100 0010 1100 0001 0xa9f7e368e558c2c1
0000 0011 1010 1110 1000 0110 1100 0001 1000 1111 1111 0001 1001 0100 1001 0111 0x03ae86c18ff19497
0101 0110 0000 1000 0001 1100 1001 0111 0001 1010 1010 0111 0011 1101 0011 1110 0x56081c971aa73d3e
'''
'''
Frame Size = 1024 bytes (1020 + 4)
Rate = 1/2
Frame Symbol Size = 1024 * 8 * 2
Input = IQ Byte. Symbol = 2 Byte
Frame Input Size = 1024 * 8 * 2 * 2
'''
frameSymbolSize = 1024 * 8
frameInputSize = frameSymbolSize * 2
frameBitSize = frameSymbolSize * 2
syncWordSize = 32
syncWordDoubleSize = 64
UW0 = 0xfca2b63db00d9794
UW1 = 0x56fbd394daa4c1c2
UW2 = 0x035d49c24ff2686b
UW3 = 0xa9042c6b255b3e3d
REVUW0 = 0xfc51793e700e6b68
REVUW1 = 0xa9f7e368e558c2c1
REVUW2 = 0x03ae86c18ff19497
REVUW3 = 0x56081c971aa73d3e
'''
Tricky, we need a 2-bit group reversal for correcting IQ parameters.
This could be done in several ways, but I will do as a Lookup Table.
Basically for every index I in this element, there will be I with
2-bit group reversed output. If you're curious how I got this values,
I was lazy also.
def bit2rev(n):
x = format(n, '#0{}b'.format(10))[2:] # Binary string of n
o = "" # Reversed 2bit binary string
for i in range(0, len(x), 2):
o += x[i+1]
o += x[i]
return int(o, 2) # Return the integer
BIT2REV = []
for i in range(256):
BIT2REV.append(bit2rev(i))
So just for example: Lets supose we get a byte with value 123 that is IQ reversed.
To un-reverse we go to the position 123 of the BIT2REV table that is: 183.
So if we get the binary strings:
123 = 01 11 10 11
186 = 10 11 01 11
So we inverted all 2 bit groups.
'''
BIT2REV = [
0, 2, 1, 3, 8, 10, 9, 11, 4, 6, 5, 7, 12, 14, 13, 15,
32, 34, 33, 35, 40, 42, 41, 43, 36, 38, 37, 39, 44, 46, 45, 47,
16, 18, 17, 19, 24, 26, 25, 27, 20, 22, 21, 23, 28, 30, 29, 31,
48, 50, 49, 51, 56, 58, 57, 59, 52, 54, 53, 55, 60, 62, 61, 63,
128, 130, 129, 131, 136, 138, 137, 139, 132, 134, 133, 135, 140, 142, 141, 143,
160, 162, 161, 163, 168, 170, 169, 171, 164, 166, 165, 167, 172, 174, 173, 175,
144, 146, 145, 147, 152, 154, 153, 155, 148, 150, 149, 151, 156, 158, 157, 159,
176, 178, 177, 179, 184, 186, 185, 187, 180, 182, 181, 183, 188, 190, 189, 191,
64, 66, 65, 67, 72, 74, 73, 75, 68, 70, 69, 71, 76, 78, 77, 79,
96, 98, 97, 99, 104, 106, 105, 107, 100, 102, 101, 103, 108, 110, 109, 111,
80, 82, 81, 83, 88, 90, 89, 91, 84, 86, 85, 87, 92, 94, 93, 95,
112, 114, 113, 115, 120, 122, 121, 123, 116, 118, 117, 119, 124, 126, 125, 127,
192, 194, 193, 195, 200, 202, 201, 203, 196, 198, 197, 199, 204, 206, 205, 207,
224, 226, 225, 227, 232, 234, 233, 235, 228, 230, 229, 231, 236, 238, 237, 239,
208, 210, 209, 211, 216, 218, 217, 219, 212, 214, 213, 215, 220, 222, 221, 223,
240, 242, 241, 243, 248, 250, 249, 251, 244, 246, 245, 247, 252, 254, 253, 255
]
'''
So for phase ambiguities we can also use a LUT. So we have four cases, but we
only need to account for one: 90 degrees. Because:
0 deg is what we want
90 deg we will do a LUT for getting 0 deg
180 deg is the negate of 0 deg (so we can just xor by 0xFF)
270 deg is the negate of 90 deg (so we can xor by 0xFF and then use 90 deg LUT)
So a 90 deg rotation in the constelation maps as:
0 deg => 90 deg
00 => 10
01 => 00
11 => 01
10 => 11
So as usual:
def phaseshift(n):
x = format(n, '#0{}b'.format(10))[2:] # Binary string of n
o = "" # 90 deg phased binary string
for i in range(0, len(x), 2):
o += "1" if x[i+1] == "0" else "0"
o += "0" if x[i] == "0" else "1"
return int(o, 2) # Return the integer
PHASED = []
for i in range(256):
PHASED.append(phaseshift(i))
'''
PHASED = [
170, 168, 171, 169, 162, 160, 163, 161, 174, 172, 175, 173, 166, 164, 167, 165,
138, 136, 139, 137, 130, 128, 131, 129, 142, 140, 143, 141, 134, 132, 135, 133,
186, 184, 187, 185, 178, 176, 179, 177, 190, 188, 191, 189, 182, 180, 183, 181,
154, 152, 155, 153, 146, 144, 147, 145, 158, 156, 159, 157, 150, 148, 151, 149,
42, 40, 43, 41, 34, 32, 35, 33, 46, 44, 47, 45, 38, 36, 39, 37,
10, 8, 11, 9, 2, 0, 3, 1, 14, 12, 15, 13, 6, 4, 7, 5,
58, 56, 59, 57, 50, 48, 51, 49, 62, 60, 63, 61, 54, 52, 55, 53,
26, 24, 27, 25, 18, 16, 19, 17, 30, 28, 31, 29, 22, 20, 23, 21,
234, 232, 235, 233, 226, 224, 227, 225, 238, 236, 239, 237, 230, 228, 231, 229,
202, 200, 203, 201, 194, 192, 195, 193, 206, 204, 207, 205, 198, 196, 199, 197,
250, 248, 251, 249, 242, 240, 243, 241, 254, 252, 255, 253, 246, 244, 247, 245,
218, 216, 219, 217, 210, 208, 211, 209, 222, 220, 223, 221, 214, 212, 215, 213,
106, 104, 107, 105, 98, 96, 99, 97, 110, 108, 111, 109, 102, 100, 103, 101,
74, 72, 75, 73, 66, 64, 67, 65, 78, 76, 79, 77, 70, 68, 71, 69,
122, 120, 123, 121, 114, 112, 115, 113, 126, 124, 127, 125, 118, 116, 119, 117,
90, 88, 91, 89, 82, 80, 83, 81, 94, 92, 95, 93, 86, 84, 87, 85
]
def binary(num, length=8):
return format(num, '#0{}b'.format(length + 2))
def binStringToIntSoftArr(b):
if b[1] == 'b':
b = b[2:]
a = []
for i in b:
a.append(int(i) * 0xFF)
return a
def checkCorrelationInBuffer():
uw0mc = 0 # Highest Correlation Factor for UW0
uw0p = 0 # Highest Correlation Position for UW0
uw1mc = 0
uw1p = 0
uw2mc = 0
uw2p = 0
uw3mc = 0
uw3p = 0
ruw0mc = 0 # Highest Correlation Factor for REVUW0
ruw0p = 0 # Highest Correlation Position for REVUW0
ruw1mc = 0
ruw1p = 0
ruw2mc = 0
ruw2p = 0
ruw3mc = 0
ruw3p = 0
for i in range(0, frameBitSize - syncWordDoubleSize):
uw0c = 0
uw1c = 0
uw2c = 0
uw3c = 0
ruw0c = 0
ruw1c = 0
ruw2c = 0
ruw3c = 0
# To get the highest correlation, we xor with the word.
for k in range(0, syncWordDoubleSize):
uw0c += sbits[i+k] ^ UW0[k]
uw1c += sbits[i+k] ^ UW1[k]
uw2c += sbits[i+k] ^ UW2[k]
uw3c += sbits[i+k] ^ UW3[k]
ruw0c += sbits[i+k] ^ REVUW0[k]
ruw1c += sbits[i+k] ^ REVUW1[k]
ruw2c += sbits[i+k] ^ REVUW2[k]
ruw3c += sbits[i+k] ^ REVUW3[k]
uw0p = i if uw0c > uw0mc else uw0p
uw1p = i if uw1c > uw1mc else uw1p
uw2p = i if uw2c > uw2mc else uw2p
uw3p = i if uw3c > uw3mc else uw3p
ruw0p = i if ruw0c > ruw0mc else ruw0p
ruw1p = i if ruw1c > ruw1mc else ruw1p
ruw2p = i if ruw2c > ruw2mc else ruw2p
ruw3p = i if ruw3c > ruw3mc else ruw3p
uw0mc = uw0c if uw0c > uw0mc else uw0mc
uw1mc = uw1c if uw1c > uw1mc else uw1mc
uw2mc = uw2c if uw2c > uw2mc else uw2mc
uw3mc = uw3c if uw3c > uw3mc else uw3mc
ruw0mc = ruw0c if ruw0c > ruw0mc else ruw0mc
ruw1mc = ruw1c if ruw1c > ruw1mc else ruw1mc
ruw2mc = ruw2c if ruw2c > ruw2mc else ruw2mc
ruw3mc = ruw3c if ruw3c > ruw3mc else ruw3mc
return uw0p, uw0mc, uw1p, uw1mc, uw2p, uw2mc, uw3p, uw3mc, ruw0p, ruw0mc, ruw1p, ruw1mc, ruw2p, ruw2mc, ruw3p, ruw3mc
UW0 = binStringToIntSoftArr(binary(UW0, syncWordDoubleSize))
UW1 = binStringToIntSoftArr(binary(UW1, syncWordDoubleSize))
UW2 = binStringToIntSoftArr(binary(UW2, syncWordDoubleSize))
UW3 = binStringToIntSoftArr(binary(UW3, syncWordDoubleSize))
REVUW0 = binStringToIntSoftArr(binary(REVUW0, syncWordDoubleSize))
REVUW1 = binStringToIntSoftArr(binary(REVUW1, syncWordDoubleSize))
REVUW2 = binStringToIntSoftArr(binary(REVUW2, syncWordDoubleSize))
REVUW3 = binStringToIntSoftArr(binary(REVUW3, syncWordDoubleSize))
f = open(ifile, "r")
fsize = os.path.getsize(ifile)
#o = open(ofile, "w")
#ob = open(ofile + "bit", "w")
sbits = collections.deque(maxlen=frameBitSize)
count = 0
fcount = 0
f.seek(skipi)
count += skipi
print "Frame Input Size: %s" %frameInputSize
while count < fsize:
'''
Read the data from input to sbits
'''
data = f.read(frameInputSize)
for i in range(0, frameInputSize):
sbits.append(ord(data[i]))
'''
Search for the sync word using correlation
'''
uw0p, uw0mc, uw1p, uw1mc, uw2p, uw2mc, uw3p, uw3mc, ruw0p, ruw0mc, ruw1p, ruw1mc, ruw2p, ruw2mc, ruw3p, ruw3mc = checkCorrelationInBuffer()
mp = max(uw0mc, uw1mc, uw2mc, uw3mc, ruw0mc, ruw1mc, ruw2mc, ruw3mc)
print "Frame: #%s" %fcount
print "Max Correlation: %s" % (mp / 256)
if mp == uw0mc:
print "Max Correlation with 0 degrees Word at %s" % uw0p
n = 0
p = uw0p
elif mp == uw1mc:
print "Max Correlation with 90 degrees Word at %s" % uw1p
n = 1
p = uw1p
elif mp == uw2mc:
print "Max Correlation with 180 degrees Word at %s" % uw2p
n = 2
p = uw2p
elif mp == uw3mc:
print "Max Correlation with 270 degrees Word at %s" % uw3p
n = 3
p = uw3p
elif mp == ruw0mc:
print "Max Correlation with 0 degrees Word at %s Reverse IQ" % ruw0p
n = 0
p = ruw0p
elif mp == ruw1mc:
print "Max Correlation with 90 degrees Word at %s Reverse IQ" % ruw1p
n = 1
p = ruw1p
elif mp == ruw2mc:
print "Max Correlation with 180 degrees Word at %s Reverse IQ" % ruw2p
n = 2
p = ruw2p
elif mp == ruw3mc:
print "Max Correlation with 270 degrees Word at %s Reverse IQ" % ruw3p
n = 3
p = ruw3p
if mp / 256 < 40:
print "Frame Lock Error. Correlation less than 47 bits"
count += frameInputSize
else:
'''
Read p bits for syncing the Circle Buffer
Each pair of bits come from 2 bytes of the input
So we will read 1 byte per bit
'''
#p -= 12
t = p if p % 2 == 0 else p + 1
data = f.read(t)
for i in range(0, t):
sbits.append(ord(data[i]))
'''
Now we should have everything in sync
'''
#frame = processFrame(list(sbits), n)
#o.write(frame)
#frameb = processFrameBitMap(list(sbits), n)
#ob.write(frameb)
fcount += 1
count += frameInputSize + t
'''
Clean everything
'''
f.close()
o.close()
ob.close()
| 1 | #!/usr/bin/env python |
| 2 | |
| 3 | # WARNING: Work-in-progress |
| 4 | |
| 5 | import os, math |
| 6 | import collections |
| 7 | |
| 8 | ifile = "2016_08_17_LRPT_09-06-31.s" #"sample.s" |
| 9 | ofile = "sample.s.out"#"sample.s.out" |
| 10 | skipi = 0 #4800 |
| 11 | |
| 12 | ''' |
| 13 | Sync Words Phased |
| 14 | |
| 15 | 0 = 00011010 11001111 11111100 00011101 = 0x1ACFFC1D |
| 16 | 1 = 10001111 01100101 01010110 10000100 = 0x8F655684 |
| 17 | 2 = 11100101 00110000 00000011 11100010 = 0xE53003E2 |
| 18 | 3 = 01110000 10011010 10101001 01111011 = 0x709AA97B |
| 19 | |
| 20 | |
| 21 | |
| 22 | 10001111 01100101 01010110 10000100 |
| 23 | 01110000 10011010 10101001 01111011 |
| 24 | |
| 25 | ''' |
| 26 | |
| 27 | ''' |
| 28 | Sync Word in 1/2 k=7 FEC: |
| 29 | |
| 30 | 1111 1100 1010 0010 1011 0110 0011 1101 1011 0000 0000 1101 1001 0111 1001 0100 0xfca2b63db00d9794 |
| 31 | 0101 0110 1111 1011 1101 0011 1001 0100 1101 1010 1010 0100 1100 0001 1100 0010 0x56fbd394daa4c1c2 |
| 32 | 0000 0011 0101 1101 0100 1001 1100 0010 0100 1111 1111 0010 0110 1000 0110 1011 0x035d49c24ff2686b |
| 33 | 1010 1001 0000 0100 0010 1100 0110 1011 0010 0101 0101 1011 0011 1110 0011 1101 0xa9042c6b255b3e3d |
| 34 | |
| 35 | also for IQ reversal, we reverse each pair of bits. Since I'm lazy, this script does the bit reversal over binary string: |
| 36 | |
| 37 | x = "1010 1001 0000 0100 0010 1100 0110 1011 0010 0101 0101 1011 0011 1110 0011 1101".replace(" ", "") |
| 38 | o = "" |
| 39 | for i in range(0, len(x), 2): |
| 40 | o += x[i+1] |
| 41 | o += x[i] |
| 42 | |
| 43 | print o |
| 44 | print hex(int(o, 2)) |
| 45 | |
| 46 | So for bit reversal we have this sync words: |
| 47 | |
| 48 | 1111 1100 0101 0001 0111 1001 0011 1110 0111 0000 0000 1110 0110 1011 0110 1000 0xfc51793e700e6b68 |
| 49 | 1010 1001 1111 0111 1110 0011 0110 1000 1110 0101 0101 1000 1100 0010 1100 0001 0xa9f7e368e558c2c1 |
| 50 | 0000 0011 1010 1110 1000 0110 1100 0001 1000 1111 1111 0001 1001 0100 1001 0111 0x03ae86c18ff19497 |
| 51 | 0101 0110 0000 1000 0001 1100 1001 0111 0001 1010 1010 0111 0011 1101 0011 1110 0x56081c971aa73d3e |
| 52 | |
| 53 | ''' |
| 54 | |
| 55 | ''' |
| 56 | Frame Size = 1024 bytes (1020 + 4) |
| 57 | Rate = 1/2 |
| 58 | Frame Symbol Size = 1024 * 8 * 2 |
| 59 | |
| 60 | Input = IQ Byte. Symbol = 2 Byte |
| 61 | Frame Input Size = 1024 * 8 * 2 * 2 |
| 62 | ''' |
| 63 | |
| 64 | frameSymbolSize = 1024 * 8 |
| 65 | frameInputSize = frameSymbolSize * 2 |
| 66 | frameBitSize = frameSymbolSize * 2 |
| 67 | syncWordSize = 32 |
| 68 | syncWordDoubleSize = 64 |
| 69 | |
| 70 | UW0 = 0xfca2b63db00d9794 |
| 71 | UW1 = 0x56fbd394daa4c1c2 |
| 72 | UW2 = 0x035d49c24ff2686b |
| 73 | UW3 = 0xa9042c6b255b3e3d |
| 74 | |
| 75 | REVUW0 = 0xfc51793e700e6b68 |
| 76 | REVUW1 = 0xa9f7e368e558c2c1 |
| 77 | REVUW2 = 0x03ae86c18ff19497 |
| 78 | REVUW3 = 0x56081c971aa73d3e |
| 79 | |
| 80 | ''' |
| 81 | Tricky, we need a 2-bit group reversal for correcting IQ parameters. |
| 82 | This could be done in several ways, but I will do as a Lookup Table. |
| 83 | Basically for every index I in this element, there will be I with |
| 84 | 2-bit group reversed output. If you're curious how I got this values, |
| 85 | I was lazy also. |
| 86 | |
| 87 | def bit2rev(n): |
| 88 | x = format(n, '#0{}b'.format(10))[2:] # Binary string of n |
| 89 | o = "" # Reversed 2bit binary string |
| 90 | for i in range(0, len(x), 2): |
| 91 | o += x[i+1] |
| 92 | o += x[i] |
| 93 | return int(o, 2) # Return the integer |
| 94 | |
| 95 | BIT2REV = [] |
| 96 | for i in range(256): |
| 97 | BIT2REV.append(bit2rev(i)) |
| 98 | |
| 99 | |
| 100 | So just for example: Lets supose we get a byte with value 123 that is IQ reversed. |
| 101 | To un-reverse we go to the position 123 of the BIT2REV table that is: 183. |
| 102 | |
| 103 | So if we get the binary strings: |
| 104 | |
| 105 | 123 = 01 11 10 11 |
| 106 | 186 = 10 11 01 11 |
| 107 | |
| 108 | So we inverted all 2 bit groups. |
| 109 | ''' |
| 110 | |
| 111 | BIT2REV = [ |
| 112 | 0, 2, 1, 3, 8, 10, 9, 11, 4, 6, 5, 7, 12, 14, 13, 15, |
| 113 | 32, 34, 33, 35, 40, 42, 41, 43, 36, 38, 37, 39, 44, 46, 45, 47, |
| 114 | 16, 18, 17, 19, 24, 26, 25, 27, 20, 22, 21, 23, 28, 30, 29, 31, |
| 115 | 48, 50, 49, 51, 56, 58, 57, 59, 52, 54, 53, 55, 60, 62, 61, 63, |
| 116 | 128, 130, 129, 131, 136, 138, 137, 139, 132, 134, 133, 135, 140, 142, 141, 143, |
| 117 | 160, 162, 161, 163, 168, 170, 169, 171, 164, 166, 165, 167, 172, 174, 173, 175, |
| 118 | 144, 146, 145, 147, 152, 154, 153, 155, 148, 150, 149, 151, 156, 158, 157, 159, |
| 119 | 176, 178, 177, 179, 184, 186, 185, 187, 180, 182, 181, 183, 188, 190, 189, 191, |
| 120 | 64, 66, 65, 67, 72, 74, 73, 75, 68, 70, 69, 71, 76, 78, 77, 79, |
| 121 | 96, 98, 97, 99, 104, 106, 105, 107, 100, 102, 101, 103, 108, 110, 109, 111, |
| 122 | 80, 82, 81, 83, 88, 90, 89, 91, 84, 86, 85, 87, 92, 94, 93, 95, |
| 123 | 112, 114, 113, 115, 120, 122, 121, 123, 116, 118, 117, 119, 124, 126, 125, 127, |
| 124 | 192, 194, 193, 195, 200, 202, 201, 203, 196, 198, 197, 199, 204, 206, 205, 207, |
| 125 | 224, 226, 225, 227, 232, 234, 233, 235, 228, 230, 229, 231, 236, 238, 237, 239, |
| 126 | 208, 210, 209, 211, 216, 218, 217, 219, 212, 214, 213, 215, 220, 222, 221, 223, |
| 127 | 240, 242, 241, 243, 248, 250, 249, 251, 244, 246, 245, 247, 252, 254, 253, 255 |
| 128 | ] |
| 129 | |
| 130 | ''' |
| 131 | So for phase ambiguities we can also use a LUT. So we have four cases, but we |
| 132 | only need to account for one: 90 degrees. Because: |
| 133 | 0 deg is what we want |
| 134 | 90 deg we will do a LUT for getting 0 deg |
| 135 | 180 deg is the negate of 0 deg (so we can just xor by 0xFF) |
| 136 | 270 deg is the negate of 90 deg (so we can xor by 0xFF and then use 90 deg LUT) |
| 137 | |
| 138 | So a 90 deg rotation in the constelation maps as: |
| 139 | 0 deg => 90 deg |
| 140 | 00 => 10 |
| 141 | 01 => 00 |
| 142 | 11 => 01 |
| 143 | 10 => 11 |
| 144 | |
| 145 | So as usual: |
| 146 | |
| 147 | def phaseshift(n): |
| 148 | x = format(n, '#0{}b'.format(10))[2:] # Binary string of n |
| 149 | o = "" # 90 deg phased binary string |
| 150 | for i in range(0, len(x), 2): |
| 151 | o += "1" if x[i+1] == "0" else "0" |
| 152 | o += "0" if x[i] == "0" else "1" |
| 153 | return int(o, 2) # Return the integer |
| 154 | |
| 155 | PHASED = [] |
| 156 | for i in range(256): |
| 157 | PHASED.append(phaseshift(i)) |
| 158 | |
| 159 | ''' |
| 160 | |
| 161 | PHASED = [ |
| 162 | 170, 168, 171, 169, 162, 160, 163, 161, 174, 172, 175, 173, 166, 164, 167, 165, |
| 163 | 138, 136, 139, 137, 130, 128, 131, 129, 142, 140, 143, 141, 134, 132, 135, 133, |
| 164 | 186, 184, 187, 185, 178, 176, 179, 177, 190, 188, 191, 189, 182, 180, 183, 181, |
| 165 | 154, 152, 155, 153, 146, 144, 147, 145, 158, 156, 159, 157, 150, 148, 151, 149, |
| 166 | 42, 40, 43, 41, 34, 32, 35, 33, 46, 44, 47, 45, 38, 36, 39, 37, |
| 167 | 10, 8, 11, 9, 2, 0, 3, 1, 14, 12, 15, 13, 6, 4, 7, 5, |
| 168 | 58, 56, 59, 57, 50, 48, 51, 49, 62, 60, 63, 61, 54, 52, 55, 53, |
| 169 | 26, 24, 27, 25, 18, 16, 19, 17, 30, 28, 31, 29, 22, 20, 23, 21, |
| 170 | 234, 232, 235, 233, 226, 224, 227, 225, 238, 236, 239, 237, 230, 228, 231, 229, |
| 171 | 202, 200, 203, 201, 194, 192, 195, 193, 206, 204, 207, 205, 198, 196, 199, 197, |
| 172 | 250, 248, 251, 249, 242, 240, 243, 241, 254, 252, 255, 253, 246, 244, 247, 245, |
| 173 | 218, 216, 219, 217, 210, 208, 211, 209, 222, 220, 223, 221, 214, 212, 215, 213, |
| 174 | 106, 104, 107, 105, 98, 96, 99, 97, 110, 108, 111, 109, 102, 100, 103, 101, |
| 175 | 74, 72, 75, 73, 66, 64, 67, 65, 78, 76, 79, 77, 70, 68, 71, 69, |
| 176 | 122, 120, 123, 121, 114, 112, 115, 113, 126, 124, 127, 125, 118, 116, 119, 117, |
| 177 | 90, 88, 91, 89, 82, 80, 83, 81, 94, 92, 95, 93, 86, 84, 87, 85 |
| 178 | ] |
| 179 | |
| 180 | |
| 181 | def binary(num, length=8): |
| 182 | return format(num, '#0{}b'.format(length + 2)) |
| 183 | |
| 184 | def binStringToIntSoftArr(b): |
| 185 | if b[1] == 'b': |
| 186 | b = b[2:] |
| 187 | a = [] |
| 188 | for i in b: |
| 189 | a.append(int(i) * 0xFF) |
| 190 | return a |
| 191 | |
| 192 | def checkCorrelationInBuffer(): |
| 193 | uw0mc = 0 # Highest Correlation Factor for UW0 |
| 194 | uw0p = 0 # Highest Correlation Position for UW0 |
| 195 | uw1mc = 0 |
| 196 | uw1p = 0 |
| 197 | uw2mc = 0 |
| 198 | uw2p = 0 |
| 199 | uw3mc = 0 |
| 200 | uw3p = 0 |
| 201 | ruw0mc = 0 # Highest Correlation Factor for REVUW0 |
| 202 | ruw0p = 0 # Highest Correlation Position for REVUW0 |
| 203 | ruw1mc = 0 |
| 204 | ruw1p = 0 |
| 205 | ruw2mc = 0 |
| 206 | ruw2p = 0 |
| 207 | ruw3mc = 0 |
| 208 | ruw3p = 0 |
| 209 | |
| 210 | for i in range(0, frameBitSize - syncWordDoubleSize): |
| 211 | uw0c = 0 |
| 212 | uw1c = 0 |
| 213 | uw2c = 0 |
| 214 | uw3c = 0 |
| 215 | ruw0c = 0 |
| 216 | ruw1c = 0 |
| 217 | ruw2c = 0 |
| 218 | ruw3c = 0 |
| 219 | # To get the highest correlation, we xor with the word. |
| 220 | for k in range(0, syncWordDoubleSize): |
| 221 | uw0c += sbits[i+k] ^ UW0[k] |
| 222 | uw1c += sbits[i+k] ^ UW1[k] |
| 223 | uw2c += sbits[i+k] ^ UW2[k] |
| 224 | uw3c += sbits[i+k] ^ UW3[k] |
| 225 | ruw0c += sbits[i+k] ^ REVUW0[k] |
| 226 | ruw1c += sbits[i+k] ^ REVUW1[k] |
| 227 | ruw2c += sbits[i+k] ^ REVUW2[k] |
| 228 | ruw3c += sbits[i+k] ^ REVUW3[k] |
| 229 | |
| 230 | uw0p = i if uw0c > uw0mc else uw0p |
| 231 | uw1p = i if uw1c > uw1mc else uw1p |
| 232 | uw2p = i if uw2c > uw2mc else uw2p |
| 233 | uw3p = i if uw3c > uw3mc else uw3p |
| 234 | ruw0p = i if ruw0c > ruw0mc else ruw0p |
| 235 | ruw1p = i if ruw1c > ruw1mc else ruw1p |
| 236 | ruw2p = i if ruw2c > ruw2mc else ruw2p |
| 237 | ruw3p = i if ruw3c > ruw3mc else ruw3p |
| 238 | |
| 239 | uw0mc = uw0c if uw0c > uw0mc else uw0mc |
| 240 | uw1mc = uw1c if uw1c > uw1mc else uw1mc |
| 241 | uw2mc = uw2c if uw2c > uw2mc else uw2mc |
| 242 | uw3mc = uw3c if uw3c > uw3mc else uw3mc |
| 243 | ruw0mc = ruw0c if ruw0c > ruw0mc else ruw0mc |
| 244 | ruw1mc = ruw1c if ruw1c > ruw1mc else ruw1mc |
| 245 | ruw2mc = ruw2c if ruw2c > ruw2mc else ruw2mc |
| 246 | ruw3mc = ruw3c if ruw3c > ruw3mc else ruw3mc |
| 247 | |
| 248 | return uw0p, uw0mc, uw1p, uw1mc, uw2p, uw2mc, uw3p, uw3mc, ruw0p, ruw0mc, ruw1p, ruw1mc, ruw2p, ruw2mc, ruw3p, ruw3mc |
| 249 | |
| 250 | |
| 251 | |
| 252 | UW0 = binStringToIntSoftArr(binary(UW0, syncWordDoubleSize)) |
| 253 | UW1 = binStringToIntSoftArr(binary(UW1, syncWordDoubleSize)) |
| 254 | UW2 = binStringToIntSoftArr(binary(UW2, syncWordDoubleSize)) |
| 255 | UW3 = binStringToIntSoftArr(binary(UW3, syncWordDoubleSize)) |
| 256 | REVUW0 = binStringToIntSoftArr(binary(REVUW0, syncWordDoubleSize)) |
| 257 | REVUW1 = binStringToIntSoftArr(binary(REVUW1, syncWordDoubleSize)) |
| 258 | REVUW2 = binStringToIntSoftArr(binary(REVUW2, syncWordDoubleSize)) |
| 259 | REVUW3 = binStringToIntSoftArr(binary(REVUW3, syncWordDoubleSize)) |
| 260 | |
| 261 | f = open(ifile, "r") |
| 262 | fsize = os.path.getsize(ifile) |
| 263 | #o = open(ofile, "w") |
| 264 | #ob = open(ofile + "bit", "w") |
| 265 | |
| 266 | sbits = collections.deque(maxlen=frameBitSize) |
| 267 | |
| 268 | count = 0 |
| 269 | fcount = 0 |
| 270 | |
| 271 | f.seek(skipi) |
| 272 | count += skipi |
| 273 | |
| 274 | print "Frame Input Size: %s" %frameInputSize |
| 275 | |
| 276 | while count < fsize: |
| 277 | ''' |
| 278 | Read the data from input to sbits |
| 279 | ''' |
| 280 | data = f.read(frameInputSize) |
| 281 | for i in range(0, frameInputSize): |
| 282 | sbits.append(ord(data[i])) |
| 283 | |
| 284 | ''' |
| 285 | Search for the sync word using correlation |
| 286 | ''' |
| 287 | |
| 288 | uw0p, uw0mc, uw1p, uw1mc, uw2p, uw2mc, uw3p, uw3mc, ruw0p, ruw0mc, ruw1p, ruw1mc, ruw2p, ruw2mc, ruw3p, ruw3mc = checkCorrelationInBuffer() |
| 289 | mp = max(uw0mc, uw1mc, uw2mc, uw3mc, ruw0mc, ruw1mc, ruw2mc, ruw3mc) |
| 290 | |
| 291 | print "Frame: #%s" %fcount |
| 292 | print "Max Correlation: %s" % (mp / 256) |
| 293 | if mp == uw0mc: |
| 294 | print "Max Correlation with 0 degrees Word at %s" % uw0p |
| 295 | n = 0 |
| 296 | p = uw0p |
| 297 | elif mp == uw1mc: |
| 298 | print "Max Correlation with 90 degrees Word at %s" % uw1p |
| 299 | n = 1 |
| 300 | p = uw1p |
| 301 | elif mp == uw2mc: |
| 302 | print "Max Correlation with 180 degrees Word at %s" % uw2p |
| 303 | n = 2 |
| 304 | p = uw2p |
| 305 | elif mp == uw3mc: |
| 306 | print "Max Correlation with 270 degrees Word at %s" % uw3p |
| 307 | n = 3 |
| 308 | p = uw3p |
| 309 | elif mp == ruw0mc: |
| 310 | print "Max Correlation with 0 degrees Word at %s Reverse IQ" % ruw0p |
| 311 | n = 0 |
| 312 | p = ruw0p |
| 313 | elif mp == ruw1mc: |
| 314 | print "Max Correlation with 90 degrees Word at %s Reverse IQ" % ruw1p |
| 315 | n = 1 |
| 316 | p = ruw1p |
| 317 | elif mp == ruw2mc: |
| 318 | print "Max Correlation with 180 degrees Word at %s Reverse IQ" % ruw2p |
| 319 | n = 2 |
| 320 | p = ruw2p |
| 321 | elif mp == ruw3mc: |
| 322 | print "Max Correlation with 270 degrees Word at %s Reverse IQ" % ruw3p |
| 323 | n = 3 |
| 324 | p = ruw3p |
| 325 | |
| 326 | if mp / 256 < 40: |
| 327 | print "Frame Lock Error. Correlation less than 47 bits" |
| 328 | count += frameInputSize |
| 329 | else: |
| 330 | ''' |
| 331 | Read p bits for syncing the Circle Buffer |
| 332 | Each pair of bits come from 2 bytes of the input |
| 333 | So we will read 1 byte per bit |
| 334 | ''' |
| 335 | #p -= 12 |
| 336 | t = p if p % 2 == 0 else p + 1 |
| 337 | data = f.read(t) |
| 338 | for i in range(0, t): |
| 339 | sbits.append(ord(data[i])) |
| 340 | |
| 341 | ''' |
| 342 | Now we should have everything in sync |
| 343 | ''' |
| 344 | #frame = processFrame(list(sbits), n) |
| 345 | #o.write(frame) |
| 346 | #frameb = processFrameBitMap(list(sbits), n) |
| 347 | #ob.write(frameb) |
| 348 | fcount += 1 |
| 349 | count += frameInputSize + t |
| 350 | |
| 351 | ''' |
| 352 | Clean everything |
| 353 | ''' |
| 354 | |
| 355 | f.close() |
| 356 | o.close() |
| 357 | ob.close() |