• Android/Automotive 多声道录音支持


    1. 内核驱动

    2.  系统配置

    2.1  配置文件

    AF 查找HW DEV可以看出,优先PRIMARY接口

    1. AudioFlinger.cpp
    2. static const char * const audio_interfaces[] = {
    3.     AUDIO_HARDWARE_MODULE_ID_PRIMARY,
    4.     AUDIO_HARDWARE_MODULE_ID_A2DP,
    5.     AUDIO_HARDWARE_MODULE_ID_USB,
    6. };

    配置Configure文件路径: /vendor/etc/audio/audio_policy_configuration.xml

    为什么是这个文件名称,APM代码有描述:

    1. APM_AudioPolicyManager.cpp:
    2. #define AUDIO_POLICY_XML_CONFIG_FILE_PATH_MAX_LENGTH 128
    3. #define AUDIO_POLICY_XML_CONFIG_FILE_NAME "audio_policy_configuration.xml"
    4. static status_t deserializeAudioPolicyXmlConfig(AudioPolicyConfig &config) {
    5. char audioPolicyXmlConfigFile[AUDIO_POLICY_XML_CONFIG_FILE_PATH_MAX_LENGTH];
    6. std::vector<const char*> fileNames;
    7. status_t ret;
    8. if (property_get_bool("ro.bluetooth.a2dp_offload.supported", false)) {
    9. if (property_get_bool("persist.bluetooth.bluetooth_audio_hal.disabled", false) &&
    10. property_get_bool("persist.bluetooth.a2dp_offload.disabled", false)) {
    11. // Both BluetoothAudio@2.0 and BluetoothA2dp@1.0 (Offlaod) are disabled, and uses
    12. // the legacy hardware module for A2DP and hearing aid.
    13. fileNames.push_back(AUDIO_POLICY_BLUETOOTH_LEGACY_HAL_XML_CONFIG_FILE_NAME);
    14. } else if (property_get_bool("persist.bluetooth.a2dp_offload.disabled", false)) {
    15. // A2DP offload supported but disabled: try to use special XML file
    16. fileNames.push_back(AUDIO_POLICY_A2DP_OFFLOAD_DISABLED_XML_CONFIG_FILE_NAME);
    17. }
    18. } else if (property_get_bool("persist.bluetooth.bluetooth_audio_hal.disabled", false)) {
    19. fileNames.push_back(AUDIO_POLICY_BLUETOOTH_LEGACY_HAL_XML_CONFIG_FILE_NAME);
    20. }
    21. fileNames.push_back(AUDIO_POLICY_XML_CONFIG_FILE_NAME);

    2.2  修改

     如上可以看出channelMasks 配置缺少多声道

    修改后://增加四声道

    注:source理解为发送端,sink理解为接受端 

    3. APP方法

    3.1 使用AudioRecord原生接口:

    为了从设备获取超过两个声道的音频,使用一个通到索引掩码:channelIndexMask

    1. final AudioFormat audioFormat=new AudioFormat.Builder()
    2. .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
    3. .setSampleRate(44100)
    4. .setChannelIndexMask(0xf/*4 channels,0...3*/)
    5. .build();
    6. final AudioRecord audioRecord = new AudioRecord.Builder()
    7. .setAudioFormat(audioFormat)
    8. .build();

    AudioFormat.java  代码setChannelIndexMask 接口如下:

     

    注意:当setChannelMask和setChannelIndexMask都设置的时候,AudioRecord只是用setChannleMask的值(最大为两个通道)。

    System/media/audio/include/system/audio-base.h针对AUDIO_CHANNEL_INDEX定义如下:

     

    3.2 使用AAudio接口:

    AAudio 是Android为解决声音延时的高效Native接口,Andriod系统标配,目前大量使用在公网对讲机,语音对讲,Voip,RTC项目中。

    1. #include
    2. result = AAudio_createStreamBuilder(&inputBuilder);
    3. if (result != AAUDIO_OK) {
    4. LOGE("%s create Stream inputBuilder failed", __func__);
    5. }
    6. AAudioStreamBuilder_setDirection(inputBuilder, AAUDIO_DIRECTION_INPUT); //设置流的方向
    7. AAudioStreamBuilder_setDeviceId(inputBuilder, AAUDIO_UNSPECIFIED);
    8. AAudioStreamBuilder_setSampleRate(inputBuilder, 48000);
    9. AAudioStreamBuilder_setChannelCount(inputBuilder, 4);//设置channel->4
    10. AAudioStreamBuilder_setFormat(inputBuilder, AAUDIO_FORMAT_PCM_I16);
    11. AAudioStreamBuilder_setPerformanceMode(inputBuilder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
    12. //数据回调
    13. AAudioStreamBuilder_setDataCallback(inputBuilder, inDataCallback, this);
    14. //create input stream
    15. result = AAudioStreamBuilder_openStream(inputBuilder, &inputStream);
    16. if (result != AAUDIO_OK) {
    17. LOGE("%s open inputStream failed", __func__);
    18. }
    19. result = AAudioStream_requestStart(inputStream);
    20. if (result != AAUDIO_OK) {
    21. LOGE("%s inputStream request Start failed", __func__);
    22. }
    23. //数据分析:
    24. aaudio_data_callback_result_t inDataCallback(
    25.         AAudioStream *stream,
    26.         void *userData,
    27.         void *audioData,
    28.         int32_t numFrames) {
    29. //note 1. 16bit->2bytes * channel->4,所以这里每帧是8个字节
    30.     memcpy(buffer, audioData, numFrames *8);//AudioCapure数据
    31.     return AAUDIO_CALLBACK_RESULT_CONTINUE;
    32. }

  • 相关阅读:
    【解锁未来】探索Web3的无限可能性-01
    软件项目管理 4.3.敏捷需求建模方法
    vector向量类使用
    Word处理控件Aspose.Words功能演示:在 Python 中比较两个 Word 文档
    【第十篇】- Maven 引入外部依赖
    数字先锋 | 教育资源乘云而来!46万城乡学子共享名师课堂
    【JAVA】java常见面试题——持续更新
    如何配置 logback?30分钟让你彻底学会代码熬夜敲
    7-39 计算阶乘和
    【Python】简记操作:Centos安装、卸载、升级Python运行环境
  • 原文地址:https://blog.csdn.net/liaochaoyun/article/details/126260094