From 5ed4701fc9424f54eebf96849d2d9afcc9a36cbf Mon Sep 17 00:00:00 2001 From: "hezhiqiang19@huawei.com" Date: Sun, 21 Jul 2024 08:37:28 +0000 Subject: [PATCH] count volume level Signed-off-by: hezhiqiang19@huawei.com Change-Id: I3d8e43a5c1aef88a5f34618d25685afb43a67436 --- .../native/audioutils/include/audio_utils.h | 1 + .../native/audioutils/src/audio_utils.cpp | 18 +- .../common/include/volume_tools.h | 4 + .../audio_service/common/src/volume_tools.cpp | 228 ++++++++++++++++++ 4 files changed, 248 insertions(+), 3 deletions(-) diff --git a/frameworks/native/audioutils/include/audio_utils.h b/frameworks/native/audioutils/include/audio_utils.h index c88f5c4fd3..c6fb8a5384 100644 --- a/frameworks/native/audioutils/include/audio_utils.h +++ b/frameworks/native/audioutils/include/audio_utils.h @@ -112,6 +112,7 @@ public: class PermissionUtil { public: + static bool VerifyIsShell(); static bool VerifyIsSystemApp(); static bool VerifySelfPermission(); static bool VerifySystemPermission(); diff --git a/frameworks/native/audioutils/src/audio_utils.cpp b/frameworks/native/audioutils/src/audio_utils.cpp index 2fbae36073..b5ebead267 100644 --- a/frameworks/native/audioutils/src/audio_utils.cpp +++ b/frameworks/native/audioutils/src/audio_utils.cpp @@ -191,6 +191,16 @@ void AudioXCollie::CancelXCollieTimer() } } +bool PermissionUtil::VerifyIsShell() +{ + auto tokenId = IPCSkeleton::GetCallingTokenID(); + auto tokenTypeFlag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId); + if (tokenTypeFlag == Security::AccessToken::TOKEN_SHELL) { + return true; + } + return false; +} + bool PermissionUtil::VerifyIsSystemApp() { uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID(); @@ -224,9 +234,9 @@ bool PermissionUtil::VerifySystemPermission() auto tokenTypeFlag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId); CHECK_AND_RETURN_RET(tokenTypeFlag != Security::AccessToken::TOKEN_NATIVE, true); - +#ifdef AUDIO_BUILD_VARIANT_ROOT CHECK_AND_RETURN_RET(tokenTypeFlag != Security::AccessToken::TOKEN_SHELL, true); - +#endif bool tmp = VerifyIsSystemApp(); CHECK_AND_RETURN_RET(!tmp, true); @@ -633,7 +643,9 @@ FILE *DumpFileUtil::OpenDumpFileInner(std::string para, std::string fileName, Au CHECK_AND_RETURN_RET_LOG(dumpFile != nullptr, dumpFile, "Error opening pcm dump file:%{public}s", filePath.c_str()); } - AUDIO_INFO_LOG("Dump file path: %{public}s", filePath.c_str()); + if (dumpFile != nullptr) { + AUDIO_INFO_LOG("Dump file path: %{public}s", filePath.c_str()); + } g_lastPara[para] = dumpPara; return dumpFile; } diff --git a/services/audio_service/common/include/volume_tools.h b/services/audio_service/common/include/volume_tools.h index 720e2a24dd..3ff7914388 100644 --- a/services/audio_service/common/include/volume_tools.h +++ b/services/audio_service/common/include/volume_tools.h @@ -37,6 +37,7 @@ static inline bool IsVolumeSame(const float& x, const float& y, const float& eps class VolumeTools { public: + static double GetVolDb(AudioSampleFormat format, int32_t vol); static bool IsVolumeValid(float volFloat); // 0.0 <= volFloat <= 1.0 static bool IsVolumeValid(int32_t volInt); // 0 <= volInt <= 65536 static bool IsVolumeValid(ChannelVolumes vols); @@ -47,6 +48,9 @@ public: // Data size should be rounded to each sample size // There will be significant sound quality loss when process uint8_t samples. static int32_t Process(const BufferDesc &buffer, AudioSampleFormat format, ChannelVolumes vols); + + // will count volume for each channel, vol sum will be kept in volStart + static ChannelVolumes CountVolumeLevel(const BufferDesc &buffer, AudioSampleFormat format, AudioChannel channel); }; } // namespace AudioStandard } // namespace OHOS diff --git a/services/audio_service/common/src/volume_tools.cpp b/services/audio_service/common/src/volume_tools.cpp index eddd216a22..9b08360f9c 100644 --- a/services/audio_service/common/src/volume_tools.cpp +++ b/services/audio_service/common/src/volume_tools.cpp @@ -15,6 +15,8 @@ #undef LOG_TAG #define LOG_TAG "VolumeTools" +#include + #include "volume_tools.h" #include "volume_tools_c.h" #include "audio_errors.h" @@ -23,10 +25,12 @@ namespace { static const int32_t UINT8_SHIFT = 0x80; static const int32_t INT24_SHIFT = 8; +static const int32_t INT24_MAX_VALUE = 8388607; static const uint32_t SHIFT_EIGHT = 8; static const uint32_t SHIFT_SIXTEEN = 16; static const uint32_t ARRAY_INDEX_TWO = 2; static const size_t MIN_FRAME_SIZE = 1; +static const size_t MAX_FRAME_SIZE = 100000; // max to about 2s for 48khz } namespace OHOS { namespace AudioStandard { @@ -219,6 +223,230 @@ int32_t VolumeTools::Process(const BufferDesc &buffer, AudioSampleFormat format, return SUCCESS; } + +double VolumeTools::GetVolDb(AudioSampleFormat format, int32_t vol) +{ + double volume = static_cast(vol); + switch (format) { + case SAMPLE_U8: + volume = volume / INT8_MAX; + break; + case SAMPLE_S16LE: + volume = volume / INT16_MAX; + break; + case SAMPLE_S24LE: + volume = volume / INT24_MAX_VALUE; + break; + case SAMPLE_S32LE: + volume = volume / INT32_MAX; + break; + case SAMPLE_F32LE: + volume = volume / INT32_MAX; + break; + default: + break; + } + return std::log10(volume); +} + +static void CountU8Volume(const BufferDesc &buffer, AudioChannel channel, ChannelVolumes &volMaps) +{ + size_t byteSizePerData = 1; // 1 for unsigned 8bit + size_t byteSizePerFrame = byteSizePerData * channel; + if (buffer.buffer == nullptr || byteSizePerFrame == 0 || buffer.bufLength % byteSizePerFrame != 0) { + AUDIO_ERR_LOG("invalid buffer, size is %{public}zu", buffer.bufLength); + return; + } + size_t frameSize = buffer.bufLength / byteSizePerFrame; + if (frameSize <= MIN_FRAME_SIZE || frameSize >= MAX_FRAME_SIZE) { + AUDIO_ERR_LOG("invalid frameSize, size is %{public}zu", frameSize); + return; + } + + // reset maps + for (size_t index = 0; index < channel; index++) { + volMaps.volStart[index] = 0; + volMaps.volEnd[index] = 0; + } + uint8_t *raw8 = buffer.buffer; + for (size_t frameIndex = 0; frameIndex < frameSize; frameIndex++) { + for (size_t channelIdx = 0; channelIdx < channel; channelIdx++) { + volMaps.volStart[channelIdx] += (*raw8 >= UINT8_SHIFT ? *raw8 - UINT8_SHIFT : UINT8_SHIFT - *raw8); + raw8++; + } + } + // Calculate the average value + for (size_t index = 0; index < channel; index++) { + volMaps.volStart[index] /= frameSize; + } + return; +} + +static void CountS16Volume(const BufferDesc &buffer, AudioChannel channel, ChannelVolumes &volMaps) +{ + size_t byteSizePerData = 2; // 2 for signed 16bit + size_t byteSizePerFrame = byteSizePerData * channel; + if (buffer.buffer == nullptr || byteSizePerFrame == 0 || buffer.bufLength % byteSizePerFrame != 0) { + AUDIO_ERR_LOG("invalid buffer, size is %{public}zu", buffer.bufLength); + return; + } + size_t frameSize = buffer.bufLength / byteSizePerFrame; + if (frameSize <= MIN_FRAME_SIZE || frameSize >= MAX_FRAME_SIZE) { + AUDIO_ERR_LOG("invalid frameSize, size is %{public}zu", frameSize); + return; + } + + // reset maps + for (size_t index = 0; index < channel; index++) { + volMaps.volStart[index] = 0; + volMaps.volEnd[index] = 0; + } + int16_t *raw16 = reinterpret_cast(buffer.buffer); + for (size_t frameIndex = 0; frameIndex < frameSize; frameIndex++) { + for (size_t channelIdx = 0; channelIdx < channel; channelIdx++) { + volMaps.volStart[channelIdx] += (*raw16 >= 0 ? *raw16: (-*raw16)); + raw16++; + } + } + // Calculate the average value + for (size_t index = 0; index < channel; index++) { + volMaps.volStart[index] /= frameSize; + } + return; +} + +static void CountS24Volume(const BufferDesc &buffer, AudioChannel channel, ChannelVolumes &volMaps) +{ + size_t byteSizePerData = 3; // 3 for 24bit + size_t byteSizePerFrame = byteSizePerData * channel; + if (buffer.buffer == nullptr || byteSizePerFrame == 0 || buffer.bufLength % byteSizePerFrame != 0) { + AUDIO_ERR_LOG("invalid buffer, size is %{public}zu", buffer.bufLength); + return; + } + size_t frameSize = buffer.bufLength / byteSizePerFrame; + if (frameSize <= MIN_FRAME_SIZE || frameSize >= MAX_FRAME_SIZE) { + AUDIO_ERR_LOG("invalid frameSize, size is %{public}zu", frameSize); + return; + } + + // reset maps + for (size_t index = 0; index < channel; index++) { + volMaps.volStart[index] = 0; + volMaps.volEnd[index] = 0; + } + uint8_t *raw8 = buffer.buffer; + for (size_t frameIndex = 0; frameIndex < frameSize; frameIndex++) { + for (size_t channelIdx = 0; channelIdx < channel; channelIdx++) { + int32_t sample = static_cast(ReadInt24LE(raw8)); + volMaps.volStart[channelIdx] += (sample >= 0 ? sample: (-sample)); + raw8 += byteSizePerData; + } + } + // Calculate the average value + for (size_t index = 0; index < channel; index++) { + volMaps.volStart[index] /= frameSize; + } + return; +} + +static void CountS32Volume(const BufferDesc &buffer, AudioChannel channel, ChannelVolumes &volMaps) +{ + size_t byteSizePerData = 4; // 4 for signed 32bit + size_t byteSizePerFrame = byteSizePerData * channel; + if (buffer.buffer == nullptr || byteSizePerFrame == 0 || buffer.bufLength % byteSizePerFrame != 0) { + AUDIO_ERR_LOG("invalid buffer, size is %{public}zu", buffer.bufLength); + return; + } + size_t frameSize = buffer.bufLength / byteSizePerFrame; + if (frameSize <= MIN_FRAME_SIZE || frameSize >= MAX_FRAME_SIZE) { + AUDIO_ERR_LOG("invalid frameSize, size is %{public}zu", frameSize); + return; + } + + // reset maps + int64_t volSums[CHANNEL_MAX] = {0}; + for (size_t index = 0; index < CHANNEL_MAX; index++) { + volSums[index] = 0; + } + int32_t *raw32 = reinterpret_cast(buffer.buffer); + for (size_t frameIndex = 0; frameIndex < frameSize; frameIndex++) { + for (size_t channelIdx = 0; channelIdx < channel; channelIdx++) { + volSums[channelIdx] += (*raw32 >= 0 ? *raw32: (-*raw32)); + raw32++; + } + } + // Calculate the average value + for (size_t index = 0; index < channel; index++) { + volSums[index] /= frameSize; + volMaps.volStart[index] = volSums[index]; + } + return; +} + +static void CountF32Volume(const BufferDesc &buffer, AudioChannel channel, ChannelVolumes &volMaps) +{ + size_t byteSizePerData = 4; // 4 for 32bit + size_t byteSizePerFrame = byteSizePerData * channel; + if (buffer.buffer == nullptr || byteSizePerFrame == 0 || buffer.bufLength % byteSizePerFrame != 0) { + AUDIO_ERR_LOG("invalid buffer, size is %{public}zu", buffer.bufLength); + return; + } + size_t frameSize = buffer.bufLength / byteSizePerFrame; + if (frameSize <= MIN_FRAME_SIZE || frameSize >= MAX_FRAME_SIZE) { + AUDIO_ERR_LOG("invalid frameSize, size is %{public}zu", frameSize); + return; + } + + // reset maps + double volSums[CHANNEL_MAX] = {0}; + for (size_t index = 0; index < CHANNEL_MAX; index++) { + volSums[index] = 0.0; + } + float *raw32 = reinterpret_cast(buffer.buffer); + for (size_t frameIndex = 0; frameIndex < frameSize; frameIndex++) { + for (size_t channelIdx = 0; channelIdx < channel; channelIdx++) { + volSums[channelIdx] += (*raw32 >= 0 ? *raw32: (-*raw32)); + raw32++; + } + } + // Calculate the average value + for (size_t index = 0; index < channel; index++) { + volSums[index] /= frameSize; + volMaps.volStart[index] = static_cast(volSums[index]); + } + return; +} + +ChannelVolumes VolumeTools::CountVolumeLevel(const BufferDesc &buffer, AudioSampleFormat format, AudioChannel channel) +{ + ChannelVolumes channelVols; + channelVols.channel = channel; + if (format > SAMPLE_F32LE || channel > CHANNEL_16) { + AUDIO_ERR_LOG("failed with invalid params"); + return channelVols; + } + switch (format) { + case SAMPLE_U8: + CountU8Volume(buffer, channel, channelVols); + break; + case SAMPLE_S16LE: + CountS16Volume(buffer, channel, channelVols); + break; + case SAMPLE_S24LE: + CountS24Volume(buffer, channel, channelVols); + break; + case SAMPLE_S32LE: + CountS32Volume(buffer, channel, channelVols); + break; + case SAMPLE_F32LE: + CountF32Volume(buffer, channel, channelVols); + break; + default: + break; + } + + return channelVols; +} } // namespace AudioStandard } // namespace OHOS -- Gitee