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

📄 mdf.c

📁 基于sip协议的网络电话源码
💻 C
📖 第 1 页 / 共 3 页
字号:
   st->X = (spx_word16_t*)speex_alloc((M+1)*N*sizeof(spx_word16_t));   st->Y = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));   st->E = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));   st->W = (spx_word32_t*)speex_alloc(M*N*sizeof(spx_word32_t));   st->PHI = (spx_word32_t*)speex_alloc(N*sizeof(spx_word32_t));   st->power = (spx_word32_t*)speex_alloc((frame_size+1)*sizeof(spx_word32_t));   st->power_1 = (spx_float_t*)speex_alloc((frame_size+1)*sizeof(spx_float_t));   st->window = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));   st->prop = (spx_word16_t*)speex_alloc(M*sizeof(spx_word16_t));   st->wtmp = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));#ifdef FIXED_POINT   st->wtmp2 = (spx_word16_t*)speex_alloc(N*sizeof(spx_word16_t));   for (i=0;i<N>>1;i++)   {      st->window[i] = (16383-SHL16(spx_cos(DIV32_16(MULT16_16(25736,i<<1),N)),1));      st->window[N-i-1] = st->window[i];   }#else   for (i=0;i<N;i++)      st->window[i] = .5-.5*cos(2*M_PI*i/N);#endif   for (i=0;i<=st->frame_size;i++)      st->power_1[i] = FLOAT_ONE;   for (i=0;i<N*M;i++)      st->W[i] = 0;   {      spx_word32_t sum = 0;      /* Ratio of ~10 between adaptation rate of first and last block */      spx_word16_t decay = SHR32(spx_exp(NEG16(DIV32_16(QCONST16(2.4,11),M))),1);      st->prop[0] = QCONST16(.7, 15);      sum = EXTEND32(st->prop[0]);      for (i=1;i<M;i++)      {         st->prop[i] = MULT16_16_Q15(st->prop[i-1], decay);         sum = ADD32(sum, EXTEND32(st->prop[i]));      }      for (i=M-1;i>=0;i--)      {         st->prop[i] = DIV32(MULT16_16(QCONST16(.8,15), st->prop[i]),sum);      }   }      st->memX=st->memD=st->memE=0;   st->preemph = QCONST16(.9,15);   if (st->sampling_rate<12000)      st->notch_radius = QCONST16(.9, 15);   else if (st->sampling_rate<24000)      st->notch_radius = QCONST16(.982, 15);   else      st->notch_radius = QCONST16(.992, 15);   st->notch_mem[0] = st->notch_mem[1] = 0;   st->adapted = 0;   st->Pey = st->Pyy = FLOAT_ONE;      st->play_buf = (spx_int16_t*)speex_alloc((PLAYBACK_DELAY+1)*st->frame_size*sizeof(spx_int16_t));   st->play_buf_pos = PLAYBACK_DELAY*st->frame_size;   st->play_buf_started = 0;      return st;}/** Resets echo canceller state */void speex_echo_state_reset(SpeexEchoState *st){   int i, M, N;   st->cancel_count=0;   st->screwed_up = 0;   N = st->window_size;   M = st->M;   for (i=0;i<N*M;i++)      st->W[i] = 0;   for (i=0;i<N*(M+1);i++)      st->X[i] = 0;   for (i=0;i<=st->frame_size;i++)   {      st->power[i] = 0;      st->power_1[i] = FLOAT_ONE;      st->Eh[i] = 0;      st->Yh[i] = 0;   }   for (i=0;i<st->frame_size;i++)   {      st->last_y[i] = 0;   }   for (i=0;i<N;i++)   {      st->E[i] = 0;      st->x[i] = 0;   }   st->notch_mem[0] = st->notch_mem[1] = 0;   st->memX=st->memD=st->memE=0;   st->saturated = 0;   st->adapted = 0;   st->sum_adapt = 0;   st->Pey = st->Pyy = FLOAT_ONE;   for (i=0;i<3*st->frame_size;i++)      st->play_buf[i] = 0;   st->play_buf_pos = PLAYBACK_DELAY*st->frame_size;   st->play_buf_started = 0;}/** Destroys an echo canceller state */void speex_echo_state_destroy(SpeexEchoState *st){   spx_fft_destroy(st->fft_table);   speex_free(st->e);   speex_free(st->x);   speex_free(st->input);   speex_free(st->y);   speex_free(st->last_y);   speex_free(st->Yf);   speex_free(st->Rf);   speex_free(st->Xf);   speex_free(st->Yh);   speex_free(st->Eh);   speex_free(st->X);   speex_free(st->Y);   speex_free(st->E);   speex_free(st->W);   speex_free(st->PHI);   speex_free(st->power);   speex_free(st->power_1);   speex_free(st->window);   speex_free(st->prop);   speex_free(st->wtmp);#ifdef FIXED_POINT   speex_free(st->wtmp2);#endif   speex_free(st->play_buf);   speex_free(st);}void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out){   int i;   /*speex_warning_int("capture with fill level ", st->play_buf_pos/st->frame_size);*/   st->play_buf_started = 1;   if (st->play_buf_pos>=st->frame_size)   {      speex_echo_cancellation(st, rec, st->play_buf, out);      st->play_buf_pos -= st->frame_size;      for (i=0;i<st->play_buf_pos;i++)         st->play_buf[i] = st->play_buf[i+st->frame_size];   } else {      speex_warning("No playback frame available (your application is buggy and/or got xruns)");      if (st->play_buf_pos!=0)      {         speex_warning("internal playback buffer corruption?");         st->play_buf_pos = 0;      }      for (i=0;i<st->frame_size;i++)         out[i] = rec[i];   }}void speex_echo_playback(SpeexEchoState *st, const spx_int16_t *play){   /*speex_warning_int("playback with fill level ", st->play_buf_pos/st->frame_size);*/   if (!st->play_buf_started)   {      speex_warning("discarded first playback frame");      return;   }   if (st->play_buf_pos<=PLAYBACK_DELAY*st->frame_size)   {      int i;      for (i=0;i<st->frame_size;i++)         st->play_buf[st->play_buf_pos+i] = play[i];      st->play_buf_pos += st->frame_size;      if (st->play_buf_pos <= (PLAYBACK_DELAY-1)*st->frame_size)      {         speex_warning("Auto-filling the buffer (your application is buggy and/or got xruns)");         for (i=0;i<st->frame_size;i++)            st->play_buf[st->play_buf_pos+i] = play[i];         st->play_buf_pos += st->frame_size;      }   } else {      speex_warning("Had to discard a playback frame (your application is buggy and/or got xruns)");   }}/** Performs echo cancellation on a frame */void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out, spx_int32_t *Yout){   speex_echo_cancellation(st, in, far_end, out);}/** Performs echo cancellation on a frame (deprecated, last arg now ignored) */void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out){   int i,j;   int N,M;   spx_word32_t Syy,See,Sxx,Sdd;   spx_word32_t Sey;   spx_word16_t ss, ss_1;   spx_float_t Pey = FLOAT_ONE, Pyy=FLOAT_ONE;   spx_float_t alpha, alpha_1;   spx_word16_t RER;   spx_word32_t tmp32;      N = st->window_size;   M = st->M;   st->cancel_count++;#ifdef FIXED_POINT   ss=DIV32_16(11469,M);   ss_1 = SUB16(32767,ss);#else   ss=.35/M;   ss_1 = 1-ss;#endif   filter_dc_notch16(in, st->notch_radius, st->input, st->frame_size, st->notch_mem);   /* Copy input data to buffer and apply pre-emphasis */   for (i=0;i<st->frame_size;i++)   {      spx_word32_t tmp32;      st->x[i] = st->x[i+st->frame_size];      tmp32 = SUB32(EXTEND32(far_end[i]), EXTEND32(MULT16_16_P15(st->preemph, st->memX)));#ifdef FIXED_POINT      /* If saturation occurs here, we need to freeze adaptation for M+1 frames (not just one) */      if (tmp32 > 32767)      {         tmp32 = 32767;         st->saturated = M+1;      }      if (tmp32 < -32767)      {         tmp32 = -32767;         st->saturated = M+1;      }      #endif      st->x[i+st->frame_size] = EXTRACT16(tmp32);      st->memX = far_end[i];            tmp32 = SUB32(EXTEND32(st->input[i]), EXTEND32(MULT16_16_P15(st->preemph, st->memD)));#ifdef FIXED_POINT      if (tmp32 > 32767)      {         tmp32 = 32767;         if (st->saturated == 0)            st->saturated = 1;      }            if (tmp32 < -32767)      {         tmp32 = -32767;         if (st->saturated == 0)            st->saturated = 1;      }#endif      st->memD = st->input[i];      st->input[i] = tmp32;   }   /* Shift memory: this could be optimized eventually*/   for (j=M-1;j>=0;j--)   {      for (i=0;i<N;i++)         st->X[(j+1)*N+i] = st->X[j*N+i];   }   /* Convert x (far end) to frequency domain */   spx_fft(st->fft_table, st->x, &st->X[0]);   #ifdef SMOOTH_BLOCKS   spectral_mul_accum(st->X, st->W, st->Y, N, M);      spx_ifft(st->fft_table, st->Y, st->e);#endif   /* Compute weight gradient */   if (st->saturated == 0)   {      for (j=M-1;j>=0;j--)      {         weighted_spectral_mul_conj(st->power_1, FLOAT_SHL(PSEUDOFLOAT(st->prop[j]),-15), &st->X[(j+1)*N], st->E, st->PHI, N);         for (i=0;i<N;i++)            st->W[j*N+i] = ADD32(st->W[j*N+i], st->PHI[i]);               }   } else {      st->saturated--;   }      /* Update weight to prevent circular convolution (MDF / AUMDF) */   for (j=0;j<M;j++)   {      /* This is a variant of the Alternatively Updated MDF (AUMDF) */      /* Remove the "if" to make this an MDF filter */      if (j==0 || st->cancel_count%(M-1) == j-1)      {#ifdef FIXED_POINT         for (i=0;i<N;i++)            st->wtmp2[i] = EXTRACT16(PSHR32(st->W[j*N+i],NORMALIZE_SCALEDOWN+16));         spx_ifft(st->fft_table, st->wtmp2, st->wtmp);         for (i=0;i<st->frame_size;i++)         {            st->wtmp[i]=0;         }         for (i=st->frame_size;i<N;i++)         {            st->wtmp[i]=SHL16(st->wtmp[i],NORMALIZE_SCALEUP);         }         spx_fft(st->fft_table, st->wtmp, st->wtmp2);         /* The "-1" in the shift is a sort of kludge that trades less efficient update speed for decrease noise */         for (i=0;i<N;i++)            st->W[j*N+i] -= SHL32(EXTEND32(st->wtmp2[i]),16+NORMALIZE_SCALEDOWN-NORMALIZE_SCALEUP-1);#else         spx_ifft(st->fft_table, &st->W[j*N], st->wtmp);         for (i=st->frame_size;i<N;i++)         {            st->wtmp[i]=0;         }

⌨️ 快捷键说明

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