summaryrefslogtreecommitdiffstats
path: root/src/conv_acc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/conv_acc.c')
-rw-r--r--src/conv_acc.c50
1 files changed, 23 insertions, 27 deletions
diff --git a/src/conv_acc.c b/src/conv_acc.c
index f45d50f0..13b220b0 100644
--- a/src/conv_acc.c
+++ b/src/conv_acc.c
@@ -164,7 +164,7 @@ struct vdecoder {
int len;
int recursive;
int intrvl;
- struct vtrellis *trellis;
+ struct vtrellis trellis;
int16_t **paths;
void (*metric_func)(const int8_t *, const int16_t *,
@@ -372,41 +372,38 @@ static void free_trellis(struct vtrellis *trellis)
vdec_free(trellis->outputs);
vdec_free(trellis->sums);
free(trellis->vals);
- free(trellis);
}
-/* Allocate and initialize the trellis object
+/* Initialize the trellis object
* Initialization consists of generating the outputs and output value of a
* given state. Due to trellis symmetry and anti-symmetry, only one of the
* transition paths is utilized by the butterfly operation in the forward
* recursion, so only one set of N outputs is required per state variable.
*/
-static struct vtrellis *generate_trellis(const struct osmo_conv_code *code)
+static int generate_trellis(struct vdecoder *dec,
+ const struct osmo_conv_code *code)
{
- int i, rc = -1;
- struct vtrellis *trellis;
+ struct vtrellis *trellis = &dec->trellis;
int16_t *outputs;
+ int i, rc;
int ns = NUM_STATES(code->K);
- int recursive = conv_code_recursive(code);
int olen = (code->N == 2) ? 2 : 4;
- trellis = (struct vtrellis *) calloc(1, sizeof(struct vtrellis));
- if (!trellis)
- goto fail;
-
trellis->num_states = ns;
trellis->sums = vdec_malloc(ns);
trellis->outputs = vdec_malloc(ns * olen);
trellis->vals = (uint8_t *) malloc(ns * sizeof(uint8_t));
- if (!trellis->sums || !trellis->outputs || !trellis->vals)
+ if (!trellis->sums || !trellis->outputs || !trellis->vals) {
+ rc = -ENOMEM;
goto fail;
+ }
/* Populate the trellis state objects */
for (i = 0; i < ns; i++) {
outputs = &trellis->outputs[olen * i];
- if (recursive) {
+ if (dec->recursive) {
rc = gen_recursive_state_info(&trellis->vals[i],
i, outputs, code);
} else {
@@ -429,11 +426,11 @@ static struct vtrellis *generate_trellis(const struct osmo_conv_code *code)
if (code->term != CONV_TERM_TAIL_BITING)
trellis->sums[0] = INT8_MAX * code->N * code->K;
- return trellis;
+ return 0;
fail:
free_trellis(trellis);
- return NULL;
+ return rc;
}
static void _traceback(struct vdecoder *dec,
@@ -444,7 +441,7 @@ static void _traceback(struct vdecoder *dec,
for (i = len - 1; i >= 0; i--) {
path = dec->paths[i][state] + 1;
- out[i] = dec->trellis->vals[state];
+ out[i] = dec->trellis.vals[state];
state = vstate_lshift(state, dec->k, path);
}
}
@@ -457,7 +454,7 @@ static void _traceback_rec(struct vdecoder *dec,
for (i = len - 1; i >= 0; i--) {
path = dec->paths[i][state] + 1;
- out[i] = path ^ dec->trellis->vals[state];
+ out[i] = path ^ dec->trellis.vals[state];
state = vstate_lshift(state, dec->k, path);
}
}
@@ -472,8 +469,8 @@ static int traceback(struct vdecoder *dec, uint8_t *out, int term, int len)
unsigned path, state = 0;
if (term != CONV_TERM_FLUSH) {
- for (i = 0; i < dec->trellis->num_states; i++) {
- sum = dec->trellis->sums[i];
+ for (i = 0; i < dec->trellis.num_states; i++) {
+ sum = dec->trellis.sums[i];
if (sum > max) {
max = sum;
state = i;
@@ -503,7 +500,7 @@ static void vdec_deinit(struct vdecoder *dec)
if (!dec)
return;
- free_trellis(dec->trellis);
+ free_trellis(&dec->trellis);
if (dec->paths != NULL) {
vdec_free(dec->paths[0]);
@@ -517,7 +514,7 @@ static void vdec_deinit(struct vdecoder *dec)
*/
static int vdec_init(struct vdecoder *dec, const struct osmo_conv_code *code)
{
- int i, ns;
+ int i, ns, rc;
ns = NUM_STATES(code->K);
@@ -563,9 +560,9 @@ static int vdec_init(struct vdecoder *dec, const struct osmo_conv_code *code)
else
dec->len = code->len;
- dec->trellis = generate_trellis(code);
- if (!dec->trellis)
- goto enomem;
+ rc = generate_trellis(dec, code);
+ if (rc)
+ return rc;
dec->paths = (int16_t **) malloc(sizeof(int16_t *) * dec->len);
if (!dec->paths)
@@ -610,13 +607,12 @@ static int depuncture(const int8_t *in, const int *punc, int8_t *out, int len)
*/
static void forward_traverse(struct vdecoder *dec, const int8_t *seq)
{
- struct vtrellis *trellis = dec->trellis;
int i;
for (i = 0; i < dec->len; i++) {
dec->metric_func(&seq[dec->n * i],
- trellis->outputs,
- trellis->sums,
+ dec->trellis.outputs,
+ dec->trellis.sums,
dec->paths[i],
!(i % dec->intrvl));
}