-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinterleave.h
More file actions
135 lines (118 loc) · 4.04 KB
/
interleave.h
File metadata and controls
135 lines (118 loc) · 4.04 KB
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
/*
* Copyright 2026 Corey Minyard
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* This is an interleaver for interleaving bits for transmission.
*/
#ifndef INTERLEAVE_H
#define INTERLEAVE_H
#include <stdint.h>
/*
* Interleaving
*
* Codes often get interleaved on the input and/or the output.
* Convolutional codes perform better if the errors are spread out,
* and errors in the real world tend to be bunched together in events.
*
* Interleaving spreads the bits out so that consecutive bits coming
* into the decoder are not consecutive bits from the receiver. It
* does this by treating the data as an array of bits that is
* interleave_len wide and total_size / interleave_len long (plus an
* extra entry for any leftover bits).
*
* For encoding, data is pulled out of the source array array starting
* with column 0 and down the rows, and after a column is complete go
* back to row 0 and go down column 1, etc. taking care with the
* entries in the last row not to index past the end of the array.
*
* For decoding, the opposite is done, you feed bits into the decoder
* and it puts it into the output bit array.
*
* Bits are numbered with the low bit in a byte first.
*/
struct interleaver {
/*
* Total length in bits of the data to interleave.
*/
unsigned int total_bits;
/*
* The number of bits to jump when interleaving, or the number of
* columns in the array.
*/
unsigned int interleave;
/*
* Total number of rows in the array. Note that the last row may
* not be full.
*/
unsigned int num_rows;
/*
* If the last row is not full (total_bits % interleave != 0) this
* will be the last column that is valid in the last row. If the
* last row is full, this will be interleave, whic is still the
* last valid row.
*/
unsigned int last_full_col;
uint8_t *data;
/* Current row and column. */
unsigned int row;
unsigned int col;
};
/*
* Initialize the interleaver structure.
*
* You must call this before using the interleaver object.
*
* interleave_len is the length of the interleave operation, or the
* number of bits to skip for consectutive bits.
*
* data is the input data for interleave_bit, the output data for
* deinterleave_bit.
*
* total_bits is the total size (in bits) of the data. It does not
* need to be byte aligned.
*/
void interleaver_init(struct interleaver *di,
unsigned int interleave_len,
uint8_t *data, unsigned int total_bits);
/*
* Interleave an operation. This particular one does not require an
* interleaver object, it generated the output to a function a bit at
* a time. Same meanings for parameters as interleave_init() above.
*
* The output function is called on every bit in output order, that
* function also get the user_data object passed in here. bit will be
* 0 or 1.
*/
void interleave(unsigned int interleave_len,
uint8_t *data, unsigned int total_bits,
void (*output)(void *user_data, unsigned int bit),
void *user_data);
/*
* Get the next output bit from the interleaver. Returns 0 or 1. Be
* sure not to call this more than total_bits or you will overrun the
* array.
*
* This function will pull bits out of the data in interleaved order.
*/
unsigned int interleave_bit(struct interleaver *di);
/*
* Give an input bit to the deinterleaver and store the next bit in
* the data. Be sure not to call this more than total_bits or you
* will overrun the array.
*
* The input bits should come in interleaved order and will be stored
* in the data array in original order.
*/
void deinterleave_bit(struct interleaver *di, unsigned int bitval);
/*
* Interleave and deinterleave blocks of data, as above, but with
* input and output blocks of data. Note that outdata must be zero-ed
* before calling this.
*/
void interleave_block(unsigned int interleave_len, uint8_t *indata,
uint8_t *outdata, unsigned int total_bits);
void deinterleave_block(unsigned int interleave_len, uint8_t *indata,
uint8_t *outdata, unsigned int total_bits);
#endif /* INTERLEAVE_H */