Java 用过零率区分清浊语音

Java 用过零率区分清浊语音,java,android,signal-processing,speech-recognition,Java,Android,Signal Processing,Speech Recognition,过零率是沿着信号的符号变化率,即信号从正到负或反向变化的速率 过零率Zn可用于: 1-区分浊音/清音语音 2-将清音语音与静态背景噪声分离 这是一种简单(但有效)的方法来区分 浊音和清音语音区域: • Voiced region: lower zero-crossing rate • Unvoiced region: higher zero-crossing rate 下面是我正在使用的代码: public double evaluate(){

过零率是沿着信号的符号变化率,即信号从正到负或反向变化的速率

过零率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;
        }
public双重评估(){
int numZC=0;
int size=signals.length;

对于(int i=0;i=0&&signals[i+1],基本问题是,虽然您已经找到了一种计算样本块过零率的方法,但您不能使用该方法来区分该块中的声音,因为它只给出一个描述整个块的数字

一个可能的解决方案是将你的大音块分成小音块,然后再进行处理。如果你这样做,你很快就会发现你随意制作的小音块不适合整齐的浊音和清音类别,只需去掉一个音块或将一个音块的音量设为零,就会让你感到“波涛汹涌”声音,甚至是刺耳的咔哒声,不会像你喜欢的那样清晰地划分词类

这可能是一个有价值的起点,因为它更接近您现有的代码,但从长远来看,它不会起作用,除非您只是想做一些粗略的工作(在这种情况下,这可能足够好了!)

为了解决这个问题,您可能需要考虑计算一个“瞬时过零率”1,它更新每个样本的Zr。
  • 我使用过零的目的是消除信号的清音部分,,,而这个代码会返回过零率。那么我该怎么做呢?!
    不清楚你想要什么。你说的“消除”是什么意思?你想保持沉默还是跳过这些部分?如果沉默,只需将不需要的部分替换为零。要跳过,只需删除这些示例。当然,你最终还是会出现单击和弹出,但我认为你知道如何摆脱这些。如果不知道,也许你可以继续阅读。请记住,你几乎肯定要删除这些示例使用一些启发式方法,如“不要删除任何小于n个样本的部分”

  • 我如何知道多少是“低”过零率,多少是“高”过零率???
    我猜一个好的阈值大约在400Hz左右,但语音不是我的专长。此外,它会因说话人、语言和其他因素而有所不同。我建议您制作一些样本,自己看看

  • 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()的输出一个简单的指数或移动平均滤波器将非常有效。

    基本问题是,虽然你已经找到了一种计算样本块过零率的方法,但你不能用它来区分该块中的声音,因为它只给你一个数字来描述你的整个b锁

    一个可能的解决方案是将你的大音块分成小音块,然后再进行处理。如果你这样做,你很快就会发现你随意制作的小音块不适合整齐的浊音和清音类别,只需去掉一个音块或将一个音块的音量设为零,就会让你感到“波涛汹涌”声音,甚至是刺耳的咔哒声,不会像你喜欢的那样清晰地划分词类

    这可能是一个有价值的起点,因为它更接近您现有的代码,但从长远来看,它不会起作用,除非您只是想做一些粗略的工作(在这种情况下,这可能足够好了!)

    为了解决这个问题,您可能需要考虑计算一个“瞬时过零率”1,它更新每个样本的Zr。
  • 我使用过零的目的是消除信号的清音部分,,,而这个代码会返回过零率。那么我该怎么做呢?!
    不清楚你想要什么。你说的“消除”是什么意思?你想保持沉默还是跳过这些部分?如果沉默,只需将不需要的部分替换为零。要跳过,只需删除这些示例。当然,你最终还是会出现单击和弹出,但我认为你知道如何摆脱这些。如果不知道,也许你可以继续阅读。请记住,你几乎肯定要删除这些示例使用一些启发式方法,如“不要删除任何小于n个样本的部分”

  • 我如何知道多少是“低”过零率,多少是“高”过零率???
    我猜一个好的阈值大约在400Hz左右,但语音不是我的专长。此外,它会因说话人、语言和其他因素而有所不同。我建议您制作一些样本,自己看看

  • 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()的输出,因为它往往会跳跃很多。一个简单的指数或移动平均滤波器将非常有效。

    这与编程无关,但与信号概念有关。最好选择“否”,我的问题实际上是编程部分