2011-05-20 40 views
2

我正在嘗試實現語音活動檢測的能量閾值算法,並且沒有爲大小爲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(n )。我正在處理離線數據,所以這不是什麼大問題 - 準確性是主要目標 - 但任何提高效率的建議都將受到高度讚賞。

此外,我是否應該使用其他因素,如自動關聯和過零率,還是單單是足夠的能量?

以下爲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(j = i; j <= i + wL ;j++) 

相反的:

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

其中又一遍又一遍的去在相同的採樣值。