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