Exemple #1
0
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];
	}
}
Exemple #2
0
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];
	}
}
Exemple #3
0
int testIterator (size_t n, size_t k)
{
	commentator.start ("Testing BitSubvector::word_iterator", __FUNCTION__);

	bool pass = true;

	std::ostream &error = commentator.report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR);

	BitVector<Endianness> v (n);

	BitVector<Endianness>::word_iterator w;
	unsigned int flip = 0;
	
	for (w = v.word_begin (); w != v.word_end (); ++w, flip = 1 - flip)
		*w = pattern[flip];

	v.back_word () = pattern[flip];

	size_t offset;
	
	for (offset = 0; offset <= n - k; ++offset) {
		BitSubvector<BitVector<Endianness>::iterator> vp (v.begin () + offset, v.begin () + (offset + k));

		BitSubvector<BitVector<Endianness>::iterator>::word_iterator i;
		BitSubvector<BitVector<Endianness>::iterator>::const_word_iterator j1, j2;

		flip = ((offset / WordTraits<BitVector<Endianness>::word_type>::bits) % 2 == 0) ? 0 : 1;
				
		for (i = vp.word_begin (), j1 = vp.word_begin (), j2 = vp.word_begin (); i != vp.word_end (); ++i, ++j1, ++j2, flip = 1 - flip) {
			if (*j1 != *i) {
				error << "ERROR: error at offset " << offset << " (n = " << n << ", k = " << k << ")" << std::endl;
				error << "ERROR: word_iterator and const_word_iterator don't agree" << std::endl;
				error << "ERROR: word_iterator: " << std::hex << *i << std::endl;
				error << "ERROR: const_word_iterator: " << std::hex << *j1 << std::endl;
				pass = false;
				goto end_test;
			}

			BitVector<Endianness>::word_type val = *j1;
			
			*i ^= val;
			
			if (*j2 != 0) {
				error << "ERROR: error at offset " << offset << " (n = " << n << ", k = " << k << ")" << std::endl;
				error << "ERROR: Pattern should be 0 after clearing" << std::endl;
				error << "ERROR: Detected " << std::hex << *j2 << std::endl;
				pass = false;
				goto end_test;
			}

			*i ^= val;
		}
	}

