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
