blob: 9413297a87e96d50364452e41268dc4c8b09a27d [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
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001147static void get_capture_delay(struct stream_in *in,
1148 size_t frames __unused,
1149 struct echo_reference_buffer *buffer)
1150{
1151 ALOGVV("%s: enter:)", __func__);
1152 /* read frames available in kernel driver buffer */
1153 unsigned int kernel_frames;
1154 struct timespec tstamp;
1155 long buf_delay;
1156 long rsmp_delay;
1157 long kernel_delay;
1158 long delay_ns;
1159 struct pcm_device *pcm_device;
1160
1161 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1162 struct pcm_device, stream_list_node);
1163
1164 if (pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &tstamp) < 0) {
1165 buffer->time_stamp.tv_sec = 0;
1166 buffer->time_stamp.tv_nsec = 0;
1167 buffer->delay_ns = 0;
1168 ALOGW("read get_capture_delay(): pcm_htimestamp error");
1169 return;
1170 }
1171
1172 /* read frames available in audio HAL input buffer
1173 * add number of frames being read as we want the capture time of first sample
1174 * in current buffer */
1175 /* frames in in->read_buf are at driver sampling rate while frames in in->proc_buf are
1176 * at requested sampling rate */
1177 buf_delay = (long)(((int64_t)(in->read_buf_frames) * 1000000000) / in->config.rate +
1178 ((int64_t)(in->proc_buf_frames) * 1000000000) / in->requested_rate );
1179
1180 /* add delay introduced by resampler */
1181 rsmp_delay = 0;
1182 if (in->resampler) {
1183 rsmp_delay = in->resampler->delay_ns(in->resampler);
1184 }
1185
1186 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / in->config.rate);
1187
1188 delay_ns = kernel_delay + buf_delay + rsmp_delay;
1189
1190 buffer->time_stamp = tstamp;
1191 buffer->delay_ns = delay_ns;
1192 ALOGVV("get_capture_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames:[%5d],"
1193 " delay_ns: [%d], kernel_delay:[%ld], buf_delay:[%ld], rsmp_delay:[%ld], "
1194 "in->read_buf_frames:[%zd], in->proc_buf_frames:[%zd], frames:[%zd]",
1195 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames,
1196 buffer->delay_ns, kernel_delay, buf_delay, rsmp_delay,
1197 in->read_buf_frames, in->proc_buf_frames, frames);
1198}
1199
1200static int32_t update_echo_reference(struct stream_in *in, size_t frames)
1201{
1202 ALOGVV("%s: enter:), in->config.channels(%d)", __func__,in->config.channels);
1203 struct echo_reference_buffer b;
1204 b.delay_ns = 0;
1205 struct pcm_device *pcm_device;
1206
1207 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1208 struct pcm_device, stream_list_node);
1209
1210 ALOGVV("update_echo_reference, in->config.channels(%d), frames = [%zd], in->ref_buf_frames = [%zd], "
1211 "b.frame_count = [%zd]",
1212 in->config.channels, frames, in->ref_buf_frames, frames - in->ref_buf_frames);
1213 if (in->ref_buf_frames < frames) {
1214 if (in->ref_buf_size < frames) {
1215 in->ref_buf_size = frames;
1216 in->ref_buf = (int16_t *)realloc(in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1217 ALOG_ASSERT((in->ref_buf != NULL),
1218 "update_echo_reference() failed to reallocate ref_buf");
1219 ALOGVV("update_echo_reference(): ref_buf %p extended to %d bytes",
1220 in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1221 }
1222 b.frame_count = frames - in->ref_buf_frames;
1223 b.raw = (void *)(in->ref_buf + in->ref_buf_frames * in->config.channels);
1224
1225 get_capture_delay(in, frames, &b);
1226
1227 if (in->echo_reference->read(in->echo_reference, &b) == 0)
1228 {
1229 in->ref_buf_frames += b.frame_count;
1230 ALOGVV("update_echo_reference(): in->ref_buf_frames:[%zd], "
1231 "in->ref_buf_size:[%zd], frames:[%zd], b.frame_count:[%zd]",
1232 in->ref_buf_frames, in->ref_buf_size, frames, b.frame_count);
1233 }
1234 } else
1235 ALOGW("update_echo_reference(): NOT enough frames to read ref buffer");
1236 return b.delay_ns;
1237}
1238
1239static int set_preprocessor_param(effect_handle_t handle,
1240 effect_param_t *param)
1241{
1242 uint32_t size = sizeof(int);
Basil Gelloefdfdba2018-05-21 18:29:12 +03001243 uint32_t bufsize = sizeof(effect_param_t) +
1244 ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
1245 param->vsize;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001246
1247 int status = (*handle)->command(handle,
1248 EFFECT_CMD_SET_PARAM,
Basil Gelloefdfdba2018-05-21 18:29:12 +03001249 bufsize,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001250 param,
1251 &size,
1252 &param->status);
1253 if (status == 0)
1254 status = param->status;
1255
1256 return status;
1257}
1258
1259static int set_preprocessor_echo_delay(effect_handle_t handle,
1260 int32_t delay_us)
1261{
Basil Gelloefdfdba2018-05-21 18:29:12 +03001262 const uint32_t param_size = sizeof(uint32_t);
1263 const uint32_t value_size = sizeof(uint32_t);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001264
Basil Gelloefdfdba2018-05-21 18:29:12 +03001265 const uint32_t param_padded_size =
1266 ((param_size - 1) / sizeof(int) + 1) * sizeof(int);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001267
Basil Gelloefdfdba2018-05-21 18:29:12 +03001268 const uint32_t bufsize = sizeof(effect_param_t) +
1269 param_padded_size + value_size;
1270
1271 uint8_t buf[bufsize];
1272 memset(&buf, 0, bufsize);
1273
1274 effect_param_t *effect_param = (effect_param_t *)&buf;
1275
1276 effect_param->psize = param_size;
1277 effect_param->vsize = value_size;
1278
1279 *(uint32_t *)&buf[sizeof(effect_param_t)] = AEC_PARAM_ECHO_DELAY;
1280 *(int32_t *)&buf[sizeof(effect_param_t) + param_padded_size] = delay_us;
1281
1282 return set_preprocessor_param(handle, effect_param);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001283}
1284
1285static void push_echo_reference(struct stream_in *in, size_t frames)
1286{
1287 ALOGVV("%s: enter:)", __func__);
1288 /* read frames from echo reference buffer and update echo delay
1289 * in->ref_buf_frames is updated with frames available in in->ref_buf */
1290
1291 int32_t delay_us = update_echo_reference(in, frames)/1000;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001292 int i;
1293 audio_buffer_t buf;
1294
1295 if (in->ref_buf_frames < frames)
1296 frames = in->ref_buf_frames;
1297
1298 buf.frameCount = frames;
1299 buf.raw = in->ref_buf;
1300
1301 for (i = 0; i < in->num_preprocessors; i++) {
1302 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1303 continue;
1304 ALOGVV("%s: effect_itfe)->process_reverse() BEGIN i=(%d) ", __func__, i);
1305 (*in->preprocessors[i].effect_itfe)->process_reverse(in->preprocessors[i].effect_itfe,
1306 &buf,
1307 NULL);
1308 ALOGVV("%s: effect_itfe)->process_reverse() END i=(%d) ", __func__, i);
1309 set_preprocessor_echo_delay(in->preprocessors[i].effect_itfe, delay_us);
1310 }
1311
1312 in->ref_buf_frames -= buf.frameCount;
1313 ALOGVV("%s: in->ref_buf_frames(%zd), in->config.channels(%d) ",
1314 __func__, in->ref_buf_frames, in->config.channels);
1315 if (in->ref_buf_frames) {
1316 memcpy(in->ref_buf,
1317 in->ref_buf + buf.frameCount * in->config.channels,
1318 in->ref_buf_frames * in->config.channels * sizeof(int16_t));
1319 }
1320}
1321
1322static void put_echo_reference(struct audio_device *adev,
1323 struct echo_reference_itfe *reference)
1324{
1325 ALOGV("%s: enter:)", __func__);
1326 int32_t prev_generation = adev->echo_reference_generation;
1327 struct stream_out *out = adev->primary_output;
1328
1329 if (adev->echo_reference != NULL &&
1330 reference == adev->echo_reference) {
1331 /* echo reference is taken from the low latency output stream used
1332 * for voice use cases */
1333 adev->echo_reference = NULL;
1334 android_atomic_inc(&adev->echo_reference_generation);
1335 if (out != NULL && out->usecase == USECASE_AUDIO_PLAYBACK) {
1336 // if the primary output is in standby or did not pick the echo reference yet
1337 // we can safely get rid of it here.
1338 // otherwise, out_write() or out_standby() will detect the change in echo reference
1339 // generation and release the echo reference owned by the stream.
1340 if ((out->echo_reference_generation != prev_generation) || out->standby)
1341 release_echo_reference(reference);
1342 } else {
1343 release_echo_reference(reference);
1344 }
1345 ALOGV("release_echo_reference");
1346 }
1347}
1348
1349static struct echo_reference_itfe *get_echo_reference(struct audio_device *adev,
1350 audio_format_t format __unused,
1351 uint32_t channel_count,
1352 uint32_t sampling_rate)
1353{
1354 ALOGV("%s: enter:)", __func__);
1355 put_echo_reference(adev, adev->echo_reference);
1356 /* echo reference is taken from the low latency output stream used
1357 * for voice use cases */
1358 if (adev->primary_output!= NULL && adev->primary_output->usecase == USECASE_AUDIO_PLAYBACK &&
1359 !adev->primary_output->standby) {
1360 struct audio_stream *stream =
1361 &adev->primary_output->stream.common;
1362 uint32_t wr_channel_count = audio_channel_count_from_out_mask(stream->get_channels(stream));
1363 uint32_t wr_sampling_rate = stream->get_sample_rate(stream);
1364 ALOGV("Calling create_echo_reference");
1365 int status = create_echo_reference(AUDIO_FORMAT_PCM_16_BIT,
1366 channel_count,
1367 sampling_rate,
1368 AUDIO_FORMAT_PCM_16_BIT,
1369 wr_channel_count,
1370 wr_sampling_rate,
1371 &adev->echo_reference);
1372 if (status == 0)
1373 android_atomic_inc(&adev->echo_reference_generation);
1374 }
1375 return adev->echo_reference;
1376}
1377
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001378static int get_playback_delay(struct stream_out *out,
1379 size_t frames,
1380 struct echo_reference_buffer *buffer)
1381{
1382 unsigned int kernel_frames;
1383 int status;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001384 struct pcm_device *pcm_device;
1385
1386 pcm_device = node_to_item(list_head(&out->pcm_dev_list),
1387 struct pcm_device, stream_list_node);
1388
1389 status = pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &buffer->time_stamp);
1390 if (status < 0) {
1391 buffer->time_stamp.tv_sec = 0;
1392 buffer->time_stamp.tv_nsec = 0;
1393 buffer->delay_ns = 0;
1394 ALOGV("get_playback_delay(): pcm_get_htimestamp error,"
1395 "setting playbackTimestamp to 0");
1396 return status;
1397 }
1398
1399 kernel_frames = pcm_get_buffer_size(pcm_device->pcm) - kernel_frames;
1400
1401 /* adjust render time stamp with delay added by current driver buffer.
1402 * Add the duration of current frame as we want the render time of the last
1403 * sample being written. */
1404 buffer->delay_ns = (long)(((int64_t)(kernel_frames + frames)* 1000000000)/
1405 out->config.rate);
1406 ALOGVV("get_playback_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5u], delay_ns: [%d],",
1407 buffer->time_stamp.tv_sec, buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns);
1408
1409 return 0;
1410}
1411
1412#define GET_COMMAND_STATUS(status, fct_status, cmd_status) \
1413 do { \
1414 if (fct_status != 0) \
1415 status = fct_status; \
1416 else if (cmd_status != 0) \
1417 status = cmd_status; \
1418 } while(0)
1419
1420static int in_configure_reverse(struct stream_in *in)
1421{
1422 int32_t cmd_status;
1423 uint32_t size = sizeof(int);
1424 effect_config_t config;
1425 int32_t status = 0;
1426 int32_t fct_status = 0;
1427 int i;
1428 ALOGV("%s: enter: in->num_preprocessors(%d)", __func__, in->num_preprocessors);
1429 if (in->num_preprocessors > 0) {
1430 config.inputCfg.channels = in->main_channels;
1431 config.outputCfg.channels = in->main_channels;
1432 config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1433 config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1434 config.inputCfg.samplingRate = in->requested_rate;
1435 config.outputCfg.samplingRate = in->requested_rate;
1436 config.inputCfg.mask =
1437 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1438 config.outputCfg.mask =
1439 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1440
1441 for (i = 0; i < in->num_preprocessors; i++)
1442 {
1443 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1444 continue;
1445 fct_status = (*(in->preprocessors[i].effect_itfe))->command(
1446 in->preprocessors[i].effect_itfe,
1447 EFFECT_CMD_SET_CONFIG_REVERSE,
1448 sizeof(effect_config_t),
1449 &config,
1450 &size,
1451 &cmd_status);
1452 ALOGV("%s: calling EFFECT_CMD_SET_CONFIG_REVERSE",__func__);
1453 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1454 }
1455 }
1456 return status;
1457}
1458
1459#define MAX_NUM_CHANNEL_CONFIGS 10
1460
1461static void in_read_audio_effect_channel_configs(struct stream_in *in __unused,
1462 struct effect_info_s *effect_info)
1463{
1464 /* size and format of the cmd are defined in hardware/audio_effect.h */
1465 effect_handle_t effect = effect_info->effect_itfe;
1466 uint32_t cmd_size = 2 * sizeof(uint32_t);
1467 uint32_t cmd[] = { EFFECT_FEATURE_AUX_CHANNELS, MAX_NUM_CHANNEL_CONFIGS };
1468 /* reply = status + number of configs (n) + n x channel_config_t */
1469 uint32_t reply_size =
1470 2 * sizeof(uint32_t) + (MAX_NUM_CHANNEL_CONFIGS * sizeof(channel_config_t));
1471 int32_t reply[reply_size];
1472 int32_t cmd_status;
1473
1474 ALOG_ASSERT((effect_info->num_channel_configs == 0),
1475 "in_read_audio_effect_channel_configs() num_channel_configs not cleared");
1476 ALOG_ASSERT((effect_info->channel_configs == NULL),
1477 "in_read_audio_effect_channel_configs() channel_configs not cleared");
1478
1479 /* if this command is not supported, then the effect is supposed to return -EINVAL.
1480 * This error will be interpreted as if the effect supports the main_channels but does not
1481 * support any aux_channels */
1482 cmd_status = (*effect)->command(effect,
1483 EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS,
1484 cmd_size,
1485 (void*)&cmd,
1486 &reply_size,
1487 (void*)&reply);
1488
1489 if (cmd_status != 0) {
1490 ALOGV("in_read_audio_effect_channel_configs(): "
1491 "fx->command returned %d", cmd_status);
1492 return;
1493 }
1494
1495 if (reply[0] != 0) {
1496 ALOGW("in_read_audio_effect_channel_configs(): "
1497 "command EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS error %d num configs %d",
1498 reply[0], (reply[0] == -ENOMEM) ? reply[1] : MAX_NUM_CHANNEL_CONFIGS);
1499 return;
1500 }
1501
1502 /* the feature is not supported */
1503 ALOGV("in_read_audio_effect_channel_configs()(): "
1504 "Feature supported and adding %d channel configs to the list", reply[1]);
1505 effect_info->num_channel_configs = reply[1];
1506 effect_info->channel_configs =
1507 (channel_config_t *) malloc(sizeof(channel_config_t) * reply[1]); /* n x configs */
1508 memcpy(effect_info->channel_configs, (reply + 2), sizeof(channel_config_t) * reply[1]);
1509}
1510
1511
1512#define NUM_IN_AUX_CNL_CONFIGS 2
1513static const channel_config_t in_aux_cnl_configs[NUM_IN_AUX_CNL_CONFIGS] = {
1514 { AUDIO_CHANNEL_IN_FRONT , AUDIO_CHANNEL_IN_BACK},
1515 { AUDIO_CHANNEL_IN_STEREO , AUDIO_CHANNEL_IN_RIGHT}
1516};
1517static uint32_t in_get_aux_channels(struct stream_in *in)
1518{
1519 int i;
1520 channel_config_t new_chcfg = {0, 0};
1521
1522 if (in->num_preprocessors == 0)
1523 return 0;
1524
1525 /* do not enable dual mic configurations when capturing from other microphones than
1526 * main or sub */
1527 if (!(in->devices & (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_BACK_MIC)))
1528 return 0;
1529
1530 /* retain most complex aux channels configuration compatible with requested main channels and
1531 * supported by audio driver and all pre processors */
1532 for (i = 0; i < NUM_IN_AUX_CNL_CONFIGS; i++) {
1533 const channel_config_t *cur_chcfg = &in_aux_cnl_configs[i];
1534 if (cur_chcfg->main_channels == in->main_channels) {
1535 size_t match_cnt;
1536 size_t idx_preproc;
1537 for (idx_preproc = 0, match_cnt = 0;
1538 /* no need to continue if at least one preprocessor doesn't match */
1539 idx_preproc < (size_t)in->num_preprocessors && match_cnt == idx_preproc;
1540 idx_preproc++) {
1541 struct effect_info_s *effect_info = &in->preprocessors[idx_preproc];
1542 size_t idx_chcfg;
1543
1544 for (idx_chcfg = 0; idx_chcfg < effect_info->num_channel_configs; idx_chcfg++) {
1545 if (memcmp(effect_info->channel_configs + idx_chcfg,
1546 cur_chcfg,
1547 sizeof(channel_config_t)) == 0) {
1548 match_cnt++;
1549 break;
1550 }
1551 }
1552 }
1553 /* if all preprocessors match, we have a candidate */
1554 if (match_cnt == (size_t)in->num_preprocessors) {
1555 /* retain most complex aux channels configuration */
1556 if (audio_channel_count_from_in_mask(cur_chcfg->aux_channels) > audio_channel_count_from_in_mask(new_chcfg.aux_channels)) {
1557 new_chcfg = *cur_chcfg;
1558 }
1559 }
1560 }
1561 }
1562
1563 ALOGV("in_get_aux_channels(): return %04x", new_chcfg.aux_channels);
1564
1565 return new_chcfg.aux_channels;
1566}
1567
1568static int in_configure_effect_channels(effect_handle_t effect,
1569 channel_config_t *channel_config)
1570{
1571 int status = 0;
1572 int fct_status;
1573 int32_t cmd_status;
1574 uint32_t reply_size;
1575 effect_config_t config;
1576 uint32_t cmd[(sizeof(uint32_t) + sizeof(channel_config_t) - 1) / sizeof(uint32_t) + 1];
1577
1578 ALOGV("in_configure_effect_channels(): configure effect with channels: [%04x][%04x]",
1579 channel_config->main_channels,
1580 channel_config->aux_channels);
1581
1582 config.inputCfg.mask = EFFECT_CONFIG_CHANNELS;
1583 config.outputCfg.mask = EFFECT_CONFIG_CHANNELS;
1584 reply_size = sizeof(effect_config_t);
1585 fct_status = (*effect)->command(effect,
1586 EFFECT_CMD_GET_CONFIG,
1587 0,
1588 NULL,
1589 &reply_size,
1590 &config);
1591 if (fct_status != 0) {
1592 ALOGE("in_configure_effect_channels(): EFFECT_CMD_GET_CONFIG failed");
1593 return fct_status;
1594 }
1595
1596 config.inputCfg.channels = channel_config->main_channels | channel_config->aux_channels;
1597 config.outputCfg.channels = config.inputCfg.channels;
1598 reply_size = sizeof(uint32_t);
1599 fct_status = (*effect)->command(effect,
1600 EFFECT_CMD_SET_CONFIG,
1601 sizeof(effect_config_t),
1602 &config,
1603 &reply_size,
1604 &cmd_status);
1605 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1606
1607 cmd[0] = EFFECT_FEATURE_AUX_CHANNELS;
1608 memcpy(cmd + 1, channel_config, sizeof(channel_config_t));
1609 reply_size = sizeof(uint32_t);
1610 fct_status = (*effect)->command(effect,
1611 EFFECT_CMD_SET_FEATURE_CONFIG,
1612 sizeof(cmd), //sizeof(uint32_t) + sizeof(channel_config_t),
1613 cmd,
1614 &reply_size,
1615 &cmd_status);
1616 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1617
1618 /* some implementations need to be re-enabled after a config change */
1619 reply_size = sizeof(uint32_t);
1620 fct_status = (*effect)->command(effect,
1621 EFFECT_CMD_ENABLE,
1622 0,
1623 NULL,
1624 &reply_size,
1625 &cmd_status);
1626 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1627
1628 return status;
1629}
1630
1631static int in_reconfigure_channels(struct stream_in *in,
1632 effect_handle_t effect,
1633 channel_config_t *channel_config,
1634 bool config_changed) {
1635
1636 int status = 0;
1637
1638 ALOGV("in_reconfigure_channels(): config_changed %d effect %p",
1639 config_changed, effect);
1640
1641 /* if config changed, reconfigure all previously added effects */
1642 if (config_changed) {
1643 int i;
1644 ALOGV("%s: config_changed (%d)", __func__, config_changed);
1645 for (i = 0; i < in->num_preprocessors; i++)
1646 {
1647 int cur_status = in_configure_effect_channels(in->preprocessors[i].effect_itfe,
1648 channel_config);
1649 ALOGV("%s: in_configure_effect_channels i=(%d), [main_channel,aux_channel]=[%d|%d], status=%d",
1650 __func__, i, channel_config->main_channels, channel_config->aux_channels, cur_status);
1651 if (cur_status != 0) {
1652 ALOGV("in_reconfigure_channels(): error %d configuring effect "
1653 "%d with channels: [%04x][%04x]",
1654 cur_status,
1655 i,
1656 channel_config->main_channels,
1657 channel_config->aux_channels);
1658 status = cur_status;
1659 }
1660 }
1661 } else if (effect != NULL && channel_config->aux_channels) {
1662 /* if aux channels config did not change but aux channels are present,
1663 * we still need to configure the effect being added */
1664 status = in_configure_effect_channels(effect, channel_config);
1665 }
1666 return status;
1667}
1668
1669static void in_update_aux_channels(struct stream_in *in,
1670 effect_handle_t effect)
1671{
1672 uint32_t aux_channels;
1673 channel_config_t channel_config;
1674 int status;
1675
1676 aux_channels = in_get_aux_channels(in);
1677
1678 channel_config.main_channels = in->main_channels;
1679 channel_config.aux_channels = aux_channels;
1680 status = in_reconfigure_channels(in,
1681 effect,
1682 &channel_config,
1683 (aux_channels != in->aux_channels));
1684
1685 if (status != 0) {
1686 ALOGV("in_update_aux_channels(): in_reconfigure_channels error %d", status);
1687 /* resetting aux channels configuration */
1688 aux_channels = 0;
1689 channel_config.aux_channels = 0;
1690 in_reconfigure_channels(in, effect, &channel_config, true);
1691 }
1692 ALOGV("%s: aux_channels=%d, in->aux_channels_changed=%d", __func__, aux_channels, in->aux_channels_changed);
1693 if (in->aux_channels != aux_channels) {
1694 in->aux_channels_changed = true;
1695 in->aux_channels = aux_channels;
1696 do_in_standby_l(in);
1697 }
1698}
1699#endif
1700
1701/* This function reads PCM data and:
1702 * - resample if needed
1703 * - process if pre-processors are attached
1704 * - discard unwanted channels
1705 */
1706static ssize_t read_and_process_frames(struct stream_in *in, void* buffer, ssize_t frames)
1707{
1708 ssize_t frames_wr = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001709 size_t src_channels = in->config.channels;
1710 size_t dst_channels = audio_channel_count_from_in_mask(in->main_channels);
1711 int i;
1712 void *proc_buf_out;
1713 struct pcm_device *pcm_device;
1714 bool has_additional_channels = (dst_channels != src_channels) ? true : false;
1715#ifdef PREPROCESSING_ENABLED
Andreas Schneider5a2f1002017-02-09 10:59:04 +01001716 audio_buffer_t in_buf;
1717 audio_buffer_t out_buf;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001718 bool has_processing = (in->num_preprocessors != 0) ? true : false;
1719#endif
1720
1721 /* Additional channels might be added on top of main_channels:
1722 * - aux_channels (by processing effects)
1723 * - extra channels due to HW limitations
1724 * In case of additional channels, we cannot work inplace
1725 */
1726 if (has_additional_channels)
1727 proc_buf_out = in->proc_buf_out;
1728 else
1729 proc_buf_out = buffer;
1730
1731 if (list_empty(&in->pcm_dev_list)) {
1732 ALOGE("%s: pcm device list empty", __func__);
1733 return -EINVAL;
1734 }
1735
1736 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1737 struct pcm_device, stream_list_node);
1738
1739#ifdef PREPROCESSING_ENABLED
1740 if (has_processing) {
1741 /* since all the processing below is done in frames and using the config.channels
1742 * as the number of channels, no changes is required in case aux_channels are present */
1743 while (frames_wr < frames) {
1744 /* first reload enough frames at the end of process input buffer */
1745 if (in->proc_buf_frames < (size_t)frames) {
1746 ssize_t frames_rd;
1747 if (in->proc_buf_size < (size_t)frames) {
1748 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1749 in->proc_buf_size = (size_t)frames;
1750 in->proc_buf_in = (int16_t *)realloc(in->proc_buf_in, size_in_bytes);
1751 ALOG_ASSERT((in->proc_buf_in != NULL),
1752 "process_frames() failed to reallocate proc_buf_in");
1753 if (has_additional_channels) {
1754 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1755 ALOG_ASSERT((in->proc_buf_out != NULL),
1756 "process_frames() failed to reallocate proc_buf_out");
1757 proc_buf_out = in->proc_buf_out;
1758 }
1759 }
1760 frames_rd = read_frames(in,
1761 in->proc_buf_in +
1762 in->proc_buf_frames * in->config.channels,
1763 frames - in->proc_buf_frames);
1764 if (frames_rd < 0) {
1765 /* Return error code */
1766 frames_wr = frames_rd;
1767 break;
1768 }
1769 in->proc_buf_frames += frames_rd;
1770 }
1771
1772 if (in->echo_reference != NULL) {
1773 push_echo_reference(in, in->proc_buf_frames);
1774 }
1775
1776 /* in_buf.frameCount and out_buf.frameCount indicate respectively
1777 * the maximum number of frames to be consumed and produced by process() */
1778 in_buf.frameCount = in->proc_buf_frames;
1779 in_buf.s16 = in->proc_buf_in;
1780 out_buf.frameCount = frames - frames_wr;
1781 out_buf.s16 = (int16_t *)proc_buf_out + frames_wr * in->config.channels;
1782
1783 /* FIXME: this works because of current pre processing library implementation that
1784 * does the actual process only when the last enabled effect process is called.
1785 * The generic solution is to have an output buffer for each effect and pass it as
1786 * input to the next.
1787 */
1788 for (i = 0; i < in->num_preprocessors; i++) {
1789 (*in->preprocessors[i].effect_itfe)->process(in->preprocessors[i].effect_itfe,
1790 &in_buf,
1791 &out_buf);
1792 }
1793
1794 /* process() has updated the number of frames consumed and produced in
1795 * in_buf.frameCount and out_buf.frameCount respectively
1796 * move remaining frames to the beginning of in->proc_buf_in */
1797 in->proc_buf_frames -= in_buf.frameCount;
1798
1799 if (in->proc_buf_frames) {
1800 memcpy(in->proc_buf_in,
1801 in->proc_buf_in + in_buf.frameCount * in->config.channels,
1802 in->proc_buf_frames * in->config.channels * sizeof(int16_t));
1803 }
1804
1805 /* if not enough frames were passed to process(), read more and retry. */
1806 if (out_buf.frameCount == 0) {
1807 ALOGW("No frames produced by preproc");
1808 continue;
1809 }
1810
1811 if ((frames_wr + (ssize_t)out_buf.frameCount) <= frames) {
1812 frames_wr += out_buf.frameCount;
1813 } else {
1814 /* The effect does not comply to the API. In theory, we should never end up here! */
1815 ALOGE("preprocessing produced too many frames: %d + %zd > %d !",
1816 (unsigned int)frames_wr, out_buf.frameCount, (unsigned int)frames);
1817 frames_wr = frames;
1818 }
1819 }
1820 }
1821 else
1822#endif //PREPROCESSING_ENABLED
1823 {
1824 /* No processing effects attached */
1825 if (has_additional_channels) {
1826 /* With additional channels, we cannot use original buffer */
1827 if (in->proc_buf_size < (size_t)frames) {
1828 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1829 in->proc_buf_size = (size_t)frames;
1830 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1831 ALOG_ASSERT((in->proc_buf_out != NULL),
1832 "process_frames() failed to reallocate proc_buf_out");
1833 proc_buf_out = in->proc_buf_out;
1834 }
1835 }
1836 frames_wr = read_frames(in, proc_buf_out, frames);
1837 }
1838
1839 /* Remove all additional channels that have been added on top of main_channels:
1840 * - aux_channels
1841 * - extra channels from HW due to HW limitations
1842 * Assumption is made that the channels are interleaved and that the main
1843 * channels are first. */
1844
1845 if (has_additional_channels)
1846 {
1847 int16_t* src_buffer = (int16_t *)proc_buf_out;
1848 int16_t* dst_buffer = (int16_t *)buffer;
1849
1850 if (dst_channels == 1) {
1851 for (i = frames_wr; i > 0; i--)
1852 {
1853 *dst_buffer++ = *src_buffer;
1854 src_buffer += src_channels;
1855 }
1856 } else {
1857 for (i = frames_wr; i > 0; i--)
1858 {
1859 memcpy(dst_buffer, src_buffer, dst_channels*sizeof(int16_t));
1860 dst_buffer += dst_channels;
1861 src_buffer += src_channels;
1862 }
1863 }
1864 }
1865
1866 return frames_wr;
1867}
1868
1869static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
1870 struct resampler_buffer* buffer)
1871{
1872 struct stream_in *in;
1873 struct pcm_device *pcm_device;
1874
1875 if (buffer_provider == NULL || buffer == NULL)
1876 return -EINVAL;
1877
1878 in = (struct stream_in *)((char *)buffer_provider -
1879 offsetof(struct stream_in, buf_provider));
1880
1881 if (list_empty(&in->pcm_dev_list)) {
1882 buffer->raw = NULL;
1883 buffer->frame_count = 0;
1884 in->read_status = -ENODEV;
1885 return -ENODEV;
1886 }
1887
1888 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1889 struct pcm_device, stream_list_node);
1890
1891 if (in->read_buf_frames == 0) {
1892 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, in->config.period_size);
1893 if (in->read_buf_size < in->config.period_size) {
1894 in->read_buf_size = in->config.period_size;
1895 in->read_buf = (int16_t *) realloc(in->read_buf, size_in_bytes);
1896 ALOG_ASSERT((in->read_buf != NULL),
1897 "get_next_buffer() failed to reallocate read_buf");
1898 }
1899
1900 in->read_status = pcm_read(pcm_device->pcm, (void*)in->read_buf, size_in_bytes);
1901
1902 if (in->read_status != 0) {
1903 ALOGE("get_next_buffer() pcm_read error %d", in->read_status);
1904 buffer->raw = NULL;
1905 buffer->frame_count = 0;
1906 return in->read_status;
1907 }
1908 in->read_buf_frames = in->config.period_size;
1909
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001910 }
1911
1912 buffer->frame_count = (buffer->frame_count > in->read_buf_frames) ?
1913 in->read_buf_frames : buffer->frame_count;
1914 buffer->i16 = in->read_buf + (in->config.period_size - in->read_buf_frames) *
1915 in->config.channels;
1916 return in->read_status;
1917}
1918
1919static void release_buffer(struct resampler_buffer_provider *buffer_provider,
1920 struct resampler_buffer* buffer)
1921{
1922 struct stream_in *in;
1923
1924 if (buffer_provider == NULL || buffer == NULL)
1925 return;
1926
1927 in = (struct stream_in *)((char *)buffer_provider -
1928 offsetof(struct stream_in, buf_provider));
1929
1930 in->read_buf_frames -= buffer->frame_count;
1931}
1932
1933/* read_frames() reads frames from kernel driver, down samples to capture rate
1934 * if necessary and output the number of frames requested to the buffer specified */
1935static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames)
1936{
1937 ssize_t frames_wr = 0;
1938
1939 struct pcm_device *pcm_device;
1940
1941 if (list_empty(&in->pcm_dev_list)) {
1942 ALOGE("%s: pcm device list empty", __func__);
1943 return -EINVAL;
1944 }
1945
1946 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1947 struct pcm_device, stream_list_node);
1948
1949 while (frames_wr < frames) {
1950 size_t frames_rd = frames - frames_wr;
1951 ALOGVV("%s: frames_rd: %zd, frames_wr: %zd, in->config.channels: %d",
1952 __func__,frames_rd,frames_wr,in->config.channels);
1953 if (in->resampler != NULL) {
1954 in->resampler->resample_from_provider(in->resampler,
1955 (int16_t *)((char *)buffer +
1956 pcm_frames_to_bytes(pcm_device->pcm, frames_wr)),
1957 &frames_rd);
1958 } else {
1959 struct resampler_buffer buf = {
Andreas Schneiderb7f32122017-01-31 08:18:34 +01001960 .raw = NULL,
1961 .frame_count = frames_rd,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001962 };
1963 get_next_buffer(&in->buf_provider, &buf);
1964 if (buf.raw != NULL) {
1965 memcpy((char *)buffer +
1966 pcm_frames_to_bytes(pcm_device->pcm, frames_wr),
1967 buf.raw,
1968 pcm_frames_to_bytes(pcm_device->pcm, buf.frame_count));
1969 frames_rd = buf.frame_count;
1970 }
1971 release_buffer(&in->buf_provider, &buf);
1972 }
1973 /* in->read_status is updated by getNextBuffer() also called by
1974 * in->resampler->resample_from_provider() */
1975 if (in->read_status != 0)
1976 return in->read_status;
1977
1978 frames_wr += frames_rd;
1979 }
1980 return frames_wr;
1981}
1982
1983static int in_release_pcm_devices(struct stream_in *in)
1984{
1985 struct pcm_device *pcm_device;
1986 struct listnode *node;
1987 struct listnode *next;
1988
1989 list_for_each_safe(node, next, &in->pcm_dev_list) {
1990 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
1991 list_remove(node);
1992 free(pcm_device);
1993 }
1994
1995 return 0;
1996}
1997
1998static int stop_input_stream(struct stream_in *in)
1999{
2000 struct audio_usecase *uc_info;
2001 struct audio_device *adev = in->dev;
2002
2003 adev->active_input = NULL;
2004 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2005 in->usecase, use_case_table[in->usecase]);
2006 uc_info = get_usecase_from_id(adev, in->usecase);
2007 if (uc_info == NULL) {
2008 ALOGE("%s: Could not find the usecase (%d) in the list",
2009 __func__, in->usecase);
2010 return -EINVAL;
2011 }
2012
2013 /* Disable the tx device */
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002014 disable_snd_device(adev, uc_info, uc_info->in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002015
2016 list_remove(&uc_info->adev_list_node);
2017 free(uc_info);
2018
2019 if (list_empty(&in->pcm_dev_list)) {
2020 ALOGE("%s: pcm device list empty", __func__);
2021 return -EINVAL;
2022 }
2023
2024 in_release_pcm_devices(in);
2025 list_init(&in->pcm_dev_list);
2026
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002027 ALOGV("%s: exit", __func__);
2028 return 0;
2029}
2030
2031static int start_input_stream(struct stream_in *in)
2032{
2033 /* Enable output device and stream routing controls */
2034 int ret = 0;
2035 bool recreate_resampler = false;
2036 struct audio_usecase *uc_info;
2037 struct audio_device *adev = in->dev;
2038 struct pcm_device_profile *pcm_profile;
2039 struct pcm_device *pcm_device;
2040
2041 ALOGV("%s: enter: usecase(%d)", __func__, in->usecase);
2042 adev->active_input = in;
2043 pcm_profile = get_pcm_device(in->usecase_type, in->devices);
2044 if (pcm_profile == NULL) {
2045 ALOGE("%s: Could not find PCM device id for the usecase(%d)",
2046 __func__, in->usecase);
2047 ret = -EINVAL;
2048 goto error_config;
2049 }
2050
2051 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002052 if (uc_info == NULL) {
2053 ret = -ENOMEM;
2054 goto error_config;
2055 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002056 uc_info->id = in->usecase;
2057 uc_info->type = PCM_CAPTURE;
2058 uc_info->stream = (struct audio_stream *)in;
2059 uc_info->devices = in->devices;
2060 uc_info->in_snd_device = SND_DEVICE_NONE;
2061 uc_info->out_snd_device = SND_DEVICE_NONE;
2062
2063 pcm_device = (struct pcm_device *)calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01002064 if (pcm_device == NULL) {
2065 free(uc_info);
2066 ret = -ENOMEM;
2067 goto error_config;
2068 }
2069
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002070 pcm_device->pcm_profile = pcm_profile;
2071 list_init(&in->pcm_dev_list);
2072 list_add_tail(&in->pcm_dev_list, &pcm_device->stream_list_node);
2073
2074 list_init(&uc_info->mixer_list);
2075 list_add_tail(&uc_info->mixer_list,
2076 &adev_get_mixer_for_card(adev,
2077 pcm_device->pcm_profile->card)->uc_list_node[uc_info->id]);
2078
2079 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2080
2081 select_devices(adev, in->usecase);
2082
2083 /* Config should be updated as profile can be changed between different calls
2084 * to this function:
2085 * - Trigger resampler creation
2086 * - Config needs to be updated */
2087 if (in->config.rate != pcm_profile->config.rate) {
2088 recreate_resampler = true;
2089 }
2090 in->config = pcm_profile->config;
2091
2092#ifdef PREPROCESSING_ENABLED
2093 if (in->aux_channels_changed) {
2094 in->config.channels = audio_channel_count_from_in_mask(in->main_channels | in->aux_channels);
2095 recreate_resampler = true;
2096 }
2097#endif
2098
2099 if (in->requested_rate != in->config.rate) {
2100 recreate_resampler = true;
2101 }
2102
2103 if (recreate_resampler) {
2104 if (in->resampler) {
2105 release_resampler(in->resampler);
2106 in->resampler = NULL;
2107 }
2108 in->buf_provider.get_next_buffer = get_next_buffer;
2109 in->buf_provider.release_buffer = release_buffer;
2110 ret = create_resampler(in->config.rate,
2111 in->requested_rate,
2112 in->config.channels,
2113 RESAMPLER_QUALITY_DEFAULT,
2114 &in->buf_provider,
2115 &in->resampler);
2116 }
2117
2118#ifdef PREPROCESSING_ENABLED
2119 if (in->enable_aec && in->echo_reference == NULL) {
2120 in->echo_reference = get_echo_reference(adev,
2121 AUDIO_FORMAT_PCM_16_BIT,
2122 audio_channel_count_from_in_mask(in->main_channels),
2123 in->requested_rate
2124 );
2125 }
2126
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002127#endif
2128
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002129 if (in->dev->voice.in_call) {
2130 ALOGV("%s: in_call, not handling PCMs", __func__);
2131 goto skip_pcm_handling;
2132 }
2133
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002134 /* Open the PCM device.
2135 * The HW is limited to support only the default pcm_profile settings.
2136 * As such a change in aux_channels will not have an effect.
2137 */
2138 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d, smp rate %d format %d, \
2139 period_size %d", __func__, pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
2140 pcm_device->pcm_profile->config.channels,pcm_device->pcm_profile->config.rate,
2141 pcm_device->pcm_profile->config.format, pcm_device->pcm_profile->config.period_size);
2142
stenkinevgeniy44335362018-05-07 18:00:13 +00002143 pcm_device->pcm = pcm_open(pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002144 PCM_IN | PCM_MONOTONIC, &pcm_device->pcm_profile->config);
2145
stenkinevgeniy44335362018-05-07 18:00:13 +00002146 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2147 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2148 pcm_close(pcm_device->pcm);
2149 pcm_device->pcm = NULL;
2150 ret = -EIO;
2151 goto error_open;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002152 }
2153
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002154skip_pcm_handling:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002155 /* force read and proc buffer reallocation in case of frame size or
2156 * channel count change */
2157 in->proc_buf_frames = 0;
2158 in->proc_buf_size = 0;
2159 in->read_buf_size = 0;
2160 in->read_buf_frames = 0;
2161
2162 /* if no supported sample rate is available, use the resampler */
2163 if (in->resampler) {
2164 in->resampler->reset(in->resampler);
2165 }
2166
2167 ALOGV("%s: exit", __func__);
2168 return ret;
2169
2170error_open:
2171 if (in->resampler) {
2172 release_resampler(in->resampler);
2173 in->resampler = NULL;
2174 }
2175 stop_input_stream(in);
2176
2177error_config:
2178 ALOGV("%s: exit: status(%d)", __func__, ret);
2179 adev->active_input = NULL;
2180 return ret;
2181}
2182
2183void lock_input_stream(struct stream_in *in)
2184{
2185 pthread_mutex_lock(&in->pre_lock);
2186 pthread_mutex_lock(&in->lock);
2187 pthread_mutex_unlock(&in->pre_lock);
2188}
2189
2190void lock_output_stream(struct stream_out *out)
2191{
2192 pthread_mutex_lock(&out->pre_lock);
2193 pthread_mutex_lock(&out->lock);
2194 pthread_mutex_unlock(&out->pre_lock);
2195}
2196
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002197static int uc_release_pcm_devices(struct audio_usecase *usecase)
2198{
2199 struct stream_out *out = (struct stream_out *)usecase->stream;
2200 struct pcm_device *pcm_device;
2201 struct listnode *node;
2202 struct listnode *next;
2203
2204 list_for_each_safe(node, next, &out->pcm_dev_list) {
2205 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2206 list_remove(node);
2207 free(pcm_device);
2208 }
2209 list_init(&usecase->mixer_list);
2210
2211 return 0;
2212}
2213
2214static int uc_select_pcm_devices(struct audio_usecase *usecase)
2215
2216{
2217 struct stream_out *out = (struct stream_out *)usecase->stream;
2218 struct pcm_device *pcm_device;
2219 struct pcm_device_profile *pcm_profile;
2220 struct mixer_card *mixer_card;
2221 audio_devices_t devices = usecase->devices;
2222
2223 list_init(&usecase->mixer_list);
2224 list_init(&out->pcm_dev_list);
2225
2226 while ((pcm_profile = get_pcm_device(usecase->type, devices)) != NULL) {
2227 pcm_device = calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01002228 if (pcm_device == NULL) {
2229 return -ENOMEM;
2230 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002231 pcm_device->pcm_profile = pcm_profile;
2232 list_add_tail(&out->pcm_dev_list, &pcm_device->stream_list_node);
2233 mixer_card = uc_get_mixer_for_card(usecase, pcm_profile->card);
2234 if (mixer_card == NULL) {
2235 mixer_card = adev_get_mixer_for_card(out->dev, pcm_profile->card);
2236 list_add_tail(&usecase->mixer_list, &mixer_card->uc_list_node[usecase->id]);
2237 }
2238 devices &= ~pcm_profile->devices;
2239 }
2240
2241 return 0;
2242}
2243
2244static int out_close_pcm_devices(struct stream_out *out)
2245{
2246 struct pcm_device *pcm_device;
2247 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002248
2249 list_for_each(node, &out->pcm_dev_list) {
2250 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002251 if (pcm_device->pcm) {
2252 pcm_close(pcm_device->pcm);
2253 pcm_device->pcm = NULL;
2254 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002255 }
2256
2257 return 0;
2258}
2259
2260static int out_open_pcm_devices(struct stream_out *out)
2261{
2262 struct pcm_device *pcm_device;
2263 struct listnode *node;
2264 int ret = 0;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002265 int pcm_device_card;
2266 int pcm_device_id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002267
2268 list_for_each(node, &out->pcm_dev_list) {
2269 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002270 pcm_device_card = pcm_device->pcm_profile->card;
2271 pcm_device_id = pcm_device->pcm_profile->id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002272
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002273 if (out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
2274 pcm_device_id = pcm_device_deep_buffer.id;
2275
2276 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
2277 __func__, pcm_device_card, pcm_device_id);
2278
2279 pcm_device->pcm = pcm_open(pcm_device_card, pcm_device_id,
stenkinevgeniy2ef158a2018-05-08 06:52:05 +00002280 PCM_OUT | PCM_MONOTONIC, &out->config);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002281
2282 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2283 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2284 pcm_device->pcm = NULL;
2285 ret = -EIO;
2286 goto error_open;
2287 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002288 }
2289 return ret;
2290
2291error_open:
2292 out_close_pcm_devices(out);
2293 return ret;
2294}
2295
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002296int disable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002297{
2298 struct audio_device *adev = out->dev;
2299 struct audio_usecase *uc_info;
2300
2301 uc_info = get_usecase_from_id(adev, out->usecase);
2302 if (uc_info == NULL) {
2303 ALOGE("%s: Could not find the usecase (%d) in the list",
2304 __func__, out->usecase);
2305 return -EINVAL;
2306 }
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002307 disable_snd_device(adev, uc_info, uc_info->out_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002308 uc_release_pcm_devices(uc_info);
2309 list_remove(&uc_info->adev_list_node);
2310 free(uc_info);
2311
2312 return 0;
2313}
2314
Andreas Schneider56204f62017-01-31 08:17:32 +01002315int enable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002316{
2317 struct audio_device *adev = out->dev;
2318 struct audio_usecase *uc_info;
2319
2320 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002321 if (uc_info == NULL) {
2322 return -ENOMEM;
2323 }
2324
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002325 uc_info->id = out->usecase;
2326 uc_info->type = PCM_PLAYBACK;
2327 uc_info->stream = (struct audio_stream *)out;
2328 uc_info->devices = out->devices;
2329 uc_info->in_snd_device = SND_DEVICE_NONE;
2330 uc_info->out_snd_device = SND_DEVICE_NONE;
2331 uc_select_pcm_devices(uc_info);
2332
2333 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2334 select_devices(adev, out->usecase);
Andreas Schneider56204f62017-01-31 08:17:32 +01002335
2336 return 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002337}
2338
2339static int stop_output_stream(struct stream_out *out)
2340{
2341 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002342 bool do_disable = true;
2343
2344 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2345 out->usecase, use_case_table[out->usecase]);
2346
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002347 stop_output_offload_stream(out, &do_disable);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002348
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002349 if (do_disable)
2350 ret = disable_output_path_l(out);
2351
2352 ALOGV("%s: exit: status(%d)", __func__, ret);
2353 return ret;
2354}
2355
2356static int start_output_stream(struct stream_out *out)
2357{
2358 int ret = 0;
2359 struct audio_device *adev = out->dev;
2360
2361 ALOGV("%s: enter: usecase(%d: %s) devices(%#x) channels(%d)",
2362 __func__, out->usecase, use_case_table[out->usecase], out->devices, out->config.channels);
2363
Andreas Schneider56204f62017-01-31 08:17:32 +01002364 ret = enable_output_path_l(out);
2365 if (ret != 0) {
2366 goto error_config;
2367 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002368
2369 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2370 out->compr = NULL;
2371 ret = out_open_pcm_devices(out);
2372 if (ret != 0)
2373 goto error_open;
2374#ifdef PREPROCESSING_ENABLED
2375 out->echo_reference = NULL;
2376 out->echo_reference_generation = adev->echo_reference_generation;
2377 if (adev->echo_reference != NULL)
2378 out->echo_reference = adev->echo_reference;
2379#endif
2380 } else {
2381 out->compr = compress_open(COMPRESS_CARD, COMPRESS_DEVICE,
2382 COMPRESS_IN, &out->compr_config);
2383 if (out->compr && !is_compress_ready(out->compr)) {
2384 ALOGE("%s: %s", __func__, compress_get_error(out->compr));
2385 compress_close(out->compr);
2386 out->compr = NULL;
2387 ret = -EIO;
2388 goto error_open;
2389 }
2390 if (out->offload_callback)
2391 compress_nonblock(out->compr, out->non_blocking);
2392
2393 if (adev->offload_fx_start_output != NULL)
2394 adev->offload_fx_start_output(out->handle);
2395 }
2396 ALOGV("%s: exit", __func__);
2397 return 0;
2398error_open:
2399 stop_output_stream(out);
2400error_config:
2401 return ret;
2402}
2403
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002404int stop_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002405{
2406 struct audio_usecase *uc_info;
2407
2408 ALOGV("%s: enter", __func__);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002409 adev->voice.in_call = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002410
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002411 stop_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002412
2413 uc_info = get_usecase_from_id(adev, USECASE_VOICE_CALL);
2414 if (uc_info == NULL) {
2415 ALOGE("%s: Could not find the usecase (%d) in the list",
2416 __func__, USECASE_VOICE_CALL);
2417 return -EINVAL;
2418 }
2419
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002420 disable_snd_device(adev, uc_info, uc_info->out_snd_device);
2421 disable_snd_device(adev, uc_info, uc_info->in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002422
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002423 list_remove(&uc_info->adev_list_node);
2424 free(uc_info);
2425
2426 ALOGV("%s: exit", __func__);
2427 return 0;
2428}
2429
2430/* always called with adev lock held */
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002431int start_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002432{
2433 struct audio_usecase *uc_info;
Andreas Schneider56204f62017-01-31 08:17:32 +01002434 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002435
2436 ALOGV("%s: enter", __func__);
2437
2438 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002439 if (uc_info == NULL) {
2440 ret = -ENOMEM;
2441 goto exit;
2442 }
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002443 /*
2444 * We set this early so that functions called after this is being set
2445 * can use it. It is e.g. needed in select_devices() to inform the RILD
2446 * which output device we use.
2447 */
2448 adev->voice.in_call = true;
Andreas Schneider56204f62017-01-31 08:17:32 +01002449
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002450 uc_info->id = USECASE_VOICE_CALL;
2451 uc_info->type = VOICE_CALL;
2452 uc_info->stream = (struct audio_stream *)adev->primary_output;
2453 uc_info->devices = adev->primary_output->devices;
2454 uc_info->in_snd_device = SND_DEVICE_NONE;
2455 uc_info->out_snd_device = SND_DEVICE_NONE;
2456
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002457 list_init(&uc_info->mixer_list);
2458 list_add_tail(&uc_info->mixer_list,
2459 &adev_get_mixer_for_card(adev, SOUND_CARD)->uc_list_node[uc_info->id]);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002460
2461 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2462
2463 select_devices(adev, USECASE_VOICE_CALL);
2464
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002465 start_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002466
2467 /* set cached volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002468 set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002469
Andreas Schneider56204f62017-01-31 08:17:32 +01002470exit:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002471 ALOGV("%s: exit", __func__);
Andreas Schneider56204f62017-01-31 08:17:32 +01002472 return ret;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002473}
2474
2475static int check_input_parameters(uint32_t sample_rate,
2476 audio_format_t format,
2477 int channel_count)
2478{
2479 if (format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL;
2480
2481 if ((channel_count < 1) || (channel_count > 2)) return -EINVAL;
2482
2483 switch (sample_rate) {
2484 case 8000:
2485 case 11025:
2486 case 12000:
2487 case 16000:
2488 case 22050:
2489 case 24000:
2490 case 32000:
2491 case 44100:
2492 case 48000:
2493 break;
2494 default:
2495 return -EINVAL;
2496 }
2497
2498 return 0;
2499}
2500
2501static size_t get_input_buffer_size(uint32_t sample_rate,
2502 audio_format_t format,
2503 int channel_count,
2504 usecase_type_t usecase_type,
2505 audio_devices_t devices)
2506{
2507 size_t size = 0;
2508 struct pcm_device_profile *pcm_profile;
2509
2510 if (check_input_parameters(sample_rate, format, channel_count) != 0)
2511 return 0;
2512
2513 pcm_profile = get_pcm_device(usecase_type, devices);
2514 if (pcm_profile == NULL)
2515 return 0;
2516
2517 /*
2518 * take resampling into account and return the closest majoring
2519 * multiple of 16 frames, as audioflinger expects audio buffers to
2520 * be a multiple of 16 frames
2521 */
2522 size = (pcm_profile->config.period_size * sample_rate) / pcm_profile->config.rate;
2523 size = ((size + 15) / 16) * 16;
2524
2525 return (size * channel_count * audio_bytes_per_sample(format));
2526
2527}
2528
2529static uint32_t out_get_sample_rate(const struct audio_stream *stream)
2530{
2531 struct stream_out *out = (struct stream_out *)stream;
2532
2533 return out->sample_rate;
2534}
2535
2536static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
2537{
2538 (void)stream;
2539 (void)rate;
2540 return -ENOSYS;
2541}
2542
2543static size_t out_get_buffer_size(const struct audio_stream *stream)
2544{
2545 struct stream_out *out = (struct stream_out *)stream;
2546
2547 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2548 return out->compr_config.fragment_size;
2549 }
2550
2551 return out->config.period_size *
2552 audio_stream_out_frame_size((const struct audio_stream_out *)stream);
2553}
2554
2555static uint32_t out_get_channels(const struct audio_stream *stream)
2556{
2557 struct stream_out *out = (struct stream_out *)stream;
2558
2559 return out->channel_mask;
2560}
2561
2562static audio_format_t out_get_format(const struct audio_stream *stream)
2563{
2564 struct stream_out *out = (struct stream_out *)stream;
2565
2566 return out->format;
2567}
2568
2569static int out_set_format(struct audio_stream *stream, audio_format_t format)
2570{
2571 (void)stream;
2572 (void)format;
2573 return -ENOSYS;
2574}
2575
2576static int do_out_standby_l(struct stream_out *out)
2577{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002578 int status = 0;
2579
2580 out->standby = true;
2581 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2582 out_close_pcm_devices(out);
2583#ifdef PREPROCESSING_ENABLED
2584 /* stop writing to echo reference */
2585 if (out->echo_reference != NULL) {
2586 out->echo_reference->write(out->echo_reference, NULL);
2587 if (out->echo_reference_generation != adev->echo_reference_generation) {
2588 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
2589 release_echo_reference(out->echo_reference);
2590 out->echo_reference_generation = adev->echo_reference_generation;
2591 }
2592 out->echo_reference = NULL;
2593 }
2594#endif
2595 } else {
2596 stop_compressed_output_l(out);
2597 out->gapless_mdata.encoder_delay = 0;
2598 out->gapless_mdata.encoder_padding = 0;
2599 if (out->compr != NULL) {
2600 compress_close(out->compr);
2601 out->compr = NULL;
2602 }
2603 }
2604 status = stop_output_stream(out);
2605
2606 return status;
2607}
2608
2609static int out_standby(struct audio_stream *stream)
2610{
2611 struct stream_out *out = (struct stream_out *)stream;
2612 struct audio_device *adev = out->dev;
2613
2614 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2615 out->usecase, use_case_table[out->usecase]);
2616 lock_output_stream(out);
2617 if (!out->standby) {
2618 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002619 amplifier_output_stream_standby((struct audio_stream_out *) stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002620 do_out_standby_l(out);
2621 pthread_mutex_unlock(&adev->lock);
2622 }
2623 pthread_mutex_unlock(&out->lock);
2624 ALOGV("%s: exit", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01002625
2626 // out->last_write_time_us = 0; unnecessary as a stale write time has same effect
2627
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002628 return 0;
2629}
2630
2631static int out_dump(const struct audio_stream *stream, int fd)
2632{
2633 (void)stream;
2634 (void)fd;
2635
2636 return 0;
2637}
2638
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002639static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
2640{
2641 struct stream_out *out = (struct stream_out *)stream;
2642 struct audio_device *adev = out->dev;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002643 struct listnode *node;
2644 struct str_parms *parms;
2645 char value[32];
2646 int ret, val = 0;
2647 struct audio_usecase *uc_info;
2648 bool do_standby = false;
2649 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002650#ifdef PREPROCESSING_ENABLED
2651 struct stream_in *in = NULL; /* if non-NULL, then force input to standby */
2652#endif
2653
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002654 ALOGV("%s: enter: usecase(%d: %s) kvpairs: %s out->devices(%#x) "
2655 "adev->mode(%#x)",
2656 __func__, out->usecase, use_case_table[out->usecase], kvpairs,
2657 out->devices, adev->mode);
2658
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002659 parms = str_parms_create_str(kvpairs);
2660 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
2661 if (ret >= 0) {
2662 val = atoi(value);
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002663
2664 ALOGV("%s: routing: usecase(%d: %s) devices=(%#x) adev->mode(%#x)",
2665 __func__, out->usecase, use_case_table[out->usecase], val,
2666 adev->mode);
2667
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002668 pthread_mutex_lock(&adev->lock_inputs);
2669 lock_output_stream(out);
2670 pthread_mutex_lock(&adev->lock);
2671#ifdef PREPROCESSING_ENABLED
2672 if (((int)out->devices != val) && (val != 0) && (!out->standby) &&
2673 (out->usecase == USECASE_AUDIO_PLAYBACK)) {
2674 /* reset active input:
2675 * - to attach the echo reference
2676 * - because a change in output device may change mic settings */
2677 if (adev->active_input && (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
2678 adev->active_input->source == AUDIO_SOURCE_MIC)) {
2679 in = adev->active_input;
2680 }
2681 }
2682#endif
Christopher N. Hesse33affb82017-11-16 17:01:37 +01002683 if (val != SND_DEVICE_NONE) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002684 bool bt_sco_active = false;
2685
2686 if (out->devices & AUDIO_DEVICE_OUT_ALL_SCO) {
2687 bt_sco_active = true;
2688 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002689 out->devices = val;
2690
2691 if (!out->standby) {
2692 uc_info = get_usecase_from_id(adev, out->usecase);
2693 if (uc_info == NULL) {
2694 ALOGE("%s: Could not find the usecase (%d) in the list",
2695 __func__, out->usecase);
2696 } else {
2697 list_for_each(node, &out->pcm_dev_list) {
2698 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2699 if ((pcm_device->pcm_profile->devices & val) == 0)
2700 do_standby = true;
2701 val &= ~pcm_device->pcm_profile->devices;
2702 }
2703 if (val != 0)
2704 do_standby = true;
2705 }
2706 if (do_standby)
2707 do_out_standby_l(out);
2708 else {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002709 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
2710 out_set_offload_parameters(adev, uc_info);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002711 select_devices(adev, out->usecase);
2712 }
2713 }
2714
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002715 if ((adev->mode == AUDIO_MODE_IN_CALL) && !adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002716 (out == adev->primary_output)) {
2717 start_voice_call(adev);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002718 } else if ((adev->mode == AUDIO_MODE_IN_CALL) &&
2719 adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002720 (out == adev->primary_output)) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002721 /* Turn on bluetooth if needed */
2722 if ((out->devices & AUDIO_DEVICE_OUT_ALL_SCO) && !bt_sco_active) {
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002723 select_devices(adev, USECASE_VOICE_CALL);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002724 start_voice_session_bt_sco(adev->voice.session);
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002725 } else {
2726 /*
2727 * When we select different devices we need to restart the
2728 * voice call. The modem closes the stream on its end and
2729 * we do not get any output.
2730 */
2731 stop_voice_call(adev);
2732 start_voice_call(adev);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002733 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002734 }
2735 }
2736
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002737 pthread_mutex_unlock(&adev->lock);
2738 pthread_mutex_unlock(&out->lock);
2739#ifdef PREPROCESSING_ENABLED
2740 if (in) {
2741 /* The lock on adev->lock_inputs prevents input stream from being closed */
2742 lock_input_stream(in);
2743 pthread_mutex_lock(&adev->lock);
2744 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
2745 do_in_standby_l(in);
2746 pthread_mutex_unlock(&adev->lock);
2747 pthread_mutex_unlock(&in->lock);
2748 }
2749#endif
2750 pthread_mutex_unlock(&adev->lock_inputs);
2751 }
2752
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002753 amplifier_set_parameters(parms);
2754
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002755 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2756 parse_compress_metadata(out, parms);
2757 }
2758
2759 str_parms_destroy(parms);
2760
2761 if (ret > 0)
2762 ret = 0;
2763 ALOGV("%s: exit: code(%d)", __func__, ret);
2764 return ret;
2765}
2766
2767static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
2768{
2769 struct stream_out *out = (struct stream_out *)stream;
2770 struct str_parms *query = str_parms_create_str(keys);
2771 char *str;
2772 char value[256];
2773 struct str_parms *reply = str_parms_create();
2774 size_t i, j;
2775 int ret;
2776 bool first = true;
2777 ALOGV("%s: enter: keys - %s", __func__, keys);
2778 ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value));
2779 if (ret >= 0) {
2780 value[0] = '\0';
2781 i = 0;
2782 while (out->supported_channel_masks[i] != 0) {
2783 for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) {
2784 if (out_channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) {
2785 if (!first) {
2786 strcat(value, "|");
2787 }
2788 strcat(value, out_channels_name_to_enum_table[j].name);
2789 first = false;
2790 break;
2791 }
2792 }
2793 i++;
2794 }
2795 str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
2796 str = str_parms_to_str(reply);
2797 } else {
2798 str = strdup(keys);
2799 }
2800 str_parms_destroy(query);
2801 str_parms_destroy(reply);
2802 ALOGV("%s: exit: returns - %s", __func__, str);
2803 return str;
2804}
2805
2806static uint32_t out_get_latency(const struct audio_stream_out *stream)
2807{
2808 struct stream_out *out = (struct stream_out *)stream;
2809
2810 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
2811 return COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
2812
2813 return (out->config.period_count * out->config.period_size * 1000) /
2814 (out->config.rate);
2815}
2816
2817static int out_set_volume(struct audio_stream_out *stream, float left,
2818 float right)
2819{
2820 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002821
2822 if (out->usecase == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
2823 /* only take left channel into account: the API is for stereo anyway */
2824 out->muted = (left == 0.0f);
2825 return 0;
2826 } else if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002827 out_set_offload_volume(left, right);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002828 }
2829
2830 return -ENOSYS;
2831}
2832
Andreas Schneider3b643832017-01-31 11:48:22 +01002833#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002834static int fast_set_affinity(pid_t tid) {
2835 cpu_set_t cpu_set;
2836 int cpu_num;
2837 const char *irq_procfs = "/proc/asound/irq_affinity";
2838 FILE *fp;
2839
2840 if ((fp = fopen(irq_procfs, "r")) == NULL) {
2841 ALOGW("Procfs node %s not found", irq_procfs);
2842 return -1;
2843 }
2844
2845 if (fscanf(fp, "%d", &cpu_num) != 1) {
2846 ALOGW("Couldn't read CPU id from procfs node %s", irq_procfs);
2847 fclose(fp);
2848 return -1;
2849 }
2850 fclose(fp);
2851
2852 CPU_ZERO(&cpu_set);
2853 CPU_SET(cpu_num, &cpu_set);
2854 return sched_setaffinity(tid, sizeof(cpu_set), &cpu_set);
2855}
Andreas Schneider3b643832017-01-31 11:48:22 +01002856#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002857
2858static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
2859 size_t bytes)
2860{
2861 struct stream_out *out = (struct stream_out *)stream;
2862 struct audio_device *adev = out->dev;
2863 ssize_t ret = 0;
2864 struct pcm_device *pcm_device;
2865 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002866#ifdef PREPROCESSING_ENABLED
stenkinevgeniyd0a02c02018-05-08 07:17:53 +00002867 size_t frame_size = audio_stream_out_frame_size(stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002868 size_t in_frames = bytes / frame_size;
2869 size_t out_frames = in_frames;
2870 struct stream_in *in = NULL;
2871#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002872
2873 lock_output_stream(out);
2874
Andreas Schneider3b643832017-01-31 11:48:22 +01002875#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002876 if (out->usecase == USECASE_AUDIO_PLAYBACK && !out->is_fastmixer_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01002877 pid_t tid = gettid();
2878 int err;
2879
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002880 err = fast_set_affinity(tid);
2881 if (err < 0) {
2882 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
2883 }
2884 out->is_fastmixer_affinity_set = true;
2885 }
Andreas Schneider3b643832017-01-31 11:48:22 +01002886#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002887
2888 if (out->standby) {
2889#ifdef PREPROCESSING_ENABLED
2890 pthread_mutex_unlock(&out->lock);
2891 /* Prevent input stream from being closed */
2892 pthread_mutex_lock(&adev->lock_inputs);
2893 lock_output_stream(out);
2894 if (!out->standby) {
2895 pthread_mutex_unlock(&adev->lock_inputs);
2896 goto false_alarm;
2897 }
2898#endif
2899 pthread_mutex_lock(&adev->lock);
2900 ret = start_output_stream(out);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002901 if (ret == 0) {
2902 amplifier_output_stream_start(stream, out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD);
2903 }
2904
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002905 /* ToDo: If use case is compress offload should return 0 */
2906 if (ret != 0) {
2907 pthread_mutex_unlock(&adev->lock);
2908#ifdef PREPROCESSING_ENABLED
2909 pthread_mutex_unlock(&adev->lock_inputs);
2910#endif
2911 goto exit;
2912 }
2913 out->standby = false;
2914
2915#ifdef PREPROCESSING_ENABLED
2916 /* A change in output device may change the microphone selection */
2917 if (adev->active_input &&
2918 (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
2919 adev->active_input->source == AUDIO_SOURCE_MIC)) {
2920 in = adev->active_input;
2921 ALOGV("%s: enter:) force_input_standby true", __func__);
2922 }
2923#endif
2924 pthread_mutex_unlock(&adev->lock);
2925#ifdef PREPROCESSING_ENABLED
2926 if (!in) {
2927 /* Leave mutex locked iff in != NULL */
2928 pthread_mutex_unlock(&adev->lock_inputs);
2929 }
2930#endif
2931 }
Andreas Schneider5a2f1002017-02-09 10:59:04 +01002932#ifdef PREPROCESSING_ENABLED
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002933false_alarm:
Andreas Schneider5a2f1002017-02-09 10:59:04 +01002934#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002935
2936 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002937 ret = out_write_offload(stream, buffer, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002938 return ret;
2939 } else {
2940#ifdef PREPROCESSING_ENABLED
2941 if (android_atomic_acquire_load(&adev->echo_reference_generation)
2942 != out->echo_reference_generation) {
2943 pthread_mutex_lock(&adev->lock);
2944 if (out->echo_reference != NULL) {
2945 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
2946 release_echo_reference(out->echo_reference);
2947 }
2948 // note that adev->echo_reference_generation here can be different from the one
2949 // tested above but it doesn't matter as we now have the adev mutex and it is consistent
2950 // with what has been set by get_echo_reference() or put_echo_reference()
2951 out->echo_reference_generation = adev->echo_reference_generation;
2952 out->echo_reference = adev->echo_reference;
2953 ALOGV("%s: update echo reference generation %d", __func__,
2954 out->echo_reference_generation);
2955 pthread_mutex_unlock(&adev->lock);
2956 }
2957#endif
2958
2959 if (out->muted)
2960 memset((void *)buffer, 0, bytes);
2961 list_for_each(node, &out->pcm_dev_list) {
2962 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002963 if (pcm_device->pcm) {
2964#ifdef PREPROCESSING_ENABLED
2965 if (out->echo_reference != NULL && pcm_device->pcm_profile->devices != SND_DEVICE_OUT_SPEAKER) {
2966 struct echo_reference_buffer b;
2967 b.raw = (void *)buffer;
2968 b.frame_count = in_frames;
2969
2970 get_playback_delay(out, out_frames, &b);
2971 out->echo_reference->write(out->echo_reference, &b);
2972 }
2973#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002974 ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
stenkinevgeniyd0a02c02018-05-08 07:17:53 +00002975 pcm_device->status = pcm_write(pcm_device->pcm, (void *)buffer, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002976 if (pcm_device->status != 0)
2977 ret = pcm_device->status;
2978 }
2979 }
2980 if (ret == 0)
2981 out->written += bytes / (out->config.channels * sizeof(short));
2982 }
2983
2984exit:
2985 pthread_mutex_unlock(&out->lock);
2986
2987 if (ret != 0) {
2988 list_for_each(node, &out->pcm_dev_list) {
2989 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2990 if (pcm_device->pcm && pcm_device->status != 0)
2991 ALOGE("%s: error %zd - %s", __func__, ret, pcm_get_error(pcm_device->pcm));
2992 }
2993 out_standby(&out->stream.common);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01002994 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
2995 clock_gettime(CLOCK_MONOTONIC, &t);
2996 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
2997 const int64_t elapsed_time_since_last_write = now - out->last_write_time_us;
2998 int64_t sleep_time = bytes * 1000000LL / audio_stream_out_frame_size(stream) /
2999 out_get_sample_rate(&stream->common) - elapsed_time_since_last_write;
3000 if (sleep_time > 0) {
3001 usleep(sleep_time);
3002 } else {
3003 // we don't sleep when we exit standby (this is typical for a real alsa buffer).
3004 sleep_time = 0;
3005 }
3006 out->last_write_time_us = now + sleep_time;
3007 // last_write_time_us is an approximation of when the (simulated) alsa
3008 // buffer is believed completely full. The usleep above waits for more space
3009 // in the buffer, but by the end of the sleep the buffer is considered
3010 // topped-off.
3011 //
3012 // On the subsequent out_write(), we measure the elapsed time spent in
3013 // the mixer. This is subtracted from the sleep estimate based on frames,
3014 // thereby accounting for drain in the alsa buffer during mixing.
3015 // This is a crude approximation; we don't handle underruns precisely.
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003016 }
3017
3018#ifdef PREPROCESSING_ENABLED
3019 if (in) {
3020 /* The lock on adev->lock_inputs prevents input stream from being closed */
3021 lock_input_stream(in);
3022 pthread_mutex_lock(&adev->lock);
3023 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
3024 do_in_standby_l(in);
3025 pthread_mutex_unlock(&adev->lock);
3026 pthread_mutex_unlock(&in->lock);
3027 /* This mutex was left locked iff in != NULL */
3028 pthread_mutex_unlock(&adev->lock_inputs);
3029 }
3030#endif
3031
3032 return bytes;
3033}
3034
3035static int out_get_render_position(const struct audio_stream_out *stream,
3036 uint32_t *dsp_frames)
3037{
3038 struct stream_out *out = (struct stream_out *)stream;
3039 *dsp_frames = 0;
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003040 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
3041 return out_get_render_offload_position(out, dsp_frames);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003042 } else
3043 return -EINVAL;
3044}
3045
3046static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3047{
3048 (void)stream;
3049 (void)effect;
3050 return 0;
3051}
3052
3053static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3054{
3055 (void)stream;
3056 (void)effect;
3057 return 0;
3058}
3059
3060static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
3061 int64_t *timestamp)
3062{
3063 (void)stream;
3064 (void)timestamp;
3065 return -EINVAL;
3066}
3067
3068static int out_get_presentation_position(const struct audio_stream_out *stream,
3069 uint64_t *frames, struct timespec *timestamp)
3070{
3071 struct stream_out *out = (struct stream_out *)stream;
Victor Lourme5869cd32018-03-26 19:36:07 +02003072 int ret = -EINVAL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003073
3074 lock_output_stream(out);
3075
3076 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003077 ret = out_get_presentation_offload_position(out, frames, timestamp);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003078 } else {
3079 /* FIXME: which device to read from? */
3080 if (!list_empty(&out->pcm_dev_list)) {
Andreas Schneiderd6359182017-02-08 16:58:22 +01003081 struct pcm_device *pcm_device;
3082 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003083 unsigned int avail;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003084
Andreas Schneiderd6359182017-02-08 16:58:22 +01003085 list_for_each(node, &out->pcm_dev_list) {
3086 pcm_device = node_to_item(node,
3087 struct pcm_device,
3088 stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003089
Andreas Schneiderd6359182017-02-08 16:58:22 +01003090 if (pcm_device->pcm != NULL) {
3091 if (pcm_get_htimestamp(pcm_device->pcm, &avail, timestamp) == 0) {
3092 size_t kernel_buffer_size = out->config.period_size * out->config.period_count;
3093 int64_t signed_frames = out->written - kernel_buffer_size + avail;
3094 /* This adjustment accounts for buffering after app processor.
3095 It is based on estimated DSP latency per use case, rather than exact. */
3096 signed_frames -=
3097 (render_latency(out->usecase) * out->sample_rate / 1000000LL);
3098
3099 /* It would be unusual for this value to be negative, but check just in case ... */
3100 if (signed_frames >= 0) {
3101 *frames = signed_frames;
3102 ret = 0;
3103 goto done;
3104 }
Andreas Schneiderd6359182017-02-08 16:58:22 +01003105 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003106 }
3107 }
3108 }
3109 }
3110
Andreas Schneiderd6359182017-02-08 16:58:22 +01003111done:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003112 pthread_mutex_unlock(&out->lock);
3113
3114 return ret;
3115}
3116
3117static int out_set_callback(struct audio_stream_out *stream,
3118 stream_callback_t callback, void *cookie)
3119{
3120 struct stream_out *out = (struct stream_out *)stream;
3121
3122 ALOGV("%s", __func__);
3123 lock_output_stream(out);
3124 out->offload_callback = callback;
3125 out->offload_cookie = cookie;
3126 pthread_mutex_unlock(&out->lock);
3127 return 0;
3128}
3129
3130static int out_pause(struct audio_stream_out* stream)
3131{
3132 struct stream_out *out = (struct stream_out *)stream;
3133 int status = -ENOSYS;
3134 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003135 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3136 status = out_pause_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003137 return status;
3138}
3139
3140static int out_resume(struct audio_stream_out* stream)
3141{
3142 struct stream_out *out = (struct stream_out *)stream;
3143 int status = -ENOSYS;
3144 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003145 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3146 status = out_resume_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003147 return status;
3148}
3149
3150static int out_drain(struct audio_stream_out* stream, audio_drain_type_t type )
3151{
3152 struct stream_out *out = (struct stream_out *)stream;
3153 int status = -ENOSYS;
3154 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003155 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3156 status = out_drain_offload(out, type);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003157 return status;
3158}
3159
3160static int out_flush(struct audio_stream_out* stream)
3161{
3162 struct stream_out *out = (struct stream_out *)stream;
3163 ALOGV("%s", __func__);
3164 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003165 return out_flush_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003166 }
3167 return -ENOSYS;
3168}
3169
3170/** audio_stream_in implementation **/
3171static uint32_t in_get_sample_rate(const struct audio_stream *stream)
3172{
3173 struct stream_in *in = (struct stream_in *)stream;
3174
3175 return in->requested_rate;
3176}
3177
3178static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
3179{
3180 (void)stream;
3181 (void)rate;
3182 return -ENOSYS;
3183}
3184
3185static uint32_t in_get_channels(const struct audio_stream *stream)
3186{
3187 struct stream_in *in = (struct stream_in *)stream;
3188
3189 return in->main_channels;
3190}
3191
3192static audio_format_t in_get_format(const struct audio_stream *stream)
3193{
3194 (void)stream;
3195 return AUDIO_FORMAT_PCM_16_BIT;
3196}
3197
3198static int in_set_format(struct audio_stream *stream, audio_format_t format)
3199{
3200 (void)stream;
3201 (void)format;
3202
3203 return -ENOSYS;
3204}
3205
3206static size_t in_get_buffer_size(const struct audio_stream *stream)
3207{
3208 struct stream_in *in = (struct stream_in *)stream;
3209
3210 return get_input_buffer_size(in->requested_rate,
3211 in_get_format(stream),
3212 audio_channel_count_from_in_mask(in->main_channels),
3213 in->usecase_type,
3214 in->devices);
3215}
3216
3217static int in_close_pcm_devices(struct stream_in *in)
3218{
3219 struct pcm_device *pcm_device;
3220 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003221
3222 list_for_each(node, &in->pcm_dev_list) {
3223 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3224 if (pcm_device) {
3225 if (pcm_device->pcm)
3226 pcm_close(pcm_device->pcm);
3227 pcm_device->pcm = NULL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003228 }
3229 }
3230 return 0;
3231}
3232
3233
3234/* must be called with stream and hw device mutex locked */
3235static int do_in_standby_l(struct stream_in *in)
3236{
3237 int status = 0;
3238
3239#ifdef PREPROCESSING_ENABLED
3240 struct audio_device *adev = in->dev;
3241#endif
3242 if (!in->standby) {
3243
3244 in_close_pcm_devices(in);
3245
3246#ifdef PREPROCESSING_ENABLED
3247 if (in->echo_reference != NULL) {
3248 /* stop reading from echo reference */
3249 in->echo_reference->read(in->echo_reference, NULL);
3250 put_echo_reference(adev, in->echo_reference);
3251 in->echo_reference = NULL;
3252 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003253#endif // PREPROCESSING_ENABLED
3254
3255 status = stop_input_stream(in);
3256
3257 if (in->read_buf) {
3258 free(in->read_buf);
3259 in->read_buf = NULL;
3260 }
3261
3262 in->standby = 1;
3263 }
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003264
3265 in->last_read_time_us = 0;
3266
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003267 return 0;
3268}
3269
3270// called with adev->lock_inputs locked
3271static int in_standby_l(struct stream_in *in)
3272{
3273 struct audio_device *adev = in->dev;
3274 int status = 0;
3275 lock_input_stream(in);
3276 if (!in->standby) {
3277 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003278 amplifier_input_stream_standby((struct audio_stream_in *) in);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003279 status = do_in_standby_l(in);
3280 pthread_mutex_unlock(&adev->lock);
3281 }
3282 pthread_mutex_unlock(&in->lock);
3283 return status;
3284}
3285
3286static int in_standby(struct audio_stream *stream)
3287{
3288 struct stream_in *in = (struct stream_in *)stream;
3289 struct audio_device *adev = in->dev;
3290 int status;
3291 ALOGV("%s: enter", __func__);
3292 pthread_mutex_lock(&adev->lock_inputs);
3293 status = in_standby_l(in);
3294 pthread_mutex_unlock(&adev->lock_inputs);
3295 ALOGV("%s: exit: status(%d)", __func__, status);
3296 return status;
3297}
3298
3299static int in_dump(const struct audio_stream *stream, int fd)
3300{
3301 (void)stream;
3302 (void)fd;
3303
3304 return 0;
3305}
3306
3307static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
3308{
3309 struct stream_in *in = (struct stream_in *)stream;
3310 struct audio_device *adev = in->dev;
3311 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003312 char value[32];
3313 int ret, val = 0;
3314 struct audio_usecase *uc_info;
3315 bool do_standby = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003316 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003317
3318 ALOGV("%s: enter: kvpairs=%s", __func__, kvpairs);
3319 parms = str_parms_create_str(kvpairs);
3320
3321 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
3322
3323 pthread_mutex_lock(&adev->lock_inputs);
3324 lock_input_stream(in);
3325 pthread_mutex_lock(&adev->lock);
3326 if (ret >= 0) {
3327 val = atoi(value);
3328 /* no audio source uses val == 0 */
3329 if (((int)in->source != val) && (val != 0)) {
3330 in->source = val;
3331 }
3332 }
3333
3334 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
3335 if (ret >= 0) {
3336 val = atoi(value);
3337 if (((int)in->devices != val) && (val != 0)) {
3338 in->devices = val;
3339 /* If recording is in progress, change the tx device to new device */
3340 if (!in->standby) {
3341 uc_info = get_usecase_from_id(adev, in->usecase);
3342 if (uc_info == NULL) {
3343 ALOGE("%s: Could not find the usecase (%d) in the list",
3344 __func__, in->usecase);
3345 } else {
3346 if (list_empty(&in->pcm_dev_list))
3347 ALOGE("%s: pcm device list empty", __func__);
3348 else {
3349 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3350 struct pcm_device, stream_list_node);
3351 if ((pcm_device->pcm_profile->devices & val & ~AUDIO_DEVICE_BIT_IN) == 0) {
3352 do_standby = true;
3353 }
3354 }
3355 }
3356 if (do_standby) {
3357 ret = do_in_standby_l(in);
3358 } else
3359 ret = select_devices(adev, in->usecase);
3360 }
3361 }
3362 }
3363 pthread_mutex_unlock(&adev->lock);
3364 pthread_mutex_unlock(&in->lock);
3365 pthread_mutex_unlock(&adev->lock_inputs);
3366 str_parms_destroy(parms);
3367
3368 if (ret > 0)
3369 ret = 0;
3370
3371 ALOGV("%s: exit: status(%d)", __func__, ret);
3372 return ret;
3373}
3374
3375static char* in_get_parameters(const struct audio_stream *stream,
3376 const char *keys)
3377{
3378 (void)stream;
3379 (void)keys;
3380
3381 return strdup("");
3382}
3383
3384static int in_set_gain(struct audio_stream_in *stream, float gain)
3385{
3386 (void)stream;
3387 (void)gain;
3388
3389 return 0;
3390}
3391
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003392static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
3393 size_t bytes)
3394{
3395 struct stream_in *in = (struct stream_in *)stream;
3396 struct audio_device *adev = in->dev;
3397 ssize_t frames = -1;
3398 int ret = -1;
3399 int read_and_process_successful = false;
3400
3401 size_t frames_rq = bytes / audio_stream_in_frame_size(stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003402
3403 /* no need to acquire adev->lock_inputs because API contract prevents a close */
3404 lock_input_stream(in);
3405
Andreas Schneider3b643832017-01-31 11:48:22 +01003406#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003407 if (in->usecase == USECASE_AUDIO_CAPTURE && !in->is_fastcapture_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003408 pid_t tid = gettid();
3409 int err;
3410
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003411 err = fast_set_affinity(tid);
3412 if (err < 0) {
3413 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
3414 }
3415 in->is_fastcapture_affinity_set = true;
3416 }
Andreas Schneider3b643832017-01-31 11:48:22 +01003417#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003418
3419 if (in->standby) {
3420 pthread_mutex_unlock(&in->lock);
3421 pthread_mutex_lock(&adev->lock_inputs);
3422 lock_input_stream(in);
3423 if (!in->standby) {
3424 pthread_mutex_unlock(&adev->lock_inputs);
3425 goto false_alarm;
3426 }
3427 pthread_mutex_lock(&adev->lock);
3428 ret = start_input_stream(in);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003429 if (ret == 0) {
3430 amplifier_input_stream_start(stream);
3431 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003432 pthread_mutex_unlock(&adev->lock);
3433 pthread_mutex_unlock(&adev->lock_inputs);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003434
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003435 if (ret != 0) {
3436 goto exit;
3437 }
3438 in->standby = 0;
3439 }
3440false_alarm:
3441
3442 if (!list_empty(&in->pcm_dev_list)) {
stenkinevgeniy44335362018-05-07 18:00:13 +00003443 /*
3444 * Read PCM and:
3445 * - resample if needed
3446 * - process if pre-processors are attached
3447 * - discard unwanted channels
3448 */
3449 frames = read_and_process_frames(in, buffer, frames_rq);
3450 if (frames >= 0)
3451 read_and_process_successful = true;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003452 }
3453
3454 /*
3455 * Instead of writing zeroes here, we could trust the hardware
3456 * to always provide zeroes when muted.
3457 */
3458 if (read_and_process_successful == true && adev->mic_mute)
3459 memset(buffer, 0, bytes);
3460
3461exit:
3462 pthread_mutex_unlock(&in->lock);
3463
3464 if (read_and_process_successful == false) {
3465 in_standby(&in->stream.common);
3466 ALOGV("%s: read failed - sleeping for buffer duration", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003467 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3468 clock_gettime(CLOCK_MONOTONIC, &t);
3469 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3470
3471 // we do a full sleep when exiting standby.
3472 const bool standby = in->last_read_time_us == 0;
3473 const int64_t elapsed_time_since_last_read = standby ?
3474 0 : now - in->last_read_time_us;
3475 int64_t sleep_time = bytes * 1000000LL / audio_stream_in_frame_size(stream) /
3476 in_get_sample_rate(&stream->common) - elapsed_time_since_last_read;
3477 if (sleep_time > 0) {
3478 usleep(sleep_time);
3479 } else {
3480 sleep_time = 0;
3481 }
3482 in->last_read_time_us = now + sleep_time;
3483 // last_read_time_us is an approximation of when the (simulated) alsa
3484 // buffer is drained by the read, and is empty.
3485 //
3486 // On the subsequent in_read(), we measure the elapsed time spent in
3487 // the recording thread. This is subtracted from the sleep estimate based on frames,
3488 // thereby accounting for fill in the alsa buffer during the interim.
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003489 memset(buffer, 0, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003490 }
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003491
3492 if (bytes > 0) {
3493 in->frames_read += bytes / audio_stream_in_frame_size(stream);
3494 }
3495
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003496 return bytes;
3497}
3498
3499static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
3500{
3501 (void)stream;
3502
3503 return 0;
3504}
3505
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003506static int in_get_capture_position(const struct audio_stream_in *stream,
3507 int64_t *frames, int64_t *time)
3508{
3509 if (stream == NULL || frames == NULL || time == NULL) {
3510 return -EINVAL;
3511 }
3512
3513 struct stream_in *in = (struct stream_in *)stream;
3514 struct pcm_device *pcm_device;
3515 int ret = -ENOSYS;
3516
3517 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3518 struct pcm_device, stream_list_node);
3519
3520 pthread_mutex_lock(&in->lock);
3521 if (pcm_device->pcm) {
3522 struct timespec timestamp;
3523 unsigned int avail;
3524 if (pcm_get_htimestamp(pcm_device->pcm, &avail, &timestamp) == 0) {
3525 *frames = in->frames_read + avail;
3526 *time = timestamp.tv_sec * 1000000000LL + timestamp.tv_nsec;
3527 ret = 0;
3528 }
3529 }
3530
3531 pthread_mutex_unlock(&in->lock);
3532 return ret;
3533}
3534
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003535static int add_remove_audio_effect(const struct audio_stream *stream,
3536 effect_handle_t effect,
3537 bool enable)
3538{
3539 struct stream_in *in = (struct stream_in *)stream;
3540 struct audio_device *adev = in->dev;
3541 int status = 0;
3542 effect_descriptor_t desc;
3543#ifdef PREPROCESSING_ENABLED
3544 int i;
3545#endif
3546 status = (*effect)->get_descriptor(effect, &desc);
3547 if (status != 0)
3548 return status;
3549
3550 ALOGI("add_remove_audio_effect(), effect type: %08x, enable: %d ", desc.type.timeLow, enable);
3551
3552 pthread_mutex_lock(&adev->lock_inputs);
3553 lock_input_stream(in);
3554 pthread_mutex_lock(&in->dev->lock);
3555#ifndef PREPROCESSING_ENABLED
3556 if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) &&
3557 in->enable_aec != enable &&
3558 (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0)) {
3559 in->enable_aec = enable;
3560 if (!in->standby)
3561 select_devices(in->dev, in->usecase);
3562 }
3563#else
3564 if ( (in->num_preprocessors > MAX_PREPROCESSORS) && (enable == true) ) {
3565 status = -ENOSYS;
3566 goto exit;
3567 }
3568 if ( enable == true ) {
3569 in->preprocessors[in->num_preprocessors].effect_itfe = effect;
3570 /* add the supported channel of the effect in the channel_configs */
3571 in_read_audio_effect_channel_configs(in, &in->preprocessors[in->num_preprocessors]);
3572 in->num_preprocessors ++;
3573 /* check compatibility between main channel supported and possible auxiliary channels */
3574 in_update_aux_channels(in, effect);//wesley crash
3575 in->aux_channels_changed = true;
3576 } else {
3577 /* if ( enable == false ) */
3578 if (in->num_preprocessors <= 0) {
3579 status = -ENOSYS;
3580 goto exit;
3581 }
3582 status = -EINVAL;
3583 for (i=0; i < in->num_preprocessors; i++) {
3584 if (status == 0) { /* status == 0 means an effect was removed from a previous slot */
3585 in->preprocessors[i - 1].effect_itfe = in->preprocessors[i].effect_itfe;
3586 in->preprocessors[i - 1].channel_configs = in->preprocessors[i].channel_configs;
3587 in->preprocessors[i - 1].num_channel_configs =
3588 in->preprocessors[i].num_channel_configs;
3589 ALOGV("add_remove_audio_effect moving fx from %d to %d", i, i-1);
3590 continue;
3591 }
3592 if ( in->preprocessors[i].effect_itfe == effect ) {
3593 ALOGV("add_remove_audio_effect found fx at index %d", i);
3594 free(in->preprocessors[i].channel_configs);
3595 status = 0;
3596 }
3597 }
3598 if (status != 0)
3599 goto exit;
3600 in->num_preprocessors--;
3601 /* if we remove one effect, at least the last proproc should be reset */
3602 in->preprocessors[in->num_preprocessors].num_channel_configs = 0;
3603 in->preprocessors[in->num_preprocessors].effect_itfe = NULL;
3604 in->preprocessors[in->num_preprocessors].channel_configs = NULL;
3605 in->aux_channels_changed = false;
3606 ALOGV("%s: enable(%d), in->aux_channels_changed(%d)", __func__, enable, in->aux_channels_changed);
3607 }
3608 ALOGI("%s: num_preprocessors = %d", __func__, in->num_preprocessors);
3609
3610 if ( memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
3611 in->enable_aec = enable;
3612 ALOGV("add_remove_audio_effect(), FX_IID_AEC, enable: %d", enable);
3613 if (!in->standby) {
3614 select_devices(in->dev, in->usecase);
3615 do_in_standby_l(in);
3616 }
3617 if (in->enable_aec == true) {
3618 in_configure_reverse(in);
3619 }
3620 }
3621exit:
3622#endif
3623 ALOGW_IF(status != 0, "add_remove_audio_effect() error %d", status);
3624 pthread_mutex_unlock(&in->dev->lock);
3625 pthread_mutex_unlock(&in->lock);
3626 pthread_mutex_unlock(&adev->lock_inputs);
3627 return status;
3628}
3629
3630static int in_add_audio_effect(const struct audio_stream *stream,
3631 effect_handle_t effect)
3632{
3633 ALOGV("%s: effect %p", __func__, effect);
3634 return add_remove_audio_effect(stream, effect, true);
3635}
3636
3637static int in_remove_audio_effect(const struct audio_stream *stream,
3638 effect_handle_t effect)
3639{
3640 ALOGV("%s: effect %p", __func__, effect);
3641 return add_remove_audio_effect(stream, effect, false);
3642}
3643
3644static int adev_open_output_stream(struct audio_hw_device *dev,
3645 audio_io_handle_t handle,
3646 audio_devices_t devices,
3647 audio_output_flags_t flags,
3648 struct audio_config *config,
3649 struct audio_stream_out **stream_out,
3650 const char *address __unused)
3651{
3652 struct audio_device *adev = (struct audio_device *)dev;
3653 struct stream_out *out;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003654 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003655 struct pcm_device_profile *pcm_profile;
3656
3657 ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
3658 __func__, config->sample_rate, config->channel_mask, devices, flags);
3659 *stream_out = NULL;
3660 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
Andreas Schneider56204f62017-01-31 08:17:32 +01003661 if (out == NULL) {
3662 ret = -ENOMEM;
3663 goto error_config;
3664 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003665
3666 if (devices == AUDIO_DEVICE_NONE)
3667 devices = AUDIO_DEVICE_OUT_SPEAKER;
3668
3669 out->flags = flags;
3670 out->devices = devices;
3671 out->dev = adev;
3672 out->format = config->format;
3673 out->sample_rate = config->sample_rate;
3674 out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3675 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
3676 out->handle = handle;
3677
3678 pcm_profile = get_pcm_device(PCM_PLAYBACK, devices);
3679 if (pcm_profile == NULL) {
3680 ret = -EINVAL;
3681 goto error_open;
3682 }
3683 out->config = pcm_profile->config;
3684
3685 /* Init use case and pcm_config */
3686 if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
3687 if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version ||
3688 config->offload_info.size != AUDIO_INFO_INITIALIZER.size) {
3689 ALOGE("%s: Unsupported Offload information", __func__);
3690 ret = -EINVAL;
3691 goto error_open;
3692 }
3693 if (!is_supported_format(config->offload_info.format)) {
3694 ALOGE("%s: Unsupported audio format", __func__);
3695 ret = -EINVAL;
3696 goto error_open;
3697 }
3698
3699 out->compr_config.codec = (struct snd_codec *)
3700 calloc(1, sizeof(struct snd_codec));
Andreas Schneider56204f62017-01-31 08:17:32 +01003701 if (out->compr_config.codec == NULL) {
3702 ret = -ENOMEM;
3703 goto error_open;
3704 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003705
3706 out->usecase = USECASE_AUDIO_PLAYBACK_OFFLOAD;
3707 if (config->offload_info.channel_mask)
3708 out->channel_mask = config->offload_info.channel_mask;
3709 else if (config->channel_mask)
3710 out->channel_mask = config->channel_mask;
3711 out->format = config->offload_info.format;
3712 out->sample_rate = config->offload_info.sample_rate;
3713
3714 out->stream.set_callback = out_set_callback;
3715 out->stream.pause = out_pause;
3716 out->stream.resume = out_resume;
3717 out->stream.drain = out_drain;
3718 out->stream.flush = out_flush;
3719
3720 out->compr_config.codec->id =
3721 get_snd_codec_id(config->offload_info.format);
3722 out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
3723 out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
3724 out->compr_config.codec->sample_rate = config->offload_info.sample_rate;
3725 out->compr_config.codec->bit_rate =
3726 config->offload_info.bit_rate;
3727 out->compr_config.codec->ch_in =
3728 audio_channel_count_from_out_mask(config->channel_mask);
3729 out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
3730
3731 if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
3732 out->non_blocking = 1;
3733
3734 out->send_new_metadata = 1;
3735 create_offload_callback_thread(out);
3736 out->offload_state = OFFLOAD_STATE_IDLE;
3737
3738 ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
3739 __func__, config->offload_info.version,
3740 config->offload_info.bit_rate);
3741 } else if (out->flags & (AUDIO_OUTPUT_FLAG_DEEP_BUFFER)) {
3742 out->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01003743 out->config = pcm_device_deep_buffer.config;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003744 out->sample_rate = out->config.rate;
3745 ALOGV("%s: use AUDIO_PLAYBACK_DEEP_BUFFER",__func__);
3746 } else {
3747 out->usecase = USECASE_AUDIO_PLAYBACK;
3748 out->sample_rate = out->config.rate;
3749 }
3750
3751 if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
3752 if (adev->primary_output == NULL)
3753 adev->primary_output = out;
3754 else {
3755 ALOGE("%s: Primary output is already opened", __func__);
3756 ret = -EEXIST;
3757 goto error_open;
3758 }
3759 }
3760
3761 /* Check if this usecase is already existing */
3762 pthread_mutex_lock(&adev->lock);
3763 if (get_usecase_from_id(adev, out->usecase) != NULL) {
3764 ALOGE("%s: Usecase (%d) is already present", __func__, out->usecase);
3765 pthread_mutex_unlock(&adev->lock);
3766 ret = -EEXIST;
3767 goto error_open;
3768 }
3769 pthread_mutex_unlock(&adev->lock);
3770
3771 out->stream.common.get_sample_rate = out_get_sample_rate;
3772 out->stream.common.set_sample_rate = out_set_sample_rate;
3773 out->stream.common.get_buffer_size = out_get_buffer_size;
3774 out->stream.common.get_channels = out_get_channels;
3775 out->stream.common.get_format = out_get_format;
3776 out->stream.common.set_format = out_set_format;
3777 out->stream.common.standby = out_standby;
3778 out->stream.common.dump = out_dump;
3779 out->stream.common.set_parameters = out_set_parameters;
3780 out->stream.common.get_parameters = out_get_parameters;
3781 out->stream.common.add_audio_effect = out_add_audio_effect;
3782 out->stream.common.remove_audio_effect = out_remove_audio_effect;
3783 out->stream.get_latency = out_get_latency;
3784 out->stream.set_volume = out_set_volume;
3785 out->stream.write = out_write;
3786 out->stream.get_render_position = out_get_render_position;
3787 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
3788 out->stream.get_presentation_position = out_get_presentation_position;
3789
3790 out->standby = 1;
3791 /* out->muted = false; by calloc() */
3792 /* out->written = 0; by calloc() */
3793
3794 pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
3795 pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
3796 pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
3797
3798 config->format = out->stream.common.get_format(&out->stream.common);
3799 config->channel_mask = out->stream.common.get_channels(&out->stream.common);
3800 config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
3801
3802 out->is_fastmixer_affinity_set = false;
3803
3804 *stream_out = &out->stream;
3805 ALOGV("%s: exit", __func__);
3806 return 0;
3807
3808error_open:
3809 free(out);
3810 *stream_out = NULL;
Andreas Schneider56204f62017-01-31 08:17:32 +01003811error_config:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003812 ALOGV("%s: exit: ret %d", __func__, ret);
3813 return ret;
3814}
3815
3816static void adev_close_output_stream(struct audio_hw_device *dev,
3817 struct audio_stream_out *stream)
3818{
3819 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003820 (void)dev;
3821
3822 ALOGV("%s: enter", __func__);
3823 out_standby(&stream->common);
3824 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
3825 destroy_offload_callback_thread(out);
3826
3827 if (out->compr_config.codec != NULL)
3828 free(out->compr_config.codec);
3829 }
3830 pthread_cond_destroy(&out->cond);
3831 pthread_mutex_destroy(&out->lock);
3832 free(stream);
3833 ALOGV("%s: exit", __func__);
3834}
3835
3836static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
3837{
3838 struct audio_device *adev = (struct audio_device *)dev;
3839 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003840 char value[32];
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003841#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003842 int val;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003843#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003844 int ret;
3845
3846 ALOGV("%s: enter: %s", __func__, kvpairs);
3847
3848 parms = str_parms_create_str(kvpairs);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003849
Andreas Schneider05bc1882017-02-09 14:03:11 +01003850 /******************************************************
3851 *** BT SCO
3852 ******************************************************/
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003853 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
3854 if (ret >= 0) {
3855 /* When set to false, HAL should disable EC and NS
3856 * But it is currently not supported.
3857 */
3858 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
Andreas Schneider74ef3a12017-02-02 18:29:12 +01003859 adev->voice.bluetooth_nrec = true;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003860 else
Andreas Schneider74ef3a12017-02-02 18:29:12 +01003861 adev->voice.bluetooth_nrec = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003862 }
3863
Andreas Schneider05bc1882017-02-09 14:03:11 +01003864 ret = str_parms_get_str(parms,
3865 AUDIO_PARAMETER_KEY_BT_SCO_WB,
3866 value,
3867 sizeof(value));
3868 if (ret >= 0) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01003869 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) {
3870 adev->voice.bluetooth_wb = true;
Andreas Schneider05bc1882017-02-09 14:03:11 +01003871 } else {
3872 adev->voice.bluetooth_wb = false;
3873 }
3874 }
3875
Andreas Schneiderecd17ce2017-02-09 10:45:21 +01003876 ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
3877 if (ret >= 0) {
3878 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
3879 adev->screen_off = false;
3880 else
3881 adev->screen_off = true;
3882 }
3883
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01003884#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003885 ret = str_parms_get_int(parms, "rotation", &val);
3886 if (ret >= 0) {
3887 bool reverse_speakers = false;
3888 switch(val) {
3889 /* FIXME: note that the code below assumes that the speakers are in the correct placement
3890 relative to the user when the device is rotated 90deg from its default rotation. This
3891 assumption is device-specific, not platform-specific like this code. */
3892 case 270:
3893 reverse_speakers = true;
3894 break;
3895 case 0:
3896 case 90:
3897 case 180:
3898 break;
3899 default:
3900 ALOGE("%s: unexpected rotation of %d", __func__, val);
3901 }
3902 pthread_mutex_lock(&adev->lock);
3903 if (adev->speaker_lr_swap != reverse_speakers) {
3904 adev->speaker_lr_swap = reverse_speakers;
3905 /* only update the selected device if there is active pcm playback */
3906 struct audio_usecase *usecase;
3907 struct listnode *node;
3908 list_for_each(node, &adev->usecase_list) {
3909 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
3910 if (usecase->type == PCM_PLAYBACK) {
3911 select_devices(adev, usecase->id);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003912 break;
3913 }
3914 }
3915 }
3916 pthread_mutex_unlock(&adev->lock);
3917 }
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01003918#endif /* SWAP_SPEAKER_ON_SCREEN_ROTATION */
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003919
3920 str_parms_destroy(parms);
3921
3922 if (ret > 0)
3923 ret = 0;
3924
3925 ALOGV("%s: exit with code(%d)", __func__, ret);
3926 return ret;
3927}
3928
3929static char* adev_get_parameters(const struct audio_hw_device *dev,
3930 const char *keys)
3931{
3932 (void)dev;
3933 (void)keys;
3934
3935 return strdup("");
3936}
3937
3938static int adev_init_check(const struct audio_hw_device *dev)
3939{
3940 (void)dev;
3941
3942 return 0;
3943}
3944
3945static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
3946{
3947 int ret = 0;
3948 struct audio_device *adev = (struct audio_device *)dev;
3949 pthread_mutex_lock(&adev->lock);
3950 /* cache volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01003951 adev->voice.volume = volume;
3952 ret = set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003953 pthread_mutex_unlock(&adev->lock);
3954 return ret;
3955}
3956
3957static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
3958{
3959 (void)dev;
3960 (void)volume;
3961
3962 return -ENOSYS;
3963}
3964
3965static int adev_get_master_volume(struct audio_hw_device *dev,
3966 float *volume)
3967{
3968 (void)dev;
3969 (void)volume;
3970
3971 return -ENOSYS;
3972}
3973
3974static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
3975{
3976 (void)dev;
3977 (void)muted;
3978
3979 return -ENOSYS;
3980}
3981
3982static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
3983{
3984 (void)dev;
3985 (void)muted;
3986
3987 return -ENOSYS;
3988}
3989
3990static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
3991{
3992 struct audio_device *adev = (struct audio_device *)dev;
3993
3994 pthread_mutex_lock(&adev->lock);
3995 if (adev->mode != mode) {
3996 ALOGI("%s mode = %d", __func__, mode);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003997 if (amplifier_set_mode(mode) != 0) {
3998 ALOGE("Failed setting amplifier mode");
3999 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004000 adev->mode = mode;
Christopher N. Hesse6c0020c2017-11-17 20:41:11 +01004001
4002 if ((mode == AUDIO_MODE_NORMAL) && adev->voice.in_call) {
4003 stop_voice_call(adev);
4004 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004005 }
4006 pthread_mutex_unlock(&adev->lock);
4007 return 0;
4008}
4009
4010static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
4011{
4012 struct audio_device *adev = (struct audio_device *)dev;
4013 int err = 0;
4014
4015 pthread_mutex_lock(&adev->lock);
4016 adev->mic_mute = state;
4017
4018 if (adev->mode == AUDIO_MODE_IN_CALL) {
Andreas Schneider107a8482017-02-06 12:36:31 +01004019 set_voice_session_mic_mute(adev->voice.session, state);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004020 }
4021
4022 pthread_mutex_unlock(&adev->lock);
4023 return err;
4024}
4025
4026static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
4027{
4028 struct audio_device *adev = (struct audio_device *)dev;
4029
4030 *state = adev->mic_mute;
4031
4032 return 0;
4033}
4034
4035static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
4036 const struct audio_config *config)
4037{
4038 (void)dev;
4039
4040 /* NOTE: we default to built in mic which may cause a mismatch between what we
4041 * report here and the actual buffer size
4042 */
4043 return get_input_buffer_size(config->sample_rate,
4044 config->format,
4045 audio_channel_count_from_in_mask(config->channel_mask),
4046 PCM_CAPTURE /* usecase_type */,
4047 AUDIO_DEVICE_IN_BUILTIN_MIC);
4048}
4049
4050static int adev_open_input_stream(struct audio_hw_device *dev,
4051 audio_io_handle_t handle __unused,
4052 audio_devices_t devices,
4053 struct audio_config *config,
4054 struct audio_stream_in **stream_in,
4055 audio_input_flags_t flags,
4056 const char *address __unused,
4057 audio_source_t source)
4058{
4059 struct audio_device *adev = (struct audio_device *)dev;
4060 struct stream_in *in;
4061 struct pcm_device_profile *pcm_profile;
4062
4063 ALOGV("%s: enter", __func__);
4064
4065 *stream_in = NULL;
4066 if (check_input_parameters(config->sample_rate, config->format,
4067 audio_channel_count_from_in_mask(config->channel_mask)) != 0)
4068 return -EINVAL;
4069
stenkinevgeniy44335362018-05-07 18:00:13 +00004070 usecase_type_t usecase_type = flags & AUDIO_INPUT_FLAG_FAST ?
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004071 PCM_CAPTURE_LOW_LATENCY : PCM_CAPTURE;
4072 pcm_profile = get_pcm_device(usecase_type, devices);
4073 if (pcm_profile == NULL && usecase_type == PCM_CAPTURE_LOW_LATENCY) {
4074 // a low latency profile may not exist for that device, fall back
4075 // to regular capture. the MixerThread automatically changes
4076 // to non-fast capture based on the buffer size.
4077 flags &= ~AUDIO_INPUT_FLAG_FAST;
4078 usecase_type = PCM_CAPTURE;
4079 pcm_profile = get_pcm_device(usecase_type, devices);
4080 }
4081 if (pcm_profile == NULL)
4082 return -EINVAL;
4083
4084 in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
Andreas Schneider56204f62017-01-31 08:17:32 +01004085 if (in == NULL) {
4086 return -ENOMEM;
4087 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004088
4089 in->stream.common.get_sample_rate = in_get_sample_rate;
4090 in->stream.common.set_sample_rate = in_set_sample_rate;
4091 in->stream.common.get_buffer_size = in_get_buffer_size;
4092 in->stream.common.get_channels = in_get_channels;
4093 in->stream.common.get_format = in_get_format;
4094 in->stream.common.set_format = in_set_format;
4095 in->stream.common.standby = in_standby;
4096 in->stream.common.dump = in_dump;
4097 in->stream.common.set_parameters = in_set_parameters;
4098 in->stream.common.get_parameters = in_get_parameters;
4099 in->stream.common.add_audio_effect = in_add_audio_effect;
4100 in->stream.common.remove_audio_effect = in_remove_audio_effect;
4101 in->stream.set_gain = in_set_gain;
4102 in->stream.read = in_read;
4103 in->stream.get_input_frames_lost = in_get_input_frames_lost;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004104 in->stream.get_capture_position = in_get_capture_position;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004105
4106 in->devices = devices;
4107 in->source = source;
4108 in->dev = adev;
4109 in->standby = 1;
4110 in->main_channels = config->channel_mask;
4111 in->requested_rate = config->sample_rate;
4112 if (config->sample_rate != CAPTURE_DEFAULT_SAMPLING_RATE)
4113 flags = flags & ~AUDIO_INPUT_FLAG_FAST;
4114 in->input_flags = flags;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004115 // in->frames_read = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004116 /* HW codec is limited to default channels. No need to update with
4117 * requested channels */
4118 in->config = pcm_profile->config;
4119
4120 /* Update config params with the requested sample rate and channels */
stenkinevgeniy44335362018-05-07 18:00:13 +00004121 in->usecase = USECASE_AUDIO_CAPTURE;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004122 in->usecase_type = usecase_type;
4123
4124 pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
4125 pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL);
4126
4127 in->is_fastcapture_affinity_set = false;
4128
4129 *stream_in = &in->stream;
4130 ALOGV("%s: exit", __func__);
4131 return 0;
4132}
4133
4134static void adev_close_input_stream(struct audio_hw_device *dev,
4135 struct audio_stream_in *stream)
4136{
4137 struct audio_device *adev = (struct audio_device *)dev;
4138 struct stream_in *in = (struct stream_in*)stream;
4139 ALOGV("%s", __func__);
4140
4141 /* prevent concurrent out_set_parameters, or out_write from standby */
4142 pthread_mutex_lock(&adev->lock_inputs);
4143
Andreas Schneidercabe5e62017-01-30 10:57:06 +01004144 if (in->read_buf) {
4145 free(in->read_buf);
4146 in->read_buf = NULL;
4147 }
4148
4149 if (in->resampler) {
4150 release_resampler(in->resampler);
4151 in->resampler = NULL;
4152 }
4153
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004154#ifdef PREPROCESSING_ENABLED
4155 int i;
4156
4157 for (i=0; i<in->num_preprocessors; i++) {
4158 free(in->preprocessors[i].channel_configs);
4159 }
4160
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004161 if (in->proc_buf_in) {
4162 free(in->proc_buf_in);
4163 in->proc_buf_in = NULL;
4164 }
4165
4166 if (in->proc_buf_out) {
4167 free(in->proc_buf_out);
4168 in->proc_buf_out = NULL;
4169 }
4170
4171 if (in->ref_buf) {
4172 free(in->ref_buf);
4173 in->ref_buf = NULL;
4174 }
4175
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004176#endif
4177
4178 in_standby_l(in);
4179 free(stream);
4180
4181 pthread_mutex_unlock(&adev->lock_inputs);
4182
4183 return;
4184}
4185
4186static int adev_dump(const audio_hw_device_t *device, int fd)
4187{
4188 (void)device;
4189 (void)fd;
4190
4191 return 0;
4192}
4193
4194static int adev_close(hw_device_t *device)
4195{
4196 struct audio_device *adev = (struct audio_device *)device;
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004197 voice_session_deinit(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004198 audio_device_ref_count--;
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004199 if (audio_device_ref_count == 0) {
4200 if (amplifier_close() != 0) {
4201 ALOGE("Amplifier close failed");
4202 }
4203 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004204 free(adev->snd_dev_ref_cnt);
4205 free_mixer_list(adev);
4206 free(device);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004207
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004208 adev = NULL;
4209
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004210 return 0;
4211}
4212
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004213/* This returns true if the input parameter looks at all plausible as a low latency period size,
4214 * or false otherwise. A return value of true doesn't mean the value is guaranteed to work,
4215 * just that it _might_ work.
4216 */
4217static bool period_size_is_plausible_for_low_latency(int period_size)
4218{
4219 switch (period_size) {
4220 case 64:
4221 case 96:
4222 case 128:
4223 case 192:
4224 case 256:
4225 return true;
4226 default:
4227 return false;
4228 }
4229}
4230
4231static int adev_open(const hw_module_t *module, const char *name,
4232 hw_device_t **device)
4233{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004234 ALOGV("%s: enter", __func__);
4235 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
4236
Andreas Schneider56204f62017-01-31 08:17:32 +01004237 *device = NULL;
4238
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004239 adev = calloc(1, sizeof(struct audio_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01004240 if (adev == NULL) {
4241 return -ENOMEM;
4242 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004243
4244 adev->device.common.tag = HARDWARE_DEVICE_TAG;
4245 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
4246 adev->device.common.module = (struct hw_module_t *)module;
4247 adev->device.common.close = adev_close;
4248
4249 adev->device.init_check = adev_init_check;
4250 adev->device.set_voice_volume = adev_set_voice_volume;
4251 adev->device.set_master_volume = adev_set_master_volume;
4252 adev->device.get_master_volume = adev_get_master_volume;
4253 adev->device.set_master_mute = adev_set_master_mute;
4254 adev->device.get_master_mute = adev_get_master_mute;
4255 adev->device.set_mode = adev_set_mode;
4256 adev->device.set_mic_mute = adev_set_mic_mute;
4257 adev->device.get_mic_mute = adev_get_mic_mute;
4258 adev->device.set_parameters = adev_set_parameters;
4259 adev->device.get_parameters = adev_get_parameters;
4260 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
4261 adev->device.open_output_stream = adev_open_output_stream;
4262 adev->device.close_output_stream = adev_close_output_stream;
4263 adev->device.open_input_stream = adev_open_input_stream;
4264 adev->device.close_input_stream = adev_close_input_stream;
4265 adev->device.dump = adev_dump;
4266
4267 /* Set the default route before the PCM stream is opened */
4268 adev->mode = AUDIO_MODE_NORMAL;
4269 adev->active_input = NULL;
4270 adev->primary_output = NULL;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004271
4272 adev->voice.volume = 1.0f;
4273 adev->voice.bluetooth_nrec = true;
4274 adev->voice.in_call = false;
Christopher N. Hessee4a1c592018-01-16 18:33:38 +01004275 adev->voice.bluetooth_wb = false;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004276
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004277 /* adev->cur_hdmi_channels = 0; by calloc() */
4278 adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
Andreas Schneider56204f62017-01-31 08:17:32 +01004279 if (adev->snd_dev_ref_cnt == NULL) {
4280 free(adev);
4281 return -ENOMEM;
4282 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004283
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004284 adev->ns_in_voice_rec = false;
4285
4286 list_init(&adev->usecase_list);
4287
4288 if (mixer_init(adev) != 0) {
4289 free(adev->snd_dev_ref_cnt);
4290 free(adev);
4291 ALOGE("%s: Failed to init, aborting.", __func__);
4292 *device = NULL;
4293 return -EINVAL;
4294 }
4295
4296 if (access(OFFLOAD_FX_LIBRARY_PATH, R_OK) == 0) {
4297 adev->offload_fx_lib = dlopen(OFFLOAD_FX_LIBRARY_PATH, RTLD_NOW);
4298 if (adev->offload_fx_lib == NULL) {
4299 ALOGE("%s: DLOPEN failed for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4300 } else {
4301 ALOGV("%s: DLOPEN successful for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4302 adev->offload_fx_start_output =
4303 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4304 "visualizer_hal_start_output");
4305 adev->offload_fx_stop_output =
4306 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4307 "visualizer_hal_stop_output");
4308 }
4309 }
4310
Christopher N. Hesse696959d2017-02-02 20:49:55 +01004311 adev->voice.session = voice_session_init(adev);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004312 if (adev->voice.session == NULL) {
4313 ALOGE("%s: Failed to initialize voice session data", __func__);
4314
4315 free(adev->snd_dev_ref_cnt);
4316 free(adev);
4317
4318 *device = NULL;
4319 return -EINVAL;
4320 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004321
Christopher N. Hessec487bbe2018-07-12 13:51:43 +02004322 if (amplifier_open() != -ENOENT) {
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004323 ALOGE("Amplifier initialization failed");
4324 }
4325
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004326 *device = &adev->device.common;
4327
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004328 audio_device_ref_count++;
4329
4330 char value[PROPERTY_VALUE_MAX];
4331 if (property_get("audio_hal.period_size", value, NULL) > 0) {
4332 int trial = atoi(value);
4333 if (period_size_is_plausible_for_low_latency(trial)) {
4334
4335 pcm_device_playback.config.period_size = trial;
4336 pcm_device_playback.config.start_threshold =
4337 PLAYBACK_START_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4338 pcm_device_playback.config.stop_threshold =
4339 PLAYBACK_STOP_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4340
4341 pcm_device_capture_low_latency.config.period_size = trial;
4342 }
4343 }
4344
4345 ALOGV("%s: exit", __func__);
4346 return 0;
4347}
4348
4349static struct hw_module_methods_t hal_module_methods = {
4350 .open = adev_open,
4351};
4352
4353struct audio_module HAL_MODULE_INFO_SYM = {
4354 .common = {
4355 .tag = HARDWARE_MODULE_TAG,
4356 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
4357 .hal_api_version = HARDWARE_HAL_API_VERSION,
4358 .id = AUDIO_HARDWARE_MODULE_ID,
Christopher N. Hessec8502b92017-01-28 14:02:15 +01004359 .name = "Samsung Audio HAL",
4360 .author = "The LineageOS Project",
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004361 .methods = &hal_module_methods,
4362 },
4363};