summaryrefslogtreecommitdiff
path: root/cesar/ce/rx/bitloading/inc/bitloading.h
blob: b6f2a658b305481a4f15df223d87fab95a3f8b99 (plain)
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
#ifndef ce_rx_bitloading_inc_bitloading_h
#define ce_rx_bitloading_inc_bitloading_h
/* Cesar project {{{
 *
 * Copyright (C) 2010 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    ce/rx/bitloading/inc/bitloading.h
 * \brief   Functions to compute tone map using TNS algorithms.
 * \ingroup ce_rx_bl
 *
 * This header declares functions used to compute and optimize tone maps using
 * the TNS algorithms. Those functions are used by the bit loading initial and
 * iterative.
 */

#include "ce/rx/bitloading/bitloading.h"

#include "mac/common/tonemap.h"
#include "mac/common/tonemask.h"

/**
 * Structure for the table to sort carriers with lowest BER impact.
 * This table will contains all the theoretical BER that respect the BER
 * consign and the impact when increasing of one modulation on theoretical
 * BER.
 */
typedef struct ce_rx_bl_ber_impact_t
{
    /**
     * Index of the carrier.
     */
    u16 carrier_index;
    /**
     * BER theoretical of the modulation that respect BER consign.
     */
    u64 ber_lower;
    /**
     * Impact on BER when increasing modulation to the next upper one.
     */
    u32 ber_diff;
} ce_rx_bl_ber_impact_t;

BEGIN_DECLS

/**
 * Compare two values.
 * \param  table  optimization table.
 * \param  p1  first position to compare.
 * \param  p2  second position to compare.
 * \return  true if p1 < p2.
 */
static inline bool
ce_rx_bl_ber_impact_compare (ce_rx_bl_ber_impact_t *table, uint p1, uint p2)
{
    /* Check parameter. */
    dbg_assert (table);

    if (table[p1].ber_diff < table[p2].ber_diff)
        return true;
    return false;
}

/**
 * Swap two values.
 * \param  table  optimization table.
 * \param  p1  first index to swap.
 * \param  p2  second index to swap.
 */
static inline void
ce_rx_bl_ber_impact_swap (ce_rx_bl_ber_impact_t *table, uint p1, uint p2)
{
    /* Check parameter. */
    dbg_assert (table);

    XCH (table[p1], table[p2]);
}

/**
 * Sort optimization table to increase carrier with lowest BER impact.
 * \param  opti_table  the optimization table to sort.
 * \param  size  the size of the opti_table.
 */
void
ce_rx_bl_sort_optimization (ce_rx_bl_ber_impact_t *opti_table, uint size);

/**
 * Set a tone map under a BER consign.
 * \param  ber_pt  BER consign to respect.
 * \param  tonemask  the tone mask context.
 * \param  fec_rate  the FEC rate to use (for the polynomial).
 * \param  bl  the bit loading context.
 * \param  tm  tone map initial generated (non-optimized version).
 * \param  opti_table  the optimization table (required to optimize the tone
 * \param  tone_en  tone enabled count (active but not 0).
 * map).
 * \return  the sum of theoretical BER for the generated tone map (based on
 * the ber_lower) pondered by the modulation (Q49U64).
 *
 * For each tone, this function will find the modulation which respect the BER
 * consign. In consequence, the tone map will always be under the BER consign.
 * In contrast, \sa ce_rx_bl_update_tone_map_at_ber_consign
 * will update the tone map at BER consign.
 *
 * It also generates an non-sorted optimization table (for next step, to
 * improve BER to reach BER consign).
 */
u64
ce_rx_bl_update_tone_map_under_ber_consign (u64 ber_pt,
                                            tonemask_info_t *tonemask,
                                            phy_fecrate_t fec_rate,
                                            ce_rx_bitloading_t *bl,
                                            tonemap_t *tm,
                                            ce_rx_bl_ber_impact_t *opti_table,
                                            uint *tone_en);

/**
 * Update a tone map to reach a BER consign.
 * \param  ber_pt  BER consign to respect.
 * \param  tonemask  the tone mask context.
 * \param  bl  the bit loading context.
 * \param  tm  tone map initial generated (non-iterative version).
 * \param  opti  the optimization table.
 * \param  ber_weighted_sum_q49  the sum of theoretical BER pondered by
 * modulation for the tone map (Q49U64)
 * \param  tone_en  tone enabled count (active but not 0).
 * \return  The position of the cursor in the optimization table.
 *
 * This function updates a tone map to make it perfectly respect the BER
 * consign (or just under).
 */
u16
ce_rx_bl_update_tone_map_at_ber_consign (u64 ber_pt,
                                         tonemask_info_t *tonemask,
                                         ce_rx_bitloading_t *bl,
                                         tonemap_t *tm,
                                         ce_rx_bl_ber_impact_t *opti,
                                         u64 *ber_weighted_sum_q49,
                                         uint *tone_en);

/**
 * Compute a tone map which iterates on the BER consign.
 * \param  bpt_initial  initial bits per tone (to compute initial BER
 * consign).
 * \param  iteration_max  maximum number of iteration.
 * \param  tonemask  the tone mask context.
 * \param  bl  the bit loading context.
 * \return  the computed tone map or NULL if no tone map computation is
 * possible.
 *
 * This function generates a tone map which respect the BER consign, based on
 * the bit per tone initial. It re-does this process with a new BER consign,
 * based on the bit per tone of the newly generated tone map. Those iterations
 * are repeated until no evolution of the BER consign or the maximum number of
 * iterations is reached.
 *
 * This whole algorithm is done twice, for each FEC rate and only keep the
 * best tone map pondered by the FEC rate.
 */
