/*
 * Copyright 2013, 2014 Range Networks, Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 * This use of this software may be subject to additional restrictions.
 * See the LEGAL file in the main directory for details.
 */


#include "BitVector.h"
#include "AmrCoder.h"
#include <iostream>
#include <stdio.h>
#include <sstream>

using namespace std;



ViterbiTCH_AFS12_2::ViterbiTCH_AFS12_2()
{
	assert(mDeferral < 32);
	mCoeffs[0] = 0x019;
	mCoeffsFB[0] = 0x019;
	mCoeffs[1] = 0x01b;
	mCoeffsFB[1] = 0x019;
	for (unsigned i = 0; i < mIRate; i++) {
		computeStateTables(i);
	}
	computeGeneratorTable();
}


//void BitVector::encode(const ViterbiTCH_AFS12_2& coder, BitVector& target) const
void ViterbiTCH_AFS12_2::encode(const BitVector& in, BitVector& target) const
{
	assert(in.size() == 250);
	assert(target.size() == 508);
	const char *u = in.begin();
	char *C = target.begin();
	const unsigned H = 4;
	BitVector r(254+H);
	for (int k = -H; k <= -1; k++) r[k+H] = 0;
	for (unsigned k = 0; k <= 249; k++) {
		r[k+H] = u[k] ^ r[k-3+H] ^ r[k-4+H];
		C[2*k] = u[k];
		C[2*k+1] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
	}
	// termination
	for (unsigned k = 250; k <= 253; k++) {
		r[k+H] = 0;
		C[2*k] = r[k-3+H] ^ r[k-4+H];
		C[2*k+1] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
	}
}



//void BitVector::encode(const ViterbiTCH_AFS10_2& coder, BitVector& target)
void ViterbiTCH_AFS10_2::encode(const BitVector& in, BitVector& target) const
{
	assert(in.size() == 210);
	assert(target.size() == 642);
	const char *u = in.begin();
	char *C = target.begin();
	const unsigned H = 4;
	BitVector r(214+H);
	for (int k = -H; k <= -1; k++) r[k+H] = 0;
	for (unsigned k = 0; k <= 209; k++) {
		r[k+H] = u[k] ^ r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H];
		C[3*k] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
		C[3*k+1] = r[k+H] ^ r[k-2+H] ^ r[k-4+H];
		C[3*k+2] = u[k];
	}
	// termination
	for (unsigned k = 210; k <= 213; k++) {
		r[k+H] = 0;
		C[3*k] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
		C[3*k+1] = r[k+H] ^ r[k-2+H] ^ r[k-4+H];
		C[3*k+2] = r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H];
	}
}



//void BitVector::encode(const ViterbiTCH_AFS7_95& coder, BitVector& target)
void ViterbiTCH_AFS7_95::encode(const BitVector& in, BitVector& target) const
{
	assert(in.size() == 165);
	assert(target.size() == 513);
	const char *u = in.begin();
	char *C = target.begin();
	const unsigned H = 6;
	BitVector r(171+H);
	for (int k = -H; k <= -1; k++) r[k+H] = 0;
	for (unsigned k = 0; k <= 164; k++) {
		r[k+H] = u[k] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-5+H] ^ r[k-6+H];
		C[3*k] = u[k];
		C[3*k+1] = r[k+H] ^ r[k-1+H] ^ r[k-4+H] ^ r[k-6+H];
		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];
	}
	// termination
	for (unsigned k = 165; k <= 170; k++) {
		r[k+H] = 0;
		C[3*k] = r[k-2+H] ^ r[k-3+H] ^ r[k-5+H] ^ r[k-6+H];
		C[3*k+1] = r[k+H] ^ r[k-1+H] ^ r[k-4+H] ^ r[k-6+H];
		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];
	}
}



void ViterbiTCH_AFS7_4::encode(const BitVector& in, BitVector& target) const
{
	assert(in.size() == 154);
	assert(target.size() == 474);
	const char *u = in.begin();
	char *C = target.begin();
	const unsigned H = 4;
	BitVector r(158+H);
	for (int k = -H; k <= -1; k++) r[k+H] = 0;
	for (unsigned k = 0; k <= 153; k++) {
		r[k+H] = u[k] ^ r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H];
		C[3*k] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
		C[3*k+1] = r[k+H] ^ r[k-2+H] ^ r[k-4+H];
		C[3*k+2] = u[k];
	}
	// termination
	for (unsigned k = 154; k <= 157; k++) {
		r[k+H] = 0;
		C[3*k] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
		C[3*k+1] = r[k+H] ^ r[k-2+H] ^ r[k-4+H];
		C[3*k+2] = r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H];
	}
}



void ViterbiTCH_AFS6_7::encode(const BitVector& in, BitVector& target) const
{
	assert(in.size() == 140);
	assert(target.size() == 576);
	const char *u = in.begin();
	char *C = target.begin();
	const unsigned H = 4;
	BitVector r(144+H);
	for (int k = -H; k <= -1; k++) r[k+H] = 0;
	for (unsigned k = 0; k <= 139; k++) {
		r[k+H] = u[k] ^ r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H];
		C[4*k] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
		C[4*k+1] = r[k+H] ^ r[k-2+H] ^ r[k-4+H];
		C[4*k+2] = u[k];
		C[4*k+3] = u[k];
	}
	// termination
	for (unsigned k = 140; k <= 143; k++) {
		r[k+H] = 0;
		C[4*k] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
		C[4*k+1] = r[k+H] ^ r[k-2+H] ^ r[k-4+H];
		C[4*k+2] = r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H];
		C[4*k+3] = r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H];
	}
}



void ViterbiTCH_AFS5_9::encode(const BitVector& in, BitVector& target) const
{
	assert(in.size() == 124);
	assert(target.size() == 520);
	const char *u = in.begin();
	char *C = target.begin();
	const unsigned H = 6;
	BitVector r(130+H);
	for (int k = -H; k <= -1; k++) r[k+H] = 0;
	for (unsigned k = 0; k <= 123; k++) {
		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];
		C[4*k] = r[k+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-5+H] ^ r[k-6+H];
		C[4*k+1] = r[k+H] ^ r[k-1+H] ^ r[k-4+H] ^ r[k-6+H];
		C[4*k+2] = u[k];
		C[4*k+3] = u[k];
	}
	// termination
	for (unsigned k = 124; k <= 129; k++) {
		r[k+H] = 0;
		C[4*k] = r[k+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-5+H] ^ r[k-6+H];
		C[4*k+1] = r[k+H] ^ r[k-1+H] ^ r[k-4+H] ^ r[k-6+H];
		C[4*k+2] = r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H] ^ r[k-6+H];
		C[4*k+3] = r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H] ^ r[k-6+H];
	}
}



void ViterbiTCH_AFS5_15::encode(const BitVector& in, BitVector& target) const
{
	assert(in.size() == 109);
	assert(target.size() == 565);
	const char *u = in.begin();
	char *C = target.begin();
	const unsigned H = 4;
	BitVector r(113+H);
	for (int k = -H; k <= -1; k++) r[k+H] = 0;
	for (unsigned k = 0; k <= 108; k++) {
		r[k+H] = u[k] ^ r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H];
		C[5*k] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
		C[5*k+1] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
		C[5*k+2] = r[k+H] ^ r[k-2+H] ^ r[k-4+H];
		C[5*k+3] = u[k];
		C[5*k+4] = u[k];
	}
	// termination
	for (unsigned k = 109; k <= 112; k++) {
		r[k+H] = 0;
		C[5*k] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
		C[5*k+1] = r[k+H] ^ r[k-1+H] ^ r[k-3+H] ^ r[k-4+H];
		C[5*k+2] = r[k+H] ^ r[k-2+H] ^ r[k-4+H];
		C[5*k+3] = r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H];
		C[5*k+4] = r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H];
	}
}



