blob: 1104caadcfdbb36e00930dbbe28757033fb085ab [file] [log] [blame]
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +00001/*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <aidl/android/media/audio/common/AudioChannelLayout.h>
18#include <aidl/android/media/audio/common/AudioDeviceType.h>
19#include <aidl/android/media/audio/common/AudioFormatType.h>
20#include <aidl/android/media/audio/common/AudioIoFlags.h>
21#include <aidl/android/media/audio/common/AudioOutputFlags.h>
22
23#include "aidl/android/media/audio/common/AudioFormatDescription.h"
24#include "core-impl/Configuration.h"
25
26using aidl::android::media::audio::common::AudioChannelLayout;
27using aidl::android::media::audio::common::AudioDeviceType;
28using aidl::android::media::audio::common::AudioFormatDescription;
29using aidl::android::media::audio::common::AudioFormatType;
30using aidl::android::media::audio::common::AudioGainConfig;
31using aidl::android::media::audio::common::AudioIoFlags;
32using aidl::android::media::audio::common::AudioOutputFlags;
33using aidl::android::media::audio::common::AudioPort;
34using aidl::android::media::audio::common::AudioPortConfig;
35using aidl::android::media::audio::common::AudioPortDeviceExt;
36using aidl::android::media::audio::common::AudioPortExt;
37using aidl::android::media::audio::common::AudioPortMixExt;
38using aidl::android::media::audio::common::AudioProfile;
39using aidl::android::media::audio::common::Int;
40using aidl::android::media::audio::common::PcmType;
41
42namespace aidl::android::hardware::audio::core::internal {
43
44static AudioProfile createProfile(PcmType pcmType, const std::vector<int32_t>& channelLayouts,
45 const std::vector<int32_t>& sampleRates) {
46 AudioProfile profile;
47 profile.format.type = AudioFormatType::PCM;
48 profile.format.pcm = pcmType;
49 for (auto layout : channelLayouts) {
50 profile.channelMasks.push_back(
51 AudioChannelLayout::make<AudioChannelLayout::layoutMask>(layout));
52 }
53 profile.sampleRates.insert(profile.sampleRates.end(), sampleRates.begin(), sampleRates.end());
54 return profile;
55}
56
57static AudioPortExt createDeviceExt(AudioDeviceType devType, int32_t flags) {
58 AudioPortDeviceExt deviceExt;
59 deviceExt.device.type.type = devType;
60 deviceExt.flags = flags;
61 return AudioPortExt::make<AudioPortExt::Tag::device>(deviceExt);
62}
63
64static AudioPortExt createPortMixExt(int32_t maxOpenStreamCount, int32_t maxActiveStreamCount) {
65 AudioPortMixExt mixExt;
66 mixExt.maxOpenStreamCount = maxOpenStreamCount;
67 mixExt.maxActiveStreamCount = maxActiveStreamCount;
68 return AudioPortExt::make<AudioPortExt::Tag::mix>(mixExt);
69}
70
71static AudioPort createPort(int32_t id, const std::string& name, int32_t flags, bool isInput,
72 const AudioPortExt& ext) {
73 AudioPort port;
74 port.id = id;
75 port.name = name;
76 port.flags = isInput ? AudioIoFlags::make<AudioIoFlags::Tag::input>(flags)
77 : AudioIoFlags::make<AudioIoFlags::Tag::output>(flags);
78 port.ext = ext;
79 return port;
80}
81
82static AudioPortConfig createPortConfig(int32_t id, int32_t portId, PcmType pcmType, int32_t layout,
83 int32_t sampleRate, int32_t flags, bool isInput,
84 const AudioPortExt& ext) {
85 AudioPortConfig config;
86 config.id = id;
87 config.portId = portId;
88 config.sampleRate = Int{.value = sampleRate};
89 config.channelMask = AudioChannelLayout::make<AudioChannelLayout::layoutMask>(layout);
90 config.format = AudioFormatDescription{.type = AudioFormatType::PCM, .pcm = pcmType};
91 config.gain = AudioGainConfig();
92 config.flags = isInput ? AudioIoFlags::make<AudioIoFlags::Tag::input>(flags)
93 : AudioIoFlags::make<AudioIoFlags::Tag::output>(flags);
94 config.ext = ext;
95 return config;
96}
97
98static AudioRoute createRoute(const std::vector<int32_t>& sources, int32_t sink) {
99 AudioRoute route;
100 route.sinkPortId = sink;
101 route.sourcePortIds.insert(route.sourcePortIds.end(), sources.begin(), sources.end());
102 return route;
103}
104
105Configuration& getNullPrimaryConfiguration() {
106 static Configuration configuration = []() {
107 Configuration c;
108
109 AudioPort nullOutDevice =
110 createPort(c.nextPortId++, "Null", 0, false,
111 createDeviceExt(AudioDeviceType::OUT_SPEAKER,
112 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE));
113 c.ports.push_back(nullOutDevice);
114
115 AudioPort primaryOutMix = createPort(c.nextPortId++, "primary output",
116 1 << static_cast<int32_t>(AudioOutputFlags::PRIMARY),
117 false, createPortMixExt(1, 1));
118 primaryOutMix.profiles.push_back(
119 createProfile(PcmType::INT_16_BIT,
120 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
121 {44100, 48000}));
122 primaryOutMix.profiles.push_back(
123 createProfile(PcmType::INT_24_BIT,
124 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
125 {44100, 48000}));
126 c.ports.push_back(primaryOutMix);
127
128 c.routes.push_back(createRoute({primaryOutMix.id}, nullOutDevice.id));
129
130 c.initialConfigs.push_back(
131 createPortConfig(nullOutDevice.id, nullOutDevice.id, PcmType::INT_24_BIT,
132 AudioChannelLayout::LAYOUT_STEREO, 48000, 0, false,
133 createDeviceExt(AudioDeviceType::OUT_SPEAKER, 0)));
134
135 AudioPort loopOutDevice = createPort(c.nextPortId++, "Loopback Out", 0, false,
136 createDeviceExt(AudioDeviceType::OUT_SUBMIX, 0));
137 loopOutDevice.profiles.push_back(
138 createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
139 c.ports.push_back(loopOutDevice);
140
141 AudioPort loopOutMix =
142 createPort(c.nextPortId++, "loopback output", 0, false, createPortMixExt(0, 0));
143 loopOutMix.profiles.push_back(
144 createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
145 c.ports.push_back(loopOutMix);
146
147 c.routes.push_back(createRoute({loopOutMix.id}, loopOutDevice.id));
148
149 AudioPort zeroInDevice =
150 createPort(c.nextPortId++, "Zero", 0, true,
151 createDeviceExt(AudioDeviceType::IN_MICROPHONE,
152 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE));
153 c.ports.push_back(zeroInDevice);
154
155 AudioPort primaryInMix =
156 createPort(c.nextPortId++, "primary input", 0, true, createPortMixExt(2, 2));
157 primaryInMix.profiles.push_back(
158 createProfile(PcmType::INT_16_BIT,
159 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO,
160 AudioChannelLayout::LAYOUT_FRONT_BACK},
161 {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000}));
162 primaryInMix.profiles.push_back(
163 createProfile(PcmType::INT_24_BIT,
164 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO,
165 AudioChannelLayout::LAYOUT_FRONT_BACK},
166 {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000}));
167 c.ports.push_back(primaryInMix);
168
169 c.routes.push_back(createRoute({zeroInDevice.id}, primaryInMix.id));
170
171 c.initialConfigs.push_back(
172 createPortConfig(zeroInDevice.id, zeroInDevice.id, PcmType::INT_24_BIT,
173 AudioChannelLayout::LAYOUT_MONO, 48000, 0, true,
174 createDeviceExt(AudioDeviceType::IN_MICROPHONE, 0)));
175
176 AudioPort loopInDevice = createPort(c.nextPortId++, "Loopback In", 0, true,
177 createDeviceExt(AudioDeviceType::IN_SUBMIX, 0));
178 loopInDevice.profiles.push_back(
179 createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
180 c.ports.push_back(loopInDevice);
181
182 AudioPort loopInMix =
183 createPort(c.nextPortId++, "loopback input", 0, true, createPortMixExt(0, 0));
184 loopInMix.profiles.push_back(
185 createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
186 c.ports.push_back(loopInMix);
187
188 c.routes.push_back(createRoute({loopInDevice.id}, loopInMix.id));
189
190 c.portConfigs.insert(c.portConfigs.end(), c.initialConfigs.begin(), c.initialConfigs.end());
191 return c;
192 }();
193 return configuration;
194}
195
196} // namespace aidl::android::hardware::audio::core::internal