def decode(self, bits): bits = np.array(list(bits), dtype=int) packets = [] flag = list(np.array(list(preamble), dtype=int))[-9:] cur_b = [] num_packets = '0' for n in range(0, bits.shape[0] - 7): if list(bits[n:n+len(flag)-1]) == flag[1:]: if len(cur_b): # end packet; do CRC and add to packets cur = "".join([str(c) for c in cur_b[len(flag)-2:-1]]) cur = util.NRZI2NRZ(cur) cur = util.bit_unstuff(cur) cur = "".join(['1' if b else '0' for b in cur]) if len(cur) < self.packet + 48: cur_b = [] continue cur += '0' * (self.packet + 48 + self.ecc_p * 16 - len(cur)) try: if self.ecc_p: cur = util.ASCIIToBin(str(self.codec_p.decode(util.binToASCII(cur)))) except: cur_b = [] continue crc = cur[0:32] idx = cur[32:40] tot = cur[40:48] payload = cur[48:] if (zlib.crc32(util.binToASCII(idx + tot + payload)) % 2**32) == int("".join(crc), 2): packets += [(int(idx, 2), payload)] num_packets = tot cur_b = [] else: cur_b += [bits[n]] return packets, int(num_packets, 2)
def receive(self, in_port, t = 75): p = pyaudio.PyAudio() Qin = Queue.Queue() cQin = Queue.Queue() t_rec = threading.Thread(target = util.record_audio, args = (Qin, cQin, p, 48000, in_port)) t_rec.start() print "STARTED RECORDING..." sys.stdout.flush() time.sleep(t) cQin.put('EOT') p.terminate() print "END RECORDING..." data = np.array([]) while not Qin.empty(): data = np.concatenate((data, Qin.get())) np.save("RECEIVED_LAST.npy", data) print "START DECODE..." rcv_bits = self.modem.demodulate_bits(data, pll_a = self.pll_a).astype(int) print "received bits:", len(rcv_bits) rcv_packets, n_p = self.packer.decode(rcv_bits) print "received packets: ", len(rcv_packets), "\t total packets: ", n_p payload = self.packer.decode_from_packets(rcv_packets, n_p) decomp = zlib.decompress(util.binToASCII(payload[2])) return util.ASCIIToBin(decomp)
def receive_saved(self, data): print "START DECODE..." rcv_bits = self.modem.demodulate_bits(data, pll_a = self.pll_a).astype(int) print "received bits:", len(rcv_bits) rcv_packets, n_p = self.packer.decode(rcv_bits) print "received packets: ", len(rcv_packets), "\t total packets: ", n_p payload = self.packer.decode_from_packets(rcv_packets, n_p) decomp = zlib.decompress(util.binToASCII(payload[2])) return util.ASCIIToBin(decomp)
def encode(self, bits, typ = 0): bits = np.array(list(bits), dtype=int) NUM_PACKETS = str(bin(int(math.ceil((2 + 24 + bits.shape[0]) / (0. + self.packet))) + 2 * self.ecc))[2:].zfill(8) PAYLOAD_TYPE = str(bin(typ))[2:].zfill(2) NUM_BITS = str(bin(bits.shape[0]))[2:].zfill(24) bits = np.concatenate((np.array(list(PAYLOAD_TYPE), dtype=int), np.array(list(NUM_BITS), dtype=int), bits)) bits = np.array(list(bits), dtype=int) z_pad = (self.packet - (bits.shape[0] % self.packet)) % self.packet print "NUM BITS: ", bits.shape[0], "\t ZPAD: ", z_pad bits = np.concatenate((bits, np.zeros(z_pad))).astype(int) packets = np.reshape(bits, (-1, self.packet)) packets_ascii = [list(util.binToASCII("".join(packet))) for packet in packets.astype(str)] packets_ecc = [self.codec.encode("".join(packet)) for packet in zip(*packets_ascii)] encoded_packets = [] for packet_num in range(int(NUM_PACKETS, 2)): packet_payload = "".join([chr(packets_ecc[i][packet_num]) for i in range(self.packet / 8)]) packet_nocrc = util.binToASCII(str(bin(packet_num))[2:].zfill(8)) + util.binToASCII(NUM_PACKETS) + packet_payload packet_withcrc = util.binToASCII(str(bin(zlib.crc32(packet_nocrc) % 2**32))[2:].zfill(32)) + packet_nocrc packet_ecc = str(self.codec_p.encode(packet_withcrc)) encoded_packets += [packet_ecc] return encoded_packets
def dry_run(self, bits, typ = 0): bits = np.array(list(bits), dtype=str) if bits.shape[0] % 8 != 0: raise Exception("Number of bits should be a multiple of 8") bits_compressed = util.ASCIIToBin(min([zlib.compress(util.binToASCII("".join(bits)), i) for i in range(1,10)], key = lambda s: len(s))) ENT_RATIO = len(bits_compressed) / float(len(bits)) bits_packets = self.packer.packets_to_bits(self.packer.encode(bits_compressed, typ)) PACKED_BYTES = len(bits_packets) / 8. print "\nEntropy compressed ratio: ", ENT_RATIO print "Final size (bytes): ", PACKED_BYTES print "Channel efficiency ratio: ", len(bits_compressed) / 8. / PACKED_BYTES self.audio_sig = self.modem.modulate(np.array(list(bits_packets), dtype=int)) print "Audio time is: ", len(self.audio_sig) / 48000. if len(self.audio_sig) < 75 * 48000: self.ready = True print "ready to go! call dt.transmit()"
def decode_from_packets(self, packets, numpackets): if len(packets) == 0 or len(packets) < numpackets - 2 * self.ecc: raise Exception("Too many packets dropped!") packets_order = ['0' * self.packet for _ in range(numpackets)] for idx, payload in packets: packets_order[idx] = payload packets_order = np.array(packets_order) packets_ascii = [list(util.binToASCII("".join(packet))) for packet in packets_order.astype(str)] packets_corrected = [self.codec.decode("".join(packet)) for packet in zip(*packets_ascii)] payload = '' for packet_num in range(numpackets - 2 * self.ecc): packet_payload = "".join([chr(packets_corrected[i][packet_num]) for i in range(self.packet / 8)]) payload += packet_payload payload_bits = util.ASCIIToBin(payload) payload_type = payload_bits[:2] payload_size = payload_bits[2:26] payload = payload_bits[26:26 + int(payload_size, 2)] return int(payload_type, 2), int(payload_size, 2), payload