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