我该如何查看我的平板电脑支持哪些采样率?

3

我有一个在很多设备上都运行正常(Xoom,Xyboard等)的应用程序,但在Galaxy 10.1上却在这一行出现了故障。

mrec.setAudioSamplingRate(44100);

当我注释掉这一行的时候,一切都顺利了。(我不确定它使用了哪个默认速率)。
我猜设备不支持这个特定的采样率,但是在文档中我找不到可以查看支持采样率的方法或对象。
非常感谢您的帮助。

2
https://dev59.com/sWsz5IYBdhLWcg3wOVL5 - Nikolay Shmyrev
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对我来说都有效,但当然,这取决于设备。

谢谢你提供如此详细的答案!我有点倾向于只是让它保持默认状态录制,以避免这种麻烦。如果我不覆盖它,你知道我该调用什么方法来找出它默认选择了什么吗? - Yevgeny Simkin
我假设你正在使用MediaRecorder类。如果速率不受支持,您的prepare()调用将失败。这就是您找出的方式。如果您选择默认值,我认为它会选择与媒体格式密切相关的那个,如此处所述:http://developer.android.com/reference/android/media/MediaRecorder.html#setAudioSamplingRate%28int%29。也许有一些外部库可以让您在录制后动态分析录制的音频,但我不知道Android定义的学习采样率的方法。 - Erol
相关链接:https://dev59.com/sWsz5IYBdhLWcg3wOVL5 - P i

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

虽然回答晚了,但我认为这可能会有用。

1
迟做总比不做好。 :) - Yevgeny Simkin
唉,这些对 getProperty 的调用返回空字符串。我可能漏掉了什么。 - John Crawford
你正在运行的设备的API级别是多少? - Reaz Murshed
从文档中可以看到,PROPERTY_OUTPUT_SAMPLE_RATE是“该设备主输出流的本机或最佳输出采样率,以十进制赫兹为单位。”因此,与录音无关。 - zeitgeist

1
这并不使用缓冲区大小作为测试,因为它不是绝对的。我在自己的ASUS 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
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接