blob: 3364e92c98a85f66d908cb6874ff5b2d0c1863d2 [file] [log] [blame]
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001/*
2 * Copyright (C) 2013 The Android Open Source Project
Christopher N. Hesse2f6f8582017-01-28 12:46:15 +01003 * Copyright (C) 2017 Christopher N. Hesse <raymanfx@gmail.com>
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#define LOG_TAG "audio_hw_primary"
19/*#define LOG_NDEBUG 0*/
20/*#define VERY_VERY_VERBOSE_LOGGING*/
21#ifdef VERY_VERY_VERBOSE_LOGGING
22#define ALOGVV ALOGV
23#else
24#define ALOGVV(a...) do { } while(0)
25#endif
26
27#define _GNU_SOURCE
28#include <errno.h>
29#include <pthread.h>
30#include <stdint.h>
31#include <sys/time.h>
32#include <stdlib.h>
33#include <math.h>
34#include <dlfcn.h>
Christopher N. Hesse297a6362017-01-28 12:40:45 +010035
36#include <cutils/log.h>
37#include <cutils/str_parms.h>
38#include <cutils/atomic.h>
39#include <cutils/sched_policy.h>
40#include <cutils/properties.h>
41
42#include <hardware/audio_effect.h>
43#include <system/thread_defs.h>
44#include <audio_effects/effect_aec.h>
45#include <audio_effects/effect_ns.h>
46#include "audio_hw.h"
Christopher N. Hesse757ac412017-01-28 14:42:48 +010047#include "compress_offload.h"
Christopher N. Hesse297a6362017-01-28 12:40:45 +010048
49#include "sound/compress_params.h"
50
Christopher N. Hesse297a6362017-01-28 12:40:45 +010051
52/* TODO: the following PCM device profiles could be read from a config file */
53static struct pcm_device_profile pcm_device_playback = {
54 .config = {
55 .channels = PLAYBACK_DEFAULT_CHANNEL_COUNT,
56 .rate = PLAYBACK_DEFAULT_SAMPLING_RATE,
57 .period_size = PLAYBACK_PERIOD_SIZE,
58 .period_count = PLAYBACK_PERIOD_COUNT,
59 .format = PCM_FORMAT_S16_LE,
60 .start_threshold = PLAYBACK_START_THRESHOLD(PLAYBACK_PERIOD_SIZE, PLAYBACK_PERIOD_COUNT),
61 .stop_threshold = PLAYBACK_STOP_THRESHOLD(PLAYBACK_PERIOD_SIZE, PLAYBACK_PERIOD_COUNT),
62 .silence_threshold = 0,
63 .silence_size = UINT_MAX,
64 .avail_min = PLAYBACK_AVAILABLE_MIN,
65 },
66 .card = SOUND_CARD,
67 .id = 9,
68 .type = PCM_PLAYBACK,
69 .devices = AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|
70 AUDIO_DEVICE_OUT_SPEAKER,
71};
72
73static struct pcm_device_profile pcm_device_capture = {
74 .config = {
75 .channels = CAPTURE_DEFAULT_CHANNEL_COUNT,
76 .rate = CAPTURE_DEFAULT_SAMPLING_RATE,
77 .period_size = CAPTURE_PERIOD_SIZE,
78 .period_count = CAPTURE_PERIOD_COUNT,
79 .format = PCM_FORMAT_S16_LE,
80 .start_threshold = CAPTURE_START_THRESHOLD,
81 .stop_threshold = 0,
82 .silence_threshold = 0,
83 .avail_min = 0,
84 },
85 .card = SOUND_CARD,
86 .id = 0,
87 .type = PCM_CAPTURE,
88 .devices = AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BACK_MIC,
89};
90
91static struct pcm_device_profile pcm_device_capture_low_latency = {
92 .config = {
93 .channels = CAPTURE_DEFAULT_CHANNEL_COUNT,
94 .rate = CAPTURE_DEFAULT_SAMPLING_RATE,
95 .period_size = CAPTURE_PERIOD_SIZE_LOW_LATENCY,
96 .period_count = CAPTURE_PERIOD_COUNT_LOW_LATENCY,
97 .format = PCM_FORMAT_S16_LE,
98 .start_threshold = CAPTURE_START_THRESHOLD,
99 .stop_threshold = 0,
100 .silence_threshold = 0,
101 .avail_min = 0,
102 },
103 .card = SOUND_CARD,
104 .id = 0,
105 .type = PCM_CAPTURE_LOW_LATENCY,
106 .devices = AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BACK_MIC,
107};
108
109static struct pcm_device_profile pcm_device_capture_loopback_aec = {
110 .config = {
111 .channels = CAPTURE_DEFAULT_CHANNEL_COUNT,
112 .rate = CAPTURE_DEFAULT_SAMPLING_RATE,
113 .period_size = CAPTURE_PERIOD_SIZE,
114 .period_count = CAPTURE_PERIOD_COUNT,
115 .format = PCM_FORMAT_S16_LE,
116 .start_threshold = CAPTURE_START_THRESHOLD,
117 .stop_threshold = 0,
118 .silence_threshold = 0,
119 .avail_min = 0,
120 },
121 .card = SOUND_CARD,
122 .id = 1,
123 .type = PCM_CAPTURE,
124 .devices = SND_DEVICE_IN_LOOPBACK_AEC,
125};
126
127static struct pcm_device_profile pcm_device_playback_sco = {
128 .config = {
129 .channels = SCO_DEFAULT_CHANNEL_COUNT,
130 .rate = SCO_DEFAULT_SAMPLING_RATE,
131 .period_size = SCO_PERIOD_SIZE,
132 .period_count = SCO_PERIOD_COUNT,
133 .format = PCM_FORMAT_S16_LE,
134 .start_threshold = SCO_START_THRESHOLD,
135 .stop_threshold = SCO_STOP_THRESHOLD,
136 .silence_threshold = 0,
137 .avail_min = SCO_AVAILABLE_MIN,
138 },
139 .card = SOUND_CARD,
140 .id = 2,
141 .type = PCM_PLAYBACK,
142 .devices =
143 AUDIO_DEVICE_OUT_BLUETOOTH_SCO|AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET|
144 AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT,
145};
146
147static struct pcm_device_profile pcm_device_capture_sco = {
148 .config = {
149 .channels = SCO_DEFAULT_CHANNEL_COUNT,
150 .rate = SCO_DEFAULT_SAMPLING_RATE,
151 .period_size = SCO_PERIOD_SIZE,
152 .period_count = SCO_PERIOD_COUNT,
153 .format = PCM_FORMAT_S16_LE,
154 .start_threshold = CAPTURE_START_THRESHOLD,
155 .stop_threshold = 0,
156 .silence_threshold = 0,
157 .avail_min = 0,
158 },
159 .card = SOUND_CARD,
160 .id = 2,
161 .type = PCM_CAPTURE,
162 .devices = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
163};
164
165static struct pcm_device_profile pcm_device_hotword_streaming = {
166 .config = {
167 .channels = 1,
168 .rate = 16000,
169 .period_size = CAPTURE_PERIOD_SIZE,
170 .period_count = CAPTURE_PERIOD_COUNT,
171 .format = PCM_FORMAT_S16_LE,
172 .start_threshold = CAPTURE_START_THRESHOLD,
173 .stop_threshold = 0,
174 .silence_threshold = 0,
175 .avail_min = 0,
176 },
177 .card = SOUND_CARD,
178 .id = 0,
179 .type = PCM_HOTWORD_STREAMING,
180 .devices = AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BACK_MIC
181};
182
183static struct pcm_device_profile * const pcm_devices[] = {
184 &pcm_device_playback,
185 &pcm_device_capture,
186 &pcm_device_capture_low_latency,
187 &pcm_device_playback_sco,
188 &pcm_device_capture_sco,
189 &pcm_device_capture_loopback_aec,
190 &pcm_device_hotword_streaming,
191 NULL,
192};
193
194static const char * const use_case_table[AUDIO_USECASE_MAX] = {
195 [USECASE_AUDIO_PLAYBACK] = "playback",
196 [USECASE_AUDIO_PLAYBACK_MULTI_CH] = "playback multi-channel",
197 [USECASE_AUDIO_PLAYBACK_OFFLOAD] = "compress-offload-playback",
198 [USECASE_AUDIO_CAPTURE] = "capture",
199 [USECASE_AUDIO_CAPTURE_HOTWORD] = "capture-hotword",
200 [USECASE_VOICE_CALL] = "voice-call",
201};
202
203
204#define STRING_TO_ENUM(string) { #string, string }
205
206static unsigned int audio_device_ref_count;
207
208static struct pcm_config pcm_config_deep_buffer = {
209 .channels = 2,
210 .rate = DEEP_BUFFER_OUTPUT_SAMPLING_RATE,
211 .period_size = DEEP_BUFFER_OUTPUT_PERIOD_SIZE,
212 .period_count = DEEP_BUFFER_OUTPUT_PERIOD_COUNT,
213 .format = PCM_FORMAT_S16_LE,
214 .start_threshold = DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4,
215 .stop_threshold = INT_MAX,
216 .avail_min = DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4,
217};
218
219struct string_to_enum {
220 const char *name;
221 uint32_t value;
222};
223
224static const struct string_to_enum out_channels_name_to_enum_table[] = {
225 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO),
226 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1),
227 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
228};
229
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100230static bool is_supported_format(audio_format_t format)
231{
232 if (format == AUDIO_FORMAT_MP3 ||
233 ((format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_AAC))
234 return true;
235
236 return false;
237}
238
239static int get_snd_codec_id(audio_format_t format)
240{
241 int id = 0;
242
243 switch (format & AUDIO_FORMAT_MAIN_MASK) {
244 case AUDIO_FORMAT_MP3:
245 id = SND_AUDIOCODEC_MP3;
246 break;
247 case AUDIO_FORMAT_AAC:
248 id = SND_AUDIOCODEC_AAC;
249 break;
250 default:
251 ALOGE("%s: Unsupported audio format", __func__);
252 }
253
254 return id;
255}
256
257/* Array to store sound devices */
258static const char * const device_table[SND_DEVICE_MAX] = {
259 [SND_DEVICE_NONE] = "none",
260 /* Playback sound devices */
261 [SND_DEVICE_OUT_HANDSET] = "handset",
262 [SND_DEVICE_OUT_SPEAKER] = "speaker",
263 [SND_DEVICE_OUT_HEADPHONES] = "headphones",
264 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
265 [SND_DEVICE_OUT_VOICE_HANDSET] = "voice-handset",
266 [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
267 [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
268 [SND_DEVICE_OUT_HDMI] = "hdmi",
269 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
270 [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
271 [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
272 [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
273 [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
274
275 /* Capture sound devices */
276 [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
277 [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
278 [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
279 [SND_DEVICE_IN_HANDSET_MIC_AEC] = "handset-mic",
280 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "voice-speaker-mic",
281 [SND_DEVICE_IN_HEADSET_MIC_AEC] = "headset-mic",
282 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
283 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
284 [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
285 [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
286 [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
287 [SND_DEVICE_IN_VOICE_DMIC_1] = "voice-dmic-1",
288 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_1] = "voice-speaker-dmic-1",
289 [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic",
290 [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic",
291 [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic",
292 [SND_DEVICE_IN_VOICE_REC_HEADSET_MIC] = "voice-rec-headset-mic",
293 [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
294 [SND_DEVICE_IN_VOICE_REC_DMIC_1] = "voice-rec-dmic-1",
295 [SND_DEVICE_IN_VOICE_REC_DMIC_NS_1] = "voice-rec-dmic-ns-1",
296 [SND_DEVICE_IN_LOOPBACK_AEC] = "loopback-aec",
297};
298
299static struct mixer_card *adev_get_mixer_for_card(struct audio_device *adev, int card)
300{
301 struct mixer_card *mixer_card;
302 struct listnode *node;
303
304 list_for_each(node, &adev->mixer_list) {
305 mixer_card = node_to_item(node, struct mixer_card, adev_list_node);
306 if (mixer_card->card == card)
307 return mixer_card;
308 }
309 return NULL;
310}
311
312static struct mixer_card *uc_get_mixer_for_card(struct audio_usecase *usecase, int card)
313{
314 struct mixer_card *mixer_card;
315 struct listnode *node;
316
317 list_for_each(node, &usecase->mixer_list) {
318 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[usecase->id]);
319 if (mixer_card->card == card)
320 return mixer_card;
321 }
322 return NULL;
323}
324
325static void free_mixer_list(struct audio_device *adev)
326{
327 struct mixer_card *mixer_card;
328 struct listnode *node;
329 struct listnode *next;
330
331 list_for_each_safe(node, next, &adev->mixer_list) {
332 mixer_card = node_to_item(node, struct mixer_card, adev_list_node);
333 list_remove(node);
334 audio_route_free(mixer_card->audio_route);
335 free(mixer_card);
336 }
337}
338
339static int mixer_init(struct audio_device *adev)
340{
341 int i;
342 int card;
343 int retry_num;
344 struct mixer *mixer;
345 struct audio_route *audio_route;
346 char mixer_path[PATH_MAX];
347 struct mixer_card *mixer_card;
348 struct listnode *node;
349
350 list_init(&adev->mixer_list);
351
352 for (i = 0; pcm_devices[i] != NULL; i++) {
353 card = pcm_devices[i]->card;
354 if (adev_get_mixer_for_card(adev, card) == NULL) {
355 retry_num = 0;
356 do {
357 mixer = mixer_open(card);
358 if (mixer == NULL) {
359 if (++retry_num > RETRY_NUMBER) {
360 ALOGE("%s unable to open the mixer for--card %d, aborting.",
361 __func__, card);
362 goto error;
363 }
364 usleep(RETRY_US);
365 }
366 } while (mixer == NULL);
367
368 sprintf(mixer_path, "/system/etc/mixer_paths_%d.xml", card);
369 audio_route = audio_route_init(card, mixer_path);
370 if (!audio_route) {
371 ALOGE("%s: Failed to init audio route controls for card %d, aborting.",
372 __func__, card);
373 goto error;
374 }
375 mixer_card = calloc(1, sizeof(struct mixer_card));
376 mixer_card->card = card;
377 mixer_card->mixer = mixer;
378 mixer_card->audio_route = audio_route;
379 list_add_tail(&adev->mixer_list, &mixer_card->adev_list_node);
380 }
381 }
382
383 return 0;
384
385error:
386 free_mixer_list(adev);
387 return -ENODEV;
388}
389
390static const char *get_snd_device_name(snd_device_t snd_device)
391{
392 const char *name = NULL;
393
394 if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
395 name = device_table[snd_device];
396
397 ALOGE_IF(name == NULL, "%s: invalid snd device %d", __func__, snd_device);
398
399 return name;
400}
401
402static const char *get_snd_device_display_name(snd_device_t snd_device)
403{
404 const char *name = get_snd_device_name(snd_device);
405
406 if (name == NULL)
407 name = "SND DEVICE NOT FOUND";
408
409 return name;
410}
411
412static struct pcm_device_profile *get_pcm_device(usecase_type_t uc_type, audio_devices_t devices)
413{
414 int i;
415
416 devices &= ~AUDIO_DEVICE_BIT_IN;
417 for (i = 0; pcm_devices[i] != NULL; i++) {
418 if ((pcm_devices[i]->type == uc_type) &&
419 (devices & pcm_devices[i]->devices))
420 break;
421 }
422 return pcm_devices[i];
423}
424
425static struct audio_usecase *get_usecase_from_id(struct audio_device *adev,
426 audio_usecase_t uc_id)
427{
428 struct audio_usecase *usecase;
429 struct listnode *node;
430
431 list_for_each(node, &adev->usecase_list) {
432 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
433 if (usecase->id == uc_id)
434 return usecase;
435 }
436 return NULL;
437}
438
439static struct audio_usecase *get_usecase_from_type(struct audio_device *adev,
440 usecase_type_t type)
441{
442 struct audio_usecase *usecase;
443 struct listnode *node;
444
445 list_for_each(node, &adev->usecase_list) {
446 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
447 if (usecase->type & type)
448 return usecase;
449 }
450 return NULL;
451}
452
453/* always called with adev lock held */
454static int set_voice_volume_l(struct audio_device *adev, float volume)
455{
456 int err = 0;
457 (void)volume;
458
459 if (adev->mode == AUDIO_MODE_IN_CALL) {
460 /* TODO */
461 }
462 return err;
463}
464
465
466static snd_device_t get_output_snd_device(struct audio_device *adev, audio_devices_t devices)
467{
468
469 audio_mode_t mode = adev->mode;
470 snd_device_t snd_device = SND_DEVICE_NONE;
471
472 ALOGV("%s: enter: output devices(%#x), mode(%d)", __func__, devices, mode);
473 if (devices == AUDIO_DEVICE_NONE ||
474 devices & AUDIO_DEVICE_BIT_IN) {
475 ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
476 goto exit;
477 }
478
479 if (mode == AUDIO_MODE_IN_CALL) {
480 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
481 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
482 if (adev->tty_mode == TTY_MODE_FULL)
483 snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES;
484 else if (adev->tty_mode == TTY_MODE_VCO)
485 snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES;
486 else if (adev->tty_mode == TTY_MODE_HCO)
487 snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
488 else
489 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
490 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
491 snd_device = SND_DEVICE_OUT_BT_SCO;
492 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
493 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
494 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
495 snd_device = SND_DEVICE_OUT_HANDSET;
496 }
497 if (snd_device != SND_DEVICE_NONE) {
498 goto exit;
499 }
500 }
501
502 if (popcount(devices) == 2) {
503 if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
504 AUDIO_DEVICE_OUT_SPEAKER)) {
505 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
506 } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
507 AUDIO_DEVICE_OUT_SPEAKER)) {
508 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
509 } else {
510 ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
511 goto exit;
512 }
513 if (snd_device != SND_DEVICE_NONE) {
514 goto exit;
515 }
516 }
517
518 if (popcount(devices) != 1) {
519 ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
520 goto exit;
521 }
522
523 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
524 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
525 snd_device = SND_DEVICE_OUT_HEADPHONES;
526 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
527 snd_device = SND_DEVICE_OUT_SPEAKER;
528 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
529 snd_device = SND_DEVICE_OUT_BT_SCO;
530 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
531 snd_device = SND_DEVICE_OUT_HANDSET;
532 } else {
533 ALOGE("%s: Unknown device(s) %#x", __func__, devices);
534 }
535exit:
536 ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
537 return snd_device;
538}
539
540static snd_device_t get_input_snd_device(struct audio_device *adev, audio_devices_t out_device)
541{
542 audio_source_t source;
543 audio_mode_t mode = adev->mode;
544 audio_devices_t in_device;
545 audio_channel_mask_t channel_mask;
546 snd_device_t snd_device = SND_DEVICE_NONE;
547 struct stream_in *active_input = NULL;
548 struct audio_usecase *usecase;
549
550 usecase = get_usecase_from_type(adev, PCM_CAPTURE|VOICE_CALL);
551 if (usecase != NULL) {
552 active_input = (struct stream_in *)usecase->stream;
553 }
554 source = (active_input == NULL) ?
555 AUDIO_SOURCE_DEFAULT : active_input->source;
556
557 in_device = ((active_input == NULL) ?
558 AUDIO_DEVICE_NONE : active_input->devices)
559 & ~AUDIO_DEVICE_BIT_IN;
560 channel_mask = (active_input == NULL) ?
561 AUDIO_CHANNEL_IN_MONO : active_input->main_channels;
562
563 ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
564 __func__, out_device, in_device);
565 if (mode == AUDIO_MODE_IN_CALL) {
566 if (out_device == AUDIO_DEVICE_NONE) {
567 ALOGE("%s: No output device set for voice call", __func__);
568 goto exit;
569 }
570 if (adev->tty_mode != TTY_MODE_OFF) {
571 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
572 out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
573 switch (adev->tty_mode) {
574 case TTY_MODE_FULL:
575 snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
576 break;
577 case TTY_MODE_VCO:
578 snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC;
579 break;
580 case TTY_MODE_HCO:
581 snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC;
582 break;
583 default:
584 ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->tty_mode);
585 }
586 goto exit;
587 }
588 }
589 if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
590 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
591 snd_device = SND_DEVICE_IN_HANDSET_MIC;
592 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
593 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
594 } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
595 snd_device = SND_DEVICE_IN_BT_SCO_MIC ;
596 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
597 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
598 }
599 } else if (source == AUDIO_SOURCE_CAMCORDER) {
600 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
601 in_device & AUDIO_DEVICE_IN_BACK_MIC) {
602 snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
603 }
604 } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
605 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
606 if (adev->dualmic_config == DUALMIC_CONFIG_1) {
607 if (channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK)
608 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_1;
609 else if (adev->ns_in_voice_rec)
610 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_NS_1;
611 }
612
613 if (snd_device == SND_DEVICE_NONE) {
614 snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
615 }
616 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
617 snd_device = SND_DEVICE_IN_VOICE_REC_HEADSET_MIC;
618 }
619 } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION || source == AUDIO_SOURCE_MIC) {
620 if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
621 in_device = AUDIO_DEVICE_IN_BACK_MIC;
622 if (active_input) {
623 if (active_input->enable_aec) {
624 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
625 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
626 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
627 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
628 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
629 } else {
630 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
631 }
632 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
633 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
634 }
635 }
636 /* TODO: set echo reference */
637 }
638 } else if (source == AUDIO_SOURCE_DEFAULT) {
639 goto exit;
640 }
641
642
643 if (snd_device != SND_DEVICE_NONE) {
644 goto exit;
645 }
646
647 if (in_device != AUDIO_DEVICE_NONE &&
648 !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
649 !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
650 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
651 snd_device = SND_DEVICE_IN_HANDSET_MIC;
652 } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
653 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
654 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
655 snd_device = SND_DEVICE_IN_HEADSET_MIC;
656 } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
657 snd_device = SND_DEVICE_IN_BT_SCO_MIC ;
658 } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
659 snd_device = SND_DEVICE_IN_HDMI_MIC;
660 } else {
661 ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
662 ALOGW("%s: Using default handset-mic", __func__);
663 snd_device = SND_DEVICE_IN_HANDSET_MIC;
664 }
665 } else {
666 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
667 snd_device = SND_DEVICE_IN_HANDSET_MIC;
668 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
669 snd_device = SND_DEVICE_IN_HEADSET_MIC;
670 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
671 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
672 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
673 snd_device = SND_DEVICE_IN_HANDSET_MIC;
674 } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
675 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
676 } else {
677 ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
678 ALOGW("%s: Using default handset-mic", __func__);
679 snd_device = SND_DEVICE_IN_HANDSET_MIC;
680 }
681 }
682exit:
683 ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
684 return snd_device;
685}
686
687static int set_hdmi_channels(struct audio_device *adev, int channel_count)
688{
689 struct mixer_ctl *ctl;
690 const char *mixer_ctl_name = "";
691 (void)adev;
692 (void)channel_count;
693 /* TODO */
694
695 return 0;
696}
697
698static int edid_get_max_channels(struct audio_device *adev)
699{
700 int max_channels = 2;
701 struct mixer_ctl *ctl;
702 (void)adev;
703
704 /* TODO */
705 return max_channels;
706}
707
708/* Delay in Us */
709static int64_t render_latency(audio_usecase_t usecase)
710{
711 (void)usecase;
712 /* TODO */
713 return 0;
714}
715
716static int enable_snd_device(struct audio_device *adev,
717 struct audio_usecase *uc_info,
718 snd_device_t snd_device,
719 bool update_mixer)
720{
721 struct mixer_card *mixer_card;
722 struct listnode *node;
723 const char *snd_device_name = get_snd_device_name(snd_device);
724
725 if (snd_device_name == NULL)
726 return -EINVAL;
727
728 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES) {
729 ALOGV("Request to enable combo device: enable individual devices\n");
730 enable_snd_device(adev, uc_info, SND_DEVICE_OUT_SPEAKER, update_mixer);
731 enable_snd_device(adev, uc_info, SND_DEVICE_OUT_HEADPHONES, update_mixer);
732 return 0;
733 }
734 adev->snd_dev_ref_cnt[snd_device]++;
735 if (adev->snd_dev_ref_cnt[snd_device] > 1) {
736 ALOGV("%s: snd_device(%d: %s) is already active",
737 __func__, snd_device, snd_device_name);
738 return 0;
739 }
740
741 ALOGV("%s: snd_device(%d: %s)", __func__,
742 snd_device, snd_device_name);
743
744 list_for_each(node, &uc_info->mixer_list) {
745 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]);
746 audio_route_apply_path(mixer_card->audio_route, snd_device_name);
747 if (update_mixer)
748 audio_route_update_mixer(mixer_card->audio_route);
749 }
750
751 return 0;
752}
753
Christopher N. Hesse757ac412017-01-28 14:42:48 +0100754int disable_snd_device(struct audio_device *adev,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100755 struct audio_usecase *uc_info,
756 snd_device_t snd_device,
757 bool update_mixer)
758{
759 struct mixer_card *mixer_card;
760 struct listnode *node;
761 const char *snd_device_name = get_snd_device_name(snd_device);
762
763 if (snd_device_name == NULL)
764 return -EINVAL;
765
766 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES) {
767 ALOGV("Request to disable combo device: disable individual devices\n");
768 disable_snd_device(adev, uc_info, SND_DEVICE_OUT_SPEAKER, update_mixer);
769 disable_snd_device(adev, uc_info, SND_DEVICE_OUT_HEADPHONES, update_mixer);
770 return 0;
771 }
772
773 if (adev->snd_dev_ref_cnt[snd_device] <= 0) {
774 ALOGE("%s: device ref cnt is already 0", __func__);
775 return -EINVAL;
776 }
777 adev->snd_dev_ref_cnt[snd_device]--;
778 if (adev->snd_dev_ref_cnt[snd_device] == 0) {
779 ALOGV("%s: snd_device(%d: %s)", __func__,
780 snd_device, snd_device_name);
781 list_for_each(node, &uc_info->mixer_list) {
782 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]);
783 audio_route_reset_path(mixer_card->audio_route, snd_device_name);
784 if (update_mixer)
785 audio_route_update_mixer(mixer_card->audio_route);
786 }
787 }
788 return 0;
789}
790
791static int select_devices(struct audio_device *adev,
792 audio_usecase_t uc_id)
793{
794 snd_device_t out_snd_device = SND_DEVICE_NONE;
795 snd_device_t in_snd_device = SND_DEVICE_NONE;
796 struct audio_usecase *usecase = NULL;
797 struct audio_usecase *vc_usecase = NULL;
798 struct listnode *node;
799 struct stream_in *active_input = NULL;
800 struct stream_out *active_out;
801 struct mixer_card *mixer_card;
802
803 ALOGV("%s: usecase(%d)", __func__, uc_id);
804
805 if (uc_id == USECASE_AUDIO_CAPTURE_HOTWORD)
806 return 0;
807
808 usecase = get_usecase_from_type(adev, PCM_CAPTURE|VOICE_CALL);
809 if (usecase != NULL) {
810 active_input = (struct stream_in *)usecase->stream;
811 }
812
813 usecase = get_usecase_from_id(adev, uc_id);
814 if (usecase == NULL) {
815 ALOGE("%s: Could not find the usecase(%d)", __func__, uc_id);
816 return -EINVAL;
817 }
818 active_out = (struct stream_out *)usecase->stream;
819
820 if (usecase->type == VOICE_CALL) {
821 out_snd_device = get_output_snd_device(adev, active_out->devices);
822 in_snd_device = get_input_snd_device(adev, active_out->devices);
823 usecase->devices = active_out->devices;
824 } else {
825 /*
826 * If the voice call is active, use the sound devices of voice call usecase
827 * so that it would not result any device switch. All the usecases will
828 * be switched to new device when select_devices() is called for voice call
829 * usecase.
830 */
831 if (adev->in_call) {
832 vc_usecase = get_usecase_from_id(adev, USECASE_VOICE_CALL);
833 if (usecase == NULL) {
834 ALOGE("%s: Could not find the voice call usecase", __func__);
835 } else {
836 in_snd_device = vc_usecase->in_snd_device;
837 out_snd_device = vc_usecase->out_snd_device;
838 }
839 }
840 if (usecase->type == PCM_PLAYBACK) {
841 usecase->devices = active_out->devices;
842 in_snd_device = SND_DEVICE_NONE;
843 if (out_snd_device == SND_DEVICE_NONE) {
844 out_snd_device = get_output_snd_device(adev, active_out->devices);
845 if (active_out == adev->primary_output &&
846 active_input &&
847 active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
848 select_devices(adev, active_input->usecase);
849 }
850 }
851 } else if (usecase->type == PCM_CAPTURE) {
852 usecase->devices = ((struct stream_in *)usecase->stream)->devices;
853 out_snd_device = SND_DEVICE_NONE;
854 if (in_snd_device == SND_DEVICE_NONE) {
855 if (active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
856 adev->primary_output && !adev->primary_output->standby) {
857 in_snd_device = get_input_snd_device(adev, adev->primary_output->devices);
858 } else {
859 in_snd_device = get_input_snd_device(adev, AUDIO_DEVICE_NONE);
860 }
861 }
862 }
863 }
864
865 if (out_snd_device == usecase->out_snd_device &&
866 in_snd_device == usecase->in_snd_device) {
867 return 0;
868 }
869
870 ALOGV("%s: out_snd_device(%d: %s) in_snd_device(%d: %s)", __func__,
871 out_snd_device, get_snd_device_display_name(out_snd_device),
872 in_snd_device, get_snd_device_display_name(in_snd_device));
873
874
875 /* Disable current sound devices */
876 if (usecase->out_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100877 disable_snd_device(adev, usecase, usecase->out_snd_device, false);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100878 }
879
880 if (usecase->in_snd_device != SND_DEVICE_NONE) {
881 disable_snd_device(adev, usecase, usecase->in_snd_device, false);
882 }
883
884 /* Enable new sound devices */
885 if (out_snd_device != SND_DEVICE_NONE) {
886 enable_snd_device(adev, usecase, out_snd_device, false);
887 }
888
889 if (in_snd_device != SND_DEVICE_NONE) {
890 enable_snd_device(adev, usecase, in_snd_device, false);
891 }
892
893 list_for_each(node, &usecase->mixer_list) {
894 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[usecase->id]);
895 audio_route_update_mixer(mixer_card->audio_route);
896 }
897
898 usecase->in_snd_device = in_snd_device;
899 usecase->out_snd_device = out_snd_device;
900
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100901 return 0;
902}
903
904
905static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames);
906static int do_in_standby_l(struct stream_in *in);
907
908#ifdef PREPROCESSING_ENABLED
909static void get_capture_reference_delay(struct stream_in *in,
910 size_t frames __unused,
911 struct echo_reference_buffer *buffer)
912{
913 ALOGVV("%s: enter:)", __func__);
914
915 /* read frames available in kernel driver buffer */
916 unsigned int kernel_frames;
917 struct timespec tstamp;
918 long buf_delay;
919 long kernel_delay;
920 long delay_ns;
921 struct pcm_device *ref_device;
922 long rsmp_delay = 0;
923
924 ref_device = node_to_item(list_tail(&in->pcm_dev_list),
925 struct pcm_device, stream_list_node);
926
927 if (pcm_get_htimestamp(ref_device->pcm, &kernel_frames, &tstamp) < 0) {
928 buffer->time_stamp.tv_sec = 0;
929 buffer->time_stamp.tv_nsec = 0;
930 buffer->delay_ns = 0;
931 ALOGW("read get_capture_reference_delay(): pcm_htimestamp error");
932 return;
933 }
934
935 /* adjust render time stamp with delay added by current driver buffer.
936 * Add the duration of current frame as we want the render time of the last
937 * sample being written. */
938
939 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / ref_device->pcm_profile->config.rate);
940
941 buffer->time_stamp = tstamp;
942 buffer->delay_ns = kernel_delay;
943
944 ALOGVV("get_capture_reference_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5d],"
945 " delay_ns: [%d] , frames:[%zd]",
946 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns, frames);
947}
948
949static void get_capture_delay(struct stream_in *in,
950 size_t frames __unused,
951 struct echo_reference_buffer *buffer)
952{
953 ALOGVV("%s: enter:)", __func__);
954 /* read frames available in kernel driver buffer */
955 unsigned int kernel_frames;
956 struct timespec tstamp;
957 long buf_delay;
958 long rsmp_delay;
959 long kernel_delay;
960 long delay_ns;
961 struct pcm_device *pcm_device;
962
963 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
964 struct pcm_device, stream_list_node);
965
966 if (pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &tstamp) < 0) {
967 buffer->time_stamp.tv_sec = 0;
968 buffer->time_stamp.tv_nsec = 0;
969 buffer->delay_ns = 0;
970 ALOGW("read get_capture_delay(): pcm_htimestamp error");
971 return;
972 }
973
974 /* read frames available in audio HAL input buffer
975 * add number of frames being read as we want the capture time of first sample
976 * in current buffer */
977 /* frames in in->read_buf are at driver sampling rate while frames in in->proc_buf are
978 * at requested sampling rate */
979 buf_delay = (long)(((int64_t)(in->read_buf_frames) * 1000000000) / in->config.rate +
980 ((int64_t)(in->proc_buf_frames) * 1000000000) / in->requested_rate );
981
982 /* add delay introduced by resampler */
983 rsmp_delay = 0;
984 if (in->resampler) {
985 rsmp_delay = in->resampler->delay_ns(in->resampler);
986 }
987
988 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / in->config.rate);
989
990 delay_ns = kernel_delay + buf_delay + rsmp_delay;
991
992 buffer->time_stamp = tstamp;
993 buffer->delay_ns = delay_ns;
994 ALOGVV("get_capture_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames:[%5d],"
995 " delay_ns: [%d], kernel_delay:[%ld], buf_delay:[%ld], rsmp_delay:[%ld], "
996 "in->read_buf_frames:[%zd], in->proc_buf_frames:[%zd], frames:[%zd]",
997 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames,
998 buffer->delay_ns, kernel_delay, buf_delay, rsmp_delay,
999 in->read_buf_frames, in->proc_buf_frames, frames);
1000}
1001
1002static int32_t update_echo_reference(struct stream_in *in, size_t frames)
1003{
1004 ALOGVV("%s: enter:), in->config.channels(%d)", __func__,in->config.channels);
1005 struct echo_reference_buffer b;
1006 b.delay_ns = 0;
1007 struct pcm_device *pcm_device;
1008
1009 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1010 struct pcm_device, stream_list_node);
1011
1012 ALOGVV("update_echo_reference, in->config.channels(%d), frames = [%zd], in->ref_buf_frames = [%zd], "
1013 "b.frame_count = [%zd]",
1014 in->config.channels, frames, in->ref_buf_frames, frames - in->ref_buf_frames);
1015 if (in->ref_buf_frames < frames) {
1016 if (in->ref_buf_size < frames) {
1017 in->ref_buf_size = frames;
1018 in->ref_buf = (int16_t *)realloc(in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1019 ALOG_ASSERT((in->ref_buf != NULL),
1020 "update_echo_reference() failed to reallocate ref_buf");
1021 ALOGVV("update_echo_reference(): ref_buf %p extended to %d bytes",
1022 in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1023 }
1024 b.frame_count = frames - in->ref_buf_frames;
1025 b.raw = (void *)(in->ref_buf + in->ref_buf_frames * in->config.channels);
1026
1027 get_capture_delay(in, frames, &b);
1028
1029 if (in->echo_reference->read(in->echo_reference, &b) == 0)
1030 {
1031 in->ref_buf_frames += b.frame_count;
1032 ALOGVV("update_echo_reference(): in->ref_buf_frames:[%zd], "
1033 "in->ref_buf_size:[%zd], frames:[%zd], b.frame_count:[%zd]",
1034 in->ref_buf_frames, in->ref_buf_size, frames, b.frame_count);
1035 }
1036 } else
1037 ALOGW("update_echo_reference(): NOT enough frames to read ref buffer");
1038 return b.delay_ns;
1039}
1040
1041static int set_preprocessor_param(effect_handle_t handle,
1042 effect_param_t *param)
1043{
1044 uint32_t size = sizeof(int);
1045 uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
1046 param->vsize;
1047
1048 int status = (*handle)->command(handle,
1049 EFFECT_CMD_SET_PARAM,
1050 sizeof (effect_param_t) + psize,
1051 param,
1052 &size,
1053 &param->status);
1054 if (status == 0)
1055 status = param->status;
1056
1057 return status;
1058}
1059
1060static int set_preprocessor_echo_delay(effect_handle_t handle,
1061 int32_t delay_us)
1062{
1063 struct {
1064 effect_param_t param;
1065 uint32_t data_0;
1066 int32_t data_1;
1067 } buf;
1068 memset(&buf, 0, sizeof(buf));
1069
1070 buf.param.psize = sizeof(uint32_t);
1071 buf.param.vsize = sizeof(uint32_t);
1072 buf.data_0 = AEC_PARAM_ECHO_DELAY;
1073 buf.data_1 = delay_us;
1074
1075 return set_preprocessor_param(handle, &buf.param);
1076}
1077
1078static void push_echo_reference(struct stream_in *in, size_t frames)
1079{
1080 ALOGVV("%s: enter:)", __func__);
1081 /* read frames from echo reference buffer and update echo delay
1082 * in->ref_buf_frames is updated with frames available in in->ref_buf */
1083
1084 int32_t delay_us = update_echo_reference(in, frames)/1000;
1085 int32_t size_in_bytes = 0;
1086 int i;
1087 audio_buffer_t buf;
1088
1089 if (in->ref_buf_frames < frames)
1090 frames = in->ref_buf_frames;
1091
1092 buf.frameCount = frames;
1093 buf.raw = in->ref_buf;
1094
1095 for (i = 0; i < in->num_preprocessors; i++) {
1096 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1097 continue;
1098 ALOGVV("%s: effect_itfe)->process_reverse() BEGIN i=(%d) ", __func__, i);
1099 (*in->preprocessors[i].effect_itfe)->process_reverse(in->preprocessors[i].effect_itfe,
1100 &buf,
1101 NULL);
1102 ALOGVV("%s: effect_itfe)->process_reverse() END i=(%d) ", __func__, i);
1103 set_preprocessor_echo_delay(in->preprocessors[i].effect_itfe, delay_us);
1104 }
1105
1106 in->ref_buf_frames -= buf.frameCount;
1107 ALOGVV("%s: in->ref_buf_frames(%zd), in->config.channels(%d) ",
1108 __func__, in->ref_buf_frames, in->config.channels);
1109 if (in->ref_buf_frames) {
1110 memcpy(in->ref_buf,
1111 in->ref_buf + buf.frameCount * in->config.channels,
1112 in->ref_buf_frames * in->config.channels * sizeof(int16_t));
1113 }
1114}
1115
1116static void put_echo_reference(struct audio_device *adev,
1117 struct echo_reference_itfe *reference)
1118{
1119 ALOGV("%s: enter:)", __func__);
1120 int32_t prev_generation = adev->echo_reference_generation;
1121 struct stream_out *out = adev->primary_output;
1122
1123 if (adev->echo_reference != NULL &&
1124 reference == adev->echo_reference) {
1125 /* echo reference is taken from the low latency output stream used
1126 * for voice use cases */
1127 adev->echo_reference = NULL;
1128 android_atomic_inc(&adev->echo_reference_generation);
1129 if (out != NULL && out->usecase == USECASE_AUDIO_PLAYBACK) {
1130 // if the primary output is in standby or did not pick the echo reference yet
1131 // we can safely get rid of it here.
1132 // otherwise, out_write() or out_standby() will detect the change in echo reference
1133 // generation and release the echo reference owned by the stream.
1134 if ((out->echo_reference_generation != prev_generation) || out->standby)
1135 release_echo_reference(reference);
1136 } else {
1137 release_echo_reference(reference);
1138 }
1139 ALOGV("release_echo_reference");
1140 }
1141}
1142
1143static struct echo_reference_itfe *get_echo_reference(struct audio_device *adev,
1144 audio_format_t format __unused,
1145 uint32_t channel_count,
1146 uint32_t sampling_rate)
1147{
1148 ALOGV("%s: enter:)", __func__);
1149 put_echo_reference(adev, adev->echo_reference);
1150 /* echo reference is taken from the low latency output stream used
1151 * for voice use cases */
1152 if (adev->primary_output!= NULL && adev->primary_output->usecase == USECASE_AUDIO_PLAYBACK &&
1153 !adev->primary_output->standby) {
1154 struct audio_stream *stream =
1155 &adev->primary_output->stream.common;
1156 uint32_t wr_channel_count = audio_channel_count_from_out_mask(stream->get_channels(stream));
1157 uint32_t wr_sampling_rate = stream->get_sample_rate(stream);
1158 ALOGV("Calling create_echo_reference");
1159 int status = create_echo_reference(AUDIO_FORMAT_PCM_16_BIT,
1160 channel_count,
1161 sampling_rate,
1162 AUDIO_FORMAT_PCM_16_BIT,
1163 wr_channel_count,
1164 wr_sampling_rate,
1165 &adev->echo_reference);
1166 if (status == 0)
1167 android_atomic_inc(&adev->echo_reference_generation);
1168 }
1169 return adev->echo_reference;
1170}
1171
1172#ifdef HW_AEC_LOOPBACK
1173static int get_hw_echo_reference(struct stream_in *in)
1174{
1175 struct pcm_device_profile *ref_pcm_profile;
1176 struct pcm_device *ref_device;
1177 struct audio_device *adev = in->dev;
1178
1179 in->hw_echo_reference = false;
1180
1181 if (adev->primary_output!= NULL &&
1182 !adev->primary_output->standby &&
1183 adev->primary_output->usecase == USECASE_AUDIO_PLAYBACK &&
1184 adev->primary_output->devices == AUDIO_DEVICE_OUT_SPEAKER) {
1185 struct audio_stream *stream = &adev->primary_output->stream.common;
1186
1187 // TODO: currently there is no low latency mode for aec reference.
1188 ref_pcm_profile = get_pcm_device(PCM_CAPTURE, pcm_device_capture_loopback_aec.devices);
1189 if (ref_pcm_profile == NULL) {
1190 ALOGE("%s: Could not find PCM device id for the usecase(%d)",
1191 __func__, pcm_device_capture_loopback_aec.devices);
1192 return -EINVAL;
1193 }
1194
1195 ref_device = (struct pcm_device *)calloc(1, sizeof(struct pcm_device));
1196 ref_device->pcm_profile = ref_pcm_profile;
1197
1198 ALOGV("%s: ref_device rate:%d, ch:%d", __func__, ref_pcm_profile->config.rate, ref_pcm_profile->config.channels);
1199 ref_device->pcm = pcm_open(ref_device->pcm_profile->card, ref_device->pcm_profile->id, PCM_IN | PCM_MONOTONIC, &ref_device->pcm_profile->config);
1200
1201 if (ref_device->pcm && !pcm_is_ready(ref_device->pcm)) {
1202 ALOGE("%s: %s", __func__, pcm_get_error(ref_device->pcm));
1203 pcm_close(ref_device->pcm);
1204 ref_device->pcm = NULL;
1205 return -EIO;
1206 }
1207 list_add_tail(&in->pcm_dev_list, &ref_device->stream_list_node);
1208
1209 in->hw_echo_reference = true;
1210
1211 ALOGV("%s: hw_echo_reference is true", __func__);
1212 }
1213
1214 return 0;
1215}
1216#endif
1217
1218static int get_playback_delay(struct stream_out *out,
1219 size_t frames,
1220 struct echo_reference_buffer *buffer)
1221{
1222 unsigned int kernel_frames;
1223 int status;
1224 int primary_pcm = 0;
1225 struct pcm_device *pcm_device;
1226
1227 pcm_device = node_to_item(list_head(&out->pcm_dev_list),
1228 struct pcm_device, stream_list_node);
1229
1230 status = pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &buffer->time_stamp);
1231 if (status < 0) {
1232 buffer->time_stamp.tv_sec = 0;
1233 buffer->time_stamp.tv_nsec = 0;
1234 buffer->delay_ns = 0;
1235 ALOGV("get_playback_delay(): pcm_get_htimestamp error,"
1236 "setting playbackTimestamp to 0");
1237 return status;
1238 }
1239
1240 kernel_frames = pcm_get_buffer_size(pcm_device->pcm) - kernel_frames;
1241
1242 /* adjust render time stamp with delay added by current driver buffer.
1243 * Add the duration of current frame as we want the render time of the last
1244 * sample being written. */
1245 buffer->delay_ns = (long)(((int64_t)(kernel_frames + frames)* 1000000000)/
1246 out->config.rate);
1247 ALOGVV("get_playback_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5u], delay_ns: [%d],",
1248 buffer->time_stamp.tv_sec, buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns);
1249
1250 return 0;
1251}
1252
1253#define GET_COMMAND_STATUS(status, fct_status, cmd_status) \
1254 do { \
1255 if (fct_status != 0) \
1256 status = fct_status; \
1257 else if (cmd_status != 0) \
1258 status = cmd_status; \
1259 } while(0)
1260
1261static int in_configure_reverse(struct stream_in *in)
1262{
1263 int32_t cmd_status;
1264 uint32_t size = sizeof(int);
1265 effect_config_t config;
1266 int32_t status = 0;
1267 int32_t fct_status = 0;
1268 int i;
1269 ALOGV("%s: enter: in->num_preprocessors(%d)", __func__, in->num_preprocessors);
1270 if (in->num_preprocessors > 0) {
1271 config.inputCfg.channels = in->main_channels;
1272 config.outputCfg.channels = in->main_channels;
1273 config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1274 config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1275 config.inputCfg.samplingRate = in->requested_rate;
1276 config.outputCfg.samplingRate = in->requested_rate;
1277 config.inputCfg.mask =
1278 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1279 config.outputCfg.mask =
1280 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1281
1282 for (i = 0; i < in->num_preprocessors; i++)
1283 {
1284 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1285 continue;
1286 fct_status = (*(in->preprocessors[i].effect_itfe))->command(
1287 in->preprocessors[i].effect_itfe,
1288 EFFECT_CMD_SET_CONFIG_REVERSE,
1289 sizeof(effect_config_t),
1290 &config,
1291 &size,
1292 &cmd_status);
1293 ALOGV("%s: calling EFFECT_CMD_SET_CONFIG_REVERSE",__func__);
1294 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1295 }
1296 }
1297 return status;
1298}
1299
1300#define MAX_NUM_CHANNEL_CONFIGS 10
1301
1302static void in_read_audio_effect_channel_configs(struct stream_in *in __unused,
1303 struct effect_info_s *effect_info)
1304{
1305 /* size and format of the cmd are defined in hardware/audio_effect.h */
1306 effect_handle_t effect = effect_info->effect_itfe;
1307 uint32_t cmd_size = 2 * sizeof(uint32_t);
1308 uint32_t cmd[] = { EFFECT_FEATURE_AUX_CHANNELS, MAX_NUM_CHANNEL_CONFIGS };
1309 /* reply = status + number of configs (n) + n x channel_config_t */
1310 uint32_t reply_size =
1311 2 * sizeof(uint32_t) + (MAX_NUM_CHANNEL_CONFIGS * sizeof(channel_config_t));
1312 int32_t reply[reply_size];
1313 int32_t cmd_status;
1314
1315 ALOG_ASSERT((effect_info->num_channel_configs == 0),
1316 "in_read_audio_effect_channel_configs() num_channel_configs not cleared");
1317 ALOG_ASSERT((effect_info->channel_configs == NULL),
1318 "in_read_audio_effect_channel_configs() channel_configs not cleared");
1319
1320 /* if this command is not supported, then the effect is supposed to return -EINVAL.
1321 * This error will be interpreted as if the effect supports the main_channels but does not
1322 * support any aux_channels */
1323 cmd_status = (*effect)->command(effect,
1324 EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS,
1325 cmd_size,
1326 (void*)&cmd,
1327 &reply_size,
1328 (void*)&reply);
1329
1330 if (cmd_status != 0) {
1331 ALOGV("in_read_audio_effect_channel_configs(): "
1332 "fx->command returned %d", cmd_status);
1333 return;
1334 }
1335
1336 if (reply[0] != 0) {
1337 ALOGW("in_read_audio_effect_channel_configs(): "
1338 "command EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS error %d num configs %d",
1339 reply[0], (reply[0] == -ENOMEM) ? reply[1] : MAX_NUM_CHANNEL_CONFIGS);
1340 return;
1341 }
1342
1343 /* the feature is not supported */
1344 ALOGV("in_read_audio_effect_channel_configs()(): "
1345 "Feature supported and adding %d channel configs to the list", reply[1]);
1346 effect_info->num_channel_configs = reply[1];
1347 effect_info->channel_configs =
1348 (channel_config_t *) malloc(sizeof(channel_config_t) * reply[1]); /* n x configs */
1349 memcpy(effect_info->channel_configs, (reply + 2), sizeof(channel_config_t) * reply[1]);
1350}
1351
1352
1353#define NUM_IN_AUX_CNL_CONFIGS 2
1354static const channel_config_t in_aux_cnl_configs[NUM_IN_AUX_CNL_CONFIGS] = {
1355 { AUDIO_CHANNEL_IN_FRONT , AUDIO_CHANNEL_IN_BACK},
1356 { AUDIO_CHANNEL_IN_STEREO , AUDIO_CHANNEL_IN_RIGHT}
1357};
1358static uint32_t in_get_aux_channels(struct stream_in *in)
1359{
1360 int i;
1361 channel_config_t new_chcfg = {0, 0};
1362
1363 if (in->num_preprocessors == 0)
1364 return 0;
1365
1366 /* do not enable dual mic configurations when capturing from other microphones than
1367 * main or sub */
1368 if (!(in->devices & (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_BACK_MIC)))
1369 return 0;
1370
1371 /* retain most complex aux channels configuration compatible with requested main channels and
1372 * supported by audio driver and all pre processors */
1373 for (i = 0; i < NUM_IN_AUX_CNL_CONFIGS; i++) {
1374 const channel_config_t *cur_chcfg = &in_aux_cnl_configs[i];
1375 if (cur_chcfg->main_channels == in->main_channels) {
1376 size_t match_cnt;
1377 size_t idx_preproc;
1378 for (idx_preproc = 0, match_cnt = 0;
1379 /* no need to continue if at least one preprocessor doesn't match */
1380 idx_preproc < (size_t)in->num_preprocessors && match_cnt == idx_preproc;
1381 idx_preproc++) {
1382 struct effect_info_s *effect_info = &in->preprocessors[idx_preproc];
1383 size_t idx_chcfg;
1384
1385 for (idx_chcfg = 0; idx_chcfg < effect_info->num_channel_configs; idx_chcfg++) {
1386 if (memcmp(effect_info->channel_configs + idx_chcfg,
1387 cur_chcfg,
1388 sizeof(channel_config_t)) == 0) {
1389 match_cnt++;
1390 break;
1391 }
1392 }
1393 }
1394 /* if all preprocessors match, we have a candidate */
1395 if (match_cnt == (size_t)in->num_preprocessors) {
1396 /* retain most complex aux channels configuration */
1397 if (audio_channel_count_from_in_mask(cur_chcfg->aux_channels) > audio_channel_count_from_in_mask(new_chcfg.aux_channels)) {
1398 new_chcfg = *cur_chcfg;
1399 }
1400 }
1401 }
1402 }
1403
1404 ALOGV("in_get_aux_channels(): return %04x", new_chcfg.aux_channels);
1405
1406 return new_chcfg.aux_channels;
1407}
1408
1409static int in_configure_effect_channels(effect_handle_t effect,
1410 channel_config_t *channel_config)
1411{
1412 int status = 0;
1413 int fct_status;
1414 int32_t cmd_status;
1415 uint32_t reply_size;
1416 effect_config_t config;
1417 uint32_t cmd[(sizeof(uint32_t) + sizeof(channel_config_t) - 1) / sizeof(uint32_t) + 1];
1418
1419 ALOGV("in_configure_effect_channels(): configure effect with channels: [%04x][%04x]",
1420 channel_config->main_channels,
1421 channel_config->aux_channels);
1422
1423 config.inputCfg.mask = EFFECT_CONFIG_CHANNELS;
1424 config.outputCfg.mask = EFFECT_CONFIG_CHANNELS;
1425 reply_size = sizeof(effect_config_t);
1426 fct_status = (*effect)->command(effect,
1427 EFFECT_CMD_GET_CONFIG,
1428 0,
1429 NULL,
1430 &reply_size,
1431 &config);
1432 if (fct_status != 0) {
1433 ALOGE("in_configure_effect_channels(): EFFECT_CMD_GET_CONFIG failed");
1434 return fct_status;
1435 }
1436
1437 config.inputCfg.channels = channel_config->main_channels | channel_config->aux_channels;
1438 config.outputCfg.channels = config.inputCfg.channels;
1439 reply_size = sizeof(uint32_t);
1440 fct_status = (*effect)->command(effect,
1441 EFFECT_CMD_SET_CONFIG,
1442 sizeof(effect_config_t),
1443 &config,
1444 &reply_size,
1445 &cmd_status);
1446 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1447
1448 cmd[0] = EFFECT_FEATURE_AUX_CHANNELS;
1449 memcpy(cmd + 1, channel_config, sizeof(channel_config_t));
1450 reply_size = sizeof(uint32_t);
1451 fct_status = (*effect)->command(effect,
1452 EFFECT_CMD_SET_FEATURE_CONFIG,
1453 sizeof(cmd), //sizeof(uint32_t) + sizeof(channel_config_t),
1454 cmd,
1455 &reply_size,
1456 &cmd_status);
1457 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1458
1459 /* some implementations need to be re-enabled after a config change */
1460 reply_size = sizeof(uint32_t);
1461 fct_status = (*effect)->command(effect,
1462 EFFECT_CMD_ENABLE,
1463 0,
1464 NULL,
1465 &reply_size,
1466 &cmd_status);
1467 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1468
1469 return status;
1470}
1471
1472static int in_reconfigure_channels(struct stream_in *in,
1473 effect_handle_t effect,
1474 channel_config_t *channel_config,
1475 bool config_changed) {
1476
1477 int status = 0;
1478
1479 ALOGV("in_reconfigure_channels(): config_changed %d effect %p",
1480 config_changed, effect);
1481
1482 /* if config changed, reconfigure all previously added effects */
1483 if (config_changed) {
1484 int i;
1485 ALOGV("%s: config_changed (%d)", __func__, config_changed);
1486 for (i = 0; i < in->num_preprocessors; i++)
1487 {
1488 int cur_status = in_configure_effect_channels(in->preprocessors[i].effect_itfe,
1489 channel_config);
1490 ALOGV("%s: in_configure_effect_channels i=(%d), [main_channel,aux_channel]=[%d|%d], status=%d",
1491 __func__, i, channel_config->main_channels, channel_config->aux_channels, cur_status);
1492 if (cur_status != 0) {
1493 ALOGV("in_reconfigure_channels(): error %d configuring effect "
1494 "%d with channels: [%04x][%04x]",
1495 cur_status,
1496 i,
1497 channel_config->main_channels,
1498 channel_config->aux_channels);
1499 status = cur_status;
1500 }
1501 }
1502 } else if (effect != NULL && channel_config->aux_channels) {
1503 /* if aux channels config did not change but aux channels are present,
1504 * we still need to configure the effect being added */
1505 status = in_configure_effect_channels(effect, channel_config);
1506 }
1507 return status;
1508}
1509
1510static void in_update_aux_channels(struct stream_in *in,
1511 effect_handle_t effect)
1512{
1513 uint32_t aux_channels;
1514 channel_config_t channel_config;
1515 int status;
1516
1517 aux_channels = in_get_aux_channels(in);
1518
1519 channel_config.main_channels = in->main_channels;
1520 channel_config.aux_channels = aux_channels;
1521 status = in_reconfigure_channels(in,
1522 effect,
1523 &channel_config,
1524 (aux_channels != in->aux_channels));
1525
1526 if (status != 0) {
1527 ALOGV("in_update_aux_channels(): in_reconfigure_channels error %d", status);
1528 /* resetting aux channels configuration */
1529 aux_channels = 0;
1530 channel_config.aux_channels = 0;
1531 in_reconfigure_channels(in, effect, &channel_config, true);
1532 }
1533 ALOGV("%s: aux_channels=%d, in->aux_channels_changed=%d", __func__, aux_channels, in->aux_channels_changed);
1534 if (in->aux_channels != aux_channels) {
1535 in->aux_channels_changed = true;
1536 in->aux_channels = aux_channels;
1537 do_in_standby_l(in);
1538 }
1539}
1540#endif
1541
1542/* This function reads PCM data and:
1543 * - resample if needed
1544 * - process if pre-processors are attached
1545 * - discard unwanted channels
1546 */
1547static ssize_t read_and_process_frames(struct stream_in *in, void* buffer, ssize_t frames)
1548{
1549 ssize_t frames_wr = 0;
1550 audio_buffer_t in_buf;
1551 audio_buffer_t out_buf;
1552 size_t src_channels = in->config.channels;
1553 size_t dst_channels = audio_channel_count_from_in_mask(in->main_channels);
1554 int i;
1555 void *proc_buf_out;
1556 struct pcm_device *pcm_device;
1557 bool has_additional_channels = (dst_channels != src_channels) ? true : false;
1558#ifdef PREPROCESSING_ENABLED
1559 bool has_processing = (in->num_preprocessors != 0) ? true : false;
1560#endif
1561
1562 /* Additional channels might be added on top of main_channels:
1563 * - aux_channels (by processing effects)
1564 * - extra channels due to HW limitations
1565 * In case of additional channels, we cannot work inplace
1566 */
1567 if (has_additional_channels)
1568 proc_buf_out = in->proc_buf_out;
1569 else
1570 proc_buf_out = buffer;
1571
1572 if (list_empty(&in->pcm_dev_list)) {
1573 ALOGE("%s: pcm device list empty", __func__);
1574 return -EINVAL;
1575 }
1576
1577 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1578 struct pcm_device, stream_list_node);
1579
1580#ifdef PREPROCESSING_ENABLED
1581 if (has_processing) {
1582 /* since all the processing below is done in frames and using the config.channels
1583 * as the number of channels, no changes is required in case aux_channels are present */
1584 while (frames_wr < frames) {
1585 /* first reload enough frames at the end of process input buffer */
1586 if (in->proc_buf_frames < (size_t)frames) {
1587 ssize_t frames_rd;
1588 if (in->proc_buf_size < (size_t)frames) {
1589 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1590 in->proc_buf_size = (size_t)frames;
1591 in->proc_buf_in = (int16_t *)realloc(in->proc_buf_in, size_in_bytes);
1592 ALOG_ASSERT((in->proc_buf_in != NULL),
1593 "process_frames() failed to reallocate proc_buf_in");
1594 if (has_additional_channels) {
1595 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1596 ALOG_ASSERT((in->proc_buf_out != NULL),
1597 "process_frames() failed to reallocate proc_buf_out");
1598 proc_buf_out = in->proc_buf_out;
1599 }
1600 }
1601 frames_rd = read_frames(in,
1602 in->proc_buf_in +
1603 in->proc_buf_frames * in->config.channels,
1604 frames - in->proc_buf_frames);
1605 if (frames_rd < 0) {
1606 /* Return error code */
1607 frames_wr = frames_rd;
1608 break;
1609 }
1610 in->proc_buf_frames += frames_rd;
1611 }
1612
1613 if (in->echo_reference != NULL) {
1614 push_echo_reference(in, in->proc_buf_frames);
1615 }
1616
1617 /* in_buf.frameCount and out_buf.frameCount indicate respectively
1618 * the maximum number of frames to be consumed and produced by process() */
1619 in_buf.frameCount = in->proc_buf_frames;
1620 in_buf.s16 = in->proc_buf_in;
1621 out_buf.frameCount = frames - frames_wr;
1622 out_buf.s16 = (int16_t *)proc_buf_out + frames_wr * in->config.channels;
1623
1624 /* FIXME: this works because of current pre processing library implementation that
1625 * does the actual process only when the last enabled effect process is called.
1626 * The generic solution is to have an output buffer for each effect and pass it as
1627 * input to the next.
1628 */
1629 for (i = 0; i < in->num_preprocessors; i++) {
1630 (*in->preprocessors[i].effect_itfe)->process(in->preprocessors[i].effect_itfe,
1631 &in_buf,
1632 &out_buf);
1633 }
1634
1635 /* process() has updated the number of frames consumed and produced in
1636 * in_buf.frameCount and out_buf.frameCount respectively
1637 * move remaining frames to the beginning of in->proc_buf_in */
1638 in->proc_buf_frames -= in_buf.frameCount;
1639
1640 if (in->proc_buf_frames) {
1641 memcpy(in->proc_buf_in,
1642 in->proc_buf_in + in_buf.frameCount * in->config.channels,
1643 in->proc_buf_frames * in->config.channels * sizeof(int16_t));
1644 }
1645
1646 /* if not enough frames were passed to process(), read more and retry. */
1647 if (out_buf.frameCount == 0) {
1648 ALOGW("No frames produced by preproc");
1649 continue;
1650 }
1651
1652 if ((frames_wr + (ssize_t)out_buf.frameCount) <= frames) {
1653 frames_wr += out_buf.frameCount;
1654 } else {
1655 /* The effect does not comply to the API. In theory, we should never end up here! */
1656 ALOGE("preprocessing produced too many frames: %d + %zd > %d !",
1657 (unsigned int)frames_wr, out_buf.frameCount, (unsigned int)frames);
1658 frames_wr = frames;
1659 }
1660 }
1661 }
1662 else
1663#endif //PREPROCESSING_ENABLED
1664 {
1665 /* No processing effects attached */
1666 if (has_additional_channels) {
1667 /* With additional channels, we cannot use original buffer */
1668 if (in->proc_buf_size < (size_t)frames) {
1669 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1670 in->proc_buf_size = (size_t)frames;
1671 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1672 ALOG_ASSERT((in->proc_buf_out != NULL),
1673 "process_frames() failed to reallocate proc_buf_out");
1674 proc_buf_out = in->proc_buf_out;
1675 }
1676 }
1677 frames_wr = read_frames(in, proc_buf_out, frames);
1678 }
1679
1680 /* Remove all additional channels that have been added on top of main_channels:
1681 * - aux_channels
1682 * - extra channels from HW due to HW limitations
1683 * Assumption is made that the channels are interleaved and that the main
1684 * channels are first. */
1685
1686 if (has_additional_channels)
1687 {
1688 int16_t* src_buffer = (int16_t *)proc_buf_out;
1689 int16_t* dst_buffer = (int16_t *)buffer;
1690
1691 if (dst_channels == 1) {
1692 for (i = frames_wr; i > 0; i--)
1693 {
1694 *dst_buffer++ = *src_buffer;
1695 src_buffer += src_channels;
1696 }
1697 } else {
1698 for (i = frames_wr; i > 0; i--)
1699 {
1700 memcpy(dst_buffer, src_buffer, dst_channels*sizeof(int16_t));
1701 dst_buffer += dst_channels;
1702 src_buffer += src_channels;
1703 }
1704 }
1705 }
1706
1707 return frames_wr;
1708}
1709
1710static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
1711 struct resampler_buffer* buffer)
1712{
1713 struct stream_in *in;
1714 struct pcm_device *pcm_device;
1715
1716 if (buffer_provider == NULL || buffer == NULL)
1717 return -EINVAL;
1718
1719 in = (struct stream_in *)((char *)buffer_provider -
1720 offsetof(struct stream_in, buf_provider));
1721
1722 if (list_empty(&in->pcm_dev_list)) {
1723 buffer->raw = NULL;
1724 buffer->frame_count = 0;
1725 in->read_status = -ENODEV;
1726 return -ENODEV;
1727 }
1728
1729 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1730 struct pcm_device, stream_list_node);
1731
1732 if (in->read_buf_frames == 0) {
1733 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, in->config.period_size);
1734 if (in->read_buf_size < in->config.period_size) {
1735 in->read_buf_size = in->config.period_size;
1736 in->read_buf = (int16_t *) realloc(in->read_buf, size_in_bytes);
1737 ALOG_ASSERT((in->read_buf != NULL),
1738 "get_next_buffer() failed to reallocate read_buf");
1739 }
1740
1741 in->read_status = pcm_read(pcm_device->pcm, (void*)in->read_buf, size_in_bytes);
1742
1743 if (in->read_status != 0) {
1744 ALOGE("get_next_buffer() pcm_read error %d", in->read_status);
1745 buffer->raw = NULL;
1746 buffer->frame_count = 0;
1747 return in->read_status;
1748 }
1749 in->read_buf_frames = in->config.period_size;
1750
1751#ifdef PREPROCESSING_ENABLED
1752#ifdef HW_AEC_LOOPBACK
1753 if (in->hw_echo_reference) {
1754 struct pcm_device *temp_device = NULL;
1755 struct pcm_device *ref_device = NULL;
1756 struct listnode *node = NULL;
1757 struct echo_reference_buffer b;
1758 size_t size_hw_ref_bytes;
1759 size_t size_hw_ref_frames;
1760 int read_status = 0;
1761
1762 ref_device = node_to_item(list_tail(&in->pcm_dev_list),
1763 struct pcm_device, stream_list_node);
1764 list_for_each(node, &in->pcm_dev_list) {
1765 temp_device = node_to_item(node, struct pcm_device, stream_list_node);
1766 if (temp_device->pcm_profile->id == 1) {
1767 ref_device = temp_device;
1768 break;
1769 }
1770 }
1771 if (ref_device) {
1772 size_hw_ref_bytes = pcm_frames_to_bytes(ref_device->pcm, ref_device->pcm_profile->config.period_size);
1773 size_hw_ref_frames = ref_device->pcm_profile->config.period_size;
1774 if (in->hw_ref_buf_size < size_hw_ref_frames) {
1775 in->hw_ref_buf_size = size_hw_ref_frames;
1776 in->hw_ref_buf = (int16_t *) realloc(in->hw_ref_buf, size_hw_ref_bytes);
1777 ALOG_ASSERT((in->hw_ref_buf != NULL),
1778 "get_next_buffer() failed to reallocate hw_ref_buf");
1779 ALOGV("get_next_buffer(): hw_ref_buf %p extended to %zd bytes",
1780 in->hw_ref_buf, size_hw_ref_bytes);
1781 }
1782
1783 read_status = pcm_read(ref_device->pcm, (void*)in->hw_ref_buf, size_hw_ref_bytes);
1784 if (read_status != 0) {
1785 ALOGE("process_frames() pcm_read error for HW reference %d", read_status);
1786 b.raw = NULL;
1787 b.frame_count = 0;
1788 }
1789 else {
1790 get_capture_reference_delay(in, size_hw_ref_frames, &b);
1791 b.raw = (void *)in->hw_ref_buf;
1792 b.frame_count = size_hw_ref_frames;
1793 if (b.delay_ns != 0)
1794 b.delay_ns = -b.delay_ns; // as this is capture delay, it needs to be subtracted from the microphone delay
1795 in->echo_reference->write(in->echo_reference, &b);
1796 }
1797 }
1798 }
1799#endif // HW_AEC_LOOPBACK
1800#endif // PREPROCESSING_ENABLED
1801 }
1802
1803 buffer->frame_count = (buffer->frame_count > in->read_buf_frames) ?
1804 in->read_buf_frames : buffer->frame_count;
1805 buffer->i16 = in->read_buf + (in->config.period_size - in->read_buf_frames) *
1806 in->config.channels;
1807 return in->read_status;
1808}
1809
1810static void release_buffer(struct resampler_buffer_provider *buffer_provider,
1811 struct resampler_buffer* buffer)
1812{
1813 struct stream_in *in;
1814
1815 if (buffer_provider == NULL || buffer == NULL)
1816 return;
1817
1818 in = (struct stream_in *)((char *)buffer_provider -
1819 offsetof(struct stream_in, buf_provider));
1820
1821 in->read_buf_frames -= buffer->frame_count;
1822}
1823
1824/* read_frames() reads frames from kernel driver, down samples to capture rate
1825 * if necessary and output the number of frames requested to the buffer specified */
1826static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames)
1827{
1828 ssize_t frames_wr = 0;
1829
1830 struct pcm_device *pcm_device;
1831
1832 if (list_empty(&in->pcm_dev_list)) {
1833 ALOGE("%s: pcm device list empty", __func__);
1834 return -EINVAL;
1835 }
1836
1837 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1838 struct pcm_device, stream_list_node);
1839
1840 while (frames_wr < frames) {
1841 size_t frames_rd = frames - frames_wr;
1842 ALOGVV("%s: frames_rd: %zd, frames_wr: %zd, in->config.channels: %d",
1843 __func__,frames_rd,frames_wr,in->config.channels);
1844 if (in->resampler != NULL) {
1845 in->resampler->resample_from_provider(in->resampler,
1846 (int16_t *)((char *)buffer +
1847 pcm_frames_to_bytes(pcm_device->pcm, frames_wr)),
1848 &frames_rd);
1849 } else {
1850 struct resampler_buffer buf = {
1851 { raw : NULL, },
1852 frame_count : frames_rd,
1853 };
1854 get_next_buffer(&in->buf_provider, &buf);
1855 if (buf.raw != NULL) {
1856 memcpy((char *)buffer +
1857 pcm_frames_to_bytes(pcm_device->pcm, frames_wr),
1858 buf.raw,
1859 pcm_frames_to_bytes(pcm_device->pcm, buf.frame_count));
1860 frames_rd = buf.frame_count;
1861 }
1862 release_buffer(&in->buf_provider, &buf);
1863 }
1864 /* in->read_status is updated by getNextBuffer() also called by
1865 * in->resampler->resample_from_provider() */
1866 if (in->read_status != 0)
1867 return in->read_status;
1868
1869 frames_wr += frames_rd;
1870 }
1871 return frames_wr;
1872}
1873
1874static int in_release_pcm_devices(struct stream_in *in)
1875{
1876 struct pcm_device *pcm_device;
1877 struct listnode *node;
1878 struct listnode *next;
1879
1880 list_for_each_safe(node, next, &in->pcm_dev_list) {
1881 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
1882 list_remove(node);
1883 free(pcm_device);
1884 }
1885
1886 return 0;
1887}
1888
1889static int stop_input_stream(struct stream_in *in)
1890{
1891 struct audio_usecase *uc_info;
1892 struct audio_device *adev = in->dev;
1893
1894 adev->active_input = NULL;
1895 ALOGV("%s: enter: usecase(%d: %s)", __func__,
1896 in->usecase, use_case_table[in->usecase]);
1897 uc_info = get_usecase_from_id(adev, in->usecase);
1898 if (uc_info == NULL) {
1899 ALOGE("%s: Could not find the usecase (%d) in the list",
1900 __func__, in->usecase);
1901 return -EINVAL;
1902 }
1903
1904 /* Disable the tx device */
1905 disable_snd_device(adev, uc_info, uc_info->in_snd_device, true);
1906
1907 list_remove(&uc_info->adev_list_node);
1908 free(uc_info);
1909
1910 if (list_empty(&in->pcm_dev_list)) {
1911 ALOGE("%s: pcm device list empty", __func__);
1912 return -EINVAL;
1913 }
1914
1915 in_release_pcm_devices(in);
1916 list_init(&in->pcm_dev_list);
1917
1918#ifdef HW_AEC_LOOPBACK
1919 if (in->hw_echo_reference)
1920 {
1921 in->hw_echo_reference = false;
1922 }
1923#endif
1924
1925 ALOGV("%s: exit", __func__);
1926 return 0;
1927}
1928
1929static int start_input_stream(struct stream_in *in)
1930{
1931 /* Enable output device and stream routing controls */
1932 int ret = 0;
1933 bool recreate_resampler = false;
1934 struct audio_usecase *uc_info;
1935 struct audio_device *adev = in->dev;
1936 struct pcm_device_profile *pcm_profile;
1937 struct pcm_device *pcm_device;
1938
1939 ALOGV("%s: enter: usecase(%d)", __func__, in->usecase);
1940 adev->active_input = in;
1941 pcm_profile = get_pcm_device(in->usecase_type, in->devices);
1942 if (pcm_profile == NULL) {
1943 ALOGE("%s: Could not find PCM device id for the usecase(%d)",
1944 __func__, in->usecase);
1945 ret = -EINVAL;
1946 goto error_config;
1947 }
1948
1949 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
1950 uc_info->id = in->usecase;
1951 uc_info->type = PCM_CAPTURE;
1952 uc_info->stream = (struct audio_stream *)in;
1953 uc_info->devices = in->devices;
1954 uc_info->in_snd_device = SND_DEVICE_NONE;
1955 uc_info->out_snd_device = SND_DEVICE_NONE;
1956
1957 pcm_device = (struct pcm_device *)calloc(1, sizeof(struct pcm_device));
1958 pcm_device->pcm_profile = pcm_profile;
1959 list_init(&in->pcm_dev_list);
1960 list_add_tail(&in->pcm_dev_list, &pcm_device->stream_list_node);
1961
1962 list_init(&uc_info->mixer_list);
1963 list_add_tail(&uc_info->mixer_list,
1964 &adev_get_mixer_for_card(adev,
1965 pcm_device->pcm_profile->card)->uc_list_node[uc_info->id]);
1966
1967 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
1968
1969 select_devices(adev, in->usecase);
1970
1971 /* Config should be updated as profile can be changed between different calls
1972 * to this function:
1973 * - Trigger resampler creation
1974 * - Config needs to be updated */
1975 if (in->config.rate != pcm_profile->config.rate) {
1976 recreate_resampler = true;
1977 }
1978 in->config = pcm_profile->config;
1979
1980#ifdef PREPROCESSING_ENABLED
1981 if (in->aux_channels_changed) {
1982 in->config.channels = audio_channel_count_from_in_mask(in->main_channels | in->aux_channels);
1983 recreate_resampler = true;
1984 }
1985#endif
1986
1987 if (in->requested_rate != in->config.rate) {
1988 recreate_resampler = true;
1989 }
1990
1991 if (recreate_resampler) {
1992 if (in->resampler) {
1993 release_resampler(in->resampler);
1994 in->resampler = NULL;
1995 }
1996 in->buf_provider.get_next_buffer = get_next_buffer;
1997 in->buf_provider.release_buffer = release_buffer;
1998 ret = create_resampler(in->config.rate,
1999 in->requested_rate,
2000 in->config.channels,
2001 RESAMPLER_QUALITY_DEFAULT,
2002 &in->buf_provider,
2003 &in->resampler);
2004 }
2005
2006#ifdef PREPROCESSING_ENABLED
2007 if (in->enable_aec && in->echo_reference == NULL) {
2008 in->echo_reference = get_echo_reference(adev,
2009 AUDIO_FORMAT_PCM_16_BIT,
2010 audio_channel_count_from_in_mask(in->main_channels),
2011 in->requested_rate
2012 );
2013 }
2014
2015#ifdef HW_AEC_LOOPBACK
2016 if (in->enable_aec) {
2017 ret = get_hw_echo_reference(in);
2018 if (ret!=0)
2019 goto error_open;
2020
2021 /* force ref buffer reallocation */
2022 in->hw_ref_buf_size = 0;
2023 }
2024#endif
2025#endif
2026
2027 /* Open the PCM device.
2028 * The HW is limited to support only the default pcm_profile settings.
2029 * As such a change in aux_channels will not have an effect.
2030 */
2031 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d, smp rate %d format %d, \
2032 period_size %d", __func__, pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
2033 pcm_device->pcm_profile->config.channels,pcm_device->pcm_profile->config.rate,
2034 pcm_device->pcm_profile->config.format, pcm_device->pcm_profile->config.period_size);
2035
2036 if (pcm_profile->type == PCM_HOTWORD_STREAMING) {
2037 if (!adev->sound_trigger_open_for_streaming) {
2038 ALOGE("%s: No handle to sound trigger HAL", __func__);
2039 ret = -EIO;
2040 goto error_open;
2041 }
2042 pcm_device->pcm = NULL;
2043 pcm_device->sound_trigger_handle = adev->sound_trigger_open_for_streaming();
2044 if (pcm_device->sound_trigger_handle <= 0) {
2045 ALOGE("%s: Failed to open DSP for streaming", __func__);
2046 ret = -EIO;
2047 goto error_open;
2048 }
2049 ALOGV("Opened DSP successfully");
2050 } else {
2051 pcm_device->sound_trigger_handle = 0;
2052 pcm_device->pcm = pcm_open(pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
2053 PCM_IN | PCM_MONOTONIC, &pcm_device->pcm_profile->config);
2054
2055 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2056 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2057 pcm_close(pcm_device->pcm);
2058 pcm_device->pcm = NULL;
2059 ret = -EIO;
2060 goto error_open;
2061 }
2062 }
2063
2064 /* force read and proc buffer reallocation in case of frame size or
2065 * channel count change */
2066 in->proc_buf_frames = 0;
2067 in->proc_buf_size = 0;
2068 in->read_buf_size = 0;
2069 in->read_buf_frames = 0;
2070
2071 /* if no supported sample rate is available, use the resampler */
2072 if (in->resampler) {
2073 in->resampler->reset(in->resampler);
2074 }
2075
2076 ALOGV("%s: exit", __func__);
2077 return ret;
2078
2079error_open:
2080 if (in->resampler) {
2081 release_resampler(in->resampler);
2082 in->resampler = NULL;
2083 }
2084 stop_input_stream(in);
2085
2086error_config:
2087 ALOGV("%s: exit: status(%d)", __func__, ret);
2088 adev->active_input = NULL;
2089 return ret;
2090}
2091
2092void lock_input_stream(struct stream_in *in)
2093{
2094 pthread_mutex_lock(&in->pre_lock);
2095 pthread_mutex_lock(&in->lock);
2096 pthread_mutex_unlock(&in->pre_lock);
2097}
2098
2099void lock_output_stream(struct stream_out *out)
2100{
2101 pthread_mutex_lock(&out->pre_lock);
2102 pthread_mutex_lock(&out->lock);
2103 pthread_mutex_unlock(&out->pre_lock);
2104}
2105
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002106static int uc_release_pcm_devices(struct audio_usecase *usecase)
2107{
2108 struct stream_out *out = (struct stream_out *)usecase->stream;
2109 struct pcm_device *pcm_device;
2110 struct listnode *node;
2111 struct listnode *next;
2112
2113 list_for_each_safe(node, next, &out->pcm_dev_list) {
2114 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2115 list_remove(node);
2116 free(pcm_device);
2117 }
2118 list_init(&usecase->mixer_list);
2119
2120 return 0;
2121}
2122
2123static int uc_select_pcm_devices(struct audio_usecase *usecase)
2124
2125{
2126 struct stream_out *out = (struct stream_out *)usecase->stream;
2127 struct pcm_device *pcm_device;
2128 struct pcm_device_profile *pcm_profile;
2129 struct mixer_card *mixer_card;
2130 audio_devices_t devices = usecase->devices;
2131
2132 list_init(&usecase->mixer_list);
2133 list_init(&out->pcm_dev_list);
2134
2135 while ((pcm_profile = get_pcm_device(usecase->type, devices)) != NULL) {
2136 pcm_device = calloc(1, sizeof(struct pcm_device));
2137 pcm_device->pcm_profile = pcm_profile;
2138 list_add_tail(&out->pcm_dev_list, &pcm_device->stream_list_node);
2139 mixer_card = uc_get_mixer_for_card(usecase, pcm_profile->card);
2140 if (mixer_card == NULL) {
2141 mixer_card = adev_get_mixer_for_card(out->dev, pcm_profile->card);
2142 list_add_tail(&usecase->mixer_list, &mixer_card->uc_list_node[usecase->id]);
2143 }
2144 devices &= ~pcm_profile->devices;
2145 }
2146
2147 return 0;
2148}
2149
2150static int out_close_pcm_devices(struct stream_out *out)
2151{
2152 struct pcm_device *pcm_device;
2153 struct listnode *node;
2154 struct audio_device *adev = out->dev;
2155
2156 list_for_each(node, &out->pcm_dev_list) {
2157 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2158 if (pcm_device->sound_trigger_handle > 0) {
2159 adev->sound_trigger_close_for_streaming(pcm_device->sound_trigger_handle);
2160 pcm_device->sound_trigger_handle = 0;
2161 }
2162 if (pcm_device->pcm) {
2163 pcm_close(pcm_device->pcm);
2164 pcm_device->pcm = NULL;
2165 }
2166 if (pcm_device->resampler) {
2167 release_resampler(pcm_device->resampler);
2168 pcm_device->resampler = NULL;
2169 }
2170 if (pcm_device->res_buffer) {
2171 free(pcm_device->res_buffer);
2172 pcm_device->res_buffer = NULL;
2173 }
2174 }
2175
2176 return 0;
2177}
2178
2179static int out_open_pcm_devices(struct stream_out *out)
2180{
2181 struct pcm_device *pcm_device;
2182 struct listnode *node;
2183 int ret = 0;
2184
2185 list_for_each(node, &out->pcm_dev_list) {
2186 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2187 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
2188 __func__, pcm_device->pcm_profile->card, pcm_device->pcm_profile->id);
2189
2190 pcm_device->pcm = pcm_open(pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
2191 PCM_OUT | PCM_MONOTONIC, &pcm_device->pcm_profile->config);
2192
2193 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2194 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2195 pcm_device->pcm = NULL;
2196 ret = -EIO;
2197 goto error_open;
2198 }
2199 /*
2200 * If the stream rate differs from the PCM rate, we need to
2201 * create a resampler.
2202 */
2203 if (out->sample_rate != pcm_device->pcm_profile->config.rate) {
2204 ALOGV("%s: create_resampler(), pcm_device_card(%d), pcm_device_id(%d), \
2205 out_rate(%d), device_rate(%d)",__func__,
2206 pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
2207 out->sample_rate, pcm_device->pcm_profile->config.rate);
2208 ret = create_resampler(out->sample_rate,
2209 pcm_device->pcm_profile->config.rate,
2210 audio_channel_count_from_out_mask(out->channel_mask),
2211 RESAMPLER_QUALITY_DEFAULT,
2212 NULL,
2213 &pcm_device->resampler);
2214 pcm_device->res_byte_count = 0;
2215 pcm_device->res_buffer = NULL;
2216 }
2217 }
2218 return ret;
2219
2220error_open:
2221 out_close_pcm_devices(out);
2222 return ret;
2223}
2224
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002225int disable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002226{
2227 struct audio_device *adev = out->dev;
2228 struct audio_usecase *uc_info;
2229
2230 uc_info = get_usecase_from_id(adev, out->usecase);
2231 if (uc_info == NULL) {
2232 ALOGE("%s: Could not find the usecase (%d) in the list",
2233 __func__, out->usecase);
2234 return -EINVAL;
2235 }
2236 disable_snd_device(adev, uc_info, uc_info->out_snd_device, true);
2237 uc_release_pcm_devices(uc_info);
2238 list_remove(&uc_info->adev_list_node);
2239 free(uc_info);
2240
2241 return 0;
2242}
2243
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002244void enable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002245{
2246 struct audio_device *adev = out->dev;
2247 struct audio_usecase *uc_info;
2248
2249 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
2250 uc_info->id = out->usecase;
2251 uc_info->type = PCM_PLAYBACK;
2252 uc_info->stream = (struct audio_stream *)out;
2253 uc_info->devices = out->devices;
2254 uc_info->in_snd_device = SND_DEVICE_NONE;
2255 uc_info->out_snd_device = SND_DEVICE_NONE;
2256 uc_select_pcm_devices(uc_info);
2257
2258 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2259 select_devices(adev, out->usecase);
2260}
2261
2262static int stop_output_stream(struct stream_out *out)
2263{
2264 int ret = 0;
2265 struct audio_device *adev = out->dev;
2266 bool do_disable = true;
2267
2268 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2269 out->usecase, use_case_table[out->usecase]);
2270
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002271 stop_output_offload_stream(out, &do_disable);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002272
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002273 if (do_disable)
2274 ret = disable_output_path_l(out);
2275
2276 ALOGV("%s: exit: status(%d)", __func__, ret);
2277 return ret;
2278}
2279
2280static int start_output_stream(struct stream_out *out)
2281{
2282 int ret = 0;
2283 struct audio_device *adev = out->dev;
2284
2285 ALOGV("%s: enter: usecase(%d: %s) devices(%#x) channels(%d)",
2286 __func__, out->usecase, use_case_table[out->usecase], out->devices, out->config.channels);
2287
2288 enable_output_path_l(out);
2289
2290 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2291 out->compr = NULL;
2292 ret = out_open_pcm_devices(out);
2293 if (ret != 0)
2294 goto error_open;
2295#ifdef PREPROCESSING_ENABLED
2296 out->echo_reference = NULL;
2297 out->echo_reference_generation = adev->echo_reference_generation;
2298 if (adev->echo_reference != NULL)
2299 out->echo_reference = adev->echo_reference;
2300#endif
2301 } else {
2302 out->compr = compress_open(COMPRESS_CARD, COMPRESS_DEVICE,
2303 COMPRESS_IN, &out->compr_config);
2304 if (out->compr && !is_compress_ready(out->compr)) {
2305 ALOGE("%s: %s", __func__, compress_get_error(out->compr));
2306 compress_close(out->compr);
2307 out->compr = NULL;
2308 ret = -EIO;
2309 goto error_open;
2310 }
2311 if (out->offload_callback)
2312 compress_nonblock(out->compr, out->non_blocking);
2313
2314 if (adev->offload_fx_start_output != NULL)
2315 adev->offload_fx_start_output(out->handle);
2316 }
2317 ALOGV("%s: exit", __func__);
2318 return 0;
2319error_open:
2320 stop_output_stream(out);
2321error_config:
2322 return ret;
2323}
2324
2325static int stop_voice_call(struct audio_device *adev)
2326{
2327 struct audio_usecase *uc_info;
2328
2329 ALOGV("%s: enter", __func__);
2330 adev->in_call = false;
2331
2332 /* TODO: implement voice call stop */
2333
2334 uc_info = get_usecase_from_id(adev, USECASE_VOICE_CALL);
2335 if (uc_info == NULL) {
2336 ALOGE("%s: Could not find the usecase (%d) in the list",
2337 __func__, USECASE_VOICE_CALL);
2338 return -EINVAL;
2339 }
2340
2341 disable_snd_device(adev, uc_info, uc_info->out_snd_device, false);
2342 disable_snd_device(adev, uc_info, uc_info->in_snd_device, true);
2343
2344 uc_release_pcm_devices(uc_info);
2345 list_remove(&uc_info->adev_list_node);
2346 free(uc_info);
2347
2348 ALOGV("%s: exit", __func__);
2349 return 0;
2350}
2351
2352/* always called with adev lock held */
2353static int start_voice_call(struct audio_device *adev)
2354{
2355 struct audio_usecase *uc_info;
2356
2357 ALOGV("%s: enter", __func__);
2358
2359 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
2360 uc_info->id = USECASE_VOICE_CALL;
2361 uc_info->type = VOICE_CALL;
2362 uc_info->stream = (struct audio_stream *)adev->primary_output;
2363 uc_info->devices = adev->primary_output->devices;
2364 uc_info->in_snd_device = SND_DEVICE_NONE;
2365 uc_info->out_snd_device = SND_DEVICE_NONE;
2366
2367 uc_select_pcm_devices(uc_info);
2368
2369 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2370
2371 select_devices(adev, USECASE_VOICE_CALL);
2372
2373
2374 /* TODO: implement voice call start */
2375
2376 /* set cached volume */
2377 set_voice_volume_l(adev, adev->voice_volume);
2378
2379 adev->in_call = true;
2380 ALOGV("%s: exit", __func__);
2381 return 0;
2382}
2383
2384static int check_input_parameters(uint32_t sample_rate,
2385 audio_format_t format,
2386 int channel_count)
2387{
2388 if (format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL;
2389
2390 if ((channel_count < 1) || (channel_count > 2)) return -EINVAL;
2391
2392 switch (sample_rate) {
2393 case 8000:
2394 case 11025:
2395 case 12000:
2396 case 16000:
2397 case 22050:
2398 case 24000:
2399 case 32000:
2400 case 44100:
2401 case 48000:
2402 break;
2403 default:
2404 return -EINVAL;
2405 }
2406
2407 return 0;
2408}
2409
2410static size_t get_input_buffer_size(uint32_t sample_rate,
2411 audio_format_t format,
2412 int channel_count,
2413 usecase_type_t usecase_type,
2414 audio_devices_t devices)
2415{
2416 size_t size = 0;
2417 struct pcm_device_profile *pcm_profile;
2418
2419 if (check_input_parameters(sample_rate, format, channel_count) != 0)
2420 return 0;
2421
2422 pcm_profile = get_pcm_device(usecase_type, devices);
2423 if (pcm_profile == NULL)
2424 return 0;
2425
2426 /*
2427 * take resampling into account and return the closest majoring
2428 * multiple of 16 frames, as audioflinger expects audio buffers to
2429 * be a multiple of 16 frames
2430 */
2431 size = (pcm_profile->config.period_size * sample_rate) / pcm_profile->config.rate;
2432 size = ((size + 15) / 16) * 16;
2433
2434 return (size * channel_count * audio_bytes_per_sample(format));
2435
2436}
2437
2438static uint32_t out_get_sample_rate(const struct audio_stream *stream)
2439{
2440 struct stream_out *out = (struct stream_out *)stream;
2441
2442 return out->sample_rate;
2443}
2444
2445static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
2446{
2447 (void)stream;
2448 (void)rate;
2449 return -ENOSYS;
2450}
2451
2452static size_t out_get_buffer_size(const struct audio_stream *stream)
2453{
2454 struct stream_out *out = (struct stream_out *)stream;
2455
2456 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2457 return out->compr_config.fragment_size;
2458 }
2459
2460 return out->config.period_size *
2461 audio_stream_out_frame_size((const struct audio_stream_out *)stream);
2462}
2463
2464static uint32_t out_get_channels(const struct audio_stream *stream)
2465{
2466 struct stream_out *out = (struct stream_out *)stream;
2467
2468 return out->channel_mask;
2469}
2470
2471static audio_format_t out_get_format(const struct audio_stream *stream)
2472{
2473 struct stream_out *out = (struct stream_out *)stream;
2474
2475 return out->format;
2476}
2477
2478static int out_set_format(struct audio_stream *stream, audio_format_t format)
2479{
2480 (void)stream;
2481 (void)format;
2482 return -ENOSYS;
2483}
2484
2485static int do_out_standby_l(struct stream_out *out)
2486{
2487 struct audio_device *adev = out->dev;
2488 int status = 0;
2489
2490 out->standby = true;
2491 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2492 out_close_pcm_devices(out);
2493#ifdef PREPROCESSING_ENABLED
2494 /* stop writing to echo reference */
2495 if (out->echo_reference != NULL) {
2496 out->echo_reference->write(out->echo_reference, NULL);
2497 if (out->echo_reference_generation != adev->echo_reference_generation) {
2498 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
2499 release_echo_reference(out->echo_reference);
2500 out->echo_reference_generation = adev->echo_reference_generation;
2501 }
2502 out->echo_reference = NULL;
2503 }
2504#endif
2505 } else {
2506 stop_compressed_output_l(out);
2507 out->gapless_mdata.encoder_delay = 0;
2508 out->gapless_mdata.encoder_padding = 0;
2509 if (out->compr != NULL) {
2510 compress_close(out->compr);
2511 out->compr = NULL;
2512 }
2513 }
2514 status = stop_output_stream(out);
2515
2516 return status;
2517}
2518
2519static int out_standby(struct audio_stream *stream)
2520{
2521 struct stream_out *out = (struct stream_out *)stream;
2522 struct audio_device *adev = out->dev;
2523
2524 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2525 out->usecase, use_case_table[out->usecase]);
2526 lock_output_stream(out);
2527 if (!out->standby) {
2528 pthread_mutex_lock(&adev->lock);
2529 do_out_standby_l(out);
2530 pthread_mutex_unlock(&adev->lock);
2531 }
2532 pthread_mutex_unlock(&out->lock);
2533 ALOGV("%s: exit", __func__);
2534 return 0;
2535}
2536
2537static int out_dump(const struct audio_stream *stream, int fd)
2538{
2539 (void)stream;
2540 (void)fd;
2541
2542 return 0;
2543}
2544
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002545static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
2546{
2547 struct stream_out *out = (struct stream_out *)stream;
2548 struct audio_device *adev = out->dev;
2549 struct audio_usecase *usecase;
2550 struct listnode *node;
2551 struct str_parms *parms;
2552 char value[32];
2553 int ret, val = 0;
2554 struct audio_usecase *uc_info;
2555 bool do_standby = false;
2556 struct pcm_device *pcm_device;
2557 struct pcm_device_profile *pcm_profile;
2558#ifdef PREPROCESSING_ENABLED
2559 struct stream_in *in = NULL; /* if non-NULL, then force input to standby */
2560#endif
2561
2562 ALOGV("%s: enter: usecase(%d: %s) kvpairs: %s out->devices(%d) adev->mode(%d)",
2563 __func__, out->usecase, use_case_table[out->usecase], kvpairs, out->devices, adev->mode);
2564 parms = str_parms_create_str(kvpairs);
2565 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
2566 if (ret >= 0) {
2567 val = atoi(value);
2568 pthread_mutex_lock(&adev->lock_inputs);
2569 lock_output_stream(out);
2570 pthread_mutex_lock(&adev->lock);
2571#ifdef PREPROCESSING_ENABLED
2572 if (((int)out->devices != val) && (val != 0) && (!out->standby) &&
2573 (out->usecase == USECASE_AUDIO_PLAYBACK)) {
2574 /* reset active input:
2575 * - to attach the echo reference
2576 * - because a change in output device may change mic settings */
2577 if (adev->active_input && (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
2578 adev->active_input->source == AUDIO_SOURCE_MIC)) {
2579 in = adev->active_input;
2580 }
2581 }
2582#endif
2583 if (val != 0) {
2584 out->devices = val;
2585
2586 if (!out->standby) {
2587 uc_info = get_usecase_from_id(adev, out->usecase);
2588 if (uc_info == NULL) {
2589 ALOGE("%s: Could not find the usecase (%d) in the list",
2590 __func__, out->usecase);
2591 } else {
2592 list_for_each(node, &out->pcm_dev_list) {
2593 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2594 if ((pcm_device->pcm_profile->devices & val) == 0)
2595 do_standby = true;
2596 val &= ~pcm_device->pcm_profile->devices;
2597 }
2598 if (val != 0)
2599 do_standby = true;
2600 }
2601 if (do_standby)
2602 do_out_standby_l(out);
2603 else {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002604 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
2605 out_set_offload_parameters(adev, uc_info);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002606 select_devices(adev, out->usecase);
2607 }
2608 }
2609
2610 if ((adev->mode == AUDIO_MODE_IN_CALL) && !adev->in_call &&
2611 (out == adev->primary_output)) {
2612 start_voice_call(adev);
2613 } else if ((adev->mode == AUDIO_MODE_IN_CALL) && adev->in_call &&
2614 (out == adev->primary_output)) {
2615 select_devices(adev, USECASE_VOICE_CALL);
2616 }
2617 }
2618
2619 if ((adev->mode == AUDIO_MODE_NORMAL) && adev->in_call &&
2620 (out == adev->primary_output)) {
2621 stop_voice_call(adev);
2622 }
2623 pthread_mutex_unlock(&adev->lock);
2624 pthread_mutex_unlock(&out->lock);
2625#ifdef PREPROCESSING_ENABLED
2626 if (in) {
2627 /* The lock on adev->lock_inputs prevents input stream from being closed */
2628 lock_input_stream(in);
2629 pthread_mutex_lock(&adev->lock);
2630 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
2631 do_in_standby_l(in);
2632 pthread_mutex_unlock(&adev->lock);
2633 pthread_mutex_unlock(&in->lock);
2634 }
2635#endif
2636 pthread_mutex_unlock(&adev->lock_inputs);
2637 }
2638
2639 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2640 parse_compress_metadata(out, parms);
2641 }
2642
2643 str_parms_destroy(parms);
2644
2645 if (ret > 0)
2646 ret = 0;
2647 ALOGV("%s: exit: code(%d)", __func__, ret);
2648 return ret;
2649}
2650
2651static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
2652{
2653 struct stream_out *out = (struct stream_out *)stream;
2654 struct str_parms *query = str_parms_create_str(keys);
2655 char *str;
2656 char value[256];
2657 struct str_parms *reply = str_parms_create();
2658 size_t i, j;
2659 int ret;
2660 bool first = true;
2661 ALOGV("%s: enter: keys - %s", __func__, keys);
2662 ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value));
2663 if (ret >= 0) {
2664 value[0] = '\0';
2665 i = 0;
2666 while (out->supported_channel_masks[i] != 0) {
2667 for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) {
2668 if (out_channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) {
2669 if (!first) {
2670 strcat(value, "|");
2671 }
2672 strcat(value, out_channels_name_to_enum_table[j].name);
2673 first = false;
2674 break;
2675 }
2676 }
2677 i++;
2678 }
2679 str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
2680 str = str_parms_to_str(reply);
2681 } else {
2682 str = strdup(keys);
2683 }
2684 str_parms_destroy(query);
2685 str_parms_destroy(reply);
2686 ALOGV("%s: exit: returns - %s", __func__, str);
2687 return str;
2688}
2689
2690static uint32_t out_get_latency(const struct audio_stream_out *stream)
2691{
2692 struct stream_out *out = (struct stream_out *)stream;
2693
2694 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
2695 return COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
2696
2697 return (out->config.period_count * out->config.period_size * 1000) /
2698 (out->config.rate);
2699}
2700
2701static int out_set_volume(struct audio_stream_out *stream, float left,
2702 float right)
2703{
2704 struct stream_out *out = (struct stream_out *)stream;
2705 struct audio_device *adev = out->dev;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002706
2707 if (out->usecase == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
2708 /* only take left channel into account: the API is for stereo anyway */
2709 out->muted = (left == 0.0f);
2710 return 0;
2711 } else if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002712 out_set_offload_volume(left, right);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002713 }
2714
2715 return -ENOSYS;
2716}
2717
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002718static int fast_set_affinity(pid_t tid) {
2719 cpu_set_t cpu_set;
2720 int cpu_num;
2721 const char *irq_procfs = "/proc/asound/irq_affinity";
2722 FILE *fp;
2723
2724 if ((fp = fopen(irq_procfs, "r")) == NULL) {
2725 ALOGW("Procfs node %s not found", irq_procfs);
2726 return -1;
2727 }
2728
2729 if (fscanf(fp, "%d", &cpu_num) != 1) {
2730 ALOGW("Couldn't read CPU id from procfs node %s", irq_procfs);
2731 fclose(fp);
2732 return -1;
2733 }
2734 fclose(fp);
2735
2736 CPU_ZERO(&cpu_set);
2737 CPU_SET(cpu_num, &cpu_set);
2738 return sched_setaffinity(tid, sizeof(cpu_set), &cpu_set);
2739}
2740
2741static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
2742 size_t bytes)
2743{
2744 struct stream_out *out = (struct stream_out *)stream;
2745 struct audio_device *adev = out->dev;
2746 ssize_t ret = 0;
2747 struct pcm_device *pcm_device;
2748 struct listnode *node;
2749 size_t frame_size = audio_stream_out_frame_size(stream);
2750 size_t frames_wr = 0, frames_rq = 0;
2751 unsigned char *data = NULL;
2752 struct pcm_config config;
2753#ifdef PREPROCESSING_ENABLED
2754 size_t in_frames = bytes / frame_size;
2755 size_t out_frames = in_frames;
2756 struct stream_in *in = NULL;
2757#endif
2758 pid_t tid;
2759 int err;
2760
2761 lock_output_stream(out);
2762
2763 if (out->usecase == USECASE_AUDIO_PLAYBACK && !out->is_fastmixer_affinity_set) {
2764 tid = gettid();
2765 err = fast_set_affinity(tid);
2766 if (err < 0) {
2767 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
2768 }
2769 out->is_fastmixer_affinity_set = true;
2770 }
2771
2772 if (out->standby) {
2773#ifdef PREPROCESSING_ENABLED
2774 pthread_mutex_unlock(&out->lock);
2775 /* Prevent input stream from being closed */
2776 pthread_mutex_lock(&adev->lock_inputs);
2777 lock_output_stream(out);
2778 if (!out->standby) {
2779 pthread_mutex_unlock(&adev->lock_inputs);
2780 goto false_alarm;
2781 }
2782#endif
2783 pthread_mutex_lock(&adev->lock);
2784 ret = start_output_stream(out);
2785 /* ToDo: If use case is compress offload should return 0 */
2786 if (ret != 0) {
2787 pthread_mutex_unlock(&adev->lock);
2788#ifdef PREPROCESSING_ENABLED
2789 pthread_mutex_unlock(&adev->lock_inputs);
2790#endif
2791 goto exit;
2792 }
2793 out->standby = false;
2794
2795#ifdef PREPROCESSING_ENABLED
2796 /* A change in output device may change the microphone selection */
2797 if (adev->active_input &&
2798 (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
2799 adev->active_input->source == AUDIO_SOURCE_MIC)) {
2800 in = adev->active_input;
2801 ALOGV("%s: enter:) force_input_standby true", __func__);
2802 }
2803#endif
2804 pthread_mutex_unlock(&adev->lock);
2805#ifdef PREPROCESSING_ENABLED
2806 if (!in) {
2807 /* Leave mutex locked iff in != NULL */
2808 pthread_mutex_unlock(&adev->lock_inputs);
2809 }
2810#endif
2811 }
2812false_alarm:
2813
2814 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002815 ret = out_write_offload(stream, buffer, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002816 return ret;
2817 } else {
2818#ifdef PREPROCESSING_ENABLED
2819 if (android_atomic_acquire_load(&adev->echo_reference_generation)
2820 != out->echo_reference_generation) {
2821 pthread_mutex_lock(&adev->lock);
2822 if (out->echo_reference != NULL) {
2823 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
2824 release_echo_reference(out->echo_reference);
2825 }
2826 // note that adev->echo_reference_generation here can be different from the one
2827 // tested above but it doesn't matter as we now have the adev mutex and it is consistent
2828 // with what has been set by get_echo_reference() or put_echo_reference()
2829 out->echo_reference_generation = adev->echo_reference_generation;
2830 out->echo_reference = adev->echo_reference;
2831 ALOGV("%s: update echo reference generation %d", __func__,
2832 out->echo_reference_generation);
2833 pthread_mutex_unlock(&adev->lock);
2834 }
2835#endif
2836
2837 if (out->muted)
2838 memset((void *)buffer, 0, bytes);
2839 list_for_each(node, &out->pcm_dev_list) {
2840 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2841 if (pcm_device->resampler) {
2842 if (bytes * pcm_device->pcm_profile->config.rate / out->sample_rate + frame_size
2843 > pcm_device->res_byte_count) {
2844 pcm_device->res_byte_count =
2845 bytes * pcm_device->pcm_profile->config.rate / out->sample_rate + frame_size;
2846 pcm_device->res_buffer =
2847 realloc(pcm_device->res_buffer, pcm_device->res_byte_count);
2848 ALOGV("%s: resampler res_byte_count = %zu", __func__,
2849 pcm_device->res_byte_count);
2850 }
2851 frames_rq = bytes / frame_size;
2852 frames_wr = pcm_device->res_byte_count / frame_size;
2853 ALOGVV("%s: resampler request frames = %d frame_size = %d",
2854 __func__, frames_rq, frame_size);
2855 pcm_device->resampler->resample_from_input(pcm_device->resampler,
2856 (int16_t *)buffer, &frames_rq, (int16_t *)pcm_device->res_buffer, &frames_wr);
2857 ALOGVV("%s: resampler output frames_= %d", __func__, frames_wr);
2858 }
2859 if (pcm_device->pcm) {
2860#ifdef PREPROCESSING_ENABLED
2861 if (out->echo_reference != NULL && pcm_device->pcm_profile->devices != SND_DEVICE_OUT_SPEAKER) {
2862 struct echo_reference_buffer b;
2863 b.raw = (void *)buffer;
2864 b.frame_count = in_frames;
2865
2866 get_playback_delay(out, out_frames, &b);
2867 out->echo_reference->write(out->echo_reference, &b);
2868 }
2869#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002870 ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
2871 if (pcm_device->resampler && pcm_device->res_buffer)
2872 pcm_device->status =
2873 pcm_write(pcm_device->pcm, (void *)pcm_device->res_buffer,
2874 frames_wr * frame_size);
2875 else
2876 pcm_device->status = pcm_write(pcm_device->pcm, (void *)buffer, bytes);
2877 if (pcm_device->status != 0)
2878 ret = pcm_device->status;
2879 }
2880 }
2881 if (ret == 0)
2882 out->written += bytes / (out->config.channels * sizeof(short));
2883 }
2884
2885exit:
2886 pthread_mutex_unlock(&out->lock);
2887
2888 if (ret != 0) {
2889 list_for_each(node, &out->pcm_dev_list) {
2890 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2891 if (pcm_device->pcm && pcm_device->status != 0)
2892 ALOGE("%s: error %zd - %s", __func__, ret, pcm_get_error(pcm_device->pcm));
2893 }
2894 out_standby(&out->stream.common);
2895 usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
2896 out_get_sample_rate(&out->stream.common));
2897 }
2898
2899#ifdef PREPROCESSING_ENABLED
2900 if (in) {
2901 /* The lock on adev->lock_inputs prevents input stream from being closed */
2902 lock_input_stream(in);
2903 pthread_mutex_lock(&adev->lock);
2904 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
2905 do_in_standby_l(in);
2906 pthread_mutex_unlock(&adev->lock);
2907 pthread_mutex_unlock(&in->lock);
2908 /* This mutex was left locked iff in != NULL */
2909 pthread_mutex_unlock(&adev->lock_inputs);
2910 }
2911#endif
2912
2913 return bytes;
2914}
2915
2916static int out_get_render_position(const struct audio_stream_out *stream,
2917 uint32_t *dsp_frames)
2918{
2919 struct stream_out *out = (struct stream_out *)stream;
2920 *dsp_frames = 0;
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002921 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2922 return out_get_render_offload_position(out, dsp_frames);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002923 } else
2924 return -EINVAL;
2925}
2926
2927static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
2928{
2929 (void)stream;
2930 (void)effect;
2931 return 0;
2932}
2933
2934static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
2935{
2936 (void)stream;
2937 (void)effect;
2938 return 0;
2939}
2940
2941static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
2942 int64_t *timestamp)
2943{
2944 (void)stream;
2945 (void)timestamp;
2946 return -EINVAL;
2947}
2948
2949static int out_get_presentation_position(const struct audio_stream_out *stream,
2950 uint64_t *frames, struct timespec *timestamp)
2951{
2952 struct stream_out *out = (struct stream_out *)stream;
2953 int ret = -1;
2954 unsigned long dsp_frames;
2955
2956 lock_output_stream(out);
2957
2958 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002959 ret = out_get_presentation_offload_position(out, frames, timestamp);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002960 } else {
2961 /* FIXME: which device to read from? */
2962 if (!list_empty(&out->pcm_dev_list)) {
2963 unsigned int avail;
2964 struct pcm_device *pcm_device = node_to_item(list_head(&out->pcm_dev_list),
2965 struct pcm_device, stream_list_node);
2966
2967 if (pcm_get_htimestamp(pcm_device->pcm, &avail, timestamp) == 0) {
2968 size_t kernel_buffer_size = out->config.period_size * out->config.period_count;
2969 int64_t signed_frames = out->written - kernel_buffer_size + avail;
2970 /* This adjustment accounts for buffering after app processor.
2971 It is based on estimated DSP latency per use case, rather than exact. */
2972 signed_frames -=
2973 (render_latency(out->usecase) * out->sample_rate / 1000000LL);
2974
2975 /* It would be unusual for this value to be negative, but check just in case ... */
2976 if (signed_frames >= 0) {
2977 *frames = signed_frames;
2978 ret = 0;
2979 }
2980 }
2981 }
2982 }
2983
2984 pthread_mutex_unlock(&out->lock);
2985
2986 return ret;
2987}
2988
2989static int out_set_callback(struct audio_stream_out *stream,
2990 stream_callback_t callback, void *cookie)
2991{
2992 struct stream_out *out = (struct stream_out *)stream;
2993
2994 ALOGV("%s", __func__);
2995 lock_output_stream(out);
2996 out->offload_callback = callback;
2997 out->offload_cookie = cookie;
2998 pthread_mutex_unlock(&out->lock);
2999 return 0;
3000}
3001
3002static int out_pause(struct audio_stream_out* stream)
3003{
3004 struct stream_out *out = (struct stream_out *)stream;
3005 int status = -ENOSYS;
3006 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003007 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3008 status = out_pause_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003009 return status;
3010}
3011
3012static int out_resume(struct audio_stream_out* stream)
3013{
3014 struct stream_out *out = (struct stream_out *)stream;
3015 int status = -ENOSYS;
3016 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003017 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3018 status = out_resume_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003019 return status;
3020}
3021
3022static int out_drain(struct audio_stream_out* stream, audio_drain_type_t type )
3023{
3024 struct stream_out *out = (struct stream_out *)stream;
3025 int status = -ENOSYS;
3026 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003027 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3028 status = out_drain_offload(out, type);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003029 return status;
3030}
3031
3032static int out_flush(struct audio_stream_out* stream)
3033{
3034 struct stream_out *out = (struct stream_out *)stream;
3035 ALOGV("%s", __func__);
3036 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003037 return out_flush_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003038 }
3039 return -ENOSYS;
3040}
3041
3042/** audio_stream_in implementation **/
3043static uint32_t in_get_sample_rate(const struct audio_stream *stream)
3044{
3045 struct stream_in *in = (struct stream_in *)stream;
3046
3047 return in->requested_rate;
3048}
3049
3050static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
3051{
3052 (void)stream;
3053 (void)rate;
3054 return -ENOSYS;
3055}
3056
3057static uint32_t in_get_channels(const struct audio_stream *stream)
3058{
3059 struct stream_in *in = (struct stream_in *)stream;
3060
3061 return in->main_channels;
3062}
3063
3064static audio_format_t in_get_format(const struct audio_stream *stream)
3065{
3066 (void)stream;
3067 return AUDIO_FORMAT_PCM_16_BIT;
3068}
3069
3070static int in_set_format(struct audio_stream *stream, audio_format_t format)
3071{
3072 (void)stream;
3073 (void)format;
3074
3075 return -ENOSYS;
3076}
3077
3078static size_t in_get_buffer_size(const struct audio_stream *stream)
3079{
3080 struct stream_in *in = (struct stream_in *)stream;
3081
3082 return get_input_buffer_size(in->requested_rate,
3083 in_get_format(stream),
3084 audio_channel_count_from_in_mask(in->main_channels),
3085 in->usecase_type,
3086 in->devices);
3087}
3088
3089static int in_close_pcm_devices(struct stream_in *in)
3090{
3091 struct pcm_device *pcm_device;
3092 struct listnode *node;
3093 struct audio_device *adev = in->dev;
3094
3095 list_for_each(node, &in->pcm_dev_list) {
3096 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3097 if (pcm_device) {
3098 if (pcm_device->pcm)
3099 pcm_close(pcm_device->pcm);
3100 pcm_device->pcm = NULL;
3101 if (pcm_device->sound_trigger_handle > 0)
3102 adev->sound_trigger_close_for_streaming(pcm_device->sound_trigger_handle);
3103 pcm_device->sound_trigger_handle = 0;
3104 }
3105 }
3106 return 0;
3107}
3108
3109
3110/* must be called with stream and hw device mutex locked */
3111static int do_in_standby_l(struct stream_in *in)
3112{
3113 int status = 0;
3114
3115#ifdef PREPROCESSING_ENABLED
3116 struct audio_device *adev = in->dev;
3117#endif
3118 if (!in->standby) {
3119
3120 in_close_pcm_devices(in);
3121
3122#ifdef PREPROCESSING_ENABLED
3123 if (in->echo_reference != NULL) {
3124 /* stop reading from echo reference */
3125 in->echo_reference->read(in->echo_reference, NULL);
3126 put_echo_reference(adev, in->echo_reference);
3127 in->echo_reference = NULL;
3128 }
3129#ifdef HW_AEC_LOOPBACK
3130 if (in->hw_echo_reference)
3131 {
3132 if (in->hw_ref_buf) {
3133 free(in->hw_ref_buf);
3134 in->hw_ref_buf = NULL;
3135 }
3136 }
3137#endif // HW_AEC_LOOPBACK
3138#endif // PREPROCESSING_ENABLED
3139
3140 status = stop_input_stream(in);
3141
3142 if (in->read_buf) {
3143 free(in->read_buf);
3144 in->read_buf = NULL;
3145 }
3146
3147 in->standby = 1;
3148 }
3149 return 0;
3150}
3151
3152// called with adev->lock_inputs locked
3153static int in_standby_l(struct stream_in *in)
3154{
3155 struct audio_device *adev = in->dev;
3156 int status = 0;
3157 lock_input_stream(in);
3158 if (!in->standby) {
3159 pthread_mutex_lock(&adev->lock);
3160 status = do_in_standby_l(in);
3161 pthread_mutex_unlock(&adev->lock);
3162 }
3163 pthread_mutex_unlock(&in->lock);
3164 return status;
3165}
3166
3167static int in_standby(struct audio_stream *stream)
3168{
3169 struct stream_in *in = (struct stream_in *)stream;
3170 struct audio_device *adev = in->dev;
3171 int status;
3172 ALOGV("%s: enter", __func__);
3173 pthread_mutex_lock(&adev->lock_inputs);
3174 status = in_standby_l(in);
3175 pthread_mutex_unlock(&adev->lock_inputs);
3176 ALOGV("%s: exit: status(%d)", __func__, status);
3177 return status;
3178}
3179
3180static int in_dump(const struct audio_stream *stream, int fd)
3181{
3182 (void)stream;
3183 (void)fd;
3184
3185 return 0;
3186}
3187
3188static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
3189{
3190 struct stream_in *in = (struct stream_in *)stream;
3191 struct audio_device *adev = in->dev;
3192 struct str_parms *parms;
3193 char *str;
3194 char value[32];
3195 int ret, val = 0;
3196 struct audio_usecase *uc_info;
3197 bool do_standby = false;
3198 struct listnode *node;
3199 struct pcm_device *pcm_device;
3200 struct pcm_device_profile *pcm_profile;
3201
3202 ALOGV("%s: enter: kvpairs=%s", __func__, kvpairs);
3203 parms = str_parms_create_str(kvpairs);
3204
3205 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
3206
3207 pthread_mutex_lock(&adev->lock_inputs);
3208 lock_input_stream(in);
3209 pthread_mutex_lock(&adev->lock);
3210 if (ret >= 0) {
3211 val = atoi(value);
3212 /* no audio source uses val == 0 */
3213 if (((int)in->source != val) && (val != 0)) {
3214 in->source = val;
3215 }
3216 }
3217
3218 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
3219 if (ret >= 0) {
3220 val = atoi(value);
3221 if (((int)in->devices != val) && (val != 0)) {
3222 in->devices = val;
3223 /* If recording is in progress, change the tx device to new device */
3224 if (!in->standby) {
3225 uc_info = get_usecase_from_id(adev, in->usecase);
3226 if (uc_info == NULL) {
3227 ALOGE("%s: Could not find the usecase (%d) in the list",
3228 __func__, in->usecase);
3229 } else {
3230 if (list_empty(&in->pcm_dev_list))
3231 ALOGE("%s: pcm device list empty", __func__);
3232 else {
3233 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3234 struct pcm_device, stream_list_node);
3235 if ((pcm_device->pcm_profile->devices & val & ~AUDIO_DEVICE_BIT_IN) == 0) {
3236 do_standby = true;
3237 }
3238 }
3239 }
3240 if (do_standby) {
3241 ret = do_in_standby_l(in);
3242 } else
3243 ret = select_devices(adev, in->usecase);
3244 }
3245 }
3246 }
3247 pthread_mutex_unlock(&adev->lock);
3248 pthread_mutex_unlock(&in->lock);
3249 pthread_mutex_unlock(&adev->lock_inputs);
3250 str_parms_destroy(parms);
3251
3252 if (ret > 0)
3253 ret = 0;
3254
3255 ALOGV("%s: exit: status(%d)", __func__, ret);
3256 return ret;
3257}
3258
3259static char* in_get_parameters(const struct audio_stream *stream,
3260 const char *keys)
3261{
3262 (void)stream;
3263 (void)keys;
3264
3265 return strdup("");
3266}
3267
3268static int in_set_gain(struct audio_stream_in *stream, float gain)
3269{
3270 (void)stream;
3271 (void)gain;
3272
3273 return 0;
3274}
3275
3276static ssize_t read_bytes_from_dsp(struct stream_in *in, void* buffer,
3277 size_t bytes)
3278{
3279 struct pcm_device *pcm_device;
3280 struct audio_device *adev = in->dev;
3281
3282 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3283 struct pcm_device, stream_list_node);
3284
3285 if (pcm_device->sound_trigger_handle > 0)
3286 return adev->sound_trigger_read_samples(pcm_device->sound_trigger_handle, buffer, bytes);
3287 else
3288 return 0;
3289}
3290
3291static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
3292 size_t bytes)
3293{
3294 struct stream_in *in = (struct stream_in *)stream;
3295 struct audio_device *adev = in->dev;
3296 ssize_t frames = -1;
3297 int ret = -1;
3298 int read_and_process_successful = false;
3299
3300 size_t frames_rq = bytes / audio_stream_in_frame_size(stream);
3301 pid_t tid;
3302 int err;
3303
3304 /* no need to acquire adev->lock_inputs because API contract prevents a close */
3305 lock_input_stream(in);
3306
3307 if (in->usecase == USECASE_AUDIO_CAPTURE && !in->is_fastcapture_affinity_set) {
3308 tid = gettid();
3309 err = fast_set_affinity(tid);
3310 if (err < 0) {
3311 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
3312 }
3313 in->is_fastcapture_affinity_set = true;
3314 }
3315
3316 if (in->standby) {
3317 pthread_mutex_unlock(&in->lock);
3318 pthread_mutex_lock(&adev->lock_inputs);
3319 lock_input_stream(in);
3320 if (!in->standby) {
3321 pthread_mutex_unlock(&adev->lock_inputs);
3322 goto false_alarm;
3323 }
3324 pthread_mutex_lock(&adev->lock);
3325 ret = start_input_stream(in);
3326 pthread_mutex_unlock(&adev->lock);
3327 pthread_mutex_unlock(&adev->lock_inputs);
3328 if (ret != 0) {
3329 goto exit;
3330 }
3331 in->standby = 0;
3332 }
3333false_alarm:
3334
3335 if (!list_empty(&in->pcm_dev_list)) {
3336 if (in->usecase == USECASE_AUDIO_CAPTURE_HOTWORD) {
3337 bytes = read_bytes_from_dsp(in, buffer, bytes);
3338 if (bytes > 0)
3339 read_and_process_successful = true;
3340 } else {
3341 /*
3342 * Read PCM and:
3343 * - resample if needed
3344 * - process if pre-processors are attached
3345 * - discard unwanted channels
3346 */
3347 frames = read_and_process_frames(in, buffer, frames_rq);
3348 if (frames >= 0)
3349 read_and_process_successful = true;
3350 }
3351 }
3352
3353 /*
3354 * Instead of writing zeroes here, we could trust the hardware
3355 * to always provide zeroes when muted.
3356 */
3357 if (read_and_process_successful == true && adev->mic_mute)
3358 memset(buffer, 0, bytes);
3359
3360exit:
3361 pthread_mutex_unlock(&in->lock);
3362
3363 if (read_and_process_successful == false) {
3364 in_standby(&in->stream.common);
3365 ALOGV("%s: read failed - sleeping for buffer duration", __func__);
3366 usleep(bytes * 1000000 / audio_stream_in_frame_size(stream) /
3367 in->requested_rate);
3368 }
3369 return bytes;
3370}
3371
3372static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
3373{
3374 (void)stream;
3375
3376 return 0;
3377}
3378
3379static int add_remove_audio_effect(const struct audio_stream *stream,
3380 effect_handle_t effect,
3381 bool enable)
3382{
3383 struct stream_in *in = (struct stream_in *)stream;
3384 struct audio_device *adev = in->dev;
3385 int status = 0;
3386 effect_descriptor_t desc;
3387#ifdef PREPROCESSING_ENABLED
3388 int i;
3389#endif
3390 status = (*effect)->get_descriptor(effect, &desc);
3391 if (status != 0)
3392 return status;
3393
3394 ALOGI("add_remove_audio_effect(), effect type: %08x, enable: %d ", desc.type.timeLow, enable);
3395
3396 pthread_mutex_lock(&adev->lock_inputs);
3397 lock_input_stream(in);
3398 pthread_mutex_lock(&in->dev->lock);
3399#ifndef PREPROCESSING_ENABLED
3400 if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) &&
3401 in->enable_aec != enable &&
3402 (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0)) {
3403 in->enable_aec = enable;
3404 if (!in->standby)
3405 select_devices(in->dev, in->usecase);
3406 }
3407#else
3408 if ( (in->num_preprocessors > MAX_PREPROCESSORS) && (enable == true) ) {
3409 status = -ENOSYS;
3410 goto exit;
3411 }
3412 if ( enable == true ) {
3413 in->preprocessors[in->num_preprocessors].effect_itfe = effect;
3414 /* add the supported channel of the effect in the channel_configs */
3415 in_read_audio_effect_channel_configs(in, &in->preprocessors[in->num_preprocessors]);
3416 in->num_preprocessors ++;
3417 /* check compatibility between main channel supported and possible auxiliary channels */
3418 in_update_aux_channels(in, effect);//wesley crash
3419 in->aux_channels_changed = true;
3420 } else {
3421 /* if ( enable == false ) */
3422 if (in->num_preprocessors <= 0) {
3423 status = -ENOSYS;
3424 goto exit;
3425 }
3426 status = -EINVAL;
3427 for (i=0; i < in->num_preprocessors; i++) {
3428 if (status == 0) { /* status == 0 means an effect was removed from a previous slot */
3429 in->preprocessors[i - 1].effect_itfe = in->preprocessors[i].effect_itfe;
3430 in->preprocessors[i - 1].channel_configs = in->preprocessors[i].channel_configs;
3431 in->preprocessors[i - 1].num_channel_configs =
3432 in->preprocessors[i].num_channel_configs;
3433 ALOGV("add_remove_audio_effect moving fx from %d to %d", i, i-1);
3434 continue;
3435 }
3436 if ( in->preprocessors[i].effect_itfe == effect ) {
3437 ALOGV("add_remove_audio_effect found fx at index %d", i);
3438 free(in->preprocessors[i].channel_configs);
3439 status = 0;
3440 }
3441 }
3442 if (status != 0)
3443 goto exit;
3444 in->num_preprocessors--;
3445 /* if we remove one effect, at least the last proproc should be reset */
3446 in->preprocessors[in->num_preprocessors].num_channel_configs = 0;
3447 in->preprocessors[in->num_preprocessors].effect_itfe = NULL;
3448 in->preprocessors[in->num_preprocessors].channel_configs = NULL;
3449 in->aux_channels_changed = false;
3450 ALOGV("%s: enable(%d), in->aux_channels_changed(%d)", __func__, enable, in->aux_channels_changed);
3451 }
3452 ALOGI("%s: num_preprocessors = %d", __func__, in->num_preprocessors);
3453
3454 if ( memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
3455 in->enable_aec = enable;
3456 ALOGV("add_remove_audio_effect(), FX_IID_AEC, enable: %d", enable);
3457 if (!in->standby) {
3458 select_devices(in->dev, in->usecase);
3459 do_in_standby_l(in);
3460 }
3461 if (in->enable_aec == true) {
3462 in_configure_reverse(in);
3463 }
3464 }
3465exit:
3466#endif
3467 ALOGW_IF(status != 0, "add_remove_audio_effect() error %d", status);
3468 pthread_mutex_unlock(&in->dev->lock);
3469 pthread_mutex_unlock(&in->lock);
3470 pthread_mutex_unlock(&adev->lock_inputs);
3471 return status;
3472}
3473
3474static int in_add_audio_effect(const struct audio_stream *stream,
3475 effect_handle_t effect)
3476{
3477 ALOGV("%s: effect %p", __func__, effect);
3478 return add_remove_audio_effect(stream, effect, true);
3479}
3480
3481static int in_remove_audio_effect(const struct audio_stream *stream,
3482 effect_handle_t effect)
3483{
3484 ALOGV("%s: effect %p", __func__, effect);
3485 return add_remove_audio_effect(stream, effect, false);
3486}
3487
3488static int adev_open_output_stream(struct audio_hw_device *dev,
3489 audio_io_handle_t handle,
3490 audio_devices_t devices,
3491 audio_output_flags_t flags,
3492 struct audio_config *config,
3493 struct audio_stream_out **stream_out,
3494 const char *address __unused)
3495{
3496 struct audio_device *adev = (struct audio_device *)dev;
3497 struct stream_out *out;
3498 int i, ret;
3499 struct pcm_device_profile *pcm_profile;
3500
3501 ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
3502 __func__, config->sample_rate, config->channel_mask, devices, flags);
3503 *stream_out = NULL;
3504 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
3505
3506 if (devices == AUDIO_DEVICE_NONE)
3507 devices = AUDIO_DEVICE_OUT_SPEAKER;
3508
3509 out->flags = flags;
3510 out->devices = devices;
3511 out->dev = adev;
3512 out->format = config->format;
3513 out->sample_rate = config->sample_rate;
3514 out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3515 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
3516 out->handle = handle;
3517
3518 pcm_profile = get_pcm_device(PCM_PLAYBACK, devices);
3519 if (pcm_profile == NULL) {
3520 ret = -EINVAL;
3521 goto error_open;
3522 }
3523 out->config = pcm_profile->config;
3524
3525 /* Init use case and pcm_config */
3526 if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
3527 if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version ||
3528 config->offload_info.size != AUDIO_INFO_INITIALIZER.size) {
3529 ALOGE("%s: Unsupported Offload information", __func__);
3530 ret = -EINVAL;
3531 goto error_open;
3532 }
3533 if (!is_supported_format(config->offload_info.format)) {
3534 ALOGE("%s: Unsupported audio format", __func__);
3535 ret = -EINVAL;
3536 goto error_open;
3537 }
3538
3539 out->compr_config.codec = (struct snd_codec *)
3540 calloc(1, sizeof(struct snd_codec));
3541
3542 out->usecase = USECASE_AUDIO_PLAYBACK_OFFLOAD;
3543 if (config->offload_info.channel_mask)
3544 out->channel_mask = config->offload_info.channel_mask;
3545 else if (config->channel_mask)
3546 out->channel_mask = config->channel_mask;
3547 out->format = config->offload_info.format;
3548 out->sample_rate = config->offload_info.sample_rate;
3549
3550 out->stream.set_callback = out_set_callback;
3551 out->stream.pause = out_pause;
3552 out->stream.resume = out_resume;
3553 out->stream.drain = out_drain;
3554 out->stream.flush = out_flush;
3555
3556 out->compr_config.codec->id =
3557 get_snd_codec_id(config->offload_info.format);
3558 out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
3559 out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
3560 out->compr_config.codec->sample_rate = config->offload_info.sample_rate;
3561 out->compr_config.codec->bit_rate =
3562 config->offload_info.bit_rate;
3563 out->compr_config.codec->ch_in =
3564 audio_channel_count_from_out_mask(config->channel_mask);
3565 out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
3566
3567 if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
3568 out->non_blocking = 1;
3569
3570 out->send_new_metadata = 1;
3571 create_offload_callback_thread(out);
3572 out->offload_state = OFFLOAD_STATE_IDLE;
3573
3574 ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
3575 __func__, config->offload_info.version,
3576 config->offload_info.bit_rate);
3577 } else if (out->flags & (AUDIO_OUTPUT_FLAG_DEEP_BUFFER)) {
3578 out->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
3579 out->config = pcm_config_deep_buffer;
3580 out->sample_rate = out->config.rate;
3581 ALOGV("%s: use AUDIO_PLAYBACK_DEEP_BUFFER",__func__);
3582 } else {
3583 out->usecase = USECASE_AUDIO_PLAYBACK;
3584 out->sample_rate = out->config.rate;
3585 }
3586
3587 if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
3588 if (adev->primary_output == NULL)
3589 adev->primary_output = out;
3590 else {
3591 ALOGE("%s: Primary output is already opened", __func__);
3592 ret = -EEXIST;
3593 goto error_open;
3594 }
3595 }
3596
3597 /* Check if this usecase is already existing */
3598 pthread_mutex_lock(&adev->lock);
3599 if (get_usecase_from_id(adev, out->usecase) != NULL) {
3600 ALOGE("%s: Usecase (%d) is already present", __func__, out->usecase);
3601 pthread_mutex_unlock(&adev->lock);
3602 ret = -EEXIST;
3603 goto error_open;
3604 }
3605 pthread_mutex_unlock(&adev->lock);
3606
3607 out->stream.common.get_sample_rate = out_get_sample_rate;
3608 out->stream.common.set_sample_rate = out_set_sample_rate;
3609 out->stream.common.get_buffer_size = out_get_buffer_size;
3610 out->stream.common.get_channels = out_get_channels;
3611 out->stream.common.get_format = out_get_format;
3612 out->stream.common.set_format = out_set_format;
3613 out->stream.common.standby = out_standby;
3614 out->stream.common.dump = out_dump;
3615 out->stream.common.set_parameters = out_set_parameters;
3616 out->stream.common.get_parameters = out_get_parameters;
3617 out->stream.common.add_audio_effect = out_add_audio_effect;
3618 out->stream.common.remove_audio_effect = out_remove_audio_effect;
3619 out->stream.get_latency = out_get_latency;
3620 out->stream.set_volume = out_set_volume;
3621 out->stream.write = out_write;
3622 out->stream.get_render_position = out_get_render_position;
3623 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
3624 out->stream.get_presentation_position = out_get_presentation_position;
3625
3626 out->standby = 1;
3627 /* out->muted = false; by calloc() */
3628 /* out->written = 0; by calloc() */
3629
3630 pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
3631 pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
3632 pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
3633
3634 config->format = out->stream.common.get_format(&out->stream.common);
3635 config->channel_mask = out->stream.common.get_channels(&out->stream.common);
3636 config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
3637
3638 out->is_fastmixer_affinity_set = false;
3639
3640 *stream_out = &out->stream;
3641 ALOGV("%s: exit", __func__);
3642 return 0;
3643
3644error_open:
3645 free(out);
3646 *stream_out = NULL;
3647 ALOGV("%s: exit: ret %d", __func__, ret);
3648 return ret;
3649}
3650
3651static void adev_close_output_stream(struct audio_hw_device *dev,
3652 struct audio_stream_out *stream)
3653{
3654 struct stream_out *out = (struct stream_out *)stream;
3655 struct audio_device *adev = out->dev;
3656 (void)dev;
3657
3658 ALOGV("%s: enter", __func__);
3659 out_standby(&stream->common);
3660 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
3661 destroy_offload_callback_thread(out);
3662
3663 if (out->compr_config.codec != NULL)
3664 free(out->compr_config.codec);
3665 }
3666 pthread_cond_destroy(&out->cond);
3667 pthread_mutex_destroy(&out->lock);
3668 free(stream);
3669 ALOGV("%s: exit", __func__);
3670}
3671
3672static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
3673{
3674 struct audio_device *adev = (struct audio_device *)dev;
3675 struct str_parms *parms;
3676 char *str;
3677 char value[32];
3678 int val;
3679 int ret;
3680
3681 ALOGV("%s: enter: %s", __func__, kvpairs);
3682
3683 parms = str_parms_create_str(kvpairs);
3684 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_TTY_MODE, value, sizeof(value));
3685 if (ret >= 0) {
3686 int tty_mode;
3687
3688 if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_OFF) == 0)
3689 tty_mode = TTY_MODE_OFF;
3690 else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_VCO) == 0)
3691 tty_mode = TTY_MODE_VCO;
3692 else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_HCO) == 0)
3693 tty_mode = TTY_MODE_HCO;
3694 else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_FULL) == 0)
3695 tty_mode = TTY_MODE_FULL;
3696 else
3697 return -EINVAL;
3698
3699 pthread_mutex_lock(&adev->lock);
3700 if (tty_mode != adev->tty_mode) {
3701 adev->tty_mode = tty_mode;
3702 if (adev->in_call)
3703 select_devices(adev, USECASE_VOICE_CALL);
3704 }
3705 pthread_mutex_unlock(&adev->lock);
3706 }
3707
3708 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
3709 if (ret >= 0) {
3710 /* When set to false, HAL should disable EC and NS
3711 * But it is currently not supported.
3712 */
3713 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
3714 adev->bluetooth_nrec = true;
3715 else
3716 adev->bluetooth_nrec = false;
3717 }
3718
3719 ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
3720 if (ret >= 0) {
3721 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
3722 adev->screen_off = false;
3723 else
3724 adev->screen_off = true;
3725 }
3726
3727 ret = str_parms_get_int(parms, "rotation", &val);
3728 if (ret >= 0) {
3729 bool reverse_speakers = false;
3730 switch(val) {
3731 /* FIXME: note that the code below assumes that the speakers are in the correct placement
3732 relative to the user when the device is rotated 90deg from its default rotation. This
3733 assumption is device-specific, not platform-specific like this code. */
3734 case 270:
3735 reverse_speakers = true;
3736 break;
3737 case 0:
3738 case 90:
3739 case 180:
3740 break;
3741 default:
3742 ALOGE("%s: unexpected rotation of %d", __func__, val);
3743 }
3744 pthread_mutex_lock(&adev->lock);
3745 if (adev->speaker_lr_swap != reverse_speakers) {
3746 adev->speaker_lr_swap = reverse_speakers;
3747 /* only update the selected device if there is active pcm playback */
3748 struct audio_usecase *usecase;
3749 struct listnode *node;
3750 list_for_each(node, &adev->usecase_list) {
3751 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
3752 if (usecase->type == PCM_PLAYBACK) {
3753 select_devices(adev, usecase->id);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003754 break;
3755 }
3756 }
3757 }
3758 pthread_mutex_unlock(&adev->lock);
3759 }
3760
3761 str_parms_destroy(parms);
3762
3763 if (ret > 0)
3764 ret = 0;
3765
3766 ALOGV("%s: exit with code(%d)", __func__, ret);
3767 return ret;
3768}
3769
3770static char* adev_get_parameters(const struct audio_hw_device *dev,
3771 const char *keys)
3772{
3773 (void)dev;
3774 (void)keys;
3775
3776 return strdup("");
3777}
3778
3779static int adev_init_check(const struct audio_hw_device *dev)
3780{
3781 (void)dev;
3782
3783 return 0;
3784}
3785
3786static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
3787{
3788 int ret = 0;
3789 struct audio_device *adev = (struct audio_device *)dev;
3790 pthread_mutex_lock(&adev->lock);
3791 /* cache volume */
3792 adev->voice_volume = volume;
3793 ret = set_voice_volume_l(adev, adev->voice_volume);
3794 pthread_mutex_unlock(&adev->lock);
3795 return ret;
3796}
3797
3798static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
3799{
3800 (void)dev;
3801 (void)volume;
3802
3803 return -ENOSYS;
3804}
3805
3806static int adev_get_master_volume(struct audio_hw_device *dev,
3807 float *volume)
3808{
3809 (void)dev;
3810 (void)volume;
3811
3812 return -ENOSYS;
3813}
3814
3815static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
3816{
3817 (void)dev;
3818 (void)muted;
3819
3820 return -ENOSYS;
3821}
3822
3823static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
3824{
3825 (void)dev;
3826 (void)muted;
3827
3828 return -ENOSYS;
3829}
3830
3831static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
3832{
3833 struct audio_device *adev = (struct audio_device *)dev;
3834
3835 pthread_mutex_lock(&adev->lock);
3836 if (adev->mode != mode) {
3837 ALOGI("%s mode = %d", __func__, mode);
3838 adev->mode = mode;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003839 }
3840 pthread_mutex_unlock(&adev->lock);
3841 return 0;
3842}
3843
3844static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
3845{
3846 struct audio_device *adev = (struct audio_device *)dev;
3847 int err = 0;
3848
3849 pthread_mutex_lock(&adev->lock);
3850 adev->mic_mute = state;
3851
3852 if (adev->mode == AUDIO_MODE_IN_CALL) {
3853 /* TODO */
3854 }
3855
3856 pthread_mutex_unlock(&adev->lock);
3857 return err;
3858}
3859
3860static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
3861{
3862 struct audio_device *adev = (struct audio_device *)dev;
3863
3864 *state = adev->mic_mute;
3865
3866 return 0;
3867}
3868
3869static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
3870 const struct audio_config *config)
3871{
3872 (void)dev;
3873
3874 /* NOTE: we default to built in mic which may cause a mismatch between what we
3875 * report here and the actual buffer size
3876 */
3877 return get_input_buffer_size(config->sample_rate,
3878 config->format,
3879 audio_channel_count_from_in_mask(config->channel_mask),
3880 PCM_CAPTURE /* usecase_type */,
3881 AUDIO_DEVICE_IN_BUILTIN_MIC);
3882}
3883
3884static int adev_open_input_stream(struct audio_hw_device *dev,
3885 audio_io_handle_t handle __unused,
3886 audio_devices_t devices,
3887 struct audio_config *config,
3888 struct audio_stream_in **stream_in,
3889 audio_input_flags_t flags,
3890 const char *address __unused,
3891 audio_source_t source)
3892{
3893 struct audio_device *adev = (struct audio_device *)dev;
3894 struct stream_in *in;
3895 struct pcm_device_profile *pcm_profile;
3896
3897 ALOGV("%s: enter", __func__);
3898
3899 *stream_in = NULL;
3900 if (check_input_parameters(config->sample_rate, config->format,
3901 audio_channel_count_from_in_mask(config->channel_mask)) != 0)
3902 return -EINVAL;
3903
3904 usecase_type_t usecase_type = source == AUDIO_SOURCE_HOTWORD ?
3905 PCM_HOTWORD_STREAMING : flags & AUDIO_INPUT_FLAG_FAST ?
3906 PCM_CAPTURE_LOW_LATENCY : PCM_CAPTURE;
3907 pcm_profile = get_pcm_device(usecase_type, devices);
3908 if (pcm_profile == NULL && usecase_type == PCM_CAPTURE_LOW_LATENCY) {
3909 // a low latency profile may not exist for that device, fall back
3910 // to regular capture. the MixerThread automatically changes
3911 // to non-fast capture based on the buffer size.
3912 flags &= ~AUDIO_INPUT_FLAG_FAST;
3913 usecase_type = PCM_CAPTURE;
3914 pcm_profile = get_pcm_device(usecase_type, devices);
3915 }
3916 if (pcm_profile == NULL)
3917 return -EINVAL;
3918
3919 in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
3920
3921 in->stream.common.get_sample_rate = in_get_sample_rate;
3922 in->stream.common.set_sample_rate = in_set_sample_rate;
3923 in->stream.common.get_buffer_size = in_get_buffer_size;
3924 in->stream.common.get_channels = in_get_channels;
3925 in->stream.common.get_format = in_get_format;
3926 in->stream.common.set_format = in_set_format;
3927 in->stream.common.standby = in_standby;
3928 in->stream.common.dump = in_dump;
3929 in->stream.common.set_parameters = in_set_parameters;
3930 in->stream.common.get_parameters = in_get_parameters;
3931 in->stream.common.add_audio_effect = in_add_audio_effect;
3932 in->stream.common.remove_audio_effect = in_remove_audio_effect;
3933 in->stream.set_gain = in_set_gain;
3934 in->stream.read = in_read;
3935 in->stream.get_input_frames_lost = in_get_input_frames_lost;
3936
3937 in->devices = devices;
3938 in->source = source;
3939 in->dev = adev;
3940 in->standby = 1;
3941 in->main_channels = config->channel_mask;
3942 in->requested_rate = config->sample_rate;
3943 if (config->sample_rate != CAPTURE_DEFAULT_SAMPLING_RATE)
3944 flags = flags & ~AUDIO_INPUT_FLAG_FAST;
3945 in->input_flags = flags;
3946 /* HW codec is limited to default channels. No need to update with
3947 * requested channels */
3948 in->config = pcm_profile->config;
3949
3950 /* Update config params with the requested sample rate and channels */
3951 if (source == AUDIO_SOURCE_HOTWORD) {
3952 in->usecase = USECASE_AUDIO_CAPTURE_HOTWORD;
3953 } else {
3954 in->usecase = USECASE_AUDIO_CAPTURE;
3955 }
3956 in->usecase_type = usecase_type;
3957
3958 pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
3959 pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL);
3960
3961 in->is_fastcapture_affinity_set = false;
3962
3963 *stream_in = &in->stream;
3964 ALOGV("%s: exit", __func__);
3965 return 0;
3966}
3967
3968static void adev_close_input_stream(struct audio_hw_device *dev,
3969 struct audio_stream_in *stream)
3970{
3971 struct audio_device *adev = (struct audio_device *)dev;
3972 struct stream_in *in = (struct stream_in*)stream;
3973 ALOGV("%s", __func__);
3974
3975 /* prevent concurrent out_set_parameters, or out_write from standby */
3976 pthread_mutex_lock(&adev->lock_inputs);
3977
3978#ifdef PREPROCESSING_ENABLED
3979 int i;
3980
3981 for (i=0; i<in->num_preprocessors; i++) {
3982 free(in->preprocessors[i].channel_configs);
3983 }
3984
3985 if (in->read_buf) {
3986 free(in->read_buf);
3987 in->read_buf = NULL;
3988 }
3989
3990 if (in->proc_buf_in) {
3991 free(in->proc_buf_in);
3992 in->proc_buf_in = NULL;
3993 }
3994
3995 if (in->proc_buf_out) {
3996 free(in->proc_buf_out);
3997 in->proc_buf_out = NULL;
3998 }
3999
4000 if (in->ref_buf) {
4001 free(in->ref_buf);
4002 in->ref_buf = NULL;
4003 }
4004
4005 if (in->resampler) {
4006 release_resampler(in->resampler);
4007 in->resampler = NULL;
4008 }
4009#endif
4010
4011 in_standby_l(in);
4012 free(stream);
4013
4014 pthread_mutex_unlock(&adev->lock_inputs);
4015
4016 return;
4017}
4018
4019static int adev_dump(const audio_hw_device_t *device, int fd)
4020{
4021 (void)device;
4022 (void)fd;
4023
4024 return 0;
4025}
4026
4027static int adev_close(hw_device_t *device)
4028{
4029 struct audio_device *adev = (struct audio_device *)device;
4030 audio_device_ref_count--;
4031 free(adev->snd_dev_ref_cnt);
4032 free_mixer_list(adev);
4033 free(device);
4034 return 0;
4035}
4036
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004037/* This returns true if the input parameter looks at all plausible as a low latency period size,
4038 * or false otherwise. A return value of true doesn't mean the value is guaranteed to work,
4039 * just that it _might_ work.
4040 */
4041static bool period_size_is_plausible_for_low_latency(int period_size)
4042{
4043 switch (period_size) {
4044 case 64:
4045 case 96:
4046 case 128:
4047 case 192:
4048 case 256:
4049 return true;
4050 default:
4051 return false;
4052 }
4053}
4054
4055static int adev_open(const hw_module_t *module, const char *name,
4056 hw_device_t **device)
4057{
4058 struct audio_device *adev;
4059 int retry_count = 0;
4060
4061 ALOGV("%s: enter", __func__);
4062 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
4063
4064 adev = calloc(1, sizeof(struct audio_device));
4065
4066 adev->device.common.tag = HARDWARE_DEVICE_TAG;
4067 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
4068 adev->device.common.module = (struct hw_module_t *)module;
4069 adev->device.common.close = adev_close;
4070
4071 adev->device.init_check = adev_init_check;
4072 adev->device.set_voice_volume = adev_set_voice_volume;
4073 adev->device.set_master_volume = adev_set_master_volume;
4074 adev->device.get_master_volume = adev_get_master_volume;
4075 adev->device.set_master_mute = adev_set_master_mute;
4076 adev->device.get_master_mute = adev_get_master_mute;
4077 adev->device.set_mode = adev_set_mode;
4078 adev->device.set_mic_mute = adev_set_mic_mute;
4079 adev->device.get_mic_mute = adev_get_mic_mute;
4080 adev->device.set_parameters = adev_set_parameters;
4081 adev->device.get_parameters = adev_get_parameters;
4082 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
4083 adev->device.open_output_stream = adev_open_output_stream;
4084 adev->device.close_output_stream = adev_close_output_stream;
4085 adev->device.open_input_stream = adev_open_input_stream;
4086 adev->device.close_input_stream = adev_close_input_stream;
4087 adev->device.dump = adev_dump;
4088
4089 /* Set the default route before the PCM stream is opened */
4090 adev->mode = AUDIO_MODE_NORMAL;
4091 adev->active_input = NULL;
4092 adev->primary_output = NULL;
4093 adev->voice_volume = 1.0f;
4094 adev->tty_mode = TTY_MODE_OFF;
4095 adev->bluetooth_nrec = true;
4096 adev->in_call = false;
4097 /* adev->cur_hdmi_channels = 0; by calloc() */
4098 adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
4099
4100 adev->dualmic_config = DUALMIC_CONFIG_NONE;
4101 adev->ns_in_voice_rec = false;
4102
4103 list_init(&adev->usecase_list);
4104
4105 if (mixer_init(adev) != 0) {
4106 free(adev->snd_dev_ref_cnt);
4107 free(adev);
4108 ALOGE("%s: Failed to init, aborting.", __func__);
4109 *device = NULL;
4110 return -EINVAL;
4111 }
4112
4113 if (access(OFFLOAD_FX_LIBRARY_PATH, R_OK) == 0) {
4114 adev->offload_fx_lib = dlopen(OFFLOAD_FX_LIBRARY_PATH, RTLD_NOW);
4115 if (adev->offload_fx_lib == NULL) {
4116 ALOGE("%s: DLOPEN failed for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4117 } else {
4118 ALOGV("%s: DLOPEN successful for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4119 adev->offload_fx_start_output =
4120 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4121 "visualizer_hal_start_output");
4122 adev->offload_fx_stop_output =
4123 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4124 "visualizer_hal_stop_output");
4125 }
4126 }
4127
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004128 if (access(SOUND_TRIGGER_HAL_LIBRARY_PATH, R_OK) == 0) {
4129 adev->sound_trigger_lib = dlopen(SOUND_TRIGGER_HAL_LIBRARY_PATH, RTLD_NOW);
4130 if (adev->sound_trigger_lib == NULL) {
4131 ALOGE("%s: DLOPEN failed for %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4132 } else {
4133 ALOGV("%s: DLOPEN successful for %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4134 adev->sound_trigger_open_for_streaming =
4135 (int (*)(void))dlsym(adev->sound_trigger_lib,
4136 "sound_trigger_open_for_streaming");
4137 adev->sound_trigger_read_samples =
4138 (size_t (*)(int, void *, size_t))dlsym(adev->sound_trigger_lib,
4139 "sound_trigger_read_samples");
4140 adev->sound_trigger_close_for_streaming =
4141 (int (*)(int))dlsym(adev->sound_trigger_lib,
4142 "sound_trigger_close_for_streaming");
4143 if (!adev->sound_trigger_open_for_streaming ||
4144 !adev->sound_trigger_read_samples ||
4145 !adev->sound_trigger_close_for_streaming) {
4146
4147 ALOGE("%s: Error grabbing functions in %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4148 adev->sound_trigger_open_for_streaming = 0;
4149 adev->sound_trigger_read_samples = 0;
4150 adev->sound_trigger_close_for_streaming = 0;
4151 }
4152 }
4153 }
4154
4155
4156 *device = &adev->device.common;
4157
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004158 audio_device_ref_count++;
4159
4160 char value[PROPERTY_VALUE_MAX];
4161 if (property_get("audio_hal.period_size", value, NULL) > 0) {
4162 int trial = atoi(value);
4163 if (period_size_is_plausible_for_low_latency(trial)) {
4164
4165 pcm_device_playback.config.period_size = trial;
4166 pcm_device_playback.config.start_threshold =
4167 PLAYBACK_START_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4168 pcm_device_playback.config.stop_threshold =
4169 PLAYBACK_STOP_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4170
4171 pcm_device_capture_low_latency.config.period_size = trial;
4172 }
4173 }
4174
4175 ALOGV("%s: exit", __func__);
4176 return 0;
4177}
4178
4179static struct hw_module_methods_t hal_module_methods = {
4180 .open = adev_open,
4181};
4182
4183struct audio_module HAL_MODULE_INFO_SYM = {
4184 .common = {
4185 .tag = HARDWARE_MODULE_TAG,
4186 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
4187 .hal_api_version = HARDWARE_HAL_API_VERSION,
4188 .id = AUDIO_HARDWARE_MODULE_ID,
Christopher N. Hessec8502b92017-01-28 14:02:15 +01004189 .name = "Samsung Audio HAL",
4190 .author = "The LineageOS Project",
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004191 .methods = &hal_module_methods,
4192 },
4193};