private int viterbi_set_traceback(viterbi v, int traceback) { if (traceback < 0 || traceback > PATHMEM - 1) return -1; v.traceback = traceback; return 0; }
private int viterbi_set_chunksize(viterbi v, int chunksize) { if (chunksize < 1 || chunksize > v.traceback) return -1; v.chunksize = chunksize; return 0; }
private viterbi viterbi_init(int k, int poly1, int poly2) { viterbi v; int i; v = new viterbi(); v.traceback = PATHMEM - 1; v.chunksize = 8; v.nstates = 1 << (k - 1); v.output = new int[1 << k]; v.metrics = new int[PATHMEM, v.nstates]; v.history = new int[PATHMEM, v.nstates]; v.sequence = new int[PATHMEM]; v.mettab = new int[2, 256]; for (i = 0; i < (1 << k); i++) v.output[i] = parity(poly1 & i) | (parity(poly2 & i) << 1); for (i = 0; i < 256; i++) { v.mettab[0, i] = 128 - i; v.mettab[1, i] = i - 128; } v.ptr = 0; return v; }
private void viterbi_reset(viterbi v) { v.metrics = new int[PATHMEM, v.nstates]; v.history = new int[PATHMEM, v.nstates]; v.ptr = 0; }
private int traceback(viterbi v, int[] metric) { int i, bestmetric, beststate; uint p, c; p = (uint)((v.ptr - 1) % PATHMEM); /* * Find the state with the best metric */ bestmetric = Int32.MinValue; // INT_MIN; beststate = 0; for (i = 0; i < v.nstates; i++) { if (v.metrics[p, i] > bestmetric) { bestmetric = v.metrics[p, i]; beststate = i; } } /* * Trace back 'traceback' steps, starting from the best state */ v.sequence[p] = beststate; for (i = 0; i < v.traceback; i++) { uint prev = (uint)((p - 1) % PATHMEM); v.sequence[prev] = v.history[p, v.sequence[p]]; p = prev; } if (metric != null) metric[0] = v.metrics[p, v.sequence[p]]; /* * Decode 'chunksize' bits */ c = 0; i = 0; for (i = 0; i < v.chunksize; i++) { /* * low bit of state is the previous input bit */ c = (uint)(c << 1); c |= (uint)(v.sequence[p] & 1); p = (uint)((p + 1) % PATHMEM); } if (metric != null) metric[0] = v.metrics[p, v.sequence[p]] - metric[0]; return (int)c; }