void ViterbiTCH_AFS4_75::encode(const BitVector& in, BitVector& target) const
{
	assert(in.size() == 101);
	assert(target.size() == 535);
	const char *u = in.begin();
	char *C = target.begin();
	const unsigned H = 6;
	BitVector r(107+H);
	for (int k = -H; k <= -1; k++) r[k+H] = 0;
	for (unsigned k = 0; k <= 100; k++) {
		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];
		C[5*k] = r[k+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-5+H] ^ r[k-6+H];
		C[5*k+1] = r[k+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-5+H] ^ r[k-6+H];
		C[5*k+2] = r[k+H] ^ r[k-1+H] ^ r[k-4+H] ^ r[k-6+H];
		C[5*k+3] = u[k];
		C[5*k+4] = u[k];
	}
	// termination
	for (unsigned k = 101; k <= 106; k++) {
		r[k+H] = 0;
		C[5*k] = r[k+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-5+H] ^ r[k-6+H];
		C[5*k+1] = r[k+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-5+H] ^ r[k-6+H];
		C[5*k+2] = r[k+H] ^ r[k-1+H] ^ r[k-4+H] ^ r[k-6+H];
		C[5*k+3] = r[k+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H] ^ r[k-6+H];
		C[5*k+4] = r[k-1+H] ^ r[k-2+H] ^ r[k-3+H] ^ r[k-4+H] ^ r[k-6+H];
	}
}


void ViterbiTCH_AFS12_2::initializeStates()
{
	for (unsigned i=0; i<mIStates; i++) vitClear(mSurvivors[i]);
	for (unsigned i=0; i<mNumCands; i++) vitClear(mCandidates[i]);
}



void ViterbiTCH_AFS12_2::computeStateTables(unsigned g)
{
	assert(g<mIRate);
	for (unsigned state=0; state<mIStates; state++) {
		for (unsigned in = 0; in <= 1; in++) {
			uint32_t inputVal = (state<<1) | in;
			mStateTable[g][inputVal] = applyPoly(inputVal, mCoeffs[g] ^ mCoeffsFB[g], mOrder+1) ^ in;
		}
	}
}

void ViterbiTCH_AFS12_2::computeGeneratorTable()
{
	for (unsigned index=0; index<mIStates*2; index++) {
		uint32_t t = 0;
		for (unsigned i = 0; i < mIRate; i++) {
			t = (t << 1) | mStateTable[i][index];
		}
		mGeneratorTable[index] = t;
	}
}






void ViterbiTCH_AFS12_2::branchCandidates()
{
	// Branch to generate new input states.
	const vCand *sp = mSurvivors;
	for (unsigned cand=0; cand<mNumCands; cand+=2) {
		uint32_t oStateShifted = (sp->oState) << mIRate;
		for (unsigned in = 0; in <= 1; in++) {
			mCandidates[cand+in].iState = ((sp->iState) << 1) | in;
			mCandidates[cand+in].cost = sp->cost;
			uint32_t outputs = oStateShifted;
			for (unsigned out = 0; out < mIRate; out++) {
				char feedback = applyPoly(sp->rState[out], mCoeffsFB[out] ^ 1, mOrder+1);
				char rState = (((sp->rState[out]) ^ feedback) << 1) | in;
				mCandidates[cand+in].rState[out] = rState;
				outputs |= (mGeneratorTable[rState & mCMask] & (1 << (mIRate - out - 1)));
			}
			mCandidates[cand+in].oState = outputs;
		}
		sp++;
	}
}


void ViterbiTCH_AFS12_2::getSoftCostMetrics(const uint32_t inSample, const float *matchCost, const float *mismatchCost)
{
	const float *cTab[2] = {matchCost,mismatchCost};
	for (unsigned i=0; i<mNumCands; i++) {
		vCand& thisCand = mCandidates[i];
		const unsigned mismatched = inSample ^ (thisCand.oState);
		for (unsigned i = 0; i < mIRate; i++) {
			thisCand.cost += cTab[(mismatched>>i)&0x01][mIRate-i-1];
		}
	}
}


void ViterbiTCH_AFS12_2::pruneCandidates()
{
	const vCand* c1 = mCandidates;					// 0-prefix
	const vCand* c2 = mCandidates + mIStates;		// 1-prefix
	for (unsigned i=0; i<mIStates; i++) {
		if (c1[i].cost < c2[i].cost) mSurvivors[i] = c1[i];
		else mSurvivors[i] = c2[i];
	}
}


const ViterbiTCH_AFS12_2::vCand& ViterbiTCH_AFS12_2::minCost() const
{
	int minIndex = 0;
	float minCost = mSurvivors[0].cost;
	for (unsigned i=1; i<mIStates; i++) {
		const float thisCost = mSurvivors[i].cost;
		if (thisCost>=minCost) continue;
		minCost = thisCost;
		minIndex=i;
	}
	return mSurvivors[minIndex];
}


const ViterbiTCH_AFS12_2::vCand& ViterbiTCH_AFS12_2::step(uint32_t inSample, const float *probs, const float *iprobs)
{
	branchCandidates();
	getSoftCostMetrics(inSample,probs,iprobs);
	pruneCandidates();
	return minCost();
}



void ViterbiTCH_AFS12_2::decode(const SoftVector &in, BitVector& target)
{
	ViterbiTCH_AFS12_2 &decoder = *this;
	const size_t sz = in.size() - 8;
	const unsigned deferral = decoder.deferral();
	const size_t ctsz = sz + deferral*decoder.iRate();
	assert(sz == decoder.iRate()*target.size());

	// Build a "history" array where each element contains the full history.
	uint32_t history[ctsz];
	{
		BitVector bits = in.sliced();
		uint32_t accum = 0;
		for (size_t i=0; i<sz; i++) {
			accum = (accum<<1) | bits.bit(i);
			history[i] = accum;
		}
		// Repeat last bit at the end.
		for (size_t i=sz; i<ctsz; i++) {
			accum = (accum<<1) | (accum & 0x01);
			history[i] = accum;
		}
	}

	// Precompute metric tables.
	float matchCostTable[ctsz];
	float mismatchCostTable[ctsz];
	{
		const float *dp = in.begin();
		for (size_t i=0; i<sz; i++) {
			// pVal is the probability that a bit is correct.
			// ipVal is the probability that a bit is incorrect.
			float pVal = dp[i];
			if (pVal>0.5F) pVal = 1.0F-pVal;
			float ipVal = 1.0F-pVal;
			// This is a cheap approximation to an ideal cost function.
			if (pVal<0.01F) pVal = 0.01;
			if (ipVal<0.01F) ipVal = 0.01;
			matchCostTable[i] = 0.25F/ipVal;
			mismatchCostTable[i] = 0.25F/pVal;
		}
	
		// pad end of table with unknowns
		for (size_t i=sz; i<ctsz; i++) {
			matchCostTable[i] = 0.5F;
			mismatchCostTable[i] = 0.5F;
		}
	}

	{
		decoder.initializeStates();
		// Each sample of history[] carries its history.
		// So we only have to process every iRate-th sample.
		const unsigned step = decoder.iRate();
		// input pointer
		const uint32_t *ip = history + step - 1;
		// output pointers
		char *op = target.begin();
		const char *const opt = target.end();
		// table pointers
		const float* match = matchCostTable;
		const float* mismatch = mismatchCostTable;
		size_t oCount = 0;
		while (op<opt) {
			// Viterbi algorithm
			assert(match-matchCostTable<(int)(sizeof(matchCostTable)/sizeof(matchCostTable[0])-1));
			assert(mismatch-mismatchCostTable<(int)(sizeof(mismatchCostTable)/sizeof(mismatchCostTable[0])-1));
			const ViterbiTCH_AFS12_2::vCand &minCost = decoder.step(*ip, match, mismatch);
			ip += step;
			match += step;
			mismatch += step;
			// output
			if (oCount>=deferral) *op++ = (minCost.iState >> deferral)&0x01;
			oCount++;
		}
	}
}



ViterbiTCH_AFS10_2::ViterbiTCH_AFS10_2()
{
	assert(mDeferral < 32);
	mCoeffs[0] = 0x01b;
	mCoeffsFB[0] = 0x01f;
	mCoeffs[1] = 0x015;
	mCoeffsFB[1] = 0x01f;
	mCoeffs[2] = 0x01f;
	mCoeffsFB[2] = 0x01f;
	for (unsigned i = 0; i < mIRate; i++) {
		computeStateTables(i);
	}
	computeGeneratorTable();
}




void ViterbiTCH_AFS10_2::initializeStates()
{
	for (unsigned i=0; i<mIStates; i++) vitClear(mSurvivors[i]);
	for (unsigned i=0; i<mNumCands; i++) vitClear(mCandidates[i]);
}



