Example #1
0
FORCE_INLINE
int __ext_viterbi_brick_init_fast(int32 frame_len, int16 code_r, int16 depth) {
	ob_count = 0;
	m_viterbi.Reset();
	frame_length = frame_len;
	code_rate = code_r;
	if (m_outbuf != NULL) free((void *)m_outbuf);
	TRELLIS_DEPTH = (size_t) depth;
	m_outbuf = (unsigned char*) malloc((size_t) (TRELLIS_DEPTH + 1));
	if (m_outbuf == NULL)
	{
	    printf("Viterbi memory allocation failure!\n");
	    exit(1);
	}
	return 0;
}
Example #2
0
FORCE_INLINE
int16 __ext_viterbi_brick_decode_fast(num8 * intInput, int len1, unsigned char* bit, int len2)
{
	static const int trellis_prefix = 6; 	 // 6 bit zero prefix
	static const int trellis_lookahead = 24;

	//uchar  m_outbuf[TRELLIS_DEPTH / 8 + 1];


	unsigned int total_byte_count = 0;

	// vector128 constants
#if defined(__GNUC__) && !defined(__ARM_NEON__)
	static const __m128i * const pVITMA = VIT_MA; // Branch Metric A
	static const __m128i * const pVITMB = VIT_MB; // Branch Metric B
#else
	static const vub * const pVITMA = (const vub*)VIT_MA; // Branch Metric A
	static const vub * const pVITMB = (const vub*)VIT_MB; // Branch Metric B
#endif


	//uchar* input = ipin.peek();
	unsigned char* input = (unsigned char*)intInput;
	//uchar* input_end = input + NUM_INPUT;
	unsigned char* input_end = input + len1;
	while (input < input_end) {
		// advance branch
		if (code_rate == CR_12)
		{
			m_viterbi.BranchACS(pVITMA, input[0], pVITMB, input[1]);
			input += 2; // jump to data
		}
		else if (code_rate == CR_34)
		{
			m_viterbi.BranchACS(pVITMA, input[0], pVITMB, input[1]);
			m_viterbi.BranchACS(pVITMA, input[2]);
			m_viterbi.BranchACS(pVITMB, input[3]);
			input += 4;
		}
		else if (code_rate == CR_23)
		{
			m_viterbi.BranchACS(pVITMA, input[0], pVITMB, input[1]);
			m_viterbi.BranchACS(pVITMA, input[2]);
			input += 3;
		}

		unsigned int tr_index = m_viterbi.trellis_index();

		if ((tr_index & 7) == 0) {
			m_viterbi.Normalize();
		}

		// check trace_back
		unsigned int output_count = 0;
		unsigned int lookahead = 0;
		const unsigned int tr_index_end = frame_length * 8 + trellis_prefix;
		if (tr_index >= tr_index_end) {
			// all bytes have been processed - track back all of them
			output_count = tr_index_end - ob_count
				- trellis_prefix;
			lookahead = tr_index - tr_index_end;
		}
		else if (tr_index >= ob_count + TRELLIS_DEPTH + trellis_lookahead + trellis_prefix)
		{
			// trace back partially

			// Note: tr_index increase during 'BranchACS', to decode out complete bytes, we may lookahead the
			// trellis without output a few more than 'trellis_lookahead'
			unsigned int remain = (tr_index - (ob_count + TRELLIS_DEPTH + trellis_lookahead + trellis_prefix)) % 8;
			output_count = TRELLIS_DEPTH;
			lookahead = trellis_lookahead + remain;
		}

		if (output_count) {
			m_viterbi.Traceback((num8 *)m_outbuf, output_count, lookahead);
			ob_count += output_count;

			unsigned int last_byte_count = 0;
			while (last_byte_count < output_count / 8) {
				bit[total_byte_count] = m_outbuf[last_byte_count];
				last_byte_count++;
				total_byte_count++;
			}
		}

	}
	return total_byte_count * 8;
}
Example #3
0
int16 __ext_viterbi_brick_decode_fast(char* intInput, int len1, uchar* bit, int len2)
{
	static const int trellis_prefix = 6; 	 // 6 bit zero prefix
	static const int trellis_lookahead = 24;

	//uchar  m_outbuf[TRELLIS_DEPTH / 8 + 1];


	uint ii = 0;

	// vector128 constants
	static const vub * const pVITMA = (const vub*)VIT_MA; // Branch Metric A
	static const vub * const pVITMB = (const vub*)VIT_MB; // Branch Metric B


	//uchar* input = ipin.peek();
	uchar* input = (uchar*)intInput;
	//uchar* input_end = input + NUM_INPUT;
	uchar* input_end = input + len1;
	while (input < input_end) {
		// advance branch
		if (code_rate == CR_12)
		{
			m_viterbi.BranchACS(pVITMA, input[0], pVITMB, input[1]);
			input += 2; // jump to data
		}
		else if (code_rate == CR_34)
		{
			m_viterbi.BranchACS(pVITMA, input[0], pVITMB, input[1]);
			m_viterbi.BranchACS(pVITMA, input[2]);
			m_viterbi.BranchACS(pVITMB, input[3]);
			input += 4;
		}
		else if (code_rate == CR_23)
		{
			m_viterbi.BranchACS(pVITMA, input[0], pVITMB, input[1]);
			m_viterbi.BranchACS(pVITMA, input[2]);
			input += 3;
		}

		uint tr_index = m_viterbi.trellis_index();

		if ((tr_index & 7) == 0) {
			m_viterbi.Normalize();
		}

		// check trace_back
		uint output_count = 0;
		uint lookahead = 0;
		const uint tr_index_end = frame_length * 8 + 16 + trellis_prefix;
		if (tr_index >= tr_index_end) {
			// all bytes have been processed - track back all of them
			output_count = tr_index_end - ob_count
				- trellis_prefix;
			lookahead = tr_index - tr_index_end;
		}
		else if (tr_index >= ob_count + TRELLIS_DEPTH + trellis_lookahead + trellis_prefix)
		{
			// trace back partially

			// Note: tr_index increase during 'BranchACS', to decode out complete bytes, we may lookahead the
			// trellis without output a few more than 'trellis_lookahead'
			uint remain = (tr_index - (ob_count + TRELLIS_DEPTH + trellis_lookahead + trellis_prefix)) % 8;
			output_count = TRELLIS_DEPTH;
			lookahead = trellis_lookahead + remain;
		}

		if (output_count) {
			m_viterbi.Traceback((char*)m_outbuf, output_count, lookahead);
			ob_count += output_count;

			//output_count >>= 3;
			while (ii < output_count) {
				//uchar* po = opin().append();
				//*po = m_outbuf[ii++];
				uchar po = m_outbuf[ii];
				bit[ii] = po;
				ii++;
				//printf ("%d (%x) \n", *po, *po );
				//Next()->Process(opin0());
			}
			//printf ( "\n" );
		}

	}
	//ipin.pop();
	return ii;
}