How can I find out what Sampling rates are supported on my tablet?

10,784

Solution 1

Yes, Android does not provide an explicit method to check it but there is a work-around with AudioRecord class' getMinBufferSize function.

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

        }
    }
}

If you checked the function description, it will return a negative value if one of the parameters entered are not supported. Assuming you enter all other inputs as valid, we are expecting it to return a negative buffersize if sample rate is not supported.

However, some people reported that it was returning positive even if sampling rate is not supported so an additional check could be done by trying to initialize an AudioRecord object, which will throw an IllegalArgumentException if it thinks it cannot deal with that sampling rate.

Finally, none of them provide a guaranteed check but using both increases your chances of getting the supported one.

Most of the time, 44100 and 48000 work for me but of course, it differs from device to device.

Solution 2

Android has AudioManager.getProperty() function to acquire minimum buffer size and get the preferred sample rate for audio record and playback. But yes of course, AudioManager.getProperty() is not available on API level < 17. Here's an example code sample on how to use this 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);

Though its a late answer, I thought this might be useful.

Solution 3

This does not use the buffer size as a test as it is not absolute. I tested said solution on my own ASUS MemoPad and the buffer size test will always return a positive integer, giving false positives.

The first method will test a passed sample rate and return true or false depending on whether or not the sample rate is supported by the device or not. The second method will iterate through a given list and return the maximum valid sampling rate (first in the list that is valid) - can be changed easily for other heuristics.

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
}
Share:
10,784
Yevgeny Simkin
Author by

Yevgeny Simkin

I fled Soviet Russia as a child and have spent my life bouncing from music to comedy to software engineering. You can follow my comedy Twitter feed here. I'm also the founder and CEO of The Russian Mob™—an agency specializing in developing SAAS, Mobile, AR, VR, and Web applications. (No: we won’t help you hack a foreign election so don’t bother asking.) On occasion, things that I think are published over at The Bulwark, which you should be reading, even if my ideas weren't being published there. If you would like to connect with me, the easiest way is through LinkedIn.

Updated on July 13, 2022

Comments

  • Yevgeny Simkin
    Yevgeny Simkin almost 2 years

    I have an app that works perfectly on a bunch of devices (Xoom, Xyboard, etc) but that fails at this line on the Galaxy 10.1

    mrec.setAudioSamplingRate(44100);
    

    When I comment this line out, everything works swimmingly. (I'm not sure what rate it uses by default).

    My guess is that the device doesn't support this particular sample rate, but I'm not seeing anything in the docs for what method of what Object I can look to, to find out what the supported sample rates are.

    All help appreciated.