Android Audio框架 audio_policy.conf文件

Android系统可以通过配置audio_policy.conf文件,来实现不同产品的差异化,audio_policy.conf文件中,配置了当前项目audio策略中支持的输入输出设备,对应的播放模式,采样率,采样精度,声道数等等。例如下面:

1 Primary {

2        sampling_rates 44100|48000

3        channel_masks AUDIO_CHANNEL_OUT_STEREO

4        formats AUDIO_FORMAT_PCM_16_BIT

5        devices AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET|AUDIO_DEVICE_OUT_FM|AUDIO_DEVICE_OUT_FM_TX

6        flags AUDIO_OUTPUT_FLAG_PRIMARY

7      }

8      low_latency {

9          sampling_rates 44100|48000

10          channel_masks AUDIO_CHANNEL_OUT_STEREO

11          formats AUDIO_FORMAT_PCM_16_BIT

12          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_PROXY|AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET|AUDIO_DEVICE_OUT_FM|AUDIO_DEVICE_OUT_FM_TX

13          flags AUDIO_OUTPUT_FLAG_FAST

14      }

15      compress_offload {

16        sampling_rates 8000|11025|16000|22050|32000|44100|48000

17        channel_masks AUDIO_CHANNEL_OUT_MONO|AUDIO_CHANNEL_OUT_STEREO

18        formats AUDIO_FORMAT_MP3|AUDIO_FORMAT_AAC_LC|AUDIO_FORMAT_AAC_HE_V1|AUDIO_FORMAT_AAC_HE_V2

19        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_PROXY|AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET|AUDIO_DEVICE_OUT_FM_TX

20        flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING

21      }

1 a2dp {

2    outputs {

3      a2dp {

4        sampling_rates 44100

5        channel_masks AUDIO_CHANNEL_OUT_STEREO

6        formats AUDIO_FORMAT_PCM_16_BIT

7        devices AUDIO_DEVICE_OUT_ALL_A2DP

8      }

9    }

10  }

11  usb {

12    outputs {

13      usb_accessory {

14        sampling_rates 44100

15        channel_masks AUDIO_CHANNEL_OUT_STEREO

16        formats AUDIO_FORMAT_PCM_16_BIT

17        devices AUDIO_DEVICE_OUT_USB_ACCESSORY

18      }

19      usb_device {

20        sampling_rates dynamic

21        channel_masks dynamic

22        formats dynamic

23        devices AUDIO_DEVICE_OUT_USB_DEVICE

24      }

25    }

26    inputs {

27      usb_device {

28        sampling_rates dynamic

29        channel_masks AUDIO_CHANNEL_IN_STEREO

30        formats AUDIO_FORMAT_PCM_16_BIT

31        devices AUDIO_DEVICE_IN_USB_DEVICE

32      }

33    }

34  }

在AudioPolicyManager中会解析此文件,获取此信息,那什么时候会需要修改此文件呢,例如:如果所在项目没有听筒设备,所以在接听电话的时候需要默认切换到喇叭输出,这个时候就需要修改此文件,把听筒设备AUDIO_DEVICE_OUT_EARPIECE从所有场景下支持的输出设备中删除,这样的话,就会切换到默认输出设备喇叭下。这个文件的信息,也可以通过指令

adb shell dumpsys media.audio_policy 打印出来,如下:

1 HW Modules dump:

2 - HW Module 1:

3  - name: primary

4  - handle: 1

5  - version: 2.0

6  - outputs:

7    output 0:

8    - name: primary

9    - sampling rates: 44100, 48000

10    - channel masks: 0x0003

11    - formats: AUDIO_FORMAT_PCM_16_BIT

12    - flags: 0x0002

13    - devices:

14      Device 1:

15      - type: AUDIO_DEVICE_OUT_EARPIECE

16      Device 2:

17      - type: AUDIO_DEVICE_OUT_SPEAKER

18      Device 3:

19      - type: AUDIO_DEVICE_OUT_WIRED_HEADSET

20      Device 4:

21      - type: AUDIO_DEVICE_OUT_WIRED_HEADPHONE

22      Device 5:

