在百度文档 http://ai.baidu.com/docs#/ASR-Android-SDK/top 中,对于识别后回调可以录制一个PCM文件保存在手机端:
保存音频 - OUT_FILE
描述: SDK 在识别的同时,把识别的音频保存下来,比如用于复现。
该参数需要设置ACCEPT_AUDIO_DATA参数demo测试:点击 设置=》保存音频。
请求示例:保存音频到 /storage/emulated/0/baiduASR/outfile.pcm{"accept-audio-data":true,"accept-audio-volume":false,"outfile":"\/storage\/emulated\/0\/baiduASR\/outfile.pcm"}
我这里的需求是这样的,用户点击按钮读一句话,读的过程中使用语音识别出说话的内容,动态显示,说完后要求手机复述原声。
由于语音识别占用设备麦克风,所以不能自己行开启录单设备,只能使用百度SDK提供的上面的接口。理论上讲,在识别后我们读取这个pcm文件,就可以实现这个需求,然后问题就来了。
第一个小问题是文件权限,我的两部安卓手机一部可以成功写入这个文件,另一部却不能,于是只能把保存地址改成程序自己的位置:
String filePath = getFileRoot(getContext()) + File.separator + "baiduasr.pcm";
String json = "{\"accept-audio-data\":true,\"accept-audio-volume\":false,\"outfile\":\""+filePath+"\",\"pid\":1737}";asr.send(SpeechConstant.ASR_START, json, null, 0, 0);
这样就都可以成功取到这个文件,第二个问题就是播放,网上有现成的代码:
https://stackoverflow.com/questions/41541956/play-pcm-stream-in-android
然而读出来全是噪音ZZZZZZ,最初以为是代码问题,重建项目重现问题排除,然后认为是PCM本身的问题,求教朋友后使用ffmpeg在PC端进行播放:
参考文档:https://ai.baidu.com/docs#/ASR-Tool-convert/top
声音完美还原,所以pcm文件没问题,查看文件大小为145920字节,播放时长为4.56秒(见上图),145920/2/4.56=16000,所以采样率肯定是16000单声道,问题肯定在于android播放上了。
在几乎穷举了android端所有可能的参数后,让我在PC端改用s16be再试一下,结果发出了和android端一样的噪音声,群友指出是大小端问题,百度了一下过程不再赘述,解决方法就是把每个采样的高8位和低8位交换。
int i = 0;
while (dis.available() > 0)
{
//music[i] = dis.readShort();
short temp = dis.readShort();
int c = (temp << 8) | (temp>> 8 & 0x00ff);
music[i] = (short) c;
i++;
}
从应用层研究到采样数据,卡了两三天时间,还是在外力的帮助下解决了。如果是自己研究的话,下一步就是把ffmpeg编译到android里去了,参考:Android最简单的基于FFmpeg的例子(四)---以命令行的形式来使用ffmpeg
希望本文能对您有所帮助。