ol_gain = exp(qe/3.5);
ol_gain = exp(qe/3.5)*SIG_SCALING;
int nb_encode(void *state, short *in, SpeexBits *bits){   EncState *st;   int i, sub, roots;   int ol_pitch;   float ol_pitch_coef;   float ol_gain;   spx_sig_t *res, *target;   spx_mem_t *mem;   char *stack;   spx_sig_t *syn_resp;   float lsp_dist=0;   spx_sig_t *orig;#ifdef EPIC_48K   int pitch_half[2];   int ol_pitch_id=0;#endif   st=(EncState *)state;   stack=st->stack;   /* Copy new data in input buffer */   speex_move(st->inBuf, st->inBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(spx_sig_t));   for (i=0;i<st->frameSize;i++)      st->inBuf[st->bufSize-st->frameSize+i] = SHL((int)in[i], SIG_SHIFT);   /* Move signals 1 frame towards the past */   speex_move(st->exc2Buf, st->exc2Buf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(spx_sig_t));   speex_move(st->excBuf, st->excBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(spx_sig_t));   speex_move(st->swBuf, st->swBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(spx_sig_t));   {      spx_word16_t *w_sig;      w_sig = PUSH(stack, st->windowSize, spx_word16_t);      /* Window for analysis */      for (i=0;i<st->windowSize;i++)         w_sig[i] = SHR(MULT16_16(SHR((spx_word32_t)(st->frame[i]),SIG_SHIFT),st->window[i]),SIG_SHIFT);      /* Compute auto-correlation */      _spx_autocorr(w_sig, st->autocorr, st->lpcSize+1, st->windowSize);   }   st->autocorr[0] = (spx_word16_t) (st->autocorr[0]*st->lpc_floor); /* Noise floor in auto-correlation domain */   /* Lag windowing: equivalent to filtering in the power-spectrum domain */   for (i=0;i<st->lpcSize+1;i++)      st->autocorr[i] = (spx_word16_t) (st->autocorr[i]*st->lagWindow[i]);   /* Levinson-Durbin */   _spx_lpc(st->lpc+1, st->autocorr, st->lpcSize);   st->lpc[0]=(spx_coef_t)LPC_SCALING;   /* LPC to LSPs (x-domain) transform */   roots=lpc_to_lsp (st->lpc, st->lpcSize, st->lsp, 15, 0.2, stack);   /* Check if we found all the roots */   if (roots!=st->lpcSize)   {      /* Search again if we can afford it */      if (st->complexity>1)         roots = lpc_to_lsp (st->lpc, st->lpcSize, st->lsp, 11, 0.05, stack);      if (roots!=st->lpcSize)       {         /*If we can't find all LSP's, do some damage control and use previous filter*/         for (i=0;i<st->lpcSize;i++)         {            st->lsp[i]=st->old_lsp[i];         }      }   }   lsp_dist=0;   for (i=0;i<st->lpcSize;i++)      lsp_dist += (st->old_lsp[i] - st->lsp[i])*(st->old_lsp[i] - st->lsp[i]);   lsp_dist /= LSP_SCALING*LSP_SCALING;   /* Whole frame analysis (open-loop estimation of pitch and excitation gain) */   {      if (st->first)         for (i=0;i<st->lpcSize;i++)            st->interp_lsp[i] = st->lsp[i];      else         for (i=0;i<st->lpcSize;i++)            st->interp_lsp[i] = .375*st->old_lsp[i] + .625*st->lsp[i];      lsp_enforce_margin(st->interp_lsp, st->lpcSize, .002);      /* Compute interpolated LPCs (unquantized) for whole frame*/      lsp_to_lpc(st->interp_lsp, st->interp_lpc, st->lpcSize,stack);      /*Open-loop pitch*/      if (!st->submodes[st->submodeID] || st->vbr_enabled || st->vad_enabled || SUBMODE(forced_pitch_gain) ||          SUBMODE(lbr_pitch) != -1)      {         int nol_pitch[6];         float nol_pitch_coef[6];                  bw_lpc(st->gamma1, st->interp_lpc, st->bw_lpc1, st->lpcSize);         bw_lpc(st->gamma2, st->interp_lpc, st->bw_lpc2, st->lpcSize);                  filter_mem2(st->frame, st->bw_lpc1, st->bw_lpc2, st->sw, st->frameSize, st->lpcSize, st->mem_sw_whole);         open_loop_nbest_pitch(st->sw, st->min_pitch, st->max_pitch, st->frameSize,                                nol_pitch, nol_pitch_coef, 6, stack);         ol_pitch=nol_pitch[0];         ol_pitch_coef = nol_pitch_coef[0];         /*Try to remove pitch multiples*/         for (i=1;i<6;i++)         {            if ((nol_pitch_coef[i]>.85*ol_pitch_coef) &&                 (fabs(nol_pitch[i]-ol_pitch/2.0)<=1 || fabs(nol_pitch[i]-ol_pitch/3.0)<=1 ||                  fabs(nol_pitch[i]-ol_pitch/4.0)<=1 || fabs(nol_pitch[i]-ol_pitch/5.0)<=1))            {               /*ol_pitch_coef=nol_pitch_coef[i];*/               ol_pitch = nol_pitch[i];            }         }         /*if (ol_pitch>50)           ol_pitch/=2;*/         /*ol_pitch_coef = sqrt(ol_pitch_coef);*/#ifdef EPIC_48K         if (st->lbr_48k)         {            if (ol_pitch < st->min_pitch+2)               ol_pitch = st->min_pitch+2;            if (ol_pitch > st->max_pitch-2)               ol_pitch = st->max_pitch-2;            open_loop_nbest_pitch(st->sw, ol_pitch-2, ol_pitch+2, st->frameSize>>1,                                   &pitch_half[0], nol_pitch_coef, 1, stack);            open_loop_nbest_pitch(st->sw+(st->frameSize>>1), pitch_half[0]-1, pitch_half[0]+2, st->frameSize>>1,                                   &pitch_half[1], nol_pitch_coef, 1, stack);         }#endif      } else {         ol_pitch=0;         ol_pitch_coef=0;      }      /*Compute "real" excitation*/      fir_mem2(st->frame, st->interp_lpc, st->exc, st->frameSize, st->lpcSize, st->mem_exc);      /* Compute open-loop excitation gain */#ifdef EPIC_48K      if (st->lbr_48k)      {         float ol1=0,ol2=0;         float ol_gain2;         ol1 = compute_rms(st->exc, st->frameSize>>1);         ol2 = compute_rms(st->exc+(st->frameSize>>1), st->frameSize>>1);         ol1 *= ol1*(st->frameSize>>1);         ol2 *= ol2*(st->frameSize>>1);         ol_gain2=ol1;         if (ol2>ol1)            ol_gain2=ol2;         ol_gain2 = sqrt(2*ol_gain2*(ol1+ol2))*1.3*(1-.5*ol_pitch_coef*ol_pitch_coef);               ol_gain=sqrt(1+ol_gain2/st->frameSize);      } else {#endif         ol_gain = compute_rms(st->exc, st->frameSize);#ifdef EPIC_48K      }#endif   }   /*VBR stuff*/   if (st->vbr && (st->vbr_enabled||st->vad_enabled))   {            if (st->abr_enabled)      {         float qual_change=0;         if (st->abr_drift2 * st->abr_drift > 0)         {            /* Only adapt if long-term and short-term drift are the same sign */            qual_change = -.00001*st->abr_drift/(1+st->abr_count);            if (qual_change>.05)               qual_change=.05;            if (qual_change<-.05)               qual_change=-.05;         }         st->vbr_quality += qual_change;         if (st->vbr_quality>10)            st->vbr_quality=10;         if (st->vbr_quality<0)            st->vbr_quality=0;      }      st->relative_quality = vbr_analysis(st->vbr, in, st->frameSize, ol_pitch, ol_pitch_coef);      /*if (delta_qual<0)*/      /*  delta_qual*=.1*(3+st->vbr_quality);*/      if (st->vbr_enabled)       {         int mode;         int choice=0;         float min_diff=100;         mode = 8;         while (mode)         {            int v1;            float thresh;            v1=(int)floor(st->vbr_quality);            if (v1==10)               thresh = vbr_nb_thresh[mode][v1];            else               thresh = (st->vbr_quality-v1)*vbr_nb_thresh[mode][v1+1] + (1+v1-st->vbr_quality)*vbr_nb_thresh[mode][v1];            if (st->relative_quality > thresh &&                 st->relative_quality-thresh<min_diff)            {               choice = mode;               min_diff = st->relative_quality-thresh;            }            mode--;         }         mode=choice;         if (mode==0)         {            if (st->dtx_count==0 || lsp_dist>.05 || !st->dtx_enabled || st->dtx_count>20)            {               mode=1;               st->dtx_count=1;            } else {               mode=0;               st->dtx_count++;            }         } else {            st->dtx_count=0;         }         speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);         if (st->abr_enabled)         {            int bitrate;            speex_encoder_ctl(state, SPEEX_GET_BITRATE, &bitrate);            st->abr_drift+=(bitrate-st->abr_enabled);            st->abr_drift2 = .95*st->abr_drift2 + .05*(bitrate-st->abr_enabled);            st->abr_count += 1.0;         }      } else {         /*VAD only case*/         int mode;         if (st->relative_quality<2)         {            if (st->dtx_count==0 || lsp_dist>.05 || !st->dtx_enabled || st->dtx_count>20)            {               st->dtx_count=1;               mode=1;            } else {               mode=0;               st->dtx_count++;            }         } else {            st->dtx_count = 0;            mode=st->submodeSelect;         }         /*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/         st->submodeID=mode;      }    } else {      st->relative_quality = -1;   }   if (st->encode_submode)   {#ifdef EPIC_48K   if (!st->lbr_48k) {#endif   /* First, transmit a zero for narrowband */   speex_bits_pack(bits, 0, 1);   /* Transmit the sub-mode we use for this frame */   speex_bits_pack(bits, st->submodeID, NB_SUBMODE_BITS);#ifdef EPIC_48K   }#endif   }   /* If null mode (no transmission), just set a couple things to zero*/   if (st->submodes[st->submodeID] == NULL)   {      for (i=0;i<st->frameSize;i++)         st->exc[i]=st->exc2[i]=st->sw[i]=0;      for (i=0;i<st->lpcSize;i++)         st->mem_sw[i]=0;      st->first=1;      st->bounded_pitch = 1;      /* Final signal synthesis from excitation */      iir_mem2(st->exc, st->interp_qlpc, st->frame, st->frameSize, st->lpcSize, st->mem_sp);      for (i=0;i<st->frameSize;i++)         in[i]=st->frame[i];      return 0;   }   /* LSP Quantization */   if (st->first)   {      for (i=0;i<st->lpcSize;i++)         st->old_lsp[i] = st->lsp[i];   }   /*Quantize LSPs*/#if 1 /*0 for unquantized*/   SUBMODE(lsp_quant)(st->lsp, st->qlsp, st->lpcSize, bits);#else   for (i=0;i<st->lpcSize;i++)     st->qlsp[i]=st->lsp[i];#endif#ifdef EPIC_48K   if (st->lbr_48k) {      speex_bits_pack(bits, pitch_half[0]-st->min_pitch, 7);      speex_bits_pack(bits, pitch_half[1]-pitch_half[0]+1, 2);            {         int quant = (int)floor(.5+7.4*ol_pitch_coef);         if (quant>7)            quant=7;         if (quant<0)            quant=0;         ol_pitch_id=quant;         speex_bits_pack(bits, quant, 3);         ol_pitch_coef=0.13514*quant;               }      {         int qe = (int)(floor(.5+2.1*log(ol_gain)))-2;         if (qe<0)            qe=0;         if (qe>15)            qe=15;         ol_gain = exp((qe+2)/2.1);         speex_bits_pack(bits, qe, 4);      }   } else {#endif   /*If we use low bit-rate pitch mode, transmit open-loop pitch*/   if (SUBMODE(lbr_pitch)!=-1)   {      speex_bits_pack(bits, ol_pitch-st->min_pitch, 7);   }    if (SUBMODE(forced_pitch_gain))   {      int quant;      quant = (int)floor(.5+15*ol_pitch_coef);      if (quant>15)         quant=15;      if (quant<0)         quant=0;      speex_bits_pack(bits, quant, 4);      ol_pitch_coef=0.066667*quant;   }         /*Quantize and transmit open-loop excitation gain*/   {      int qe = (int)(floor(3.5*log(ol_gain)));      if (qe<0)         qe=0;      if (qe>31)         qe=31;      ol_gain = exp(qe/3.5);      speex_bits_pack(bits, qe, 5);   }#ifdef EPIC_48K   }#endif   /* Special case for first frame */   if (st->first)   {      for (i=0;i<st->lpcSize;i++)         st->old_qlsp[i] = st->qlsp[i];   }   /* Filter response */   res = PUSH(stack, st->subframeSize, spx_sig_t);   /* Target signal */   target = PUSH(stack, st->subframeSize, spx_sig_t);   syn_resp = PUSH(stack, st->subframeSize, spx_sig_t);   mem = PUSH(stack, st->lpcSize, spx_mem_t);   orig = PUSH(stack, st->frameSize, spx_sig_t);   for (i=0;i<st->frameSize;i++)      orig[i]=st->frame[i];   /* Loop on sub-frames */   for (sub=0;sub<st->nbSubframes;sub++)   {      float tmp;      int   offset;      spx_sig_t *sp, *sw, *exc, *exc2;      int pitch;#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;      /* Original signal */      sp=st->frame+offset;      /* Excitation */      exc=st->exc+offset;      /* Weighted signal */      sw=st->sw+offset;      exc2=st->exc2+offset;      /* LSP interpolation (quantized and unquantized) */      tmp = (1.0 + sub)/st->nbSubframes;      for (i=0;i<st->lpcSize;i++)         st->interp_lsp[i] = (1-tmp)*st->old_lsp[i] + tmp*st->lsp[i];      for (i=0;i<st->lpcSize;i++)         st->interp_qlsp[i] = (1-tmp)*st->old_qlsp[i] + tmp*st->qlsp[i];      /* Make sure the filters are stable */      lsp_enforce_margin(st->interp_lsp, st->lpcSize, .002);      lsp_enforce_margin(st->interp_qlsp, st->lpcSize, .002);      /* Compute interpolated LPCs (quantized and unquantized) */      lsp_to_lpc(st->interp_lsp, st->interp_lpc, st->lpcSize,stack);      lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack);      /* Compute analysis filter gain at w=pi (for use in SB-CELP) */      tmp=1;      st->pi_gain[sub]=0;      for (i=0;i<=st->lpcSize;i++)      {         st->pi_gain[sub] += tmp*st->interp_qlpc[i];         tmp = -tmp;      }      st->pi_gain[sub] /= LPC_SCALING;      /* Compute bandwidth-expanded (unquantized) LPCs for perceptual weighting */      bw_lpc(st->gamma1, st->interp_lpc, st->bw_lpc1, st->lpcSize);      if (st->gamma2>=0)         bw_lpc(st->gamma2, st->interp_lpc, st->bw_lpc2, st->lpcSize);      else      {         st->bw_lpc2[0]=1;         for (i=1;i<=st->lpcSize;i++)            st->bw_lpc2[i]=0;      }      /* Compute impulse response of A(z/g1) / ( A(z)*A(z/g2) )*/      for (i=0;i<st->subframeSize;i++)         exc[i]=0;      exc[0]=SIG_SCALING;      syn_percep_zero(exc, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, syn_resp, st->subframeSize, st->lpcSize, stack);      /* Reset excitation */      for (i=0;i<st->subframeSize;i++)         exc[i]=0;      for (i=0;i<st->subframeSize;i++)         exc2[i]=0;      /* Compute zero response of A(z/g1) / ( A(z/g2) * A(z) ) */      for (i=0;i<st->lpcSize;i++)         mem[i]=st->mem_sp[i];      iir_mem2(exc, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, mem);            for (i=0;i<st->lpcSize;i++)         mem[i]=st->mem_sw[i];      filter_mem2(exc, st->bw_lpc1, st->bw_lpc2, res, st->subframeSize, st->lpcSize, mem);            /* Compute weighted signal */      for (i=0;i<st->lpcSize;i++)         mem[i]=st->mem_sw[i];      filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, mem);            /* Compute target signal */      for (i=0;i<st->subframeSize;i++)         target[i]=sw[i]-res[i];      for (i=0;i<st->subframeSize;i++)         exc[i]=exc2[i]=0;      /* If we have a long-term predictor (otherwise, something's wrong) */      if (SUBMODE(ltp_quant))      {         int pit_min, pit_max;         /* Long-term prediction */         if (SUBMODE(lbr_pitch) != -1)         {            /* Low bit-rate pitch handling */            int margin;            margin = SUBMODE(lbr_pitch);            if (margin)            {               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;            } else {               pit_min=pit_max=ol_pitch;            }         } else {            pit_min = st->min_pitch;            pit_max = st->max_pitch;         }                  /* Force pitch to use only the current frame if needed */         if (st->bounded_pitch && pit_max>offset)            pit_max=offset;#ifdef EPIC_48K         if (st->lbr_48k)         {            pitch = SUBMODE(ltp_quant)(target, sw, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,                                       exc, SUBMODE(ltp_params), pit_min, pit_max, ol_pitch_coef,                                       st->lpcSize, st->subframeSize, bits, stack,                                        exc2, syn_resp, st->complexity, ol_pitch_id);         } else {#endif         /* Perform pitch search */         pitch = SUBMODE(ltp_quant)(target, sw, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,                                    exc, SUBMODE(ltp_params), pit_min, pit_max, ol_pitch_coef,                                    st->lpcSize, st->subframeSize, bits, stack,                                     exc2, syn_resp, st->complexity, 0);#ifdef EPIC_48K         }#endif         st->pitch[sub]=pitch;      } else {         speex_error ("No pitch prediction, what's wrong");      }      /* Update target for adaptive codebook contribution */      syn_percep_zero(exc, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, res, st->subframeSize, st->lpcSize, stack);      for (i=0;i<st->subframeSize;i++)         target[i]-=res[i];      /* Quantization of innovation */      {         spx_sig_t *innov;         float ener=0, ener_1;         innov = st->innov+sub*st->subframeSize;         for (i=0;i<st->subframeSize;i++)            innov[i]=0;                  residue_percep_zero(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, st->buf2, st->subframeSize, st->lpcSize, stack);         ener = compute_rms(st->buf2, st->subframeSize);         /*for (i=0;i<st->subframeSize;i++)            printf ("%f\n", st->buf2[i]/ener);         */                  ener /= ol_gain;         /* Calculate gain correction for the sub-frame (if any) */         if (SUBMODE(have_subframe_gain))          {            int qe;            ener=log(ener);            if (SUBMODE(have_subframe_gain)==3)            {               qe = vq_index(&ener, exc_gain_quant_scal3, 1, 8);               speex_bits_pack(bits, qe, 3);               ener=exc_gain_quant_scal3[qe];            } else {               qe = vq_index(&ener, exc_gain_quant_scal1, 1, 2);               speex_bits_pack(bits, qe, 1);               ener=exc_gain_quant_scal1[qe];                           }            ener=exp(ener);         } else {            ener=1;         }         ener*=ol_gain;         /*printf ("%f %f\n", ener, ol_gain);*/         ener_1 = 1/ener;         /* Normalize innovation */         signal_div(target, target, ener, st->subframeSize);                  /* Quantize innovation */         if (SUBMODE(innovation_quant))         {            /* Codebook search */            SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,                                       SUBMODE(innovation_params), st->lpcSize, st->subframeSize,                                       innov, syn_resp, bits, stack, st->complexity);                        /* De-normalize innovation and update excitation */            signal_mul(innov, innov, ener, st->subframeSize);            for (i=0;i<st->subframeSize;i++)               exc[i] += innov[i];         } else {            speex_error("No fixed codebook");         }         /* In some (rare) modes, we do a second search (more bits) to reduce noise even more */         if (SUBMODE(double_codebook)) {            char *tmp_stack=stack;            spx_sig_t *innov2 = PUSH(tmp_stack, st->subframeSize, spx_sig_t);            for (i=0;i<st->subframeSize;i++)               innov2[i]=0;            for (i=0;i<st->subframeSize;i++)               target[i]*=2.2;            SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,                                       SUBMODE(innovation_params), st->lpcSize, st->subframeSize,                                       innov2, syn_resp, bits, tmp_stack, st->complexity);            for (i=0;i<st->subframeSize;i++)               innov2[i]*=ener*(1/2.2);            for (i=0;i<st->subframeSize;i++)               exc[i] += innov2[i];         }         signal_mul(target, target, ener, st->subframeSize);      }      /*Keep the previous memory*/      for (i=0;i<st->lpcSize;i++)         mem[i]=st->mem_sp[i];      /* Final signal synthesis from excitation */      iir_mem2(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp);      /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */      filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw);      for (i=0;i<st->subframeSize;i++)         exc2[i]=exc[i];   }   /* Store the LSPs for interpolation in the next frame */   if (st->submodeID>=1)   {      for (i=0;i<st->lpcSize;i++)         st->old_lsp[i] = st->lsp[i];      for (i=0;i<st->lpcSize;i++)         st->old_qlsp[i] = st->qlsp[i];   }   if (st->submodeID==1)   {      if (st->dtx_count)         speex_bits_pack(bits, 15, 4);      else         speex_bits_pack(bits, 0, 4);   }   /* The next frame will not be the first (Duh!) */   st->first = 0;   if (0) {      float ener=0, err=0;      float snr;      for (i=0;i<st->frameSize;i++)      {         ener+=st->frame[i]*st->frame[i];         err += (st->frame[i]-orig[i])*(st->frame[i]-orig[i]);      }      snr = 10*log10((ener+1)/(err+1));      /*printf ("%f %f %f\n", snr, ener, err);*/   }   /* Replace input by synthesized speech */   for (i=0;i<st->frameSize;i++)   {      spx_word32_t sig = PSHR(st->frame[i],SIG_SHIFT);      if (sig>32767)         sig = 32767;      if (sig<-32767)         sig = -32767;     in[i]=sig;   }   if (SUBMODE(innovation_quant) == noise_codebook_quant || st->submodeID==0)      st->bounded_pitch = 1;   else      st->bounded_pitch = 0;   return 1;}