/*#define __TEST #ifdef __TEST #include FILE *test; FILE *codage; #endif*/ /* * Project: Direct Subband 16000 bps coder and SBCELP 4800 bps coder * Workfile: encoder.c * Author: Alfred Wiesen * Created: 30 August 1995 * Last update: 4 September 1995 * DLL Version: 1.00 * Revision: Single DLL for coder and decoder. * Comment: * * (C) Copyright 1993-95 Lernout & Hauspie Speech Products N.V. (TM) * All rights reserved. Company confidential. */ // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ // Included files // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ #include #include #include #include "fv_x8.h" #include "data.h" #include "bib_32.h" // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ // Function prototypes // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ void InitializeCoderInstanceData(PVOID p, DWORD dwMaxBitRate); void decimation_I(short input_I[],short coef_I[],short low_part_mem_I[],short order); #if 0 // PhilF: The following is never called!!! void quant_0a16_I2(short z1, short z2 ,short vec[], short maxv, short B1[], short B2[], long *code); #endif void quant_sous_bandes(PC16008DATA p,short *in,short *codes_max, long *codes_sb, short *indic_br/*, short *code_max_br*/); void code_res_I(PC16008DATA p,short input[],short coef[],short qmf_mem[],short v_code[],long cod_long[], short ind_br[]/*, short c_max_br*/); #ifdef CELP4800 void COEFF_A(PC4808DATA p),CALPITCH(PC4808DATA p),CHERCHE(PC4808DATA p); void PERIODE(PC4808DATA p,short no),FRAME(PC4808DATA p); void lsp_quant(PC4808DATA p,short lsp[],short nbit[],short bitdi[],short vcode[]); void cal_dic1(PC4808DATA p,short *y,short *sr,short *espopt,short *posit,short dec,short esp,short sigpit[],short soulong,long tlsp[],long vmax[]); //void cal_dic2(short q,short espace,short phase,short *s_r,short *hy,short *b,short *vois,short *esp,short *qq,short *phas,short sigpit[],short soulong,long tlsp[],long vmax[]); void cal_dic2(PC4808DATA p,short q,short espace,short phase,short *s_r,short *hy,short *b,short *vois,short *esp,short *qq,short *phas); #endif void decimation(short *vin,short *vout,short nech); /*void iConvert64To8(int *in, int *out, int N, int *mem); void iConvert8To64(int *in, int *out, int N, int *mem); void BandPass(int *,int *,int *,int);*/ // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ // Global variables for coder // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ /*#define MAXCODINGHANDLES 10 // Instance data structure PC16008DATA pCoderData; C16008DATA CoderData[MAXCODINGHANDLES]; int CodingHandles[MAXCODINGHANDLES];*/ // ROM tables : extern short coef_I[]; // QMF filter coeffs extern short B3_I[]; // Five levels quantification table extern short B4_I[]; // Four levels quantification table extern short B5_I[]; // Five levels quantification table extern short B6_I[]; // Nine levels quantification table extern short B7_I[]; // Nine levels quantification table extern short B8_I[]; // Nine levels quantification table extern short B9_I[]; // Nine levels quantification table extern short max_level[]; // Quantified maximum sample level extern long coeffs[]; extern long Mask[]; extern short hamming[]; extern short A0[]; extern short tabcos[]; extern short LSP_Q[]; extern short TAB_DI[]; extern short GQ[]; extern short GV[]; extern short BQ[]; extern short BV[]; extern short NBB[]; extern short BITDD[]; extern short LSP0ROM[]; //extern short quantif[]; //extern short bits[]; //extern short bytes[]; // RAM variables : /*extern short codes_max[]; // Quantized max. of each subband extern long codes_sb[]; // Two codes for each of the quantized subband extern short indic_sp[]; // type of subband (1=noise; 0=to be decoded) extern short code_max_br; // 1 bit for coding the noise extern short DATA_I[]; // Intermediate vector = input and output of QMF extern char stream[]; // Coded data buffer*/ // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ // Function implementation // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ void InitializeCoderInstanceData(PVOID p, DWORD dwMaxBitRate) // Instance data initializations { short i; #ifdef CELP4800 if (dwMaxBitRate == 4800) { ((PC4808DATA)p)->dwMaxBitRate = dwMaxBitRate; ((PC4808DATA)p)->mem_pit[0]=((PC4808DATA)p)->mem_pit[1]=69; for (i=0;i<10;i++) ((PC4808DATA)p)->LSP0[i]=LSP0ROM[i]; } else #endif { ((PC16008DATA)p)->dwMaxBitRate = dwMaxBitRate; for (i=0;inbbit[i]=8; // On met les compteurs a "zero"; // on suppose demarrer par du bruit ((PC16008DATA)p)->MAX_LEVEL = MAX_LEVEL1; // valeur par defaut si le debit n'augmente pas trop ((PC16008DATA)p)->DIV_MAX = DIV_MAX1; // cad on ne traite pas les sb < 5% du max[i] ((PC16008DATA)p)->quantif[0] = 9; ((PC16008DATA)p)->quantif[1] = 9; ((PC16008DATA)p)->quantif[4] = 5; ((PC16008DATA)p)->quantif[5] = 5; ((PC16008DATA)p)->quantif[6] = 5; ((PC16008DATA)p)->quantif[7] = 5; ((PC16008DATA)p)->quantif[8] = 5; ((PC16008DATA)p)->quantif[9] = 5; ((PC16008DATA)p)->bits[0] = 52; ((PC16008DATA)p)->bits[2] = 38; ((PC16008DATA)p)->bits[3] = 38; ((PC16008DATA)p)->bits[4] = 38; // Bug 3214: Just in case we get carried away, init the end of the arrays in both configurations ((PC16008DATA)p)->quantif[10] = 5; ((PC16008DATA)p)->quantif[11] = 5; ((PC16008DATA)p)->bits[5] = 38; if (dwMaxBitRate == 16000) { ((PC16008DATA)p)->NBSB_SP_MAX = NBSB_SP_MAX1_16000; // nbre max de sb pouvant etre du signal ((PC16008DATA)p)->quantif[2] = 7; ((PC16008DATA)p)->quantif[3] = 7; ((PC16008DATA)p)->bits[1] = 46; } else { ((PC16008DATA)p)->NBSB_SP_MAX = NBSB_SP_MAX1_8000_12000; // nbre max de sb pouvant etre du signal ((PC16008DATA)p)->quantif[2] = 9; ((PC16008DATA)p)->quantif[3] = 9; ((PC16008DATA)p)->bits[1] = 52; } } return; } //------------------------------------------------------------------------ void decimation_I(short input_I[],short coef_I[],short low_part_mem_I[],short order) // // Purpose : from data stored in DATA[], create the N_SB subbands // Remark : output subband is stored at (input[]+N_SB*L_RES) // { short i,j,lng; short *low_out_part_I; short *high_out_part_I; short *buffer_I,*sa_vec_I; buffer_I = low_part_mem_I; for (i=0;i> (i+1); high_out_part_I=low_out_part_I+lng; sa_vec_I=low_out_part_I; for (j=0;j<(1<B1[x])&&(xB2[x])&&(xB1[x])&&(xB2[x])&&(xB1[x])&&(xB2[x])&&(xB1[x])&&(xB2[x])&&(xmax[i]) max[i]=abs(*(in+16*i+j)); } for (i=0;i<8;i++) { if (max[i]>2*max_level[31]) j = 31; else for (j=0; max[i]>2*max_level[j]; j++); codes_max_loc[i]=j; max[i]=2*max_level[j]; } // fin quantifiation p->nbbit_cf+=8; // 8 bits for the indic_sp maxmax=0; for (i=0;i<8;i++) // On cherche le plus grand maximum { if (max[i]>maxmax) maxmax=max[i]; } maxmax/=p->DIV_MAX; // On le divise par 10 a 20 (cad a peu pres 10 a 5 %) ord=8; p->nbsb_sp=0; for (i=0;i<8;i++) // Calculates the order of the subbands { // 1 is higher energy than 2 than 3,.. maximum=32767; for (j=7;j>=0;j--) { if ((order[j]==0)&&(max[j]p->NBSB_SP_MAX)||(maximum<=p->MAX_LEVEL)||(maximum<=maxmax) ) { indic_sp[max_num]=0; // c'est 1 bande qui sera du bruit } else { indic_sp[max_num]=1; p->nbsb_sp++; } ord--; } j=0; for (i=0;i<8;i++) { if (indic_sp[i]==1) { codes_max[j]=codes_max_loc[i]; //5* 4 ou 5 bits suffisent j++; p->nbbit_cf+=5; // 5 bits per coded max } } for (i=p->nbsb_sp-1;i>=0;i--) { j=0; while (order[j]!=i+1) j++; quant_0a16_I3(p->quantif[2*i],p->quantif[2*i+1],in+j*16,max[j],codes_sb+2*i); p->nbbit_cf+=p->bits[i]; } if (p->dwMaxBitRate == 16000) { j=0; #ifdef MAX_SB_ABSOLU sb_count=p->nbsb_sp; if (sb_count>=MAX_SB_ABSOLU) return; #endif for (i=0;i<8;i++) { if (indic_sp[i]==0) { codes_max[p->nbsb_sp+j]=codes_max_loc[i]; //5* 4 ou 5 bits suffisent j++; p->nbbit_cf+=5; // 5 bits per coded max #ifdef MAX_SB_ABSOLU sb_count++; quant_0a16_I3(SILENCE_QUANT_LEVEL_16000,SILENCE_QUANT_LEVEL_16000,in+i*16,max[i],codes_sb+2*sb_count); p->nbbit_cf+=SILENCE_CODING_BIT_16000; if (sb_count>=MAX_SB_ABSOLU) break; #endif } } #ifndef MAX_SB_ABSOLU for (i=7;i>=p->nbsb_sp;i--) { j=0; while (order[j]!=i+1) j++; quant_0a16_I3(SILENCE_QUANT_LEVEL_16000,SILENCE_QUANT_LEVEL_16000,in+j*16,max[j],codes_sb+2*i); p->nbbit_cf+=SILENCE_CODING_BIT_16000; } #endif } } //------------------------------------------------------------------------ void code_res_I(PC16008DATA p,short input[],short coef[],short qmf_mem[],short v_code[],long cod_long[], short ind_br[]/*, short c_max_br*/) { decimation_I(input,coef,qmf_mem,Fil_Lenght); quant_sous_bandes(p,input+3*L_RES,v_code,cod_long,ind_br/*AW,&c_max_br*/); } //------------------------------------------------------------------------ short Multiplexing( char *Stream, long *Codes, short *CodeSizes, short NumCodes, short StreamSize) { short B,P; // B=bits … coder, P=bits libres short i,j; #ifdef __CHECK_FORMAT long TotalBytes=0; for (i=0;iStreamSize*8) return 1; #endif i=0; j=0; B=CodeSizes[i]; // bits … coder P=8; // 1 octet libre au d‚part Stream[j]=0; while (iB) { Stream[j]|=(Codes[i]&Mask[B])<<(P-B); P-=B; i++; B=CodeSizes[i]; } else if (P>(B-P))&Mask[P]; B-=P; P=8; j++; Stream[j]=0; } else { Stream[j]|=Codes[i]&Mask[P]; i++; j++; P=8; B=CodeSizes[i]; Stream[j]=0; } } return 0; } // ------------------------------------------------------------------------ #ifdef CELP4800 void iteration(PC4808DATA p,long *P,short n,short *s) { short i; p->a=0x7fffffffL; for(i=0;i<7 ;i++) { horner(P,p->ttt,&p->a,n,*s); horner(p->ttt,p->TLSP+12,&p->b,(short)(n-1),*s); *s += calcul_s(p->a,p->b); } horner(P,p->ttt,&p->a,n,*s); *(P+n) = 0; long_to_long(p->ttt,P,n); } // ------------------------------------------------------------------------ void ai_to_lsp(PC4808DATA p,long *ai_pq,short *lsp) { short s; short n; ai_to_pq(ai_pq,10); s=0x7fff; p->ptr1 = lsp; for(n=5; n>2; n--) { iteration(p,ai_pq,n,&s); *p->ptr1++ = s; if (lsp[0]<0) lsp[0]=s=32765; iteration(p,ai_pq+6,n,&s); *p->ptr1++ = s; } binome(lsp+6,ai_pq); } // ------------------------------------------------------------------------ void cal_dic1(PC4808DATA p,short *y,short *sr,short *espopt,short *posit,short dec,short esp, short *sigpi,short soulong,long *tlsp,long *vmax) { short i,k,limite; long *vene; vene = (long *)(sigpi+150); venergy(y,vene,soulong); k=soulong-1; for (i=0;iptr1 = sr;limite=i; *tlsp = *(p->ptr1+limite); limite += esp; while (limiteptr1+limite); limite += esp;} *(tlsp+1) = *(vene+k-i); limite=upd_max_d(tlsp,vmax); if (limite) {*posit=i; *espopt=esp; *posit=i; *espopt=esp;} } } // ------------------------------------------------------------------------ void cal_dic2(PC4808DATA p,short q,short espace,short phase,short *s_r,short *hy, short *b,short *vois,short *esp,short *qq,short *phas) { short i,j,i0,k; short src[10],*y2; short cc[10]; long R11; y2 = p->SIGPI+75; R11 = 0; init_zero(y2,p->SOULONG); for (j=0;j0) cc[j]=1; else cc[j]=-1; for (i=0;i0) { add_sf_vect(y2,hy,i0,p->SOULONG); } else { sub_sf_vect(y2,hy,i0,p->SOULONG); } } energy2(y2,p->TLSP+1,p->SOULONG); *p->TLSP=R11; i = upd_max_d(p->TLSP,p->VMAX); if (i) { short_to_short(cc,b,q); *vois=0; *esp=espace; *qq=q; *phas=phase; } /* for (i=0;i0) { cc[j]=1; R11 += (long)(src[j]); add_sf_vect(y2,hy,i0,SOULONG); } else { cc[j]=-1; R11 -= (long)(src[j]); sub_sf_vect(y2,hy,i0,SOULONG); } } energy2(y2,TLSP+1,SOULONG); *TLSP=R11; i = upd_max_d(TLSP,VMAX); if (i) { short_to_short(cc,b,q); *vois=0; *esp=espace; *qq=q; *phas=phase; } i0=phase-espace; for (i=0;iTLSP+2,lng); correlation(vech+debut-i,vech+debut,p->TLSP,lng); norm_corrl(vv,p->TLSP); for (i=pitch-delta+1;i<=pitch+delta;i++) { correlation(vech+debut-i,vech+debut,p->TLSP,lng); p->TLSP[10] = (long)vech[debut-i]*(long)vech[debut-i]; p->TLSP[11] = (long)vech[fin-i+1]*(long)vech[fin-i+1]; upd_ene(p->TLSP+2,p->TLSP+10); k=i-pitch+delta; norm_corrl(vv+2*k,p->TLSP); } } // ------------------------------------------------------------------------ void right_correl(PC4808DATA p,short vech[],short debut,short fin,short pitch,short delta,long *vv) { short i,k,lng; lng=fin-debut+1; i=pitch-delta; energy(vech+debut+i,p->TLSP+2,lng); correlation(vech+debut+i,vech+debut,p->TLSP,lng); norm_corrr(vv,p->TLSP); for (i=pitch-delta+1;i<=pitch+delta;i++) { correlation(vech+debut+i,vech+debut,p->TLSP,lng); p->TLSP[11]=(long)vech[debut+i-1]*(long)vech[debut+i-1]; p->TLSP[10]=(long)vech[fin+i]*(long)vech[fin+i]; upd_ene(p->TLSP+2,p->TLSP+10); k=i-pitch+delta; norm_corrr(vv+2*k,p->TLSP); } } // ------------------------------------------------------------------------ void COEFF_A(PC4808DATA p) { fenetre(p->SIG+SOUDECAL1-RECS2,hamming,p->SIGPI,NECHFEN); autocor(p->SIGPI,p->TLSP,NECHFEN,NETAGES); // TLSP[0]=ldiv(TLSP[0]*1001L,1000L); if (*p->TLSP) { schur(p->LSP,p->TLSP,NETAGES); ki_to_ai(p->LSP,p->TLSP,NETAGES); ai_to_lsp(p,p->TLSP,p->LSP); cos_to_teta(tabcos,p->LSP,10); } else short_to_short(p->LSP0,p->LSP,10); lsp_quant(p,p->LSP,NBB,BITDD,p->code); short_to_short(p->LSP,p->A3,10); teta_to_cos(tabcos,p->A3,10); lsp_to_ai(p->A3,p->TLSP,10); interpol(p->LSP0,p->LSP,p->A1,NETAGES); teta_to_cos(tabcos,p->A1,10); lsp_to_ai(p->A1,p->TLSP,10); interpol(p->LSP,p->LSP0,p->A2,NETAGES); teta_to_cos(tabcos,p->A2,10); lsp_to_ai(p->A2,p->TLSP,10); short_to_short(p->LSP,p->LSP0,NETAGES); } // ------------------------------------------------------------------------ void lsp_quant(PC4808DATA p,short lsp[],short nbit[],short bitdi[],short vcode[]) { short i,iopt,k,nombi,m,m1,k2; short *delta,*lsptab,dmin,tmp,demi; delta = p->E; lsptab = LSP_Q; m1 = NETAGES/2; for (i=0;itmp) if (delta[i]>1; for (i=0;i>16); for (i=0;i>16); dmin=32767; for (i=0;i>1; for (i=0;i>16); dmin=32767; for (i=0;iA2,p->A1,11); i0=SOUDECAL1; break; case 2: short_to_short(p->A3,p->A1,11); i0=SOUDECAL1+SOUDECAL; break; } f_inverse(p->MINV,p->A1,p->SIG+i0,p->E,p->SOULONG,NETAGES); } // ------------------------------------------------------------------------ void PERIODE(PC4808DATA p,short no) { short i,P1,P2; short *y0,*y1,*y2; short MAX,MAX2,j,bit_garde; y0=p->SIGPI; y2=y0+75; y1=p->E_PE; fenetre(p->A1,A0,p->Aw,11); init_zero(p->zz,12); p->H[0]=4096; init_zero(p->H+1,(short)(p->SOULONG-1)); synthesis(p->zz,p->Aw,p->H,p->H,35,NETAGES,0); if (no) { P1=p->PITCH-3; if (P1PITCH+4; if (P2>LIM_P2) P2=LIM_P2; } else { P1=p->PITCH-5; if (P1PITCH+5; if (P2>LIM_P2) P2=LIM_P2; } // calc_p(&P1,&P2,PITCH,LIM_P1,LIM_P2,no); MAX = max_vect(p->E,p->SOULONG); if (P2SOULONG) MAX2 = max_vect(p->EE+lngEE-P2,P2); else { if (P1SOULONG) j=P1+16; else j=p->SOULONG+16; MAX2 = max_vect(p->EE+lngEE-P2,j); } if (MAX2>MAX) MAX=MAX2; if (MAX & 0xe000) { i=MAX >> 13; if (!(i>>1)) bit_garde=1; else bit_garde=2; } else bit_garde=0; init_zero(p->zz,12); synthesis(p->zz,p->Aw,p->E,y1,p->SOULONG,NETAGES,bit_garde); if (P1SOULONG) { short_to_short(p->EE+lngEE-P1,y0,P1); for (i=P1;iSOULONG;i++) y0[i]=0; } else short_to_short(p->EE+lngEE-P1,y0,p->SOULONG); init_zero(p->zz,12); synthesis(p->zz,p->Aw,y0,y0,p->SOULONG,NETAGES,bit_garde); short_to_short(y0,y2,p->SOULONG); if (P1SOULONG) add_sf_vect(y2,y0,P1,p->SOULONG); if (2*P1SOULONG) add_sf_vect(y2,y0,(short)(P1<<1),p->SOULONG); energy(y2,p->TLSP+2,p->SOULONG); correlation(y1,y2,p->TLSP,p->SOULONG); p->VMAX[1]=-6969; p->VMAX[4]=P1; upd_max(p->TLSP,p->VMAX,P1); for (i=P1+1;i<=P2;i++) { p->ptr1=y0; y0=y2; y2=p->ptr1; update_ltp(y0,y2,p->H+1,p->SOULONG,bit_garde,p->EE[lngEE-i]); if (iSOULONG) { short_to_short(y0,y2,p->SOULONG); add_sf_vect(y2,y0,i,p->SOULONG); if (2*iSOULONG) add_sf_vect(y2,y0,(short)(i<<1),p->SOULONG); energy(y2,p->TLSP+2,p->SOULONG); correlation(y1,y2,p->TLSP,p->SOULONG); } else { energy(y0,p->TLSP+2,p->SOULONG); correlation(y1,y0,p->TLSP,p->SOULONG); } upd_max(p->TLSP,p->VMAX,i); } #if 0 //*(p->VMAX+2) = 28265821L; //*(p->VMAX+3) = 61L; //*(p->VMAX+2) = 881427L; //*(p->VMAX+3) = 1L; //*(p->VMAX+2) = 9851363L; //*(p->VMAX+3) = 6L; //*(p->VMAX+2) = 812881L; //*(p->VMAX+3) = 2L; #if 1 // Save jmp if ((*(p->VMAX+2) < 0L) || (*(p->VMAX+3) == 0L) || (((long)((long)(*(p->VMAX+2))/(long)(*(p->VMAX+3))) & 0xFFFC0000) == 0L)) proc_gain(p->VMAX+2,p->ttt); else *(p->ttt) = 0L; // *(p->VMAX+3) = 0L; #else if ((*(p->VMAX+2) > 0L) && (*(p->VMAX+3)) && ((long)((long)(*(p->VMAX+2))/(long)(*(p->VMAX+3))) & 0x0FFC0000)) { *(p->ttt) = 0L; // *(p->VMAX+3) = 0L; } else proc_gain(p->VMAX+2,p->ttt); #endif #else //*(p->VMAX+2) = 28265821L; //*(p->VMAX+3) = 61L; //*(p->VMAX+2) = 881427L; //*(p->VMAX+3) = 1L; //*(p->VMAX+2) = 9851363L; //*(p->VMAX+3) = 6L; //*(p->VMAX+2) = 812881L; //*(p->VMAX+3) = 2L; proc_gain(p->VMAX+2,p->ttt); #endif p->PITCH=(short)p->VMAX[4]; /* if (ttt[0]>32767) GLTP=32767; else if (ttt[0]<-32767) GLTP=-32767; else GLTP=ttt[0]; m = abs(GLTP); for (i=1;i<=10;i++) if ((m>=BQ[i-1])&&(m0) { GLTP=BV[i] ; k=i-1; } else { GLTP=-BV[i]; k=i+10-1; } break; } if (GLTP>=BQ[10]) { GLTP=BV[10]; k=9; } if (GLTP<-BQ[6]) { GLTP=-BV[6]; k=15 ; } */ p->code[11+p->depl]=calc_gltp(&p->GLTP,BQ,BV,p->ttt[0]);; p->code[10+p->depl]=p->PITCH; if (p->PITCHSOULONG) { short_to_short(p->EE+lngEE-p->PITCH,p->E_PE,p->PITCH); short_to_short(p->E_PE,p->E_PE+p->PITCH,(short)(p->SOULONG-p->PITCH)); mult_fact(p->E_PE,p->E_PE,p->GLTP,p->SOULONG); } else { mult_fact(p->EE+lngEE-p->PITCH,p->E_PE,p->GLTP,p->SOULONG); } } // ------------------------------------------------------------------------ void CHERCHE(PC4808DATA p) { short i; short position,esp_opt; short k,j; short c[10],VOISE,npopt,phas_opt,cod,sign; short Gopt; short *sr,*y0; short MAX,bit_garde; sr=p->SIGPI; y0=sr+75; for (i=0;iSOULONG;i++) p->E[i] -= p->E_PE[i]; init_zero(p->zz,12); synthesis(p->zz,p->Aw,p->E,sr,p->SOULONG,NETAGES,0); MAX = max_vect(sr,p->SOULONG); /* if (MAX & 0xfe00) { i=MAX >> 9; if (!(i>>1)) bit_garde=1; else if (!(i>>2)) bit_garde=2; else if (!(i>>3)) bit_garde=3; else if (!(i>>4)) bit_garde=4; else if (!(i>>5)) bit_garde=5; else bit_garde=6; } else bit_garde=0; */ bit_garde=calc_garde(MAX); inver_v_int(sr,y0,p->SOULONG); init_zero(p->zz,12); synthesis(p->zz,p->Aw,y0,y0,p->SOULONG,NETAGES,bit_garde); inver_v_int(y0,sr,p->SOULONG); p->VMAX[0]=-6969; Gopt=position=0; VOISE=1; if ( !p->UNVOIS ) { esp_opt=p->PITCH; short_to_short(p->H,y0,p->SOULONG); if (p->PITCHSOULONG) add_sf_vect(y0,p->H,p->PITCH,p->SOULONG); // cal_dic1(y0,sr,&esp_opt,&position,SOULONG,PITCH); cal_dic1(p,y0,sr,&esp_opt,&position,p->SOULONG,p->PITCH,p->SIGPI,p->SOULONG,p->TLSP,p->VMAX); /* if (PITCH>=SOULONG) { if (PITCH/2H,c,&VOISE,&esp_opt,&npopt,&phas_opt); cal_dic2(p,7,8,3,sr,p->H,c,&VOISE,&esp_opt,&npopt,&phas_opt); /* cal_dic2(8,7,0,sr,H,c,&VOISE,&esp_opt,&npopt,&phas_opt,SIGPI,SOULONG,TLSP,VMAX); cal_dic2(7,8,3,sr,H,c,&VOISE,&esp_opt,&npopt,&phas_opt,SIGPI,SOULONG,TLSP,VMAX); */ proc_gain2(p->VMAX+1,p->VMAX,bit_garde); if (p->VMAX[0]>32767) Gopt=32767; else if (p->VMAX[0]<-32767) Gopt=-32767; else Gopt=(short)p->VMAX[0]; if (VOISE==0) { if (c[0]==-1) { Gopt=-Gopt; for (k=0;kPITCH) cod=position; else cod = position+SOUDECAL1; } p->code[12+p->depl]=cod; if (Gopt<0) { Gopt=-Gopt; sign=1; } else sign=0; for (i=1;i<=16;i++) if ((Gopt>=GQ[i-1])&&(Gopt=GQ[16]) { Gopt=GV[16]; cod=15; } if (sign) { Gopt = -Gopt; cod += 16; } p->code[13+p->depl]=cod; // Gopt=calc_gopt(c,code,GQ,GV,VOISE,npopt,PITCH,esp_opt,depl,position,SOUDECAL1,VMAX[0]); short_to_short(p->E_PE,p->E,p->SOULONG); if (VOISE==1) { i=0; do { p->E[position+i] += Gopt; i += esp_opt; } while ((position+i)SOULONG); } else for (j=0;jE[esp_opt*j+phas_opt] += c[j]*Gopt; short_to_short(p->EE+p->SOULONG,p->EE,(short)(lngEE-p->SOULONG)); short_to_short(p->E,p->EE+lngEE-p->SOULONG,p->SOULONG); } // ------------------------------------------------------------------------ void FRAME(PC4808DATA p) // Purpose : concatenate all parameters // Input parameter : // code[] : parameters code // Output parameter : // output_stream[] : multiplexed code // // Comments: The LTP or Adaptive codebook is also called PITCH. // // Bit allocation : Codebook or gain "i" is the codebook for suboutput_stream "i". // code[0] = LSP(0) : 3bits code[10] = LTP codebook 1 : 7bits // code[1] = LSP(1) : 4bits code[11] = LTP gain 1 : 4bits // code[2] = LSP(2) : 4bits code[12] = Binary codebook 1 : 8bits // code[3] = LSP(3) : 3bits code[13] = Binary gain 1 : 5bits // code[4] = LSP(4) : 4bits code[14] = LTP codebook 2 : 4bits // code[5] = LSP(5) : 3bits code[15] = LTP gain 2 : 4bits // code[6] = LSP(6) : 3bits code[16] = Binary codebook 2 : 8bits // code[7] = LSP(7) : 2bits code[17] = Binary gain 2 : 5bits // code[8] = LSP(8) : 3bits code[18] = LTP codebook 3 : 4bits // code[9] = LSP(9) : 1bits code[19] = LTP gain 3 : 4bits // code[20] = Binary codebook 3 : 8bits // code[21] = Binary gain 3 : 5bits // // output_stream[0] = LSP[0] | LSP[1] | LSP[2] | (Binary gain 2) // output_stream[1] = LSP[3] | (Binary gain 3) | (Binary codebook 1) // output_stream[2] = LSP[4] | LSP[5] | LSP[6] | LSP[7] | LSP[8] | LSP[9] // output_stream[3] = (LTP codebook 1) | (LTP gain 1) | (Binary gain 1) // output_stream[4] = (LTP codebook 2) | (LTP gain 2) | (Binary codebook 2) // output_stream[5] = (LTP codebook 3) | (LTP gain 3) | (Binary codebook 3) { p->code[18] = p->code[18]-p->code[14]+7; p->code[14] = p->code[14]-p->code[10]+7; p->code[10] -= LIM_P1; p->output_frame[0] = (p->code[0]<<13) | (p->code[1]<<9) | (p->code[2]<<5) | p->code[17]; p->output_frame[1] = (p->code[3]<<13) | (p->code[21]<<8) | p->code[12]; p->output_frame[2] = (p->code[4]<<12) | (p->code[5]<<9) | (p->code[6]<<6) | (p->code[7]<<4) | (p->code[8]<<1) | p->code[9]; p->output_frame[3] = (p->code[10]<<9) | (p->code[11]<<5) | p->code[13]; p->output_frame[4] = (p->code[14]<<12) | (p->code[15]<<8) | p->code[16]; p->output_frame[5] = (p->code[18]<<12) | (p->code[19]<<8) | p->code[20]; /* code[18] = code[18]-code[14]+3; code[14] = code[14]-code[10]+3; code[10] -= LIM_P1; output_frame[0] = (code[0]<<13) | (code[1]<<9) | code[12]; output_frame[1] = (code[3]<<13) | (code[2]<<9) | code[16]; output_frame[2] = (code[5]<<13) | (code[4]<<9) | code[20]; output_frame[3] = (code[10]<<9) | (code[6]<<6) | (code[14]<<3) | code[18]; output_frame[4] = (code[11]<<12) | (code[15]<<8) | (code[19]<<4) | (code[7]<<2) | code[8]; output_frame[5] = (code[13]<<11) | (code[17]<<6) | (code[21]<<1) | code[9]; */ } // ------------------------------------------------------------------------ void CALPITCH(PC4808DATA p) { short P1,P2,P3,j0,j1,L; /* long GG; GG=0; for (j=0;jialf=0; deacc(p->M_PIT,p->SIGPI+10,29491,150,&p->ialf); deacc(p->SIG+SOUDECAL1-RECS2,p->SIGPI+160,29491,211,&p->ialf); j0=(L-80)/2; j1=j0+80; /* filt_iir(memfil_calp,coef_calp,SIGPI+10,SIG_CALP,361,3); // filtrage for (j=0;j<90;j++) SIG_CALP[j]=SIG_CALP[4*j]; //d‚cimation par 4 */ //// decime(SIGPI+10,SIG_CALP,coef_calp,Zai,Zbi,361); decimation(p->SIGPI+10,p->SIG_CALP,90); P1=max_autoc(p->SIG_CALP+40,28,5,14)*4; P2=max_autoc(p->SIG_CALP+20,56,13,28)*4; /* P1=max_autoc(SIGPI+160,130,LIM_P1,LIM_P1+35); P2=max_autoc(SIGPI+160-80,280,LIM_P1+30,LIM_P2); */ P3=P2/2; p->ialf=P2/3; if ( (p->ialf>p->mem_pit[0]-17)&&(p->ialfmem_pit[0]+17) && (abs(p->mem_pit[0]-p->ialf)mem_pit[0]-P3))) P3=p->ialf; left_correl(p,p->SIGPI,j0,j1,P1,2,p->veci1); left_correl(p,p->SIGPI,j0,j1,P2,2,p->veci2); left_correl(p,p->SIGPI,j0,j1,P3,2,p->veci3); right_correl(p,p->SIGPI,j0,j1,P1,2,p->veci1); right_correl(p,p->SIGPI,j0,j1,P2,2,p->veci2); right_correl(p,p->SIGPI,j0,j1,P3,2,p->veci3); P1=max_posit(p->veci1,p->TLSP,P1,5); P2=max_posit(p->veci2,p->TLSP+2,P2,5); P3=max_posit(p->veci3,p->TLSP+4,P3,5); if (p->TLSP[1]>p->TLSP[3]) p->PITCH =P1; else if ((p->TLSP[1]==p->TLSP[3]) && (p->TLSP[0]>p->TLSP[2])) p->PITCH=P1; else { p->PITCH=P2; p->TLSP[0]=p->TLSP[2]; p->TLSP[1]=p->TLSP[3];} if ( (P3>p->mem_pit[0]-17) && (P3mem_pit[0]+17)) { if (abs(p->mem_pit[1]-p->mem_pit[0])<15) p->TLSP[0] = p->TLSP[0]>>1 + p->TLSP[0]>>2; if (abs(P3-P1)>6) p->TLSP[0] = p->TLSP[0]>>1 + p->TLSP[0]>>2; if (p->TLSP[0]<0x40000000L) { p->TLSP[0]<<=1; p->TLSP[1]--;} // if (TLSP[0]<0x40000000) { TLSP[0]<<=1; TLSP[1]--;} if (p->TLSP[1]TLSP[5]) p->PITCH =P3; else if ((p->TLSP[1]==p->TLSP[5]) && (p->TLSP[0]TLSP[4])) p->PITCH=P3; } p->mem_pit[1]=p->mem_pit[0]; p->mem_pit[0]=p->PITCH; } #endif // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ // DLL entry points // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ LH_PREFIX HANDLE LH_SUFFIX MSLHSB_Open_Coder(DWORD dwMaxBitRate) { PVOID pCoderData; /*short i,flag=0; // Test if there are free handles for (i=0;idwMaxBitRate != 4800) && #endif (((PC16008DATA)pCoderData)->dwMaxBitRate != 8000) && (((PC16008DATA)pCoderData)->dwMaxBitRate != 12000) && (((PC16008DATA)pCoderData)->dwMaxBitRate != 16000)) return (LH_ERRCODE)LH_EBADARG; #ifdef CELP4800 if ((((PC4808DATA)pCoderData)->dwMaxBitRate == 4800)) { // then check the buffer sizes passed as argument. if ((*lpSrcBufSize<2*NECHDECAL)||(*lpDstBufSize<12)) return (LH_ERRCODE)LH_EBADARG; *lpSrcBufSize=2*NECHDECAL; *lpDstBufSize=12; input = (short *)lpSrcBuf; in=((PC4808DATA)pCoderData)->SIG+SOUDECAL1+RECS2; for (i=0;imem2,((PC4808DATA)pCoderData)->SIG+SOUDECAL1+RECS2,((PC4808DATA)pCoderData)->SIG+SOUDECAL1+RECS2,DECAL); CALPITCH(((PC4808DATA)pCoderData)); COEFF_A(((PC4808DATA)pCoderData)); for (i=0;i<3;i++) { if (i==0) ((PC4808DATA)pCoderData)->SOULONG=SOUDECAL1; else ((PC4808DATA)pCoderData)->SOULONG=SOUDECAL; ((PC4808DATA)pCoderData)->depl=i*4; RESIDU(((PC4808DATA)pCoderData),i); PERIODE(((PC4808DATA)pCoderData),i); CHERCHE(((PC4808DATA)pCoderData)); dsynthesis(((PC4808DATA)pCoderData)->DMSY,((PC4808DATA)pCoderData)->A1,((PC4808DATA)pCoderData)->E,((PC4808DATA)pCoderData)->E_PE,((PC4808DATA)pCoderData)->SOULONG,NETAGES); for (k=0;k<=11;k++) ((PC4808DATA)pCoderData)->MINV[12-k] = ((PC4808DATA)pCoderData)->E_PE[((PC4808DATA)pCoderData)->SOULONG-12+k]; ((PC4808DATA)pCoderData)->MINV[0]=(short)(((PC4808DATA)pCoderData)->DMSY[0] >> 16); } FRAME(((PC4808DATA)pCoderData)); short_to_short(((PC4808DATA)pCoderData)->SIG+SOUDECAL1-RECS2,((PC4808DATA)pCoderData)->M_PIT,160); short_to_short(((PC4808DATA)pCoderData)->SIG+NECHDECAL,((PC4808DATA)pCoderData)->SIG,SOUDECAL1+RECS2); ptr4 = (unsigned short *)&((PC4808DATA)pCoderData)->output_frame; ptr2 = (unsigned short *)lpDstBuf; for (i =0;i<6;i++) ptr2[i] = ptr4[i]; } else #endif { input = (short *)lpSrcBuf; ((PC16008DATA)pCoderData)->nbbit_cf=0; // then check the buffer sizes passed as argument. switch (((PC16008DATA)pCoderData)->dwMaxBitRate) { case 8000: if ((*lpSrcBufSize<2*160)||(*lpDstBufSizeDATA_I[i]=(*input++)>>1; // TEST >>2 #ifdef _X86_ PassLow8(((PC16008DATA)pCoderData)->DATA_I,ivect8,((PC16008DATA)pCoderData)->memBP,160); iConvert8To64(ivect8,((PC16008DATA)pCoderData)->DATA_I,160,((PC16008DATA)pCoderData)->imem1); #else SampleRate8000To6400(((PC16008DATA)pCoderData)->DATA_I, ((PC16008DATA)pCoderData)->DATA_I, 160, ((PC16008DATA)pCoderData)->imem1, &((PC16008DATA)pCoderData)->uiDelayPosition, &((PC16008DATA)pCoderData)->iInputStreamTime, &((PC16008DATA)pCoderData)->iOutputStreamTime ); #endif break; case 12000: if ((*lpSrcBufSize<2*128)||(*lpDstBufSizeDATA_I[i]=(*input++)>>1; // TEST >>2 break; case 16000: if ((*lpSrcBufSize<2*128)||(*lpDstBufSizeDATA_I[i]=(*input++)>>1; // TEST >>2 break; } code_res_I(((PC16008DATA)pCoderData),((PC16008DATA)pCoderData)->DATA_I,coef_I,((PC16008DATA)pCoderData)->QMF_MEM_ANAL_I,((PC16008DATA)pCoderData)->codes_max, ((PC16008DATA)pCoderData)->codes_sb,((PC16008DATA)pCoderData)->indic_sp); //*#ifdef __VARIABLE__ for (i=NBFAC-1;i>0;i--) { ((PC16008DATA)pCoderData)->nbbit[i]=((PC16008DATA)pCoderData)->nbbit[i-1]; // on re-adapte les tranches precedentes } ((PC16008DATA)pCoderData)->nbbit[0]=((PC16008DATA)pCoderData)->nbbit_cf; // valeur pour la tranche actuelle nbb_ave=0L; for (i=0;inbbit[i]; if (((PC16008DATA)pCoderData)->dwMaxBitRate == 8000) { iNBSPF = NBSPF_4800_8000; iMOD_TH1 = MOD_TH1_8000; iMOD_TH2 = MOD_TH2_8000; iMOD_TH3 = MOD_TH3_8000; iNBSB_SP_MAX1 = NBSB_SP_MAX1_8000_12000; iNBSB_SP_MAX2 = NBSB_SP_MAX2_8000_12000; iNBSB_SP_MAX3 = NBSB_SP_MAX3_8000_12000; iNBSB_SP_MAX4 = NBSB_SP_MAX4_8000_12000; } else { iNBSPF = NBSPF_12000_16000; iMOD_TH1 = MOD_TH1_12000_16000; if (((PC16008DATA)pCoderData)->dwMaxBitRate == 12000) { iMOD_TH2 = MOD_TH2_12000; iMOD_TH3 = MOD_TH3_12000; iNBSB_SP_MAX1 = NBSB_SP_MAX1_8000_12000; iNBSB_SP_MAX2 = NBSB_SP_MAX2_8000_12000; iNBSB_SP_MAX3 = NBSB_SP_MAX3_8000_12000; iNBSB_SP_MAX4 = NBSB_SP_MAX4_8000_12000; } else { iMOD_TH2 = MOD_TH2_16000; iMOD_TH3 = MOD_TH3_16000; iNBSB_SP_MAX1 = NBSB_SP_MAX1_16000; iNBSB_SP_MAX2 = NBSB_SP_MAX2_16000; iNBSB_SP_MAX3 = NBSB_SP_MAX3_16000; iNBSB_SP_MAX4 = NBSB_SP_MAX4_16000; } } nbb_ave=(short)((nbb_ave*F_ECH)/(NBFAC*iNBSPF)); // On retablit les seuils en fonction de la moyenne calculee if (nbb_ave<=iMOD_TH1) { ((PC16008DATA)pCoderData)->MAX_LEVEL = MAX_LEVEL1; // valeur par defaut si le debit n'augmente pas trop ((PC16008DATA)pCoderData)->DIV_MAX = DIV_MAX1; // cad on ne traite pas les sb < 5% du max[i] ((PC16008DATA)pCoderData)->NBSB_SP_MAX = iNBSB_SP_MAX1; // nbre max de sb pouvant etre du signal } else { if (nbb_ave<=iMOD_TH2) // on a depasse le 1er seuils mais pas le 2eme { ((PC16008DATA)pCoderData)->MAX_LEVEL = MAX_LEVEL2; // on rejette plus de tranches ((PC16008DATA)pCoderData)->DIV_MAX = DIV_MAX2; // cad on ne traite pas les sb < 7% du max[i] ((PC16008DATA)pCoderData)->NBSB_SP_MAX = iNBSB_SP_MAX2; // nbre max de sb pouvant etre du signal } else { if (nbb_ave<=iMOD_TH3) // on a depasse le 1er seuils mais pas le 2eme { ((PC16008DATA)pCoderData)->MAX_LEVEL = MAX_LEVEL3; // on rejette un max ((PC16008DATA)pCoderData)->DIV_MAX = DIV_MAX3; // cad on ne traite pas les sb < 5% du max[i] ((PC16008DATA)pCoderData)->NBSB_SP_MAX = iNBSB_SP_MAX3; // nbre max de sb pouvant etre du signal } else // on a depasse le troisieme seuil; il faut descendre! { ((PC16008DATA)pCoderData)->MAX_LEVEL = MAX_LEVEL4; // meme seuil de rejet ((PC16008DATA)pCoderData)->DIV_MAX = DIV_MAX4; // cad on ne traite pas les sb <10% du max[i] ((PC16008DATA)pCoderData)->NBSB_SP_MAX = iNBSB_SP_MAX4; // nbre max de sb pouvant etre du signal } } }/**/ ((PC16008DATA)pCoderData)->stream[0]=0; for (i=0;i<8;i++) ((PC16008DATA)pCoderData)->stream[0]|=(((PC16008DATA)pCoderData)->indic_sp[i]&0x01)<nbsb_sp]; #if 0 temp=(short)((float)((PC16008DATA)pCoderData)->nbbit_cf/8.0+0.99); #else // We want to go away of libcmt, msvcrt... and // floating point is not really essential here... if (((PC16008DATA)pCoderData)->nbbit_cf) temp=(short)((((PC16008DATA)pCoderData)->nbbit_cf-1)/8+1); else temp=0; #endif for (i=0;i<24;i++) codesizes[i]=0; for (i=0;i<((PC16008DATA)pCoderData)->nbsb_sp;i++) { codes[i]=(long)((PC16008DATA)pCoderData)->codes_max[i]; codes[((PC16008DATA)pCoderData)->nbsb_sp+2*i]=(long)((PC16008DATA)pCoderData)->codes_sb[2*i]; codes[((PC16008DATA)pCoderData)->nbsb_sp+2*i+1]=(long)((PC16008DATA)pCoderData)->codes_sb[2*i+1]; codesizes[i]=5; codesizes[((PC16008DATA)pCoderData)->nbsb_sp+2*i]=((PC16008DATA)pCoderData)->bits[i]/2; codesizes[((PC16008DATA)pCoderData)->nbsb_sp+2*i+1]=((PC16008DATA)pCoderData)->bits[i]/2; numcodes+=3; } if (((PC16008DATA)pCoderData)->dwMaxBitRate == 16000) { for (i=((PC16008DATA)pCoderData)->nbsb_sp;i<8;i++) { codes[2*((PC16008DATA)pCoderData)->nbsb_sp+i]=(long)((PC16008DATA)pCoderData)->codes_max[i]; codes[8+2*i]=(long)((PC16008DATA)pCoderData)->codes_sb[2*i]; codes[8+2*i+1]=(long)((PC16008DATA)pCoderData)->codes_sb[2*i+1]; codesizes[2*((PC16008DATA)pCoderData)->nbsb_sp+i]=5; codesizes[8+2*i]=SILENCE_CODING_BIT_16000/2; codesizes[8+2*i+1]=SILENCE_CODING_BIT_16000/2; numcodes+=3; } Multiplexing(((PC16008DATA)pCoderData)->stream+1,codes,codesizes,numcodes,(short)(temp-1)); } else if (((PC16008DATA)pCoderData)->nbsb_sp) Multiplexing(((PC16008DATA)pCoderData)->stream+1,codes,codesizes,numcodes,(short)(temp-1)); *lpDstBufSize=temp; ptr3 = (unsigned char *)&((PC16008DATA)pCoderData)->stream; ptr1 = (unsigned char *)lpDstBuf; for (i =0;i<*lpDstBufSize;i++) ptr1[i] = ptr3[i]; } return (LH_SUCCESS); } // ------------------------------------------------------------------------ LH_PREFIX LH_ERRCODE LH_SUFFIX MSLHSB_Close_Coder(HANDLE hAccess) { PVOID pCoderData; /*short i,flag=0; // Check if right handle for (i=0;i