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 */
29 struct AlsaAdapterCfgInfo {
30 char adapterName[MAX_CARD_NAME_LEN];
31 int32_t cardId;
32 char cardName[MAX_CARD_NAME_LEN];
33 };
34 struct AlsaAdapterList {
35 int32_t num;
36 struct AlsaAdapterCfgInfo list[AUDIO_MAX_CARD_NUM];
37 };
38 static struct AlsaAdapterList g_alsaAdapterList[SND_CARD_MAX];
39
40 struct 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 };
46 struct AlsaCardsList {
47 int32_t num;
48 struct AlsaDevInfo alsaDevIns[MAX_CARD_NUM];
49 };
50 static struct AlsaCardsList g_alsaCardsDevList;
51
52
CfgReadAdapterFile(const char * fpath)53 static 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
CfgGetAdapterCount()107 static 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
CfgGetAdapterCardType(const char * adapterName)116 static 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
CfgGetAdapterInfo(const char * adapterName,struct AlsaAdapterCfgInfo infos[],int infoLen)134 static 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
CfgDumpAdapterInfo(struct AlsaAdapterCfgInfo * info)154 static 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
CfgSaveAdapterStruct(cJSON * adapter,struct AlsaAdapterCfgInfo * info)189 static 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
CfgParseAdapterItems(cJSON * adapterObj)226 static 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
CfgSaveAdapterFromFile(void)268 int32_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
DevGetInfoByAdapter(struct AlsaAdapterCfgInfo infos[],int32_t size)297 static 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
DevGetInfoByPcmInfoId(const char * name)312 static 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
DevSaveCardPcmInfo(snd_ctl_t * handle,snd_pcm_stream_t stream,int card,const char * deviceName)326 static 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
DevSaveDriverInfo(snd_pcm_stream_t stream)378 static 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
SndSaveCardListInfo(snd_pcm_stream_t stream)426 int32_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
SndMatchSelAdapter(struct AlsaSoundCard * cardIns,const char * adapterName)462 int32_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
SndConverAlsaPcmFormat(const struct AudioPcmHwParams * hwParams,snd_pcm_format_t * alsaPcmFormat)508 int32_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
SndPcmPrepare(struct AlsaSoundCard * cardIns)557 int32_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
SndisBusy(struct AlsaSoundCard * cardIns)568 bool SndisBusy(struct AlsaSoundCard *cardIns)
569 {
570 if (cardIns == NULL) {
571 return false;
572 }
573 return (cardIns->pcmHandle == NULL) ? false : true;
574 }
575
SndOpenMixer(struct AlsaSoundCard * cardIns)576 int32_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
SndGetRunState(struct AlsaSoundCard * cardIns)626 snd_pcm_state_t SndGetRunState(struct AlsaSoundCard * cardIns)
627 {
628 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
629 return snd_pcm_state(cardIns->pcmHandle);
630 }
631
SndCloseHandle(struct AlsaSoundCard * cardIns)632 void 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
AudioInitPortOut(struct AudioPort * audioPort)661 static void AudioInitPortOut(struct AudioPort *audioPort)
662 {
663 audioPort->dir = PORT_OUT;
664 audioPort->portId = 0;
665 audioPort->portName = strdup("AOP");
666 }
667
AudioInitPortIn(struct AudioPort * audioPort)668 static void AudioInitPortIn(struct AudioPort *audioPort)
669 {
670 audioPort->dir = PORT_IN;
671 audioPort->portId = 0;
672 audioPort->portName = strdup("AIP");
673 }
674
AudioInitPortOutAndIn(struct AudioPort * audioPort)675 static void AudioInitPortOutAndIn(struct AudioPort *audioPort)
676 {
677 audioPort->dir = PORT_OUT_IN;
678 audioPort->portId = 0;
679 audioPort->portName = strdup("AIOP");
680 }
681
AudioInitPorts(struct AudioAdapterDescriptor * desc,enum SndCardType type)682 static 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
AudioGetAllCardInfo(struct AudioAdapterDescriptor ** descs,int32_t * sndCardNum)734 int32_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
HdfIoServiceBindName(const char * serviceName)768 struct HdfIoService *HdfIoServiceBindName(const char *serviceName)
769 {
770 (void)serviceName;
771 /* Nothing to do */
772 static struct HdfIoService hdfIoService;
773 return &hdfIoService;
774 }
775
AudioBindService(const char * name)776 struct 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
AudioCloseService(const struct DevHandle * handle)795 void AudioCloseService(const struct DevHandle *handle)
796 {
797 if (handle != NULL) {
798 AudioMemFree((void **)&handle);
799 }
800 }
801
SndElementItemInit(struct AlsaMixerCtlElement * m)802 void SndElementItemInit(struct AlsaMixerCtlElement *m)
803 {
804 m->iface = IFACE_MIXER;
805 m->index = 0;
806 m->device = 0;
807 m->subdevice = 0;
808 }
809
ConvertIfaceType(enum SndIfaceType iface)810 static 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
SetElementInfo(snd_ctl_t * alsaHandle,const struct AlsaMixerCtlElement * ctlElem,snd_ctl_elem_info_t * info,snd_ctl_elem_id_t * id)839 static 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
SndElementReadInt(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,long * value)876 int32_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
SndElementReadEnum(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,unsigned int * item)926 int32_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
SndElementReadRange(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,long * mix,long * max)974 int32_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
SndElementReadSwitch(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,bool * on)1026 int32_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
SndElementWriteInt(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,long value)1075 int32_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
SndElementWriteEnum(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,unsigned int item)1126 int32_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
SndElementWriteSwitch(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,bool on)1175 int32_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
SndElementWrite(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem)1225 int32_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
SndElementGroupWrite(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * elemGroup,int32_t groupSize)1271 int32_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
SndTraversalMixerElement(struct AlsaSoundCard * cardIns,bool (* callback)(void * data,snd_ctl_elem_id_t * elem_id),void * data)1286 int32_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