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