blob: f5d679bd3e7d5da59303c64a6f1307945df3f415 [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>
Mikhail Naganov111e0ce2022-06-17 21:41:19 +000023#include <media/stagefright/foundation/MediaDefs.h>
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +000024
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +000025#include "core-impl/Configuration.h"
26
27using aidl::android::media::audio::common::AudioChannelLayout;
Mikhail Naganov00603d12022-05-02 22:52:13 +000028using aidl::android::media::audio::common::AudioDeviceDescription;
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +000029using aidl::android::media::audio::common::AudioDeviceType;
30using aidl::android::media::audio::common::AudioFormatDescription;
31using aidl::android::media::audio::common::AudioFormatType;
32using aidl::android::media::audio::common::AudioGainConfig;
33using aidl::android::media::audio::common::AudioIoFlags;
34using aidl::android::media::audio::common::AudioOutputFlags;
35using aidl::android::media::audio::common::AudioPort;
36using aidl::android::media::audio::common::AudioPortConfig;
37using aidl::android::media::audio::common::AudioPortDeviceExt;
38using aidl::android::media::audio::common::AudioPortExt;
39using aidl::android::media::audio::common::AudioPortMixExt;
40using aidl::android::media::audio::common::AudioProfile;
41using aidl::android::media::audio::common::Int;
42using aidl::android::media::audio::common::PcmType;
43
44namespace aidl::android::hardware::audio::core::internal {
45
Mikhail Naganov111e0ce2022-06-17 21:41:19 +000046static void fillProfile(AudioProfile* profile, const std::vector<int32_t>& channelLayouts,
47 const std::vector<int32_t>& sampleRates) {
48 for (auto layout : channelLayouts) {
49 profile->channelMasks.push_back(
50 AudioChannelLayout::make<AudioChannelLayout::layoutMask>(layout));
51 }
52 profile->sampleRates.insert(profile->sampleRates.end(), sampleRates.begin(), sampleRates.end());
53}
54
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +000055static AudioProfile createProfile(PcmType pcmType, const std::vector<int32_t>& channelLayouts,
56 const std::vector<int32_t>& sampleRates) {
57 AudioProfile profile;
58 profile.format.type = AudioFormatType::PCM;
59 profile.format.pcm = pcmType;
Mikhail Naganov111e0ce2022-06-17 21:41:19 +000060 fillProfile(&profile, channelLayouts, sampleRates);
61 return profile;
62}
63
64static AudioProfile createProfile(const std::string& encodingType,
65 const std::vector<int32_t>& channelLayouts,
66 const std::vector<int32_t>& sampleRates) {
67 AudioProfile profile;
68 profile.format.encoding = encodingType;
69 fillProfile(&profile, channelLayouts, sampleRates);
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +000070 return profile;
71}
72
Mikhail Naganov00603d12022-05-02 22:52:13 +000073static AudioPortExt createDeviceExt(AudioDeviceType devType, int32_t flags,
74 std::string connection = "") {
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +000075 AudioPortDeviceExt deviceExt;
76 deviceExt.device.type.type = devType;
Mikhail Naganov00603d12022-05-02 22:52:13 +000077 deviceExt.device.type.connection = std::move(connection);
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +000078 deviceExt.flags = flags;
79 return AudioPortExt::make<AudioPortExt::Tag::device>(deviceExt);
80}
81
82static AudioPortExt createPortMixExt(int32_t maxOpenStreamCount, int32_t maxActiveStreamCount) {
83 AudioPortMixExt mixExt;
84 mixExt.maxOpenStreamCount = maxOpenStreamCount;
85 mixExt.maxActiveStreamCount = maxActiveStreamCount;
86 return AudioPortExt::make<AudioPortExt::Tag::mix>(mixExt);
87}
88
89static AudioPort createPort(int32_t id, const std::string& name, int32_t flags, bool isInput,
90 const AudioPortExt& ext) {
91 AudioPort port;
92 port.id = id;
93 port.name = name;
94 port.flags = isInput ? AudioIoFlags::make<AudioIoFlags::Tag::input>(flags)
95 : AudioIoFlags::make<AudioIoFlags::Tag::output>(flags);
96 port.ext = ext;
97 return port;
98}
99
100static AudioPortConfig createPortConfig(int32_t id, int32_t portId, PcmType pcmType, int32_t layout,
101 int32_t sampleRate, int32_t flags, bool isInput,
102 const AudioPortExt& ext) {
103 AudioPortConfig config;
104 config.id = id;
105 config.portId = portId;
106 config.sampleRate = Int{.value = sampleRate};
107 config.channelMask = AudioChannelLayout::make<AudioChannelLayout::layoutMask>(layout);
108 config.format = AudioFormatDescription{.type = AudioFormatType::PCM, .pcm = pcmType};
109 config.gain = AudioGainConfig();
110 config.flags = isInput ? AudioIoFlags::make<AudioIoFlags::Tag::input>(flags)
111 : AudioIoFlags::make<AudioIoFlags::Tag::output>(flags);
112 config.ext = ext;
113 return config;
114}
115
116static AudioRoute createRoute(const std::vector<int32_t>& sources, int32_t sink) {
117 AudioRoute route;
118 route.sinkPortId = sink;
119 route.sourcePortIds.insert(route.sourcePortIds.end(), sources.begin(), sources.end());
120 return route;
121}
122
Mikhail Naganov00603d12022-05-02 22:52:13 +0000123// Configuration:
124//
125// Device ports:
126// * "Null", OUT_SPEAKER, default
127// - no profiles specified
128// * "Loopback Out", OUT_SUBMIX
129// - profile PCM 24-bit; STEREO; 48000
130// * "USB Out", OUT_DEVICE, CONNECTION_USB
131// - no profiles specified
132// * "Zero", IN_MICROPHONE, default
133// - no profiles specified
134// * "Loopback In", IN_SUBMIX
135// - profile PCM 24-bit; STEREO; 48000
136// * "USB In", IN_DEVICE, CONNECTION_USB
137// - no profiles specified
138//
139// Mix ports:
140// * "primary output", PRIMARY, 1 max open, 1 max active stream
141// - profile PCM 16-bit; MONO, STEREO; 44100, 48000
142// - profile PCM 24-bit; MONO, STEREO; 44100, 48000
Mikhail Naganov111e0ce2022-06-17 21:41:19 +0000143// * "compressed offload", DIRECT|COMPRESS_OFFLOAD|NON_BLOCKING, 1 max open, 1 max active stream
144// - profile MP3; MONO, STEREO; 44100, 48000
Mikhail Naganov00603d12022-05-02 22:52:13 +0000145// * "loopback output", stream count unlimited
146// - profile PCM 24-bit; STEREO; 48000
147// * "primary input", 2 max open, 2 max active streams
148// - profile PCM 16-bit; MONO, STEREO, FRONT_BACK;
149// 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
150// - profile PCM 24-bit; MONO, STEREO, FRONT_BACK;
151// 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
152// * "loopback input", stream count unlimited
153// - profile PCM 24-bit; STEREO; 48000
154//
155// Routes:
Mikhail Naganov111e0ce2022-06-17 21:41:19 +0000156// "primary out", "compressed offload" -> "Null"
157// "primary out", "compressed offload" -> "USB Out"
Mikhail Naganov00603d12022-05-02 22:52:13 +0000158// "loopback out" -> "Loopback Out"
159// "Zero", "USB In" -> "primary input"
160// "Loopback In" -> "loopback input"
161//
162// Initial port configs:
163// * "Null" device port: PCM 24-bit; STEREO; 48000
164// * "Zero" device port: PCM 24-bit; MONO; 48000
165//
166// Profiles for device port connected state:
167// * USB Out":
168// - profile PCM 16-bit; MONO, STEREO; 44100, 48000
169// - profile PCM 24-bit; MONO, STEREO; 44100, 48000
170// * USB In":
171// - profile PCM 16-bit; MONO, STEREO; 44100, 48000
172// - profile PCM 24-bit; MONO, STEREO; 44100, 48000
173//
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +0000174Configuration& getNullPrimaryConfiguration() {
175 static Configuration configuration = []() {
Mikhail Naganov00603d12022-05-02 22:52:13 +0000176 const std::vector<AudioProfile> standardPcmAudioProfiles = {
177 createProfile(PcmType::INT_16_BIT,
178 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
179 {44100, 48000}),
180 createProfile(PcmType::INT_24_BIT,
181 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
182 {44100, 48000})};
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +0000183 Configuration c;
184
185 AudioPort nullOutDevice =
186 createPort(c.nextPortId++, "Null", 0, false,
187 createDeviceExt(AudioDeviceType::OUT_SPEAKER,
188 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE));
189 c.ports.push_back(nullOutDevice);
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +0000190 c.initialConfigs.push_back(
191 createPortConfig(nullOutDevice.id, nullOutDevice.id, PcmType::INT_24_BIT,
192 AudioChannelLayout::LAYOUT_STEREO, 48000, 0, false,
193 createDeviceExt(AudioDeviceType::OUT_SPEAKER, 0)));
194
Mikhail Naganov00603d12022-05-02 22:52:13 +0000195 AudioPort primaryOutMix = createPort(c.nextPortId++, "primary output",
196 1 << static_cast<int32_t>(AudioOutputFlags::PRIMARY),
197 false, createPortMixExt(1, 1));
198 primaryOutMix.profiles.insert(primaryOutMix.profiles.begin(),
199 standardPcmAudioProfiles.begin(),
200 standardPcmAudioProfiles.end());
201 c.ports.push_back(primaryOutMix);
202
Mikhail Naganov111e0ce2022-06-17 21:41:19 +0000203 AudioPort compressedOffloadOutMix =
204 createPort(c.nextPortId++, "compressed offload",
205 1 << static_cast<int32_t>(AudioOutputFlags::DIRECT) |
206 1 << static_cast<int32_t>(AudioOutputFlags::COMPRESS_OFFLOAD) |
207 1 << static_cast<int32_t>(AudioOutputFlags::NON_BLOCKING),
208 false, createPortMixExt(1, 1));
209 compressedOffloadOutMix.profiles.push_back(
210 createProfile(::android::MEDIA_MIMETYPE_AUDIO_MPEG,
211 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
212 {44100, 48000}));
213 c.ports.push_back(compressedOffloadOutMix);
214
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +0000215 AudioPort loopOutDevice = createPort(c.nextPortId++, "Loopback Out", 0, false,
216 createDeviceExt(AudioDeviceType::OUT_SUBMIX, 0));
217 loopOutDevice.profiles.push_back(
218 createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
219 c.ports.push_back(loopOutDevice);
220
221 AudioPort loopOutMix =
222 createPort(c.nextPortId++, "loopback output", 0, false, createPortMixExt(0, 0));
223 loopOutMix.profiles.push_back(
224 createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
225 c.ports.push_back(loopOutMix);
226
Mikhail Naganov00603d12022-05-02 22:52:13 +0000227 AudioPort usbOutDevice =
228 createPort(c.nextPortId++, "USB Out", 0, false,
229 createDeviceExt(AudioDeviceType::OUT_DEVICE, 0,
230 AudioDeviceDescription::CONNECTION_USB));
231 c.ports.push_back(usbOutDevice);
232 c.connectedProfiles[usbOutDevice.id] = standardPcmAudioProfiles;
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +0000233
234 AudioPort zeroInDevice =
235 createPort(c.nextPortId++, "Zero", 0, true,
236 createDeviceExt(AudioDeviceType::IN_MICROPHONE,
237 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE));
238 c.ports.push_back(zeroInDevice);
Mikhail Naganov00603d12022-05-02 22:52:13 +0000239 c.initialConfigs.push_back(
240 createPortConfig(zeroInDevice.id, zeroInDevice.id, PcmType::INT_24_BIT,
241 AudioChannelLayout::LAYOUT_MONO, 48000, 0, true,
242 createDeviceExt(AudioDeviceType::IN_MICROPHONE, 0)));
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +0000243
244 AudioPort primaryInMix =
245 createPort(c.nextPortId++, "primary input", 0, true, createPortMixExt(2, 2));
246 primaryInMix.profiles.push_back(
247 createProfile(PcmType::INT_16_BIT,
248 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO,
249 AudioChannelLayout::LAYOUT_FRONT_BACK},
250 {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000}));
251 primaryInMix.profiles.push_back(
252 createProfile(PcmType::INT_24_BIT,
253 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO,
254 AudioChannelLayout::LAYOUT_FRONT_BACK},
255 {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000}));
256 c.ports.push_back(primaryInMix);
257
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +0000258 AudioPort loopInDevice = createPort(c.nextPortId++, "Loopback In", 0, true,
259 createDeviceExt(AudioDeviceType::IN_SUBMIX, 0));
260 loopInDevice.profiles.push_back(
261 createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
262 c.ports.push_back(loopInDevice);
263
264 AudioPort loopInMix =
265 createPort(c.nextPortId++, "loopback input", 0, true, createPortMixExt(0, 0));
266 loopInMix.profiles.push_back(
267 createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
268 c.ports.push_back(loopInMix);
269
Mikhail Naganov00603d12022-05-02 22:52:13 +0000270 AudioPort usbInDevice = createPort(c.nextPortId++, "USB In", 0, true,
271 createDeviceExt(AudioDeviceType::IN_DEVICE, 0,
272 AudioDeviceDescription::CONNECTION_USB));
273 c.ports.push_back(usbInDevice);
274 c.connectedProfiles[usbInDevice.id] = standardPcmAudioProfiles;
275
Mikhail Naganov111e0ce2022-06-17 21:41:19 +0000276 c.routes.push_back(
277 createRoute({primaryOutMix.id, compressedOffloadOutMix.id}, nullOutDevice.id));
278 c.routes.push_back(
279 createRoute({primaryOutMix.id, compressedOffloadOutMix.id}, usbOutDevice.id));
Mikhail Naganov00603d12022-05-02 22:52:13 +0000280 c.routes.push_back(createRoute({loopOutMix.id}, loopOutDevice.id));
281 c.routes.push_back(createRoute({zeroInDevice.id, usbInDevice.id}, primaryInMix.id));
Mikhail Naganovdf5adfd2021-11-11 22:09:22 +0000282 c.routes.push_back(createRoute({loopInDevice.id}, loopInMix.id));
283
284 c.portConfigs.insert(c.portConfigs.end(), c.initialConfigs.begin(), c.initialConfigs.end());
285 return c;
286 }();
287 return configuration;
288}
289
290} // namespace aidl::android::hardware::audio::core::internal