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