1 /*
2 * Copyright (c) 2023 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 <cstdio>
17 #include <cstring>
18 #include <cstdlib>
19 #include <unistd.h>
20 #include <cerrno>
21 #include <fcntl.h>
22 #include <csignal>
23 #include <sys/stat.h>
24
25 #include <iostream>
26 #include <string>
27
28 #include <securec.h>
29 #include "unistd.h"
30 #include "distributedaudiotest.h"
31 #include "daudio_errorcode.h"
32 #include "daudio_log.h"
33
34 using OHOS::HDI::DistributedAudio::Audio::V1_0::IAudioAdapter;
35 using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioAdapterDescriptor;
36 using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioFormat;
37 using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioPort;
38 using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioPortDirection;
39 using OHOS::HDI::DistributedAudio::Audio::V1_0::IAudioManager;
40 using OHOS::HDI::DistributedAudio::Audio::V1_0::IAudioRender;
41 using OHOS::HDI::DistributedAudio::Audio::V1_0::IAudioCapture;
42 using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioSampleAttributes;
43 using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioDeviceDescriptor;
44 using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioCategory;
45 using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioRouteNode;
46 using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioExtParamKey;
47 using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioRoute;
48 using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioSceneDescriptor;
49 using OHOS::HDI::DistributedAudio::Audio::V1_0::IAudioCallback;
50 using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioPortPin;
51 using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioPortType;
52 using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioPortRole;
53 using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioCallbackType;
54
55 namespace {
56 using namespace OHOS::DistributedHardware;
57 static int32_t ParamEventCallback(AudioExtParamKey key, const char *condition, const char *value, void *reserved,
58 void *cookie);
59
60 class AudioParamCallbackImpl final : public IAudioCallback {
61 public:
AudioParamCallbackImpl()62 AudioParamCallbackImpl() {}
~AudioParamCallbackImpl()63 ~AudioParamCallbackImpl() override {}
64
65 int32_t RenderCallback(AudioCallbackType type, int8_t &reserved, int8_t &cookie) override;
66 int32_t ParamCallback(AudioExtParamKey key, const std::string &condition, const std::string &value,
67 int8_t &reserved, int8_t cookie) override;
68 };
69
RenderCallback(AudioCallbackType type,int8_t & reserved,int8_t & cookie)70 int32_t AudioParamCallbackImpl::RenderCallback(AudioCallbackType type, int8_t &reserved, int8_t &cookie)
71 {
72 (void) type;
73 (void) reserved;
74 (void) cookie;
75 return DH_SUCCESS;
76 }
77
ParamCallback(AudioExtParamKey key,const std::string & condition,const std::string & value,int8_t & reserved,int8_t cookie)78 int32_t AudioParamCallbackImpl::ParamCallback(AudioExtParamKey key, const std::string &condition,
79 const std::string &value, int8_t &reserved, int8_t cookie)
80 {
81 (void) cookie;
82 void *cookies = nullptr;
83 ParamEventCallback(static_cast<::AudioExtParamKey>(key), condition.c_str(),
84 value.c_str(), static_cast<void *>(&reserved), cookies);
85 return DH_SUCCESS;
86 }
87
88 const int32_t CMD_QUIT = 0;
89 const int32_t CMD_FIND = 9;
90 const int32_t CMD_OPEN_SPK = 1;
91 const int32_t CMD_CLOSE_SPK = 2;
92 const int32_t CMD_START_SPK = 3;
93 const int32_t CMD_STOP_SPK = 4;
94 const int32_t CMD_OPEN_MIC = 5;
95 const int32_t CMD_CLOSE_MIC = 6;
96 const int32_t CMD_START_MIC = 7;
97 const int32_t CMD_STOP_MIC = 8;
98 const int32_t CMD_SET_VOL = 11;
99 const int32_t CMD_GET_VOL = 12;
100
101 const char DEV_TYPE_SPK = '1';
102 const char DEV_TYPE_MIC = '2';
103 const char SPK_FILE_PATH[128] = "/data/test.wav";
104 const char MIC_FILE_PATH[128] = "/data/mic.pcm";
105 constexpr int32_t TYPE_OFFSET = 12;
106 constexpr int32_t AUDIO_SAMPLE_RATE = 48000;
107 constexpr int32_t VOLUME_MIN = 0;
108 constexpr int32_t VOLUME_MAX = 15;
109 constexpr int32_t RENDER_FRAME_SIZE = 3840;
110 constexpr int32_t RENDER_INTER_LEAVED = 1;
111 constexpr int32_t RENDER_STREAM_ID = 0;
112 constexpr int32_t RENDER_CHANNEL_MASK = 2;
113 constexpr int32_t CAPTURE_INTER_LEAVED = 1;
114 constexpr int32_t CAPTURE_STREAM_ID = 2;
115 constexpr int32_t CAPTURE_CHANNEL_MASK = 2;
116 constexpr int64_t AUDIO_FRAME_TIME_INTERFAL_DEFAULT = 21333;
117
118 static OHOS::sptr<IAudioManager> g_manager = nullptr;
119 static OHOS::sptr<IAudioAdapter> g_adapter = nullptr;
120 static OHOS::sptr<IAudioRender> g_render = nullptr;
121 static OHOS::sptr<IAudioCapture> g_capture = nullptr;
122 static std::vector<AudioAdapterDescriptor> g_devices;
123 static OHOS::sptr<IAudioCallback> g_callbackStub = nullptr;
124 static std::string g_devId = "";
125
126 static constexpr const char* PLAY_THREAD = "playThread";
127 static constexpr const char* CAPTURE_THREAD = "captureThread";
128
129 uint32_t g_renderId = 0;
130 uint32_t g_captureId = 0;
131 int32_t g_frameNum = 0;
132 int32_t g_frameIndex = 0;
133 int32_t g_micFrameNum = 0;
134 bool g_isInitRenderData = false;
135 static std::vector<uint8_t*> renderData;
136
137 static DeviceStatus g_spkStatus = DeviceStatus::DEVICE_IDLE;
138 static DeviceStatus g_micStatus = DeviceStatus::DEVICE_IDLE;
139
140 static std::thread g_playingThread;
141 static std::thread g_capingThread;
142 FILE *g_micFile = nullptr;
143
144 static void CloseSpk();
145 static void CloseMic();
146
GetNowTimeUs()147 static int64_t GetNowTimeUs()
148 {
149 std::chrono::microseconds nowUs =
150 std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch());
151 return nowUs.count();
152 }
153
GetUserInput()154 static int32_t GetUserInput()
155 {
156 int32_t res = -1;
157 size_t count = 3;
158 std::cout << ">>";
159 int ret = scanf_s("%d", &res);
160 if (ret == -1) {
161 std::cout << "get input error" << std::endl;
162 }
163 while (std::cin.fail() && count > 0) {
164 std::cin.clear();
165 std::cin.ignore();
166 std::cout << "invalid input, not a number! Please retry with a number." << std::endl;
167 std::cout << ">>";
168 ret = scanf_s("%d", &res);
169 if (ret == -1) {
170 std::cout << "get input error" << std::endl;
171 }
172 count--;
173 }
174 return res;
175 }
176
FindAudioDevice()177 static void FindAudioDevice()
178 {
179 if (g_manager == nullptr) {
180 std::cout << "Audio manager is null, Please Check network!" << std::endl;
181 return;
182 }
183 int32_t ret = g_manager->GetAllAdapters(g_devices);
184 if (ret != DH_SUCCESS) {
185 std::cout << "Get audio devices failed!" << std::endl;
186 return;
187 }
188 for (uint32_t index = 0; index < g_devices.size(); index++) {
189 const AudioAdapterDescriptor desc = g_devices[index];
190 if (index == 0) {
191 g_devId = desc.adapterName;
192 break;
193 }
194 }
195 }
196
InitTestDemo()197 static int32_t InitTestDemo()
198 {
199 std::cout << "**********************************************************************************" << std::endl;
200 std::cout << "Distributed Audio Test Demo Bin v1.3." << std::endl;
201 std::cout << "**********************************************************************************" << std::endl;
202 std::cout << std::endl;
203 std::cout << "Init distributed audio hdf service." << std::endl;
204 g_manager = IAudioManager::Get("daudio_primary_service", false);
205 if (g_manager == nullptr) {
206 std::cout << "Distributed audio manager is null, Please Check network!" << std::endl;
207 return ERR_DH_AUDIO_FAILED;
208 }
209 std::cout << "Load audio manager success." << std::endl;
210 FindAudioDevice();
211 if (g_devId.empty()) {
212 std::cout << "Cannot find distributed device. Please input 9 to query distribtued device." << std::endl;
213 } else {
214 std::cout << "Find one distributed device: " << g_devId << std::endl;
215 }
216 return DH_SUCCESS;
217 }
218
HandleDevError(const char * condition,const char * value)219 static void HandleDevError(const char *condition, const char *value)
220 {
221 if (condition[TYPE_OFFSET] == DEV_TYPE_SPK && g_spkStatus != DeviceStatus::DEVICE_IDLE) {
222 CloseSpk();
223 }
224
225 if (condition[TYPE_OFFSET] == DEV_TYPE_MIC && g_micStatus == DeviceStatus::DEVICE_IDLE) {
226 CloseMic();
227 }
228
229 std::cout << "Receive abnormal event, Demo quit." << std::endl;
230 }
231
ParamEventCallback(AudioExtParamKey key,const char * condition,const char * value,void * reserved,void * cookie)232 static int32_t ParamEventCallback(AudioExtParamKey key, const char *condition, const char *value, void *reserved,
233 void *cookie)
234 {
235 std::string val(value);
236 std::string con(condition);
237 std::cout << std::endl;
238 std::cout << "**********************************************************************************" << std::endl;
239 std::cout << "Event recived: " << key << std::endl;
240 std::cout << "Condition: " << con << std::endl;
241 std::cout << "Value: " << val << std::endl;
242 std::cout << "**********************************************************************************" << std::endl;
243 std::cout << std::endl;
244
245 if (key == AudioExtParamKey::AUDIO_EXT_PARAM_KEY_STATUS && con.rfind("ERR_EVENT", 0) == 0) {
246 HandleDevError(condition, value);
247 }
248 return DH_SUCCESS;
249 }
250
LoadSpkDev(const std::string & devId)251 static int32_t LoadSpkDev(const std::string &devId)
252 {
253 struct AudioAdapterDescriptor dev;
254 for (uint32_t index = 0; index < g_devices.size(); index++) {
255 struct AudioAdapterDescriptor desc = g_devices[index];
256 if (desc.adapterName == devId) {
257 dev = desc;
258 break;
259 }
260 }
261 if (dev.adapterName.data() == nullptr) {
262 std::cout << "Input device id is wrong." << std::endl;
263 FindAudioDevice();
264 return ERR_DH_AUDIO_FAILED;
265 }
266 if (g_manager == nullptr) {
267 return ERR_DH_AUDIO_FAILED;
268 }
269 if (g_adapter == nullptr) {
270 int32_t ret = g_manager->LoadAdapter(dev, g_adapter);
271 if (ret != DH_SUCCESS || g_adapter == nullptr) {
272 std::cout << "Load audio device failed, ret: " << ret << std::endl;
273 return ERR_DH_AUDIO_FAILED;
274 }
275 }
276 return DH_SUCCESS;
277 }
278
OpenSpk(const std::string & devId)279 static void OpenSpk(const std::string &devId)
280 {
281 if (g_spkStatus != DeviceStatus::DEVICE_IDLE) {
282 std::cout << "Speaker device is already opened." << std::endl;
283 return;
284 }
285 if (LoadSpkDev(devId) != DH_SUCCESS) {
286 std::cout << "Load spk failed" << std::endl;
287 return;
288 }
289
290 g_callbackStub = OHOS::sptr<IAudioCallback>(new AudioParamCallbackImpl());
291 if (g_adapter == nullptr) {
292 return;
293 }
294 int32_t ret = g_adapter->RegExtraParamObserver(g_callbackStub, 0);
295 if (ret != DH_SUCCESS) {
296 std::cout << "Register observer failed, ret: " << ret << std::endl;
297 return;
298 }
299
300 struct AudioDeviceDescriptor renderDesc;
301 renderDesc.pins = AudioPortPin::PIN_OUT_SPEAKER;
302 renderDesc.desc = "";
303 AudioSampleAttributes g_rattrs = {};
304 g_rattrs.type = AudioCategory::AUDIO_IN_MEDIA;
305 g_rattrs.interleaved = RENDER_INTER_LEAVED;
306 g_rattrs.streamId = RENDER_STREAM_ID;
307 g_rattrs.channelCount = RENDER_CHANNEL_MASK;
308 g_rattrs.sampleRate = AUDIO_SAMPLE_RATE;
309 g_rattrs.format = AudioFormat::AUDIO_FORMAT_TYPE_PCM_16_BIT;
310 ret = g_adapter->CreateRender(renderDesc, g_rattrs, g_render, g_renderId);
311 if (ret != DH_SUCCESS || g_render == nullptr) {
312 std::cout << "Open SPK device failed, ret: " << ret << std::endl;
313 return;
314 }
315 g_spkStatus = DeviceStatus::DEVICE_OPEN;
316 std::cout << "Open SPK device success." << std::endl;
317 }
318
WriteStreamWait(const int64_t & startTime)319 static void WriteStreamWait(const int64_t &startTime)
320 {
321 int64_t endTime = GetNowTimeUs();
322 int64_t passTime = endTime - startTime;
323
324 if (passTime > AUDIO_FRAME_TIME_INTERFAL_DEFAULT) {
325 return;
326 }
327 int64_t remainTime = AUDIO_FRAME_TIME_INTERFAL_DEFAULT - passTime;
328 std::this_thread::sleep_for(std::chrono::microseconds(remainTime));
329 }
330
Play()331 static void Play()
332 {
333 if (g_render == nullptr) {
334 std::cout << "SPK device is null." << std::endl;
335 return;
336 }
337 if (pthread_setname_np(pthread_self(), PLAY_THREAD) != DH_SUCCESS) {
338 std::cout << "Play thread setname failed." << std::endl;
339 }
340 std::cout << "Playing thread started." << std::endl;
341 g_render->Start();
342 g_spkStatus = DeviceStatus::DEVICE_START;
343
344 uint64_t size = 0;
345 while (g_spkStatus == DeviceStatus::DEVICE_START) {
346 int64_t startTime = GetNowTimeUs();
347
348 std::vector<int8_t> frameHal(RENDER_FRAME_SIZE);
349 int32_t ret = memcpy_s(frameHal.data(), RENDER_FRAME_SIZE, renderData[g_frameIndex], RENDER_FRAME_SIZE);
350 if (ret != EOK) {
351 DHLOGE("Copy render frame failed, error code %{public}d.", ret);
352 return;
353 }
354 ret = g_render->RenderFrame(frameHal, size);
355 if (ret != DH_SUCCESS) {
356 std::cout<<"RenderFrame failed, index: "<< g_frameIndex << ", ret: " << ret << std::endl;
357 }
358 g_frameIndex++;
359 if (g_frameNum != 0 && g_frameIndex == g_frameNum) {
360 g_frameIndex = 0;
361 }
362 WriteStreamWait(startTime);
363 }
364 std::cout << "Playing thread stopped." << std::endl;
365 }
366
StartRender()367 static void StartRender()
368 {
369 if (g_spkStatus == DeviceStatus::DEVICE_IDLE) {
370 std::cout << "Speaker device is not opened, start render failed." << std::endl;
371 return;
372 }
373
374 if (g_spkStatus == DeviceStatus::DEVICE_OPEN) {
375 WavHdr wavHeader;
376 size_t headerSize = sizeof(WavHdr);
377 if (!g_isInitRenderData) {
378 struct stat statbuf;
379 stat(SPK_FILE_PATH, &statbuf);
380 int32_t size = statbuf.st_size;
381 g_frameNum = (size - static_cast<int32_t>(headerSize)) / RENDER_FRAME_SIZE;
382 std::cout << "Audio file frame num: " << g_frameNum << std::endl;
383 for (int32_t j = 0; j < g_frameNum; j++) {
384 uint8_t *frame = new uint8_t[RENDER_FRAME_SIZE]();
385 renderData.push_back(frame);
386 }
387 g_isInitRenderData = true;
388 }
389 FILE *wavFile = fopen(SPK_FILE_PATH, "rb");
390 fread(&wavHeader, 1, headerSize, wavFile);
391 for (int32_t i = 0; i < g_frameNum; i++) {
392 fread(renderData[i], 1, RENDER_FRAME_SIZE, wavFile);
393 }
394 fclose(wavFile);
395 g_frameIndex = 0;
396 g_playingThread = std::thread(Play);
397 return;
398 }
399 if (g_spkStatus == DeviceStatus::DEVICE_START) {
400 std::cout << "Speaker device is started." << std::endl;
401 return;
402 }
403 if (g_spkStatus == DeviceStatus::DEVICE_STOP) {
404 g_playingThread = std::thread(Play);
405 }
406 }
407
StopRender()408 static void StopRender()
409 {
410 if (g_render == nullptr) {
411 std::cout << "SPK device is null." << std::endl;
412 return;
413 }
414
415 if (g_spkStatus == DeviceStatus::DEVICE_IDLE) {
416 std::cout << "Speaker device is not opened." << std::endl;
417 return;
418 }
419
420 if (g_spkStatus == DeviceStatus::DEVICE_OPEN) {
421 std::cout << "Speaker device is not started." << std::endl;
422 return;
423 }
424
425 if (g_spkStatus == DeviceStatus::DEVICE_STOP) {
426 std::cout << "Speaker device is already stoped." << std::endl;
427 return;
428 }
429
430 g_spkStatus = DeviceStatus::DEVICE_STOP;
431 if (g_playingThread.joinable()) {
432 g_playingThread.join();
433 }
434 g_render->Stop();
435 }
436
CloseSpk()437 static void CloseSpk()
438 {
439 if (g_spkStatus == DeviceStatus::DEVICE_IDLE) {
440 std::cout << "Speaker device is not opened." << std::endl;
441 return;
442 }
443
444 if (g_spkStatus == DeviceStatus::DEVICE_START) {
445 StopRender();
446 }
447
448 if (g_adapter != nullptr) {
449 int32_t ret = g_adapter->DestroyRender(g_renderId);
450 if (ret != DH_SUCCESS) {
451 std::cout << "Close speaker failed" << std::endl;
452 return;
453 }
454 }
455 if (g_micStatus == DeviceStatus::DEVICE_IDLE && g_manager != nullptr) {
456 g_manager->UnloadAdapter(g_devId);
457 g_adapter = nullptr;
458 }
459 g_spkStatus = DeviceStatus::DEVICE_IDLE;
460
461 if (g_isInitRenderData) {
462 for (auto &p : renderData) {
463 delete[] p;
464 }
465 renderData.clear();
466 g_isInitRenderData = false;
467 }
468 std::cout << "Close SPK device success." << std::endl;
469 }
470
LoadMicDev(const std::string & devId)471 static int32_t LoadMicDev(const std::string &devId)
472 {
473 struct AudioAdapterDescriptor dev;
474 for (uint32_t index = 0; index < g_devices.size(); index++) {
475 struct AudioAdapterDescriptor desc = g_devices[index];
476 if (desc.adapterName == devId) {
477 dev = desc;
478 break;
479 }
480 }
481 if (dev.adapterName.data() == nullptr) {
482 std::cout << "Input device id is wrong." << std::endl;
483 FindAudioDevice();
484 return ERR_DH_AUDIO_FAILED;
485 }
486 if (g_manager == nullptr) {
487 return ERR_DH_AUDIO_FAILED;
488 }
489 if (g_adapter == nullptr) {
490 int32_t ret = g_manager->LoadAdapter(dev, g_adapter);
491 if (ret != DH_SUCCESS || g_adapter == nullptr) {
492 std::cout << "Load audio device failed, ret: " << ret << std::endl;
493 return ERR_DH_AUDIO_FAILED;
494 }
495 }
496 return DH_SUCCESS;
497 }
498
OpenMic(const std::string & devId)499 static void OpenMic(const std::string &devId)
500 {
501 if (g_micStatus != DeviceStatus::DEVICE_IDLE) {
502 std::cout << "Mic device is already opened." << std::endl;
503 return;
504 }
505 if (LoadMicDev(devId) != DH_SUCCESS) {
506 std::cout << "Load audio device failed." << std::endl;
507 return;
508 }
509
510 AudioDeviceDescriptor captureDesc;
511 captureDesc.pins = AudioPortPin::PIN_IN_MIC;
512 captureDesc.desc = "";
513 AudioSampleAttributes captureAttr;
514 captureAttr.type = AudioCategory::AUDIO_IN_MEDIA;
515 captureAttr.interleaved = CAPTURE_INTER_LEAVED;
516 captureAttr.streamId = CAPTURE_STREAM_ID;
517 captureAttr.channelCount = CAPTURE_CHANNEL_MASK;
518 captureAttr.sampleRate = AUDIO_SAMPLE_RATE;
519 captureAttr.format = AudioFormat::AUDIO_FORMAT_TYPE_PCM_16_BIT;
520 if (g_adapter == nullptr) {
521 return;
522 }
523 int32_t ret = g_adapter->CreateCapture(captureDesc, captureAttr, g_capture, g_captureId);
524 if (ret != DH_SUCCESS || g_capture == nullptr) {
525 std::cout << "Open MIC device failed." << std::endl;
526 return;
527 }
528 g_micStatus = DeviceStatus::DEVICE_OPEN;
529 std::cout << "Open MIC device success." << std::endl;
530 }
531
ReadStreamWait(const int64_t & startTime)532 static void ReadStreamWait(const int64_t &startTime)
533 {
534 int64_t endTime = GetNowTimeUs();
535 int32_t passTime = endTime - startTime;
536
537 if (passTime > AUDIO_FRAME_TIME_INTERFAL_DEFAULT) {
538 return;
539 }
540 int64_t remainTime = AUDIO_FRAME_TIME_INTERFAL_DEFAULT - passTime;
541 std::this_thread::sleep_for(std::chrono::microseconds(remainTime));
542 }
543
Capture()544 static void Capture()
545 {
546 if (g_capture == nullptr) {
547 std::cout << "MIC device is null." << std::endl;
548 return;
549 }
550 if (pthread_setname_np(pthread_self(), CAPTURE_THREAD) != DH_SUCCESS) {
551 std::cout << "Capture thread setname failed." << std::endl;
552 }
553 std::cout << "Capturing thread started." << std::endl;
554 g_capture->Start();
555 g_micStatus = DeviceStatus::DEVICE_START;
556
557 uint64_t size = 0;
558 while (g_micStatus == DeviceStatus::DEVICE_START) {
559 std::vector<int8_t> data(RENDER_FRAME_SIZE);
560 int64_t startTime = GetNowTimeUs();
561 int32_t ret = g_capture->CaptureFrame(data, size);
562 if (ret != DH_SUCCESS) {
563 std::cout << "CaptureFrame failed, ret: " << ret << std::endl;
564 return;
565 }
566 size_t writeCnt = fwrite(data.data(), 1, RENDER_FRAME_SIZE, g_micFile);
567 if (static_cast<int32_t>(writeCnt) != RENDER_FRAME_SIZE) {
568 std::cout << "fwrite data failed." << std::endl;
569 }
570 g_micFrameNum++;
571 ReadStreamWait(startTime);
572 }
573 std::cout << "Capturing thread stopped." << std::endl;
574 }
575
StartCapture()576 static void StartCapture()
577 {
578 if (g_micStatus == DeviceStatus::DEVICE_IDLE) {
579 std::cout << "Mic device is not opened, start capture failed." << std::endl;
580 return;
581 }
582
583 if (g_micStatus == DeviceStatus::DEVICE_OPEN) {
584 g_micFile = fopen(MIC_FILE_PATH, "ab+");
585 if (g_micFile == nullptr) {
586 std::cout << "Open pcm file failed." << std::endl;
587 return;
588 }
589 g_capingThread = std::thread(Capture);
590 return;
591 }
592
593 if (g_micStatus == DeviceStatus::DEVICE_START) {
594 std::cout << "Mic device is already started." << std::endl;
595 return;
596 }
597
598 if (g_micStatus == DeviceStatus::DEVICE_STOP) {
599 g_capingThread = std::thread(Capture);
600 }
601 }
602
StopCapture()603 static void StopCapture()
604 {
605 if (g_capture == nullptr) {
606 std::cout << "MIC device is null." << std::endl;
607 return;
608 }
609 if (g_micStatus == DeviceStatus::DEVICE_IDLE) {
610 std::cout << "Mic device is not opened." << std::endl;
611 return;
612 }
613 if (g_micStatus == DeviceStatus::DEVICE_OPEN) {
614 std::cout << "Mic device is not started." << std::endl;
615 return;
616 }
617 if (g_micStatus == DeviceStatus::DEVICE_STOP) {
618 std::cout << "Mic device is already started." << std::endl;
619 return;
620 }
621 g_micStatus = DeviceStatus::DEVICE_STOP;
622 if (g_capingThread.joinable()) {
623 g_capingThread.join();
624 }
625 g_capture->Stop();
626 }
627
CloseMic()628 static void CloseMic()
629 {
630 if (g_micStatus == DeviceStatus::DEVICE_IDLE) {
631 std::cout << "Mic device is not opened." << std::endl;
632 return;
633 }
634
635 if (g_micStatus == DeviceStatus::DEVICE_START) {
636 StopCapture();
637 }
638
639 if (g_adapter != nullptr) {
640 int32_t ret = g_adapter->DestroyCapture(g_captureId);
641 if (ret != DH_SUCCESS) {
642 std::cout << "Close mic failed." << std::endl;
643 return;
644 }
645 }
646 if (g_spkStatus == DeviceStatus::DEVICE_IDLE && g_manager != nullptr) {
647 g_manager->UnloadAdapter(g_devId);
648 g_adapter = nullptr;
649 }
650 if (g_micFile != nullptr) {
651 fclose(g_micFile);
652 g_micFile = nullptr;
653 }
654 g_micStatus = DeviceStatus::DEVICE_IDLE;
655 std::cout << "Close MIC device success." << std::endl;
656 }
657
SetVolume()658 static void SetVolume()
659 {
660 if (g_spkStatus == DeviceStatus::DEVICE_IDLE) {
661 std::cout << "Speaker is not opened, can not set volume." << std::endl;
662 return;
663 }
664 std::cout << "Please input volum to set [0,15]." << std::endl;
665 int32_t volInt = GetUserInput();
666 if (volInt < VOLUME_MIN || volInt > VOLUME_MAX) {
667 std::cout << "Volume is invalid." << std::endl;
668 return;
669 }
670 std::cout << "Set volume: " << volInt << std::endl;
671 AudioExtParamKey key = AudioExtParamKey::AUDIO_EXT_PARAM_KEY_VOLUME;
672 std::string condition = "EVENT_TYPE=1;VOLUME_GROUP_ID=1;AUDIO_VOLUME_TYPE=1;";
673 std::string volStr = std::to_string(volInt);
674 if (g_adapter != nullptr) {
675 int32_t ret = g_adapter->SetExtraParams(key, condition, volStr);
676 if (ret != DH_SUCCESS) {
677 std::cout << "Set volume failed" << std::endl;
678 }
679 }
680 }
681
GetVolume()682 static void GetVolume()
683 {
684 if (g_spkStatus == DeviceStatus::DEVICE_IDLE) {
685 std::cout << "Speaker is not opened, can not get volume." << std::endl;
686 return;
687 }
688 AudioExtParamKey key = AudioExtParamKey::AUDIO_EXT_PARAM_KEY_VOLUME;
689 std::string condition = "EVENT_TYPE=1;VOLUME_GROUP_ID=1;AUDIO_VOLUME_TYPE=1;";
690 std::string vol;
691 if (g_adapter != nullptr) {
692 int32_t ret = g_adapter->GetExtraParams(key, condition.c_str(), vol);
693 if (ret != DH_SUCCESS) {
694 std::cout << "Get Volume failed." << std::endl;
695 return;
696 }
697 }
698 std::cout << "Get volume success. volume: " << vol <<std::endl;
699 }
700
HandleAudioEvent(const int32_t cmd)701 static void HandleAudioEvent(const int32_t cmd)
702 {
703 switch (cmd) {
704 case CMD_FIND:
705 FindAudioDevice();
706 break;
707 case CMD_OPEN_SPK:
708 OpenSpk(g_devId);
709 break;
710 case CMD_START_SPK:
711 StartRender();
712 break;
713 case CMD_STOP_SPK:
714 StopRender();
715 break;
716 case CMD_CLOSE_SPK:
717 CloseSpk();
718 break;
719 case CMD_OPEN_MIC:
720 OpenMic(g_devId);
721 break;
722 case CMD_START_MIC:
723 StartCapture();
724 break;
725 case CMD_STOP_MIC:
726 StopCapture();
727 break;
728 case CMD_CLOSE_MIC:
729 CloseMic();
730 break;
731 case CMD_SET_VOL:
732 SetVolume();
733 break;
734 case CMD_GET_VOL:
735 GetVolume();
736 break;
737 default:
738 std::cout << "Unkown opeartion." << std::endl;
739 break;
740 }
741 }
742
PrintInteractiveUsage()743 static void PrintInteractiveUsage()
744 {
745 std::cout << std::endl << "=============== InteractiveRunTestSelect ================" << std::endl;
746 std::cout << "You can respond to instructions for corresponding option:" << std::endl;
747 std::cout << "\t enter 1 to open spk. " << std::endl;
748 std::cout << "\t enter 2 to close spk. " << std::endl;
749 std::cout << "\t enter 3 to start play. " << std::endl;
750 std::cout << "\t enter 4 to stop play. " << std::endl;
751 std::cout << "\t enter 5 to open mic. " << std::endl;
752 std::cout << "\t enter 6 to clsoe mic. " << std::endl;
753 std::cout << "\t enter 7 to start record. " << std::endl;
754 std::cout << "\t enter 8 to stop record. " << std::endl;
755 std::cout << "\t enter 9 to manullt find device. " << std::endl;
756 std::cout << "\t enter 11 to set volume. " << std::endl;
757 std::cout << "\t enter 12 to get volume. " << std::endl;
758 std::cout << "\t enter 0 to exit. " << std::endl;
759 }
760 }
761
main(int argc,char * argv[])762 int main(int argc, char *argv[])
763 {
764 if (InitTestDemo() != DH_SUCCESS) {
765 return ERR_DH_AUDIO_FAILED;
766 }
767 while (true) {
768 PrintInteractiveUsage();
769 int32_t cmd = GetUserInput();
770 if (cmd == CMD_QUIT) {
771 CloseSpk();
772 CloseMic();
773 break;
774 }
775 HandleAudioEvent(cmd);
776 }
777 return 0;
778 }