1 /*
2 * Copyright (c) 2023-2025 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 #ifndef LOG_TAG
16 #define LOG_TAG "VolumeTools"
17 #endif
18
19 #include <cmath>
20
21 #include "volume_tools.h"
22 #include "volume_tools_c.h"
23 #include "audio_errors.h"
24 #include "audio_service_log.h"
25 #include "audio_utils.h"
26
27 namespace {
28 static const int32_t UINT8_SHIFT = 0x80;
29 static const int32_t INT24_SHIFT = 8;
30 static const int32_t INT24_MAX_VALUE = 8388607;
31 static const uint32_t SHIFT_EIGHT = 8;
32 static const int32_t RIGHT_SHIFT_8 = 256;
33 static const uint32_t SHIFT_SIXTEEN = 16;
34 static const uint32_t ARRAY_INDEX_TWO = 2;
35 static const size_t MIN_FRAME_SIZE = 1;
36 static const size_t MAX_FRAME_SIZE = 100000; // max to about 2s for 48khz
37 static const uint32_t INT_32_MAX = 0x7fffffff;
38 static const int32_t HALF_FACTOR = 2;
39 static const int32_t INT32_VOLUME_MIN = 0; // 0, min volume
40 static const uint32_t VOLUME_SHIFT = 16;
41 static constexpr int32_t INT32_VOLUME_MAX = 1 << VOLUME_SHIFT; // 1 << 16 = 65536, max volume
42 }
43 namespace OHOS {
44 namespace AudioStandard {
IsVolumeValid(float volFloat)45 bool VolumeTools::IsVolumeValid(float volFloat)
46 {
47 return volFloat >= 0.0 && volFloat <= 1.0;
48 }
49
IsVolumeValid(int32_t volInt)50 bool VolumeTools::IsVolumeValid(int32_t volInt)
51 {
52 return volInt >= INT32_VOLUME_MIN && volInt <= INT32_VOLUME_MAX;
53 }
IsVolumeValid(ChannelVolumes vols)54 bool VolumeTools::IsVolumeValid(ChannelVolumes vols)
55 {
56 if (vols.channel > CHANNEL_16 || vols.channel < MONO) {
57 return false;
58 }
59 for (size_t i = 0; i < vols.channel; i++) {
60 if (!IsVolumeValid(vols.volStart[i]) || !IsVolumeValid(vols.volEnd[i])) {
61 return false;
62 }
63 }
64
65 return true;
66 }
67
GetInt32Vol(float volFloat)68 int32_t VolumeTools::GetInt32Vol(float volFloat)
69 {
70 if (IsVolumeValid(volFloat)) {
71 return volFloat * INT32_VOLUME_MAX;
72 }
73 if (volFloat < 0.0) {
74 return INT32_VOLUME_MIN;
75 }
76 return INT32_VOLUME_MAX;
77 }
78
GetChannelVolumes(AudioChannel channel,int32_t volStart,int32_t volEnd)79 ChannelVolumes VolumeTools::GetChannelVolumes(AudioChannel channel, int32_t volStart, int32_t volEnd)
80 {
81 ChannelVolumes vols = {};
82 if (!IsVolumeValid(volStart) || !IsVolumeValid(volEnd) || channel > CHANNEL_16 || channel < MONO) {
83 AUDIO_ERR_LOG("GetChannelVolumes failed with invalid vol:%{public}d %{public}d channel: %{public}d", volStart,
84 volEnd, channel);
85 return vols;
86 }
87 for (size_t i = 0; i < channel; i++) {
88 vols.volStart[i] = volStart;
89 vols.volEnd[i] = volEnd;
90 }
91 vols.channel = channel;
92 return vols;
93 }
94
GetChannelVolumes(AudioChannel channel,float volStart,float volEnd)95 ChannelVolumes VolumeTools::GetChannelVolumes(AudioChannel channel, float volStart, float volEnd)
96 {
97 ChannelVolumes vols = {};
98 if (!IsVolumeValid(volStart) || !IsVolumeValid(volEnd) || channel > CHANNEL_16 || channel < MONO) {
99 AUDIO_ERR_LOG("GetChannelVolumes failed with invalid vol:%{public}f %{public}f channel: %{public}d", volStart,
100 volEnd, channel);
101 return vols;
102 }
103 for (size_t i = 0; i < channel; i++) {
104 vols.volStart[i] = GetInt32Vol(volStart);
105 vols.volEnd[i] = GetInt32Vol(volEnd);
106 }
107 vols.channel = channel;
108 return vols;
109 }
110
GetByteSize(AudioSampleFormat format)111 size_t VolumeTools::GetByteSize(AudioSampleFormat format)
112 {
113 size_t bitWidthSize = 0;
114 switch (format) {
115 case SAMPLE_U8:
116 bitWidthSize = 1; // size is 1
117 break;
118 case SAMPLE_S16LE:
119 bitWidthSize = 2; // size is 2
120 break;
121 case SAMPLE_S24LE:
122 bitWidthSize = 3; // size is 3
123 break;
124 case SAMPLE_S32LE:
125 bitWidthSize = 4; // size is 4
126 break;
127 case SAMPLE_F32LE:
128 bitWidthSize = 4; // size is 4
129 break;
130 default:
131 bitWidthSize = 2; // default size is 2
132 break;
133 }
134 return bitWidthSize;
135 }
136
ReadInt24LE(const uint8_t * p)137 static inline uint32_t ReadInt24LE(const uint8_t *p)
138 {
139 return ((uint32_t) p[ARRAY_INDEX_TWO] << SHIFT_SIXTEEN) | ((uint32_t) p[1] << SHIFT_EIGHT) | ((uint32_t) p[0]);
140 }
141
WriteInt24LE(uint8_t * p,uint32_t u)142 static inline void WriteInt24LE(uint8_t *p, uint32_t u)
143 {
144 p[ARRAY_INDEX_TWO] = (uint8_t) (u >> SHIFT_SIXTEEN);
145 p[1] = (uint8_t) (u >> SHIFT_EIGHT);
146 p[0] = (uint8_t) u;
147 }
148
VolumeFlatten(int32_t vol)149 inline int32_t VolumeFlatten(int32_t vol)
150 {
151 return vol < INT32_VOLUME_MIN ? 0 : (vol > INT32_VOLUME_MAX ? INT32_VOLUME_MAX : vol);
152 }
153
ProcessOneFrame(uint8_t * ptr,AudioSampleFormat format,int32_t vol)154 void ProcessOneFrame(uint8_t *ptr, AudioSampleFormat format, int32_t vol)
155 {
156 int64_t temp = 0;
157 int16_t *raw16 = nullptr;
158 int32_t *raw32 = nullptr;
159 float *rawFloat = nullptr;
160 switch (format) {
161 case SAMPLE_U8:
162 temp = *ptr - UINT8_SHIFT;
163 temp = (temp * vol) >> VOLUME_SHIFT;
164 temp = temp < INT8_MIN ? INT8_MIN : (temp > INT8_MAX ? INT8_MAX : temp);
165 *ptr = static_cast<uint8_t>(temp + UINT8_SHIFT);
166 break;
167 case SAMPLE_S16LE:
168 raw16 = reinterpret_cast<int16_t *>(ptr);
169 temp = (*raw16 * static_cast<int64_t>(vol)) >> VOLUME_SHIFT;
170 *raw16 = temp > INT16_MAX ? INT16_MAX : (temp < INT16_MIN ? INT16_MIN : temp);
171 break;
172 case SAMPLE_S24LE:
173 temp = static_cast<int32_t>(ReadInt24LE(ptr) << INT24_SHIFT) * static_cast<int64_t>(vol) >> VOLUME_SHIFT;
174 WriteInt24LE(ptr, (static_cast<uint32_t>(temp) >> INT24_SHIFT));
175 break;
176 case SAMPLE_S32LE:
177 raw32 = reinterpret_cast<int32_t *>(ptr);
178 // int32_t * int16_t, max result is int48_t
179 temp = (*raw32 * static_cast<int64_t>(vol)) >> VOLUME_SHIFT;
180 *raw32 = temp > INT32_MAX ? INT32_MAX : (temp < INT32_MIN ? INT32_MIN : temp);
181 break;
182 case SAMPLE_F32LE:
183 rawFloat = reinterpret_cast<float *>(ptr);
184 *rawFloat = *rawFloat * (static_cast<float>(vol) / INT32_VOLUME_MAX);
185 break;
186 default:
187 AUDIO_ERR_LOG("ProcessOneFrame with invalid format");
188 break;
189 }
190 }
191
192 // |---------frame1--------|---------frame2--------|---------frame3--------|
193 // |ch1-ch2-ch3-ch4-ch5-ch6|ch1-ch2-ch3-ch4-ch5-ch6|ch1-ch2-ch3-ch4-ch5-ch6|
Process(const RingBufferWrapper & ringBufferDesc,AudioSampleFormat format,ChannelVolumes vols)194 int32_t VolumeTools::Process(const RingBufferWrapper& ringBufferDesc, AudioSampleFormat format, ChannelVolumes vols)
195 {
196 // parms check
197 if (format > SAMPLE_F32LE || !IsVolumeValid(vols)) {
198 AUDIO_ERR_LOG("Process failed with invalid params");
199 return ERR_INVALID_PARAM;
200 }
201 size_t byteSizePerData = GetByteSize(format);
202 size_t byteSizePerFrame = byteSizePerData * vols.channel;
203 if (ringBufferDesc.dataLength == 0 || ((ringBufferDesc.dataLength % byteSizePerFrame) != 0) ||
204 ((ringBufferDesc.basicBufferDescs[0].bufLength) % byteSizePerFrame != 0)) {
205 AUDIO_ERR_LOG("Process failed with invalid buffer, size is %{public}zu", ringBufferDesc.dataLength);
206 return ERR_INVALID_PARAM;
207 }
208
209 size_t frameSize = ringBufferDesc.dataLength / byteSizePerFrame;
210 if (frameSize < MIN_FRAME_SIZE) {
211 AUDIO_ERR_LOG("Process failed with invalid frameSize, size is %{public}zu", frameSize);
212 return ERR_INVALID_PARAM;
213 }
214
215 float volStep[CHANNEL_MAX] = {};
216 for (size_t channelIdx = 0; channelIdx < vols.channel; channelIdx++) {
217 if (vols.volEnd[channelIdx] == vols.volStart[channelIdx] || frameSize == MIN_FRAME_SIZE) {
218 volStep[channelIdx] = 0.0;
219 } else {
220 volStep[channelIdx] = (static_cast<float>(vols.volEnd[channelIdx] - vols.volStart[channelIdx])) /
221 (frameSize - MIN_FRAME_SIZE);
222 }
223 }
224
225 RingBufferWrapper srcBuffer = ringBufferDesc;
226 for (size_t frameIndex = 0; frameIndex < frameSize; frameIndex++) {
227 for (size_t channelIdx = 0; channelIdx < vols.channel; channelIdx++) {
228 int32_t vol = volStep[channelIdx] * frameIndex + vols.volStart[channelIdx];
229 vol = VolumeFlatten(vol);
230 uint8_t *samplePtr = srcBuffer.basicBufferDescs[0].buffer + channelIdx * byteSizePerData;
231 ProcessOneFrame(samplePtr, format, vol);
232 }
233 if (srcBuffer.SeekFromStart(byteSizePerFrame) != SUCCESS) {
234 // This branch should never be executed under any valid conditions. Consider let it crash?
235 AUDIO_ERR_LOG("Seek err");
236 return ERR_INVALID_PARAM;
237 }
238 }
239
240 return SUCCESS;
241 }
242
Process(const BufferDesc & bufferDesc,AudioSampleFormat format,ChannelVolumes vols)243 int32_t VolumeTools::Process(const BufferDesc &bufferDesc, AudioSampleFormat format, ChannelVolumes vols)
244 {
245 if (bufferDesc.dataLength > bufferDesc.bufLength || bufferDesc.buffer == nullptr || bufferDesc.dataLength == 0) {
246 AUDIO_ERR_LOG("invalid bufferDesc");
247 return ERR_INVALID_PARAM;
248 }
249 RingBufferWrapper ringBufferDesc;
250 ringBufferDesc.dataLength = bufferDesc.dataLength;
251 ringBufferDesc.basicBufferDescs[0].bufLength = bufferDesc.bufLength;
252 ringBufferDesc.basicBufferDescs[0].buffer = bufferDesc.buffer;
253
254 return Process(ringBufferDesc, format, vols);
255 }
256
GetVolDb(AudioSampleFormat format,int32_t vol)257 double VolumeTools::GetVolDb(AudioSampleFormat format, int32_t vol)
258 {
259 double volume = static_cast<double>(vol);
260 switch (format) {
261 case SAMPLE_U8:
262 volume = volume / INT8_MAX;
263 break;
264 case SAMPLE_S16LE:
265 volume = volume / INT16_MAX;
266 break;
267 case SAMPLE_S24LE:
268 volume = volume / INT24_MAX_VALUE;
269 break;
270 case SAMPLE_S32LE:
271 volume = volume / INT32_MAX;
272 break;
273 case SAMPLE_F32LE:
274 volume = volume / INT32_MAX;
275 break;
276 default:
277 break;
278 }
279 return std::log10(volume);
280 }
281
CountU8Volume(const BufferDesc & buffer,AudioChannel channel,ChannelVolumes & volMaps,size_t split,AudioSampleFormat format)282 static void CountU8Volume(const BufferDesc &buffer, AudioChannel channel, ChannelVolumes &volMaps, size_t split,
283 AudioSampleFormat format)
284 {
285 if (split == 0) {
286 AUDIO_ERR_LOG("invalid split");
287 return;
288 }
289 size_t byteSizePerData = VolumeTools::GetByteSize(format);
290 size_t byteSizePerFrame = byteSizePerData * channel;
291 if (buffer.buffer == nullptr || byteSizePerFrame == 0 || buffer.bufLength % byteSizePerFrame != 0) {
292 AUDIO_ERR_LOG("invalid buffer, size is %{public}zu", buffer.bufLength);
293 return;
294 }
295 size_t frameSize = buffer.bufLength / byteSizePerFrame;
296 if (frameSize < MIN_FRAME_SIZE || frameSize >= MAX_FRAME_SIZE) {
297 AUDIO_ERR_LOG("invalid frameSize, size is %{public}zu", frameSize);
298 return;
299 }
300
301 // reset maps
302 for (size_t index = 0; index < channel; index++) {
303 volMaps.volStart[index] = 0;
304 volMaps.volEnd[index] = 0;
305 }
306 uint8_t *raw8 = buffer.buffer;
307 for (size_t frameIndex = 0; frameIndex < frameSize - (split - 1); frameIndex += split) {
308 for (size_t channelIdx = 0; channelIdx < channel; channelIdx++) {
309 volMaps.volStart[channelIdx] += (*raw8 >= UINT8_SHIFT ? *raw8 - UINT8_SHIFT : UINT8_SHIFT - *raw8);
310 raw8++;
311 }
312 raw8 += (split - 1) * channel;
313 }
314 // Calculate the average value
315 size_t size = frameSize / split;
316 if (size == 0) {
317 AUDIO_ERR_LOG("invalid size");
318 return;
319 }
320 for (size_t index = 0; index < channel; index++) {
321 volMaps.volStart[index] /= static_cast<int32_t>(size);
322 }
323 return;
324 }
325
CountS16Volume(const BufferDesc & buffer,AudioChannel channel,ChannelVolumes & volMaps,size_t split,AudioSampleFormat format)326 static void CountS16Volume(const BufferDesc &buffer, AudioChannel channel, ChannelVolumes &volMaps, size_t split,
327 AudioSampleFormat format)
328 {
329 if (split == 0) {
330 AUDIO_ERR_LOG("invalid split");
331 return;
332 }
333 size_t byteSizePerData = VolumeTools::GetByteSize(format);
334 size_t byteSizePerFrame = byteSizePerData * channel;
335 if (buffer.buffer == nullptr || byteSizePerFrame == 0 || buffer.bufLength % byteSizePerFrame != 0) {
336 AUDIO_ERR_LOG("invalid buffer, size is %{public}zu", buffer.bufLength);
337 return;
338 }
339 size_t frameSize = buffer.bufLength / byteSizePerFrame;
340 if (frameSize < MIN_FRAME_SIZE || frameSize >= MAX_FRAME_SIZE) {
341 AUDIO_ERR_LOG("invalid frameSize, size is %{public}zu", frameSize);
342 return;
343 }
344
345 // reset maps
346 for (size_t index = 0; index < channel; index++) {
347 volMaps.volStart[index] = 0;
348 volMaps.volEnd[index] = 0;
349 }
350 int16_t *raw16 = reinterpret_cast<int16_t *>(buffer.buffer);
351 for (size_t frameIndex = 0; frameIndex < frameSize - (split - 1); frameIndex += split) {
352 for (size_t channelIdx = 0; channelIdx < channel; channelIdx++) {
353 volMaps.volStart[channelIdx] += (*raw16 >= 0 ? *raw16 : (-*raw16));
354 raw16++;
355 }
356 raw16 += (split - 1) * channel;
357 }
358 // Calculate the average value
359 size_t size = frameSize / split;
360 if (size == 0) {
361 AUDIO_ERR_LOG("invalid size");
362 return;
363 }
364 for (size_t index = 0; index < channel; index++) {
365 volMaps.volStart[index] /= static_cast<int32_t>(size);
366 }
367 return;
368 }
369
CountS24Volume(const BufferDesc & buffer,AudioChannel channel,ChannelVolumes & volMaps,size_t split,AudioSampleFormat format)370 static void CountS24Volume(const BufferDesc &buffer, AudioChannel channel, ChannelVolumes &volMaps, size_t split,
371 AudioSampleFormat format)
372 {
373 if (split == 0) {
374 AUDIO_ERR_LOG("invalid split");
375 return;
376 }
377 const size_t byteSizePerData = VolumeTools::GetByteSize(format);
378 size_t byteSizePerFrame = byteSizePerData * channel;
379 if (buffer.buffer == nullptr || byteSizePerFrame == 0 || buffer.bufLength % byteSizePerFrame != 0) {
380 AUDIO_ERR_LOG("invalid buffer, size is %{public}zu", buffer.bufLength);
381 return;
382 }
383 size_t frameSize = buffer.bufLength / byteSizePerFrame;
384 if (frameSize < MIN_FRAME_SIZE || frameSize >= MAX_FRAME_SIZE) {
385 AUDIO_ERR_LOG("invalid frameSize, size is %{public}zu", frameSize);
386 return;
387 }
388
389 // reset maps
390 for (size_t index = 0; index < channel; index++) {
391 volMaps.volStart[index] = 0;
392 volMaps.volEnd[index] = 0;
393 }
394 int64_t volSums[CHANNEL_MAX] = {0};
395 uint8_t *raw8 = buffer.buffer;
396 for (size_t frameIndex = 0; frameIndex < frameSize - (split - 1); frameIndex += split) {
397 for (size_t channelIdx = 0; channelIdx < channel; channelIdx++) {
398 int32_t sample = static_cast<int32_t>(ReadInt24LE(raw8) << INT24_SHIFT);
399 volSums[channelIdx] += std::abs(sample);
400 raw8 += byteSizePerData;
401 }
402 raw8 += (split - 1) * channel * byteSizePerData;
403 }
404 // Calculate the average value
405 size_t size = frameSize / split;
406 if (size == 0) {
407 AUDIO_ERR_LOG("invalid size");
408 return;
409 }
410 for (size_t index = 0; index < channel; index++) {
411 volSums[index] /= RIGHT_SHIFT_8; // equal to " >> INT24_SHIFT"
412 volMaps.volStart[index] = static_cast<int32_t>(volSums[index] / size);
413 }
414 return;
415 }
416
CountS32Volume(const BufferDesc & buffer,AudioChannel channel,ChannelVolumes & volMaps,size_t split,AudioSampleFormat format)417 static void CountS32Volume(const BufferDesc &buffer, AudioChannel channel, ChannelVolumes &volMaps, size_t split,
418 AudioSampleFormat format)
419 {
420 if (split == 0) {
421 AUDIO_ERR_LOG("invalid split");
422 return;
423 }
424 const size_t byteSizePerData = VolumeTools::GetByteSize(format);
425 size_t byteSizePerFrame = byteSizePerData * channel;
426 if (buffer.buffer == nullptr || byteSizePerFrame == 0 || buffer.bufLength % byteSizePerFrame != 0) {
427 AUDIO_ERR_LOG("invalid buffer, size is %{public}zu", buffer.bufLength);
428 return;
429 }
430 size_t frameSize = buffer.bufLength / byteSizePerFrame;
431 if (frameSize < MIN_FRAME_SIZE || frameSize >= MAX_FRAME_SIZE) {
432 AUDIO_ERR_LOG("invalid frameSize, size is %{public}zu", frameSize);
433 return;
434 }
435
436 // reset maps
437 int64_t volSums[CHANNEL_MAX] = {0};
438 for (size_t index = 0; index < CHANNEL_MAX; index++) {
439 volSums[index] = 0;
440 }
441 int32_t *raw32 = reinterpret_cast<int32_t *>(buffer.buffer);
442 for (size_t frameIndex = 0; frameIndex < frameSize - (split - 1); frameIndex += split) {
443 for (size_t channelIdx = 0; channelIdx < channel; channelIdx++) {
444 if (*raw32 >= 0) {
445 volSums[channelIdx] += *raw32;
446 } else {
447 volSums[channelIdx] -= *raw32;
448 }
449 raw32++;
450 }
451 raw32 += (split - 1) * channel;
452 }
453
454 // Calculate the average value
455 size_t size = frameSize / split;
456 if (size == 0) {
457 AUDIO_ERR_LOG("invalid size");
458 return;
459 }
460 for (size_t index = 0; index < channel; index++) {
461 volSums[index] /= static_cast<int64_t>(size);
462 volMaps.volStart[index] = static_cast<int32_t>(volSums[index]);
463 }
464 return;
465 }
466
CountF32Volume(const BufferDesc & buffer,AudioChannel channel,ChannelVolumes & volMaps,size_t split,AudioSampleFormat format)467 static void CountF32Volume(const BufferDesc &buffer, AudioChannel channel, ChannelVolumes &volMaps, size_t split,
468 AudioSampleFormat format)
469 {
470 if (split == 0) {
471 AUDIO_ERR_LOG("invalid split");
472 return;
473 }
474 size_t byteSizePerData = VolumeTools::GetByteSize(format);
475 size_t byteSizePerFrame = byteSizePerData * channel;
476 if (buffer.buffer == nullptr || byteSizePerFrame == 0 || buffer.bufLength % byteSizePerFrame != 0) {
477 AUDIO_ERR_LOG("invalid buffer, size is %{public}zu", buffer.bufLength);
478 return;
479 }
480 size_t frameSize = buffer.bufLength / byteSizePerFrame;
481 if (frameSize < MIN_FRAME_SIZE || frameSize >= MAX_FRAME_SIZE) {
482 AUDIO_ERR_LOG("invalid frameSize, size is %{public}zu", frameSize);
483 return;
484 }
485
486 // reset maps
487 double volSums[CHANNEL_MAX] = {0};
488 for (size_t index = 0; index < CHANNEL_MAX; index++) {
489 volSums[index] = 0.0;
490 }
491 float *raw32 = reinterpret_cast<float *>(buffer.buffer);
492 for (size_t frameIndex = 0; frameIndex < frameSize - (split - 1); frameIndex += split) {
493 for (size_t channelIdx = 0; channelIdx < channel; channelIdx++) {
494 volSums[channelIdx] += (*raw32 >= 0 ? *raw32 : (-*raw32));
495 raw32++;
496 }
497 raw32 += (split - 1) * channel;
498 }
499 // Calculate the average value
500 size_t size = frameSize / split;
501 if (size == 0) {
502 AUDIO_ERR_LOG("invalid size");
503 return;
504 }
505 for (size_t index = 0; index < channel; index++) {
506 volSums[index] = (volSums[index] * INT32_MAX) / static_cast<double>(size);
507 volMaps.volStart[index] = static_cast<int32_t>(volSums[index]);
508 }
509 return;
510 }
511
CountVolumeLevel(const BufferDesc & buffer,AudioSampleFormat format,AudioChannel channel,size_t split)512 ChannelVolumes VolumeTools::CountVolumeLevel(const BufferDesc &buffer, AudioSampleFormat format, AudioChannel channel,
513 size_t split)
514 {
515 ChannelVolumes channelVols = {};
516 channelVols.channel = channel;
517 if (format > SAMPLE_F32LE || channel > CHANNEL_16) {
518 AUDIO_ERR_LOG("failed with invalid params");
519 return channelVols;
520 }
521 switch (format) {
522 case SAMPLE_U8:
523 CountU8Volume(buffer, channel, channelVols, split, format);
524 break;
525 case SAMPLE_S16LE:
526 CountS16Volume(buffer, channel, channelVols, split, format);
527 break;
528 case SAMPLE_S24LE:
529 CountS24Volume(buffer, channel, channelVols, split, format);
530 break;
531 case SAMPLE_S32LE:
532 CountS32Volume(buffer, channel, channelVols, split, format);
533 break;
534 case SAMPLE_F32LE:
535 CountF32Volume(buffer, channel, channelVols, split, format);
536 break;
537 default:
538 break;
539 }
540
541 return channelVols;
542 }
543
DfxOperation(const BufferDesc & buffer,AudioStreamInfo streamInfo,std::string logTag,int64_t & volumeDataCount,size_t split)544 void VolumeTools::DfxOperation(const BufferDesc &buffer, AudioStreamInfo streamInfo, std::string logTag,
545 int64_t &volumeDataCount, size_t split)
546 {
547 size_t byteSizePerData = GetByteSize(streamInfo.format);
548 size_t frameLen = byteSizePerData * static_cast<size_t>(streamInfo.channels) *
549 static_cast<size_t>(streamInfo.samplingRate) * 0.02; // 0.02s
550 CHECK_AND_RETURN_LOG(frameLen > 0, "frameLen is invalid");
551 int64_t minVolume = INT_32_MAX;
552 for (size_t index = 0; index < (buffer.bufLength + frameLen - 1) / frameLen; index++) {
553 BufferDesc temp = {buffer.buffer + frameLen * index, std::min(buffer.bufLength - frameLen * index, frameLen),
554 std::min(buffer.dataLength - frameLen * index, frameLen)};
555 ChannelVolumes vols = CountVolumeLevel(temp, streamInfo.format, streamInfo.channels, split);
556 if (streamInfo.channels == MONO) {
557 minVolume = std::min(minVolume, static_cast<int64_t>(vols.volStart[0]));
558 } else {
559 minVolume = std::min(minVolume, static_cast<int64_t>(vols.volStart[0]) / HALF_FACTOR
560 + static_cast<int64_t>(vols.volStart[1]) / HALF_FACTOR);
561 }
562 AudioLogUtils::ProcessVolumeData(logTag, vols, volumeDataCount);
563 }
564 Trace::Count(logTag, minVolume);
565 }
566
CalcMuteFrame(BufferDesc & buffer,AudioStreamInfo streamInfo,std::string logTag,int64_t & volumeDataCount,int64_t & muteFrameCnt,size_t split)567 void VolumeTools::CalcMuteFrame(BufferDesc &buffer, AudioStreamInfo streamInfo, std::string logTag,
568 int64_t &volumeDataCount, int64_t &muteFrameCnt, size_t split)
569 {
570 size_t byteSizePerData = VolumeTools::GetByteSize(streamInfo.format);
571 size_t byteSizePerFrame = byteSizePerData * streamInfo.channels;
572 size_t frameLen = byteSizePerData * static_cast<size_t>(streamInfo.channels) *
573 static_cast<size_t>(streamInfo.samplingRate) * 0.02; // 0.02s
574
575 if (frameLen == 0) {
576 AUDIO_ERR_LOG("invalid size");
577 return;
578 }
579 int64_t minVolume = INT_32_MAX;
580 for (size_t index = 0; index < (buffer.bufLength + frameLen - 1) / frameLen; index++) {
581 BufferDesc temp = {buffer.buffer + frameLen * index, std::min(buffer.bufLength - frameLen * index, frameLen),
582 std::min(buffer.dataLength - frameLen * index, frameLen)};
583
584 size_t frameSize = temp.bufLength / byteSizePerFrame;
585 ChannelVolumes vols = VolumeTools::CountVolumeLevel(temp, streamInfo.format, streamInfo.channels, split);
586 if (streamInfo.channels == MONO) {
587 minVolume = std::min(minVolume, static_cast<int64_t>(vols.volStart[0]));
588 } else {
589 minVolume = std::min(minVolume, static_cast<int64_t>(vols.volStart[0]) / HALF_FACTOR
590 + static_cast<int64_t>(vols.volStart[1]) / HALF_FACTOR);
591 }
592 AudioLogUtils::ProcessVolumeData(logTag, vols, volumeDataCount);
593 if (volumeDataCount < 0) {
594 muteFrameCnt += static_cast<int64_t>(frameSize);
595 }
596 }
597 Trace::Count(logTag, minVolume);
598 }
599
IsZeroVolume(float volume)600 bool VolumeTools::IsZeroVolume(float volume)
601 {
602 float d = volume - 0.0f;
603 if ((d >= 0 && d <= FLOAT_EPS) || (d <= 0 && d >= -FLOAT_EPS)) {
604 return true;
605 }
606 return false;
607 }
608 } // namespace AudioStandard
609 } // namespace OHOS
610
611 #ifdef __cplusplus
612 extern "C" {
613 #endif
614 using namespace OHOS::AudioStandard;
615
ProcessVol(uint8_t * buffer,size_t length,AudioRawFormat rawformat,float volStart,float volEnd)616 int32_t ProcessVol(uint8_t *buffer, size_t length, AudioRawFormat rawformat, float volStart, float volEnd)
617 {
618 BufferDesc desc = {0};
619 desc.buffer = buffer;
620 desc.bufLength = length;
621 desc.dataLength = length;
622 ChannelVolumes mapVols = VolumeTools::GetChannelVolumes(static_cast<AudioChannel>(rawformat.channels), volStart,
623 volEnd);
624 return VolumeTools::Process(desc, static_cast<AudioSampleFormat>(rawformat.format), mapVols);
625 }
626
627 #ifdef __cplusplus
628 }
629 #endif