我正在尝试实现自动录音功能,类似于Talking Tom应用程序 . 我使用以下代码从录音机读取输入并分析缓冲区:
float totalAbsValue = 0.0f;
short sample = 0;
numberOfReadBytes = audioRecorder.read( audioBuffer, 0, bufferSizeInBytes);
// Analyze Sound.
for( int i=0; i<bufferSizeInBytes; i+=2 )
{
sample = (short)( (audioBuffer[i]) | audioBuffer[i + 1] << 8 );
totalAbsValue += Math.abs( sample ) / (numberOfReadBytes/2);
}
// Analyze temp buffer.
tempFloatBuffer[tempIndex%3] = totalAbsValue;
float temp = 0.0f;
for( int i=0; i<3; ++i )
temp += tempFloatBuffer[i];
现在我能够检测来自录音机的语音输入,我可以分析音频缓冲区 .
缓冲区被转换为浮点值,如果它增加一定量,则假设背景中有一些声音并开始录制 . 但问题是该应用程序开始记录所有背景噪音,包括风扇/交流管道声音 .
任何人都可以帮我分析缓冲区来检测人声吗?或者还有其他方法可以从录音机输入中检测人声吗?
提前致谢,
9 回答
你究竟想要什么?你只是想过滤掉音频中的人类语音,还是你真的想知道这个人说的是什么?
通过在设备背面用第二个麦克风记录背景噪声并减去两个信号,几乎每个智能手机都会对人类语音进行过滤 . 但说实话,我还没有看到任何Android API,你可以直接访问这两个信号 .
如果你想进行语音转换,那么看看Sphinx4和Praat . 两人都做了这个工作,但我还没有看到Android的实现 . Sphinx4声称完全用Java编写,因此应该可以将其嵌入到Android应用程序中 .
他们中的大多数人误解了这个问题,他们的回答解决了与你不同的问题 .
您应该在缓冲区中解析音频,搜索语音人类范围内的频率 . 一旦你发现它们,就意味着有人开始说话了,你就可以开始录音了(不要忘记包括缓冲区,因为它包含了演讲的第一部分) .
搜索打印音频原始流中的频率列表的例程
如果你想要一个干净的录音,你可以
2.过滤后,噪音会降低,你可以使用语音识别API
API's
滤波越多越好噪声越多识别,但在滤波时要小心,因为它还可以将噪声与声音一起消除 .
另请阅读有关FFt的更多信息
Fast Fourier Transform of Human Voice
希望这可以帮助 :)
对于语音检测,请尝试使用ftt算法 .
对于噪音,请尝试speex库 .
我试图在Windows上解决类似的问题 . 我快速学到的一件事 - 使用快速傅里叶变换进行简单的频率分析是不够的 . 很多噪音都会影响到人的频率 - 从麦克风上的简单敲击到拍手 . 即使某种程度的复杂过滤也不会这样做 . 我发现最简单的方法是将噪声带到 Cloud API并要求它转录语音 . 如果 Cloud API可以转录为合理长度的字符串,那么我可以继续录制 - 否则,停止录制 . 这确实需要您采样一些噪音并将其发送给 Cloud 提供商 .
语音检测并不那么简单 . 有几种算法,其中一些已发布,例如GSM VAD . 有几个开源的VAD库可供使用,其中一些是讨论的here
在完全一般的情况下,这是一个未解决的问题 . 在实际意义上......
第一步是尽可能使录音无噪音 . 正如其他人所指出的那样,首先是定向麦克风,因为它集中在你想要保持的声音上 .
第二步是过滤 . 如前所述,电话公司在人们实际需要语音理解的频率范围方面做了大量工作 . 过滤掉该范围之外的频率将使声音听起来像......好吧,电话......但是会消除更多的背景噪音 .
如果你想超越它,事情会变得非常复杂 . 有一些算法,如果你可以向他们展示你在特定录音中考虑噪音的样本,就会对其进行分析并尝试将其减去,而不会损坏你想要保留太多的声音 . 这不是简单的编程;如果我是你,我会认真考虑从已经做对的人那里购买它,而不是试图重新发明/重新实现它 . 我不知道它们是否可用于Android,或者典型的Android机箱是否具有足够的计算能力来执行它们,如实时 . (我在工作室里使用了SoundSoap来消除A / C噪音,效果非常好 . )
事实上,我自己的倾向是将问题简化为已解决的问题:使用我可以获得的最具方向性和最接近的麦克风,让Android进行录制...但是然后进行信号处理以便稍后清理它,使用关闭 - 货架工具 . 但我承认我有偏见因为我已经投资了后者 .
您是否考虑过使用Microsoft的语音识别API?您可以使用语音密钥话语开始录制,就像他们在星际迷航中询问计算机之前所说的“计算机”一样 . 使用ISpRecognizer :: CreateRecoContext加载识别语法并开始识别 . 然后使用ISpPhrase执行检查,看看是否应该开始录制 .
处理输入的方法是使用专门的库来消除噪音 .
例如,http://audacity.sourceforge.net,可以去除噪音 .
只要您描述了主要类型的噪声,您应该只剩下语音 .
在从用户捕获之前以及在用户结束捕获之后收集采样数据是值得的,因为这将在环境中提供噪声的时间样本 . 如果每个用户都面临独特的背景噪音挑战,这非常有用