blob: c415d42ce9ddaeefda2de6fe6f031d8e6cbe73ff [file] [log] [blame]
#include <memory.h>
#include <stdio.h>
#include <assert.h>
#include "common.h"
void dec_viterbi_F(dvector* Metr_mem, unsigned char* history_mem, bitvector* bit_stream,
const dvarray* Dist, const param_viterbi_t* param, size_t n)
{
size_t i_in = 0, i_punct, i, j, vote, bv = 0;
double *Metr0, *Metr1, *Metr;
char X0, X1, Y0, Y1;
unsigned char history[MAX_Nways][MAX_history];
unsigned char history_new[MAX_Nways][MAX_history+1];
#if 0
/* FIXME */
/* Time varies between runs giving false negatives about which run
(JIT or LLC) failed */
double startTime, now, estTotal;
#endif /* 0 */
if (bit_stream->length) {
bitvector_clear(bit_stream);
}
if (n==0) {
n = Dist->data[0].length;
}
bitvector_init(bit_stream, n);
Metr = (double*)malloc(Metr_mem->length*sizeof(double));
Metr0 = (double*)malloc(Metr_mem->length*sizeof(double));
Metr1 = (double*)malloc(Metr_mem->length*sizeof(double));
memcpy(Metr, Metr_mem->data, Metr_mem->length*sizeof(double));
memcpy(history, history_mem, sizeof(history));
#if 0
/* FIXME */
/* Time varies between runs giving false negatives about which run
(JIT or LLC) failed */
startTime = sTime();
#endif /* 0 */
i_punct = 0;
while (i_in<bit_stream->length) {
#if 0
/* FIXME */
/* Time varies between runs giving false negatives about which run
(JIT or LLC) failed */
if (i_in && (i_in % 10000 == 0)) {
now = sTime();
estTotal = ((double)1.02*bit_stream->length/((double)i_in))*(now-startTime);
printf("Viterbi: Estimate %1.1lf%% complete (%1.1lf seconds / %1.1lf seconds)...\n",
(double)100.0*i_in/(1.02*bit_stream->length), now-startTime, estTotal);
fflush(stdout);
}
#endif /* 0 */
memcpy(Metr0, Metr, Metr_mem->length*sizeof(double));
memcpy(Metr1, Metr, Metr_mem->length*sizeof(double));
if (param->punct1[i_punct] == 1) {
for (i=0; i<param->Nways; ++i) {
X0 = param->Tabl_X[i];
X1 = 1 - param->Tabl_X[i];
Metr0[i] = Metr0[i] + Dist->data[X0].data[i_in];
Metr1[i] = Metr1[i] + Dist->data[X1].data[i_in];
}
++i_in;
}
if (param->punct2[i_punct] == 1) {
if (i_in >= bit_stream->length) {
assert(0 && "Synchronization in Viterbi: i_in > size(Dist,2)");
}
for (i=0; i<param->Nways; ++i) {
Y0 = param->Tabl_Y[i];
Y1 = 1 - param->Tabl_Y[i];
Metr0[i] = Metr0[i] + Dist->data[Y0].data[i_in];
Metr1[i] = Metr1[i] + Dist->data[Y1].data[i_in];
}
++i_in;
}
for (i=0; i<param->Nways/2; ++i) {
if (Metr0[2*i] <= Metr0[2*i+1]) {
Metr[i] = Metr0[2*i];
history_new[i][0] = 0;
for (j=0; j<MAX_history; ++j) {
history_new[i][j+1] = history[2*i][j];
}
} else {
Metr[i] = Metr0[2*i+1];
history_new[i][0] = 1;
for (j=0; j<MAX_history; ++j) {
history_new[i][j+1] = history[2*i+1][j];
}
}
if (Metr1[2*i] <= Metr1[2*i+1]) {
Metr[i+param->Nways/2] = Metr1[2*i];
history_new[i+param->Nways/2][0] = 0;
for (j=0; j<MAX_history; ++j) {
history_new[i+param->Nways/2][j+1] = history[2*i][j];
}
} else {
Metr[i+param->Nways/2] = Metr1[2*i+1];
history_new[i+param->Nways/2][0] = 1;
for (j=0; j<MAX_history; ++j) {
history_new[i+param->Nways/2][j+1] = history[2*i+1][j];
}
}
}
for (vote=i=0; i<param->Nways; ++i) {
vote += (history_new[i][MAX_history] == 0);
}
if (vote >= param->Nways/2) {
bit_stream->data[bv++] = 0;
} else {
bit_stream->data[bv++] = 1;
}
for (i=0; i<param->Nways; ++i) {
for (j=0; j<MAX_history; ++j) {
history[i][j] = history_new[i][j];
}
}
if (++i_punct == param->n_in) {
i_punct = 0;
}
}
bit_stream->data = (unsigned char*)realloc(bit_stream->data, bv*sizeof(unsigned char));
bit_stream->length = bv;
memcpy(Metr_mem->data, Metr, Metr_mem->length*sizeof(double));
memcpy(history_mem, history, sizeof(history));
free(Metr);
free(Metr0);
free(Metr1);
}