• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 #include "audio_common_converter.h"
16 #include <cmath>
17 
18 namespace OHOS {
19 namespace AudioStandard {
20 constexpr float AUDIO_SAMPLE_32BIT_VALUE = 2147483647.f;
21 constexpr int32_t BYTES_ALIGNMENT_SIZE = 8;
22 constexpr int32_t AUDIO_24BIT_LENGTH = 3;
23 constexpr int32_t AUDIO_SAMPLE_FORMAT_8BIT = 0;
24 constexpr int32_t AUDIO_SAMPLE_FORMAT_16BIT = 1;
25 constexpr int32_t AUDIO_SAMPLE_FORMAT_24BIT = 2;
26 constexpr int32_t AUDIO_SAMPLE_FORMAT_32BIT = 3;
27 constexpr int32_t AUDIO_SAMPLE_FORMAT_32F_BIT = 4;
28 constexpr int32_t AUDIO_SAMPLE_24BIT_LENGTH = 24;
29 constexpr int32_t AUDIO_SAMPLE_16BIT_LENGTH = 16;
30 constexpr int32_t AUDIO_NUMBER_2 = 2;
31 constexpr float SCALE = 1 << (AUDIO_SAMPLE_16BIT_LENGTH - 1);
32 
GetVolumeStep(const BufferBaseInfo & bufferInfo)33 inline float GetVolumeStep(const BufferBaseInfo &bufferInfo)
34 {
35     if (bufferInfo.frameSize <= 0) {
36         return 0.f;
37     }
38     float volStep = (bufferInfo.volumeEd - bufferInfo.volumeBg) * bufferInfo.channelCount / bufferInfo.frameSize;
39     return volStep;
40 }
41 
GetVolume(float volStep,int32_t frameIndex,float volumeBg)42 inline float GetVolume(float volStep, int32_t frameIndex, float volumeBg)
43 {
44     float vol = volStep * frameIndex + volumeBg;
45     return vol;
46 }
47 
CopyFromU8ToS32(const uint8_t * buffer,int32_t * dst,float volStep,const BufferBaseInfo & bufferInfo)48 inline void CopyFromU8ToS32(const uint8_t *buffer, int32_t *dst, float volStep, const BufferBaseInfo &bufferInfo)
49 {
50     int32_t frameCount = bufferInfo.frameSize / bufferInfo.channelCount;
51     dst += bufferInfo.frameSize;
52     buffer += bufferInfo.frameSize;
53     for (; frameCount > 0; --frameCount) {
54         float vol = GetVolume(volStep, frameCount, bufferInfo.volumeBg);
55         for (uint32_t i = 0; i < bufferInfo.channelCount; i++) {
56             *--dst = (((int32_t)(*--buffer) - 0x80) << AUDIO_SAMPLE_24BIT_LENGTH) * vol;
57         }
58     }
59 }
60 
CopyFromS16ToS32(const int16_t * buffer,int32_t * dst,float volStep,const BufferBaseInfo & bufferInfo)61 inline void CopyFromS16ToS32(const int16_t *buffer, int32_t *dst, float volStep, const BufferBaseInfo &bufferInfo)
62 {
63     int32_t frameCount = bufferInfo.frameSize / bufferInfo.channelCount;
64     dst += bufferInfo.frameSize;
65     buffer += bufferInfo.frameSize;
66     for (; frameCount > 0; --frameCount) {
67         float vol = GetVolume(volStep, frameCount, bufferInfo.volumeBg);
68         for (uint32_t i = 0; i < bufferInfo.channelCount; i++) {
69             *--dst = (((int32_t) * --buffer) << AUDIO_SAMPLE_16BIT_LENGTH) * vol;
70         }
71     }
72 }
73 
CopyFrom24ToS32(const uint8_t * buffer,int32_t * dst,float volStep,const BufferBaseInfo & bufferInfo)74 static void CopyFrom24ToS32(const uint8_t *buffer, int32_t *dst, float volStep, const BufferBaseInfo &bufferInfo)
75 {
76     int32_t frameCount = bufferInfo.frameSize / bufferInfo.channelCount;
77     dst += bufferInfo.frameSize;
78     buffer += bufferInfo.frameSize * AUDIO_24BIT_LENGTH;
79     for (; frameCount > 0; --frameCount) {
80         float vol = GetVolume(volStep, frameCount, bufferInfo.volumeBg);
81         for (uint32_t i = 0; i < bufferInfo.channelCount; i++) {
82             buffer -= AUDIO_24BIT_LENGTH;
83             *--dst = ((buffer[0] << BYTES_ALIGNMENT_SIZE) | (buffer[1] << AUDIO_SAMPLE_16BIT_LENGTH) |
84                 (buffer[AUDIO_NUMBER_2] << AUDIO_SAMPLE_24BIT_LENGTH)) * vol;
85         }
86     }
87 }
88 
CopyFromS32ToS32(const int32_t * buffer,int32_t * dst,float volStep,const BufferBaseInfo & bufferInfo)89 inline void CopyFromS32ToS32(const int32_t *buffer, int32_t *dst, float volStep, const BufferBaseInfo &bufferInfo)
90 {
91     int32_t frameCount = bufferInfo.frameSize / bufferInfo.channelCount;
92     dst += bufferInfo.frameSize;
93     buffer += bufferInfo.frameSize;
94     for (; frameCount > 0; --frameCount) {
95         float vol = GetVolume(volStep, frameCount, bufferInfo.volumeBg);
96         for (uint32_t i = 0; i < bufferInfo.channelCount; i++) {
97             *--dst = (*--buffer * vol);
98         }
99     }
100 }
101 
CopyFromF32ToS32(const float * buffer,int32_t * dst,float volStep,const BufferBaseInfo & bufferInfo)102 inline void CopyFromF32ToS32(const float *buffer, int32_t *dst, float volStep, const BufferBaseInfo &bufferInfo)
103 {
104     int32_t frameCount = bufferInfo.frameSize / bufferInfo.channelCount;
105     for (int32_t j = 0; j < frameCount; j++) {
106         float vol = GetVolume(volStep, j + 1, bufferInfo.volumeBg);
107         for (uint32_t i = 0; i < bufferInfo.channelCount; i++) {
108             *dst++ = *buffer++ * vol * AUDIO_SAMPLE_32BIT_VALUE;
109         }
110     }
111 }
112 
ConvertBufferTo32Bit(const BufferBaseInfo & srcBuffer,std::vector<char> & dstBuffer)113 void AudioCommonConverter::ConvertBufferTo32Bit(const BufferBaseInfo &srcBuffer, std::vector<char> &dstBuffer)
114 {
115     if (srcBuffer.frameSize != (dstBuffer.size() / sizeof(int32_t))) {
116         return;
117     }
118     uint8_t *buffer = srcBuffer.buffer;
119     float volumeStep = GetVolumeStep(srcBuffer);
120     int32_t *dst = reinterpret_cast<int32_t *>(dstBuffer.data());
121     switch (srcBuffer.format) {
122         case AUDIO_SAMPLE_FORMAT_8BIT:
123             CopyFromU8ToS32(buffer, dst, volumeStep, srcBuffer);
124             break;
125         case AUDIO_SAMPLE_FORMAT_16BIT: {
126             const int16_t *src = reinterpret_cast<const int16_t *>(buffer);
127             CopyFromS16ToS32(src, dst, volumeStep, srcBuffer);
128             break;
129         }
130         case AUDIO_SAMPLE_FORMAT_24BIT:
131             CopyFrom24ToS32(buffer, dst, volumeStep, srcBuffer);
132             break;
133         case AUDIO_SAMPLE_FORMAT_32BIT: {
134             const int32_t *src = reinterpret_cast<const int32_t *>(buffer);
135             CopyFromS32ToS32(src, dst, volumeStep, srcBuffer);
136             break;
137         }
138         case AUDIO_SAMPLE_FORMAT_32F_BIT: {
139             const float *src = reinterpret_cast<const float *>(buffer);
140             CopyFromF32ToS32(src, dst, volumeStep, srcBuffer);
141             break;
142         }
143         default:
144             break;
145     }
146 }
147 
CopyFromU8ToS16(const uint8_t * buffer,int16_t * dst,float volStep,const BufferBaseInfo & bufferInfo)148 inline void CopyFromU8ToS16(const uint8_t *buffer, int16_t *dst, float volStep, const BufferBaseInfo &bufferInfo)
149 {
150     int32_t frameCount = bufferInfo.frameSize / bufferInfo.channelCount;
151     dst += bufferInfo.frameSize;
152     buffer += bufferInfo.frameSize;
153     for (; frameCount > 0; --frameCount) {
154         float vol = GetVolume(volStep, frameCount, bufferInfo.volumeBg);
155         for (uint32_t i = 0; i < bufferInfo.channelCount; i++) {
156             *--dst = (((int16_t)(*--buffer) - 0x80) << BYTES_ALIGNMENT_SIZE) * vol;
157         }
158     }
159 }
160 
CopyFromS16ToS16(const int16_t * buffer,int16_t * dst,float volStep,const BufferBaseInfo & bufferInfo)161 inline void CopyFromS16ToS16(const int16_t *buffer, int16_t *dst, float volStep, const BufferBaseInfo &bufferInfo)
162 {
163     int32_t frameCount = bufferInfo.frameSize / bufferInfo.channelCount;
164     dst += bufferInfo.frameSize;
165     buffer += bufferInfo.frameSize;
166     for (; frameCount > 0; --frameCount) {
167         float vol = GetVolume(volStep, frameCount, bufferInfo.volumeBg);
168         for (uint32_t i = 0; i < bufferInfo.channelCount; i++) {
169             *--dst = (*--buffer * vol);
170         }
171     }
172 }
173 
CopyFrom24ToS16(const uint8_t * buffer,int16_t * dst,float volStep,const BufferBaseInfo & bufferInfo)174 inline void CopyFrom24ToS16(const uint8_t *buffer, int16_t *dst, float volStep, const BufferBaseInfo &bufferInfo)
175 {
176     int32_t frameCount = bufferInfo.frameSize / bufferInfo.channelCount;
177     dst += bufferInfo.frameSize;
178     buffer += bufferInfo.frameSize * AUDIO_24BIT_LENGTH;
179     for (; frameCount > 0; --frameCount) {
180         float vol = GetVolume(volStep, frameCount, bufferInfo.volumeBg);
181         for (uint32_t i = 0; i < bufferInfo.channelCount; i++) {
182             buffer -= AUDIO_24BIT_LENGTH;
183             *--dst = ((buffer[1]) | (buffer[AUDIO_NUMBER_2] << BYTES_ALIGNMENT_SIZE)) * vol;
184         }
185     }
186 }
187 
CopyFromS32ToS16(const int32_t * buffer,int16_t * dst,float volStep,const BufferBaseInfo & bufferInfo)188 inline void CopyFromS32ToS16(const int32_t *buffer, int16_t *dst, float volStep, const BufferBaseInfo &bufferInfo)
189 {
190     int32_t frameCount = bufferInfo.frameSize / bufferInfo.channelCount;
191     dst += bufferInfo.frameSize;
192     buffer += bufferInfo.frameSize;
193     for (; frameCount > 0; --frameCount) {
194         float vol = GetVolume(volStep, frameCount, bufferInfo.volumeBg);
195         for (uint32_t i = 0; i < bufferInfo.channelCount; i++) {
196             *--dst = ((*--buffer >> AUDIO_SAMPLE_16BIT_LENGTH) * vol);
197         }
198     }
199 }
200 
CopyFromF32ToS16(const float * buffer,int16_t * dst,float volStep,const BufferBaseInfo & bufferInfo)201 inline void CopyFromF32ToS16(const float *buffer, int16_t *dst, float volStep, const BufferBaseInfo &bufferInfo)
202 {
203     int32_t frameCount = bufferInfo.frameSize / bufferInfo.channelCount;
204     for (int32_t j = 0; j < frameCount; j++) {
205         float vol = GetVolume(volStep, j + 1, bufferInfo.volumeBg);
206         for (uint32_t i = 0; i < bufferInfo.channelCount; i++) {
207             *dst++ = *buffer++ * SCALE * vol;
208         }
209     }
210 }
211 
ConvertBufferTo16Bit(const BufferBaseInfo & srcBuffer,std::vector<char> & dstBuffer)212 void AudioCommonConverter::ConvertBufferTo16Bit(const BufferBaseInfo &srcBuffer, std::vector<char> &dstBuffer)
213 {
214     if (srcBuffer.frameSize != (dstBuffer.size() / sizeof(int16_t))) {
215         return;
216     }
217     int16_t *dst = reinterpret_cast<int16_t *>(dstBuffer.data());
218     uint8_t *buffer = srcBuffer.buffer;
219     float volumeStep = GetVolumeStep(srcBuffer);
220     switch (srcBuffer.format) {
221         case AUDIO_SAMPLE_FORMAT_8BIT:
222             CopyFromU8ToS16(buffer, dst, volumeStep, srcBuffer);
223             break;
224         case AUDIO_SAMPLE_FORMAT_16BIT: {
225             const int16_t *src = reinterpret_cast<const int16_t *>(buffer);
226             CopyFromS16ToS16(src, dst, volumeStep, srcBuffer);
227             break;
228         }
229         case AUDIO_SAMPLE_FORMAT_24BIT:
230             CopyFrom24ToS16(buffer, dst, volumeStep, srcBuffer);
231             break;
232         case AUDIO_SAMPLE_FORMAT_32BIT: {
233             const int32_t *src = reinterpret_cast<const int32_t *>(buffer);
234             CopyFromS32ToS16(src, dst, volumeStep, srcBuffer);
235             break;
236         }
237         case AUDIO_SAMPLE_FORMAT_32F_BIT: {
238             const float *src = reinterpret_cast<const float *>(buffer);
239             CopyFromF32ToS16(src, dst, volumeStep, srcBuffer);
240             break;
241         }
242         default:
243             break;
244     }
245 }
246 
ConvertS24ToFloat(const uint8_t * buffer,int32_t index,int32_t format)247 inline int32_t ConvertS24ToFloat(const uint8_t *buffer, int32_t index, int32_t format)
248 {
249     int32_t sampleValue = 0;
250     sampleValue = ((buffer[index * format + AUDIO_NUMBER_2] & 0xff) << AUDIO_SAMPLE_24BIT_LENGTH) |
251         ((buffer[index * format + 1] & 0xff) << AUDIO_SAMPLE_16BIT_LENGTH) |
252         ((buffer[index * format] & 0xff) << BYTES_ALIGNMENT_SIZE);
253     return sampleValue;
254 }
255 
ConvertFloatToFloatWithVolume(const BufferBaseInfo & srcBuffer,std::vector<float> & floatBuffer)256 void AudioCommonConverter::ConvertFloatToFloatWithVolume(const BufferBaseInfo &srcBuffer,
257                                                          std::vector<float> &floatBuffer)
258 {
259     if (srcBuffer.frameSize != floatBuffer.size()) {
260         return;
261     }
262     float *buffer = reinterpret_cast<float *>(srcBuffer.buffer);
263     float volumeStep = GetVolumeStep(srcBuffer);
264     uint32_t frameCount = floatBuffer.size() / srcBuffer.channelCount;
265     for (uint32_t i = 0; i < frameCount; i++) {
266         float volume = GetVolume(volumeStep, i + 1, srcBuffer.volumeBg);
267         for (uint32_t j = 0; j < srcBuffer.channelCount; j++) {
268             uint32_t index = i * srcBuffer.channelCount + j;
269             floatBuffer[index] = buffer[index] * volume;
270         }
271     }
272 }
273 
ConvertBufferToFloat(const BufferBaseInfo & srcBuffer,std::vector<float> & floatBuffer)274 void AudioCommonConverter::ConvertBufferToFloat(const BufferBaseInfo &srcBuffer, std::vector<float> &floatBuffer)
275 {
276     if (srcBuffer.frameSize != floatBuffer.size()) {
277         return;
278     }
279     uint8_t *buffer = srcBuffer.buffer;
280     float volumeStep = GetVolumeStep(srcBuffer);
281     uint32_t convertValue = srcBuffer.samplePerFrame * BYTES_ALIGNMENT_SIZE - 1;
282     uint32_t frameCount = floatBuffer.size() / srcBuffer.channelCount;
283     for (uint32_t i = 0; i < frameCount; i++) {
284         float volume = GetVolume(volumeStep, i + 1, srcBuffer.volumeBg);
285         for (uint32_t j = 0; j < srcBuffer.channelCount; j++) {
286             int32_t sampleValue = 0;
287             uint32_t index = i * srcBuffer.channelCount + j;
288             if (srcBuffer.samplePerFrame == AUDIO_24BIT_LENGTH) {
289                 sampleValue = ConvertS24ToFloat(buffer, static_cast<int32_t>(index), srcBuffer.samplePerFrame);
290                 floatBuffer[index] = sampleValue * volume * (1.0f / AUDIO_SAMPLE_32BIT_VALUE);
291                 continue;
292             }
293             for (uint32_t k = 0; k < srcBuffer.samplePerFrame; k++) {
294                 sampleValue |= (buffer[index * srcBuffer.samplePerFrame + k] & 0xff) << (k * BYTES_ALIGNMENT_SIZE);
295             }
296             floatBuffer[index] = sampleValue * volume * (1.0f / (1U << convertValue));
297         }
298     }
299 }
300 
ConvertFloatToAudioBuffer(const std::vector<float> & floatBuffer,uint8_t * buffer,uint32_t samplePerFrame)301 void AudioCommonConverter::ConvertFloatToAudioBuffer(const std::vector<float> &floatBuffer, uint8_t *buffer,
302     uint32_t samplePerFrame)
303 {
304     uint32_t convertValue = samplePerFrame * BYTES_ALIGNMENT_SIZE - 1;
305     for (uint32_t i = 0; i < floatBuffer.size(); i++) {
306         int32_t sampleValue = static_cast<int32_t>(floatBuffer[i] * std::pow(AUDIO_NUMBER_2, convertValue));
307         for (uint32_t j = 0; j < samplePerFrame; j++) {
308             uint8_t tempValue = (sampleValue >> (BYTES_ALIGNMENT_SIZE * j)) & 0xff;
309             buffer[samplePerFrame * i + j] = tempValue;
310         }
311     }
312 }
313 } // namespace AudioStandard
314 } // namespace OHOS
315