mirror of
https://github.com/romanz/amodem.git
synced 2026-05-06 02:16:27 +08:00
refactor loop
This commit is contained in:
25
drift.py
25
drift.py
@@ -1,31 +1,10 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
|
import pylab
|
||||||
|
|
||||||
import recv
|
|
||||||
import common
|
import common
|
||||||
import sigproc
|
import sigproc
|
||||||
import sampling
|
|
||||||
import loop
|
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():
|
def main():
|
||||||
f0 = 10e3
|
f0 = 10e3
|
||||||
_, x = common.load(file('recv_10kHz.pcm', 'rb'))
|
_, x = common.load(file('recv_10kHz.pcm', 'rb'))
|
||||||
@@ -34,7 +13,7 @@ def main():
|
|||||||
S = []
|
S = []
|
||||||
Y = []
|
Y = []
|
||||||
|
|
||||||
symbols = FreqLoop(x, f0)
|
symbols = loop.FreqLoop(x, f0)
|
||||||
prefix = 100
|
prefix = 100
|
||||||
for s in symbols:
|
for s in symbols:
|
||||||
S.append(s)
|
S.append(s)
|
||||||
|
|||||||
40
loop.py
40
loop.py
@@ -1,5 +1,9 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
import recv
|
||||||
|
import sampling
|
||||||
|
import sigproc
|
||||||
|
|
||||||
class Filter(object):
|
class Filter(object):
|
||||||
def __init__(self, b, a=()):
|
def __init__(self, b, a=()):
|
||||||
self.b = b
|
self.b = b
|
||||||
@@ -15,26 +19,20 @@ class Filter(object):
|
|||||||
self.y = [y] + self.y
|
self.y = [y] + self.y
|
||||||
return y
|
return y
|
||||||
|
|
||||||
class Loop(object):
|
class FreqLoop(object):
|
||||||
def __init__(self, x, A, k, h):
|
def __init__(self, x, freq):
|
||||||
self.x = np.array(x)
|
self.sampler = sampling.Sampler(x, sampling.Interpolator())
|
||||||
self.A = np.array(A)
|
self.symbols = recv.extract_symbols(self.sampler, freq)
|
||||||
self.k = np.array(k)
|
Kp, Ki = 0.2, 0.01
|
||||||
self.h = np.array(h)
|
b = np.array([1, -1])*Kp + np.array([0.5, 0.5])*Ki
|
||||||
|
self.filt = Filter(b=b, a=[1])
|
||||||
|
self.correction = 0.0
|
||||||
|
|
||||||
def __call__(self, y):
|
def correct(self, actual, expected):
|
||||||
self.err = y - np.dot(self.h, self.x)
|
self.err = np.angle(expected / actual) / np.pi
|
||||||
self.dx = self.k * self.err
|
self.err = sigproc.clip(self.err, [-0.1, 0.1])
|
||||||
self.x = self.x + self.dx
|
self.correction = self.filt(self.err)
|
||||||
self.x = np.dot(self.A, self.x)
|
self.sampler.correct(offset=self.correction)
|
||||||
|
|
||||||
class Integrator(Loop):
|
|
||||||
def __init__(self, phase, freq, k):
|
|
||||||
x = [phase, freq] # state variable vector
|
|
||||||
# evolution matrix:
|
|
||||||
# | phase' = phase + freq
|
|
||||||
# | freq' = freq
|
|
||||||
A = [[1, 1], [0, 1]]
|
|
||||||
h = [1, 0] # phase = dot(h, x)
|
|
||||||
Loop.__init__(self, x=x, A=A, k=k, h=h)
|
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return iter(self.symbols)
|
||||||
|
|||||||
Reference in New Issue
Block a user