-
Notifications
You must be signed in to change notification settings - Fork 0
/
config.py
91 lines (72 loc) · 3.13 KB
/
config.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
"""Configuration class."""
import numpy as np
class Configuration:
Fs = 32000.0 # sampling frequency [Hz]
Tsym = 0.001 # symbol duration [seconds]
Npoints = 64
frequencies = [1e3, 8e3] # use 1..8 kHz carriers
# audio config
bits_per_sample = 16
latency = 0.1
# sender config
silence_start = 0.25
silence_stop = 0.25
# receiver config
skip_start = 0.1
timeout = 60.0
def __init__(self, **kwargs):
self.__dict__.update(**kwargs)
self.sample_size = self.bits_per_sample // 8
assert self.sample_size * 8 == self.bits_per_sample
self.Ts = 1.0 / self.Fs
self.Fsym = 1 / self.Tsym
self.Nsym = int(self.Tsym / self.Ts)
self.baud = int(1.0 / self.Tsym)
assert self.baud * self.Tsym == 1
if len(self.frequencies) != 1:
first, last = self.frequencies
self.frequencies = np.arange(first, last + self.baud, self.baud)
self.Nfreq = len(self.frequencies)
self.carrier_index = 0
self.Fc = self.frequencies[self.carrier_index]
bits_per_symbol = int(np.log2(self.Npoints))
assert 2 ** bits_per_symbol == self.Npoints
self.bits_per_baud = bits_per_symbol * self.Nfreq
self.modem_bps = self.baud * self.bits_per_baud
self.carriers = np.array([
np.exp(2j * np.pi * f * np.arange(0, self.Nsym) * self.Ts)
for f in self.frequencies
])
# QAM constellation
Nx = 2 ** int(np.ceil(bits_per_symbol // 2))
Ny = self.Npoints // Nx
symbols = [complex(x, y) for x in range(Nx) for y in range(Ny)]
symbols = np.array(symbols)
symbols = symbols - symbols[-1]/2
self.symbols = symbols / np.max(np.abs(symbols))
print(self.symbols)
# MODEM configurations for various bitrates [kbps]
bitrates = {
1: Configuration(Fs=8e3, Npoints=2, frequencies=[2e3]),
2: Configuration(Fs=8e3, Npoints=4, frequencies=[2e3]),
4: Configuration(Fs=8e3, Npoints=16, frequencies=[2e3]),
8: Configuration(Fs=8e3, Npoints=16, frequencies=[1e3, 2e3]),
12: Configuration(Fs=16e3, Npoints=16, frequencies=[3e3, 5e3]),
16: Configuration(Fs=16e3, Npoints=16, frequencies=[2e3, 5e3]),
20: Configuration(Fs=16e3, Npoints=16, frequencies=[2e3, 6e3]),
24: Configuration(Fs=16e3, Npoints=16, frequencies=[1e3, 6e3]),
28: Configuration(Fs=32e3, Npoints=16, frequencies=[3e3, 9e3]),
32: Configuration(Fs=32e3, Npoints=16, frequencies=[2e3, 9e3]),
36: Configuration(Fs=32e3, Npoints=64, frequencies=[4e3, 9e3]),
42: Configuration(Fs=32e3, Npoints=64, frequencies=[4e3, 10e3]),
48: Configuration(Fs=32e3, Npoints=64, frequencies=[3e3, 10e3]),
54: Configuration(Fs=32e3, Npoints=64, frequencies=[2e3, 10e3]),
60: Configuration(Fs=32e3, Npoints=64, frequencies=[2e3, 11e3]),
64: Configuration(Fs=32e3, Npoints=256, frequencies=[3e3, 10e3]),
72: Configuration(Fs=32e3, Npoints=256, frequencies=[2e3, 10e3]),
80: Configuration(Fs=32e3, Npoints=256, frequencies=[2e3, 11e3]),
}
def fastest():
return bitrates[max(bitrates)]
def slowest():
return bitrates[min(bitrates)]