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