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 34using OHOS::HDI::DistributedAudio::Audio::V1_0::IAudioAdapter; 35using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioAdapterDescriptor; 36using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioFormat; 37using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioPort; 38using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioPortDirection; 39using OHOS::HDI::DistributedAudio::Audio::V1_0::IAudioManager; 40using OHOS::HDI::DistributedAudio::Audio::V1_0::IAudioRender; 41using OHOS::HDI::DistributedAudio::Audio::V1_0::IAudioCapture; 42using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioSampleAttributes; 43using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioDeviceDescriptor; 44using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioCategory; 45using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioRouteNode; 46using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioExtParamKey; 47using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioRoute; 48using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioSceneDescriptor; 49using OHOS::HDI::DistributedAudio::Audio::V1_0::IAudioCallback; 50using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioPortPin; 51using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioPortType; 52using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioPortRole; 53using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioCallbackType; 54 55namespace { 56using namespace OHOS::DistributedHardware; 57static int32_t ParamEventCallback(AudioExtParamKey key, const char *condition, const char *value, void *reserved, 58 void *cookie); 59 60class AudioParamCallbackImpl final : public IAudioCallback { 61public: 62 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 70int32_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 78int32_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 88const int32_t CMD_QUIT = 0; 89const int32_t CMD_FIND = 9; 90const int32_t CMD_OPEN_SPK = 1; 91const int32_t CMD_CLOSE_SPK = 2; 92const int32_t CMD_START_SPK = 3; 93const int32_t CMD_STOP_SPK = 4; 94const int32_t CMD_OPEN_MIC = 5; 95const int32_t CMD_CLOSE_MIC = 6; 96const int32_t CMD_START_MIC = 7; 97const int32_t CMD_STOP_MIC = 8; 98const int32_t CMD_SET_VOL = 11; 99const int32_t CMD_GET_VOL = 12; 100 101const char DEV_TYPE_SPK = '1'; 102const char DEV_TYPE_MIC = '2'; 103const char SPK_FILE_PATH[128] = "/data/test.wav"; 104const char MIC_FILE_PATH[128] = "/data/mic.pcm"; 105constexpr int32_t TYPE_OFFSET = 12; 106constexpr int32_t AUDIO_SAMPLE_RATE = 48000; 107constexpr int32_t VOLUME_MIN = 0; 108constexpr int32_t VOLUME_MAX = 15; 109constexpr int32_t RENDER_FRAME_SIZE = 3840; 110constexpr int32_t RENDER_INTER_LEAVED = 1; 111constexpr int32_t RENDER_STREAM_ID = 0; 112constexpr int32_t RENDER_CHANNEL_MASK = 2; 113constexpr int32_t CAPTURE_INTER_LEAVED = 1; 114constexpr int32_t CAPTURE_STREAM_ID = 2; 115constexpr int32_t CAPTURE_CHANNEL_MASK = 2; 116constexpr int64_t AUDIO_FRAME_TIME_INTERFAL_DEFAULT = 21333; 117 118static OHOS::sptr<IAudioManager> g_manager = nullptr; 119static OHOS::sptr<IAudioAdapter> g_adapter = nullptr; 120static OHOS::sptr<IAudioRender> g_render = nullptr; 121static OHOS::sptr<IAudioCapture> g_capture = nullptr; 122static std::vector<AudioAdapterDescriptor> g_devices; 123static OHOS::sptr<IAudioCallback> g_callbackStub = nullptr; 124static std::string g_devId = ""; 125 126static constexpr const char* PLAY_THREAD = "playThread"; 127static constexpr const char* CAPTURE_THREAD = "captureThread"; 128 129uint32_t g_renderId = 0; 130uint32_t g_captureId = 0; 131int32_t g_frameNum = 0; 132int32_t g_frameIndex = 0; 133int32_t g_micFrameNum = 0; 134bool g_isInitRenderData = false; 135static std::vector<uint8_t*> renderData; 136 137static DeviceStatus g_spkStatus = DeviceStatus::DEVICE_IDLE; 138static DeviceStatus g_micStatus = DeviceStatus::DEVICE_IDLE; 139 140static std::thread g_playingThread; 141static std::thread g_capingThread; 142FILE *g_micFile = nullptr; 143 144static void CloseSpk(); 145static void CloseMic(); 146 147static 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 154static 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 177static 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 197static 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 219static 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 232static 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 251static 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 279static 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 319static 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 331static 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 367static 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 408static 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 437static 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 471static 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 499static 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 532static 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 544static 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 576static 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 603static 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 628static 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 658static 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 682static 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 701static 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 743static 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 762int 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}