23      - type: AUDIO_DEVICE_OUT_ALL_SCO

24      Device 6:

25      - type: AUDIO_DEVICE_OUT_PROXY

26      Device 7:

27      - type: AUDIO_DEVICE_OUT_AUX_DIGITAL

28      Device 8:

29      - type: AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET

30      Device 9:

31      - type: AUDIO_DEVICE_OUT_FM

32      Device 10:

33      - type: AUDIO_DEVICE_OUT_FM_TX

34    output 1:

35    - name: low_latency

36    - sampling rates: 44100, 48000

37    - channel masks: 0x0003

38    - formats: AUDIO_FORMAT_PCM_16_BIT

39    - flags: 0x0004

40    - devices:

41      Device 1:

42      - type: AUDIO_DEVICE_OUT_SPEAKER

43      Device 2:

44      - type: AUDIO_DEVICE_OUT_EARPIECE

45      Device 3:

46      - type: AUDIO_DEVICE_OUT_WIRED_HEADSET

47      Device 4:

48      - type: AUDIO_DEVICE_OUT_WIRED_HEADPHONE

49      Device 5:

50      - type: AUDIO_DEVICE_OUT_ALL_SCO

51      Device 6:

52      - type: AUDIO_DEVICE_OUT_AUX_DIGITAL

53      Device 7:

54      - type: AUDIO_DEVICE_OUT_PROXY

55      Device 8:

56      - type: AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET

57      Device 9:

58      - type: AUDIO_DEVICE_OUT_FM

59      Device 10:

在文件系统里,有两个地方存放此文件/system/etc/audio_policy.conf 和 /vendor/etc/audio_policy.conf, 在创建AudioPolicyManager的时候会加载此配置文件:

  1 AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)

  2 {

  3    /*将默认输出设备设置成SPEAKER*/

  4    mDefaultOutputDevice = new DeviceDescriptor(String8(""), AUDIO_DEVICE_OUT_SPEAKER);

  5    /*加载audio_policy.conf文件,先默认去加载vendor目录下的文件,如果找不到就去加载system目录下的*/

  6    if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) {

  7        if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) {

  8            ALOGE("could not load audio policy configuration file, setting defaults");

  9            /*如果两个目录都没有找到,就去加载一个默认的配置,默认的配置中会创建一个Primary module,

10            为它创建一个默认的输出设备speaker和默认输出设备主Mic.

11            */

12            defaultAudioPolicyConfig();

13        }

14    }

15

16    /*把所有的输入输出设备都会操作打开一遍,检查该设备是否是有效的*/

17    // open all output streams needed to access attached devices

18    audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();

19    audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;

20    for (size_t i = 0; i < mHwModules.size(); i++) {

21        mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName);

22        if (mHwModules[i]->mHandle == 0) {

23            ALOGW("could not open HW module %s", mHwModules[i]->mName);

24            continue;

25        }

26        // open all output streams needed to access attached devices

27        // except for direct output streams that are only opened when they are actually

28        // required by an app.

29        // This also validates mAvailableOutputDevices list

30        for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)

31        {

32            const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j];

33

34            if (outProfile->mSupportedDevices.isEmpty()) {

35                ALOGW("Output profile contains no device on module %s", mHwModules[i]->mName);

36                continue;

37            }

38

39            if ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {

40                continue;

41            }

42            audio_devices_t profileType = outProfile->mSupportedDevices.types();

43            if ((profileType & mDefaultOutputDevice->mDeviceType) != AUDIO_DEVICE_NONE) {

44                profileType = mDefaultOutputDevice->mDeviceType;

45            } else {

46                // chose first device present in mSupportedDevices also part of

47                // outputDeviceTypes

48                for (size_t k = 0; k  < outProfile->mSupportedDevices.size(); k++) {

49                    profileType = outProfile->mSupportedDevices[k]->mDeviceType;

50                    if ((profileType & outputDeviceTypes) != 0) {

51                        break;

52                    }

53                }

54            }

55            if ((profileType & outputDeviceTypes) == 0) {

56                continue;

57            }

58            sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(outProfile);

59

60            outputDesc->mDevice = profileType;

