4 * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
29 #include "tizen-audio-internal.h"
30 #include "tizen-audio-impl.h"
32 /* #define DEBUG_TIMING */
34 static device_type_t outDeviceTypes[] = {
35 { AUDIO_DEVICE_OUT_SPEAKER, "Speaker" },
36 { AUDIO_DEVICE_OUT_JACK, "Headphones" },
37 { AUDIO_DEVICE_OUT_BT_SCO, "Bluetooth" },
38 { AUDIO_DEVICE_OUT_AUX, "Line" },
39 { AUDIO_DEVICE_OUT_HDMI, "HDMI" },
43 static device_type_t inDeviceTypes[] = {
44 { AUDIO_DEVICE_IN_MAIN_MIC, "MainMic" },
45 { AUDIO_DEVICE_IN_JACK, "HeadsetMic" },
46 { AUDIO_DEVICE_IN_BT_SCO, "BT Mic" },
50 static uint32_t __convert_device_string_to_enum(const char* device_str, uint32_t direction)
54 if (!strncmp(device_str, "builtin-speaker", MAX_NAME_LEN)) {
55 device = AUDIO_DEVICE_OUT_SPEAKER;
56 } else if (!strncmp(device_str, "builtin-receiver", MAX_NAME_LEN)) {
57 device = AUDIO_DEVICE_OUT_RECEIVER;
58 } else if ((!strncmp(device_str, "audio-jack", MAX_NAME_LEN)) && (direction == AUDIO_DIRECTION_OUT)) {
59 device = AUDIO_DEVICE_OUT_JACK;
60 } else if ((!strncmp(device_str, "bt-sco", MAX_NAME_LEN)) && (direction == AUDIO_DIRECTION_OUT)) {
61 device = AUDIO_DEVICE_OUT_BT_SCO;
62 } else if (!strncmp(device_str, "aux", MAX_NAME_LEN)) {
63 device = AUDIO_DEVICE_OUT_AUX;
64 } else if (!strncmp(device_str, "hdmi", MAX_NAME_LEN)) {
65 device = AUDIO_DEVICE_OUT_HDMI;
66 } else if ((!strncmp(device_str, "builtin-mic", MAX_NAME_LEN))) {
67 device = AUDIO_DEVICE_IN_MAIN_MIC;
68 } else if ((!strncmp(device_str, "audio-jack", MAX_NAME_LEN)) && (direction == AUDIO_DIRECTION_IN)) {
69 device = AUDIO_DEVICE_IN_JACK;
70 } else if ((!strncmp(device_str, "bt-sco", MAX_NAME_LEN)) && (direction == AUDIO_DIRECTION_IN)) {
71 device = AUDIO_DEVICE_IN_BT_SCO;
73 device = AUDIO_DEVICE_NONE;
75 AUDIO_LOG_INFO("device type(%s), enum(0x%x)", device_str, device);
79 static audio_return_t __set_devices(audio_hal_t *ah, device_info_t *devices, uint32_t num_of_devices)
81 audio_return_t audio_ret = AUDIO_RET_OK;
82 uint32_t new_device = 0;
83 const char *active_devices[MAX_DEVICES] = {NULL,};
84 int i = 0, j = 0, dev_idx = 0;
86 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
87 AUDIO_RETURN_VAL_IF_FAIL(devices, AUDIO_ERR_PARAMETER);
88 AUDIO_RETURN_VAL_IF_FAIL(num_of_devices, AUDIO_ERR_PARAMETER);
90 if (num_of_devices > MAX_DEVICES) {
91 num_of_devices = MAX_DEVICES;
92 AUDIO_LOG_ERROR("error: num_of_devices");
93 return AUDIO_ERR_PARAMETER;
96 if (devices[0].direction == AUDIO_DIRECTION_OUT) {
97 ah->device.active_out &= 0x0;
98 if (ah->device.active_in) {
99 /* check the active in devices */
100 for (j = 0; j < inDeviceTypes[j].type; j++) {
101 if (((ah->device.active_in & (~AUDIO_DEVICE_IN)) & inDeviceTypes[j].type))
102 active_devices[dev_idx++] = inDeviceTypes[j].name;
105 } else if (devices[0].direction == AUDIO_DIRECTION_IN) {
106 ah->device.active_in &= 0x0;
107 if (ah->device.active_out) {
108 /* check the active out devices */
109 for (j = 0; j < outDeviceTypes[j].type; j++) {
110 if (ah->device.active_out & outDeviceTypes[j].type)
111 active_devices[dev_idx++] = outDeviceTypes[j].name;
116 for (i = 0; i < num_of_devices; i++) {
117 new_device = __convert_device_string_to_enum(devices[i].type, devices[i].direction);
118 if (new_device & AUDIO_DEVICE_IN) {
119 for (j = 0; j < inDeviceTypes[j].type; j++) {
120 if (new_device == inDeviceTypes[j].type) {
121 active_devices[dev_idx++] = inDeviceTypes[j].name;
122 ah->device.active_in |= new_device;
126 for (j = 0; j < outDeviceTypes[j].type; j++) {
127 if (new_device == outDeviceTypes[j].type) {
128 active_devices[dev_idx++] = outDeviceTypes[j].name;
129 ah->device.active_out |= new_device;
135 if (active_devices[0] == NULL) {
136 AUDIO_LOG_ERROR("Failed to set device: active device is NULL");
137 return AUDIO_ERR_PARAMETER;
143 static audio_return_t __update_route_ap_playback_capture(audio_hal_t *ah, audio_route_info_t *route_info)
145 audio_return_t audio_ret = AUDIO_RET_OK;
146 device_info_t *devices = NULL;
148 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
149 AUDIO_RETURN_VAL_IF_FAIL(route_info, AUDIO_ERR_PARAMETER);
151 devices = route_info->device_infos;
153 AUDIO_LOG_INFO("update_route_ap_playback_capture++ ");
155 audio_ret = __set_devices(ah, devices, route_info->num_of_devices);
157 AUDIO_LOG_ERROR("Failed to set devices: error = 0x%x", audio_ret);
164 static audio_return_t __update_route_voip(audio_hal_t *ah, device_info_t *devices, int32_t num_of_devices)
166 audio_return_t audio_ret = AUDIO_RET_OK;
168 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
169 AUDIO_RETURN_VAL_IF_FAIL(devices, AUDIO_ERR_PARAMETER);
171 AUDIO_LOG_INFO("update_route_voip++");
173 audio_ret = __set_devices(ah, devices, num_of_devices);
175 AUDIO_LOG_ERROR("Failed to set devices: error = 0x%x", audio_ret);
182 static audio_return_t __update_route_reset(audio_hal_t *ah, uint32_t direction)
184 audio_return_t audio_ret = AUDIO_RET_OK;
185 const char *active_devices[MAX_DEVICES] = {NULL,};
186 int i = 0, dev_idx = 0;
188 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
190 AUDIO_LOG_INFO("update_route_reset++, direction(0x%x)", direction);
192 if (direction == AUDIO_DIRECTION_OUT) {
193 ah->device.active_out &= 0x0;
194 if (ah->device.active_in) {
195 /* check the active in devices */
196 for (i = 0; i < inDeviceTypes[i].type; i++) {
197 if (((ah->device.active_in & (~AUDIO_DEVICE_IN)) & inDeviceTypes[i].type)) {
198 active_devices[dev_idx++] = inDeviceTypes[i].name;
199 AUDIO_LOG_INFO("added for in : %s", inDeviceTypes[i].name);
204 ah->device.active_in &= 0x0;
205 if (ah->device.active_out) {
206 /* check the active out devices */
207 for (i = 0; i < outDeviceTypes[i].type; i++) {
208 if (ah->device.active_out & outDeviceTypes[i].type) {
209 active_devices[dev_idx++] = outDeviceTypes[i].name;
210 AUDIO_LOG_INFO("added for out : %s", outDeviceTypes[i].name);
216 if (active_devices[0] == NULL) {
217 AUDIO_LOG_DEBUG("active device is NULL, no need to update.");
224 audio_return_t _audio_routing_init(audio_hal_t *ah)
226 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
228 ah->device.active_in = 0x0;
229 ah->device.active_out = 0x0;
234 audio_return_t _audio_routing_deinit(audio_hal_t *ah)
236 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
241 #define LOOPBACK_ARG_LATENCY_MSEC 30
242 #define LOOPBACK_ARG_ADJUST_TIME_SEC 3
243 audio_return_t audio_update_route(void *audio_handle, audio_route_info_t *info)
245 audio_return_t audio_ret = AUDIO_RET_OK;
246 audio_hal_t *ah = (audio_hal_t *)audio_handle;
247 device_info_t *devices = NULL;
249 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
250 AUDIO_RETURN_VAL_IF_FAIL(info, AUDIO_ERR_PARAMETER);
251 AUDIO_RETURN_VAL_IF_FAIL(info->role, AUDIO_ERR_PARAMETER);
253 AUDIO_LOG_INFO("role:%s", info->role);
255 devices = info->device_infos;
257 if (!strncmp("voip", info->role, MAX_NAME_LEN)) {
258 if ((audio_ret = __update_route_voip(ah, devices, info->num_of_devices)))
259 AUDIO_LOG_WARN("update voip route return 0x%x", audio_ret);
261 } else if (!strncmp("reset", info->role, MAX_NAME_LEN)) {
262 if ((audio_ret = __update_route_reset(ah, devices->direction)))
263 AUDIO_LOG_WARN("update reset return 0x%x", audio_ret);
266 /* send latency and adjust time for loopback */
267 if (!strncmp("loopback", info->role, MAX_NAME_LEN)) {
268 _audio_comm_send_message(ah, "loopback::latency", LOOPBACK_ARG_LATENCY_MSEC);
269 _audio_comm_send_message(ah, "loopback::adjust_time", LOOPBACK_ARG_ADJUST_TIME_SEC);
271 /* need to prepare for "alarm","notification","emergency","voice-information","voice-recognition","ringtone" */
272 if ((audio_ret = __update_route_ap_playback_capture(ah, info)))
273 AUDIO_LOG_WARN("update playback route return 0x%x", audio_ret);
278 audio_return_t audio_update_route_option(void *audio_handle, audio_route_option_t *option)
280 audio_return_t audio_ret = AUDIO_RET_OK;
281 audio_hal_t *ah = (audio_hal_t *)audio_handle;
283 AUDIO_RETURN_VAL_IF_FAIL(ah, AUDIO_ERR_PARAMETER);
284 AUDIO_RETURN_VAL_IF_FAIL(option, AUDIO_ERR_PARAMETER);
286 AUDIO_LOG_INFO("role:%s, name:%s, value:%d", option->role, option->name, option->value);