/* * Copyright (c) 2024-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common/log.h" #include "calc_max_amplitude.h" namespace { constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_SYSTEM_PLAYER, "CalcMaxAmplitude" }; } namespace OHOS { namespace Media { namespace CalcMaxAmplitude { constexpr int32_t SAMPLE_S24_BYTE_NUM = 3; constexpr int32_t ONE_BYTE_BITS = 8; constexpr int32_t MAX_VALUE_OF_SIGNED_24_BIT = 0x7FFFFF; constexpr int32_t MAX_VALUE_OF_SIGNED_32_BIT = 0x7FFFFFFF; constexpr int32_t SAMPLE_U8_C = 0; constexpr int32_t SAMPLE_S16_C = 1; constexpr int32_t SAMPLE_S24_C = 2; constexpr int32_t SAMPLE_S32_C = 3; float CalculateMaxAmplitudeForPCM8Bit(int8_t *frame, uint64_t nSamples) { FALSE_RETURN_V(frame != nullptr && nSamples != 0, 0.0f); int curMaxAmplitude = 0; for (uint32_t i = nSamples; i > 0; --i) { int8_t value = *frame++; if (value < 0) { value = -value; } if (curMaxAmplitude < value) { curMaxAmplitude = value; } } return float(curMaxAmplitude) / SCHAR_MAX; } float CalculateMaxAmplitudeForPCM16Bit(int16_t *frame, uint64_t nSamples) { FALSE_RETURN_V(frame != nullptr && nSamples != 0, 0.0f); int curMaxAmplitude = 0; for (uint32_t i = nSamples; i > 0; --i) { int16_t value = *frame++; if (value < 0) { value = -value; } if (curMaxAmplitude < value) { curMaxAmplitude = value; } } return float(curMaxAmplitude) / SHRT_MAX; } float CalculateMaxAmplitudeForPCM24Bit(char *frame, uint64_t nSamples) { FALSE_RETURN_V(frame != nullptr && nSamples != 0, 0.0f); int curMaxAmplitude = 0; for (uint32_t i = 0; i < nSamples; ++i) { char *curPos = frame + (i * SAMPLE_S24_BYTE_NUM); int32_t curValue = 0; for (uint32_t j = 0; j < SAMPLE_S24_BYTE_NUM; ++j) { curValue += (*(curPos + j) << (ONE_BYTE_BITS * j)); } if (curValue < 0) { curValue = -curValue; } if (curMaxAmplitude < curValue) { curMaxAmplitude = curValue; } } return float(curMaxAmplitude) / MAX_VALUE_OF_SIGNED_24_BIT; } float CalculateMaxAmplitudeForPCM32Bit(int32_t *frame, uint64_t nSamples) { FALSE_RETURN_V(frame != nullptr && nSamples != 0, 0.0f); int curMaxAmplitude = 0; for (uint32_t i = nSamples; i > 0; --i) { int32_t value = *frame++; if (value < 0) { value = -value; } if (curMaxAmplitude < value) { curMaxAmplitude = value; } } return float(curMaxAmplitude) / float(MAX_VALUE_OF_SIGNED_32_BIT); } float UpdateMaxAmplitude(char *frame, uint64_t replyBytes, int32_t adapterFormat) { FALSE_RETURN_V(frame != nullptr && replyBytes != 0, 0.0f); switch (adapterFormat) { case SAMPLE_U8_C: { return CalculateMaxAmplitudeForPCM8Bit(reinterpret_cast(frame), replyBytes); } case SAMPLE_S16_C: { return CalculateMaxAmplitudeForPCM16Bit(reinterpret_cast(frame), (replyBytes / sizeof(int16_t))); } case SAMPLE_S24_C: { return CalculateMaxAmplitudeForPCM24Bit(frame, (replyBytes / SAMPLE_S24_BYTE_NUM)); } case SAMPLE_S32_C: { return CalculateMaxAmplitudeForPCM32Bit(reinterpret_cast(frame), (replyBytes / sizeof(int32_t))); } default: { MEDIA_LOG_I("getMaxAmplitude: Unsupported audio format: %{public}d", adapterFormat); return 0; } } } } // namespace CalcMaxAmpiitude } // namespace Media } // namespace OHOS