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