Java 如何确定平板电脑支持的采样率?

Java 如何确定平板电脑支持的采样率?,java,android,audio-recording,Java,Android,Audio Recording,我有一个应用程序可以在很多设备(Xoom、Xyboard等)上完美运行,但在Galaxy 10.1上这一行失败了 mrec.setAudioSamplingRate(44100); 当我把这行注释掉时,一切都很顺利。(我不确定它默认使用的速率) 我的猜测是,该设备不支持这种特定的采样率,但我在文档中没有看到任何关于我可以寻找什么对象的方法,以了解支持的采样率是多少 感谢所有帮助。是的,Android没有提供一个明确的方法来检查它,但是有一个解决方案,可以使用AudioRecord类的函数 pu

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

mrec.setAudioSamplingRate(44100);
当我把这行注释掉时,一切都很顺利。(我不确定它默认使用的速率)

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


感谢所有帮助。

是的,Android没有提供一个明确的方法来检查它,但是有一个解决方案,可以使用AudioRecord类的函数

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

        }
    }
}
如果选中函数描述,如果输入的参数之一不受支持,则函数描述将返回负值。假设您输入的所有其他输入都是有效的,如果不支持采样率,我们希望它返回负缓冲大小

但是,有些人报告说,即使不支持采样率,它也会返回正值,因此可以通过尝试初始化来执行附加检查,如果它认为无法处理该采样率,则会抛出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);

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

这不使用缓冲区大小作为测试,因为它不是绝对的。我在自己的华硕记事本上测试了上述解决方案,缓冲区大小测试将始终返回一个正整数,给出误报

第一种方法将测试通过的采样率,并根据设备是否支持采样率返回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
}

谢谢你的详细回答!我有点倾向于让它默认录制,以避免这种麻烦。你们知道我调用什么方法来找出*它默认选择了什么,如果我不重写它的话?我假设你们使用的是MediaRecorder类。如果不支持该速率,则prepare()调用将失败。你就是这样发现的。如果使用默认设置,我认为它将选择与媒体格式密切相关的一种,如下所述:。也许有一些外部库允许您在事后动态分析录制的音频,但我不知道Android定义的方法来了解它正在选择的采样率。相关:总是比不选择好:)唉,这些对
getProperty
的调用返回空字符串。我可能遗漏了什么。您正在运行的设备的API级别是多少?