[RK3399][Android7.1]修改系统配置同时输出Speaker和USB音频

这篇博客介绍了在Android7.1中如何修改音频控制策略,以实现在Speaker和USB音频设备间切换。作者提供了两种方法:一种是通过修改硬件层的Audio_hw.c文件,另一种是在Framework层的AudioPolicyManager.cpp中进行修改。在修改后,需要注意可能产生的声音卡顿问题,并进行了相应调整。更新后的代码确保了媒体、闹钟和铃声都通过USB音频输出。
摘要由CSDN通过智能技术生成

 

参考链接:Android7.1 音频声音控制策略

参考文中给了两种方法,第一种没有成功,第二种成功了。第一种可能是参数给错了,例子给的是Speaker和耳机,我需要的是Speaker和USB音频。

 

第一种:

文件路径:hardware\qcom\audio\hal\Audio_hw.c

int start_output_stream(struct stream_out *out)
{
	...
	// Jon Add Begin
	out->devices = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
	// End
	...
	uc_info->devices = out->devices;
	...
	//完成声卡和路由的切换和打开
	select_devices(adev, out->usecase);
	...
}

git比较如下:

ubt@ubt-ThinkPad-E470:~/proj/firefly-rk3399$ git diff hardware/qcom/audio/hal
diff --git a/hardware/qcom/audio/hal/audio_hw.c b/hardware/qcom/audio/hal/audio_hw.c
index 0a5bccb..bc0683d 100644
--- a/hardware/qcom/audio/hal/audio_hw.c
+++ b/hardware/qcom/audio/hal/audio_hw.c
@@ -1645,6 +1645,9 @@ int start_output_stream(struct stream_out *out)
         goto error_config;
     }
 
+       // dlc-add 20210223
+       //out->devices = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
+
     uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
     uc_info->id = out->usecase;
     uc_info->type = PCM_PLAYBACK;

其中  SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES  在platform.h 音频设备定义,下面仅列举一部分:

/* Sound devices specific to the platform
 * The DEVICE_OUT_* and DEVICE_IN_* should be mapped to these sound
 * devices to enable corresponding mixer paths
 */
enum {
    SND_DEVICE_NONE = 0,
 
    /* Playback devices */
    SND_DEVICE_MIN,
    SND_DEVICE_OUT_BEGIN = SND_DEVICE_MIN,
    SND_DEVICE_OUT_HANDSET = SND_DEVICE_OUT_BEGIN,
    SND_DEVICE_OUT_SPEAKER,
    SND_DEVICE_OUT_HEADPHONES,
    SND_DEVICE_OUT_HEADPHONES_DSD,
    SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
    SND_DEVICE_OUT_SPEAKER_AND_LINE,
    SND_DEVICE_OUT_VOICE_HANDSET,
    SND_DEVICE_OUT_VOICE_SPEAKER,
    SND_DEVICE_OUT_VOICE_HEADPHONES,
    SND_DEVICE_OUT_VOICE_LINE,
    SND_DEVICE_OUT_HDMI,
    SND_DEVICE_OUT_DISPLAY_PORT,
    SND_DEVICE_OUT_BT_SCO,
    SND_DEVICE_OUT_BT_A2DP,
    SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP,
    SND_DEVICE_OUT_AFE_PROXY,
    SND_DEVICE_OUT_USB_HEADSET,
    SND_DEVICE_OUT_USB_HEADPHONES,
    SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET,
    SND_DEVICE_OUT_SPEAKER_PROTECTED,
    SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED,
    SND_DEVICE_OUT_END,
 
    /* Capture devices */
    SND_DEVICE_IN_BEGIN = SND_DEVICE_OUT_END,
    SND_DEVICE_IN_HANDSET_MIC  = SND_DEVICE_IN_BEGIN, // 58
    SND_DEVICE_IN_SPEAKER_MIC,
    SND_DEVICE_IN_HEADSET_MIC,
    SND_DEVICE_IN_VOICE_SPEAKER_MIC,
    SND_DEVICE_IN_VOICE_HEADSET_MIC,
    SND_DEVICE_IN_BT_SCO_MIC,
    SND_DEVICE_IN_CAMCORDER_MIC,
    SND_DEVICE_IN_END,
 
    SND_DEVICE_MAX = SND_DEVICE_IN_END,
};

根据需求配置,如果需要Speaker和USB,则应使用  SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET  ,这个我没有测试,大家有时间可以试试。

 

