Exemplo n.º 1
0
void rateMatchFunc(BitVector &in,BitVector &out, int eini)
{
	int nin = in.size();
	int nout = out.size();
	if (nout == nin) {
		in.copyTo(out);
		return;
	}
	int eplus = 2 * nin;				// eplus = a * Ni,j
	int eminus = 2 * (nout - nin);	// eminus = a * abs(deltaNi,j)
	if (eminus < 0) { eminus = - eminus; }
	float e = eini;
	int m; // index of current bit, except zero-based as opposed to spec that is 1 based.
	char *inp = in.begin();		// cheating just a bit for efficiency.
	char *outp = out.begin();
	char *outend = out.end();
	if (nout < nin) {
		// Puncture bits as necessary.
		// Note from spec: loop termination Xi == Xij == number of bits before rate matching == nin.
		for (m=0; m < nin && outp < outend; m++) {
			e = e - eminus;
			if (e <= 0) {
				e = e + eplus;
				continue;		// skip the bit.
			}
			*outp++ = inp[m];
		}
	} else {
		// Repeat bits as necessary.
		for (m=0; m < nin && outp < outend; m++) {
			e = e - eminus;
			while (e <= 0) {
				if (outp >= outend) goto failed;
				*outp++ = inp[m];	// repeat the bit.
				e = e + eplus;
			}
			*outp++ = inp[m];
		}
	}
	if (m != nin || outp != outend) {
		failed:
		LOG(ERR) << "rate matching mis-calculation, results:"
			<<LOGVAR(nin)<<LOGVAR(m)<<LOGVAR(nout)<<LOGVAR2(outp,outp-out.begin())
			<<LOGVAR(e)<<LOGVAR(eplus)<<LOGVAR(eminus)<<LOGVAR(eini);
	}
}
Exemplo n.º 2
0
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++;
		}
	}
}