• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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