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