diff --git a/lib/decoding/AmrCoder.cpp b/lib/decoding/AmrCoder.cpp
new file mode 100644
index 0000000..d02e69c
--- /dev/null
+++ b/lib/decoding/AmrCoder.cpp
@@ -0,0 +1,1887 @@
+/*
+* Copyright 2013, 2014 Range Networks, Inc.
+*
+* This software is distributed under multiple licenses;
+* see the COPYING file in the main directory for licensing
+* information for this specific distribution.
+*
+* This use of this software may be subject to additional restrictions.
+* See the LEGAL file in the main directory for details.
+
+    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.
+
+*/
+
+
+#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++;
+		}
+	}
+}
+
+
+
diff --git a/lib/decoding/AmrCoder.h b/lib/decoding/AmrCoder.h
new file mode 100644
index 0000000..c1df823
--- /dev/null
+++ b/lib/decoding/AmrCoder.h
@@ -0,0 +1,936 @@
+/*
+* Copyright 2013, 2014 Range Networks, Inc.
+*
+* This software is distributed under multiple licenses;
+* see the COPYING file in the main directory for licensing
+* information for this specific distribution.
+*
+* This use of this software may be subject to additional restrictions.
+* See the LEGAL file in the main directory for details.
+
+    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.
+
+*/
+#ifndef _AMRCODER_H_
+#define _AMRCODER_H_
+#include <stdint.h>
+#include "BitVector.h"
+#include "Viterbi.h"
+
+
+
+/**
+	Class to represent recursive systematic convolutional coders/decoders of rate 1/2, memory length 4.
+*/
+class ViterbiTCH_AFS12_2 : public ViterbiBase {
+
+	private:
+		/**name Lots of precomputed elements so the compiler can optimize like hell. */
+		//@{
+		/**@name Core values. */
+		//@{
+		static const unsigned mIRate = 2;	///< reciprocal of rate
+		static const unsigned mOrder = 4;	///< memory length of generators
+		//@}
+		/**@name Derived values. */
+		//@{
+		static const unsigned mIStates = 0x01 << mOrder;	///< number of states, number of survivors
+		static const uint32_t mSMask = mIStates-1;			///< survivor mask
+		static const uint32_t mCMask = (mSMask<<1) | 0x01;	///< candidate mask
+		static const uint32_t mOMask = (0x01<<mIRate)-1;	///< ouput mask, all iRate low bits set
+		static const unsigned mNumCands = mIStates*2;		///< number of candidates to generate during branching
+		static const unsigned mDeferral = 6*mOrder;			///< deferral to be used
+		//@}
+		//@}
+
+		/** Precomputed tables. */
+		//@{
+		uint32_t mCoeffs[mIRate];					///< output polynomial for each generator
+		uint32_t mCoeffsFB[mIRate];					///< feedback polynomial for each generator
+		uint32_t mStateTable[mIRate][2*mIStates];	///< precomputed generator output tables
+		uint32_t mGeneratorTable[2*mIStates];		///< precomputed coder output table
+		//@}
+	
+	public:
+
+		/**
+		  A candidate sequence in a Viterbi decoder.
+		  The 32-bit state register can support a deferral of 6 with a 4th-order coder.
+		 */
+		typedef struct candStruct {
+			uint32_t iState;	///< encoder input associated with this candidate
+			uint32_t oState;	///< encoder output associated with this candidate
+			char rState[mIRate];///< real states of encoders associated with this candidate
+			float cost;			///< cost (metric value), float to support soft inputs
+		} vCand;
+
+		/** Clear a structure. */
+		void vitClear(vCand& v)
+		{
+			v.iState=0;
+			v.oState=0;
+			v.cost=0;
+			for (unsigned i = 0; i < mIRate; i++) v.rState[i] = 0;
+		}
+		
+
+	private:
+
+		/**@name Survivors and candidates. */
+		//@{
+		vCand mSurvivors[mIStates];			///< current survivor pool
+		vCand mCandidates[2*mIStates];		///< current candidate pool
+		//@}
+
+	public:
+
+		unsigned iRate() const { return mIRate; }
+		uint32_t cMask() const { return mCMask; }
+		uint32_t stateTable(unsigned g, unsigned i) const { return mStateTable[g][i]; }
+		unsigned deferral() const { return mDeferral; }
+		
+
+		ViterbiTCH_AFS12_2();
+
+		/** Set all cost metrics to zero. */
+		void initializeStates();
+
+		/**
+			Full cycle of the Viterbi algorithm: branch, metrics, prune, select.
+			@return reference to minimum-cost candidate.
+		*/
+		const vCand& step(uint32_t inSample, const float *probs, const float *iprobs);
+
+	private:
+
+		/** Branch survivors into new candidates. */
+		void branchCandidates();
+
+		/** Compute cost metrics for soft-inputs. */
+		void getSoftCostMetrics(uint32_t inSample, const float *probs, const float *iprobs);
+
+		/** Select survivors from the candidate set. */
+		void pruneCandidates();
+
+		/** Find the minimum cost survivor. */
+		const vCand& minCost() const;
+
+		/**
+			Precompute the state tables.
+			@param g Generator index 0..((1/rate)-1)
+		*/
+		void computeStateTables(unsigned g);
+
+		/**
+			Precompute the generator outputs.
+			mCoeffs must be defined first.
+		*/
+		void computeGeneratorTable();
+		void encode(const BitVector &in, BitVector& target) const;
+		void decode(const SoftVector &in, BitVector& target);
+};
+
+
+
+/**
+	Class to represent recursive systematic convolutional coders/decoders of rate 1/3, memory length 4.
+*/
+class ViterbiTCH_AFS10_2 : public ViterbiBase {
+
+	private:
+		/**name Lots of precomputed elements so the compiler can optimize like hell. */
+		//@{
+		/**@name Core values. */
+		//@{
+		static const unsigned mIRate = 3;	///< reciprocal of rate
+		static const unsigned mOrder = 4;	///< memory length of generators
+		//@}
+		/**@name Derived values. */
+		//@{
+		static const unsigned mIStates = 0x01 << mOrder;	///< number of states, number of survivors
+		static const uint32_t mSMask = mIStates-1;			///< survivor mask
+		static const uint32_t mCMask = (mSMask<<1) | 0x01;	///< candidate mask
+		static const uint32_t mOMask = (0x01<<mIRate)-1;	///< ouput mask, all iRate low bits set
+		static const unsigned mNumCands = mIStates*2;		///< number of candidates to generate during branching
+		static const unsigned mDeferral = 6*mOrder;			///< deferral to be used
+		//@}
+		//@}
+
+		/** Precomputed tables. */
+		//@{
+		uint32_t mCoeffs[mIRate];					///< output polynomial for each generator
+		uint32_t mCoeffsFB[mIRate];					///< feedback polynomial for each generator
+		uint32_t mStateTable[mIRate][2*mIStates];	///< precomputed generator output tables
+		uint32_t mGeneratorTable[2*mIStates];		///< precomputed coder output table
+		//@}
+	
+	public:
+
+		/**
+		  A candidate sequence in a Viterbi decoder.
+		  The 32-bit state register can support a deferral of 6 with a 4th-order coder.
+		 */
+		typedef struct candStruct {
+			uint32_t iState;	///< encoder input associated with this candidate
+			uint32_t oState;	///< encoder output associated with this candidate
+			char rState[mIRate];///< real states of encoders associated with this candidate
+			float cost;			///< cost (metric value), float to support soft inputs
+		} vCand;
+
+		/** Clear a structure. */
+		void vitClear(vCand& v)
+		{
+			v.iState=0;
+			v.oState=0;
+			v.cost=0;
+			for (unsigned i = 0; i < mIRate; i++) v.rState[i] = 0;
+		}
+		
+
+	private:
+
+		/**@name Survivors and candidates. */
+		//@{
+		vCand mSurvivors[mIStates];			///< current survivor pool
+		vCand mCandidates[2*mIStates];		///< current candidate pool
+		//@}
+
+	public:
+
+		unsigned iRate() const { return mIRate; }
+		uint32_t cMask() const { return mCMask; }
+		uint32_t stateTable(unsigned g, unsigned i) const { return mStateTable[g][i]; }
+		unsigned deferral() const { return mDeferral; }
+		
+
+		ViterbiTCH_AFS10_2();
+
+		/** Set all cost metrics to zero. */
+		void initializeStates();
+
+		/**
+			Full cycle of the Viterbi algorithm: branch, metrics, prune, select.
+			@return reference to minimum-cost candidate.
+		*/
+		const vCand& step(uint32_t inSample, const float *probs, const float *iprobs);
+
+	private:
+
+		/** Branch survivors into new candidates. */
+		void branchCandidates();
+
+		/** Compute cost metrics for soft-inputs. */
+		void getSoftCostMetrics(uint32_t inSample, const float *probs, const float *iprobs);
+
+		/** Select survivors from the candidate set. */
+		void pruneCandidates();
+
+		/** Find the minimum cost survivor. */
+		const vCand& minCost() const;
+
+		/**
+			Precompute the state tables.
+			@param g Generator index 0..((1/rate)-1)
+		*/
+		void computeStateTables(unsigned g);
+
+		/**
+			Precompute the generator outputs.
+			mCoeffs must be defined first.
+		*/
+		void computeGeneratorTable();
+		void encode(const BitVector &in, BitVector& target) const;
+		void decode(const SoftVector &in, BitVector& target);
+
+};
+
+
+
+/**
+	Class to represent recursive systematic convolutional coders/decoders of rate 1/3, memory length 6.
+*/
+class ViterbiTCH_AFS7_95 : public ViterbiBase {
+
+	private:
+		/**name Lots of precomputed elements so the compiler can optimize like hell. */
+		//@{
+		/**@name Core values. */
+		//@{
+		static const unsigned mIRate = 3;	///< reciprocal of rate
+		static const unsigned mOrder = 6;	///< memory length of generators
+		//@}
+		/**@name Derived values. */
+		//@{
+		static const unsigned mIStates = 0x01 << mOrder;	///< number of states, number of survivors
+		static const uint32_t mSMask = mIStates-1;			///< survivor mask
+		static const uint32_t mCMask = (mSMask<<1) | 0x01;	///< candidate mask
+		static const uint32_t mOMask = (0x01<<mIRate)-1;	///< ouput mask, all iRate low bits set
+		static const unsigned mNumCands = mIStates*2;		///< number of candidates to generate during branching
+		static const unsigned mDeferral = 5*mOrder;			///< deferral to be used
+		//@}
+		//@}
+
+		/** Precomputed tables. */
+		//@{
+		uint32_t mCoeffs[mIRate];					///< output polynomial for each generator
+		uint32_t mCoeffsFB[mIRate];					///< feedback polynomial for each generator
+		uint32_t mStateTable[mIRate][2*mIStates];	///< precomputed generator output tables
+		uint32_t mGeneratorTable[2*mIStates];		///< precomputed coder output table
+		//@}
+	
+	public:
+
+		/**
+		  A candidate sequence in a Viterbi decoder.
+		  The 32-bit state register can support a deferral of 5*order with a 6th-order coder.
+		 */
+		typedef struct candStruct {
+			uint32_t iState;	///< encoder input associated with this candidate
+			uint32_t oState;	///< encoder output associated with this candidate
+			char rState[mIRate];///< real states of encoders associated with this candidate
+			float cost;			///< cost (metric value), float to support soft inputs
+		} vCand;
+
+		/** Clear a structure. */
+		void vitClear(vCand& v)
+		{
+			v.iState=0;
+			v.oState=0;
+			v.cost=0;
+			for (unsigned i = 0; i < mIRate; i++) v.rState[i] = 0;
+		}
+		
+
+	private:
+
+		/**@name Survivors and candidates. */
+		//@{
+		vCand mSurvivors[mIStates];			///< current survivor pool
+		vCand mCandidates[2*mIStates];		///< current candidate pool
+		//@}
+
+	public:
+
+		unsigned iRate() const { return mIRate; }
+		uint32_t cMask() const { return mCMask; }
+		uint32_t stateTable(unsigned g, unsigned i) const { return mStateTable[g][i]; }
+		unsigned deferral() const { return mDeferral; }
+		
+
+		ViterbiTCH_AFS7_95();
+
+		/** Set all cost metrics to zero. */
+		void initializeStates();
+
+		/**
+			Full cycle of the Viterbi algorithm: branch, metrics, prune, select.
+			@return reference to minimum-cost candidate.
+		*/
+		const vCand& step(uint32_t inSample, const float *probs, const float *iprobs);
+
+	private:
+
+		/** Branch survivors into new candidates. */
+		void branchCandidates();
+
+		/** Compute cost metrics for soft-inputs. */
+		void getSoftCostMetrics(uint32_t inSample, const float *probs, const float *iprobs);
+
+		/** Select survivors from the candidate set. */
+		void pruneCandidates();
+
+		/** Find the minimum cost survivor. */
+		const vCand& minCost() const;
+
+		/**
+			Precompute the state tables.
+			@param g Generator index 0..((1/rate)-1)
+		*/
+		void computeStateTables(unsigned g);
+
+		/**
+			Precompute the generator outputs.
+			mCoeffs must be defined first.
+		*/
+		void computeGeneratorTable();
+		void encode(const BitVector &in, BitVector& target) const;
+		void decode(const SoftVector &in, BitVector& target);
+
+};
+
+
+
+/**
+	Class to represent recursive systematic convolutional coders/decoders of rate 1/3, memory length 4.
+*/
+class ViterbiTCH_AFS7_4 : public ViterbiBase {
+
+	private:
+		/**name Lots of precomputed elements so the compiler can optimize like hell. */
+		//@{
+		/**@name Core values. */
+		//@{
+		static const unsigned mIRate = 3;	///< reciprocal of rate
+		static const unsigned mOrder = 4;	///< memory length of generators
+		//@}
+		/**@name Derived values. */
+		//@{
+		static const unsigned mIStates = 0x01 << mOrder;	///< number of states, number of survivors
+		static const uint32_t mSMask = mIStates-1;			///< survivor mask
+		static const uint32_t mCMask = (mSMask<<1) | 0x01;	///< candidate mask
+		static const uint32_t mOMask = (0x01<<mIRate)-1;	///< ouput mask, all iRate low bits set
+		static const unsigned mNumCands = mIStates*2;		///< number of candidates to generate during branching
+		static const unsigned mDeferral = 6*mOrder;			///< deferral to be used
+		//@}
+		//@}
+
+		/** Precomputed tables. */
+		//@{
+		uint32_t mCoeffs[mIRate];					///< output polynomial for each generator
+		uint32_t mCoeffsFB[mIRate];					///< feedback polynomial for each generator
+		uint32_t mStateTable[mIRate][2*mIStates];	///< precomputed generator output tables
+		uint32_t mGeneratorTable[2*mIStates];		///< precomputed coder output table
+		//@}
+	
+	public:
+
+		/**
+		  A candidate sequence in a Viterbi decoder.
+		  The 32-bit state register can support a deferral of 6 with a 4th-order coder.
+		 */
+		typedef struct candStruct {
+			uint32_t iState;	///< encoder input associated with this candidate
+			uint32_t oState;	///< encoder output associated with this candidate
+			char rState[mIRate];///< real states of encoders associated with this candidate
+			float cost;			///< cost (metric value), float to support soft inputs
+		} vCand;
+
+		/** Clear a structure. */
+		void vitClear(vCand& v)
+		{
+			v.iState=0;
+			v.oState=0;
+			v.cost=0;
+			for (unsigned i = 0; i < mIRate; i++) v.rState[i] = 0;
+		}
+		
+
+	private:
+
+		/**@name Survivors and candidates. */
+		//@{
+		vCand mSurvivors[mIStates];			///< current survivor pool
+		vCand mCandidates[2*mIStates];		///< current candidate pool
+		//@}
+
+	public:
+
+		unsigned iRate() const { return mIRate; }
+		uint32_t cMask() const { return mCMask; }
+		uint32_t stateTable(unsigned g, unsigned i) const { return mStateTable[g][i]; }
+		unsigned deferral() const { return mDeferral; }
+		
+
+		ViterbiTCH_AFS7_4();
+
+		/** Set all cost metrics to zero. */
+		void initializeStates();
+
+		/**
+			Full cycle of the Viterbi algorithm: branch, metrics, prune, select.
+			@return reference to minimum-cost candidate.
+		*/
+		const vCand& step(uint32_t inSample, const float *probs, const float *iprobs);
+
+	private:
+
+		/** Branch survivors into new candidates. */
+		void branchCandidates();
+
+		/** Compute cost metrics for soft-inputs. */
+		void getSoftCostMetrics(uint32_t inSample, const float *probs, const float *iprobs);
+
+		/** Select survivors from the candidate set. */
+		void pruneCandidates();
+
+		/** Find the minimum cost survivor. */
+		const vCand& minCost() const;
+
+		/**
+			Precompute the state tables.
+			@param g Generator index 0..((1/rate)-1)
+		*/
+		void computeStateTables(unsigned g);
+
+		/**
+			Precompute the generator outputs.
+			mCoeffs must be defined first.
+		*/
+		void computeGeneratorTable();
+		void encode(const BitVector &in, BitVector& target) const;
+		void decode(const SoftVector &in, BitVector& target);
+
+};
+
+
+
+/**
+	Class to represent recursive systematic convolutional coders/decoders of rate 1/4, memory length 4.
+*/
+class ViterbiTCH_AFS6_7 : public ViterbiBase {
+
+	private:
+		/**name Lots of precomputed elements so the compiler can optimize like hell. */
+		//@{
+		/**@name Core values. */
+		//@{
+		static const unsigned mIRate = 4;	///< reciprocal of rate
+		static const unsigned mOrder = 4;	///< memory length of generators
+		//@}
+		/**@name Derived values. */
+		//@{
+		static const unsigned mIStates = 0x01 << mOrder;	///< number of states, number of survivors
+		static const uint32_t mSMask = mIStates-1;			///< survivor mask
+		static const uint32_t mCMask = (mSMask<<1) | 0x01;	///< candidate mask
+		static const uint32_t mOMask = (0x01<<mIRate)-1;	///< ouput mask, all iRate low bits set
+		static const unsigned mNumCands = mIStates*2;		///< number of candidates to generate during branching
+		static const unsigned mDeferral = 6*mOrder;			///< deferral to be used
+		//@}
+		//@}
+
+		/** Precomputed tables. */
+		//@{
+		uint32_t mCoeffs[mIRate];					///< output polynomial for each generator
+		uint32_t mCoeffsFB[mIRate];					///< feedback polynomial for each generator
+		uint32_t mStateTable[mIRate][2*mIStates];	///< precomputed generator output tables
+		uint32_t mGeneratorTable[2*mIStates];		///< precomputed coder output table
+		//@}
+	
+	public:
+
+		/**
+		  A candidate sequence in a Viterbi decoder.
+		  The 32-bit state register can support a deferral of 6 with a 4th-order coder.
+		 */
+		typedef struct candStruct {
+			uint32_t iState;	///< encoder input associated with this candidate
+			uint32_t oState;	///< encoder output associated with this candidate
+			char rState[mIRate];///< real states of encoders associated with this candidate
+			float cost;			///< cost (metric value), float to support soft inputs
+		} vCand;
+
+		/** Clear a structure. */
+		void vitClear(vCand& v)
+		{
+			v.iState=0;
+			v.oState=0;
+			v.cost=0;
+			for (unsigned i = 0; i < mIRate; i++) v.rState[i] = 0;
+		}
+		
+
+	private:
+
+		/**@name Survivors and candidates. */
+		//@{
+		vCand mSurvivors[mIStates];			///< current survivor pool
+		vCand mCandidates[2*mIStates];		///< current candidate pool
+		//@}
+
+	public:
+
+		unsigned iRate() const { return mIRate; }
+		uint32_t cMask() const { return mCMask; }
+		uint32_t stateTable(unsigned g, unsigned i) const { return mStateTable[g][i]; }
+		unsigned deferral() const { return mDeferral; }
+		
+
+		ViterbiTCH_AFS6_7();
+
+		/** Set all cost metrics to zero. */
+		void initializeStates();
+
+		/**
+			Full cycle of the Viterbi algorithm: branch, metrics, prune, select.
+			@return reference to minimum-cost candidate.
+		*/
+		const vCand& step(uint32_t inSample, const float *probs, const float *iprobs);
+
+	private:
+
+		/** Branch survivors into new candidates. */
+		void branchCandidates();
+
+		/** Compute cost metrics for soft-inputs. */
+		void getSoftCostMetrics(uint32_t inSample, const float *probs, const float *iprobs);
+
+		/** Select survivors from the candidate set. */
+		void pruneCandidates();
+
+		/** Find the minimum cost survivor. */
+		const vCand& minCost() const;
+
+		/**
+			Precompute the state tables.
+			@param g Generator index 0..((1/rate)-1)
+		*/
+		void computeStateTables(unsigned g);
+
+		/**
+			Precompute the generator outputs.
+			mCoeffs must be defined first.
+		*/
+		void computeGeneratorTable();
+		void encode(const BitVector &in, BitVector& target) const;
+		void decode(const SoftVector &in, BitVector& target);
+
+};
+
+
+
+/**
+	Class to represent recursive systematic convolutional coders/decoders of rate 1/4, memory length 6.
+*/
+class ViterbiTCH_AFS5_9 : public ViterbiBase {
+
+	private:
+		/**name Lots of precomputed elements so the compiler can optimize like hell. */
+		//@{
+		/**@name Core values. */
+		//@{
+		static const unsigned mIRate = 4;	///< reciprocal of rate
+		static const unsigned mOrder = 6;	///< memory length of generators
+		//@}
+		/**@name Derived values. */
+		//@{
+		static const unsigned mIStates = 0x01 << mOrder;	///< number of states, number of survivors
+		static const uint32_t mSMask = mIStates-1;			///< survivor mask
+		static const uint32_t mCMask = (mSMask<<1) | 0x01;	///< candidate mask
+		static const uint32_t mOMask = (0x01<<mIRate)-1;	///< ouput mask, all iRate low bits set
+		static const unsigned mNumCands = mIStates*2;		///< number of candidates to generate during branching
+		static const unsigned mDeferral = 5*mOrder;			///< deferral to be used
+		//@}
+		//@}
+
+		/** Precomputed tables. */
+		//@{
+		uint32_t mCoeffs[mIRate];					///< output polynomial for each generator
+		uint32_t mCoeffsFB[mIRate];					///< feedback polynomial for each generator
+		uint32_t mStateTable[mIRate][2*mIStates];	///< precomputed generator output tables
+		uint32_t mGeneratorTable[2*mIStates];		///< precomputed coder output table
+		//@}
+	
+	public:
+
+		/**
+		  A candidate sequence in a Viterbi decoder.
+		  The 32-bit state register can support a deferral of 5*order with a 6th-order coder.
+		 */
+		typedef struct candStruct {
+			uint32_t iState;	///< encoder input associated with this candidate
+			uint32_t oState;	///< encoder output associated with this candidate
+			char rState[mIRate];///< real states of encoders associated with this candidate
+			float cost;			///< cost (metric value), float to support soft inputs
+		} vCand;
+
+		/** Clear a structure. */
+		void vitClear(vCand& v)
+		{
+			v.iState=0;
+			v.oState=0;
+			v.cost=0;
+			for (unsigned i = 0; i < mIRate; i++) v.rState[i] = 0;
+		}
+		
+
+	private:
+
+		/**@name Survivors and candidates. */
+		//@{
+		vCand mSurvivors[mIStates];			///< current survivor pool
+		vCand mCandidates[2*mIStates];		///< current candidate pool
+		//@}
+
+	public:
+
+		unsigned iRate() const { return mIRate; }
+		uint32_t cMask() const { return mCMask; }
+		uint32_t stateTable(unsigned g, unsigned i) const { return mStateTable[g][i]; }
+		unsigned deferral() const { return mDeferral; }
+		
+
+		ViterbiTCH_AFS5_9();
+
+		/** Set all cost metrics to zero. */
+		void initializeStates();
+
+		/**
+			Full cycle of the Viterbi algorithm: branch, metrics, prune, select.
+			@return reference to minimum-cost candidate.
+		*/
+		const vCand& step(uint32_t inSample, const float *probs, const float *iprobs);
+
+	private:
+
+		/** Branch survivors into new candidates. */
+		void branchCandidates();
+
+		/** Compute cost metrics for soft-inputs. */
+		void getSoftCostMetrics(uint32_t inSample, const float *probs, const float *iprobs);
+
+		/** Select survivors from the candidate set. */
+		void pruneCandidates();
+
+		/** Find the minimum cost survivor. */
+		const vCand& minCost() const;
+
+		/**
+			Precompute the state tables.
+			@param g Generator index 0..((1/rate)-1)
+		*/
+		void computeStateTables(unsigned g);
+
+		/**
+			Precompute the generator outputs.
+			mCoeffs must be defined first.
+		*/
+		void computeGeneratorTable();
+		void encode(const BitVector &in, BitVector& target) const;
+		void decode(const SoftVector &in, BitVector& target);
+
+};
+
+
+
+/**
+	Class to represent recursive systematic convolutional coders/decoders of rate 1/5, memory length 4.
+*/
+class ViterbiTCH_AFS5_15 : public ViterbiBase {
+
+	private:
+		/**name Lots of precomputed elements so the compiler can optimize like hell. */
+		//@{
+		/**@name Core values. */
+		//@{
+		static const unsigned mIRate = 5;	///< reciprocal of rate
+		static const unsigned mOrder = 4;	///< memory length of generators
+		//@}
+		/**@name Derived values. */
+		//@{
+		static const unsigned mIStates = 0x01 << mOrder;	///< number of states, number of survivors
+		static const uint32_t mSMask = mIStates-1;			///< survivor mask
+		static const uint32_t mCMask = (mSMask<<1) | 0x01;	///< candidate mask
+		static const uint32_t mOMask = (0x01<<mIRate)-1;	///< ouput mask, all iRate low bits set
+		static const unsigned mNumCands = mIStates*2;		///< number of candidates to generate during branching
+		static const unsigned mDeferral = 6*mOrder;			///< deferral to be used
+		//@}
+		//@}
+
+		/** Precomputed tables. */
+		//@{
+		uint32_t mCoeffs[mIRate];					///< output polynomial for each generator
+		uint32_t mCoeffsFB[mIRate];					///< feedback polynomial for each generator
+		uint32_t mStateTable[mIRate][2*mIStates];	///< precomputed generator output tables
+		uint32_t mGeneratorTable[2*mIStates];		///< precomputed coder output table
+		//@}
+	
+	public:
+
+		/**
+		  A candidate sequence in a Viterbi decoder.
+		  The 32-bit state register can support a deferral of 6 with a 4th-order coder.
+		 */
+		typedef struct candStruct {
+			uint32_t iState;	///< encoder input associated with this candidate
+			uint32_t oState;	///< encoder output associated with this candidate
+			char rState[mIRate];///< real states of encoders associated with this candidate
+			float cost;			///< cost (metric value), float to support soft inputs
+		} vCand;
+
+		/** Clear a structure. */
+		void vitClear(vCand& v)
+		{
+			v.iState=0;
+			v.oState=0;
+			v.cost=0;
+			for (unsigned i = 0; i < mIRate; i++) v.rState[i] = 0;
+		}
+		
+
+	private:
+
+		/**@name Survivors and candidates. */
+		//@{
+		vCand mSurvivors[mIStates];			///< current survivor pool
+		vCand mCandidates[2*mIStates];		///< current candidate pool
+		//@}
+
+	public:
+
+		unsigned iRate() const { return mIRate; }
+		uint32_t cMask() const { return mCMask; }
+		uint32_t stateTable(unsigned g, unsigned i) const { return mStateTable[g][i]; }
+		unsigned deferral() const { return mDeferral; }
+		
+
+		ViterbiTCH_AFS5_15();
+
+		/** Set all cost metrics to zero. */
+		void initializeStates();
+
+		/**
+			Full cycle of the Viterbi algorithm: branch, metrics, prune, select.
+			@return reference to minimum-cost candidate.
+		*/
+		const vCand& step(uint32_t inSample, const float *probs, const float *iprobs);
+
+	private:
+
+		/** Branch survivors into new candidates. */
+		void branchCandidates();
+
+		/** Compute cost metrics for soft-inputs. */
+		void getSoftCostMetrics(uint32_t inSample, const float *probs, const float *iprobs);
+
+		/** Select survivors from the candidate set. */
+		void pruneCandidates();
+
+		/** Find the minimum cost survivor. */
+		const vCand& minCost() const;
+
+		/**
+			Precompute the state tables.
+			@param g Generator index 0..((1/rate)-1)
+		*/
+		void computeStateTables(unsigned g);
+
+		/**
+			Precompute the generator outputs.
+			mCoeffs must be defined first.
+		*/
+		void computeGeneratorTable();
+		void encode(const BitVector &in, BitVector& target) const;
+		void decode(const SoftVector &in, BitVector& target);
+
+};
+
+
+
+/**
+	Class to represent recursive systematic convolutional coders/decoders of rate 1/5, memory length 6.
+*/
+class ViterbiTCH_AFS4_75 : public ViterbiBase {
+
+	private:
+		/**name Lots of precomputed elements so the compiler can optimize like hell. */
+		//@{
+		/**@name Core values. */
+		//@{
+		static const unsigned mIRate = 5;	///< reciprocal of rate
+		static const unsigned mOrder = 6;	///< memory length of generators
+		//@}
+		/**@name Derived values. */
+		//@{
+		static const unsigned mIStates = 0x01 << mOrder;	///< number of states, number of survivors
+		static const uint32_t mSMask = mIStates-1;			///< survivor mask
+		static const uint32_t mCMask = (mSMask<<1) | 0x01;	///< candidate mask
+		static const uint32_t mOMask = (0x01<<mIRate)-1;	///< ouput mask, all iRate low bits set
+		static const unsigned mNumCands = mIStates*2;		///< number of candidates to generate during branching
+		static const unsigned mDeferral = 5*mOrder;			///< deferral to be used
+		//@}
+		//@}
+
+		/** Precomputed tables. */
+		//@{
+		uint32_t mCoeffs[mIRate];					///< output polynomial for each generator
+		uint32_t mCoeffsFB[mIRate];					///< feedback polynomial for each generator
+		uint32_t mStateTable[mIRate][2*mIStates];	///< precomputed generator output tables
+		uint32_t mGeneratorTable[2*mIStates];		///< precomputed coder output table
+		//@}
+	
+	public:
+
+		/**
+		  A candidate sequence in a Viterbi decoder.
+		  The 32-bit state register can support a deferral of 5*order with a 6th-order coder.
+		 */
+		typedef struct candStruct {
+			uint32_t iState;	///< encoder input associated with this candidate
+			uint32_t oState;	///< encoder output associated with this candidate
+			char rState[mIRate];///< real states of encoders associated with this candidate
+			float cost;			///< cost (metric value), float to support soft inputs
+		} vCand;
+
+		/** Clear a structure. */
+		void vitClear(vCand& v)
+		{
+			v.iState=0;
+			v.oState=0;
+			v.cost=0;
+			for (unsigned i = 0; i < mIRate; i++) v.rState[i] = 0;
+		}
+		
+
+	private:
+
+		/**@name Survivors and candidates. */
+		//@{
+		vCand mSurvivors[mIStates];			///< current survivor pool
+		vCand mCandidates[2*mIStates];		///< current candidate pool
+		//@}
+
+	public:
+
+		unsigned iRate() const { return mIRate; }
+		uint32_t cMask() const { return mCMask; }
+		uint32_t stateTable(unsigned g, unsigned i) const { return mStateTable[g][i]; }
+		unsigned deferral() const { return mDeferral; }
+		
+
+		ViterbiTCH_AFS4_75();
+
+		/** Set all cost metrics to zero. */
+		void initializeStates();
+
+		/**
+			Full cycle of the Viterbi algorithm: branch, metrics, prune, select.
+			@return reference to minimum-cost candidate.
+		*/
+		const vCand& step(uint32_t inSample, const float *probs, const float *iprobs);
+
+	private:
+
+		/** Branch survivors into new candidates. */
+		void branchCandidates();
+
+		/** Compute cost metrics for soft-inputs. */
+		void getSoftCostMetrics(uint32_t inSample, const float *probs, const float *iprobs);
+
+		/** Select survivors from the candidate set. */
+		void pruneCandidates();
+
+		/** Find the minimum cost survivor. */
+		const vCand& minCost() const;
+
+		/**
+			Precompute the state tables.
+			@param g Generator index 0..((1/rate)-1)
+		*/
+		void computeStateTables(unsigned g);
+
+		/**
+			Precompute the generator outputs.
+			mCoeffs must be defined first.
+		*/
+		void computeGeneratorTable();
+		void encode(const BitVector &in, BitVector& target) const;
+		void decode(const SoftVector &in, BitVector& target);
+
+};
+
+
+
+
+#endif
diff --git a/lib/decoding/BitVector.cpp b/lib/decoding/BitVector.cpp
index c0c097b..86f326a 100644
--- a/lib/decoding/BitVector.cpp
+++ b/lib/decoding/BitVector.cpp
@@ -375,6 +375,34 @@
 	targ[bytes] = peekField(whole,rem) << (8-rem);
 }
 
