Android AudioRecord Supported Sampling Rates
Asked Answered
H

8

40

I'm trying to figure out what sampling rates are supported for phones running Android 2.2 and greater. We'd like to sample at a rate lower than 44.1kHz and not have to resample.
I know that all phones support 44100Hz but was wondering if there's a table out there that shows what sampling rates are valid for specific phones. I've seen Android's documentation ( http://developer.android.com/reference/android/media/AudioRecord.html) but it doesn't help much.
Has anyone found a list of these sampling rates??

Hsinking answered 7/11, 2011 at 22:15 Comment(0)
M
62

The original poster has probably long since moved on, but I'll post this in case anyone else finds this question.

Unfortunately, in my experience, each device can support different sample rates. The only sure way of knowing what sample rates a device supports is to test them individually by checking the result of AudioRecord.getMinBufferSize() is non negative (which means there was an error), and returns a valid minimum buffer size.

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

        }
    }
}
Marie answered 10/2, 2012 at 6:55 Comment(2)
Does it exist any app which performs such test?Ostium
However, some people reported that it was returning positive even if the 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.Eclampsia
S
18

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.

Saintebeuve answered 11/3, 2014 at 5:45 Comment(3)
PROPERTY_OUTPUT_SAMPLE_RATE gives you the optimal sample rate for playback, not recording. As far as I can see, there is no method to obtain Audiorecord's optimal sample rate.Amandaamandi
@Anuj Jain , Why no method !? was meant audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);Cum
@aladin, from the documentation - PROPERTY_OUTPUT_SAMPLE_RATE is the native or optimal output sample rate for this device's primary output stream, in decimal Hz. So, not related to recording.Amandaamandi
S
13

