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

📄 nb_celp.c

📁 一个开源的sip源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
      st->submodeID=0;   } else    {      /* If bits is NULL, consider the packet to be lost (what could we do anyway) */      if (!bits)      {         nb_decode_lost(st, out, stack);         return 0;      }      if (st->encode_submode)      {#ifdef EPIC_48K         if (!st->lbr_48k) {#endif      /* Search for next narrowband block (handle requests, skip wideband blocks) */      do {         if (speex_bits_remaining(bits)<5)            return -1;         wideband = speex_bits_unpack_unsigned(bits, 1);         if (wideband) /* Skip wideband block (for compatibility) */         {            int submode;            int advance;            advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);            speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);            if (advance < 0)            {               speex_notify("Invalid mode encountered. The stream is corrupted.");               return -2;            }             advance -= (SB_SUBMODE_BITS+1);            speex_bits_advance(bits, advance);                        if (speex_bits_remaining(bits)<5)               return -1;            wideband = speex_bits_unpack_unsigned(bits, 1);            if (wideband)            {               advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);               speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);               if (advance < 0)               {                  speex_notify("Invalid mode encountered. The stream is corrupted.");                  return -2;               }                advance -= (SB_SUBMODE_BITS+1);               speex_bits_advance(bits, advance);               wideband = speex_bits_unpack_unsigned(bits, 1);               if (wideband)               {                  speex_notify("More than two wideband layers found. The stream is corrupted.");                  return -2;               }            }         }         if (speex_bits_remaining(bits)<4)            return -1;         /* FIXME: Check for overflow */         m = speex_bits_unpack_unsigned(bits, 4);         if (m==15) /* We found a terminator */         {            return -1;         } else if (m==14) /* Speex in-band request */         {            int ret = speex_inband_handler(bits, st->speex_callbacks, state);            if (ret)               return ret;         } else if (m==13) /* User in-band request */         {            int ret = st->user_callback.func(bits, state, st->user_callback.data);            if (ret)               return ret;         } else if (m>8) /* Invalid mode */         {            speex_notify("Invalid mode encountered. The stream is corrupted.");            return -2;         }            } while (m>8);      /* Get the sub-mode that was used */      st->submodeID = m;#ifdef EPIC_48K         }#endif      }   }   /* Shift all buffers by one frame */   speex_move(st->excBuf, st->excBuf+st->frameSize, (2*st->max_pitch + st->subframeSize + 12)*sizeof(spx_word16_t));   /* If null mode (no transmission), just set a couple things to zero*/   if (st->submodes[st->submodeID] == NULL)   {      VARDECL(spx_coef_t *lpc);      ALLOC(lpc, st->lpcSize, spx_coef_t);      bw_lpc(QCONST16(0.93f,15), st->interp_qlpc, lpc, st->lpcSize);      {         float innov_gain=0;         float pgain=GAIN_SCALING_1*st->last_pitch_gain;         if (pgain>.6)            pgain=.6;         /* FIXME: This was innov, not exc */         innov_gain = compute_rms16(st->exc, st->frameSize);         for (i=0;i<st->frameSize;i++)            st->exc[i]=speex_rand(innov_gain, &st->seed);      }      st->first=1;      for (i=0;i<st->frameSize;i++)         out[i] = st->exc[i];      /* Final signal synthesis from excitation */      iir_mem16(out, lpc, out, st->frameSize, st->lpcSize, st->mem_sp, stack);      st->count_lost=0;      return 0;   }   ALLOC(qlsp, st->lpcSize, spx_lsp_t);   /* Unquantize LSPs */   SUBMODE(lsp_unquant)(qlsp, st->lpcSize, bits);   /*Damp memory if a frame was lost and the LSP changed too much*/   if (st->count_lost)   {      spx_word16_t fact;      spx_word32_t lsp_dist=0;      for (i=0;i<st->lpcSize;i++)         lsp_dist = ADD32(lsp_dist, EXTEND32(ABS(st->old_qlsp[i] - qlsp[i])));#ifdef FIXED_POINT      fact = SHR16(19661,SHR32(lsp_dist,LSP_SHIFT+2));      #else      fact = .6*exp(-.2*lsp_dist);#endif      for (i=0;i<st->lpcSize;i++)         st->mem_sp[i] = MULT16_32_Q15(fact,st->mem_sp[i]);   }   /* Handle first frame and lost-packet case */   if (st->first || st->count_lost)   {      for (i=0;i<st->lpcSize;i++)         st->old_qlsp[i] = qlsp[i];   }#ifdef EPIC_48K   if (st->lbr_48k) {      pitch_half[0] = st->min_pitch+speex_bits_unpack_unsigned(bits, 7);      pitch_half[1] = pitch_half[0]+speex_bits_unpack_unsigned(bits, 2)-1;      ol_pitch_id = speex_bits_unpack_unsigned(bits, 3);      ol_pitch_coef=GAIN_SCALING*0.13514*ol_pitch_id;      {         int qe;         qe = speex_bits_unpack_unsigned(bits, 4);         ol_gain = SIG_SCALING*exp((qe+2)/2.1),SIG_SHIFT;      }   } else {#endif   /* Get open-loop pitch estimation for low bit-rate pitch coding */   if (SUBMODE(lbr_pitch)!=-1)   {      ol_pitch = st->min_pitch+speex_bits_unpack_unsigned(bits, 7);   }       if (SUBMODE(forced_pitch_gain))   {      int quant;      quant = speex_bits_unpack_unsigned(bits, 4);      ol_pitch_coef=GAIN_SCALING*0.066667*quant;   }      /* Get global excitation gain */   {      int qe;      qe = speex_bits_unpack_unsigned(bits, 5);#ifdef FIXED_POINT      /* FIXME: Perhaps we could slightly lower the gain here when the output is going to saturate? */      ol_gain = MULT16_32_Q15(28406,ol_gain_table[qe]);#else      ol_gain = SIG_SCALING*exp(qe/3.5);#endif   }#ifdef EPIC_48K   }#endif   ALLOC(ak, st->lpcSize, spx_coef_t);   ALLOC(innov, st->subframeSize, spx_sig_t);   ALLOC(exc32, st->subframeSize, spx_word32_t);   if (st->submodeID==1)   {      int extra;      extra = speex_bits_unpack_unsigned(bits, 4);      if (extra==15)         st->dtx_enabled=1;      else         st->dtx_enabled=0;   }   if (st->submodeID>1)      st->dtx_enabled=0;   /*Loop on subframes */   for (sub=0;sub<st->nbSubframes;sub++)   {      int offset;      spx_word16_t *exc;      spx_word16_t *sp;      spx_word16_t *innov_save = NULL;      spx_word16_t tmp;#ifdef EPIC_48K      if (st->lbr_48k)      {         if (sub*2 < st->nbSubframes)            ol_pitch = pitch_half[0];         else            ol_pitch = pitch_half[1];      }#endif      /* Offset relative to start of frame */      offset = st->subframeSize*sub;      /* Excitation */      exc=st->exc+offset;      /* Original signal */      sp=out+offset;      if (st->innov_save)         innov_save = st->innov_save+offset;      /* Reset excitation */      for (i=0;i<st->subframeSize;i++)         exc[i]=0;      /*Adaptive codebook contribution*/      if (SUBMODE(ltp_unquant))      {         int pit_min, pit_max;         /* Handle pitch constraints if any */         if (SUBMODE(lbr_pitch) != -1)         {            int margin;            margin = SUBMODE(lbr_pitch);            if (margin)            {/* GT - need optimization?               if (ol_pitch < st->min_pitch+margin-1)                  ol_pitch=st->min_pitch+margin-1;               if (ol_pitch > st->max_pitch-margin)                  ol_pitch=st->max_pitch-margin;               pit_min = ol_pitch-margin+1;               pit_max = ol_pitch+margin;*/               pit_min = ol_pitch-margin+1;               if (pit_min < st->min_pitch)		  pit_min = st->min_pitch;               pit_max = ol_pitch+margin;               if (pit_max > st->max_pitch)		  pit_max = st->max_pitch;            } else {               pit_min = pit_max = ol_pitch;            }         } else {            pit_min = st->min_pitch;            pit_max = st->max_pitch;         }#ifdef EPIC_48K         if (st->lbr_48k)         {             SUBMODE(ltp_unquant)(exc, exc32, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params),                                   st->subframeSize, &pitch, &pitch_gain[0], bits, stack,                                   st->count_lost, offset, st->last_pitch_gain, ol_pitch_id);         } else {#endif             SUBMODE(ltp_unquant)(exc, exc32, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params),                                   st->subframeSize, &pitch, &pitch_gain[0], bits, stack,                                   st->count_lost, offset, st->last_pitch_gain, 0);#ifdef EPIC_48K         }#endif         /* Ensuring that things aren't blowing up as would happen if e.g. an encoder is          crafting packets to make us produce NaNs and slow down the decoder (vague DoS threat).         We can probably be even more aggressive and limit to 15000 or so. */         sanitize_values32(exc32, NEG32(QCONST32(32000,SIG_SHIFT-1)), QCONST32(32000,SIG_SHIFT-1), st->subframeSize);                  tmp = gain_3tap_to_1tap(pitch_gain);         pitch_average += tmp;         if ((tmp>best_pitch_gain&&ABS(2*best_pitch-pitch)>=3&&ABS(3*best_pitch-pitch)>=4&&ABS(4*best_pitch-pitch)>=5)               || (tmp>MULT16_16_Q15(QCONST16(.6,15),best_pitch_gain)&&(ABS(best_pitch-2*pitch)<3||ABS(best_pitch-3*pitch)<4||ABS(best_pitch-4*pitch)<5))               || (MULT16_16_Q15(QCONST16(.67,15),tmp)>best_pitch_gain&&(ABS(2*best_pitch-pitch)<3||ABS(3*best_pitch-pitch)<4||ABS(4*best_pitch-pitch)<5)) )         {            best_pitch = pitch;            if (tmp > best_pitch_gain)               best_pitch_gain = tmp;         }      } else {         speex_error("No pitch prediction, what's wrong");      }            /* Unquantize the innovation */      {         int q_energy;         spx_word32_t ener;                  for (i=0;i<st->subframeSize;i++)            innov[i]=0;         /* Decode sub-frame gain correction */         if (SUBMODE(have_subframe_gain)==3)         {            q_energy = speex_bits_unpack_unsigned(bits, 3);            ener = MULT16_32_Q14(exc_gain_quant_scal3[q_energy],ol_gain);         } else if (SUBMODE(have_subframe_gain)==1)         {            q_energy = speex_bits_unpack_unsigned(bits, 1);            ener = MULT16_32_Q14(exc_gain_quant_scal1[q_energy],ol_gain);         } else {            ener = ol_gain;         }                           if (SUBMODE(innovation_unquant))         {            /*Fixed codebook contribution*/            SUBMODE(innovation_unquant)(innov, SUBMODE(innovation_params), st->subframeSize, bits, stack, &st->seed);            /* De-normalize innovation and update excitation */#ifdef FIXED_POINT            signal_mul(innov, innov, ener, st->subframeSize);#else            signal_mul(innov, innov, ener, st->subframeSize);#endif            /* Decode second codebook (only for some modes) */            if (SUBMODE(double_codebook))            {               char *tmp_stack=stack;               VARDECL(spx_sig_t *innov2);               ALLOC(innov2, st->subframeSize, spx_sig_t);               for (i=0;i<st->subframeSize;i++)                  innov2[i]=0;               SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize, bits, stack, &st->seed);               signal_mul(innov2, innov2, MULT16_32_Q15(QCONST16(0.454545f,15),ener), st->subframeSize);               for (i=0;i<st->subframeSize;i++)                  innov[i] = ADD32(innov[i], innov2[i]);               stack = tmp_stack;            }            for (i=0;i<st->subframeSize;i++)               exc[i]=EXTRACT16(SATURATE32(PSHR32(ADD32(SHL32(exc32[i],1),innov[i]),SIG_SHIFT),32767));            /*print_vec(exc, 40, "innov");*/            if (innov_save)            {               for (i=0;i<st->subframeSize;i++)                  innov_save[i] = EXTRACT16(PSHR32(innov[i], SIG_SHIFT));            }         } else {            speex_error("No fixed codebook");         }         /*Vocoder mode*/         if (st->submodeID==1)          {            float g=ol_pitch_coef*GAIN_SCALING_1;                        for (i=0;i<st->subframeSize;i++)               exc[i]=0;            while (st->voc_offset<st->subframeSize)            {               if (st->voc_offset>=0)                  exc[st->voc_offset]=sqrt(1.0*ol_pitch);               st->voc_offset+=ol_pitch;            }            st->voc_offset -= st->subframeSize;            g=.5+2*(g-.6);            if (g<0)               g=0;            if (g>1)               g=1;            for (i=0;i<st->subframeSize;i++)            {               spx_word16_t exci=exc[i];               /* FIXME: cleanup the innov[i]/SIG_SCALING */               exc[i]=.8*g*exc[i]*PSHR32(ol_gain,SIG_SHIFT) + .6*g*st->voc_m1*PSHR32(ol_gain,SIG_SHIFT) + (1-.5*g)*PSHR32(innov[i],SIG_SHIFT) - .5*g*PSHR32(st->voc_m2,SIG_SHIFT);               st->voc_m1 = exci;               st->voc_m2=innov[i];               st->voc_mean = .95*st->voc_mean + .05*exc[i];               exc[i]-=st->voc_mean;            }         }      }   }

⌨️ 快捷键说明

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