Android 7.1 系统裁剪、定制化实践 snd

编程入门 行业动态 更新时间:2024-10-13 22:20:38

Android 7.1 <a href=https://www.elefans.com/category/jswz/34/1770742.html style=系统裁剪、定制化实践 snd"/>

Android 7.1 系统裁剪、定制化实践 snd

背景描述:

此篇是对《Android音频框架之一 详解audioPolicy流程及HAL驱动加载》、《Android音频框架之二 用户录音启动流程源码走读》 和
《Android音频框架之三 用户录音启动流程源码走读 startRecord》的延续内容;本篇描述是 android7.1 源码中,如果增加 TinyAlsaHAL
的源码,并配置 Android 系统启动和加载库项目,移植 tinyalsa 至 hikey960-Androi7.1 平台,以完成这个系列博文所实现的功能。

Android 7.0 引入了一种新的音频政策配置文件格式 (XML),用于描述音频拓扑,Android 7.0 弃用了 audio_policy.conf,并增加了
对使用 XML 文件格式来定义音频拓扑的支持,这种文件格式更通俗易懂,具有多种编辑和解析工具,并且足够灵活,可以描述复杂的音频拓扑。

第一步 配置 audio_policy_configuration.xml 模式有效

1.1> Android7.1-RK3288 配置方法:

开启 USE_XML_AUDIO_POLICY_CONF 功能,并把配置文件内容拷贝至系统文件系统

@ device/rockchip/rk3288/device.mk 
## config audio policy by ljb
USE_XML_AUDIO_POLICY_CONF := 1
PRODUCT_COPY_FILES += frameworks/av/services/audiopolicy/config/audio_policy_configuration.xml:system/etc/audio_policy_configuration.xml\
frameworks/av/services/audiopolicy/config/a2dp_audio_policy_configuration.xml:system/etc/a2dp_audio_policy_configuration.xml\
frameworks/av/services/audiopolicy/config/usb_audio_policy_configuration.xml:system/etc/usb_audio_policy_configuration.xml\
frameworks/av/services/audiopolicy/config/r_submix_audio_policy_configuration.xml:system/etc/r_submix_audio_policy_configuration.xml\
frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:system/etc/audio_policy_volumes.xml\
frameworks/av/services/audiopolicy/config/default_volume_tables.xml:system/etc/default_volume_tables.xml

添加库文件及调试工具的支持

@ device/rockchip/common/device.mk 
# audio lib
PRODUCT_PACKAGES += \audio_policy.$(TARGET_BOARD_HARDWARE) \audio.primary.$(TARGET_BOARD_HARDWARE) \audio.r_submix.default\libaudioroute# audio lib
PRODUCT_PACKAGES += \libasound \alsa.default \acoustics.default \libtinyalsa \tinymix \tinyplay \tinycap \tinypcminfo

1.2> Android8.1-hikey960 配置方法:

@ device/linaro/hikey/hikey960/device-hikey960.mk
增加如下配置内容

# Build HiKey960 HDMI audio HAL. Experimental only may not work. FIXME
USE_XML_AUDIO_POLICY_CONF := 1
PRODUCT_COPY_FILES += frameworks/av/services/audiopolicy/config/audio_policy_configuration.xml:system/etc/audio_policy_configuration.xml\
frameworks/av/services/audiopolicy/config/a2dp_audio_policy_configuration.xml:system/etc/a2dp_audio_policy_configuration.xml\
frameworks/av/services/audiopolicy/config/usb_audio_policy_configuration.xml:system/etc/usb_audio_policy_configuration.xml\
frameworks/av/services/audiopolicy/config/r_submix_audio_policy_configuration.xml:system/etc/r_submix_audio_policy_configuration.xml\
frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:system/etc/audio_policy_volumes.xml\
frameworks/av/services/audiopolicy/config/default_volume_tables.xml:system/etc/default_volume_tables.xml# audio.primary configuration
PRODUCT_PACKAGES += audio.primary.$(TARGET_BOARD_PLATFORM)\audio.r_submix.default# TinyAlsaHAL configuration
PRODUCT_PACKAGES += \libasound \libaudioroute \alsa.default \acoustics.default \libtinyalsa \tinymix \tinyplay \tinycap \tinypcminfo

第二处 修改 BOARD_USES_ALSA_AUDIO 有效
@ device/linaro/hikey/BoardConfigCommon.mk

#BOARD_USES_GENERIC_AUDIO := true     # 关闭 GENERIC_AUDIO
BOARD_USES_ALSA_AUDIO := true         # 开启 ALSA_AUDIO 

第二步 修改音频配置文件

用文件夹中audio_policy_configuration.xml文件,把此文件覆盖
@ frameworks/av/services/audiopolicy/config/audio_policy_configuration.xml
文件。
配置文件内容如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><audioPolicyConfiguration version="1.0" xmlns:xi=""><!-- version section contains a “version” tag in the form “major.minor” e.g version=”1.0” --><!-- Global configuration Decalaration --><globalConfiguration speaker_drc_enabled="true"/><modules><!-- Primary Audio HAL --><module name="primary" halVersion="2.5"><attachedDevices><item>Speaker</item><item>Remote Submix Out</item><item>Built-In Mic</item><item>Remote Submix In</item></attachedDevices><defaultOutputDevice>Speaker</defaultOutputDevice><!-- “mixPorts”: listing all output and input streams exposed by the audio HAL --><mixPorts><mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY"><profile name="" format="AUDIO_FORMAT_PCM_16_BIT"samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/></mixPort><mixPort name="primary input" role="sink"><profile name="" format="AUDIO_FORMAT_PCM_16_BIT"samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"channelMasks="AUDIO_CHANNEL_IN_STEREO"/></mixPort><!-- r_submix --><mixPort name="r_submix output" role="source"><profile name="" format="AUDIO_FORMAT_PCM_16_BIT"samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/></mixPort><mixPort name="r_submix input" role="sink"><profile name="" format="AUDIO_FORMAT_PCM_16_BIT"samplingRates="44100,48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/></mixPort></mixPorts><!-- “devicePorts”: a list of device descriptors for all input and output devices accessible via this module. --><devicePorts><!-- Output devices declaration, i.e. Sink DEVICE PORT --><devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address=""><profile name="" format="AUDIO_FORMAT_PCM_16_BIT"samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/><gains><gain name="gain_1" mode="AUDIO_GAIN_MODE_JOINT"minValueMB="-8400"maxValueMB="4000"defaultValueMB="0"stepValueMB="100"/></gains></devicePort><devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source"><profile name="" format="AUDIO_FORMAT_PCM_16_BIT"samplingRates="44100,48000"channelMasks="AUDIO_CHANNEL_IN_STEREO"/></devicePort><!-- add remote deviceport by ljb --><devicePort tagName="Remote Submix Out" role="sink" type="AUDIO_DEVICE_OUT_REMOTE_SUBMIX"><profile name="" format="AUDIO_FORMAT_PCM_16_BIT"samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/></devicePort><devicePort tagName="Remote Submix In" type="AUDIO_DEVICE_IN_REMOTE_SUBMIX" role="source"><profile name="" format="AUDIO_FORMAT_PCM_16_BIT"samplingRates="44100,48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/></devicePort></devicePorts><!-- route declaration, i.e. list all available sources for a given sink --><routes><route type="mix" sink="Speaker"sources="primary output"/>          <route type="mix" sink="primary input"sources="Built-In Mic"/><!-- r_submix route --><route type="mix" sink="Remote Submix Out"sources="r_submix output"/><route type="mix" sink="r_submix input"sources="Remote Submix In"/></routes></module></modules><!-- End of Modules section --><!-- Volume section --><xi:include href="audio_policy_volumes.xml"/><xi:include href="default_volume_tables.xml"/><!-- End of Volume section --></audioPolicyConfiguration>

第三步 移植TinyAlsaHAL 声卡驱动

在安卓系统源码中,把 device/linaro/hikey/audio 路径下文件夹内容清除掉,
把此文件夹下 audio.tar.bz2 文件解压至 device/linaro/hikey/ 路径下。
audio文件夹中 Android.mk 配置内容如下:

# Copyright (C) 2012 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      .0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := audio.primary.$(TARGET_BOARD_PLATFORM)
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_SRC_FILES := \audio_setting.c \audio_bitstream.c \audio_hw.c \alsa_route.c \alsa_mixer.c \voice_preprocess.c \audio_hw_hdmi.cLOCAL_C_INCLUDES += \external/tinyalsa/include \$(call include-path-for, audio-utils) \$(call include-path-for, audio-route) \$(call include-path-for, speex)LOCAL_CFLAGS := -Wno-unused-parameterifeq ($(AUD_VOICE_CONFIG),voice_support)
LOCAL_CFLAGS += -DVOICE_SUPPORT
endifLOCAL_CFLAGS += -Wno-error
LOCAL_SHARED_LIBRARIES := liblog libcutils libtinyalsa libaudioutils libaudioroute libhardware_legacy libspeexresampler
LOCAL_STATIC_LIBRARIES := libspeex
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)include $(CLEAR_VARS)
LOCAL_CFLAGS += -Wno-error
LOCAL_SRC_FILES:= amix.c alsa_mixer.c
LOCAL_MODULE:= amix
LOCAL_PROPRIETARY_MODULE := true
LOCAL_SHARED_LIBRARIES := liblog libc libcutils
LOCAL_MODULE_TAGS:= debug
include $(BUILD_EXECUTABLE)

此 TinyAlsaHAL 中的 audio_hw.c 文件中;
此源码在RK3288平台上实现TinyAlsaHAL基础上修改如下:

@ hardware/rockchip/audio/tinyalsa_hal/audio_hw.c 
static int start_input_stream(struct stream_in *in)
{struct audio_device *adev = in->dev;int  ret = 0;//ALOGV("Debug_dump_info: %s : %d , in->device: 0x%04x \n ", __func__, __LINE__, in->device);ALOGD("Debug_dump_info: %s : %d enter process", __func__, __LINE__ );in_dump(in, 0);route_pcm_open(getRouteFromDevice(in->device | AUDIO_DEVICE_BIT_IN));if(in->input_source == 0x08){ //> 修改对 Remote_submix 类型支持ALOGD("Debug_dump_info: %s : %d ,PCM_CARD:%d PCM_DEVICE:%d PCM_IN:%d ", __func__, __LINE__, PCM_CARD, PCM_DEVICE_SCO, PCM_IN);in->pcm = pcm_open(PCM_CARD, PCM_DEVICE_SCO, PCM_IN, in->config);}else{ALOGD("Debug_dump_info: %s : %d ,PCM_CARD:%d PCM_DEVICE:%d PCM_IN:%d ", __func__, __LINE__, PCM_CARD, PCM_DEVICE, PCM_IN);in->pcm = pcm_open(PCM_CARD, PCM_DEVICE, PCM_IN, in->config);}if (in->pcm && !pcm_is_ready(in->pcm)) {ALOGE("Debug_dump_info: pcm_open() failed: %s", pcm_get_error(in->pcm));pcm_close(in->pcm);return -ENOMEM;}/* if no supported sample rate is available, use the resampler */if (in->resampler)in->resampler->reset(in->resampler);in->frames_in = 0;adev->input_source = in->input_source;adev->in_device = in->device;adev->in_channel_mask = in->channel_mask;ALOGD("Debug_dump_info: %s : %d , sourceType: %4x \n ", __func__, __LINE__, in->input_source);if (in->device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)start_bt_sco(adev);/* initialize volume ramp */in->ramp_frames = (CAPTURE_START_RAMP_MS * in->requested_rate) / 1000;in->ramp_step = (uint16_t)(USHRT_MAX / in->ramp_frames);in->ramp_vol = 0;;ALOGD("Debug_dump_info: %s : %d exit process", __func__, __LINE__ );return 0;
}

