audiotrack这个最坑爹的class经过十几个小时的不断尝试,总算被自己搞明白了,最近总在想android使用java开发,看上去类库很丰富,但能完成的功能其实还是蛮有限的,如果想自己写JNI再让java层来调用,要做的工作巨大,最主要的是,效率可能还极端低下,否则你只能用系统提供的,也就是说google提供了什么,你能做什么很大程度上已经确定,最简单的例子莫过于音视频的编解码了,做好android->pc端语音的时候,我以为pc->android的语音是很easy的事,我想的太简单了,原因还是在于,能用的类只有2个,要么mediaplayer,要么audiotrack,mediaplayer相对偏上层,它可以播放编码过的文件,但是,仅局限于本地文件,或者是网络流媒体点播,也就是说对于socket传过来的实时stream,它无能为力,那么,只能用audiotrack,它相对底层,但只能播放pcm的原始数据,也就是说,所有编码过的文件它无能为力,这对于想利用3G网络来通话的APP来说,每秒16000bytes的数据量其实是非常大的。尽管如此,目前无高效解码amr的代码出现前,也只有这样了。android官方文档说audiotrack是通过write来将wave文件直接write到硬件上去的,但是,最坑爹的问题出现了,它没告诉你write的bytes如果小于该硬件所需要的最小buffersize会有令人厌烦的白噪声!!!而且这种白噪声也越来越大以至于无法容忍,google了个十几个小时,翻遍了所有的论坛,包括stackoverflow,没一个人指出这点。
发现问题了,解决方法就简单,每次从socket中读出的文件,write到硬件上,如果write的值小于buffersize,则直接中断本次循环,这样就没有白噪声了,但低噪相当的大,好歹能听清楚说话,在电脑上放了几首歌,在手机上用耳机来听,效果勉强能接受。
还有一点,就是java虚拟机是大端模式,而pc机上如果是使用c/c++来开发,恰好传的pcm码流又是>8bit的话。不转模式会听到熟悉的白噪声。。。