2013-07-08 88 views
2

過零率是沿着信號的符號變化率,即信號從正變化爲負或反變化的速率。使用零交叉率區分濁音/清音語音

過零率的Zn可以用來:

1-區分濁音/清音語音從靜態背景噪聲 -2-獨立清音語音。

這是 有聲和無聲的講話地區來區分一個簡單(但有效)的方式:

• Voiced region: lower zero-crossing rate 
• Unvoiced region: higher zero-crossing rate 

,這裏是我使用的代碼:

 public double evaluate(){ 
      int numZC=0; 
      int size=signals.length; 

      for (int i=0; i<size-1; i++){ 
        if((signals[i]>=0 && signals[i+1]<0) || (signals[i]<0 && signals[i+1]>=0)){ 
          numZC++; 
        } 
      }      

      return numZC/lengthInSecond; 
     } 

我的問題是:

1-我使用零交叉的目標是消除信號的清音部分,,,這段代碼給出了零交叉率(ZERO-CROSSING RATE)。那麼我將如何做到這一點?!

2-我將如何知道「低」過零率和「高」過零率有多大?

+0

這與編程無關,但與信號概念有關。最好去http://dsp.stackexchange.com/ – leonbloy

+0

不,我的問題實際上是編程的一部分!這就是爲什麼我在這裏發佈它! @leonbloy – hana

+0

出於好奇,你有一個研究鏈接,詳細說明如何使用過零率來區分濁音和濁音? – Shannon

回答

4

基本問題是,雖然你已經找到了一種方法來計算一塊樣本的過零率,但你不能用它來區分該塊內的聲音,因爲它只給你一個數字來描述你的整個街區。

一個可能的解決方案是將你的大塊分成小塊,然後處理這些塊。如果你這樣做了,你很快就會發現,你任意製作的小塊不適合整齊的濁音和清音類別,只是刪除一個塊或者將塊的音量設置爲零會讓你「波濤洶涌」聽起來甚至刺耳的咔嚓聲,並且不會將講話的部分按照你喜歡的方式乾淨地分開。

這可能是一個值得開始的地方,因爲它更接近您現有的代碼,但從長遠來看它不會奏效,除非您只是想要做一些粗糙的事情(在這種情況下,這可能會足夠好!)。

要解決這個問題,您可能需要考慮計算更新每個樣品的Zr的「瞬時過零率」。

  1. My goal of using zero crossing is to eliminate the unvoiced part of the signal,,, and this code gives back the ZERO-CROSSING RATE. SO how will i do that?!目前尚不清楚你想要什麼。 「消除」是什麼意思?你想沉默還是想跳過那些部分?對於沉默,只需用零替換不需要的部分即可。要跳過,只需刪除這些樣本。當然,你仍然會得到點擊和流行音樂,但我認爲你知道如何擺脫這一點。如果沒有,也許你可以閱讀linear interpolation.請記住,你幾乎肯定必須應用一些啓發式的「不要刪除小於n個樣本的任何部分」。

  2. How will i know how much is a "low" zero-crossing rate and how much is a "high" zero-crossing rate???我想一個好的門檻大概在400Hz左右,但是講話不是我的專業。此外,演講人可能會略微改變一下,也可能通過語言和其他因素。我建議你做一些樣品並親自看看。

這個名字是有點誤導,你可以說:「有沒有這樣的事,作爲一個瞬時過零率」。我不是在這裏爭論的;而是我想用這句話,因爲它表達我的意思,我希望你能理解它。只要說你應該儘可能經常更新Zr就足夠了。例如。是這樣的:

int lastSign = 0; 
int lastCrossing = 0; 
float nextZeroCrossing(float newSample) { 
    int thisSign = newSample > 0 ? 1 : -1 ; 
    if(thisSign != lastSign) { 
     lastSign = thisSign; 
     //zero crossing has happened. Update our estimate of Zr using lastCrossing and return that 
    } else { 
     ++lastCrossing; 
     //zero crossing has not happened. Return existing Zr 
    } 
} 

您可能要「平穩」 nextZeroCrossing(輸出),因爲它往往會跳開了不少。一個簡單的指數或移動平均過濾器將會很好。