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
16 #include <iostream>
17 #include <cstddef>
18 #include <cstdint>
19 #include <cstring>
20 #include "audio_utils.h"
21 #include <algorithm>
22 #include <cinttypes>
23 #include "audio_proresampler_process.h"
24 #include "audio_engine_log.h"
25 #include "audio_proresampler.h"
26 #include "audio_stream_info.h"
27 namespace OHOS {
28 namespace AudioStandard {
29 using namespace std;
30 using namespace HPAE;
31 static const uint8_t* RAW_DATA = nullptr;
32 static size_t g_dataSize = 0;
33 static size_t g_pos;
34 const size_t THRESHOLD = 10;
35 const size_t NUM_TWO = 2;
36 const size_t NUM_SEVEN = 7;
37 const static std::vector<uint32_t> TEST_CHANNELS = {MONO, STEREO, CHANNEL_6};
38
39 const static std::map<uint32_t, uint32_t> TEST_SAMPLE_RATE_COMBINATION = { // {input, output} combination
40 {SAMPLE_RATE_24000, SAMPLE_RATE_48000},
41 {SAMPLE_RATE_16000, SAMPLE_RATE_48000},
42 {SAMPLE_RATE_44100, SAMPLE_RATE_192000},
43 {SAMPLE_RATE_48000, SAMPLE_RATE_24000},
44 {SAMPLE_RATE_48000, SAMPLE_RATE_16000},
45 {SAMPLE_RATE_192000, SAMPLE_RATE_44100},
46 };
47
48 constexpr uint32_t INVALID_QUALITY = -1;
49 constexpr uint32_t QUALITY_ONE = 1;
50 constexpr uint32_t FRAME_LEN_20MS = 20;
51 constexpr uint32_t FRAME_LEN_40MS = 40;
52 constexpr uint32_t MS_PER_SECOND = 1000;
53 template<class T>
GetData()54 T GetData()
55 {
56 T object {};
57 size_t objectSize = sizeof(object);
58 if (RAW_DATA == nullptr || objectSize > g_dataSize - g_pos) {
59 return object;
60 }
61 errno_t ret = memcpy_s(&object, objectSize, RAW_DATA + g_pos, objectSize);
62 if (ret != EOK) {
63 return {};
64 }
65 g_pos += objectSize;
66 return object;
67 }
68
69 template<class T>
GetArrLength(T & arr)70 uint32_t GetArrLength(T& arr)
71 {
72 if (arr == nullptr) {
73 AUDIO_INFO_LOG("%{public}s: The array length is equal to 0", __func__);
74 return 0;
75 }
76 return sizeof(arr) / sizeof(arr[0]);
77 }
78
SingleStagePolyphaseResamplerSetRate1()79 void SingleStagePolyphaseResamplerSetRate1()
80 {
81 SingleStagePolyphaseResamplerState state;
82 uint32_t decimateFactor = 0;
83 uint32_t interpolateFactor = 0;
84 SingleStagePolyphaseResamplerSetRate(&state, decimateFactor, interpolateFactor);
85 }
86
SingleStagePolyphaseResamplerSetRate2()87 void SingleStagePolyphaseResamplerSetRate2()
88 {
89 SingleStagePolyphaseResamplerState state;
90 uint32_t decimateFactor = 0;
91 uint32_t interpolateFactor = 2;
92 SingleStagePolyphaseResamplerSetRate(&state, decimateFactor, interpolateFactor);
93 }
94
SingleStagePolyphaseResamplerSetRate3()95 void SingleStagePolyphaseResamplerSetRate3()
96 {
97 SingleStagePolyphaseResamplerState state;
98 uint32_t decimateFactor = 2;
99 uint32_t interpolateFactor = 0;
100 SingleStagePolyphaseResamplerSetRate(&state, decimateFactor, interpolateFactor);
101 }
102
SingleStagePolyphaseResamplerSetRate4()103 void SingleStagePolyphaseResamplerSetRate4()
104 {
105 SingleStagePolyphaseResamplerState state;
106 uint32_t decimateFactor = GetData<uint32_t>();
107 uint32_t interpolateFactor = GetData<uint32_t>();
108 SingleStagePolyphaseResamplerSetRate(&state, decimateFactor, interpolateFactor);
109 }
110
InitTest()111 void InitTest()
112 {
113 // test invalid input
114 int32_t err = RESAMPLER_ERR_SUCCESS;
115 SingleStagePolyphaseResamplerInit(STEREO, SAMPLE_RATE_24000, SAMPLE_RATE_48000, INVALID_QUALITY, &err);
116
117 // test valid input
118 SingleStagePolyphaseResamplerInit(STEREO, SAMPLE_RATE_24000, SAMPLE_RATE_48000, QUALITY_ONE, &err);
119
120 // test 11025 input
121 ProResampler resampler1(SAMPLE_RATE_11025, SAMPLE_RATE_48000, STEREO, QUALITY_ONE);
122
123 // test other input
124 ProResampler resampler2(SAMPLE_RATE_48000, SAMPLE_RATE_44100, STEREO, QUALITY_ONE);
125 }
126
ProcessTest()127 void ProcessTest()
128 {
129 for (uint32_t channels: TEST_CHANNELS) {
130 for (auto pair: TEST_SAMPLE_RATE_COMBINATION) {
131 uint32_t inRate = pair.first;
132 uint32_t outRate = pair.second;
133 uint32_t inFrameLen = inRate * FRAME_LEN_20MS / MS_PER_SECOND;
134 uint32_t outFrameLen = outRate * FRAME_LEN_20MS / MS_PER_SECOND;
135 ProResampler resampler(inRate, outRate, channels, QUALITY_ONE);
136 std::vector<float> in(inFrameLen * channels);
137 std::vector<float> out(outFrameLen * channels);
138 resampler.Process(in.data(), inFrameLen, out.data(), outFrameLen);
139 }
140 }
141
142 ProResampler resampler(SAMPLE_RATE_11025, SAMPLE_RATE_48000, STEREO, QUALITY_ONE);
143 uint32_t inFrameLen = SAMPLE_RATE_11025 * FRAME_LEN_40MS / MS_PER_SECOND;
144 uint32_t outFrameLen = SAMPLE_RATE_48000 * FRAME_LEN_20MS / MS_PER_SECOND;
145 std::vector<float> in(inFrameLen * STEREO);
146 std::vector<float> out(outFrameLen * STEREO);
147 resampler.Process(in.data(), inFrameLen, out.data(), outFrameLen);
148
149 inFrameLen = 0;
150 resampler.Process(in.data(), inFrameLen, out.data(), outFrameLen);
151 resampler.Process(in.data(), inFrameLen, out.data(), outFrameLen);
152 }
153
UpdateRatesTest1()154 void UpdateRatesTest1()
155 {
156 ProResampler resampler(SAMPLE_RATE_48000, SAMPLE_RATE_96000, STEREO, QUALITY_ONE);
157 resampler.UpdateRates(SAMPLE_RATE_11025, SAMPLE_RATE_48000);
158 }
159
UpdateRatesTest2()160 void UpdateRatesTest2()
161 {
162 ProResampler resampler(SAMPLE_RATE_48000, SAMPLE_RATE_96000, STEREO, QUALITY_ONE);
163 resampler.UpdateRates(NUM_TWO, SAMPLE_RATE_48000);
164 }
165
UpdateChannel()166 void UpdateChannel()
167 {
168 ProResampler resampler(SAMPLE_RATE_48000, SAMPLE_RATE_96000, STEREO, QUALITY_ONE);
169
170 resampler.UpdateChannels(CHANNEL_6);
171 }
172
ErrCodeToString()173 void ErrCodeToString()
174 {
175 ProResampler resampler(SAMPLE_RATE_48000, SAMPLE_RATE_96000, STEREO, QUALITY_ONE);
176 resampler.ErrCodeToString(RESAMPLER_ERR_SUCCESS);
177 resampler.ErrCodeToString(RESAMPLER_ERR_ALLOC_FAILED);
178 resampler.ErrCodeToString(RESAMPLER_ERR_OVERFLOW);
179 resampler.ErrCodeToString(NUM_SEVEN);
180 resampler.ErrCodeToString(RESAMPLER_ERR_INVALID_ARG);
181 resampler.ErrCodeToString(GetData<int32_t>());
182 }
183
184 typedef void (*TestFuncs)();
185 TestFuncs g_testFuncs[] = {
186 SingleStagePolyphaseResamplerSetRate1,
187 SingleStagePolyphaseResamplerSetRate2,
188 SingleStagePolyphaseResamplerSetRate3,
189 SingleStagePolyphaseResamplerSetRate4,
190 InitTest,
191 ProcessTest,
192 UpdateRatesTest1,
193 UpdateRatesTest2,
194 UpdateChannel,
195 ErrCodeToString,
196 };
197
FuzzTest(const uint8_t * rawData,size_t size)198 bool FuzzTest(const uint8_t* rawData, size_t size)
199 {
200 if (rawData == nullptr) {
201 return false;
202 }
203
204 // initialize data
205 RAW_DATA = rawData;
206 g_dataSize = size;
207 g_pos = 0;
208
209 uint32_t code = GetData<uint32_t>();
210 uint32_t len = GetArrLength(g_testFuncs);
211 if (len > 0) {
212 g_testFuncs[code % len]();
213 } else {
214 AUDIO_INFO_LOG("%{public}s: The len length is equal to 0", __func__);
215 }
216
217 return true;
218 }
219 } // namespace AudioStandard
220 } // namesapce OHOS
221
222 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)223 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
224 {
225 if (size < OHOS::AudioStandard::THRESHOLD) {
226 return 0;
227 }
228
229 OHOS::AudioStandard::FuzzTest(data, size);
230 return 0;
231 }
232