1/* 2 * Copyright (c) 2022 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 "alsa_soundcard.h" 17#include <ctype.h> 18#include "cJSON.h" 19 20#define HDF_LOG_TAG HDF_AUDIO_HAL_SND 21 22#define ALSA_CARD_CONFIG_FILE HDF_CONFIG_DIR "/alsa_adapter.json" 23#define ALSA_CONFIG_FILE_MAX (2 * 1024) // 2KB 24#define SUPPORT_CAPTURE_OR_RENDER 1 25#define SUPPORT_CAPTURE_AND_RENDER 2 26#define MALLOC_MAX 100 27 28/* Define structure description alsa_adapter.hson information */ 29struct AlsaAdapterCfgInfo { 30 char adapterName[MAX_CARD_NAME_LEN]; 31 int32_t cardId; 32 char cardName[MAX_CARD_NAME_LEN]; 33}; 34struct AlsaAdapterList { 35 int32_t num; 36 struct AlsaAdapterCfgInfo list[AUDIO_MAX_CARD_NUM]; 37}; 38static struct AlsaAdapterList g_alsaAdapterList[SND_CARD_MAX]; 39 40struct AlsaDevInfo { 41 char cardId[MAX_CARD_NAME_LEN + 1]; 42 char pcmInfoId[MAX_CARD_NAME_LEN + 1]; 43 int32_t card; 44 int32_t device; 45}; 46struct AlsaCardsList { 47 int32_t num; 48 struct AlsaDevInfo alsaDevIns[MAX_CARD_NUM]; 49}; 50static struct AlsaCardsList g_alsaCardsDevList; 51 52 53static char *CfgReadAdapterFile(const char *fpath) 54{ 55 FILE *fp = NULL; 56 char *pJsonStr = NULL; 57 char pathBuf[PATH_MAX] = {0}; 58 59 if (fpath == NULL) { 60 AUDIO_FUNC_LOGE("Parameter is null!!!"); 61 return NULL; 62 } 63 if (realpath(fpath, pathBuf) == NULL) { 64 AUDIO_FUNC_LOGE("File path invalid!"); 65 return NULL; 66 } 67 68 fp = fopen(pathBuf, "r"); 69 if (fp == NULL) { 70 AUDIO_FUNC_LOGE("Can not open config file [ %{public}s ].", fpath); 71 return NULL; 72 } 73 if (fseek(fp, 0, SEEK_END) != 0) { 74 AUDIO_FUNC_LOGE("fseek configuration file error!"); 75 (void)fclose(fp); 76 return NULL; 77 } 78 int32_t jsonStrSize = ftell(fp); 79 if (jsonStrSize <= 0) { 80 AUDIO_FUNC_LOGE("The configuration file size <= 0!"); 81 (void)fclose(fp); 82 return NULL; 83 } 84 rewind(fp); 85 if (jsonStrSize > ALSA_CONFIG_FILE_MAX) { 86 AUDIO_FUNC_LOGE("The configuration file is too large to load!"); 87 (void)fclose(fp); 88 return NULL; 89 } 90 pJsonStr = (char *)OsalMemCalloc((uint32_t)jsonStrSize + 1); 91 if (pJsonStr == NULL) { 92 AUDIO_FUNC_LOGE("OsalMemCalloc pJsonStr failed!"); 93 (void)fclose(fp); 94 return NULL; 95 } 96 if (fread(pJsonStr, jsonStrSize, 1, fp) != 1) { 97 AUDIO_FUNC_LOGE("Read to config file failed!!!"); 98 (void)fclose(fp); 99 AudioMemFree((void **)&pJsonStr); 100 return NULL; 101 } 102 (void)fclose(fp); 103 104 return pJsonStr; 105} 106 107static int32_t CfgGetAdapterCount() 108{ 109 int32_t num = 0; 110 for (enum SndCardType type = SND_CARD_PRIMARY; type < SND_CARD_MAX; ++type) { 111 num += g_alsaAdapterList[type].num; 112 } 113 return num; 114} 115 116static enum SndCardType CfgGetAdapterCardType(const char* adapterName) 117{ 118 if (adapterName == NULL) { 119 return SND_CARD_UNKNOWN; 120 } 121 122 struct AlsaAdapterCfgInfo *info; 123 for (enum SndCardType type = SND_CARD_PRIMARY; type < SND_CARD_MAX; ++type) { 124 for (int32_t i = 0; i < g_alsaAdapterList[type].num; ++i) { 125 info = &g_alsaAdapterList[type].list[i]; 126 if (strncmp(adapterName, info->adapterName, strlen(info->adapterName)) == 0) { 127 return type; 128 } 129 } 130 } 131 return SND_CARD_UNKNOWN; 132} 133 134static int CfgGetAdapterInfo(const char* adapterName, struct AlsaAdapterCfgInfo infos[], int infoLen) 135{ 136 if (adapterName == NULL) { 137 return 0; 138 } 139 140 struct AlsaAdapterCfgInfo *info; 141 int index = 0; 142 for (enum SndCardType type = SND_CARD_PRIMARY; type < SND_CARD_MAX; ++type) { 143 for (int32_t i = 0; i < g_alsaAdapterList[type].num; ++i) { 144 info = &g_alsaAdapterList[type].list[i]; 145 if (strncmp(adapterName, info->adapterName, strlen(info->adapterName)) == 0 146 && index < infoLen) { 147 infos[index++] = *info; 148 } 149 } 150 } 151 return index; 152} 153 154static int32_t CfgDumpAdapterInfo(struct AlsaAdapterCfgInfo *info) 155{ 156 enum SndCardType cardType = SND_CARD_UNKNOWN; 157 CHECK_NULL_PTR_RETURN_DEFAULT(info); 158 159 if (strcmp(info->adapterName, PRIMARY) == 0) { 160 cardType = SND_CARD_PRIMARY; 161 } else if (strcmp(info->adapterName, HDMI) == 0) { 162 cardType = SND_CARD_HDMI; 163 } else if (strcmp(info->adapterName, USB) == 0) { 164 cardType = SND_CARD_USB; 165 } else if (strcmp(info->adapterName, A2DP) == 0) { 166 cardType = SND_CARD_BT; 167 } 168 169 if (cardType == SND_CARD_UNKNOWN) { 170 AUDIO_FUNC_LOGE("Error: %{public}s is unspupported adapter name", info->adapterName); 171 } 172 173 int32_t idx = g_alsaAdapterList[cardType].num; 174 int32_t ret = memcpy_s((void*)&g_alsaAdapterList[cardType].list[idx], sizeof(struct AlsaAdapterCfgInfo), 175 (void*)info, sizeof(struct AlsaAdapterCfgInfo)); 176 if (ret != EOK) { 177 AUDIO_FUNC_LOGE("memcpy_s g_alsaAdapterList fail!"); 178 return HDF_FAILURE; 179 } 180 g_alsaAdapterList[cardType].num++; 181 182 AUDIO_FUNC_LOGI("cardId:%{public}d: adapterName:%{public}s, cardName:%{public}s", 183 g_alsaAdapterList[cardType].list[idx].cardId, 184 g_alsaAdapterList[cardType].list[idx].adapterName, 185 g_alsaAdapterList[cardType].list[idx].cardName); 186 return HDF_SUCCESS; 187} 188 189static int32_t CfgSaveAdapterStruct(cJSON *adapter, struct AlsaAdapterCfgInfo *info) 190{ 191 CHECK_NULL_PTR_RETURN_DEFAULT(adapter); 192 CHECK_NULL_PTR_RETURN_DEFAULT(info); 193 194 cJSON *item = cJSON_GetObjectItem(adapter, "name"); 195 if (item == NULL || item->valuestring == NULL) { 196 AUDIO_FUNC_LOGE("adapter name is null!"); 197 return HDF_FAILURE; 198 } 199 int32_t ret = memcpy_s(info->adapterName, MAX_CARD_NAME_LEN - 1, item->valuestring, MAX_CARD_NAME_LEN - 1); 200 if (ret != EOK) { 201 AUDIO_FUNC_LOGE("memcpy_s adapterName fail!"); 202 return HDF_FAILURE; 203 } 204 205 item = cJSON_GetObjectItem(adapter, "cardId"); 206 if (item == NULL) { 207 AUDIO_FUNC_LOGE("cardId not set!"); 208 return HDF_FAILURE; 209 } 210 info->cardId = item->valuedouble; 211 212 item = cJSON_GetObjectItem(adapter, "cardName"); 213 if (item == NULL || item->valuestring == NULL) { 214 AUDIO_FUNC_LOGE("cardName is null!"); 215 return HDF_FAILURE; 216 } 217 ret = memcpy_s(info->cardName, MAX_CARD_NAME_LEN - 1, item->valuestring, MAX_CARD_NAME_LEN - 1); 218 if (ret != EOK) { 219 AUDIO_FUNC_LOGE("memcpy_s cardName fail!"); 220 return HDF_FAILURE; 221 } 222 223 return HDF_SUCCESS; 224} 225 226static int32_t CfgParseAdapterItems(cJSON *adapterObj) 227{ 228 cJSON *adapterItems = NULL; 229 230 adapterItems = cJSON_GetObjectItem(adapterObj, "adapters"); 231 if (adapterItems == NULL) { 232 AUDIO_FUNC_LOGE("Get adapterItems from json failed!\n"); 233 return HDF_FAILURE; 234 } 235 int32_t adapterNum = cJSON_GetArraySize(adapterItems); 236 if (adapterNum <= 0) { 237 AUDIO_FUNC_LOGE("Get adapter number failed!"); 238 return HDF_FAILURE; 239 } else if (adapterNum > MAX_CARD_NUM) { 240 AUDIO_FUNC_LOGE("Read adapters number is %{public}d over max num %{public}d!", adapterNum, MAX_CARD_NUM); 241 return HDF_FAILURE; 242 } 243 244 for (int32_t i = 0; i < adapterNum; ++i) { 245 cJSON *adapter; 246 struct AlsaAdapterCfgInfo info; 247 adapter = cJSON_GetArrayItem(adapterItems, i); 248 if (adapter == NULL) { 249 AUDIO_FUNC_LOGE("Get adapter item from array failed!"); 250 } 251 252 int32_t ret = CfgSaveAdapterStruct(adapter, &info); 253 if (ret != HDF_SUCCESS) { 254 AUDIO_FUNC_LOGE("CfgSaveAdapterStruct failed!"); 255 return HDF_FAILURE; 256 } 257 258 ret = CfgDumpAdapterInfo(&info); 259 if (ret != HDF_SUCCESS) { 260 AUDIO_FUNC_LOGE("CfgDumpAdapterInfo failed!"); 261 return HDF_FAILURE; 262 } 263 } 264 265 return HDF_SUCCESS; 266} 267 268int32_t CfgSaveAdapterFromFile(void) 269{ 270 cJSON *adapterObj = NULL; 271 char *configBuf = NULL; 272 273 configBuf = CfgReadAdapterFile(ALSA_CARD_CONFIG_FILE); 274 if (configBuf == NULL) { 275 AUDIO_FUNC_LOGE("CfgReadAdapterFile failed!"); 276 return HDF_FAILURE; 277 } 278 adapterObj = cJSON_Parse(configBuf); 279 if (adapterObj == NULL) { 280 AUDIO_FUNC_LOGE("Parse json file failed!"); 281 AudioMemFree((void **)&configBuf); 282 return HDF_FAILURE; 283 } 284 AudioMemFree((void **)&configBuf); 285 286 int32_t ret = CfgParseAdapterItems(adapterObj); 287 if (ret != HDF_SUCCESS) { 288 cJSON_Delete(adapterObj); 289 AUDIO_FUNC_LOGE("Parse adapter items failed!"); 290 return HDF_FAILURE; 291 } 292 293 cJSON_Delete(adapterObj); 294 return HDF_SUCCESS; 295} 296 297static struct AlsaDevInfo *DevGetInfoByAdapter(struct AlsaAdapterCfgInfo infos[], int32_t size) 298{ 299 struct AlsaDevInfo *info = NULL; 300 int num = g_alsaCardsDevList.num; 301 for (int i = 0; i < num; ++i) { 302 info = &g_alsaCardsDevList.alsaDevIns[i]; 303 for (int j = 0; j < size; ++j) { 304 if (info->card == infos[j].cardId) { 305 return info; 306 } 307 } 308 } 309 return NULL; 310} 311 312static struct AlsaDevInfo *DevGetInfoByPcmInfoId(const char * name) 313{ 314 struct AlsaDevInfo *info = NULL; 315 int num = g_alsaCardsDevList.num; 316 for (int i = 0; i < num; ++i) { 317 info = &g_alsaCardsDevList.alsaDevIns[i]; 318 if (strcmp(name, info->pcmInfoId) == 0) { 319 return info; 320 } 321 } 322 323 return NULL; 324} 325 326static int32_t DevSaveCardPcmInfo(snd_ctl_t *handle, snd_pcm_stream_t stream, int card, const char *deviceName) 327{ 328 int pcmDev = -1; 329 snd_ctl_card_info_t *info = NULL; 330 snd_pcm_info_t *pcminfo = NULL; 331 snd_ctl_card_info_alloca(&info); 332 snd_pcm_info_alloca(&pcminfo); 333 334 if (snd_ctl_card_info(handle, info) != 0) { 335 AUDIO_FUNC_LOGE("snd_ctl_card_info failed."); 336 return HDF_FAILURE; 337 } 338 if (snd_ctl_pcm_next_device(handle, &pcmDev) < 0 || pcmDev < 0) { 339 AUDIO_FUNC_LOGE("No pcm device found"); 340 return HDF_FAILURE; 341 } 342 while (pcmDev >= 0) { 343 snd_pcm_info_set_device(pcminfo, pcmDev); 344 snd_pcm_info_set_subdevice(pcminfo, 0); 345 snd_pcm_info_set_stream(pcminfo, stream); 346 int32_t ret = snd_ctl_pcm_info(handle, pcminfo); 347 if (ret < 0) { 348 if (ret != -ENOENT) { 349 AUDIO_FUNC_LOGE("control digital audio info (%{public}d)", pcmDev); 350 } 351 } else { 352 struct AlsaDevInfo *devInfo = &g_alsaCardsDevList.alsaDevIns[g_alsaCardsDevList.num]; 353 const char *cardId = snd_ctl_card_info_get_id(info); 354 const char *pcmInfoId = snd_pcm_info_get_id(pcminfo); 355 AUDIO_FUNC_LOGD("alsa cardName: %{public}s, pcmInfoId %{public}s", cardId, pcmInfoId); 356 devInfo->card = card; 357 devInfo->device = pcmDev; 358 if (strncpy_s(devInfo->cardId, MAX_CARD_NAME_LEN + 1, cardId, strlen(cardId)) != 0) { 359 AUDIO_FUNC_LOGE("strncpy_s failed!"); 360 return HDF_FAILURE; 361 } 362 if (strncpy_s(devInfo->pcmInfoId, MAX_CARD_NAME_LEN + 1, pcmInfoId, strlen(pcmInfoId)) != 0) { 363 AUDIO_FUNC_LOGE("strncpy_s failed!"); 364 return HDF_FAILURE; 365 } 366 g_alsaCardsDevList.num++; 367 } 368 369 if (snd_ctl_pcm_next_device(handle, &pcmDev) < 0) { 370 AUDIO_FUNC_LOGE("snd_ctl_pcm_next_device error!"); 371 return HDF_FAILURE; 372 } 373 AUDIO_FUNC_LOGD("soundcard pcm device number: %{public}d.", pcmDev); 374 } 375 return HDF_SUCCESS; 376} 377 378static int32_t DevSaveDriverInfo(snd_pcm_stream_t stream) 379{ 380 snd_ctl_t *handle = NULL; 381 int card = -1; 382 char deviceName[MAX_CARD_NAME_LEN] = {0}; 383 384 int32_t ret = snd_card_next(&card); 385 if (ret < 0 || card < 0) { 386 AUDIO_FUNC_LOGE("No soundcards found: %{public}s.", snd_strerror(ret)); 387 return HDF_FAILURE; 388 } 389 390 while (card >= 0) { 391 (void)memset_s(deviceName, MAX_CARD_NAME_LEN, 0, MAX_CARD_NAME_LEN); 392 ret = snprintf_s(deviceName, MAX_CARD_NAME_LEN, MAX_CARD_NAME_LEN - 1, "hw:%d", card); 393 if (ret < 0) { 394 AUDIO_FUNC_LOGE("snprintf_s failed"); 395 snd_ctl_close(handle); 396 return HDF_FAILURE; 397 } 398 399 ret = snd_ctl_open(&handle, deviceName, 0); 400 if (ret != 0) { 401 AUDIO_FUNC_LOGE("snd_ctl_open failed."); 402 return HDF_FAILURE; 403 } 404 405 ret = DevSaveCardPcmInfo(handle, stream, card, deviceName); 406 if (ret != HDF_SUCCESS) { 407 AUDIO_FUNC_LOGE("save alsa sound cards %{public}s pcm info failed!", deviceName); 408 } 409 410 ret = snd_ctl_close(handle); 411 if (ret < 0) { 412 AUDIO_FUNC_LOGE("snd_ctl_close error: %{public}s.", snd_strerror(ret)); 413 return HDF_FAILURE; 414 } 415 416 ret = snd_card_next(&card); 417 if (ret < 0) { 418 AUDIO_FUNC_LOGE("snd_card_next error: %{public}s", snd_strerror(ret)); 419 return HDF_FAILURE; 420 } 421 } 422 423 return HDF_SUCCESS; 424} 425 426int32_t SndSaveCardListInfo(snd_pcm_stream_t stream) 427{ 428 (void)memset_s(&g_alsaAdapterList, sizeof(struct AlsaAdapterList) * SND_CARD_MAX, 429 0, sizeof(struct AlsaAdapterList) * SND_CARD_MAX); 430 (void)memset_s(&g_alsaCardsDevList, sizeof(struct AlsaCardsList), 431 0, sizeof(struct AlsaCardsList)); 432 433 /* Parse sound card from configuration file */ 434 int32_t ret = CfgSaveAdapterFromFile(); 435 if (ret != HDF_SUCCESS) { 436 AUDIO_FUNC_LOGE("parse config file failed! ret = %{public}d", ret); 437 return HDF_FAILURE; 438 } 439 440 /* Read sound card list from alsa hardware */ 441 ret = DevSaveDriverInfo(stream); 442 if (ret != HDF_SUCCESS) { 443 AUDIO_FUNC_LOGE("failed to save alsa sound cards driver info"); 444 return HDF_FAILURE; 445 } 446 447 /* if the alsa hardware include usb then add to adapter list */ 448 struct AlsaDevInfo *devInfo = DevGetInfoByPcmInfoId(USB); 449 if (devInfo != NULL) { 450 g_alsaAdapterList[SND_CARD_USB].num = 1; 451 ret = memcpy_s((void*)&g_alsaAdapterList[SND_CARD_USB].list[0].adapterName, MAX_CARD_NAME_LEN, 452 USB, sizeof(USB)); 453 if (ret != EOK) { 454 AUDIO_FUNC_LOGE("memcpy_s adapterName fail!"); 455 return HDF_FAILURE; 456 } 457 } 458 459 return HDF_SUCCESS; 460} 461 462int32_t SndMatchSelAdapter(struct AlsaSoundCard *cardIns, const char *adapterName) 463{ 464 struct AlsaDevInfo *devInfo = NULL; 465 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns); 466 CHECK_NULL_PTR_RETURN_DEFAULT(adapterName); 467 468 enum SndCardType cardType = CfgGetAdapterCardType(adapterName); 469 if (cardType == SND_CARD_UNKNOWN) { 470 AUDIO_FUNC_LOGE("unknow card type error."); 471 return HDF_FAILURE; 472 } 473 cardIns->cardType = cardType; 474 475 struct AlsaAdapterCfgInfo adapterInfos[g_alsaAdapterList[cardType].num]; 476 int32_t num = CfgGetAdapterInfo(adapterName, adapterInfos, g_alsaAdapterList[cardType].num); 477 if (num == 0) { 478 AUDIO_FUNC_LOGE("adapter %{public}s is not exits.", cardIns->adapterName); 479 return HDF_FAILURE; 480 } 481 482 devInfo = DevGetInfoByAdapter(adapterInfos, num); 483 if (devInfo == NULL) { 484 AUDIO_FUNC_LOGE("adapter %{public}s cant not find sound card device.", cardIns->adapterName); 485 return HDF_FAILURE; 486 } 487 488 int32_t ret = snprintf_s(cardIns->devName, MAX_CARD_NAME_LEN, MAX_CARD_NAME_LEN - 1, 489 "hw:%d,%d", devInfo->card, devInfo->device); 490 if (ret < 0) { 491 AUDIO_FUNC_LOGE("%{public}s snprintf_s devName failed", cardIns->adapterName); 492 return HDF_FAILURE; 493 } 494 ret = snprintf_s(cardIns->ctrlName, MAX_CARD_NAME_LEN, MAX_CARD_NAME_LEN - 1, "hw:%d", devInfo->card); 495 if (ret < 0) { 496 AUDIO_FUNC_LOGE("%{public}s snprintf_s ctrlName failed", cardIns->adapterName); 497 return HDF_FAILURE; 498 } 499 ret = snprintf_s(cardIns->alsaCardId, MAX_CARD_NAME_LEN, MAX_CARD_NAME_LEN - 1, "%s", devInfo->cardId); 500 if (ret < 0) { 501 AUDIO_FUNC_LOGE("%{public}s snprintf_s alsaCardId failed", cardIns->adapterName); 502 return HDF_FAILURE; 503 } 504 505 return HDF_SUCCESS; 506} 507 508int32_t SndConverAlsaPcmFormat(const struct AudioPcmHwParams *hwParams, snd_pcm_format_t *alsaPcmFormat) 509{ 510 CHECK_NULL_PTR_RETURN_DEFAULT(hwParams); 511 CHECK_NULL_PTR_RETURN_DEFAULT(alsaPcmFormat); 512 enum AudioFormat audioFormat = hwParams->format; 513 bool isBigEndian = hwParams->isBigEndian; 514 515 /** Little Endian */ 516 if (!isBigEndian) { 517 switch (audioFormat) { 518 case AUDIO_FORMAT_TYPE_PCM_8_BIT: 519 *alsaPcmFormat = SND_PCM_FORMAT_S8; /** Signed 8 bit */ 520 break; 521 case AUDIO_FORMAT_TYPE_PCM_16_BIT: 522 *alsaPcmFormat = SND_PCM_FORMAT_S16_LE; /** Signed 16 bit Little Endian */ 523 break; 524 case AUDIO_FORMAT_TYPE_PCM_24_BIT: 525 *alsaPcmFormat = SND_PCM_FORMAT_S24_LE; /** Signed 24 bit Little Endian */ 526 break; 527 case AUDIO_FORMAT_TYPE_PCM_32_BIT: 528 *alsaPcmFormat = SND_PCM_FORMAT_S32_LE; /** Signed 32 bit Little Endian */ 529 break; 530 default: 531 AUDIO_FUNC_LOGE("not support format %{public}d", audioFormat); 532 return HDF_ERR_NOT_SUPPORT; 533 } 534 } else { /** Big Endian */ 535 switch (audioFormat) { 536 case AUDIO_FORMAT_TYPE_PCM_8_BIT: 537 *alsaPcmFormat = SND_PCM_FORMAT_S8; /** Signed 8 bit */ 538 break; 539 case AUDIO_FORMAT_TYPE_PCM_16_BIT: 540 *alsaPcmFormat = SND_PCM_FORMAT_S16_BE; /** Signed 16 bit Big Endian */ 541 break; 542 case AUDIO_FORMAT_TYPE_PCM_24_BIT: 543 *alsaPcmFormat = SND_PCM_FORMAT_S24_BE; /** Signed 24 bit Big Endian */ 544 break; 545 case AUDIO_FORMAT_TYPE_PCM_32_BIT: 546 *alsaPcmFormat = SND_PCM_FORMAT_S32_BE; /** Signed 32 bit Big Endian */ 547 break; 548 default: 549 AUDIO_FUNC_LOGE("not support format %{public}d", audioFormat); 550 return HDF_ERR_NOT_SUPPORT; 551 } 552 } 553 554 return HDF_SUCCESS; 555} 556 557int32_t SndPcmPrepare(struct AlsaSoundCard *cardIns) 558{ 559 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns); 560 int32_t ret = snd_pcm_prepare(cardIns->pcmHandle); 561 if (ret < 0) { 562 AUDIO_FUNC_LOGE("snd_pcm_prepare fail: %{public}s", snd_strerror(ret)); 563 return HDF_FAILURE; 564 } 565 return HDF_SUCCESS; 566} 567 568bool SndisBusy(struct AlsaSoundCard *cardIns) 569{ 570 if (cardIns == NULL) { 571 return false; 572 } 573 return (cardIns->pcmHandle == NULL) ? false : true; 574} 575 576int32_t SndOpenMixer(struct AlsaSoundCard *cardIns) 577{ 578 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns); 579 580 if (strlen(cardIns->ctrlName) == 0) { 581 AUDIO_FUNC_LOGE("The soundcard ctrname is null."); 582 return HDF_FAILURE; 583 } 584 585 int32_t ret = snd_mixer_open(&cardIns->mixerHandle, 0); 586 if (ret < 0) { 587 AUDIO_FUNC_LOGE("Failed to open mixer: %{public}s.", snd_strerror(ret)); 588 return HDF_FAILURE; 589 } 590 591 ret = snd_mixer_attach(cardIns->mixerHandle, cardIns->ctrlName); 592 if (ret < 0) { 593 AUDIO_FUNC_LOGE("Failed to attach mixer: %{public}s.", snd_strerror(ret)); 594 ret = snd_mixer_close(cardIns->mixerHandle); 595 if (ret < 0) { 596 AUDIO_FUNC_LOGE("mixer close error: %{public}s.", snd_strerror(ret)); 597 } 598 cardIns->mixerHandle = NULL; 599 return HDF_FAILURE; 600 } 601 602 ret = snd_mixer_selem_register(cardIns->mixerHandle, NULL, NULL); 603 if (ret < 0) { 604 AUDIO_FUNC_LOGE("Failed to register mixer element: %{public}s.", snd_strerror(ret)); 605 ret = snd_mixer_close(cardIns->mixerHandle); 606 if (ret < 0) { 607 AUDIO_FUNC_LOGE("mixer close error: %{public}s.", snd_strerror(ret)); 608 } 609 cardIns->mixerHandle = NULL; 610 return HDF_FAILURE; 611 } 612 613 ret = snd_mixer_load(cardIns->mixerHandle); 614 if (ret < 0) { 615 AUDIO_FUNC_LOGE("Failed to load mixer element: %{public}s.", snd_strerror(ret)); 616 ret = snd_mixer_close(cardIns->mixerHandle); 617 if (ret < 0) { 618 AUDIO_FUNC_LOGE("mixer close error: %{public}s.", snd_strerror(ret)); 619 } 620 cardIns->mixerHandle = NULL; 621 return HDF_FAILURE; 622 } 623 return HDF_SUCCESS; 624} 625 626snd_pcm_state_t SndGetRunState(struct AlsaSoundCard * cardIns) 627{ 628 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns); 629 return snd_pcm_state(cardIns->pcmHandle); 630} 631 632void SndCloseHandle(struct AlsaSoundCard *cardIns) 633{ 634 if (cardIns == NULL) { 635 AUDIO_FUNC_LOGE("cardIns is NULL"); 636 return; 637 } 638 if (cardIns->cardStatus > 0) { 639 cardIns->cardStatus -= 1; 640 } 641 if (cardIns->cardStatus == 0) { 642 int32_t ret; 643 if (cardIns->pcmHandle != NULL) { 644 ret = snd_pcm_close(cardIns->pcmHandle); 645 if (ret < 0) { 646 AUDIO_FUNC_LOGE("snd_pcm_close fail: %{public}s", snd_strerror(ret)); 647 } 648 cardIns->pcmHandle = NULL; 649 } 650 if (cardIns->mixerHandle != NULL) { 651 ret = snd_mixer_close(cardIns->mixerHandle); 652 if (ret < 0) { 653 AUDIO_FUNC_LOGE("mixer close error: %{public}s.", snd_strerror(ret)); 654 } 655 cardIns->mixerHandle = NULL; 656 } 657 (void)memset_s(cardIns, sizeof(struct AlsaSoundCard), 0, sizeof(struct AlsaSoundCard)); 658 } 659} 660 661static void AudioInitPortOut(struct AudioPort *audioPort) 662{ 663 audioPort->dir = PORT_OUT; 664 audioPort->portId = 0; 665 audioPort->portName = strdup("AOP"); 666} 667 668static void AudioInitPortIn(struct AudioPort *audioPort) 669{ 670 audioPort->dir = PORT_IN; 671 audioPort->portId = 0; 672 audioPort->portName = strdup("AIP"); 673} 674 675static void AudioInitPortOutAndIn(struct AudioPort *audioPort) 676{ 677 audioPort->dir = PORT_OUT_IN; 678 audioPort->portId = 0; 679 audioPort->portName = strdup("AIOP"); 680} 681 682static int32_t AudioInitPorts(struct AudioAdapterDescriptor *desc, enum SndCardType type) 683{ 684 uint8_t portNum = 0; 685 CHECK_NULL_PTR_RETURN_DEFAULT(desc); 686 687 switch (type) { 688 case SND_CARD_PRIMARY: 689 portNum = PORT_OUT_IN; 690 break; 691 case SND_CARD_HDMI: 692 portNum = PORT_OUT; 693 break; 694 case SND_CARD_USB: 695 portNum = PORT_IN; 696 break; 697 default: 698 AUDIO_FUNC_LOGE("Unknown sound card type does not support this sound card temporarily!"); 699 return HDF_FAILURE; 700 } 701 702#ifndef AUDIO_HDI_SERVICE_MODE 703 desc->portNum = portNum; 704#else 705 desc->portsLen = portNum; 706#endif 707 if (portNum == 0) { 708 AUDIO_FUNC_LOGE("portNum is zero"); 709 return HDF_FAILURE; 710 } 711 desc->ports = (struct AudioPort *)OsalMemCalloc(sizeof(struct AudioPort) * portNum); 712 if (desc->ports == NULL) { 713 AUDIO_FUNC_LOGE("OsalMemCalloc failed!"); 714 return HDF_ERR_MALLOC_FAIL; 715 } 716 717 if (type == SND_CARD_PRIMARY) { 718 AudioInitPortOut(&desc->ports[0]); 719 AudioInitPortIn(&desc->ports[SUPPORT_CAPTURE_OR_RENDER]); 720 AudioInitPortOutAndIn(&desc->ports[SUPPORT_CAPTURE_AND_RENDER]); 721 } else if (type == SND_CARD_HDMI) { 722 AudioInitPortOut(&desc->ports[0]); 723 } else if (type == SND_CARD_USB) { 724 AudioInitPortOut(&desc->ports[0]); 725 AudioInitPortIn(&desc->ports[SUPPORT_CAPTURE_OR_RENDER]); 726 } else { 727 AUDIO_FUNC_LOGE("adapter list not support sound card type %{public}d", type); 728 return HDF_FAILURE; 729 } 730 731 return HDF_SUCCESS; 732} 733 734int32_t AudioGetAllCardInfo(struct AudioAdapterDescriptor **descs, int32_t *sndCardNum) 735{ 736 CHECK_NULL_PTR_RETURN_DEFAULT(descs); 737 CHECK_NULL_PTR_RETURN_DEFAULT(sndCardNum); 738 739 int32_t ret = SndSaveCardListInfo(SND_PCM_STREAM_PLAYBACK); 740 if (ret != HDF_SUCCESS) { 741 return HDF_FAILURE; 742 } 743 744 int32_t adapterNum = CfgGetAdapterCount(); 745 if (*descs == NULL && adapterNum > 0 && adapterNum < MALLOC_MAX) { 746 AUDIO_FUNC_LOGW("*descs is null, need memcalloc."); 747 *descs = (struct AudioAdapterDescriptor *)OsalMemCalloc(sizeof(struct AudioAdapterDescriptor) * adapterNum); 748 if (*descs == NULL) { 749 AUDIO_FUNC_LOGE("OsalMemCalloc descs is NULL"); 750 return HDF_ERR_MALLOC_FAIL; 751 } 752 } 753 *sndCardNum = adapterNum; 754 755 int32_t idx = 0; 756 for (enum SndCardType type = SND_CARD_PRIMARY; type < SND_CARD_MAX; ++type) { 757 for (int32_t i = 0; i < g_alsaAdapterList[type].num; ++i) { 758 (*descs)[idx].adapterName = strdup(g_alsaAdapterList[type].list[i].adapterName); 759 AudioInitPorts(&(*descs)[idx], type); 760 AUDIO_FUNC_LOGI("adapter name : %{public}s", (*descs)[idx].adapterName); 761 idx++; 762 } 763 } 764 765 return HDF_SUCCESS; 766} 767 768struct HdfIoService *HdfIoServiceBindName(const char *serviceName) 769{ 770 (void)serviceName; 771 /* Nothing to do */ 772 static struct HdfIoService hdfIoService; 773 return &hdfIoService; 774} 775 776struct DevHandle *AudioBindService(const char *name) 777{ 778 struct DevHandle *handle = NULL; 779 780 if (name == NULL) { 781 AUDIO_FUNC_LOGE("service name NULL!"); 782 return NULL; 783 } 784 785 handle = (struct DevHandle *)OsalMemCalloc(sizeof(struct DevHandle)); 786 if (handle == NULL) { 787 AUDIO_FUNC_LOGE("OsalMemCalloc handle failed!!!"); 788 return NULL; 789 } 790 791 AUDIO_FUNC_LOGI("BIND SERVICE SUCCESS!"); 792 return handle; 793} 794 795void AudioCloseService(const struct DevHandle *handle) 796{ 797 if (handle != NULL) { 798 AudioMemFree((void **)&handle); 799 } 800} 801 802void SndElementItemInit(struct AlsaMixerCtlElement *m) 803{ 804 m->iface = IFACE_MIXER; 805 m->index = 0; 806 m->device = 0; 807 m->subdevice = 0; 808} 809 810static snd_ctl_elem_iface_t ConvertIfaceType(enum SndIfaceType iface) 811{ 812 snd_ctl_elem_iface_t snd_iface; 813 switch (iface) { 814 case IFACE_CARD: 815 snd_iface = SND_CTL_ELEM_IFACE_CARD; 816 break; 817 case IFACE_MIXER: 818 snd_iface = SND_CTL_ELEM_IFACE_MIXER; 819 break; 820 case IFACE_PCM: 821 snd_iface = SND_CTL_ELEM_IFACE_PCM; 822 break; 823 case IFACE_RAWMIDI: 824 snd_iface = SND_CTL_ELEM_IFACE_RAWMIDI; 825 break; 826 case IFACE_TIMER: 827 snd_iface = SND_CTL_ELEM_IFACE_TIMER; 828 break; 829 case IFACE_SEQUENCER: 830 snd_iface = SND_CTL_ELEM_IFACE_SEQUENCER; 831 break; 832 default: 833 snd_iface = SND_CTL_ELEM_IFACE_MIXER; 834 break; 835 } 836 return snd_iface; 837} 838 839static int32_t SetElementInfo(snd_ctl_t *alsaHandle, const struct AlsaMixerCtlElement *ctlElem, 840 snd_ctl_elem_info_t *info, snd_ctl_elem_id_t *id) 841{ 842 CHECK_NULL_PTR_RETURN_DEFAULT(alsaHandle); 843 CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem); 844 CHECK_NULL_PTR_RETURN_DEFAULT(info); 845 CHECK_NULL_PTR_RETURN_DEFAULT(id); 846 847 if (ctlElem->numid >= 0) { 848 snd_ctl_elem_id_set_numid(id, ctlElem->numid); 849 } 850 if (ctlElem->index >= 0) { 851 snd_ctl_elem_id_set_index(id, ctlElem->index); 852 } 853 if (ctlElem->device >= 0) { 854 snd_ctl_elem_id_set_device(id, ctlElem->device); 855 } 856 if (ctlElem->subdevice >= 0) { 857 snd_ctl_elem_id_set_subdevice(id, ctlElem->subdevice); 858 } 859 860 snd_ctl_elem_iface_t ifaceType = ConvertIfaceType(ctlElem->iface); 861 snd_ctl_elem_id_set_interface(id, ifaceType); 862 if (ctlElem->name) { 863 snd_ctl_elem_id_set_name(id, ctlElem->name); 864 } 865 snd_ctl_elem_info_set_id(info, id); 866 int32_t ret = snd_ctl_elem_info(alsaHandle, info); 867 if (ret < 0) { 868 AUDIO_FUNC_LOGE("Cannot find the given element from elem_value\n"); 869 return HDF_FAILURE; 870 } 871 snd_ctl_elem_info_get_id(info, id); 872 873 return HDF_SUCCESS; 874} 875 876int32_t SndElementReadInt(struct AlsaSoundCard *cardIns, 877 const struct AlsaMixerCtlElement *ctlElem, long *value) 878{ 879 snd_ctl_t *alsaHandle = NULL; 880 snd_ctl_elem_id_t *elem_id = NULL; 881 snd_ctl_elem_info_t *elem_info = NULL; 882 snd_ctl_elem_value_t *elem_value = NULL; 883 884 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns); 885 CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem); 886 887 int ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0); 888 if (ret < 0) { 889 AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret)); 890 return HDF_FAILURE; 891 } 892 893 snd_ctl_elem_id_alloca(&elem_id); 894 snd_ctl_elem_info_alloca(&elem_info); 895 snd_ctl_elem_value_alloca(&elem_value); 896 ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id); 897 if (ret != HDF_SUCCESS) { 898 AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name); 899 return HDF_FAILURE; 900 } 901 snd_ctl_elem_value_set_id(elem_value, elem_id); 902 903 if (!snd_ctl_elem_info_is_readable(elem_info)) { 904 AUDIO_FUNC_LOGE("Element read enable\n"); 905 return HDF_FAILURE; 906 } 907 ret = snd_ctl_elem_read(alsaHandle, elem_value); 908 if (ret < 0) { 909 AUDIO_FUNC_LOGE("Cannot read the given element from elem_value \n"); 910 return HDF_FAILURE; 911 } 912 913 snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(elem_info); 914 if (type == SND_CTL_ELEM_TYPE_INTEGER) { 915 *value = snd_ctl_elem_value_get_integer(elem_value, 0); 916 } else if (type == SND_CTL_ELEM_TYPE_INTEGER64) { 917 *value = (long)snd_ctl_elem_value_get_integer64(elem_value, 0); 918 } else { 919 AUDIO_FUNC_LOGE("Element type is not interger\n"); 920 return HDF_FAILURE; 921 } 922 923 return HDF_SUCCESS; 924} 925 926int32_t SndElementReadEnum( 927 struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem, unsigned int *item) 928{ 929 snd_ctl_t *alsaHandle = NULL; 930 snd_ctl_elem_id_t *elem_id = NULL; 931 snd_ctl_elem_info_t *elem_info = NULL; 932 snd_ctl_elem_value_t *elem_value = NULL; 933 934 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns); 935 CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem); 936 937 int ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0); 938 if (ret < 0) { 939 AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret)); 940 return HDF_FAILURE; 941 } 942 943 snd_ctl_elem_id_alloca(&elem_id); 944 snd_ctl_elem_info_alloca(&elem_info); 945 snd_ctl_elem_value_alloca(&elem_value); 946 ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id); 947 if (ret != HDF_SUCCESS) { 948 AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name); 949 return HDF_FAILURE; 950 } 951 snd_ctl_elem_value_set_id(elem_value, elem_id); 952 953 if (!snd_ctl_elem_info_is_readable(elem_info)) { 954 AUDIO_FUNC_LOGE("Element read enable\n"); 955 return HDF_FAILURE; 956 } 957 ret = snd_ctl_elem_read(alsaHandle, elem_value); 958 if (ret < 0) { 959 AUDIO_FUNC_LOGE("Cannot read the given element from elem_value \n"); 960 return HDF_FAILURE; 961 } 962 963 snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(elem_info); 964 if (type == SND_CTL_ELEM_TYPE_ENUMERATED) { 965 *item = snd_ctl_elem_value_get_enumerated(elem_value, 0); 966 } else { 967 AUDIO_FUNC_LOGE("Element type is not enumerated\n"); 968 return HDF_FAILURE; 969 } 970 971 return HDF_SUCCESS; 972} 973 974int32_t SndElementReadRange( 975 struct AlsaSoundCard * cardIns, const struct AlsaMixerCtlElement * ctlElem, long * mix, long * max) 976{ 977 snd_ctl_t *alsaHandle = NULL; 978 snd_ctl_elem_id_t *elem_id = NULL; 979 snd_ctl_elem_info_t *elem_info = NULL; 980 snd_ctl_elem_value_t *elem_value = NULL; 981 982 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns); 983 CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem); 984 985 int ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0); 986 if (ret < 0) { 987 AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret)); 988 return HDF_FAILURE; 989 } 990 991 snd_ctl_elem_id_alloca(&elem_id); 992 snd_ctl_elem_info_alloca(&elem_info); 993 snd_ctl_elem_value_alloca(&elem_value); 994 ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id); 995 if (ret != HDF_SUCCESS) { 996 AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name); 997 return HDF_FAILURE; 998 } 999 snd_ctl_elem_value_set_id(elem_value, elem_id); 1000 1001 if (!snd_ctl_elem_info_is_readable(elem_info)) { 1002 AUDIO_FUNC_LOGE("Element read enable\n"); 1003 return HDF_FAILURE; 1004 } 1005 ret = snd_ctl_elem_read(alsaHandle, elem_value); 1006 if (ret < 0) { 1007 AUDIO_FUNC_LOGE("Cannot read the given element from elem_value \n"); 1008 return HDF_FAILURE; 1009 } 1010 1011 snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(elem_info); 1012 if (type == SND_CTL_ELEM_TYPE_INTEGER) { 1013 *mix = snd_ctl_elem_info_get_min(elem_info); 1014 *max = snd_ctl_elem_info_get_max(elem_info); 1015 } else if (type == SND_CTL_ELEM_TYPE_INTEGER64) { 1016 *mix = (long)snd_ctl_elem_info_get_min64(elem_info); 1017 *max = (long)snd_ctl_elem_info_get_max64(elem_info); 1018 } else { 1019 AUDIO_FUNC_LOGE("Element value is not integer type!\n"); 1020 return HDF_FAILURE; 1021 } 1022 1023 return HDF_SUCCESS; 1024} 1025 1026int32_t SndElementReadSwitch( 1027 struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem, bool *on) 1028{ 1029 snd_ctl_t *alsaHandle = NULL; 1030 snd_ctl_elem_id_t *elem_id = NULL; 1031 snd_ctl_elem_info_t *elem_info = NULL; 1032 snd_ctl_elem_value_t *elem_value = NULL; 1033 1034 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns); 1035 CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem); 1036 1037 int ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0); 1038 if (ret < 0) { 1039 AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret)); 1040 return HDF_FAILURE; 1041 } 1042 1043 snd_ctl_elem_id_alloca(&elem_id); 1044 snd_ctl_elem_info_alloca(&elem_info); 1045 snd_ctl_elem_value_alloca(&elem_value); 1046 ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id); 1047 if (ret != HDF_SUCCESS) { 1048 AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name); 1049 return HDF_FAILURE; 1050 } 1051 snd_ctl_elem_value_set_id(elem_value, elem_id); 1052 1053 if (!snd_ctl_elem_info_is_readable(elem_info)) { 1054 AUDIO_FUNC_LOGE("Element read enable\n"); 1055 return HDF_FAILURE; 1056 } 1057 ret = snd_ctl_elem_read(alsaHandle, elem_value); 1058 if (ret < 0) { 1059 AUDIO_FUNC_LOGE("Cannot read the given element from elem_value \n"); 1060 return HDF_FAILURE; 1061 } 1062 1063 snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(elem_info); 1064 if (type == SND_CTL_ELEM_TYPE_BOOLEAN) { 1065 ret = snd_ctl_elem_value_get_boolean(elem_value, 0); 1066 *on = (ret > 0) ? true : false; 1067 } else { 1068 AUDIO_FUNC_LOGE("Element type is not boolean\n"); 1069 return HDF_FAILURE; 1070 } 1071 1072 return HDF_SUCCESS; 1073} 1074 1075int32_t SndElementWriteInt( 1076 struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem, long value) 1077{ 1078 snd_ctl_t *alsaHandle = NULL; 1079 snd_ctl_elem_id_t *elem_id = NULL; 1080 snd_ctl_elem_info_t *elem_info = NULL; 1081 snd_ctl_elem_value_t *elem_value = NULL; 1082 1083 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns); 1084 CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem); 1085 1086 int ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0); 1087 if (ret < 0) { 1088 AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret)); 1089 return HDF_FAILURE; 1090 } 1091 1092 snd_ctl_elem_id_alloca(&elem_id); 1093 snd_ctl_elem_info_alloca(&elem_info); 1094 snd_ctl_elem_value_alloca(&elem_value); 1095 ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id); 1096 if (ret != HDF_SUCCESS) { 1097 AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name); 1098 return HDF_FAILURE; 1099 } 1100 1101 if (!snd_ctl_elem_info_is_writable(elem_info)) { 1102 AUDIO_FUNC_LOGE("Element write enable\n"); 1103 return HDF_FAILURE; 1104 } 1105 1106 snd_ctl_elem_value_set_id(elem_value, elem_id); 1107 snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(elem_info); 1108 if (type == SND_CTL_ELEM_TYPE_INTEGER) { 1109 snd_ctl_elem_value_set_integer(elem_value, 0, value); 1110 } else if (type == SND_CTL_ELEM_TYPE_INTEGER64) { 1111 snd_ctl_elem_value_set_integer64(elem_value, 0, (long long)value); 1112 } else { 1113 AUDIO_FUNC_LOGE("Element value is not integer type!\n"); 1114 return HDF_FAILURE; 1115 } 1116 1117 ret = snd_ctl_elem_write(alsaHandle, elem_value); 1118 if (ret < 0) { 1119 AUDIO_FUNC_LOGE("snd_ctl_elem_write failed!\n"); 1120 return HDF_FAILURE; 1121 } 1122 1123 return HDF_SUCCESS; 1124} 1125 1126int32_t SndElementWriteEnum( 1127 struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem, unsigned int item) 1128{ 1129 snd_ctl_t *alsaHandle = NULL; 1130 snd_ctl_elem_id_t *elem_id = NULL; 1131 snd_ctl_elem_info_t *elem_info = NULL; 1132 snd_ctl_elem_value_t *elem_value = NULL; 1133 1134 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns); 1135 CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem); 1136 1137 int ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0); 1138 if (ret < 0) { 1139 AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret)); 1140 return HDF_FAILURE; 1141 } 1142 1143 snd_ctl_elem_id_alloca(&elem_id); 1144 snd_ctl_elem_info_alloca(&elem_info); 1145 snd_ctl_elem_value_alloca(&elem_value); 1146 ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id); 1147 if (ret != HDF_SUCCESS) { 1148 AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name); 1149 return HDF_FAILURE; 1150 } 1151 1152 if (!snd_ctl_elem_info_is_writable(elem_info)) { 1153 AUDIO_FUNC_LOGE("Element write enable\n"); 1154 return HDF_FAILURE; 1155 } 1156 1157 snd_ctl_elem_value_set_id(elem_value, elem_id); 1158 snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(elem_info); 1159 if (type == SND_CTL_ELEM_TYPE_ENUMERATED) { 1160 snd_ctl_elem_value_set_enumerated(elem_value, 0, item); 1161 } else { 1162 AUDIO_FUNC_LOGE("Element value is not enum type!\n"); 1163 return HDF_FAILURE; 1164 } 1165 1166 ret = snd_ctl_elem_write(alsaHandle, elem_value); 1167 if (ret < 0) { 1168 AUDIO_FUNC_LOGE("snd_ctl_elem_write failed!\n"); 1169 return HDF_FAILURE; 1170 } 1171 1172 return HDF_SUCCESS; 1173} 1174 1175int32_t SndElementWriteSwitch( 1176 struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem, bool on) 1177{ 1178 snd_ctl_t *alsaHandle = NULL; 1179 snd_ctl_elem_id_t *elem_id; 1180 snd_ctl_elem_info_t *elem_info; 1181 snd_ctl_elem_value_t *elem_value; 1182 1183 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns); 1184 CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem); 1185 1186 int ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0); 1187 if (ret < 0) { 1188 AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret)); 1189 return HDF_FAILURE; 1190 } 1191 1192 snd_ctl_elem_id_alloca(&elem_id); 1193 snd_ctl_elem_info_alloca(&elem_info); 1194 snd_ctl_elem_value_alloca(&elem_value); 1195 ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id); 1196 if (ret != HDF_SUCCESS) { 1197 AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name); 1198 return HDF_FAILURE; 1199 } 1200 1201 if (!snd_ctl_elem_info_is_writable(elem_info)) { 1202 AUDIO_FUNC_LOGE("Element write enable\n"); 1203 return HDF_FAILURE; 1204 } 1205 1206 snd_ctl_elem_value_set_id(elem_value, elem_id); 1207 snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(elem_info); 1208 if (type == SND_CTL_ELEM_TYPE_BOOLEAN) { 1209 int value = on ? 1 : 0; 1210 snd_ctl_elem_value_set_boolean(elem_value, 0, value); 1211 } else { 1212 AUDIO_FUNC_LOGE("Element value is not boolean type!\n"); 1213 return HDF_FAILURE; 1214 } 1215 1216 ret = snd_ctl_elem_write(alsaHandle, elem_value); 1217 if (ret < 0) { 1218 AUDIO_FUNC_LOGE("snd_ctl_elem_write failed!\n"); 1219 return HDF_FAILURE; 1220 } 1221 1222 return HDF_SUCCESS; 1223} 1224 1225int32_t SndElementWrite( 1226 struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem) 1227{ 1228 snd_ctl_t *alsaHandle = NULL; 1229 snd_ctl_elem_id_t *elem_id = NULL; 1230 snd_ctl_elem_info_t *elem_info = NULL; 1231 snd_ctl_elem_value_t *elem_value = NULL; 1232 1233 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns); 1234 CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem); 1235 1236 int ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0); 1237 if (ret < 0) { 1238 AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret)); 1239 return HDF_FAILURE; 1240 } 1241 1242 snd_ctl_elem_id_alloca(&elem_id); 1243 snd_ctl_elem_info_alloca(&elem_info); 1244 snd_ctl_elem_value_alloca(&elem_value); 1245 ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id); 1246 if (ret != HDF_SUCCESS) { 1247 AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name); 1248 return HDF_FAILURE; 1249 } 1250 1251 if (!snd_ctl_elem_info_is_writable(elem_info)) { 1252 AUDIO_FUNC_LOGE("Element write enable\n"); 1253 return HDF_FAILURE; 1254 } 1255 1256 snd_ctl_elem_value_set_id(elem_value, elem_id); 1257 ret = snd_ctl_ascii_value_parse(alsaHandle, elem_value, elem_info, ctlElem->value); 1258 if (ret < 0) { 1259 AUDIO_FUNC_LOGE("Control parse error: %s\n", snd_strerror(ret)); 1260 return HDF_FAILURE; 1261 } 1262 ret = snd_ctl_elem_write(alsaHandle, elem_value); 1263 if (ret < 0) { 1264 AUDIO_FUNC_LOGE("Control element write error: %s\n", snd_strerror(ret)); 1265 return HDF_FAILURE; 1266 } 1267 1268 return HDF_SUCCESS; 1269} 1270 1271int32_t SndElementGroupWrite( 1272 struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement* elemGroup, int32_t groupSize) 1273{ 1274 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns); 1275 1276 for (int i = 0; i < groupSize; ++i) { 1277 int err = SndElementWrite(cardIns, &elemGroup[i]); 1278 if (err < 0) { 1279 AUDIO_FUNC_LOGE("Cant't set element %{public}s", elemGroup[i].name); 1280 } 1281 } 1282 1283 return HDF_SUCCESS; 1284} 1285 1286int32_t SndTraversalMixerElement(struct AlsaSoundCard *cardIns, 1287 bool (*callback)(void *data, snd_ctl_elem_id_t *elem_id), void *data) 1288{ 1289 snd_hctl_t *handle = NULL; 1290 snd_hctl_elem_t *elem = NULL; 1291 snd_ctl_elem_id_t *elem_id = NULL; 1292 snd_ctl_elem_info_t *elem_info = NULL; 1293 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns); 1294 CHECK_NULL_PTR_RETURN_DEFAULT(callback); 1295 1296 int ret = snd_hctl_open(&handle, cardIns->ctrlName, 0); 1297 if (ret < 0) { 1298 AUDIO_FUNC_LOGE("Control %{public}s open error: %{public}s", 1299 cardIns->ctrlName, snd_strerror(ret)); 1300 return HDF_FAILURE; 1301 } 1302 ret = snd_hctl_load(handle); 1303 if (ret < 0) { 1304 AUDIO_FUNC_LOGE("Control %{public}s local error: %{public}s\n", 1305 cardIns->ctrlName, snd_strerror(ret)); 1306 return HDF_FAILURE; 1307 } 1308 1309 snd_ctl_elem_id_alloca(&elem_id); 1310 snd_ctl_elem_info_alloca(&elem_info); 1311 for (elem = snd_hctl_first_elem(handle); elem; elem = snd_hctl_elem_next(elem)) { 1312 ret = snd_hctl_elem_info(elem, elem_info); 1313 if (ret < 0) { 1314 AUDIO_FUNC_LOGE("Control %{public}s snd_hctl_elem_info error: %{public}s\n", 1315 cardIns->ctrlName, snd_strerror(ret)); 1316 return HDF_FAILURE; 1317 } 1318 if (snd_ctl_elem_info_is_inactive(elem_info)) { 1319 continue; 1320 } 1321 snd_hctl_elem_get_id(elem, elem_id); 1322 if (callback(data, elem_id)) { 1323 (void)snd_hctl_close(handle); 1324 return HDF_SUCCESS; 1325 } 1326 } 1327 (void)snd_hctl_close(handle); 1328 return HDF_FAILURE; 1329} 1330