1/* 2 * Copyright (c) 2022-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 <dlfcn.h> 17#include <limits.h> 18#include <pthread.h> 19#include <securec.h> 20#include <signal.h> 21#include <stdio.h> 22#include <stdlib.h> 23#include <string.h> 24#include <sys/mman.h> 25#include <sys/stat.h> 26#include <unistd.h> 27#include "framework_common.h" 28#include "hdf_base.h" 29#include "inttypes.h" 30#include "osal_mem.h" 31#include "v4_0/audio_types.h" 32#include "v4_0/iaudio_manager.h" 33 34#define MAX_AUDIO_ADAPTER_DESC 5 35#define BUFFER_LEN 256 36#define AUDIO_CHANNELCOUNT 2 37#define AUDIO_SAMPLE_RATE_48K 48000 38#define PATH_LEN 256 39#define DEEP_BUFFER_RENDER_PERIOD_SIZE 4096 40#define INT_32_MAX 0x7fffffff 41#define EXT_PARAMS_MAXLEN 107 42#define BITS_TO_FROMAT 3 43 44struct StrPara { 45 struct IAudioRender *render; 46 FILE *file; 47 struct AudioSampleAttributes attrs; 48 uint64_t *replyBytes; 49 char *frame; 50 int32_t bufferSize; 51}; 52 53struct IAudioRender *g_render = NULL; 54struct IAudioAdapter *g_adapter = NULL; 55static struct IAudioManager *g_audioManager = NULL; 56struct AudioDeviceDescriptor g_devDesc; 57struct AudioSampleAttributes g_attrs; 58struct AudioPort g_audioPort; 59struct AudioHeadInfo g_wavHeadInfo; 60static struct StrPara g_str; 61uint32_t g_renderId = 0; 62 63pthread_t g_tids; 64char *g_frame = NULL; 65FILE *g_file; 66 67char g_path[256]; 68char g_adapterName[PATH_LEN] = {0}; 69static int32_t g_closeEnd = 0; 70pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; 71pthread_cond_t g_functionCond = PTHREAD_COND_INITIALIZER; 72bool g_waitSleep = false; 73bool g_isDirect = true; 74 75enum RenderMenuId { 76 RENDER_START = 1, 77 RENDER_STOP, 78 RENDER_RESUME, 79 RENDER_PAUSE, 80 SET_RENDER_VOLUME, 81 SET_RENDER_GAIN, 82 SET_RENDER_MUTE, 83 SET_RENDER_ATTRIBUTES, 84 SET_RENDER_SLECET_SCENE, 85 GET_RENDER_EXT_PARAMS, 86 GET_RENDER_POSITION, 87}; 88 89enum RenderInputType { 90 INPUT_INT = 0, 91 INPUT_FLOAT, 92 INPUT_UINT32, 93}; 94 95typedef int32_t (*AudioRenderOperation)(struct IAudioRender **); 96 97struct ProcessRenderMenuSwitchList { 98 enum RenderMenuId cmd; 99 AudioRenderOperation operation; 100}; 101 102static int32_t CheckInputName(int type, void *val) 103{ 104 if (val == NULL) { 105 return HDF_FAILURE; 106 } 107 108 int ret; 109 int inputInt = 0; 110 float inputFloat = 0.0; 111 uint32_t inputUint = 0; 112 113 printf("\n"); 114 switch (type) { 115 case INPUT_INT: 116 ret = scanf_s("%d", &inputInt); 117 if (inputInt < 0 || inputInt > GET_RENDER_POSITION + 1) { 118 if (g_frame != NULL) { 119 OsalMemFree(g_frame); 120 g_frame = NULL; 121 } 122 AUDIO_FUNC_LOGE("Input failure"); 123 return HDF_FAILURE; 124 } 125 126 *(int *)val = inputInt; 127 break; 128 case INPUT_FLOAT: 129 ret = scanf_s("%f", &inputFloat); 130 131 *(float *)val = inputFloat; 132 break; 133 case INPUT_UINT32: 134 ret = scanf_s("%u", &inputUint); 135 if (inputUint > 0xFFFFFFFF) { 136 return HDF_FAILURE; 137 } 138 139 *(uint32_t *)val = inputUint; 140 break; 141 default: 142 ret = EOF; 143 break; 144 } 145 146 if (ret == 0) { 147 CleanStdin(); 148 } else if (ret == EOF) { 149 AUDIO_FUNC_LOGE("Input failure occurs!"); 150 return HDF_FAILURE; 151 } 152 return HDF_SUCCESS; 153} 154 155static int32_t InitAttrs(struct AudioSampleAttributes *attrs) 156{ 157 if (attrs == NULL) { 158 return HDF_FAILURE; 159 } 160 /* Initialization of audio parameters for playback */ 161 attrs->format = AUDIO_FORMAT_TYPE_PCM_16_BIT; 162 attrs->channelCount = AUDIO_CHANNELCOUNT; 163 attrs->sampleRate = AUDIO_SAMPLE_RATE_48K; 164 attrs->interleaved = 0; 165 attrs->type = AUDIO_IN_MEDIA; 166 attrs->period = DEEP_BUFFER_RENDER_PERIOD_SIZE; 167 attrs->frameSize = PCM_16_BIT * attrs->channelCount / PCM_8_BIT; 168 attrs->isBigEndian = false; 169 attrs->isSignedData = true; 170 attrs->startThreshold = DEEP_BUFFER_RENDER_PERIOD_SIZE / (attrs->frameSize); 171 attrs->stopThreshold = INT_32_MAX; 172 attrs->silenceThreshold = 0; 173 return HDF_SUCCESS; 174} 175 176static int32_t InitDevDesc(struct AudioDeviceDescriptor *devDesc, uint32_t portId) 177{ 178 if (devDesc == NULL) { 179 return HDF_FAILURE; 180 } 181 /* Initialization of audio parameters for playback */ 182 devDesc->portId = portId; 183 devDesc->pins = PIN_OUT_SPEAKER; 184 devDesc->desc = strdup("cardname"); 185 return HDF_SUCCESS; 186} 187 188static void StreamClose(int32_t sig) 189{ 190 /* allow the stream to be closed gracefully */ 191 (void)signal(sig, SIG_IGN); 192 g_closeEnd = 1; 193} 194 195static uint32_t PcmFramesToBytes(const struct AudioSampleAttributes attrs) 196{ 197 return DEEP_BUFFER_RENDER_PERIOD_SIZE * attrs.channelCount * (PcmFormatToBits(attrs.format) >> BITS_TO_FROMAT); 198} 199 200static int32_t StopAudioFiles(struct IAudioRender **renderS) 201{ 202 if (renderS == NULL) { 203 return HDF_FAILURE; 204 } 205 if (g_waitSleep) { 206 pthread_mutex_lock(&g_mutex); 207 g_waitSleep = false; 208 pthread_cond_signal(&g_functionCond); 209 pthread_mutex_unlock(&g_mutex); 210 } 211 if (!g_closeEnd) { 212 g_closeEnd = true; 213 usleep(100000); // sleep 100000us 214 } 215 216 struct IAudioRender *render = *renderS; 217 if (render == NULL) { 218 AUDIO_FUNC_LOGE("render is null"); 219 return HDF_FAILURE; 220 } 221 222 int32_t ret = render->Stop((void *)render); 223 if (ret < 0) { 224 AUDIO_FUNC_LOGE("Stop Render!"); 225 } 226 227 if (g_adapter == NULL || g_adapter->DestroyRender == NULL) { 228 return HDF_FAILURE; 229 } 230 231 ret = g_adapter->DestroyRender(g_adapter, g_renderId); 232 if (ret < 0) { 233 AUDIO_FUNC_LOGE("Destroy Render!"); 234 } 235 236 IAudioRenderRelease(render, g_isDirect); 237 238 *renderS = NULL; 239 g_render = NULL; 240 if (g_frame != NULL) { 241 OsalMemFree(g_frame); 242 g_frame = NULL; 243 } 244 245 if (g_file != NULL) { 246 fclose(g_file); 247 g_file = NULL; 248 } 249 printf("Stop Successful\n"); 250 return ret; 251} 252 253static int32_t FrameStartMmap(const struct StrPara *param) 254{ 255 if (param == NULL) { 256 return HDF_FAILURE; 257 } 258 const struct StrPara *strParam = param; 259 struct IAudioRender *render = strParam->render; 260 struct AudioMmapBufferDescriptor mmapDesc; 261 262 (void)signal(SIGINT, StreamClose); 263 264 // get file length 265 char pathBuf[PATH_MAX] = {'\0'}; 266 if (realpath(g_path, pathBuf) == NULL) { 267 return HDF_FAILURE; 268 } 269 270 // get fileSize 271 FILE *fp = fopen(pathBuf, "rb+"); 272 if (fp == NULL) { 273 printf("Open file failed!\n"); 274 return HDF_FAILURE; 275 } 276 277 int32_t ret = fseek(fp, 0, SEEK_END); 278 if (ret != 0) { 279 fclose(fp); 280 return HDF_FAILURE; 281 } 282 283 int32_t reqSize = (int32_t)ftell(fp); 284 if (reqSize < 0) { 285 fclose(fp); 286 return HDF_FAILURE; 287 } 288 (void)fclose(fp); 289 // Init param 290 mmapDesc.memoryFd = 0; // default 0 291 mmapDesc.filePath = strdup(pathBuf); 292 mmapDesc.isShareable = 1; // 1:Shareable ,0:Don't share 293 mmapDesc.transferFrameSize = DEEP_BUFFER_RENDER_PERIOD_SIZE / 4; // One frame size 4 bit 294 mmapDesc.offset = sizeof(g_wavHeadInfo); 295 296 // start 297 if (render == NULL || render->ReqMmapBuffer == NULL) { 298 free(mmapDesc.filePath); 299 return HDF_FAILURE; 300 } 301 302 ret = render->ReqMmapBuffer(render, reqSize, &mmapDesc); 303 if (ret < 0 || reqSize <= 0) { 304 free(mmapDesc.filePath); 305 printf("Request map fail,please check.\n"); 306 return HDF_FAILURE; 307 } 308 309 if (g_render != NULL) { 310 ret = StopAudioFiles(&render); 311 if (ret < 0) { 312 free(mmapDesc.filePath); 313 AUDIO_FUNC_LOGE("StopAudioFiles File!"); 314 } 315 } 316 free(mmapDesc.filePath); 317 return HDF_SUCCESS; 318} 319 320static int32_t FrameStart(const struct StrPara *param) 321{ 322 if (param == NULL) { 323 return HDF_FAILURE; 324 } 325 326 size_t numRead; 327 char *frame = param->frame; 328 int32_t bufferSize = param->bufferSize; 329 struct IAudioRender *render = param->render; 330 size_t remainingDataSize = g_wavHeadInfo.riffSize; 331 332 (void)signal(SIGINT, StreamClose); 333 if (g_file == NULL) { 334 return HDF_FAILURE; 335 } 336 337 if (render == NULL || render->RenderFrame == NULL || frame == NULL) { 338 return HDF_FAILURE; 339 } 340 341 do { 342 uint64_t replyBytes = 0; 343 size_t readSize = (remainingDataSize > bufferSize) ? (size_t)bufferSize : remainingDataSize; 344 numRead = fread(frame, 1, readSize, g_file); 345 if (numRead > 0) { 346 int32_t ret = render->RenderFrame(render, (int8_t *)frame, numRead, &replyBytes); 347 if (ret == HDF_ERR_INVALID_OBJECT) { 348 AUDIO_FUNC_LOGE("Render already stop!"); 349 break; 350 } 351 remainingDataSize -= numRead; 352 } 353 354 while (g_waitSleep) { 355 printf("music pause now.\n"); 356 pthread_cond_wait(&g_functionCond, &g_mutex); 357 printf("music resume now.\n"); 358 } 359 } while (!g_closeEnd && numRead > 0 && remainingDataSize > 0); 360 361 if (!g_closeEnd) { 362 printf("\nPlay complete, please select input again\n"); 363 (void)StopAudioFiles(&render); 364 } 365 return HDF_SUCCESS; 366} 367 368static int32_t InitPlayingAudioParam(struct IAudioRender *render) 369{ 370 if (render == NULL) { 371 return HDF_FAILURE; 372 } 373 uint64_t frameSize = 0; 374 uint64_t frameCount = 0; 375 uint64_t bufferSize = 0; 376 if (render->GetFrameSize(render, &frameSize) != HDF_SUCCESS) { 377 AUDIO_FUNC_LOGE("get frame size failed"); 378 } 379 if (render->GetFrameCount(render, &frameCount) != HDF_SUCCESS) { 380 AUDIO_FUNC_LOGE("get frame count failed"); 381 } 382 383 bufferSize = frameCount * frameSize; 384 if (bufferSize == 0) { 385 bufferSize = PcmFramesToBytes(g_attrs); 386 AUDIO_FUNC_LOGE("buffer size by calc is %" PRIu64 "", bufferSize); 387 } 388 389 g_frame = (char *)OsalMemCalloc(bufferSize); 390 if (g_frame == NULL) { 391 return HDF_FAILURE; 392 } 393 394 (void)memset_s(&g_str, sizeof(struct StrPara), 0, sizeof(struct StrPara)); 395 396 g_str.render = render; 397 g_str.bufferSize = (int32_t)bufferSize; 398 g_str.frame = g_frame; 399 return HDF_SUCCESS; 400} 401 402static void PrintPlayMode(void) 403{ 404 printf(" ============= Play Render Mode ==========\n"); 405 printf("| 1. Render non-mmap |\n"); 406 printf("| 2. Render mmap |\n"); 407 printf(" ======================================== \n"); 408} 409 410static int32_t SelectPlayMode(int32_t *palyModeFlag) 411{ 412 if (palyModeFlag == NULL) { 413 AUDIO_FUNC_LOGE("palyModeFlag is null"); 414 return HDF_FAILURE; 415 } 416 417 int choice = 0; 418 419 system("clear"); 420 421 PrintPlayMode(); 422 423 printf("Please enter your choice:"); 424 425 int32_t ret = CheckInputName(INPUT_INT, (void *)&choice); 426 if (ret < 0) { 427 AUDIO_FUNC_LOGE("CheckInputName Fail"); 428 return HDF_FAILURE; 429 } else { 430 *palyModeFlag = choice; 431 } 432 return HDF_SUCCESS; 433} 434 435static int32_t StartPlayThread(int32_t palyModeFlag) 436{ 437 pthread_attr_t tidsAttr; 438 pthread_attr_init(&tidsAttr); 439 pthread_attr_setdetachstate(&tidsAttr, PTHREAD_CREATE_DETACHED); 440 switch (palyModeFlag) { 441 case 1: // 1. Stander Loading 442 if (pthread_create(&g_tids, &tidsAttr, (void *)(&FrameStart), &g_str) != 0) { 443 AUDIO_FUNC_LOGE("Create Thread Fail"); 444 return HDF_FAILURE; 445 } 446 break; 447 case 2: // 2. Low latency Loading 448 if (pthread_create(&g_tids, &tidsAttr, (void *)(&FrameStartMmap), &g_str) != 0) { 449 AUDIO_FUNC_LOGE("Create Thread Fail"); 450 return HDF_FAILURE; 451 } 452 break; 453 default: 454 printf("Input error,Switched to non-mmap Mode for you.\n"); 455 SystemInputFail(); 456 457 if (pthread_create(&g_tids, &tidsAttr, (void *)(&FrameStart), &g_str) != 0) { 458 AUDIO_FUNC_LOGE("Create Thread Fail"); 459 return HDF_FAILURE; 460 } 461 break; 462 } 463 return HDF_SUCCESS; 464} 465 466static int32_t PlayingAudioInitFile(void) 467{ 468 if (g_file != NULL) { 469 AUDIO_FUNC_LOGE("the music is playing,please stop first"); 470 return HDF_FAILURE; 471 } 472 g_closeEnd = false; 473 474 char pathBuf[PATH_MAX] = {'\0'}; 475 if (realpath(g_path, pathBuf) == NULL) { 476 return HDF_FAILURE; 477 } 478 479 g_file = fopen(pathBuf, "rb"); 480 if (g_file == NULL) { 481 printf("failed to open '%s'\n", g_path); 482 return HDF_FAILURE; 483 } 484 485 if (CheckWavFileHeader(g_file, &g_wavHeadInfo, &g_attrs) < 0) { 486 FileClose(&g_file); 487 return HDF_FAILURE; 488 } 489 490 (void)chmod(g_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); 491 492 return HDF_SUCCESS; 493} 494 495static int32_t PlayingAudioInitRender(struct IAudioRender **renderTemp) 496{ 497 if (renderTemp == NULL) { 498 AUDIO_FUNC_LOGE("render is null"); 499 return HDF_FAILURE; 500 } 501 struct IAudioRender *render = NULL; 502 if (g_adapter == NULL || g_adapter->CreateRender == NULL) { 503 return HDF_FAILURE; 504 } 505 int32_t ret = g_adapter->CreateRender(g_adapter, &g_devDesc, &g_attrs, &render, &g_renderId); 506 if (render == NULL || ret < 0 || render->RenderFrame == NULL) { 507 AUDIO_FUNC_LOGE("AudioDeviceCreateRender failed or RenderFrame is null"); 508 return HDF_FAILURE; 509 } 510 511 // Playing audio files 512 if (render->Start((void *)render)) { 513 AUDIO_FUNC_LOGE("Start Bind Fail!"); 514 g_adapter->DestroyRender(g_adapter, g_renderId); 515 IAudioRenderRelease(render, g_isDirect); 516 return HDF_FAILURE; 517 } 518 519 if (InitPlayingAudioParam(render) < 0) { 520 g_adapter->DestroyRender(g_adapter, g_renderId); 521 IAudioRenderRelease(render, g_isDirect); 522 return HDF_FAILURE; 523 } 524 *renderTemp = render; 525 return HDF_SUCCESS; 526} 527 528static int32_t PlayingAudioFiles(struct IAudioRender **renderS) 529{ 530 if (renderS == NULL || g_adapter == NULL) { 531 return HDF_FAILURE; 532 } 533 534 if (PlayingAudioInitFile() < 0) { 535 AUDIO_FUNC_LOGE("PlayingAudioInitFile Fail"); 536 return HDF_FAILURE; 537 } 538 539 int32_t palyModeFlag = 0; 540 if (SelectPlayMode(&palyModeFlag) < 0) { 541 AUDIO_FUNC_LOGE("SelectPlayMode Fail"); 542 FileClose(&g_file); 543 return HDF_FAILURE; 544 } 545 546 struct IAudioRender *render = NULL; 547 if (PlayingAudioInitRender(&render) < 0) { 548 AUDIO_FUNC_LOGE("PlayingAudioInitRender fail"); 549 FileClose(&g_file); 550 return HDF_FAILURE; 551 } 552 553 if (StartPlayThread(palyModeFlag) < 0) { 554 FileClose(&g_file); 555 if (g_adapter != NULL && g_adapter->DestroyRender != NULL) { 556 g_adapter->DestroyRender(g_adapter, g_renderId); 557 } 558 IAudioRenderRelease(render, g_isDirect); 559 return HDF_FAILURE; 560 } 561 562 *renderS = render; 563 printf("Start Successful,Music is playing\n"); 564 return HDF_SUCCESS; 565} 566 567static int32_t SelectLoadingMode(void) 568{ 569 int choice = 0; 570 571 system("clear"); 572 573 PrintLoadModeMenu(); 574 575 printf("Please enter your choice:"); 576 577 int32_t ret = CheckInputName(INPUT_INT, (void *)&choice); 578 if (ret < 0) { 579 return HDF_FAILURE; 580 } 581 582 switch (choice) { 583 case 1: // 1 is Passthrough Loading 584 g_isDirect = true; 585 break; 586 case 2: // 2 is IPC Loading 587 g_isDirect = false; 588 break; 589 default: 590 printf("Input error,Switched to direct loading in for you.\n"); 591 SystemInputFail(); 592 g_isDirect = true; 593 break; 594 } 595 596 return HDF_SUCCESS; 597} 598 599void AudioAdapterDescriptorFree(struct AudioAdapterDescriptor *dataBlock, bool freeSelf) 600{ 601 if (dataBlock == NULL) { 602 return; 603 } 604 605 if (dataBlock->adapterName != NULL) { 606 OsalMemFree(dataBlock->adapterName); 607 dataBlock->adapterName = NULL; 608 } 609 610 if (dataBlock->ports != NULL) { 611 OsalMemFree(dataBlock->ports); 612 } 613 614 if (freeSelf) { 615 OsalMemFree(dataBlock); 616 } 617} 618 619static void ReleaseAdapterDescs(struct AudioAdapterDescriptor **descs, uint32_t descsLen) 620{ 621 if (descsLen > 0 && descs != NULL && (*descs) != NULL) { 622 for (uint32_t i = 0; i < descsLen; i++) { 623 AudioAdapterDescriptorFree(&(*descs)[i], false); 624 } 625 OsalMemFree(*descs); 626 *descs = NULL; 627 } 628} 629 630static int32_t GetManagerAndLoadAdapter(struct AudioPort *renderPort) 631{ 632 int32_t adapterIndex = 0; 633 634 if (renderPort == NULL) { 635 AUDIO_FUNC_LOGE("The Parameter is NULL"); 636 return HDF_FAILURE; 637 } 638 639 struct IAudioManager *audioManagerIns = IAudioManagerGet(g_isDirect); 640 if (audioManagerIns == NULL) { 641 AUDIO_FUNC_LOGE("Get audio Manager Fail"); 642 return HDF_FAILURE; 643 } 644 645 g_audioManager = audioManagerIns; 646 647 struct AudioAdapterDescriptor *descs = (struct AudioAdapterDescriptor *)OsalMemCalloc( 648 sizeof(struct AudioAdapterDescriptor) * (MAX_AUDIO_ADAPTER_DESC)); 649 if (descs == NULL) { 650 AUDIO_FUNC_LOGE("OsalMemCalloc for descs failed"); 651 return HDF_FAILURE; 652 } 653 654 uint32_t adapterNum = MAX_AUDIO_ADAPTER_DESC; 655 656 int32_t ret = audioManagerIns->GetAllAdapters(audioManagerIns, descs, &adapterNum); 657 if (ret < 0 || adapterNum == 0) { 658 AUDIO_FUNC_LOGE("Get All Adapters Fail"); 659 ReleaseAdapterDescs(&descs, MAX_AUDIO_ADAPTER_DESC); 660 return HDF_ERR_NOT_SUPPORT; 661 } 662 if (SelectAudioCard(descs, adapterNum, &adapterIndex) != HDF_SUCCESS) { 663 ReleaseAdapterDescs(&descs, MAX_AUDIO_ADAPTER_DESC); 664 return HDF_ERR_NOT_SUPPORT; 665 } 666 if (strcpy_s(g_adapterName, PATH_LEN, descs[adapterIndex - 1].adapterName) < 0) { 667 ReleaseAdapterDescs(&descs, MAX_AUDIO_ADAPTER_DESC); 668 return HDF_ERR_NOT_SUPPORT; 669 } 670 if (SwitchAudioPort(&descs[adapterIndex - 1], PORT_OUT, renderPort) != HDF_SUCCESS) { 671 ReleaseAdapterDescs(&descs, MAX_AUDIO_ADAPTER_DESC); 672 return HDF_ERR_NOT_SUPPORT; 673 } 674 if (audioManagerIns->LoadAdapter(audioManagerIns, &descs[adapterIndex - 1], &g_adapter)) { 675 AUDIO_FUNC_LOGE("Load Adapter Fail"); 676 ReleaseAdapterDescs(&descs, MAX_AUDIO_ADAPTER_DESC); 677 return HDF_ERR_NOT_SUPPORT; 678 } 679 680 ReleaseAdapterDescs(&descs, MAX_AUDIO_ADAPTER_DESC); 681 682 return HDF_SUCCESS; 683} 684 685static int32_t InitRenderParam(uint32_t portId) 686{ 687 if (g_adapter == NULL || g_adapter->InitAllPorts == NULL) { 688 return HDF_FAILURE; 689 } 690 // Initialization port information, can fill through mode and other parameters 691 (void)g_adapter->InitAllPorts(g_adapter); 692 693 // User needs to set 694 if (InitAttrs(&g_attrs) < 0) { 695 AUDIO_FUNC_LOGE("InitAttrs failed"); 696 return HDF_FAILURE; 697 } 698 699 // Specify a hardware device 700 if (InitDevDesc(&g_devDesc, portId) < 0) { 701 AUDIO_FUNC_LOGE("InitDevDesc failed"); 702 return HDF_FAILURE; 703 } 704 return HDF_SUCCESS; 705} 706 707static int32_t RenderGetAdapterAndInitEnvParams(void) 708{ 709 struct AudioPort renderPort; 710 711 int32_t ret = GetManagerAndLoadAdapter(&renderPort); 712 if (ret < 0) { 713 return ret; 714 } 715 716 if (InitRenderParam(renderPort.portId) < 0) { 717 g_audioManager->UnloadAdapter(g_audioManager, g_adapterName); 718 IAudioAdapterRelease(g_adapter, g_isDirect); 719 g_adapter = NULL; 720 return HDF_FAILURE; 721 } 722 return HDF_SUCCESS; 723} 724 725static int32_t InitParam(void) 726{ 727 if (SelectLoadingMode() < 0) { 728 return HDF_FAILURE; 729 } 730 731 /* Select loading mode,end */ 732 g_audioPort.dir = PORT_OUT; 733 g_audioPort.portId = 0; 734 g_audioPort.portName = "AOP"; 735 736 if (RenderGetAdapterAndInitEnvParams() < 0) { 737 AUDIO_FUNC_LOGE("GetProxyManagerFunc Fail"); 738 if (g_audioManager != NULL) { 739 IAudioManagerRelease(g_audioManager, g_isDirect); 740 g_audioManager = NULL; 741 } 742 return HDF_FAILURE; 743 } 744 return HDF_SUCCESS; 745} 746 747static int32_t SetRenderMute(struct IAudioRender **render) 748{ 749 (void)render; 750 if (g_render == NULL || g_render->GetMute == NULL) { 751 return HDF_FAILURE; 752 } 753 754 int32_t val; 755 bool isMute = false; 756 757 int32_t ret = g_render->GetMute((void *)g_render, &isMute); 758 if (ret < 0) { 759 AUDIO_FUNC_LOGE("The current mute state was not obtained!"); 760 } 761 762 printf("Now %s ,Do you need to set mute status(1/0):", isMute ? "mute" : "not mute"); 763 764 ret = CheckInputName(INPUT_INT, (void *)&val); 765 if (ret < 0) { 766 return HDF_FAILURE; 767 } 768 769 if (g_render == NULL || g_render->SetMute == NULL) { 770 AUDIO_FUNC_LOGE("Music already stop!"); 771 SystemInputFail(); 772 return HDF_FAILURE; 773 } 774 if (val == 1) { 775 ret = g_render->SetMute((void *)g_render, !isMute); 776 } 777 return ret; 778} 779 780static int32_t SetRenderVolume(struct IAudioRender **render) 781{ 782 (void)render; 783 if (g_render == NULL || g_render->GetVolume == NULL) { 784 return HDF_FAILURE; 785 } 786 787 int32_t ret; 788 float val = 0.0; 789 790 ret = g_render->GetVolume((void *)g_render, &val); 791 if (ret < 0) { 792 AUDIO_FUNC_LOGE("Get current volume failed!"); 793 SystemInputFail(); 794 return ret; 795 } 796 797 printf("Now the volume is %f ,Please enter the volume value you want to set (0.0-1.0):", val); 798 799 ret = CheckInputName(INPUT_FLOAT, (void *)&val); 800 if (ret < 0) { 801 return HDF_FAILURE; 802 } 803 804 if (val < 0.0 || val > 1.0) { 805 AUDIO_FUNC_LOGE("Invalid volume value!"); 806 SystemInputFail(); 807 return HDF_FAILURE; 808 } 809 810 if (g_render == NULL || g_render->SetVolume == NULL) { 811 AUDIO_FUNC_LOGE("Music already stop!"); 812 SystemInputFail(); 813 return HDF_FAILURE; 814 } 815 816 ret = g_render->SetVolume((void *)g_render, val); 817 if (ret < 0) { 818 AUDIO_FUNC_LOGE("set volume fail!"); 819 SystemInputFail(); 820 } 821 return ret; 822} 823 824static int32_t GetRenderGain(struct IAudioRender **render) 825{ 826 (void)render; 827 if (g_render == NULL || g_render->GetGain == NULL) { 828 return HDF_FAILURE; 829 } 830 831 float val = 1.0; 832 833 int32_t ret = g_render->GetGain((void *)g_render, &val); 834 if (ret < 0) { 835 AUDIO_FUNC_LOGE("Get current gain failed!"); 836 SystemInputFail(); 837 return HDF_FAILURE; 838 } 839 printf("Now the gain is %f,", val); 840 SystemInputFail(); 841 return HDF_SUCCESS; 842} 843 844static int32_t SetRenderPause(struct IAudioRender **render) 845{ 846 (void)render; 847 848 if (g_waitSleep) { 849 AUDIO_FUNC_LOGE("Already pause,not need pause again!"); 850 SystemInputFail(); 851 return HDF_FAILURE; 852 } 853 854 if (g_render == NULL || g_render->Pause == NULL) { 855 return HDF_FAILURE; 856 } 857 858 int32_t ret = g_render->Pause((void *)g_render); 859 if (ret != 0) { 860 return HDF_FAILURE; 861 } 862 863 printf("Pause success!\n"); 864 g_waitSleep = true; 865 return HDF_SUCCESS; 866} 867 868static int32_t SetRenderResume(struct IAudioRender **render) 869{ 870 (void)render; 871 872 if (!g_waitSleep) { 873 AUDIO_FUNC_LOGE("Now is Playing,not need resume!"); 874 SystemInputFail(); 875 return HDF_FAILURE; 876 } 877 878 if (g_render == NULL || g_render->Resume == NULL) { 879 return HDF_FAILURE; 880 } 881 882 int32_t ret = g_render->Resume((void *)g_render); 883 if (ret != 0) { 884 return HDF_FAILURE; 885 } 886 printf("resume success!\n"); 887 888 pthread_mutex_lock(&g_mutex); 889 g_waitSleep = false; 890 pthread_cond_signal(&g_functionCond); 891 pthread_mutex_unlock(&g_mutex); 892 return HDF_SUCCESS; 893} 894static void PrintAttributesFromat(void) 895{ 896 printf(" ============= Render Sample Attributes Fromat =============== \n"); 897 printf("| 1. Render AUDIO_FORMAT_TYPE_PCM_8_BIT |\n"); 898 printf("| 2. Render AUDIO_FORMAT_TYPE_PCM_16_BIT |\n"); 899 printf("| 3. Render AUDIO_FORMAT_TYPE_PCM_24_BIT |\n"); 900 printf("| 4. Render AUDIO_FORMAT_TYPE_PCM_32_BIT |\n"); 901 printf(" ============================================================= \n"); 902} 903static int32_t SelectAttributesFomat(uint32_t *pcmFomat) 904{ 905 if (pcmFomat == NULL) { 906 AUDIO_FUNC_LOGE("fomat is null!"); 907 return HDF_FAILURE; 908 } 909 910 int val = 0; 911 912 PrintAttributesFromat(); 913 914 printf("Please select audio format,If not selected, the default is 16bit:"); 915 916 int32_t ret = CheckInputName(INPUT_INT, (void *)&val); 917 if (ret < 0) { 918 AUDIO_FUNC_LOGE("CheckInputName failed."); 919 return HDF_FAILURE; 920 } 921 922 switch (val) { 923 case AUDIO_FORMAT_TYPE_PCM_8_BIT: 924 *pcmFomat = AUDIO_FORMAT_TYPE_PCM_8_BIT; 925 break; 926 case AUDIO_FORMAT_TYPE_PCM_16_BIT: 927 *pcmFomat = AUDIO_FORMAT_TYPE_PCM_16_BIT; 928 break; 929 case AUDIO_FORMAT_TYPE_PCM_24_BIT: 930 *pcmFomat = AUDIO_FORMAT_TYPE_PCM_24_BIT; 931 break; 932 case AUDIO_FORMAT_TYPE_PCM_32_BIT: 933 *pcmFomat = AUDIO_FORMAT_TYPE_PCM_32_BIT; 934 break; 935 default: 936 *pcmFomat = AUDIO_FORMAT_TYPE_PCM_16_BIT; 937 break; 938 } 939 return HDF_SUCCESS; 940} 941 942static int32_t SetRenderAttributes(struct IAudioRender **render) 943{ 944 (void)render; 945 946 struct AudioSampleAttributes attrs; 947 948 if (g_render == NULL || g_render->GetSampleAttributes == NULL) { 949 AUDIO_FUNC_LOGE("The pointer is null!"); 950 return HDF_FAILURE; 951 } 952 953 int32_t ret = g_render->GetSampleAttributes((void *)g_render, &attrs); 954 if (ret < 0) { 955 AUDIO_FUNC_LOGE("GetRenderAttributes failed!"); 956 } else { 957 printf("Current sample attributes:\n"); 958 printf("audioType is %u\nfomat is %u\nsampleRate is %u\nchannalCount is" 959 "%u\nperiod is %u\nframesize is %u\nbigEndian is %u\nSignedData is %u\n", 960 attrs.type, attrs.format, attrs.sampleRate, attrs.channelCount, attrs.period, attrs.frameSize, 961 attrs.isBigEndian, attrs.isSignedData); 962 } 963 printf("Set Sample Attributes,"); 964 SystemInputFail(); 965 system("clear"); 966 printf("The sample attributes you want to set,Step by step, please.\n"); 967 968 ret = SelectAttributesFomat((uint32_t *)(&attrs.format)); 969 if (ret < 0) { 970 AUDIO_FUNC_LOGE("SetRenderAttributes format failed!"); 971 return HDF_FAILURE; 972 } 973 974 printf("\nPlease input sample rate(48000,44100,32000...):"); 975 976 ret = CheckInputName(INPUT_UINT32, (void *)(&attrs.sampleRate)); 977 if (ret < 0) { 978 return HDF_FAILURE; 979 } 980 981 printf("\nPlease input bigEndian(false=0/true=1):"); 982 983 ret = CheckInputName(INPUT_UINT32, (void *)(&attrs.isBigEndian)); 984 if (ret < 0) { 985 return HDF_FAILURE; 986 } 987 if (g_render == NULL || g_render->SetSampleAttributes == NULL) { 988 AUDIO_FUNC_LOGE("Music already complete,Please replay and set the attrbutes!"); 989 SystemInputFail(); 990 return HDF_FAILURE; 991 } 992 993 ret = g_render->SetSampleAttributes((void *)g_render, &attrs); 994 if (ret < 0) { 995 AUDIO_FUNC_LOGE("Set render attributes failed!"); 996 SystemInputFail(); 997 } 998 return ret; 999} 1000 1001static int32_t PrintRenderSelectPinFirst(struct AudioSceneDescriptor *scene) 1002{ 1003 system("clear"); 1004 printf(" ==================== Select Pin ===================== \n"); 1005 printf("| 0. Speaker |\n"); 1006 printf("| 1. HeadPhones |\n"); 1007 printf(" ===================================================== \n"); 1008 1009 printf("Please input your choice:\n"); 1010 int32_t val = 0; 1011 int32_t ret = CheckInputName(INPUT_INT, (void *)&val); 1012 if (ret < 0) { 1013 AUDIO_FUNC_LOGE("Invalid value!"); 1014 SystemInputFail(); 1015 return HDF_FAILURE; 1016 } 1017 1018 if (val == 1) { 1019 scene->desc.pins = PIN_OUT_HEADSET; 1020 } else { 1021 scene->desc.pins = PIN_OUT_SPEAKER; 1022 } 1023 1024 return HDF_SUCCESS; 1025} 1026 1027static int32_t PrintRenderSelectPinSecond(struct AudioSceneDescriptor *scene) 1028{ 1029 system("clear"); 1030 printf(" ==================== Select Pin ===================== \n"); 1031 printf("| 0. Speaker |\n"); 1032 printf("| 1. HeadPhones |\n"); 1033 printf("| 2. Speaker and HeadPhones |\n"); 1034 printf(" ===================================================== \n"); 1035 1036 printf("Please input your choice:\n"); 1037 int32_t val = 0; 1038 int32_t ret = CheckInputName(INPUT_INT, (void *)&val); 1039 if (ret < 0) { 1040 AUDIO_FUNC_LOGE("Invalid value!"); 1041 SystemInputFail(); 1042 return HDF_FAILURE; 1043 } 1044 1045 if (val == 1) { 1046 scene->desc.pins = PIN_OUT_HEADSET; 1047 } else if (val == 0) { 1048 scene->desc.pins = PIN_OUT_SPEAKER; 1049 } else { 1050 scene->desc.pins = PIN_OUT_SPEAKER | PIN_OUT_HEADSET; 1051 } 1052 1053 return HDF_SUCCESS; 1054} 1055 1056static int32_t PrintRenderSelectPinThird(struct AudioSceneDescriptor *scene) 1057{ 1058 system("clear"); 1059 printf(" ==================== Select Pin ===================== \n"); 1060 printf("| 0. Speaker |\n"); 1061 printf("| 1. HeadPhones |\n"); 1062 printf(" ===================================================== \n"); 1063 1064 printf("Please input your choice:\n"); 1065 int32_t val = 0; 1066 int32_t ret = CheckInputName(INPUT_INT, (void *)&val); 1067 if (ret < 0) { 1068 AUDIO_FUNC_LOGE("Invalid value!"); 1069 SystemInputFail(); 1070 return HDF_FAILURE; 1071 } 1072 1073 if (val == 1) { 1074 scene->desc.pins = PIN_OUT_HEADSET; 1075 } else { 1076 scene->desc.pins = PIN_OUT_SPEAKER; 1077 } 1078 1079 return HDF_SUCCESS; 1080} 1081 1082static void SelectSceneMenu(void) 1083{ 1084 printf(" =================== Select Scene ======================== \n"); 1085 printf("0 is Midea. |\n"); 1086 printf("1 is Communication. |\n"); 1087 printf("2 is Ring-Tone. |\n"); 1088 printf("3 is Voice-Call. |\n"); 1089 printf("4 is Mmap. |\n"); 1090 printf(" ========================================================= \n"); 1091} 1092 1093static int32_t SelectRenderScene(struct IAudioRender **render) 1094{ 1095 (void)render; 1096 1097 int32_t val = 0; 1098 struct AudioSceneDescriptor scene; 1099 system("clear"); 1100 SelectSceneMenu(); 1101 printf("Please input your choice:\n"); 1102 1103 int32_t ret = CheckInputName(INPUT_INT, (void *)&val); 1104 if (ret < 0) { 1105 AUDIO_FUNC_LOGE("Invalid value!"); 1106 SystemInputFail(); 1107 return HDF_FAILURE; 1108 } 1109 1110 switch (val) { 1111 case AUDIO_IN_MEDIA: 1112 scene.scene.id = AUDIO_IN_MEDIA; 1113 PrintRenderSelectPinFirst(&scene); 1114 break; 1115 case AUDIO_IN_COMMUNICATION: 1116 scene.scene.id = AUDIO_IN_COMMUNICATION; 1117 PrintRenderSelectPinSecond(&scene); 1118 break; 1119 case AUDIO_IN_RINGTONE: 1120 scene.scene.id = AUDIO_IN_RINGTONE; 1121 scene.desc.pins = PIN_OUT_SPEAKER | PIN_OUT_HEADSET; 1122 break; 1123 case AUDIO_IN_CALL: 1124 scene.scene.id = AUDIO_IN_CALL; 1125 PrintRenderSelectPinThird(&scene); 1126 break; 1127 case AUDIO_MMAP_NOIRQ: 1128 scene.scene.id = AUDIO_MMAP_NOIRQ; 1129 PrintRenderSelectPinFirst(&scene); 1130 break; 1131 default: 1132 break; 1133 } 1134 1135 scene.desc.desc = "mic"; 1136 1137 if (g_render == NULL || g_render->SelectScene == NULL) { 1138 AUDIO_FUNC_LOGE("Music already stop,"); 1139 SystemInputFail(); 1140 return HDF_FAILURE; 1141 } 1142 1143 ret = g_render->SelectScene((void *)g_render, &scene); 1144 if (ret < 0) { 1145 AUDIO_FUNC_LOGE("Select scene fail\n"); 1146 } 1147 return ret; 1148} 1149 1150static int32_t GetExtParams(struct IAudioRender **render) 1151{ 1152 (void)render; 1153 if (g_render == NULL || g_render->GetExtraParams == NULL) { 1154 return HDF_FAILURE; 1155 } 1156 1157 char keyValueList[BUFFER_LEN] = {0}; 1158 1159 int32_t ret = g_render->GetExtraParams((void *)g_render, keyValueList, EXT_PARAMS_MAXLEN); 1160 if (ret < 0) { 1161 AUDIO_FUNC_LOGE("Get EXT params failed!"); 1162 SystemInputFail(); 1163 return HDF_FAILURE; 1164 } 1165 printf("keyValueList = %s\n", keyValueList); 1166 return HDF_SUCCESS; 1167} 1168 1169static int32_t GetRenderMmapPosition(struct IAudioRender **render) 1170{ 1171 (void)render; 1172 1173 if (g_render == NULL || g_render->GetMmapPosition == NULL) { 1174 return HDF_FAILURE; 1175 } 1176 1177 uint64_t frames = 0; 1178 struct AudioTimeStamp time; 1179 time.tvNSec = 0; 1180 time.tvSec = 0; 1181 1182 int32_t ret = g_render->GetMmapPosition((void *)g_render, &frames, &time); 1183 if (ret < 0) { 1184 AUDIO_FUNC_LOGE("Get current Mmap frames Position failed!"); 1185 SystemInputFail(); 1186 return HDF_FAILURE; 1187 } 1188 printf("Now the Position is %" PRIu64 "\n", frames); 1189 return HDF_SUCCESS; 1190} 1191 1192static void PrintMenu2(void) 1193{ 1194 printf(" ================== Play Render Menu ================== \n"); 1195 printf("| 1. Render Start |\n"); 1196 printf("| 2. Render Stop |\n"); 1197 printf("| 3. Render Resume |\n"); 1198 printf("| 4. Render Pause |\n"); 1199 printf("| 5. Render SetVolume |\n"); 1200 printf("| 6. Render GetGain |\n"); 1201 printf("| 7. Render SetMute |\n"); 1202 printf("| 8. Render SetAttributes |\n"); 1203 printf("| 9. Render SelectScene |\n"); 1204 printf("| 10. Render getEXtParams |\n"); 1205 printf("| 11. Render getMmapPosition |\n"); 1206 printf("| 12.Exit |\n"); 1207 printf(" ====================================================== \n"); 1208} 1209 1210static struct ProcessRenderMenuSwitchList g_processRenderMenuSwitchList[] = { 1211 {RENDER_START, PlayingAudioFiles }, 1212 {RENDER_STOP, StopAudioFiles }, 1213 {RENDER_RESUME, SetRenderResume }, 1214 {RENDER_PAUSE, SetRenderPause }, 1215 {SET_RENDER_VOLUME, SetRenderVolume }, 1216 {SET_RENDER_GAIN, GetRenderGain }, 1217 {SET_RENDER_MUTE, SetRenderMute }, 1218 {SET_RENDER_ATTRIBUTES, SetRenderAttributes }, 1219 {SET_RENDER_SLECET_SCENE, SelectRenderScene }, 1220 {GET_RENDER_EXT_PARAMS, GetExtParams }, 1221 {GET_RENDER_POSITION, GetRenderMmapPosition}, 1222}; 1223 1224static void ProcessMenu(int32_t choice) 1225{ 1226 if (choice == GET_RENDER_POSITION + 1) { 1227 return; 1228 } 1229 1230 if (g_render == NULL && choice != 1) { 1231 AUDIO_FUNC_LOGE("This render already release!"); 1232 SystemInputFail(); 1233 return; 1234 } 1235 1236 for (int32_t i = RENDER_START; i <= GET_RENDER_POSITION; ++i) { 1237 if ((choice == (int32_t)g_processRenderMenuSwitchList[i - 1].cmd) && 1238 (g_processRenderMenuSwitchList[i - 1].operation != NULL)) { 1239 g_processRenderMenuSwitchList[i - 1].operation(&g_render); 1240 } 1241 } 1242} 1243 1244static void Choice(void) 1245{ 1246 int32_t choice = 0; 1247 1248 while (choice < GET_RENDER_POSITION + 1 && choice >= 0) { 1249 system("clear"); 1250 PrintMenu2(); 1251 printf("your choice is:\n"); 1252 1253 int32_t ret = CheckInputName(INPUT_INT, (void *)&choice); 1254 if (ret < 0) { 1255 continue; 1256 } 1257 1258 if (choice < RENDER_START || choice > GET_RENDER_POSITION + 1) { 1259 AUDIO_FUNC_LOGE("You input is wrong!"); 1260 choice = 0; 1261 SystemInputFail(); 1262 continue; 1263 } 1264 ProcessMenu(choice); 1265 } 1266} 1267 1268int32_t main(int32_t argc, char const *argv[]) 1269{ 1270 if (argc < 2 || argv == NULL || argv[0] == NULL) { // The parameter number is not greater than 2 1271 printf("usage:[1]sample [2]/data/test.wav\n"); 1272 return 0; 1273 } 1274 1275 if (argv[1] == NULL || strlen(argv[1]) == 0) { 1276 return HDF_FAILURE; 1277 } 1278 1279 int32_t ret = strncpy_s(g_path, PATH_LEN - 1, argv[1], strlen(argv[1]) + 1); 1280 if (ret != 0) { 1281 AUDIO_FUNC_LOGE("strncpy_s Fail!"); 1282 return HDF_FAILURE; 1283 } 1284 1285 char pathBuf[PATH_MAX] = {'\0'}; 1286 if (realpath(g_path, pathBuf) == NULL) { 1287 AUDIO_FUNC_LOGE("realpath Fail!"); 1288 return HDF_FAILURE; 1289 } 1290 1291 if (InitParam() != HDF_SUCCESS) { // init 1292 AUDIO_FUNC_LOGE("InitParam Fail!"); 1293 return HDF_FAILURE; 1294 } 1295 1296 Choice(); 1297 1298 if (g_render != NULL && g_adapter != NULL) { 1299 StopAudioFiles(&g_render); 1300 } 1301 1302 if (g_audioManager != NULL && g_audioManager->UnloadAdapter != NULL) { 1303 g_audioManager->UnloadAdapter(g_audioManager, g_adapterName); 1304 IAudioAdapterRelease(g_adapter, g_isDirect); 1305 g_adapter = NULL; 1306 IAudioManagerRelease(g_audioManager, g_isDirect); 1307 g_audioManager = NULL; 1308 } 1309 return 0; 1310} 1311