1 /*
2 * Copyright (c) 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 #include "securec.h"
16 #include "hpae_format_convert.h"
17
18
19 namespace OHOS {
20 namespace AudioStandard {
21 namespace HPAE {
22 constexpr float FLOAT_EPS = 1e-6f;
23 constexpr int OFFSET_BIT_24 = 3;
24 constexpr int BIT_DEPTH_TWO = 2;
25 constexpr int BIT_8 = 8;
26 constexpr int BIT_16 = 16;
27 constexpr int BIT_32 = 32;
28
Read24Bit(const uint8_t * p)29 static uint32_t Read24Bit(const uint8_t *p)
30 {
31 return ((uint32_t) p[BIT_DEPTH_TWO] << BIT_16) | ((uint32_t) p[1] << BIT_8) | ((uint32_t) p[0]);
32 }
33
Write24Bit(uint8_t * p,uint32_t u)34 static void Write24Bit(uint8_t *p, uint32_t u)
35 {
36 p[BIT_DEPTH_TWO] = (uint8_t) (u >> BIT_16);
37 p[1] = (uint8_t) (u >> BIT_8);
38 p[0] = (uint8_t) u;
39 }
40
ConvertFromU8ToFloat(unsigned n,const uint8_t * a,float * b)41 static void ConvertFromU8ToFloat(unsigned n, const uint8_t *a, float *b)
42 {
43 for (; n > 0; n--, a++, b++) {
44 *b = (float)(*a - (uint8_t)0x80U) * (1.0 / 0x80U);
45 }
46 }
47
ConvertFrom16BitToFloat(unsigned n,const int16_t * a,float * b)48 static void ConvertFrom16BitToFloat(unsigned n, const int16_t *a, float *b)
49 {
50 for (; n > 0; n--) {
51 *(b++) = *(a++) * (1.0f / (1 << (BIT_16 - 1)));
52 }
53 }
54
ConvertFrom24BitToFloat(unsigned n,const uint8_t * a,float * b)55 static void ConvertFrom24BitToFloat(unsigned n, const uint8_t *a, float *b)
56 {
57 for (; n > 0; n--) {
58 int32_t s = Read24Bit(a) << BIT_8;
59 *b = s * (1.0f / (1U << (BIT_32 - 1)));
60 a += OFFSET_BIT_24;
61 b++;
62 }
63 }
64
ConvertFrom32BitToFloat(unsigned n,const int32_t * a,float * b)65 static void ConvertFrom32BitToFloat(unsigned n, const int32_t *a, float *b)
66 {
67 for (; n > 0; n--) {
68 *(b++) = *(a++) * (1.0f / (1U << (BIT_32 - 1)));
69 }
70 }
71
CapMax(float v)72 static float CapMax(float v)
73 {
74 float value = v;
75 if (v > 1.0f) {
76 value = 1.0f - FLOAT_EPS;
77 } else if (v < -1.0f) {
78 value = -1.0f + FLOAT_EPS;
79 }
80 return value;
81 }
82
ConvertFromFloatToU8(unsigned n,const float * a,uint8_t * b)83 static void ConvertFromFloatToU8(unsigned n, const float *a, uint8_t *b)
84 {
85 for (; n > 0; n--) {
86 float v = *(a++);
87 *(b++) = (uint8_t)(CapMax(v) * 127.0f + 128.0f);
88 }
89 }
90
ConvertFromFloatTo16Bit(unsigned n,const float * a,int16_t * b)91 static void ConvertFromFloatTo16Bit(unsigned n, const float *a, int16_t *b)
92 {
93 for (; n > 0; n--) {
94 float tmp = *a++;
95 float v = CapMax(tmp) * (1 << (BIT_16 - 1));
96 *(b++) = (int16_t) v;
97 }
98 }
99
ConvertFromFloatTo24Bit(unsigned n,const float * a,uint8_t * b)100 static void ConvertFromFloatTo24Bit(unsigned n, const float *a, uint8_t *b)
101 {
102 for (; n > 0; n--) {
103 float tmp = *a++;
104 float v = CapMax(tmp) * (1U << (BIT_32 - 1));
105 Write24Bit(b, ((int32_t) v) >> BIT_8);
106 b += OFFSET_BIT_24;
107 }
108 }
109
ConvertFromFloatTo32Bit(unsigned n,const float * a,int32_t * b)110 static void ConvertFromFloatTo32Bit(unsigned n, const float *a, int32_t *b)
111 {
112 for (; n > 0; n--) {
113 float tmp = *a++;
114 float v = CapMax(tmp) * (1U << (BIT_32 - 1));
115 *(b++) = (int32_t) v;
116 }
117 }
118
ConvertToFloat(AudioSampleFormat format,unsigned n,void * src,float * dst)119 void ConvertToFloat(AudioSampleFormat format, unsigned n, void *src, float *dst)
120 {
121 int32_t ret;
122 switch (format) {
123 case SAMPLE_U8:
124 ConvertFromU8ToFloat(n, (const uint8_t *)src, dst);
125 break;
126 case SAMPLE_S16LE:
127 ConvertFrom16BitToFloat(n, (const int16_t *)src, dst);
128 break;
129 case SAMPLE_S24LE:
130 ConvertFrom24BitToFloat(n, (const uint8_t *)src, dst);
131 break;
132 case SAMPLE_S32LE:
133 ConvertFrom32BitToFloat(n, (const int32_t *)src, dst);
134 break;
135 default:
136 ret = memcpy_s(dst, n * sizeof(float), (const float *)src, n * sizeof(float));
137 if (ret != 0) {
138 float *srcFloat = (float *)src;
139 for (uint32_t i = 0; i < n; i++) {
140 dst[i] = srcFloat[i];
141 }
142 }
143 break;
144 }
145 }
146
ConvertFromFloat(AudioSampleFormat format,unsigned n,float * src,void * dst)147 void ConvertFromFloat(AudioSampleFormat format, unsigned n, float *src, void *dst)
148 {
149 int32_t ret;
150 switch (format) {
151 case SAMPLE_U8:
152 ConvertFromFloatToU8(n, src, (uint8_t *)dst);
153 break;
154 case SAMPLE_S16LE:
155 ConvertFromFloatTo16Bit(n, src, (int16_t *)dst);
156 break;
157 case SAMPLE_S24LE:
158 ConvertFromFloatTo24Bit(n, src, (uint8_t *)dst);
159 break;
160 case SAMPLE_S32LE:
161 ConvertFromFloatTo32Bit(n, src, (int32_t *)dst);
162 break;
163 default:
164 ret = memcpy_s(dst, n * sizeof(float), src, n * sizeof(float));
165 if (ret != 0) {
166 float *dstFloat = (float *)dst;
167 for (uint32_t i = 0; i < n; i++) {
168 dstFloat[i] = src[i];
169 }
170 }
171 break;
172 }
173 }
174 }}}