blob: 19d0b3c93fa62f4dae8a84241d2529953af67d7d [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>
Mikhail Naganov00603d12022-05-02 22:52:13 +000019#include <aidl/android/media/audio/common/AudioFormatDescription.h>
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +000020#include <aidl/android/media/audio/common/AudioFormatType.h>
21#include <aidl/android/media/audio/common/AudioIoFlags.h>
22#include <aidl/android/media/audio/common/AudioOutputFlags.h>
23
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +000024#include "core-impl/Configuration.h"
25
26using aidl::android::media::audio::common::AudioChannelLayout;
Mikhail Naganov00603d12022-05-02 22:52:13 +000027using aidl::android::media::audio::common::AudioDeviceDescription;
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +000028using aidl::android::media::audio::common::AudioDeviceType;
29using aidl::android::media::audio::common::AudioFormatDescription;
30using aidl::android::media::audio::common::AudioFormatType;
31using aidl::android::media::audio::common::AudioGainConfig;
32using aidl::android::media::audio::common::AudioIoFlags;
33using aidl::android::media::audio::common::AudioOutputFlags;
34using aidl::android::media::audio::common::AudioPort;
35using aidl::android::media::audio::common::AudioPortConfig;
36using aidl::android::media::audio::common::AudioPortDeviceExt;
37using aidl::android::media::audio::common::AudioPortExt;
38using aidl::android::media::audio::common::AudioPortMixExt;
39using aidl::android::media::audio::common::AudioProfile;
40using aidl::android::media::audio::common::Int;
41using aidl::android::media::audio::common::PcmType;
42
43namespace aidl::android::hardware::audio::core::internal {
44
45static AudioProfile createProfile(PcmType pcmType, const std::vector<int32_t>& channelLayouts,
46 const std::vector<int32_t>& sampleRates) {
47 AudioProfile profile;
48 profile.format.type = AudioFormatType::PCM;
49 profile.format.pcm = pcmType;
50 for (auto layout : channelLayouts) {
51 profile.channelMasks.push_back(
52 AudioChannelLayout::make<AudioChannelLayout::layoutMask>(layout));
53 }
54 profile.sampleRates.insert(profile.sampleRates.end(), sampleRates.begin(), sampleRates.end());
55 return profile;
56}
57
Mikhail Naganov00603d12022-05-02 22:52:13 +000058static AudioPortExt createDeviceExt(AudioDeviceType devType, int32_t flags,
59 std::string connection = "") {
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +000060 AudioPortDeviceExt deviceExt;
61 deviceExt.device.type.type = devType;
Mikhail Naganov00603d12022-05-02 22:52:13 +000062 deviceExt.device.type.connection = std::move(connection);
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +000063 deviceExt.flags = flags;
64 return AudioPortExt::make<AudioPortExt::Tag::device>(deviceExt);
65}
66
67static AudioPortExt createPortMixExt(int32_t maxOpenStreamCount, int32_t maxActiveStreamCount) {
68 AudioPortMixExt mixExt;
69 mixExt.maxOpenStreamCount = maxOpenStreamCount;
70 mixExt.maxActiveStreamCount = maxActiveStreamCount;
71 return AudioPortExt::make<AudioPortExt::Tag::mix>(mixExt);
72}
73
74static AudioPort createPort(int32_t id, const std::string& name, int32_t flags, bool isInput,
75 const AudioPortExt& ext) {
76 AudioPort port;
77 port.id = id;
78 port.name = name;
79 port.flags = isInput ? AudioIoFlags::make<AudioIoFlags::Tag::input>(flags)
80 : AudioIoFlags::make<AudioIoFlags::Tag::output>(flags);
81 port.ext = ext;
82 return port;
83}
84
85static AudioPortConfig createPortConfig(int32_t id, int32_t portId, PcmType pcmType, int32_t layout,
86 int32_t sampleRate, int32_t flags, bool isInput,
87 const AudioPortExt& ext) {
88 AudioPortConfig config;
89 config.id = id;
90 config.portId = portId;
91 config.sampleRate = Int{.value = sampleRate};
92 config.channelMask = AudioChannelLayout::make<AudioChannelLayout::layoutMask>(layout);
93 config.format = AudioFormatDescription{.type = AudioFormatType::PCM, .pcm = pcmType};
94 config.gain = AudioGainConfig();
95 config.flags = isInput ? AudioIoFlags::make<AudioIoFlags::Tag::input>(flags)
96 : AudioIoFlags::make<AudioIoFlags::Tag::output>(flags);
97 config.ext = ext;
98 return config;
99}
100
101static AudioRoute createRoute(const std::vector<int32_t>& sources, int32_t sink) {
102 AudioRoute route;
103 route.sinkPortId = sink;
104 route.sourcePortIds.insert(route.sourcePortIds.end(), sources.begin(), sources.end());
105 return route;
106}
107
Mikhail Naganov00603d12022-05-02 22:52:13 +0000108// Configuration:
109//
110// Device ports:
111// * "Null", OUT_SPEAKER, default
112// - no profiles specified
113// * "Loopback Out", OUT_SUBMIX
114// - profile PCM 24-bit; STEREO; 48000
115// * "USB Out", OUT_DEVICE, CONNECTION_USB
116// - no profiles specified
117// * "Zero", IN_MICROPHONE, default
118// - no profiles specified
119// * "Loopback In", IN_SUBMIX
120// - profile PCM 24-bit; STEREO; 48000
121// * "USB In", IN_DEVICE, CONNECTION_USB
122// - no profiles specified
123//
124// Mix ports:
125// * "primary output", PRIMARY, 1 max open, 1 max active stream
126// - profile PCM 16-bit; MONO, STEREO; 44100, 48000
127// - profile PCM 24-bit; MONO, STEREO; 44100, 48000
128// * "loopback output", stream count unlimited
129// - profile PCM 24-bit; STEREO; 48000
130// * "primary input", 2 max open, 2 max active streams
131// - profile PCM 16-bit; MONO, STEREO, FRONT_BACK;
132// 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
133// - profile PCM 24-bit; MONO, STEREO, FRONT_BACK;
134// 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
135// * "loopback input", stream count unlimited
136// - profile PCM 24-bit; STEREO; 48000
137//
138// Routes:
139// "primary out" -> "Null"
140// "primary out" -> "USB Out"
141// "loopback out" -> "Loopback Out"
142// "Zero", "USB In" -> "primary input"
143// "Loopback In" -> "loopback input"
144//
145// Initial port configs:
146// * "Null" device port: PCM 24-bit; STEREO; 48000
147// * "Zero" device port: PCM 24-bit; MONO; 48000
148//
149// Profiles for device port connected state:
150// * USB Out":
151// - profile PCM 16-bit; MONO, STEREO; 44100, 48000
152// - profile PCM 24-bit; MONO, STEREO; 44100, 48000
153// * USB In":
154// - profile PCM 16-bit; MONO, STEREO; 44100, 48000
155// - profile PCM 24-bit; MONO, STEREO; 44100, 48000
156//
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +0000157Configuration& getNullPrimaryConfiguration() {
158 static Configuration configuration = []() {
Mikhail Naganov00603d12022-05-02 22:52:13 +0000159 const std::vector<AudioProfile> standardPcmAudioProfiles = {
160 createProfile(PcmType::INT_16_BIT,
161 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
162 {44100, 48000}),
163 createProfile(PcmType::INT_24_BIT,
164 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
165 {44100, 48000})};
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +0000166 Configuration c;
167
168 AudioPort nullOutDevice =
169 createPort(c.nextPortId++, "Null", 0, false,
170 createDeviceExt(AudioDeviceType::OUT_SPEAKER,
171 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE));
172 c.ports.push_back(nullOutDevice);
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +0000173 c.initialConfigs.push_back(
174 createPortConfig(nullOutDevice.id, nullOutDevice.id, PcmType::INT_24_BIT,
175 AudioChannelLayout::LAYOUT_STEREO, 48000, 0, false,
176 createDeviceExt(AudioDeviceType::OUT_SPEAKER, 0)));
177
Mikhail Naganov00603d12022-05-02 22:52:13 +0000178 AudioPort primaryOutMix = createPort(c.nextPortId++, "primary output",
179 1 << static_cast<int32_t>(AudioOutputFlags::PRIMARY),
180 false, createPortMixExt(1, 1));
181 primaryOutMix.profiles.insert(primaryOutMix.profiles.begin(),
182 standardPcmAudioProfiles.begin(),
183 standardPcmAudioProfiles.end());
184 c.ports.push_back(primaryOutMix);
185
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +0000186 AudioPort loopOutDevice = createPort(c.nextPortId++, "Loopback Out", 0, false,
187 createDeviceExt(AudioDeviceType::OUT_SUBMIX, 0));
188 loopOutDevice.profiles.push_back(
189 createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
190 c.ports.push_back(loopOutDevice);
191
192 AudioPort loopOutMix =
193 createPort(c.nextPortId++, "loopback output", 0, false, createPortMixExt(0, 0));
194 loopOutMix.profiles.push_back(
195 createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
196 c.ports.push_back(loopOutMix);
197
Mikhail Naganov00603d12022-05-02 22:52:13 +0000198 AudioPort usbOutDevice =
199 createPort(c.nextPortId++, "USB Out", 0, false,
200 createDeviceExt(AudioDeviceType::OUT_DEVICE, 0,
201 AudioDeviceDescription::CONNECTION_USB));
202 c.ports.push_back(usbOutDevice);
203 c.connectedProfiles[usbOutDevice.id] = standardPcmAudioProfiles;
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +0000204
205 AudioPort zeroInDevice =
206 createPort(c.nextPortId++, "Zero", 0, true,
207 createDeviceExt(AudioDeviceType::IN_MICROPHONE,
208 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE));
209 c.ports.push_back(zeroInDevice);
Mikhail Naganov00603d12022-05-02 22:52:13 +0000210 c.initialConfigs.push_back(
211 createPortConfig(zeroInDevice.id, zeroInDevice.id, PcmType::INT_24_BIT,
212 AudioChannelLayout::LAYOUT_MONO, 48000, 0, true,
213 createDeviceExt(AudioDeviceType::IN_MICROPHONE, 0)));
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +0000214
215 AudioPort primaryInMix =
216 createPort(c.nextPortId++, "primary input", 0, true, createPortMixExt(2, 2));
217 primaryInMix.profiles.push_back(
218 createProfile(PcmType::INT_16_BIT,
219 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO,
220 AudioChannelLayout::LAYOUT_FRONT_BACK},
221 {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000}));
222 primaryInMix.profiles.push_back(
223 createProfile(PcmType::INT_24_BIT,
224 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO,
225 AudioChannelLayout::LAYOUT_FRONT_BACK},
226 {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000}));
227 c.ports.push_back(primaryInMix);
228
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +0000229 AudioPort loopInDevice = createPort(c.nextPortId++, "Loopback In", 0, true,
230 createDeviceExt(AudioDeviceType::IN_SUBMIX, 0));
231 loopInDevice.profiles.push_back(
232 createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
233 c.ports.push_back(loopInDevice);
234
235 AudioPort loopInMix =
236 createPort(c.nextPortId++, "loopback input", 0, true, createPortMixExt(0, 0));
237 loopInMix.profiles.push_back(
238 createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
239 c.ports.push_back(loopInMix);
240
Mikhail Naganov00603d12022-05-02 22:52:13 +0000241 AudioPort usbInDevice = createPort(c.nextPortId++, "USB In", 0, true,
242 createDeviceExt(AudioDeviceType::IN_DEVICE, 0,
243 AudioDeviceDescription::CONNECTION_USB));
244 c.ports.push_back(usbInDevice);
245 c.connectedProfiles[usbInDevice.id] = standardPcmAudioProfiles;
246
247 c.routes.push_back(createRoute({primaryOutMix.id}, nullOutDevice.id));
248 c.routes.push_back(createRoute({primaryOutMix.id}, usbOutDevice.id));
249 c.routes.push_back(createRoute({loopOutMix.id}, loopOutDevice.id));
250 c.routes.push_back(createRoute({zeroInDevice.id, usbInDevice.id}, primaryInMix.id));
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +0000251 c.routes.push_back(createRoute({loopInDevice.id}, loopInMix.id));
252
253 c.portConfigs.insert(c.portConfigs.end(), c.initialConfigs.begin(), c.initialConfigs.end());
254 return c;
255 }();
256 return configuration;
257}
258
259} // namespace aidl::android::hardware::audio::core::internal