AudioTrack流程

应用层设置声音类型

设置属性

说明: 根据应用层设置的声音类型设置属性
framework/av/media/libmedia/AudioTrack.cpp
AudioTrack::setAttributesFromStreamType

2067 void AudioTrack::setAttributesFromStreamType(audio_stream_type_t streamType) {
2068     mAttributes.flags = 0x0;
2069
2070     switch(streamType) {
2071     case AUDIO_STREAM_DEFAULT:
2072     case AUDIO_STREAM_MUSIC:
2073         mAttributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
2074         mAttributes.usage = AUDIO_USAGE_MEDIA;
2075         break;
2076     case AUDIO_STREAM_VOICE_CALL:
2077         mAttributes.content_type = AUDIO_CONTENT_TYPE_SPEECH;
2078         mAttributes.usage = AUDIO_USAGE_VOICE_COMMUNICATION;
2079         break;
2080     case AUDIO_STREAM_ENFORCED_AUDIBLE:
2081         mAttributes.flags  |= AUDIO_FLAG_AUDIBILITY_ENFORCED;

根据streamType设置content_type、usage和flags。

确定类别/组

根据声音属性确定它的类别/组
frameworks/av/services/audiopolicy/AudioPolicyManager.cpp
AudioPolicyManager::getStrategyForAttr

3921 uint32_t AudioPolicyManager::getStrategyForAttr(const audio_attributes_t *attr) {
3922     // flags to strategy mapping
3923     if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
3924         return (uint32_t) STRATEGY_ENFORCED_AUDIBLE;
3925     }
3926
3927     // usage to strategy mapping
3928     switch (attr->usage) {
3929     case AUDIO_USAGE_MEDIA:
3930     case AUDIO_USAGE_GAME:
3931     case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
3932     case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
3933     case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
3934         return (uint32_t) STRATEGY_MEDIA;
3935
3936     case AUDIO_USAGE_VOICE_COMMUNICATION:
3937         return (uint32_t) STRATEGY_PHONE;
3938
3939     case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
3940         return (uint32_t) STRATEGY_DTMF;
3941
3942     case AUDIO_USAGE_ALARM:
3943     case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
3944         return (uint32_t) STRATEGY_SONIFICATION;
3945
3946     case AUDIO_USAGE_NOTIFICATION:
3947     case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
3948     case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
3949     case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
3950     case AUDIO_USAGE_NOTIFICATION_EVENT:
3951         return (uint32_t) STRATEGY_SONIFICATION_RESPECTFUL;
3952
3953     case AUDIO_USAGE_UNKNOWN:
3954     default:
3955         return (uint32_t) STRATEGY_MEDIA;
3956     }
3957 }

确定播放设备

根据声音类别/组确定播放(耳机/蓝牙/喇叭)

AudioPolicyManager::getDeviceForStrategy
如果在应用层选的是AUDIO_STREAM_VOICE_CALL,对应的strategy是STRATEGY_PHONE,分析下函数策略:

3970 audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,
3971                                                              bool fromCache)
3972 {
3973     uint32_t device = AUDIO_DEVICE_NONE;
3974
3975     if (fromCache) {
3976         ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x",
3977               strategy, mDeviceForStrategy[strategy]);
3978         return mDeviceForStrategy[strategy];
3979     }
3980     audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types();
3981     switch (strategy) {
4020     case STRATEGY_PHONE:
4021         // Force use of only devices on primary output if:
4022         // - in call AND
4023         //   - cannot route from voice call RX OR
4024         //   - audio HAL version is < 3.0 and TX device is on the primary HW module
4025         if (mPhoneState == AUDIO_MODE_IN_CALL) {
4026             audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
4027             sp<AudioOutputDescriptor> hwOutputDesc = mOutputs.valueFor(mPrimaryOutput);
4028             if (((mAvailableInputDevices.types() &
4029                     AUDIO_DEVICE_IN_TELEPHONY_RX & ~AUDIO_DEVICE_BIT_IN) == 0) ||
4030                     (((txDevice & availablePrimaryInputDevices() & ~AUDIO_DEVICE_BIT_IN) != 0) &&
4031                          (hwOutputDesc->getAudioPort()->mModule->mHalVersion <
4032                              AUDIO_DEVICE_API_VERSION_3_0))) {
4033                 availableOutputDeviceTypes = availablePrimaryOutputDevices();
4034             }
4035         }
4036         // for phone strategy, we first consider the forced use and then the available devices by order
4037         // of priority
4038         switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
4039         case AUDIO_POLICY_FORCE_BT_SCO:   //蓝牙
4040             if (!isInCall() || strategy != STRATEGY_DTMF) {
4041                 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT//蓝牙车载设备
4042                 if (device) break;
4043             }
4044             device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET; //蓝牙耳机
4045             if (device) break;
4046             device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;  //
4047             if (device) break;
4048             // if SCO device is requested but no SCO device is available, fall back to default case
4049             // FALL THROUGH
4050
4051         default:    // FORCE_NONE
4052             // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
4053             if (!isInCall() &&
4054                     (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
4055                     (getA2dpOutput() != 0) && !mA2dpSuspended) {
4056                 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;  //蓝牙立体声
4057                 if (device) break;
4058                 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;//蓝牙立体耳机
4059                 if (device) break;
4060             }
4061             device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;//不带话筒的耳机
4062             if (device) break;
4063             device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET;//带话筒的耳机
4064             if (device) break;
4065             device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE;
4066             if (device) break;
4067             if (mPhoneState != AUDIO_MODE_IN_CALL) {
4068                 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;
4069                 if (device) break;
4070                 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;//
4071                 if (device) break;
4072                 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL;
4073                 if (device) break;
4074                 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;//
4075                 if (device) break;
4076             }
4077             device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_EARPIECE;    //听筒
4078             if (device) break;
4079             device = mDefaultOutputDevice->mDeviceType;
4080             if (device == AUDIO_DEVICE_NONE) {
4081                 ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE");
4082             }
4083             break;   

总结:
安卓手机打电话时:

  1. 如果使用强制设备来播放声音,比如扬声器和蓝牙。
  2. 如果没有使用强制设备来播放
    2.1 如果连接上蓝牙车载导航,优先使用车载导航播放声音
    2.2 连上耳机 ,使用耳机播放声音
    2.3 如果蓝牙,耳机都没有连接,则使用扬声器来播放声音。

确定outputs

DefaultKeyedVector<audio_io_handle_t, sp<AudioOutputDescriptor> > mOutputs;class AudioOutputDescriptor: public AudioPortConfig{..........const sp<IOProfile> mProfile;.....}

配置文件格式如下:

 27   primary {                                                                     28     outputs {                                                                   29       primary {                                                                 30         sampling_rates 44100                                                    31         channel_masks AUDIO_CHANNEL_OUT_STEREO                                  32         formats AUDIO_FORMAT_PCM_16_BIT                                         33         devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL34         flags AUDIO_OUTPUT_FLAG_PRIMARY                                         35       }                                                                         36     }

解析配置文件函数会把outputs选项中所有output放入到mOutputs中,显然这个配置文件中只有1个output。
每个output所有内容都保存到mProfile中,这样mProfile包括devices也就是该output支持的设备列表。

audio_io_handle_t AudioPolicyManager::getOutputForDevice(audio_devices_t device,audio_stream_type_t stream,uint32_t samplingRate,audio_format_t format,audio_channel_mask_t channelMask,audio_output_flags_t flags,const audio_offload_info_t *offloadInfo)
{
non_direct_output:// ignoring channel mask due to downmix capability in mixer// open a non direct output// for non direct outputs, only PCM is supportedif (audio_is_linear_pcm(format)) {// get which output is suitable for the specified stream. The actual// routing change will happen when startOutput() will be calledSortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);// at this stage we should ignore the DIRECT flag as no direct output could be found earlierflags = (audio_output_flags_t)(flags & ~AUDIO_OUTPUT_FLAG_DIRECT);output = selectOutput(outputs, flags, format);}ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d,""format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags);ALOGV("getOutput() returns output %d", output);return output;
}

getOutputsForDevice(device, mOutputs);传输mOutputs就是配置文件中所有output选项的数组。

SortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevice(audio_devices_t device,DefaultKeyedVector<audio_io_handle_t, sp<AudioOutputDescriptor> > openOutputs)
{SortedVector<audio_io_handle_t> outputs;ALOGVV("getOutputsForDevice() device %04x", device);for (size_t i = 0; i < openOutputs.size(); i++) {ALOGVV("output %d isDuplicated=%d device=%04x",i, openOutputs.valueAt(i)->isDuplicated(), openOutputs.valueAt(i)->supportedDevices());if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) {ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i));outputs.add(openOutputs.keyAt(i));}}return outputs;
}