void ViterbiTCH_AFS10_2::computeStateTables(unsigned g)
{
	assert(g<mIRate);
	for (unsigned state=0; state<mIStates; state++) {
		for (unsigned in = 0; in <= 1; in++) {
			uint32_t inputVal = (state<<1) | in;
			mStateTable[g][inputVal] = applyPoly(inputVal, mCoeffs[g] ^ mCoeffsFB[g], mOrder+1) ^ in;
		}
	}
}

void ViterbiTCH_AFS10_2::computeGeneratorTable()
{
	for (unsigned index=0; index<mIStates*2; index++) {
		uint32_t t = 0;
		for (unsigned i = 0; i < mIRate; i++) {
			t = (t << 1) | mStateTable[i][index];
		}
		mGeneratorTable[index] = t;
	}
}






void ViterbiTCH_AFS10_2::branchCandidates()
{
	// Branch to generate new input states.
	const vCand *sp = mSurvivors;
	for (unsigned cand=0; cand<mNumCands; cand+=2) {
		uint32_t oStateShifted = (sp->oState) << mIRate;
		for (unsigned in = 0; in <= 1; in++) {
			mCandidates[cand+in].iState = ((sp->iState) << 1) | in;
			mCandidates[cand+in].cost = sp->cost;
			uint32_t outputs = oStateShifted;
			for (unsigned out = 0; out < mIRate; out++) {
				char feedback = applyPoly(sp->rState[out], mCoeffsFB[out] ^ 1, mOrder+1);
				char rState = (((sp->rState[out]) ^ feedback) << 1) | in;
				mCandidates[cand+in].rState[out] = rState;
				outputs |= (mGeneratorTable[rState & mCMask] & (1 << (mIRate - out - 1)));
			}
			mCandidates[cand+in].oState = outputs;
		}
		sp++;
	}
}


void ViterbiTCH_AFS10_2::getSoftCostMetrics(const uint32_t inSample, const float *matchCost, const float *mismatchCost)
{
	const float *cTab[2] = {matchCost,mismatchCost};
	for (unsigned i=0; i<mNumCands; i++) {
		vCand& thisCand = mCandidates[i];
		const unsigned mismatched = inSample ^ (thisCand.oState);
		for (unsigned i = 0; i < mIRate; i++) {
			thisCand.cost += cTab[(mismatched>>i)&0x01][mIRate-i-1];
		}
	}
}


void ViterbiTCH_AFS10_2::pruneCandidates()
{
	const vCand* c1 = mCandidates;					// 0-prefix
	const vCand* c2 = mCandidates + mIStates;		// 1-prefix
	for (unsigned i=0; i<mIStates; i++) {
		if (c1[i].cost < c2[i].cost) mSurvivors[i] = c1[i];
		else mSurvivors[i] = c2[i];
	}
}


const ViterbiTCH_AFS10_2::vCand& ViterbiTCH_AFS10_2::minCost() const
{
	int minIndex = 0;
	float minCost = mSurvivors[0].cost;
	for (unsigned i=1; i<mIStates; i++) {
		const float thisCost = mSurvivors[i].cost;
		if (thisCost>=minCost) continue;
		minCost = thisCost;
		minIndex=i;
	}
	return mSurvivors[minIndex];
}


const ViterbiTCH_AFS10_2::vCand& ViterbiTCH_AFS10_2::step(uint32_t inSample, const float *probs, const float *iprobs)
{
	branchCandidates();
	getSoftCostMetrics(inSample,probs,iprobs);
	pruneCandidates();
	return minCost();
}



void ViterbiTCH_AFS10_2::decode(const SoftVector &in, BitVector& target)
{
	ViterbiTCH_AFS10_2 &decoder = *this;
	const size_t sz = in.size() - 12;
	const unsigned deferral = decoder.deferral();
	const size_t ctsz = sz + deferral*decoder.iRate();
	assert(sz == decoder.iRate()*target.size());

	// Build a "history" array where each element contains the full history.
	uint32_t history[ctsz];
	{
		BitVector bits = in.sliced();
		uint32_t accum = 0;
		for (size_t i=0; i<sz; i++) {
			accum = (accum<<1) | bits.bit(i);
			history[i] = accum;
		}
		// Repeat last bit at the end.
		for (size_t i=sz; i<ctsz; i++) {
			accum = (accum<<1) | (accum & 0x01);
			history[i] = accum;
		}
	}

	// Precompute metric tables.
	float matchCostTable[ctsz];
	float mismatchCostTable[ctsz];
	{
		const float *dp = in.begin();
		for (size_t i=0; i<sz; i++) {
			// pVal is the probability that a bit is correct.
			// ipVal is the probability that a bit is incorrect.
			float pVal = dp[i];
			if (pVal>0.5F) pVal = 1.0F-pVal;
			float ipVal = 1.0F-pVal;
			// This is a cheap approximation to an ideal cost function.
			if (pVal<0.01F) pVal = 0.01;
			if (ipVal<0.01F) ipVal = 0.01;
			matchCostTable[i] = 0.25F/ipVal;
			mismatchCostTable[i] = 0.25F/pVal;
		}
	
		// pad end of table with unknowns
		for (size_t i=sz; i<ctsz; i++) {
			matchCostTable[i] = 0.5F;
			mismatchCostTable[i] = 0.5F;
		}
	}

	{
		decoder.initializeStates();
		// Each sample of history[] carries its history.
		// So we only have to process every iRate-th sample.
		const unsigned step = decoder.iRate();
		// input pointer
		const uint32_t *ip = history + step - 1;
		// output pointers
		char *op = target.begin();
		const char *const opt = target.end();
		// table pointers
		const float* match = matchCostTable;
		const float* mismatch = mismatchCostTable;
		size_t oCount = 0;
		while (op<opt) {
			// Viterbi algorithm
			assert(match-matchCostTable<(int)(sizeof(matchCostTable)/sizeof(matchCostTable[0])-1));
			assert(mismatch-mismatchCostTable<(int)(sizeof(mismatchCostTable)/sizeof(mismatchCostTable[0])-1));
			const ViterbiTCH_AFS10_2::vCand &minCost = decoder.step(*ip, match, mismatch);
			ip += step;
			match += step;
			mismatch += step;
			// output
			if (oCount>=deferral) *op++ = (minCost.iState >> deferral)&0x01;
			oCount++;
		}
	}
}



ViterbiTCH_AFS7_95::ViterbiTCH_AFS7_95()
{
	assert(mDeferral < 32);
	mCoeffs[0] = 0x06d;
	mCoeffsFB[0] = 0x06d;
	mCoeffs[1] = 0x053;
	mCoeffsFB[1] = 0x06d;
	mCoeffs[2] = 0x05f;
	mCoeffsFB[2] = 0x06d;
	for (unsigned i = 0; i < mIRate; i++) {
		computeStateTables(i);
	}
	computeGeneratorTable();
}




void ViterbiTCH_AFS7_95::initializeStates()
{
	for (unsigned i=0; i<mIStates; i++) vitClear(mSurvivors[i]);
	for (unsigned i=0; i<mNumCands; i++) vitClear(mCandidates[i]);
}



void ViterbiTCH_AFS7_95::computeStateTables(unsigned g)
{
	assert(g<mIRate);
	for (unsigned state=0; state<mIStates; state++) {
		for (unsigned in = 0; in <= 1; in++) {
			uint32_t inputVal = (state<<1) | in;
			mStateTable[g][inputVal] = applyPoly(inputVal, mCoeffs[g] ^ mCoeffsFB[g], mOrder+1) ^ in;
		}
	}
}

void ViterbiTCH_AFS7_95::computeGeneratorTable()
{
	for (unsigned index=0; index<mIStates*2; index++) {
		uint32_t t = 0;
		for (unsigned i = 0; i < mIRate; i++) {
			t = (t << 1) | mStateTable[i][index];
		}
		mGeneratorTable[index] = t;
	}
}






