static void ifft_pass (complex_t * buf, const sample_t * weight, int n) { complex_t * buf1; complex_t * buf2; complex_t * buf3; sample_t tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; int i; buf++; buf1 = buf + n; buf2 = buf + 2 * n; buf3 = buf + 3 * n; BUTTERFLY_ZERO (buf[-1], buf1[-1], buf2[-1], buf3[-1]); i = n - 1; do { BUTTERFLY (buf[0], buf1[0], buf2[0], buf3[0], weight[0], weight[2*i-n]); buf++; buf1++; buf2++; buf3++; weight++; } while (--i); }
void CDataEncode::ViterbiK7(int *R, int LengthR, int *Decision)//卷积码译码 { int G[VITERBI_STATUS_NUM]={0}; int S[VITERBI_STATUS_NUM]={0}; int G_L[VITERBI_STATUS_NUM]={0}; int ii=0; int jj=0; int kk=0; for (jj=0;jj<DEC_OUT_MAX_LEN;jj++) { Z[jj]=0; State_log[jj]=0; } for (jj=0;jj<VITERBI_STATUS_NUM*TRACKLEN;jj++) { *((int*)Track_log+jj)=0; *((int*)Track_log_D+jj)=0; } for (jj=0;jj<VITERBI_STATUS_NUM;jj++) { G[jj]=0; S[jj]=0; } for (jj=0;jj<VITERBI_STATUS_NUM;jj++) { G_L[jj]=10000; } G_L[0]=0; for (ii=0;ii<LengthR/4;ii++) { Z[ii]=(R[4*ii]!=0)*8 +(R[4*ii+1]!=0)*4 +(R[4*ii+2]!=0)*2 +(R[4*ii+3]!=0)*1; } for (ii=0;ii<LengthR/4;ii++) { for(jj=0;jj<VITERBI_STATUS_NUM;jj++) { BUTTERFLY(&G_L[0],Z[ii],&s_all[jj][0],&o_all[jj][0],&S[jj],&G[jj]); } for(jj=0;jj<VITERBI_STATUS_NUM*TRACKLEN;jj++) { *((int*)Track_log_D+jj)=*((int*)Track_log+jj); } for(jj=0;jj<VITERBI_STATUS_NUM;jj++) { for(kk=0;kk<TRACKLEN-1;kk++) { Track_log[jj][kk]=Track_log_D[S[jj]][kk+1]; } Track_log[jj][TRACKLEN-1]=S[jj]; } for(jj=0;jj<VITERBI_STATUS_NUM;jj++) { G_L[jj]=G[jj]; } if(ii>TRACKLEN) { State_log[ii-TRACKLEN-1]=Track_log_D[0][0]; } } kk=min64index(G); for(jj=0;jj<TRACKLEN;jj++) { State_log[jj+LengthR/4-TRACKLEN-1]=Track_log[kk][jj]; } State_log[LengthR/4-1]=kk; for(jj=0;jj<LengthR/4;jj++) { Decision[jj]=InputTable[State_log[jj]]; } }
/* Need some options here: user settable metric table, verbosity options, etc */ main(int argc,char *argv[]) { unsigned int bitcnt = 0; int beststate,i; long cmetric[64],nmetric[64]; unsigned long paths[2*PATHMEM]; register unsigned long dec; int mets[8]; unsigned int pi = 0,first=1; unsigned char symbols[3]; int mettab[2][256]; /* Initialize metric table (make this an option) * This table assumes a symbol of 0 is the * strongest possible '0', and a symbol * of 255 is the strongest possible '1'. A symbol * of 128 is an erasure */ for(i=0;i<256;i++){ mettab[0][i] = 128 - i; mettab[1][255-i] = 127 - i; } cmetric[0] = 0; for(i=1;i<64;i++) cmetric[i] = -99999; /* Main loop -- read input symbols and run ACS butterflies, * periodically tracing back to produce decoded output data. * The loop is unrolled to process two bits per iteration. */ for(;;){ /* Renormalize metrics to prevent overflow */ if(cmetric[0] > (LONG_MAX - RENORMALIZE)){ for(i=0;i<64;i++) cmetric[i] -= LONG_MAX; } else if(cmetric[0] < LONG_MIN+RENORMALIZE){ for(i=0;i<64;i++) cmetric[i] += LONG_MAX; } /* Read input symbol pair and compute branch metrics */ symbols[0] = getchar(); symbols[1] = getchar(); symbols[2] = getchar(); if(feof(stdin)) break; mets[0] = mettab[0][symbols[0]] + mettab[0][symbols[1]] + mettab[0][symbols[2]]; mets[1] = mettab[0][symbols[0]] + mettab[0][symbols[1]] + mettab[1][symbols[2]]; mets[3] = mettab[0][symbols[0]] + mettab[1][symbols[1]] + mettab[1][symbols[2]]; mets[2] = mettab[0][symbols[0]] + mettab[1][symbols[1]] + mettab[0][symbols[2]]; mets[6] = mettab[1][symbols[0]] + mettab[1][symbols[1]] + mettab[0][symbols[2]]; mets[7] = mettab[1][symbols[0]] + mettab[1][symbols[1]] + mettab[1][symbols[2]]; mets[5] = mettab[1][symbols[0]] + mettab[0][symbols[1]] + mettab[1][symbols[2]]; mets[4] = mettab[1][symbols[0]] + mettab[0][symbols[1]] + mettab[0][symbols[2]]; /* On even numbered bits, the butterflies read from cmetrics[] * and write to nmetrics[]. On odd numbered bits, the reverse * is done */ /* These macro calls were generated by genbut.c * and rearranged by hand for speed */ dec = 0; BUTTERFLY(0,0); BUTTERFLY(14,0); BUTTERFLY(2,7); BUTTERFLY(12,7); BUTTERFLY(1,6); BUTTERFLY(15,6); BUTTERFLY(3,1); BUTTERFLY(13,1); BUTTERFLY(4,5); BUTTERFLY(10,5); BUTTERFLY(6,2); BUTTERFLY(8,2); BUTTERFLY(5,3); BUTTERFLY(11,3); BUTTERFLY(7,4); BUTTERFLY(9,4); paths[2*pi] = dec; dec = 0; BUTTERFLY(19,0); BUTTERFLY(29,0); BUTTERFLY(17,7); BUTTERFLY(31,7); BUTTERFLY(18,6); BUTTERFLY(28,6); BUTTERFLY(16,1); BUTTERFLY(30,1); BUTTERFLY(23,5); BUTTERFLY(25,5); BUTTERFLY(21,2); BUTTERFLY(27,2); BUTTERFLY(22,3); BUTTERFLY(24,3); BUTTERFLY(20,4); BUTTERFLY(26,4); paths[2*pi+1] = dec; pi++; /* Read input symbol pair and compute branch metrics */ symbols[0] = getchar(); symbols[1] = getchar(); symbols[2] = getchar(); if(feof(stdin)) break; mets[0] = mettab[0][symbols[0]] + mettab[0][symbols[1]] + mettab[0][symbols[2]]; mets[1] = mettab[0][symbols[0]] + mettab[0][symbols[1]] + mettab[1][symbols[2]]; mets[3] = mettab[0][symbols[0]] + mettab[1][symbols[1]] + mettab[1][symbols[2]]; mets[2] = mettab[0][symbols[0]] + mettab[1][symbols[1]] + mettab[0][symbols[2]]; mets[6] = mettab[1][symbols[0]] + mettab[1][symbols[1]] + mettab[0][symbols[2]]; mets[7] = mettab[1][symbols[0]] + mettab[1][symbols[1]] + mettab[1][symbols[2]]; mets[5] = mettab[1][symbols[0]] + mettab[0][symbols[1]] + mettab[1][symbols[2]]; mets[4] = mettab[1][symbols[0]] + mettab[0][symbols[1]] + mettab[0][symbols[2]]; dec = 0; BUTTERFLY2(0,0); BUTTERFLY2(14,0); BUTTERFLY2(2,7); BUTTERFLY2(12,7); BUTTERFLY2(1,6); BUTTERFLY2(15,6); BUTTERFLY2(3,1); BUTTERFLY2(13,1); BUTTERFLY2(4,5); BUTTERFLY2(10,5); BUTTERFLY2(6,2); BUTTERFLY2(8,2); BUTTERFLY2(5,3); BUTTERFLY2(11,3); BUTTERFLY2(7,4); BUTTERFLY2(9,4); paths[2*pi] = dec; dec = 0; BUTTERFLY2(19,0); BUTTERFLY2(29,0); BUTTERFLY2(17,7); BUTTERFLY2(31,7); BUTTERFLY2(18,6); BUTTERFLY2(28,6); BUTTERFLY2(16,1); BUTTERFLY2(30,1); BUTTERFLY2(23,5); BUTTERFLY2(25,5); BUTTERFLY2(21,2); BUTTERFLY2(27,2); BUTTERFLY2(22,3); BUTTERFLY2(24,3); BUTTERFLY2(20,4); BUTTERFLY2(26,4); paths[2*pi+1] = dec; pi = (pi + 1) % PATHMEM; if((pi % TRACECHUNK) == 0){ if(!first) traceback(paths,pi); first = 0; } } flush(paths,pi); }
void fft64(void *a) { v16* const A = a; register v16 X0, X1, X2, X3, X4, X5, X6, X7; #define X(i) X##i X0 = A[0]; X1 = A[1]; X2 = A[2]; X3 = A[3]; X4 = A[4]; X5 = A[5]; X6 = A[6]; X7 = A[7]; #define DO_REDUCE(i) \ X(i) = REDUCE(X(i)) /* * Begin with 8 parallels DIF FFT_8 * * FFT_8 using w=4 as 8th root of unity * Unrolled decimation in frequency (DIF) radix-2 NTT. * Output data is in revbin_permuted order. */ #define wn0 0 #define wn1 2 #define wn2 4 #define wn3 6 #define BUTTERFLY(i,j,n) \ do { \ v16 u= X(i); \ v16 v= X(j); \ X(i) = v16_add(u, v); \ if (n) \ X(j) = v16_shift_l(v16_sub(u, v), XCAT(wn,n)); \ else \ X(j) = v16_sub(u, v); \ } while(0) BUTTERFLY(0, 4, 0); BUTTERFLY(1, 5, 1); BUTTERFLY(2, 6, 2); BUTTERFLY(3, 7, 3); DO_REDUCE(5); DO_REDUCE(6); DO_REDUCE(7); BUTTERFLY(0, 2, 0); BUTTERFLY(4, 6, 0); BUTTERFLY(1, 3, 2); BUTTERFLY(5, 7, 2); BUTTERFLY(0, 1, 0); BUTTERFLY(2, 3, 0); BUTTERFLY(4, 5, 0); BUTTERFLY(6, 7, 0); /* We don't need to reduce X(0) */ DO_REDUCE_FULL_S(1); DO_REDUCE_FULL_S(2); DO_REDUCE_FULL_S(3); DO_REDUCE_FULL_S(4); DO_REDUCE_FULL_S(5); DO_REDUCE_FULL_S(6); DO_REDUCE_FULL_S(7); #undef BUTTERFLY /* * Multiply by twiddle factors */ X(1) = v16_mul(X(1), FFT64_Twiddle[0].v16); X(2) = v16_mul(X(2), FFT64_Twiddle[1].v16); X(3) = v16_mul(X(3), FFT64_Twiddle[2].v16); X(4) = v16_mul(X(4), FFT64_Twiddle[3].v16); X(5) = v16_mul(X(5), FFT64_Twiddle[4].v16); X(6) = v16_mul(X(6), FFT64_Twiddle[5].v16); X(7) = v16_mul(X(7), FFT64_Twiddle[6].v16); /* * Transpose the FFT state with a revbin order permutation * on the rows and the column. * This will make the full FFT_64 in order. */ #ifdef v16_interleave_inplace #define INTERLEAVE(i,j) v16_interleave_inplace(X(i), X(j)) #else #define INTERLEAVE(i,j) \ do { \ v16 t1= X(i); \ v16 t2= X(j); \ X(i) = v16_interleavel(t1, t2); \ X(j) = v16_interleaveh(t1, t2); \ } while(0) #endif INTERLEAVE(0, 1); INTERLEAVE(2, 3); INTERLEAVE(4, 5); INTERLEAVE(6, 7); INTERLEAVE(0, 2); INTERLEAVE(1, 3); INTERLEAVE(4, 6); INTERLEAVE(5, 7); INTERLEAVE(0, 4); INTERLEAVE(1, 5); INTERLEAVE(2, 6); INTERLEAVE(3, 7); #undef INTERLEAVE /* * Finish with 8 parallels DIT FFT_8 * * FFT_8 using w=4 as 8th root of unity * Unrolled decimation in time (DIT) radix-2 NTT. * Intput data is in revbin_permuted order. */ #define BUTTERFLY(i,j,n) \ do { \ v16 u= X(i); \ v16 v= X(j); \ if (n) \ v = v16_shift_l(v, XCAT(wn,n)); \ X(i) = v16_add(u, v); \ X(j) = v16_sub(u, v); \ } while(0) DO_REDUCE(0); DO_REDUCE(1); DO_REDUCE(2); DO_REDUCE(3); DO_REDUCE(4); DO_REDUCE(5); DO_REDUCE(6); DO_REDUCE(7); BUTTERFLY(0, 1, 0); BUTTERFLY(2, 3, 0); BUTTERFLY(4, 5, 0); BUTTERFLY(6, 7, 0); BUTTERFLY(0, 2, 0); BUTTERFLY(4, 6, 0); BUTTERFLY(1, 3, 2); BUTTERFLY(5, 7, 2); DO_REDUCE(7); BUTTERFLY(0, 4, 0); BUTTERFLY(1, 5, 1); BUTTERFLY(2, 6, 2); BUTTERFLY(3, 7, 3); DO_REDUCE_FULL_S(0); DO_REDUCE_FULL_S(1); DO_REDUCE_FULL_S(2); DO_REDUCE_FULL_S(3); DO_REDUCE_FULL_S(4); DO_REDUCE_FULL_S(5); DO_REDUCE_FULL_S(6); DO_REDUCE_FULL_S(7); #undef BUTTERFLY A[0] = X0; A[1] = X1; A[2] = X2; A[3] = X3; A[4] = X4; A[5] = X5; A[6] = X6; A[7] = X7; #undef X }