17 #ifndef LEANSDR_VITERBI_H 18 #define LEANSDR_VITERBI_H 43 template <
typename TS,
int NSTATES,
typename TUS,
int NUS,
int NCS>
59 for (TS s = 0; s < NSTATES; ++s)
60 for (
int cs = 0; cs < NCS; ++cs)
69 fprintf(stderr,
"NCS must be a power of 2\n");
74 for (TS s = 0; s < NSTATES; ++s)
76 for (TUS
us = 0;
us < NUS; ++
us)
82 for (
int b = 1; b < NUS; b *= 2)
84 us_rev |= (NUS / 2 / b);
85 shiftreg |= us_rev * NSTATES;
87 for (
int g = 0; g < nG; ++g)
88 cs = (cs << 1) |
parity(shiftreg & G[g]);
92 if (b->
pred != NOSTATE)
94 fprintf(stderr,
"Invalid convolutional code\n");
104 for (
int s = 0; s < NSTATES; ++s)
106 fprintf(stderr,
"State %02x:", s);
107 for (
int cs = 0; cs < NCS; ++cs)
110 if (b->
pred == NOSTATE)
111 fprintf(stderr,
" - ");
113 fprintf(stderr,
" %02x+%x", b->
pred, b->
us);
115 fprintf(stderr,
"\n");
121 template <
typename TUS,
127 virtual TUS update(TBM *costs, TPM *quality = NULL) = 0;
128 virtual TUS update(TCS s, TBM cost, TPM *quality = NULL) = 0;
131 template <
typename TS,
int NSTATES,
132 typename TUS,
int NUS,
133 typename TCS,
int NCS,
134 typename TBM,
typename TPM,
152 states = &statebanks[0];
153 newstates = &statebanks[1];
154 for (TS s = 0; s < NSTATES; ++s)
155 (*states)[s].
cost = 0;
157 max_tpm = (TPM)0 - 1;
161 for (max_tpm = 0; max_tpm * 2 + 1 > max_tpm; max_tpm = max_tpm * 2 + 1)
168 TUS
update(TBM costs[NCS], TPM *quality = NULL)
170 TPM best_tpm = max_tpm, best2_tpm = max_tpm;
173 for (
int s = 0; s < NSTATES; ++s)
175 TPM best_m = max_tpm;
178 for (
int cs = 0; cs < NCS; ++cs)
184 TPM m = (*states)[b->
pred].cost + costs[cs];
191 (*newstates)[s].path = (*states)[best_b->
pred].path;
192 (*newstates)[s].path.append(best_b->
us);
193 (*newstates)[s].cost = best_m;
195 if (best_m < best_tpm)
198 best2_tpm = best_tpm;
201 else if (best_m < best2_tpm)
211 for (TS s = 0; s < NSTATES; ++s)
212 (*states)[s].cost -= best_tpm;
215 fprintf(stderr,
"-%2d = [", best_tpm);
216 for ( TS s=0; s<NSTATES; ++s ) fprintf(stderr,
" %d", (*states)[s].cost);
217 fprintf(stderr,
" ]\n");
221 *quality = best2_tpm - best_tpm;
223 return (*states)[best_state].path.read();
230 TUS
update(
int nm, TCS cs[], TBM costs[], TPM *quality = NULL)
232 TPM best_tpm = max_tpm, best2_tpm = max_tpm;
235 for (
int s = 0; s < NSTATES; ++s)
238 TPM best_m = max_tpm;
240 for (
int im = 0; im < nm; ++im)
246 TPM m = (*states)[b->
pred].cost + costs[im];
258 for (
int cs = 0; cs < NCS; ++cs)
264 TPM m = (*states)[b->
pred].cost;
272 (*newstates)[s].path = (*states)[best_b->
pred].path;
273 (*newstates)[s].path.append(best_b->
us);
274 (*newstates)[s].cost = best_m;
276 if (best_m < best_tpm)
279 best2_tpm = best_tpm;
282 else if (best_m < best2_tpm)
292 for (TS s = 0; s < NSTATES; ++s)
293 (*states)[s].cost -= best_tpm;
296 fprintf(stderr,
"-%2d = [", best_tpm);
297 for ( TS s=0; s<NSTATES; ++s ) fprintf(stderr,
" %d", (*states)[s].cost);
298 fprintf(stderr,
" ]\n");
302 *quality = best2_tpm - best_tpm;
304 return (*states)[best_state].path.read();
310 TUS
update(TCS cs, TBM cost, TPM *quality = NULL)
312 return update(1, &cs, &cost, quality);
317 fprintf(stderr,
"[");
318 for (TS s = 0; s < NSTATES; ++s)
320 fprintf(stderr,
" %02x:%d", s, states[s].cost);
321 fprintf(stderr,
"\n");
333 template <
typename T,
typename TUS,
int NBITS,
int DEPTH>
339 TUS
read() {
return (val >> (DEPTH - 1) * NBITS) & ((1 << NBITS) - 1); }
344 #endif // LEANSDR_VITERBI_H
struct leansdr::trellis::state::branch branches[NCS]
viterbi_dec(trellis< TS, NSTATES, TUS, NUS, NCS > *_trellis)
struct leansdr::trellis::state states[NSTATES]
TUS update(TCS cs, TBM cost, TPM *quality=NULL)
trellis< TS, NSTATES, TUS, NUS, NCS > * trell
TUS update(int nm, TCS cs[], TBM costs[], TPM *quality=NULL)
void init_convolutional(const uint16_t G[])
unsigned char parity(uint8_t x)
TUS update(TBM costs[NCS], TPM *quality=NULL)
unsigned __int64 uint64_t