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