mirror of
https://github.com/romanz/amodem.git
synced 2026-03-18 07:36:02 +08:00
Fix prefix decoding by scaling signal using prefix amplitude
This commit is contained in:
33
recv.py
33
recv.py
@@ -44,6 +44,7 @@ def report_carrier(bufs, begin):
|
||||
' coherence=%.3f%%, amplitude=%.3f',
|
||||
begin * config.Tsym * 1e3 / config.Nsym, config.Fc / 1e3,
|
||||
np.abs(sigproc.coherence(x, config.Fc)) * 100, amp)
|
||||
return amp
|
||||
|
||||
|
||||
def detect(samples, freq):
|
||||
@@ -62,7 +63,7 @@ def detect(samples, freq):
|
||||
if counter == CARRIER_THRESHOLD:
|
||||
length = (CARRIER_THRESHOLD - 1) * config.Nsym
|
||||
begin = offset - length
|
||||
report_carrier(bufs, begin=begin)
|
||||
amplitude = report_carrier(bufs, begin=begin)
|
||||
break
|
||||
else:
|
||||
raise ValueError('No carrier detected')
|
||||
@@ -82,7 +83,7 @@ def detect(samples, freq):
|
||||
log.info('Carrier starts at %.3f ms',
|
||||
start * config.Tsym * 1e3 / config.Nsym)
|
||||
|
||||
return itertools.chain(buf[offset:], samples)
|
||||
return itertools.chain(buf[offset:], samples), amplitude
|
||||
|
||||
|
||||
def find_start(buf, length):
|
||||
@@ -95,21 +96,30 @@ def find_start(buf, length):
|
||||
def receive_prefix(symbols):
|
||||
S = common.take(symbols, len(train.prefix))[:, config.carrier_index]
|
||||
sliced = np.round(S)
|
||||
|
||||
nonzeros = np.array(train.prefix, dtype=bool)
|
||||
if pylab:
|
||||
pylab.figure()
|
||||
show.constellation(S, sliced, 'Prefix')
|
||||
|
||||
bits = np.array(np.abs(sliced), dtype=int)
|
||||
if all(bits != train.prefix):
|
||||
if any(bits != train.prefix):
|
||||
raise ValueError('Incorrect prefix')
|
||||
|
||||
log.info('Prefix OK')
|
||||
|
||||
nonzeros = np.array(train.prefix, dtype=bool)
|
||||
pilot_tone = S[nonzeros]
|
||||
phase = np.unwrap(np.angle(pilot_tone)) / (2 * np.pi)
|
||||
indices = np.arange(len(phase))
|
||||
a, b = sigproc.linear_regression(indices, phase)
|
||||
|
||||
freq_err = a / (config.Tsym * config.Fc)
|
||||
last_phase = a * indices[-1] + b
|
||||
log.debug('Current phase on carrier: %.3f', last_phase)
|
||||
|
||||
freq_err, mean_phase = sigproc.drift(pilot_tone) / (config.Tsym * config.Fc)
|
||||
expected_phase, = set(np.angle(sliced[nonzeros]) / (2 * np.pi))
|
||||
log.debug('Excepted phase on carrier: %.3f', expected_phase)
|
||||
|
||||
sampling_err = (mean_phase - expected_phase) * config.Nsym
|
||||
sampling_err = (last_phase - expected_phase) * config.Nsym
|
||||
log.info('Frequency error: %.2f ppm', freq_err * 1e6)
|
||||
log.info('Sampling error: %.2f samples', sampling_err)
|
||||
return freq_err, sampling_err
|
||||
@@ -198,13 +208,14 @@ def demodulate(symbols, filters, freqs, sampler):
|
||||
sampler.offset -= correction
|
||||
|
||||
|
||||
def receive(signal, freqs):
|
||||
def receive(signal, freqs, gain=1.0):
|
||||
signal = loop.FreqLoop(signal, freqs)
|
||||
signal.sampler.gain = gain
|
||||
symbols = iter(signal)
|
||||
|
||||
freq_err, offset_err = receive_prefix(symbols)
|
||||
signal.sampler.freq -= freq_err
|
||||
signal.sampler.offset -= offset_err
|
||||
signal.sampler.freq -= freq_err
|
||||
|
||||
filters = train_receiver(symbols, freqs)
|
||||
data_bits = demodulate(symbols, filters, freqs, signal.sampler)
|
||||
@@ -240,8 +251,8 @@ def main(args):
|
||||
stream.check = common.check_saturation
|
||||
|
||||
size = 0
|
||||
signal = detect(signal, config.Fc)
|
||||
bits = receive(signal, modem.freqs)
|
||||
signal, amplitude = detect(signal, config.Fc)
|
||||
bits = receive(signal, modem.freqs, gain=1.0/amplitude)
|
||||
try:
|
||||
for chunk in decode(bits):
|
||||
sys.stdout.write(chunk)
|
||||
|
||||
@@ -43,6 +43,7 @@ class Sampler(object):
|
||||
self.offset = self.interp.width + 1
|
||||
self.buff = np.zeros(self.interp.coeff_len)
|
||||
self.index = 0
|
||||
self.gain = 1.0
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
@@ -52,7 +53,7 @@ class Sampler(object):
|
||||
self.offset += offset
|
||||
|
||||
def next(self):
|
||||
res = self._sample()
|
||||
res = self._sample() * self.gain
|
||||
self.offset += self.freq
|
||||
return res
|
||||
|
||||
|
||||
Reference in New Issue
Block a user