void ViterbiTCH_AFS7_95::branchCandidates()
{
	// Branch to generate new input states.
	const vCand *sp = mSurvivors;
	for (unsigned cand=0; cand<mNumCands; cand+=2) {
		uint32_t oStateShifted = (sp->oState) << mIRate;
		for (unsigned in = 0; in <= 1; in++) {
			mCandidates[cand+in].iState = ((sp->iState) << 1) | in;
			mCandidates[cand+in].cost = sp->cost;
			uint32_t outputs = oStateShifted;
			for (unsigned out = 0; out < mIRate; out++) {
				char feedback = applyPoly(sp->rState[out], mCoeffsFB[out] ^ 1, mOrder+1);
				char rState = (((sp->rState[out]) ^ feedback) << 1) | in;
				mCandidates[cand+in].rState[out] = rState;
				outputs |= (mGeneratorTable[rState & mCMask] & (1 << (mIRate - out - 1)));
			}
			mCandidates[cand+in].oState = outputs;
		}
		sp++;
	}
}


void ViterbiTCH_AFS7_95::getSoftCostMetrics(const uint32_t inSample, const float *matchCost, const float *mismatchCost)
{
	const float *cTab[2] = {matchCost,mismatchCost};
	for (unsigned i=0; i<mNumCands; i++) {
		vCand& thisCand = mCandidates[i];
		const unsigned mismatched = inSample ^ (thisCand.oState);
		for (unsigned i = 0; i < mIRate; i++) {
			thisCand.cost += cTab[(mismatched>>i)&0x01][mIRate-i-1];
		}
	}
}


void ViterbiTCH_AFS7_95::pruneCandidates()
{
	const vCand* c1 = mCandidates;					// 0-prefix
	const vCand* c2 = mCandidates + mIStates;		// 1-prefix
	for (unsigned i=0; i<mIStates; i++) {
		if (c1[i].cost < c2[i].cost) mSurvivors[i] = c1[i];
		else mSurvivors[i] = c2[i];
	}
}


const ViterbiTCH_AFS7_95::vCand& ViterbiTCH_AFS7_95::minCost() const
{
	int minIndex = 0;
	float minCost = mSurvivors[0].cost;
	for (unsigned i=1; i<mIStates; i++) {
		const float thisCost = mSurvivors[i].cost;
		if (thisCost>=minCost) continue;
		minCost = thisCost;
		minIndex=i;
	}
	return mSurvivors[minIndex];
}


const ViterbiTCH_AFS7_95::vCand& ViterbiTCH_AFS7_95::step(uint32_t inSample, const float *probs, const float *iprobs)
{
	branchCandidates();
	getSoftCostMetrics(inSample,probs,iprobs);
	pruneCandidates();
	return minCost();
}



void ViterbiTCH_AFS7_95::decode(const SoftVector &in, BitVector& target)
{
	ViterbiTCH_AFS7_95 &decoder = *this;
	const size_t sz = in.size() - 18;
	const unsigned deferral = decoder.deferral();
	const size_t ctsz = sz + deferral*decoder.iRate();
	assert(sz == decoder.iRate()*target.size());

	// Build a "history" array where each element contains the full history.
	uint32_t history[ctsz];
	{
		BitVector bits = in.sliced();
		uint32_t accum = 0;
		for (size_t i=0; i<sz; i++) {
			accum = (accum<<1) | bits.bit(i);
			history[i] = accum;
		}
		// Repeat last bit at the end.
		for (size_t i=sz; i<ctsz; i++) {
			accum = (accum<<1) | (accum & 0x01);
			history[i] = accum;
		}
	}

	// Precompute metric tables.
	float matchCostTable[ctsz];
	float mismatchCostTable[ctsz];
	{
		const float *dp = in.begin();
		for (size_t i=0; i<sz; i++) {
			// pVal is the probability that a bit is correct.
			// ipVal is the probability that a bit is incorrect.
			float pVal = dp[i];
			if (pVal>0.5F) pVal = 1.0F-pVal;
			float ipVal = 1.0F-pVal;
			// This is a cheap approximation to an ideal cost function.
			if (pVal<0.01F) pVal = 0.01;
			if (ipVal<0.01F) ipVal = 0.01;
			matchCostTable[i] = 0.25F/ipVal;
			mismatchCostTable[i] = 0.25F/pVal;
		}
	
		// pad end of table with unknowns
		for (size_t i=sz; i<ctsz; i++) {
			matchCostTable[i] = 0.5F;
			mismatchCostTable[i] = 0.5F;
		}
	}

	{
		decoder.initializeStates();
		// Each sample of history[] carries its history.
		// So we only have to process every iRate-th sample.
		const unsigned step = decoder.iRate();
		// input pointer
		const uint32_t *ip = history + step - 1;
		// output pointers
		char *op = target.begin();
		const char *const opt = target.end();
		// table pointers
		const float* match = matchCostTable;
		const float* mismatch = mismatchCostTable;
		size_t oCount = 0;
		while (op<opt) {
			// Viterbi algorithm
			assert(match-matchCostTable<(int)(sizeof(matchCostTable)/sizeof(matchCostTable[0])-1));
			assert(mismatch-mismatchCostTable<(int)(sizeof(mismatchCostTable)/sizeof(mismatchCostTable[0])-1));
			const ViterbiTCH_AFS7_95::vCand &minCost = decoder.step(*ip, match, mismatch);
			ip += step;
			match += step;
			mismatch += step;
			// output
			if (oCount>=deferral) *op++ = (minCost.iState >> deferral)&0x01;
			oCount++;
		}
	}
}



ViterbiTCH_AFS7_4::ViterbiTCH_AFS7_4()
{
	assert(mDeferral < 32);
	mCoeffs[0] = 0x01b;
	mCoeffsFB[0] = 0x01f;
	mCoeffs[1] = 0x015;
	mCoeffsFB[1] = 0x01f;
	mCoeffs[2] = 0x01f;
	mCoeffsFB[2] = 0x01f;
	for (unsigned i = 0; i < mIRate; i++) {
		computeStateTables(i);
	}
	computeGeneratorTable();
}




void ViterbiTCH_AFS7_4::initializeStates()
{
	for (unsigned i=0; i<mIStates; i++) vitClear(mSurvivors[i]);
	for (unsigned i=0; i<mNumCands; i++) vitClear(mCandidates[i]);
}



void ViterbiTCH_AFS7_4::computeStateTables(unsigned g)
{
	assert(g<mIRate);
	for (unsigned state=0; state<mIStates; state++) {
		for (unsigned in = 0; in <= 1; in++) {
			uint32_t inputVal = (state<<1) | in;
			mStateTable[g][inputVal] = applyPoly(inputVal, mCoeffs[g] ^ mCoeffsFB[g], mOrder+1) ^ in;
		}
	}
}

void ViterbiTCH_AFS7_4::computeGeneratorTable()
{
	for (unsigned index=0; index<mIStates*2; index++) {
		uint32_t t = 0;
		for (unsigned i = 0; i < mIRate; i++) {
			t = (t << 1) | mStateTable[i][index];
		}
		mGeneratorTable[index] = t;
	}
}






void ViterbiTCH_AFS7_4::branchCandidates()
{
	// Branch to generate new input states.
	const vCand *sp = mSurvivors;
	for (unsigned cand=0; cand<mNumCands; cand+=2) {
		uint32_t oStateShifted = (sp->oState) << mIRate;
		for (unsigned in = 0; in <= 1; in++) {
			mCandidates[cand+in].iState = ((sp->iState) << 1) | in;
			mCandidates[cand+in].cost = sp->cost;
			uint32_t outputs = oStateShifted;
			for (unsigned out = 0; out < mIRate; out++) {
				char feedback = applyPoly(sp->rState[out], mCoeffsFB[out] ^ 1, mOrder+1);
				char rState = (((sp->rState[out]) ^ feedback) << 1) | in;
				mCandidates[cand+in].rState[out] = rState;
				outputs |= (mGeneratorTable[rState & mCMask] & (1 << (mIRate - out - 1)));
			}
			mCandidates[cand+in].oState = outputs;
		}
		sp++;
	}
}


void ViterbiTCH_AFS7_4::getSoftCostMetrics(const uint32_t inSample, const float *matchCost, const float *mismatchCost)
{
	const float *cTab[2] = {matchCost,mismatchCost};
	for (unsigned i=0; i<mNumCands; i++) {
		vCand& thisCand = mCandidates[i];
		const unsigned mismatched = inSample ^ (thisCand.oState);
		for (unsigned i = 0; i < mIRate; i++) {
			thisCand.cost += cTab[(mismatched>>i)&0x01][mIRate-i-1];
		}
	}
}


