run ecc in parallel on demodulation

This commit is contained in:
Roman Zeyde
2014-07-20 12:42:42 +03:00
parent 1b5c1e7541
commit a431b04d1c
3 changed files with 24 additions and 27 deletions

16
ecc.py
View File

@@ -4,8 +4,6 @@ from reedsolo import rs_encode_msg, rs_correct_msg
import logging
log = logging.getLogger(__name__)
import common
DEFAULT_NSYM = 10
BLOCK_SIZE = 255
@@ -17,7 +15,6 @@ def end_of_stream(size):
def encode(data, nsym=DEFAULT_NSYM):
chunk_size = BLOCK_SIZE - nsym - 1
enc = bytearray()
for i in range(0, len(data), chunk_size):
chunk = bytearray(data[i:i+chunk_size])
@@ -26,19 +23,20 @@ def encode(data, nsym=DEFAULT_NSYM):
padding = b'\x00' * (chunk_size - size)
chunk.extend(padding)
chunk = bytearray([size]) + chunk
enc.extend(rs_encode_msg(chunk, nsym))
block = bytearray([size]) + chunk
yield rs_encode_msg(block, nsym)
enc.extend(rs_encode_msg(end_of_stream(chunk_size), nsym))
return enc
yield rs_encode_msg(end_of_stream(chunk_size), nsym)
def decode(data, nsym=DEFAULT_NSYM):
def decode(blocks, nsym=DEFAULT_NSYM):
last_chunk = end_of_stream(BLOCK_SIZE - nsym - 1)
for _, block in common.iterate(data, BLOCK_SIZE):
for block in blocks:
assert len(block) == BLOCK_SIZE
chunk = bytearray(rs_correct_msg(block, nsym))
if chunk == last_chunk:
log.info('EOF encountered')
return # end of stream
size = chunk[0]

30
recv.py
View File

@@ -141,6 +141,7 @@ def demodulate(symbols, filters, freqs):
yield bits
decoded_bits = decoded_bits + len(bits)
# TODO: make this run even after EOF
duration = time.time() - start
audio_time = decoded_bits / sigproc.modem_bps
log.info('Demodulated %.3f kB @ %.3f seconds = %.1f%% realtime',
@@ -162,28 +163,24 @@ def receive(signal, freqs):
signal.sampler.freq -= err
filters = train_receiver(symbols, freqs)
return demodulate(symbols, filters, freqs)
data_bits = demodulate(symbols, filters, freqs)
return itertools.chain.from_iterable(data_bits)
def decode(bits_iterator):
import cStringIO
import bitarray
import ecc
result = cStringIO.StringIO()
while True:
bits = itertools.islice(bits_iterator, 8 * ecc.BLOCK_SIZE)
block = bitarray.bitarray(endian='little')
block.extend(bits)
if not block:
break
result.write(block)
data = bytearray(result.getvalue())
data = ecc.decode(data)
if data is None:
log.warning('No blocks decoded!')
def blocks():
while True:
bits = itertools.islice(bits_iterator, 8 * ecc.BLOCK_SIZE)
block = bitarray.bitarray(endian='little')
block.extend(bits)
if not block:
break
yield bytearray(block.tobytes())
data = ecc.decode(blocks())
return data
@@ -213,9 +210,8 @@ def main(fname):
if peak > SATURATION_THRESHOLD:
raise ValueError('Saturation detected: {:.3f}'.format(peak))
data_bits = receive(x / amp, frequencies)
bits = itertools.chain.from_iterable(data_bits)
size = 0
bits = receive(x / amp, frequencies)
for chunk in decode(bits):
sys.stdout.write(chunk)
size = size + len(chunk)

View File

@@ -60,7 +60,10 @@ def main(fname):
training_size / wave.bytes_per_second)
log.info('%d bits to be send', len(data)*8)
bits = list(to_bits(ecc.encode(data)))
buf = bytearray()
for block in ecc.encode(data):
buf.extend(block)
bits = list(to_bits(buf))
ecc_ratio = 1.0 - len(data)*8.0 / len(bits)
log.info('%d bits modulated (%.1f%% ECC)', len(bits), ecc_ratio * 100)
modulate(fd, bits)