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