⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chan_dec.c

📁 语音压缩编码和解码的标准,其中包含部分源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
         if ((rbits <= bit_class[0]+8) || (SpeechCodecMode == 2)) {
            /* Allocate all redundancy to class 0 */
            if (SpeechCodecMode < 2) {
               bit_class[3] = bit_class[3]-4;
            }else{
               bit_class[0] = bit_class[0]-4;
            }
	    r[0] = GetRate(rbits,(Word16)(-32768),bit_class[0]+4,inv_b0p4,0);
            if (r[0] == 12) {
               for (i=0;i<4;i++) {
                  bit_class[4] = bit_class[4] + bit_class[i];
                  bit_class[i] = 0;
               }
            }else{
               bit_class[0] = bit_class[0] + 4;
            }
            for (j=0;j<3;j++) punctur[0][j] = PuncturTable[r[0]-12][j];
         }else{
	    r[0] = GetRate(rbits,weight[0],bit_class[0],inv_bit_class[0],1);
            if (r[0] < 24) r[0] = 24;
            if (r[0] > 36) r[0] = 36;
            for (j=0;j<3;j++) punctur[0][j] = PuncturTable[r[0]-12][j];
            bit_class[3] = bit_class[3] - 4;
            bit_class[0] = bit_class[0] + 4;
            for (i=1;i<4;i++) {
               abits = bitrate_test (bit_class,punctur,i-1);
               if (abits < cbits) {
		  r[i] = GetRate(rbits,weight[i],bit_class[i],inv_bit_class[i],1);
                  if (r[i] <  18) r[i] =  18;
                  if (r[i] > 36) r[i] = 36;
                  if (r[i] > r[0]) r[i] = r[0];
                  for (j=0;j<3;j++) punctur[i][j] = PuncturTable[r[i]-12][j];
                  bit_class[i-1] = bit_class[i-1] - 4;
                  bit_class[i]   = bit_class[i]   + 4;
               }else {
                  break;
               }
            }
         }
      }
   }

   /* Determine which class is the last protected one */
   /* ----------------------------------------------- */
   last=0;
   for (i=1;i<5;i++){
      if (r[i] > 12) last=i;
   }

   /* Determine channel bitrate with these settings */
   /* --------------------------------------------- */
   abits = bitrate_test (bit_class,punctur,last);
   if (abits > cbits) {
      /* too many bits are used: shift bits from high to low protection */
      /* -------------------------------------------------------------- */
      if (SpeechCodecMode < 2){
         bitrate_adapt_high (bit_class,punctur,cbits,r,last);
      }else{
         r[0]--;
         for (j=0;j<3;j++) punctur[0][j] = PuncturTable[r[0]-12][j];
         if (r[0] == 12) bit_class[0]=bit_class[0]-4;
      }
   }
   if ((abits < cbits) && (r[0]>12) && (rbits < limit) && (SpeechCodecMode < 2)) {
      /* too few bits are used:: shift bits from low to high protection */
      /* -------------------------------------------------------------- */
      bitrate_adapt_low (bit_class,punctur,cbits,r,last);
   }
   return;
}

/*_________________________________________________________________________________
 |                                                                                 |
 | Determine rate for one bit class                                                |
 |               (section 2.5.1)                                                   |
 |_________________________________________________________________________________|
*/
static Word16 GetRate (Word16 rbits, Word16 weight, Word16 bit_class, Word16 inv_bit_class, Word16 rnd)
{
         
   Word16 tmp;
   Word32 L_tmp1, L_tmp2;

   /* Calculate 12*(rbits*weight+bit_class) */
   /* ------------------------------------- */
   L_tmp1 = - L_mult(rbits,weight);
   L_tmp2 = - L_mult(bit_class,(Word16)(-32768));
   L_tmp1 = L_add(L_tmp1,L_tmp2);

   /* Multiply by 12 */
   /* -------------- */
   L_tmp2 = L_shl(L_tmp1,3);
   L_tmp1 = L_shl(L_tmp1,2);
   L_tmp1 = L_add(L_tmp1,L_tmp2);
   tmp   = (Word16) L_shr(L_tmp1,12);

   /* Multiply by inv_bit_class and round */
   /* ----------------------------------- */
   L_tmp1 = L_mult(tmp,inv_bit_class);
   tmp    = (Word16) L_shr(L_tmp1,24);
   tmp    = add(tmp,rnd);
   tmp    = shr (tmp,1);
   return(tmp);
}

