mirror of
https://github.com/romanz/amodem.git
synced 2026-04-21 05:36:42 +08:00
refactor recv.py
This commit is contained in:
2
loop.py
2
loop.py
@@ -21,7 +21,7 @@ class Filter(object):
|
|||||||
return y
|
return y
|
||||||
|
|
||||||
class FreqLoop(object):
|
class FreqLoop(object):
|
||||||
def __init__(self, x, freqs, prefix=None):
|
def __init__(self, x, freqs, prefix=0.0):
|
||||||
interp = sampling.Interpolator()
|
interp = sampling.Interpolator()
|
||||||
if prefix is None:
|
if prefix is None:
|
||||||
prefix = []
|
prefix = []
|
||||||
|
|||||||
30
recv.py
30
recv.py
@@ -51,27 +51,23 @@ def find_start(x, start):
|
|||||||
def take(symbols, i, n):
|
def take(symbols, i, n):
|
||||||
return np.array([s if i is None else s[i] for s in itertools.islice(symbols, n)])
|
return np.array([s if i is None else s[i] for s in itertools.islice(symbols, n)])
|
||||||
|
|
||||||
def receive(x, freqs):
|
def receive_prefix(symbols):
|
||||||
x = list(x)
|
|
||||||
lp = loop.FreqLoop(x, freqs, prefix=0.0)
|
|
||||||
|
|
||||||
symbols = iter(lp)
|
|
||||||
|
|
||||||
S = take(symbols, carrier_index, len(train.prefix))
|
S = take(symbols, carrier_index, len(train.prefix))
|
||||||
y = np.abs(S)
|
y = np.abs(S)
|
||||||
bits = np.round(y)
|
bits = np.round(y)
|
||||||
|
|
||||||
bits = np.array(bits, dtype=int)
|
bits = np.array(bits, dtype=int)
|
||||||
if all(bits != train.prefix):
|
if all(bits != train.prefix):
|
||||||
return None
|
raise ValueError('Incorrect prefix')
|
||||||
|
|
||||||
log.info('Prefix OK')
|
log.info('Prefix OK')
|
||||||
|
|
||||||
err = sigproc.drift( S[np.array(train.prefix, dtype=bool)] ) / (Tsym * Fc)
|
err = sigproc.drift( S[np.array(train.prefix, dtype=bool)] ) / (Tsym * Fc)
|
||||||
log.info('Frequency error: %.2f ppm', err * 1e6)
|
log.info('Frequency error: %.2f ppm', err * 1e6)
|
||||||
lp.sampler.freq -= err
|
return err
|
||||||
|
|
||||||
|
def train_receiver(symbols, freqs):
|
||||||
filters = {}
|
filters = {}
|
||||||
|
|
||||||
full_scale = len(freqs)
|
full_scale = len(freqs)
|
||||||
training_bits = np.array(train.equalizer)
|
training_bits = np.array(train.equalizer)
|
||||||
expected = full_scale * training_bits
|
expected = full_scale * training_bits
|
||||||
@@ -95,12 +91,15 @@ def receive(x, freqs):
|
|||||||
|
|
||||||
train_result = y > 0.5 * full_scale
|
train_result = y > 0.5 * full_scale
|
||||||
if not all(train_result == training_bits):
|
if not all(train_result == training_bits):
|
||||||
return None
|
return ValueError('#{} training failed on {} Hz'.format(i, freq))
|
||||||
|
|
||||||
noise = y - expected
|
noise = y - expected
|
||||||
Pnoise = sigproc.power(noise)
|
Pnoise = sigproc.power(noise)
|
||||||
log.info('{:10.1f} kHz: Noise sigma={:.4f}, SNR={:.1f} dB'.format( freq/1e3, Pnoise**0.5, 10*np.log10(1/Pnoise) ))
|
log.info('{:10.1f} kHz: Noise sigma={:.4f}, SNR={:.1f} dB'.format( freq/1e3, Pnoise**0.5, 10*np.log10(1/Pnoise) ))
|
||||||
|
|
||||||
|
return filters
|
||||||
|
|
||||||
|
def demodulate(symbols, filters, freqs):
|
||||||
streams = []
|
streams = []
|
||||||
symbol_list = []
|
symbol_list = []
|
||||||
|
|
||||||
@@ -133,6 +132,17 @@ def receive(x, freqs):
|
|||||||
return bitstream
|
return bitstream
|
||||||
|
|
||||||
|
|
||||||
|
def receive(signal, freqs):
|
||||||
|
signal = loop.FreqLoop(signal, freqs)
|
||||||
|
symbols = iter(signal)
|
||||||
|
|
||||||
|
err = receive_prefix(symbols)
|
||||||
|
signal.sampler.freq -= err
|
||||||
|
|
||||||
|
filters = train_receiver(symbols, freqs)
|
||||||
|
return demodulate(symbols, filters, freqs)
|
||||||
|
|
||||||
|
|
||||||
def main(fname):
|
def main(fname):
|
||||||
|
|
||||||
_, x = load(open(fname, 'rb'))
|
_, x = load(open(fname, 'rb'))
|
||||||
|
|||||||
Reference in New Issue
Block a user