静音去除的问题
一般來說,和設置的threshold參數關系很大,但是這里僅是要一個算法。
或者說,從這偵測到的第一個認為是靜音的分組開始,就丟棄還是要等等。如何平滑,從說話到靜音,和從靜音到說話的過程。
多謝
首先,這不是一個簡單的問題。
靜音檢測,不只是檢測通話人是否Talking,更重要的是如何在通話環境中參雜著其他噪聲
時如何能夠排除這些噪聲干擾,并正確的得到檢驗結果。
平滑靜聲與說話之間的過程也是一個重要的問題。
呵呵,期待大家能將已實現的技術和經驗拿出來共享 :)
是呀,這是一個應該很有用的題目。
所以所謂的靜音檢測,一般正式的叫法是:靜噪抑制技術,甚至還包含有一部分的回音消除,如果是在時延較大ip網,也是必須的。當然,首先需要的是一塊比較好的聲卡和一個抑噪耳機,(比如viaVoice帶的)
我這里只有一個比較原始的思路:設置一個threshold值,一個比率。檢測語音的分組,如果其中大部分數據都在門閾值以下,就認為是背景噪音或者說靜默時間的語音包,予以丟棄。但是這里涉及一個參數設置問題,一個平滑問題。所以還是要請教大家,希望大家關注。
在實際中還有一個更為普遍的問題:就是白噪音的問題,對于參數的設定就更為重要了。
目前是這樣做的,但是效果不是非常好。
///________________________________________________________________________
/// Method: DetectSilence
/// Params:
/// lpData: the data for detect
/// inLen: data length
/// Function:
/// detect the data. discard the background noise and other
/// noise. the parameter is sensible.
///________________________________________________________________________
DWORD CAudioMgr::DetectSilence(LPBYTE lpData, DWORD inLen)
{
static bool bSpeakingState = TRUE; // 指明目前的狀態是通話還是靜默
static unsigned int nConsecutive = 0; // 用來計算連續出現的某種類型的包
bool bNoisePacket; // 當前檢測的語音包類型(判斷)
long hit = 0; // 要來計算語音包中符合條件的位數。long足夠了
unsigned int i; // 循環變量
// 推測當前語音包類型
for(i = 0; i < inLen; i++) {
if((lpData[i] <= 0 + constThreshold )
|| (lpData[i] >= 255 - constThreshold))
hit++;
}
float ratio = (float)hit/ inLen;
if (ratio > constHitratio)
{
bNoisePacket = TRUE;
}
else
{
bNoisePacket = FALSE;
}
if( TRUE == bSpeakingState) // 如果目前是通話狀態
{
if(FALSE == bNoisePacket) // 如果目前的包斷定為語音包
{
nConsecutive = 0; // 計數清零
return inLen;
}
else // 如果目前是靜音包
{
nConsecutive++;
if( constNoiseCons < nConsecutive ) // 如果已經連續出現了足夠的靜音包
{
nConsecutive = 0 ; // 計數清零
TRACE("從通話狀態轉化到靜音狀態!**********\n");
bSpeakingState = FALSE; // 轉換到靜音狀態
return 0;
}
else
{
return inLen; // 仍然提交
}
}
}
else // 如果當前是靜音狀態
{
if(TRUE == bNoisePacket) // 如果目前的包斷定為靜音包
{
nConsecutive = 0; // 計數清零
return 0;
}
else // 如果目前是語音包
{
nConsecutive++;
if( constVoiceCons < nConsecutive ) // 如果已經連續出現了足夠的語音包
{
nConsecutive = 0 ; // 計數清零
TRACE("*********從靜音狀態轉化到通話狀態!\n");
bSpeakingState = TRUE; // 轉換到靜音狀態
return inLen;
}
else
{
return 0; // 否則仍然丟棄
}
}
}
}
但是在實際使用中:上面我寫的算法在經過調整參數之后,可以較為滿意的偵測到靜默的狀態,但是在網絡傳輸中收到的語音包會出現較明顯的滯后。不知道為什么?我每次都是及時發送出數據包的。
還有,按理說應該是在應用程序運行前,出現類似于MSN Message Service的語音設備音量調整的。那位可不可以指教如何很方便的做?
多謝了。
總結
- 上一篇: 恶搞无限弹窗
- 下一篇: js读取excel时间格式转换