• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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