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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
#
# Copyright 2005 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
_default_bitrate = 500e3
_valid_spbs = (2,3,4,5,6,7)
def _gen_tx_info(converter_rate):
results = []
for spb in _valid_spbs:
for interp in range(16, 512 + 1, 4):
bitrate = converter_rate / interp / spb
results.append((bitrate, spb, interp))
results.sort()
return results
def _gen_rx_info(converter_rate):
results = []
for spb in _valid_spbs:
for decim in range(8, 256 + 1, 2):
bitrate = converter_rate / decim / spb
results.append((bitrate, spb, decim))
results.sort()
return results
def _filter_info(info, samples_per_baud, xrate):
if samples_per_baud is not None:
info = [x for x in info if x[1] == samples_per_baud]
if xrate is not None:
info = [x for x in info if x[2] == xrate]
return info
def _pick_best(target_bitrate, bits_per_symbol, info):
"""
@returns tuple (bitrate, samples_per_baud, interp_rate_or_decim_rate)
"""
if len(info) == 0:
raise RuntimeError, "info is zero length!"
if target_bitrate is None: # return the fastest one
return info[-1]
# convert bit rate to symbol rate
target_symbolrate = target_bitrate / bits_per_symbol
# Find the closest matching symbol rate.
# In the event of a tie, the one with the lowest samples_per_baud wins.
# (We already sorted them, so the first one is the one we take)
best = info[0]
best_delta = abs(target_symbolrate - best[0])
for x in info[1:]:
delta = abs(target_symbolrate - x[0])
if delta < best_delta:
best_delta = delta
best = x
# convert symbol rate back to bit rate
return ((best[0] * bits_per_symbol),) + best[1:]
def _pick_bitrate(bitrate, bits_per_symbol, samples_per_baud,
xrate, converter_rate, gen_info):
"""
@returns tuple (bitrate, samples_per_baud, interp_rate_or_decim_rate)
"""
if not isinstance(bits_per_symbol, int) or bits_per_symbol < 1:
raise ValueError, "bits_per_symbol must be an int >= 1"
if samples_per_baud is not None and xrate is not None: # completely determined
return (float(converter_rate) / xrate / samples_per_baud,
samples_per_baud, xrate)
if bitrate is None and samples_per_baud is None and xrate is None:
bitrate = _default_bitrate
# now we have a target bitrate and possibly an xrate or
# samples_per_baud constraint, but not both of them.
return _pick_best(bitrate, bits_per_symbol,
_filter_info(gen_info(converter_rate), samples_per_baud, xrate))
# ---------------------------------------------------------------------------------------
def pick_tx_bitrate(bitrate, bits_per_symbol, samples_per_baud,
interp_rate, converter_rate=128e6):
"""
Given the 4 input parameters, return at configuration that matches
@param bitrate: desired bitrate or None
@type bitrate: number or None
@param bits_per_symbol: E.g., BPSK -> 1, QPSK -> 2, 8-PSK -> 3
@type bits_per_symbol: integer >= 1
@param samples_per_baud: samples/baud (aka samples/symbol)
@type samples_per_baud: number or None
@param interp_rate: USRP interpolation factor
@type interp_rate: integer or None
@param converter_rate: converter sample rate in Hz
@type converter_rate: number
@returns tuple (bitrate, samples_per_baud, interp_rate)
"""
return _pick_bitrate(bitrate, bits_per_symbol, samples_per_baud,
interp_rate, converter_rate, _gen_tx_info)
def pick_rx_bitrate(bitrate, bits_per_symbol, samples_per_baud,
decim_rate, converter_rate=64e6):
"""
Given the 4 input parameters, return at configuration that matches
@param bitrate: desired bitrate or None
@type bitrate: number or None
@param bits_per_symbol: E.g., BPSK -> 1, QPSK -> 2, 8-PSK -> 3
@type bits_per_symbol: integer >= 1
@param samples_per_baud: samples/baud (aka samples/symbol)
@type samples_per_baud: number or None
@param decim_rate: USRP decimation factor
@type decim_rate: integer or None
@param converter_rate: converter sample rate in Hz
@type converter_rate: number
@returns tuple (bitrate, samples_per_baud, decim_rate)
"""
return _pick_bitrate(bitrate, bits_per_symbol, samples_per_baud,
decim_rate, converter_rate, _gen_rx_info)
|