我正在开发一个以音频播放为中心的Android应用程序,我遇到了一些不稳定的行为(音频口吃和打嗝),我怀疑这可能是某些设备固有的,操作系统版本或设备的本机缓冲区大小。
关于我的实现-我需要低延迟,所以我在OpenSL ES回调中处理我的音频,并使用128个样本的相当小的缓冲区大小来排队缓冲区。我在回调期间进行mp3解码,但由于我的环缓冲区大小,我不需要在每个回调周期中解码。
我正在使用远程测试服务来衡量各种设备和操作系统版本的音频播放质量,这里是我发现的一些不一致的例子。
- 三星Galaxy S4 w/Android 4.4 -没有音频播放问题
- 三星Galaxy S4 w/Android 4.3 -用户在锁定/解锁设备时体验音频脱落/口吃
- 三星Galaxy Note 2 w/Android 4.1.2 -没有问题
- 三星Galaxy Note 2 w/Android 4.3 -播放时音频丢失,锁定/解锁屏幕时口吃。
就我个人而言,我有一部4.1.2版本的Galaxy S3和4.4版本的Nexus 5,从来没有遇到过这些问题。我也有一些旧的2.3.7设备没有出现这些问题(2010年的Droid Incredible, LG Optimus Elite)。
我很有信心,我没有过度使用处理器,因为我可以在旧的姜饼设备上运行这个程序。
我的问题:
- 如果我将我的基本SDK提高到4.2,我可以从硬件检测到本机缓冲区大小,并在缓冲队列回调期间使用这个的一些倍数。这对结巴和辍学的问题,特别是在屏幕锁定的情况下,会有很大的不同吗?
- Android 4.3是否存在已知的音频播放问题?特别是在屏幕锁定动作中?这可能只是三星的问题吗?
- 是否有其他方法来提高性能以避免这个问题?我的应用程序绝对需要OpenSL ES。
谢谢。
增大缓冲区大小可以解决失真和噪声等问题。是的,当SDK高于4.2时,您可以使用以下命令从硬件检测本机缓冲区大小:
String size = audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER);
但是另一种获得Audio Record最小缓冲区大小的方法是:
int minForAudioRecord = AudioRecord.getMinBufferSize(8000,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
And for Audio Playback:
int minForAudioTrack = AudioTrack.getMinBufferSize(8000,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT);
如果您的SDK版本大于或等于4.2,那么您可以为音频设置首选采样率。
String rate = audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
我发现三星设备在处理这些事情时是最糟糕的,因为每个设备都有不同的方法来处理音频驱动。