适配USB声卡的热插拔和播放录音基础功能

OH版本:5.0.0.71

RISC-V平板:SpacemiT MusePaper(8核AI CPU K1)

一. vendor层修改

1. alsa_adapter.json 添加USB声卡信息

{
    "adapters": [
        {
            "name": "primary",
            "cardId": 0,
            "cardName": "sndes8326"
        },
        {
            "name": "usb",
            "cardId": 1,
            "cardName": "C"
        }
    ]
}

2. audio_policy_config.xml 添加USB声卡播放录制属性

buffersize设置不对易出现无声音、杂音等问题,可根据aplay/arecord执行过程中cat声卡节点的hw_params确定,多数usb头戴式耳机为单声道需根据实际配置否则也会录音失败。

...
<audioPolicyConfiguration xmlns:xi="http://www.w3.org/2001/XInclude" version="1.0">
    <adapters>
        ...
        <adapter name="usb">
            <pipes>
                <pipe name="usb_output" role="output">
                    <paProp lib="libmodule-hdi-sink.z.so" role="sink" fixed_latency="0" render_in_idle_state="1" moduleName="Usb_arm_speaker"/>
                    <streamProps>
                        <streamProp format="s16le" sampleRates="44100" channelLayout="CH_LAYOUT_STEREO" bufferSize="24000"/>
                    </streamProps>
                    <attributes>
                        <attribute name="preload" value="true"/>
                    </attributes>
                </pipe>
                <pipe name="usb_input" role="input">
                    <paProp lib="libmodule-hdi-source.z.so" role="source" moduleName="Usb_arm_mic"/>
                    <streamProps>
                        <streamProp format="s16le" sampleRates="44100" channelLayout="CH_LAYOUT_MONO" bufferSize="19200"/>
                    </streamProps>
                </pipe>
            </pipes>
            <devices>
                <device name="Usb_Headset_Out" type="DEVICE_TYPE_USB_HEADSET" pin="PIN_OUT_USB_HEADSET" role="output" supportPipes="usb_output"/>
                <device name="Usb_Headset_In" type="DEVICE_TYPE_USB_HEADSET" pin="PIN_IN_USB_HEADSET" role="input" supportPipes="usb_input"/>
            </devices>
        </adapter>
        ...
    </adapters>
    ...
    <globalConfigs>
        <defaultOutput adapter="usb" pipe="usb_output" device="Usb_arm_speaker"/>
        ...
</audioPolicyConfiguration>

二、Base层修改

base\startup\init\ueventd\etc\ueventd.config

添加usb节点权限:

...
/dev/bus/usb/* 0666 0 0

出现类似报错需要上述修改:

三、HDI层修改

drivers\peripheral\audio\hdi_service\primary_impl\src\audio_adapter.c

CheckParaDesc函数中添加对USB声卡的PIN_OUT_USB_HEADSET支持

@@ -94,11 +94,11 @@ int32_t CheckParaDesc(const struct AudioDeviceDescriptor *desc, const char *type
 
     enum AudioPortPin pins = desc->pins;
     if (!strcmp(type, TYPE_CAPTURE)) {
-        if (pins == PIN_IN_MIC || pins == PIN_IN_HS_MIC || pins == PIN_IN_LINEIN) {
+        if (pins == PIN_IN_MIC || pins == PIN_IN_HS_MIC || pins == PIN_IN_LINEIN || PIN_OUT_USB_HEADSET) {
             return HDF_SUCCESS;
         }
     } else if (!strcmp(type, TYPE_RENDER)) {
-        if (pins == PIN_OUT_SPEAKER || pins == PIN_OUT_HEADSET || pins == PIN_OUT_LINEOUT || pins == PIN_OUT_HDMI
+        if (pins == PIN_OUT_SPEAKER || pins == PIN_OUT_HEADSET || pins == PIN_OUT_LINEOUT || pins == PIN_OUT_HDMI || PIN_OUT_USB_HEADSET
             || pins == (PIN_OUT_SPEAKER | PIN_OUT_HEADSET)) {
             return HDF_SUCCESS;
         }

四、audio_framework层修改

1.foundation/multimedia/audio_framework/services/audio_policy/server/src/service/audio_policy_service.cpp

使能isArmUsbDevice_进而进行后续adapter的初始化

@@ -3876,9 +3876,9 @@ int32_t AudioPolicyService::HandleSpecialDeviceType(DeviceType &devType, bool &i
         const std::string value = g_adProxy->GetAudioParameter("need_change_usb_device");
         IPCSkeleton::SetCallingIdentity(identity);
         AUDIO_INFO_LOG("get value %{public}s  from hal when usb device connect", value.c_str());
-        if (value == "false") {
+        // if (value == "false") {
             isArmUsbDevice_ = true;
-        }
+        // }
     }

2. 修复录音应用录制音频速度变快问题

foundation\multimedia\audio_framework\services\audio_service\server\src\capturer_in_server.cpp

@@ -32,7 +32,7 @@ namespace OHOS {
 namespace AudioStandard {
 namespace {
     static constexpr int32_t VOLUME_SHIFT_NUMBER = 16; // 1 >> 16 = 65536, max volume
-    static const size_t CAPTURER_BUFFER_DEFAULT_NUM = 4;
+    static const size_t CAPTURER_BUFFER_DEFAULT_NUM = 5;
     static const size_t CAPTURER_BUFFER_WAKE_UP_NUM = 100;
     static const uint32_t OVERFLOW_LOG_LOOP_COUNT = 100;
 }

foundation\multimedia\audio_framework\services\audio_service\server\src\pa_adapter_manager.cpp

@@ -33,7 +33,7 @@ namespace OHOS {
 namespace AudioStandard {
 const uint32_t CHECK_UTIL_SUCCESS = 0;
 const uint64_t BUF_LENGTH_IN_MSEC = 20;
-static const uint32_t PA_RECORD_MAX_LENGTH_NORMAL = 4;
+static const uint32_t PA_RECORD_MAX_LENGTH_NORMAL = 5;
 static const uint32_t PA_RECORD_MAX_LENGTH_WAKEUP = 30;
 static const int32_t CONNECT_STREAM_TIMEOUT_IN_SEC = 5; // 5S
 static const std::unordered_map<AudioStreamType, std::string> STREAM_TYPE_ENUM_STRING_MAP = {

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