blob: 3d80f7b614bf3cc2233fa1dd3f07105c8cd6ddfe [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 */
874 if (adev->in_call) {
875 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__);
2406 adev->in_call = false;
2407
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 */
2459 set_voice_volume_l(adev, adev->voice_volume);
2460
2461 adev->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
2696 if ((adev->mode == AUDIO_MODE_IN_CALL) && !adev->in_call &&
2697 (out == adev->primary_output)) {
2698 start_voice_call(adev);
2699 } else if ((adev->mode == AUDIO_MODE_IN_CALL) && adev->in_call &&
2700 (out == adev->primary_output)) {
2701 select_devices(adev, USECASE_VOICE_CALL);
2702 }
2703 }
2704
2705 if ((adev->mode == AUDIO_MODE_NORMAL) && adev->in_call &&
2706 (out == adev->primary_output)) {
2707 stop_voice_call(adev);
2708 }
2709 pthread_mutex_unlock(&adev->lock);
2710 pthread_mutex_unlock(&out->lock);
2711#ifdef PREPROCESSING_ENABLED
2712 if (in) {
2713 /* The lock on adev->lock_inputs prevents input stream from being closed */
2714 lock_input_stream(in);
2715 pthread_mutex_lock(&adev->lock);
2716 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
2717 do_in_standby_l(in);
2718 pthread_mutex_unlock(&adev->lock);
2719 pthread_mutex_unlock(&in->lock);
2720 }
2721#endif
2722 pthread_mutex_unlock(&adev->lock_inputs);
2723 }
2724
2725 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2726 parse_compress_metadata(out, parms);
2727 }
2728
2729 str_parms_destroy(parms);
2730
2731 if (ret > 0)
2732 ret = 0;
2733 ALOGV("%s: exit: code(%d)", __func__, ret);
2734 return ret;
2735}
2736
2737static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
2738{
2739 struct stream_out *out = (struct stream_out *)stream;
2740 struct str_parms *query = str_parms_create_str(keys);
2741 char *str;
2742 char value[256];
2743 struct str_parms *reply = str_parms_create();
2744 size_t i, j;
2745 int ret;
2746 bool first = true;
2747 ALOGV("%s: enter: keys - %s", __func__, keys);
2748 ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value));
2749 if (ret >= 0) {
2750 value[0] = '\0';
2751 i = 0;
2752 while (out->supported_channel_masks[i] != 0) {
2753 for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) {
2754 if (out_channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) {
2755 if (!first) {
2756 strcat(value, "|");
2757 }
2758 strcat(value, out_channels_name_to_enum_table[j].name);
2759 first = false;
2760 break;
2761 }
2762 }
2763 i++;
2764 }
2765 str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
2766 str = str_parms_to_str(reply);
2767 } else {
2768 str = strdup(keys);
2769 }
2770 str_parms_destroy(query);
2771 str_parms_destroy(reply);
2772 ALOGV("%s: exit: returns - %s", __func__, str);
2773 return str;
2774}
2775
2776static uint32_t out_get_latency(const struct audio_stream_out *stream)
2777{
2778 struct stream_out *out = (struct stream_out *)stream;
2779
2780 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
2781 return COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
2782
2783 return (out->config.period_count * out->config.period_size * 1000) /
2784 (out->config.rate);
2785}
2786
2787static int out_set_volume(struct audio_stream_out *stream, float left,
2788 float right)
2789{
2790 struct stream_out *out = (struct stream_out *)stream;
2791 struct audio_device *adev = out->dev;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002792
2793 if (out->usecase == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
2794 /* only take left channel into account: the API is for stereo anyway */
2795 out->muted = (left == 0.0f);
2796 return 0;
2797 } else if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002798 out_set_offload_volume(left, right);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002799 }
2800
2801 return -ENOSYS;
2802}
2803
Andreas Schneider3b643832017-01-31 11:48:22 +01002804#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002805static int fast_set_affinity(pid_t tid) {
2806 cpu_set_t cpu_set;
2807 int cpu_num;
2808 const char *irq_procfs = "/proc/asound/irq_affinity";
2809 FILE *fp;
2810
2811 if ((fp = fopen(irq_procfs, "r")) == NULL) {
2812 ALOGW("Procfs node %s not found", irq_procfs);
2813 return -1;
2814 }
2815
2816 if (fscanf(fp, "%d", &cpu_num) != 1) {
2817 ALOGW("Couldn't read CPU id from procfs node %s", irq_procfs);
2818 fclose(fp);
2819 return -1;
2820 }
2821 fclose(fp);
2822
2823 CPU_ZERO(&cpu_set);
2824 CPU_SET(cpu_num, &cpu_set);
2825 return sched_setaffinity(tid, sizeof(cpu_set), &cpu_set);
2826}
Andreas Schneider3b643832017-01-31 11:48:22 +01002827#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002828
2829static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
2830 size_t bytes)
2831{
2832 struct stream_out *out = (struct stream_out *)stream;
2833 struct audio_device *adev = out->dev;
2834 ssize_t ret = 0;
2835 struct pcm_device *pcm_device;
2836 struct listnode *node;
2837 size_t frame_size = audio_stream_out_frame_size(stream);
2838 size_t frames_wr = 0, frames_rq = 0;
2839 unsigned char *data = NULL;
2840 struct pcm_config config;
2841#ifdef PREPROCESSING_ENABLED
2842 size_t in_frames = bytes / frame_size;
2843 size_t out_frames = in_frames;
2844 struct stream_in *in = NULL;
2845#endif
2846 pid_t tid;
2847 int err;
2848
2849 lock_output_stream(out);
2850
Andreas Schneider3b643832017-01-31 11:48:22 +01002851#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002852 if (out->usecase == USECASE_AUDIO_PLAYBACK && !out->is_fastmixer_affinity_set) {
2853 tid = gettid();
2854 err = fast_set_affinity(tid);
2855 if (err < 0) {
2856 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
2857 }
2858 out->is_fastmixer_affinity_set = true;
2859 }
Andreas Schneider3b643832017-01-31 11:48:22 +01002860#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002861
2862 if (out->standby) {
2863#ifdef PREPROCESSING_ENABLED
2864 pthread_mutex_unlock(&out->lock);
2865 /* Prevent input stream from being closed */
2866 pthread_mutex_lock(&adev->lock_inputs);
2867 lock_output_stream(out);
2868 if (!out->standby) {
2869 pthread_mutex_unlock(&adev->lock_inputs);
2870 goto false_alarm;
2871 }
2872#endif
2873 pthread_mutex_lock(&adev->lock);
2874 ret = start_output_stream(out);
2875 /* ToDo: If use case is compress offload should return 0 */
2876 if (ret != 0) {
2877 pthread_mutex_unlock(&adev->lock);
2878#ifdef PREPROCESSING_ENABLED
2879 pthread_mutex_unlock(&adev->lock_inputs);
2880#endif
2881 goto exit;
2882 }
2883 out->standby = false;
2884
2885#ifdef PREPROCESSING_ENABLED
2886 /* A change in output device may change the microphone selection */
2887 if (adev->active_input &&
2888 (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
2889 adev->active_input->source == AUDIO_SOURCE_MIC)) {
2890 in = adev->active_input;
2891 ALOGV("%s: enter:) force_input_standby true", __func__);
2892 }
2893#endif
2894 pthread_mutex_unlock(&adev->lock);
2895#ifdef PREPROCESSING_ENABLED
2896 if (!in) {
2897 /* Leave mutex locked iff in != NULL */
2898 pthread_mutex_unlock(&adev->lock_inputs);
2899 }
2900#endif
2901 }
2902false_alarm:
2903
2904 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002905 ret = out_write_offload(stream, buffer, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002906 return ret;
2907 } else {
2908#ifdef PREPROCESSING_ENABLED
2909 if (android_atomic_acquire_load(&adev->echo_reference_generation)
2910 != out->echo_reference_generation) {
2911 pthread_mutex_lock(&adev->lock);
2912 if (out->echo_reference != NULL) {
2913 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
2914 release_echo_reference(out->echo_reference);
2915 }
2916 // note that adev->echo_reference_generation here can be different from the one
2917 // tested above but it doesn't matter as we now have the adev mutex and it is consistent
2918 // with what has been set by get_echo_reference() or put_echo_reference()
2919 out->echo_reference_generation = adev->echo_reference_generation;
2920 out->echo_reference = adev->echo_reference;
2921 ALOGV("%s: update echo reference generation %d", __func__,
2922 out->echo_reference_generation);
2923 pthread_mutex_unlock(&adev->lock);
2924 }
2925#endif
2926
2927 if (out->muted)
2928 memset((void *)buffer, 0, bytes);
2929 list_for_each(node, &out->pcm_dev_list) {
2930 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2931 if (pcm_device->resampler) {
2932 if (bytes * pcm_device->pcm_profile->config.rate / out->sample_rate + frame_size
2933 > pcm_device->res_byte_count) {
2934 pcm_device->res_byte_count =
2935 bytes * pcm_device->pcm_profile->config.rate / out->sample_rate + frame_size;
2936 pcm_device->res_buffer =
2937 realloc(pcm_device->res_buffer, pcm_device->res_byte_count);
2938 ALOGV("%s: resampler res_byte_count = %zu", __func__,
2939 pcm_device->res_byte_count);
2940 }
2941 frames_rq = bytes / frame_size;
2942 frames_wr = pcm_device->res_byte_count / frame_size;
2943 ALOGVV("%s: resampler request frames = %d frame_size = %d",
2944 __func__, frames_rq, frame_size);
2945 pcm_device->resampler->resample_from_input(pcm_device->resampler,
2946 (int16_t *)buffer, &frames_rq, (int16_t *)pcm_device->res_buffer, &frames_wr);
2947 ALOGVV("%s: resampler output frames_= %d", __func__, frames_wr);
2948 }
2949 if (pcm_device->pcm) {
2950#ifdef PREPROCESSING_ENABLED
2951 if (out->echo_reference != NULL && pcm_device->pcm_profile->devices != SND_DEVICE_OUT_SPEAKER) {
2952 struct echo_reference_buffer b;
2953 b.raw = (void *)buffer;
2954 b.frame_count = in_frames;
2955
2956 get_playback_delay(out, out_frames, &b);
2957 out->echo_reference->write(out->echo_reference, &b);
2958 }
2959#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002960 ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
2961 if (pcm_device->resampler && pcm_device->res_buffer)
2962 pcm_device->status =
2963 pcm_write(pcm_device->pcm, (void *)pcm_device->res_buffer,
2964 frames_wr * frame_size);
2965 else
2966 pcm_device->status = pcm_write(pcm_device->pcm, (void *)buffer, bytes);
2967 if (pcm_device->status != 0)
2968 ret = pcm_device->status;
2969 }
2970 }
2971 if (ret == 0)
2972 out->written += bytes / (out->config.channels * sizeof(short));
2973 }
2974
2975exit:
2976 pthread_mutex_unlock(&out->lock);
2977
2978 if (ret != 0) {
2979 list_for_each(node, &out->pcm_dev_list) {
2980 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2981 if (pcm_device->pcm && pcm_device->status != 0)
2982 ALOGE("%s: error %zd - %s", __func__, ret, pcm_get_error(pcm_device->pcm));
2983 }
2984 out_standby(&out->stream.common);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01002985 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
2986 clock_gettime(CLOCK_MONOTONIC, &t);
2987 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
2988 const int64_t elapsed_time_since_last_write = now - out->last_write_time_us;
2989 int64_t sleep_time = bytes * 1000000LL / audio_stream_out_frame_size(stream) /
2990 out_get_sample_rate(&stream->common) - elapsed_time_since_last_write;
2991 if (sleep_time > 0) {
2992 usleep(sleep_time);
2993 } else {
2994 // we don't sleep when we exit standby (this is typical for a real alsa buffer).
2995 sleep_time = 0;
2996 }
2997 out->last_write_time_us = now + sleep_time;
2998 // last_write_time_us is an approximation of when the (simulated) alsa
2999 // buffer is believed completely full. The usleep above waits for more space
3000 // in the buffer, but by the end of the sleep the buffer is considered
3001 // topped-off.
3002 //
3003 // On the subsequent out_write(), we measure the elapsed time spent in
3004 // the mixer. This is subtracted from the sleep estimate based on frames,
3005 // thereby accounting for drain in the alsa buffer during mixing.
3006 // This is a crude approximation; we don't handle underruns precisely.
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003007 }
3008
3009#ifdef PREPROCESSING_ENABLED
3010 if (in) {
3011 /* The lock on adev->lock_inputs prevents input stream from being closed */
3012 lock_input_stream(in);
3013 pthread_mutex_lock(&adev->lock);
3014 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
3015 do_in_standby_l(in);
3016 pthread_mutex_unlock(&adev->lock);
3017 pthread_mutex_unlock(&in->lock);
3018 /* This mutex was left locked iff in != NULL */
3019 pthread_mutex_unlock(&adev->lock_inputs);
3020 }
3021#endif
3022
3023 return bytes;
3024}
3025
3026static int out_get_render_position(const struct audio_stream_out *stream,
3027 uint32_t *dsp_frames)
3028{
3029 struct stream_out *out = (struct stream_out *)stream;
3030 *dsp_frames = 0;
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003031 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
3032 return out_get_render_offload_position(out, dsp_frames);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003033 } else
3034 return -EINVAL;
3035}
3036
3037static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3038{
3039 (void)stream;
3040 (void)effect;
3041 return 0;
3042}
3043
3044static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3045{
3046 (void)stream;
3047 (void)effect;
3048 return 0;
3049}
3050
3051static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
3052 int64_t *timestamp)
3053{
3054 (void)stream;
3055 (void)timestamp;
3056 return -EINVAL;
3057}
3058
3059static int out_get_presentation_position(const struct audio_stream_out *stream,
3060 uint64_t *frames, struct timespec *timestamp)
3061{
3062 struct stream_out *out = (struct stream_out *)stream;
3063 int ret = -1;
3064 unsigned long dsp_frames;
3065
3066 lock_output_stream(out);
3067
3068 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003069 ret = out_get_presentation_offload_position(out, frames, timestamp);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003070 } else {
3071 /* FIXME: which device to read from? */
3072 if (!list_empty(&out->pcm_dev_list)) {
3073 unsigned int avail;
3074 struct pcm_device *pcm_device = node_to_item(list_head(&out->pcm_dev_list),
3075 struct pcm_device, stream_list_node);
3076
3077 if (pcm_get_htimestamp(pcm_device->pcm, &avail, timestamp) == 0) {
3078 size_t kernel_buffer_size = out->config.period_size * out->config.period_count;
3079 int64_t signed_frames = out->written - kernel_buffer_size + avail;
3080 /* This adjustment accounts for buffering after app processor.
3081 It is based on estimated DSP latency per use case, rather than exact. */
3082 signed_frames -=
3083 (render_latency(out->usecase) * out->sample_rate / 1000000LL);
3084
3085 /* It would be unusual for this value to be negative, but check just in case ... */
3086 if (signed_frames >= 0) {
3087 *frames = signed_frames;
3088 ret = 0;
3089 }
3090 }
3091 }
3092 }
3093
3094 pthread_mutex_unlock(&out->lock);
3095
3096 return ret;
3097}
3098
3099static int out_set_callback(struct audio_stream_out *stream,
3100 stream_callback_t callback, void *cookie)
3101{
3102 struct stream_out *out = (struct stream_out *)stream;
3103
3104 ALOGV("%s", __func__);
3105 lock_output_stream(out);
3106 out->offload_callback = callback;
3107 out->offload_cookie = cookie;
3108 pthread_mutex_unlock(&out->lock);
3109 return 0;
3110}
3111
3112static int out_pause(struct audio_stream_out* stream)
3113{
3114 struct stream_out *out = (struct stream_out *)stream;
3115 int status = -ENOSYS;
3116 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003117 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3118 status = out_pause_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003119 return status;
3120}
3121
3122static int out_resume(struct audio_stream_out* stream)
3123{
3124 struct stream_out *out = (struct stream_out *)stream;
3125 int status = -ENOSYS;
3126 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003127 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3128 status = out_resume_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003129 return status;
3130}
3131
3132static int out_drain(struct audio_stream_out* stream, audio_drain_type_t type )
3133{
3134 struct stream_out *out = (struct stream_out *)stream;
3135 int status = -ENOSYS;
3136 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003137 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3138 status = out_drain_offload(out, type);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003139 return status;
3140}
3141
3142static int out_flush(struct audio_stream_out* stream)
3143{
3144 struct stream_out *out = (struct stream_out *)stream;
3145 ALOGV("%s", __func__);
3146 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003147 return out_flush_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003148 }
3149 return -ENOSYS;
3150}
3151
3152/** audio_stream_in implementation **/
3153static uint32_t in_get_sample_rate(const struct audio_stream *stream)
3154{
3155 struct stream_in *in = (struct stream_in *)stream;
3156
3157 return in->requested_rate;
3158}
3159
3160static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
3161{
3162 (void)stream;
3163 (void)rate;
3164 return -ENOSYS;
3165}
3166
3167static uint32_t in_get_channels(const struct audio_stream *stream)
3168{
3169 struct stream_in *in = (struct stream_in *)stream;
3170
3171 return in->main_channels;
3172}
3173
3174static audio_format_t in_get_format(const struct audio_stream *stream)
3175{
3176 (void)stream;
3177 return AUDIO_FORMAT_PCM_16_BIT;
3178}
3179
3180static int in_set_format(struct audio_stream *stream, audio_format_t format)
3181{
3182 (void)stream;
3183 (void)format;
3184
3185 return -ENOSYS;
3186}
3187
3188static size_t in_get_buffer_size(const struct audio_stream *stream)
3189{
3190 struct stream_in *in = (struct stream_in *)stream;
3191
3192 return get_input_buffer_size(in->requested_rate,
3193 in_get_format(stream),
3194 audio_channel_count_from_in_mask(in->main_channels),
3195 in->usecase_type,
3196 in->devices);
3197}
3198
3199static int in_close_pcm_devices(struct stream_in *in)
3200{
3201 struct pcm_device *pcm_device;
3202 struct listnode *node;
3203 struct audio_device *adev = in->dev;
3204
3205 list_for_each(node, &in->pcm_dev_list) {
3206 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3207 if (pcm_device) {
3208 if (pcm_device->pcm)
3209 pcm_close(pcm_device->pcm);
3210 pcm_device->pcm = NULL;
3211 if (pcm_device->sound_trigger_handle > 0)
3212 adev->sound_trigger_close_for_streaming(pcm_device->sound_trigger_handle);
3213 pcm_device->sound_trigger_handle = 0;
3214 }
3215 }
3216 return 0;
3217}
3218
3219
3220/* must be called with stream and hw device mutex locked */
3221static int do_in_standby_l(struct stream_in *in)
3222{
3223 int status = 0;
3224
3225#ifdef PREPROCESSING_ENABLED
3226 struct audio_device *adev = in->dev;
3227#endif
3228 if (!in->standby) {
3229
3230 in_close_pcm_devices(in);
3231
3232#ifdef PREPROCESSING_ENABLED
3233 if (in->echo_reference != NULL) {
3234 /* stop reading from echo reference */
3235 in->echo_reference->read(in->echo_reference, NULL);
3236 put_echo_reference(adev, in->echo_reference);
3237 in->echo_reference = NULL;
3238 }
3239#ifdef HW_AEC_LOOPBACK
3240 if (in->hw_echo_reference)
3241 {
3242 if (in->hw_ref_buf) {
3243 free(in->hw_ref_buf);
3244 in->hw_ref_buf = NULL;
3245 }
3246 }
3247#endif // HW_AEC_LOOPBACK
3248#endif // PREPROCESSING_ENABLED
3249
3250 status = stop_input_stream(in);
3251
3252 if (in->read_buf) {
3253 free(in->read_buf);
3254 in->read_buf = NULL;
3255 }
3256
3257 in->standby = 1;
3258 }
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003259
3260 in->last_read_time_us = 0;
3261
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003262 return 0;
3263}
3264
3265// called with adev->lock_inputs locked
3266static int in_standby_l(struct stream_in *in)
3267{
3268 struct audio_device *adev = in->dev;
3269 int status = 0;
3270 lock_input_stream(in);
3271 if (!in->standby) {
3272 pthread_mutex_lock(&adev->lock);
3273 status = do_in_standby_l(in);
3274 pthread_mutex_unlock(&adev->lock);
3275 }
3276 pthread_mutex_unlock(&in->lock);
3277 return status;
3278}
3279
3280static int in_standby(struct audio_stream *stream)
3281{
3282 struct stream_in *in = (struct stream_in *)stream;
3283 struct audio_device *adev = in->dev;
3284 int status;
3285 ALOGV("%s: enter", __func__);
3286 pthread_mutex_lock(&adev->lock_inputs);
3287 status = in_standby_l(in);
3288 pthread_mutex_unlock(&adev->lock_inputs);
3289 ALOGV("%s: exit: status(%d)", __func__, status);
3290 return status;
3291}
3292
3293static int in_dump(const struct audio_stream *stream, int fd)
3294{
3295 (void)stream;
3296 (void)fd;
3297
3298 return 0;
3299}
3300
3301static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
3302{
3303 struct stream_in *in = (struct stream_in *)stream;
3304 struct audio_device *adev = in->dev;
3305 struct str_parms *parms;
3306 char *str;
3307 char value[32];
3308 int ret, val = 0;
3309 struct audio_usecase *uc_info;
3310 bool do_standby = false;
3311 struct listnode *node;
3312 struct pcm_device *pcm_device;
3313 struct pcm_device_profile *pcm_profile;
3314
3315 ALOGV("%s: enter: kvpairs=%s", __func__, kvpairs);
3316 parms = str_parms_create_str(kvpairs);
3317
3318 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
3319
3320 pthread_mutex_lock(&adev->lock_inputs);
3321 lock_input_stream(in);
3322 pthread_mutex_lock(&adev->lock);
3323 if (ret >= 0) {
3324 val = atoi(value);
3325 /* no audio source uses val == 0 */
3326 if (((int)in->source != val) && (val != 0)) {
3327 in->source = val;
3328 }
3329 }
3330
3331 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
3332 if (ret >= 0) {
3333 val = atoi(value);
3334 if (((int)in->devices != val) && (val != 0)) {
3335 in->devices = val;
3336 /* If recording is in progress, change the tx device to new device */
3337 if (!in->standby) {
3338 uc_info = get_usecase_from_id(adev, in->usecase);
3339 if (uc_info == NULL) {
3340 ALOGE("%s: Could not find the usecase (%d) in the list",
3341 __func__, in->usecase);
3342 } else {
3343 if (list_empty(&in->pcm_dev_list))
3344 ALOGE("%s: pcm device list empty", __func__);
3345 else {
3346 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3347 struct pcm_device, stream_list_node);
3348 if ((pcm_device->pcm_profile->devices & val & ~AUDIO_DEVICE_BIT_IN) == 0) {
3349 do_standby = true;
3350 }
3351 }
3352 }
3353 if (do_standby) {
3354 ret = do_in_standby_l(in);
3355 } else
3356 ret = select_devices(adev, in->usecase);
3357 }
3358 }
3359 }
3360 pthread_mutex_unlock(&adev->lock);
3361 pthread_mutex_unlock(&in->lock);
3362 pthread_mutex_unlock(&adev->lock_inputs);
3363 str_parms_destroy(parms);
3364
3365 if (ret > 0)
3366 ret = 0;
3367
3368 ALOGV("%s: exit: status(%d)", __func__, ret);
3369 return ret;
3370}
3371
3372static char* in_get_parameters(const struct audio_stream *stream,
3373 const char *keys)
3374{
3375 (void)stream;
3376 (void)keys;
3377
3378 return strdup("");
3379}
3380
3381static int in_set_gain(struct audio_stream_in *stream, float gain)
3382{
3383 (void)stream;
3384 (void)gain;
3385
3386 return 0;
3387}
3388
3389static ssize_t read_bytes_from_dsp(struct stream_in *in, void* buffer,
3390 size_t bytes)
3391{
3392 struct pcm_device *pcm_device;
3393 struct audio_device *adev = in->dev;
3394
3395 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3396 struct pcm_device, stream_list_node);
3397
3398 if (pcm_device->sound_trigger_handle > 0)
3399 return adev->sound_trigger_read_samples(pcm_device->sound_trigger_handle, buffer, bytes);
3400 else
3401 return 0;
3402}
3403
3404static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
3405 size_t bytes)
3406{
3407 struct stream_in *in = (struct stream_in *)stream;
3408 struct audio_device *adev = in->dev;
3409 ssize_t frames = -1;
3410 int ret = -1;
3411 int read_and_process_successful = false;
3412
3413 size_t frames_rq = bytes / audio_stream_in_frame_size(stream);
3414 pid_t tid;
3415 int err;
3416
3417 /* no need to acquire adev->lock_inputs because API contract prevents a close */
3418 lock_input_stream(in);
3419
Andreas Schneider3b643832017-01-31 11:48:22 +01003420#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003421 if (in->usecase == USECASE_AUDIO_CAPTURE && !in->is_fastcapture_affinity_set) {
3422 tid = gettid();
3423 err = fast_set_affinity(tid);
3424 if (err < 0) {
3425 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
3426 }
3427 in->is_fastcapture_affinity_set = true;
3428 }
Andreas Schneider3b643832017-01-31 11:48:22 +01003429#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003430
3431 if (in->standby) {
3432 pthread_mutex_unlock(&in->lock);
3433 pthread_mutex_lock(&adev->lock_inputs);
3434 lock_input_stream(in);
3435 if (!in->standby) {
3436 pthread_mutex_unlock(&adev->lock_inputs);
3437 goto false_alarm;
3438 }
3439 pthread_mutex_lock(&adev->lock);
3440 ret = start_input_stream(in);
3441 pthread_mutex_unlock(&adev->lock);
3442 pthread_mutex_unlock(&adev->lock_inputs);
3443 if (ret != 0) {
3444 goto exit;
3445 }
3446 in->standby = 0;
3447 }
3448false_alarm:
3449
3450 if (!list_empty(&in->pcm_dev_list)) {
3451 if (in->usecase == USECASE_AUDIO_CAPTURE_HOTWORD) {
3452 bytes = read_bytes_from_dsp(in, buffer, bytes);
3453 if (bytes > 0)
3454 read_and_process_successful = true;
3455 } else {
3456 /*
3457 * Read PCM and:
3458 * - resample if needed
3459 * - process if pre-processors are attached
3460 * - discard unwanted channels
3461 */
3462 frames = read_and_process_frames(in, buffer, frames_rq);
3463 if (frames >= 0)
3464 read_and_process_successful = true;
3465 }
3466 }
3467
3468 /*
3469 * Instead of writing zeroes here, we could trust the hardware
3470 * to always provide zeroes when muted.
3471 */
3472 if (read_and_process_successful == true && adev->mic_mute)
3473 memset(buffer, 0, bytes);
3474
3475exit:
3476 pthread_mutex_unlock(&in->lock);
3477
3478 if (read_and_process_successful == false) {
3479 in_standby(&in->stream.common);
3480 ALOGV("%s: read failed - sleeping for buffer duration", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003481 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3482 clock_gettime(CLOCK_MONOTONIC, &t);
3483 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3484
3485 // we do a full sleep when exiting standby.
3486 const bool standby = in->last_read_time_us == 0;
3487 const int64_t elapsed_time_since_last_read = standby ?
3488 0 : now - in->last_read_time_us;
3489 int64_t sleep_time = bytes * 1000000LL / audio_stream_in_frame_size(stream) /
3490 in_get_sample_rate(&stream->common) - elapsed_time_since_last_read;
3491 if (sleep_time > 0) {
3492 usleep(sleep_time);
3493 } else {
3494 sleep_time = 0;
3495 }
3496 in->last_read_time_us = now + sleep_time;
3497 // last_read_time_us is an approximation of when the (simulated) alsa
3498 // buffer is drained by the read, and is empty.
3499 //
3500 // On the subsequent in_read(), we measure the elapsed time spent in
3501 // the recording thread. This is subtracted from the sleep estimate based on frames,
3502 // thereby accounting for fill in the alsa buffer during the interim.
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003503 memset(buffer, 0, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003504 }
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003505
3506 if (bytes > 0) {
3507 in->frames_read += bytes / audio_stream_in_frame_size(stream);
3508 }
3509
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003510 return bytes;
3511}
3512
3513static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
3514{
3515 (void)stream;
3516
3517 return 0;
3518}
3519
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003520static int in_get_capture_position(const struct audio_stream_in *stream,
3521 int64_t *frames, int64_t *time)
3522{
3523 if (stream == NULL || frames == NULL || time == NULL) {
3524 return -EINVAL;
3525 }
3526
3527 struct stream_in *in = (struct stream_in *)stream;
3528 struct pcm_device *pcm_device;
3529 int ret = -ENOSYS;
3530
3531 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3532 struct pcm_device, stream_list_node);
3533
3534 pthread_mutex_lock(&in->lock);
3535 if (pcm_device->pcm) {
3536 struct timespec timestamp;
3537 unsigned int avail;
3538 if (pcm_get_htimestamp(pcm_device->pcm, &avail, &timestamp) == 0) {
3539 *frames = in->frames_read + avail;
3540 *time = timestamp.tv_sec * 1000000000LL + timestamp.tv_nsec;
3541 ret = 0;
3542 }
3543 }
3544
3545 pthread_mutex_unlock(&in->lock);
3546 return ret;
3547}
3548
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003549static int add_remove_audio_effect(const struct audio_stream *stream,
3550 effect_handle_t effect,
3551 bool enable)
3552{
3553 struct stream_in *in = (struct stream_in *)stream;
3554 struct audio_device *adev = in->dev;
3555 int status = 0;
3556 effect_descriptor_t desc;
3557#ifdef PREPROCESSING_ENABLED
3558 int i;
3559#endif
3560 status = (*effect)->get_descriptor(effect, &desc);
3561 if (status != 0)
3562 return status;
3563
3564 ALOGI("add_remove_audio_effect(), effect type: %08x, enable: %d ", desc.type.timeLow, enable);
3565
3566 pthread_mutex_lock(&adev->lock_inputs);
3567 lock_input_stream(in);
3568 pthread_mutex_lock(&in->dev->lock);
3569#ifndef PREPROCESSING_ENABLED
3570 if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) &&
3571 in->enable_aec != enable &&
3572 (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0)) {
3573 in->enable_aec = enable;
3574 if (!in->standby)
3575 select_devices(in->dev, in->usecase);
3576 }
3577#else
3578 if ( (in->num_preprocessors > MAX_PREPROCESSORS) && (enable == true) ) {
3579 status = -ENOSYS;
3580 goto exit;
3581 }
3582 if ( enable == true ) {
3583 in->preprocessors[in->num_preprocessors].effect_itfe = effect;
3584 /* add the supported channel of the effect in the channel_configs */
3585 in_read_audio_effect_channel_configs(in, &in->preprocessors[in->num_preprocessors]);
3586 in->num_preprocessors ++;
3587 /* check compatibility between main channel supported and possible auxiliary channels */
3588 in_update_aux_channels(in, effect);//wesley crash
3589 in->aux_channels_changed = true;
3590 } else {
3591 /* if ( enable == false ) */
3592 if (in->num_preprocessors <= 0) {
3593 status = -ENOSYS;
3594 goto exit;
3595 }
3596 status = -EINVAL;
3597 for (i=0; i < in->num_preprocessors; i++) {
3598 if (status == 0) { /* status == 0 means an effect was removed from a previous slot */
3599 in->preprocessors[i - 1].effect_itfe = in->preprocessors[i].effect_itfe;
3600 in->preprocessors[i - 1].channel_configs = in->preprocessors[i].channel_configs;
3601 in->preprocessors[i - 1].num_channel_configs =
3602 in->preprocessors[i].num_channel_configs;
3603 ALOGV("add_remove_audio_effect moving fx from %d to %d", i, i-1);
3604 continue;
3605 }
3606 if ( in->preprocessors[i].effect_itfe == effect ) {
3607 ALOGV("add_remove_audio_effect found fx at index %d", i);
3608 free(in->preprocessors[i].channel_configs);
3609 status = 0;
3610 }
3611 }
3612 if (status != 0)
3613 goto exit;
3614 in->num_preprocessors--;
3615 /* if we remove one effect, at least the last proproc should be reset */
3616 in->preprocessors[in->num_preprocessors].num_channel_configs = 0;
3617 in->preprocessors[in->num_preprocessors].effect_itfe = NULL;
3618 in->preprocessors[in->num_preprocessors].channel_configs = NULL;
3619 in->aux_channels_changed = false;
3620 ALOGV("%s: enable(%d), in->aux_channels_changed(%d)", __func__, enable, in->aux_channels_changed);
3621 }
3622 ALOGI("%s: num_preprocessors = %d", __func__, in->num_preprocessors);
3623
3624 if ( memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
3625 in->enable_aec = enable;
3626 ALOGV("add_remove_audio_effect(), FX_IID_AEC, enable: %d", enable);
3627 if (!in->standby) {
3628 select_devices(in->dev, in->usecase);
3629 do_in_standby_l(in);
3630 }
3631 if (in->enable_aec == true) {
3632 in_configure_reverse(in);
3633 }
3634 }
3635exit:
3636#endif
3637 ALOGW_IF(status != 0, "add_remove_audio_effect() error %d", status);
3638 pthread_mutex_unlock(&in->dev->lock);
3639 pthread_mutex_unlock(&in->lock);
3640 pthread_mutex_unlock(&adev->lock_inputs);
3641 return status;
3642}
3643
3644static int in_add_audio_effect(const struct audio_stream *stream,
3645 effect_handle_t effect)
3646{
3647 ALOGV("%s: effect %p", __func__, effect);
3648 return add_remove_audio_effect(stream, effect, true);
3649}
3650
3651static int in_remove_audio_effect(const struct audio_stream *stream,
3652 effect_handle_t effect)
3653{
3654 ALOGV("%s: effect %p", __func__, effect);
3655 return add_remove_audio_effect(stream, effect, false);
3656}
3657
3658static int adev_open_output_stream(struct audio_hw_device *dev,
3659 audio_io_handle_t handle,
3660 audio_devices_t devices,
3661 audio_output_flags_t flags,
3662 struct audio_config *config,
3663 struct audio_stream_out **stream_out,
3664 const char *address __unused)
3665{
3666 struct audio_device *adev = (struct audio_device *)dev;
3667 struct stream_out *out;
Andreas Schneider56204f62017-01-31 08:17:32 +01003668 int i, ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003669 struct pcm_device_profile *pcm_profile;
3670
3671 ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
3672 __func__, config->sample_rate, config->channel_mask, devices, flags);
3673 *stream_out = NULL;
3674 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
Andreas Schneider56204f62017-01-31 08:17:32 +01003675 if (out == NULL) {
3676 ret = -ENOMEM;
3677 goto error_config;
3678 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003679
3680 if (devices == AUDIO_DEVICE_NONE)
3681 devices = AUDIO_DEVICE_OUT_SPEAKER;
3682
3683 out->flags = flags;
3684 out->devices = devices;
3685 out->dev = adev;
3686 out->format = config->format;
3687 out->sample_rate = config->sample_rate;
3688 out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3689 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
3690 out->handle = handle;
3691
3692 pcm_profile = get_pcm_device(PCM_PLAYBACK, devices);
3693 if (pcm_profile == NULL) {
3694 ret = -EINVAL;
3695 goto error_open;
3696 }
3697 out->config = pcm_profile->config;
3698
3699 /* Init use case and pcm_config */
3700 if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
3701 if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version ||
3702 config->offload_info.size != AUDIO_INFO_INITIALIZER.size) {
3703 ALOGE("%s: Unsupported Offload information", __func__);
3704 ret = -EINVAL;
3705 goto error_open;
3706 }
3707 if (!is_supported_format(config->offload_info.format)) {
3708 ALOGE("%s: Unsupported audio format", __func__);
3709 ret = -EINVAL;
3710 goto error_open;
3711 }
3712
3713 out->compr_config.codec = (struct snd_codec *)
3714 calloc(1, sizeof(struct snd_codec));
Andreas Schneider56204f62017-01-31 08:17:32 +01003715 if (out->compr_config.codec == NULL) {
3716 ret = -ENOMEM;
3717 goto error_open;
3718 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003719
3720 out->usecase = USECASE_AUDIO_PLAYBACK_OFFLOAD;
3721 if (config->offload_info.channel_mask)
3722 out->channel_mask = config->offload_info.channel_mask;
3723 else if (config->channel_mask)
3724 out->channel_mask = config->channel_mask;
3725 out->format = config->offload_info.format;
3726 out->sample_rate = config->offload_info.sample_rate;
3727
3728 out->stream.set_callback = out_set_callback;
3729 out->stream.pause = out_pause;
3730 out->stream.resume = out_resume;
3731 out->stream.drain = out_drain;
3732 out->stream.flush = out_flush;
3733
3734 out->compr_config.codec->id =
3735 get_snd_codec_id(config->offload_info.format);
3736 out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
3737 out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
3738 out->compr_config.codec->sample_rate = config->offload_info.sample_rate;
3739 out->compr_config.codec->bit_rate =
3740 config->offload_info.bit_rate;
3741 out->compr_config.codec->ch_in =
3742 audio_channel_count_from_out_mask(config->channel_mask);
3743 out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
3744
3745 if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
3746 out->non_blocking = 1;
3747
3748 out->send_new_metadata = 1;
3749 create_offload_callback_thread(out);
3750 out->offload_state = OFFLOAD_STATE_IDLE;
3751
3752 ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
3753 __func__, config->offload_info.version,
3754 config->offload_info.bit_rate);
3755 } else if (out->flags & (AUDIO_OUTPUT_FLAG_DEEP_BUFFER)) {
3756 out->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01003757 out->config = pcm_device_deep_buffer.config;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003758 out->sample_rate = out->config.rate;
3759 ALOGV("%s: use AUDIO_PLAYBACK_DEEP_BUFFER",__func__);
3760 } else {
3761 out->usecase = USECASE_AUDIO_PLAYBACK;
3762 out->sample_rate = out->config.rate;
3763 }
3764
3765 if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
3766 if (adev->primary_output == NULL)
3767 adev->primary_output = out;
3768 else {
3769 ALOGE("%s: Primary output is already opened", __func__);
3770 ret = -EEXIST;
3771 goto error_open;
3772 }
3773 }
3774
3775 /* Check if this usecase is already existing */
3776 pthread_mutex_lock(&adev->lock);
3777 if (get_usecase_from_id(adev, out->usecase) != NULL) {
3778 ALOGE("%s: Usecase (%d) is already present", __func__, out->usecase);
3779 pthread_mutex_unlock(&adev->lock);
3780 ret = -EEXIST;
3781 goto error_open;
3782 }
3783 pthread_mutex_unlock(&adev->lock);
3784
3785 out->stream.common.get_sample_rate = out_get_sample_rate;
3786 out->stream.common.set_sample_rate = out_set_sample_rate;
3787 out->stream.common.get_buffer_size = out_get_buffer_size;
3788 out->stream.common.get_channels = out_get_channels;
3789 out->stream.common.get_format = out_get_format;
3790 out->stream.common.set_format = out_set_format;
3791 out->stream.common.standby = out_standby;
3792 out->stream.common.dump = out_dump;
3793 out->stream.common.set_parameters = out_set_parameters;
3794 out->stream.common.get_parameters = out_get_parameters;
3795 out->stream.common.add_audio_effect = out_add_audio_effect;
3796 out->stream.common.remove_audio_effect = out_remove_audio_effect;
3797 out->stream.get_latency = out_get_latency;
3798 out->stream.set_volume = out_set_volume;
3799 out->stream.write = out_write;
3800 out->stream.get_render_position = out_get_render_position;
3801 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
3802 out->stream.get_presentation_position = out_get_presentation_position;
3803
3804 out->standby = 1;
3805 /* out->muted = false; by calloc() */
3806 /* out->written = 0; by calloc() */
3807
3808 pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
3809 pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
3810 pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
3811
3812 config->format = out->stream.common.get_format(&out->stream.common);
3813 config->channel_mask = out->stream.common.get_channels(&out->stream.common);
3814 config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
3815
3816 out->is_fastmixer_affinity_set = false;
3817
3818 *stream_out = &out->stream;
3819 ALOGV("%s: exit", __func__);
3820 return 0;
3821
3822error_open:
3823 free(out);
3824 *stream_out = NULL;
Andreas Schneider56204f62017-01-31 08:17:32 +01003825error_config:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003826 ALOGV("%s: exit: ret %d", __func__, ret);
3827 return ret;
3828}
3829
3830static void adev_close_output_stream(struct audio_hw_device *dev,
3831 struct audio_stream_out *stream)
3832{
3833 struct stream_out *out = (struct stream_out *)stream;
3834 struct audio_device *adev = out->dev;
3835 (void)dev;
3836
3837 ALOGV("%s: enter", __func__);
3838 out_standby(&stream->common);
3839 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
3840 destroy_offload_callback_thread(out);
3841
3842 if (out->compr_config.codec != NULL)
3843 free(out->compr_config.codec);
3844 }
3845 pthread_cond_destroy(&out->cond);
3846 pthread_mutex_destroy(&out->lock);
3847 free(stream);
3848 ALOGV("%s: exit", __func__);
3849}
3850
3851static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
3852{
3853 struct audio_device *adev = (struct audio_device *)dev;
3854 struct str_parms *parms;
3855 char *str;
3856 char value[32];
3857 int val;
3858 int ret;
3859
3860 ALOGV("%s: enter: %s", __func__, kvpairs);
3861
3862 parms = str_parms_create_str(kvpairs);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003863
3864 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
3865 if (ret >= 0) {
3866 /* When set to false, HAL should disable EC and NS
3867 * But it is currently not supported.
3868 */
3869 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
3870 adev->bluetooth_nrec = true;
3871 else
3872 adev->bluetooth_nrec = false;
3873 }
3874
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01003875#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003876 ret = str_parms_get_int(parms, "rotation", &val);
3877 if (ret >= 0) {
3878 bool reverse_speakers = false;
3879 switch(val) {
3880 /* FIXME: note that the code below assumes that the speakers are in the correct placement
3881 relative to the user when the device is rotated 90deg from its default rotation. This
3882 assumption is device-specific, not platform-specific like this code. */
3883 case 270:
3884 reverse_speakers = true;
3885 break;
3886 case 0:
3887 case 90:
3888 case 180:
3889 break;
3890 default:
3891 ALOGE("%s: unexpected rotation of %d", __func__, val);
3892 }
3893 pthread_mutex_lock(&adev->lock);
3894 if (adev->speaker_lr_swap != reverse_speakers) {
3895 adev->speaker_lr_swap = reverse_speakers;
3896 /* only update the selected device if there is active pcm playback */
3897 struct audio_usecase *usecase;
3898 struct listnode *node;
3899 list_for_each(node, &adev->usecase_list) {
3900 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
3901 if (usecase->type == PCM_PLAYBACK) {
3902 select_devices(adev, usecase->id);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003903 break;
3904 }
3905 }
3906 }
3907 pthread_mutex_unlock(&adev->lock);
3908 }
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01003909#endif /* SWAP_SPEAKER_ON_SCREEN_ROTATION */
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003910
3911 str_parms_destroy(parms);
3912
3913 if (ret > 0)
3914 ret = 0;
3915
3916 ALOGV("%s: exit with code(%d)", __func__, ret);
3917 return ret;
3918}
3919
3920static char* adev_get_parameters(const struct audio_hw_device *dev,
3921 const char *keys)
3922{
3923 (void)dev;
3924 (void)keys;
3925
3926 return strdup("");
3927}
3928
3929static int adev_init_check(const struct audio_hw_device *dev)
3930{
3931 (void)dev;
3932
3933 return 0;
3934}
3935
3936static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
3937{
3938 int ret = 0;
3939 struct audio_device *adev = (struct audio_device *)dev;
3940 pthread_mutex_lock(&adev->lock);
3941 /* cache volume */
3942 adev->voice_volume = volume;
3943 ret = set_voice_volume_l(adev, adev->voice_volume);
3944 pthread_mutex_unlock(&adev->lock);
3945 return ret;
3946}
3947
3948static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
3949{
3950 (void)dev;
3951 (void)volume;
3952
3953 return -ENOSYS;
3954}
3955
3956static int adev_get_master_volume(struct audio_hw_device *dev,
3957 float *volume)
3958{
3959 (void)dev;
3960 (void)volume;
3961
3962 return -ENOSYS;
3963}
3964
3965static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
3966{
3967 (void)dev;
3968 (void)muted;
3969
3970 return -ENOSYS;
3971}
3972
3973static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
3974{
3975 (void)dev;
3976 (void)muted;
3977
3978 return -ENOSYS;
3979}
3980
3981static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
3982{
3983 struct audio_device *adev = (struct audio_device *)dev;
3984
3985 pthread_mutex_lock(&adev->lock);
3986 if (adev->mode != mode) {
3987 ALOGI("%s mode = %d", __func__, mode);
3988 adev->mode = mode;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003989 }
3990 pthread_mutex_unlock(&adev->lock);
3991 return 0;
3992}
3993
3994static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
3995{
3996 struct audio_device *adev = (struct audio_device *)dev;
3997 int err = 0;
3998
3999 pthread_mutex_lock(&adev->lock);
4000 adev->mic_mute = state;
4001
4002 if (adev->mode == AUDIO_MODE_IN_CALL) {
4003 /* TODO */
4004 }
4005
4006 pthread_mutex_unlock(&adev->lock);
4007 return err;
4008}
4009
4010static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
4011{
4012 struct audio_device *adev = (struct audio_device *)dev;
4013
4014 *state = adev->mic_mute;
4015
4016 return 0;
4017}
4018
4019static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
4020 const struct audio_config *config)
4021{
4022 (void)dev;
4023
4024 /* NOTE: we default to built in mic which may cause a mismatch between what we
4025 * report here and the actual buffer size
4026 */
4027 return get_input_buffer_size(config->sample_rate,
4028 config->format,
4029 audio_channel_count_from_in_mask(config->channel_mask),
4030 PCM_CAPTURE /* usecase_type */,
4031 AUDIO_DEVICE_IN_BUILTIN_MIC);
4032}
4033
4034static int adev_open_input_stream(struct audio_hw_device *dev,
4035 audio_io_handle_t handle __unused,
4036 audio_devices_t devices,
4037 struct audio_config *config,
4038 struct audio_stream_in **stream_in,
4039 audio_input_flags_t flags,
4040 const char *address __unused,
4041 audio_source_t source)
4042{
4043 struct audio_device *adev = (struct audio_device *)dev;
4044 struct stream_in *in;
4045 struct pcm_device_profile *pcm_profile;
4046
4047 ALOGV("%s: enter", __func__);
4048
4049 *stream_in = NULL;
4050 if (check_input_parameters(config->sample_rate, config->format,
4051 audio_channel_count_from_in_mask(config->channel_mask)) != 0)
4052 return -EINVAL;
4053
4054 usecase_type_t usecase_type = source == AUDIO_SOURCE_HOTWORD ?
4055 PCM_HOTWORD_STREAMING : flags & AUDIO_INPUT_FLAG_FAST ?
4056 PCM_CAPTURE_LOW_LATENCY : PCM_CAPTURE;
4057 pcm_profile = get_pcm_device(usecase_type, devices);
4058 if (pcm_profile == NULL && usecase_type == PCM_CAPTURE_LOW_LATENCY) {
4059 // a low latency profile may not exist for that device, fall back
4060 // to regular capture. the MixerThread automatically changes
4061 // to non-fast capture based on the buffer size.
4062 flags &= ~AUDIO_INPUT_FLAG_FAST;
4063 usecase_type = PCM_CAPTURE;
4064 pcm_profile = get_pcm_device(usecase_type, devices);
4065 }
4066 if (pcm_profile == NULL)
4067 return -EINVAL;
4068
4069 in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
Andreas Schneider56204f62017-01-31 08:17:32 +01004070 if (in == NULL) {
4071 return -ENOMEM;
4072 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004073
4074 in->stream.common.get_sample_rate = in_get_sample_rate;
4075 in->stream.common.set_sample_rate = in_set_sample_rate;
4076 in->stream.common.get_buffer_size = in_get_buffer_size;
4077 in->stream.common.get_channels = in_get_channels;
4078 in->stream.common.get_format = in_get_format;
4079 in->stream.common.set_format = in_set_format;
4080 in->stream.common.standby = in_standby;
4081 in->stream.common.dump = in_dump;
4082 in->stream.common.set_parameters = in_set_parameters;
4083 in->stream.common.get_parameters = in_get_parameters;
4084 in->stream.common.add_audio_effect = in_add_audio_effect;
4085 in->stream.common.remove_audio_effect = in_remove_audio_effect;
4086 in->stream.set_gain = in_set_gain;
4087 in->stream.read = in_read;
4088 in->stream.get_input_frames_lost = in_get_input_frames_lost;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004089 in->stream.get_capture_position = in_get_capture_position;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004090
4091 in->devices = devices;
4092 in->source = source;
4093 in->dev = adev;
4094 in->standby = 1;
4095 in->main_channels = config->channel_mask;
4096 in->requested_rate = config->sample_rate;
4097 if (config->sample_rate != CAPTURE_DEFAULT_SAMPLING_RATE)
4098 flags = flags & ~AUDIO_INPUT_FLAG_FAST;
4099 in->input_flags = flags;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004100 // in->frames_read = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004101 /* HW codec is limited to default channels. No need to update with
4102 * requested channels */
4103 in->config = pcm_profile->config;
4104
4105 /* Update config params with the requested sample rate and channels */
4106 if (source == AUDIO_SOURCE_HOTWORD) {
4107 in->usecase = USECASE_AUDIO_CAPTURE_HOTWORD;
4108 } else {
4109 in->usecase = USECASE_AUDIO_CAPTURE;
4110 }
4111 in->usecase_type = usecase_type;
4112
4113 pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
4114 pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL);
4115
4116 in->is_fastcapture_affinity_set = false;
4117
4118 *stream_in = &in->stream;
4119 ALOGV("%s: exit", __func__);
4120 return 0;
4121}
4122
4123static void adev_close_input_stream(struct audio_hw_device *dev,
4124 struct audio_stream_in *stream)
4125{
4126 struct audio_device *adev = (struct audio_device *)dev;
4127 struct stream_in *in = (struct stream_in*)stream;
4128 ALOGV("%s", __func__);
4129
4130 /* prevent concurrent out_set_parameters, or out_write from standby */
4131 pthread_mutex_lock(&adev->lock_inputs);
4132
Andreas Schneidercabe5e62017-01-30 10:57:06 +01004133 if (in->read_buf) {
4134 free(in->read_buf);
4135 in->read_buf = NULL;
4136 }
4137
4138 if (in->resampler) {
4139 release_resampler(in->resampler);
4140 in->resampler = NULL;
4141 }
4142
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004143#ifdef PREPROCESSING_ENABLED
4144 int i;
4145
4146 for (i=0; i<in->num_preprocessors; i++) {
4147 free(in->preprocessors[i].channel_configs);
4148 }
4149
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004150 if (in->proc_buf_in) {
4151 free(in->proc_buf_in);
4152 in->proc_buf_in = NULL;
4153 }
4154
4155 if (in->proc_buf_out) {
4156 free(in->proc_buf_out);
4157 in->proc_buf_out = NULL;
4158 }
4159
4160 if (in->ref_buf) {
4161 free(in->ref_buf);
4162 in->ref_buf = NULL;
4163 }
4164
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004165#endif
4166
4167 in_standby_l(in);
4168 free(stream);
4169
4170 pthread_mutex_unlock(&adev->lock_inputs);
4171
4172 return;
4173}
4174
4175static int adev_dump(const audio_hw_device_t *device, int fd)
4176{
4177 (void)device;
4178 (void)fd;
4179
4180 return 0;
4181}
4182
4183static int adev_close(hw_device_t *device)
4184{
4185 struct audio_device *adev = (struct audio_device *)device;
4186 audio_device_ref_count--;
4187 free(adev->snd_dev_ref_cnt);
4188 free_mixer_list(adev);
4189 free(device);
4190 return 0;
4191}
4192
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004193/* This returns true if the input parameter looks at all plausible as a low latency period size,
4194 * or false otherwise. A return value of true doesn't mean the value is guaranteed to work,
4195 * just that it _might_ work.
4196 */
4197static bool period_size_is_plausible_for_low_latency(int period_size)
4198{
4199 switch (period_size) {
4200 case 64:
4201 case 96:
4202 case 128:
4203 case 192:
4204 case 256:
4205 return true;
4206 default:
4207 return false;
4208 }
4209}
4210
4211static int adev_open(const hw_module_t *module, const char *name,
4212 hw_device_t **device)
4213{
4214 struct audio_device *adev;
4215 int retry_count = 0;
4216
4217 ALOGV("%s: enter", __func__);
4218 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
4219
Andreas Schneider56204f62017-01-31 08:17:32 +01004220 *device = NULL;
4221
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004222 adev = calloc(1, sizeof(struct audio_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01004223 if (adev == NULL) {
4224 return -ENOMEM;
4225 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004226
4227 adev->device.common.tag = HARDWARE_DEVICE_TAG;
4228 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
4229 adev->device.common.module = (struct hw_module_t *)module;
4230 adev->device.common.close = adev_close;
4231
4232 adev->device.init_check = adev_init_check;
4233 adev->device.set_voice_volume = adev_set_voice_volume;
4234 adev->device.set_master_volume = adev_set_master_volume;
4235 adev->device.get_master_volume = adev_get_master_volume;
4236 adev->device.set_master_mute = adev_set_master_mute;
4237 adev->device.get_master_mute = adev_get_master_mute;
4238 adev->device.set_mode = adev_set_mode;
4239 adev->device.set_mic_mute = adev_set_mic_mute;
4240 adev->device.get_mic_mute = adev_get_mic_mute;
4241 adev->device.set_parameters = adev_set_parameters;
4242 adev->device.get_parameters = adev_get_parameters;
4243 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
4244 adev->device.open_output_stream = adev_open_output_stream;
4245 adev->device.close_output_stream = adev_close_output_stream;
4246 adev->device.open_input_stream = adev_open_input_stream;
4247 adev->device.close_input_stream = adev_close_input_stream;
4248 adev->device.dump = adev_dump;
4249
4250 /* Set the default route before the PCM stream is opened */
4251 adev->mode = AUDIO_MODE_NORMAL;
4252 adev->active_input = NULL;
4253 adev->primary_output = NULL;
4254 adev->voice_volume = 1.0f;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004255 adev->bluetooth_nrec = true;
4256 adev->in_call = false;
4257 /* adev->cur_hdmi_channels = 0; by calloc() */
4258 adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
Andreas Schneider56204f62017-01-31 08:17:32 +01004259 if (adev->snd_dev_ref_cnt == NULL) {
4260 free(adev);
4261 return -ENOMEM;
4262 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004263
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004264 adev->ns_in_voice_rec = false;
4265
4266 list_init(&adev->usecase_list);
4267
4268 if (mixer_init(adev) != 0) {
4269 free(adev->snd_dev_ref_cnt);
4270 free(adev);
4271 ALOGE("%s: Failed to init, aborting.", __func__);
4272 *device = NULL;
4273 return -EINVAL;
4274 }
4275
4276 if (access(OFFLOAD_FX_LIBRARY_PATH, R_OK) == 0) {
4277 adev->offload_fx_lib = dlopen(OFFLOAD_FX_LIBRARY_PATH, RTLD_NOW);
4278 if (adev->offload_fx_lib == NULL) {
4279 ALOGE("%s: DLOPEN failed for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4280 } else {
4281 ALOGV("%s: DLOPEN successful for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4282 adev->offload_fx_start_output =
4283 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4284 "visualizer_hal_start_output");
4285 adev->offload_fx_stop_output =
4286 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4287 "visualizer_hal_stop_output");
4288 }
4289 }
4290
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004291 if (access(SOUND_TRIGGER_HAL_LIBRARY_PATH, R_OK) == 0) {
4292 adev->sound_trigger_lib = dlopen(SOUND_TRIGGER_HAL_LIBRARY_PATH, RTLD_NOW);
4293 if (adev->sound_trigger_lib == NULL) {
4294 ALOGE("%s: DLOPEN failed for %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4295 } else {
4296 ALOGV("%s: DLOPEN successful for %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4297 adev->sound_trigger_open_for_streaming =
4298 (int (*)(void))dlsym(adev->sound_trigger_lib,
4299 "sound_trigger_open_for_streaming");
4300 adev->sound_trigger_read_samples =
4301 (size_t (*)(int, void *, size_t))dlsym(adev->sound_trigger_lib,
4302 "sound_trigger_read_samples");
4303 adev->sound_trigger_close_for_streaming =
4304 (int (*)(int))dlsym(adev->sound_trigger_lib,
4305 "sound_trigger_close_for_streaming");
4306 if (!adev->sound_trigger_open_for_streaming ||
4307 !adev->sound_trigger_read_samples ||
4308 !adev->sound_trigger_close_for_streaming) {
4309
4310 ALOGE("%s: Error grabbing functions in %s", __func__, SOUND_TRIGGER_HAL_LIBRARY_PATH);
4311 adev->sound_trigger_open_for_streaming = 0;
4312 adev->sound_trigger_read_samples = 0;
4313 adev->sound_trigger_close_for_streaming = 0;
4314 }
4315 }
4316 }
4317
4318
4319 *device = &adev->device.common;
4320
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004321 audio_device_ref_count++;
4322
4323 char value[PROPERTY_VALUE_MAX];
4324 if (property_get("audio_hal.period_size", value, NULL) > 0) {
4325 int trial = atoi(value);
4326 if (period_size_is_plausible_for_low_latency(trial)) {
4327
4328 pcm_device_playback.config.period_size = trial;
4329 pcm_device_playback.config.start_threshold =
4330 PLAYBACK_START_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4331 pcm_device_playback.config.stop_threshold =
4332 PLAYBACK_STOP_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4333
4334 pcm_device_capture_low_latency.config.period_size = trial;
4335 }
4336 }
4337
4338 ALOGV("%s: exit", __func__);
4339 return 0;
4340}
4341
4342static struct hw_module_methods_t hal_module_methods = {
4343 .open = adev_open,
4344};
4345
4346struct audio_module HAL_MODULE_INFO_SYM = {
4347 .common = {
4348 .tag = HARDWARE_MODULE_TAG,
4349 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
4350 .hal_api_version = HARDWARE_HAL_API_VERSION,
4351 .id = AUDIO_HARDWARE_MODULE_ID,
Christopher N. Hessec8502b92017-01-28 14:02:15 +01004352 .name = "Samsung Audio HAL",
4353 .author = "The LineageOS Project",
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004354 .methods = &hal_module_methods,
4355 },
4356};