61            audio_config_t config = AUDIO_CONFIG_INITIALIZER;

62            config.sample_rate = outputDesc->mSamplingRate;

63            config.channel_mask = outputDesc->mChannelMask;

64            config.format = outputDesc->mFormat;

65            audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;

66            status_t status = mpClientInterface->openOutput(outProfile->mModule->mHandle,

67                                                            &output,

68                                                            &config,

69                                                            &outputDesc->mDevice,

70                                                            String8(""),

71                                                            &outputDesc->mLatency,

72                                                            outputDesc->mFlags);

73

74            if (status != NO_ERROR) {

75                ALOGW("Cannot open output stream for device %08x on hw module %s",

76                      outputDesc->mDevice,

77                      mHwModules[i]->mName);

78            } else {

79                outputDesc->mSamplingRate = config.sample_rate;

80                outputDesc->mChannelMask = config.channel_mask;

81                outputDesc->mFormat = config.format;

82

83                for (size_t k = 0; k  < outProfile->mSupportedDevices.size(); k++) {

84                    audio_devices_t type = outProfile->mSupportedDevices[k]->mDeviceType;

85                    ssize_t index =

86                            mAvailableOutputDevices.indexOf(outProfile->mSupportedDevices[k]);

87                    /*如果打开的输出设备有效,为它分配一个 有效的ID,赋值对应的module*/

88                    // give a valid ID to an attached device once confirmed it is reachable

89                    if ((index >= 0) && (mAvailableOutputDevices[index]->mId == 0)) {

90                        mAvailableOutputDevices[index]->mId = nextUniqueId();

91                        mAvailableOutputDevices[index]->mModule = mHwModules[i];

92                    }

93                }

94                if (mPrimaryOutput == 0 &&

95                        outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {

96                    mPrimaryOutput = output;

97                }

98                addOutput(output, outputDesc);

99                setOutputDevice(output,

100                                outputDesc->mDevice,

101                                true);

102            }

103        }

104        // open input streams needed to access attached devices to validate

105        // mAvailableInputDevices list

106        for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)

107        {

108            const sp<IOProfile> inProfile = mHwModules[i]->mInputProfiles[j];

109

110            if (inProfile->mSupportedDevices.isEmpty()) {

111                ALOGW("Input profile contains no device on module %s", mHwModules[i]->mName);

112                continue;

113            }

114            // chose first device present in mSupportedDevices also part of

115            // inputDeviceTypes

116            audio_devices_t profileType = AUDIO_DEVICE_NONE;

117            for (size_t k = 0; k  < inProfile->mSupportedDevices.size(); k++) {

118                profileType = inProfile->mSupportedDevices[k]->mDeviceType;

119                if (profileType & inputDeviceTypes) {

120                    break;

121                }

122            }

123            if ((profileType & inputDeviceTypes) == 0) {

124                continue;

125            }

126            sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(inProfile);

127

128            inputDesc->mInputSource = AUDIO_SOURCE_MIC;

129            inputDesc->mDevice = profileType;

130

131            // find the address

132            DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(profileType);

133            //  the inputs vector must be of size 1, but we don't want to crash here

134            String8 address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress

135                    : String8("");

136            ALOGV("  for input device 0x%x using address %s", profileType, address.string());

137            ALOGE_IF(inputDevices.size() == 0, "Input device list is empty!");

138

139            audio_config_t config = AUDIO_CONFIG_INITIALIZER;

140            config.sample_rate = inputDesc->mSamplingRate;

141            config.channel_mask = inputDesc->mChannelMask;

142            config.format = inputDesc->mFormat;

143            audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;

144            status_t status = mpClientInterface->openInput(inProfile->mModule->mHandle,

145                                                            &input,

146                                                            &config,

147                                                            &inputDesc->mDevice,

148                                                            address,

149                                                            AUDIO_SOURCE_MIC,

150                                                            AUDIO_INPUT_FLAG_NONE);

151

152            if (status == NO_ERROR) {

153                for (size_t k = 0; k  < inProfile->mSupportedDevices.size(); k++) {

154                    audio_devices_t type = inProfile->mSupportedDevices[k]->mDeviceType;

155                    ssize_t index =

156                            mAvailableInputDevices.indexOf(inProfile->mSupportedDevices[k]);

157                    // give a valid ID to an attached device once confirmed it is reachable

158                    if ((index >= 0) && (mAvailableInputDevices[index]->mId == 0)) {

159                        mAvailableInputDevices[index]->mId = nextUniqueId();

160                        mAvailableInputDevices[index]->mModule = mHwModules[i];

161                    }

162                }

163                mpClientInterface->closeInput(input);

164            } else {

165                ALOGW("Cannot open input stream for device %08x on hw module %s",

166                      inputDesc->mDevice,

167                      mHwModules[i]->mName);

168            }

169        }

