mirror of
https://github.com/romanz/amodem.git
synced 2026-02-08 18:38:01 +08:00
66 lines
1.5 KiB
Python
66 lines
1.5 KiB
Python
import numpy as np
|
|
|
|
import recv
|
|
import common
|
|
import sigproc
|
|
import sampling
|
|
import loop
|
|
|
|
class FreqLoop(object):
|
|
def __init__(self, x, freq):
|
|
self.sampler = sampling.Sampler(x, sampling.Interpolator())
|
|
self.symbols = recv.extract_symbols(self.sampler, freq)
|
|
Kp, Ki = 0.2, 0.01
|
|
b = np.array([1, -1])*Kp + np.array([0.5, 0.5])*Ki
|
|
self.filt = loop.Filter(b=b, a=[1])
|
|
self.correction = 0.0
|
|
|
|
def correct(self, actual, expected):
|
|
self.err = np.angle(expected / actual) / np.pi
|
|
self.err = sigproc.clip(self.err, [-0.1, 0.1])
|
|
self.correction = self.filt(self.err)
|
|
self.sampler.correct(offset=self.correction)
|
|
|
|
def __iter__(self):
|
|
return iter(self.symbols)
|
|
|
|
import pylab
|
|
|
|
def main():
|
|
f0 = 10e3
|
|
_, x = common.load(file('recv_10kHz.pcm', 'rb'))
|
|
x = x[100:]
|
|
|
|
S = []
|
|
Y = []
|
|
|
|
symbols = FreqLoop(x, f0)
|
|
prefix = 100
|
|
for s in symbols:
|
|
S.append(s)
|
|
if len(S) > prefix:
|
|
symbols.correct(s, np.mean(S[:prefix]))
|
|
Y.append([
|
|
symbols.correction * (f0 / common.Nsym),
|
|
])
|
|
|
|
S = np.array(S)
|
|
|
|
pylab.figure()
|
|
|
|
pylab.subplot(121)
|
|
circle = np.exp(2j*np.pi*np.linspace(0, 1, 1001))
|
|
pylab.plot(S.real, S.imag, '.', circle.real, circle.imag, ':')
|
|
pylab.grid('on')
|
|
pylab.axis('equal')
|
|
|
|
Y = np.array(Y)
|
|
a = 0.01
|
|
pylab.subplot(122)
|
|
pylab.plot(list(sigproc.lfilter([a], [1, a-1], Y)), '-')
|
|
pylab.grid('on')
|
|
|
|
if __name__ == '__main__':
|
|
main()
|
|
pylab.show()
|