blob: d02e69cb87d05c8b40e1e2f1f72cd83e4e816e52 [file] [log] [blame]
Roman Khassrafd38206c2015-06-07 16:26:29 +02001/*
2* Copyright 2013, 2014 Range Networks, Inc.
3*
4* This software is distributed under multiple licenses;
5* see the COPYING file in the main directory for licensing
6* information for this specific distribution.
7*
8* This use of this software may be subject to additional restrictions.
9* See the LEGAL file in the main directory for details.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
15*/
16
17
18#include "BitVector.h"
19#include "AmrCoder.h"
20#include <iostream>
21#include <stdio.h>
22#include <sstream>
23
24using namespace std;
25
26
27
28ViterbiTCH_AFS12_2::ViterbiTCH_AFS12_2()
29{
30 assert(mDeferral < 32);
31 mCoeffs[0] = 0x019;
32 mCoeffsFB[0] = 0x019;
33 mCoeffs[1] = 0x01b;
34 mCoeffsFB[1] = 0x019;
35 for (unsigned i = 0; i < mIRate; i++) {
36 computeStateTables(i);
37 }
38 computeGeneratorTable();
39}
40
41
42//void BitVector::encode(const ViterbiTCH_AFS12_2& coder, BitVector& target) const
43void ViterbiTCH_AFS12_2::encode(const BitVector& in, BitVector& target) const
44{
45 assert(in.size() == 250);
46 assert(target.size() == 508);
47 const char *u = in.begin();
48 char *C = target.begin();
49 const unsigned H = 4;
50 BitVector r(254+H);
51 for (int k = -H; k <= -1; k++) r[k+H] = 0;
52 for (unsigned k = 0; k <= 249; k++) {
53 r[k+H] = u[k] ^ r[k-3+H] ^ r[k-4+H];
54 C[2*k] = u[k];
55 C[2*k+1] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
56 }
57 // termination
58 for (unsigned k = 250; k <= 253; k++) {
59 r[k+H] = 0;
60 C[2*k] = r[k-3+H] ^ r[k-4+H];
61 C[2*k+1] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
62 }
63}
64
65
66
67//void BitVector::encode(const ViterbiTCH_AFS10_2& coder, BitVector& target)
68void ViterbiTCH_AFS10_2::encode(const BitVector& in, BitVector& target) const
69{
70 assert(in.size() == 210);
71 assert(target.size() == 642);
72 const char *u = in.begin();
73 char *C = target.begin();
74 const unsigned H = 4;
75 BitVector r(214+H);
76 for (int k = -H; k <= -1; k++) r[k+H] = 0;
77 for (unsigned k = 0; k <= 209; k++) {
78 r[k+H] = u[k] ^ r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H];
79 C[3*k] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
80 C[3*k+1] = r[k+H] ^ r[k-2+H] ^ r[k-4+H];
81 C[3*k+2] = u[k];
82 }
83 // termination
84 for (unsigned k = 210; k <= 213; k++) {
85 r[k+H] = 0;
86 C[3*k] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
87 C[3*k+1] = r[k+H] ^ r[k-2+H] ^ r[k-4+H];
88 C[3*k+2] = r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H];
89 }
90}
91
92
93
94//void BitVector::encode(const ViterbiTCH_AFS7_95& coder, BitVector& target)
95void ViterbiTCH_AFS7_95::encode(const BitVector& in, BitVector& target) const
96{
97 assert(in.size() == 165);
98 assert(target.size() == 513);
99 const char *u = in.begin();
100 char *C = target.begin();
101 const unsigned H = 6;
102 BitVector r(171+H);
103 for (int k = -H; k <= -1; k++) r[k+H] = 0;
104 for (unsigned k = 0; k <= 164; k++) {
105 r[k+H] = u[k] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-5+H] ^ r[k-6+H];
106 C[3*k] = u[k];
107 C[3*k+1] = r[k+H] ^ r[k-1+H] ^ r[k-4+H] ^ r[k-6+H];
108 C[3*k+2] = r[k+H] ^ r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H] ^ r[k-6+H];
109 }
110 // termination
111 for (unsigned k = 165; k <= 170; k++) {
112 r[k+H] = 0;
113 C[3*k] = r[k-2+H] ^ r[k-3+H] ^ r[k-5+H] ^ r[k-6+H];
114 C[3*k+1] = r[k+H] ^ r[k-1+H] ^ r[k-4+H] ^ r[k-6+H];
115 C[3*k+2] = r[k+H] ^ r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H] ^ r[k-6+H];
116 }
117}
118
119
120
121void ViterbiTCH_AFS7_4::encode(const BitVector& in, BitVector& target) const
122{
123 assert(in.size() == 154);
124 assert(target.size() == 474);
125 const char *u = in.begin();
126 char *C = target.begin();
127 const unsigned H = 4;
128 BitVector r(158+H);
129 for (int k = -H; k <= -1; k++) r[k+H] = 0;
130 for (unsigned k = 0; k <= 153; k++) {
131 r[k+H] = u[k] ^ r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H];
132 C[3*k] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
133 C[3*k+1] = r[k+H] ^ r[k-2+H] ^ r[k-4+H];
134 C[3*k+2] = u[k];
135 }
136 // termination
137 for (unsigned k = 154; k <= 157; k++) {
138 r[k+H] = 0;
139 C[3*k] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
140 C[3*k+1] = r[k+H] ^ r[k-2+H] ^ r[k-4+H];
141 C[3*k+2] = r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H];
142 }
143}
144
145
146
147void ViterbiTCH_AFS6_7::encode(const BitVector& in, BitVector& target) const
148{
149 assert(in.size() == 140);
150 assert(target.size() == 576);
151 const char *u = in.begin();
152 char *C = target.begin();
153 const unsigned H = 4;
154 BitVector r(144+H);
155 for (int k = -H; k <= -1; k++) r[k+H] = 0;
156 for (unsigned k = 0; k <= 139; k++) {
157 r[k+H] = u[k] ^ r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H];
158 C[4*k] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
159 C[4*k+1] = r[k+H] ^ r[k-2+H] ^ r[k-4+H];
160 C[4*k+2] = u[k];
161 C[4*k+3] = u[k];
162 }
163 // termination
164 for (unsigned k = 140; k <= 143; k++) {
165 r[k+H] = 0;
166 C[4*k] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
167 C[4*k+1] = r[k+H] ^ r[k-2+H] ^ r[k-4+H];
168 C[4*k+2] = r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H];
169 C[4*k+3] = r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H];
170 }
171}
172
173
174
175void ViterbiTCH_AFS5_9::encode(const BitVector& in, BitVector& target) const
176{
177 assert(in.size() == 124);
178 assert(target.size() == 520);
179 const char *u = in.begin();
180 char *C = target.begin();
181 const unsigned H = 6;
182 BitVector r(130+H);
183 for (int k = -H; k <= -1; k++) r[k+H] = 0;
184 for (unsigned k = 0; k <= 123; k++) {
185 r[k+H] = u[k] ^ r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H] ^ r[k-6+H];
186 C[4*k] = r[k+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-5+H] ^ r[k-6+H];
187 C[4*k+1] = r[k+H] ^ r[k-1+H] ^ r[k-4+H] ^ r[k-6+H];
188 C[4*k+2] = u[k];
189 C[4*k+3] = u[k];
190 }
191 // termination
192 for (unsigned k = 124; k <= 129; k++) {
193 r[k+H] = 0;
194 C[4*k] = r[k+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-5+H] ^ r[k-6+H];
195 C[4*k+1] = r[k+H] ^ r[k-1+H] ^ r[k-4+H] ^ r[k-6+H];
196 C[4*k+2] = r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H] ^ r[k-6+H];
197 C[4*k+3] = r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H] ^ r[k-6+H];
198 }
199}
200
201
202
203void ViterbiTCH_AFS5_15::encode(const BitVector& in, BitVector& target) const
204{
205 assert(in.size() == 109);
206 assert(target.size() == 565);
207 const char *u = in.begin();
208 char *C = target.begin();
209 const unsigned H = 4;
210 BitVector r(113+H);
211 for (int k = -H; k <= -1; k++) r[k+H] = 0;
212 for (unsigned k = 0; k <= 108; k++) {
213 r[k+H] = u[k] ^ r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H];
214 C[5*k] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
215 C[5*k+1] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
216 C[5*k+2] = r[k+H] ^ r[k-2+H] ^ r[k-4+H];
217 C[5*k+3] = u[k];
218 C[5*k+4] = u[k];
219 }
220 // termination
221 for (unsigned k = 109; k <= 112; k++) {
222 r[k+H] = 0;
223 C[5*k] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
224 C[5*k+1] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
225 C[5*k+2] = r[k+H] ^ r[k-2+H] ^ r[k-4+H];
226 C[5*k+3] = r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H];
227 C[5*k+4] = r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H];
228 }
229}
230
231
232
233void ViterbiTCH_AFS4_75::encode(const BitVector& in, BitVector& target) const
234{
235 assert(in.size() == 101);
236 assert(target.size() == 535);
237 const char *u = in.begin();
238 char *C = target.begin();
239 const unsigned H = 6;
240 BitVector r(107+H);
241 for (int k = -H; k <= -1; k++) r[k+H] = 0;
242 for (unsigned k = 0; k <= 100; k++) {
243 r[k+H] = u[k] ^ r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H] ^ r[k-6+H];
244 C[5*k] = r[k+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-5+H] ^ r[k-6+H];
245 C[5*k+1] = r[k+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-5+H] ^ r[k-6+H];
246 C[5*k+2] = r[k+H] ^ r[k-1+H] ^ r[k-4+H] ^ r[k-6+H];
247 C[5*k+3] = u[k];
248 C[5*k+4] = u[k];
249 }
250 // termination
251 for (unsigned k = 101; k <= 106; k++) {
252 r[k+H] = 0;
253 C[5*k] = r[k+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-5+H] ^ r[k-6+H];
254 C[5*k+1] = r[k+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-5+H] ^ r[k-6+H];
255 C[5*k+2] = r[k+H] ^ r[k-1+H] ^ r[k-4+H] ^ r[k-6+H];
256 C[5*k+3] = r[k+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H] ^ r[k-6+H];
257 C[5*k+4] = r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H] ^ r[k-6+H];
258 }
259}
260
261
262void ViterbiTCH_AFS12_2::initializeStates()
263{
264 for (unsigned i=0; i<mIStates; i++) vitClear(mSurvivors[i]);
265 for (unsigned i=0; i<mNumCands; i++) vitClear(mCandidates[i]);
266}
267
268
269
270void ViterbiTCH_AFS12_2::computeStateTables(unsigned g)
271{
272 assert(g<mIRate);
273 for (unsigned state=0; state<mIStates; state++) {
274 for (unsigned in = 0; in <= 1; in++) {
275 uint32_t inputVal = (state<<1) | in;
276 mStateTable[g][inputVal] = applyPoly(inputVal, mCoeffs[g] ^ mCoeffsFB[g], mOrder+1) ^ in;
277 }
278 }
279}
280
281void ViterbiTCH_AFS12_2::computeGeneratorTable()
282{
283 for (unsigned index=0; index<mIStates*2; index++) {
284 uint32_t t = 0;
285 for (unsigned i = 0; i < mIRate; i++) {
286 t = (t << 1) | mStateTable[i][index];
287 }
288 mGeneratorTable[index] = t;
289 }
290}
291
292
293
294
295
296
297void ViterbiTCH_AFS12_2::branchCandidates()
298{
299 // Branch to generate new input states.
300 const vCand *sp = mSurvivors;
301 for (unsigned cand=0; cand<mNumCands; cand+=2) {
302 uint32_t oStateShifted = (sp->oState) << mIRate;
303 for (unsigned in = 0; in <= 1; in++) {
304 mCandidates[cand+in].iState = ((sp->iState) << 1) | in;
305 mCandidates[cand+in].cost = sp->cost;
306 uint32_t outputs = oStateShifted;
307 for (unsigned out = 0; out < mIRate; out++) {
308 char feedback = applyPoly(sp->rState[out], mCoeffsFB[out] ^ 1, mOrder+1);
309 char rState = (((sp->rState[out]) ^ feedback) << 1) | in;
310 mCandidates[cand+in].rState[out] = rState;
311 outputs |= (mGeneratorTable[rState & mCMask] & (1 << (mIRate - out - 1)));
312 }
313 mCandidates[cand+in].oState = outputs;
314 }
315 sp++;
316 }
317}
318
319
320void ViterbiTCH_AFS12_2::getSoftCostMetrics(const uint32_t inSample, const float *matchCost, const float *mismatchCost)
321{
322 const float *cTab[2] = {matchCost,mismatchCost};
323 for (unsigned i=0; i<mNumCands; i++) {
324 vCand& thisCand = mCandidates[i];
325 const unsigned mismatched = inSample ^ (thisCand.oState);
326 for (unsigned i = 0; i < mIRate; i++) {
327 thisCand.cost += cTab[(mismatched>>i)&0x01][mIRate-i-1];
328 }
329 }
330}
331
332
333void ViterbiTCH_AFS12_2::pruneCandidates()
334{
335 const vCand* c1 = mCandidates; // 0-prefix
336 const vCand* c2 = mCandidates + mIStates; // 1-prefix
337 for (unsigned i=0; i<mIStates; i++) {
338 if (c1[i].cost < c2[i].cost) mSurvivors[i] = c1[i];
339 else mSurvivors[i] = c2[i];
340 }
341}
342
343
344const ViterbiTCH_AFS12_2::vCand& ViterbiTCH_AFS12_2::minCost() const
345{
346 int minIndex = 0;
347 float minCost = mSurvivors[0].cost;
348 for (unsigned i=1; i<mIStates; i++) {
349 const float thisCost = mSurvivors[i].cost;
350 if (thisCost>=minCost) continue;
351 minCost = thisCost;
352 minIndex=i;
353 }
354 return mSurvivors[minIndex];
355}
356
357
358const ViterbiTCH_AFS12_2::vCand& ViterbiTCH_AFS12_2::step(uint32_t inSample, const float *probs, const float *iprobs)
359{
360 branchCandidates();
361 getSoftCostMetrics(inSample,probs,iprobs);
362 pruneCandidates();
363 return minCost();
364}
365
366
367
368void ViterbiTCH_AFS12_2::decode(const SoftVector &in, BitVector& target)
369{
370 ViterbiTCH_AFS12_2 &decoder = *this;
371 const size_t sz = in.size() - 8;
372 const unsigned deferral = decoder.deferral();
373 const size_t ctsz = sz + deferral*decoder.iRate();
374 assert(sz == decoder.iRate()*target.size());
375
376 // Build a "history" array where each element contains the full history.
377 uint32_t history[ctsz];
378 {
379 BitVector bits = in.sliced();
380 uint32_t accum = 0;
381 for (size_t i=0; i<sz; i++) {
382 accum = (accum<<1) | bits.bit(i);
383 history[i] = accum;
384 }
385 // Repeat last bit at the end.
386 for (size_t i=sz; i<ctsz; i++) {
387 accum = (accum<<1) | (accum & 0x01);
388 history[i] = accum;
389 }
390 }
391
392 // Precompute metric tables.
393 float matchCostTable[ctsz];
394 float mismatchCostTable[ctsz];
395 {
396 const float *dp = in.begin();
397 for (size_t i=0; i<sz; i++) {
398 // pVal is the probability that a bit is correct.
399 // ipVal is the probability that a bit is incorrect.
400 float pVal = dp[i];
401 if (pVal>0.5F) pVal = 1.0F-pVal;
402 float ipVal = 1.0F-pVal;
403 // This is a cheap approximation to an ideal cost function.
404 if (pVal<0.01F) pVal = 0.01;
405 if (ipVal<0.01F) ipVal = 0.01;
406 matchCostTable[i] = 0.25F/ipVal;
407 mismatchCostTable[i] = 0.25F/pVal;
408 }
409
410 // pad end of table with unknowns
411 for (size_t i=sz; i<ctsz; i++) {
412 matchCostTable[i] = 0.5F;
413 mismatchCostTable[i] = 0.5F;
414 }
415 }
416
417 {
418 decoder.initializeStates();
419 // Each sample of history[] carries its history.
420 // So we only have to process every iRate-th sample.
421 const unsigned step = decoder.iRate();
422 // input pointer
423 const uint32_t *ip = history + step - 1;
424 // output pointers
425 char *op = target.begin();
426 const char *const opt = target.end();
427 // table pointers
428 const float* match = matchCostTable;
429 const float* mismatch = mismatchCostTable;
430 size_t oCount = 0;
431 while (op<opt) {
432 // Viterbi algorithm
433 assert(match-matchCostTable<(int)(sizeof(matchCostTable)/sizeof(matchCostTable[0])-1));
434 assert(mismatch-mismatchCostTable<(int)(sizeof(mismatchCostTable)/sizeof(mismatchCostTable[0])-1));
435 const ViterbiTCH_AFS12_2::vCand &minCost = decoder.step(*ip, match, mismatch);
436 ip += step;
437 match += step;
438 mismatch += step;
439 // output
440 if (oCount>=deferral) *op++ = (minCost.iState >> deferral)&0x01;
441 oCount++;
442 }
443 }
444}
445
446
447
448ViterbiTCH_AFS10_2::ViterbiTCH_AFS10_2()
449{
450 assert(mDeferral < 32);
451 mCoeffs[0] = 0x01b;
452 mCoeffsFB[0] = 0x01f;
453 mCoeffs[1] = 0x015;
454 mCoeffsFB[1] = 0x01f;
455 mCoeffs[2] = 0x01f;
456 mCoeffsFB[2] = 0x01f;
457 for (unsigned i = 0; i < mIRate; i++) {
458 computeStateTables(i);
459 }
460 computeGeneratorTable();
461}
462
463
464
465
466void ViterbiTCH_AFS10_2::initializeStates()
467{
468 for (unsigned i=0; i<mIStates; i++) vitClear(mSurvivors[i]);
469 for (unsigned i=0; i<mNumCands; i++) vitClear(mCandidates[i]);
470}
471
472
473
474void ViterbiTCH_AFS10_2::computeStateTables(unsigned g)
475{
476 assert(g<mIRate);
477 for (unsigned state=0; state<mIStates; state++) {
478 for (unsigned in = 0; in <= 1; in++) {
479 uint32_t inputVal = (state<<1) | in;
480 mStateTable[g][inputVal] = applyPoly(inputVal, mCoeffs[g] ^ mCoeffsFB[g], mOrder+1) ^ in;
481 }
482 }
483}
484
485void ViterbiTCH_AFS10_2::computeGeneratorTable()
486{
487 for (unsigned index=0; index<mIStates*2; index++) {
488 uint32_t t = 0;
489 for (unsigned i = 0; i < mIRate; i++) {
490 t = (t << 1) | mStateTable[i][index];
491 }
492 mGeneratorTable[index] = t;
493 }
494}
495
496
497
498
499
500
501void ViterbiTCH_AFS10_2::branchCandidates()
502{
503 // Branch to generate new input states.
504 const vCand *sp = mSurvivors;
505 for (unsigned cand=0; cand<mNumCands; cand+=2) {
506 uint32_t oStateShifted = (sp->oState) << mIRate;
507 for (unsigned in = 0; in <= 1; in++) {
508 mCandidates[cand+in].iState = ((sp->iState) << 1) | in;
509 mCandidates[cand+in].cost = sp->cost;
510 uint32_t outputs = oStateShifted;
511 for (unsigned out = 0; out < mIRate; out++) {
512 char feedback = applyPoly(sp->rState[out], mCoeffsFB[out] ^ 1, mOrder+1);
513 char rState = (((sp->rState[out]) ^ feedback) << 1) | in;
514 mCandidates[cand+in].rState[out] = rState;
515 outputs |= (mGeneratorTable[rState & mCMask] & (1 << (mIRate - out - 1)));
516 }
517 mCandidates[cand+in].oState = outputs;
518 }
519 sp++;
520 }
521}
522
523
524void ViterbiTCH_AFS10_2::getSoftCostMetrics(const uint32_t inSample, const float *matchCost, const float *mismatchCost)
525{
526 const float *cTab[2] = {matchCost,mismatchCost};
527 for (unsigned i=0; i<mNumCands; i++) {
528 vCand& thisCand = mCandidates[i];
529 const unsigned mismatched = inSample ^ (thisCand.oState);
530 for (unsigned i = 0; i < mIRate; i++) {
531 thisCand.cost += cTab[(mismatched>>i)&0x01][mIRate-i-1];
532 }
533 }
534}
535
536
537void ViterbiTCH_AFS10_2::pruneCandidates()
538{
539 const vCand* c1 = mCandidates; // 0-prefix
540 const vCand* c2 = mCandidates + mIStates; // 1-prefix
541 for (unsigned i=0; i<mIStates; i++) {
542 if (c1[i].cost < c2[i].cost) mSurvivors[i] = c1[i];
543 else mSurvivors[i] = c2[i];
544 }
545}
546
547
548const ViterbiTCH_AFS10_2::vCand& ViterbiTCH_AFS10_2::minCost() const
549{
550 int minIndex = 0;
551 float minCost = mSurvivors[0].cost;
552 for (unsigned i=1; i<mIStates; i++) {
553 const float thisCost = mSurvivors[i].cost;
554 if (thisCost>=minCost) continue;
555 minCost = thisCost;
556 minIndex=i;
557 }
558 return mSurvivors[minIndex];
559}
560
561
562const ViterbiTCH_AFS10_2::vCand& ViterbiTCH_AFS10_2::step(uint32_t inSample, const float *probs, const float *iprobs)
563{
564 branchCandidates();
565 getSoftCostMetrics(inSample,probs,iprobs);
566 pruneCandidates();
567 return minCost();
568}
569
570
571
572void ViterbiTCH_AFS10_2::decode(const SoftVector &in, BitVector& target)
573{
574 ViterbiTCH_AFS10_2 &decoder = *this;
575 const size_t sz = in.size() - 12;
576 const unsigned deferral = decoder.deferral();
577 const size_t ctsz = sz + deferral*decoder.iRate();
578 assert(sz == decoder.iRate()*target.size());
579
580 // Build a "history" array where each element contains the full history.
581 uint32_t history[ctsz];
582 {
583 BitVector bits = in.sliced();
584 uint32_t accum = 0;
585 for (size_t i=0; i<sz; i++) {
586 accum = (accum<<1) | bits.bit(i);
587 history[i] = accum;
588 }
589 // Repeat last bit at the end.
590 for (size_t i=sz; i<ctsz; i++) {
591 accum = (accum<<1) | (accum & 0x01);
592 history[i] = accum;
593 }
594 }
595
596 // Precompute metric tables.
597 float matchCostTable[ctsz];
598 float mismatchCostTable[ctsz];
599 {
600 const float *dp = in.begin();
601 for (size_t i=0; i<sz; i++) {
602 // pVal is the probability that a bit is correct.
603 // ipVal is the probability that a bit is incorrect.
604 float pVal = dp[i];
605 if (pVal>0.5F) pVal = 1.0F-pVal;
606 float ipVal = 1.0F-pVal;
607 // This is a cheap approximation to an ideal cost function.
608 if (pVal<0.01F) pVal = 0.01;
609 if (ipVal<0.01F) ipVal = 0.01;
610 matchCostTable[i] = 0.25F/ipVal;
611 mismatchCostTable[i] = 0.25F/pVal;
612 }
613
614 // pad end of table with unknowns
615 for (size_t i=sz; i<ctsz; i++) {
616 matchCostTable[i] = 0.5F;
617 mismatchCostTable[i] = 0.5F;
618 }
619 }
620
621 {
622 decoder.initializeStates();
623 // Each sample of history[] carries its history.
624 // So we only have to process every iRate-th sample.
625 const unsigned step = decoder.iRate();
626 // input pointer
627 const uint32_t *ip = history + step - 1;
628 // output pointers
629 char *op = target.begin();
630 const char *const opt = target.end();
631 // table pointers
632 const float* match = matchCostTable;
633 const float* mismatch = mismatchCostTable;
634 size_t oCount = 0;
635 while (op<opt) {
636 // Viterbi algorithm
637 assert(match-matchCostTable<(int)(sizeof(matchCostTable)/sizeof(matchCostTable[0])-1));
638 assert(mismatch-mismatchCostTable<(int)(sizeof(mismatchCostTable)/sizeof(mismatchCostTable[0])-1));
639 const ViterbiTCH_AFS10_2::vCand &minCost = decoder.step(*ip, match, mismatch);
640 ip += step;
641 match += step;
642 mismatch += step;
643 // output
644 if (oCount>=deferral) *op++ = (minCost.iState >> deferral)&0x01;
645 oCount++;
646 }
647 }
648}
649
650
651
652ViterbiTCH_AFS7_95::ViterbiTCH_AFS7_95()
653{
654 assert(mDeferral < 32);
655 mCoeffs[0] = 0x06d;
656 mCoeffsFB[0] = 0x06d;
657 mCoeffs[1] = 0x053;
658 mCoeffsFB[1] = 0x06d;
659 mCoeffs[2] = 0x05f;
660 mCoeffsFB[2] = 0x06d;
661 for (unsigned i = 0; i < mIRate; i++) {
662 computeStateTables(i);
663 }
664 computeGeneratorTable();
665}
666
667
668
669
670void ViterbiTCH_AFS7_95::initializeStates()
671{
672 for (unsigned i=0; i<mIStates; i++) vitClear(mSurvivors[i]);
673 for (unsigned i=0; i<mNumCands; i++) vitClear(mCandidates[i]);
674}
675
676
677
678void ViterbiTCH_AFS7_95::computeStateTables(unsigned g)
679{
680 assert(g<mIRate);
681 for (unsigned state=0; state<mIStates; state++) {
682 for (unsigned in = 0; in <= 1; in++) {
683 uint32_t inputVal = (state<<1) | in;
684 mStateTable[g][inputVal] = applyPoly(inputVal, mCoeffs[g] ^ mCoeffsFB[g], mOrder+1) ^ in;
685 }
686 }
687}
688
689void ViterbiTCH_AFS7_95::computeGeneratorTable()
690{
691 for (unsigned index=0; index<mIStates*2; index++) {
692 uint32_t t = 0;
693 for (unsigned i = 0; i < mIRate; i++) {
694 t = (t << 1) | mStateTable[i][index];
695 }
696 mGeneratorTable[index] = t;
697 }
698}
699
700
701
702
703
704
705void ViterbiTCH_AFS7_95::branchCandidates()
706{
707 // Branch to generate new input states.
708 const vCand *sp = mSurvivors;
709 for (unsigned cand=0; cand<mNumCands; cand+=2) {
710 uint32_t oStateShifted = (sp->oState) << mIRate;
711 for (unsigned in = 0; in <= 1; in++) {
712 mCandidates[cand+in].iState = ((sp->iState) << 1) | in;
713 mCandidates[cand+in].cost = sp->cost;
714 uint32_t outputs = oStateShifted;
715 for (unsigned out = 0; out < mIRate; out++) {
716 char feedback = applyPoly(sp->rState[out], mCoeffsFB[out] ^ 1, mOrder+1);
717 char rState = (((sp->rState[out]) ^ feedback) << 1) | in;
718 mCandidates[cand+in].rState[out] = rState;
719 outputs |= (mGeneratorTable[rState & mCMask] & (1 << (mIRate - out - 1)));
720 }
721 mCandidates[cand+in].oState = outputs;
722 }
723 sp++;
724 }
725}
726
727
728void ViterbiTCH_AFS7_95::getSoftCostMetrics(const uint32_t inSample, const float *matchCost, const float *mismatchCost)
729{
730 const float *cTab[2] = {matchCost,mismatchCost};
731 for (unsigned i=0; i<mNumCands; i++) {
732 vCand& thisCand = mCandidates[i];
733 const unsigned mismatched = inSample ^ (thisCand.oState);
734 for (unsigned i = 0; i < mIRate; i++) {
735 thisCand.cost += cTab[(mismatched>>i)&0x01][mIRate-i-1];
736 }
737 }
738}
739
740
741void ViterbiTCH_AFS7_95::pruneCandidates()
742{
743 const vCand* c1 = mCandidates; // 0-prefix
744 const vCand* c2 = mCandidates + mIStates; // 1-prefix
745 for (unsigned i=0; i<mIStates; i++) {
746 if (c1[i].cost < c2[i].cost) mSurvivors[i] = c1[i];
747 else mSurvivors[i] = c2[i];
748 }
749}
750
751
752const ViterbiTCH_AFS7_95::vCand& ViterbiTCH_AFS7_95::minCost() const
753{
754 int minIndex = 0;
755 float minCost = mSurvivors[0].cost;
756 for (unsigned i=1; i<mIStates; i++) {
757 const float thisCost = mSurvivors[i].cost;
758 if (thisCost>=minCost) continue;
759 minCost = thisCost;
760 minIndex=i;
761 }
762 return mSurvivors[minIndex];
763}
764
765
766const ViterbiTCH_AFS7_95::vCand& ViterbiTCH_AFS7_95::step(uint32_t inSample, const float *probs, const float *iprobs)
767{
768 branchCandidates();
769 getSoftCostMetrics(inSample,probs,iprobs);
770 pruneCandidates();
771 return minCost();
772}
773
774
775
776void ViterbiTCH_AFS7_95::decode(const SoftVector &in, BitVector& target)
777{
778 ViterbiTCH_AFS7_95 &decoder = *this;
779 const size_t sz = in.size() - 18;
780 const unsigned deferral = decoder.deferral();
781 const size_t ctsz = sz + deferral*decoder.iRate();
782 assert(sz == decoder.iRate()*target.size());
783
784 // Build a "history" array where each element contains the full history.
785 uint32_t history[ctsz];
786 {
787 BitVector bits = in.sliced();
788 uint32_t accum = 0;
789 for (size_t i=0; i<sz; i++) {
790 accum = (accum<<1) | bits.bit(i);
791 history[i] = accum;
792 }
793 // Repeat last bit at the end.
794 for (size_t i=sz; i<ctsz; i++) {
795 accum = (accum<<1) | (accum & 0x01);
796 history[i] = accum;
797 }
798 }
799
800 // Precompute metric tables.
801 float matchCostTable[ctsz];
802 float mismatchCostTable[ctsz];
803 {
804 const float *dp = in.begin();
805 for (size_t i=0; i<sz; i++) {
806 // pVal is the probability that a bit is correct.
807 // ipVal is the probability that a bit is incorrect.
808 float pVal = dp[i];
809 if (pVal>0.5F) pVal = 1.0F-pVal;
810 float ipVal = 1.0F-pVal;
811 // This is a cheap approximation to an ideal cost function.
812 if (pVal<0.01F) pVal = 0.01;
813 if (ipVal<0.01F) ipVal = 0.01;
814 matchCostTable[i] = 0.25F/ipVal;
815 mismatchCostTable[i] = 0.25F/pVal;
816 }
817
818 // pad end of table with unknowns
819 for (size_t i=sz; i<ctsz; i++) {
820 matchCostTable[i] = 0.5F;
821 mismatchCostTable[i] = 0.5F;
822 }
823 }
824
825 {
826 decoder.initializeStates();
827 // Each sample of history[] carries its history.
828 // So we only have to process every iRate-th sample.
829 const unsigned step = decoder.iRate();
830 // input pointer
831 const uint32_t *ip = history + step - 1;
832 // output pointers
833 char *op = target.begin();
834 const char *const opt = target.end();
835 // table pointers
836 const float* match = matchCostTable;
837 const float* mismatch = mismatchCostTable;
838 size_t oCount = 0;
839 while (op<opt) {
840 // Viterbi algorithm
841 assert(match-matchCostTable<(int)(sizeof(matchCostTable)/sizeof(matchCostTable[0])-1));
842 assert(mismatch-mismatchCostTable<(int)(sizeof(mismatchCostTable)/sizeof(mismatchCostTable[0])-1));
843 const ViterbiTCH_AFS7_95::vCand &minCost = decoder.step(*ip, match, mismatch);
844 ip += step;
845 match += step;
846 mismatch += step;
847 // output
848 if (oCount>=deferral) *op++ = (minCost.iState >> deferral)&0x01;
849 oCount++;
850 }
851 }
852}
853
854
855
856ViterbiTCH_AFS7_4::ViterbiTCH_AFS7_4()
857{
858 assert(mDeferral < 32);
859 mCoeffs[0] = 0x01b;
860 mCoeffsFB[0] = 0x01f;
861 mCoeffs[1] = 0x015;
862 mCoeffsFB[1] = 0x01f;
863 mCoeffs[2] = 0x01f;
864 mCoeffsFB[2] = 0x01f;
865 for (unsigned i = 0; i < mIRate; i++) {
866 computeStateTables(i);
867 }
868 computeGeneratorTable();
869}
870
871
872
873
874void ViterbiTCH_AFS7_4::initializeStates()
875{
876 for (unsigned i=0; i<mIStates; i++) vitClear(mSurvivors[i]);
877 for (unsigned i=0; i<mNumCands; i++) vitClear(mCandidates[i]);
878}
879
880
881
882void ViterbiTCH_AFS7_4::computeStateTables(unsigned g)
883{
884 assert(g<mIRate);
885 for (unsigned state=0; state<mIStates; state++) {
886 for (unsigned in = 0; in <= 1; in++) {
887 uint32_t inputVal = (state<<1) | in;
888 mStateTable[g][inputVal] = applyPoly(inputVal, mCoeffs[g] ^ mCoeffsFB[g], mOrder+1) ^ in;
889 }
890 }
891}
892
893void ViterbiTCH_AFS7_4::computeGeneratorTable()
894{
895 for (unsigned index=0; index<mIStates*2; index++) {
896 uint32_t t = 0;
897 for (unsigned i = 0; i < mIRate; i++) {
898 t = (t << 1) | mStateTable[i][index];
899 }
900 mGeneratorTable[index] = t;
901 }
902}
903
904
905
906
907
908
909void ViterbiTCH_AFS7_4::branchCandidates()
910{
911 // Branch to generate new input states.
912 const vCand *sp = mSurvivors;
913 for (unsigned cand=0; cand<mNumCands; cand+=2) {
914 uint32_t oStateShifted = (sp->oState) << mIRate;
915 for (unsigned in = 0; in <= 1; in++) {
916 mCandidates[cand+in].iState = ((sp->iState) << 1) | in;
917 mCandidates[cand+in].cost = sp->cost;
918 uint32_t outputs = oStateShifted;
919 for (unsigned out = 0; out < mIRate; out++) {
920 char feedback = applyPoly(sp->rState[out], mCoeffsFB[out] ^ 1, mOrder+1);
921 char rState = (((sp->rState[out]) ^ feedback) << 1) | in;
922 mCandidates[cand+in].rState[out] = rState;
923 outputs |= (mGeneratorTable[rState & mCMask] & (1 << (mIRate - out - 1)));
924 }
925 mCandidates[cand+in].oState = outputs;
926 }
927 sp++;
928 }
929}
930
931
932void ViterbiTCH_AFS7_4::getSoftCostMetrics(const uint32_t inSample, const float *matchCost, const float *mismatchCost)
933{
934 const float *cTab[2] = {matchCost,mismatchCost};
935 for (unsigned i=0; i<mNumCands; i++) {
936 vCand& thisCand = mCandidates[i];
937 const unsigned mismatched = inSample ^ (thisCand.oState);
938 for (unsigned i = 0; i < mIRate; i++) {
939 thisCand.cost += cTab[(mismatched>>i)&0x01][mIRate-i-1];
940 }
941 }
942}
943
944
945void ViterbiTCH_AFS7_4::pruneCandidates()
946{
947 const vCand* c1 = mCandidates; // 0-prefix
948 const vCand* c2 = mCandidates + mIStates; // 1-prefix
949 for (unsigned i=0; i<mIStates; i++) {
950 if (c1[i].cost < c2[i].cost) mSurvivors[i] = c1[i];
951 else mSurvivors[i] = c2[i];
952 }
953}
954
955
956const ViterbiTCH_AFS7_4::vCand& ViterbiTCH_AFS7_4::minCost() const
957{
958 int minIndex = 0;
959 float minCost = mSurvivors[0].cost;
960 for (unsigned i=1; i<mIStates; i++) {
961 const float thisCost = mSurvivors[i].cost;
962 if (thisCost>=minCost) continue;
963 minCost = thisCost;
964 minIndex=i;
965 }
966 return mSurvivors[minIndex];
967}
968
969
970const ViterbiTCH_AFS7_4::vCand& ViterbiTCH_AFS7_4::step(uint32_t inSample, const float *probs, const float *iprobs)
971{
972 branchCandidates();
973 getSoftCostMetrics(inSample,probs,iprobs);
974 pruneCandidates();
975 return minCost();
976}
977
978
979
980void ViterbiTCH_AFS7_4::decode(const SoftVector &in, BitVector& target)
981{
982 ViterbiTCH_AFS7_4 &decoder = *this;
983 const size_t sz = in.size() - 12;
984 const unsigned deferral = decoder.deferral();
985 const size_t ctsz = sz + deferral*decoder.iRate();
986 assert(sz == decoder.iRate()*target.size());
987
988 // Build a "history" array where each element contains the full history.
989 uint32_t history[ctsz];
990 {
991 BitVector bits = in.sliced();
992 uint32_t accum = 0;
993 for (size_t i=0; i<sz; i++) {
994 accum = (accum<<1) | bits.bit(i);
995 history[i] = accum;
996 }
997 // Repeat last bit at the end.
998 for (size_t i=sz; i<ctsz; i++) {
999 accum = (accum<<1) | (accum & 0x01);
1000 history[i] = accum;
1001 }
1002 }
1003
1004 // Precompute metric tables.
1005 float matchCostTable[ctsz];
1006 float mismatchCostTable[ctsz];
1007 {
1008 const float *dp = in.begin();
1009 for (size_t i=0; i<sz; i++) {
1010 // pVal is the probability that a bit is correct.
1011 // ipVal is the probability that a bit is incorrect.
1012 float pVal = dp[i];
1013 if (pVal>0.5F) pVal = 1.0F-pVal;
1014 float ipVal = 1.0F-pVal;
1015 // This is a cheap approximation to an ideal cost function.
1016 if (pVal<0.01F) pVal = 0.01;
1017 if (ipVal<0.01F) ipVal = 0.01;
1018 matchCostTable[i] = 0.25F/ipVal;
1019 mismatchCostTable[i] = 0.25F/pVal;
1020 }
1021
1022 // pad end of table with unknowns
1023 for (size_t i=sz; i<ctsz; i++) {
1024 matchCostTable[i] = 0.5F;
1025 mismatchCostTable[i] = 0.5F;
1026 }
1027 }
1028
1029 {
1030 decoder.initializeStates();
1031 // Each sample of history[] carries its history.
1032 // So we only have to process every iRate-th sample.
1033 const unsigned step = decoder.iRate();
1034 // input pointer
1035 const uint32_t *ip = history + step - 1;
1036 // output pointers
1037 char *op = target.begin();
1038 const char *const opt = target.end();
1039 // table pointers
1040 const float* match = matchCostTable;
1041 const float* mismatch = mismatchCostTable;
1042 size_t oCount = 0;
1043 while (op<opt) {
1044 // Viterbi algorithm
1045 assert(match-matchCostTable<(int)(sizeof(matchCostTable)/sizeof(matchCostTable[0])-1));
1046 assert(mismatch-mismatchCostTable<(int)(sizeof(mismatchCostTable)/sizeof(mismatchCostTable[0])-1));
1047 const ViterbiTCH_AFS7_4::vCand &minCost = decoder.step(*ip, match, mismatch);
1048 ip += step;
1049 match += step;
1050 mismatch += step;
1051 // output
1052 if (oCount>=deferral) *op++ = (minCost.iState >> deferral)&0x01;
1053 oCount++;
1054 }
1055 }
1056}
1057
1058
1059
1060ViterbiTCH_AFS6_7::ViterbiTCH_AFS6_7()
1061{
1062 assert(mDeferral < 32);
1063 mCoeffs[0] = 0x01b;
1064 mCoeffsFB[0] = 0x01f;
1065 mCoeffs[1] = 0x015;
1066 mCoeffsFB[1] = 0x01f;
1067 mCoeffs[2] = 0x01f;
1068 mCoeffsFB[2] = 0x01f;
1069 mCoeffs[3] = 0x01f;
1070 mCoeffsFB[3] = 0x01f;
1071 for (unsigned i = 0; i < mIRate; i++) {
1072 computeStateTables(i);
1073 }
1074 computeGeneratorTable();
1075}
1076
1077
1078
1079
1080void ViterbiTCH_AFS6_7::initializeStates()
1081{
1082 for (unsigned i=0; i<mIStates; i++) vitClear(mSurvivors[i]);
1083 for (unsigned i=0; i<mNumCands; i++) vitClear(mCandidates[i]);
1084}
1085
1086
1087
1088void ViterbiTCH_AFS6_7::computeStateTables(unsigned g)
1089{
1090 assert(g<mIRate);
1091 for (unsigned state=0; state<mIStates; state++) {
1092 for (unsigned in = 0; in <= 1; in++) {
1093 uint32_t inputVal = (state<<1) | in;
1094 mStateTable[g][inputVal] = applyPoly(inputVal, mCoeffs[g] ^ mCoeffsFB[g], mOrder+1) ^ in;
1095 }
1096 }
1097}
1098
1099void ViterbiTCH_AFS6_7::computeGeneratorTable()
1100{
1101 for (unsigned index=0; index<mIStates*2; index++) {
1102 uint32_t t = 0;
1103 for (unsigned i = 0; i < mIRate; i++) {
1104 t = (t << 1) | mStateTable[i][index];
1105 }
1106 mGeneratorTable[index] = t;
1107 }
1108}
1109
1110
1111
1112
1113
1114
1115void ViterbiTCH_AFS6_7::branchCandidates()
1116{
1117 // Branch to generate new input states.
1118 const vCand *sp = mSurvivors;
1119 for (unsigned cand=0; cand<mNumCands; cand+=2) {
1120 uint32_t oStateShifted = (sp->oState) << mIRate;
1121 for (unsigned in = 0; in <= 1; in++) {
1122 mCandidates[cand+in].iState = ((sp->iState) << 1) | in;
1123 mCandidates[cand+in].cost = sp->cost;
1124 uint32_t outputs = oStateShifted;
1125 for (unsigned out = 0; out < mIRate; out++) {
1126 char feedback = applyPoly(sp->rState[out], mCoeffsFB[out] ^ 1, mOrder+1);
1127 char rState = (((sp->rState[out]) ^ feedback) << 1) | in;
1128 mCandidates[cand+in].rState[out] = rState;
1129 outputs |= (mGeneratorTable[rState & mCMask] & (1 << (mIRate - out - 1)));
1130 }
1131 mCandidates[cand+in].oState = outputs;
1132 }
1133 sp++;
1134 }
1135}
1136
1137
1138void ViterbiTCH_AFS6_7::getSoftCostMetrics(const uint32_t inSample, const float *matchCost, const float *mismatchCost)
1139{
1140 const float *cTab[2] = {matchCost,mismatchCost};
1141 for (unsigned i=0; i<mNumCands; i++) {
1142 vCand& thisCand = mCandidates[i];
1143 const unsigned mismatched = inSample ^ (thisCand.oState);
1144 for (unsigned i = 0; i < mIRate; i++) {
1145 thisCand.cost += cTab[(mismatched>>i)&0x01][mIRate-i-1];
1146 }
1147 }
1148}
1149
1150
1151void ViterbiTCH_AFS6_7::pruneCandidates()
1152{
1153 const vCand* c1 = mCandidates; // 0-prefix
1154 const vCand* c2 = mCandidates + mIStates; // 1-prefix
1155 for (unsigned i=0; i<mIStates; i++) {
1156 if (c1[i].cost < c2[i].cost) mSurvivors[i] = c1[i];
1157 else mSurvivors[i] = c2[i];
1158 }
1159}
1160
1161
1162const ViterbiTCH_AFS6_7::vCand& ViterbiTCH_AFS6_7::minCost() const
1163{
1164 int minIndex = 0;
1165 float minCost = mSurvivors[0].cost;
1166 for (unsigned i=1; i<mIStates; i++) {
1167 const float thisCost = mSurvivors[i].cost;
1168 if (thisCost>=minCost) continue;
1169 minCost = thisCost;
1170 minIndex=i;
1171 }
1172 return mSurvivors[minIndex];
1173}
1174
1175
1176const ViterbiTCH_AFS6_7::vCand& ViterbiTCH_AFS6_7::step(uint32_t inSample, const float *probs, const float *iprobs)
1177{
1178 branchCandidates();
1179 getSoftCostMetrics(inSample,probs,iprobs);
1180 pruneCandidates();
1181 return minCost();
1182}
1183
1184
1185
1186void ViterbiTCH_AFS6_7::decode(const SoftVector &in, BitVector& target)
1187{
1188 ViterbiTCH_AFS6_7 &decoder = *this;
1189 const size_t sz = in.size() - 16;
1190 const unsigned deferral = decoder.deferral();
1191 const size_t ctsz = sz + deferral*decoder.iRate();
1192 assert(sz == decoder.iRate()*target.size());
1193
1194 // Build a "history" array where each element contains the full history.
1195 uint32_t history[ctsz];
1196 {
1197 BitVector bits = in.sliced();
1198 uint32_t accum = 0;
1199 for (size_t i=0; i<sz; i++) {
1200 accum = (accum<<1) | bits.bit(i);
1201 history[i] = accum;
1202 }
1203 // Repeat last bit at the end.
1204 for (size_t i=sz; i<ctsz; i++) {
1205 accum = (accum<<1) | (accum & 0x01);
1206 history[i] = accum;
1207 }
1208 }
1209
1210 // Precompute metric tables.
1211 float matchCostTable[ctsz];
1212 float mismatchCostTable[ctsz];
1213 {
1214 const float *dp = in.begin();
1215 for (size_t i=0; i<sz; i++) {
1216 // pVal is the probability that a bit is correct.
1217 // ipVal is the probability that a bit is incorrect.
1218 float pVal = dp[i];
1219 if (pVal>0.5F) pVal = 1.0F-pVal;
1220 float ipVal = 1.0F-pVal;
1221 // This is a cheap approximation to an ideal cost function.
1222 if (pVal<0.01F) pVal = 0.01;
1223 if (ipVal<0.01F) ipVal = 0.01;
1224 matchCostTable[i] = 0.25F/ipVal;
1225 mismatchCostTable[i] = 0.25F/pVal;
1226 }
1227
1228 // pad end of table with unknowns
1229 for (size_t i=sz; i<ctsz; i++) {
1230 matchCostTable[i] = 0.5F;
1231 mismatchCostTable[i] = 0.5F;
1232 }
1233 }
1234
1235 {
1236 decoder.initializeStates();
1237 // Each sample of history[] carries its history.
1238 // So we only have to process every iRate-th sample.
1239 const unsigned step = decoder.iRate();
1240 // input pointer
1241 const uint32_t *ip = history + step - 1;
1242 // output pointers
1243 char *op = target.begin();
1244 const char *const opt = target.end();
1245 // table pointers
1246 const float* match = matchCostTable;
1247 const float* mismatch = mismatchCostTable;
1248 size_t oCount = 0;
1249 while (op<opt) {
1250 // Viterbi algorithm
1251 assert(match-matchCostTable<(int)(sizeof(matchCostTable)/sizeof(matchCostTable[0])-1));
1252 assert(mismatch-mismatchCostTable<(int)(sizeof(mismatchCostTable)/sizeof(mismatchCostTable[0])-1));
1253 const ViterbiTCH_AFS6_7::vCand &minCost = decoder.step(*ip, match, mismatch);
1254 ip += step;
1255 match += step;
1256 mismatch += step;
1257 // output
1258 if (oCount>=deferral) *op++ = (minCost.iState >> deferral)&0x01;
1259 oCount++;
1260 }
1261 }
1262}
1263
1264
1265
1266ViterbiTCH_AFS5_9::ViterbiTCH_AFS5_9()
1267{
1268 assert(mDeferral < 32);
1269 mCoeffs[0] = 0x06d;
1270 mCoeffsFB[0] = 0x05f;
1271 mCoeffs[1] = 0x053;
1272 mCoeffsFB[1] = 0x05f;
1273 mCoeffs[2] = 0x05f;
1274 mCoeffsFB[2] = 0x05f;
1275 mCoeffs[3] = 0x05f;
1276 mCoeffsFB[3] = 0x05f;
1277 for (unsigned i = 0; i < mIRate; i++) {
1278 computeStateTables(i);
1279 }
1280 computeGeneratorTable();
1281}
1282
1283
1284
1285
1286void ViterbiTCH_AFS5_9::initializeStates()
1287{
1288 for (unsigned i=0; i<mIStates; i++) vitClear(mSurvivors[i]);
1289 for (unsigned i=0; i<mNumCands; i++) vitClear(mCandidates[i]);
1290}
1291
1292
1293
1294void ViterbiTCH_AFS5_9::computeStateTables(unsigned g)
1295{
1296 assert(g<mIRate);
1297 for (unsigned state=0; state<mIStates; state++) {
1298 for (unsigned in = 0; in <= 1; in++) {
1299 uint32_t inputVal = (state<<1) | in;
1300 mStateTable[g][inputVal] = applyPoly(inputVal, mCoeffs[g] ^ mCoeffsFB[g], mOrder+1) ^ in;
1301 }
1302 }
1303}
1304
1305void ViterbiTCH_AFS5_9::computeGeneratorTable()
1306{
1307 for (unsigned index=0; index<mIStates*2; index++) {
1308 uint32_t t = 0;
1309 for (unsigned i = 0; i < mIRate; i++) {
1310 t = (t << 1) | mStateTable[i][index];
1311 }
1312 mGeneratorTable[index] = t;
1313 }
1314}
1315
1316
1317
1318
1319
1320
1321void ViterbiTCH_AFS5_9::branchCandidates()
1322{
1323 // Branch to generate new input states.
1324 const vCand *sp = mSurvivors;
1325 for (unsigned cand=0; cand<mNumCands; cand+=2) {
1326 uint32_t oStateShifted = (sp->oState) << mIRate;
1327 for (unsigned in = 0; in <= 1; in++) {
1328 mCandidates[cand+in].iState = ((sp->iState) << 1) | in;
1329 mCandidates[cand+in].cost = sp->cost;
1330 uint32_t outputs = oStateShifted;
1331 for (unsigned out = 0; out < mIRate; out++) {
1332 char feedback = applyPoly(sp->rState[out], mCoeffsFB[out] ^ 1, mOrder+1);
1333 char rState = (((sp->rState[out]) ^ feedback) << 1) | in;
1334 mCandidates[cand+in].rState[out] = rState;
1335 outputs |= (mGeneratorTable[rState & mCMask] & (1 << (mIRate - out - 1)));
1336 }
1337 mCandidates[cand+in].oState = outputs;
1338 }
1339 sp++;
1340 }
1341}
1342
1343
1344void ViterbiTCH_AFS5_9::getSoftCostMetrics(const uint32_t inSample, const float *matchCost, const float *mismatchCost)
1345{
1346 const float *cTab[2] = {matchCost,mismatchCost};
1347 for (unsigned i=0; i<mNumCands; i++) {
1348 vCand& thisCand = mCandidates[i];
1349 const unsigned mismatched = inSample ^ (thisCand.oState);
1350 for (unsigned i = 0; i < mIRate; i++) {
1351 thisCand.cost += cTab[(mismatched>>i)&0x01][mIRate-i-1];
1352 }
1353 }
1354}
1355
1356
1357void ViterbiTCH_AFS5_9::pruneCandidates()
1358{
1359 const vCand* c1 = mCandidates; // 0-prefix
1360 const vCand* c2 = mCandidates + mIStates; // 1-prefix
1361 for (unsigned i=0; i<mIStates; i++) {
1362 if (c1[i].cost < c2[i].cost) mSurvivors[i] = c1[i];
1363 else mSurvivors[i] = c2[i];
1364 }
1365}
1366
1367
1368const ViterbiTCH_AFS5_9::vCand& ViterbiTCH_AFS5_9::minCost() const
1369{
1370 int minIndex = 0;
1371 float minCost = mSurvivors[0].cost;
1372 for (unsigned i=1; i<mIStates; i++) {
1373 const float thisCost = mSurvivors[i].cost;
1374 if (thisCost>=minCost) continue;
1375 minCost = thisCost;
1376 minIndex=i;
1377 }
1378 return mSurvivors[minIndex];
1379}
1380
1381
1382const ViterbiTCH_AFS5_9::vCand& ViterbiTCH_AFS5_9::step(uint32_t inSample, const float *probs, const float *iprobs)
1383{
1384 branchCandidates();
1385 getSoftCostMetrics(inSample,probs,iprobs);
1386 pruneCandidates();
1387 return minCost();
1388}
1389
1390
1391
1392void ViterbiTCH_AFS5_9::decode(const SoftVector &in, BitVector& target)
1393{
1394 ViterbiTCH_AFS5_9 &decoder = *this;
1395 const size_t sz = in.size() - 24;
1396 const unsigned deferral = decoder.deferral();
1397 const size_t ctsz = sz + deferral*decoder.iRate();
1398 assert(sz == decoder.iRate()*target.size());
1399
1400 // Build a "history" array where each element contains the full history.
1401 uint32_t history[ctsz];
1402 {
1403 BitVector bits = in.sliced();
1404 uint32_t accum = 0;
1405 for (size_t i=0; i<sz; i++) {
1406 accum = (accum<<1) | bits.bit(i);
1407 history[i] = accum;
1408 }
1409 // Repeat last bit at the end.
1410 for (size_t i=sz; i<ctsz; i++) {
1411 accum = (accum<<1) | (accum & 0x01);
1412 history[i] = accum;
1413 }
1414 }
1415
1416 // Precompute metric tables.
1417 float matchCostTable[ctsz];
1418 float mismatchCostTable[ctsz];
1419 {
1420 const float *dp = in.begin();
1421 for (size_t i=0; i<sz; i++) {
1422 // pVal is the probability that a bit is correct.
1423 // ipVal is the probability that a bit is incorrect.
1424 float pVal = dp[i];
1425 if (pVal>0.5F) pVal = 1.0F-pVal;
1426 float ipVal = 1.0F-pVal;
1427 // This is a cheap approximation to an ideal cost function.
1428 if (pVal<0.01F) pVal = 0.01;
1429 if (ipVal<0.01F) ipVal = 0.01;
1430 matchCostTable[i] = 0.25F/ipVal;
1431 mismatchCostTable[i] = 0.25F/pVal;
1432 }
1433
1434 // pad end of table with unknowns
1435 for (size_t i=sz; i<ctsz; i++) {
1436 matchCostTable[i] = 0.5F;
1437 mismatchCostTable[i] = 0.5F;
1438 }
1439 }
1440
1441 {
1442 decoder.initializeStates();
1443 // Each sample of history[] carries its history.
1444 // So we only have to process every iRate-th sample.
1445 const unsigned step = decoder.iRate();
1446 // input pointer
1447 const uint32_t *ip = history + step - 1;
1448 // output pointers
1449 char *op = target.begin();
1450 const char *const opt = target.end();
1451 // table pointers
1452 const float* match = matchCostTable;
1453 const float* mismatch = mismatchCostTable;
1454 size_t oCount = 0;
1455 while (op<opt) {
1456 // Viterbi algorithm
1457 assert(match-matchCostTable<(int)(sizeof(matchCostTable)/sizeof(matchCostTable[0])-1));
1458 assert(mismatch-mismatchCostTable<(int)(sizeof(mismatchCostTable)/sizeof(mismatchCostTable[0])-1));
1459 const ViterbiTCH_AFS5_9::vCand &minCost = decoder.step(*ip, match, mismatch);
1460 ip += step;
1461 match += step;
1462 mismatch += step;
1463 // output
1464 if (oCount>=deferral) *op++ = (minCost.iState >> deferral)&0x01;
1465 oCount++;
1466 }
1467 }
1468}
1469
1470
1471
1472ViterbiTCH_AFS5_15::ViterbiTCH_AFS5_15()
1473{
1474 assert(mDeferral < 32);
1475 mCoeffs[0] = 0x01b;
1476 mCoeffsFB[0] = 0x01f;
1477 mCoeffs[1] = 0x01b;
1478 mCoeffsFB[1] = 0x01f;
1479 mCoeffs[2] = 0x015;
1480 mCoeffsFB[2] = 0x01f;
1481 mCoeffs[3] = 0x01f;
1482 mCoeffsFB[3] = 0x01f;
1483 mCoeffs[4] = 0x01f;
1484 mCoeffsFB[4] = 0x01f;
1485 for (unsigned i = 0; i < mIRate; i++) {
1486 computeStateTables(i);
1487 }
1488 computeGeneratorTable();
1489}
1490
1491
1492
1493
1494void ViterbiTCH_AFS5_15::initializeStates()
1495{
1496 for (unsigned i=0; i<mIStates; i++) vitClear(mSurvivors[i]);
1497 for (unsigned i=0; i<mNumCands; i++) vitClear(mCandidates[i]);
1498}
1499
1500
1501
1502void ViterbiTCH_AFS5_15::computeStateTables(unsigned g)
1503{
1504 assert(g<mIRate);
1505 for (unsigned state=0; state<mIStates; state++) {
1506 for (unsigned in = 0; in <= 1; in++) {
1507 uint32_t inputVal = (state<<1) | in;
1508 mStateTable[g][inputVal] = applyPoly(inputVal, mCoeffs[g] ^ mCoeffsFB[g], mOrder+1) ^ in;
1509 }
1510 }
1511}
1512
1513void ViterbiTCH_AFS5_15::computeGeneratorTable()
1514{
1515 for (unsigned index=0; index<mIStates*2; index++) {
1516 uint32_t t = 0;
1517 for (unsigned i = 0; i < mIRate; i++) {
1518 t = (t << 1) | mStateTable[i][index];
1519 }
1520 mGeneratorTable[index] = t;
1521 }
1522}
1523
1524
1525
1526
1527
1528
1529void ViterbiTCH_AFS5_15::branchCandidates()
1530{
1531 // Branch to generate new input states.
1532 const vCand *sp = mSurvivors;
1533 for (unsigned cand=0; cand<mNumCands; cand+=2) {
1534 uint32_t oStateShifted = (sp->oState) << mIRate;
1535 for (unsigned in = 0; in <= 1; in++) {
1536 mCandidates[cand+in].iState = ((sp->iState) << 1) | in;
1537 mCandidates[cand+in].cost = sp->cost;
1538 uint32_t outputs = oStateShifted;
1539 for (unsigned out = 0; out < mIRate; out++) {
1540 char feedback = applyPoly(sp->rState[out], mCoeffsFB[out] ^ 1, mOrder+1);
1541 char rState = (((sp->rState[out]) ^ feedback) << 1) | in;
1542 mCandidates[cand+in].rState[out] = rState;
1543 outputs |= (mGeneratorTable[rState & mCMask] & (1 << (mIRate - out - 1)));
1544 }
1545 mCandidates[cand+in].oState = outputs;
1546 }
1547 sp++;
1548 }
1549}
1550
1551
1552void ViterbiTCH_AFS5_15::getSoftCostMetrics(const uint32_t inSample, const float *matchCost, const float *mismatchCost)
1553{
1554 const float *cTab[2] = {matchCost,mismatchCost};
1555 for (unsigned i=0; i<mNumCands; i++) {
1556 vCand& thisCand = mCandidates[i];
1557 const unsigned mismatched = inSample ^ (thisCand.oState);
1558 for (unsigned i = 0; i < mIRate; i++) {
1559 thisCand.cost += cTab[(mismatched>>i)&0x01][mIRate-i-1];
1560 }
1561 }
1562}
1563
1564
1565void ViterbiTCH_AFS5_15::pruneCandidates()
1566{
1567 const vCand* c1 = mCandidates; // 0-prefix
1568 const vCand* c2 = mCandidates + mIStates; // 1-prefix
1569 for (unsigned i=0; i<mIStates; i++) {
1570 if (c1[i].cost < c2[i].cost) mSurvivors[i] = c1[i];
1571 else mSurvivors[i] = c2[i];
1572 }
1573}
1574
1575
1576const ViterbiTCH_AFS5_15::vCand& ViterbiTCH_AFS5_15::minCost() const
1577{
1578 int minIndex = 0;
1579 float minCost = mSurvivors[0].cost;
1580 for (unsigned i=1; i<mIStates; i++) {
1581 const float thisCost = mSurvivors[i].cost;
1582 if (thisCost>=minCost) continue;
1583 minCost = thisCost;
1584 minIndex=i;
1585 }
1586 return mSurvivors[minIndex];
1587}
1588
1589
1590const ViterbiTCH_AFS5_15::vCand& ViterbiTCH_AFS5_15::step(uint32_t inSample, const float *probs, const float *iprobs)
1591{
1592 branchCandidates();
1593 getSoftCostMetrics(inSample,probs,iprobs);
1594 pruneCandidates();
1595 return minCost();
1596}
1597
1598
1599
1600void ViterbiTCH_AFS5_15::decode(const SoftVector &in, BitVector& target)
1601{
1602 ViterbiTCH_AFS5_15 &decoder = *this;
1603 const size_t sz = in.size() - 20;
1604 const unsigned deferral = decoder.deferral();
1605 const size_t ctsz = sz + deferral*decoder.iRate();
1606 assert(sz == decoder.iRate()*target.size());
1607
1608 // Build a "history" array where each element contains the full history.
1609 uint32_t history[ctsz];
1610 {
1611 BitVector bits = in.sliced();
1612 uint32_t accum = 0;
1613 for (size_t i=0; i<sz; i++) {
1614 accum = (accum<<1) | bits.bit(i);
1615 history[i] = accum;
1616 }
1617 // Repeat last bit at the end.
1618 for (size_t i=sz; i<ctsz; i++) {
1619 accum = (accum<<1) | (accum & 0x01);
1620 history[i] = accum;
1621 }
1622 }
1623
1624 // Precompute metric tables.
1625 float matchCostTable[ctsz];
1626 float mismatchCostTable[ctsz];
1627 {
1628 const float *dp = in.begin();
1629 for (size_t i=0; i<sz; i++) {
1630 // pVal is the probability that a bit is correct.
1631 // ipVal is the probability that a bit is incorrect.
1632 float pVal = dp[i];
1633 if (pVal>0.5F) pVal = 1.0F-pVal;
1634 float ipVal = 1.0F-pVal;
1635 // This is a cheap approximation to an ideal cost function.
1636 if (pVal<0.01F) pVal = 0.01;
1637 if (ipVal<0.01F) ipVal = 0.01;
1638 matchCostTable[i] = 0.25F/ipVal;
1639 mismatchCostTable[i] = 0.25F/pVal;
1640 }
1641
1642 // pad end of table with unknowns
1643 for (size_t i=sz; i<ctsz; i++) {
1644 matchCostTable[i] = 0.5F;
1645 mismatchCostTable[i] = 0.5F;
1646 }
1647 }
1648
1649 {
1650 decoder.initializeStates();
1651 // Each sample of history[] carries its history.
1652 // So we only have to process every iRate-th sample.
1653 const unsigned step = decoder.iRate();
1654 // input pointer
1655 const uint32_t *ip = history + step - 1;
1656 // output pointers
1657 char *op = target.begin();
1658 const char *const opt = target.end();
1659 // table pointers
1660 const float* match = matchCostTable;
1661 const float* mismatch = mismatchCostTable;
1662 size_t oCount = 0;
1663 while (op<opt) {
1664 // Viterbi algorithm
1665 assert(match-matchCostTable<(int)(sizeof(matchCostTable)/sizeof(matchCostTable[0])-1));
1666 assert(mismatch-mismatchCostTable<(int)(sizeof(mismatchCostTable)/sizeof(mismatchCostTable[0])-1));
1667 const ViterbiTCH_AFS5_15::vCand &minCost = decoder.step(*ip, match, mismatch);
1668 ip += step;
1669 match += step;
1670 mismatch += step;
1671 // output
1672 if (oCount>=deferral) *op++ = (minCost.iState >> deferral)&0x01;
1673 oCount++;
1674 }
1675 }
1676}
1677
1678
1679
1680ViterbiTCH_AFS4_75::ViterbiTCH_AFS4_75()
1681{
1682 assert(mDeferral < 32);
1683 mCoeffs[0] = 0x06d;
1684 mCoeffsFB[0] = 0x05f;
1685 mCoeffs[1] = 0x06d;
1686 mCoeffsFB[1] = 0x05f;
1687 mCoeffs[2] = 0x053;
1688 mCoeffsFB[2] = 0x05f;
1689 mCoeffs[3] = 0x05f;
1690 mCoeffsFB[3] = 0x05f;
1691 mCoeffs[4] = 0x05f;
1692 mCoeffsFB[4] = 0x05f;
1693 for (unsigned i = 0; i < mIRate; i++) {
1694 computeStateTables(i);
1695 }
1696 computeGeneratorTable();
1697}
1698
1699
1700
1701
1702void ViterbiTCH_AFS4_75::initializeStates()
1703{
1704 for (unsigned i=0; i<mIStates; i++) vitClear(mSurvivors[i]);
1705 for (unsigned i=0; i<mNumCands; i++) vitClear(mCandidates[i]);
1706}
1707
1708
1709
1710void ViterbiTCH_AFS4_75::computeStateTables(unsigned g)
1711{
1712 assert(g<mIRate);
1713 for (unsigned state=0; state<mIStates; state++) {
1714 for (unsigned in = 0; in <= 1; in++) {
1715 uint32_t inputVal = (state<<1) | in;
1716 mStateTable[g][inputVal] = applyPoly(inputVal, mCoeffs[g] ^ mCoeffsFB[g], mOrder+1) ^ in;
1717 }
1718 }
1719}
1720
1721void ViterbiTCH_AFS4_75::computeGeneratorTable()
1722{
1723 for (unsigned index=0; index<mIStates*2; index++) {
1724 uint32_t t = 0;
1725 for (unsigned i = 0; i < mIRate; i++) {
1726 t = (t << 1) | mStateTable[i][index];
1727 }
1728 mGeneratorTable[index] = t;
1729 }
1730}
1731
1732
1733
1734
1735
1736
1737void ViterbiTCH_AFS4_75::branchCandidates()
1738{
1739 // Branch to generate new input states.
1740 const vCand *sp = mSurvivors;
1741 for (unsigned cand=0; cand<mNumCands; cand+=2) {
1742 uint32_t oStateShifted = (sp->oState) << mIRate;
1743 for (unsigned in = 0; in <= 1; in++) {
1744 mCandidates[cand+in].iState = ((sp->iState) << 1) | in;
1745 mCandidates[cand+in].cost = sp->cost;
1746 uint32_t outputs = oStateShifted;
1747 for (unsigned out = 0; out < mIRate; out++) {
1748 char feedback = applyPoly(sp->rState[out], mCoeffsFB[out] ^ 1, mOrder+1);
1749 char rState = (((sp->rState[out]) ^ feedback) << 1) | in;
1750 mCandidates[cand+in].rState[out] = rState;
1751 outputs |= (mGeneratorTable[rState & mCMask] & (1 << (mIRate - out - 1)));
1752 }
1753 mCandidates[cand+in].oState = outputs;
1754 }
1755 sp++;
1756 }
1757}
1758
1759
1760void ViterbiTCH_AFS4_75::getSoftCostMetrics(const uint32_t inSample, const float *matchCost, const float *mismatchCost)
1761{
1762 const float *cTab[2] = {matchCost,mismatchCost};
1763 for (unsigned i=0; i<mNumCands; i++) {
1764 vCand& thisCand = mCandidates[i];
1765 const unsigned mismatched = inSample ^ (thisCand.oState);
1766 for (unsigned i = 0; i < mIRate; i++) {
1767 thisCand.cost += cTab[(mismatched>>i)&0x01][mIRate-i-1];
1768 }
1769 }
1770}
1771
1772
1773void ViterbiTCH_AFS4_75::pruneCandidates()
1774{
1775 const vCand* c1 = mCandidates; // 0-prefix
1776 const vCand* c2 = mCandidates + mIStates; // 1-prefix
1777 for (unsigned i=0; i<mIStates; i++) {
1778 if (c1[i].cost < c2[i].cost) mSurvivors[i] = c1[i];
1779 else mSurvivors[i] = c2[i];
1780 }
1781}
1782
1783
1784const ViterbiTCH_AFS4_75::vCand& ViterbiTCH_AFS4_75::minCost() const
1785{
1786 int minIndex = 0;
1787 float minCost = mSurvivors[0].cost;
1788 for (unsigned i=1; i<mIStates; i++) {
1789 const float thisCost = mSurvivors[i].cost;
1790 if (thisCost>=minCost) continue;
1791 minCost = thisCost;
1792 minIndex=i;
1793 }
1794 return mSurvivors[minIndex];
1795}
1796
1797
1798const ViterbiTCH_AFS4_75::vCand& ViterbiTCH_AFS4_75::step(uint32_t inSample, const float *probs, const float *iprobs)
1799{
1800 branchCandidates();
1801 getSoftCostMetrics(inSample,probs,iprobs);
1802 pruneCandidates();
1803 return minCost();
1804}
1805
1806
1807
1808void ViterbiTCH_AFS4_75::decode(const SoftVector &in, BitVector& target)
1809{
1810 ViterbiTCH_AFS4_75 &decoder = *this;
1811 const size_t sz = in.size() - 30;
1812 const unsigned deferral = decoder.deferral();
1813 const size_t ctsz = sz + deferral*decoder.iRate();
1814 assert(sz == decoder.iRate()*target.size());
1815
1816 // Build a "history" array where each element contains the full history.
1817 uint32_t history[ctsz];
1818 {
1819 BitVector bits = in.sliced();
1820 uint32_t accum = 0;
1821 for (size_t i=0; i<sz; i++) {
1822 accum = (accum<<1) | bits.bit(i);
1823 history[i] = accum;
1824 }
1825 // Repeat last bit at the end.
1826 for (size_t i=sz; i<ctsz; i++) {
1827 accum = (accum<<1) | (accum & 0x01);
1828 history[i] = accum;
1829 }
1830 }
1831
1832 // Precompute metric tables.
1833 float matchCostTable[ctsz];
1834 float mismatchCostTable[ctsz];
1835 {
1836 const float *dp = in.begin();
1837 for (size_t i=0; i<sz; i++) {
1838 // pVal is the probability that a bit is correct.
1839 // ipVal is the probability that a bit is incorrect.
1840 float pVal = dp[i];
1841 if (pVal>0.5F) pVal = 1.0F-pVal;
1842 float ipVal = 1.0F-pVal;
1843 // This is a cheap approximation to an ideal cost function.
1844 if (pVal<0.01F) pVal = 0.01;
1845 if (ipVal<0.01F) ipVal = 0.01;
1846 matchCostTable[i] = 0.25F/ipVal;
1847 mismatchCostTable[i] = 0.25F/pVal;
1848 }
1849
1850 // pad end of table with unknowns
1851 for (size_t i=sz; i<ctsz; i++) {
1852 matchCostTable[i] = 0.5F;
1853 mismatchCostTable[i] = 0.5F;
1854 }
1855 }
1856
1857 {
1858 decoder.initializeStates();
1859 // Each sample of history[] carries its history.
1860 // So we only have to process every iRate-th sample.
1861 const unsigned step = decoder.iRate();
1862 // input pointer
1863 const uint32_t *ip = history + step - 1;
1864 // output pointers
1865 char *op = target.begin();
1866 const char *const opt = target.end();
1867 // table pointers
1868 const float* match = matchCostTable;
1869 const float* mismatch = mismatchCostTable;
1870 size_t oCount = 0;
1871 while (op<opt) {
1872 // Viterbi algorithm
1873 assert(match-matchCostTable<(int)(sizeof(matchCostTable)/sizeof(matchCostTable[0])-1));
1874 assert(mismatch-mismatchCostTable<(int)(sizeof(mismatchCostTable)/sizeof(mismatchCostTable[0])-1));
1875 const ViterbiTCH_AFS4_75::vCand &minCost = decoder.step(*ip, match, mismatch);
1876 ip += step;
1877 match += step;
1878 mismatch += step;
1879 // output
1880 if (oCount>=deferral) *op++ = (minCost.iState >> deferral)&0x01;
1881 oCount++;
1882 }
1883 }
1884}
1885
1886
1887