1 /*
2 * Copyright (c) 2024-2024 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 #include "common/log.h"
16 #include "calc_max_amplitude.h"
17
18 namespace {
19 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_SYSTEM_PLAYER, "CalcMaxAmplitude" };
20 }
21 namespace OHOS {
22 namespace Media {
23 namespace CalcMaxAmplitude {
24 constexpr int32_t SAMPLE_S24_BYTE_NUM = 3;
25 constexpr int32_t ONE_BYTE_BITS = 8;
26 constexpr int32_t MAX_VALUE_OF_SIGNED_24_BIT = 0x7FFFFF;
27 constexpr int32_t MAX_VALUE_OF_SIGNED_32_BIT = 0x7FFFFFFF;
28 constexpr int32_t SAMPLE_U8_C = 0;
29 constexpr int32_t SAMPLE_S16_C = 1;
30 constexpr int32_t SAMPLE_S24_C = 2;
31 constexpr int32_t SAMPLE_S32_C = 3;
32
CalculateMaxAmplitudeForPCM8Bit(int8_t * frame,uint64_t nSamples)33 float CalculateMaxAmplitudeForPCM8Bit(int8_t *frame, uint64_t nSamples)
34 {
35 FALSE_RETURN_V(frame != nullptr && nSamples != 0, 0.0f);
36 int curMaxAmplitude = 0;
37 for (uint32_t i = nSamples; i > 0; --i) {
38 int8_t value = *frame++;
39 if (value < 0) {
40 value = -value;
41 }
42 if (curMaxAmplitude < value) {
43 curMaxAmplitude = value;
44 }
45 }
46 return float(curMaxAmplitude) / SCHAR_MAX;
47 }
48
CalculateMaxAmplitudeForPCM16Bit(int16_t * frame,uint64_t nSamples)49 float CalculateMaxAmplitudeForPCM16Bit(int16_t *frame, uint64_t nSamples)
50 {
51 FALSE_RETURN_V(frame != nullptr && nSamples != 0, 0.0f);
52 int curMaxAmplitude = 0;
53 for (uint32_t i = nSamples; i > 0; --i) {
54 int16_t value = *frame++;
55 if (value < 0) {
56 value = -value;
57 }
58 if (curMaxAmplitude < value) {
59 curMaxAmplitude = value;
60 }
61 }
62 return float(curMaxAmplitude) / SHRT_MAX;
63 }
64
CalculateMaxAmplitudeForPCM24Bit(char * frame,uint64_t nSamples)65 float CalculateMaxAmplitudeForPCM24Bit(char *frame, uint64_t nSamples)
66 {
67 FALSE_RETURN_V(frame != nullptr && nSamples != 0, 0.0f);
68 int curMaxAmplitude = 0;
69 for (uint32_t i = 0; i < nSamples; ++i) {
70 char *curPos = frame + (i * SAMPLE_S24_BYTE_NUM);
71 int32_t curValue = 0;
72 for (uint32_t j = 0; j < SAMPLE_S24_BYTE_NUM; ++j) {
73 curValue += (*(curPos + j) << (ONE_BYTE_BITS * j));
74 }
75 if (curValue < 0) {
76 curValue = -curValue;
77 }
78 if (curMaxAmplitude < curValue) {
79 curMaxAmplitude = curValue;
80 }
81 }
82 return float(curMaxAmplitude) / MAX_VALUE_OF_SIGNED_24_BIT;
83 }
84
CalculateMaxAmplitudeForPCM32Bit(int32_t * frame,uint64_t nSamples)85 float CalculateMaxAmplitudeForPCM32Bit(int32_t *frame, uint64_t nSamples)
86 {
87 FALSE_RETURN_V(frame != nullptr && nSamples != 0, 0.0f);
88 int curMaxAmplitude = 0;
89 for (uint32_t i = nSamples; i > 0; --i) {
90 int32_t value = *frame++;
91 if (value < 0) {
92 value = -value;
93 }
94 if (curMaxAmplitude < value) {
95 curMaxAmplitude = value;
96 }
97 }
98 return float(curMaxAmplitude) / float(MAX_VALUE_OF_SIGNED_32_BIT);
99 }
100
UpdateMaxAmplitude(char * frame,uint64_t replyBytes,int32_t adapterFormat)101 float UpdateMaxAmplitude(char *frame, uint64_t replyBytes, int32_t adapterFormat)
102 {
103 FALSE_RETURN_V(frame != nullptr && replyBytes != 0, 0.0f);
104 switch (adapterFormat) {
105 case SAMPLE_U8_C: {
106 return CalculateMaxAmplitudeForPCM8Bit(reinterpret_cast<int8_t *>(frame), replyBytes);
107 }
108 case SAMPLE_S16_C: {
109 return CalculateMaxAmplitudeForPCM16Bit(reinterpret_cast<int16_t *>(frame),
110 (replyBytes / sizeof(int16_t)));
111 }
112 case SAMPLE_S24_C: {
113 return CalculateMaxAmplitudeForPCM24Bit(frame, (replyBytes / SAMPLE_S24_BYTE_NUM));
114 }
115 case SAMPLE_S32_C: {
116 return CalculateMaxAmplitudeForPCM32Bit(reinterpret_cast<int32_t *>(frame),
117 (replyBytes / sizeof(int32_t)));
118 }
119 default: {
120 MEDIA_LOG_I("getMaxAmplitude: Unsupported audio format: %{public}d", adapterFormat);
121 return 0;
122 }
123 }
124 }
125 } // namespace CalcMaxAmpiitude
126 } // namespace Media
127 } // namespace OHOS