+void BitVector::pack2(unsigned char* targ) const
+{
+    unsigned int i;
+    unsigned char curbyte = 0;
+
+    for (i = 0; i < size(); i++)
+    {
+        uint8_t bitnum = 7 - (i % 8);
+        curbyte |= ((char)bit(i) << bitnum);
+        if(i % 8 == 7){
+            *targ++ = curbyte;
+            curbyte = 0;
+        }
+    }
+
+	// Assumes MSB-first packing.
+//	unsigned bytes = size()/8;
+//	for (unsigned i=0; i<bytes; i++) {
+//		targ[i] = peekField(i*8,8);
+//	}
+//	unsigned whole = bytes*8;
+//	unsigned rem = size() - whole;
+//	if (rem==0) return;
+//	targ[bytes] = peekField(whole,rem) << (8-rem);
+}
+
+
+
 string BitVector::packToString() const
 {
 	string result;
diff --git a/lib/decoding/BitVector.h b/lib/decoding/BitVector.h
index 0f78b97..0899817 100644
--- a/lib/decoding/BitVector.h
+++ b/lib/decoding/BitVector.h
@@ -243,6 +243,10 @@
 
 	/** Pack into a char array. */
 	void pack(unsigned char*) const;
+
+	/*  Roman: This is here for debugging */
+	void pack2(unsigned char*) const;
+
 	// Same as pack but return a string.
 	std::string packToString() const;
 
diff --git a/lib/decoding/GSM503Tables.cpp b/lib/decoding/GSM503Tables.cpp
new file mode 100644
index 0000000..02150f2
--- /dev/null
+++ b/lib/decoding/GSM503Tables.cpp
@@ -0,0 +1,322 @@
+/*
+* Copyright 2012, 2014 Range Networks, Inc.
+*
+* This software is distributed under multiple licenses; see the COPYING file in the main directory for licensing information for this specific distribution.
+*
+* This use of this software may be subject to additional restrictions.
+* See the LEGAL file in the main directory for details.
+
+    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.
+
+*/
+
+
+
+#include "GSM503Tables.h"
+
+
+/*
+	This array encodes GSM 05.03 Table 7.
+*/
+const unsigned int GSM::gAMRBitOrderTCH_AFS12_2[244] = {
+	   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
+	  10,  11,  12,  13,  14,  23,  15,  16,  17,  18,
+	  19,  20,  21,  22,  24,  25,  26,  27,  28,  38,
+	 141,  39, 142,  40, 143,  41, 144,  42, 145,  43,
+	 146,  44, 147,  45, 148,  46, 149,  47,  97, 150,
+	 200,  48,  98, 151, 201,  49,  99, 152, 202,  86,
+	 136, 189, 239,  87, 137, 190, 240,  88, 138, 191,
+	 241,  91, 194,  92, 195,  93, 196,  94, 197,  95,
+	 198,  29,  30,  31,  32,  33,  34,  35,  50, 100,
+	 153, 203,  89, 139, 192, 242,  51, 101, 154, 204,
+	  55, 105, 158, 208,  90, 140, 193, 243,  59, 109,
+	 162, 212,  63, 113, 166, 216,  67, 117, 170, 220,
+	  36,  37,  54,  53,  52,  58,  57,  56,  62,  61,
+	  60,  66,  65,  64,  70,  69,  68, 104, 103, 102,
+	 108, 107, 106, 112, 111, 110, 116, 115, 114, 120,
+	 119, 118, 157, 156, 155, 161, 160, 159, 165, 164,
+	 163, 169, 168, 167, 173, 172, 171, 207, 206, 205,
+	 211, 210, 209, 215, 214, 213, 219, 218, 217, 223,
+	 222, 221,  73,  72,  71,  76,  75,  74,  79,  78,
+	  77,  82,  81,  80,  85,  84,  83, 123, 122, 121,
+	 126, 125, 124, 129, 128, 127, 132, 131, 130, 135,
+	 134, 133, 176, 175, 174, 179, 178, 177, 182, 181,
+	 180, 185, 184, 183, 188, 187, 186, 226, 225, 224,
+	 229, 228, 227, 232, 231, 230, 235, 234, 233, 238,
+	 237, 236,  96, 199
+};
+
+
+/*
+	This array encodes GSM 05.03 Table 8.
+*/
+const unsigned int GSM::gAMRBitOrderTCH_AFS10_2[204] = {
+	   7,   6,   5,   4,   3,   2,   1,   0,  16,  15,
+	  14,  13,  12,  11,  10,   9,   8,  26,  27,  28,
+	  29,  30,  31, 115, 116, 117, 118, 119, 120,  72,
+	  73, 161, 162,  65,  68,  69, 108, 111, 112, 154,
+	 157, 158, 197, 200, 201,  32,  33, 121, 122,  74,
+	  75, 163, 164,  66, 109, 155, 198,  19,  23,  21,
+	  22,  18,  17,  20,  24,  25,  37,  36,  35,  34,
+	  80,  79,  78,  77, 126, 125, 124, 123, 169, 168,
+	 167, 166,  70,  67,  71, 113, 110, 114, 159, 156,
+	 160, 202, 199, 203,  76, 165,  81,  82,  92,  91,
+	  93,  83,  95,  85,  84,  94, 101, 102,  96, 104,
+	  86, 103,  87,  97, 127, 128, 138, 137, 139, 129,
+	 141, 131, 130, 140, 147, 148, 142, 150, 132, 149,
+	 133, 143, 170, 171, 181, 180, 182, 172, 184, 174,
+	 173, 183, 190, 191, 185, 193, 175, 192, 176, 186,
+	  38,  39,  49,  48,  50,  40,  52,  42,  41,  51,
+	  58,  59,  53,  61,  43,  60,  44,  54, 194, 179,
+	 189, 196, 177, 195, 178, 187, 188, 151, 136, 146,
+	 153, 134, 152, 135, 144, 145, 105,  90, 100, 107,
+	  88, 106,  89,  98,  99,  62,  47,  57,  64,  45,
+	  63,  46,  55,  56
+};
+
+
+/*
+	This array encodes GSM 05.03 Table 9.
+*/
+const unsigned int GSM::gAMRBitOrderTCH_AFS7_95[159] = {
+	   8,   7,   6,   5,   4,   3,   2,  14,  16,   9,
+	  10,  12,  13,  15,  11,  17,  20,  22,  24,  23,
+	  19,  18,  21,  56,  88, 122, 154,  57,  89, 123,
+	 155,  58,  90, 124, 156,  52,  84, 118, 150,  53,
+	  85, 119, 151,  27,  93,  28,  94,  29,  95,  30,
+	  96,  31,  97,  61, 127,  62, 128,  63, 129,  59,
+	  91, 125, 157,  32,  98,  64, 130,   1,   0,  25,
+	  26,  33,  99,  34, 100,  65, 131,  66, 132,  54,
+	  86, 120, 152,  60,  92, 126, 158,  55,  87, 121,
+	 153, 117, 116, 115,  46,  78, 112, 144,  43,  75,
+	 109, 141,  40,  72, 106, 138,  36,  68, 102, 134,
+	 114, 149, 148, 147, 146,  83,  82,  81,  80,  51,
+	  50,  49,  48,  47,  45,  44,  42,  39,  35,  79,
+	  77,  76,  74,  71,  67, 113, 111, 110, 108, 105,
+	 101, 145, 143, 142, 140, 137, 133,  41,  73, 107,
+	 139,  37,  69, 103, 135,  38,  70, 104, 136
+};
+
+/*
+	This array encodes GSM 05.03 Table 10.
+*/
+const unsigned int GSM::gAMRBitOrderTCH_AFS7_4[148] = {
+	   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
+	  10,  11,  12,  13,  14,  15,  16,  26,  87,  27,
+	  88,  28,  89,  29,  90,  30,  91,  51,  80, 112,
+	 141,  52,  81, 113, 142,  54,  83, 115, 144,  55,
+	  84, 116, 145,  58, 119,  59, 120,  21,  22,  23,
+	  17,  18,  19,  31,  60,  92, 121,  56,  85, 117,
+	 146,  20,  24,  25,  50,  79, 111, 140,  57,  86,
+	 118, 147,  49,  78, 110, 139,  48,  77,  53,  82,
+	 114, 143, 109, 138,  47,  76, 108, 137,  32,  33,
+	  61,  62,  93,  94, 122, 123,  41,  42,  43,  44,
+	  45,  46,  70,  71,  72,  73,  74,  75, 102, 103,
+	 104, 105, 106, 107, 131, 132, 133, 134, 135, 136,
+	  34,  63,  95, 124,  35,  64,  96, 125,  36,  65,
+	  97, 126,  37,  66,  98, 127,  38,  67,  99, 128,
+	  39,  68, 100, 129,  40,  69, 101, 130
+};
+
+/*
+	This array encodes GSM 05.03 Table 11.
+*/
+const unsigned int GSM::gAMRBitOrderTCH_AFS6_7[134] = {
+	   0,   1,   4,   3,   5,   6,  13,   7,   2,   8,
+	   9,  11,  15,  12,  14,  10,  28,  82,  29,  83,
+	  27,  81,  26,  80,  30,  84,  16,  55, 109,  56,
+	 110,  31,  85,  57, 111,  48,  73, 102, 127,  32,
+	  86,  51,  76, 105, 130,  52,  77, 106, 131,  58,
+	 112,  33,  87,  19,  23,  53,  78, 107, 132,  21,
+	  22,  18,  17,  20,  24,  25,  50,  75, 104, 129,
+	  47,  72, 101, 126,  54,  79, 108, 133,  46,  71,
+	 100, 125, 128, 103,  74,  49,  45,  70,  99, 124,
+	  42,  67,  96, 121,  39,  64,  93, 118,  38,  63,
+	  92, 117,  35,  60,  89, 114,  34,  59,  88, 113,
+	  44,  69,  98, 123,  43,  68,  97, 122,  41,  66,
+	  95, 120,  40,  65,  94, 119,  37,  62,  91, 116,
+	  36,  61,  90, 115
+};
+
+/*
+	This array encodes GSM 05.03 Table 12.
+*/
+const unsigned int GSM::gAMRBitOrderTCH_AFS5_9[118] = {
+	   0,   1,   4,   5,   3,   6,   7,   2,  13,  15,
+	   8,   9,  11,  12,  14,  10,  16,  28,  74,  29,
+	  75,  27,  73,  26,  72,  30,  76,  51,  97,  50,
+	  71,  96, 117,  31,  77,  52,  98,  49,  70,  95,
+	 116,  53,  99,  32,  78,  33,  79,  48,  69,  94,
+	 115,  47,  68,  93, 114,  46,  67,  92, 113,  19,
+	  21,  23,  22,  18,  17,  20,  24, 111,  43,  89,
+	 110,  64,  65,  44,  90,  25,  45,  66,  91, 112,
+	  54, 100,  40,  61,  86, 107,  39,  60,  85, 106,
+	  36,  57,  82, 103,  35,  56,  81, 102,  34,  55,
+	  80, 101,  42,  63,  88, 109,  41,  62,  87, 108,
+	  38,  59,  84, 105,  37,  58,  83, 104
+};
+
+/*
+	This array encodes GSM 05.03 Table 13.
+*/
+const unsigned int GSM::gAMRBitOrderTCH_AFS5_15[103] = {
+	   7,   6,   5,   4,   3,   2,   1,   0,  15,  14,
+	  13,  12,  11,  10,   9,   8,  23,  24,  25,  26,
+	  27,  46,  65,  84,  45,  44,  43,  64,  63,  62,
+	  83,  82,  81, 102, 101, 100,  42,  61,  80,  99,
+	  28,  47,  66,  85,  18,  41,  60,  79,  98,  29,
+	  48,  67,  17,  20,  22,  40,  59,  78,  97,  21,
+	  30,  49,  68,  86,  19,  16,  87,  39,  38,  58,
+	  57,  77,  35,  54,  73,  92,  76,  96,  95,  36,
+	  55,  74,  93,  32,  51,  33,  52,  70,  71,  89,
+	  90,  31,  50,  69,  88,  37,  56,  75,  94,  34,
+	  53,  72,  91
+};
+
+/*
+	This array encodes GSM 05.03 Table 14.
+*/
+const unsigned int GSM::gAMRBitOrderTCH_AFS4_75[95] = {
+	   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
+	  10,  11,  12,  13,  14,  15,  23,  24,  25,  26,
+	  27,  28,  48,  49,  61,  62,  82,  83,  47,  46,
+	  45,  44,  81,  80,  79,  78,  17,  18,  20,  22,
+	  77,  76,  75,  74,  29,  30,  43,  42,  41,  40,
+	  38,  39,  16,  19,  21,  50,  51,  59,  60,  63,
+	  64,  72,  73,  84,  85,  93,  94,  32,  33,  35,
+	  36,  53,  54,  56,  57,  66,  67,  69,  70,  87,
+	  88,  90,  91,  34,  55,  68,  89,  37,  58,  71,
+	  92,  31,  52,  65,  86
+};
+
+/* GSM 05.03 3.9.4.4 */
+const unsigned int GSM::gAMRPuncturedTCH_AFS12_2[60] = {
+	321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363, 365,
+	369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401, 405, 409,
+	411, 413, 417, 421, 425, 427, 429, 433, 437, 441, 443, 445, 449,
+	453, 457, 459, 461, 465, 469, 473, 475, 477, 481, 485, 489, 491,
+	493, 495, 497, 499, 501, 503, 505, 507
+};
+
+/* GSM 05.03 3.9.4.4 */
+const unsigned int GSM::gAMRPuncturedTCH_AFS10_2[194] = {
+	1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43, 46, 52, 55, 58,
+	64, 67, 70, 76, 79, 82, 88, 91, 94, 100, 103, 106, 112, 115,
+	118, 124, 127, 130, 136, 139, 142, 148, 151, 154, 160, 163, 166,
+	172, 175, 178, 184, 187, 190, 196, 199, 202, 208, 211, 214, 220,
+	223, 226, 232, 235, 238, 244, 247, 250, 256, 259, 262, 268, 271,
+	274, 280, 283, 286, 292, 295, 298, 304, 307, 310, 316, 319, 322,
+	325, 328, 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361,
+	364, 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400,
+	403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436, 439,
+	442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, 475, 478,
+	481, 484, 487, 490, 493, 496, 499, 502, 505, 508, 511, 514, 517,
+	520, 523, 526, 529, 532, 535, 538, 541, 544, 547, 550, 553, 556,
+	559, 562, 565, 568, 571, 574, 577, 580, 583, 586, 589, 592, 595,
+	598, 601, 604, 607, 609, 610, 613, 616, 619, 621, 622, 625, 627,
+	628, 631, 633, 634, 636, 637, 639, 640
+};
+
+/* GSM 05.03 3.9.4.4 */
+const unsigned int GSM::gAMRPuncturedTCH_AFS7_95[65] = {
+	1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310, 317, 319, 325,
+	332, 334, 341, 343, 349, 356, 358, 365, 367, 373, 380, 382, 385,
+	389, 391, 397, 404, 406, 409, 413, 415, 421, 428, 430, 433, 437,
+	439, 445, 452, 454, 457, 461, 463, 469, 476, 478, 481, 485, 487,
+	490, 493, 500, 502, 503, 505, 506, 508, 509, 511, 512
+};
+
+/* GSM 05.03 3.9.4.4 */
+const unsigned int GSM::gAMRPuncturedTCH_AFS7_4[26] = {
+	0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415, 421,
+	427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469, 471,
+	472
+};
+
+/* GSM 05.03 3.9.4.4 */
+const unsigned int GSM::gAMRPuncturedTCH_AFS6_7[128] = {
+	1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107, 119, 135, 147,
+	159, 175, 187, 199, 215, 227, 239, 255, 267, 279, 287, 291, 295,
+	299, 303, 307, 311, 315, 319, 323, 327, 331, 335, 339, 343, 347,
+	351, 355, 359, 363, 367, 369, 371, 375, 377, 379, 383, 385, 387,
+	391, 393, 395, 399, 401, 403, 407, 409, 411, 415, 417, 419, 423,
+	425, 427, 431, 433, 435, 439, 441, 443, 447, 449, 451, 455, 457,
+	459, 463, 465, 467, 471, 473, 475, 479, 481, 483, 487, 489, 491,
+	495, 497, 499, 503, 505, 507, 511, 513, 515, 519, 521, 523, 527,
+	529, 531, 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557,
+	559, 561, 563, 565, 567, 569, 571, 573, 575
+};
+
+/* GSM 05.03 3.9.4.4 */
+const unsigned int GSM::gAMRPuncturedTCH_AFS5_9[72] = {
+	0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95, 111, 127, 143,
+	159, 175, 191, 207, 223, 239, 255, 271, 287, 303, 319, 327, 331,
+	335, 343, 347, 351, 359, 363, 367, 375, 379, 383, 391, 395, 399,
+	407, 411, 415, 423, 427, 431, 439, 443, 447, 455, 459, 463, 467,
+	471, 475, 479, 483, 487, 491, 495, 499, 503, 507, 509, 511, 512,
+	513, 515, 516, 517, 519
+};
+
+/* GSM 05.03 3.9.4.4 */
+const unsigned int GSM::gAMRPuncturedTCH_AFS5_15[117] = {
+	0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40, 50, 60, 70,
+	80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200,
+	210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 315, 320,
+	325, 330, 334, 335, 340, 344, 345, 350, 354, 355, 360, 364, 365,
+	370, 374, 375, 380, 384, 385, 390, 394, 395, 400, 404, 405, 410,
+	414, 415, 420, 424, 425, 430, 434, 435, 440, 444, 445, 450, 454,
+	455, 460, 464, 465, 470, 474, 475, 480, 484, 485, 490, 494, 495,
+	500, 504, 505, 510, 514, 515, 520, 524, 525, 529, 530, 534, 535,
+	539, 540, 544, 545, 549, 550, 554, 555, 559, 560, 564
+};
+
+/* GSM 05.03 3.9.4.4 */
+const unsigned int GSM::gAMRPuncturedTCH_AFS4_75[87] = {
+	0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55, 65, 75, 85, 95,
+	105, 115, 125, 135, 145, 155, 165, 175, 185, 195, 205, 215, 225,
+	235, 245, 255, 265, 275, 285, 295, 305, 315, 325, 335, 345, 355,
+	365, 375, 385, 395, 400, 405, 410, 415, 420, 425, 430, 435, 440,
+	445, 450, 455, 459, 460, 465, 470, 475, 479, 480, 485, 490, 495,
+	499, 500, 505, 509, 510, 515, 517, 519, 520, 522, 524, 525, 526,
+	527, 529, 530, 531, 532, 534
+};
+
+/* GSM 05.03 Tables 7-14 */
+const unsigned int *GSM::gAMRBitOrder[8] = {
+	GSM::gAMRBitOrderTCH_AFS12_2,
+	GSM::gAMRBitOrderTCH_AFS10_2,
+	GSM::gAMRBitOrderTCH_AFS7_95,
+	GSM::gAMRBitOrderTCH_AFS7_4,
+	GSM::gAMRBitOrderTCH_AFS6_7,
+	GSM::gAMRBitOrderTCH_AFS5_9,
+	GSM::gAMRBitOrderTCH_AFS5_15,
+	GSM::gAMRBitOrderTCH_AFS4_75
+};
+
+/* GSM 05.03 3.9.4.2 */
+const unsigned int GSM::gAMRKd[9] = {244, 204, 159, 148, 134, 118, 103, 95, 260};	// The last entry is for TCH_FS (GSM mode)
+
+/* GSM 05.03 3.9.4.2 */
+const unsigned int GSM::gAMRClass1ALth[8] = {81, 65, 75, 61, 55, 55, 49, 39};
+
+/* GSM 05.03 3.9.4.4 */
+const unsigned int GSM::gAMRTCHUCLth[8] = {508, 642, 513, 474, 576, 520, 565, 535};
+
+/* GSM 05.03 3.9.4.2 */
+const unsigned int GSM::gAMRPunctureLth[8] = {60, 194, 65, 26, 128, 72, 117, 87};
+
+/* GSM 05.03 3.9.4.4 */
+const unsigned int *GSM::gAMRPuncture[8] = {
+	GSM::gAMRPuncturedTCH_AFS12_2,
+	GSM::gAMRPuncturedTCH_AFS10_2,
+	GSM::gAMRPuncturedTCH_AFS7_95,
+	GSM::gAMRPuncturedTCH_AFS7_4,
+	GSM::gAMRPuncturedTCH_AFS6_7,
+	GSM::gAMRPuncturedTCH_AFS5_9,
+	GSM::gAMRPuncturedTCH_AFS5_15,
+	GSM::gAMRPuncturedTCH_AFS4_75
+};
+
+
diff --git a/lib/decoding/GSM503Tables.h b/lib/decoding/GSM503Tables.h
new file mode 100644
index 0000000..6b6327c
--- /dev/null
+++ b/lib/decoding/GSM503Tables.h
@@ -0,0 +1,71 @@
+/*
+* Copyright 2012, 2014 Range Networks, Inc.
+*
+* This software is distributed under multiple licenses; see the COPYING file in the main directory for licensing information for this specific distribution.
+*
+* This use of this software may be subject to additional restrictions.
+* See the LEGAL file in the main directory for details.
+
+    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.
+
+*/
+
+
+
+#ifndef GSM503TABLES_H
+#define GSM503TABLES_H
+
+
+
+namespace GSM {
+
+// don't change the positions in this enum
+// (pat) The first 8 values are used as indicies into numerous tables.
+// (pat) Encoder/decoder mode includes 8 modes for AMR + TCH_FS makes 9.
+// TODO: Add AFS_SID type.  And why is it not type 8?
+enum AMRMode {TCH_AFS12_2, TCH_AFS10_2, TCH_AFS7_95, TCH_AFS7_4, TCH_AFS6_7, TCH_AFS5_9, TCH_AFS5_15, TCH_AFS4_75, TCH_FS};
+
+/** Tables #7-14 from GSM 05.03 */
+extern const unsigned int gAMRBitOrderTCH_AFS12_2[244];
+extern const unsigned int gAMRBitOrderTCH_AFS10_2[204];
+extern const unsigned int gAMRBitOrderTCH_AFS7_95[159];
+extern const unsigned int gAMRBitOrderTCH_AFS7_4[148];
+extern const unsigned int gAMRBitOrderTCH_AFS6_7[134];
+extern const unsigned int gAMRBitOrderTCH_AFS5_9[118];
+extern const unsigned int gAMRBitOrderTCH_AFS5_15[103];
+extern const unsigned int gAMRBitOrderTCH_AFS4_75[95];
+
+/** GSM 05.03 3.9.4.4 */
+extern const unsigned int gAMRPuncturedTCH_AFS12_2[60];
+extern const unsigned int gAMRPuncturedTCH_AFS10_2[194];
+extern const unsigned int gAMRPuncturedTCH_AFS7_95[65];
+extern const unsigned int gAMRPuncturedTCH_AFS7_4[26];
+extern const unsigned int gAMRPuncturedTCH_AFS6_7[128];
+extern const unsigned int gAMRPuncturedTCH_AFS5_9[72];
+extern const unsigned int gAMRPuncturedTCH_AFS5_15[117];
+extern const unsigned int gAMRPuncturedTCH_AFS4_75[87];
+
+/* GSM 05.03 Tables 7-14 */
+extern const unsigned *gAMRBitOrder[8];
+
+/* GSM 05.03 3.9.4.2 */
+extern const unsigned gAMRKd[9];
+
+/* GSM 05.03 3.9.4.2 */
+extern const unsigned gAMRClass1ALth[8];
+
+/* GSM 05.03 3.9.4.4 */
+extern const unsigned gAMRTCHUCLth[8];
+
+/* GSM 05.03 3.9.4.2 */
+extern const unsigned gAMRPunctureLth[8];
+
+/* GSM 05.03 3.9.4.4 */
+extern const unsigned *gAMRPuncture[8];
+
+}
+
+
+#endif
diff --git a/lib/decoding/VocoderFrame.h b/lib/decoding/VocoderFrame.h
index 28d57c3..1651a29 100644
--- a/lib/decoding/VocoderFrame.h
+++ b/lib/decoding/VocoderFrame.h
@@ -40,4 +40,23 @@
 
 };
 
