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