第二种方式:

在Framework中修改,路径如下:frameworks\av\services\audiopolicy\managerdefault\AudioPolicyManager.cpp

audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,
                                                         bool fromCache)
{
	...
	
	/*Begin Add Jon*/
	if(strategy == STRATEGY_MEDIA)
		return AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_WIRED_HEADSET;
	/*End*/
	
    return mEngine->getDeviceForStrategy(strategy);
}

git文件比较如下:

ubt@ubt-ThinkPad-E470:~/proj/firefly-rk3399$ git diff frameworks/av/services/audiopolicy/managerdefault
diff --git a/frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 1a8a84a..2951461 100644
--- a/frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -4657,6 +4657,19 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate
               strategy, mDeviceForStrategy[strategy]);
         return mDeviceForStrategy[strategy];
     }
+
+       // dlc-add 20210223
+       /*Begin Add Jon*/
+    ALOGD(" getDeviceForStrategy() strategy type:%d", strategy );
+       
+       if( (strategy == STRATEGY_MEDIA) ||
+        (strategy == STRATEGY_SONIFICATION) ||
+        (strategy == STRATEGY_SONIFICATION_RESPECTFUL) )
+               return AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_USB_DEVICE;
+
+
+       /*End*/
+
     return mEngine->getDeviceForStrategy(strategy);
 }

其中添加的判断语句意思为:判断声音为媒体、闹钟和铃声。直接返回  SPEAKER和USB_DEVICE。

其中 strategy类型如下:

enum routing_strategy {
    STRATEGY_MEDIA,
    STRATEGY_PHONE,
    STRATEGY_SONIFICATION,
    STRATEGY_SONIFICATION_RESPECTFUL,
    STRATEGY_DTMF,
    STRATEGY_ENFORCED_AUDIBLE,
    STRATEGY_TRANSMITTED_THROUGH_SPEAKER,
    STRATEGY_ACCESSIBILITY,
    STRATEGY_REROUTING,
    NUM_STRATEGIES
};

根据需要自行修改。

返回的类型枚举如下:

enum {
    AUDIO_DEVICE_NONE                          = 0x0,
    /* reserved bits */
    AUDIO_DEVICE_BIT_IN                        = 0x80000000,
    AUDIO_DEVICE_BIT_DEFAULT                   = 0x40000000,
    /* output devices */
    AUDIO_DEVICE_OUT_EARPIECE                  = 0x1,    // 听筒
    AUDIO_DEVICE_OUT_SPEAKER                   = 0x2,    // 扬声器
    AUDIO_DEVICE_OUT_WIRED_HEADSET             = 0x4,    // 线控耳机,可以通过耳机控制远端播放、暂停、音量调节等功能的耳机
    AUDIO_DEVICE_OUT_WIRED_HEADPHONE           = 0x8,    // 普通耳机,只能听,不能操控播放
    AUDIO_DEVICE_OUT_BLUETOOTH_SCO             = 0x10,   // 单声道蓝牙耳机,十进制32
    AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET     = 0x20,   // 车载免提蓝牙设备,十进制64
    AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT      = 0x40,   // 立体声蓝牙耳机
    AUDIO_DEVICE_OUT_BLUETOOTH_A2DP            = 0x80,   // 十进制128
    AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100,  // 十进制256
    AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER    = 0x200,  // 十进制512
    AUDIO_DEVICE_OUT_AUX_DIGITAL               = 0x400,  // 十进制1024
    AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET         = 0x800,  // 十进制2048
    AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET         = 0x1000, // 十进制4096
    AUDIO_DEVICE_OUT_USB_ACCESSORY             = 0x2000,
    AUDIO_DEVICE_OUT_USB_DEVICE                = 0x4000,
    AUDIO_DEVICE_OUT_REMOTE_SUBMIX             = 0x8000,
    AUDIO_DEVICE_OUT_DEFAULT                   = AUDIO_DEVICE_BIT_DEFAULT,
    AUDIO_DEVICE_OUT_ALL      = (AUDIO_DEVICE_OUT_EARPIECE |
                                 AUDIO_DEVICE_OUT_SPEAKER |
                                 AUDIO_DEVICE_OUT_WIRED_HEADSET |
                                 AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
                                 AUDIO_DEVICE_OUT_BLUETOOTH_SCO |
                                 AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
                                 AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT |
                                 AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
                                 AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
                                 AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER |
                                 AUDIO_DEVICE_OUT_AUX_DIGITAL |
                                 AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
                                 AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET |
                                 AUDIO_DEVICE_OUT_USB_ACCESSORY |
                                 AUDIO_DEVICE_OUT_USB_DEVICE |
                                 AUDIO_DEVICE_OUT_REMOTE_SUBMIX |
                                 AUDIO_DEVICE_OUT_DEFAULT),
    AUDIO_DEVICE_OUT_ALL_A2DP = (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
                                 AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
                                 AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER),
    AUDIO_DEVICE_OUT_ALL_SCO  = (AUDIO_DEVICE_OUT_BLUETOOTH_SCO |
                                 AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
                                 AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT),
    AUDIO_DEVICE_OUT_ALL_USB  = (AUDIO_DEVICE_OUT_USB_ACCESSORY |
                                 AUDIO_DEVICE_OUT_USB_DEVICE),
 