void ViterbiTCH_AFS7_4::pruneCandidates()
{
	const vCand* c1 = mCandidates;					// 0-prefix
	const vCand* c2 = mCandidates + mIStates;		// 1-prefix
	for (unsigned i=0; i<mIStates; i++) {
		if (c1[i].cost < c2[i].cost) mSurvivors[i] = c1[i];
		else mSurvivors[i] = c2[i];
	}
}


const ViterbiTCH_AFS7_4::vCand& ViterbiTCH_AFS7_4::minCost() const
{
	int minIndex = 0;
	float minCost = mSurvivors[0].cost;
	for (unsigned i=1; i<mIStates; i++) {
		const float thisCost = mSurvivors[i].cost;
		if (thisCost>=minCost) continue;
		minCost = thisCost;
		minIndex=i;
	}
	return mSurvivors[minIndex];
}


const ViterbiTCH_AFS7_4::vCand& ViterbiTCH_AFS7_4::step(uint32_t inSample, const float *probs, const float *iprobs)
{
	branchCandidates();
	getSoftCostMetrics(inSample,probs,iprobs);
	pruneCandidates();
	return minCost();
}



void ViterbiTCH_AFS7_4::decode(const SoftVector &in, BitVector& target)
{
	ViterbiTCH_AFS7_4 &decoder = *this;
	const size_t sz = in.size() - 12;
	const unsigned deferral = decoder.deferral();
	const size_t ctsz = sz + deferral*decoder.iRate();
	assert(sz == decoder.iRate()*target.size());

	// Build a "history" array where each element contains the full history.
	uint32_t history[ctsz];
	{
		BitVector bits = in.sliced();
		uint32_t accum = 0;
		for (size_t i=0; i<sz; i++) {
			accum = (accum<<1) | bits.bit(i);
			history[i] = accum;
		}
		// Repeat last bit at the end.
		for (size_t i=sz; i<ctsz; i++) {
			accum = (accum<<1) | (accum & 0x01);
			history[i] = accum;
		}
	}

	// Precompute metric tables.
	float matchCostTable[ctsz];
	float mismatchCostTable[ctsz];
	{
		const float *dp = in.begin();
		for (size_t i=0; i<sz; i++) {
			// pVal is the probability that a bit is correct.
			// ipVal is the probability that a bit is incorrect.
			float pVal = dp[i];
			if (pVal>0.5F) pVal = 1.0F-pVal;
			float ipVal = 1.0F-pVal;
			// This is a cheap approximation to an ideal cost function.
			if (pVal<0.01F) pVal = 0.01;
			if (ipVal<0.01F) ipVal = 0.01;
			matchCostTable[i] = 0.25F/ipVal;
			mismatchCostTable[i] = 0.25F/pVal;
		}
	
		// pad end of table with unknowns
		for (size_t i=sz; i<ctsz; i++) {
			matchCostTable[i] = 0.5F;
			mismatchCostTable[i] = 0.5F;
		}
	}

	{
		decoder.initializeStates();
		// Each sample of history[] carries its history.
		// So we only have to process every iRate-th sample.
		const unsigned step = decoder.iRate();
		// input pointer
		const uint32_t *ip = history + step - 1;
		// output pointers
		char *op = target.begin();
		const char *const opt = target.end();
		// table pointers
		const float* match = matchCostTable;
		const float* mismatch = mismatchCostTable;
		size_t oCount = 0;
		while (op<opt) {
			// Viterbi algorithm
			assert(match-matchCostTable<(int)(sizeof(matchCostTable)/sizeof(matchCostTable[0])-1));
			assert(mismatch-mismatchCostTable<(int)(sizeof(mismatchCostTable)/sizeof(mismatchCostTable[0])-1));
			const ViterbiTCH_AFS7_4::vCand &minCost = decoder.step(*ip, match, mismatch);
			ip += step;
			match += step;
			mismatch += step;
			// output
			if (oCount>=deferral) *op++ = (minCost.iState >> deferral)&0x01;
			oCount++;
		}
	}
}



ViterbiTCH_AFS6_7::ViterbiTCH_AFS6_7()
{
	assert(mDeferral < 32);
	mCoeffs[0] = 0x01b;
	mCoeffsFB[0] = 0x01f;
	mCoeffs[1] = 0x015;
	mCoeffsFB[1] = 0x01f;
	mCoeffs[2] = 0x01f;
	mCoeffsFB[2] = 0x01f;
	mCoeffs[3] = 0x01f;
	mCoeffsFB[3] = 0x01f;
	for (unsigned i = 0; i < mIRate; i++) {
		computeStateTables(i);
	}
	computeGeneratorTable();
}




void ViterbiTCH_AFS6_7::initializeStates()
{
	for (unsigned i=0; i<mIStates; i++) vitClear(mSurvivors[i]);
	for (unsigned i=0; i<mNumCands; i++) vitClear(mCandidates[i]);
}



void ViterbiTCH_AFS6_7::computeStateTables(unsigned g)
{
	assert(g<mIRate);
	for (unsigned state=0; state<mIStates; state++) {
		for (unsigned in = 0; in <= 1; in++) {
			uint32_t inputVal = (state<<1) | in;
			mStateTable[g][inputVal] = applyPoly(inputVal, mCoeffs[g] ^ mCoeffsFB[g], mOrder+1) ^ in;
		}
	}
}

void ViterbiTCH_AFS6_7::computeGeneratorTable()
{
	for (unsigned index=0; index<mIStates*2; index++) {
		uint32_t t = 0;
		for (unsigned i = 0; i < mIRate; i++) {
			t = (t << 1) | mStateTable[i][index];
		}
		mGeneratorTable[index] = t;
	}
}






void ViterbiTCH_AFS6_7::branchCandidates()
{
	// Branch to generate new input states.
	const vCand *sp = mSurvivors;
	for (unsigned cand=0; cand<mNumCands; cand+=2) {
		uint32_t oStateShifted = (sp->oState) << mIRate;
		for (unsigned in = 0; in <= 1; in++) {
			mCandidates[cand+in].iState = ((sp->iState) << 1) | in;
			mCandidates[cand+in].cost = sp->cost;
			uint32_t outputs = oStateShifted;
			for (unsigned out = 0; out < mIRate; out++) {
				char feedback = applyPoly(sp->rState[out], mCoeffsFB[out] ^ 1, mOrder+1);
				char rState = (((sp->rState[out]) ^ feedback) << 1) | in;
				mCandidates[cand+in].rState[out] = rState;
				outputs |= (mGeneratorTable[rState & mCMask] & (1 << (mIRate - out - 1)));
			}
			mCandidates[cand+in].oState = outputs;
		}
		sp++;
	}
}


void ViterbiTCH_AFS6_7::getSoftCostMetrics(const uint32_t inSample, const float *matchCost, const float *mismatchCost)
{
	const float *cTab[2] = {matchCost,mismatchCost};
	for (unsigned i=0; i<mNumCands; i++) {
		vCand& thisCand = mCandidates[i];
		const unsigned mismatched = inSample ^ (thisCand.oState);
		for (unsigned i = 0; i < mIRate; i++) {
			thisCand.cost += cTab[(mismatched>>i)&0x01][mIRate-i-1];
		}
	}
}


void ViterbiTCH_AFS6_7::pruneCandidates()
{
	const vCand* c1 = mCandidates;					// 0-prefix
	const vCand* c2 = mCandidates + mIStates;		// 1-prefix
	for (unsigned i=0; i<mIStates; i++) {
		if (c1[i].cost < c2[i].cost) mSurvivors[i] = c1[i];
		else mSurvivors[i] = c2[i];
	}
}


const ViterbiTCH_AFS6_7::vCand& ViterbiTCH_AFS6_7::minCost() const
{
	int minIndex = 0;
	float minCost = mSurvivors[0].cost;
	for (unsigned i=1; i<mIStates; i++) {
		const float thisCost = mSurvivors[i].cost;
		if (thisCost>=minCost) continue;
		minCost = thisCost;
		minIndex=i;
	}
	return mSurvivors[minIndex];
}


