• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "alsa_lib_common.h"
17 
18 #define HDF_LOG_TAG HDF_AUDIO_HAL_LIB
19 
AlsaControls(char * cardCtlName,const char * pathName,uint32_t * numId)20 static int32_t AlsaControls(char *cardCtlName, const char *pathName, uint32_t *numId)
21 {
22     int ret;
23     snd_hctl_t *handle = NULL;
24     snd_hctl_elem_t *elem = NULL;
25     snd_ctl_elem_id_t *id = NULL;
26     snd_ctl_elem_info_t *info = NULL;
27 
28     if (cardCtlName == NULL || pathName == NULL || numId == NULL) {
29         AUDIO_FUNC_LOGE("The parameter is NULL!");
30         return HDF_FAILURE;
31     }
32 
33     snd_ctl_elem_id_alloca(&id);
34     snd_ctl_elem_info_alloca(&info);
35     if (id == NULL || info == NULL) {
36         AUDIO_FUNC_LOGE("alloca failed!");
37         return HDF_FAILURE;
38     }
39     if ((ret = snd_hctl_open(&handle, cardCtlName, 0)) < 0) {
40         AUDIO_FUNC_LOGE("Control %{public}s open error: %{public}s", cardCtlName, snd_strerror(ret));
41         return ret;
42     }
43     if ((ret = snd_hctl_load(handle)) < 0) {
44         AUDIO_FUNC_LOGE("Control %{public}s local error: %{public}s\n", cardCtlName, snd_strerror(ret));
45         return ret;
46     }
47     /* Obtain the path information of the sound card in the control node */
48     for (elem = snd_hctl_first_elem(handle); elem != NULL; elem = snd_hctl_elem_next(elem)) {
49         if ((ret = snd_hctl_elem_info(elem, info)) < 0) {
50             AUDIO_FUNC_LOGE("Control %{public}s snd_hctl_elem_info error: %{public}s.", cardCtlName, snd_strerror(ret));
51             return ret;
52         }
53         if (snd_ctl_elem_info_is_inactive(info)) {
54             continue;
55         }
56         snd_hctl_elem_get_id(elem, id);
57         const char *name = snd_ctl_elem_id_get_name(id);
58         if (strncmp(name, pathName, strlen(pathName)) == 0) {
59             *numId = snd_ctl_elem_id_get_numid(id);
60             (void)snd_hctl_close(handle);
61             return ret;
62         }
63     }
64     AUDIO_FUNC_LOGE("The set ctlName was not found!");
65     (void)snd_hctl_close(handle);
66     return HDF_FAILURE;
67 }
68 
AudioCtlElemWrite(const char * ctlName,uint32_t numId,uint32_t item)69 static int32_t AudioCtlElemWrite(const char *ctlName, uint32_t numId, uint32_t item)
70 {
71     int32_t ret;
72     snd_ctl_t *ctlHandle = NULL;
73     snd_ctl_elem_value_t *ctlElemValue = NULL;
74 
75     if (ctlName == NULL) {
76         AUDIO_FUNC_LOGE("The parameter is NULL!");
77         return HDF_FAILURE;
78     }
79     ret = snd_ctl_elem_value_malloc(&ctlElemValue);
80     if (ret < 0) {
81         AUDIO_FUNC_LOGE("snd_ctl_elem_value_malloc error: %{public}s", snd_strerror(ret));
82         return HDF_FAILURE;
83     }
84 
85     ret = snd_ctl_open(&ctlHandle, ctlName, 0);
86     if (ret < 0) {
87         AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
88         snd_ctl_elem_value_free(ctlElemValue);
89         return HDF_FAILURE;
90     }
91     snd_ctl_elem_value_set_numid(ctlElemValue, numId);
92     snd_ctl_elem_value_set_interface(ctlElemValue, SND_CTL_ELEM_IFACE_MIXER);
93     snd_ctl_elem_value_set_integer(ctlElemValue, 0, item); // 0 is index of the member
94     ret = snd_ctl_elem_write(ctlHandle, ctlElemValue);
95     if (ret < 0) {
96         AUDIO_FUNC_LOGE("snd_ctl_elem_write error: %{public}s", snd_strerror(ret));
97     }
98 
99     snd_ctl_elem_value_free(ctlElemValue);
100     (void)snd_ctl_close(ctlHandle);
101     return ret;
102 }
103 
EnableAudioRenderRoute(const struct AudioHwRenderParam * renderData)104 int32_t EnableAudioRenderRoute(const struct AudioHwRenderParam *renderData)
105 {
106     struct AudioCardInfo *cardIns = NULL;
107     uint32_t numId;
108     const char *pathName = NULL;
109     int32_t itemValue;
110     if (renderData == NULL) {
111         AUDIO_FUNC_LOGE("The parameter is NULL!");
112         return HDF_FAILURE;
113     }
114 
115     const char *adapterName = renderData->renderMode.hwInfo.adapterName;
116     cardIns = AudioGetCardInstance(adapterName);
117     if (cardIns == NULL) {
118         AUDIO_FUNC_LOGE("AudioRenderGetCardIns failed.");
119         return HDF_FAILURE;
120     }
121 
122     int32_t devCount = renderData->renderMode.hwInfo.pathSelect.deviceInfo.deviceNum;
123     if (devCount < 0 || devCount > PATHPLAN_COUNT - 1) {
124         AUDIO_FUNC_LOGE("devCount is error!");
125         return HDF_FAILURE;
126     }
127     for (int32_t i = 0; i < devCount; i++) {
128         pathName = renderData->renderMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[i].deviceSwitch;
129         itemValue = renderData->renderMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[i].value;
130         if (AlsaControls(cardIns->ctrlName, pathName, &numId) < 0) {
131             AUDIO_FUNC_LOGE("AlsaControls failed, pathName: %{public}s.", pathName);
132             return HDF_FAILURE;
133         }
134         if (AudioCtlElemWrite(cardIns->ctrlName, numId, itemValue) != HDF_SUCCESS) {
135             AUDIO_FUNC_LOGE("AudioCtlElemWrite failed.");
136             return HDF_FAILURE;
137         }
138     }
139 
140     return HDF_SUCCESS;
141 }
142 
EnableAudioCaptureRoute(const struct AudioHwCaptureParam * captureData)143 int32_t EnableAudioCaptureRoute(const struct AudioHwCaptureParam *captureData)
144 {
145     uint32_t numId;
146     int32_t itemValue;
147     struct AudioCardInfo *cardIns = NULL;
148     const char *capturePathName = NULL;
149 
150     if (captureData == NULL) {
151         AUDIO_FUNC_LOGE("The parameter is NULL!");
152         return HDF_FAILURE;
153     }
154 
155     const char *adapterName = captureData->captureMode.hwInfo.adapterName;
156     cardIns = AudioGetCardInstance(adapterName);
157     if (cardIns == NULL) {
158         AUDIO_FUNC_LOGE("AudioCaptureGetCardIns failed.");
159         return HDF_FAILURE;
160     }
161 
162     int32_t devCount = captureData->captureMode.hwInfo.pathSelect.deviceInfo.deviceNum;
163     if (devCount < 0 || devCount > PATHPLAN_COUNT - 1) {
164         AUDIO_FUNC_LOGE("deviceIndex is error!");
165         return HDF_FAILURE;
166     }
167     for (int32_t i = 0; i < devCount; i++) {
168         capturePathName = captureData->captureMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[i].deviceSwitch;
169         itemValue = captureData->captureMode.hwInfo.pathSelect.deviceInfo.deviceSwitchs[i].value;
170         if (AlsaControls(cardIns->ctrlName, capturePathName, &numId) < 0) {
171             AUDIO_FUNC_LOGE("AlsaControls failed, pathName: %{public}s!", capturePathName);
172             return HDF_FAILURE;
173         }
174         if (AudioCtlElemWrite(cardIns->ctrlName, numId, itemValue) != HDF_SUCCESS) {
175             AUDIO_FUNC_LOGE("AudioCtlElemWrite failed!");
176             return HDF_FAILURE;
177         }
178     }
179 
180     return HDF_SUCCESS;
181 }
182