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