const ViterbiTCH_AFS6_7::vCand& ViterbiTCH_AFS6_7::step(uint32_t inSample, const float *probs, const float *iprobs)
{
	branchCandidates();
	getSoftCostMetrics(inSample,probs,iprobs);
	pruneCandidates();
	return minCost();
}



void ViterbiTCH_AFS6_7::decode(const SoftVector &in, BitVector& target)
{
	ViterbiTCH_AFS6_7 &decoder = *this;
	const size_t sz = in.size() - 16;
	const unsigned deferral = decoder.deferral();
	const size_t ctsz = sz + deferral*decoder.iRate();
	assert(sz == decoder.iRate()*target.size());

	// Build a "history" array where each element contains the full history.
	uint32_t history[ctsz];
	{
		BitVector bits = in.sliced();
		uint32_t accum = 0;
		for (size_t i=0; i<sz; i++) {
			accum = (accum<<1) | bits.bit(i);
			history[i] = accum;
		}
		// Repeat last bit at the end.
		for (size_t i=sz; i<ctsz; i++) {
			accum = (accum<<1) | (accum & 0x01);
			history[i] = accum;
		}
	}

	// Precompute metric tables.
	float matchCostTable[ctsz];
	float mismatchCostTable[ctsz];
	{
		const float *dp = in.begin();
		for (size_t i=0; i<sz; i++) {
			// pVal is the probability that a bit is correct.
			// ipVal is the probability that a bit is incorrect.
			float pVal = dp[i];
			if (pVal>0.5F) pVal = 1.0F-pVal;
			float ipVal = 1.0F-pVal;
			// This is a cheap approximation to an ideal cost function.
			if (pVal<0.01F) pVal = 0.01;
			if (ipVal<0.01F) ipVal = 0.01;
			matchCostTable[i] = 0.25F/ipVal;
			mismatchCostTable[i] = 0.25F/pVal;
		}
	
		// pad end of table with unknowns
		for (size_t i=sz; i<ctsz; i++) {
			matchCostTable[i] = 0.5F;
			mismatchCostTable[i] = 0.5F;
		}
	}

	{
		decoder.initializeStates();
		// Each sample of history[] carries its history.
		// So we only have to process every iRate-th sample.
		const unsigned step = decoder.iRate();
		// input pointer
		const uint32_t *ip = history + step - 1;
		// output pointers
		char *op = target.begin();
		const char *const opt = target.end();
		// table pointers
		const float* match = matchCostTable;
		const float* mismatch = mismatchCostTable;
		size_t oCount = 0;
		while (op<opt) {
			// Viterbi algorithm
			assert(match-matchCostTable<(int)(sizeof(matchCostTable)/sizeof(matchCostTable[0])-1));
			assert(mismatch-mismatchCostTable<(int)(sizeof(mismatchCostTable)/sizeof(mismatchCostTable[0])-1));
			const ViterbiTCH_AFS6_7::vCand &minCost = decoder.step(*ip, match, mismatch);
			ip += step;
			match += step;
			mismatch += step;
			// output
			if (oCount>=deferral) *op++ = (minCost.iState >> deferral)&0x01;
			oCount++;
		}
	}
}



ViterbiTCH_AFS5_9::ViterbiTCH_AFS5_9()
{
	assert(mDeferral < 32);
	mCoeffs[0] = 0x06d;
	mCoeffsFB[0] = 0x05f;
	mCoeffs[1] = 0x053;
	mCoeffsFB[1] = 0x05f;
	mCoeffs[2] = 0x05f;
	mCoeffsFB[2] = 0x05f;
	mCoeffs[3] = 0x05f;
	mCoeffsFB[3] = 0x05f;
	for (unsigned i = 0; i < mIRate; i++) {
		computeStateTables(i);
	}
	computeGeneratorTable();
}




void ViterbiTCH_AFS5_9::initializeStates()
{
	for (unsigned i=0; i<mIStates; i++) vitClear(mSurvivors[i]);
	for (unsigned i=0; i<mNumCands; i++) vitClear(mCandidates[i]);
}



void ViterbiTCH_AFS5_9::computeStateTables(unsigned g)
{
	assert(g<mIRate);
	for (unsigned state=0; state<mIStates; state++) {
		for (unsigned in = 0; in <= 1; in++) {
			uint32_t inputVal = (state<<1) | in;
			mStateTable[g][inputVal] = applyPoly(inputVal, mCoeffs[g] ^ mCoeffsFB[g], mOrder+1) ^ in;
		}
	}
}

void ViterbiTCH_AFS5_9::computeGeneratorTable()
{
	for (unsigned index=0; index<mIStates*2; index++) {
		uint32_t t = 0;
		for (unsigned i = 0; i < mIRate; i++) {
			t = (t << 1) | mStateTable[i][index];
		}
		mGeneratorTable[index] = t;
	}
}






void ViterbiTCH_AFS5_9::branchCandidates()
{
	// Branch to generate new input states.
	const vCand *sp = mSurvivors;
	for (unsigned cand=0; cand<mNumCands; cand+=2) {
		uint32_t oStateShifted = (sp->oState) << mIRate;
		for (unsigned in = 0; in <= 1; in++) {
			mCandidates[cand+in].iState = ((sp->iState) << 1) | in;
			mCandidates[cand+in].cost = sp->cost;
			uint32_t outputs = oStateShifted;
			for (unsigned out = 0; out < mIRate; out++) {
				char feedback = applyPoly(sp->rState[out], mCoeffsFB[out] ^ 1, mOrder+1);
				char rState = (((sp->rState[out]) ^ feedback) << 1) | in;
				mCandidates[cand+in].rState[out] = rState;
				outputs |= (mGeneratorTable[rState & mCMask] & (1 << (mIRate - out - 1)));
			}
			mCandidates[cand+in].oState = outputs;
		}
		sp++;
	}
}


void ViterbiTCH_AFS5_9::getSoftCostMetrics(const uint32_t inSample, const float *matchCost, const float *mismatchCost)
{
	const float *cTab[2] = {matchCost,mismatchCost};
	for (unsigned i=0; i<mNumCands; i++) {
		vCand& thisCand = mCandidates[i];
		const unsigned mismatched = inSample ^ (thisCand.oState);
		for (unsigned i = 0; i < mIRate; i++) {
			thisCand.cost += cTab[(mismatched>>i)&0x01][mIRate-i-1];
		}
	}
}


void ViterbiTCH_AFS5_9::pruneCandidates()
{
	const vCand* c1 = mCandidates;					// 0-prefix
	const vCand* c2 = mCandidates + mIStates;		// 1-prefix
	for (unsigned i=0; i<mIStates; i++) {
		if (c1[i].cost < c2[i].cost) mSurvivors[i] = c1[i];
		else mSurvivors[i] = c2[i];
	}
}


const ViterbiTCH_AFS5_9::vCand& ViterbiTCH_AFS5_9::minCost() const
{
	int minIndex = 0;
	float minCost = mSurvivors[0].cost;
	for (unsigned i=1; i<mIStates; i++) {
		const float thisCost = mSurvivors[i].cost;
		if (thisCost>=minCost) continue;
		minCost = thisCost;
		minIndex=i;
	}
	return mSurvivors[minIndex];
}


const ViterbiTCH_AFS5_9::vCand& ViterbiTCH_AFS5_9::step(uint32_t inSample, const float *probs, const float *iprobs)
{
	branchCandidates();
	getSoftCostMetrics(inSample,probs,iprobs);
	pruneCandidates();
	return minCost();
}



