blob: 6843fd25818e0a138ad5fd5d10b97587e5cbaa7a [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>
stenkinevgeniy44335362018-05-07 18:00:13 +00005 * Copyright (C) 2018 The LineageOS Project
Christopher N. Hesse297a6362017-01-28 12:40:45 +01006 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20#define LOG_TAG "audio_hw_primary"
21/*#define LOG_NDEBUG 0*/
22/*#define VERY_VERY_VERBOSE_LOGGING*/
23#ifdef VERY_VERY_VERBOSE_LOGGING
24#define ALOGVV ALOGV
25#else
26#define ALOGVV(a...) do { } while(0)
27#endif
28
29#define _GNU_SOURCE
30#include <errno.h>
31#include <pthread.h>
32#include <stdint.h>
33#include <sys/time.h>
34#include <stdlib.h>
35#include <math.h>
36#include <dlfcn.h>
Christopher N. Hesse297a6362017-01-28 12:40:45 +010037
38#include <cutils/log.h>
39#include <cutils/str_parms.h>
40#include <cutils/atomic.h>
41#include <cutils/sched_policy.h>
42#include <cutils/properties.h>
43
Christopher N. Hessed23c6b52017-01-28 14:18:10 +010044#include <samsung_audio.h>
45
Christopher N. Hesse297a6362017-01-28 12:40:45 +010046#include <hardware/audio_effect.h>
47#include <system/thread_defs.h>
48#include <audio_effects/effect_aec.h>
49#include <audio_effects/effect_ns.h>
50#include "audio_hw.h"
Christopher N. Hesse757ac412017-01-28 14:42:48 +010051#include "compress_offload.h"
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +010052#include "voice.h"
Christopher N. Hesse297a6362017-01-28 12:40:45 +010053
54#include "sound/compress_params.h"
55
Christopher N. Hesse297a6362017-01-28 12:40:45 +010056
57/* TODO: the following PCM device profiles could be read from a config file */
58static struct pcm_device_profile pcm_device_playback = {
59 .config = {
60 .channels = PLAYBACK_DEFAULT_CHANNEL_COUNT,
61 .rate = PLAYBACK_DEFAULT_SAMPLING_RATE,
62 .period_size = PLAYBACK_PERIOD_SIZE,
63 .period_count = PLAYBACK_PERIOD_COUNT,
64 .format = PCM_FORMAT_S16_LE,
65 .start_threshold = PLAYBACK_START_THRESHOLD(PLAYBACK_PERIOD_SIZE, PLAYBACK_PERIOD_COUNT),
66 .stop_threshold = PLAYBACK_STOP_THRESHOLD(PLAYBACK_PERIOD_SIZE, PLAYBACK_PERIOD_COUNT),
67 .silence_threshold = 0,
68 .silence_size = UINT_MAX,
69 .avail_min = PLAYBACK_AVAILABLE_MIN,
70 },
71 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +010072 .id = SOUND_PLAYBACK_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +010073 .type = PCM_PLAYBACK,
74 .devices = AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|
Fevax86ac2342017-02-08 09:52:12 +010075 AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +010076};
77
Christopher N. Hesse8414bd22017-01-30 18:57:20 +010078static struct pcm_device_profile pcm_device_deep_buffer = {
79 .config = {
80 .channels = PLAYBACK_DEFAULT_CHANNEL_COUNT,
81 .rate = DEEP_BUFFER_OUTPUT_SAMPLING_RATE,
82 .period_size = DEEP_BUFFER_OUTPUT_PERIOD_SIZE,
83 .period_count = DEEP_BUFFER_OUTPUT_PERIOD_COUNT,
84 .format = PCM_FORMAT_S16_LE,
85 .start_threshold = DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4,
86 .stop_threshold = INT_MAX,
87 .avail_min = DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4,
88 },
89 .card = SOUND_CARD,
90 .id = SOUND_DEEP_BUFFER_DEVICE,
91 .type = PCM_PLAYBACK,
92 .devices = AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|
Fevax86ac2342017-02-08 09:52:12 +010093 AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE,
Christopher N. Hesse8414bd22017-01-30 18:57:20 +010094};
95
Christopher N. Hesse297a6362017-01-28 12:40:45 +010096static struct pcm_device_profile pcm_device_capture = {
97 .config = {
98 .channels = CAPTURE_DEFAULT_CHANNEL_COUNT,
99 .rate = CAPTURE_DEFAULT_SAMPLING_RATE,
100 .period_size = CAPTURE_PERIOD_SIZE,
101 .period_count = CAPTURE_PERIOD_COUNT,
102 .format = PCM_FORMAT_S16_LE,
103 .start_threshold = CAPTURE_START_THRESHOLD,
104 .stop_threshold = 0,
105 .silence_threshold = 0,
106 .avail_min = 0,
107 },
108 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100109 .id = SOUND_CAPTURE_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100110 .type = PCM_CAPTURE,
111 .devices = AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BACK_MIC,
112};
113
114static struct pcm_device_profile pcm_device_capture_low_latency = {
115 .config = {
116 .channels = CAPTURE_DEFAULT_CHANNEL_COUNT,
117 .rate = CAPTURE_DEFAULT_SAMPLING_RATE,
118 .period_size = CAPTURE_PERIOD_SIZE_LOW_LATENCY,
119 .period_count = CAPTURE_PERIOD_COUNT_LOW_LATENCY,
120 .format = PCM_FORMAT_S16_LE,
121 .start_threshold = CAPTURE_START_THRESHOLD,
122 .stop_threshold = 0,
123 .silence_threshold = 0,
124 .avail_min = 0,
125 },
126 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100127 .id = SOUND_CAPTURE_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100128 .type = PCM_CAPTURE_LOW_LATENCY,
129 .devices = AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BACK_MIC,
130};
131
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100132static struct pcm_device_profile pcm_device_playback_sco = {
133 .config = {
134 .channels = SCO_DEFAULT_CHANNEL_COUNT,
135 .rate = SCO_DEFAULT_SAMPLING_RATE,
136 .period_size = SCO_PERIOD_SIZE,
137 .period_count = SCO_PERIOD_COUNT,
138 .format = PCM_FORMAT_S16_LE,
139 .start_threshold = SCO_START_THRESHOLD,
140 .stop_threshold = SCO_STOP_THRESHOLD,
141 .silence_threshold = 0,
142 .avail_min = SCO_AVAILABLE_MIN,
143 },
144 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100145 .id = SOUND_PLAYBACK_SCO_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100146 .type = PCM_PLAYBACK,
147 .devices =
148 AUDIO_DEVICE_OUT_BLUETOOTH_SCO|AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET|
149 AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT,
150};
151
152static struct pcm_device_profile pcm_device_capture_sco = {
153 .config = {
154 .channels = SCO_DEFAULT_CHANNEL_COUNT,
155 .rate = SCO_DEFAULT_SAMPLING_RATE,
156 .period_size = SCO_PERIOD_SIZE,
157 .period_count = SCO_PERIOD_COUNT,
158 .format = PCM_FORMAT_S16_LE,
159 .start_threshold = CAPTURE_START_THRESHOLD,
160 .stop_threshold = 0,
161 .silence_threshold = 0,
162 .avail_min = 0,
163 },
164 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100165 .id = SOUND_CAPTURE_SCO_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100166 .type = PCM_CAPTURE,
167 .devices = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
168};
169
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100170static struct pcm_device_profile * const pcm_devices[] = {
171 &pcm_device_playback,
172 &pcm_device_capture,
173 &pcm_device_capture_low_latency,
174 &pcm_device_playback_sco,
175 &pcm_device_capture_sco,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100176 NULL,
177};
178
179static const char * const use_case_table[AUDIO_USECASE_MAX] = {
180 [USECASE_AUDIO_PLAYBACK] = "playback",
181 [USECASE_AUDIO_PLAYBACK_MULTI_CH] = "playback multi-channel",
182 [USECASE_AUDIO_PLAYBACK_OFFLOAD] = "compress-offload-playback",
Andreas Schneiderdf6fc8a2017-02-14 11:38:41 +0100183 [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = "playback deep-buffer",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100184 [USECASE_AUDIO_CAPTURE] = "capture",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100185 [USECASE_VOICE_CALL] = "voice-call",
186};
187
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100188#define STRING_TO_ENUM(string) { #string, string }
189
190static unsigned int audio_device_ref_count;
191
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100192struct string_to_enum {
193 const char *name;
194 uint32_t value;
195};
196
197static const struct string_to_enum out_channels_name_to_enum_table[] = {
198 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO),
199 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1),
200 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
201};
202
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +0200203static struct audio_device *adev = NULL;
204
205static amplifier_device_t * get_amplifier_device(void)
206{
207 if (adev)
208 return adev->amp;
209
210 return NULL;
211}
212
213static int amplifier_open(void)
214{
215 int rc;
216 amplifier_module_t *module;
217
218 rc = hw_get_module(AMPLIFIER_HARDWARE_MODULE_ID,
219 (const hw_module_t **) &module);
220 if (rc) {
Christopher N. Hessec487bbe2018-07-12 13:51:43 +0200221 if (rc == -ENOENT) {
222 // no amplifier HAL present
223 return -ENOENT;
224 }
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +0200225 ALOGV("%s: Failed to obtain reference to amplifier module: %s\n",
226 __func__, strerror(-rc));
227 return -ENODEV;
228 }
229
230 rc = amplifier_device_open((const hw_module_t *) module, &adev->amp);
231 if (rc) {
232 ALOGV("%s: Failed to open amplifier hardware device: %s\n",
233 __func__, strerror(-rc));
234 return -ENODEV;
235 }
236
237 return 0;
238}
239
240static int amplifier_set_input_devices(uint32_t devices)
241{
242 amplifier_device_t *amp = get_amplifier_device();
243 if (amp && amp->set_input_devices)
244 return amp->set_input_devices(amp, devices);
245
246 return 0;
247}
248
249static int amplifier_set_output_devices(uint32_t devices)
250{
251 amplifier_device_t *amp = get_amplifier_device();
252 if (amp && amp->set_output_devices)
253 return amp->set_output_devices(amp, devices);
254
255 return 0;
256}
257
258static int amplifier_enable_devices(uint32_t devices, bool enable)
259{
260 amplifier_device_t *amp = get_amplifier_device();
261 bool is_output = devices > SND_DEVICE_OUT_BEGIN &&
262 devices < SND_DEVICE_OUT_END;
263
264 if (amp && amp->enable_output_devices && is_output)
265 return amp->enable_output_devices(amp, devices, enable);
266
267 if (amp && amp->enable_input_devices && !is_output)
268 return amp->enable_input_devices(amp, devices, enable);
269
270 return 0;
271}
272
273static int amplifier_set_mode(audio_mode_t mode)
274{
275 amplifier_device_t *amp = get_amplifier_device();
276 if (amp && amp->set_mode)
277 return amp->set_mode(amp, mode);
278
279 return 0;
280}
281
282static int amplifier_output_stream_start(struct audio_stream_out *stream,
283 bool offload)
284{
285 amplifier_device_t *amp = get_amplifier_device();
286 if (amp && amp->output_stream_start)
287 return amp->output_stream_start(amp, stream, offload);
288
289 return 0;
290}
291
292static int amplifier_input_stream_start(struct audio_stream_in *stream)
293{
294 amplifier_device_t *amp = get_amplifier_device();
295 if (amp && amp->input_stream_start)
296 return amp->input_stream_start(amp, stream);
297
298 return 0;
299}
300
301static int amplifier_output_stream_standby(struct audio_stream_out *stream)
302{
303 amplifier_device_t *amp = get_amplifier_device();
304 if (amp && amp->output_stream_standby)
305 return amp->output_stream_standby(amp, stream);
306
307 return 0;
308}
309
310static int amplifier_input_stream_standby(struct audio_stream_in *stream)
311{
312 amplifier_device_t *amp = get_amplifier_device();
313 if (amp && amp->input_stream_standby)
314 return amp->input_stream_standby(amp, stream);
315
316 return 0;
317}
318
319static int amplifier_set_parameters(struct str_parms *parms)
320{
321 amplifier_device_t *amp = get_amplifier_device();
322 if (amp && amp->set_parameters)
323 return amp->set_parameters(amp, parms);
324
325 return 0;
326}
327
328static int amplifier_close(void)
329{
330 amplifier_device_t *amp = get_amplifier_device();
331 if (amp)
332 amplifier_device_close(amp);
333
334 return 0;
335}
336
Andreas Schneider759368f2017-02-02 16:11:14 +0100337struct timespec time_spec_diff(struct timespec time1, struct timespec time0) {
338 struct timespec ret;
339 int xsec = 0;
Andreas Schneider759368f2017-02-02 16:11:14 +0100340
341 if (time0.tv_nsec > time1.tv_nsec) {
342 xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1));
343 time0.tv_nsec -= (long int) (1E9 * xsec);
344 time0.tv_sec += xsec;
345 }
346
347 if ((time1.tv_nsec - time0.tv_nsec) > 1E9) {
348 xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9);
349 time0.tv_nsec += (long int) (1E9 * xsec);
350 time0.tv_sec -= xsec;
351 }
352
Paul Keithf114e2e2017-02-14 20:41:33 -0600353 ret.tv_sec = labs(time1.tv_sec - time0.tv_sec);
354 ret.tv_nsec = labs(time1.tv_nsec - time0.tv_nsec);
Andreas Schneider759368f2017-02-02 16:11:14 +0100355
356 return ret;
357}
358
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100359static bool is_supported_format(audio_format_t format)
360{
361 if (format == AUDIO_FORMAT_MP3 ||
362 ((format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_AAC))
363 return true;
364
365 return false;
366}
367
368static int get_snd_codec_id(audio_format_t format)
369{
370 int id = 0;
371
372 switch (format & AUDIO_FORMAT_MAIN_MASK) {
373 case AUDIO_FORMAT_MP3:
374 id = SND_AUDIOCODEC_MP3;
375 break;
376 case AUDIO_FORMAT_AAC:
377 id = SND_AUDIOCODEC_AAC;
378 break;
379 default:
380 ALOGE("%s: Unsupported audio format", __func__);
381 }
382
383 return id;
384}
385
386/* Array to store sound devices */
387static const char * const device_table[SND_DEVICE_MAX] = {
388 [SND_DEVICE_NONE] = "none",
389 /* Playback sound devices */
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100390 [SND_DEVICE_OUT_EARPIECE] = "earpiece",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100391 [SND_DEVICE_OUT_SPEAKER] = "speaker",
392 [SND_DEVICE_OUT_HEADPHONES] = "headphones",
393 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100394 [SND_DEVICE_OUT_VOICE_EARPIECE] = "voice-earpiece",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100395 [SND_DEVICE_OUT_VOICE_EARPIECE_WB] = "voice-earpiece-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100396 [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100397 [SND_DEVICE_OUT_VOICE_SPEAKER_WB] = "voice-speaker-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100398 [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100399 [SND_DEVICE_OUT_VOICE_HEADPHONES_WB] = "voice-headphones-wb",
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100400 [SND_DEVICE_OUT_VOICE_BT_SCO] = "voice-bt-sco-headset",
401 [SND_DEVICE_OUT_VOICE_BT_SCO_WB] = "voice-bt-sco-headset-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100402 [SND_DEVICE_OUT_HDMI] = "hdmi",
403 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
404 [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100405
406 /* Capture sound devices */
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100407 [SND_DEVICE_IN_EARPIECE_MIC] = "earpiece-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100408 [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
409 [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100410 [SND_DEVICE_IN_EARPIECE_MIC_AEC] = "earpiece-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100411 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "voice-speaker-mic",
412 [SND_DEVICE_IN_HEADSET_MIC_AEC] = "headset-mic",
Andreas Schneider82f32482017-02-06 09:00:48 +0100413 [SND_DEVICE_IN_VOICE_MIC] = "voice-mic",
414 [SND_DEVICE_IN_VOICE_EARPIECE_MIC] = "voice-earpiece-mic",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100415 [SND_DEVICE_IN_VOICE_EARPIECE_MIC_WB] = "voice-earpiece-mic-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100416 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100417 [SND_DEVICE_IN_VOICE_SPEAKER_MIC_WB] = "voice-speaker-mic-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100418 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100419 [SND_DEVICE_IN_VOICE_HEADSET_MIC_WB] = "voice-headset-mic-wb",
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100420 [SND_DEVICE_IN_VOICE_BT_SCO_MIC] = "voice-bt-sco-mic",
421 [SND_DEVICE_IN_VOICE_BT_SCO_MIC_WB] = "voice-bt-sco-mic-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100422 [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
423 [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
424 [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100425 [SND_DEVICE_IN_VOICE_REC_HEADSET_MIC] = "voice-rec-headset-mic",
426 [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100427};
428
429static struct mixer_card *adev_get_mixer_for_card(struct audio_device *adev, int card)
430{
431 struct mixer_card *mixer_card;
432 struct listnode *node;
433
434 list_for_each(node, &adev->mixer_list) {
435 mixer_card = node_to_item(node, struct mixer_card, adev_list_node);
436 if (mixer_card->card == card)
437 return mixer_card;
438 }
439 return NULL;
440}
441
442static struct mixer_card *uc_get_mixer_for_card(struct audio_usecase *usecase, int card)
443{
444 struct mixer_card *mixer_card;
445 struct listnode *node;
446
447 list_for_each(node, &usecase->mixer_list) {
448 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[usecase->id]);
449 if (mixer_card->card == card)
450 return mixer_card;
451 }
452 return NULL;
453}
454
455static void free_mixer_list(struct audio_device *adev)
456{
457 struct mixer_card *mixer_card;
458 struct listnode *node;
459 struct listnode *next;
460
461 list_for_each_safe(node, next, &adev->mixer_list) {
462 mixer_card = node_to_item(node, struct mixer_card, adev_list_node);
463 list_remove(node);
464 audio_route_free(mixer_card->audio_route);
465 free(mixer_card);
466 }
467}
468
469static int mixer_init(struct audio_device *adev)
470{
471 int i;
472 int card;
473 int retry_num;
474 struct mixer *mixer;
475 struct audio_route *audio_route;
476 char mixer_path[PATH_MAX];
477 struct mixer_card *mixer_card;
Andreas Schneider56204f62017-01-31 08:17:32 +0100478 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100479
480 list_init(&adev->mixer_list);
481
482 for (i = 0; pcm_devices[i] != NULL; i++) {
483 card = pcm_devices[i]->card;
484 if (adev_get_mixer_for_card(adev, card) == NULL) {
485 retry_num = 0;
486 do {
487 mixer = mixer_open(card);
488 if (mixer == NULL) {
489 if (++retry_num > RETRY_NUMBER) {
490 ALOGE("%s unable to open the mixer for--card %d, aborting.",
491 __func__, card);
Andreas Schneider56204f62017-01-31 08:17:32 +0100492 ret = -ENODEV;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100493 goto error;
494 }
495 usleep(RETRY_US);
496 }
497 } while (mixer == NULL);
498
Christopher N. Hessed8d04fd2018-01-28 00:07:47 +0100499 sprintf(mixer_path, "/vendor/etc/mixer_paths_%d.xml", card);
Christopher N. Hesse2beff422018-01-28 13:16:17 +0100500 if (access(mixer_path, F_OK) == -1) {
Christopher N. Hessed8d04fd2018-01-28 00:07:47 +0100501 ALOGW("%s: Failed to open mixer paths from %s, retrying with legacy location",
Christopher N. Hesse2beff422018-01-28 13:16:17 +0100502 __func__, mixer_path);
Christopher N. Hessed8d04fd2018-01-28 00:07:47 +0100503 sprintf(mixer_path, "/system/etc/mixer_paths_%d.xml", card);
504 if (access(mixer_path, F_OK) == -1) {
505 ALOGE("%s: Failed to load a mixer paths configuration, your system will crash",
506 __func__);
507 }
Christopher N. Hesse2beff422018-01-28 13:16:17 +0100508 }
509
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100510 audio_route = audio_route_init(card, mixer_path);
511 if (!audio_route) {
512 ALOGE("%s: Failed to init audio route controls for card %d, aborting.",
513 __func__, card);
Andreas Schneider56204f62017-01-31 08:17:32 +0100514 ret = -ENODEV;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100515 goto error;
516 }
517 mixer_card = calloc(1, sizeof(struct mixer_card));
Andreas Schneider56204f62017-01-31 08:17:32 +0100518 if (mixer_card == NULL) {
519 ret = -ENOMEM;
520 goto error;
521 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100522 mixer_card->card = card;
523 mixer_card->mixer = mixer;
524 mixer_card->audio_route = audio_route;
Andreas Schneider759368f2017-02-02 16:11:14 +0100525
526 /* Do not sleep on first enable_snd_device() */
527 mixer_card->dsp_poweroff_time.tv_sec = 1;
528 mixer_card->dsp_poweroff_time.tv_nsec = 0;
529
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100530 list_add_tail(&adev->mixer_list, &mixer_card->adev_list_node);
531 }
532 }
533
534 return 0;
535
536error:
537 free_mixer_list(adev);
Andreas Schneider56204f62017-01-31 08:17:32 +0100538 return ret;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100539}
540
541static const char *get_snd_device_name(snd_device_t snd_device)
542{
543 const char *name = NULL;
544
Andreas Schneideradb788d2017-02-13 15:19:36 +0100545 if (snd_device == SND_DEVICE_NONE ||
Andreas Schneiderdde54c02017-02-15 14:10:58 +0100546 (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX))
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100547 name = device_table[snd_device];
548
549 ALOGE_IF(name == NULL, "%s: invalid snd device %d", __func__, snd_device);
550
551 return name;
552}
553
554static const char *get_snd_device_display_name(snd_device_t snd_device)
555{
556 const char *name = get_snd_device_name(snd_device);
557
558 if (name == NULL)
559 name = "SND DEVICE NOT FOUND";
560
561 return name;
562}
563
564static struct pcm_device_profile *get_pcm_device(usecase_type_t uc_type, audio_devices_t devices)
565{
566 int i;
567
568 devices &= ~AUDIO_DEVICE_BIT_IN;
569 for (i = 0; pcm_devices[i] != NULL; i++) {
570 if ((pcm_devices[i]->type == uc_type) &&
571 (devices & pcm_devices[i]->devices))
572 break;
573 }
574 return pcm_devices[i];
575}
576
577static struct audio_usecase *get_usecase_from_id(struct audio_device *adev,
578 audio_usecase_t uc_id)
579{
580 struct audio_usecase *usecase;
581 struct listnode *node;
582
583 list_for_each(node, &adev->usecase_list) {
584 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
585 if (usecase->id == uc_id)
586 return usecase;
587 }
588 return NULL;
589}
590
591static struct audio_usecase *get_usecase_from_type(struct audio_device *adev,
592 usecase_type_t type)
593{
594 struct audio_usecase *usecase;
595 struct listnode *node;
596
597 list_for_each(node, &adev->usecase_list) {
598 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
599 if (usecase->type & type)
600 return usecase;
601 }
602 return NULL;
603}
604
605/* always called with adev lock held */
606static int set_voice_volume_l(struct audio_device *adev, float volume)
607{
608 int err = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100609
610 if (adev->mode == AUDIO_MODE_IN_CALL) {
Christopher N. Hesse696959d2017-02-02 20:49:55 +0100611 set_voice_session_volume(adev->voice.session, volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100612 }
Christopher N. Hesse696959d2017-02-02 20:49:55 +0100613
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100614 return err;
615}
616
617
618static snd_device_t get_output_snd_device(struct audio_device *adev, audio_devices_t devices)
619{
620
621 audio_mode_t mode = adev->mode;
622 snd_device_t snd_device = SND_DEVICE_NONE;
623
624 ALOGV("%s: enter: output devices(%#x), mode(%d)", __func__, devices, mode);
625 if (devices == AUDIO_DEVICE_NONE ||
626 devices & AUDIO_DEVICE_BIT_IN) {
627 ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
628 goto exit;
629 }
630
631 if (mode == AUDIO_MODE_IN_CALL) {
632 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
633 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Andreas Schneidera2b77322017-01-30 22:33:56 +0100634 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
Fevax51bd12c2017-03-15 10:56:39 -0300635 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100636 snd_device = SND_DEVICE_OUT_VOICE_BT_SCO;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100637 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
638 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
639 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Andreas Schneider59486fa2017-02-06 09:16:39 +0100640 snd_device = SND_DEVICE_OUT_VOICE_EARPIECE;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100641 }
Andreas Schneider59486fa2017-02-06 09:16:39 +0100642
643 if (voice_session_uses_wideband(adev->voice.session)) {
644 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
645 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
646 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES_WB;
Fevax51bd12c2017-03-15 10:56:39 -0300647 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100648 snd_device = SND_DEVICE_OUT_VOICE_BT_SCO_WB;
Andreas Schneider59486fa2017-02-06 09:16:39 +0100649 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
650 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_WB;
651 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
652 snd_device = SND_DEVICE_OUT_VOICE_EARPIECE_WB;
653 }
654 }
655
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100656 if (snd_device != SND_DEVICE_NONE) {
657 goto exit;
658 }
659 }
660
661 if (popcount(devices) == 2) {
662 if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
663 AUDIO_DEVICE_OUT_SPEAKER)) {
664 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
665 } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
666 AUDIO_DEVICE_OUT_SPEAKER)) {
667 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
668 } else {
669 ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
670 goto exit;
671 }
672 if (snd_device != SND_DEVICE_NONE) {
673 goto exit;
674 }
675 }
676
677 if (popcount(devices) != 1) {
678 ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
679 goto exit;
680 }
681
682 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
683 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
684 snd_device = SND_DEVICE_OUT_HEADPHONES;
685 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
686 snd_device = SND_DEVICE_OUT_SPEAKER;
687 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
688 snd_device = SND_DEVICE_OUT_BT_SCO;
689 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100690 snd_device = SND_DEVICE_OUT_EARPIECE;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100691 } else {
692 ALOGE("%s: Unknown device(s) %#x", __func__, devices);
693 }
694exit:
695 ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
696 return snd_device;
697}
698
699static snd_device_t get_input_snd_device(struct audio_device *adev, audio_devices_t out_device)
700{
701 audio_source_t source;
702 audio_mode_t mode = adev->mode;
703 audio_devices_t in_device;
704 audio_channel_mask_t channel_mask;
705 snd_device_t snd_device = SND_DEVICE_NONE;
706 struct stream_in *active_input = NULL;
707 struct audio_usecase *usecase;
708
709 usecase = get_usecase_from_type(adev, PCM_CAPTURE|VOICE_CALL);
710 if (usecase != NULL) {
711 active_input = (struct stream_in *)usecase->stream;
712 }
713 source = (active_input == NULL) ?
714 AUDIO_SOURCE_DEFAULT : active_input->source;
715
Andreas Schneider757e2d82017-02-10 19:28:35 +0100716 in_device = (active_input == NULL) ?
717 AUDIO_DEVICE_NONE :
718 (active_input->devices & ~AUDIO_DEVICE_BIT_IN);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100719 channel_mask = (active_input == NULL) ?
720 AUDIO_CHANNEL_IN_MONO : active_input->main_channels;
721
722 ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
723 __func__, out_device, in_device);
724 if (mode == AUDIO_MODE_IN_CALL) {
725 if (out_device == AUDIO_DEVICE_NONE) {
726 ALOGE("%s: No output device set for voice call", __func__);
727 goto exit;
728 }
Andreas Schneidera2b77322017-01-30 22:33:56 +0100729
Andreas Schneider82f32482017-02-06 09:00:48 +0100730 snd_device = SND_DEVICE_IN_VOICE_MIC;
731 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100732 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
Andreas Schneider82f32482017-02-06 09:00:48 +0100733 }
734
735 if (voice_session_uses_twomic(adev->voice.session)) {
736 if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
737 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
738 snd_device = SND_DEVICE_IN_VOICE_EARPIECE_MIC;
739 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
740 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
741 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100742 }
Andreas Schneider59486fa2017-02-06 09:16:39 +0100743
744 if (voice_session_uses_wideband(adev->voice.session)) {
745 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
746 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC_WB;
747 }
748
749 if (voice_session_uses_twomic(adev->voice.session)) {
750 if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
751 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
752 snd_device = SND_DEVICE_IN_VOICE_EARPIECE_MIC_WB;
753 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
754 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC_WB;
755 }
756 }
757 }
Andreas Schneider05bc1882017-02-09 14:03:11 +0100758
759 /* BT SCO */
760 if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
761 snd_device = SND_DEVICE_IN_VOICE_MIC;
762
763 if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
Fevax51bd12c2017-03-15 10:56:39 -0300764 if (voice_session_uses_wideband(adev->voice.session)) {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100765 snd_device = SND_DEVICE_IN_VOICE_BT_SCO_MIC_WB;
Fevax51bd12c2017-03-15 10:56:39 -0300766 } else {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100767 snd_device = SND_DEVICE_IN_VOICE_BT_SCO_MIC;
Fevax51bd12c2017-03-15 10:56:39 -0300768 }
Andreas Schneider05bc1882017-02-09 14:03:11 +0100769 } else if (voice_session_uses_twomic(adev->voice.session)) {
770 snd_device = SND_DEVICE_IN_VOICE_EARPIECE_MIC;
771 }
772 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100773 } else if (source == AUDIO_SOURCE_CAMCORDER) {
774 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
775 in_device & AUDIO_DEVICE_IN_BACK_MIC) {
776 snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
777 }
778 } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
779 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100780 if (snd_device == SND_DEVICE_NONE) {
781 snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
782 }
783 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
784 snd_device = SND_DEVICE_IN_VOICE_REC_HEADSET_MIC;
785 }
786 } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION || source == AUDIO_SOURCE_MIC) {
787 if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
788 in_device = AUDIO_DEVICE_IN_BACK_MIC;
789 if (active_input) {
790 if (active_input->enable_aec) {
791 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
792 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
793 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
794 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
795 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
796 } else {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100797 snd_device = SND_DEVICE_IN_EARPIECE_MIC_AEC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100798 }
799 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
800 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
801 }
802 }
803 /* TODO: set echo reference */
804 }
805 } else if (source == AUDIO_SOURCE_DEFAULT) {
806 goto exit;
807 }
808
809
810 if (snd_device != SND_DEVICE_NONE) {
811 goto exit;
812 }
813
814 if (in_device != AUDIO_DEVICE_NONE &&
815 !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
816 !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
817 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100818 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100819 } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
820 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
821 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
822 snd_device = SND_DEVICE_IN_HEADSET_MIC;
823 } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
824 snd_device = SND_DEVICE_IN_BT_SCO_MIC ;
825 } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
826 snd_device = SND_DEVICE_IN_HDMI_MIC;
827 } else {
828 ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100829 ALOGW("%s: Using default earpiece-mic", __func__);
830 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100831 }
832 } else {
833 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100834 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100835 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
836 snd_device = SND_DEVICE_IN_HEADSET_MIC;
837 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
838 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
839 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100840 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100841 } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
842 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
843 } else {
844 ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100845 ALOGW("%s: Using default earpiece-mic", __func__);
846 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100847 }
848 }
849exit:
850 ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
851 return snd_device;
852}
853
Andreas Schneider5a2f1002017-02-09 10:59:04 +0100854#if 0
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100855static int set_hdmi_channels(struct audio_device *adev, int channel_count)
856{
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100857 (void)adev;
858 (void)channel_count;
859 /* TODO */
860
861 return 0;
862}
863
864static int edid_get_max_channels(struct audio_device *adev)
865{
866 int max_channels = 2;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100867 (void)adev;
868
869 /* TODO */
870 return max_channels;
871}
Andreas Schneider5a2f1002017-02-09 10:59:04 +0100872#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100873
874/* Delay in Us */
875static int64_t render_latency(audio_usecase_t usecase)
876{
877 (void)usecase;
878 /* TODO */
879 return 0;
880}
881
882static int enable_snd_device(struct audio_device *adev,
883 struct audio_usecase *uc_info,
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100884 snd_device_t snd_device)
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100885{
886 struct mixer_card *mixer_card;
887 struct listnode *node;
888 const char *snd_device_name = get_snd_device_name(snd_device);
Andreas Schneider759368f2017-02-02 16:11:14 +0100889#ifdef DSP_POWEROFF_DELAY
890 struct timespec activation_time;
891 struct timespec elapsed_time;
892#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100893
894 if (snd_device_name == NULL)
895 return -EINVAL;
896
897 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES) {
898 ALOGV("Request to enable combo device: enable individual devices\n");
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100899 enable_snd_device(adev, uc_info, SND_DEVICE_OUT_SPEAKER);
900 enable_snd_device(adev, uc_info, SND_DEVICE_OUT_HEADPHONES);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100901 return 0;
902 }
903 adev->snd_dev_ref_cnt[snd_device]++;
904 if (adev->snd_dev_ref_cnt[snd_device] > 1) {
905 ALOGV("%s: snd_device(%d: %s) is already active",
906 __func__, snd_device, snd_device_name);
907 return 0;
908 }
909
910 ALOGV("%s: snd_device(%d: %s)", __func__,
911 snd_device, snd_device_name);
912
913 list_for_each(node, &uc_info->mixer_list) {
914 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]);
Andreas Schneider759368f2017-02-02 16:11:14 +0100915
916#ifdef DSP_POWEROFF_DELAY
917 clock_gettime(CLOCK_MONOTONIC, &activation_time);
918
Andreas Schneider58735a92017-02-13 16:48:17 +0100919 elapsed_time = time_spec_diff(activation_time,
920 mixer_card->dsp_poweroff_time);
Andreas Schneider759368f2017-02-02 16:11:14 +0100921 if (elapsed_time.tv_sec == 0) {
922 long elapsed_usec = elapsed_time.tv_nsec / 1000;
923
924 if (elapsed_usec < DSP_POWEROFF_DELAY) {
925 usleep(DSP_POWEROFF_DELAY - elapsed_usec);
926 }
927 }
Andreas Schneider759368f2017-02-02 16:11:14 +0100928#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +0200929
930 amplifier_enable_devices(snd_device, true);
931
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100932 audio_route_apply_and_update_path(mixer_card->audio_route, snd_device_name);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100933 }
934
935 return 0;
936}
937
Christopher N. Hesse757ac412017-01-28 14:42:48 +0100938int disable_snd_device(struct audio_device *adev,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100939 struct audio_usecase *uc_info,
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100940 snd_device_t snd_device)
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100941{
942 struct mixer_card *mixer_card;
943 struct listnode *node;
Christopher N. Hesse11ef2112018-02-02 23:19:42 +0100944 struct audio_usecase *out_uc_info = get_usecase_from_type(adev, PCM_PLAYBACK);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100945 const char *snd_device_name = get_snd_device_name(snd_device);
Christopher N. Hesse11ef2112018-02-02 23:19:42 +0100946 const char *out_snd_device_name = NULL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100947
948 if (snd_device_name == NULL)
949 return -EINVAL;
950
951 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES) {
952 ALOGV("Request to disable combo device: disable individual devices\n");
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100953 disable_snd_device(adev, uc_info, SND_DEVICE_OUT_SPEAKER);
954 disable_snd_device(adev, uc_info, SND_DEVICE_OUT_HEADPHONES);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100955 return 0;
956 }
957
958 if (adev->snd_dev_ref_cnt[snd_device] <= 0) {
959 ALOGE("%s: device ref cnt is already 0", __func__);
960 return -EINVAL;
961 }
962 adev->snd_dev_ref_cnt[snd_device]--;
963 if (adev->snd_dev_ref_cnt[snd_device] == 0) {
964 ALOGV("%s: snd_device(%d: %s)", __func__,
965 snd_device, snd_device_name);
966 list_for_each(node, &uc_info->mixer_list) {
967 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]);
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100968 audio_route_reset_and_update_path(mixer_card->audio_route, snd_device_name);
Christopher N. Hesse719630a2018-02-12 01:47:48 +0100969 if (snd_device > SND_DEVICE_IN_BEGIN && out_uc_info != NULL) {
Christopher N. Hesse11ef2112018-02-02 23:19:42 +0100970 /*
971 * Cycle the rx device to eliminate routing conflicts.
972 * This prevents issues when an input route shares mixer controls with an output
973 * route.
974 */
975 out_snd_device_name = get_snd_device_name(out_uc_info->out_snd_device);
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100976 audio_route_apply_and_update_path(mixer_card->audio_route, out_snd_device_name);
Andreas Schneider759368f2017-02-02 16:11:14 +0100977 }
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +0200978
979 amplifier_enable_devices(snd_device, false);
Andreas Schneider759368f2017-02-02 16:11:14 +0100980#ifdef DSP_POWEROFF_DELAY
981 clock_gettime(CLOCK_MONOTONIC, &(mixer_card->dsp_poweroff_time));
982#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100983 }
984 }
985 return 0;
986}
987
stenkinevgeniyb81e05f2018-05-08 12:02:35 +0000988static void check_and_route_usecases(struct audio_device *adev,
989 struct audio_usecase *uc_info,
990 usecase_type_t type,
991 snd_device_t snd_device)
992{
993 struct listnode *node;
994 struct audio_usecase *usecase;
995 bool switch_device[AUDIO_USECASE_MAX], need_switch = false;
996 snd_device_t usecase_snd_device = SND_DEVICE_NONE;
997 int i;
998
999 /*
1000 * This function is to make sure that all the usecases that are active on
1001 * the hardware codec backend are always routed to any one device that is
1002 * handled by the hardware codec.
1003 * For example, if low-latency and deep-buffer usecases are currently active
1004 * on speaker and out_set_parameters(headset) is received on low-latency
1005 * output, then we have to make sure deep-buffer is also switched to headset or
1006 * if audio-record and voice-call usecases are currently
1007 * active on speaker(rx) and speaker-mic (tx) and out_set_parameters(earpiece)
1008 * is received for voice call then we have to make sure that audio-record
1009 * usecase is also switched to earpiece i.e.
1010 * because of the limitation that both the devices cannot be enabled
1011 * at the same time as they share the same backend.
1012 */
1013 /* Disable all the usecases on the shared backend other than the
1014 specified usecase */
1015 for (i = 0; i < AUDIO_USECASE_MAX; i++)
1016 switch_device[i] = false;
1017
1018 list_for_each(node, &adev->usecase_list) {
1019 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
1020 if (usecase->type != type || usecase == uc_info)
1021 continue;
1022 usecase_snd_device = (type == PCM_PLAYBACK) ? usecase->out_snd_device :
1023 usecase->in_snd_device;
1024 if (usecase_snd_device != snd_device) {
1025 ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..",
1026 __func__, use_case_table[usecase->id],
1027 get_snd_device_name(usecase_snd_device));
1028 switch_device[usecase->id] = true;
1029 need_switch = true;
1030 }
1031 }
1032 if (need_switch) {
1033 list_for_each(node, &adev->usecase_list) {
1034 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
1035 usecase_snd_device = (type == PCM_PLAYBACK) ? usecase->out_snd_device :
1036 usecase->in_snd_device;
1037 if (switch_device[usecase->id]) {
1038 disable_snd_device(adev, usecase, usecase_snd_device);
1039 enable_snd_device(adev, usecase, snd_device);
1040 if (type == PCM_PLAYBACK)
1041 usecase->out_snd_device = snd_device;
1042 else
1043 usecase->in_snd_device = snd_device;
1044 }
1045 }
1046 }
1047}
1048
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001049static int select_devices(struct audio_device *adev,
1050 audio_usecase_t uc_id)
1051{
1052 snd_device_t out_snd_device = SND_DEVICE_NONE;
1053 snd_device_t in_snd_device = SND_DEVICE_NONE;
1054 struct audio_usecase *usecase = NULL;
1055 struct audio_usecase *vc_usecase = NULL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001056 struct stream_in *active_input = NULL;
1057 struct stream_out *active_out;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001058
1059 ALOGV("%s: usecase(%d)", __func__, uc_id);
1060
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001061 usecase = get_usecase_from_type(adev, PCM_CAPTURE|VOICE_CALL);
1062 if (usecase != NULL) {
1063 active_input = (struct stream_in *)usecase->stream;
1064 }
1065
1066 usecase = get_usecase_from_id(adev, uc_id);
1067 if (usecase == NULL) {
1068 ALOGE("%s: Could not find the usecase(%d)", __func__, uc_id);
1069 return -EINVAL;
1070 }
1071 active_out = (struct stream_out *)usecase->stream;
1072
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001073
1074 /*
1075 * If the voice call is active, use the sound devices of voice call usecase
1076 * so that it would not result any device switch. All the usecases will
1077 * be switched to new device when select_devices() is called for voice call
1078 * usecase.
1079 */
1080 if (usecase->type != VOICE_CALL && adev->voice.in_call) {
1081 vc_usecase = get_usecase_from_id(adev, USECASE_VOICE_CALL);
1082 if (vc_usecase == NULL) {
1083 ALOGE("%s: Could not find the voice call usecase", __func__);
1084 } else {
Christopher N. Hesse77880a22017-11-17 20:27:50 +01001085 ALOGV("%s: in call, reusing devices (rx: %s, tx: %s)", __func__,
1086 get_snd_device_display_name(vc_usecase->out_snd_device),
1087 get_snd_device_display_name(vc_usecase->in_snd_device));
1088 usecase->devices = vc_usecase->devices;
1089 return 0;
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001090 }
1091 }
1092
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001093 if (usecase->type == VOICE_CALL) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001094 usecase->devices = active_out->devices;
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001095 prepare_voice_session(adev->voice.session, active_out->devices);
1096 out_snd_device = get_output_snd_device(adev, active_out->devices);
1097 in_snd_device = get_input_snd_device(adev, active_out->devices);
1098 } else if (usecase->type == PCM_PLAYBACK) {
1099 usecase->devices = active_out->devices;
1100 in_snd_device = SND_DEVICE_NONE;
1101 if (out_snd_device == SND_DEVICE_NONE) {
1102 out_snd_device = get_output_snd_device(adev, active_out->devices);
1103 if (active_out == adev->primary_output &&
1104 active_input &&
1105 active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
1106 select_devices(adev, active_input->usecase);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001107 }
1108 }
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001109 } else if (usecase->type == PCM_CAPTURE) {
1110 usecase->devices = ((struct stream_in *)usecase->stream)->devices;
1111 out_snd_device = SND_DEVICE_NONE;
1112 if (in_snd_device == SND_DEVICE_NONE) {
1113 if (active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
1114 adev->primary_output && !adev->primary_output->standby) {
1115 in_snd_device = get_input_snd_device(adev, adev->primary_output->devices);
1116 } else {
1117 in_snd_device = get_input_snd_device(adev, AUDIO_DEVICE_NONE);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001118 }
1119 }
1120 }
1121
1122 if (out_snd_device == usecase->out_snd_device &&
1123 in_snd_device == usecase->in_snd_device) {
1124 return 0;
1125 }
1126
1127 ALOGV("%s: out_snd_device(%d: %s) in_snd_device(%d: %s)", __func__,
1128 out_snd_device, get_snd_device_display_name(out_snd_device),
1129 in_snd_device, get_snd_device_display_name(in_snd_device));
1130
1131
1132 /* Disable current sound devices */
1133 if (usecase->out_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001134 disable_snd_device(adev, usecase, usecase->out_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001135 }
1136
1137 if (usecase->in_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001138 disable_snd_device(adev, usecase, usecase->in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001139 }
1140
1141 /* Enable new sound devices */
1142 if (out_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse696959d2017-02-02 20:49:55 +01001143 /* We need to update the audio path if we switch the out devices */
1144 if (adev->voice.in_call) {
1145 set_voice_session_audio_path(adev->voice.session);
1146 }
1147
stenkinevgeniyb81e05f2018-05-08 12:02:35 +00001148 check_and_route_usecases(adev, usecase, PCM_PLAYBACK, out_snd_device);
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001149 enable_snd_device(adev, usecase, out_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001150 }
1151
1152 if (in_snd_device != SND_DEVICE_NONE) {
stenkinevgeniyb81e05f2018-05-08 12:02:35 +00001153 check_and_route_usecases(adev, usecase, PCM_CAPTURE, in_snd_device);
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001154 enable_snd_device(adev, usecase, in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001155 }
1156
1157 usecase->in_snd_device = in_snd_device;
1158 usecase->out_snd_device = out_snd_device;
1159
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02001160 /* Rely on amplifier_set_devices to distinguish between in/out devices */
1161 amplifier_set_input_devices(in_snd_device);
1162 amplifier_set_output_devices(out_snd_device);
1163
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001164 return 0;
1165}
1166
1167
1168static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames);
1169static int do_in_standby_l(struct stream_in *in);
1170
1171#ifdef PREPROCESSING_ENABLED
1172static void get_capture_reference_delay(struct stream_in *in,
1173 size_t frames __unused,
1174 struct echo_reference_buffer *buffer)
1175{
1176 ALOGVV("%s: enter:)", __func__);
1177
1178 /* read frames available in kernel driver buffer */
1179 unsigned int kernel_frames;
1180 struct timespec tstamp;
1181 long buf_delay;
1182 long kernel_delay;
1183 long delay_ns;
1184 struct pcm_device *ref_device;
1185 long rsmp_delay = 0;
1186
1187 ref_device = node_to_item(list_tail(&in->pcm_dev_list),
1188 struct pcm_device, stream_list_node);
1189
1190 if (pcm_get_htimestamp(ref_device->pcm, &kernel_frames, &tstamp) < 0) {
1191 buffer->time_stamp.tv_sec = 0;
1192 buffer->time_stamp.tv_nsec = 0;
1193 buffer->delay_ns = 0;
1194 ALOGW("read get_capture_reference_delay(): pcm_htimestamp error");
1195 return;
1196 }
1197
1198 /* adjust render time stamp with delay added by current driver buffer.
1199 * Add the duration of current frame as we want the render time of the last
1200 * sample being written. */
1201
1202 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / ref_device->pcm_profile->config.rate);
1203
1204 buffer->time_stamp = tstamp;
1205 buffer->delay_ns = kernel_delay;
1206
1207 ALOGVV("get_capture_reference_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5d],"
1208 " delay_ns: [%d] , frames:[%zd]",
1209 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns, frames);
1210}
1211
1212static void get_capture_delay(struct stream_in *in,
1213 size_t frames __unused,
1214 struct echo_reference_buffer *buffer)
1215{
1216 ALOGVV("%s: enter:)", __func__);
1217 /* read frames available in kernel driver buffer */
1218 unsigned int kernel_frames;
1219 struct timespec tstamp;
1220 long buf_delay;
1221 long rsmp_delay;
1222 long kernel_delay;
1223 long delay_ns;
1224 struct pcm_device *pcm_device;
1225
1226 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1227 struct pcm_device, stream_list_node);
1228
1229 if (pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &tstamp) < 0) {
1230 buffer->time_stamp.tv_sec = 0;
1231 buffer->time_stamp.tv_nsec = 0;
1232 buffer->delay_ns = 0;
1233 ALOGW("read get_capture_delay(): pcm_htimestamp error");
1234 return;
1235 }
1236
1237 /* read frames available in audio HAL input buffer
1238 * add number of frames being read as we want the capture time of first sample
1239 * in current buffer */
1240 /* frames in in->read_buf are at driver sampling rate while frames in in->proc_buf are
1241 * at requested sampling rate */
1242 buf_delay = (long)(((int64_t)(in->read_buf_frames) * 1000000000) / in->config.rate +
1243 ((int64_t)(in->proc_buf_frames) * 1000000000) / in->requested_rate );
1244
1245 /* add delay introduced by resampler */
1246 rsmp_delay = 0;
1247 if (in->resampler) {
1248 rsmp_delay = in->resampler->delay_ns(in->resampler);
1249 }
1250
1251 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / in->config.rate);
1252
1253 delay_ns = kernel_delay + buf_delay + rsmp_delay;
1254
1255 buffer->time_stamp = tstamp;
1256 buffer->delay_ns = delay_ns;
1257 ALOGVV("get_capture_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames:[%5d],"
1258 " delay_ns: [%d], kernel_delay:[%ld], buf_delay:[%ld], rsmp_delay:[%ld], "
1259 "in->read_buf_frames:[%zd], in->proc_buf_frames:[%zd], frames:[%zd]",
1260 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames,
1261 buffer->delay_ns, kernel_delay, buf_delay, rsmp_delay,
1262 in->read_buf_frames, in->proc_buf_frames, frames);
1263}
1264
1265static int32_t update_echo_reference(struct stream_in *in, size_t frames)
1266{
1267 ALOGVV("%s: enter:), in->config.channels(%d)", __func__,in->config.channels);
1268 struct echo_reference_buffer b;
1269 b.delay_ns = 0;
1270 struct pcm_device *pcm_device;
1271
1272 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1273 struct pcm_device, stream_list_node);
1274
1275 ALOGVV("update_echo_reference, in->config.channels(%d), frames = [%zd], in->ref_buf_frames = [%zd], "
1276 "b.frame_count = [%zd]",
1277 in->config.channels, frames, in->ref_buf_frames, frames - in->ref_buf_frames);
1278 if (in->ref_buf_frames < frames) {
1279 if (in->ref_buf_size < frames) {
1280 in->ref_buf_size = frames;
1281 in->ref_buf = (int16_t *)realloc(in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1282 ALOG_ASSERT((in->ref_buf != NULL),
1283 "update_echo_reference() failed to reallocate ref_buf");
1284 ALOGVV("update_echo_reference(): ref_buf %p extended to %d bytes",
1285 in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1286 }
1287 b.frame_count = frames - in->ref_buf_frames;
1288 b.raw = (void *)(in->ref_buf + in->ref_buf_frames * in->config.channels);
1289
1290 get_capture_delay(in, frames, &b);
1291
1292 if (in->echo_reference->read(in->echo_reference, &b) == 0)
1293 {
1294 in->ref_buf_frames += b.frame_count;
1295 ALOGVV("update_echo_reference(): in->ref_buf_frames:[%zd], "
1296 "in->ref_buf_size:[%zd], frames:[%zd], b.frame_count:[%zd]",
1297 in->ref_buf_frames, in->ref_buf_size, frames, b.frame_count);
1298 }
1299 } else
1300 ALOGW("update_echo_reference(): NOT enough frames to read ref buffer");
1301 return b.delay_ns;
1302}
1303
1304static int set_preprocessor_param(effect_handle_t handle,
1305 effect_param_t *param)
1306{
1307 uint32_t size = sizeof(int);
1308 uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
1309 param->vsize;
1310
1311 int status = (*handle)->command(handle,
1312 EFFECT_CMD_SET_PARAM,
1313 sizeof (effect_param_t) + psize,
1314 param,
1315 &size,
1316 &param->status);
1317 if (status == 0)
1318 status = param->status;
1319
1320 return status;
1321}
1322
1323static int set_preprocessor_echo_delay(effect_handle_t handle,
1324 int32_t delay_us)
1325{
1326 struct {
1327 effect_param_t param;
1328 uint32_t data_0;
1329 int32_t data_1;
1330 } buf;
1331 memset(&buf, 0, sizeof(buf));
1332
1333 buf.param.psize = sizeof(uint32_t);
1334 buf.param.vsize = sizeof(uint32_t);
1335 buf.data_0 = AEC_PARAM_ECHO_DELAY;
1336 buf.data_1 = delay_us;
1337
1338 return set_preprocessor_param(handle, &buf.param);
1339}
1340
1341static void push_echo_reference(struct stream_in *in, size_t frames)
1342{
1343 ALOGVV("%s: enter:)", __func__);
1344 /* read frames from echo reference buffer and update echo delay
1345 * in->ref_buf_frames is updated with frames available in in->ref_buf */
1346
1347 int32_t delay_us = update_echo_reference(in, frames)/1000;
1348 int32_t size_in_bytes = 0;
1349 int i;
1350 audio_buffer_t buf;
1351
1352 if (in->ref_buf_frames < frames)
1353 frames = in->ref_buf_frames;
1354
1355 buf.frameCount = frames;
1356 buf.raw = in->ref_buf;
1357
1358 for (i = 0; i < in->num_preprocessors; i++) {
1359 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1360 continue;
1361 ALOGVV("%s: effect_itfe)->process_reverse() BEGIN i=(%d) ", __func__, i);
1362 (*in->preprocessors[i].effect_itfe)->process_reverse(in->preprocessors[i].effect_itfe,
1363 &buf,
1364 NULL);
1365 ALOGVV("%s: effect_itfe)->process_reverse() END i=(%d) ", __func__, i);
1366 set_preprocessor_echo_delay(in->preprocessors[i].effect_itfe, delay_us);
1367 }
1368
1369 in->ref_buf_frames -= buf.frameCount;
1370 ALOGVV("%s: in->ref_buf_frames(%zd), in->config.channels(%d) ",
1371 __func__, in->ref_buf_frames, in->config.channels);
1372 if (in->ref_buf_frames) {
1373 memcpy(in->ref_buf,
1374 in->ref_buf + buf.frameCount * in->config.channels,
1375 in->ref_buf_frames * in->config.channels * sizeof(int16_t));
1376 }
1377}
1378
1379static void put_echo_reference(struct audio_device *adev,
1380 struct echo_reference_itfe *reference)
1381{
1382 ALOGV("%s: enter:)", __func__);
1383 int32_t prev_generation = adev->echo_reference_generation;
1384 struct stream_out *out = adev->primary_output;
1385
1386 if (adev->echo_reference != NULL &&
1387 reference == adev->echo_reference) {
1388 /* echo reference is taken from the low latency output stream used
1389 * for voice use cases */
1390 adev->echo_reference = NULL;
1391 android_atomic_inc(&adev->echo_reference_generation);
1392 if (out != NULL && out->usecase == USECASE_AUDIO_PLAYBACK) {
1393 // if the primary output is in standby or did not pick the echo reference yet
1394 // we can safely get rid of it here.
1395 // otherwise, out_write() or out_standby() will detect the change in echo reference
1396 // generation and release the echo reference owned by the stream.
1397 if ((out->echo_reference_generation != prev_generation) || out->standby)
1398 release_echo_reference(reference);
1399 } else {
1400 release_echo_reference(reference);
1401 }
1402 ALOGV("release_echo_reference");
1403 }
1404}
1405
1406static struct echo_reference_itfe *get_echo_reference(struct audio_device *adev,
1407 audio_format_t format __unused,
1408 uint32_t channel_count,
1409 uint32_t sampling_rate)
1410{
1411 ALOGV("%s: enter:)", __func__);
1412 put_echo_reference(adev, adev->echo_reference);
1413 /* echo reference is taken from the low latency output stream used
1414 * for voice use cases */
1415 if (adev->primary_output!= NULL && adev->primary_output->usecase == USECASE_AUDIO_PLAYBACK &&
1416 !adev->primary_output->standby) {
1417 struct audio_stream *stream =
1418 &adev->primary_output->stream.common;
1419 uint32_t wr_channel_count = audio_channel_count_from_out_mask(stream->get_channels(stream));
1420 uint32_t wr_sampling_rate = stream->get_sample_rate(stream);
1421 ALOGV("Calling create_echo_reference");
1422 int status = create_echo_reference(AUDIO_FORMAT_PCM_16_BIT,
1423 channel_count,
1424 sampling_rate,
1425 AUDIO_FORMAT_PCM_16_BIT,
1426 wr_channel_count,
1427 wr_sampling_rate,
1428 &adev->echo_reference);
1429 if (status == 0)
1430 android_atomic_inc(&adev->echo_reference_generation);
1431 }
1432 return adev->echo_reference;
1433}
1434
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001435static int get_playback_delay(struct stream_out *out,
1436 size_t frames,
1437 struct echo_reference_buffer *buffer)
1438{
1439 unsigned int kernel_frames;
1440 int status;
1441 int primary_pcm = 0;
1442 struct pcm_device *pcm_device;
1443
1444 pcm_device = node_to_item(list_head(&out->pcm_dev_list),
1445 struct pcm_device, stream_list_node);
1446
1447 status = pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &buffer->time_stamp);
1448 if (status < 0) {
1449 buffer->time_stamp.tv_sec = 0;
1450 buffer->time_stamp.tv_nsec = 0;
1451 buffer->delay_ns = 0;
1452 ALOGV("get_playback_delay(): pcm_get_htimestamp error,"
1453 "setting playbackTimestamp to 0");
1454 return status;
1455 }
1456
1457 kernel_frames = pcm_get_buffer_size(pcm_device->pcm) - kernel_frames;
1458
1459 /* adjust render time stamp with delay added by current driver buffer.
1460 * Add the duration of current frame as we want the render time of the last
1461 * sample being written. */
1462 buffer->delay_ns = (long)(((int64_t)(kernel_frames + frames)* 1000000000)/
1463 out->config.rate);
1464 ALOGVV("get_playback_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5u], delay_ns: [%d],",
1465 buffer->time_stamp.tv_sec, buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns);
1466
1467 return 0;
1468}
1469
1470#define GET_COMMAND_STATUS(status, fct_status, cmd_status) \
1471 do { \
1472 if (fct_status != 0) \
1473 status = fct_status; \
1474 else if (cmd_status != 0) \
1475 status = cmd_status; \
1476 } while(0)
1477
1478static int in_configure_reverse(struct stream_in *in)
1479{
1480 int32_t cmd_status;
1481 uint32_t size = sizeof(int);
1482 effect_config_t config;
1483 int32_t status = 0;
1484 int32_t fct_status = 0;
1485 int i;
1486 ALOGV("%s: enter: in->num_preprocessors(%d)", __func__, in->num_preprocessors);
1487 if (in->num_preprocessors > 0) {
1488 config.inputCfg.channels = in->main_channels;
1489 config.outputCfg.channels = in->main_channels;
1490 config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1491 config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1492 config.inputCfg.samplingRate = in->requested_rate;
1493 config.outputCfg.samplingRate = in->requested_rate;
1494 config.inputCfg.mask =
1495 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1496 config.outputCfg.mask =
1497 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1498
1499 for (i = 0; i < in->num_preprocessors; i++)
1500 {
1501 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1502 continue;
1503 fct_status = (*(in->preprocessors[i].effect_itfe))->command(
1504 in->preprocessors[i].effect_itfe,
1505 EFFECT_CMD_SET_CONFIG_REVERSE,
1506 sizeof(effect_config_t),
1507 &config,
1508 &size,
1509 &cmd_status);
1510 ALOGV("%s: calling EFFECT_CMD_SET_CONFIG_REVERSE",__func__);
1511 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1512 }
1513 }
1514 return status;
1515}
1516
1517#define MAX_NUM_CHANNEL_CONFIGS 10
1518
1519static void in_read_audio_effect_channel_configs(struct stream_in *in __unused,
1520 struct effect_info_s *effect_info)
1521{
1522 /* size and format of the cmd are defined in hardware/audio_effect.h */
1523 effect_handle_t effect = effect_info->effect_itfe;
1524 uint32_t cmd_size = 2 * sizeof(uint32_t);
1525 uint32_t cmd[] = { EFFECT_FEATURE_AUX_CHANNELS, MAX_NUM_CHANNEL_CONFIGS };
1526 /* reply = status + number of configs (n) + n x channel_config_t */
1527 uint32_t reply_size =
1528 2 * sizeof(uint32_t) + (MAX_NUM_CHANNEL_CONFIGS * sizeof(channel_config_t));
1529 int32_t reply[reply_size];
1530 int32_t cmd_status;
1531
1532 ALOG_ASSERT((effect_info->num_channel_configs == 0),
1533 "in_read_audio_effect_channel_configs() num_channel_configs not cleared");
1534 ALOG_ASSERT((effect_info->channel_configs == NULL),
1535 "in_read_audio_effect_channel_configs() channel_configs not cleared");
1536
1537 /* if this command is not supported, then the effect is supposed to return -EINVAL.
1538 * This error will be interpreted as if the effect supports the main_channels but does not
1539 * support any aux_channels */
1540 cmd_status = (*effect)->command(effect,
1541 EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS,
1542 cmd_size,
1543 (void*)&cmd,
1544 &reply_size,
1545 (void*)&reply);
1546
1547 if (cmd_status != 0) {
1548 ALOGV("in_read_audio_effect_channel_configs(): "
1549 "fx->command returned %d", cmd_status);
1550 return;
1551 }
1552
1553 if (reply[0] != 0) {
1554 ALOGW("in_read_audio_effect_channel_configs(): "
1555 "command EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS error %d num configs %d",
1556 reply[0], (reply[0] == -ENOMEM) ? reply[1] : MAX_NUM_CHANNEL_CONFIGS);
1557 return;
1558 }
1559
1560 /* the feature is not supported */
1561 ALOGV("in_read_audio_effect_channel_configs()(): "
1562 "Feature supported and adding %d channel configs to the list", reply[1]);
1563 effect_info->num_channel_configs = reply[1];
1564 effect_info->channel_configs =
1565 (channel_config_t *) malloc(sizeof(channel_config_t) * reply[1]); /* n x configs */
1566 memcpy(effect_info->channel_configs, (reply + 2), sizeof(channel_config_t) * reply[1]);
1567}
1568
1569
1570#define NUM_IN_AUX_CNL_CONFIGS 2
1571static const channel_config_t in_aux_cnl_configs[NUM_IN_AUX_CNL_CONFIGS] = {
1572 { AUDIO_CHANNEL_IN_FRONT , AUDIO_CHANNEL_IN_BACK},
1573 { AUDIO_CHANNEL_IN_STEREO , AUDIO_CHANNEL_IN_RIGHT}
1574};
1575static uint32_t in_get_aux_channels(struct stream_in *in)
1576{
1577 int i;
1578 channel_config_t new_chcfg = {0, 0};
1579
1580 if (in->num_preprocessors == 0)
1581 return 0;
1582
1583 /* do not enable dual mic configurations when capturing from other microphones than
1584 * main or sub */
1585 if (!(in->devices & (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_BACK_MIC)))
1586 return 0;
1587
1588 /* retain most complex aux channels configuration compatible with requested main channels and
1589 * supported by audio driver and all pre processors */
1590 for (i = 0; i < NUM_IN_AUX_CNL_CONFIGS; i++) {
1591 const channel_config_t *cur_chcfg = &in_aux_cnl_configs[i];
1592 if (cur_chcfg->main_channels == in->main_channels) {
1593 size_t match_cnt;
1594 size_t idx_preproc;
1595 for (idx_preproc = 0, match_cnt = 0;
1596 /* no need to continue if at least one preprocessor doesn't match */
1597 idx_preproc < (size_t)in->num_preprocessors && match_cnt == idx_preproc;
1598 idx_preproc++) {
1599 struct effect_info_s *effect_info = &in->preprocessors[idx_preproc];
1600 size_t idx_chcfg;
1601
1602 for (idx_chcfg = 0; idx_chcfg < effect_info->num_channel_configs; idx_chcfg++) {
1603 if (memcmp(effect_info->channel_configs + idx_chcfg,
1604 cur_chcfg,
1605 sizeof(channel_config_t)) == 0) {
1606 match_cnt++;
1607 break;
1608 }
1609 }
1610 }
1611 /* if all preprocessors match, we have a candidate */
1612 if (match_cnt == (size_t)in->num_preprocessors) {
1613 /* retain most complex aux channels configuration */
1614 if (audio_channel_count_from_in_mask(cur_chcfg->aux_channels) > audio_channel_count_from_in_mask(new_chcfg.aux_channels)) {
1615 new_chcfg = *cur_chcfg;
1616 }
1617 }
1618 }
1619 }
1620
1621 ALOGV("in_get_aux_channels(): return %04x", new_chcfg.aux_channels);
1622
1623 return new_chcfg.aux_channels;
1624}
1625
1626static int in_configure_effect_channels(effect_handle_t effect,
1627 channel_config_t *channel_config)
1628{
1629 int status = 0;
1630 int fct_status;
1631 int32_t cmd_status;
1632 uint32_t reply_size;
1633 effect_config_t config;
1634 uint32_t cmd[(sizeof(uint32_t) + sizeof(channel_config_t) - 1) / sizeof(uint32_t) + 1];
1635
1636 ALOGV("in_configure_effect_channels(): configure effect with channels: [%04x][%04x]",
1637 channel_config->main_channels,
1638 channel_config->aux_channels);
1639
1640 config.inputCfg.mask = EFFECT_CONFIG_CHANNELS;
1641 config.outputCfg.mask = EFFECT_CONFIG_CHANNELS;
1642 reply_size = sizeof(effect_config_t);
1643 fct_status = (*effect)->command(effect,
1644 EFFECT_CMD_GET_CONFIG,
1645 0,
1646 NULL,
1647 &reply_size,
1648 &config);
1649 if (fct_status != 0) {
1650 ALOGE("in_configure_effect_channels(): EFFECT_CMD_GET_CONFIG failed");
1651 return fct_status;
1652 }
1653
1654 config.inputCfg.channels = channel_config->main_channels | channel_config->aux_channels;
1655 config.outputCfg.channels = config.inputCfg.channels;
1656 reply_size = sizeof(uint32_t);
1657 fct_status = (*effect)->command(effect,
1658 EFFECT_CMD_SET_CONFIG,
1659 sizeof(effect_config_t),
1660 &config,
1661 &reply_size,
1662 &cmd_status);
1663 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1664
1665 cmd[0] = EFFECT_FEATURE_AUX_CHANNELS;
1666 memcpy(cmd + 1, channel_config, sizeof(channel_config_t));
1667 reply_size = sizeof(uint32_t);
1668 fct_status = (*effect)->command(effect,
1669 EFFECT_CMD_SET_FEATURE_CONFIG,
1670 sizeof(cmd), //sizeof(uint32_t) + sizeof(channel_config_t),
1671 cmd,
1672 &reply_size,
1673 &cmd_status);
1674 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1675
1676 /* some implementations need to be re-enabled after a config change */
1677 reply_size = sizeof(uint32_t);
1678 fct_status = (*effect)->command(effect,
1679 EFFECT_CMD_ENABLE,
1680 0,
1681 NULL,
1682 &reply_size,
1683 &cmd_status);
1684 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1685
1686 return status;
1687}
1688
1689static int in_reconfigure_channels(struct stream_in *in,
1690 effect_handle_t effect,
1691 channel_config_t *channel_config,
1692 bool config_changed) {
1693
1694 int status = 0;
1695
1696 ALOGV("in_reconfigure_channels(): config_changed %d effect %p",
1697 config_changed, effect);
1698
1699 /* if config changed, reconfigure all previously added effects */
1700 if (config_changed) {
1701 int i;
1702 ALOGV("%s: config_changed (%d)", __func__, config_changed);
1703 for (i = 0; i < in->num_preprocessors; i++)
1704 {
1705 int cur_status = in_configure_effect_channels(in->preprocessors[i].effect_itfe,
1706 channel_config);
1707 ALOGV("%s: in_configure_effect_channels i=(%d), [main_channel,aux_channel]=[%d|%d], status=%d",
1708 __func__, i, channel_config->main_channels, channel_config->aux_channels, cur_status);
1709 if (cur_status != 0) {
1710 ALOGV("in_reconfigure_channels(): error %d configuring effect "
1711 "%d with channels: [%04x][%04x]",
1712 cur_status,
1713 i,
1714 channel_config->main_channels,
1715 channel_config->aux_channels);
1716 status = cur_status;
1717 }
1718 }
1719 } else if (effect != NULL && channel_config->aux_channels) {
1720 /* if aux channels config did not change but aux channels are present,
1721 * we still need to configure the effect being added */
1722 status = in_configure_effect_channels(effect, channel_config);
1723 }
1724 return status;
1725}
1726
1727static void in_update_aux_channels(struct stream_in *in,
1728 effect_handle_t effect)
1729{
1730 uint32_t aux_channels;
1731 channel_config_t channel_config;
1732 int status;
1733
1734 aux_channels = in_get_aux_channels(in);
1735
1736 channel_config.main_channels = in->main_channels;
1737 channel_config.aux_channels = aux_channels;
1738 status = in_reconfigure_channels(in,
1739 effect,
1740 &channel_config,
1741 (aux_channels != in->aux_channels));
1742
1743 if (status != 0) {
1744 ALOGV("in_update_aux_channels(): in_reconfigure_channels error %d", status);
1745 /* resetting aux channels configuration */
1746 aux_channels = 0;
1747 channel_config.aux_channels = 0;
1748 in_reconfigure_channels(in, effect, &channel_config, true);
1749 }
1750 ALOGV("%s: aux_channels=%d, in->aux_channels_changed=%d", __func__, aux_channels, in->aux_channels_changed);
1751 if (in->aux_channels != aux_channels) {
1752 in->aux_channels_changed = true;
1753 in->aux_channels = aux_channels;
1754 do_in_standby_l(in);
1755 }
1756}
1757#endif
1758
1759/* This function reads PCM data and:
1760 * - resample if needed
1761 * - process if pre-processors are attached
1762 * - discard unwanted channels
1763 */
1764static ssize_t read_and_process_frames(struct stream_in *in, void* buffer, ssize_t frames)
1765{
1766 ssize_t frames_wr = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001767 size_t src_channels = in->config.channels;
1768 size_t dst_channels = audio_channel_count_from_in_mask(in->main_channels);
1769 int i;
1770 void *proc_buf_out;
1771 struct pcm_device *pcm_device;
1772 bool has_additional_channels = (dst_channels != src_channels) ? true : false;
1773#ifdef PREPROCESSING_ENABLED
Andreas Schneider5a2f1002017-02-09 10:59:04 +01001774 audio_buffer_t in_buf;
1775 audio_buffer_t out_buf;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001776 bool has_processing = (in->num_preprocessors != 0) ? true : false;
1777#endif
1778
1779 /* Additional channels might be added on top of main_channels:
1780 * - aux_channels (by processing effects)
1781 * - extra channels due to HW limitations
1782 * In case of additional channels, we cannot work inplace
1783 */
1784 if (has_additional_channels)
1785 proc_buf_out = in->proc_buf_out;
1786 else
1787 proc_buf_out = buffer;
1788
1789 if (list_empty(&in->pcm_dev_list)) {
1790 ALOGE("%s: pcm device list empty", __func__);
1791 return -EINVAL;
1792 }
1793
1794 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1795 struct pcm_device, stream_list_node);
1796
1797#ifdef PREPROCESSING_ENABLED
1798 if (has_processing) {
1799 /* since all the processing below is done in frames and using the config.channels
1800 * as the number of channels, no changes is required in case aux_channels are present */
1801 while (frames_wr < frames) {
1802 /* first reload enough frames at the end of process input buffer */
1803 if (in->proc_buf_frames < (size_t)frames) {
1804 ssize_t frames_rd;
1805 if (in->proc_buf_size < (size_t)frames) {
1806 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1807 in->proc_buf_size = (size_t)frames;
1808 in->proc_buf_in = (int16_t *)realloc(in->proc_buf_in, size_in_bytes);
1809 ALOG_ASSERT((in->proc_buf_in != NULL),
1810 "process_frames() failed to reallocate proc_buf_in");
1811 if (has_additional_channels) {
1812 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1813 ALOG_ASSERT((in->proc_buf_out != NULL),
1814 "process_frames() failed to reallocate proc_buf_out");
1815 proc_buf_out = in->proc_buf_out;
1816 }
1817 }
1818 frames_rd = read_frames(in,
1819 in->proc_buf_in +
1820 in->proc_buf_frames * in->config.channels,
1821 frames - in->proc_buf_frames);
1822 if (frames_rd < 0) {
1823 /* Return error code */
1824 frames_wr = frames_rd;
1825 break;
1826 }
1827 in->proc_buf_frames += frames_rd;
1828 }
1829
1830 if (in->echo_reference != NULL) {
1831 push_echo_reference(in, in->proc_buf_frames);
1832 }
1833
1834 /* in_buf.frameCount and out_buf.frameCount indicate respectively
1835 * the maximum number of frames to be consumed and produced by process() */
1836 in_buf.frameCount = in->proc_buf_frames;
1837 in_buf.s16 = in->proc_buf_in;
1838 out_buf.frameCount = frames - frames_wr;
1839 out_buf.s16 = (int16_t *)proc_buf_out + frames_wr * in->config.channels;
1840
1841 /* FIXME: this works because of current pre processing library implementation that
1842 * does the actual process only when the last enabled effect process is called.
1843 * The generic solution is to have an output buffer for each effect and pass it as
1844 * input to the next.
1845 */
1846 for (i = 0; i < in->num_preprocessors; i++) {
1847 (*in->preprocessors[i].effect_itfe)->process(in->preprocessors[i].effect_itfe,
1848 &in_buf,
1849 &out_buf);
1850 }
1851
1852 /* process() has updated the number of frames consumed and produced in
1853 * in_buf.frameCount and out_buf.frameCount respectively
1854 * move remaining frames to the beginning of in->proc_buf_in */
1855 in->proc_buf_frames -= in_buf.frameCount;
1856
1857 if (in->proc_buf_frames) {
1858 memcpy(in->proc_buf_in,
1859 in->proc_buf_in + in_buf.frameCount * in->config.channels,
1860 in->proc_buf_frames * in->config.channels * sizeof(int16_t));
1861 }
1862
1863 /* if not enough frames were passed to process(), read more and retry. */
1864 if (out_buf.frameCount == 0) {
1865 ALOGW("No frames produced by preproc");
1866 continue;
1867 }
1868
1869 if ((frames_wr + (ssize_t)out_buf.frameCount) <= frames) {
1870 frames_wr += out_buf.frameCount;
1871 } else {
1872 /* The effect does not comply to the API. In theory, we should never end up here! */
1873 ALOGE("preprocessing produced too many frames: %d + %zd > %d !",
1874 (unsigned int)frames_wr, out_buf.frameCount, (unsigned int)frames);
1875 frames_wr = frames;
1876 }
1877 }
1878 }
1879 else
1880#endif //PREPROCESSING_ENABLED
1881 {
1882 /* No processing effects attached */
1883 if (has_additional_channels) {
1884 /* With additional channels, we cannot use original buffer */
1885 if (in->proc_buf_size < (size_t)frames) {
1886 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1887 in->proc_buf_size = (size_t)frames;
1888 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1889 ALOG_ASSERT((in->proc_buf_out != NULL),
1890 "process_frames() failed to reallocate proc_buf_out");
1891 proc_buf_out = in->proc_buf_out;
1892 }
1893 }
1894 frames_wr = read_frames(in, proc_buf_out, frames);
1895 }
1896
1897 /* Remove all additional channels that have been added on top of main_channels:
1898 * - aux_channels
1899 * - extra channels from HW due to HW limitations
1900 * Assumption is made that the channels are interleaved and that the main
1901 * channels are first. */
1902
1903 if (has_additional_channels)
1904 {
1905 int16_t* src_buffer = (int16_t *)proc_buf_out;
1906 int16_t* dst_buffer = (int16_t *)buffer;
1907
1908 if (dst_channels == 1) {
1909 for (i = frames_wr; i > 0; i--)
1910 {
1911 *dst_buffer++ = *src_buffer;
1912 src_buffer += src_channels;
1913 }
1914 } else {
1915 for (i = frames_wr; i > 0; i--)
1916 {
1917 memcpy(dst_buffer, src_buffer, dst_channels*sizeof(int16_t));
1918 dst_buffer += dst_channels;
1919 src_buffer += src_channels;
1920 }
1921 }
1922 }
1923
1924 return frames_wr;
1925}
1926
1927static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
1928 struct resampler_buffer* buffer)
1929{
1930 struct stream_in *in;
1931 struct pcm_device *pcm_device;
1932
1933 if (buffer_provider == NULL || buffer == NULL)
1934 return -EINVAL;
1935
1936 in = (struct stream_in *)((char *)buffer_provider -
1937 offsetof(struct stream_in, buf_provider));
1938
1939 if (list_empty(&in->pcm_dev_list)) {
1940 buffer->raw = NULL;
1941 buffer->frame_count = 0;
1942 in->read_status = -ENODEV;
1943 return -ENODEV;
1944 }
1945
1946 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1947 struct pcm_device, stream_list_node);
1948
1949 if (in->read_buf_frames == 0) {
1950 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, in->config.period_size);
1951 if (in->read_buf_size < in->config.period_size) {
1952 in->read_buf_size = in->config.period_size;
1953 in->read_buf = (int16_t *) realloc(in->read_buf, size_in_bytes);
1954 ALOG_ASSERT((in->read_buf != NULL),
1955 "get_next_buffer() failed to reallocate read_buf");
1956 }
1957
1958 in->read_status = pcm_read(pcm_device->pcm, (void*)in->read_buf, size_in_bytes);
1959
1960 if (in->read_status != 0) {
1961 ALOGE("get_next_buffer() pcm_read error %d", in->read_status);
1962 buffer->raw = NULL;
1963 buffer->frame_count = 0;
1964 return in->read_status;
1965 }
1966 in->read_buf_frames = in->config.period_size;
1967
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001968 }
1969
1970 buffer->frame_count = (buffer->frame_count > in->read_buf_frames) ?
1971 in->read_buf_frames : buffer->frame_count;
1972 buffer->i16 = in->read_buf + (in->config.period_size - in->read_buf_frames) *
1973 in->config.channels;
1974 return in->read_status;
1975}
1976
1977static void release_buffer(struct resampler_buffer_provider *buffer_provider,
1978 struct resampler_buffer* buffer)
1979{
1980 struct stream_in *in;
1981
1982 if (buffer_provider == NULL || buffer == NULL)
1983 return;
1984
1985 in = (struct stream_in *)((char *)buffer_provider -
1986 offsetof(struct stream_in, buf_provider));
1987
1988 in->read_buf_frames -= buffer->frame_count;
1989}
1990
1991/* read_frames() reads frames from kernel driver, down samples to capture rate
1992 * if necessary and output the number of frames requested to the buffer specified */
1993static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames)
1994{
1995 ssize_t frames_wr = 0;
1996
1997 struct pcm_device *pcm_device;
1998
1999 if (list_empty(&in->pcm_dev_list)) {
2000 ALOGE("%s: pcm device list empty", __func__);
2001 return -EINVAL;
2002 }
2003
2004 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
2005 struct pcm_device, stream_list_node);
2006
2007 while (frames_wr < frames) {
2008 size_t frames_rd = frames - frames_wr;
2009 ALOGVV("%s: frames_rd: %zd, frames_wr: %zd, in->config.channels: %d",
2010 __func__,frames_rd,frames_wr,in->config.channels);
2011 if (in->resampler != NULL) {
2012 in->resampler->resample_from_provider(in->resampler,
2013 (int16_t *)((char *)buffer +
2014 pcm_frames_to_bytes(pcm_device->pcm, frames_wr)),
2015 &frames_rd);
2016 } else {
2017 struct resampler_buffer buf = {
Andreas Schneiderb7f32122017-01-31 08:18:34 +01002018 .raw = NULL,
2019 .frame_count = frames_rd,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002020 };
2021 get_next_buffer(&in->buf_provider, &buf);
2022 if (buf.raw != NULL) {
2023 memcpy((char *)buffer +
2024 pcm_frames_to_bytes(pcm_device->pcm, frames_wr),
2025 buf.raw,
2026 pcm_frames_to_bytes(pcm_device->pcm, buf.frame_count));
2027 frames_rd = buf.frame_count;
2028 }
2029 release_buffer(&in->buf_provider, &buf);
2030 }
2031 /* in->read_status is updated by getNextBuffer() also called by
2032 * in->resampler->resample_from_provider() */
2033 if (in->read_status != 0)
2034 return in->read_status;
2035
2036 frames_wr += frames_rd;
2037 }
2038 return frames_wr;
2039}
2040
2041static int in_release_pcm_devices(struct stream_in *in)
2042{
2043 struct pcm_device *pcm_device;
2044 struct listnode *node;
2045 struct listnode *next;
2046
2047 list_for_each_safe(node, next, &in->pcm_dev_list) {
2048 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2049 list_remove(node);
2050 free(pcm_device);
2051 }
2052
2053 return 0;
2054}
2055
2056static int stop_input_stream(struct stream_in *in)
2057{
2058 struct audio_usecase *uc_info;
2059 struct audio_device *adev = in->dev;
2060
2061 adev->active_input = NULL;
2062 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2063 in->usecase, use_case_table[in->usecase]);
2064 uc_info = get_usecase_from_id(adev, in->usecase);
2065 if (uc_info == NULL) {
2066 ALOGE("%s: Could not find the usecase (%d) in the list",
2067 __func__, in->usecase);
2068 return -EINVAL;
2069 }
2070
2071 /* Disable the tx device */
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002072 disable_snd_device(adev, uc_info, uc_info->in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002073
2074 list_remove(&uc_info->adev_list_node);
2075 free(uc_info);
2076
2077 if (list_empty(&in->pcm_dev_list)) {
2078 ALOGE("%s: pcm device list empty", __func__);
2079 return -EINVAL;
2080 }
2081
2082 in_release_pcm_devices(in);
2083 list_init(&in->pcm_dev_list);
2084
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002085 ALOGV("%s: exit", __func__);
2086 return 0;
2087}
2088
2089static int start_input_stream(struct stream_in *in)
2090{
2091 /* Enable output device and stream routing controls */
2092 int ret = 0;
2093 bool recreate_resampler = false;
2094 struct audio_usecase *uc_info;
2095 struct audio_device *adev = in->dev;
2096 struct pcm_device_profile *pcm_profile;
2097 struct pcm_device *pcm_device;
2098
2099 ALOGV("%s: enter: usecase(%d)", __func__, in->usecase);
2100 adev->active_input = in;
2101 pcm_profile = get_pcm_device(in->usecase_type, in->devices);
2102 if (pcm_profile == NULL) {
2103 ALOGE("%s: Could not find PCM device id for the usecase(%d)",
2104 __func__, in->usecase);
2105 ret = -EINVAL;
2106 goto error_config;
2107 }
2108
2109 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002110 if (uc_info == NULL) {
2111 ret = -ENOMEM;
2112 goto error_config;
2113 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002114 uc_info->id = in->usecase;
2115 uc_info->type = PCM_CAPTURE;
2116 uc_info->stream = (struct audio_stream *)in;
2117 uc_info->devices = in->devices;
2118 uc_info->in_snd_device = SND_DEVICE_NONE;
2119 uc_info->out_snd_device = SND_DEVICE_NONE;
2120
2121 pcm_device = (struct pcm_device *)calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01002122 if (pcm_device == NULL) {
2123 free(uc_info);
2124 ret = -ENOMEM;
2125 goto error_config;
2126 }
2127
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002128 pcm_device->pcm_profile = pcm_profile;
2129 list_init(&in->pcm_dev_list);
2130 list_add_tail(&in->pcm_dev_list, &pcm_device->stream_list_node);
2131
2132 list_init(&uc_info->mixer_list);
2133 list_add_tail(&uc_info->mixer_list,
2134 &adev_get_mixer_for_card(adev,
2135 pcm_device->pcm_profile->card)->uc_list_node[uc_info->id]);
2136
2137 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2138
2139 select_devices(adev, in->usecase);
2140
2141 /* Config should be updated as profile can be changed between different calls
2142 * to this function:
2143 * - Trigger resampler creation
2144 * - Config needs to be updated */
2145 if (in->config.rate != pcm_profile->config.rate) {
2146 recreate_resampler = true;
2147 }
2148 in->config = pcm_profile->config;
2149
2150#ifdef PREPROCESSING_ENABLED
2151 if (in->aux_channels_changed) {
2152 in->config.channels = audio_channel_count_from_in_mask(in->main_channels | in->aux_channels);
2153 recreate_resampler = true;
2154 }
2155#endif
2156
2157 if (in->requested_rate != in->config.rate) {
2158 recreate_resampler = true;
2159 }
2160
2161 if (recreate_resampler) {
2162 if (in->resampler) {
2163 release_resampler(in->resampler);
2164 in->resampler = NULL;
2165 }
2166 in->buf_provider.get_next_buffer = get_next_buffer;
2167 in->buf_provider.release_buffer = release_buffer;
2168 ret = create_resampler(in->config.rate,
2169 in->requested_rate,
2170 in->config.channels,
2171 RESAMPLER_QUALITY_DEFAULT,
2172 &in->buf_provider,
2173 &in->resampler);
2174 }
2175
2176#ifdef PREPROCESSING_ENABLED
2177 if (in->enable_aec && in->echo_reference == NULL) {
2178 in->echo_reference = get_echo_reference(adev,
2179 AUDIO_FORMAT_PCM_16_BIT,
2180 audio_channel_count_from_in_mask(in->main_channels),
2181 in->requested_rate
2182 );
2183 }
2184
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002185#endif
2186
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002187 if (in->dev->voice.in_call) {
2188 ALOGV("%s: in_call, not handling PCMs", __func__);
2189 goto skip_pcm_handling;
2190 }
2191
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002192 /* Open the PCM device.
2193 * The HW is limited to support only the default pcm_profile settings.
2194 * As such a change in aux_channels will not have an effect.
2195 */
2196 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d, smp rate %d format %d, \
2197 period_size %d", __func__, pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
2198 pcm_device->pcm_profile->config.channels,pcm_device->pcm_profile->config.rate,
2199 pcm_device->pcm_profile->config.format, pcm_device->pcm_profile->config.period_size);
2200
stenkinevgeniy44335362018-05-07 18:00:13 +00002201 pcm_device->pcm = pcm_open(pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002202 PCM_IN | PCM_MONOTONIC, &pcm_device->pcm_profile->config);
2203
stenkinevgeniy44335362018-05-07 18:00:13 +00002204 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2205 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2206 pcm_close(pcm_device->pcm);
2207 pcm_device->pcm = NULL;
2208 ret = -EIO;
2209 goto error_open;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002210 }
2211
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002212skip_pcm_handling:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002213 /* force read and proc buffer reallocation in case of frame size or
2214 * channel count change */
2215 in->proc_buf_frames = 0;
2216 in->proc_buf_size = 0;
2217 in->read_buf_size = 0;
2218 in->read_buf_frames = 0;
2219
2220 /* if no supported sample rate is available, use the resampler */
2221 if (in->resampler) {
2222 in->resampler->reset(in->resampler);
2223 }
2224
2225 ALOGV("%s: exit", __func__);
2226 return ret;
2227
2228error_open:
2229 if (in->resampler) {
2230 release_resampler(in->resampler);
2231 in->resampler = NULL;
2232 }
2233 stop_input_stream(in);
2234
2235error_config:
2236 ALOGV("%s: exit: status(%d)", __func__, ret);
2237 adev->active_input = NULL;
2238 return ret;
2239}
2240
2241void lock_input_stream(struct stream_in *in)
2242{
2243 pthread_mutex_lock(&in->pre_lock);
2244 pthread_mutex_lock(&in->lock);
2245 pthread_mutex_unlock(&in->pre_lock);
2246}
2247
2248void lock_output_stream(struct stream_out *out)
2249{
2250 pthread_mutex_lock(&out->pre_lock);
2251 pthread_mutex_lock(&out->lock);
2252 pthread_mutex_unlock(&out->pre_lock);
2253}
2254
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002255static int uc_release_pcm_devices(struct audio_usecase *usecase)
2256{
2257 struct stream_out *out = (struct stream_out *)usecase->stream;
2258 struct pcm_device *pcm_device;
2259 struct listnode *node;
2260 struct listnode *next;
2261
2262 list_for_each_safe(node, next, &out->pcm_dev_list) {
2263 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2264 list_remove(node);
2265 free(pcm_device);
2266 }
2267 list_init(&usecase->mixer_list);
2268
2269 return 0;
2270}
2271
2272static int uc_select_pcm_devices(struct audio_usecase *usecase)
2273
2274{
2275 struct stream_out *out = (struct stream_out *)usecase->stream;
2276 struct pcm_device *pcm_device;
2277 struct pcm_device_profile *pcm_profile;
2278 struct mixer_card *mixer_card;
2279 audio_devices_t devices = usecase->devices;
2280
2281 list_init(&usecase->mixer_list);
2282 list_init(&out->pcm_dev_list);
2283
2284 while ((pcm_profile = get_pcm_device(usecase->type, devices)) != NULL) {
2285 pcm_device = calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01002286 if (pcm_device == NULL) {
2287 return -ENOMEM;
2288 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002289 pcm_device->pcm_profile = pcm_profile;
2290 list_add_tail(&out->pcm_dev_list, &pcm_device->stream_list_node);
2291 mixer_card = uc_get_mixer_for_card(usecase, pcm_profile->card);
2292 if (mixer_card == NULL) {
2293 mixer_card = adev_get_mixer_for_card(out->dev, pcm_profile->card);
2294 list_add_tail(&usecase->mixer_list, &mixer_card->uc_list_node[usecase->id]);
2295 }
2296 devices &= ~pcm_profile->devices;
2297 }
2298
2299 return 0;
2300}
2301
2302static int out_close_pcm_devices(struct stream_out *out)
2303{
2304 struct pcm_device *pcm_device;
2305 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002306
2307 list_for_each(node, &out->pcm_dev_list) {
2308 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002309 if (pcm_device->pcm) {
2310 pcm_close(pcm_device->pcm);
2311 pcm_device->pcm = NULL;
2312 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002313 }
2314
2315 return 0;
2316}
2317
2318static int out_open_pcm_devices(struct stream_out *out)
2319{
2320 struct pcm_device *pcm_device;
2321 struct listnode *node;
2322 int ret = 0;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002323 int pcm_device_card;
2324 int pcm_device_id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002325
2326 list_for_each(node, &out->pcm_dev_list) {
2327 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002328 pcm_device_card = pcm_device->pcm_profile->card;
2329 pcm_device_id = pcm_device->pcm_profile->id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002330
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002331 if (out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
2332 pcm_device_id = pcm_device_deep_buffer.id;
2333
2334 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
2335 __func__, pcm_device_card, pcm_device_id);
2336
2337 pcm_device->pcm = pcm_open(pcm_device_card, pcm_device_id,
stenkinevgeniy2ef158a2018-05-08 06:52:05 +00002338 PCM_OUT | PCM_MONOTONIC, &out->config);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002339
2340 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2341 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2342 pcm_device->pcm = NULL;
2343 ret = -EIO;
2344 goto error_open;
2345 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002346 }
2347 return ret;
2348
2349error_open:
2350 out_close_pcm_devices(out);
2351 return ret;
2352}
2353
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002354int disable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002355{
2356 struct audio_device *adev = out->dev;
2357 struct audio_usecase *uc_info;
2358
2359 uc_info = get_usecase_from_id(adev, out->usecase);
2360 if (uc_info == NULL) {
2361 ALOGE("%s: Could not find the usecase (%d) in the list",
2362 __func__, out->usecase);
2363 return -EINVAL;
2364 }
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002365 disable_snd_device(adev, uc_info, uc_info->out_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002366 uc_release_pcm_devices(uc_info);
2367 list_remove(&uc_info->adev_list_node);
2368 free(uc_info);
2369
2370 return 0;
2371}
2372
Andreas Schneider56204f62017-01-31 08:17:32 +01002373int enable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002374{
2375 struct audio_device *adev = out->dev;
2376 struct audio_usecase *uc_info;
2377
2378 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002379 if (uc_info == NULL) {
2380 return -ENOMEM;
2381 }
2382
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002383 uc_info->id = out->usecase;
2384 uc_info->type = PCM_PLAYBACK;
2385 uc_info->stream = (struct audio_stream *)out;
2386 uc_info->devices = out->devices;
2387 uc_info->in_snd_device = SND_DEVICE_NONE;
2388 uc_info->out_snd_device = SND_DEVICE_NONE;
2389 uc_select_pcm_devices(uc_info);
2390
2391 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2392 select_devices(adev, out->usecase);
Andreas Schneider56204f62017-01-31 08:17:32 +01002393
2394 return 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002395}
2396
2397static int stop_output_stream(struct stream_out *out)
2398{
2399 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002400 bool do_disable = true;
2401
2402 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2403 out->usecase, use_case_table[out->usecase]);
2404
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002405 stop_output_offload_stream(out, &do_disable);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002406
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002407 if (do_disable)
2408 ret = disable_output_path_l(out);
2409
2410 ALOGV("%s: exit: status(%d)", __func__, ret);
2411 return ret;
2412}
2413
2414static int start_output_stream(struct stream_out *out)
2415{
2416 int ret = 0;
2417 struct audio_device *adev = out->dev;
2418
2419 ALOGV("%s: enter: usecase(%d: %s) devices(%#x) channels(%d)",
2420 __func__, out->usecase, use_case_table[out->usecase], out->devices, out->config.channels);
2421
Andreas Schneider56204f62017-01-31 08:17:32 +01002422 ret = enable_output_path_l(out);
2423 if (ret != 0) {
2424 goto error_config;
2425 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002426
2427 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2428 out->compr = NULL;
2429 ret = out_open_pcm_devices(out);
2430 if (ret != 0)
2431 goto error_open;
2432#ifdef PREPROCESSING_ENABLED
2433 out->echo_reference = NULL;
2434 out->echo_reference_generation = adev->echo_reference_generation;
2435 if (adev->echo_reference != NULL)
2436 out->echo_reference = adev->echo_reference;
2437#endif
2438 } else {
2439 out->compr = compress_open(COMPRESS_CARD, COMPRESS_DEVICE,
2440 COMPRESS_IN, &out->compr_config);
2441 if (out->compr && !is_compress_ready(out->compr)) {
2442 ALOGE("%s: %s", __func__, compress_get_error(out->compr));
2443 compress_close(out->compr);
2444 out->compr = NULL;
2445 ret = -EIO;
2446 goto error_open;
2447 }
2448 if (out->offload_callback)
2449 compress_nonblock(out->compr, out->non_blocking);
2450
2451 if (adev->offload_fx_start_output != NULL)
2452 adev->offload_fx_start_output(out->handle);
2453 }
2454 ALOGV("%s: exit", __func__);
2455 return 0;
2456error_open:
2457 stop_output_stream(out);
2458error_config:
2459 return ret;
2460}
2461
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002462int stop_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002463{
2464 struct audio_usecase *uc_info;
2465
2466 ALOGV("%s: enter", __func__);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002467 adev->voice.in_call = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002468
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002469 stop_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002470
2471 uc_info = get_usecase_from_id(adev, USECASE_VOICE_CALL);
2472 if (uc_info == NULL) {
2473 ALOGE("%s: Could not find the usecase (%d) in the list",
2474 __func__, USECASE_VOICE_CALL);
2475 return -EINVAL;
2476 }
2477
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002478 disable_snd_device(adev, uc_info, uc_info->out_snd_device);
2479 disable_snd_device(adev, uc_info, uc_info->in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002480
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002481 list_remove(&uc_info->adev_list_node);
2482 free(uc_info);
2483
2484 ALOGV("%s: exit", __func__);
2485 return 0;
2486}
2487
2488/* always called with adev lock held */
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002489int start_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002490{
2491 struct audio_usecase *uc_info;
Andreas Schneider56204f62017-01-31 08:17:32 +01002492 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002493
2494 ALOGV("%s: enter", __func__);
2495
2496 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002497 if (uc_info == NULL) {
2498 ret = -ENOMEM;
2499 goto exit;
2500 }
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002501 /*
2502 * We set this early so that functions called after this is being set
2503 * can use it. It is e.g. needed in select_devices() to inform the RILD
2504 * which output device we use.
2505 */
2506 adev->voice.in_call = true;
Andreas Schneider56204f62017-01-31 08:17:32 +01002507
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002508 uc_info->id = USECASE_VOICE_CALL;
2509 uc_info->type = VOICE_CALL;
2510 uc_info->stream = (struct audio_stream *)adev->primary_output;
2511 uc_info->devices = adev->primary_output->devices;
2512 uc_info->in_snd_device = SND_DEVICE_NONE;
2513 uc_info->out_snd_device = SND_DEVICE_NONE;
2514
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002515 list_init(&uc_info->mixer_list);
2516 list_add_tail(&uc_info->mixer_list,
2517 &adev_get_mixer_for_card(adev, SOUND_CARD)->uc_list_node[uc_info->id]);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002518
2519 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2520
2521 select_devices(adev, USECASE_VOICE_CALL);
2522
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002523 start_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002524
2525 /* set cached volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002526 set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002527
Andreas Schneider56204f62017-01-31 08:17:32 +01002528exit:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002529 ALOGV("%s: exit", __func__);
Andreas Schneider56204f62017-01-31 08:17:32 +01002530 return ret;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002531}
2532
2533static int check_input_parameters(uint32_t sample_rate,
2534 audio_format_t format,
2535 int channel_count)
2536{
2537 if (format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL;
2538
2539 if ((channel_count < 1) || (channel_count > 2)) return -EINVAL;
2540
2541 switch (sample_rate) {
2542 case 8000:
2543 case 11025:
2544 case 12000:
2545 case 16000:
2546 case 22050:
2547 case 24000:
2548 case 32000:
2549 case 44100:
2550 case 48000:
2551 break;
2552 default:
2553 return -EINVAL;
2554 }
2555
2556 return 0;
2557}
2558
2559static size_t get_input_buffer_size(uint32_t sample_rate,
2560 audio_format_t format,
2561 int channel_count,
2562 usecase_type_t usecase_type,
2563 audio_devices_t devices)
2564{
2565 size_t size = 0;
2566 struct pcm_device_profile *pcm_profile;
2567
2568 if (check_input_parameters(sample_rate, format, channel_count) != 0)
2569 return 0;
2570
2571 pcm_profile = get_pcm_device(usecase_type, devices);
2572 if (pcm_profile == NULL)
2573 return 0;
2574
2575 /*
2576 * take resampling into account and return the closest majoring
2577 * multiple of 16 frames, as audioflinger expects audio buffers to
2578 * be a multiple of 16 frames
2579 */
2580 size = (pcm_profile->config.period_size * sample_rate) / pcm_profile->config.rate;
2581 size = ((size + 15) / 16) * 16;
2582
2583 return (size * channel_count * audio_bytes_per_sample(format));
2584
2585}
2586
2587static uint32_t out_get_sample_rate(const struct audio_stream *stream)
2588{
2589 struct stream_out *out = (struct stream_out *)stream;
2590
2591 return out->sample_rate;
2592}
2593
2594static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
2595{
2596 (void)stream;
2597 (void)rate;
2598 return -ENOSYS;
2599}
2600
2601static size_t out_get_buffer_size(const struct audio_stream *stream)
2602{
2603 struct stream_out *out = (struct stream_out *)stream;
2604
2605 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2606 return out->compr_config.fragment_size;
2607 }
2608
2609 return out->config.period_size *
2610 audio_stream_out_frame_size((const struct audio_stream_out *)stream);
2611}
2612
2613static uint32_t out_get_channels(const struct audio_stream *stream)
2614{
2615 struct stream_out *out = (struct stream_out *)stream;
2616
2617 return out->channel_mask;
2618}
2619
2620static audio_format_t out_get_format(const struct audio_stream *stream)
2621{
2622 struct stream_out *out = (struct stream_out *)stream;
2623
2624 return out->format;
2625}
2626
2627static int out_set_format(struct audio_stream *stream, audio_format_t format)
2628{
2629 (void)stream;
2630 (void)format;
2631 return -ENOSYS;
2632}
2633
2634static int do_out_standby_l(struct stream_out *out)
2635{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002636 int status = 0;
2637
2638 out->standby = true;
2639 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2640 out_close_pcm_devices(out);
2641#ifdef PREPROCESSING_ENABLED
2642 /* stop writing to echo reference */
2643 if (out->echo_reference != NULL) {
2644 out->echo_reference->write(out->echo_reference, NULL);
2645 if (out->echo_reference_generation != adev->echo_reference_generation) {
2646 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
2647 release_echo_reference(out->echo_reference);
2648 out->echo_reference_generation = adev->echo_reference_generation;
2649 }
2650 out->echo_reference = NULL;
2651 }
2652#endif
2653 } else {
2654 stop_compressed_output_l(out);
2655 out->gapless_mdata.encoder_delay = 0;
2656 out->gapless_mdata.encoder_padding = 0;
2657 if (out->compr != NULL) {
2658 compress_close(out->compr);
2659 out->compr = NULL;
2660 }
2661 }
2662 status = stop_output_stream(out);
2663
2664 return status;
2665}
2666
2667static int out_standby(struct audio_stream *stream)
2668{
2669 struct stream_out *out = (struct stream_out *)stream;
2670 struct audio_device *adev = out->dev;
2671
2672 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2673 out->usecase, use_case_table[out->usecase]);
2674 lock_output_stream(out);
2675 if (!out->standby) {
2676 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002677 amplifier_output_stream_standby((struct audio_stream_out *) stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002678 do_out_standby_l(out);
2679 pthread_mutex_unlock(&adev->lock);
2680 }
2681 pthread_mutex_unlock(&out->lock);
2682 ALOGV("%s: exit", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01002683
2684 // out->last_write_time_us = 0; unnecessary as a stale write time has same effect
2685
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002686 return 0;
2687}
2688
2689static int out_dump(const struct audio_stream *stream, int fd)
2690{
2691 (void)stream;
2692 (void)fd;
2693
2694 return 0;
2695}
2696
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002697static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
2698{
2699 struct stream_out *out = (struct stream_out *)stream;
2700 struct audio_device *adev = out->dev;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002701 struct listnode *node;
2702 struct str_parms *parms;
2703 char value[32];
2704 int ret, val = 0;
2705 struct audio_usecase *uc_info;
2706 bool do_standby = false;
2707 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002708#ifdef PREPROCESSING_ENABLED
2709 struct stream_in *in = NULL; /* if non-NULL, then force input to standby */
2710#endif
2711
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002712 ALOGV("%s: enter: usecase(%d: %s) kvpairs: %s out->devices(%#x) "
2713 "adev->mode(%#x)",
2714 __func__, out->usecase, use_case_table[out->usecase], kvpairs,
2715 out->devices, adev->mode);
2716
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002717 parms = str_parms_create_str(kvpairs);
2718 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
2719 if (ret >= 0) {
2720 val = atoi(value);
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002721
2722 ALOGV("%s: routing: usecase(%d: %s) devices=(%#x) adev->mode(%#x)",
2723 __func__, out->usecase, use_case_table[out->usecase], val,
2724 adev->mode);
2725
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002726 pthread_mutex_lock(&adev->lock_inputs);
2727 lock_output_stream(out);
2728 pthread_mutex_lock(&adev->lock);
2729#ifdef PREPROCESSING_ENABLED
2730 if (((int)out->devices != val) && (val != 0) && (!out->standby) &&
2731 (out->usecase == USECASE_AUDIO_PLAYBACK)) {
2732 /* reset active input:
2733 * - to attach the echo reference
2734 * - because a change in output device may change mic settings */
2735 if (adev->active_input && (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
2736 adev->active_input->source == AUDIO_SOURCE_MIC)) {
2737 in = adev->active_input;
2738 }
2739 }
2740#endif
Christopher N. Hesse33affb82017-11-16 17:01:37 +01002741 if (val != SND_DEVICE_NONE) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002742 bool bt_sco_active = false;
2743
2744 if (out->devices & AUDIO_DEVICE_OUT_ALL_SCO) {
2745 bt_sco_active = true;
2746 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002747 out->devices = val;
2748
2749 if (!out->standby) {
2750 uc_info = get_usecase_from_id(adev, out->usecase);
2751 if (uc_info == NULL) {
2752 ALOGE("%s: Could not find the usecase (%d) in the list",
2753 __func__, out->usecase);
2754 } else {
2755 list_for_each(node, &out->pcm_dev_list) {
2756 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2757 if ((pcm_device->pcm_profile->devices & val) == 0)
2758 do_standby = true;
2759 val &= ~pcm_device->pcm_profile->devices;
2760 }
2761 if (val != 0)
2762 do_standby = true;
2763 }
2764 if (do_standby)
2765 do_out_standby_l(out);
2766 else {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002767 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
2768 out_set_offload_parameters(adev, uc_info);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002769 select_devices(adev, out->usecase);
2770 }
2771 }
2772
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002773 if ((adev->mode == AUDIO_MODE_IN_CALL) && !adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002774 (out == adev->primary_output)) {
2775 start_voice_call(adev);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002776 } else if ((adev->mode == AUDIO_MODE_IN_CALL) &&
2777 adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002778 (out == adev->primary_output)) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002779 /* Turn on bluetooth if needed */
2780 if ((out->devices & AUDIO_DEVICE_OUT_ALL_SCO) && !bt_sco_active) {
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002781 select_devices(adev, USECASE_VOICE_CALL);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002782 start_voice_session_bt_sco(adev->voice.session);
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002783 } else {
2784 /*
2785 * When we select different devices we need to restart the
2786 * voice call. The modem closes the stream on its end and
2787 * we do not get any output.
2788 */
2789 stop_voice_call(adev);
2790 start_voice_call(adev);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002791 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002792 }
2793 }
2794
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002795 pthread_mutex_unlock(&adev->lock);
2796 pthread_mutex_unlock(&out->lock);
2797#ifdef PREPROCESSING_ENABLED
2798 if (in) {
2799 /* The lock on adev->lock_inputs prevents input stream from being closed */
2800 lock_input_stream(in);
2801 pthread_mutex_lock(&adev->lock);
2802 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
2803 do_in_standby_l(in);
2804 pthread_mutex_unlock(&adev->lock);
2805 pthread_mutex_unlock(&in->lock);
2806 }
2807#endif
2808 pthread_mutex_unlock(&adev->lock_inputs);
2809 }
2810
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002811 amplifier_set_parameters(parms);
2812
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002813 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2814 parse_compress_metadata(out, parms);
2815 }
2816
2817 str_parms_destroy(parms);
2818
2819 if (ret > 0)
2820 ret = 0;
2821 ALOGV("%s: exit: code(%d)", __func__, ret);
2822 return ret;
2823}
2824
2825static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
2826{
2827 struct stream_out *out = (struct stream_out *)stream;
2828 struct str_parms *query = str_parms_create_str(keys);
2829 char *str;
2830 char value[256];
2831 struct str_parms *reply = str_parms_create();
2832 size_t i, j;
2833 int ret;
2834 bool first = true;
2835 ALOGV("%s: enter: keys - %s", __func__, keys);
2836 ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value));
2837 if (ret >= 0) {
2838 value[0] = '\0';
2839 i = 0;
2840 while (out->supported_channel_masks[i] != 0) {
2841 for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) {
2842 if (out_channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) {
2843 if (!first) {
2844 strcat(value, "|");
2845 }
2846 strcat(value, out_channels_name_to_enum_table[j].name);
2847 first = false;
2848 break;
2849 }
2850 }
2851 i++;
2852 }
2853 str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
2854 str = str_parms_to_str(reply);
2855 } else {
2856 str = strdup(keys);
2857 }
2858 str_parms_destroy(query);
2859 str_parms_destroy(reply);
2860 ALOGV("%s: exit: returns - %s", __func__, str);
2861 return str;
2862}
2863
2864static uint32_t out_get_latency(const struct audio_stream_out *stream)
2865{
2866 struct stream_out *out = (struct stream_out *)stream;
2867
2868 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
2869 return COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
2870
2871 return (out->config.period_count * out->config.period_size * 1000) /
2872 (out->config.rate);
2873}
2874
2875static int out_set_volume(struct audio_stream_out *stream, float left,
2876 float right)
2877{
2878 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002879
2880 if (out->usecase == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
2881 /* only take left channel into account: the API is for stereo anyway */
2882 out->muted = (left == 0.0f);
2883 return 0;
2884 } else if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002885 out_set_offload_volume(left, right);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002886 }
2887
2888 return -ENOSYS;
2889}
2890
Andreas Schneider3b643832017-01-31 11:48:22 +01002891#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002892static int fast_set_affinity(pid_t tid) {
2893 cpu_set_t cpu_set;
2894 int cpu_num;
2895 const char *irq_procfs = "/proc/asound/irq_affinity";
2896 FILE *fp;
2897
2898 if ((fp = fopen(irq_procfs, "r")) == NULL) {
2899 ALOGW("Procfs node %s not found", irq_procfs);
2900 return -1;
2901 }
2902
2903 if (fscanf(fp, "%d", &cpu_num) != 1) {
2904 ALOGW("Couldn't read CPU id from procfs node %s", irq_procfs);
2905 fclose(fp);
2906 return -1;
2907 }
2908 fclose(fp);
2909
2910 CPU_ZERO(&cpu_set);
2911 CPU_SET(cpu_num, &cpu_set);
2912 return sched_setaffinity(tid, sizeof(cpu_set), &cpu_set);
2913}
Andreas Schneider3b643832017-01-31 11:48:22 +01002914#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002915
2916static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
2917 size_t bytes)
2918{
2919 struct stream_out *out = (struct stream_out *)stream;
2920 struct audio_device *adev = out->dev;
2921 ssize_t ret = 0;
2922 struct pcm_device *pcm_device;
2923 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002924#ifdef PREPROCESSING_ENABLED
stenkinevgeniyd0a02c02018-05-08 07:17:53 +00002925 size_t frame_size = audio_stream_out_frame_size(stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002926 size_t in_frames = bytes / frame_size;
2927 size_t out_frames = in_frames;
2928 struct stream_in *in = NULL;
2929#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002930
2931 lock_output_stream(out);
2932
Andreas Schneider3b643832017-01-31 11:48:22 +01002933#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002934 if (out->usecase == USECASE_AUDIO_PLAYBACK && !out->is_fastmixer_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01002935 pid_t tid = gettid();
2936 int err;
2937
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002938 err = fast_set_affinity(tid);
2939 if (err < 0) {
2940 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
2941 }
2942 out->is_fastmixer_affinity_set = true;
2943 }
Andreas Schneider3b643832017-01-31 11:48:22 +01002944#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002945
2946 if (out->standby) {
2947#ifdef PREPROCESSING_ENABLED
2948 pthread_mutex_unlock(&out->lock);
2949 /* Prevent input stream from being closed */
2950 pthread_mutex_lock(&adev->lock_inputs);
2951 lock_output_stream(out);
2952 if (!out->standby) {
2953 pthread_mutex_unlock(&adev->lock_inputs);
2954 goto false_alarm;
2955 }
2956#endif
2957 pthread_mutex_lock(&adev->lock);
2958 ret = start_output_stream(out);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002959 if (ret == 0) {
2960 amplifier_output_stream_start(stream, out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD);
2961 }
2962
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002963 /* ToDo: If use case is compress offload should return 0 */
2964 if (ret != 0) {
2965 pthread_mutex_unlock(&adev->lock);
2966#ifdef PREPROCESSING_ENABLED
2967 pthread_mutex_unlock(&adev->lock_inputs);
2968#endif
2969 goto exit;
2970 }
2971 out->standby = false;
2972
2973#ifdef PREPROCESSING_ENABLED
2974 /* A change in output device may change the microphone selection */
2975 if (adev->active_input &&
2976 (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
2977 adev->active_input->source == AUDIO_SOURCE_MIC)) {
2978 in = adev->active_input;
2979 ALOGV("%s: enter:) force_input_standby true", __func__);
2980 }
2981#endif
2982 pthread_mutex_unlock(&adev->lock);
2983#ifdef PREPROCESSING_ENABLED
2984 if (!in) {
2985 /* Leave mutex locked iff in != NULL */
2986 pthread_mutex_unlock(&adev->lock_inputs);
2987 }
2988#endif
2989 }
Andreas Schneider5a2f1002017-02-09 10:59:04 +01002990#ifdef PREPROCESSING_ENABLED
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002991false_alarm:
Andreas Schneider5a2f1002017-02-09 10:59:04 +01002992#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002993
2994 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002995 ret = out_write_offload(stream, buffer, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002996 return ret;
2997 } else {
2998#ifdef PREPROCESSING_ENABLED
2999 if (android_atomic_acquire_load(&adev->echo_reference_generation)
3000 != out->echo_reference_generation) {
3001 pthread_mutex_lock(&adev->lock);
3002 if (out->echo_reference != NULL) {
3003 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
3004 release_echo_reference(out->echo_reference);
3005 }
3006 // note that adev->echo_reference_generation here can be different from the one
3007 // tested above but it doesn't matter as we now have the adev mutex and it is consistent
3008 // with what has been set by get_echo_reference() or put_echo_reference()
3009 out->echo_reference_generation = adev->echo_reference_generation;
3010 out->echo_reference = adev->echo_reference;
3011 ALOGV("%s: update echo reference generation %d", __func__,
3012 out->echo_reference_generation);
3013 pthread_mutex_unlock(&adev->lock);
3014 }
3015#endif
3016
3017 if (out->muted)
3018 memset((void *)buffer, 0, bytes);
3019 list_for_each(node, &out->pcm_dev_list) {
3020 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003021 if (pcm_device->pcm) {
3022#ifdef PREPROCESSING_ENABLED
3023 if (out->echo_reference != NULL && pcm_device->pcm_profile->devices != SND_DEVICE_OUT_SPEAKER) {
3024 struct echo_reference_buffer b;
3025 b.raw = (void *)buffer;
3026 b.frame_count = in_frames;
3027
3028 get_playback_delay(out, out_frames, &b);
3029 out->echo_reference->write(out->echo_reference, &b);
3030 }
3031#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003032 ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
stenkinevgeniyd0a02c02018-05-08 07:17:53 +00003033 pcm_device->status = pcm_write(pcm_device->pcm, (void *)buffer, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003034 if (pcm_device->status != 0)
3035 ret = pcm_device->status;
3036 }
3037 }
3038 if (ret == 0)
3039 out->written += bytes / (out->config.channels * sizeof(short));
3040 }
3041
3042exit:
3043 pthread_mutex_unlock(&out->lock);
3044
3045 if (ret != 0) {
3046 list_for_each(node, &out->pcm_dev_list) {
3047 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3048 if (pcm_device->pcm && pcm_device->status != 0)
3049 ALOGE("%s: error %zd - %s", __func__, ret, pcm_get_error(pcm_device->pcm));
3050 }
3051 out_standby(&out->stream.common);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003052 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3053 clock_gettime(CLOCK_MONOTONIC, &t);
3054 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3055 const int64_t elapsed_time_since_last_write = now - out->last_write_time_us;
3056 int64_t sleep_time = bytes * 1000000LL / audio_stream_out_frame_size(stream) /
3057 out_get_sample_rate(&stream->common) - elapsed_time_since_last_write;
3058 if (sleep_time > 0) {
3059 usleep(sleep_time);
3060 } else {
3061 // we don't sleep when we exit standby (this is typical for a real alsa buffer).
3062 sleep_time = 0;
3063 }
3064 out->last_write_time_us = now + sleep_time;
3065 // last_write_time_us is an approximation of when the (simulated) alsa
3066 // buffer is believed completely full. The usleep above waits for more space
3067 // in the buffer, but by the end of the sleep the buffer is considered
3068 // topped-off.
3069 //
3070 // On the subsequent out_write(), we measure the elapsed time spent in
3071 // the mixer. This is subtracted from the sleep estimate based on frames,
3072 // thereby accounting for drain in the alsa buffer during mixing.
3073 // This is a crude approximation; we don't handle underruns precisely.
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003074 }
3075
3076#ifdef PREPROCESSING_ENABLED
3077 if (in) {
3078 /* The lock on adev->lock_inputs prevents input stream from being closed */
3079 lock_input_stream(in);
3080 pthread_mutex_lock(&adev->lock);
3081 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
3082 do_in_standby_l(in);
3083 pthread_mutex_unlock(&adev->lock);
3084 pthread_mutex_unlock(&in->lock);
3085 /* This mutex was left locked iff in != NULL */
3086 pthread_mutex_unlock(&adev->lock_inputs);
3087 }
3088#endif
3089
3090 return bytes;
3091}
3092
3093static int out_get_render_position(const struct audio_stream_out *stream,
3094 uint32_t *dsp_frames)
3095{
3096 struct stream_out *out = (struct stream_out *)stream;
3097 *dsp_frames = 0;
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003098 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
3099 return out_get_render_offload_position(out, dsp_frames);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003100 } else
3101 return -EINVAL;
3102}
3103
3104static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3105{
3106 (void)stream;
3107 (void)effect;
3108 return 0;
3109}
3110
3111static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3112{
3113 (void)stream;
3114 (void)effect;
3115 return 0;
3116}
3117
3118static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
3119 int64_t *timestamp)
3120{
3121 (void)stream;
3122 (void)timestamp;
3123 return -EINVAL;
3124}
3125
3126static int out_get_presentation_position(const struct audio_stream_out *stream,
3127 uint64_t *frames, struct timespec *timestamp)
3128{
3129 struct stream_out *out = (struct stream_out *)stream;
Victor Lourme5869cd32018-03-26 19:36:07 +02003130 int ret = -EINVAL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003131
3132 lock_output_stream(out);
3133
3134 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003135 ret = out_get_presentation_offload_position(out, frames, timestamp);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003136 } else {
3137 /* FIXME: which device to read from? */
3138 if (!list_empty(&out->pcm_dev_list)) {
Andreas Schneiderd6359182017-02-08 16:58:22 +01003139 struct pcm_device *pcm_device;
3140 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003141 unsigned int avail;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003142
Andreas Schneiderd6359182017-02-08 16:58:22 +01003143 list_for_each(node, &out->pcm_dev_list) {
3144 pcm_device = node_to_item(node,
3145 struct pcm_device,
3146 stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003147
Andreas Schneiderd6359182017-02-08 16:58:22 +01003148 if (pcm_device->pcm != NULL) {
3149 if (pcm_get_htimestamp(pcm_device->pcm, &avail, timestamp) == 0) {
3150 size_t kernel_buffer_size = out->config.period_size * out->config.period_count;
3151 int64_t signed_frames = out->written - kernel_buffer_size + avail;
3152 /* This adjustment accounts for buffering after app processor.
3153 It is based on estimated DSP latency per use case, rather than exact. */
3154 signed_frames -=
3155 (render_latency(out->usecase) * out->sample_rate / 1000000LL);
3156
3157 /* It would be unusual for this value to be negative, but check just in case ... */
3158 if (signed_frames >= 0) {
3159 *frames = signed_frames;
3160 ret = 0;
3161 goto done;
3162 }
Andreas Schneiderd6359182017-02-08 16:58:22 +01003163 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003164 }
3165 }
3166 }
3167 }
3168
Andreas Schneiderd6359182017-02-08 16:58:22 +01003169done:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003170 pthread_mutex_unlock(&out->lock);
3171
3172 return ret;
3173}
3174
3175static int out_set_callback(struct audio_stream_out *stream,
3176 stream_callback_t callback, void *cookie)
3177{
3178 struct stream_out *out = (struct stream_out *)stream;
3179
3180 ALOGV("%s", __func__);
3181 lock_output_stream(out);
3182 out->offload_callback = callback;
3183 out->offload_cookie = cookie;
3184 pthread_mutex_unlock(&out->lock);
3185 return 0;
3186}
3187
3188static int out_pause(struct audio_stream_out* stream)
3189{
3190 struct stream_out *out = (struct stream_out *)stream;
3191 int status = -ENOSYS;
3192 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003193 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3194 status = out_pause_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003195 return status;
3196}
3197
3198static int out_resume(struct audio_stream_out* stream)
3199{
3200 struct stream_out *out = (struct stream_out *)stream;
3201 int status = -ENOSYS;
3202 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003203 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3204 status = out_resume_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003205 return status;
3206}
3207
3208static int out_drain(struct audio_stream_out* stream, audio_drain_type_t type )
3209{
3210 struct stream_out *out = (struct stream_out *)stream;
3211 int status = -ENOSYS;
3212 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003213 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3214 status = out_drain_offload(out, type);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003215 return status;
3216}
3217
3218static int out_flush(struct audio_stream_out* stream)
3219{
3220 struct stream_out *out = (struct stream_out *)stream;
3221 ALOGV("%s", __func__);
3222 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003223 return out_flush_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003224 }
3225 return -ENOSYS;
3226}
3227
3228/** audio_stream_in implementation **/
3229static uint32_t in_get_sample_rate(const struct audio_stream *stream)
3230{
3231 struct stream_in *in = (struct stream_in *)stream;
3232
3233 return in->requested_rate;
3234}
3235
3236static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
3237{
3238 (void)stream;
3239 (void)rate;
3240 return -ENOSYS;
3241}
3242
3243static uint32_t in_get_channels(const struct audio_stream *stream)
3244{
3245 struct stream_in *in = (struct stream_in *)stream;
3246
3247 return in->main_channels;
3248}
3249
3250static audio_format_t in_get_format(const struct audio_stream *stream)
3251{
3252 (void)stream;
3253 return AUDIO_FORMAT_PCM_16_BIT;
3254}
3255
3256static int in_set_format(struct audio_stream *stream, audio_format_t format)
3257{
3258 (void)stream;
3259 (void)format;
3260
3261 return -ENOSYS;
3262}
3263
3264static size_t in_get_buffer_size(const struct audio_stream *stream)
3265{
3266 struct stream_in *in = (struct stream_in *)stream;
3267
3268 return get_input_buffer_size(in->requested_rate,
3269 in_get_format(stream),
3270 audio_channel_count_from_in_mask(in->main_channels),
3271 in->usecase_type,
3272 in->devices);
3273}
3274
3275static int in_close_pcm_devices(struct stream_in *in)
3276{
3277 struct pcm_device *pcm_device;
3278 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003279
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;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003286 }
3287 }
3288 return 0;
3289}
3290
3291
3292/* must be called with stream and hw device mutex locked */
3293static int do_in_standby_l(struct stream_in *in)
3294{
3295 int status = 0;
3296
3297#ifdef PREPROCESSING_ENABLED
3298 struct audio_device *adev = in->dev;
3299#endif
3300 if (!in->standby) {
3301
3302 in_close_pcm_devices(in);
3303
3304#ifdef PREPROCESSING_ENABLED
3305 if (in->echo_reference != NULL) {
3306 /* stop reading from echo reference */
3307 in->echo_reference->read(in->echo_reference, NULL);
3308 put_echo_reference(adev, in->echo_reference);
3309 in->echo_reference = NULL;
3310 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003311#endif // PREPROCESSING_ENABLED
3312
3313 status = stop_input_stream(in);
3314
3315 if (in->read_buf) {
3316 free(in->read_buf);
3317 in->read_buf = NULL;
3318 }
3319
3320 in->standby = 1;
3321 }
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003322
3323 in->last_read_time_us = 0;
3324
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003325 return 0;
3326}
3327
3328// called with adev->lock_inputs locked
3329static int in_standby_l(struct stream_in *in)
3330{
3331 struct audio_device *adev = in->dev;
3332 int status = 0;
3333 lock_input_stream(in);
3334 if (!in->standby) {
3335 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003336 amplifier_input_stream_standby((struct audio_stream_in *) in);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003337 status = do_in_standby_l(in);
3338 pthread_mutex_unlock(&adev->lock);
3339 }
3340 pthread_mutex_unlock(&in->lock);
3341 return status;
3342}
3343
3344static int in_standby(struct audio_stream *stream)
3345{
3346 struct stream_in *in = (struct stream_in *)stream;
3347 struct audio_device *adev = in->dev;
3348 int status;
3349 ALOGV("%s: enter", __func__);
3350 pthread_mutex_lock(&adev->lock_inputs);
3351 status = in_standby_l(in);
3352 pthread_mutex_unlock(&adev->lock_inputs);
3353 ALOGV("%s: exit: status(%d)", __func__, status);
3354 return status;
3355}
3356
3357static int in_dump(const struct audio_stream *stream, int fd)
3358{
3359 (void)stream;
3360 (void)fd;
3361
3362 return 0;
3363}
3364
3365static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
3366{
3367 struct stream_in *in = (struct stream_in *)stream;
3368 struct audio_device *adev = in->dev;
3369 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003370 char value[32];
3371 int ret, val = 0;
3372 struct audio_usecase *uc_info;
3373 bool do_standby = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003374 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003375
3376 ALOGV("%s: enter: kvpairs=%s", __func__, kvpairs);
3377 parms = str_parms_create_str(kvpairs);
3378
3379 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
3380
3381 pthread_mutex_lock(&adev->lock_inputs);
3382 lock_input_stream(in);
3383 pthread_mutex_lock(&adev->lock);
3384 if (ret >= 0) {
3385 val = atoi(value);
3386 /* no audio source uses val == 0 */
3387 if (((int)in->source != val) && (val != 0)) {
3388 in->source = val;
3389 }
3390 }
3391
3392 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
3393 if (ret >= 0) {
3394 val = atoi(value);
3395 if (((int)in->devices != val) && (val != 0)) {
3396 in->devices = val;
3397 /* If recording is in progress, change the tx device to new device */
3398 if (!in->standby) {
3399 uc_info = get_usecase_from_id(adev, in->usecase);
3400 if (uc_info == NULL) {
3401 ALOGE("%s: Could not find the usecase (%d) in the list",
3402 __func__, in->usecase);
3403 } else {
3404 if (list_empty(&in->pcm_dev_list))
3405 ALOGE("%s: pcm device list empty", __func__);
3406 else {
3407 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3408 struct pcm_device, stream_list_node);
3409 if ((pcm_device->pcm_profile->devices & val & ~AUDIO_DEVICE_BIT_IN) == 0) {
3410 do_standby = true;
3411 }
3412 }
3413 }
3414 if (do_standby) {
3415 ret = do_in_standby_l(in);
3416 } else
3417 ret = select_devices(adev, in->usecase);
3418 }
3419 }
3420 }
3421 pthread_mutex_unlock(&adev->lock);
3422 pthread_mutex_unlock(&in->lock);
3423 pthread_mutex_unlock(&adev->lock_inputs);
3424 str_parms_destroy(parms);
3425
3426 if (ret > 0)
3427 ret = 0;
3428
3429 ALOGV("%s: exit: status(%d)", __func__, ret);
3430 return ret;
3431}
3432
3433static char* in_get_parameters(const struct audio_stream *stream,
3434 const char *keys)
3435{
3436 (void)stream;
3437 (void)keys;
3438
3439 return strdup("");
3440}
3441
3442static int in_set_gain(struct audio_stream_in *stream, float gain)
3443{
3444 (void)stream;
3445 (void)gain;
3446
3447 return 0;
3448}
3449
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003450static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
3451 size_t bytes)
3452{
3453 struct stream_in *in = (struct stream_in *)stream;
3454 struct audio_device *adev = in->dev;
3455 ssize_t frames = -1;
3456 int ret = -1;
3457 int read_and_process_successful = false;
3458
3459 size_t frames_rq = bytes / audio_stream_in_frame_size(stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003460
3461 /* no need to acquire adev->lock_inputs because API contract prevents a close */
3462 lock_input_stream(in);
3463
Andreas Schneider3b643832017-01-31 11:48:22 +01003464#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003465 if (in->usecase == USECASE_AUDIO_CAPTURE && !in->is_fastcapture_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003466 pid_t tid = gettid();
3467 int err;
3468
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003469 err = fast_set_affinity(tid);
3470 if (err < 0) {
3471 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
3472 }
3473 in->is_fastcapture_affinity_set = true;
3474 }
Andreas Schneider3b643832017-01-31 11:48:22 +01003475#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003476
3477 if (in->standby) {
3478 pthread_mutex_unlock(&in->lock);
3479 pthread_mutex_lock(&adev->lock_inputs);
3480 lock_input_stream(in);
3481 if (!in->standby) {
3482 pthread_mutex_unlock(&adev->lock_inputs);
3483 goto false_alarm;
3484 }
3485 pthread_mutex_lock(&adev->lock);
3486 ret = start_input_stream(in);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003487 if (ret == 0) {
3488 amplifier_input_stream_start(stream);
3489 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003490 pthread_mutex_unlock(&adev->lock);
3491 pthread_mutex_unlock(&adev->lock_inputs);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003492
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003493 if (ret != 0) {
3494 goto exit;
3495 }
3496 in->standby = 0;
3497 }
3498false_alarm:
3499
3500 if (!list_empty(&in->pcm_dev_list)) {
stenkinevgeniy44335362018-05-07 18:00:13 +00003501 /*
3502 * Read PCM and:
3503 * - resample if needed
3504 * - process if pre-processors are attached
3505 * - discard unwanted channels
3506 */
3507 frames = read_and_process_frames(in, buffer, frames_rq);
3508 if (frames >= 0)
3509 read_and_process_successful = true;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003510 }
3511
3512 /*
3513 * Instead of writing zeroes here, we could trust the hardware
3514 * to always provide zeroes when muted.
3515 */
3516 if (read_and_process_successful == true && adev->mic_mute)
3517 memset(buffer, 0, bytes);
3518
3519exit:
3520 pthread_mutex_unlock(&in->lock);
3521
3522 if (read_and_process_successful == false) {
3523 in_standby(&in->stream.common);
3524 ALOGV("%s: read failed - sleeping for buffer duration", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003525 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3526 clock_gettime(CLOCK_MONOTONIC, &t);
3527 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3528
3529 // we do a full sleep when exiting standby.
3530 const bool standby = in->last_read_time_us == 0;
3531 const int64_t elapsed_time_since_last_read = standby ?
3532 0 : now - in->last_read_time_us;
3533 int64_t sleep_time = bytes * 1000000LL / audio_stream_in_frame_size(stream) /
3534 in_get_sample_rate(&stream->common) - elapsed_time_since_last_read;
3535 if (sleep_time > 0) {
3536 usleep(sleep_time);
3537 } else {
3538 sleep_time = 0;
3539 }
3540 in->last_read_time_us = now + sleep_time;
3541 // last_read_time_us is an approximation of when the (simulated) alsa
3542 // buffer is drained by the read, and is empty.
3543 //
3544 // On the subsequent in_read(), we measure the elapsed time spent in
3545 // the recording thread. This is subtracted from the sleep estimate based on frames,
3546 // thereby accounting for fill in the alsa buffer during the interim.
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003547 memset(buffer, 0, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003548 }
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003549
3550 if (bytes > 0) {
3551 in->frames_read += bytes / audio_stream_in_frame_size(stream);
3552 }
3553
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003554 return bytes;
3555}
3556
3557static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
3558{
3559 (void)stream;
3560
3561 return 0;
3562}
3563
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003564static int in_get_capture_position(const struct audio_stream_in *stream,
3565 int64_t *frames, int64_t *time)
3566{
3567 if (stream == NULL || frames == NULL || time == NULL) {
3568 return -EINVAL;
3569 }
3570
3571 struct stream_in *in = (struct stream_in *)stream;
3572 struct pcm_device *pcm_device;
3573 int ret = -ENOSYS;
3574
3575 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3576 struct pcm_device, stream_list_node);
3577
3578 pthread_mutex_lock(&in->lock);
3579 if (pcm_device->pcm) {
3580 struct timespec timestamp;
3581 unsigned int avail;
3582 if (pcm_get_htimestamp(pcm_device->pcm, &avail, &timestamp) == 0) {
3583 *frames = in->frames_read + avail;
3584 *time = timestamp.tv_sec * 1000000000LL + timestamp.tv_nsec;
3585 ret = 0;
3586 }
3587 }
3588
3589 pthread_mutex_unlock(&in->lock);
3590 return ret;
3591}
3592
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003593static int add_remove_audio_effect(const struct audio_stream *stream,
3594 effect_handle_t effect,
3595 bool enable)
3596{
3597 struct stream_in *in = (struct stream_in *)stream;
3598 struct audio_device *adev = in->dev;
3599 int status = 0;
3600 effect_descriptor_t desc;
3601#ifdef PREPROCESSING_ENABLED
3602 int i;
3603#endif
3604 status = (*effect)->get_descriptor(effect, &desc);
3605 if (status != 0)
3606 return status;
3607
3608 ALOGI("add_remove_audio_effect(), effect type: %08x, enable: %d ", desc.type.timeLow, enable);
3609
3610 pthread_mutex_lock(&adev->lock_inputs);
3611 lock_input_stream(in);
3612 pthread_mutex_lock(&in->dev->lock);
3613#ifndef PREPROCESSING_ENABLED
3614 if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) &&
3615 in->enable_aec != enable &&
3616 (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0)) {
3617 in->enable_aec = enable;
3618 if (!in->standby)
3619 select_devices(in->dev, in->usecase);
3620 }
3621#else
3622 if ( (in->num_preprocessors > MAX_PREPROCESSORS) && (enable == true) ) {
3623 status = -ENOSYS;
3624 goto exit;
3625 }
3626 if ( enable == true ) {
3627 in->preprocessors[in->num_preprocessors].effect_itfe = effect;
3628 /* add the supported channel of the effect in the channel_configs */
3629 in_read_audio_effect_channel_configs(in, &in->preprocessors[in->num_preprocessors]);
3630 in->num_preprocessors ++;
3631 /* check compatibility between main channel supported and possible auxiliary channels */
3632 in_update_aux_channels(in, effect);//wesley crash
3633 in->aux_channels_changed = true;
3634 } else {
3635 /* if ( enable == false ) */
3636 if (in->num_preprocessors <= 0) {
3637 status = -ENOSYS;
3638 goto exit;
3639 }
3640 status = -EINVAL;
3641 for (i=0; i < in->num_preprocessors; i++) {
3642 if (status == 0) { /* status == 0 means an effect was removed from a previous slot */
3643 in->preprocessors[i - 1].effect_itfe = in->preprocessors[i].effect_itfe;
3644 in->preprocessors[i - 1].channel_configs = in->preprocessors[i].channel_configs;
3645 in->preprocessors[i - 1].num_channel_configs =
3646 in->preprocessors[i].num_channel_configs;
3647 ALOGV("add_remove_audio_effect moving fx from %d to %d", i, i-1);
3648 continue;
3649 }
3650 if ( in->preprocessors[i].effect_itfe == effect ) {
3651 ALOGV("add_remove_audio_effect found fx at index %d", i);
3652 free(in->preprocessors[i].channel_configs);
3653 status = 0;
3654 }
3655 }
3656 if (status != 0)
3657 goto exit;
3658 in->num_preprocessors--;
3659 /* if we remove one effect, at least the last proproc should be reset */
3660 in->preprocessors[in->num_preprocessors].num_channel_configs = 0;
3661 in->preprocessors[in->num_preprocessors].effect_itfe = NULL;
3662 in->preprocessors[in->num_preprocessors].channel_configs = NULL;
3663 in->aux_channels_changed = false;
3664 ALOGV("%s: enable(%d), in->aux_channels_changed(%d)", __func__, enable, in->aux_channels_changed);
3665 }
3666 ALOGI("%s: num_preprocessors = %d", __func__, in->num_preprocessors);
3667
3668 if ( memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
3669 in->enable_aec = enable;
3670 ALOGV("add_remove_audio_effect(), FX_IID_AEC, enable: %d", enable);
3671 if (!in->standby) {
3672 select_devices(in->dev, in->usecase);
3673 do_in_standby_l(in);
3674 }
3675 if (in->enable_aec == true) {
3676 in_configure_reverse(in);
3677 }
3678 }
3679exit:
3680#endif
3681 ALOGW_IF(status != 0, "add_remove_audio_effect() error %d", status);
3682 pthread_mutex_unlock(&in->dev->lock);
3683 pthread_mutex_unlock(&in->lock);
3684 pthread_mutex_unlock(&adev->lock_inputs);
3685 return status;
3686}
3687
3688static int in_add_audio_effect(const struct audio_stream *stream,
3689 effect_handle_t effect)
3690{
3691 ALOGV("%s: effect %p", __func__, effect);
3692 return add_remove_audio_effect(stream, effect, true);
3693}
3694
3695static int in_remove_audio_effect(const struct audio_stream *stream,
3696 effect_handle_t effect)
3697{
3698 ALOGV("%s: effect %p", __func__, effect);
3699 return add_remove_audio_effect(stream, effect, false);
3700}
3701
3702static int adev_open_output_stream(struct audio_hw_device *dev,
3703 audio_io_handle_t handle,
3704 audio_devices_t devices,
3705 audio_output_flags_t flags,
3706 struct audio_config *config,
3707 struct audio_stream_out **stream_out,
3708 const char *address __unused)
3709{
3710 struct audio_device *adev = (struct audio_device *)dev;
3711 struct stream_out *out;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003712 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003713 struct pcm_device_profile *pcm_profile;
3714
3715 ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
3716 __func__, config->sample_rate, config->channel_mask, devices, flags);
3717 *stream_out = NULL;
3718 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
Andreas Schneider56204f62017-01-31 08:17:32 +01003719 if (out == NULL) {
3720 ret = -ENOMEM;
3721 goto error_config;
3722 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003723
3724 if (devices == AUDIO_DEVICE_NONE)
3725 devices = AUDIO_DEVICE_OUT_SPEAKER;
3726
3727 out->flags = flags;
3728 out->devices = devices;
3729 out->dev = adev;
3730 out->format = config->format;
3731 out->sample_rate = config->sample_rate;
3732 out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3733 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
3734 out->handle = handle;
3735
3736 pcm_profile = get_pcm_device(PCM_PLAYBACK, devices);
3737 if (pcm_profile == NULL) {
3738 ret = -EINVAL;
3739 goto error_open;
3740 }
3741 out->config = pcm_profile->config;
3742
3743 /* Init use case and pcm_config */
3744 if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
3745 if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version ||
3746 config->offload_info.size != AUDIO_INFO_INITIALIZER.size) {
3747 ALOGE("%s: Unsupported Offload information", __func__);
3748 ret = -EINVAL;
3749 goto error_open;
3750 }
3751 if (!is_supported_format(config->offload_info.format)) {
3752 ALOGE("%s: Unsupported audio format", __func__);
3753 ret = -EINVAL;
3754 goto error_open;
3755 }
3756
3757 out->compr_config.codec = (struct snd_codec *)
3758 calloc(1, sizeof(struct snd_codec));
Andreas Schneider56204f62017-01-31 08:17:32 +01003759 if (out->compr_config.codec == NULL) {
3760 ret = -ENOMEM;
3761 goto error_open;
3762 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003763
3764 out->usecase = USECASE_AUDIO_PLAYBACK_OFFLOAD;
3765 if (config->offload_info.channel_mask)
3766 out->channel_mask = config->offload_info.channel_mask;
3767 else if (config->channel_mask)
3768 out->channel_mask = config->channel_mask;
3769 out->format = config->offload_info.format;
3770 out->sample_rate = config->offload_info.sample_rate;
3771
3772 out->stream.set_callback = out_set_callback;
3773 out->stream.pause = out_pause;
3774 out->stream.resume = out_resume;
3775 out->stream.drain = out_drain;
3776 out->stream.flush = out_flush;
3777
3778 out->compr_config.codec->id =
3779 get_snd_codec_id(config->offload_info.format);
3780 out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
3781 out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
3782 out->compr_config.codec->sample_rate = config->offload_info.sample_rate;
3783 out->compr_config.codec->bit_rate =
3784 config->offload_info.bit_rate;
3785 out->compr_config.codec->ch_in =
3786 audio_channel_count_from_out_mask(config->channel_mask);
3787 out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
3788
3789 if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
3790 out->non_blocking = 1;
3791
3792 out->send_new_metadata = 1;
3793 create_offload_callback_thread(out);
3794 out->offload_state = OFFLOAD_STATE_IDLE;
3795
3796 ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
3797 __func__, config->offload_info.version,
3798 config->offload_info.bit_rate);
3799 } else if (out->flags & (AUDIO_OUTPUT_FLAG_DEEP_BUFFER)) {
3800 out->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01003801 out->config = pcm_device_deep_buffer.config;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003802 out->sample_rate = out->config.rate;
3803 ALOGV("%s: use AUDIO_PLAYBACK_DEEP_BUFFER",__func__);
3804 } else {
3805 out->usecase = USECASE_AUDIO_PLAYBACK;
3806 out->sample_rate = out->config.rate;
3807 }
3808
3809 if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
3810 if (adev->primary_output == NULL)
3811 adev->primary_output = out;
3812 else {
3813 ALOGE("%s: Primary output is already opened", __func__);
3814 ret = -EEXIST;
3815 goto error_open;
3816 }
3817 }
3818
3819 /* Check if this usecase is already existing */
3820 pthread_mutex_lock(&adev->lock);
3821 if (get_usecase_from_id(adev, out->usecase) != NULL) {
3822 ALOGE("%s: Usecase (%d) is already present", __func__, out->usecase);
3823 pthread_mutex_unlock(&adev->lock);
3824 ret = -EEXIST;
3825 goto error_open;
3826 }
3827 pthread_mutex_unlock(&adev->lock);
3828
3829 out->stream.common.get_sample_rate = out_get_sample_rate;
3830 out->stream.common.set_sample_rate = out_set_sample_rate;
3831 out->stream.common.get_buffer_size = out_get_buffer_size;
3832 out->stream.common.get_channels = out_get_channels;
3833 out->stream.common.get_format = out_get_format;
3834 out->stream.common.set_format = out_set_format;
3835 out->stream.common.standby = out_standby;
3836 out->stream.common.dump = out_dump;
3837 out->stream.common.set_parameters = out_set_parameters;
3838 out->stream.common.get_parameters = out_get_parameters;
3839 out->stream.common.add_audio_effect = out_add_audio_effect;
3840 out->stream.common.remove_audio_effect = out_remove_audio_effect;
3841 out->stream.get_latency = out_get_latency;
3842 out->stream.set_volume = out_set_volume;
3843 out->stream.write = out_write;
3844 out->stream.get_render_position = out_get_render_position;
3845 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
3846 out->stream.get_presentation_position = out_get_presentation_position;
3847
3848 out->standby = 1;
3849 /* out->muted = false; by calloc() */
3850 /* out->written = 0; by calloc() */
3851
3852 pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
3853 pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
3854 pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
3855
3856 config->format = out->stream.common.get_format(&out->stream.common);
3857 config->channel_mask = out->stream.common.get_channels(&out->stream.common);
3858 config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
3859
3860 out->is_fastmixer_affinity_set = false;
3861
3862 *stream_out = &out->stream;
3863 ALOGV("%s: exit", __func__);
3864 return 0;
3865
3866error_open:
3867 free(out);
3868 *stream_out = NULL;
Andreas Schneider56204f62017-01-31 08:17:32 +01003869error_config:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003870 ALOGV("%s: exit: ret %d", __func__, ret);
3871 return ret;
3872}
3873
3874static void adev_close_output_stream(struct audio_hw_device *dev,
3875 struct audio_stream_out *stream)
3876{
3877 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003878 (void)dev;
3879
3880 ALOGV("%s: enter", __func__);
3881 out_standby(&stream->common);
3882 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
3883 destroy_offload_callback_thread(out);
3884
3885 if (out->compr_config.codec != NULL)
3886 free(out->compr_config.codec);
3887 }
3888 pthread_cond_destroy(&out->cond);
3889 pthread_mutex_destroy(&out->lock);
3890 free(stream);
3891 ALOGV("%s: exit", __func__);
3892}
3893
3894static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
3895{
3896 struct audio_device *adev = (struct audio_device *)dev;
3897 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003898 char value[32];
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003899#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003900 int val;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003901#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003902 int ret;
3903
3904 ALOGV("%s: enter: %s", __func__, kvpairs);
3905
3906 parms = str_parms_create_str(kvpairs);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003907
Andreas Schneider05bc1882017-02-09 14:03:11 +01003908 /******************************************************
3909 *** BT SCO
3910 ******************************************************/
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003911 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
3912 if (ret >= 0) {
3913 /* When set to false, HAL should disable EC and NS
3914 * But it is currently not supported.
3915 */
3916 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
Andreas Schneider74ef3a12017-02-02 18:29:12 +01003917 adev->voice.bluetooth_nrec = true;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003918 else
Andreas Schneider74ef3a12017-02-02 18:29:12 +01003919 adev->voice.bluetooth_nrec = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003920 }
3921
Andreas Schneider05bc1882017-02-09 14:03:11 +01003922 ret = str_parms_get_str(parms,
3923 AUDIO_PARAMETER_KEY_BT_SCO_WB,
3924 value,
3925 sizeof(value));
3926 if (ret >= 0) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01003927 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) {
3928 adev->voice.bluetooth_wb = true;
Andreas Schneider05bc1882017-02-09 14:03:11 +01003929 } else {
3930 adev->voice.bluetooth_wb = false;
3931 }
3932 }
3933
Andreas Schneiderecd17ce2017-02-09 10:45:21 +01003934 ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
3935 if (ret >= 0) {
3936 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
3937 adev->screen_off = false;
3938 else
3939 adev->screen_off = true;
3940 }
3941
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01003942#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003943 ret = str_parms_get_int(parms, "rotation", &val);
3944 if (ret >= 0) {
3945 bool reverse_speakers = false;
3946 switch(val) {
3947 /* FIXME: note that the code below assumes that the speakers are in the correct placement
3948 relative to the user when the device is rotated 90deg from its default rotation. This
3949 assumption is device-specific, not platform-specific like this code. */
3950 case 270:
3951 reverse_speakers = true;
3952 break;
3953 case 0:
3954 case 90:
3955 case 180:
3956 break;
3957 default:
3958 ALOGE("%s: unexpected rotation of %d", __func__, val);
3959 }
3960 pthread_mutex_lock(&adev->lock);
3961 if (adev->speaker_lr_swap != reverse_speakers) {
3962 adev->speaker_lr_swap = reverse_speakers;
3963 /* only update the selected device if there is active pcm playback */
3964 struct audio_usecase *usecase;
3965 struct listnode *node;
3966 list_for_each(node, &adev->usecase_list) {
3967 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
3968 if (usecase->type == PCM_PLAYBACK) {
3969 select_devices(adev, usecase->id);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003970 break;
3971 }
3972 }
3973 }
3974 pthread_mutex_unlock(&adev->lock);
3975 }
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01003976#endif /* SWAP_SPEAKER_ON_SCREEN_ROTATION */
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003977
3978 str_parms_destroy(parms);
3979
3980 if (ret > 0)
3981 ret = 0;
3982
3983 ALOGV("%s: exit with code(%d)", __func__, ret);
3984 return ret;
3985}
3986
3987static char* adev_get_parameters(const struct audio_hw_device *dev,
3988 const char *keys)
3989{
3990 (void)dev;
3991 (void)keys;
3992
3993 return strdup("");
3994}
3995
3996static int adev_init_check(const struct audio_hw_device *dev)
3997{
3998 (void)dev;
3999
4000 return 0;
4001}
4002
4003static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
4004{
4005 int ret = 0;
4006 struct audio_device *adev = (struct audio_device *)dev;
4007 pthread_mutex_lock(&adev->lock);
4008 /* cache volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004009 adev->voice.volume = volume;
4010 ret = set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004011 pthread_mutex_unlock(&adev->lock);
4012 return ret;
4013}
4014
4015static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
4016{
4017 (void)dev;
4018 (void)volume;
4019
4020 return -ENOSYS;
4021}
4022
4023static int adev_get_master_volume(struct audio_hw_device *dev,
4024 float *volume)
4025{
4026 (void)dev;
4027 (void)volume;
4028
4029 return -ENOSYS;
4030}
4031
4032static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
4033{
4034 (void)dev;
4035 (void)muted;
4036
4037 return -ENOSYS;
4038}
4039
4040static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
4041{
4042 (void)dev;
4043 (void)muted;
4044
4045 return -ENOSYS;
4046}
4047
4048static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
4049{
4050 struct audio_device *adev = (struct audio_device *)dev;
4051
4052 pthread_mutex_lock(&adev->lock);
4053 if (adev->mode != mode) {
4054 ALOGI("%s mode = %d", __func__, mode);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004055 if (amplifier_set_mode(mode) != 0) {
4056 ALOGE("Failed setting amplifier mode");
4057 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004058 adev->mode = mode;
Christopher N. Hesse6c0020c2017-11-17 20:41:11 +01004059
4060 if ((mode == AUDIO_MODE_NORMAL) && adev->voice.in_call) {
4061 stop_voice_call(adev);
4062 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004063 }
4064 pthread_mutex_unlock(&adev->lock);
4065 return 0;
4066}
4067
4068static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
4069{
4070 struct audio_device *adev = (struct audio_device *)dev;
4071 int err = 0;
4072
4073 pthread_mutex_lock(&adev->lock);
4074 adev->mic_mute = state;
4075
4076 if (adev->mode == AUDIO_MODE_IN_CALL) {
Andreas Schneider107a8482017-02-06 12:36:31 +01004077 set_voice_session_mic_mute(adev->voice.session, state);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004078 }
4079
4080 pthread_mutex_unlock(&adev->lock);
4081 return err;
4082}
4083
4084static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
4085{
4086 struct audio_device *adev = (struct audio_device *)dev;
4087
4088 *state = adev->mic_mute;
4089
4090 return 0;
4091}
4092
4093static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
4094 const struct audio_config *config)
4095{
4096 (void)dev;
4097
4098 /* NOTE: we default to built in mic which may cause a mismatch between what we
4099 * report here and the actual buffer size
4100 */
4101 return get_input_buffer_size(config->sample_rate,
4102 config->format,
4103 audio_channel_count_from_in_mask(config->channel_mask),
4104 PCM_CAPTURE /* usecase_type */,
4105 AUDIO_DEVICE_IN_BUILTIN_MIC);
4106}
4107
4108static int adev_open_input_stream(struct audio_hw_device *dev,
4109 audio_io_handle_t handle __unused,
4110 audio_devices_t devices,
4111 struct audio_config *config,
4112 struct audio_stream_in **stream_in,
4113 audio_input_flags_t flags,
4114 const char *address __unused,
4115 audio_source_t source)
4116{
4117 struct audio_device *adev = (struct audio_device *)dev;
4118 struct stream_in *in;
4119 struct pcm_device_profile *pcm_profile;
4120
4121 ALOGV("%s: enter", __func__);
4122
4123 *stream_in = NULL;
4124 if (check_input_parameters(config->sample_rate, config->format,
4125 audio_channel_count_from_in_mask(config->channel_mask)) != 0)
4126 return -EINVAL;
4127
stenkinevgeniy44335362018-05-07 18:00:13 +00004128 usecase_type_t usecase_type = flags & AUDIO_INPUT_FLAG_FAST ?
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004129 PCM_CAPTURE_LOW_LATENCY : PCM_CAPTURE;
4130 pcm_profile = get_pcm_device(usecase_type, devices);
4131 if (pcm_profile == NULL && usecase_type == PCM_CAPTURE_LOW_LATENCY) {
4132 // a low latency profile may not exist for that device, fall back
4133 // to regular capture. the MixerThread automatically changes
4134 // to non-fast capture based on the buffer size.
4135 flags &= ~AUDIO_INPUT_FLAG_FAST;
4136 usecase_type = PCM_CAPTURE;
4137 pcm_profile = get_pcm_device(usecase_type, devices);
4138 }
4139 if (pcm_profile == NULL)
4140 return -EINVAL;
4141
4142 in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
Andreas Schneider56204f62017-01-31 08:17:32 +01004143 if (in == NULL) {
4144 return -ENOMEM;
4145 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004146
4147 in->stream.common.get_sample_rate = in_get_sample_rate;
4148 in->stream.common.set_sample_rate = in_set_sample_rate;
4149 in->stream.common.get_buffer_size = in_get_buffer_size;
4150 in->stream.common.get_channels = in_get_channels;
4151 in->stream.common.get_format = in_get_format;
4152 in->stream.common.set_format = in_set_format;
4153 in->stream.common.standby = in_standby;
4154 in->stream.common.dump = in_dump;
4155 in->stream.common.set_parameters = in_set_parameters;
4156 in->stream.common.get_parameters = in_get_parameters;
4157 in->stream.common.add_audio_effect = in_add_audio_effect;
4158 in->stream.common.remove_audio_effect = in_remove_audio_effect;
4159 in->stream.set_gain = in_set_gain;
4160 in->stream.read = in_read;
4161 in->stream.get_input_frames_lost = in_get_input_frames_lost;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004162 in->stream.get_capture_position = in_get_capture_position;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004163
4164 in->devices = devices;
4165 in->source = source;
4166 in->dev = adev;
4167 in->standby = 1;
4168 in->main_channels = config->channel_mask;
4169 in->requested_rate = config->sample_rate;
4170 if (config->sample_rate != CAPTURE_DEFAULT_SAMPLING_RATE)
4171 flags = flags & ~AUDIO_INPUT_FLAG_FAST;
4172 in->input_flags = flags;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004173 // in->frames_read = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004174 /* HW codec is limited to default channels. No need to update with
4175 * requested channels */
4176 in->config = pcm_profile->config;
4177
4178 /* Update config params with the requested sample rate and channels */
stenkinevgeniy44335362018-05-07 18:00:13 +00004179 in->usecase = USECASE_AUDIO_CAPTURE;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004180 in->usecase_type = usecase_type;
4181
4182 pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
4183 pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL);
4184
4185 in->is_fastcapture_affinity_set = false;
4186
4187 *stream_in = &in->stream;
4188 ALOGV("%s: exit", __func__);
4189 return 0;
4190}
4191
4192static void adev_close_input_stream(struct audio_hw_device *dev,
4193 struct audio_stream_in *stream)
4194{
4195 struct audio_device *adev = (struct audio_device *)dev;
4196 struct stream_in *in = (struct stream_in*)stream;
4197 ALOGV("%s", __func__);
4198
4199 /* prevent concurrent out_set_parameters, or out_write from standby */
4200 pthread_mutex_lock(&adev->lock_inputs);
4201
Andreas Schneidercabe5e62017-01-30 10:57:06 +01004202 if (in->read_buf) {
4203 free(in->read_buf);
4204 in->read_buf = NULL;
4205 }
4206
4207 if (in->resampler) {
4208 release_resampler(in->resampler);
4209 in->resampler = NULL;
4210 }
4211
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004212#ifdef PREPROCESSING_ENABLED
4213 int i;
4214
4215 for (i=0; i<in->num_preprocessors; i++) {
4216 free(in->preprocessors[i].channel_configs);
4217 }
4218
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004219 if (in->proc_buf_in) {
4220 free(in->proc_buf_in);
4221 in->proc_buf_in = NULL;
4222 }
4223
4224 if (in->proc_buf_out) {
4225 free(in->proc_buf_out);
4226 in->proc_buf_out = NULL;
4227 }
4228
4229 if (in->ref_buf) {
4230 free(in->ref_buf);
4231 in->ref_buf = NULL;
4232 }
4233
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004234#endif
4235
4236 in_standby_l(in);
4237 free(stream);
4238
4239 pthread_mutex_unlock(&adev->lock_inputs);
4240
4241 return;
4242}
4243
4244static int adev_dump(const audio_hw_device_t *device, int fd)
4245{
4246 (void)device;
4247 (void)fd;
4248
4249 return 0;
4250}
4251
4252static int adev_close(hw_device_t *device)
4253{
4254 struct audio_device *adev = (struct audio_device *)device;
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004255 voice_session_deinit(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004256 audio_device_ref_count--;
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004257 if (audio_device_ref_count == 0) {
4258 if (amplifier_close() != 0) {
4259 ALOGE("Amplifier close failed");
4260 }
4261 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004262 free(adev->snd_dev_ref_cnt);
4263 free_mixer_list(adev);
4264 free(device);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004265
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004266 adev = NULL;
4267
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004268 return 0;
4269}
4270
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004271/* This returns true if the input parameter looks at all plausible as a low latency period size,
4272 * or false otherwise. A return value of true doesn't mean the value is guaranteed to work,
4273 * just that it _might_ work.
4274 */
4275static bool period_size_is_plausible_for_low_latency(int period_size)
4276{
4277 switch (period_size) {
4278 case 64:
4279 case 96:
4280 case 128:
4281 case 192:
4282 case 256:
4283 return true;
4284 default:
4285 return false;
4286 }
4287}
4288
4289static int adev_open(const hw_module_t *module, const char *name,
4290 hw_device_t **device)
4291{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004292 ALOGV("%s: enter", __func__);
4293 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
4294
Andreas Schneider56204f62017-01-31 08:17:32 +01004295 *device = NULL;
4296
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004297 adev = calloc(1, sizeof(struct audio_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01004298 if (adev == NULL) {
4299 return -ENOMEM;
4300 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004301
4302 adev->device.common.tag = HARDWARE_DEVICE_TAG;
4303 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
4304 adev->device.common.module = (struct hw_module_t *)module;
4305 adev->device.common.close = adev_close;
4306
4307 adev->device.init_check = adev_init_check;
4308 adev->device.set_voice_volume = adev_set_voice_volume;
4309 adev->device.set_master_volume = adev_set_master_volume;
4310 adev->device.get_master_volume = adev_get_master_volume;
4311 adev->device.set_master_mute = adev_set_master_mute;
4312 adev->device.get_master_mute = adev_get_master_mute;
4313 adev->device.set_mode = adev_set_mode;
4314 adev->device.set_mic_mute = adev_set_mic_mute;
4315 adev->device.get_mic_mute = adev_get_mic_mute;
4316 adev->device.set_parameters = adev_set_parameters;
4317 adev->device.get_parameters = adev_get_parameters;
4318 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
4319 adev->device.open_output_stream = adev_open_output_stream;
4320 adev->device.close_output_stream = adev_close_output_stream;
4321 adev->device.open_input_stream = adev_open_input_stream;
4322 adev->device.close_input_stream = adev_close_input_stream;
4323 adev->device.dump = adev_dump;
4324
4325 /* Set the default route before the PCM stream is opened */
4326 adev->mode = AUDIO_MODE_NORMAL;
4327 adev->active_input = NULL;
4328 adev->primary_output = NULL;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004329
4330 adev->voice.volume = 1.0f;
4331 adev->voice.bluetooth_nrec = true;
4332 adev->voice.in_call = false;
Christopher N. Hessee4a1c592018-01-16 18:33:38 +01004333 adev->voice.bluetooth_wb = false;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004334
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004335 /* adev->cur_hdmi_channels = 0; by calloc() */
4336 adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
Andreas Schneider56204f62017-01-31 08:17:32 +01004337 if (adev->snd_dev_ref_cnt == NULL) {
4338 free(adev);
4339 return -ENOMEM;
4340 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004341
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004342 adev->ns_in_voice_rec = false;
4343
4344 list_init(&adev->usecase_list);
4345
4346 if (mixer_init(adev) != 0) {
4347 free(adev->snd_dev_ref_cnt);
4348 free(adev);
4349 ALOGE("%s: Failed to init, aborting.", __func__);
4350 *device = NULL;
4351 return -EINVAL;
4352 }
4353
4354 if (access(OFFLOAD_FX_LIBRARY_PATH, R_OK) == 0) {
4355 adev->offload_fx_lib = dlopen(OFFLOAD_FX_LIBRARY_PATH, RTLD_NOW);
4356 if (adev->offload_fx_lib == NULL) {
4357 ALOGE("%s: DLOPEN failed for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4358 } else {
4359 ALOGV("%s: DLOPEN successful for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4360 adev->offload_fx_start_output =
4361 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4362 "visualizer_hal_start_output");
4363 adev->offload_fx_stop_output =
4364 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4365 "visualizer_hal_stop_output");
4366 }
4367 }
4368
Christopher N. Hesse696959d2017-02-02 20:49:55 +01004369 adev->voice.session = voice_session_init(adev);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004370 if (adev->voice.session == NULL) {
4371 ALOGE("%s: Failed to initialize voice session data", __func__);
4372
4373 free(adev->snd_dev_ref_cnt);
4374 free(adev);
4375
4376 *device = NULL;
4377 return -EINVAL;
4378 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004379
Christopher N. Hessec487bbe2018-07-12 13:51:43 +02004380 if (amplifier_open() != -ENOENT) {
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004381 ALOGE("Amplifier initialization failed");
4382 }
4383
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004384 *device = &adev->device.common;
4385
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004386 audio_device_ref_count++;
4387
4388 char value[PROPERTY_VALUE_MAX];
4389 if (property_get("audio_hal.period_size", value, NULL) > 0) {
4390 int trial = atoi(value);
4391 if (period_size_is_plausible_for_low_latency(trial)) {
4392
4393 pcm_device_playback.config.period_size = trial;
4394 pcm_device_playback.config.start_threshold =
4395 PLAYBACK_START_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4396 pcm_device_playback.config.stop_threshold =
4397 PLAYBACK_STOP_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4398
4399 pcm_device_capture_low_latency.config.period_size = trial;
4400 }
4401 }
4402
4403 ALOGV("%s: exit", __func__);
4404 return 0;
4405}
4406
4407static struct hw_module_methods_t hal_module_methods = {
4408 .open = adev_open,
4409};
4410
4411struct audio_module HAL_MODULE_INFO_SYM = {
4412 .common = {
4413 .tag = HARDWARE_MODULE_TAG,
4414 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
4415 .hal_api_version = HARDWARE_HAL_API_VERSION,
4416 .id = AUDIO_HARDWARE_MODULE_ID,
Christopher N. Hessec8502b92017-01-28 14:02:15 +01004417 .name = "Samsung Audio HAL",
4418 .author = "The LineageOS Project",
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004419 .methods = &hal_module_methods,
4420 },
4421};