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 
ConvertBufferTo32Bit(const uint8_t * buffer,int32_t format,int32_t * dst,size_t count,float volume)32 void AudioCommonConverter::ConvertBufferTo32Bit(const uint8_t *buffer, int32_t format, int32_t *dst, size_t count,
33                                                 float volume)
34 {
35     switch (format) {
36         case AUDIO_SAMPLE_FORMAT_8BIT:
37             dst += count;
38             buffer += count;
39             for (; count > 0; --count) {
40                 *--dst = ((int32_t)(*--buffer) - 0x80) << AUDIO_SAMPLE_24BIT_LENGTH;
41             }
42             break;
43         case AUDIO_SAMPLE_FORMAT_16BIT: {
44             const int16_t *src = reinterpret_cast<const int16_t *>(buffer);
45             dst += count;
46             src += count;
47             for (; count > 0; --count) {
48                 *--dst = (int32_t)((*--src << AUDIO_SAMPLE_16BIT_LENGTH) * volume);
49             }
50             break;
51         }
52         case AUDIO_SAMPLE_FORMAT_24BIT:
53             dst += count;
54             buffer += count * AUDIO_24BIT_LENGTH;
55             for (; count > 0; --count) {
56                 buffer -= AUDIO_24BIT_LENGTH;
57                 *--dst = ((buffer[0] << BYTES_ALIGNMENT_SIZE) | (buffer[1] << AUDIO_SAMPLE_16BIT_LENGTH) |
58                           (buffer[AUDIO_NUMBER_2] << AUDIO_SAMPLE_24BIT_LENGTH)) *
59                          volume;
60             }
61             break;
62         case AUDIO_SAMPLE_FORMAT_32BIT: {
63             const int32_t *src = reinterpret_cast<const int32_t *>(buffer);
64             dst += count;
65             src += count;
66             for (; count > 0; --count) {
67                 *--dst = (*--src * volume);
68             }
69             break;
70         }
71         case AUDIO_SAMPLE_FORMAT_32F_BIT: {
72             const float *src = reinterpret_cast<const float *>(buffer);
73             for (; count > 0; --count) {
74                 *dst++ = *src++ * volume * AUDIO_SAMPLE_32BIT_VALUE;
75             }
76             break;
77         }
78         default:
79             break;
80     }
81 }
82 
ConvertBufferTo16Bit(const uint8_t * buffer,int32_t format,int16_t * dst,size_t count,float volume)83 void AudioCommonConverter::ConvertBufferTo16Bit(const uint8_t *buffer, int32_t format, int16_t *dst, size_t count,
84                                                 float volume)
85 {
86     switch (format) {
87         case AUDIO_SAMPLE_FORMAT_8BIT:
88             dst += count;
89             buffer += count;
90             for (; count > 0; --count) {
91                 *--dst = ((int16_t)(*--buffer) - 0x80) << BYTES_ALIGNMENT_SIZE;
92             }
93             break;
94         case AUDIO_SAMPLE_FORMAT_16BIT: {
95             const int16_t *src = reinterpret_cast<const int16_t *>(buffer);
96             dst += count;
97             src += count;
98             for (; count > 0; --count) {
99                 *--dst = (*--src * volume);
100             }
101             break;
102         }
103         case AUDIO_SAMPLE_FORMAT_24BIT:
104             dst += count;
105             buffer += count * AUDIO_24BIT_LENGTH;
106             for (; count > 0; --count) {
107                 *dst++ = ((buffer[1]) | (buffer[AUDIO_NUMBER_2] << BYTES_ALIGNMENT_SIZE)) * volume;
108                 buffer += AUDIO_24BIT_LENGTH;
109             }
110             break;
111         case AUDIO_SAMPLE_FORMAT_32BIT: {
112             const int32_t *src = reinterpret_cast<const int32_t *>(buffer);
113             dst += count;
114             src += count;
115             for (; count > 0; --count) {
116                 *--dst = ((*--src >> AUDIO_SAMPLE_16BIT_LENGTH) * volume);
117             }
118             break;
119         }
120         case AUDIO_SAMPLE_FORMAT_32F_BIT: {
121             const float *src = reinterpret_cast<const float *>(buffer);
122             static const float scale = 1 << (AUDIO_SAMPLE_16BIT_LENGTH - 1);
123             for (; count > 0; --count) {
124                 *dst++ = *src++ * scale * volume;
125             }
126             break;
127         }
128         default:
129             break;
130     }
131 }
132 
ConvertBufferToFloat(const uint8_t * buffer,uint32_t samplePerFrame,std::vector<float> & floatBuffer,float volume)133 void AudioCommonConverter::ConvertBufferToFloat(const uint8_t *buffer, uint32_t samplePerFrame,
134                                                 std::vector<float> &floatBuffer, float volume)
135 {
136     uint32_t convertValue = samplePerFrame * BYTES_ALIGNMENT_SIZE - 1;
137     for (uint32_t i = 0; i < floatBuffer.size(); i++) {
138         int32_t sampleValue = 0;
139         if (samplePerFrame == AUDIO_24BIT_LENGTH) {
140             sampleValue = ((buffer[i * samplePerFrame + AUDIO_NUMBER_2] & 0xff) << AUDIO_SAMPLE_24BIT_LENGTH) |
141                           ((buffer[i * samplePerFrame + 1] & 0xff) << AUDIO_SAMPLE_16BIT_LENGTH) |
142                           ((buffer[i * samplePerFrame] & 0xff) << BYTES_ALIGNMENT_SIZE);
143             floatBuffer[i] = sampleValue * volume * (1.0f / AUDIO_SAMPLE_32BIT_VALUE);
144             continue;
145         }
146         for (uint32_t j = 0; j < samplePerFrame; j++) {
147             sampleValue |= (buffer[i * samplePerFrame + j] & 0xff) << (j * BYTES_ALIGNMENT_SIZE);
148         }
149         floatBuffer[i] = sampleValue * volume * (1.0f / (1U << convertValue));
150     }
151 }
152 
ConvertFloatToAudioBuffer(const std::vector<float> & floatBuffer,uint8_t * buffer,uint32_t samplePerFrame)153 void AudioCommonConverter::ConvertFloatToAudioBuffer(const std::vector<float> &floatBuffer, uint8_t *buffer,
154                                                      uint32_t samplePerFrame)
155 {
156     uint32_t convertValue = samplePerFrame * BYTES_ALIGNMENT_SIZE - 1;
157     for (uint32_t i = 0; i < floatBuffer.size(); i++) {
158         int32_t sampleValue = static_cast<int32_t>(floatBuffer[i] * std::pow(AUDIO_NUMBER_2, convertValue));
159         for (uint32_t j = 0; j < samplePerFrame; j++) {
160             uint8_t tempValue = (sampleValue >> (BYTES_ALIGNMENT_SIZE * j)) & 0xff;
161             buffer[samplePerFrame * i + j] = tempValue;
162         }
163     }
164 }
165 } // namespace AudioStandard
166 } // namespace OHOS
167