void ViterbiTCH_AFS5_9::decode(const SoftVector &in, BitVector& target)
{
	ViterbiTCH_AFS5_9 &decoder = *this;
	const size_t sz = in.size() - 24;
	const unsigned deferral = decoder.deferral();
	const size_t ctsz = sz + deferral*decoder.iRate();
	assert(sz == decoder.iRate()*target.size());

	// Build a "history" array where each element contains the full history.
	uint32_t history[ctsz];
	{
		BitVector bits = in.sliced();
		uint32_t accum = 0;
		for (size_t i=0; i<sz; i++) {
			accum = (accum<<1) | bits.bit(i);
			history[i] = accum;
		}
		// Repeat last bit at the end.
		for (size_t i=sz; i<ctsz; i++) {
			accum = (accum<<1) | (accum & 0x01);
			history[i] = accum;
		}
	}

	// Precompute metric tables.
	float matchCostTable[ctsz];
	float mismatchCostTable[ctsz];
	{
		const float *dp = in.begin();
		for (size_t i=0; i<sz; i++) {
			// pVal is the probability that a bit is correct.
			// ipVal is the probability that a bit is incorrect.
			float pVal = dp[i];
			if (pVal>0.5F) pVal = 1.0F-pVal;
			float ipVal = 1.0F-pVal;
			// This is a cheap approximation to an ideal cost function.
			if (pVal<0.01F) pVal = 0.01;
			if (ipVal<0.01F) ipVal = 0.01;
			matchCostTable[i] = 0.25F/ipVal;
			mismatchCostTable[i] = 0.25F/pVal;
		}
	
		// pad end of table with unknowns
		for (size_t i=sz; i<ctsz; i++) {
			matchCostTable[i] = 0.5F;
			mismatchCostTable[i] = 0.5F;
		}
	}

	{
		decoder.initializeStates();
		// Each sample of history[] carries its history.
		// So we only have to process every iRate-th sample.
		const unsigned step = decoder.iRate();
		// input pointer
		const uint32_t *ip = history + step - 1;
		// output pointers
		char *op = target.begin();
		const char *const opt = target.end();
		// table pointers
		const float* match = matchCostTable;
		const float* mismatch = mismatchCostTable;
		size_t oCount = 0;
		while (op<opt) {
			// Viterbi algorithm
			assert(match-matchCostTable<(int)(sizeof(matchCostTable)/sizeof(matchCostTable[0])-1));
			assert(mismatch-mismatchCostTable<(int)(sizeof(mismatchCostTable)/sizeof(mismatchCostTable[0])-1));
			const ViterbiTCH_AFS5_9::vCand &minCost = decoder.step(*ip, match, mismatch);
			ip += step;
			match += step;
			mismatch += step;
			// output
			if (oCount>=deferral) *op++ = (minCost.iState >> deferral)&0x01;
			oCount++;
		}
	}
}



ViterbiTCH_AFS5_15::ViterbiTCH_AFS5_15()
{
	assert(mDeferral < 32);
	mCoeffs[0] = 0x01b;
	mCoeffsFB[0] = 0x01f;
	mCoeffs[1] = 0x01b;
	mCoeffsFB[1] = 0x01f;
	mCoeffs[2] = 0x015;
	mCoeffsFB[2] = 0x01f;
	mCoeffs[3] = 0x01f;
	mCoeffsFB[3] = 0x01f;
	mCoeffs[4] = 0x01f;
	mCoeffsFB[4] = 0x01f;
	for (unsigned i = 0; i < mIRate; i++) {
		computeStateTables(i);
	}
	computeGeneratorTable();
}




void ViterbiTCH_AFS5_15::initializeStates()
{
	for (unsigned i=0; i<mIStates; i++) vitClear(mSurvivors[i]);
	for (unsigned i=0; i<mNumCands; i++) vitClear(mCandidates[i]);
}



void ViterbiTCH_AFS5_15::computeStateTables(unsigned g)
{
	assert(g<mIRate);
	for (unsigned state=0; state<mIStates; state++) {
		for (unsigned in = 0; in <= 1; in++) {
			uint32_t inputVal = (state<<1) | in;
			mStateTable[g][inputVal] = applyPoly(inputVal, mCoeffs[g] ^ mCoeffsFB[g], mOrder+1) ^ in;
		}
	}
}

void ViterbiTCH_AFS5_15::computeGeneratorTable()
{
	for (unsigned index=0; index<mIStates*2; index++) {
		uint32_t t = 0;
		for (unsigned i = 0; i < mIRate; i++) {
			t = (t << 1) | mStateTable[i][index];
		}
		mGeneratorTable[index] = t;
	}
}






void ViterbiTCH_AFS5_15::branchCandidates()
{
	// Branch to generate new input states.
	const vCand *sp = mSurvivors;
	for (unsigned cand=0; cand<mNumCands; cand+=2) {
		uint32_t oStateShifted = (sp->oState) << mIRate;
		for (unsigned in = 0; in <= 1; in++) {
			mCandidates[cand+in].iState = ((sp->iState) << 1) | in;
			mCandidates[cand+in].cost = sp->cost;
			uint32_t outputs = oStateShifted;
			for (unsigned out = 0; out < mIRate; out++) {
				char feedback = applyPoly(sp->rState[out], mCoeffsFB[out] ^ 1, mOrder+1);
				char rState = (((sp->rState[out]) ^ feedback) << 1) | in;
				mCandidates[cand+in].rState[out] = rState;
				outputs |= (mGeneratorTable[rState & mCMask] & (1 << (mIRate - out - 1)));
			}
			mCandidates[cand+in].oState = outputs;
		}
		sp++;
	}
}


void ViterbiTCH_AFS5_15::getSoftCostMetrics(const uint32_t inSample, const float *matchCost, const float *mismatchCost)
{
	const float *cTab[2] = {matchCost,mismatchCost};
	for (unsigned i=0; i<mNumCands; i++) {
		vCand& thisCand = mCandidates[i];
		const unsigned mismatched = inSample ^ (thisCand.oState);
		for (unsigned i = 0; i < mIRate; i++) {
			thisCand.cost += cTab[(mismatched>>i)&0x01][mIRate-i-1];
		}
	}
}


void ViterbiTCH_AFS5_15::pruneCandidates()
{
	const vCand* c1 = mCandidates;					// 0-prefix
	const vCand* c2 = mCandidates + mIStates;		// 1-prefix
	for (unsigned i=0; i<mIStates; i++) {
		if (c1[i].cost < c2[i].cost) mSurvivors[i] = c1[i];
		else mSurvivors[i] = c2[i];
	}
}


const ViterbiTCH_AFS5_15::vCand& ViterbiTCH_AFS5_15::minCost() const
{
	int minIndex = 0;
	float minCost = mSurvivors[0].cost;
	for (unsigned i=1; i<mIStates; i++) {
		const float thisCost = mSurvivors[i].cost;
		if (thisCost>=minCost) continue;
		minCost = thisCost;
		minIndex=i;
	}
	return mSurvivors[minIndex];
}


const ViterbiTCH_AFS5_15::vCand& ViterbiTCH_AFS5_15::step(uint32_t inSample, const float *probs, const float *iprobs)
{
	branchCandidates();
	getSoftCostMetrics(inSample,probs,iprobs);
	pruneCandidates();
	return minCost();
}



void ViterbiTCH_AFS5_15::decode(const SoftVector &in, BitVector& target)
{
	ViterbiTCH_AFS5_15 &decoder = *this;
	const size_t sz = in.size() - 20;
	const unsigned deferral = decoder.deferral();
	const size_t ctsz = sz + deferral*decoder.iRate();
	assert(sz == decoder.iRate()*target.size());

	// Build a "history" array where each element contains the full history.
	uint32_t history[ctsz];
	{
		BitVector bits = in.sliced();
		uint32_t accum = 0;
		for (size_t i=0; i<sz; i++) {
			accum = (accum<<1) | bits.bit(i);
			history[i] = accum;
		}
		// Repeat last bit at the end.
		for (size_t i=sz; i<ctsz; i++) {
			accum = (accum<<1) | (accum & 0x01);
			history[i] = accum;
		}
	}

	// Precompute metric tables.
	float matchCostTable[ctsz];
	float mismatchCostTable[ctsz];
	{
		const float *dp = in.begin();
		for (size_t i=0; i<sz; i++) {
			// pVal is the probability that a bit is correct.
			// ipVal is the probability that a bit is incorrect.
			float pVal = dp[i];
			if (pVal>0.5F) pVal = 1.0F-pVal;
			float ipVal = 1.0F-pVal;
			// This is a cheap approximation to an ideal cost function.
			if (pVal<0.01F) pVal = 0.01;
			if (ipVal<0.01F) ipVal = 0.01;
			matchCostTable[i] = 0.25F/ipVal;
			mismatchCostTable[i] = 0.25F/pVal;
		}
	
		// pad end of table with unknowns
		for (size_t i=sz; i<ctsz; i++) {
			matchCostTable[i] = 0.5F;
			mismatchCostTable[i] = 0.5F;
		}
	}

	{
		decoder.initializeStates();
		// Each sample of history[] carries its history.
		// So we only have to process every iRate-th sample.
		const unsigned step = decoder.iRate();
		// input pointer
		const uint32_t *ip = history + step - 1;
		// output pointers
		char *op = target.begin();
		const char *const opt = target.end();
		// table pointers
		const float* match = matchCostTable;
		const float* mismatch = mismatchCostTable;
		size_t oCount = 0;
		while (op<opt) {
			// Viterbi algorithm
			assert(match-matchCostTable<(int)(sizeof(matchCostTable)/sizeof(matchCostTable[0])-1));
			assert(mismatch-mismatchCostTable<(int)(sizeof(mismatchCostTable)/sizeof(mismatchCostTable[0])-1));
			const ViterbiTCH_AFS5_15::vCand &minCost = decoder.step(*ip, match, mismatch);
			ip += step;
			match += step;
			mismatch += step;
			// output
			if (oCount>=deferral) *op++ = (minCost.iState >> deferral)&0x01;
			oCount++;
		}
	}
}



