Android: как получить предпочтительный (собственный) размер аудиобуфера и частоту дискретизации звука в C/C++?

Чтобы получить предпочтительный размер аудиобуфера и частоту дискретизации звука для данного устройства Android, вы можете выполнить следующий код Java:

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

Можно ли сделать это на C/C++ вместо этого?

Если да, то как?

API openSLES, похоже, не предлагает эту функцию. Я заметил, что openSLES.h определяет структуру SLAudioInputDescriptor, а также SLAudioOutputDescriptor, но если это доступно на Android, я не уверен, как получить поддерживаемые частоты дискретизации микрофона и динамика. Кроме того, структура не содержит информации о предпочтительном размере буфера.


person user1884325    schedule 15.08.2015    source источник
comment
Я работал с OpenSL раньше, и мне нужно было то же самое, что и вам. Было бы лучше, если бы мы могли получить предпочтительную частоту дискретизации на собственной стороне, поскольку API Java поддерживает уровень API 17 или выше. Поэтому я опубликовал точную проблему, а затем решил ее сам. Вы также можете посмотреть на этот вопрос и ответить на него. Это может вам помочь, если у вас похожая ситуация. stackoverflow.com/questions/22342040/   -  person Reaz Murshed    schedule 07.02.2016
comment
SLAudioOutputDescriptor и SLAudioInputDescriptor не реализованы в Android. Ответ Реаза выглядит как хорошее резюме текущих передовых практик.   -  person Ian Ni-Lewis    schedule 13.05.2016


Ответы (1)


Конечно, это не часть OpenSL ES API, эти параметры специфичны для Android и являются частью ОС Android.

К сожалению, я не нашел способа получить эти параметры непосредственно в нативном коде. В итоге я вызывал функции Java через JNI.

Вот псевдокод:

    jclass audioSystem = env->FindClass("android/media/AudioSystem");
    jmethodID method = env->GetStaticMethodID(audioSystem, "getPrimaryOutputSamplingRate", "()I");
    jint nativeOutputSampleRate = env->CallStaticIntMethod(audioSystem, method);
    method = env->GetStaticMethodID(audioSystem, "getPrimaryOutputFrameCount", "()I");
    jint nativeBufferLength = env->CallStaticIntMethod(audioSystem, method);

Добавьте обработку ошибок, как вы хотите.

person Over17    schedule 19.02.2016
comment
Конечно, я бы не стал говорить, но это правда, что вызовы Java — единственный способ получить эту информацию. - person Ian Ni-Lewis; 13.05.2016