Beispiel #1
0
void apfilter(int16_t a[],	/* (i) Q12 : prediction coefficients  */
	      int16_t m,		/* (i)     : LPC order                */
	      int16_t x[],	/* (i) Q0  : input signal             */
	      int16_t y[],	/* (o) Q0  : output signal            */
	      int16_t lg,	/* (i)     : size of filtering        */
	      int16_t mem[],	/* (i/o) Q0: filter memory            */
	      int16_t update	/* (i)     : memory update flag       */
    )
{
	int16_t buf[BUFFERSIZE];	/* buffer for filter memory & signal */
	int32_t a0;
	int16_t *fp1;
	int16_t i, n;

	/* copy filter memory to beginning part of temporary buffer */
	W16copy(buf, mem, m);

	/* loop through every element of the current vector */
	for (n = 0; n < lg; n++) {

		/* perform bv_multiply-bv_adds along the delay line of filter */
		fp1 = &buf[n];
		a0 = L_bv_mult0(4096, x[n]);	// Q12
		for (i = m; i > 0; i--)
			a0 = bv_L_msu0(a0, a[i], *fp1++);	// Q12

		/* update temporary buffer for filter memory */
		*fp1 = intround(L_bv_shl(a0, 4));
	}

	/* copy to output array */
	W16copy(y, buf + m, lg);

	/* get the filter memory after filtering the current vector */
	if (update)
		W16copy(mem, buf + lg, m);

	return;
}
Beispiel #2
0
void BV16_Decode(
                 struct BV16_Bit_Stream     *bs,
                 struct BV16_Decoder_State  *ds,
                 Word16    *x)
{
   Word32 lgq, lg_el;
   Word16 gainq;         /* Q3 */
   Word16 pp;
   Word32 a0;
   Word16 gain_exp;
   Word16 i;
   Word16 a0hi, a0lo;
   Word16 ltsym[LTMOFF+FRSZ];
   Word16 xq[LXQ];
   Word16 a[LPCO+1];
   Word16 lspq[LPCO];       /* Q15 */
   Word16 cbs[VDIM*CBSZ];
   Word16 bq[3];         /* Q15 */
   Word32 bss;
   Word32  E;
   
   /* set frame erasure flags */
   if (ds->cfecount != 0) {
      ds->ngfae = 1;
   } else {
      ds->ngfae++;
      if (ds->ngfae>LGPORDER) ds->ngfae=LGPORDER+1;
   }
   
   /* reset frame erasure counter */
   ds->cfecount = 0;
   
   /* decode pitch period */
   pp = (bs->ppidx + MINPP);
   
   /* decode spectral information */
   lspdec(lspq,bs->lspidx,ds->lsppm,ds->lsplast);
   lsp2a(lspq,a);
   W16copy(ds->lsplast, lspq, LPCO);
   
   /* decode pitch taps */
   pp3dec(bs->bqidx, bq);
   
   /* decode gain */
   a0 = gaindec(&lgq,bs->gidx,ds->lgpm,ds->prevlg,ds->level,
      &ds->nggalgc,&lg_el);
   
   /* gain normalization */
   gain_exp = sub(norm_l(a0), 2);
   /* scale down quantized gain by 1.5, 1/1.5=2/3 (21845 Q15) */
   L_Extract(a0, &a0hi, &a0lo);
   a0 = Mpy_32_16(a0hi, a0lo, 21845);  
   gainq = intround(L_shl(a0, gain_exp));
   
   
   /* scale the scalar quantizer codebook to current signal level */
   for (i=0;i<(VDIM*CBSZ);i++) cbs[i] = mult_r(gainq, cccb[i]);
   
   /* copy state memory to buffer */
   W16copy(xq, ds->xq, XQOFF);
   W16copy(ltsym, ds->ltsym, LTMOFF);
   
   /* decoding of the excitation signal with integrated long-term */
   /* and short-term synthesis */
   excdec_w_synth(xq+XQOFF,ltsym+LTMOFF,ds->stsym,bs->qvidx,bq,cbs,pp,
      a,gain_exp,&E);
   
   ds->E = E;
   
   /* update the remaining state memory */
   W16copy(ds->ltsym, ltsym+FRSZ, LTMOFF);
   W16copy(ds->xq, xq+FRSZ, XQOFF);
   ds->pp_last = pp;
   W16copy(ds->bq_last, bq, 3);
   
   /* level estimation */
   estlevel(lg_el,&ds->level,&ds->lmax,&ds->lmin,&ds->lmean,&ds->x1,
      ds->ngfae, ds->nggalgc,&ds->estl_alpha_min);

   /* adaptive postfiltering */
   postfilter(xq, pp, &(ds->ma_a), ds->b_prv, &(ds->pp_prv), x);

   /* scale signal up by 1.5 */
   for(i=0; i<FRSZ; i++)
      x[i] = add(x[i], shr(x[i],1));
   
   W16copy(ds->atplc, a, LPCO+1);
   bss = L_add(L_add(bq[0], bq[1]), bq[2]);
   if (bss > 32768)
      bss = 32768;
   else if (bss < 0)
      bss = 0;
   ds->per = add(shr(ds->per, 1), (Word16)L_shr(bss, 1));
   
}
Beispiel #3
0
void excdec_w_synth(
                    Word16 *xq,      /* (o) Q0 quantized signal vector               */
                    Word16 *ltsym,   /* (i/o) Q0 quantized excitation signal vector  */
                    Word16 *stsym,   /* (i/o) Q0 short-term predictor memory         */
                    Word16 *idx,     /* (o) quantizer codebook index for uq[] vector */
                    Word16 *b,       /* (i) Q15 coefficient of 3-tap pitch predictor */
                    Word16 *cb,      /* (i) Q0 codebook                              */
                    Word16 pp,       /* pitch period (# of 8 kHz samples)            */
                    Word16 *aq,      /* (i) Q12 short-term predictor coefficients    */
                    Word16 gain_exp, /* gain_exp of current sub-frame                */
                    Word32 *EE
                    )
{
   Word16 i, n, m, *ip, id;
   Word16 *fp1, *fp2, *fp3;
   Word32 a0;
   Word16 tt;
   Word32 E;
   Word32 a1;
   Word16 buf1[LPCO+FRSZ];   /* buffer for filter memory & signal     */
   Word16 uq[VDIM];           /* selected codebook vector (incl. sign) */ 
   
   W16copy(buf1, stsym, LPCO);  /* buffer is used to avoid memory shifts */
   
   ip=idx;
   E = 0;
   
   /* Loop through every vector of the current subframe */
   for (m = 0; m < FRSZ; m += VDIM) {
      
      /********************************************************************************/
      /*                               Excitation vector                              */
      /********************************************************************************/
      
      id = *ip++;   /* get codebook index of current vector */
      fp1 = uq;
      if (id < CBSZ){
         fp2 = &cb[id*VDIM];
         for (n=0;n<VDIM;n++) {
            *fp1++ = *fp2++;                 // Q0
         }
      }
      else {
         id -= CBSZ;
         fp2 = &cb[id*VDIM];
         for (n=0;n<VDIM;n++) {
            *fp1++ = negate(*fp2++);         // Q0
         }
      }
      
      /********************************************************************************/
      /*                      Long-term and short-term synthesis                      */
      /********************************************************************************/
      
      fp2 = uq;
      fp3 = ltsym + m;
      for (n = m; n < m + VDIM; n++) {
         
         /* Un-normalized excitation */
         a0 = L_shr(L_deposit_h(*fp2++), gain_exp); // Q16
         
         /* Excitation energy for PLC */
         tt = intround(a0);                     // Q0
         E = L_mac0(E, tt, tt);
         
         /* Long-term predicion */
         fp1 = &ltsym[n-pp+1];               // Q0
         a1  = L_mult(*fp1--, b[0]);         // Q16
         a1  = L_mac(a1, *fp1--, b[1]);
         a1  = L_mac(a1, *fp1--, b[2]);
         
         /* Update long-term filter synthesis memory */
         a0 = L_add(a0, a1);
         *fp3++ = intround(a0);                 // Q0
         
         /* Short-term prediction */
         fp1 = &buf1[n];                     // Q0
         a1 = 0;                             // Q13
         for(i = LPCO; i > 0; i--) 
            a1 = L_msu(a1, *fp1++, aq[i]);   // Q13
         a1 = L_shl(a1, 3);                  // Q16
         a1 = L_add(a0, a1); 
         *fp1++ = intround(a1);                 // Q0
         
      }
   }
   
   /* Update noise feedback filter memory after filtering current subframe */
   W16copy(stsym, buf1+FRSZ, LPCO);
   
   /* copy to speech buffer */
   W16copy(xq, buf1+LPCO, FRSZ);
   *EE = E;

   return;
}
Beispiel #4
0
void a2lsp(
           Word16 pc[],       /* (i) Q12: predictor coefficients */
           Word16 lsp[],      /* (o) Q15: line spectral pairs    */
           Word16 old_lsp[])  /* (i) Q15: old lsp                */
{
   Word16 i, j, exp;
   Word16 fa_man[NAB], fa_exp[NAB], fb_man[NAB], fb_exp[NAB];
   Word16 ta_man[NAB], ta_exp[NAB], tb_man[NAB], tb_exp[NAB];
   Word16 *t_man, *t_exp;
   Word32 a0;
   Word16 nd2, nf, ngrd;
   Word16 xroot, xlow, ylow, ind, xhigh, yhigh, xmid, ymid, dx, dy, dxdy, x, sign;


   /* Find normalization for fa and fb */
   /*   fb[0] = fa[0] = 1.0;                             */
   /*   for (i = 1, j = LPCO; i <= (LPCO/2); i++, j--) { */
   /*      fa[i] = pc[i] + pc[j] - fa[i-1];              */
   /*      fb[i] = pc[i] - pc[j] + fb[i-1];              */
   /*   }                                                */
   fa_man[0] = 16384; 
   fa_exp[0] = 6;       // fa_man[0] in high 16-bits >> fa_exp[0] = 1.0 in Q24 
   fb_man[0] = 16384;
   fb_exp[0] = 6;       // fb_man[0] in high 16-bits >> fb_exp[0] = 1.0 in Q24
   for (i = 1, j = LPCO; i <= (LPCO/2); i++, j--) {
      a0 = L_mult0(pc[i], 4096);     // Q24
      a0 = L_mac0(a0, pc[j], 4096);  // Q24
      a0 = L_sub(a0, L_shr(L_deposit_h(fa_man[i-1]),fa_exp[i-1]));  // Q24
      fa_exp[i] = norm_l(a0);
      fa_man[i] = intround(L_shl(a0, fa_exp[i]));  // Q(8+fb_exp[i])

      a0 = L_mult0(pc[i], 4096);     // Q24
      a0 = L_msu0(a0, pc[j], 4096);  // Q24
      a0 = L_add(a0, L_shr(L_deposit_h(fb_man[i-1]),fb_exp[i-1]));  // Q24
      fb_exp[i] = norm_l(a0);
      fb_man[i] = intround(L_shl(a0, fb_exp[i]));  // Q(8+fb_exp[i])
   }

   nd2 = (LPCO)/2;

   /* ta[] and tb[] in Q(7+exp)               */
   /* ta[0] = fa[nab-1]; ta[i] = 2.0 * fa[j]; */
   /* tb[0] = fb[nab-1]; tb[i] = 2.0 * fb[j]; */
   ta_man[0] = fa_man[NAB-1];
   ta_exp[0] = add(fa_exp[NAB-1], 1);
   tb_man[0] = fb_man[NAB-1];
   tb_exp[0] = add(fb_exp[NAB-1], 1);
   for (i = 1, j = NAB - 2; i < NAB; ++i, --j) {
      ta_man[i] = fa_man[j];
      ta_exp[i] = fa_exp[j];
      tb_man[i] = fb_man[j];
      tb_exp[i] = fb_exp[j];
   }

   nf = 0;
   t_man = ta_man;
   t_exp = ta_exp;
   xroot = 0x7fff;
   ngrd  = 0;
   xlow  = grid[0];  // Q15
   ylow = FNevChebP(xlow, t_man, t_exp, nd2);
   ind = 0;

   /* Root search loop */
   while (ngrd<(Ngrd-1) && nf < LPCO) {
      
      ngrd++;
      xhigh = xlow;
      yhigh = ylow;
      xlow  = grid[ngrd];
      ylow = FNevChebP(xlow, t_man, t_exp, nd2);
      
      if ( L_mult(ylow ,yhigh) <= 0) {
         
         /* Bisections of the interval containing a sign change */
         
         dx = xhigh - xlow;
         for (i = 1; i <= NBIS; ++i) {
            dx = shr(dx, 1);
            xmid = add(xlow, dx);
            ymid = FNevChebP(xmid, t_man, t_exp, nd2);
            if (L_mult(ylow,ymid) <= 0) {
               yhigh = ymid;
               xhigh = xmid;
            } else {
               ylow = ymid;
               xlow = xmid;
            }
         }
         
         /*
         * Linear interpolation in the subinterval with a sign change
         * (take care if yhigh=ylow=0)
         */
         
         dx = sub(xhigh, xlow);
         dy  = sub(ylow, yhigh);
         if (dy != 0) {
            sign = dy;
            dy = abs_s(dy);
            exp = norm_s(dy);
            dy = shl(dy, exp);
            /* The maximum grid distance is 1629 =>                                  */
            /* Maximum dx=1629/2^4=101.8125, i.e. 16384/101.8125=160.92~128 (7 bits) */
            /* However, due to the starting point for the search of a new root,      */
            /* xlow = xroot, 1 more bit of headroom for the division is required.    */
            dxdy = div_s(shl(dx,6), dy); 
            a0 = L_mult(dxdy, ylow);
            a0 = L_shr(a0, sub(6, exp));
            x  = intround(a0);
            if(sign < 0) x = negate(x);
            xmid = add(xlow, x);
         } 
         else {
            xmid = add(xlow, shr(dx,1));
         }
         
         /* acos mapping for New lsp component */
         while (( costable[ind] >= xmid ) && (ind < 63)) ind++;
         ind--;
         a0 = L_mult( sub(xmid, costable[ind]) , acosslope[ind] );
         x  = intround(L_shl(a0, 4));
         lsp[nf] = add(x, shl(ind, 9));
         ++nf;
         
         /* Start the search for the roots of next polynomial at the estimated
         * location of the root just found.  We have to catch the case that the
         * two polynomials have roots at the same place to avoid getting stuck at
         * that root.
         */
         
         if (xmid >= xroot) xmid = xlow - dx;
         xroot = xmid;
         if (t_man == ta_man){
            t_man = tb_man;
            t_exp = tb_exp;
         }
         else{
            t_man = ta_man;
            t_exp = ta_exp;
         }
         xlow = xmid;
         ylow = FNevChebP(xlow, t_man, t_exp, nd2);
         
      }
   }
   
   /* Check if all LSPs are found */
   if( sub(nf, LPCO) < 0)
   {
      W16copy(lsp, old_lsp, LPCO);
   }

   return;
}