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