+class VocoderAMR_5_9_Frame : public BitVector {
+
+        public:
+
+        VocoderAMR_5_9_Frame()
+                :BitVector(118+8)
+        { fillField(0,0x14,8); /* AMR-NB 12.2 */ }
+
+        /** Construct by unpacking a char[32]. */
+        VocoderAMR_5_9_Frame(const unsigned char *src)
+                :BitVector(118+8)
+        { unpack(src); }
+
+        BitVector payload() { return tail(8); }
+//        const BitVector payload() const { return tail(8); }
+
+};
+
+
 #endif
diff --git a/lib/decoding/tch_f_decoder_impl.cc b/lib/decoding/tch_f_decoder_impl.cc
index 12163c9..b4ff24f 100644
--- a/lib/decoding/tch_f_decoder_impl.cc
+++ b/lib/decoding/tch_f_decoder_impl.cc
@@ -52,13 +52,16 @@
       d_collected_bursts_num(0),
       mBlockCoder(0x10004820009ULL, 40, 224),
       mU(228),
-      mP(mU.segment(184,40)), mD(mU.head(184)), mDP(mU.head(224)),
+      mP(mU.segment(184,40)),
+      mD(mU.head(184)),
+      mDP(mU.head(224)),
       mC(CONV_SIZE),
       mClass1_c(mC.head(378)),
       mClass2_c(mC.segment(378, 78)),
       mTCHU(189),
       mTCHD(260),