/*_________________________________________________________________________________
 |                                                                                 |
 | Adaptation of bit allocation to meet channel bitrate requirement                |
 |               (section 2.5.1)                                                   |
 |_________________________________________________________________________________|
*/
static void bitrate_adapt_low (Word16 bit_class[],Word16 punctur[5][3],
                               Word16 cbits, Word16 r[], Word16 last)
{
   Word16 abits,src,dest;

   src  = last+1;
   dest = last;
   for (;;) {
      if (bit_class[src] == 0) {
         if (src == last) return;
         src = last;
         dest = last-1;
         if (r[src] == r[dest]) return;
      }
      /* shift one bit from bit_class[src] to bit_class[dest] */
      /* ---------------------------------------------------- */
      bit_class[src]--;
      bit_class[dest]++;
      abits = bitrate_test (bit_class,punctur,last);
      if (abits >= cbits) break;      
   }

   if (abits > cbits) bitrate_adapt_high (bit_class,punctur,cbits,r,last);

   return;
}

/*_________________________________________________________________________________
 |                                                                                 |
 | Adaptation of bit allocation to meet channel bitrate requirement                |
 |               (section 2.5.1)                                                   |
 |_________________________________________________________________________________|
*/
static void bitrate_adapt_high (Word16 bit_class[],Word16 punctur[5][3],
                                Word16 cbits, Word16 r[], Word16 last)
{
   Word16 abits,i;

   if (r[3] > 21) {
      /* The number of bits in the unprotected class may not be increased */
      /* ---------------------------------------------------------------- */
      for (;;) {
         for (i=2;i>0;i--){
            /* shift one bit of bit_class[i] to bit_class[i+1] */
            /* ----------------------------------------------- */
            if (bit_class[i] == 0) return;
            bit_class[i]--;
            bit_class[i+1]++;
            abits = bitrate_test (bit_class,punctur,last);
            if (abits <= cbits) break;      
         }
         if (abits <= cbits) break;      
      }
   }else{
      for (;;) {
         /* shift one bit of bit_class[last] to bit_class[last+1] */
         /* ----------------------------------------------------- */
         if (bit_class[last] == 0) {
            printf ("\n\n Error in bitrate_adapt_high\n\n");
            exit(1);
         }
         bit_class[last]--;
         bit_class[last+1]++;
         abits = bitrate_test (bit_class,punctur,last);
         if (abits <= cbits) break;
      }
   }
   return;
}


/*_______________________________________________________________________
 |                                                                      |
 | Determination of required channel bitrate                            |
 |               (section 2.5.1)                                        |
 |______________________________________________________________________|
*/
static bitrate_test( Word16 nbit_class[], Word16 punctur[5][3], Word16 last )
{
    Word16 i, j, k, ptr0, cnt;
    static const Word16 mask[16] = { 0X0001, 0X0002, 0X0004, 0X0008,
                                   0X0010, 0X0020, 0X0040, 0X0080,
                                   0X0100, 0X0200, 0X0400, 0X0800,
                                   0X1000, 0X2000, 0X4000, -32768 };

    /* Encode the protected classes: */
    /* ----------------------------- */
    ptr0 = 0;
    cnt  = 0;
    for( k = 0; k <= last; ++k ) {
        for( i = 0; i < nbit_class[k]; ++i ) {
            for( j = 0; j < 3; ++j ) {
                if(( punctur[k][j] & mask[cnt] ) != 0 ) ptr0++;
            }
            cnt = ++cnt % 12;
        }
    }

    /* Determine channel bitrate */
    /* ------------------------- */
    for (i=last+1;i<5;i++) ptr0 = ptr0 + nbit_class[i];

    ptr0 += BCHLen;

    return(ptr0);

}