    /* input devices */
    AUDIO_DEVICE_IN_COMMUNICATION         = AUDIO_DEVICE_BIT_IN | 0x1,
    AUDIO_DEVICE_IN_AMBIENT               = AUDIO_DEVICE_BIT_IN | 0x2,
    AUDIO_DEVICE_IN_BUILTIN_MIC           = AUDIO_DEVICE_BIT_IN | 0x4,  //手机自带MIC
    AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET = AUDIO_DEVICE_BIT_IN | 0x8,
    AUDIO_DEVICE_IN_WIRED_HEADSET         = AUDIO_DEVICE_BIT_IN | 0x10,  //耳机
    AUDIO_DEVICE_IN_AUX_DIGITAL           = AUDIO_DEVICE_BIT_IN | 0x20,
    AUDIO_DEVICE_IN_VOICE_CALL            = AUDIO_DEVICE_BIT_IN | 0x40,
    AUDIO_DEVICE_IN_BACK_MIC              = AUDIO_DEVICE_BIT_IN | 0x80,
    AUDIO_DEVICE_IN_REMOTE_SUBMIX         = AUDIO_DEVICE_BIT_IN | 0x100,
    AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET     = AUDIO_DEVICE_BIT_IN | 0x200,
    AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET     = AUDIO_DEVICE_BIT_IN | 0x400,
    AUDIO_DEVICE_IN_USB_ACCESSORY         = AUDIO_DEVICE_BIT_IN | 0x800,
    AUDIO_DEVICE_IN_USB_DEVICE            = AUDIO_DEVICE_BIT_IN | 0x1000,
    AUDIO_DEVICE_IN_DEFAULT               = AUDIO_DEVICE_BIT_IN | AUDIO_DEVICE_BIT_DEFAULT,
 
    AUDIO_DEVICE_IN_ALL     = (AUDIO_DEVICE_IN_COMMUNICATION |
                               AUDIO_DEVICE_IN_AMBIENT |
                               AUDIO_DEVICE_IN_BUILTIN_MIC |
                               AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET |
                               AUDIO_DEVICE_IN_WIRED_HEADSET |
                               AUDIO_DEVICE_IN_AUX_DIGITAL |
                               AUDIO_DEVICE_IN_VOICE_CALL |
                               AUDIO_DEVICE_IN_BACK_MIC |
                               AUDIO_DEVICE_IN_REMOTE_SUBMIX |
                               AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET |
                               AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET |
                               AUDIO_DEVICE_IN_USB_ACCESSORY |
                               AUDIO_DEVICE_IN_USB_DEVICE |
                               AUDIO_DEVICE_IN_DEFAULT),
    AUDIO_DEVICE_IN_ALL_SCO = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
};

 

我需要的是Speaker和USB转音频同时输出声音,因此直接返回这两个return AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_USB_DEVICE;如果有其他需要,根据定义自选,简单暴力。

这样设置后,可能会有一些意想不到的效果,配置以后一定要多测试。

 

 

2021.02.26 更新:

采用第二种方式 更新后,在同时使用USB音频和Speaker播放时,会出现卡顿的情况。

因为在原系统上,接入USB音频后,媒体音量会通过USB音频输出,通知音量会随机选择通过SUB音频或通过Speaker输出。因此修改了相应的功能,在插入USB音频时,不管是媒体声音,还是通知声音,都从USB音频播放。USB音频拔出后,均从Speaker输出。修改如下:

audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,
4640                                                          bool fromCache)
4641 {
4642     // dlc add
4643     routing_strategy tmp_strategy;
4644 
4645     if( (strategy == STRATEGY_MEDIA) ||
4646         (strategy == STRATEGY_SONIFICATION) ||
4647         (strategy == STRATEGY_SONIFICATION_RESPECTFUL) )
4648     {
4649         tmp_strategy = STRATEGY_MEDIA;
4650     }
4651 
4652     // Routing
4653     // see if we have an explicit route
4654     // scan the whole RouteMap, for each entry, convert the stream type to a strategy
4655     // (getStrategy(stream)).
4656     // if the strategy from the stream type in the RouteMap is the same as the argument above,
4657     // and activity count is non-zero
4658     // the device = the device from the descriptor in the RouteMap, and exit.
4659     for (size_t routeIndex = 0; routeIndex < mOutputRoutes.size(); routeIndex++) {
4660         sp<SessionRoute> route = mOutputRoutes.valueAt(routeIndex);
4661         routing_strategy routeStrategy = getStrategy(route->mStreamType);
4662         //if ((routeStrategy == strategy) && route->isActive()) {
4663         if ((routeStrategy == tmp_strategy) && route->isActive()) {
4664             return route->mDeviceDescriptor->type();
4665         }
4666     }
4667 
4668     if (fromCache) {
4669         ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x",
4670               strategy, mDeviceForStrategy[strategy]);
4671         //return mDeviceForStrategy[strategy];
4672         return mDeviceForStrategy[tmp_strategy];
4673     }
4674 
4675     // dlc-add 20210223
4676     /*Begin Add Jon 
4677     ALOGD(" getDeviceForStrategy() strategy type:%d", strategy );
4678     
4679     if( (strategy == STRATEGY_MEDIA) ||
4680         (strategy == STRATEGY_SONIFICATION) ||
4681         (strategy == STRATEGY_SONIFICATION_RESPECTFUL) )
4682         return AUDIO_DEVICE_OUT_USB_DEVICE;
4683 
4684 
4685      End */
4685      End */
4686 
4687     //return mEngine->getDeviceForStrategy(strategy);
4688     return mEngine->getDeviceForStrategy(tmp_strategy);
4689 }

git比较如下:

@@ -4647,7 +4659,8 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate
 audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,
                                                          bool fromCache)
 {
+       // dlc add
+       routing_strategy tmp_strategy;
+
+       if( (strategy == STRATEGY_MEDIA) ||
+        (strategy == STRATEGY_SONIFICATION) ||
+        (strategy == STRATEGY_SONIFICATION_RESPECTFUL) )
+       {
+               tmp_strategy = STRATEGY_MEDIA;
+       }       
+       
     // Routing
     // see if we have an explicit route
     // scan the whole RouteMap, for each entry, convert the stream type to a strategy

     for (size_t routeIndex = 0; routeIndex < mOutputRoutes.size(); routeIndex++) {
         sp<SessionRoute> route = mOutputRoutes.valueAt(routeIndex);
         routing_strategy routeStrategy = getStrategy(route->mStreamType);
-        if ((routeStrategy == strategy) && route->isActive()) {
+        //if ((routeStrategy == strategy) && route->isActive()) {
+        if ((routeStrategy == tmp_strategy) && route->isActive()) {
             return route->mDeviceDescriptor->type();
         }
     }

     if (fromCache) {
         ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x",
               strategy, mDeviceForStrategy[strategy]);
-        return mDeviceForStrategy[strategy];
+        //return mDeviceForStrategy[strategy];
+        return mDeviceForStrategy[tmp_strategy];
     }
-    return mEngine->getDeviceForStrategy(strategy);
+
+       // dlc-add 20210223
+       /*Begin Add Jon 
+    ALOGD(" getDeviceForStrategy() strategy type:%d", strategy );
+       
+       if( (strategy == STRATEGY_MEDIA) ||
+        (strategy == STRATEGY_SONIFICATION) ||
+        (strategy == STRATEGY_SONIFICATION_RESPECTFUL) )
+               return AUDIO_DEVICE_OUT_USB_DEVICE;
+
+
+        End */
+
+    //return mEngine->getDeviceForStrategy(strategy);
+    return mEngine->getDeviceForStrategy(tmp_strategy);

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值