1 /*
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 <Utils.h>
18 #include <aidl/android/media/audio/common/AudioChannelLayout.h>
19 #include <aidl/android/media/audio/common/AudioDeviceType.h>
20 #include <aidl/android/media/audio/common/AudioFormatDescription.h>
21 #include <aidl/android/media/audio/common/AudioFormatType.h>
22 #include <aidl/android/media/audio/common/AudioIoFlags.h>
23 #include <aidl/android/media/audio/common/AudioOutputFlags.h>
24 #include <media/stagefright/foundation/MediaDefs.h>
25
26 #include "core-impl/Configuration.h"
27
28 using aidl::android::hardware::audio::common::makeBitPositionFlagMask;
29 using aidl::android::media::audio::common::AudioChannelLayout;
30 using aidl::android::media::audio::common::AudioDeviceDescription;
31 using aidl::android::media::audio::common::AudioDeviceType;
32 using aidl::android::media::audio::common::AudioFormatDescription;
33 using aidl::android::media::audio::common::AudioFormatType;
34 using aidl::android::media::audio::common::AudioGainConfig;
35 using aidl::android::media::audio::common::AudioIoFlags;
36 using aidl::android::media::audio::common::AudioOutputFlags;
37 using aidl::android::media::audio::common::AudioPort;
38 using aidl::android::media::audio::common::AudioPortConfig;
39 using aidl::android::media::audio::common::AudioPortDeviceExt;
40 using aidl::android::media::audio::common::AudioPortExt;
41 using aidl::android::media::audio::common::AudioPortMixExt;
42 using aidl::android::media::audio::common::AudioProfile;
43 using aidl::android::media::audio::common::Int;
44 using aidl::android::media::audio::common::MicrophoneInfo;
45 using aidl::android::media::audio::common::PcmType;
46
47 namespace aidl::android::hardware::audio::core::internal {
48
fillProfile(AudioProfile * profile,const std::vector<int32_t> & channelLayouts,const std::vector<int32_t> & sampleRates)49 static void fillProfile(AudioProfile* profile, const std::vector<int32_t>& channelLayouts,
50 const std::vector<int32_t>& sampleRates) {
51 for (auto layout : channelLayouts) {
52 profile->channelMasks.push_back(
53 AudioChannelLayout::make<AudioChannelLayout::layoutMask>(layout));
54 }
55 profile->sampleRates.insert(profile->sampleRates.end(), sampleRates.begin(), sampleRates.end());
56 }
57
createProfile(PcmType pcmType,const std::vector<int32_t> & channelLayouts,const std::vector<int32_t> & sampleRates)58 static AudioProfile createProfile(PcmType pcmType, const std::vector<int32_t>& channelLayouts,
59 const std::vector<int32_t>& sampleRates) {
60 AudioProfile profile;
61 profile.format.type = AudioFormatType::PCM;
62 profile.format.pcm = pcmType;
63 fillProfile(&profile, channelLayouts, sampleRates);
64 return profile;
65 }
66
createProfile(const std::string & encodingType,const std::vector<int32_t> & channelLayouts,const std::vector<int32_t> & sampleRates)67 static AudioProfile createProfile(const std::string& encodingType,
68 const std::vector<int32_t>& channelLayouts,
69 const std::vector<int32_t>& sampleRates) {
70 AudioProfile profile;
71 profile.format.encoding = encodingType;
72 fillProfile(&profile, channelLayouts, sampleRates);
73 return profile;
74 }
75
createDeviceExt(AudioDeviceType devType,int32_t flags,std::string connection="")76 static AudioPortExt createDeviceExt(AudioDeviceType devType, int32_t flags,
77 std::string connection = "") {
78 AudioPortDeviceExt deviceExt;
79 deviceExt.device.type.type = devType;
80 if (devType == AudioDeviceType::IN_MICROPHONE && connection.empty()) {
81 deviceExt.device.address = "bottom";
82 } else if (devType == AudioDeviceType::IN_MICROPHONE_BACK && connection.empty()) {
83 deviceExt.device.address = "back";
84 }
85 deviceExt.device.type.connection = std::move(connection);
86 deviceExt.flags = flags;
87 return AudioPortExt::make<AudioPortExt::Tag::device>(deviceExt);
88 }
89
createPortMixExt(int32_t maxOpenStreamCount,int32_t maxActiveStreamCount)90 static AudioPortExt createPortMixExt(int32_t maxOpenStreamCount, int32_t maxActiveStreamCount) {
91 AudioPortMixExt mixExt;
92 mixExt.maxOpenStreamCount = maxOpenStreamCount;
93 mixExt.maxActiveStreamCount = maxActiveStreamCount;
94 return AudioPortExt::make<AudioPortExt::Tag::mix>(mixExt);
95 }
96
createPort(int32_t id,const std::string & name,int32_t flags,bool isInput,const AudioPortExt & ext)97 static AudioPort createPort(int32_t id, const std::string& name, int32_t flags, bool isInput,
98 const AudioPortExt& ext) {
99 AudioPort port;
100 port.id = id;
101 port.name = name;
102 port.flags = isInput ? AudioIoFlags::make<AudioIoFlags::Tag::input>(flags)
103 : AudioIoFlags::make<AudioIoFlags::Tag::output>(flags);
104 port.ext = ext;
105 return port;
106 }
107
createPortConfig(int32_t id,int32_t portId,PcmType pcmType,int32_t layout,int32_t sampleRate,int32_t flags,bool isInput,const AudioPortExt & ext)108 static AudioPortConfig createPortConfig(int32_t id, int32_t portId, PcmType pcmType, int32_t layout,
109 int32_t sampleRate, int32_t flags, bool isInput,
110 const AudioPortExt& ext) {
111 AudioPortConfig config;
112 config.id = id;
113 config.portId = portId;
114 config.sampleRate = Int{.value = sampleRate};
115 config.channelMask = AudioChannelLayout::make<AudioChannelLayout::layoutMask>(layout);
116 config.format = AudioFormatDescription{.type = AudioFormatType::PCM, .pcm = pcmType};
117 config.gain = AudioGainConfig();
118 config.flags = isInput ? AudioIoFlags::make<AudioIoFlags::Tag::input>(flags)
119 : AudioIoFlags::make<AudioIoFlags::Tag::output>(flags);
120 config.ext = ext;
121 return config;
122 }
123
createRoute(const std::vector<AudioPort> & sources,const AudioPort & sink)124 static AudioRoute createRoute(const std::vector<AudioPort>& sources, const AudioPort& sink) {
125 AudioRoute route;
126 route.sinkPortId = sink.id;
127 std::transform(sources.begin(), sources.end(), std::back_inserter(route.sourcePortIds),
128 [](const auto& port) { return port.id; });
129 return route;
130 }
131
132 // Primary (default) configuration:
133 //
134 // Device ports:
135 // * "Speaker", OUT_SPEAKER, default
136 // - no profiles specified
137 // * "Built-In Mic", IN_MICROPHONE, default
138 // - no profiles specified
139 // * "Telephony Tx", OUT_TELEPHONY_TX
140 // - no profiles specified
141 // * "Telephony Rx", IN_TELEPHONY_RX
142 // - no profiles specified
143 // * "FM Tuner", IN_FM_TUNER
144 // - no profiles specified
145 //
146 // Mix ports:
147 // * "primary output", PRIMARY, 1 max open, 1 max active stream
148 // - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
149 // * "primary input", 1 max open, 1 max active stream
150 // - profile PCM 16-bit; MONO, STEREO;
151 // 8000, 11025, 16000, 32000, 44100, 48000
152 // * "telephony_tx", 1 max open, 1 max active stream
153 // - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
154 // * "telephony_rx", 1 max open, 1 max active stream
155 // - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
156 // * "fm_tuner", 1 max open, 1 max active stream
157 // - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
158 //
159 // Routes:
160 // "primary out" -> "Speaker"
161 // "Built-In Mic" -> "primary input"
162 // "Telephony Rx" -> "telephony_rx"
163 // "telephony_tx" -> "Telephony Tx"
164 // "FM Tuner" -> "fm_tuner"
165 //
166 // Initial port configs:
167 // * "Speaker" device port: PCM 16-bit; STEREO; 48000
168 // * "Built-In Mic" device port: PCM 16-bit; MONO; 48000
169 // * "Telephony Tx" device port: PCM 16-bit; MONO; 48000
170 // * "Telephony Rx" device port: PCM 16-bit; MONO; 48000
171 // * "FM Tuner" device port: PCM 16-bit; STEREO; 48000
172 //
getPrimaryConfiguration()173 std::unique_ptr<Configuration> getPrimaryConfiguration() {
174 static const Configuration configuration = []() {
175 const std::vector<AudioProfile> standardPcmAudioProfiles = {
176 createProfile(PcmType::INT_16_BIT,
177 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
178 {8000, 11025, 16000, 32000, 44100, 48000})};
179 Configuration c;
180
181 // Device ports
182
183 AudioPort speakerOutDevice =
184 createPort(c.nextPortId++, "Speaker", 0, false,
185 createDeviceExt(AudioDeviceType::OUT_SPEAKER,
186 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE));
187 c.ports.push_back(speakerOutDevice);
188 c.initialConfigs.push_back(
189 createPortConfig(speakerOutDevice.id, speakerOutDevice.id, PcmType::INT_16_BIT,
190 AudioChannelLayout::LAYOUT_STEREO, 48000, 0, false,
191 createDeviceExt(AudioDeviceType::OUT_SPEAKER, 0)));
192
193 AudioPort micInDevice =
194 createPort(c.nextPortId++, "Built-In Mic", 0, true,
195 createDeviceExt(AudioDeviceType::IN_MICROPHONE,
196 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE));
197 c.ports.push_back(micInDevice);
198 c.initialConfigs.push_back(
199 createPortConfig(micInDevice.id, micInDevice.id, PcmType::INT_16_BIT,
200 AudioChannelLayout::LAYOUT_MONO, 48000, 0, true,
201 createDeviceExt(AudioDeviceType::IN_MICROPHONE, 0)));
202
203 AudioPort telephonyTxOutDevice =
204 createPort(c.nextPortId++, "Telephony Tx", 0, false,
205 createDeviceExt(AudioDeviceType::OUT_TELEPHONY_TX, 0));
206 c.ports.push_back(telephonyTxOutDevice);
207 c.initialConfigs.push_back(
208 createPortConfig(telephonyTxOutDevice.id, telephonyTxOutDevice.id,
209 PcmType::INT_16_BIT, AudioChannelLayout::LAYOUT_MONO, 48000, 0,
210 false, createDeviceExt(AudioDeviceType::OUT_TELEPHONY_TX, 0)));
211
212 AudioPort telephonyRxInDevice =
213 createPort(c.nextPortId++, "Telephony Rx", 0, true,
214 createDeviceExt(AudioDeviceType::IN_TELEPHONY_RX, 0));
215 c.ports.push_back(telephonyRxInDevice);
216 c.initialConfigs.push_back(
217 createPortConfig(telephonyRxInDevice.id, telephonyRxInDevice.id,
218 PcmType::INT_16_BIT, AudioChannelLayout::LAYOUT_MONO, 48000, 0,
219 true, createDeviceExt(AudioDeviceType::IN_TELEPHONY_RX, 0)));
220
221 AudioPort fmTunerInDevice = createPort(c.nextPortId++, "FM Tuner", 0, true,
222 createDeviceExt(AudioDeviceType::IN_FM_TUNER, 0));
223 c.ports.push_back(fmTunerInDevice);
224 c.initialConfigs.push_back(
225 createPortConfig(fmTunerInDevice.id, fmTunerInDevice.id, PcmType::INT_16_BIT,
226 AudioChannelLayout::LAYOUT_STEREO, 48000, 0, true,
227 createDeviceExt(AudioDeviceType::IN_FM_TUNER, 0)));
228
229 // Mix ports
230
231 AudioPort primaryOutMix = createPort(c.nextPortId++, "primary output",
232 makeBitPositionFlagMask(AudioOutputFlags::PRIMARY),
233 false, createPortMixExt(0, 0));
234 primaryOutMix.profiles.insert(primaryOutMix.profiles.begin(),
235 standardPcmAudioProfiles.begin(),
236 standardPcmAudioProfiles.end());
237 c.ports.push_back(primaryOutMix);
238
239 AudioPort primaryInMix =
240 createPort(c.nextPortId++, "primary input", 0, true, createPortMixExt(0, 0));
241 primaryInMix.profiles.push_back(
242 createProfile(PcmType::INT_16_BIT,
243 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
244 {8000, 11025, 16000, 32000, 44100, 48000}));
245 c.ports.push_back(primaryInMix);
246
247 AudioPort telephonyTxOutMix =
248 createPort(c.nextPortId++, "telephony_tx", 0, false, createPortMixExt(1, 1));
249 telephonyTxOutMix.profiles.insert(telephonyTxOutMix.profiles.begin(),
250 standardPcmAudioProfiles.begin(),
251 standardPcmAudioProfiles.end());
252 c.ports.push_back(telephonyTxOutMix);
253
254 AudioPort telephonyRxInMix =
255 createPort(c.nextPortId++, "telephony_rx", 0, true, createPortMixExt(1, 1));
256 telephonyRxInMix.profiles.insert(telephonyRxInMix.profiles.begin(),
257 standardPcmAudioProfiles.begin(),
258 standardPcmAudioProfiles.end());
259 c.ports.push_back(telephonyRxInMix);
260
261 AudioPort fmTunerInMix =
262 createPort(c.nextPortId++, "fm_tuner", 0, true, createPortMixExt(1, 1));
263 fmTunerInMix.profiles.insert(fmTunerInMix.profiles.begin(),
264 standardPcmAudioProfiles.begin(),
265 standardPcmAudioProfiles.end());
266 c.ports.push_back(fmTunerInMix);
267
268 c.routes.push_back(createRoute({primaryOutMix}, speakerOutDevice));
269 c.routes.push_back(createRoute({micInDevice}, primaryInMix));
270 c.routes.push_back(createRoute({telephonyRxInDevice}, telephonyRxInMix));
271 c.routes.push_back(createRoute({telephonyTxOutMix}, telephonyTxOutDevice));
272 c.routes.push_back(createRoute({fmTunerInDevice}, fmTunerInMix));
273
274 c.portConfigs.insert(c.portConfigs.end(), c.initialConfigs.begin(), c.initialConfigs.end());
275
276 MicrophoneInfo mic;
277 mic.id = "mic";
278 mic.device = micInDevice.ext.get<AudioPortExt::Tag::device>().device;
279 mic.group = 0;
280 mic.indexInTheGroup = 0;
281 c.microphones = std::vector<MicrophoneInfo>{mic};
282
283 return c;
284 }();
285 return std::make_unique<Configuration>(configuration);
286 }
287
288 // Remote Submix configuration:
289 //
290 // Device ports:
291 // * "Remote Submix Out", OUT_SUBMIX
292 // - no profiles specified
293 // * "Remote Submix In", IN_SUBMIX
294 // - no profiles specified
295 //
296 // Mix ports:
297 // * "r_submix output", unlimited max open, unlimited max active stream
298 // - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
299 // - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
300 // - profile PCM 32-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
301 // - profile PCM 32-bit float; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
302 // * "r_submix input", unlimited max open, unlimited max active stream
303 // - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
304 // - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
305 // - profile PCM 32-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
306 // - profile PCM 32-bit float; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
307 //
308 // Routes:
309 // "r_submix output" -> "Remote Submix Out"
310 // "Remote Submix In" -> "r_submix input"
311 //
getRSubmixConfiguration()312 std::unique_ptr<Configuration> getRSubmixConfiguration() {
313 static const Configuration configuration = []() {
314 Configuration c;
315 const std::vector<AudioProfile> standardPcmAudioProfiles{
316 createProfile(PcmType::FLOAT_32_BIT,
317 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
318 {8000, 11025, 16000, 32000, 44100, 48000}),
319 createProfile(PcmType::INT_32_BIT,
320 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
321 {8000, 11025, 16000, 32000, 44100, 48000}),
322 createProfile(PcmType::INT_24_BIT,
323 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
324 {8000, 11025, 16000, 32000, 44100, 48000}),
325 createProfile(PcmType::INT_16_BIT,
326 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
327 {8000, 11025, 16000, 32000, 44100, 48000})};
328
329 // Device ports
330
331 AudioPort rsubmixOutDevice =
332 createPort(c.nextPortId++, "Remote Submix Out", 0, false,
333 createDeviceExt(AudioDeviceType::OUT_SUBMIX, 0,
334 AudioDeviceDescription::CONNECTION_VIRTUAL));
335 c.ports.push_back(rsubmixOutDevice);
336 c.connectedProfiles[rsubmixOutDevice.id] = standardPcmAudioProfiles;
337
338 AudioPort rsubmixInDevice =
339 createPort(c.nextPortId++, "Remote Submix In", 0, true,
340 createDeviceExt(AudioDeviceType::IN_SUBMIX, 0,
341 AudioDeviceDescription::CONNECTION_VIRTUAL));
342 c.ports.push_back(rsubmixInDevice);
343 c.connectedProfiles[rsubmixInDevice.id] = standardPcmAudioProfiles;
344
345 // Mix ports
346
347 AudioPort rsubmixOutMix =
348 createPort(c.nextPortId++, "r_submix output", 0, false, createPortMixExt(0, 0));
349 rsubmixOutMix.profiles = standardPcmAudioProfiles;
350 c.ports.push_back(rsubmixOutMix);
351
352 AudioPort rsubmixInMix =
353 createPort(c.nextPortId++, "r_submix input", 0, true, createPortMixExt(0, 0));
354 rsubmixInMix.profiles = standardPcmAudioProfiles;
355 c.ports.push_back(rsubmixInMix);
356
357 c.routes.push_back(createRoute({rsubmixOutMix}, rsubmixOutDevice));
358 c.routes.push_back(createRoute({rsubmixInDevice}, rsubmixInMix));
359
360 return c;
361 }();
362 return std::make_unique<Configuration>(configuration);
363 }
364
365 // Usb configuration:
366 //
367 // Device ports:
368 // * "USB Device Out", OUT_DEVICE, CONNECTION_USB
369 // - no profiles specified
370 // * "USB Headset Out", OUT_HEADSET, CONNECTION_USB
371 // - no profiles specified
372 // * "USB Device In", IN_DEVICE, CONNECTION_USB
373 // - no profiles specified
374 // * "USB Headset In", IN_HEADSET, CONNECTION_USB
375 // - no profiles specified
376 //
377 // Mix ports:
378 // * "usb_device output", 1 max open, 1 max active stream
379 // - no profiles specified
380 // * "usb_device input", 1 max open, 1 max active stream
381 // - no profiles specified
382 //
383 // Routes:
384 // * "usb_device output" -> "USB Device Out"
385 // * "usb_device output" -> "USB Headset Out"
386 // * "USB Device In", "USB Headset In" -> "usb_device input"
387 //
388 // Profiles for device port connected state:
389 // * "USB Device Out", "USB Headset Out":
390 // - profile PCM 16-bit; MONO, STEREO, INDEX_MASK_1, INDEX_MASK_2; 44100, 48000
391 // - profile PCM 24-bit; MONO, STEREO, INDEX_MASK_1, INDEX_MASK_2; 44100, 48000
392 // * "USB Device In", "USB Headset In":
393 // - profile PCM 16-bit; MONO, STEREO, INDEX_MASK_1, INDEX_MASK_2; 44100, 48000
394 // - profile PCM 24-bit; MONO, STEREO, INDEX_MASK_1, INDEX_MASK_2; 44100, 48000
395 //
getUsbConfiguration()396 std::unique_ptr<Configuration> getUsbConfiguration() {
397 static const Configuration configuration = []() {
398 const std::vector<AudioProfile> standardPcmAudioProfiles = {
399 createProfile(PcmType::INT_16_BIT,
400 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO,
401 AudioChannelLayout::INDEX_MASK_1, AudioChannelLayout::INDEX_MASK_2},
402 {44100, 48000}),
403 createProfile(PcmType::INT_24_BIT,
404 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO,
405 AudioChannelLayout::INDEX_MASK_1, AudioChannelLayout::INDEX_MASK_2},
406 {44100, 48000})};
407 Configuration c;
408
409 // Device ports
410
411 AudioPort usbOutDevice =
412 createPort(c.nextPortId++, "USB Device Out", 0, false,
413 createDeviceExt(AudioDeviceType::OUT_DEVICE, 0,
414 AudioDeviceDescription::CONNECTION_USB));
415 c.ports.push_back(usbOutDevice);
416 c.connectedProfiles[usbOutDevice.id] = standardPcmAudioProfiles;
417
418 AudioPort usbOutHeadset =
419 createPort(c.nextPortId++, "USB Headset Out", 0, false,
420 createDeviceExt(AudioDeviceType::OUT_HEADSET, 0,
421 AudioDeviceDescription::CONNECTION_USB));
422 c.ports.push_back(usbOutHeadset);
423 c.connectedProfiles[usbOutHeadset.id] = standardPcmAudioProfiles;
424
425 AudioPort usbInDevice = createPort(c.nextPortId++, "USB Device In", 0, true,
426 createDeviceExt(AudioDeviceType::IN_DEVICE, 0,
427 AudioDeviceDescription::CONNECTION_USB));
428 c.ports.push_back(usbInDevice);
429 c.connectedProfiles[usbInDevice.id] = standardPcmAudioProfiles;
430
431 AudioPort usbInHeadset =
432 createPort(c.nextPortId++, "USB Headset In", 0, true,
433 createDeviceExt(AudioDeviceType::IN_HEADSET, 0,
434 AudioDeviceDescription::CONNECTION_USB));
435 c.ports.push_back(usbInHeadset);
436 c.connectedProfiles[usbInHeadset.id] = standardPcmAudioProfiles;
437
438 // Mix ports
439
440 AudioPort usbDeviceOutMix =
441 createPort(c.nextPortId++, "usb_device output", 0, false, createPortMixExt(1, 1));
442 c.ports.push_back(usbDeviceOutMix);
443
444 AudioPort usbDeviceInMix =
445 createPort(c.nextPortId++, "usb_device input", 0, true, createPortMixExt(1, 1));
446 c.ports.push_back(usbDeviceInMix);
447
448 c.routes.push_back(createRoute({usbDeviceOutMix}, usbOutDevice));
449 c.routes.push_back(createRoute({usbDeviceOutMix}, usbOutHeadset));
450 c.routes.push_back(createRoute({usbInDevice, usbInHeadset}, usbDeviceInMix));
451
452 return c;
453 }();
454 return std::make_unique<Configuration>(configuration);
455 }
456
457 // Stub configuration:
458 //
459 // Device ports:
460 // * "Test Out", OUT_AFE_PROXY
461 // - no profiles specified
462 // * "Test In", IN_AFE_PROXY
463 // - no profiles specified
464 // * "Wired Headset", OUT_HEADSET
465 // - profile PCM 24-bit; STEREO; 48000
466 // * "Wired Headset Mic", IN_HEADSET
467 // - profile PCM 24-bit; MONO; 48000
468 //
469 // Mix ports:
470 // * "test output", 1 max open, 1 max active stream
471 // - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
472 // * "test fast output", 1 max open, 1 max active stream
473 // - profile PCM 24-bit; STEREO; 44100, 48000
474 // * "test compressed offload", DIRECT|COMPRESS_OFFLOAD|NON_BLOCKING, 1 max open, 1 max active
475 // stream
476 // - profile MP3; MONO, STEREO; 44100, 48000
477 // * "test input", 2 max open, 2 max active streams
478 // - profile PCM 24-bit; MONO, STEREO, FRONT_BACK;
479 // 8000, 11025, 16000, 22050, 32000, 44100, 48000
480 //
481 // Routes:
482 // "test output", "test fast output", "test compressed offload" -> "Test Out"
483 // "test output" -> "Wired Headset"
484 // "Test In", "Wired Headset Mic" -> "test input"
485 //
486 // Initial port configs:
487 // * "Test Out" device port: PCM 24-bit; STEREO; 48000
488 // * "Test In" device port: PCM 24-bit; MONO; 48000
489 //
getStubConfiguration()490 std::unique_ptr<Configuration> getStubConfiguration() {
491 static const Configuration configuration = []() {
492 Configuration c;
493
494 // Device ports
495
496 AudioPort testOutDevice = createPort(c.nextPortId++, "Test Out", 0, false,
497 createDeviceExt(AudioDeviceType::OUT_AFE_PROXY, 0));
498 c.ports.push_back(testOutDevice);
499 c.initialConfigs.push_back(
500 createPortConfig(testOutDevice.id, testOutDevice.id, PcmType::INT_24_BIT,
501 AudioChannelLayout::LAYOUT_STEREO, 48000, 0, false,
502 createDeviceExt(AudioDeviceType::OUT_AFE_PROXY, 0)));
503
504 AudioPort headsetOutDevice =
505 createPort(c.nextPortId++, "Wired Headset", 0, false,
506 createDeviceExt(AudioDeviceType::OUT_HEADSET, 0,
507 AudioDeviceDescription::CONNECTION_ANALOG));
508 headsetOutDevice.profiles.push_back(
509 createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
510 c.ports.push_back(headsetOutDevice);
511
512 AudioPort testInDevice = createPort(c.nextPortId++, "Test In", 0, true,
513 createDeviceExt(AudioDeviceType::IN_AFE_PROXY, 0));
514 c.ports.push_back(testInDevice);
515 c.initialConfigs.push_back(
516 createPortConfig(testInDevice.id, testInDevice.id, PcmType::INT_24_BIT,
517 AudioChannelLayout::LAYOUT_MONO, 48000, 0, true,
518 createDeviceExt(AudioDeviceType::IN_AFE_PROXY, 0)));
519
520 AudioPort headsetInDevice =
521 createPort(c.nextPortId++, "Wired Headset Mic", 0, true,
522 createDeviceExt(AudioDeviceType::IN_HEADSET, 0,
523 AudioDeviceDescription::CONNECTION_ANALOG));
524 headsetInDevice.profiles.push_back(
525 createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_MONO}, {48000}));
526 c.ports.push_back(headsetInDevice);
527
528 // Mix ports
529
530 AudioPort testOutMix =
531 createPort(c.nextPortId++, "test output", 0, false, createPortMixExt(1, 1));
532 testOutMix.profiles.push_back(
533 createProfile(PcmType::INT_24_BIT,
534 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
535 {8000, 11025, 16000, 32000, 44100, 48000}));
536 c.ports.push_back(testOutMix);
537
538 AudioPort testFastOutMix = createPort(c.nextPortId++, "test fast output",
539 makeBitPositionFlagMask({AudioOutputFlags::FAST}),
540 false, createPortMixExt(1, 1));
541 testFastOutMix.profiles.push_back(createProfile(
542 PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {44100, 48000}));
543 c.ports.push_back(testFastOutMix);
544
545 AudioPort compressedOffloadOutMix =
546 createPort(c.nextPortId++, "test compressed offload",
547 makeBitPositionFlagMask({AudioOutputFlags::DIRECT,
548 AudioOutputFlags::COMPRESS_OFFLOAD,
549 AudioOutputFlags::NON_BLOCKING}),
550 false, createPortMixExt(1, 1));
551 compressedOffloadOutMix.profiles.push_back(
552 createProfile(::android::MEDIA_MIMETYPE_AUDIO_MPEG,
553 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
554 {44100, 48000}));
555 c.ports.push_back(compressedOffloadOutMix);
556
557 AudioPort testInMIx =
558 createPort(c.nextPortId++, "test input", 0, true, createPortMixExt(2, 2));
559 testInMIx.profiles.push_back(
560 createProfile(PcmType::INT_16_BIT,
561 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO,
562 AudioChannelLayout::LAYOUT_FRONT_BACK},
563 {8000, 11025, 16000, 22050, 32000, 44100, 48000}));
564 testInMIx.profiles.push_back(
565 createProfile(PcmType::INT_24_BIT,
566 {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO,
567 AudioChannelLayout::LAYOUT_FRONT_BACK},
568 {8000, 11025, 16000, 22050, 32000, 44100, 48000}));
569 c.ports.push_back(testInMIx);
570
571 c.routes.push_back(
572 createRoute({testOutMix, testFastOutMix, compressedOffloadOutMix}, testOutDevice));
573 c.routes.push_back(createRoute({testOutMix}, headsetOutDevice));
574 c.routes.push_back(createRoute({testInDevice, headsetInDevice}, testInMIx));
575
576 c.portConfigs.insert(c.portConfigs.end(), c.initialConfigs.begin(), c.initialConfigs.end());
577
578 return c;
579 }();
580 return std::make_unique<Configuration>(configuration);
581 }
582
583 // Bluetooth configuration:
584 //
585 // Device ports:
586 // * "BT A2DP Out", OUT_DEVICE, CONNECTION_BT_A2DP
587 // - profile PCM 16-bit; STEREO; 44100, 48000, 88200, 96000
588 // * "BT A2DP Headphones", OUT_HEADPHONE, CONNECTION_BT_A2DP
589 // - profile PCM 16-bit; STEREO; 44100, 48000, 88200, 96000
590 // * "BT A2DP Speaker", OUT_SPEAKER, CONNECTION_BT_A2DP
591 // - profile PCM 16-bit; STEREO; 44100, 48000, 88200, 96000
592 // * "BT Hearing Aid Out", OUT_HEARING_AID, CONNECTION_WIRELESS
593 // - no profiles specified
594 //
595 // Mix ports:
596 // * "a2dp output", 1 max open, 1 max active stream
597 // - no profiles specified
598 // * "hearing aid output", 1 max open, 1 max active stream
599 // - profile PCM 16-bit; STEREO; 16000, 24000
600 //
601 // Routes:
602 // "a2dp output" -> "BT A2DP Out"
603 // "a2dp output" -> "BT A2DP Headphones"
604 // "a2dp output" -> "BT A2DP Speaker"
605 // "hearing aid output" -> "BT Hearing Aid Out"
606 //
getBluetoothConfiguration()607 std::unique_ptr<Configuration> getBluetoothConfiguration() {
608 static const Configuration configuration = []() {
609 const std::vector<AudioProfile> standardPcmAudioProfiles = {
610 createProfile(PcmType::INT_16_BIT, {AudioChannelLayout::LAYOUT_STEREO},
611 {44100, 48000, 88200, 96000})};
612 Configuration c;
613
614 // Device ports
615 AudioPort btOutDevice =
616 createPort(c.nextPortId++, "BT A2DP Out", 0, false,
617 createDeviceExt(AudioDeviceType::OUT_DEVICE, 0,
618 AudioDeviceDescription::CONNECTION_BT_A2DP));
619 btOutDevice.profiles.insert(btOutDevice.profiles.begin(), standardPcmAudioProfiles.begin(),
620 standardPcmAudioProfiles.end());
621 c.ports.push_back(btOutDevice);
622 c.connectedProfiles[btOutDevice.id] = standardPcmAudioProfiles;
623
624 AudioPort btOutHeadphone =
625 createPort(c.nextPortId++, "BT A2DP Headphones", 0, false,
626 createDeviceExt(AudioDeviceType::OUT_HEADPHONE, 0,
627 AudioDeviceDescription::CONNECTION_BT_A2DP));
628 btOutHeadphone.profiles.insert(btOutHeadphone.profiles.begin(),
629 standardPcmAudioProfiles.begin(),
630 standardPcmAudioProfiles.end());
631 c.ports.push_back(btOutHeadphone);
632 c.connectedProfiles[btOutHeadphone.id] = standardPcmAudioProfiles;
633
634 AudioPort btOutSpeaker =
635 createPort(c.nextPortId++, "BT A2DP Speaker", 0, false,
636 createDeviceExt(AudioDeviceType::OUT_SPEAKER, 0,
637 AudioDeviceDescription::CONNECTION_BT_A2DP));
638 btOutSpeaker.profiles.insert(btOutSpeaker.profiles.begin(),
639 standardPcmAudioProfiles.begin(),
640 standardPcmAudioProfiles.end());
641 c.ports.push_back(btOutSpeaker);
642 c.connectedProfiles[btOutSpeaker.id] = standardPcmAudioProfiles;
643
644 AudioPort btOutHearingAid =
645 createPort(c.nextPortId++, "BT Hearing Aid Out", 0, false,
646 createDeviceExt(AudioDeviceType::OUT_HEARING_AID, 0,
647 AudioDeviceDescription::CONNECTION_WIRELESS));
648 c.ports.push_back(btOutHearingAid);
649 c.connectedProfiles[btOutHearingAid.id] = std::vector<AudioProfile>(
650 {createProfile(PcmType::INT_16_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {16000})});
651
652 // Mix ports
653 AudioPort btOutMix =
654 createPort(c.nextPortId++, "a2dp output", 0, false, createPortMixExt(1, 1));
655 c.ports.push_back(btOutMix);
656
657 AudioPort btHearingOutMix =
658 createPort(c.nextPortId++, "hearing aid output", 0, false, createPortMixExt(1, 1));
659 btHearingOutMix.profiles.push_back(createProfile(
660 PcmType::INT_16_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {16000, 24000}));
661 c.ports.push_back(btHearingOutMix);
662
663 c.routes.push_back(createRoute({btOutMix}, btOutDevice));
664 c.routes.push_back(createRoute({btOutMix}, btOutHeadphone));
665 c.routes.push_back(createRoute({btOutMix}, btOutSpeaker));
666 c.routes.push_back(createRoute({btHearingOutMix}, btOutHearingAid));
667
668 return c;
669 }();
670 return std::make_unique<Configuration>(configuration);
671 }
672
673 } // namespace aidl::android::hardware::audio::core::internal
674