就是相应的device,轮询mOutputs所有的output中的device选项,查看每个output支持的device如果支持( if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) ),这把该output加入outputs数组中( outputs.add(openOutputs.keyAt(i)))。返回这个outputs数组。

从outputs 选择output

        SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);// at this stage we should ignore the DIRECT flag as no direct output could be found earlierflags = (audio_output_flags_t)(flags & ~AUDIO_OUTPUT_FLAG_DIRECT);output = selectOutput(outputs, flags, format);

在得到outputs数组,也就是device支持的output数组。调用selectOutput函数

audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_handle_t>& outputs,audio_output_flags_t flags,audio_format_t format)
{// select one output among several that provide a path to a particular device or set of// devices (the list was previously build by getOutputsForDevice()).// The priority is as follows:// 1: the output with the highest number of requested policy flags// 2: the primary output// 3: the first output in the list}

1
a. APP创建AudioTrack时传入flag
b. output对应的profle(/system/etc/audio_policy.conf)中也有flag
c. 使用上述a,b的flag进行比较,取出吻合度最高的output,也就是两个flag中bit吻合度最高的。如果最高吻合的output不止一个执行步骤2。

最高吻合的output中有primary output支持该设备,则选择primary output.

如果最高吻合的output咩有primary output,则选择第一个output。

后续

  1. 确定了output也就确定了playbackThread
    2)在playbackThread中创建了对应的track
    3)APP的AudioTrack和playbackThread的mTracks中的track之间建立共享内存。

