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