end_test:
	commentator.stop (MSG_STATUS (pass));

	return pass;
}
TEST(BoolManager, GetVector)
{
    BoolManager bm;
    BitVector bv = bm.getBitVector("a", 2);
    ASSERT_EQ(bv.size(), 2);
    EXPECT_EQ(bv.begin()->toString(), "a[0]");
    EXPECT_EQ((bv.begin() + 1)->toString(), "a[1]");
}
Exemple #5
0
bool testWordLength (size_t n, size_t k)
{
	commentator.start ("Testing word-length", __FUNCTION__);

	bool pass = true;

	std::ostream &error = commentator.report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR);

	BitVector<Endianness> v (n);

	BitVector<Endianness>::word_iterator w;
	unsigned int flip = 0;
	
	for (w = v.word_begin (); w != v.word_end (); ++w, flip = 1 - flip)
		*w = pattern[flip];

	size_t offset;

	size_t correct_len = k / WordTraits<BitVector<Endianness>::word_type>::bits;

	if (k % WordTraits<BitVector<Endianness>::word_type>::bits != 0)
		++correct_len;

	--correct_len; // New semantics
	
	for (offset = 0; offset <= n - k; ++offset) {
		BitSubvector<BitVector<Endianness>::iterator> vp (v.begin () + offset, v.begin () + (offset + k));

		BitSubvector<BitVector<Endianness>::iterator>::word_iterator i;
		BitSubvector<BitVector<Endianness>::iterator>::const_word_iterator j;

		size_t len;

		for (i = vp.word_begin (), len = 0; i != vp.word_end (); ++i, ++len);
		
		if (len != correct_len) {
			error << "ERROR: error at offset " << offset << std::endl;
			error << "ERROR: length for word_iterator should be " << correct_len << std::endl;
			error << "ERROR: but computed " << len << std::endl;
			pass = false;
		}

		for (j = vp.word_begin (), len = 0; j != vp.word_end (); ++j, ++len);
		
		if (len != correct_len) {
			error << "ERROR: error at offset " << offset << std::endl;
			error << "ERROR: length for const_word_iterator should be " << correct_len << std::endl;
			error << "ERROR: but computed " << len << std::endl;
			pass = false;
		}
	}

	commentator.stop (MSG_STATUS (pass));

	return pass;
}
Exemple #6
0
bool testConstIterator (size_t n, size_t k)
{
	commentator.start ("Testing BitSubvector::const_word_iterator", __FUNCTION__);

	bool pass = true;

	std::ostream &error = commentator.report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR);

	BitVector<Endianness> v (n);

	BitVector<Endianness>::word_iterator w;
	unsigned int flip = 0;
	
	for (w = v.word_begin (); w != v.word_end (); ++w, flip = 1 - flip)
		*w = pattern[flip];

	v.back_word () = pattern[flip];

	size_t offset;
	
	for (offset = 0; offset <= n - k; ++offset) {
		BitSubvector<BitVector<Endianness>::const_iterator> vp (v.begin () + offset, v.begin () + (offset + k));

		BitSubvector<BitVector<Endianness>::const_iterator>::const_word_iterator i;

		flip = ((offset / WordTraits<BitVector<Endianness>::word_type>::bits) % 2 == 0) ? 0 : 1;

		size_t idx = 0;
				
		for (i = vp.word_begin (); i != vp.word_end (); ++i, flip = 1 - flip, idx += WordTraits<BitVector<Endianness>::word_type>::bits) {
			BitVector<Endianness>::word_type check = connect (pattern[flip], pattern[1-flip], offset % WordTraits<BitVector<Endianness>::word_type>::bits);

			if (idx + WordTraits<BitVector<Endianness>::word_type>::bits > k)
				check &= Endianness::mask_left (k % WordTraits<BitVector<Endianness>::word_type>::bits);
			
			if (*i != check) {
				error << "ERROR: error at offset " << offset << std::endl;
				error << "ERROR: Pattern should be " << std::hex << check << std::endl;
				error << "ERROR: Detected " << std::hex << *i << std::endl;
				pass = false;
				goto end_test;
			}
		}
	}

end_test:
	commentator.stop (MSG_STATUS (pass));

	return pass;
}
Exemple #7
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);
	}
}
Exemple #8
0
int testBackWord ()
{
	commentator.start ("Testing back_word", __FUNCTION__);

	bool pass = true;

	std::ostream &error = commentator.report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR);

	static const int n = 3 * WordTraits<BitVector<Endianness>::word_type>::bits;
	static const int k = 16;

	BitVector<Endianness> v (n);

	BitVector<Endianness>::word_iterator w;
	
	size_t offset;
	unsigned int flip = 0;
	
	for (offset = 0; offset < WordTraits<BitVector<Endianness>::word_type>::bits; ++offset, flip = 1 - flip) {
		BitSubvector<BitVector<Endianness>::iterator> vp1 (v.begin () + offset, v.begin () + (offset + k));
		BitSubvector<BitVector<Endianness>::const_iterator> vp2 (v.begin () + offset, v.begin () + (offset + WordTraits<BitVector<Endianness>::word_type>::bits));

		vp1.back_word () = pattern[flip];

		BitVector<Endianness>::word_type check = pattern[flip] & Endianness::mask_left (k);

		if (vp1.back_word () != check) {
			error << "ERROR: error at offset " << std::dec << offset << " (rereading back_word)" << std::endl;
			error << "ERROR: Pattern should be " << std::hex << check << std::endl;
			error << "ERROR: Detected " << std::hex << vp1.back_word () << std::endl;
			pass = false;
		}

		if (vp2.front_word () != check) {
			error << "ERROR: error at offset " << std::dec << offset << " (checking against a const subvector)" << std::endl;
			error << "ERROR: Pattern should be " << std::hex << check << std::endl;
			error << "ERROR: Detected " << std::hex << vp2.front_word () << std::endl;
			pass = false;
		}
	}

	commentator.stop (MSG_STATUS (pass));

	return pass;
}
Exemple #9
0
//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];
	}
}
Exemple #10
0
//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];
	}
}
Exemple #11
0
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];
	}
}
Exemple #12
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++;
		}
	}
}