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