static void hamming_distance( Word16 chan_bit_np[], Word16 metric[], Word16 temp[] )
{
#define SCALE 2
    static const Word16 code_word[16][3] = { 
        {  16384/SCALE,  16384/SCALE,  16384/SCALE }, 
        { -16384/SCALE, -16384/SCALE, -16384/SCALE },
        { -16384/SCALE,  16384/SCALE, -16384/SCALE }, 
        {  16384/SCALE, -16384/SCALE,  16384/SCALE }, 
        {  16384/SCALE, -16384/SCALE, -16384/SCALE }, 
        { -16384/SCALE,  16384/SCALE,  16384/SCALE },
        { -16384/SCALE, -16384/SCALE,  16384/SCALE }, 
        {  16384/SCALE,  16384/SCALE, -16384/SCALE }, 
        {  16384/SCALE, -16384/SCALE,  16384/SCALE },
        { -16384/SCALE,  16384/SCALE, -16384/SCALE },
        { -16384/SCALE, -16384/SCALE, -16384/SCALE }, 
        {  16384/SCALE,  16384/SCALE,  16384/SCALE }, 
        {  16384/SCALE,  16384/SCALE, -16384/SCALE }, 
        { -16384/SCALE, -16384/SCALE,  16384/SCALE },
        { -16384/SCALE,  16384/SCALE,  16384/SCALE },
        {  16384/SCALE, -16384/SCALE, -16384/SCALE }};
    Word16 ham_dist, i, j;
    Word32 acc;

    for( i = 0, j = 0; i < 8; ++i ) {
        acc = L_mac(   0, code_word[j][0], chan_bit_np[0] );
        acc = L_mac( acc, code_word[j][1], chan_bit_np[1] );
        acc = L_mac( acc, code_word[j][2], chan_bit_np[2] );
        ham_dist = extract_h( acc );
        temp[j] = add( metric[i], ham_dist );
        temp[j+17] = add( metric[i+8], ham_dist );
        ++j;
        acc = L_mac(   0, code_word[j][0], chan_bit_np[0] );
        acc = L_mac( acc, code_word[j][1], chan_bit_np[1] );
        acc = L_mac( acc, code_word[j][2], chan_bit_np[2] );
        ham_dist = extract_h( acc );
        temp[j] = add( metric[i], ham_dist );
        temp[j+15] = add( metric[i+8], ham_dist );
        ++j;
    }
}

static void metric_update( Word16 chan_bit_np[], Word16 metric[], Word16 *surv_mem )
{
    Word16 temp[32], j;

    hamming_distance( chan_bit_np, metric, temp );
    for( j = 0; j < 16; ++j ) {
        if( sub( temp[j], temp[j+16] ) >= 0 ) {
            metric[j] = temp[j];
	    if (metric[j] > 32760) printf("metric problem 1 %d\n",metric[j]);
	    if (metric[j] < -32760) printf("metric problem 1 %d\n",metric[j]);
            clrbit( *surv_mem, j );
        } else {
            metric[j] = temp[j+16];
            setbit( *surv_mem, j );
	    if (metric[j] > 32760) printf("metric problem 2 %d\n",metric[j]);
	    if (metric[j] < -32760) printf("metric problem 2 %d\n",metric[j]);
        }
    }
}

static Word16 metric_difference( Word16 chan_bit_np[], Word16 metric[], Word16 adr )
{
    Word16 delta, temp[32], j;

    hamming_distance( chan_bit_np, metric, temp );
    for( j = 0; j < 16; ++j )
        metric[j] = ( sub( temp[j], temp[j+16] ) >= 0 ) ? temp[j] : temp[j+16];

    /* Compute difference metric: */
    /* -------------------------- */
    delta = abs_s( sub( temp[adr], temp[adr+16] ));

    /* Scale difference metric: */
    /* ------------------------ */
    return( shr( delta, 1 ));
}


static void metric_update_delta( Word16 chan_bit_np[], Word16 metric[],
    Word16 *surv_mem, Word16 delta_soft[] )
{
    Word16 temp[32], j;

    hamming_distance( chan_bit_np, metric, temp );
    for( j = 0; j < 16; ++j ) {

        /* Compute difference metric: */
        /* -------------------------- */
        delta_soft[j] = sub( temp[j], temp[j+16] );

        if( delta_soft[j] >= 0 ) {
            metric[j] = temp[j];
            clrbit( *surv_mem, j );
        } else {
            metric[j] = temp[j+16];
            setbit( *surv_mem, j );
        }
    }
}




static void viterbi( Word16 nbit_class[], Word16 punctur[5][3], 
                     Word16 chan_bit_r[], Word16 info_bit_r[], 
                     Word16 info_bit_r_soft[])
{
    Word16 chan_bit_np[1500][3], surv[200], surv_mem[200];
    Word16 ninfo_conv, metric[16];
    Word16 ptr0, ptr1, adr, cnt12, i, j, k, last, n0;
    static const Word16 mask[16] = { 0X0001, 0X0002, 0X0004, 0X0008,
                                   0X0010, 0X0020, 0X0040, 0X0080,
                                   0X0100, 0X0200, 0X0400, 0X0800,
                                   0X1000, 0X2000, 0X4000, -32768 };


    if (punctur[0][0] != 0) {

       /* Check which class is the last protected one */
       last=0;
       for (i=1;i<5;i++){
          if (punctur[i][0] != 0) last=i;
       }
       for (ninfo_conv=0,i=0;i<=last;i++)  ninfo_conv += nbit_class[i];
       for (n0=0,i=last+1;i<5;i++)  n0 += nbit_class[i];
   
   
       /* Initialise metrics: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -