一种Android系统双屏异显的两路音频实现方法

技术领域
[0001]
本发明涉及一种Android系统双屏异显的两路音频实现方法。
背景技术
[0002]
关于Android系统的双屏异显两路音频的实现目前还没有通用的方法,Android系
统的双屏异显两路音频的需求是:主屏的声音从主屏对应的声卡输出、副屏的声音从副屏
对应声卡输出,不能有混音。
[0003]
如图1所示,现有的Android系统音频整个框架包括应用层APP、framework层、lib
层、hal层、驱动以及硬件。
[0004]
应用层APP,这是整个音频体系的最上层,因而并不是Android系统实现异显两路
音频输出的重点。比如厂商根据特定需求自己写的一个音乐播放器,游戏中使用到声音,或
者调节音频的一类软件等等。
[0005]
Framework层,Android提供了两个功能类,AudioTrack和AudioRecorder;除此以
外,A nd r o id系统还为我们控制音频系统提供了 A ud i o Ma na g e r、A ud i o Se r v i c e及
AudioSystem类。这些都是framework为便利上层应用开发所设计的。
[0006]
Libraries层,framework层的很多类,实际上只是应用程序使用Android库文件的
" 中介 " 而已。因为上层应用采用java语言编写,它们需要最直接的java接口的支持,这就是
framework层存在的意义之一。而作为 " 中介 " ,它们并不会真正去实现具体的功能,或者只
实现其中的一部分功能 ,而把主要重心放在库中来完成。比如上面的 A ud i o T ra c k、
AudioRecorder等等在库中都能找到相对应的类,这些库多数是C++语言编写的。除了上面
的类库实现外,音频系统还需要一个 " 核心中控 " ,或者用Android中通用的实现来讲,需要
一个系统服务,这就是AudioFlinger和AudioPolicyService。
[0007]
HAL层,从设计上来看,硬件抽象层是AudioFlinger直接访问的对象。这说明了两
个问题,一方面AudioFlinger并不直接调用底层的驱动程序;另一方面,AudioFlinger上层
(包括和它同一层的MediaPlayerService)的模块只需要与它进行交互就可以实现音频相
关的功能了。因而我们可以认为AudioFlinger是Android音频系统中真正的 " 隔离板 " ,无论
下面如何变化,上层的实现都可以保持兼容。音频方面的硬件抽象层主要分为两部分,即
AudioFlinger和AudioPolicyService。实际上后者并不是一个真实的设备,只是采用虚拟
设备的方式来让厂商可以方便地定制出自己的策略。抽象层的任务是将AudioFlinger/
AudioPolicyService真正地与硬件设备关联起来,但又必须提供灵活的结构来应对变
化------特别是对于Android这个更新相当频繁的系统。比如以前Android系统中的Audio系
统依赖于alsa - lib,但后期就变为了tinyalsa,这样的转变不应该对上层造成破坏。因而
AudioHAL提供了统一的接口来定义它与AudioFlinger/AudioPolicyService之间的通信方
式,这就是audio_hw_device、audio_stream_in及audio_stream_out等等存在的目的,这些
S t r u c t数据类型内部大多只是函数指针的定义 ,是一些 " 壳 " 。当 A u d i o F l i n g e r /
AudioPolicyService初始化时,它们会去寻找系统中最匹配的实现(这些实现驻留在以
说 明 书
1/9 页
4
CN 108132771 A
4 audio .primary .* ,audio .a2dp .*为名的各种库中)来填充这些 " 壳 " 。根据产品的不同,音频
设备存在很大差异,在Android的音频架构中,这些问题都是由HAL层的audio .primary等等
库来解决的,而不需要大规模地修改上层实现。换句话说,厂商在定制时的重点就是如何提
供这部分库的高效实现了。
[0008]
本发明是基于Android系统的双屏异显两路音频的需求以及现有的Android系统
音频整个框架,来实现两路音频输出的。
发明内容
[0009]
本发明要解决的技术问题,在于提供一种Android系统双屏异显的两路音频实现
方法,从而弥补了Android系统的双屏异显两路音频输出的空白。
[0010]
本发明是这样实现的:一种Android系统双屏异显的两路音频实现方法,包括进入
双屏模式过程、播放音频过程和退出双屏模式过程;
[0011]
所述进入双屏模式过程包括:
[0012]
步骤S11、响应用户操作而进入双屏模式,首先模拟上报声卡插入事件;
[0013]
步骤S12、在AudioManager打开第二个声卡;
[0014]
步骤S13、在AudioFlinger创建新的PlaybackThread;
[0015]
所述播放音频过程包括;
[0016]
步骤S21、App要播放声音前先判断是否是主屏播放声音,若是进入步骤S22,若否,
进入步骤S23;
[0017]
步骤S22、设置主屏声音的streamType,根据streamType在第一个声卡播放声音;
[0018]
步骤S23、设置副屏声音的streamType,根据streamType在第二个声卡播放声音;
[0019]
所述退出双屏模式过程包括:
[0020]
步骤S31、响应用户操作而退出双屏模式,首先模拟上报声卡断开事件;
[0021]
步骤S32、在AudioManager关闭第二个声卡;
[0022]
步骤S33、在AudioFlinger销毁第二个PlaybackThread,结束。
[0023]
进 一 步 的 ,所 述 步 骤 S 1 2 实 现 之 前 需 是 在 P h o n e W i n d o w . j a v a 的
superDispatchKeyEvent里面预先添加force_speaker广播,并设置media .audio .device_
policy .db的属性,异显状态下设置该属性为 " speaker " ,同显状态设置该属性为 " hdmi " ,然
后在InputManagerService .java的start里面接收广播,收到广播后,触发耳机线控事件。
[0024]
进一步的,所述步骤S12具体是:系统声音默认从hdmi输出,当switchValues为0
时,mHeadState的状态设置成BIT_HDMI_AUDIO;当switchValues的值为1时,mHeadState的
状态设置包括BIT_HDMI_AUDIO和BIT_USB_HEADSET_DGTL,目的是同时打开hdmi和speaker
两路输出,这种情况会触发AudFlinger中的openDuplicateOutput创建两个MixerThread,
从而打开第二个声卡。
[0025]
进一步的 ,所述步骤 S 21中 ,所述 A p p判断是否是主屏播放声音是通过判断
media .audio .device_policy .db的属性来实现,若该属性为 " speaker " ,则判断为异显状
态,若该属性为 " hdmi " ,则判断为同显状态。
[0026]
进一步的,本发明方法还包括主副屏切换过程,所述主副屏切换过程是:
[0027]
系统默认从hdmi输出,同屏时声音也从hdmi输出;异显时,副屏的声音从speaker
说 明 书
2/9 页
5
CN 108132771 A
5 输 出 ,主 屏的 声 音 从 h d m i 输 出 ;首 先 获 取 副 屏 上 a c t i v i t y 的 p i d ,并 设 置 为
" media .audio .activity .pid " 属性的值,同屏时,属性值设置为 - 1
[0028]
在moveTransitionToSecondDisplay中添加
[0029]
SystemProperties .set ("media .audio .activity .pid" ,String .valueOf
(win .mSession .mPid));
[0030]
在updateDisplayShowSynchronization中添加
[0031]
SystemProperties .set("media .audio .activity .pid" ,String .valueOf( - 1));
[0032]
在audiopolicy的Engine .cpp的getDeviceForStrategyInt中添加
[0033]
返回AUDIO_DEVICE_OUT_WIRED_HEADSET表示声音最终从speaker输出;
[0034]
返回AUDIO_DEVICE_OUT_AUX_DIGITAL表示声音最终从hdmi输出。
[0035]
进一步的,本发明方法还包括输出设备的修改过程:
[0036]
修改的文件路径:/device/rockchip/common/audio_policy_rk30board .conf
[0037]
修改的内容包括:
[0038]
(1)更改全局配置里的输出设备,由AUDIO_DEVICE_OUT_SPEAKER改为AUDIO_
DEVICE_OUT_AUX_DIGITAL;
[0039]
(2)更改primary默认输出设备;
[0040]
(3)添加dgtl输出。
[0041]
进一步的,本发明方法还包括增加dgtl库:
[0042]
复制hardware/rockchip/audio/tinyalsa_hal到hardware/rockchip/audio/
tinyalsa_hal_dgtl,并修改Android .mk;
[0043]
将audio_hw .c中connect_hdmi的值改为false,屏蔽hdmi;
[0044]
编译生成audio .dgtl .rk30board .so;
[0045]
最终,如果输出要求是hdmi,AudioFlinger会调用audio .dgtl .primary .so;如果
输出要求是speaker,AudioFlinger会调用audio .dgtl .rk30board .so。
[0046]
本发明具有如下优点:本发明方法通过软件和硬件上的设置,使主屏的声音从主
屏对应的声卡输出、副屏的声音从副屏对应声卡输出,最终实现了Android系统双屏异显的
两路音频输出,填补了这一技术领域的空白。
附图说明
[0047]
下面参照附图结合实施例对本发明作进一步的说明。
[0048]
图1为现有的Android系统的音频框架示意图。
[0049]
图2为本发明方法执行流程图。
具体实施方式
[0050]
请参阅图2所示,本发明的Android系统双屏异显的两路音频实现方法,包括进入
双屏模式过程、播放音频过程和退出双屏模式过程;
[0051]
所述进入双屏模式过程包括:
[0052]
步骤S11、响应用户操作而进入双屏模式,首先模拟上报声卡插入事件;
[0053]
步骤S12、在AudioManager打开第二个声卡;
说 明 书
3/9 页
6
CN 108132771 A
6 [0054]
步骤S13、在AudioFlinger创建新的PlaybackThread;
[0055]
所述播放音频过程包括;
[0056]
步骤S21、App要播放声音前先判断是否是主屏播放声音,若是进入步骤S22,若否,
进入步骤S23;
[0057]
步骤S22、设置主屏声音的streamType,根据streamType在第一个声卡播放声音;
[0058]
步骤S23、设置副屏声音的streamType,根据streamType在第二个声卡播放声音;
[0059]
所述退出双屏模式过程包括:
[0060]
步骤S31、响应用户操作而退出双屏模式,首先模拟上报声卡断开事件;
[0061]
步骤S32、在AudioManager关闭第二个声卡;
[0062]
步骤S33、在AudioFlinger销毁第二个PlaybackThread,结束。
[0063]
所述步骤S12实现之前需是在PhoneWindow .java的superDispatchKeyEvent里面
预先添加force_speaker广播,并设置media .audio .device_policy .db的属性,异显状态下
设置该属性为 " speaker " ,同显状态设置该属性为 " hdmi " ,App即可通过该属性来判断是否
是主屏播放声音,添加和设置的具体代码实现过程如下:
[0064]
[0065]
然后在InputManagerService .java的start里面接收广播,收到广播后,触发耳机
说 明 书
4/9 页
7
CN 108132771 A
7 线控事件。具体代码的实现过程是:
[0066]
[0067]
[0068]
所述步骤 S1 2具体是:系统声音默认从 hd m i输出,当 s w i t c h Va l ue s为 0时 ,
mHeadState的状态设置成BIT_HDMI_AUDIO;当switchValues的值为1时,mHeadState的状态
说 明 书
5/9 页
8
CN 108132771 A
8 设置包括BIT_HDMI_AUDIO和BIT_USB_HEADSET_DGTL,目的是同时打开hdmi和speaker两路
输出,这种情况会触发AudioFlinger中的openDuplicateOutput创建两个MixerThread,从
而打开第二个声卡,输出是hdmi还是speaker通过AudioPolicy来进行控制。具体是:
[0069]
MixerThread*thread1=checkMixerThread_l(output1);
[0070]
MixerThread*thread2=checkMixerThread_l(output2);
[0071]
所 述 步 骤 S 2 1 中 ,所 述 A p p 判 断 是 否 是 主 屏 播 放 声 音 是 通 过 判 断
media .audio .device_policy .db的属性来实现,若该属性为 " speaker " ,则判断为异显状
态,若该属性为 " hdmi " ,则判断为同显状态。
[0072]
本发明方法还包括主副屏切换过程,所述主副屏切换过程是:
[0073]
系统默认从hdmi输出,同屏时声音也从hdmi输出;异显时,副屏的声音从speaker
输 出 ,主 屏的 声 音 从 h d m i 输 出 ;首 先 获 取 副 屏 上 a c t i v i t y 的 p i d ,并 设 置 为
" media .audio .activity .pid " 属性的值,同屏时,属性值设置为 - 1。其代码实现过程是:
[0074]
在moveTransitionToSecondDisplay中添加
[0075]
SystemProperties .set ("media .audio .activity .pid" ,String .valueOf
(win .mSession .mPid));
[0076]
在updateDisplayShowSynchronization中添加
[0077]
SystemProperties .set("media .audio .activity .pid" ,String .valueOf( - 1));
[0078]
接着在audiopolicy的Engine .cpp的getDeviceForStrategyInt中获取并解析
m e d i a .a u d i o .d e v i c e _ p o l i c y .d b的属性 ,即在
a u d i o p o l i c y的 E n g i n e .c p p的
getDeviceForStrategyInt中添加:
[0079]
说 明 书
6/9 页
9
CN 108132771 A
9 [0080]
[0081]
如果该属性里面的值是speaker,则返回AUDIO_DEVICE_OUT_WIRED_HEADSET,表示
声音最终从speaker输出;
[0082]
如果该属性里面的值是hdmi,则返回AUDIO_DEVICE_OUT_AUX_DIGITAL,表示声音
最终从hdmi输出。
[0083]
本发明方法还包括输出设备的修改过程:
[0084]
由于原来系统只有一个输出,要满足两路输出,因此需添加一个输出。
[0085]
修改的文件路径:/device/rockchip/common/audio_policy_rk30board .conf
[0086]
修改的内容包括:
[0087]
(1)更改全局配置里的输出设备,由AUDIO_DEVICE_OUT_SPEAKER改为AUDIO_
DEVICE_OUT_AUX_DIGITAL,代码实现过程是:
[0088]
[0089]
(2)更改primary默认输出设备,代码实现过程是:
[0090]
说 明 书
7/9 页
10
CN 108132771 A
10 [0091]
[0092]
(3)添加dgtl输出,即添加一个虚拟输出,代码实现过程是。
[0093]
[0094]
本发明方法还包括增加dgtl库,这个库是硬件抽象层的修改,为了给第二个音频
输出设备使用,实现两路音频设备同时输出声音,互不冲突,代码实现过程是:
[0095]
复制hardware/rockchip/audio/tinyalsa_hal到hardware/rockchip/audio/
tinyalsa_hal_dgtl,并修改Android .mk;具体如下:
[0096]
LOCAL_MODULE:=audio .dgtl .$(TARGET_BOARD_HARDWARE)
[0097]
将audio_hw .c中connect_hdmi的值改为false,屏蔽hdmi;
[0098]
connet_hdmi=false;
说 明 书
8/9 页
11
CN 108132771 A
11 [0099]
编译生成audio .dgtl .rk30board .so;
[0100]
最终,如果输出要求是hdmi,AudioFlinger会调用audio .dgtl .primary .so;如果
输出要求是speaker,AudioFlinger会调用audio .dgtl .rk30board .so。
[0101]
最后打上补丁,这些补丁即前面说明的代码实现过程,最后弄了一个整体完整的
补丁包:
[0102]
在framework/base/下打上补丁Dual_Audio_framework_base .patch;
[0103]
在framework/av/下打上补丁Dual_audio_framework_av .patch;
[0104]
在 h a r d w a r e / l i b h a r d w a r e / 下 打 上 补 丁 D u a l _ a u d i o _ h a r d w a r e _
libhardware .patch。
[0105]
虽然以上描述了本发明的具体实施方式,但是熟悉本技术领域的技术人员应当理
解,我们所描述的具体的实施例只是说明性的,而不是用于对本发明的范围的限定,熟悉本
领域的技术人员在依照本发明的精神所作的等效的修饰以及变化,都应当涵盖在本发明的
权利要求所保护的范围内。

相关推荐
SRC_BLUE_1734 分钟前
SQLI LABS | Less-39 GET-Stacked Query Injection-Intiger Based
android·网络安全·adb·less
runing_an_min2 小时前
ffmpeg视频滤镜:缓入缓出-fade
ffmpeg·音视频·fade·缓出·缓入
无尽的大道4 小时前
Android打包流程图
android
AI服务老曹4 小时前
建立更及时、更有效的安全生产优化提升策略的智慧油站开源了
大数据·人工智能·物联网·开源·音视频
镭封5 小时前
android studio 配置过程
android·ide·android studio
夜雨星辰4875 小时前
Android Studio 学习——整体框架和概念
android·学习·android studio
邹阿涛涛涛涛涛涛6 小时前
月之暗面招 Android 开发,大家快来投简历呀
android·人工智能·aigc
IAM四十二6 小时前
Jetpack Compose State 你用对了吗?
android·android jetpack·composer
gomogomono6 小时前
HDR视频技术之一:光学与人类视觉感知特性基础
音视频·hdr
小东来6 小时前
剪辑视频和制作视频的软件哪个好
音视频