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

📄 chan_enc.c

📁 语音压缩编码和解码的标准,其中包含部分源代码
💻 C
📖 第 1 页 / 共 5 页
字号:

   /* Determine the number of available channel bits per frame (multiply by 0.03) */
   /* ----------------------------------------------------------------------------*/
   L_tmp = L_mult(ChannelBitrate,31458);
   cbits = (Word16) L_shr(L_tmp,21);

   if ((SpeechCodecMode & 0x3) == 0){
      for (i=0;i<5;i++) bit_class[i] = BitClass63[i];
      for (i=0;i<5;i++) weight[i] = Weight63[i];
      inv_b0p4 = inv_b0p4_63;
      for (i=0;i<4;i++) inv_bit_class[i] = InvBitClass63[i];
      NInfoBits = NInfoBits6_3;
   }
   if ((SpeechCodecMode & 0x3) == 1){
      for (i=0;i<5;i++) bit_class[i] = BitClass53[i];
      for (i=0;i<5;i++) weight[i] = Weight53[i];
      inv_b0p4 = inv_b0p4_53;
      for (i=0;i<4;i++) inv_bit_class[i] = InvBitClass53[i];
      NInfoBits = NInfoBits5_3;
   }
   if ((SpeechCodecMode & 0x3) == 2){
      for (i=0;i<5;i++) bit_class[i] = BitClassSID[i];
      for (i=0;i<5;i++) weight[i] = WeightSID[i];
      inv_b0p4 = inv_b0p4_SID;
      NInfoBits = NInfoBitsSID;
   }

   /* Determine the number of available redundancy bits per frame */
   /* ----------------------------------------------------------- */
   rbits = cbits - (NInfoBits+CrcLen+BCHLen);

   /* Check whether enough bits are available */
   /* --------------------------------------- */
   if (rbits < 0) {
      printf ("\n\nNot enough channel bitrate specified\n");
      printf ("The minimum channel bitrate is %.2f kbit/s \n",
            ((float)(BCHLen+CrcLen+NInfoBits)*1000./30.));
      exit(1);
   }

   if (rbits == 0) {
      /* No convolutional code specified */
      /* ------------------------------- */
      if (SpeechCodecMode < 2) {
         bit_class[3] = bit_class[3]-4;
      }else{
         bit_class[0] = bit_class[0]-4;
      }
      for (i=0;i<4;i++) {
         bit_class[4] = bit_class[4] + bit_class[i];
         bit_class[i] = 0;
      }
      for (i=0;i<5;i++){
         r[i]=12;
         for (j=0;j<3;j++) punctur[i][j] = PuncturTable[r[i]-12][j];
      }
   }else{

      /* Check whether too much bits have been specified */
      /* ----------------------------------------------- */
      limit = 2*(bit_class[0]+bit_class[1]+bit_class[2]+
                 bit_class[3]+bit_class[4]) + 4;
      if (rbits >= limit) {
         /* The requested channel bitrate is too high. The channel bitrate */
         /* is therefore limited to the maximum allowed value.             */
         /* -------------------------------------------------------------- */
         for (i=0;i<4;i++) r[i]=36;
         r[4]=12;
         for (i=0;i<5;i++){
            for (j=0;j<3;j++) punctur[i][j] = PuncturTable[r[i]-12][j];
         }
         bit_class[3] = bit_class[3] + bit_class[4];
         bit_class[4] = 0;
      }else{
         /* Initialise rates and puncturing tables */
         /* -------------------------------------- */
         for (i=0;i<5;i++)   r[i]=12;
         for (i=0;i<5;i++){
            for (j=0;j<3;j++) punctur[i][j] = PuncturTable[r[i]-12][j];
         }

         /* Determine rate for the most sensitive bit class */
         /* ----------------------------------------------- */
         rbits = rbits - 4; /* tail bits have to be transmitted */
         if (rbits < 0) rbits=0;
         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);

}

/*__________________________________________________________________________
 |                                                                          |
 | Reorder G.723.1 information bitstream considering subjective sensitivity |
 |               (sections 2.2 and 2.3)                                     |
 |__________________________________________________________________________|
*/
static void bit_allocation( char CInfoBitStream[], Word16 info_bit[] )
{

/* Definition of high rate bitordering table (see Table C3a) */
/* --------------------------------------------------------- */
static const Word16   BitOrder63[NBits6_3] = 
       {175, 180, 189, 190, 191, 192 , -1 , -1,
         98 , 73, 107, 154, 167, 168, 169, 170,
         30 , 17 , 16 , 31 , 48 , 55 , 49 , 71,
          6  , 4  , 0  , 2 , 11 , 26 , 10 , 14,

⌨️ 快捷键说明

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