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