我有一个可以在一堆设备上完美运行的应用程序(Xoom,Xyboard等),但在Galaxy 10.1的这一行上失败了
mrec.setAudioSamplingRate(44100);
当我评论这条线时,一切都在游泳。 (我不确定它默认使用的速率)。 我的猜测是该设备不支持这个特定的采样率,但是我没有在文档中看到任何可以查找对象的方法,以找出支持的采样率。
所有帮助表示赞赏。
答案 0 :(得分:12)
是的,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
}
}
}
如果您检查了功能说明,如果不支持输入的参数之一,它将返回负值。假设您输入的所有其他输入都是有效的,如果不支持采样率,我们期望它返回负缓冲区。
然而,有些人报告即使不支持采样率也会返回正数,因此可以通过尝试初始化an AudioRecord object来进行额外的检查,如果它认为无法处理,则会抛出IllegalArgumentException采样率。
最后,它们都没有提供有保证的支票,但使用两者都会增加获得支持的支票的机会。
大部分时间,44100和48000对我有用,但当然,它因设备而异。
答案 1 :(得分:6)
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);
虽然这是一个迟到的答案,但我认为这可能有用。
答案 2 :(得分:0)
这不会将缓冲区大小用作测试,因为它不是绝对的。我在自己的华硕MemoPad上测试了所说的解决方案,缓冲区大小测试总是返回一个正整数,给出误报。
第一种方法将测试传递的采样率并返回true或false,具体取决于设备是否支持采样率。第二种方法将遍历给定列表并返回最大有效采样率(列表中第一个有效的采样率) - 可以轻松更改其他启发式。
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
}