ViterbiTCH_AFS4_75::ViterbiTCH_AFS4_75()
{
	assert(mDeferral < 32);
	mCoeffs[0] = 0x06d;
	mCoeffsFB[0] = 0x05f;
	mCoeffs[1] = 0x06d;
	mCoeffsFB[1] = 0x05f;
	mCoeffs[2] = 0x053;
	mCoeffsFB[2] = 0x05f;
	mCoeffs[3] = 0x05f;
	mCoeffsFB[3] = 0x05f;
	mCoeffs[4] = 0x05f;
	mCoeffsFB[4] = 0x05f;
	for (unsigned i = 0; i < mIRate; i++) {
		computeStateTables(i);
	}
	computeGeneratorTable();
}




void ViterbiTCH_AFS4_75::initializeStates()
{
	for (unsigned i=0; i<mIStates; i++) vitClear(mSurvivors[i]);
	for (unsigned i=0; i<mNumCands; i++) vitClear(mCandidates[i]);
}



void ViterbiTCH_AFS4_75::computeStateTables(unsigned g)
{
	assert(g<mIRate);
	for (unsigned state=0; state<mIStates; state++) {
		for (unsigned in = 0; in <= 1; in++) {
			uint32_t inputVal = (state<<1) | in;
			mStateTable[g][inputVal] = applyPoly(inputVal, mCoeffs[g] ^ mCoeffsFB[g], mOrder+1) ^ in;
		}
	}
}

void ViterbiTCH_AFS4_75::computeGeneratorTable()
{
	for (unsigned index=0; index<mIStates*2; index++) {
		uint32_t t = 0;
		for (unsigned i = 0; i < mIRate; i++) {
			t = (t << 1) | mStateTable[i][index];
		}
		mGeneratorTable[index] = t;
	}
}






void ViterbiTCH_AFS4_75::branchCandidates()
{
	// Branch to generate new input states.
	const vCand *sp = mSurvivors;
	for (unsigned cand=0; cand<mNumCands; cand+=2) {
		uint32_t oStateShifted = (sp->oState) << mIRate;
		for (unsigned in = 0; in <= 1; in++) {
			mCandidates[cand+in].iState = ((sp->iState) << 1) | in;
			mCandidates[cand+in].cost = sp->cost;
			uint32_t outputs = oStateShifted;
			for (unsigned out = 0; out < mIRate; out++) {
				char feedback = applyPoly(sp->rState[out], mCoeffsFB[out] ^ 1, mOrder+1);
				char rState = (((sp->rState[out]) ^ feedback) << 1) | in;
				mCandidates[cand+in].rState[out] = rState;
				outputs |= (mGeneratorTable[rState & mCMask] & (1 << (mIRate - out - 1)));
			}
			mCandidates[cand+in].oState = outputs;
		}
		sp++;
	}
}


void ViterbiTCH_AFS4_75::getSoftCostMetrics(const uint32_t inSample, const float *matchCost, const float *mismatchCost)
{
	const float *cTab[2] = {matchCost,mismatchCost};
	for (unsigned i=0; i<mNumCands; i++) {
		vCand& thisCand = mCandidates[i];
		const unsigned mismatched = inSample ^ (thisCand.oState);
		for (unsigned i = 0; i < mIRate; i++) {
			thisCand.cost += cTab[(mismatched>>i)&0x01][mIRate-i-1];
		}
	}
}


void ViterbiTCH_AFS4_75::pruneCandidates()
{
	const vCand* c1 = mCandidates;					// 0-prefix
	const vCand* c2 = mCandidates + mIStates;		// 1-prefix
	for (unsigned i=0; i<mIStates; i++) {
		if (c1[i].cost < c2[i].cost) mSurvivors[i] = c1[i];
		else mSurvivors[i] = c2[i];
	}
}


const ViterbiTCH_AFS4_75::vCand& ViterbiTCH_AFS4_75::minCost() const
{
	int minIndex = 0;
	float minCost = mSurvivors[0].cost;
	for (unsigned i=1; i<mIStates; i++) {
		const float thisCost = mSurvivors[i].cost;
		if (thisCost>=minCost) continue;
		minCost = thisCost;
		minIndex=i;
	}
	return mSurvivors[minIndex];
}


const ViterbiTCH_AFS4_75::vCand& ViterbiTCH_AFS4_75::step(uint32_t inSample, const float *probs, const float *iprobs)
{
	branchCandidates();
	getSoftCostMetrics(inSample,probs,iprobs);
	pruneCandidates();
	return minCost();
}



void ViterbiTCH_AFS4_75::decode(const SoftVector &in, BitVector& target)
{
	ViterbiTCH_AFS4_75 &decoder = *this;
	const size_t sz = in.size() - 30;
	const unsigned deferral = decoder.deferral();
	const size_t ctsz = sz + deferral*decoder.iRate();
	assert(sz == decoder.iRate()*target.size());

	// Build a "history" array where each element contains the full history.
	uint32_t history[ctsz];
	{
		BitVector bits = in.sliced();
		uint32_t accum = 0;
		for (size_t i=0; i<sz; i++) {
			accum = (accum<<1) | bits.bit(i);
			history[i] = accum;
		}
		// Repeat last bit at the end.
		for (size_t i=sz; i<ctsz; i++) {
			accum = (accum<<1) | (accum & 0x01);
			history[i] = accum;
		}
	}

	// Precompute metric tables.
	float matchCostTable[ctsz];
	float mismatchCostTable[ctsz];
	{
		const float *dp = in.begin();
		for (size_t i=0; i<sz; i++) {
			// pVal is the probability that a bit is correct.
			// ipVal is the probability that a bit is incorrect.
			float pVal = dp[i];
			if (pVal>0.5F) pVal = 1.0F-pVal;
			float ipVal = 1.0F-pVal;
			// This is a cheap approximation to an ideal cost function.
			if (pVal<0.01F) pVal = 0.01;
			if (ipVal<0.01F) ipVal = 0.01;
			matchCostTable[i] = 0.25F/ipVal;
			mismatchCostTable[i] = 0.25F/pVal;
		}
	
		// pad end of table with unknowns
		for (size_t i=sz; i<ctsz; i++) {
			matchCostTable[i] = 0.5F;
			mismatchCostTable[i] = 0.5F;
		}
	}

	{
		decoder.initializeStates();
		// Each sample of history[] carries its history.
		// So we only have to process every iRate-th sample.
		const unsigned step = decoder.iRate();
		// input pointer
		const uint32_t *ip = history + step - 1;
		// output pointers
		char *op = target.begin();
		const char *const opt = target.end();
		// table pointers
		const float* match = matchCostTable;
		const float* mismatch = mismatchCostTable;
		size_t oCount = 0;
		while (op<opt) {
			// Viterbi algorithm
			assert(match-matchCostTable<(int)(sizeof(matchCostTable)/sizeof(matchCostTable[0])-1));
			assert(mismatch-mismatchCostTable<(int)(sizeof(mismatchCostTable)/sizeof(mismatchCostTable[0])-1));
			const ViterbiTCH_AFS4_75::vCand &minCost = decoder.step(*ip, match, mismatch);
			ip += step;
			match += step;
			mismatch += step;
			// output
			if (oCount>=deferral) *op++ = (minCost.iState >> deferral)&0x01;
			oCount++;
		}
	}
}



