Android AudioRecord Поддерживаемые скорости выборки - PullRequest
32 голосов
/ 08 ноября 2011

Я пытаюсь выяснить, какие частоты дискретизации поддерживаются для телефонов под управлением Android 2.2 и выше.Мы бы хотели сэмплировать на частоте ниже 44,1 кГц и не нужно делать сэмплирование.Я знаю, что все телефоны поддерживают 44100 Гц, но мне было интересно, есть ли там таблица, показывающая, какие частоты дискретизации действительны для конкретных телефонов.Я видел документацию по Android (http://developer.android.com/reference/android/media/AudioRecord.html), но это мало помогает.Кто-нибудь нашел список этих частот дискретизации ??

Ответы [ 8 ]

56 голосов
/ 10 февраля 2012

Оригинальный постер, вероятно, уже давно перенесен, но я опубликую его на тот случай, если кто-нибудь еще найдет этот вопрос.

К сожалению, по моему опыту, каждое устройство может поддерживать разные частоты дискретизации.Единственный надежный способ узнать, какую частоту дискретизации поддерживает устройство, - это проверить их индивидуально, проверив, что результат 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

        }
    }
}
16 голосов
/ 11 марта 2014

Android имеет функцию AudioManager.getProperty() для получения минимального размера буфера и получения предпочтительной частоты дискретизации для аудиозаписи и воспроизведения.Но да, конечно, AudioManager.getProperty () недоступен на уровне API <17 </strong>.Вот пример кода для использования этого 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);

Хотя это поздний ответ, я подумал, что это может быть полезно.

13 голосов
/ 05 июня 2012

К сожалению, даже не все телефоны поддерживают предположительно гарантированную частоту 44,1 кГц: (

Я тестировал Samsung GalaxyY (GT-S5360L), и если вы производите запись с источника Camcorder (микрофон окружения)единственными поддерживаемыми частотами являются 8 кГц и 16 кГц. Запись при частоте 44,1 кГц приводит к полному мусору, а при частоте 11,025 кГц - записи с изменением высоты тона и меньшей продолжительностью, чем у исходного звука.

Более того, обе стратегии, предложенные @Yahmaи @Tom терпит неудачу на этом конкретном телефоне, так как возможно получить положительный минимальный размер буфера из неподдерживаемой конфигурации, и, что еще хуже, я был вынужден перезагрузить телефон, чтобы заставить аудио стек работать снова, после попыткииспользовать класс AudioRecord, инициализированный из параметров, которые производят предположительно действительный, (не исключая повышение) экземпляр AudioTrack или AudioRecord.

Честно говоря, я немного обеспокоен проблемами, которые я вижу, когдавыпуская звуковое приложение в дикую природу. В нашем случае мы вынужденытолько слой преобразования частоты дискретизации, если мы рассчитываем повторно использовать наши алгоритмы (ожидая частоту записи 44,1 кГц) на этой конкретной модели телефона.

: (

3 голосов
/ 04 июня 2014

У меня есть телефон (Acer Z3), где я получаю положительный размер буфера, возвращаемый из AudioRecord.getMinBufferSize (...) при тестировании 11025 Гц.Однако, если я впоследствии запусту

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

, я вижу, что эта частота выборки фактически не представляет допустимую конфигурацию (как указал user1222021 от 5 июня 12 июня).Поэтому мое решение состоит в том, чтобы запустить оба теста, чтобы найти действительную частоту дискретизации.

2 голосов
/ 29 апреля 2015

Этот метод дает минимальную частоту дискретизации звука, поддерживаемую вашим устройством.

ПРИМЕЧАНИЕ : Вы можете повернуть цикл for, чтобы получить максимальную частоту выборки, поддерживаемую вашим устройством (не забудьте изменить имя метода).

ПРИМЕЧАНИЕ 2 : Несмотря на то, что android doc говорит, что поддерживается частота дискретизации до 48000 (48 кГц), я добавил все возможные частоты дискретизации (как в википедии), так как кто знает, что новые устройства могут записывать аудио UHD в более высоком (выборка) частота кадров.

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;
}
2 голосов
/ 18 февраля 2012

Я бы хотел предоставить альтернативу ответу Яхмы.

Я согласен с его / ее предположением, что он должен быть протестирован (хотя, предположительно, он варьируется в зависимости от модели, а не устройства), но использование getMinBufferSize мне кажется немного косвенным.

ВЧтобы проверить, поддерживается ли желаемая частота дискретизации, я предлагаю попытаться создать экземпляр AudioTrack с желаемой частотой дискретизации - если указанная частота дискретизации не поддерживается, вы получите исключение в виде:

"java.lang.IllegalArgumentException: 2756 Гц не поддерживается частота дискретизации "

0 голосов
/ 20 июня 2017

Просто обновленная информация здесь.Я потратил некоторое время, пытаясь получить доступ к записи с микрофона для работы с Android 6 (4.4 KitKat был в порядке).Показанная ошибка была такой же, как я получил для 4.4 при использовании неправильных настроек для частоты дискретизации / шт.Теперь нужно сделать время выполнения: https://developer.android.com/training/permissions/requesting.html

0 голосов
/ 17 ноября 2016
    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;
    }

Этот код предоставит вам максимальную поддерживаемую частоту дискретизации в вашей ОС Android. Просто объявите ArrayList <Integer> TrueMan; в начале вашего класса. Затем вы можете использовать высокую частоту дискретизации в AudioTrack и AudioRecord, чтобы получить лучшее качество звука. Reference .

...