diff options
Diffstat (limited to 'gr-dtv/lib/dvbt/dvbt_viterbi_decoder_impl.cc')
-rw-r--r-- | gr-dtv/lib/dvbt/dvbt_viterbi_decoder_impl.cc | 975 |
1 files changed, 486 insertions, 489 deletions
diff --git a/gr-dtv/lib/dvbt/dvbt_viterbi_decoder_impl.cc b/gr-dtv/lib/dvbt/dvbt_viterbi_decoder_impl.cc index 97b014f9ae..e2acf1180e 100644 --- a/gr-dtv/lib/dvbt/dvbt_viterbi_decoder_impl.cc +++ b/gr-dtv/lib/dvbt/dvbt_viterbi_decoder_impl.cc @@ -1,17 +1,17 @@ /* -*- c++ -*- */ -/* +/* * Copyright 2015,2016 Free Software Foundation, Inc. - * + * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. - * + * * This software 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. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, @@ -26,625 +26,610 @@ #include "dvbt_viterbi_decoder_impl.h" namespace gr { - namespace dtv { - - const unsigned char dvbt_viterbi_decoder_impl::d_puncture_1_2[2] = {1, 1}; - const unsigned char dvbt_viterbi_decoder_impl::d_puncture_2_3[4] = {1, 1, 0, 1}; - const unsigned char dvbt_viterbi_decoder_impl::d_puncture_3_4[6] = {1, 1, 0, 1, 1, 0}; - const unsigned char dvbt_viterbi_decoder_impl::d_puncture_5_6[10] = {1, 1, 0, 1, 1, 0, 0, 1, 1, 0}; - const unsigned char dvbt_viterbi_decoder_impl::d_puncture_7_8[14] = {1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0}; - /* 8-bit parity lookup table, generated by partab.c */ - const unsigned char dvbt_viterbi_decoder_impl::d_Partab[] = { - 0, 1, 1, 0, 1, 0, 0, 1, - 1, 0, 0, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 0, 1, - 1, 0, 0, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 0, 1, - 0, 1, 1, 0, 1, 0, 0, 1, - 1, 0, 0, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 0, 1, - 0, 1, 1, 0, 1, 0, 0, 1, - 1, 0, 0, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 0, 1, - 1, 0, 0, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 0, 1, - 1, 0, 0, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 0, 1, - 0, 1, 1, 0, 1, 0, 0, 1, - 1, 0, 0, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 0, 1, - 1, 0, 0, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 0, 1, - 0, 1, 1, 0, 1, 0, 0, 1, - 1, 0, 0, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 0, 1, - 1, 0, 0, 1, 0, 1, 1, 0, - 0, 1, 1, 0, 1, 0, 0, 1, - 0, 1, 1, 0, 1, 0, 0, 1, - 1, 0, 0, 1, 0, 1, 1, 0, - }; +namespace dtv { + +const unsigned char dvbt_viterbi_decoder_impl::d_puncture_1_2[2] = { 1, 1 }; +const unsigned char dvbt_viterbi_decoder_impl::d_puncture_2_3[4] = { 1, 1, 0, 1 }; +const unsigned char dvbt_viterbi_decoder_impl::d_puncture_3_4[6] = { 1, 1, 0, 1, 1, 0 }; +const unsigned char dvbt_viterbi_decoder_impl::d_puncture_5_6[10] = { 1, 1, 0, 1, 1, + 0, 0, 1, 1, 0 }; +const unsigned char dvbt_viterbi_decoder_impl::d_puncture_7_8[14] = { + 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0 +}; +/* 8-bit parity lookup table, generated by partab.c */ +const unsigned char dvbt_viterbi_decoder_impl::d_Partab[] = { + 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, + 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, + 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, + 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, + 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, + 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, + 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, +}; #ifdef DTV_SSE2 - __GR_ATTR_ALIGNED(16) __m128i dvbt_viterbi_decoder_impl::d_metric0[4]; - __GR_ATTR_ALIGNED(16) __m128i dvbt_viterbi_decoder_impl::d_metric1[4]; - __GR_ATTR_ALIGNED(16) __m128i dvbt_viterbi_decoder_impl::d_path0[4]; - __GR_ATTR_ALIGNED(16) __m128i dvbt_viterbi_decoder_impl::d_path1[4]; +__GR_ATTR_ALIGNED(16) __m128i dvbt_viterbi_decoder_impl::d_metric0[4]; +__GR_ATTR_ALIGNED(16) __m128i dvbt_viterbi_decoder_impl::d_metric1[4]; +__GR_ATTR_ALIGNED(16) __m128i dvbt_viterbi_decoder_impl::d_path0[4]; +__GR_ATTR_ALIGNED(16) __m128i dvbt_viterbi_decoder_impl::d_path1[4]; #else - __GR_ATTR_ALIGNED(16) unsigned char dvbt_viterbi_decoder_impl::d_metric0_generic[64]; - __GR_ATTR_ALIGNED(16) unsigned char dvbt_viterbi_decoder_impl::d_metric1_generic[64]; - __GR_ATTR_ALIGNED(16) unsigned char dvbt_viterbi_decoder_impl::d_path0_generic[64]; - __GR_ATTR_ALIGNED(16) unsigned char dvbt_viterbi_decoder_impl::d_path1_generic[64]; +__GR_ATTR_ALIGNED(16) unsigned char dvbt_viterbi_decoder_impl::d_metric0_generic[64]; +__GR_ATTR_ALIGNED(16) unsigned char dvbt_viterbi_decoder_impl::d_metric1_generic[64]; +__GR_ATTR_ALIGNED(16) unsigned char dvbt_viterbi_decoder_impl::d_path0_generic[64]; +__GR_ATTR_ALIGNED(16) unsigned char dvbt_viterbi_decoder_impl::d_path1_generic[64]; #endif #ifdef DTV_SSE2 - __GR_ATTR_ALIGNED(16) branchtab27 dvbt_viterbi_decoder_impl::Branchtab27_sse2[2]; +__GR_ATTR_ALIGNED(16) branchtab27 dvbt_viterbi_decoder_impl::Branchtab27_sse2[2]; #else - __GR_ATTR_ALIGNED(16) branchtab27 dvbt_viterbi_decoder_impl::Branchtab27_generic[2]; +__GR_ATTR_ALIGNED(16) branchtab27 dvbt_viterbi_decoder_impl::Branchtab27_generic[2]; #endif - __GR_ATTR_ALIGNED(16) unsigned char dvbt_viterbi_decoder_impl::mmresult[64]; - __GR_ATTR_ALIGNED(16) unsigned char dvbt_viterbi_decoder_impl::ppresult[TRACEBACK_MAX][64]; +__GR_ATTR_ALIGNED(16) unsigned char dvbt_viterbi_decoder_impl::mmresult[64]; +__GR_ATTR_ALIGNED(16) +unsigned char dvbt_viterbi_decoder_impl::ppresult[TRACEBACK_MAX][64]; #ifdef DTV_SSE2 - void - dvbt_viterbi_decoder_impl::dvbt_viterbi_chunks_init_sse2(__m128i *mm0, __m128i *pp0) - { +void dvbt_viterbi_decoder_impl::dvbt_viterbi_chunks_init_sse2(__m128i* mm0, __m128i* pp0) +{ #else - void - dvbt_viterbi_decoder_impl::dvbt_viterbi_chunks_init_generic(unsigned char *mm0, unsigned char *pp0) - { +void dvbt_viterbi_decoder_impl::dvbt_viterbi_chunks_init_generic(unsigned char* mm0, + unsigned char* pp0) +{ #endif - // Initialize starting metrics to prefer 0 state - int i, j; + // Initialize starting metrics to prefer 0 state + int i, j; #ifdef DTV_SSE2 - for (i = 0; i < 4; i++) { + for (i = 0; i < 4; i++) { mm0[i] = _mm_setzero_si128(); pp0[i] = _mm_setzero_si128(); - } + } - int polys[2] = { POLYA, POLYB }; - for (i = 0; i < 32; i++) { - Branchtab27_sse2[0].c[i] = (polys[0] < 0) ^ d_Partab[(2*i) & abs(polys[0])] ? 1 : 0; - Branchtab27_sse2[1].c[i] = (polys[1] < 0) ^ d_Partab[(2*i) & abs(polys[1])] ? 1 : 0; - } + int polys[2] = { POLYA, POLYB }; + for (i = 0; i < 32; i++) { + Branchtab27_sse2[0].c[i] = + (polys[0] < 0) ^ d_Partab[(2 * i) & abs(polys[0])] ? 1 : 0; + Branchtab27_sse2[1].c[i] = + (polys[1] < 0) ^ d_Partab[(2 * i) & abs(polys[1])] ? 1 : 0; + } #else - for (i = 0; i < 64; i++) { + for (i = 0; i < 64; i++) { mm0[i] = 0; pp0[i] = 0; - } + } - int polys[2] = { POLYA, POLYB }; - for (i = 0; i < 32; i++) { - Branchtab27_generic[0].c[i] = (polys[0] < 0) ^ d_Partab[(2*i) & abs(polys[0])] ? 1 : 0; - Branchtab27_generic[1].c[i] = (polys[1] < 0) ^ d_Partab[(2*i) & abs(polys[1])] ? 1 : 0; - } + int polys[2] = { POLYA, POLYB }; + for (i = 0; i < 32; i++) { + Branchtab27_generic[0].c[i] = + (polys[0] < 0) ^ d_Partab[(2 * i) & abs(polys[0])] ? 1 : 0; + Branchtab27_generic[1].c[i] = + (polys[1] < 0) ^ d_Partab[(2 * i) & abs(polys[1])] ? 1 : 0; + } #endif - for (i = 0; i < 64; i++) { + for (i = 0; i < 64; i++) { mmresult[i] = 0; for (j = 0; j < TRACEBACK_MAX; j++) { - ppresult[j][i] = 0; + ppresult[j][i] = 0; } - } } +} #ifdef DTV_SSE2 - void - dvbt_viterbi_decoder_impl::dvbt_viterbi_butterfly2_sse2(unsigned char *symbols, __m128i *mm0, __m128i *mm1, __m128i *pp0, __m128i *pp1) - { - int i; +void dvbt_viterbi_decoder_impl::dvbt_viterbi_butterfly2_sse2( + unsigned char* symbols, __m128i* mm0, __m128i* mm1, __m128i* pp0, __m128i* pp1) +{ + int i; - __m128i *metric0, *metric1; - __m128i *path0, *path1; + __m128i *metric0, *metric1; + __m128i *path0, *path1; - metric0 = mm0; - path0 = pp0; - metric1 = mm1; - path1 = pp1; + metric0 = mm0; + path0 = pp0; + metric1 = mm1; + path1 = pp1; - // Operate on 4 symbols (2 bits) at a time + // Operate on 4 symbols (2 bits) at a time - __m128i m0, m1, m2, m3, decision0, decision1, survivor0, survivor1; - __m128i metsv, metsvm; - __m128i shift0, shift1; - __m128i tmp0, tmp1; - __m128i sym0v, sym1v; + __m128i m0, m1, m2, m3, decision0, decision1, survivor0, survivor1; + __m128i metsv, metsvm; + __m128i shift0, shift1; + __m128i tmp0, tmp1; + __m128i sym0v, sym1v; - sym0v = _mm_set1_epi8(symbols[0]); - sym1v = _mm_set1_epi8(symbols[1]); + sym0v = _mm_set1_epi8(symbols[0]); + sym1v = _mm_set1_epi8(symbols[1]); - for (i = 0; i < 2; i++) { + for (i = 0; i < 2; i++) { if (symbols[0] == 2) { - metsvm = _mm_xor_si128(Branchtab27_sse2[1].v[i],sym1v); - metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm); - } - else if (symbols[1] == 2) { - metsvm = _mm_xor_si128(Branchtab27_sse2[0].v[i],sym0v); - metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm); - } - else { - metsvm = _mm_add_epi8(_mm_xor_si128(Branchtab27_sse2[0].v[i],sym0v),_mm_xor_si128(Branchtab27_sse2[1].v[i],sym1v)); - metsv = _mm_sub_epi8(_mm_set1_epi8(2),metsvm); + metsvm = _mm_xor_si128(Branchtab27_sse2[1].v[i], sym1v); + metsv = _mm_sub_epi8(_mm_set1_epi8(1), metsvm); + } else if (symbols[1] == 2) { + metsvm = _mm_xor_si128(Branchtab27_sse2[0].v[i], sym0v); + metsv = _mm_sub_epi8(_mm_set1_epi8(1), metsvm); + } else { + metsvm = _mm_add_epi8(_mm_xor_si128(Branchtab27_sse2[0].v[i], sym0v), + _mm_xor_si128(Branchtab27_sse2[1].v[i], sym1v)); + metsv = _mm_sub_epi8(_mm_set1_epi8(2), metsvm); } m0 = _mm_add_epi8(metric0[i], metsv); - m1 = _mm_add_epi8(metric0[i+2], metsvm); + m1 = _mm_add_epi8(metric0[i + 2], metsvm); m2 = _mm_add_epi8(metric0[i], metsvm); - m3 = _mm_add_epi8(metric0[i+2], metsv); + m3 = _mm_add_epi8(metric0[i + 2], metsv); - decision0 = _mm_cmpgt_epi8(_mm_sub_epi8(m0,m1),_mm_setzero_si128()); - decision1 = _mm_cmpgt_epi8(_mm_sub_epi8(m2,m3),_mm_setzero_si128()); - survivor0 = _mm_or_si128(_mm_and_si128(decision0,m0),_mm_andnot_si128(decision0,m1)); - survivor1 = _mm_or_si128(_mm_and_si128(decision1,m2),_mm_andnot_si128(decision1,m3)); + decision0 = _mm_cmpgt_epi8(_mm_sub_epi8(m0, m1), _mm_setzero_si128()); + decision1 = _mm_cmpgt_epi8(_mm_sub_epi8(m2, m3), _mm_setzero_si128()); + survivor0 = + _mm_or_si128(_mm_and_si128(decision0, m0), _mm_andnot_si128(decision0, m1)); + survivor1 = + _mm_or_si128(_mm_and_si128(decision1, m2), _mm_andnot_si128(decision1, m3)); shift0 = _mm_slli_epi16(path0[i], 1); - shift1 = _mm_slli_epi16(path0[2+i], 1); + shift1 = _mm_slli_epi16(path0[2 + i], 1); shift1 = _mm_add_epi8(shift1, _mm_set1_epi8(1)); - metric1[2*i] = _mm_unpacklo_epi8(survivor0,survivor1); - tmp0 = _mm_or_si128(_mm_and_si128(decision0,shift0),_mm_andnot_si128(decision0,shift1)); + metric1[2 * i] = _mm_unpacklo_epi8(survivor0, survivor1); + tmp0 = _mm_or_si128(_mm_and_si128(decision0, shift0), + _mm_andnot_si128(decision0, shift1)); - metric1[2*i+1] = _mm_unpackhi_epi8(survivor0,survivor1); - tmp1 = _mm_or_si128(_mm_and_si128(decision1,shift0),_mm_andnot_si128(decision1,shift1)); + metric1[2 * i + 1] = _mm_unpackhi_epi8(survivor0, survivor1); + tmp1 = _mm_or_si128(_mm_and_si128(decision1, shift0), + _mm_andnot_si128(decision1, shift1)); - path1[2*i] = _mm_unpacklo_epi8(tmp0, tmp1); - path1[2*i+1] = _mm_unpackhi_epi8(tmp0, tmp1); - } + path1[2 * i] = _mm_unpacklo_epi8(tmp0, tmp1); + path1[2 * i + 1] = _mm_unpackhi_epi8(tmp0, tmp1); + } - metric0 = mm1; - path0 = pp1; - metric1 = mm0; - path1 = pp0; + metric0 = mm1; + path0 = pp1; + metric1 = mm0; + path1 = pp0; - sym0v = _mm_set1_epi8(symbols[2]); - sym1v = _mm_set1_epi8(symbols[3]); + sym0v = _mm_set1_epi8(symbols[2]); + sym1v = _mm_set1_epi8(symbols[3]); - for (i = 0; i < 2; i++) { + for (i = 0; i < 2; i++) { if (symbols[2] == 2) { - metsvm = _mm_xor_si128(Branchtab27_sse2[1].v[i],sym1v); - metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm); - } - else if (symbols[3] == 2) { - metsvm = _mm_xor_si128(Branchtab27_sse2[0].v[i],sym0v); - metsv = _mm_sub_epi8(_mm_set1_epi8(1),metsvm); - } - else { - metsvm = _mm_add_epi8(_mm_xor_si128(Branchtab27_sse2[0].v[i],sym0v),_mm_xor_si128(Branchtab27_sse2[1].v[i],sym1v)); - metsv = _mm_sub_epi8(_mm_set1_epi8(2),metsvm); + metsvm = _mm_xor_si128(Branchtab27_sse2[1].v[i], sym1v); + metsv = _mm_sub_epi8(_mm_set1_epi8(1), metsvm); + } else if (symbols[3] == 2) { + metsvm = _mm_xor_si128(Branchtab27_sse2[0].v[i], sym0v); + metsv = _mm_sub_epi8(_mm_set1_epi8(1), metsvm); + } else { + metsvm = _mm_add_epi8(_mm_xor_si128(Branchtab27_sse2[0].v[i], sym0v), + _mm_xor_si128(Branchtab27_sse2[1].v[i], sym1v)); + metsv = _mm_sub_epi8(_mm_set1_epi8(2), metsvm); } m0 = _mm_add_epi8(metric0[i], metsv); - m1 = _mm_add_epi8(metric0[i+2], metsvm); + m1 = _mm_add_epi8(metric0[i + 2], metsvm); m2 = _mm_add_epi8(metric0[i], metsvm); - m3 = _mm_add_epi8(metric0[i+2], metsv); + m3 = _mm_add_epi8(metric0[i + 2], metsv); - decision0 = _mm_cmpgt_epi8(_mm_sub_epi8(m0,m1),_mm_setzero_si128()); - decision1 = _mm_cmpgt_epi8(_mm_sub_epi8(m2,m3),_mm_setzero_si128()); - survivor0 = _mm_or_si128(_mm_and_si128(decision0,m0),_mm_andnot_si128(decision0,m1)); - survivor1 = _mm_or_si128(_mm_and_si128(decision1,m2),_mm_andnot_si128(decision1,m3)); + decision0 = _mm_cmpgt_epi8(_mm_sub_epi8(m0, m1), _mm_setzero_si128()); + decision1 = _mm_cmpgt_epi8(_mm_sub_epi8(m2, m3), _mm_setzero_si128()); + survivor0 = + _mm_or_si128(_mm_and_si128(decision0, m0), _mm_andnot_si128(decision0, m1)); + survivor1 = + _mm_or_si128(_mm_and_si128(decision1, m2), _mm_andnot_si128(decision1, m3)); shift0 = _mm_slli_epi16(path0[i], 1); - shift1 = _mm_slli_epi16(path0[2+i], 1); + shift1 = _mm_slli_epi16(path0[2 + i], 1); shift1 = _mm_add_epi8(shift1, _mm_set1_epi8(1)); - metric1[2*i] = _mm_unpacklo_epi8(survivor0,survivor1); - tmp0 = _mm_or_si128(_mm_and_si128(decision0,shift0),_mm_andnot_si128(decision0,shift1)); + metric1[2 * i] = _mm_unpacklo_epi8(survivor0, survivor1); + tmp0 = _mm_or_si128(_mm_and_si128(decision0, shift0), + _mm_andnot_si128(decision0, shift1)); - metric1[2*i+1] = _mm_unpackhi_epi8(survivor0,survivor1); - tmp1 = _mm_or_si128(_mm_and_si128(decision1,shift0),_mm_andnot_si128(decision1,shift1)); + metric1[2 * i + 1] = _mm_unpackhi_epi8(survivor0, survivor1); + tmp1 = _mm_or_si128(_mm_and_si128(decision1, shift0), + _mm_andnot_si128(decision1, shift1)); - path1[2*i] = _mm_unpacklo_epi8(tmp0, tmp1); - path1[2*i+1] = _mm_unpackhi_epi8(tmp0, tmp1); - } + path1[2 * i] = _mm_unpacklo_epi8(tmp0, tmp1); + path1[2 * i + 1] = _mm_unpackhi_epi8(tmp0, tmp1); } +} #else - void - dvbt_viterbi_decoder_impl::dvbt_viterbi_butterfly2_generic(unsigned char *symbols, unsigned char *mm0, unsigned char *mm1, unsigned char *pp0, unsigned char *pp1) - { - int i, j, k; - - unsigned char *metric0, *metric1; - unsigned char *path0, *path1; - - metric0 = mm0; - path0 = pp0; - metric1 = mm1; - path1 = pp1; - - // Operate on 4 symbols (2 bits) at a time - - unsigned char m0[16], m1[16], m2[16], m3[16], decision0[16], decision1[16], survivor0[16], survivor1[16]; - unsigned char metsv[16], metsvm[16]; - unsigned char shift0[16], shift1[16]; - unsigned char tmp0[16], tmp1[16]; - unsigned char sym0v[16], sym1v[16]; - unsigned short simd_epi16; - - for (j = 0; j < 16; j++) { +void dvbt_viterbi_decoder_impl::dvbt_viterbi_butterfly2_generic(unsigned char* symbols, + unsigned char* mm0, + unsigned char* mm1, + unsigned char* pp0, + unsigned char* pp1) +{ + int i, j, k; + + unsigned char *metric0, *metric1; + unsigned char *path0, *path1; + + metric0 = mm0; + path0 = pp0; + metric1 = mm1; + path1 = pp1; + + // Operate on 4 symbols (2 bits) at a time + + unsigned char m0[16], m1[16], m2[16], m3[16], decision0[16], decision1[16], + survivor0[16], survivor1[16]; + unsigned char metsv[16], metsvm[16]; + unsigned char shift0[16], shift1[16]; + unsigned char tmp0[16], tmp1[16]; + unsigned char sym0v[16], sym1v[16]; + unsigned short simd_epi16; + + for (j = 0; j < 16; j++) { sym0v[j] = symbols[0]; sym1v[j] = symbols[1]; - } + } - for (i = 0; i < 2; i++) { + for (i = 0; i < 2; i++) { if (symbols[0] == 2) { - for (j = 0; j < 16; j++) { - metsvm[j] = Branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]; - metsv[j] = 1 - metsvm[j]; - } - } - else if (symbols[1] == 2) { - for (j = 0; j < 16; j++) { - metsvm[j] = Branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]; - metsv[j] = 1 - metsvm[j]; - } - } - else { - for (j = 0; j < 16; j++) { - metsvm[j] = (Branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]) + (Branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]); - metsv[j] = 2 - metsvm[j]; - } + for (j = 0; j < 16; j++) { + metsvm[j] = Branchtab27_generic[1].c[(i * 16) + j] ^ sym1v[j]; + metsv[j] = 1 - metsvm[j]; + } + } else if (symbols[1] == 2) { + for (j = 0; j < 16; j++) { + metsvm[j] = Branchtab27_generic[0].c[(i * 16) + j] ^ sym0v[j]; + metsv[j] = 1 - metsvm[j]; + } + } else { + for (j = 0; j < 16; j++) { + metsvm[j] = (Branchtab27_generic[0].c[(i * 16) + j] ^ sym0v[j]) + + (Branchtab27_generic[1].c[(i * 16) + j] ^ sym1v[j]); + metsv[j] = 2 - metsvm[j]; + } } for (j = 0; j < 16; j++) { - m0[j] = metric0[(i*16) + j] + metsv[j]; - m1[j] = metric0[((i+2)*16) + j] + metsvm[j]; - m2[j] = metric0[(i*16) + j] + metsvm[j]; - m3[j] = metric0[((i+2)*16) + j] + metsv[j]; + m0[j] = metric0[(i * 16) + j] + metsv[j]; + m1[j] = metric0[((i + 2) * 16) + j] + metsvm[j]; + m2[j] = metric0[(i * 16) + j] + metsvm[j]; + m3[j] = metric0[((i + 2) * 16) + j] + metsv[j]; } for (j = 0; j < 16; j++) { - decision0[j] = ((m0[j] - m1[j]) > 0) ? 0xff : 0x0; - decision1[j] = ((m2[j] - m3[j]) > 0) ? 0xff : 0x0; - survivor0[j] = (decision0[j] & m0[j]) | ((~decision0[j]) & m1[j]); - survivor1[j] = (decision1[j] & m2[j]) | ((~decision1[j]) & m3[j]); + decision0[j] = ((m0[j] - m1[j]) > 0) ? 0xff : 0x0; + decision1[j] = ((m2[j] - m3[j]) > 0) ? 0xff : 0x0; + survivor0[j] = (decision0[j] & m0[j]) | ((~decision0[j]) & m1[j]); + survivor1[j] = (decision1[j] & m2[j]) | ((~decision1[j]) & m3[j]); } for (j = 0; j < 16; j += 2) { - simd_epi16 = path0[(i*16) + j]; - simd_epi16 |= path0[(i*16) + (j+1)] << 8; - simd_epi16 <<= 1; - shift0[j] = simd_epi16; - shift0[j+1] = simd_epi16 >> 8; - - simd_epi16 = path0[((i+2)*16) + j]; - simd_epi16 |= path0[((i+2)*16) + (j+1)] << 8; - simd_epi16 <<= 1; - shift1[j] = simd_epi16; - shift1[j+1] = simd_epi16 >> 8; + simd_epi16 = path0[(i * 16) + j]; + simd_epi16 |= path0[(i * 16) + (j + 1)] << 8; + simd_epi16 <<= 1; + shift0[j] = simd_epi16; + shift0[j + 1] = simd_epi16 >> 8; + + simd_epi16 = path0[((i + 2) * 16) + j]; + simd_epi16 |= path0[((i + 2) * 16) + (j + 1)] << 8; + simd_epi16 <<= 1; + shift1[j] = simd_epi16; + shift1[j + 1] = simd_epi16 >> 8; } for (j = 0; j < 16; j++) { - shift1[j] = shift1[j] + 1; + shift1[j] = shift1[j] + 1; } for (j = 0, k = 0; j < 16; j += 2, k++) { - metric1[(2*i*16) + j] = survivor0[k]; - metric1[(2*i*16) + (j+1)] = survivor1[k]; + metric1[(2 * i * 16) + j] = survivor0[k]; + metric1[(2 * i * 16) + (j + 1)] = survivor1[k]; } for (j = 0; j < 16; j++) { - tmp0[j] = (decision0[j] & shift0[j]) | ((~decision0[j]) & shift1[j]); + tmp0[j] = (decision0[j] & shift0[j]) | ((~decision0[j]) & shift1[j]); } for (j = 0, k = 8; j < 16; j += 2, k++) { - metric1[((2*i+1)*16) + j] = survivor0[k]; - metric1[((2*i+1)*16) + (j+1)] = survivor1[k]; + metric1[((2 * i + 1) * 16) + j] = survivor0[k]; + metric1[((2 * i + 1) * 16) + (j + 1)] = survivor1[k]; } for (j = 0; j < 16; j++) { - tmp1[j] = (decision1[j] & shift0[j]) | ((~decision1[j]) & shift1[j]); + tmp1[j] = (decision1[j] & shift0[j]) | ((~decision1[j]) & shift1[j]); } for (j = 0, k = 0; j < 16; j += 2, k++) { - path1[(2*i*16) + j] = tmp0[k]; - path1[(2*i*16) + (j+1)] = tmp1[k]; + path1[(2 * i * 16) + j] = tmp0[k]; + path1[(2 * i * 16) + (j + 1)] = tmp1[k]; } for (j = 0, k = 8; j < 16; j += 2, k++) { - path1[((2*i+1)*16) + j] = tmp0[k]; - path1[((2*i+1)*16) + (j+1)] = tmp1[k]; + path1[((2 * i + 1) * 16) + j] = tmp0[k]; + path1[((2 * i + 1) * 16) + (j + 1)] = tmp1[k]; } - } + } - metric0 = mm1; - path0 = pp1; - metric1 = mm0; - path1 = pp0; + metric0 = mm1; + path0 = pp1; + metric1 = mm0; + path1 = pp0; - for (j = 0; j < 16; j++) { + for (j = 0; j < 16; j++) { sym0v[j] = symbols[2]; sym1v[j] = symbols[3]; - } + } - for (i = 0; i < 2; i++) { + for (i = 0; i < 2; i++) { if (symbols[2] == 2) { - for (j = 0; j < 16; j++) { - metsvm[j] = Branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]; - metsv[j] = 1 - metsvm[j]; - } - } - else if (symbols[3] == 2) { - for (j = 0; j < 16; j++) { - metsvm[j] = Branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]; - metsv[j] = 1 - metsvm[j]; - } - } - else { - for (j = 0; j < 16; j++) { - metsvm[j] = (Branchtab27_generic[0].c[(i*16) + j] ^ sym0v[j]) + (Branchtab27_generic[1].c[(i*16) + j] ^ sym1v[j]); - metsv[j] = 2 - metsvm[j]; - } + for (j = 0; j < 16; j++) { + metsvm[j] = Branchtab27_generic[1].c[(i * 16) + j] ^ sym1v[j]; + metsv[j] = 1 - metsvm[j]; + } + } else if (symbols[3] == 2) { + for (j = 0; j < 16; j++) { + metsvm[j] = Branchtab27_generic[0].c[(i * 16) + j] ^ sym0v[j]; + metsv[j] = 1 - metsvm[j]; + } + } else { + for (j = 0; j < 16; j++) { + metsvm[j] = (Branchtab27_generic[0].c[(i * 16) + j] ^ sym0v[j]) + + (Branchtab27_generic[1].c[(i * 16) + j] ^ sym1v[j]); + metsv[j] = 2 - metsvm[j]; + } } for (j = 0; j < 16; j++) { - m0[j] = metric0[(i*16) + j] + metsv[j]; - m1[j] = metric0[((i+2)*16) + j] + metsvm[j]; - m2[j] = metric0[(i*16) + j] + metsvm[j]; - m3[j] = metric0[((i+2)*16) + j] + metsv[j]; + m0[j] = metric0[(i * 16) + j] + metsv[j]; + m1[j] = metric0[((i + 2) * 16) + j] + metsvm[j]; + m2[j] = metric0[(i * 16) + j] + metsvm[j]; + m3[j] = metric0[((i + 2) * 16) + j] + metsv[j]; } for (j = 0; j < 16; j++) { - decision0[j] = ((m0[j] - m1[j]) > 0) ? 0xff : 0x0; - decision1[j] = ((m2[j] - m3[j]) > 0) ? 0xff : 0x0; - survivor0[j] = (decision0[j] & m0[j]) | ((~decision0[j]) & m1[j]); - survivor1[j] = (decision1[j] & m2[j]) | ((~decision1[j]) & m3[j]); + decision0[j] = ((m0[j] - m1[j]) > 0) ? 0xff : 0x0; + decision1[j] = ((m2[j] - m3[j]) > 0) ? 0xff : 0x0; + survivor0[j] = (decision0[j] & m0[j]) | ((~decision0[j]) & m1[j]); + survivor1[j] = (decision1[j] & m2[j]) | ((~decision1[j]) & m3[j]); } for (j = 0; j < 16; j += 2) { - simd_epi16 = path0[(i*16) + j]; - simd_epi16 |= path0[(i*16) + (j+1)] << 8; - simd_epi16 <<= 1; - shift0[j] = simd_epi16; - shift0[j+1] = simd_epi16 >> 8; - - simd_epi16 = path0[((i+2)*16) + j]; - simd_epi16 |= path0[((i+2)*16) + (j+1)] << 8; - simd_epi16 <<= 1; - shift1[j] = simd_epi16; - shift1[j+1] = simd_epi16 >> 8; + simd_epi16 = path0[(i * 16) + j]; + simd_epi16 |= path0[(i * 16) + (j + 1)] << 8; + simd_epi16 <<= 1; + shift0[j] = simd_epi16; + shift0[j + 1] = simd_epi16 >> 8; + + simd_epi16 = path0[((i + 2) * 16) + j]; + simd_epi16 |= path0[((i + 2) * 16) + (j + 1)] << 8; + simd_epi16 <<= 1; + shift1[j] = simd_epi16; + shift1[j + 1] = simd_epi16 >> 8; } for (j = 0; j < 16; j++) { - shift1[j] = shift1[j] + 1; + shift1[j] = shift1[j] + 1; } for (j = 0, k = 0; j < 16; j += 2, k++) { - metric1[(2*i*16) + j] = survivor0[k]; - metric1[(2*i*16) + (j+1)] = survivor1[k]; + metric1[(2 * i * 16) + j] = survivor0[k]; + metric1[(2 * i * 16) + (j + 1)] = survivor1[k]; } for (j = 0; j < 16; j++) { - tmp0[j] = (decision0[j] & shift0[j]) | ((~decision0[j]) & shift1[j]); + tmp0[j] = (decision0[j] & shift0[j]) | ((~decision0[j]) & shift1[j]); } for (j = 0, k = 8; j < 16; j += 2, k++) { - metric1[((2*i+1)*16) + j] = survivor0[k]; - metric1[((2*i+1)*16) + (j+1)] = survivor1[k]; + metric1[((2 * i + 1) * 16) + j] = survivor0[k]; + metric1[((2 * i + 1) * 16) + (j + 1)] = survivor1[k]; } for (j = 0; j < 16; j++) { - tmp1[j] = (decision1[j] & shift0[j]) | ((~decision1[j]) & shift1[j]); + tmp1[j] = (decision1[j] & shift0[j]) | ((~decision1[j]) & shift1[j]); } for (j = 0, k = 0; j < 16; j += 2, k++) { - path1[(2*i*16) + j] = tmp0[k]; - path1[(2*i*16) + (j+1)] = tmp1[k]; + path1[(2 * i * 16) + j] = tmp0[k]; + path1[(2 * i * 16) + (j + 1)] = tmp1[k]; } for (j = 0, k = 8; j < 16; j += 2, k++) { - path1[((2*i+1)*16) + j] = tmp0[k]; - path1[((2*i+1)*16) + (j+1)] = tmp1[k]; + path1[((2 * i + 1) * 16) + j] = tmp0[k]; + path1[((2 * i + 1) * 16) + (j + 1)] = tmp1[k]; } - } } +} #endif #ifdef DTV_SSE2 - unsigned char - dvbt_viterbi_decoder_impl::dvbt_viterbi_get_output_sse2(__m128i *mm0, __m128i *pp0, int ntraceback, unsigned char *outbuf) - { +unsigned char dvbt_viterbi_decoder_impl::dvbt_viterbi_get_output_sse2( + __m128i* mm0, __m128i* pp0, int ntraceback, unsigned char* outbuf) +{ #else - unsigned char - dvbt_viterbi_decoder_impl::dvbt_viterbi_get_output_generic(unsigned char *mm0, unsigned char *pp0, int ntraceback, unsigned char *outbuf) - { +unsigned char dvbt_viterbi_decoder_impl::dvbt_viterbi_get_output_generic( + unsigned char* mm0, unsigned char* pp0, int ntraceback, unsigned char* outbuf) +{ #endif - // Find current best path - int i; - int bestmetric, minmetric; - int beststate = 0; - int pos = 0; + // Find current best path + int i; + int bestmetric, minmetric; + int beststate = 0; + int pos = 0; #ifndef DTV_SSE2 - int j; + int j; #endif - // Implement a circular buffer with the last ntraceback paths - store_pos = (store_pos + 1) % ntraceback; + // Implement a circular buffer with the last ntraceback paths + store_pos = (store_pos + 1) % ntraceback; #ifdef DTV_SSE2 - // TODO - find another way to extract the value - for (i = 0; i < 4; i++) { - _mm_store_si128((__m128i *) &mmresult[i*16], mm0[i]); - _mm_store_si128((__m128i *) &ppresult[store_pos][i*16], pp0[i]); - } + // TODO - find another way to extract the value + for (i = 0; i < 4; i++) { + _mm_store_si128((__m128i*)&mmresult[i * 16], mm0[i]); + _mm_store_si128((__m128i*)&ppresult[store_pos][i * 16], pp0[i]); + } #else - for (i = 0; i < 4; i++) { + for (i = 0; i < 4; i++) { for (j = 0; j < 16; j++) { - mmresult[(i*16) + j] = mm0[(i*16) + j]; - ppresult[store_pos][(i*16) + j] = pp0[(i*16) + j]; + mmresult[(i * 16) + j] = mm0[(i * 16) + j]; + ppresult[store_pos][(i * 16) + j] = pp0[(i * 16) + j]; } - } + } #endif - // Find out the best final state - bestmetric = mmresult[beststate]; - minmetric = mmresult[beststate]; + // Find out the best final state + bestmetric = mmresult[beststate]; + minmetric = mmresult[beststate]; - for (i = 1; i < 64; i++) { + for (i = 1; i < 64; i++) { if (mmresult[i] > bestmetric) { - bestmetric = mmresult[i]; - beststate = i; + bestmetric = mmresult[i]; + beststate = i; } if (mmresult[i] < minmetric) { - minmetric = mmresult[i]; + minmetric = mmresult[i]; } - } + } - // Trace back - for (i = 0, pos = store_pos; i < (ntraceback - 1); i++) { + // Trace back + for (i = 0, pos = store_pos; i < (ntraceback - 1); i++) { // Obtain the state from the output bits // by clocking in the output bits in reverse order. // The state has only 6 bits beststate = ppresult[pos][beststate] >> 2; pos = (pos - 1 + ntraceback) % ntraceback; - } + } - // Store output byte - *outbuf = ppresult[pos][beststate]; + // Store output byte + *outbuf = ppresult[pos][beststate]; #ifdef DTV_SSE2 - // Zero out the path variable - // and prevent metric overflow - for (i = 0; i < 4; i++) { + // Zero out the path variable + // and prevent metric overflow + for (i = 0; i < 4; i++) { pp0[i] = _mm_setzero_si128(); mm0[i] = _mm_sub_epi8(mm0[i], _mm_set1_epi8(minmetric)); - } + } #else - for (i = 0; i < 4; i++) { + for (i = 0; i < 4; i++) { for (j = 0; j < 16; j++) { - pp0[(i*16) + j] = 0; - mm0[(i*16) + j] = mm0[(i*16) + j] - minmetric; + pp0[(i * 16) + j] = 0; + mm0[(i * 16) + j] = mm0[(i * 16) + j] - minmetric; } - } + } #endif - return bestmetric; - } + return bestmetric; +} - dvbt_viterbi_decoder::sptr - dvbt_viterbi_decoder::make(dvb_constellation_t constellation, \ - dvbt_hierarchy_t hierarchy, dvb_code_rate_t coderate, int bsize) - { - return gnuradio::get_initial_sptr - (new dvbt_viterbi_decoder_impl(constellation, hierarchy, coderate, bsize)); - } +dvbt_viterbi_decoder::sptr dvbt_viterbi_decoder::make(dvb_constellation_t constellation, + dvbt_hierarchy_t hierarchy, + dvb_code_rate_t coderate, + int bsize) +{ + return gnuradio::get_initial_sptr( + new dvbt_viterbi_decoder_impl(constellation, hierarchy, coderate, bsize)); +} - /* - * The private constructor - */ - dvbt_viterbi_decoder_impl::dvbt_viterbi_decoder_impl(dvb_constellation_t constellation, \ - dvbt_hierarchy_t hierarchy, dvb_code_rate_t coderate, int bsize) - : block("dvbt_viterbi_decoder", - io_signature::make(1, 1, sizeof (unsigned char)), - io_signature::make(1, 1, sizeof (unsigned char))), +/* + * The private constructor + */ +dvbt_viterbi_decoder_impl::dvbt_viterbi_decoder_impl(dvb_constellation_t constellation, + dvbt_hierarchy_t hierarchy, + dvb_code_rate_t coderate, + int bsize) + : block("dvbt_viterbi_decoder", + io_signature::make(1, 1, sizeof(unsigned char)), + io_signature::make(1, 1, sizeof(unsigned char))), config(constellation, hierarchy, coderate, coderate), d_bsize(bsize), d_init(0), store_pos(0) - { - //Determine k - input of encoder - d_k = config.d_cr_k; - //Determine n - output of encoder - d_n = config.d_cr_n; - //Determine m - constellation symbol size - d_m = config.d_m; - // Determine puncturing vector and traceback - if (config.d_code_rate_HP == C1_2) { +{ + // Determine k - input of encoder + d_k = config.d_cr_k; + // Determine n - output of encoder + d_n = config.d_cr_n; + // Determine m - constellation symbol size + d_m = config.d_m; + // Determine puncturing vector and traceback + if (config.d_code_rate_HP == C1_2) { d_puncture = d_puncture_1_2; d_ntraceback = 5; - } - else if (config.d_code_rate_HP == C2_3) { + } else if (config.d_code_rate_HP == C2_3) { d_puncture = d_puncture_2_3; d_ntraceback = 9; - } - else if (config.d_code_rate_HP == C3_4) { + } else if (config.d_code_rate_HP == C3_4) { d_puncture = d_puncture_3_4; d_ntraceback = 10; - } - else if (config.d_code_rate_HP == C5_6) { + } else if (config.d_code_rate_HP == C5_6) { d_puncture = d_puncture_5_6; d_ntraceback = 15; - } - else if (config.d_code_rate_HP == C7_8) { + } else if (config.d_code_rate_HP == C7_8) { d_puncture = d_puncture_7_8; d_ntraceback = 24; - } - else { + } else { d_puncture = d_puncture_1_2; d_ntraceback = 5; - } - - /* - * We input n bytes, each carrying m bits => nm bits - * The result after decoding is km bits, therefore km/8 bytes. - * - * out/in rate is therefore km/8n in bytes - */ - - assert ((d_bsize * d_n) % d_m == 0); - set_output_multiple (d_bsize * d_k / 8); - - /* - * Calculate process variables: - * Number of symbols (d_m bits) in all blocks - * It is also the number of input bytes since - * one byte always contains just one symbol. - */ - d_nsymbols = d_bsize * d_n / d_m; - // Number of bits after depuncturing a block (before decoding) - d_nbits = 2 * d_k * d_bsize; - // Number of output bytes after decoding - d_nout = d_nbits / 2 / 8; - - // Allocate the buffer for the bits - d_inbits = new (std::nothrow) unsigned char [d_nbits]; - if (d_inbits == NULL) { + } + + /* + * We input n bytes, each carrying m bits => nm bits + * The result after decoding is km bits, therefore km/8 bytes. + * + * out/in rate is therefore km/8n in bytes + */ + + assert((d_bsize * d_n) % d_m == 0); + set_output_multiple(d_bsize * d_k / 8); + + /* + * Calculate process variables: + * Number of symbols (d_m bits) in all blocks + * It is also the number of input bytes since + * one byte always contains just one symbol. + */ + d_nsymbols = d_bsize * d_n / d_m; + // Number of bits after depuncturing a block (before decoding) + d_nbits = 2 * d_k * d_bsize; + // Number of output bytes after decoding + d_nout = d_nbits / 2 / 8; + + // Allocate the buffer for the bits + d_inbits = new (std::nothrow) unsigned char[d_nbits]; + if (d_inbits == NULL) { GR_LOG_FATAL(d_logger, "Viterbi Decoder, cannot allocate memory for d_inbits."); throw std::bad_alloc(); - } + } - mettab[0][0] = 1; - mettab[0][1] = 0; - mettab[1][0] = 0; - mettab[1][1] = 1; + mettab[0][0] = 1; + mettab[0][1] = 0; + mettab[1][0] = 0; + mettab[1][1] = 1; #ifdef DTV_SSE2 - dvbt_viterbi_chunks_init_sse2(d_metric0, d_path0); + dvbt_viterbi_chunks_init_sse2(d_metric0, d_path0); #else - dvbt_viterbi_chunks_init_generic(d_metric0_generic, d_path0_generic); + dvbt_viterbi_chunks_init_generic(d_metric0_generic, d_path0_generic); #endif +} - } - - /* - * Our virtual destructor. - */ - dvbt_viterbi_decoder_impl::~dvbt_viterbi_decoder_impl() - { - delete [] d_inbits; - } +/* + * Our virtual destructor. + */ +dvbt_viterbi_decoder_impl::~dvbt_viterbi_decoder_impl() { delete[] d_inbits; } - void - dvbt_viterbi_decoder_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required) - { - int input_required = noutput_items * 8 * d_n / (d_k * d_m); +void dvbt_viterbi_decoder_impl::forecast(int noutput_items, + gr_vector_int& ninput_items_required) +{ + int input_required = noutput_items * 8 * d_n / (d_k * d_m); - unsigned ninputs = ninput_items_required.size(); - for (unsigned int i = 0; i < ninputs; i++) { + unsigned ninputs = ninput_items_required.size(); + for (unsigned int i = 0; i < ninputs; i++) { ninput_items_required[i] = input_required; - } } +} - int - dvbt_viterbi_decoder_impl::general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { - int nstreams = input_items.size(); - int nblocks = 8 * noutput_items / (d_bsize * d_k); - int out_count = 0; +int dvbt_viterbi_decoder_impl::general_work(int noutput_items, + gr_vector_int& ninput_items, + gr_vector_const_void_star& input_items, + gr_vector_void_star& output_items) +{ + int nstreams = input_items.size(); + int nblocks = 8 * noutput_items / (d_bsize * d_k); + int out_count = 0; - for (int m = 0; m < nstreams; m++) { - const unsigned char *in = (const unsigned char *) input_items[m]; - unsigned char *out = (unsigned char *) output_items[m]; + for (int m = 0; m < nstreams; m++) { + const unsigned char* in = (const unsigned char*)input_items[m]; + unsigned char* out = (unsigned char*)output_items[m]; /* * Look for a tag that signals superframe_start and consume all input items @@ -652,89 +637,102 @@ namespace gr { * This will actually reset the viterbi decoder. */ std::vector<tag_t> tags; - const uint64_t nread = this->nitems_read(0); //number of items read on port 0 - this->get_tags_in_range(tags, 0, nread, nread + (nblocks * d_nsymbols), pmt::string_to_symbol("superframe_start")); + const uint64_t nread = this->nitems_read(0); // number of items read on port 0 + this->get_tags_in_range(tags, + 0, + nread, + nread + (nblocks * d_nsymbols), + pmt::string_to_symbol("superframe_start")); if (tags.size()) { - d_init = 0; + d_init = 0; #ifdef DTV_SSE2 - dvbt_viterbi_chunks_init_sse2(d_metric0, d_path0); + dvbt_viterbi_chunks_init_sse2(d_metric0, d_path0); #else - dvbt_viterbi_chunks_init_generic(d_metric0_generic, d_path0_generic); + dvbt_viterbi_chunks_init_generic(d_metric0_generic, d_path0_generic); #endif - if (tags[0].offset - nread) { - consume_each(tags[0].offset - nread); - return (0); - } + if (tags[0].offset - nread) { + consume_each(tags[0].offset - nread); + return (0); + } } // This is actually the Viterbi decoder for (int n = 0; n < nblocks; n++) { - /* - * Depuncture and unpack a block. - * We receive the symbol (d_m bits/byte) in one byte (e.g. for QAM16 00001111). - * Create a buffer of bytes containing just one bit/byte. - * Also depuncture according to the puncture vector. - * TODO - reduce the number of branches while depuncturing. - */ - for (int count = 0, i = 0; i < d_nsymbols; i++) { - for (int j = (d_m - 1); j >= 0; j--) { - // Depuncture - while (d_puncture[count % (2 * d_k)] == 0) { - d_inbits[count++] = 2; - } - - // Insert received bits - d_inbits[count++] = (in[(n * d_nsymbols) + i] >> j) & 1; - - // Depuncture - while (d_puncture[count % (2 * d_k)] == 0) { - d_inbits[count++] = 2; - } + /* + * Depuncture and unpack a block. + * We receive the symbol (d_m bits/byte) in one byte (e.g. for QAM16 + * 00001111). Create a buffer of bytes containing just one bit/byte. Also + * depuncture according to the puncture vector. + * TODO - reduce the number of branches while depuncturing. + */ + for (int count = 0, i = 0; i < d_nsymbols; i++) { + for (int j = (d_m - 1); j >= 0; j--) { + // Depuncture + while (d_puncture[count % (2 * d_k)] == 0) { + d_inbits[count++] = 2; + } + + // Insert received bits + d_inbits[count++] = (in[(n * d_nsymbols) + i] >> j) & 1; + + // Depuncture + while (d_puncture[count % (2 * d_k)] == 0) { + d_inbits[count++] = 2; + } + } } - } - /* - * Decode a block. - */ - for (int in_count = 0; in_count < d_nbits; in_count++) { - if ((in_count % 4) == 0) { // 0 or 3 + /* + * Decode a block. + */ + for (int in_count = 0; in_count < d_nbits; in_count++) { + if ((in_count % 4) == 0) { // 0 or 3 #ifdef DTV_SSE2 - dvbt_viterbi_butterfly2_sse2(&d_inbits[in_count & 0xfffffffc], d_metric0, d_metric1, d_path0, d_path1); + dvbt_viterbi_butterfly2_sse2(&d_inbits[in_count & 0xfffffffc], + d_metric0, + d_metric1, + d_path0, + d_path1); #else - dvbt_viterbi_butterfly2_generic(&d_inbits[in_count & 0xfffffffc], d_metric0_generic, d_metric1_generic, d_path0_generic, d_path1_generic); + dvbt_viterbi_butterfly2_generic(&d_inbits[in_count & 0xfffffffc], + d_metric0_generic, + d_metric1_generic, + d_path0_generic, + d_path1_generic); #endif - if ((in_count > 0) && (in_count % 16) == 8) { // 8 or 11 - unsigned char c; + if ((in_count > 0) && (in_count % 16) == 8) { // 8 or 11 + unsigned char c; #ifdef DTV_SSE2 - dvbt_viterbi_get_output_sse2(d_metric0, d_path0, d_ntraceback, &c); + dvbt_viterbi_get_output_sse2( + d_metric0, d_path0, d_ntraceback, &c); #else - dvbt_viterbi_get_output_generic(d_metric0_generic, d_path0_generic, d_ntraceback, &c); + dvbt_viterbi_get_output_generic( + d_metric0_generic, d_path0_generic, d_ntraceback, &c); #endif - if (d_init == 0) { - if (out_count >= d_ntraceback) { - out[out_count - d_ntraceback] = c; - } + if (d_init == 0) { + if (out_count >= d_ntraceback) { + out[out_count - d_ntraceback] = c; + } + } else { + out[out_count] = c; + } + out_count++; + } } - else { - out[out_count] = c; - } - out_count++; - } } - } } - } + } - int to_out = noutput_items; + int to_out = noutput_items; - if (d_init == 0) { + if (d_init == 0) { /* * Send superframe_start to signal this situation * downstream @@ -747,16 +745,15 @@ namespace gr { // Take in consideration the traceback length to_out = to_out - d_ntraceback; d_init = 1; - } + } - // Tell runtime system how many input items we consumed on - // each input stream. - consume_each (nblocks * d_nsymbols); + // Tell runtime system how many input items we consumed on + // each input stream. + consume_each(nblocks * d_nsymbols); - // Tell runtime system how many output items we produced. - return (to_out); - } + // Tell runtime system how many output items we produced. + return (to_out); +} - } /* namespace dtv */ +} /* namespace dtv */ } /* namespace gr */ - |