AudioTrack过程相关推荐

  1. WebRTC 的 AudioSource/AudioTrack

    按照 WebRTC 的设计,AudioSource 是一个音频源,它可以向外提供 PCM 音频帧数据,比如麦克风录制可以提供 PCM 音频帧数据,它应该是一个 AudioSource.然而在 WebR ...

  2. ktm390蓝牙连接安卓_蓝牙音乐AudioTrack Session ID的获取

    当今这个音视频无处不在的时代,音频跟踪会话ID(AudioTrack Session ID)是个很重要的参数,可以用来实现音频相关的一些特效.接下来的内容我们就探究如何在安卓蓝牙系统中获取该id. 熟 ...

  3. 获取sessionid_蓝牙音乐AudioTrack Session ID的获取

    当今这个音视频无处不在的时代,音频跟踪会话ID(AudioTrack Session ID)是个很重要的参数,可以用来实现音频相关的一些特效.接下来的内容我们就探究如何在安卓蓝牙系统中获取该id. 熟 ...

  4. Android多媒体:AudioTrack

    原址 AudioTrack是和PlaybackThread中创建的Track一一对应的,Track是Bn,AudioTrack是Bp.音乐APP通过操作AudioTrack来进行音乐数据的传输.具体过 ...

  5. 深入剖析Android音频(四)AudioTrack

    原址 播放声音可以用MediaPlayer和AudioTrack,两者都提供了Java API供应用开发者使用.虽然都可以播放声音,但两者还是有很大的区别的.其中最大的区别是MediaPlayer可以 ...

  6. Android 音频系统:从 AudioTrack 到 AudioFlinger(全)

    Android 音频框架概述 Audio 是整个 Android 平台非常重要的一个组成部分,负责音频数据的采集和输出.音频流的控制.音频设备的管理.音量调节等,主要包括如下部分: Audio App ...

  7. Android 11 Audio框架探索之AudioTracK(二)

    在上一篇介绍了关于AudioPolicyService与AudioFlinger服务的启动及初始化.这里探索一下AudioTrack与AudioFlinger做了那些事情. MediaPlayer会在 ...

  8. Android音视频学习系列(五) — 掌握音频基础知识并使用AudioTrack、OpenSL ES渲染PCM数据

    系列文章 Android音视频学习系列(一) - JNI从入门到精通 Android音视频学习系列(二) - 交叉编译动态库.静态库的入门 Android音视频学习系列(三) - Shell脚本入门 ...

  9. android 音频播放过程,一种Android系统中的音频播放方法与流程

    本申请涉及android系统技术,特别涉及一种android系统中的音频播放方法. 背景技术: 在android系统中,现有的使用audiotrack进行音频播放时,audiotrack应用与andr ...

最新文章

  1. seo说_百度指数看世间沉浮_如何快速排名-互点快速排名_网站关键词排名常见问题 - 搜狗快速排名...
  2. ASP.NET MVC实现一个用户只能登录一次 单用户登录
  3. 金融领域下的数据挖掘算法应用:逻辑回归模型
  4. Linux环境下启动Tomcat太慢
  5. matlab损失函数出现nan,[译]在训练过程中loss出现NaN的原因以及可以采取的方法。...
  6. 逍遥android模拟器设置,逍遥安卓模拟器最佳设置电脑上玩手游流畅不卡多开更好用...
  7. udp 协议阻断_应对UDP反射放大攻击的五种常用防护思路
  8. android开发GPS定位测试(附效果图和示例)【转】
  9. python语言的jenkinapi
  10. java实现 tf-idf
  11. MySql Binlog初识
  12. Ubuntu14.04/16.04安装Dukto
  13. 一元线性拟合的matlab,基于MATLAB的一元线性回归分析
  14. domain adaptation论文记录
  15. ES插件es-head下载和安装
  16. 计算机专业在广东省的录取分数线,深圳大学广东本科批稳居广东高校前4!2019各省录取分数线发布!...
  17. HTB-Blocky
  18. 有机化学php,有机化学原理
  19. 360桌面助手待办事项同步/迁移的方法(从一台电脑迁移到另外一台电脑上)
  20. AHP算法MATLAB代码

热门文章

  1. 【求职】完美世界 C++方向面经
  2. 服务器系统加固经验分享
  3. 师范计算机专业前景,师范数学专业就业前景
  4. 同款蓝牙耳机为什么会串联_烂大街的蓝牙耳机音质都一样,为什么有人买更贵的AirPods...
  5. android ormlite 查询,带引号的ORMLite查询,Android
  6. Altium Designer 10 (AD10)制作贴片图
  7. crmeb 小程序包大小超过2M的解决方法
  8. 安装OpenBLAS
  9. Java中的日志级别
  10. 树莓派搭建股票量化分析服务器 基于tushare python