使用过零率区分浊音/清音语音

时间:2013-07-08 18:25:17

标签: java android signal-processing speech-recognition

过零率是沿信号的符号变化率,即信号从正变为负或变回的速率。

过零率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-我使用零交叉的目标是消除信号的清音部分,并且此代码返回零交叉率。那我该怎么办?!

2-我怎么知道“低”过零率是多少以及“高”过零率是多少?

1 个答案:

答案 0 :(得分:4)

根本问题在于,虽然您已经找到了一种计算样本块过零率的方法,但您无法使用它来区分该块内的声音,因为它只会为您提供一个描述整个样本的数字块。

一个可能的解决方案是将您的大块分成小块,然后处理它们。如果你这样做,你很快就会发现你的小块,你任意制作的,不适合整齐的浊音和清音类别,只需删除一个块或将一个块的音量设置为零就会让你“波涛汹涌”听起来甚至是刺耳的咔哒声,并且不会像你喜欢的那样干净地分割词性。

这可能是一个有价值的开始,因为它更接近你现有的代码,但从长远来看它将无法解决,除非你只是想做一些粗糙的事情(在这种情况下,这可能是够好了!)。

要解决此问题,您可能需要考虑计算更新每个样品的Zr的“瞬时过零率” 1

  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左右,但演讲不是我的专长。此外,它会因发言者而有所不同,可能还会受到语言和其他因素的影响。我建议你做一些样品,亲自看看。

  3. 1 这个名字有点误导,你可以说“没有瞬时过零率”。我不是在这里争辩的;相反,我想使用那个短语,因为它表达了我的意思,我希望你理解它。我只想说你应该尽可能多地更新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()的输出,因为它会倾向于大量跳转。简单的指数或移动平均滤波器效果很好。