3

我有一个应用程序可以在一堆设备(Xoom、Xyboard 等)上完美运行,但在 Galaxy 10.1 的这条线上却失败了

mrec.setAudioSamplingRate(44100);

当我评论这条线时,一切都会顺利进行。(我不确定它默认使用的速率)。

我的猜测是该设备不支持这个特定的采样率,但我在文档中没有看到任何关于我可以查看什么对象的方法,以找出支持的采样率是多少。

所有帮助表示赞赏。

4

3 回答 3

14

是的,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 对我有用,但当然,它因设备而异。

于 2012-07-19T04:18:25.680 回答
7

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);

虽然这是一个迟到的答案,但我认为这可能很有用。

于 2014-03-11T05:51:43.237 回答
1

这不使用缓冲区大小作为测试,因为它不是绝对的。我在自己的 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
}
于 2014-04-17T15:28:02.747 回答