Unfortunately not even all phones support the supposedly guaranteed 44.1kHz rate :(

I' ve been testing a Samsung GalaxyY (GT-S5360L) and if you record from the Camcorder source (ambience microphone), the only supported rates are 8kHz and 16kHz. Recording @ 44.1kHz produces utter garbage and @ 11.025kHz produces a pitch-altered recording with slightly less duration than the original sound.

Moreover, both strategies suggested by @Yahma and @Tom fail on this particular phone, as it is possible to receive a positive, minimum-buffer size from an unsupported configuration, and worse, I've been forced to reset the phone to get the audio stack working again, after attempting to use an AudioRecord class initialized from parameters that produce a supposedly valid, (non-exception raising) AudioTrack or AudioRecord instance.

I'm frankly a little bit worried at the problems I envision when releasing a sound-app to the wild. In our case, we are being forced to introduce a costly sample-rate-conversion layer if we expect to reuse our algorithms (expecting a 44.1kHz recording rate)on this particular phone model.

:(

Seeing answered 5/6, 2012 at 17:54 Comment(0)
S
3

I have a phone (Acer Z3) where I get a positive buffer size returned from AudioRecord.getMinBufferSize(...) when testing 11025 Hz. However, if I subsequently run

audioRecord = new AudioRecord(...);
int state = audioRecord.getState();
if (state != AudioRecord.STATE_INITIALIZED) ...

I can see that this sampling rate in fact does not represent a valid configuration (as pointed out by user1222021 on Jun 5 '12). So my solution is to run both tests to find a valid sampling rate.

Sievers answered 4/6, 2014 at 5:44 Comment(0)
A
3

This method gives the minimum audio sample rate supported by your device.

NOTE : You may reverse the for loop to get the maximum sample rate supported by your device (Don't forget to change the method name).

NOTE 2 : Though android doc says upto 48000(48khz) sample rate is supported ,I have added all the possible sampling rates (as in wikipedia) since who know new devices may record UHD audio in higher (sampling) framerates.

private int getMinSupportedSampleRate() {
    /*
     * Valid Audio Sample rates
     * 
     * @see <a
     * href="http://en.wikipedia.org/wiki/Sampling_%28signal_processing%29"
     * >Wikipedia</a>
     */
    final int validSampleRates[] = new int[] { 8000, 11025, 16000, 22050,
            32000, 37800, 44056, 44100, 47250, 48000, 50000, 50400, 88200,
            96000, 176400, 192000, 352800, 2822400, 5644800 };
    /*
     * Selecting default audio input source for recording since
     * AudioFormat.CHANNEL_CONFIGURATION_DEFAULT is deprecated and selecting
     * default encoding format.
     */
    for (int i = 0; i < validSampleRates.length; i++) {
        int result = AudioRecord.getMinBufferSize(validSampleRates[i],
                AudioFormat.CHANNEL_IN_DEFAULT,
                AudioFormat.ENCODING_DEFAULT);
        if (result != AudioRecord.ERROR
                && result != AudioRecord.ERROR_BAD_VALUE && result > 0) {
            // return the mininum supported audio sample rate
            return validSampleRates[i];
        }
    }
    // If none of the sample rates are supported return -1 handle it in
    // calling method
    return -1;
}
Almandine answered 29/4, 2015 at 15:20 Comment(3)
what does it returns? at least any error or crash log?Almandine
AudioFormat.CHANNEL_IN_DEFAULT, AudioFormat.ENCODING_DEFAULT can return not supported values for recorder. For example stereo, whyle most microphone are mono.Volnay
No idea if this works, but 99% sure 4800 should be 48000Spondaic
P
1

I'd like to provide an alternative to Yahma's answer.

I agree with his/her proposition that it must be tested (though presumably it varies according to the model, not the device), but using getMinBufferSize seems a bit indirect to me.

In order to test whether a desired sample rate is supported I suggest attempting to construct an AudioTrack instance with the desired sample rate - if the specified sample rate is not supported you will get an exception of the form:

"java.lang.IllegalArgumentException: 2756Hz is not a supported sample rate"

Pygmy answered 17/2, 2012 at 20:31 Comment(2)
That would work for AudioTrack, but the OP specifically stated he was using the AudioRecord API.Marie
It is an old question, but do you know if nowadays can I use 44100 for all devices? @PygmyUnlisted
O
0
    public  class Bigestnumber extends AsyncTask<String, String, String>{
        ProgressDialog pdLoading = new ProgressDialog(MainActivity.this);

        @Override
        protected String doInBackground(String... params) {
            final int validSampleRates[] = new int[]{
                    5644800, 2822400, 352800, 192000, 176400, 96000,
                    88200, 50400, 50000, 48000,47250, 44100, 44056, 37800, 32000, 22050, 16000, 11025, 4800, 8000};
            TrueMan = new ArrayList <Integer> ();
            for (int smaple : validSampleRates){
                if(validSampleRate(smaple) == true) {
                    TrueMan.add(smaple);
                }}


            return null;
        }
        @Override
        protected void onPostExecute(String result) {

            Integer largest = Collections.max(TrueMan);
            System.out.println("Largest   " + String.valueOf(largest));



        }

    }

   public 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;
        } finally {
            if(recorder != null)
                recorder.release();
        }
        return true;
    }

This Code will give you Max Supported Sample Rate on your Android OS. Just Declare ArrayList <Integer> TrueMan; in your beggining of the class. Then you can use high sample rate in AudioTrack and AudioRecord to get better sound quality. Reference.

Ozone answered 17/11, 2016 at 17:49 Comment(0)
L
0

Just some updated information here. I spent some time trying to get access to recording from the microphone to work with Android 6 (4.4 KitKat was fine). The error shown was the same as I got for 4.4 when using the wrong settings for sample rate/pcm etc. But my problem was in fact that the Permissions in AndroidManifest.xml are no longer sufficient to request access to the Microphone and in fact this now needs to be done run time: https://developer.android.com/training/permissions/requesting.html

Locale answered 20/6, 2017 at 8:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.