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