Java 用过零率区分清浊语音
过零率是沿着信号的符号变化率,即信号从正到负或反向变化的速率 过零率Zn可用于: 1-区分浊音/清音语音 2-将清音语音与静态背景噪声分离 这是一种简单(但有效)的方法来区分 浊音和清音语音区域: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(){
• 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()的输出,因为它往往会跳跃很多。一个简单的指数或移动平均滤波器将非常有效。这与编程无关,但与信号概念有关。最好选择“否”,我的问题实际上是编程部分