-      mClass1A_d(mTCHD.head(50))
+      mClass1A_d(mTCHD.head(50)),
+      mTCHParity(0x0b, 3, 50)
     {
         d_speech_file = fopen( file.c_str(), "wb" );
         if (d_speech_file == NULL)
@@ -83,6 +86,8 @@
         message_port_register_in(pmt::mp("bursts"));
         set_msg_handler(pmt::mp("bursts"), boost::bind(&tch_f_decoder_impl::decode, this, _1));
         message_port_register_out(pmt::mp("msgs"));
+
+        setCodingMode(mode);
     }
 
     tch_f_decoder_impl::~tch_f_decoder_impl()
@@ -159,75 +164,203 @@
                 }
             }
 
-            mVR204Coder.decode(mClass1_c, mTCHU);
-            mClass2_c.sliced().copyToSegment(mTCHD, 182);
-
-            // 3.1.2.1
-            // copy class 1 bits u[] to d[]
-            for (unsigned k = 0; k <= 90; k++) {
-              mTCHD[2*k] = mTCHU[k];
-              mTCHD[2*k+1] = mTCHU[184-k];
-            }
-
-            Parity mTCHParity(0x0b, 3, 50);
-
-            // 3.1.2.1
-            // check parity of class 1A
-            unsigned sentParity = (~mTCHU.peekField(91, 3)) & 0x07;
-            unsigned calcParity = mClass1A_d.parity(mTCHParity) & 0x07;
-
-            bool good = (sentParity == calcParity);
-
-            if (good)
+            // Decode voice frames and write to file
+            if (d_tch_mode == TCH_FS || d_tch_mode == TCH_EFR)
             {
-                unsigned char mTCHFrame[33];
-                unsigned int  mTCHFrameLength;
+                mVR204Coder.decode(mClass1_c, mTCHU);
+                mClass2_c.sliced().copyToSegment(mTCHD, 182);
 
-                if (d_tch_mode == TCH_FS) // GSM-FR
-                {
-                    // Undo Um's importance-sorted bit ordering.
-                    // See GSM 05.03 3.1 and Tablee 2.
-                    VocoderFrame mVFrame;
-
-                    BitVector payload = mVFrame.payload();
-                    mTCHD.unmap(GSM::g610BitOrder, 260, payload);
-                    mVFrame.pack(mTCHFrame);
-                    mTCHFrameLength = 33;
+                // 3.1.2.1
+                // copy class 1 bits u[] to d[]
+                for (unsigned k = 0; k <= 90; k++) {
+                  mTCHD[2*k] = mTCHU[k];
+                  mTCHD[2*k+1] = mTCHU[184-k];
                 }
-                else if (d_tch_mode == TCH_EFR) // GSM-EFR / AMR 12.2
+
+                // 3.1.2.1
+                // check parity of class 1A
+                unsigned sentParity = (~mTCHU.peekField(91, 3)) & 0x07;
+                unsigned calcParity = mClass1A_d.parity(mTCHParity) & 0x07;
+
+                bool good = (sentParity == calcParity);
+
+                if (good)
                 {
-                    VocoderAMRFrame mVFrameAMR;
+                    unsigned char frameBuffer[33];
+                    unsigned int  mTCHFrameLength;
 
-                    BitVector payload = mVFrameAMR.payload();
-                    BitVector TCHW(260), EFRBits(244);
+                    if (d_tch_mode == TCH_FS) // GSM-FR
+                    {
+                        unsigned char mFrameHeader = 0x0d;
+                        mTCHFrameLength = 33;
 
-                    // Undo Um's EFR bit ordering.
-                    mTCHD.unmap(GSM::g660BitOrder, 260, TCHW);
+                        // Undo Um's importance-sorted bit ordering.
+                        // See GSM 05.03 3.1 and Table 2.
+                        BitVector frFrame(260 + 4); // FR has a frameheader of 4 bits only
+                        BitVector payload = frFrame.tail(4);
 
-                    // Remove repeating bits and CRC to get raw EFR frame (244 bits)
-                    for (unsigned k=0; k<71; k++)
-                      EFRBits[k] = TCHW[k] & 1;
+                        mTCHD.unmap(GSM::g610BitOrder, 260, payload);
+                        frFrame.pack(frameBuffer);
 
-                    for (unsigned k=73; k<123; k++)
-                      EFRBits[k-2] = TCHW[k] & 1;
+                    }
+                    else if (d_tch_mode == TCH_EFR) // GSM-EFR
+                    {
+                        unsigned char mFrameHeader = 0x3c;
 
-                    for (unsigned k=125; k<178; k++)
-                      EFRBits[k-4] = TCHW[k] & 1;
+                        // AMR Frame, consisting of a 8 bit frame header, plus the payload from decoding
+                        BitVector amrFrame(244 + 8); // Same output length as AMR 12.2
+                        BitVector payload = amrFrame.tail(8);
 
-                    for (unsigned k=180; k<230; k++)
-                      EFRBits[k-6] = TCHW[k] & 1;
+                        BitVector TCHW(260), EFRBits(244);
 
-                    for (unsigned k=232; k<252; k++)
-                      EFRBits[k-8] = TCHW[k] & 1;
+                        // write frame header
+                        amrFrame.fillField(0, mFrameHeader, 8);
 
-                    // Map bits as AMR 12.2k
-                    EFRBits.map(GSM::g690_12_2_BitOrder, 244, payload);
+                        // Undo Um's EFR bit ordering.
+                        mTCHD.unmap(GSM::g660BitOrder, 260, TCHW);
 
-                    // Put the whole frame (hdr + payload)
-                    mVFrameAMR.pack(mTCHFrame);
-                    mTCHFrameLength = 32;
+                        // Remove repeating bits and CRC to get raw EFR frame (244 bits)
+                        for (unsigned k=0; k<71; k++)
+                          EFRBits[k] = TCHW[k] & 1;
+
+                        for (unsigned k=73; k<123; k++)
+                          EFRBits[k-2] = TCHW[k] & 1;
+
+                        for (unsigned k=125; k<178; k++)
+                          EFRBits[k-4] = TCHW[k] & 1;
+
+                        for (unsigned k=180; k<230; k++)
+                          EFRBits[k-6] = TCHW[k] & 1;
+
+                        for (unsigned k=232; k<252; k++)
+                          EFRBits[k-8] = TCHW[k] & 1;
+
+                        // Map bits as AMR 12.2k
+                        EFRBits.map(GSM::g690_12_2_BitOrder, 244, payload);
+
+                        // Put the whole frame (hdr + payload)
+                        mTCHFrameLength = 32;
+                        amrFrame.pack(frameBuffer);
+
+                    }
+                    fwrite(frameBuffer, 1 , mTCHFrameLength, d_speech_file);
                 }
-                fwrite(mTCHFrame, 1 , mTCHFrameLength, d_speech_file);
+            }
+            else
+            {
+                // Handle inband bits, see 3.9.4.1
+                // OpenBTS source takes last 8 bits as inband bits for some reason. This may be either a
+                // divergence between their implementation and GSM specification, which works because
+                // both their encoder and decoder do it same way, or they handle the issue at some other place
+                // SoftVector cMinus8 = mC.segment(0, mC.size() - 8);
+                SoftVector cMinus8 = mC.segment(8, mC.size());
+                cMinus8.copyUnPunctured(mTCHUC, mPuncture, mPunctureLth);
+
+                // 3.9.4.4
+                // decode from uc[] to u[]
+                mViterbi->decode(mTCHUC, mTCHU);
+
+                // 3.9.4.3 -- class 1a bits in u[] to d[]
+                for (unsigned k=0; k < mClass1ALth; k++) {
+                    mTCHD[k] = mTCHU[k];
+                }
+
+                // 3.9.4.3 -- class 1b bits in u[] to d[]
+                for (unsigned k=0; k < mClass1BLth; k++) {
+                    mTCHD[k+mClass1ALth] = mTCHU[k+mClass1ALth+6];
+                }
+
+                // Check parity
+                unsigned sentParity = (~mTCHU.peekField(mClass1ALth,6)) & 0x3f;
+                BitVector class1A = mTCHU.segment(0, mClass1ALth);
+                unsigned calcParity = class1A.parity(mTCHParity) & 0x3f;
+
+                bool good = (sentParity == calcParity);
+
+                if (good)
+                {
+                    unsigned char frameBuffer[mAMRFrameLth];
+                    // AMR Frame, consisting of a 8 bit frame header, plus the payload from decoding
+                    BitVector amrFrame(mKd + 8);
+                    BitVector payload = amrFrame.tail(8);
+
+                    // write frame header
+                    amrFrame.fillField(0, mAMRFrameHeader, 8);
+
+                    // We don't unmap here, but copy the decoded bits directly
+                    // Decoder already delivers correct bit order
+                    // mTCHD.unmap(mAMRBitOrder, payload.size(), payload);
+                    mTCHD.copyTo(payload);
+                    amrFrame.pack(frameBuffer);
+                    fwrite(frameBuffer, 1 , mAMRFrameLth, d_speech_file);
+                }
+            }
+        }
+    }
+
+    void tch_f_decoder_impl::setCodingMode(tch_mode mode)
+    {
+        if (d_tch_mode  != TCH_FS && d_tch_mode != TCH_EFR)
+        {
+            mKd = GSM::gAMRKd[d_tch_mode];
+            mTCHD.resize(mKd);
+            mTCHU.resize(mKd+6);
+            mTCHParity = Parity(0x06f,6, GSM::gAMRClass1ALth[d_tch_mode]);
+            mAMRBitOrder = GSM::gAMRBitOrder[d_tch_mode];
+            mClass1ALth = GSM::gAMRClass1ALth[d_tch_mode];
+            mClass1BLth = GSM::gAMRKd[d_tch_mode] - GSM::gAMRClass1ALth[d_tch_mode];
+            mTCHUC.resize(GSM::gAMRTCHUCLth[d_tch_mode]);
+            mPuncture = GSM::gAMRPuncture[d_tch_mode];
+            mPunctureLth = GSM::gAMRPunctureLth[d_tch_mode];
+            mClass1A_d.dup(mTCHD.head(mClass1ALth));
+
+            switch (d_tch_mode)
+            {
+                case TCH_AFS12_2:
+                    mViterbi = new ViterbiTCH_AFS12_2();
+                    mAMRFrameLth = 32;
+                    mAMRFrameHeader = 0x3c;
+                    break;
+                case TCH_AFS10_2:
+                    mViterbi = new ViterbiTCH_AFS10_2();
+                    mAMRFrameLth = 27;
+                    mAMRFrameHeader = 0x3c;
+                    break;
+                case TCH_AFS7_95:
+                    mViterbi = new ViterbiTCH_AFS7_95();
+                    mAMRFrameLth = 21;
+                    mAMRFrameHeader = 0x3c;
+                    break;
+                case TCH_AFS7_4:
+                    mViterbi = new ViterbiTCH_AFS7_4();
+                    mAMRFrameLth = 20;
+                    mAMRFrameHeader = 0x3c;
+                    break;
+                case TCH_AFS6_7:
+                    mViterbi = new ViterbiTCH_AFS6_7();
+                    mAMRFrameLth = 18;
+                    mAMRFrameHeader = 0x3c;
+                    break;
+                case TCH_AFS5_9:
+                    mViterbi = new ViterbiTCH_AFS5_9();
+                    mAMRFrameLth = 16;
+                    mAMRFrameHeader = 0x14;
+                    break;
+                case TCH_AFS5_15:
+                    mViterbi = new ViterbiTCH_AFS5_15();
+                    mAMRFrameLth = 14;
+                    mAMRFrameHeader = 0x3c;
+                    break;
+                case TCH_AFS4_75:
+                    mViterbi = new ViterbiTCH_AFS4_75();
+                    mAMRFrameLth = 13;
+                    mAMRFrameHeader = 0x3c;
+                    break;
+                default:
+                    mViterbi = new ViterbiTCH_AFS12_2();
+                    mAMRFrameLth = 32;
+                    mAMRFrameHeader = 0x3c;
+                    break;
             }
         }
     }
