blob: 8f83fb8e0cd5815328ee0edcbf5d885c5a4a905f [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) {
744 snd_device = SND_DEVICE_IN_VOICE_MIC;
745
746 if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
Fevax51bd12c2017-03-15 10:56:39 -0300747 if (voice_session_uses_wideband(adev->voice.session)) {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100748 snd_device = SND_DEVICE_IN_VOICE_BT_SCO_MIC_WB;
Fevax51bd12c2017-03-15 10:56:39 -0300749 } else {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100750 snd_device = SND_DEVICE_IN_VOICE_BT_SCO_MIC;
Fevax51bd12c2017-03-15 10:56:39 -0300751 }
Andreas Schneider05bc1882017-02-09 14:03:11 +0100752 } else if (voice_session_uses_twomic(adev->voice.session)) {
753 snd_device = SND_DEVICE_IN_VOICE_EARPIECE_MIC;
754 }
755 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100756 } else if (source == AUDIO_SOURCE_CAMCORDER) {
757 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
758 in_device & AUDIO_DEVICE_IN_BACK_MIC) {
759 snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
760 }
761 } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
762 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100763 if (snd_device == SND_DEVICE_NONE) {
764 snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
765 }
766 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
767 snd_device = SND_DEVICE_IN_VOICE_REC_HEADSET_MIC;
768 }
769 } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION || source == AUDIO_SOURCE_MIC) {
770 if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
771 in_device = AUDIO_DEVICE_IN_BACK_MIC;
772 if (active_input) {
773 if (active_input->enable_aec) {
774 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
775 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
776 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
777 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
778 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
779 } else {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100780 snd_device = SND_DEVICE_IN_EARPIECE_MIC_AEC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100781 }
782 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
783 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
784 }
785 }
786 /* TODO: set echo reference */
787 }
788 } else if (source == AUDIO_SOURCE_DEFAULT) {
789 goto exit;
790 }
791
792
793 if (snd_device != SND_DEVICE_NONE) {
794 goto exit;
795 }
796
797 if (in_device != AUDIO_DEVICE_NONE &&
798 !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
799 !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
800 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100801 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100802 } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
803 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
804 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
805 snd_device = SND_DEVICE_IN_HEADSET_MIC;
806 } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
807 snd_device = SND_DEVICE_IN_BT_SCO_MIC ;
808 } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
809 snd_device = SND_DEVICE_IN_HDMI_MIC;
810 } else {
811 ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100812 ALOGW("%s: Using default earpiece-mic", __func__);
813 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100814 }
815 } else {
816 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100817 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100818 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
819 snd_device = SND_DEVICE_IN_HEADSET_MIC;
820 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
821 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
822 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100823 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100824 } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
825 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
826 } else {
827 ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100828 ALOGW("%s: Using default earpiece-mic", __func__);
829 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100830 }
831 }
832exit:
833 ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
834 return snd_device;
835}
836
Andreas Schneider5a2f1002017-02-09 10:59:04 +0100837#if 0
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100838static int set_hdmi_channels(struct audio_device *adev, int channel_count)
839{
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100840 (void)adev;
841 (void)channel_count;
842 /* TODO */
843
844 return 0;
845}
846
847static int edid_get_max_channels(struct audio_device *adev)
848{
849 int max_channels = 2;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100850 (void)adev;
851
852 /* TODO */
853 return max_channels;
854}
Andreas Schneider5a2f1002017-02-09 10:59:04 +0100855#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100856
857/* Delay in Us */
858static int64_t render_latency(audio_usecase_t usecase)
859{
860 (void)usecase;
861 /* TODO */
862 return 0;
863}
864
865static int enable_snd_device(struct audio_device *adev,
866 struct audio_usecase *uc_info,
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100867 snd_device_t snd_device)
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100868{
869 struct mixer_card *mixer_card;
870 struct listnode *node;
871 const char *snd_device_name = get_snd_device_name(snd_device);
Andreas Schneider759368f2017-02-02 16:11:14 +0100872#ifdef DSP_POWEROFF_DELAY
873 struct timespec activation_time;
874 struct timespec elapsed_time;
875#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100876
877 if (snd_device_name == NULL)
878 return -EINVAL;
879
880 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES) {
881 ALOGV("Request to enable combo device: enable individual devices\n");
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100882 enable_snd_device(adev, uc_info, SND_DEVICE_OUT_SPEAKER);
883 enable_snd_device(adev, uc_info, SND_DEVICE_OUT_HEADPHONES);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100884 return 0;
885 }
886 adev->snd_dev_ref_cnt[snd_device]++;
887 if (adev->snd_dev_ref_cnt[snd_device] > 1) {
888 ALOGV("%s: snd_device(%d: %s) is already active",
889 __func__, snd_device, snd_device_name);
890 return 0;
891 }
892
893 ALOGV("%s: snd_device(%d: %s)", __func__,
894 snd_device, snd_device_name);
895
896 list_for_each(node, &uc_info->mixer_list) {
897 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]);
Andreas Schneider759368f2017-02-02 16:11:14 +0100898
899#ifdef DSP_POWEROFF_DELAY
900 clock_gettime(CLOCK_MONOTONIC, &activation_time);
901
Andreas Schneider58735a92017-02-13 16:48:17 +0100902 elapsed_time = time_spec_diff(activation_time,
903 mixer_card->dsp_poweroff_time);
Andreas Schneider759368f2017-02-02 16:11:14 +0100904 if (elapsed_time.tv_sec == 0) {
905 long elapsed_usec = elapsed_time.tv_nsec / 1000;
906
907 if (elapsed_usec < DSP_POWEROFF_DELAY) {
908 usleep(DSP_POWEROFF_DELAY - elapsed_usec);
909 }
910 }
Andreas Schneider759368f2017-02-02 16:11:14 +0100911#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +0200912
913 amplifier_enable_devices(snd_device, true);
914
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100915 audio_route_apply_and_update_path(mixer_card->audio_route, snd_device_name);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100916 }
917
918 return 0;
919}
920
Christopher N. Hesse757ac412017-01-28 14:42:48 +0100921int disable_snd_device(struct audio_device *adev,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100922 struct audio_usecase *uc_info,
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100923 snd_device_t snd_device)
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100924{
925 struct mixer_card *mixer_card;
926 struct listnode *node;
Christopher N. Hesse11ef2112018-02-02 23:19:42 +0100927 struct audio_usecase *out_uc_info = get_usecase_from_type(adev, PCM_PLAYBACK);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100928 const char *snd_device_name = get_snd_device_name(snd_device);
Christopher N. Hesse11ef2112018-02-02 23:19:42 +0100929 const char *out_snd_device_name = NULL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100930
931 if (snd_device_name == NULL)
932 return -EINVAL;
933
934 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES) {
935 ALOGV("Request to disable combo device: disable individual devices\n");
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100936 disable_snd_device(adev, uc_info, SND_DEVICE_OUT_SPEAKER);
937 disable_snd_device(adev, uc_info, SND_DEVICE_OUT_HEADPHONES);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100938 return 0;
939 }
940
941 if (adev->snd_dev_ref_cnt[snd_device] <= 0) {
942 ALOGE("%s: device ref cnt is already 0", __func__);
943 return -EINVAL;
944 }
945 adev->snd_dev_ref_cnt[snd_device]--;
946 if (adev->snd_dev_ref_cnt[snd_device] == 0) {
947 ALOGV("%s: snd_device(%d: %s)", __func__,
948 snd_device, snd_device_name);
949 list_for_each(node, &uc_info->mixer_list) {
950 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]);
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100951 audio_route_reset_and_update_path(mixer_card->audio_route, snd_device_name);
Christopher N. Hesse719630a2018-02-12 01:47:48 +0100952 if (snd_device > SND_DEVICE_IN_BEGIN && out_uc_info != NULL) {
Christopher N. Hesse11ef2112018-02-02 23:19:42 +0100953 /*
954 * Cycle the rx device to eliminate routing conflicts.
955 * This prevents issues when an input route shares mixer controls with an output
956 * route.
957 */
958 out_snd_device_name = get_snd_device_name(out_uc_info->out_snd_device);
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100959 audio_route_apply_and_update_path(mixer_card->audio_route, out_snd_device_name);
Andreas Schneider759368f2017-02-02 16:11:14 +0100960 }
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +0200961
962 amplifier_enable_devices(snd_device, false);
Andreas Schneider759368f2017-02-02 16:11:14 +0100963#ifdef DSP_POWEROFF_DELAY
964 clock_gettime(CLOCK_MONOTONIC, &(mixer_card->dsp_poweroff_time));
965#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100966 }
967 }
968 return 0;
969}
970
stenkinevgeniyb81e05f2018-05-08 12:02:35 +0000971static void check_and_route_usecases(struct audio_device *adev,
972 struct audio_usecase *uc_info,
973 usecase_type_t type,
974 snd_device_t snd_device)
975{
976 struct listnode *node;
977 struct audio_usecase *usecase;
978 bool switch_device[AUDIO_USECASE_MAX], need_switch = false;
979 snd_device_t usecase_snd_device = SND_DEVICE_NONE;
980 int i;
981
982 /*
983 * This function is to make sure that all the usecases that are active on
984 * the hardware codec backend are always routed to any one device that is
985 * handled by the hardware codec.
986 * For example, if low-latency and deep-buffer usecases are currently active
987 * on speaker and out_set_parameters(headset) is received on low-latency
988 * output, then we have to make sure deep-buffer is also switched to headset or
989 * if audio-record and voice-call usecases are currently
990 * active on speaker(rx) and speaker-mic (tx) and out_set_parameters(earpiece)
991 * is received for voice call then we have to make sure that audio-record
992 * usecase is also switched to earpiece i.e.
993 * because of the limitation that both the devices cannot be enabled
994 * at the same time as they share the same backend.
995 */
996 /* Disable all the usecases on the shared backend other than the
997 specified usecase */
998 for (i = 0; i < AUDIO_USECASE_MAX; i++)
999 switch_device[i] = false;
1000
1001 list_for_each(node, &adev->usecase_list) {
1002 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
1003 if (usecase->type != type || usecase == uc_info)
1004 continue;
1005 usecase_snd_device = (type == PCM_PLAYBACK) ? usecase->out_snd_device :
1006 usecase->in_snd_device;
1007 if (usecase_snd_device != snd_device) {
1008 ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..",
1009 __func__, use_case_table[usecase->id],
1010 get_snd_device_name(usecase_snd_device));
1011 switch_device[usecase->id] = true;
1012 need_switch = true;
1013 }
1014 }
1015 if (need_switch) {
1016 list_for_each(node, &adev->usecase_list) {
1017 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
1018 usecase_snd_device = (type == PCM_PLAYBACK) ? usecase->out_snd_device :
1019 usecase->in_snd_device;
1020 if (switch_device[usecase->id]) {
1021 disable_snd_device(adev, usecase, usecase_snd_device);
1022 enable_snd_device(adev, usecase, snd_device);
1023 if (type == PCM_PLAYBACK)
1024 usecase->out_snd_device = snd_device;
1025 else
1026 usecase->in_snd_device = snd_device;
1027 }
1028 }
1029 }
1030}
1031
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001032static int select_devices(struct audio_device *adev,
1033 audio_usecase_t uc_id)
1034{
1035 snd_device_t out_snd_device = SND_DEVICE_NONE;
1036 snd_device_t in_snd_device = SND_DEVICE_NONE;
1037 struct audio_usecase *usecase = NULL;
1038 struct audio_usecase *vc_usecase = NULL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001039 struct stream_in *active_input = NULL;
1040 struct stream_out *active_out;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001041
1042 ALOGV("%s: usecase(%d)", __func__, uc_id);
1043
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001044 usecase = get_usecase_from_type(adev, PCM_CAPTURE|VOICE_CALL);
1045 if (usecase != NULL) {
1046 active_input = (struct stream_in *)usecase->stream;
1047 }
1048
1049 usecase = get_usecase_from_id(adev, uc_id);
1050 if (usecase == NULL) {
1051 ALOGE("%s: Could not find the usecase(%d)", __func__, uc_id);
1052 return -EINVAL;
1053 }
1054 active_out = (struct stream_out *)usecase->stream;
1055
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001056
1057 /*
1058 * If the voice call is active, use the sound devices of voice call usecase
1059 * so that it would not result any device switch. All the usecases will
1060 * be switched to new device when select_devices() is called for voice call
1061 * usecase.
1062 */
1063 if (usecase->type != VOICE_CALL && adev->voice.in_call) {
1064 vc_usecase = get_usecase_from_id(adev, USECASE_VOICE_CALL);
1065 if (vc_usecase == NULL) {
1066 ALOGE("%s: Could not find the voice call usecase", __func__);
1067 } else {
Christopher N. Hesse77880a22017-11-17 20:27:50 +01001068 ALOGV("%s: in call, reusing devices (rx: %s, tx: %s)", __func__,
1069 get_snd_device_display_name(vc_usecase->out_snd_device),
1070 get_snd_device_display_name(vc_usecase->in_snd_device));
1071 usecase->devices = vc_usecase->devices;
1072 return 0;
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001073 }
1074 }
1075
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001076 if (usecase->type == VOICE_CALL) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001077 usecase->devices = active_out->devices;
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001078 prepare_voice_session(adev->voice.session, active_out->devices);
1079 out_snd_device = get_output_snd_device(adev, active_out->devices);
1080 in_snd_device = get_input_snd_device(adev, active_out->devices);
1081 } else if (usecase->type == PCM_PLAYBACK) {
1082 usecase->devices = active_out->devices;
1083 in_snd_device = SND_DEVICE_NONE;
1084 if (out_snd_device == SND_DEVICE_NONE) {
1085 out_snd_device = get_output_snd_device(adev, active_out->devices);
1086 if (active_out == adev->primary_output &&
1087 active_input &&
1088 active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
1089 select_devices(adev, active_input->usecase);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001090 }
1091 }
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001092 } else if (usecase->type == PCM_CAPTURE) {
1093 usecase->devices = ((struct stream_in *)usecase->stream)->devices;
1094 out_snd_device = SND_DEVICE_NONE;
1095 if (in_snd_device == SND_DEVICE_NONE) {
1096 if (active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
1097 adev->primary_output && !adev->primary_output->standby) {
1098 in_snd_device = get_input_snd_device(adev, adev->primary_output->devices);
1099 } else {
1100 in_snd_device = get_input_snd_device(adev, AUDIO_DEVICE_NONE);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001101 }
1102 }
1103 }
1104
1105 if (out_snd_device == usecase->out_snd_device &&
1106 in_snd_device == usecase->in_snd_device) {
1107 return 0;
1108 }
1109
1110 ALOGV("%s: out_snd_device(%d: %s) in_snd_device(%d: %s)", __func__,
1111 out_snd_device, get_snd_device_display_name(out_snd_device),
1112 in_snd_device, get_snd_device_display_name(in_snd_device));
1113
1114
1115 /* Disable current sound devices */
1116 if (usecase->out_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001117 disable_snd_device(adev, usecase, usecase->out_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001118 }
1119
1120 if (usecase->in_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001121 disable_snd_device(adev, usecase, usecase->in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001122 }
1123
1124 /* Enable new sound devices */
1125 if (out_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse696959d2017-02-02 20:49:55 +01001126 /* We need to update the audio path if we switch the out devices */
1127 if (adev->voice.in_call) {
1128 set_voice_session_audio_path(adev->voice.session);
1129 }
1130
stenkinevgeniyb81e05f2018-05-08 12:02:35 +00001131 check_and_route_usecases(adev, usecase, PCM_PLAYBACK, out_snd_device);
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001132 enable_snd_device(adev, usecase, out_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001133 }
1134
1135 if (in_snd_device != SND_DEVICE_NONE) {
stenkinevgeniyb81e05f2018-05-08 12:02:35 +00001136 check_and_route_usecases(adev, usecase, PCM_CAPTURE, in_snd_device);
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001137 enable_snd_device(adev, usecase, in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001138 }
1139
1140 usecase->in_snd_device = in_snd_device;
1141 usecase->out_snd_device = out_snd_device;
1142
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02001143 /* Rely on amplifier_set_devices to distinguish between in/out devices */
1144 amplifier_set_input_devices(in_snd_device);
1145 amplifier_set_output_devices(out_snd_device);
1146
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001147 return 0;
1148}
1149
1150
1151static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames);
1152static int do_in_standby_l(struct stream_in *in);
1153
1154#ifdef PREPROCESSING_ENABLED
1155static void get_capture_reference_delay(struct stream_in *in,
1156 size_t frames __unused,
1157 struct echo_reference_buffer *buffer)
1158{
1159 ALOGVV("%s: enter:)", __func__);
1160
1161 /* read frames available in kernel driver buffer */
1162 unsigned int kernel_frames;
1163 struct timespec tstamp;
1164 long buf_delay;
1165 long kernel_delay;
1166 long delay_ns;
1167 struct pcm_device *ref_device;
1168 long rsmp_delay = 0;
1169
1170 ref_device = node_to_item(list_tail(&in->pcm_dev_list),
1171 struct pcm_device, stream_list_node);
1172
1173 if (pcm_get_htimestamp(ref_device->pcm, &kernel_frames, &tstamp) < 0) {
1174 buffer->time_stamp.tv_sec = 0;
1175 buffer->time_stamp.tv_nsec = 0;
1176 buffer->delay_ns = 0;
1177 ALOGW("read get_capture_reference_delay(): pcm_htimestamp error");
1178 return;
1179 }
1180
1181 /* adjust render time stamp with delay added by current driver buffer.
1182 * Add the duration of current frame as we want the render time of the last
1183 * sample being written. */
1184
1185 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / ref_device->pcm_profile->config.rate);
1186
1187 buffer->time_stamp = tstamp;
1188 buffer->delay_ns = kernel_delay;
1189
1190 ALOGVV("get_capture_reference_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5d],"
1191 " delay_ns: [%d] , frames:[%zd]",
1192 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns, frames);
1193}
1194
1195static void get_capture_delay(struct stream_in *in,
1196 size_t frames __unused,
1197 struct echo_reference_buffer *buffer)
1198{
1199 ALOGVV("%s: enter:)", __func__);
1200 /* read frames available in kernel driver buffer */
1201 unsigned int kernel_frames;
1202 struct timespec tstamp;
1203 long buf_delay;
1204 long rsmp_delay;
1205 long kernel_delay;
1206 long delay_ns;
1207 struct pcm_device *pcm_device;
1208
1209 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1210 struct pcm_device, stream_list_node);
1211
1212 if (pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &tstamp) < 0) {
1213 buffer->time_stamp.tv_sec = 0;
1214 buffer->time_stamp.tv_nsec = 0;
1215 buffer->delay_ns = 0;
1216 ALOGW("read get_capture_delay(): pcm_htimestamp error");
1217 return;
1218 }
1219
1220 /* read frames available in audio HAL input buffer
1221 * add number of frames being read as we want the capture time of first sample
1222 * in current buffer */
1223 /* frames in in->read_buf are at driver sampling rate while frames in in->proc_buf are
1224 * at requested sampling rate */
1225 buf_delay = (long)(((int64_t)(in->read_buf_frames) * 1000000000) / in->config.rate +
1226 ((int64_t)(in->proc_buf_frames) * 1000000000) / in->requested_rate );
1227
1228 /* add delay introduced by resampler */
1229 rsmp_delay = 0;
1230 if (in->resampler) {
1231 rsmp_delay = in->resampler->delay_ns(in->resampler);
1232 }
1233
1234 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / in->config.rate);
1235
1236 delay_ns = kernel_delay + buf_delay + rsmp_delay;
1237
1238 buffer->time_stamp = tstamp;
1239 buffer->delay_ns = delay_ns;
1240 ALOGVV("get_capture_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames:[%5d],"
1241 " delay_ns: [%d], kernel_delay:[%ld], buf_delay:[%ld], rsmp_delay:[%ld], "
1242 "in->read_buf_frames:[%zd], in->proc_buf_frames:[%zd], frames:[%zd]",
1243 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames,
1244 buffer->delay_ns, kernel_delay, buf_delay, rsmp_delay,
1245 in->read_buf_frames, in->proc_buf_frames, frames);
1246}
1247
1248static int32_t update_echo_reference(struct stream_in *in, size_t frames)
1249{
1250 ALOGVV("%s: enter:), in->config.channels(%d)", __func__,in->config.channels);
1251 struct echo_reference_buffer b;
1252 b.delay_ns = 0;
1253 struct pcm_device *pcm_device;
1254
1255 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1256 struct pcm_device, stream_list_node);
1257
1258 ALOGVV("update_echo_reference, in->config.channels(%d), frames = [%zd], in->ref_buf_frames = [%zd], "
1259 "b.frame_count = [%zd]",
1260 in->config.channels, frames, in->ref_buf_frames, frames - in->ref_buf_frames);
1261 if (in->ref_buf_frames < frames) {
1262 if (in->ref_buf_size < frames) {
1263 in->ref_buf_size = frames;
1264 in->ref_buf = (int16_t *)realloc(in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1265 ALOG_ASSERT((in->ref_buf != NULL),
1266 "update_echo_reference() failed to reallocate ref_buf");
1267 ALOGVV("update_echo_reference(): ref_buf %p extended to %d bytes",
1268 in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1269 }
1270 b.frame_count = frames - in->ref_buf_frames;
1271 b.raw = (void *)(in->ref_buf + in->ref_buf_frames * in->config.channels);
1272
1273 get_capture_delay(in, frames, &b);
1274
1275 if (in->echo_reference->read(in->echo_reference, &b) == 0)
1276 {
1277 in->ref_buf_frames += b.frame_count;
1278 ALOGVV("update_echo_reference(): in->ref_buf_frames:[%zd], "
1279 "in->ref_buf_size:[%zd], frames:[%zd], b.frame_count:[%zd]",
1280 in->ref_buf_frames, in->ref_buf_size, frames, b.frame_count);
1281 }
1282 } else
1283 ALOGW("update_echo_reference(): NOT enough frames to read ref buffer");
1284 return b.delay_ns;
1285}
1286
1287static int set_preprocessor_param(effect_handle_t handle,
1288 effect_param_t *param)
1289{
1290 uint32_t size = sizeof(int);
1291 uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
1292 param->vsize;
1293
1294 int status = (*handle)->command(handle,
1295 EFFECT_CMD_SET_PARAM,
1296 sizeof (effect_param_t) + psize,
1297 param,
1298 &size,
1299 &param->status);
1300 if (status == 0)
1301 status = param->status;
1302
1303 return status;
1304}
1305
1306static int set_preprocessor_echo_delay(effect_handle_t handle,
1307 int32_t delay_us)
1308{
1309 struct {
1310 effect_param_t param;
1311 uint32_t data_0;
1312 int32_t data_1;
1313 } buf;
1314 memset(&buf, 0, sizeof(buf));
1315
1316 buf.param.psize = sizeof(uint32_t);
1317 buf.param.vsize = sizeof(uint32_t);
1318 buf.data_0 = AEC_PARAM_ECHO_DELAY;
1319 buf.data_1 = delay_us;
1320
1321 return set_preprocessor_param(handle, &buf.param);
1322}
1323
1324static void push_echo_reference(struct stream_in *in, size_t frames)
1325{
1326 ALOGVV("%s: enter:)", __func__);
1327 /* read frames from echo reference buffer and update echo delay
1328 * in->ref_buf_frames is updated with frames available in in->ref_buf */
1329
1330 int32_t delay_us = update_echo_reference(in, frames)/1000;
1331 int32_t size_in_bytes = 0;
1332 int i;
1333 audio_buffer_t buf;
1334
1335 if (in->ref_buf_frames < frames)
1336 frames = in->ref_buf_frames;
1337
1338 buf.frameCount = frames;
1339 buf.raw = in->ref_buf;
1340
1341 for (i = 0; i < in->num_preprocessors; i++) {
1342 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1343 continue;
1344 ALOGVV("%s: effect_itfe)->process_reverse() BEGIN i=(%d) ", __func__, i);
1345 (*in->preprocessors[i].effect_itfe)->process_reverse(in->preprocessors[i].effect_itfe,
1346 &buf,
1347 NULL);
1348 ALOGVV("%s: effect_itfe)->process_reverse() END i=(%d) ", __func__, i);
1349 set_preprocessor_echo_delay(in->preprocessors[i].effect_itfe, delay_us);
1350 }
1351
1352 in->ref_buf_frames -= buf.frameCount;
1353 ALOGVV("%s: in->ref_buf_frames(%zd), in->config.channels(%d) ",
1354 __func__, in->ref_buf_frames, in->config.channels);
1355 if (in->ref_buf_frames) {
1356 memcpy(in->ref_buf,
1357 in->ref_buf + buf.frameCount * in->config.channels,
1358 in->ref_buf_frames * in->config.channels * sizeof(int16_t));
1359 }
1360}
1361
1362static void put_echo_reference(struct audio_device *adev,
1363 struct echo_reference_itfe *reference)
1364{
1365 ALOGV("%s: enter:)", __func__);
1366 int32_t prev_generation = adev->echo_reference_generation;
1367 struct stream_out *out = adev->primary_output;
1368
1369 if (adev->echo_reference != NULL &&
1370 reference == adev->echo_reference) {
1371 /* echo reference is taken from the low latency output stream used
1372 * for voice use cases */
1373 adev->echo_reference = NULL;
1374 android_atomic_inc(&adev->echo_reference_generation);
1375 if (out != NULL && out->usecase == USECASE_AUDIO_PLAYBACK) {
1376 // if the primary output is in standby or did not pick the echo reference yet
1377 // we can safely get rid of it here.
1378 // otherwise, out_write() or out_standby() will detect the change in echo reference
1379 // generation and release the echo reference owned by the stream.
1380 if ((out->echo_reference_generation != prev_generation) || out->standby)
1381 release_echo_reference(reference);
1382 } else {
1383 release_echo_reference(reference);
1384 }
1385 ALOGV("release_echo_reference");
1386 }
1387}
1388
1389static struct echo_reference_itfe *get_echo_reference(struct audio_device *adev,
1390 audio_format_t format __unused,
1391 uint32_t channel_count,
1392 uint32_t sampling_rate)
1393{
1394 ALOGV("%s: enter:)", __func__);
1395 put_echo_reference(adev, adev->echo_reference);
1396 /* echo reference is taken from the low latency output stream used
1397 * for voice use cases */
1398 if (adev->primary_output!= NULL && adev->primary_output->usecase == USECASE_AUDIO_PLAYBACK &&
1399 !adev->primary_output->standby) {
1400 struct audio_stream *stream =
1401 &adev->primary_output->stream.common;
1402 uint32_t wr_channel_count = audio_channel_count_from_out_mask(stream->get_channels(stream));
1403 uint32_t wr_sampling_rate = stream->get_sample_rate(stream);
1404 ALOGV("Calling create_echo_reference");
1405 int status = create_echo_reference(AUDIO_FORMAT_PCM_16_BIT,
1406 channel_count,
1407 sampling_rate,
1408 AUDIO_FORMAT_PCM_16_BIT,
1409 wr_channel_count,
1410 wr_sampling_rate,
1411 &adev->echo_reference);
1412 if (status == 0)
1413 android_atomic_inc(&adev->echo_reference_generation);
1414 }
1415 return adev->echo_reference;
1416}
1417
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001418static int get_playback_delay(struct stream_out *out,
1419 size_t frames,
1420 struct echo_reference_buffer *buffer)
1421{
1422 unsigned int kernel_frames;
1423 int status;
1424 int primary_pcm = 0;
1425 struct pcm_device *pcm_device;
1426
1427 pcm_device = node_to_item(list_head(&out->pcm_dev_list),
1428 struct pcm_device, stream_list_node);
1429
1430 status = pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &buffer->time_stamp);
1431 if (status < 0) {
1432 buffer->time_stamp.tv_sec = 0;
1433 buffer->time_stamp.tv_nsec = 0;
1434 buffer->delay_ns = 0;
1435 ALOGV("get_playback_delay(): pcm_get_htimestamp error,"
1436 "setting playbackTimestamp to 0");
1437 return status;
1438 }
1439
1440 kernel_frames = pcm_get_buffer_size(pcm_device->pcm) - kernel_frames;
1441
1442 /* adjust render time stamp with delay added by current driver buffer.
1443 * Add the duration of current frame as we want the render time of the last
1444 * sample being written. */
1445 buffer->delay_ns = (long)(((int64_t)(kernel_frames + frames)* 1000000000)/
1446 out->config.rate);
1447 ALOGVV("get_playback_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5u], delay_ns: [%d],",
1448 buffer->time_stamp.tv_sec, buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns);
1449
1450 return 0;
1451}
1452
1453#define GET_COMMAND_STATUS(status, fct_status, cmd_status) \
1454 do { \
1455 if (fct_status != 0) \
1456 status = fct_status; \
1457 else if (cmd_status != 0) \
1458 status = cmd_status; \
1459 } while(0)
1460
1461static int in_configure_reverse(struct stream_in *in)
1462{
1463 int32_t cmd_status;
1464 uint32_t size = sizeof(int);
1465 effect_config_t config;
1466 int32_t status = 0;
1467 int32_t fct_status = 0;
1468 int i;
1469 ALOGV("%s: enter: in->num_preprocessors(%d)", __func__, in->num_preprocessors);
1470 if (in->num_preprocessors > 0) {
1471 config.inputCfg.channels = in->main_channels;
1472 config.outputCfg.channels = in->main_channels;
1473 config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1474 config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1475 config.inputCfg.samplingRate = in->requested_rate;
1476 config.outputCfg.samplingRate = in->requested_rate;
1477 config.inputCfg.mask =
1478 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1479 config.outputCfg.mask =
1480 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1481
1482 for (i = 0; i < in->num_preprocessors; i++)
1483 {
1484 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1485 continue;
1486 fct_status = (*(in->preprocessors[i].effect_itfe))->command(
1487 in->preprocessors[i].effect_itfe,
1488 EFFECT_CMD_SET_CONFIG_REVERSE,
1489 sizeof(effect_config_t),
1490 &config,
1491 &size,
1492 &cmd_status);
1493 ALOGV("%s: calling EFFECT_CMD_SET_CONFIG_REVERSE",__func__);
1494 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1495 }
1496 }
1497 return status;
1498}
1499
1500#define MAX_NUM_CHANNEL_CONFIGS 10
1501
1502static void in_read_audio_effect_channel_configs(struct stream_in *in __unused,
1503 struct effect_info_s *effect_info)
1504{
1505 /* size and format of the cmd are defined in hardware/audio_effect.h */
1506 effect_handle_t effect = effect_info->effect_itfe;
1507 uint32_t cmd_size = 2 * sizeof(uint32_t);
1508 uint32_t cmd[] = { EFFECT_FEATURE_AUX_CHANNELS, MAX_NUM_CHANNEL_CONFIGS };
1509 /* reply = status + number of configs (n) + n x channel_config_t */
1510 uint32_t reply_size =
1511 2 * sizeof(uint32_t) + (MAX_NUM_CHANNEL_CONFIGS * sizeof(channel_config_t));
1512 int32_t reply[reply_size];
1513 int32_t cmd_status;
1514
1515 ALOG_ASSERT((effect_info->num_channel_configs == 0),
1516 "in_read_audio_effect_channel_configs() num_channel_configs not cleared");
1517 ALOG_ASSERT((effect_info->channel_configs == NULL),
1518 "in_read_audio_effect_channel_configs() channel_configs not cleared");
1519
1520 /* if this command is not supported, then the effect is supposed to return -EINVAL.
1521 * This error will be interpreted as if the effect supports the main_channels but does not
1522 * support any aux_channels */
1523 cmd_status = (*effect)->command(effect,
1524 EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS,
1525 cmd_size,
1526 (void*)&cmd,
1527 &reply_size,
1528 (void*)&reply);
1529
1530 if (cmd_status != 0) {
1531 ALOGV("in_read_audio_effect_channel_configs(): "
1532 "fx->command returned %d", cmd_status);
1533 return;
1534 }
1535
1536 if (reply[0] != 0) {
1537 ALOGW("in_read_audio_effect_channel_configs(): "
1538 "command EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS error %d num configs %d",
1539 reply[0], (reply[0] == -ENOMEM) ? reply[1] : MAX_NUM_CHANNEL_CONFIGS);
1540 return;
1541 }
1542
1543 /* the feature is not supported */
1544 ALOGV("in_read_audio_effect_channel_configs()(): "
1545 "Feature supported and adding %d channel configs to the list", reply[1]);
1546 effect_info->num_channel_configs = reply[1];
1547 effect_info->channel_configs =
1548 (channel_config_t *) malloc(sizeof(channel_config_t) * reply[1]); /* n x configs */
1549 memcpy(effect_info->channel_configs, (reply + 2), sizeof(channel_config_t) * reply[1]);
1550}
1551
1552
1553#define NUM_IN_AUX_CNL_CONFIGS 2
1554static const channel_config_t in_aux_cnl_configs[NUM_IN_AUX_CNL_CONFIGS] = {
1555 { AUDIO_CHANNEL_IN_FRONT , AUDIO_CHANNEL_IN_BACK},
1556 { AUDIO_CHANNEL_IN_STEREO , AUDIO_CHANNEL_IN_RIGHT}
1557};
1558static uint32_t in_get_aux_channels(struct stream_in *in)
1559{
1560 int i;
1561 channel_config_t new_chcfg = {0, 0};
1562
1563 if (in->num_preprocessors == 0)
1564 return 0;
1565
1566 /* do not enable dual mic configurations when capturing from other microphones than
1567 * main or sub */
1568 if (!(in->devices & (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_BACK_MIC)))
1569 return 0;
1570
1571 /* retain most complex aux channels configuration compatible with requested main channels and
1572 * supported by audio driver and all pre processors */
1573 for (i = 0; i < NUM_IN_AUX_CNL_CONFIGS; i++) {
1574 const channel_config_t *cur_chcfg = &in_aux_cnl_configs[i];
1575 if (cur_chcfg->main_channels == in->main_channels) {
1576 size_t match_cnt;
1577 size_t idx_preproc;
1578 for (idx_preproc = 0, match_cnt = 0;
1579 /* no need to continue if at least one preprocessor doesn't match */
1580 idx_preproc < (size_t)in->num_preprocessors && match_cnt == idx_preproc;
1581 idx_preproc++) {
1582 struct effect_info_s *effect_info = &in->preprocessors[idx_preproc];
1583 size_t idx_chcfg;
1584
1585 for (idx_chcfg = 0; idx_chcfg < effect_info->num_channel_configs; idx_chcfg++) {
1586 if (memcmp(effect_info->channel_configs + idx_chcfg,
1587 cur_chcfg,
1588 sizeof(channel_config_t)) == 0) {
1589 match_cnt++;
1590 break;
1591 }
1592 }
1593 }
1594 /* if all preprocessors match, we have a candidate */
1595 if (match_cnt == (size_t)in->num_preprocessors) {
1596 /* retain most complex aux channels configuration */
1597 if (audio_channel_count_from_in_mask(cur_chcfg->aux_channels) > audio_channel_count_from_in_mask(new_chcfg.aux_channels)) {
1598 new_chcfg = *cur_chcfg;
1599 }
1600 }
1601 }
1602 }
1603
1604 ALOGV("in_get_aux_channels(): return %04x", new_chcfg.aux_channels);
1605
1606 return new_chcfg.aux_channels;
1607}
1608
1609static int in_configure_effect_channels(effect_handle_t effect,
1610 channel_config_t *channel_config)
1611{
1612 int status = 0;
1613 int fct_status;
1614 int32_t cmd_status;
1615 uint32_t reply_size;
1616 effect_config_t config;
1617 uint32_t cmd[(sizeof(uint32_t) + sizeof(channel_config_t) - 1) / sizeof(uint32_t) + 1];
1618
1619 ALOGV("in_configure_effect_channels(): configure effect with channels: [%04x][%04x]",
1620 channel_config->main_channels,
1621 channel_config->aux_channels);
1622
1623 config.inputCfg.mask = EFFECT_CONFIG_CHANNELS;
1624 config.outputCfg.mask = EFFECT_CONFIG_CHANNELS;
1625 reply_size = sizeof(effect_config_t);
1626 fct_status = (*effect)->command(effect,
1627 EFFECT_CMD_GET_CONFIG,
1628 0,
1629 NULL,
1630 &reply_size,
1631 &config);
1632 if (fct_status != 0) {
1633 ALOGE("in_configure_effect_channels(): EFFECT_CMD_GET_CONFIG failed");
1634 return fct_status;
1635 }
1636
1637 config.inputCfg.channels = channel_config->main_channels | channel_config->aux_channels;
1638 config.outputCfg.channels = config.inputCfg.channels;
1639 reply_size = sizeof(uint32_t);
1640 fct_status = (*effect)->command(effect,
1641 EFFECT_CMD_SET_CONFIG,
1642 sizeof(effect_config_t),
1643 &config,
1644 &reply_size,
1645 &cmd_status);
1646 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1647
1648 cmd[0] = EFFECT_FEATURE_AUX_CHANNELS;
1649 memcpy(cmd + 1, channel_config, sizeof(channel_config_t));
1650 reply_size = sizeof(uint32_t);
1651 fct_status = (*effect)->command(effect,
1652 EFFECT_CMD_SET_FEATURE_CONFIG,
1653 sizeof(cmd), //sizeof(uint32_t) + sizeof(channel_config_t),
1654 cmd,
1655 &reply_size,
1656 &cmd_status);
1657 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1658
1659 /* some implementations need to be re-enabled after a config change */
1660 reply_size = sizeof(uint32_t);
1661 fct_status = (*effect)->command(effect,
1662 EFFECT_CMD_ENABLE,
1663 0,
1664 NULL,
1665 &reply_size,
1666 &cmd_status);
1667 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1668
1669 return status;
1670}
1671
1672static int in_reconfigure_channels(struct stream_in *in,
1673 effect_handle_t effect,
1674 channel_config_t *channel_config,
1675 bool config_changed) {
1676
1677 int status = 0;
1678
1679 ALOGV("in_reconfigure_channels(): config_changed %d effect %p",
1680 config_changed, effect);
1681
1682 /* if config changed, reconfigure all previously added effects */
1683 if (config_changed) {
1684 int i;
1685 ALOGV("%s: config_changed (%d)", __func__, config_changed);
1686 for (i = 0; i < in->num_preprocessors; i++)
1687 {
1688 int cur_status = in_configure_effect_channels(in->preprocessors[i].effect_itfe,
1689 channel_config);
1690 ALOGV("%s: in_configure_effect_channels i=(%d), [main_channel,aux_channel]=[%d|%d], status=%d",
1691 __func__, i, channel_config->main_channels, channel_config->aux_channels, cur_status);
1692 if (cur_status != 0) {
1693 ALOGV("in_reconfigure_channels(): error %d configuring effect "
1694 "%d with channels: [%04x][%04x]",
1695 cur_status,
1696 i,
1697 channel_config->main_channels,
1698 channel_config->aux_channels);
1699 status = cur_status;
1700 }
1701 }
1702 } else if (effect != NULL && channel_config->aux_channels) {
1703 /* if aux channels config did not change but aux channels are present,
1704 * we still need to configure the effect being added */
1705 status = in_configure_effect_channels(effect, channel_config);
1706 }
1707 return status;
1708}
1709
1710static void in_update_aux_channels(struct stream_in *in,
1711 effect_handle_t effect)
1712{
1713 uint32_t aux_channels;
1714 channel_config_t channel_config;
1715 int status;
1716
1717 aux_channels = in_get_aux_channels(in);
1718
1719 channel_config.main_channels = in->main_channels;
1720 channel_config.aux_channels = aux_channels;
1721 status = in_reconfigure_channels(in,
1722 effect,
1723 &channel_config,
1724 (aux_channels != in->aux_channels));
1725
1726 if (status != 0) {
1727 ALOGV("in_update_aux_channels(): in_reconfigure_channels error %d", status);
1728 /* resetting aux channels configuration */
1729 aux_channels = 0;
1730 channel_config.aux_channels = 0;
1731 in_reconfigure_channels(in, effect, &channel_config, true);
1732 }
1733 ALOGV("%s: aux_channels=%d, in->aux_channels_changed=%d", __func__, aux_channels, in->aux_channels_changed);
1734 if (in->aux_channels != aux_channels) {
1735 in->aux_channels_changed = true;
1736 in->aux_channels = aux_channels;
1737 do_in_standby_l(in);
1738 }
1739}
1740#endif
1741
1742/* This function reads PCM data and:
1743 * - resample if needed
1744 * - process if pre-processors are attached
1745 * - discard unwanted channels
1746 */
1747static ssize_t read_and_process_frames(struct stream_in *in, void* buffer, ssize_t frames)
1748{
1749 ssize_t frames_wr = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001750 size_t src_channels = in->config.channels;
1751 size_t dst_channels = audio_channel_count_from_in_mask(in->main_channels);
1752 int i;
1753 void *proc_buf_out;
1754 struct pcm_device *pcm_device;
1755 bool has_additional_channels = (dst_channels != src_channels) ? true : false;
1756#ifdef PREPROCESSING_ENABLED
Andreas Schneider5a2f1002017-02-09 10:59:04 +01001757 audio_buffer_t in_buf;
1758 audio_buffer_t out_buf;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001759 bool has_processing = (in->num_preprocessors != 0) ? true : false;
1760#endif
1761
1762 /* Additional channels might be added on top of main_channels:
1763 * - aux_channels (by processing effects)
1764 * - extra channels due to HW limitations
1765 * In case of additional channels, we cannot work inplace
1766 */
1767 if (has_additional_channels)
1768 proc_buf_out = in->proc_buf_out;
1769 else
1770 proc_buf_out = buffer;
1771
1772 if (list_empty(&in->pcm_dev_list)) {
1773 ALOGE("%s: pcm device list empty", __func__);
1774 return -EINVAL;
1775 }
1776
1777 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1778 struct pcm_device, stream_list_node);
1779
1780#ifdef PREPROCESSING_ENABLED
1781 if (has_processing) {
1782 /* since all the processing below is done in frames and using the config.channels
1783 * as the number of channels, no changes is required in case aux_channels are present */
1784 while (frames_wr < frames) {
1785 /* first reload enough frames at the end of process input buffer */
1786 if (in->proc_buf_frames < (size_t)frames) {
1787 ssize_t frames_rd;
1788 if (in->proc_buf_size < (size_t)frames) {
1789 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1790 in->proc_buf_size = (size_t)frames;
1791 in->proc_buf_in = (int16_t *)realloc(in->proc_buf_in, size_in_bytes);
1792 ALOG_ASSERT((in->proc_buf_in != NULL),
1793 "process_frames() failed to reallocate proc_buf_in");
1794 if (has_additional_channels) {
1795 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1796 ALOG_ASSERT((in->proc_buf_out != NULL),
1797 "process_frames() failed to reallocate proc_buf_out");
1798 proc_buf_out = in->proc_buf_out;
1799 }
1800 }
1801 frames_rd = read_frames(in,
1802 in->proc_buf_in +
1803 in->proc_buf_frames * in->config.channels,
1804 frames - in->proc_buf_frames);
1805 if (frames_rd < 0) {
1806 /* Return error code */
1807 frames_wr = frames_rd;
1808 break;
1809 }
1810 in->proc_buf_frames += frames_rd;
1811 }
1812
1813 if (in->echo_reference != NULL) {
1814 push_echo_reference(in, in->proc_buf_frames);
1815 }
1816
1817 /* in_buf.frameCount and out_buf.frameCount indicate respectively
1818 * the maximum number of frames to be consumed and produced by process() */
1819 in_buf.frameCount = in->proc_buf_frames;
1820 in_buf.s16 = in->proc_buf_in;
1821 out_buf.frameCount = frames - frames_wr;
1822 out_buf.s16 = (int16_t *)proc_buf_out + frames_wr * in->config.channels;
1823
1824 /* FIXME: this works because of current pre processing library implementation that
1825 * does the actual process only when the last enabled effect process is called.
1826 * The generic solution is to have an output buffer for each effect and pass it as
1827 * input to the next.
1828 */
1829 for (i = 0; i < in->num_preprocessors; i++) {
1830 (*in->preprocessors[i].effect_itfe)->process(in->preprocessors[i].effect_itfe,
1831 &in_buf,
1832 &out_buf);
1833 }
1834
1835 /* process() has updated the number of frames consumed and produced in
1836 * in_buf.frameCount and out_buf.frameCount respectively
1837 * move remaining frames to the beginning of in->proc_buf_in */
1838 in->proc_buf_frames -= in_buf.frameCount;
1839
1840 if (in->proc_buf_frames) {
1841 memcpy(in->proc_buf_in,
1842 in->proc_buf_in + in_buf.frameCount * in->config.channels,
1843 in->proc_buf_frames * in->config.channels * sizeof(int16_t));
1844 }
1845
1846 /* if not enough frames were passed to process(), read more and retry. */
1847 if (out_buf.frameCount == 0) {
1848 ALOGW("No frames produced by preproc");
1849 continue;
1850 }
1851
1852 if ((frames_wr + (ssize_t)out_buf.frameCount) <= frames) {
1853 frames_wr += out_buf.frameCount;
1854 } else {
1855 /* The effect does not comply to the API. In theory, we should never end up here! */
1856 ALOGE("preprocessing produced too many frames: %d + %zd > %d !",
1857 (unsigned int)frames_wr, out_buf.frameCount, (unsigned int)frames);
1858 frames_wr = frames;
1859 }
1860 }
1861 }
1862 else
1863#endif //PREPROCESSING_ENABLED
1864 {
1865 /* No processing effects attached */
1866 if (has_additional_channels) {
1867 /* With additional channels, we cannot use original buffer */
1868 if (in->proc_buf_size < (size_t)frames) {
1869 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1870 in->proc_buf_size = (size_t)frames;
1871 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1872 ALOG_ASSERT((in->proc_buf_out != NULL),
1873 "process_frames() failed to reallocate proc_buf_out");
1874 proc_buf_out = in->proc_buf_out;
1875 }
1876 }
1877 frames_wr = read_frames(in, proc_buf_out, frames);
1878 }
1879
1880 /* Remove all additional channels that have been added on top of main_channels:
1881 * - aux_channels
1882 * - extra channels from HW due to HW limitations
1883 * Assumption is made that the channels are interleaved and that the main
1884 * channels are first. */
1885
1886 if (has_additional_channels)
1887 {
1888 int16_t* src_buffer = (int16_t *)proc_buf_out;
1889 int16_t* dst_buffer = (int16_t *)buffer;
1890
1891 if (dst_channels == 1) {
1892 for (i = frames_wr; i > 0; i--)
1893 {
1894 *dst_buffer++ = *src_buffer;
1895 src_buffer += src_channels;
1896 }
1897 } else {
1898 for (i = frames_wr; i > 0; i--)
1899 {
1900 memcpy(dst_buffer, src_buffer, dst_channels*sizeof(int16_t));
1901 dst_buffer += dst_channels;
1902 src_buffer += src_channels;
1903 }
1904 }
1905 }
1906
1907 return frames_wr;
1908}
1909
1910static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
1911 struct resampler_buffer* buffer)
1912{
1913 struct stream_in *in;
1914 struct pcm_device *pcm_device;
1915
1916 if (buffer_provider == NULL || buffer == NULL)
1917 return -EINVAL;
1918
1919 in = (struct stream_in *)((char *)buffer_provider -
1920 offsetof(struct stream_in, buf_provider));
1921
1922 if (list_empty(&in->pcm_dev_list)) {
1923 buffer->raw = NULL;
1924 buffer->frame_count = 0;
1925 in->read_status = -ENODEV;
1926 return -ENODEV;
1927 }
1928
1929 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1930 struct pcm_device, stream_list_node);
1931
1932 if (in->read_buf_frames == 0) {
1933 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, in->config.period_size);
1934 if (in->read_buf_size < in->config.period_size) {
1935 in->read_buf_size = in->config.period_size;
1936 in->read_buf = (int16_t *) realloc(in->read_buf, size_in_bytes);
1937 ALOG_ASSERT((in->read_buf != NULL),
1938 "get_next_buffer() failed to reallocate read_buf");
1939 }
1940
1941 in->read_status = pcm_read(pcm_device->pcm, (void*)in->read_buf, size_in_bytes);
1942
1943 if (in->read_status != 0) {
1944 ALOGE("get_next_buffer() pcm_read error %d", in->read_status);
1945 buffer->raw = NULL;
1946 buffer->frame_count = 0;
1947 return in->read_status;
1948 }
1949 in->read_buf_frames = in->config.period_size;
1950
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001951 }
1952
1953 buffer->frame_count = (buffer->frame_count > in->read_buf_frames) ?
1954 in->read_buf_frames : buffer->frame_count;
1955 buffer->i16 = in->read_buf + (in->config.period_size - in->read_buf_frames) *
1956 in->config.channels;
1957 return in->read_status;
1958}
1959
1960static void release_buffer(struct resampler_buffer_provider *buffer_provider,
1961 struct resampler_buffer* buffer)
1962{
1963 struct stream_in *in;
1964
1965 if (buffer_provider == NULL || buffer == NULL)
1966 return;
1967
1968 in = (struct stream_in *)((char *)buffer_provider -
1969 offsetof(struct stream_in, buf_provider));
1970
1971 in->read_buf_frames -= buffer->frame_count;
1972}
1973
1974/* read_frames() reads frames from kernel driver, down samples to capture rate
1975 * if necessary and output the number of frames requested to the buffer specified */
1976static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames)
1977{
1978 ssize_t frames_wr = 0;
1979
1980 struct pcm_device *pcm_device;
1981
1982 if (list_empty(&in->pcm_dev_list)) {
1983 ALOGE("%s: pcm device list empty", __func__);
1984 return -EINVAL;
1985 }
1986
1987 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1988 struct pcm_device, stream_list_node);
1989
1990 while (frames_wr < frames) {
1991 size_t frames_rd = frames - frames_wr;
1992 ALOGVV("%s: frames_rd: %zd, frames_wr: %zd, in->config.channels: %d",
1993 __func__,frames_rd,frames_wr,in->config.channels);
1994 if (in->resampler != NULL) {
1995 in->resampler->resample_from_provider(in->resampler,
1996 (int16_t *)((char *)buffer +
1997 pcm_frames_to_bytes(pcm_device->pcm, frames_wr)),
1998 &frames_rd);
1999 } else {
2000 struct resampler_buffer buf = {
Andreas Schneiderb7f32122017-01-31 08:18:34 +01002001 .raw = NULL,
2002 .frame_count = frames_rd,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002003 };
2004 get_next_buffer(&in->buf_provider, &buf);
2005 if (buf.raw != NULL) {
2006 memcpy((char *)buffer +
2007 pcm_frames_to_bytes(pcm_device->pcm, frames_wr),
2008 buf.raw,
2009 pcm_frames_to_bytes(pcm_device->pcm, buf.frame_count));
2010 frames_rd = buf.frame_count;
2011 }
2012 release_buffer(&in->buf_provider, &buf);
2013 }
2014 /* in->read_status is updated by getNextBuffer() also called by
2015 * in->resampler->resample_from_provider() */
2016 if (in->read_status != 0)
2017 return in->read_status;
2018
2019 frames_wr += frames_rd;
2020 }
2021 return frames_wr;
2022}
2023
2024static int in_release_pcm_devices(struct stream_in *in)
2025{
2026 struct pcm_device *pcm_device;
2027 struct listnode *node;
2028 struct listnode *next;
2029
2030 list_for_each_safe(node, next, &in->pcm_dev_list) {
2031 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2032 list_remove(node);
2033 free(pcm_device);
2034 }
2035
2036 return 0;
2037}
2038
2039static int stop_input_stream(struct stream_in *in)
2040{
2041 struct audio_usecase *uc_info;
2042 struct audio_device *adev = in->dev;
2043
2044 adev->active_input = NULL;
2045 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2046 in->usecase, use_case_table[in->usecase]);
2047 uc_info = get_usecase_from_id(adev, in->usecase);
2048 if (uc_info == NULL) {
2049 ALOGE("%s: Could not find the usecase (%d) in the list",
2050 __func__, in->usecase);
2051 return -EINVAL;
2052 }
2053
2054 /* Disable the tx device */
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002055 disable_snd_device(adev, uc_info, uc_info->in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002056
2057 list_remove(&uc_info->adev_list_node);
2058 free(uc_info);
2059
2060 if (list_empty(&in->pcm_dev_list)) {
2061 ALOGE("%s: pcm device list empty", __func__);
2062 return -EINVAL;
2063 }
2064
2065 in_release_pcm_devices(in);
2066 list_init(&in->pcm_dev_list);
2067
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002068 ALOGV("%s: exit", __func__);
2069 return 0;
2070}
2071
2072static int start_input_stream(struct stream_in *in)
2073{
2074 /* Enable output device and stream routing controls */
2075 int ret = 0;
2076 bool recreate_resampler = false;
2077 struct audio_usecase *uc_info;
2078 struct audio_device *adev = in->dev;
2079 struct pcm_device_profile *pcm_profile;
2080 struct pcm_device *pcm_device;
2081
2082 ALOGV("%s: enter: usecase(%d)", __func__, in->usecase);
2083 adev->active_input = in;
2084 pcm_profile = get_pcm_device(in->usecase_type, in->devices);
2085 if (pcm_profile == NULL) {
2086 ALOGE("%s: Could not find PCM device id for the usecase(%d)",
2087 __func__, in->usecase);
2088 ret = -EINVAL;
2089 goto error_config;
2090 }
2091
2092 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002093 if (uc_info == NULL) {
2094 ret = -ENOMEM;
2095 goto error_config;
2096 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002097 uc_info->id = in->usecase;
2098 uc_info->type = PCM_CAPTURE;
2099 uc_info->stream = (struct audio_stream *)in;
2100 uc_info->devices = in->devices;
2101 uc_info->in_snd_device = SND_DEVICE_NONE;
2102 uc_info->out_snd_device = SND_DEVICE_NONE;
2103
2104 pcm_device = (struct pcm_device *)calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01002105 if (pcm_device == NULL) {
2106 free(uc_info);
2107 ret = -ENOMEM;
2108 goto error_config;
2109 }
2110
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002111 pcm_device->pcm_profile = pcm_profile;
2112 list_init(&in->pcm_dev_list);
2113 list_add_tail(&in->pcm_dev_list, &pcm_device->stream_list_node);
2114
2115 list_init(&uc_info->mixer_list);
2116 list_add_tail(&uc_info->mixer_list,
2117 &adev_get_mixer_for_card(adev,
2118 pcm_device->pcm_profile->card)->uc_list_node[uc_info->id]);
2119
2120 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2121
2122 select_devices(adev, in->usecase);
2123
2124 /* Config should be updated as profile can be changed between different calls
2125 * to this function:
2126 * - Trigger resampler creation
2127 * - Config needs to be updated */
2128 if (in->config.rate != pcm_profile->config.rate) {
2129 recreate_resampler = true;
2130 }
2131 in->config = pcm_profile->config;
2132
2133#ifdef PREPROCESSING_ENABLED
2134 if (in->aux_channels_changed) {
2135 in->config.channels = audio_channel_count_from_in_mask(in->main_channels | in->aux_channels);
2136 recreate_resampler = true;
2137 }
2138#endif
2139
2140 if (in->requested_rate != in->config.rate) {
2141 recreate_resampler = true;
2142 }
2143
2144 if (recreate_resampler) {
2145 if (in->resampler) {
2146 release_resampler(in->resampler);
2147 in->resampler = NULL;
2148 }
2149 in->buf_provider.get_next_buffer = get_next_buffer;
2150 in->buf_provider.release_buffer = release_buffer;
2151 ret = create_resampler(in->config.rate,
2152 in->requested_rate,
2153 in->config.channels,
2154 RESAMPLER_QUALITY_DEFAULT,
2155 &in->buf_provider,
2156 &in->resampler);
2157 }
2158
2159#ifdef PREPROCESSING_ENABLED
2160 if (in->enable_aec && in->echo_reference == NULL) {
2161 in->echo_reference = get_echo_reference(adev,
2162 AUDIO_FORMAT_PCM_16_BIT,
2163 audio_channel_count_from_in_mask(in->main_channels),
2164 in->requested_rate
2165 );
2166 }
2167
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002168#endif
2169
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002170 if (in->dev->voice.in_call) {
2171 ALOGV("%s: in_call, not handling PCMs", __func__);
2172 goto skip_pcm_handling;
2173 }
2174
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002175 /* Open the PCM device.
2176 * The HW is limited to support only the default pcm_profile settings.
2177 * As such a change in aux_channels will not have an effect.
2178 */
2179 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d, smp rate %d format %d, \
2180 period_size %d", __func__, pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
2181 pcm_device->pcm_profile->config.channels,pcm_device->pcm_profile->config.rate,
2182 pcm_device->pcm_profile->config.format, pcm_device->pcm_profile->config.period_size);
2183
stenkinevgeniy44335362018-05-07 18:00:13 +00002184 pcm_device->pcm = pcm_open(pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002185 PCM_IN | PCM_MONOTONIC, &pcm_device->pcm_profile->config);
2186
stenkinevgeniy44335362018-05-07 18:00:13 +00002187 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2188 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2189 pcm_close(pcm_device->pcm);
2190 pcm_device->pcm = NULL;
2191 ret = -EIO;
2192 goto error_open;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002193 }
2194
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002195skip_pcm_handling:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002196 /* force read and proc buffer reallocation in case of frame size or
2197 * channel count change */
2198 in->proc_buf_frames = 0;
2199 in->proc_buf_size = 0;
2200 in->read_buf_size = 0;
2201 in->read_buf_frames = 0;
2202
2203 /* if no supported sample rate is available, use the resampler */
2204 if (in->resampler) {
2205 in->resampler->reset(in->resampler);
2206 }
2207
2208 ALOGV("%s: exit", __func__);
2209 return ret;
2210
2211error_open:
2212 if (in->resampler) {
2213 release_resampler(in->resampler);
2214 in->resampler = NULL;
2215 }
2216 stop_input_stream(in);
2217
2218error_config:
2219 ALOGV("%s: exit: status(%d)", __func__, ret);
2220 adev->active_input = NULL;
2221 return ret;
2222}
2223
2224void lock_input_stream(struct stream_in *in)
2225{
2226 pthread_mutex_lock(&in->pre_lock);
2227 pthread_mutex_lock(&in->lock);
2228 pthread_mutex_unlock(&in->pre_lock);
2229}
2230
2231void lock_output_stream(struct stream_out *out)
2232{
2233 pthread_mutex_lock(&out->pre_lock);
2234 pthread_mutex_lock(&out->lock);
2235 pthread_mutex_unlock(&out->pre_lock);
2236}
2237
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002238static int uc_release_pcm_devices(struct audio_usecase *usecase)
2239{
2240 struct stream_out *out = (struct stream_out *)usecase->stream;
2241 struct pcm_device *pcm_device;
2242 struct listnode *node;
2243 struct listnode *next;
2244
2245 list_for_each_safe(node, next, &out->pcm_dev_list) {
2246 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2247 list_remove(node);
2248 free(pcm_device);
2249 }
2250 list_init(&usecase->mixer_list);
2251
2252 return 0;
2253}
2254
2255static int uc_select_pcm_devices(struct audio_usecase *usecase)
2256
2257{
2258 struct stream_out *out = (struct stream_out *)usecase->stream;
2259 struct pcm_device *pcm_device;
2260 struct pcm_device_profile *pcm_profile;
2261 struct mixer_card *mixer_card;
2262 audio_devices_t devices = usecase->devices;
2263
2264 list_init(&usecase->mixer_list);
2265 list_init(&out->pcm_dev_list);
2266
2267 while ((pcm_profile = get_pcm_device(usecase->type, devices)) != NULL) {
2268 pcm_device = calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01002269 if (pcm_device == NULL) {
2270 return -ENOMEM;
2271 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002272 pcm_device->pcm_profile = pcm_profile;
2273 list_add_tail(&out->pcm_dev_list, &pcm_device->stream_list_node);
2274 mixer_card = uc_get_mixer_for_card(usecase, pcm_profile->card);
2275 if (mixer_card == NULL) {
2276 mixer_card = adev_get_mixer_for_card(out->dev, pcm_profile->card);
2277 list_add_tail(&usecase->mixer_list, &mixer_card->uc_list_node[usecase->id]);
2278 }
2279 devices &= ~pcm_profile->devices;
2280 }
2281
2282 return 0;
2283}
2284
2285static int out_close_pcm_devices(struct stream_out *out)
2286{
2287 struct pcm_device *pcm_device;
2288 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002289
2290 list_for_each(node, &out->pcm_dev_list) {
2291 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002292 if (pcm_device->pcm) {
2293 pcm_close(pcm_device->pcm);
2294 pcm_device->pcm = NULL;
2295 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002296 }
2297
2298 return 0;
2299}
2300
2301static int out_open_pcm_devices(struct stream_out *out)
2302{
2303 struct pcm_device *pcm_device;
2304 struct listnode *node;
2305 int ret = 0;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002306 int pcm_device_card;
2307 int pcm_device_id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002308
2309 list_for_each(node, &out->pcm_dev_list) {
2310 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002311 pcm_device_card = pcm_device->pcm_profile->card;
2312 pcm_device_id = pcm_device->pcm_profile->id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002313
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002314 if (out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
2315 pcm_device_id = pcm_device_deep_buffer.id;
2316
2317 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
2318 __func__, pcm_device_card, pcm_device_id);
2319
2320 pcm_device->pcm = pcm_open(pcm_device_card, pcm_device_id,
stenkinevgeniy2ef158a2018-05-08 06:52:05 +00002321 PCM_OUT | PCM_MONOTONIC, &out->config);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002322
2323 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2324 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2325 pcm_device->pcm = NULL;
2326 ret = -EIO;
2327 goto error_open;
2328 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002329 }
2330 return ret;
2331
2332error_open:
2333 out_close_pcm_devices(out);
2334 return ret;
2335}
2336
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002337int disable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002338{
2339 struct audio_device *adev = out->dev;
2340 struct audio_usecase *uc_info;
2341
2342 uc_info = get_usecase_from_id(adev, out->usecase);
2343 if (uc_info == NULL) {
2344 ALOGE("%s: Could not find the usecase (%d) in the list",
2345 __func__, out->usecase);
2346 return -EINVAL;
2347 }
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002348 disable_snd_device(adev, uc_info, uc_info->out_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002349 uc_release_pcm_devices(uc_info);
2350 list_remove(&uc_info->adev_list_node);
2351 free(uc_info);
2352
2353 return 0;
2354}
2355
Andreas Schneider56204f62017-01-31 08:17:32 +01002356int enable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002357{
2358 struct audio_device *adev = out->dev;
2359 struct audio_usecase *uc_info;
2360
2361 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002362 if (uc_info == NULL) {
2363 return -ENOMEM;
2364 }
2365
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002366 uc_info->id = out->usecase;
2367 uc_info->type = PCM_PLAYBACK;
2368 uc_info->stream = (struct audio_stream *)out;
2369 uc_info->devices = out->devices;
2370 uc_info->in_snd_device = SND_DEVICE_NONE;
2371 uc_info->out_snd_device = SND_DEVICE_NONE;
2372 uc_select_pcm_devices(uc_info);
2373
2374 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2375 select_devices(adev, out->usecase);
Andreas Schneider56204f62017-01-31 08:17:32 +01002376
2377 return 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002378}
2379
2380static int stop_output_stream(struct stream_out *out)
2381{
2382 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002383 bool do_disable = true;
2384
2385 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2386 out->usecase, use_case_table[out->usecase]);
2387
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002388 stop_output_offload_stream(out, &do_disable);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002389
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002390 if (do_disable)
2391 ret = disable_output_path_l(out);
2392
2393 ALOGV("%s: exit: status(%d)", __func__, ret);
2394 return ret;
2395}
2396
2397static int start_output_stream(struct stream_out *out)
2398{
2399 int ret = 0;
2400 struct audio_device *adev = out->dev;
2401
2402 ALOGV("%s: enter: usecase(%d: %s) devices(%#x) channels(%d)",
2403 __func__, out->usecase, use_case_table[out->usecase], out->devices, out->config.channels);
2404
Andreas Schneider56204f62017-01-31 08:17:32 +01002405 ret = enable_output_path_l(out);
2406 if (ret != 0) {
2407 goto error_config;
2408 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002409
2410 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2411 out->compr = NULL;
2412 ret = out_open_pcm_devices(out);
2413 if (ret != 0)
2414 goto error_open;
2415#ifdef PREPROCESSING_ENABLED
2416 out->echo_reference = NULL;
2417 out->echo_reference_generation = adev->echo_reference_generation;
2418 if (adev->echo_reference != NULL)
2419 out->echo_reference = adev->echo_reference;
2420#endif
2421 } else {
2422 out->compr = compress_open(COMPRESS_CARD, COMPRESS_DEVICE,
2423 COMPRESS_IN, &out->compr_config);
2424 if (out->compr && !is_compress_ready(out->compr)) {
2425 ALOGE("%s: %s", __func__, compress_get_error(out->compr));
2426 compress_close(out->compr);
2427 out->compr = NULL;
2428 ret = -EIO;
2429 goto error_open;
2430 }
2431 if (out->offload_callback)
2432 compress_nonblock(out->compr, out->non_blocking);
2433
2434 if (adev->offload_fx_start_output != NULL)
2435 adev->offload_fx_start_output(out->handle);
2436 }
2437 ALOGV("%s: exit", __func__);
2438 return 0;
2439error_open:
2440 stop_output_stream(out);
2441error_config:
2442 return ret;
2443}
2444
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002445int stop_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002446{
2447 struct audio_usecase *uc_info;
2448
2449 ALOGV("%s: enter", __func__);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002450 adev->voice.in_call = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002451
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002452 stop_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002453
2454 uc_info = get_usecase_from_id(adev, USECASE_VOICE_CALL);
2455 if (uc_info == NULL) {
2456 ALOGE("%s: Could not find the usecase (%d) in the list",
2457 __func__, USECASE_VOICE_CALL);
2458 return -EINVAL;
2459 }
2460
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002461 disable_snd_device(adev, uc_info, uc_info->out_snd_device);
2462 disable_snd_device(adev, uc_info, uc_info->in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002463
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002464 list_remove(&uc_info->adev_list_node);
2465 free(uc_info);
2466
2467 ALOGV("%s: exit", __func__);
2468 return 0;
2469}
2470
2471/* always called with adev lock held */
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002472int start_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002473{
2474 struct audio_usecase *uc_info;
Andreas Schneider56204f62017-01-31 08:17:32 +01002475 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002476
2477 ALOGV("%s: enter", __func__);
2478
2479 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002480 if (uc_info == NULL) {
2481 ret = -ENOMEM;
2482 goto exit;
2483 }
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002484 /*
2485 * We set this early so that functions called after this is being set
2486 * can use it. It is e.g. needed in select_devices() to inform the RILD
2487 * which output device we use.
2488 */
2489 adev->voice.in_call = true;
Andreas Schneider56204f62017-01-31 08:17:32 +01002490
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002491 uc_info->id = USECASE_VOICE_CALL;
2492 uc_info->type = VOICE_CALL;
2493 uc_info->stream = (struct audio_stream *)adev->primary_output;
2494 uc_info->devices = adev->primary_output->devices;
2495 uc_info->in_snd_device = SND_DEVICE_NONE;
2496 uc_info->out_snd_device = SND_DEVICE_NONE;
2497
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002498 list_init(&uc_info->mixer_list);
2499 list_add_tail(&uc_info->mixer_list,
2500 &adev_get_mixer_for_card(adev, SOUND_CARD)->uc_list_node[uc_info->id]);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002501
2502 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2503
2504 select_devices(adev, USECASE_VOICE_CALL);
2505
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002506 start_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002507
2508 /* set cached volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002509 set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002510
Andreas Schneider56204f62017-01-31 08:17:32 +01002511exit:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002512 ALOGV("%s: exit", __func__);
Andreas Schneider56204f62017-01-31 08:17:32 +01002513 return ret;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002514}
2515
2516static int check_input_parameters(uint32_t sample_rate,
2517 audio_format_t format,
2518 int channel_count)
2519{
2520 if (format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL;
2521
2522 if ((channel_count < 1) || (channel_count > 2)) return -EINVAL;
2523
2524 switch (sample_rate) {
2525 case 8000:
2526 case 11025:
2527 case 12000:
2528 case 16000:
2529 case 22050:
2530 case 24000:
2531 case 32000:
2532 case 44100:
2533 case 48000:
2534 break;
2535 default:
2536 return -EINVAL;
2537 }
2538
2539 return 0;
2540}
2541
2542static size_t get_input_buffer_size(uint32_t sample_rate,
2543 audio_format_t format,
2544 int channel_count,
2545 usecase_type_t usecase_type,
2546 audio_devices_t devices)
2547{
2548 size_t size = 0;
2549 struct pcm_device_profile *pcm_profile;
2550
2551 if (check_input_parameters(sample_rate, format, channel_count) != 0)
2552 return 0;
2553
2554 pcm_profile = get_pcm_device(usecase_type, devices);
2555 if (pcm_profile == NULL)
2556 return 0;
2557
2558 /*
2559 * take resampling into account and return the closest majoring
2560 * multiple of 16 frames, as audioflinger expects audio buffers to
2561 * be a multiple of 16 frames
2562 */
2563 size = (pcm_profile->config.period_size * sample_rate) / pcm_profile->config.rate;
2564 size = ((size + 15) / 16) * 16;
2565
2566 return (size * channel_count * audio_bytes_per_sample(format));
2567
2568}
2569
2570static uint32_t out_get_sample_rate(const struct audio_stream *stream)
2571{
2572 struct stream_out *out = (struct stream_out *)stream;
2573
2574 return out->sample_rate;
2575}
2576
2577static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
2578{
2579 (void)stream;
2580 (void)rate;
2581 return -ENOSYS;
2582}
2583
2584static size_t out_get_buffer_size(const struct audio_stream *stream)
2585{
2586 struct stream_out *out = (struct stream_out *)stream;
2587
2588 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2589 return out->compr_config.fragment_size;
2590 }
2591
2592 return out->config.period_size *
2593 audio_stream_out_frame_size((const struct audio_stream_out *)stream);
2594}
2595
2596static uint32_t out_get_channels(const struct audio_stream *stream)
2597{
2598 struct stream_out *out = (struct stream_out *)stream;
2599
2600 return out->channel_mask;
2601}
2602
2603static audio_format_t out_get_format(const struct audio_stream *stream)
2604{
2605 struct stream_out *out = (struct stream_out *)stream;
2606
2607 return out->format;
2608}
2609
2610static int out_set_format(struct audio_stream *stream, audio_format_t format)
2611{
2612 (void)stream;
2613 (void)format;
2614 return -ENOSYS;
2615}
2616
2617static int do_out_standby_l(struct stream_out *out)
2618{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002619 int status = 0;
2620
2621 out->standby = true;
2622 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2623 out_close_pcm_devices(out);
2624#ifdef PREPROCESSING_ENABLED
2625 /* stop writing to echo reference */
2626 if (out->echo_reference != NULL) {
2627 out->echo_reference->write(out->echo_reference, NULL);
2628 if (out->echo_reference_generation != adev->echo_reference_generation) {
2629 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
2630 release_echo_reference(out->echo_reference);
2631 out->echo_reference_generation = adev->echo_reference_generation;
2632 }
2633 out->echo_reference = NULL;
2634 }
2635#endif
2636 } else {
2637 stop_compressed_output_l(out);
2638 out->gapless_mdata.encoder_delay = 0;
2639 out->gapless_mdata.encoder_padding = 0;
2640 if (out->compr != NULL) {
2641 compress_close(out->compr);
2642 out->compr = NULL;
2643 }
2644 }
2645 status = stop_output_stream(out);
2646
2647 return status;
2648}
2649
2650static int out_standby(struct audio_stream *stream)
2651{
2652 struct stream_out *out = (struct stream_out *)stream;
2653 struct audio_device *adev = out->dev;
2654
2655 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2656 out->usecase, use_case_table[out->usecase]);
2657 lock_output_stream(out);
2658 if (!out->standby) {
2659 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002660 amplifier_output_stream_standby((struct audio_stream_out *) stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002661 do_out_standby_l(out);
2662 pthread_mutex_unlock(&adev->lock);
2663 }
2664 pthread_mutex_unlock(&out->lock);
2665 ALOGV("%s: exit", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01002666
2667 // out->last_write_time_us = 0; unnecessary as a stale write time has same effect
2668
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002669 return 0;
2670}
2671
2672static int out_dump(const struct audio_stream *stream, int fd)
2673{
2674 (void)stream;
2675 (void)fd;
2676
2677 return 0;
2678}
2679
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002680static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
2681{
2682 struct stream_out *out = (struct stream_out *)stream;
2683 struct audio_device *adev = out->dev;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002684 struct listnode *node;
2685 struct str_parms *parms;
2686 char value[32];
2687 int ret, val = 0;
2688 struct audio_usecase *uc_info;
2689 bool do_standby = false;
2690 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002691#ifdef PREPROCESSING_ENABLED
2692 struct stream_in *in = NULL; /* if non-NULL, then force input to standby */
2693#endif
2694
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002695 ALOGV("%s: enter: usecase(%d: %s) kvpairs: %s out->devices(%#x) "
2696 "adev->mode(%#x)",
2697 __func__, out->usecase, use_case_table[out->usecase], kvpairs,
2698 out->devices, adev->mode);
2699
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002700 parms = str_parms_create_str(kvpairs);
2701 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
2702 if (ret >= 0) {
2703 val = atoi(value);
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002704
2705 ALOGV("%s: routing: usecase(%d: %s) devices=(%#x) adev->mode(%#x)",
2706 __func__, out->usecase, use_case_table[out->usecase], val,
2707 adev->mode);
2708
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002709 pthread_mutex_lock(&adev->lock_inputs);
2710 lock_output_stream(out);
2711 pthread_mutex_lock(&adev->lock);
2712#ifdef PREPROCESSING_ENABLED
2713 if (((int)out->devices != val) && (val != 0) && (!out->standby) &&
2714 (out->usecase == USECASE_AUDIO_PLAYBACK)) {
2715 /* reset active input:
2716 * - to attach the echo reference
2717 * - because a change in output device may change mic settings */
2718 if (adev->active_input && (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
2719 adev->active_input->source == AUDIO_SOURCE_MIC)) {
2720 in = adev->active_input;
2721 }
2722 }
2723#endif
Christopher N. Hesse33affb82017-11-16 17:01:37 +01002724 if (val != SND_DEVICE_NONE) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002725 bool bt_sco_active = false;
2726
2727 if (out->devices & AUDIO_DEVICE_OUT_ALL_SCO) {
2728 bt_sco_active = true;
2729 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002730 out->devices = val;
2731
2732 if (!out->standby) {
2733 uc_info = get_usecase_from_id(adev, out->usecase);
2734 if (uc_info == NULL) {
2735 ALOGE("%s: Could not find the usecase (%d) in the list",
2736 __func__, out->usecase);
2737 } else {
2738 list_for_each(node, &out->pcm_dev_list) {
2739 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2740 if ((pcm_device->pcm_profile->devices & val) == 0)
2741 do_standby = true;
2742 val &= ~pcm_device->pcm_profile->devices;
2743 }
2744 if (val != 0)
2745 do_standby = true;
2746 }
2747 if (do_standby)
2748 do_out_standby_l(out);
2749 else {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002750 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
2751 out_set_offload_parameters(adev, uc_info);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002752 select_devices(adev, out->usecase);
2753 }
2754 }
2755
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002756 if ((adev->mode == AUDIO_MODE_IN_CALL) && !adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002757 (out == adev->primary_output)) {
2758 start_voice_call(adev);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002759 } else if ((adev->mode == AUDIO_MODE_IN_CALL) &&
2760 adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002761 (out == adev->primary_output)) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002762 /* Turn on bluetooth if needed */
2763 if ((out->devices & AUDIO_DEVICE_OUT_ALL_SCO) && !bt_sco_active) {
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002764 select_devices(adev, USECASE_VOICE_CALL);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002765 start_voice_session_bt_sco(adev->voice.session);
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002766 } else {
2767 /*
2768 * When we select different devices we need to restart the
2769 * voice call. The modem closes the stream on its end and
2770 * we do not get any output.
2771 */
2772 stop_voice_call(adev);
2773 start_voice_call(adev);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002774 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002775 }
2776 }
2777
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002778 pthread_mutex_unlock(&adev->lock);
2779 pthread_mutex_unlock(&out->lock);
2780#ifdef PREPROCESSING_ENABLED
2781 if (in) {
2782 /* The lock on adev->lock_inputs prevents input stream from being closed */
2783 lock_input_stream(in);
2784 pthread_mutex_lock(&adev->lock);
2785 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
2786 do_in_standby_l(in);
2787 pthread_mutex_unlock(&adev->lock);
2788 pthread_mutex_unlock(&in->lock);
2789 }
2790#endif
2791 pthread_mutex_unlock(&adev->lock_inputs);
2792 }
2793
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002794 amplifier_set_parameters(parms);
2795
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002796 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2797 parse_compress_metadata(out, parms);
2798 }
2799
2800 str_parms_destroy(parms);
2801
2802 if (ret > 0)
2803 ret = 0;
2804 ALOGV("%s: exit: code(%d)", __func__, ret);
2805 return ret;
2806}
2807
2808static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
2809{
2810 struct stream_out *out = (struct stream_out *)stream;
2811 struct str_parms *query = str_parms_create_str(keys);
2812 char *str;
2813 char value[256];
2814 struct str_parms *reply = str_parms_create();
2815 size_t i, j;
2816 int ret;
2817 bool first = true;
2818 ALOGV("%s: enter: keys - %s", __func__, keys);
2819 ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value));
2820 if (ret >= 0) {
2821 value[0] = '\0';
2822 i = 0;
2823 while (out->supported_channel_masks[i] != 0) {
2824 for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) {
2825 if (out_channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) {
2826 if (!first) {
2827 strcat(value, "|");
2828 }
2829 strcat(value, out_channels_name_to_enum_table[j].name);
2830 first = false;
2831 break;
2832 }
2833 }
2834 i++;
2835 }
2836 str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
2837 str = str_parms_to_str(reply);
2838 } else {
2839 str = strdup(keys);
2840 }
2841 str_parms_destroy(query);
2842 str_parms_destroy(reply);
2843 ALOGV("%s: exit: returns - %s", __func__, str);
2844 return str;
2845}
2846
2847static uint32_t out_get_latency(const struct audio_stream_out *stream)
2848{
2849 struct stream_out *out = (struct stream_out *)stream;
2850
2851 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
2852 return COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
2853
2854 return (out->config.period_count * out->config.period_size * 1000) /
2855 (out->config.rate);
2856}
2857
2858static int out_set_volume(struct audio_stream_out *stream, float left,
2859 float right)
2860{
2861 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002862
2863 if (out->usecase == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
2864 /* only take left channel into account: the API is for stereo anyway */
2865 out->muted = (left == 0.0f);
2866 return 0;
2867 } else if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002868 out_set_offload_volume(left, right);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002869 }
2870
2871 return -ENOSYS;
2872}
2873
Andreas Schneider3b643832017-01-31 11:48:22 +01002874#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002875static int fast_set_affinity(pid_t tid) {
2876 cpu_set_t cpu_set;
2877 int cpu_num;
2878 const char *irq_procfs = "/proc/asound/irq_affinity";
2879 FILE *fp;
2880
2881 if ((fp = fopen(irq_procfs, "r")) == NULL) {
2882 ALOGW("Procfs node %s not found", irq_procfs);
2883 return -1;
2884 }
2885
2886 if (fscanf(fp, "%d", &cpu_num) != 1) {
2887 ALOGW("Couldn't read CPU id from procfs node %s", irq_procfs);
2888 fclose(fp);
2889 return -1;
2890 }
2891 fclose(fp);
2892
2893 CPU_ZERO(&cpu_set);
2894 CPU_SET(cpu_num, &cpu_set);
2895 return sched_setaffinity(tid, sizeof(cpu_set), &cpu_set);
2896}
Andreas Schneider3b643832017-01-31 11:48:22 +01002897#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002898
2899static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
2900 size_t bytes)
2901{
2902 struct stream_out *out = (struct stream_out *)stream;
2903 struct audio_device *adev = out->dev;
2904 ssize_t ret = 0;
2905 struct pcm_device *pcm_device;
2906 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002907#ifdef PREPROCESSING_ENABLED
stenkinevgeniyd0a02c02018-05-08 07:17:53 +00002908 size_t frame_size = audio_stream_out_frame_size(stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002909 size_t in_frames = bytes / frame_size;
2910 size_t out_frames = in_frames;
2911 struct stream_in *in = NULL;
2912#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002913
2914 lock_output_stream(out);
2915
Andreas Schneider3b643832017-01-31 11:48:22 +01002916#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002917 if (out->usecase == USECASE_AUDIO_PLAYBACK && !out->is_fastmixer_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01002918 pid_t tid = gettid();
2919 int err;
2920
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002921 err = fast_set_affinity(tid);
2922 if (err < 0) {
2923 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
2924 }
2925 out->is_fastmixer_affinity_set = true;
2926 }
Andreas Schneider3b643832017-01-31 11:48:22 +01002927#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002928
2929 if (out->standby) {
2930#ifdef PREPROCESSING_ENABLED
2931 pthread_mutex_unlock(&out->lock);
2932 /* Prevent input stream from being closed */
2933 pthread_mutex_lock(&adev->lock_inputs);
2934 lock_output_stream(out);
2935 if (!out->standby) {
2936 pthread_mutex_unlock(&adev->lock_inputs);
2937 goto false_alarm;
2938 }
2939#endif
2940 pthread_mutex_lock(&adev->lock);
2941 ret = start_output_stream(out);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002942 if (ret == 0) {
2943 amplifier_output_stream_start(stream, out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD);
2944 }
2945
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002946 /* ToDo: If use case is compress offload should return 0 */
2947 if (ret != 0) {
2948 pthread_mutex_unlock(&adev->lock);
2949#ifdef PREPROCESSING_ENABLED
2950 pthread_mutex_unlock(&adev->lock_inputs);
2951#endif
2952 goto exit;
2953 }
2954 out->standby = false;
2955
2956#ifdef PREPROCESSING_ENABLED
2957 /* A change in output device may change the microphone selection */
2958 if (adev->active_input &&
2959 (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
2960 adev->active_input->source == AUDIO_SOURCE_MIC)) {
2961 in = adev->active_input;
2962 ALOGV("%s: enter:) force_input_standby true", __func__);
2963 }
2964#endif
2965 pthread_mutex_unlock(&adev->lock);
2966#ifdef PREPROCESSING_ENABLED
2967 if (!in) {
2968 /* Leave mutex locked iff in != NULL */
2969 pthread_mutex_unlock(&adev->lock_inputs);
2970 }
2971#endif
2972 }
Andreas Schneider5a2f1002017-02-09 10:59:04 +01002973#ifdef PREPROCESSING_ENABLED
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002974false_alarm:
Andreas Schneider5a2f1002017-02-09 10:59:04 +01002975#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002976
2977 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002978 ret = out_write_offload(stream, buffer, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002979 return ret;
2980 } else {
2981#ifdef PREPROCESSING_ENABLED
2982 if (android_atomic_acquire_load(&adev->echo_reference_generation)
2983 != out->echo_reference_generation) {
2984 pthread_mutex_lock(&adev->lock);
2985 if (out->echo_reference != NULL) {
2986 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
2987 release_echo_reference(out->echo_reference);
2988 }
2989 // note that adev->echo_reference_generation here can be different from the one
2990 // tested above but it doesn't matter as we now have the adev mutex and it is consistent
2991 // with what has been set by get_echo_reference() or put_echo_reference()
2992 out->echo_reference_generation = adev->echo_reference_generation;
2993 out->echo_reference = adev->echo_reference;
2994 ALOGV("%s: update echo reference generation %d", __func__,
2995 out->echo_reference_generation);
2996 pthread_mutex_unlock(&adev->lock);
2997 }
2998#endif
2999
3000 if (out->muted)
3001 memset((void *)buffer, 0, bytes);
3002 list_for_each(node, &out->pcm_dev_list) {
3003 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003004 if (pcm_device->pcm) {
3005#ifdef PREPROCESSING_ENABLED
3006 if (out->echo_reference != NULL && pcm_device->pcm_profile->devices != SND_DEVICE_OUT_SPEAKER) {
3007 struct echo_reference_buffer b;
3008 b.raw = (void *)buffer;
3009 b.frame_count = in_frames;
3010
3011 get_playback_delay(out, out_frames, &b);
3012 out->echo_reference->write(out->echo_reference, &b);
3013 }
3014#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003015 ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
stenkinevgeniyd0a02c02018-05-08 07:17:53 +00003016 pcm_device->status = pcm_write(pcm_device->pcm, (void *)buffer, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003017 if (pcm_device->status != 0)
3018 ret = pcm_device->status;
3019 }
3020 }
3021 if (ret == 0)
3022 out->written += bytes / (out->config.channels * sizeof(short));
3023 }
3024
3025exit:
3026 pthread_mutex_unlock(&out->lock);
3027
3028 if (ret != 0) {
3029 list_for_each(node, &out->pcm_dev_list) {
3030 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3031 if (pcm_device->pcm && pcm_device->status != 0)
3032 ALOGE("%s: error %zd - %s", __func__, ret, pcm_get_error(pcm_device->pcm));
3033 }
3034 out_standby(&out->stream.common);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003035 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3036 clock_gettime(CLOCK_MONOTONIC, &t);
3037 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3038 const int64_t elapsed_time_since_last_write = now - out->last_write_time_us;
3039 int64_t sleep_time = bytes * 1000000LL / audio_stream_out_frame_size(stream) /
3040 out_get_sample_rate(&stream->common) - elapsed_time_since_last_write;
3041 if (sleep_time > 0) {
3042 usleep(sleep_time);
3043 } else {
3044 // we don't sleep when we exit standby (this is typical for a real alsa buffer).
3045 sleep_time = 0;
3046 }
3047 out->last_write_time_us = now + sleep_time;
3048 // last_write_time_us is an approximation of when the (simulated) alsa
3049 // buffer is believed completely full. The usleep above waits for more space
3050 // in the buffer, but by the end of the sleep the buffer is considered
3051 // topped-off.
3052 //
3053 // On the subsequent out_write(), we measure the elapsed time spent in
3054 // the mixer. This is subtracted from the sleep estimate based on frames,
3055 // thereby accounting for drain in the alsa buffer during mixing.
3056 // This is a crude approximation; we don't handle underruns precisely.
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003057 }
3058
3059#ifdef PREPROCESSING_ENABLED
3060 if (in) {
3061 /* The lock on adev->lock_inputs prevents input stream from being closed */
3062 lock_input_stream(in);
3063 pthread_mutex_lock(&adev->lock);
3064 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
3065 do_in_standby_l(in);
3066 pthread_mutex_unlock(&adev->lock);
3067 pthread_mutex_unlock(&in->lock);
3068 /* This mutex was left locked iff in != NULL */
3069 pthread_mutex_unlock(&adev->lock_inputs);
3070 }
3071#endif
3072
3073 return bytes;
3074}
3075
3076static int out_get_render_position(const struct audio_stream_out *stream,
3077 uint32_t *dsp_frames)
3078{
3079 struct stream_out *out = (struct stream_out *)stream;
3080 *dsp_frames = 0;
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003081 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
3082 return out_get_render_offload_position(out, dsp_frames);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003083 } else
3084 return -EINVAL;
3085}
3086
3087static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3088{
3089 (void)stream;
3090 (void)effect;
3091 return 0;
3092}
3093
3094static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3095{
3096 (void)stream;
3097 (void)effect;
3098 return 0;
3099}
3100
3101static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
3102 int64_t *timestamp)
3103{
3104 (void)stream;
3105 (void)timestamp;
3106 return -EINVAL;
3107}
3108
3109static int out_get_presentation_position(const struct audio_stream_out *stream,
3110 uint64_t *frames, struct timespec *timestamp)
3111{
3112 struct stream_out *out = (struct stream_out *)stream;
Victor Lourme5869cd32018-03-26 19:36:07 +02003113 int ret = -EINVAL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003114
3115 lock_output_stream(out);
3116
3117 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003118 ret = out_get_presentation_offload_position(out, frames, timestamp);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003119 } else {
3120 /* FIXME: which device to read from? */
3121 if (!list_empty(&out->pcm_dev_list)) {
Andreas Schneiderd6359182017-02-08 16:58:22 +01003122 struct pcm_device *pcm_device;
3123 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003124 unsigned int avail;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003125
Andreas Schneiderd6359182017-02-08 16:58:22 +01003126 list_for_each(node, &out->pcm_dev_list) {
3127 pcm_device = node_to_item(node,
3128 struct pcm_device,
3129 stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003130
Andreas Schneiderd6359182017-02-08 16:58:22 +01003131 if (pcm_device->pcm != NULL) {
3132 if (pcm_get_htimestamp(pcm_device->pcm, &avail, timestamp) == 0) {
3133 size_t kernel_buffer_size = out->config.period_size * out->config.period_count;
3134 int64_t signed_frames = out->written - kernel_buffer_size + avail;
3135 /* This adjustment accounts for buffering after app processor.
3136 It is based on estimated DSP latency per use case, rather than exact. */
3137 signed_frames -=
3138 (render_latency(out->usecase) * out->sample_rate / 1000000LL);
3139
3140 /* It would be unusual for this value to be negative, but check just in case ... */
3141 if (signed_frames >= 0) {
3142 *frames = signed_frames;
3143 ret = 0;
3144 goto done;
3145 }
Andreas Schneiderd6359182017-02-08 16:58:22 +01003146 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003147 }
3148 }
3149 }
3150 }
3151
Andreas Schneiderd6359182017-02-08 16:58:22 +01003152done:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003153 pthread_mutex_unlock(&out->lock);
3154
3155 return ret;
3156}
3157
3158static int out_set_callback(struct audio_stream_out *stream,
3159 stream_callback_t callback, void *cookie)
3160{
3161 struct stream_out *out = (struct stream_out *)stream;
3162
3163 ALOGV("%s", __func__);
3164 lock_output_stream(out);
3165 out->offload_callback = callback;
3166 out->offload_cookie = cookie;
3167 pthread_mutex_unlock(&out->lock);
3168 return 0;
3169}
3170
3171static int out_pause(struct audio_stream_out* stream)
3172{
3173 struct stream_out *out = (struct stream_out *)stream;
3174 int status = -ENOSYS;
3175 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003176 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3177 status = out_pause_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003178 return status;
3179}
3180
3181static int out_resume(struct audio_stream_out* stream)
3182{
3183 struct stream_out *out = (struct stream_out *)stream;
3184 int status = -ENOSYS;
3185 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003186 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3187 status = out_resume_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003188 return status;
3189}
3190
3191static int out_drain(struct audio_stream_out* stream, audio_drain_type_t type )
3192{
3193 struct stream_out *out = (struct stream_out *)stream;
3194 int status = -ENOSYS;
3195 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003196 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3197 status = out_drain_offload(out, type);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003198 return status;
3199}
3200
3201static int out_flush(struct audio_stream_out* stream)
3202{
3203 struct stream_out *out = (struct stream_out *)stream;
3204 ALOGV("%s", __func__);
3205 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003206 return out_flush_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003207 }
3208 return -ENOSYS;
3209}
3210
3211/** audio_stream_in implementation **/
3212static uint32_t in_get_sample_rate(const struct audio_stream *stream)
3213{
3214 struct stream_in *in = (struct stream_in *)stream;
3215
3216 return in->requested_rate;
3217}
3218
3219static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
3220{
3221 (void)stream;
3222 (void)rate;
3223 return -ENOSYS;
3224}
3225
3226static uint32_t in_get_channels(const struct audio_stream *stream)
3227{
3228 struct stream_in *in = (struct stream_in *)stream;
3229
3230 return in->main_channels;
3231}
3232
3233static audio_format_t in_get_format(const struct audio_stream *stream)
3234{
3235 (void)stream;
3236 return AUDIO_FORMAT_PCM_16_BIT;
3237}
3238
3239static int in_set_format(struct audio_stream *stream, audio_format_t format)
3240{
3241 (void)stream;
3242 (void)format;
3243
3244 return -ENOSYS;
3245}
3246
3247static size_t in_get_buffer_size(const struct audio_stream *stream)
3248{
3249 struct stream_in *in = (struct stream_in *)stream;
3250
3251 return get_input_buffer_size(in->requested_rate,
3252 in_get_format(stream),
3253 audio_channel_count_from_in_mask(in->main_channels),
3254 in->usecase_type,
3255 in->devices);
3256}
3257
3258static int in_close_pcm_devices(struct stream_in *in)
3259{
3260 struct pcm_device *pcm_device;
3261 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003262
3263 list_for_each(node, &in->pcm_dev_list) {
3264 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3265 if (pcm_device) {
3266 if (pcm_device->pcm)
3267 pcm_close(pcm_device->pcm);
3268 pcm_device->pcm = NULL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003269 }
3270 }
3271 return 0;
3272}
3273
3274
3275/* must be called with stream and hw device mutex locked */
3276static int do_in_standby_l(struct stream_in *in)
3277{
3278 int status = 0;
3279
3280#ifdef PREPROCESSING_ENABLED
3281 struct audio_device *adev = in->dev;
3282#endif
3283 if (!in->standby) {
3284
3285 in_close_pcm_devices(in);
3286
3287#ifdef PREPROCESSING_ENABLED
3288 if (in->echo_reference != NULL) {
3289 /* stop reading from echo reference */
3290 in->echo_reference->read(in->echo_reference, NULL);
3291 put_echo_reference(adev, in->echo_reference);
3292 in->echo_reference = NULL;
3293 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003294#endif // PREPROCESSING_ENABLED
3295
3296 status = stop_input_stream(in);
3297
3298 if (in->read_buf) {
3299 free(in->read_buf);
3300 in->read_buf = NULL;
3301 }
3302
3303 in->standby = 1;
3304 }
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003305
3306 in->last_read_time_us = 0;
3307
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003308 return 0;
3309}
3310
3311// called with adev->lock_inputs locked
3312static int in_standby_l(struct stream_in *in)
3313{
3314 struct audio_device *adev = in->dev;
3315 int status = 0;
3316 lock_input_stream(in);
3317 if (!in->standby) {
3318 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003319 amplifier_input_stream_standby((struct audio_stream_in *) in);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003320 status = do_in_standby_l(in);
3321 pthread_mutex_unlock(&adev->lock);
3322 }
3323 pthread_mutex_unlock(&in->lock);
3324 return status;
3325}
3326
3327static int in_standby(struct audio_stream *stream)
3328{
3329 struct stream_in *in = (struct stream_in *)stream;
3330 struct audio_device *adev = in->dev;
3331 int status;
3332 ALOGV("%s: enter", __func__);
3333 pthread_mutex_lock(&adev->lock_inputs);
3334 status = in_standby_l(in);
3335 pthread_mutex_unlock(&adev->lock_inputs);
3336 ALOGV("%s: exit: status(%d)", __func__, status);
3337 return status;
3338}
3339
3340static int in_dump(const struct audio_stream *stream, int fd)
3341{
3342 (void)stream;
3343 (void)fd;
3344
3345 return 0;
3346}
3347
3348static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
3349{
3350 struct stream_in *in = (struct stream_in *)stream;
3351 struct audio_device *adev = in->dev;
3352 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003353 char value[32];
3354 int ret, val = 0;
3355 struct audio_usecase *uc_info;
3356 bool do_standby = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003357 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003358
3359 ALOGV("%s: enter: kvpairs=%s", __func__, kvpairs);
3360 parms = str_parms_create_str(kvpairs);
3361
3362 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
3363
3364 pthread_mutex_lock(&adev->lock_inputs);
3365 lock_input_stream(in);
3366 pthread_mutex_lock(&adev->lock);
3367 if (ret >= 0) {
3368 val = atoi(value);
3369 /* no audio source uses val == 0 */
3370 if (((int)in->source != val) && (val != 0)) {
3371 in->source = val;
3372 }
3373 }
3374
3375 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
3376 if (ret >= 0) {
3377 val = atoi(value);
3378 if (((int)in->devices != val) && (val != 0)) {
3379 in->devices = val;
3380 /* If recording is in progress, change the tx device to new device */
3381 if (!in->standby) {
3382 uc_info = get_usecase_from_id(adev, in->usecase);
3383 if (uc_info == NULL) {
3384 ALOGE("%s: Could not find the usecase (%d) in the list",
3385 __func__, in->usecase);
3386 } else {
3387 if (list_empty(&in->pcm_dev_list))
3388 ALOGE("%s: pcm device list empty", __func__);
3389 else {
3390 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3391 struct pcm_device, stream_list_node);
3392 if ((pcm_device->pcm_profile->devices & val & ~AUDIO_DEVICE_BIT_IN) == 0) {
3393 do_standby = true;
3394 }
3395 }
3396 }
3397 if (do_standby) {
3398 ret = do_in_standby_l(in);
3399 } else
3400 ret = select_devices(adev, in->usecase);
3401 }
3402 }
3403 }
3404 pthread_mutex_unlock(&adev->lock);
3405 pthread_mutex_unlock(&in->lock);
3406 pthread_mutex_unlock(&adev->lock_inputs);
3407 str_parms_destroy(parms);
3408
3409 if (ret > 0)
3410 ret = 0;
3411
3412 ALOGV("%s: exit: status(%d)", __func__, ret);
3413 return ret;
3414}
3415
3416static char* in_get_parameters(const struct audio_stream *stream,
3417 const char *keys)
3418{
3419 (void)stream;
3420 (void)keys;
3421
3422 return strdup("");
3423}
3424
3425static int in_set_gain(struct audio_stream_in *stream, float gain)
3426{
3427 (void)stream;
3428 (void)gain;
3429
3430 return 0;
3431}
3432
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003433static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
3434 size_t bytes)
3435{
3436 struct stream_in *in = (struct stream_in *)stream;
3437 struct audio_device *adev = in->dev;
3438 ssize_t frames = -1;
3439 int ret = -1;
3440 int read_and_process_successful = false;
3441
3442 size_t frames_rq = bytes / audio_stream_in_frame_size(stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003443
3444 /* no need to acquire adev->lock_inputs because API contract prevents a close */
3445 lock_input_stream(in);
3446
Andreas Schneider3b643832017-01-31 11:48:22 +01003447#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003448 if (in->usecase == USECASE_AUDIO_CAPTURE && !in->is_fastcapture_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003449 pid_t tid = gettid();
3450 int err;
3451
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003452 err = fast_set_affinity(tid);
3453 if (err < 0) {
3454 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
3455 }
3456 in->is_fastcapture_affinity_set = true;
3457 }
Andreas Schneider3b643832017-01-31 11:48:22 +01003458#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003459
3460 if (in->standby) {
3461 pthread_mutex_unlock(&in->lock);
3462 pthread_mutex_lock(&adev->lock_inputs);
3463 lock_input_stream(in);
3464 if (!in->standby) {
3465 pthread_mutex_unlock(&adev->lock_inputs);
3466 goto false_alarm;
3467 }
3468 pthread_mutex_lock(&adev->lock);
3469 ret = start_input_stream(in);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003470 if (ret == 0) {
3471 amplifier_input_stream_start(stream);
3472 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003473 pthread_mutex_unlock(&adev->lock);
3474 pthread_mutex_unlock(&adev->lock_inputs);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003475
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003476 if (ret != 0) {
3477 goto exit;
3478 }
3479 in->standby = 0;
3480 }
3481false_alarm:
3482
3483 if (!list_empty(&in->pcm_dev_list)) {
stenkinevgeniy44335362018-05-07 18:00:13 +00003484 /*
3485 * Read PCM and:
3486 * - resample if needed
3487 * - process if pre-processors are attached
3488 * - discard unwanted channels
3489 */
3490 frames = read_and_process_frames(in, buffer, frames_rq);
3491 if (frames >= 0)
3492 read_and_process_successful = true;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003493 }
3494
3495 /*
3496 * Instead of writing zeroes here, we could trust the hardware
3497 * to always provide zeroes when muted.
3498 */
3499 if (read_and_process_successful == true && adev->mic_mute)
3500 memset(buffer, 0, bytes);
3501
3502exit:
3503 pthread_mutex_unlock(&in->lock);
3504
3505 if (read_and_process_successful == false) {
3506 in_standby(&in->stream.common);
3507 ALOGV("%s: read failed - sleeping for buffer duration", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003508 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3509 clock_gettime(CLOCK_MONOTONIC, &t);
3510 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3511
3512 // we do a full sleep when exiting standby.
3513 const bool standby = in->last_read_time_us == 0;
3514 const int64_t elapsed_time_since_last_read = standby ?
3515 0 : now - in->last_read_time_us;
3516 int64_t sleep_time = bytes * 1000000LL / audio_stream_in_frame_size(stream) /
3517 in_get_sample_rate(&stream->common) - elapsed_time_since_last_read;
3518 if (sleep_time > 0) {
3519 usleep(sleep_time);
3520 } else {
3521 sleep_time = 0;
3522 }
3523 in->last_read_time_us = now + sleep_time;
3524 // last_read_time_us is an approximation of when the (simulated) alsa
3525 // buffer is drained by the read, and is empty.
3526 //
3527 // On the subsequent in_read(), we measure the elapsed time spent in
3528 // the recording thread. This is subtracted from the sleep estimate based on frames,
3529 // thereby accounting for fill in the alsa buffer during the interim.
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003530 memset(buffer, 0, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003531 }
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003532
3533 if (bytes > 0) {
3534 in->frames_read += bytes / audio_stream_in_frame_size(stream);
3535 }
3536
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003537 return bytes;
3538}
3539
3540static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
3541{
3542 (void)stream;
3543
3544 return 0;
3545}
3546
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003547static int in_get_capture_position(const struct audio_stream_in *stream,
3548 int64_t *frames, int64_t *time)
3549{
3550 if (stream == NULL || frames == NULL || time == NULL) {
3551 return -EINVAL;
3552 }
3553
3554 struct stream_in *in = (struct stream_in *)stream;
3555 struct pcm_device *pcm_device;
3556 int ret = -ENOSYS;
3557
3558 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3559 struct pcm_device, stream_list_node);
3560
3561 pthread_mutex_lock(&in->lock);
3562 if (pcm_device->pcm) {
3563 struct timespec timestamp;
3564 unsigned int avail;
3565 if (pcm_get_htimestamp(pcm_device->pcm, &avail, &timestamp) == 0) {
3566 *frames = in->frames_read + avail;
3567 *time = timestamp.tv_sec * 1000000000LL + timestamp.tv_nsec;
3568 ret = 0;
3569 }
3570 }
3571
3572 pthread_mutex_unlock(&in->lock);
3573 return ret;
3574}
3575
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003576static int add_remove_audio_effect(const struct audio_stream *stream,
3577 effect_handle_t effect,
3578 bool enable)
3579{
3580 struct stream_in *in = (struct stream_in *)stream;
3581 struct audio_device *adev = in->dev;
3582 int status = 0;
3583 effect_descriptor_t desc;
3584#ifdef PREPROCESSING_ENABLED
3585 int i;
3586#endif
3587 status = (*effect)->get_descriptor(effect, &desc);
3588 if (status != 0)
3589 return status;
3590
3591 ALOGI("add_remove_audio_effect(), effect type: %08x, enable: %d ", desc.type.timeLow, enable);
3592
3593 pthread_mutex_lock(&adev->lock_inputs);
3594 lock_input_stream(in);
3595 pthread_mutex_lock(&in->dev->lock);
3596#ifndef PREPROCESSING_ENABLED
3597 if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) &&
3598 in->enable_aec != enable &&
3599 (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0)) {
3600 in->enable_aec = enable;
3601 if (!in->standby)
3602 select_devices(in->dev, in->usecase);
3603 }
3604#else
3605 if ( (in->num_preprocessors > MAX_PREPROCESSORS) && (enable == true) ) {
3606 status = -ENOSYS;
3607 goto exit;
3608 }
3609 if ( enable == true ) {
3610 in->preprocessors[in->num_preprocessors].effect_itfe = effect;
3611 /* add the supported channel of the effect in the channel_configs */
3612 in_read_audio_effect_channel_configs(in, &in->preprocessors[in->num_preprocessors]);
3613 in->num_preprocessors ++;
3614 /* check compatibility between main channel supported and possible auxiliary channels */
3615 in_update_aux_channels(in, effect);//wesley crash
3616 in->aux_channels_changed = true;
3617 } else {
3618 /* if ( enable == false ) */
3619 if (in->num_preprocessors <= 0) {
3620 status = -ENOSYS;
3621 goto exit;
3622 }
3623 status = -EINVAL;
3624 for (i=0; i < in->num_preprocessors; i++) {
3625 if (status == 0) { /* status == 0 means an effect was removed from a previous slot */
3626 in->preprocessors[i - 1].effect_itfe = in->preprocessors[i].effect_itfe;
3627 in->preprocessors[i - 1].channel_configs = in->preprocessors[i].channel_configs;
3628 in->preprocessors[i - 1].num_channel_configs =
3629 in->preprocessors[i].num_channel_configs;
3630 ALOGV("add_remove_audio_effect moving fx from %d to %d", i, i-1);
3631 continue;
3632 }
3633 if ( in->preprocessors[i].effect_itfe == effect ) {
3634 ALOGV("add_remove_audio_effect found fx at index %d", i);
3635 free(in->preprocessors[i].channel_configs);
3636 status = 0;
3637 }
3638 }
3639 if (status != 0)
3640 goto exit;
3641 in->num_preprocessors--;
3642 /* if we remove one effect, at least the last proproc should be reset */
3643 in->preprocessors[in->num_preprocessors].num_channel_configs = 0;
3644 in->preprocessors[in->num_preprocessors].effect_itfe = NULL;
3645 in->preprocessors[in->num_preprocessors].channel_configs = NULL;
3646 in->aux_channels_changed = false;
3647 ALOGV("%s: enable(%d), in->aux_channels_changed(%d)", __func__, enable, in->aux_channels_changed);
3648 }
3649 ALOGI("%s: num_preprocessors = %d", __func__, in->num_preprocessors);
3650
3651 if ( memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
3652 in->enable_aec = enable;
3653 ALOGV("add_remove_audio_effect(), FX_IID_AEC, enable: %d", enable);
3654 if (!in->standby) {
3655 select_devices(in->dev, in->usecase);
3656 do_in_standby_l(in);
3657 }
3658 if (in->enable_aec == true) {
3659 in_configure_reverse(in);
3660 }
3661 }
3662exit:
3663#endif
3664 ALOGW_IF(status != 0, "add_remove_audio_effect() error %d", status);
3665 pthread_mutex_unlock(&in->dev->lock);
3666 pthread_mutex_unlock(&in->lock);
3667 pthread_mutex_unlock(&adev->lock_inputs);
3668 return status;
3669}
3670
3671static int in_add_audio_effect(const struct audio_stream *stream,
3672 effect_handle_t effect)
3673{
3674 ALOGV("%s: effect %p", __func__, effect);
3675 return add_remove_audio_effect(stream, effect, true);
3676}
3677
3678static int in_remove_audio_effect(const struct audio_stream *stream,
3679 effect_handle_t effect)
3680{
3681 ALOGV("%s: effect %p", __func__, effect);
3682 return add_remove_audio_effect(stream, effect, false);
3683}
3684
3685static int adev_open_output_stream(struct audio_hw_device *dev,
3686 audio_io_handle_t handle,
3687 audio_devices_t devices,
3688 audio_output_flags_t flags,
3689 struct audio_config *config,
3690 struct audio_stream_out **stream_out,
3691 const char *address __unused)
3692{
3693 struct audio_device *adev = (struct audio_device *)dev;
3694 struct stream_out *out;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003695 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003696 struct pcm_device_profile *pcm_profile;
3697
3698 ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
3699 __func__, config->sample_rate, config->channel_mask, devices, flags);
3700 *stream_out = NULL;
3701 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
Andreas Schneider56204f62017-01-31 08:17:32 +01003702 if (out == NULL) {
3703 ret = -ENOMEM;
3704 goto error_config;
3705 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003706
3707 if (devices == AUDIO_DEVICE_NONE)
3708 devices = AUDIO_DEVICE_OUT_SPEAKER;
3709
3710 out->flags = flags;
3711 out->devices = devices;
3712 out->dev = adev;
3713 out->format = config->format;
3714 out->sample_rate = config->sample_rate;
3715 out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3716 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
3717 out->handle = handle;
3718
3719 pcm_profile = get_pcm_device(PCM_PLAYBACK, devices);
3720 if (pcm_profile == NULL) {
3721 ret = -EINVAL;
3722 goto error_open;
3723 }
3724 out->config = pcm_profile->config;
3725
3726 /* Init use case and pcm_config */
3727 if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
3728 if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version ||
3729 config->offload_info.size != AUDIO_INFO_INITIALIZER.size) {
3730 ALOGE("%s: Unsupported Offload information", __func__);
3731 ret = -EINVAL;
3732 goto error_open;
3733 }
3734 if (!is_supported_format(config->offload_info.format)) {
3735 ALOGE("%s: Unsupported audio format", __func__);
3736 ret = -EINVAL;
3737 goto error_open;
3738 }
3739
3740 out->compr_config.codec = (struct snd_codec *)
3741 calloc(1, sizeof(struct snd_codec));
Andreas Schneider56204f62017-01-31 08:17:32 +01003742 if (out->compr_config.codec == NULL) {
3743 ret = -ENOMEM;
3744 goto error_open;
3745 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003746
3747 out->usecase = USECASE_AUDIO_PLAYBACK_OFFLOAD;
3748 if (config->offload_info.channel_mask)
3749 out->channel_mask = config->offload_info.channel_mask;
3750 else if (config->channel_mask)
3751 out->channel_mask = config->channel_mask;
3752 out->format = config->offload_info.format;
3753 out->sample_rate = config->offload_info.sample_rate;
3754
3755 out->stream.set_callback = out_set_callback;
3756 out->stream.pause = out_pause;
3757 out->stream.resume = out_resume;
3758 out->stream.drain = out_drain;
3759 out->stream.flush = out_flush;
3760
3761 out->compr_config.codec->id =
3762 get_snd_codec_id(config->offload_info.format);
3763 out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
3764 out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
3765 out->compr_config.codec->sample_rate = config->offload_info.sample_rate;
3766 out->compr_config.codec->bit_rate =
3767 config->offload_info.bit_rate;
3768 out->compr_config.codec->ch_in =
3769 audio_channel_count_from_out_mask(config->channel_mask);
3770 out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
3771
3772 if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
3773 out->non_blocking = 1;
3774
3775 out->send_new_metadata = 1;
3776 create_offload_callback_thread(out);
3777 out->offload_state = OFFLOAD_STATE_IDLE;
3778
3779 ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
3780 __func__, config->offload_info.version,
3781 config->offload_info.bit_rate);
3782 } else if (out->flags & (AUDIO_OUTPUT_FLAG_DEEP_BUFFER)) {
3783 out->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01003784 out->config = pcm_device_deep_buffer.config;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003785 out->sample_rate = out->config.rate;
3786 ALOGV("%s: use AUDIO_PLAYBACK_DEEP_BUFFER",__func__);
3787 } else {
3788 out->usecase = USECASE_AUDIO_PLAYBACK;
3789 out->sample_rate = out->config.rate;
3790 }
3791
3792 if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
3793 if (adev->primary_output == NULL)
3794 adev->primary_output = out;
3795 else {
3796 ALOGE("%s: Primary output is already opened", __func__);
3797 ret = -EEXIST;
3798 goto error_open;
3799 }
3800 }
3801
3802 /* Check if this usecase is already existing */
3803 pthread_mutex_lock(&adev->lock);
3804 if (get_usecase_from_id(adev, out->usecase) != NULL) {
3805 ALOGE("%s: Usecase (%d) is already present", __func__, out->usecase);
3806 pthread_mutex_unlock(&adev->lock);
3807 ret = -EEXIST;
3808 goto error_open;
3809 }
3810 pthread_mutex_unlock(&adev->lock);
3811
3812 out->stream.common.get_sample_rate = out_get_sample_rate;
3813 out->stream.common.set_sample_rate = out_set_sample_rate;
3814 out->stream.common.get_buffer_size = out_get_buffer_size;
3815 out->stream.common.get_channels = out_get_channels;
3816 out->stream.common.get_format = out_get_format;
3817 out->stream.common.set_format = out_set_format;
3818 out->stream.common.standby = out_standby;
3819 out->stream.common.dump = out_dump;
3820 out->stream.common.set_parameters = out_set_parameters;
3821 out->stream.common.get_parameters = out_get_parameters;
3822 out->stream.common.add_audio_effect = out_add_audio_effect;
3823 out->stream.common.remove_audio_effect = out_remove_audio_effect;
3824 out->stream.get_latency = out_get_latency;
3825 out->stream.set_volume = out_set_volume;
3826 out->stream.write = out_write;
3827 out->stream.get_render_position = out_get_render_position;
3828 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
3829 out->stream.get_presentation_position = out_get_presentation_position;
3830
3831 out->standby = 1;
3832 /* out->muted = false; by calloc() */
3833 /* out->written = 0; by calloc() */
3834
3835 pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
3836 pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
3837 pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
3838
3839 config->format = out->stream.common.get_format(&out->stream.common);
3840 config->channel_mask = out->stream.common.get_channels(&out->stream.common);
3841 config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
3842
3843 out->is_fastmixer_affinity_set = false;
3844
3845 *stream_out = &out->stream;
3846 ALOGV("%s: exit", __func__);
3847 return 0;
3848
3849error_open:
3850 free(out);
3851 *stream_out = NULL;
Andreas Schneider56204f62017-01-31 08:17:32 +01003852error_config:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003853 ALOGV("%s: exit: ret %d", __func__, ret);
3854 return ret;
3855}
3856
3857static void adev_close_output_stream(struct audio_hw_device *dev,
3858 struct audio_stream_out *stream)
3859{
3860 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003861 (void)dev;
3862
3863 ALOGV("%s: enter", __func__);
3864 out_standby(&stream->common);
3865 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
3866 destroy_offload_callback_thread(out);
3867
3868 if (out->compr_config.codec != NULL)
3869 free(out->compr_config.codec);
3870 }
3871 pthread_cond_destroy(&out->cond);
3872 pthread_mutex_destroy(&out->lock);
3873 free(stream);
3874 ALOGV("%s: exit", __func__);
3875}
3876
3877static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
3878{
3879 struct audio_device *adev = (struct audio_device *)dev;
3880 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003881 char value[32];
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003882#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003883 int val;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003884#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003885 int ret;
3886
3887 ALOGV("%s: enter: %s", __func__, kvpairs);
3888
3889 parms = str_parms_create_str(kvpairs);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003890
Andreas Schneider05bc1882017-02-09 14:03:11 +01003891 /******************************************************
3892 *** BT SCO
3893 ******************************************************/
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003894 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
3895 if (ret >= 0) {
3896 /* When set to false, HAL should disable EC and NS
3897 * But it is currently not supported.
3898 */
3899 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
Andreas Schneider74ef3a12017-02-02 18:29:12 +01003900 adev->voice.bluetooth_nrec = true;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003901 else
Andreas Schneider74ef3a12017-02-02 18:29:12 +01003902 adev->voice.bluetooth_nrec = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003903 }
3904
Andreas Schneider05bc1882017-02-09 14:03:11 +01003905 ret = str_parms_get_str(parms,
3906 AUDIO_PARAMETER_KEY_BT_SCO_WB,
3907 value,
3908 sizeof(value));
3909 if (ret >= 0) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01003910 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) {
3911 adev->voice.bluetooth_wb = true;
Andreas Schneider05bc1882017-02-09 14:03:11 +01003912 } else {
3913 adev->voice.bluetooth_wb = false;
3914 }
3915 }
3916
Andreas Schneiderecd17ce2017-02-09 10:45:21 +01003917 ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
3918 if (ret >= 0) {
3919 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
3920 adev->screen_off = false;
3921 else
3922 adev->screen_off = true;
3923 }
3924
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01003925#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003926 ret = str_parms_get_int(parms, "rotation", &val);
3927 if (ret >= 0) {
3928 bool reverse_speakers = false;
3929 switch(val) {
3930 /* FIXME: note that the code below assumes that the speakers are in the correct placement
3931 relative to the user when the device is rotated 90deg from its default rotation. This
3932 assumption is device-specific, not platform-specific like this code. */
3933 case 270:
3934 reverse_speakers = true;
3935 break;
3936 case 0:
3937 case 90:
3938 case 180:
3939 break;
3940 default:
3941 ALOGE("%s: unexpected rotation of %d", __func__, val);
3942 }
3943 pthread_mutex_lock(&adev->lock);
3944 if (adev->speaker_lr_swap != reverse_speakers) {
3945 adev->speaker_lr_swap = reverse_speakers;
3946 /* only update the selected device if there is active pcm playback */
3947 struct audio_usecase *usecase;
3948 struct listnode *node;
3949 list_for_each(node, &adev->usecase_list) {
3950 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
3951 if (usecase->type == PCM_PLAYBACK) {
3952 select_devices(adev, usecase->id);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003953 break;
3954 }
3955 }
3956 }
3957 pthread_mutex_unlock(&adev->lock);
3958 }
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01003959#endif /* SWAP_SPEAKER_ON_SCREEN_ROTATION */
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003960
3961 str_parms_destroy(parms);
3962
3963 if (ret > 0)
3964 ret = 0;
3965
3966 ALOGV("%s: exit with code(%d)", __func__, ret);
3967 return ret;
3968}
3969
3970static char* adev_get_parameters(const struct audio_hw_device *dev,
3971 const char *keys)
3972{
3973 (void)dev;
3974 (void)keys;
3975
3976 return strdup("");
3977}
3978
3979static int adev_init_check(const struct audio_hw_device *dev)
3980{
3981 (void)dev;
3982
3983 return 0;
3984}
3985
3986static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
3987{
3988 int ret = 0;
3989 struct audio_device *adev = (struct audio_device *)dev;
3990 pthread_mutex_lock(&adev->lock);
3991 /* cache volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01003992 adev->voice.volume = volume;
3993 ret = set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003994 pthread_mutex_unlock(&adev->lock);
3995 return ret;
3996}
3997
3998static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
3999{
4000 (void)dev;
4001 (void)volume;
4002
4003 return -ENOSYS;
4004}
4005
4006static int adev_get_master_volume(struct audio_hw_device *dev,
4007 float *volume)
4008{
4009 (void)dev;
4010 (void)volume;
4011
4012 return -ENOSYS;
4013}
4014
4015static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
4016{
4017 (void)dev;
4018 (void)muted;
4019
4020 return -ENOSYS;
4021}
4022
4023static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
4024{
4025 (void)dev;
4026 (void)muted;
4027
4028 return -ENOSYS;
4029}
4030
4031static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
4032{
4033 struct audio_device *adev = (struct audio_device *)dev;
4034
4035 pthread_mutex_lock(&adev->lock);
4036 if (adev->mode != mode) {
4037 ALOGI("%s mode = %d", __func__, mode);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004038 if (amplifier_set_mode(mode) != 0) {
4039 ALOGE("Failed setting amplifier mode");
4040 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004041 adev->mode = mode;
Christopher N. Hesse6c0020c2017-11-17 20:41:11 +01004042
4043 if ((mode == AUDIO_MODE_NORMAL) && adev->voice.in_call) {
4044 stop_voice_call(adev);
4045 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004046 }
4047 pthread_mutex_unlock(&adev->lock);
4048 return 0;
4049}
4050
4051static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
4052{
4053 struct audio_device *adev = (struct audio_device *)dev;
4054 int err = 0;
4055
4056 pthread_mutex_lock(&adev->lock);
4057 adev->mic_mute = state;
4058
4059 if (adev->mode == AUDIO_MODE_IN_CALL) {
Andreas Schneider107a8482017-02-06 12:36:31 +01004060 set_voice_session_mic_mute(adev->voice.session, state);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004061 }
4062
4063 pthread_mutex_unlock(&adev->lock);
4064 return err;
4065}
4066
4067static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
4068{
4069 struct audio_device *adev = (struct audio_device *)dev;
4070
4071 *state = adev->mic_mute;
4072
4073 return 0;
4074}
4075
4076static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
4077 const struct audio_config *config)
4078{
4079 (void)dev;
4080
4081 /* NOTE: we default to built in mic which may cause a mismatch between what we
4082 * report here and the actual buffer size
4083 */
4084 return get_input_buffer_size(config->sample_rate,
4085 config->format,
4086 audio_channel_count_from_in_mask(config->channel_mask),
4087 PCM_CAPTURE /* usecase_type */,
4088 AUDIO_DEVICE_IN_BUILTIN_MIC);
4089}
4090
4091static int adev_open_input_stream(struct audio_hw_device *dev,
4092 audio_io_handle_t handle __unused,
4093 audio_devices_t devices,
4094 struct audio_config *config,
4095 struct audio_stream_in **stream_in,
4096 audio_input_flags_t flags,
4097 const char *address __unused,
4098 audio_source_t source)
4099{
4100 struct audio_device *adev = (struct audio_device *)dev;
4101 struct stream_in *in;
4102 struct pcm_device_profile *pcm_profile;
4103
4104 ALOGV("%s: enter", __func__);
4105
4106 *stream_in = NULL;
4107 if (check_input_parameters(config->sample_rate, config->format,
4108 audio_channel_count_from_in_mask(config->channel_mask)) != 0)
4109 return -EINVAL;
4110
stenkinevgeniy44335362018-05-07 18:00:13 +00004111 usecase_type_t usecase_type = flags & AUDIO_INPUT_FLAG_FAST ?
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004112 PCM_CAPTURE_LOW_LATENCY : PCM_CAPTURE;
4113 pcm_profile = get_pcm_device(usecase_type, devices);
4114 if (pcm_profile == NULL && usecase_type == PCM_CAPTURE_LOW_LATENCY) {
4115 // a low latency profile may not exist for that device, fall back
4116 // to regular capture. the MixerThread automatically changes
4117 // to non-fast capture based on the buffer size.
4118 flags &= ~AUDIO_INPUT_FLAG_FAST;
4119 usecase_type = PCM_CAPTURE;
4120 pcm_profile = get_pcm_device(usecase_type, devices);
4121 }
4122 if (pcm_profile == NULL)
4123 return -EINVAL;
4124
4125 in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
Andreas Schneider56204f62017-01-31 08:17:32 +01004126 if (in == NULL) {
4127 return -ENOMEM;
4128 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004129
4130 in->stream.common.get_sample_rate = in_get_sample_rate;
4131 in->stream.common.set_sample_rate = in_set_sample_rate;
4132 in->stream.common.get_buffer_size = in_get_buffer_size;
4133 in->stream.common.get_channels = in_get_channels;
4134 in->stream.common.get_format = in_get_format;
4135 in->stream.common.set_format = in_set_format;
4136 in->stream.common.standby = in_standby;
4137 in->stream.common.dump = in_dump;
4138 in->stream.common.set_parameters = in_set_parameters;
4139 in->stream.common.get_parameters = in_get_parameters;
4140 in->stream.common.add_audio_effect = in_add_audio_effect;
4141 in->stream.common.remove_audio_effect = in_remove_audio_effect;
4142 in->stream.set_gain = in_set_gain;
4143 in->stream.read = in_read;
4144 in->stream.get_input_frames_lost = in_get_input_frames_lost;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004145 in->stream.get_capture_position = in_get_capture_position;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004146
4147 in->devices = devices;
4148 in->source = source;
4149 in->dev = adev;
4150 in->standby = 1;
4151 in->main_channels = config->channel_mask;
4152 in->requested_rate = config->sample_rate;
4153 if (config->sample_rate != CAPTURE_DEFAULT_SAMPLING_RATE)
4154 flags = flags & ~AUDIO_INPUT_FLAG_FAST;
4155 in->input_flags = flags;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004156 // in->frames_read = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004157 /* HW codec is limited to default channels. No need to update with
4158 * requested channels */
4159 in->config = pcm_profile->config;
4160
4161 /* Update config params with the requested sample rate and channels */
stenkinevgeniy44335362018-05-07 18:00:13 +00004162 in->usecase = USECASE_AUDIO_CAPTURE;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004163 in->usecase_type = usecase_type;
4164
4165 pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
4166 pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL);
4167
4168 in->is_fastcapture_affinity_set = false;
4169
4170 *stream_in = &in->stream;
4171 ALOGV("%s: exit", __func__);
4172 return 0;
4173}
4174
4175static void adev_close_input_stream(struct audio_hw_device *dev,
4176 struct audio_stream_in *stream)
4177{
4178 struct audio_device *adev = (struct audio_device *)dev;
4179 struct stream_in *in = (struct stream_in*)stream;
4180 ALOGV("%s", __func__);
4181
4182 /* prevent concurrent out_set_parameters, or out_write from standby */
4183 pthread_mutex_lock(&adev->lock_inputs);
4184
Andreas Schneidercabe5e62017-01-30 10:57:06 +01004185 if (in->read_buf) {
4186 free(in->read_buf);
4187 in->read_buf = NULL;
4188 }
4189
4190 if (in->resampler) {
4191 release_resampler(in->resampler);
4192 in->resampler = NULL;
4193 }
4194
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004195#ifdef PREPROCESSING_ENABLED
4196 int i;
4197
4198 for (i=0; i<in->num_preprocessors; i++) {
4199 free(in->preprocessors[i].channel_configs);
4200 }
4201
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004202 if (in->proc_buf_in) {
4203 free(in->proc_buf_in);
4204 in->proc_buf_in = NULL;
4205 }
4206
4207 if (in->proc_buf_out) {
4208 free(in->proc_buf_out);
4209 in->proc_buf_out = NULL;
4210 }
4211
4212 if (in->ref_buf) {
4213 free(in->ref_buf);
4214 in->ref_buf = NULL;
4215 }
4216
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004217#endif
4218
4219 in_standby_l(in);
4220 free(stream);
4221
4222 pthread_mutex_unlock(&adev->lock_inputs);
4223
4224 return;
4225}
4226
4227static int adev_dump(const audio_hw_device_t *device, int fd)
4228{
4229 (void)device;
4230 (void)fd;
4231
4232 return 0;
4233}
4234
4235static int adev_close(hw_device_t *device)
4236{
4237 struct audio_device *adev = (struct audio_device *)device;
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004238 voice_session_deinit(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004239 audio_device_ref_count--;
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004240 if (audio_device_ref_count == 0) {
4241 if (amplifier_close() != 0) {
4242 ALOGE("Amplifier close failed");
4243 }
4244 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004245 free(adev->snd_dev_ref_cnt);
4246 free_mixer_list(adev);
4247 free(device);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004248
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004249 adev = NULL;
4250
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004251 return 0;
4252}
4253
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004254/* This returns true if the input parameter looks at all plausible as a low latency period size,
4255 * or false otherwise. A return value of true doesn't mean the value is guaranteed to work,
4256 * just that it _might_ work.
4257 */
4258static bool period_size_is_plausible_for_low_latency(int period_size)
4259{
4260 switch (period_size) {
4261 case 64:
4262 case 96:
4263 case 128:
4264 case 192:
4265 case 256:
4266 return true;
4267 default:
4268 return false;
4269 }
4270}
4271
4272static int adev_open(const hw_module_t *module, const char *name,
4273 hw_device_t **device)
4274{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004275 ALOGV("%s: enter", __func__);
4276 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
4277
Andreas Schneider56204f62017-01-31 08:17:32 +01004278 *device = NULL;
4279
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004280 adev = calloc(1, sizeof(struct audio_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01004281 if (adev == NULL) {
4282 return -ENOMEM;
4283 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004284
4285 adev->device.common.tag = HARDWARE_DEVICE_TAG;
4286 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
4287 adev->device.common.module = (struct hw_module_t *)module;
4288 adev->device.common.close = adev_close;
4289
4290 adev->device.init_check = adev_init_check;
4291 adev->device.set_voice_volume = adev_set_voice_volume;
4292 adev->device.set_master_volume = adev_set_master_volume;
4293 adev->device.get_master_volume = adev_get_master_volume;
4294 adev->device.set_master_mute = adev_set_master_mute;
4295 adev->device.get_master_mute = adev_get_master_mute;
4296 adev->device.set_mode = adev_set_mode;
4297 adev->device.set_mic_mute = adev_set_mic_mute;
4298 adev->device.get_mic_mute = adev_get_mic_mute;
4299 adev->device.set_parameters = adev_set_parameters;
4300 adev->device.get_parameters = adev_get_parameters;
4301 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
4302 adev->device.open_output_stream = adev_open_output_stream;
4303 adev->device.close_output_stream = adev_close_output_stream;
4304 adev->device.open_input_stream = adev_open_input_stream;
4305 adev->device.close_input_stream = adev_close_input_stream;
4306 adev->device.dump = adev_dump;
4307
4308 /* Set the default route before the PCM stream is opened */
4309 adev->mode = AUDIO_MODE_NORMAL;
4310 adev->active_input = NULL;
4311 adev->primary_output = NULL;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004312
4313 adev->voice.volume = 1.0f;
4314 adev->voice.bluetooth_nrec = true;
4315 adev->voice.in_call = false;
Christopher N. Hessee4a1c592018-01-16 18:33:38 +01004316 adev->voice.bluetooth_wb = false;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004317
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004318 /* adev->cur_hdmi_channels = 0; by calloc() */
4319 adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
Andreas Schneider56204f62017-01-31 08:17:32 +01004320 if (adev->snd_dev_ref_cnt == NULL) {
4321 free(adev);
4322 return -ENOMEM;
4323 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004324
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004325 adev->ns_in_voice_rec = false;
4326
4327 list_init(&adev->usecase_list);
4328
4329 if (mixer_init(adev) != 0) {
4330 free(adev->snd_dev_ref_cnt);
4331 free(adev);
4332 ALOGE("%s: Failed to init, aborting.", __func__);
4333 *device = NULL;
4334 return -EINVAL;
4335 }
4336
4337 if (access(OFFLOAD_FX_LIBRARY_PATH, R_OK) == 0) {
4338 adev->offload_fx_lib = dlopen(OFFLOAD_FX_LIBRARY_PATH, RTLD_NOW);
4339 if (adev->offload_fx_lib == NULL) {
4340 ALOGE("%s: DLOPEN failed for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4341 } else {
4342 ALOGV("%s: DLOPEN successful for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4343 adev->offload_fx_start_output =
4344 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4345 "visualizer_hal_start_output");
4346 adev->offload_fx_stop_output =
4347 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4348 "visualizer_hal_stop_output");
4349 }
4350 }
4351
Christopher N. Hesse696959d2017-02-02 20:49:55 +01004352 adev->voice.session = voice_session_init(adev);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004353 if (adev->voice.session == NULL) {
4354 ALOGE("%s: Failed to initialize voice session data", __func__);
4355
4356 free(adev->snd_dev_ref_cnt);
4357 free(adev);
4358
4359 *device = NULL;
4360 return -EINVAL;
4361 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004362
Christopher N. Hessec487bbe2018-07-12 13:51:43 +02004363 if (amplifier_open() != -ENOENT) {
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004364 ALOGE("Amplifier initialization failed");
4365 }
4366
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004367 *device = &adev->device.common;
4368
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004369 audio_device_ref_count++;
4370
4371 char value[PROPERTY_VALUE_MAX];
4372 if (property_get("audio_hal.period_size", value, NULL) > 0) {
4373 int trial = atoi(value);
4374 if (period_size_is_plausible_for_low_latency(trial)) {
4375
4376 pcm_device_playback.config.period_size = trial;
4377 pcm_device_playback.config.start_threshold =
4378 PLAYBACK_START_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4379 pcm_device_playback.config.stop_threshold =
4380 PLAYBACK_STOP_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4381
4382 pcm_device_capture_low_latency.config.period_size = trial;
4383 }
4384 }
4385
4386 ALOGV("%s: exit", __func__);
4387 return 0;
4388}
4389
4390static struct hw_module_methods_t hal_module_methods = {
4391 .open = adev_open,
4392};
4393
4394struct audio_module HAL_MODULE_INFO_SYM = {
4395 .common = {
4396 .tag = HARDWARE_MODULE_TAG,
4397 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
4398 .hal_api_version = HARDWARE_HAL_API_VERSION,
4399 .id = AUDIO_HARDWARE_MODULE_ID,
Christopher N. Hessec8502b92017-01-28 14:02:15 +01004400 .name = "Samsung Audio HAL",
4401 .author = "The LineageOS Project",
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004402 .methods = &hal_module_methods,
4403 },
4404};