我有一个应用程序可以在一堆设备(Xoom、Xyboard 等)上完美运行,但在 Galaxy 10.1 的这条线上却失败了
mrec.setAudioSamplingRate(44100);
当我评论这条线时,一切都会顺利进行。(我不确定它默认使用的速率)。
我的猜测是该设备不支持这个特定的采样率,但我在文档中没有看到任何关于我可以查看什么对象的方法,以找出支持的采样率是多少。
所有帮助表示赞赏。
我有一个应用程序可以在一堆设备(Xoom、Xyboard 等)上完美运行,但在 Galaxy 10.1 的这条线上却失败了
mrec.setAudioSamplingRate(44100);
当我评论这条线时,一切都会顺利进行。(我不确定它默认使用的速率)。
我的猜测是该设备不支持这个特定的采样率,但我在文档中没有看到任何关于我可以查看什么对象的方法,以找出支持的采样率是多少。
所有帮助表示赞赏。
是的,Android 没有提供明确的方法来检查它,但是有一个使用 AudioRecord 类的getMinBufferSize函数的解决方法。
public void getValidSampleRates() {
for (int rate : new int[] {8000, 11025, 16000, 22050, 44100}) { // add the rates you wish to check against
int bufferSize = AudioRecord.getMinBufferSize(rate, AudioFormat.CHANNEL_CONFIGURATION_DEFAULT, AudioFormat.ENCODING_PCM_16BIT);
if (bufferSize > 0) {
// buffer size is valid, Sample rate supported
}
}
}
如果您检查了函数描述,如果输入的参数之一不受支持,它将返回负值。假设您输入所有其他有效输入,如果不支持采样率,我们期望它返回负缓冲区大小。
但是,有些人报告说即使不支持采样率,它也会返回正值,因此可以通过尝试初始化AudioRecord 对象来进行额外检查,如果它认为无法处理该采样率,则会抛出 IllegalArgumentException。
最后,它们都没有提供有保证的检查,但同时使用两者都会增加您获得支持检查的机会。
大多数时候,44100 和 48000 对我有用,但当然,它因设备而异。
Android 具有AudioManager.getProperty()
获取最小缓冲区大小并获得音频记录和播放的首选采样率的功能。但是,当然,AudioManager.getProperty()
在 API 级别 < 17 上不可用。这是有关如何使用此 API 的示例代码示例。
// To get preferred buffer size and sampling rate.
AudioManager audioManager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
String rate = audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
String size = audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER);
Log.d("Buffer Size and sample rate", "Size :" + size + " & Rate: " + rate);
虽然这是一个迟到的答案,但我认为这可能很有用。
这不使用缓冲区大小作为测试,因为它不是绝对的。我在自己的 ASUS MemoPad 上测试了上述解决方案,缓冲区大小测试将始终返回一个正整数,给出误报。
第一种方法将测试通过的采样率,并根据设备是否支持采样率返回真或假。第二种方法将遍历给定的列表并返回最大有效采样率(列表中的第一个有效采样率) - 可以轻松更改其他启发式方法。
boolean validSampleRate(int sample_rate) {
AudioRecord recorder = null;
try {
int bufferSize = AudioRecord.getMinBufferSize(sample_rate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, sample_rate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
} catch(IllegalArgumentException e) {
return false; // cannot sample at this rate
} finally {
if(recorder != null)
recorder.release(); // release resources to prevent a memory leak
}
return true; // if nothing has been returned yet, then we must be able to sample at this rate!
}
int maxValidSampleRate() {
int[] sample_rates = new int[]{44100, 16000}; // pad list with other samples rates you want to test for
for(int sample_rate : sample_rates) {
if(validSampleRate(sample_rate))
return sample_rate; // this rate is supported, so return it!
}
return -1; // no valid sample rate
}