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