blob: e2bde0fe13f914b0b7b66a3600a752a3e18f0a24 [file] [log] [blame]
justinweng20fb6d82019-02-21 18:49:00 -07001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "audio_hw_audiozoom"
18/*#define LOG_NDEBUG 0*/
19
20#include <errno.h>
21#include <log/log.h>
22#include <stdlib.h>
23#include <expat.h>
24#include <audio_hw.h>
25#include <system/audio.h>
justinweng20fb6d82019-02-21 18:49:00 -070026#include "audio_extn.h"
27
28#include "audiozoom.h"
29
30#include <resolv.h>
31
32#define AUDIOZOOM_PRESET_FILE "/vendor/etc/audiozoom.xml"
justinweng20fb6d82019-02-21 18:49:00 -070033
vivek mehtaba5ed152019-05-03 17:28:25 -070034// --- external function dependency ---
35fp_platform_set_parameters_t fp_platform_set_parameters;
36
justinweng20fb6d82019-02-21 18:49:00 -070037typedef struct qdsp_audiozoom_cfg {
38 uint32_t topo_id;
39 uint32_t module_id;
40 uint32_t instance_id;
41 uint32_t zoom_param_id;
42 uint32_t wide_param_id;
43 uint32_t dir_param_id;
44 uint32_t app_type;
45} qdsp_audiozoom_cfg_t;
46
47static qdsp_audiozoom_cfg_t qdsp_audiozoom;
48
49static void start_tag(void *userdata __unused, const XML_Char *tag_name,
50 const XML_Char **attr)
51{
52 uint32_t index = 0;
53
54 if (!attr) {
55 ALOGE("%s: NULL platform/tag_name/attr", __func__);
56 return;
57 }
58
59 if (strcmp(tag_name, "topo") == 0) {
60 if (strcmp(attr[0], "id") == 0) {
61 if (attr[1])
62 qdsp_audiozoom.topo_id = atoi(attr[1]);
63 }
64 } else if (strcmp(tag_name, "module") == 0) {
65 if (strcmp(attr[0], "id") == 0) {
66 if (attr[1])
67 qdsp_audiozoom.module_id = atoi(attr[1]);
68 }
69 } else if (strcmp(tag_name, "param") == 0) {
70 while (attr[index] != NULL) {
71 if (strcmp(attr[index], "zoom_id") == 0) {
72 index++;
73 if (attr[index])
74 qdsp_audiozoom.zoom_param_id = atoi(attr[index]);
75 else
76 break;
77 } else if (strcmp(attr[index], "wide_id") == 0) {
78 index++;
79 if (attr[index])
80 qdsp_audiozoom.wide_param_id = atoi(attr[index]);
81 else
82 break;
83 } else if (strcmp(attr[index], "dir_id") == 0) {
84 index++;
85 if (attr[index])
86 qdsp_audiozoom.dir_param_id = atoi(attr[index]);
87 else
88 break;
89 }
90 index++;
91 }
92 } else if (strcmp(tag_name, "app_type") == 0) {
93 if (strcmp(attr[0], "id") == 0) {
94 if (attr[1])
95 qdsp_audiozoom.app_type = atoi(attr[1]);
96 }
97 } else if (strcmp(tag_name, "instance") == 0) {
98 if (strcmp(attr[0], "id") == 0) {
99 if (attr[1])
100 qdsp_audiozoom.instance_id = atoi(attr[1]);
101 }
102 } else {
103 ALOGE("%s: %s is not a supported tag", __func__, tag_name);
104 }
105
106 return;
107}
108
109static void end_tag(void *userdata __unused, const XML_Char *tag_name)
110{
111 if (strcmp(tag_name, "topo") == 0) {
112 } else if (strcmp(tag_name, "module") == 0) {
113 } else if (strcmp(tag_name, "param") == 0) {
114 } else if (strcmp(tag_name, "app_type") == 0) {
115 } else if (strcmp(tag_name, "instance") == 0) {
116 } else {
117 ALOGE("%s: %s is not a supported tag", __func__, tag_name);
118 }
119}
120
vivek mehtaba5ed152019-05-03 17:28:25 -0700121static int audiozoom_parse_info(const char *filename)
justinweng20fb6d82019-02-21 18:49:00 -0700122{
123 XML_Parser parser;
124 FILE *file;
125 int ret = 0;
126 int bytes_read;
127 void *buf;
128 static const uint32_t kBufSize = 1024;
129
130 file = fopen(filename, "r");
131 if (!file) {
132 ALOGE("%s: Failed to open %s", __func__, filename);
133 ret = -ENODEV;
134 goto done;
135 }
136
137 parser = XML_ParserCreate(NULL);
138 if (!parser) {
139 ALOGE("%s: Failed to create XML parser!", __func__);
140 ret = -ENODEV;
141 goto err_close_file;
142 }
143
144 XML_SetElementHandler(parser, start_tag, end_tag);
145
146 while (1) {
147 buf = XML_GetBuffer(parser, kBufSize);
148 if (buf == NULL) {
149 ALOGE("%s: XML_GetBuffer failed", __func__);
150 ret = -ENOMEM;
151 goto err_free_parser;
152 }
153
154 bytes_read = fread(buf, 1, kBufSize, file);
155 if (bytes_read < 0) {
156 ALOGE("%s: fread failed, bytes read = %d", __func__, bytes_read);
157 ret = bytes_read;
158 goto err_free_parser;
159 }
160
161 if (XML_ParseBuffer(parser, bytes_read,
162 bytes_read == 0) == XML_STATUS_ERROR) {
163 ALOGE("%s: XML_ParseBuffer failed, for %s",
164 __func__, filename);
165 ret = -EINVAL;
166 goto err_free_parser;
167 }
168
169 if (bytes_read == 0)
170 break;
171 }
172
173err_free_parser:
174 XML_ParserFree(parser);
175err_close_file:
176 fclose(file);
177done:
178 return ret;
179}
180
vivek mehtaba5ed152019-05-03 17:28:25 -0700181int audiozoom_set_microphone_direction(
justinweng20fb6d82019-02-21 18:49:00 -0700182 struct stream_in *in, audio_microphone_direction_t dir)
183{
184 (void)in;
185 (void)dir;
186 return 0;
187}
188
vivek mehtaba5ed152019-05-03 17:28:25 -0700189static int audiozoom_set_microphone_field_dimension_zoom(
justinweng20fb6d82019-02-21 18:49:00 -0700190 struct stream_in *in, float zoom)
191{
192 struct audio_device *adev = in->dev;
193 struct str_parms *parms = str_parms_create();
justinweng81bca282019-03-27 20:27:06 -0700194 /* The encoding process in b64_ntop represents 24-bit groups of input bits
195 as output strings of 4 encoded characters. */
196 char data[((sizeof(zoom) + 2) / 3) * 4 + 1] = {0};
justinweng20fb6d82019-02-21 18:49:00 -0700197 int32_t ret;
198
199 if (zoom > 1.0 || zoom < 0)
200 return -EINVAL;
201
202 if (qdsp_audiozoom.topo_id == 0 || qdsp_audiozoom.module_id == 0 ||
203 qdsp_audiozoom.zoom_param_id == 0)
204 return -ENOSYS;
205
Aniket Kumar Lata0e6e1e52019-11-14 21:43:55 -0800206 str_parms_add_int(parms, "cal_devid", get_device_types(&in->device_list));
justinweng20fb6d82019-02-21 18:49:00 -0700207 str_parms_add_int(parms, "cal_apptype", in->app_type_cfg.app_type);
208 str_parms_add_int(parms, "cal_topoid", qdsp_audiozoom.topo_id);
209 str_parms_add_int(parms, "cal_moduleid", qdsp_audiozoom.module_id);
210 str_parms_add_int(parms, "cal_instanceid", qdsp_audiozoom.instance_id);
211 str_parms_add_int(parms, "cal_paramid", qdsp_audiozoom.zoom_param_id);
212
justinweng81bca282019-03-27 20:27:06 -0700213 ret = b64_ntop((uint8_t*)&zoom, sizeof(zoom), data, sizeof(data));
justinweng20fb6d82019-02-21 18:49:00 -0700214 if (ret > 0) {
215 str_parms_add_str(parms, "cal_data", data);
216
vivek mehtaba5ed152019-05-03 17:28:25 -0700217 fp_platform_set_parameters(adev->platform, parms);
justinweng20fb6d82019-02-21 18:49:00 -0700218 } else {
219 ALOGE("%s: failed to convert data to string, ret %d", __func__, ret);
220 }
221
222 str_parms_destroy(parms);
223
224 return 0;
225}
226
vivek mehtaba5ed152019-05-03 17:28:25 -0700227static int audiozoom_set_microphone_field_dimension_wide_angle(
justinweng20fb6d82019-02-21 18:49:00 -0700228 struct stream_in *in, float zoom)
229{
230 (void)in;
231 (void)zoom;
232 return 0;
233}
234
vivek mehtaba5ed152019-05-03 17:28:25 -0700235int audiozoom_set_microphone_field_dimension(
justinweng20fb6d82019-02-21 18:49:00 -0700236 struct stream_in *in, float zoom)
237{
238 if (zoom > 1.0 || zoom < -1.0)
239 return -EINVAL;
240
241 if (zoom >= 0 && zoom <= 1.0)
vivek mehtaba5ed152019-05-03 17:28:25 -0700242 return audiozoom_set_microphone_field_dimension_zoom(in, zoom);
justinweng20fb6d82019-02-21 18:49:00 -0700243
244 if (zoom >= -1.0 && zoom <= 0)
vivek mehtaba5ed152019-05-03 17:28:25 -0700245 return audiozoom_set_microphone_field_dimension_wide_angle(in, zoom);
justinweng20fb6d82019-02-21 18:49:00 -0700246
247 return 0;
248}
249
vivek mehtaba5ed152019-05-03 17:28:25 -0700250int audiozoom_init(audiozoom_init_config_t init_config)
justinweng20fb6d82019-02-21 18:49:00 -0700251{
vivek mehtaba5ed152019-05-03 17:28:25 -0700252 fp_platform_set_parameters = init_config.fp_platform_set_parameters;
253 audiozoom_parse_info(AUDIOZOOM_PRESET_FILE);
justinweng20fb6d82019-02-21 18:49:00 -0700254
255 ALOGV("%s: topo_id=%d, module_id=%d, instance_id=%d, zoom__id=%d, dir_id=%d, app_type=%d",
256 __func__, qdsp_audiozoom.topo_id, qdsp_audiozoom.module_id, qdsp_audiozoom.instance_id,
257 qdsp_audiozoom.zoom_param_id, qdsp_audiozoom.dir_param_id,qdsp_audiozoom.app_type);
258
259 return 0;
260}