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