684403fb774ca7f28905e26deece3013a6ff9fe5
[platform/adaptation/emulator/audio-hal-emul.git] / tizen-audio-impl-ctrl.c
1 /*
2  * audio-hal
3  *
4  * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <pthread.h>
28
29 #include "tizen-audio-internal.h"
30
31 #ifdef __MIXER_PARAM_DUMP
32 static void __dump_mixer_param(char *dump, long *param, int size)
33 {
34     int i, len;
35
36     for (i = 0; i < size; i++) {
37         len = sprintf(dump, "%ld", *param);
38         if (len > 0)
39             dump += len;
40         if (i != size -1) {
41             *dump++ = ',';
42         }
43
44         param++;
45     }
46     *dump = '\0';
47 }
48 #endif
49
50 audio_return_t _control_init(audio_hal_t *ah)
51 {
52     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
53
54     pthread_mutex_init(&(ah->mixer.mutex), NULL);
55     return AUDIO_RET_OK;
56 }
57
58 audio_return_t _control_deinit(audio_hal_t *ah)
59 {
60     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
61
62     pthread_mutex_destroy(&(ah->mixer.mutex));
63     return AUDIO_RET_OK;
64 }
65
66 audio_return_t _mixer_control_set_param(audio_hal_t *ah, const char* ctl_name, snd_ctl_elem_value_t* param, int size)
67 {
68     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
69
70     /* TODO. */
71     return AUDIO_RET_OK;
72 }
73
74 audio_return_t _mixer_control_get_value(audio_hal_t *ah, const char *card, const char *ctl_name, int *val)
75 {
76     snd_ctl_t *handle;
77     snd_ctl_elem_value_t *control;
78     snd_ctl_elem_id_t *id;
79     snd_ctl_elem_info_t *info;
80     snd_ctl_elem_type_t type;
81
82     int ret = 0, count = 0, i = 0;
83
84     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
85     AUDIO_RETURN_VAL_IF_FAIL(card, AUDIO_ERR_PARAMETER);
86     AUDIO_RETURN_VAL_IF_FAIL(ctl_name, AUDIO_ERR_PARAMETER);
87     AUDIO_RETURN_VAL_IF_FAIL(val, AUDIO_ERR_PARAMETER);
88
89     pthread_mutex_lock(&(ah->mixer.mutex));
90
91     ret = snd_ctl_open(&handle, card, 0);
92     if (ret < 0) {
93         AUDIO_LOG_ERROR("snd_ctl_open error, %s\n", snd_strerror(ret));
94         pthread_mutex_unlock(&(ah->mixer.mutex));
95         return AUDIO_ERR_IOCTL;
96     }
97
98     // Get Element Info
99
100     snd_ctl_elem_id_alloca(&id);
101     snd_ctl_elem_info_alloca(&info);
102     snd_ctl_elem_value_alloca(&control);
103
104     snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
105     snd_ctl_elem_id_set_name(id, ctl_name);
106
107     snd_ctl_elem_info_set_id(info, id);
108     if (snd_ctl_elem_info(handle, info) < 0) {
109         AUDIO_LOG_ERROR("Cannot find control element: %s\n", ctl_name);
110         goto close;
111     }
112     snd_ctl_elem_info_get_id(info, id);
113
114     type = snd_ctl_elem_info_get_type(info);
115     count = snd_ctl_elem_info_get_count(info);
116
117     snd_ctl_elem_value_set_id(control, id);
118
119     if (snd_ctl_elem_read(handle, control) < 0) {
120         AUDIO_LOG_ERROR("snd_ctl_elem_read failed \n");
121         goto close;
122 }
123
124     switch (type) {
125     case SND_CTL_ELEM_TYPE_BOOLEAN:
126         *val = snd_ctl_elem_value_get_boolean(control, i);
127         break;
128     case SND_CTL_ELEM_TYPE_INTEGER:
129         for (i = 0; i < count; i++)
130         *val = snd_ctl_elem_value_get_integer(control, i);
131         break;
132     case SND_CTL_ELEM_TYPE_ENUMERATED:
133         for (i = 0; i < count; i++)
134         *val = snd_ctl_elem_value_get_enumerated(control, i);
135         break;
136     default:
137         AUDIO_LOG_WARN("unsupported control element type\n");
138         goto close;
139     }
140
141     snd_ctl_close(handle);
142
143 #ifdef AUDIO_DEBUG
144     AUDIO_LOG_INFO("get mixer(%s) = %d success", ctl_name, *val);
145 #endif
146
147     pthread_mutex_unlock(&(ah->mixer.mutex));
148     return AUDIO_RET_OK;
149
150 close:
151     AUDIO_LOG_ERROR("Error\n");
152     snd_ctl_close(handle);
153     pthread_mutex_unlock(&(ah->mixer.mutex));
154     return AUDIO_ERR_UNDEFINED;
155 }
156
157 audio_return_t _mixer_control_set_value(audio_hal_t *ah, const char *card, const char *ctl_name, int val)
158 {
159     snd_ctl_t *handle;
160     snd_ctl_elem_value_t *control;
161     snd_ctl_elem_id_t *id;
162     snd_ctl_elem_info_t *info;
163     snd_ctl_elem_type_t type;
164     int ret = 0, count = 0, i = 0;
165
166     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
167     AUDIO_RETURN_VAL_IF_FAIL(card, AUDIO_ERR_PARAMETER);
168     AUDIO_RETURN_VAL_IF_FAIL(ctl_name, AUDIO_ERR_PARAMETER);
169
170     pthread_mutex_lock(&(ah->mixer.mutex));
171
172     ret = snd_ctl_open(&handle, card, 0);
173     if (ret < 0) {
174         AUDIO_LOG_ERROR("snd_ctl_open error, card: %s: %s", card, snd_strerror(ret));
175         pthread_mutex_unlock(&(ah->mixer.mutex));
176         return AUDIO_ERR_IOCTL;
177     }
178
179     // Get Element Info
180
181     snd_ctl_elem_id_alloca(&id);
182     snd_ctl_elem_info_alloca(&info);
183     snd_ctl_elem_value_alloca(&control);
184
185     snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
186     snd_ctl_elem_id_set_name(id, ctl_name);
187
188     snd_ctl_elem_info_set_id(info, id);
189     if (snd_ctl_elem_info(handle, info) < 0) {
190         AUDIO_LOG_ERROR("Cannot find control element: %s", ctl_name);
191         goto close;
192     }
193     snd_ctl_elem_info_get_id(info, id);
194
195     type = snd_ctl_elem_info_get_type(info);
196     count = snd_ctl_elem_info_get_count(info);
197
198     snd_ctl_elem_value_set_id(control, id);
199
200     snd_ctl_elem_read(handle, control);
201
202     switch (type) {
203     case SND_CTL_ELEM_TYPE_BOOLEAN:
204         for (i = 0; i < count; i++)
205             snd_ctl_elem_value_set_boolean(control, i, val);
206         break;
207     case SND_CTL_ELEM_TYPE_INTEGER:
208         for (i = 0; i < count; i++)
209             snd_ctl_elem_value_set_integer(control, i, val);
210         break;
211     case SND_CTL_ELEM_TYPE_ENUMERATED:
212         for (i = 0; i < count; i++)
213             snd_ctl_elem_value_set_enumerated(control, i, val);
214         break;
215
216     default:
217         AUDIO_LOG_WARN("unsupported control element type");
218         goto close;
219     }
220
221     snd_ctl_elem_write(handle, control);
222
223     snd_ctl_close(handle);
224
225     AUDIO_LOG_INFO("set mixer(%s) = %d success", ctl_name, val);
226
227     pthread_mutex_unlock(&(ah->mixer.mutex));
228     return AUDIO_RET_OK;
229
230 close:
231     AUDIO_LOG_ERROR("Error");
232     snd_ctl_close(handle);
233     pthread_mutex_unlock(&(ah->mixer.mutex));
234     return AUDIO_ERR_UNDEFINED;
235 }
236
237 audio_return_t _mixer_control_set_value_string(audio_hal_t *ah, const char* ctl_name, const char* value)
238 {
239     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
240     AUDIO_RETURN_VAL_IF_FAIL(ctl_name, AUDIO_ERR_PARAMETER);
241
242     /* TODO. */
243     return AUDIO_RET_OK;
244 }
245
246
247 audio_return_t _mixer_control_get_element(audio_hal_t *ah, const char *ctl_name, snd_hctl_elem_t **elem)
248 {
249     AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
250     AUDIO_RETURN_VAL_IF_FAIL(ctl_name, AUDIO_ERR_PARAMETER);
251     AUDIO_RETURN_VAL_IF_FAIL(elem, AUDIO_ERR_PARAMETER);
252
253     /* TODO. */
254     return AUDIO_RET_OK;
255 }