blob: 4d0b6709baa8342cef0d758bba0a68eb8a12b599 [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 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002250 }
2251
2252 return 0;
2253}
2254
2255static int out_open_pcm_devices(struct stream_out *out)
2256{
2257 struct pcm_device *pcm_device;
2258 struct listnode *node;
2259 int ret = 0;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002260 int pcm_device_card;
2261 int pcm_device_id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002262
2263 list_for_each(node, &out->pcm_dev_list) {
2264 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002265 pcm_device_card = pcm_device->pcm_profile->card;
2266 pcm_device_id = pcm_device->pcm_profile->id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002267
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002268 if (out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
2269 pcm_device_id = pcm_device_deep_buffer.id;
2270
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002271 if (out->dev->voice.in_call) {
2272 ALOGV("%s: in_call, not opening PCMs", __func__);
2273 return ret;
2274 }
2275
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002276 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
2277 __func__, pcm_device_card, pcm_device_id);
2278
2279 pcm_device->pcm = pcm_open(pcm_device_card, pcm_device_id,
stenkinevgeniy2ef158a2018-05-08 06:52:05 +00002280 PCM_OUT | PCM_MONOTONIC, &out->config);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002281
2282 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2283 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2284 pcm_device->pcm = NULL;
2285 ret = -EIO;
2286 goto error_open;
2287 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002288 }
2289 return ret;
2290
2291error_open:
2292 out_close_pcm_devices(out);
2293 return ret;
2294}
2295
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002296int disable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002297{
2298 struct audio_device *adev = out->dev;
2299 struct audio_usecase *uc_info;
2300
2301 uc_info = get_usecase_from_id(adev, out->usecase);
2302 if (uc_info == NULL) {
2303 ALOGE("%s: Could not find the usecase (%d) in the list",
2304 __func__, out->usecase);
2305 return -EINVAL;
2306 }
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002307 disable_snd_device(adev, uc_info, uc_info->out_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002308 uc_release_pcm_devices(uc_info);
2309 list_remove(&uc_info->adev_list_node);
2310 free(uc_info);
2311
2312 return 0;
2313}
2314
Andreas Schneider56204f62017-01-31 08:17:32 +01002315int enable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002316{
2317 struct audio_device *adev = out->dev;
2318 struct audio_usecase *uc_info;
2319
2320 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002321 if (uc_info == NULL) {
2322 return -ENOMEM;
2323 }
2324
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002325 uc_info->id = out->usecase;
2326 uc_info->type = PCM_PLAYBACK;
2327 uc_info->stream = (struct audio_stream *)out;
2328 uc_info->devices = out->devices;
2329 uc_info->in_snd_device = SND_DEVICE_NONE;
2330 uc_info->out_snd_device = SND_DEVICE_NONE;
2331 uc_select_pcm_devices(uc_info);
2332
2333 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2334 select_devices(adev, out->usecase);
Andreas Schneider56204f62017-01-31 08:17:32 +01002335
2336 return 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002337}
2338
2339static int stop_output_stream(struct stream_out *out)
2340{
2341 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002342 bool do_disable = true;
2343
2344 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2345 out->usecase, use_case_table[out->usecase]);
2346
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002347 stop_output_offload_stream(out, &do_disable);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002348
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002349 if (do_disable)
2350 ret = disable_output_path_l(out);
2351
2352 ALOGV("%s: exit: status(%d)", __func__, ret);
2353 return ret;
2354}
2355
2356static int start_output_stream(struct stream_out *out)
2357{
2358 int ret = 0;
2359 struct audio_device *adev = out->dev;
2360
2361 ALOGV("%s: enter: usecase(%d: %s) devices(%#x) channels(%d)",
2362 __func__, out->usecase, use_case_table[out->usecase], out->devices, out->config.channels);
2363
Andreas Schneider56204f62017-01-31 08:17:32 +01002364 ret = enable_output_path_l(out);
2365 if (ret != 0) {
2366 goto error_config;
2367 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002368
2369 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2370 out->compr = NULL;
2371 ret = out_open_pcm_devices(out);
2372 if (ret != 0)
2373 goto error_open;
2374#ifdef PREPROCESSING_ENABLED
2375 out->echo_reference = NULL;
2376 out->echo_reference_generation = adev->echo_reference_generation;
2377 if (adev->echo_reference != NULL)
2378 out->echo_reference = adev->echo_reference;
2379#endif
2380 } else {
2381 out->compr = compress_open(COMPRESS_CARD, COMPRESS_DEVICE,
2382 COMPRESS_IN, &out->compr_config);
2383 if (out->compr && !is_compress_ready(out->compr)) {
2384 ALOGE("%s: %s", __func__, compress_get_error(out->compr));
2385 compress_close(out->compr);
2386 out->compr = NULL;
2387 ret = -EIO;
2388 goto error_open;
2389 }
2390 if (out->offload_callback)
2391 compress_nonblock(out->compr, out->non_blocking);
2392
2393 if (adev->offload_fx_start_output != NULL)
2394 adev->offload_fx_start_output(out->handle);
2395 }
2396 ALOGV("%s: exit", __func__);
2397 return 0;
2398error_open:
2399 stop_output_stream(out);
2400error_config:
2401 return ret;
2402}
2403
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002404int stop_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002405{
2406 struct audio_usecase *uc_info;
2407
2408 ALOGV("%s: enter", __func__);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002409 adev->voice.in_call = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002410
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002411 stop_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002412
2413 uc_info = get_usecase_from_id(adev, USECASE_VOICE_CALL);
2414 if (uc_info == NULL) {
2415 ALOGE("%s: Could not find the usecase (%d) in the list",
2416 __func__, USECASE_VOICE_CALL);
2417 return -EINVAL;
2418 }
2419
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002420 disable_snd_device(adev, uc_info, uc_info->out_snd_device);
2421 disable_snd_device(adev, uc_info, uc_info->in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002422
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002423 list_remove(&uc_info->adev_list_node);
2424 free(uc_info);
2425
2426 ALOGV("%s: exit", __func__);
2427 return 0;
2428}
2429
2430/* always called with adev lock held */
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002431int start_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002432{
2433 struct audio_usecase *uc_info;
Andreas Schneider56204f62017-01-31 08:17:32 +01002434 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002435
2436 ALOGV("%s: enter", __func__);
2437
2438 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002439 if (uc_info == NULL) {
2440 ret = -ENOMEM;
2441 goto exit;
2442 }
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002443 /*
2444 * We set this early so that functions called after this is being set
2445 * can use it. It is e.g. needed in select_devices() to inform the RILD
2446 * which output device we use.
2447 */
2448 adev->voice.in_call = true;
Andreas Schneider56204f62017-01-31 08:17:32 +01002449
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002450 uc_info->id = USECASE_VOICE_CALL;
2451 uc_info->type = VOICE_CALL;
2452 uc_info->stream = (struct audio_stream *)adev->primary_output;
2453 uc_info->devices = adev->primary_output->devices;
2454 uc_info->in_snd_device = SND_DEVICE_NONE;
2455 uc_info->out_snd_device = SND_DEVICE_NONE;
2456
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002457 list_init(&uc_info->mixer_list);
2458 list_add_tail(&uc_info->mixer_list,
2459 &adev_get_mixer_for_card(adev, SOUND_CARD)->uc_list_node[uc_info->id]);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002460
2461 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2462
2463 select_devices(adev, USECASE_VOICE_CALL);
2464
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002465 start_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002466
2467 /* set cached volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002468 set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002469
Andreas Schneider56204f62017-01-31 08:17:32 +01002470exit:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002471 ALOGV("%s: exit", __func__);
Andreas Schneider56204f62017-01-31 08:17:32 +01002472 return ret;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002473}
2474
2475static int check_input_parameters(uint32_t sample_rate,
2476 audio_format_t format,
2477 int channel_count)
2478{
2479 if (format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL;
2480
2481 if ((channel_count < 1) || (channel_count > 2)) return -EINVAL;
2482
2483 switch (sample_rate) {
2484 case 8000:
2485 case 11025:
2486 case 12000:
2487 case 16000:
2488 case 22050:
2489 case 24000:
2490 case 32000:
2491 case 44100:
2492 case 48000:
2493 break;
2494 default:
2495 return -EINVAL;
2496 }
2497
2498 return 0;
2499}
2500
2501static size_t get_input_buffer_size(uint32_t sample_rate,
2502 audio_format_t format,
2503 int channel_count,
2504 usecase_type_t usecase_type,
2505 audio_devices_t devices)
2506{
2507 size_t size = 0;
2508 struct pcm_device_profile *pcm_profile;
2509
2510 if (check_input_parameters(sample_rate, format, channel_count) != 0)
2511 return 0;
2512
2513 pcm_profile = get_pcm_device(usecase_type, devices);
2514 if (pcm_profile == NULL)
2515 return 0;
2516
2517 /*
2518 * take resampling into account and return the closest majoring
2519 * multiple of 16 frames, as audioflinger expects audio buffers to
2520 * be a multiple of 16 frames
2521 */
2522 size = (pcm_profile->config.period_size * sample_rate) / pcm_profile->config.rate;
2523 size = ((size + 15) / 16) * 16;
2524
2525 return (size * channel_count * audio_bytes_per_sample(format));
2526
2527}
2528
2529static uint32_t out_get_sample_rate(const struct audio_stream *stream)
2530{
2531 struct stream_out *out = (struct stream_out *)stream;
2532
2533 return out->sample_rate;
2534}
2535
2536static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
2537{
2538 (void)stream;
2539 (void)rate;
2540 return -ENOSYS;
2541}
2542
2543static size_t out_get_buffer_size(const struct audio_stream *stream)
2544{
2545 struct stream_out *out = (struct stream_out *)stream;
2546
2547 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2548 return out->compr_config.fragment_size;
2549 }
2550
2551 return out->config.period_size *
2552 audio_stream_out_frame_size((const struct audio_stream_out *)stream);
2553}
2554
2555static uint32_t out_get_channels(const struct audio_stream *stream)
2556{
2557 struct stream_out *out = (struct stream_out *)stream;
2558
2559 return out->channel_mask;
2560}
2561
2562static audio_format_t out_get_format(const struct audio_stream *stream)
2563{
2564 struct stream_out *out = (struct stream_out *)stream;
2565
2566 return out->format;
2567}
2568
2569static int out_set_format(struct audio_stream *stream, audio_format_t format)
2570{
2571 (void)stream;
2572 (void)format;
2573 return -ENOSYS;
2574}
2575
2576static int do_out_standby_l(struct stream_out *out)
2577{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002578 int status = 0;
2579
2580 out->standby = true;
2581 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2582 out_close_pcm_devices(out);
2583#ifdef PREPROCESSING_ENABLED
2584 /* stop writing to echo reference */
2585 if (out->echo_reference != NULL) {
2586 out->echo_reference->write(out->echo_reference, NULL);
2587 if (out->echo_reference_generation != adev->echo_reference_generation) {
2588 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
2589 release_echo_reference(out->echo_reference);
2590 out->echo_reference_generation = adev->echo_reference_generation;
2591 }
2592 out->echo_reference = NULL;
2593 }
2594#endif
2595 } else {
2596 stop_compressed_output_l(out);
2597 out->gapless_mdata.encoder_delay = 0;
2598 out->gapless_mdata.encoder_padding = 0;
2599 if (out->compr != NULL) {
2600 compress_close(out->compr);
2601 out->compr = NULL;
2602 }
2603 }
2604 status = stop_output_stream(out);
2605
2606 return status;
2607}
2608
2609static int out_standby(struct audio_stream *stream)
2610{
2611 struct stream_out *out = (struct stream_out *)stream;
2612 struct audio_device *adev = out->dev;
2613
2614 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2615 out->usecase, use_case_table[out->usecase]);
2616 lock_output_stream(out);
2617 if (!out->standby) {
2618 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002619 amplifier_output_stream_standby((struct audio_stream_out *) stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002620 do_out_standby_l(out);
2621 pthread_mutex_unlock(&adev->lock);
2622 }
2623 pthread_mutex_unlock(&out->lock);
2624 ALOGV("%s: exit", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01002625
2626 // out->last_write_time_us = 0; unnecessary as a stale write time has same effect
2627
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002628 return 0;
2629}
2630
2631static int out_dump(const struct audio_stream *stream, int fd)
2632{
2633 (void)stream;
2634 (void)fd;
2635
2636 return 0;
2637}
2638
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002639static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
2640{
2641 struct stream_out *out = (struct stream_out *)stream;
2642 struct audio_device *adev = out->dev;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002643 struct listnode *node;
2644 struct str_parms *parms;
2645 char value[32];
2646 int ret, val = 0;
2647 struct audio_usecase *uc_info;
2648 bool do_standby = false;
2649 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002650#ifdef PREPROCESSING_ENABLED
2651 struct stream_in *in = NULL; /* if non-NULL, then force input to standby */
2652#endif
2653
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002654 ALOGV("%s: enter: usecase(%d: %s) kvpairs: %s out->devices(%#x) "
2655 "adev->mode(%#x)",
2656 __func__, out->usecase, use_case_table[out->usecase], kvpairs,
2657 out->devices, adev->mode);
2658
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002659 parms = str_parms_create_str(kvpairs);
2660 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
2661 if (ret >= 0) {
2662 val = atoi(value);
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002663
2664 ALOGV("%s: routing: usecase(%d: %s) devices=(%#x) adev->mode(%#x)",
2665 __func__, out->usecase, use_case_table[out->usecase], val,
2666 adev->mode);
2667
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002668 pthread_mutex_lock(&adev->lock_inputs);
2669 lock_output_stream(out);
2670 pthread_mutex_lock(&adev->lock);
2671#ifdef PREPROCESSING_ENABLED
2672 if (((int)out->devices != val) && (val != 0) && (!out->standby) &&
2673 (out->usecase == USECASE_AUDIO_PLAYBACK)) {
2674 /* reset active input:
2675 * - to attach the echo reference
2676 * - because a change in output device may change mic settings */
2677 if (adev->active_input && (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
2678 adev->active_input->source == AUDIO_SOURCE_MIC)) {
2679 in = adev->active_input;
2680 }
2681 }
2682#endif
Christopher N. Hesse33affb82017-11-16 17:01:37 +01002683 if (val != SND_DEVICE_NONE) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002684 bool bt_sco_active = false;
2685
2686 if (out->devices & AUDIO_DEVICE_OUT_ALL_SCO) {
2687 bt_sco_active = true;
2688 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002689 out->devices = val;
2690
2691 if (!out->standby) {
2692 uc_info = get_usecase_from_id(adev, out->usecase);
2693 if (uc_info == NULL) {
2694 ALOGE("%s: Could not find the usecase (%d) in the list",
2695 __func__, out->usecase);
2696 } else {
2697 list_for_each(node, &out->pcm_dev_list) {
2698 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2699 if ((pcm_device->pcm_profile->devices & val) == 0)
2700 do_standby = true;
2701 val &= ~pcm_device->pcm_profile->devices;
2702 }
2703 if (val != 0)
2704 do_standby = true;
2705 }
2706 if (do_standby)
2707 do_out_standby_l(out);
2708 else {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002709 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
2710 out_set_offload_parameters(adev, uc_info);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002711 select_devices(adev, out->usecase);
2712 }
2713 }
2714
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002715 if ((adev->mode == AUDIO_MODE_IN_CALL) && !adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002716 (out == adev->primary_output)) {
2717 start_voice_call(adev);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002718 } else if ((adev->mode == AUDIO_MODE_IN_CALL) &&
2719 adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002720 (out == adev->primary_output)) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002721 /* Turn on bluetooth if needed */
2722 if ((out->devices & AUDIO_DEVICE_OUT_ALL_SCO) && !bt_sco_active) {
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002723 select_devices(adev, USECASE_VOICE_CALL);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002724 start_voice_session_bt_sco(adev->voice.session);
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002725 } else {
2726 /*
2727 * When we select different devices we need to restart the
2728 * voice call. The modem closes the stream on its end and
2729 * we do not get any output.
2730 */
2731 stop_voice_call(adev);
2732 start_voice_call(adev);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002733 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002734 }
2735 }
2736
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002737 pthread_mutex_unlock(&adev->lock);
2738 pthread_mutex_unlock(&out->lock);
2739#ifdef PREPROCESSING_ENABLED
2740 if (in) {
2741 /* The lock on adev->lock_inputs prevents input stream from being closed */
2742 lock_input_stream(in);
2743 pthread_mutex_lock(&adev->lock);
2744 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
2745 do_in_standby_l(in);
2746 pthread_mutex_unlock(&adev->lock);
2747 pthread_mutex_unlock(&in->lock);
2748 }
2749#endif
2750 pthread_mutex_unlock(&adev->lock_inputs);
2751 }
2752
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002753 amplifier_set_parameters(parms);
2754
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002755 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2756 parse_compress_metadata(out, parms);
2757 }
2758
2759 str_parms_destroy(parms);
2760
2761 if (ret > 0)
2762 ret = 0;
2763 ALOGV("%s: exit: code(%d)", __func__, ret);
2764 return ret;
2765}
2766
2767static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
2768{
2769 struct stream_out *out = (struct stream_out *)stream;
2770 struct str_parms *query = str_parms_create_str(keys);
2771 char *str;
2772 char value[256];
2773 struct str_parms *reply = str_parms_create();
2774 size_t i, j;
2775 int ret;
2776 bool first = true;
2777 ALOGV("%s: enter: keys - %s", __func__, keys);
2778 ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value));
2779 if (ret >= 0) {
2780 value[0] = '\0';
2781 i = 0;
2782 while (out->supported_channel_masks[i] != 0) {
2783 for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) {
2784 if (out_channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) {
2785 if (!first) {
2786 strcat(value, "|");
2787 }
2788 strcat(value, out_channels_name_to_enum_table[j].name);
2789 first = false;
2790 break;
2791 }
2792 }
2793 i++;
2794 }
2795 str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
2796 str = str_parms_to_str(reply);
2797 } else {
2798 str = strdup(keys);
2799 }
2800 str_parms_destroy(query);
2801 str_parms_destroy(reply);
2802 ALOGV("%s: exit: returns - %s", __func__, str);
2803 return str;
2804}
2805
2806static uint32_t out_get_latency(const struct audio_stream_out *stream)
2807{
2808 struct stream_out *out = (struct stream_out *)stream;
2809
2810 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
2811 return COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
2812
2813 return (out->config.period_count * out->config.period_size * 1000) /
2814 (out->config.rate);
2815}
2816
2817static int out_set_volume(struct audio_stream_out *stream, float left,
2818 float right)
2819{
2820 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002821
2822 if (out->usecase == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
2823 /* only take left channel into account: the API is for stereo anyway */
2824 out->muted = (left == 0.0f);
2825 return 0;
2826 } else if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002827 out_set_offload_volume(left, right);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002828 }
2829
2830 return -ENOSYS;
2831}
2832
Andreas Schneider3b643832017-01-31 11:48:22 +01002833#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002834static int fast_set_affinity(pid_t tid) {
2835 cpu_set_t cpu_set;
2836 int cpu_num;
2837 const char *irq_procfs = "/proc/asound/irq_affinity";
2838 FILE *fp;
2839
2840 if ((fp = fopen(irq_procfs, "r")) == NULL) {
2841 ALOGW("Procfs node %s not found", irq_procfs);
2842 return -1;
2843 }
2844
2845 if (fscanf(fp, "%d", &cpu_num) != 1) {
2846 ALOGW("Couldn't read CPU id from procfs node %s", irq_procfs);
2847 fclose(fp);
2848 return -1;
2849 }
2850 fclose(fp);
2851
2852 CPU_ZERO(&cpu_set);
2853 CPU_SET(cpu_num, &cpu_set);
2854 return sched_setaffinity(tid, sizeof(cpu_set), &cpu_set);
2855}
Andreas Schneider3b643832017-01-31 11:48:22 +01002856#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002857
2858static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
2859 size_t bytes)
2860{
2861 struct stream_out *out = (struct stream_out *)stream;
2862 struct audio_device *adev = out->dev;
2863 ssize_t ret = 0;
2864 struct pcm_device *pcm_device;
2865 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002866#ifdef PREPROCESSING_ENABLED
stenkinevgeniyd0a02c02018-05-08 07:17:53 +00002867 size_t frame_size = audio_stream_out_frame_size(stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002868 size_t in_frames = bytes / frame_size;
2869 size_t out_frames = in_frames;
2870 struct stream_in *in = NULL;
2871#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002872
2873 lock_output_stream(out);
2874
Andreas Schneider3b643832017-01-31 11:48:22 +01002875#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002876 if (out->usecase == USECASE_AUDIO_PLAYBACK && !out->is_fastmixer_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01002877 pid_t tid = gettid();
2878 int err;
2879
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002880 err = fast_set_affinity(tid);
2881 if (err < 0) {
2882 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
2883 }
2884 out->is_fastmixer_affinity_set = true;
2885 }
Andreas Schneider3b643832017-01-31 11:48:22 +01002886#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002887
2888 if (out->standby) {
2889#ifdef PREPROCESSING_ENABLED
2890 pthread_mutex_unlock(&out->lock);
2891 /* Prevent input stream from being closed */
2892 pthread_mutex_lock(&adev->lock_inputs);
2893 lock_output_stream(out);
2894 if (!out->standby) {
2895 pthread_mutex_unlock(&adev->lock_inputs);
2896 goto false_alarm;
2897 }
2898#endif
2899 pthread_mutex_lock(&adev->lock);
2900 ret = start_output_stream(out);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002901 if (ret == 0) {
2902 amplifier_output_stream_start(stream, out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD);
2903 }
2904
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002905 /* ToDo: If use case is compress offload should return 0 */
2906 if (ret != 0) {
2907 pthread_mutex_unlock(&adev->lock);
2908#ifdef PREPROCESSING_ENABLED
2909 pthread_mutex_unlock(&adev->lock_inputs);
2910#endif
2911 goto exit;
2912 }
2913 out->standby = false;
2914
2915#ifdef PREPROCESSING_ENABLED
2916 /* A change in output device may change the microphone selection */
2917 if (adev->active_input &&
2918 (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
2919 adev->active_input->source == AUDIO_SOURCE_MIC)) {
2920 in = adev->active_input;
2921 ALOGV("%s: enter:) force_input_standby true", __func__);
2922 }
2923#endif
2924 pthread_mutex_unlock(&adev->lock);
2925#ifdef PREPROCESSING_ENABLED
2926 if (!in) {
2927 /* Leave mutex locked iff in != NULL */
2928 pthread_mutex_unlock(&adev->lock_inputs);
2929 }
2930#endif
2931 }
Andreas Schneider5a2f1002017-02-09 10:59:04 +01002932#ifdef PREPROCESSING_ENABLED
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002933false_alarm:
Andreas Schneider5a2f1002017-02-09 10:59:04 +01002934#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002935
2936 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002937 ret = out_write_offload(stream, buffer, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002938 return ret;
2939 } else {
2940#ifdef PREPROCESSING_ENABLED
2941 if (android_atomic_acquire_load(&adev->echo_reference_generation)
2942 != out->echo_reference_generation) {
2943 pthread_mutex_lock(&adev->lock);
2944 if (out->echo_reference != NULL) {
2945 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
2946 release_echo_reference(out->echo_reference);
2947 }
2948 // note that adev->echo_reference_generation here can be different from the one
2949 // tested above but it doesn't matter as we now have the adev mutex and it is consistent
2950 // with what has been set by get_echo_reference() or put_echo_reference()
2951 out->echo_reference_generation = adev->echo_reference_generation;
2952 out->echo_reference = adev->echo_reference;
2953 ALOGV("%s: update echo reference generation %d", __func__,
2954 out->echo_reference_generation);
2955 pthread_mutex_unlock(&adev->lock);
2956 }
2957#endif
2958
2959 if (out->muted)
2960 memset((void *)buffer, 0, bytes);
2961 list_for_each(node, &out->pcm_dev_list) {
2962 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002963 if (pcm_device->pcm) {
2964#ifdef PREPROCESSING_ENABLED
2965 if (out->echo_reference != NULL && pcm_device->pcm_profile->devices != SND_DEVICE_OUT_SPEAKER) {
2966 struct echo_reference_buffer b;
2967 b.raw = (void *)buffer;
2968 b.frame_count = in_frames;
2969
2970 get_playback_delay(out, out_frames, &b);
2971 out->echo_reference->write(out->echo_reference, &b);
2972 }
2973#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002974 ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
stenkinevgeniyd0a02c02018-05-08 07:17:53 +00002975 pcm_device->status = pcm_write(pcm_device->pcm, (void *)buffer, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002976 if (pcm_device->status != 0)
2977 ret = pcm_device->status;
2978 }
2979 }
2980 if (ret == 0)
2981 out->written += bytes / (out->config.channels * sizeof(short));
2982 }
2983
2984exit:
2985 pthread_mutex_unlock(&out->lock);
2986
2987 if (ret != 0) {
2988 list_for_each(node, &out->pcm_dev_list) {
2989 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2990 if (pcm_device->pcm && pcm_device->status != 0)
2991 ALOGE("%s: error %zd - %s", __func__, ret, pcm_get_error(pcm_device->pcm));
2992 }
2993 out_standby(&out->stream.common);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01002994 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
2995 clock_gettime(CLOCK_MONOTONIC, &t);
2996 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
2997 const int64_t elapsed_time_since_last_write = now - out->last_write_time_us;
2998 int64_t sleep_time = bytes * 1000000LL / audio_stream_out_frame_size(stream) /
2999 out_get_sample_rate(&stream->common) - elapsed_time_since_last_write;
3000 if (sleep_time > 0) {
3001 usleep(sleep_time);
3002 } else {
3003 // we don't sleep when we exit standby (this is typical for a real alsa buffer).
3004 sleep_time = 0;
3005 }
3006 out->last_write_time_us = now + sleep_time;
3007 // last_write_time_us is an approximation of when the (simulated) alsa
3008 // buffer is believed completely full. The usleep above waits for more space
3009 // in the buffer, but by the end of the sleep the buffer is considered
3010 // topped-off.
3011 //
3012 // On the subsequent out_write(), we measure the elapsed time spent in
3013 // the mixer. This is subtracted from the sleep estimate based on frames,
3014 // thereby accounting for drain in the alsa buffer during mixing.
3015 // This is a crude approximation; we don't handle underruns precisely.
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003016 }
3017
3018#ifdef PREPROCESSING_ENABLED
3019 if (in) {
3020 /* The lock on adev->lock_inputs prevents input stream from being closed */
3021 lock_input_stream(in);
3022 pthread_mutex_lock(&adev->lock);
3023 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
3024 do_in_standby_l(in);
3025 pthread_mutex_unlock(&adev->lock);
3026 pthread_mutex_unlock(&in->lock);
3027 /* This mutex was left locked iff in != NULL */
3028 pthread_mutex_unlock(&adev->lock_inputs);
3029 }
3030#endif
3031
3032 return bytes;
3033}
3034
3035static int out_get_render_position(const struct audio_stream_out *stream,
3036 uint32_t *dsp_frames)
3037{
3038 struct stream_out *out = (struct stream_out *)stream;
3039 *dsp_frames = 0;
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003040 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
3041 return out_get_render_offload_position(out, dsp_frames);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003042 } else
3043 return -EINVAL;
3044}
3045
3046static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3047{
3048 (void)stream;
3049 (void)effect;
3050 return 0;
3051}
3052
3053static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3054{
3055 (void)stream;
3056 (void)effect;
3057 return 0;
3058}
3059
3060static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
3061 int64_t *timestamp)
3062{
3063 (void)stream;
3064 (void)timestamp;
3065 return -EINVAL;
3066}
3067
3068static int out_get_presentation_position(const struct audio_stream_out *stream,
3069 uint64_t *frames, struct timespec *timestamp)
3070{
3071 struct stream_out *out = (struct stream_out *)stream;
Victor Lourme5869cd32018-03-26 19:36:07 +02003072 int ret = -EINVAL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003073
3074 lock_output_stream(out);
3075
3076 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003077 ret = out_get_presentation_offload_position(out, frames, timestamp);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003078 } else {
Andreas Schneider97fa7f12017-02-11 14:21:56 +01003079 if (out->dev->voice.in_call) {
3080 ALOGVV("%s: in_call, do not handle PCMs", __func__);
3081 ret = 0;
3082 goto done;
3083 }
3084
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003085 /* FIXME: which device to read from? */
3086 if (!list_empty(&out->pcm_dev_list)) {
Andreas Schneiderd6359182017-02-08 16:58:22 +01003087 struct pcm_device *pcm_device;
3088 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003089 unsigned int avail;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003090
Andreas Schneiderd6359182017-02-08 16:58:22 +01003091 list_for_each(node, &out->pcm_dev_list) {
3092 pcm_device = node_to_item(node,
3093 struct pcm_device,
3094 stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003095
Andreas Schneiderd6359182017-02-08 16:58:22 +01003096 if (pcm_device->pcm != NULL) {
3097 if (pcm_get_htimestamp(pcm_device->pcm, &avail, timestamp) == 0) {
3098 size_t kernel_buffer_size = out->config.period_size * out->config.period_count;
3099 int64_t signed_frames = out->written - kernel_buffer_size + avail;
3100 /* This adjustment accounts for buffering after app processor.
3101 It is based on estimated DSP latency per use case, rather than exact. */
3102 signed_frames -=
3103 (render_latency(out->usecase) * out->sample_rate / 1000000LL);
3104
3105 /* It would be unusual for this value to be negative, but check just in case ... */
3106 if (signed_frames >= 0) {
3107 *frames = signed_frames;
3108 ret = 0;
3109 goto done;
3110 }
Andreas Schneiderd6359182017-02-08 16:58:22 +01003111 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003112 }
3113 }
3114 }
3115 }
3116
Andreas Schneiderd6359182017-02-08 16:58:22 +01003117done:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003118 pthread_mutex_unlock(&out->lock);
3119
3120 return ret;
3121}
3122
3123static int out_set_callback(struct audio_stream_out *stream,
3124 stream_callback_t callback, void *cookie)
3125{
3126 struct stream_out *out = (struct stream_out *)stream;
3127
3128 ALOGV("%s", __func__);
3129 lock_output_stream(out);
3130 out->offload_callback = callback;
3131 out->offload_cookie = cookie;
3132 pthread_mutex_unlock(&out->lock);
3133 return 0;
3134}
3135
3136static int out_pause(struct audio_stream_out* stream)
3137{
3138 struct stream_out *out = (struct stream_out *)stream;
3139 int status = -ENOSYS;
3140 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003141 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3142 status = out_pause_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003143 return status;
3144}
3145
3146static int out_resume(struct audio_stream_out* stream)
3147{
3148 struct stream_out *out = (struct stream_out *)stream;
3149 int status = -ENOSYS;
3150 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003151 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3152 status = out_resume_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003153 return status;
3154}
3155
3156static int out_drain(struct audio_stream_out* stream, audio_drain_type_t type )
3157{
3158 struct stream_out *out = (struct stream_out *)stream;
3159 int status = -ENOSYS;
3160 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003161 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3162 status = out_drain_offload(out, type);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003163 return status;
3164}
3165
3166static int out_flush(struct audio_stream_out* stream)
3167{
3168 struct stream_out *out = (struct stream_out *)stream;
3169 ALOGV("%s", __func__);
3170 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003171 return out_flush_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003172 }
3173 return -ENOSYS;
3174}
3175
3176/** audio_stream_in implementation **/
3177static uint32_t in_get_sample_rate(const struct audio_stream *stream)
3178{
3179 struct stream_in *in = (struct stream_in *)stream;
3180
3181 return in->requested_rate;
3182}
3183
3184static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
3185{
3186 (void)stream;
3187 (void)rate;
3188 return -ENOSYS;
3189}
3190
3191static uint32_t in_get_channels(const struct audio_stream *stream)
3192{
3193 struct stream_in *in = (struct stream_in *)stream;
3194
3195 return in->main_channels;
3196}
3197
3198static audio_format_t in_get_format(const struct audio_stream *stream)
3199{
3200 (void)stream;
3201 return AUDIO_FORMAT_PCM_16_BIT;
3202}
3203
3204static int in_set_format(struct audio_stream *stream, audio_format_t format)
3205{
3206 (void)stream;
3207 (void)format;
3208
3209 return -ENOSYS;
3210}
3211
3212static size_t in_get_buffer_size(const struct audio_stream *stream)
3213{
3214 struct stream_in *in = (struct stream_in *)stream;
3215
3216 return get_input_buffer_size(in->requested_rate,
3217 in_get_format(stream),
3218 audio_channel_count_from_in_mask(in->main_channels),
3219 in->usecase_type,
3220 in->devices);
3221}
3222
3223static int in_close_pcm_devices(struct stream_in *in)
3224{
3225 struct pcm_device *pcm_device;
3226 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003227
3228 list_for_each(node, &in->pcm_dev_list) {
3229 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3230 if (pcm_device) {
3231 if (pcm_device->pcm)
3232 pcm_close(pcm_device->pcm);
3233 pcm_device->pcm = NULL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003234 }
3235 }
3236 return 0;
3237}
3238
3239
3240/* must be called with stream and hw device mutex locked */
3241static int do_in_standby_l(struct stream_in *in)
3242{
3243 int status = 0;
3244
3245#ifdef PREPROCESSING_ENABLED
3246 struct audio_device *adev = in->dev;
3247#endif
3248 if (!in->standby) {
3249
3250 in_close_pcm_devices(in);
3251
3252#ifdef PREPROCESSING_ENABLED
3253 if (in->echo_reference != NULL) {
3254 /* stop reading from echo reference */
3255 in->echo_reference->read(in->echo_reference, NULL);
3256 put_echo_reference(adev, in->echo_reference);
3257 in->echo_reference = NULL;
3258 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003259#endif // PREPROCESSING_ENABLED
3260
3261 status = stop_input_stream(in);
3262
3263 if (in->read_buf) {
3264 free(in->read_buf);
3265 in->read_buf = NULL;
3266 }
3267
3268 in->standby = 1;
3269 }
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003270
3271 in->last_read_time_us = 0;
3272
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003273 return 0;
3274}
3275
3276// called with adev->lock_inputs locked
3277static int in_standby_l(struct stream_in *in)
3278{
3279 struct audio_device *adev = in->dev;
3280 int status = 0;
3281 lock_input_stream(in);
3282 if (!in->standby) {
3283 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003284 amplifier_input_stream_standby((struct audio_stream_in *) in);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003285 status = do_in_standby_l(in);
3286 pthread_mutex_unlock(&adev->lock);
3287 }
3288 pthread_mutex_unlock(&in->lock);
3289 return status;
3290}
3291
3292static int in_standby(struct audio_stream *stream)
3293{
3294 struct stream_in *in = (struct stream_in *)stream;
3295 struct audio_device *adev = in->dev;
3296 int status;
3297 ALOGV("%s: enter", __func__);
3298 pthread_mutex_lock(&adev->lock_inputs);
3299 status = in_standby_l(in);
3300 pthread_mutex_unlock(&adev->lock_inputs);
3301 ALOGV("%s: exit: status(%d)", __func__, status);
3302 return status;
3303}
3304
3305static int in_dump(const struct audio_stream *stream, int fd)
3306{
3307 (void)stream;
3308 (void)fd;
3309
3310 return 0;
3311}
3312
3313static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
3314{
3315 struct stream_in *in = (struct stream_in *)stream;
3316 struct audio_device *adev = in->dev;
3317 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003318 char value[32];
3319 int ret, val = 0;
3320 struct audio_usecase *uc_info;
3321 bool do_standby = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003322 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003323
3324 ALOGV("%s: enter: kvpairs=%s", __func__, kvpairs);
3325 parms = str_parms_create_str(kvpairs);
3326
3327 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
3328
3329 pthread_mutex_lock(&adev->lock_inputs);
3330 lock_input_stream(in);
3331 pthread_mutex_lock(&adev->lock);
3332 if (ret >= 0) {
3333 val = atoi(value);
3334 /* no audio source uses val == 0 */
3335 if (((int)in->source != val) && (val != 0)) {
3336 in->source = val;
3337 }
3338 }
3339
3340 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
3341 if (ret >= 0) {
3342 val = atoi(value);
3343 if (((int)in->devices != val) && (val != 0)) {
3344 in->devices = val;
3345 /* If recording is in progress, change the tx device to new device */
3346 if (!in->standby) {
3347 uc_info = get_usecase_from_id(adev, in->usecase);
3348 if (uc_info == NULL) {
3349 ALOGE("%s: Could not find the usecase (%d) in the list",
3350 __func__, in->usecase);
3351 } else {
3352 if (list_empty(&in->pcm_dev_list))
3353 ALOGE("%s: pcm device list empty", __func__);
3354 else {
3355 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3356 struct pcm_device, stream_list_node);
3357 if ((pcm_device->pcm_profile->devices & val & ~AUDIO_DEVICE_BIT_IN) == 0) {
3358 do_standby = true;
3359 }
3360 }
3361 }
3362 if (do_standby) {
3363 ret = do_in_standby_l(in);
3364 } else
3365 ret = select_devices(adev, in->usecase);
3366 }
3367 }
3368 }
3369 pthread_mutex_unlock(&adev->lock);
3370 pthread_mutex_unlock(&in->lock);
3371 pthread_mutex_unlock(&adev->lock_inputs);
3372 str_parms_destroy(parms);
3373
3374 if (ret > 0)
3375 ret = 0;
3376
3377 ALOGV("%s: exit: status(%d)", __func__, ret);
3378 return ret;
3379}
3380
3381static char* in_get_parameters(const struct audio_stream *stream,
3382 const char *keys)
3383{
3384 (void)stream;
3385 (void)keys;
3386
3387 return strdup("");
3388}
3389
3390static int in_set_gain(struct audio_stream_in *stream, float gain)
3391{
3392 (void)stream;
3393 (void)gain;
3394
3395 return 0;
3396}
3397
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003398static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
3399 size_t bytes)
3400{
3401 struct stream_in *in = (struct stream_in *)stream;
3402 struct audio_device *adev = in->dev;
3403 ssize_t frames = -1;
3404 int ret = -1;
3405 int read_and_process_successful = false;
3406
3407 size_t frames_rq = bytes / audio_stream_in_frame_size(stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003408
3409 /* no need to acquire adev->lock_inputs because API contract prevents a close */
3410 lock_input_stream(in);
3411
Andreas Schneider3b643832017-01-31 11:48:22 +01003412#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003413 if (in->usecase == USECASE_AUDIO_CAPTURE && !in->is_fastcapture_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003414 pid_t tid = gettid();
3415 int err;
3416
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003417 err = fast_set_affinity(tid);
3418 if (err < 0) {
3419 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
3420 }
3421 in->is_fastcapture_affinity_set = true;
3422 }
Andreas Schneider3b643832017-01-31 11:48:22 +01003423#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003424
3425 if (in->standby) {
3426 pthread_mutex_unlock(&in->lock);
3427 pthread_mutex_lock(&adev->lock_inputs);
3428 lock_input_stream(in);
3429 if (!in->standby) {
3430 pthread_mutex_unlock(&adev->lock_inputs);
3431 goto false_alarm;
3432 }
3433 pthread_mutex_lock(&adev->lock);
3434 ret = start_input_stream(in);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003435 if (ret == 0) {
3436 amplifier_input_stream_start(stream);
3437 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003438 pthread_mutex_unlock(&adev->lock);
3439 pthread_mutex_unlock(&adev->lock_inputs);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003440
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003441 if (ret != 0) {
3442 goto exit;
3443 }
3444 in->standby = 0;
3445 }
3446false_alarm:
3447
3448 if (!list_empty(&in->pcm_dev_list)) {
stenkinevgeniy44335362018-05-07 18:00:13 +00003449 /*
3450 * Read PCM and:
3451 * - resample if needed
3452 * - process if pre-processors are attached
3453 * - discard unwanted channels
3454 */
3455 frames = read_and_process_frames(in, buffer, frames_rq);
3456 if (frames >= 0)
3457 read_and_process_successful = true;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003458 }
3459
3460 /*
3461 * Instead of writing zeroes here, we could trust the hardware
3462 * to always provide zeroes when muted.
3463 */
3464 if (read_and_process_successful == true && adev->mic_mute)
3465 memset(buffer, 0, bytes);
3466
3467exit:
3468 pthread_mutex_unlock(&in->lock);
3469
3470 if (read_and_process_successful == false) {
3471 in_standby(&in->stream.common);
3472 ALOGV("%s: read failed - sleeping for buffer duration", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003473 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3474 clock_gettime(CLOCK_MONOTONIC, &t);
3475 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3476
3477 // we do a full sleep when exiting standby.
3478 const bool standby = in->last_read_time_us == 0;
3479 const int64_t elapsed_time_since_last_read = standby ?
3480 0 : now - in->last_read_time_us;
3481 int64_t sleep_time = bytes * 1000000LL / audio_stream_in_frame_size(stream) /
3482 in_get_sample_rate(&stream->common) - elapsed_time_since_last_read;
3483 if (sleep_time > 0) {
3484 usleep(sleep_time);
3485 } else {
3486 sleep_time = 0;
3487 }
3488 in->last_read_time_us = now + sleep_time;
3489 // last_read_time_us is an approximation of when the (simulated) alsa
3490 // buffer is drained by the read, and is empty.
3491 //
3492 // On the subsequent in_read(), we measure the elapsed time spent in
3493 // the recording thread. This is subtracted from the sleep estimate based on frames,
3494 // thereby accounting for fill in the alsa buffer during the interim.
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003495 memset(buffer, 0, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003496 }
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003497
3498 if (bytes > 0) {
3499 in->frames_read += bytes / audio_stream_in_frame_size(stream);
3500 }
3501
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003502 return bytes;
3503}
3504
3505static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
3506{
3507 (void)stream;
3508
3509 return 0;
3510}
3511
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003512static int in_get_capture_position(const struct audio_stream_in *stream,
3513 int64_t *frames, int64_t *time)
3514{
3515 if (stream == NULL || frames == NULL || time == NULL) {
3516 return -EINVAL;
3517 }
3518
3519 struct stream_in *in = (struct stream_in *)stream;
3520 struct pcm_device *pcm_device;
3521 int ret = -ENOSYS;
3522
3523 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3524 struct pcm_device, stream_list_node);
3525
3526 pthread_mutex_lock(&in->lock);
3527 if (pcm_device->pcm) {
3528 struct timespec timestamp;
3529 unsigned int avail;
3530 if (pcm_get_htimestamp(pcm_device->pcm, &avail, &timestamp) == 0) {
3531 *frames = in->frames_read + avail;
3532 *time = timestamp.tv_sec * 1000000000LL + timestamp.tv_nsec;
3533 ret = 0;
3534 }
3535 }
3536
3537 pthread_mutex_unlock(&in->lock);
3538 return ret;
3539}
3540
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003541static int add_remove_audio_effect(const struct audio_stream *stream,
3542 effect_handle_t effect,
3543 bool enable)
3544{
3545 struct stream_in *in = (struct stream_in *)stream;
3546 struct audio_device *adev = in->dev;
3547 int status = 0;
3548 effect_descriptor_t desc;
3549#ifdef PREPROCESSING_ENABLED
3550 int i;
3551#endif
3552 status = (*effect)->get_descriptor(effect, &desc);
3553 if (status != 0)
3554 return status;
3555
3556 ALOGI("add_remove_audio_effect(), effect type: %08x, enable: %d ", desc.type.timeLow, enable);
3557
3558 pthread_mutex_lock(&adev->lock_inputs);
3559 lock_input_stream(in);
3560 pthread_mutex_lock(&in->dev->lock);
3561#ifndef PREPROCESSING_ENABLED
3562 if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) &&
3563 in->enable_aec != enable &&
3564 (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0)) {
3565 in->enable_aec = enable;
3566 if (!in->standby)
3567 select_devices(in->dev, in->usecase);
3568 }
3569#else
3570 if ( (in->num_preprocessors > MAX_PREPROCESSORS) && (enable == true) ) {
3571 status = -ENOSYS;
3572 goto exit;
3573 }
3574 if ( enable == true ) {
3575 in->preprocessors[in->num_preprocessors].effect_itfe = effect;
3576 /* add the supported channel of the effect in the channel_configs */
3577 in_read_audio_effect_channel_configs(in, &in->preprocessors[in->num_preprocessors]);
3578 in->num_preprocessors ++;
3579 /* check compatibility between main channel supported and possible auxiliary channels */
3580 in_update_aux_channels(in, effect);//wesley crash
3581 in->aux_channels_changed = true;
3582 } else {
3583 /* if ( enable == false ) */
3584 if (in->num_preprocessors <= 0) {
3585 status = -ENOSYS;
3586 goto exit;
3587 }
3588 status = -EINVAL;
3589 for (i=0; i < in->num_preprocessors; i++) {
3590 if (status == 0) { /* status == 0 means an effect was removed from a previous slot */
3591 in->preprocessors[i - 1].effect_itfe = in->preprocessors[i].effect_itfe;
3592 in->preprocessors[i - 1].channel_configs = in->preprocessors[i].channel_configs;
3593 in->preprocessors[i - 1].num_channel_configs =
3594 in->preprocessors[i].num_channel_configs;
3595 ALOGV("add_remove_audio_effect moving fx from %d to %d", i, i-1);
3596 continue;
3597 }
3598 if ( in->preprocessors[i].effect_itfe == effect ) {
3599 ALOGV("add_remove_audio_effect found fx at index %d", i);
3600 free(in->preprocessors[i].channel_configs);
3601 status = 0;
3602 }
3603 }
3604 if (status != 0)
3605 goto exit;
3606 in->num_preprocessors--;
3607 /* if we remove one effect, at least the last proproc should be reset */
3608 in->preprocessors[in->num_preprocessors].num_channel_configs = 0;
3609 in->preprocessors[in->num_preprocessors].effect_itfe = NULL;
3610 in->preprocessors[in->num_preprocessors].channel_configs = NULL;
3611 in->aux_channels_changed = false;
3612 ALOGV("%s: enable(%d), in->aux_channels_changed(%d)", __func__, enable, in->aux_channels_changed);
3613 }
3614 ALOGI("%s: num_preprocessors = %d", __func__, in->num_preprocessors);
3615
3616 if ( memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
3617 in->enable_aec = enable;
3618 ALOGV("add_remove_audio_effect(), FX_IID_AEC, enable: %d", enable);
3619 if (!in->standby) {
3620 select_devices(in->dev, in->usecase);
3621 do_in_standby_l(in);
3622 }
3623 if (in->enable_aec == true) {
3624 in_configure_reverse(in);
3625 }
3626 }
3627exit:
3628#endif
3629 ALOGW_IF(status != 0, "add_remove_audio_effect() error %d", status);
3630 pthread_mutex_unlock(&in->dev->lock);
3631 pthread_mutex_unlock(&in->lock);
3632 pthread_mutex_unlock(&adev->lock_inputs);
3633 return status;
3634}
3635
3636static int in_add_audio_effect(const struct audio_stream *stream,
3637 effect_handle_t effect)
3638{
3639 ALOGV("%s: effect %p", __func__, effect);
3640 return add_remove_audio_effect(stream, effect, true);
3641}
3642
3643static int in_remove_audio_effect(const struct audio_stream *stream,
3644 effect_handle_t effect)
3645{
3646 ALOGV("%s: effect %p", __func__, effect);
3647 return add_remove_audio_effect(stream, effect, false);
3648}
3649
3650static int adev_open_output_stream(struct audio_hw_device *dev,
3651 audio_io_handle_t handle,
3652 audio_devices_t devices,
3653 audio_output_flags_t flags,
3654 struct audio_config *config,
3655 struct audio_stream_out **stream_out,
3656 const char *address __unused)
3657{
3658 struct audio_device *adev = (struct audio_device *)dev;
3659 struct stream_out *out;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003660 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003661 struct pcm_device_profile *pcm_profile;
3662
3663 ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
3664 __func__, config->sample_rate, config->channel_mask, devices, flags);
3665 *stream_out = NULL;
3666 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
Andreas Schneider56204f62017-01-31 08:17:32 +01003667 if (out == NULL) {
3668 ret = -ENOMEM;
3669 goto error_config;
3670 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003671
3672 if (devices == AUDIO_DEVICE_NONE)
3673 devices = AUDIO_DEVICE_OUT_SPEAKER;
3674
3675 out->flags = flags;
3676 out->devices = devices;
3677 out->dev = adev;
3678 out->format = config->format;
3679 out->sample_rate = config->sample_rate;
3680 out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3681 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
3682 out->handle = handle;
3683
3684 pcm_profile = get_pcm_device(PCM_PLAYBACK, devices);
3685 if (pcm_profile == NULL) {
3686 ret = -EINVAL;
3687 goto error_open;
3688 }
3689 out->config = pcm_profile->config;
3690
3691 /* Init use case and pcm_config */
3692 if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
3693 if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version ||
3694 config->offload_info.size != AUDIO_INFO_INITIALIZER.size) {
3695 ALOGE("%s: Unsupported Offload information", __func__);
3696 ret = -EINVAL;
3697 goto error_open;
3698 }
3699 if (!is_supported_format(config->offload_info.format)) {
3700 ALOGE("%s: Unsupported audio format", __func__);
3701 ret = -EINVAL;
3702 goto error_open;
3703 }
3704
3705 out->compr_config.codec = (struct snd_codec *)
3706 calloc(1, sizeof(struct snd_codec));
Andreas Schneider56204f62017-01-31 08:17:32 +01003707 if (out->compr_config.codec == NULL) {
3708 ret = -ENOMEM;
3709 goto error_open;
3710 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003711
3712 out->usecase = USECASE_AUDIO_PLAYBACK_OFFLOAD;
3713 if (config->offload_info.channel_mask)
3714 out->channel_mask = config->offload_info.channel_mask;
3715 else if (config->channel_mask)
3716 out->channel_mask = config->channel_mask;
3717 out->format = config->offload_info.format;
3718 out->sample_rate = config->offload_info.sample_rate;
3719
3720 out->stream.set_callback = out_set_callback;
3721 out->stream.pause = out_pause;
3722 out->stream.resume = out_resume;
3723 out->stream.drain = out_drain;
3724 out->stream.flush = out_flush;
3725
3726 out->compr_config.codec->id =
3727 get_snd_codec_id(config->offload_info.format);
3728 out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
3729 out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
3730 out->compr_config.codec->sample_rate = config->offload_info.sample_rate;
3731 out->compr_config.codec->bit_rate =
3732 config->offload_info.bit_rate;
3733 out->compr_config.codec->ch_in =
3734 audio_channel_count_from_out_mask(config->channel_mask);
3735 out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
3736
3737 if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
3738 out->non_blocking = 1;
3739
3740 out->send_new_metadata = 1;
3741 create_offload_callback_thread(out);
3742 out->offload_state = OFFLOAD_STATE_IDLE;
3743
3744 ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
3745 __func__, config->offload_info.version,
3746 config->offload_info.bit_rate);
3747 } else if (out->flags & (AUDIO_OUTPUT_FLAG_DEEP_BUFFER)) {
3748 out->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01003749 out->config = pcm_device_deep_buffer.config;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003750 out->sample_rate = out->config.rate;
3751 ALOGV("%s: use AUDIO_PLAYBACK_DEEP_BUFFER",__func__);
3752 } else {
3753 out->usecase = USECASE_AUDIO_PLAYBACK;
3754 out->sample_rate = out->config.rate;
3755 }
3756
3757 if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
3758 if (adev->primary_output == NULL)
3759 adev->primary_output = out;
3760 else {
3761 ALOGE("%s: Primary output is already opened", __func__);
3762 ret = -EEXIST;
3763 goto error_open;
3764 }
3765 }
3766
3767 /* Check if this usecase is already existing */
3768 pthread_mutex_lock(&adev->lock);
3769 if (get_usecase_from_id(adev, out->usecase) != NULL) {
3770 ALOGE("%s: Usecase (%d) is already present", __func__, out->usecase);
3771 pthread_mutex_unlock(&adev->lock);
3772 ret = -EEXIST;
3773 goto error_open;
3774 }
3775 pthread_mutex_unlock(&adev->lock);
3776
3777 out->stream.common.get_sample_rate = out_get_sample_rate;
3778 out->stream.common.set_sample_rate = out_set_sample_rate;
3779 out->stream.common.get_buffer_size = out_get_buffer_size;
3780 out->stream.common.get_channels = out_get_channels;
3781 out->stream.common.get_format = out_get_format;
3782 out->stream.common.set_format = out_set_format;
3783 out->stream.common.standby = out_standby;
3784 out->stream.common.dump = out_dump;
3785 out->stream.common.set_parameters = out_set_parameters;
3786 out->stream.common.get_parameters = out_get_parameters;
3787 out->stream.common.add_audio_effect = out_add_audio_effect;
3788 out->stream.common.remove_audio_effect = out_remove_audio_effect;
3789 out->stream.get_latency = out_get_latency;
3790 out->stream.set_volume = out_set_volume;
3791 out->stream.write = out_write;
3792 out->stream.get_render_position = out_get_render_position;
3793 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
3794 out->stream.get_presentation_position = out_get_presentation_position;
3795
3796 out->standby = 1;
3797 /* out->muted = false; by calloc() */
3798 /* out->written = 0; by calloc() */
3799
3800 pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
3801 pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
3802 pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
3803
3804 config->format = out->stream.common.get_format(&out->stream.common);
3805 config->channel_mask = out->stream.common.get_channels(&out->stream.common);
3806 config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
3807
3808 out->is_fastmixer_affinity_set = false;
3809
3810 *stream_out = &out->stream;
3811 ALOGV("%s: exit", __func__);
3812 return 0;
3813
3814error_open:
3815 free(out);
3816 *stream_out = NULL;
Andreas Schneider56204f62017-01-31 08:17:32 +01003817error_config:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003818 ALOGV("%s: exit: ret %d", __func__, ret);
3819 return ret;
3820}
3821
3822static void adev_close_output_stream(struct audio_hw_device *dev,
3823 struct audio_stream_out *stream)
3824{
3825 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003826 (void)dev;
3827
3828 ALOGV("%s: enter", __func__);
3829 out_standby(&stream->common);
3830 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
3831 destroy_offload_callback_thread(out);
3832
3833 if (out->compr_config.codec != NULL)
3834 free(out->compr_config.codec);
3835 }
3836 pthread_cond_destroy(&out->cond);
3837 pthread_mutex_destroy(&out->lock);
3838 free(stream);
3839 ALOGV("%s: exit", __func__);
3840}
3841
3842static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
3843{
3844 struct audio_device *adev = (struct audio_device *)dev;
3845 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003846 char value[32];
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003847#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003848 int val;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003849#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003850 int ret;
3851
3852 ALOGV("%s: enter: %s", __func__, kvpairs);
3853
3854 parms = str_parms_create_str(kvpairs);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003855
Andreas Schneider05bc1882017-02-09 14:03:11 +01003856 /******************************************************
3857 *** BT SCO
3858 ******************************************************/
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003859 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
3860 if (ret >= 0) {
3861 /* When set to false, HAL should disable EC and NS
3862 * But it is currently not supported.
3863 */
3864 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
Andreas Schneider74ef3a12017-02-02 18:29:12 +01003865 adev->voice.bluetooth_nrec = true;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003866 else
Andreas Schneider74ef3a12017-02-02 18:29:12 +01003867 adev->voice.bluetooth_nrec = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003868 }
3869
Andreas Schneider05bc1882017-02-09 14:03:11 +01003870 ret = str_parms_get_str(parms,
3871 AUDIO_PARAMETER_KEY_BT_SCO_WB,
3872 value,
3873 sizeof(value));
3874 if (ret >= 0) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01003875 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) {
3876 adev->voice.bluetooth_wb = true;
Andreas Schneider05bc1882017-02-09 14:03:11 +01003877 } else {
3878 adev->voice.bluetooth_wb = false;
3879 }
3880 }
3881
Andreas Schneiderecd17ce2017-02-09 10:45:21 +01003882 ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
3883 if (ret >= 0) {
3884 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
3885 adev->screen_off = false;
3886 else
3887 adev->screen_off = true;
3888 }
3889
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01003890#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003891 ret = str_parms_get_int(parms, "rotation", &val);
3892 if (ret >= 0) {
3893 bool reverse_speakers = false;
3894 switch(val) {
3895 /* FIXME: note that the code below assumes that the speakers are in the correct placement
3896 relative to the user when the device is rotated 90deg from its default rotation. This
3897 assumption is device-specific, not platform-specific like this code. */
3898 case 270:
3899 reverse_speakers = true;
3900 break;
3901 case 0:
3902 case 90:
3903 case 180:
3904 break;
3905 default:
3906 ALOGE("%s: unexpected rotation of %d", __func__, val);
3907 }
3908 pthread_mutex_lock(&adev->lock);
3909 if (adev->speaker_lr_swap != reverse_speakers) {
3910 adev->speaker_lr_swap = reverse_speakers;
3911 /* only update the selected device if there is active pcm playback */
3912 struct audio_usecase *usecase;
3913 struct listnode *node;
3914 list_for_each(node, &adev->usecase_list) {
3915 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
3916 if (usecase->type == PCM_PLAYBACK) {
3917 select_devices(adev, usecase->id);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003918 break;
3919 }
3920 }
3921 }
3922 pthread_mutex_unlock(&adev->lock);
3923 }
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01003924#endif /* SWAP_SPEAKER_ON_SCREEN_ROTATION */
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003925
3926 str_parms_destroy(parms);
3927
3928 if (ret > 0)
3929 ret = 0;
3930
3931 ALOGV("%s: exit with code(%d)", __func__, ret);
3932 return ret;
3933}
3934
3935static char* adev_get_parameters(const struct audio_hw_device *dev,
3936 const char *keys)
3937{
3938 (void)dev;
3939 (void)keys;
3940
3941 return strdup("");
3942}
3943
3944static int adev_init_check(const struct audio_hw_device *dev)
3945{
3946 (void)dev;
3947
3948 return 0;
3949}
3950
3951static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
3952{
3953 int ret = 0;
3954 struct audio_device *adev = (struct audio_device *)dev;
3955 pthread_mutex_lock(&adev->lock);
3956 /* cache volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01003957 adev->voice.volume = volume;
3958 ret = set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003959 pthread_mutex_unlock(&adev->lock);
3960 return ret;
3961}
3962
3963static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
3964{
3965 (void)dev;
3966 (void)volume;
3967
3968 return -ENOSYS;
3969}
3970
3971static int adev_get_master_volume(struct audio_hw_device *dev,
3972 float *volume)
3973{
3974 (void)dev;
3975 (void)volume;
3976
3977 return -ENOSYS;
3978}
3979
3980static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
3981{
3982 (void)dev;
3983 (void)muted;
3984
3985 return -ENOSYS;
3986}
3987
3988static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
3989{
3990 (void)dev;
3991 (void)muted;
3992
3993 return -ENOSYS;
3994}
3995
3996static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
3997{
3998 struct audio_device *adev = (struct audio_device *)dev;
3999
4000 pthread_mutex_lock(&adev->lock);
4001 if (adev->mode != mode) {
4002 ALOGI("%s mode = %d", __func__, mode);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004003 if (amplifier_set_mode(mode) != 0) {
4004 ALOGE("Failed setting amplifier mode");
4005 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004006 adev->mode = mode;
Christopher N. Hesse6c0020c2017-11-17 20:41:11 +01004007
4008 if ((mode == AUDIO_MODE_NORMAL) && adev->voice.in_call) {
4009 stop_voice_call(adev);
4010 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004011 }
4012 pthread_mutex_unlock(&adev->lock);
4013 return 0;
4014}
4015
4016static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
4017{
4018 struct audio_device *adev = (struct audio_device *)dev;
4019 int err = 0;
4020
4021 pthread_mutex_lock(&adev->lock);
4022 adev->mic_mute = state;
4023
4024 if (adev->mode == AUDIO_MODE_IN_CALL) {
Andreas Schneider107a8482017-02-06 12:36:31 +01004025 set_voice_session_mic_mute(adev->voice.session, state);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004026 }
4027
4028 pthread_mutex_unlock(&adev->lock);
4029 return err;
4030}
4031
4032static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
4033{
4034 struct audio_device *adev = (struct audio_device *)dev;
4035
4036 *state = adev->mic_mute;
4037
4038 return 0;
4039}
4040
4041static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
4042 const struct audio_config *config)
4043{
4044 (void)dev;
4045
4046 /* NOTE: we default to built in mic which may cause a mismatch between what we
4047 * report here and the actual buffer size
4048 */
4049 return get_input_buffer_size(config->sample_rate,
4050 config->format,
4051 audio_channel_count_from_in_mask(config->channel_mask),
4052 PCM_CAPTURE /* usecase_type */,
4053 AUDIO_DEVICE_IN_BUILTIN_MIC);
4054}
4055
4056static int adev_open_input_stream(struct audio_hw_device *dev,
4057 audio_io_handle_t handle __unused,
4058 audio_devices_t devices,
4059 struct audio_config *config,
4060 struct audio_stream_in **stream_in,
4061 audio_input_flags_t flags,
4062 const char *address __unused,
4063 audio_source_t source)
4064{
4065 struct audio_device *adev = (struct audio_device *)dev;
4066 struct stream_in *in;
4067 struct pcm_device_profile *pcm_profile;
4068
4069 ALOGV("%s: enter", __func__);
4070
4071 *stream_in = NULL;
4072 if (check_input_parameters(config->sample_rate, config->format,
4073 audio_channel_count_from_in_mask(config->channel_mask)) != 0)
4074 return -EINVAL;
4075
stenkinevgeniy44335362018-05-07 18:00:13 +00004076 usecase_type_t usecase_type = flags & AUDIO_INPUT_FLAG_FAST ?
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004077 PCM_CAPTURE_LOW_LATENCY : PCM_CAPTURE;
4078 pcm_profile = get_pcm_device(usecase_type, devices);
4079 if (pcm_profile == NULL && usecase_type == PCM_CAPTURE_LOW_LATENCY) {
4080 // a low latency profile may not exist for that device, fall back
4081 // to regular capture. the MixerThread automatically changes
4082 // to non-fast capture based on the buffer size.
4083 flags &= ~AUDIO_INPUT_FLAG_FAST;
4084 usecase_type = PCM_CAPTURE;
4085 pcm_profile = get_pcm_device(usecase_type, devices);
4086 }
4087 if (pcm_profile == NULL)
4088 return -EINVAL;
4089
4090 in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
Andreas Schneider56204f62017-01-31 08:17:32 +01004091 if (in == NULL) {
4092 return -ENOMEM;
4093 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004094
4095 in->stream.common.get_sample_rate = in_get_sample_rate;
4096 in->stream.common.set_sample_rate = in_set_sample_rate;
4097 in->stream.common.get_buffer_size = in_get_buffer_size;
4098 in->stream.common.get_channels = in_get_channels;
4099 in->stream.common.get_format = in_get_format;
4100 in->stream.common.set_format = in_set_format;
4101 in->stream.common.standby = in_standby;
4102 in->stream.common.dump = in_dump;
4103 in->stream.common.set_parameters = in_set_parameters;
4104 in->stream.common.get_parameters = in_get_parameters;
4105 in->stream.common.add_audio_effect = in_add_audio_effect;
4106 in->stream.common.remove_audio_effect = in_remove_audio_effect;
4107 in->stream.set_gain = in_set_gain;
4108 in->stream.read = in_read;
4109 in->stream.get_input_frames_lost = in_get_input_frames_lost;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004110 in->stream.get_capture_position = in_get_capture_position;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004111
4112 in->devices = devices;
4113 in->source = source;
4114 in->dev = adev;
4115 in->standby = 1;
4116 in->main_channels = config->channel_mask;
4117 in->requested_rate = config->sample_rate;
4118 if (config->sample_rate != CAPTURE_DEFAULT_SAMPLING_RATE)
4119 flags = flags & ~AUDIO_INPUT_FLAG_FAST;
4120 in->input_flags = flags;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004121 // in->frames_read = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004122 /* HW codec is limited to default channels. No need to update with
4123 * requested channels */
4124 in->config = pcm_profile->config;
4125
4126 /* Update config params with the requested sample rate and channels */
stenkinevgeniy44335362018-05-07 18:00:13 +00004127 in->usecase = USECASE_AUDIO_CAPTURE;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004128 in->usecase_type = usecase_type;
4129
4130 pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
4131 pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL);
4132
4133 in->is_fastcapture_affinity_set = false;
4134
4135 *stream_in = &in->stream;
4136 ALOGV("%s: exit", __func__);
4137 return 0;
4138}
4139
4140static void adev_close_input_stream(struct audio_hw_device *dev,
4141 struct audio_stream_in *stream)
4142{
4143 struct audio_device *adev = (struct audio_device *)dev;
4144 struct stream_in *in = (struct stream_in*)stream;
4145 ALOGV("%s", __func__);
4146
4147 /* prevent concurrent out_set_parameters, or out_write from standby */
4148 pthread_mutex_lock(&adev->lock_inputs);
4149
Andreas Schneidercabe5e62017-01-30 10:57:06 +01004150 if (in->read_buf) {
4151 free(in->read_buf);
4152 in->read_buf = NULL;
4153 }
4154
4155 if (in->resampler) {
4156 release_resampler(in->resampler);
4157 in->resampler = NULL;
4158 }
4159
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004160#ifdef PREPROCESSING_ENABLED
4161 int i;
4162
4163 for (i=0; i<in->num_preprocessors; i++) {
4164 free(in->preprocessors[i].channel_configs);
4165 }
4166
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004167 if (in->proc_buf_in) {
4168 free(in->proc_buf_in);
4169 in->proc_buf_in = NULL;
4170 }
4171
4172 if (in->proc_buf_out) {
4173 free(in->proc_buf_out);
4174 in->proc_buf_out = NULL;
4175 }
4176
4177 if (in->ref_buf) {
4178 free(in->ref_buf);
4179 in->ref_buf = NULL;
4180 }
4181
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004182#endif
4183
4184 in_standby_l(in);
4185 free(stream);
4186
4187 pthread_mutex_unlock(&adev->lock_inputs);
4188
4189 return;
4190}
4191
4192static int adev_dump(const audio_hw_device_t *device, int fd)
4193{
4194 (void)device;
4195 (void)fd;
4196
4197 return 0;
4198}
4199
4200static int adev_close(hw_device_t *device)
4201{
4202 struct audio_device *adev = (struct audio_device *)device;
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004203 voice_session_deinit(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004204 audio_device_ref_count--;
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004205 if (audio_device_ref_count == 0) {
4206 if (amplifier_close() != 0) {
4207 ALOGE("Amplifier close failed");
4208 }
4209 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004210 free(adev->snd_dev_ref_cnt);
4211 free_mixer_list(adev);
4212 free(device);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004213
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004214 adev = NULL;
4215
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004216 return 0;
4217}
4218
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004219/* This returns true if the input parameter looks at all plausible as a low latency period size,
4220 * or false otherwise. A return value of true doesn't mean the value is guaranteed to work,
4221 * just that it _might_ work.
4222 */
4223static bool period_size_is_plausible_for_low_latency(int period_size)
4224{
4225 switch (period_size) {
4226 case 64:
4227 case 96:
4228 case 128:
4229 case 192:
4230 case 256:
4231 return true;
4232 default:
4233 return false;
4234 }
4235}
4236
4237static int adev_open(const hw_module_t *module, const char *name,
4238 hw_device_t **device)
4239{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004240 ALOGV("%s: enter", __func__);
4241 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
4242
Andreas Schneider56204f62017-01-31 08:17:32 +01004243 *device = NULL;
4244
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004245 adev = calloc(1, sizeof(struct audio_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01004246 if (adev == NULL) {
4247 return -ENOMEM;
4248 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004249
4250 adev->device.common.tag = HARDWARE_DEVICE_TAG;
4251 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
4252 adev->device.common.module = (struct hw_module_t *)module;
4253 adev->device.common.close = adev_close;
4254
4255 adev->device.init_check = adev_init_check;
4256 adev->device.set_voice_volume = adev_set_voice_volume;
4257 adev->device.set_master_volume = adev_set_master_volume;
4258 adev->device.get_master_volume = adev_get_master_volume;
4259 adev->device.set_master_mute = adev_set_master_mute;
4260 adev->device.get_master_mute = adev_get_master_mute;
4261 adev->device.set_mode = adev_set_mode;
4262 adev->device.set_mic_mute = adev_set_mic_mute;
4263 adev->device.get_mic_mute = adev_get_mic_mute;
4264 adev->device.set_parameters = adev_set_parameters;
4265 adev->device.get_parameters = adev_get_parameters;
4266 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
4267 adev->device.open_output_stream = adev_open_output_stream;
4268 adev->device.close_output_stream = adev_close_output_stream;
4269 adev->device.open_input_stream = adev_open_input_stream;
4270 adev->device.close_input_stream = adev_close_input_stream;
4271 adev->device.dump = adev_dump;
4272
4273 /* Set the default route before the PCM stream is opened */
4274 adev->mode = AUDIO_MODE_NORMAL;
4275 adev->active_input = NULL;
4276 adev->primary_output = NULL;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004277
4278 adev->voice.volume = 1.0f;
4279 adev->voice.bluetooth_nrec = true;
4280 adev->voice.in_call = false;
Christopher N. Hessee4a1c592018-01-16 18:33:38 +01004281 adev->voice.bluetooth_wb = false;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004282
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004283 /* adev->cur_hdmi_channels = 0; by calloc() */
4284 adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
Andreas Schneider56204f62017-01-31 08:17:32 +01004285 if (adev->snd_dev_ref_cnt == NULL) {
4286 free(adev);
4287 return -ENOMEM;
4288 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004289
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004290 adev->ns_in_voice_rec = false;
4291
4292 list_init(&adev->usecase_list);
4293
4294 if (mixer_init(adev) != 0) {
4295 free(adev->snd_dev_ref_cnt);
4296 free(adev);
4297 ALOGE("%s: Failed to init, aborting.", __func__);
4298 *device = NULL;
4299 return -EINVAL;
4300 }
4301
4302 if (access(OFFLOAD_FX_LIBRARY_PATH, R_OK) == 0) {
4303 adev->offload_fx_lib = dlopen(OFFLOAD_FX_LIBRARY_PATH, RTLD_NOW);
4304 if (adev->offload_fx_lib == NULL) {
4305 ALOGE("%s: DLOPEN failed for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4306 } else {
4307 ALOGV("%s: DLOPEN successful for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4308 adev->offload_fx_start_output =
4309 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4310 "visualizer_hal_start_output");
4311 adev->offload_fx_stop_output =
4312 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4313 "visualizer_hal_stop_output");
4314 }
4315 }
4316
Christopher N. Hesse696959d2017-02-02 20:49:55 +01004317 adev->voice.session = voice_session_init(adev);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004318 if (adev->voice.session == NULL) {
4319 ALOGE("%s: Failed to initialize voice session data", __func__);
4320
4321 free(adev->snd_dev_ref_cnt);
4322 free(adev);
4323
4324 *device = NULL;
4325 return -EINVAL;
4326 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004327
Christopher N. Hessec487bbe2018-07-12 13:51:43 +02004328 if (amplifier_open() != -ENOENT) {
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004329 ALOGE("Amplifier initialization failed");
4330 }
4331
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004332 *device = &adev->device.common;
4333
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004334 audio_device_ref_count++;
4335
4336 char value[PROPERTY_VALUE_MAX];
4337 if (property_get("audio_hal.period_size", value, NULL) > 0) {
4338 int trial = atoi(value);
4339 if (period_size_is_plausible_for_low_latency(trial)) {
4340
4341 pcm_device_playback.config.period_size = trial;
4342 pcm_device_playback.config.start_threshold =
4343 PLAYBACK_START_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4344 pcm_device_playback.config.stop_threshold =
4345 PLAYBACK_STOP_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4346
4347 pcm_device_capture_low_latency.config.period_size = trial;
4348 }
4349 }
4350
4351 ALOGV("%s: exit", __func__);
4352 return 0;
4353}
4354
4355static struct hw_module_methods_t hal_module_methods = {
4356 .open = adev_open,
4357};
4358
4359struct audio_module HAL_MODULE_INFO_SYM = {
4360 .common = {
4361 .tag = HARDWARE_MODULE_TAG,
4362 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
4363 .hal_api_version = HARDWARE_HAL_API_VERSION,
4364 .id = AUDIO_HARDWARE_MODULE_ID,
Christopher N. Hessec8502b92017-01-28 14:02:15 +01004365 .name = "Samsung Audio HAL",
4366 .author = "The LineageOS Project",
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004367 .methods = &hal_module_methods,
4368 },
4369};