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 #ifndef LOG_TAG
16 #define LOG_TAG "InnerCapTest"
17 #endif
18
19 #include <chrono>
20 #include <cstdio>
21 #include <cstdlib>
22 #include <cinttypes>
23 #include <unistd.h>
24 #include <thread>
25 #include <random>
26 #include <iostream>
27 #include "securec.h"
28 #include <map>
29
30 #include "audio_capturer_log.h"
31 #include "audio_capturer.h"
32
33 using namespace std;
34 namespace OHOS {
35 namespace AudioStandard {
36 enum CapturerMode : int32_t {
37 DIRECTLY_READ = 0,
38 READ_AFTER_CALLBACK = 1,
39 };
40
41 enum OperationCode : int32_t {
42 CODE_INVALID = -1,
43 CAPTURER_CODE_INIT = 0,
44 CAPTURER_CODE_START = 1,
45 CAPTURER_CODE_PAUSE = 2,
46 CAPTURER_CODE_FLUSH = 3,
47 CAPTURER_CODE_STOP = 4,
48 CAPTURER_CODE_RELEASE = 5,
49 EXIT_DEMO = 1000,
50 CAPTURER_CODE_MAX
51 };
52
53 class PaCapturerTest : public AudioCapturerReadCallback, public enable_shared_from_this<PaCapturerTest> {
54 public:
~PaCapturerTest()55 virtual ~PaCapturerTest() {};
56
57 int32_t InitCapturer(CapturerMode capturerMode);
58 int32_t StartRecorder();
59 int32_t PauseRecorder();
60 int32_t FlushRecorder();
61 int32_t StopRecorder();
62 int32_t ReleaseRecorder();
63 void OnReadData(size_t length) override;
64
65 private:
66 std::unique_ptr<AudioCapturer> audioCapturer_ = nullptr;
67 std::condition_variable enableReadCv_;
68 bool enableRead_ = false;
69 FILE *pfd_ = nullptr;
70 CapturerMode capturerMode_ = READ_AFTER_CALLBACK;
71 };
72
OnReadData(size_t length)73 void PaCapturerTest::OnReadData(size_t length)
74 {
75 int32_t ret = -1;
76 AUDIO_INFO_LOG("PaCapturerTest::OnReadData, length: %{public}zu", length);
77 BufferDesc bufferDesc = { nullptr, 0, 0 };
78 audioCapturer_->GetBufferDesc(bufferDesc);
79
80 ret = fwrite(reinterpret_cast<void *>(bufferDesc.buffer), 1, bufferDesc.bufLength, pfd_);
81 if (ret != 0) { AUDIO_ERR_LOG(" something wrong when writing pcm! "); }
82
83 audioCapturer_->Enqueue(bufferDesc);
84 }
85
InitCapturer(CapturerMode capturerMode)86 int32_t PaCapturerTest::InitCapturer(CapturerMode capturerMode)
87 {
88 AUDIO_INFO_LOG("Start InitCapturer");
89 capturerMode_ = capturerMode;
90 AudioCapturerOptions capturerOptions;
91 capturerOptions.streamInfo.samplingRate = SAMPLE_RATE_48000;
92 capturerOptions.streamInfo.encoding = AudioEncodingType::ENCODING_PCM;
93 capturerOptions.streamInfo.format = AudioSampleFormat::SAMPLE_S16LE;
94 capturerOptions.streamInfo.channels = AudioChannel::STEREO;
95 capturerOptions.capturerInfo.sourceType = SourceType::SOURCE_TYPE_PLAYBACK_CAPTURE;
96 capturerOptions.capturerInfo.capturerFlags = 0;
97
98 audioCapturer_ = AudioCapturer::Create(capturerOptions);
99 if (audioCapturer_ == nullptr) {
100 AUDIO_ERR_LOG("Create audioCapturer failed");
101 return -1;
102 }
103 if (capturerMode_ == READ_AFTER_CALLBACK) {
104 if (audioCapturer_->SetCaptureMode(CAPTURE_MODE_CALLBACK)) {
105 AUDIO_ERR_LOG("SetCaptureMode failed");
106 return -1;
107 }
108 if (audioCapturer_->SetCapturerReadCallback(shared_from_this())) {
109 AUDIO_ERR_LOG("SetCapturerReadCallback failed");
110 return -1;
111 }
112 }
113 AUDIO_INFO_LOG("Audio capturer create success.");
114 pfd_ = fopen("/data/data/.pulse_dir/capturer.pcm", "wb+");
115 return 0;
116 }
117
StartRecorder()118 int32_t PaCapturerTest::StartRecorder()
119 {
120 AUDIO_INFO_LOG("StartRecorder");
121 if (audioCapturer_ == nullptr) {
122 AUDIO_ERR_LOG("audioCapturer_ init failed.");
123 return -1;
124 }
125 enableRead_ = true;
126 enableReadCv_.notify_all();
127 if (!audioCapturer_->Start()) {
128 AUDIO_ERR_LOG("Audio capturer start failed.");
129 return -1;
130 }
131 return 0;
132 }
133
PauseRecorder()134 int32_t PaCapturerTest::PauseRecorder()
135 {
136 if (audioCapturer_ == nullptr) {
137 AUDIO_ERR_LOG("audioCapturer_ init failed.");
138 return -1;
139 }
140 enableRead_ = false;
141 if (!audioCapturer_->Pause()) {
142 AUDIO_ERR_LOG("Audio capturer start failed.");
143 return -1;
144 }
145 return 0;
146 }
147
FlushRecorder()148 int32_t PaCapturerTest::FlushRecorder()
149 {
150 if (audioCapturer_ == nullptr) {
151 AUDIO_ERR_LOG("audioCapturer_ init failed.");
152 return -1;
153 }
154 if (!audioCapturer_->Flush()) {
155 AUDIO_ERR_LOG("Audio capturer start failed.");
156 return -1;
157 }
158 return 0;
159 }
160
StopRecorder()161 int32_t PaCapturerTest::StopRecorder()
162 {
163 if (audioCapturer_ == nullptr) {
164 AUDIO_ERR_LOG("audioCapturer_ init failed.");
165 return -1;
166 }
167 if (!audioCapturer_->Stop()) {
168 AUDIO_ERR_LOG("Audio capturer stop failed.");
169 return -1;
170 }
171 return 0;
172 }
173
ReleaseRecorder()174 int32_t PaCapturerTest::ReleaseRecorder()
175 {
176 int32_t ret = -1;
177 if (audioCapturer_ == nullptr) {
178 AUDIO_ERR_LOG("audioCapturer_ init failed.");
179 return -1;
180 }
181 enableRead_ = false;
182 if (!audioCapturer_->Release()) {
183 AUDIO_ERR_LOG("Audio capturer stop failed.");
184 return -1;
185 }
186 audioCapturer_ = nullptr;
187 ret = fclose(pfd_);
188 if (ret != 0) { AUDIO_ERR_LOG(" something wrong when fclose! "); }
189 pfd_ = nullptr;
190 return 0;
191 }
192
GetUserInput()193 int32_t GetUserInput()
194 {
195 int32_t res = -1; // result
196 size_t count = 3; // try three time
197 int32_t ret = -1;
198 cout << ">> >> >>";
199
200 ret = scanf_s("%d", &res);
201 if (ret != 0) { AUDIO_ERR_LOG(" something wrong when scanf_s! "); }
202 while (res < 0 && count-- > 0) {
203 cout << "invalid input, not a number! Please retry with a number." << endl;
204 cout << ">> >> >>";
205 ret = scanf_s("%d", &res);
206 if (ret != 0) { AUDIO_ERR_LOG(" something wrong when scanf_s! "); }
207 }
208
209 return res;
210 }
211
PrintUsage()212 void PrintUsage()
213 {
214 cout << "[inner capturer Test App]" << endl << endl;
215 cout << "Supported Functionalities:" << endl;
216 cout << "================================Usage=======================================" << endl << endl;
217 cout << " 0: Init Capturer." << endl;
218 cout << " 1: Start read." << endl;
219 cout << " 2: Pause read." << endl;
220 cout << " 3: Flush read." << endl;
221 cout << " 4: Stop read." << endl;
222 cout << " 5: Release read." << endl;
223
224 cout << " 1000: exit demo." << endl;
225 cout << " Please input your choice: " << endl;
226 cout << "================================Usage=======================================" << endl << endl;
227 }
228
InitRecorder(std::shared_ptr<PaCapturerTest> capturerTest,CapturerMode capturerMode)229 int32_t InitRecorder(std::shared_ptr<PaCapturerTest> capturerTest, CapturerMode capturerMode)
230 {
231 if (capturerTest == nullptr) {
232 cout << "PaCapturerTest obj is nullptr, init recorder error." << endl;
233 return -1;
234 }
235 int32_t ret = capturerTest->InitCapturer(capturerMode);
236 if (ret != 0) {
237 cout << "Init capturer error!" << endl;
238 return -1;
239 }
240 return 0;
241 }
242
StartRecorder(std::shared_ptr<PaCapturerTest> capturerTest)243 int32_t StartRecorder(std::shared_ptr<PaCapturerTest> capturerTest)
244 {
245 if (capturerTest == nullptr) {
246 cout << "PaCapturerTest obj is nullptr, start recorder error." << endl;
247 return -1;
248 }
249 int32_t ret = capturerTest->StartRecorder();
250 if (ret != 0) {
251 cout << "Start recorder error!" << endl;
252 return -1;
253 }
254 return 0;
255 }
256
PauseRecorder(std::shared_ptr<PaCapturerTest> capturerTest)257 int32_t PauseRecorder(std::shared_ptr<PaCapturerTest> capturerTest)
258 {
259 if (capturerTest == nullptr) {
260 cout << "PaCapturerTest obj is nullptr, pause recorder error." << endl;
261 return -1;
262 }
263 int32_t ret = capturerTest->PauseRecorder();
264 if (ret != 0) {
265 cout << "Pause recorder error!" << endl;
266 return -1;
267 }
268 return 0;
269 }
270
FlushRecorder(std::shared_ptr<PaCapturerTest> capturerTest)271 int32_t FlushRecorder(std::shared_ptr<PaCapturerTest> capturerTest)
272 {
273 if (capturerTest == nullptr) {
274 cout << "PaCapturerTest obj is nullptr, Flush recorder error." << endl;
275 return -1;
276 }
277 int32_t ret = capturerTest->FlushRecorder();
278 if (ret != 0) {
279 cout << "Flush recorder error!" << endl;
280 return -1;
281 }
282 return 0;
283 }
284
StopRecorder(std::shared_ptr<PaCapturerTest> capturerTest)285 int32_t StopRecorder(std::shared_ptr<PaCapturerTest> capturerTest)
286 {
287 if (capturerTest == nullptr) {
288 cout << "PaCapturerTest obj is nullptr, stop recorder error." << endl;
289 return -1;
290 }
291 int32_t ret = capturerTest->StopRecorder();
292 if (ret != 0) {
293 cout << "Stop recorder error!" << endl;
294 return -1;
295 }
296 return 0;
297 }
298
ReleaseRecorder(std::shared_ptr<PaCapturerTest> capturerTest)299 int32_t ReleaseRecorder(std::shared_ptr<PaCapturerTest> capturerTest)
300 {
301 if (capturerTest == nullptr) {
302 cout << "PaCapturerTest obj is nullptr, stop recorder error." << endl;
303 return -1;
304 }
305 int32_t ret = capturerTest->ReleaseRecorder();
306 if (ret != 0) {
307 cout << "Stop recorder error!" << endl;
308 return -1;
309 }
310 return 0;
311 }
312
HandleCapturerCode(OperationCode optCode,std::shared_ptr<PaCapturerTest> capturerTest)313 void HandleCapturerCode(OperationCode optCode, std::shared_ptr<PaCapturerTest> capturerTest)
314 {
315 switch (optCode) {
316 case CAPTURER_CODE_START:
317 StartRecorder(capturerTest);
318 break;
319 case CAPTURER_CODE_PAUSE:
320 PauseRecorder(capturerTest);
321 break;
322 case CAPTURER_CODE_FLUSH:
323 FlushRecorder(capturerTest);
324 break;
325 case CAPTURER_CODE_STOP:
326 StopRecorder(capturerTest);
327 break;
328 case CAPTURER_CODE_RELEASE:
329 ReleaseRecorder(capturerTest);
330 break;
331 default:
332 cout << "Invalid input: " << optCode << endl;
333 break;
334 }
335 }
336
Loop(std::shared_ptr<PaCapturerTest> capturerTest)337 void Loop(std::shared_ptr<PaCapturerTest> capturerTest)
338 {
339 bool isProcTestRun = true;
340 while (isProcTestRun) {
341 PrintUsage();
342 OperationCode optCode = CODE_INVALID;
343 int32_t res = GetUserInput();
344 int32_t capturerMode = 1; // default callback
345
346 if (res < 0 && res >= OperationCode::CAPTURER_CODE_MAX) {
347 cout << "OperationCode is INVALID!" << endl;
348 return;
349 }
350 optCode = static_cast<OperationCode>(res);
351 switch (optCode) {
352 // Capturer
353 case CAPTURER_CODE_INIT:
354 cout << " ==== Recorder has been inited, use callback mode ==== " << endl;
355 InitRecorder(capturerTest, static_cast<CapturerMode>(capturerMode));
356 break;
357 case EXIT_DEMO:
358 isProcTestRun = false;
359 break;
360 default:
361 HandleCapturerCode(optCode, capturerTest);
362 break;
363 }
364 }
365 }
366 }
367 }
368
369 using namespace OHOS::AudioStandard;
370 using namespace std;
main(int argc,char * argv[])371 int main(int argc, char* argv[])
372 {
373 cout << "oh inner capturer test." << endl;
374 std::shared_ptr<PaCapturerTest> capturerTest = std::make_shared<PaCapturerTest>();
375 Loop(capturerTest);
376 return 0;
377 }
378