blob: 7bb02a0f812292ee24cdd6cc06972b6c21d07266 [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|
stenkinevgeniy3de97672018-05-20 14:18:53 +000075 AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|
76 AUDIO_DEVICE_OUT_BLUETOOTH_SCO|AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET|
77 AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT,
Christopher N. Hesse297a6362017-01-28 12:40:45 +010078};
79
Christopher N. Hesse8414bd22017-01-30 18:57:20 +010080static struct pcm_device_profile pcm_device_deep_buffer = {
81 .config = {
82 .channels = PLAYBACK_DEFAULT_CHANNEL_COUNT,
83 .rate = DEEP_BUFFER_OUTPUT_SAMPLING_RATE,
84 .period_size = DEEP_BUFFER_OUTPUT_PERIOD_SIZE,
85 .period_count = DEEP_BUFFER_OUTPUT_PERIOD_COUNT,
86 .format = PCM_FORMAT_S16_LE,
87 .start_threshold = DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4,
88 .stop_threshold = INT_MAX,
89 .avail_min = DEEP_BUFFER_OUTPUT_PERIOD_SIZE / 4,
90 },
91 .card = SOUND_CARD,
92 .id = SOUND_DEEP_BUFFER_DEVICE,
93 .type = PCM_PLAYBACK,
94 .devices = AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|
stenkinevgeniy3de97672018-05-20 14:18:53 +000095 AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|
96 AUDIO_DEVICE_OUT_BLUETOOTH_SCO|AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET|
97 AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT,
Christopher N. Hesse8414bd22017-01-30 18:57:20 +010098};
99
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100100static struct pcm_device_profile pcm_device_capture = {
101 .config = {
102 .channels = CAPTURE_DEFAULT_CHANNEL_COUNT,
103 .rate = CAPTURE_DEFAULT_SAMPLING_RATE,
104 .period_size = CAPTURE_PERIOD_SIZE,
105 .period_count = CAPTURE_PERIOD_COUNT,
106 .format = PCM_FORMAT_S16_LE,
107 .start_threshold = CAPTURE_START_THRESHOLD,
108 .stop_threshold = 0,
109 .silence_threshold = 0,
110 .avail_min = 0,
111 },
112 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100113 .id = SOUND_CAPTURE_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100114 .type = PCM_CAPTURE,
115 .devices = AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BACK_MIC,
116};
117
118static struct pcm_device_profile pcm_device_capture_low_latency = {
119 .config = {
120 .channels = CAPTURE_DEFAULT_CHANNEL_COUNT,
121 .rate = CAPTURE_DEFAULT_SAMPLING_RATE,
122 .period_size = CAPTURE_PERIOD_SIZE_LOW_LATENCY,
123 .period_count = CAPTURE_PERIOD_COUNT_LOW_LATENCY,
124 .format = PCM_FORMAT_S16_LE,
125 .start_threshold = CAPTURE_START_THRESHOLD,
126 .stop_threshold = 0,
127 .silence_threshold = 0,
128 .avail_min = 0,
129 },
130 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100131 .id = SOUND_CAPTURE_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100132 .type = PCM_CAPTURE_LOW_LATENCY,
133 .devices = AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET|AUDIO_DEVICE_IN_BACK_MIC,
134};
135
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100136static struct pcm_device_profile pcm_device_capture_sco = {
137 .config = {
138 .channels = SCO_DEFAULT_CHANNEL_COUNT,
139 .rate = SCO_DEFAULT_SAMPLING_RATE,
140 .period_size = SCO_PERIOD_SIZE,
141 .period_count = SCO_PERIOD_COUNT,
142 .format = PCM_FORMAT_S16_LE,
143 .start_threshold = CAPTURE_START_THRESHOLD,
144 .stop_threshold = 0,
145 .silence_threshold = 0,
146 .avail_min = 0,
147 },
148 .card = SOUND_CARD,
Christopher N. Hessed23c6b52017-01-28 14:18:10 +0100149 .id = SOUND_CAPTURE_SCO_DEVICE,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100150 .type = PCM_CAPTURE,
151 .devices = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
152};
153
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100154static struct pcm_device_profile * const pcm_devices[] = {
155 &pcm_device_playback,
156 &pcm_device_capture,
157 &pcm_device_capture_low_latency,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100158 &pcm_device_capture_sco,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100159 NULL,
160};
161
162static const char * const use_case_table[AUDIO_USECASE_MAX] = {
163 [USECASE_AUDIO_PLAYBACK] = "playback",
164 [USECASE_AUDIO_PLAYBACK_MULTI_CH] = "playback multi-channel",
165 [USECASE_AUDIO_PLAYBACK_OFFLOAD] = "compress-offload-playback",
Andreas Schneiderdf6fc8a2017-02-14 11:38:41 +0100166 [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = "playback deep-buffer",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100167 [USECASE_AUDIO_CAPTURE] = "capture",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100168 [USECASE_VOICE_CALL] = "voice-call",
169};
170
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100171#define STRING_TO_ENUM(string) { #string, string }
172
173static unsigned int audio_device_ref_count;
174
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100175struct string_to_enum {
176 const char *name;
177 uint32_t value;
178};
179
180static const struct string_to_enum out_channels_name_to_enum_table[] = {
181 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO),
182 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1),
183 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
184};
185
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +0200186static struct audio_device *adev = NULL;
187
188static amplifier_device_t * get_amplifier_device(void)
189{
190 if (adev)
191 return adev->amp;
192
193 return NULL;
194}
195
196static int amplifier_open(void)
197{
198 int rc;
199 amplifier_module_t *module;
200
201 rc = hw_get_module(AMPLIFIER_HARDWARE_MODULE_ID,
202 (const hw_module_t **) &module);
203 if (rc) {
Christopher N. Hessec487bbe2018-07-12 13:51:43 +0200204 if (rc == -ENOENT) {
205 // no amplifier HAL present
206 return -ENOENT;
207 }
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +0200208 ALOGV("%s: Failed to obtain reference to amplifier module: %s\n",
209 __func__, strerror(-rc));
210 return -ENODEV;
211 }
212
213 rc = amplifier_device_open((const hw_module_t *) module, &adev->amp);
214 if (rc) {
215 ALOGV("%s: Failed to open amplifier hardware device: %s\n",
216 __func__, strerror(-rc));
217 return -ENODEV;
218 }
219
220 return 0;
221}
222
223static int amplifier_set_input_devices(uint32_t devices)
224{
225 amplifier_device_t *amp = get_amplifier_device();
226 if (amp && amp->set_input_devices)
227 return amp->set_input_devices(amp, devices);
228
229 return 0;
230}
231
232static int amplifier_set_output_devices(uint32_t devices)
233{
234 amplifier_device_t *amp = get_amplifier_device();
235 if (amp && amp->set_output_devices)
236 return amp->set_output_devices(amp, devices);
237
238 return 0;
239}
240
241static int amplifier_enable_devices(uint32_t devices, bool enable)
242{
243 amplifier_device_t *amp = get_amplifier_device();
244 bool is_output = devices > SND_DEVICE_OUT_BEGIN &&
245 devices < SND_DEVICE_OUT_END;
246
247 if (amp && amp->enable_output_devices && is_output)
248 return amp->enable_output_devices(amp, devices, enable);
249
250 if (amp && amp->enable_input_devices && !is_output)
251 return amp->enable_input_devices(amp, devices, enable);
252
253 return 0;
254}
255
256static int amplifier_set_mode(audio_mode_t mode)
257{
258 amplifier_device_t *amp = get_amplifier_device();
259 if (amp && amp->set_mode)
260 return amp->set_mode(amp, mode);
261
262 return 0;
263}
264
265static int amplifier_output_stream_start(struct audio_stream_out *stream,
266 bool offload)
267{
268 amplifier_device_t *amp = get_amplifier_device();
269 if (amp && amp->output_stream_start)
270 return amp->output_stream_start(amp, stream, offload);
271
272 return 0;
273}
274
275static int amplifier_input_stream_start(struct audio_stream_in *stream)
276{
277 amplifier_device_t *amp = get_amplifier_device();
278 if (amp && amp->input_stream_start)
279 return amp->input_stream_start(amp, stream);
280
281 return 0;
282}
283
284static int amplifier_output_stream_standby(struct audio_stream_out *stream)
285{
286 amplifier_device_t *amp = get_amplifier_device();
287 if (amp && amp->output_stream_standby)
288 return amp->output_stream_standby(amp, stream);
289
290 return 0;
291}
292
293static int amplifier_input_stream_standby(struct audio_stream_in *stream)
294{
295 amplifier_device_t *amp = get_amplifier_device();
296 if (amp && amp->input_stream_standby)
297 return amp->input_stream_standby(amp, stream);
298
299 return 0;
300}
301
302static int amplifier_set_parameters(struct str_parms *parms)
303{
304 amplifier_device_t *amp = get_amplifier_device();
305 if (amp && amp->set_parameters)
306 return amp->set_parameters(amp, parms);
307
308 return 0;
309}
310
311static int amplifier_close(void)
312{
313 amplifier_device_t *amp = get_amplifier_device();
314 if (amp)
315 amplifier_device_close(amp);
316
317 return 0;
318}
319
Andreas Schneider759368f2017-02-02 16:11:14 +0100320struct timespec time_spec_diff(struct timespec time1, struct timespec time0) {
321 struct timespec ret;
322 int xsec = 0;
Andreas Schneider759368f2017-02-02 16:11:14 +0100323
324 if (time0.tv_nsec > time1.tv_nsec) {
325 xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1));
326 time0.tv_nsec -= (long int) (1E9 * xsec);
327 time0.tv_sec += xsec;
328 }
329
330 if ((time1.tv_nsec - time0.tv_nsec) > 1E9) {
331 xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9);
332 time0.tv_nsec += (long int) (1E9 * xsec);
333 time0.tv_sec -= xsec;
334 }
335
Paul Keithf114e2e2017-02-14 20:41:33 -0600336 ret.tv_sec = labs(time1.tv_sec - time0.tv_sec);
337 ret.tv_nsec = labs(time1.tv_nsec - time0.tv_nsec);
Andreas Schneider759368f2017-02-02 16:11:14 +0100338
339 return ret;
340}
341
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100342static bool is_supported_format(audio_format_t format)
343{
344 if (format == AUDIO_FORMAT_MP3 ||
345 ((format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_AAC))
346 return true;
347
348 return false;
349}
350
351static int get_snd_codec_id(audio_format_t format)
352{
353 int id = 0;
354
355 switch (format & AUDIO_FORMAT_MAIN_MASK) {
356 case AUDIO_FORMAT_MP3:
357 id = SND_AUDIOCODEC_MP3;
358 break;
359 case AUDIO_FORMAT_AAC:
360 id = SND_AUDIOCODEC_AAC;
361 break;
362 default:
363 ALOGE("%s: Unsupported audio format", __func__);
364 }
365
366 return id;
367}
368
369/* Array to store sound devices */
370static const char * const device_table[SND_DEVICE_MAX] = {
371 [SND_DEVICE_NONE] = "none",
372 /* Playback sound devices */
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100373 [SND_DEVICE_OUT_EARPIECE] = "earpiece",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100374 [SND_DEVICE_OUT_SPEAKER] = "speaker",
375 [SND_DEVICE_OUT_HEADPHONES] = "headphones",
376 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100377 [SND_DEVICE_OUT_VOICE_EARPIECE] = "voice-earpiece",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100378 [SND_DEVICE_OUT_VOICE_EARPIECE_WB] = "voice-earpiece-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100379 [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100380 [SND_DEVICE_OUT_VOICE_SPEAKER_WB] = "voice-speaker-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100381 [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100382 [SND_DEVICE_OUT_VOICE_HEADPHONES_WB] = "voice-headphones-wb",
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100383 [SND_DEVICE_OUT_VOICE_BT_SCO] = "voice-bt-sco-headset",
384 [SND_DEVICE_OUT_VOICE_BT_SCO_WB] = "voice-bt-sco-headset-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100385 [SND_DEVICE_OUT_HDMI] = "hdmi",
386 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
387 [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100388
389 /* Capture sound devices */
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100390 [SND_DEVICE_IN_EARPIECE_MIC] = "earpiece-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100391 [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
392 [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100393 [SND_DEVICE_IN_EARPIECE_MIC_AEC] = "earpiece-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100394 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "voice-speaker-mic",
395 [SND_DEVICE_IN_HEADSET_MIC_AEC] = "headset-mic",
Andreas Schneider82f32482017-02-06 09:00:48 +0100396 [SND_DEVICE_IN_VOICE_MIC] = "voice-mic",
397 [SND_DEVICE_IN_VOICE_EARPIECE_MIC] = "voice-earpiece-mic",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100398 [SND_DEVICE_IN_VOICE_EARPIECE_MIC_WB] = "voice-earpiece-mic-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100399 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100400 [SND_DEVICE_IN_VOICE_SPEAKER_MIC_WB] = "voice-speaker-mic-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100401 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100402 [SND_DEVICE_IN_VOICE_HEADSET_MIC_WB] = "voice-headset-mic-wb",
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100403 [SND_DEVICE_IN_VOICE_BT_SCO_MIC] = "voice-bt-sco-mic",
404 [SND_DEVICE_IN_VOICE_BT_SCO_MIC_WB] = "voice-bt-sco-mic-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100405 [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
406 [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
407 [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100408 [SND_DEVICE_IN_VOICE_REC_HEADSET_MIC] = "voice-rec-headset-mic",
409 [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100410};
411
412static struct mixer_card *adev_get_mixer_for_card(struct audio_device *adev, int card)
413{
414 struct mixer_card *mixer_card;
415 struct listnode *node;
416
417 list_for_each(node, &adev->mixer_list) {
418 mixer_card = node_to_item(node, struct mixer_card, adev_list_node);
419 if (mixer_card->card == card)
420 return mixer_card;
421 }
422 return NULL;
423}
424
425static struct mixer_card *uc_get_mixer_for_card(struct audio_usecase *usecase, int card)
426{
427 struct mixer_card *mixer_card;
428 struct listnode *node;
429
430 list_for_each(node, &usecase->mixer_list) {
431 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[usecase->id]);
432 if (mixer_card->card == card)
433 return mixer_card;
434 }
435 return NULL;
436}
437
438static void free_mixer_list(struct audio_device *adev)
439{
440 struct mixer_card *mixer_card;
441 struct listnode *node;
442 struct listnode *next;
443
444 list_for_each_safe(node, next, &adev->mixer_list) {
445 mixer_card = node_to_item(node, struct mixer_card, adev_list_node);
446 list_remove(node);
447 audio_route_free(mixer_card->audio_route);
448 free(mixer_card);
449 }
450}
451
452static int mixer_init(struct audio_device *adev)
453{
454 int i;
455 int card;
456 int retry_num;
457 struct mixer *mixer;
458 struct audio_route *audio_route;
459 char mixer_path[PATH_MAX];
460 struct mixer_card *mixer_card;
Andreas Schneider56204f62017-01-31 08:17:32 +0100461 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100462
463 list_init(&adev->mixer_list);
464
465 for (i = 0; pcm_devices[i] != NULL; i++) {
466 card = pcm_devices[i]->card;
467 if (adev_get_mixer_for_card(adev, card) == NULL) {
468 retry_num = 0;
469 do {
470 mixer = mixer_open(card);
471 if (mixer == NULL) {
472 if (++retry_num > RETRY_NUMBER) {
473 ALOGE("%s unable to open the mixer for--card %d, aborting.",
474 __func__, card);
Andreas Schneider56204f62017-01-31 08:17:32 +0100475 ret = -ENODEV;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100476 goto error;
477 }
478 usleep(RETRY_US);
479 }
480 } while (mixer == NULL);
481
Christopher N. Hessed8d04fd2018-01-28 00:07:47 +0100482 sprintf(mixer_path, "/vendor/etc/mixer_paths_%d.xml", card);
Christopher N. Hesse2beff422018-01-28 13:16:17 +0100483 if (access(mixer_path, F_OK) == -1) {
Christopher N. Hessed8d04fd2018-01-28 00:07:47 +0100484 ALOGW("%s: Failed to open mixer paths from %s, retrying with legacy location",
Christopher N. Hesse2beff422018-01-28 13:16:17 +0100485 __func__, mixer_path);
Christopher N. Hessed8d04fd2018-01-28 00:07:47 +0100486 sprintf(mixer_path, "/system/etc/mixer_paths_%d.xml", card);
487 if (access(mixer_path, F_OK) == -1) {
488 ALOGE("%s: Failed to load a mixer paths configuration, your system will crash",
489 __func__);
490 }
Christopher N. Hesse2beff422018-01-28 13:16:17 +0100491 }
492
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100493 audio_route = audio_route_init(card, mixer_path);
494 if (!audio_route) {
495 ALOGE("%s: Failed to init audio route controls for card %d, aborting.",
496 __func__, card);
Andreas Schneider56204f62017-01-31 08:17:32 +0100497 ret = -ENODEV;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100498 goto error;
499 }
500 mixer_card = calloc(1, sizeof(struct mixer_card));
Andreas Schneider56204f62017-01-31 08:17:32 +0100501 if (mixer_card == NULL) {
502 ret = -ENOMEM;
503 goto error;
504 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100505 mixer_card->card = card;
506 mixer_card->mixer = mixer;
507 mixer_card->audio_route = audio_route;
Andreas Schneider759368f2017-02-02 16:11:14 +0100508
509 /* Do not sleep on first enable_snd_device() */
510 mixer_card->dsp_poweroff_time.tv_sec = 1;
511 mixer_card->dsp_poweroff_time.tv_nsec = 0;
512
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100513 list_add_tail(&adev->mixer_list, &mixer_card->adev_list_node);
514 }
515 }
516
517 return 0;
518
519error:
520 free_mixer_list(adev);
Andreas Schneider56204f62017-01-31 08:17:32 +0100521 return ret;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100522}
523
524static const char *get_snd_device_name(snd_device_t snd_device)
525{
526 const char *name = NULL;
527
Andreas Schneideradb788d2017-02-13 15:19:36 +0100528 if (snd_device == SND_DEVICE_NONE ||
Andreas Schneiderdde54c02017-02-15 14:10:58 +0100529 (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX))
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100530 name = device_table[snd_device];
531
532 ALOGE_IF(name == NULL, "%s: invalid snd device %d", __func__, snd_device);
533
534 return name;
535}
536
537static const char *get_snd_device_display_name(snd_device_t snd_device)
538{
539 const char *name = get_snd_device_name(snd_device);
540
541 if (name == NULL)
542 name = "SND DEVICE NOT FOUND";
543
544 return name;
545}
546
547static struct pcm_device_profile *get_pcm_device(usecase_type_t uc_type, audio_devices_t devices)
548{
549 int i;
550
551 devices &= ~AUDIO_DEVICE_BIT_IN;
552 for (i = 0; pcm_devices[i] != NULL; i++) {
553 if ((pcm_devices[i]->type == uc_type) &&
554 (devices & pcm_devices[i]->devices))
555 break;
556 }
557 return pcm_devices[i];
558}
559
560static struct audio_usecase *get_usecase_from_id(struct audio_device *adev,
561 audio_usecase_t uc_id)
562{
563 struct audio_usecase *usecase;
564 struct listnode *node;
565
566 list_for_each(node, &adev->usecase_list) {
567 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
568 if (usecase->id == uc_id)
569 return usecase;
570 }
571 return NULL;
572}
573
574static struct audio_usecase *get_usecase_from_type(struct audio_device *adev,
575 usecase_type_t type)
576{
577 struct audio_usecase *usecase;
578 struct listnode *node;
579
580 list_for_each(node, &adev->usecase_list) {
581 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
582 if (usecase->type & type)
583 return usecase;
584 }
585 return NULL;
586}
587
588/* always called with adev lock held */
589static int set_voice_volume_l(struct audio_device *adev, float volume)
590{
591 int err = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100592
593 if (adev->mode == AUDIO_MODE_IN_CALL) {
Christopher N. Hesse696959d2017-02-02 20:49:55 +0100594 set_voice_session_volume(adev->voice.session, volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100595 }
Christopher N. Hesse696959d2017-02-02 20:49:55 +0100596
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100597 return err;
598}
599
600
601static snd_device_t get_output_snd_device(struct audio_device *adev, audio_devices_t devices)
602{
603
604 audio_mode_t mode = adev->mode;
605 snd_device_t snd_device = SND_DEVICE_NONE;
606
607 ALOGV("%s: enter: output devices(%#x), mode(%d)", __func__, devices, mode);
608 if (devices == AUDIO_DEVICE_NONE ||
609 devices & AUDIO_DEVICE_BIT_IN) {
610 ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
611 goto exit;
612 }
613
614 if (mode == AUDIO_MODE_IN_CALL) {
615 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
616 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Andreas Schneidera2b77322017-01-30 22:33:56 +0100617 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
Fevax51bd12c2017-03-15 10:56:39 -0300618 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100619 snd_device = SND_DEVICE_OUT_VOICE_BT_SCO;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100620 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
621 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
622 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Andreas Schneider59486fa2017-02-06 09:16:39 +0100623 snd_device = SND_DEVICE_OUT_VOICE_EARPIECE;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100624 }
Andreas Schneider59486fa2017-02-06 09:16:39 +0100625
626 if (voice_session_uses_wideband(adev->voice.session)) {
627 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
628 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
629 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES_WB;
Fevax51bd12c2017-03-15 10:56:39 -0300630 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100631 snd_device = SND_DEVICE_OUT_VOICE_BT_SCO_WB;
Andreas Schneider59486fa2017-02-06 09:16:39 +0100632 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
633 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_WB;
634 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
635 snd_device = SND_DEVICE_OUT_VOICE_EARPIECE_WB;
636 }
637 }
638
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100639 if (snd_device != SND_DEVICE_NONE) {
640 goto exit;
641 }
642 }
643
644 if (popcount(devices) == 2) {
645 if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
646 AUDIO_DEVICE_OUT_SPEAKER)) {
647 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
648 } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
649 AUDIO_DEVICE_OUT_SPEAKER)) {
650 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
651 } else {
652 ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
653 goto exit;
654 }
655 if (snd_device != SND_DEVICE_NONE) {
656 goto exit;
657 }
658 }
659
660 if (popcount(devices) != 1) {
661 ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
662 goto exit;
663 }
664
665 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
666 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
667 snd_device = SND_DEVICE_OUT_HEADPHONES;
668 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
669 snd_device = SND_DEVICE_OUT_SPEAKER;
670 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
671 snd_device = SND_DEVICE_OUT_BT_SCO;
672 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100673 snd_device = SND_DEVICE_OUT_EARPIECE;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100674 } else {
675 ALOGE("%s: Unknown device(s) %#x", __func__, devices);
676 }
677exit:
678 ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
679 return snd_device;
680}
681
682static snd_device_t get_input_snd_device(struct audio_device *adev, audio_devices_t out_device)
683{
684 audio_source_t source;
685 audio_mode_t mode = adev->mode;
686 audio_devices_t in_device;
687 audio_channel_mask_t channel_mask;
688 snd_device_t snd_device = SND_DEVICE_NONE;
689 struct stream_in *active_input = NULL;
690 struct audio_usecase *usecase;
691
692 usecase = get_usecase_from_type(adev, PCM_CAPTURE|VOICE_CALL);
693 if (usecase != NULL) {
694 active_input = (struct stream_in *)usecase->stream;
695 }
696 source = (active_input == NULL) ?
697 AUDIO_SOURCE_DEFAULT : active_input->source;
698
Andreas Schneider757e2d82017-02-10 19:28:35 +0100699 in_device = (active_input == NULL) ?
700 AUDIO_DEVICE_NONE :
701 (active_input->devices & ~AUDIO_DEVICE_BIT_IN);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100702 channel_mask = (active_input == NULL) ?
703 AUDIO_CHANNEL_IN_MONO : active_input->main_channels;
704
705 ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
706 __func__, out_device, in_device);
707 if (mode == AUDIO_MODE_IN_CALL) {
708 if (out_device == AUDIO_DEVICE_NONE) {
709 ALOGE("%s: No output device set for voice call", __func__);
710 goto exit;
711 }
Andreas Schneidera2b77322017-01-30 22:33:56 +0100712
Andreas Schneider82f32482017-02-06 09:00:48 +0100713 snd_device = SND_DEVICE_IN_VOICE_MIC;
714 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100715 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
Andreas Schneider82f32482017-02-06 09:00:48 +0100716 }
717
718 if (voice_session_uses_twomic(adev->voice.session)) {
719 if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
720 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
721 snd_device = SND_DEVICE_IN_VOICE_EARPIECE_MIC;
722 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
723 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
724 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100725 }
Andreas Schneider59486fa2017-02-06 09:16:39 +0100726
727 if (voice_session_uses_wideband(adev->voice.session)) {
728 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
729 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC_WB;
730 }
731
732 if (voice_session_uses_twomic(adev->voice.session)) {
733 if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
734 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
735 snd_device = SND_DEVICE_IN_VOICE_EARPIECE_MIC_WB;
736 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
737 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC_WB;
738 }
739 }
740 }
Andreas Schneider05bc1882017-02-09 14:03:11 +0100741
742 /* BT SCO */
743 if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
Andreas Schneider05bc1882017-02-09 14:03:11 +0100744
stenkinevgeniy097e2942018-05-22 18:06:48 +0000745 if (voice_session_uses_wideband(adev->voice.session)) {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100746 snd_device = SND_DEVICE_IN_VOICE_BT_SCO_MIC_WB;
stenkinevgeniy097e2942018-05-22 18:06:48 +0000747 } else {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100748 snd_device = SND_DEVICE_IN_VOICE_BT_SCO_MIC;
Andreas Schneider05bc1882017-02-09 14:03:11 +0100749 }
750 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100751 } else if (source == AUDIO_SOURCE_CAMCORDER) {
752 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
753 in_device & AUDIO_DEVICE_IN_BACK_MIC) {
754 snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
755 }
756 } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
757 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100758 if (snd_device == SND_DEVICE_NONE) {
759 snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
760 }
761 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
762 snd_device = SND_DEVICE_IN_VOICE_REC_HEADSET_MIC;
763 }
764 } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION || source == AUDIO_SOURCE_MIC) {
765 if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
766 in_device = AUDIO_DEVICE_IN_BACK_MIC;
767 if (active_input) {
768 if (active_input->enable_aec) {
769 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
770 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
771 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
772 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
773 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
774 } else {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100775 snd_device = SND_DEVICE_IN_EARPIECE_MIC_AEC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100776 }
777 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
778 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
779 }
780 }
781 /* TODO: set echo reference */
782 }
783 } else if (source == AUDIO_SOURCE_DEFAULT) {
784 goto exit;
785 }
786
787
788 if (snd_device != SND_DEVICE_NONE) {
789 goto exit;
790 }
791
792 if (in_device != AUDIO_DEVICE_NONE &&
793 !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
794 !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
795 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100796 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100797 } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
798 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
799 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
800 snd_device = SND_DEVICE_IN_HEADSET_MIC;
801 } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
802 snd_device = SND_DEVICE_IN_BT_SCO_MIC ;
803 } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
804 snd_device = SND_DEVICE_IN_HDMI_MIC;
805 } else {
806 ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100807 ALOGW("%s: Using default earpiece-mic", __func__);
808 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100809 }
810 } else {
811 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100812 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100813 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
814 snd_device = SND_DEVICE_IN_HEADSET_MIC;
815 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
816 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
817 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
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 (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
820 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
821 } else {
822 ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100823 ALOGW("%s: Using default earpiece-mic", __func__);
824 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100825 }
826 }
827exit:
828 ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
829 return snd_device;
830}
831
Andreas Schneider5a2f1002017-02-09 10:59:04 +0100832#if 0
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100833static int set_hdmi_channels(struct audio_device *adev, int channel_count)
834{
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100835 (void)adev;
836 (void)channel_count;
837 /* TODO */
838
839 return 0;
840}
841
842static int edid_get_max_channels(struct audio_device *adev)
843{
844 int max_channels = 2;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100845 (void)adev;
846
847 /* TODO */
848 return max_channels;
849}
Andreas Schneider5a2f1002017-02-09 10:59:04 +0100850#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100851
852/* Delay in Us */
853static int64_t render_latency(audio_usecase_t usecase)
854{
855 (void)usecase;
856 /* TODO */
857 return 0;
858}
859
860static int enable_snd_device(struct audio_device *adev,
861 struct audio_usecase *uc_info,
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100862 snd_device_t snd_device)
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100863{
864 struct mixer_card *mixer_card;
865 struct listnode *node;
866 const char *snd_device_name = get_snd_device_name(snd_device);
Andreas Schneider759368f2017-02-02 16:11:14 +0100867#ifdef DSP_POWEROFF_DELAY
868 struct timespec activation_time;
869 struct timespec elapsed_time;
870#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100871
872 if (snd_device_name == NULL)
873 return -EINVAL;
874
875 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES) {
876 ALOGV("Request to enable combo device: enable individual devices\n");
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100877 enable_snd_device(adev, uc_info, SND_DEVICE_OUT_SPEAKER);
878 enable_snd_device(adev, uc_info, SND_DEVICE_OUT_HEADPHONES);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100879 return 0;
880 }
881 adev->snd_dev_ref_cnt[snd_device]++;
882 if (adev->snd_dev_ref_cnt[snd_device] > 1) {
883 ALOGV("%s: snd_device(%d: %s) is already active",
884 __func__, snd_device, snd_device_name);
885 return 0;
886 }
887
888 ALOGV("%s: snd_device(%d: %s)", __func__,
889 snd_device, snd_device_name);
890
891 list_for_each(node, &uc_info->mixer_list) {
892 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]);
Andreas Schneider759368f2017-02-02 16:11:14 +0100893
894#ifdef DSP_POWEROFF_DELAY
895 clock_gettime(CLOCK_MONOTONIC, &activation_time);
896
Andreas Schneider58735a92017-02-13 16:48:17 +0100897 elapsed_time = time_spec_diff(activation_time,
898 mixer_card->dsp_poweroff_time);
Andreas Schneider759368f2017-02-02 16:11:14 +0100899 if (elapsed_time.tv_sec == 0) {
900 long elapsed_usec = elapsed_time.tv_nsec / 1000;
901
902 if (elapsed_usec < DSP_POWEROFF_DELAY) {
903 usleep(DSP_POWEROFF_DELAY - elapsed_usec);
904 }
905 }
Andreas Schneider759368f2017-02-02 16:11:14 +0100906#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +0200907
908 amplifier_enable_devices(snd_device, true);
909
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100910 audio_route_apply_and_update_path(mixer_card->audio_route, snd_device_name);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100911 }
912
913 return 0;
914}
915
Christopher N. Hesse757ac412017-01-28 14:42:48 +0100916int disable_snd_device(struct audio_device *adev,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100917 struct audio_usecase *uc_info,
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100918 snd_device_t snd_device)
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100919{
920 struct mixer_card *mixer_card;
921 struct listnode *node;
Christopher N. Hesse11ef2112018-02-02 23:19:42 +0100922 struct audio_usecase *out_uc_info = get_usecase_from_type(adev, PCM_PLAYBACK);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100923 const char *snd_device_name = get_snd_device_name(snd_device);
Christopher N. Hesse11ef2112018-02-02 23:19:42 +0100924 const char *out_snd_device_name = NULL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100925
926 if (snd_device_name == NULL)
927 return -EINVAL;
928
929 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES) {
930 ALOGV("Request to disable combo device: disable individual devices\n");
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100931 disable_snd_device(adev, uc_info, SND_DEVICE_OUT_SPEAKER);
932 disable_snd_device(adev, uc_info, SND_DEVICE_OUT_HEADPHONES);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100933 return 0;
934 }
935
936 if (adev->snd_dev_ref_cnt[snd_device] <= 0) {
937 ALOGE("%s: device ref cnt is already 0", __func__);
938 return -EINVAL;
939 }
940 adev->snd_dev_ref_cnt[snd_device]--;
941 if (adev->snd_dev_ref_cnt[snd_device] == 0) {
942 ALOGV("%s: snd_device(%d: %s)", __func__,
943 snd_device, snd_device_name);
944 list_for_each(node, &uc_info->mixer_list) {
945 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]);
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100946 audio_route_reset_and_update_path(mixer_card->audio_route, snd_device_name);
Christopher N. Hesse719630a2018-02-12 01:47:48 +0100947 if (snd_device > SND_DEVICE_IN_BEGIN && out_uc_info != NULL) {
Christopher N. Hesse11ef2112018-02-02 23:19:42 +0100948 /*
949 * Cycle the rx device to eliminate routing conflicts.
950 * This prevents issues when an input route shares mixer controls with an output
951 * route.
952 */
953 out_snd_device_name = get_snd_device_name(out_uc_info->out_snd_device);
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100954 audio_route_apply_and_update_path(mixer_card->audio_route, out_snd_device_name);
Andreas Schneider759368f2017-02-02 16:11:14 +0100955 }
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +0200956
957 amplifier_enable_devices(snd_device, false);
Andreas Schneider759368f2017-02-02 16:11:14 +0100958#ifdef DSP_POWEROFF_DELAY
959 clock_gettime(CLOCK_MONOTONIC, &(mixer_card->dsp_poweroff_time));
960#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100961 }
962 }
963 return 0;
964}
965
stenkinevgeniyb81e05f2018-05-08 12:02:35 +0000966static void check_and_route_usecases(struct audio_device *adev,
967 struct audio_usecase *uc_info,
968 usecase_type_t type,
969 snd_device_t snd_device)
970{
971 struct listnode *node;
972 struct audio_usecase *usecase;
973 bool switch_device[AUDIO_USECASE_MAX], need_switch = false;
974 snd_device_t usecase_snd_device = SND_DEVICE_NONE;
975 int i;
976
977 /*
978 * This function is to make sure that all the usecases that are active on
979 * the hardware codec backend are always routed to any one device that is
980 * handled by the hardware codec.
981 * For example, if low-latency and deep-buffer usecases are currently active
982 * on speaker and out_set_parameters(headset) is received on low-latency
983 * output, then we have to make sure deep-buffer is also switched to headset or
984 * if audio-record and voice-call usecases are currently
985 * active on speaker(rx) and speaker-mic (tx) and out_set_parameters(earpiece)
986 * is received for voice call then we have to make sure that audio-record
987 * usecase is also switched to earpiece i.e.
988 * because of the limitation that both the devices cannot be enabled
989 * at the same time as they share the same backend.
990 */
991 /* Disable all the usecases on the shared backend other than the
992 specified usecase */
993 for (i = 0; i < AUDIO_USECASE_MAX; i++)
994 switch_device[i] = false;
995
996 list_for_each(node, &adev->usecase_list) {
997 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
998 if (usecase->type != type || usecase == uc_info)
999 continue;
1000 usecase_snd_device = (type == PCM_PLAYBACK) ? usecase->out_snd_device :
1001 usecase->in_snd_device;
1002 if (usecase_snd_device != snd_device) {
1003 ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..",
1004 __func__, use_case_table[usecase->id],
1005 get_snd_device_name(usecase_snd_device));
1006 switch_device[usecase->id] = true;
1007 need_switch = true;
1008 }
1009 }
1010 if (need_switch) {
1011 list_for_each(node, &adev->usecase_list) {
1012 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
1013 usecase_snd_device = (type == PCM_PLAYBACK) ? usecase->out_snd_device :
1014 usecase->in_snd_device;
1015 if (switch_device[usecase->id]) {
1016 disable_snd_device(adev, usecase, usecase_snd_device);
1017 enable_snd_device(adev, usecase, snd_device);
1018 if (type == PCM_PLAYBACK)
1019 usecase->out_snd_device = snd_device;
1020 else
1021 usecase->in_snd_device = snd_device;
1022 }
1023 }
1024 }
1025}
1026
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001027static int select_devices(struct audio_device *adev,
1028 audio_usecase_t uc_id)
1029{
1030 snd_device_t out_snd_device = SND_DEVICE_NONE;
1031 snd_device_t in_snd_device = SND_DEVICE_NONE;
1032 struct audio_usecase *usecase = NULL;
1033 struct audio_usecase *vc_usecase = NULL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001034 struct stream_in *active_input = NULL;
1035 struct stream_out *active_out;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001036
1037 ALOGV("%s: usecase(%d)", __func__, uc_id);
1038
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001039 usecase = get_usecase_from_type(adev, PCM_CAPTURE|VOICE_CALL);
1040 if (usecase != NULL) {
1041 active_input = (struct stream_in *)usecase->stream;
1042 }
1043
1044 usecase = get_usecase_from_id(adev, uc_id);
1045 if (usecase == NULL) {
1046 ALOGE("%s: Could not find the usecase(%d)", __func__, uc_id);
1047 return -EINVAL;
1048 }
1049 active_out = (struct stream_out *)usecase->stream;
1050
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001051
1052 /*
1053 * If the voice call is active, use the sound devices of voice call usecase
1054 * so that it would not result any device switch. All the usecases will
1055 * be switched to new device when select_devices() is called for voice call
1056 * usecase.
1057 */
1058 if (usecase->type != VOICE_CALL && adev->voice.in_call) {
1059 vc_usecase = get_usecase_from_id(adev, USECASE_VOICE_CALL);
1060 if (vc_usecase == NULL) {
1061 ALOGE("%s: Could not find the voice call usecase", __func__);
1062 } else {
Christopher N. Hesse77880a22017-11-17 20:27:50 +01001063 ALOGV("%s: in call, reusing devices (rx: %s, tx: %s)", __func__,
1064 get_snd_device_display_name(vc_usecase->out_snd_device),
1065 get_snd_device_display_name(vc_usecase->in_snd_device));
1066 usecase->devices = vc_usecase->devices;
1067 return 0;
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001068 }
1069 }
1070
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001071 if (usecase->type == VOICE_CALL) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001072 usecase->devices = active_out->devices;
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001073 prepare_voice_session(adev->voice.session, active_out->devices);
1074 out_snd_device = get_output_snd_device(adev, active_out->devices);
1075 in_snd_device = get_input_snd_device(adev, active_out->devices);
1076 } else if (usecase->type == PCM_PLAYBACK) {
1077 usecase->devices = active_out->devices;
1078 in_snd_device = SND_DEVICE_NONE;
1079 if (out_snd_device == SND_DEVICE_NONE) {
1080 out_snd_device = get_output_snd_device(adev, active_out->devices);
1081 if (active_out == adev->primary_output &&
1082 active_input &&
1083 active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
1084 select_devices(adev, active_input->usecase);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001085 }
1086 }
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001087 } else if (usecase->type == PCM_CAPTURE) {
1088 usecase->devices = ((struct stream_in *)usecase->stream)->devices;
1089 out_snd_device = SND_DEVICE_NONE;
1090 if (in_snd_device == SND_DEVICE_NONE) {
1091 if (active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
1092 adev->primary_output && !adev->primary_output->standby) {
1093 in_snd_device = get_input_snd_device(adev, adev->primary_output->devices);
1094 } else {
1095 in_snd_device = get_input_snd_device(adev, AUDIO_DEVICE_NONE);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001096 }
1097 }
1098 }
1099
1100 if (out_snd_device == usecase->out_snd_device &&
1101 in_snd_device == usecase->in_snd_device) {
1102 return 0;
1103 }
1104
1105 ALOGV("%s: out_snd_device(%d: %s) in_snd_device(%d: %s)", __func__,
1106 out_snd_device, get_snd_device_display_name(out_snd_device),
1107 in_snd_device, get_snd_device_display_name(in_snd_device));
1108
1109
1110 /* Disable current sound devices */
1111 if (usecase->out_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001112 disable_snd_device(adev, usecase, usecase->out_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001113 }
1114
1115 if (usecase->in_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001116 disable_snd_device(adev, usecase, usecase->in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001117 }
1118
1119 /* Enable new sound devices */
1120 if (out_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse696959d2017-02-02 20:49:55 +01001121 /* We need to update the audio path if we switch the out devices */
1122 if (adev->voice.in_call) {
1123 set_voice_session_audio_path(adev->voice.session);
1124 }
1125
stenkinevgeniyb81e05f2018-05-08 12:02:35 +00001126 check_and_route_usecases(adev, usecase, PCM_PLAYBACK, out_snd_device);
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001127 enable_snd_device(adev, usecase, out_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001128 }
1129
1130 if (in_snd_device != SND_DEVICE_NONE) {
stenkinevgeniyb81e05f2018-05-08 12:02:35 +00001131 check_and_route_usecases(adev, usecase, PCM_CAPTURE, in_snd_device);
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001132 enable_snd_device(adev, usecase, in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001133 }
1134
1135 usecase->in_snd_device = in_snd_device;
1136 usecase->out_snd_device = out_snd_device;
1137
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02001138 /* Rely on amplifier_set_devices to distinguish between in/out devices */
1139 amplifier_set_input_devices(in_snd_device);
1140 amplifier_set_output_devices(out_snd_device);
1141
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001142 return 0;
1143}
1144
1145
1146static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames);
1147static int do_in_standby_l(struct stream_in *in);
1148
1149#ifdef PREPROCESSING_ENABLED
1150static void get_capture_reference_delay(struct stream_in *in,
1151 size_t frames __unused,
1152 struct echo_reference_buffer *buffer)
1153{
1154 ALOGVV("%s: enter:)", __func__);
1155
1156 /* read frames available in kernel driver buffer */
1157 unsigned int kernel_frames;
1158 struct timespec tstamp;
1159 long buf_delay;
1160 long kernel_delay;
1161 long delay_ns;
1162 struct pcm_device *ref_device;
1163 long rsmp_delay = 0;
1164
1165 ref_device = node_to_item(list_tail(&in->pcm_dev_list),
1166 struct pcm_device, stream_list_node);
1167
1168 if (pcm_get_htimestamp(ref_device->pcm, &kernel_frames, &tstamp) < 0) {
1169 buffer->time_stamp.tv_sec = 0;
1170 buffer->time_stamp.tv_nsec = 0;
1171 buffer->delay_ns = 0;
1172 ALOGW("read get_capture_reference_delay(): pcm_htimestamp error");
1173 return;
1174 }
1175
1176 /* adjust render time stamp with delay added by current driver buffer.
1177 * Add the duration of current frame as we want the render time of the last
1178 * sample being written. */
1179
1180 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / ref_device->pcm_profile->config.rate);
1181
1182 buffer->time_stamp = tstamp;
1183 buffer->delay_ns = kernel_delay;
1184
1185 ALOGVV("get_capture_reference_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5d],"
1186 " delay_ns: [%d] , frames:[%zd]",
1187 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns, frames);
1188}
1189
1190static void get_capture_delay(struct stream_in *in,
1191 size_t frames __unused,
1192 struct echo_reference_buffer *buffer)
1193{
1194 ALOGVV("%s: enter:)", __func__);
1195 /* read frames available in kernel driver buffer */
1196 unsigned int kernel_frames;
1197 struct timespec tstamp;
1198 long buf_delay;
1199 long rsmp_delay;
1200 long kernel_delay;
1201 long delay_ns;
1202 struct pcm_device *pcm_device;
1203
1204 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1205 struct pcm_device, stream_list_node);
1206
1207 if (pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &tstamp) < 0) {
1208 buffer->time_stamp.tv_sec = 0;
1209 buffer->time_stamp.tv_nsec = 0;
1210 buffer->delay_ns = 0;
1211 ALOGW("read get_capture_delay(): pcm_htimestamp error");
1212 return;
1213 }
1214
1215 /* read frames available in audio HAL input buffer
1216 * add number of frames being read as we want the capture time of first sample
1217 * in current buffer */
1218 /* frames in in->read_buf are at driver sampling rate while frames in in->proc_buf are
1219 * at requested sampling rate */
1220 buf_delay = (long)(((int64_t)(in->read_buf_frames) * 1000000000) / in->config.rate +
1221 ((int64_t)(in->proc_buf_frames) * 1000000000) / in->requested_rate );
1222
1223 /* add delay introduced by resampler */
1224 rsmp_delay = 0;
1225 if (in->resampler) {
1226 rsmp_delay = in->resampler->delay_ns(in->resampler);
1227 }
1228
1229 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / in->config.rate);
1230
1231 delay_ns = kernel_delay + buf_delay + rsmp_delay;
1232
1233 buffer->time_stamp = tstamp;
1234 buffer->delay_ns = delay_ns;
1235 ALOGVV("get_capture_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames:[%5d],"
1236 " delay_ns: [%d], kernel_delay:[%ld], buf_delay:[%ld], rsmp_delay:[%ld], "
1237 "in->read_buf_frames:[%zd], in->proc_buf_frames:[%zd], frames:[%zd]",
1238 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames,
1239 buffer->delay_ns, kernel_delay, buf_delay, rsmp_delay,
1240 in->read_buf_frames, in->proc_buf_frames, frames);
1241}
1242
1243static int32_t update_echo_reference(struct stream_in *in, size_t frames)
1244{
1245 ALOGVV("%s: enter:), in->config.channels(%d)", __func__,in->config.channels);
1246 struct echo_reference_buffer b;
1247 b.delay_ns = 0;
1248 struct pcm_device *pcm_device;
1249
1250 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1251 struct pcm_device, stream_list_node);
1252
1253 ALOGVV("update_echo_reference, in->config.channels(%d), frames = [%zd], in->ref_buf_frames = [%zd], "
1254 "b.frame_count = [%zd]",
1255 in->config.channels, frames, in->ref_buf_frames, frames - in->ref_buf_frames);
1256 if (in->ref_buf_frames < frames) {
1257 if (in->ref_buf_size < frames) {
1258 in->ref_buf_size = frames;
1259 in->ref_buf = (int16_t *)realloc(in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1260 ALOG_ASSERT((in->ref_buf != NULL),
1261 "update_echo_reference() failed to reallocate ref_buf");
1262 ALOGVV("update_echo_reference(): ref_buf %p extended to %d bytes",
1263 in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1264 }
1265 b.frame_count = frames - in->ref_buf_frames;
1266 b.raw = (void *)(in->ref_buf + in->ref_buf_frames * in->config.channels);
1267
1268 get_capture_delay(in, frames, &b);
1269
1270 if (in->echo_reference->read(in->echo_reference, &b) == 0)
1271 {
1272 in->ref_buf_frames += b.frame_count;
1273 ALOGVV("update_echo_reference(): in->ref_buf_frames:[%zd], "
1274 "in->ref_buf_size:[%zd], frames:[%zd], b.frame_count:[%zd]",
1275 in->ref_buf_frames, in->ref_buf_size, frames, b.frame_count);
1276 }
1277 } else
1278 ALOGW("update_echo_reference(): NOT enough frames to read ref buffer");
1279 return b.delay_ns;
1280}
1281
1282static int set_preprocessor_param(effect_handle_t handle,
1283 effect_param_t *param)
1284{
1285 uint32_t size = sizeof(int);
1286 uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
1287 param->vsize;
1288
1289 int status = (*handle)->command(handle,
1290 EFFECT_CMD_SET_PARAM,
1291 sizeof (effect_param_t) + psize,
1292 param,
1293 &size,
1294 &param->status);
1295 if (status == 0)
1296 status = param->status;
1297
1298 return status;
1299}
1300
1301static int set_preprocessor_echo_delay(effect_handle_t handle,
1302 int32_t delay_us)
1303{
1304 struct {
1305 effect_param_t param;
1306 uint32_t data_0;
1307 int32_t data_1;
1308 } buf;
1309 memset(&buf, 0, sizeof(buf));
1310
1311 buf.param.psize = sizeof(uint32_t);
1312 buf.param.vsize = sizeof(uint32_t);
1313 buf.data_0 = AEC_PARAM_ECHO_DELAY;
1314 buf.data_1 = delay_us;
1315
1316 return set_preprocessor_param(handle, &buf.param);
1317}
1318
1319static void push_echo_reference(struct stream_in *in, size_t frames)
1320{
1321 ALOGVV("%s: enter:)", __func__);
1322 /* read frames from echo reference buffer and update echo delay
1323 * in->ref_buf_frames is updated with frames available in in->ref_buf */
1324
1325 int32_t delay_us = update_echo_reference(in, frames)/1000;
1326 int32_t size_in_bytes = 0;
1327 int i;
1328 audio_buffer_t buf;
1329
1330 if (in->ref_buf_frames < frames)
1331 frames = in->ref_buf_frames;
1332
1333 buf.frameCount = frames;
1334 buf.raw = in->ref_buf;
1335
1336 for (i = 0; i < in->num_preprocessors; i++) {
1337 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1338 continue;
1339 ALOGVV("%s: effect_itfe)->process_reverse() BEGIN i=(%d) ", __func__, i);
1340 (*in->preprocessors[i].effect_itfe)->process_reverse(in->preprocessors[i].effect_itfe,
1341 &buf,
1342 NULL);
1343 ALOGVV("%s: effect_itfe)->process_reverse() END i=(%d) ", __func__, i);
1344 set_preprocessor_echo_delay(in->preprocessors[i].effect_itfe, delay_us);
1345 }
1346
1347 in->ref_buf_frames -= buf.frameCount;
1348 ALOGVV("%s: in->ref_buf_frames(%zd), in->config.channels(%d) ",
1349 __func__, in->ref_buf_frames, in->config.channels);
1350 if (in->ref_buf_frames) {
1351 memcpy(in->ref_buf,
1352 in->ref_buf + buf.frameCount * in->config.channels,
1353 in->ref_buf_frames * in->config.channels * sizeof(int16_t));
1354 }
1355}
1356
1357static void put_echo_reference(struct audio_device *adev,
1358 struct echo_reference_itfe *reference)
1359{
1360 ALOGV("%s: enter:)", __func__);
1361 int32_t prev_generation = adev->echo_reference_generation;
1362 struct stream_out *out = adev->primary_output;
1363
1364 if (adev->echo_reference != NULL &&
1365 reference == adev->echo_reference) {
1366 /* echo reference is taken from the low latency output stream used
1367 * for voice use cases */
1368 adev->echo_reference = NULL;
1369 android_atomic_inc(&adev->echo_reference_generation);
1370 if (out != NULL && out->usecase == USECASE_AUDIO_PLAYBACK) {
1371 // if the primary output is in standby or did not pick the echo reference yet
1372 // we can safely get rid of it here.
1373 // otherwise, out_write() or out_standby() will detect the change in echo reference
1374 // generation and release the echo reference owned by the stream.
1375 if ((out->echo_reference_generation != prev_generation) || out->standby)
1376 release_echo_reference(reference);
1377 } else {
1378 release_echo_reference(reference);
1379 }
1380 ALOGV("release_echo_reference");
1381 }
1382}
1383
1384static struct echo_reference_itfe *get_echo_reference(struct audio_device *adev,
1385 audio_format_t format __unused,
1386 uint32_t channel_count,
1387 uint32_t sampling_rate)
1388{
1389 ALOGV("%s: enter:)", __func__);
1390 put_echo_reference(adev, adev->echo_reference);
1391 /* echo reference is taken from the low latency output stream used
1392 * for voice use cases */
1393 if (adev->primary_output!= NULL && adev->primary_output->usecase == USECASE_AUDIO_PLAYBACK &&
1394 !adev->primary_output->standby) {
1395 struct audio_stream *stream =
1396 &adev->primary_output->stream.common;
1397 uint32_t wr_channel_count = audio_channel_count_from_out_mask(stream->get_channels(stream));
1398 uint32_t wr_sampling_rate = stream->get_sample_rate(stream);
1399 ALOGV("Calling create_echo_reference");
1400 int status = create_echo_reference(AUDIO_FORMAT_PCM_16_BIT,
1401 channel_count,
1402 sampling_rate,
1403 AUDIO_FORMAT_PCM_16_BIT,
1404 wr_channel_count,
1405 wr_sampling_rate,
1406 &adev->echo_reference);
1407 if (status == 0)
1408 android_atomic_inc(&adev->echo_reference_generation);
1409 }
1410 return adev->echo_reference;
1411}
1412
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001413static int get_playback_delay(struct stream_out *out,
1414 size_t frames,
1415 struct echo_reference_buffer *buffer)
1416{
1417 unsigned int kernel_frames;
1418 int status;
1419 int primary_pcm = 0;
1420 struct pcm_device *pcm_device;
1421
1422 pcm_device = node_to_item(list_head(&out->pcm_dev_list),
1423 struct pcm_device, stream_list_node);
1424
1425 status = pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &buffer->time_stamp);
1426 if (status < 0) {
1427 buffer->time_stamp.tv_sec = 0;
1428 buffer->time_stamp.tv_nsec = 0;
1429 buffer->delay_ns = 0;
1430 ALOGV("get_playback_delay(): pcm_get_htimestamp error,"
1431 "setting playbackTimestamp to 0");
1432 return status;
1433 }
1434
1435 kernel_frames = pcm_get_buffer_size(pcm_device->pcm) - kernel_frames;
1436
1437 /* adjust render time stamp with delay added by current driver buffer.
1438 * Add the duration of current frame as we want the render time of the last
1439 * sample being written. */
1440 buffer->delay_ns = (long)(((int64_t)(kernel_frames + frames)* 1000000000)/
1441 out->config.rate);
1442 ALOGVV("get_playback_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5u], delay_ns: [%d],",
1443 buffer->time_stamp.tv_sec, buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns);
1444
1445 return 0;
1446}
1447
1448#define GET_COMMAND_STATUS(status, fct_status, cmd_status) \
1449 do { \
1450 if (fct_status != 0) \
1451 status = fct_status; \
1452 else if (cmd_status != 0) \
1453 status = cmd_status; \
1454 } while(0)
1455
1456static int in_configure_reverse(struct stream_in *in)
1457{
1458 int32_t cmd_status;
1459 uint32_t size = sizeof(int);
1460 effect_config_t config;
1461 int32_t status = 0;
1462 int32_t fct_status = 0;
1463 int i;
1464 ALOGV("%s: enter: in->num_preprocessors(%d)", __func__, in->num_preprocessors);
1465 if (in->num_preprocessors > 0) {
1466 config.inputCfg.channels = in->main_channels;
1467 config.outputCfg.channels = in->main_channels;
1468 config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1469 config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1470 config.inputCfg.samplingRate = in->requested_rate;
1471 config.outputCfg.samplingRate = in->requested_rate;
1472 config.inputCfg.mask =
1473 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1474 config.outputCfg.mask =
1475 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1476
1477 for (i = 0; i < in->num_preprocessors; i++)
1478 {
1479 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1480 continue;
1481 fct_status = (*(in->preprocessors[i].effect_itfe))->command(
1482 in->preprocessors[i].effect_itfe,
1483 EFFECT_CMD_SET_CONFIG_REVERSE,
1484 sizeof(effect_config_t),
1485 &config,
1486 &size,
1487 &cmd_status);
1488 ALOGV("%s: calling EFFECT_CMD_SET_CONFIG_REVERSE",__func__);
1489 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1490 }
1491 }
1492 return status;
1493}
1494
1495#define MAX_NUM_CHANNEL_CONFIGS 10
1496
1497static void in_read_audio_effect_channel_configs(struct stream_in *in __unused,
1498 struct effect_info_s *effect_info)
1499{
1500 /* size and format of the cmd are defined in hardware/audio_effect.h */
1501 effect_handle_t effect = effect_info->effect_itfe;
1502 uint32_t cmd_size = 2 * sizeof(uint32_t);
1503 uint32_t cmd[] = { EFFECT_FEATURE_AUX_CHANNELS, MAX_NUM_CHANNEL_CONFIGS };
1504 /* reply = status + number of configs (n) + n x channel_config_t */
1505 uint32_t reply_size =
1506 2 * sizeof(uint32_t) + (MAX_NUM_CHANNEL_CONFIGS * sizeof(channel_config_t));
1507 int32_t reply[reply_size];
1508 int32_t cmd_status;
1509
1510 ALOG_ASSERT((effect_info->num_channel_configs == 0),
1511 "in_read_audio_effect_channel_configs() num_channel_configs not cleared");
1512 ALOG_ASSERT((effect_info->channel_configs == NULL),
1513 "in_read_audio_effect_channel_configs() channel_configs not cleared");
1514
1515 /* if this command is not supported, then the effect is supposed to return -EINVAL.
1516 * This error will be interpreted as if the effect supports the main_channels but does not
1517 * support any aux_channels */
1518 cmd_status = (*effect)->command(effect,
1519 EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS,
1520 cmd_size,
1521 (void*)&cmd,
1522 &reply_size,
1523 (void*)&reply);
1524
1525 if (cmd_status != 0) {
1526 ALOGV("in_read_audio_effect_channel_configs(): "
1527 "fx->command returned %d", cmd_status);
1528 return;
1529 }
1530
1531 if (reply[0] != 0) {
1532 ALOGW("in_read_audio_effect_channel_configs(): "
1533 "command EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS error %d num configs %d",
1534 reply[0], (reply[0] == -ENOMEM) ? reply[1] : MAX_NUM_CHANNEL_CONFIGS);
1535 return;
1536 }
1537
1538 /* the feature is not supported */
1539 ALOGV("in_read_audio_effect_channel_configs()(): "
1540 "Feature supported and adding %d channel configs to the list", reply[1]);
1541 effect_info->num_channel_configs = reply[1];
1542 effect_info->channel_configs =
1543 (channel_config_t *) malloc(sizeof(channel_config_t) * reply[1]); /* n x configs */
1544 memcpy(effect_info->channel_configs, (reply + 2), sizeof(channel_config_t) * reply[1]);
1545}
1546
1547
1548#define NUM_IN_AUX_CNL_CONFIGS 2
1549static const channel_config_t in_aux_cnl_configs[NUM_IN_AUX_CNL_CONFIGS] = {
1550 { AUDIO_CHANNEL_IN_FRONT , AUDIO_CHANNEL_IN_BACK},
1551 { AUDIO_CHANNEL_IN_STEREO , AUDIO_CHANNEL_IN_RIGHT}
1552};
1553static uint32_t in_get_aux_channels(struct stream_in *in)
1554{
1555 int i;
1556 channel_config_t new_chcfg = {0, 0};
1557
1558 if (in->num_preprocessors == 0)
1559 return 0;
1560
1561 /* do not enable dual mic configurations when capturing from other microphones than
1562 * main or sub */
1563 if (!(in->devices & (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_BACK_MIC)))
1564 return 0;
1565
1566 /* retain most complex aux channels configuration compatible with requested main channels and
1567 * supported by audio driver and all pre processors */
1568 for (i = 0; i < NUM_IN_AUX_CNL_CONFIGS; i++) {
1569 const channel_config_t *cur_chcfg = &in_aux_cnl_configs[i];
1570 if (cur_chcfg->main_channels == in->main_channels) {
1571 size_t match_cnt;
1572 size_t idx_preproc;
1573 for (idx_preproc = 0, match_cnt = 0;
1574 /* no need to continue if at least one preprocessor doesn't match */
1575 idx_preproc < (size_t)in->num_preprocessors && match_cnt == idx_preproc;
1576 idx_preproc++) {
1577 struct effect_info_s *effect_info = &in->preprocessors[idx_preproc];
1578 size_t idx_chcfg;
1579
1580 for (idx_chcfg = 0; idx_chcfg < effect_info->num_channel_configs; idx_chcfg++) {
1581 if (memcmp(effect_info->channel_configs + idx_chcfg,
1582 cur_chcfg,
1583 sizeof(channel_config_t)) == 0) {
1584 match_cnt++;
1585 break;
1586 }
1587 }
1588 }
1589 /* if all preprocessors match, we have a candidate */
1590 if (match_cnt == (size_t)in->num_preprocessors) {
1591 /* retain most complex aux channels configuration */
1592 if (audio_channel_count_from_in_mask(cur_chcfg->aux_channels) > audio_channel_count_from_in_mask(new_chcfg.aux_channels)) {
1593 new_chcfg = *cur_chcfg;
1594 }
1595 }
1596 }
1597 }
1598
1599 ALOGV("in_get_aux_channels(): return %04x", new_chcfg.aux_channels);
1600
1601 return new_chcfg.aux_channels;
1602}
1603
1604static int in_configure_effect_channels(effect_handle_t effect,
1605 channel_config_t *channel_config)
1606{
1607 int status = 0;
1608 int fct_status;
1609 int32_t cmd_status;
1610 uint32_t reply_size;
1611 effect_config_t config;
1612 uint32_t cmd[(sizeof(uint32_t) + sizeof(channel_config_t) - 1) / sizeof(uint32_t) + 1];
1613
1614 ALOGV("in_configure_effect_channels(): configure effect with channels: [%04x][%04x]",
1615 channel_config->main_channels,
1616 channel_config->aux_channels);
1617
1618 config.inputCfg.mask = EFFECT_CONFIG_CHANNELS;
1619 config.outputCfg.mask = EFFECT_CONFIG_CHANNELS;
1620 reply_size = sizeof(effect_config_t);
1621 fct_status = (*effect)->command(effect,
1622 EFFECT_CMD_GET_CONFIG,
1623 0,
1624 NULL,
1625 &reply_size,
1626 &config);
1627 if (fct_status != 0) {
1628 ALOGE("in_configure_effect_channels(): EFFECT_CMD_GET_CONFIG failed");
1629 return fct_status;
1630 }
1631
1632 config.inputCfg.channels = channel_config->main_channels | channel_config->aux_channels;
1633 config.outputCfg.channels = config.inputCfg.channels;
1634 reply_size = sizeof(uint32_t);
1635 fct_status = (*effect)->command(effect,
1636 EFFECT_CMD_SET_CONFIG,
1637 sizeof(effect_config_t),
1638 &config,
1639 &reply_size,
1640 &cmd_status);
1641 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1642
1643 cmd[0] = EFFECT_FEATURE_AUX_CHANNELS;
1644 memcpy(cmd + 1, channel_config, sizeof(channel_config_t));
1645 reply_size = sizeof(uint32_t);
1646 fct_status = (*effect)->command(effect,
1647 EFFECT_CMD_SET_FEATURE_CONFIG,
1648 sizeof(cmd), //sizeof(uint32_t) + sizeof(channel_config_t),
1649 cmd,
1650 &reply_size,
1651 &cmd_status);
1652 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1653
1654 /* some implementations need to be re-enabled after a config change */
1655 reply_size = sizeof(uint32_t);
1656 fct_status = (*effect)->command(effect,
1657 EFFECT_CMD_ENABLE,
1658 0,
1659 NULL,
1660 &reply_size,
1661 &cmd_status);
1662 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1663
1664 return status;
1665}
1666
1667static int in_reconfigure_channels(struct stream_in *in,
1668 effect_handle_t effect,
1669 channel_config_t *channel_config,
1670 bool config_changed) {
1671
1672 int status = 0;
1673
1674 ALOGV("in_reconfigure_channels(): config_changed %d effect %p",
1675 config_changed, effect);
1676
1677 /* if config changed, reconfigure all previously added effects */
1678 if (config_changed) {
1679 int i;
1680 ALOGV("%s: config_changed (%d)", __func__, config_changed);
1681 for (i = 0; i < in->num_preprocessors; i++)
1682 {
1683 int cur_status = in_configure_effect_channels(in->preprocessors[i].effect_itfe,
1684 channel_config);
1685 ALOGV("%s: in_configure_effect_channels i=(%d), [main_channel,aux_channel]=[%d|%d], status=%d",
1686 __func__, i, channel_config->main_channels, channel_config->aux_channels, cur_status);
1687 if (cur_status != 0) {
1688 ALOGV("in_reconfigure_channels(): error %d configuring effect "
1689 "%d with channels: [%04x][%04x]",
1690 cur_status,
1691 i,
1692 channel_config->main_channels,
1693 channel_config->aux_channels);
1694 status = cur_status;
1695 }
1696 }
1697 } else if (effect != NULL && channel_config->aux_channels) {
1698 /* if aux channels config did not change but aux channels are present,
1699 * we still need to configure the effect being added */
1700 status = in_configure_effect_channels(effect, channel_config);
1701 }
1702 return status;
1703}
1704
1705static void in_update_aux_channels(struct stream_in *in,
1706 effect_handle_t effect)
1707{
1708 uint32_t aux_channels;
1709 channel_config_t channel_config;
1710 int status;
1711
1712 aux_channels = in_get_aux_channels(in);
1713
1714 channel_config.main_channels = in->main_channels;
1715 channel_config.aux_channels = aux_channels;
1716 status = in_reconfigure_channels(in,
1717 effect,
1718 &channel_config,
1719 (aux_channels != in->aux_channels));
1720
1721 if (status != 0) {
1722 ALOGV("in_update_aux_channels(): in_reconfigure_channels error %d", status);
1723 /* resetting aux channels configuration */
1724 aux_channels = 0;
1725 channel_config.aux_channels = 0;
1726 in_reconfigure_channels(in, effect, &channel_config, true);
1727 }
1728 ALOGV("%s: aux_channels=%d, in->aux_channels_changed=%d", __func__, aux_channels, in->aux_channels_changed);
1729 if (in->aux_channels != aux_channels) {
1730 in->aux_channels_changed = true;
1731 in->aux_channels = aux_channels;
1732 do_in_standby_l(in);
1733 }
1734}
1735#endif
1736
1737/* This function reads PCM data and:
1738 * - resample if needed
1739 * - process if pre-processors are attached
1740 * - discard unwanted channels
1741 */
1742static ssize_t read_and_process_frames(struct stream_in *in, void* buffer, ssize_t frames)
1743{
1744 ssize_t frames_wr = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001745 size_t src_channels = in->config.channels;
1746 size_t dst_channels = audio_channel_count_from_in_mask(in->main_channels);
1747 int i;
1748 void *proc_buf_out;
1749 struct pcm_device *pcm_device;
1750 bool has_additional_channels = (dst_channels != src_channels) ? true : false;
1751#ifdef PREPROCESSING_ENABLED
Andreas Schneider5a2f1002017-02-09 10:59:04 +01001752 audio_buffer_t in_buf;
1753 audio_buffer_t out_buf;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001754 bool has_processing = (in->num_preprocessors != 0) ? true : false;
1755#endif
1756
1757 /* Additional channels might be added on top of main_channels:
1758 * - aux_channels (by processing effects)
1759 * - extra channels due to HW limitations
1760 * In case of additional channels, we cannot work inplace
1761 */
1762 if (has_additional_channels)
1763 proc_buf_out = in->proc_buf_out;
1764 else
1765 proc_buf_out = buffer;
1766
1767 if (list_empty(&in->pcm_dev_list)) {
1768 ALOGE("%s: pcm device list empty", __func__);
1769 return -EINVAL;
1770 }
1771
1772 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1773 struct pcm_device, stream_list_node);
1774
1775#ifdef PREPROCESSING_ENABLED
1776 if (has_processing) {
1777 /* since all the processing below is done in frames and using the config.channels
1778 * as the number of channels, no changes is required in case aux_channels are present */
1779 while (frames_wr < frames) {
1780 /* first reload enough frames at the end of process input buffer */
1781 if (in->proc_buf_frames < (size_t)frames) {
1782 ssize_t frames_rd;
1783 if (in->proc_buf_size < (size_t)frames) {
1784 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1785 in->proc_buf_size = (size_t)frames;
1786 in->proc_buf_in = (int16_t *)realloc(in->proc_buf_in, size_in_bytes);
1787 ALOG_ASSERT((in->proc_buf_in != NULL),
1788 "process_frames() failed to reallocate proc_buf_in");
1789 if (has_additional_channels) {
1790 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1791 ALOG_ASSERT((in->proc_buf_out != NULL),
1792 "process_frames() failed to reallocate proc_buf_out");
1793 proc_buf_out = in->proc_buf_out;
1794 }
1795 }
1796 frames_rd = read_frames(in,
1797 in->proc_buf_in +
1798 in->proc_buf_frames * in->config.channels,
1799 frames - in->proc_buf_frames);
1800 if (frames_rd < 0) {
1801 /* Return error code */
1802 frames_wr = frames_rd;
1803 break;
1804 }
1805 in->proc_buf_frames += frames_rd;
1806 }
1807
1808 if (in->echo_reference != NULL) {
1809 push_echo_reference(in, in->proc_buf_frames);
1810 }
1811
1812 /* in_buf.frameCount and out_buf.frameCount indicate respectively
1813 * the maximum number of frames to be consumed and produced by process() */
1814 in_buf.frameCount = in->proc_buf_frames;
1815 in_buf.s16 = in->proc_buf_in;
1816 out_buf.frameCount = frames - frames_wr;
1817 out_buf.s16 = (int16_t *)proc_buf_out + frames_wr * in->config.channels;
1818
1819 /* FIXME: this works because of current pre processing library implementation that
1820 * does the actual process only when the last enabled effect process is called.
1821 * The generic solution is to have an output buffer for each effect and pass it as
1822 * input to the next.
1823 */
1824 for (i = 0; i < in->num_preprocessors; i++) {
1825 (*in->preprocessors[i].effect_itfe)->process(in->preprocessors[i].effect_itfe,
1826 &in_buf,
1827 &out_buf);
1828 }
1829
1830 /* process() has updated the number of frames consumed and produced in
1831 * in_buf.frameCount and out_buf.frameCount respectively
1832 * move remaining frames to the beginning of in->proc_buf_in */
1833 in->proc_buf_frames -= in_buf.frameCount;
1834
1835 if (in->proc_buf_frames) {
1836 memcpy(in->proc_buf_in,
1837 in->proc_buf_in + in_buf.frameCount * in->config.channels,
1838 in->proc_buf_frames * in->config.channels * sizeof(int16_t));
1839 }
1840
1841 /* if not enough frames were passed to process(), read more and retry. */
1842 if (out_buf.frameCount == 0) {
1843 ALOGW("No frames produced by preproc");
1844 continue;
1845 }
1846
1847 if ((frames_wr + (ssize_t)out_buf.frameCount) <= frames) {
1848 frames_wr += out_buf.frameCount;
1849 } else {
1850 /* The effect does not comply to the API. In theory, we should never end up here! */
1851 ALOGE("preprocessing produced too many frames: %d + %zd > %d !",
1852 (unsigned int)frames_wr, out_buf.frameCount, (unsigned int)frames);
1853 frames_wr = frames;
1854 }
1855 }
1856 }
1857 else
1858#endif //PREPROCESSING_ENABLED
1859 {
1860 /* No processing effects attached */
1861 if (has_additional_channels) {
1862 /* With additional channels, we cannot use original buffer */
1863 if (in->proc_buf_size < (size_t)frames) {
1864 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1865 in->proc_buf_size = (size_t)frames;
1866 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1867 ALOG_ASSERT((in->proc_buf_out != NULL),
1868 "process_frames() failed to reallocate proc_buf_out");
1869 proc_buf_out = in->proc_buf_out;
1870 }
1871 }
1872 frames_wr = read_frames(in, proc_buf_out, frames);
1873 }
1874
1875 /* Remove all additional channels that have been added on top of main_channels:
1876 * - aux_channels
1877 * - extra channels from HW due to HW limitations
1878 * Assumption is made that the channels are interleaved and that the main
1879 * channels are first. */
1880
1881 if (has_additional_channels)
1882 {
1883 int16_t* src_buffer = (int16_t *)proc_buf_out;
1884 int16_t* dst_buffer = (int16_t *)buffer;
1885
1886 if (dst_channels == 1) {
1887 for (i = frames_wr; i > 0; i--)
1888 {
1889 *dst_buffer++ = *src_buffer;
1890 src_buffer += src_channels;
1891 }
1892 } else {
1893 for (i = frames_wr; i > 0; i--)
1894 {
1895 memcpy(dst_buffer, src_buffer, dst_channels*sizeof(int16_t));
1896 dst_buffer += dst_channels;
1897 src_buffer += src_channels;
1898 }
1899 }
1900 }
1901
1902 return frames_wr;
1903}
1904
1905static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
1906 struct resampler_buffer* buffer)
1907{
1908 struct stream_in *in;
1909 struct pcm_device *pcm_device;
1910
1911 if (buffer_provider == NULL || buffer == NULL)
1912 return -EINVAL;
1913
1914 in = (struct stream_in *)((char *)buffer_provider -
1915 offsetof(struct stream_in, buf_provider));
1916
1917 if (list_empty(&in->pcm_dev_list)) {
1918 buffer->raw = NULL;
1919 buffer->frame_count = 0;
1920 in->read_status = -ENODEV;
1921 return -ENODEV;
1922 }
1923
1924 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1925 struct pcm_device, stream_list_node);
1926
1927 if (in->read_buf_frames == 0) {
1928 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, in->config.period_size);
1929 if (in->read_buf_size < in->config.period_size) {
1930 in->read_buf_size = in->config.period_size;
1931 in->read_buf = (int16_t *) realloc(in->read_buf, size_in_bytes);
1932 ALOG_ASSERT((in->read_buf != NULL),
1933 "get_next_buffer() failed to reallocate read_buf");
1934 }
1935
1936 in->read_status = pcm_read(pcm_device->pcm, (void*)in->read_buf, size_in_bytes);
1937
1938 if (in->read_status != 0) {
1939 ALOGE("get_next_buffer() pcm_read error %d", in->read_status);
1940 buffer->raw = NULL;
1941 buffer->frame_count = 0;
1942 return in->read_status;
1943 }
1944 in->read_buf_frames = in->config.period_size;
1945
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001946 }
1947
1948 buffer->frame_count = (buffer->frame_count > in->read_buf_frames) ?
1949 in->read_buf_frames : buffer->frame_count;
1950 buffer->i16 = in->read_buf + (in->config.period_size - in->read_buf_frames) *
1951 in->config.channels;
1952 return in->read_status;
1953}
1954
1955static void release_buffer(struct resampler_buffer_provider *buffer_provider,
1956 struct resampler_buffer* buffer)
1957{
1958 struct stream_in *in;
1959
1960 if (buffer_provider == NULL || buffer == NULL)
1961 return;
1962
1963 in = (struct stream_in *)((char *)buffer_provider -
1964 offsetof(struct stream_in, buf_provider));
1965
1966 in->read_buf_frames -= buffer->frame_count;
1967}
1968
1969/* read_frames() reads frames from kernel driver, down samples to capture rate
1970 * if necessary and output the number of frames requested to the buffer specified */
1971static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames)
1972{
1973 ssize_t frames_wr = 0;
1974
1975 struct pcm_device *pcm_device;
1976
1977 if (list_empty(&in->pcm_dev_list)) {
1978 ALOGE("%s: pcm device list empty", __func__);
1979 return -EINVAL;
1980 }
1981
1982 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1983 struct pcm_device, stream_list_node);
1984
1985 while (frames_wr < frames) {
1986 size_t frames_rd = frames - frames_wr;
1987 ALOGVV("%s: frames_rd: %zd, frames_wr: %zd, in->config.channels: %d",
1988 __func__,frames_rd,frames_wr,in->config.channels);
1989 if (in->resampler != NULL) {
1990 in->resampler->resample_from_provider(in->resampler,
1991 (int16_t *)((char *)buffer +
1992 pcm_frames_to_bytes(pcm_device->pcm, frames_wr)),
1993 &frames_rd);
1994 } else {
1995 struct resampler_buffer buf = {
Andreas Schneiderb7f32122017-01-31 08:18:34 +01001996 .raw = NULL,
1997 .frame_count = frames_rd,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001998 };
1999 get_next_buffer(&in->buf_provider, &buf);
2000 if (buf.raw != NULL) {
2001 memcpy((char *)buffer +
2002 pcm_frames_to_bytes(pcm_device->pcm, frames_wr),
2003 buf.raw,
2004 pcm_frames_to_bytes(pcm_device->pcm, buf.frame_count));
2005 frames_rd = buf.frame_count;
2006 }
2007 release_buffer(&in->buf_provider, &buf);
2008 }
2009 /* in->read_status is updated by getNextBuffer() also called by
2010 * in->resampler->resample_from_provider() */
2011 if (in->read_status != 0)
2012 return in->read_status;
2013
2014 frames_wr += frames_rd;
2015 }
2016 return frames_wr;
2017}
2018
2019static int in_release_pcm_devices(struct stream_in *in)
2020{
2021 struct pcm_device *pcm_device;
2022 struct listnode *node;
2023 struct listnode *next;
2024
2025 list_for_each_safe(node, next, &in->pcm_dev_list) {
2026 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2027 list_remove(node);
2028 free(pcm_device);
2029 }
2030
2031 return 0;
2032}
2033
2034static int stop_input_stream(struct stream_in *in)
2035{
2036 struct audio_usecase *uc_info;
2037 struct audio_device *adev = in->dev;
2038
2039 adev->active_input = NULL;
2040 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2041 in->usecase, use_case_table[in->usecase]);
2042 uc_info = get_usecase_from_id(adev, in->usecase);
2043 if (uc_info == NULL) {
2044 ALOGE("%s: Could not find the usecase (%d) in the list",
2045 __func__, in->usecase);
2046 return -EINVAL;
2047 }
2048
2049 /* Disable the tx device */
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002050 disable_snd_device(adev, uc_info, uc_info->in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002051
2052 list_remove(&uc_info->adev_list_node);
2053 free(uc_info);
2054
2055 if (list_empty(&in->pcm_dev_list)) {
2056 ALOGE("%s: pcm device list empty", __func__);
2057 return -EINVAL;
2058 }
2059
2060 in_release_pcm_devices(in);
2061 list_init(&in->pcm_dev_list);
2062
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002063 ALOGV("%s: exit", __func__);
2064 return 0;
2065}
2066
2067static int start_input_stream(struct stream_in *in)
2068{
2069 /* Enable output device and stream routing controls */
2070 int ret = 0;
2071 bool recreate_resampler = false;
2072 struct audio_usecase *uc_info;
2073 struct audio_device *adev = in->dev;
2074 struct pcm_device_profile *pcm_profile;
2075 struct pcm_device *pcm_device;
2076
2077 ALOGV("%s: enter: usecase(%d)", __func__, in->usecase);
2078 adev->active_input = in;
2079 pcm_profile = get_pcm_device(in->usecase_type, in->devices);
2080 if (pcm_profile == NULL) {
2081 ALOGE("%s: Could not find PCM device id for the usecase(%d)",
2082 __func__, in->usecase);
2083 ret = -EINVAL;
2084 goto error_config;
2085 }
2086
2087 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002088 if (uc_info == NULL) {
2089 ret = -ENOMEM;
2090 goto error_config;
2091 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002092 uc_info->id = in->usecase;
2093 uc_info->type = PCM_CAPTURE;
2094 uc_info->stream = (struct audio_stream *)in;
2095 uc_info->devices = in->devices;
2096 uc_info->in_snd_device = SND_DEVICE_NONE;
2097 uc_info->out_snd_device = SND_DEVICE_NONE;
2098
2099 pcm_device = (struct pcm_device *)calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01002100 if (pcm_device == NULL) {
2101 free(uc_info);
2102 ret = -ENOMEM;
2103 goto error_config;
2104 }
2105
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002106 pcm_device->pcm_profile = pcm_profile;
2107 list_init(&in->pcm_dev_list);
2108 list_add_tail(&in->pcm_dev_list, &pcm_device->stream_list_node);
2109
2110 list_init(&uc_info->mixer_list);
2111 list_add_tail(&uc_info->mixer_list,
2112 &adev_get_mixer_for_card(adev,
2113 pcm_device->pcm_profile->card)->uc_list_node[uc_info->id]);
2114
2115 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2116
2117 select_devices(adev, in->usecase);
2118
2119 /* Config should be updated as profile can be changed between different calls
2120 * to this function:
2121 * - Trigger resampler creation
2122 * - Config needs to be updated */
2123 if (in->config.rate != pcm_profile->config.rate) {
2124 recreate_resampler = true;
2125 }
2126 in->config = pcm_profile->config;
2127
2128#ifdef PREPROCESSING_ENABLED
2129 if (in->aux_channels_changed) {
2130 in->config.channels = audio_channel_count_from_in_mask(in->main_channels | in->aux_channels);
2131 recreate_resampler = true;
2132 }
2133#endif
2134
2135 if (in->requested_rate != in->config.rate) {
2136 recreate_resampler = true;
2137 }
2138
2139 if (recreate_resampler) {
2140 if (in->resampler) {
2141 release_resampler(in->resampler);
2142 in->resampler = NULL;
2143 }
2144 in->buf_provider.get_next_buffer = get_next_buffer;
2145 in->buf_provider.release_buffer = release_buffer;
2146 ret = create_resampler(in->config.rate,
2147 in->requested_rate,
2148 in->config.channels,
2149 RESAMPLER_QUALITY_DEFAULT,
2150 &in->buf_provider,
2151 &in->resampler);
2152 }
2153
2154#ifdef PREPROCESSING_ENABLED
2155 if (in->enable_aec && in->echo_reference == NULL) {
2156 in->echo_reference = get_echo_reference(adev,
2157 AUDIO_FORMAT_PCM_16_BIT,
2158 audio_channel_count_from_in_mask(in->main_channels),
2159 in->requested_rate
2160 );
2161 }
2162
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002163#endif
2164
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002165 if (in->dev->voice.in_call) {
2166 ALOGV("%s: in_call, not handling PCMs", __func__);
2167 goto skip_pcm_handling;
2168 }
2169
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002170 /* Open the PCM device.
2171 * The HW is limited to support only the default pcm_profile settings.
2172 * As such a change in aux_channels will not have an effect.
2173 */
2174 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d, smp rate %d format %d, \
2175 period_size %d", __func__, pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
2176 pcm_device->pcm_profile->config.channels,pcm_device->pcm_profile->config.rate,
2177 pcm_device->pcm_profile->config.format, pcm_device->pcm_profile->config.period_size);
2178
stenkinevgeniy44335362018-05-07 18:00:13 +00002179 pcm_device->pcm = pcm_open(pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002180 PCM_IN | PCM_MONOTONIC, &pcm_device->pcm_profile->config);
2181
stenkinevgeniy44335362018-05-07 18:00:13 +00002182 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2183 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2184 pcm_close(pcm_device->pcm);
2185 pcm_device->pcm = NULL;
2186 ret = -EIO;
2187 goto error_open;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002188 }
2189
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002190skip_pcm_handling:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002191 /* force read and proc buffer reallocation in case of frame size or
2192 * channel count change */
2193 in->proc_buf_frames = 0;
2194 in->proc_buf_size = 0;
2195 in->read_buf_size = 0;
2196 in->read_buf_frames = 0;
2197
2198 /* if no supported sample rate is available, use the resampler */
2199 if (in->resampler) {
2200 in->resampler->reset(in->resampler);
2201 }
2202
2203 ALOGV("%s: exit", __func__);
2204 return ret;
2205
2206error_open:
2207 if (in->resampler) {
2208 release_resampler(in->resampler);
2209 in->resampler = NULL;
2210 }
2211 stop_input_stream(in);
2212
2213error_config:
2214 ALOGV("%s: exit: status(%d)", __func__, ret);
2215 adev->active_input = NULL;
2216 return ret;
2217}
2218
2219void lock_input_stream(struct stream_in *in)
2220{
2221 pthread_mutex_lock(&in->pre_lock);
2222 pthread_mutex_lock(&in->lock);
2223 pthread_mutex_unlock(&in->pre_lock);
2224}
2225
2226void lock_output_stream(struct stream_out *out)
2227{
2228 pthread_mutex_lock(&out->pre_lock);
2229 pthread_mutex_lock(&out->lock);
2230 pthread_mutex_unlock(&out->pre_lock);
2231}
2232
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002233static int uc_release_pcm_devices(struct audio_usecase *usecase)
2234{
2235 struct stream_out *out = (struct stream_out *)usecase->stream;
2236 struct pcm_device *pcm_device;
2237 struct listnode *node;
2238 struct listnode *next;
2239
2240 list_for_each_safe(node, next, &out->pcm_dev_list) {
2241 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2242 list_remove(node);
2243 free(pcm_device);
2244 }
2245 list_init(&usecase->mixer_list);
2246
2247 return 0;
2248}
2249
2250static int uc_select_pcm_devices(struct audio_usecase *usecase)
2251
2252{
2253 struct stream_out *out = (struct stream_out *)usecase->stream;
2254 struct pcm_device *pcm_device;
2255 struct pcm_device_profile *pcm_profile;
2256 struct mixer_card *mixer_card;
2257 audio_devices_t devices = usecase->devices;
2258
2259 list_init(&usecase->mixer_list);
2260 list_init(&out->pcm_dev_list);
2261
2262 while ((pcm_profile = get_pcm_device(usecase->type, devices)) != NULL) {
2263 pcm_device = calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01002264 if (pcm_device == NULL) {
2265 return -ENOMEM;
2266 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002267 pcm_device->pcm_profile = pcm_profile;
2268 list_add_tail(&out->pcm_dev_list, &pcm_device->stream_list_node);
2269 mixer_card = uc_get_mixer_for_card(usecase, pcm_profile->card);
2270 if (mixer_card == NULL) {
2271 mixer_card = adev_get_mixer_for_card(out->dev, pcm_profile->card);
2272 list_add_tail(&usecase->mixer_list, &mixer_card->uc_list_node[usecase->id]);
2273 }
2274 devices &= ~pcm_profile->devices;
2275 }
2276
2277 return 0;
2278}
2279
2280static int out_close_pcm_devices(struct stream_out *out)
2281{
2282 struct pcm_device *pcm_device;
2283 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002284
2285 list_for_each(node, &out->pcm_dev_list) {
2286 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002287 if (pcm_device->pcm) {
2288 pcm_close(pcm_device->pcm);
2289 pcm_device->pcm = NULL;
2290 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002291 }
2292
2293 return 0;
2294}
2295
2296static int out_open_pcm_devices(struct stream_out *out)
2297{
2298 struct pcm_device *pcm_device;
2299 struct listnode *node;
2300 int ret = 0;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002301 int pcm_device_card;
2302 int pcm_device_id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002303
2304 list_for_each(node, &out->pcm_dev_list) {
2305 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002306 pcm_device_card = pcm_device->pcm_profile->card;
2307 pcm_device_id = pcm_device->pcm_profile->id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002308
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002309 if (out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
2310 pcm_device_id = pcm_device_deep_buffer.id;
2311
2312 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
2313 __func__, pcm_device_card, pcm_device_id);
2314
2315 pcm_device->pcm = pcm_open(pcm_device_card, pcm_device_id,
stenkinevgeniy2ef158a2018-05-08 06:52:05 +00002316 PCM_OUT | PCM_MONOTONIC, &out->config);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002317
2318 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2319 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2320 pcm_device->pcm = NULL;
2321 ret = -EIO;
2322 goto error_open;
2323 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002324 }
2325 return ret;
2326
2327error_open:
2328 out_close_pcm_devices(out);
2329 return ret;
2330}
2331
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002332int disable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002333{
2334 struct audio_device *adev = out->dev;
2335 struct audio_usecase *uc_info;
2336
2337 uc_info = get_usecase_from_id(adev, out->usecase);
2338 if (uc_info == NULL) {
2339 ALOGE("%s: Could not find the usecase (%d) in the list",
2340 __func__, out->usecase);
2341 return -EINVAL;
2342 }
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002343 disable_snd_device(adev, uc_info, uc_info->out_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002344 uc_release_pcm_devices(uc_info);
2345 list_remove(&uc_info->adev_list_node);
2346 free(uc_info);
2347
2348 return 0;
2349}
2350
Andreas Schneider56204f62017-01-31 08:17:32 +01002351int enable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002352{
2353 struct audio_device *adev = out->dev;
2354 struct audio_usecase *uc_info;
2355
2356 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002357 if (uc_info == NULL) {
2358 return -ENOMEM;
2359 }
2360
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002361 uc_info->id = out->usecase;
2362 uc_info->type = PCM_PLAYBACK;
2363 uc_info->stream = (struct audio_stream *)out;
2364 uc_info->devices = out->devices;
2365 uc_info->in_snd_device = SND_DEVICE_NONE;
2366 uc_info->out_snd_device = SND_DEVICE_NONE;
2367 uc_select_pcm_devices(uc_info);
2368
2369 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2370 select_devices(adev, out->usecase);
Andreas Schneider56204f62017-01-31 08:17:32 +01002371
2372 return 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002373}
2374
2375static int stop_output_stream(struct stream_out *out)
2376{
2377 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002378 bool do_disable = true;
2379
2380 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2381 out->usecase, use_case_table[out->usecase]);
2382
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002383 stop_output_offload_stream(out, &do_disable);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002384
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002385 if (do_disable)
2386 ret = disable_output_path_l(out);
2387
2388 ALOGV("%s: exit: status(%d)", __func__, ret);
2389 return ret;
2390}
2391
2392static int start_output_stream(struct stream_out *out)
2393{
2394 int ret = 0;
2395 struct audio_device *adev = out->dev;
2396
2397 ALOGV("%s: enter: usecase(%d: %s) devices(%#x) channels(%d)",
2398 __func__, out->usecase, use_case_table[out->usecase], out->devices, out->config.channels);
2399
Andreas Schneider56204f62017-01-31 08:17:32 +01002400 ret = enable_output_path_l(out);
2401 if (ret != 0) {
2402 goto error_config;
2403 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002404
2405 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2406 out->compr = NULL;
2407 ret = out_open_pcm_devices(out);
2408 if (ret != 0)
2409 goto error_open;
2410#ifdef PREPROCESSING_ENABLED
2411 out->echo_reference = NULL;
2412 out->echo_reference_generation = adev->echo_reference_generation;
2413 if (adev->echo_reference != NULL)
2414 out->echo_reference = adev->echo_reference;
2415#endif
2416 } else {
2417 out->compr = compress_open(COMPRESS_CARD, COMPRESS_DEVICE,
2418 COMPRESS_IN, &out->compr_config);
2419 if (out->compr && !is_compress_ready(out->compr)) {
2420 ALOGE("%s: %s", __func__, compress_get_error(out->compr));
2421 compress_close(out->compr);
2422 out->compr = NULL;
2423 ret = -EIO;
2424 goto error_open;
2425 }
2426 if (out->offload_callback)
2427 compress_nonblock(out->compr, out->non_blocking);
2428
2429 if (adev->offload_fx_start_output != NULL)
2430 adev->offload_fx_start_output(out->handle);
2431 }
2432 ALOGV("%s: exit", __func__);
2433 return 0;
2434error_open:
2435 stop_output_stream(out);
2436error_config:
2437 return ret;
2438}
2439
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002440int stop_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002441{
2442 struct audio_usecase *uc_info;
2443
2444 ALOGV("%s: enter", __func__);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002445 adev->voice.in_call = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002446
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002447 stop_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002448
2449 uc_info = get_usecase_from_id(adev, USECASE_VOICE_CALL);
2450 if (uc_info == NULL) {
2451 ALOGE("%s: Could not find the usecase (%d) in the list",
2452 __func__, USECASE_VOICE_CALL);
2453 return -EINVAL;
2454 }
2455
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002456 disable_snd_device(adev, uc_info, uc_info->out_snd_device);
2457 disable_snd_device(adev, uc_info, uc_info->in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002458
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002459 list_remove(&uc_info->adev_list_node);
2460 free(uc_info);
2461
2462 ALOGV("%s: exit", __func__);
2463 return 0;
2464}
2465
2466/* always called with adev lock held */
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002467int start_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002468{
2469 struct audio_usecase *uc_info;
Andreas Schneider56204f62017-01-31 08:17:32 +01002470 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002471
2472 ALOGV("%s: enter", __func__);
2473
2474 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002475 if (uc_info == NULL) {
2476 ret = -ENOMEM;
2477 goto exit;
2478 }
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002479 /*
2480 * We set this early so that functions called after this is being set
2481 * can use it. It is e.g. needed in select_devices() to inform the RILD
2482 * which output device we use.
2483 */
2484 adev->voice.in_call = true;
Andreas Schneider56204f62017-01-31 08:17:32 +01002485
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002486 uc_info->id = USECASE_VOICE_CALL;
2487 uc_info->type = VOICE_CALL;
2488 uc_info->stream = (struct audio_stream *)adev->primary_output;
2489 uc_info->devices = adev->primary_output->devices;
2490 uc_info->in_snd_device = SND_DEVICE_NONE;
2491 uc_info->out_snd_device = SND_DEVICE_NONE;
2492
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002493 list_init(&uc_info->mixer_list);
2494 list_add_tail(&uc_info->mixer_list,
2495 &adev_get_mixer_for_card(adev, SOUND_CARD)->uc_list_node[uc_info->id]);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002496
2497 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2498
2499 select_devices(adev, USECASE_VOICE_CALL);
2500
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002501 start_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002502
2503 /* set cached volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002504 set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002505
Andreas Schneider56204f62017-01-31 08:17:32 +01002506exit:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002507 ALOGV("%s: exit", __func__);
Andreas Schneider56204f62017-01-31 08:17:32 +01002508 return ret;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002509}
2510
2511static int check_input_parameters(uint32_t sample_rate,
2512 audio_format_t format,
2513 int channel_count)
2514{
2515 if (format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL;
2516
2517 if ((channel_count < 1) || (channel_count > 2)) return -EINVAL;
2518
2519 switch (sample_rate) {
2520 case 8000:
2521 case 11025:
2522 case 12000:
2523 case 16000:
2524 case 22050:
2525 case 24000:
2526 case 32000:
2527 case 44100:
2528 case 48000:
2529 break;
2530 default:
2531 return -EINVAL;
2532 }
2533
2534 return 0;
2535}
2536
2537static size_t get_input_buffer_size(uint32_t sample_rate,
2538 audio_format_t format,
2539 int channel_count,
2540 usecase_type_t usecase_type,
2541 audio_devices_t devices)
2542{
2543 size_t size = 0;
2544 struct pcm_device_profile *pcm_profile;
2545
2546 if (check_input_parameters(sample_rate, format, channel_count) != 0)
2547 return 0;
2548
2549 pcm_profile = get_pcm_device(usecase_type, devices);
2550 if (pcm_profile == NULL)
2551 return 0;
2552
2553 /*
2554 * take resampling into account and return the closest majoring
2555 * multiple of 16 frames, as audioflinger expects audio buffers to
2556 * be a multiple of 16 frames
2557 */
2558 size = (pcm_profile->config.period_size * sample_rate) / pcm_profile->config.rate;
2559 size = ((size + 15) / 16) * 16;
2560
2561 return (size * channel_count * audio_bytes_per_sample(format));
2562
2563}
2564
2565static uint32_t out_get_sample_rate(const struct audio_stream *stream)
2566{
2567 struct stream_out *out = (struct stream_out *)stream;
2568
2569 return out->sample_rate;
2570}
2571
2572static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
2573{
2574 (void)stream;
2575 (void)rate;
2576 return -ENOSYS;
2577}
2578
2579static size_t out_get_buffer_size(const struct audio_stream *stream)
2580{
2581 struct stream_out *out = (struct stream_out *)stream;
2582
2583 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2584 return out->compr_config.fragment_size;
2585 }
2586
2587 return out->config.period_size *
2588 audio_stream_out_frame_size((const struct audio_stream_out *)stream);
2589}
2590
2591static uint32_t out_get_channels(const struct audio_stream *stream)
2592{
2593 struct stream_out *out = (struct stream_out *)stream;
2594
2595 return out->channel_mask;
2596}
2597
2598static audio_format_t out_get_format(const struct audio_stream *stream)
2599{
2600 struct stream_out *out = (struct stream_out *)stream;
2601
2602 return out->format;
2603}
2604
2605static int out_set_format(struct audio_stream *stream, audio_format_t format)
2606{
2607 (void)stream;
2608 (void)format;
2609 return -ENOSYS;
2610}
2611
2612static int do_out_standby_l(struct stream_out *out)
2613{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002614 int status = 0;
2615
2616 out->standby = true;
2617 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2618 out_close_pcm_devices(out);
2619#ifdef PREPROCESSING_ENABLED
2620 /* stop writing to echo reference */
2621 if (out->echo_reference != NULL) {
2622 out->echo_reference->write(out->echo_reference, NULL);
2623 if (out->echo_reference_generation != adev->echo_reference_generation) {
2624 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
2625 release_echo_reference(out->echo_reference);
2626 out->echo_reference_generation = adev->echo_reference_generation;
2627 }
2628 out->echo_reference = NULL;
2629 }
2630#endif
2631 } else {
2632 stop_compressed_output_l(out);
2633 out->gapless_mdata.encoder_delay = 0;
2634 out->gapless_mdata.encoder_padding = 0;
2635 if (out->compr != NULL) {
2636 compress_close(out->compr);
2637 out->compr = NULL;
2638 }
2639 }
2640 status = stop_output_stream(out);
2641
2642 return status;
2643}
2644
2645static int out_standby(struct audio_stream *stream)
2646{
2647 struct stream_out *out = (struct stream_out *)stream;
2648 struct audio_device *adev = out->dev;
2649
2650 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2651 out->usecase, use_case_table[out->usecase]);
2652 lock_output_stream(out);
2653 if (!out->standby) {
2654 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002655 amplifier_output_stream_standby((struct audio_stream_out *) stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002656 do_out_standby_l(out);
2657 pthread_mutex_unlock(&adev->lock);
2658 }
2659 pthread_mutex_unlock(&out->lock);
2660 ALOGV("%s: exit", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01002661
2662 // out->last_write_time_us = 0; unnecessary as a stale write time has same effect
2663
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002664 return 0;
2665}
2666
2667static int out_dump(const struct audio_stream *stream, int fd)
2668{
2669 (void)stream;
2670 (void)fd;
2671
2672 return 0;
2673}
2674
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002675static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
2676{
2677 struct stream_out *out = (struct stream_out *)stream;
2678 struct audio_device *adev = out->dev;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002679 struct listnode *node;
2680 struct str_parms *parms;
2681 char value[32];
2682 int ret, val = 0;
2683 struct audio_usecase *uc_info;
2684 bool do_standby = false;
2685 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002686#ifdef PREPROCESSING_ENABLED
2687 struct stream_in *in = NULL; /* if non-NULL, then force input to standby */
2688#endif
2689
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002690 ALOGV("%s: enter: usecase(%d: %s) kvpairs: %s out->devices(%#x) "
2691 "adev->mode(%#x)",
2692 __func__, out->usecase, use_case_table[out->usecase], kvpairs,
2693 out->devices, adev->mode);
2694
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002695 parms = str_parms_create_str(kvpairs);
2696 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
2697 if (ret >= 0) {
2698 val = atoi(value);
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002699
2700 ALOGV("%s: routing: usecase(%d: %s) devices=(%#x) adev->mode(%#x)",
2701 __func__, out->usecase, use_case_table[out->usecase], val,
2702 adev->mode);
2703
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002704 pthread_mutex_lock(&adev->lock_inputs);
2705 lock_output_stream(out);
2706 pthread_mutex_lock(&adev->lock);
2707#ifdef PREPROCESSING_ENABLED
2708 if (((int)out->devices != val) && (val != 0) && (!out->standby) &&
2709 (out->usecase == USECASE_AUDIO_PLAYBACK)) {
2710 /* reset active input:
2711 * - to attach the echo reference
2712 * - because a change in output device may change mic settings */
2713 if (adev->active_input && (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
2714 adev->active_input->source == AUDIO_SOURCE_MIC)) {
2715 in = adev->active_input;
2716 }
2717 }
2718#endif
Christopher N. Hesse33affb82017-11-16 17:01:37 +01002719 if (val != SND_DEVICE_NONE) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002720 bool bt_sco_active = false;
2721
2722 if (out->devices & AUDIO_DEVICE_OUT_ALL_SCO) {
2723 bt_sco_active = true;
2724 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002725 out->devices = val;
2726
2727 if (!out->standby) {
2728 uc_info = get_usecase_from_id(adev, out->usecase);
2729 if (uc_info == NULL) {
2730 ALOGE("%s: Could not find the usecase (%d) in the list",
2731 __func__, out->usecase);
2732 } else {
2733 list_for_each(node, &out->pcm_dev_list) {
2734 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2735 if ((pcm_device->pcm_profile->devices & val) == 0)
2736 do_standby = true;
2737 val &= ~pcm_device->pcm_profile->devices;
2738 }
2739 if (val != 0)
2740 do_standby = true;
2741 }
2742 if (do_standby)
2743 do_out_standby_l(out);
2744 else {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002745 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
2746 out_set_offload_parameters(adev, uc_info);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002747 select_devices(adev, out->usecase);
2748 }
2749 }
2750
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002751 if ((adev->mode == AUDIO_MODE_IN_CALL) && !adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002752 (out == adev->primary_output)) {
2753 start_voice_call(adev);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002754 } else if ((adev->mode == AUDIO_MODE_IN_CALL) &&
2755 adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002756 (out == adev->primary_output)) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002757 /* Turn on bluetooth if needed */
2758 if ((out->devices & AUDIO_DEVICE_OUT_ALL_SCO) && !bt_sco_active) {
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002759 select_devices(adev, USECASE_VOICE_CALL);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002760 start_voice_session_bt_sco(adev->voice.session);
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002761 } else {
2762 /*
2763 * When we select different devices we need to restart the
2764 * voice call. The modem closes the stream on its end and
2765 * we do not get any output.
2766 */
2767 stop_voice_call(adev);
2768 start_voice_call(adev);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002769 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002770 }
2771 }
2772
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002773 pthread_mutex_unlock(&adev->lock);
2774 pthread_mutex_unlock(&out->lock);
2775#ifdef PREPROCESSING_ENABLED
2776 if (in) {
2777 /* The lock on adev->lock_inputs prevents input stream from being closed */
2778 lock_input_stream(in);
2779 pthread_mutex_lock(&adev->lock);
2780 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
2781 do_in_standby_l(in);
2782 pthread_mutex_unlock(&adev->lock);
2783 pthread_mutex_unlock(&in->lock);
2784 }
2785#endif
2786 pthread_mutex_unlock(&adev->lock_inputs);
2787 }
2788
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002789 amplifier_set_parameters(parms);
2790
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002791 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2792 parse_compress_metadata(out, parms);
2793 }
2794
2795 str_parms_destroy(parms);
2796
2797 if (ret > 0)
2798 ret = 0;
2799 ALOGV("%s: exit: code(%d)", __func__, ret);
2800 return ret;
2801}
2802
2803static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
2804{
2805 struct stream_out *out = (struct stream_out *)stream;
2806 struct str_parms *query = str_parms_create_str(keys);
2807 char *str;
2808 char value[256];
2809 struct str_parms *reply = str_parms_create();
2810 size_t i, j;
2811 int ret;
2812 bool first = true;
2813 ALOGV("%s: enter: keys - %s", __func__, keys);
2814 ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value));
2815 if (ret >= 0) {
2816 value[0] = '\0';
2817 i = 0;
2818 while (out->supported_channel_masks[i] != 0) {
2819 for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) {
2820 if (out_channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) {
2821 if (!first) {
2822 strcat(value, "|");
2823 }
2824 strcat(value, out_channels_name_to_enum_table[j].name);
2825 first = false;
2826 break;
2827 }
2828 }
2829 i++;
2830 }
2831 str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
2832 str = str_parms_to_str(reply);
2833 } else {
2834 str = strdup(keys);
2835 }
2836 str_parms_destroy(query);
2837 str_parms_destroy(reply);
2838 ALOGV("%s: exit: returns - %s", __func__, str);
2839 return str;
2840}
2841
2842static uint32_t out_get_latency(const struct audio_stream_out *stream)
2843{
2844 struct stream_out *out = (struct stream_out *)stream;
2845
2846 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
2847 return COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
2848
2849 return (out->config.period_count * out->config.period_size * 1000) /
2850 (out->config.rate);
2851}
2852
2853static int out_set_volume(struct audio_stream_out *stream, float left,
2854 float right)
2855{
2856 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002857
2858 if (out->usecase == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
2859 /* only take left channel into account: the API is for stereo anyway */
2860 out->muted = (left == 0.0f);
2861 return 0;
2862 } else if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002863 out_set_offload_volume(left, right);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002864 }
2865
2866 return -ENOSYS;
2867}
2868
Andreas Schneider3b643832017-01-31 11:48:22 +01002869#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002870static int fast_set_affinity(pid_t tid) {
2871 cpu_set_t cpu_set;
2872 int cpu_num;
2873 const char *irq_procfs = "/proc/asound/irq_affinity";
2874 FILE *fp;
2875
2876 if ((fp = fopen(irq_procfs, "r")) == NULL) {
2877 ALOGW("Procfs node %s not found", irq_procfs);
2878 return -1;
2879 }
2880
2881 if (fscanf(fp, "%d", &cpu_num) != 1) {
2882 ALOGW("Couldn't read CPU id from procfs node %s", irq_procfs);
2883 fclose(fp);
2884 return -1;
2885 }
2886 fclose(fp);
2887
2888 CPU_ZERO(&cpu_set);
2889 CPU_SET(cpu_num, &cpu_set);
2890 return sched_setaffinity(tid, sizeof(cpu_set), &cpu_set);
2891}
Andreas Schneider3b643832017-01-31 11:48:22 +01002892#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002893
2894static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
2895 size_t bytes)
2896{
2897 struct stream_out *out = (struct stream_out *)stream;
2898 struct audio_device *adev = out->dev;
2899 ssize_t ret = 0;
2900 struct pcm_device *pcm_device;
2901 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002902#ifdef PREPROCESSING_ENABLED
stenkinevgeniyd0a02c02018-05-08 07:17:53 +00002903 size_t frame_size = audio_stream_out_frame_size(stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002904 size_t in_frames = bytes / frame_size;
2905 size_t out_frames = in_frames;
2906 struct stream_in *in = NULL;
2907#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002908
2909 lock_output_stream(out);
2910
Andreas Schneider3b643832017-01-31 11:48:22 +01002911#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002912 if (out->usecase == USECASE_AUDIO_PLAYBACK && !out->is_fastmixer_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01002913 pid_t tid = gettid();
2914 int err;
2915
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002916 err = fast_set_affinity(tid);
2917 if (err < 0) {
2918 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
2919 }
2920 out->is_fastmixer_affinity_set = true;
2921 }
Andreas Schneider3b643832017-01-31 11:48:22 +01002922#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002923
2924 if (out->standby) {
2925#ifdef PREPROCESSING_ENABLED
2926 pthread_mutex_unlock(&out->lock);
2927 /* Prevent input stream from being closed */
2928 pthread_mutex_lock(&adev->lock_inputs);
2929 lock_output_stream(out);
2930 if (!out->standby) {
2931 pthread_mutex_unlock(&adev->lock_inputs);
2932 goto false_alarm;
2933 }
2934#endif
2935 pthread_mutex_lock(&adev->lock);
2936 ret = start_output_stream(out);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002937 if (ret == 0) {
2938 amplifier_output_stream_start(stream, out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD);
2939 }
2940
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002941 /* ToDo: If use case is compress offload should return 0 */
2942 if (ret != 0) {
2943 pthread_mutex_unlock(&adev->lock);
2944#ifdef PREPROCESSING_ENABLED
2945 pthread_mutex_unlock(&adev->lock_inputs);
2946#endif
2947 goto exit;
2948 }
2949 out->standby = false;
2950
2951#ifdef PREPROCESSING_ENABLED
2952 /* A change in output device may change the microphone selection */
2953 if (adev->active_input &&
2954 (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
2955 adev->active_input->source == AUDIO_SOURCE_MIC)) {
2956 in = adev->active_input;
2957 ALOGV("%s: enter:) force_input_standby true", __func__);
2958 }
2959#endif
2960 pthread_mutex_unlock(&adev->lock);
2961#ifdef PREPROCESSING_ENABLED
2962 if (!in) {
2963 /* Leave mutex locked iff in != NULL */
2964 pthread_mutex_unlock(&adev->lock_inputs);
2965 }
2966#endif
2967 }
Andreas Schneider5a2f1002017-02-09 10:59:04 +01002968#ifdef PREPROCESSING_ENABLED
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002969false_alarm:
Andreas Schneider5a2f1002017-02-09 10:59:04 +01002970#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002971
2972 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002973 ret = out_write_offload(stream, buffer, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002974 return ret;
2975 } else {
2976#ifdef PREPROCESSING_ENABLED
2977 if (android_atomic_acquire_load(&adev->echo_reference_generation)
2978 != out->echo_reference_generation) {
2979 pthread_mutex_lock(&adev->lock);
2980 if (out->echo_reference != NULL) {
2981 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
2982 release_echo_reference(out->echo_reference);
2983 }
2984 // note that adev->echo_reference_generation here can be different from the one
2985 // tested above but it doesn't matter as we now have the adev mutex and it is consistent
2986 // with what has been set by get_echo_reference() or put_echo_reference()
2987 out->echo_reference_generation = adev->echo_reference_generation;
2988 out->echo_reference = adev->echo_reference;
2989 ALOGV("%s: update echo reference generation %d", __func__,
2990 out->echo_reference_generation);
2991 pthread_mutex_unlock(&adev->lock);
2992 }
2993#endif
2994
2995 if (out->muted)
2996 memset((void *)buffer, 0, bytes);
2997 list_for_each(node, &out->pcm_dev_list) {
2998 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002999 if (pcm_device->pcm) {
3000#ifdef PREPROCESSING_ENABLED
3001 if (out->echo_reference != NULL && pcm_device->pcm_profile->devices != SND_DEVICE_OUT_SPEAKER) {
3002 struct echo_reference_buffer b;
3003 b.raw = (void *)buffer;
3004 b.frame_count = in_frames;
3005
3006 get_playback_delay(out, out_frames, &b);
3007 out->echo_reference->write(out->echo_reference, &b);
3008 }
3009#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003010 ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
stenkinevgeniyd0a02c02018-05-08 07:17:53 +00003011 pcm_device->status = pcm_write(pcm_device->pcm, (void *)buffer, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003012 if (pcm_device->status != 0)
3013 ret = pcm_device->status;
3014 }
3015 }
3016 if (ret == 0)
3017 out->written += bytes / (out->config.channels * sizeof(short));
3018 }
3019
3020exit:
3021 pthread_mutex_unlock(&out->lock);
3022
3023 if (ret != 0) {
3024 list_for_each(node, &out->pcm_dev_list) {
3025 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3026 if (pcm_device->pcm && pcm_device->status != 0)
3027 ALOGE("%s: error %zd - %s", __func__, ret, pcm_get_error(pcm_device->pcm));
3028 }
3029 out_standby(&out->stream.common);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003030 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3031 clock_gettime(CLOCK_MONOTONIC, &t);
3032 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3033 const int64_t elapsed_time_since_last_write = now - out->last_write_time_us;
3034 int64_t sleep_time = bytes * 1000000LL / audio_stream_out_frame_size(stream) /
3035 out_get_sample_rate(&stream->common) - elapsed_time_since_last_write;
3036 if (sleep_time > 0) {
3037 usleep(sleep_time);
3038 } else {
3039 // we don't sleep when we exit standby (this is typical for a real alsa buffer).
3040 sleep_time = 0;
3041 }
3042 out->last_write_time_us = now + sleep_time;
3043 // last_write_time_us is an approximation of when the (simulated) alsa
3044 // buffer is believed completely full. The usleep above waits for more space
3045 // in the buffer, but by the end of the sleep the buffer is considered
3046 // topped-off.
3047 //
3048 // On the subsequent out_write(), we measure the elapsed time spent in
3049 // the mixer. This is subtracted from the sleep estimate based on frames,
3050 // thereby accounting for drain in the alsa buffer during mixing.
3051 // This is a crude approximation; we don't handle underruns precisely.
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003052 }
3053
3054#ifdef PREPROCESSING_ENABLED
3055 if (in) {
3056 /* The lock on adev->lock_inputs prevents input stream from being closed */
3057 lock_input_stream(in);
3058 pthread_mutex_lock(&adev->lock);
3059 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
3060 do_in_standby_l(in);
3061 pthread_mutex_unlock(&adev->lock);
3062 pthread_mutex_unlock(&in->lock);
3063 /* This mutex was left locked iff in != NULL */
3064 pthread_mutex_unlock(&adev->lock_inputs);
3065 }
3066#endif
3067
3068 return bytes;
3069}
3070
3071static int out_get_render_position(const struct audio_stream_out *stream,
3072 uint32_t *dsp_frames)
3073{
3074 struct stream_out *out = (struct stream_out *)stream;
3075 *dsp_frames = 0;
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003076 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
3077 return out_get_render_offload_position(out, dsp_frames);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003078 } else
3079 return -EINVAL;
3080}
3081
3082static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3083{
3084 (void)stream;
3085 (void)effect;
3086 return 0;
3087}
3088
3089static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3090{
3091 (void)stream;
3092 (void)effect;
3093 return 0;
3094}
3095
3096static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
3097 int64_t *timestamp)
3098{
3099 (void)stream;
3100 (void)timestamp;
3101 return -EINVAL;
3102}
3103
3104static int out_get_presentation_position(const struct audio_stream_out *stream,
3105 uint64_t *frames, struct timespec *timestamp)
3106{
3107 struct stream_out *out = (struct stream_out *)stream;
Victor Lourme5869cd32018-03-26 19:36:07 +02003108 int ret = -EINVAL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003109
3110 lock_output_stream(out);
3111
3112 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003113 ret = out_get_presentation_offload_position(out, frames, timestamp);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003114 } else {
3115 /* FIXME: which device to read from? */
3116 if (!list_empty(&out->pcm_dev_list)) {
Andreas Schneiderd6359182017-02-08 16:58:22 +01003117 struct pcm_device *pcm_device;
3118 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003119 unsigned int avail;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003120
Andreas Schneiderd6359182017-02-08 16:58:22 +01003121 list_for_each(node, &out->pcm_dev_list) {
3122 pcm_device = node_to_item(node,
3123 struct pcm_device,
3124 stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003125
Andreas Schneiderd6359182017-02-08 16:58:22 +01003126 if (pcm_device->pcm != NULL) {
3127 if (pcm_get_htimestamp(pcm_device->pcm, &avail, timestamp) == 0) {
3128 size_t kernel_buffer_size = out->config.period_size * out->config.period_count;
3129 int64_t signed_frames = out->written - kernel_buffer_size + avail;
3130 /* This adjustment accounts for buffering after app processor.
3131 It is based on estimated DSP latency per use case, rather than exact. */
3132 signed_frames -=
3133 (render_latency(out->usecase) * out->sample_rate / 1000000LL);
3134
3135 /* It would be unusual for this value to be negative, but check just in case ... */
3136 if (signed_frames >= 0) {
3137 *frames = signed_frames;
3138 ret = 0;
3139 goto done;
3140 }
Andreas Schneiderd6359182017-02-08 16:58:22 +01003141 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003142 }
3143 }
3144 }
3145 }
3146
Andreas Schneiderd6359182017-02-08 16:58:22 +01003147done:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003148 pthread_mutex_unlock(&out->lock);
3149
3150 return ret;
3151}
3152
3153static int out_set_callback(struct audio_stream_out *stream,
3154 stream_callback_t callback, void *cookie)
3155{
3156 struct stream_out *out = (struct stream_out *)stream;
3157
3158 ALOGV("%s", __func__);
3159 lock_output_stream(out);
3160 out->offload_callback = callback;
3161 out->offload_cookie = cookie;
3162 pthread_mutex_unlock(&out->lock);
3163 return 0;
3164}
3165
3166static int out_pause(struct audio_stream_out* stream)
3167{
3168 struct stream_out *out = (struct stream_out *)stream;
3169 int status = -ENOSYS;
3170 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003171 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3172 status = out_pause_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003173 return status;
3174}
3175
3176static int out_resume(struct audio_stream_out* stream)
3177{
3178 struct stream_out *out = (struct stream_out *)stream;
3179 int status = -ENOSYS;
3180 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003181 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3182 status = out_resume_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003183 return status;
3184}
3185
3186static int out_drain(struct audio_stream_out* stream, audio_drain_type_t type )
3187{
3188 struct stream_out *out = (struct stream_out *)stream;
3189 int status = -ENOSYS;
3190 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003191 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3192 status = out_drain_offload(out, type);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003193 return status;
3194}
3195
3196static int out_flush(struct audio_stream_out* stream)
3197{
3198 struct stream_out *out = (struct stream_out *)stream;
3199 ALOGV("%s", __func__);
3200 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003201 return out_flush_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003202 }
3203 return -ENOSYS;
3204}
3205
3206/** audio_stream_in implementation **/
3207static uint32_t in_get_sample_rate(const struct audio_stream *stream)
3208{
3209 struct stream_in *in = (struct stream_in *)stream;
3210
3211 return in->requested_rate;
3212}
3213
3214static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
3215{
3216 (void)stream;
3217 (void)rate;
3218 return -ENOSYS;
3219}
3220
3221static uint32_t in_get_channels(const struct audio_stream *stream)
3222{
3223 struct stream_in *in = (struct stream_in *)stream;
3224
3225 return in->main_channels;
3226}
3227
3228static audio_format_t in_get_format(const struct audio_stream *stream)
3229{
3230 (void)stream;
3231 return AUDIO_FORMAT_PCM_16_BIT;
3232}
3233
3234static int in_set_format(struct audio_stream *stream, audio_format_t format)
3235{
3236 (void)stream;
3237 (void)format;
3238
3239 return -ENOSYS;
3240}
3241
3242static size_t in_get_buffer_size(const struct audio_stream *stream)
3243{
3244 struct stream_in *in = (struct stream_in *)stream;
3245
3246 return get_input_buffer_size(in->requested_rate,
3247 in_get_format(stream),
3248 audio_channel_count_from_in_mask(in->main_channels),
3249 in->usecase_type,
3250 in->devices);
3251}
3252
3253static int in_close_pcm_devices(struct stream_in *in)
3254{
3255 struct pcm_device *pcm_device;
3256 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003257
3258 list_for_each(node, &in->pcm_dev_list) {
3259 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3260 if (pcm_device) {
3261 if (pcm_device->pcm)
3262 pcm_close(pcm_device->pcm);
3263 pcm_device->pcm = NULL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003264 }
3265 }
3266 return 0;
3267}
3268
3269
3270/* must be called with stream and hw device mutex locked */
3271static int do_in_standby_l(struct stream_in *in)
3272{
3273 int status = 0;
3274
3275#ifdef PREPROCESSING_ENABLED
3276 struct audio_device *adev = in->dev;
3277#endif
3278 if (!in->standby) {
3279
3280 in_close_pcm_devices(in);
3281
3282#ifdef PREPROCESSING_ENABLED
3283 if (in->echo_reference != NULL) {
3284 /* stop reading from echo reference */
3285 in->echo_reference->read(in->echo_reference, NULL);
3286 put_echo_reference(adev, in->echo_reference);
3287 in->echo_reference = NULL;
3288 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003289#endif // PREPROCESSING_ENABLED
3290
3291 status = stop_input_stream(in);
3292
3293 if (in->read_buf) {
3294 free(in->read_buf);
3295 in->read_buf = NULL;
3296 }
3297
3298 in->standby = 1;
3299 }
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003300
3301 in->last_read_time_us = 0;
3302
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003303 return 0;
3304}
3305
3306// called with adev->lock_inputs locked
3307static int in_standby_l(struct stream_in *in)
3308{
3309 struct audio_device *adev = in->dev;
3310 int status = 0;
3311 lock_input_stream(in);
3312 if (!in->standby) {
3313 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003314 amplifier_input_stream_standby((struct audio_stream_in *) in);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003315 status = do_in_standby_l(in);
3316 pthread_mutex_unlock(&adev->lock);
3317 }
3318 pthread_mutex_unlock(&in->lock);
3319 return status;
3320}
3321
3322static int in_standby(struct audio_stream *stream)
3323{
3324 struct stream_in *in = (struct stream_in *)stream;
3325 struct audio_device *adev = in->dev;
3326 int status;
3327 ALOGV("%s: enter", __func__);
3328 pthread_mutex_lock(&adev->lock_inputs);
3329 status = in_standby_l(in);
3330 pthread_mutex_unlock(&adev->lock_inputs);
3331 ALOGV("%s: exit: status(%d)", __func__, status);
3332 return status;
3333}
3334
3335static int in_dump(const struct audio_stream *stream, int fd)
3336{
3337 (void)stream;
3338 (void)fd;
3339
3340 return 0;
3341}
3342
3343static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
3344{
3345 struct stream_in *in = (struct stream_in *)stream;
3346 struct audio_device *adev = in->dev;
3347 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003348 char value[32];
3349 int ret, val = 0;
3350 struct audio_usecase *uc_info;
3351 bool do_standby = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003352 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003353
3354 ALOGV("%s: enter: kvpairs=%s", __func__, kvpairs);
3355 parms = str_parms_create_str(kvpairs);
3356
3357 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
3358
3359 pthread_mutex_lock(&adev->lock_inputs);
3360 lock_input_stream(in);
3361 pthread_mutex_lock(&adev->lock);
3362 if (ret >= 0) {
3363 val = atoi(value);
3364 /* no audio source uses val == 0 */
3365 if (((int)in->source != val) && (val != 0)) {
3366 in->source = val;
3367 }
3368 }
3369
3370 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
3371 if (ret >= 0) {
3372 val = atoi(value);
3373 if (((int)in->devices != val) && (val != 0)) {
3374 in->devices = val;
3375 /* If recording is in progress, change the tx device to new device */
3376 if (!in->standby) {
3377 uc_info = get_usecase_from_id(adev, in->usecase);
3378 if (uc_info == NULL) {
3379 ALOGE("%s: Could not find the usecase (%d) in the list",
3380 __func__, in->usecase);
3381 } else {
3382 if (list_empty(&in->pcm_dev_list))
3383 ALOGE("%s: pcm device list empty", __func__);
3384 else {
3385 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3386 struct pcm_device, stream_list_node);
3387 if ((pcm_device->pcm_profile->devices & val & ~AUDIO_DEVICE_BIT_IN) == 0) {
3388 do_standby = true;
3389 }
3390 }
3391 }
3392 if (do_standby) {
3393 ret = do_in_standby_l(in);
3394 } else
3395 ret = select_devices(adev, in->usecase);
3396 }
3397 }
3398 }
3399 pthread_mutex_unlock(&adev->lock);
3400 pthread_mutex_unlock(&in->lock);
3401 pthread_mutex_unlock(&adev->lock_inputs);
3402 str_parms_destroy(parms);
3403
3404 if (ret > 0)
3405 ret = 0;
3406
3407 ALOGV("%s: exit: status(%d)", __func__, ret);
3408 return ret;
3409}
3410
3411static char* in_get_parameters(const struct audio_stream *stream,
3412 const char *keys)
3413{
3414 (void)stream;
3415 (void)keys;
3416
3417 return strdup("");
3418}
3419
3420static int in_set_gain(struct audio_stream_in *stream, float gain)
3421{
3422 (void)stream;
3423 (void)gain;
3424
3425 return 0;
3426}
3427
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003428static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
3429 size_t bytes)
3430{
3431 struct stream_in *in = (struct stream_in *)stream;
3432 struct audio_device *adev = in->dev;
3433 ssize_t frames = -1;
3434 int ret = -1;
3435 int read_and_process_successful = false;
3436
3437 size_t frames_rq = bytes / audio_stream_in_frame_size(stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003438
3439 /* no need to acquire adev->lock_inputs because API contract prevents a close */
3440 lock_input_stream(in);
3441
Andreas Schneider3b643832017-01-31 11:48:22 +01003442#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003443 if (in->usecase == USECASE_AUDIO_CAPTURE && !in->is_fastcapture_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003444 pid_t tid = gettid();
3445 int err;
3446
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003447 err = fast_set_affinity(tid);
3448 if (err < 0) {
3449 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
3450 }
3451 in->is_fastcapture_affinity_set = true;
3452 }
Andreas Schneider3b643832017-01-31 11:48:22 +01003453#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003454
3455 if (in->standby) {
3456 pthread_mutex_unlock(&in->lock);
3457 pthread_mutex_lock(&adev->lock_inputs);
3458 lock_input_stream(in);
3459 if (!in->standby) {
3460 pthread_mutex_unlock(&adev->lock_inputs);
3461 goto false_alarm;
3462 }
3463 pthread_mutex_lock(&adev->lock);
3464 ret = start_input_stream(in);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003465 if (ret == 0) {
3466 amplifier_input_stream_start(stream);
3467 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003468 pthread_mutex_unlock(&adev->lock);
3469 pthread_mutex_unlock(&adev->lock_inputs);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003470
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003471 if (ret != 0) {
3472 goto exit;
3473 }
3474 in->standby = 0;
3475 }
3476false_alarm:
3477
3478 if (!list_empty(&in->pcm_dev_list)) {
stenkinevgeniy44335362018-05-07 18:00:13 +00003479 /*
3480 * Read PCM and:
3481 * - resample if needed
3482 * - process if pre-processors are attached
3483 * - discard unwanted channels
3484 */
3485 frames = read_and_process_frames(in, buffer, frames_rq);
3486 if (frames >= 0)
3487 read_and_process_successful = true;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003488 }
3489
3490 /*
3491 * Instead of writing zeroes here, we could trust the hardware
3492 * to always provide zeroes when muted.
3493 */
3494 if (read_and_process_successful == true && adev->mic_mute)
3495 memset(buffer, 0, bytes);
3496
3497exit:
3498 pthread_mutex_unlock(&in->lock);
3499
3500 if (read_and_process_successful == false) {
3501 in_standby(&in->stream.common);
3502 ALOGV("%s: read failed - sleeping for buffer duration", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003503 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3504 clock_gettime(CLOCK_MONOTONIC, &t);
3505 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3506
3507 // we do a full sleep when exiting standby.
3508 const bool standby = in->last_read_time_us == 0;
3509 const int64_t elapsed_time_since_last_read = standby ?
3510 0 : now - in->last_read_time_us;
3511 int64_t sleep_time = bytes * 1000000LL / audio_stream_in_frame_size(stream) /
3512 in_get_sample_rate(&stream->common) - elapsed_time_since_last_read;
3513 if (sleep_time > 0) {
3514 usleep(sleep_time);
3515 } else {
3516 sleep_time = 0;
3517 }
3518 in->last_read_time_us = now + sleep_time;
3519 // last_read_time_us is an approximation of when the (simulated) alsa
3520 // buffer is drained by the read, and is empty.
3521 //
3522 // On the subsequent in_read(), we measure the elapsed time spent in
3523 // the recording thread. This is subtracted from the sleep estimate based on frames,
3524 // thereby accounting for fill in the alsa buffer during the interim.
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003525 memset(buffer, 0, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003526 }
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003527
3528 if (bytes > 0) {
3529 in->frames_read += bytes / audio_stream_in_frame_size(stream);
3530 }
3531
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003532 return bytes;
3533}
3534
3535static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
3536{
3537 (void)stream;
3538
3539 return 0;
3540}
3541
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003542static int in_get_capture_position(const struct audio_stream_in *stream,
3543 int64_t *frames, int64_t *time)
3544{
3545 if (stream == NULL || frames == NULL || time == NULL) {
3546 return -EINVAL;
3547 }
3548
3549 struct stream_in *in = (struct stream_in *)stream;
3550 struct pcm_device *pcm_device;
3551 int ret = -ENOSYS;
3552
3553 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3554 struct pcm_device, stream_list_node);
3555
3556 pthread_mutex_lock(&in->lock);
3557 if (pcm_device->pcm) {
3558 struct timespec timestamp;
3559 unsigned int avail;
3560 if (pcm_get_htimestamp(pcm_device->pcm, &avail, &timestamp) == 0) {
3561 *frames = in->frames_read + avail;
3562 *time = timestamp.tv_sec * 1000000000LL + timestamp.tv_nsec;
3563 ret = 0;
3564 }
3565 }
3566
3567 pthread_mutex_unlock(&in->lock);
3568 return ret;
3569}
3570
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003571static int add_remove_audio_effect(const struct audio_stream *stream,
3572 effect_handle_t effect,
3573 bool enable)
3574{
3575 struct stream_in *in = (struct stream_in *)stream;
3576 struct audio_device *adev = in->dev;
3577 int status = 0;
3578 effect_descriptor_t desc;
3579#ifdef PREPROCESSING_ENABLED
3580 int i;
3581#endif
3582 status = (*effect)->get_descriptor(effect, &desc);
3583 if (status != 0)
3584 return status;
3585
3586 ALOGI("add_remove_audio_effect(), effect type: %08x, enable: %d ", desc.type.timeLow, enable);
3587
3588 pthread_mutex_lock(&adev->lock_inputs);
3589 lock_input_stream(in);
3590 pthread_mutex_lock(&in->dev->lock);
3591#ifndef PREPROCESSING_ENABLED
3592 if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) &&
3593 in->enable_aec != enable &&
3594 (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0)) {
3595 in->enable_aec = enable;
3596 if (!in->standby)
3597 select_devices(in->dev, in->usecase);
3598 }
3599#else
3600 if ( (in->num_preprocessors > MAX_PREPROCESSORS) && (enable == true) ) {
3601 status = -ENOSYS;
3602 goto exit;
3603 }
3604 if ( enable == true ) {
3605 in->preprocessors[in->num_preprocessors].effect_itfe = effect;
3606 /* add the supported channel of the effect in the channel_configs */
3607 in_read_audio_effect_channel_configs(in, &in->preprocessors[in->num_preprocessors]);
3608 in->num_preprocessors ++;
3609 /* check compatibility between main channel supported and possible auxiliary channels */
3610 in_update_aux_channels(in, effect);//wesley crash
3611 in->aux_channels_changed = true;
3612 } else {
3613 /* if ( enable == false ) */
3614 if (in->num_preprocessors <= 0) {
3615 status = -ENOSYS;
3616 goto exit;
3617 }
3618 status = -EINVAL;
3619 for (i=0; i < in->num_preprocessors; i++) {
3620 if (status == 0) { /* status == 0 means an effect was removed from a previous slot */
3621 in->preprocessors[i - 1].effect_itfe = in->preprocessors[i].effect_itfe;
3622 in->preprocessors[i - 1].channel_configs = in->preprocessors[i].channel_configs;
3623 in->preprocessors[i - 1].num_channel_configs =
3624 in->preprocessors[i].num_channel_configs;
3625 ALOGV("add_remove_audio_effect moving fx from %d to %d", i, i-1);
3626 continue;
3627 }
3628 if ( in->preprocessors[i].effect_itfe == effect ) {
3629 ALOGV("add_remove_audio_effect found fx at index %d", i);
3630 free(in->preprocessors[i].channel_configs);
3631 status = 0;
3632 }
3633 }
3634 if (status != 0)
3635 goto exit;
3636 in->num_preprocessors--;
3637 /* if we remove one effect, at least the last proproc should be reset */
3638 in->preprocessors[in->num_preprocessors].num_channel_configs = 0;
3639 in->preprocessors[in->num_preprocessors].effect_itfe = NULL;
3640 in->preprocessors[in->num_preprocessors].channel_configs = NULL;
3641 in->aux_channels_changed = false;
3642 ALOGV("%s: enable(%d), in->aux_channels_changed(%d)", __func__, enable, in->aux_channels_changed);
3643 }
3644 ALOGI("%s: num_preprocessors = %d", __func__, in->num_preprocessors);
3645
3646 if ( memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
3647 in->enable_aec = enable;
3648 ALOGV("add_remove_audio_effect(), FX_IID_AEC, enable: %d", enable);
3649 if (!in->standby) {
3650 select_devices(in->dev, in->usecase);
3651 do_in_standby_l(in);
3652 }
3653 if (in->enable_aec == true) {
3654 in_configure_reverse(in);
3655 }
3656 }
3657exit:
3658#endif
3659 ALOGW_IF(status != 0, "add_remove_audio_effect() error %d", status);
3660 pthread_mutex_unlock(&in->dev->lock);
3661 pthread_mutex_unlock(&in->lock);
3662 pthread_mutex_unlock(&adev->lock_inputs);
3663 return status;
3664}
3665
3666static int in_add_audio_effect(const struct audio_stream *stream,
3667 effect_handle_t effect)
3668{
3669 ALOGV("%s: effect %p", __func__, effect);
3670 return add_remove_audio_effect(stream, effect, true);
3671}
3672
3673static int in_remove_audio_effect(const struct audio_stream *stream,
3674 effect_handle_t effect)
3675{
3676 ALOGV("%s: effect %p", __func__, effect);
3677 return add_remove_audio_effect(stream, effect, false);
3678}
3679
3680static int adev_open_output_stream(struct audio_hw_device *dev,
3681 audio_io_handle_t handle,
3682 audio_devices_t devices,
3683 audio_output_flags_t flags,
3684 struct audio_config *config,
3685 struct audio_stream_out **stream_out,
3686 const char *address __unused)
3687{
3688 struct audio_device *adev = (struct audio_device *)dev;
3689 struct stream_out *out;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003690 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003691 struct pcm_device_profile *pcm_profile;
3692
3693 ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
3694 __func__, config->sample_rate, config->channel_mask, devices, flags);
3695 *stream_out = NULL;
3696 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
Andreas Schneider56204f62017-01-31 08:17:32 +01003697 if (out == NULL) {
3698 ret = -ENOMEM;
3699 goto error_config;
3700 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003701
3702 if (devices == AUDIO_DEVICE_NONE)
3703 devices = AUDIO_DEVICE_OUT_SPEAKER;
3704
3705 out->flags = flags;
3706 out->devices = devices;
3707 out->dev = adev;
3708 out->format = config->format;
3709 out->sample_rate = config->sample_rate;
3710 out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3711 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
3712 out->handle = handle;
3713
3714 pcm_profile = get_pcm_device(PCM_PLAYBACK, devices);
3715 if (pcm_profile == NULL) {
3716 ret = -EINVAL;
3717 goto error_open;
3718 }
3719 out->config = pcm_profile->config;
3720
3721 /* Init use case and pcm_config */
3722 if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
3723 if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version ||
3724 config->offload_info.size != AUDIO_INFO_INITIALIZER.size) {
3725 ALOGE("%s: Unsupported Offload information", __func__);
3726 ret = -EINVAL;
3727 goto error_open;
3728 }
3729 if (!is_supported_format(config->offload_info.format)) {
3730 ALOGE("%s: Unsupported audio format", __func__);
3731 ret = -EINVAL;
3732 goto error_open;
3733 }
3734
3735 out->compr_config.codec = (struct snd_codec *)
3736 calloc(1, sizeof(struct snd_codec));
Andreas Schneider56204f62017-01-31 08:17:32 +01003737 if (out->compr_config.codec == NULL) {
3738 ret = -ENOMEM;
3739 goto error_open;
3740 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003741
3742 out->usecase = USECASE_AUDIO_PLAYBACK_OFFLOAD;
3743 if (config->offload_info.channel_mask)
3744 out->channel_mask = config->offload_info.channel_mask;
3745 else if (config->channel_mask)
3746 out->channel_mask = config->channel_mask;
3747 out->format = config->offload_info.format;
3748 out->sample_rate = config->offload_info.sample_rate;
3749
3750 out->stream.set_callback = out_set_callback;
3751 out->stream.pause = out_pause;
3752 out->stream.resume = out_resume;
3753 out->stream.drain = out_drain;
3754 out->stream.flush = out_flush;
3755
3756 out->compr_config.codec->id =
3757 get_snd_codec_id(config->offload_info.format);
3758 out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
3759 out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
3760 out->compr_config.codec->sample_rate = config->offload_info.sample_rate;
3761 out->compr_config.codec->bit_rate =
3762 config->offload_info.bit_rate;
3763 out->compr_config.codec->ch_in =
3764 audio_channel_count_from_out_mask(config->channel_mask);
3765 out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
3766
3767 if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
3768 out->non_blocking = 1;
3769
3770 out->send_new_metadata = 1;
3771 create_offload_callback_thread(out);
3772 out->offload_state = OFFLOAD_STATE_IDLE;
3773
3774 ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
3775 __func__, config->offload_info.version,
3776 config->offload_info.bit_rate);
3777 } else if (out->flags & (AUDIO_OUTPUT_FLAG_DEEP_BUFFER)) {
3778 out->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01003779 out->config = pcm_device_deep_buffer.config;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003780 out->sample_rate = out->config.rate;
3781 ALOGV("%s: use AUDIO_PLAYBACK_DEEP_BUFFER",__func__);
3782 } else {
3783 out->usecase = USECASE_AUDIO_PLAYBACK;
3784 out->sample_rate = out->config.rate;
3785 }
3786
3787 if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
3788 if (adev->primary_output == NULL)
3789 adev->primary_output = out;
3790 else {
3791 ALOGE("%s: Primary output is already opened", __func__);
3792 ret = -EEXIST;
3793 goto error_open;
3794 }
3795 }
3796
3797 /* Check if this usecase is already existing */
3798 pthread_mutex_lock(&adev->lock);
3799 if (get_usecase_from_id(adev, out->usecase) != NULL) {
3800 ALOGE("%s: Usecase (%d) is already present", __func__, out->usecase);
3801 pthread_mutex_unlock(&adev->lock);
3802 ret = -EEXIST;
3803 goto error_open;
3804 }
3805 pthread_mutex_unlock(&adev->lock);
3806
3807 out->stream.common.get_sample_rate = out_get_sample_rate;
3808 out->stream.common.set_sample_rate = out_set_sample_rate;
3809 out->stream.common.get_buffer_size = out_get_buffer_size;
3810 out->stream.common.get_channels = out_get_channels;
3811 out->stream.common.get_format = out_get_format;
3812 out->stream.common.set_format = out_set_format;
3813 out->stream.common.standby = out_standby;
3814 out->stream.common.dump = out_dump;
3815 out->stream.common.set_parameters = out_set_parameters;
3816 out->stream.common.get_parameters = out_get_parameters;
3817 out->stream.common.add_audio_effect = out_add_audio_effect;
3818 out->stream.common.remove_audio_effect = out_remove_audio_effect;
3819 out->stream.get_latency = out_get_latency;
3820 out->stream.set_volume = out_set_volume;
3821 out->stream.write = out_write;
3822 out->stream.get_render_position = out_get_render_position;
3823 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
3824 out->stream.get_presentation_position = out_get_presentation_position;
3825
3826 out->standby = 1;
3827 /* out->muted = false; by calloc() */
3828 /* out->written = 0; by calloc() */
3829
3830 pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
3831 pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
3832 pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
3833
3834 config->format = out->stream.common.get_format(&out->stream.common);
3835 config->channel_mask = out->stream.common.get_channels(&out->stream.common);
3836 config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
3837
3838 out->is_fastmixer_affinity_set = false;
3839
3840 *stream_out = &out->stream;
3841 ALOGV("%s: exit", __func__);
3842 return 0;
3843
3844error_open:
3845 free(out);
3846 *stream_out = NULL;
Andreas Schneider56204f62017-01-31 08:17:32 +01003847error_config:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003848 ALOGV("%s: exit: ret %d", __func__, ret);
3849 return ret;
3850}
3851
3852static void adev_close_output_stream(struct audio_hw_device *dev,
3853 struct audio_stream_out *stream)
3854{
3855 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003856 (void)dev;
3857
3858 ALOGV("%s: enter", __func__);
3859 out_standby(&stream->common);
3860 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
3861 destroy_offload_callback_thread(out);
3862
3863 if (out->compr_config.codec != NULL)
3864 free(out->compr_config.codec);
3865 }
3866 pthread_cond_destroy(&out->cond);
3867 pthread_mutex_destroy(&out->lock);
3868 free(stream);
3869 ALOGV("%s: exit", __func__);
3870}
3871
3872static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
3873{
3874 struct audio_device *adev = (struct audio_device *)dev;
3875 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003876 char value[32];
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003877#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003878 int val;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003879#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003880 int ret;
3881
3882 ALOGV("%s: enter: %s", __func__, kvpairs);
3883
3884 parms = str_parms_create_str(kvpairs);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003885
Andreas Schneider05bc1882017-02-09 14:03:11 +01003886 /******************************************************
3887 *** BT SCO
3888 ******************************************************/
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003889 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
3890 if (ret >= 0) {
3891 /* When set to false, HAL should disable EC and NS
3892 * But it is currently not supported.
3893 */
3894 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
Andreas Schneider74ef3a12017-02-02 18:29:12 +01003895 adev->voice.bluetooth_nrec = true;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003896 else
Andreas Schneider74ef3a12017-02-02 18:29:12 +01003897 adev->voice.bluetooth_nrec = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003898 }
3899
Andreas Schneider05bc1882017-02-09 14:03:11 +01003900 ret = str_parms_get_str(parms,
3901 AUDIO_PARAMETER_KEY_BT_SCO_WB,
3902 value,
3903 sizeof(value));
3904 if (ret >= 0) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01003905 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) {
3906 adev->voice.bluetooth_wb = true;
Andreas Schneider05bc1882017-02-09 14:03:11 +01003907 } else {
3908 adev->voice.bluetooth_wb = false;
3909 }
3910 }
3911
Andreas Schneiderecd17ce2017-02-09 10:45:21 +01003912 ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
3913 if (ret >= 0) {
3914 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
3915 adev->screen_off = false;
3916 else
3917 adev->screen_off = true;
3918 }
3919
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01003920#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003921 ret = str_parms_get_int(parms, "rotation", &val);
3922 if (ret >= 0) {
3923 bool reverse_speakers = false;
3924 switch(val) {
3925 /* FIXME: note that the code below assumes that the speakers are in the correct placement
3926 relative to the user when the device is rotated 90deg from its default rotation. This
3927 assumption is device-specific, not platform-specific like this code. */
3928 case 270:
3929 reverse_speakers = true;
3930 break;
3931 case 0:
3932 case 90:
3933 case 180:
3934 break;
3935 default:
3936 ALOGE("%s: unexpected rotation of %d", __func__, val);
3937 }
3938 pthread_mutex_lock(&adev->lock);
3939 if (adev->speaker_lr_swap != reverse_speakers) {
3940 adev->speaker_lr_swap = reverse_speakers;
3941 /* only update the selected device if there is active pcm playback */
3942 struct audio_usecase *usecase;
3943 struct listnode *node;
3944 list_for_each(node, &adev->usecase_list) {
3945 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
3946 if (usecase->type == PCM_PLAYBACK) {
3947 select_devices(adev, usecase->id);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003948 break;
3949 }
3950 }
3951 }
3952 pthread_mutex_unlock(&adev->lock);
3953 }
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01003954#endif /* SWAP_SPEAKER_ON_SCREEN_ROTATION */
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003955
3956 str_parms_destroy(parms);
3957
3958 if (ret > 0)
3959 ret = 0;
3960
3961 ALOGV("%s: exit with code(%d)", __func__, ret);
3962 return ret;
3963}
3964
3965static char* adev_get_parameters(const struct audio_hw_device *dev,
3966 const char *keys)
3967{
3968 (void)dev;
3969 (void)keys;
3970
3971 return strdup("");
3972}
3973
3974static int adev_init_check(const struct audio_hw_device *dev)
3975{
3976 (void)dev;
3977
3978 return 0;
3979}
3980
3981static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
3982{
3983 int ret = 0;
3984 struct audio_device *adev = (struct audio_device *)dev;
3985 pthread_mutex_lock(&adev->lock);
3986 /* cache volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01003987 adev->voice.volume = volume;
3988 ret = set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003989 pthread_mutex_unlock(&adev->lock);
3990 return ret;
3991}
3992
3993static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
3994{
3995 (void)dev;
3996 (void)volume;
3997
3998 return -ENOSYS;
3999}
4000
4001static int adev_get_master_volume(struct audio_hw_device *dev,
4002 float *volume)
4003{
4004 (void)dev;
4005 (void)volume;
4006
4007 return -ENOSYS;
4008}
4009
4010static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
4011{
4012 (void)dev;
4013 (void)muted;
4014
4015 return -ENOSYS;
4016}
4017
4018static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
4019{
4020 (void)dev;
4021 (void)muted;
4022
4023 return -ENOSYS;
4024}
4025
4026static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
4027{
4028 struct audio_device *adev = (struct audio_device *)dev;
4029
4030 pthread_mutex_lock(&adev->lock);
4031 if (adev->mode != mode) {
4032 ALOGI("%s mode = %d", __func__, mode);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004033 if (amplifier_set_mode(mode) != 0) {
4034 ALOGE("Failed setting amplifier mode");
4035 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004036 adev->mode = mode;
Christopher N. Hesse6c0020c2017-11-17 20:41:11 +01004037
4038 if ((mode == AUDIO_MODE_NORMAL) && adev->voice.in_call) {
4039 stop_voice_call(adev);
4040 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004041 }
4042 pthread_mutex_unlock(&adev->lock);
4043 return 0;
4044}
4045
4046static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
4047{
4048 struct audio_device *adev = (struct audio_device *)dev;
4049 int err = 0;
4050
4051 pthread_mutex_lock(&adev->lock);
4052 adev->mic_mute = state;
4053
4054 if (adev->mode == AUDIO_MODE_IN_CALL) {
Andreas Schneider107a8482017-02-06 12:36:31 +01004055 set_voice_session_mic_mute(adev->voice.session, state);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004056 }
4057
4058 pthread_mutex_unlock(&adev->lock);
4059 return err;
4060}
4061
4062static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
4063{
4064 struct audio_device *adev = (struct audio_device *)dev;
4065
4066 *state = adev->mic_mute;
4067
4068 return 0;
4069}
4070
4071static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
4072 const struct audio_config *config)
4073{
4074 (void)dev;
4075
4076 /* NOTE: we default to built in mic which may cause a mismatch between what we
4077 * report here and the actual buffer size
4078 */
4079 return get_input_buffer_size(config->sample_rate,
4080 config->format,
4081 audio_channel_count_from_in_mask(config->channel_mask),
4082 PCM_CAPTURE /* usecase_type */,
4083 AUDIO_DEVICE_IN_BUILTIN_MIC);
4084}
4085
4086static int adev_open_input_stream(struct audio_hw_device *dev,
4087 audio_io_handle_t handle __unused,
4088 audio_devices_t devices,
4089 struct audio_config *config,
4090 struct audio_stream_in **stream_in,
4091 audio_input_flags_t flags,
4092 const char *address __unused,
4093 audio_source_t source)
4094{
4095 struct audio_device *adev = (struct audio_device *)dev;
4096 struct stream_in *in;
4097 struct pcm_device_profile *pcm_profile;
4098
4099 ALOGV("%s: enter", __func__);
4100
4101 *stream_in = NULL;
4102 if (check_input_parameters(config->sample_rate, config->format,
4103 audio_channel_count_from_in_mask(config->channel_mask)) != 0)
4104 return -EINVAL;
4105
stenkinevgeniy44335362018-05-07 18:00:13 +00004106 usecase_type_t usecase_type = flags & AUDIO_INPUT_FLAG_FAST ?
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004107 PCM_CAPTURE_LOW_LATENCY : PCM_CAPTURE;
4108 pcm_profile = get_pcm_device(usecase_type, devices);
4109 if (pcm_profile == NULL && usecase_type == PCM_CAPTURE_LOW_LATENCY) {
4110 // a low latency profile may not exist for that device, fall back
4111 // to regular capture. the MixerThread automatically changes
4112 // to non-fast capture based on the buffer size.
4113 flags &= ~AUDIO_INPUT_FLAG_FAST;
4114 usecase_type = PCM_CAPTURE;
4115 pcm_profile = get_pcm_device(usecase_type, devices);
4116 }
4117 if (pcm_profile == NULL)
4118 return -EINVAL;
4119
4120 in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
Andreas Schneider56204f62017-01-31 08:17:32 +01004121 if (in == NULL) {
4122 return -ENOMEM;
4123 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004124
4125 in->stream.common.get_sample_rate = in_get_sample_rate;
4126 in->stream.common.set_sample_rate = in_set_sample_rate;
4127 in->stream.common.get_buffer_size = in_get_buffer_size;
4128 in->stream.common.get_channels = in_get_channels;
4129 in->stream.common.get_format = in_get_format;
4130 in->stream.common.set_format = in_set_format;
4131 in->stream.common.standby = in_standby;
4132 in->stream.common.dump = in_dump;
4133 in->stream.common.set_parameters = in_set_parameters;
4134 in->stream.common.get_parameters = in_get_parameters;
4135 in->stream.common.add_audio_effect = in_add_audio_effect;
4136 in->stream.common.remove_audio_effect = in_remove_audio_effect;
4137 in->stream.set_gain = in_set_gain;
4138 in->stream.read = in_read;
4139 in->stream.get_input_frames_lost = in_get_input_frames_lost;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004140 in->stream.get_capture_position = in_get_capture_position;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004141
4142 in->devices = devices;
4143 in->source = source;
4144 in->dev = adev;
4145 in->standby = 1;
4146 in->main_channels = config->channel_mask;
4147 in->requested_rate = config->sample_rate;
4148 if (config->sample_rate != CAPTURE_DEFAULT_SAMPLING_RATE)
4149 flags = flags & ~AUDIO_INPUT_FLAG_FAST;
4150 in->input_flags = flags;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004151 // in->frames_read = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004152 /* HW codec is limited to default channels. No need to update with
4153 * requested channels */
4154 in->config = pcm_profile->config;
4155
4156 /* Update config params with the requested sample rate and channels */
stenkinevgeniy44335362018-05-07 18:00:13 +00004157 in->usecase = USECASE_AUDIO_CAPTURE;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004158 in->usecase_type = usecase_type;
4159
4160 pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
4161 pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL);
4162
4163 in->is_fastcapture_affinity_set = false;
4164
4165 *stream_in = &in->stream;
4166 ALOGV("%s: exit", __func__);
4167 return 0;
4168}
4169
4170static void adev_close_input_stream(struct audio_hw_device *dev,
4171 struct audio_stream_in *stream)
4172{
4173 struct audio_device *adev = (struct audio_device *)dev;
4174 struct stream_in *in = (struct stream_in*)stream;
4175 ALOGV("%s", __func__);
4176
4177 /* prevent concurrent out_set_parameters, or out_write from standby */
4178 pthread_mutex_lock(&adev->lock_inputs);
4179
Andreas Schneidercabe5e62017-01-30 10:57:06 +01004180 if (in->read_buf) {
4181 free(in->read_buf);
4182 in->read_buf = NULL;
4183 }
4184
4185 if (in->resampler) {
4186 release_resampler(in->resampler);
4187 in->resampler = NULL;
4188 }
4189
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004190#ifdef PREPROCESSING_ENABLED
4191 int i;
4192
4193 for (i=0; i<in->num_preprocessors; i++) {
4194 free(in->preprocessors[i].channel_configs);
4195 }
4196
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004197 if (in->proc_buf_in) {
4198 free(in->proc_buf_in);
4199 in->proc_buf_in = NULL;
4200 }
4201
4202 if (in->proc_buf_out) {
4203 free(in->proc_buf_out);
4204 in->proc_buf_out = NULL;
4205 }
4206
4207 if (in->ref_buf) {
4208 free(in->ref_buf);
4209 in->ref_buf = NULL;
4210 }
4211
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004212#endif
4213
4214 in_standby_l(in);
4215 free(stream);
4216
4217 pthread_mutex_unlock(&adev->lock_inputs);
4218
4219 return;
4220}
4221
4222static int adev_dump(const audio_hw_device_t *device, int fd)
4223{
4224 (void)device;
4225 (void)fd;
4226
4227 return 0;
4228}
4229
4230static int adev_close(hw_device_t *device)
4231{
4232 struct audio_device *adev = (struct audio_device *)device;
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004233 voice_session_deinit(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004234 audio_device_ref_count--;
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004235 if (audio_device_ref_count == 0) {
4236 if (amplifier_close() != 0) {
4237 ALOGE("Amplifier close failed");
4238 }
4239 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004240 free(adev->snd_dev_ref_cnt);
4241 free_mixer_list(adev);
4242 free(device);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004243
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004244 adev = NULL;
4245
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004246 return 0;
4247}
4248
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004249/* This returns true if the input parameter looks at all plausible as a low latency period size,
4250 * or false otherwise. A return value of true doesn't mean the value is guaranteed to work,
4251 * just that it _might_ work.
4252 */
4253static bool period_size_is_plausible_for_low_latency(int period_size)
4254{
4255 switch (period_size) {
4256 case 64:
4257 case 96:
4258 case 128:
4259 case 192:
4260 case 256:
4261 return true;
4262 default:
4263 return false;
4264 }
4265}
4266
4267static int adev_open(const hw_module_t *module, const char *name,
4268 hw_device_t **device)
4269{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004270 ALOGV("%s: enter", __func__);
4271 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
4272
Andreas Schneider56204f62017-01-31 08:17:32 +01004273 *device = NULL;
4274
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004275 adev = calloc(1, sizeof(struct audio_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01004276 if (adev == NULL) {
4277 return -ENOMEM;
4278 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004279
4280 adev->device.common.tag = HARDWARE_DEVICE_TAG;
4281 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
4282 adev->device.common.module = (struct hw_module_t *)module;
4283 adev->device.common.close = adev_close;
4284
4285 adev->device.init_check = adev_init_check;
4286 adev->device.set_voice_volume = adev_set_voice_volume;
4287 adev->device.set_master_volume = adev_set_master_volume;
4288 adev->device.get_master_volume = adev_get_master_volume;
4289 adev->device.set_master_mute = adev_set_master_mute;
4290 adev->device.get_master_mute = adev_get_master_mute;
4291 adev->device.set_mode = adev_set_mode;
4292 adev->device.set_mic_mute = adev_set_mic_mute;
4293 adev->device.get_mic_mute = adev_get_mic_mute;
4294 adev->device.set_parameters = adev_set_parameters;
4295 adev->device.get_parameters = adev_get_parameters;
4296 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
4297 adev->device.open_output_stream = adev_open_output_stream;
4298 adev->device.close_output_stream = adev_close_output_stream;
4299 adev->device.open_input_stream = adev_open_input_stream;
4300 adev->device.close_input_stream = adev_close_input_stream;
4301 adev->device.dump = adev_dump;
4302
4303 /* Set the default route before the PCM stream is opened */
4304 adev->mode = AUDIO_MODE_NORMAL;
4305 adev->active_input = NULL;
4306 adev->primary_output = NULL;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004307
4308 adev->voice.volume = 1.0f;
4309 adev->voice.bluetooth_nrec = true;
4310 adev->voice.in_call = false;
Christopher N. Hessee4a1c592018-01-16 18:33:38 +01004311 adev->voice.bluetooth_wb = false;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004312
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004313 /* adev->cur_hdmi_channels = 0; by calloc() */
4314 adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
Andreas Schneider56204f62017-01-31 08:17:32 +01004315 if (adev->snd_dev_ref_cnt == NULL) {
4316 free(adev);
4317 return -ENOMEM;
4318 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004319
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004320 adev->ns_in_voice_rec = false;
4321
4322 list_init(&adev->usecase_list);
4323
4324 if (mixer_init(adev) != 0) {
4325 free(adev->snd_dev_ref_cnt);
4326 free(adev);
4327 ALOGE("%s: Failed to init, aborting.", __func__);
4328 *device = NULL;
4329 return -EINVAL;
4330 }
4331
4332 if (access(OFFLOAD_FX_LIBRARY_PATH, R_OK) == 0) {
4333 adev->offload_fx_lib = dlopen(OFFLOAD_FX_LIBRARY_PATH, RTLD_NOW);
4334 if (adev->offload_fx_lib == NULL) {
4335 ALOGE("%s: DLOPEN failed for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4336 } else {
4337 ALOGV("%s: DLOPEN successful for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4338 adev->offload_fx_start_output =
4339 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4340 "visualizer_hal_start_output");
4341 adev->offload_fx_stop_output =
4342 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4343 "visualizer_hal_stop_output");
4344 }
4345 }
4346
Christopher N. Hesse696959d2017-02-02 20:49:55 +01004347 adev->voice.session = voice_session_init(adev);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004348 if (adev->voice.session == NULL) {
4349 ALOGE("%s: Failed to initialize voice session data", __func__);
4350
4351 free(adev->snd_dev_ref_cnt);
4352 free(adev);
4353
4354 *device = NULL;
4355 return -EINVAL;
4356 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004357
Christopher N. Hessec487bbe2018-07-12 13:51:43 +02004358 if (amplifier_open() != -ENOENT) {
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004359 ALOGE("Amplifier initialization failed");
4360 }
4361
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004362 *device = &adev->device.common;
4363
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004364 audio_device_ref_count++;
4365
4366 char value[PROPERTY_VALUE_MAX];
4367 if (property_get("audio_hal.period_size", value, NULL) > 0) {
4368 int trial = atoi(value);
4369 if (period_size_is_plausible_for_low_latency(trial)) {
4370
4371 pcm_device_playback.config.period_size = trial;
4372 pcm_device_playback.config.start_threshold =
4373 PLAYBACK_START_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4374 pcm_device_playback.config.stop_threshold =
4375 PLAYBACK_STOP_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4376
4377 pcm_device_capture_low_latency.config.period_size = trial;
4378 }
4379 }
4380
4381 ALOGV("%s: exit", __func__);
4382 return 0;
4383}
4384
4385static struct hw_module_methods_t hal_module_methods = {
4386 .open = adev_open,
4387};
4388
4389struct audio_module HAL_MODULE_INFO_SYM = {
4390 .common = {
4391 .tag = HARDWARE_MODULE_TAG,
4392 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
4393 .hal_api_version = HARDWARE_HAL_API_VERSION,
4394 .id = AUDIO_HARDWARE_MODULE_ID,
Christopher N. Hessec8502b92017-01-28 14:02:15 +01004395 .name = "Samsung Audio HAL",
4396 .author = "The LineageOS Project",
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004397 .methods = &hal_module_methods,
4398 },
4399};