1 /*
2 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 #define LOG_TAG "source_track"
30 /*#define LOG_NDEBUG 0*/
31 #define LOG_NDDEBUG 0
32
33 #include <errno.h>
34 #include <math.h>
35 #include <cutils/log.h>
36
37 #include "audio_hw.h"
38 #include "platform.h"
39 #include "platform_api.h"
40 #include "voice_extn.h"
41 #include <stdlib.h>
42 #include <cutils/str_parms.h>
43
44 #ifdef SOURCE_TRACKING_ENABLED
45 /* Audio Paramater Key to identify the list of start angles.
46 * Starting angle (in degrees) defines the boundary starting angle for each sector.
47 */
48 #define AUDIO_PARAMETER_KEY_SOUND_FOCUS_START_ANGLES "SoundFocus.start_angles"
49 /* Audio Paramater Key to identify the list of enable flags corresponding to each sector.
50 */
51 #define AUDIO_PARAMETER_KEY_SOUND_FOCUS_ENABLE_SECTORS "SoundFocus.enable_sectors"
52 /* Audio Paramater Key to identify the gain step value to be applied to all enabled sectors.
53 */
54 #define AUDIO_PARAMETER_KEY_SOUND_FOCUS_GAIN_STEP "SoundFocus.gain_step"
55 /* Audio Paramater Key to identify the list of voice activity detector outputs corresponding
56 * to each sector.
57 */
58 #define AUDIO_PARAMETER_KEY_SOURCE_TRACK_VAD "SourceTrack.vad"
59 /* Audio Paramater Key to identify the direction (in degrees) of arrival for desired talker
60 * (dominant source of speech).
61 */
62 #define AUDIO_PARAMETER_KEY_SOURCE_TRACK_DOA_SPEECH "SourceTrack.doa_speech"
63 /* Audio Paramater Key to identify the list of directions (in degrees) of arrival for
64 * interferers (interfering noise sources).
65 */
66 #define AUDIO_PARAMETER_KEY_SOURCE_TRACK_DOA_NOISE "SourceTrack.doa_noise"
67 /* Audio Paramater Key to identify the list of sound strength indicators at each degree
68 * of the horizontal plane referred to by a full circle (360 degrees).
69 */
70 #define AUDIO_PARAMETER_KEY_SOURCE_TRACK_POLAR_ACTIVITY "SourceTrack.polar_activity"
71
72 #define BITMASK_AUDIO_PARAMETER_KEY_SOUND_FOCUS_START_ANGLES 0x1
73 #define BITMASK_AUDIO_PARAMETER_KEY_SOUND_FOCUS_ENABLE_SECTORS 0x2
74 #define BITMASK_AUDIO_PARAMETER_KEY_SOUND_FOCUS_GAIN_STEP 0x4
75 #define BITMASK_AUDIO_PARAMETER_KEY_SOURCE_TRACK_VAD 0x8
76 #define BITMASK_AUDIO_PARAMETER_KEY_SOURCE_TRACK_DOA_SPEECH 0x10
77 #define BITMASK_AUDIO_PARAMETER_KEY_SOURCE_TRACK_DOA_NOISE 0x20
78 #define BITMASK_AUDIO_PARAMETER_KEY_SOURCE_TRACK_POLAR_ACTIVITY 0x40
79
80 #define BITMASK_AUDIO_PARAMETER_KEYS_SOUND_FOCUS \
81 (BITMASK_AUDIO_PARAMETER_KEY_SOUND_FOCUS_START_ANGLES |\
82 BITMASK_AUDIO_PARAMETER_KEY_SOUND_FOCUS_ENABLE_SECTORS |\
83 BITMASK_AUDIO_PARAMETER_KEY_SOUND_FOCUS_GAIN_STEP)
84
85 #define BITMASK_AUDIO_PARAMETER_KEYS_SOURCE_TRACKING \
86 (BITMASK_AUDIO_PARAMETER_KEY_SOURCE_TRACK_VAD |\
87 BITMASK_AUDIO_PARAMETER_KEY_SOURCE_TRACK_DOA_SPEECH |\
88 BITMASK_AUDIO_PARAMETER_KEY_SOURCE_TRACK_DOA_NOISE |\
89 BITMASK_AUDIO_PARAMETER_KEY_SOURCE_TRACK_POLAR_ACTIVITY)
90
91 #define MAX_SECTORS 8
92 #define MAX_STR_SIZE 2048
93
94 struct audio_device_to_audio_interface audio_device_to_interface_table[];
95 int audio_device_to_interface_table_len;
96
97 struct sound_focus_param {
98 uint16_t start_angle[MAX_SECTORS];
99 uint8_t enable[MAX_SECTORS];
100 uint16_t gain_step;
101 };
102
103 struct source_tracking_param {
104 uint8_t vad[MAX_SECTORS];
105 uint16_t doa_speech;
106 uint16_t doa_noise[3];
107 uint8_t polar_activity[360];
108 };
109
add_audio_intf_name_to_mixer_ctl(audio_devices_t device,char * mixer_ctl_name,struct audio_device_to_audio_interface * table,int len)110 static int add_audio_intf_name_to_mixer_ctl(audio_devices_t device, char *mixer_ctl_name,
111 struct audio_device_to_audio_interface *table, int len)
112 {
113 int ret = 0;
114 int i;
115
116 if (table == NULL) {
117 ALOGE("%s: table is NULL", __func__);
118
119 ret = -EINVAL;
120 goto done;
121 }
122
123 if (mixer_ctl_name == NULL) {
124 ret = -EINVAL;
125 goto done;
126 }
127
128 for (i=0; i < len; i++) {
129 if (device == table[i].device) {
130 strlcat(mixer_ctl_name, " ", MIXER_PATH_MAX_LENGTH);
131 strlcat(mixer_ctl_name, table[i].interface_name, MIXER_PATH_MAX_LENGTH);
132 break;
133 }
134 }
135
136 if (i == len) {
137 ALOGE("%s: Audio Device not found in the table", __func__);
138
139 ret = -EINVAL;
140 }
141 done:
142 return ret;
143 }
144
is_stt_supported_snd_device(snd_device_t snd_device)145 static bool is_stt_supported_snd_device(snd_device_t snd_device)
146 {
147 bool ret = false;
148
149 switch (snd_device) {
150 case SND_DEVICE_IN_HANDSET_DMIC:
151 case SND_DEVICE_IN_HANDSET_DMIC_AEC:
152 case SND_DEVICE_IN_HANDSET_DMIC_NS:
153 case SND_DEVICE_IN_HANDSET_DMIC_AEC_NS:
154 case SND_DEVICE_IN_HANDSET_STEREO_DMIC:
155 case SND_DEVICE_IN_HANDSET_QMIC:
156 case SND_DEVICE_IN_VOICE_DMIC:
157 case SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE:
158 case SND_DEVICE_IN_HEADSET_MIC_FLUENCE:
159 case SND_DEVICE_IN_SPEAKER_DMIC:
160 case SND_DEVICE_IN_SPEAKER_DMIC_AEC:
161 case SND_DEVICE_IN_SPEAKER_DMIC_NS:
162 case SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS:
163 case SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE:
164 case SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE:
165 case SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE:
166 case SND_DEVICE_IN_SPEAKER_QMIC_AEC:
167 case SND_DEVICE_IN_SPEAKER_QMIC_NS:
168 case SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS:
169 case SND_DEVICE_IN_VOICE_SPEAKER_DMIC:
170 case SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BROADSIDE:
171 case SND_DEVICE_IN_VOICE_SPEAKER_QMIC:
172 ret = true;
173 break;
174 default:
175 break;
176 }
177
178 return ret;
179 }
180
get_input_audio_device(audio_devices_t device)181 audio_devices_t get_input_audio_device(audio_devices_t device)
182 {
183 audio_devices_t in_device = device;
184
185 switch (device) {
186 case AUDIO_DEVICE_OUT_EARPIECE:
187 case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
188 in_device = AUDIO_DEVICE_IN_BUILTIN_MIC;
189 break;
190 case AUDIO_DEVICE_OUT_SPEAKER:
191 in_device = AUDIO_DEVICE_IN_BACK_MIC;
192 break;
193 case AUDIO_DEVICE_OUT_WIRED_HEADSET:
194 in_device = AUDIO_DEVICE_IN_WIRED_HEADSET;
195 break;
196 case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
197 in_device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
198 break;
199 default:
200 break;
201 }
202
203 return in_device;
204 }
205
derive_mixer_ctl_from_usecase_intf(struct audio_device * adev,char * mixer_ctl_name)206 static int derive_mixer_ctl_from_usecase_intf(struct audio_device *adev,
207 char *mixer_ctl_name) {
208 struct audio_usecase *usecase = NULL;
209 audio_devices_t in_device;
210 int ret = 0;
211
212 if (mixer_ctl_name == NULL) {
213 ALOGE("%s: mixer_ctl_name is NULL", __func__);
214
215 ret = -EINVAL;
216 goto done;
217 }
218
219 if (voice_is_in_call(adev)) {
220 strlcat(mixer_ctl_name, " ", MIXER_PATH_MAX_LENGTH);
221 strlcat(mixer_ctl_name, "Voice Tx", MIXER_PATH_MAX_LENGTH);
222 usecase = get_usecase_from_list(adev,
223 get_usecase_id_from_usecase_type(adev, VOICE_CALL));
224 } else if (voice_extn_compress_voip_is_active(adev)) {
225 strlcat(mixer_ctl_name, " ", MIXER_PATH_MAX_LENGTH);
226 strlcat(mixer_ctl_name, "Voice Tx", MIXER_PATH_MAX_LENGTH);
227 usecase = get_usecase_from_list(adev, USECASE_COMPRESS_VOIP_CALL);
228 } else {
229 strlcat(mixer_ctl_name, " ", MIXER_PATH_MAX_LENGTH);
230 strlcat(mixer_ctl_name, "Audio Tx", MIXER_PATH_MAX_LENGTH);
231 usecase = get_usecase_from_list(adev, get_usecase_id_from_usecase_type(adev, PCM_CAPTURE));
232 }
233
234 if (usecase && (usecase->id != USECASE_AUDIO_SPKR_CALIB_TX)) {
235 if (is_stt_supported_snd_device(usecase->in_snd_device)) {
236 in_device = get_input_audio_device(usecase->devices);
237 ret = add_audio_intf_name_to_mixer_ctl(in_device, mixer_ctl_name,
238 audio_device_to_interface_table, audio_device_to_interface_table_len);
239 } else {
240 ALOGE("%s: Sound Focus/Source Tracking not supported on the input sound device (%s)",
241 __func__, platform_get_snd_device_name(usecase->in_snd_device));
242
243 ret = -EINVAL;
244 }
245 } else {
246 ALOGE("%s: No use case is active which supports Sound Focus/Source Tracking",
247 __func__);
248
249 ret = -EINVAL;
250 }
251
252 done:
253 return ret;
254 }
255
parse_soundfocus_sourcetracking_keys(struct str_parms * parms)256 static int parse_soundfocus_sourcetracking_keys(struct str_parms *parms)
257 {
258 char *str;
259 char *value = NULL;
260 int val, len;
261 int ret = 0, err;
262 char *kv_pairs = str_parms_to_str(parms);
263
264 ALOGV_IF(kv_pairs != NULL, "%s: enter: %s", __func__, kv_pairs);
265
266 len = strlen(kv_pairs);
267 value = (char*)calloc(len, sizeof(char));
268 if(value == NULL) {
269 ret = -ENOMEM;
270 ALOGE("%s: failed to allocate memory", __func__);
271
272 goto done;
273 }
274
275 err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SOUND_FOCUS_START_ANGLES,
276 value, len);
277 if (err >= 0) {
278 str_parms_del(parms, AUDIO_PARAMETER_KEY_SOUND_FOCUS_START_ANGLES);
279 ret = ret | BITMASK_AUDIO_PARAMETER_KEY_SOUND_FOCUS_START_ANGLES;
280 }
281
282 err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SOUND_FOCUS_ENABLE_SECTORS,
283 value, len);
284 if (err >= 0) {
285 str_parms_del(parms, AUDIO_PARAMETER_KEY_SOUND_FOCUS_ENABLE_SECTORS);
286 ret = ret | BITMASK_AUDIO_PARAMETER_KEY_SOUND_FOCUS_ENABLE_SECTORS;
287 }
288
289 err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SOUND_FOCUS_GAIN_STEP,
290 value, len);
291 if (err >= 0) {
292 str_parms_del(parms, AUDIO_PARAMETER_KEY_SOUND_FOCUS_GAIN_STEP);
293 ret = ret | BITMASK_AUDIO_PARAMETER_KEY_SOUND_FOCUS_GAIN_STEP;
294 }
295
296 err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SOURCE_TRACK_VAD,
297 value, len);
298 if (err >= 0) {
299 str_parms_del(parms, AUDIO_PARAMETER_KEY_SOURCE_TRACK_VAD);
300 ret = ret | BITMASK_AUDIO_PARAMETER_KEY_SOURCE_TRACK_VAD;
301 }
302
303 err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SOURCE_TRACK_DOA_SPEECH,
304 value, len);
305 if (err >= 0) {
306 str_parms_del(parms, AUDIO_PARAMETER_KEY_SOURCE_TRACK_DOA_SPEECH);
307 ret = ret | BITMASK_AUDIO_PARAMETER_KEY_SOURCE_TRACK_DOA_SPEECH;
308 }
309
310 err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SOURCE_TRACK_DOA_NOISE,
311 value, len);
312 if (err >= 0) {
313 str_parms_del(parms, AUDIO_PARAMETER_KEY_SOURCE_TRACK_DOA_NOISE);
314 ret = ret | BITMASK_AUDIO_PARAMETER_KEY_SOURCE_TRACK_DOA_NOISE;
315 }
316
317 err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SOURCE_TRACK_POLAR_ACTIVITY,
318 value, len);
319 if (err >= 0) {
320 str_parms_del(parms, AUDIO_PARAMETER_KEY_SOURCE_TRACK_POLAR_ACTIVITY);
321 ret = ret | BITMASK_AUDIO_PARAMETER_KEY_SOURCE_TRACK_POLAR_ACTIVITY;
322 }
323
324 done:
325 free(kv_pairs);
326 if(value != NULL)
327 free(value);
328 ALOGV("%s: returning bitmask = %d", __func__, ret);
329
330 return ret;
331 }
332
get_soundfocus_sourcetracking_data(struct audio_device * adev,const int bitmask,struct sound_focus_param * sound_focus_data,struct source_tracking_param * source_tracking_data)333 static int get_soundfocus_sourcetracking_data(struct audio_device *adev,
334 const int bitmask,
335 struct sound_focus_param *sound_focus_data,
336 struct source_tracking_param *source_tracking_data)
337 {
338 struct mixer_ctl *ctl;
339 char sound_focus_mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = "Sound Focus";
340 char source_tracking_mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = "Source Tracking";
341 int ret = -EINVAL;
342 int i, count;
343
344 if (bitmask & BITMASK_AUDIO_PARAMETER_KEYS_SOUND_FOCUS) {
345 /* Derive the mixer control name based on the use case and the audio interface
346 * for the corresponding audio device
347 */
348 ret = derive_mixer_ctl_from_usecase_intf(adev, sound_focus_mixer_ctl_name);
349 if (ret != 0) {
350 ALOGE("%s: Could not get Sound Focus Params", __func__);
351
352 goto done;
353 } else {
354 ALOGV("%s: Mixer Ctl name: %s", __func__, sound_focus_mixer_ctl_name);
355 }
356
357 ctl = mixer_get_ctl_by_name(adev->mixer, sound_focus_mixer_ctl_name);
358 if (!ctl) {
359 ALOGE("%s: Could not get ctl for mixer cmd - %s",
360 __func__, sound_focus_mixer_ctl_name);
361
362 ret = -EINVAL;
363 goto done;
364 } else {
365 ALOGV("%s: Getting Sound Focus Params", __func__);
366
367 mixer_ctl_update(ctl);
368 count = mixer_ctl_get_num_values(ctl);
369 if (count != sizeof(struct sound_focus_param)) {
370 ALOGE("%s: mixer_ctl_get_num_values() invalid sound focus data size", __func__);
371
372 ret = -EINVAL;
373 goto done;
374 }
375
376 ret = mixer_ctl_get_array(ctl, (void *)sound_focus_data, count);
377 if (ret != 0) {
378 ALOGE("%s: mixer_ctl_get_array() failed to get Sound Focus Params", __func__);
379
380 ret = -EINVAL;
381 goto done;
382 }
383 }
384 }
385
386 if (bitmask & BITMASK_AUDIO_PARAMETER_KEYS_SOURCE_TRACKING) {
387 /* Derive the mixer control name based on the use case and the audio interface
388 * for the corresponding audio device
389 */
390 ret = derive_mixer_ctl_from_usecase_intf(adev, source_tracking_mixer_ctl_name);
391 if (ret != 0) {
392 ALOGE("%s: Could not get Source Tracking Params", __func__);
393
394 goto done;
395 } else {
396 ALOGV("%s: Mixer Ctl name: %s", __func__, source_tracking_mixer_ctl_name);
397 }
398
399 ctl = mixer_get_ctl_by_name(adev->mixer, source_tracking_mixer_ctl_name);
400 if (!ctl) {
401 ALOGE("%s: Could not get ctl for mixer cmd - %s",
402 __func__, source_tracking_mixer_ctl_name);
403
404 ret = -EINVAL;
405 goto done;
406 } else {
407 ALOGV("%s: Getting Source Tracking Params", __func__);
408
409 mixer_ctl_update(ctl);
410 count = mixer_ctl_get_num_values(ctl);
411 if (count != sizeof(struct source_tracking_param)) {
412 ALOGE("%s: mixer_ctl_get_num_values() invalid source tracking data size", __func__);
413
414 ret = -EINVAL;
415 goto done;
416 }
417
418 ret = mixer_ctl_get_array(ctl, (void *)source_tracking_data, count);
419 if (ret != 0) {
420 ALOGE("%s: mixer_ctl_get_array() failed to get Source Tracking Params", __func__);
421
422 ret = -EINVAL;
423 goto done;
424 }
425 }
426 }
427
428 done:
429 return ret;
430 }
431
send_soundfocus_sourcetracking_params(struct str_parms * reply,const int bitmask,const struct sound_focus_param sound_focus_data,const struct source_tracking_param source_tracking_data)432 static void send_soundfocus_sourcetracking_params(struct str_parms *reply,
433 const int bitmask,
434 const struct sound_focus_param sound_focus_data,
435 const struct source_tracking_param source_tracking_data)
436 {
437 int i = 0, len = 0;
438 char value[MAX_STR_SIZE] = "";
439
440 if (bitmask & BITMASK_AUDIO_PARAMETER_KEY_SOUND_FOCUS_START_ANGLES) {
441 for (i = 0; i < MAX_SECTORS; i++) {
442 if ((i >=4) && (sound_focus_data.start_angle[i] == 0xFFFF))
443 continue;
444 if (i)
445 snprintf(value + strlen(value), MAX_STR_SIZE, ",");
446 snprintf(value + strlen(value), MAX_STR_SIZE, "%d", sound_focus_data.start_angle[i]);
447 }
448 str_parms_add_str(reply, AUDIO_PARAMETER_KEY_SOUND_FOCUS_START_ANGLES, value);
449 }
450
451 strlcpy(value, "", sizeof(""));
452 if (bitmask & BITMASK_AUDIO_PARAMETER_KEY_SOUND_FOCUS_ENABLE_SECTORS) {
453 for (i = 0; i < MAX_SECTORS; i++) {
454 if ((i >=4) && (sound_focus_data.enable[i] == 0xFF))
455 continue;
456 if (i)
457 snprintf(value + strlen(value), MAX_STR_SIZE, ",");
458 snprintf(value + strlen(value), MAX_STR_SIZE, "%d", sound_focus_data.enable[i]);
459 }
460 str_parms_add_str(reply, AUDIO_PARAMETER_KEY_SOUND_FOCUS_ENABLE_SECTORS, value);
461 }
462
463 if (bitmask & BITMASK_AUDIO_PARAMETER_KEY_SOUND_FOCUS_GAIN_STEP)
464 str_parms_add_int(reply, AUDIO_PARAMETER_KEY_SOUND_FOCUS_GAIN_STEP, sound_focus_data.gain_step);
465
466 strlcpy(value, "", sizeof(""));
467 if (bitmask & BITMASK_AUDIO_PARAMETER_KEY_SOURCE_TRACK_VAD) {
468 for (i = 0; i < MAX_SECTORS; i++) {
469 if ((i >=4) && (source_tracking_data.vad[i] == 0xFF))
470 continue;
471 if (i)
472 snprintf(value + strlen(value), MAX_STR_SIZE, ",");
473 snprintf(value + strlen(value), MAX_STR_SIZE, "%d", source_tracking_data.vad[i]);
474 }
475 str_parms_add_str(reply, AUDIO_PARAMETER_KEY_SOURCE_TRACK_VAD, value);
476 }
477
478 if (bitmask & BITMASK_AUDIO_PARAMETER_KEY_SOURCE_TRACK_DOA_SPEECH)
479 str_parms_add_int(reply, AUDIO_PARAMETER_KEY_SOURCE_TRACK_DOA_SPEECH, source_tracking_data.doa_speech);
480
481 strlcpy(value, "", sizeof(""));
482 if (bitmask & BITMASK_AUDIO_PARAMETER_KEY_SOURCE_TRACK_DOA_NOISE) {
483 snprintf(value, MAX_STR_SIZE,
484 "%d,%d,%d", source_tracking_data.doa_noise[0], source_tracking_data.doa_noise[1], source_tracking_data.doa_noise[2]);
485 str_parms_add_str(reply, AUDIO_PARAMETER_KEY_SOURCE_TRACK_DOA_NOISE, value);
486 }
487
488 strlcpy(value, "", sizeof(""));
489 if (bitmask & BITMASK_AUDIO_PARAMETER_KEY_SOURCE_TRACK_POLAR_ACTIVITY) {
490 for (i = 0; i < 360; i++) {
491 if (i)
492 snprintf(value + strlen(value), MAX_STR_SIZE, ",");
493 snprintf(value + strlen(value), MAX_STR_SIZE, "%d", source_tracking_data.polar_activity[i]);
494 }
495 str_parms_add_str(reply, AUDIO_PARAMETER_KEY_SOURCE_TRACK_POLAR_ACTIVITY, value);
496 }
497 }
498
audio_extn_source_track_get_parameters(struct audio_device * adev,struct str_parms * query,struct str_parms * reply)499 void audio_extn_source_track_get_parameters(struct audio_device *adev,
500 struct str_parms *query,
501 struct str_parms *reply)
502 {
503 int bitmask = 0, ret = 0;
504 struct sound_focus_param sound_focus_data;
505 struct source_tracking_param source_tracking_data;
506
507 memset(&sound_focus_data, 0xFF, sizeof(struct sound_focus_param));
508 memset(&source_tracking_data, 0xFF, sizeof(struct source_tracking_param));
509
510 // Parse the input parameters string for Source Tracking keys
511 bitmask = parse_soundfocus_sourcetracking_keys(query);
512 if (bitmask) {
513 // Get the parameter values from the backend
514 ret = get_soundfocus_sourcetracking_data(adev, bitmask, &sound_focus_data, &source_tracking_data);
515 if (ret == 0) {
516 // Construct the return string with key, value pairs
517 send_soundfocus_sourcetracking_params(reply, bitmask, sound_focus_data, source_tracking_data);
518 }
519 }
520 }
521
audio_extn_source_track_set_parameters(struct audio_device * adev,struct str_parms * parms)522 void audio_extn_source_track_set_parameters(struct audio_device *adev,
523 struct str_parms *parms)
524 {
525 int len, ret, count;;
526 struct mixer_ctl *ctl;
527 char sound_focus_mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = "Sound Focus";
528 char *value = NULL;
529 char *kv_pairs = str_parms_to_str(parms);
530
531 len = strlen(kv_pairs);
532 value = (char*)calloc(len, sizeof(char));
533 if(value == NULL) {
534 ret = -ENOMEM;
535 ALOGE("%s: failed to allocate memory", __func__);
536
537 goto done;
538 }
539
540 // Parse the input parameter string for Source Tracking key, value pairs
541 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SOUND_FOCUS_START_ANGLES,
542 value, len);
543 if (ret >= 0) {
544 char *saveptr, *tok;
545 int i = 0, val;
546 struct sound_focus_param sound_focus_param;
547
548 memset(&sound_focus_param, 0xFF, sizeof(struct sound_focus_param));
549
550 str_parms_del(parms, AUDIO_PARAMETER_KEY_SOUND_FOCUS_START_ANGLES);
551 tok = strtok_r(value, ",", &saveptr);
552 while ((i < MAX_SECTORS) && (tok != NULL)) {
553 if (sscanf(tok, "%d", &val) == 1) {
554 sound_focus_param.start_angle[i++] = (uint16_t)val;
555 }
556 tok = strtok_r(NULL, ",", &saveptr);
557 }
558
559 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SOUND_FOCUS_ENABLE_SECTORS,
560 value, len);
561 if (ret >= 0) {
562 str_parms_del(parms, AUDIO_PARAMETER_KEY_SOUND_FOCUS_ENABLE_SECTORS);
563 tok = strtok_r(value, ",", &saveptr);
564 i = 0;
565 while ((i < MAX_SECTORS) && (tok != NULL)) {
566 if (sscanf(tok, "%d", &val) == 1) {
567 sound_focus_param.enable[i++] = (uint8_t)val;
568 }
569 tok = strtok_r(NULL, ",", &saveptr);
570 }
571 } else {
572 ALOGE("%s: SoundFocus.enable_sectors key not found", __func__);
573
574 goto done;
575 }
576
577 ret = str_parms_get_int(parms, AUDIO_PARAMETER_KEY_SOUND_FOCUS_GAIN_STEP, &val);
578 if (ret >= 0) {
579 str_parms_del(parms, AUDIO_PARAMETER_KEY_SOUND_FOCUS_GAIN_STEP);
580 sound_focus_param.gain_step = (uint16_t)val;
581 } else {
582 ALOGE("%s: SoundFocus.gain_step key not found", __func__);
583
584 goto done;
585 }
586
587 /* Derive the mixer control name based on the use case and the audio h/w
588 * interface name for the corresponding audio device
589 */
590 ret = derive_mixer_ctl_from_usecase_intf(adev, sound_focus_mixer_ctl_name);
591 if (ret != 0) {
592 ALOGE("%s: Could not set Sound Focus Params", __func__);
593
594 goto done;
595 } else {
596 ALOGV("%s: Mixer Ctl name: %s", __func__, sound_focus_mixer_ctl_name);
597 }
598
599 ctl = mixer_get_ctl_by_name(adev->mixer, sound_focus_mixer_ctl_name);
600 if (!ctl) {
601 ALOGE("%s: Could not get ctl for mixer cmd - %s",
602 __func__, sound_focus_mixer_ctl_name);
603
604 goto done;
605 } else {
606 ALOGV("%s: Setting Sound Focus Params", __func__);
607
608 for (i = 0; i < MAX_SECTORS;i++) {
609 ALOGV("%s: start_angles[%d] = %d", __func__, i, sound_focus_param.start_angle[i]);
610 }
611 for (i = 0; i < MAX_SECTORS;i++) {
612 ALOGV("%s: enable_sectors[%d] = %d", __func__, i, sound_focus_param.enable[i]);
613 }
614 ALOGV("%s: gain_step = %d", __func__, sound_focus_param.gain_step);
615
616 mixer_ctl_update(ctl);
617 count = mixer_ctl_get_num_values(ctl);
618 if (count != sizeof(struct sound_focus_param)) {
619 ALOGE("%s: mixer_ctl_get_num_values() invalid data size", __func__);
620
621 goto done;
622 }
623
624 // Set the parameters on the mixer control derived above
625 ret = mixer_ctl_set_array(ctl, (void *)&sound_focus_param, count);
626 if (ret != 0) {
627 ALOGE("%s: mixer_ctl_set_array() failed to set Sound Focus Params", __func__);
628
629 goto done;
630 }
631 }
632 }
633
634 done:
635 free(kv_pairs);
636 if(value != NULL)
637 free(value);
638 return;
639 }
640 #endif /* SOURCE_TRACKING_ENABLED end */
641