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