tonemap_t *
ce_rx_bl_compute_tone_map_iterative (const u64 bpt_initial[PHY_FEC_RATE_NB],
                                     uint iteration_max,
                                     tonemask_info_t *tonemask,
                                     ce_rx_bitloading_t *bl);

/**
 * List actions to perform during a tone map update.
 */
typedef enum ce_rx_bl_tone_map_update_actions_t
{
    /** Tone map update - . */
    CE_RX_BL_TONE_MAP_UPDATE_MINUS,
    /** Tone map update + .*/
    CE_RX_BL_TONE_MAP_UPDATE_PLUS,
    /** Tone map update none. */
    CE_RX_BL_TONE_MAP_UPDATE_NONE,
    /** Tone map update action count. */
    CE_RX_BL_TONE_MAP_UPDATE_NB
} ce_rx_bl_tone_map_update_actions_t;

/**
 * Tone map update parameters (see bitloading algorithm documentation).
 * \warning  Must be positive values.
 */
#define CE_RX_BL_TONE_MAP_UPDATE_MINUS_COEFF 800
#define CE_RX_BL_TONE_MAP_UPDATE_PLUS_COEFF 133
/**
 * This define a percentage of BERin target.
 * It permits to define a zone where we don't perform any action.
 * This zone is between BERinT and (BERinT -
 * BerinT / CE_RX_BL_TONE_MAP_UPDATE_MIDDLE_PERCENTAGE).
 * \warning  Percentage must be strictly positive.
 */
#define CE_RX_BL_TONE_MAP_UPDATE_MIDDLE_PERCENTAGE 10

/**
 * Compute which action to perform depend on sliding means.
 * \param  ber_target  ber target
 * \param  means  ber sliding means
 * \return  tone map update action to perform
 * \see  ce_rx_bl_tone_map_update_actions_t.
 */
ce_rx_bl_tone_map_update_actions_t
ce_rx_bl_tone_map_update_action (u64 ber_target,
                                 u64 means[CE_RX_BL_BER_SLIDING_MEAN_NB]);

/**
 * Compute the number of tones to shift in the optimization table depend on
 * the BER target, the action to perform and the current BER sliding means.
 * \param  action  action to perform
 * \param  ber_target  ber target
 * \param  means  ber sliding means
 * \return  number of shift you may theoretically do on the optimization
 * table (this number can be out of range).
 * The direction of optimization only depends on action value.
 */
u16
ce_rx_bl_tone_map_update_count (ce_rx_bl_tone_map_update_actions_t action,
                                u64 ber_target,
                                u64 means[CE_RX_BL_BER_SLIDING_MEAN_NB]);

/**
 * This corresponds to the output status of
 * ce_rx_bl_tone_map_update_compute_new_tonemap.
 * \see  ce_rx_bl_tone_map_update_compute_new_tonemap.
 */
typedef enum ce_rx_bl_tone_map_update_status_t
{
    /** Successfully updated tone map. */
    CE_RX_BL_TONE_MAP_UPDATE_STATUS_OK,
    /** No action to perform, it's ok. */
    CE_RX_BL_TONE_MAP_UPDATE_STATUS_NOTHING,
    /** Update ok but minimal limit of optimization table reached. */
    CE_RX_BL_TONE_MAP_UPDATE_STATUS_OUT_OF_RANGE_MIN,
    /** Update ok but maximal limit of optimization table reached. */
    CE_RX_BL_TONE_MAP_UPDATE_STATUS_OUT_OF_RANGE_MAX,
    /** Update ok but we stop at first maximum carriage. */
    CE_RX_BL_TONE_MAP_UPDATE_STATUS_MAX_CARRIAGE,
    /** Update ok but we stop at first minimum carriage. */
    CE_RX_BL_TONE_MAP_UPDATE_STATUS_MIN_CARRIAGE,
    /** Error, no update done. */
    CE_RX_BL_TONE_MAP_UPDATE_STATUS_ERROR,
    /** Tone map update status count. */
    CE_RX_BL_TONE_MAP_UPDATE_STATUS_NB
} ce_rx_bl_tone_map_update_status_t;

/**
 * Create a new tone map based on old one with some adjustments
 * done using the optimization table. The new tone map is copied
 * in new_tonemap depending of the return value. Except if the ERROR status
 * occurs, the number of shift done in the optimization table is updated.
 * \see  ce_rx_bl_tone_map_update_status_t).
 * \param  bl  pointer to ce_rx_bitloading_t for optimization table access,
 * ber sliding means and optimization cursor.
 * \param  ber_target  ber target.
 * \param  tm  tone map to update (which stay unedited and is copied to
 * new_tonemap in case of successful update).
 * \param  tone_en  tone enabled count.
 * \param  new_tonemap  new tone map pointer if return status is OK.
 * \return  operation status (see ce_rx_bl_tone_map_update_status_t).
 */
ce_rx_bl_tone_map_update_status_t
ce_rx_bl_tone_map_update_compute_new_tonemap (ce_rx_bitloading_t *bl,
                                              u64 ber_target,
                                              tonemap_t *tm,
                                              uint tone_en,
                                              tonemap_t **new_tonemap);

/**
 * Update PB Error Rate sliding mean.
 * \param  pber_sliding_mean  PB Error Rate sliding mean.
 * \param  pb_count  total PB count, must be superior to zero.
 * \param  false_pb_count  false PB count.
 */
void
ce_rx_bl_pber_sliding_mean_update (ce_rx_bitloading_t *bt,
                                   uint pb_count,
                                   uint false_pb_count);

END_DECLS

#endif /* ce_rx_bitloading_inc_bitloading_h */