blob: 2bd2eca42cf2052cc2192bdc3031a6e9b3bf4e0b [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. Hesse297a6362017-01-28 12:40:45 +01003438 }
3439 return bytes;
3440}
3441
3442static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
3443{
3444 (void)stream;
3445
3446 return 0;
3447}
3448
3449static int add_remove_audio_effect(const struct audio_stream *stream,
3450 effect_handle_t effect,
3451 bool enable)
3452{
3453 struct stream_in *in = (struct stream_in *)stream;
3454 struct audio_device *adev = in->dev;
3455 int status = 0;
3456 effect_descriptor_t desc;
3457#ifdef PREPROCESSING_ENABLED
3458 int i;
3459#endif
3460 status = (*effect)->get_descriptor(effect, &desc);
3461 if (status != 0)
3462 return status;
3463
3464 ALOGI("add_remove_audio_effect(), effect type: %08x, enable: %d ", desc.type.timeLow, enable);
3465
3466 pthread_mutex_lock(&adev->lock_inputs);
3467 lock_input_stream(in);
3468 pthread_mutex_lock(&in->dev->lock);
3469#ifndef PREPROCESSING_ENABLED
3470 if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) &&
3471 in->enable_aec != enable &&
3472 (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0)) {
3473 in->enable_aec = enable;
3474 if (!in->standby)
3475 select_devices(in->dev, in->usecase);
3476 }
3477#else
3478 if ( (in->num_preprocessors > MAX_PREPROCESSORS) && (enable == true) ) {
3479 status = -ENOSYS;
3480 goto exit;
3481 }
3482 if ( enable == true ) {
3483 in->preprocessors[in->num_preprocessors].effect_itfe = effect;
3484 /* add the supported channel of the effect in the channel_configs */
3485 in_read_audio_effect_channel_configs(in, &in->preprocessors[in->num_preprocessors]);
3486 in->num_preprocessors ++;
3487 /* check compatibility between main channel supported and possible auxiliary channels */
3488 in_update_aux_channels(in, effect);//wesley crash
3489 in->aux_channels_changed = true;
3490 } else {
3491 /* if ( enable == false ) */
3492 if (in->num_preprocessors <= 0) {
3493 status = -ENOSYS;
3494 goto exit;
3495 }
3496 status = -EINVAL;
3497 for (i=0; i < in->num_preprocessors; i++) {
3498 if (status == 0) { /* status == 0 means an effect was removed from a previous slot */
3499 in->preprocessors[i - 1].effect_itfe = in->preprocessors[i].effect_itfe;
3500 in->preprocessors[i - 1].channel_configs = in->preprocessors[i].channel_configs;
3501 in->preprocessors[i - 1].num_channel_configs =
3502 in->preprocessors[i].num_channel_configs;
3503 ALOGV("add_remove_audio_effect moving fx from %d to %d", i, i-1);
3504 continue;
3505 }
3506 if ( in->preprocessors[i].effect_itfe == effect ) {
3507 ALOGV("add_remove_audio_effect found fx at index %d", i);
3508 free(in->preprocessors[i].channel_configs);
3509 status = 0;
3510 }
3511 }
3512 if (status != 0)
3513 goto exit;
3514 in->num_preprocessors--;
3515 /* if we remove one effect, at least the last proproc should be reset */
3516 in->preprocessors[in->num_preprocessors].num_channel_configs = 0;
3517 in->preprocessors[in->num_preprocessors].effect_itfe = NULL;
3518 in->preprocessors[in->num_preprocessors].channel_configs = NULL;
3519 in->aux_channels_changed = false;
3520 ALOGV("%s: enable(%d), in->aux_channels_changed(%d)", __func__, enable, in->aux_channels_changed);
3521 }
3522 ALOGI("%s: num_preprocessors = %d", __func__, in->num_preprocessors);
3523
3524 if ( memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
3525 in->enable_aec = enable;
3526 ALOGV("add_remove_audio_effect(), FX_IID_AEC, enable: %d", enable);
3527 if (!in->standby) {
3528 select_devices(in->dev, in->usecase);
3529 do_in_standby_l(in);
3530 }
3531 if (in->enable_aec == true) {
3532 in_configure_reverse(in);
3533 }
3534 }
3535exit:
3536#endif
3537 ALOGW_IF(status != 0, "add_remove_audio_effect() error %d", status);
3538 pthread_mutex_unlock(&in->dev->lock);
3539 pthread_mutex_unlock(&in->lock);
3540 pthread_mutex_unlock(&adev->lock_inputs);
3541 return status;
3542}
3543
3544static int in_add_audio_effect(const struct audio_stream *stream,
3545 effect_handle_t effect)
3546{
3547 ALOGV("%s: effect %p", __func__, effect);
3548 return add_remove_audio_effect(stream, effect, true);
3549}
3550
3551static int in_remove_audio_effect(const struct audio_stream *stream,
3552 effect_handle_t effect)
3553{
3554 ALOGV("%s: effect %p", __func__, effect);
3555 return add_remove_audio_effect(stream, effect, false);
3556}
3557
3558static int adev_open_output_stream(struct audio_hw_device *dev,
3559 audio_io_handle_t handle,
3560 audio_devices_t devices,
3561 audio_output_flags_t flags,
3562 struct audio_config *config,
3563 struct audio_stream_out **stream_out,
3564 const char *address __unused)
3565{
3566 struct audio_device *adev = (struct audio_device *)dev;
3567 struct stream_out *out;
3568 int i, ret;
3569 struct pcm_device_profile *pcm_profile;
3570
3571 ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
3572 __func__, config->sample_rate, config->channel_mask, devices, flags);
3573 *stream_out = NULL;
3574 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
3575
3576 if (devices == AUDIO_DEVICE_NONE)
3577 devices = AUDIO_DEVICE_OUT_SPEAKER;
3578
3579 out->flags = flags;
3580 out->devices = devices;
3581 out->dev = adev;
3582 out->format = config->format;
3583 out->sample_rate = config->sample_rate;
3584 out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3585 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
3586 out->handle = handle;
3587
3588 pcm_profile = get_pcm_device(PCM_PLAYBACK, devices);
3589 if (pcm_profile == NULL) {
3590 ret = -EINVAL;
3591 goto error_open;
3592 }
3593 out->config = pcm_profile->config;
3594
3595 /* Init use case and pcm_config */
3596 if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
3597 if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version ||
3598 config->offload_info.size != AUDIO_INFO_INITIALIZER.size) {
3599 ALOGE("%s: Unsupported Offload information", __func__);
3600 ret = -EINVAL;
3601 goto error_open;
3602 }
3603 if (!is_supported_format(config->offload_info.format)) {
3604 ALOGE("%s: Unsupported audio format", __func__);
3605 ret = -EINVAL;
3606 goto error_open;
3607 }
3608
3609 out->compr_config.codec = (struct snd_codec *)
3610 calloc(1, sizeof(struct snd_codec));
3611
3612 out->usecase = USECASE_AUDIO_PLAYBACK_OFFLOAD;
3613 if (config->offload_info.channel_mask)
3614 out->channel_mask = config->offload_info.channel_mask;
3615 else if (config->channel_mask)
3616 out->channel_mask = config->channel_mask;
3617 out->format = config->offload_info.format;
3618 out->sample_rate = config->offload_info.sample_rate;
3619
3620 out->stream.set_callback = out_set_callback;
3621 out->stream.pause = out_pause;
3622 out->stream.resume = out_resume;
3623 out->stream.drain = out_drain;
3624 out->stream.flush = out_flush;
3625
3626 out->compr_config.codec->id =
3627 get_snd_codec_id(config->offload_info.format);
3628 out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
3629 out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
3630 out->compr_config.codec->sample_rate = config->offload_info.sample_rate;
3631 out->compr_config.codec->bit_rate =
3632 config->offload_info.bit_rate;
3633 out->compr_config.codec->ch_in =
3634 audio_channel_count_from_out_mask(config->channel_mask);
3635 out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
3636
3637 if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
3638 out->non_blocking = 1;
3639
3640 out->send_new_metadata = 1;
3641 create_offload_callback_thread(out);
3642 out->offload_state = OFFLOAD_STATE_IDLE;
3643
3644 ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
3645 __func__, config->offload_info.version,
3646 config->offload_info.bit_rate);
3647 } else if (out->flags & (AUDIO_OUTPUT_FLAG_DEEP_BUFFER)) {
3648 out->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01003649 out->config = pcm_device_deep_buffer.config;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003650 out->sample_rate = out->config.rate;
3651 ALOGV("%s: use AUDIO_PLAYBACK_DEEP_BUFFER",__func__);
3652 } else {
3653 out->usecase = USECASE_AUDIO_PLAYBACK;
3654 out->sample_rate = out->config.rate;
3655 }
3656
3657 if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
3658 if (adev->primary_output == NULL)
3659 adev->primary_output = out;
3660 else {
3661 ALOGE("%s: Primary output is already opened", __func__);
3662 ret = -EEXIST;
3663 goto error_open;
3664 }
3665 }
3666
3667 /* Check if this usecase is already existing */
3668 pthread_mutex_lock(&adev->lock);
3669 if (get_usecase_from_id(adev, out->usecase) != NULL) {
3670 ALOGE("%s: Usecase (%d) is already present", __func__, out->usecase);
3671 pthread_mutex_unlock(&adev->lock);
3672 ret = -EEXIST;
3673 goto error_open;
3674 }
3675 pthread_mutex_unlock(&adev->lock);
3676
3677 out->stream.common.get_sample_rate = out_get_sample_rate;
3678 out->stream.common.set_sample_rate = out_set_sample_rate;
3679 out->stream.common.get_buffer_size = out_get_buffer_size;
3680 out->stream.common.get_channels = out_get_channels;
3681 out->stream.common.get_format = out_get_format;
3682 out->stream.common.set_format = out_set_format;
3683 out->stream.common.standby = out_standby;
3684 out->stream.common.dump = out_dump;
3685 out->stream.common.set_parameters = out_set_parameters;
3686 out->stream.common.get_parameters = out_get_parameters;
3687 out->stream.common.add_audio_effect = out_add_audio_effect;
3688 out->stream.common.remove_audio_effect = out_remove_audio_effect;
3689 out->stream.get_latency = out_get_latency;
3690 out->stream.set_volume = out_set_volume;
3691 out->stream.write = out_write;
3692 out->stream.get_render_position = out_get_render_position;
3693 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
3694 out->stream.get_presentation_position = out_get_presentation_position;
3695
3696 out->standby = 1;
3697 /* out->muted = false; by calloc() */
3698 /* out->written = 0; by calloc() */
3699
3700 pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
3701 pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
3702 pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
3703
3704 config->format = out->stream.common.get_format(&out->stream.common);
3705 config->channel_mask = out->stream.common.get_channels(&out->stream.common);
3706 config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
3707
3708 out->is_fastmixer_affinity_set = false;
3709
3710 *stream_out = &out->stream;
3711 ALOGV("%s: exit", __func__);
3712 return 0;
3713
3714error_open:
3715 free(out);
3716 *stream_out = NULL;
3717 ALOGV("%s: exit: ret %d", __func__, ret);
3718 return ret;
3719}
3720
3721static void adev_close_output_stream(struct audio_hw_device *dev,
3722 struct audio_stream_out *stream)
3723{
3724 struct stream_out *out = (struct stream_out *)stream;
3725 struct audio_device *adev = out->dev;
3726 (void)dev;
3727
3728 ALOGV("%s: enter", __func__);
3729 out_standby(&stream->common);
3730 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
3731 destroy_offload_callback_thread(out);
3732
3733 if (out->compr_config.codec != NULL)
3734 free(out->compr_config.codec);
3735 }
3736 pthread_cond_destroy(&out->cond);
3737 pthread_mutex_destroy(&out->lock);
3738 free(stream);
3739 ALOGV("%s: exit", __func__);
3740}
3741
3742static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
3743{
3744 struct audio_device *adev = (struct audio_device *)dev;
3745 struct str_parms *parms;
3746 char *str;
3747 char value[32];
3748 int val;
3749 int ret;
3750
3751 ALOGV("%s: enter: %s", __func__, kvpairs);
3752
3753 parms = str_parms_create_str(kvpairs);
3754 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_TTY_MODE, value, sizeof(value));
3755 if (ret >= 0) {
3756 int tty_mode;
3757
3758 if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_OFF) == 0)
3759 tty_mode = TTY_MODE_OFF;
3760 else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_VCO) == 0)
3761 tty_mode = TTY_MODE_VCO;
3762 else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_HCO) == 0)
3763 tty_mode = TTY_MODE_HCO;
3764 else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_FULL) == 0)
3765 tty_mode = TTY_MODE_FULL;
3766 else
3767 return -EINVAL;
3768
3769 pthread_mutex_lock(&adev->lock);
3770 if (tty_mode != adev->tty_mode) {
3771 adev->tty_mode = tty_mode;
3772 if (adev->in_call)
3773 select_devices(adev, USECASE_VOICE_CALL);
3774 }
3775 pthread_mutex_unlock(&adev->lock);
3776 }
3777
3778 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
3779 if (ret >= 0) {
3780 /* When set to false, HAL should disable EC and NS
3781 * But it is currently not supported.
3782 */
3783 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
3784 adev->bluetooth_nrec = true;
3785 else
3786 adev->bluetooth_nrec = false;
3787 }
3788
3789 ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
3790 if (ret >= 0) {
3791 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
3792 adev->screen_off = false;
3793 else
3794 adev->screen_off = true;
3795 }
3796
3797 ret = str_parms_get_int(parms, "rotation", &val);
3798 if (ret >= 0) {
3799 bool reverse_speakers = false;
3800 switch(val) {
3801 /* FIXME: note that the code below assumes that the speakers are in the correct placement
3802 relative to the user when the device is rotated 90deg from its default rotation. This
3803 assumption is device-specific, not platform-specific like this code. */
3804 case 270:
3805 reverse_speakers = true;
3806 break;
3807 case 0:
3808 case 90:
3809 case 180:
3810 break;
3811 default:
3812 ALOGE("%s: unexpected rotation of %d", __func__, val);
3813 }
3814 pthread_mutex_lock(&adev->lock);
3815 if (adev->speaker_lr_swap != reverse_speakers) {
3816 adev->speaker_lr_swap = reverse_speakers;
3817 /* only update the selected device if there is active pcm playback */
3818 struct audio_usecase *usecase;
3819 struct listnode *node;
3820 list_for_each(node, &adev->usecase_list) {
3821 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
3822 if (usecase->type == PCM_PLAYBACK) {
3823 select_devices(adev, usecase->id);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003824 break;
3825 }
3826 }
3827 }
3828 pthread_mutex_unlock(&adev->lock);
3829 }
3830
3831 str_parms_destroy(parms);
3832
3833 if (ret > 0)
3834 ret = 0;
3835
3836 ALOGV("%s: exit with code(%d)", __func__, ret);
3837 return ret;
3838}
3839
3840static char* adev_get_parameters(const struct audio_hw_device *dev,
3841 const char *keys)
3842{
3843 (void)dev;
3844 (void)keys;
3845
3846 return strdup("");
3847}
3848
3849static int adev_init_check(const struct audio_hw_device *dev)
3850{
3851 (void)dev;
3852
3853 return 0;
3854}
3855
3856static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
3857{
3858 int ret = 0;
3859 struct audio_device *adev = (struct audio_device *)dev;
3860 pthread_mutex_lock(&adev->lock);
3861 /* cache volume */
3862 adev->voice_volume = volume;
3863 ret = set_voice_volume_l(adev, adev->voice_volume);
3864 pthread_mutex_unlock(&adev->lock);
3865 return ret;
3866}
3867
3868static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
3869{
3870 (void)dev;
3871 (void)volume;
3872
3873 return -ENOSYS;
3874}
3875
3876static int adev_get_master_volume(struct audio_hw_device *dev,
3877 float *volume)
3878{
3879 (void)dev;
3880 (void)volume;
3881
3882 return -ENOSYS;
3883}
3884
3885static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
3886{
3887 (void)dev;
3888 (void)muted;
3889
3890 return -ENOSYS;
3891}
3892
3893static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
3894{
3895 (void)dev;
3896 (void)muted;
3897
3898 return -ENOSYS;
3899}
3900
3901static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
3902{
3903 struct audio_device *adev = (struct audio_device *)dev;
3904
3905 pthread_mutex_lock(&adev->lock);
3906 if (adev->mode != mode) {
3907 ALOGI("%s mode = %d", __func__, mode);
3908 adev->mode = mode;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003909 }
3910 pthread_mutex_unlock(&adev->lock);
3911 return 0;
3912}
3913
3914static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
3915{
3916 struct audio_device *adev = (struct audio_device *)dev;
3917 int err = 0;
3918
3919 pthread_mutex_lock(&adev->lock);
3920 adev->mic_mute = state;
3921
3922 if (adev->mode == AUDIO_MODE_IN_CALL) {
3923 /* TODO */
3924 }
3925
3926 pthread_mutex_unlock(&adev->lock);
3927 return err;
3928}
3929
3930static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
3931{
3932 struct audio_device *adev = (struct audio_device *)dev;
3933
3934 *state = adev->mic_mute;
3935
3936 return 0;
3937}
3938
3939static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
3940 const struct audio_config *config)
3941{
3942 (void)dev;
3943
3944 /* NOTE: we default to built in mic which may cause a mismatch between what we
3945 * report here and the actual buffer size
3946 */
3947 return get_input_buffer_size(config->sample_rate,
3948 config->format,
3949 audio_channel_count_from_in_mask(config->channel_mask),
3950 PCM_CAPTURE /* usecase_type */,
3951 AUDIO_DEVICE_IN_BUILTIN_MIC);
3952}
3953
3954static int adev_open_input_stream(struct audio_hw_device *dev,
3955 audio_io_handle_t handle __unused,
3956 audio_devices_t devices,
3957 struct audio_config *config,
3958 struct audio_stream_in **stream_in,
3959 audio_input_flags_t flags,
3960 const char *address __unused,
3961 audio_source_t source)
3962{
3963 struct audio_device *adev = (struct audio_device *)dev;
3964 struct stream_in *in;
3965 struct pcm_device_profile *pcm_profile;
3966
3967 ALOGV("%s: enter", __func__);
3968
3969 *stream_in = NULL;
3970 if (check_input_parameters(config->sample_rate, config->format,
3971 audio_channel_count_from_in_mask(config->channel_mask)) != 0)
3972 return -EINVAL;
3973
3974 usecase_type_t usecase_type = source == AUDIO_SOURCE_HOTWORD ?
3975 PCM_HOTWORD_STREAMING : flags & AUDIO_INPUT_FLAG_FAST ?
3976 PCM_CAPTURE_LOW_LATENCY : PCM_CAPTURE;
3977 pcm_profile = get_pcm_device(usecase_type, devices);
3978 if (pcm_profile == NULL && usecase_type == PCM_CAPTURE_LOW_LATENCY) {
3979 // a low latency profile may not exist for that device, fall back
3980 // to regular capture. the MixerThread automatically changes
3981 // to non-fast capture based on the buffer size.
3982 flags &= ~AUDIO_INPUT_FLAG_FAST;
3983 usecase_type = PCM_CAPTURE;
3984 pcm_profile = get_pcm_device(usecase_type, devices);
3985 }
3986 if (pcm_profile == NULL)
3987 return -EINVAL;
3988
3989 in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
3990
3991 in->stream.common.get_sample_rate = in_get_sample_rate;
3992 in->stream.common.set_sample_rate = in_set_sample_rate;
3993 in->stream.common.get_buffer_size = in_get_buffer_size;
3994 in->stream.common.get_channels = in_get_channels;
3995 in->stream.common.get_format = in_get_format;
3996 in->stream.common.set_format = in_set_format;
3997 in->stream.common.standby = in_standby;
3998 in->stream.common.dump = in_dump;
3999 in->stream.common.set_parameters = in_set_parameters;
4000 in->stream.common.get_parameters = in_get_parameters;
4001 in->stream.common.add_audio_effect = in_add_audio_effect;
4002 in->stream.common.remove_audio_effect = in_remove_audio_effect;
4003 in->stream.set_gain = in_set_gain;
4004 in->stream.read = in_read;
4005 in->stream.get_input_frames_lost = in_get_input_frames_lost;
4006
4007 in->devices = devices;
4008 in->source = source;
4009 in->dev = adev;
4010 in->standby = 1;
4011 in->main_channels = config->channel_mask;
4012 in->requested_rate = config->sample_rate;
4013 if (config->sample_rate != CAPTURE_DEFAULT_SAMPLING_RATE)
4014 flags = flags & ~AUDIO_INPUT_FLAG_FAST;
4015 in->input_flags = flags;
4016 /* HW codec is limited to default channels. No need to update with
4017 * requested channels */
4018 in->config = pcm_profile->config;
4019
4020 /* Update config params with the requested sample rate and channels */
4021 if (source == AUDIO_SOURCE_HOTWORD) {
4022 in->usecase = USECASE_AUDIO_CAPTURE_HOTWORD;
4023 } else {
4024 in->usecase = USECASE_AUDIO_CAPTURE;
4025 }
4026 in->usecase_type = usecase_type;
4027
4028 pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
4029 pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL);
4030
4031 in->is_fastcapture_affinity_set = false;
4032
4033 *stream_in = &in->stream;
4034 ALOGV("%s: exit", __func__);
4035 return 0;
4036}
4037
4038static void adev_close_input_stream(struct audio_hw_device *dev,
4039 struct audio_stream_in *stream)
4040{
4041 struct audio_device *adev = (struct audio_device *)dev;
4042 struct stream_in *in = (struct stream_in*)stream;
4043 ALOGV("%s", __func__);
4044
4045 /* prevent concurrent out_set_parameters, or out_write from standby */
4046 pthread_mutex_lock(&adev->lock_inputs);
4047
Andreas Schneidercabe5e62017-01-30 10:57:06 +01004048 if (in->read_buf) {
4049 free(in->read_buf);
4050 in->read_buf = NULL;
4051 }
4052
4053 if (in->resampler) {
4054 release_resampler(in->resampler);
4055 in->resampler = NULL;
4056 }
4057
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004058#ifdef PREPROCESSING_ENABLED
4059 int i;
4060
4061 for (i=0; i<in->num_preprocessors; i++) {
4062 free(in->preprocessors[i].channel_configs);
4063 }
4064
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004065 if (in->proc_buf_in) {
4066 free(in->proc_buf_in);
4067 in->proc_buf_in = NULL;
4068 }
4069
4070 if (in->proc_buf_out) {
4071 free(in->proc_buf_out);
4072 in->proc_buf_out = NULL;
4073 }
4074
4075 if (in->ref_buf) {
4076 free(in->ref_buf);
4077 in->ref_buf = NULL;
4078 }
4079
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004080#endif
4081
4082 in_standby_l(in);
4083 free(stream);
4084
4085 pthread_mutex_unlock(&adev->lock_inputs);
4086
4087 return;
4088}
4089
4090static int adev_dump(const audio_hw_device_t *device, int fd)
4091{
4092 (void)device;
4093 (void)fd;
4094
4095 return 0;
4096}
4097
4098static int adev_close(hw_device_t *device)
4099{
4100 struct audio_device *adev = (struct audio_device *)device;
4101 audio_device_ref_count--;
4102 free(adev->snd_dev_ref_cnt);
4103 free_mixer_list(adev);
4104 free(device);
4105 return 0;
4106}
4107
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004108/* This returns true if the input parameter looks at all plausible as a low latency period size,
4109 * or false otherwise. A return value of true doesn't mean the value is guaranteed to work,
4110 * just that it _might_ work.
4111 */
4112static bool period_size_is_plausible_for_low_latency(int period_size)
4113{
4114 switch (period_size) {
4115 case 64:
4116 case 96:
4117 case 128:
4118 case 192:
4119 case 256:
4120 return true;
4121 default:
4122 return false;
4123 }
4124}
4125
4126static int adev_open(const hw_module_t *module, const char *name,
4127 hw_device_t **device)
4128{
4129 struct audio_device *adev;
4130 int retry_count = 0;
4131
4132 ALOGV("%s: enter", __func__);
4133 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
4134
4135 adev = calloc(1, sizeof(struct audio_device));
4136
4137 adev->device.common.tag = HARDWARE_DEVICE_TAG;
4138 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
4139 adev->device.common.module = (struct hw_module_t *)module;
4140 adev->device.common.close = adev_close;
4141
4142 adev->device.init_check = adev_init_check;
4143 adev->device.set_voice_volume = adev_set_voice_volume;
4144 adev->device.set_master_volume = adev_set_master_volume;
4145 adev->device.get_master_volume = adev_get_master_volume;
4146 adev->device.set_master_mute = adev_set_master_mute;
4147 adev->device.get_master_mute = adev_get_master_mute;
4148 adev->device.set_mode = adev_set_mode;
4149 adev->device.set_mic_mute = adev_set_mic_mute;
4150 adev->device.get_mic_mute = adev_get_mic_mute;
4151 adev->device.set_parameters = adev_set_parameters;
4152 adev->device.get_parameters = adev_get_parameters;
4153 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
4154 adev->device.open_output_stream = adev_open_output_stream;
4155 adev->device.close_output_stream = adev_close_output_stream;
4156 adev->device.open_input_stream = adev_open_input_stream;
4157 adev->device.close_input_stream = adev_close_input_stream;
4158 adev->device.dump = adev_dump;
4159
4160 /* Set the default route before the PCM stream is opened */
4161 adev->mode = AUDIO_MODE_NORMAL;
4162 adev->active_input = NULL;
4163 adev->primary_output = NULL;
4164 adev->voice_volume = 1.0f;
4165 adev->tty_mode = TTY_MODE_OFF;
4166 adev->bluetooth_nrec = true;
4167 adev->in_call = false;
4168 /* adev->cur_hdmi_channels = 0; by calloc() */
4169 adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
4170
4171 adev->dualmic_config = DUALMIC_CONFIG_NONE;
4172 adev->ns_in_voice_rec = false;
4173
4174 list_init(&adev->usecase_list);
4175
4176 if (mixer_init(adev) != 0) {
4177 free(adev->snd_dev_ref_cnt);
4178 free(adev);
4179 ALOGE("%s: Failed to init, aborting.", __func__);
4180 *device = NULL;
4181 return -EINVAL;
4182 }
4183
4184 if (access(OFFLOAD_FX_LIBRARY_PATH, R_OK) == 0) {
4185 adev->offload_fx_lib = dlopen(OFFLOAD_FX_LIBRARY_PATH, RTLD_NOW);
4186 if (adev->offload_fx_lib == NULL) {
4187 ALOGE("%s: DLOPEN failed for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4188 } else {
4189 ALOGV("%s: DLOPEN successful for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4190 adev->offload_fx_start_output =
4191 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4192 "visualizer_hal_start_output");
4193 adev->offload_fx_stop_output =
4194 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4195 "visualizer_hal_stop_output");
4196 }
4197 }
4198
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004199 if (access(SOUND_TRIGGER_HAL_LIBRARY_PATH, R_OK) == 0) {
4200 adev->sound_trigger_lib = dlopen(SOUND_TRIGGER_HAL_LIBRARY_PATH, RTLD_NOW);
4201 if (adev->sound_trigger_lib == NULL) {
4202 ALOGE("%s: DLOPEN failed for %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4203 } else {
4204 ALOGV("%s: DLOPEN successful for %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4205 adev->sound_trigger_open_for_streaming =
4206 (int (*)(void))dlsym(adev->sound_trigger_lib,
4207 "sound_trigger_open_for_streaming");
4208 adev->sound_trigger_read_samples =
4209 (size_t (*)(int, void *, size_t))dlsym(adev->sound_trigger_lib,
4210 "sound_trigger_read_samples");
4211 adev->sound_trigger_close_for_streaming =
4212 (int (*)(int))dlsym(adev->sound_trigger_lib,
4213 "sound_trigger_close_for_streaming");
4214 if (!adev->sound_trigger_open_for_streaming ||
4215 !adev->sound_trigger_read_samples ||
4216 !adev->sound_trigger_close_for_streaming) {
4217
4218 ALOGE("%s: Error grabbing functions in %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4219 adev->sound_trigger_open_for_streaming = 0;
4220 adev->sound_trigger_read_samples = 0;
4221 adev->sound_trigger_close_for_streaming = 0;
4222 }
4223 }
4224 }
4225
4226
4227 *device = &adev->device.common;
4228
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004229 audio_device_ref_count++;
4230
4231 char value[PROPERTY_VALUE_MAX];
4232 if (property_get("audio_hal.period_size", value, NULL) > 0) {
4233 int trial = atoi(value);
4234 if (period_size_is_plausible_for_low_latency(trial)) {
4235
4236 pcm_device_playback.config.period_size = trial;
4237 pcm_device_playback.config.start_threshold =
4238 PLAYBACK_START_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4239 pcm_device_playback.config.stop_threshold =
4240 PLAYBACK_STOP_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4241
4242 pcm_device_capture_low_latency.config.period_size = trial;
4243 }
4244 }
4245
4246 ALOGV("%s: exit", __func__);
4247 return 0;
4248}
4249
4250static struct hw_module_methods_t hal_module_methods = {
4251 .open = adev_open,
4252};
4253
4254struct audio_module HAL_MODULE_INFO_SYM = {
4255 .common = {
4256 .tag = HARDWARE_MODULE_TAG,
4257 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
4258 .hal_api_version = HARDWARE_HAL_API_VERSION,
4259 .id = AUDIO_HARDWARE_MODULE_ID,
Christopher N. Hessec8502b92017-01-28 14:02:15 +01004260 .name = "Samsung Audio HAL",
4261 .author = "The LineageOS Project",
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004262 .methods = &hal_module_methods,
4263 },
4264};