refactor calibration recv script

This commit is contained in:
Roman Zeyde
2014-10-21 10:42:13 +03:00
parent 6b483335e9
commit 3a59a54107
3 changed files with 50 additions and 25 deletions

View File

@@ -12,7 +12,7 @@ CALIBRATION_SYMBOLS = int(1.0 * config.Fs)
ALLOWED_EXCEPTIONS = (IOError, KeyboardInterrupt) ALLOWED_EXCEPTIONS = (IOError, KeyboardInterrupt)
def send(wave_play=wave.play): def send(wave_play=wave.play, verbose=False):
t = np.arange(0, CALIBRATION_SYMBOLS) * config.Ts t = np.arange(0, CALIBRATION_SYMBOLS) * config.Ts
signal = [np.sin(2 * np.pi * f * t) for f in config.frequencies] signal = [np.sin(2 * np.pi * f * t) for f in config.frequencies]
signal = common.dumps(np.concatenate(signal)) signal = common.dumps(np.concatenate(signal))
@@ -28,41 +28,66 @@ def send(wave_play=wave.play):
p.kill() p.kill()
FRAME_LENGTH = 100 * config.Nsym FRAME_LENGTH = 200 * config.Nsym
def recorder(process): def recorder(process):
t = np.arange(0, FRAME_LENGTH) * config.Ts
scaling_factor = 0.5 * len(t)
carriers = [np.exp(2j * np.pi * f * t) for f in config.frequencies]
carriers = np.array(carriers) / scaling_factor
frame_size = int(wave.bytes_per_sample * FRAME_LENGTH) frame_size = int(wave.bytes_per_sample * FRAME_LENGTH)
fd = process.stdout fd = process.stdout
states = [True]
errors = ['weak', 'strong', 'noisy']
try: try:
while True: while True:
data = fd.read(frame_size) data = fd.read(frame_size)
if len(data) < frame_size: if len(data) < frame_size:
return return
data = common.loads(data) data = common.loads(data)
data = data - np.mean(data) frame = data - np.mean(data)
yield data
coeffs = np.dot(carriers, frame)
peak = np.max(np.abs(frame))
total = np.sqrt(np.dot(frame, frame) / scaling_factor)
max_index = np.argmax(np.abs(coeffs))
freq = config.frequencies[max_index]
rms = abs(coeffs[max_index])
coherency = rms / total
flags = [rms > 0.1, peak < 1.0, coherency > 0.9999]
states.append(all(flags))
states = states[-2:]
message = 'good signal'
error = not any(states)
if error:
error_index = flags.index(False)
message = 'too {} signal'.format(errors[error_index])
yield dict(
freq=freq, rms=rms, peak=peak, coherency=coherency,
total=total, error=error, message=message
)
except ALLOWED_EXCEPTIONS: except ALLOWED_EXCEPTIONS:
pass pass
finally: finally:
process.kill() process.kill()
fmt = '{freq:6.0f} Hz: {message:s}{extra:s}'
fields = ['peak', 'total', 'rms', 'coherency']
def recv(wave_record=wave.record, log=sys.stdout.write): def recv(wave_record=wave.record, printer=sys.stdout.write, verbose=False):
t = np.arange(0, FRAME_LENGTH) * config.Ts extra = ''
carriers = [np.exp(2j * np.pi * f * t) for f in config.frequencies] if verbose:
carriers = np.array(carriers) / (0.5 * len(t)) extra = ''.join(', {0}={{{0}:.4f}}'.format(f) for f in fields)
for r in recorder(wave_record(stdout=wave.sp.PIPE)):
for frame in recorder(wave_record(stdout=wave.sp.PIPE)): msg = fmt.format(extra=extra.format(**r), **r)
peak = np.max(np.abs(frame)) if not r['error']:
coeffs = np.dot(carriers, frame) log.info(msg)
max_index = np.argmax(np.abs(coeffs)) else:
max_coeff = coeffs[max_index] log.error(msg)
freq = config.frequencies[max_index]
rms = abs(max_coeff)
total = np.sqrt(np.dot(frame, frame) / (0.5 * len(t)))
coherency = rms / total
log(fmt.format(freq / 1e3, 100 * coherency, rms, total, peak))
fmt = '{:4.0f} kHz @ {:6.2f}% : RMS = {:.4f}, Total = {:.4f}, Peak = {:.4f}\n'

View File

@@ -148,7 +148,7 @@ def run_modem(args, func):
def run_send(args): def run_send(args):
if args.calibrate: if args.calibrate:
calib.send() calib.send(verbose=args.verbose)
elif args.wave: elif args.wave:
join_process(wave.play(fname=args.input)) join_process(wave.play(fname=args.input))
else: else:
@@ -157,7 +157,7 @@ def run_send(args):
def run_recv(args): def run_recv(args):
if args.calibrate: if args.calibrate:
calib.recv() calib.recv(verbose=args.verbose)
elif args.wave: elif args.wave:
join_process(wave.record(fname=args.output)) join_process(wave.record(fname=args.output))
else: else:

View File

@@ -43,5 +43,5 @@ def test_errors():
def _read(data): def _read(data):
raise KeyboardInterrupt() raise KeyboardInterrupt()
p.read = _read p.read = _read
calib.recv(p) calib.recv(p, verbose=True)
assert p.buf.tell() == 0 assert p.buf.tell() == 0