Проблема с реализацией алгоритма энергетического порога для обнаружения Голосовой активности

#speech-recognition

#распознавание речи

Вопрос:

Я пытаюсь реализовать алгоритм энергетического порога для обнаружения голосовой активности и не получаю значимых значений энергии для кадров размером wL.

 wL = 1784 // about 40 ms (
const double decay_constant = 0.90 // some optimal value between 0 and 1
double prevrms = 1.0  // avoid DivideByZero
double threshold = some optimal value after some experimentation

for (int i = 0; i < noSamples ; i  = wL)
{
   for (int j = 0; j < wL; j  )
   {
     // Exponential decay
     total = total * decay_constant;
     total  = (audioSample[j] * audioSample[j]); // sum of squares
   }

   double mean = total / wL;
   double rms = Math.Round(Math.Sqrt(mean),2); // root mean sqare
   double prevrms = 1.0;

   if(rms/prevrms > threshold)
   {
  // voice detected
   }

   prevrms = rms;
   rms = 0.0;
}
  

Что не так с приведенной выше реализацией? rms вычисляется для каждого кадра как 0,19.

Другая проблема заключается в скорости, так как на выполнение вышеописанного ушло около 30 минут. В настоящее время реализация составляет O (n2). Я работаю с автономными данными, поэтому это не так важно — точность является основной целью — но любые предложения по повышению эффективности были бы высоко оценены.

Кроме того, должен ли я использовать другие факторы, такие как автокорреляция и скорость пересечения нуля, или достаточно одной энергии?

Ниже приводится краткое описание файла WAV (только с учетом чистой разговорной речи) Я использую:

 // WAV file information
Sampling Frequency: 44100     Bits Per Sample:  16 
Channels: 2    nBlockAlign: 4   wavdata size: 557941248 bytes
Duration: 3162.932 sec    Samples: 139485312    Time between samples: 0.0227 ms
Byte position at start of samples: 44 bytes  (0x2C)

Chosen first sample to display:  1   (0.000 ms)
Chosen end  sample to display:  1784   (40.431 ms)

16 bit max possible value is:  32767  (0x7FFF)
16 bit min possible value is: -32768  (0x8000)
  

Ответ №1:

Я нашел проблему. Мой второй цикл for был настроен неправильно. В принципе, второй цикл for должен быть примерно таким:

 for(j = i; j <= i   wL ;j  )
  

Вместо:

 for(j = 0; j < wL; j  )
  

Который повторял одни и те же значения выборки снова и снова.