1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #ifndef LOG_TAG
16 #define LOG_TAG "HpaeDownMixer"
17 #endif
18 #include <algorithm>
19 #include <cinttypes>
20 #include "securec.h"
21 #include "down_mixer.h"
22 #include "audio_engine_log.h"
23
24 namespace OHOS {
25 namespace AudioStandard {
26 namespace HPAE {
27 // Initial output channel index
28 enum OutChannelIndex : uint32_t {
29 FL = 0,
30 FR,
31 FC,
32 SW,
33 // Back channel should be placed before side channel
34 BL,
35 BR
36 };
37
38 static constexpr uint32_t INDEX_SIX = 6;
39 static constexpr uint32_t INDEX_SEVEN = 7;
40 static constexpr uint32_t INDEX_EIGHT = 8;
41 static constexpr uint32_t INDEX_NINE = 9;
42 static constexpr uint32_t INDEX_TEN = 10;
43 static constexpr uint32_t INDEX_ELEVEN = 11;
44 static constexpr uint32_t MAX_FRAME_LENGTH = SAMPLE_RATE_192000 * 10; // max framelength is sample rate 192000, 10s
45
46 // channel masks for downmixing general output channel layout
47 static constexpr uint64_t MASK_MIDDLE_FRONT = FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER |
48 FRONT_LEFT_OF_CENTER | FRONT_RIGHT_OF_CENTER | WIDE_LEFT | WIDE_RIGHT;
49
50 static constexpr uint64_t MASK_MIDDLE_REAR = BACK_LEFT | BACK_RIGHT | BACK_CENTER
51 | SIDE_LEFT
52 | SIDE_RIGHT;
53
54 static constexpr uint64_t MASK_TOP_FRONT = TOP_FRONT_LEFT
55 | TOP_FRONT_CENTER
56 | TOP_FRONT_RIGHT;
57
58 static constexpr uint64_t MASK_TOP_REAR = TOP_CENTER
59 | TOP_BACK_LEFT
60 | TOP_BACK_CENTER
61 | TOP_BACK_RIGHT
62 | TOP_SIDE_LEFT
63 | TOP_SIDE_RIGHT;
64
65 static constexpr uint64_t MASK_BOTTOM = BOTTOM_FRONT_CENTER
66 | BOTTOM_FRONT_LEFT
67 | BOTTOM_FRONT_RIGHT;
68
69 static constexpr uint64_t MASK_LFE = LOW_FREQUENCY
70 | LOW_FREQUENCY_2;
71
72 static uint32_t BitCounts(uint64_t bits);
73 static bool IsValidChLayout(AudioChannelLayout &chLayout, uint32_t chCounts);
74
75 // 改成默认构造
DownMixer()76 DownMixer::DownMixer()
77 {
78 downMixTable_.resize(MAX_CHANNELS, std::vector<float>(MAX_CHANNELS, 0));
79 }
80
81 // setParam
SetParam(AudioChannelInfo inChannelInfo,AudioChannelInfo outChannelInfo,uint32_t formatSize,bool mixLfe)82 int32_t DownMixer::SetParam(AudioChannelInfo inChannelInfo, AudioChannelInfo outChannelInfo,
83 uint32_t formatSize, bool mixLfe)
84 {
85 ResetSelf();
86 inLayout_ = inChannelInfo.channelLayout;
87 outLayout_ = outChannelInfo.channelLayout;
88 inChannels_ = inChannelInfo.numChannels;
89 outChannels_ = outChannelInfo.numChannels;
90 mixLfe_ = mixLfe;
91
92 CHECK_AND_RETURN_RET_LOG((inChannels_ >= 0) && (inChannels_ <= MAX_CHANNELS), DMIX_ERR_INVALID_ARG,
93 "invalid input channels");
94 CHECK_AND_RETURN_RET_LOG((outChannels_ >= 0) && (outChannels_ <= MAX_CHANNELS), DMIX_ERR_INVALID_ARG,
95 "invalid output channels");
96
97 formatSize_ = formatSize;
98 int32_t ret = SetupDownMixTable();
99 if (ret == DMIX_ERR_SUCCESS) {
100 isInitialized_ = true;
101 }
102 return ret;
103 }
104
Process(uint32_t frameLen,float * in,uint32_t inLen,float * out,uint32_t outLen)105 int32_t DownMixer::Process(uint32_t frameLen, float* in, uint32_t inLen, float* out, uint32_t outLen)
106 {
107 CHECK_AND_RETURN_RET_LOG(in, DMIX_ERR_INVALID_ARG, "input pointer is nullptr");
108 CHECK_AND_RETURN_RET_LOG(out, DMIX_ERR_INVALID_ARG, "output pointer is nullptr");
109 CHECK_AND_RETURN_RET_LOG(frameLen <= MAX_FRAME_LENGTH, DMIX_ERR_INVALID_ARG, "invalid frameSize");
110 CHECK_AND_RETURN_RET_LOG(isInitialized_, DMIX_ERR_ALLOC_FAILED, "Downmixe table has not been initialized!");
111
112 uint32_t expectInLen = frameLen * inChannels_ * formatSize_;
113 uint32_t expectOutLen = frameLen * outChannels_ * formatSize_;
114 if ((expectInLen > inLen) || (expectOutLen > outLen)) {
115 AUDIO_ERR_LOG("unexpected inLen %{public}d or outLen %{public}d", inLen, outLen);
116 int32_t ret = memcpy_s(out, outLen, in, inLen);
117 CHECK_AND_RETURN_RET_LOG(ret == EOK, DMIX_ERR_ALLOC_FAILED, "memcpy failed when processing unexpected len");
118 return DMIX_ERR_ALLOC_FAILED;
119 }
120 // For HOA, copy the first channel into all output channels
121 if (isInLayoutHOA_) {
122 for (uint32_t i = 0; i < frameLen; i++) {
123 for (uint32_t c = 0; c < outChannels_; c++) {
124 out[outChannels_ * i + c] = in[inChannels_ * i];
125 }
126 }
127 return DMIX_ERR_SUCCESS;
128 }
129 float a;
130 for (; frameLen > 0; frameLen--) {
131 for (uint32_t i = 0; i < outChannels_; i++) {
132 a = 0.0f;
133 for (uint32_t j = 0; j < inChannels_; j++) {
134 a += in[j] * downMixTable_[i][j];
135 }
136 *(out++) = a;
137 }
138 in += inChannels_;
139 }
140 return DMIX_ERR_SUCCESS;
141 }
142
SetupDownMixTable()143 int32_t DownMixer::SetupDownMixTable()
144 {
145 if ((!IsValidChLayout(inLayout_, inChannels_)) || (!IsValidChLayout(outLayout_, outChannels_))
146 || inLayout_ == outLayout_ || inChannels_ <= outChannels_) {
147 AUDIO_ERR_LOG("invalid input or output channellayout: input channel count %{public}d, "
148 "inLayout_ %{public}" PRIu64 "output channel count %{public}d, outLayout_ %{public}" PRIu64 "",
149 inChannels_, inLayout_, outChannels_, outLayout_);
150 return DMIX_ERR_INVALID_ARG;
151 }
152 CheckIsHOA(inLayout_);
153 switch (outLayout_) {
154 case CH_LAYOUT_STEREO: {
155 SetupStereoDmixTable();
156 break;
157 }
158 case CH_LAYOUT_5POINT1: {
159 Setup5Point1DmixTable();
160 break;
161 }
162 case CH_LAYOUT_5POINT1POINT2: {
163 Setup5Point1Point2DmixTable();
164 break;
165 }
166 case CH_LAYOUT_5POINT1POINT4: {
167 Setup5Point1Point4DmixTable();
168 break;
169 }
170 case CH_LAYOUT_7POINT1: {
171 Setup7Point1DmixTable();
172 break;
173 }
174 case CH_LAYOUT_7POINT1POINT2: {
175 Setup7Point1Point2DmixTable();
176 break;
177 }
178 case CH_LAYOUT_7POINT1POINT4: {
179 Setup7Point1Point4DmixTable();
180 break;
181 }
182 default: {
183 SetupGeneralDmixTable();
184 break;
185 }
186 }
187 NormalizeDMixTable();
188 AUDIO_INFO_LOG("setup downmix table success!");
189 isInitialized_ = true;
190 return DMIX_ERR_SUCCESS;
191 }
192
NormalizeDMixTable()193 void DownMixer::NormalizeDMixTable()
194 {
195 float maxx = 0.0f;
196 for (uint32_t i = 0; i < outChannels_; i++) {
197 float summ = 0.0f;
198 for (uint32_t j = 0; j < inChannels_; j++) {
199 summ += downMixTable_[i][j];
200 }
201 maxx = std::max(maxx, summ);
202 }
203
204 if (maxx < 1e-6) {
205 AUDIO_ERR_LOG("invalid channel num: in_ch = %{public}u, out_ch = %{public}u",
206 inChannels_, outChannels_);
207 maxx = 1.0f;
208 } else {
209 maxx = 1.0f / maxx;
210 }
211
212 for (uint32_t i = 0; i < outChannels_; i++) {
213 for (uint32_t j = 0; j < inChannels_; j++) {
214 downMixTable_[i][j] *= maxx;
215 }
216 }
217 }
218
ResetSelf()219 void DownMixer::ResetSelf()
220 {
221 isInitialized_ = false;
222 inChannels_ = 0;
223 outChannels_ = 0;
224 inLayout_ = CH_LAYOUT_UNKNOWN;
225 outLayout_ = CH_LAYOUT_UNKNOWN;
226 for (auto &row : downMixTable_) {
227 std::fill(row.begin(), row.end(), 0.0f);
228 }
229 }
230
Reset()231 void DownMixer::Reset()
232 {
233 ResetSelf();
234 }
235
SetupStereoDmixTable()236 void DownMixer::SetupStereoDmixTable()
237 {
238 uint64_t inChMsk = inLayout_;
239 for (uint32_t i = 0; i < inChannels_; i++) {
240 uint64_t bit = inChMsk & (~inChMsk + 1);
241 downMixTable_[FL][i] = 0.f;
242 downMixTable_[FR][i] = 0.f;
243 SetupStereoDmixTablePart1(bit, i);
244 SetupStereoDmixTablePart2(bit, i);
245 inChMsk ^= bit;
246 }
247 }
248
Setup5Point1DmixTable()249 void DownMixer::Setup5Point1DmixTable()
250 {
251 uint64_t inChMsk = inLayout_;
252 for (uint32_t i = 0; i < inChannels_; i++) {
253 downMixTable_[FL][i] = 0.f;
254 downMixTable_[FR][i] = 0.f;
255 downMixTable_[FC][i] = 0.f;
256 downMixTable_[SW][i] = 0.f;
257 downMixTable_[BL][i] = 0.f;
258 downMixTable_[BR][i] = 0.f;
259 uint64_t bit = inChMsk & (~inChMsk + 1);
260 Setup5Point1DmixTablePart1(bit, i);
261 Setup5Point1DmixTablePart2(bit, i);
262 inChMsk ^= bit;
263 }
264 }
Setup5Point1Point2DmixTable()265 void DownMixer::Setup5Point1Point2DmixTable()
266 {
267 gTsl_ = INDEX_SIX;
268 gTsr_ = INDEX_SEVEN;
269 uint64_t inChMsk = inLayout_;
270 for (unsigned i = 0; i < inChannels_; i++) {
271 uint64_t bit = inChMsk & (~inChMsk + 1);
272 downMixTable_[FL][i] = downMixTable_[FR][i] = downMixTable_[FC][i] = 0.f;
273 downMixTable_[SW][i] = downMixTable_[BL][i] = downMixTable_[BR][i] = 0.f;
274 downMixTable_[gTsl_][i] = downMixTable_[gTsr_][i] = 0.f;
275 Setup5Point1Point2DmixTablePart1(bit, i);
276 Setup5Point1Point2DmixTablePart2(bit, i);
277 inChMsk ^= bit;
278 }
279 }
Setup5Point1Point4DmixTable()280 void DownMixer::Setup5Point1Point4DmixTable()
281 {
282 gTfl_ = INDEX_SIX;
283 gTfr_ = INDEX_SEVEN;
284 gTbl_ = INDEX_EIGHT;
285 gTbr_ = INDEX_NINE;
286 uint64_t inChMsk = inLayout_;
287 for (unsigned i = 0; i < inChannels_; i++) {
288 uint64_t bit = inChMsk & (~inChMsk + 1);
289 downMixTable_[FL][i] = downMixTable_[FR][i] = downMixTable_[FC][i] = 0.f;
290 downMixTable_[SW][i] = downMixTable_[BL][i] = downMixTable_[BR][i] = 0.f;
291 downMixTable_[gTfl_][i] = downMixTable_[gTfr_][i] = 0.f;
292 downMixTable_[gTbl_][i] = downMixTable_[gTbr_][i] = 0.f;
293 Setup5Point1Point4DmixTablePart1(bit, i);
294 Setup5Point1Point4DmixTablePart2(bit, i);
295 inChMsk ^= bit;
296 }
297 }
Setup7Point1DmixTable()298 void DownMixer::Setup7Point1DmixTable()
299 {
300 gSl_ = INDEX_SIX;
301 gSr_ = INDEX_SEVEN;
302 uint64_t inChMsk = inLayout_;
303 for (unsigned i = 0; i < inChannels_; i++) {
304 uint64_t bit = inChMsk & (~inChMsk + 1);
305 downMixTable_[FL][i] = downMixTable_[FR][i] = downMixTable_[FC][i] = 0.f;
306 downMixTable_[SW][i] = downMixTable_[gSl_][i] = downMixTable_[gSr_][i] = 0.f;
307 downMixTable_[BL][i] = downMixTable_[BR][i] = 0.f;
308 Setup7Point1DmixTablePart1(bit, i);
309 Setup7Point1DmixTablePart2(bit, i);
310 inChMsk ^= bit;
311 }
312 }
Setup7Point1Point2DmixTable()313 void DownMixer::Setup7Point1Point2DmixTable()
314 {
315 gSl_ = INDEX_SIX;
316 gSr_ = INDEX_SEVEN;
317 gTsl_ = INDEX_EIGHT;
318 gTsr_ = INDEX_NINE;
319 uint64_t inChMsk = inLayout_;
320 for (unsigned i = 0; i < inChannels_; i++) {
321 uint64_t bit = inChMsk & (~inChMsk + 1);
322 downMixTable_[FL][i] = downMixTable_[FR][i] = downMixTable_[FC][i] = 0.f;
323 downMixTable_[SW][i] = downMixTable_[gSl_][i] = downMixTable_[gSr_][i] = 0.f;
324 downMixTable_[BL][i] = downMixTable_[BR][i] = 0.f;
325 downMixTable_[gTsl_][i] = downMixTable_[gTsr_][i] = 0.f;
326 Setup7Point1Point2DmixTablePart1(bit, i);
327 Setup7Point1Point2DmixTablePart2(bit, i);
328 inChMsk ^= bit;
329 }
330 }
Setup7Point1Point4DmixTable()331 void DownMixer::Setup7Point1Point4DmixTable()
332 {
333 gSl_ = INDEX_SIX;
334 gSr_ = INDEX_SEVEN;
335 gTfl_ = INDEX_EIGHT;
336 gTfr_ = INDEX_NINE;
337 gTbl_ = INDEX_TEN;
338 gTbr_ = INDEX_ELEVEN;
339 uint64_t inChMsk = inLayout_;
340 for (unsigned i = 0; i < inChannels_; i++) {
341 uint64_t bit = inChMsk & (~inChMsk + 1);
342 downMixTable_[FL][i] = downMixTable_[FR][i] = downMixTable_[FC][i] = 0.f;
343 downMixTable_[SW][i] = downMixTable_[gSl_][i] = downMixTable_[gSr_][i] = 0.f;
344 downMixTable_[BL][i] = downMixTable_[BR][i] = 0.f;
345 downMixTable_[gTfl_][i] = downMixTable_[gTfr_][i] = 0.f;
346 downMixTable_[gTbl_][i] = downMixTable_[gTbr_][i] = 0.f;
347 Setup7Point1Point4DmixTablePart1(bit, i);
348 Setup7Point1Point4DmixTablePart2(bit, i);
349 inChMsk ^= bit;
350 }
351 }
352
SetupGeneralDmixTable()353 void DownMixer::SetupGeneralDmixTable()
354 {
355 // MONO
356 if (outLayout_ == CH_LAYOUT_MONO) {
357 for (uint32_t i = 0; i < inChannels_; i++) {
358 downMixTable_[0][i] = COEF_0DB_F;
359 }
360 }
361 // check invalid output musk later in init()
362 uint64_t outChMsk = outLayout_;
363
364 for (uint32_t i = 0; i < outChannels_; i++) {
365 uint64_t outBit = outChMsk & (~outChMsk + 1);
366 uint64_t inChMsk = inLayout_;
367 for (uint32_t j = 0; j < inChannels_; j++) {
368 uint64_t inBit = inChMsk & (~inChMsk + 1);
369 if (inBit & outBit) { // if in channel and out channel is the same
370 downMixTable_[i][j] = COEF_0DB_F;
371 } else if (inBit == TOP_CENTER) {
372 // check general downmix table!
373 DownMixTopCenter(inBit, outBit, i, j);
374 } else if ((inBit & MASK_MIDDLE_FRONT) != 0) {
375 DownMixMidFront(inBit, outBit, i, j);
376 } else if ((inBit & MASK_MIDDLE_REAR) != 0) {
377 DownMixMidRear(inBit, outBit, i, j);
378 } else if ((inBit & MASK_BOTTOM) != 0) {
379 DownMixBottom(inBit, outBit, i, j);
380 } else if ((inBit & MASK_LFE) != 0) {
381 DownMixLfe(inBit, outBit, i, j);
382 } else if ((inBit & MASK_TOP_FRONT) != 0) {
383 DownMixTopFront(inBit, outBit, i, j);
384 } else if ((inBit & MASK_TOP_REAR) != 0) {
385 DownMixTopRear(inBit, outBit, i, j);
386 }
387 inChMsk ^= inBit;
388 }
389 outChMsk ^= outBit;
390 }
391 }
392
SetupStereoDmixTablePart1(uint64_t bit,uint32_t i)393 void DownMixer::SetupStereoDmixTablePart1(uint64_t bit, uint32_t i)
394 {
395 switch (bit) {
396 case FRONT_LEFT:
397 case TOP_FRONT_LEFT:
398 case BOTTOM_FRONT_LEFT:
399 downMixTable_[FL][i] = COEF_0DB_F;
400 downMixTable_[FR][i] = COEF_ZERO_F;
401 break;
402 case FRONT_RIGHT:
403 case TOP_FRONT_RIGHT:
404 case BOTTOM_FRONT_RIGHT:
405 downMixTable_[FL][i] = COEF_ZERO_F;
406 downMixTable_[FR][i] = COEF_0DB_F;
407 break;
408 case FRONT_CENTER:
409 case TOP_FRONT_CENTER:
410 case BOTTOM_FRONT_CENTER:
411 downMixTable_[FL][i] = COEF_M3DB_F;
412 downMixTable_[FR][i] = COEF_M3DB_F;
413 break;
414 case BACK_LEFT:
415 case SIDE_LEFT:
416 case TOP_BACK_LEFT:
417 case TOP_SIDE_LEFT:
418 case WIDE_LEFT:
419 downMixTable_[FL][i] = COEF_M3DB_F;
420 downMixTable_[FR][i] = COEF_ZERO_F;
421 break;
422 case BACK_RIGHT:
423 case SIDE_RIGHT:
424 case TOP_BACK_RIGHT:
425 case TOP_SIDE_RIGHT:
426 case WIDE_RIGHT:
427 downMixTable_[FL][i] = COEF_ZERO_F;
428 downMixTable_[FR][i] = COEF_M3DB_F;
429 break;
430 case BACK_CENTER:
431 downMixTable_[FL][i] = COEF_M6DB_F;
432 downMixTable_[FR][i] = COEF_M6DB_F;
433 break;
434 default:
435 break;
436 }
437 }
438
SetupStereoDmixTablePart2(uint64_t bit,uint32_t i)439 void DownMixer::SetupStereoDmixTablePart2(uint64_t bit, uint32_t i)
440 {
441 switch (bit) {
442 case FRONT_LEFT_OF_CENTER:
443 downMixTable_[FL][i] = COEF_M435DB_F;
444 downMixTable_[FR][i] = COEF_M12DB_F;
445 break;
446 case FRONT_RIGHT_OF_CENTER:
447 downMixTable_[FL][i] = COEF_M12DB_F;
448 downMixTable_[FR][i] = COEF_M435DB_F;
449 break;
450 case TOP_BACK_CENTER:
451 downMixTable_[FL][i] = COEF_M9DB_F;
452 downMixTable_[FR][i] = COEF_M9DB_F;
453 break;
454 case TOP_CENTER:
455 downMixTable_[FL][i] = COEF_M899DB_F;
456 downMixTable_[FR][i] = COEF_M899DB_F;
457 break;
458 case LOW_FREQUENCY_2:
459 if (mixLfe_) {
460 downMixTable_[FL][i] = COEF_ZERO_F;
461 downMixTable_[FR][i] = COEF_M6DB_F;
462 }
463 break;
464 case LOW_FREQUENCY:
465 if ((mixLfe_) & (inLayout_ & (LOW_FREQUENCY_2))) {
466 downMixTable_[FL][i] = COEF_M6DB_F;
467 downMixTable_[FR][i] = COEF_ZERO_F;
468 } else if (mixLfe_) {
469 downMixTable_[FL][i] = COEF_M6DB_F;
470 downMixTable_[FR][i] = COEF_M6DB_F;
471 }
472 break;
473 default:
474 break;
475 }
476 }
477
Setup5Point1DmixTablePart1(uint64_t bit,uint32_t i)478 void DownMixer::Setup5Point1DmixTablePart1(uint64_t bit, uint32_t i)
479 {
480 switch (bit) {
481 case FRONT_LEFT:
482 case TOP_FRONT_LEFT:
483 case BOTTOM_FRONT_LEFT:
484 case WIDE_LEFT:
485 downMixTable_[FL][i] = COEF_0DB_F;
486 break;
487 case FRONT_RIGHT:
488 case TOP_FRONT_RIGHT:
489 case BOTTOM_FRONT_RIGHT:
490 case WIDE_RIGHT:
491 downMixTable_[FR][i] = COEF_0DB_F;
492 break;
493 case FRONT_CENTER:
494 case TOP_FRONT_CENTER:
495 case BOTTOM_FRONT_CENTER:
496 downMixTable_[FC][i] = COEF_0DB_F;
497 break;
498 case SIDE_LEFT:
499 case BACK_LEFT:
500 case TOP_BACK_LEFT:
501 case TOP_SIDE_LEFT:
502 downMixTable_[BL][i] = COEF_0DB_F;
503 break;
504 case (SIDE_RIGHT):
505 case (BACK_RIGHT):
506 case (TOP_BACK_RIGHT):
507 case (TOP_SIDE_RIGHT):
508 downMixTable_[BR][i] = COEF_0DB_F;
509 break;
510 default:
511 break;
512 }
513 }
514
Setup5Point1DmixTablePart2(uint64_t bit,uint32_t i)515 void DownMixer::Setup5Point1DmixTablePart2(uint64_t bit, uint32_t i)
516 {
517 switch (bit) {
518 case (LOW_FREQUENCY):
519 case (LOW_FREQUENCY_2):
520 if (mixLfe_) {
521 downMixTable_[SW][i] = COEF_0DB_F;
522 }
523 break;
524 case (FRONT_LEFT_OF_CENTER):
525 downMixTable_[FL][i] = COEF_M45DB_F;
526 downMixTable_[FC][i] = COEF_M3DB_F;
527 break;
528 case (FRONT_RIGHT_OF_CENTER):
529 downMixTable_[FR][i] = COEF_M45DB_F;
530 downMixTable_[FC][i] = COEF_M3DB_F;
531 break;
532 case (BACK_CENTER):
533 case (TOP_BACK_CENTER):
534 downMixTable_[BL][i] = COEF_M3DB_F;
535 downMixTable_[BR][i] = COEF_M3DB_F;
536 break;
537 case (TOP_CENTER):
538 downMixTable_[FC][i] = COEF_M6DB_F;
539 downMixTable_[BL][i] = COEF_M6DB_F;
540 downMixTable_[BR][i] = COEF_M6DB_F;
541 break;
542 default:
543 break;
544 }
545 }
546
Setup5Point1Point2DmixTablePart1(uint64_t bit,uint32_t i)547 void DownMixer::Setup5Point1Point2DmixTablePart1(uint64_t bit, uint32_t i)
548 {
549 switch (bit) {
550 case (FRONT_LEFT):
551 case (TOP_FRONT_LEFT):
552 case (BOTTOM_FRONT_LEFT):
553 case (WIDE_LEFT):
554 downMixTable_[FL][i] = COEF_0DB_F;
555 break;
556 case (FRONT_RIGHT):
557 case (TOP_FRONT_RIGHT):
558 case (BOTTOM_FRONT_RIGHT):
559 case (WIDE_RIGHT):
560 downMixTable_[FR][i] = COEF_0DB_F;
561 break;
562 case (FRONT_CENTER):
563 case (TOP_FRONT_CENTER):
564 case (BOTTOM_FRONT_CENTER):
565 downMixTable_[FC][i] = COEF_0DB_F;
566 break;
567 case (SIDE_LEFT):
568 case (BACK_LEFT):
569 downMixTable_[BL][i] = COEF_0DB_F;
570 break;
571 case (SIDE_RIGHT):
572 case (BACK_RIGHT):
573 downMixTable_[BR][i] = COEF_0DB_F;
574 break;
575 default:
576 break;
577 }
578 }
579
Setup5Point1Point2DmixTablePart2(uint64_t bit,uint32_t i)580 void DownMixer::Setup5Point1Point2DmixTablePart2(uint64_t bit, uint32_t i)
581 {
582 switch (bit) {
583 case (TOP_BACK_LEFT):
584 case (TOP_SIDE_LEFT):
585 downMixTable_[gTsl_][i] = COEF_0DB_F;
586 break;
587 case (TOP_BACK_RIGHT):
588 case (TOP_SIDE_RIGHT):
589 downMixTable_[gTsr_][i] = COEF_0DB_F;
590 break;
591 case (LOW_FREQUENCY):
592 case (LOW_FREQUENCY_2):
593 if (mixLfe_) {
594 downMixTable_[SW][i] = COEF_0DB_F;
595 }
596 break;
597 case (FRONT_LEFT_OF_CENTER):
598 downMixTable_[FL][i] = COEF_M45DB_F;
599 downMixTable_[FC][i] = COEF_M3DB_F;
600 break;
601 case (FRONT_RIGHT_OF_CENTER):
602 downMixTable_[FR][i] = COEF_M45DB_F;
603 downMixTable_[FC][i] = COEF_M3DB_F;
604 break;
605 case (BACK_CENTER):
606 downMixTable_[BL][i] = COEF_M3DB_F;
607 downMixTable_[BR][i] = COEF_M3DB_F;
608 break;
609 case (TOP_BACK_CENTER):
610 case (TOP_CENTER):
611 downMixTable_[gTsl_][i] = COEF_M3DB_F;
612 downMixTable_[gTsr_][i] = COEF_M3DB_F;
613 break;
614 default:
615 break;
616 }
617 }
618
Setup5Point1Point4DmixTablePart1(uint64_t bit,uint32_t i)619 void DownMixer::Setup5Point1Point4DmixTablePart1(uint64_t bit, uint32_t i)
620 {
621 switch (bit) {
622 case (FRONT_LEFT):
623 case (BOTTOM_FRONT_LEFT):
624 case (WIDE_LEFT):
625 downMixTable_[FL][i] = COEF_0DB_F;
626 break;
627 case (FRONT_RIGHT):
628 case (BOTTOM_FRONT_RIGHT):
629 case (WIDE_RIGHT):
630 downMixTable_[FR][i] = COEF_0DB_F;
631 break;
632 case (FRONT_CENTER):
633 case (BOTTOM_FRONT_CENTER):
634 downMixTable_[FC][i] = COEF_0DB_F;
635 break;
636 case (SIDE_LEFT):
637 case (BACK_LEFT):
638 downMixTable_[BL][i] = COEF_0DB_F;
639 break;
640 case (SIDE_RIGHT):
641 case (BACK_RIGHT):
642 downMixTable_[BR][i] = COEF_0DB_F;
643 break;
644 case (TOP_FRONT_LEFT):
645 downMixTable_[gTfl_][i] = COEF_0DB_F;
646 break;
647 case (TOP_FRONT_RIGHT):
648 downMixTable_[gTfr_][i] = COEF_0DB_F;
649 break;
650 case (TOP_BACK_LEFT):
651 case (TOP_SIDE_LEFT):
652 downMixTable_[gTbl_][i] = COEF_0DB_F;
653 break;
654 case (TOP_BACK_RIGHT):
655 case (TOP_SIDE_RIGHT):
656 downMixTable_[gTbr_][i] = COEF_0DB_F;
657 break;
658 case (LOW_FREQUENCY):
659 case (LOW_FREQUENCY_2):
660 if (mixLfe_) {
661 downMixTable_[SW][i] = COEF_0DB_F;
662 }
663 break;
664 default:
665 break;
666 }
667 }
668
Setup5Point1Point4DmixTablePart2(uint64_t bit,uint32_t i)669 void DownMixer::Setup5Point1Point4DmixTablePart2(uint64_t bit, uint32_t i)
670 {
671 switch (bit) {
672 case (FRONT_LEFT_OF_CENTER):
673 downMixTable_[FL][i] = COEF_M45DB_F;
674 downMixTable_[FC][i] = COEF_M3DB_F;
675 break;
676 case (FRONT_RIGHT_OF_CENTER):
677 downMixTable_[FR][i] = COEF_M45DB_F;
678 downMixTable_[FC][i] = COEF_M3DB_F;
679 break;
680 case (BACK_CENTER):
681 downMixTable_[BL][i] = COEF_M3DB_F;
682 downMixTable_[BR][i] = COEF_M3DB_F;
683 break;
684 case (TOP_FRONT_CENTER):
685 downMixTable_[gTfl_][i] = COEF_M3DB_F;
686 downMixTable_[gTfr_][i] = COEF_M3DB_F;
687 break;
688 case (TOP_BACK_CENTER):
689 downMixTable_[gTbl_][i] = COEF_M3DB_F;
690 downMixTable_[gTbr_][i] = COEF_M3DB_F;
691 break;
692 case (TOP_CENTER):
693 downMixTable_[gTfl_][i] = COEF_M6DB_F;
694 downMixTable_[gTfr_][i] = COEF_M6DB_F;
695 downMixTable_[gTbl_][i] = COEF_M6DB_F;
696 downMixTable_[gTbr_][i] = COEF_M6DB_F;
697 break;
698 default:
699 break;
700 }
701 }
702
Setup7Point1DmixTablePart1(uint64_t bit,uint32_t i)703 void DownMixer::Setup7Point1DmixTablePart1(uint64_t bit, uint32_t i)
704 {
705 switch (bit) {
706 case (FRONT_LEFT):
707 case (TOP_FRONT_LEFT):
708 case (BOTTOM_FRONT_LEFT):
709 case (WIDE_LEFT):
710 downMixTable_[FL][i] = COEF_0DB_F;
711 break;
712 case (FRONT_RIGHT):
713 case (TOP_FRONT_RIGHT):
714 case (BOTTOM_FRONT_RIGHT):
715 case (WIDE_RIGHT):
716 downMixTable_[FR][i] = COEF_0DB_F;
717 break;
718 case (FRONT_CENTER):
719 case (TOP_FRONT_CENTER):
720 case (BOTTOM_FRONT_CENTER):
721 downMixTable_[FC][i] = COEF_0DB_F;
722 break;
723 case (SIDE_LEFT):
724 case (TOP_SIDE_LEFT):
725 downMixTable_[gSl_][i] = COEF_0DB_F;
726 break;
727 case (SIDE_RIGHT):
728 case (TOP_SIDE_RIGHT):
729 downMixTable_[gSr_][i] = COEF_0DB_F;
730 break;
731 case (BACK_LEFT):
732 case (TOP_BACK_LEFT):
733 downMixTable_[BL][i] = COEF_0DB_F;
734 break;
735 case (BACK_RIGHT):
736 case (TOP_BACK_RIGHT):
737 downMixTable_[BR][i] = COEF_0DB_F;
738 break;
739 default:
740 break;
741 }
742 }
743
Setup7Point1DmixTablePart2(uint64_t bit,uint32_t i)744 void DownMixer::Setup7Point1DmixTablePart2(uint64_t bit, uint32_t i)
745 {
746 switch (bit) {
747 case (LOW_FREQUENCY):
748 case (LOW_FREQUENCY_2):
749 if (mixLfe_) {
750 downMixTable_[SW][i] = COEF_0DB_F;
751 }
752 break;
753 case (FRONT_LEFT_OF_CENTER):
754 downMixTable_[FL][i] = COEF_M45DB_F;
755 downMixTable_[FC][i] = COEF_M3DB_F;
756 break;
757 case (FRONT_RIGHT_OF_CENTER):
758 downMixTable_[FR][i] = COEF_M45DB_F;
759 downMixTable_[FC][i] = COEF_M3DB_F;
760 break;
761 case (BACK_CENTER):
762 case (TOP_BACK_CENTER):
763 downMixTable_[BL][i] = COEF_M3DB_F;
764 downMixTable_[BR][i] = COEF_M3DB_F;
765 break;
766 case (TOP_CENTER):
767 downMixTable_[FC][i] = COEF_M6DB_F;
768 downMixTable_[gSl_][i] = COEF_M6DB_F;
769 downMixTable_[gSr_][i] = COEF_M6DB_F;
770 break;
771 default:
772 break;
773 }
774 }
775
Setup7Point1Point2DmixTablePart1(uint64_t bit,uint32_t i)776 void DownMixer::Setup7Point1Point2DmixTablePart1(uint64_t bit, uint32_t i)
777 {
778 switch (bit) {
779 case (FRONT_LEFT):
780 case (TOP_FRONT_LEFT):
781 case (BOTTOM_FRONT_LEFT):
782 case (WIDE_LEFT):
783 downMixTable_[FL][i] = COEF_0DB_F;
784 break;
785 case (FRONT_RIGHT):
786 case (TOP_FRONT_RIGHT):
787 case (BOTTOM_FRONT_RIGHT):
788 case (WIDE_RIGHT):
789 downMixTable_[FR][i] = COEF_0DB_F;
790 break;
791 case (FRONT_CENTER):
792 case (TOP_FRONT_CENTER):
793 case (BOTTOM_FRONT_CENTER):
794 downMixTable_[FC][i] = COEF_0DB_F;
795 break;
796 case (SIDE_LEFT):
797 downMixTable_[gSl_][i] = COEF_0DB_F;
798 break;
799 case (SIDE_RIGHT):
800 downMixTable_[gSr_][i] = COEF_0DB_F;
801 break;
802 case (BACK_LEFT):
803 downMixTable_[BL][i] = COEF_0DB_F;
804 break;
805 case (BACK_RIGHT):
806 downMixTable_[BR][i] = COEF_0DB_F;
807 break;
808 case (TOP_BACK_LEFT):
809 case (TOP_SIDE_LEFT):
810 downMixTable_[gTsl_][i] = COEF_0DB_F;
811 break;
812 case (TOP_BACK_RIGHT):
813 case (TOP_SIDE_RIGHT):
814 downMixTable_[gTsr_][i] = COEF_0DB_F;
815 break;
816 case (LOW_FREQUENCY):
817 case (LOW_FREQUENCY_2):
818 if (mixLfe_) {
819 downMixTable_[SW][i] = COEF_0DB_F;
820 }
821 break;
822 default:
823 break;
824 }
825 }
826
Setup7Point1Point2DmixTablePart2(uint64_t bit,uint32_t i)827 void DownMixer::Setup7Point1Point2DmixTablePart2(uint64_t bit, uint32_t i)
828 {
829 switch (bit) {
830 case (FRONT_LEFT_OF_CENTER):
831 downMixTable_[FL][i] = COEF_M45DB_F;
832 downMixTable_[FC][i] = COEF_M3DB_F;
833 break;
834 case (FRONT_RIGHT_OF_CENTER):
835 downMixTable_[FR][i] = COEF_M45DB_F;
836 downMixTable_[FC][i] = COEF_M3DB_F;
837 break;
838 case (BACK_CENTER):
839 downMixTable_[BL][i] = COEF_M3DB_F;
840 downMixTable_[BR][i] = COEF_M3DB_F;
841 break;
842 case (TOP_BACK_CENTER):
843 case (TOP_CENTER):
844 downMixTable_[gTsl_][i] = COEF_M3DB_F;
845 downMixTable_[gTsr_][i] = COEF_M3DB_F;
846 break;
847 default:
848 break;
849 }
850 }
851
Setup7Point1Point4DmixTablePart1(uint64_t bit,uint32_t i)852 void DownMixer::Setup7Point1Point4DmixTablePart1(uint64_t bit, uint32_t i)
853 {
854 switch (bit) {
855 case (FRONT_LEFT):
856 case (BOTTOM_FRONT_LEFT):
857 case (WIDE_LEFT):
858 downMixTable_[FL][i] = COEF_0DB_F;
859 break;
860 case (FRONT_RIGHT):
861 case (BOTTOM_FRONT_RIGHT):
862 case (WIDE_RIGHT):
863 downMixTable_[FR][i] = COEF_0DB_F;
864 break;
865 case (FRONT_CENTER):
866 case (BOTTOM_FRONT_CENTER):
867 downMixTable_[FC][i] = COEF_0DB_F;
868 break;
869 case (SIDE_LEFT):
870 downMixTable_[gSl_][i] = COEF_0DB_F;
871 break;
872 case (SIDE_RIGHT):
873 downMixTable_[gSr_][i] = COEF_0DB_F;
874 break;
875 case (BACK_LEFT):
876 downMixTable_[BL][i] = COEF_0DB_F;
877 break;
878 case (BACK_RIGHT):
879 downMixTable_[BR][i] = COEF_0DB_F;
880 break;
881 case (TOP_FRONT_LEFT):
882 downMixTable_[gTfl_][i] = COEF_0DB_F;
883 break;
884 case (TOP_FRONT_RIGHT):
885 downMixTable_[gTfr_][i] = COEF_0DB_F;
886 break;
887 case (TOP_BACK_LEFT):
888 case (TOP_SIDE_LEFT):
889 downMixTable_[gTbl_][i] = COEF_0DB_F;
890 break;
891 case (TOP_BACK_RIGHT):
892 case (TOP_SIDE_RIGHT):
893 downMixTable_[gTbr_][i] = COEF_0DB_F;
894 break;
895 default:
896 break;
897 }
898 }
899
Setup7Point1Point4DmixTablePart2(uint64_t bit,uint32_t i)900 void DownMixer::Setup7Point1Point4DmixTablePart2(uint64_t bit, uint32_t i)
901 {
902 switch (bit) {
903 case (LOW_FREQUENCY):
904 case (LOW_FREQUENCY_2):
905 if (mixLfe_) {
906 downMixTable_[SW][i] = COEF_0DB_F;
907 }
908 break;
909 case (FRONT_LEFT_OF_CENTER):
910 downMixTable_[FL][i] = COEF_M45DB_F;
911 downMixTable_[FC][i] = COEF_M3DB_F;
912 break;
913 case (FRONT_RIGHT_OF_CENTER):
914 downMixTable_[FR][i] = COEF_M45DB_F;
915 downMixTable_[FC][i] = COEF_M3DB_F;
916 break;
917 case (BACK_CENTER):
918 downMixTable_[BL][i] = COEF_M3DB_F;
919 downMixTable_[BR][i] = COEF_M3DB_F;
920 break;
921 case (TOP_FRONT_CENTER):
922 downMixTable_[gTfl_][i] = COEF_M3DB_F;
923 downMixTable_[gTfr_][i] = COEF_M3DB_F;
924 break;
925 case (TOP_BACK_CENTER):
926 downMixTable_[gTbl_][i] = COEF_M3DB_F;
927 downMixTable_[gTbr_][i] = COEF_M3DB_F;
928 break;
929 case (TOP_CENTER):
930 downMixTable_[gTfl_][i] = COEF_M6DB_F;
931 downMixTable_[gTfr_][i] = COEF_M6DB_F;
932 downMixTable_[gTbl_][i] = COEF_M6DB_F;
933 downMixTable_[gTbr_][i] = COEF_M6DB_F;
934 break;
935 default:
936 break;
937 }
938 }
939
DownMixBottom(uint64_t inBit,uint64_t outBit,uint32_t i,uint32_t j)940 void DownMixer::DownMixBottom(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j)
941 {
942 if ((inBit & MASK_BOTTOM) && (outBit & MASK_BOTTOM)) {
943 downMixTable_[i][j] = COEF_M3DB_F;
944 } else {
945 DownMixMidFront(inBit, outBit, i, j);
946 }
947 }
948
DownMixMidFront(uint64_t inBit,uint64_t outBit,uint32_t i,uint32_t j)949 void DownMixer::DownMixMidFront(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j)
950 {
951 if ((inBit & MASK_MIDDLE_FRONT) && (outBit & MASK_MIDDLE_FRONT)) {
952 downMixTable_[i][j] = COEF_M3DB_F;
953 }
954 }
955
DownMixMidRear(uint64_t inBit,uint64_t outBit,uint32_t i,uint32_t j)956 void DownMixer::DownMixMidRear(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j)
957 {
958 // Middle layer
959 switch (inBit) {
960 case BACK_CENTER:
961 if ((outBit == BACK_LEFT) || (outBit == SIDE_LEFT) || (outBit == WIDE_LEFT) || (outBit == FRONT_LEFT) ||
962 (outBit == BACK_RIGHT) || outBit == SIDE_RIGHT || outBit == WIDE_RIGHT || outBit == FRONT_RIGHT) {
963 downMixTable_[i][j] = COEF_M3DB_F;
964 }
965 break;
966 case BACK_LEFT:
967 if (outBit == SIDE_LEFT) {
968 downMixTable_[i][j] = COEF_0DB_F;
969 } else if (outBit == BACK_CENTER) {
970 downMixTable_[i][j] = COEF_0DB_F;
971 } else {
972 DownMixMidFront(WIDE_LEFT, outBit, i, j);
973 }
974 break;
975 case BACK_RIGHT:
976 if (outBit == SIDE_RIGHT) {
977 downMixTable_[i][j] = COEF_0DB_F;
978 } else if (outBit == BACK_CENTER) {
979 downMixTable_[i][j] = COEF_0DB_F;
980 } else {
981 DownMixMidFront(WIDE_RIGHT, outBit, i, j);
982 }
983 break;
984 default:
985 break;
986 }
987 }
988
DownMixLfe(uint64_t inBit,uint64_t outBit,uint32_t i,uint32_t j)989 void DownMixer::DownMixLfe(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j)
990 {
991 if ((MASK_LFE & inBit) && (MASK_LFE & outBit)) {
992 downMixTable_[i][j] = COEF_0DB_F;
993 } else {
994 if ((inBit == LOW_FREQUENCY) && ((outBit & CH_LAYOUT_STEREO)!= 0)) {
995 downMixTable_[i][j] = COEF_M6DB_F;
996 } else if ((inBit == LOW_FREQUENCY_2) && ((outBit & CH_LAYOUT_STEREO) != 0)) {
997 downMixTable_[i][j] = COEF_M6DB_F;
998 }
999 }
1000 }
1001
DownMixTopCenter(uint64_t inBit,uint64_t outBit,uint32_t i,uint32_t j)1002 void DownMixer::DownMixTopCenter(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j)
1003 {
1004 uint64_t exitTopOuts = outLayout_ & (MASK_TOP_FRONT | MASK_TOP_REAR);
1005 uint64_t exitMiddleOuts = outLayout_ & (MASK_MIDDLE_FRONT | MASK_MIDDLE_REAR);
1006 if (exitTopOuts != 0) { // exist top outs
1007 uint32_t numChannels = BitCounts(exitTopOuts);
1008 uint32_t coeff = 1.0f / sqrt((float)numChannels);
1009 if ((outBit & exitTopOuts) != 0) {
1010 downMixTable_[i][j] = coeff;
1011 }
1012 } else if (exitMiddleOuts != 0) {
1013 uint32_t numChannels = BitCounts(exitMiddleOuts);
1014 uint32_t coeff = 1.0f / sqrt((float)numChannels);
1015 if ((outBit & exitMiddleOuts) != 0) {
1016 downMixTable_[i][j] = coeff;
1017 }
1018 }
1019 }
1020
DownMixTopFront(uint64_t inBit,uint64_t outBit,uint32_t i,uint32_t j)1021 void DownMixer::DownMixTopFront(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j)
1022 {
1023 uint64_t existTopFrontOuts = outLayout_ & MASK_TOP_FRONT;
1024 if (existTopFrontOuts != 0) {
1025 if ((outBit & MASK_TOP_FRONT) != 0) {
1026 downMixTable_[i][j] = COEF_M3DB_F;
1027 }
1028 } else {
1029 DownMixMidFront(TOP_FRONT_CENTER, outBit, i, j);
1030 }
1031 }
1032
DownMixTopRear(uint64_t inBit,uint64_t outBit,uint32_t i,uint32_t j)1033 void DownMixer::DownMixTopRear(uint64_t inBit, uint64_t outBit, uint32_t i, uint32_t j)
1034 {
1035 uint64_t existTopRearOuts = outLayout_ & MASK_TOP_REAR;
1036 if (existTopRearOuts != 0) {
1037 if ((outBit & MASK_TOP_REAR) != 0) {
1038 downMixTable_[i][j] = COEF_M3DB_F;
1039 }
1040 } else {
1041 DownMixMidRear(BACK_CENTER, outBit, i, j);
1042 }
1043 }
1044
BitCounts(uint64_t bits)1045 static uint32_t BitCounts(uint64_t bits)
1046 {
1047 uint32_t num = 0;
1048 for (; bits != 0; bits &= bits - 1) {
1049 num++;
1050 }
1051 return num;
1052 }
1053
IsValidChLayout(AudioChannelLayout & chLayout,uint32_t chCounts)1054 static bool IsValidChLayout(AudioChannelLayout &chLayout, uint32_t chCounts)
1055 {
1056 if (chCounts < MONO || chCounts > CHANNEL_16) {
1057 return false;
1058 }
1059 if (chLayout == CH_LAYOUT_UNKNOWN || BitCounts(chLayout) != chCounts) {
1060 chLayout = DownMixer::SetDefaultChannelLayout((AudioChannel)chCounts);
1061 }
1062 return true;
1063 }
1064
SetDefaultChannelLayout(AudioChannel channels)1065 AudioChannelLayout DownMixer::SetDefaultChannelLayout(AudioChannel channels)
1066 {
1067 CHECK_AND_RETURN_RET_LOG((channels >= MONO) && (channels <= CHANNEL_16), CH_LAYOUT_UNKNOWN,
1068 "invalid channel count");
1069 switch (channels) {
1070 case MONO:
1071 return CH_LAYOUT_MONO;
1072 case STEREO:
1073 return CH_LAYOUT_STEREO;
1074 case CHANNEL_3:
1075 return CH_LAYOUT_SURROUND;
1076 case CHANNEL_4:
1077 return CH_LAYOUT_3POINT1;
1078 case CHANNEL_5:
1079 return CH_LAYOUT_4POINT1;
1080 case CHANNEL_6:
1081 return CH_LAYOUT_5POINT1;
1082 case CHANNEL_7:
1083 return CH_LAYOUT_6POINT1;
1084 case CHANNEL_8:
1085 return CH_LAYOUT_5POINT1POINT2;
1086 case CHANNEL_9:
1087 return CH_LAYOUT_HOA_ORDER2_ACN_N3D;
1088 case CHANNEL_10:
1089 return CH_LAYOUT_7POINT1POINT2;
1090 case CHANNEL_12:
1091 return CH_LAYOUT_7POINT1POINT4;
1092 case CHANNEL_14:
1093 return CH_LAYOUT_9POINT1POINT4;
1094 case CHANNEL_16:
1095 return CH_LAYOUT_9POINT1POINT6;
1096 default:
1097 return CH_LAYOUT_UNKNOWN;
1098 }
1099 }
1100
CheckIsHOA(AudioChannelLayout layout)1101 bool DownMixer::CheckIsHOA(AudioChannelLayout layout)
1102 {
1103 if ((layout == CH_LAYOUT_HOA_ORDER1_ACN_N3D) || (layout == CH_LAYOUT_HOA_ORDER1_ACN_SN3D) ||
1104 (layout == CH_LAYOUT_HOA_ORDER1_FUMA) || (layout == CH_LAYOUT_HOA_ORDER2_ACN_N3D) ||
1105 (layout == CH_LAYOUT_HOA_ORDER2_ACN_SN3D) || (layout == CH_LAYOUT_HOA_ORDER2_FUMA) ||
1106 (layout == CH_LAYOUT_HOA_ORDER3_ACN_N3D) || (layout == CH_LAYOUT_HOA_ORDER3_ACN_SN3D) ||
1107 (layout == CH_LAYOUT_HOA_ORDER3_FUMA))
1108 {
1109 isInLayoutHOA_ = true;
1110 return true;
1111 }
1112 isInLayoutHOA_ = false;
1113 return false;
1114 }
1115
1116 } // HPAE
1117 } // AudioStandard
1118 } // OHOS