blob: 8194d1fd4eec4ee96e0427e9201f14678b01db09 [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) {
221 ALOGV("%s: Failed to obtain reference to amplifier module: %s\n",
222 __func__, strerror(-rc));
223 return -ENODEV;
224 }
225
226 rc = amplifier_device_open((const hw_module_t *) module, &adev->amp);
227 if (rc) {
228 ALOGV("%s: Failed to open amplifier hardware device: %s\n",
229 __func__, strerror(-rc));
230 return -ENODEV;
231 }
232
233 return 0;
234}
235
236static int amplifier_set_input_devices(uint32_t devices)
237{
238 amplifier_device_t *amp = get_amplifier_device();
239 if (amp && amp->set_input_devices)
240 return amp->set_input_devices(amp, devices);
241
242 return 0;
243}
244
245static int amplifier_set_output_devices(uint32_t devices)
246{
247 amplifier_device_t *amp = get_amplifier_device();
248 if (amp && amp->set_output_devices)
249 return amp->set_output_devices(amp, devices);
250
251 return 0;
252}
253
254static int amplifier_enable_devices(uint32_t devices, bool enable)
255{
256 amplifier_device_t *amp = get_amplifier_device();
257 bool is_output = devices > SND_DEVICE_OUT_BEGIN &&
258 devices < SND_DEVICE_OUT_END;
259
260 if (amp && amp->enable_output_devices && is_output)
261 return amp->enable_output_devices(amp, devices, enable);
262
263 if (amp && amp->enable_input_devices && !is_output)
264 return amp->enable_input_devices(amp, devices, enable);
265
266 return 0;
267}
268
269static int amplifier_set_mode(audio_mode_t mode)
270{
271 amplifier_device_t *amp = get_amplifier_device();
272 if (amp && amp->set_mode)
273 return amp->set_mode(amp, mode);
274
275 return 0;
276}
277
278static int amplifier_output_stream_start(struct audio_stream_out *stream,
279 bool offload)
280{
281 amplifier_device_t *amp = get_amplifier_device();
282 if (amp && amp->output_stream_start)
283 return amp->output_stream_start(amp, stream, offload);
284
285 return 0;
286}
287
288static int amplifier_input_stream_start(struct audio_stream_in *stream)
289{
290 amplifier_device_t *amp = get_amplifier_device();
291 if (amp && amp->input_stream_start)
292 return amp->input_stream_start(amp, stream);
293
294 return 0;
295}
296
297static int amplifier_output_stream_standby(struct audio_stream_out *stream)
298{
299 amplifier_device_t *amp = get_amplifier_device();
300 if (amp && amp->output_stream_standby)
301 return amp->output_stream_standby(amp, stream);
302
303 return 0;
304}
305
306static int amplifier_input_stream_standby(struct audio_stream_in *stream)
307{
308 amplifier_device_t *amp = get_amplifier_device();
309 if (amp && amp->input_stream_standby)
310 return amp->input_stream_standby(amp, stream);
311
312 return 0;
313}
314
315static int amplifier_set_parameters(struct str_parms *parms)
316{
317 amplifier_device_t *amp = get_amplifier_device();
318 if (amp && amp->set_parameters)
319 return amp->set_parameters(amp, parms);
320
321 return 0;
322}
323
324static int amplifier_close(void)
325{
326 amplifier_device_t *amp = get_amplifier_device();
327 if (amp)
328 amplifier_device_close(amp);
329
330 return 0;
331}
332
Andreas Schneider759368f2017-02-02 16:11:14 +0100333struct timespec time_spec_diff(struct timespec time1, struct timespec time0) {
334 struct timespec ret;
335 int xsec = 0;
Andreas Schneider759368f2017-02-02 16:11:14 +0100336
337 if (time0.tv_nsec > time1.tv_nsec) {
338 xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1));
339 time0.tv_nsec -= (long int) (1E9 * xsec);
340 time0.tv_sec += xsec;
341 }
342
343 if ((time1.tv_nsec - time0.tv_nsec) > 1E9) {
344 xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9);
345 time0.tv_nsec += (long int) (1E9 * xsec);
346 time0.tv_sec -= xsec;
347 }
348
Paul Keithf114e2e2017-02-14 20:41:33 -0600349 ret.tv_sec = labs(time1.tv_sec - time0.tv_sec);
350 ret.tv_nsec = labs(time1.tv_nsec - time0.tv_nsec);
Andreas Schneider759368f2017-02-02 16:11:14 +0100351
352 return ret;
353}
354
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100355static bool is_supported_format(audio_format_t format)
356{
357 if (format == AUDIO_FORMAT_MP3 ||
358 ((format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_AAC))
359 return true;
360
361 return false;
362}
363
364static int get_snd_codec_id(audio_format_t format)
365{
366 int id = 0;
367
368 switch (format & AUDIO_FORMAT_MAIN_MASK) {
369 case AUDIO_FORMAT_MP3:
370 id = SND_AUDIOCODEC_MP3;
371 break;
372 case AUDIO_FORMAT_AAC:
373 id = SND_AUDIOCODEC_AAC;
374 break;
375 default:
376 ALOGE("%s: Unsupported audio format", __func__);
377 }
378
379 return id;
380}
381
382/* Array to store sound devices */
383static const char * const device_table[SND_DEVICE_MAX] = {
384 [SND_DEVICE_NONE] = "none",
385 /* Playback sound devices */
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100386 [SND_DEVICE_OUT_EARPIECE] = "earpiece",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100387 [SND_DEVICE_OUT_SPEAKER] = "speaker",
388 [SND_DEVICE_OUT_HEADPHONES] = "headphones",
389 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100390 [SND_DEVICE_OUT_VOICE_EARPIECE] = "voice-earpiece",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100391 [SND_DEVICE_OUT_VOICE_EARPIECE_WB] = "voice-earpiece-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100392 [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100393 [SND_DEVICE_OUT_VOICE_SPEAKER_WB] = "voice-speaker-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100394 [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100395 [SND_DEVICE_OUT_VOICE_HEADPHONES_WB] = "voice-headphones-wb",
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100396 [SND_DEVICE_OUT_VOICE_BT_SCO] = "voice-bt-sco-headset",
397 [SND_DEVICE_OUT_VOICE_BT_SCO_WB] = "voice-bt-sco-headset-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100398 [SND_DEVICE_OUT_HDMI] = "hdmi",
399 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
400 [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100401
402 /* Capture sound devices */
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100403 [SND_DEVICE_IN_EARPIECE_MIC] = "earpiece-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100404 [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
405 [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100406 [SND_DEVICE_IN_EARPIECE_MIC_AEC] = "earpiece-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100407 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "voice-speaker-mic",
408 [SND_DEVICE_IN_HEADSET_MIC_AEC] = "headset-mic",
Andreas Schneider82f32482017-02-06 09:00:48 +0100409 [SND_DEVICE_IN_VOICE_MIC] = "voice-mic",
410 [SND_DEVICE_IN_VOICE_EARPIECE_MIC] = "voice-earpiece-mic",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100411 [SND_DEVICE_IN_VOICE_EARPIECE_MIC_WB] = "voice-earpiece-mic-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100412 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100413 [SND_DEVICE_IN_VOICE_SPEAKER_MIC_WB] = "voice-speaker-mic-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100414 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
Andreas Schneider59486fa2017-02-06 09:16:39 +0100415 [SND_DEVICE_IN_VOICE_HEADSET_MIC_WB] = "voice-headset-mic-wb",
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100416 [SND_DEVICE_IN_VOICE_BT_SCO_MIC] = "voice-bt-sco-mic",
417 [SND_DEVICE_IN_VOICE_BT_SCO_MIC_WB] = "voice-bt-sco-mic-wb",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100418 [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
419 [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
420 [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100421 [SND_DEVICE_IN_VOICE_REC_HEADSET_MIC] = "voice-rec-headset-mic",
422 [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100423};
424
425static struct mixer_card *adev_get_mixer_for_card(struct audio_device *adev, int card)
426{
427 struct mixer_card *mixer_card;
428 struct listnode *node;
429
430 list_for_each(node, &adev->mixer_list) {
431 mixer_card = node_to_item(node, struct mixer_card, adev_list_node);
432 if (mixer_card->card == card)
433 return mixer_card;
434 }
435 return NULL;
436}
437
438static struct mixer_card *uc_get_mixer_for_card(struct audio_usecase *usecase, int card)
439{
440 struct mixer_card *mixer_card;
441 struct listnode *node;
442
443 list_for_each(node, &usecase->mixer_list) {
444 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[usecase->id]);
445 if (mixer_card->card == card)
446 return mixer_card;
447 }
448 return NULL;
449}
450
451static void free_mixer_list(struct audio_device *adev)
452{
453 struct mixer_card *mixer_card;
454 struct listnode *node;
455 struct listnode *next;
456
457 list_for_each_safe(node, next, &adev->mixer_list) {
458 mixer_card = node_to_item(node, struct mixer_card, adev_list_node);
459 list_remove(node);
460 audio_route_free(mixer_card->audio_route);
461 free(mixer_card);
462 }
463}
464
465static int mixer_init(struct audio_device *adev)
466{
467 int i;
468 int card;
469 int retry_num;
470 struct mixer *mixer;
471 struct audio_route *audio_route;
472 char mixer_path[PATH_MAX];
473 struct mixer_card *mixer_card;
Andreas Schneider56204f62017-01-31 08:17:32 +0100474 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100475
476 list_init(&adev->mixer_list);
477
478 for (i = 0; pcm_devices[i] != NULL; i++) {
479 card = pcm_devices[i]->card;
480 if (adev_get_mixer_for_card(adev, card) == NULL) {
481 retry_num = 0;
482 do {
483 mixer = mixer_open(card);
484 if (mixer == NULL) {
485 if (++retry_num > RETRY_NUMBER) {
486 ALOGE("%s unable to open the mixer for--card %d, aborting.",
487 __func__, card);
Andreas Schneider56204f62017-01-31 08:17:32 +0100488 ret = -ENODEV;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100489 goto error;
490 }
491 usleep(RETRY_US);
492 }
493 } while (mixer == NULL);
494
Christopher N. Hessed8d04fd2018-01-28 00:07:47 +0100495 sprintf(mixer_path, "/vendor/etc/mixer_paths_%d.xml", card);
Christopher N. Hesse2beff422018-01-28 13:16:17 +0100496 if (access(mixer_path, F_OK) == -1) {
Christopher N. Hessed8d04fd2018-01-28 00:07:47 +0100497 ALOGW("%s: Failed to open mixer paths from %s, retrying with legacy location",
Christopher N. Hesse2beff422018-01-28 13:16:17 +0100498 __func__, mixer_path);
Christopher N. Hessed8d04fd2018-01-28 00:07:47 +0100499 sprintf(mixer_path, "/system/etc/mixer_paths_%d.xml", card);
500 if (access(mixer_path, F_OK) == -1) {
501 ALOGE("%s: Failed to load a mixer paths configuration, your system will crash",
502 __func__);
503 }
Christopher N. Hesse2beff422018-01-28 13:16:17 +0100504 }
505
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100506 audio_route = audio_route_init(card, mixer_path);
507 if (!audio_route) {
508 ALOGE("%s: Failed to init audio route controls for card %d, aborting.",
509 __func__, card);
Andreas Schneider56204f62017-01-31 08:17:32 +0100510 ret = -ENODEV;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100511 goto error;
512 }
513 mixer_card = calloc(1, sizeof(struct mixer_card));
Andreas Schneider56204f62017-01-31 08:17:32 +0100514 if (mixer_card == NULL) {
515 ret = -ENOMEM;
516 goto error;
517 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100518 mixer_card->card = card;
519 mixer_card->mixer = mixer;
520 mixer_card->audio_route = audio_route;
Andreas Schneider759368f2017-02-02 16:11:14 +0100521
522 /* Do not sleep on first enable_snd_device() */
523 mixer_card->dsp_poweroff_time.tv_sec = 1;
524 mixer_card->dsp_poweroff_time.tv_nsec = 0;
525
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100526 list_add_tail(&adev->mixer_list, &mixer_card->adev_list_node);
527 }
528 }
529
530 return 0;
531
532error:
533 free_mixer_list(adev);
Andreas Schneider56204f62017-01-31 08:17:32 +0100534 return ret;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100535}
536
537static const char *get_snd_device_name(snd_device_t snd_device)
538{
539 const char *name = NULL;
540
Andreas Schneideradb788d2017-02-13 15:19:36 +0100541 if (snd_device == SND_DEVICE_NONE ||
Andreas Schneiderdde54c02017-02-15 14:10:58 +0100542 (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX))
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100543 name = device_table[snd_device];
544
545 ALOGE_IF(name == NULL, "%s: invalid snd device %d", __func__, snd_device);
546
547 return name;
548}
549
550static const char *get_snd_device_display_name(snd_device_t snd_device)
551{
552 const char *name = get_snd_device_name(snd_device);
553
554 if (name == NULL)
555 name = "SND DEVICE NOT FOUND";
556
557 return name;
558}
559
560static struct pcm_device_profile *get_pcm_device(usecase_type_t uc_type, audio_devices_t devices)
561{
562 int i;
563
564 devices &= ~AUDIO_DEVICE_BIT_IN;
565 for (i = 0; pcm_devices[i] != NULL; i++) {
566 if ((pcm_devices[i]->type == uc_type) &&
567 (devices & pcm_devices[i]->devices))
568 break;
569 }
570 return pcm_devices[i];
571}
572
573static struct audio_usecase *get_usecase_from_id(struct audio_device *adev,
574 audio_usecase_t uc_id)
575{
576 struct audio_usecase *usecase;
577 struct listnode *node;
578
579 list_for_each(node, &adev->usecase_list) {
580 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
581 if (usecase->id == uc_id)
582 return usecase;
583 }
584 return NULL;
585}
586
587static struct audio_usecase *get_usecase_from_type(struct audio_device *adev,
588 usecase_type_t type)
589{
590 struct audio_usecase *usecase;
591 struct listnode *node;
592
593 list_for_each(node, &adev->usecase_list) {
594 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
595 if (usecase->type & type)
596 return usecase;
597 }
598 return NULL;
599}
600
601/* always called with adev lock held */
602static int set_voice_volume_l(struct audio_device *adev, float volume)
603{
604 int err = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100605
606 if (adev->mode == AUDIO_MODE_IN_CALL) {
Christopher N. Hesse696959d2017-02-02 20:49:55 +0100607 set_voice_session_volume(adev->voice.session, volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100608 }
Christopher N. Hesse696959d2017-02-02 20:49:55 +0100609
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100610 return err;
611}
612
613
614static snd_device_t get_output_snd_device(struct audio_device *adev, audio_devices_t devices)
615{
616
617 audio_mode_t mode = adev->mode;
618 snd_device_t snd_device = SND_DEVICE_NONE;
619
620 ALOGV("%s: enter: output devices(%#x), mode(%d)", __func__, devices, mode);
621 if (devices == AUDIO_DEVICE_NONE ||
622 devices & AUDIO_DEVICE_BIT_IN) {
623 ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
624 goto exit;
625 }
626
627 if (mode == AUDIO_MODE_IN_CALL) {
628 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
629 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Andreas Schneidera2b77322017-01-30 22:33:56 +0100630 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
Fevax51bd12c2017-03-15 10:56:39 -0300631 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100632 snd_device = SND_DEVICE_OUT_VOICE_BT_SCO;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100633 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
634 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
635 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Andreas Schneider59486fa2017-02-06 09:16:39 +0100636 snd_device = SND_DEVICE_OUT_VOICE_EARPIECE;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100637 }
Andreas Schneider59486fa2017-02-06 09:16:39 +0100638
639 if (voice_session_uses_wideband(adev->voice.session)) {
640 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
641 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
642 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES_WB;
Fevax51bd12c2017-03-15 10:56:39 -0300643 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100644 snd_device = SND_DEVICE_OUT_VOICE_BT_SCO_WB;
Andreas Schneider59486fa2017-02-06 09:16:39 +0100645 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
646 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_WB;
647 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
648 snd_device = SND_DEVICE_OUT_VOICE_EARPIECE_WB;
649 }
650 }
651
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100652 if (snd_device != SND_DEVICE_NONE) {
653 goto exit;
654 }
655 }
656
657 if (popcount(devices) == 2) {
658 if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
659 AUDIO_DEVICE_OUT_SPEAKER)) {
660 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
661 } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
662 AUDIO_DEVICE_OUT_SPEAKER)) {
663 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
664 } else {
665 ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
666 goto exit;
667 }
668 if (snd_device != SND_DEVICE_NONE) {
669 goto exit;
670 }
671 }
672
673 if (popcount(devices) != 1) {
674 ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
675 goto exit;
676 }
677
678 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
679 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
680 snd_device = SND_DEVICE_OUT_HEADPHONES;
681 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
682 snd_device = SND_DEVICE_OUT_SPEAKER;
683 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
684 snd_device = SND_DEVICE_OUT_BT_SCO;
685 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100686 snd_device = SND_DEVICE_OUT_EARPIECE;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100687 } else {
688 ALOGE("%s: Unknown device(s) %#x", __func__, devices);
689 }
690exit:
691 ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
692 return snd_device;
693}
694
695static snd_device_t get_input_snd_device(struct audio_device *adev, audio_devices_t out_device)
696{
697 audio_source_t source;
698 audio_mode_t mode = adev->mode;
699 audio_devices_t in_device;
700 audio_channel_mask_t channel_mask;
701 snd_device_t snd_device = SND_DEVICE_NONE;
702 struct stream_in *active_input = NULL;
703 struct audio_usecase *usecase;
704
705 usecase = get_usecase_from_type(adev, PCM_CAPTURE|VOICE_CALL);
706 if (usecase != NULL) {
707 active_input = (struct stream_in *)usecase->stream;
708 }
709 source = (active_input == NULL) ?
710 AUDIO_SOURCE_DEFAULT : active_input->source;
711
Andreas Schneider757e2d82017-02-10 19:28:35 +0100712 in_device = (active_input == NULL) ?
713 AUDIO_DEVICE_NONE :
714 (active_input->devices & ~AUDIO_DEVICE_BIT_IN);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100715 channel_mask = (active_input == NULL) ?
716 AUDIO_CHANNEL_IN_MONO : active_input->main_channels;
717
718 ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
719 __func__, out_device, in_device);
720 if (mode == AUDIO_MODE_IN_CALL) {
721 if (out_device == AUDIO_DEVICE_NONE) {
722 ALOGE("%s: No output device set for voice call", __func__);
723 goto exit;
724 }
Andreas Schneidera2b77322017-01-30 22:33:56 +0100725
Andreas Schneider82f32482017-02-06 09:00:48 +0100726 snd_device = SND_DEVICE_IN_VOICE_MIC;
727 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100728 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
Andreas Schneider82f32482017-02-06 09:00:48 +0100729 }
730
731 if (voice_session_uses_twomic(adev->voice.session)) {
732 if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
733 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
734 snd_device = SND_DEVICE_IN_VOICE_EARPIECE_MIC;
735 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
736 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
737 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100738 }
Andreas Schneider59486fa2017-02-06 09:16:39 +0100739
740 if (voice_session_uses_wideband(adev->voice.session)) {
741 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
742 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC_WB;
743 }
744
745 if (voice_session_uses_twomic(adev->voice.session)) {
746 if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
747 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
748 snd_device = SND_DEVICE_IN_VOICE_EARPIECE_MIC_WB;
749 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
750 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC_WB;
751 }
752 }
753 }
Andreas Schneider05bc1882017-02-09 14:03:11 +0100754
755 /* BT SCO */
756 if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
757 snd_device = SND_DEVICE_IN_VOICE_MIC;
758
759 if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
Fevax51bd12c2017-03-15 10:56:39 -0300760 if (voice_session_uses_wideband(adev->voice.session)) {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100761 snd_device = SND_DEVICE_IN_VOICE_BT_SCO_MIC_WB;
Fevax51bd12c2017-03-15 10:56:39 -0300762 } else {
Christopher N. Hesse56caa262017-03-20 19:40:53 +0100763 snd_device = SND_DEVICE_IN_VOICE_BT_SCO_MIC;
Fevax51bd12c2017-03-15 10:56:39 -0300764 }
Andreas Schneider05bc1882017-02-09 14:03:11 +0100765 } else if (voice_session_uses_twomic(adev->voice.session)) {
766 snd_device = SND_DEVICE_IN_VOICE_EARPIECE_MIC;
767 }
768 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100769 } else if (source == AUDIO_SOURCE_CAMCORDER) {
770 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
771 in_device & AUDIO_DEVICE_IN_BACK_MIC) {
772 snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
773 }
774 } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
775 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100776 if (snd_device == SND_DEVICE_NONE) {
777 snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
778 }
779 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
780 snd_device = SND_DEVICE_IN_VOICE_REC_HEADSET_MIC;
781 }
782 } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION || source == AUDIO_SOURCE_MIC) {
783 if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
784 in_device = AUDIO_DEVICE_IN_BACK_MIC;
785 if (active_input) {
786 if (active_input->enable_aec) {
787 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
788 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
789 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
790 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
791 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
792 } else {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100793 snd_device = SND_DEVICE_IN_EARPIECE_MIC_AEC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100794 }
795 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
796 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
797 }
798 }
799 /* TODO: set echo reference */
800 }
801 } else if (source == AUDIO_SOURCE_DEFAULT) {
802 goto exit;
803 }
804
805
806 if (snd_device != SND_DEVICE_NONE) {
807 goto exit;
808 }
809
810 if (in_device != AUDIO_DEVICE_NONE &&
811 !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
812 !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
813 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100814 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100815 } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
816 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
817 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
818 snd_device = SND_DEVICE_IN_HEADSET_MIC;
819 } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
820 snd_device = SND_DEVICE_IN_BT_SCO_MIC ;
821 } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
822 snd_device = SND_DEVICE_IN_HDMI_MIC;
823 } else {
824 ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100825 ALOGW("%s: Using default earpiece-mic", __func__);
826 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100827 }
828 } else {
829 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100830 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100831 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
832 snd_device = SND_DEVICE_IN_HEADSET_MIC;
833 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
834 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
835 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100836 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100837 } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
838 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
839 } else {
840 ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
Christopher N. Hesse530cf0d2017-01-31 21:59:54 +0100841 ALOGW("%s: Using default earpiece-mic", __func__);
842 snd_device = SND_DEVICE_IN_EARPIECE_MIC;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100843 }
844 }
845exit:
846 ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
847 return snd_device;
848}
849
Andreas Schneider5a2f1002017-02-09 10:59:04 +0100850#if 0
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100851static int set_hdmi_channels(struct audio_device *adev, int channel_count)
852{
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100853 (void)adev;
854 (void)channel_count;
855 /* TODO */
856
857 return 0;
858}
859
860static int edid_get_max_channels(struct audio_device *adev)
861{
862 int max_channels = 2;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100863 (void)adev;
864
865 /* TODO */
866 return max_channels;
867}
Andreas Schneider5a2f1002017-02-09 10:59:04 +0100868#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100869
870/* Delay in Us */
871static int64_t render_latency(audio_usecase_t usecase)
872{
873 (void)usecase;
874 /* TODO */
875 return 0;
876}
877
878static int enable_snd_device(struct audio_device *adev,
879 struct audio_usecase *uc_info,
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100880 snd_device_t snd_device)
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100881{
882 struct mixer_card *mixer_card;
883 struct listnode *node;
884 const char *snd_device_name = get_snd_device_name(snd_device);
Andreas Schneider759368f2017-02-02 16:11:14 +0100885#ifdef DSP_POWEROFF_DELAY
886 struct timespec activation_time;
887 struct timespec elapsed_time;
888#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100889
890 if (snd_device_name == NULL)
891 return -EINVAL;
892
893 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES) {
894 ALOGV("Request to enable combo device: enable individual devices\n");
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100895 enable_snd_device(adev, uc_info, SND_DEVICE_OUT_SPEAKER);
896 enable_snd_device(adev, uc_info, SND_DEVICE_OUT_HEADPHONES);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100897 return 0;
898 }
899 adev->snd_dev_ref_cnt[snd_device]++;
900 if (adev->snd_dev_ref_cnt[snd_device] > 1) {
901 ALOGV("%s: snd_device(%d: %s) is already active",
902 __func__, snd_device, snd_device_name);
903 return 0;
904 }
905
906 ALOGV("%s: snd_device(%d: %s)", __func__,
907 snd_device, snd_device_name);
908
909 list_for_each(node, &uc_info->mixer_list) {
910 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]);
Andreas Schneider759368f2017-02-02 16:11:14 +0100911
912#ifdef DSP_POWEROFF_DELAY
913 clock_gettime(CLOCK_MONOTONIC, &activation_time);
914
Andreas Schneider58735a92017-02-13 16:48:17 +0100915 elapsed_time = time_spec_diff(activation_time,
916 mixer_card->dsp_poweroff_time);
Andreas Schneider759368f2017-02-02 16:11:14 +0100917 if (elapsed_time.tv_sec == 0) {
918 long elapsed_usec = elapsed_time.tv_nsec / 1000;
919
920 if (elapsed_usec < DSP_POWEROFF_DELAY) {
921 usleep(DSP_POWEROFF_DELAY - elapsed_usec);
922 }
923 }
Andreas Schneider759368f2017-02-02 16:11:14 +0100924#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +0200925
926 amplifier_enable_devices(snd_device, true);
927
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100928 audio_route_apply_and_update_path(mixer_card->audio_route, snd_device_name);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100929 }
930
931 return 0;
932}
933
Christopher N. Hesse757ac412017-01-28 14:42:48 +0100934int disable_snd_device(struct audio_device *adev,
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100935 struct audio_usecase *uc_info,
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100936 snd_device_t snd_device)
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100937{
938 struct mixer_card *mixer_card;
939 struct listnode *node;
Christopher N. Hesse11ef2112018-02-02 23:19:42 +0100940 struct audio_usecase *out_uc_info = get_usecase_from_type(adev, PCM_PLAYBACK);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100941 const char *snd_device_name = get_snd_device_name(snd_device);
Christopher N. Hesse11ef2112018-02-02 23:19:42 +0100942 const char *out_snd_device_name = NULL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100943
944 if (snd_device_name == NULL)
945 return -EINVAL;
946
947 if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES) {
948 ALOGV("Request to disable combo device: disable individual devices\n");
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100949 disable_snd_device(adev, uc_info, SND_DEVICE_OUT_SPEAKER);
950 disable_snd_device(adev, uc_info, SND_DEVICE_OUT_HEADPHONES);
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100951 return 0;
952 }
953
954 if (adev->snd_dev_ref_cnt[snd_device] <= 0) {
955 ALOGE("%s: device ref cnt is already 0", __func__);
956 return -EINVAL;
957 }
958 adev->snd_dev_ref_cnt[snd_device]--;
959 if (adev->snd_dev_ref_cnt[snd_device] == 0) {
960 ALOGV("%s: snd_device(%d: %s)", __func__,
961 snd_device, snd_device_name);
962 list_for_each(node, &uc_info->mixer_list) {
963 mixer_card = node_to_item(node, struct mixer_card, uc_list_node[uc_info->id]);
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100964 audio_route_reset_and_update_path(mixer_card->audio_route, snd_device_name);
Christopher N. Hesse719630a2018-02-12 01:47:48 +0100965 if (snd_device > SND_DEVICE_IN_BEGIN && out_uc_info != NULL) {
Christopher N. Hesse11ef2112018-02-02 23:19:42 +0100966 /*
967 * Cycle the rx device to eliminate routing conflicts.
968 * This prevents issues when an input route shares mixer controls with an output
969 * route.
970 */
971 out_snd_device_name = get_snd_device_name(out_uc_info->out_snd_device);
Christopher N. Hesse8179c012018-03-09 23:20:55 +0100972 audio_route_apply_and_update_path(mixer_card->audio_route, out_snd_device_name);
Andreas Schneider759368f2017-02-02 16:11:14 +0100973 }
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +0200974
975 amplifier_enable_devices(snd_device, false);
Andreas Schneider759368f2017-02-02 16:11:14 +0100976#ifdef DSP_POWEROFF_DELAY
977 clock_gettime(CLOCK_MONOTONIC, &(mixer_card->dsp_poweroff_time));
978#endif /* DSP_POWEROFF_DELAY */
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100979 }
980 }
981 return 0;
982}
983
984static int select_devices(struct audio_device *adev,
985 audio_usecase_t uc_id)
986{
987 snd_device_t out_snd_device = SND_DEVICE_NONE;
988 snd_device_t in_snd_device = SND_DEVICE_NONE;
989 struct audio_usecase *usecase = NULL;
990 struct audio_usecase *vc_usecase = NULL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100991 struct stream_in *active_input = NULL;
992 struct stream_out *active_out;
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100993
994 ALOGV("%s: usecase(%d)", __func__, uc_id);
995
Christopher N. Hesse297a6362017-01-28 12:40:45 +0100996 usecase = get_usecase_from_type(adev, PCM_CAPTURE|VOICE_CALL);
997 if (usecase != NULL) {
998 active_input = (struct stream_in *)usecase->stream;
999 }
1000
1001 usecase = get_usecase_from_id(adev, uc_id);
1002 if (usecase == NULL) {
1003 ALOGE("%s: Could not find the usecase(%d)", __func__, uc_id);
1004 return -EINVAL;
1005 }
1006 active_out = (struct stream_out *)usecase->stream;
1007
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001008
1009 /*
1010 * If the voice call is active, use the sound devices of voice call usecase
1011 * so that it would not result any device switch. All the usecases will
1012 * be switched to new device when select_devices() is called for voice call
1013 * usecase.
1014 */
1015 if (usecase->type != VOICE_CALL && adev->voice.in_call) {
1016 vc_usecase = get_usecase_from_id(adev, USECASE_VOICE_CALL);
1017 if (vc_usecase == NULL) {
1018 ALOGE("%s: Could not find the voice call usecase", __func__);
1019 } else {
Christopher N. Hesse77880a22017-11-17 20:27:50 +01001020 ALOGV("%s: in call, reusing devices (rx: %s, tx: %s)", __func__,
1021 get_snd_device_display_name(vc_usecase->out_snd_device),
1022 get_snd_device_display_name(vc_usecase->in_snd_device));
1023 usecase->devices = vc_usecase->devices;
1024 return 0;
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001025 }
1026 }
1027
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001028 if (usecase->type == VOICE_CALL) {
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001029 usecase->devices = active_out->devices;
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001030 prepare_voice_session(adev->voice.session, active_out->devices);
1031 out_snd_device = get_output_snd_device(adev, active_out->devices);
1032 in_snd_device = get_input_snd_device(adev, active_out->devices);
1033 } else if (usecase->type == PCM_PLAYBACK) {
1034 usecase->devices = active_out->devices;
1035 in_snd_device = SND_DEVICE_NONE;
1036 if (out_snd_device == SND_DEVICE_NONE) {
1037 out_snd_device = get_output_snd_device(adev, active_out->devices);
1038 if (active_out == adev->primary_output &&
1039 active_input &&
1040 active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
1041 select_devices(adev, active_input->usecase);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001042 }
1043 }
Christopher N. Hesse130da9f2017-02-15 12:18:41 +01001044 } else if (usecase->type == PCM_CAPTURE) {
1045 usecase->devices = ((struct stream_in *)usecase->stream)->devices;
1046 out_snd_device = SND_DEVICE_NONE;
1047 if (in_snd_device == SND_DEVICE_NONE) {
1048 if (active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
1049 adev->primary_output && !adev->primary_output->standby) {
1050 in_snd_device = get_input_snd_device(adev, adev->primary_output->devices);
1051 } else {
1052 in_snd_device = get_input_snd_device(adev, AUDIO_DEVICE_NONE);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001053 }
1054 }
1055 }
1056
1057 if (out_snd_device == usecase->out_snd_device &&
1058 in_snd_device == usecase->in_snd_device) {
1059 return 0;
1060 }
1061
1062 ALOGV("%s: out_snd_device(%d: %s) in_snd_device(%d: %s)", __func__,
1063 out_snd_device, get_snd_device_display_name(out_snd_device),
1064 in_snd_device, get_snd_device_display_name(in_snd_device));
1065
1066
1067 /* Disable current sound devices */
1068 if (usecase->out_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001069 disable_snd_device(adev, usecase, usecase->out_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001070 }
1071
1072 if (usecase->in_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001073 disable_snd_device(adev, usecase, usecase->in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001074 }
1075
1076 /* Enable new sound devices */
1077 if (out_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse696959d2017-02-02 20:49:55 +01001078 /* We need to update the audio path if we switch the out devices */
1079 if (adev->voice.in_call) {
1080 set_voice_session_audio_path(adev->voice.session);
1081 }
1082
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001083 enable_snd_device(adev, usecase, out_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001084 }
1085
1086 if (in_snd_device != SND_DEVICE_NONE) {
Christopher N. Hesse8179c012018-03-09 23:20:55 +01001087 enable_snd_device(adev, usecase, in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001088 }
1089
1090 usecase->in_snd_device = in_snd_device;
1091 usecase->out_snd_device = out_snd_device;
1092
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02001093 /* Rely on amplifier_set_devices to distinguish between in/out devices */
1094 amplifier_set_input_devices(in_snd_device);
1095 amplifier_set_output_devices(out_snd_device);
1096
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001097 return 0;
1098}
1099
1100
1101static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames);
1102static int do_in_standby_l(struct stream_in *in);
1103
1104#ifdef PREPROCESSING_ENABLED
1105static void get_capture_reference_delay(struct stream_in *in,
1106 size_t frames __unused,
1107 struct echo_reference_buffer *buffer)
1108{
1109 ALOGVV("%s: enter:)", __func__);
1110
1111 /* read frames available in kernel driver buffer */
1112 unsigned int kernel_frames;
1113 struct timespec tstamp;
1114 long buf_delay;
1115 long kernel_delay;
1116 long delay_ns;
1117 struct pcm_device *ref_device;
1118 long rsmp_delay = 0;
1119
1120 ref_device = node_to_item(list_tail(&in->pcm_dev_list),
1121 struct pcm_device, stream_list_node);
1122
1123 if (pcm_get_htimestamp(ref_device->pcm, &kernel_frames, &tstamp) < 0) {
1124 buffer->time_stamp.tv_sec = 0;
1125 buffer->time_stamp.tv_nsec = 0;
1126 buffer->delay_ns = 0;
1127 ALOGW("read get_capture_reference_delay(): pcm_htimestamp error");
1128 return;
1129 }
1130
1131 /* adjust render time stamp with delay added by current driver buffer.
1132 * Add the duration of current frame as we want the render time of the last
1133 * sample being written. */
1134
1135 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / ref_device->pcm_profile->config.rate);
1136
1137 buffer->time_stamp = tstamp;
1138 buffer->delay_ns = kernel_delay;
1139
1140 ALOGVV("get_capture_reference_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5d],"
1141 " delay_ns: [%d] , frames:[%zd]",
1142 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns, frames);
1143}
1144
1145static void get_capture_delay(struct stream_in *in,
1146 size_t frames __unused,
1147 struct echo_reference_buffer *buffer)
1148{
1149 ALOGVV("%s: enter:)", __func__);
1150 /* read frames available in kernel driver buffer */
1151 unsigned int kernel_frames;
1152 struct timespec tstamp;
1153 long buf_delay;
1154 long rsmp_delay;
1155 long kernel_delay;
1156 long delay_ns;
1157 struct pcm_device *pcm_device;
1158
1159 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1160 struct pcm_device, stream_list_node);
1161
1162 if (pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &tstamp) < 0) {
1163 buffer->time_stamp.tv_sec = 0;
1164 buffer->time_stamp.tv_nsec = 0;
1165 buffer->delay_ns = 0;
1166 ALOGW("read get_capture_delay(): pcm_htimestamp error");
1167 return;
1168 }
1169
1170 /* read frames available in audio HAL input buffer
1171 * add number of frames being read as we want the capture time of first sample
1172 * in current buffer */
1173 /* frames in in->read_buf are at driver sampling rate while frames in in->proc_buf are
1174 * at requested sampling rate */
1175 buf_delay = (long)(((int64_t)(in->read_buf_frames) * 1000000000) / in->config.rate +
1176 ((int64_t)(in->proc_buf_frames) * 1000000000) / in->requested_rate );
1177
1178 /* add delay introduced by resampler */
1179 rsmp_delay = 0;
1180 if (in->resampler) {
1181 rsmp_delay = in->resampler->delay_ns(in->resampler);
1182 }
1183
1184 kernel_delay = (long)(((int64_t)kernel_frames * 1000000000) / in->config.rate);
1185
1186 delay_ns = kernel_delay + buf_delay + rsmp_delay;
1187
1188 buffer->time_stamp = tstamp;
1189 buffer->delay_ns = delay_ns;
1190 ALOGVV("get_capture_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames:[%5d],"
1191 " delay_ns: [%d], kernel_delay:[%ld], buf_delay:[%ld], rsmp_delay:[%ld], "
1192 "in->read_buf_frames:[%zd], in->proc_buf_frames:[%zd], frames:[%zd]",
1193 buffer->time_stamp.tv_sec , buffer->time_stamp.tv_nsec, kernel_frames,
1194 buffer->delay_ns, kernel_delay, buf_delay, rsmp_delay,
1195 in->read_buf_frames, in->proc_buf_frames, frames);
1196}
1197
1198static int32_t update_echo_reference(struct stream_in *in, size_t frames)
1199{
1200 ALOGVV("%s: enter:), in->config.channels(%d)", __func__,in->config.channels);
1201 struct echo_reference_buffer b;
1202 b.delay_ns = 0;
1203 struct pcm_device *pcm_device;
1204
1205 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1206 struct pcm_device, stream_list_node);
1207
1208 ALOGVV("update_echo_reference, in->config.channels(%d), frames = [%zd], in->ref_buf_frames = [%zd], "
1209 "b.frame_count = [%zd]",
1210 in->config.channels, frames, in->ref_buf_frames, frames - in->ref_buf_frames);
1211 if (in->ref_buf_frames < frames) {
1212 if (in->ref_buf_size < frames) {
1213 in->ref_buf_size = frames;
1214 in->ref_buf = (int16_t *)realloc(in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1215 ALOG_ASSERT((in->ref_buf != NULL),
1216 "update_echo_reference() failed to reallocate ref_buf");
1217 ALOGVV("update_echo_reference(): ref_buf %p extended to %d bytes",
1218 in->ref_buf, pcm_frames_to_bytes(pcm_device->pcm, frames));
1219 }
1220 b.frame_count = frames - in->ref_buf_frames;
1221 b.raw = (void *)(in->ref_buf + in->ref_buf_frames * in->config.channels);
1222
1223 get_capture_delay(in, frames, &b);
1224
1225 if (in->echo_reference->read(in->echo_reference, &b) == 0)
1226 {
1227 in->ref_buf_frames += b.frame_count;
1228 ALOGVV("update_echo_reference(): in->ref_buf_frames:[%zd], "
1229 "in->ref_buf_size:[%zd], frames:[%zd], b.frame_count:[%zd]",
1230 in->ref_buf_frames, in->ref_buf_size, frames, b.frame_count);
1231 }
1232 } else
1233 ALOGW("update_echo_reference(): NOT enough frames to read ref buffer");
1234 return b.delay_ns;
1235}
1236
1237static int set_preprocessor_param(effect_handle_t handle,
1238 effect_param_t *param)
1239{
1240 uint32_t size = sizeof(int);
1241 uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
1242 param->vsize;
1243
1244 int status = (*handle)->command(handle,
1245 EFFECT_CMD_SET_PARAM,
1246 sizeof (effect_param_t) + psize,
1247 param,
1248 &size,
1249 &param->status);
1250 if (status == 0)
1251 status = param->status;
1252
1253 return status;
1254}
1255
1256static int set_preprocessor_echo_delay(effect_handle_t handle,
1257 int32_t delay_us)
1258{
1259 struct {
1260 effect_param_t param;
1261 uint32_t data_0;
1262 int32_t data_1;
1263 } buf;
1264 memset(&buf, 0, sizeof(buf));
1265
1266 buf.param.psize = sizeof(uint32_t);
1267 buf.param.vsize = sizeof(uint32_t);
1268 buf.data_0 = AEC_PARAM_ECHO_DELAY;
1269 buf.data_1 = delay_us;
1270
1271 return set_preprocessor_param(handle, &buf.param);
1272}
1273
1274static void push_echo_reference(struct stream_in *in, size_t frames)
1275{
1276 ALOGVV("%s: enter:)", __func__);
1277 /* read frames from echo reference buffer and update echo delay
1278 * in->ref_buf_frames is updated with frames available in in->ref_buf */
1279
1280 int32_t delay_us = update_echo_reference(in, frames)/1000;
1281 int32_t size_in_bytes = 0;
1282 int i;
1283 audio_buffer_t buf;
1284
1285 if (in->ref_buf_frames < frames)
1286 frames = in->ref_buf_frames;
1287
1288 buf.frameCount = frames;
1289 buf.raw = in->ref_buf;
1290
1291 for (i = 0; i < in->num_preprocessors; i++) {
1292 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1293 continue;
1294 ALOGVV("%s: effect_itfe)->process_reverse() BEGIN i=(%d) ", __func__, i);
1295 (*in->preprocessors[i].effect_itfe)->process_reverse(in->preprocessors[i].effect_itfe,
1296 &buf,
1297 NULL);
1298 ALOGVV("%s: effect_itfe)->process_reverse() END i=(%d) ", __func__, i);
1299 set_preprocessor_echo_delay(in->preprocessors[i].effect_itfe, delay_us);
1300 }
1301
1302 in->ref_buf_frames -= buf.frameCount;
1303 ALOGVV("%s: in->ref_buf_frames(%zd), in->config.channels(%d) ",
1304 __func__, in->ref_buf_frames, in->config.channels);
1305 if (in->ref_buf_frames) {
1306 memcpy(in->ref_buf,
1307 in->ref_buf + buf.frameCount * in->config.channels,
1308 in->ref_buf_frames * in->config.channels * sizeof(int16_t));
1309 }
1310}
1311
1312static void put_echo_reference(struct audio_device *adev,
1313 struct echo_reference_itfe *reference)
1314{
1315 ALOGV("%s: enter:)", __func__);
1316 int32_t prev_generation = adev->echo_reference_generation;
1317 struct stream_out *out = adev->primary_output;
1318
1319 if (adev->echo_reference != NULL &&
1320 reference == adev->echo_reference) {
1321 /* echo reference is taken from the low latency output stream used
1322 * for voice use cases */
1323 adev->echo_reference = NULL;
1324 android_atomic_inc(&adev->echo_reference_generation);
1325 if (out != NULL && out->usecase == USECASE_AUDIO_PLAYBACK) {
1326 // if the primary output is in standby or did not pick the echo reference yet
1327 // we can safely get rid of it here.
1328 // otherwise, out_write() or out_standby() will detect the change in echo reference
1329 // generation and release the echo reference owned by the stream.
1330 if ((out->echo_reference_generation != prev_generation) || out->standby)
1331 release_echo_reference(reference);
1332 } else {
1333 release_echo_reference(reference);
1334 }
1335 ALOGV("release_echo_reference");
1336 }
1337}
1338
1339static struct echo_reference_itfe *get_echo_reference(struct audio_device *adev,
1340 audio_format_t format __unused,
1341 uint32_t channel_count,
1342 uint32_t sampling_rate)
1343{
1344 ALOGV("%s: enter:)", __func__);
1345 put_echo_reference(adev, adev->echo_reference);
1346 /* echo reference is taken from the low latency output stream used
1347 * for voice use cases */
1348 if (adev->primary_output!= NULL && adev->primary_output->usecase == USECASE_AUDIO_PLAYBACK &&
1349 !adev->primary_output->standby) {
1350 struct audio_stream *stream =
1351 &adev->primary_output->stream.common;
1352 uint32_t wr_channel_count = audio_channel_count_from_out_mask(stream->get_channels(stream));
1353 uint32_t wr_sampling_rate = stream->get_sample_rate(stream);
1354 ALOGV("Calling create_echo_reference");
1355 int status = create_echo_reference(AUDIO_FORMAT_PCM_16_BIT,
1356 channel_count,
1357 sampling_rate,
1358 AUDIO_FORMAT_PCM_16_BIT,
1359 wr_channel_count,
1360 wr_sampling_rate,
1361 &adev->echo_reference);
1362 if (status == 0)
1363 android_atomic_inc(&adev->echo_reference_generation);
1364 }
1365 return adev->echo_reference;
1366}
1367
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001368static int get_playback_delay(struct stream_out *out,
1369 size_t frames,
1370 struct echo_reference_buffer *buffer)
1371{
1372 unsigned int kernel_frames;
1373 int status;
1374 int primary_pcm = 0;
1375 struct pcm_device *pcm_device;
1376
1377 pcm_device = node_to_item(list_head(&out->pcm_dev_list),
1378 struct pcm_device, stream_list_node);
1379
1380 status = pcm_get_htimestamp(pcm_device->pcm, &kernel_frames, &buffer->time_stamp);
1381 if (status < 0) {
1382 buffer->time_stamp.tv_sec = 0;
1383 buffer->time_stamp.tv_nsec = 0;
1384 buffer->delay_ns = 0;
1385 ALOGV("get_playback_delay(): pcm_get_htimestamp error,"
1386 "setting playbackTimestamp to 0");
1387 return status;
1388 }
1389
1390 kernel_frames = pcm_get_buffer_size(pcm_device->pcm) - kernel_frames;
1391
1392 /* adjust render time stamp with delay added by current driver buffer.
1393 * Add the duration of current frame as we want the render time of the last
1394 * sample being written. */
1395 buffer->delay_ns = (long)(((int64_t)(kernel_frames + frames)* 1000000000)/
1396 out->config.rate);
1397 ALOGVV("get_playback_delay_time_stamp Secs: [%10ld], nSecs: [%9ld], kernel_frames: [%5u], delay_ns: [%d],",
1398 buffer->time_stamp.tv_sec, buffer->time_stamp.tv_nsec, kernel_frames, buffer->delay_ns);
1399
1400 return 0;
1401}
1402
1403#define GET_COMMAND_STATUS(status, fct_status, cmd_status) \
1404 do { \
1405 if (fct_status != 0) \
1406 status = fct_status; \
1407 else if (cmd_status != 0) \
1408 status = cmd_status; \
1409 } while(0)
1410
1411static int in_configure_reverse(struct stream_in *in)
1412{
1413 int32_t cmd_status;
1414 uint32_t size = sizeof(int);
1415 effect_config_t config;
1416 int32_t status = 0;
1417 int32_t fct_status = 0;
1418 int i;
1419 ALOGV("%s: enter: in->num_preprocessors(%d)", __func__, in->num_preprocessors);
1420 if (in->num_preprocessors > 0) {
1421 config.inputCfg.channels = in->main_channels;
1422 config.outputCfg.channels = in->main_channels;
1423 config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1424 config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1425 config.inputCfg.samplingRate = in->requested_rate;
1426 config.outputCfg.samplingRate = in->requested_rate;
1427 config.inputCfg.mask =
1428 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1429 config.outputCfg.mask =
1430 ( EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT );
1431
1432 for (i = 0; i < in->num_preprocessors; i++)
1433 {
1434 if ((*in->preprocessors[i].effect_itfe)->process_reverse == NULL)
1435 continue;
1436 fct_status = (*(in->preprocessors[i].effect_itfe))->command(
1437 in->preprocessors[i].effect_itfe,
1438 EFFECT_CMD_SET_CONFIG_REVERSE,
1439 sizeof(effect_config_t),
1440 &config,
1441 &size,
1442 &cmd_status);
1443 ALOGV("%s: calling EFFECT_CMD_SET_CONFIG_REVERSE",__func__);
1444 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1445 }
1446 }
1447 return status;
1448}
1449
1450#define MAX_NUM_CHANNEL_CONFIGS 10
1451
1452static void in_read_audio_effect_channel_configs(struct stream_in *in __unused,
1453 struct effect_info_s *effect_info)
1454{
1455 /* size and format of the cmd are defined in hardware/audio_effect.h */
1456 effect_handle_t effect = effect_info->effect_itfe;
1457 uint32_t cmd_size = 2 * sizeof(uint32_t);
1458 uint32_t cmd[] = { EFFECT_FEATURE_AUX_CHANNELS, MAX_NUM_CHANNEL_CONFIGS };
1459 /* reply = status + number of configs (n) + n x channel_config_t */
1460 uint32_t reply_size =
1461 2 * sizeof(uint32_t) + (MAX_NUM_CHANNEL_CONFIGS * sizeof(channel_config_t));
1462 int32_t reply[reply_size];
1463 int32_t cmd_status;
1464
1465 ALOG_ASSERT((effect_info->num_channel_configs == 0),
1466 "in_read_audio_effect_channel_configs() num_channel_configs not cleared");
1467 ALOG_ASSERT((effect_info->channel_configs == NULL),
1468 "in_read_audio_effect_channel_configs() channel_configs not cleared");
1469
1470 /* if this command is not supported, then the effect is supposed to return -EINVAL.
1471 * This error will be interpreted as if the effect supports the main_channels but does not
1472 * support any aux_channels */
1473 cmd_status = (*effect)->command(effect,
1474 EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS,
1475 cmd_size,
1476 (void*)&cmd,
1477 &reply_size,
1478 (void*)&reply);
1479
1480 if (cmd_status != 0) {
1481 ALOGV("in_read_audio_effect_channel_configs(): "
1482 "fx->command returned %d", cmd_status);
1483 return;
1484 }
1485
1486 if (reply[0] != 0) {
1487 ALOGW("in_read_audio_effect_channel_configs(): "
1488 "command EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS error %d num configs %d",
1489 reply[0], (reply[0] == -ENOMEM) ? reply[1] : MAX_NUM_CHANNEL_CONFIGS);
1490 return;
1491 }
1492
1493 /* the feature is not supported */
1494 ALOGV("in_read_audio_effect_channel_configs()(): "
1495 "Feature supported and adding %d channel configs to the list", reply[1]);
1496 effect_info->num_channel_configs = reply[1];
1497 effect_info->channel_configs =
1498 (channel_config_t *) malloc(sizeof(channel_config_t) * reply[1]); /* n x configs */
1499 memcpy(effect_info->channel_configs, (reply + 2), sizeof(channel_config_t) * reply[1]);
1500}
1501
1502
1503#define NUM_IN_AUX_CNL_CONFIGS 2
1504static const channel_config_t in_aux_cnl_configs[NUM_IN_AUX_CNL_CONFIGS] = {
1505 { AUDIO_CHANNEL_IN_FRONT , AUDIO_CHANNEL_IN_BACK},
1506 { AUDIO_CHANNEL_IN_STEREO , AUDIO_CHANNEL_IN_RIGHT}
1507};
1508static uint32_t in_get_aux_channels(struct stream_in *in)
1509{
1510 int i;
1511 channel_config_t new_chcfg = {0, 0};
1512
1513 if (in->num_preprocessors == 0)
1514 return 0;
1515
1516 /* do not enable dual mic configurations when capturing from other microphones than
1517 * main or sub */
1518 if (!(in->devices & (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_BACK_MIC)))
1519 return 0;
1520
1521 /* retain most complex aux channels configuration compatible with requested main channels and
1522 * supported by audio driver and all pre processors */
1523 for (i = 0; i < NUM_IN_AUX_CNL_CONFIGS; i++) {
1524 const channel_config_t *cur_chcfg = &in_aux_cnl_configs[i];
1525 if (cur_chcfg->main_channels == in->main_channels) {
1526 size_t match_cnt;
1527 size_t idx_preproc;
1528 for (idx_preproc = 0, match_cnt = 0;
1529 /* no need to continue if at least one preprocessor doesn't match */
1530 idx_preproc < (size_t)in->num_preprocessors && match_cnt == idx_preproc;
1531 idx_preproc++) {
1532 struct effect_info_s *effect_info = &in->preprocessors[idx_preproc];
1533 size_t idx_chcfg;
1534
1535 for (idx_chcfg = 0; idx_chcfg < effect_info->num_channel_configs; idx_chcfg++) {
1536 if (memcmp(effect_info->channel_configs + idx_chcfg,
1537 cur_chcfg,
1538 sizeof(channel_config_t)) == 0) {
1539 match_cnt++;
1540 break;
1541 }
1542 }
1543 }
1544 /* if all preprocessors match, we have a candidate */
1545 if (match_cnt == (size_t)in->num_preprocessors) {
1546 /* retain most complex aux channels configuration */
1547 if (audio_channel_count_from_in_mask(cur_chcfg->aux_channels) > audio_channel_count_from_in_mask(new_chcfg.aux_channels)) {
1548 new_chcfg = *cur_chcfg;
1549 }
1550 }
1551 }
1552 }
1553
1554 ALOGV("in_get_aux_channels(): return %04x", new_chcfg.aux_channels);
1555
1556 return new_chcfg.aux_channels;
1557}
1558
1559static int in_configure_effect_channels(effect_handle_t effect,
1560 channel_config_t *channel_config)
1561{
1562 int status = 0;
1563 int fct_status;
1564 int32_t cmd_status;
1565 uint32_t reply_size;
1566 effect_config_t config;
1567 uint32_t cmd[(sizeof(uint32_t) + sizeof(channel_config_t) - 1) / sizeof(uint32_t) + 1];
1568
1569 ALOGV("in_configure_effect_channels(): configure effect with channels: [%04x][%04x]",
1570 channel_config->main_channels,
1571 channel_config->aux_channels);
1572
1573 config.inputCfg.mask = EFFECT_CONFIG_CHANNELS;
1574 config.outputCfg.mask = EFFECT_CONFIG_CHANNELS;
1575 reply_size = sizeof(effect_config_t);
1576 fct_status = (*effect)->command(effect,
1577 EFFECT_CMD_GET_CONFIG,
1578 0,
1579 NULL,
1580 &reply_size,
1581 &config);
1582 if (fct_status != 0) {
1583 ALOGE("in_configure_effect_channels(): EFFECT_CMD_GET_CONFIG failed");
1584 return fct_status;
1585 }
1586
1587 config.inputCfg.channels = channel_config->main_channels | channel_config->aux_channels;
1588 config.outputCfg.channels = config.inputCfg.channels;
1589 reply_size = sizeof(uint32_t);
1590 fct_status = (*effect)->command(effect,
1591 EFFECT_CMD_SET_CONFIG,
1592 sizeof(effect_config_t),
1593 &config,
1594 &reply_size,
1595 &cmd_status);
1596 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1597
1598 cmd[0] = EFFECT_FEATURE_AUX_CHANNELS;
1599 memcpy(cmd + 1, channel_config, sizeof(channel_config_t));
1600 reply_size = sizeof(uint32_t);
1601 fct_status = (*effect)->command(effect,
1602 EFFECT_CMD_SET_FEATURE_CONFIG,
1603 sizeof(cmd), //sizeof(uint32_t) + sizeof(channel_config_t),
1604 cmd,
1605 &reply_size,
1606 &cmd_status);
1607 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1608
1609 /* some implementations need to be re-enabled after a config change */
1610 reply_size = sizeof(uint32_t);
1611 fct_status = (*effect)->command(effect,
1612 EFFECT_CMD_ENABLE,
1613 0,
1614 NULL,
1615 &reply_size,
1616 &cmd_status);
1617 GET_COMMAND_STATUS(status, fct_status, cmd_status);
1618
1619 return status;
1620}
1621
1622static int in_reconfigure_channels(struct stream_in *in,
1623 effect_handle_t effect,
1624 channel_config_t *channel_config,
1625 bool config_changed) {
1626
1627 int status = 0;
1628
1629 ALOGV("in_reconfigure_channels(): config_changed %d effect %p",
1630 config_changed, effect);
1631
1632 /* if config changed, reconfigure all previously added effects */
1633 if (config_changed) {
1634 int i;
1635 ALOGV("%s: config_changed (%d)", __func__, config_changed);
1636 for (i = 0; i < in->num_preprocessors; i++)
1637 {
1638 int cur_status = in_configure_effect_channels(in->preprocessors[i].effect_itfe,
1639 channel_config);
1640 ALOGV("%s: in_configure_effect_channels i=(%d), [main_channel,aux_channel]=[%d|%d], status=%d",
1641 __func__, i, channel_config->main_channels, channel_config->aux_channels, cur_status);
1642 if (cur_status != 0) {
1643 ALOGV("in_reconfigure_channels(): error %d configuring effect "
1644 "%d with channels: [%04x][%04x]",
1645 cur_status,
1646 i,
1647 channel_config->main_channels,
1648 channel_config->aux_channels);
1649 status = cur_status;
1650 }
1651 }
1652 } else if (effect != NULL && channel_config->aux_channels) {
1653 /* if aux channels config did not change but aux channels are present,
1654 * we still need to configure the effect being added */
1655 status = in_configure_effect_channels(effect, channel_config);
1656 }
1657 return status;
1658}
1659
1660static void in_update_aux_channels(struct stream_in *in,
1661 effect_handle_t effect)
1662{
1663 uint32_t aux_channels;
1664 channel_config_t channel_config;
1665 int status;
1666
1667 aux_channels = in_get_aux_channels(in);
1668
1669 channel_config.main_channels = in->main_channels;
1670 channel_config.aux_channels = aux_channels;
1671 status = in_reconfigure_channels(in,
1672 effect,
1673 &channel_config,
1674 (aux_channels != in->aux_channels));
1675
1676 if (status != 0) {
1677 ALOGV("in_update_aux_channels(): in_reconfigure_channels error %d", status);
1678 /* resetting aux channels configuration */
1679 aux_channels = 0;
1680 channel_config.aux_channels = 0;
1681 in_reconfigure_channels(in, effect, &channel_config, true);
1682 }
1683 ALOGV("%s: aux_channels=%d, in->aux_channels_changed=%d", __func__, aux_channels, in->aux_channels_changed);
1684 if (in->aux_channels != aux_channels) {
1685 in->aux_channels_changed = true;
1686 in->aux_channels = aux_channels;
1687 do_in_standby_l(in);
1688 }
1689}
1690#endif
1691
1692/* This function reads PCM data and:
1693 * - resample if needed
1694 * - process if pre-processors are attached
1695 * - discard unwanted channels
1696 */
1697static ssize_t read_and_process_frames(struct stream_in *in, void* buffer, ssize_t frames)
1698{
1699 ssize_t frames_wr = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001700 size_t src_channels = in->config.channels;
1701 size_t dst_channels = audio_channel_count_from_in_mask(in->main_channels);
1702 int i;
1703 void *proc_buf_out;
1704 struct pcm_device *pcm_device;
1705 bool has_additional_channels = (dst_channels != src_channels) ? true : false;
1706#ifdef PREPROCESSING_ENABLED
Andreas Schneider5a2f1002017-02-09 10:59:04 +01001707 audio_buffer_t in_buf;
1708 audio_buffer_t out_buf;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001709 bool has_processing = (in->num_preprocessors != 0) ? true : false;
1710#endif
1711
1712 /* Additional channels might be added on top of main_channels:
1713 * - aux_channels (by processing effects)
1714 * - extra channels due to HW limitations
1715 * In case of additional channels, we cannot work inplace
1716 */
1717 if (has_additional_channels)
1718 proc_buf_out = in->proc_buf_out;
1719 else
1720 proc_buf_out = buffer;
1721
1722 if (list_empty(&in->pcm_dev_list)) {
1723 ALOGE("%s: pcm device list empty", __func__);
1724 return -EINVAL;
1725 }
1726
1727 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1728 struct pcm_device, stream_list_node);
1729
1730#ifdef PREPROCESSING_ENABLED
1731 if (has_processing) {
1732 /* since all the processing below is done in frames and using the config.channels
1733 * as the number of channels, no changes is required in case aux_channels are present */
1734 while (frames_wr < frames) {
1735 /* first reload enough frames at the end of process input buffer */
1736 if (in->proc_buf_frames < (size_t)frames) {
1737 ssize_t frames_rd;
1738 if (in->proc_buf_size < (size_t)frames) {
1739 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1740 in->proc_buf_size = (size_t)frames;
1741 in->proc_buf_in = (int16_t *)realloc(in->proc_buf_in, size_in_bytes);
1742 ALOG_ASSERT((in->proc_buf_in != NULL),
1743 "process_frames() failed to reallocate proc_buf_in");
1744 if (has_additional_channels) {
1745 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1746 ALOG_ASSERT((in->proc_buf_out != NULL),
1747 "process_frames() failed to reallocate proc_buf_out");
1748 proc_buf_out = in->proc_buf_out;
1749 }
1750 }
1751 frames_rd = read_frames(in,
1752 in->proc_buf_in +
1753 in->proc_buf_frames * in->config.channels,
1754 frames - in->proc_buf_frames);
1755 if (frames_rd < 0) {
1756 /* Return error code */
1757 frames_wr = frames_rd;
1758 break;
1759 }
1760 in->proc_buf_frames += frames_rd;
1761 }
1762
1763 if (in->echo_reference != NULL) {
1764 push_echo_reference(in, in->proc_buf_frames);
1765 }
1766
1767 /* in_buf.frameCount and out_buf.frameCount indicate respectively
1768 * the maximum number of frames to be consumed and produced by process() */
1769 in_buf.frameCount = in->proc_buf_frames;
1770 in_buf.s16 = in->proc_buf_in;
1771 out_buf.frameCount = frames - frames_wr;
1772 out_buf.s16 = (int16_t *)proc_buf_out + frames_wr * in->config.channels;
1773
1774 /* FIXME: this works because of current pre processing library implementation that
1775 * does the actual process only when the last enabled effect process is called.
1776 * The generic solution is to have an output buffer for each effect and pass it as
1777 * input to the next.
1778 */
1779 for (i = 0; i < in->num_preprocessors; i++) {
1780 (*in->preprocessors[i].effect_itfe)->process(in->preprocessors[i].effect_itfe,
1781 &in_buf,
1782 &out_buf);
1783 }
1784
1785 /* process() has updated the number of frames consumed and produced in
1786 * in_buf.frameCount and out_buf.frameCount respectively
1787 * move remaining frames to the beginning of in->proc_buf_in */
1788 in->proc_buf_frames -= in_buf.frameCount;
1789
1790 if (in->proc_buf_frames) {
1791 memcpy(in->proc_buf_in,
1792 in->proc_buf_in + in_buf.frameCount * in->config.channels,
1793 in->proc_buf_frames * in->config.channels * sizeof(int16_t));
1794 }
1795
1796 /* if not enough frames were passed to process(), read more and retry. */
1797 if (out_buf.frameCount == 0) {
1798 ALOGW("No frames produced by preproc");
1799 continue;
1800 }
1801
1802 if ((frames_wr + (ssize_t)out_buf.frameCount) <= frames) {
1803 frames_wr += out_buf.frameCount;
1804 } else {
1805 /* The effect does not comply to the API. In theory, we should never end up here! */
1806 ALOGE("preprocessing produced too many frames: %d + %zd > %d !",
1807 (unsigned int)frames_wr, out_buf.frameCount, (unsigned int)frames);
1808 frames_wr = frames;
1809 }
1810 }
1811 }
1812 else
1813#endif //PREPROCESSING_ENABLED
1814 {
1815 /* No processing effects attached */
1816 if (has_additional_channels) {
1817 /* With additional channels, we cannot use original buffer */
1818 if (in->proc_buf_size < (size_t)frames) {
1819 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, frames);
1820 in->proc_buf_size = (size_t)frames;
1821 in->proc_buf_out = (int16_t *)realloc(in->proc_buf_out, size_in_bytes);
1822 ALOG_ASSERT((in->proc_buf_out != NULL),
1823 "process_frames() failed to reallocate proc_buf_out");
1824 proc_buf_out = in->proc_buf_out;
1825 }
1826 }
1827 frames_wr = read_frames(in, proc_buf_out, frames);
1828 }
1829
1830 /* Remove all additional channels that have been added on top of main_channels:
1831 * - aux_channels
1832 * - extra channels from HW due to HW limitations
1833 * Assumption is made that the channels are interleaved and that the main
1834 * channels are first. */
1835
1836 if (has_additional_channels)
1837 {
1838 int16_t* src_buffer = (int16_t *)proc_buf_out;
1839 int16_t* dst_buffer = (int16_t *)buffer;
1840
1841 if (dst_channels == 1) {
1842 for (i = frames_wr; i > 0; i--)
1843 {
1844 *dst_buffer++ = *src_buffer;
1845 src_buffer += src_channels;
1846 }
1847 } else {
1848 for (i = frames_wr; i > 0; i--)
1849 {
1850 memcpy(dst_buffer, src_buffer, dst_channels*sizeof(int16_t));
1851 dst_buffer += dst_channels;
1852 src_buffer += src_channels;
1853 }
1854 }
1855 }
1856
1857 return frames_wr;
1858}
1859
1860static int get_next_buffer(struct resampler_buffer_provider *buffer_provider,
1861 struct resampler_buffer* buffer)
1862{
1863 struct stream_in *in;
1864 struct pcm_device *pcm_device;
1865
1866 if (buffer_provider == NULL || buffer == NULL)
1867 return -EINVAL;
1868
1869 in = (struct stream_in *)((char *)buffer_provider -
1870 offsetof(struct stream_in, buf_provider));
1871
1872 if (list_empty(&in->pcm_dev_list)) {
1873 buffer->raw = NULL;
1874 buffer->frame_count = 0;
1875 in->read_status = -ENODEV;
1876 return -ENODEV;
1877 }
1878
1879 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1880 struct pcm_device, stream_list_node);
1881
1882 if (in->read_buf_frames == 0) {
1883 size_t size_in_bytes = pcm_frames_to_bytes(pcm_device->pcm, in->config.period_size);
1884 if (in->read_buf_size < in->config.period_size) {
1885 in->read_buf_size = in->config.period_size;
1886 in->read_buf = (int16_t *) realloc(in->read_buf, size_in_bytes);
1887 ALOG_ASSERT((in->read_buf != NULL),
1888 "get_next_buffer() failed to reallocate read_buf");
1889 }
1890
1891 in->read_status = pcm_read(pcm_device->pcm, (void*)in->read_buf, size_in_bytes);
1892
1893 if (in->read_status != 0) {
1894 ALOGE("get_next_buffer() pcm_read error %d", in->read_status);
1895 buffer->raw = NULL;
1896 buffer->frame_count = 0;
1897 return in->read_status;
1898 }
1899 in->read_buf_frames = in->config.period_size;
1900
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001901 }
1902
1903 buffer->frame_count = (buffer->frame_count > in->read_buf_frames) ?
1904 in->read_buf_frames : buffer->frame_count;
1905 buffer->i16 = in->read_buf + (in->config.period_size - in->read_buf_frames) *
1906 in->config.channels;
1907 return in->read_status;
1908}
1909
1910static void release_buffer(struct resampler_buffer_provider *buffer_provider,
1911 struct resampler_buffer* buffer)
1912{
1913 struct stream_in *in;
1914
1915 if (buffer_provider == NULL || buffer == NULL)
1916 return;
1917
1918 in = (struct stream_in *)((char *)buffer_provider -
1919 offsetof(struct stream_in, buf_provider));
1920
1921 in->read_buf_frames -= buffer->frame_count;
1922}
1923
1924/* read_frames() reads frames from kernel driver, down samples to capture rate
1925 * if necessary and output the number of frames requested to the buffer specified */
1926static ssize_t read_frames(struct stream_in *in, void *buffer, ssize_t frames)
1927{
1928 ssize_t frames_wr = 0;
1929
1930 struct pcm_device *pcm_device;
1931
1932 if (list_empty(&in->pcm_dev_list)) {
1933 ALOGE("%s: pcm device list empty", __func__);
1934 return -EINVAL;
1935 }
1936
1937 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
1938 struct pcm_device, stream_list_node);
1939
1940 while (frames_wr < frames) {
1941 size_t frames_rd = frames - frames_wr;
1942 ALOGVV("%s: frames_rd: %zd, frames_wr: %zd, in->config.channels: %d",
1943 __func__,frames_rd,frames_wr,in->config.channels);
1944 if (in->resampler != NULL) {
1945 in->resampler->resample_from_provider(in->resampler,
1946 (int16_t *)((char *)buffer +
1947 pcm_frames_to_bytes(pcm_device->pcm, frames_wr)),
1948 &frames_rd);
1949 } else {
1950 struct resampler_buffer buf = {
Andreas Schneiderb7f32122017-01-31 08:18:34 +01001951 .raw = NULL,
1952 .frame_count = frames_rd,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01001953 };
1954 get_next_buffer(&in->buf_provider, &buf);
1955 if (buf.raw != NULL) {
1956 memcpy((char *)buffer +
1957 pcm_frames_to_bytes(pcm_device->pcm, frames_wr),
1958 buf.raw,
1959 pcm_frames_to_bytes(pcm_device->pcm, buf.frame_count));
1960 frames_rd = buf.frame_count;
1961 }
1962 release_buffer(&in->buf_provider, &buf);
1963 }
1964 /* in->read_status is updated by getNextBuffer() also called by
1965 * in->resampler->resample_from_provider() */
1966 if (in->read_status != 0)
1967 return in->read_status;
1968
1969 frames_wr += frames_rd;
1970 }
1971 return frames_wr;
1972}
1973
1974static int in_release_pcm_devices(struct stream_in *in)
1975{
1976 struct pcm_device *pcm_device;
1977 struct listnode *node;
1978 struct listnode *next;
1979
1980 list_for_each_safe(node, next, &in->pcm_dev_list) {
1981 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
1982 list_remove(node);
1983 free(pcm_device);
1984 }
1985
1986 return 0;
1987}
1988
1989static int stop_input_stream(struct stream_in *in)
1990{
1991 struct audio_usecase *uc_info;
1992 struct audio_device *adev = in->dev;
1993
1994 adev->active_input = NULL;
1995 ALOGV("%s: enter: usecase(%d: %s)", __func__,
1996 in->usecase, use_case_table[in->usecase]);
1997 uc_info = get_usecase_from_id(adev, in->usecase);
1998 if (uc_info == NULL) {
1999 ALOGE("%s: Could not find the usecase (%d) in the list",
2000 __func__, in->usecase);
2001 return -EINVAL;
2002 }
2003
2004 /* Disable the tx device */
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002005 disable_snd_device(adev, uc_info, uc_info->in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002006
2007 list_remove(&uc_info->adev_list_node);
2008 free(uc_info);
2009
2010 if (list_empty(&in->pcm_dev_list)) {
2011 ALOGE("%s: pcm device list empty", __func__);
2012 return -EINVAL;
2013 }
2014
2015 in_release_pcm_devices(in);
2016 list_init(&in->pcm_dev_list);
2017
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002018 ALOGV("%s: exit", __func__);
2019 return 0;
2020}
2021
2022static int start_input_stream(struct stream_in *in)
2023{
2024 /* Enable output device and stream routing controls */
2025 int ret = 0;
2026 bool recreate_resampler = false;
2027 struct audio_usecase *uc_info;
2028 struct audio_device *adev = in->dev;
2029 struct pcm_device_profile *pcm_profile;
2030 struct pcm_device *pcm_device;
2031
2032 ALOGV("%s: enter: usecase(%d)", __func__, in->usecase);
2033 adev->active_input = in;
2034 pcm_profile = get_pcm_device(in->usecase_type, in->devices);
2035 if (pcm_profile == NULL) {
2036 ALOGE("%s: Could not find PCM device id for the usecase(%d)",
2037 __func__, in->usecase);
2038 ret = -EINVAL;
2039 goto error_config;
2040 }
2041
2042 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002043 if (uc_info == NULL) {
2044 ret = -ENOMEM;
2045 goto error_config;
2046 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002047 uc_info->id = in->usecase;
2048 uc_info->type = PCM_CAPTURE;
2049 uc_info->stream = (struct audio_stream *)in;
2050 uc_info->devices = in->devices;
2051 uc_info->in_snd_device = SND_DEVICE_NONE;
2052 uc_info->out_snd_device = SND_DEVICE_NONE;
2053
2054 pcm_device = (struct pcm_device *)calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01002055 if (pcm_device == NULL) {
2056 free(uc_info);
2057 ret = -ENOMEM;
2058 goto error_config;
2059 }
2060
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002061 pcm_device->pcm_profile = pcm_profile;
2062 list_init(&in->pcm_dev_list);
2063 list_add_tail(&in->pcm_dev_list, &pcm_device->stream_list_node);
2064
2065 list_init(&uc_info->mixer_list);
2066 list_add_tail(&uc_info->mixer_list,
2067 &adev_get_mixer_for_card(adev,
2068 pcm_device->pcm_profile->card)->uc_list_node[uc_info->id]);
2069
2070 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2071
2072 select_devices(adev, in->usecase);
2073
2074 /* Config should be updated as profile can be changed between different calls
2075 * to this function:
2076 * - Trigger resampler creation
2077 * - Config needs to be updated */
2078 if (in->config.rate != pcm_profile->config.rate) {
2079 recreate_resampler = true;
2080 }
2081 in->config = pcm_profile->config;
2082
2083#ifdef PREPROCESSING_ENABLED
2084 if (in->aux_channels_changed) {
2085 in->config.channels = audio_channel_count_from_in_mask(in->main_channels | in->aux_channels);
2086 recreate_resampler = true;
2087 }
2088#endif
2089
2090 if (in->requested_rate != in->config.rate) {
2091 recreate_resampler = true;
2092 }
2093
2094 if (recreate_resampler) {
2095 if (in->resampler) {
2096 release_resampler(in->resampler);
2097 in->resampler = NULL;
2098 }
2099 in->buf_provider.get_next_buffer = get_next_buffer;
2100 in->buf_provider.release_buffer = release_buffer;
2101 ret = create_resampler(in->config.rate,
2102 in->requested_rate,
2103 in->config.channels,
2104 RESAMPLER_QUALITY_DEFAULT,
2105 &in->buf_provider,
2106 &in->resampler);
2107 }
2108
2109#ifdef PREPROCESSING_ENABLED
2110 if (in->enable_aec && in->echo_reference == NULL) {
2111 in->echo_reference = get_echo_reference(adev,
2112 AUDIO_FORMAT_PCM_16_BIT,
2113 audio_channel_count_from_in_mask(in->main_channels),
2114 in->requested_rate
2115 );
2116 }
2117
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002118#endif
2119
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002120 if (in->dev->voice.in_call) {
2121 ALOGV("%s: in_call, not handling PCMs", __func__);
2122 goto skip_pcm_handling;
2123 }
2124
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002125 /* Open the PCM device.
2126 * The HW is limited to support only the default pcm_profile settings.
2127 * As such a change in aux_channels will not have an effect.
2128 */
2129 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d, smp rate %d format %d, \
2130 period_size %d", __func__, pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
2131 pcm_device->pcm_profile->config.channels,pcm_device->pcm_profile->config.rate,
2132 pcm_device->pcm_profile->config.format, pcm_device->pcm_profile->config.period_size);
2133
stenkinevgeniy44335362018-05-07 18:00:13 +00002134 pcm_device->pcm = pcm_open(pcm_device->pcm_profile->card, pcm_device->pcm_profile->id,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002135 PCM_IN | PCM_MONOTONIC, &pcm_device->pcm_profile->config);
2136
stenkinevgeniy44335362018-05-07 18:00:13 +00002137 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2138 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2139 pcm_close(pcm_device->pcm);
2140 pcm_device->pcm = NULL;
2141 ret = -EIO;
2142 goto error_open;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002143 }
2144
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002145skip_pcm_handling:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002146 /* force read and proc buffer reallocation in case of frame size or
2147 * channel count change */
2148 in->proc_buf_frames = 0;
2149 in->proc_buf_size = 0;
2150 in->read_buf_size = 0;
2151 in->read_buf_frames = 0;
2152
2153 /* if no supported sample rate is available, use the resampler */
2154 if (in->resampler) {
2155 in->resampler->reset(in->resampler);
2156 }
2157
2158 ALOGV("%s: exit", __func__);
2159 return ret;
2160
2161error_open:
2162 if (in->resampler) {
2163 release_resampler(in->resampler);
2164 in->resampler = NULL;
2165 }
2166 stop_input_stream(in);
2167
2168error_config:
2169 ALOGV("%s: exit: status(%d)", __func__, ret);
2170 adev->active_input = NULL;
2171 return ret;
2172}
2173
2174void lock_input_stream(struct stream_in *in)
2175{
2176 pthread_mutex_lock(&in->pre_lock);
2177 pthread_mutex_lock(&in->lock);
2178 pthread_mutex_unlock(&in->pre_lock);
2179}
2180
2181void lock_output_stream(struct stream_out *out)
2182{
2183 pthread_mutex_lock(&out->pre_lock);
2184 pthread_mutex_lock(&out->lock);
2185 pthread_mutex_unlock(&out->pre_lock);
2186}
2187
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002188static int uc_release_pcm_devices(struct audio_usecase *usecase)
2189{
2190 struct stream_out *out = (struct stream_out *)usecase->stream;
2191 struct pcm_device *pcm_device;
2192 struct listnode *node;
2193 struct listnode *next;
2194
2195 list_for_each_safe(node, next, &out->pcm_dev_list) {
2196 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2197 list_remove(node);
2198 free(pcm_device);
2199 }
2200 list_init(&usecase->mixer_list);
2201
2202 return 0;
2203}
2204
2205static int uc_select_pcm_devices(struct audio_usecase *usecase)
2206
2207{
2208 struct stream_out *out = (struct stream_out *)usecase->stream;
2209 struct pcm_device *pcm_device;
2210 struct pcm_device_profile *pcm_profile;
2211 struct mixer_card *mixer_card;
2212 audio_devices_t devices = usecase->devices;
2213
2214 list_init(&usecase->mixer_list);
2215 list_init(&out->pcm_dev_list);
2216
2217 while ((pcm_profile = get_pcm_device(usecase->type, devices)) != NULL) {
2218 pcm_device = calloc(1, sizeof(struct pcm_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01002219 if (pcm_device == NULL) {
2220 return -ENOMEM;
2221 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002222 pcm_device->pcm_profile = pcm_profile;
2223 list_add_tail(&out->pcm_dev_list, &pcm_device->stream_list_node);
2224 mixer_card = uc_get_mixer_for_card(usecase, pcm_profile->card);
2225 if (mixer_card == NULL) {
2226 mixer_card = adev_get_mixer_for_card(out->dev, pcm_profile->card);
2227 list_add_tail(&usecase->mixer_list, &mixer_card->uc_list_node[usecase->id]);
2228 }
2229 devices &= ~pcm_profile->devices;
2230 }
2231
2232 return 0;
2233}
2234
2235static int out_close_pcm_devices(struct stream_out *out)
2236{
2237 struct pcm_device *pcm_device;
2238 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002239
2240 list_for_each(node, &out->pcm_dev_list) {
2241 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002242 if (pcm_device->pcm) {
2243 pcm_close(pcm_device->pcm);
2244 pcm_device->pcm = NULL;
2245 }
2246 if (pcm_device->resampler) {
2247 release_resampler(pcm_device->resampler);
2248 pcm_device->resampler = NULL;
2249 }
2250 if (pcm_device->res_buffer) {
2251 free(pcm_device->res_buffer);
2252 pcm_device->res_buffer = NULL;
2253 }
2254 }
2255
2256 return 0;
2257}
2258
2259static int out_open_pcm_devices(struct stream_out *out)
2260{
2261 struct pcm_device *pcm_device;
2262 struct listnode *node;
2263 int ret = 0;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002264 int pcm_device_card;
2265 int pcm_device_id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002266
2267 list_for_each(node, &out->pcm_dev_list) {
2268 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002269 pcm_device_card = pcm_device->pcm_profile->card;
2270 pcm_device_id = pcm_device->pcm_profile->id;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002271
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002272 if (out->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
2273 pcm_device_id = pcm_device_deep_buffer.id;
2274
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002275 if (out->dev->voice.in_call) {
2276 ALOGV("%s: in_call, not opening PCMs", __func__);
2277 return ret;
2278 }
2279
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002280 ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
2281 __func__, pcm_device_card, pcm_device_id);
2282
2283 pcm_device->pcm = pcm_open(pcm_device_card, pcm_device_id,
stenkinevgeniy2ef158a2018-05-08 06:52:05 +00002284 PCM_OUT | PCM_MONOTONIC, &out->config);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002285
2286 if (pcm_device->pcm && !pcm_is_ready(pcm_device->pcm)) {
2287 ALOGE("%s: %s", __func__, pcm_get_error(pcm_device->pcm));
2288 pcm_device->pcm = NULL;
2289 ret = -EIO;
2290 goto error_open;
2291 }
2292 /*
2293 * If the stream rate differs from the PCM rate, we need to
2294 * create a resampler.
2295 */
2296 if (out->sample_rate != pcm_device->pcm_profile->config.rate) {
2297 ALOGV("%s: create_resampler(), pcm_device_card(%d), pcm_device_id(%d), \
2298 out_rate(%d), device_rate(%d)",__func__,
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01002299 pcm_device_card, pcm_device_id,
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002300 out->sample_rate, pcm_device->pcm_profile->config.rate);
2301 ret = create_resampler(out->sample_rate,
2302 pcm_device->pcm_profile->config.rate,
2303 audio_channel_count_from_out_mask(out->channel_mask),
2304 RESAMPLER_QUALITY_DEFAULT,
2305 NULL,
2306 &pcm_device->resampler);
2307 pcm_device->res_byte_count = 0;
2308 pcm_device->res_buffer = NULL;
2309 }
2310 }
2311 return ret;
2312
2313error_open:
2314 out_close_pcm_devices(out);
2315 return ret;
2316}
2317
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002318int disable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002319{
2320 struct audio_device *adev = out->dev;
2321 struct audio_usecase *uc_info;
2322
2323 uc_info = get_usecase_from_id(adev, out->usecase);
2324 if (uc_info == NULL) {
2325 ALOGE("%s: Could not find the usecase (%d) in the list",
2326 __func__, out->usecase);
2327 return -EINVAL;
2328 }
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002329 disable_snd_device(adev, uc_info, uc_info->out_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002330 uc_release_pcm_devices(uc_info);
2331 list_remove(&uc_info->adev_list_node);
2332 free(uc_info);
2333
2334 return 0;
2335}
2336
Andreas Schneider56204f62017-01-31 08:17:32 +01002337int enable_output_path_l(struct stream_out *out)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002338{
2339 struct audio_device *adev = out->dev;
2340 struct audio_usecase *uc_info;
2341
2342 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002343 if (uc_info == NULL) {
2344 return -ENOMEM;
2345 }
2346
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002347 uc_info->id = out->usecase;
2348 uc_info->type = PCM_PLAYBACK;
2349 uc_info->stream = (struct audio_stream *)out;
2350 uc_info->devices = out->devices;
2351 uc_info->in_snd_device = SND_DEVICE_NONE;
2352 uc_info->out_snd_device = SND_DEVICE_NONE;
2353 uc_select_pcm_devices(uc_info);
2354
2355 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2356 select_devices(adev, out->usecase);
Andreas Schneider56204f62017-01-31 08:17:32 +01002357
2358 return 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002359}
2360
2361static int stop_output_stream(struct stream_out *out)
2362{
2363 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002364 bool do_disable = true;
2365
2366 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2367 out->usecase, use_case_table[out->usecase]);
2368
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002369 stop_output_offload_stream(out, &do_disable);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002370
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002371 if (do_disable)
2372 ret = disable_output_path_l(out);
2373
2374 ALOGV("%s: exit: status(%d)", __func__, ret);
2375 return ret;
2376}
2377
2378static int start_output_stream(struct stream_out *out)
2379{
2380 int ret = 0;
2381 struct audio_device *adev = out->dev;
2382
2383 ALOGV("%s: enter: usecase(%d: %s) devices(%#x) channels(%d)",
2384 __func__, out->usecase, use_case_table[out->usecase], out->devices, out->config.channels);
2385
Andreas Schneider56204f62017-01-31 08:17:32 +01002386 ret = enable_output_path_l(out);
2387 if (ret != 0) {
2388 goto error_config;
2389 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002390
2391 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2392 out->compr = NULL;
2393 ret = out_open_pcm_devices(out);
2394 if (ret != 0)
2395 goto error_open;
2396#ifdef PREPROCESSING_ENABLED
2397 out->echo_reference = NULL;
2398 out->echo_reference_generation = adev->echo_reference_generation;
2399 if (adev->echo_reference != NULL)
2400 out->echo_reference = adev->echo_reference;
2401#endif
2402 } else {
2403 out->compr = compress_open(COMPRESS_CARD, COMPRESS_DEVICE,
2404 COMPRESS_IN, &out->compr_config);
2405 if (out->compr && !is_compress_ready(out->compr)) {
2406 ALOGE("%s: %s", __func__, compress_get_error(out->compr));
2407 compress_close(out->compr);
2408 out->compr = NULL;
2409 ret = -EIO;
2410 goto error_open;
2411 }
2412 if (out->offload_callback)
2413 compress_nonblock(out->compr, out->non_blocking);
2414
2415 if (adev->offload_fx_start_output != NULL)
2416 adev->offload_fx_start_output(out->handle);
2417 }
2418 ALOGV("%s: exit", __func__);
2419 return 0;
2420error_open:
2421 stop_output_stream(out);
2422error_config:
2423 return ret;
2424}
2425
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002426int stop_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002427{
2428 struct audio_usecase *uc_info;
2429
2430 ALOGV("%s: enter", __func__);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002431 adev->voice.in_call = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002432
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002433 stop_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002434
2435 uc_info = get_usecase_from_id(adev, USECASE_VOICE_CALL);
2436 if (uc_info == NULL) {
2437 ALOGE("%s: Could not find the usecase (%d) in the list",
2438 __func__, USECASE_VOICE_CALL);
2439 return -EINVAL;
2440 }
2441
Christopher N. Hesse8179c012018-03-09 23:20:55 +01002442 disable_snd_device(adev, uc_info, uc_info->out_snd_device);
2443 disable_snd_device(adev, uc_info, uc_info->in_snd_device);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002444
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002445 list_remove(&uc_info->adev_list_node);
2446 free(uc_info);
2447
2448 ALOGV("%s: exit", __func__);
2449 return 0;
2450}
2451
2452/* always called with adev lock held */
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002453int start_voice_call(struct audio_device *adev)
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002454{
2455 struct audio_usecase *uc_info;
Andreas Schneider56204f62017-01-31 08:17:32 +01002456 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002457
2458 ALOGV("%s: enter", __func__);
2459
2460 uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
Andreas Schneider56204f62017-01-31 08:17:32 +01002461 if (uc_info == NULL) {
2462 ret = -ENOMEM;
2463 goto exit;
2464 }
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002465 /*
2466 * We set this early so that functions called after this is being set
2467 * can use it. It is e.g. needed in select_devices() to inform the RILD
2468 * which output device we use.
2469 */
2470 adev->voice.in_call = true;
Andreas Schneider56204f62017-01-31 08:17:32 +01002471
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002472 uc_info->id = USECASE_VOICE_CALL;
2473 uc_info->type = VOICE_CALL;
2474 uc_info->stream = (struct audio_stream *)adev->primary_output;
2475 uc_info->devices = adev->primary_output->devices;
2476 uc_info->in_snd_device = SND_DEVICE_NONE;
2477 uc_info->out_snd_device = SND_DEVICE_NONE;
2478
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002479 list_init(&uc_info->mixer_list);
2480 list_add_tail(&uc_info->mixer_list,
2481 &adev_get_mixer_for_card(adev, SOUND_CARD)->uc_list_node[uc_info->id]);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002482
2483 list_add_tail(&adev->usecase_list, &uc_info->adev_list_node);
2484
2485 select_devices(adev, USECASE_VOICE_CALL);
2486
Christopher N. Hesse696959d2017-02-02 20:49:55 +01002487 start_voice_session(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002488
2489 /* set cached volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002490 set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002491
Andreas Schneider56204f62017-01-31 08:17:32 +01002492exit:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002493 ALOGV("%s: exit", __func__);
Andreas Schneider56204f62017-01-31 08:17:32 +01002494 return ret;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002495}
2496
2497static int check_input_parameters(uint32_t sample_rate,
2498 audio_format_t format,
2499 int channel_count)
2500{
2501 if (format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL;
2502
2503 if ((channel_count < 1) || (channel_count > 2)) return -EINVAL;
2504
2505 switch (sample_rate) {
2506 case 8000:
2507 case 11025:
2508 case 12000:
2509 case 16000:
2510 case 22050:
2511 case 24000:
2512 case 32000:
2513 case 44100:
2514 case 48000:
2515 break;
2516 default:
2517 return -EINVAL;
2518 }
2519
2520 return 0;
2521}
2522
2523static size_t get_input_buffer_size(uint32_t sample_rate,
2524 audio_format_t format,
2525 int channel_count,
2526 usecase_type_t usecase_type,
2527 audio_devices_t devices)
2528{
2529 size_t size = 0;
2530 struct pcm_device_profile *pcm_profile;
2531
2532 if (check_input_parameters(sample_rate, format, channel_count) != 0)
2533 return 0;
2534
2535 pcm_profile = get_pcm_device(usecase_type, devices);
2536 if (pcm_profile == NULL)
2537 return 0;
2538
2539 /*
2540 * take resampling into account and return the closest majoring
2541 * multiple of 16 frames, as audioflinger expects audio buffers to
2542 * be a multiple of 16 frames
2543 */
2544 size = (pcm_profile->config.period_size * sample_rate) / pcm_profile->config.rate;
2545 size = ((size + 15) / 16) * 16;
2546
2547 return (size * channel_count * audio_bytes_per_sample(format));
2548
2549}
2550
2551static uint32_t out_get_sample_rate(const struct audio_stream *stream)
2552{
2553 struct stream_out *out = (struct stream_out *)stream;
2554
2555 return out->sample_rate;
2556}
2557
2558static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
2559{
2560 (void)stream;
2561 (void)rate;
2562 return -ENOSYS;
2563}
2564
2565static size_t out_get_buffer_size(const struct audio_stream *stream)
2566{
2567 struct stream_out *out = (struct stream_out *)stream;
2568
2569 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2570 return out->compr_config.fragment_size;
2571 }
2572
2573 return out->config.period_size *
2574 audio_stream_out_frame_size((const struct audio_stream_out *)stream);
2575}
2576
2577static uint32_t out_get_channels(const struct audio_stream *stream)
2578{
2579 struct stream_out *out = (struct stream_out *)stream;
2580
2581 return out->channel_mask;
2582}
2583
2584static audio_format_t out_get_format(const struct audio_stream *stream)
2585{
2586 struct stream_out *out = (struct stream_out *)stream;
2587
2588 return out->format;
2589}
2590
2591static int out_set_format(struct audio_stream *stream, audio_format_t format)
2592{
2593 (void)stream;
2594 (void)format;
2595 return -ENOSYS;
2596}
2597
2598static int do_out_standby_l(struct stream_out *out)
2599{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002600 int status = 0;
2601
2602 out->standby = true;
2603 if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2604 out_close_pcm_devices(out);
2605#ifdef PREPROCESSING_ENABLED
2606 /* stop writing to echo reference */
2607 if (out->echo_reference != NULL) {
2608 out->echo_reference->write(out->echo_reference, NULL);
2609 if (out->echo_reference_generation != adev->echo_reference_generation) {
2610 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
2611 release_echo_reference(out->echo_reference);
2612 out->echo_reference_generation = adev->echo_reference_generation;
2613 }
2614 out->echo_reference = NULL;
2615 }
2616#endif
2617 } else {
2618 stop_compressed_output_l(out);
2619 out->gapless_mdata.encoder_delay = 0;
2620 out->gapless_mdata.encoder_padding = 0;
2621 if (out->compr != NULL) {
2622 compress_close(out->compr);
2623 out->compr = NULL;
2624 }
2625 }
2626 status = stop_output_stream(out);
2627
2628 return status;
2629}
2630
2631static int out_standby(struct audio_stream *stream)
2632{
2633 struct stream_out *out = (struct stream_out *)stream;
2634 struct audio_device *adev = out->dev;
2635
2636 ALOGV("%s: enter: usecase(%d: %s)", __func__,
2637 out->usecase, use_case_table[out->usecase]);
2638 lock_output_stream(out);
2639 if (!out->standby) {
2640 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002641 amplifier_output_stream_standby((struct audio_stream_out *) stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002642 do_out_standby_l(out);
2643 pthread_mutex_unlock(&adev->lock);
2644 }
2645 pthread_mutex_unlock(&out->lock);
2646 ALOGV("%s: exit", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01002647
2648 // out->last_write_time_us = 0; unnecessary as a stale write time has same effect
2649
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002650 return 0;
2651}
2652
2653static int out_dump(const struct audio_stream *stream, int fd)
2654{
2655 (void)stream;
2656 (void)fd;
2657
2658 return 0;
2659}
2660
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002661static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
2662{
2663 struct stream_out *out = (struct stream_out *)stream;
2664 struct audio_device *adev = out->dev;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002665 struct listnode *node;
2666 struct str_parms *parms;
2667 char value[32];
2668 int ret, val = 0;
2669 struct audio_usecase *uc_info;
2670 bool do_standby = false;
2671 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002672#ifdef PREPROCESSING_ENABLED
2673 struct stream_in *in = NULL; /* if non-NULL, then force input to standby */
2674#endif
2675
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002676 ALOGV("%s: enter: usecase(%d: %s) kvpairs: %s out->devices(%#x) "
2677 "adev->mode(%#x)",
2678 __func__, out->usecase, use_case_table[out->usecase], kvpairs,
2679 out->devices, adev->mode);
2680
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002681 parms = str_parms_create_str(kvpairs);
2682 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
2683 if (ret >= 0) {
2684 val = atoi(value);
Andreas Schneiderdd8a3692017-02-14 12:51:30 +01002685
2686 ALOGV("%s: routing: usecase(%d: %s) devices=(%#x) adev->mode(%#x)",
2687 __func__, out->usecase, use_case_table[out->usecase], val,
2688 adev->mode);
2689
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002690 pthread_mutex_lock(&adev->lock_inputs);
2691 lock_output_stream(out);
2692 pthread_mutex_lock(&adev->lock);
2693#ifdef PREPROCESSING_ENABLED
2694 if (((int)out->devices != val) && (val != 0) && (!out->standby) &&
2695 (out->usecase == USECASE_AUDIO_PLAYBACK)) {
2696 /* reset active input:
2697 * - to attach the echo reference
2698 * - because a change in output device may change mic settings */
2699 if (adev->active_input && (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
2700 adev->active_input->source == AUDIO_SOURCE_MIC)) {
2701 in = adev->active_input;
2702 }
2703 }
2704#endif
Christopher N. Hesse33affb82017-11-16 17:01:37 +01002705 if (val != SND_DEVICE_NONE) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002706 bool bt_sco_active = false;
2707
2708 if (out->devices & AUDIO_DEVICE_OUT_ALL_SCO) {
2709 bt_sco_active = true;
2710 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002711 out->devices = val;
2712
2713 if (!out->standby) {
2714 uc_info = get_usecase_from_id(adev, out->usecase);
2715 if (uc_info == NULL) {
2716 ALOGE("%s: Could not find the usecase (%d) in the list",
2717 __func__, out->usecase);
2718 } else {
2719 list_for_each(node, &out->pcm_dev_list) {
2720 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2721 if ((pcm_device->pcm_profile->devices & val) == 0)
2722 do_standby = true;
2723 val &= ~pcm_device->pcm_profile->devices;
2724 }
2725 if (val != 0)
2726 do_standby = true;
2727 }
2728 if (do_standby)
2729 do_out_standby_l(out);
2730 else {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002731 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
2732 out_set_offload_parameters(adev, uc_info);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002733 select_devices(adev, out->usecase);
2734 }
2735 }
2736
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002737 if ((adev->mode == AUDIO_MODE_IN_CALL) && !adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002738 (out == adev->primary_output)) {
2739 start_voice_call(adev);
Andreas Schneider74ef3a12017-02-02 18:29:12 +01002740 } else if ((adev->mode == AUDIO_MODE_IN_CALL) &&
2741 adev->voice.in_call &&
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002742 (out == adev->primary_output)) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01002743 /* Turn on bluetooth if needed */
2744 if ((out->devices & AUDIO_DEVICE_OUT_ALL_SCO) && !bt_sco_active) {
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002745 select_devices(adev, USECASE_VOICE_CALL);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002746 start_voice_session_bt_sco(adev->voice.session);
Andreas Schneidere9a44a22017-02-14 13:00:48 +01002747 } else {
2748 /*
2749 * When we select different devices we need to restart the
2750 * voice call. The modem closes the stream on its end and
2751 * we do not get any output.
2752 */
2753 stop_voice_call(adev);
2754 start_voice_call(adev);
Andreas Schneider05bc1882017-02-09 14:03:11 +01002755 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002756 }
2757 }
2758
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002759 pthread_mutex_unlock(&adev->lock);
2760 pthread_mutex_unlock(&out->lock);
2761#ifdef PREPROCESSING_ENABLED
2762 if (in) {
2763 /* The lock on adev->lock_inputs prevents input stream from being closed */
2764 lock_input_stream(in);
2765 pthread_mutex_lock(&adev->lock);
2766 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
2767 do_in_standby_l(in);
2768 pthread_mutex_unlock(&adev->lock);
2769 pthread_mutex_unlock(&in->lock);
2770 }
2771#endif
2772 pthread_mutex_unlock(&adev->lock_inputs);
2773 }
2774
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002775 amplifier_set_parameters(parms);
2776
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002777 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
2778 parse_compress_metadata(out, parms);
2779 }
2780
2781 str_parms_destroy(parms);
2782
2783 if (ret > 0)
2784 ret = 0;
2785 ALOGV("%s: exit: code(%d)", __func__, ret);
2786 return ret;
2787}
2788
2789static char* out_get_parameters(const struct audio_stream *stream, const char *keys)
2790{
2791 struct stream_out *out = (struct stream_out *)stream;
2792 struct str_parms *query = str_parms_create_str(keys);
2793 char *str;
2794 char value[256];
2795 struct str_parms *reply = str_parms_create();
2796 size_t i, j;
2797 int ret;
2798 bool first = true;
2799 ALOGV("%s: enter: keys - %s", __func__, keys);
2800 ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value, sizeof(value));
2801 if (ret >= 0) {
2802 value[0] = '\0';
2803 i = 0;
2804 while (out->supported_channel_masks[i] != 0) {
2805 for (j = 0; j < ARRAY_SIZE(out_channels_name_to_enum_table); j++) {
2806 if (out_channels_name_to_enum_table[j].value == out->supported_channel_masks[i]) {
2807 if (!first) {
2808 strcat(value, "|");
2809 }
2810 strcat(value, out_channels_name_to_enum_table[j].name);
2811 first = false;
2812 break;
2813 }
2814 }
2815 i++;
2816 }
2817 str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
2818 str = str_parms_to_str(reply);
2819 } else {
2820 str = strdup(keys);
2821 }
2822 str_parms_destroy(query);
2823 str_parms_destroy(reply);
2824 ALOGV("%s: exit: returns - %s", __func__, str);
2825 return str;
2826}
2827
2828static uint32_t out_get_latency(const struct audio_stream_out *stream)
2829{
2830 struct stream_out *out = (struct stream_out *)stream;
2831
2832 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
2833 return COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
2834
2835 return (out->config.period_count * out->config.period_size * 1000) /
2836 (out->config.rate);
2837}
2838
2839static int out_set_volume(struct audio_stream_out *stream, float left,
2840 float right)
2841{
2842 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002843
2844 if (out->usecase == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
2845 /* only take left channel into account: the API is for stereo anyway */
2846 out->muted = (left == 0.0f);
2847 return 0;
2848 } else if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002849 out_set_offload_volume(left, right);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002850 }
2851
2852 return -ENOSYS;
2853}
2854
Andreas Schneider3b643832017-01-31 11:48:22 +01002855#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002856static int fast_set_affinity(pid_t tid) {
2857 cpu_set_t cpu_set;
2858 int cpu_num;
2859 const char *irq_procfs = "/proc/asound/irq_affinity";
2860 FILE *fp;
2861
2862 if ((fp = fopen(irq_procfs, "r")) == NULL) {
2863 ALOGW("Procfs node %s not found", irq_procfs);
2864 return -1;
2865 }
2866
2867 if (fscanf(fp, "%d", &cpu_num) != 1) {
2868 ALOGW("Couldn't read CPU id from procfs node %s", irq_procfs);
2869 fclose(fp);
2870 return -1;
2871 }
2872 fclose(fp);
2873
2874 CPU_ZERO(&cpu_set);
2875 CPU_SET(cpu_num, &cpu_set);
2876 return sched_setaffinity(tid, sizeof(cpu_set), &cpu_set);
2877}
Andreas Schneider3b643832017-01-31 11:48:22 +01002878#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002879
2880static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
2881 size_t bytes)
2882{
2883 struct stream_out *out = (struct stream_out *)stream;
2884 struct audio_device *adev = out->dev;
2885 ssize_t ret = 0;
2886 struct pcm_device *pcm_device;
2887 struct listnode *node;
2888 size_t frame_size = audio_stream_out_frame_size(stream);
2889 size_t frames_wr = 0, frames_rq = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002890#ifdef PREPROCESSING_ENABLED
2891 size_t in_frames = bytes / frame_size;
2892 size_t out_frames = in_frames;
2893 struct stream_in *in = NULL;
2894#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002895
2896 lock_output_stream(out);
2897
Andreas Schneider3b643832017-01-31 11:48:22 +01002898#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002899 if (out->usecase == USECASE_AUDIO_PLAYBACK && !out->is_fastmixer_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01002900 pid_t tid = gettid();
2901 int err;
2902
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002903 err = fast_set_affinity(tid);
2904 if (err < 0) {
2905 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
2906 }
2907 out->is_fastmixer_affinity_set = true;
2908 }
Andreas Schneider3b643832017-01-31 11:48:22 +01002909#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002910
2911 if (out->standby) {
2912#ifdef PREPROCESSING_ENABLED
2913 pthread_mutex_unlock(&out->lock);
2914 /* Prevent input stream from being closed */
2915 pthread_mutex_lock(&adev->lock_inputs);
2916 lock_output_stream(out);
2917 if (!out->standby) {
2918 pthread_mutex_unlock(&adev->lock_inputs);
2919 goto false_alarm;
2920 }
2921#endif
2922 pthread_mutex_lock(&adev->lock);
2923 ret = start_output_stream(out);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02002924 if (ret == 0) {
2925 amplifier_output_stream_start(stream, out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD);
2926 }
2927
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002928 /* ToDo: If use case is compress offload should return 0 */
2929 if (ret != 0) {
2930 pthread_mutex_unlock(&adev->lock);
2931#ifdef PREPROCESSING_ENABLED
2932 pthread_mutex_unlock(&adev->lock_inputs);
2933#endif
2934 goto exit;
2935 }
2936 out->standby = false;
2937
2938#ifdef PREPROCESSING_ENABLED
2939 /* A change in output device may change the microphone selection */
2940 if (adev->active_input &&
2941 (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
2942 adev->active_input->source == AUDIO_SOURCE_MIC)) {
2943 in = adev->active_input;
2944 ALOGV("%s: enter:) force_input_standby true", __func__);
2945 }
2946#endif
2947 pthread_mutex_unlock(&adev->lock);
2948#ifdef PREPROCESSING_ENABLED
2949 if (!in) {
2950 /* Leave mutex locked iff in != NULL */
2951 pthread_mutex_unlock(&adev->lock_inputs);
2952 }
2953#endif
2954 }
Andreas Schneider5a2f1002017-02-09 10:59:04 +01002955#ifdef PREPROCESSING_ENABLED
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002956false_alarm:
Andreas Schneider5a2f1002017-02-09 10:59:04 +01002957#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002958
2959 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01002960 ret = out_write_offload(stream, buffer, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01002961 return ret;
2962 } else {
2963#ifdef PREPROCESSING_ENABLED
2964 if (android_atomic_acquire_load(&adev->echo_reference_generation)
2965 != out->echo_reference_generation) {
2966 pthread_mutex_lock(&adev->lock);
2967 if (out->echo_reference != NULL) {
2968 ALOGV("%s: release_echo_reference %p", __func__, out->echo_reference);
2969 release_echo_reference(out->echo_reference);
2970 }
2971 // note that adev->echo_reference_generation here can be different from the one
2972 // tested above but it doesn't matter as we now have the adev mutex and it is consistent
2973 // with what has been set by get_echo_reference() or put_echo_reference()
2974 out->echo_reference_generation = adev->echo_reference_generation;
2975 out->echo_reference = adev->echo_reference;
2976 ALOGV("%s: update echo reference generation %d", __func__,
2977 out->echo_reference_generation);
2978 pthread_mutex_unlock(&adev->lock);
2979 }
2980#endif
2981
2982 if (out->muted)
2983 memset((void *)buffer, 0, bytes);
2984 list_for_each(node, &out->pcm_dev_list) {
2985 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
2986 if (pcm_device->resampler) {
2987 if (bytes * pcm_device->pcm_profile->config.rate / out->sample_rate + frame_size
2988 > pcm_device->res_byte_count) {
2989 pcm_device->res_byte_count =
2990 bytes * pcm_device->pcm_profile->config.rate / out->sample_rate + frame_size;
2991 pcm_device->res_buffer =
2992 realloc(pcm_device->res_buffer, pcm_device->res_byte_count);
2993 ALOGV("%s: resampler res_byte_count = %zu", __func__,
2994 pcm_device->res_byte_count);
2995 }
2996 frames_rq = bytes / frame_size;
2997 frames_wr = pcm_device->res_byte_count / frame_size;
2998 ALOGVV("%s: resampler request frames = %d frame_size = %d",
2999 __func__, frames_rq, frame_size);
3000 pcm_device->resampler->resample_from_input(pcm_device->resampler,
3001 (int16_t *)buffer, &frames_rq, (int16_t *)pcm_device->res_buffer, &frames_wr);
3002 ALOGVV("%s: resampler output frames_= %d", __func__, frames_wr);
3003 }
3004 if (pcm_device->pcm) {
3005#ifdef PREPROCESSING_ENABLED
3006 if (out->echo_reference != NULL && pcm_device->pcm_profile->devices != SND_DEVICE_OUT_SPEAKER) {
3007 struct echo_reference_buffer b;
3008 b.raw = (void *)buffer;
3009 b.frame_count = in_frames;
3010
3011 get_playback_delay(out, out_frames, &b);
3012 out->echo_reference->write(out->echo_reference, &b);
3013 }
3014#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003015 ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
3016 if (pcm_device->resampler && pcm_device->res_buffer)
3017 pcm_device->status =
3018 pcm_write(pcm_device->pcm, (void *)pcm_device->res_buffer,
3019 frames_wr * frame_size);
3020 else
3021 pcm_device->status = pcm_write(pcm_device->pcm, (void *)buffer, bytes);
3022 if (pcm_device->status != 0)
3023 ret = pcm_device->status;
3024 }
3025 }
3026 if (ret == 0)
3027 out->written += bytes / (out->config.channels * sizeof(short));
3028 }
3029
3030exit:
3031 pthread_mutex_unlock(&out->lock);
3032
3033 if (ret != 0) {
3034 list_for_each(node, &out->pcm_dev_list) {
3035 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3036 if (pcm_device->pcm && pcm_device->status != 0)
3037 ALOGE("%s: error %zd - %s", __func__, ret, pcm_get_error(pcm_device->pcm));
3038 }
3039 out_standby(&out->stream.common);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003040 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3041 clock_gettime(CLOCK_MONOTONIC, &t);
3042 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3043 const int64_t elapsed_time_since_last_write = now - out->last_write_time_us;
3044 int64_t sleep_time = bytes * 1000000LL / audio_stream_out_frame_size(stream) /
3045 out_get_sample_rate(&stream->common) - elapsed_time_since_last_write;
3046 if (sleep_time > 0) {
3047 usleep(sleep_time);
3048 } else {
3049 // we don't sleep when we exit standby (this is typical for a real alsa buffer).
3050 sleep_time = 0;
3051 }
3052 out->last_write_time_us = now + sleep_time;
3053 // last_write_time_us is an approximation of when the (simulated) alsa
3054 // buffer is believed completely full. The usleep above waits for more space
3055 // in the buffer, but by the end of the sleep the buffer is considered
3056 // topped-off.
3057 //
3058 // On the subsequent out_write(), we measure the elapsed time spent in
3059 // the mixer. This is subtracted from the sleep estimate based on frames,
3060 // thereby accounting for drain in the alsa buffer during mixing.
3061 // This is a crude approximation; we don't handle underruns precisely.
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003062 }
3063
3064#ifdef PREPROCESSING_ENABLED
3065 if (in) {
3066 /* The lock on adev->lock_inputs prevents input stream from being closed */
3067 lock_input_stream(in);
3068 pthread_mutex_lock(&adev->lock);
3069 LOG_ALWAYS_FATAL_IF(in != adev->active_input);
3070 do_in_standby_l(in);
3071 pthread_mutex_unlock(&adev->lock);
3072 pthread_mutex_unlock(&in->lock);
3073 /* This mutex was left locked iff in != NULL */
3074 pthread_mutex_unlock(&adev->lock_inputs);
3075 }
3076#endif
3077
3078 return bytes;
3079}
3080
3081static int out_get_render_position(const struct audio_stream_out *stream,
3082 uint32_t *dsp_frames)
3083{
3084 struct stream_out *out = (struct stream_out *)stream;
3085 *dsp_frames = 0;
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003086 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
3087 return out_get_render_offload_position(out, dsp_frames);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003088 } else
3089 return -EINVAL;
3090}
3091
3092static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3093{
3094 (void)stream;
3095 (void)effect;
3096 return 0;
3097}
3098
3099static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
3100{
3101 (void)stream;
3102 (void)effect;
3103 return 0;
3104}
3105
3106static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
3107 int64_t *timestamp)
3108{
3109 (void)stream;
3110 (void)timestamp;
3111 return -EINVAL;
3112}
3113
3114static int out_get_presentation_position(const struct audio_stream_out *stream,
3115 uint64_t *frames, struct timespec *timestamp)
3116{
3117 struct stream_out *out = (struct stream_out *)stream;
Victor Lourme5869cd32018-03-26 19:36:07 +02003118 int ret = -EINVAL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003119
3120 lock_output_stream(out);
3121
3122 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003123 ret = out_get_presentation_offload_position(out, frames, timestamp);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003124 } else {
Andreas Schneider97fa7f12017-02-11 14:21:56 +01003125 if (out->dev->voice.in_call) {
3126 ALOGVV("%s: in_call, do not handle PCMs", __func__);
3127 ret = 0;
3128 goto done;
3129 }
3130
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003131 /* FIXME: which device to read from? */
3132 if (!list_empty(&out->pcm_dev_list)) {
Andreas Schneiderd6359182017-02-08 16:58:22 +01003133 struct pcm_device *pcm_device;
3134 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003135 unsigned int avail;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003136
Andreas Schneiderd6359182017-02-08 16:58:22 +01003137 list_for_each(node, &out->pcm_dev_list) {
3138 pcm_device = node_to_item(node,
3139 struct pcm_device,
3140 stream_list_node);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003141
Andreas Schneiderd6359182017-02-08 16:58:22 +01003142 if (pcm_device->pcm != NULL) {
3143 if (pcm_get_htimestamp(pcm_device->pcm, &avail, timestamp) == 0) {
3144 size_t kernel_buffer_size = out->config.period_size * out->config.period_count;
3145 int64_t signed_frames = out->written - kernel_buffer_size + avail;
3146 /* This adjustment accounts for buffering after app processor.
3147 It is based on estimated DSP latency per use case, rather than exact. */
3148 signed_frames -=
3149 (render_latency(out->usecase) * out->sample_rate / 1000000LL);
3150
3151 /* It would be unusual for this value to be negative, but check just in case ... */
3152 if (signed_frames >= 0) {
3153 *frames = signed_frames;
3154 ret = 0;
3155 goto done;
3156 }
Andreas Schneiderd6359182017-02-08 16:58:22 +01003157 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003158 }
3159 }
3160 }
3161 }
3162
Andreas Schneiderd6359182017-02-08 16:58:22 +01003163done:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003164 pthread_mutex_unlock(&out->lock);
3165
3166 return ret;
3167}
3168
3169static int out_set_callback(struct audio_stream_out *stream,
3170 stream_callback_t callback, void *cookie)
3171{
3172 struct stream_out *out = (struct stream_out *)stream;
3173
3174 ALOGV("%s", __func__);
3175 lock_output_stream(out);
3176 out->offload_callback = callback;
3177 out->offload_cookie = cookie;
3178 pthread_mutex_unlock(&out->lock);
3179 return 0;
3180}
3181
3182static int out_pause(struct audio_stream_out* stream)
3183{
3184 struct stream_out *out = (struct stream_out *)stream;
3185 int status = -ENOSYS;
3186 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003187 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3188 status = out_pause_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003189 return status;
3190}
3191
3192static int out_resume(struct audio_stream_out* stream)
3193{
3194 struct stream_out *out = (struct stream_out *)stream;
3195 int status = -ENOSYS;
3196 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003197 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3198 status = out_resume_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003199 return status;
3200}
3201
3202static int out_drain(struct audio_stream_out* stream, audio_drain_type_t type )
3203{
3204 struct stream_out *out = (struct stream_out *)stream;
3205 int status = -ENOSYS;
3206 ALOGV("%s", __func__);
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003207 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD)
3208 status = out_drain_offload(out, type);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003209 return status;
3210}
3211
3212static int out_flush(struct audio_stream_out* stream)
3213{
3214 struct stream_out *out = (struct stream_out *)stream;
3215 ALOGV("%s", __func__);
3216 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
Christopher N. Hesse757ac412017-01-28 14:42:48 +01003217 return out_flush_offload(out);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003218 }
3219 return -ENOSYS;
3220}
3221
3222/** audio_stream_in implementation **/
3223static uint32_t in_get_sample_rate(const struct audio_stream *stream)
3224{
3225 struct stream_in *in = (struct stream_in *)stream;
3226
3227 return in->requested_rate;
3228}
3229
3230static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
3231{
3232 (void)stream;
3233 (void)rate;
3234 return -ENOSYS;
3235}
3236
3237static uint32_t in_get_channels(const struct audio_stream *stream)
3238{
3239 struct stream_in *in = (struct stream_in *)stream;
3240
3241 return in->main_channels;
3242}
3243
3244static audio_format_t in_get_format(const struct audio_stream *stream)
3245{
3246 (void)stream;
3247 return AUDIO_FORMAT_PCM_16_BIT;
3248}
3249
3250static int in_set_format(struct audio_stream *stream, audio_format_t format)
3251{
3252 (void)stream;
3253 (void)format;
3254
3255 return -ENOSYS;
3256}
3257
3258static size_t in_get_buffer_size(const struct audio_stream *stream)
3259{
3260 struct stream_in *in = (struct stream_in *)stream;
3261
3262 return get_input_buffer_size(in->requested_rate,
3263 in_get_format(stream),
3264 audio_channel_count_from_in_mask(in->main_channels),
3265 in->usecase_type,
3266 in->devices);
3267}
3268
3269static int in_close_pcm_devices(struct stream_in *in)
3270{
3271 struct pcm_device *pcm_device;
3272 struct listnode *node;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003273
3274 list_for_each(node, &in->pcm_dev_list) {
3275 pcm_device = node_to_item(node, struct pcm_device, stream_list_node);
3276 if (pcm_device) {
3277 if (pcm_device->pcm)
3278 pcm_close(pcm_device->pcm);
3279 pcm_device->pcm = NULL;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003280 }
3281 }
3282 return 0;
3283}
3284
3285
3286/* must be called with stream and hw device mutex locked */
3287static int do_in_standby_l(struct stream_in *in)
3288{
3289 int status = 0;
3290
3291#ifdef PREPROCESSING_ENABLED
3292 struct audio_device *adev = in->dev;
3293#endif
3294 if (!in->standby) {
3295
3296 in_close_pcm_devices(in);
3297
3298#ifdef PREPROCESSING_ENABLED
3299 if (in->echo_reference != NULL) {
3300 /* stop reading from echo reference */
3301 in->echo_reference->read(in->echo_reference, NULL);
3302 put_echo_reference(adev, in->echo_reference);
3303 in->echo_reference = NULL;
3304 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003305#endif // PREPROCESSING_ENABLED
3306
3307 status = stop_input_stream(in);
3308
3309 if (in->read_buf) {
3310 free(in->read_buf);
3311 in->read_buf = NULL;
3312 }
3313
3314 in->standby = 1;
3315 }
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003316
3317 in->last_read_time_us = 0;
3318
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003319 return 0;
3320}
3321
3322// called with adev->lock_inputs locked
3323static int in_standby_l(struct stream_in *in)
3324{
3325 struct audio_device *adev = in->dev;
3326 int status = 0;
3327 lock_input_stream(in);
3328 if (!in->standby) {
3329 pthread_mutex_lock(&adev->lock);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003330 amplifier_input_stream_standby((struct audio_stream_in *) in);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003331 status = do_in_standby_l(in);
3332 pthread_mutex_unlock(&adev->lock);
3333 }
3334 pthread_mutex_unlock(&in->lock);
3335 return status;
3336}
3337
3338static int in_standby(struct audio_stream *stream)
3339{
3340 struct stream_in *in = (struct stream_in *)stream;
3341 struct audio_device *adev = in->dev;
3342 int status;
3343 ALOGV("%s: enter", __func__);
3344 pthread_mutex_lock(&adev->lock_inputs);
3345 status = in_standby_l(in);
3346 pthread_mutex_unlock(&adev->lock_inputs);
3347 ALOGV("%s: exit: status(%d)", __func__, status);
3348 return status;
3349}
3350
3351static int in_dump(const struct audio_stream *stream, int fd)
3352{
3353 (void)stream;
3354 (void)fd;
3355
3356 return 0;
3357}
3358
3359static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
3360{
3361 struct stream_in *in = (struct stream_in *)stream;
3362 struct audio_device *adev = in->dev;
3363 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003364 char value[32];
3365 int ret, val = 0;
3366 struct audio_usecase *uc_info;
3367 bool do_standby = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003368 struct pcm_device *pcm_device;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003369
3370 ALOGV("%s: enter: kvpairs=%s", __func__, kvpairs);
3371 parms = str_parms_create_str(kvpairs);
3372
3373 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
3374
3375 pthread_mutex_lock(&adev->lock_inputs);
3376 lock_input_stream(in);
3377 pthread_mutex_lock(&adev->lock);
3378 if (ret >= 0) {
3379 val = atoi(value);
3380 /* no audio source uses val == 0 */
3381 if (((int)in->source != val) && (val != 0)) {
3382 in->source = val;
3383 }
3384 }
3385
3386 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
3387 if (ret >= 0) {
3388 val = atoi(value);
3389 if (((int)in->devices != val) && (val != 0)) {
3390 in->devices = val;
3391 /* If recording is in progress, change the tx device to new device */
3392 if (!in->standby) {
3393 uc_info = get_usecase_from_id(adev, in->usecase);
3394 if (uc_info == NULL) {
3395 ALOGE("%s: Could not find the usecase (%d) in the list",
3396 __func__, in->usecase);
3397 } else {
3398 if (list_empty(&in->pcm_dev_list))
3399 ALOGE("%s: pcm device list empty", __func__);
3400 else {
3401 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3402 struct pcm_device, stream_list_node);
3403 if ((pcm_device->pcm_profile->devices & val & ~AUDIO_DEVICE_BIT_IN) == 0) {
3404 do_standby = true;
3405 }
3406 }
3407 }
3408 if (do_standby) {
3409 ret = do_in_standby_l(in);
3410 } else
3411 ret = select_devices(adev, in->usecase);
3412 }
3413 }
3414 }
3415 pthread_mutex_unlock(&adev->lock);
3416 pthread_mutex_unlock(&in->lock);
3417 pthread_mutex_unlock(&adev->lock_inputs);
3418 str_parms_destroy(parms);
3419
3420 if (ret > 0)
3421 ret = 0;
3422
3423 ALOGV("%s: exit: status(%d)", __func__, ret);
3424 return ret;
3425}
3426
3427static char* in_get_parameters(const struct audio_stream *stream,
3428 const char *keys)
3429{
3430 (void)stream;
3431 (void)keys;
3432
3433 return strdup("");
3434}
3435
3436static int in_set_gain(struct audio_stream_in *stream, float gain)
3437{
3438 (void)stream;
3439 (void)gain;
3440
3441 return 0;
3442}
3443
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003444static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
3445 size_t bytes)
3446{
3447 struct stream_in *in = (struct stream_in *)stream;
3448 struct audio_device *adev = in->dev;
3449 ssize_t frames = -1;
3450 int ret = -1;
3451 int read_and_process_successful = false;
3452
3453 size_t frames_rq = bytes / audio_stream_in_frame_size(stream);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003454
3455 /* no need to acquire adev->lock_inputs because API contract prevents a close */
3456 lock_input_stream(in);
3457
Andreas Schneider3b643832017-01-31 11:48:22 +01003458#if SUPPORTS_IRQ_AFFINITY
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003459 if (in->usecase == USECASE_AUDIO_CAPTURE && !in->is_fastcapture_affinity_set) {
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003460 pid_t tid = gettid();
3461 int err;
3462
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003463 err = fast_set_affinity(tid);
3464 if (err < 0) {
3465 ALOGW("Couldn't set affinity for tid %d; error %d", tid, err);
3466 }
3467 in->is_fastcapture_affinity_set = true;
3468 }
Andreas Schneider3b643832017-01-31 11:48:22 +01003469#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003470
3471 if (in->standby) {
3472 pthread_mutex_unlock(&in->lock);
3473 pthread_mutex_lock(&adev->lock_inputs);
3474 lock_input_stream(in);
3475 if (!in->standby) {
3476 pthread_mutex_unlock(&adev->lock_inputs);
3477 goto false_alarm;
3478 }
3479 pthread_mutex_lock(&adev->lock);
3480 ret = start_input_stream(in);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003481 if (ret == 0) {
3482 amplifier_input_stream_start(stream);
3483 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003484 pthread_mutex_unlock(&adev->lock);
3485 pthread_mutex_unlock(&adev->lock_inputs);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02003486
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003487 if (ret != 0) {
3488 goto exit;
3489 }
3490 in->standby = 0;
3491 }
3492false_alarm:
3493
3494 if (!list_empty(&in->pcm_dev_list)) {
stenkinevgeniy44335362018-05-07 18:00:13 +00003495 /*
3496 * Read PCM and:
3497 * - resample if needed
3498 * - process if pre-processors are attached
3499 * - discard unwanted channels
3500 */
3501 frames = read_and_process_frames(in, buffer, frames_rq);
3502 if (frames >= 0)
3503 read_and_process_successful = true;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003504 }
3505
3506 /*
3507 * Instead of writing zeroes here, we could trust the hardware
3508 * to always provide zeroes when muted.
3509 */
3510 if (read_and_process_successful == true && adev->mic_mute)
3511 memset(buffer, 0, bytes);
3512
3513exit:
3514 pthread_mutex_unlock(&in->lock);
3515
3516 if (read_and_process_successful == false) {
3517 in_standby(&in->stream.common);
3518 ALOGV("%s: read failed - sleeping for buffer duration", __func__);
Christopher N. Hessee6b3a3e2017-01-08 00:03:23 +01003519 struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
3520 clock_gettime(CLOCK_MONOTONIC, &t);
3521 const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
3522
3523 // we do a full sleep when exiting standby.
3524 const bool standby = in->last_read_time_us == 0;
3525 const int64_t elapsed_time_since_last_read = standby ?
3526 0 : now - in->last_read_time_us;
3527 int64_t sleep_time = bytes * 1000000LL / audio_stream_in_frame_size(stream) /
3528 in_get_sample_rate(&stream->common) - elapsed_time_since_last_read;
3529 if (sleep_time > 0) {
3530 usleep(sleep_time);
3531 } else {
3532 sleep_time = 0;
3533 }
3534 in->last_read_time_us = now + sleep_time;
3535 // last_read_time_us is an approximation of when the (simulated) alsa
3536 // buffer is drained by the read, and is empty.
3537 //
3538 // On the subsequent in_read(), we measure the elapsed time spent in
3539 // the recording thread. This is subtracted from the sleep estimate based on frames,
3540 // thereby accounting for fill in the alsa buffer during the interim.
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003541 memset(buffer, 0, bytes);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003542 }
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003543
3544 if (bytes > 0) {
3545 in->frames_read += bytes / audio_stream_in_frame_size(stream);
3546 }
3547
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003548 return bytes;
3549}
3550
3551static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
3552{
3553 (void)stream;
3554
3555 return 0;
3556}
3557
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01003558static int in_get_capture_position(const struct audio_stream_in *stream,
3559 int64_t *frames, int64_t *time)
3560{
3561 if (stream == NULL || frames == NULL || time == NULL) {
3562 return -EINVAL;
3563 }
3564
3565 struct stream_in *in = (struct stream_in *)stream;
3566 struct pcm_device *pcm_device;
3567 int ret = -ENOSYS;
3568
3569 pcm_device = node_to_item(list_head(&in->pcm_dev_list),
3570 struct pcm_device, stream_list_node);
3571
3572 pthread_mutex_lock(&in->lock);
3573 if (pcm_device->pcm) {
3574 struct timespec timestamp;
3575 unsigned int avail;
3576 if (pcm_get_htimestamp(pcm_device->pcm, &avail, &timestamp) == 0) {
3577 *frames = in->frames_read + avail;
3578 *time = timestamp.tv_sec * 1000000000LL + timestamp.tv_nsec;
3579 ret = 0;
3580 }
3581 }
3582
3583 pthread_mutex_unlock(&in->lock);
3584 return ret;
3585}
3586
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003587static int add_remove_audio_effect(const struct audio_stream *stream,
3588 effect_handle_t effect,
3589 bool enable)
3590{
3591 struct stream_in *in = (struct stream_in *)stream;
3592 struct audio_device *adev = in->dev;
3593 int status = 0;
3594 effect_descriptor_t desc;
3595#ifdef PREPROCESSING_ENABLED
3596 int i;
3597#endif
3598 status = (*effect)->get_descriptor(effect, &desc);
3599 if (status != 0)
3600 return status;
3601
3602 ALOGI("add_remove_audio_effect(), effect type: %08x, enable: %d ", desc.type.timeLow, enable);
3603
3604 pthread_mutex_lock(&adev->lock_inputs);
3605 lock_input_stream(in);
3606 pthread_mutex_lock(&in->dev->lock);
3607#ifndef PREPROCESSING_ENABLED
3608 if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) &&
3609 in->enable_aec != enable &&
3610 (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0)) {
3611 in->enable_aec = enable;
3612 if (!in->standby)
3613 select_devices(in->dev, in->usecase);
3614 }
3615#else
3616 if ( (in->num_preprocessors > MAX_PREPROCESSORS) && (enable == true) ) {
3617 status = -ENOSYS;
3618 goto exit;
3619 }
3620 if ( enable == true ) {
3621 in->preprocessors[in->num_preprocessors].effect_itfe = effect;
3622 /* add the supported channel of the effect in the channel_configs */
3623 in_read_audio_effect_channel_configs(in, &in->preprocessors[in->num_preprocessors]);
3624 in->num_preprocessors ++;
3625 /* check compatibility between main channel supported and possible auxiliary channels */
3626 in_update_aux_channels(in, effect);//wesley crash
3627 in->aux_channels_changed = true;
3628 } else {
3629 /* if ( enable == false ) */
3630 if (in->num_preprocessors <= 0) {
3631 status = -ENOSYS;
3632 goto exit;
3633 }
3634 status = -EINVAL;
3635 for (i=0; i < in->num_preprocessors; i++) {
3636 if (status == 0) { /* status == 0 means an effect was removed from a previous slot */
3637 in->preprocessors[i - 1].effect_itfe = in->preprocessors[i].effect_itfe;
3638 in->preprocessors[i - 1].channel_configs = in->preprocessors[i].channel_configs;
3639 in->preprocessors[i - 1].num_channel_configs =
3640 in->preprocessors[i].num_channel_configs;
3641 ALOGV("add_remove_audio_effect moving fx from %d to %d", i, i-1);
3642 continue;
3643 }
3644 if ( in->preprocessors[i].effect_itfe == effect ) {
3645 ALOGV("add_remove_audio_effect found fx at index %d", i);
3646 free(in->preprocessors[i].channel_configs);
3647 status = 0;
3648 }
3649 }
3650 if (status != 0)
3651 goto exit;
3652 in->num_preprocessors--;
3653 /* if we remove one effect, at least the last proproc should be reset */
3654 in->preprocessors[in->num_preprocessors].num_channel_configs = 0;
3655 in->preprocessors[in->num_preprocessors].effect_itfe = NULL;
3656 in->preprocessors[in->num_preprocessors].channel_configs = NULL;
3657 in->aux_channels_changed = false;
3658 ALOGV("%s: enable(%d), in->aux_channels_changed(%d)", __func__, enable, in->aux_channels_changed);
3659 }
3660 ALOGI("%s: num_preprocessors = %d", __func__, in->num_preprocessors);
3661
3662 if ( memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
3663 in->enable_aec = enable;
3664 ALOGV("add_remove_audio_effect(), FX_IID_AEC, enable: %d", enable);
3665 if (!in->standby) {
3666 select_devices(in->dev, in->usecase);
3667 do_in_standby_l(in);
3668 }
3669 if (in->enable_aec == true) {
3670 in_configure_reverse(in);
3671 }
3672 }
3673exit:
3674#endif
3675 ALOGW_IF(status != 0, "add_remove_audio_effect() error %d", status);
3676 pthread_mutex_unlock(&in->dev->lock);
3677 pthread_mutex_unlock(&in->lock);
3678 pthread_mutex_unlock(&adev->lock_inputs);
3679 return status;
3680}
3681
3682static int in_add_audio_effect(const struct audio_stream *stream,
3683 effect_handle_t effect)
3684{
3685 ALOGV("%s: effect %p", __func__, effect);
3686 return add_remove_audio_effect(stream, effect, true);
3687}
3688
3689static int in_remove_audio_effect(const struct audio_stream *stream,
3690 effect_handle_t effect)
3691{
3692 ALOGV("%s: effect %p", __func__, effect);
3693 return add_remove_audio_effect(stream, effect, false);
3694}
3695
3696static int adev_open_output_stream(struct audio_hw_device *dev,
3697 audio_io_handle_t handle,
3698 audio_devices_t devices,
3699 audio_output_flags_t flags,
3700 struct audio_config *config,
3701 struct audio_stream_out **stream_out,
3702 const char *address __unused)
3703{
3704 struct audio_device *adev = (struct audio_device *)dev;
3705 struct stream_out *out;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003706 int ret = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003707 struct pcm_device_profile *pcm_profile;
3708
3709 ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
3710 __func__, config->sample_rate, config->channel_mask, devices, flags);
3711 *stream_out = NULL;
3712 out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
Andreas Schneider56204f62017-01-31 08:17:32 +01003713 if (out == NULL) {
3714 ret = -ENOMEM;
3715 goto error_config;
3716 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003717
3718 if (devices == AUDIO_DEVICE_NONE)
3719 devices = AUDIO_DEVICE_OUT_SPEAKER;
3720
3721 out->flags = flags;
3722 out->devices = devices;
3723 out->dev = adev;
3724 out->format = config->format;
3725 out->sample_rate = config->sample_rate;
3726 out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
3727 out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
3728 out->handle = handle;
3729
3730 pcm_profile = get_pcm_device(PCM_PLAYBACK, devices);
3731 if (pcm_profile == NULL) {
3732 ret = -EINVAL;
3733 goto error_open;
3734 }
3735 out->config = pcm_profile->config;
3736
3737 /* Init use case and pcm_config */
3738 if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
3739 if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version ||
3740 config->offload_info.size != AUDIO_INFO_INITIALIZER.size) {
3741 ALOGE("%s: Unsupported Offload information", __func__);
3742 ret = -EINVAL;
3743 goto error_open;
3744 }
3745 if (!is_supported_format(config->offload_info.format)) {
3746 ALOGE("%s: Unsupported audio format", __func__);
3747 ret = -EINVAL;
3748 goto error_open;
3749 }
3750
3751 out->compr_config.codec = (struct snd_codec *)
3752 calloc(1, sizeof(struct snd_codec));
Andreas Schneider56204f62017-01-31 08:17:32 +01003753 if (out->compr_config.codec == NULL) {
3754 ret = -ENOMEM;
3755 goto error_open;
3756 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003757
3758 out->usecase = USECASE_AUDIO_PLAYBACK_OFFLOAD;
3759 if (config->offload_info.channel_mask)
3760 out->channel_mask = config->offload_info.channel_mask;
3761 else if (config->channel_mask)
3762 out->channel_mask = config->channel_mask;
3763 out->format = config->offload_info.format;
3764 out->sample_rate = config->offload_info.sample_rate;
3765
3766 out->stream.set_callback = out_set_callback;
3767 out->stream.pause = out_pause;
3768 out->stream.resume = out_resume;
3769 out->stream.drain = out_drain;
3770 out->stream.flush = out_flush;
3771
3772 out->compr_config.codec->id =
3773 get_snd_codec_id(config->offload_info.format);
3774 out->compr_config.fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
3775 out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
3776 out->compr_config.codec->sample_rate = config->offload_info.sample_rate;
3777 out->compr_config.codec->bit_rate =
3778 config->offload_info.bit_rate;
3779 out->compr_config.codec->ch_in =
3780 audio_channel_count_from_out_mask(config->channel_mask);
3781 out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
3782
3783 if (flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING)
3784 out->non_blocking = 1;
3785
3786 out->send_new_metadata = 1;
3787 create_offload_callback_thread(out);
3788 out->offload_state = OFFLOAD_STATE_IDLE;
3789
3790 ALOGV("%s: offloaded output offload_info version %04x bit rate %d",
3791 __func__, config->offload_info.version,
3792 config->offload_info.bit_rate);
3793 } else if (out->flags & (AUDIO_OUTPUT_FLAG_DEEP_BUFFER)) {
3794 out->usecase = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
Christopher N. Hesse8414bd22017-01-30 18:57:20 +01003795 out->config = pcm_device_deep_buffer.config;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003796 out->sample_rate = out->config.rate;
3797 ALOGV("%s: use AUDIO_PLAYBACK_DEEP_BUFFER",__func__);
3798 } else {
3799 out->usecase = USECASE_AUDIO_PLAYBACK;
3800 out->sample_rate = out->config.rate;
3801 }
3802
3803 if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
3804 if (adev->primary_output == NULL)
3805 adev->primary_output = out;
3806 else {
3807 ALOGE("%s: Primary output is already opened", __func__);
3808 ret = -EEXIST;
3809 goto error_open;
3810 }
3811 }
3812
3813 /* Check if this usecase is already existing */
3814 pthread_mutex_lock(&adev->lock);
3815 if (get_usecase_from_id(adev, out->usecase) != NULL) {
3816 ALOGE("%s: Usecase (%d) is already present", __func__, out->usecase);
3817 pthread_mutex_unlock(&adev->lock);
3818 ret = -EEXIST;
3819 goto error_open;
3820 }
3821 pthread_mutex_unlock(&adev->lock);
3822
3823 out->stream.common.get_sample_rate = out_get_sample_rate;
3824 out->stream.common.set_sample_rate = out_set_sample_rate;
3825 out->stream.common.get_buffer_size = out_get_buffer_size;
3826 out->stream.common.get_channels = out_get_channels;
3827 out->stream.common.get_format = out_get_format;
3828 out->stream.common.set_format = out_set_format;
3829 out->stream.common.standby = out_standby;
3830 out->stream.common.dump = out_dump;
3831 out->stream.common.set_parameters = out_set_parameters;
3832 out->stream.common.get_parameters = out_get_parameters;
3833 out->stream.common.add_audio_effect = out_add_audio_effect;
3834 out->stream.common.remove_audio_effect = out_remove_audio_effect;
3835 out->stream.get_latency = out_get_latency;
3836 out->stream.set_volume = out_set_volume;
3837 out->stream.write = out_write;
3838 out->stream.get_render_position = out_get_render_position;
3839 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
3840 out->stream.get_presentation_position = out_get_presentation_position;
3841
3842 out->standby = 1;
3843 /* out->muted = false; by calloc() */
3844 /* out->written = 0; by calloc() */
3845
3846 pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
3847 pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
3848 pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
3849
3850 config->format = out->stream.common.get_format(&out->stream.common);
3851 config->channel_mask = out->stream.common.get_channels(&out->stream.common);
3852 config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
3853
3854 out->is_fastmixer_affinity_set = false;
3855
3856 *stream_out = &out->stream;
3857 ALOGV("%s: exit", __func__);
3858 return 0;
3859
3860error_open:
3861 free(out);
3862 *stream_out = NULL;
Andreas Schneider56204f62017-01-31 08:17:32 +01003863error_config:
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003864 ALOGV("%s: exit: ret %d", __func__, ret);
3865 return ret;
3866}
3867
3868static void adev_close_output_stream(struct audio_hw_device *dev,
3869 struct audio_stream_out *stream)
3870{
3871 struct stream_out *out = (struct stream_out *)stream;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003872 (void)dev;
3873
3874 ALOGV("%s: enter", __func__);
3875 out_standby(&stream->common);
3876 if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
3877 destroy_offload_callback_thread(out);
3878
3879 if (out->compr_config.codec != NULL)
3880 free(out->compr_config.codec);
3881 }
3882 pthread_cond_destroy(&out->cond);
3883 pthread_mutex_destroy(&out->lock);
3884 free(stream);
3885 ALOGV("%s: exit", __func__);
3886}
3887
3888static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
3889{
3890 struct audio_device *adev = (struct audio_device *)dev;
3891 struct str_parms *parms;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003892 char value[32];
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003893#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003894 int val;
Andreas Schneider5a2f1002017-02-09 10:59:04 +01003895#endif
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003896 int ret;
3897
3898 ALOGV("%s: enter: %s", __func__, kvpairs);
3899
3900 parms = str_parms_create_str(kvpairs);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003901
Andreas Schneider05bc1882017-02-09 14:03:11 +01003902 /******************************************************
3903 *** BT SCO
3904 ******************************************************/
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003905 ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
3906 if (ret >= 0) {
3907 /* When set to false, HAL should disable EC and NS
3908 * But it is currently not supported.
3909 */
3910 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
Andreas Schneider74ef3a12017-02-02 18:29:12 +01003911 adev->voice.bluetooth_nrec = true;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003912 else
Andreas Schneider74ef3a12017-02-02 18:29:12 +01003913 adev->voice.bluetooth_nrec = false;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003914 }
3915
Andreas Schneider05bc1882017-02-09 14:03:11 +01003916 ret = str_parms_get_str(parms,
3917 AUDIO_PARAMETER_KEY_BT_SCO_WB,
3918 value,
3919 sizeof(value));
3920 if (ret >= 0) {
Andreas Schneider05bc1882017-02-09 14:03:11 +01003921 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0) {
3922 adev->voice.bluetooth_wb = true;
Andreas Schneider05bc1882017-02-09 14:03:11 +01003923 } else {
3924 adev->voice.bluetooth_wb = false;
3925 }
3926 }
3927
Andreas Schneiderecd17ce2017-02-09 10:45:21 +01003928 ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
3929 if (ret >= 0) {
3930 if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
3931 adev->screen_off = false;
3932 else
3933 adev->screen_off = true;
3934 }
3935
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01003936#if SWAP_SPEAKER_ON_SCREEN_ROTATION
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003937 ret = str_parms_get_int(parms, "rotation", &val);
3938 if (ret >= 0) {
3939 bool reverse_speakers = false;
3940 switch(val) {
3941 /* FIXME: note that the code below assumes that the speakers are in the correct placement
3942 relative to the user when the device is rotated 90deg from its default rotation. This
3943 assumption is device-specific, not platform-specific like this code. */
3944 case 270:
3945 reverse_speakers = true;
3946 break;
3947 case 0:
3948 case 90:
3949 case 180:
3950 break;
3951 default:
3952 ALOGE("%s: unexpected rotation of %d", __func__, val);
3953 }
3954 pthread_mutex_lock(&adev->lock);
3955 if (adev->speaker_lr_swap != reverse_speakers) {
3956 adev->speaker_lr_swap = reverse_speakers;
3957 /* only update the selected device if there is active pcm playback */
3958 struct audio_usecase *usecase;
3959 struct listnode *node;
3960 list_for_each(node, &adev->usecase_list) {
3961 usecase = node_to_item(node, struct audio_usecase, adev_list_node);
3962 if (usecase->type == PCM_PLAYBACK) {
3963 select_devices(adev, usecase->id);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003964 break;
3965 }
3966 }
3967 }
3968 pthread_mutex_unlock(&adev->lock);
3969 }
Andreas Schneiderdc15cec2017-01-30 22:36:25 +01003970#endif /* SWAP_SPEAKER_ON_SCREEN_ROTATION */
Christopher N. Hesse297a6362017-01-28 12:40:45 +01003971
3972 str_parms_destroy(parms);
3973
3974 if (ret > 0)
3975 ret = 0;
3976
3977 ALOGV("%s: exit with code(%d)", __func__, ret);
3978 return ret;
3979}
3980
3981static char* adev_get_parameters(const struct audio_hw_device *dev,
3982 const char *keys)
3983{
3984 (void)dev;
3985 (void)keys;
3986
3987 return strdup("");
3988}
3989
3990static int adev_init_check(const struct audio_hw_device *dev)
3991{
3992 (void)dev;
3993
3994 return 0;
3995}
3996
3997static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
3998{
3999 int ret = 0;
4000 struct audio_device *adev = (struct audio_device *)dev;
4001 pthread_mutex_lock(&adev->lock);
4002 /* cache volume */
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004003 adev->voice.volume = volume;
4004 ret = set_voice_volume_l(adev, adev->voice.volume);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004005 pthread_mutex_unlock(&adev->lock);
4006 return ret;
4007}
4008
4009static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
4010{
4011 (void)dev;
4012 (void)volume;
4013
4014 return -ENOSYS;
4015}
4016
4017static int adev_get_master_volume(struct audio_hw_device *dev,
4018 float *volume)
4019{
4020 (void)dev;
4021 (void)volume;
4022
4023 return -ENOSYS;
4024}
4025
4026static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
4027{
4028 (void)dev;
4029 (void)muted;
4030
4031 return -ENOSYS;
4032}
4033
4034static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
4035{
4036 (void)dev;
4037 (void)muted;
4038
4039 return -ENOSYS;
4040}
4041
4042static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
4043{
4044 struct audio_device *adev = (struct audio_device *)dev;
4045
4046 pthread_mutex_lock(&adev->lock);
4047 if (adev->mode != mode) {
4048 ALOGI("%s mode = %d", __func__, mode);
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004049 if (amplifier_set_mode(mode) != 0) {
4050 ALOGE("Failed setting amplifier mode");
4051 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004052 adev->mode = mode;
Christopher N. Hesse6c0020c2017-11-17 20:41:11 +01004053
4054 if ((mode == AUDIO_MODE_NORMAL) && adev->voice.in_call) {
4055 stop_voice_call(adev);
4056 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004057 }
4058 pthread_mutex_unlock(&adev->lock);
4059 return 0;
4060}
4061
4062static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
4063{
4064 struct audio_device *adev = (struct audio_device *)dev;
4065 int err = 0;
4066
4067 pthread_mutex_lock(&adev->lock);
4068 adev->mic_mute = state;
4069
4070 if (adev->mode == AUDIO_MODE_IN_CALL) {
Andreas Schneider107a8482017-02-06 12:36:31 +01004071 set_voice_session_mic_mute(adev->voice.session, state);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004072 }
4073
4074 pthread_mutex_unlock(&adev->lock);
4075 return err;
4076}
4077
4078static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
4079{
4080 struct audio_device *adev = (struct audio_device *)dev;
4081
4082 *state = adev->mic_mute;
4083
4084 return 0;
4085}
4086
4087static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
4088 const struct audio_config *config)
4089{
4090 (void)dev;
4091
4092 /* NOTE: we default to built in mic which may cause a mismatch between what we
4093 * report here and the actual buffer size
4094 */
4095 return get_input_buffer_size(config->sample_rate,
4096 config->format,
4097 audio_channel_count_from_in_mask(config->channel_mask),
4098 PCM_CAPTURE /* usecase_type */,
4099 AUDIO_DEVICE_IN_BUILTIN_MIC);
4100}
4101
4102static int adev_open_input_stream(struct audio_hw_device *dev,
4103 audio_io_handle_t handle __unused,
4104 audio_devices_t devices,
4105 struct audio_config *config,
4106 struct audio_stream_in **stream_in,
4107 audio_input_flags_t flags,
4108 const char *address __unused,
4109 audio_source_t source)
4110{
4111 struct audio_device *adev = (struct audio_device *)dev;
4112 struct stream_in *in;
4113 struct pcm_device_profile *pcm_profile;
4114
4115 ALOGV("%s: enter", __func__);
4116
4117 *stream_in = NULL;
4118 if (check_input_parameters(config->sample_rate, config->format,
4119 audio_channel_count_from_in_mask(config->channel_mask)) != 0)
4120 return -EINVAL;
4121
stenkinevgeniy44335362018-05-07 18:00:13 +00004122 usecase_type_t usecase_type = flags & AUDIO_INPUT_FLAG_FAST ?
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004123 PCM_CAPTURE_LOW_LATENCY : PCM_CAPTURE;
4124 pcm_profile = get_pcm_device(usecase_type, devices);
4125 if (pcm_profile == NULL && usecase_type == PCM_CAPTURE_LOW_LATENCY) {
4126 // a low latency profile may not exist for that device, fall back
4127 // to regular capture. the MixerThread automatically changes
4128 // to non-fast capture based on the buffer size.
4129 flags &= ~AUDIO_INPUT_FLAG_FAST;
4130 usecase_type = PCM_CAPTURE;
4131 pcm_profile = get_pcm_device(usecase_type, devices);
4132 }
4133 if (pcm_profile == NULL)
4134 return -EINVAL;
4135
4136 in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
Andreas Schneider56204f62017-01-31 08:17:32 +01004137 if (in == NULL) {
4138 return -ENOMEM;
4139 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004140
4141 in->stream.common.get_sample_rate = in_get_sample_rate;
4142 in->stream.common.set_sample_rate = in_set_sample_rate;
4143 in->stream.common.get_buffer_size = in_get_buffer_size;
4144 in->stream.common.get_channels = in_get_channels;
4145 in->stream.common.get_format = in_get_format;
4146 in->stream.common.set_format = in_set_format;
4147 in->stream.common.standby = in_standby;
4148 in->stream.common.dump = in_dump;
4149 in->stream.common.set_parameters = in_set_parameters;
4150 in->stream.common.get_parameters = in_get_parameters;
4151 in->stream.common.add_audio_effect = in_add_audio_effect;
4152 in->stream.common.remove_audio_effect = in_remove_audio_effect;
4153 in->stream.set_gain = in_set_gain;
4154 in->stream.read = in_read;
4155 in->stream.get_input_frames_lost = in_get_input_frames_lost;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004156 in->stream.get_capture_position = in_get_capture_position;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004157
4158 in->devices = devices;
4159 in->source = source;
4160 in->dev = adev;
4161 in->standby = 1;
4162 in->main_channels = config->channel_mask;
4163 in->requested_rate = config->sample_rate;
4164 if (config->sample_rate != CAPTURE_DEFAULT_SAMPLING_RATE)
4165 flags = flags & ~AUDIO_INPUT_FLAG_FAST;
4166 in->input_flags = flags;
Christopher N. Hessece6d5af2017-01-12 11:40:30 +01004167 // in->frames_read = 0;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004168 /* HW codec is limited to default channels. No need to update with
4169 * requested channels */
4170 in->config = pcm_profile->config;
4171
4172 /* Update config params with the requested sample rate and channels */
stenkinevgeniy44335362018-05-07 18:00:13 +00004173 in->usecase = USECASE_AUDIO_CAPTURE;
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004174 in->usecase_type = usecase_type;
4175
4176 pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
4177 pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL);
4178
4179 in->is_fastcapture_affinity_set = false;
4180
4181 *stream_in = &in->stream;
4182 ALOGV("%s: exit", __func__);
4183 return 0;
4184}
4185
4186static void adev_close_input_stream(struct audio_hw_device *dev,
4187 struct audio_stream_in *stream)
4188{
4189 struct audio_device *adev = (struct audio_device *)dev;
4190 struct stream_in *in = (struct stream_in*)stream;
4191 ALOGV("%s", __func__);
4192
4193 /* prevent concurrent out_set_parameters, or out_write from standby */
4194 pthread_mutex_lock(&adev->lock_inputs);
4195
Andreas Schneidercabe5e62017-01-30 10:57:06 +01004196 if (in->read_buf) {
4197 free(in->read_buf);
4198 in->read_buf = NULL;
4199 }
4200
4201 if (in->resampler) {
4202 release_resampler(in->resampler);
4203 in->resampler = NULL;
4204 }
4205
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004206#ifdef PREPROCESSING_ENABLED
4207 int i;
4208
4209 for (i=0; i<in->num_preprocessors; i++) {
4210 free(in->preprocessors[i].channel_configs);
4211 }
4212
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004213 if (in->proc_buf_in) {
4214 free(in->proc_buf_in);
4215 in->proc_buf_in = NULL;
4216 }
4217
4218 if (in->proc_buf_out) {
4219 free(in->proc_buf_out);
4220 in->proc_buf_out = NULL;
4221 }
4222
4223 if (in->ref_buf) {
4224 free(in->ref_buf);
4225 in->ref_buf = NULL;
4226 }
4227
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004228#endif
4229
4230 in_standby_l(in);
4231 free(stream);
4232
4233 pthread_mutex_unlock(&adev->lock_inputs);
4234
4235 return;
4236}
4237
4238static int adev_dump(const audio_hw_device_t *device, int fd)
4239{
4240 (void)device;
4241 (void)fd;
4242
4243 return 0;
4244}
4245
4246static int adev_close(hw_device_t *device)
4247{
4248 struct audio_device *adev = (struct audio_device *)device;
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004249 voice_session_deinit(adev->voice.session);
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004250 audio_device_ref_count--;
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004251 if (audio_device_ref_count == 0) {
4252 if (amplifier_close() != 0) {
4253 ALOGE("Amplifier close failed");
4254 }
4255 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004256 free(adev->snd_dev_ref_cnt);
4257 free_mixer_list(adev);
4258 free(device);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004259
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004260 adev = NULL;
4261
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004262 return 0;
4263}
4264
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004265/* This returns true if the input parameter looks at all plausible as a low latency period size,
4266 * or false otherwise. A return value of true doesn't mean the value is guaranteed to work,
4267 * just that it _might_ work.
4268 */
4269static bool period_size_is_plausible_for_low_latency(int period_size)
4270{
4271 switch (period_size) {
4272 case 64:
4273 case 96:
4274 case 128:
4275 case 192:
4276 case 256:
4277 return true;
4278 default:
4279 return false;
4280 }
4281}
4282
4283static int adev_open(const hw_module_t *module, const char *name,
4284 hw_device_t **device)
4285{
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004286 ALOGV("%s: enter", __func__);
4287 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
4288
Andreas Schneider56204f62017-01-31 08:17:32 +01004289 *device = NULL;
4290
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004291 adev = calloc(1, sizeof(struct audio_device));
Andreas Schneider56204f62017-01-31 08:17:32 +01004292 if (adev == NULL) {
4293 return -ENOMEM;
4294 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004295
4296 adev->device.common.tag = HARDWARE_DEVICE_TAG;
4297 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
4298 adev->device.common.module = (struct hw_module_t *)module;
4299 adev->device.common.close = adev_close;
4300
4301 adev->device.init_check = adev_init_check;
4302 adev->device.set_voice_volume = adev_set_voice_volume;
4303 adev->device.set_master_volume = adev_set_master_volume;
4304 adev->device.get_master_volume = adev_get_master_volume;
4305 adev->device.set_master_mute = adev_set_master_mute;
4306 adev->device.get_master_mute = adev_get_master_mute;
4307 adev->device.set_mode = adev_set_mode;
4308 adev->device.set_mic_mute = adev_set_mic_mute;
4309 adev->device.get_mic_mute = adev_get_mic_mute;
4310 adev->device.set_parameters = adev_set_parameters;
4311 adev->device.get_parameters = adev_get_parameters;
4312 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
4313 adev->device.open_output_stream = adev_open_output_stream;
4314 adev->device.close_output_stream = adev_close_output_stream;
4315 adev->device.open_input_stream = adev_open_input_stream;
4316 adev->device.close_input_stream = adev_close_input_stream;
4317 adev->device.dump = adev_dump;
4318
4319 /* Set the default route before the PCM stream is opened */
4320 adev->mode = AUDIO_MODE_NORMAL;
4321 adev->active_input = NULL;
4322 adev->primary_output = NULL;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004323
4324 adev->voice.volume = 1.0f;
4325 adev->voice.bluetooth_nrec = true;
4326 adev->voice.in_call = false;
Christopher N. Hessee4a1c592018-01-16 18:33:38 +01004327 adev->voice.bluetooth_wb = false;
Andreas Schneider74ef3a12017-02-02 18:29:12 +01004328
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004329 /* adev->cur_hdmi_channels = 0; by calloc() */
4330 adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
Andreas Schneider56204f62017-01-31 08:17:32 +01004331 if (adev->snd_dev_ref_cnt == NULL) {
4332 free(adev);
4333 return -ENOMEM;
4334 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004335
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004336 adev->ns_in_voice_rec = false;
4337
4338 list_init(&adev->usecase_list);
4339
4340 if (mixer_init(adev) != 0) {
4341 free(adev->snd_dev_ref_cnt);
4342 free(adev);
4343 ALOGE("%s: Failed to init, aborting.", __func__);
4344 *device = NULL;
4345 return -EINVAL;
4346 }
4347
4348 if (access(OFFLOAD_FX_LIBRARY_PATH, R_OK) == 0) {
4349 adev->offload_fx_lib = dlopen(OFFLOAD_FX_LIBRARY_PATH, RTLD_NOW);
4350 if (adev->offload_fx_lib == NULL) {
4351 ALOGE("%s: DLOPEN failed for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4352 } else {
4353 ALOGV("%s: DLOPEN successful for %s", __func__, OFFLOAD_FX_LIBRARY_PATH);
4354 adev->offload_fx_start_output =
4355 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4356 "visualizer_hal_start_output");
4357 adev->offload_fx_stop_output =
4358 (int (*)(audio_io_handle_t))dlsym(adev->offload_fx_lib,
4359 "visualizer_hal_stop_output");
4360 }
4361 }
4362
Christopher N. Hesse696959d2017-02-02 20:49:55 +01004363 adev->voice.session = voice_session_init(adev);
Christopher N. Hesse41c9f3d2017-02-02 20:48:56 +01004364 if (adev->voice.session == NULL) {
4365 ALOGE("%s: Failed to initialize voice session data", __func__);
4366
4367 free(adev->snd_dev_ref_cnt);
4368 free(adev);
4369
4370 *device = NULL;
4371 return -EINVAL;
4372 }
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004373
Christopher N. Hesse6a2a3072017-08-04 21:17:55 +02004374 if (amplifier_open() != 0) {
4375 ALOGE("Amplifier initialization failed");
4376 }
4377
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004378 *device = &adev->device.common;
4379
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004380 audio_device_ref_count++;
4381
4382 char value[PROPERTY_VALUE_MAX];
4383 if (property_get("audio_hal.period_size", value, NULL) > 0) {
4384 int trial = atoi(value);
4385 if (period_size_is_plausible_for_low_latency(trial)) {
4386
4387 pcm_device_playback.config.period_size = trial;
4388 pcm_device_playback.config.start_threshold =
4389 PLAYBACK_START_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4390 pcm_device_playback.config.stop_threshold =
4391 PLAYBACK_STOP_THRESHOLD(trial, PLAYBACK_PERIOD_COUNT);
4392
4393 pcm_device_capture_low_latency.config.period_size = trial;
4394 }
4395 }
4396
4397 ALOGV("%s: exit", __func__);
4398 return 0;
4399}
4400
4401static struct hw_module_methods_t hal_module_methods = {
4402 .open = adev_open,
4403};
4404
4405struct audio_module HAL_MODULE_INFO_SYM = {
4406 .common = {
4407 .tag = HARDWARE_MODULE_TAG,
4408 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
4409 .hal_api_version = HARDWARE_HAL_API_VERSION,
4410 .id = AUDIO_HARDWARE_MODULE_ID,
Christopher N. Hessec8502b92017-01-28 14:02:15 +01004411 .name = "Samsung Audio HAL",
4412 .author = "The LineageOS Project",
Christopher N. Hesse297a6362017-01-28 12:40:45 +01004413 .methods = &hal_module_methods,
4414 },
4415};