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