diff --git a/lib/decoding/tch_f_decoder_impl.h b/lib/decoding/tch_f_decoder_impl.h
index 90854cb..d603845 100644
--- a/lib/decoding/tch_f_decoder_impl.h
+++ b/lib/decoding/tch_f_decoder_impl.h
@@ -23,7 +23,10 @@
 #ifndef INCLUDED_GSM_TCH_F_DECODER_IMPL_H
 #define INCLUDED_GSM_TCH_F_DECODER_IMPL_H
 
+#include "AmrCoder.h"
+#include "BitVector.h"
 #include "VocoderFrame.h"
+#include "GSM503Tables.h"
 #include "GSM610Tables.h"
 #include "GSM660Tables.h"
 #include "GSM690Tables.h"
@@ -53,26 +56,39 @@
                 pmt::pmt_t d_bursts[8];
                 FILE * d_speech_file;
                 enum tch_mode d_tch_mode;
-                void decode(pmt::pmt_t msg);
-                const unsigned char amr_nb_magic[6] = { 0x23, 0x21, 0x41, 0x4d, 0x52, 0x0a };
-
-                ViterbiR2O4 mVR204Coder;
 
                 BitVector mU;
                 BitVector mP;
                 BitVector mD;
                 BitVector mDP;
-                Parity mBlockCoder;
-
-                unsigned char iBLOCK[2*BLOCKS*iBLOCK_SIZE];
-                SoftVector mC;
-                SoftVector mClass1_c;
-                SoftVector mClass2_c;
                 BitVector mTCHU;
                 BitVector mTCHD;
                 BitVector mClass1A_d;
+                SoftVector mC;
+                SoftVector mClass1_c;
+                SoftVector mClass2_c;
+                SoftVector mTCHUC;
 
+                Parity mBlockCoder;
+                Parity mTCHParity;
 
+                ViterbiR2O4 mVR204Coder;
+                ViterbiBase *mViterbi;
+
+                const unsigned char amr_nb_magic[6] = { 0x23, 0x21, 0x41, 0x4d, 0x52, 0x0a };
+                unsigned char iBLOCK[2*BLOCKS*iBLOCK_SIZE];
+                unsigned char mAMRFrameHeader;
+
+                const unsigned *mAMRBitOrder;
+                const unsigned *mPuncture;
+                unsigned mClass1ALth;
+                unsigned mClass1BLth;
+                unsigned mPunctureLth;
+                uint8_t mAMRFrameLth;
+                uint8_t mKd;
+
+                void decode(pmt::pmt_t msg);
+                void setCodingMode(tch_mode mode);
             public:
                 tch_f_decoder_impl(tch_mode mode, const std::string &file);
                 ~tch_f_decoder_impl();