170    }

171   

172    /*确认mAvailableOutputDevices设备列表中的所有输出设备的id是有效的,如果无效,移除该设备*/

173    // make sure all attached devices have been allocated a unique ID

174    for (size_t i = 0; i  < mAvailableOutputDevices.size();) {

175        if (mAvailableOutputDevices[i]->mId == 0) {

176            ALOGW("Input device %08x unreachable", mAvailableOutputDevices[i]->mDeviceType);

177            mAvailableOutputDevices.remove(mAvailableOutputDevices[i]);

178            continue;

179        }

180        i++;

181    }

182    for (size_t i = 0; i  < mAvailableInputDevices.size();) {

183        if (mAvailableInputDevices[i]->mId == 0) {

184            ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->mDeviceType);

185            mAvailableInputDevices.remove(mAvailableInputDevices[i]);

186            continue;

187        }

188        i++;

189    }

190   

191    /*确认默认输出设备是有效的*/

192    // make sure default device is reachable

193    if (mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) {

194        ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->mDeviceType);

195    }

196

197    ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output");

198

199    /*更新下音频策略*/

200    updateDevicesAndOutputs();

201 }

在创建AudioPolicyManager的时候,会load audio_policy.conf文件建立起有效输出设备列表mAvailableOutputDevices 和有效输入设备列表mAvailableInputDevices。

1 status_t AudioPolicyManager::loadAudioPolicyConfig(const char *path)

2 {

3    cnode *root;

4    char *data;

5

6    data = (char *)load_file(path, NULL);

7    if (data == NULL) {

8        return -ENODEV;

9    }

10    root = config_node("", "");

11    config_load(root, data);

12

13    /*根据配置文件支持的module,分别load  audio.<primary/a2dp/usb>.<device>.so 这三个so文件 */

14    loadHwModules(root);

15    // legacy audio_policy.conf files have one global_configuration section

16    /*加载audio_policy.conf 中的global_configuration 配置*/

17    loadGlobalConfig(root, getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY));

18    config_free(root);

19    free(root);

20    free(data);

21

22    ALOGI("loadAudioPolicyConfig() loaded %s\n", path);

23 }

24

25   

配置文件中可以看到,一般平台都会支持primary, a2dp, usb三中输出方式,所以,这里会分别load三个module的so文件。如果两个地方配置文件找不到,也会创建一个默认的primary module来进行音频的输入输出。

为什么会想到看这个呢,是因为在播放的音乐的时候,选用播放模式的时候,会判断是否可以用compress_offload模式,其中,有一项判断,就是判断它的设置是否在compress_offload支持的范围,而compress_offload支持的参数,就是在此conf文件中配置的。

例如,它支持8k~48k之间的采样率,支持MP3,AAC格式,支持常见的喇叭,听筒,耳机等输出,如果设置的参数,不在此配置内,就不能使用compress_offload模式进行播放

1 compress_offload {

2        sampling_rates 8000|11025|16000|22050|32000|44100|48000

3        channel_masks AUDIO_CHANNEL_OUT_MONO|AUDIO_CHANNEL_OUT_STEREO

4        formats AUDIO_FORMAT_MP3|AUDIO_FORMAT_AAC_LC|AUDIO_FORMAT_AAC_HE_V1|AUDIO_FORMAT_AAC_HE_V2

5        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_PROXY|AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET|AUDIO_DEVICE_OUT_FM_TX

6        flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING



转载:https://www.cnblogs.com/wulizhi/p/8179067.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342