Как я могу адаптировать эхоподавитель speex для обработки образцов с плавающей точкой? - PullRequest
0 голосов
/ 03 мая 2011

Добрый день!Как я могу использовать образцы с плавающей запятой для обработки эхоподавления?Я пытался изменить интерфейс и тело центральной функции:

с

void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out);

на

void float_speex_echo_cancellation(SpeexEchoState *st, const float rec[], const float play[], float out[]);

и с

...
       for (i=0;i<st->frame_size;i++)
      {
         spx_word32_t tmp_out;
         tmp_out = SUB32(EXTEND32(st->input[chan*st->frame_size+i]), EXTEND32(st->e[chan*N+i+st->frame_size]));
         tmp_out = ADD32(tmp_out, EXTEND32(MULT16_16_P15(st->preemph, st->memE[chan])));

         if (in[i*C+chan] <= -32000 || in[i*C+chan] >= 32000)
         {
         if (st->saturated == 0)
            st->saturated = 1;
         }

         **out[i*C+chan] = (spx_int16_t)WORD2INT(tmp_out);**

         st->memE[chan] = tmp_out;
      }
...

на

  ...

     for (i=0;i<st->frame_size;i++)
          {
             spx_word32_t tmp_out;
             tmp_out = SUB32(EXTEND32(st->input[chan*st->frame_size+i]), EXTEND32(st->e[chan*N+i+st->frame_size]));
             tmp_out = ADD32(tmp_out, EXTEND32(MULT16_16_P15(st->preemph, st->memE[chan])));

             if (in[i*C+chan] <= -32000 || in[i*C+chan] >= 32000)
             {
             if (st->saturated == 0)
                st->saturated = 1;
             }

             **out[i*C+chan] = /*(spx_int16_t)WORD2INT(*/tmp_out*/)*/;**

             st->memE[chan] = tmp_out;
          }
    ...

и от

static inline void filter_dc_notch16(const spx_int16_t *in, spx_word16_t radius, spx_word16_t *out, int len, spx_mem_t *mem, int stride)
{
   int i;
   spx_word16_t den2;
   den2 = (spx_word16_t)(radius*radius + .7f*(1.f-radius)*(1.f-radius));
   for (i=0;i<len;i++)
   {
      spx_int16_t vin = in[i*stride];
      spx_word32_t vout = mem[0] + SHL32(EXTEND32(vin),15);
      mem[0] = mem[1] + 2*(-vin + radius*vout);
      mem[1] = SHL32(EXTEND32(vin),15) - MULT16_32_Q15(den2,vout);
      out[i] = SATURATE32(PSHR32(MULT16_32_Q15(radius,vout),15),32767);
   }
}

до

 static inline void float_filter_dc_notch16(const /*spx_int16_t*/spx_word16_t *in, spx_word16_t radius, spx_word16_t *out, int len, spx_mem_t *mem, int stride)
{
   int i;
   spx_word16_t den2;
   den2 = /*(spx_word16_t)*/(radius*radius + .7f*(1.f-radius)*(1.f-radius));
   for (i=0;i<len;i++)
   {
      /*spx_int16_t*/spx_word16_t vin = in[i*stride];
      spx_word32_t vout = mem[0] + SHL32(EXTEND32(vin),15);
      mem[0] = mem[1] + 2*(-vin + radius*vout);
      mem[1] = SHL32(EXTEND32(vin),15) - MULT16_32_Q15(den2,vout);
      out[i] = /*SATURATE32(*/PSHR32(MULT16_32_Q15(radius,vout),15)/*,32767)*/;
   }
}

Итак, я предотвратил преобразование результата вывода типа с плавающей запятой в короткое int, но теперь я получаю предупреждение:

speex_warning («Эхоподавитель начал действовать забавно и получил удар (сброс). Он клянется, что теперь будет себя вести.»);

, который указывает на параметр st-> screwed_up, имеющий 50 значенийэто признаки установки на ноль всех сэмплов:

...

 if (!(Syy>=0 && Sxx>=0 && See >= 0)
   || !(Sff < N*1e9 && Syy < N*1e9 && Sxx < N*1e9)
  )

{ st->screwed_up += 50; for (i=0;iframe_size*C;i++) out[i] = 0; }

...

Что я могу сделать?

enter code here

1 Ответ

0 голосов
/ 12 мая 2011

Почему вы хотите использовать образцы с плавающей точкой?Стандартное линейное аудио PCM представляется в виде целочисленных выборок в соответствии с выбранным битрейтом - 8 бит, 16 бит и т. Д.

Откуда вы получаете этот вход?

На вашем месте я быпросто конвертируйте все, что у вас есть, в шорты и предоставьте Speex, чтобы он мог работать с ним.

...