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