mirror of
https://github.com/romanz/amodem.git
synced 2026-03-25 11:51:02 +08:00
calib: test all frequencies
This commit is contained in:
@@ -1,47 +1,66 @@
|
|||||||
import sys
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
import logging
|
||||||
|
import sys
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
from . import common
|
from . import common
|
||||||
from . import config
|
from . import config
|
||||||
from . import dsp
|
|
||||||
from . import wave
|
from . import wave
|
||||||
|
|
||||||
Tsample = 1
|
CALIBRATION_SYMBOLS = int(1.0 * config.Fs)
|
||||||
t = np.arange(int(Tsample * config.Fs)) * config.Ts
|
|
||||||
sig = np.exp(2j * np.pi * config.Fc * t)
|
|
||||||
sig_dump = common.dumps(sig)
|
|
||||||
fmt = 'coherence={:.3f} amplitude={:.3f} phase={:+.1f} peak={:.3f}\n'
|
|
||||||
|
|
||||||
|
ALLOWED_EXCEPTIONS = (IOError, KeyboardInterrupt)
|
||||||
|
|
||||||
def send(wave_play=wave.play):
|
def send(wave_play=wave.play):
|
||||||
p = wave_play(stdin=wave.sp.PIPE, stderr=open('/dev/null'))
|
t = np.arange(0, CALIBRATION_SYMBOLS) * config.Ts
|
||||||
|
signal = [np.sin(2 * np.pi * f * t) for f in config.frequencies]
|
||||||
|
signal = common.dumps(np.concatenate(signal))
|
||||||
|
|
||||||
|
p = wave_play(stdin=wave.sp.PIPE)
|
||||||
|
fd = p.stdin
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
try:
|
fd.write(signal)
|
||||||
p.stdin.write(sig_dump)
|
except ALLOWED_EXCEPTIONS:
|
||||||
except IOError:
|
pass
|
||||||
return
|
finally:
|
||||||
except KeyboardInterrupt:
|
|
||||||
p.kill()
|
p.kill()
|
||||||
|
|
||||||
|
|
||||||
def recv(wave_record=wave.record, reporter=sys.stdout.write):
|
FRAME_LENGTH = 100 * config.Nsym
|
||||||
p = wave_record(stdout=wave.sp.PIPE)
|
|
||||||
|
def recorder(process):
|
||||||
|
frame_size = int(wave.bytes_per_sample * FRAME_LENGTH)
|
||||||
|
fd = process.stdout
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
data = p.stdout.read(len(sig_dump))
|
data = fd.read(frame_size)
|
||||||
if len(data) < len(sig_dump):
|
if len(data) < frame_size:
|
||||||
return
|
return
|
||||||
x = common.loads(data)
|
data = common.loads(data)
|
||||||
x = x - np.mean(x)
|
data = data - np.mean(data)
|
||||||
|
yield data
|
||||||
|
except ALLOWED_EXCEPTIONS:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
process.kill()
|
||||||
|
|
||||||
normalization_factor = np.sqrt(0.5 * len(x)) * dsp.norm(x)
|
def recv(wave_record=wave.record, log=sys.stdout.write):
|
||||||
coherence = np.abs(np.dot(x, sig)) / normalization_factor
|
t = np.arange(0, FRAME_LENGTH) * config.Ts
|
||||||
z = np.dot(x, sig.conj()) / (0.5 * len(x))
|
carriers = [np.exp(2j * np.pi * f * t) for f in config.frequencies]
|
||||||
amplitude = np.abs(z)
|
carriers = np.array(carriers) / (0.5 * len(t))
|
||||||
phase = np.angle(z)
|
|
||||||
peak = np.max(np.abs(x))
|
|
||||||
|
|
||||||
reporter(fmt.format(coherence, amplitude, phase * 180/np.pi, peak))
|
for frame in recorder(wave_record(stdout=wave.sp.PIPE)):
|
||||||
except KeyboardInterrupt:
|
peak = np.max(np.abs(frame))
|
||||||
p.kill()
|
coeffs = np.dot(carriers, frame)
|
||||||
|
max_index = np.argmax(np.abs(coeffs))
|
||||||
|
max_coeff = coeffs[max_index]
|
||||||
|
|
||||||
|
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'
|
||||||
|
|||||||
Reference in New Issue
Block a user