笔者在源码中修改对 Remote_submix 输入源类型支持,对应的声卡和PCM_DEVICE如源码中描述,读者如不是很了解对应关系,
请参考《ubuntu 20 使用命令行 snd-aloop 实现内录音、录制音乐播放器的音频》 博文内容,snd-aloop声卡驱动配置文件中,
已经指定此 PCM_DEVICE 为 1 时,通过 snd-aloop驱动获取的音频数据,就是系统播放音频内容。

第四步 修改源码

修改 @frameworks/av/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp 文件内容如下:

status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,audio_io_handle_t *input,audio_session_t session,pid_t pid,uid_t uid,uint32_t samplingRate,audio_format_t format,audio_channel_mask_t channelMask,audio_input_flags_t flags,audio_port_handle_t selectedDeviceId)
{if (mAudioPolicyManager == NULL) {return NO_INIT;}... //省略部分代码{Mutex::Autolock _l(mLock);// the audio_in_acoustics_t parameter is ignored by get_input()status = mAudioPolicyManager->getInputForAttr(attr, input, session, uid,samplingRate, format, channelMask,flags, selectedDeviceId,&inputType);audioPolicyEffects = mAudioPolicyEffects;ALOGD("Debug_dump_info: %s,%d Status:%d ", __func__, __LINE__, status);if (status == NO_ERROR) {// enforce permission (if any) required for each type of inputswitch (inputType) {case AudioPolicyInterface::API_INPUT_LEGACY:break;case AudioPolicyInterface::API_INPUT_TELEPHONY_RX:// FIXME: use the same permission as for remote submix for now.case AudioPolicyInterface::API_INPUT_MIX_CAPTURE:if (!captureAudioOutputAllowed(pid, uid)) {//> close this code by ljb 2022-3-14,屏蔽下面两条代码//ALOGE("Debug_dump_info: getInputForAttr() permission denied: capture not allowed");//status = PERMISSION_DENIED;}break;case AudioPolicyInterface::API_INPUT_MIX_EXT_POLICY_REROUTE:if (!modifyAudioRoutingAllowed()) {ALOGE("Debug_dump_info: getInputForAttr() permission denied: modify audio routing not allowed");status = PERMISSION_DENIED;}break;case AudioPolicyInterface::API_INPUT_INVALID:default:LOG_ALWAYS_FATAL("getInputForAttr() encountered an invalid input type %d",(int)inputType);break;}ALOGD("Debug_dump_info: %s,%d Status:%d ", __func__, __LINE__, status);}if (status != NO_ERROR) {ALOGD("Debug_dump_info: %s,%d Status:%d ", __func__, __LINE__, status);if (status == PERMISSION_DENIED) {mAudioPolicyManager->releaseInput(*input, session);}return status;}}

此源码仅屏蔽权限授权部分,其他未做修改。

case AudioPolicyInterface::API_INPUT_MIX_CAPTURE:if (!captureAudioOutputAllowed(pid, uid)) {//> close this code by ljb 2022-3-14,屏蔽下面两条代码//ALOGE("Debug_dump_info: getInputForAttr() permission denied: capture not allowed");//status = PERMISSION_DENIED;}break;

第五步 编译验证

在 android8.1 源码中,设备选择 hikey960 来验证此部分功能, Android 源码编译成功,
因笔者的安卓8.1镜像是运行在容器中,实际测试情况待时间方便会分享那部分内容。
在 android7.1 系统 rk3288 平台笔者已经成功实现此功能,第一步 中相关修改就是基于
实验成功基础上。

更多推荐

Android 7.1 系统裁剪、定制化实践 snd

本文发布于:2024-02-24 15:50:48,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1695830.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:系统   Android   snd

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!